Skip to content

Commit c6d5db4

Browse files
committed
exif: use common fn to write both IFDs
1 parent 3921660 commit c6d5db4

File tree

1 file changed

+32
-45
lines changed

1 file changed

+32
-45
lines changed

src/gpujpeg_exif.c

Lines changed: 32 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -203,76 +203,63 @@ write_exif_tag(struct gpujpeg_writer* writer, enum exif_tiff_tag tag, union valu
203203
write_exif_emit_lt_4b_tag(writer, t->id, t->type, size, val, start, end);
204204
}
205205

206+
struct tag_info
207+
{
208+
enum exif_tiff_tag tag;
209+
union value_u value;
210+
};
211+
206212
static void
207-
gpujpeg_write_0th(struct gpujpeg_encoder* encoder, const uint8_t* start)
213+
gpujpeg_write_ifd(struct gpujpeg_encoder* encoder, const uint8_t* start, size_t count,
214+
const struct tag_info tags[static count])
208215
{
209216
struct gpujpeg_writer *writer = encoder->writer;
210-
const struct tag_info
211-
{
212-
enum exif_tiff_tag tag;
213-
union value_u value;
214-
} tags[] = {
215-
{ETIFF_XRESOLUTION, {.urational = {72, 1}} },
216-
{ETIFF_YRESOLUTION, {.urational = {72, 1}} },
217-
{ETIFF_RESOLUTION_UNIT, {.uvalue = ETIFF_INCHES}},
218-
{ETIFF_SOFTWARE, {.csvalue = "GPUJPEG"} },
219-
{ETIFF_YCBCR_POSITIONING, {.uvalue = ETIFF_CENTER}}, // center
220-
{ETIFF_EXIF_IFD_POINTER, {0} }, // value later; should be last
221-
};
222217
enum {
223-
NB_OF_INTEROP_SZ = 2,
224-
SIZE_0TH_IFD = NB_OF_INTEROP_SZ + (ARR_SIZE(tags) * IFD_ITEM_SZ) + NEXT_IFD_PTR_SZ,
218+
EXIF_IFD_NUM_SZ = 2,
225219
};
220+
uint8_t *end = writer->buffer_current + EXIF_IFD_NUM_SZ + (count * IFD_ITEM_SZ) + NEXT_IFD_PTR_SZ;
221+
gpujpeg_writer_emit_2byte(writer, count); // IFD Item Count
226222

227-
uint8_t *end = writer->buffer_current + SIZE_0TH_IFD;
228-
229-
gpujpeg_writer_emit_2byte(writer, ARR_SIZE(tags)); // Number of Interoperability
230-
for (unsigned i = 0; i < ARR_SIZE(tags); ++i) {
223+
for ( unsigned i = 0; i < count; ++i ) {
231224
const struct tag_info* info = &tags[i];
232225
union value_u value = info->value;
233-
if (info->tag == ETIFF_EXIF_IFD_POINTER) {
226+
if ( info->tag == ETIFF_EXIF_IFD_POINTER ) {
234227
value.uvalue = end - start;
235228
}
236229
write_exif_tag(writer, info->tag, value, start, &end);
237230
}
238231
gpujpeg_writer_emit_4byte(writer, 0); // Next IFD Offset (none)
239-
writer->buffer_current = end; // jump after the section Value longer than 4Byte of 0th IFD
232+
writer->buffer_current = end; // jump after the section Value longer than 4Byte of 0th IFD
233+
}
234+
235+
static void
236+
gpujpeg_write_0th(struct gpujpeg_encoder* encoder, const uint8_t* start)
237+
{
238+
struct gpujpeg_writer *writer = encoder->writer;
239+
const struct tag_info tags[] = {
240+
{ETIFF_XRESOLUTION, {.urational = {72, 1}} },
241+
{ETIFF_YRESOLUTION, {.urational = {72, 1}} },
242+
{ETIFF_RESOLUTION_UNIT, {.uvalue = ETIFF_INCHES}},
243+
{ETIFF_SOFTWARE, {.csvalue = "GPUJPEG"} },
244+
{ETIFF_YCBCR_POSITIONING, {.uvalue = ETIFF_CENTER}}, // center
245+
{ETIFF_EXIF_IFD_POINTER, {0} }, // value later; should be last
246+
};
247+
248+
gpujpeg_write_ifd(encoder, start, ARR_SIZE(tags), tags);
240249
}
241250

242251
static void gpujpeg_write_exif_ifd(struct gpujpeg_encoder* encoder, const uint8_t *start)
243252
{
244253
struct gpujpeg_writer *writer = encoder->writer;
245-
const struct tag_info
246-
{
247-
enum exif_tiff_tag tag;
248-
union value_u value;
249-
} tags[] = {
254+
const struct tag_info tags[] = {
250255
{EEXIF_EXIF_VERSION, {.csvalue = "0230"} }, // 2.30
251256
{EEXIF_COMPONENTS_CONFIGURATION, {.csvalue = "\1\2\3\0"} }, // YCbCr
252257
{EEXIF_FLASHPIX_VERSION, {.csvalue = "0100"} }, // "0100"
253258
{EEXIF_COLOR_SPACE, {.uvalue = ETIFF_SRGB} },
254259
{EEXIF_PIXEL_X_DIMENSION, {encoder->coder.param_image.width} },
255260
{EEXIF_PIXEL_Y_DIMENSION, {encoder->coder.param_image.height}},
256261
};
257-
enum {
258-
EXIF_IFD_NUM_SZ = 2,
259-
SIZE_EXIF_IFD = EXIF_IFD_NUM_SZ + (ARR_SIZE(tags) * IFD_ITEM_SZ) + NEXT_IFD_PTR_SZ,
260-
};
261-
262-
uint8_t *end = writer->buffer_current + SIZE_EXIF_IFD;
263-
264-
gpujpeg_writer_emit_2byte(writer, ARR_SIZE(tags)); // Exif IFD Number
265-
266-
for (unsigned i = 0; i < ARR_SIZE(tags); ++i) {
267-
const struct tag_info* info = &tags[i];
268-
union value_u value = info->value;
269-
if (info->tag == ETIFF_EXIF_IFD_POINTER) {
270-
value.uvalue = end - start;
271-
}
272-
write_exif_tag(writer, info->tag, value, start, &end);
273-
}
274-
gpujpeg_writer_emit_4byte(writer, 0); // Next IFD Offset (none)
275-
writer->buffer_current = end; // jump after the section Value longer than 4Byte of 0th IFD
262+
gpujpeg_write_ifd(encoder, start, ARR_SIZE(tags), tags);
276263
}
277264

278265

0 commit comments

Comments
 (0)