Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlCore/plugins/ioTIFF.cpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #include "ioTIFF.hpp"
00033 #include <vlCore/LoadWriterManager.hpp>
00034 #include <vlCore/VisualizationLibrary.hpp>
00035 #include <vlCore/FileSystem.hpp>
00036 #include <vlCore/VirtualFile.hpp>
00037 #include <vlCore/Image.hpp>
00038 #include <tiffio.h>
00039 
00040 // mic fixme: read and write 16 bits images.
00041 
00042 using namespace vl;
00043 
00044 namespace
00045 {
00046   void tiff_error(const char*, const char*, va_list)
00047   {
00048     vl::Log::error("ioTIFF unspecified error.\n");
00049   }
00050   void tiff_warning(const char *, const char *, va_list)
00051   {
00052   }
00053   tsize_t tiff_io_read_func(thandle_t fd, tdata_t buf, tsize_t size)
00054   {
00055     VirtualFile *fin = (VirtualFile*)fd;
00056     long long c = fin->read(buf,size);
00057     return (tsize_t)c;
00058   }
00059   tsize_t tiff_io_write_func(thandle_t fd, tdata_t buf, tsize_t size)
00060   {
00061     VirtualFile *fin = (VirtualFile*)fd;
00062     long long c = fin->write(buf,size);
00063     return (tsize_t)c;
00064   }
00065   toff_t tiff_io_seek_func(thandle_t fd, toff_t off, int i)
00066   {
00067     VirtualFile*fin = (VirtualFile*)fd;
00068 
00069     switch(i)
00070     {
00071     case SEEK_SET:
00072       fin->seekSet(off);
00073       return (tsize_t)fin->position();
00074 
00075     case SEEK_CUR:
00076       fin->seekCur(off);
00077       return (tsize_t)fin->position();
00078 
00079     case SEEK_END:
00080       fin->seekEnd(off);
00081       return (tsize_t)fin->position();
00082 
00083     default:
00084       return 0;
00085     }
00086   }
00087   int tiff_io_close_func(thandle_t fd) 
00088   {
00089     VirtualFile*fin = (VirtualFile*)fd;
00090     fin->close();
00091     return 0;
00092   }
00093   toff_t tiff_io_size_func(thandle_t fd)
00094   {
00095     VirtualFile *fin = (VirtualFile*)fd;
00096     return (tsize_t)fin->size();
00097   }
00098   int tiff_io_map_func(thandle_t, tdata_t*, toff_t*) 
00099   { 
00100     return 0; 
00101   }
00102   void tiff_io_unmap_func(thandle_t, tdata_t, toff_t) 
00103   {
00104     return;
00105   }
00106 }
00107 
00108 //-----------------------------------------------------------------------------
00109 ref<Image> vl::loadTIFF(const String& path)
00110 {
00111   ref<VirtualFile> file = defFileSystem()->locateFile(path);
00112   if ( !file )
00113   {
00114     Log::error( Say("File '%s' not found.\n") << path );
00115     return NULL;
00116   }
00117   else
00118     return loadTIFF(file.get());
00119 }
00120 //-----------------------------------------------------------------------------
00121 ref<Image> vl::loadTIFF(VirtualFile* file)
00122 {
00123   file->open(OM_ReadOnly);
00124   ref<Image> img = new Image;
00125 
00126   TIFFSetErrorHandler(tiff_error);
00127   TIFFSetWarningHandler(tiff_warning);
00128 
00129   TIFF* tif = TIFFClientOpen("tiffread", "r", reinterpret_cast<thandle_t>(file),
00130                 tiff_io_read_func, 
00131                 tiff_io_write_func,
00132                 tiff_io_seek_func,
00133                 tiff_io_close_func,
00134                 tiff_io_size_func,
00135                 tiff_io_map_func,
00136                 tiff_io_unmap_func);
00137 
00138   if (tif) 
00139   {
00140     uint32 w, h;
00141     size_t npixels;
00142     uint32* raster;
00143     
00144     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
00145     TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
00146     npixels = w * h;
00147     raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));
00148     if (raster != NULL) 
00149     {
00150       if (TIFFReadRGBAImage(tif, w, h, raster, 0)) 
00151       {
00152         img->allocate2D(w,h,1,vl::IF_RGBA,vl::IT_UNSIGNED_BYTE);
00153         memcpy(img->pixels(), raster, img->requiredMemory());
00154       }
00155       _TIFFfree(raster);
00156     }
00157     uint16 orientation = ORIENTATION_TOPLEFT; // default
00158     TIFFGetField(tif, TIFFTAG_ORIENTATION, &orientation);
00159     if (orientation == ORIENTATION_LEFTBOT )
00160       img->flipVertically();
00161     TIFFClose(tif);
00162   }
00163   
00164   file->close();
00165   return img;
00166 }
00167 //-----------------------------------------------------------------------------
00168 bool vl::isTIFF(VirtualFile* file)
00169 {
00170   if (!file->open(OM_ReadOnly))
00171     return false;
00172 
00173   unsigned char byteorder[2];
00174   file->read(byteorder, 2);
00175   bool little_endian = byteorder[0] == 'I'; // 'I' == LE, 'M' == BE
00176   unsigned short version = file->readUInt16(little_endian);
00177   file->close();
00178 
00179   if (byteorder[0] != byteorder[1])
00180     return false;
00181 
00182   if (byteorder[0] != 'M' && byteorder[0] != 'I')
00183     return false;
00184 
00185   if (byteorder[1] != 'M' && byteorder[1] != 'I')
00186     return false;
00187 
00188   if (version != 42)
00189     return false;
00190 
00191   return true;
00192 }
00193 //-----------------------------------------------------------------------------
00194 bool vl::saveTIFF(const Image* image, const String& path)
00195 {
00196   ref<DiskFile> file = new DiskFile(path);
00197   return saveTIFF(image, file.get());
00198 }
00199 //-----------------------------------------------------------------------------
00200 bool vl::saveTIFF(const Image* src, VirtualFile* fout)
00201 {
00202   // mic fixme: handle somehow not supported image type, cubemaps, 3d textures, mimaps etc.
00203 
00204   int w = src->width();
00205   int h = src->height();
00206   int d = src->depth();
00207   if (h == 0) h=1;
00208   if (d == 0) d=1;
00209   if (src->isCubemap()) d=6;
00210   h = h*d;
00211 
00212   // convert src to IT_UNSIGNED_BYTE / IF_RGBA
00213   ref<Image> cimg;
00214   if (src->type() != IT_UNSIGNED_BYTE)
00215   {
00216     cimg = src->convertType(IT_UNSIGNED_BYTE);
00217     src = cimg.get();
00218     if (!cimg)
00219     {
00220       Log::error( Say("saveTIFF('%s'): could not convert src to IT_UNSIGNED_BYTE.\n") << fout->path() );
00221       return false;
00222     }
00223   }
00224   if (src->format() != IF_RGBA)
00225   {
00226     cimg = src->convertFormat(IF_RGBA);
00227     src = cimg.get();
00228     if (!cimg)
00229     {
00230       Log::error( Say("saveTIFF('%s'): could not convert src to IF_RGBA.\n") << fout->path() );
00231       return false;
00232     }
00233   }
00234 
00235   const int SHORT     = 3;
00236   const int LONG      = 4;
00237   const int RATIONAL  = 5;
00238 
00239   if (!fout->open(OM_WriteOnly))
00240   {
00241     Log::error( Say("TIFF: could not open '%s' for writing.\n") << fout->path() );
00242     return false;
00243   }
00244 
00245   // little endian
00246   unsigned char little_endian[] = { 'I', 'I' };
00247   fout->write(little_endian, 2);
00248 
00249   unsigned short version = 42;
00250   fout->writeUInt16(version);
00251 
00252   unsigned long ifd_offset = 8;
00253   fout->writeUInt32(ifd_offset);
00254 
00255   unsigned short dir_count = 14;
00256   fout->writeUInt16(dir_count);
00257 
00258   unsigned short tag, type;
00259   unsigned long count;
00260 
00261   // WIDTH
00262 
00263   tag = 256; fout->writeUInt16(tag);
00264   type = SHORT; fout->writeUInt16(type);
00265   count = 1; fout->writeUInt32(count);
00266   fout->writeUInt16((unsigned short)w); fout->writeUInt16(0);
00267 
00268   // HEIGHT
00269 
00270   tag = 257; fout->writeUInt16(tag);
00271   type = SHORT; fout->writeUInt16(type);
00272   count = 1; fout->writeUInt32(count);
00273   fout->writeUInt16((unsigned short)h); fout->writeUInt16(0);
00274 
00275   // BITS PER SAMPLE
00276 
00277   tag = 258; fout->writeUInt16(tag);
00278   type = SHORT; fout->writeUInt16(type);
00279   count = 4; fout->writeUInt32(count);
00280   fout->writeUInt32(10 + dir_count*12 + 4 + 16);
00281 
00282   // COMPRESSION
00283 
00284   tag = 259; fout->writeUInt16(tag);
00285   type = SHORT; fout->writeUInt16(type);
00286   count = 1; fout->writeUInt32(count);
00287   fout->writeUInt16(1); fout->writeUInt16(0);
00288 
00289   // PHOTOMETRIC INTERPRETATION
00290 
00291   tag = 262; fout->writeUInt16(tag);
00292   type = SHORT; fout->writeUInt16(type);
00293   count = 1; fout->writeUInt32(count);
00294   fout->writeUInt16(2); fout->writeUInt16(0);
00295 
00296   // STRIP OFFSET
00297 
00298   tag = 273; fout->writeUInt16(tag);
00299   type = LONG; fout->writeUInt16(type);
00300   count = 1; fout->writeUInt32(count);
00301   fout->writeUInt32(10 + dir_count*12 + 4 + 16 + 8);
00302 
00303   // SAMPLES PER PIXEL
00304 
00305   tag = 277; fout->writeUInt16(tag);
00306   type = SHORT; fout->writeUInt16(type);
00307   count = 1; fout->writeUInt32(count);
00308   fout->writeUInt16(4); fout->writeUInt16(0);
00309 
00310   // ROWS PER STRIP
00311 
00312   tag = 278; fout->writeUInt16(tag);
00313   type = SHORT; fout->writeUInt16(type);
00314   count = 1; fout->writeUInt32(count);
00315   fout->writeUInt16((unsigned short)h); fout->writeUInt16(0);
00316 
00317   // STRIP BYTE COUNT
00318 
00319   tag = 279; fout->writeUInt16(tag);
00320   type = LONG; fout->writeUInt16(type);
00321   count = 1; fout->writeUInt32(count);
00322   fout->writeUInt32(src->requiredMemory());
00323 
00324   // X RESOLUTION
00325 
00326   tag = 282; fout->writeUInt16(tag);
00327   type = RATIONAL; fout->writeUInt16(type);
00328   count = 1; fout->writeUInt32(count);
00329   fout->writeUInt32(10 + dir_count*12 + 4 + 0);
00330 
00331   // Y RESOLUTION
00332 
00333   tag = 283; fout->writeUInt16(tag);
00334   type = RATIONAL; fout->writeUInt16(type);
00335   count = 1; fout->writeUInt32(count);
00336   fout->writeUInt32(10 + dir_count*12 + 4 + 8);
00337 
00338   // PLANAR CONFIGURATION
00339 
00340   tag = 284; fout->writeUInt16(tag);
00341   type = SHORT; fout->writeUInt16(type);
00342   count = 1; fout->writeUInt32(count);
00343   fout->writeUInt16(1); fout->writeUInt16(0);
00344 
00345   // RESOLUTION UNIT
00346 
00347   tag = 296; fout->writeUInt16(tag);
00348   type = SHORT; fout->writeUInt16(type);
00349   count = 1; fout->writeUInt32(count);
00350   fout->writeUInt16(2); fout->writeUInt16(0);
00351 
00352   // EXTRA SAMPLES
00353 
00354   tag = 338; fout->writeUInt16(tag);
00355   type = SHORT; fout->writeUInt16(type);
00356   count = 1; fout->writeUInt32(count);
00357   fout->writeUInt16(0); fout->writeUInt16(0);
00358 
00359   // next ifd offset
00360   fout->writeUInt32(0);
00361 
00362   // rational1
00363   fout->writeUInt32(72);
00364   fout->writeUInt32(1);
00365   // rational2
00366   fout->writeUInt32(72);
00367   fout->writeUInt32(1);
00368 
00369   // bits per sample
00370   fout->writeUInt16(8);
00371   fout->writeUInt16(8);
00372   fout->writeUInt16(8);
00373   fout->writeUInt16(8);
00374 
00375   // save the lines in reverse order
00376   int y = h;
00377   while( y-- )
00378     fout->write(src->pixels()+src->pitch()*y, w*src->bitsPerPixel()/8);
00379 
00380   fout->close();
00381   return true;
00382 }
00383 //-----------------------------------------------------------------------------

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:30.
Permission is granted to use this page to write and publish articles regarding Visualization Library.