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 = TIFFSafeMultiply(tmsize_t,alpha?4:3,tilesize); 759 if (bufsize == 0) { 760 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtTileSeparate"); 761 return (0); 762 } 763 764 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); 765 TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); 766 767 flip = setorientation(img); 768 if (flip & FLIP_VERTICALLY) { 769 y = h - 1; 770 toskew = -(int32)(tw + w); 771 } 772 else { 773 y = 0; 774 toskew = -(int32)(tw - w); 775 } 776 777 switch( img->photometric ) 778 { 779 case PHOTOMETRIC_MINISWHITE: 780 case PHOTOMETRIC_MINISBLACK: 781 case PHOTOMETRIC_PALETTE: 782 colorchannels = 1; 783 break; 784 785 default: 786 colorchannels = 3; 787 break; 788 } 789 790 /* 791 * Leftmost tile is clipped on left side if col_offset > 0. 792 */ 793 leftmost_fromskew = img->col_offset % tw; 794 leftmost_tw = tw - leftmost_fromskew; 795 leftmost_toskew = toskew + leftmost_fromskew; 796 for (row = 0; ret != 0 && row < h; row += nrow) 797 { 798 rowstoread = th - (row + img->row_offset) % th; 799 nrow = (row + rowstoread > h ? h - row : rowstoread); 800 fromskew = leftmost_fromskew; 801 this_tw = leftmost_tw; 802 this_toskew = leftmost_toskew; 803 tocol = 0; 804 col = img->col_offset; 805 while (tocol < w) 806 { 807 if( buf == NULL ) 808 { 809 if (_TIFFReadTileAndAllocBuffer( 810 tif, (void**) &buf, bufsize, col, 811 row+img->row_offset,0,0)==(tmsize_t)(-1) 812 && (buf == NULL || img->stoponerr)) 813 { 814 ret = 0; 815 break; 816 } 817 p0 = buf; 818 if( colorchannels == 1 ) 819 { 820 p2 = p1 = p0; 821 pa = (alpha?(p0+3*tilesize):NULL); 822 } 823 else 824 { 825 p1 = p0 + tilesize; 826 p2 = p1 + tilesize; 827 pa = (alpha?(p2+tilesize):NULL); 828 } 829 } 830 else if (TIFFReadTile(tif, p0, col, 831 row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr) 832 { 833 ret = 0; 834 break; 835 } 836 if (colorchannels > 1 837 && TIFFReadTile(tif, p1, col, 838 row+img->row_offset,0,1) == (tmsize_t)(-1) 839 && img->stoponerr) 840 { 841 ret = 0; 842 break; 843 } 844 if (colorchannels > 1 845 && TIFFReadTile(tif, p2, col, 846 row+img->row_offset,0,2) == (tmsize_t)(-1) 847 && img->stoponerr) 848 { 849 ret = 0; 850 break; 851 } 852 if (alpha 853 && TIFFReadTile(tif,pa,col, 854 row+img->row_offset,0,colorchannels) == (tmsize_t)(-1) 855 && img->stoponerr) 856 { 857 ret = 0; 858 break; 859 } 860 861 pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif) + \ 862 ((tmsize_t) fromskew * img->samplesperpixel); 863 if (tocol + this_tw > w) 864 { 865 /* 866 * Rightmost tile is clipped on right side. 867 */ 868 fromskew = tw - (w - tocol); 869 this_tw = tw - fromskew; 870 this_toskew = toskew + fromskew; 871 } 872 (*put)(img, raster+y*w+tocol, tocol, y, this_tw, nrow, fromskew, this_toskew, \ 873 p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL)); 874 tocol += this_tw; 875 col += this_tw; 876 /* 877 * After the leftmost tile, tiles are no longer clipped on left side. 878 */ 879 fromskew = 0; 880 this_tw = tw; 881 this_toskew = toskew; 882 } 883 884 y += ((flip & FLIP_VERTICALLY) ?-(int32) nrow : (int32) nrow); 885 } 886 887 if (flip & FLIP_HORIZONTALLY) { 888 uint32 line; 889 890 for (line = 0; line < h; line++) { 891 uint32 *left = raster + (line * w); 892 uint32 *right = left + w - 1; 893 894 while ( left < right ) { 895 uint32 temp = *left; 896 *left = *right; 897 *right = temp; 898 left++; 899 right--; 900 } 901 } 902 } 903 904 _TIFFfree(buf); 905 return (ret); 906 } 907 908 /* 909 * Get a strip-organized image that has 910 * PlanarConfiguration contiguous if SamplesPerPixel > 1 911 * or 912 * SamplesPerPixel == 1 913 */ 914 static int 915 gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) 916 { 917 TIFF* tif = img->tif; 918 tileContigRoutine put = img->put.contig; 919 uint32 row, y, nrow, nrowsub, rowstoread; 920 tmsize_t pos; 921 unsigned char* buf = NULL; 922 uint32 rowsperstrip; 923 uint16 subsamplinghor,subsamplingver; 924 uint32 imagewidth = img->width; 925 tmsize_t scanline; 926 int32 fromskew, toskew; 927 int ret = 1, flip; 928 tmsize_t maxstripsize; 929 930 TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver); 931 if( subsamplingver == 0 ) { 932 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Invalid vertical YCbCr subsampling"); 933 return (0); 934 } 935 936 maxstripsize = TIFFStripSize(tif); 937 938 flip = setorientation(img); 939 if (flip & FLIP_VERTICALLY) { 940 y = h - 1; 941 toskew = -(int32)(w + w); 942 } else { 943 y = 0; 944 toskew = -(int32)(w - w); 945 } 946 947 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); 948 949 scanline = TIFFScanlineSize(tif); 950 fromskew = (w < imagewidth ? imagewidth - w : 0); 951 for (row = 0; row < h; row += nrow) 952 { 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 if (_TIFFReadEncodedStripAndAllocBuffer(tif, 959 TIFFComputeStrip(tif,row+img->row_offset, 0), 960 (void**)(&buf), 961 maxstripsize, 962 ((row + img->row_offset)%rowsperstrip + nrowsub) * scanline)==(tmsize_t)(-1) 963 && (buf == NULL || img->stoponerr)) 964 { 965 ret = 0; 966 break; 967 } 968 969 pos = ((row + img->row_offset) % rowsperstrip) * scanline + \ 970 ((tmsize_t) img->col_offset * img->samplesperpixel); 971 (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos); 972 y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow); 973 } 974 975 if (flip & FLIP_HORIZONTALLY) { 976 uint32 line; 977 978 for (line = 0; line < h; line++) { 979 uint32 *left = raster + (line * w); 980 uint32 *right = left + w - 1; 981 982 while ( left < right ) { 983 uint32 temp = *left; 984 *left = *right; 985 *right = temp; 986 left++; 987 right--; 988 } 989 } 990 } 991 992 _TIFFfree(buf); 993 return (ret); 994 } 995 996 /* 997 * Get a strip-organized image with 998 * SamplesPerPixel > 1 999 * PlanarConfiguration separated 1000 * We assume that all such images are RGB. 1001 */ 1002 static int 1003 gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) 1004 { 1005 TIFF* tif = img->tif; 1006 tileSeparateRoutine put = img->put.separate; 1007 unsigned char *buf = NULL; 1008 unsigned char *p0 = NULL, *p1 = NULL, *p2 = NULL, *pa = NULL; 1009 uint32 row, y, nrow, rowstoread; 1010 tmsize_t pos; 1011 tmsize_t scanline; 1012 uint32 rowsperstrip, offset_row; 1013 uint32 imagewidth = img->width; 1014 tmsize_t stripsize; 1015 tmsize_t bufsize; 1016 int32 fromskew, toskew; 1017 int alpha = img->alpha; 1018 int ret = 1, flip; 1019 uint16 colorchannels; 1020 1021 stripsize = TIFFStripSize(tif); 1022 bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,stripsize); 1023 if (bufsize == 0) { 1024 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtStripSeparate"); 1025 return (0); 1026 } 1027 1028 flip = setorientation(img); 1029 if (flip & FLIP_VERTICALLY) { 1030 y = h - 1; 1031 toskew = -(int32)(w + w); 1032 } 1033 else { 1034 y = 0; 1035 toskew = -(int32)(w - w); 1036 } 1037 1038 switch( img->photometric ) 1039 { 1040 case PHOTOMETRIC_MINISWHITE: 1041 case PHOTOMETRIC_MINISBLACK: 1042 case PHOTOMETRIC_PALETTE: 1043 colorchannels = 1; 1044 break; 1045 1046 default: 1047 colorchannels = 3; 1048 break; 1049 } 1050 1051 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); 1052 scanline = TIFFScanlineSize(tif); 1053 fromskew = (w < imagewidth ? imagewidth - w : 0); 1054 for (row = 0; row < h; row += nrow) 1055 { 1056 rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; 1057 nrow = (row + rowstoread > h ? h - row : rowstoread); 1058 offset_row = row + img->row_offset; 1059 if( buf == NULL ) 1060 { 1061 if (_TIFFReadEncodedStripAndAllocBuffer( 1062 tif, TIFFComputeStrip(tif, offset_row, 0), 1063 (void**) &buf, bufsize, 1064 ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1) 1065 && (buf == NULL || img->stoponerr)) 1066 { 1067 ret = 0; 1068 break; 1069 } 1070 p0 = buf; 1071 if( colorchannels == 1 ) 1072 { 1073 p2 = p1 = p0; 1074 pa = (alpha?(p0+3*stripsize):NULL); 1075 } 1076 else 1077 { 1078 p1 = p0 + stripsize; 1079 p2 = p1 + stripsize; 1080 pa = (alpha?(p2+stripsize):NULL); 1081 } 1082 } 1083 else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0), 1084 p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1) 1085 && img->stoponerr) 1086 { 1087 ret = 0; 1088 break; 1089 } 1090 if (colorchannels > 1 1091 && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1), 1092 p1, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1) 1093 && img->stoponerr) 1094 { 1095 ret = 0; 1096 break; 1097 } 1098 if (colorchannels > 1 1099 && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2), 1100 p2, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1) 1101 && img->stoponerr) 1102 { 1103 ret = 0; 1104 break; 1105 } 1106 if (alpha) 1107 { 1108 if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, colorchannels), 1109 pa, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1) 1110 && img->stoponerr) 1111 { 1112 ret = 0; 1113 break; 1114 } 1115 } 1116 1117 pos = ((row + img->row_offset) % rowsperstrip) * scanline + \ 1118 ((tmsize_t) img->col_offset * img->samplesperpixel); 1119 (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos, 1120 p2 + pos, (alpha?(pa+pos):NULL)); 1121 y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow); 1122 } 1123 1124 if (flip & FLIP_HORIZONTALLY) { 1125 uint32 line; 1126 1127 for (line = 0; line < h; line++) { 1128 uint32 *left = raster + (line * w); 1129 uint32 *right = left + w - 1; 1130 1131 while ( left < right ) { 1132 uint32 temp = *left; 1133 *left = *right; 1134 *right = temp; 1135 left++; 1136 right--; 1137 } 1138 } 1139 } 1140 1141 _TIFFfree(buf); 1142 return (ret); 1143 } 1144 1145 /* 1146 * The following routines move decoded data returned 1147 * from the TIFF library into rasters filled with packed 1148 * ABGR pixels (i.e. suitable for passing to lrecwrite.) 1149 * 1150 * The routines have been created according to the most 1151 * important cases and optimized. PickContigCase and 1152 * PickSeparateCase analyze the parameters and select 1153 * the appropriate "get" and "put" routine to use. 1154 */ 1155 #define REPEAT8(op) REPEAT4(op); REPEAT4(op) 1156 #define REPEAT4(op) REPEAT2(op); REPEAT2(op) 1157 #define REPEAT2(op) op; op 1158 #define CASE8(x,op) \ 1159 switch (x) { \ 1160 case 7: op; /*-fallthrough*/ \ 1161 case 6: op; /*-fallthrough*/ \ 1162 case 5: op; /*-fallthrough*/ \ 1163 case 4: op; /*-fallthrough*/ \ 1164 case 3: op; /*-fallthrough*/ \ 1165 case 2: op; /*-fallthrough*/ \ 1166 case 1: op; \ 1167 } 1168 #define CASE4(x,op) switch (x) { case 3: op; /*-fallthrough*/ case 2: op; /*-fallthrough*/ case 1: op; } 1169 #define NOP 1170 1171 #define UNROLL8(w, op1, op2) { \ 1172 uint32 _x; \ 1173 for (_x = w; _x >= 8; _x -= 8) { \ 1174 op1; \ 1175 REPEAT8(op2); \ 1176 } \ 1177 if (_x > 0) { \ 1178 op1; \ 1179 CASE8(_x,op2); \ 1180 } \ 1181 } 1182 #define UNROLL4(w, op1, op2) { \ 1183 uint32 _x; \ 1184 for (_x = w; _x >= 4; _x -= 4) { \ 1185 op1; \ 1186 REPEAT4(op2); \ 1187 } \ 1188 if (_x > 0) { \ 1189 op1; \ 1190 CASE4(_x,op2); \ 1191 } \ 1192 } 1193 #define UNROLL2(w, op1, op2) { \ 1194 uint32 _x; \ 1195 for (_x = w; _x >= 2; _x -= 2) { \ 1196 op1; \ 1197 REPEAT2(op2); \ 1198 } \ 1199 if (_x) { \ 1200 op1; \ 1201 op2; \ 1202 } \ 1203 } 1204 1205 #define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; } 1206 #define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; } 1207 1208 #define A1 (((uint32)0xffL)<<24) 1209 #define PACK(r,g,b) \ 1210 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1) 1211 #define PACK4(r,g,b,a) \ 1212 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24)) 1213 #define W2B(v) (((v)>>8)&0xff) 1214 /* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */ 1215 #define PACKW(r,g,b) \ 1216 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1) 1217 #define PACKW4(r,g,b,a) \ 1218 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24)) 1219 1220 #define DECLAREContigPutFunc(name) \ 1221 static void name(\ 1222 TIFFRGBAImage* img, \ 1223 uint32* cp, \ 1224 uint32 x, uint32 y, \ 1225 uint32 w, uint32 h, \ 1226 int32 fromskew, int32 toskew, \ 1227 unsigned char* pp \ 1228 ) 1229 1230 /* 1231 * 8-bit palette => colormap/RGB 1232 */ 1233 DECLAREContigPutFunc(put8bitcmaptile) 1234 { 1235 uint32** PALmap = img->PALmap; 1236 int samplesperpixel = img->samplesperpixel; 1237 1238 (void) y; 1239 for( ; h > 0; --h) { 1240 for (x = w; x > 0; --x) 1241 { 1242 *cp++ = PALmap[*pp][0]; 1243 pp += samplesperpixel; 1244 } 1245 cp += toskew; 1246 pp += fromskew; 1247 } 1248 } 1249 1250 /* 1251 * 4-bit palette => colormap/RGB 1252 */ 1253 DECLAREContigPutFunc(put4bitcmaptile) 1254 { 1255 uint32** PALmap = img->PALmap; 1256 1257 (void) x; (void) y; 1258 fromskew /= 2; 1259 for( ; h > 0; --h) { 1260 uint32* bw; 1261 UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++); 1262 cp += toskew; 1263 pp += fromskew; 1264 } 1265 } 1266 1267 /* 1268 * 2-bit palette => colormap/RGB 1269 */ 1270 DECLAREContigPutFunc(put2bitcmaptile) 1271 { 1272 uint32** PALmap = img->PALmap; 1273 1274 (void) x; (void) y; 1275 fromskew /= 4; 1276 for( ; h > 0; --h) { 1277 uint32* bw; 1278 UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++); 1279 cp += toskew; 1280 pp += fromskew; 1281 } 1282 } 1283 1284 /* 1285 * 1-bit palette => colormap/RGB 1286 */ 1287 DECLAREContigPutFunc(put1bitcmaptile) 1288 { 1289 uint32** PALmap = img->PALmap; 1290 1291 (void) x; (void) y; 1292 fromskew /= 8; 1293 for( ; h > 0; --h) { 1294 uint32* bw; 1295 UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++); 1296 cp += toskew; 1297 pp += fromskew; 1298 } 1299 } 1300 1301 /* 1302 * 8-bit greyscale => colormap/RGB 1303 */ 1304 DECLAREContigPutFunc(putgreytile) 1305 { 1306 int samplesperpixel = img->samplesperpixel; 1307 uint32** BWmap = img->BWmap; 1308 1309 (void) y; 1310 for( ; h > 0; --h) { 1311 for (x = w; x > 0; --x) 1312 { 1313 *cp++ = BWmap[*pp][0]; 1314 pp += samplesperpixel; 1315 } 1316 cp += toskew; 1317 pp += fromskew; 1318 } 1319 } 1320 1321 /* 1322 * 8-bit greyscale with associated alpha => colormap/RGBA 1323 */ 1324 DECLAREContigPutFunc(putagreytile) 1325 { 1326 int samplesperpixel = img->samplesperpixel; 1327 uint32** BWmap = img->BWmap; 1328 1329 (void) y; 1330 for( ; h > 0; --h) { 1331 for (x = w; x > 0; --x) 1332 { 1333 *cp++ = BWmap[*pp][0] & ((uint32)*(pp+1) << 24 | ~A1); 1334 pp += samplesperpixel; 1335 } 1336 cp += toskew; 1337 pp += fromskew; 1338 } 1339 } 1340 1341 /* 1342 * 16-bit greyscale => colormap/RGB 1343 */ 1344 DECLAREContigPutFunc(put16bitbwtile) 1345 { 1346 int samplesperpixel = img->samplesperpixel; 1347 uint32** BWmap = img->BWmap; 1348 1349 (void) y; 1350 for( ; h > 0; --h) { 1351 uint16 *wp = (uint16 *) pp; 1352 1353 for (x = w; x > 0; --x) 1354 { 1355 /* use high order byte of 16bit value */ 1356 1357 *cp++ = BWmap[*wp >> 8][0]; 1358 pp += 2 * samplesperpixel; 1359 wp += samplesperpixel; 1360 } 1361 cp += toskew; 1362 pp += fromskew; 1363 } 1364 } 1365 1366 /* 1367 * 1-bit bilevel => colormap/RGB 1368 */ 1369 DECLAREContigPutFunc(put1bitbwtile) 1370 { 1371 uint32** BWmap = img->BWmap; 1372 1373 (void) x; (void) y; 1374 fromskew /= 8; 1375 for( ; h > 0; --h) { 1376 uint32* bw; 1377 UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++); 1378 cp += toskew; 1379 pp += fromskew; 1380 } 1381 } 1382 1383 /* 1384 * 2-bit greyscale => colormap/RGB 1385 */ 1386 DECLAREContigPutFunc(put2bitbwtile) 1387 { 1388 uint32** BWmap = img->BWmap; 1389 1390 (void) x; (void) y; 1391 fromskew /= 4; 1392 for( ; h > 0; --h) { 1393 uint32* bw; 1394 UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++); 1395 cp += toskew; 1396 pp += fromskew; 1397 } 1398 } 1399 1400 /* 1401 * 4-bit greyscale => colormap/RGB 1402 */ 1403 DECLAREContigPutFunc(put4bitbwtile) 1404 { 1405 uint32** BWmap = img->BWmap; 1406 1407 (void) x; (void) y; 1408 fromskew /= 2; 1409 for( ; h > 0; --h) { 1410 uint32* bw; 1411 UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++); 1412 cp += toskew; 1413 pp += fromskew; 1414 } 1415 } 1416 1417 /* 1418 * 8-bit packed samples, no Map => RGB 1419 */ 1420 DECLAREContigPutFunc(putRGBcontig8bittile) 1421 { 1422 int samplesperpixel = img->samplesperpixel; 1423 1424 (void) x; (void) y; 1425 fromskew *= samplesperpixel; 1426 for( ; h > 0; --h) { 1427 UNROLL8(w, NOP, 1428 *cp++ = PACK(pp[0], pp[1], pp[2]); 1429 pp += samplesperpixel); 1430 cp += toskew; 1431 pp += fromskew; 1432 } 1433 } 1434 1435 /* 1436 * 8-bit packed samples => RGBA w/ associated alpha 1437 * (known to have Map == NULL) 1438 */ 1439 DECLAREContigPutFunc(putRGBAAcontig8bittile) 1440 { 1441 int samplesperpixel = img->samplesperpixel; 1442 1443 (void) x; (void) y; 1444 fromskew *= samplesperpixel; 1445 for( ; h > 0; --h) { 1446 UNROLL8(w, NOP, 1447 *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]); 1448 pp += samplesperpixel); 1449 cp += toskew; 1450 pp += fromskew; 1451 } 1452 } 1453 1454 /* 1455 * 8-bit packed samples => RGBA w/ unassociated alpha 1456 * (known to have Map == NULL) 1457 */ 1458 DECLAREContigPutFunc(putRGBUAcontig8bittile) 1459 { 1460 int samplesperpixel = img->samplesperpixel; 1461 (void) y; 1462 fromskew *= samplesperpixel; 1463 for( ; h > 0; --h) { 1464 uint32 r, g, b, a; 1465 uint8* m; 1466 for (x = w; x > 0; --x) { 1467 a = pp[3]; 1468 m = img->UaToAa+((size_t) a<<8); 1469 r = m[pp[0]]; 1470 g = m[pp[1]]; 1471 b = m[pp[2]]; 1472 *cp++ = PACK4(r,g,b,a); 1473 pp += samplesperpixel; 1474 } 1475 cp += toskew; 1476 pp += fromskew; 1477 } 1478 } 1479 1480 /* 1481 * 16-bit packed samples => RGB 1482 */ 1483 DECLAREContigPutFunc(putRGBcontig16bittile) 1484 { 1485 int samplesperpixel = img->samplesperpixel; 1486 uint16 *wp = (uint16 *)pp; 1487 (void) y; 1488 fromskew *= samplesperpixel; 1489 for( ; h > 0; --h) { 1490 for (x = w; x > 0; --x) { 1491 *cp++ = PACK(img->Bitdepth16To8[wp[0]], 1492 img->Bitdepth16To8[wp[1]], 1493 img->Bitdepth16To8[wp[2]]); 1494 wp += samplesperpixel; 1495 } 1496 cp += toskew; 1497 wp += fromskew; 1498 } 1499 } 1500 1501 /* 1502 * 16-bit packed samples => RGBA w/ associated alpha 1503 * (known to have Map == NULL) 1504 */ 1505 DECLAREContigPutFunc(putRGBAAcontig16bittile) 1506 { 1507 int samplesperpixel = img->samplesperpixel; 1508 uint16 *wp = (uint16 *)pp; 1509 (void) y; 1510 fromskew *= samplesperpixel; 1511 for( ; h > 0; --h) { 1512 for (x = w; x > 0; --x) { 1513 *cp++ = PACK4(img->Bitdepth16To8[wp[0]], 1514 img->Bitdepth16To8[wp[1]], 1515 img->Bitdepth16To8[wp[2]], 1516 img->Bitdepth16To8[wp[3]]); 1517 wp += samplesperpixel; 1518 } 1519 cp += toskew; 1520 wp += fromskew; 1521 } 1522 } 1523 1524 /* 1525 * 16-bit packed samples => RGBA w/ unassociated alpha 1526 * (known to have Map == NULL) 1527 */ 1528 DECLAREContigPutFunc(putRGBUAcontig16bittile) 1529 { 1530 int samplesperpixel = img->samplesperpixel; 1531 uint16 *wp = (uint16 *)pp; 1532 (void) y; 1533 fromskew *= samplesperpixel; 1534 for( ; h > 0; --h) { 1535 uint32 r,g,b,a; 1536 uint8* m; 1537 for (x = w; x > 0; --x) { 1538 a = img->Bitdepth16To8[wp[3]]; 1539 m = img->UaToAa+((size_t) a<<8); 1540 r = m[img->Bitdepth16To8[wp[0]]]; 1541 g = m[img->Bitdepth16To8[wp[1]]]; 1542 b = m[img->Bitdepth16To8[wp[2]]]; 1543 *cp++ = PACK4(r,g,b,a); 1544 wp += samplesperpixel; 1545 } 1546 cp += toskew; 1547 wp += fromskew; 1548 } 1549 } 1550 1551 /* 1552 * 8-bit packed CMYK samples w/o Map => RGB 1553 * 1554 * NB: The conversion of CMYK->RGB is *very* crude. 1555 */ 1556 DECLAREContigPutFunc(putRGBcontig8bitCMYKtile) 1557 { 1558 int samplesperpixel = img->samplesperpixel; 1559 uint16 r, g, b, k; 1560 1561 (void) x; (void) y; 1562 fromskew *= samplesperpixel; 1563 for( ; h > 0; --h) { 1564 UNROLL8(w, NOP, 1565 k = 255 - pp[3]; 1566 r = (k*(255-pp[0]))/255; 1567 g = (k*(255-pp[1]))/255; 1568 b = (k*(255-pp[2]))/255; 1569 *cp++ = PACK(r, g, b); 1570 pp += samplesperpixel); 1571 cp += toskew; 1572 pp += fromskew; 1573 } 1574 } 1575 1576 /* 1577 * 8-bit packed CMYK samples w/Map => RGB 1578 * 1579 * NB: The conversion of CMYK->RGB is *very* crude. 1580 */ 1581 DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile) 1582 { 1583 int samplesperpixel = img->samplesperpixel; 1584 TIFFRGBValue* Map = img->Map; 1585 uint16 r, g, b, k; 1586 1587 (void) y; 1588 fromskew *= samplesperpixel; 1589 for( ; h > 0; --h) { 1590 for (x = w; x > 0; --x) { 1591 k = 255 - pp[3]; 1592 r = (k*(255-pp[0]))/255; 1593 g = (k*(255-pp[1]))/255; 1594 b = (k*(255-pp[2]))/255; 1595 *cp++ = PACK(Map[r], Map[g], Map[b]); 1596 pp += samplesperpixel; 1597 } 1598 pp += fromskew; 1599 cp += toskew; 1600 } 1601 } 1602 1603 #define DECLARESepPutFunc(name) \ 1604 static void name(\ 1605 TIFFRGBAImage* img,\ 1606 uint32* cp,\ 1607 uint32 x, uint32 y, \ 1608 uint32 w, uint32 h,\ 1609 int32 fromskew, int32 toskew,\ 1610 unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\ 1611 ) 1612 1613 /* 1614 * 8-bit unpacked samples => RGB 1615 */ 1616 DECLARESepPutFunc(putRGBseparate8bittile) 1617 { 1618 (void) img; (void) x; (void) y; (void) a; 1619 for( ; h > 0; --h) { 1620 UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++)); 1621 SKEW(r, g, b, fromskew); 1622 cp += toskew; 1623 } 1624 } 1625 1626 /* 1627 * 8-bit unpacked samples => RGBA w/ associated alpha 1628 */ 1629 DECLARESepPutFunc(putRGBAAseparate8bittile) 1630 { 1631 (void) img; (void) x; (void) y; 1632 for( ; h > 0; --h) { 1633 UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++)); 1634 SKEW4(r, g, b, a, fromskew); 1635 cp += toskew; 1636 } 1637 } 1638 1639 /* 1640 * 8-bit unpacked CMYK samples => RGBA 1641 */ 1642 DECLARESepPutFunc(putCMYKseparate8bittile) 1643 { 1644 (void) img; (void) y; 1645 for( ; h > 0; --h) { 1646 uint32 rv, gv, bv, kv; 1647 for (x = w; x > 0; --x) { 1648 kv = 255 - *a++; 1649 rv = (kv*(255-*r++))/255; 1650 gv = (kv*(255-*g++))/255; 1651 bv = (kv*(255-*b++))/255; 1652 *cp++ = PACK4(rv,gv,bv,255); 1653 } 1654 SKEW4(r, g, b, a, fromskew); 1655 cp += toskew; 1656 } 1657 } 1658 1659 /* 1660 * 8-bit unpacked samples => RGBA w/ unassociated alpha 1661 */ 1662 DECLARESepPutFunc(putRGBUAseparate8bittile) 1663 { 1664 (void) img; (void) y; 1665 for( ; h > 0; --h) { 1666 uint32 rv, gv, bv, av; 1667 uint8* m; 1668 for (x = w; x > 0; --x) { 1669 av = *a++; 1670 m = img->UaToAa+((size_t) av<<8); 1671 rv = m[*r++]; 1672 gv = m[*g++]; 1673 bv = m[*b++]; 1674 *cp++ = PACK4(rv,gv,bv,av); 1675 } 1676 SKEW4(r, g, b, a, fromskew); 1677 cp += toskew; 1678 } 1679 } 1680 1681 /* 1682 * 16-bit unpacked samples => RGB 1683 */ 1684 DECLARESepPutFunc(putRGBseparate16bittile) 1685 { 1686 uint16 *wr = (uint16*) r; 1687 uint16 *wg = (uint16*) g; 1688 uint16 *wb = (uint16*) b; 1689 (void) img; (void) y; (void) a; 1690 for( ; h > 0; --h) { 1691 for (x = 0; x < w; x++) 1692 *cp++ = PACK(img->Bitdepth16To8[*wr++], 1693 img->Bitdepth16To8[*wg++], 1694 img->Bitdepth16To8[*wb++]); 1695 SKEW(wr, wg, wb, fromskew); 1696 cp += toskew; 1697 } 1698 } 1699 1700 /* 1701 * 16-bit unpacked samples => RGBA w/ associated alpha 1702 */ 1703 DECLARESepPutFunc(putRGBAAseparate16bittile) 1704 { 1705 uint16 *wr = (uint16*) r; 1706 uint16 *wg = (uint16*) g; 1707 uint16 *wb = (uint16*) b; 1708 uint16 *wa = (uint16*) a; 1709 (void) img; (void) y; 1710 for( ; h > 0; --h) { 1711 for (x = 0; x < w; x++) 1712 *cp++ = PACK4(img->Bitdepth16To8[*wr++], 1713 img->Bitdepth16To8[*wg++], 1714 img->Bitdepth16To8[*wb++], 1715 img->Bitdepth16To8[*wa++]); 1716 SKEW4(wr, wg, wb, wa, fromskew); 1717 cp += toskew; 1718 } 1719 } 1720 1721 /* 1722 * 16-bit unpacked samples => RGBA w/ unassociated alpha 1723 */ 1724 DECLARESepPutFunc(putRGBUAseparate16bittile) 1725 { 1726 uint16 *wr = (uint16*) r; 1727 uint16 *wg = (uint16*) g; 1728 uint16 *wb = (uint16*) b; 1729 uint16 *wa = (uint16*) a; 1730 (void) img; (void) y; 1731 for( ; h > 0; --h) { 1732 uint32 r2,g2,b2,a2; 1733 uint8* m; 1734 for (x = w; x > 0; --x) { 1735 a2 = img->Bitdepth16To8[*wa++]; 1736 m = img->UaToAa+((size_t) a2<<8); 1737 r2 = m[img->Bitdepth16To8[*wr++]]; 1738 g2 = m[img->Bitdepth16To8[*wg++]]; 1739 b2 = m[img->Bitdepth16To8[*wb++]]; 1740 *cp++ = PACK4(r2,g2,b2,a2); 1741 } 1742 SKEW4(wr, wg, wb, wa, fromskew); 1743 cp += toskew; 1744 } 1745 } 1746 1747 /* 1748 * 8-bit packed CIE L*a*b 1976 samples => RGB 1749 */ 1750 DECLAREContigPutFunc(putcontig8bitCIELab) 1751 { 1752 float X, Y, Z; 1753 uint32 r, g, b; 1754 (void) y; 1755 fromskew *= 3; 1756 for( ; h > 0; --h) { 1757 for (x = w; x > 0; --x) { 1758 TIFFCIELabToXYZ(img->cielab, 1759 (unsigned char)pp[0], 1760 (signed char)pp[1], 1761 (signed char)pp[2], 1762 &X, &Y, &Z); 1763 TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b); 1764 *cp++ = PACK(r, g, b); 1765 pp += 3; 1766 } 1767 cp += toskew; 1768 pp += fromskew; 1769 } 1770 } 1771 1772 /* 1773 * YCbCr -> RGB conversion and packing routines. 1774 */ 1775 1776 #define YCbCrtoRGB(dst, Y) { \ 1777 uint32 r, g, b; \ 1778 TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \ 1779 dst = PACK(r, g, b); \ 1780 } 1781 1782 /* 1783 * 8-bit packed YCbCr samples => RGB 1784 * This function is generic for different sampling sizes, 1785 * and can handle blocks sizes that aren't multiples of the 1786 * sampling size. However, it is substantially less optimized 1787 * than the specific sampling cases. It is used as a fallback 1788 * for difficult blocks. 1789 */ 1790 #ifdef notdef 1791 static void putcontig8bitYCbCrGenericTile( 1792 TIFFRGBAImage* img, 1793 uint32* cp, 1794 uint32 x, uint32 y, 1795 uint32 w, uint32 h, 1796 int32 fromskew, int32 toskew, 1797 unsigned char* pp, 1798 int h_group, 1799 int v_group ) 1800 1801 { 1802 uint32* cp1 = cp+w+toskew; 1803 uint32* cp2 = cp1+w+toskew; 1804 uint32* cp3 = cp2+w+toskew; 1805 int32 incr = 3*w+4*toskew; 1806 int32 Cb, Cr; 1807 int group_size = v_group * h_group + 2; 1808 1809 (void) y; 1810 fromskew = (fromskew * group_size) / h_group; 1811 1812 for( yy = 0; yy < h; yy++ ) 1813 { 1814 unsigned char *pp_line; 1815 int y_line_group = yy / v_group; 1816 int y_remainder = yy - y_line_group * v_group; 1817 1818 pp_line = pp + v_line_group * 1819 1820 1821 for( xx = 0; xx < w; xx++ ) 1822 { 1823 Cb = pp 1824 } 1825 } 1826 for (; h >= 4; h -= 4) { 1827 x = w>>2; 1828 do { 1829 Cb = pp[16]; 1830 Cr = pp[17]; 1831 1832 YCbCrtoRGB(cp [0], pp[ 0]); 1833 YCbCrtoRGB(cp [1], pp[ 1]); 1834 YCbCrtoRGB(cp [2], pp[ 2]); 1835 YCbCrtoRGB(cp [3], pp[ 3]); 1836 YCbCrtoRGB(cp1[0], pp[ 4]); 1837 YCbCrtoRGB(cp1[1], pp[ 5]); 1838 YCbCrtoRGB(cp1[2], pp[ 6]); 1839 YCbCrtoRGB(cp1[3], pp[ 7]); 1840 YCbCrtoRGB(cp2[0], pp[ 8]); 1841 YCbCrtoRGB(cp2[1], pp[ 9]); 1842 YCbCrtoRGB(cp2[2], pp[10]); 1843 YCbCrtoRGB(cp2[3], pp[11]); 1844 YCbCrtoRGB(cp3[0], pp[12]); 1845 YCbCrtoRGB(cp3[1], pp[13]); 1846 YCbCrtoRGB(cp3[2], pp[14]); 1847 YCbCrtoRGB(cp3[3], pp[15]); 1848 1849 cp += 4, cp1 += 4, cp2 += 4, cp3 += 4; 1850 pp += 18; 1851 } while (--x); 1852 cp += incr, cp1 += incr, cp2 += incr, cp3 += incr; 1853 pp += fromskew; 1854 } 1855 } 1856 #endif 1857 1858 /* 1859 * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB 1860 */ 1861 DECLAREContigPutFunc(putcontig8bitYCbCr44tile) 1862 { 1863 uint32* cp1 = cp+w+toskew; 1864 uint32* cp2 = cp1+w+toskew; 1865 uint32* cp3 = cp2+w+toskew; 1866 int32 incr = 3*w+4*toskew; 1867 1868 (void) y; 1869 /* adjust fromskew */ 1870 fromskew = (fromskew / 4) * (4*2+2); 1871 if ((h & 3) == 0 && (w & 3) == 0) { 1872 for (; h >= 4; h -= 4) { 1873 x = w>>2; 1874 do { 1875 int32 Cb = pp[16]; 1876 int32 Cr = pp[17]; 1877 1878 YCbCrtoRGB(cp [0], pp[ 0]); 1879 YCbCrtoRGB(cp [1], pp[ 1]); 1880 YCbCrtoRGB(cp [2], pp[ 2]); 1881 YCbCrtoRGB(cp [3], pp[ 3]); 1882 YCbCrtoRGB(cp1[0], pp[ 4]); 1883 YCbCrtoRGB(cp1[1], pp[ 5]); 1884 YCbCrtoRGB(cp1[2], pp[ 6]); 1885 YCbCrtoRGB(cp1[3], pp[ 7]); 1886 YCbCrtoRGB(cp2[0], pp[ 8]); 1887 YCbCrtoRGB(cp2[1], pp[ 9]); 1888 YCbCrtoRGB(cp2[2], pp[10]); 1889 YCbCrtoRGB(cp2[3], pp[11]); 1890 YCbCrtoRGB(cp3[0], pp[12]); 1891 YCbCrtoRGB(cp3[1], pp[13]); 1892 YCbCrtoRGB(cp3[2], pp[14]); 1893 YCbCrtoRGB(cp3[3], pp[15]); 1894 1895 cp += 4; 1896 cp1 += 4; 1897 cp2 += 4; 1898 cp3 += 4; 1899 pp += 18; 1900 } while (--x); 1901 cp += incr; 1902 cp1 += incr; 1903 cp2 += incr; 1904 cp3 += incr; 1905 pp += fromskew; 1906 } 1907 } else { 1908 while (h > 0) { 1909 for (x = w; x > 0;) { 1910 int32 Cb = pp[16]; 1911 int32 Cr = pp[17]; 1912 switch (x) { 1913 default: 1914 switch (h) { 1915 default: YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */ 1916 case 3: YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */ 1917 case 2: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */ 1918 case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */ 1919 } /* FALLTHROUGH */ 1920 case 3: 1921 switch (h) { 1922 default: YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */ 1923 case 3: YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */ 1924 case 2: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */ 1925 case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */ 1926 } /* FALLTHROUGH */ 1927 case 2: 1928 switch (h) { 1929 default: YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */ 1930 case 3: YCbCrtoRGB(cp2[1], pp[ 9]); /* FALLTHROUGH */ 1931 case 2: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */ 1932 case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */ 1933 } /* FALLTHROUGH */ 1934 case 1: 1935 switch (h) { 1936 default: YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */ 1937 case 3: YCbCrtoRGB(cp2[0], pp[ 8]); /* FALLTHROUGH */ 1938 case 2: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */ 1939 case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */ 1940 } /* FALLTHROUGH */ 1941 } 1942 if (x < 4) { 1943 cp += x; cp1 += x; cp2 += x; cp3 += x; 1944 x = 0; 1945 } 1946 else { 1947 cp += 4; cp1 += 4; cp2 += 4; cp3 += 4; 1948 x -= 4; 1949 } 1950 pp += 18; 1951 } 1952 if (h <= 4) 1953 break; 1954 h -= 4; 1955 cp += incr; 1956 cp1 += incr; 1957 cp2 += incr; 1958 cp3 += incr; 1959 pp += fromskew; 1960 } 1961 } 1962 } 1963 1964 /* 1965 * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB 1966 */ 1967 DECLAREContigPutFunc(putcontig8bitYCbCr42tile) 1968 { 1969 uint32* cp1 = cp+w+toskew; 1970 int32 incr = 2*toskew+w; 1971 1972 (void) y; 1973 fromskew = (fromskew / 4) * (4*2+2); 1974 if ((w & 3) == 0 && (h & 1) == 0) { 1975 for (; h >= 2; h -= 2) { 1976 x = w>>2; 1977 do { 1978 int32 Cb = pp[8]; 1979 int32 Cr = pp[9]; 1980 1981 YCbCrtoRGB(cp [0], pp[0]); 1982 YCbCrtoRGB(cp [1], pp[1]); 1983 YCbCrtoRGB(cp [2], pp[2]); 1984 YCbCrtoRGB(cp [3], pp[3]); 1985 YCbCrtoRGB(cp1[0], pp[4]); 1986 YCbCrtoRGB(cp1[1], pp[5]); 1987 YCbCrtoRGB(cp1[2], pp[6]); 1988 YCbCrtoRGB(cp1[3], pp[7]); 1989 1990 cp += 4; 1991 cp1 += 4; 1992 pp += 10; 1993 } while (--x); 1994 cp += incr; 1995 cp1 += incr; 1996 pp += fromskew; 1997 } 1998 } else { 1999 while (h > 0) { 2000 for (x = w; x > 0;) { 2001 int32 Cb = pp[8]; 2002 int32 Cr = pp[9]; 2003 switch (x) { 2004 default: 2005 switch (h) { 2006 default: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */ 2007 case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */ 2008 } /* FALLTHROUGH */ 2009 case 3: 2010 switch (h) { 2011 default: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */ 2012 case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */ 2013 } /* FALLTHROUGH */ 2014 case 2: 2015 switch (h) { 2016 default: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */ 2017 case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */ 2018 } /* FALLTHROUGH */ 2019 case 1: 2020 switch (h) { 2021 default: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */ 2022 case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */ 2023 } /* FALLTHROUGH */ 2024 } 2025 if (x < 4) { 2026 cp += x; cp1 += x; 2027 x = 0; 2028 } 2029 else { 2030 cp += 4; cp1 += 4; 2031 x -= 4; 2032 } 2033 pp += 10; 2034 } 2035 if (h <= 2) 2036 break; 2037 h -= 2; 2038 cp += incr; 2039 cp1 += incr; 2040 pp += fromskew; 2041 } 2042 } 2043 } 2044 2045 /* 2046 * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB 2047 */ 2048 DECLAREContigPutFunc(putcontig8bitYCbCr41tile) 2049 { 2050 (void) y; 2051 fromskew = (fromskew / 4) * (4*1+2); 2052 do { 2053 x = w>>2; 2054 while(x>0) { 2055 int32 Cb = pp[4]; 2056 int32 Cr = pp[5]; 2057 2058 YCbCrtoRGB(cp [0], pp[0]); 2059 YCbCrtoRGB(cp [1], pp[1]); 2060 YCbCrtoRGB(cp [2], pp[2]); 2061 YCbCrtoRGB(cp [3], pp[3]); 2062 2063 cp += 4; 2064 pp += 6; 2065 x--; 2066 } 2067 2068 if( (w&3) != 0 ) 2069 { 2070 int32 Cb = pp[4]; 2071 int32 Cr = pp[5]; 2072 2073 switch( (w&3) ) { 2074 case 3: YCbCrtoRGB(cp [2], pp[2]); /*-fallthrough*/ 2075 case 2: YCbCrtoRGB(cp [1], pp[1]); /*-fallthrough*/ 2076 case 1: YCbCrtoRGB(cp [0], pp[0]); /*-fallthrough*/ 2077 case 0: break; 2078 } 2079 2080 cp += (w&3); 2081 pp += 6; 2082 } 2083 2084 cp += toskew; 2085 pp += fromskew; 2086 } while (--h); 2087 2088 } 2089 2090 /* 2091 * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB 2092 */ 2093 DECLAREContigPutFunc(putcontig8bitYCbCr22tile) 2094 { 2095 uint32* cp2; 2096 int32 incr = 2*toskew+w; 2097 (void) y; 2098 fromskew = (fromskew / 2) * (2*2+2); 2099 cp2 = cp+w+toskew; 2100 while (h>=2) { 2101 x = w; 2102 while (x>=2) { 2103 uint32 Cb = pp[4]; 2104 uint32 Cr = pp[5]; 2105 YCbCrtoRGB(cp[0], pp[0]); 2106 YCbCrtoRGB(cp[1], pp[1]); 2107 YCbCrtoRGB(cp2[0], pp[2]); 2108 YCbCrtoRGB(cp2[1], pp[3]); 2109 cp += 2; 2110 cp2 += 2; 2111 pp += 6; 2112 x -= 2; 2113 } 2114 if (x==1) { 2115 uint32 Cb = pp[4]; 2116 uint32 Cr = pp[5]; 2117 YCbCrtoRGB(cp[0], pp[0]); 2118 YCbCrtoRGB(cp2[0], pp[2]); 2119 cp ++ ; 2120 cp2 ++ ; 2121 pp += 6; 2122 } 2123 cp += incr; 2124 cp2 += incr; 2125 pp += fromskew; 2126 h-=2; 2127 } 2128 if (h==1) { 2129 x = w; 2130 while (x>=2) { 2131 uint32 Cb = pp[4]; 2132 uint32 Cr = pp[5]; 2133 YCbCrtoRGB(cp[0], pp[0]); 2134 YCbCrtoRGB(cp[1], pp[1]); 2135 cp += 2; 2136 cp2 += 2; 2137 pp += 6; 2138 x -= 2; 2139 } 2140 if (x==1) { 2141 uint32 Cb = pp[4]; 2142 uint32 Cr = pp[5]; 2143 YCbCrtoRGB(cp[0], pp[0]); 2144 } 2145 } 2146 } 2147 2148 /* 2149 * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB 2150 */ 2151 DECLAREContigPutFunc(putcontig8bitYCbCr21tile) 2152 { 2153 (void) y; 2154 fromskew = (fromskew / 2) * (2*1+2); 2155 do { 2156 x = w>>1; 2157 while(x>0) { 2158 int32 Cb = pp[2]; 2159 int32 Cr = pp[3]; 2160 2161 YCbCrtoRGB(cp[0], pp[0]); 2162 YCbCrtoRGB(cp[1], pp[1]); 2163 2164 cp += 2; 2165 pp += 4; 2166 x --; 2167 } 2168 2169 if( (w&1) != 0 ) 2170 { 2171 int32 Cb = pp[2]; 2172 int32 Cr = pp[3]; 2173 2174 YCbCrtoRGB(cp[0], pp[0]); 2175 2176 cp += 1; 2177 pp += 4; 2178 } 2179 2180 cp += toskew; 2181 pp += fromskew; 2182 } while (--h); 2183 } 2184 2185 /* 2186 * 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB 2187 */ 2188 DECLAREContigPutFunc(putcontig8bitYCbCr12tile) 2189 { 2190 uint32* cp2; 2191 int32 incr = 2*toskew+w; 2192 (void) y; 2193 fromskew = (fromskew / 1) * (1 * 2 + 2); 2194 cp2 = cp+w+toskew; 2195 while (h>=2) { 2196 x = w; 2197 do { 2198 uint32 Cb = pp[2]; 2199 uint32 Cr = pp[3]; 2200 YCbCrtoRGB(cp[0], pp[0]); 2201 YCbCrtoRGB(cp2[0], pp[1]); 2202 cp ++; 2203 cp2 ++; 2204 pp += 4; 2205 } while (--x); 2206 cp += incr; 2207 cp2 += incr; 2208 pp += fromskew; 2209 h-=2; 2210 } 2211 if (h==1) { 2212 x = w; 2213 do { 2214 uint32 Cb = pp[2]; 2215 uint32 Cr = pp[3]; 2216 YCbCrtoRGB(cp[0], pp[0]); 2217 cp ++; 2218 pp += 4; 2219 } while (--x); 2220 } 2221 } 2222 2223 /* 2224 * 8-bit packed YCbCr samples w/ no subsampling => RGB 2225 */ 2226 DECLAREContigPutFunc(putcontig8bitYCbCr11tile) 2227 { 2228 (void) y; 2229 fromskew = (fromskew / 1) * (1 * 1 + 2); 2230 do { 2231 x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */ 2232 do { 2233 int32 Cb = pp[1]; 2234 int32 Cr = pp[2]; 2235 2236 YCbCrtoRGB(*cp++, pp[0]); 2237 2238 pp += 3; 2239 } while (--x); 2240 cp += toskew; 2241 pp += fromskew; 2242 } while (--h); 2243 } 2244 2245 /* 2246 * 8-bit packed YCbCr samples w/ no subsampling => RGB 2247 */ 2248 DECLARESepPutFunc(putseparate8bitYCbCr11tile) 2249 { 2250 (void) y; 2251 (void) a; 2252 /* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */ 2253 for( ; h > 0; --h) { 2254 x = w; 2255 do { 2256 uint32 dr, dg, db; 2257 TIFFYCbCrtoRGB(img->ycbcr,*r++,*g++,*b++,&dr,&dg,&db); 2258 *cp++ = PACK(dr,dg,db); 2259 } while (--x); 2260 SKEW(r, g, b, fromskew); 2261 cp += toskew; 2262 } 2263 } 2264 #undef YCbCrtoRGB 2265 2266 static int isInRefBlackWhiteRange(float f) 2267 { 2268 return f > (float)(-0x7FFFFFFF + 128) && f < (float)0x7FFFFFFF; 2269 } 2270 2271 static int 2272 initYCbCrConversion(TIFFRGBAImage* img) 2273 { 2274 static const char module[] = "initYCbCrConversion"; 2275 2276 float *luma, *refBlackWhite; 2277 2278 if (img->ycbcr == NULL) { 2279 img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc( 2280 TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long)) 2281 + 4*256*sizeof (TIFFRGBValue) 2282 + 2*256*sizeof (int) 2283 + 3*256*sizeof (int32) 2284 ); 2285 if (img->ycbcr == NULL) { 2286 TIFFErrorExt(img->tif->tif_clientdata, module, 2287 "No space for YCbCr->RGB conversion state"); 2288 return (0); 2289 } 2290 } 2291 2292 TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma); 2293 TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE, 2294 &refBlackWhite); 2295 2296 /* Do some validation to avoid later issues. Detect NaN for now */ 2297 /* and also if lumaGreen is zero since we divide by it later */ 2298 if( luma[0] != luma[0] || 2299 luma[1] != luma[1] || 2300 luma[1] == 0.0 || 2301 luma[2] != luma[2] ) 2302 { 2303 TIFFErrorExt(img->tif->tif_clientdata, module, 2304 "Invalid values for YCbCrCoefficients tag"); 2305 return (0); 2306 } 2307 2308 if( !isInRefBlackWhiteRange(refBlackWhite[0]) || 2309 !isInRefBlackWhiteRange(refBlackWhite[1]) || 2310 !isInRefBlackWhiteRange(refBlackWhite[2]) || 2311 !isInRefBlackWhiteRange(refBlackWhite[3]) || 2312 !isInRefBlackWhiteRange(refBlackWhite[4]) || 2313 !isInRefBlackWhiteRange(refBlackWhite[5]) ) 2314 { 2315 TIFFErrorExt(img->tif->tif_clientdata, module, 2316 "Invalid values for ReferenceBlackWhite tag"); 2317 return (0); 2318 } 2319 2320 if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0) 2321 return(0); 2322 return (1); 2323 } 2324 2325 static tileContigRoutine 2326 initCIELabConversion(TIFFRGBAImage* img) 2327 { 2328 static const char module[] = "initCIELabConversion"; 2329 2330 float *whitePoint; 2331 float refWhite[3]; 2332 2333 TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint); 2334 if (whitePoint[1] == 0.0f ) { 2335 TIFFErrorExt(img->tif->tif_clientdata, module, 2336 "Invalid value for WhitePoint tag."); 2337 return NULL; 2338 } 2339 2340 if (!img->cielab) { 2341 img->cielab = (TIFFCIELabToRGB *) 2342 _TIFFmalloc(sizeof(TIFFCIELabToRGB)); 2343 if (!img->cielab) { 2344 TIFFErrorExt(img->tif->tif_clientdata, module, 2345 "No space for CIE L*a*b*->RGB conversion state."); 2346 return NULL; 2347 } 2348 } 2349 2350 refWhite[1] = 100.0F; 2351 refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1]; 2352 refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1]) 2353 / whitePoint[1] * refWhite[1]; 2354 if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) { 2355 TIFFErrorExt(img->tif->tif_clientdata, module, 2356 "Failed to initialize CIE L*a*b*->RGB conversion state."); 2357 _TIFFfree(img->cielab); 2358 return NULL; 2359 } 2360 2361 return putcontig8bitCIELab; 2362 } 2363 2364 /* 2365 * Greyscale images with less than 8 bits/sample are handled 2366 * with a table to avoid lots of shifts and masks. The table 2367 * is setup so that put*bwtile (below) can retrieve 8/bitspersample 2368 * pixel values simply by indexing into the table with one 2369 * number. 2370 */ 2371 static int 2372 makebwmap(TIFFRGBAImage* img) 2373 { 2374 TIFFRGBValue* Map = img->Map; 2375 int bitspersample = img->bitspersample; 2376 int nsamples = 8 / bitspersample; 2377 int i; 2378 uint32* p; 2379 2380 if( nsamples == 0 ) 2381 nsamples = 1; 2382 2383 img->BWmap = (uint32**) _TIFFmalloc( 2384 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32))); 2385 if (img->BWmap == NULL) { 2386 TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for B&W mapping table"); 2387 return (0); 2388 } 2389 p = (uint32*)(img->BWmap + 256); 2390 for (i = 0; i < 256; i++) { 2391 TIFFRGBValue c; 2392 img->BWmap[i] = p; 2393 switch (bitspersample) { 2394 #define GREY(x) c = Map[x]; *p++ = PACK(c,c,c); 2395 case 1: 2396 GREY(i>>7); 2397 GREY((i>>6)&1); 2398 GREY((i>>5)&1); 2399 GREY((i>>4)&1); 2400 GREY((i>>3)&1); 2401 GREY((i>>2)&1); 2402 GREY((i>>1)&1); 2403 GREY(i&1); 2404 break; 2405 case 2: 2406 GREY(i>>6); 2407 GREY((i>>4)&3); 2408 GREY((i>>2)&3); 2409 GREY(i&3); 2410 break; 2411 case 4: 2412 GREY(i>>4); 2413 GREY(i&0xf); 2414 break; 2415 case 8: 2416 case 16: 2417 GREY(i); 2418 break; 2419 } 2420 #undef GREY 2421 } 2422 return (1); 2423 } 2424 2425 /* 2426 * Construct a mapping table to convert from the range 2427 * of the data samples to [0,255] --for display. This 2428 * process also handles inverting B&W images when needed. 2429 */ 2430 static int 2431 setupMap(TIFFRGBAImage* img) 2432 { 2433 int32 x, range; 2434 2435 range = (int32)((1L<<img->bitspersample)-1); 2436 2437 /* treat 16 bit the same as eight bit */ 2438 if( img->bitspersample == 16 ) 2439 range = (int32) 255; 2440 2441 img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue)); 2442 if (img->Map == NULL) { 2443 TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), 2444 "No space for photometric conversion table"); 2445 return (0); 2446 } 2447 if (img->photometric == PHOTOMETRIC_MINISWHITE) { 2448 for (x = 0; x <= range; x++) 2449 img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range); 2450 } else { 2451 for (x = 0; x <= range; x++) 2452 img->Map[x] = (TIFFRGBValue) ((x * 255) / range); 2453 } 2454 if (img->bitspersample <= 16 && 2455 (img->photometric == PHOTOMETRIC_MINISBLACK || 2456 img->photometric == PHOTOMETRIC_MINISWHITE)) { 2457 /* 2458 * Use photometric mapping table to construct 2459 * unpacking tables for samples <= 8 bits. 2460 */ 2461 if (!makebwmap(img)) 2462 return (0); 2463 /* no longer need Map, free it */ 2464 _TIFFfree(img->Map); 2465 img->Map = NULL; 2466 } 2467 return (1); 2468 } 2469 2470 static int 2471 checkcmap(TIFFRGBAImage* img) 2472 { 2473 uint16* r = img->redcmap; 2474 uint16* g = img->greencmap; 2475 uint16* b = img->bluecmap; 2476 long n = 1L<<img->bitspersample; 2477 2478 while (n-- > 0) 2479 if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) 2480 return (16); 2481 return (8); 2482 } 2483 2484 static void 2485 cvtcmap(TIFFRGBAImage* img) 2486 { 2487 uint16* r = img->redcmap; 2488 uint16* g = img->greencmap; 2489 uint16* b = img->bluecmap; 2490 long i; 2491 2492 for (i = (1L<<img->bitspersample)-1; i >= 0; i--) { 2493 #define CVT(x) ((uint16)((x)>>8)) 2494 r[i] = CVT(r[i]); 2495 g[i] = CVT(g[i]); 2496 b[i] = CVT(b[i]); 2497 #undef CVT 2498 } 2499 } 2500 2501 /* 2502 * Palette images with <= 8 bits/sample are handled 2503 * with a table to avoid lots of shifts and masks. The table 2504 * is setup so that put*cmaptile (below) can retrieve 8/bitspersample 2505 * pixel values simply by indexing into the table with one 2506 * number. 2507 */ 2508 static int 2509 makecmap(TIFFRGBAImage* img) 2510 { 2511 int bitspersample = img->bitspersample; 2512 int nsamples = 8 / bitspersample; 2513 uint16* r = img->redcmap; 2514 uint16* g = img->greencmap; 2515 uint16* b = img->bluecmap; 2516 uint32 *p; 2517 int i; 2518 2519 img->PALmap = (uint32**) _TIFFmalloc( 2520 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32))); 2521 if (img->PALmap == NULL) { 2522 TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for Palette mapping table"); 2523 return (0); 2524 } 2525 p = (uint32*)(img->PALmap + 256); 2526 for (i = 0; i < 256; i++) { 2527 TIFFRGBValue c; 2528 img->PALmap[i] = p; 2529 #define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff); 2530 switch (bitspersample) { 2531 case 1: 2532 CMAP(i>>7); 2533 CMAP((i>>6)&1); 2534 CMAP((i>>5)&1); 2535 CMAP((i>>4)&1); 2536 CMAP((i>>3)&1); 2537 CMAP((i>>2)&1); 2538 CMAP((i>>1)&1); 2539 CMAP(i&1); 2540 break; 2541 case 2: 2542 CMAP(i>>6); 2543 CMAP((i>>4)&3); 2544 CMAP((i>>2)&3); 2545 CMAP(i&3); 2546 break; 2547 case 4: 2548 CMAP(i>>4); 2549 CMAP(i&0xf); 2550 break; 2551 case 8: 2552 CMAP(i); 2553 break; 2554 } 2555 #undef CMAP 2556 } 2557 return (1); 2558 } 2559 2560 /* 2561 * Construct any mapping table used 2562 * by the associated put routine. 2563 */ 2564 static int 2565 buildMap(TIFFRGBAImage* img) 2566 { 2567 switch (img->photometric) { 2568 case PHOTOMETRIC_RGB: 2569 case PHOTOMETRIC_YCBCR: 2570 case PHOTOMETRIC_SEPARATED: 2571 if (img->bitspersample == 8) 2572 break; 2573 /* fall through... */ 2574 case PHOTOMETRIC_MINISBLACK: 2575 case PHOTOMETRIC_MINISWHITE: 2576 if (!setupMap(img)) 2577 return (0); 2578 break; 2579 case PHOTOMETRIC_PALETTE: 2580 /* 2581 * Convert 16-bit colormap to 8-bit (unless it looks 2582 * like an old-style 8-bit colormap). 2583 */ 2584 if (checkcmap(img) == 16) 2585 cvtcmap(img); 2586 else 2587 TIFFWarningExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "Assuming 8-bit colormap"); 2588 /* 2589 * Use mapping table and colormap to construct 2590 * unpacking tables for samples < 8 bits. 2591 */ 2592 if (img->bitspersample <= 8 && !makecmap(img)) 2593 return (0); 2594 break; 2595 } 2596 return (1); 2597 } 2598 2599 /* 2600 * Select the appropriate conversion routine for packed data. 2601 */ 2602 static int 2603 PickContigCase(TIFFRGBAImage* img) 2604 { 2605 img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig; 2606 img->put.contig = NULL; 2607 switch (img->photometric) { 2608 case PHOTOMETRIC_RGB: 2609 switch (img->bitspersample) { 2610 case 8: 2611 if (img->alpha == EXTRASAMPLE_ASSOCALPHA && 2612 img->samplesperpixel >= 4) 2613 img->put.contig = putRGBAAcontig8bittile; 2614 else if (img->alpha == EXTRASAMPLE_UNASSALPHA && 2615 img->samplesperpixel >= 4) 2616 { 2617 if (BuildMapUaToAa(img)) 2618 img->put.contig = putRGBUAcontig8bittile; 2619 } 2620 else if( img->samplesperpixel >= 3 ) 2621 img->put.contig = putRGBcontig8bittile; 2622 break; 2623 case 16: 2624 if (img->alpha == EXTRASAMPLE_ASSOCALPHA && 2625 img->samplesperpixel >=4 ) 2626 { 2627 if (BuildMapBitdepth16To8(img)) 2628 img->put.contig = putRGBAAcontig16bittile; 2629 } 2630 else if (img->alpha == EXTRASAMPLE_UNASSALPHA && 2631 img->samplesperpixel >=4 ) 2632 { 2633 if (BuildMapBitdepth16To8(img) && 2634 BuildMapUaToAa(img)) 2635 img->put.contig = putRGBUAcontig16bittile; 2636 } 2637 else if( img->samplesperpixel >=3 ) 2638 { 2639 if (BuildMapBitdepth16To8(img)) 2640 img->put.contig = putRGBcontig16bittile; 2641 } 2642 break; 2643 } 2644 break; 2645 case PHOTOMETRIC_SEPARATED: 2646 if (img->samplesperpixel >=4 && buildMap(img)) { 2647 if (img->bitspersample == 8) { 2648 if (!img->Map) 2649 img->put.contig = putRGBcontig8bitCMYKtile; 2650 else 2651 img->put.contig = putRGBcontig8bitCMYKMaptile; 2652 } 2653 } 2654 break; 2655 case PHOTOMETRIC_PALETTE: 2656 if (buildMap(img)) { 2657 switch (img->bitspersample) { 2658 case 8: 2659 img->put.contig = put8bitcmaptile; 2660 break; 2661 case 4: 2662 img->put.contig = put4bitcmaptile; 2663 break; 2664 case 2: 2665 img->put.contig = put2bitcmaptile; 2666 break; 2667 case 1: 2668 img->put.contig = put1bitcmaptile; 2669 break; 2670 } 2671 } 2672 break; 2673 case PHOTOMETRIC_MINISWHITE: 2674 case PHOTOMETRIC_MINISBLACK: 2675 if (buildMap(img)) { 2676 switch (img->bitspersample) { 2677 case 16: 2678 img->put.contig = put16bitbwtile; 2679 break; 2680 case 8: 2681 if (img->alpha && img->samplesperpixel == 2) 2682 img->put.contig = putagreytile; 2683 else 2684 img->put.contig = putgreytile; 2685 break; 2686 case 4: 2687 img->put.contig = put4bitbwtile; 2688 break; 2689 case 2: 2690 img->put.contig = put2bitbwtile; 2691 break; 2692 case 1: 2693 img->put.contig = put1bitbwtile; 2694 break; 2695 } 2696 } 2697 break; 2698 case PHOTOMETRIC_YCBCR: 2699 if ((img->bitspersample==8) && (img->samplesperpixel==3)) 2700 { 2701 if (initYCbCrConversion(img)!=0) 2702 { 2703 /* 2704 * The 6.0 spec says that subsampling must be 2705 * one of 1, 2, or 4, and that vertical subsampling 2706 * must always be <= horizontal subsampling; so 2707 * there are only a few possibilities and we just 2708 * enumerate the cases. 2709 * Joris: added support for the [1,2] case, nonetheless, to accommodate 2710 * some OJPEG files 2711 */ 2712 uint16 SubsamplingHor; 2713 uint16 SubsamplingVer; 2714 TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &SubsamplingHor, &SubsamplingVer); 2715 switch ((SubsamplingHor<<4)|SubsamplingVer) { 2716 case 0x44: 2717 img->put.contig = putcontig8bitYCbCr44tile; 2718 break; 2719 case 0x42: 2720 img->put.contig = putcontig8bitYCbCr42tile; 2721 break; 2722 case 0x41: 2723 img->put.contig = putcontig8bitYCbCr41tile; 2724 break; 2725 case 0x22: 2726 img->put.contig = putcontig8bitYCbCr22tile; 2727 break; 2728 case 0x21: 2729 img->put.contig = putcontig8bitYCbCr21tile; 2730 break; 2731 case 0x12: 2732 img->put.contig = putcontig8bitYCbCr12tile; 2733 break; 2734 case 0x11: 2735 img->put.contig = putcontig8bitYCbCr11tile; 2736 break; 2737 } 2738 } 2739 } 2740 break; 2741 case PHOTOMETRIC_CIELAB: 2742 if (img->samplesperpixel == 3 && buildMap(img)) { 2743 if (img->bitspersample == 8) 2744 img->put.contig = initCIELabConversion(img); 2745 break; 2746 } 2747 } 2748 return ((img->get!=NULL) && (img->put.contig!=NULL)); 2749 } 2750 2751 /* 2752 * Select the appropriate conversion routine for unpacked data. 2753 * 2754 * NB: we assume that unpacked single channel data is directed 2755 * to the "packed routines. 2756 */ 2757 static int 2758 PickSeparateCase(TIFFRGBAImage* img) 2759 { 2760 img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate; 2761 img->put.separate = NULL; 2762 switch (img->photometric) { 2763 case PHOTOMETRIC_MINISWHITE: 2764 case PHOTOMETRIC_MINISBLACK: 2765 /* greyscale images processed pretty much as RGB by gtTileSeparate */ 2766 case PHOTOMETRIC_RGB: 2767 switch (img->bitspersample) { 2768 case 8: 2769 if (img->alpha == EXTRASAMPLE_ASSOCALPHA) 2770 img->put.separate = putRGBAAseparate8bittile; 2771 else if (img->alpha == EXTRASAMPLE_UNASSALPHA) 2772 { 2773 if (BuildMapUaToAa(img)) 2774 img->put.separate = putRGBUAseparate8bittile; 2775 } 2776 else 2777 img->put.separate = putRGBseparate8bittile; 2778 break; 2779 case 16: 2780 if (img->alpha == EXTRASAMPLE_ASSOCALPHA) 2781 { 2782 if (BuildMapBitdepth16To8(img)) 2783 img->put.separate = putRGBAAseparate16bittile; 2784 } 2785 else if (img->alpha == EXTRASAMPLE_UNASSALPHA) 2786 { 2787 if (BuildMapBitdepth16To8(img) && 2788 BuildMapUaToAa(img)) 2789 img->put.separate = putRGBUAseparate16bittile; 2790 } 2791 else 2792 { 2793 if (BuildMapBitdepth16To8(img)) 2794 img->put.separate = putRGBseparate16bittile; 2795 } 2796 break; 2797 } 2798 break; 2799 case PHOTOMETRIC_SEPARATED: 2800 if (img->bitspersample == 8 && img->samplesperpixel == 4) 2801 { 2802 img->alpha = 1; // Not alpha, but seems like the only way to get 4th band 2803 img->put.separate = putCMYKseparate8bittile; 2804 } 2805 break; 2806 case PHOTOMETRIC_YCBCR: 2807 if ((img->bitspersample==8) && (img->samplesperpixel==3)) 2808 { 2809 if (initYCbCrConversion(img)!=0) 2810 { 2811 uint16 hs, vs; 2812 TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs); 2813 switch ((hs<<4)|vs) { 2814 case 0x11: 2815 img->put.separate = putseparate8bitYCbCr11tile; 2816 break; 2817 /* TODO: add other cases here */ 2818 } 2819 } 2820 } 2821 break; 2822 } 2823 return ((img->get!=NULL) && (img->put.separate!=NULL)); 2824 } 2825 2826 static int 2827 BuildMapUaToAa(TIFFRGBAImage* img) 2828 { 2829 static const char module[]="BuildMapUaToAa"; 2830 uint8* m; 2831 uint16 na,nv; 2832 assert(img->UaToAa==NULL); 2833 img->UaToAa=_TIFFmalloc(65536); 2834 if (img->UaToAa==NULL) 2835 { 2836 TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory"); 2837 return(0); 2838 } 2839 m=img->UaToAa; 2840 for (na=0; na<256; na++) 2841 { 2842 for (nv=0; nv<256; nv++) 2843 *m++=(uint8)((nv*na+127)/255); 2844 } 2845 return(1); 2846 } 2847 2848 static int 2849 BuildMapBitdepth16To8(TIFFRGBAImage* img) 2850 { 2851 static const char module[]="BuildMapBitdepth16To8"; 2852 uint8* m; 2853 uint32 n; 2854 assert(img->Bitdepth16To8==NULL); 2855 img->Bitdepth16To8=_TIFFmalloc(65536); 2856 if (img->Bitdepth16To8==NULL) 2857 { 2858 TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory"); 2859 return(0); 2860 } 2861 m=img->Bitdepth16To8; 2862 for (n=0; n<65536; n++) 2863 *m++=(uint8)((n+128)/257); 2864 return(1); 2865 } 2866 2867 2868 /* 2869 * Read a whole strip off data from the file, and convert to RGBA form. 2870 * If this is the last strip, then it will only contain the portion of 2871 * the strip that is actually within the image space. The result is 2872 * organized in bottom to top form. 2873 */ 2874 2875 2876 int 2877 TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster ) 2878 2879 { 2880 return TIFFReadRGBAStripExt(tif, row, raster, 0 ); 2881 } 2882 2883 int 2884 TIFFReadRGBAStripExt(TIFF* tif, uint32 row, uint32 * raster, int stop_on_error) 2885 2886 { 2887 char emsg[1024] = ""; 2888 TIFFRGBAImage img; 2889 int ok; 2890 uint32 rowsperstrip, rows_to_read; 2891 2892 if( TIFFIsTiled( tif ) ) 2893 { 2894 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), 2895 "Can't use TIFFReadRGBAStrip() with tiled file."); 2896 return (0); 2897 } 2898 2899 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); 2900 if( (row % rowsperstrip) != 0 ) 2901 { 2902 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), 2903 "Row passed to TIFFReadRGBAStrip() must be first in a strip."); 2904 return (0); 2905 } 2906 2907 if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) { 2908 2909 img.row_offset = row; 2910 img.col_offset = 0; 2911 2912 if( row + rowsperstrip > img.height ) 2913 rows_to_read = img.height - row; 2914 else 2915 rows_to_read = rowsperstrip; 2916 2917 ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read ); 2918 2919 TIFFRGBAImageEnd(&img); 2920 } else { 2921 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg); 2922 ok = 0; 2923 } 2924 2925 return (ok); 2926 } 2927 2928 /* 2929 * Read a whole tile off data from the file, and convert to RGBA form. 2930 * The returned RGBA data is organized from bottom to top of tile, 2931 * and may include zeroed areas if the tile extends off the image. 2932 */ 2933 2934 int 2935 TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster) 2936 2937 { 2938 return TIFFReadRGBATileExt(tif, col, row, raster, 0 ); 2939 } 2940 2941 2942 int 2943 TIFFReadRGBATileExt(TIFF* tif, uint32 col, uint32 row, uint32 * raster, int stop_on_error ) 2944 { 2945 char emsg[1024] = ""; 2946 TIFFRGBAImage img; 2947 int ok; 2948 uint32 tile_xsize, tile_ysize; 2949 uint32 read_xsize, read_ysize; 2950 uint32 i_row; 2951 2952 /* 2953 * Verify that our request is legal - on a tile file, and on a 2954 * tile boundary. 2955 */ 2956 2957 if( !TIFFIsTiled( tif ) ) 2958 { 2959 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), 2960 "Can't use TIFFReadRGBATile() with stripped file."); 2961 return (0); 2962 } 2963 2964 TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize); 2965 TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize); 2966 if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 ) 2967 { 2968 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), 2969 "Row/col passed to TIFFReadRGBATile() must be top" 2970 "left corner of a tile."); 2971 return (0); 2972 } 2973 2974 /* 2975 * Setup the RGBA reader. 2976 */ 2977 2978 if (!TIFFRGBAImageOK(tif, emsg) 2979 || !TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) { 2980 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg); 2981 return( 0 ); 2982 } 2983 2984 /* 2985 * The TIFFRGBAImageGet() function doesn't allow us to get off the 2986 * edge of the image, even to fill an otherwise valid tile. So we 2987 * figure out how much we can read, and fix up the tile buffer to 2988 * a full tile configuration afterwards. 2989 */ 2990 2991 if( row + tile_ysize > img.height ) 2992 read_ysize = img.height - row; 2993 else 2994 read_ysize = tile_ysize; 2995 2996 if( col + tile_xsize > img.width ) 2997 read_xsize = img.width - col; 2998 else 2999 read_xsize = tile_xsize; 3000 3001 /* 3002 * Read the chunk of imagery. 3003 */ 3004 3005 img.row_offset = row; 3006 img.col_offset = col; 3007 3008 ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize ); 3009 3010 TIFFRGBAImageEnd(&img); 3011 3012 /* 3013 * If our read was incomplete we will need to fix up the tile by 3014 * shifting the data around as if a full tile of data is being returned. 3015 * 3016 * This is all the more complicated because the image is organized in 3017 * bottom to top format. 3018 */ 3019 3020 if( read_xsize == tile_xsize && read_ysize == tile_ysize ) 3021 return( ok ); 3022 3023 for( i_row = 0; i_row < read_ysize; i_row++ ) { 3024 memmove( raster + (tile_ysize - i_row - 1) * tile_xsize, 3025 raster + (read_ysize - i_row - 1) * read_xsize, 3026 read_xsize * sizeof(uint32) ); 3027 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize, 3028 0, sizeof(uint32) * (tile_xsize - read_xsize) ); 3029 } 3030 3031 for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) { 3032 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize, 3033 0, sizeof(uint32) * tile_xsize ); 3034 } 3035 3036 return (ok); 3037 } 3038 3039 /* vim: set ts=8 sts=8 sw=8 noet: */ 3040 /* 3041 * Local Variables: 3042 * mode: c 3043 * c-basic-offset: 8 3044 * fill-column: 78 3045 * End: 3046 */ 3047