00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00035 #include <stdlib.h>
00036 #include <string.h>
00037
00038 #include "tiffio.h"
00039
00040
00041
00042
00043
00057 static uint8 *read_tiff_rgba_raw(const char *fname,
00058 size_t * nx, size_t * ny, size_t * nc) {
00059 TIFF *tiffp = NULL;
00060 uint32 width = 0, height = 0, nbsamples = 0;
00061 uint32 *data_tiff = NULL;
00062 uint32 *ptr_in, *ptr_end;
00063 uint8 *data = NULL;
00064 uint8 *ptr_r, *ptr_g, *ptr_b;
00065
00066
00067 if ((NULL == nx) || (NULL == ny) || (NULL == nc))
00068 return NULL;
00069
00070
00071 (void) TIFFSetWarningHandler(NULL);
00072
00073
00074 if (NULL == (tiffp = TIFFOpen(fname, "r")))
00075 return NULL;
00076
00077
00078 if (1 != TIFFGetField(tiffp, TIFFTAG_IMAGEWIDTH, &width)
00079 || 1 != TIFFGetField(tiffp, TIFFTAG_IMAGELENGTH, &height)
00080 || 1 != TIFFGetField(tiffp, TIFFTAG_SAMPLESPERPIXEL, &nbsamples)
00081 || NULL == (data_tiff = (uint32 *) malloc(width * height
00082 * sizeof(uint32)))) {
00083 TIFFClose(tiffp);
00084 return NULL;
00085 }
00086
00087
00088 if (1 != TIFFReadRGBAImageOriented(tiffp, width, height, data_tiff,
00089 ORIENTATION_TOPLEFT, 1)) {
00090 free(data_tiff);
00091 TIFFClose(tiffp);
00092 return NULL;
00093 }
00094
00095 TIFFClose(tiffp);
00096
00097 *nx = (size_t) width;
00098 *ny = (size_t) height;
00099 *nc = (size_t) nbsamples;
00100
00101
00102
00103
00104
00105 if (NULL == (data = (uint8 *) malloc(*nx * *ny * 3 * sizeof(uint8)))) {
00106 free(data_tiff);
00107 return NULL;
00108 }
00109
00110
00111
00112
00113
00114 ptr_in = data_tiff;
00115 ptr_end = ptr_in + *nx * *ny;
00116 ptr_r = data;
00117 ptr_g = ptr_r + *nx * *ny;
00118 ptr_b = ptr_g + *nx * *ny;
00119 while (ptr_in < ptr_end) {
00120 *ptr_r++ = (uint8) TIFFGetR(*ptr_in);
00121 *ptr_g++ = (uint8) TIFFGetG(*ptr_in);
00122 *ptr_b++ = (uint8) TIFFGetB(*ptr_in);
00123 ptr_in++;
00124 }
00125 free(data_tiff);
00126
00127
00128 if ((3 == *nc)
00129 || (3 < *nc))
00130 *nc = 3;
00131 else if ((1 == *nc)
00132 || (2 == *nc)) {
00133 *nc = 1;
00134
00135 data = (uint8 *) realloc(data, *nx * *ny * *nc * sizeof(float));
00136 } else {
00137 free(data);
00138 return NULL;
00139 }
00140 return data;
00141 }
00142
00157 float *read_tiff_f32(const char *fname, size_t * nx, size_t * ny, size_t * nc) {
00158 uint8 *data_tiff = NULL;
00159 uint8 *ptr_in, *ptr_end;
00160 float *data = NULL;
00161 float *ptr_out;
00162
00163
00164 if ((NULL == nx) || (NULL == ny) || (NULL == nc))
00165 return NULL;
00166
00167
00168 if (NULL == (data_tiff = read_tiff_rgba_raw(fname, nx, ny, nc)))
00169 return NULL;
00170 if (NULL == (data = (float *) malloc(*nx * *ny * *nc * sizeof(float)))) {
00171 free(data_tiff);
00172 return NULL;
00173 }
00174
00175
00176 ptr_in = data_tiff;
00177 ptr_end = ptr_in + *nx * *ny * *nc;
00178 ptr_out = data;
00179 while (ptr_in < ptr_end)
00180 *ptr_out++ = (float) *ptr_in++;
00181
00182 free(data_tiff);
00183
00184 return data;
00185 }
00186
00201 unsigned char *read_tiff_u8(const char *fname,
00202 size_t * nx, size_t * ny, size_t * nc)
00203
00204
00205 {
00206 uint8 *data_tiff = NULL;
00207 uint8 *ptr_in, *ptr_end;
00208 unsigned char *data = NULL;
00209 unsigned char *ptr_out;
00210
00211
00212 if ((NULL == nx) || (NULL == ny) || (NULL == nc))
00213 return NULL;
00214
00215
00216 if (NULL == (data_tiff = read_tiff_rgba_raw(fname, nx, ny, nc)))
00217 return NULL;
00218
00219
00220 if (NULL == (data = (unsigned char *)
00221 malloc(*nx * *ny * *nc * sizeof(unsigned char)))) {
00222 free(data_tiff);
00223 return NULL;
00224 }
00225
00226
00227 ptr_in = data_tiff;
00228 ptr_end = ptr_in + *nx * *ny;
00229 ptr_out = data;
00230 while (ptr_in < ptr_end)
00231 *ptr_out++ = (unsigned char) *ptr_in++;
00232
00233 free(data_tiff);
00234
00235 return data;
00236 }
00237
00238
00239
00240
00241
00259 static int write_tiff_raw(const char *fname, const uint8 * data_raw,
00260 size_t nx, size_t ny, size_t nc) {
00261 TIFF *tiffp = NULL;
00262 uint8 *data_tiff = NULL;
00263 uint16 ttag_photometric;
00264
00265
00266
00267
00268
00269
00270
00271 if (NULL == data_raw
00272 || 4294967295. < (double) nx || 4294967295. < (double) ny)
00273 return -1;
00274
00275 if (1 == nc) {
00276
00277 if (NULL == (data_tiff = (uint8 *) malloc(nx * ny * nc
00278 * sizeof(uint8))))
00279 return -1;
00280 memcpy(data_tiff, data_raw, nx * ny * nc * sizeof(uint8));
00281 ttag_photometric = PHOTOMETRIC_MINISBLACK;
00282 } else if (3 == nc) {
00283 uint8 *ptr_out, *ptr_end, *ptr_r, *ptr_g, *ptr_b;
00284
00285
00286 if (NULL == (data_tiff = (uint8 *) malloc(nx * ny * nc
00287 * sizeof(uint8))))
00288 return -1;
00289
00290 ptr_out = data_tiff;
00291 ptr_end = ptr_out + nx * ny * nc;
00292 ptr_r = (uint8 *) data_raw;
00293 ptr_g = ptr_r + nx * ny;
00294 ptr_b = ptr_g + nx * ny;
00295 while (ptr_out < ptr_end) {
00296 *ptr_out++ = *ptr_r++;
00297 *ptr_out++ = *ptr_g++;
00298 *ptr_out++ = *ptr_b++;
00299 }
00300 ttag_photometric = PHOTOMETRIC_RGB;
00301 } else
00302 return -1;
00303
00304
00305 (void) TIFFSetWarningHandler(NULL);
00306
00307
00308 if (NULL == (tiffp = TIFFOpen(fname, "w"))) {
00309 free(data_tiff);
00310 return -1;
00311 }
00312
00313
00314 if (1 != TIFFSetField(tiffp, TIFFTAG_IMAGEWIDTH, nx)
00315 || 1 != TIFFSetField(tiffp, TIFFTAG_IMAGELENGTH, ny)
00316 || 1 != TIFFSetField(tiffp, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT)
00317 || 1 != TIFFSetField(tiffp, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)
00318 || 1 != TIFFSetField(tiffp, TIFFTAG_BITSPERSAMPLE, 8)
00319 || 1 != TIFFSetField(tiffp, TIFFTAG_ROWSPERSTRIP, ny)
00320 || 1 != TIFFSetField(tiffp, TIFFTAG_COMPRESSION, COMPRESSION_LZW)
00321
00322 || 1 != TIFFSetField(tiffp, TIFFTAG_SAMPLESPERPIXEL, nc)
00323 || 1 != TIFFSetField(tiffp, TIFFTAG_PHOTOMETRIC, ttag_photometric)
00324
00325 || (nx * ny * nc != (unsigned int)
00326 TIFFWriteEncodedStrip(tiffp, (tstrip_t) 0, (tdata_t) data_tiff,
00327 (tsize_t) (nx * ny * nc)))) {
00328 free(data_tiff);
00329 TIFFClose(tiffp);
00330 return -1;
00331 }
00332
00333
00334 free(data_tiff);
00335 TIFFClose(tiffp);
00336 return 0;
00337 }
00338
00351 int write_tiff_f32(const char *fname, const float *data,
00352 size_t nx, size_t ny, size_t nc) {
00353 uint8 *data_tiff = NULL;
00354 uint8 *ptr_out, *ptr_end;
00355 const float *ptr_in;
00356 int retval;
00357
00358
00359 if (NULL == data)
00360 return -1;
00361
00362
00363 if (NULL == (data_tiff = (uint8 *) malloc(nx * ny * nc * sizeof(uint8))))
00364 return -1;
00365
00366
00367 ptr_out = data_tiff;
00368 ptr_end = ptr_out + nx * ny * nc;
00369 ptr_in = data;
00370 while (ptr_out < ptr_end)
00371 *ptr_out++ = (uint8) (*ptr_in++ + .5);
00372
00373
00374 retval = write_tiff_raw(fname, data_tiff, nx, ny, nc);
00375
00376 free(data_tiff);
00377
00378 return retval;
00379 }
00380
00395 int write_tiff_u8(const char *fname, const unsigned char *data,
00396 size_t nx, size_t ny, size_t nc)
00397
00398
00399 {
00400 uint8 *data_tiff = NULL;
00401 uint8 *ptr_out, *ptr_end;
00402 const unsigned char *ptr_in;
00403 int retval;
00404
00405
00406 if (NULL == data)
00407 return -1;
00408
00409
00410 if (NULL == (data_tiff = (uint8 *) malloc(nx * ny * nc * sizeof(uint8))))
00411 return -1;
00412
00413
00414 ptr_out = data_tiff;
00415 ptr_end = ptr_out + nx * ny;
00416 ptr_in = data;
00417 while (ptr_out < ptr_end)
00418 *ptr_out++ = (uint8) (*ptr_in++ + .5);
00419
00420
00421 retval = write_tiff_raw(fname, data_tiff, nx, ny, nc);
00422
00423 free(data_tiff);
00424
00425 return retval;
00426 }