14#include <jasper/jasper.h>
20class QJp2HandlerPrivate
22 Q_DECLARE_PUBLIC(QJp2Handler)
23 Q_DISABLE_COPY(QJp2HandlerPrivate)
28 QJp2HandlerPrivate(QJp2Handler *q_ptr);
34
35
36
37
38
39
40
41
42
43
44
53 bool write(
const QImage &image,
int quality);
55 typedef void (Jpeg2000JasperReader::*ScanlineFunc)(jas_seqent_t**
const, uchar*);
56 typedef void (Jpeg2000JasperReader::*ScanlineFuncWrite)(jas_matrix_t**, uchar*);
58 void copyJasperQt(ScanlineFunc scanlinecopier);
59 void copyJasperQtGeneric();
60 void copyScanlineJasperQtRGB(jas_seqent_t **
const jasperRow, uchar *qtScanLine);
61 void copyScanlineJasperQtRGBA(jas_seqent_t **
const jasperRow, uchar *qtScanLine);
62 void copyScanlineJasperQtGray(jas_seqent_t **
const jasperRow, uchar *qtScanLine);
63 void copyScanlineJasperQtGrayA(jas_seqent_t **
const jasperRow, uchar *qtScanLine);
65 void copyQtJasper(
const ScanlineFuncWrite scanlinecopier);
66 void copyScanlineQtJasperRGB(jas_matrix_t ** jasperRow, uchar *qtScanLine);
67 void copyScanlineQtJasperRGBA(jas_matrix_t ** jasperRow, uchar *qtScanLine);
68 void copyScanlineQtJasperColormapRGB(jas_matrix_t ** jasperRow, uchar *qtScanLine);
69 void copyScanlineQtJasperColormapRGBA(jas_matrix_t ** jasperRow, uchar *qtScanLine);
70 void copyScanlineQtJasperColormapGrayscale(jas_matrix_t ** jasperRow, uchar *qtScanLine);
71 void copyScanlineQtJasperColormapGrayscaleA(jas_matrix_t ** jasperRow, uchar *qtScanLine);
73 bool attemptColorspaceChange(
int wantedColorSpace);
74 bool createJasperMatrix(jas_matrix_t **&matrix);
75 bool freeJasperMatrix(jas_matrix_t **matrix);
76 void printColorSpaceError();
77 jas_image_cmptparm_t createComponentMetadata(
const int width,
const int height);
78 jas_image_t *newRGBAImage(
const int width,
const int height,
bool alpha);
79 jas_image_t *newGrayscaleImage(
const int width,
const int height,
bool alpha);
80 bool decodeColorSpace(
int clrspc, QString &family, QString &specific);
81 void printMetadata(jas_image_t *image);
95 jas_image_t *jasper_image;
98 int jasComponentPrecicion[4];
99 int computedComponentWidth ;
100 int computedComponentHeight;
101 int computedComponentHorizontalSubsampling;
102 int computedComponentVerticalSubsampling;
103 int jasperColorspaceFamily;
106 int colorComponentMapping[4];
111 : writeQuality(100), subType(
"jp2"), q_ptr(q_ptr)
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
148
149
156
157
164
165
166
167
168
169
170
171
172
175 bool bCanRead =
false;
178 if (header.startsWith(QByteArrayLiteral(
"\000\000\000\fjP \r\n\207\n"))) {
182 *subType = QByteArray(
"jp2");
183 }
else if (header.startsWith(QByteArrayLiteral(
"\377\117\377\121\000"))) {
187 *subType = QByteArray(
"j2k");
194
206
214
217 Q_D(
const QJp2Handler);
219 if (d->subType == QByteArray(
"jp2"))
225 return writer
.write(image, d->writeQuality);
229
230
231
234 Q_D(
const QJp2Handler);
235 if (option == Quality) {
236 return QVariant(d->writeQuality);
237 }
else if (option == SubType) {
238 return QVariant(d->subType);
244
245
246
247
248
249
250
251
252
253
254void QJp2Handler::setOption(ImageOption option,
const QVariant &value)
257 if (option == Quality) {
259 const int quality = value.toInt(&ok);
261 d->writeQuality = quality;
262 }
else if (option == SubType) {
263 const QByteArray subTypeCandidate = value.toByteArray();
265 if (subTypeCandidate == QByteArrayLiteral(
"jp2") ||
266 subTypeCandidate == QByteArrayLiteral(
"j2k"))
267 d->subType = subTypeCandidate;
272
273
274
277 return (option == Quality || option == SubType);
281
282
295
296
297
298
299
300
302 : jasperOk(
true), ioDevice(iod), format(format), hasAlpha(
false)
304#if JAS_VERSION_MAJOR
< 3
307 qDebug(
"Jasper Library initialization failed");
311#if QT_VERSION >= QT_VERSION_CHECK(6
, 0
, 0
)
312 if (QImageReader::allocationLimit() > 0)
313 jas_conf_set_max_mem_usage(qsizetype(QImageReader::allocationLimit()) * 1024 * 1024);
316 jas_conf_set_max_mem_usage(128 * 1024 * 1024);
318 if (jas_init_library()) {
320 qDebug(
"Jasper library initialization failed");
322 if (jas_init_thread()) {
323 jas_cleanup_library();
325 qDebug(
"Jasper thread initialization failed");
332#if JAS_VERSION_MAJOR
< 3
337 if (jas_cleanup_thread()) {
338 qDebug(
"Jasper thread cleanup failed");
340 if (jas_cleanup_library()) {
341 qDebug(
"Jasper library cleanup failed");
348
349
350
356 const auto jasCoordInIntRange = [](jas_image_coord_t v) {
357 return v >= 1 && qint64(v) <= qint64(std::numeric_limits<
int>::max());
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376 QByteArray fileContents = ioDevice->readAll();
377 jas_stream_t *imageData = jas_stream_memopen(fileContents.data(),
378 fileContents.size());
379 jasper_image = jas_image_decode(imageData, jas_image_getfmt(imageData), 0);
380 jas_stream_close(imageData);
382 qDebug(
"Jasper library can't decode Jpeg2000 image data");
388 qtWidth = jas_image_width(jasper_image);
389 qtHeight = jas_image_height(jasper_image);
390 jasNumComponents = jas_image_numcmpts(jasper_image);
391 jasperColorspaceFamily = jas_clrspc_fam(jas_image_clrspc(jasper_image));
393 if (jasNumComponents < 1 || jasNumComponents > 4) {
394 qDebug(
"Unsupported number of components (%d) in JPEG 2000 image", jasNumComponents);
398 bool needColorspaceChange =
false;
399 if (jasperColorspaceFamily != JAS_CLRSPC_FAM_RGB &&
400 jasperColorspaceFamily != JAS_CLRSPC_FAM_GRAY)
401 needColorspaceChange =
true;
405 for (c = 0; c < jasNumComponents; ++c) {
406 jasComponentPrecicion[c] = jas_image_cmptprec(jasper_image, c);
409 if (jasComponentPrecicion[c] > 8 || jasComponentPrecicion[c] < 8)
410 needColorspaceChange =
true;
413 if (jas_image_cmpthstep(jasper_image, c) != 1 ||
414 jas_image_cmptvstep(jasper_image, c) != 1)
415 needColorspaceChange =
true;
418 if (jas_image_cmptsgnd(jasper_image, c) != 0)
419 needColorspaceChange =
true;
423
424
425
426
427
428
430 bool decodeOk =
true;
431 if (needColorspaceChange)
432 decodeOk = attemptColorspaceChange(JAS_CLRSPC_SRGB);
435 printColorSpaceError();
440 const jas_image_coord_t imageWidth = jas_image_width(jasper_image);
441 const jas_image_coord_t imageHeight = jas_image_height(jasper_image);
442 if (!jasCoordInIntRange(imageWidth) || !jasCoordInIntRange(imageHeight)) {
443 qDebug(
"The Qt JPEG 2000 reader does not support image dimensions this large");
446 qtWidth = imageWidth;
447 qtHeight = imageHeight;
448 jasNumComponents = jas_image_numcmpts(jasper_image);
449 jasperColorspaceFamily = jas_clrspc_fam(jas_image_clrspc(jasper_image));
450 if (jasNumComponents < 1 || jasNumComponents > 4) {
451 qDebug(
"Unsupported number of components (%d) in JPEG 2000 image", jasNumComponents);
454 for (c = 0; c < jasNumComponents; ++c) {
455 jasComponentPrecicion[c] = jas_image_cmptprec(jasper_image, c);
458 if (jasperColorspaceFamily != JAS_CLRSPC_FAM_RGB &&
459 jasperColorspaceFamily != JAS_CLRSPC_FAM_GRAY) {
460 qDebug(
"The Qt JPEG 2000 reader was unable to convert colorspace to RGB or grayscale");
466 bool oddComponentSubsampling =
false;
467 for (c = 0; c < jasNumComponents; ++c) {
468 if (jas_image_cmpthstep(jasper_image, c) != 1 ||
469 jas_image_cmptvstep(jasper_image, c) != 1) {
470 oddComponentSubsampling =
true;
474 if (oddComponentSubsampling) {
477 const jas_image_coord_t cmptWidth = jas_image_cmptwidth(jasper_image, 0);
478 const jas_image_coord_t cmptHeight = jas_image_cmptheight(jasper_image, 0);
479 const jas_image_coord_t hstep = jas_image_cmpthstep(jasper_image, 0);
480 const jas_image_coord_t vstep = jas_image_cmptvstep(jasper_image, 0);
481 if (!jasCoordInIntRange(cmptWidth) || !jasCoordInIntRange(cmptHeight) ||
482 !jasCoordInIntRange(hstep) || !jasCoordInIntRange(vstep)) {
483 qDebug(
"The Qt JPEG 2000 reader does not support image dimensions this large");
486 computedComponentWidth = cmptWidth;
487 computedComponentHeight = cmptHeight;
488 computedComponentHorizontalSubsampling = hstep;
489 computedComponentVerticalSubsampling = vstep;
491 for (c = 1; c < jasNumComponents; ++c) {
492 if (computedComponentWidth != jas_image_cmptwidth(jasper_image, c) ||
493 computedComponentWidth != jas_image_cmptwidth(jasper_image, c) ||
494 computedComponentHorizontalSubsampling != jas_image_cmpthstep(jasper_image, c) ||
495 computedComponentVerticalSubsampling != jas_image_cmptvstep(jasper_image, c)) {
496 qDebug(
"The Qt JPEG 2000 reader does not support images where "
497 "component geometry differs from image geometry");
501 if (qMulOverflow(computedComponentWidth, computedComponentHorizontalSubsampling, &qtWidth) ||
502 qMulOverflow(computedComponentHeight, computedComponentVerticalSubsampling, &qtHeight)) {
503 qDebug(
"The Qt JPEG 2000 reader does not support image dimensions this large");
509 for (c = 0; c < jasNumComponents; ++c) {
511 if (jasComponentPrecicion[c]>8 || jasComponentPrecicion[c]<8) {
512 qDebug(
"The Qt JPEG 2000 reader does not support components with "
518 if (oddComponentSubsampling) {
519 qDebug(
"The Qt JPEG 2000 reader does not support components with "
520 "a subsampling factor != 1 (yet)");
525 if (jas_image_cmptsgnd(jasper_image, c) != 0) {
526 qDebug(
"Qt JPEG 2000 reader does not support signed components");
532 if (!oddComponentSubsampling)
533 if (jas_image_cmpttlx(jasper_image,c) != 0 ||
534 jas_image_cmpttly(jasper_image,c) != 0 ||
535 jas_image_cmptbrx(jasper_image,c) != jas_image_brx(jasper_image) ||
536 jas_image_cmptbry(jasper_image,c) != jas_image_bry(jasper_image) ||
537 jas_image_cmptwidth (jasper_image, c) != jas_image_width (jasper_image) ||
538 jas_image_cmptheight(jasper_image, c) != jas_image_height(jasper_image )) {
539 qDebug(
"The Qt JPEG 2000 reader does not support images where "
540 "component geometry differs from image geometry");
541 printMetadata(jasper_image);
554 jasperColorspaceFamily = jas_clrspc_fam(jas_image_clrspc(jasper_image));
555 if (jasperColorspaceFamily == JAS_CLRSPC_FAM_RGB) {
556 if (jasNumComponents > 4)
557 qDebug(
"JPEG 2000 reader expected 3 or 4 components, got %d",
561 colorComponentMapping[0] = jas_image_getcmptbytype(jasper_image,
563 colorComponentMapping[1] = jas_image_getcmptbytype(jasper_image,
565 colorComponentMapping[2] = jas_image_getcmptbytype(jasper_image,
568 }
else if (jasperColorspaceFamily == JAS_CLRSPC_FAM_GRAY) {
569 if (jasNumComponents > 2)
570 qDebug(
"JPEG 2000 reader expected 1 or 2 components, got %d",
572 colorComponentMapping[0] = jas_image_getcmptbytype(jasper_image,
573 JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y));
576 printColorSpaceError();
583 const int posibleAlphaComponent1 = 3;
584 const int posibleAlphaComponent2 = 48;
586 if (jasNumComponents == qtNumComponents + 1) {
587 colorComponentMapping[qtNumComponents] = jas_image_getcmptbytype(jasper_image, posibleAlphaComponent1);
588 if (colorComponentMapping[qtNumComponents] < 0) {
589 colorComponentMapping[qtNumComponents] = jas_image_getcmptbytype(jasper_image, posibleAlphaComponent2);
591 if (colorComponentMapping[qtNumComponents] > 0) {
598 for (c = 0; c < qtNumComponents; ++c) {
599 if (colorComponentMapping[c] < 0) {
600 qDebug(
"JPEG 2000 reader missing a color component");
606 QImage::Format qtFormat = QImage::Format_Invalid;
607 if (jasperColorspaceFamily == JAS_CLRSPC_FAM_RGB)
608 qtFormat = hasAlpha ? QImage::Format_ARGB32 : QImage::Format_RGB32;
609 else if (jasperColorspaceFamily == JAS_CLRSPC_FAM_GRAY)
610 qtFormat = hasAlpha ? QImage::Format_ARGB32 : QImage::Format_Grayscale8;
611 if (!QImageIOHandler::allocateImage(QSize(qtWidth, qtHeight), qtFormat, &qtImage))
615 if (oddComponentSubsampling) {
618 copyJasperQtGeneric();
619 }
else if (jasperColorspaceFamily == JAS_CLRSPC_FAM_RGB) {
621 copyJasperQt(&Jpeg2000JasperReader::copyScanlineJasperQtRGBA);
623 copyJasperQt(&Jpeg2000JasperReader::copyScanlineJasperQtRGB);
624 }
else if (jasperColorspaceFamily == JAS_CLRSPC_FAM_GRAY) {
626 copyJasperQt(&Jpeg2000JasperReader::copyScanlineJasperQtGrayA);
628 copyJasperQt(&Jpeg2000JasperReader::copyScanlineJasperQtGray);
637
638
642 jas_matrix_t **jasperMatrix;
643 jas_seqent_t **jasperRow;
644 createJasperMatrix(jasperMatrix);
645 jasperRow = (jas_seqent_t**)malloc(jasNumComponents *
sizeof(jas_seqent_t *));
646 Q_CHECK_PTR(jasperRow);
649 for (
int componentY = 0; componentY < computedComponentHeight; ++componentY) {
650 for (
int c = 0; c < jasNumComponents; ++c) {
651 jas_image_readcmpt(jasper_image, colorComponentMapping[c], 0,
652 componentY, computedComponentWidth, 1,
654 jasperRow[c] = jas_matrix_getref(jasperMatrix[c], 0, 0);
656 for (
int verticalSubsample = 0;
657 verticalSubsample < computedComponentVerticalSubsampling;
658 ++verticalSubsample) {
659 uchar *scanLineUchar = qtImage.scanLine(imageY);
660 QRgb *scanLineQRgb =
reinterpret_cast<QRgb *>(scanLineUchar);
661 for (
int componentX = 0; componentX < computedComponentWidth;
663 for (
int horizontalSubsample = 0;
664 horizontalSubsample <
665 computedComponentHorizontalSubsampling;
666 ++horizontalSubsample) {
667 if (jasperColorspaceFamily == JAS_CLRSPC_FAM_RGB) {
669 *scanLineQRgb++ = (jasperRow[3][componentX] << 24) |
670 (jasperRow[0][componentX] << 16) |
671 (jasperRow[1][componentX] << 8) |
672 jasperRow[2][componentX];
674 *scanLineQRgb++ = (jasperRow[0][componentX] << 16) |
675 (jasperRow[1][componentX] << 8) |
676 jasperRow[2][componentX];
678 }
else if (jasperColorspaceFamily == JAS_CLRSPC_FAM_GRAY) {
680 *scanLineQRgb++ = (jasperRow[1][componentX] << 24) |
681 (jasperRow[0][componentX] << 16) |
682 (jasperRow[0][componentX] << 8) |
683 jasperRow[0][componentX];
685 *scanLineUchar++ = jasperRow[0][componentX];
696
697
698
699
703 jas_matrix_t **jasperMatrix;
704 jas_seqent_t **jasperRow;
706 createJasperMatrix(jasperMatrix);
707 jasperRow = (jas_seqent_t**)malloc(jasNumComponents *
sizeof(jas_seqent_t *));
708 Q_CHECK_PTR(jasperRow);
710 for (
int scanline = 0; scanline < qtHeight; ++scanline) {
711 for (
int c = 0; c < jasNumComponents; ++c) {
712 jas_image_readcmpt(jasper_image, colorComponentMapping[c], 0,
713 scanline, qtWidth, 1, jasperMatrix[c]);
714 jasperRow[c] = jas_matrix_getref(jasperMatrix[c], 0, 0);
716 (
this->*scanlineCopier)(jasperRow, qtImage.scanLine(scanline));
719 freeJasperMatrix(jasperMatrix);
724
725
726
728 jas_seqent_t **
const jasperRow, uchar *qtScanLine)
730 QRgb *scanLine =
reinterpret_cast<QRgb *>(qtScanLine);
731 for (
int c = 0; c < qtWidth; ++c) {
732 *scanLine++ = (0xFF << 24) |
733 (jasperRow[0][c] << 16) |
734 (jasperRow[1][c] << 8) |
740
741
742
743void Jpeg2000JasperReader::copyScanlineJasperQtRGBA(jas_seqent_t **
const jasperRow, uchar *qtScanLine)
745 QRgb *scanLine =
reinterpret_cast<QRgb *>(qtScanLine);
746 for (
int c = 0; c < qtWidth; ++c) {
747 *scanLine++ = (jasperRow[3][c] << 24) |
748 (jasperRow[0][c] << 16) |
749 (jasperRow[1][c] << 8) |
755
756
757
758void Jpeg2000JasperReader::copyScanlineJasperQtGray(jas_seqent_t **
const jasperRow, uchar *qtScanLine)
760 for (
int c = 0; c < qtWidth; ++c) {
762 *qtScanLine++ = jasperRow[0][c];
767
768
769
770
771
772
773void Jpeg2000JasperReader::copyScanlineJasperQtGrayA(jas_seqent_t **
const jasperRow, uchar *qtScanLine)
775 QRgb *scanLine =
reinterpret_cast<QRgb *>(qtScanLine);
776 for (
int c = 0; c < qtWidth; ++c) {
777 *scanLine++ = (jasperRow[1][c] << 24) |
778 (jasperRow[0][c] << 16) |
779 (jasperRow[0][c] << 8) |
785
786
787
788
789
790
798 qtHeight = qtImage.height();
799 qtWidth = qtImage.width();
800 qtDepth = qtImage.depth();
803 jasper_image = newRGBAImage(qtWidth, qtHeight, qtImage.hasAlphaChannel());
807 if (qtImage.hasAlphaChannel())
808 copyQtJasper(&Jpeg2000JasperReader::copyScanlineQtJasperRGBA);
810 copyQtJasper(&Jpeg2000JasperReader::copyScanlineQtJasperRGB);
811 }
else if (qtDepth == 8) {
813 if (qtImage.allGray()) {
814 jasper_image = newGrayscaleImage(qtWidth, qtHeight, qtImage.hasAlphaChannel());
818 if (qtImage.hasAlphaChannel())
819 copyQtJasper(&Jpeg2000JasperReader::copyScanlineQtJasperColormapGrayscaleA);
821 copyQtJasper(&Jpeg2000JasperReader::copyScanlineQtJasperColormapGrayscale);
824 jasper_image = newRGBAImage(qtWidth, qtHeight, qtImage.hasAlphaChannel());
828 if (qtImage.hasAlphaChannel())
829 copyQtJasper(&Jpeg2000JasperReader::copyScanlineQtJasperColormapRGBA);
831 copyQtJasper(&Jpeg2000JasperReader::copyScanlineQtJasperColormapRGB);
834 qDebug(
"Unable to handle color depth %d", qtDepth);
840 fmtid = jas_image_strtofmt(
const_cast<
char*>(
"jp2"));
843 fmtid = jas_image_strtofmt(
const_cast<
char*>(
"jpc"));
845 const int minQuality = 0;
846 const int maxQuality = 100;
850 if (quality <= minQuality)
851 quality = minQuality;
852 if (quality > maxQuality)
853 quality = maxQuality;
861 const double minRate = 0.001;
867 const double maxRate = 0.3;
871 const double jasperRate = minRate + pow((
double(quality) /
double(maxQuality)), 2) * maxRate;
876 QString jasperFormatString;
880 if (quality != maxQuality) {
881 jasperFormatString += QLatin1String(
"mode=real");
882 jasperFormatString += QString(QLatin1String(
" rate=%1")).arg(jasperRate);
886 jas_stream_t * memory_stream = jas_stream_memopen(0, 0);
889 char *str = qstrdup(jasperFormatString.toLatin1().constData());
890 jas_image_encode(jasper_image, memory_stream, fmtid, str);
892 jas_stream_flush(memory_stream);
898 char *buffer =
reinterpret_cast<
char *>(
reinterpret_cast<jas_stream_memobj_t*>(memory_stream->obj_)->buf_);
899 qint64 length = jas_stream_length(memory_stream);
900 ioDevice->write(buffer, length);
902 jas_stream_close(memory_stream);
903 jas_image_destroy(jasper_image);
909
910
911
912
916 jas_matrix_t **jasperMatrix;
917 createJasperMatrix(jasperMatrix);
919 for (
int scanline = 0; scanline < qtHeight; ++scanline) {
920 (
this->*scanlinecopier)(jasperMatrix, qtImage.scanLine(scanline));
923 for (
int c = 0; c < jasNumComponents; ++c)
924 jas_image_writecmpt(jasper_image, c, 0, scanline, qtWidth, 1,
927 freeJasperMatrix(jasperMatrix);
931
932
936 QRgb *scanLineBuffer =
reinterpret_cast<QRgb *>(qtScanLine);
937 for (
int col = 0; col < qtWidth; ++col) {
938 jas_matrix_set(jasperRow[0], 0, col, (*scanLineBuffer & 0xFF0000) >> 16);
939 jas_matrix_set(jasperRow[1], 0, col, (*scanLineBuffer & 0x00FF00) >> 8);
940 jas_matrix_set(jasperRow[2], 0, col, *scanLineBuffer & 0x0000FF);
946
947
951 QRgb *scanLineBuffer =
reinterpret_cast<QRgb *>(qtScanLine);
952 for (
int col = 0; col < qtWidth; ++col) {
953 jas_matrix_set(jasperRow[3], 0, col, (*scanLineBuffer & 0xFF000000) >> 24);
954 jas_matrix_set(jasperRow[0], 0, col, (*scanLineBuffer & 0x00FF0000) >> 16);
955 jas_matrix_set(jasperRow[1], 0, col, (*scanLineBuffer & 0x0000FF00) >> 8);
956 jas_matrix_set(jasperRow[2], 0, col, *scanLineBuffer & 0x000000FF);
962
963
967 for (
int col = 0; col < qtWidth; ++col) {
968 QRgb color = qtImage.color(*qtScanLine);
969 jas_matrix_set(jasperRow[0], 0, col, qRed(color));
970 jas_matrix_set(jasperRow[1], 0, col, qGreen(color));
971 jas_matrix_set(jasperRow[2], 0, col, qBlue(color));
977
978
982 for (
int col = 0; col < qtWidth; ++col) {
983 QRgb color = qtImage.color(*qtScanLine);
984 jas_matrix_set(jasperRow[0], 0, col, qRed(color));
985 jas_matrix_set(jasperRow[1], 0, col, qGreen(color));
986 jas_matrix_set(jasperRow[2], 0, col, qBlue(color));
987 jas_matrix_set(jasperRow[3], 0, col, qAlpha(color));
993
994
998 for (
int col = 0; col < qtWidth; ++col) {
999 QRgb color = qtImage.color(*qtScanLine);
1000 jas_matrix_set(jasperRow[0], 0, col, qGray(color));
1006
1007
1011 for (
int col = 0; col < qtWidth; ++col) {
1012 QRgb color = qtImage.color(*qtScanLine);
1013 jas_matrix_set(jasperRow[0], 0, col, qGray(color));
1014 jas_matrix_set(jasperRow[1], 0, col, qAlpha(color));
1020
1021
1022
1023
1027 jas_cmprof_t *outprof;
1028 if (!(outprof = jas_cmprof_createfromclrspc(wantedColorSpace)))
1031 jas_image_t *newimage;
1032 if (!(newimage = jas_image_chclrspc(jasper_image, outprof,
1033 JAS_CMXFORM_INTENT_PER))) {
1034 jas_cmprof_destroy(outprof);
1037 jas_image_destroy(jasper_image);
1038 jas_cmprof_destroy(outprof);
1039 jasper_image = newimage;
1044
1045
1046
1048 const int width,
const int height)
1050 jas_image_cmptparm_t param;
1055 param.width = width;
1056 param.height = height;
1063
1064
1065
1067 const int height,
bool alpha)
1069 jasNumComponents = alpha ? 4 : 3;
1070 jas_image_cmptparm_t *params =
new jas_image_cmptparm_t[jasNumComponents];
1071 jas_image_cmptparm_t param = createComponentMetadata(width, height);
1072 for (
int c=0; c < jasNumComponents; c++)
1074 jas_image_t *newImage = jas_image_create(jasNumComponents, params,
1082 jas_image_setcmpttype(newImage, 0, JAS_IMAGE_CT_RGB_R);
1083 jas_image_setcmpttype(newImage, 1, JAS_IMAGE_CT_RGB_G);
1084 jas_image_setcmpttype(newImage, 2, JAS_IMAGE_CT_RGB_B);
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1099 jas_image_setcmpttype(newImage, 3, JAS_IMAGE_CT_OPACITY);
1105
1106
1107
1112 jasNumComponents = alpha ? 2 : 1;
1113 jas_image_cmptparm_t param = createComponentMetadata(width, height);
1114 jas_image_t *newImage = jas_image_create(1, ¶m, JAS_CLRSPC_SGRAY);
1118 jas_image_setcmpttype(newImage, 0, JAS_IMAGE_CT_GRAY_Y);
1122 jas_image_setcmpttype(newImage, 1, JAS_IMAGE_CT_OPACITY);
1127
1128
1129
1130
1133 matrix = (jas_matrix_t**)malloc(jasNumComponents *
sizeof(jas_matrix_t *));
1134 for (
int c = 0; c < jasNumComponents; ++c)
1135 matrix[c] = jas_matrix_create(1, qtWidth);
1140
1141
1142
1143
1146 for (
int c = 0; c < jasNumComponents; ++c)
1147 jas_matrix_destroy(matrix[c]);
1153
1154
1157 QString colorspaceFamily, colorspaceSpecific;
1158 decodeColorSpace(jas_image_clrspc(jasper_image), colorspaceFamily,
1159 colorspaceSpecific);
1160 qDebug(
"Jpeg2000 decoder is not able to handle color space %s - %s",
1161 qPrintable(colorspaceFamily), qPrintable(colorspaceSpecific));
1164
1165
1169 int fam = jas_clrspc_fam(clrspc);
1170 int mbr = jas_clrspc_mbr(clrspc);
1173 case 0: family = QLatin1String(
"JAS_CLRSPC_FAM_UNKNOWN");
break;
1174 case 1: family = QLatin1String(
"JAS_CLRSPC_FAM_XYZ");
break;
1175 case 2: family = QLatin1String(
"JAS_CLRSPC_FAM_LAB");
break;
1176 case 3: family = QLatin1String(
"JAS_CLRSPC_FAM_GRAY");
break;
1177 case 4: family = QLatin1String(
"JAS_CLRSPC_FAM_RGB");
break;
1178 case 5: family = QLatin1String(
"JAS_CLRSPC_FAM_YCBCR");
break;
1179 default: family = QLatin1String(
"Unknown");
return false;
1185 case 1: specific = QLatin1String(
"JAS_CLRSPC_CIEXYZ");
break;
1186 case 2: specific = QLatin1String(
"JAS_CLRSPC_CIELAB");
break;
1187 case 3: specific = QLatin1String(
"JAS_CLRSPC_SGRAY");
break;
1188 case 4: specific = QLatin1String(
"JAS_CLRSPC_SRGB");
break;
1189 case 5: specific = QLatin1String(
"JAS_CLRSPC_SYCBCR");
break;
1190 default: specific = QLatin1String(
"Unknown");
return false;
1195 case 3: specific = QLatin1String(
"JAS_CLRSPC_GENGRAY");
break;
1196 case 4: specific = QLatin1String(
"JAS_CLRSPC_GENRGB");
break;
1197 case 5: specific = QLatin1String(
"JAS_CLRSPC_GENYCBCR");
break;
1198 default: specific = QLatin1String(
"Unknown");
return false;
1207
1208
1213 qDebug(
"Image width: %ld",
long(jas_image_width(image)));
1214 qDebug(
"Image height: %ld",
long(jas_image_height(image)));
1215 qDebug(
"Coordinates on reference grid: (%ld,%ld) (%ld,%ld)",
1216 long(jas_image_tlx(image)),
long(jas_image_tly(image)),
1217 long(jas_image_brx(image)),
long(jas_image_bry(image)));
1218 qDebug(
"Number of image components: %d", jas_image_numcmpts(image));
1220 QString colorspaceFamily;
1221 QString colorspaceSpecific;
1222 decodeColorSpace(jas_image_clrspc(image), colorspaceFamily, colorspaceSpecific);
1223 qDebug(
"Color model (space): %d, %s - %s", jas_image_clrspc(image),
1224 qPrintable(colorspaceFamily), qPrintable(colorspaceSpecific));
1226 qDebug(
"Component metadata:");
1228 for (
int c = 0; c <
static_cast<
int>(jas_image_numcmpts(image)); ++c) {
1229 qDebug(
"Component %d:", c);
1230 qDebug(
" Component type: %ld",
long(jas_image_cmpttype(image, c)));
1231 qDebug(
" Width: %ld",
long(jas_image_cmptwidth(image, c)));
1232 qDebug(
" Height: %ld",
long(jas_image_cmptheight(image, c)));
1233 qDebug(
" Signedness: %d", jas_image_cmptsgnd(image, c));
1234 qDebug(
" Precision: %d", jas_image_cmptprec(image, c));
1235 qDebug(
" Horizontal subsampling factor: %ld",
long(jas_image_cmpthstep(image, c)));
1236 qDebug(
" Vertical subsampling factor: %ld",
long(jas_image_cmptvstep(image, c)));
1237 qDebug(
" Coordinates on reference grid: (%ld,%ld) (%ld,%ld)",
1238 long(jas_image_cmpttlx(image, c)),
long(jas_image_cmpttly(image, c)),
1239 long(jas_image_cmptbrx(image, c)),
long(jas_image_cmptbry(image, c)));
bool read(QImage *pImage)
Jpeg2000JasperReader(QIODevice *iod, const SubFormat format=Jp2Format)
bool write(const QImage &image, int quality)
Opens the file data and attempts to decode it using the Jasper library.
QIODevice * device() const
Returns the device currently assigned to QImageReader, or \nullptr if no device has been assigned.
The QJp2Handler class provides support for reading and writing JPEG 2000 image files with the Qt plug...
~QJp2Handler()
Destructor for QJp2Handler.
QJp2Handler()
Constructs an instance of QJp2Handler.
static bool canRead(QIODevice *iod, QByteArray *subType)
Verifies if some values (magic bytes) are set as expected in the header of the file.
bool write(const QImage &image) override
\reimp
bool read(QImage *image) override
\reimp
bool canRead() const override
\reimp
Automatic resource handling for a jas_image_t*.
ScopedJasperImage(jas_image_t *&image)