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 jas_matrix_t *cmptmatrix[3];
246 jas_seqent_t *buf[3];
249 for (
int k = 0; k < 3; ++k ) {
250 prec[k] = jas_image_cmptprec(gs.altimage, cmptlut[k]);
251 if (!(cmptmatrix[k] = jas_matrix_create(1, width))) {
256 qti = QImage( jas_image_width( gs.altimage ), jas_image_height( gs.altimage ),
257 QImage::Format_RGB32 );
261 uint32_t* data = (uint32_t*)qti.bits();
263 for(
int y = 0; y < height; ++y ) {
264 for(
int k = 0; k < 3; ++k ) {
265 if (jas_image_readcmpt(gs.altimage, cmptlut[k], 0, y, width, 1, cmptmatrix[k])) {
268 buf[k] = jas_matrix_getref(cmptmatrix[k], 0, 0);
270 for(
int x = 0; x < width; ++x ) {
271 for(
int k = 0; k < 3; ++k ) {
275 v[k] <<= 8 - prec[k];
277 if( v[k] < 0 ) v[k] = 0;
278 else if( v[k] > 255 ) v[k] = 255;
282 *data++ = qRgb( v[0], v[1], v[2] );
286 for (
int k = 0; k < 3; ++k ) {
288 jas_matrix_destroy(cmptmatrix[k]);
301 jas_image_cmptparm_t* cmptparms =
new jas_image_cmptparm_t[ 3 ];
303 for (
int i = 0; i < 3; ++i ) {
305 cmptparms[i].tlx = 0;
306 cmptparms[i].tly = 0;
309 cmptparms[i].hstep = 1;
310 cmptparms[i].vstep = 1;
311 cmptparms[i].width = qi.width();
312 cmptparms[i].height = qi.height();
315 cmptparms[i].prec = 8;
316 cmptparms[i].sgnd =
false;
319 jas_image_t* ji = jas_image_create( 3 , cmptparms, JAS_CLRSPC_UNKNOWN );
330 const unsigned height = qi.height();
331 const unsigned width = qi.width();
333 jas_matrix_t* m = jas_matrix_create( height, width );
334 if( !m )
return false;
336 jas_image_setclrspc( ji, JAS_CLRSPC_SRGB );
338 jas_image_setcmpttype( ji, 0, JAS_IMAGE_CT_RGB_R );
339 for(
uint y = 0; y < height; ++y )
340 for(
uint x = 0; x < width; ++x )
341 jas_matrix_set( m, y, x, qRed( qi.pixel( x, y ) ) );
342 jas_image_writecmpt( ji, 0, 0, 0, width, height, m );
344 jas_image_setcmpttype( ji, 1, JAS_IMAGE_CT_RGB_G );
345 for(
uint y = 0; y < height; ++y )
346 for(
uint x = 0; x < width; ++x )
347 jas_matrix_set( m, y, x, qGreen( qi.pixel( x, y ) ) );
348 jas_image_writecmpt( ji, 1, 0, 0, width, height, m );
350 jas_image_setcmpttype( ji, 2, JAS_IMAGE_CT_RGB_B );
351 for(
uint y = 0; y < height; ++y )
352 for(
uint x = 0; x < width; ++x )
353 jas_matrix_set( m, y, x, qBlue( qi.pixel( x, y ) ) );
354 jas_image_writecmpt( ji, 2, 0, 0, width, height, m );
355 jas_matrix_destroy( m );
363 jas_stream_t* stream = 0;
367 if( !stream )
return false;
371 jas_stream_close( stream );
376 jas_stream_close( stream );
377 jas_image_destroy( ji );
387 sprintf(rateBuffer,
"rate=%.2g\n", (quality < 0) ?
DEFAULT_RATE : quality / 100.0);
388 int i = jp2_encode( ji, stream, rateBuffer);
390 jas_image_destroy( ji );
391 jas_stream_close( stream );
393 if( i != 0 )
return false;
423 return device->peek(6) == QByteArray(
"\x00\x00\x00\x0C\x6A\x50", 6);
431 if( !(gs.image =
read_image( device() )) )
return false;
437 if( gs.image ) jas_image_destroy( gs.image );
438 if( gs.altimage ) jas_image_destroy( gs.altimage );
450 return option == Quality;
455 if (option == Quality)
462 if (option == Quality)
463 quality = qBound(-1, value.toInt(), 100);
471 class JP2Plugin :
public QImageIOPlugin
474 QStringList keys()
const;
475 Capabilities capabilities(QIODevice *device,
const QByteArray &format)
const;
476 QImageIOHandler *create(QIODevice *device,
const QByteArray &format = QByteArray())
const;
479 QStringList JP2Plugin::keys()
const
481 return QStringList() <<
"jp2";
484 QImageIOPlugin::Capabilities JP2Plugin::capabilities(QIODevice *device,
const QByteArray &format)
const
487 return Capabilities(CanRead | CanWrite);
488 if (!format.isEmpty())
490 if (!device->isOpen())
496 if (device->isWritable())
501 QImageIOHandler *JP2Plugin::create(QIODevice *device,
const QByteArray &format)
const
504 handler->setDevice(device);
505 handler->setFormat(format);
509 Q_EXPORT_STATIC_PLUGIN(JP2Plugin)
510 Q_EXPORT_PLUGIN2(jp2, JP2Plugin)
void setOption(ImageOption option, const QVariant &value)
static jas_stream_t * jas_stream_create()
static int qiodevice_close(jas_stream_obj_t *)
static void jas_stream_initbuf(jas_stream_t *stream, int bufmode, char *buf, int bufsize)
QImageIO Routines to read/write JPEG2000 images.
static jas_image_t * read_image(QIODevice *io)
static jas_image_t * create_image(const QImage &qi)
static int qiodevice_write(jas_stream_obj_t *obj, char *buf, int cnt)
static bool write_components(jas_image_t *ji, const QImage &qi)
static bool render_view(gs_t &gs, QImage *outImage)
static int qiodevice_read(jas_stream_obj_t *obj, char *buf, int cnt)
bool supportsOption(ImageOption option) const
static bool write_image(const QImage &image, QIODevice *io, int quality)
static jas_stream_ops_t jas_stream_qiodeviceops
bool write(const QImage &image)
static jas_stream_t * jas_stream_qiodevice(QIODevice *iodevice)
static bool convert_colorspace(gs_t &gs)
QVariant option(ImageOption option) const
#define DEFAULT_RATE
QImageIO Routines to read/write JPEG2000 images.
static long qiodevice_seek(jas_stream_obj_t *obj, long offset, int origin)