12 #ifdef HAVE_SYS_TYPES_H
13 #include <sys/types.h>
22 #include <QTextStream>
27 #include <jasper/jasper.h>
31 #define DEFAULT_RATE 0.10
42 if (!(stream = (jas_stream_t*)jas_malloc(
sizeof(jas_stream_t)))) {
45 stream->openmode_ = 0;
49 stream->bufstart_ = 0;
56 stream->rwlimit_ = -1;
67 assert(!stream->bufbase_);
69 if (bufmode != JAS_STREAM_UNBUF) {
74 if ((stream->bufbase_ = (
unsigned char*)jas_malloc(JAS_STREAM_BUFSIZE +
75 JAS_STREAM_MAXPUTBACK))) {
76 stream->bufmode_ |= JAS_STREAM_FREEBUF;
77 stream->bufsize_ = JAS_STREAM_BUFSIZE;
81 stream->bufbase_ = stream->tinybuf_;
88 assert(bufsize > JAS_STREAM_MAXPUTBACK);
89 stream->bufbase_ = JAS_CAST(
uchar *, buf);
90 stream->bufsize_ = bufsize - JAS_STREAM_MAXPUTBACK;
97 stream->bufbase_ = stream->tinybuf_;
100 stream->bufstart_ = &stream->bufbase_[JAS_STREAM_MAXPUTBACK];
101 stream->ptr_ = stream->bufstart_;
103 stream->bufmode_ |= bufmode & JAS_STREAM_BUFMODEMASK;
108 QIODevice *io = (QIODevice*) obj;
109 return io->read(buf, cnt);
114 QIODevice *io = (QIODevice*) obj;
115 return io->write(buf, cnt);
120 QIODevice *io = (QIODevice*) obj;
128 newpos = io->size() - offset;
131 newpos = io->pos() + offset;
139 if ( io->seek(newpos) )
159 jas_stream_t *stream;
161 if ( !iodevice )
return 0;
168 stream->openmode_ = JAS_STREAM_READ | JAS_STREAM_WRITE | JAS_STREAM_BINARY;
173 stream->obj_ = (
void *)iodevice;
186 jas_image_t* altimage;
193 jas_stream_t* in = 0;
199 jas_image_t* image = jas_image_decode( in, -1, 0 );
200 jas_stream_close( in );
209 jas_cmprof_t *outprof = jas_cmprof_createfromclrspc( JAS_CLRSPC_SRGB );
210 if( !outprof )
return false;
212 gs.altimage = jas_image_chclrspc( gs.image, outprof,
213 JAS_CMXFORM_INTENT_PER );
214 if( !gs.altimage )
return false;
222 if ( !gs.altimage )
return false;
224 if((gs.cmptlut[0] = jas_image_getcmptbytype(gs.altimage,
225 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R))) < 0 ||
226 (gs.cmptlut[1] = jas_image_getcmptbytype(gs.altimage,
227 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G))) < 0 ||
228 (gs.cmptlut[2] = jas_image_getcmptbytype(gs.altimage,
229 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B))) < 0) {
233 const int* cmptlut = gs.cmptlut;
237 const int width = jas_image_cmptwidth( gs.altimage, cmptlut[0] );
238 const int height = jas_image_cmptheight( gs.altimage, cmptlut[0] );
239 for(
int i = 1; i < 3; ++i ) {
240 if (jas_image_cmptwidth( gs.altimage, cmptlut[i] ) != width ||
241 jas_image_cmptheight( gs.altimage, cmptlut[i] ) != height)
245 qti = QImage( jas_image_width( gs.altimage ), jas_image_height( gs.altimage ),
246 QImage::Format_RGB32 );
248 uint32_t* data = (uint32_t*)qti.bits();
250 for(
int y = 0; y < height; ++y ) {
251 for(
int x = 0; x < width; ++x ) {
252 for(
int k = 0; k < 3; ++k ) {
253 v[k] = jas_image_readcmptsample( gs.altimage, cmptlut[k], x, y );
256 v[k] <<= 8 - jas_image_cmptprec( gs.altimage, cmptlut[k] );
258 if( v[k] < 0 ) v[k] = 0;
259 else if( v[k] > 255 ) v[k] = 255;
262 *data++ = qRgb( v[0], v[1], v[2] );
274 jas_image_cmptparm_t* cmptparms =
new jas_image_cmptparm_t[ 3 ];
276 for (
int i = 0; i < 3; ++i ) {
278 cmptparms[i].tlx = 0;
279 cmptparms[i].tly = 0;
282 cmptparms[i].hstep = 1;
283 cmptparms[i].vstep = 1;
284 cmptparms[i].width = qi.width();
285 cmptparms[i].height = qi.height();
288 cmptparms[i].prec = 8;
289 cmptparms[i].sgnd =
false;
292 jas_image_t* ji = jas_image_create( 3 , cmptparms, JAS_CLRSPC_UNKNOWN );
303 const unsigned height = qi.height();
304 const unsigned width = qi.width();
306 jas_matrix_t* m = jas_matrix_create( height, width );
307 if( !m )
return false;
309 jas_image_setclrspc( ji, JAS_CLRSPC_SRGB );
311 jas_image_setcmpttype( ji, 0, JAS_IMAGE_CT_RGB_R );
312 for(
uint y = 0; y < height; ++y )
313 for(
uint x = 0; x < width; ++x )
314 jas_matrix_set( m, y, x, qRed( qi.pixel( x, y ) ) );
315 jas_image_writecmpt( ji, 0, 0, 0, width, height, m );
317 jas_image_setcmpttype( ji, 1, JAS_IMAGE_CT_RGB_G );
318 for(
uint y = 0; y < height; ++y )
319 for(
uint x = 0; x < width; ++x )
320 jas_matrix_set( m, y, x, qGreen( qi.pixel( x, y ) ) );
321 jas_image_writecmpt( ji, 1, 0, 0, width, height, m );
323 jas_image_setcmpttype( ji, 2, JAS_IMAGE_CT_RGB_B );
324 for(
uint y = 0; y < height; ++y )
325 for(
uint x = 0; x < width; ++x )
326 jas_matrix_set( m, y, x, qBlue( qi.pixel( x, y ) ) );
327 jas_image_writecmpt( ji, 2, 0, 0, width, height, m );
328 jas_matrix_destroy( m );
336 jas_stream_t* stream = 0;
340 if( !stream )
return false;
344 jas_stream_close( stream );
349 jas_stream_close( stream );
350 jas_image_destroy( ji );
360 sprintf(rateBuffer,
"rate=%.2g\n", (quality < 0) ?
DEFAULT_RATE : quality / 100.0);
361 int i = jp2_encode( ji, stream, rateBuffer);
363 jas_image_destroy( ji );
364 jas_stream_close( stream );
366 if( i != 0 )
return false;
396 return device->peek(6) == QByteArray(
"\x00\x00\x00\x0C\x6A\x50", 6);
404 if( !(gs.image =
read_image( device() )) )
return false;
410 if( gs.image ) jas_image_destroy( gs.image );
411 if( gs.altimage ) jas_image_destroy( gs.altimage );
423 return option == Quality;
428 if (option == Quality)
435 if (option == Quality)
436 quality = qBound(-1, value.toInt(), 100);
444 class JP2Plugin :
public QImageIOPlugin
447 QStringList keys()
const;
448 Capabilities capabilities(QIODevice *device,
const QByteArray &format)
const;
449 QImageIOHandler *create(QIODevice *device,
const QByteArray &format = QByteArray())
const;
452 QStringList JP2Plugin::keys()
const
454 return QStringList() <<
"jp2";
457 QImageIOPlugin::Capabilities JP2Plugin::capabilities(QIODevice *device,
const QByteArray &format)
const
460 return Capabilities(CanRead | CanWrite);
461 if (!format.isEmpty())
463 if (!device->isOpen())
469 if (device->isWritable())
474 QImageIOHandler *JP2Plugin::create(QIODevice *device,
const QByteArray &format)
const
477 handler->setDevice(device);
478 handler->setFormat(format);
482 Q_EXPORT_STATIC_PLUGIN(JP2Plugin)
483 Q_EXPORT_PLUGIN2(jp2, JP2Plugin)