1 /* 2 * Copyright (c) 1991-1997 Sam Leffler 3 * Copyright (c) 1991-1997 Silicon Graphics, Inc. 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and 6 * its documentation for any purpose is hereby granted without fee, provided 7 * that (i) the above copyright notices and this permission notice appear in 8 * all copies of the software and related documentation, and (ii) the names of 9 * Sam Leffler and Silicon Graphics may not be used in any advertising or 10 * publicity relating to the software without the specific, prior written 11 * permission of Sam Leffler and Silicon Graphics. 12 * 13 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 14 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 15 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 16 * 17 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR 18 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 19 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 20 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 21 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 22 * OF THIS SOFTWARE. 23 */ 24 25 /* 26 * TIFF Library 27 * 28 * Read and return a packed RGBA image. 29 */ 30 #include <precomp.h> 31 //#include <stdio.h> 32 33 static int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32); 34 static int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32); 35 static int gtStripContig(TIFFRGBAImage*, uint32*, uint32, uint32); 36 static int gtStripSeparate(TIFFRGBAImage*, uint32*, uint32, uint32); 37 static int PickContigCase(TIFFRGBAImage*); 38 static int PickSeparateCase(TIFFRGBAImage*); 39 40 static int BuildMapUaToAa(TIFFRGBAImage* img); 41 static int BuildMapBitdepth16To8(TIFFRGBAImage* img); 42 43 static const char photoTag[] = "PhotometricInterpretation"; 44 45 /* 46 * Helper constants used in Orientation tag handling 47 */ 48 #define FLIP_VERTICALLY 0x01 49 #define FLIP_HORIZONTALLY 0x02 50 51 /* 52 * Color conversion constants. We will define display types here. 53 */ 54 55 static const TIFFDisplay display_sRGB = { 56 { /* XYZ -> luminance matrix */ 57 { 3.2410F, -1.5374F, -0.4986F }, 58 { -0.9692F, 1.8760F, 0.0416F }, 59 { 0.0556F, -0.2040F, 1.0570F } 60 }, 61 100.0F, 100.0F, 100.0F, /* Light o/p for reference white */ 62 255, 255, 255, /* Pixel values for ref. white */ 63 1.0F, 1.0F, 1.0F, /* Residual light o/p for black pixel */ 64 2.4F, 2.4F, 2.4F, /* Gamma values for the three guns */ 65 }; 66 67 /* 68 * Check the image to see if TIFFReadRGBAImage can deal with it. 69 * 1/0 is returned according to whether or not the image can 70 * be handled. If 0 is returned, emsg contains the reason 71 * why it is being rejected. 72 */ 73 int 74 TIFFRGBAImageOK(TIFF* tif, char emsg[1024]) 75 { 76 TIFFDirectory* td = &tif->tif_dir; 77 uint16 photometric; 78 int colorchannels; 79 80 if (!tif->tif_decodestatus) { 81 sprintf(emsg, "Sorry, requested compression method is not configured"); 82 return (0); 83 } 84 switch (td->td_bitspersample) { 85 case 1: 86 case 2: 87 case 4: 88 case 8: 89 case 16: 90 break; 91 default: 92 sprintf(emsg, "Sorry, can not handle images with %d-bit samples", 93 td->td_bitspersample); 94 return (0); 95 } 96 if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP) { 97 sprintf(emsg, "Sorry, can not handle images with IEEE floating-point samples"); 98 return (0); 99 } 100 colorchannels = td->td_samplesperpixel - td->td_extrasamples; 101 if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) { 102 switch (colorchannels) { 103 case 1: 104 photometric = PHOTOMETRIC_MINISBLACK; 105 break; 106 case 3: 107 photometric = PHOTOMETRIC_RGB; 108 break; 109 default: 110 sprintf(emsg, "Missing needed %s tag", photoTag); 111 return (0); 112 } 113 } 114 switch (photometric) { 115 case PHOTOMETRIC_MINISWHITE: 116 case PHOTOMETRIC_MINISBLACK: 117 case PHOTOMETRIC_PALETTE: 118 if (td->td_planarconfig == PLANARCONFIG_CONTIG 119 && td->td_samplesperpixel != 1 120 && td->td_bitspersample < 8 ) { 121 sprintf(emsg, 122 "Sorry, can not handle contiguous data with %s=%d, " 123 "and %s=%d and Bits/Sample=%d", 124 photoTag, photometric, 125 "Samples/pixel", td->td_samplesperpixel, 126 td->td_bitspersample); 127 return (0); 128 } 129 /* 130 * We should likely validate that any extra samples are either 131 * to be ignored, or are alpha, and if alpha we should try to use 132 * them. But for now we won't bother with this. 133 */ 134 break; 135 case PHOTOMETRIC_YCBCR: 136 /* 137 * TODO: if at all meaningful and useful, make more complete 138 * support check here, or better still, refactor to let supporting 139 * code decide whether there is support and what meaningful 140 * error to return 141 */ 142 break; 143 case PHOTOMETRIC_RGB: 144 if (colorchannels < 3) { 145 sprintf(emsg, "Sorry, can not handle RGB image with %s=%d", 146 "Color channels", colorchannels); 147 return (0); 148 } 149 break; 150 case PHOTOMETRIC_SEPARATED: 151 { 152 uint16 inkset; 153 TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); 154 if (inkset != INKSET_CMYK) { 155 sprintf(emsg, 156 "Sorry, can not handle separated image with %s=%d", 157 "InkSet", inkset); 158 return 0; 159 } 160 if (td->td_samplesperpixel < 4) { 161 sprintf(emsg, 162 "Sorry, can not handle separated image with %s=%d", 163 "Samples/pixel", td->td_samplesperpixel); 164 return 0; 165 } 166 break; 167 } 168 case PHOTOMETRIC_LOGL: 169 if (td->td_compression != COMPRESSION_SGILOG) { 170 sprintf(emsg, "Sorry, LogL data must have %s=%d", 171 "Compression", COMPRESSION_SGILOG); 172 return (0); 173 } 174 break; 175 case PHOTOMETRIC_LOGLUV: 176 if (td->td_compression != COMPRESSION_SGILOG && 177 td->td_compression != COMPRESSION_SGILOG24) { 178 sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d", 179 "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24); 180 return (0); 181 } 182 if (td->td_planarconfig != PLANARCONFIG_CONTIG) { 183 sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d", 184 "Planarconfiguration", td->td_planarconfig); 185 return (0); 186 } 187 if ( td->td_samplesperpixel != 3 || colorchannels != 3 ) { 188 sprintf(emsg, 189 "Sorry, can not handle image with %s=%d, %s=%d", 190 "Samples/pixel", td->td_samplesperpixel, 191 "colorchannels", colorchannels); 192 return 0; 193 } 194 break; 195 case PHOTOMETRIC_CIELAB: 196 if ( td->td_samplesperpixel != 3 || colorchannels != 3 || td->td_bitspersample != 8 ) { 197 sprintf(emsg, 198 "Sorry, can not handle image with %s=%d, %s=%d and %s=%d", 199 "Samples/pixel", td->td_samplesperpixel, 200 "colorchannels", colorchannels, 201 "Bits/sample", td->td_bitspersample); 202 return 0; 203 } 204 break; 205 default: 206 sprintf(emsg, "Sorry, can not handle image with %s=%d", 207 photoTag, photometric); 208 return (0); 209 } 210 return (1); 211 } 212 213 void 214 TIFFRGBAImageEnd(TIFFRGBAImage* img) 215 { 216 if (img->Map) { 217 _TIFFfree(img->Map); 218 img->Map = NULL; 219 } 220 if (img->BWmap) { 221 _TIFFfree(img->BWmap); 222 img->BWmap = NULL; 223 } 224 if (img->PALmap) { 225 _TIFFfree(img->PALmap); 226 img->PALmap = NULL; 227 } 228 if (img->ycbcr) { 229 _TIFFfree(img->ycbcr); 230 img->ycbcr = NULL; 231 } 232 if (img->cielab) { 233 _TIFFfree(img->cielab); 234 img->cielab = NULL; 235 } 236 if (img->UaToAa) { 237 _TIFFfree(img->UaToAa); 238 img->UaToAa = NULL; 239 } 240 if (img->Bitdepth16To8) { 241 _TIFFfree(img->Bitdepth16To8); 242 img->Bitdepth16To8 = NULL; 243 } 244 245 if( img->redcmap ) { 246 _TIFFfree( img->redcmap ); 247 _TIFFfree( img->greencmap ); 248 _TIFFfree( img->bluecmap ); 249 img->redcmap = img->greencmap = img->bluecmap = NULL; 250 } 251 } 252 253 static int 254 isCCITTCompression(TIFF* tif) 255 { 256 uint16 compress; 257 TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress); 258 return (compress == COMPRESSION_CCITTFAX3 || 259 compress == COMPRESSION_CCITTFAX4 || 260 compress == COMPRESSION_CCITTRLE || 261 compress == COMPRESSION_CCITTRLEW); 262 } 263 264 int 265 TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) 266 { 267 uint16* sampleinfo; 268 uint16 extrasamples; 269 uint16 planarconfig; 270 uint16 compress; 271 int colorchannels; 272 uint16 *red_orig, *green_orig, *blue_orig; 273 int n_color; 274 275 if( !TIFFRGBAImageOK(tif, emsg) ) 276 return 0; 277 278 /* Initialize to normal values */ 279 img->row_offset = 0; 280 img->col_offset = 0; 281 img->redcmap = NULL; 282 img->greencmap = NULL; 283 img->bluecmap = NULL; 284 img->Map = NULL; 285 img->BWmap = NULL; 286 img->PALmap = NULL; 287 img->ycbcr = NULL; 288 img->cielab = NULL; 289 img->UaToAa = NULL; 290 img->Bitdepth16To8 = NULL; 291 img->req_orientation = ORIENTATION_BOTLEFT; /* It is the default */ 292 293 img->tif = tif; 294 img->stoponerr = stop; 295 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample); 296 switch (img->bitspersample) { 297 case 1: 298 case 2: 299 case 4: 300 case 8: 301 case 16: 302 break; 303 default: 304 sprintf(emsg, "Sorry, can not handle images with %d-bit samples", 305 img->bitspersample); 306 goto fail_return; 307 } 308 img->alpha = 0; 309 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel); 310 TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, 311 &extrasamples, &sampleinfo); 312 if (extrasamples >= 1) 313 { 314 switch (sampleinfo[0]) { 315 case EXTRASAMPLE_UNSPECIFIED: /* Workaround for some images without */ 316 if (img->samplesperpixel > 3) /* correct info about alpha channel */ 317 img->alpha = EXTRASAMPLE_ASSOCALPHA; 318 break; 319 case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */ 320 case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */ 321 img->alpha = sampleinfo[0]; 322 break; 323 } 324 } 325 326 #ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA 327 if( !TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) 328 img->photometric = PHOTOMETRIC_MINISWHITE; 329 330 if( extrasamples == 0 331 && img->samplesperpixel == 4 332 && img->photometric == PHOTOMETRIC_RGB ) 333 { 334 img->alpha = EXTRASAMPLE_ASSOCALPHA; 335 extrasamples = 1; 336 } 337 #endif 338 339 colorchannels = img->samplesperpixel - extrasamples; 340 TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress); 341 TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig); 342 if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) { 343 switch (colorchannels) { 344 case 1: 345 if (isCCITTCompression(tif)) 346 img->photometric = PHOTOMETRIC_MINISWHITE; 347 else 348 img->photometric = PHOTOMETRIC_MINISBLACK; 349 break; 350 case 3: 351 img->photometric = PHOTOMETRIC_RGB; 352 break; 353 default: 354 sprintf(emsg, "Missing needed %s tag", photoTag); 355 goto fail_return; 356 } 357 } 358 switch (img->photometric) { 359 case PHOTOMETRIC_PALETTE: 360 if (!TIFFGetField(tif, TIFFTAG_COLORMAP, 361 &red_orig, &green_orig, &blue_orig)) { 362 sprintf(emsg, "Missing required \"Colormap\" tag"); 363 goto fail_return; 364 } 365 366 /* copy the colormaps so we can modify them */ 367 n_color = (1U << img->bitspersample); 368 img->redcmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color); 369 img->greencmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color); 370 img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color); 371 if( !img->redcmap || !img->greencmap || !img->bluecmap ) { 372 sprintf(emsg, "Out of memory for colormap copy"); 373 goto fail_return; 374 } 375 376 _TIFFmemcpy( img->redcmap, red_orig, n_color * 2 ); 377 _TIFFmemcpy( img->greencmap, green_orig, n_color * 2 ); 378 _TIFFmemcpy( img->bluecmap, blue_orig, n_color * 2 ); 379 380 /* fall through... */ 381 case PHOTOMETRIC_MINISWHITE: 382 case PHOTOMETRIC_MINISBLACK: 383 if (planarconfig == PLANARCONFIG_CONTIG 384 && img->samplesperpixel != 1 385 && img->bitspersample < 8 ) { 386 sprintf(emsg, 387 "Sorry, can not handle contiguous data with %s=%d, " 388 "and %s=%d and Bits/Sample=%d", 389 photoTag, img->photometric, 390 "Samples/pixel", img->samplesperpixel, 391 img->bitspersample); 392 goto fail_return; 393 } 394 break; 395 case PHOTOMETRIC_YCBCR: 396 /* It would probably be nice to have a reality check here. */ 397 if (planarconfig == PLANARCONFIG_CONTIG) 398 /* can rely on libjpeg to convert to RGB */ 399 /* XXX should restore current state on exit */ 400 switch (compress) { 401 case COMPRESSION_JPEG: 402 /* 403 * TODO: when complete tests verify complete desubsampling 404 * and YCbCr handling, remove use of TIFFTAG_JPEGCOLORMODE in 405 * favor of tif_getimage.c native handling 406 */ 407 TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB); 408 img->photometric = PHOTOMETRIC_RGB; 409 break; 410 default: 411 /* do nothing */; 412 break; 413 } 414 /* 415 * TODO: if at all meaningful and useful, make more complete 416 * support check here, or better still, refactor to let supporting 417 * code decide whether there is support and what meaningful 418 * error to return 419 */ 420 break; 421 case PHOTOMETRIC_RGB: 422 if (colorchannels < 3) { 423 sprintf(emsg, "Sorry, can not handle RGB image with %s=%d", 424 "Color channels", colorchannels); 425 goto fail_return; 426 } 427 break; 428 case PHOTOMETRIC_SEPARATED: 429 { 430 uint16 inkset; 431 TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); 432 if (inkset != INKSET_CMYK) { 433 sprintf(emsg, "Sorry, can not handle separated image with %s=%d", 434 "InkSet", inkset); 435 goto fail_return; 436 } 437 if (img->samplesperpixel < 4) { 438 sprintf(emsg, "Sorry, can not handle separated image with %s=%d", 439 "Samples/pixel", img->samplesperpixel); 440 goto fail_return; 441 } 442 } 443 break; 444 case PHOTOMETRIC_LOGL: 445 if (compress != COMPRESSION_SGILOG) { 446 sprintf(emsg, "Sorry, LogL data must have %s=%d", 447 "Compression", COMPRESSION_SGILOG); 448 goto fail_return; 449 } 450 TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); 451 img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */ 452 img->bitspersample = 8; 453 break; 454 case PHOTOMETRIC_LOGLUV: 455 if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) { 456 sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d", 457 "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24); 458 goto fail_return; 459 } 460 if (planarconfig != PLANARCONFIG_CONTIG) { 461 sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d", 462 "Planarconfiguration", planarconfig); 463 return (0); 464 } 465 TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); 466 img->photometric = PHOTOMETRIC_RGB; /* little white lie */ 467 img->bitspersample = 8; 468 break; 469 case PHOTOMETRIC_CIELAB: 470 break; 471 default: 472 sprintf(emsg, "Sorry, can not handle image with %s=%d", 473 photoTag, img->photometric); 474 goto fail_return; 475 } 476 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width); 477 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height); 478 TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation); 479 img->isContig = 480 !(planarconfig == PLANARCONFIG_SEPARATE && img->samplesperpixel > 1); 481 if (img->isContig) { 482 if (!PickContigCase(img)) { 483 sprintf(emsg, "Sorry, can not handle image"); 484 goto fail_return; 485 } 486 } else { 487 if (!PickSeparateCase(img)) { 488 sprintf(emsg, "Sorry, can not handle image"); 489 goto fail_return; 490 } 491 } 492 return 1; 493 494 fail_return: 495 TIFFRGBAImageEnd( img ); 496 return 0; 497 } 498 499 int 500 TIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) 501 { 502 if (img->get == NULL) { 503 TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No \"get\" routine setup"); 504 return (0); 505 } 506 if (img->put.any == NULL) { 507 TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), 508 "No \"put\" routine setupl; probably can not handle image format"); 509 return (0); 510 } 511 return (*img->get)(img, raster, w, h); 512 } 513 514 /* 515 * Read the specified image into an ABGR-format rastertaking in account 516 * specified orientation. 517 */ 518 int 519 TIFFReadRGBAImageOriented(TIFF* tif, 520 uint32 rwidth, uint32 rheight, uint32* raster, 521 int orientation, int stop) 522 { 523 char emsg[1024] = ""; 524 TIFFRGBAImage img; 525 int ok; 526 527 if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) { 528 img.req_orientation = (uint16)orientation; 529 /* XXX verify rwidth and rheight against width and height */ 530 ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth, 531 rwidth, img.height); 532 TIFFRGBAImageEnd(&img); 533 } else { 534 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg); 535 ok = 0; 536 } 537 return (ok); 538 } 539 540 /* 541 * Read the specified image into an ABGR-format raster. Use bottom left 542 * origin for raster by default. 543 */ 544 int 545 TIFFReadRGBAImage(TIFF* tif, 546 uint32 rwidth, uint32 rheight, uint32* raster, int stop) 547 { 548 return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster, 549 ORIENTATION_BOTLEFT, stop); 550 } 551 552 static int 553 setorientation(TIFFRGBAImage* img) 554 { 555 switch (img->orientation) { 556 case ORIENTATION_TOPLEFT: 557 case ORIENTATION_LEFTTOP: 558 if (img->req_orientation == ORIENTATION_TOPRIGHT || 559 img->req_orientation == ORIENTATION_RIGHTTOP) 560 return FLIP_HORIZONTALLY; 561 else if (img->req_orientation == ORIENTATION_BOTRIGHT || 562 img->req_orientation == ORIENTATION_RIGHTBOT) 563 return FLIP_HORIZONTALLY | FLIP_VERTICALLY; 564 else if (img->req_orientation == ORIENTATION_BOTLEFT || 565 img->req_orientation == ORIENTATION_LEFTBOT) 566 return FLIP_VERTICALLY; 567 else 568 return 0; 569 case ORIENTATION_TOPRIGHT: 570 case ORIENTATION_RIGHTTOP: 571 if (img->req_orientation == ORIENTATION_TOPLEFT || 572 img->req_orientation == ORIENTATION_LEFTTOP) 573 return FLIP_HORIZONTALLY; 574 else if (img->req_orientation == ORIENTATION_BOTRIGHT || 575 img->req_orientation == ORIENTATION_RIGHTBOT) 576 return FLIP_VERTICALLY; 577 else if (img->req_orientation == ORIENTATION_BOTLEFT || 578 img->req_orientation == ORIENTATION_LEFTBOT) 579 return FLIP_HORIZONTALLY | FLIP_VERTICALLY; 580 else 581 return 0; 582 case ORIENTATION_BOTRIGHT: 583 case ORIENTATION_RIGHTBOT: 584 if (img->req_orientation == ORIENTATION_TOPLEFT || 585 img->req_orientation == ORIENTATION_LEFTTOP) 586 return FLIP_HORIZONTALLY | FLIP_VERTICALLY; 587 else if (img->req_orientation == ORIENTATION_TOPRIGHT || 588 img->req_orientation == ORIENTATION_RIGHTTOP) 589 return FLIP_VERTICALLY; 590 else if (img->req_orientation == ORIENTATION_BOTLEFT || 591 img->req_orientation == ORIENTATION_LEFTBOT) 592 return FLIP_HORIZONTALLY; 593 else 594 return 0; 595 case ORIENTATION_BOTLEFT: 596 case ORIENTATION_LEFTBOT: 597 if (img->req_orientation == ORIENTATION_TOPLEFT || 598 img->req_orientation == ORIENTATION_LEFTTOP) 599 return FLIP_VERTICALLY; 600 else if (img->req_orientation == ORIENTATION_TOPRIGHT || 601 img->req_orientation == ORIENTATION_RIGHTTOP) 602 return FLIP_HORIZONTALLY | FLIP_VERTICALLY; 603 else if (img->req_orientation == ORIENTATION_BOTRIGHT || 604 img->req_orientation == ORIENTATION_RIGHTBOT) 605 return FLIP_HORIZONTALLY; 606 else 607 return 0; 608 default: /* NOTREACHED */ 609 return 0; 610 } 611 } 612 613 /* 614 * Get an tile-organized image that has 615 * PlanarConfiguration contiguous if SamplesPerPixel > 1 616 * or 617 * SamplesPerPixel == 1 618 */ 619 static int 620 gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) 621 { 622 TIFF* tif = img->tif; 623 tileContigRoutine put = img->put.contig; 624 uint32 col, row, y, rowstoread; 625 tmsize_t pos; 626 uint32 tw, th; 627 unsigned char* buf = NULL; 628 int32 fromskew, toskew; 629 uint32 nrow; 630 int ret = 1, flip; 631 uint32 this_tw, tocol; 632 int32 this_toskew, leftmost_toskew; 633 int32 leftmost_fromskew; 634 uint32 leftmost_tw; 635 tmsize_t bufsize; 636 637 bufsize = TIFFTileSize(tif); 638 if (bufsize == 0) { 639 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer"); 640 return (0); 641 } 642 643 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); 644 TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); 645 646 flip = setorientation(img); 647 if (flip & FLIP_VERTICALLY) { 648 y = h - 1; 649 toskew = -(int32)(tw + w); 650 } 651 else { 652 y = 0; 653 toskew = -(int32)(tw - w); 654 } 655 656 /* 657 * Leftmost tile is clipped on left side if col_offset > 0. 658 */ 659 leftmost_fromskew = img->col_offset % tw; 660 leftmost_tw = tw - leftmost_fromskew; 661 leftmost_toskew = toskew + leftmost_fromskew; 662 for (row = 0; ret != 0 && row < h; row += nrow) 663 { 664 rowstoread = th - (row + img->row_offset) % th; 665 nrow = (row + rowstoread > h ? h - row : rowstoread); 666 fromskew = leftmost_fromskew; 667 this_tw = leftmost_tw; 668 this_toskew = leftmost_toskew; 669 tocol = 0; 670 col = img->col_offset; 671 while (tocol < w) 672 { 673 if (_TIFFReadTileAndAllocBuffer(tif, (void**) &buf, bufsize, col, 674 row+img->row_offset, 0, 0)==(tmsize_t)(-1) && 675 (buf == NULL || img->stoponerr)) 676 { 677 ret = 0; 678 break; 679 } 680 pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif) + \ 681 ((tmsize_t) fromskew * img->samplesperpixel); 682 if (tocol + this_tw > w) 683 { 684 /* 685 * Rightmost tile is clipped on right side. 686 */ 687 fromskew = tw - (w - tocol); 688 this_tw = tw - fromskew; 689 this_toskew = toskew + fromskew; 690 } 691 (*put)(img, raster+y*w+tocol, tocol, y, this_tw, nrow, fromskew, this_toskew, buf + pos); 692 tocol += this_tw; 693 col += this_tw; 694 /* 695 * After the leftmost tile, tiles are no longer clipped on left side. 696 */ 697 fromskew = 0; 698 this_tw = tw; 699 this_toskew = toskew; 700 } 701 702 y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow); 703 } 704 _TIFFfree(buf); 705 706 if (flip & FLIP_HORIZONTALLY) { 707 uint32 line; 708 709 for (line = 0; line < h; line++) { 710 uint32 *left = raster + (line * w); 711 uint32 *right = left + w - 1; 712 713 while ( left < right ) { 714 uint32 temp = *left; 715 *left = *right; 716 *right = temp; 717 left++; 718 right--; 719 } 720 } 721 } 722 723 return (ret); 724 } 725 726 /* 727 * Get an tile-organized image that has 728 * SamplesPerPixel > 1 729 * PlanarConfiguration separated 730 * We assume that all such images are RGB. 731 */ 732 static int 733 gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) 734 { 735 TIFF* tif = img->tif; 736 tileSeparateRoutine put = img->put.separate; 737 uint32 col, row, y, rowstoread; 738 tmsize_t pos; 739 uint32 tw, th; 740 unsigned char* buf = NULL; 741 unsigned char* p0 = NULL; 742 unsigned char* p1 = NULL; 743 unsigned char* p2 = NULL; 744 unsigned char* pa = NULL; 745 tmsize_t tilesize; 746 tmsize_t bufsize; 747 int32 fromskew, toskew; 748 int alpha = img->alpha; 749 uint32 nrow; 750 int ret = 1, flip; 751 uint16 colorchannels; 752 uint32 this_tw, tocol; 753 int32 this_toskew, leftmost_toskew; 754 int32 leftmost_fromskew; 755 uint32 leftmost_tw; 756 757 tilesize = TIFFTileSize(tif); 758 bufsize = _TIFFMultiplySSize(tif, alpha?4:3,tilesize, "gtTileSeparate"); 759 if (bufsize == 0) { 760 return (0); 761 } 762 763 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); 764 TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); 765 766 flip = setorientation(img); 767 if (flip & FLIP_VERTICALLY) { 768 y = h - 1; 769 toskew = -(int32)(tw + w); 770 } 771 else { 772 y = 0; 773 toskew = -(int32)(tw - w); 774 } 775 776 switch( img->photometric ) 777 { 778 case PHOTOMETRIC_MINISWHITE: 779 case PHOTOMETRIC_MINISBLACK: 780 case PHOTOMETRIC_PALETTE: 781 colorchannels = 1; 782 break; 783 784 default: 785 colorchannels = 3; 786 break; 787 } 788 789 /* 790 * Leftmost tile is clipped on left side if col_offset > 0. 791 */ 792 leftmost_fromskew = img->col_offset % tw; 793 leftmost_tw = tw - leftmost_fromskew; 794 leftmost_toskew = toskew + leftmost_fromskew; 795 for (row = 0; ret != 0 && row < h; row += nrow) 796 { 797 rowstoread = th - (row + img->row_offset) % th; 798 nrow = (row + rowstoread > h ? h - row : rowstoread); 799 fromskew = leftmost_fromskew; 800 this_tw = leftmost_tw; 801 this_toskew = leftmost_toskew; 802 tocol = 0; 803 col = img->col_offset; 804 while (tocol < w) 805 { 806 if( buf == NULL ) 807 { 808 if (_TIFFReadTileAndAllocBuffer( 809 tif, (void**) &buf, bufsize, col, 810 row+img->row_offset,0,0)==(tmsize_t)(-1) 811 && (buf == NULL || img->stoponerr)) 812 { 813 ret = 0; 814 break; 815 } 816 p0 = buf; 817 if( colorchannels == 1 ) 818 { 819 p2 = p1 = p0; 820 pa = (alpha?(p0+3*tilesize):NULL); 821 } 822 else 823 { 824 p1 = p0 + tilesize; 825 p2 = p1 + tilesize; 826 pa = (alpha?(p2+tilesize):NULL); 827 } 828 } 829 else if (TIFFReadTile(tif, p0, col, 830 row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr) 831 { 832 ret = 0; 833 break; 834 } 835 if (colorchannels > 1 836 && TIFFReadTile(tif, p1, col, 837 row+img->row_offset,0,1) == (tmsize_t)(-1) 838 && img->stoponerr) 839 { 840 ret = 0; 841 break; 842 } 843 if (colorchannels > 1 844 && TIFFReadTile(tif, p2, col, 845 row+img->row_offset,0,2) == (tmsize_t)(-1) 846 && img->stoponerr) 847 { 848 ret = 0; 849 break; 850 } 851 if (alpha 852 && TIFFReadTile(tif,pa,col, 853 row+img->row_offset,0,colorchannels) == (tmsize_t)(-1) 854 && img->stoponerr) 855 { 856 ret = 0; 857 break; 858 } 859 860 pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif) + \ 861 ((tmsize_t) fromskew * img->samplesperpixel); 862 if (tocol + this_tw > w) 863 { 864 /* 865 * Rightmost tile is clipped on right side. 866 */ 867 fromskew = tw - (w - tocol); 868 this_tw = tw - fromskew; 869 this_toskew = toskew + fromskew; 870 } 871 (*put)(img, raster+y*w+tocol, tocol, y, this_tw, nrow, fromskew, this_toskew, \ 872 p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL)); 873 tocol += this_tw; 874 col += this_tw; 875 /* 876 * After the leftmost tile, tiles are no longer clipped on left side. 877 */ 878 fromskew = 0; 879 this_tw = tw; 880 this_toskew = toskew; 881 } 882 883 y += ((flip & FLIP_VERTICALLY) ?-(int32) nrow : (int32) nrow); 884 } 885 886 if (flip & FLIP_HORIZONTALLY) { 887 uint32 line; 888 889 for (line = 0; line < h; line++) { 890 uint32 *left = raster + (line * w); 891 uint32 *right = left + w - 1; 892 893 while ( left < right ) { 894 uint32 temp = *left; 895 *left = *right; 896 *right = temp; 897 left++; 898 right--; 899 } 900 } 901 } 902 903 _TIFFfree(buf); 904 return (ret); 905 } 906 907 /* 908 * Get a strip-organized image that has 909 * PlanarConfiguration contiguous if SamplesPerPixel > 1 910 * or 911 * SamplesPerPixel == 1 912 */ 913 static int 914 gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) 915 { 916 TIFF* tif = img->tif; 917 tileContigRoutine put = img->put.contig; 918 uint32 row, y, nrow, nrowsub, rowstoread; 919 tmsize_t pos; 920 unsigned char* buf = NULL; 921 uint32 rowsperstrip; 922 uint16 subsamplinghor,subsamplingver; 923 uint32 imagewidth = img->width; 924 tmsize_t scanline; 925 int32 fromskew, toskew; 926 int ret = 1, flip; 927 tmsize_t maxstripsize; 928 929 TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver); 930 if( subsamplingver == 0 ) { 931 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Invalid vertical YCbCr subsampling"); 932 return (0); 933 } 934 935 maxstripsize = TIFFStripSize(tif); 936 937 flip = setorientation(img); 938 if (flip & FLIP_VERTICALLY) { 939 y = h - 1; 940 toskew = -(int32)(w + w); 941 } else { 942 y = 0; 943 toskew = -(int32)(w - w); 944 } 945 946 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); 947 948 scanline = TIFFScanlineSize(tif); 949 fromskew = (w < imagewidth ? imagewidth - w : 0); 950 for (row = 0; row < h; row += nrow) 951 { 952 uint32 temp; 953 rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; 954 nrow = (row + rowstoread > h ? h - row : rowstoread); 955 nrowsub = nrow; 956 if ((nrowsub%subsamplingver)!=0) 957 nrowsub+=subsamplingver-nrowsub%subsamplingver; 958 temp = (row + img->row_offset)%rowsperstrip + nrowsub; 959 if( scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline) ) 960 { 961 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in gtStripContig"); 962 return 0; 963 } 964 if (_TIFFReadEncodedStripAndAllocBuffer(tif, 965 TIFFComputeStrip(tif,row+img->row_offset, 0), 966 (void**)(&buf), 967 maxstripsize, 968 temp * scanline)==(tmsize_t)(-1) 969 && (buf == NULL || img->stoponerr)) 970 { 971 ret = 0; 972 break; 973 } 974 975 pos = ((row + img->row_offset) % rowsperstrip) * scanline + \ 976 ((tmsize_t) img->col_offset * img->samplesperpixel); 977 (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos); 978 y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow); 979 } 980 981 if (flip & FLIP_HORIZONTALLY) { 982 uint32 line; 983 984 for (line = 0; line < h; line++) { 985 uint32 *left = raster + (line * w); 986 uint32 *right = left + w - 1; 987 988 while ( left < right ) { 989 uint32 temp = *left; 990 *left = *right; 991 *right = temp; 992 left++; 993 right--; 994 } 995 } 996 } 997 998 _TIFFfree(buf); 999 return (ret); 1000 } 1001 1002 /* 1003 * Get a strip-organized image with 1004 * SamplesPerPixel > 1 1005 * PlanarConfiguration separated 1006 * We assume that all such images are RGB. 1007 */ 1008 static int 1009 gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) 1010 { 1011 TIFF* tif = img->tif; 1012 tileSeparateRoutine put = img->put.separate; 1013 unsigned char *buf = NULL; 1014 unsigned char *p0 = NULL, *p1 = NULL, *p2 = NULL, *pa = NULL; 1015 uint32 row, y, nrow, rowstoread; 1016 tmsize_t pos; 1017 tmsize_t scanline; 1018 uint32 rowsperstrip, offset_row; 1019 uint32 imagewidth = img->width; 1020 tmsize_t stripsize; 1021 tmsize_t bufsize; 1022 int32 fromskew, toskew; 1023 int alpha = img->alpha; 1024 int ret = 1, flip; 1025 uint16 colorchannels; 1026 1027 stripsize = TIFFStripSize(tif); 1028 bufsize = _TIFFMultiplySSize(tif,alpha?4:3,stripsize, "gtStripSeparate"); 1029 if (bufsize == 0) { 1030 return (0); 1031 } 1032 1033 flip = setorientation(img); 1034 if (flip & FLIP_VERTICALLY) { 1035 y = h - 1; 1036 toskew = -(int32)(w + w); 1037 } 1038 else { 1039 y = 0; 1040 toskew = -(int32)(w - w); 1041 } 1042 1043 switch( img->photometric ) 1044 { 1045 case PHOTOMETRIC_MINISWHITE: 1046 case PHOTOMETRIC_MINISBLACK: 1047 case PHOTOMETRIC_PALETTE: 1048 colorchannels = 1; 1049 break; 1050 1051 default: 1052 colorchannels = 3; 1053 break; 1054 } 1055 1056 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); 1057 scanline = TIFFScanlineSize(tif); 1058 fromskew = (w < imagewidth ? imagewidth - w : 0); 1059 for (row = 0; row < h; row += nrow) 1060 { 1061 uint32 temp; 1062 rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; 1063 nrow = (row + rowstoread > h ? h - row : rowstoread); 1064 offset_row = row + img->row_offset; 1065 temp = (row + img->row_offset)%rowsperstrip + nrow; 1066 if( scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline) ) 1067 { 1068 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in gtStripSeparate"); 1069 return 0; 1070 } 1071 if( buf == NULL ) 1072 { 1073 if (_TIFFReadEncodedStripAndAllocBuffer( 1074 tif, TIFFComputeStrip(tif, offset_row, 0), 1075 (void**) &buf, bufsize, 1076 temp * scanline)==(tmsize_t)(-1) 1077 && (buf == NULL || img->stoponerr)) 1078 { 1079 ret = 0; 1080 break; 1081 } 1082 p0 = buf; 1083 if( colorchannels == 1 ) 1084 { 1085 p2 = p1 = p0; 1086 pa = (alpha?(p0+3*stripsize):NULL); 1087 } 1088 else 1089 { 1090 p1 = p0 + stripsize; 1091 p2 = p1 + stripsize; 1092 pa = (alpha?(p2+stripsize):NULL); 1093 } 1094 } 1095 else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0), 1096 p0, temp * scanline)==(tmsize_t)(-1) 1097 && img->stoponerr) 1098 { 1099 ret = 0; 1100 break; 1101 } 1102 if (colorchannels > 1 1103 && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1), 1104 p1, temp * scanline) == (tmsize_t)(-1) 1105 && img->stoponerr) 1106 { 1107 ret = 0; 1108 break; 1109 } 1110 if (colorchannels > 1 1111 && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2), 1112 p2, temp * scanline) == (tmsize_t)(-1) 1113 && img->stoponerr) 1114 { 1115 ret = 0; 1116 break; 1117 } 1118 if (alpha) 1119 { 1120 if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, colorchannels), 1121 pa, temp * scanline)==(tmsize_t)(-1) 1122 && img->stoponerr) 1123 { 1124 ret = 0; 1125 break; 1126 } 1127 } 1128 1129 pos = ((row + img->row_offset) % rowsperstrip) * scanline + \ 1130 ((tmsize_t) img->col_offset * img->samplesperpixel); 1131 (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos, 1132 p2 + pos, (alpha?(pa+pos):NULL)); 1133 y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow); 1134 } 1135 1136 if (flip & FLIP_HORIZONTALLY) { 1137 uint32 line; 1138 1139 for (line = 0; line < h; line++) { 1140 uint32 *left = raster + (line * w); 1141 uint32 *right = left + w - 1; 1142 1143 while ( left < right ) { 1144 uint32 temp = *left; 1145 *left = *right; 1146 *right = temp; 1147 left++; 1148 right--; 1149 } 1150 } 1151 } 1152 1153 _TIFFfree(buf); 1154 return (ret); 1155 } 1156 1157 /* 1158 * The following routines move decoded data returned 1159 * from the TIFF library into rasters filled with packed 1160 * ABGR pixels (i.e. suitable for passing to lrecwrite.) 1161 * 1162 * The routines have been created according to the most 1163 * important cases and optimized. PickContigCase and 1164 * PickSeparateCase analyze the parameters and select 1165 * the appropriate "get" and "put" routine to use. 1166 */ 1167 #define REPEAT8(op) REPEAT4(op); REPEAT4(op) 1168 #define REPEAT4(op) REPEAT2(op); REPEAT2(op) 1169 #define REPEAT2(op) op; op 1170 #define CASE8(x,op) \ 1171 switch (x) { \ 1172 case 7: op; /*-fallthrough*/ \ 1173 case 6: op; /*-fallthrough*/ \ 1174 case 5: op; /*-fallthrough*/ \ 1175 case 4: op; /*-fallthrough*/ \ 1176 case 3: op; /*-fallthrough*/ \ 1177 case 2: op; /*-fallthrough*/ \ 1178 case 1: op; \ 1179 } 1180 #define CASE4(x,op) switch (x) { case 3: op; /*-fallthrough*/ case 2: op; /*-fallthrough*/ case 1: op; } 1181 #define NOP 1182 1183 #define UNROLL8(w, op1, op2) { \ 1184 uint32 _x; \ 1185 for (_x = w; _x >= 8; _x -= 8) { \ 1186 op1; \ 1187 REPEAT8(op2); \ 1188 } \ 1189 if (_x > 0) { \ 1190 op1; \ 1191 CASE8(_x,op2); \ 1192 } \ 1193 } 1194 #define UNROLL4(w, op1, op2) { \ 1195 uint32 _x; \ 1196 for (_x = w; _x >= 4; _x -= 4) { \ 1197 op1; \ 1198 REPEAT4(op2); \ 1199 } \ 1200 if (_x > 0) { \ 1201 op1; \ 1202 CASE4(_x,op2); \ 1203 } \ 1204 } 1205 #define UNROLL2(w, op1, op2) { \ 1206 uint32 _x; \ 1207 for (_x = w; _x >= 2; _x -= 2) { \ 1208 op1; \ 1209 REPEAT2(op2); \ 1210 } \ 1211 if (_x) { \ 1212 op1; \ 1213 op2; \ 1214 } \ 1215 } 1216 1217 #define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; } 1218 #define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; } 1219 1220 #define A1 (((uint32)0xffL)<<24) 1221 #define PACK(r,g,b) \ 1222 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1) 1223 #define PACK4(r,g,b,a) \ 1224 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24)) 1225 #define W2B(v) (((v)>>8)&0xff) 1226 /* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */ 1227 #define PACKW(r,g,b) \ 1228 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1) 1229 #define PACKW4(r,g,b,a) \ 1230 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24)) 1231 1232 #define DECLAREContigPutFunc(name) \ 1233 static void name(\ 1234 TIFFRGBAImage* img, \ 1235 uint32* cp, \ 1236 uint32 x, uint32 y, \ 1237 uint32 w, uint32 h, \ 1238 int32 fromskew, int32 toskew, \ 1239 unsigned char* pp \ 1240 ) 1241 1242 /* 1243 * 8-bit palette => colormap/RGB 1244 */ 1245 DECLAREContigPutFunc(put8bitcmaptile) 1246 { 1247 uint32** PALmap = img->PALmap; 1248 int samplesperpixel = img->samplesperpixel; 1249 1250 (void) y; 1251 for( ; h > 0; --h) { 1252 for (x = w; x > 0; --x) 1253 { 1254 *cp++ = PALmap[*pp][0]; 1255 pp += samplesperpixel; 1256 } 1257 cp += toskew; 1258 pp += fromskew; 1259 } 1260 } 1261 1262 /* 1263 * 4-bit palette => colormap/RGB 1264 */ 1265 DECLAREContigPutFunc(put4bitcmaptile) 1266 { 1267 uint32** PALmap = img->PALmap; 1268 1269 (void) x; (void) y; 1270 fromskew /= 2; 1271 for( ; h > 0; --h) { 1272 uint32* bw; 1273 UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++); 1274 cp += toskew; 1275 pp += fromskew; 1276 } 1277 } 1278 1279 /* 1280 * 2-bit palette => colormap/RGB 1281 */ 1282 DECLAREContigPutFunc(put2bitcmaptile) 1283 { 1284 uint32** PALmap = img->PALmap; 1285 1286 (void) x; (void) y; 1287 fromskew /= 4; 1288 for( ; h > 0; --h) { 1289 uint32* bw; 1290 UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++); 1291 cp += toskew; 1292 pp += fromskew; 1293 } 1294 } 1295 1296 /* 1297 * 1-bit palette => colormap/RGB 1298 */ 1299 DECLAREContigPutFunc(put1bitcmaptile) 1300 { 1301 uint32** PALmap = img->PALmap; 1302 1303 (void) x; (void) y; 1304 fromskew /= 8; 1305 for( ; h > 0; --h) { 1306 uint32* bw; 1307 UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++); 1308 cp += toskew; 1309 pp += fromskew; 1310 } 1311 } 1312 1313 /* 1314 * 8-bit greyscale => colormap/RGB 1315 */ 1316 DECLAREContigPutFunc(putgreytile) 1317 { 1318 int samplesperpixel = img->samplesperpixel; 1319 uint32** BWmap = img->BWmap; 1320 1321 (void) y; 1322 for( ; h > 0; --h) { 1323 for (x = w; x > 0; --x) 1324 { 1325 *cp++ = BWmap[*pp][0]; 1326 pp += samplesperpixel; 1327 } 1328 cp += toskew; 1329 pp += fromskew; 1330 } 1331 } 1332 1333 /* 1334 * 8-bit greyscale with associated alpha => colormap/RGBA 1335 */ 1336 DECLAREContigPutFunc(putagreytile) 1337 { 1338 int samplesperpixel = img->samplesperpixel; 1339 uint32** BWmap = img->BWmap; 1340 1341 (void) y; 1342 for( ; h > 0; --h) { 1343 for (x = w; x > 0; --x) 1344 { 1345 *cp++ = BWmap[*pp][0] & ((uint32)*(pp+1) << 24 | ~A1); 1346 pp += samplesperpixel; 1347 } 1348 cp += toskew; 1349 pp += fromskew; 1350 } 1351 } 1352 1353 /* 1354 * 16-bit greyscale => colormap/RGB 1355 */ 1356 DECLAREContigPutFunc(put16bitbwtile) 1357 { 1358 int samplesperpixel = img->samplesperpixel; 1359 uint32** BWmap = img->BWmap; 1360 1361 (void) y; 1362 for( ; h > 0; --h) { 1363 uint16 *wp = (uint16 *) pp; 1364 1365 for (x = w; x > 0; --x) 1366 { 1367 /* use high order byte of 16bit value */ 1368 1369 *cp++ = BWmap[*wp >> 8][0]; 1370 pp += 2 * samplesperpixel; 1371 wp += samplesperpixel; 1372 } 1373 cp += toskew; 1374 pp += fromskew; 1375 } 1376 } 1377 1378 /* 1379 * 1-bit bilevel => colormap/RGB 1380 */ 1381 DECLAREContigPutFunc(put1bitbwtile) 1382 { 1383 uint32** BWmap = img->BWmap; 1384 1385 (void) x; (void) y; 1386 fromskew /= 8; 1387 for( ; h > 0; --h) { 1388 uint32* bw; 1389 UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++); 1390 cp += toskew; 1391 pp += fromskew; 1392 } 1393 } 1394 1395 /* 1396 * 2-bit greyscale => colormap/RGB 1397 */ 1398 DECLAREContigPutFunc(put2bitbwtile) 1399 { 1400 uint32** BWmap = img->BWmap; 1401 1402 (void) x; (void) y; 1403 fromskew /= 4; 1404 for( ; h > 0; --h) { 1405 uint32* bw; 1406 UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++); 1407 cp += toskew; 1408 pp += fromskew; 1409 } 1410 } 1411 1412 /* 1413 * 4-bit greyscale => colormap/RGB 1414 */ 1415 DECLAREContigPutFunc(put4bitbwtile) 1416 { 1417 uint32** BWmap = img->BWmap; 1418 1419 (void) x; (void) y; 1420 fromskew /= 2; 1421 for( ; h > 0; --h) { 1422 uint32* bw; 1423 UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++); 1424 cp += toskew; 1425 pp += fromskew; 1426 } 1427 } 1428 1429 /* 1430 * 8-bit packed samples, no Map => RGB 1431 */ 1432 DECLAREContigPutFunc(putRGBcontig8bittile) 1433 { 1434 int samplesperpixel = img->samplesperpixel; 1435 1436 (void) x; (void) y; 1437 fromskew *= samplesperpixel; 1438 for( ; h > 0; --h) { 1439 UNROLL8(w, NOP, 1440 *cp++ = PACK(pp[0], pp[1], pp[2]); 1441 pp += samplesperpixel); 1442 cp += toskew; 1443 pp += fromskew; 1444 } 1445 } 1446 1447 /* 1448 * 8-bit packed samples => RGBA w/ associated alpha 1449 * (known to have Map == NULL) 1450 */ 1451 DECLAREContigPutFunc(putRGBAAcontig8bittile) 1452 { 1453 int samplesperpixel = img->samplesperpixel; 1454 1455 (void) x; (void) y; 1456 fromskew *= samplesperpixel; 1457 for( ; h > 0; --h) { 1458 UNROLL8(w, NOP, 1459 *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]); 1460 pp += samplesperpixel); 1461 cp += toskew; 1462 pp += fromskew; 1463 } 1464 } 1465 1466 /* 1467 * 8-bit packed samples => RGBA w/ unassociated alpha 1468 * (known to have Map == NULL) 1469 */ 1470 DECLAREContigPutFunc(putRGBUAcontig8bittile) 1471 { 1472 int samplesperpixel = img->samplesperpixel; 1473 (void) y; 1474 fromskew *= samplesperpixel; 1475 for( ; h > 0; --h) { 1476 uint32 r, g, b, a; 1477 uint8* m; 1478 for (x = w; x > 0; --x) { 1479 a = pp[3]; 1480 m = img->UaToAa+((size_t) a<<8); 1481 r = m[pp[0]]; 1482 g = m[pp[1]]; 1483 b = m[pp[2]]; 1484 *cp++ = PACK4(r,g,b,a); 1485 pp += samplesperpixel; 1486 } 1487 cp += toskew; 1488 pp += fromskew; 1489 } 1490 } 1491 1492 /* 1493 * 16-bit packed samples => RGB 1494 */ 1495 DECLAREContigPutFunc(putRGBcontig16bittile) 1496 { 1497 int samplesperpixel = img->samplesperpixel; 1498 uint16 *wp = (uint16 *)pp; 1499 (void) y; 1500 fromskew *= samplesperpixel; 1501 for( ; h > 0; --h) { 1502 for (x = w; x > 0; --x) { 1503 *cp++ = PACK(img->Bitdepth16To8[wp[0]], 1504 img->Bitdepth16To8[wp[1]], 1505 img->Bitdepth16To8[wp[2]]); 1506 wp += samplesperpixel; 1507 } 1508 cp += toskew; 1509 wp += fromskew; 1510 } 1511 } 1512 1513 /* 1514 * 16-bit packed samples => RGBA w/ associated alpha 1515 * (known to have Map == NULL) 1516 */ 1517 DECLAREContigPutFunc(putRGBAAcontig16bittile) 1518 { 1519 int samplesperpixel = img->samplesperpixel; 1520 uint16 *wp = (uint16 *)pp; 1521 (void) y; 1522 fromskew *= samplesperpixel; 1523 for( ; h > 0; --h) { 1524 for (x = w; x > 0; --x) { 1525 *cp++ = PACK4(img->Bitdepth16To8[wp[0]], 1526 img->Bitdepth16To8[wp[1]], 1527 img->Bitdepth16To8[wp[2]], 1528 img->Bitdepth16To8[wp[3]]); 1529 wp += samplesperpixel; 1530 } 1531 cp += toskew; 1532 wp += fromskew; 1533 } 1534 } 1535 1536 /* 1537 * 16-bit packed samples => RGBA w/ unassociated alpha 1538 * (known to have Map == NULL) 1539 */ 1540 DECLAREContigPutFunc(putRGBUAcontig16bittile) 1541 { 1542 int samplesperpixel = img->samplesperpixel; 1543 uint16 *wp = (uint16 *)pp; 1544 (void) y; 1545 fromskew *= samplesperpixel; 1546 for( ; h > 0; --h) { 1547 uint32 r,g,b,a; 1548 uint8* m; 1549 for (x = w; x > 0; --x) { 1550 a = img->Bitdepth16To8[wp[3]]; 1551 m = img->UaToAa+((size_t) a<<8); 1552 r = m[img->Bitdepth16To8[wp[0]]]; 1553 g = m[img->Bitdepth16To8[wp[1]]]; 1554 b = m[img->Bitdepth16To8[wp[2]]]; 1555 *cp++ = PACK4(r,g,b,a); 1556 wp += samplesperpixel; 1557 } 1558 cp += toskew; 1559 wp += fromskew; 1560 } 1561 } 1562 1563 /* 1564 * 8-bit packed CMYK samples w/o Map => RGB 1565 * 1566 * NB: The conversion of CMYK->RGB is *very* crude. 1567 */ 1568 DECLAREContigPutFunc(putRGBcontig8bitCMYKtile) 1569 { 1570 int samplesperpixel = img->samplesperpixel; 1571 uint16 r, g, b, k; 1572 1573 (void) x; (void) y; 1574 fromskew *= samplesperpixel; 1575 for( ; h > 0; --h) { 1576 UNROLL8(w, NOP, 1577 k = 255 - pp[3]; 1578 r = (k*(255-pp[0]))/255; 1579 g = (k*(255-pp[1]))/255; 1580 b = (k*(255-pp[2]))/255; 1581 *cp++ = PACK(r, g, b); 1582 pp += samplesperpixel); 1583 cp += toskew; 1584 pp += fromskew; 1585 } 1586 } 1587 1588 /* 1589 * 8-bit packed CMYK samples w/Map => RGB 1590 * 1591 * NB: The conversion of CMYK->RGB is *very* crude. 1592 */ 1593 DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile) 1594 { 1595 int samplesperpixel = img->samplesperpixel; 1596 TIFFRGBValue* Map = img->Map; 1597 uint16 r, g, b, k; 1598 1599 (void) y; 1600 fromskew *= samplesperpixel; 1601 for( ; h > 0; --h) { 1602 for (x = w; x > 0; --x) { 1603 k = 255 - pp[3]; 1604 r = (k*(255-pp[0]))/255; 1605 g = (k*(255-pp[1]))/255; 1606 b = (k*(255-pp[2]))/255; 1607 *cp++ = PACK(Map[r], Map[g], Map[b]); 1608 pp += samplesperpixel; 1609 } 1610 pp += fromskew; 1611 cp += toskew; 1612 } 1613 } 1614 1615 #define DECLARESepPutFunc(name) \ 1616 static void name(\ 1617 TIFFRGBAImage* img,\ 1618 uint32* cp,\ 1619 uint32 x, uint32 y, \ 1620 uint32 w, uint32 h,\ 1621 int32 fromskew, int32 toskew,\ 1622 unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\ 1623 ) 1624 1625 /* 1626 * 8-bit unpacked samples => RGB 1627 */ 1628 DECLARESepPutFunc(putRGBseparate8bittile) 1629 { 1630 (void) img; (void) x; (void) y; (void) a; 1631 for( ; h > 0; --h) { 1632 UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++)); 1633 SKEW(r, g, b, fromskew); 1634 cp += toskew; 1635 } 1636 } 1637 1638 /* 1639 * 8-bit unpacked samples => RGBA w/ associated alpha 1640 */ 1641 DECLARESepPutFunc(putRGBAAseparate8bittile) 1642 { 1643 (void) img; (void) x; (void) y; 1644 for( ; h > 0; --h) { 1645 UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++)); 1646 SKEW4(r, g, b, a, fromskew); 1647 cp += toskew; 1648 } 1649 } 1650 1651 /* 1652 * 8-bit unpacked CMYK samples => RGBA 1653 */ 1654 DECLARESepPutFunc(putCMYKseparate8bittile) 1655 { 1656 (void) img; (void) y; 1657 for( ; h > 0; --h) { 1658 uint32 rv, gv, bv, kv; 1659 for (x = w; x > 0; --x) { 1660 kv = 255 - *a++; 1661 rv = (kv*(255-*r++))/255; 1662 gv = (kv*(255-*g++))/255; 1663 bv = (kv*(255-*b++))/255; 1664 *cp++ = PACK4(rv,gv,bv,255); 1665 } 1666 SKEW4(r, g, b, a, fromskew); 1667 cp += toskew; 1668 } 1669 } 1670 1671 /* 1672 * 8-bit unpacked samples => RGBA w/ unassociated alpha 1673 */ 1674 DECLARESepPutFunc(putRGBUAseparate8bittile) 1675 { 1676 (void) img; (void) y; 1677 for( ; h > 0; --h) { 1678 uint32 rv, gv, bv, av; 1679 uint8* m; 1680 for (x = w; x > 0; --x) { 1681 av = *a++; 1682 m = img->UaToAa+((size_t) av<<8); 1683 rv = m[*r++]; 1684 gv = m[*g++]; 1685 bv = m[*b++]; 1686 *cp++ = PACK4(rv,gv,bv,av); 1687 } 1688 SKEW4(r, g, b, a, fromskew); 1689 cp += toskew; 1690 } 1691 } 1692 1693 /* 1694 * 16-bit unpacked samples => RGB 1695 */ 1696 DECLARESepPutFunc(putRGBseparate16bittile) 1697 { 1698 uint16 *wr = (uint16*) r; 1699 uint16 *wg = (uint16*) g; 1700 uint16 *wb = (uint16*) b; 1701 (void) img; (void) y; (void) a; 1702 for( ; h > 0; --h) { 1703 for (x = 0; x < w; x++) 1704 *cp++ = PACK(img->Bitdepth16To8[*wr++], 1705 img->Bitdepth16To8[*wg++], 1706 img->Bitdepth16To8[*wb++]); 1707 SKEW(wr, wg, wb, fromskew); 1708 cp += toskew; 1709 } 1710 } 1711 1712 /* 1713 * 16-bit unpacked samples => RGBA w/ associated alpha 1714 */ 1715 DECLARESepPutFunc(putRGBAAseparate16bittile) 1716 { 1717 uint16 *wr = (uint16*) r; 1718 uint16 *wg = (uint16*) g; 1719 uint16 *wb = (uint16*) b; 1720 uint16 *wa = (uint16*) a; 1721 (void) img; (void) y; 1722 for( ; h > 0; --h) { 1723 for (x = 0; x < w; x++) 1724 *cp++ = PACK4(img->Bitdepth16To8[*wr++], 1725 img->Bitdepth16To8[*wg++], 1726 img->Bitdepth16To8[*wb++], 1727 img->Bitdepth16To8[*wa++]); 1728 SKEW4(wr, wg, wb, wa, fromskew); 1729 cp += toskew; 1730 } 1731 } 1732 1733 /* 1734 * 16-bit unpacked samples => RGBA w/ unassociated alpha 1735 */ 1736 DECLARESepPutFunc(putRGBUAseparate16bittile) 1737 { 1738 uint16 *wr = (uint16*) r; 1739 uint16 *wg = (uint16*) g; 1740 uint16 *wb = (uint16*) b; 1741 uint16 *wa = (uint16*) a; 1742 (void) img; (void) y; 1743 for( ; h > 0; --h) { 1744 uint32 r2,g2,b2,a2; 1745 uint8* m; 1746 for (x = w; x > 0; --x) { 1747 a2 = img->Bitdepth16To8[*wa++]; 1748 m = img->UaToAa+((size_t) a2<<8); 1749 r2 = m[img->Bitdepth16To8[*wr++]]; 1750 g2 = m[img->Bitdepth16To8[*wg++]]; 1751 b2 = m[img->Bitdepth16To8[*wb++]]; 1752 *cp++ = PACK4(r2,g2,b2,a2); 1753 } 1754 SKEW4(wr, wg, wb, wa, fromskew); 1755 cp += toskew; 1756 } 1757 } 1758 1759 /* 1760 * 8-bit packed CIE L*a*b 1976 samples => RGB 1761 */ 1762 DECLAREContigPutFunc(putcontig8bitCIELab) 1763 { 1764 float X, Y, Z; 1765 uint32 r, g, b; 1766 (void) y; 1767 fromskew *= 3; 1768 for( ; h > 0; --h) { 1769 for (x = w; x > 0; --x) { 1770 TIFFCIELabToXYZ(img->cielab, 1771 (unsigned char)pp[0], 1772 (signed char)pp[1], 1773 (signed char)pp[2], 1774 &X, &Y, &Z); 1775 TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b); 1776 *cp++ = PACK(r, g, b); 1777 pp += 3; 1778 } 1779 cp += toskew; 1780 pp += fromskew; 1781 } 1782 } 1783 1784 /* 1785 * YCbCr -> RGB conversion and packing routines. 1786 */ 1787 1788 #define YCbCrtoRGB(dst, Y) { \ 1789 uint32 r, g, b; \ 1790 TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \ 1791 dst = PACK(r, g, b); \ 1792 } 1793 1794 /* 1795 * 8-bit packed YCbCr samples => RGB 1796 * This function is generic for different sampling sizes, 1797 * and can handle blocks sizes that aren't multiples of the 1798 * sampling size. However, it is substantially less optimized 1799 * than the specific sampling cases. It is used as a fallback 1800 * for difficult blocks. 1801 */ 1802 #ifdef notdef 1803 static void putcontig8bitYCbCrGenericTile( 1804 TIFFRGBAImage* img, 1805 uint32* cp, 1806 uint32 x, uint32 y, 1807 uint32 w, uint32 h, 1808 int32 fromskew, int32 toskew, 1809 unsigned char* pp, 1810 int h_group, 1811 int v_group ) 1812 1813 { 1814 uint32* cp1 = cp+w+toskew; 1815 uint32* cp2 = cp1+w+toskew; 1816 uint32* cp3 = cp2+w+toskew; 1817 int32 incr = 3*w+4*toskew; 1818 int32 Cb, Cr; 1819 int group_size = v_group * h_group + 2; 1820 1821 (void) y; 1822 fromskew = (fromskew * group_size) / h_group; 1823 1824 for( yy = 0; yy < h; yy++ ) 1825 { 1826 unsigned char *pp_line; 1827 int y_line_group = yy / v_group; 1828 int y_remainder = yy - y_line_group * v_group; 1829 1830 pp_line = pp + v_line_group * 1831 1832 1833 for( xx = 0; xx < w; xx++ ) 1834 { 1835 Cb = pp 1836 } 1837 } 1838 for (; h >= 4; h -= 4) { 1839 x = w>>2; 1840 do { 1841 Cb = pp[16]; 1842 Cr = pp[17]; 1843 1844 YCbCrtoRGB(cp [0], pp[ 0]); 1845 YCbCrtoRGB(cp [1], pp[ 1]); 1846 YCbCrtoRGB(cp [2], pp[ 2]); 1847 YCbCrtoRGB(cp [3], pp[ 3]); 1848 YCbCrtoRGB(cp1[0], pp[ 4]); 1849 YCbCrtoRGB(cp1[1], pp[ 5]); 1850 YCbCrtoRGB(cp1[2], pp[ 6]); 1851 YCbCrtoRGB(cp1[3], pp[ 7]); 1852 YCbCrtoRGB(cp2[0], pp[ 8]); 1853 YCbCrtoRGB(cp2[1], pp[ 9]); 1854 YCbCrtoRGB(cp2[2], pp[10]); 1855 YCbCrtoRGB(cp2[3], pp[11]); 1856 YCbCrtoRGB(cp3[0], pp[12]); 1857 YCbCrtoRGB(cp3[1], pp[13]); 1858 YCbCrtoRGB(cp3[2], pp[14]); 1859 YCbCrtoRGB(cp3[3], pp[15]); 1860 1861 cp += 4, cp1 += 4, cp2 += 4, cp3 += 4; 1862 pp += 18; 1863 } while (--x); 1864 cp += incr, cp1 += incr, cp2 += incr, cp3 += incr; 1865 pp += fromskew; 1866 } 1867 } 1868 #endif 1869 1870 /* 1871 * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB 1872 */ 1873 DECLAREContigPutFunc(putcontig8bitYCbCr44tile) 1874 { 1875 uint32* cp1 = cp+w+toskew; 1876 uint32* cp2 = cp1+w+toskew; 1877 uint32* cp3 = cp2+w+toskew; 1878 int32 incr = 3*w+4*toskew; 1879 1880 (void) y; 1881 /* adjust fromskew */ 1882 fromskew = (fromskew / 4) * (4*2+2); 1883 if ((h & 3) == 0 && (w & 3) == 0) { 1884 for (; h >= 4; h -= 4) { 1885 x = w>>2; 1886 do { 1887 int32 Cb = pp[16]; 1888 int32 Cr = pp[17]; 1889 1890 YCbCrtoRGB(cp [0], pp[ 0]); 1891 YCbCrtoRGB(cp [1], pp[ 1]); 1892 YCbCrtoRGB(cp [2], pp[ 2]); 1893 YCbCrtoRGB(cp [3], pp[ 3]); 1894 YCbCrtoRGB(cp1[0], pp[ 4]); 1895 YCbCrtoRGB(cp1[1], pp[ 5]); 1896 YCbCrtoRGB(cp1[2], pp[ 6]); 1897 YCbCrtoRGB(cp1[3], pp[ 7]); 1898 YCbCrtoRGB(cp2[0], pp[ 8]); 1899 YCbCrtoRGB(cp2[1], pp[ 9]); 1900 YCbCrtoRGB(cp2[2], pp[10]); 1901 YCbCrtoRGB(cp2[3], pp[11]); 1902 YCbCrtoRGB(cp3[0], pp[12]); 1903 YCbCrtoRGB(cp3[1], pp[13]); 1904 YCbCrtoRGB(cp3[2], pp[14]); 1905 YCbCrtoRGB(cp3[3], pp[15]); 1906 1907 cp += 4; 1908 cp1 += 4; 1909 cp2 += 4; 1910 cp3 += 4; 1911 pp += 18; 1912 } while (--x); 1913 cp += incr; 1914 cp1 += incr; 1915 cp2 += incr; 1916 cp3 += incr; 1917 pp += fromskew; 1918 } 1919 } else { 1920 while (h > 0) { 1921 for (x = w; x > 0;) { 1922 int32 Cb = pp[16]; 1923 int32 Cr = pp[17]; 1924 switch (x) { 1925 default: 1926 switch (h) { 1927 default: YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */ 1928 case 3: YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */ 1929 case 2: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */ 1930 case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */ 1931 } /* FALLTHROUGH */ 1932 case 3: 1933 switch (h) { 1934 default: YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */ 1935 case 3: YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */ 1936 case 2: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */ 1937 case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */ 1938 } /* FALLTHROUGH */ 1939 case 2: 1940 switch (h) { 1941 default: YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */ 1942 case 3: YCbCrtoRGB(cp2[1], pp[ 9]); /* FALLTHROUGH */ 1943 case 2: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */ 1944 case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */ 1945 } /* FALLTHROUGH */ 1946 case 1: 1947 switch (h) { 1948 default: YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */ 1949 case 3: YCbCrtoRGB(cp2[0], pp[ 8]); /* FALLTHROUGH */ 1950 case 2: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */ 1951 case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */ 1952 } /* FALLTHROUGH */ 1953 } 1954 if (x < 4) { 1955 cp += x; cp1 += x; cp2 += x; cp3 += x; 1956 x = 0; 1957 } 1958 else { 1959 cp += 4; cp1 += 4; cp2 += 4; cp3 += 4; 1960 x -= 4; 1961 } 1962 pp += 18; 1963 } 1964 if (h <= 4) 1965 break; 1966 h -= 4; 1967 cp += incr; 1968 cp1 += incr; 1969 cp2 += incr; 1970 cp3 += incr; 1971 pp += fromskew; 1972 } 1973 } 1974 } 1975 1976 /* 1977 * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB 1978 */ 1979 DECLAREContigPutFunc(putcontig8bitYCbCr42tile) 1980 { 1981 uint32* cp1 = cp+w+toskew; 1982 int32 incr = 2*toskew+w; 1983 1984 (void) y; 1985 fromskew = (fromskew / 4) * (4*2+2); 1986 if ((w & 3) == 0 && (h & 1) == 0) { 1987 for (; h >= 2; h -= 2) { 1988 x = w>>2; 1989 do { 1990 int32 Cb = pp[8]; 1991 int32 Cr = pp[9]; 1992 1993 YCbCrtoRGB(cp [0], pp[0]); 1994 YCbCrtoRGB(cp [1], pp[1]); 1995 YCbCrtoRGB(cp [2], pp[2]); 1996 YCbCrtoRGB(cp [3], pp[3]); 1997 YCbCrtoRGB(cp1[0], pp[4]); 1998 YCbCrtoRGB(cp1[1], pp[5]); 1999 YCbCrtoRGB(cp1[2], pp[6]); 2000 YCbCrtoRGB(cp1[3], pp[7]); 2001 2002 cp += 4; 2003 cp1 += 4; 2004 pp += 10; 2005 } while (--x); 2006 cp += incr; 2007 cp1 += incr; 2008 pp += fromskew; 2009 } 2010 } else { 2011 while (h > 0) { 2012 for (x = w; x > 0;) { 2013 int32 Cb = pp[8]; 2014 int32 Cr = pp[9]; 2015 switch (x) { 2016 default: 2017 switch (h) { 2018 default: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */ 2019 case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */ 2020 } /* FALLTHROUGH */ 2021 case 3: 2022 switch (h) { 2023 default: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */ 2024 case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */ 2025 } /* FALLTHROUGH */ 2026 case 2: 2027 switch (h) { 2028 default: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */ 2029 case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */ 2030 } /* FALLTHROUGH */ 2031 case 1: 2032 switch (h) { 2033 default: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */ 2034 case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */ 2035 } /* FALLTHROUGH */ 2036 } 2037 if (x < 4) { 2038 cp += x; cp1 += x; 2039 x = 0; 2040 } 2041 else { 2042 cp += 4; cp1 += 4; 2043 x -= 4; 2044 } 2045 pp += 10; 2046 } 2047 if (h <= 2) 2048 break; 2049 h -= 2; 2050 cp += incr; 2051 cp1 += incr; 2052 pp += fromskew; 2053 } 2054 } 2055 } 2056 2057 /* 2058 * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB 2059 */ 2060 DECLAREContigPutFunc(putcontig8bitYCbCr41tile) 2061 { 2062 (void) y; 2063 fromskew = (fromskew / 4) * (4*1+2); 2064 do { 2065 x = w>>2; 2066 while(x>0) { 2067 int32 Cb = pp[4]; 2068 int32 Cr = pp[5]; 2069 2070 YCbCrtoRGB(cp [0], pp[0]); 2071 YCbCrtoRGB(cp [1], pp[1]); 2072 YCbCrtoRGB(cp [2], pp[2]); 2073 YCbCrtoRGB(cp [3], pp[3]); 2074 2075 cp += 4; 2076 pp += 6; 2077 x--; 2078 } 2079 2080 if( (w&3) != 0 ) 2081 { 2082 int32 Cb = pp[4]; 2083 int32 Cr = pp[5]; 2084 2085 switch( (w&3) ) { 2086 case 3: YCbCrtoRGB(cp [2], pp[2]); /*-fallthrough*/ 2087 case 2: YCbCrtoRGB(cp [1], pp[1]); /*-fallthrough*/ 2088 case 1: YCbCrtoRGB(cp [0], pp[0]); /*-fallthrough*/ 2089 case 0: break; 2090 } 2091 2092 cp += (w&3); 2093 pp += 6; 2094 } 2095 2096 cp += toskew; 2097 pp += fromskew; 2098 } while (--h); 2099 2100 } 2101 2102 /* 2103 * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB 2104 */ 2105 DECLAREContigPutFunc(putcontig8bitYCbCr22tile) 2106 { 2107 uint32* cp2; 2108 int32 incr = 2*toskew+w; 2109 (void) y; 2110 fromskew = (fromskew / 2) * (2*2+2); 2111 cp2 = cp+w+toskew; 2112 while (h>=2) { 2113 x = w; 2114 while (x>=2) { 2115 uint32 Cb = pp[4]; 2116 uint32 Cr = pp[5]; 2117 YCbCrtoRGB(cp[0], pp[0]); 2118 YCbCrtoRGB(cp[1], pp[1]); 2119 YCbCrtoRGB(cp2[0], pp[2]); 2120 YCbCrtoRGB(cp2[1], pp[3]); 2121 cp += 2; 2122 cp2 += 2; 2123 pp += 6; 2124 x -= 2; 2125 } 2126 if (x==1) { 2127 uint32 Cb = pp[4]; 2128 uint32 Cr = pp[5]; 2129 YCbCrtoRGB(cp[0], pp[0]); 2130 YCbCrtoRGB(cp2[0], pp[2]); 2131 cp ++ ; 2132 cp2 ++ ; 2133 pp += 6; 2134 } 2135 cp += incr; 2136 cp2 += incr; 2137 pp += fromskew; 2138 h-=2; 2139 } 2140 if (h==1) { 2141 x = w; 2142 while (x>=2) { 2143 uint32 Cb = pp[4]; 2144 uint32 Cr = pp[5]; 2145 YCbCrtoRGB(cp[0], pp[0]); 2146 YCbCrtoRGB(cp[1], pp[1]); 2147 cp += 2; 2148 cp2 += 2; 2149 pp += 6; 2150 x -= 2; 2151 } 2152 if (x==1) { 2153 uint32 Cb = pp[4]; 2154 uint32 Cr = pp[5]; 2155 YCbCrtoRGB(cp[0], pp[0]); 2156 } 2157 } 2158 } 2159 2160 /* 2161 * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB 2162 */ 2163 DECLAREContigPutFunc(putcontig8bitYCbCr21tile) 2164 { 2165 (void) y; 2166 fromskew = (fromskew / 2) * (2*1+2); 2167 do { 2168 x = w>>1; 2169 while(x>0) { 2170 int32 Cb = pp[2]; 2171 int32 Cr = pp[3]; 2172 2173 YCbCrtoRGB(cp[0], pp[0]); 2174 YCbCrtoRGB(cp[1], pp[1]); 2175 2176 cp += 2; 2177 pp += 4; 2178 x --; 2179 } 2180 2181 if( (w&1) != 0 ) 2182 { 2183 int32 Cb = pp[2]; 2184 int32 Cr = pp[3]; 2185 2186 YCbCrtoRGB(cp[0], pp[0]); 2187 2188 cp += 1; 2189 pp += 4; 2190 } 2191 2192 cp += toskew; 2193 pp += fromskew; 2194 } while (--h); 2195 } 2196 2197 /* 2198 * 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB 2199 */ 2200 DECLAREContigPutFunc(putcontig8bitYCbCr12tile) 2201 { 2202 uint32* cp2; 2203 int32 incr = 2*toskew+w; 2204 (void) y; 2205 fromskew = (fromskew / 1) * (1 * 2 + 2); 2206 cp2 = cp+w+toskew; 2207 while (h>=2) { 2208 x = w; 2209 do { 2210 uint32 Cb = pp[2]; 2211 uint32 Cr = pp[3]; 2212 YCbCrtoRGB(cp[0], pp[0]); 2213 YCbCrtoRGB(cp2[0], pp[1]); 2214 cp ++; 2215 cp2 ++; 2216 pp += 4; 2217 } while (--x); 2218 cp += incr; 2219 cp2 += incr; 2220 pp += fromskew; 2221 h-=2; 2222 } 2223 if (h==1) { 2224 x = w; 2225 do { 2226 uint32 Cb = pp[2]; 2227 uint32 Cr = pp[3]; 2228 YCbCrtoRGB(cp[0], pp[0]); 2229 cp ++; 2230 pp += 4; 2231 } while (--x); 2232 } 2233 } 2234 2235 /* 2236 * 8-bit packed YCbCr samples w/ no subsampling => RGB 2237 */ 2238 DECLAREContigPutFunc(putcontig8bitYCbCr11tile) 2239 { 2240 (void) y; 2241 fromskew = (fromskew / 1) * (1 * 1 + 2); 2242 do { 2243 x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */ 2244 do { 2245 int32 Cb = pp[1]; 2246 int32 Cr = pp[2]; 2247 2248 YCbCrtoRGB(*cp++, pp[0]); 2249 2250 pp += 3; 2251 } while (--x); 2252 cp += toskew; 2253 pp += fromskew; 2254 } while (--h); 2255 } 2256 2257 /* 2258 * 8-bit packed YCbCr samples w/ no subsampling => RGB 2259 */ 2260 DECLARESepPutFunc(putseparate8bitYCbCr11tile) 2261 { 2262 (void) y; 2263 (void) a; 2264 /* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */ 2265 for( ; h > 0; --h) { 2266 x = w; 2267 do { 2268 uint32 dr, dg, db; 2269 TIFFYCbCrtoRGB(img->ycbcr,*r++,*g++,*b++,&dr,&dg,&db); 2270 *cp++ = PACK(dr,dg,db); 2271 } while (--x); 2272 SKEW(r, g, b, fromskew); 2273 cp += toskew; 2274 } 2275 } 2276 #undef YCbCrtoRGB 2277 2278 static int isInRefBlackWhiteRange(float f) 2279 { 2280 return f > (float)(-0x7FFFFFFF + 128) && f < (float)0x7FFFFFFF; 2281 } 2282 2283 static int 2284 initYCbCrConversion(TIFFRGBAImage* img) 2285 { 2286 static const char module[] = "initYCbCrConversion"; 2287 2288 float *luma, *refBlackWhite; 2289 2290 if (img->ycbcr == NULL) { 2291 img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc( 2292 TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long)) 2293 + 4*256*sizeof (TIFFRGBValue) 2294 + 2*256*sizeof (int) 2295 + 3*256*sizeof (int32) 2296 ); 2297 if (img->ycbcr == NULL) { 2298 TIFFErrorExt(img->tif->tif_clientdata, module, 2299 "No space for YCbCr->RGB conversion state"); 2300 return (0); 2301 } 2302 } 2303 2304 TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma); 2305 TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE, 2306 &refBlackWhite); 2307 2308 /* Do some validation to avoid later issues. Detect NaN for now */ 2309 /* and also if lumaGreen is zero since we divide by it later */ 2310 if( luma[0] != luma[0] || 2311 luma[1] != luma[1] || 2312 luma[1] == 0.0 || 2313 luma[2] != luma[2] ) 2314 { 2315 TIFFErrorExt(img->tif->tif_clientdata, module, 2316 "Invalid values for YCbCrCoefficients tag"); 2317 return (0); 2318 } 2319 2320 if( !isInRefBlackWhiteRange(refBlackWhite[0]) || 2321 !isInRefBlackWhiteRange(refBlackWhite[1]) || 2322 !isInRefBlackWhiteRange(refBlackWhite[2]) || 2323 !isInRefBlackWhiteRange(refBlackWhite[3]) || 2324 !isInRefBlackWhiteRange(refBlackWhite[4]) || 2325 !isInRefBlackWhiteRange(refBlackWhite[5]) ) 2326 { 2327 TIFFErrorExt(img->tif->tif_clientdata, module, 2328 "Invalid values for ReferenceBlackWhite tag"); 2329 return (0); 2330 } 2331 2332 if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0) 2333 return(0); 2334 return (1); 2335 } 2336 2337 static tileContigRoutine 2338 initCIELabConversion(TIFFRGBAImage* img) 2339 { 2340 static const char module[] = "initCIELabConversion"; 2341 2342 float *whitePoint; 2343 float refWhite[3]; 2344 2345 TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint); 2346 if (whitePoint[1] == 0.0f ) { 2347 TIFFErrorExt(img->tif->tif_clientdata, module, 2348 "Invalid value for WhitePoint tag."); 2349 return NULL; 2350 } 2351 2352 if (!img->cielab) { 2353 img->cielab = (TIFFCIELabToRGB *) 2354 _TIFFmalloc(sizeof(TIFFCIELabToRGB)); 2355 if (!img->cielab) { 2356 TIFFErrorExt(img->tif->tif_clientdata, module, 2357 "No space for CIE L*a*b*->RGB conversion state."); 2358 return NULL; 2359 } 2360 } 2361 2362 refWhite[1] = 100.0F; 2363 refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1]; 2364 refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1]) 2365 / whitePoint[1] * refWhite[1]; 2366 if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) { 2367 TIFFErrorExt(img->tif->tif_clientdata, module, 2368 "Failed to initialize CIE L*a*b*->RGB conversion state."); 2369 _TIFFfree(img->cielab); 2370 return NULL; 2371 } 2372 2373 return putcontig8bitCIELab; 2374 } 2375 2376 /* 2377 * Greyscale images with less than 8 bits/sample are handled 2378 * with a table to avoid lots of shifts and masks. The table 2379 * is setup so that put*bwtile (below) can retrieve 8/bitspersample 2380 * pixel values simply by indexing into the table with one 2381 * number. 2382 */ 2383 static int 2384 makebwmap(TIFFRGBAImage* img) 2385 { 2386 TIFFRGBValue* Map = img->Map; 2387 int bitspersample = img->bitspersample; 2388 int nsamples = 8 / bitspersample; 2389 int i; 2390 uint32* p; 2391 2392 if( nsamples == 0 ) 2393 nsamples = 1; 2394 2395 img->BWmap = (uint32**) _TIFFmalloc( 2396 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32))); 2397 if (img->BWmap == NULL) { 2398 TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for B&W mapping table"); 2399 return (0); 2400 } 2401 p = (uint32*)(img->BWmap + 256); 2402 for (i = 0; i < 256; i++) { 2403 TIFFRGBValue c; 2404 img->BWmap[i] = p; 2405 switch (bitspersample) { 2406 #define GREY(x) c = Map[x]; *p++ = PACK(c,c,c); 2407 case 1: 2408 GREY(i>>7); 2409 GREY((i>>6)&1); 2410 GREY((i>>5)&1); 2411 GREY((i>>4)&1); 2412 GREY((i>>3)&1); 2413 GREY((i>>2)&1); 2414 GREY((i>>1)&1); 2415 GREY(i&1); 2416 break; 2417 case 2: 2418 GREY(i>>6); 2419 GREY((i>>4)&3); 2420 GREY((i>>2)&3); 2421 GREY(i&3); 2422 break; 2423 case 4: 2424 GREY(i>>4); 2425 GREY(i&0xf); 2426 break; 2427 case 8: 2428 case 16: 2429 GREY(i); 2430 break; 2431 } 2432 #undef GREY 2433 } 2434 return (1); 2435 } 2436 2437 /* 2438 * Construct a mapping table to convert from the range 2439 * of the data samples to [0,255] --for display. This 2440 * process also handles inverting B&W images when needed. 2441 */ 2442 static int 2443 setupMap(TIFFRGBAImage* img) 2444 { 2445 int32 x, range; 2446 2447 range = (int32)((1L<<img->bitspersample)-1); 2448 2449 /* treat 16 bit the same as eight bit */ 2450 if( img->bitspersample == 16 ) 2451 range = (int32) 255; 2452 2453 img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue)); 2454 if (img->Map == NULL) { 2455 TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), 2456 "No space for photometric conversion table"); 2457 return (0); 2458 } 2459 if (img->photometric == PHOTOMETRIC_MINISWHITE) { 2460 for (x = 0; x <= range; x++) 2461 img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range); 2462 } else { 2463 for (x = 0; x <= range; x++) 2464 img->Map[x] = (TIFFRGBValue) ((x * 255) / range); 2465 } 2466 if (img->bitspersample <= 16 && 2467 (img->photometric == PHOTOMETRIC_MINISBLACK || 2468 img->photometric == PHOTOMETRIC_MINISWHITE)) { 2469 /* 2470 * Use photometric mapping table to construct 2471 * unpacking tables for samples <= 8 bits. 2472 */ 2473 if (!makebwmap(img)) 2474 return (0); 2475 /* no longer need Map, free it */ 2476 _TIFFfree(img->Map); 2477 img->Map = NULL; 2478 } 2479 return (1); 2480 } 2481 2482 static int 2483 checkcmap(TIFFRGBAImage* img) 2484 { 2485 uint16* r = img->redcmap; 2486 uint16* g = img->greencmap; 2487 uint16* b = img->bluecmap; 2488 long n = 1L<<img->bitspersample; 2489 2490 while (n-- > 0) 2491 if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) 2492 return (16); 2493 return (8); 2494 } 2495 2496 static void 2497 cvtcmap(TIFFRGBAImage* img) 2498 { 2499 uint16* r = img->redcmap; 2500 uint16* g = img->greencmap; 2501 uint16* b = img->bluecmap; 2502 long i; 2503 2504 for (i = (1L<<img->bitspersample)-1; i >= 0; i--) { 2505 #define CVT(x) ((uint16)((x)>>8)) 2506 r[i] = CVT(r[i]); 2507 g[i] = CVT(g[i]); 2508 b[i] = CVT(b[i]); 2509 #undef CVT 2510 } 2511 } 2512 2513 /* 2514 * Palette images with <= 8 bits/sample are handled 2515 * with a table to avoid lots of shifts and masks. The table 2516 * is setup so that put*cmaptile (below) can retrieve 8/bitspersample 2517 * pixel values simply by indexing into the table with one 2518 * number. 2519 */ 2520 static int 2521 makecmap(TIFFRGBAImage* img) 2522 { 2523 int bitspersample = img->bitspersample; 2524 int nsamples = 8 / bitspersample; 2525 uint16* r = img->redcmap; 2526 uint16* g = img->greencmap; 2527 uint16* b = img->bluecmap; 2528 uint32 *p; 2529 int i; 2530 2531 img->PALmap = (uint32**) _TIFFmalloc( 2532 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32))); 2533 if (img->PALmap == NULL) { 2534 TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for Palette mapping table"); 2535 return (0); 2536 } 2537 p = (uint32*)(img->PALmap + 256); 2538 for (i = 0; i < 256; i++) { 2539 TIFFRGBValue c; 2540 img->PALmap[i] = p; 2541 #define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff); 2542 switch (bitspersample) { 2543 case 1: 2544 CMAP(i>>7); 2545 CMAP((i>>6)&1); 2546 CMAP((i>>5)&1); 2547 CMAP((i>>4)&1); 2548 CMAP((i>>3)&1); 2549 CMAP((i>>2)&1); 2550 CMAP((i>>1)&1); 2551 CMAP(i&1); 2552 break; 2553 case 2: 2554 CMAP(i>>6); 2555 CMAP((i>>4)&3); 2556 CMAP((i>>2)&3); 2557 CMAP(i&3); 2558 break; 2559 case 4: 2560 CMAP(i>>4); 2561 CMAP(i&0xf); 2562 break; 2563 case 8: 2564 CMAP(i); 2565 break; 2566 } 2567 #undef CMAP 2568 } 2569 return (1); 2570 } 2571 2572 /* 2573 * Construct any mapping table used 2574 * by the associated put routine. 2575 */ 2576 static int 2577 buildMap(TIFFRGBAImage* img) 2578 { 2579 switch (img->photometric) { 2580 case PHOTOMETRIC_RGB: 2581 case PHOTOMETRIC_YCBCR: 2582 case PHOTOMETRIC_SEPARATED: 2583 if (img->bitspersample == 8) 2584 break; 2585 /* fall through... */ 2586 case PHOTOMETRIC_MINISBLACK: 2587 case PHOTOMETRIC_MINISWHITE: 2588 if (!setupMap(img)) 2589 return (0); 2590 break; 2591 case PHOTOMETRIC_PALETTE: 2592 /* 2593 * Convert 16-bit colormap to 8-bit (unless it looks 2594 * like an old-style 8-bit colormap). 2595 */ 2596 if (checkcmap(img) == 16) 2597 cvtcmap(img); 2598 else 2599 TIFFWarningExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "Assuming 8-bit colormap"); 2600 /* 2601 * Use mapping table and colormap to construct 2602 * unpacking tables for samples < 8 bits. 2603 */ 2604 if (img->bitspersample <= 8 && !makecmap(img)) 2605 return (0); 2606 break; 2607 } 2608 return (1); 2609 } 2610 2611 /* 2612 * Select the appropriate conversion routine for packed data. 2613 */ 2614 static int 2615 PickContigCase(TIFFRGBAImage* img) 2616 { 2617 img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig; 2618 img->put.contig = NULL; 2619 switch (img->photometric) { 2620 case PHOTOMETRIC_RGB: 2621 switch (img->bitspersample) { 2622 case 8: 2623 if (img->alpha == EXTRASAMPLE_ASSOCALPHA && 2624 img->samplesperpixel >= 4) 2625 img->put.contig = putRGBAAcontig8bittile; 2626 else if (img->alpha == EXTRASAMPLE_UNASSALPHA && 2627 img->samplesperpixel >= 4) 2628 { 2629 if (BuildMapUaToAa(img)) 2630 img->put.contig = putRGBUAcontig8bittile; 2631 } 2632 else if( img->samplesperpixel >= 3 ) 2633 img->put.contig = putRGBcontig8bittile; 2634 break; 2635 case 16: 2636 if (img->alpha == EXTRASAMPLE_ASSOCALPHA && 2637 img->samplesperpixel >=4 ) 2638 { 2639 if (BuildMapBitdepth16To8(img)) 2640 img->put.contig = putRGBAAcontig16bittile; 2641 } 2642 else if (img->alpha == EXTRASAMPLE_UNASSALPHA && 2643 img->samplesperpixel >=4 ) 2644 { 2645 if (BuildMapBitdepth16To8(img) && 2646 BuildMapUaToAa(img)) 2647 img->put.contig = putRGBUAcontig16bittile; 2648 } 2649 else if( img->samplesperpixel >=3 ) 2650 { 2651 if (BuildMapBitdepth16To8(img)) 2652 img->put.contig = putRGBcontig16bittile; 2653 } 2654 break; 2655 } 2656 break; 2657 case PHOTOMETRIC_SEPARATED: 2658 if (img->samplesperpixel >=4 && buildMap(img)) { 2659 if (img->bitspersample == 8) { 2660 if (!img->Map) 2661 img->put.contig = putRGBcontig8bitCMYKtile; 2662 else 2663 img->put.contig = putRGBcontig8bitCMYKMaptile; 2664 } 2665 } 2666 break; 2667 case PHOTOMETRIC_PALETTE: 2668 if (buildMap(img)) { 2669 switch (img->bitspersample) { 2670 case 8: 2671 img->put.contig = put8bitcmaptile; 2672 break; 2673 case 4: 2674 img->put.contig = put4bitcmaptile; 2675 break; 2676 case 2: 2677 img->put.contig = put2bitcmaptile; 2678 break; 2679 case 1: 2680 img->put.contig = put1bitcmaptile; 2681 break; 2682 } 2683 } 2684 break; 2685 case PHOTOMETRIC_MINISWHITE: 2686 case PHOTOMETRIC_MINISBLACK: 2687 if (buildMap(img)) { 2688 switch (img->bitspersample) { 2689 case 16: 2690 img->put.contig = put16bitbwtile; 2691 break; 2692 case 8: 2693 if (img->alpha && img->samplesperpixel == 2) 2694 img->put.contig = putagreytile; 2695 else 2696 img->put.contig = putgreytile; 2697 break; 2698 case 4: 2699 img->put.contig = put4bitbwtile; 2700 break; 2701 case 2: 2702 img->put.contig = put2bitbwtile; 2703 break; 2704 case 1: 2705 img->put.contig = put1bitbwtile; 2706 break; 2707 } 2708 } 2709 break; 2710 case PHOTOMETRIC_YCBCR: 2711 if ((img->bitspersample==8) && (img->samplesperpixel==3)) 2712 { 2713 if (initYCbCrConversion(img)!=0) 2714 { 2715 /* 2716 * The 6.0 spec says that subsampling must be 2717 * one of 1, 2, or 4, and that vertical subsampling 2718 * must always be <= horizontal subsampling; so 2719 * there are only a few possibilities and we just 2720 * enumerate the cases. 2721 * Joris: added support for the [1,2] case, nonetheless, to accommodate 2722 * some OJPEG files 2723 */ 2724 uint16 SubsamplingHor; 2725 uint16 SubsamplingVer; 2726 TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &SubsamplingHor, &SubsamplingVer); 2727 switch ((SubsamplingHor<<4)|SubsamplingVer) { 2728 case 0x44: 2729 img->put.contig = putcontig8bitYCbCr44tile; 2730 break; 2731 case 0x42: 2732 img->put.contig = putcontig8bitYCbCr42tile; 2733 break; 2734 case 0x41: 2735 img->put.contig = putcontig8bitYCbCr41tile; 2736 break; 2737 case 0x22: 2738 img->put.contig = putcontig8bitYCbCr22tile; 2739 break; 2740 case 0x21: 2741 img->put.contig = putcontig8bitYCbCr21tile; 2742 break; 2743 case 0x12: 2744 img->put.contig = putcontig8bitYCbCr12tile; 2745 break; 2746 case 0x11: 2747 img->put.contig = putcontig8bitYCbCr11tile; 2748 break; 2749 } 2750 } 2751 } 2752 break; 2753 case PHOTOMETRIC_CIELAB: 2754 if (img->samplesperpixel == 3 && buildMap(img)) { 2755 if (img->bitspersample == 8) 2756 img->put.contig = initCIELabConversion(img); 2757 break; 2758 } 2759 } 2760 return ((img->get!=NULL) && (img->put.contig!=NULL)); 2761 } 2762 2763 /* 2764 * Select the appropriate conversion routine for unpacked data. 2765 * 2766 * NB: we assume that unpacked single channel data is directed 2767 * to the "packed routines. 2768 */ 2769 static int 2770 PickSeparateCase(TIFFRGBAImage* img) 2771 { 2772 img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate; 2773 img->put.separate = NULL; 2774 switch (img->photometric) { 2775 case PHOTOMETRIC_MINISWHITE: 2776 case PHOTOMETRIC_MINISBLACK: 2777 /* greyscale images processed pretty much as RGB by gtTileSeparate */ 2778 case PHOTOMETRIC_RGB: 2779 switch (img->bitspersample) { 2780 case 8: 2781 if (img->alpha == EXTRASAMPLE_ASSOCALPHA) 2782 img->put.separate = putRGBAAseparate8bittile; 2783 else if (img->alpha == EXTRASAMPLE_UNASSALPHA) 2784 { 2785 if (BuildMapUaToAa(img)) 2786 img->put.separate = putRGBUAseparate8bittile; 2787 } 2788 else 2789 img->put.separate = putRGBseparate8bittile; 2790 break; 2791 case 16: 2792 if (img->alpha == EXTRASAMPLE_ASSOCALPHA) 2793 { 2794 if (BuildMapBitdepth16To8(img)) 2795 img->put.separate = putRGBAAseparate16bittile; 2796 } 2797 else if (img->alpha == EXTRASAMPLE_UNASSALPHA) 2798 { 2799 if (BuildMapBitdepth16To8(img) && 2800 BuildMapUaToAa(img)) 2801 img->put.separate = putRGBUAseparate16bittile; 2802 } 2803 else 2804 { 2805 if (BuildMapBitdepth16To8(img)) 2806 img->put.separate = putRGBseparate16bittile; 2807 } 2808 break; 2809 } 2810 break; 2811 case PHOTOMETRIC_SEPARATED: 2812 if (img->bitspersample == 8 && img->samplesperpixel == 4) 2813 { 2814 img->alpha = 1; // Not alpha, but seems like the only way to get 4th band 2815 img->put.separate = putCMYKseparate8bittile; 2816 } 2817 break; 2818 case PHOTOMETRIC_YCBCR: 2819 if ((img->bitspersample==8) && (img->samplesperpixel==3)) 2820 { 2821 if (initYCbCrConversion(img)!=0) 2822 { 2823 uint16 hs, vs; 2824 TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs); 2825 switch ((hs<<4)|vs) { 2826 case 0x11: 2827 img->put.separate = putseparate8bitYCbCr11tile; 2828 break; 2829 /* TODO: add other cases here */ 2830 } 2831 } 2832 } 2833 break; 2834 } 2835 return ((img->get!=NULL) && (img->put.separate!=NULL)); 2836 } 2837 2838 static int 2839 BuildMapUaToAa(TIFFRGBAImage* img) 2840 { 2841 static const char module[]="BuildMapUaToAa"; 2842 uint8* m; 2843 uint16 na,nv; 2844 assert(img->UaToAa==NULL); 2845 img->UaToAa=_TIFFmalloc(65536); 2846 if (img->UaToAa==NULL) 2847 { 2848 TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory"); 2849 return(0); 2850 } 2851 m=img->UaToAa; 2852 for (na=0; na<256; na++) 2853 { 2854 for (nv=0; nv<256; nv++) 2855 *m++=(uint8)((nv*na+127)/255); 2856 } 2857 return(1); 2858 } 2859 2860 static int 2861 BuildMapBitdepth16To8(TIFFRGBAImage* img) 2862 { 2863 static const char module[]="BuildMapBitdepth16To8"; 2864 uint8* m; 2865 uint32 n; 2866 assert(img->Bitdepth16To8==NULL); 2867 img->Bitdepth16To8=_TIFFmalloc(65536); 2868 if (img->Bitdepth16To8==NULL) 2869 { 2870 TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory"); 2871 return(0); 2872 } 2873 m=img->Bitdepth16To8; 2874 for (n=0; n<65536; n++) 2875 *m++=(uint8)((n+128)/257); 2876 return(1); 2877 } 2878 2879 2880 /* 2881 * Read a whole strip off data from the file, and convert to RGBA form. 2882 * If this is the last strip, then it will only contain the portion of 2883 * the strip that is actually within the image space. The result is 2884 * organized in bottom to top form. 2885 */ 2886 2887 2888 int 2889 TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster ) 2890 2891 { 2892 return TIFFReadRGBAStripExt(tif, row, raster, 0 ); 2893 } 2894 2895 int 2896 TIFFReadRGBAStripExt(TIFF* tif, uint32 row, uint32 * raster, int stop_on_error) 2897 2898 { 2899 char emsg[1024] = ""; 2900 TIFFRGBAImage img; 2901 int ok; 2902 uint32 rowsperstrip, rows_to_read; 2903 2904 if( TIFFIsTiled( tif ) ) 2905 { 2906 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), 2907 "Can't use TIFFReadRGBAStrip() with tiled file."); 2908 return (0); 2909 } 2910 2911 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); 2912 if( (row % rowsperstrip) != 0 ) 2913 { 2914 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), 2915 "Row passed to TIFFReadRGBAStrip() must be first in a strip."); 2916 return (0); 2917 } 2918 2919 if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) { 2920 2921 img.row_offset = row; 2922 img.col_offset = 0; 2923 2924 if( row + rowsperstrip > img.height ) 2925 rows_to_read = img.height - row; 2926 else 2927 rows_to_read = rowsperstrip; 2928 2929 ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read ); 2930 2931 TIFFRGBAImageEnd(&img); 2932 } else { 2933 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg); 2934 ok = 0; 2935 } 2936 2937 return (ok); 2938 } 2939 2940 /* 2941 * Read a whole tile off data from the file, and convert to RGBA form. 2942 * The returned RGBA data is organized from bottom to top of tile, 2943 * and may include zeroed areas if the tile extends off the image. 2944 */ 2945 2946 int 2947 TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster) 2948 2949 { 2950 return TIFFReadRGBATileExt(tif, col, row, raster, 0 ); 2951 } 2952 2953 2954 int 2955 TIFFReadRGBATileExt(TIFF* tif, uint32 col, uint32 row, uint32 * raster, int stop_on_error ) 2956 { 2957 char emsg[1024] = ""; 2958 TIFFRGBAImage img; 2959 int ok; 2960 uint32 tile_xsize, tile_ysize; 2961 uint32 read_xsize, read_ysize; 2962 uint32 i_row; 2963 2964 /* 2965 * Verify that our request is legal - on a tile file, and on a 2966 * tile boundary. 2967 */ 2968 2969 if( !TIFFIsTiled( tif ) ) 2970 { 2971 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), 2972 "Can't use TIFFReadRGBATile() with striped file."); 2973 return (0); 2974 } 2975 2976 TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize); 2977 TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize); 2978 if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 ) 2979 { 2980 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), 2981 "Row/col passed to TIFFReadRGBATile() must be top" 2982 "left corner of a tile."); 2983 return (0); 2984 } 2985 2986 /* 2987 * Setup the RGBA reader. 2988 */ 2989 2990 if (!TIFFRGBAImageOK(tif, emsg) 2991 || !TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) { 2992 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg); 2993 return( 0 ); 2994 } 2995 2996 /* 2997 * The TIFFRGBAImageGet() function doesn't allow us to get off the 2998 * edge of the image, even to fill an otherwise valid tile. So we 2999 * figure out how much we can read, and fix up the tile buffer to 3000 * a full tile configuration afterwards. 3001 */ 3002 3003 if( row + tile_ysize > img.height ) 3004 read_ysize = img.height - row; 3005 else 3006 read_ysize = tile_ysize; 3007 3008 if( col + tile_xsize > img.width ) 3009 read_xsize = img.width - col; 3010 else 3011 read_xsize = tile_xsize; 3012 3013 /* 3014 * Read the chunk of imagery. 3015 */ 3016 3017 img.row_offset = row; 3018 img.col_offset = col; 3019 3020 ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize ); 3021 3022 TIFFRGBAImageEnd(&img); 3023 3024 /* 3025 * If our read was incomplete we will need to fix up the tile by 3026 * shifting the data around as if a full tile of data is being returned. 3027 * 3028 * This is all the more complicated because the image is organized in 3029 * bottom to top format. 3030 */ 3031 3032 if( read_xsize == tile_xsize && read_ysize == tile_ysize ) 3033 return( ok ); 3034 3035 for( i_row = 0; i_row < read_ysize; i_row++ ) { 3036 memmove( raster + (tile_ysize - i_row - 1) * tile_xsize, 3037 raster + (read_ysize - i_row - 1) * read_xsize, 3038 read_xsize * sizeof(uint32) ); 3039 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize, 3040 0, sizeof(uint32) * (tile_xsize - read_xsize) ); 3041 } 3042 3043 for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) { 3044 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize, 3045 0, sizeof(uint32) * tile_xsize ); 3046 } 3047 3048 return (ok); 3049 } 3050 3051 /* vim: set ts=8 sts=8 sw=8 noet: */ 3052 /* 3053 * Local Variables: 3054 * mode: c 3055 * c-basic-offset: 8 3056 * fill-column: 78 3057 * End: 3058 */ 3059