• Main Page
  • Related Pages
  • Files
  • File List
  • Globals

mcm/io_tiff_all.c

Go to the documentation of this file.
00001 /*
00002  * Copyright 2009, 2010 IPOL Image Processing On Line http://www.ipol.im/
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation, either version 3 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00035 #include <stdlib.h>
00036 #include <string.h>
00037 
00038 #include "tiffio.h"
00039 
00040 /*
00041  * READ FUNCTIONS
00042  */
00043 
00057 static uint8 *read_tiff_rgba_raw(const char *fname,
00058                                  size_t * nx, size_t * ny, size_t * nc) 
00059 {
00060     TIFF *tiffp = NULL;
00061     uint32 width = 0, height = 0, nbsamples = 0;
00062     uint32 *data_tiff = NULL;
00063     uint32 *ptr_in, *ptr_end;
00064     uint8 *data = NULL;
00065     uint8 *ptr_r, *ptr_g, *ptr_b;
00066 
00067     /* check the pointers */
00068     if ((NULL == nx) || (NULL == ny) || (NULL == nc))
00069         return NULL;
00070 
00071     /* no warning messages */
00072     (void) TIFFSetWarningHandler(NULL);
00073 
00074     /* open the TIFF file and structure */
00075     if (NULL == (tiffp = TIFFOpen(fname, "r")))
00076         return NULL;
00077 
00078     /* read width and height and allocate the storage raster */
00079     if (1 != TIFFGetField(tiffp, TIFFTAG_IMAGEWIDTH, &width)
00080         || 1 != TIFFGetField(tiffp, TIFFTAG_IMAGELENGTH, &height)
00081         || 1 != TIFFGetField(tiffp, TIFFTAG_SAMPLESPERPIXEL, &nbsamples)
00082         || NULL == (data_tiff = (uint32 *) malloc(width * height
00083                                                   * sizeof(uint32))))
00084     {
00085         TIFFClose(tiffp);
00086         return NULL;
00087     }
00088 
00089     /* read the image data */
00090     if (1 != TIFFReadRGBAImageOriented(tiffp, width, height, data_tiff,
00091                                        ORIENTATION_TOPLEFT, 1))
00092     {
00093         free(data_tiff);
00094         TIFFClose(tiffp);
00095         return NULL;
00096     }
00097     /* close the TIFF file and structure */
00098     TIFFClose(tiffp);
00099 
00100     *nx = (size_t) width;
00101     *ny = (size_t) height;
00102     *nc = (size_t) nbsamples;    /* here I decide the correct number of channels
00103                                  and here stops the equivalent function of
00104                                  tiff_float_rw2.c */
00105 
00106 
00107     /* allocate the RGB deinterlaced array */
00108     if (NULL == (data = (uint8 *) malloc(*nx * *ny * 3 * sizeof(uint8))))
00109     {
00110         free(data_tiff);
00111         return NULL;
00112     }
00113 
00114     /*
00115      * deinterlace the TIFF raw array (ptr_in)
00116      * into four arrays (ptr_r, ptr_g, ptr_b, ptr_a)
00117      */
00118     ptr_in = data_tiff;
00119     ptr_end = ptr_in + *nx * *ny;
00120     ptr_r = data;
00121     ptr_g = ptr_r + *nx * *ny;
00122     ptr_b = ptr_g + *nx * *ny;
00123     while (ptr_in < ptr_end)
00124     {
00125         *ptr_r++ = (uint8) TIFFGetR(*ptr_in);
00126         *ptr_g++ = (uint8) TIFFGetG(*ptr_in);
00127         *ptr_b++ = (uint8) TIFFGetB(*ptr_in);
00128         ptr_in++;
00129     }
00130     free(data_tiff);
00131 
00132     /* select the correct number of channels to report */
00133     if ((3 == *nc)              /* RGB */
00134         || (3 < *nc))           /* RGB + alpha + ... */
00135         *nc = 3;
00136     else if ((1 == *nc)         /* grayscale */
00137              || (2 == *nc))     /* grayscale + alpha */
00138     {
00139         *nc = 1;
00140         /* truncate the deinterlaced array */
00141         data = (uint8 *) realloc(data, *nx * *ny * *nc * sizeof(float));
00142     }
00143     else                        /* 0 == *nc ?? */
00144     {
00145         free(data);
00146         return NULL;
00147     }
00148     return data;
00149 }
00150 
00165 float *read_tiff_f32(const char *fname, size_t * nx, size_t * ny, size_t * nc)
00166 {
00167     uint8 *data_tiff = NULL;
00168     uint8 *ptr_in, *ptr_end;
00169     float *data = NULL;
00170     float *ptr_out;
00171 
00172     /* check the pointers */
00173     if ((NULL == nx) || (NULL == ny) || (NULL == nc))
00174         return NULL;
00175 
00176     /* get the raw TIFF data */
00177     if (NULL == (data_tiff = read_tiff_rgba_raw(fname, nx, ny, nc)))
00178         return NULL;
00179     if (NULL == (data = (float *) malloc(*nx * *ny * *nc * sizeof(float))))
00180     {
00181         free(data_tiff);
00182         return NULL;
00183     }
00184        
00185     /* convert the image data */
00186     ptr_in = data_tiff;
00187     ptr_end = ptr_in + *nx * *ny * *nc;
00188     ptr_out = data;
00189     while (ptr_in < ptr_end)
00190           *ptr_out++ = (float) *ptr_in++;
00191     
00192     free(data_tiff);
00193 
00194     return data;
00195 }
00196 
00211 unsigned char *read_tiff_u8(const char *fname,
00212                             size_t * nx, size_t * ny, size_t * nc)  /* The only difference
00213                             between this function and the previous one is that here *data
00214                             and *ptr_out are unsigned char, which permits us to save on memory */
00215 {
00216     uint8 *data_tiff = NULL;
00217     uint8 *ptr_in, *ptr_end;
00218     unsigned char *data = NULL;
00219     unsigned char *ptr_out;
00220 
00221     /* check the pointers */
00222     if ((NULL == nx) || (NULL == ny) || (NULL == nc))
00223         return NULL;
00224 
00225     /* get the raw TIFF data */
00226     if (NULL == (data_tiff = read_tiff_rgba_raw(fname, nx, ny, nc)))
00227         return NULL;
00228 
00229     /* allocate the RGB array */
00230     if (NULL == (data = (unsigned char *)
00231                  malloc(*nx * *ny * *nc * sizeof(unsigned char))))
00232     {
00233         free(data_tiff);
00234         return NULL;
00235     }
00236 
00237     /* convert the image data */
00238     ptr_in = data_tiff;
00239     ptr_end = ptr_in + *nx * *ny;
00240     ptr_out = data;
00241     while (ptr_in < ptr_end)
00242         *ptr_out++ = (unsigned char) *ptr_in++;
00243 
00244     free(data_tiff);
00245 
00246     return data;
00247 }
00248 
00249 /*
00250  * WRITE FUNCTIONS
00251  */
00252 
00270 static int write_tiff_raw(const char *fname, const uint8 * data_raw,
00271                           size_t nx, size_t ny, size_t nc)
00272 {
00273     TIFF *tiffp = NULL;
00274     uint8 *data_tiff = NULL;
00275     uint16 ttag_photometric;
00276 
00277     /*
00278      * ensure the data is allocated
00279      * and the width and height are within the limits
00280      * (tiff uses uint32, 2^32 - 1 = 4294967295)
00281      * and open the TIFF file and structure
00282      */
00283     if (NULL == data_raw
00284         || 4294967295. < (double) nx || 4294967295. < (double) ny)
00285         return -1;
00286 
00287     if (1 == nc)                /* grayscale */
00288     {
00289         /* create the tiff array */
00290         if (NULL == (data_tiff = (uint8 *) malloc(nx * ny * nc
00291                                                   * sizeof(uint8))))
00292             return -1;
00293         memcpy(data_tiff, data_raw, nx * ny * nc * sizeof(uint8));
00294         ttag_photometric = PHOTOMETRIC_MINISBLACK;
00295     }
00296     else if (3 == nc)           /* RGB */
00297     {
00298         uint8 *ptr_out, *ptr_end, *ptr_r, *ptr_g, *ptr_b;
00299 
00300         /* create the tiff array */
00301         if (NULL == (data_tiff = (uint8 *) malloc(nx * ny * nc
00302                                                   * sizeof(uint8))))
00303             return -1;
00304         /* interlace three contiguous arrays (ptr_r, ptr_g, ptr_b) */
00305         ptr_out = data_tiff;
00306         ptr_end = ptr_out + nx * ny * nc;
00307         ptr_r = (uint8 *) data_raw;
00308         ptr_g = ptr_r + nx * ny;
00309         ptr_b = ptr_g + nx * ny;
00310         while (ptr_out < ptr_end)
00311         {
00312             *ptr_out++ = *ptr_r++;
00313             *ptr_out++ = *ptr_g++;
00314             *ptr_out++ = *ptr_b++;
00315         }
00316         ttag_photometric = PHOTOMETRIC_RGB;
00317     }
00318     else
00319         return -1;
00320 
00321     /* no warning messages */
00322     (void) TIFFSetWarningHandler(NULL);
00323 
00324     /* open the TIFF file and structure */
00325     if (NULL == (tiffp = TIFFOpen(fname, "w")))
00326     {
00327         free(data_tiff);
00328         return -1;
00329     }
00330 
00331     /* insert tags into the TIFF structure */
00332     if (1 != TIFFSetField(tiffp, TIFFTAG_IMAGEWIDTH, nx)
00333         || 1 != TIFFSetField(tiffp, TIFFTAG_IMAGELENGTH, ny)
00334         || 1 != TIFFSetField(tiffp, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT)
00335         || 1 != TIFFSetField(tiffp, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)
00336         || 1 != TIFFSetField(tiffp, TIFFTAG_BITSPERSAMPLE, 8)
00337         || 1 != TIFFSetField(tiffp, TIFFTAG_ROWSPERSTRIP, ny)
00338         || 1 != TIFFSetField(tiffp, TIFFTAG_COMPRESSION, COMPRESSION_LZW)
00339         /* nc-dependant tags */
00340         || 1 != TIFFSetField(tiffp, TIFFTAG_SAMPLESPERPIXEL, nc)
00341         || 1 != TIFFSetField(tiffp, TIFFTAG_PHOTOMETRIC, ttag_photometric)
00342         /* write the image as one single compressed strip */
00343         || (nx * ny * nc != (unsigned int)
00344             TIFFWriteEncodedStrip(tiffp, (tstrip_t) 0, (tdata_t) data_tiff,
00345                                   (tsize_t) (nx * ny * nc))))
00346     {
00347         free(data_tiff);
00348         TIFFClose(tiffp);
00349         return -1;
00350     }
00351 
00352     /* free the TIFF structure and data, return success */
00353     free(data_tiff);
00354     TIFFClose(tiffp);
00355     return 0;
00356 }
00357 
00370 int write_tiff_f32(const char *fname, const float *data,
00371                    size_t nx, size_t ny, size_t nc)
00372 {
00373     uint8 *data_tiff = NULL;
00374     uint8 *ptr_out, *ptr_end;
00375     const float *ptr_in;
00376     int retval;
00377 
00378     /* check allocaton */
00379     if (NULL == data)
00380         return -1;
00381 
00382     /* create the tiff array */
00383     if (NULL == (data_tiff = (uint8 *) malloc(nx * ny * nc * sizeof(uint8))))
00384         return -1;
00385 
00386     /* round and convert to uint8 */
00387     ptr_out = data_tiff;
00388     ptr_end = ptr_out + nx * ny * nc;
00389     ptr_in = data;
00390     while (ptr_out < ptr_end)
00391         *ptr_out++ = (uint8) (*ptr_in++ + .5);
00392 
00393     /* write the file */
00394     retval = write_tiff_raw(fname, data_tiff, nx, ny, nc);
00395 
00396     free(data_tiff);
00397 
00398     return retval;
00399 }
00400 
00415 int write_tiff_u8(const char *fname, const unsigned char *data,
00416                   size_t nx, size_t ny, size_t nc) /* The only difference
00417                             between this function and the previous one is that
00418                             here *ptr_in is unsigned char, which permits us to save on memory */
00419 {
00420     uint8 *data_tiff = NULL;
00421     uint8 *ptr_out, *ptr_end;
00422     const unsigned char *ptr_in;
00423     int retval;
00424 
00425     /* check allocaton */
00426     if (NULL == data)
00427         return -1;
00428 
00429     /* create the tiff array */
00430     if (NULL == (data_tiff = (uint8 *) malloc(nx * ny * nc * sizeof(uint8))))
00431         return -1;
00432 
00433     /* round and convert to uint8 */
00434     ptr_out = data_tiff;
00435     ptr_end = ptr_out + nx * ny;
00436     ptr_in = data;
00437     while (ptr_out < ptr_end)
00438         *ptr_out++ = (uint8) (*ptr_in++ + .5);
00439 
00440     /* write the file */
00441     retval = write_tiff_raw(fname, data_tiff, nx, ny, nc);
00442 
00443     free(data_tiff);
00444 
00445     return retval;
00446 }

Generated on Thu Feb 17 2011 15:42:24 for fds_mcm by  doxygen 1.7.1