aboutsummaryrefslogtreecommitdiff
path: root/graphics/jpeg/files/patch-rdjpgcom.c
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/jpeg/files/patch-rdjpgcom.c')
-rw-r--r--graphics/jpeg/files/patch-rdjpgcom.c218
1 files changed, 218 insertions, 0 deletions
diff --git a/graphics/jpeg/files/patch-rdjpgcom.c b/graphics/jpeg/files/patch-rdjpgcom.c
new file mode 100644
index 000000000000..db6bd23c249f
--- /dev/null
+++ b/graphics/jpeg/files/patch-rdjpgcom.c
@@ -0,0 +1,218 @@
+--- rdjpgcom.c.orig Sun Oct 12 00:41:04 1997
++++ rdjpgcom.c Thu Mar 18 06:37:23 2004
+@@ -14,6 +14,7 @@
+ #define JPEG_CJPEG_DJPEG /* to get the command-line config symbols */
+ #include "jinclude.h" /* get auto-config symbols, <stdio.h> */
+
++#include <locale.h> /* to declare setlocale() */
+ #include <ctype.h> /* to declare isupper(), tolower() */
+ #ifdef USE_SETMODE
+ #include <fcntl.h> /* to declare setmode()'s parameter macros */
+@@ -120,6 +121,7 @@
+ #define M_EOI 0xD9 /* End Of Image (end of datastream) */
+ #define M_SOS 0xDA /* Start Of Scan (begins compressed data) */
+ #define M_APP0 0xE0 /* Application-specific marker, type N */
++#define M_APP1 0xE1 /* Typically EXIF marker */
+ #define M_APP12 0xEC /* (we don't bother to list all 16 APPn's) */
+ #define M_COM 0xFE /* COMment */
+
+@@ -210,6 +212,175 @@
+ }
+ }
+
++/*
++ * Helper routine to skip the given number of bytes.
++ */
++
++static void
++skip_n (unsigned int length)
++{
++ while (length > 0) {
++ (void) read_1_byte();
++ length--;
++ }
++}
++
++/*
++ * Parses an APP1 marker looking for EXIF data. If EXIF, the orientation is
++ * reported to stdout.
++ */
++
++static void
++process_APP1 (void)
++{
++ unsigned int length, i;
++ int is_motorola; /* byte order indicator */
++ unsigned int offset, number_of_tags, tagnum;
++ int orientation;
++ char *ostr;
++ /* This 64K buffer would probably be best if allocated dynamically, but it's
++ * the only one on this program so it's really not that
++ * important. Allocating on the stack is not an option, as 64K might be too
++ * big for some (crippled) platforms. */
++ static unsigned char exif_data[65536L];
++
++ /* Get the marker parameter length count */
++ length = read_2_bytes();
++ /* Length includes itself, so must be at least 2 */
++ if (length < 2)
++ ERREXIT("Erroneous JPEG marker length");
++ length -= 2;
++
++ /* We only care if APP1 is really an EXIF marker. Minimum length is 6 for
++ * signature plus 12 for an IFD. */
++ if (length < 18) {
++ skip_n(length);
++ return;
++ }
++
++ /* Check for actual EXIF marker */
++ for (i=0; i < 6; i++)
++ exif_data[i] = (unsigned char) read_1_byte();
++ length -= 6;
++ if (exif_data[0] != 0x45 ||
++ exif_data[1] != 0x78 ||
++ exif_data[2] != 0x69 ||
++ exif_data[3] != 0x66 ||
++ exif_data[4] != 0 ||
++ exif_data[5] != 0) {
++ skip_n(length);
++ return;
++ }
++
++ /* Read all EXIF body */
++ for (i=0; i < length; i++)
++ exif_data[i] = (unsigned char) read_1_byte();
++
++ /* Discover byte order */
++ if (exif_data[0] == 0x49 && exif_data[1] == 0x49)
++ is_motorola = 0;
++ else if (exif_data[0] == 0x4D && exif_data[1] == 0x4D)
++ is_motorola = 1;
++ else
++ return;
++
++ /* Check Tag Mark */
++ if (is_motorola) {
++ if (exif_data[2] != 0) return;
++ if (exif_data[3] != 0x2A) return;
++ } else {
++ if (exif_data[3] != 0) return;
++ if (exif_data[2] != 0x2A) return;
++ }
++
++ /* Get first IFD offset (offset to IFD0) */
++ if (is_motorola) {
++ if (exif_data[4] != 0) return;
++ if (exif_data[5] != 0) return;
++ offset = exif_data[6];
++ offset <<= 8;
++ offset += exif_data[7];
++ } else {
++ if (exif_data[7] != 0) return;
++ if (exif_data[6] != 0) return;
++ offset = exif_data[5];
++ offset <<= 8;
++ offset += exif_data[4];
++ }
++ if (offset > length - 2) return; /* check end of data segment */
++
++ /* Get the number of directory entries contained in this IFD */
++ if (is_motorola) {
++ number_of_tags = exif_data[offset];
++ number_of_tags <<= 8;
++ number_of_tags += exif_data[offset+1];
++ } else {
++ number_of_tags = exif_data[offset+1];
++ number_of_tags <<= 8;
++ number_of_tags += exif_data[offset];
++ }
++ if (number_of_tags == 0) return;
++ offset += 2;
++
++ /* Search for Orientation Tag in IFD0 */
++ for (;;) {
++ if (offset > length - 12) return; /* check end of data segment */
++ /* Get Tag number */
++ if (is_motorola) {
++ tagnum = exif_data[offset];
++ tagnum <<= 8;
++ tagnum += exif_data[offset+1];
++ } else {
++ tagnum = exif_data[offset+1];
++ tagnum <<= 8;
++ tagnum += exif_data[offset];
++ }
++ if (tagnum == 0x0112) break; /* found Orientation Tag */
++ if (--number_of_tags == 0) return;
++ offset += 12;
++ }
++
++ /* Get the Orientation value */
++ if (is_motorola) {
++ if (exif_data[offset+8] != 0) return;
++ orientation = exif_data[offset+9];
++ } else {
++ if (exif_data[offset+9] != 0) return;
++ orientation = exif_data[offset+8];
++ }
++ if (orientation == 0 || orientation > 8) return;
++
++ /* Print the orientation (position of the 0th row - 0th column) */
++ switch (orientation) {
++ case 1:
++ ostr = "top-left";
++ break;
++ case 2:
++ ostr = "top-right";
++ break;
++ case 3:
++ ostr = "bottom-right";
++ break;
++ case 4:
++ ostr = "bottom-left";
++ break;
++ case 5:
++ ostr = "left-top";
++ break;
++ case 6:
++ ostr = "right-top";
++ break;
++ case 7:
++ ostr = "right-bottom";
++ break;
++ case 8:
++ ostr = "left-bottom";
++ break;
++ default:
++ return;
++ }
++ printf("EXIF orientation: %s\n",ostr);
++}
+
+ /*
+ * Process a COM marker.
+@@ -231,6 +402,7 @@
+ ERREXIT("Erroneous JPEG marker length");
+ length -= 2;
+
++ setlocale(LC_ALL, "");
+ while (length > 0) {
+ ch = read_1_byte();
+ /* Emit the character in a readable form.
+@@ -363,6 +535,15 @@
+
+ case M_COM:
+ process_COM();
++ break;
++
++ case M_APP1:
++ /* APP1 is usually the EXIF marker used by digital cameras, attempt to
++ * process it to give some useful info. */
++ if (verbose) {
++ process_APP1();
++ } else
++ skip_variable();
+ break;
+
+ case M_APP12: