00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "io_tiff.h"
00021
00022
00023
00024
00025
00026
00027
00039 static uint32 *read_tiff_rgba_raw(const char *fname, size_t * nx, size_t * ny)
00040 {
00041 TIFF *tiffp = NULL;
00042 uint32 width = 0, height = 0;
00043 uint32 *data_tiff = NULL;
00044 size_t size;
00045
00046
00047 (void) TIFFSetWarningHandler(NULL);
00048
00049
00050 if (NULL == (tiffp = TIFFOpen(fname, "r")))
00051 return NULL;
00052
00053
00054 if (1 != TIFFGetField(tiffp, TIFFTAG_IMAGEWIDTH, &width)
00055 || 1 != TIFFGetField(tiffp, TIFFTAG_IMAGELENGTH, &height)
00056 || NULL == (data_tiff = (uint32 *) malloc(width * height
00057 * sizeof(uint32))))
00058 {
00059 TIFFClose(tiffp);
00060 return NULL;
00061 }
00062
00063 size = (size_t) width * (size_t) height;
00064 if (NULL != nx)
00065 *nx = (size_t) width;
00066 if (NULL != ny)
00067 *ny = (size_t) height;
00068
00069
00070 if (1 != TIFFReadRGBAImageOriented(tiffp, width, height, data_tiff,
00071 ORIENTATION_TOPLEFT, 1))
00072 {
00073 free(data_tiff);
00074 TIFFClose(tiffp);
00075 return NULL;
00076 }
00077
00078
00079 TIFFClose(tiffp);
00080
00081 return data_tiff;
00082 }
00083
00096 static void *read_tiff_rgba(const char *fname, size_t * nx, size_t * ny,
00097 int dtype)
00098 {
00099 uint32 *data_tiff = NULL;
00100 uint32 *ptr_in, *ptr_end;
00101
00102
00103 if (NULL == (data_tiff = read_tiff_rgba_raw(fname, nx, ny)))
00104 return NULL;
00105 ptr_in = data_tiff;
00106 ptr_end = ptr_in + *nx * *ny;
00107
00108 switch (dtype)
00109 {
00110 case DT_U8:
00111 {
00112 unsigned char *data = NULL;
00113 unsigned char *ptr_r, *ptr_g, *ptr_b, *ptr_a;
00114
00115
00116 if (NULL == (data = (unsigned char *) malloc(4 * *nx * *ny
00117 * sizeof(unsigned char))))
00118 {
00119 free(data_tiff);
00120 return NULL;
00121 }
00122
00123
00124 ptr_r = data;
00125 ptr_g = ptr_r + *nx * *ny;
00126 ptr_b = ptr_g + *nx * *ny;
00127 ptr_a = ptr_b + *nx * *ny;
00128
00129
00130
00131
00132
00133 while (ptr_in < ptr_end)
00134 {
00135 *ptr_r++ = (unsigned char) TIFFGetR(*ptr_in);
00136 *ptr_g++ = (unsigned char) TIFFGetG(*ptr_in);
00137 *ptr_b++ = (unsigned char) TIFFGetB(*ptr_in);
00138 *ptr_a++ = (unsigned char) TIFFGetA(*ptr_in);
00139 ptr_in++;
00140 }
00141
00142 free(data_tiff);
00143
00144 return (void *) data;
00145 }
00146 case DT_F32:
00147 {
00148 float *data = NULL;
00149 float *ptr_r, *ptr_g, *ptr_b, *ptr_a;
00150
00151
00152 if (NULL == (data = (float *) malloc(4 * *nx * *ny
00153 * sizeof(float))))
00154 {
00155 free(data_tiff);
00156 return NULL;
00157 }
00158
00159
00160 ptr_r = data;
00161 ptr_g = ptr_r + *nx * *ny;
00162 ptr_b = ptr_g + *nx * *ny;
00163 ptr_a = ptr_b + *nx * *ny;
00164
00165
00166
00167
00168
00169 while (ptr_in < ptr_end)
00170 {
00171 *ptr_r++ = (float) TIFFGetR(*ptr_in);
00172 *ptr_g++ = (float) TIFFGetG(*ptr_in);
00173 *ptr_b++ = (float) TIFFGetB(*ptr_in);
00174 *ptr_a++ = (float) TIFFGetA(*ptr_in);
00175 ptr_in++;
00176 }
00177
00178 free(data_tiff);
00179
00180 return (void *) data;
00181 }
00182 default:
00183 return NULL;
00184 }
00185 }
00186
00198 float *read_tiff_rgba_f32(const char *fname, size_t * nx, size_t * ny)
00199 {
00200 return (float *) read_tiff_rgba(fname, nx, ny, DT_F32);
00201 }
00202
00214 unsigned char *read_tiff_rgba_u8(const char *fname, size_t * nx, size_t * ny)
00215 {
00216 return (unsigned char *) read_tiff_rgba(fname, nx, ny, DT_U8);
00217 }
00218
00219
00220
00221
00222
00228 static int write_tiff_rgba_raw(const char *fname, const uint32 *data_tiff,
00229 size_t nx, size_t ny)
00230 {
00231 TIFF *tiffp = NULL;
00232 uint16 alpha_type[] = { EXTRASAMPLE_ASSOCALPHA };
00233 size_t size;
00234
00235
00236
00237
00238
00239
00240
00241 if (NULL == data_tiff
00242 || 4294967295. < (double) nx || 4294967295. < (double) ny)
00243 return -1;
00244 size = nx * ny;
00245
00246
00247 (void) TIFFSetWarningHandler(NULL);
00248
00249
00250 if (NULL == (tiffp = TIFFOpen(fname, "w")))
00251 return -1;
00252
00253
00254 if (1 != TIFFSetField(tiffp, TIFFTAG_IMAGEWIDTH, nx)
00255 || 1 != TIFFSetField(tiffp, TIFFTAG_IMAGELENGTH, ny)
00256 || 1 != TIFFSetField(tiffp, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT)
00257 || 1 != TIFFSetField(tiffp, TIFFTAG_BITSPERSAMPLE, 8)
00258 || 1 != TIFFSetField(tiffp, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)
00259 || 1 != TIFFSetField(tiffp, TIFFTAG_ROWSPERSTRIP, ny)
00260 || 1 != TIFFSetField(tiffp, TIFFTAG_SAMPLESPERPIXEL, 4)
00261 || 1 != TIFFSetField(tiffp, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB)
00262 || 1 != TIFFSetField(tiffp, TIFFTAG_COMPRESSION, COMPRESSION_LZW)
00263 || 1 != TIFFSetField(tiffp, TIFFTAG_EXTRASAMPLES, 1, alpha_type))
00264 {
00265 TIFFClose(tiffp);
00266 return -1;
00267 }
00268
00269
00270 if (4 * nx * ny != (unsigned int)
00271 TIFFWriteEncodedStrip(tiffp, (tstrip_t) 0, (tdata_t) data_tiff,
00272 (tsize_t) (4 * size)))
00273 {
00274 TIFFClose(tiffp);
00275 return -1;
00276 }
00277
00278
00279 TIFFClose(tiffp);
00280 return 0;
00281 }
00282
00289 #define TIFFPackRGBA(r, g, b, a) (uint32) ((r & 0xff) \
00290 | (g & 0xff) << 8 \
00291 | (b & 0xff) << 16 \
00292 | (a & 0xff) << 24)
00293
00306 static int write_tiff_rgba(const char *fname, const void *data,
00307 size_t nx, size_t ny, int dtype)
00308 {
00309 uint32 *data_tiff = NULL;
00310 uint32 *ptr_out, *ptr_end;
00311 int retval;
00312
00313
00314 if (NULL == data)
00315 return -1;
00316
00317
00318 if (NULL == (data_tiff = (uint32*) malloc(nx * ny * sizeof(uint32))))
00319 return -1;
00320 ptr_out = data_tiff;
00321 ptr_end = ptr_out + nx * ny;
00322
00323 switch (dtype)
00324 {
00325 case DT_U8:
00326 {
00327 const unsigned char *ptr_r, *ptr_g, *ptr_b, *ptr_a;
00328
00329
00330 ptr_r = (unsigned char *) data;
00331 ptr_g = ptr_r + nx * ny;
00332 ptr_b = ptr_g + nx * ny;
00333 ptr_a = ptr_b + nx * ny;
00334
00335
00336
00337
00338
00339 while (ptr_out < ptr_end)
00340 *ptr_out++ = TIFFPackRGBA((uint8) (*ptr_r++),
00341 (uint8) (*ptr_g++),
00342 (uint8) (*ptr_b++),
00343 (uint8) (*ptr_a++));
00344 break;
00345 }
00346 case DT_F32:
00347 {
00348 const float *ptr_r, *ptr_g, *ptr_b, *ptr_a;
00349
00350
00351 ptr_r = (float *) data;
00352 ptr_g = ptr_r + nx * ny;
00353 ptr_b = ptr_g + nx * ny;
00354 ptr_a = ptr_b + nx * ny;
00355
00356
00357
00358
00359
00360 while (ptr_out < ptr_end)
00361 *ptr_out++ = TIFFPackRGBA((uint8) (*ptr_r++ + .5),
00362 (uint8) (*ptr_g++ + .5),
00363 (uint8) (*ptr_b++ + .5),
00364 (uint8) (*ptr_a++ + .5));
00365 break;
00366 }
00367 default:
00368 return -1;
00369 }
00370
00371
00372 retval = write_tiff_rgba_raw(fname, data_tiff, nx, ny);
00373
00374 free(data_tiff);
00375
00376 return retval;
00377 }
00378
00388 int write_tiff_rgba_f32(const char *fname, const float *data,
00389 size_t nx, size_t ny)
00390 {
00391 return write_tiff_rgba(fname, (void *) data, nx, ny, DT_F32);
00392 }
00393
00403 int write_tiff_rgba_u8(const char *fname, const unsigned char *data,
00404 size_t nx, size_t ny)
00405 {
00406 return write_tiff_rgba(fname, (void *) data, nx, ny, DT_U8);
00407 }
00408
00409