- メインページ
- モジュール
- ネームスペース
- データ構造
- ファイル

- ファイル一覧
- グローバル

tiff.h
説明を見る。
1 //
2 // Copyright (c) 2003-2011, MIST Project, Nagoya University
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the name of the Nagoya University nor the names of its contributors
16 // may be used to endorse or promote products derived from this software
17 // without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28
36 #ifndef __INCLUDE_MIST_TIFF__
37 #define __INCLUDE_MIST_TIFF__
38
39
40 #ifndef __INCLUDE_MIST_H__
41 #include "../mist.h"
42 #endif
43
44 // カラー画像の設定を読み込む
45 #ifndef __INCLUDE_MIST_COLOR_H__
46 #include "../config/color.h"
47 #endif
48
49 #ifndef __INCLUDE_MIST_LIMITS__
50 #include "../limits.h"
51 #endif
52
53
54 #include <iostream>
55 #include <string>
56
57 #define ORIENTATION_BOTTOMLEFT 4
58 #include <tiffio.h>
59
60
61 // mist名前空間の始まり
62 _MIST_BEGIN
63
64
65 namespace __tiff_controller__
66 {
67 // グレースケール版
68 template < bool b >
69 struct _tiff_writer_
70 {
71 template < class T, class Allocator >
72 static bool write( const array2< T, Allocator > &image, const std::string &filename, bool use_lzw_compression )
73 {
74 typedef typename array2< T, Allocator >::size_type size_type;
75
76 if( image.empty( ) )
77 {
78 return( false );
79 }
80 else if( image.width( ) == 0 )
81 {
82 std::cerr << "Image width is zero!" << std::endl;
83 return( false );
84 }
85 else if( image.height( ) == 0 )
86 {
87 std::cerr << "Image height is zero!" << std::endl;
88 return( false );
89 }
90
91 TIFF *tif;
92 size_type tiffW, tiffH;
93
94 tif = TIFFOpen( filename.c_str( ), "w" );
95 if( tif == NULL )
96 {
97 return( false );
98 }
99
100 tiffW = image.width( );
101 tiffH = image.height( );
102
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 )
114 {
115 // LZW圧縮を利用するかどうか
116 TIFFSetField( tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW );
117 }
118
119 size_type size = image.width( ) * image.height( );
120 size_type lsize = image.width( );
121 unsigned char *buf = new unsigned char[ size ];
122 size_type i;
123
124 for( i = 0 ; i < image.width( ) * image.height( ) ; i++ )
125 {
126 buf[ i ] = static_cast< unsigned char >( image[ i ] );
127 }
128
129 bool ret = true;
130 for( i = 0 ; i < tiffH ; i++ )
131 {
132 if( TIFFWriteScanline( tif, buf + i * lsize, static_cast< unsigned int >( i ), 0 ) < 0 )
133 {
134 ret = false;
135 break;
136 }
137 }
138
139 delete [] buf;
140
141 TIFFFlushData( tif );
142 TIFFClose( tif );
143
144 return( ret );
145 }
146
147 template < class Allocator >
148 static bool write( const array2< unsigned short, Allocator > &image, const std::string &filename, bool use_lzw_compression )
149 {
150 typedef typename array2< unsigned short, Allocator >::size_type size_type;
151
152 if( image.empty( ) )
153 {
154 return( false );
155 }
156 else if( image.width( ) == 0 )
157 {
158 std::cerr << "Image width is zero!" << std::endl;
159 return( false );
160 }
161 else if( image.height( ) == 0 )
162 {
163 std::cerr << "Image height is zero!" << std::endl;
164 return( false );
165 }
166
167 TIFF *tif;
168 size_type tiffW, tiffH;
169
170 tif = TIFFOpen( filename.c_str( ), "w" );
171 if( tif == NULL )
172 {
173 return( false );
174 }
175
176 tiffW = image.width( );
177 tiffH = image.height( );
178
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 )
190 {
191 // LZW圧縮を利用するかどうか
192 TIFFSetField( tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW );
193 }
194
195 size_type size = image.width( ) * image.height( );
196 size_type lsize = image.width( );
197 unsigned short *buf = new unsigned short[ size ];
198 size_type i;
199
200 for( i = 0 ; i < image.width( ) * image.height( ) ; i++ )
201 {
202 buf[ i ] = image[ i ];
203 }
204
205 bool ret = true;
206 for( i = 0 ; i < tiffH ; i++ )
207 {
208 if( TIFFWriteScanline( tif, buf + i * lsize, static_cast< unsigned int >( i ), 0 ) < 0 )
209 {
210 ret = false;
211 break;
212 }
213 }
214
215 delete [] buf;
216
217 TIFFFlushData( tif );
218 TIFFClose( tif );
219
220 return( ret );
221 }
222 };
223
224 // カラー画素版
225 template < >
226 struct _tiff_writer_< true >
227 {
228 template < class T, class Allocator >
229 static bool write( const array2< T, Allocator > &image, const std::string &filename, bool use_lzw_compression )
230 {
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;
235
236 if( image.empty( ) )
237 {
238 return( false );
239 }
240 else if( image.width( ) == 0 )
241 {
242 std::cerr << "Image width is zero!" << std::endl;
243 return( false );
244 }
245 else if( image.height( ) == 0 )
246 {
247 std::cerr << "Image height is zero!" << std::endl;
248 return( false );
249 }
250
251 TIFF *tif;
252 size_type tiffW, tiffH;
253
254 tif = TIFFOpen( filename.c_str( ), "w" );
255 if( tif == NULL )
256 {
257 return( false );
258 }
259
260 tiffW = image.width( );
261 tiffH = image.height( );
262
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 )
274 {
275 // LZW圧縮を利用するかどうか
276 TIFFSetField( tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW );
277 }
278
279 size_type size = image.width( ) * image.height( ) * 3;
280 size_type lsize = image.width( ) * 3;
281 unsigned char *buf = new unsigned char[ size ];
282 size_type i;
283
284 for( i = 0 ; i < image.width( ) * image.height( ) ; i++ )
285 {
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 );
290 }
291
292 bool ret = true;
293 for( i = 0 ; i < tiffH ; i++ )
294 {
295 if( TIFFWriteScanline( tif, buf + i * lsize, static_cast< unsigned int >( i ), 0 ) < 0 )
296 {
297 ret = false;
298 break;
299 }
300 }
301
302 delete [] buf;
303
304 TIFFFlushData( tif );
305 TIFFClose( tif );
306
307 return( ret );
308 }
309
310 template < class Allocator >
311 static bool write( const array2< rgb< unsigned short >, Allocator > &image, const std::string &filename, bool use_lzw_compression )
312 {
313 typedef typename array2< rgb< unsigned short >, Allocator >::size_type size_type;
314
315 if( image.empty( ) )
316 {
317 return( false );
318 }
319 else if( image.width( ) == 0 )
320 {
321 std::cerr << "Image width is zero!" << std::endl;
322 return( false );
323 }
324 else if( image.height( ) == 0 )
325 {
326 std::cerr << "Image height is zero!" << std::endl;
327 return( false );
328 }
329
330 TIFF *tif;
331 size_type tiffW, tiffH;
332
333 tif = TIFFOpen( filename.c_str( ), "w" );
334 if( tif == NULL )
335 {
336 return( false );
337 }
338
339 tiffW = image.width( );
340 tiffH = image.height( );
341
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 )
353 {
354 // LZW圧縮を利用するかどうか
355 TIFFSetField( tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW );
356 }
357
358 size_type size = image.width( ) * image.height( ) * 3;
359 size_type lsize = image.width( ) * 3;
360 unsigned short *buf = new unsigned short[ size ];
361 size_type i;
362
363 for( i = 0 ; i < image.width( ) * image.height( ) ; i++ )
364 {
365 buf[ i * 3 + 0 ] = image[ i ].r;
366 buf[ i * 3 + 1 ] = image[ i ].g;
367 buf[ i * 3 + 2 ] = image[ i ].b;
368 }
369
370 bool ret = true;
371 for( i = 0 ; i < tiffH ; i++ )
372 {
373 if( TIFFWriteScanline( tif, buf + i * lsize, static_cast< unsigned int >( i ), 0 ) < 0 )
374 {
375 ret = false;
376 break;
377 }
378 }
379
380 delete [] buf;
381
382 TIFFFlushData( tif );
383 TIFFClose( tif );
384
385 return( ret );
386 }
387
388 template < class Allocator >
389 static bool write( const array2< rgba< unsigned short >, Allocator > &image, const std::string &filename, bool use_lzw_compression )
390 {
391 typedef typename array2< rgba< unsigned short >, Allocator >::size_type size_type;
392
393 if( image.empty( ) )
394 {
395 return( false );
396 }
397 else if( image.width( ) == 0 )
398 {
399 std::cerr << "Image width is zero!" << std::endl;
400 return( false );
401 }
402 else if( image.height( ) == 0 )
403 {
404 std::cerr << "Image height is zero!" << std::endl;
405 return( false );
406 }
407
408 TIFF *tif;
409 size_type tiffW, tiffH;
410
411 tif = TIFFOpen( filename.c_str( ), "w" );
412 if( tif == NULL )
413 {
414 return( false );
415 }
416
417 tiffW = image.width( );
418 tiffH = image.height( );
419
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 )
431 {
432 // LZW圧縮を利用するかどうか
433 TIFFSetField( tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW );
434 }
435
436 size_type size = image.width( ) * image.height( ) * 3;
437 size_type lsize = image.width( ) * 3;
438 unsigned short *buf = new unsigned short[ size ];
439 size_type i;
440
441 for( i = 0 ; i < image.width( ) * image.height( ) ; i++ )
442 {
443 buf[ i * 3 + 0 ] = image[ i ].r;
444 buf[ i * 3 + 1 ] = image[ i ].g;
445 buf[ i * 3 + 2 ] = image[ i ].b;
446 }
447
448 bool ret = true;
449 for( i = 0 ; i < tiffH ; i++ )
450 {
451 if( TIFFWriteScanline( tif, buf + i * lsize, static_cast< unsigned int >( i ), 0 ) < 0 )
452 {
453 ret = false;
454 break;
455 }
456 }
457
458 delete [] buf;
459
460 TIFFFlushData( tif );
461 TIFFClose( tif );
462
463 return( ret );
464 }
465 };
466
467 template < class T, class Allocator >
468 struct tiff_controller
469 {
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;
474
475 static bool read( array2< T, Allocator > &image, const std::string &filename )
476 {
477 int cols, rows;
478 TIFF *tif;
479 unsigned short bps, spp, photomet;
480 unsigned short *redcolormap;
481 unsigned short *greencolormap;
482 unsigned short *bluecolormap;
483
484 tif = TIFFOpen( filename.c_str( ), "r" );
485 if( tif == NULL )
486 {
487 std::cerr << "Can't Open [" << filename << "]!!" << std::endl;
488 return( false );
489 }
490
491 if( !TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE , &bps ) )
492 {
493 bps = 1;
494 }
495 if( !TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &spp ) )
496 {
497 spp = 1;
498 }
499 if( !TIFFGetField( tif, TIFFTAG_PHOTOMETRIC , &photomet ) )
500 {
501 std::cerr << "error getting photometric" << std::endl;
502 }
503
504 switch( spp )
505 {
506 case 1:
507 case 3:
508 case 4:
509 break;
510
511 default:
512 std::cerr << "can only handle 1-channel gray scale or 1- or 3-channel color" << std::endl;
513 break;
514 }
515
516 TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &cols );
517 TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &rows );
518
519 int maxval = ( 1 << bps ) - 1;
520
521 if( photomet == PHOTOMETRIC_PALETTE )
522 {
523 // カラーパレットを利用する場合はパレットを読み込む
524 if( !TIFFGetField( tif, TIFFTAG_COLORMAP, &redcolormap, &greencolormap, &bluecolormap ) )
525 {
526 std::cerr << "error getting colormaped" << std::endl;
527 }
528 }
529
530 unsigned char *buf = new unsigned char[ TIFFScanlineSize( tif ) ];
531
532 if( buf == NULL )
533 {
534 std::cerr << "can't allocate memory for scanline buffer" << std::endl;
535 }
536
537 size_type width = cols;
538 size_type height = rows;
539
540 bool isBigEndian = TIFFIsBigEndian( tif ) != 0;
541
542 image.resize( width, height );
543
544 for( size_type j = 0 ; j < height ; ++j )
545 {
546 if( TIFFReadScanline( tif, buf, static_cast< unsigned int >( j ), 0 ) < 0 )
547 {
548 std::cerr << "bad data read on line " << j << std::endl;
549 }
550
551 switch( photomet )
552 {
553 case PHOTOMETRIC_MINISBLACK:
554 if( bps == 16 )
555 {
556 if( isBigEndian )
557 {
558 for( size_type i = 0 ; i < width ; ++i )
559 {
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 ) );
562 }
563 }
564 else
565 {
566 for( size_type i = 0 ; i < width ; ++i )
567 {
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 ) );
570 }
571 }
572 }
573 else
574 {
575 for( size_type i = 0 ; i < width ; ++i )
576 {
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 ) );
579 }
580 }
581 break;
582
583 case PHOTOMETRIC_MINISWHITE:
584 if( bps == 16 )
585 {
586 if( isBigEndian )
587 {
588 for( size_type i = 0 ; i < width ; ++i )
589 {
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 ) );
592 }
593 }
594 else
595 {
596 for( size_type i = 0 ; i < width ; ++i )
597 {
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 ) );
600 }
601 }
602 }
603 else
604 {
605 for( size_type i = 0 ; i < width ; ++i )
606 {
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 ) );
609 }
610 }
611 break;
612
613 case PHOTOMETRIC_PALETTE:
614 for( size_type i = 0 ; i < width ; ++i )
615 {
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 ] ) );
620 }
621 break;
622
623 case PHOTOMETRIC_RGB:
624 if( spp == 3 )
625 {
626 unsigned char *p = buf;
627 if( bps == 16 )
628 {
629 if( isBigEndian )
630 {
631 for( size_type i = 0 ; i < width ; ++i, p += 6 )
632 {
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 ) );
637 }
638 }
639 else
640 {
641 for( size_type i = 0 ; i < width ; ++i, p += 6 )
642 {
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 ) );
647 }
648 }
649 }
650 else
651 {
652 for( size_type i = 0 ; i < width ; ++i )
653 {
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 ) );
658 }
659 }
660 }
661 else
662 {
663 unsigned char *p = buf;
664 if( bps == 16 )
665 {
666 if( isBigEndian )
667 {
668 for( size_type i = 0 ; i < width ; ++i, p += 8 )
669 {
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 ) );
674 }
675 }
676 else
677 {
678 for( size_type i = 0 ; i < width ; ++i, p += 8 )
679 {
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 ) );
684 }
685 }
686 }
687 else
688 {
689 for( size_type i = 0 ; i < width ; ++i )
690 {
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 ) );
695 p++;
696 }
697 }
698 }
699 break;
700
701 default:
702 break;
703 }
704 }
705
706 delete [] buf;
707 TIFFClose( tif );
708
709 return( true );
710 }
711
712 static bool write( const array2< T, Allocator > &image, const std::string &filename, bool use_lzw_compression )
713 {
714 return( _tiff_writer_< is_color< T >::value >::write( image, filename, use_lzw_compression ) );
715 }
716 };
717 }
718
721
733
734
746 template < class T, class Allocator >
747 bool read_tiff( array2< T, Allocator > &image, const std::string &filename )
748 {
749 return( __tiff_controller__::tiff_controller< T, Allocator >::read( image, filename ) );
750 }
751
752
764 template < class T, class Allocator >
765 bool read_tiff( array2< T, Allocator > &image, const std::wstring &filename )
766 {
767 return( read_tiff( image, wstr2str( filename ) ) );
768 }
769
770
783 template < class T, class Allocator >
784 bool write_tiff( const array2< T, Allocator > &image, const std::string &filename, bool use_lzw_compression = _LZW_COMPRESSION_SUPPORT_ )
785 {
786 return( __tiff_controller__::tiff_controller< T, Allocator >::write( image, filename, use_lzw_compression ) );
787 }
788
789
802 template < class T, class Allocator >
803 bool write_tiff( const array2< T, Allocator > &image, const std::wstring &filename, bool use_lzw_compression = _LZW_COMPRESSION_SUPPORT_ )
804 {
805 return( write_tiff( image, wstr2str( filename ), use_lzw_compression ) );
806 }
807
808
810 // TIFF画像入出力グループの終わり
811
813 // 画像入出力グループの終わり
814
815
816 // mist名前空間の終わり
817 _MIST_END
818
819
820 #endif // __INCLUDE_MIST_TIFF__
821