146 {
148 const QByteArray file_str = filename.toUtf8();
149 opj_codec_t *l_codec = 0;
150 opj_dparameters_t parameters;
151 bool hasColorSpaceInfo = false;
152 opj_stream_t *l_stream = NULL;
153 opj_image_t *
image = NULL;
154 int pos = 0;
156 unsigned int numComponents = 0;
157 unsigned int precision = 0;
161 bool isSigned;
162 int32_t signedCorrection = 0;
164
165
166 opj_set_default_decoder_parameters(¶meters);
167
168 parameters.decod_format =
infile_format(file_str.constData());
169 if (parameters.decod_format == -1) {
172 goto beach;
173 }
174
175
176
177 switch (parameters.decod_format) {
179 l_codec = opj_create_decompress(OPJ_CODEC_J2K);
180 break;
181 }
183 l_codec = opj_create_decompress(OPJ_CODEC_JP2);
184 hasColorSpaceInfo = true;
185 break;
186 }
187 }
188 Q_ASSERT(l_codec);
189
190 opj_codec_set_threads( l_codec,QThread::idealThreadCount() );
191
192
193 opj_setup_decoder(l_codec, ¶meters);
194
195 l_stream = opj_stream_create_default_file_stream(file_str.constData(), 1);
196 if (!l_stream) {
199 goto beach;
200 }
201
202
206
207 if (!opj_read_header(l_stream, l_codec, &
image)) {
210 goto beach;
211 }
212
213
214 if (!(opj_decode(l_codec, l_stream,
image)
215 && opj_end_decompress(l_codec, l_stream))) {
218 goto beach;
219 }
220
221
222 numComponents =
image->numcomps;
223 if (
image->numcomps == 0) {
226 goto beach;
227 }
228 precision =
image->comps[0].prec;
229 for (uint32_t i = 1; i < numComponents; ++i) {
230 if (
image->comps[i].prec != precision) {
231 std::ostringstream buffer;
232 buffer << "All components must have the same bit depth "
233 << precision;
236 goto beach;
237 }
238 }
239 isSigned = false;
240 for (uint32_t i = 0; i < numComponents; ++i) {
241 if ((
image->comps[i].dx != 1) || (
image->comps[i].dy != 1)) {
244 goto beach;
245 }
246 isSigned = isSigned || (
image->comps[0].sgnd);
247 }
248 if (isSigned)
249 signedCorrection = 1 << (precision - 1);
250
252 << "Image has " << numComponents << " numComponents and a bit depth of "
253 << precision <<
" for color space " <<
image->color_space;
255 if (!hasColorSpaceInfo) {
256 if (numComponents == 3) {
257 image->color_space = OPJ_CLRSPC_SRGB;
258 } else if (numComponents == 1) {
259 image->color_space = OPJ_CLRSPC_GRAY;
260 }
261 }
262 switch (
image->color_space) {
263 case OPJ_CLRSPC_UNKNOWN:
264 case OPJ_CLRSPC_UNSPECIFIED:
265 break;
266 case OPJ_CLRSPC_SRGB: {
267 if (precision == 16 || precision == 12) {
269 } else if (precision == 8) {
271 }
272 if (numComponents != 3) {
273 std::ostringstream buffer;
274 buffer << "sRGB: number of numComponents " << numComponents
275 << " does not equal 3";
278 goto beach;
279 }
283 break;
284 }
285 case OPJ_CLRSPC_GRAY: {
286 if (precision == 16 || precision == 12) {
289 } else if (precision == 8) {
292 }
293 if (numComponents != 1) {
294 std::ostringstream buffer;
295 buffer << "Grayscale: number of numComponents " << numComponents
296 << " greater than 1";
299 goto beach;
300 }
301 channelorder[0] = 0;
302 break;
303 }
304 case OPJ_CLRSPC_SYCC:
307 goto beach;
308 break;
309 case OPJ_CLRSPC_EYCC:
312 goto beach;
313 break;
314 case OPJ_CLRSPC_CMYK:
317 goto beach;
318 break;
319 default:
320 break;
321 }
322
323 if (!colorSpace) {
326 goto beach;
327 }
328
329
334 colorSpace, "built image");
335 }
336
337
341
342
344 for (OPJ_UINT32
v = 0;
v <
image->y1; ++
v) {
345 if (precision == 16 || precision == 12) {
346 do {
347 quint16 *px = reinterpret_cast<quint16*>(it->rawData());
348 for (uint32_t i = 0; i < numComponents; ++i) {
349 px[channelorder[i]] =
image->comps[i].data[pos]
350 + signedCorrection;
351 }
353 ++pos;
354
355 } while (it->nextPixel());
356 } else if (precision == 8) {
357 do {
358 quint8 *px = it->rawData();
359 for (uint32_t i = 0; i < numComponents; ++i) {
360 px[channelorder[i]] =
image->comps[i].data[pos]
361 + signedCorrection;
362 }
364 ++pos;
365
366 } while (it->nextPixel());
367 }
368 it->nextRow();
369 }
370
371beach:
372 if (l_stream)
373 opj_stream_destroy(l_stream);
374 if (l_codec)
375 opj_destroy_codec(l_codec);
377 opj_image_destroy(
image);
382 return res;
383}
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())