]>
git.saurik.com Git - wxWidgets.git/blob - src/common/imagtiff.cpp
   1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxImage TIFF handler 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  11 #pragma implementation "imagtiff.h" 
  14 // For compilers that support precompilation, includes "wx.h". 
  15 #include "wx/wxprec.h" 
  23 #if wxUSE_IMAGE && wxUSE_LIBTIFF 
  25 #include "wx/imagtiff.h" 
  26 #include "wx/bitmap.h" 
  35 #include "wx/filefn.h" 
  36 #include "wx/wfstream.h" 
  38 #include "wx/module.h" 
  40 #ifndef TIFFLINKAGEMODE 
  41   #define TIFFLINKAGEMODE LINKAGEMODE 
  44 //----------------------------------------------------------------------------- 
  46 //----------------------------------------------------------------------------- 
  48 IMPLEMENT_DYNAMIC_CLASS(wxTIFFHandler
,wxImageHandler
) 
  55 tsize_t TIFFLINKAGEMODE
 
  56 _tiffNullProc(thandle_t 
WXUNUSED(handle
), 
  57           tdata_t 
WXUNUSED(buf
), 
  58           tsize_t 
WXUNUSED(size
)) 
  63 tsize_t TIFFLINKAGEMODE
 
  64 _tiffReadProc(thandle_t handle
, tdata_t buf
, tsize_t size
) 
  66     wxInputStream 
*stream 
= (wxInputStream
*) handle
; 
  67     stream
->Read( (void*) buf
, (size_t) size 
); 
  68     return stream
->LastRead(); 
  71 tsize_t TIFFLINKAGEMODE
 
  72 _tiffWriteProc(thandle_t handle
, tdata_t buf
, tsize_t size
) 
  74     wxOutputStream 
*stream 
= (wxOutputStream
*) handle
; 
  75     stream
->Write( (void*) buf
, (size_t) size 
); 
  76     return stream
->LastWrite(); 
  79 toff_t TIFFLINKAGEMODE
 
  80 _tiffSeekIProc(thandle_t handle
, toff_t off
, int whence
) 
  82     wxInputStream 
*stream 
= (wxInputStream
*) handle
; 
  86         case SEEK_SET
: mode 
= wxFromStart
; break; 
  87         case SEEK_CUR
: mode 
= wxFromCurrent
; break; 
  88         case SEEK_END
: mode 
= wxFromEnd
; break; 
  89         default:       mode 
= wxFromCurrent
; break; 
  92     return (toff_t
)stream
->SeekI( (off_t
)off
, mode 
); 
  95 toff_t TIFFLINKAGEMODE
 
  96 _tiffSeekOProc(thandle_t handle
, toff_t off
, int whence
) 
  98     wxOutputStream 
*stream 
= (wxOutputStream
*) handle
; 
 102         case SEEK_SET
: mode 
= wxFromStart
; break; 
 103         case SEEK_CUR
: mode 
= wxFromCurrent
; break; 
 104         case SEEK_END
: mode 
= wxFromEnd
; break; 
 105         default:       mode 
= wxFromCurrent
; break; 
 108     return (toff_t
)stream
->SeekO( (off_t
)off
, mode 
); 
 112 _tiffCloseProc(thandle_t 
WXUNUSED(handle
)) 
 117 toff_t TIFFLINKAGEMODE
 
 118 _tiffSizeProc(thandle_t handle
) 
 120     wxStreamBase 
*stream 
= (wxStreamBase
*) handle
; 
 121     return (toff_t
) stream
->GetSize(); 
 125 _tiffMapProc(thandle_t 
WXUNUSED(handle
), 
 126              tdata_t
* WXUNUSED(pbase
), 
 127              toff_t
* WXUNUSED(psize
)) 
 133 _tiffUnmapProc(thandle_t 
WXUNUSED(handle
), 
 134                tdata_t 
WXUNUSED(base
), 
 135                toff_t 
WXUNUSED(size
)) 
 140 TIFFwxWarningHandler(const char* module, const char* fmt
, va_list ap
) 
 143             wxLogWarning(_("tiff module: %s"), module); 
 144     wxLogWarning((wxChar 
*) fmt
, ap
); 
 148 TIFFwxErrorHandler(const char* module, const char* fmt
, va_list ap
) 
 151             wxLogError(_("tiff module: %s"), module); 
 152     wxVLogError((wxChar 
*) fmt
, ap
); 
 158 TIFFwxOpen(wxInputStream 
&stream
, const char* name
, const char* mode
) 
 160     TIFF
* tif 
= TIFFClientOpen(name
, mode
, 
 162         _tiffReadProc
, _tiffNullProc
, 
 163         _tiffSeekIProc
, _tiffCloseProc
, _tiffSizeProc
, 
 164         _tiffMapProc
, _tiffUnmapProc
); 
 170 TIFFwxOpen(wxOutputStream 
&stream
, const char* name
, const char* mode
) 
 172     TIFF
* tif 
= TIFFClientOpen(name
, mode
, 
 174         _tiffNullProc
, _tiffWriteProc
, 
 175         _tiffSeekOProc
, _tiffCloseProc
, _tiffSizeProc
, 
 176         _tiffMapProc
, _tiffUnmapProc
); 
 181 wxTIFFHandler::wxTIFFHandler() 
 183     m_name 
= wxT("TIFF file"); 
 184     m_extension 
= wxT("tif"); 
 185     m_type 
= wxBITMAP_TYPE_TIF
; 
 186     m_mime 
