diff options
author | dinoex <dinoex@FreeBSD.org> | 2004-03-18 22:53:47 +0800 |
---|---|---|
committer | dinoex <dinoex@FreeBSD.org> | 2004-03-18 22:53:47 +0800 |
commit | 7bab82777232174a5b09f21c258e67143b79b88a (patch) | |
tree | b9ac9d413532e19ff8fd5de7ce595ce6258c23ee /graphics/jpeg/files | |
parent | c48ffc8c32c5acfc4eb1a2187e073119994cf709 (diff) | |
download | freebsd-ports-gnome-7bab82777232174a5b09f21c258e67143b79b88a.tar.gz freebsd-ports-gnome-7bab82777232174a5b09f21c258e67143b79b88a.tar.zst freebsd-ports-gnome-7bab82777232174a5b09f21c258e67143b79b88a.zip |
- Patches from
http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=106060 ,
http://sylvana.net/jpegcrop/exifpatch.html
Which add EXIF support to jpegtran (lossless JPEG transforms) and to
rdjpgcom to add reporting of EXIF orientation in verbose mode.
- Tools from http://sylvana.net/jpegcrop/exif_orientation.html
which allow automatic JPEG orientation using the EXIF tag from the camera.
(I think it should be done with DISTFILES rather than with PATCH_SITES,
though).
Roman Shterenzon
(some cleanup done)
Diffstat (limited to 'graphics/jpeg/files')
-rw-r--r-- | graphics/jpeg/files/patch-ae | 18 | ||||
-rw-r--r-- | graphics/jpeg/files/patch-configure (renamed from graphics/jpeg/files/patch-ab) | 0 | ||||
-rw-r--r-- | graphics/jpeg/files/patch-djpeg.c (renamed from graphics/jpeg/files/patch-ad) | 0 | ||||
-rw-r--r-- | graphics/jpeg/files/patch-exifautotran | 7 | ||||
-rw-r--r-- | graphics/jpeg/files/patch-jpegtran.1 | 44 | ||||
-rw-r--r-- | graphics/jpeg/files/patch-jpegtran.c | 99 | ||||
-rw-r--r-- | graphics/jpeg/files/patch-rdjpgcom.c | 218 | ||||
-rw-r--r-- | graphics/jpeg/files/patch-transupp.c | 284 | ||||
-rw-r--r-- | graphics/jpeg/files/patch-transupp.h | 12 |
9 files changed, 664 insertions, 18 deletions
diff --git a/graphics/jpeg/files/patch-ae b/graphics/jpeg/files/patch-ae deleted file mode 100644 index 5004e6cd3040..000000000000 --- a/graphics/jpeg/files/patch-ae +++ /dev/null @@ -1,18 +0,0 @@ ---- rdjpgcom.c.orig Sat Oct 11 18:41:04 1997 -+++ rdjpgcom.c Mon Apr 24 16:04:13 2000 -@@ -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 */ -@@ -231,6 +232,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. diff --git a/graphics/jpeg/files/patch-ab b/graphics/jpeg/files/patch-configure index 85392d80c6ae..85392d80c6ae 100644 --- a/graphics/jpeg/files/patch-ab +++ b/graphics/jpeg/files/patch-configure diff --git a/graphics/jpeg/files/patch-ad b/graphics/jpeg/files/patch-djpeg.c index 224fefe2e850..224fefe2e850 100644 --- a/graphics/jpeg/files/patch-ad +++ b/graphics/jpeg/files/patch-djpeg.c diff --git a/graphics/jpeg/files/patch-exifautotran b/graphics/jpeg/files/patch-exifautotran new file mode 100644 index 000000000000..418f618019ba --- /dev/null +++ b/graphics/jpeg/files/patch-exifautotran @@ -0,0 +1,7 @@ +--- exifautotran.orig Thu Mar 18 06:25:27 2004 ++++ exifautotran Thu Mar 18 06:28:29 2004 +@@ -1,3 +1,4 @@ ++#!/bin/sh + # exifautotran [list of files] + # + # Transforms Exif files so that Orientation becomes 1 diff --git a/graphics/jpeg/files/patch-jpegtran.1 b/graphics/jpeg/files/patch-jpegtran.1 new file mode 100644 index 000000000000..fe4eb1372f4d --- /dev/null +++ b/graphics/jpeg/files/patch-jpegtran.1 @@ -0,0 +1,44 @@ +--- jpegtran.1.exif 1997-08-03 22:01:01.000000000 +0200 ++++ jpegtran.1 2003-09-30 14:35:36.000000000 +0200 +@@ -161,6 +161,14 @@ + Copy all extra markers. This setting preserves miscellaneous markers + found in the source file, such as JFIF thumbnails and Photoshop settings. + In some files these extra markers can be sizable. ++See 'EXIF FILES' for special tratement of EXIF markers. ++.TP ++.B \-copy exif ++This setting preserves the EXIF marker, commonly found in JPEG files produced ++by digital cameras, in addition to any comment markers. If there is an EXIF ++marker it is copied and the JFIF marker (incompatible with EXIF) is ++omitted. If there is no EXIF marker a JFIF one is emitted as usual. See 'EXIF ++FILES' for special tratement of EXIF markers. + .PP + The default behavior is + .BR "\-copy comments" . +@@ -189,6 +197,26 @@ + .B \-debug + Same as + .BR \-verbose . ++.SH EXIF FILES ++The EXIF variety of JPEG files, which are often produced by digital cameras, ++are recognized by jpegtran as EXIF files (i.e. not as JFIF, the ++usual variety of JPEG files). If the input file is recognized as EXIF (i.e., ++there is an EXIF marker and no JFIF marker) the '-copy exif' option is ++automatically turned on if '-copy comments', or no '-copy' option, was ++specified. Thus, unless '-copy none' is specified an EXIF file is kept as EXIF ++and not converted to JFIF. ++.PP ++If a geometrical transformation is applied (e.g., rotate, transpose) the EXIF ++width and height fields are set to the width and height of the output ++image. Furthermore, the orientation field is reset to one, meaning tha the ++orientation of the output image is upright (i.e. normal). ++.PP ++Note that an explicitely given '-copy exif' option will output an EXIF file if ++the input is an EXIF file that was saved as JFIF, and that the EXIF marker is ++still present. This option is useful for recovering EXIF files that where ++converted to JFIF by a non EXIF-aware software. Note however, that the data in ++the EXIF marker is not validated, unless a geometrical transformation is ++applied. + .SH EXAMPLES + .LP + This example converts a baseline JPEG file to progressive form: diff --git a/graphics/jpeg/files/patch-jpegtran.c b/graphics/jpeg/files/patch-jpegtran.c new file mode 100644 index 000000000000..429d1099e56d --- /dev/null +++ b/graphics/jpeg/files/patch-jpegtran.c @@ -0,0 +1,99 @@ +--- jpegtran.c.exif 1997-07-24 04:37:26.000000000 +0200 ++++ jpegtran.c 2003-09-29 22:31:22.000000000 +0200 +@@ -56,6 +56,7 @@ + fprintf(stderr, " -copy none Copy no extra markers from source file\n"); + fprintf(stderr, " -copy comments Copy only comment markers (default)\n"); + fprintf(stderr, " -copy all Copy all extra markers\n"); ++ fprintf(stderr, " -copy exif Copy EXIF marker and omit JFIF if EXIF\n"); + #ifdef ENTROPY_OPT_SUPPORTED + fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n"); + #endif +@@ -109,6 +110,50 @@ + #endif + } + ++LOCAL(void) ++handle_exif (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, ++ JCOPY_OPTION *copyoption) ++/* Adjust the marker writing options to create an EXIF file, instead of JFIF, ++ * if so requested or an EXIF file is detected as input. Must be called after ++ * jpeg_copy_critical_parameters() as that sets the defaults. */ ++{ ++ jpeg_saved_marker_ptr cur_marker, prev_marker; ++ ++ /* Look for an exif marker */ ++ prev_marker = NULL; ++ cur_marker = srcinfo->marker_list; ++ while (cur_marker != NULL) { ++ if (cur_marker->marker == JPEG_APP0+1 && ++ cur_marker->data_length >= 6 && ++ GETJOCTET(cur_marker->data[0]) == 0x45 && ++ GETJOCTET(cur_marker->data[1]) == 0x78 && ++ GETJOCTET(cur_marker->data[2]) == 0x69 && ++ GETJOCTET(cur_marker->data[3]) == 0x66 && ++ GETJOCTET(cur_marker->data[4]) == 0 && ++ GETJOCTET(cur_marker->data[5]) == 0) ++ break; /* found an EXIF marker */ ++ prev_marker = cur_marker; ++ cur_marker = cur_marker->next; ++ } ++ /* If we've found an EXIF marker but not JFIF this is an EXIF file. Unless ++ * explicitely requested, make sure we keep the EXIF marker and do not ++ * emit a JFIF marker (which would come before). EXIF requires that the ++ * first marker be EXIF. */ ++ if (cur_marker != NULL && ++ ((*copyoption != JCOPYOPT_NONE && !srcinfo->saw_JFIF_marker) || ++ (*copyoption == JCOPYOPT_EXIF))) { ++ dstinfo->write_JFIF_header = FALSE; ++ if (*copyoption == JCOPYOPT_COMMENTS) ++ *copyoption = JCOPYOPT_EXIF; ++ } ++ /* If making an EXIF file, make sure that EXIF is first marker */ ++ if (cur_marker != NULL && prev_marker != NULL && ++ *copyoption == JCOPYOPT_EXIF) { ++ prev_marker->next = cur_marker->next; ++ cur_marker->next = srcinfo->marker_list; ++ srcinfo->marker_list = cur_marker; ++ } ++} + + LOCAL(int) + parse_switches (j_compress_ptr cinfo, int argc, char **argv, +@@ -170,6 +215,8 @@ + copyoption = JCOPYOPT_COMMENTS; + } else if (keymatch(argv[argn], "all", 1)) { + copyoption = JCOPYOPT_ALL; ++ } else if (keymatch(argv[argn], "exif", 1)) { ++ copyoption = JCOPYOPT_EXIF; + } else + usage(); + +@@ -181,6 +228,7 @@ + if (! printed_version) { + fprintf(stderr, "Independent JPEG Group's JPEGTRAN, version %s\n%s\n", + JVERSION, JCOPYRIGHT); ++ fprintf(stderr, "EXIF support v 0.1 added 29-Sep-2003\n"); + printed_version = TRUE; + } + cinfo->err->trace_level++; +@@ -452,6 +500,7 @@ + /* Initialize destination compression parameters from source values */ + jpeg_copy_critical_parameters(&srcinfo, &dstinfo); + ++ + /* Adjust destination parameters if required by transform options; + * also find out which set of coefficient arrays will hold the output. + */ +@@ -464,8 +513,12 @@ + #endif + + /* Adjust default compression parameters by re-parsing the options */ ++ /* Save value of copyoption */ + file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE); + ++ /* If we want EXIF, make sure we do not write incompatible markers */ ++ handle_exif(&srcinfo,&dstinfo,©option); ++ + /* Specify data destination for compression */ + jpeg_stdio_dest(&dstinfo, output_file); + 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: diff --git a/graphics/jpeg/files/patch-transupp.c b/graphics/jpeg/files/patch-transupp.c new file mode 100644 index 000000000000..48927aa80bc0 --- /dev/null +++ b/graphics/jpeg/files/patch-transupp.c @@ -0,0 +1,284 @@ +--- transupp.c.exif 1997-08-10 02:15:26.000000000 +0200 ++++ transupp.c 2003-09-29 22:28:42.000000000 +0200 +@@ -717,6 +717,194 @@ + } + + ++/* Adjust Exif image parameters. ++ * ++ * We try to adjust the Tags ExifImageWidth, ExifImageHeight and ++ * ExifOrientation if possible. If the given new_* value is zero the ++ * corresponding tag is not adjusted. ++ */ ++ ++LOCAL(void) ++adjust_exif_parameters (JOCTET FAR * data, unsigned int length, ++ JDIMENSION new_width, JDIMENSION new_height, ++ unsigned int new_orient) ++{ ++ boolean is_motorola; /* Flag for byte order */ ++ unsigned int number_of_tags, tagnum; ++ unsigned int firstoffset, offset, exifsuboffset; ++ JDIMENSION new_value; ++ ++ if (length < 12) return; /* Length of an IFD entry */ ++ ++ /* Discover byte order */ ++ if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49) ++ is_motorola = FALSE; ++ else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D) ++ is_motorola = TRUE; ++ else ++ return; ++ ++ /* Check Tag Mark */ ++ if (is_motorola) { ++ if (GETJOCTET(data[2]) != 0) return; ++ if (GETJOCTET(data[3]) != 0x2A) return; ++ } else { ++ if (GETJOCTET(data[3]) != 0) return; ++ if (GETJOCTET(data[2]) != 0x2A) return; ++ } ++ ++ /* Get first IFD offset (offset to IFD0) */ ++ if (is_motorola) { ++ if (GETJOCTET(data[4]) != 0) return; ++ if (GETJOCTET(data[5]) != 0) return; ++ firstoffset = GETJOCTET(data[6]); ++ firstoffset <<= 8; ++ firstoffset += GETJOCTET(data[7]); ++ } else { ++ if (GETJOCTET(data[7]) != 0) return; ++ if (GETJOCTET(data[6]) != 0) return; ++ firstoffset = GETJOCTET(data[5]); ++ firstoffset <<= 8; ++ firstoffset += GETJOCTET(data[4]); ++ } ++ if (firstoffset > length - 2) return; /* check end of data segment */ ++ ++ /* Get the number of directory entries contained in this IFD */ ++ if (is_motorola) { ++ number_of_tags = GETJOCTET(data[firstoffset]); ++ number_of_tags <<= 8; ++ number_of_tags += GETJOCTET(data[firstoffset+1]); ++ } else { ++ number_of_tags = GETJOCTET(data[firstoffset+1]); ++ number_of_tags <<= 8; ++ number_of_tags += GETJOCTET(data[firstoffset]); ++ } ++ if (number_of_tags == 0) return; ++ firstoffset += 2; ++ ++ /* Search for ExifSubIFD offset and ExifOrient Tag in IFD0 */ ++ exifsuboffset = 0; ++ for (;;) { ++ if (firstoffset > length - 12) break; /* check end of data segment */ ++ /* Get Tag number */ ++ if (is_motorola) { ++ tagnum = GETJOCTET(data[firstoffset]); ++ tagnum <<= 8; ++ tagnum += GETJOCTET(data[firstoffset+1]); ++ } else { ++ tagnum = GETJOCTET(data[firstoffset+1]); ++ tagnum <<= 8; ++ tagnum += GETJOCTET(data[firstoffset]); ++ } ++ if (tagnum == 0x0112 && new_orient > 0) { /* found ExifOrientation */ ++ if (is_motorola) { ++ data[firstoffset+2] = 0; /* Format = unsigned short (2 octets) */ ++ data[firstoffset+3] = 3; ++ data[firstoffset+4] = 0; /* Number Of Components = 1 */ ++ data[firstoffset+5] = 0; ++ data[firstoffset+6] = 0; ++ data[firstoffset+7] = 1; ++ data[firstoffset+8] = 0; ++ data[firstoffset+9] = (JOCTET)new_orient; ++ data[firstoffset+10] = 0; ++ data[firstoffset+11] = 0; ++ } else { ++ data[firstoffset+2] = 3; /* Format = unsigned short (2 octets) */ ++ data[firstoffset+3] = 0; ++ data[firstoffset+4] = 1; /* Number Of Components = 1 */ ++ data[firstoffset+5] = 0; ++ data[firstoffset+6] = 0; ++ data[firstoffset+7] = 0; ++ data[firstoffset+8] = (JOCTET)new_orient; ++ data[firstoffset+9] = 0; ++ data[firstoffset+10] = 0; ++ data[firstoffset+11] = 0; ++ } ++ } else if (tagnum == 0x8769) { ++ exifsuboffset = firstoffset; /* found ExifSubIFD offset Tag */ ++ } ++ if (--number_of_tags == 0) break; ++ firstoffset += 12; ++ } ++ if (exifsuboffset == 0) return; ++ ++ /* Get the ExifSubIFD offset */ ++ if (is_motorola) { ++ if (GETJOCTET(data[exifsuboffset+8]) != 0) return; ++ if (GETJOCTET(data[exifsuboffset+9]) != 0) return; ++ offset = GETJOCTET(data[exifsuboffset+10]); ++ offset <<= 8; ++ offset += GETJOCTET(data[exifsuboffset+11]); ++ } else { ++ if (GETJOCTET(data[exifsuboffset+11]) != 0) return; ++ if (GETJOCTET(data[exifsuboffset+10]) != 0) return; ++ offset = GETJOCTET(data[exifsuboffset+9]); ++ offset <<= 8; ++ offset += GETJOCTET(data[exifsuboffset+8]); ++ } ++ if (offset > length - 2) return; /* check end of data segment */ ++ ++ /* Get the number of directory entries contained in this SubIFD */ ++ if (is_motorola) { ++ number_of_tags = GETJOCTET(data[offset]); ++ number_of_tags <<= 8; ++ number_of_tags += GETJOCTET(data[offset+1]); ++ } else { ++ number_of_tags = GETJOCTET(data[offset+1]); ++ number_of_tags <<= 8; ++ number_of_tags += GETJOCTET(data[offset]); ++ } ++ if (number_of_tags < 2) return; ++ offset += 2; ++ ++ /* Search for ExifImageWidth and ExifImageHeight Tags in this SubIFD */ ++ do { ++ if (offset > length - 12) return; /* check end of data segment */ ++ /* Get Tag number */ ++ if (is_motorola) { ++ tagnum = GETJOCTET(data[offset]); ++ tagnum <<= 8; ++ tagnum += GETJOCTET(data[offset+1]); ++ } else { ++ tagnum = GETJOCTET(data[offset+1]); ++ tagnum <<= 8; ++ tagnum += GETJOCTET(data[offset]); ++ } ++ if ((tagnum == 0xA002 && new_width > 0) || ++ (tagnum == 0xA003 && new_height > 0)) { ++ if (tagnum == 0xA002) ++ new_value = new_width; /* ExifImageWidth Tag */ ++ else ++ new_value = new_height; /* ExifImageHeight Tag */ ++ if (is_motorola) { ++ data[offset+2] = 0; /* Format = unsigned long (4 octets) */ ++ data[offset+3] = 4; ++ data[offset+4] = 0; /* Number Of Components = 1 */ ++ data[offset+5] = 0; ++ data[offset+6] = 0; ++ data[offset+7] = 1; ++ data[offset+8] = 0; ++ data[offset+9] = 0; ++ data[offset+10] = (JOCTET)((new_value >> 8) & 0xFF); ++ data[offset+11] = (JOCTET)(new_value & 0xFF); ++ } else { ++ data[offset+2] = 4; /* Format = unsigned long (4 octets) */ ++ data[offset+3] = 0; ++ data[offset+4] = 1; /* Number Of Components = 1 */ ++ data[offset+5] = 0; ++ data[offset+6] = 0; ++ data[offset+7] = 0; ++ data[offset+8] = (JOCTET)(new_value & 0xFF); ++ data[offset+9] = (JOCTET)((new_value >> 8) & 0xFF); ++ data[offset+10] = 0; ++ data[offset+11] = 0; ++ } ++ } ++ offset += 12; ++ } while (--number_of_tags); ++} ++ ++ + /* Adjust output image parameters as needed. + * + * This must be called after jpeg_copy_critical_parameters() +@@ -734,6 +922,8 @@ + jvirt_barray_ptr *src_coef_arrays, + jpeg_transform_info *info) + { ++ jpeg_saved_marker_ptr cur_marker; /* ptr to walk the marker list */ ++ + /* If force-to-grayscale is requested, adjust destination parameters */ + if (info->force_grayscale) { + /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed +@@ -799,6 +989,28 @@ + break; + } + ++ /* Adjust Exif properties. Exif requires its APP marker to be the first ++ * one, but we allow other locations for mixed JFIF/Exif files. */ ++ cur_marker = srcinfo->marker_list; ++ while (cur_marker != NULL) { ++ if (cur_marker->marker == JPEG_APP0+1 && ++ cur_marker->data_length >= 6 && ++ GETJOCTET(cur_marker->data[0]) == 0x45 && ++ GETJOCTET(cur_marker->data[1]) == 0x78 && ++ GETJOCTET(cur_marker->data[2]) == 0x69 && ++ GETJOCTET(cur_marker->data[3]) == 0x66 && ++ GETJOCTET(cur_marker->data[4]) == 0 && ++ GETJOCTET(cur_marker->data[5]) == 0) { ++ /* Adjust Exif image parameters */ ++ if (info->transform != JXFORM_NONE) ++ /* Align data segment to start of TIFF structure for parsing */ ++ adjust_exif_parameters(cur_marker->data + 6, ++ cur_marker->data_length - 6, ++ dstinfo->image_width, dstinfo->image_height, 1); ++ } ++ cur_marker = cur_marker->next; ++ } ++ + /* Return the appropriate output data set */ + if (info->workspace_coef_arrays != NULL) + return info->workspace_coef_arrays; +@@ -854,6 +1066,8 @@ + + + /* Setup decompression object to save desired markers in memory. ++ * Unless JCOPYOPT_NONE is given, the COM and potential EXIF markers (APP1) ++ * are always saved. + * This must be called before jpeg_read_header() to have the desired effect. + */ + +@@ -871,6 +1085,8 @@ + if (option == JCOPYOPT_ALL) { + for (m = 0; m < 16; m++) + jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF); ++ } else if (option != JCOPYOPT_NONE) { ++ jpeg_save_markers(srcinfo, JPEG_APP0 + 1, 0xFFFF); + } + #endif /* SAVE_MARKERS_SUPPORTED */ + } +@@ -888,12 +1104,27 @@ + { + jpeg_saved_marker_ptr marker; + +- /* In the current implementation, we don't actually need to examine the +- * option flag here; we just copy everything that got saved. +- * But to avoid confusion, we do not output JFIF and Adobe APP14 markers ++ /* NOTE: to avoid confusion, we do not output JFIF and Adobe APP14 markers + * if the encoder library already wrote one. + */ ++ if (option == JCOPYOPT_NONE) return; + for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) { ++ if (option == JCOPYOPT_COMMENTS && ++ marker->marker != JPEG_COM) { ++ continue; /* only COM accpeted if JCOPYOPT_COMMENTS */ ++ } ++ if (option == JCOPYOPT_EXIF && ++ marker->marker != JPEG_COM && ++ !(marker->marker == JPEG_APP0+1 && ++ marker->data_length >= 6 && ++ GETJOCTET(marker->data[0]) == 0x45 && ++ GETJOCTET(marker->data[1]) == 0x78 && ++ GETJOCTET(marker->data[2]) == 0x69 && ++ GETJOCTET(marker->data[3]) == 0x66 && ++ GETJOCTET(marker->data[4]) == 0 && ++ GETJOCTET(marker->data[5]) == 0)) { ++ continue; /* only COM and APP1-EXIF if JCOPYOPT_EXIF */ ++ } + if (dstinfo->write_JFIF_header && + marker->marker == JPEG_APP0 && + marker->data_length >= 5 && diff --git a/graphics/jpeg/files/patch-transupp.h b/graphics/jpeg/files/patch-transupp.h new file mode 100644 index 000000000000..f295b2803445 --- /dev/null +++ b/graphics/jpeg/files/patch-transupp.h @@ -0,0 +1,12 @@ +--- transupp.h.exif 1997-07-24 04:39:12.000000000 +0200 ++++ transupp.h 2003-09-25 01:05:12.000000000 +0200 +@@ -121,7 +121,8 @@ + typedef enum { + JCOPYOPT_NONE, /* copy no optional markers */ + JCOPYOPT_COMMENTS, /* copy only comment (COM) markers */ +- JCOPYOPT_ALL /* copy all optional markers */ ++ JCOPYOPT_ALL, /* copy all optional markers */ ++ JCOPYOPT_EXIF /* copy Exif APP1 marker */ + } JCOPY_OPTION; + + #define JCOPYOPT_DEFAULT JCOPYOPT_COMMENTS /* recommended default */ |