147 {
149 const QByteArray file_str = filename.toUtf8();
150 opj_codec_t *l_codec = 0;
151 opj_dparameters_t parameters;
152 bool hasColorSpaceInfo = false;
153 opj_stream_t *l_stream = NULL;
154 opj_image_t *
image = NULL;
155 int pos = 0;
157 unsigned int numComponents = 0;
158 unsigned int precision = 0;
162 bool isSigned;
163 int32_t signedCorrection = 0;
165
166
167 opj_set_default_decoder_parameters(¶meters);
168
169 parameters.decod_format =
infile_format(file_str.constData());
170 if (parameters.decod_format == -1) {
173 goto beach;
174 }
175
176
177
178 switch (parameters.decod_format) {
180 l_codec = opj_create_decompress(OPJ_CODEC_J2K);
181 break;
182 }
184 l_codec = opj_create_decompress(OPJ_CODEC_JP2);
185 hasColorSpaceInfo = true;
186 break;
187 }
188 }
189 Q_ASSERT(l_codec);
190
191 opj_codec_set_threads( l_codec,QThread::idealThreadCount() );
192
193
194 opj_setup_decoder(l_codec, ¶meters);
195
196 l_stream = opj_stream_create_default_file_stream(file_str.constData(), 1);
197 if (!l_stream) {
200 goto beach;
201 }
202
203
207
208 if (!opj_read_header(l_stream, l_codec, &
image)) {
211 goto beach;
212 }
213
214
215 if (!(opj_decode(l_codec, l_stream,
image)
216 && opj_end_decompress(l_codec, l_stream))) {
219 goto beach;
220 }
221
222
223 numComponents =
image->numcomps;
224 if (
image->numcomps == 0) {
227 goto beach;
228 }
229 precision =
image->comps[0].prec;
230 for (uint32_t i = 1; i < numComponents; ++i) {
231 if (
image->comps[i].prec != precision) {
232 std::ostringstream buffer;
233 buffer << "All components must have the same bit depth "
234 << precision;
237 goto beach;
238 }
239 }
240 isSigned = false;
241 for (uint32_t i = 0; i < numComponents; ++i) {
242 if ((
image->comps[i].dx != 1) || (
image->comps[i].dy != 1)) {
245 goto beach;
246 }
247 isSigned = isSigned || (
image->comps[0].sgnd);
248 }
249 if (isSigned)
250 signedCorrection = 1 << (precision - 1);
251
253 << "Image has " << numComponents << " numComponents and a bit depth of "
254 << precision <<
" for color space " <<
image->color_space;
256 if (!hasColorSpaceInfo) {
257 if (numComponents == 3) {
258 image->color_space = OPJ_CLRSPC_SRGB;
259 } else if (numComponents == 1) {
260 image->color_space = OPJ_CLRSPC_GRAY;
261 }
262 }
263 switch (
image->color_space) {
264 case OPJ_CLRSPC_UNKNOWN:
265 case OPJ_CLRSPC_UNSPECIFIED:
266 break;
267 case OPJ_CLRSPC_SRGB: {
268 if (precision == 16 || precision == 12) {
270 } else if (precision == 8) {
272 }
273 if (numComponents != 3) {
274 std::ostringstream buffer;
275 buffer << "sRGB: number of numComponents " << numComponents
276 << " does not equal 3";
279 goto beach;
280 }
284 break;
285 }
286 case OPJ_CLRSPC_GRAY: {
287 if (precision == 16 || precision == 12) {
290 } else if (precision == 8) {
293 }
294 if (numComponents != 1) {
295 std::ostringstream buffer;
296 buffer << "Grayscale: number of numComponents " << numComponents
297 << " greater than 1";
300 goto beach;
301 }
302 channelorder[0] = 0;
303 break;
304 }
305 case OPJ_CLRSPC_SYCC:
308 goto beach;
309 break;
310 case OPJ_CLRSPC_EYCC:
313 goto beach;
314 break;
315 case OPJ_CLRSPC_CMYK:
318 goto beach;
319 break;
320 default:
321 break;
322 }
323
324 if (!colorSpace) {
327 goto beach;
328 }
329
330
335 colorSpace, "built image");
336 }
337
338
342
343
345 for (OPJ_UINT32
v = 0;
v <
image->y1; ++
v) {
346 if (precision == 16 || precision == 12) {
347 do {
348 quint16 *px = reinterpret_cast<quint16*>(it->rawData());
349 for (uint32_t i = 0; i < numComponents; ++i) {
350 px[channelorder[i]] =
image->comps[i].data[pos]
351 + signedCorrection;
352 }
354 ++pos;
355
356 } while (it->nextPixel());
357 } else if (precision == 8) {
358 do {
359 quint8 *px = it->rawData();
360 for (uint32_t i = 0; i < numComponents; ++i) {
361 px[channelorder[i]] =
image->comps[i].data[pos]
362 + signedCorrection;
363 }
365 ++pos;
366
367 } while (it->nextPixel());
368 }
369 it->nextRow();
370 }
371
372beach:
373 if (l_stream)
374 opj_stream_destroy(l_stream);
375 if (l_codec)
376 opj_destroy_codec(l_codec);
378 opj_image_destroy(
image);
383 return res;
384}
const KoID GrayAColorModelID("GRAYA", ki18n("Grayscale/Alpha"))
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
const KoID Integer16BitsColorDepthID("U16", ki18n("16-bit integer/channel"))
const quint8 OPACITY_OPAQUE_U8
int infile_format(const char *fname)
void addErrorString(const std::string &str)
KisUndoStore * createUndoStore()
void setErrorMessage(const QString &errMsg)
void setWarningMessage(const QString &warningMsg)
QString nextLayerName(const QString &baseName="") const
KisHLineIteratorSP createHLineIteratorNG(qint32 x, qint32 y, qint32 w)
virtual void setOpacity(quint8 *pixels, quint8 alpha, qint32 nPixels) const =0
static void warning_callback(const char *msg, void *client_data)
static void error_callback(const char *msg, void *client_data)
static void info_callback(const char *msg, void *client_data)
@ FormatFeaturesUnsupported
@ FormatColorSpaceUnsupported
bool addNode(KisNodeSP node, KisNodeSP parent=KisNodeSP(), KisNodeAdditionFlags flags=KisNodeAdditionFlag::None)
KisPaintDeviceSP paintDevice
static const qint32 blue_pos
static const qint32 green_pos
static const qint32 red_pos
const KoColorSpace * colorSpace(const QString &colorModelId, const QString &colorDepthId, const KoColorProfile *profile)
static KoColorSpaceRegistry * instance()
const KoColorSpace * rgb8(const QString &profileName=QString())
const KoColorSpace * rgb16(const QString &profileName=QString())