= wxT("image/tiff"); 
 187     TIFFSetWarningHandler((TIFFErrorHandler
) TIFFwxWarningHandler
); 
 188     TIFFSetErrorHandler((TIFFErrorHandler
) TIFFwxErrorHandler
); 
 191 bool wxTIFFHandler::LoadFile( wxImage 
*image
, wxInputStream
& stream
, bool verbose
, int index 
) 
 198     TIFF 
*tif 
= TIFFwxOpen( stream
, "image", "r" ); 
 203             wxLogError( _("TIFF: Error loading image.") ); 
 208     if (!TIFFSetDirectory( tif
, (tdir_t
)index 
)) 
 211             wxLogError( _("Invalid TIFF image index.") ); 
 222     TIFFGetField( tif
, TIFFTAG_IMAGEWIDTH
, &w 
); 
 223     TIFFGetField( tif
, TIFFTAG_IMAGELENGTH
, &h 
); 
 227     raster 
= (uint32
*) _TIFFmalloc( npixels 
* sizeof(uint32
) ); 
 232             wxLogError( _("TIFF: Couldn't allocate memory.") ); 
 239     image
->Create( (int)w
, (int)h 
); 
 243             wxLogError( _("TIFF: Couldn't allocate memory.") ); 
 251     if (!TIFFReadRGBAImage( tif
, w
, h
, raster
, 0 )) 
 254             wxLogError( _("TIFF: Error reading image.") ); 
 263     bool hasmask 
= FALSE
; 
 265     unsigned char *ptr 
= image
->GetData(); 
 269     for (uint32 i 
= 0; i 
< h
; i
++) 
 271         for (uint32 j 
= 0; j 
< w
; j
++) 
 273             unsigned char alpha 
= (unsigned char)TIFFGetA(raster
[pos
]); 
 277                 ptr
[0] = image
->GetMaskRed(); 
 279                 ptr
[0] = image
->GetMaskGreen(); 
 281                 ptr
[0] = image
->GetMaskBlue(); 
 286                 ptr
[0] = (unsigned char)TIFFGetR(raster
[pos
]); 
 288                 ptr
[0] = (unsigned char)TIFFGetG(raster
[pos
]); 
 290                 ptr
[0] = (unsigned char)TIFFGetB(raster
[pos
]); 
 295         ptr 
-= 2*w
*3; // subtract line we just added plus one line 
 302     image
->SetMask( hasmask 
); 
 307 int wxTIFFHandler::GetImageCount( wxInputStream
& stream 
) 
 309     TIFF 
*tif 
= TIFFwxOpen( stream
, "image", "r" ); 
 314     int dircount 
= 0;  // according to the libtiff docs, dircount should be set to 1 here??? 
 317     } while (TIFFReadDirectory(tif
)); 
 324 bool wxTIFFHandler::SaveFile( wxImage 
*image
, wxOutputStream
& stream
, bool verbose 
) 
 326     TIFF 
*tif 
= TIFFwxOpen( stream
, "image", "w" ); 
 331             wxLogError( _("TIFF: Error saving image.") ); 
 336     TIFFSetField(tif
, TIFFTAG_IMAGEWIDTH
,  (uint32
)image
->GetWidth()); 
 337     TIFFSetField(tif
, TIFFTAG_IMAGELENGTH
, (uint32
)image
->GetHeight()); 
 338     TIFFSetField(tif
, TIFFTAG_ORIENTATION
, ORIENTATION_TOPLEFT
); 
 339     TIFFSetField(tif
, TIFFTAG_SAMPLESPERPIXEL
, 3); 
 340     TIFFSetField(tif
, TIFFTAG_BITSPERSAMPLE
, 8); 
 341     TIFFSetField(tif
, TIFFTAG_PLANARCONFIG
, PLANARCONFIG_CONTIG
); 
 342     TIFFSetField(tif
, TIFFTAG_PHOTOMETRIC
, PHOTOMETRIC_RGB
); 
 343     TIFFSetField(tif
, TIFFTAG_COMPRESSION
, COMPRESSION_LZW
); 
 345     tsize_t linebytes 
= (tsize_t
)image
->GetWidth() * 3; 
 348     if (TIFFScanlineSize(tif
) > linebytes
) 
 350         buf 
= (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif
)); 
 354                 wxLogError( _("TIFF: Couldn't allocate memory.") ); 
 366     TIFFSetField(tif
, TIFFTAG_ROWSPERSTRIP
, 
 367         TIFFDefaultStripSize(tif
, (uint32
) -1)); 
 369     unsigned char *ptr 
= image
->GetData(); 
 370     for (int row 
= 0; row 
< image
->GetHeight(); row
++) 
 373             memcpy(buf
, ptr
, image
->GetWidth()); 
 375         if (TIFFWriteScanline(tif
, buf 
? buf 
: ptr
, (uint32
)row
, 0) < 0) 
 378                 wxLogError( _("TIFF: Error writing image.") ); 
 386         ptr 
+= image
->GetWidth()*3; 
 389     (void) TIFFClose(tif
); 
 397 bool wxTIFFHandler::DoCanRead( wxInputStream
& stream 
) 
 399     unsigned char hdr
[2]; 
 401     if ( !stream
.Read(&hdr
, WXSIZEOF(hdr
)) ) 
 404     return (hdr
[0] == 'I' && hdr
[1] == 'I') || 
 405            (hdr
[0] == 'M' && hdr
[1] == 'M'); 
 408 #endif  // wxUSE_STREAMS 
 410 #endif  // wxUSE_LIBTIFF