8 #if !defined(__STDC_LIMIT_MACROS)
9 #define __STDC_LIMIT_MACROS
12 #ifdef HAVE_SYS_TYPES_H
13 #include <sys/types.h>
19 #include <tdetempfile.h>
21 #include <tqcstring.h>
28 #include <jasper/jasper.h>
32 #define DEFAULT_RATE 0.10
39 int cmptlut[MAXCMPTS];
41 jas_image_t* altimage;
46 read_image(
const TQImageIO* io )
53 if( ( qf =
dynamic_cast<TQFile*
>( io->ioDevice() ) ) ) {
55 in = jas_stream_fopen( TQFile::encodeName( qf->name() ),
"rb" );
58 tempf =
new KTempFile();
59 if( tempf->status() != 0 ) {
63 tempf->setAutoDelete(
true );
64 TQFile* out = tempf->file();
66 TQByteArray b( 4096 );
69 while( ( size = io->ioDevice()->readBlock( b.data(), 4096 ) ) > 0 ) {
71 if( ( out->writeBlock( b.data(), size ) ) == -1 )
break;
76 in = jas_stream_fopen( TQFile::encodeName( tempf->name() ),
"rb" );
83 jas_image_t* image = jas_image_decode( in, -1, 0 );
84 jas_stream_close( in );
92 convert_colorspace( gs_t& gs )
94 jas_cmprof_t *outprof = jas_cmprof_createfromclrspc( JAS_CLRSPC_SRGB );
95 if( !outprof )
return false;
97 gs.altimage = jas_image_chclrspc( gs.image, outprof,
98 JAS_CMXFORM_INTENT_PER );
99 if( !gs.altimage )
return false;
105 render_view( gs_t& gs, TQImage& qti )
107 if((gs.cmptlut[0] = jas_image_getcmptbytype(gs.altimage,
108 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R))) < 0 ||
109 (gs.cmptlut[1] = jas_image_getcmptbytype(gs.altimage,
110 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G))) < 0 ||
111 (gs.cmptlut[2] = jas_image_getcmptbytype(gs.altimage,
112 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B))) < 0) {
116 const int* cmptlut = gs.cmptlut;
120 const int width = jas_image_cmptwidth( gs.altimage, cmptlut[0] );
121 const int height = jas_image_cmptheight( gs.altimage, cmptlut[0] );
122 for(
int i = 1; i < 3; ++i ) {
123 if (jas_image_cmptwidth( gs.altimage, cmptlut[i] ) != width ||
124 jas_image_cmptheight( gs.altimage, cmptlut[i] ) != height)
128 if( !qti.create( jas_image_width( gs.altimage ),
129 jas_image_height( gs.altimage ), 32 ) )
132 uint32_t* data = (uint32_t*)qti.bits();
134 for(
int y = 0; y < height; ++y ) {
135 for(
int x = 0; x < width; ++x ) {
136 for(
int k = 0; k < 3; ++k ) {
137 v[k] = jas_image_readcmptsample( gs.altimage, cmptlut[k], x, y );
140 v[k] <<= 8 - jas_image_cmptprec( gs.altimage, cmptlut[k] );
142 if( v[k] < 0 ) v[k] = 0;
143 else if( v[k] > 255 ) v[k] = 255;
146 *data++ = tqRgb( v[0], v[1], v[2] );
152 static bool initializeJasper()
154 #if defined(JAS_VERSION_MAJOR) && (JAS_VERSION_MAJOR >= 3)
158 size_t memoryLimit = (512 * 1024) * 1024;
159 size_t jasperTotalMemory = jas_get_total_mem_size();
160 if (!jasperTotalMemory)
162 jasperTotalMemory = JAS_DEFAULT_MAX_MEM_USAGE;
164 memoryLimit = memoryLimit < jasperTotalMemory ? memoryLimit : jasperTotalMemory;
165 jas_conf_set_max_mem_usage(memoryLimit);
167 if (jas_init_library())
172 if (jas_init_thread())
174 jas_cleanup_library();
188 static void cleanupJasper()
190 #if defined(JAS_VERSION_MAJOR) && (JAS_VERSION_MAJOR >= 3)
191 jas_cleanup_thread();
192 jas_cleanup_library();
199 kimgio_jp2_read( TQImageIO* io )
201 if (!initializeJasper())
203 kdError(399) <<
"Failed to initialize JasPer library" << endl;
208 gs.image = read_image(io);
212 kdError(399) <<
"Failed to read JP2 image from IO." << endl;
217 if (!convert_colorspace(gs))
219 kdError(399) <<
"Could not convert JP2 colorspace." << endl;
225 render_view( gs, image );
227 if( gs.image ) jas_image_destroy( gs.image );
228 if( gs.altimage ) jas_image_destroy( gs.altimage );
232 io->setImage( image );
238 create_image(
const TQImage& qi )
241 jas_image_cmptparm_t* cmptparms =
new jas_image_cmptparm_t[ 3 ];
243 for (
int i = 0; i < 3; ++i ) {
245 cmptparms[i].tlx = 0;
246 cmptparms[i].tly = 0;
249 cmptparms[i].hstep = 1;
250 cmptparms[i].vstep = 1;
251 cmptparms[i].width = qi.width();
252 cmptparms[i].height = qi.height();
255 cmptparms[i].prec = 8;
256 cmptparms[i].sgnd =
false;
259 jas_image_t* ji = jas_image_create( 3 , cmptparms, JAS_CLRSPC_UNKNOWN );
268 write_components( jas_image_t* ji,
const TQImage& qi )
270 const unsigned height = qi.height();
271 const unsigned width = qi.width();
273 jas_matrix_t* m = jas_matrix_create( height, width );
274 if( !m )
return false;
276 jas_image_setclrspc( ji, JAS_CLRSPC_SRGB );
278 jas_image_setcmpttype( ji, 0, JAS_IMAGE_CT_RGB_R );
279 for( uint y = 0; y < height; ++y )
280 for( uint x = 0; x < width; ++x )
281 jas_matrix_set( m, y, x, tqRed( qi.pixel( x, y ) ) );
282 jas_image_writecmpt( ji, 0, 0, 0, width, height, m );
284 jas_image_setcmpttype( ji, 1, JAS_IMAGE_CT_RGB_G );
285 for( uint y = 0; y < height; ++y )
286 for( uint x = 0; x < width; ++x )
287 jas_matrix_set( m, y, x, tqGreen( qi.pixel( x, y ) ) );
288 jas_image_writecmpt( ji, 1, 0, 0, width, height, m );
290 jas_image_setcmpttype( ji, 2, JAS_IMAGE_CT_RGB_B );
291 for( uint y = 0; y < height; ++y )
292 for( uint x = 0; x < width; ++x )
293 jas_matrix_set( m, y, x, tqBlue( qi.pixel( x, y ) ) );
294 jas_image_writecmpt( ji, 2, 0, 0, width, height, m );
295 jas_matrix_destroy( m );
301 kimgio_jp2_write( TQImageIO* io )
303 if (!initializeJasper())
305 kdError(399) <<
"Failed to initialize JasPer library." << endl;
311 jas_stream_t* stream = 0;
314 KTempFile* ktempf = 0;
315 if( ( qf =
dynamic_cast<TQFile*
>( io->ioDevice() ) ) ) {
317 stream = jas_stream_fdopen( dup( qf->handle() ),
"w" );
319 ktempf =
new KTempFile;
320 ktempf->setAutoDelete(
true );
321 stream = jas_stream_fdopen( dup( ktempf->handle()),
"w" );
329 <<
"Failed to create a stream to write JP2 image" << endl;
334 jas_image_t* ji = create_image( io->image() );
337 jas_stream_close( stream );
342 if( !write_components( ji, io->image() ) ) {
344 jas_stream_close( stream );
345 jas_image_destroy( ji );
355 TQTextStream ts( &rate, IO_WriteOnly );
357 << ( (io->quality() < 0) ? DEFAULT_RATE : io->quality() / 100.0F );
358 # if defined(JAS_VERSION_MAJOR) && (JAS_VERSION_MAJOR >= 3)
359 const jas_image_fmtinfo_t *jp2_fmtinfo = jas_image_lookupfmtbyname(
"jp2");
363 i = jas_image_encode(ji, stream, jp2_fmtinfo->id, rate.utf8().data());
366 int i = jp2_encode( ji, stream, rate.utf8().data() );
369 jas_image_destroy( ji );
370 jas_stream_close( stream );
373 if( i != 0 ) {
delete ktempf;
return; }
377 TQFile* in = ktempf->file();
379 TQByteArray b( 4096 );
383 if( !in->at( 0 ) ) {
delete ktempf;
return; }
386 while( ( size = in->readBlock( b.data(), 4096 ) ) > 0 ) {
387 if( ( io->ioDevice()->writeBlock( b.data(), size ) ) == -1 ) {
392 io->ioDevice()->flush();
396 if( size == -1 )
return;
401 io->setStatus( IO_Ok );