1793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* $Id: tif_getimage.c,v 1.82 2012-06-06 00:17:49 fwarmerdam Exp $ */ 2793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 3793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 4793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Copyright (c) 1991-1997 Sam Leffler 5793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Copyright (c) 1991-1997 Silicon Graphics, Inc. 6793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 7793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Permission to use, copy, modify, distribute, and sell this software and 8793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * its documentation for any purpose is hereby granted without fee, provided 9793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * that (i) the above copyright notices and this permission notice appear in 10793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * all copies of the software and related documentation, and (ii) the names of 11793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Sam Leffler and Silicon Graphics may not be used in any advertising or 12793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * publicity relating to the software without the specific, prior written 13793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * permission of Sam Leffler and Silicon Graphics. 14793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 15793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 16793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 17793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 18793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 19793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR 20793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 21793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 22793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 23793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 24793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * OF THIS SOFTWARE. 25793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 26793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 27793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 28793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * TIFF Library 29793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 30793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Read and return a packed RGBA image. 31793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 32793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "tiffiop.h" 33793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <stdio.h> 34793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 35793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32); 36793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32); 37793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int gtStripContig(TIFFRGBAImage*, uint32*, uint32, uint32); 38793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int gtStripSeparate(TIFFRGBAImage*, uint32*, uint32, uint32); 39793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int PickContigCase(TIFFRGBAImage*); 40793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int PickSeparateCase(TIFFRGBAImage*); 41793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 42793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int BuildMapUaToAa(TIFFRGBAImage* img); 43793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int BuildMapBitdepth16To8(TIFFRGBAImage* img); 44793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 45793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic const char photoTag[] = "PhotometricInterpretation"; 46793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 47793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 48793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Helper constants used in Orientation tag handling 49793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 50793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define FLIP_VERTICALLY 0x01 51793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define FLIP_HORIZONTALLY 0x02 52793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 53793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 54793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Color conversion constants. We will define display types here. 55793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 56793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 57793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic const TIFFDisplay display_sRGB = { 58793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { /* XYZ -> luminance matrix */ 59793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 3.2410F, -1.5374F, -0.4986F }, 60793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { -0.9692F, 1.8760F, 0.0416F }, 61793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 0.0556F, -0.2040F, 1.0570F } 62793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler }, 63793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 100.0F, 100.0F, 100.0F, /* Light o/p for reference white */ 64793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 255, 255, 255, /* Pixel values for ref. white */ 65793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1.0F, 1.0F, 1.0F, /* Residual light o/p for black pixel */ 66793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2.4F, 2.4F, 2.4F, /* Gamma values for the three guns */ 67793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}; 68793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 69793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 70793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Check the image to see if TIFFReadRGBAImage can deal with it. 71793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 1/0 is returned according to whether or not the image can 72793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * be handled. If 0 is returned, emsg contains the reason 73793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * why it is being rejected. 74793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 75793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint 76793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTIFFRGBAImageOK(TIFF* tif, char emsg[1024]) 77793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 78793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFDirectory* td = &tif->tif_dir; 79793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 photometric; 80793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int colorchannels; 81793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 82793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!tif->tif_decodestatus) { 83793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Sorry, requested compression method is not configured"); 84793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 85793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 86793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (td->td_bitspersample) { 87793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: 88793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 2: 89793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 4: 90793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 8: 91793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 16: 92793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 93793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 94793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Sorry, can not handle images with %d-bit samples", 95793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler td->td_bitspersample); 96793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 97793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 98793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler colorchannels = td->td_samplesperpixel - td->td_extrasamples; 99793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) { 100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (colorchannels) { 101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: 102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler photometric = PHOTOMETRIC_MINISBLACK; 103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 3: 105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler photometric = PHOTOMETRIC_RGB; 106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Missing needed %s tag", photoTag); 109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (photometric) { 113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_MINISWHITE: 114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_MINISBLACK: 115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_PALETTE: 116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (td->td_planarconfig == PLANARCONFIG_CONTIG 117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && td->td_samplesperpixel != 1 118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && td->td_bitspersample < 8 ) { 119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, 120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Sorry, can not handle contiguous data with %s=%d, " 121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "and %s=%d and Bits/Sample=%d", 122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler photoTag, photometric, 123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Samples/pixel", td->td_samplesperpixel, 124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler td->td_bitspersample); 125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* 128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * We should likely validate that any extra samples are either 129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * to be ignored, or are alpha, and if alpha we should try to use 130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * them. But for now we won't bother with this. 131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_YCBCR: 134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* 135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * TODO: if at all meaningful and useful, make more complete 136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * support check here, or better still, refactor to let supporting 137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * code decide whether there is support and what meaningfull 138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * error to return 139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_RGB: 142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (colorchannels < 3) { 143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Sorry, can not handle RGB image with %s=%d", 144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Color channels", colorchannels); 145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_SEPARATED: 149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 inkset; 151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); 152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (inkset != INKSET_CMYK) { 153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, 154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Sorry, can not handle separated image with %s=%d", 155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "InkSet", inkset); 156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (td->td_samplesperpixel < 4) { 159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, 160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Sorry, can not handle separated image with %s=%d", 161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Samples/pixel", td->td_samplesperpixel); 162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_LOGL: 167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (td->td_compression != COMPRESSION_SGILOG) { 168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Sorry, LogL data must have %s=%d", 169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Compression", COMPRESSION_SGILOG); 170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_LOGLUV: 174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (td->td_compression != COMPRESSION_SGILOG && 175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler td->td_compression != COMPRESSION_SGILOG24) { 176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d", 177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24); 178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (td->td_planarconfig != PLANARCONFIG_CONTIG) { 181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d", 182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Planarconfiguration", td->td_planarconfig); 183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_CIELAB: 187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Sorry, can not handle image with %s=%d", 190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler photoTag, photometric); 191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (1); 194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid 197793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTIFFRGBAImageEnd(TIFFRGBAImage* img) 198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->Map) 200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree(img->Map), img->Map = NULL; 201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->BWmap) 202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree(img->BWmap), img->BWmap = NULL; 203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->PALmap) 204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree(img->PALmap), img->PALmap = NULL; 205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->ycbcr) 206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree(img->ycbcr), img->ycbcr = NULL; 207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->cielab) 208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree(img->cielab), img->cielab = NULL; 209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->UaToAa) 210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree(img->UaToAa), img->UaToAa = NULL; 211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->Bitdepth16To8) 212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree(img->Bitdepth16To8), img->Bitdepth16To8 = NULL; 213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 214793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( img->redcmap ) { 215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree( img->redcmap ); 216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree( img->greencmap ); 217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree( img->bluecmap ); 218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->redcmap = img->greencmap = img->bluecmap = NULL; 219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int 223793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerisCCITTCompression(TIFF* tif) 224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 compress; 226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress); 227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (compress == COMPRESSION_CCITTFAX3 || 228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler compress == COMPRESSION_CCITTFAX4 || 229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler compress == COMPRESSION_CCITTRLE || 230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler compress == COMPRESSION_CCITTRLEW); 231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint 234793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) 235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16* sampleinfo; 237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 extrasamples; 238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 planarconfig; 239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 compress; 240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int colorchannels; 241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 *red_orig, *green_orig, *blue_orig; 242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int n_color; 243793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 244793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Initialize to normal values */ 245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->row_offset = 0; 246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->col_offset = 0; 247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->redcmap = NULL; 248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->greencmap = NULL; 249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->bluecmap = NULL; 250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->req_orientation = ORIENTATION_BOTLEFT; /* It is the default */ 251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->tif = tif; 253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->stoponerr = stop; 254793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample); 255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (img->bitspersample) { 256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: 257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 2: 258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 4: 259793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 8: 260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 16: 261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Sorry, can not handle images with %d-bit samples", 264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->bitspersample); 265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto fail_return; 266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->alpha = 0; 268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel); 269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, 270793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler &extrasamples, &sampleinfo); 271793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (extrasamples >= 1) 272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (sampleinfo[0]) { 274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case EXTRASAMPLE_UNSPECIFIED: /* Workaround for some images without */ 275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->samplesperpixel > 3) /* correct info about alpha channel */ 276793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->alpha = EXTRASAMPLE_ASSOCALPHA; 277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */ 279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */ 280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->alpha = sampleinfo[0]; 281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA 286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( !TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) 287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->photometric = PHOTOMETRIC_MINISWHITE; 288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( extrasamples == 0 290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && img->samplesperpixel == 4 291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && img->photometric == PHOTOMETRIC_RGB ) 292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 293793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->alpha = EXTRASAMPLE_ASSOCALPHA; 294793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler extrasamples = 1; 295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler colorchannels = img->samplesperpixel - extrasamples; 299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress); 300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig); 301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) { 302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (colorchannels) { 303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: 304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (isCCITTCompression(tif)) 305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->photometric = PHOTOMETRIC_MINISWHITE; 306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->photometric = PHOTOMETRIC_MINISBLACK; 308793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 3: 310793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->photometric = PHOTOMETRIC_RGB; 311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Missing needed %s tag", photoTag); 314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto fail_return; 315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (img->photometric) { 318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_PALETTE: 319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!TIFFGetField(tif, TIFFTAG_COLORMAP, 320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler &red_orig, &green_orig, &blue_orig)) { 321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Missing required \"Colormap\" tag"); 322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto fail_return; 323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 324793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 325793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* copy the colormaps so we can modify them */ 326793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler n_color = (1L << img->bitspersample); 327793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->redcmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color); 328793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->greencmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color); 329793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color); 330793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( !img->redcmap || !img->greencmap || !img->bluecmap ) { 331793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Out of memory for colormap copy"); 332793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto fail_return; 333793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 334793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 335793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFmemcpy( img->redcmap, red_orig, n_color * 2 ); 336793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFmemcpy( img->greencmap, green_orig, n_color * 2 ); 337793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFmemcpy( img->bluecmap, blue_orig, n_color * 2 ); 338793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 339793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* fall thru... */ 340793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_MINISWHITE: 341793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_MINISBLACK: 342793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (planarconfig == PLANARCONFIG_CONTIG 343793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && img->samplesperpixel != 1 344793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && img->bitspersample < 8 ) { 345793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, 346793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Sorry, can not handle contiguous data with %s=%d, " 347793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "and %s=%d and Bits/Sample=%d", 348793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler photoTag, img->photometric, 349793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Samples/pixel", img->samplesperpixel, 350793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->bitspersample); 351793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto fail_return; 352793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 353793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 354793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_YCBCR: 355793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* It would probably be nice to have a reality check here. */ 356793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (planarconfig == PLANARCONFIG_CONTIG) 357793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* can rely on libjpeg to convert to RGB */ 358793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* XXX should restore current state on exit */ 359793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (compress) { 360793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case COMPRESSION_JPEG: 361793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* 362793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * TODO: when complete tests verify complete desubsampling 363793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * and YCbCr handling, remove use of TIFFTAG_JPEGCOLORMODE in 364793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * favor of tif_getimage.c native handling 365793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 366793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB); 367793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->photometric = PHOTOMETRIC_RGB; 368793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 369793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 370793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* do nothing */; 371793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 372793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 373793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* 374793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * TODO: if at all meaningful and useful, make more complete 375793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * support check here, or better still, refactor to let supporting 376793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * code decide whether there is support and what meaningfull 377793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * error to return 378793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 379793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 380793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_RGB: 381793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (colorchannels < 3) { 382793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Sorry, can not handle RGB image with %s=%d", 383793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Color channels", colorchannels); 384793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto fail_return; 385793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 386793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 387793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_SEPARATED: 388793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 389793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 inkset; 390793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); 391793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (inkset != INKSET_CMYK) { 392793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Sorry, can not handle separated image with %s=%d", 393793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "InkSet", inkset); 394793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto fail_return; 395793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 396793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->samplesperpixel < 4) { 397793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Sorry, can not handle separated image with %s=%d", 398793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Samples/pixel", img->samplesperpixel); 399793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto fail_return; 400793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 401793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 402793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 403793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_LOGL: 404793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (compress != COMPRESSION_SGILOG) { 405793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Sorry, LogL data must have %s=%d", 406793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Compression", COMPRESSION_SGILOG); 407793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto fail_return; 408793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 409793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); 410793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */ 411793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->bitspersample = 8; 412793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 413793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_LOGLUV: 414793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) { 415793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d", 416793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24); 417793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto fail_return; 418793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 419793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (planarconfig != PLANARCONFIG_CONTIG) { 420793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d", 421793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Planarconfiguration", planarconfig); 422793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 423793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 424793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); 425793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->photometric = PHOTOMETRIC_RGB; /* little white lie */ 426793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->bitspersample = 8; 427793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 428793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_CIELAB: 429793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 430793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 431793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Sorry, can not handle image with %s=%d", 432793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler photoTag, img->photometric); 433793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto fail_return; 434793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 435793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->Map = NULL; 436793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->BWmap = NULL; 437793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->PALmap = NULL; 438793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->ycbcr = NULL; 439793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->cielab = NULL; 440793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->UaToAa = NULL; 441793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->Bitdepth16To8 = NULL; 442793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width); 443793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height); 444793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation); 445793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->isContig = 446793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler !(planarconfig == PLANARCONFIG_SEPARATE && img->samplesperpixel > 1); 447793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->isContig) { 448793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!PickContigCase(img)) { 449793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Sorry, can not handle image"); 450793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto fail_return; 451793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 452793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 453793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!PickSeparateCase(img)) { 454793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sprintf(emsg, "Sorry, can not handle image"); 455793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto fail_return; 456793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 457793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 458793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 1; 459793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 460793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fail_return: 461793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree( img->redcmap ); 462793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree( img->greencmap ); 463793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree( img->bluecmap ); 464793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->redcmap = img->greencmap = img->bluecmap = NULL; 465793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 466793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 467793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 468793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint 469793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) 470793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 471793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->get == NULL) { 472793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No \"get\" routine setup"); 473793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 474793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 475793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->put.any == NULL) { 476793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), 477793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "No \"put\" routine setupl; probably can not handle image format"); 478793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 479793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 480793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (*img->get)(img, raster, w, h); 481793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 482793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 483793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 484793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Read the specified image into an ABGR-format rastertaking in account 485793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * specified orientation. 486793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 487793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint 488793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTIFFReadRGBAImageOriented(TIFF* tif, 489793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 rwidth, uint32 rheight, uint32* raster, 490793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int orientation, int stop) 491793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 492793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler char emsg[1024] = ""; 493793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFRGBAImage img; 494793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int ok; 495793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 496793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) { 497793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img.req_orientation = orientation; 498793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* XXX verify rwidth and rheight against width and height */ 499793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth, 500793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler rwidth, img.height); 501793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFRGBAImageEnd(&img); 502793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 503793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg); 504793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ok = 0; 505793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 506793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (ok); 507793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 508793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 509793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 510793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Read the specified image into an ABGR-format raster. Use bottom left 511793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * origin for raster by default. 512793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 513793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint 514793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTIFFReadRGBAImage(TIFF* tif, 515793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 rwidth, uint32 rheight, uint32* raster, int stop) 516793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 517793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster, 518793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ORIENTATION_BOTLEFT, stop); 519793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 520793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 521793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int 522793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslersetorientation(TIFFRGBAImage* img) 523793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 524793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (img->orientation) { 525793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case ORIENTATION_TOPLEFT: 526793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case ORIENTATION_LEFTTOP: 527793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->req_orientation == ORIENTATION_TOPRIGHT || 528793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->req_orientation == ORIENTATION_RIGHTTOP) 529793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return FLIP_HORIZONTALLY; 530793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (img->req_orientation == ORIENTATION_BOTRIGHT || 531793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->req_orientation == ORIENTATION_RIGHTBOT) 532793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return FLIP_HORIZONTALLY | FLIP_VERTICALLY; 533793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (img->req_orientation == ORIENTATION_BOTLEFT || 534793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->req_orientation == ORIENTATION_LEFTBOT) 535793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return FLIP_VERTICALLY; 536793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 537793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 538793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case ORIENTATION_TOPRIGHT: 539793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case ORIENTATION_RIGHTTOP: 540793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->req_orientation == ORIENTATION_TOPLEFT || 541793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->req_orientation == ORIENTATION_LEFTTOP) 542793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return FLIP_HORIZONTALLY; 543793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (img->req_orientation == ORIENTATION_BOTRIGHT || 544793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->req_orientation == ORIENTATION_RIGHTBOT) 545793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return FLIP_VERTICALLY; 546793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (img->req_orientation == ORIENTATION_BOTLEFT || 547793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->req_orientation == ORIENTATION_LEFTBOT) 548793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return FLIP_HORIZONTALLY | FLIP_VERTICALLY; 549793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 550793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 551793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case ORIENTATION_BOTRIGHT: 552793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case ORIENTATION_RIGHTBOT: 553793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->req_orientation == ORIENTATION_TOPLEFT || 554793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->req_orientation == ORIENTATION_LEFTTOP) 555793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return FLIP_HORIZONTALLY | FLIP_VERTICALLY; 556793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (img->req_orientation == ORIENTATION_TOPRIGHT || 557793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->req_orientation == ORIENTATION_RIGHTTOP) 558793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return FLIP_VERTICALLY; 559793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (img->req_orientation == ORIENTATION_BOTLEFT || 560793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->req_orientation == ORIENTATION_LEFTBOT) 561793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return FLIP_HORIZONTALLY; 562793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 563793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 564793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case ORIENTATION_BOTLEFT: 565793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case ORIENTATION_LEFTBOT: 566793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->req_orientation == ORIENTATION_TOPLEFT || 567793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->req_orientation == ORIENTATION_LEFTTOP) 568793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return FLIP_VERTICALLY; 569793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (img->req_orientation == ORIENTATION_TOPRIGHT || 570793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->req_orientation == ORIENTATION_RIGHTTOP) 571793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return FLIP_HORIZONTALLY | FLIP_VERTICALLY; 572793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (img->req_orientation == ORIENTATION_BOTRIGHT || 573793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->req_orientation == ORIENTATION_RIGHTBOT) 574793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return FLIP_HORIZONTALLY; 575793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 576793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 577793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: /* NOTREACHED */ 578793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 579793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 580793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 581793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 582793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 583793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Get an tile-organized image that has 584793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * PlanarConfiguration contiguous if SamplesPerPixel > 1 585793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * or 586793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * SamplesPerPixel == 1 587793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 588793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int 589793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslergtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) 590793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 591793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFF* tif = img->tif; 592793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tileContigRoutine put = img->put.contig; 593793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 col, row, y, rowstoread; 594793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tmsize_t pos; 595793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 tw, th; 596793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char* buf; 597793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 fromskew, toskew; 598793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 nrow; 599793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int ret = 1, flip; 600793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 601793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler buf = (unsigned char*) _TIFFmalloc(TIFFTileSize(tif)); 602793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (buf == 0) { 603793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer"); 604793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 605793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 606793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFmemset(buf, 0, TIFFTileSize(tif)); 607793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); 608793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); 609793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 610793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler flip = setorientation(img); 611793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (flip & FLIP_VERTICALLY) { 612793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler y = h - 1; 613793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler toskew = -(int32)(tw + w); 614793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 615793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else { 616793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler y = 0; 617793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler toskew = -(int32)(tw - w); 618793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 619793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 620793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (row = 0; row < h; row += nrow) 621793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 622793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler rowstoread = th - (row + img->row_offset) % th; 623793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler nrow = (row + rowstoread > h ? h - row : rowstoread); 624793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (col = 0; col < w; col += tw) 625793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 626793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (TIFFReadTile(tif, buf, col+img->col_offset, 627793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler row+img->row_offset, 0, 0)==(tmsize_t)(-1) && img->stoponerr) 628793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 629793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = 0; 630793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 631793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 632793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 633793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif); 634793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 635793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (col + tw > w) 636793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 637793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* 638793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Tile is clipped horizontally. Calculate 639793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * visible portion and skewing factors. 640793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 641793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 npix = w - col; 642793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew = tw - npix; 643793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (*put)(img, raster+y*w+col, col, y, 644793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler npix, nrow, fromskew, toskew + fromskew, buf + pos); 645793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 646793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 647793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 648793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (*put)(img, raster+y*w+col, col, y, tw, nrow, 0, toskew, buf + pos); 649793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 650793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 651793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 652793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); 653793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 654793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree(buf); 655793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 656793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (flip & FLIP_HORIZONTALLY) { 657793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 line; 658793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 659793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (line = 0; line < h; line++) { 660793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 *left = raster + (line * w); 661793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 *right = left + w - 1; 662793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 663793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while ( left < right ) { 664793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 temp = *left; 665793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *left = *right; 666793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *right = temp; 667793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler left++, right--; 668793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 669793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 670793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 671793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 672793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (ret); 673793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 674793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 675793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 676793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Get an tile-organized image that has 677793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * SamplesPerPixel > 1 678793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * PlanarConfiguration separated 679793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * We assume that all such images are RGB. 680793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 681793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int 682793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslergtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) 683793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 684793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFF* tif = img->tif; 685793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tileSeparateRoutine put = img->put.separate; 686793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 col, row, y, rowstoread; 687793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tmsize_t pos; 688793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 tw, th; 689793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char* buf; 690793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char* p0; 691793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char* p1; 692793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char* p2; 693793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char* pa; 694793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tmsize_t tilesize; 695793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tmsize_t bufsize; 696793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 fromskew, toskew; 697793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int alpha = img->alpha; 698793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 nrow; 699793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int ret = 1, flip; 700793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int colorchannels; 701793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 702793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tilesize = TIFFTileSize(tif); 703793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,tilesize); 704793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (bufsize == 0) { 705793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtTileSeparate"); 706793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 707793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 708793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler buf = (unsigned char*) _TIFFmalloc(bufsize); 709793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (buf == 0) { 710793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer"); 711793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 712793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 713793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFmemset(buf, 0, bufsize); 714793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler p0 = buf; 715793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler p1 = p0 + tilesize; 716793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler p2 = p1 + tilesize; 717793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pa = (alpha?(p2+tilesize):NULL); 718793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); 719793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); 720793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 721793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler flip = setorientation(img); 722793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (flip & FLIP_VERTICALLY) { 723793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler y = h - 1; 724793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler toskew = -(int32)(tw + w); 725793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 726793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else { 727793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler y = 0; 728793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler toskew = -(int32)(tw - w); 729793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 730793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 731793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch( img->photometric ) 732793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 733793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_MINISWHITE: 734793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_MINISBLACK: 735793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_PALETTE: 736793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler colorchannels = 1; 737793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler p2 = p1 = p0; 738793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 739793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 740793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 741793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler colorchannels = 3; 742793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 743793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 744793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 745793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (row = 0; row < h; row += nrow) 746793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 747793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler rowstoread = th - (row + img->row_offset) % th; 748793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler nrow = (row + rowstoread > h ? h - row : rowstoread); 749793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (col = 0; col < w; col += tw) 750793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 751793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (TIFFReadTile(tif, p0, col+img->col_offset, 752793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr) 753793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 754793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = 0; 755793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 756793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 757793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (colorchannels > 1 758793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && TIFFReadTile(tif, p1, col+img->col_offset, 759793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler row+img->row_offset,0,1) == (tmsize_t)(-1) 760793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && img->stoponerr) 761793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 762793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = 0; 763793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 764793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 765793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (colorchannels > 1 766793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && TIFFReadTile(tif, p2, col+img->col_offset, 767793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler row+img->row_offset,0,2) == (tmsize_t)(-1) 768793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && img->stoponerr) 769793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 770793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = 0; 771793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 772793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 773793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (alpha 774793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && TIFFReadTile(tif,pa,col+img->col_offset, 775793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler row+img->row_offset,0,colorchannels) == (tmsize_t)(-1) 776793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && img->stoponerr) 777793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 778793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = 0; 779793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 780793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 781793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 782793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif); 783793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 784793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (col + tw > w) 785793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 786793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* 787793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Tile is clipped horizontally. Calculate 788793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * visible portion and skewing factors. 789793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 790793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 npix = w - col; 791793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew = tw - npix; 792793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (*put)(img, raster+y*w+col, col, y, 793793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler npix, nrow, fromskew, toskew + fromskew, 794793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL)); 795793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 796793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (*put)(img, raster+y*w+col, col, y, 797793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tw, nrow, 0, toskew, p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL)); 798793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 799793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 800793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 801793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler y += (flip & FLIP_VERTICALLY ?-(int32) nrow : (int32) nrow); 802793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 803793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 804793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (flip & FLIP_HORIZONTALLY) { 805793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 line; 806793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 807793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (line = 0; line < h; line++) { 808793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 *left = raster + (line * w); 809793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 *right = left + w - 1; 810793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 811793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while ( left < right ) { 812793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 temp = *left; 813793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *left = *right; 814793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *right = temp; 815793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler left++, right--; 816793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 817793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 818793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 819793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 820793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree(buf); 821793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (ret); 822793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 823793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 824793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 825793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Get a strip-organized image that has 826793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * PlanarConfiguration contiguous if SamplesPerPixel > 1 827793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * or 828793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * SamplesPerPixel == 1 829793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 830793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int 831793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslergtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) 832793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 833793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFF* tif = img->tif; 834793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tileContigRoutine put = img->put.contig; 835793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 row, y, nrow, nrowsub, rowstoread; 836793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tmsize_t pos; 837793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char* buf; 838793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 rowsperstrip; 839793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 subsamplinghor,subsamplingver; 840793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 imagewidth = img->width; 841793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tmsize_t scanline; 842793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 fromskew, toskew; 843793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int ret = 1, flip; 844793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 845793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler buf = (unsigned char*) _TIFFmalloc(TIFFStripSize(tif)); 846793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (buf == 0) { 847793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer"); 848793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 849793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 850793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFmemset(buf, 0, TIFFStripSize(tif)); 851793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 852793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler flip = setorientation(img); 853793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (flip & FLIP_VERTICALLY) { 854793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler y = h - 1; 855793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler toskew = -(int32)(w + w); 856793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 857793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler y = 0; 858793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler toskew = -(int32)(w - w); 859793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 860793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 861793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); 862793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver); 863793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler scanline = TIFFScanlineSize(tif); 864793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew = (w < imagewidth ? imagewidth - w : 0); 865793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (row = 0; row < h; row += nrow) 866793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 867793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; 868793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler nrow = (row + rowstoread > h ? h - row : rowstoread); 869793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler nrowsub = nrow; 870793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((nrowsub%subsamplingver)!=0) 871793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler nrowsub+=subsamplingver-nrowsub%subsamplingver; 872793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (TIFFReadEncodedStrip(tif, 873793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFComputeStrip(tif,row+img->row_offset, 0), 874793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler buf, 875793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ((row + img->row_offset)%rowsperstrip + nrowsub) * scanline)==(tmsize_t)(-1) 876793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && img->stoponerr) 877793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 878793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = 0; 879793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 880793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 881793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 882793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pos = ((row + img->row_offset) % rowsperstrip) * scanline; 883793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos); 884793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); 885793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 886793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 887793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (flip & FLIP_HORIZONTALLY) { 888793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 line; 889793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 890793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (line = 0; line < h; line++) { 891793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 *left = raster + (line * w); 892793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 *right = left + w - 1; 893793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 894793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while ( left < right ) { 895793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 temp = *left; 896793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *left = *right; 897793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *right = temp; 898793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler left++, right--; 899793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 900793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 901793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 902793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 903793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree(buf); 904793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (ret); 905793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 906793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 907793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 908793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Get a strip-organized image with 909793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * SamplesPerPixel > 1 910793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * PlanarConfiguration separated 911793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * We assume that all such images are RGB. 912793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 913793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int 914793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslergtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) 915793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 916793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFF* tif = img->tif; 917793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tileSeparateRoutine put = img->put.separate; 918793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char *buf; 919793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char *p0, *p1, *p2, *pa; 920793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 row, y, nrow, rowstoread; 921793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tmsize_t pos; 922793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tmsize_t scanline; 923793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 rowsperstrip, offset_row; 924793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 imagewidth = img->width; 925793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tmsize_t stripsize; 926793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tmsize_t bufsize; 927793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 fromskew, toskew; 928793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int alpha = img->alpha; 929793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int ret = 1, flip, colorchannels; 930793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 931793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler stripsize = TIFFStripSize(tif); 932793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,stripsize); 933793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (bufsize == 0) { 934793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtStripSeparate"); 935793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 936793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 937793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler p0 = buf = (unsigned char *)_TIFFmalloc(bufsize); 938793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (buf == 0) { 939793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer"); 940793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 941793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 942793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFmemset(buf, 0, bufsize); 943793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler p1 = p0 + stripsize; 944793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler p2 = p1 + stripsize; 945793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pa = (alpha?(p2+stripsize):NULL); 946793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 947793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler flip = setorientation(img); 948793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (flip & FLIP_VERTICALLY) { 949793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler y = h - 1; 950793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler toskew = -(int32)(w + w); 951793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 952793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else { 953793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler y = 0; 954793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler toskew = -(int32)(w - w); 955793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 956793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 957793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch( img->photometric ) 958793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 959793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_MINISWHITE: 960793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_MINISBLACK: 961793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_PALETTE: 962793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler colorchannels = 1; 963793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler p2 = p1 = p0; 964793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 965793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 966793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 967793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler colorchannels = 3; 968793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 969793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 970793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 971793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); 972793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler scanline = TIFFScanlineSize(tif); 973793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew = (w < imagewidth ? imagewidth - w : 0); 974793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (row = 0; row < h; row += nrow) 975793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 976793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; 977793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler nrow = (row + rowstoread > h ? h - row : rowstoread); 978793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler offset_row = row + img->row_offset; 979793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0), 980793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1) 981793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && img->stoponerr) 982793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 983793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = 0; 984793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 985793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 986793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (colorchannels > 1 987793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1), 988793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler p1, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1) 989793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && img->stoponerr) 990793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 991793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = 0; 992793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 993793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 994793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (colorchannels > 1 995793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2), 996793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler p2, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1) 997793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && img->stoponerr) 998793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 999793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = 0; 1000793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1001793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1002793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (alpha) 1003793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1004793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, colorchannels), 1005793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pa, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1) 1006793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler && img->stoponerr) 1007793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1008793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = 0; 1009793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1010793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1011793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1012793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1013793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pos = ((row + img->row_offset) % rowsperstrip) * scanline; 1014793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos, 1015793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler p2 + pos, (alpha?(pa+pos):NULL)); 1016793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow); 1017793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1018793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1019793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (flip & FLIP_HORIZONTALLY) { 1020793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 line; 1021793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1022793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (line = 0; line < h; line++) { 1023793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 *left = raster + (line * w); 1024793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 *right = left + w - 1; 1025793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1026793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while ( left < right ) { 1027793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 temp = *left; 1028793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *left = *right; 1029793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *right = temp; 1030793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler left++, right--; 1031793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1032793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1033793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1034793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1035793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree(buf); 1036793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (ret); 1037793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1038793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1039793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1040793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * The following routines move decoded data returned 1041793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * from the TIFF library into rasters filled with packed 1042793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * ABGR pixels (i.e. suitable for passing to lrecwrite.) 1043793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 1044793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * The routines have been created according to the most 1045793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * important cases and optimized. PickContigCase and 1046793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * PickSeparateCase analyze the parameters and select 1047793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * the appropriate "get" and "put" routine to use. 1048793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1049793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define REPEAT8(op) REPEAT4(op); REPEAT4(op) 1050793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define REPEAT4(op) REPEAT2(op); REPEAT2(op) 1051793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define REPEAT2(op) op; op 1052793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define CASE8(x,op) \ 1053793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (x) { \ 1054793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 7: op; case 6: op; case 5: op; \ 1055793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 4: op; case 3: op; case 2: op; \ 1056793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: op; \ 1057793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1058793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define CASE4(x,op) switch (x) { case 3: op; case 2: op; case 1: op; } 1059793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define NOP 1060793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1061793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define UNROLL8(w, op1, op2) { \ 1062793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 _x; \ 1063793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (_x = w; _x >= 8; _x -= 8) { \ 1064793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler op1; \ 1065793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler REPEAT8(op2); \ 1066793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } \ 1067793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (_x > 0) { \ 1068793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler op1; \ 1069793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CASE8(_x,op2); \ 1070793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } \ 1071793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1072793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define UNROLL4(w, op1, op2) { \ 1073793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 _x; \ 1074793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (_x = w; _x >= 4; _x -= 4) { \ 1075793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler op1; \ 1076793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler REPEAT4(op2); \ 1077793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } \ 1078793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (_x > 0) { \ 1079793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler op1; \ 1080793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CASE4(_x,op2); \ 1081793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } \ 1082793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1083793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define UNROLL2(w, op1, op2) { \ 1084793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 _x; \ 1085793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (_x = w; _x >= 2; _x -= 2) { \ 1086793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler op1; \ 1087793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler REPEAT2(op2); \ 1088793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } \ 1089793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (_x) { \ 1090793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler op1; \ 1091793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler op2; \ 1092793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } \ 1093793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1094793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1095793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; } 1096793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; } 1097793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1098793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define A1 (((uint32)0xffL)<<24) 1099793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define PACK(r,g,b) \ 1100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1) 1101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define PACK4(r,g,b,a) \ 1102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24)) 1103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define W2B(v) (((v)>>8)&0xff) 1104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */ 1105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define PACKW(r,g,b) \ 1106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1) 1107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define PACKW4(r,g,b,a) \ 1108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24)) 1109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define DECLAREContigPutFunc(name) \ 1111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void name(\ 1112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFRGBAImage* img, \ 1113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* cp, \ 1114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 x, uint32 y, \ 1115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 w, uint32 h, \ 1116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 fromskew, int32 toskew, \ 1117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char* pp \ 1118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler) 1119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit palette => colormap/RGB 1122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1123793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(put8bitcmaptile) 1124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32** PALmap = img->PALmap; 1126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int samplesperpixel = img->samplesperpixel; 1127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 1129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = w; x-- > 0;) 1131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = PALmap[*pp][0]; 1133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += samplesperpixel; 1134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 4-bit palette => colormap/RGB 1142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1143793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(put4bitcmaptile) 1144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32** PALmap = img->PALmap; 1146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) x; (void) y; 1148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew /= 2; 1149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* bw; 1151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++); 1152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 2-bit palette => colormap/RGB 1159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1160793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(put2bitcmaptile) 1161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32** PALmap = img->PALmap; 1163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) x; (void) y; 1165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew /= 4; 1166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* bw; 1168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++); 1169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 1-bit palette => colormap/RGB 1176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1177793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(put1bitcmaptile) 1178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32** PALmap = img->PALmap; 1180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) x; (void) y; 1182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew /= 8; 1183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* bw; 1185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++); 1186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit greyscale => colormap/RGB 1193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1194793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putgreytile) 1195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int samplesperpixel = img->samplesperpixel; 1197793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32** BWmap = img->BWmap; 1198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 1200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = w; x-- > 0;) 1202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = BWmap[*pp][0]; 1204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += samplesperpixel; 1205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit greyscale with associated alpha => colormap/RGBA 1213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1214793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putagreytile) 1215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int samplesperpixel = img->samplesperpixel; 1217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32** BWmap = img->BWmap; 1218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 1220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = w; x-- > 0;) 1222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = BWmap[*pp][0] & (*(pp+1) << 24 | ~A1); 1224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += samplesperpixel; 1225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 16-bit greyscale => colormap/RGB 1233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1234793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(put16bitbwtile) 1235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int samplesperpixel = img->samplesperpixel; 1237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32** BWmap = img->BWmap; 1238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 1240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 *wp = (uint16 *) pp; 1242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1243793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = w; x-- > 0;) 1244793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* use high order byte of 16bit value */ 1246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = BWmap[*wp >> 8][0]; 1248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += 2 * samplesperpixel; 1249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler wp += samplesperpixel; 1250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1254793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 1-bit bilevel => colormap/RGB 1258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1259793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(put1bitbwtile) 1260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32** BWmap = img->BWmap; 1262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) x; (void) y; 1264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew /= 8; 1265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* bw; 1267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++); 1268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1270793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1271793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 2-bit greyscale => colormap/RGB 1275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1276793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(put2bitbwtile) 1277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32** BWmap = img->BWmap; 1279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) x; (void) y; 1281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew /= 4; 1282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* bw; 1284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++); 1285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 4-bit greyscale => colormap/RGB 1292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1293793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(put4bitbwtile) 1294793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32** BWmap = img->BWmap; 1296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) x; (void) y; 1298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew /= 2; 1299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* bw; 1301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++); 1302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1308793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed samples, no Map => RGB 1309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1310793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putRGBcontig8bittile) 1311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int samplesperpixel = img->samplesperpixel; 1313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) x; (void) y; 1315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew *= samplesperpixel; 1316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UNROLL8(w, NOP, 1318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = PACK(pp[0], pp[1], pp[2]); 1319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += samplesperpixel); 1320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1324793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1325793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1326793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed samples => RGBA w/ associated alpha 1327793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * (known to have Map == NULL) 1328793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1329793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putRGBAAcontig8bittile) 1330793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1331793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int samplesperpixel = img->samplesperpixel; 1332793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1333793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) x; (void) y; 1334793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew *= samplesperpixel; 1335793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1336793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UNROLL8(w, NOP, 1337793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]); 1338793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += samplesperpixel); 1339793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1340793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1341793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1342793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1343793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1344793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1345793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed samples => RGBA w/ unassociated alpha 1346793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * (known to have Map == NULL) 1347793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1348793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putRGBUAcontig8bittile) 1349793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1350793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int samplesperpixel = img->samplesperpixel; 1351793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 1352793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew *= samplesperpixel; 1353793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1354793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 r, g, b, a; 1355793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint8* m; 1356793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = w; x-- > 0;) { 1357793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler a = pp[3]; 1358793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler m = img->UaToAa+(a<<8); 1359793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler r = m[pp[0]]; 1360793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler g = m[pp[1]]; 1361793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler b = m[pp[2]]; 1362793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = PACK4(r,g,b,a); 1363793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += samplesperpixel; 1364793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1365793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1366793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1367793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1368793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1369793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1370793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1371793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 16-bit packed samples => RGB 1372793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1373793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putRGBcontig16bittile) 1374793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1375793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int samplesperpixel = img->samplesperpixel; 1376793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 *wp = (uint16 *)pp; 1377793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 1378793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew *= samplesperpixel; 1379793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1380793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = w; x-- > 0;) { 1381793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = PACK(img->Bitdepth16To8[wp[0]], 1382793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->Bitdepth16To8[wp[1]], 1383793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->Bitdepth16To8[wp[2]]); 1384793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler wp += samplesperpixel; 1385793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1386793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1387793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler wp += fromskew; 1388793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1389793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1390793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1391793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1392793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 16-bit packed samples => RGBA w/ associated alpha 1393793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * (known to have Map == NULL) 1394793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1395793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putRGBAAcontig16bittile) 1396793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1397793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int samplesperpixel = img->samplesperpixel; 1398793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 *wp = (uint16 *)pp; 1399793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 1400793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew *= samplesperpixel; 1401793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1402793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = w; x-- > 0;) { 1403793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = PACK4(img->Bitdepth16To8[wp[0]], 1404793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->Bitdepth16To8[wp[1]], 1405793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->Bitdepth16To8[wp[2]], 1406793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->Bitdepth16To8[wp[3]]); 1407793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler wp += samplesperpixel; 1408793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1409793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1410793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler wp += fromskew; 1411793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1412793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1413793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1414793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1415793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 16-bit packed samples => RGBA w/ unassociated alpha 1416793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * (known to have Map == NULL) 1417793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1418793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putRGBUAcontig16bittile) 1419793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1420793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int samplesperpixel = img->samplesperpixel; 1421793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 *wp = (uint16 *)pp; 1422793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 1423793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew *= samplesperpixel; 1424793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1425793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 r,g,b,a; 1426793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint8* m; 1427793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = w; x-- > 0;) { 1428793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler a = img->Bitdepth16To8[wp[3]]; 1429793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler m = img->UaToAa+(a<<8); 1430793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler r = m[img->Bitdepth16To8[wp[0]]]; 1431793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler g = m[img->Bitdepth16To8[wp[1]]]; 1432793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler b = m[img->Bitdepth16To8[wp[2]]]; 1433793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = PACK4(r,g,b,a); 1434793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler wp += samplesperpixel; 1435793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1436793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1437793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler wp += fromskew; 1438793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1439793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1440793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1441793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1442793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed CMYK samples w/o Map => RGB 1443793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 1444793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * NB: The conversion of CMYK->RGB is *very* crude. 1445793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1446793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putRGBcontig8bitCMYKtile) 1447793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1448793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int samplesperpixel = img->samplesperpixel; 1449793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 r, g, b, k; 1450793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1451793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) x; (void) y; 1452793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew *= samplesperpixel; 1453793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1454793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UNROLL8(w, NOP, 1455793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler k = 255 - pp[3]; 1456793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler r = (k*(255-pp[0]))/255; 1457793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler g = (k*(255-pp[1]))/255; 1458793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler b = (k*(255-pp[2]))/255; 1459793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = PACK(r, g, b); 1460793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += samplesperpixel); 1461793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1462793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1463793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1464793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1465793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1466793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1467793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed CMYK samples w/Map => RGB 1468793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 1469793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * NB: The conversion of CMYK->RGB is *very* crude. 1470793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1471793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile) 1472793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1473793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int samplesperpixel = img->samplesperpixel; 1474793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFRGBValue* Map = img->Map; 1475793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 r, g, b, k; 1476793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1477793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 1478793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew *= samplesperpixel; 1479793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1480793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = w; x-- > 0;) { 1481793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler k = 255 - pp[3]; 1482793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler r = (k*(255-pp[0]))/255; 1483793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler g = (k*(255-pp[1]))/255; 1484793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler b = (k*(255-pp[2]))/255; 1485793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = PACK(Map[r], Map[g], Map[b]); 1486793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += samplesperpixel; 1487793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1488793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1489793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1490793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1491793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1492793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1493793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define DECLARESepPutFunc(name) \ 1494793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void name(\ 1495793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFRGBAImage* img,\ 1496793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* cp,\ 1497793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 x, uint32 y, \ 1498793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 w, uint32 h,\ 1499793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 fromskew, int32 toskew,\ 1500793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\ 1501793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler) 1502793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1503793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1504793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit unpacked samples => RGB 1505793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1506793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLARESepPutFunc(putRGBseparate8bittile) 1507793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1508793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) img; (void) x; (void) y; (void) a; 1509793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1510793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++)); 1511793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler SKEW(r, g, b, fromskew); 1512793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1513793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1514793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1515793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1516793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1517793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit unpacked samples => RGBA w/ associated alpha 1518793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1519793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLARESepPutFunc(putRGBAAseparate8bittile) 1520793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1521793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) img; (void) x; (void) y; 1522793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1523793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++)); 1524793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler SKEW4(r, g, b, a, fromskew); 1525793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1526793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1527793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1528793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1529793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1530793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit unpacked CMYK samples => RGBA 1531793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1532793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLARESepPutFunc(putCMYKseparate8bittile) 1533793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1534793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) img; (void) y; 1535793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1536793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 rv, gv, bv, kv; 1537793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = w; x-- > 0;) { 1538793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler kv = 255 - *a++; 1539793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler rv = (kv*(255-*r++))/255; 1540793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler gv = (kv*(255-*g++))/255; 1541793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bv = (kv*(255-*b++))/255; 1542793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = PACK4(rv,gv,bv,255); 1543793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1544793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler SKEW4(r, g, b, a, fromskew); 1545793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1546793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1547793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1548793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1549793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1550793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit unpacked samples => RGBA w/ unassociated alpha 1551793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1552793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLARESepPutFunc(putRGBUAseparate8bittile) 1553793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1554793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) img; (void) y; 1555793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1556793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 rv, gv, bv, av; 1557793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint8* m; 1558793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = w; x-- > 0;) { 1559793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler av = *a++; 1560793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler m = img->UaToAa+(av<<8); 1561793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler rv = m[*r++]; 1562793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler gv = m[*g++]; 1563793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bv = m[*b++]; 1564793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = PACK4(rv,gv,bv,av); 1565793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1566793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler SKEW4(r, g, b, a, fromskew); 1567793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1568793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1569793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1570793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1571793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1572793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 16-bit unpacked samples => RGB 1573793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1574793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLARESepPutFunc(putRGBseparate16bittile) 1575793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1576793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 *wr = (uint16*) r; 1577793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 *wg = (uint16*) g; 1578793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 *wb = (uint16*) b; 1579793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) img; (void) y; (void) a; 1580793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1581793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = 0; x < w; x++) 1582793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = PACK(img->Bitdepth16To8[*wr++], 1583793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->Bitdepth16To8[*wg++], 1584793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->Bitdepth16To8[*wb++]); 1585793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler SKEW(wr, wg, wb, fromskew); 1586793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1587793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1588793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1589793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1590793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1591793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 16-bit unpacked samples => RGBA w/ associated alpha 1592793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1593793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLARESepPutFunc(putRGBAAseparate16bittile) 1594793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1595793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 *wr = (uint16*) r; 1596793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 *wg = (uint16*) g; 1597793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 *wb = (uint16*) b; 1598793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 *wa = (uint16*) a; 1599793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) img; (void) y; 1600793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1601793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = 0; x < w; x++) 1602793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = PACK4(img->Bitdepth16To8[*wr++], 1603793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->Bitdepth16To8[*wg++], 1604793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->Bitdepth16To8[*wb++], 1605793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->Bitdepth16To8[*wa++]); 1606793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler SKEW4(wr, wg, wb, wa, fromskew); 1607793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1608793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1609793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1610793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1611793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1612793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 16-bit unpacked samples => RGBA w/ unassociated alpha 1613793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1614793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLARESepPutFunc(putRGBUAseparate16bittile) 1615793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1616793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 *wr = (uint16*) r; 1617793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 *wg = (uint16*) g; 1618793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 *wb = (uint16*) b; 1619793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 *wa = (uint16*) a; 1620793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) img; (void) y; 1621793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1622793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 r,g,b,a; 1623793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint8* m; 1624793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = w; x-- > 0;) { 1625793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler a = img->Bitdepth16To8[*wa++]; 1626793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler m = img->UaToAa+(a<<8); 1627793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler r = m[img->Bitdepth16To8[*wr++]]; 1628793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler g = m[img->Bitdepth16To8[*wg++]]; 1629793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler b = m[img->Bitdepth16To8[*wb++]]; 1630793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = PACK4(r,g,b,a); 1631793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1632793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler SKEW4(wr, wg, wb, wa, fromskew); 1633793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1634793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1635793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1636793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1637793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1638793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed CIE L*a*b 1976 samples => RGB 1639793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1640793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putcontig8bitCIELab) 1641793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1642793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler float X, Y, Z; 1643793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 r, g, b; 1644793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 1645793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew *= 3; 1646793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 1647793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = w; x-- > 0;) { 1648793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFCIELabToXYZ(img->cielab, 1649793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (unsigned char)pp[0], 1650793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (signed char)pp[1], 1651793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (signed char)pp[2], 1652793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler &X, &Y, &Z); 1653793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b); 1654793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = PACK(r, g, b); 1655793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += 3; 1656793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1657793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1658793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1659793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1660793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1661793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1662793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1663793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * YCbCr -> RGB conversion and packing routines. 1664793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1665793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1666793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define YCbCrtoRGB(dst, Y) { \ 1667793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 r, g, b; \ 1668793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \ 1669793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler dst = PACK(r, g, b); \ 1670793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1671793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1672793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1673793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed YCbCr samples => RGB 1674793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * This function is generic for different sampling sizes, 1675793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * and can handle blocks sizes that aren't multiples of the 1676793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * sampling size. However, it is substantially less optimized 1677793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * than the specific sampling cases. It is used as a fallback 1678793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * for difficult blocks. 1679793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1680793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef notdef 1681793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void putcontig8bitYCbCrGenericTile( 1682793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFRGBAImage* img, 1683793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* cp, 1684793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 x, uint32 y, 1685793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 w, uint32 h, 1686793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 fromskew, int32 toskew, 1687793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char* pp, 1688793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int h_group, 1689793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int v_group ) 1690793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1691793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1692793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* cp1 = cp+w+toskew; 1693793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* cp2 = cp1+w+toskew; 1694793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* cp3 = cp2+w+toskew; 1695793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 incr = 3*w+4*toskew; 1696793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cb, Cr; 1697793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int group_size = v_group * h_group + 2; 1698793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1699793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 1700793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew = (fromskew * group_size) / h_group; 1701793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1702793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( yy = 0; yy < h; yy++ ) 1703793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1704793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char *pp_line; 1705793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int y_line_group = yy / v_group; 1706793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int y_remainder = yy - y_line_group * v_group; 1707793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1708793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp_line = pp + v_line_group * 1709793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1710793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1711793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( xx = 0; xx < w; xx++ ) 1712793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1713793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Cb = pp 1714793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1715793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1716793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (; h >= 4; h -= 4) { 1717793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler x = w>>2; 1718793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 1719793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Cb = pp[16]; 1720793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Cr = pp[17]; 1721793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1722793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp [0], pp[ 0]); 1723793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp [1], pp[ 1]); 1724793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp [2], pp[ 2]); 1725793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp [3], pp[ 3]); 1726793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp1[0], pp[ 4]); 1727793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp1[1], pp[ 5]); 1728793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp1[2], pp[ 6]); 1729793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp1[3], pp[ 7]); 1730793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp2[0], pp[ 8]); 1731793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp2[1], pp[ 9]); 1732793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp2[2], pp[10]); 1733793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp2[3], pp[11]); 1734793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp3[0], pp[12]); 1735793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp3[1], pp[13]); 1736793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp3[2], pp[14]); 1737793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp3[3], pp[15]); 1738793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1739793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += 4, cp1 += 4, cp2 += 4, cp3 += 4; 1740793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += 18; 1741793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (--x); 1742793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += incr, cp1 += incr, cp2 += incr, cp3 += incr; 1743793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1744793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1745793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1746793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 1747793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1748793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1749793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB 1750793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1751793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putcontig8bitYCbCr44tile) 1752793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1753793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* cp1 = cp+w+toskew; 1754793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* cp2 = cp1+w+toskew; 1755793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* cp3 = cp2+w+toskew; 1756793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 incr = 3*w+4*toskew; 1757793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1758793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 1759793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* adjust fromskew */ 1760793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew = (fromskew * 18) / 4; 1761793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((h & 3) == 0 && (w & 3) == 0) { 1762793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (; h >= 4; h -= 4) { 1763793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler x = w>>2; 1764793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 1765793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cb = pp[16]; 1766793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cr = pp[17]; 1767793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1768793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp [0], pp[ 0]); 1769793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp [1], pp[ 1]); 1770793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp [2], pp[ 2]); 1771793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp [3], pp[ 3]); 1772793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp1[0], pp[ 4]); 1773793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp1[1], pp[ 5]); 1774793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp1[2], pp[ 6]); 1775793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp1[3], pp[ 7]); 1776793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp2[0], pp[ 8]); 1777793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp2[1], pp[ 9]); 1778793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp2[2], pp[10]); 1779793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp2[3], pp[11]); 1780793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp3[0], pp[12]); 1781793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp3[1], pp[13]); 1782793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp3[2], pp[14]); 1783793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp3[3], pp[15]); 1784793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1785793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += 4, cp1 += 4, cp2 += 4, cp3 += 4; 1786793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += 18; 1787793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (--x); 1788793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += incr, cp1 += incr, cp2 += incr, cp3 += incr; 1789793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1790793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1791793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 1792793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h > 0) { 1793793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = w; x > 0;) { 1794793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cb = pp[16]; 1795793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cr = pp[17]; 1796793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (x) { 1797793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 1798793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (h) { 1799793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */ 1800793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 3: YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */ 1801793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 2: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */ 1802793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */ 1803793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } /* FALLTHROUGH */ 1804793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 3: 1805793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (h) { 1806793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */ 1807793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 3: YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */ 1808793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 2: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */ 1809793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */ 1810793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } /* FALLTHROUGH */ 1811793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 2: 1812793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (h) { 1813793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */ 1814793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 3: YCbCrtoRGB(cp2[1], pp[ 9]); /* FALLTHROUGH */ 1815793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 2: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */ 1816793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */ 1817793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } /* FALLTHROUGH */ 1818793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: 1819793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (h) { 1820793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */ 1821793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 3: YCbCrtoRGB(cp2[0], pp[ 8]); /* FALLTHROUGH */ 1822793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 2: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */ 1823793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */ 1824793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } /* FALLTHROUGH */ 1825793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1826793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (x < 4) { 1827793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += x; cp1 += x; cp2 += x; cp3 += x; 1828793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler x = 0; 1829793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1830793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else { 1831793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += 4; cp1 += 4; cp2 += 4; cp3 += 4; 1832793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler x -= 4; 1833793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1834793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += 18; 1835793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1836793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (h <= 4) 1837793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1838793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler h -= 4; 1839793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += incr, cp1 += incr, cp2 += incr, cp3 += incr; 1840793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1841793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1842793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1843793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1844793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1845793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1846793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB 1847793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1848793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putcontig8bitYCbCr42tile) 1849793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1850793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* cp1 = cp+w+toskew; 1851793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 incr = 2*toskew+w; 1852793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1853793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 1854793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew = (fromskew * 10) / 4; 1855793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((h & 3) == 0 && (w & 1) == 0) { 1856793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (; h >= 2; h -= 2) { 1857793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler x = w>>2; 1858793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 1859793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cb = pp[8]; 1860793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cr = pp[9]; 1861793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1862793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp [0], pp[0]); 1863793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp [1], pp[1]); 1864793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp [2], pp[2]); 1865793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp [3], pp[3]); 1866793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp1[0], pp[4]); 1867793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp1[1], pp[5]); 1868793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp1[2], pp[6]); 1869793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp1[3], pp[7]); 1870793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1871793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += 4, cp1 += 4; 1872793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += 10; 1873793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (--x); 1874793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += incr, cp1 += incr; 1875793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1876793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1877793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 1878793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h > 0) { 1879793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = w; x > 0;) { 1880793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cb = pp[8]; 1881793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cr = pp[9]; 1882793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (x) { 1883793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 1884793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (h) { 1885793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */ 1886793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */ 1887793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } /* FALLTHROUGH */ 1888793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 3: 1889793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (h) { 1890793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */ 1891793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */ 1892793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } /* FALLTHROUGH */ 1893793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 2: 1894793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (h) { 1895793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */ 1896793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */ 1897793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } /* FALLTHROUGH */ 1898793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: 1899793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (h) { 1900793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */ 1901793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */ 1902793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } /* FALLTHROUGH */ 1903793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1904793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (x < 4) { 1905793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += x; cp1 += x; 1906793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler x = 0; 1907793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1908793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else { 1909793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += 4; cp1 += 4; 1910793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler x -= 4; 1911793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1912793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += 10; 1913793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1914793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (h <= 2) 1915793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1916793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler h -= 2; 1917793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += incr, cp1 += incr; 1918793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1919793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1920793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1921793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1922793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1923793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1924793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB 1925793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1926793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putcontig8bitYCbCr41tile) 1927793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1928793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 1929793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* XXX adjust fromskew */ 1930793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 1931793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler x = w>>2; 1932793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 1933793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cb = pp[4]; 1934793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cr = pp[5]; 1935793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1936793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp [0], pp[0]); 1937793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp [1], pp[1]); 1938793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp [2], pp[2]); 1939793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp [3], pp[3]); 1940793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1941793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += 4; 1942793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += 6; 1943793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (--x); 1944793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1945793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( (w&3) != 0 ) 1946793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1947793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cb = pp[4]; 1948793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cr = pp[5]; 1949793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1950793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch( (w&3) ) { 1951793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 3: YCbCrtoRGB(cp [2], pp[2]); 1952793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 2: YCbCrtoRGB(cp [1], pp[1]); 1953793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: YCbCrtoRGB(cp [0], pp[0]); 1954793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 0: break; 1955793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1956793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1957793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += (w&3); 1958793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += 6; 1959793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1960793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1961793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 1962793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 1963793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (--h); 1964793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1965793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1966793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1967793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1968793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB 1969793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1970793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putcontig8bitYCbCr22tile) 1971793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1972793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* cp2; 1973793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 incr = 2*toskew+w; 1974793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 1975793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew = (fromskew / 2) * 6; 1976793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp2 = cp+w+toskew; 1977793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h>=2) { 1978793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler x = w; 1979793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (x>=2) { 1980793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 Cb = pp[4]; 1981793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 Cr = pp[5]; 1982793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp[0], pp[0]); 1983793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp[1], pp[1]); 1984793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp2[0], pp[2]); 1985793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp2[1], pp[3]); 1986793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += 2; 1987793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp2 += 2; 1988793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += 6; 1989793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler x -= 2; 1990793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1991793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (x==1) { 1992793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 Cb = pp[4]; 1993793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 Cr = pp[5]; 1994793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp[0], pp[0]); 1995793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp2[0], pp[2]); 1996793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp ++ ; 1997793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp2 ++ ; 1998793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += 6; 1999793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2000793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += incr; 2001793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp2 += incr; 2002793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 2003793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler h-=2; 2004793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2005793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (h==1) { 2006793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler x = w; 2007793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (x>=2) { 2008793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 Cb = pp[4]; 2009793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 Cr = pp[5]; 2010793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp[0], pp[0]); 2011793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp[1], pp[1]); 2012793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += 2; 2013793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp2 += 2; 2014793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += 6; 2015793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler x -= 2; 2016793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2017793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (x==1) { 2018793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 Cb = pp[4]; 2019793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 Cr = pp[5]; 2020793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp[0], pp[0]); 2021793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2022793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2023793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2024793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2025793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 2026793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB 2027793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2028793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putcontig8bitYCbCr21tile) 2029793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 2030793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 2031793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew = (fromskew * 4) / 2; 2032793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 2033793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler x = w>>1; 2034793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 2035793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cb = pp[2]; 2036793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cr = pp[3]; 2037793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2038793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp[0], pp[0]); 2039793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp[1], pp[1]); 2040793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2041793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += 2; 2042793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += 4; 2043793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (--x); 2044793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2045793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( (w&1) != 0 ) 2046793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2047793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cb = pp[2]; 2048793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cr = pp[3]; 2049793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2050793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp[0], pp[0]); 2051793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2052793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += 1; 2053793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += 4; 2054793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2055793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2056793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 2057793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 2058793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (--h); 2059793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2060793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2061793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 2062793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB 2063793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2064793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putcontig8bitYCbCr12tile) 2065793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 2066793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* cp2; 2067793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 incr = 2*toskew+w; 2068793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 2069793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew = (fromskew / 2) * 4; 2070793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp2 = cp+w+toskew; 2071793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h>=2) { 2072793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler x = w; 2073793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 2074793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 Cb = pp[2]; 2075793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 Cr = pp[3]; 2076793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp[0], pp[0]); 2077793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp2[0], pp[1]); 2078793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp ++; 2079793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp2 ++; 2080793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += 4; 2081793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (--x); 2082793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += incr; 2083793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp2 += incr; 2084793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 2085793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler h-=2; 2086793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2087793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (h==1) { 2088793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler x = w; 2089793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 2090793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 Cb = pp[2]; 2091793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 Cr = pp[3]; 2092793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(cp[0], pp[0]); 2093793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp ++; 2094793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += 4; 2095793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (--x); 2096793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2097793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2098793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2099793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 2100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed YCbCr samples w/ no subsampling => RGB 2101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2102793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putcontig8bitYCbCr11tile) 2103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 2104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 2105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fromskew *= 3; 2106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 2107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */ 2108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 2109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cb = pp[1]; 2110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 Cr = pp[2]; 2111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler YCbCrtoRGB(*cp++, pp[0]); 2113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += 3; 2115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (--x); 2116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 2117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pp += fromskew; 2118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (--h); 2119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 2122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed YCbCr samples w/ no subsampling => RGB 2123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2124793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLARESepPutFunc(putseparate8bitYCbCr11tile) 2125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 2126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) y; 2127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (void) a; 2128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */ 2129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (h-- > 0) { 2130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler x = w; 2131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 2132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 dr, dg, db; 2133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFYCbCrtoRGB(img->ycbcr,*r++,*g++,*b++,&dr,&dg,&db); 2134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *cp++ = PACK(dr,dg,db); 2135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (--x); 2136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler SKEW(r, g, b, fromskew); 2137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cp += toskew; 2138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#undef YCbCrtoRGB 2141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int 2143793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerinitYCbCrConversion(TIFFRGBAImage* img) 2144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 2145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler static const char module[] = "initYCbCrConversion"; 2146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler float *luma, *refBlackWhite; 2148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->ycbcr == NULL) { 2150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc( 2151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long)) 2152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler + 4*256*sizeof (TIFFRGBValue) 2153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler + 2*256*sizeof (int) 2154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler + 3*256*sizeof (int32) 2155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ); 2156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->ycbcr == NULL) { 2157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(img->tif->tif_clientdata, module, 2158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "No space for YCbCr->RGB conversion state"); 2159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 2160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma); 2164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE, 2165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler &refBlackWhite); 2166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0) 2167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return(0); 2168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (1); 2169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic tileContigRoutine 2172793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerinitCIELabConversion(TIFFRGBAImage* img) 2173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 2174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler static const char module[] = "initCIELabConversion"; 2175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler float *whitePoint; 2177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler float refWhite[3]; 2178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!img->cielab) { 2180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->cielab = (TIFFCIELabToRGB *) 2181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFmalloc(sizeof(TIFFCIELabToRGB)); 2182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!img->cielab) { 2183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(img->tif->tif_clientdata, module, 2184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "No space for CIE L*a*b*->RGB conversion state."); 2185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return NULL; 2186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint); 2190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler refWhite[1] = 100.0F; 2191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1]; 2192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1]) 2193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler / whitePoint[1] * refWhite[1]; 2194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) { 2195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(img->tif->tif_clientdata, module, 2196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Failed to initialize CIE L*a*b*->RGB conversion state."); 2197793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree(img->cielab); 2198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return NULL; 2199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return putcontig8bitCIELab; 2202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 2205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Greyscale images with less than 8 bits/sample are handled 2206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * with a table to avoid lots of shifts and masks. The table 2207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * is setup so that put*bwtile (below) can retrieve 8/bitspersample 2208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * pixel values simply by indexing into the table with one 2209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * number. 2210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int 2212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslermakebwmap(TIFFRGBAImage* img) 2213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 2214793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFRGBValue* Map = img->Map; 2215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int bitspersample = img->bitspersample; 2216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int nsamples = 8 / bitspersample; 2217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int i; 2218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32* p; 2219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( nsamples == 0 ) 2221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler nsamples = 1; 2222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->BWmap = (uint32**) _TIFFmalloc( 2224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32))); 2225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->BWmap == NULL) { 2226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for B&W mapping table"); 2227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 2228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler p = (uint32*)(img->BWmap + 256); 2230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (i = 0; i < 256; i++) { 2231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFRGBValue c; 2232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->BWmap[i] = p; 2233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (bitspersample) { 2234793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define GREY(x) c = Map[x]; *p++ = PACK(c,c,c); 2235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: 2236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler GREY(i>>7); 2237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler GREY((i>>6)&1); 2238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler GREY((i>>5)&1); 2239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler GREY((i>>4)&1); 2240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler GREY((i>>3)&1); 2241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler GREY((i>>2)&1); 2242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler GREY((i>>1)&1); 2243793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler GREY(i&1); 2244793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 2: 2246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler GREY(i>>6); 2247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler GREY((i>>4)&3); 2248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler GREY((i>>2)&3); 2249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler GREY(i&3); 2250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 4: 2252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler GREY(i>>4); 2253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler GREY(i&0xf); 2254793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 8: 2256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 16: 2257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler GREY(i); 2258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2259793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#undef GREY 2261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (1); 2263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 2266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Construct a mapping table to convert from the range 2267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * of the data samples to [0,255] --for display. This 2268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * process also handles inverting B&W images when needed. 2269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2270793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int 2271793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslersetupMap(TIFFRGBAImage* img) 2272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 2273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int32 x, range; 2274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler range = (int32)((1L<<img->bitspersample)-1); 2276793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* treat 16 bit the same as eight bit */ 2278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( img->bitspersample == 16 ) 2279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler range = (int32) 255; 2280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue)); 2282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->Map == NULL) { 2283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), 2284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "No space for photometric conversion table"); 2285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 2286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->photometric == PHOTOMETRIC_MINISWHITE) { 2288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = 0; x <= range; x++) 2289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range); 2290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 2291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (x = 0; x <= range; x++) 2292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->Map[x] = (TIFFRGBValue) ((x * 255) / range); 2293793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2294793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->bitspersample <= 16 && 2295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (img->photometric == PHOTOMETRIC_MINISBLACK || 2296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->photometric == PHOTOMETRIC_MINISWHITE)) { 2297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* 2298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Use photometric mapping table to construct 2299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * unpacking tables for samples <= 8 bits. 2300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!makebwmap(img)) 2302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 2303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* no longer need Map, free it */ 2304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFfree(img->Map), img->Map = NULL; 2305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (1); 2307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2308793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int 2310793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslercheckcmap(TIFFRGBAImage* img) 2311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 2312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16* r = img->redcmap; 2313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16* g = img->greencmap; 2314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16* b = img->bluecmap; 2315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler long n = 1L<<img->bitspersample; 2316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (n-- > 0) 2318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) 2319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (16); 2320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (8); 2321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void 2324793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslercvtcmap(TIFFRGBAImage* img) 2325793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 2326793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16* r = img->redcmap; 2327793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16* g = img->greencmap; 2328793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16* b = img->bluecmap; 2329793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler long i; 2330793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2331793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (i = (1L<<img->bitspersample)-1; i >= 0; i--) { 2332793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define CVT(x) ((uint16)((x)>>8)) 2333793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler r[i] = CVT(r[i]); 2334793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler g[i] = CVT(g[i]); 2335793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler b[i] = CVT(b[i]); 2336793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#undef CVT 2337793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2338793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2339793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2340793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 2341793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Palette images with <= 8 bits/sample are handled 2342793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * with a table to avoid lots of shifts and masks. The table 2343793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * is setup so that put*cmaptile (below) can retrieve 8/bitspersample 2344793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * pixel values simply by indexing into the table with one 2345793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * number. 2346793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2347793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int 2348793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslermakecmap(TIFFRGBAImage* img) 2349793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 2350793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int bitspersample = img->bitspersample; 2351793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int nsamples = 8 / bitspersample; 2352793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16* r = img->redcmap; 2353793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16* g = img->greencmap; 2354793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16* b = img->bluecmap; 2355793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 *p; 2356793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int i; 2357793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2358793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->PALmap = (uint32**) _TIFFmalloc( 2359793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32))); 2360793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->PALmap == NULL) { 2361793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for Palette mapping table"); 2362793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 2363793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2364793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler p = (uint32*)(img->PALmap + 256); 2365793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (i = 0; i < 256; i++) { 2366793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFRGBValue c; 2367793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->PALmap[i] = p; 2368793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff); 2369793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (bitspersample) { 2370793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: 2371793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CMAP(i>>7); 2372793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CMAP((i>>6)&1); 2373793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CMAP((i>>5)&1); 2374793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CMAP((i>>4)&1); 2375793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CMAP((i>>3)&1); 2376793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CMAP((i>>2)&1); 2377793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CMAP((i>>1)&1); 2378793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CMAP(i&1); 2379793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2380793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 2: 2381793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CMAP(i>>6); 2382793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CMAP((i>>4)&3); 2383793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CMAP((i>>2)&3); 2384793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CMAP(i&3); 2385793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2386793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 4: 2387793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CMAP(i>>4); 2388793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CMAP(i&0xf); 2389793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2390793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 8: 2391793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CMAP(i); 2392793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2393793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2394793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#undef CMAP 2395793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2396793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (1); 2397793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2398793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2399793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 2400793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Construct any mapping table used 2401793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * by the associated put routine. 2402793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2403793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int 2404793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerbuildMap(TIFFRGBAImage* img) 2405793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 2406793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (img->photometric) { 2407793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_RGB: 2408793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_YCBCR: 2409793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_SEPARATED: 2410793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->bitspersample == 8) 2411793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2412793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* fall thru... */ 2413793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_MINISBLACK: 2414793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_MINISWHITE: 2415793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!setupMap(img)) 2416793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 2417793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2418793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_PALETTE: 2419793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* 2420793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Convert 16-bit colormap to 8-bit (unless it looks 2421793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * like an old-style 8-bit colormap). 2422793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2423793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (checkcmap(img) == 16) 2424793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cvtcmap(img); 2425793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 2426793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFWarningExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "Assuming 8-bit colormap"); 2427793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* 2428793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Use mapping table and colormap to construct 2429793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * unpacking tables for samples < 8 bits. 2430793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2431793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->bitspersample <= 8 && !makecmap(img)) 2432793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 2433793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2434793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2435793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (1); 2436793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2437793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2438793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 2439793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Select the appropriate conversion routine for packed data. 2440793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2441793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int 2442793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerPickContigCase(TIFFRGBAImage* img) 2443793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 2444793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig; 2445793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = NULL; 2446793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (img->photometric) { 2447793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_RGB: 2448793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (img->bitspersample) { 2449793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 8: 2450793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->alpha == EXTRASAMPLE_ASSOCALPHA) 2451793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = putRGBAAcontig8bittile; 2452793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (img->alpha == EXTRASAMPLE_UNASSALPHA) 2453793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2454793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (BuildMapUaToAa(img)) 2455793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = putRGBUAcontig8bittile; 2456793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2457793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 2458793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = putRGBcontig8bittile; 2459793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2460793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 16: 2461793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->alpha == EXTRASAMPLE_ASSOCALPHA) 2462793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2463793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (BuildMapBitdepth16To8(img)) 2464793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = putRGBAAcontig16bittile; 2465793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2466793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (img->alpha == EXTRASAMPLE_UNASSALPHA) 2467793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2468793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (BuildMapBitdepth16To8(img) && 2469793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler BuildMapUaToAa(img)) 2470793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = putRGBUAcontig16bittile; 2471793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2472793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 2473793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2474793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (BuildMapBitdepth16To8(img)) 2475793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = putRGBcontig16bittile; 2476793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2477793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2478793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2479793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2480793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_SEPARATED: 2481793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (buildMap(img)) { 2482793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->bitspersample == 8) { 2483793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!img->Map) 2484793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = putRGBcontig8bitCMYKtile; 2485793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 2486793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = putRGBcontig8bitCMYKMaptile; 2487793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2488793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2489793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2490793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_PALETTE: 2491793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (buildMap(img)) { 2492793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (img->bitspersample) { 2493793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 8: 2494793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = put8bitcmaptile; 2495793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2496793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 4: 2497793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = put4bitcmaptile; 2498793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2499793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 2: 2500793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = put2bitcmaptile; 2501793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2502793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: 2503793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = put1bitcmaptile; 2504793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2505793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2506793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2507793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2508793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_MINISWHITE: 2509793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_MINISBLACK: 2510793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (buildMap(img)) { 2511793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (img->bitspersample) { 2512793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 16: 2513793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = put16bitbwtile; 2514793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2515793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 8: 2516793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->alpha && img->samplesperpixel == 2) 2517793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = putagreytile; 2518793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 2519793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = putgreytile; 2520793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2521793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 4: 2522793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = put4bitbwtile; 2523793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2524793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 2: 2525793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = put2bitbwtile; 2526793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2527793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: 2528793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = put1bitbwtile; 2529793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2530793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2531793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2532793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2533793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_YCBCR: 2534793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((img->bitspersample==8) && (img->samplesperpixel==3)) 2535793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2536793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (initYCbCrConversion(img)!=0) 2537793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2538793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* 2539793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * The 6.0 spec says that subsampling must be 2540793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * one of 1, 2, or 4, and that vertical subsampling 2541793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * must always be <= horizontal subsampling; so 2542793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * there are only a few possibilities and we just 2543793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * enumerate the cases. 2544793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Joris: added support for the [1,2] case, nonetheless, to accomodate 2545793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * some OJPEG files 2546793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2547793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 SubsamplingHor; 2548793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 SubsamplingVer; 2549793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &SubsamplingHor, &SubsamplingVer); 2550793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch ((SubsamplingHor<<4)|SubsamplingVer) { 2551793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 0x44: 2552793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = putcontig8bitYCbCr44tile; 2553793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2554793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 0x42: 2555793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = putcontig8bitYCbCr42tile; 2556793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2557793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 0x41: 2558793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = putcontig8bitYCbCr41tile; 2559793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2560793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 0x22: 2561793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = putcontig8bitYCbCr22tile; 2562793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2563793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 0x21: 2564793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = putcontig8bitYCbCr21tile; 2565793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2566793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 0x12: 2567793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = putcontig8bitYCbCr12tile; 2568793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2569793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 0x11: 2570793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = putcontig8bitYCbCr11tile; 2571793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2572793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2573793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2574793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2575793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2576793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_CIELAB: 2577793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (buildMap(img)) { 2578793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->bitspersample == 8) 2579793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.contig = initCIELabConversion(img); 2580793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2581793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2582793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2583793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return ((img->get!=NULL) && (img->put.contig!=NULL)); 2584793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2585793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2586793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 2587793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Select the appropriate conversion routine for unpacked data. 2588793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 2589793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * NB: we assume that unpacked single channel data is directed 2590793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * to the "packed routines. 2591793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2592793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int 2593793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerPickSeparateCase(TIFFRGBAImage* img) 2594793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 2595793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate; 2596793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.separate = NULL; 2597793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (img->photometric) { 2598793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_MINISWHITE: 2599793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_MINISBLACK: 2600793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* greyscale images processed pretty much as RGB by gtTileSeparate */ 2601793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_RGB: 2602793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (img->bitspersample) { 2603793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 8: 2604793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->alpha == EXTRASAMPLE_ASSOCALPHA) 2605793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.separate = putRGBAAseparate8bittile; 2606793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (img->alpha == EXTRASAMPLE_UNASSALPHA) 2607793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2608793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (BuildMapUaToAa(img)) 2609793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.separate = putRGBUAseparate8bittile; 2610793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2611793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 2612793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.separate = putRGBseparate8bittile; 2613793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2614793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 16: 2615793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->alpha == EXTRASAMPLE_ASSOCALPHA) 2616793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2617793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (BuildMapBitdepth16To8(img)) 2618793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.separate = putRGBAAseparate16bittile; 2619793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2620793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (img->alpha == EXTRASAMPLE_UNASSALPHA) 2621793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2622793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (BuildMapBitdepth16To8(img) && 2623793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler BuildMapUaToAa(img)) 2624793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.separate = putRGBUAseparate16bittile; 2625793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2626793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 2627793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2628793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (BuildMapBitdepth16To8(img)) 2629793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.separate = putRGBseparate16bittile; 2630793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2631793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2632793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2633793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2634793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_SEPARATED: 2635793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->bitspersample == 8 && img->samplesperpixel == 4) 2636793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2637793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->alpha = 1; // Not alpha, but seems like the only way to get 4th band 2638793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.separate = putCMYKseparate8bittile; 2639793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2640793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2641793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case PHOTOMETRIC_YCBCR: 2642793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((img->bitspersample==8) && (img->samplesperpixel==3)) 2643793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2644793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (initYCbCrConversion(img)!=0) 2645793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2646793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 hs, vs; 2647793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs); 2648793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch ((hs<<4)|vs) { 2649793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 0x11: 2650793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->put.separate = putseparate8bitYCbCr11tile; 2651793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2652793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* TODO: add other cases here */ 2653793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2654793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2655793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2656793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 2657793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2658793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return ((img->get!=NULL) && (img->put.separate!=NULL)); 2659793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2660793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2661793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int 2662793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerBuildMapUaToAa(TIFFRGBAImage* img) 2663793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 2664793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler static const char module[]="BuildMapUaToAa"; 2665793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint8* m; 2666793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint16 na,nv; 2667793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler assert(img->UaToAa==NULL); 2668793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->UaToAa=_TIFFmalloc(65536); 2669793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->UaToAa==NULL) 2670793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2671793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory"); 2672793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return(0); 2673793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2674793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler m=img->UaToAa; 2675793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (na=0; na<256; na++) 2676793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2677793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (nv=0; nv<256; nv++) 2678793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *m++=(nv*na+127)/255; 2679793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2680793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return(1); 2681793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2682793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2683793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int 2684793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerBuildMapBitdepth16To8(TIFFRGBAImage* img) 2685793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 2686793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler static const char module[]="BuildMapBitdepth16To8"; 2687793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint8* m; 2688793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 n; 2689793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler assert(img->Bitdepth16To8==NULL); 2690793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img->Bitdepth16To8=_TIFFmalloc(65536); 2691793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (img->Bitdepth16To8==NULL) 2692793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2693793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory"); 2694793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return(0); 2695793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2696793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler m=img->Bitdepth16To8; 2697793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (n=0; n<65536; n++) 2698793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *m++=(n+128)/257; 2699793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return(1); 2700793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2701793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2702793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2703793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 2704793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Read a whole strip off data from the file, and convert to RGBA form. 2705793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * If this is the last strip, then it will only contain the portion of 2706793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * the strip that is actually within the image space. The result is 2707793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * organized in bottom to top form. 2708793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2709793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2710793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2711793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint 2712793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster ) 2713793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2714793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 2715793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler char emsg[1024] = ""; 2716793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFRGBAImage img; 2717793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int ok; 2718793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 rowsperstrip, rows_to_read; 2719793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2720793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( TIFFIsTiled( tif ) ) 2721793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2722793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), 2723793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Can't use TIFFReadRGBAStrip() with tiled file."); 2724793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 2725793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2726793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2727793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); 2728793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( (row % rowsperstrip) != 0 ) 2729793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2730793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), 2731793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Row passed to TIFFReadRGBAStrip() must be first in a strip."); 2732793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 2733793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2734793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2735793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, 0, emsg)) { 2736793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2737793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img.row_offset = row; 2738793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img.col_offset = 0; 2739793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2740793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( row + rowsperstrip > img.height ) 2741793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler rows_to_read = img.height - row; 2742793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 2743793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler rows_to_read = rowsperstrip; 2744793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2745793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read ); 2746793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2747793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFRGBAImageEnd(&img); 2748793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } else { 2749793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg); 2750793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ok = 0; 2751793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2752793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2753793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (ok); 2754793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2755793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2756793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 2757793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Read a whole tile off data from the file, and convert to RGBA form. 2758793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * The returned RGBA data is organized from bottom to top of tile, 2759793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * and may include zeroed areas if the tile extends off the image. 2760793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2761793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2762793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint 2763793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster) 2764793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2765793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 2766793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler char emsg[1024] = ""; 2767793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFRGBAImage img; 2768793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int ok; 2769793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 tile_xsize, tile_ysize; 2770793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 read_xsize, read_ysize; 2771793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler uint32 i_row; 2772793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2773793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* 2774793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Verify that our request is legal - on a tile file, and on a 2775793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * tile boundary. 2776793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2777793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2778793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( !TIFFIsTiled( tif ) ) 2779793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2780793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), 2781793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Can't use TIFFReadRGBATile() with stripped file."); 2782793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 2783793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2784793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2785793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize); 2786793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize); 2787793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 ) 2788793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 2789793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), 2790793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Row/col passed to TIFFReadRGBATile() must be top" 2791793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "left corner of a tile."); 2792793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (0); 2793793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2794793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2795793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* 2796793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Setup the RGBA reader. 2797793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2798793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2799793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!TIFFRGBAImageOK(tif, emsg) 2800793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler || !TIFFRGBAImageBegin(&img, tif, 0, emsg)) { 2801793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg); 2802793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return( 0 ); 2803793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2804793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2805793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* 2806793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * The TIFFRGBAImageGet() function doesn't allow us to get off the 2807793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * edge of the image, even to fill an otherwise valid tile. So we 2808793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * figure out how much we can read, and fix up the tile buffer to 2809793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * a full tile configuration afterwards. 2810793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2811793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2812793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( row + tile_ysize > img.height ) 2813793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler read_ysize = img.height - row; 2814793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 2815793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler read_ysize = tile_ysize; 2816793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2817793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( col + tile_xsize > img.width ) 2818793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler read_xsize = img.width - col; 2819793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 2820793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler read_xsize = tile_xsize; 2821793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2822793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* 2823793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Read the chunk of imagery. 2824793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2825793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2826793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img.row_offset = row; 2827793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler img.col_offset = col; 2828793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2829793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize ); 2830793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2831793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler TIFFRGBAImageEnd(&img); 2832793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2833793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* 2834793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * If our read was incomplete we will need to fix up the tile by 2835793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * shifting the data around as if a full tile of data is being returned. 2836793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 2837793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * This is all the more complicated because the image is organized in 2838793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * bottom to top format. 2839793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2840793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2841793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( read_xsize == tile_xsize && read_ysize == tile_ysize ) 2842793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return( ok ); 2843793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2844793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( i_row = 0; i_row < read_ysize; i_row++ ) { 2845793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler memmove( raster + (tile_ysize - i_row - 1) * tile_xsize, 2846793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler raster + (read_ysize - i_row - 1) * read_xsize, 2847793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler read_xsize * sizeof(uint32) ); 2848793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize, 2849793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 0, sizeof(uint32) * (tile_xsize - read_xsize) ); 2850793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2851793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2852793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) { 2853793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize, 2854793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 0, sizeof(uint32) * tile_xsize ); 2855793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 2856793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2857793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (ok); 2858793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 2859793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 2860793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* vim: set ts=8 sts=8 sw=8 noet: */ 2861793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 2862793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Local Variables: 2863793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * mode: c 2864793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * c-basic-offset: 8 2865793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * fill-column: 78 2866793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * End: 2867793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 2868