1 /*M/////////////////////////////////////////////////////////////////////////////////////// 2 // 3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4 // 5 // By downloading, copying, installing or using the software you agree to this license. 6 // If you do not agree to this license, do not download, install, 7 // copy or use the software. 8 // 9 // 10 // Intel License Agreement 11 // For Open Source Computer Vision Library 12 // 13 // Copyright (C) 2000, Intel Corporation, all rights reserved. 14 // Third party copyrights are property of their respective owners. 15 // 16 // Redistribution and use in source and binary forms, with or without modification, 17 // are permitted provided that the following conditions are met: 18 // 19 // * Redistribution's of source code must retain the above copyright notice, 20 // this list of conditions and the following disclaimer. 21 // 22 // * Redistribution's in binary form must reproduce the above copyright notice, 23 // this list of conditions and the following disclaimer in the documentation 24 // and/or other materials provided with the distribution. 25 // 26 // * The name of Intel Corporation may not be used to endorse or promote products 27 // derived from this software without specific prior written permission. 28 // 29 // This software is provided by the copyright holders and contributors "as is" and 30 // any express or implied warranties, including, but not limited to, the implied 31 // warranties of merchantability and fitness for a particular purpose are disclaimed. 32 // In no event shall the Intel Corporation or contributors be liable for any direct, 33 // indirect, incidental, special, exemplary, or consequential damages 34 // (including, but not limited to, procurement of substitute goods or services; 35 // loss of use, data, or profits; or business interruption) however caused 36 // and on any theory of liability, whether in contract, strict liability, 37 // or tort (including negligence or otherwise) arising in any way out of 38 // the use of this software, even if advised of the possibility of such damage. 39 // 40 //M*/ 41 42 #include "_highgui.h" 43 44 #ifdef HAVE_JASPER 45 46 #include "grfmt_jpeg2000.h" 47 48 // JPEG-2000 Filter Factory 49 GrFmtJpeg2000::GrFmtJpeg2000() 50 { 51 m_sign_len = 12; 52 m_signature = "\x00\x00\x00\x0cjP \r\n\x87\n"; 53 m_description = "JPEG-2000 files (*.jp2)"; 54 jas_init(); 55 } 56 57 58 GrFmtJpeg2000::~GrFmtJpeg2000() 59 { 60 jas_cleanup(); 61 } 62 63 64 GrFmtReader* GrFmtJpeg2000::NewReader( const char* filename ) 65 { 66 return new GrFmtJpeg2000Reader( filename ); 67 } 68 69 70 GrFmtWriter* GrFmtJpeg2000::NewWriter( const char* filename ) 71 { 72 return new GrFmtJpeg2000Writer( filename ); 73 } 74 75 76 /////////////////////// GrFmtJpeg2000Reader /////////////////// 77 78 GrFmtJpeg2000Reader::GrFmtJpeg2000Reader( const char* filename ) : GrFmtReader( filename ) 79 { 80 m_stream = 0; 81 m_image = 0; 82 } 83 84 85 GrFmtJpeg2000Reader::~GrFmtJpeg2000Reader() 86 { 87 } 88 89 90 void GrFmtJpeg2000Reader::Close() 91 { 92 if( m_stream ) 93 { 94 jas_stream_close( m_stream ); 95 m_stream = 0; 96 } 97 98 if( m_image ) 99 { 100 jas_image_destroy( m_image ); 101 m_image = 0; 102 } 103 GrFmtReader::Close(); 104 } 105 106 107 bool GrFmtJpeg2000Reader::ReadHeader() 108 { 109 bool result = false; 110 111 Close(); 112 113 m_stream = jas_stream_fopen( m_filename, "rb" ); 114 if( m_stream ) 115 { 116 m_image = jas_image_decode( m_stream, -1, 0 ); 117 if( m_image ) { 118 m_width = jas_image_width( m_image ); 119 m_height = jas_image_height( m_image ); 120 121 int cntcmpts = 0; // count the known components 122 int numcmpts = jas_image_numcmpts( m_image ); 123 for( int i = 0; i < numcmpts; i++ ) 124 { 125 int depth = jas_image_cmptprec( m_image, i ); 126 if( depth > m_bit_depth ) 127 m_bit_depth = depth; 128 if( m_bit_depth > 8 ) 129 m_bit_depth = 16; 130 131 if( jas_image_cmpttype( m_image, i ) > 2 ) 132 continue; 133 cntcmpts++; 134 } 135 136 if( cntcmpts ) 137 { 138 m_iscolor = (cntcmpts > 1); 139 140 result = true; 141 } 142 } 143 } 144 145 if( !result ) 146 Close(); 147 148 return result; 149 } 150 151 152 bool GrFmtJpeg2000Reader::ReadData( uchar* data, int step, int color ) 153 { 154 bool result = false; 155 156 color = color > 0 || ( m_iscolor && color < 0 ); 157 158 if( m_stream && m_image ) 159 { 160 bool convert; 161 int colorspace; 162 if( color ) 163 { 164 convert = (jas_image_clrspc( m_image ) != JAS_CLRSPC_SRGB); 165 colorspace = JAS_CLRSPC_SRGB; 166 } 167 else 168 { 169 convert = (jas_clrspc_fam( jas_image_clrspc( m_image ) ) != JAS_CLRSPC_FAM_GRAY); 170 colorspace = JAS_CLRSPC_SGRAY; // TODO GENGRAY or SGRAY? 171 } 172 173 // convert to the desired colorspace 174 if( convert ) 175 { 176 jas_cmprof_t *clrprof = jas_cmprof_createfromclrspc( colorspace ); 177 if( clrprof ) 178 { 179 jas_image_t *img = jas_image_chclrspc( m_image, clrprof, JAS_CMXFORM_INTENT_RELCLR ); 180 if( img ) 181 { 182 jas_image_destroy( m_image ); 183 m_image = img; 184 result = true; 185 } 186 else 187 fprintf(stderr, "JPEG 2000 LOADER ERROR: cannot convert colorspace\n"); 188 jas_cmprof_destroy( clrprof ); 189 } 190 else 191 fprintf(stderr, "JPEG 2000 LOADER ERROR: unable to create colorspace\n"); 192 } 193 else 194 result = true; 195 196 if( result ) 197 { 198 int ncmpts; 199 int cmptlut[3]; 200 if( color ) 201 { 202 cmptlut[0] = jas_image_getcmptbytype( m_image, JAS_IMAGE_CT_RGB_B ); 203 cmptlut[1] = jas_image_getcmptbytype( m_image, JAS_IMAGE_CT_RGB_G ); 204 cmptlut[2] = jas_image_getcmptbytype( m_image, JAS_IMAGE_CT_RGB_R ); 205 if( cmptlut[0] < 0 || cmptlut[1] < 0 || cmptlut[0] < 0 ) 206 result = false; 207 ncmpts = 3; 208 } 209 else 210 { 211 cmptlut[0] = jas_image_getcmptbytype( m_image, JAS_IMAGE_CT_GRAY_Y ); 212 if( cmptlut[0] < 0 ) 213 result = false; 214 ncmpts = 1; 215 } 216 217 if( result ) 218 { 219 for( int i = 0; i < ncmpts; i++ ) 220 { 221 int maxval = 1 << jas_image_cmptprec( m_image, cmptlut[i] ); 222 int offset = jas_image_cmptsgnd( m_image, cmptlut[i] ) ? maxval / 2 : 0; 223 224 int yend = jas_image_cmptbry( m_image, cmptlut[i] ); 225 int ystep = jas_image_cmptvstep( m_image, cmptlut[i] ); 226 int xend = jas_image_cmptbrx( m_image, cmptlut[i] ); 227 int xstep = jas_image_cmpthstep( m_image, cmptlut[i] ); 228 229 jas_matrix_t *buffer = jas_matrix_create( yend / ystep, xend / xstep ); 230 if( buffer ) 231 { 232 if( !jas_image_readcmpt( m_image, cmptlut[i], 0, 0, xend / xstep, yend / ystep, buffer )) 233 { 234 if( m_bit_depth == 8 || !m_native_depth ) 235 result = ReadComponent8u( data + i, buffer, step, cmptlut[i], maxval, offset, ncmpts ); 236 else 237 result = ReadComponent16u( ((unsigned short *)data) + i, buffer, step / 2, cmptlut[i], maxval, offset, ncmpts ); 238 if( !result ) 239 { 240 i = ncmpts; 241 result = false; 242 } 243 } 244 jas_matrix_destroy( buffer ); 245 } 246 } 247 } 248 } 249 else 250 fprintf(stderr, "JPEG2000 LOADER ERROR: colorspace conversion failed\n" ); 251 } 252 253 Close(); 254 255 return result; 256 } 257 258 259 bool GrFmtJpeg2000Reader::ReadComponent8u( uchar *data, jas_matrix_t *buffer, 260 int step, int cmpt, 261 int maxval, int offset, int ncmpts ) 262 { 263 int xstart = jas_image_cmpttlx( m_image, cmpt ); 264 int xend = jas_image_cmptbrx( m_image, cmpt ); 265 int xstep = jas_image_cmpthstep( m_image, cmpt ); 266 int xoffset = jas_image_tlx( m_image ); 267 int ystart = jas_image_cmpttly( m_image, cmpt ); 268 int yend = jas_image_cmptbry( m_image, cmpt ); 269 int ystep = jas_image_cmptvstep( m_image, cmpt ); 270 int yoffset = jas_image_tly( m_image ); 271 int x, y, x1, y1, j; 272 int rshift = cvRound(log(maxval/256.)/log(2.)); 273 int lshift = MAX(0, -rshift); 274 rshift = MAX(0, rshift); 275 int delta = (rshift > 0 ? 1 << (rshift - 1) : 0) + offset; 276 277 for( y = 0; y < yend - ystart; ) 278 { 279 jas_seqent_t* pix_row = &jas_matrix_get( buffer, y / ystep, 0 ); 280 uchar* dst = data + (y - yoffset) * step - xoffset; 281 282 if( xstep == 1 ) 283 { 284 if( maxval == 256 && offset == 0 ) 285 for( x = 0; x < xend - xstart; x++ ) 286 { 287 int pix = pix_row[x]; 288 dst[x*ncmpts] = CV_CAST_8U(pix); 289 } 290 else 291 for( x = 0; x < xend - xstart; x++ ) 292 { 293 int pix = ((pix_row[x] + delta) >> rshift) << lshift; 294 dst[x*ncmpts] = CV_CAST_8U(pix); 295 } 296 } 297 else if( xstep == 2 && offset == 0 ) 298 for( x = 0, j = 0; x < xend - xstart; x += 2, j++ ) 299 { 300 int pix = ((pix_row[j] + delta) >> rshift) << lshift; 301 dst[x*ncmpts] = dst[(x+1)*ncmpts] = CV_CAST_8U(pix); 302 } 303 else 304 for( x = 0, j = 0; x < xend - xstart; j++ ) 305 { 306 int pix = ((pix_row[j] + delta) >> rshift) << lshift; 307 pix = CV_CAST_8U(pix); 308 for( x1 = x + xstep; x < x1; x++ ) 309 dst[x*ncmpts] = (uchar)pix; 310 } 311 y1 = y + ystep; 312 for( ++y; y < y1; y++, dst += step ) 313 for( x = 0; x < xend - xstart; x++ ) 314 dst[x*ncmpts + step] = dst[x*ncmpts]; 315 } 316 317 return true; 318 } 319 320 321 bool GrFmtJpeg2000Reader::ReadComponent16u( unsigned short *data, jas_matrix_t *buffer, 322 int step, int cmpt, 323 int maxval, int offset, int ncmpts ) 324 { 325 int xstart = jas_image_cmpttlx( m_image, cmpt ); 326 int xend = jas_image_cmptbrx( m_image, cmpt ); 327 int xstep = jas_image_cmpthstep( m_image, cmpt ); 328 int xoffset = jas_image_tlx( m_image ); 329 int ystart = jas_image_cmpttly( m_image, cmpt ); 330 int yend = jas_image_cmptbry( m_image, cmpt ); 331 int ystep = jas_image_cmptvstep( m_image, cmpt ); 332 int yoffset = jas_image_tly( m_image ); 333 int x, y, x1, y1, j; 334 int rshift = cvRound(log(maxval/65536.)/log(2.)); 335 int lshift = MAX(0, -rshift); 336 rshift = MAX(0, rshift); 337 int delta = (rshift > 0 ? 1 << (rshift - 1) : 0) + offset; 338 339 for( y = 0; y < yend - ystart; ) 340 { 341 jas_seqent_t* pix_row = &jas_matrix_get( buffer, y / ystep, 0 ); 342 ushort* dst = data + (y - yoffset) * step - xoffset; 343 344 if( xstep == 1 ) 345 { 346 if( maxval == 65536 && offset == 0 ) 347 for( x = 0; x < xend - xstart; x++ ) 348 { 349 int pix = pix_row[x]; 350 dst[x*ncmpts] = CV_CAST_16U(pix); 351 } 352 else 353 for( x = 0; x < xend - xstart; x++ ) 354 { 355 int pix = ((pix_row[x] + delta) >> rshift) << lshift; 356 dst[x*ncmpts] = CV_CAST_16U(pix); 357 } 358 } 359 else if( xstep == 2 && offset == 0 ) 360 for( x = 0, j = 0; x < xend - xstart; x += 2, j++ ) 361 { 362 int pix = ((pix_row[j] + delta) >> rshift) << lshift; 363 dst[x*ncmpts] = dst[(x+1)*ncmpts] = CV_CAST_16U(pix); 364 } 365 else 366 for( x = 0, j = 0; x < xend - xstart; j++ ) 367 { 368 int pix = ((pix_row[j] + delta) >> rshift) << lshift; 369 pix = CV_CAST_16U(pix); 370 for( x1 = x + xstep; x < x1; x++ ) 371 dst[x*ncmpts] = (ushort)pix; 372 } 373 y1 = y + ystep; 374 for( ++y; y < y1; y++, dst += step ) 375 for( x = 0; x < xend - xstart; x++ ) 376 dst[x*ncmpts + step] = dst[x*ncmpts]; 377 } 378 379 return true; 380 } 381 382 383 /////////////////////// GrFmtJpeg2000Writer /////////////////// 384 385 386 GrFmtJpeg2000Writer::GrFmtJpeg2000Writer( const char* filename ) : GrFmtWriter( filename ) 387 { 388 } 389 390 391 GrFmtJpeg2000Writer::~GrFmtJpeg2000Writer() 392 { 393 } 394 395 396 bool GrFmtJpeg2000Writer::IsFormatSupported( int depth ) 397 { 398 return depth == IPL_DEPTH_8U || depth == IPL_DEPTH_16U; 399 } 400 401 402 bool GrFmtJpeg2000Writer::WriteImage( const uchar* data, int step, 403 int width, int height, int depth, int channels ) 404 { 405 if( channels > 3 || channels < 1 ) 406 return false; 407 408 jas_image_cmptparm_t component_info[3]; 409 for( int i = 0; i < channels; i++ ) 410 { 411 component_info[i].tlx = 0; 412 component_info[i].tly = 0; 413 component_info[i].hstep = 1; 414 component_info[i].vstep = 1; 415 component_info[i].width = width; 416 component_info[i].height = height; 417 component_info[i].prec = depth; 418 component_info[i].sgnd = 0; 419 } 420 jas_image_t *img = jas_image_create( channels, component_info, (channels == 1) ? JAS_CLRSPC_SGRAY : JAS_CLRSPC_SRGB ); 421 if( !img ) 422 return false; 423 424 if(channels == 1) 425 jas_image_setcmpttype( img, 0, JAS_IMAGE_CT_GRAY_Y ); 426 else 427 { 428 jas_image_setcmpttype( img, 0, JAS_IMAGE_CT_RGB_B ); 429 jas_image_setcmpttype( img, 1, JAS_IMAGE_CT_RGB_G ); 430 jas_image_setcmpttype( img, 2, JAS_IMAGE_CT_RGB_R ); 431 } 432 433 bool result; 434 if( depth == 8 ) 435 result = WriteComponent8u( img, data, step, channels, width, height ); 436 else 437 result = WriteComponent16u( img, (const unsigned short *)data, step / 2, channels, width, height ); 438 if( result ) 439 { 440 jas_stream_t *stream = jas_stream_fopen( m_filename, "wb" ); 441 if( stream ) 442 { 443 result = !jas_image_encode( img, stream, jas_image_strtofmt( "jp2" ), "" ); 444 445 jas_stream_close( stream ); 446 } 447 448 } 449 jas_image_destroy( img ); 450 451 return result; 452 } 453 454 455 bool GrFmtJpeg2000Writer::WriteComponent8u( jas_image_t *img, const uchar *data, 456 int step, int ncmpts, int w, int h ) 457 { 458 jas_matrix_t *row = jas_matrix_create( 1, w ); 459 if(!row) 460 return false; 461 462 for( int y = 0; y < h; y++, data += step ) 463 { 464 for( int i = 0; i < ncmpts; i++ ) 465 { 466 for( int x = 0; x < w; x++) 467 jas_matrix_setv( row, x, data[x * ncmpts + i] ); 468 jas_image_writecmpt( img, i, 0, y, w, 1, row ); 469 } 470 } 471 472 jas_matrix_destroy( row ); 473 474 return true; 475 } 476 477 478 bool GrFmtJpeg2000Writer::WriteComponent16u( jas_image_t *img, const unsigned short *data, 479 int step, int ncmpts, int w, int h ) 480 { 481 jas_matrix_t *row = jas_matrix_create( 1, w ); 482 if(!row) 483 return false; 484 485 for( int y = 0; y < h; y++, data += step ) 486 { 487 for( int i = 0; i < ncmpts; i++ ) 488 { 489 for( int x = 0; x < w; x++) 490 jas_matrix_setv( row, x, data[x * ncmpts + i] ); 491 jas_image_writecmpt( img, i, 0, y, w, 1, row ); 492 } 493 } 494 495 jas_matrix_destroy( row ); 496 497 return true; 498 } 499 500 #endif 501 502 /* End of file. */ 503