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