36 #ifndef __INCLUDE_MIST_JPEG2000__
37 #define __INCLUDE_MIST_JPEG2000__
40 #ifndef __INCLUDE_MIST_H__
45 #ifndef __INCLUDE_MIST_COLOR_H__
46 #include "../config/color.h"
49 #ifndef __INCLUDE_MIST_LIMITS__
50 #include "../limits.h"
71 namespace __jpeg2000_controller__
74 struct _create_opj_image_
77 template <
class T,
class Allocator >
78 static opj_image_t *create(
const array2< T, Allocator > &image,
const opj_cparameters_t ¶m )
80 opj_image_cmptparm_t cmptparm[ 1 ];
82 memset( cmptparm, 0, 1 *
sizeof( opj_image_cmptparm_t ) );
85 for(
size_t i = 0 ; i < 1 ; i++ )
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( ) );
97 opj_image_t *img = opj_image_create( 1, cmptparm, CLRSPC_GRAY );
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;
106 for(
size_t i = 0 ; i < image.size( ) ; i++ )
108 img->comps[ 0 ].data[ i ] =
static_cast< int >( image[ i ] );
116 struct _create_opj_image_< true >
119 template <
class T,
class Allocator >
120 static opj_image_t *create(
const array2< T, Allocator > &image,
const opj_cparameters_t ¶m )
122 opj_image_cmptparm_t cmptparm[ 3 ];
124 memset( cmptparm, 0, 3 *
sizeof( opj_image_cmptparm_t ) );
127 for(
size_t i = 0 ; i < 3 ; i++ )
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( ) );
139 opj_image_t *img = opj_image_create( 3, cmptparm, CLRSPC_SRGB );
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;
148 for(
size_t i = 0 ; i < image.size( ) ; i++ )
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 );
159 inline std::string to_lower_case(
const std::string &str )
162 for( std::string::size_type i = 0 ; i < str.size( ) ; i++ )
164 s +=
static_cast< char >( tolower( str[ i ] ) );
169 inline std::string get_ext(
const std::string &str )
171 std::string::size_type index = str.rfind(
'.' );
172 if( index == str.npos )
176 return( str.substr( index ) );
179 template <
class T,
class Allocator >
180 struct jpeg2000_controller
182 typedef _pixel_converter_< T > pixel_converter;
183 typedef typename pixel_converter::color_type color_type;
185 static bool read( array2< T, Allocator > &image,
const std::string &filename )
187 typedef typename array2< T, Allocator >::size_type size_type;
188 typedef typename array2< T, Allocator >::difference_type difference_type;
191 FILE *fp = fopen( filename.c_str( ),
"rb" );
194 std::cerr <<
"Can't open file " << filename << std::endl;
199 fseek( fp, 0, SEEK_END );
200 size_type filesize = ftell( fp );
201 fseek( fp, 0, SEEK_SET );
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 )
209 read_size = fread( pointer,
sizeof(
unsigned char ), 1024, fp );
210 if( read_size < 1024 )
214 pointer += read_size;
221 std::string ext = to_lower_case( get_ext( filename ) );
222 OPJ_CODEC_FORMAT codec;
227 else if( ext ==
".j2k" || ext ==
".j2c" )
231 else if( ext ==
".jpt" )
237 opj_dparameters_t param;
240 opj_set_default_decoder_parameters( ¶m );
244 opj_dinfo_t *dinfo = opj_create_decompress( codec );
247 opj_event_mgr_t event_mgr;
248 memset( &event_mgr, 0,
sizeof( opj_event_mgr_t ) );
252 opj_set_event_mgr( (opj_common_ptr)dinfo, &event_mgr, stderr );
255 opj_setup_decoder( dinfo, ¶m );
258 opj_cio_t *cio = opj_cio_open( ( opj_common_ptr )dinfo, buff, static_cast< int >( filesize ) );
261 opj_image_t *img = opj_decode( dinfo, cio );
264 std::cerr <<
"Failed to read JPEG2000 image from " << filename << std::endl;
266 opj_destroy_decompress( dinfo );
267 opj_cio_close( cio );
278 if( img->numcomps != 1 && img->numcomps != 3 )
281 opj_destroy_decompress( dinfo );
282 opj_cio_close( cio );
284 std::cerr <<
"Invalid image is loaded." << std::endl;
290 image.resize( img->comps[ 0 ].w, img->comps[ 0 ].h );
292 if( img->numcomps == 1 )
294 for( size_type i = 0 ; i < image.size( ) ; i++ )
296 int pix = img->comps[ 0 ].data[ i ];
297 image[ i ] = pixel_converter::convert_to( pix, pix, pix );
302 for( size_type i = 0 ; i < image.size( ) ; i++ )
304 image[ i ] = pixel_converter::convert_to( img->comps[ 0 ].data[ i ], img->comps[ 1 ].data[ i ], img->comps[ 2 ].data[ i ] );
310 opj_cio_close( cio );
311 opj_destroy_decompress( dinfo );
312 opj_image_destroy( img );
317 static bool write(
const array2< T, Allocator > &image,
const std::string &filename,
double compression_level )
319 typedef typename array2< T, Allocator >::size_type size_type;
320 typedef typename array2< T, Allocator >::difference_type difference_type;
322 if( image.width( ) == 0 )
324 std::cerr <<
"Image width is zero!" << std::endl;
327 else if( image.height( ) == 0 )
329 std::cerr <<
"Image height is zero!" << std::endl;
334 opj_cparameters_t param;
337 opj_set_default_encoder_parameters( ¶m );
341 param.tcp_rates[ 0 ] =
static_cast< float >( compression_level );
342 param.tcp_numlayers = 1;
343 param.cp_disto_alloc = 1;
346 static char comment[] =
"Created by MIST with OpenJPEG Library";
347 param.cp_comment = comment;
350 opj_image_t *img = _create_opj_image_< is_color< T >::value >::create( image, param );
353 param.tcp_mct = img->numcomps == 3 ? 1 : 0;
356 opj_event_mgr_t event_mgr;
357 memset( &event_mgr, 0,
sizeof( opj_event_mgr_t ) );
363 opj_cinfo_t * cinfo = opj_create_compress( CODEC_JP2 );
366 opj_set_event_mgr( ( opj_common_ptr )cinfo, &event_mgr, stderr );
369 opj_setup_encoder( cinfo, ¶m, img );
372 opj_cio_t *cio = opj_cio_open( ( opj_common_ptr )cinfo, NULL, 0 );
375 if( !opj_encode( cinfo, cio, img, NULL ) )
377 opj_cio_close( cio );
378 opj_destroy_compress( cinfo );
379 opj_image_destroy( img );
386 difference_type codestream_length = cio_tell( cio );
389 FILE *fp = fopen( filename.c_str( ),
"wb" );
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;
402 unsigned char *pointer = cio->buffer;
403 while( codestream_length > 0 )
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;
414 opj_cio_close( cio );
415 opj_destroy_compress( cinfo );
416 opj_image_destroy( img );
450 template <
class T,
class Allocator >
453 return( __jpeg2000_controller__::jpeg2000_controller< T, Allocator >::read( image, filename ) );
467 template <
class T,
class Allocator >
485 template <
class T,
class Allocator >
488 return( __jpeg2000_controller__::jpeg2000_controller< T, Allocator >::write( image, filename, compression_level ) );
503 template <
class T,
class Allocator >
521 #endif // __INCLUDE_MIST_JPEG2000__