diff options
Diffstat (limited to 'graphics/jpeg/files/patch-rdjpgcom.c')
-rw-r--r-- | graphics/jpeg/files/patch-rdjpgcom.c | 218 |
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: |