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