| 1 | 
greg | 
3.1 | 
#ifndef lint | 
| 2 | 
greg | 
3.11 | 
static const char       RCSid[] = "$Id: tmaptiff.c,v 3.10 2011/05/20 02:06:38 greg Exp $"; | 
| 3 | 
greg | 
3.1 | 
#endif | 
| 4 | 
  | 
  | 
/* | 
| 5 | 
  | 
  | 
 * Perform tone mapping on TIFF input. | 
| 6 | 
  | 
  | 
 * | 
| 7 | 
  | 
  | 
 * Externals declared in tmaptiff.h | 
| 8 | 
  | 
  | 
 */ | 
| 9 | 
  | 
  | 
 | 
| 10 | 
greg | 
3.2 | 
#include "copyright.h" | 
| 11 | 
greg | 
3.1 | 
 | 
| 12 | 
  | 
  | 
#include <stdio.h> | 
| 13 | 
greg | 
3.8 | 
#include <stdlib.h> | 
| 14 | 
greg | 
3.9 | 
#include "tiffio.h" | 
| 15 | 
greg | 
3.7 | 
#include "tmprivat.h" | 
| 16 | 
greg | 
3.1 | 
#include "tmaptiff.h" | 
| 17 | 
  | 
  | 
 | 
| 18 | 
greg | 
3.3 | 
                                        /* input cases we handle */ | 
| 19 | 
  | 
  | 
#define TC_LOGLUV32     1 | 
| 20 | 
  | 
  | 
#define TC_LOGLUV24     2 | 
| 21 | 
  | 
  | 
#define TC_LOGL16       3 | 
| 22 | 
  | 
  | 
#define TC_GRYFLOAT     4 | 
| 23 | 
  | 
  | 
#define TC_RGBFLOAT     5 | 
| 24 | 
  | 
  | 
#define TC_GRYSHORT     6 | 
| 25 | 
  | 
  | 
#define TC_RGBSHORT     7 | 
| 26 | 
  | 
  | 
 | 
| 27 | 
  | 
  | 
/* figure out what kind of TIFF we have and if we can tone-map it */ | 
| 28 | 
  | 
  | 
static int | 
| 29 | 
  | 
  | 
getTIFFtype(TIFF *tif) | 
| 30 | 
  | 
  | 
{ | 
| 31 | 
  | 
  | 
        uint16  comp, phot, pconf; | 
| 32 | 
  | 
  | 
        uint16  samp_fmt, bits_samp; | 
| 33 | 
  | 
  | 
         | 
| 34 | 
  | 
  | 
        TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &pconf); | 
| 35 | 
  | 
  | 
        if (pconf != PLANARCONFIG_CONTIG) | 
| 36 | 
  | 
  | 
                return(0); | 
| 37 | 
  | 
  | 
        TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &phot); | 
| 38 | 
  | 
  | 
        TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &comp); | 
| 39 | 
  | 
  | 
        TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLEFORMAT, &samp_fmt); | 
| 40 | 
  | 
  | 
        TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bits_samp); | 
