Skip to content

Commit 92ae822

Browse files
committed
Exif: return metadata in struct
Currently just the Orinentation, which is moreover not honored but this can be further used by the caller, eg. get_image_info.
1 parent 7905174 commit 92ae822

File tree

3 files changed

+38
-25
lines changed

3 files changed

+38
-25
lines changed

src/gpujpeg_exif.c

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,6 @@ const struct exif_tiff_tag_info_t {
143143

144144
// misc constants
145145
enum {
146-
ETIFF_ORIENT_HORIZONTAL = 1, // normal
147146
ETIFF_CENTER = 1,
148147
ETIFF_SRGB = 1,
149148
ETIFF_INCHES = 2,
@@ -325,13 +324,13 @@ gpujpeg_write_0th(struct gpujpeg_writer* writer, const uint8_t* start,
325324
struct tm buf;
326325
(void) strftime(date_time, sizeof date_time, "%Y:%m:%d %H:%M:%S", localtime_s(&now, &buf));
327326
struct tag_value tags[] = {
328-
{ETIFF_ORIENTATION, {.uvalue = (uint32_t[]){ETIFF_ORIENT_HORIZONTAL}}},
329-
{ETIFF_XRESOLUTION, {.uvalue = (uint32_t[]){DPI_DEFAULT, 1}} },
330-
{ETIFF_YRESOLUTION, {.uvalue = (uint32_t[]){DPI_DEFAULT, 1}} },
331-
{ETIFF_RESOLUTION_UNIT, {.uvalue = (uint32_t[]){ETIFF_INCHES}} },
332-
{ETIFF_SOFTWARE, {.csvalue = "GPUJPEG"} },
333-
{ETIFF_DATE_TIME , {.csvalue = date_time} },
334-
{ETIFF_YCBCR_POSITIONING, {.uvalue = (uint32_t[]){ETIFF_CENTER}} },
327+
{ETIFF_ORIENTATION, {.uvalue = (uint32_t[]){EXIF_ORIENTATION_HORIZONTAL}}},
328+
{ETIFF_XRESOLUTION, {.uvalue = (uint32_t[]){DPI_DEFAULT, 1}} },
329+
{ETIFF_YRESOLUTION, {.uvalue = (uint32_t[]){DPI_DEFAULT, 1}} },
330+
{ETIFF_RESOLUTION_UNIT, {.uvalue = (uint32_t[]){ETIFF_INCHES}} },
331+
{ETIFF_SOFTWARE, {.csvalue = "GPUJPEG"} },
332+
{ETIFF_DATE_TIME , {.csvalue = date_time} },
333+
{ETIFF_YCBCR_POSITIONING, {.uvalue = (uint32_t[]){ETIFF_CENTER}} },
335334
{ETIFF_EXIF_IFD_POINTER, {0} }, // value will be set later
336335
};
337336
size_t tag_count = ARR_SIZE(tags);
@@ -614,7 +613,7 @@ read_4byte_le(uint8_t** image) {
614613

615614
static void
616615
read_0th_ifd(uint8_t** image, const uint8_t* image_end, int verbose, uint16_t (*read_2byte)(uint8_t**),
617-
uint32_t (*read_4byte)(uint8_t**))
616+
uint32_t (*read_4byte)(uint8_t**), struct gpujpeg_exif_parameters* parsed)
618617
{
619618
if ( *image + 2 > image_end ) {
620619
WARN_MSG("Unexpected end of file!\n");
@@ -646,8 +645,8 @@ read_0th_ifd(uint8_t** image, const uint8_t* image_end, int verbose, uint16_t (*
646645
}
647646
DEBUG_MSG(verbose, MOD_NAME "Found IFD0 tag %s (%#x) type %s: count=%u, %s=%#x\n", exif_tiff_tag_info[tag].name,
648647
tag_id, type_name, count, count * size <= 4 ? "value" : "offset", val);
649-
if ( tag == ETIFF_ORIENTATION && val != ETIFF_ORIENT_HORIZONTAL ) {
650-
WARN_MSG(MOD_NAME "Orientation %d not handled!\n", val);
648+
if ( tag == ETIFF_ORIENTATION ) {
649+
parsed->orientation = val;
651650
}
652651
}
653652

@@ -664,7 +663,7 @@ read_0th_ifd(uint8_t** image, const uint8_t* image_end, int verbose, uint16_t (*
664663
* JPEG Orientation is checked and of not horizontal, warning is issued.
665664
*/
666665
void
667-
gpujpeg_exif_parse(uint8_t** image, const uint8_t* image_end, int verbose)
666+
gpujpeg_exif_parse(uint8_t** image, const uint8_t* image_end, int verbose, struct gpujpeg_exif_parameters* parsed)
668667
{
669668
#define HANDLE_ERROR(...) \
670669
WARN_MSG(__VA_ARGS__); \
@@ -714,7 +713,7 @@ gpujpeg_exif_parse(uint8_t** image, const uint8_t* image_end, int verbose)
714713

715714
uint32_t offset = read_4byte(image); // 0th IFD offset
716715
*image = base + offset;
717-
read_0th_ifd(image, image_end, verbose, read_2byte, read_4byte);
716+
read_0th_ifd(image, image_end, verbose, read_2byte, read_4byte, parsed);
718717

719718
*image = image_start + length;
720719
#undef HANDLE_ERROR

src/gpujpeg_exif.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,17 @@
3030
#ifndef GPUJPEG_EXIF_H_6755D546_2A90_46DF_9ECA_22F575C3E7E3
3131
#define GPUJPEG_EXIF_H_6755D546_2A90_46DF_9ECA_22F575C3E7E3
3232

33-
#ifndef __cplusplus
3433
#include <stdbool.h>
3534
#include <stdint.h>
36-
#endif // not defined __cplusplus
3735

3836
struct gpujpeg_exif_tags;
39-
40-
struct gpujpeg_writer;
4137
struct gpujpeg_image_parameters;
4238
struct gpujpeg_parameters;
39+
struct gpujpeg_writer;
40+
41+
enum {
42+
EXIF_ORIENTATION_HORIZONTAL = 1, // normal
43+
};
4344

4445
void
4546
gpujpeg_writer_write_exif(struct gpujpeg_writer* writer, const struct gpujpeg_parameters* param,
@@ -51,7 +52,12 @@ gpujpeg_exif_add_tag(struct gpujpeg_exif_tags** exif_tags, const char *cfg);
5152
void
5253
gpujpeg_exif_tags_destroy(struct gpujpeg_exif_tags* exif_tags);
5354

55+
struct gpujpeg_exif_parameters
56+
{
57+
unsigned orientation; ///< EXIF_ORIENTATION_HORIZONTAL or a different value
58+
};
59+
5460
void
55-
gpujpeg_exif_parse(uint8_t** image, const uint8_t* image_end, int verbose);
61+
gpujpeg_exif_parse(uint8_t** image, const uint8_t* image_end, int verbose, struct gpujpeg_exif_parameters* parsed);
5662

5763
#endif // defined GPUJPEG_EXIF_H_6755D546_2A90_46DF_9ECA_22F575C3E7E3

src/gpujpeg_reader.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,8 @@ gpujpeg_reader_read_app0(uint8_t** image, const uint8_t* image_end, enum gpujpeg
302302

303303
static void
304304
gpujpeg_reader_read_app1(uint8_t** image, const uint8_t* image_end, enum gpujpeg_header_type* header_type,
305-
enum gpujpeg_color_space* color_space, int verbose)
305+
enum gpujpeg_color_space* color_space, int verbose,
306+
struct gpujpeg_exif_parameters* exif_metadata)
306307
{
307308
if ( image_end - *image < 2 ) {
308309
ERROR_MSG("Unexpected end of APP1 marker!\n");
@@ -319,7 +320,8 @@ gpujpeg_reader_read_app1(uint8_t** image, const uint8_t* image_end, enum gpujpeg
319320
if ( strcmp((char *) type_tag, "Exif") == 0 ) {
320321
*color_space = GPUJPEG_YCBCR_BT601_256LVLS;
321322
*header_type = GPUJPEG_HEADER_EXIF;
322-
gpujpeg_exif_parse(image, image_end, verbose);
323+
memset(exif_metadata, 0, sizeof *exif_metadata);
324+
gpujpeg_exif_parse(image, image_end, verbose, exif_metadata);
323325
return;
324326
}
325327
WARN_MSG("Skipping unsupported APP1 marker \"%s\"!\n", type_tag);
@@ -1362,8 +1364,8 @@ gpujpeg_reader_read_sos(struct gpujpeg_decoder* decoder, struct gpujpeg_reader*
13621364
static int
13631365
gpujpeg_reader_read_common_markers(uint8_t** image, const uint8_t* image_end, int marker, int log_level,
13641366
bool ff_cs_itu601_is_709, enum gpujpeg_color_space* color_space,
1365-
enum gpujpeg_header_type *header_type,
1366-
int* restart_interval, bool* in_spiff)
1367+
enum gpujpeg_header_type* header_type, int* restart_interval, bool* in_spiff,
1368+
struct gpujpeg_exif_parameters* exif_metadata)
13671369
{
13681370
int rc = 0;
13691371
switch (marker)
@@ -1374,7 +1376,7 @@ gpujpeg_reader_read_common_markers(uint8_t** image, const uint8_t* image_end, in
13741376
}
13751377
break;
13761378
case GPUJPEG_MARKER_APP1:
1377-
gpujpeg_reader_read_app1(image, image_end, header_type, color_space, log_level);
1379+
gpujpeg_reader_read_app1(image, image_end, header_type, color_space, log_level, exif_metadata);
13781380
break;
13791381
case GPUJPEG_MARKER_APP8:
13801382
if ( gpujpeg_reader_read_app8(image, image_end, color_space, header_type, log_level, in_spiff) != 0 ) {
@@ -1534,6 +1536,7 @@ gpujpeg_reader_read_image(struct gpujpeg_decoder* decoder, uint8_t* image, size_
15341536
reader.segment_info_size = 0;
15351537
enum gpujpeg_color_space header_color_space = GPUJPEG_NONE;
15361538
enum gpujpeg_header_type header_type = GPUJPEG_HEADER_DEFAULT;
1539+
struct gpujpeg_exif_parameters exif_metadata;
15371540

15381541
// Get image end
15391542
uint8_t* image_end = image + image_size;
@@ -1557,7 +1560,7 @@ gpujpeg_reader_read_image(struct gpujpeg_decoder* decoder, uint8_t* image, size_
15571560
// Read more info according to the marker
15581561
int rc = gpujpeg_reader_read_common_markers(&image, image_end, marker, decoder->coder.param.verbose,
15591562
decoder->ff_cs_itu601_is_709, &header_color_space, &header_type,
1560-
&reader.param.restart_interval, &in_spiff);
1563+
&reader.param.restart_interval, &in_spiff, &exif_metadata);
15611564
if ( rc < 0 ) {
15621565
return rc;
15631566
}
@@ -1638,6 +1641,10 @@ gpujpeg_reader_read_image(struct gpujpeg_decoder* decoder, uint8_t* image, size_
16381641
return -1;
16391642
}
16401643

1644+
if ( header_type == GPUJPEG_HEADER_EXIF && exif_metadata.orientation != EXIF_ORIENTATION_HORIZONTAL ) {
1645+
WARN_MSG("Exif %d not handled!\n", exif_metadata.orientation);
1646+
}
1647+
16411648
return 0;
16421649
}
16431650

@@ -1665,6 +1672,7 @@ gpujpeg_reader_get_image_info(uint8_t *image, size_t image_size, struct gpujpeg_
16651672
enum gpujpeg_color_space header_color_space = GPUJPEG_NONE;
16661673
enum gpujpeg_header_type header_type = GPUJPEG_HEADER_DEFAULT;
16671674
uint8_t *image_end = image + image_size;
1675+
struct gpujpeg_exif_parameters exif_metadata;
16681676

16691677
param->interleaved = 0;
16701678
param->restart_interval = 0;
@@ -1688,7 +1696,7 @@ gpujpeg_reader_get_image_info(uint8_t *image, size_t image_size, struct gpujpeg_
16881696
// Read more info according to the marker
16891697
int rc =
16901698
gpujpeg_reader_read_common_markers(&image, image_end, marker, param->verbose, false, &header_color_space,
1691-
&header_type, &param->restart_interval, &in_spiff);
1699+
&header_type, &param->restart_interval, &in_spiff, &exif_metadata);
16921700
if ( rc < 0 ) {
16931701
return rc;
16941702
}

0 commit comments

Comments
 (0)