# Visualization Library

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

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

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/src/vlCore/plugins/vlTIFF.cpp

Go to the documentation of this file.

    00001 /**************************************************************************************/
    00002 /*                                                                                    */
    00003 /*  Visualization Library                                                             */
    00004 /*  http://www.visualizationlibrary.com                                               */
    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 "vlTIFF.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 using namespace vl;
    00041
    00042 namespace
    00043 {
    00044   void tiff_error(const char*, const char*, va_list)
    00045   {
    00046     vl::Log::error("vlTIFF unspecified error.\n");
    00047   }
    00048   void tiff_warning(const char *, const char *, va_list)
    00049   {
    00050   }
    00051   tsize_t tiff_io_read_func(thandle_t fd, tdata_t buf, tsize_t size)
    00052   {
    00053     VirtualFile *fin = (VirtualFile*)fd;
    00054     long long c = fin->read(buf,size);
    00055     return (tsize_t)c;
    00056   }
    00057   tsize_t tiff_io_write_func(thandle_t fd, tdata_t buf, tsize_t size)
    00058   {
    00059     VirtualFile *fin = (VirtualFile*)fd;
    00060     long long c = fin->write(buf,size);
    00061     return (tsize_t)c;
    00062   }
    00063   toff_t tiff_io_seek_func(thandle_t fd, toff_t off, int i)
    00064   {
    00065     VirtualFile*fin = (VirtualFile*)fd;
    00066
    00067     switch(i)
    00068     {
    00069     case SEEK_SET:
    00070       fin->seekSet(off);
    00071       return (tsize_t)fin->position();
    00072
    00073     case SEEK_CUR:
    00074       fin->seekCur(off);
    00075       return (tsize_t)fin->position();
    00076
    00077     case SEEK_END:
    00078       fin->seekEnd(off);
    00079       return (tsize_t)fin->position();
    00080
    00081     default:
    00082       return 0;
    00083     }
    00084   }
    00085   int tiff_io_close_func(thandle_t fd)
    00086   {
    00087     VirtualFile*fin = (VirtualFile*)fd;
    00088     fin->close();
    00089     return 0;
    00090   }
    00091   toff_t tiff_io_size_func(thandle_t fd)
    00092   {
    00093     VirtualFile *fin = (VirtualFile*)fd;
    00094     return (tsize_t)fin->size();
    00095   }
    00096   int tiff_io_map_func(thandle_t, tdata_t*, toff_t*)
    00097   {
    00098     return 0;
    00099   }
    00100   void tiff_io_unmap_func(thandle_t, tdata_t, toff_t)
    00101   {
    00102     return;
    00103   }
    00104 }
    00105
    00106 //-----------------------------------------------------------------------------
    00107 ref<Image> vl::loadTIFF(const String& path)
    00108 {
    00109   ref<VirtualFile> file = defFileSystem()->locateFile(path);
    00110   if ( !file )
    00111   {
    00112     Log::error( Say("File '%s' not found.\n") << path );
    00113     return NULL;
    00114   }
    00115   else
    00116     return loadTIFF(file.get());
    00117 }
    00118 //-----------------------------------------------------------------------------
    00119 ref<Image> vl::loadTIFF(VirtualFile* file)
    00120 {
    00121   file->open(OM_ReadOnly);
    00122   ref<Image> img = new Image;
    00123
    00124   TIFFSetErrorHandler(tiff_error);
    00125   TIFFSetWarningHandler(tiff_warning);
    00126
    00127   TIFF* tif = TIFFClientOpen("tiffread", "r", reinterpret_cast<thandle_t>(file),
    00128                 tiff_io_read_func,
    00129                 tiff_io_write_func,
    00130                 tiff_io_seek_func,
    00131                 tiff_io_close_func,
    00132                 tiff_io_size_func,
    00133                 tiff_io_map_func,
    00134                 tiff_io_unmap_func);
    00135
    00136   if (tif)
    00137   {
    00138     uint32 w, h;
    00139     size_t npixels;
    00140     uint32* raster;
    00141
    00142     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
    00143     TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
    00144     npixels = w * h;
    00145     raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));
    00146     if (raster != NULL)
    00147     {
    00148       if (TIFFReadRGBAImage(tif, w, h, raster, 0))
    00149       {
    00150         img->allocate2D(w,h,1,vl::IF_RGBA,vl::IT_UNSIGNED_BYTE);
    00151         memcpy(img->pixels(), raster, img->requiredMemory());
    00152       }
    00153       _TIFFfree(raster);
    00154     }
    00155     uint16 orientation = ORIENTATION_TOPLEFT; // default
    00156     TIFFGetField(tif, TIFFTAG_ORIENTATION, &orientation);
    00157     if (orientation == ORIENTATION_LEFTBOT )
    00158       img->flipVertically();
    00159     TIFFClose(tif);
    00160   }
    00161
    00162   file->close();
    00163   return img;
    00164 }
    00165 //-----------------------------------------------------------------------------
    00166 bool vl::isTIFF(VirtualFile* file)
    00167 {
    00168   if (!file->open(OM_ReadOnly))
    00169     return false;
    00170
    00171   unsigned char byteorder[2];
    00172   file->read(byteorder, 2);
    00173   bool little_endian = byteorder[0] == 'I'; // 'I' == LE, 'M' == BE
    00174   unsigned short version = file->readUInt16(little_endian);
    00175   file->close();
    00176
    00177   if (byteorder[0] != byteorder[1])
    00178     return false;
    00179
    00180   if (byteorder[0] != 'M' && byteorder[0] != 'I')
    00181     return false;
    00182
    00183   if (byteorder[1] != 'M' && byteorder[1] != 'I')
    00184     return false;
    00185
    00186   if (version != 42)
    00187     return false;
    00188
    00189   return true;
    00190 }
    00191 //-----------------------------------------------------------------------------
    00192 bool vl::saveTIFF(const Image* image, const String& path)
    00193 {
    00194   ref<DiskFile> file = new DiskFile(path);
    00195   return saveTIFF(image, file.get());
    00196 }
    00197 //-----------------------------------------------------------------------------
    00198 bool vl::saveTIFF(const Image* src, VirtualFile* fout)
    00199 {
    00200   //if (src->dimension() != ID_2D )
    00201   //{
    00202   //  Log::error( Say("saveTIFF('%s'): can save only 2D images.\n") << fout->path() );
    00203   //  return false;
    00204   //}
    00205
    00206   int w = src->width();
    00207   int h = src->height();
    00208   int d = src->depth();
    00209   if (h == 0) h=1;
    00210   if (d == 0) d=1;
    00211   if (src->isCubemap()) d=6;
    00212   h = h*d;
    00213
    00214   // convert src to IT_UNSIGNED_BYTE / IF_RGBA
    00215   ref<Image> cimg;
    00216   if (src->type() != IT_UNSIGNED_BYTE)
    00217   {
    00218     cimg = src->convertType(IT_UNSIGNED_BYTE);
    00219     src = cimg.get();
    00220     if (!cimg)
    00221     {
    00222       Log::error( Say("saveTIFF('%s'): could not convert src to IT_UNSIGNED_BYTE.\n") << fout->path() );
    00223       return false;
    00224     }
    00225   }
    00226   if (src->format() != IF_RGBA)
    00227   {
    00228     cimg = src->convertFormat(IF_RGBA);
    00229     src = cimg.get();
    00230     if (!cimg)
    00231     {
    00232       Log::error( Say("saveTIFF('%s'): could not convert src to IF_RGBA.\n") << fout->path() );
    00233       return false;
    00234     }
    00235   }
    00236
    00237   const int SHORT     = 3;
    00238   const int LONG      = 4;
    00239   const int RATIONAL  = 5;
    00240
    00241   if (!fout->open(OM_WriteOnly))
    00242   {
    00243     Log::error( Say("TIFF: could not open '%s' for writing.\n") << fout->path() );
    00244     return false;
    00245   }
    00246
    00247   // little endian
    00248   unsigned char little_endian[] = { 'I', 'I' };
    00249   fout->write(little_endian, 2);
    00250
    00251   unsigned short version = 42;
    00252   fout->writeUInt16(version);
    00253
    00254   unsigned long ifd_offset = 8;
    00255   fout->writeUInt32(ifd_offset);
    00256
    00257   unsigned short dir_count = 14;
    00258   fout->writeUInt16(dir_count);
    00259
    00260   unsigned short tag, type;
    00261   unsigned long count;
    00262
    00263   // WIDTH
    00264
    00265   tag = 256; fout->writeUInt16(tag);
    00266   type = SHORT; fout->writeUInt16(type);
    00267   count = 1; fout->writeUInt32(count);
    00268   fout->writeUInt16((unsigned short)w); fout->writeUInt16(0);
    00269
    00270   // HEIGHT
    00271
    00272   tag = 257; fout->writeUInt16(tag);
    00273   type = SHORT; fout->writeUInt16(type);
    00274   count = 1; fout->writeUInt32(count);
    00275   fout->writeUInt16((unsigned short)h); fout->writeUInt16(0);
    00276
    00277   // BITS PER SAMPLE
    00278
    00279   tag = 258; fout->writeUInt16(tag);
    00280   type = SHORT; fout->writeUInt16(type);
    00281   count = 4; fout->writeUInt32(count);
    00282   fout->writeUInt32(10 + dir_count*12 + 4 + 16);
    00283
    00284   // COMPRESSION
    00285
    00286   tag = 259; fout->writeUInt16(tag);
    00287   type = SHORT; fout->writeUInt16(type);
    00288   count = 1; fout->writeUInt32(count);
    00289   fout->writeUInt16(1); fout->writeUInt16(0);
    00290
    00291   // PHOTOMETRIC INTERPRETATION
    00292
    00293   tag = 262; fout->writeUInt16(tag);
    00294   type = SHORT; fout->writeUInt16(type);
    00295   count = 1; fout->writeUInt32(count);
    00296   fout->writeUInt16(2); fout->writeUInt16(0);
    00297
    00298   // STRIP OFFSET
    00299
    00300   tag = 273; fout->writeUInt16(tag);
    00301   type = LONG; fout->writeUInt16(type);
    00302   count = 1; fout->writeUInt32(count);
    00303   fout->writeUInt32(10 + dir_count*12 + 4 + 16 + 8);
    00304
    00305   // SAMPLES PER PIXEL
    00306
    00307   tag = 277; fout->writeUInt16(tag);
    00308   type = SHORT; fout->writeUInt16(type);
    00309   count = 1; fout->writeUInt32(count);
    00310   fout->writeUInt16(4); fout->writeUInt16(0);
    00311
    00312   // ROWS PER STRIP
    00313
    00314   tag = 278; fout->writeUInt16(tag);
    00315   type = SHORT; fout->writeUInt16(type);
    00316   count = 1; fout->writeUInt32(count);
    00317   fout->writeUInt16((unsigned short)h); fout->writeUInt16(0);
    00318
    00319   // STRIP BYTE COUNT
    00320
    00321   tag = 279; fout->writeUInt16(tag);
    00322   type = LONG; fout->writeUInt16(type);
    00323   count = 1; fout->writeUInt32(count);
    00324   fout->writeUInt32(src->requiredMemory());
    00325
    00326   // X RESOLUTION
    00327
    00328   tag = 282; fout->writeUInt16(tag);
    00329   type = RATIONAL; fout->writeUInt16(type);
    00330   count = 1; fout->writeUInt32(count);
    00331   fout->writeUInt32(10 + dir_count*12 + 4 + 0);
    00332
    00333   // Y RESOLUTION
    00334
    00335   tag = 283; fout->writeUInt16(tag);
    00336   type = RATIONAL; fout->writeUInt16(type);
    00337   count = 1; fout->writeUInt32(count);
    00338   fout->writeUInt32(10 + dir_count*12 + 4 + 8);
    00339
    00340   // PLANAR CONFIGURATION
    00341
    00342   tag = 284; fout->writeUInt16(tag);
    00343   type = SHORT; fout->writeUInt16(type);
    00344   count = 1; fout->writeUInt32(count);
    00345   fout->writeUInt16(1); fout->writeUInt16(0);
    00346
    00347   // RESOLUTION UNIT
    00348
    00349   tag = 296; fout->writeUInt16(tag);
    00350   type = SHORT; fout->writeUInt16(type);
    00351   count = 1; fout->writeUInt32(count);
    00352   fout->writeUInt16(2); fout->writeUInt16(0);
    00353
    00354   // EXTRA SAMPLES
    00355
    00356   tag = 338; fout->writeUInt16(tag);
    00357   type = SHORT; fout->writeUInt16(type);
    00358   count = 1; fout->writeUInt32(count);
    00359   fout->writeUInt16(0); fout->writeUInt16(0);
    00360
    00361   // next ifd offset
    00362   fout->writeUInt32(0);
    00363
    00364   // rational1
    00365   fout->writeUInt32(72);
    00366   fout->writeUInt32(1);
    00367   // rational2
    00368   fout->writeUInt32(72);
    00369   fout->writeUInt32(1);
    00370
    00371   // bits per sample
    00372   fout->writeUInt16(8);
    00373   fout->writeUInt16(8);
    00374   fout->writeUInt16(8);
    00375   fout->writeUInt16(8);
    00376
    00377   // save the lines in reverse order
    00378   int y = h;
    00379   while( y-- )
    00380     fout->write(src->pixels()+src->pitch()*y, w*src->bitsPerPixel()/8);
    00381   // fout->write(src->pixels(), src->requiredMemory());
    00382
    00383   fout->close();
    00384   return true;
    00385 }
    00386 //-----------------------------------------------------------------------------

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:21.
Permission is granted to use this page to write and publish articles regarding Visualization Library.