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
GrFmtJpeg2000()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
~GrFmtJpeg2000()58 GrFmtJpeg2000::~GrFmtJpeg2000()
59 {
60 jas_cleanup();
61 }
62
63
NewReader(const char * filename)64 GrFmtReader* GrFmtJpeg2000::NewReader( const char* filename )
65 {
66 return new GrFmtJpeg2000Reader( filename );
67 }
68
69
NewWriter(const char * filename)70 GrFmtWriter* GrFmtJpeg2000::NewWriter( const char* filename )
71 {
72 return new GrFmtJpeg2000Writer( filename );
73 }
74
75
76 /////////////////////// GrFmtJpeg2000Reader ///////////////////
77
GrFmtJpeg2000Reader(const char * filename)78 GrFmtJpeg2000Reader::GrFmtJpeg2000Reader( const char* filename ) : GrFmtReader( filename )
79 {
80 m_stream = 0;
81 m_image = 0;
82 }
83
84
~GrFmtJpeg2000Reader()85 GrFmtJpeg2000Reader::~GrFmtJpeg2000Reader()
86 {
87 }
88
89
Close()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
ReadHeader()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
ReadData(uchar * data,int step,int color)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
ReadComponent8u(uchar * data,jas_matrix_t * buffer,int step,int cmpt,int maxval,int offset,int ncmpts)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
ReadComponent16u(unsigned short * data,jas_matrix_t * buffer,int step,int cmpt,int maxval,int offset,int ncmpts)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
GrFmtJpeg2000Writer(const char * filename)386 GrFmtJpeg2000Writer::GrFmtJpeg2000Writer( const char* filename ) : GrFmtWriter( filename )
387 {
388 }
389
390
~GrFmtJpeg2000Writer()391 GrFmtJpeg2000Writer::~GrFmtJpeg2000Writer()
392 {
393 }
394
395
IsFormatSupported(int depth)396 bool GrFmtJpeg2000Writer::IsFormatSupported( int depth )
397 {
398 return depth == IPL_DEPTH_8U || depth == IPL_DEPTH_16U;
399 }
400
401
WriteImage(const uchar * data,int step,int width,int height,int depth,int channels)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
WriteComponent8u(jas_image_t * img,const uchar * data,int step,int ncmpts,int w,int h)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
WriteComponent16u(jas_image_t * img,const unsigned short * data,int step,int ncmpts,int w,int h)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