| 41 | 
  | 
  | 
        switch (phot) { | 
| 42 | 
  | 
  | 
        case PHOTOMETRIC_LOGLUV: | 
| 43 | 
  | 
  | 
                if (comp == COMPRESSION_SGILOG) | 
| 44 | 
  | 
  | 
                        return(TC_LOGLUV32); | 
| 45 | 
  | 
  | 
                if (comp == COMPRESSION_SGILOG24) | 
| 46 | 
  | 
  | 
                        return(TC_LOGLUV24); | 
| 47 | 
  | 
  | 
                return(0); | 
| 48 | 
  | 
  | 
        case PHOTOMETRIC_LOGL: | 
| 49 | 
  | 
  | 
                if (comp == COMPRESSION_SGILOG) | 
| 50 | 
  | 
  | 
                        return(TC_LOGL16); | 
| 51 | 
  | 
  | 
                return(0); | 
| 52 | 
  | 
  | 
        case PHOTOMETRIC_MINISBLACK: | 
| 53 | 
  | 
  | 
                if (samp_fmt == SAMPLEFORMAT_UINT) { | 
| 54 | 
  | 
  | 
                        if (bits_samp == 16) | 
| 55 | 
  | 
  | 
                                return(TC_GRYSHORT); | 
| 56 | 
  | 
  | 
                        return(0); | 
| 57 | 
  | 
  | 
                } | 
| 58 | 
  | 
  | 
                if (samp_fmt == SAMPLEFORMAT_IEEEFP) { | 
| 59 | 
  | 
  | 
                        if (bits_samp == 8*sizeof(float)) | 
| 60 | 
  | 
  | 
                                return(TC_GRYFLOAT); | 
| 61 | 
  | 
  | 
                        return(0); | 
| 62 | 
  | 
  | 
                } | 
| 63 | 
  | 
  | 
                return(0); | 
| 64 | 
  | 
  | 
        case PHOTOMETRIC_RGB: | 
| 65 | 
  | 
  | 
                if (samp_fmt == SAMPLEFORMAT_UINT) { | 
| 66 | 
  | 
  | 
                        if (bits_samp == 16) | 
| 67 | 
  | 
  | 
                                return(TC_RGBSHORT); | 
| 68 | 
  | 
  | 
                        return(0); | 
| 69 | 
  | 
  | 
                } | 
| 70 | 
  | 
  | 
                if (samp_fmt == SAMPLEFORMAT_IEEEFP) { | 
| 71 | 
  | 
  | 
                        if (bits_samp == 8*sizeof(float)) | 
| 72 | 
  | 
  | 
                                return(TC_RGBFLOAT); | 
| 73 | 
  | 
  | 
                        return(0); | 
| 74 | 
  | 
  | 
                } | 
| 75 | 
  | 
  | 
                return(0); | 
| 76 | 
  | 
  | 
        } | 
| 77 | 
  | 
  | 
        return(0); | 
| 78 | 
  | 
  | 
} | 
| 79 | 
greg | 
3.1 | 
 | 
| 80 | 
greg | 
3.3 | 
/* load and convert TIFF */ | 
| 81 | 
greg | 
3.1 | 
int | 
| 82 | 
greg | 
3.10 | 
tmLoadTIFF(TMstruct *tms, TMbright **lpp, uby8 **cpp, | 
| 83 | 
greg | 
3.5 | 
                int *xp, int *yp, char *fname, TIFF *tp) | 
| 84 | 
greg | 
3.1 | 
{ | 
| 85 | 
  | 
  | 
        char    *funcName = fname==NULL ? "tmLoadTIFF" : fname; | 
| 86 | 
greg | 
3.5 | 
        RGBPRIMP        inppri = tms->monpri; | 
| 87 | 
greg | 
3.3 | 
        RGBPRIMS        myprims; | 
| 88 | 
  | 
  | 
        float   *fa; | 
| 89 | 
greg | 
3.1 | 
        TIFF    *tif; | 
| 90 | 
  | 
  | 
        int     err; | 
| 91 | 
greg | 
3.3 | 
        union {uint16 *w; uint32 *l; float *f; MEM_PTR p;} sl; | 
| 92 | 
greg | 
3.1 | 
        uint32  width, height; | 
| 93 | 
greg | 
3.3 | 
        int     tcase; | 
| 94 | 
greg | 
3.1 | 
        double  stonits; | 
| 95 | 
  | 
  | 
        int     y; | 
| 96 | 
  | 
  | 
                                        /* check arguments */ | 
| 97 | 
greg | 
3.5 | 
        if (tms == NULL) | 
| 98 | 
greg | 
3.1 | 
                returnErr(TM_E_TMINVAL); | 
| 99 | 
schorsch | 
3.4 | 
        if ((lpp == NULL) | (xp == NULL) | (yp == NULL) | | 
| 100 | 
  | 
  | 
                        ((fname == NULL) & (tp == NULL))) | 
| 101 | 
greg | 
3.1 | 
                returnErr(TM_E_ILLEGAL); | 
| 102 | 
  | 
  | 
                                        /* check/get TIFF tags */ | 
| 103 | 
  | 
  | 
        sl.p = NULL; *lpp = NULL; | 
| 104 | 
  | 
  | 
        if (cpp != TM_NOCHROMP) *cpp = TM_NOCHROM; | 
| 105 | 
  | 
  | 
        err = TM_E_BADFILE; | 
| 106 | 
  | 
  | 
        if ((tif = tp) == NULL && (tif = TIFFOpen(fname, "r")) == NULL) | 
| 107 | 
  | 
  | 
                returnErr(TM_E_BADFILE); | 
| 108 | 
greg | 
3.3 | 
        tcase = getTIFFtype(tif); | 
| 109 | 
  | 
  | 
        if (!tcase) | 
| 110 | 
  | 
  | 
                goto done; | 
| 111 | 
greg | 
3.1 | 
        if (!TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width) || | 
| 112 | 
  | 
  | 
                        !TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height)) | 
