36 #ifndef __INCLUDE_MIST_TIFF__
37 #define __INCLUDE_MIST_TIFF__
40 #ifndef __INCLUDE_MIST_H__
45 #ifndef __INCLUDE_MIST_COLOR_H__
46 #include "../config/color.h"
49 #ifndef __INCLUDE_MIST_LIMITS__
50 #include "../limits.h"
57 #define ORIENTATION_BOTTOMLEFT 4
65 namespace __tiff_controller__
71 template <
class T,
class Allocator >
72 static bool write(
const array2< T, Allocator > &image,
const std::string &filename,
bool use_lzw_compression )
74 typedef typename array2< T, Allocator >::size_type size_type;
80 else if( image.width( ) == 0 )
82 std::cerr <<
"Image width is zero!" << std::endl;
85 else if( image.height( ) == 0 )
87 std::cerr <<
"Image height is zero!" << std::endl;
92 size_type tiffW, tiffH;
94 tif = TIFFOpen( filename.c_str( ),
"w" );
100 tiffW = image.width( );
101 tiffH = image.height( );
103 TIFFSetField( tif, TIFFTAG_IMAGEWIDTH, tiffW );
104 TIFFSetField( tif, TIFFTAG_IMAGELENGTH, tiffH );
105 TIFFSetField( tif, TIFFTAG_BITSPERSAMPLE, 8 );
106 TIFFSetField( tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK );
107 TIFFSetField( tif, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB );
108 TIFFSetField( tif, TIFFTAG_DOCUMENTNAME,
"MIST Project Team" );
109 TIFFSetField( tif, TIFFTAG_IMAGEDESCRIPTION,
"Created by MIST TIFF Conveter" );
110 TIFFSetField( tif, TIFFTAG_SAMPLESPERPIXEL, 1 );
111 TIFFSetField( tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize( tif, (
unsigned int )-1 ) );
112 TIFFSetField( tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
113 if( use_lzw_compression )
116 TIFFSetField( tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW );
119 size_type size = image.width( ) * image.height( );
120 size_type lsize = image.width( );
121 unsigned char *buf =
new unsigned char[ size ];
124 for( i = 0 ; i < image.width( ) * image.height( ) ; i++ )
126 buf[ i ] =
static_cast< unsigned char >( image[ i ] );
130 for( i = 0 ; i < tiffH ; i++ )
132 if( TIFFWriteScanline( tif, buf + i * lsize, static_cast< unsigned int >( i ), 0 ) < 0 )
141 TIFFFlushData( tif );
147 template <
class Allocator >
148 static bool write(
const array2< unsigned short, Allocator > &image,
const std::string &filename,
bool use_lzw_compression )
150 typedef typename array2< unsigned short, Allocator >::size_type size_type;
156 else if( image.width( ) == 0 )
158 std::cerr <<
"Image width is zero!" << std::endl;
161 else if( image.height( ) == 0 )
163 std::cerr <<
"Image height is zero!" << std::endl;
168 size_type tiffW, tiffH;
170 tif = TIFFOpen( filename.c_str( ),
"w" );
176 tiffW = image.width( );
177 tiffH = image.height( );
179 TIFFSetField( tif, TIFFTAG_IMAGEWIDTH, tiffW );
180 TIFFSetField( tif, TIFFTAG_IMAGELENGTH, tiffH );
181 TIFFSetField( tif, TIFFTAG_BITSPERSAMPLE, 16 );
182 TIFFSetField( tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK );
183 TIFFSetField( tif, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB );
184 TIFFSetField( tif, TIFFTAG_DOCUMENTNAME,
"MIST Project Team" );
185 TIFFSetField( tif, TIFFTAG_IMAGEDESCRIPTION,
"Created by MIST TIFF Conveter" );
186 TIFFSetField( tif, TIFFTAG_SAMPLESPERPIXEL, 1 );
187 TIFFSetField( tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize( tif, (
unsigned int )-1 ) );
188 TIFFSetField( tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
189 if( use_lzw_compression )
192 TIFFSetField( tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW );
195 size_type size = image.width( ) * image.height( );
196 size_type lsize = image.width( );
197 unsigned short *buf =
new unsigned short[ size ];
200 for( i = 0 ; i < image.width( ) * image.height( ) ; i++ )
202 buf[ i ] = image[ i ];
206 for( i = 0 ; i < tiffH ; i++ )
208 if( TIFFWriteScanline( tif, buf + i * lsize, static_cast< unsigned int >( i ), 0 ) < 0 )
217 TIFFFlushData( tif );
226 struct _tiff_writer_< true >
228 template <
class T,
class Allocator >
229 static bool write(
const array2< T, Allocator > &image,
const std::string &filename,
bool use_lzw_compression )
231 typedef _pixel_converter_< T > pixel_converter;
232 typedef typename pixel_converter::color_type color_type;
233 typedef typename pixel_converter::value_type value_type;
234 typedef typename array2< T, Allocator >::size_type size_type;
240 else if( image.width( ) == 0 )
242 std::cerr <<
"Image width is zero!" << std::endl;
245 else if( image.height( ) == 0 )
247 std::cerr <<
"Image height is zero!" << std::endl;
252 size_type tiffW, tiffH;
254 tif = TIFFOpen( filename.c_str( ),
"w" );
260 tiffW = image.width( );
261 tiffH = image.height( );
263 TIFFSetField( tif, TIFFTAG_IMAGEWIDTH, tiffW );
264 TIFFSetField( tif, TIFFTAG_IMAGELENGTH, tiffH );
265 TIFFSetField( tif, TIFFTAG_BITSPERSAMPLE, 8 );
266 TIFFSetField( tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB );
267 TIFFSetField( tif, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB );
268 TIFFSetField( tif, TIFFTAG_DOCUMENTNAME,
"MIST Project Team" );
269 TIFFSetField( tif, TIFFTAG_IMAGEDESCRIPTION,
"Created by MIST TIFF Conveter" );
270 TIFFSetField( tif, TIFFTAG_SAMPLESPERPIXEL, 3 );
271 TIFFSetField( tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize( tif, (
unsigned int )-1 ) );
272 TIFFSetField( tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
273 if( use_lzw_compression )
276 TIFFSetField( tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW );
279 size_type size = image.width( ) * image.height( ) * 3;
280 size_type lsize = image.width( ) * 3;
281 unsigned char *buf =
new unsigned char[ size ];
284 for( i = 0 ; i < image.width( ) * image.height( ) ; i++ )
286 color_type c =
limits_0_255( pixel_converter::convert_from( image[ i ] ) );
287 buf[ i * 3 + 0 ] =
static_cast< unsigned char >( c.r );
288 buf[ i * 3 + 1 ] =
static_cast< unsigned char >( c.g );
289 buf[ i * 3 + 2 ] =
static_cast< unsigned char >( c.b );
293 for( i = 0 ; i < tiffH ; i++ )
295 if( TIFFWriteScanline( tif, buf + i * lsize, static_cast< unsigned int >( i ), 0 ) < 0 )
304 TIFFFlushData( tif );
310 template <
class Allocator >
311 static bool write(
const array2< rgb< unsigned short >, Allocator > &image,
const std::string &filename,
bool use_lzw_compression )
313 typedef typename array2< rgb< unsigned short >, Allocator >::size_type size_type;
319 else if( image.width( ) == 0 )
321 std::cerr <<
"Image width is zero!" << std::endl;
324 else if( image.height( ) == 0 )
326 std::cerr <<
"Image height is zero!" << std::endl;
331 size_type tiffW, tiffH;
333 tif = TIFFOpen( filename.c_str( ),
"w" );
339 tiffW = image.width( );
340 tiffH = image.height( );
342 TIFFSetField( tif, TIFFTAG_IMAGEWIDTH, tiffW );
343 TIFFSetField( tif, TIFFTAG_IMAGELENGTH, tiffH );
344 TIFFSetField( tif, TIFFTAG_BITSPERSAMPLE, 16 );
345 TIFFSetField( tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB );
346 TIFFSetField( tif, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB );
347 TIFFSetField( tif, TIFFTAG_DOCUMENTNAME,
"MIST Project Team" );
348 TIFFSetField( tif, TIFFTAG_IMAGEDESCRIPTION,
"Created by MIST TIFF Conveter" );
349 TIFFSetField( tif, TIFFTAG_SAMPLESPERPIXEL, 3 );
350 TIFFSetField( tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize( tif, (
unsigned int )-1 ) );
351 TIFFSetField( tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
352 if( use_lzw_compression )
355 TIFFSetField( tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW );
358 size_type size = image.width( ) * image.height( ) * 3;
359 size_type lsize = image.width( ) * 3;
360 unsigned short *buf =
new unsigned short[ size ];
363 for( i = 0 ; i < image.width( ) * image.height( ) ; i++ )
365 buf[ i * 3 + 0 ] = image[ i ].r;
366 buf[ i * 3 + 1 ] = image[ i ].g;
367 buf[ i * 3 + 2 ] = image[ i ].b;
371 for( i = 0 ; i < tiffH ; i++ )
373 if( TIFFWriteScanline( tif, buf + i * lsize, static_cast< unsigned int >( i ), 0 ) < 0 )
382 TIFFFlushData( tif );
388 template <
class Allocator >
389 static bool write(
const array2< rgba< unsigned short >, Allocator > &image,
const std::string &filename,
bool use_lzw_compression )
391 typedef typename array2< rgba< unsigned short >, Allocator >::size_type size_type;
397 else if( image.width( ) == 0 )
399 std::cerr <<
"Image width is zero!" << std::endl;
402 else if( image.height( ) == 0 )
404 std::cerr <<
"Image height is zero!" << std::endl;
409 size_type tiffW, tiffH;
411 tif = TIFFOpen( filename.c_str( ),
"w" );
417 tiffW = image.width( );
418 tiffH = image.height( );
420 TIFFSetField( tif, TIFFTAG_IMAGEWIDTH, tiffW );
421 TIFFSetField( tif, TIFFTAG_IMAGELENGTH, tiffH );
422 TIFFSetField( tif, TIFFTAG_BITSPERSAMPLE, 16 );
423 TIFFSetField( tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB );
424 TIFFSetField( tif, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB );
425 TIFFSetField( tif, TIFFTAG_DOCUMENTNAME,
"MIST Project Team" );
426 TIFFSetField( tif, TIFFTAG_IMAGEDESCRIPTION,
"Created by MIST TIFF Conveter" );
427 TIFFSetField( tif, TIFFTAG_SAMPLESPERPIXEL, 3 );
428 TIFFSetField( tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize( tif, (
unsigned int )-1 ) );
429 TIFFSetField( tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
430 if( use_lzw_compression )
433 TIFFSetField( tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW );
436 size_type size = image.width( ) * image.height( ) * 3;
437 size_type lsize = image.width( ) * 3;
438 unsigned short *buf =
new unsigned short[ size ];
441 for( i = 0 ; i < image.width( ) * image.height( ) ; i++ )
443 buf[ i * 3 + 0 ] = image[ i ].r;
444 buf[ i * 3 + 1 ] = image[ i ].g;
445 buf[ i * 3 + 2 ] = image[ i ].b;
449 for( i = 0 ; i < tiffH ; i++ )
451 if( TIFFWriteScanline( tif, buf + i * lsize, static_cast< unsigned int >( i ), 0 ) < 0 )
460 TIFFFlushData( tif );
467 template <
class T,
class Allocator >
468 struct tiff_controller
470 typedef _pixel_converter_< T > pixel_converter;
471 typedef typename pixel_converter::color_type color_type;
472 typedef typename pixel_converter::value_type value_type;
473 typedef typename array2< T, Allocator >::size_type size_type;
475 static bool read( array2< T, Allocator > &image,
const std::string &filename )
479 unsigned short bps, spp, photomet;
480 unsigned short *redcolormap;
481 unsigned short *greencolormap;
482 unsigned short *bluecolormap;
484 tif = TIFFOpen( filename.c_str( ),
"r" );
487 std::cerr <<
"Can't Open [" << filename <<
"]!!" << std::endl;
491 if( !TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE , &bps ) )
495 if( !TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &spp ) )
499 if( !TIFFGetField( tif, TIFFTAG_PHOTOMETRIC , &photomet ) )
501 std::cerr <<
"error getting photometric" << std::endl;
512 std::cerr <<
"can only handle 1-channel gray scale or 1- or 3-channel color" << std::endl;
516 TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &cols );
517 TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &rows );
519 int maxval = ( 1 << bps ) - 1;
521 if( photomet == PHOTOMETRIC_PALETTE )
524 if( !TIFFGetField( tif, TIFFTAG_COLORMAP, &redcolormap, &greencolormap, &bluecolormap ) )
526 std::cerr <<
"error getting colormaped" << std::endl;
530 unsigned char *buf =
new unsigned char[ TIFFScanlineSize( tif ) ];
534 std::cerr <<
"can't allocate memory for scanline buffer" << std::endl;
537 size_type width = cols;
538 size_type height = rows;
540 bool isBigEndian = TIFFIsBigEndian( tif ) != 0;
542 image.resize( width, height );
544 for( size_type j = 0 ; j < height ; ++j )
546 if( TIFFReadScanline( tif, buf, static_cast< unsigned int >( j ), 0 ) < 0 )
548 std::cerr <<
"bad data read on line " << j << std::endl;
553 case PHOTOMETRIC_MINISBLACK:
558 for( size_type i = 0 ; i < width ; ++i )
560 int sample = ( ( buf[ i * 2 ] << 8 ) | ( buf[ i * 2 + 1 ] ) ) & maxval;
561 image( i, j ) = pixel_converter::convert_to( static_cast< value_type >( sample ), static_cast< value_type >( sample ), static_cast< value_type >( sample ) );
566 for( size_type i = 0 ; i < width ; ++i )
568 int sample = ( ( buf[ i * 2 ] ) | ( buf[ i * 2 + 1 ] << 8 ) ) & maxval;
569 image( i, j ) = pixel_converter::convert_to( static_cast< value_type >( sample ), static_cast< value_type >( sample ), static_cast< value_type >( sample ) );
575 for( size_type i = 0 ; i < width ; ++i )
577 unsigned char sample = buf[ i ] & maxval;
578 image( i, j ) = pixel_converter::convert_to( static_cast< value_type >( sample ), static_cast< value_type >( sample ), static_cast< value_type >( sample ) );
583 case PHOTOMETRIC_MINISWHITE:
588 for( size_type i = 0 ; i < width ; ++i )
590 int sample = maxval - ( ( ( buf[ i * 2 ] << 8 ) | ( buf[ i * 2 + 1 ] ) ) & maxval );
591 image( i, j ) = pixel_converter::convert_to( static_cast< value_type >( sample ), static_cast< value_type >( sample ), static_cast< value_type >( sample ) );
596 for( size_type i = 0 ; i < width ; ++i )
598 int sample = ( ( buf[ i * 2 ] ) | ( buf[ i * 2 + 1 ] << 8 ) ) & maxval;
599 image( i, j ) = pixel_converter::convert_to( static_cast< value_type >( sample ), static_cast< value_type >( sample ), static_cast< value_type >( sample ) );
605 for( size_type i = 0 ; i < width ; ++i )
607 int sample = maxval - ( buf[ i ] & maxval );
608 image( i, j ) = pixel_converter::convert_to( static_cast< value_type >( sample ), static_cast< value_type >( sample ), static_cast< value_type >( sample ) );
613 case PHOTOMETRIC_PALETTE:
614 for( size_type i = 0 ; i < width ; ++i )
616 unsigned char sample = buf[ i ] & maxval;
617 image( i, j ) = pixel_converter::convert_to( static_cast< value_type >( redcolormap[ sample ] ),
618 static_cast< value_type >( greencolormap[ sample ] ),
619 static_cast< value_type >( bluecolormap[ sample ] ) );
623 case PHOTOMETRIC_RGB:
626 unsigned char *p = buf;
631 for( size_type i = 0 ; i < width ; ++i, p += 6 )
633 unsigned short r = ( ( p[ 0 ] << 8 ) | p[ 1 ] ) & maxval;
634 unsigned short g = ( ( p[ 2 ] << 8 ) | p[ 3 ] ) & maxval;
635 unsigned short b = ( ( p[ 4 ] << 8 ) | p[ 5 ] ) & maxval;
636 image( i, j ) = pixel_converter::convert_to( static_cast< value_type >( r ), static_cast< value_type >( g ), static_cast< value_type >( b ) );
641 for( size_type i = 0 ; i < width ; ++i, p += 6 )
643 unsigned short r = ( p[ 0 ] | ( p[ 1 ] << 8 ) ) & maxval;
644 unsigned short g = ( p[ 2 ] | ( p[ 3 ] << 8 ) ) & maxval;
645 unsigned short b = ( p[ 4 ] | ( p[ 5 ] << 8 ) ) & maxval;
646 image( i, j ) = pixel_converter::convert_to( static_cast< value_type >( r ), static_cast< value_type >( g ), static_cast< value_type >( b ) );
652 for( size_type i = 0 ; i < width ; ++i )
654 unsigned char r = *p++;
655 unsigned char g = *p++;
656 unsigned char b = *p++;
657 image( i, j ) = pixel_converter::convert_to( static_cast< value_type >( r ), static_cast< value_type >( g ), static_cast< value_type >( b ) );
663 unsigned char *p = buf;
668 for( size_type i = 0 ; i < width ; ++i, p += 8 )
670 unsigned short r = ( ( p[ 0 ] << 8 ) | p[ 1 ] ) & maxval;
671 unsigned short g = ( ( p[ 2 ] << 8 ) | p[ 3 ] ) & maxval;
672 unsigned short b = ( ( p[ 4 ] << 8 ) | p[ 5 ] ) & maxval;
673 image( i, j ) = pixel_converter::convert_to( static_cast< value_type >( r ), static_cast< value_type >( g ), static_cast< value_type >( b ) );
678 for( size_type i = 0 ; i < width ; ++i, p += 8 )
680 unsigned short r = ( p[ 0 ] | ( p[ 1 ] << 8 ) ) & maxval;
681 unsigned short g = ( p[ 2 ] | ( p[ 3 ] << 8 ) ) & maxval;
682 unsigned short b = ( p[ 4 ] | ( p[ 5 ] << 8 ) ) & maxval;
683 image( i, j ) = pixel_converter::convert_to( static_cast< value_type >( r ), static_cast< value_type >( g ), static_cast< value_type >( b ) );
689 for( size_type i = 0 ; i < width ; ++i )
691 unsigned char r = *p++;
692 unsigned char g = *p++;
693 unsigned char b = *p++;
694 image( i, j ) = pixel_converter::convert_to( static_cast< value_type >( r ), static_cast< value_type >( g ), static_cast< value_type >( b ) );
712 static bool write(
const array2< T, Allocator > &image,
const std::string &filename,
bool use_lzw_compression )
714 return( _tiff_writer_< is_color< T >::value >::write( image, filename, use_lzw_compression ) );
746 template <
class T,
class Allocator >
749 return( __tiff_controller__::tiff_controller< T, Allocator >::read( image, filename ) );
764 template <
class T,
class Allocator >
783 template <
class T,
class Allocator >
786 return( __tiff_controller__::tiff_controller< T, Allocator >::write( image, filename, use_lzw_compression ) );
802 template <
class T,
class Allocator >
820 #endif // __INCLUDE_MIST_TIFF__