# Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/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 v2011.09.1162 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu Jan 26 2012 00:43:30.
Permission is granted to use this page to write and publish articles regarding Visualization Library.