| 113 | 
  | 
  | 
                goto done; | 
| 114 | 
  | 
  | 
        *xp = width; *yp = height; | 
| 115 | 
greg | 
3.3 | 
        if (TIFFGetField(tif, TIFFTAG_PRIMARYCHROMATICITIES, &fa)) { | 
| 116 | 
  | 
  | 
                myprims[RED][CIEX] = fa[0]; | 
| 117 | 
  | 
  | 
                myprims[RED][CIEY] = fa[1]; | 
| 118 | 
  | 
  | 
                myprims[GRN][CIEX] = fa[2]; | 
| 119 | 
  | 
  | 
                myprims[GRN][CIEY] = fa[3]; | 
| 120 | 
  | 
  | 
                myprims[BLU][CIEX] = fa[4]; | 
| 121 | 
  | 
  | 
                myprims[BLU][CIEY] = fa[5]; | 
| 122 | 
  | 
  | 
                myprims[WHT][CIEX] = 1./3.; | 
| 123 | 
  | 
  | 
                myprims[WHT][CIEY] = 1./3.; | 
| 124 | 
  | 
  | 
                if (TIFFGetField(tif, TIFFTAG_WHITEPOINT, &fa)) { | 
| 125 | 
  | 
  | 
                        myprims[WHT][CIEX] = fa[0]; | 
| 126 | 
  | 
  | 
                        myprims[WHT][CIEY] = fa[1]; | 
| 127 | 
  | 
  | 
                } | 
| 128 | 
  | 
  | 
                inppri = myprims; | 
| 129 | 
  | 
  | 
        } | 
| 130 | 
greg | 
3.1 | 
        if (!TIFFGetField(tif, TIFFTAG_STONITS, &stonits)) | 
| 131 | 
  | 
  | 
                stonits = 1.; | 
| 132 | 
greg | 
3.3 | 
        switch (tcase) {                /* set up conversion */ | 
| 133 | 
  | 
  | 
        case TC_LOGLUV32: | 
| 134 | 
  | 
  | 
        case TC_LOGLUV24: | 
| 135 | 
greg | 
3.1 | 
                TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_RAW); | 
| 136 | 
  | 
  | 
                sl.l = (uint32 *)malloc(width*sizeof(uint32)); | 
| 137 | 
greg | 
3.6 | 
                tmSetSpace(tms, TM_XYZPRIM, stonits, NULL); | 
| 138 | 
greg | 
3.3 | 
                break; | 
| 139 | 
  | 
  | 
        case TC_LOGL16: | 
| 140 | 
greg | 
3.1 | 
                TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_16BIT); | 
| 141 | 
  | 
  | 
                sl.w = (uint16 *)malloc(width*sizeof(uint16)); | 
| 142 | 
greg | 
3.6 | 
                tmSetSpace(tms, tms->monpri, stonits, NULL); | 
| 143 | 
greg | 
3.3 | 
                break; | 
| 144 | 
  | 
  | 
        case TC_RGBFLOAT: | 
| 145 | 
  | 
  | 
                sl.f = (float *)malloc(width*3*sizeof(float)); | 
| 146 | 
greg | 
3.6 | 
                tmSetSpace(tms, inppri, stonits, NULL); | 
| 147 | 
greg | 
3.3 | 
                break; | 
| 148 | 
  | 
  | 
        case TC_GRYFLOAT: | 
| 149 | 
  | 
  | 
                sl.f = (float *)malloc(width*sizeof(float)); | 
| 150 | 
greg | 
3.6 | 
                tmSetSpace(tms, tms->monpri, stonits, NULL); | 
| 151 | 
greg | 
3.3 | 
                break; | 
| 152 | 
  | 
  | 
        case TC_RGBSHORT: | 
| 153 | 
  | 
  | 
                sl.w = (uint16 *)malloc(width*3*sizeof(uint16)); | 
| 154 | 
greg | 
3.6 | 
                tmSetSpace(tms, inppri, stonits, NULL); | 
| 155 | 
greg | 
3.3 | 
                break; | 
| 156 | 
  | 
  | 
        case TC_GRYSHORT: | 
| 157 | 
  | 
  | 
                sl.w = (uint16 *)malloc(width*sizeof(uint16)); | 
| 158 | 
greg | 
3.6 | 
                tmSetSpace(tms, tms->monpri, stonits, NULL); | 
| 159 | 
greg | 
3.3 | 
                break; | 
| 160 | 
  | 
  | 
        default: | 
| 161 | 
  | 
  | 
                err = TM_E_CODERR1; | 
| 162 | 
greg | 
3.1 | 
                goto done; | 
| 163 | 
greg | 
3.3 | 
        } | 
| 164 | 
greg | 
3.1 | 
        *lpp = (TMbright *)malloc(width*height*sizeof(TMbright)); | 
| 165 | 
schorsch | 
3.4 | 
        if ((sl.p == NULL) | (*lpp == NULL)) { | 
| 166 | 
greg | 
3.1 | 
                err = TM_E_NOMEM; | 
| 167 | 
  | 
  | 
                goto done; | 
| 168 | 
  | 
  | 
        } | 
| 169 | 
greg | 
3.3 | 
        switch (tcase) {                /* allocate color if needed */ | 
| 170 | 
  | 
  | 
        case TC_LOGLUV32: | 
| 171 | 
  | 
  | 
        case TC_LOGLUV24: | 
| 172 | 
  | 
  | 
        case TC_RGBFLOAT: | 
| 173 | 
  | 
  | 
        case TC_RGBSHORT: | 
| 174 | 
  | 
  | 
                if (cpp == TM_NOCHROMP) | 
| 175 | 
  | 
  | 
                        break; | 
| 176 | 
greg | 
3.10 | 
                *cpp = (uby8 *)malloc(width*height*3*sizeof(uby8)); | 
| 177 | 
greg | 
3.3 | 
                if (*cpp == NULL) { | 
| 178 | 
  | 
  | 
                        err = TM_E_NOMEM; | 
| 179 | 
  | 
  | 
                        goto done; | 
| 180 | 
  | 
  | 
                } | 
| 181 | 
  | 
  | 
                break; | 
| 182 | 
  | 
  | 
        } | 
| 183 | 
greg | 
3.1 | 
                                        /* read and convert each scanline */ | 
| 184 | 
  | 
  | 
        for (y = 0; y < height; y++) { | 
| 185 | 
  | 
  | 
                if (TIFFReadScanline(tif, sl.p, y, 0) < 0) { | 
| 186 | 
  | 
  | 
                        err = TM_E_BADFILE; | 
| 187 | 
  | 
  | 
                        break; | 
| 188 | 
  | 
  | 
                } | 
| 189 | 
greg | 
3.3 | 
                switch (tcase) { | 
| 190 | 
  | 
  | 
                case TC_LOGLUV32: | 
| 191 | 
greg | 
3.5 | 
                        err = tmCvLuv32(tms, *lpp + y*width, | 
| 192 | 
greg | 
3.3 | 
                                cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width, | 
| 193 | 
  | 
  | 
                                        sl.l, width); | 
| 194 | 
  | 
  | 
                        break; | 
| 195 | 
  | 
  | 
                case TC_LOGLUV24: | 
| 196 | 
greg | 
3.5 | 
                        err = tmCvLuv24(tms, *lpp + y*width, | 
| 197 | 
greg | 
3.1 | 
                                cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width, | 
| 198 | 
  | 
  | 
                                        sl.l, width); | 
| 199 | 
greg | 
3.3 | 
                        break; | 
| 200 | 
  | 
  | 
                case TC_LOGL16: | 
| 201 | 
greg | 
3.5 | 
                        err = tmCvL16(tms, *lpp + y*width, sl.w, width); | 
| 202 | 
greg | 
3.3 | 
                        break; | 
| 203 | 
  | 
  | 
                case TC_RGBFLOAT: | 
| 204 | 
greg | 
3.5 | 
                        err = tmCvColors(tms, *lpp + y*width, | 
| 205 | 
greg | 
3.3 | 
                                cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width, | 
| 206 | 
  | 
  | 
                                        (COLOR *)sl.f, width); | 
| 207 | 
  | 
  | 
                        break; | 
| 208 | 
  | 
  | 
                case TC_GRYFLOAT: | 
| 209 | 
greg | 
3.5 | 
                        err = tmCvGrays(tms, *lpp + y*width, sl.f, width); | 
| 210 | 
greg | 
3.3 | 
                        break; | 
| 211 | 
  | 
  | 
                case TC_RGBSHORT: | 
| 212 | 
greg | 
3.5 | 
                        err = tmCvRGB48(tms, *lpp + y*width, | 
| 213 | 
greg | 
3.1 | 
                                cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width, | 
| 214 | 
greg | 
3.3 | 
                                        (uint16 (*)[3])sl.w, width, DEFGAM); | 
| 215 | 
  | 
  | 
                        break; | 
| 216 | 
  | 
  | 
                case TC_GRYSHORT: | 
| 217 | 
greg | 
3.5 | 
                        err = tmCvGray16(tms, *lpp + y*width, | 
| 218 | 
  | 
  | 
                                        sl.w, width, DEFGAM); | 
| 219 | 
greg | 
3.3 | 
                        break; | 
| 220 | 
  | 
  | 
                default: | 
| 221 | 
  | 
  | 
                        err = TM_E_CODERR1; | 
| 222 | 
  | 
  | 
                        break; | 
| 223 | 
  | 
  | 
                } | 
| 224 | 
greg | 
3.1 | 
                if (err != TM_E_OK) | 
| 225 | 
  | 
  | 
                        break; | 
| 226 | 
  | 
  | 
        } | 
