2009.12.10 18:28 "[Tiff] YCbCr", by Steve Mills

2010.01.14 16:02 "Re: [Tiff] JPEG compression in 3.9.2", by Richard Nolde

On 01/14/2010 04:35 AM, jcupitt@gmail.com wrote:

I just ran into this problem as well. TIFFReadEncodedStrip() seems to write beyond the end of it's buffer for subsampled JPEG YCbCr images.

I did not have the problem of writing beyond the end of the buffer because I allocated a buffer large enough for the upsampled data to begin with. My experience was that the amount of data returned was only half of what I expected when the data was subsampled.

I was able to get it working by adding this case to my reader:

        case PHOTOMETRIC_YCBCR:
                TIFFSetField( tiff, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB );
                parse_rgb8(...
                break;

ie. by asking libjpeg to convert YCbCr to rgb on load. Not a good solution if you actually want YCbCR of course, but it did fix my crashes.

John,
    Thanks for your note. I was using a much broader brush with the
following in the code to load the image:

   if (input_compression == COMPRESSION_JPEG)
     {
     jpegcolormode = JPEGCOLORMODE_RGB;
     TIFFSetField(in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
     }

and the following in the code to write the image.

   TIFFGetField(in, TIFFTAG_JPEGCOLORMODE, &input_jpeg_colormode);
#ifdef DEBUG2
   TIFFError("writeSingleSection", "Input compression: %s",
         (input_compression == COMPRESSION_OJPEG)? "Old Jpeg":
         ((input_compression == COMPRESSION_JPEG)? "New Jpeg": "Non
Jpeg"));
#endif
   if (compression == COMPRESSION_JPEG)
     {
     if ((input_photometric == PHOTOMETRIC_PALETTE) || /* color map
indexed */
         (input_photometric == PHOTOMETRIC_MASK)) /* $holdout mask */
       {
       TIFFError ("writeSingleSection",
                  "JPEG compression cannot be used with %s image data",
          (input_photometric == PHOTOMETRIC_PALETTE)?
                  "palette": "mask");
       return (-1);
       }
     if (input_photometric == PHOTOMETRIC_RGB)
       {
       if (jpegcolormode == JPEGCOLORMODE_RGB)
     TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
       else
     TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
       }
     else
     TIFFSetField(out, TIFFTAG_PHOTOMETRIC, input_photometric);
     }

Based on what I've been reading on the list, I may need to put some of the code that is in the output logic into the input logic. I was trying to handle the case of YCbCr separately from OJPEG and new JPEG and finally gave up. It should be possible to have YCrCr data that is not JPEG (Old or New) compressed. I was hoping that Lee Howard's work might simplify this before I returned to my code as my attempts to wade through the JPEG interface in Libtiff did not get me very far.

Richard