jpeg2000.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_JPEG2000__
37 #define __INCLUDE_MIST_JPEG2000__
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 extern "C"
58 {
59 #ifndef OPJ_STATIC
60  #define OPJ_STATIC
61 #endif
62 
63 #include <openjpeg.h>
64 }
65 
66 
67 // mist名前空間の始まり
69 
70 
71 namespace __jpeg2000_controller__
72 {
73  template < bool b >
74  struct _create_opj_image_
75  {
76  // グレースケールの画像を作成する
77  template < class T, class Allocator >
78  static opj_image_t *create( const array2< T, Allocator > &image, const opj_cparameters_t &param )
79  {
80  opj_image_cmptparm_t cmptparm[ 1 ];
81 
82  memset( cmptparm, 0, 1 * sizeof( opj_image_cmptparm_t ) );
83 
84  // 各色プレーンの設定を行う
85  for( size_t i = 0 ; i < 1 ; i++ )
86  {
87  cmptparm[ i ].prec = 8;
88  cmptparm[ i ].bpp = 8;
89  cmptparm[ i ].sgnd = 0;
90  cmptparm[ i ].dx = param.subsampling_dx;
91  cmptparm[ i ].dy = param.subsampling_dy;
92  cmptparm[ i ].w = static_cast< int >( image.width( ) );
93  cmptparm[ i ].h = static_cast< int >( image.height( ) );
94  }
95 
96  // カラー画像として作成する
97  opj_image_t *img = opj_image_create( 1, cmptparm, CLRSPC_GRAY );
98 
99  // 画像のオフセットとレンダリンググリッドを設定する
100  img->x0 = param.image_offset_x0;
101  img->y0 = param.image_offset_y0;
102  img->x1 = img->x0 + ( static_cast< int >( image.width( ) ) - 1 ) * param.subsampling_dx + 1;
103  img->y1 = img->y0 + ( static_cast< int >( image.height( ) ) - 1 ) * param.subsampling_dy + 1;
104 
105  // 画像データをコピーする
106  for( size_t i = 0 ; i < image.size( ) ; i++ )
107  {
108  img->comps[ 0 ].data[ i ] = static_cast< int >( image[ i ] );
109  }
110 
111  return( img );
112  }
113  };
114 
115  template < >
116  struct _create_opj_image_< true >
117  {
118  // カラー画像を作成する
119  template < class T, class Allocator >
120  static opj_image_t *create( const array2< T, Allocator > &image, const opj_cparameters_t &param )
121  {
122  opj_image_cmptparm_t cmptparm[ 3 ];
123 
124  memset( cmptparm, 0, 3 * sizeof( opj_image_cmptparm_t ) );
125 
126  // 各色プレーンの設定を行う
127  for( size_t i = 0 ; i < 3 ; i++ )
128  {
129  cmptparm[ i ].prec = 8;
130  cmptparm[ i ].bpp = 8;
131  cmptparm[ i ].sgnd = 0;
132  cmptparm[ i ].dx = param.subsampling_dx;
133  cmptparm[ i ].dy = param.subsampling_dy;
134  cmptparm[ i ].w = static_cast< int >( image.width( ) );
135  cmptparm[ i ].h = static_cast< int >( image.height( ) );
136  }
137 
138  // カラー画像として作成する
139  opj_image_t *img = opj_image_create( 3, cmptparm, CLRSPC_SRGB );
140 
141  // 画像のオフセットとレンダリンググリッドを設定する
142  img->x0 = param.image_offset_x0;
143  img->y0 = param.image_offset_y0;
144  img->x1 = img->x0 + ( static_cast< int >( image.width( ) ) - 1 ) * param.subsampling_dx + 1;
145  img->y1 = img->y0 + ( static_cast< int >( image.height( ) ) - 1 ) * param.subsampling_dy + 1;
146 
147  // 画像データをコピーする
148  for( size_t i = 0 ; i < image.size( ) ; i++ )
149  {
150  img->comps[ 0 ].data[ i ] = static_cast< int >( image[ i ].r );
151  img->comps[ 1 ].data[ i ] = static_cast< int >( image[ i ].g );
152  img->comps[ 2 ].data[ i ] = static_cast< int >( image[ i ].b );
153  }
154 
155  return( img );
156  }
157  };
158 
159  inline std::string to_lower_case( const std::string &str )
160  {
161  std::string s = "";
162  for( std::string::size_type i = 0 ; i < str.size( ) ; i++ )
163  {
164  s += static_cast< char >( tolower( str[ i ] ) );
165  }
166  return( s );
167  }
168 
169  inline std::string get_ext( const std::string &str )
170  {
171  std::string::size_type index = str.rfind( '.' );
172  if( index == str.npos )
173  {
174  return( "" );
175  }
176  return( str.substr( index ) );
177  }
178 
179  template < class T, class Allocator >
180  struct jpeg2000_controller
181  {
182  typedef _pixel_converter_< T > pixel_converter;
183  typedef typename pixel_converter::color_type color_type;
184 
185  static bool read( array2< T, Allocator > &image, const std::string &filename )
186  {
187  typedef typename array2< T, Allocator >::size_type size_type;
188  typedef typename array2< T, Allocator >::difference_type difference_type;
189 
190  // ファイルからデータをすべて読み込む
191  FILE *fp = fopen( filename.c_str( ), "rb" );
192  if( fp == NULL )
193  {
194  std::cerr << "Can't open file " << filename << std::endl;
195  return( false );
196  }
197 
198  // ファイルサイズを取得
199  fseek( fp, 0, SEEK_END );
200  size_type filesize = ftell( fp );
201  fseek( fp, 0, SEEK_SET );
202 
203  // データを少しずつ読み込む
204  unsigned char *buff = new unsigned char[ filesize + 1 ];
205  unsigned char *pointer = buff;
206  size_type read_size = 0;
207  while( feof( fp ) == 0 )
208  {
209  read_size = fread( pointer, sizeof( unsigned char ), 1024, fp );
210  if( read_size < 1024 )
211  {
212  break;
213  }
214  pointer += read_size;
215  }
216 
217  // ファイルを閉じる
218  fclose( fp );
219 
220  // デコーダを決定する
221  std::string ext = to_lower_case( get_ext( filename ) );
222  OPJ_CODEC_FORMAT codec;
223  if( ext == ".jp2" )
224  {
225  codec = CODEC_JP2;
226  }
227  else if( ext == ".j2k" || ext == ".j2c" )
228  {
229  codec = CODEC_J2K;
230  }
231  else if( ext == ".jpt" )
232  {
233  codec = CODEC_JPT;
234  }
235 
236  // OpenJPEGライブラリの圧縮パラメータ
237  opj_dparameters_t param;
238 
239  // デコードパラメータをデフォルトに設定する
240  opj_set_default_decoder_parameters( &param );
241 
242  // デコーダエンジンを初期化する
243  //opj_dinfo_t *dinfo = opj_create_decompress( CODEC_UNKNOWN );
244  opj_dinfo_t *dinfo = opj_create_decompress( codec );
245 
246  // エラーハンドリングの関数を設定する
247  opj_event_mgr_t event_mgr;
248  memset( &event_mgr, 0, sizeof( opj_event_mgr_t ) );
249  //event_mgr.error_handler = error;
250  //event_mgr.warning_handler = warning;
251  //event_mgr.info_handler = info;
252  opj_set_event_mgr( (opj_common_ptr)dinfo, &event_mgr, stderr );
253 
254  // デコーダにパラメータを設定する
255  opj_setup_decoder( dinfo, &param );
256 
257  // デコード用のメモリストリームを準備する
258  opj_cio_t *cio = opj_cio_open( ( opj_common_ptr )dinfo, buff, static_cast< int >( filesize ) );
259 
260  // 画像をデコードする
261  opj_image_t *img = opj_decode( dinfo, cio );
262  if( img == NULL )
263  {
264  std::cerr << "Failed to read JPEG2000 image from " << filename << std::endl;
265 
266  opj_destroy_decompress( dinfo );
267  opj_cio_close( cio );
268 
269  delete [] buff;
270 
271  return( false );
272  }
273  else
274  {
275  delete [] buff;
276  }
277 
278  if( img->numcomps != 1 && img->numcomps != 3 )
279  {
280  // おかしな画像が読み込まれた?
281  opj_destroy_decompress( dinfo );
282  opj_cio_close( cio );
283 
284  std::cerr << "Invalid image is loaded." << std::endl;
285 
286  return( false );
287  }
288 
289  // OpenJPEG ライブラリの画像形式からMISTの形式に変換する
290  image.resize( img->comps[ 0 ].w, img->comps[ 0 ].h );
291 
292  if( img->numcomps == 1 )
293  {
294  for( size_type i = 0 ; i < image.size( ) ; i++ )
295  {
296  int pix = img->comps[ 0 ].data[ i ];
297  image[ i ] = pixel_converter::convert_to( pix, pix, pix );
298  }
299  }
300  else // img->numcomps == 3
301  {
302  for( size_type i = 0 ; i < image.size( ) ; i++ )
303  {
304  image[ i ] = pixel_converter::convert_to( img->comps[ 0 ].data[ i ], img->comps[ 1 ].data[ i ], img->comps[ 2 ].data[ i ] );
305  }
306  }
307 
308 
309  // OpenJPEG ライブラリで使用したリソース等を開放する
310  opj_cio_close( cio );
311  opj_destroy_decompress( dinfo );
312  opj_image_destroy( img );
313 
314  return( true );
315  }
316 
317  static bool write( const array2< T, Allocator > &image, const std::string &filename, double compression_level )
318  {
319  typedef typename array2< T, Allocator >::size_type size_type;
320  typedef typename array2< T, Allocator >::difference_type difference_type;
321 
322  if( image.width( ) == 0 )
323  {
324  std::cerr << "Image width is zero!" << std::endl;
325  return( false );
326  }
327  else if( image.height( ) == 0 )
328  {
329  std::cerr << "Image height is zero!" << std::endl;
330  return( false );
331  }
332 
333  // OpenJPEGライブラリの圧縮パラメータ
334  opj_cparameters_t param;
335 
336  // エンコードパラメータをデフォルトに設定する
337  opj_set_default_encoder_parameters( &param );
338 
339  // 圧縮率を設定する
340  // 0はLossless圧縮
341  param.tcp_rates[ 0 ] = static_cast< float >( compression_level );
342  param.tcp_numlayers = 1;
343  param.cp_disto_alloc = 1;
344 
345  // コメントを埋め込む
346  static char comment[] = "Created by MIST with OpenJPEG Library";
347  param.cp_comment = comment;
348 
349  // OpenJPEGライブラリ内部で使用する画像形式に変換する
350  opj_image_t *img = _create_opj_image_< is_color< T >::value >::create( image, param );
351 
352  // 色のコンポーネントの数を調べる
353  param.tcp_mct = img->numcomps == 3 ? 1 : 0;
354 
355  // エラーハンドリングの関数を設定する
356  opj_event_mgr_t event_mgr;
357  memset( &event_mgr, 0, sizeof( opj_event_mgr_t ) );
358  //event_mgr.error_handler = error;
359  //event_mgr.warning_handler = warning;
360  //event_mgr.info_handler = info;
361 
362  // JPEG2000の圧縮エンジンを初期化する
363  opj_cinfo_t * cinfo = opj_create_compress( CODEC_JP2 );
364 
365  // エラー処理用の関数を設定する
366  opj_set_event_mgr( ( opj_common_ptr )cinfo, &event_mgr, stderr );
367 
368  // JPEG2000 の圧縮エンジンにパラメータと画像を設定する
369  opj_setup_encoder( cinfo, &param, img );
370 
371  // 画像をメモリ上に展開するためのオブジェクトを初期化する
372  opj_cio_t *cio = opj_cio_open( ( opj_common_ptr )cinfo, NULL, 0 );
373 
374  // JPEG2000で画像を圧縮する
375  if( !opj_encode( cinfo, cio, img, NULL ) )
376  {
377  opj_cio_close( cio );
378  opj_destroy_compress( cinfo );
379  opj_image_destroy( img );
380 
381  // 圧縮に失敗
382  return( false );
383  }
384 
385  // 圧縮後のデータ長を取得する
386  difference_type codestream_length = cio_tell( cio );
387 
388  // 画像出力用のファイルポインタを作成する
389  FILE *fp = fopen( filename.c_str( ), "wb" );
390 
391  if( fp == NULL )
392  {
393  // 画像を作成することができなかった・・・
394  opj_cio_close( cio );
395  opj_destroy_compress( cinfo );
396  opj_image_destroy( img );
397  std::cerr << "Failed to write image to " << filename << std::endl;
398  return( false );
399  }
400 
401  // 画像データをファイルに少しずつ書き出す
402  unsigned char *pointer = cio->buffer;
403  while( codestream_length > 0 )
404  {
405  size_type write_size = fwrite( pointer, sizeof( unsigned char ), codestream_length > 1024 ? 1024 : codestream_length, fp );
406  pointer += write_size;
407  codestream_length -= write_size;
408  }
409 
410  // ファイルを閉じる
411  fclose( fp );
412 
413  // OpenJPEG ライブラリで使用したリソース等を開放する
414  opj_cio_close( cio );
415  opj_destroy_compress( cinfo );
416  opj_image_destroy( img );
417 
418  return( true );
419  }
420  };
421 }
422 
423 
426 
438 
439 
450 template < class T, class Allocator >
451 bool read_jpeg2000( array2< T, Allocator > &image, const std::string &filename )
452 {
453  return( __jpeg2000_controller__::jpeg2000_controller< T, Allocator >::read( image, filename ) );
454 }
455 
456 
467 template < class T, class Allocator >
468 bool read_jpeg2000( array2< T, Allocator > &image, const std::wstring &filename )
469 {
470  return( read_jpeg2000( image, wstr2str( filename ) ) );
471 }
472 
473 
485 template < class T, class Allocator >
486 bool write_jpeg2000( const array2< T, Allocator > &image, const std::string &filename, double compression_level = 0 )
487 {
488  return( __jpeg2000_controller__::jpeg2000_controller< T, Allocator >::write( image, filename, compression_level ) );
489 }
490 
491 
503 template < class T, class Allocator >
504 bool write_jpeg2000( const array2< T, Allocator > &image, const std::wstring &filename, double compression_level = 0 )
505 {
506  return( write_jpeg2000( image, wstr2str( filename ), compression_level ) );
507 }
508 
509 
511 // JPEG2000 画像入出力グループの終わり
512 
514 // 画像入出力グループの終わり
515 
516 
517 // mist名前空間の終わり
518 _MIST_END
519 
520 
521 #endif // __INCLUDE_MIST_JPEG2000__
522 

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