Skip to content

Commit 64f3595

Browse files
committed
jpeg_reader: SPIFF: port changes from GPUJPEG
GPUJPEG commit 06f18868b message: ```` gpujpeg_reader spiff: directory read fix+updates - FIXED: skipping content the dir entries other than EOD (+ early returns) - pass the complete length, not -2 (it is misleading) - length check - increase from 6 (4+2) to 8 - T.84 says ELEN should be at least 8 (seems that EDATA should be at least 2 bytes) ```
1 parent d803eb5 commit 64f3595

File tree

1 file changed

+45
-22
lines changed

1 file changed

+45
-22
lines changed

src/utils/jpeg_reader.c

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,12 @@ enum jpeg_marker_code {
196196
JPEG_MARKER_ERROR = 0x100
197197
};
198198

199+
struct jpeg_reader
200+
{
201+
const uint8_t *const image_end;
202+
enum jpeg_color_spec header_color_space;
203+
bool in_spiff;
204+
};
199205

200206
static const char* jpeg_marker_name(enum jpeg_marker_code code)
201207
{
@@ -711,47 +717,62 @@ read_spiff_header(uint8_t** image, enum jpeg_color_spec *color_space, bool *in_s
711717
}
712718

713719
static int
714-
read_spiff_directory(uint8_t** image, const uint8_t* image_end, int length, _Bool *in_spiff)
720+
read_spiff_directory(uint8_t** image, struct jpeg_reader *reader, int length)
715721
{
716-
if (length < 4) {
717-
fprintf(stderr, "[GPUJPEG] [Error] APP8 SPIFF directory too short (%d bytes)\n", length + 2);
718-
image += length;
722+
if ( length < 8 ) { // ELEN at least 8
723+
MSG(ERROR, "APP8 SPIFF directory too short (%d bytes)\n", length);
724+
image += length - 2;
719725
return -1;
720726
}
721727
uint32_t tag = read_4byte(*image);
722-
debug_msg("Read SPIFF tag 0x%x with length %d.\n", tag, length + 2);
723-
if (tag == SPIFF_ENTRY_TAG_EOD && length == SPIFF_ENTRY_TAG_EOD_LENGHT - 2) {
724-
int marker_soi = read_marker(image, image_end);
728+
MSG(DEBUG2, "Read SPIFF tag 0x%x with length %d.\n", tag, length);
729+
if ( tag == SPIFF_ENTRY_TAG_EOD && length == SPIFF_ENTRY_TAG_EOD_LENGHT ) {
730+
int marker_soi = read_marker(image, reader->image_end);
725731
if ( marker_soi != JPEG_MARKER_SOI ) {
726-
verbose_msg("SPIFF entry 0x1 should be followed directly with SOI.\n");
732+
MSG(VERBOSE, "SPIFF entry 0x1 should be followed directly with SOI.\n");
727733
return -1;
728734
}
729-
debug_msg("SPIFF EOD presented.\n");
730-
*in_spiff = 0;
731-
} else if (tag >> 24U != 0) {
732-
verbose_msg( "Erroneous SPIFF tag 0x%x (first byte should be 0).", tag);
733-
} else {
734-
debug_msg("SPIFF tag 0x%x with length %d presented.\n", tag, length + 2);
735+
MSG(DEBUG2, "SPIFF EOD presented.\n");
736+
reader->in_spiff = false;
737+
return 0;
735738
}
739+
740+
if ( tag >> 24U != 0 ) { // given by the standard
741+
MSG(VERBOSE, "Erroneous SPIFF tag 0x%x (first byte should be 0).", tag);
742+
*image += length - 6;
743+
return 0;
744+
}
745+
// if ( tag == SPIFF_ENTRY_TAG_ORIENATAION ) {
746+
// int rotation = gpujpeg_reader_read_byte(*image);
747+
// bool flip = gpujpeg_reader_read_byte(*image);
748+
// reader->metadata->vals[GPUJPEG_METADATA_ORIENTATION].orient.rotation = rotation;
749+
// reader->metadata->vals[GPUJPEG_METADATA_ORIENTATION].orient.flip = flip;
750+
// reader->metadata->vals[GPUJPEG_METADATA_ORIENTATION].set = 1;
751+
// DEBUG_MSG(reader->param.verbose, "SPIFF CW rotation: %d deg%s\n", rotation * 90, flip ? ", mirrored" : "");
752+
// *image += 2; // 2 bytes reserved
753+
// return 0;
754+
// }
755+
MSG(DEBUG2, "Unhandled SPIFF tag 0x%x with length %d presented.\n", tag, length);
756+
*image += length - 6;
736757
return 0;
737758
}
738759

739760
static int
740-
read_app8(uint8_t** image, const uint8_t* image_end, enum jpeg_color_spec *color_space, bool *in_spiff)
761+
read_app8(uint8_t** image, struct jpeg_reader *reader)
741762
{
742-
if(image_end - *image < 2) {
763+
if(reader->image_end - *image < 2) {
743764
fprintf(stderr, "[GPUJPEG] [Error] Could not read APP8 marker length (end of data)\n");
744765
return -1;
745766
}
746767
int length = read_2byte(*image);
747768
length -= 2;
748-
if(image_end - *image < length) {
769+
if(reader->image_end - *image < length) {
749770
fprintf(stderr, "[GPUJPEG] [Error] APP8 marker goes beyond end of data\n");
750771
return -1;
751772
}
752773

753-
if (*in_spiff) {
754-
return read_spiff_directory(image, image_end, length, in_spiff);
774+
if (reader->in_spiff) {
775+
return read_spiff_directory(image, reader, length);
755776
}
756777

757778
if (length + 2 != SPIFF_MARKER_LEN) {
@@ -776,7 +797,7 @@ read_app8(uint8_t** image, const uint8_t* image_end, enum jpeg_color_spec *color
776797
return 0;
777798
}
778799

779-
return read_spiff_header(image, color_space, in_spiff);
800+
return read_spiff_header(image, &reader->header_color_space, &reader->in_spiff);
780801
}
781802

782803
static int
@@ -858,7 +879,9 @@ int jpeg_read_info(uint8_t *image, int len, struct jpeg_info *info)
858879
info->com[0] = '\0'; // if COM is not present
859880
info->color_spec = JPEG_COLOR_SPEC_YCBCR_JPEG; // default
860881
bool marker_present[255] = { 0 };
861-
bool in_spiff = false;
882+
struct jpeg_reader reader = {
883+
.image_end = image_end,
884+
};
862885

863886
// currently reading up to SOS marker gives us all needed data
864887
while (!marker_present[JPEG_MARKER_EOI] && !marker_present[JPEG_MARKER_SOS]
@@ -919,7 +942,7 @@ int jpeg_read_info(uint8_t *image, int len, struct jpeg_info *info)
919942
break;
920943

921944
case JPEG_MARKER_APP8:
922-
if ( read_app8(&image, image_end, &info->color_spec, &in_spiff ) != 0 ) {
945+
if ( read_app8(&image, &reader ) != 0 ) {
923946
return -1;
924947
}
925948
break;

0 commit comments

Comments
 (0)