diff options
author | Dirk Meyer <dinoex@FreeBSD.org> | 2004-03-18 14:53:47 +0000 |
---|---|---|
committer | Dirk Meyer <dinoex@FreeBSD.org> | 2004-03-18 14:53:47 +0000 |
commit | 7a318b355a4c52d62ee6070475839a2eb7bb9d98 (patch) | |
tree | a9079928dc93bc9bc303b756fc34276b012bfc80 /graphics/jpeg-mmx/files/patch-transupp.c | |
parent | - Remove dead WWW (diff) |
- 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-mmx/files/patch-transupp.c')
-rw-r--r-- | graphics/jpeg-mmx/files/patch-transupp.c | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/graphics/jpeg-mmx/files/patch-transupp.c b/graphics/jpeg-mmx/files/patch-transupp.c new file mode 100644 index 000000000000..48927aa80bc0 --- /dev/null +++ b/graphics/jpeg-mmx/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 && |