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