2 #include "Jpeg2000Callbacks.h"
3 #include "Jpeg2000Color.h"
4 #include "Jpeg2000FormatDefs.h"
11 #define JP2_RFC3745_MAGIC "\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a"
12 #define JP2_MAGIC "\x0d\x0a\x87\x0a"
13 #define J2K_CODESTREAM_MAGIC "\xff\x4f\xff\x51"
19 void Jpeg2000::applyImageTweaks (opj_image_t *image)
const
21 if (image->color_space == OPJ_CLRSPC_SYCC) {
22 color_sycc_to_rgb (image);
25 if (image->color_space != OPJ_CLRSPC_SYCC &&
26 image->numcomps == 3 &&
27 image->comps[0].dx == image->comps[0].dy &&
28 image->comps[1].dx != 1) {
29 image->color_space = OPJ_CLRSPC_SYCC;
30 }
else if (image->numcomps <= 2) {
31 image->color_space = OPJ_CLRSPC_GRAY;
34 if (image->icc_profile_buf) {
35 #if defined(OPJ_HAVE_LIBLCMS1) || defined(OPJ_HAVE_LIBLCMS2)
36 color_apply_icc_profile (image);
38 free (image->icc_profile_buf);
39 image->icc_profile_buf = 0;
40 image->icc_profile_len = 0;
44 opj_codec_t *Jpeg2000::decode (
int decodeFormat)
const
49 return opj_create_decompress(OPJ_CODEC_J2K);
52 return opj_create_decompress(OPJ_CODEC_JP2);
55 return opj_create_decompress(OPJ_CODEC_JPT);
64 int Jpeg2000::getFileFormat(
const char *filename)
const
66 static const char *extension[] = {
"pgx",
"pnm",
"pgm",
"ppm",
"bmp",
67 "tif",
"raw",
"rawl",
"tga",
"png",
68 "j2k",
"jp2",
"jpt",
"j2c",
"jpc"};
69 static const int format[] = {PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT,
70 TIF_DFMT, RAW_DFMT, RAWL_DFMT, TGA_DFMT, PNG_DFMT,
71 J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT, J2K_CFMT};
72 const char * ext = strrchr(filename,
'.');
78 for (
unsigned int i = 0; i <
sizeof(format)/
sizeof(*format); i++) {
79 if(strcasecmp(ext, extension[i]) == 0) {
88 void Jpeg2000::initializeParameters (opj_dparameters_t ¶meters)
const
90 parameters.cp_reduce = 0;
91 parameters.cp_layer = 0;
92 parameters.cod_format = 10;
93 parameters.decod_format = 1;
98 parameters.m_verbose = 0;
99 parameters.tile_index = 0;
100 parameters.nb_tile_to_decode = 0;
101 parameters.jpwl_correct = 0;
102 parameters.jpwl_exp_comps = 0;
103 parameters.jpwl_max_tiles = 0;
104 parameters.flags = 0;
107 int Jpeg2000::inputFormat(
const char *filename)
const
110 const char *s, *magic_s;
111 int ext_format, magic_format;
112 unsigned char buf[12];
113 OPJ_SIZE_T l_nb_read;
115 reader = fopen(filename,
118 if (reader == NULL) {
123 l_nb_read = fread(buf, 1, 12, reader);
125 if (l_nb_read != 12) {
129 ext_format = getFileFormat(filename);
131 if (ext_format == JPT_CFMT) {
135 if (memcmp(buf, JP2_RFC3745_MAGIC, 12) == 0 || memcmp(buf, JP2_MAGIC, 4) == 0) {
136 magic_format = JP2_CFMT;
138 }
else if (memcmp(buf, J2K_CODESTREAM_MAGIC, 4) == 0) {
139 magic_format = J2K_CFMT;
140 magic_s =
".j2k or .jpc or .j2c";
145 if (magic_format == ext_format) {
149 s = filename + strlen(filename) - 4;
151 LOG4CPP_ERROR_S ((*mainCat)) <<
"Jpeg2000::inputFormat"
152 <<
"The extension of this file is incorrect. Found " << s
153 <<
". Should be " << magic_s;
158 bool Jpeg2000::invalidFileExtension (
const QString &filename)
const
160 const int CHARACTER_IN_EXTENSION = 3;
166 QString extensionGot = filename.right (CHARACTER_IN_EXTENSION);
168 QStringList extensions = supportedFileExtensions();
169 QStringList::iterator itr;
170 for (itr = extensions.begin(); itr != extensions.end(); itr++) {
172 QString extensionWanted = *itr;
173 if (QString::compare (extensionGot,
175 Qt::CaseInsensitive)) {
187 QImage &imageResult)
const
189 LOG4CPP_INFO_S ((*mainCat)) <<
"Jpeg2000::load"
190 <<
" filename=" << filename.toLatin1().data();
192 if (invalidFileExtension (filename)) {
196 opj_dparameters_t parameters;
197 initializeParameters (parameters);
199 parameters.decod_format = inputFormat (filename.toLatin1().data());
201 opj_stream_t *inStream = opj_stream_create_default_file_stream (filename.toLatin1().data(), 1);
203 LOG4CPP_ERROR_S ((*mainCat)) <<
"Jpeg2000::load encountered error opening stream";
208 opj_codec_t *inCodec = decode (parameters.decod_format);
210 LOG4CPP_ERROR_S ((*mainCat)) <<
"Jpeg2000::load encountered error creating decoding stream";
211 opj_stream_destroy (inStream);
216 opj_set_info_handler (inCodec, infoCallback, 0);
217 opj_set_warning_handler (inCodec, warningCallback, 0);
218 opj_set_error_handler (inCodec, errorCallback, 0);
220 if (!opj_setup_decoder (inCodec,
222 LOG4CPP_ERROR_S ((*mainCat)) <<
"Jpeg2000::load encountered error decoding stream";
223 opj_stream_destroy (inStream);
224 opj_destroy_codec (inCodec);
230 if (!opj_read_header (inStream,
233 LOG4CPP_ERROR_S ((*mainCat)) <<
"Jpeg2000::load encountered error reading header";
234 opj_stream_destroy (inStream);
235 opj_destroy_codec (inCodec);
236 opj_image_destroy (image);
241 if (!(opj_decode (inCodec,
244 opj_end_decompress (inCodec,
246 LOG4CPP_ERROR_S ((*mainCat)) <<
"Jpeg2000::load failed to decode image";
247 opj_destroy_codec (inCodec);
248 opj_stream_destroy (inStream);
249 opj_image_destroy (image);
254 opj_stream_destroy (inStream);
256 applyImageTweaks (image);
261 buffer.open (QBuffer::WriteOnly);
262 if (imagetopnm (image,
264 LOG4CPP_ERROR_S ((*mainCat)) <<
"Jpeg2000::load failed to generate new image";
276 imageResult.loadFromData(buffer.data());
282 opj_destroy_codec (inCodec);
284 opj_image_destroy (image);
289 QStringList Jpeg2000::supportedFileExtensions ()
const
291 QStringList extensions;
294 extensions <<
"j2k" <<
"jp2" <<
"jpc" <<
"jpt";
301 QStringList extensions = supportedFileExtensions();
302 QStringList wildcards;
304 QStringList::iterator itr;
305 for (itr = extensions.begin(); itr != extensions.end(); itr++) {
306 QString extension = *itr;
307 QString wildcard = QString (
"*.%1").arg (extension);
308 wildcards << wildcard;
bool load(const QString &filename, QImage &image) const
Load image from jpeg2000 file.
Jpeg2000()
Single constructor.
QStringList supportedImageWildcards() const
List the supported jpeg2000 file extensions, for filtering import files.