2011.06.09 05:34 "Re: [Tiff] Patch for tif_ojpeg version 3.9.5", by Andreas Kleinert
Yes, as OJPEG is known to be broken (und thus deprecated) anyway, it can't hurt to improve libtiff's capability to read out what is there (and hopefully more easily allow to convert it to something less broken)...
-------- Original Message --------
I for one would certainly be very interested in these changes, if they can be reasonably verified not to cause problems for anyone else. The author's description of what he has changed and why seems reasonable to me, but I have not considered it in great detail. However, I do work with some files that currently fail to open properly using libtiff, and it sounds like these changes might fix those problems.
----- Original Message -----
Sent: Wednesday, June 08, 2011 17:32
Subject: [Tiff] Patch for tif_ojpeg version 3.9.5
I have received some TIFF_OJPEG images that doesn't open in LibTIFF 3.9.5, and I found that after some code changes in LibTIFF it could be opened. We would like to know if anybody is interested in evaluating our changes, to see if they are useful for inclusion into LibTIFF. Description of the problems found in my TIFF_OJPEG images:
- JPEGInterchangeFormat doesn't point to the exact start of a JPEG marker. Instead, it points to the character "J" in the "JFIF" which is not a JPEG marker itself, but a magic number inside the APP_0 segment.
- On the other hand, StripOffset points to the correct JPEG marker, SOI (Start of Image, 0xFF 0xD8) as would be expected by LibTIFF.
- I found that LibTIFF leans toward JPEGInterchangeFormat when both tags are present. So, one of my change is to try JPEGInterchangeFormat first (to keep the same behavior as LibTIFF), and if it fails try StripOffset or TileOffset for second chance. To make it faster, I do a quick test of the first byte to see if it is 0xFF.
- This is implemented by splitting the OJPEGReadHeaderInfoSec function into two parts: the first part (keeping the same function name) is responsible for trying both start addresses. The second part, in a new function named OJPEGReadHeaderInfoSecStream, will take a start address and start parsing the JPEG markers.
- The remaining problems with my TIFF_OJPEG images are related to mismatches between what is stored in the TIFF IFD and the actual parameters that are required to decode the JPEG datastream. There is already an "OJPEG parameter correction routine" in LibTIFF, named "OJPEGSubsamplingCorrect". I added more rules to fix the issues in my images. In particular, some images have wrong BitsPerSample (e.g. 4 in a grayscale OJPEG image), wrong SamplesPerPixel (e.g. 1 in a YCbCr OJPEG image or 3 in a grayscale OJPEG image), and Photometric (using a color Photometric in a grayscale OJPEG image or vice versa)
- Because TIFF calculates the memory buffer sizes based on the TIFF IFD values, the "parameter correction" needs to be triggered early enough to prevent the wrong buffer size being used during decoding. For this reason, I modified "tif_dirread.c" so that for TIFF_OJPEG images, it will trigger "tif_ojpeg.c" to run the correction routine, so that the first call to "GetField" will fetch the right values.
- There is one more code change in OJPEGPostDecode, which allows single-strip OJPEG images (with or without YCbCr subsampling) to be decoded by TIFFReadScanline.
- I would like to hear any feedback you have about my code changes. If you want me to try to subdivide the patch into smaller changes, please let me know.