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