2000.04.17 00:03 "libtiff crash with tiled jpeg (was: unknown tag 33918)", by Tom Lane
Tiffcp creates files it does not read correctly.
To reproduce:
Create a tiled RGB JPEG with tiffcp, then try to convert that file to some other type. tiffcp will crash. Note that the file created seems to be good, it is just that tiffcp cannot read files of this type correctly.
Ed,
This jogged my memory a little bit. I think I fixed the problem in my private copy a long time ago, and then forgot to submit the patch :-(. Mea maxima culpa. Try the attached patch and see if it helps.
This diff is against three-year-old sources, but it looks like tiffcp hasn't changed too much...
regards, tom lane
organizer, Independent JPEG Group
*** tools/tiffcp.c.orig Tue Sep 2 13:54:39 1997
--- tools/tiffcp.c Fri Oct 3 00:10:22 1997
***************
*** 42,47 ****
--- 42,49 ----
#define TRUE 1
#define FALSE 0
+ /* working copies of encoding parameters: these can change for each image */
+
static int outtiled = -1;
static uint32 tilewidth;
static uint32 tilelength;
***************
*** 52,61 ****
static uint16 fillorder;
static uint32 rowsperstrip;
static uint32 g3opts;
static int ignore = FALSE; /* if true, ignore read errors */
static uint32 defg3opts = (uint32) -1;
static int quality = 75; /* JPEG quality */
! static int jpegcolormode = JPEGCOLORMODE_RGB;
static uint16 defcompression = (uint16) -1;
static uint16 defpredictor = (uint16) -1;
--- 54,67 ----
static uint16 fillorder;
static uint32 rowsperstrip;
static uint32 g3opts;
+ static int jpegcolormode;
+
+ /* encoding parameters given by user switches: these do not change per image */
+
static int ignore = FALSE; /* if true, ignore read errors */
static uint32 defg3opts = (uint32) -1;
static int quality = 75; /* JPEG quality */
! static int defjpegcolormode = JPEGCOLORMODE_RGB;
static uint16 defcompression = (uint16) -1;
static uint16 defpredictor = (uint16) -1;
***************
*** 171,176 ****
--- 177,183 ----
tilewidth = deftilewidth;
tilelength = deftilelength;
g3opts = defg3opts;
+ jpegcolormode = defjpegcolormode;
if (!tiffcp(in, out) || !TIFFWriteDirectory(out)) {
(void) TIFFClose(out);
return (1);
***************
*** 183,188 ****
--- 190,209 ----
}
static void
+ processJPEGOptions(char* cp)
+ {
+ while (cp = strchr(cp, ':')) {
+ cp++;
+ if (isdigit(*cp))
+ quality = atoi(cp);
+ else if (*cp == 'r')
+ defjpegcolormode = JPEGCOLORMODE_RAW;
+ else
+ usage();
+ }
+ }
+
+ static void
processG3Options(char* cp)
{
if (cp = strchr(cp, ':')) {
***************
*** 210,220 ****
} else if (streq(opt, "packbits")) {
defcompression = COMPRESSION_PACKBITS;
} else if (strneq(opt, "jpeg", 4)) {
! char* cp = strchr(opt, ':');
! if (cp && isdigit(cp[1]))
! quality = atoi(cp+1);
! if (cp && strchr(cp, 'r'))
! jpegcolormode = JPEGCOLORMODE_RAW;
defcompression = COMPRESSION_JPEG;
} else if (strneq(opt, "g3", 2)) {
processG3Options(opt);
--- 231,237 ----
} else if (streq(opt, "packbits")) {
defcompression = COMPRESSION_PACKBITS;
} else if (strneq(opt, "jpeg", 4)) {
! processJPEGOptions(opt);
defcompression = COMPRESSION_JPEG;
} else if (strneq(opt, "g3", 2)) {
processG3Options(opt);
***************
*** 426,431 ****
--- 443,449 ----
uint16 bitspersample, samplesperpixel;
copyFunc cf;
uint32 w, l;
+ uint16 sourcephoto;
struct cpTag* p;
CopyField(TIFFTAG_IMAGEWIDTH, w);
***************
*** 436,449 ****
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
else
CopyField(TIFFTAG_COMPRESSION, compression);
! if (compression == COMPRESSION_JPEG && jpegcolormode == JPEGCOLORMODE_RGB)
! TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
! else if (compression == COMPRESSION_SGILOG || compression == COMPRESSION_SGILOG24)
TIFFSetField(out, TIFFTAG_PHOTOMETRIC,
samplesperpixel == 1 ?
PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
! else
! CopyTag(TIFFTAG_PHOTOMETRIC, 1, TIFF_SHORT);
if (fillorder != 0)
TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
else
--- 454,482 ----
TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
else
CopyField(TIFFTAG_COMPRESSION, compression);
! CopyField(TIFFTAG_PHOTOMETRIC, sourcephoto);
! /*
! * Certain combinations of compression and colorspace are overridden;
! * essentially we provide free colorspace conversion in these cases.
! */
! if (compression == COMPRESSION_JPEG) {
! /* If RGB->YCbCr conversion is enabled and appropriate,
! * change PhotometricInterpretation to suit.
! * Otherwise, set JPEGCOLORMODE_RAW so that the JPEG codec
! * isn't fooled if, say, the input Photometric is YCbCr.
! */
! if (jpegcolormode == JPEGCOLORMODE_RGB &&
! sourcephoto == PHOTOMETRIC_RGB &&
! samplesperpixel == 3)
! TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
! else
! jpegcolormode = JPEGCOLORMODE_RAW;
! } else if (compression == COMPRESSION_SGILOG ||
! compression == COMPRESSION_SGILOG24) {
TIFFSetField(out, TIFFTAG_PHOTOMETRIC,
samplesperpixel == 1 ?
PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV);
! }
if (fillorder != 0)
TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
else