Package: libjpeg-turbo-progs Version: 1:1.5.2-2+b1 Severity: normal Tags: patch
Dear Maintainer, according to the EXIF standard, the APP1 segment (which contains the EXIF data) must occur immediately after the SOI (start of image) marker at the beginning of a JFIF file. The jpegexiforient program is built on this assumption, but it turns out that sometimes this isn't the case (e.g., when Digikam writes JFIF files to be sent by e-mail), and jpegexiforient fails to work – it neither outputs the current orientation nor is it able to change it. Following the robustness principle, jpegexiforient should work even in cases where the APP1 segment isn't first in the file, because it makes very little difference to the code. I'm attaching a patch that will fix jpegexiforient in this respect. -- System Information: Debian Release: 10.1 APT prefers testing APT policy: (500, 'testing'), (500, 'stable') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 4.19.0-6-amd64 (SMP w/4 CPU cores) Kernel taint flags: TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8), LANGUAGE= (charmap=UTF-8) Shell: /bin/sh linked to /usr/bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled Versions of packages libjpeg-turbo-progs depends on: ii libc6 2.28-10 ii libjpeg62-turbo 1:1.5.2-2+b1 ii libturbojpeg0 1:1.5.2-2+b1 libjpeg-turbo-progs recommends no packages. libjpeg-turbo-progs suggests no packages. -- no debconf information
--- jpegexiforient.c.orig 2017-08-25 10:27:48.000000000 +0200 +++ jpegexiforient.c 2019-12-22 17:06:46.138211599 +0100 @@ -105,7 +105,9 @@ unsigned int length, i; int is_motorola; /* Flag for byte order */ unsigned int offset, number_of_tags, tagnum; - + int found_app1; + unsigned int exif_start; + progname = argv[0]; if (progname == NULL || progname[0] == 0) progname = "jpegexiforient"; /* in case C library doesn't provide it */ @@ -153,14 +155,38 @@ } } - /* Read File head, check for JPEG SOI + Exif APP1 */ - for (i = 0; i < 4; i++) + /* Read File head, check for JPEG SOI */ + for (i = 0; i < 2; i++) exif_data[i] = (unsigned char) read_1_byte(); if (exif_data[0] != 0xFF || - exif_data[1] != 0xD8 || - exif_data[2] != 0xFF || - exif_data[3] != 0xE1) + exif_data[1] != 0xD8) { + fprintf(stderr, "%s: input doesn't look like JFIF ", progname); return 0; + } + + /* Try to find the JPEG APP1 segment, which doesn't */ + /* necessarily show up immediately after the SOI */ + found_app1 = 0; + exif_start = 2; + while (!feof(myfile)) { + for (i = 0; i < 2; i++) + exif_data[i] = (unsigned char) read_1_byte(); + if (exif_data[0] == 0xFF && exif_data[1] == 0xE1) { + found_app1 = 1; + break; + } + + /* Get the length of the (non-APP1) segment */ + /* and skip it */ + length = read_2_bytes(); + exif_start += length + 2; + for (i = 0; i < length - 2; i++) + read_1_byte(); + } + if (!found_app1) { + fprintf(stderr, "%s: didn't find JPEG-APP1 segment ", progname); + return 0; + } /* Get the marker parameter length count */ length = read_2_bytes(); @@ -193,6 +219,8 @@ else return 0; + exif_start += 10; + /* Check Tag Mark */ if (is_motorola) { if (exif_data[2] != 0) return 0; @@ -217,7 +245,7 @@ offset += exif_data[4]; } if (offset > length - 2) return 0; /* check end of data segment */ - + /* Get the number of directory entries contained in this IFD */ if (is_motorola) { number_of_tags = exif_data[offset]; @@ -274,7 +302,7 @@ exif_data[offset+10] = 0; exif_data[offset+11] = 0; } - fseek(myfile, (4 + 2 + 6 + 2) + offset, SEEK_SET); + fseek(myfile, exif_start + offset + 2, SEEK_SET); fwrite(exif_data + 2 + offset, 1, 10, myfile); } else { /* Get the Orientation value */