Page 1 of 1

pict coder bug

Posted: 2006-11-24T22:59:25-07:00
by el_supremo
I've think I've found the problem with pict.c reported in http://redux.imagemagick.org/discussion ... php?t=7875
As I mentioned in that thread, there's a difference between the way that pict.c writes the resolutions and the way that it reads them.
The error appears to be in the way that they are read because if I fix up the read code to conform to the way that it is written, the fixed code can also read a PCT image produced from PSPX (my debugging also showed that PSPX must be writing the resolutions in the same way as the pict.c code, which is why I've assumed that it's the read that is wrong).
I found some sample PCT images on the web (http://www.fileformat.info/format/macpi ... /index.htm) and IM identifies them with the correct resolution. If I use convert to just read a sample PCT and write it as a PCT, PSPX can read the resulting file but if I convert a JPG to PCT, PSPX still can't read it, but this is a start.

The ReadPixmap macro needs to be changed to this so that it reads the resolutions as "short" instead of "long":

Code: Select all

/*
  ImageMagick Macintosh PICT Methods.
*/
#define ReadPixmap(pixmap) \
{ \
  pixmap.version=ReadBlobMSBShort(image); \
  pixmap.pack_type=ReadBlobMSBShort(image); \
  pixmap.pack_size=ReadBlobMSBLong(image); \
  pixmap.horizontal_resolution=ReadBlobMSBShort(image); \
  (void) ReadBlobMSBShort(image); \
  pixmap.vertical_resolution=ReadBlobMSBShort(image); \
  (void) ReadBlobMSBShort(image); \
  pixmap.pixel_type=ReadBlobMSBShort(image); \
  pixmap.bits_per_pixel=ReadBlobMSBShort(image); \
  pixmap.component_count=ReadBlobMSBShort(image); \
  pixmap.component_size=ReadBlobMSBShort(image); \
  pixmap.plane_bytes=ReadBlobMSBLong(image); \
  pixmap.table=ReadBlobMSBLong(image); \
  pixmap.reserved=ReadBlobMSBLong(image); \
}
And then in the ReadPICTImage function make the three following additions.
After this code:

Code: Select all

  /*
    Create black canvas.
  */
  flags=0;
  image->columns=frame.right-frame.left;
  image->rows=frame.bottom-frame.top;
add this:

Code: Select all

  image->x_resolution = DefaultResolution;
  image->y_resolution = DefaultResolution;
  image->units=UndefinedResolution;
After this code:

Code: Select all

            if (pattern != 1)
              ThrowReaderException(CorruptImageError,"UnknownPatternType");
            length=ReadBlobMSBShort(image);
            ReadRectangle(frame);
            ReadPixmap(pixmap);
add this:

Code: Select all

      
			image->x_resolution = pixmap.horizontal_resolution;
			image->y_resolution = pixmap.vertical_resolution;
			image->units=PixelsPerInchResolution;
and after this:

Code: Select all

            if ((code == 0x9a) || (code == 0x9b) ||
                ((bytes_per_line & 0x8000) != 0))
              {
                ReadPixmap(pixmap);
add this:

Code: Select all

				image->x_resolution = pixmap.horizontal_resolution;
				image->y_resolution = pixmap.vertical_resolution;
				image->units=PixelsPerInchResolution;
Pete

Posted: 2006-11-24T23:34:17-07:00
by el_supremo
I found that if I convert a png to pct PSPX can read the resulting image so I had a look at why converting JPG to PCT caused a problem. It turns out that if the input image is a JPG then the pict coder uses JPG compression when it writes out the PCT and there appears to be a bug in this code somewhere. A workaround is to include "-compress none" when converting JPG to PCT.

Pete