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 }