| 227 | 
  | 
  | 
done:                                   /* clean up */ | 
| 228 | 
  | 
  | 
        if (tp == NULL) | 
| 229 | 
  | 
  | 
                TIFFClose(tif); | 
| 230 | 
  | 
  | 
        if (sl.p != NULL) | 
| 231 | 
  | 
  | 
                free(sl.p); | 
| 232 | 
  | 
  | 
        if (err != TM_E_OK) {           /* free buffers on error */ | 
| 233 | 
  | 
  | 
                if (*lpp != NULL) | 
| 234 | 
  | 
  | 
                        free((MEM_PTR)*lpp); | 
| 235 | 
  | 
  | 
                *lpp = NULL; | 
| 236 | 
  | 
  | 
                if (cpp != TM_NOCHROMP) { | 
| 237 | 
  | 
  | 
                        if (*cpp != TM_NOCHROM) | 
| 238 | 
  | 
  | 
                                free((MEM_PTR)*cpp); | 
| 239 | 
  | 
  | 
                        *cpp = NULL; | 
| 240 | 
  | 
  | 
                } | 
| 241 | 
  | 
  | 
                *xp = *yp = 0; | 
| 242 | 
  | 
  | 
                returnErr(err); | 
| 243 | 
  | 
  | 
        } | 
| 244 | 
  | 
  | 
        returnOK; | 
| 245 | 
  | 
  | 
} | 
| 246 | 
  | 
  | 
 | 
| 247 | 
  | 
  | 
 | 
| 248 | 
  | 
  | 
/* | 
| 249 | 
  | 
  | 
 * Load and tone-map a SGILOG TIFF. | 
| 250 | 
  | 
  | 
 * Beware of greyscale input -- you must check the PHOTOMETRIC tag to | 
| 251 | 
  | 
  | 
 * determine that the returned array contains only grey values, not RGB. | 
| 252 | 
  | 
  | 
 * As in tmMapPicture(), grey values are also returned if flags&TM_F_BW. | 
| 253 | 
  | 
  | 
 */ | 
| 254 | 
  | 
  | 
int | 
| 255 | 
greg | 
3.10 | 
tmMapTIFF(uby8 **psp, int *xp, int *yp, int flags, RGBPRIMP monpri, | 
| 256 | 
greg | 
3.3 | 
        double gamval, double Lddyn, double Ldmax, char *fname, TIFF *tp) | 
