Skip to content

Commit b43e8a5

Browse files
committed
exif: use common fn to write both IFDs
1 parent fac6d8e commit b43e8a5

File tree

1 file changed

+35
-48
lines changed

1 file changed

+35
-48
lines changed

src/gpujpeg_exif.c

Lines changed: 35 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -197,76 +197,63 @@ write_exif_tag(struct gpujpeg_writer* writer, enum exif_tiff_tag tag, union valu
197197
write_exif_emit_lt_4b_tag(writer, t->id, t->type, size, val, start, end);
198198
}
199199

200+
struct tag_value
201+
{
202+
enum exif_tiff_tag tag;
203+
union value_u value;
204+
};
205+
206+
/**
207+
* @param tags array of tags, should be ordered awcending according to exif_tiff_tag_info_t.id
208+
*/
200209
static void
201-
gpujpeg_write_0th(struct gpujpeg_encoder* encoder, const uint8_t* start)
210+
gpujpeg_write_ifd(struct gpujpeg_writer* writer, const uint8_t* start, size_t count,
211+
const struct tag_value tags[])
202212
{
203-
struct gpujpeg_writer *writer = encoder->writer;
204-
const struct tag_info
205-
{
206-
enum exif_tiff_tag tag;
207-
union value_u value;
208-
} tags[] = {
209-
{ETIFF_XRESOLUTION, {.urational = {72, 1}} },
210-
{ETIFF_YRESOLUTION, {.urational = {72, 1}} },
211-
{ETIFF_RESOLUTION_UNIT, {.uvalue = ETIFF_INCHES}},
212-
{ETIFF_SOFTWARE, {.csvalue = "GPUJPEG"} },
213-
{ETIFF_YCBCR_POSITIONING, {.uvalue = ETIFF_CENTER}}, // center
214-
{ETIFF_EXIF_IFD_POINTER, {0} }, // value later; should be last
215-
};
216213
enum {
217-
NB_OF_INTEROP_SZ = 2,
218-
SIZE_0TH_IFD = NB_OF_INTEROP_SZ + (ARR_SIZE(tags) * IFD_ITEM_SZ) + NEXT_IFD_PTR_SZ,
214+
EXIF_IFD_NUM_SZ = 2,
219215
};
216+
uint8_t *end = writer->buffer_current + EXIF_IFD_NUM_SZ + (count * IFD_ITEM_SZ) + NEXT_IFD_PTR_SZ;
217+
gpujpeg_writer_emit_2byte(writer, count); // IFD Item Count
220218

221-
uint8_t *end = writer->buffer_current + SIZE_0TH_IFD;
222-
223-
gpujpeg_writer_emit_2byte(writer, ARR_SIZE(tags)); // Number of Interoperability
224-
for (unsigned i = 0; i < ARR_SIZE(tags); ++i) {
225-
const struct tag_info* info = &tags[i];
219+
for ( unsigned i = 0; i < count; ++i ) {
220+
const struct tag_value* info = &tags[i];
226221
union value_u value = info->value;
227-
if (info->tag == ETIFF_EXIF_IFD_POINTER) {
222+
if ( info->tag == ETIFF_EXIF_IFD_POINTER ) {
228223
value.uvalue = end - start;
229224
}
230225
write_exif_tag(writer, info->tag, value, start, &end);
231226
}
232227
gpujpeg_writer_emit_4byte(writer, 0); // Next IFD Offset (none)
233-
writer->buffer_current = end; // jump after the section Value longer than 4Byte of 0th IFD
228+
writer->buffer_current = end; // jump after the section Value longer than 4Byte of 0th IFD
229+
}
230+
231+
static void
232+
gpujpeg_write_0th(struct gpujpeg_encoder* encoder, const uint8_t* start)
233+
{
234+
const struct tag_value tags[] = {
235+
{ETIFF_XRESOLUTION, {.urational = {72, 1}} },
236+
{ETIFF_YRESOLUTION, {.urational = {72, 1}} },
237+
{ETIFF_RESOLUTION_UNIT, {.uvalue = ETIFF_INCHES}},
238+
{ETIFF_SOFTWARE, {.csvalue = "GPUJPEG"} },
239+
{ETIFF_YCBCR_POSITIONING, {.uvalue = ETIFF_CENTER}}, // center
240+
{ETIFF_EXIF_IFD_POINTER, {0} }, // value later; should be last
241+
};
242+
243+
gpujpeg_write_ifd(encoder->writer, start, ARR_SIZE(tags), tags);
234244
}
235245

236246
static void gpujpeg_write_exif_ifd(struct gpujpeg_encoder* encoder, const uint8_t *start)
237247
{
238-
struct gpujpeg_writer *writer = encoder->writer;
239-
const struct tag_info
240-
{
241-
enum exif_tiff_tag tag;
242-
union value_u value;
243-
} tags[] = {
248+
const struct tag_value tags[] = {
244249
{EEXIF_EXIF_VERSION, {.csvalue = "0230"} }, // 2.30
245250
{EEXIF_COMPONENTS_CONFIGURATION, {.csvalue = "\1\2\3\0"} }, // YCbCr
246251
{EEXIF_FLASHPIX_VERSION, {.csvalue = "0100"} }, // "0100"
247252
{EEXIF_COLOR_SPACE, {.uvalue = ETIFF_SRGB} },
248253
{EEXIF_PIXEL_X_DIMENSION, {encoder->coder.param_image.width} },
249254
{EEXIF_PIXEL_Y_DIMENSION, {encoder->coder.param_image.height}},
250255
};
251-
enum {
252-
EXIF_IFD_NUM_SZ = 2,
253-
SIZE_EXIF_IFD = EXIF_IFD_NUM_SZ + (ARR_SIZE(tags) * IFD_ITEM_SZ) + NEXT_IFD_PTR_SZ,
254-
};
255-
256-
uint8_t *end = writer->buffer_current + SIZE_EXIF_IFD;
257-
258-
gpujpeg_writer_emit_2byte(writer, ARR_SIZE(tags)); // Exif IFD Number
259-
260-
for (unsigned i = 0; i < ARR_SIZE(tags); ++i) {
261-
const struct tag_info* info = &tags[i];
262-
union value_u value = info->value;
263-
if (info->tag == ETIFF_EXIF_IFD_POINTER) {
264-
value.uvalue = end - start;
265-
}
266-
write_exif_tag(writer, info->tag, value, start, &end);
267-
}
268-
gpujpeg_writer_emit_4byte(writer, 0); // Next IFD Offset (none)
269-
writer->buffer_current = end; // jump after the section Value longer than 4Byte of 0th IFD
256+
gpujpeg_write_ifd(encoder->writer, start, ARR_SIZE(tags), tags);
270257
}
271258

272259

0 commit comments

Comments
 (0)