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