| 257 | 
greg | 
3.1 | 
{ | 
| 258 | 
  | 
  | 
        char    *funcName = fname==NULL ? "tmMapTIFF" : fname; | 
| 259 | 
greg | 
3.11 | 
        TMstruct        *tms = NULL; | 
| 260 | 
greg | 
3.1 | 
        TMbright        *lp; | 
| 261 | 
greg | 
3.10 | 
        uby8    *cp; | 
| 262 | 
greg | 
3.1 | 
        int     err; | 
| 263 | 
  | 
  | 
                                        /* check arguments */ | 
| 264 | 
schorsch | 
3.4 | 
        if ((psp == NULL) | (xp == NULL) | (yp == NULL) | (monpri == NULL) | | 
| 265 | 
  | 
  | 
                        ((fname == NULL) & (tp == NULL))) | 
| 266 | 
greg | 
3.1 | 
                returnErr(TM_E_ILLEGAL); | 
| 267 | 
  | 
  | 
        if (gamval < MINGAM) gamval = DEFGAM; | 
| 268 | 
  | 
  | 
        if (Lddyn < MINLDDYN) Lddyn = DEFLDDYN; | 
| 269 | 
  | 
  | 
        if (Ldmax < MINLDMAX) Ldmax = DEFLDMAX; | 
| 270 | 
  | 
  | 
        if (flags & TM_F_BW) monpri = stdprims; | 
| 271 | 
  | 
  | 
                                        /* initialize tone mapping */ | 
| 272 | 
greg | 
3.5 | 
        if ((tms = tmInit(flags, monpri, gamval)) == NULL) | 
| 273 | 
greg | 
3.1 | 
                returnErr(TM_E_NOMEM); | 
| 274 | 
  | 
  | 
                                        /* load and convert TIFF */ | 
| 275 | 
  | 
  | 
        cp = TM_NOCHROM; | 
| 276 | 
greg | 
3.5 | 
        err = tmLoadTIFF(tms, &lp, flags&TM_F_BW ? TM_NOCHROMP : &cp, | 
| 277 | 
greg | 
3.1 | 
                        xp, yp, fname, tp); | 
| 278 | 
  | 
  | 
        if (err != TM_E_OK) { | 
| 279 | 
greg | 
3.5 | 
                tmDone(tms); | 
| 280 | 
greg | 
3.1 | 
                return(err); | 
| 281 | 
  | 
  | 
        } | 
| 282 | 
  | 
  | 
        if (cp == TM_NOCHROM) { | 
| 283 | 
greg | 
3.10 | 
                *psp = (uby8 *)malloc(*xp * *yp * sizeof(uby8)); | 
| 284 | 
greg | 
3.1 | 
                if (*psp == NULL) { | 
| 285 | 
  | 
  | 
                        free((MEM_PTR)lp); | 
| 286 | 
greg | 
3.5 | 
                        tmDone(tms); | 
| 287 | 
greg | 
3.1 | 
                        returnErr(TM_E_NOMEM); | 
| 288 | 
  | 
  | 
                } | 
| 289 | 
  | 
  | 
        } else | 
| 290 | 
  | 
  | 
                *psp = cp; | 
| 291 | 
  | 
  | 
                                        /* compute color mapping */ | 
| 292 | 
greg | 
3.5 | 
        err = tmAddHisto(tms, lp, *xp * *yp, 1); | 
| 293 | 
greg | 
3.1 | 
        if (err != TM_E_OK) | 
| 294 | 
  | 
  | 
                goto done; | 
| 295 | 
greg | 
3.5 | 
        err = tmComputeMapping(tms, gamval, Lddyn, Ldmax); | 
| 296 | 
greg | 
3.1 | 
        if (err != TM_E_OK) | 
| 297 | 
  | 
  | 
                goto done; | 
| 298 | 
  | 
  | 
                                        /* map pixels */ | 
| 299 | 
greg | 
3.5 | 
        err = tmMapPixels(tms, *psp, lp, cp, *xp * *yp); | 
| 300 | 
greg | 
3.1 | 
 | 
| 301 | 
  | 
  | 
done:                                   /* clean up */ | 
| 302 | 
  | 
  | 
        free((MEM_PTR)lp); | 
| 303 | 
greg | 
3.5 | 
        tmDone(tms); | 
| 304 | 
greg | 
3.1 | 
        if (err != TM_E_OK) {           /* free memory on error */ | 
| 305 | 
  | 
  | 
                free((MEM_PTR)*psp); | 
| 306 | 
  | 
  | 
                *psp = NULL; | 
| 307 | 
  | 
  | 
                *xp = *yp = 0; | 
| 308 | 
  | 
  | 
                returnErr(err); | 
| 309 | 
  | 
  | 
        } | 
| 310 | 
  | 
  | 
        returnOK; | 
| 311 | 
  | 
  | 
} |