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