jpeg.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_JPEG__
37 #define __INCLUDE_MIST_JPEG__
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 
58 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
59 
60  #define XMD_H
61  #define HAVE_INT32 // JPEG用INT32型を持っている宣言
62  #define HAVE_BOOLEAN // JPEG用boolean型を持っている宣言
63 
64 #endif
65 
66 extern "C"
67 {
68 #include <jpeglib.h>
69 }
70 
71 
72 // mist名前空間の始まり
74 
75 
76 namespace __jpeg_controller__
77 {
78  template < class T, class Allocator >
79  struct jpeg_controller
80  {
81  typedef _pixel_converter_< T > pixel_converter;
82  typedef typename pixel_converter::color_type color_type;
83 
84  static bool read( array2< T, Allocator > &image, const std::string &filename )
85  {
86  FILE *fin; // 読み書き用ファイルポインター
87  fin = fopen( filename.c_str( ), "rb" );
88  if( fin == NULL ) return( false );
89 
90  JDIMENSION i, j;
91  JSAMPROW bitmap[1]; // ビットマップデータ配列へのポインター
92  jpeg_decompress_struct dinfo; // JPEG解凍情報構造体
93  jpeg_error_mgr jerr; // JPEGエラー処理用構造体
94  int scanlen; // ビットマップ1行のバイト数
95 
96  dinfo.err = jpeg_std_error( &jerr );
97  jpeg_create_decompress( &dinfo );
98 
99  //jpeg_stdio_src(&dinfo, fin, 0);
100  jpeg_stdio_src( &dinfo, fin );
101 
102  int n = jpeg_read_header( &dinfo, true );
103  if( n < 1 )
104  {
105  jpeg_destroy_decompress( &dinfo );
106  return(false);
107  }
108 
109  jpeg_start_decompress( &dinfo );
110  scanlen = dinfo.output_width * dinfo.output_components;
111 
112  image.resize( dinfo.output_width, dinfo.output_height );
113 
114  JSAMPLE *buffer = new JSAMPLE[ scanlen ];
115  for( j = 0 ; j < dinfo.output_height ; j++ )
116  {
117  bitmap[0] = &buffer[0];
118  if( dinfo.output_scanline < dinfo.output_height ) jpeg_read_scanlines( &dinfo, bitmap, 1 );
119  for( i = 0 ; i < dinfo.output_width ; i++ )
120  {
121  switch( dinfo.output_components )
122  {
123  case 1:
124  image( i, j ) = pixel_converter::convert_to( buffer[ i ], buffer[ i ], buffer[ i ] );
125  break;
126 
127  case 3:
128  image( i, j ) = pixel_converter::convert_to( buffer[ i * 3 + 0 ], buffer[ i * 3 + 1 ], buffer[ i * 3 + 2 ] );
129  break;
130 
131  default:
132  break;
133  }
134  }
135  }
136 
137  jpeg_finish_decompress( &dinfo );
138 
139  fclose( fin );
140  delete [] buffer;
141 
142  jpeg_destroy_decompress( &dinfo );
143 
144  return( true );
145  }
146 
147  static bool write( const array2< T, Allocator > &image, const std::string &filename, int quality )
148  {
149  if( image.width( ) == 0 )
150  {
151  std::cerr << "Image width is zero!" << std::endl;
152  return( false );
153  }
154  else if( image.height( ) == 0 )
155  {
156  std::cerr << "Image height is zero!" << std::endl;
157  return( false );
158  }
159 
160  FILE *fout; // 読み書き用ファイルポインター
161  fout = fopen( filename.c_str( ), "wb" );
162  if( fout == NULL ) return( false );
163 
164  JDIMENSION i, j;
165  JDIMENSION w = static_cast< JDIMENSION >( image.width( ) ), h = static_cast< JDIMENSION >( image.height( ) );
166  JSAMPROW bitmap[1]; /* pointer to JSAMPLE row[s] */
167  jpeg_compress_struct cinfo; // JPEG解凍情報構造体
168  jpeg_error_mgr jerr; // JPEGエラー処理用構造体
169  //int linelen; // ビットマップ1行の正味バイト数
170  int scanlen = w * 3; // ビットマップ1行のバイト数
171 
172  cinfo.err = jpeg_std_error( &jerr );
173  jpeg_create_compress( &cinfo );
174  //jpeg_stdio_dest(&cinfo, fout, 0);
175  jpeg_stdio_dest( &cinfo, fout );
176  cinfo.image_width = w;
177  cinfo.image_height = h;
178  cinfo.input_components = 3;
179  cinfo.in_color_space = JCS_RGB;
180  jpeg_set_defaults( &cinfo );
181  jpeg_set_quality( &cinfo, quality, true );
182  jpeg_start_compress( &cinfo, true );
183 
184  JSAMPLE *buffer = new JSAMPLE[ w * h * 3 ];
185  JSAMPLE *p = buffer;
186 
187  for( j = 0 ; j < h ; j++ )
188  {
189  for( i = 0 ; i < w ; i++ )
190  {
191  color_type c = limits_0_255( pixel_converter::convert_from( image( i, j ) ) );
192  *p++ = static_cast< JSAMPLE >( c.r );
193  *p++ = static_cast< JSAMPLE >( c.g );
194  *p++ = static_cast< JSAMPLE >( c.b );
195  }
196  }
197 
198  while( cinfo.next_scanline < cinfo.image_height )
199  {
200  bitmap[0] = &buffer[ cinfo.next_scanline * scanlen ];
201  jpeg_write_scanlines( &cinfo, bitmap, 1 );
202  }
203 
204  jpeg_finish_compress( &cinfo );
205 
206  fclose( fout );
207  delete [] buffer;
208 
209  jpeg_destroy_compress( &cinfo );
210 
211  return( true );
212  }
213  };
214 }
215 
216 
219 
231 
232 
243 template < class T, class Allocator >
244 bool read_jpeg( array2< T, Allocator > &image, const std::string &filename )
245 {
246  return( __jpeg_controller__::jpeg_controller< T, Allocator >::read( image, filename ) );
247 }
248 
249 
260 template < class T, class Allocator >
261 bool read_jpeg( array2< T, Allocator > &image, const std::wstring &filename )
262 {
263  return( read_jpeg( image, wstr2str( filename ) ) );
264 }
265 
266 
278 template < class T, class Allocator >
279 bool write_jpeg( const array2< T, Allocator > &image, const std::string &filename, int quality = 100 )
280 {
281  return( __jpeg_controller__::jpeg_controller< T, Allocator >::write( image, filename, quality ) );
282 }
283 
284 
296 template < class T, class Allocator >
297 bool write_jpeg( const array2< T, Allocator > &image, const std::wstring &filename, int quality = 100 )
298 {
299  return( write_jpeg( image, wstr2str( filename ), quality ) );
300 }
301 
302 
304 // JPEG 画像入出力グループの終わり
305 
307 // 画像入出力グループの終わり
308 
309 
310 // mist名前空間の終わり
311 _MIST_END
312 
313 
314 #endif // __INCLUDE_MIST_JPEG__
315 

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