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 */

Reply via email to