1 /*
2  * xvtiff.c - load routine for 'TIFF' format pictures
3  *
4  * LoadTIFF(fname, numcols, quick)  -  load a TIFF file
5  */
6 
7 #ifndef va_start
8 #  define NEEDSARGS
9 #endif
10 
11 #include "xv.h"
12 
13 #ifdef HAVE_TIFF
14 
15 #include "tiffio.h"     /* has to be after xv.h, as it needs varargs/stdarg */
16 
17 
18 /* Portions fall under the following copyright:
19  *
20  * Copyright (c) 1992, 1993, 1994 Sam Leffler
21  * Copyright (c) 1992, 1993, 1994 Silicon Graphics, Inc.
22  *
23  * Permission to use, copy, modify, distribute, and sell this software and
24  * its documentation for any purpose is hereby granted without fee, provided
25  * that (i) the above copyright notices and this permission notice appear in
26  * all copies of the software and related documentation, and (ii) the names of
27  * Sam Leffler and Silicon Graphics may not be used in any advertising or
28  * publicity relating to the software without the specific, prior written
29  * permission of Sam Leffler and Silicon Graphics.
30  *
31  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
33  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
34  *
35  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
36  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
37  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
38  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
39  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
40  * OF THIS SOFTWARE.
41  */
42 
43 
44 static int   copyTiff    PARM((TIFF *, char *));
45 static int   cpStrips    PARM((TIFF *, TIFF *));
46 static int   cpTiles     PARM((TIFF *, TIFF *));
47 static byte *loadPalette PARM((TIFF *, uint32, uint32, int, int, PICINFO *));
48 static byte *loadColor   PARM((TIFF *, uint32, uint32, int, int, PICINFO *));
49 static int   loadImage   PARM((TIFF *, uint32, uint32, byte *, int));
50 static void  _TIFFerr    PARM((const char *, const char *, va_list));
51 static void  _TIFFwarn   PARM((const char *, const char *, va_list));
52 
53 static long  filesize;
54 static byte *rmap, *gmap, *bmap;
55 static const char *filename;
56 
57 static int   error_occurred;
58 
59 
60 /*******************************************/
LoadTIFF(fname,pinfo,quick)61 int LoadTIFF(fname, pinfo, quick)
62      char    *fname;
63      PICINFO *pinfo;
64      int      quick;
65 /*******************************************/
66 {
67   /* returns '1' on success, '0' on failure */
68 
69   TIFF  *tif;
70   uint32 w, h;
71   float  xres, yres;
72   short	 bps, spp, photo, orient;
73   FILE  *fp;
74   byte  *pic8;
75   char  *desc, oldpath[MAXPATHLEN+1], tmppath[MAXPATHLEN+1], *sp;
76   char   tmp[256], tmpname[256];
77   int    i, nump;
78 
79   error_occurred = 0;
80 
81   pinfo->type = PIC8;
82 
83   TIFFSetErrorHandler(_TIFFerr);
84   TIFFSetWarningHandler(_TIFFwarn);
85 
86   /* open the stream to find out filesize (for info box) */
87   fp = fopen(fname,"r");
88   if (!fp) {
89     TIFFError("LoadTIFF()", "couldn't open file");
90     return 0;
91   }
92 
93   fseek(fp, 0L, 2);
94   filesize = ftell(fp);
95   fclose(fp);
96 
97 
98 
99   rmap = pinfo->r;  gmap = pinfo->g;  bmap = pinfo->b;
100 
101   /* a kludge:  temporarily cd to the directory that the file is in (if
102      the file has a path), and cd back when done, as I can't make the
103      various TIFF error messages print the simple filename */
104 
105   filename = fname;    /* use fullname unless it all works out */
106   oldpath[0] = '\0';
107   if (fname[0] == '/') {
108     xv_getwd(oldpath, sizeof(oldpath));
109     strcpy(tmppath, fname);
110     sp = (char *) BaseName(tmppath);  /* intentionally losing constness */
111     if (sp != tmppath) {
112       sp[-1] = '\0';     /* truncate before last '/' char */
113       if (chdir(tmppath)) {
114 	oldpath[0] = '\0';
115       }
116       else filename = BaseName(fname);
117     }
118   }
119 
120 
121   nump = 1;
122 
123   if (!quick) {
124     /* see if there's more than 1 image in tiff file, to determine if we
125        should do multi-page thing... */
126 
127     tif = TIFFOpen(filename, "r");
128     if (!tif) return 0;
129     while (TIFFReadDirectory(tif)) ++nump;
130     TIFFClose(tif);
131     if (DEBUG)
132       fprintf(stderr,"LoadTIFF: %d page%s found\n", nump, nump==1 ? "" : "s");
133 
134 
135     /* if there are multiple images, copy them out to multiple tmp files,
136        and load the first one... */
137 
138     if (nump>1) {
139       TIFF *in;
140 
141       /* GRR 20050320:  converted this fake mktemp() to use mktemp()/mkstemp()
142          internally (formerly it simply prepended tmpdir to the string and
143          returned immediately) */
144       xv_mktemp(tmpname, "xvpgXXXXXX");
145 
146       if (tmpname[0] == '\0') {   /* mktemp() or mkstemp() blew up */
147         sprintf(dummystr,"LoadTIFF: Unable to create temporary filename???");
148         ErrPopUp(dummystr, "\nHow unlikely!");
149         return 0;
150       }
151 
152       /* GRR 20070506:  could clean up unappended tmpname-file here (Linux
153          bug?), but "cleaner" (more general) to do so in KillPageFiles() */
154 
155       in = TIFFOpen(filename, "r");
156       if (!in) return 0;
157       for (i=1; i<=nump; i++) {
158 	sprintf(tmp, "%s%d", tmpname, i);
159 	if (!copyTiff(in, tmp)) {
160 	  SetISTR(ISTR_WARNING, "LoadTIFF:  Error writing page files!");
161 	  break;
162 	}
163 
164 	if (!TIFFReadDirectory(in)) break;
165       }
166       TIFFClose(in);
167       if (DEBUG)
168 	fprintf(stderr,"LoadTIFF: %d page%s written\n",
169 		i-1, (i-1)==1 ? "" : "s");
170 
171       sprintf(tmp, "%s%d", tmpname, 1);           /* start with page #1 */
172       filename = tmp;
173     }
174   }  /* if (!quick) ... */
175 
176 
177   tif = TIFFOpen(filename, "r");
178   if (!tif) return 0;
179 
180   /* flip orientation so that image comes in X order */
181   TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &orient);
182   switch (orient) {
183   case ORIENTATION_TOPLEFT:
184   case ORIENTATION_TOPRIGHT:
185   case ORIENTATION_LEFTTOP:
186   case ORIENTATION_RIGHTTOP:   orient = ORIENTATION_BOTLEFT;   break;
187 
188   case ORIENTATION_BOTRIGHT:
189   case ORIENTATION_BOTLEFT:
190   case ORIENTATION_RIGHTBOT:
191   case ORIENTATION_LEFTBOT:    orient = ORIENTATION_TOPLEFT;   break;
192   }
193 
194   TIFFSetField(tif, TIFFTAG_ORIENTATION, orient);
195 
196   TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
197   TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
198   TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bps);
199   TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photo);
200   TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &spp);
201   if ((TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres) == 1) &&
202       (TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres) == 1)) {
203     normaspect = yres / xres;
204     if (DEBUG) fprintf(stderr,"TIFF aspect = %f\n", normaspect);
205   }
206 
207   if (spp == 1) {
208       pic8 = loadPalette(tif, w, h, photo, bps, pinfo);
209   } else {
210       pic8 = loadColor(tif, w, h, photo, bps, pinfo);
211   }
212 
213   /* try to get comments, if any */
214   pinfo->comment = (char *) NULL;
215 
216   desc = (char *) NULL;
217 
218   TIFFGetField(tif, TIFFTAG_IMAGEDESCRIPTION, &desc);
219   if (desc && strlen(desc) > (size_t) 0) {
220     /* kludge:  tiff library seems to return bizarre comments */
221     if (strlen(desc)==4 && strcmp(desc, "\367\377\353\370")==0) {}
222     else {
223       pinfo->comment = (char *) malloc(strlen(desc) + 1);
224       if (pinfo->comment) strcpy(pinfo->comment, desc);
225     }
226   }
227 
228   TIFFClose(tif);
229 
230   /* un-kludge */
231   if (oldpath[0] != '\0') chdir(oldpath);
232 
233 
234   if (error_occurred) {
235     if (pic8) free(pic8);
236     if (pinfo->comment) free(pinfo->comment);
237     pinfo->comment = (char *) NULL;
238     if (!quick && nump>1) KillPageFiles(tmpname, nump);
239     SetCursors(-1);
240     return 0;
241   }
242 
243 
244   pinfo->pic = pic8;
245   pinfo->w = w;  pinfo->h = h;
246   pinfo->normw = pinfo->w;   pinfo->normh = pinfo->h;
247   pinfo->frmType = F_TIFF;
248 
249   if (nump>1) strcpy(pinfo->pagebname, tmpname);
250   pinfo->numpages = nump;
251 
252   if (pinfo->pic) return 1;
253 
254 
255   /* failed.  if we malloc'd a comment, free it */
256   if (pinfo->comment) free(pinfo->comment);
257   pinfo->comment = (char *) NULL;
258 
259   if (!quick && nump>1) KillPageFiles(tmpname, nump);
260   SetCursors(-1);
261 
262   return 0;
263 }
264 
265 
266 
267 
268 /*******************************************/
269 
270 #define CopyField(tag, v) \
271   if (TIFFGetField(in, tag, &v))            TIFFSetField(out, tag, v)
272 #define CopyField2(tag, v1, v2) \
273   if (TIFFGetField(in, tag, &v1, &v2))      TIFFSetField(out, tag, v1, v2)
274 #define CopyField3(tag, v1, v2, v3) \
275   if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
276 
277 
278 /*******************************************/
copyTiff(in,fname)279 static int copyTiff(in, fname)
280      TIFF *in;
281      char *fname;
282 {
283   /* copies tiff (sub)image to given filename.  (Used only for multipage
284      images.)  Returns 0 on error */
285 
286   TIFF   *out;
287   short   bitspersample, samplesperpixel, shortv, *shortav;
288   uint32  w, l;
289   float   floatv, *floatav;
290   char   *stringv;
291   uint32  longv;
292   uint16 *red, *green, *blue, shortv2;
293   int     rv;
294 
295   out = TIFFOpen(fname, "w");
296   if (!out) return 0;
297 
298   if (TIFFGetField(in, TIFFTAG_COMPRESSION, &shortv)){
299     /* Currently, the TIFF Library cannot correctly copy TIFF version 6.0 (or
300      * earlier) files that use "old" JPEG compression, so don't even try. */
301     if (shortv == COMPRESSION_OJPEG) return 0;
302     TIFFSetField(out, TIFFTAG_COMPRESSION, shortv);
303   }
304   CopyField (TIFFTAG_SUBFILETYPE,         longv);
305   CopyField (TIFFTAG_TILEWIDTH,           w);
306   CopyField (TIFFTAG_TILELENGTH,          l);
307   CopyField (TIFFTAG_IMAGEWIDTH,          w);
308   CopyField (TIFFTAG_IMAGELENGTH,         l);
309   CopyField (TIFFTAG_BITSPERSAMPLE,       bitspersample);
310   CopyField (TIFFTAG_PREDICTOR,           shortv);
311   CopyField (TIFFTAG_PHOTOMETRIC,         shortv);
312   CopyField (TIFFTAG_THRESHHOLDING,       shortv);
313   CopyField (TIFFTAG_FILLORDER,           shortv);
314   CopyField (TIFFTAG_ORIENTATION,         shortv);
315   CopyField (TIFFTAG_SAMPLESPERPIXEL,     samplesperpixel);
316   CopyField (TIFFTAG_MINSAMPLEVALUE,      shortv);
317   CopyField (TIFFTAG_MAXSAMPLEVALUE,      shortv);
318   CopyField (TIFFTAG_XRESOLUTION,         floatv);
319   CopyField (TIFFTAG_YRESOLUTION,         floatv);
320   CopyField (TIFFTAG_GROUP3OPTIONS,       longv);
321   CopyField (TIFFTAG_GROUP4OPTIONS,       longv);
322   CopyField (TIFFTAG_RESOLUTIONUNIT,      shortv);
323   CopyField (TIFFTAG_PLANARCONFIG,        shortv);
324   CopyField (TIFFTAG_ROWSPERSTRIP,        longv);
325   CopyField (TIFFTAG_XPOSITION,           floatv);
326   CopyField (TIFFTAG_YPOSITION,           floatv);
327   CopyField (TIFFTAG_IMAGEDEPTH,          longv);
328   CopyField (TIFFTAG_TILEDEPTH,           longv);
329   CopyField2(TIFFTAG_EXTRASAMPLES,        shortv, shortav);
330   CopyField3(TIFFTAG_COLORMAP,            red, green, blue);
331   CopyField2(TIFFTAG_PAGENUMBER,          shortv, shortv2);
332   CopyField (TIFFTAG_ARTIST,              stringv);
333   CopyField (TIFFTAG_IMAGEDESCRIPTION,    stringv);
334   CopyField (TIFFTAG_MAKE,                stringv);
335   CopyField (TIFFTAG_MODEL,               stringv);
336   CopyField (TIFFTAG_SOFTWARE,            stringv);
337   CopyField (TIFFTAG_DATETIME,            stringv);
338   CopyField (TIFFTAG_HOSTCOMPUTER,        stringv);
339   CopyField (TIFFTAG_PAGENAME,            stringv);
340   CopyField (TIFFTAG_DOCUMENTNAME,        stringv);
341   CopyField2(TIFFTAG_JPEGTABLES,          longv, stringv);
342   CopyField (TIFFTAG_YCBCRCOEFFICIENTS,   floatav);
343   CopyField2(TIFFTAG_YCBCRSUBSAMPLING,    shortv,shortv2);
344   CopyField (TIFFTAG_YCBCRPOSITIONING,    shortv);
345   CopyField (TIFFTAG_REFERENCEBLACKWHITE, floatav);
346 
347   if (TIFFIsTiled(in)) rv = cpTiles (in, out);
348                   else rv = cpStrips(in, out);
349 
350   TIFFClose(out);
351   return rv;
352 }
353 
354 
355 /*******************************************/
cpStrips(in,out)356 static int cpStrips(in, out)
357      TIFF *in, *out;
358 {
359   tsize_t bufsize;
360   byte *buf;
361 
362   bufsize = TIFFStripSize(in);
363   if (bufsize <= 0) return 0;  /* tsize_t is signed */
364   buf = (byte *) malloc((size_t) bufsize);
365   if (buf) {
366     tstrip_t s, ns = TIFFNumberOfStrips(in);
367     uint32 *bytecounts;
368 
369     TIFFGetField(in, TIFFTAG_STRIPBYTECOUNTS, &bytecounts);
370     for (s = 0; s < ns; s++) {
371       if (bytecounts[s] > bufsize) {
372 	buf = (unsigned char *) realloc(buf, (size_t) bytecounts[s]);
373 	if (!buf) return (0);
374 	bufsize = bytecounts[s];
375       }
376       if (TIFFReadRawStrip (in,  s, buf, (tsize_t) bytecounts[s]) < 0 ||
377 	  TIFFWriteRawStrip(out, s, buf, (tsize_t) bytecounts[s]) < 0) {
378 	free(buf);
379 	return 0;
380       }
381     }
382     free(buf);
383     return 1;
384   }
385   return 0;
386 }
387 
388 
389 /*******************************/
cpTiles(in,out)390 static int cpTiles(in, out)
391      TIFF *in, *out;
392 {
393   tsize_t bufsize;
394   byte   *buf;
395 
396   bufsize = TIFFTileSize(in);
397   if (bufsize <= 0) return 0;  /* tsize_t is signed */
398   buf = (unsigned char *) malloc((size_t) bufsize);
399   if (buf) {
400     ttile_t t, nt = TIFFNumberOfTiles(in);
401     uint32 *bytecounts;
402 
403     TIFFGetField(in, TIFFTAG_TILEBYTECOUNTS, &bytecounts);
404     for (t = 0; t < nt; t++) {
405       if (bytecounts[t] > bufsize) {
406 	buf = (unsigned char *)realloc(buf, (size_t) bytecounts[t]);
407 	if (!buf) return (0);
408 	bufsize = bytecounts[t];
409       }
410       if (TIFFReadRawTile (in,  t, buf, (tsize_t) bytecounts[t]) < 0 ||
411 	  TIFFWriteRawTile(out, t, buf, (tsize_t) bytecounts[t]) < 0) {
412 	free(buf);
413 	return 0;
414       }
415     }
416     free(buf);
417     return 1;
418   }
419   return 0;
420 }
421 
422 
423 /*******************************************/
loadPalette(tif,w,h,photo,bps,pinfo)424 static byte *loadPalette(tif, w, h, photo, bps, pinfo)
425      TIFF *tif;
426      uint32 w,h;
427      int   photo,bps;
428      PICINFO *pinfo;
429 {
430   byte *pic8;
431   uint32 npixels;
432 
433   switch (photo) {
434   case PHOTOMETRIC_PALETTE:
435     pinfo->colType = F_FULLCOLOR;
436     sprintf(pinfo->fullInfo, "TIFF, %u-bit, palette format.  (%ld bytes)",
437 	    bps, filesize);
438     break;
439 
440   case PHOTOMETRIC_MINISWHITE:
441   case PHOTOMETRIC_MINISBLACK:
442     pinfo->colType = (bps==1) ? F_BWDITHER : F_GREYSCALE;
443     sprintf(pinfo->fullInfo,"TIFF, %u-bit, %s format.  (%ld bytes)",
444 	    bps,
445 	    photo == PHOTOMETRIC_MINISWHITE ? "min-is-white" :
446 	    "min-is-black",
447 	    filesize);
448     break;
449   }
450 
451   sprintf(pinfo->shrtInfo, "%ux%u TIFF.",(u_int) w, (u_int) h);
452 
453   npixels = w*h;
454   if (npixels/w != h) {
455     /* SetISTR(ISTR_WARNING, "loadPalette() - image dimensions too large"); */
456     TIFFError(filename, "Image dimensions too large");
457     return (byte *) NULL;
458   }
459 
460   pic8 = (byte *) malloc((size_t) npixels);
461   if (!pic8) FatalError("loadPalette() - couldn't malloc 'pic8'");
462 
463   if (loadImage(tif, w, h, pic8, 0)) return pic8;
464 
465   return (byte *) NULL;
466 }
467 
468 
469 /*******************************************/
loadColor(tif,w,h,photo,bps,pinfo)470 static byte *loadColor(tif, w, h, photo, bps, pinfo)
471      TIFF *tif;
472      uint32 w,h;
473      int   photo,bps;
474      PICINFO *pinfo;
475 {
476   byte *pic24, *pic8;
477   uint32 npixels, count;
478 
479   pinfo->colType = F_FULLCOLOR;
480   sprintf(pinfo->fullInfo, "TIFF, %u-bit, %s format.  (%ld bytes)",
481 	  bps,
482 	  (photo == PHOTOMETRIC_RGB ?	"RGB" :
483 	   photo == PHOTOMETRIC_YCBCR ?	"YCbCr" :
484 	   "???"),
485 	  filesize);
486 
487   sprintf(pinfo->shrtInfo, "%ux%u TIFF.",(u_int) w, (u_int) h);
488 
489   npixels = w*h;
490   count = 3*npixels;
491   if (npixels/w != h || count/3 != npixels) {
492     /* SetISTR(ISTR_WARNING, "loadPalette() - image dimensions too large"); */
493     TIFFError(filename, "Image dimensions too large");
494     return (byte *) NULL;
495   }
496 
497   /* allocate 24-bit image */
498   pic24 = (byte *) malloc((size_t) count);
499   if (!pic24) FatalError("loadColor() - couldn't malloc 'pic24'");
500 
501   pic8 = (byte *) NULL;
502 
503   if (loadImage(tif, w, h, pic24, 0)) {
504     pinfo->type = PIC24;
505     pic8 = pic24;
506   }
507   else free(pic24);
508 
509   return pic8;
510 }
511 
512 
513 /*******************************************/
_TIFFerr(module,fmt,ap)514 static void _TIFFerr(module, fmt, ap)
515      const char *module;
516      const char *fmt;
517      va_list     ap;
518 {
519   char buf[2048];
520   char *cp = buf;
521 
522   if (module != NULL) {
523     sprintf(cp, "%s: ", module);
524     cp = (char *) index(cp, '\0');
525   }
526 
527   vsprintf(cp, fmt, ap);
528   strcat(cp, ".");
529 
530   SetISTR(ISTR_WARNING, "%s", buf);
531 
532   error_occurred = 1;
533 }
534 
535 
536 /*******************************************/
_TIFFwarn(module,fmt,ap)537 static void _TIFFwarn(module, fmt, ap)
538      const char *module;
539      const char *fmt;
540      va_list     ap;
541 {
542   char buf[2048];
543   char *cp = buf;
544 
545   if (module != NULL) {
546     sprintf(cp, "%s: ", module);
547     cp = (char *) index(cp, '\0');
548   }
549   strcpy(cp, "Warning, ");
550   cp = (char *) index(cp, '\0');
551   vsprintf(cp, fmt, ap);
552   strcat(cp, ".");
553 
554   SetISTR(ISTR_WARNING, "%s", buf);
555 }
556 
557 
558 
559 
560 
561 
562 typedef	byte RGBvalue;
563 
564 static	u_short bitspersample;
565 static	u_short samplesperpixel;
566 static	u_short photometric;
567 static	u_short orientation;
568 
569 /* colormap for pallete images */
570 static	u_short *redcmap, *greencmap, *bluecmap;
571 static	int      stoponerr;			/* stop on read error */
572 
573 /* YCbCr support */
574 static	u_short YCbCrHorizSampling;
575 static	u_short YCbCrVertSampling;
576 static	float   *YCbCrCoeffs;
577 static	float   *refBlackWhite;
578 
579 static	byte **BWmap;
580 static	byte **PALmap;
581 
582 /* XXX Work around some collisions with the new library. */
583 #define tileContigRoutine _tileContigRoutine
584 #define tileSeparateRoutine _tileSeparateRoutine
585 
586 typedef void (*tileContigRoutine)   PARM((byte*, u_char*, RGBvalue*,
587 					  uint32, uint32, int, int));
588 
589 typedef void (*tileSeparateRoutine) PARM((byte*, u_char*, u_char*, u_char*,
590                                          RGBvalue*, uint32, uint32, int, int));
591 
592 
593 static int    checkcmap             PARM((int, u_short*, u_short*, u_short*));
594 
595 static int    gt                       PARM((TIFF *, uint32, uint32, byte *));
596 static uint32 setorientation           PARM((TIFF *, uint32));
597 static int    gtTileContig             PARM((TIFF *, byte *, RGBvalue *,
598 					     uint32, uint32, int));
599 static int    gtTileSeparate           PARM((TIFF *, byte *, RGBvalue *,
600 					     uint32, uint32, int));
601 static int    gtStripContig            PARM((TIFF *, byte *, RGBvalue *,
602 					     uint32, uint32, int));
603 static int    gtStripSeparate          PARM((TIFF *, byte *, RGBvalue *,
604 					     uint32, uint32, int));
605 
606 static int    makebwmap                PARM((void));
607 static int    makecmap                 PARM((void));
608 
609 static void   put8bitcmaptile          PARM((byte *, u_char *, RGBvalue *,
610 					     uint32, uint32, int, int));
611 static void   put4bitcmaptile          PARM((byte *, u_char *, RGBvalue *,
612 					     uint32, uint32, int, int));
613 static void   put2bitcmaptile          PARM((byte *, u_char *, RGBvalue *,
614 					     uint32, uint32, int, int));
615 static void   put1bitcmaptile          PARM((byte *, u_char *, RGBvalue *,
616 					     uint32, uint32, int, int));
617 static void   putgreytile              PARM((byte *, u_char *, RGBvalue *,
618 					     uint32, uint32, int, int));
619 static void   put1bitbwtile            PARM((byte *, u_char *, RGBvalue *,
620 					     uint32, uint32, int, int));
621 static void   put2bitbwtile            PARM((byte *, u_char *, RGBvalue *,
622 					     uint32, uint32, int, int));
623 static void   put4bitbwtile            PARM((byte *, u_char *, RGBvalue *,
624 					     uint32, uint32, int, int));
625 static void   put16bitbwtile           PARM((byte *, u_short *, RGBvalue *,
626 					     uint32, uint32, int, int));
627 
628 static void   putRGBcontig8bittile     PARM((byte *, u_char *, RGBvalue *,
629 					     uint32, uint32, int, int));
630 
631 static void   putRGBcontig16bittile    PARM((byte *, u_short *, RGBvalue *,
632 					     uint32, uint32, int, int));
633 
634 static void   putRGBseparate8bittile   PARM((byte *, u_char *, u_char *,
635 					     u_char *, RGBvalue *,
636 					     uint32, uint32, int, int));
637 
638 static void   putRGBseparate16bittile  PARM((byte *, u_short *, u_short *,
639 					    u_short *, RGBvalue *,
640 					    uint32, uint32, int, int));
641 
642 
643 static void   initYCbCrConversion      PARM((void));
644 
645 static void   putRGBContigYCbCrClump   PARM((byte *, u_char *, int, int,
646 					     uint32, int, int, int));
647 
648 static void   putRGBSeparateYCbCrClump PARM((byte *, u_char *, u_char *,
649 					     u_char *, int, int, uint32, int,
650 					     int, int));
651 
652 static void   putRGBSeparate16bitYCbCrClump PARM((byte *, u_short *, u_short *,
653 						  u_short *, int, int, uint32,
654 						  int, int, int));
655 
656 static void   putcontig8bitYCbCrtile   PARM((byte *, u_char *, RGBvalue *,
657 					     uint32, uint32, int, int));
658 
659 static void   putYCbCrseparate8bittile PARM((byte *, u_char *, u_char *,
660 					     u_char *, RGBvalue *,
661 					     uint32, uint32, int, int));
662 
663 static void   putYCbCrseparate16bittile PARM((byte *, u_short *, u_short *,
664 					      u_short *, RGBvalue *,
665 					      uint32, uint32, int, int));
666 
667 static tileContigRoutine   pickTileContigCase   PARM((RGBvalue *));
668 static tileSeparateRoutine pickTileSeparateCase PARM((RGBvalue *));
669 
670 
671 /*******************************************/
loadImage(tif,rwidth,rheight,raster,stop)672 static int loadImage(tif, rwidth, rheight, raster, stop)
673      TIFF *tif;
674      uint32 rwidth, rheight;
675      byte *raster;
676      int stop;
677 {
678   int ok;
679   uint32 width, height;
680 
681   TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
682   switch (bitspersample) {
683   case 1:
684   case 2:
685   case 4:
686   case 8:
687   case 16:  break;
688 
689   default:
690     TIFFError(TIFFFileName(tif),
691 	      "Sorry, cannot handle %d-bit pictures", bitspersample);
692     return (0);
693   }
694 
695 
696   TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
697   switch (samplesperpixel) {
698   case 1:
699   case 3:
700   case 4:  break;
701 
702   default:
703     TIFFError(TIFFFileName(tif),
704 	      "Sorry, cannot handle %d-channel images", samplesperpixel);
705     return (0);
706   }
707 
708 
709   if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
710     switch (samplesperpixel) {
711     case 1:  photometric = PHOTOMETRIC_MINISBLACK;   break;
712 
713     case 3:
714     case 4:  photometric = PHOTOMETRIC_RGB;          break;
715 
716     default:
717       TIFFError(TIFFFileName(tif),
718 		"Missing needed \"PhotometricInterpretation\" tag");
719       return (0);
720     }
721 
722     TIFFWarning(TIFFFileName(tif),
723 	      "No \"PhotometricInterpretation\" tag, assuming %s\n",
724 	      photometric == PHOTOMETRIC_RGB ? "RGB" : "min-is-black");
725   }
726 
727   /* XXX maybe should check photometric? */
728   TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
729   TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
730 
731   /* XXX verify rwidth and rheight against width and height */
732   stoponerr = stop;
733   BWmap = NULL;
734   PALmap = NULL;
735   ok = gt(tif, rwidth, height, raster + (rheight-height)*rwidth);
736   if (BWmap)
737     free((char *)BWmap);
738   if (PALmap)
739     free((char *)PALmap);
740   return (ok);
741 }
742 
743 
744 /*******************************************/
checkcmap(n,r,g,b)745 static int checkcmap(n, r, g, b)
746      int n;
747      u_short *r, *g, *b;
748 {
749   while (n-- >= 0)
750     if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) return (16);
751 
752   TIFFWarning(filename, "Assuming 8-bit colormap");
753   return (8);
754 }
755 
756 
757 /*******************************************/
gt(tif,w,h,raster)758 static int gt(tif, w, h, raster)
759      TIFF   *tif;
760      uint32 w, h;
761      byte   *raster;
762 {
763 #ifdef USE_LIBJPEG_FOR_TIFF_YCbCr_RGB_CONVERSION
764   u_short compression;
765 #endif
766   u_short minsamplevalue, maxsamplevalue, planarconfig;
767   RGBvalue *Map;
768   int bpp = 1, e;
769   int x, range;
770 
771 #ifdef USE_LIBJPEG_FOR_TIFF_YCbCr_RGB_CONVERSION
772   TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression);
773 #endif
774   TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
775   TIFFGetFieldDefaulted(tif, TIFFTAG_MINSAMPLEVALUE, &minsamplevalue);
776   TIFFGetFieldDefaulted(tif, TIFFTAG_MAXSAMPLEVALUE, &maxsamplevalue);
777   Map = NULL;
778 
779   switch (photometric) {
780   case PHOTOMETRIC_YCBCR:
781 #ifdef USE_LIBJPEG_FOR_TIFF_YCbCr_RGB_CONVERSION
782     if (compression == COMPRESSION_JPEG
783 #ifdef LIBTIFF_HAS_OLDJPEG_SUPPORT
784                                         || compression == COMPRESSION_OJPEG
785 #endif
786                                                                             ) {
787       /* FIXME:  Remove the following test as soon as TIFF Library is fixed!
788        *   (Currently [June 2002] this requires supporting patches in both
789        *   tif_ojpeg.c and tif_jpeg.c in order to support subsampled YCbCr
790        *   images having separated color planes.) */
791       if (planarconfig == PLANARCONFIG_CONTIG) {
792         /* can rely on libjpeg to convert to RGB (assuming newer libtiff,
793          * compiled with appropriate forms of JPEG support) */
794         TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
795         photometric = PHOTOMETRIC_RGB;
796       } else {
797         TIFFError(filename, "Cannot handle format");
798         return (0);
799       }
800     } else
801 #endif // USE_LIBJPEG_FOR_TIFF_YCbCr_RGB_CONVERSION
802     {
803       TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRCOEFFICIENTS, &YCbCrCoeffs);
804       TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
805 			    &YCbCrHorizSampling, &YCbCrVertSampling);
806 
807       /* According to the TIFF specification, if no "ReferenceBlackWhite"
808        * tag is present in the input file, "TIFFGetFieldDefaulted()" returns
809        * default reference black and white levels suitable for PHOTOMETRIC_RGB;
810        * namely:  <0,255,0,255,0,255>.  But for PHOTOMETRIC_YCBCR in JPEG
811        * images, the usual default (e.g., corresponding to the behavior of the
812        * IJG libjpeg) is:  <0,255,128,255,128,255>.  Since libtiff doesn't have
813        * a clean, standard interface for making this repair, the following
814        * slightly dirty code installs the default.  --Scott Marovich,
815        * Hewlett-Packard Labs, 9/2001.
816        */
817       if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE, &refBlackWhite)) {
818         TIFFGetFieldDefaulted(tif, TIFFTAG_REFERENCEBLACKWHITE, &refBlackWhite);
819         refBlackWhite[4] = refBlackWhite[2] = 1 << (bitspersample - 1);
820       }
821       TIFFGetFieldDefaulted(tif, TIFFTAG_REFERENCEBLACKWHITE, &refBlackWhite);
822       initYCbCrConversion();
823     }
824     /* fall thru... */
825 
826   case PHOTOMETRIC_RGB:
827     bpp *= 3;
828     if (minsamplevalue == 0 && maxsamplevalue == 255)
829       break;
830 
831     /* fall thru... */
832   case PHOTOMETRIC_MINISBLACK:
833   case PHOTOMETRIC_MINISWHITE:
834     range = maxsamplevalue - minsamplevalue;
835     Map = (RGBvalue *)malloc((range + 1) * sizeof (RGBvalue));
836     if (Map == NULL) {
837       TIFFError(filename, "No space for photometric conversion table");
838       return (0);
839     }
840 
841     if (photometric == PHOTOMETRIC_MINISWHITE) {
842       for (x = 0; x <= range; x++)
843 	Map[x] = (255*(range-x))/range;
844     } else {
845       for (x = 0; x <= range; x++)
846 	Map[x] = (255*x)/range;
847     }
848 
849     if (range<256) {
850       for (x=0; x<=range; x++) rmap[x] = gmap[x] = bmap[x] = Map[x];
851     } else {
852       for (x=0; x<256; x++)
853 	rmap[x] = gmap[x] = bmap[x] = Map[(range*x)/255];
854     }
855 
856     if (photometric != PHOTOMETRIC_RGB && bitspersample <= 8) {
857       /*
858        * Use photometric mapping table to construct
859        * unpacking tables for samples <= 8 bits.
860        */
861       if (!makebwmap())
862 	return (0);
863       /* no longer need Map, free it */
864       free((char *)Map);
865       Map = NULL;
866     }
867     break;
868 
869   case PHOTOMETRIC_PALETTE:
870     if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
871 		      &redcmap, &greencmap, &bluecmap)) {
872       TIFFError(filename, "Missing required \"Colormap\" tag");
873       return (0);
874     }
875 
876     /*
877      * Convert 16-bit colormap to 8-bit (unless it looks
878      * like an old-style 8-bit colormap).
879      */
880     range = (1<<bitspersample)-1;
881     if (checkcmap(range, redcmap, greencmap, bluecmap) == 16) {
882 
883 #define	CVT(x)		((((int) x) * 255) / ((1L<<16)-1))
884 
885       for (x = range; x >= 0; x--) {
886 	rmap[x] = CVT(redcmap[x]);
887 	gmap[x] = CVT(greencmap[x]);
888 	bmap[x] = CVT(bluecmap[x]);
889       }
890     } else {
891       for (x = range; x >= 0; x--) {
892 	rmap[x] = redcmap[x];
893 	gmap[x] = greencmap[x];
894 	bmap[x] = bluecmap[x];
895       }
896     }
897 
898     if (bitspersample <= 8) {
899       /*
900        * Use mapping table to construct
901        * unpacking tables for samples < 8 bits.
902        */
903       if (!makecmap())
904 	return (0);
905     }
906     break;
907 
908   default:
909     TIFFError(filename, "Unknown photometric tag %u", photometric);
910     return (0);
911   }
912 
913   if (planarconfig == PLANARCONFIG_SEPARATE && samplesperpixel > 1) {
914     e = TIFFIsTiled(tif) ? gtTileSeparate (tif, raster, Map, h, w, bpp) :
915                            gtStripSeparate(tif, raster, Map, h, w, bpp);
916   } else {
917     e = TIFFIsTiled(tif) ? gtTileContig (tif, raster, Map, h, w, bpp) :
918                            gtStripContig(tif, raster, Map, h, w, bpp);
919   }
920 
921   if (Map) free((char *)Map);
922   return (e);
923 }
924 
925 
926 /*******************************************/
setorientation(tif,h)927 static uint32 setorientation(tif, h)
928      TIFF *tif;
929      uint32 h;
930 {
931   /* note that orientation was flipped in LoadTIFF() (near line 175) */
932 
933   uint32 y;
934 
935   TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &orientation);
936   switch (orientation) {
937   case ORIENTATION_BOTRIGHT:
938   case ORIENTATION_RIGHTBOT:	/* XXX */
939   case ORIENTATION_LEFTBOT:	/* XXX */
940     TIFFWarning(filename, "using bottom-left orientation");
941     orientation = ORIENTATION_BOTLEFT;
942 
943     /* fall thru... */
944   case ORIENTATION_BOTLEFT:
945     y = 0;
946     break;
947 
948   case ORIENTATION_TOPRIGHT:
949   case ORIENTATION_RIGHTTOP:	/* XXX */
950   case ORIENTATION_LEFTTOP:	/* XXX */
951   default:
952     TIFFWarning(filename, "using top-left orientation");
953     orientation = ORIENTATION_TOPLEFT;
954     /* fall thru... */
955   case ORIENTATION_TOPLEFT:
956     /* GRR 20050319:  This may be wrong for tiled images (also stripped?);
957      *   looks like we want to return th-1 instead of h-1 in at least some
958      *   cases.  For now, just added quick hack (USE_TILED_TIFF_BOTLEFT_FIX)
959      *   to gtTileContig().  (Note that, as of libtiff 3.7.1, tiffcp still
960      *   has exactly the same bug.) */
961     y = h-1;
962     break;
963   }
964   return (y);
965 }
966 
967 
968 
969 
970 /*
971  * Get a tile-organized image that has
972  *	PlanarConfiguration contiguous if SamplesPerPixel > 1
973  * or
974  *	SamplesPerPixel == 1
975  */
976 /*******************************************/
gtTileContig(tif,raster,Map,h,w,bpp)977 static int gtTileContig(tif, raster, Map, h, w, bpp)
978      TIFF *tif;
979      byte *raster;
980      RGBvalue *Map;
981      uint32 h, w;
982      int bpp;
983 {
984   uint32 col, row, y;
985   uint32 tw, th;
986   u_char *buf;
987   int fromskew, toskew;
988   u_int nrow;
989   tileContigRoutine put;
990   tsize_t bufsize;
991 
992   put = pickTileContigCase(Map);
993   if (put == 0) return (0);
994 
995   bufsize = TIFFTileSize(tif);
996   if (bufsize <= 0) return 0;  /* tsize_t is signed */
997   buf = (u_char *) malloc((size_t) bufsize);
998   if (buf == 0) {
999     TIFFError(filename, "No space for tile buffer");
1000     return (0);
1001   }
1002 
1003   TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
1004   TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
1005   y = setorientation(tif, h);
1006 #ifdef USE_TILED_TIFF_BOTLEFT_FIX  /* image _originally_ ORIENTATION_BOTLEFT */
1007   /* this fix causes tiles as a whole to be placed starting at the top,
1008    * regardless of orientation; the only difference is what happens within
1009    * a given tile (see toskew, below) */
1010   /* GRR FIXME:  apply globally in setorientation()? */
1011   if (orientation == ORIENTATION_TOPLEFT)
1012     y = th-1;
1013 #endif
1014   /* toskew causes individual tiles to copy from bottom to top for
1015    * ORIENTATION_TOPLEFT and from top to bottom otherwise */
1016   toskew = (orientation == ORIENTATION_TOPLEFT ? -tw + -w : -tw + w);
1017 
1018   for (row = 0; row < h; row += th) {
1019     nrow = (row + th > h ? h - row : th);
1020     for (col = 0; col < w; col += tw) {
1021       /*
1022        * This reads the tile at (col,row) into buf.  "The data placed in buf
1023        * are returned decompressed and, typically, in the native byte- and
1024        * bit-ordering, but are otherwise packed."
1025        */
1026       if (TIFFReadTile(tif, buf, (uint32)col, (uint32)row, 0, 0) < 0
1027 	  && stoponerr) break;
1028 
1029       if (col + tw > w) {
1030 	/*
1031 	 * Tile is clipped horizontally.  Calculate
1032 	 * visible portion and skewing factors.
1033 	 */
1034 	uint32 npix = w - col;
1035 	fromskew = tw - npix;
1036 	(*put)(raster + (y*w + col)*bpp, buf, Map, npix, (uint32) nrow,
1037 	       fromskew, (int) ((toskew + fromskew)*bpp) );
1038       } else
1039 	(*put)(raster + (y*w + col)*bpp, buf, Map, tw,   (uint32) nrow,
1040 	       0, (int) (toskew*bpp));
1041     }
1042 
1043 #ifdef USE_TILED_TIFF_BOTLEFT_FIX  /* image _originally_ ORIENTATION_BOTLEFT */
1044     y += nrow;
1045 #else
1046     y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
1047 #endif
1048   }
1049   free(buf);
1050   return (1);
1051 }
1052 
1053 
1054 
1055 
1056 /*
1057  * Get a tile-organized image that has
1058  *	 SamplesPerPixel > 1
1059  *	 PlanarConfiguration separated
1060  * We assume that all such images are RGB.
1061  */
1062 
1063 /*******************************************/
gtTileSeparate(tif,raster,Map,h,w,bpp)1064 static int gtTileSeparate(tif, raster, Map, h, w, bpp)
1065      TIFF *tif;
1066      byte *raster;
1067      RGBvalue *Map;
1068      uint32 h, w;
1069      int bpp;
1070 {
1071   uint32 tw, th;
1072   uint32 col, row, y;
1073   u_char *buf;
1074   u_char *r, *g, *b;
1075   tsize_t tilesize;
1076   uint32 bufsize;
1077   int fromskew, toskew;
1078   u_int nrow;
1079   tileSeparateRoutine put;
1080 
1081   put = pickTileSeparateCase(Map);
1082   if (put == 0) return (0);
1083 
1084   tilesize = TIFFTileSize(tif);
1085   bufsize = 3*tilesize;
1086   if (tilesize <= 0 || bufsize/3 != tilesize) {  /* tsize_t is signed */
1087     TIFFError(filename, "Image dimensions too large");
1088     return 0;
1089   }
1090   buf = (u_char *) malloc((size_t) bufsize);
1091   if (buf == 0) {
1092     TIFFError(filename, "No space for tile buffer");
1093     return (0);
1094   }
1095   r = buf;
1096   g = r + tilesize;
1097   b = g + tilesize;
1098   TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
1099   TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
1100   y = setorientation(tif, h);
1101   toskew = (orientation == ORIENTATION_TOPLEFT ? -tw + -w : -tw + w);
1102 
1103   for (row = 0; row < h; row += th) {
1104     nrow = (row + th > h ? h - row : th);
1105     for (col = 0; col < w; col += tw) {
1106       tsample_t band;
1107 
1108       band = 0;
1109       if (TIFFReadTile(tif, r, (uint32) col, (uint32) row,0, band) < 0
1110 	  && stoponerr) break;
1111 
1112       band = 1;
1113       if (TIFFReadTile(tif, g, (uint32) col, (uint32) row,0, band) < 0
1114 	  && stoponerr) break;
1115 
1116       band = 2;
1117       if (TIFFReadTile(tif, b, (uint32) col, (uint32) row,0, band) < 0
1118 	  && stoponerr) break;
1119 
1120       if (col + tw > w) {
1121 	/*
1122 	 * Tile is clipped horizontally.  Calculate
1123 	 * visible portion and skewing factors.
1124 	 */
1125 	uint32 npix = w - col;
1126 	fromskew = tw - npix;
1127 	(*put)(raster + (y*w + col)*bpp, r, g, b, Map, npix, (uint32) nrow,
1128 	       fromskew, (int) ((toskew + fromskew)*bpp));
1129       } else
1130 	(*put)(raster + (y*w + col)*bpp, r, g, b, Map, tw, (uint32) nrow,
1131 	       0, (int) (toskew*bpp));
1132     }
1133     y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
1134   }
1135   free(buf);
1136   return (1);
1137 }
1138 
1139 /*
1140  * Get a strip-organized image that has
1141  *	PlanarConfiguration contiguous if SamplesPerPixel > 1
1142  * or
1143  *	SamplesPerPixel == 1
1144  */
1145 /*******************************************/
gtStripContig(tif,raster,Map,h,w,bpp)1146 static int gtStripContig(tif, raster, Map, h, w, bpp)
1147      TIFF *tif;
1148      byte *raster;
1149      RGBvalue *Map;
1150      uint32 h, w;
1151      int bpp;
1152 {
1153   uint32 row, y, nrow;
1154   u_char *buf;
1155   tileContigRoutine put;
1156   uint32 rowsperstrip;
1157   uint32 imagewidth;
1158   int scanline;
1159   int fromskew, toskew;
1160   tsize_t bufsize;
1161 
1162   put = pickTileContigCase(Map);
1163   if (put == 0)
1164     return (0);
1165 
1166   bufsize = TIFFStripSize(tif);
1167   if (bufsize <= 0) return 0;  /* tsize_t is signed */
1168   buf = (u_char *) malloc((size_t) bufsize);
1169   if (buf == 0) {
1170     TIFFError(filename, "No space for strip buffer");
1171     return (0);
1172   }
1173   y = setorientation(tif, h);
1174   toskew = (orientation == ORIENTATION_TOPLEFT ? -w + -w : -w + w);
1175   TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1176   TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth);
1177   scanline = TIFFScanlineSize(tif);
1178   fromskew = (w < imagewidth ? imagewidth - w : 0);
1179   for (row = 0; row < h; row += rowsperstrip) {
1180     nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
1181     if (TIFFReadEncodedStrip(tif,
1182 			     TIFFComputeStrip(tif, (uint32) row,(tsample_t) 0),
1183 			     (tdata_t) buf, (tsize_t)(nrow*scanline)) < 0
1184 	&& stoponerr) break;
1185 
1186     (*put)(raster + y*w*bpp, buf, Map, w, nrow, fromskew, toskew*bpp);
1187 
1188     y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
1189   }
1190   free(buf);
1191   return (1);
1192 }
1193 
1194 
1195 /*
1196  * Get a strip-organized image with
1197  *	 SamplesPerPixel > 1
1198  *	 PlanarConfiguration separated
1199  * We assume that all such images are RGB.
1200  */
gtStripSeparate(tif,raster,Map,h,w,bpp)1201 static int gtStripSeparate(tif, raster, Map, h, w, bpp)
1202      TIFF *tif;
1203      byte *raster;
1204      register RGBvalue *Map;
1205      uint32 h, w;
1206      int bpp;
1207 {
1208   uint32 nrow, row, y;
1209   u_char *buf;
1210   u_char *r, *g, *b;
1211   tsize_t stripsize;
1212   uint32 bufsize;
1213   int fromskew, toskew;
1214   int scanline;
1215   tileSeparateRoutine put;
1216   uint32 rowsperstrip;
1217   uint32 imagewidth;
1218 
1219   stripsize = TIFFStripSize(tif);
1220   bufsize = 3*stripsize;
1221   if (stripsize <= 0 || bufsize/3 != stripsize) {  /* tsize_t is signed */
1222     TIFFError(filename, "Image dimensions too large");
1223     return 0;
1224   }
1225   buf = (u_char *) malloc((size_t) bufsize);
1226   if (buf == 0) {
1227     TIFFError(filename, "No space for strip buffer");
1228     return (0);
1229   }
1230   r = buf;
1231   g = r + stripsize;
1232   b = g + stripsize;
1233   put = pickTileSeparateCase(Map);
1234   if (put == 0) {
1235     TIFFError(filename, "Cannot handle format");
1236     return (0);
1237   }
1238   y = setorientation(tif, h);
1239   toskew = (orientation == ORIENTATION_TOPLEFT ? -w + -w : -w + w);
1240   TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1241   TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth);
1242   scanline = TIFFScanlineSize(tif);
1243   fromskew = (w < imagewidth ? imagewidth - w : 0);
1244   for (row = 0; row < h; row += rowsperstrip) {
1245     tsample_t band;
1246 
1247     nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
1248     band = 0;
1249     if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, (uint32) row, band),
1250 			     (tdata_t) r, (tsize_t)(nrow*scanline)) < 0
1251 	&& stoponerr) break;
1252 
1253     band = 1;
1254     if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, (uint32) row, band),
1255 			     (tdata_t) g, (tsize_t)(nrow*scanline)) < 0
1256 	&& stoponerr) break;
1257 
1258     band = 2;
1259     if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, (uint32) row, band),
1260 			     (tdata_t) b, (tsize_t)(nrow*scanline)) < 0
1261 	&& stoponerr) break;
1262 
1263     (*put)(raster + y*w*bpp, r, g, b, Map, w, nrow, fromskew, toskew*bpp);
1264 
1265     y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
1266   }
1267   free(buf);
1268   return (1);
1269 }
1270 
1271 
1272 /*
1273  * Greyscale images with less than 8 bits/sample are handled
1274  * with a table to avoid lots of shifts and masks.  The table
1275  * is set up so that put*bwtile (below) can retrieve 8/bitspersample
1276  * pixel values simply by indexing into the table with one
1277  * number.
1278  */
makebwmap()1279 static int makebwmap()
1280 {
1281   register int i;
1282   int nsamples = 8 / bitspersample;
1283   register byte *p;
1284 
1285   BWmap = (byte **)malloc(
1286 			  256*sizeof (byte *)+(256*nsamples*sizeof(byte)));
1287   if (BWmap == NULL) {
1288     TIFFError(filename, "No space for B&W mapping table");
1289     return (0);
1290   }
1291   p = (byte *)(BWmap + 256);
1292   for (i = 0; i < 256; i++) {
1293     BWmap[i] = p;
1294     switch (bitspersample) {
1295 #define	GREY(x)	*p++ = x;
1296     case 1:
1297       GREY(i>>7);
1298       GREY((i>>6)&1);
1299       GREY((i>>5)&1);
1300       GREY((i>>4)&1);
1301       GREY((i>>3)&1);
1302       GREY((i>>2)&1);
1303       GREY((i>>1)&1);
1304       GREY(i&1);
1305       break;
1306     case 2:
1307       GREY(i>>6);
1308       GREY((i>>4)&3);
1309       GREY((i>>2)&3);
1310       GREY(i&3);
1311       break;
1312     case 4:
1313       GREY(i>>4);
1314       GREY(i&0xf);
1315       break;
1316     case 8:
1317       GREY(i);
1318       break;
1319     }
1320 #undef	GREY
1321   }
1322   return (1);
1323 }
1324 
1325 
1326 /*
1327  * Palette images with <= 8 bits/sample are handled with
1328  * a table to avoid lots of shifts and masks.  The table
1329  * is set up so that put*cmaptile (below) can retrieve
1330  * (8/bitspersample) pixel-values simply by indexing into
1331  * the table with one number.
1332  */
makecmap()1333 static int makecmap()
1334 {
1335   register int i;
1336   int nsamples = 8 / bitspersample;
1337   register byte *p;
1338 
1339   PALmap = (byte **)malloc(
1340 			   256*sizeof (byte *)+(256*nsamples*sizeof(byte)));
1341   if (PALmap == NULL) {
1342     TIFFError(filename, "No space for Palette mapping table");
1343     return (0);
1344   }
1345   p = (byte *)(PALmap + 256);
1346   for (i = 0; i < 256; i++) {
1347     PALmap[i] = p;
1348 #define	CMAP(x)	*p++ = x;
1349     switch (bitspersample) {
1350     case 1:
1351       CMAP(i>>7);
1352       CMAP((i>>6)&1);
1353       CMAP((i>>5)&1);
1354       CMAP((i>>4)&1);
1355       CMAP((i>>3)&1);
1356       CMAP((i>>2)&1);
1357       CMAP((i>>1)&1);
1358       CMAP(i&1);
1359       break;
1360     case 2:
1361       CMAP(i>>6);
1362       CMAP((i>>4)&3);
1363       CMAP((i>>2)&3);
1364       CMAP(i&3);
1365       break;
1366     case 4:
1367       CMAP(i>>4);
1368       CMAP(i&0xf);
1369       break;
1370     case 8:
1371       CMAP(i);
1372       break;
1373     }
1374 #undef CMAP
1375   }
1376   return (1);
1377 }
1378 
1379 
1380 /*
1381  * The following routines move decoded data returned
1382  * from the TIFF library into rasters filled with packed
1383  * ABGR pixels (i.e., suitable for passing to lrecwrite.)
1384  *
1385  * The routines have been created according to the most
1386  * important cases and optimized.  pickTileContigCase and
1387  * pickTileSeparateCase analyze the parameters and select
1388  * the appropriate "put" routine to use.
1389  */
1390 
1391 #define	REPEAT8(op)	REPEAT4(op); REPEAT4(op)
1392 #define	REPEAT4(op)	REPEAT2(op); REPEAT2(op)
1393 #define	REPEAT2(op)	op; op
1394 #define	CASE8(x,op)				\
1395 	switch (x) {				\
1396 	case 7: op; case 6: op; case 5: op;	\
1397 	case 4: op; case 3: op; case 2: op;	\
1398 	case 1: op;				\
1399 	}
1400 #define	CASE4(x,op)	switch (x) { case 3: op; case 2: op; case 1: op; }
1401 
1402 #define	UNROLL8(w, op1, op2) {		\
1403 	uint32 x;	                \
1404 	for (x = w; x >= 8; x -= 8) {	\
1405 		op1;			\
1406 		REPEAT8(op2);		\
1407 	}				\
1408 	if (x > 0) {			\
1409 		op1;			\
1410 		CASE8(x,op2);		\
1411 	}				\
1412 }
1413 
1414 #define	UNROLL4(w, op1, op2) {		\
1415 	uint32 x;		        \
1416 	for (x = w; x >= 4; x -= 4) {	\
1417 		op1;			\
1418 		REPEAT4(op2);		\
1419 	}				\
1420 	if (x > 0) {			\
1421 		op1;			\
1422 		CASE4(x,op2);		\
1423 	}				\
1424 }
1425 
1426 #define	UNROLL2(w, op1, op2) {		\
1427 	uint32 x;		        \
1428 	for (x = w; x >= 2; x -= 2) {	\
1429 		op1;			\
1430 		REPEAT2(op2);		\
1431 	}				\
1432 	if (x) {			\
1433 		op1;			\
1434 		op2;			\
1435 	}				\
1436 }
1437 
1438 
1439 #define	SKEW(r,g,b,skew)	{ r += skew; g += skew; b += skew; }
1440 
1441 
1442 
1443 /*
1444  * 8-bit palette => colormap/RGB
1445  */
put8bitcmaptile(cp,pp,Map,w,h,fromskew,toskew)1446 static void put8bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
1447      byte *cp;
1448      u_char *pp;
1449      RGBvalue *Map;
1450      uint32 w, h;
1451      int fromskew, toskew;
1452 {
1453   while (h-- > 0) {
1454     UNROLL8(w, , *cp++ = PALmap[*pp++][0]);
1455     cp += toskew;
1456     pp += fromskew;
1457   }
1458 }
1459 
1460 /*
1461  * 4-bit palette => colormap/RGB
1462  */
put4bitcmaptile(cp,pp,Map,w,h,fromskew,toskew)1463 static void put4bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
1464      byte     *cp;
1465      u_char   *pp;
1466      RGBvalue *Map;
1467      uint32    w, h;
1468      int       fromskew, toskew;
1469 {
1470   register byte *bw;
1471 
1472   fromskew /= 2;
1473   while (h-- > 0) {
1474     UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
1475     cp += toskew;
1476     pp += fromskew;
1477   }
1478 }
1479 
1480 
1481 /*
1482  * 2-bit palette => colormap/RGB
1483  */
put2bitcmaptile(cp,pp,Map,w,h,fromskew,toskew)1484 static void put2bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
1485      byte     *cp;
1486      u_char   *pp;
1487      RGBvalue *Map;
1488      uint32    w, h;
1489      int       fromskew, toskew;
1490 {
1491   register byte *bw;
1492 
1493   fromskew /= 4;
1494   while (h-- > 0) {
1495     UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
1496     cp += toskew;
1497     pp += fromskew;
1498   }
1499 }
1500 
1501 /*
1502  * 1-bit palette => colormap/RGB
1503  */
put1bitcmaptile(cp,pp,Map,w,h,fromskew,toskew)1504 static void put1bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
1505 	byte     *cp;
1506 	u_char   *pp;
1507 	RGBvalue *Map;
1508 	uint32    w, h;
1509 	int       fromskew, toskew;
1510 {
1511   register byte *bw;
1512 
1513   fromskew /= 8;
1514   while (h-- > 0) {
1515     UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++)
1516     cp += toskew;
1517     pp += fromskew;
1518   }
1519 }
1520 
1521 
1522 /*
1523  * 8-bit greyscale => colormap/RGB
1524  */
putgreytile(cp,pp,Map,w,h,fromskew,toskew)1525 static void putgreytile(cp, pp, Map, w, h, fromskew, toskew)
1526      register byte *cp;
1527      register u_char *pp;
1528      RGBvalue *Map;
1529      uint32 w, h;
1530      int fromskew, toskew;
1531 {
1532   while (h-- > 0) {
1533     register uint32 x;
1534     for (x = w; x-- > 0;)
1535       *cp++ = BWmap[*pp++][0];
1536     cp += toskew;
1537     pp += fromskew;
1538   }
1539 }
1540 
1541 
1542 /*
1543  * 1-bit bilevel => colormap/RGB
1544  */
put1bitbwtile(cp,pp,Map,w,h,fromskew,toskew)1545 static void put1bitbwtile(cp, pp, Map, w, h, fromskew, toskew)
1546      byte *cp;
1547      u_char *pp;
1548      RGBvalue *Map;
1549      uint32 w, h;
1550      int fromskew, toskew;
1551 {
1552   register byte *bw;
1553 
1554   fromskew /= 8;
1555   while (h-- > 0) {
1556     UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++)
1557     cp += toskew;
1558     pp += fromskew;
1559   }
1560 }
1561 
1562 /*
1563  * 2-bit greyscale => colormap/RGB
1564  */
put2bitbwtile(cp,pp,Map,w,h,fromskew,toskew)1565 static void put2bitbwtile(cp, pp, Map, w, h, fromskew, toskew)
1566      byte *cp;
1567      u_char *pp;
1568      RGBvalue *Map;
1569      uint32 w, h;
1570      int fromskew, toskew;
1571 {
1572   register byte *bw;
1573 
1574   fromskew /= 4;
1575   while (h-- > 0) {
1576     UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
1577     cp += toskew;
1578     pp += fromskew;
1579   }
1580 }
1581 
1582 /*
1583  * 4-bit greyscale => colormap/RGB
1584  */
put4bitbwtile(cp,pp,Map,w,h,fromskew,toskew)1585 static void put4bitbwtile(cp, pp, Map, w, h, fromskew, toskew)
1586      byte *cp;
1587      u_char *pp;
1588      RGBvalue *Map;
1589      uint32 w, h;
1590      int fromskew, toskew;
1591 {
1592   register byte *bw;
1593 
1594   fromskew /= 2;
1595   while (h-- > 0) {
1596     UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
1597     cp += toskew;
1598     pp += fromskew;
1599   }
1600 }
1601 
1602 /*
1603  * 16-bit greyscale => colormap/RGB
1604  */
put16bitbwtile(cp,pp,Map,w,h,fromskew,toskew)1605 static void put16bitbwtile(cp, pp, Map, w, h, fromskew, toskew)
1606      byte  *cp;
1607      u_short *pp;
1608      RGBvalue *Map;
1609      uint32 w, h;
1610      int fromskew, toskew;
1611 {
1612   register uint32   x;
1613 
1614   while (h-- > 0) {
1615     for (x=w; x>0; x--) {
1616       *cp++ = Map[*pp++];
1617     }
1618     cp += toskew;
1619     pp += fromskew;
1620   }
1621 }
1622 
1623 
1624 
1625 /*
1626  * 8-bit packed samples => RGB
1627  */
putRGBcontig8bittile(cp,pp,Map,w,h,fromskew,toskew)1628 static void putRGBcontig8bittile(cp, pp, Map, w, h, fromskew, toskew)
1629      byte *cp;
1630      u_char *pp;
1631      RGBvalue *Map;
1632      uint32 w, h;
1633      int fromskew, toskew;
1634 {
1635   fromskew *= samplesperpixel;
1636   if (Map) {
1637     while (h-- > 0) {
1638       register uint32 x;
1639       for (x = w; x-- > 0;) {
1640 	*cp++ = Map[pp[0]];
1641 	*cp++ = Map[pp[1]];
1642 	*cp++ = Map[pp[2]];
1643 	pp += samplesperpixel;
1644       }
1645       pp += fromskew;
1646       cp += toskew;
1647     }
1648   } else {
1649     while (h-- > 0) {
1650       UNROLL8(w, ,
1651 	      *cp++ = pp[0];
1652 	      *cp++ = pp[1];
1653 	      *cp++ = pp[2];
1654 	      pp += samplesperpixel);
1655       cp += toskew;
1656       pp += fromskew;
1657     }
1658   }
1659 }
1660 
1661 /*
1662  * 16-bit packed samples => RGB
1663  */
putRGBcontig16bittile(cp,pp,Map,w,h,fromskew,toskew)1664 static void putRGBcontig16bittile(cp, pp, Map, w, h, fromskew, toskew)
1665      byte *cp;
1666      u_short *pp;
1667      RGBvalue *Map;
1668      uint32 w, h;
1669      int fromskew, toskew;
1670 {
1671   register u_int x;
1672 
1673   fromskew *= samplesperpixel;
1674   if (Map) {
1675     while (h-- > 0) {
1676       for (x = w; x-- > 0;) {
1677 	*cp++ = Map[pp[0]];
1678 	*cp++ = Map[pp[1]];
1679 	*cp++ = Map[pp[2]];
1680 	pp += samplesperpixel;
1681       }
1682       cp += toskew;
1683       pp += fromskew;
1684     }
1685   } else {
1686     while (h-- > 0) {
1687       for (x = w; x-- > 0;) {
1688 	*cp++ = pp[0];
1689 	*cp++ = pp[1];
1690 	*cp++ = pp[2];
1691 	pp += samplesperpixel;
1692       }
1693       cp += toskew;
1694       pp += fromskew;
1695     }
1696   }
1697 }
1698 
1699 /*
1700  * 8-bit unpacked samples => RGB
1701  */
putRGBseparate8bittile(cp,r,g,b,Map,w,h,fromskew,toskew)1702 static void putRGBseparate8bittile(cp, r, g, b, Map, w, h, fromskew, toskew)
1703      byte *cp;
1704      u_char *r, *g, *b;
1705      RGBvalue *Map;
1706      uint32 w, h;
1707      int fromskew, toskew;
1708 
1709 {
1710   if (Map) {
1711     while (h-- > 0) {
1712       register uint32 x;
1713       for (x = w; x > 0; x--) {
1714 	*cp++ = Map[*r++];
1715 	*cp++ = Map[*g++];
1716 	*cp++ = Map[*b++];
1717       }
1718       SKEW(r, g, b, fromskew);
1719       cp += toskew;
1720     }
1721   } else {
1722     while (h-- > 0) {
1723       UNROLL8(w, ,
1724 	      *cp++ = *r++;
1725 	      *cp++ = *g++;
1726 	      *cp++ = *b++;
1727 	      );
1728       SKEW(r, g, b, fromskew);
1729       cp += toskew;
1730     }
1731   }
1732 }
1733 
1734 /*
1735  * 16-bit unpacked samples => RGB
1736  */
putRGBseparate16bittile(cp,r,g,b,Map,w,h,fromskew,toskew)1737 static void putRGBseparate16bittile(cp, r, g, b, Map, w, h, fromskew, toskew)
1738      byte *cp;
1739      u_short *r, *g, *b;
1740      RGBvalue *Map;
1741      uint32 w, h;
1742      int fromskew, toskew;
1743 {
1744   uint32 x;
1745 
1746   if (Map) {
1747     while (h-- > 0) {
1748       for (x = w; x > 0; x--) {
1749 	*cp++ = Map[*r++];
1750 	*cp++ = Map[*g++];
1751 	*cp++ = Map[*b++];
1752       }
1753       SKEW(r, g, b, fromskew);
1754       cp += toskew;
1755     }
1756   } else {
1757     while (h-- > 0) {
1758       for (x = 0; x < w; x++) {
1759 	*cp++ = *r++;
1760 	*cp++ = *g++;
1761 	*cp++ = *b++;
1762       }
1763       SKEW(r, g, b, fromskew);
1764       cp += toskew;
1765     }
1766   }
1767 }
1768 
1769 #define Code2V(c, RB, RW, CR)  (((((int)c)-(int)RB)*(float)CR)/(float)(RW-RB))
1770 
1771 #define	CLAMP(f,min,max) \
1772     (int)((f)+.5 < (min) ? (min) : (f)+.5 > (max) ? (max) : (f)+.5)
1773 
1774 #define	LumaRed		YCbCrCoeffs[0]
1775 #define	LumaGreen	YCbCrCoeffs[1]
1776 #define	LumaBlue	YCbCrCoeffs[2]
1777 
1778 static	float D1, D2, D3, D4 /*, D5 */;
1779 
1780 
initYCbCrConversion()1781 static void initYCbCrConversion()
1782 {
1783   /*
1784    * Old, broken version (goes back at least to 19920426; made worse 19941222):
1785    *   YCbCrCoeffs[] = {0.299, 0.587, 0.114}
1786    *     D1 = 1.402
1787    *     D2 = 0.714136
1788    *     D3 = 1.772
1789    *     D4 = 0.138691  <-- bogus
1790    *     D5 = 1.70358   <-- unnecessary
1791    *
1792    * New, fixed version (GRR 20050319):
1793    *   YCbCrCoeffs[] = {0.299, 0.587, 0.114}
1794    *     D1 = 1.402
1795    *     D2 = 0.714136
1796    *     D3 = 1.772
1797    *     D4 = 0.344136
1798    */
1799   D1 = 2 - 2*LumaRed;
1800   D2 = D1*LumaRed / LumaGreen;
1801   D3 = 2 - 2*LumaBlue;
1802   D4 = D3*LumaBlue / LumaGreen;  /* ARGH, used to be D2*LumaBlue/LumaGreen ! */
1803 /* D5 = 1.0 / LumaGreen; */      /* unnecessary */
1804 }
1805 
putRGBContigYCbCrClump(cp,pp,cw,ch,w,n,fromskew,toskew)1806 static void putRGBContigYCbCrClump(cp, pp, cw, ch, w, n, fromskew, toskew)
1807      byte *cp;
1808      u_char *pp;
1809      int cw, ch;
1810      uint32 w;
1811      int n, fromskew, toskew;
1812 {
1813   float Cb, Cr;
1814   int j, k;
1815 
1816   Cb = Code2V(pp[n],   refBlackWhite[2], refBlackWhite[3], 127);
1817   Cr = Code2V(pp[n+1], refBlackWhite[4], refBlackWhite[5], 127);
1818   for (j = 0; j < ch; j++) {
1819     for (k = 0; k < cw; k++) {
1820       float Y, R, G, B;
1821       Y = Code2V(*pp++,
1822 		 refBlackWhite[0], refBlackWhite[1], 255);
1823       R = Y + Cr*D1;
1824 /*    G = Y*D5 - Cb*D4 - Cr*D2;  highly bogus! */
1825       G = Y - Cb*D4 - Cr*D2;
1826       B = Y + Cb*D3;
1827       /*
1828        * These are what the JPEG/JFIF equations--which aren't _necessarily_
1829        * what JPEG/TIFF uses but which seem close enough--are supposed to be,
1830        * according to Avery Lee (e.g., see http://www.fourcc.org/fccyvrgb.php):
1831        *
1832        *     R = Y + 1.402 (Cr-128)
1833        *     G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128)
1834        *     B = Y + 1.772 (Cb-128)
1835        *
1836        * Translated into xvtiff.c notation:
1837        *
1838        *     R = Y + Cr*D1
1839        *     G = Y - Cb*D4' - Cr*D2   (i.e., omit D5 and fix D4)
1840        *     B = Y + Cb*D3
1841        */
1842       cp[3*k+0] = CLAMP(R,0,255);
1843       cp[3*k+1] = CLAMP(G,0,255);
1844       cp[3*k+2] = CLAMP(B,0,255);
1845     }
1846     cp += 3*w+toskew;
1847     pp += fromskew;
1848   }
1849 }
1850 
putRGBSeparateYCbCrClump(cp,y,cb,cr,cw,ch,w,n,fromskew,toskew)1851 static void putRGBSeparateYCbCrClump(cp, y, cb, cr, cw, ch, w, n, fromskew, toskew)
1852      byte *cp;
1853      u_char *y, *cb, *cr;
1854      int cw, ch;
1855      uint32 w;
1856      int n, fromskew, toskew;
1857 {
1858   float Cb, Cr;
1859   int j, k;
1860 
1861   Cb = Code2V(cb[0], refBlackWhite[2], refBlackWhite[3], 127);
1862   Cr = Code2V(cr[0], refBlackWhite[4], refBlackWhite[5], 127);
1863   for (j = 0; j < ch; j++) {
1864     for (k = 0; k < cw; k++) {
1865       float Y, R, G, B;
1866       Y = Code2V(y[k], refBlackWhite[0], refBlackWhite[1], 255);
1867       R = Y + Cr*D1;
1868       G = Y - Cb*D4 - Cr*D2;
1869       B = Y + Cb*D3;
1870       cp[3*k+0] = CLAMP(R,0,255);
1871       cp[3*k+1] = CLAMP(G,0,255);
1872       cp[3*k+2] = CLAMP(B,0,255);
1873     }
1874     cp += w*3 + toskew;
1875     y  += w + ch*fromskew;
1876   }
1877 }
1878 
putRGBSeparate16bitYCbCrClump(cp,y,cb,cr,cw,ch,w,n,fromskew,toskew)1879 static void putRGBSeparate16bitYCbCrClump(cp, y, cb, cr, cw, ch, w, n, fromskew, toskew)
1880      byte *cp;
1881      u_short *y, *cb, *cr;
1882      int cw, ch;
1883      uint32 w;
1884      int n, fromskew, toskew;
1885 {
1886   float Cb, Cr;
1887   int j, k;
1888 
1889   Cb = Code2V(cb[0], refBlackWhite[2], refBlackWhite[3], 127);
1890   Cr = Code2V(cr[0], refBlackWhite[4], refBlackWhite[5], 127);
1891   for (j = 0; j < ch; j++) {
1892     for (k = 0; k < cw; k++) {
1893       float Y, R, G, B;
1894       Y = Code2V(y[k], refBlackWhite[0], refBlackWhite[1], 255);
1895       R = Y + Cr*D1;
1896       G = Y - Cb*D4 - Cr*D2;
1897       B = Y + Cb*D3;
1898       cp[3*k+0] = CLAMP(R,0,255);
1899       cp[3*k+1] = CLAMP(G,0,255);
1900       cp[3*k+2] = CLAMP(B,0,255);
1901     }
1902     cp += w*3 + toskew;
1903     y  += w + ch*fromskew;
1904   }
1905 }
1906 
1907 #undef LumaBlue
1908 #undef LumaGreen
1909 #undef LumaRed
1910 #undef CLAMP
1911 #undef Code2V
1912 
1913 
1914 /*
1915  * 8-bit packed YCbCr samples => RGB
1916  */
putcontig8bitYCbCrtile(cp,pp,Map,w,h,fromskew,toskew)1917 static void putcontig8bitYCbCrtile(cp, pp, Map, w, h, fromskew, toskew)
1918      byte *cp;
1919      u_char *pp;
1920      RGBvalue *Map;
1921      uint32 w, h;
1922      int fromskew, toskew;
1923 {
1924   u_int Coff = YCbCrVertSampling * YCbCrHorizSampling;
1925   byte *tp;
1926   uint32 x;
1927 
1928   /* XXX adjust fromskew */
1929   while (h >= YCbCrVertSampling) {
1930     tp = cp;
1931     for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
1932       putRGBContigYCbCrClump(tp, pp, YCbCrHorizSampling, YCbCrVertSampling,
1933 			     w, (int) Coff, 0, toskew);
1934       tp += 3*YCbCrHorizSampling;
1935       pp += Coff+2;
1936     }
1937     if (x > 0) {
1938       putRGBContigYCbCrClump(tp, pp, (int) x, YCbCrVertSampling,
1939 			     w, (int) Coff, (int)(YCbCrHorizSampling - x),
1940 			     toskew);
1941       pp += Coff+2;
1942     }
1943     cp += YCbCrVertSampling*(3*w + toskew);
1944     pp += fromskew;
1945     h -= YCbCrVertSampling;
1946   }
1947   if (h > 0) {
1948     tp = cp;
1949     for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
1950       putRGBContigYCbCrClump(tp, pp, YCbCrHorizSampling, (int) h,
1951 			     w, (int) Coff, 0, toskew);
1952       tp += 3*YCbCrHorizSampling;
1953       pp += Coff+2;
1954     }
1955     if (x > 0)
1956       putRGBContigYCbCrClump(tp, pp, (int) x, (int) h, w,
1957 			     (int)Coff, (int)(YCbCrHorizSampling-x),toskew);
1958   }
1959 }
1960 
1961 /*
1962  * 8-bit unpacked YCbCr samples => RGB
1963  */
putYCbCrseparate8bittile(cp,y,cb,cr,Map,w,h,fromskew,toskew)1964 static void putYCbCrseparate8bittile(cp, y, cb, cr, Map, w, h, fromskew, toskew)
1965      byte *cp;
1966      u_char *y, *cb, *cr;
1967      RGBvalue *Map;
1968      uint32 w, h;
1969      int fromskew, toskew;
1970 {
1971   uint32 x;
1972   int fromskew2 = fromskew/YCbCrHorizSampling;
1973 
1974   while (h >= YCbCrVertSampling) {
1975     for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
1976       putRGBSeparateYCbCrClump(cp, y, cb, cr, YCbCrHorizSampling,
1977 			       YCbCrVertSampling, w, 0, 0, toskew);
1978       cp += 3*YCbCrHorizSampling;
1979       y += YCbCrHorizSampling;
1980       ++cb;
1981       ++cr;
1982     }
1983     if (x > 0) {
1984       putRGBSeparateYCbCrClump(cp, y, cb, cr, (int) x, YCbCrVertSampling,
1985 			       w, 0, (int)(YCbCrHorizSampling - x), toskew);
1986       cp += x*3;
1987       y += YCbCrHorizSampling;
1988       ++cb;
1989       ++cr;
1990     }
1991     cp += (YCbCrVertSampling - 1)*w*3 + YCbCrVertSampling*toskew;
1992     y  += (YCbCrVertSampling - 1)*w + YCbCrVertSampling*fromskew;
1993     cb += fromskew2;
1994     cr += fromskew2;
1995     h -= YCbCrVertSampling;
1996   }
1997   if (h > 0) {
1998     for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
1999       putRGBSeparateYCbCrClump(cp, y, cb, cr, YCbCrHorizSampling, (int) h,
2000 			       w, 0, 0, toskew);
2001       cp += 3*YCbCrHorizSampling;
2002       y += YCbCrHorizSampling;
2003       ++cb;
2004       ++cr;
2005     }
2006     if (x > 0)
2007       putRGBSeparateYCbCrClump(cp, y, cb, cr, (int) x, (int) h, w,
2008 			       0, (int)(YCbCrHorizSampling-x),toskew);
2009   }
2010 }
2011 
2012 /*
2013  * 16-bit unpacked YCbCr samples => RGB
2014  */
putYCbCrseparate16bittile(cp,y,cb,cr,Map,w,h,fromskew,toskew)2015 static void putYCbCrseparate16bittile(cp, y, cb, cr, Map, w, h, fromskew, toskew)
2016      byte *cp;
2017      u_short *y, *cb, *cr;
2018      RGBvalue *Map;
2019      uint32 w, h;
2020      int fromskew, toskew;
2021 {
2022   uint32 x;
2023   int fromskew2 = fromskew/YCbCrHorizSampling;
2024 
2025   while (h >= YCbCrVertSampling) {
2026     for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
2027       putRGBSeparate16bitYCbCrClump(cp, y, cb, cr, YCbCrHorizSampling,
2028 		 		    YCbCrVertSampling, w, 0, 0, toskew);
2029       cp += 3*YCbCrHorizSampling;
2030       y += YCbCrHorizSampling;
2031       ++cb;
2032       ++cr;
2033     }
2034     if (x > 0) {
2035       putRGBSeparate16bitYCbCrClump(cp, y, cb, cr, (int) x, YCbCrVertSampling,
2036 				    w, 0, (int)(YCbCrHorizSampling - x),
2037 				    toskew);
2038       cp += x*3;
2039       y += YCbCrHorizSampling;
2040       ++cb;
2041       ++cr;
2042     }
2043     cp += (YCbCrVertSampling - 1)*w*3 + YCbCrVertSampling*toskew;
2044     y  += (YCbCrVertSampling - 1)*w + YCbCrVertSampling*fromskew;
2045     cb += fromskew2;
2046     cr += fromskew2;
2047     h -= YCbCrVertSampling;
2048   }
2049   if (h > 0) {
2050     for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
2051       putRGBSeparate16bitYCbCrClump(cp, y, cb, cr, YCbCrHorizSampling, (int) h,
2052 				    w, 0, 0, toskew);
2053       cp += 3*YCbCrHorizSampling;
2054       y += YCbCrHorizSampling;
2055       ++cb;
2056       ++cr;
2057     }
2058     if (x > 0)
2059       putRGBSeparate16bitYCbCrClump(cp, y, cb, cr, (int) x, (int) h, w,
2060 			 	    0, (int)(YCbCrHorizSampling-x),toskew);
2061   }
2062 }
2063 
2064 /*
2065  * Select the appropriate conversion routine for packed data.
2066  */
pickTileContigCase(Map)2067 static tileContigRoutine pickTileContigCase(Map)
2068      RGBvalue* Map;
2069 {
2070   tileContigRoutine put = 0;
2071 
2072   switch (photometric) {
2073   case PHOTOMETRIC_RGB:
2074     switch (bitspersample) {
2075     case 8:  put = (tileContigRoutine) putRGBcontig8bittile;   break;
2076     case 16: put = (tileContigRoutine) putRGBcontig16bittile;  break;
2077     }
2078     break;
2079 
2080   case PHOTOMETRIC_PALETTE:
2081     switch (bitspersample) {
2082     case 8: put = put8bitcmaptile; break;
2083     case 4: put = put4bitcmaptile; break;
2084     case 2: put = put2bitcmaptile; break;
2085     case 1: put = put1bitcmaptile; break;
2086     }
2087     break;
2088 
2089   case PHOTOMETRIC_MINISWHITE:
2090   case PHOTOMETRIC_MINISBLACK:
2091     switch (bitspersample) {
2092     case 16: put = (tileContigRoutine) put16bitbwtile; break;
2093     case 8:  put = putgreytile;    break;
2094     case 4:  put = put4bitbwtile;  break;
2095     case 2:  put = put2bitbwtile;  break;
2096     case 1:  put = put1bitbwtile;  break;
2097     }
2098     break;
2099 
2100   case PHOTOMETRIC_YCBCR:
2101     switch (bitspersample) {
2102     case 8: put = putcontig8bitYCbCrtile; break;
2103     }
2104     break;
2105   }
2106 
2107   if (put==0) TIFFError(filename, "Cannot handle format");
2108   return (put);
2109 }
2110 
2111 
2112 /*
2113  * Select the appropriate conversion routine for unpacked data.
2114  *
2115  * NB: we assume that unpacked single-channel data is directed
2116  *	 to the "packed" routines.
2117  */
pickTileSeparateCase(Map)2118 static tileSeparateRoutine pickTileSeparateCase(Map)
2119      RGBvalue* Map;
2120 {
2121   tileSeparateRoutine put = 0;
2122 
2123   switch (photometric) {
2124   case PHOTOMETRIC_RGB:
2125     switch (bitspersample) {
2126     case  8: put = (tileSeparateRoutine) putRGBseparate8bittile;  break;
2127     case 16: put = (tileSeparateRoutine) putRGBseparate16bittile; break;
2128     }
2129     break;
2130 
2131   case PHOTOMETRIC_YCBCR:
2132     switch (bitspersample) {
2133     case  8: put = (tileSeparateRoutine) putYCbCrseparate8bittile;  break;
2134     case 16: put = (tileSeparateRoutine) putYCbCrseparate16bittile; break;
2135     }
2136     break;
2137   }
2138 
2139   if (put==0) TIFFError(filename, "Cannot handle format");
2140   return (put);
2141 }
2142 
2143 
2144 
2145 /*******************************************/
2146 void
VersionInfoTIFF()2147 VersionInfoTIFF()      /* GRR 19980605 */
2148 {
2149   char temp[1024], *p, *q;
2150 
2151   strcpy(temp, TIFFGetVersion());
2152   p = temp;
2153   while (!isdigit(*p))
2154     ++p;
2155   if ((q = strchr(p, '\n')) != NULL)
2156     *q = '\0';
2157 
2158   fprintf(stderr, "   Compiled with libtiff %s", p);
2159 #ifdef TIFFLIB_VERSION
2160   fprintf(stderr, " of %d", TIFFLIB_VERSION);    /* e.g., 19960307 */
2161 #endif
2162   fprintf(stderr, ".\n");
2163 }
2164 
2165 
2166 
2167 #endif /* HAVE_TIFF */
2168