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名前空間の始まり
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  // 上位ビットが1のとき反復。次に続くデータバイト(ピクセルのバイト数を単位として)を繰り返す。
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 

Generated on Wed Nov 12 2014 19:44:25 for MIST by doxygen 1.8.1.2