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

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

tga.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
33
34 #ifndef __INCLUDE_MIST_TGA__
35 #define __INCLUDE_MIST_TGA__
36
37
38 #ifndef __INCLUDE_MIST_H__
39 #include "../mist.h"
40 #endif
41
42 // カラー画像の設定を読み込む
43 #ifndef __INCLUDE_MIST_COLOR_H__
44 #include "../config/color.h"
45 #endif
46
47 #ifndef __INCLUDE_MIST_ENDIAN__
48 #include "../config/endian.h"
49 #endif
50
51 #ifndef __INCLUDE_MIST_LIMITS__
52 #include "../limits.h"
53 #endif
54
55
56 #include <iostream>
57 #include <string>
58
59 #include <deque>
60 #include <map>
61 #include <algorithm>
62
63
64 // mist名前空間の始まり
65 _MIST_BEGIN
66
67
68 namespace __tga_controller__
69 {
70 // 構造体内のアライメントを1バイトに設定し，パディングを禁止する
71 #if defined(__MIST_MSVC__) || defined(__INTEL_COMPILER)
72 #pragma pack( push, tga_align, 1 )
73 #endif
74 struct _tga_header_
75 {
76 enum{ bytes = 18 };
77
78 // ID Length Field 1 ( 1 byte )
79 unsigned char id_length;
80
81 // Color Map Type Field 2 ( 1 byte )
82 unsigned char color_map_type;
83
84 // Image Type Field 3 ( 1 byte )
85 unsigned char image_type;
86
87 // Color Map Specification Field 4 ( 5 bytes )
88 unsigned short first_entry_index;
89 unsigned short color_map_length;
90 unsigned char color_map_entry_size;
91
92 // Image Specification Field 4 ( 10 bytes )
93 unsigned short x_origin;
94 unsigned short y_origin;
95 unsigned short image_width;
96 unsigned short image_height;
97 unsigned char pixel_depth;
98 unsigned char image_descriptor;
99
100 } _MIST_PACKED;
101
102 #if defined(__MIST_MSVC__) || defined(__INTEL_COMPILER)
103 #pragma pack( pop, tga_align )
104 #endif
105 // 構造体内のアライメントを1バイトに設定し，パディングを禁止する 〜 ここまで 〜
106
107
108 template < class T, class Allocator >
109 struct tga_controller
110 {
111 typedef typename array2< T, Allocator >::size_type size_type;
112 typedef typename array2< T, Allocator >::difference_type difference_type;
113 typedef _pixel_converter_< T > pixel_converter;
114 typedef typename pixel_converter::color_type color_type;
115
116 static bool is_supported( size_type tga_bits )
117 {
118 bool ret = false;
119 switch( tga_bits )
120 {
121 case 16:
122 case 24:
123 case 32:
124 ret = true;
125 break;
126
127 default:
128 break;
129 }
130 return( ret );
131 }
132
133 static bool decode_RLE( const unsigned char *pixel, unsigned char * &buff, size_type snum_bytes, size_type num_bytes, size_type pixel_bytes )
134 {
135 buff = new unsigned char[ num_bytes ];
136 memset( buff, 0, sizeof( unsigned char ) * num_bytes );
137
138 size_type i = 0, j = 0;
139 for( ; i < snum_bytes && j < num_bytes ; )
140 {
141 unsigned char byte = pixel[ i++ ];
142 if( ( byte & 0x80 ) != 0 )
143 {
144 // 上位ビットが１のとき反復。次に続くデータバイト（ピクセルのバイト数を単位として）を繰り返す。
145 // 繰り返す回数は、byte & 0x7F + 1
146 // 例： 83 0A -> 0A 0A 0A 0A
147
148 size_type num = ( byte & 0x7f ) + 1;
149
150 // 範囲外アクセスのチェック
151 if( i + pixel_bytes > snum_bytes || j + num * pixel_bytes > num_bytes )
152 {
153 break;
154 }
155
156 for( size_type l = 0 ; l < num ; l++ )
157 {
158 for( size_type m = 0 ; m < pixel_bytes ; m++ )
159 {
160 buff[ j + l * pixel_bytes + m ] = pixel[ i + m ];
161 }
162 }
163
164 i += pixel_bytes;
165 j += num * pixel_bytes;
166 }
167 else
168 {
169 // 上位ビットが0のとき、リテラルグループ(Literal group)が続く。制御バイトの後ろ
170 // byte+1 個のデータ（ピクセルのバイト数を単位として）をコピーする。
171 // 例： 04 0A 0B 0C 0D 0E -> 0A 0B 0C 0D 0E
172 size_type num = byte + 1;
173
174 // 範囲外アクセスのチェック
175 if( i + num * pixel_bytes > snum_bytes || j + num * pixel_bytes > num_bytes )
176 {
177 break;
178 }
179
180 memcpy( buff + j, pixel + i, sizeof( unsigned char ) * num * pixel_bytes );
181
182 i += num * pixel_bytes;
183 j += num * pixel_bytes;
184 }
185 }
186
187 if( j != num_bytes )
188 {
189 // RLEのデコードに失敗
190 delete [] buff;
191 buff = NULL;
192 return( false );
193 }
194
195 return( true );
196 }
197
198 inline static bool is_equal( const unsigned char *pix1, const unsigned char *pix2, size_type pixel_bytes )
199 {
200 for( size_type i = 0 ; i < pixel_bytes ; i++ )
201 {
202 if( pix1[ i ] != pix2[ i ] )
203 {
204 return( false );
205 }
206 }
207 return( true );
208 }
209
210 inline static size_type count_run_length( const unsigned char *pixel, size_type num_bytes, size_type pixel_bytes )
211 {
212 if( num_bytes < 2 )
213 {
214 return( 0 );
215 }
216
217 size_type i, l;
218 for( i = 0 ; i < num_bytes ; i++ )
219 {
220 for( l = 0 ; l < pixel_bytes ; l++ )
221 {
222 if( pixel[ l ] != pixel[ i * pixel_bytes + l ] )
223 {
224 break;
225 }
226 }
227
228 if( l != pixel_bytes )
229 {
230 return( i );
231 }
232 }
233 return( i );
234 }
235
236 static size_type encode_RLE( unsigned char *pixel, size_type num_bytes, size_type pixel_bytes )
237 {
238 unsigned char *buff = new unsigned char[ num_bytes * 2 ];
239 unsigned char temp[ 20 ];
240
241 // ランレングスのリストを作成する
242 size_type num = num_bytes / pixel_bytes, count = 0, k;
243 unsigned char *pbuff = buff;
244 const unsigned char *pix = pixel;
245 const unsigned char *epix = pixel + num_bytes;
246 for( size_type i = 0 ; i < num ; i++ )
247 {
248 size_type len = count_run_length( pix, epix - pix, pixel_bytes );
249
250 if( len > 2 )
251 {
252 size_type nrun = len / 128;
253 size_type rest = len % 128;
254
255 temp[ 0 ] = 0xff;
256
257 for( k = 0 ; k < pixel_bytes ; k++ )
258 {
259 temp[ k + 1 ] = pix[ k ];
260 }
261
262 for( k = 0 ; k < nrun ; k++ )
263 {
264 for( size_type l = 0 ; l <= pixel_bytes ; l++ )
265 {
266 pbuff[ l ] = temp[ l ];
267 }
268 pbuff += pixel_bytes + 1;
269 }
270
271 pix += 128 * nrun * pixel_bytes;
272
273 if( rest > 2 )
274 {
275 temp[ 0 ] = 0x80 + static_cast< unsigned char >( rest - 1 );
276 for( size_type l = 0 ; l <= pixel_bytes ; l++ )
277 {
278 pbuff[ l ] = temp[ l ];
279 }
280 pbuff += pixel_bytes + 1;
281 pix += pixel_bytes * rest;
282
283 count = 0;
284 }
285 else if( rest > 0 )
286 {
287 pbuff[ 0 ] = static_cast< unsigned char >( rest - 1 );
288
289 for( k = 0 ; k < pixel_bytes * rest ; k++ )
290 {
291 pbuff[ k + 1 ] = pix[ k ];
292 }
293 pbuff += pixel_bytes * rest + 1;
294 pix += pixel_bytes * rest;
295
296 count = rest;
297 }
298 }
299 else if( len > 0 )
300 {
301 if( count > 0 )
302 {
303 size_type total = count + len;
304 size_type nnum, rest;
305
306 if( total > 128 )
307 {
308 rest = total % 128;
309 nnum = total - rest;
310 }
311 else
312 {
313 nnum = total;
314 rest = 0;
315 }
316
317 pbuff[ 0 ] = static_cast< unsigned char >( nnum - 1 );
318
319 for( k = 0 ; k < pixel_bytes * nnum ; k++ )
320 {
321 pbuff[ k + 1 ] = pix[ k ];
322 }
323 pbuff += pixel_bytes * nnum + 1;
324 pix += pixel_bytes * nnum;
325
326 if( rest > 0 )
327 {
328 pbuff[ 0 ] = static_cast< unsigned char >( rest - 1 );
329
330 for( k = 0 ; k < pixel_bytes * rest ; k++ )
331 {
332 pbuff[ k + 1 ] = pix[ k ];
333 }
334 pbuff += pixel_bytes * rest + 1;
335 pix += pixel_bytes * rest;
336 }
337
338 count = rest;
339 }
340 else
341 {
342 pbuff[ 0 ] = static_cast< unsigned char >( len - 1 );
343
344 for( k = 0 ; k < pixel_bytes * len ; k++ )
345 {
346 pbuff[ k + 1 ] = pix[ k ];
347 }
348 pbuff += pixel_bytes * len + 1;
349 pix += pixel_bytes * len;
350
351 count = len;
352 }
353 }
354 }
355
356 if( num_bytes <= static_cast< size_type >( pbuff - buff ) )
357 {
358 // RLEのエンコードに失敗
359 delete [] buff;
360 return( num_bytes );
361 }
362 else
363 {
364 num_bytes = pbuff - buff;
365 memcpy( pixel, buff, num_bytes );
366 delete [] buff;
367 return( num_bytes );
368 }
369 }
370
371
372 static bool convert_from_tga_data( unsigned char *tga, size_type num_bytes, array2< T, Allocator > &image )
373 {
374 // TGA用のヘッダの位置を指定する
375 _tga_header_ *pheader = reinterpret_cast < _tga_header_ * >( tga );
376 _tga_header_ &header = *pheader;
377
378 difference_type width = header.image_width;
379 difference_type height = header.image_height;
380 difference_type pixel_bytes = header.pixel_depth / 8;
381
382 unsigned char *color_map_data = tga + _tga_header_::bytes;
383 unsigned char *image_data = color_map_data + ( header.color_map_type == 0 ? 0 : header.color_map_length * header.color_map_entry_size / 8 );
384
385 // unsigned char *pfooter = image_data + width * height * pixel_bytes;
386
387 bool is_RLE = ( header.image_type & 0x08 ) != 0;
388 bool is_Huffman = ( header.image_type & 0x20 ) != 0;
389 bool from_top = ( header.image_descriptor & 0x20 ) != 0;
390 bool from_left = ( header.image_descriptor & 0x10 ) == 0;
391
392 if( is_Huffman || header.image_type > 11 )
393 {
394 // 未サポート
395 return( false );
396 }
397
398 unsigned char *buff = NULL, *pixels = NULL;
399
400 if( is_RLE )
401 {
402 if( !decode_RLE( image_data, buff, tga + num_bytes - image_data, width * height * pixel_bytes, pixel_bytes ) )
403 {
404 return( false );
405 }
406 pixels = buff + ( from_top ? 0 : width * ( height - 1 ) * pixel_bytes );
407 }
408 else
409 {
410 pixels = image_data + ( from_top ? 0 : width * ( height - 1 ) * pixel_bytes );
411 }
412
413 difference_type line_skip = from_top ? width * pixel_bytes : - width * pixel_bytes;
414 difference_type pixel_skip = from_left ? pixel_bytes : - pixel_bytes;
415
416 image.resize( width, height );
417
418 bool ret = true;
419
420 difference_type i, j, k;
421 switch( header.image_type & 0x07 )
422 {
423 case 1: // Color-mapped Image
424 for( j = 0 ; j < height ; j++ )
425 {
426 unsigned char *pixel = pixels + line_skip * j + ( from_left ? 0 : pixel_bytes ) * ( width - 1 );
427
428 for( i = 0 ; i < width ; i++ )
429 {
430 difference_type tmp = 0;
431 unsigned char *pix = pixel + pixel_skip * i;
432
433 for( k = pixel_bytes - 1 ; k >= 0 ; k-- )
434 {
435 tmp = ( tmp << 8 ) + pix[ k ];
436 }
437
438 difference_type index = tmp - header.first_entry_index;
439
440 switch( header.color_map_entry_size )
441 {
442 case 16:
443 {
444 unsigned short v = reinterpret_cast< unsigned short * >( color_map_data + index * 2 )[ 0 ];
445 unsigned char a = ( v & 0x8000 ) >> 15;
446 unsigned char r = ( ( v & 0x7c00 ) >> 10 ) * 8;
447 unsigned char g = ( ( v & 0x03e0 ) >> 5 ) * 8;
448 unsigned char b = ( v & 0x001f ) * 8;
449 image( i, j ) = pixel_converter::convert_to( r, g, b, static_cast< unsigned char >( a * 255 ) );
450 }
451 break;
452
453 case 24:
454 {
455 unsigned char r = color_map_data[ index * 3 + 2 ];
456 unsigned char g = color_map_data[ index * 3 + 1 ];
457 unsigned char b = color_map_data[ index * 3 + 0 ];
458 image( i, j ) = pixel_converter::convert_to( r, g, b );
459 }
460 break;
461
462 case 32:
463 {
464 unsigned char a = color_map_data[ index * 4 + 3 ];
465 unsigned char r = color_map_data[ index * 4 + 2 ];
466 unsigned char g = color_map_data[ index * 4 + 1 ];
467 unsigned char b = color_map_data[ index * 4 + 0 ];
468 image( i, j ) = pixel_converter::convert_to( r, g, b, a );
469 }
470 break;
471
472 default:
473 break;
474 }
475 }
476 }
477 break;
478
479 case 2: // True-color Image
480 for( j = 0 ; j < height ; j++ )
481 {
482 unsigned char *pixel = pixels + line_skip * j + ( from_left ? 0 : pixel_bytes ) * ( width - 1 );
483
484 switch( header.pixel_depth )
485 {
486 case 16:
487 for( i = 0 ; i < width ; i++ )
488 {
489 unsigned short pix = reinterpret_cast< unsigned short * >( pixel + pixel_skip * i )[ 0 ];
490 unsigned char a = ( pix & 0x8000 ) >> 15;
491 unsigned char r = ( ( pix & 0x7c00 ) >> 10 ) * 8;
492 unsigned char g = ( ( pix & 0x03e0 ) >> 5 ) * 8;
493 unsigned char b = ( pix & 0x001f ) * 8;
494 image( i, j ) = pixel_converter::convert_to( r, g, b, static_cast< unsigned char >( a * 255 ) );
495 }
496 break;
497
498 case 24:
499 for( i = 0 ; i < width ; i++ )
500 {
501 unsigned char *pix = pixel + pixel_skip * i;
502 image( i, j ) = pixel_converter::convert_to( pix[ 2 ], pix[ 1 ], pix[ 0 ] );
503 }
504 break;
505
506 case 32:
507 for( i = 0 ; i < width ; i++ )
508 {
509 unsigned char *pix = pixel + pixel_skip * i;
510 image( i, j ) = pixel_converter::convert_to( pix[ 2 ], pix[ 1 ], pix[ 0 ], pix[ 3 ] );
511 }
512 break;
513
514 default:
515 break;
516 }
517 }
518 break;
519
520 case 3: // Black and White Image
521 if( header.pixel_depth != 8 )
522 {
523 ret = false;
524 }
525 else
526 {
527 for( j = 0 ; j < height ; j++ )
528 {
529 unsigned char *pixel = pixels + line_skip * j + ( from_left ? 0 : pixel_bytes ) * ( width - 1 );
530
531 for( i = 0 ; i < width ; i++ )
532 {
533 unsigned char *pix = pixel + pixel_skip * i;
534 image( i, j ) = pixel_converter::convert_to( pix[ 0 ], pix[ 0 ], pix[ 0 ] );
535 }
536 }
537 }
538 break;
539 }
540
541 delete [] buff;
542
543 return( ret );
544 }
545
546 static difference_type convert_to_tga_data( const array2< T, Allocator > &image, unsigned char * &tga, size_type tga_bits, bool is_encode_RLE, bool from_top, bool from_left )
547 {
548 if( image.empty( ) )
549 {
550 return( -1 );
551 }
552
553 difference_type pixel_bytes = tga_bits / 8;
554 difference_type width = image.width( );
555 difference_type height = image.height( );
556
557 tga = new unsigned char[ _tga_header_::bytes + width * height * pixel_bytes ];
558
559 // TGA用のヘッダの位置を指定する
560 _tga_header_ *pheader = reinterpret_cast < _tga_header_ * >( tga );
561 _tga_header_ &header = *pheader;
562
563 // ID Length Field 1 ( 1 byte )
564 header.id_length = 0;
565
566 // Color Map Type Field 2 ( 1 byte )
567 header.color_map_type = 0;
568
569 // Image Type Field 3 ( 1 byte )
570 header.image_type = 2 + ( is_encode_RLE ? 8 : 0 );
571
572 // Color Map Specification Field 4 ( 5 bytes )
573 header.first_entry_index = 0;
574 header.color_map_length = 0;
575 header.color_map_entry_size = 0;
576
577 // Image Specification Field 4 ( 10 bytes )
578 header.x_origin = 0;
579 header.y_origin = 0;
580 header.image_width = static_cast< unsigned short >( width );
581 header.image_height = static_cast< unsigned short >( height );
582 header.pixel_depth = static_cast< unsigned char >( tga_bits );
583 header.image_descriptor = ( is_encode_RLE ? 0x08 : 0 ) | ( from_top ? 0x20 : 0 ) | ( from_left ? 0 : 0x10 );
584
585 unsigned char *image_data = tga + _tga_header_::bytes;
586
587 unsigned char *pixels = image_data + ( from_top ? 0 : width * ( height - 1 ) * pixel_bytes );
588
589 difference_type line_skip = from_top ? width * pixel_bytes : - width * pixel_bytes;
590 difference_type pixel_skip = from_left ? pixel_bytes : - pixel_bytes;
591
592 difference_type i, j;
593 for( j = 0 ; j < height ; j++ )
594 {
595 unsigned char *pixel = pixels + line_skip * j + ( from_left ? 0 : pixel_bytes ) * ( width - 1 );
596
597 switch( header.pixel_depth )
598 {
599 case 16:
600 for( i = 0 ; i < width ; i++ )
601 {
602 color_type c = limits_0_255( pixel_converter::convert_from( image( i, j ) ) );
603 unsigned short &pix = reinterpret_cast< unsigned short * >( pixel + pixel_skip * i )[ 0 ];
604 unsigned short a = ( ( c.a == 0 ? 0 : 1 ) << 15 ) & 0x8000;
605 unsigned short r = ( static_cast< unsigned char >( c.r / 8 ) << 10 ) & 0x7c00;
606 unsigned short g = ( static_cast< unsigned char >( c.g / 8 ) << 5 ) & 0x03e0;
607 unsigned short b = static_cast< unsigned char >( c.b / 8 ) & 0x001f;
608 pix = a | r | g | b;
609 }
610 break;
611
612 case 24:
613 for( i = 0 ; i < width ; i++ )
614 {
615 color_type c = limits_0_255( pixel_converter::convert_from( image( i, j ) ) );
616 unsigned char *pix = pixel + pixel_skip * i;
617 pix[ 0 ] = static_cast< unsigned char >( c.b );
618 pix[ 1 ] = static_cast< unsigned char >( c.g );
619 pix[ 2 ] = static_cast< unsigned char >( c.r );
620 }
621 break;
622
623 case 32:
624 for( i = 0 ; i < width ; i++ )
625 {
626 color_type c = limits_0_255( pixel_converter::convert_from( image( i, j ) ) );
627 unsigned char *pix = pixel + pixel_skip * i;
628 pix[ 0 ] = static_cast< unsigned char >( c.b );
629 pix[ 1 ] = static_cast< unsigned char >( c.g );
630 pix[ 2 ] = static_cast< unsigned char >( c.r );
631 pix[ 3 ] = static_cast< unsigned char >( c.a );
632 }
633 break;
634
635 default:
636 break;
637 }
638 }
639
640 if( is_encode_RLE )
641 {
642 // RLEエンコードを行う
643 // 失敗したら，無圧縮に変更する
644 difference_type nbytes = encode_RLE( image_data, width * height * pixel_bytes, pixel_bytes );
645
646 if( nbytes == width * height * pixel_bytes )
647 {
648 header.image_type = 2;
649 header.image_descriptor = ( from_top ? 0x20 : 0 ) | ( from_left ? 0 : 0x10 );
650 }
651
652 return( _tga_header_::bytes + nbytes );
653 }
654 else
655 {
656 return( _tga_header_::bytes + width * height * pixel_bytes );
657 }
658 }
659
660 static bool read( array2< T, Allocator > &image, const std::string &filename )
661 {
662 typedef typename array2< T, Allocator >::size_type size_type;
663
664 size_type filesize;
665 FILE *fp;
666 if( ( fp = fopen( filename.c_str( ), "rb" ) ) == NULL ) return( false );
667
668 // ファイルサイズを取得
669 fseek( fp, 0, SEEK_END );
670 filesize = ftell( fp );
671 fseek( fp, 0, SEEK_SET );
672
673 unsigned char *buff = new unsigned char[ filesize + 1 ];
674 unsigned char *pointer = buff;
675 size_type read_size = 0;
676 while( feof( fp ) == 0 )
677 {
678 read_size = fread( pointer, sizeof( unsigned char ), 1024, fp );
679 if( read_size < 1024 )
680 {
681 break;
682 }
683 pointer += read_size;
684 }
685 fclose( fp );
686
687 bool ret = convert_from_tga_data( buff, filesize, image );
688 delete [] buff;
689 return( ret );
690 }
691
692 static bool write( const array2< T, Allocator > &image, const std::string &filename, size_type tga_bits, bool is_encode_RLE )
693 {
694 typedef typename array2< T, Allocator >::size_type size_type;
695
696 if( image.width( ) == 0 )
697 {
698 std::cerr << "Image width is zero!" << std::endl;
699 return( false );
700 }
701 else if( image.height( ) == 0 )
702 {
703 std::cerr << "Image height is zero!" << std::endl;
704 return( false );
705 }
706 else if( !is_supported( tga_bits ) )
707 {
708 std::cerr << "This format is not supported currently!" << std::endl;
709 return( false );
710 }
711
712 unsigned char *buff = NULL;
713 difference_type size = convert_to_tga_data( image, buff, tga_bits, is_encode_RLE, true, true );
714
715 if( size <= 0 )
716 {
717 delete [] buff;
718 return( false );
719 }
720
721 FILE *fp;
722 if( ( fp = fopen( filename.c_str( ), "wb" ) ) == NULL )
723 {
724 delete [] buff;
725 return( false );
726 }
727
728
729 // ファイルへ書き出し
730 unsigned char *pointer = buff;
731 size_type write_size = 0, writed_size = 0;
732 while( size > 0 )
733 {
734 write_size = size < 1024 ? size : 1024;
735
736 writed_size = fwrite( pointer, sizeof( unsigned char ), write_size, fp );
737 pointer += writed_size;
738 size -= writed_size;
739 if( write_size != writed_size )
740 {
741 fclose( fp );
742 delete [] buff;
743 return( false );
744 }
745 }
746 fclose( fp );
747
748 delete [] buff;
749 return( true );
750 }
751 };
752 }
753
756
769
770
781 template < class T, class Allocator >
782 bool read_tga( array2< T, Allocator > &image, const std::string &filename )
783 {
784 return( __tga_controller__::tga_controller< T, Allocator >::read( image, filename ) );
785 }
786
787
798 template < class T, class Allocator >
799 bool read_tga( array2< T, Allocator > &image, const std::wstring &filename )
800 {
801 return( read_tga( image, wstr2str( filename ) ) );
802 }
803
804
819 template < class T, class Allocator >
820 bool write_tga( const array2< T, Allocator > &image, const std::string &filename, typename array2< T, Allocator >::size_type tga_bits = 32, bool is_encode_RLE = true )
821 {
822 return( __tga_controller__::tga_controller< T, Allocator >::write( image, filename, tga_bits, is_encode_RLE ) );
823 }
824
825
840 template < class T, class Allocator >
841 bool write_tga( const array2< T, Allocator > &image, const std::wstring &filename, typename array2< T, Allocator >::size_type tga_bits = 32, bool is_encode_RLE = true )
842 {
843 return( write_tga( image, wstr2str( filename ), tga_bits, is_encode_RLE ) );
844 }
845
847 // TGA 画像入出力グループの終わり
848
850 // 画像入出力グループの終わり
851
852
853 // mist名前空間の終わり
854 _MIST_END
855
856
857 #endif // __INCLUDE_MIST_TGA__
858