static uint_fast32_t jp2_gettypeasoc(int colorspace, int ctype) { int type; int asoc; if (ctype & JAS_IMAGE_CT_OPACITY) { type = JP2_CDEF_TYPE_OPACITY; asoc = JP2_CDEF_ASOC_ALL; goto done; } type = JP2_CDEF_TYPE_UNSPEC; asoc = JP2_CDEF_ASOC_NONE; switch (jas_clrspc_fam(colorspace)) { case JAS_CLRSPC_FAM_RGB: switch (JAS_IMAGE_CT_COLOR(ctype)) { case JAS_IMAGE_CT_RGB_R: type = JP2_CDEF_TYPE_COLOR; asoc = JP2_CDEF_RGB_R; break; case JAS_IMAGE_CT_RGB_G: type = JP2_CDEF_TYPE_COLOR; asoc = JP2_CDEF_RGB_G; break; case JAS_IMAGE_CT_RGB_B: type = JP2_CDEF_TYPE_COLOR; asoc = JP2_CDEF_RGB_B; break; } break; case JAS_CLRSPC_FAM_YCBCR: switch (JAS_IMAGE_CT_COLOR(ctype)) { case JAS_IMAGE_CT_YCBCR_Y: type = JP2_CDEF_TYPE_COLOR; asoc = JP2_CDEF_YCBCR_Y; break; case JAS_IMAGE_CT_YCBCR_CB: type = JP2_CDEF_TYPE_COLOR; asoc = JP2_CDEF_YCBCR_CB; break; case JAS_IMAGE_CT_YCBCR_CR: type = JP2_CDEF_TYPE_COLOR; asoc = JP2_CDEF_YCBCR_CR; break; } break; case JAS_CLRSPC_FAM_GRAY: type = JP2_CDEF_TYPE_COLOR; asoc = JP2_CDEF_GRAY_Y; break; } done: return (type << 16) | asoc; }
static char *colorspacename(jas_clrspc_t clrspc) { switch (jas_clrspc_fam(clrspc)) { case JAS_CLRSPC_FAM_UNKNOWN: return "Unknown"; case JAS_CLRSPC_FAM_XYZ: return "XYZ"; case JAS_CLRSPC_FAM_LAB: return "Lab"; case JAS_CLRSPC_FAM_GRAY: return "Gray"; case JAS_CLRSPC_FAM_RGB: return "RGB"; case JAS_CLRSPC_FAM_YCBCR: return "YCbCr"; } return "Unknown"; }
int jas_clrspc_numchans(int clrspc) { switch (jas_clrspc_fam(clrspc)) { case JAS_CLRSPC_FAM_XYZ: case JAS_CLRSPC_FAM_LAB: case JAS_CLRSPC_FAM_RGB: case JAS_CLRSPC_FAM_YCBCR: return 3; break; case JAS_CLRSPC_FAM_GRAY: return 1; break; default: abort(); break; } }
int jas_clrspc_numchans(int clrspc) { switch (jas_clrspc_fam(clrspc)) { case JAS_CLRSPC_FAM_XYZ: case JAS_CLRSPC_FAM_LAB: case JAS_CLRSPC_FAM_RGB: case JAS_CLRSPC_FAM_YCBCR: return 3; break; case JAS_CLRSPC_FAM_GRAY: return 1; break; default: jas_error( JAS_ERR_UNSUPPORTED_COLOR_SPACE_IN_JAS_CLRSPC_NUMCHANS, "JAS_ERR_UNSUPPORTED_COLOR_SPACE_IN_JAS_CLRSPC_NUMCHANS" ); break; } return 0; }
static int tojpgcs(int colorspace) { switch (jas_clrspc_fam(colorspace)) { case JAS_CLRSPC_FAM_RGB: return JCS_RGB; break; case JAS_CLRSPC_FAM_YCBCR: return JCS_YCbCr; break; case JAS_CLRSPC_FAM_GRAY: return JCS_GRAYSCALE; break; default: jas_error( JAS_ERR_INVALID_CLRSPACE_TOJPGCS, "JAS_ERR_INVALID_CLRSPACE_TOJPGCS" ); return -1; break; } }
bool Jpeg2KDecoder::readData(Mat& img) { bool result = false; int color = img.channels() > 1; uchar* data = img.data; int step = img.step; jas_stream_t* stream = (jas_stream_t*)m_stream; jas_image_t* image = (jas_image_t*)m_image; if (stream && image) { bool convert; int colorspace; if (color) { convert = (jas_image_clrspc(image) != JAS_CLRSPC_SRGB); colorspace = JAS_CLRSPC_SRGB; } else { convert = (jas_clrspc_fam(jas_image_clrspc(image)) != JAS_CLRSPC_FAM_GRAY); colorspace = JAS_CLRSPC_SGRAY; // TODO GENGRAY or SGRAY? } // convert to the desired colorspace if (convert) { jas_cmprof_t* clrprof = jas_cmprof_createfromclrspc(colorspace); if (clrprof) { jas_image_t* _img = jas_image_chclrspc(image, clrprof, JAS_CMXFORM_INTENT_RELCLR); if (_img) { jas_image_destroy(image); m_image = image = _img; result = true; } else { fprintf(stderr, "JPEG 2000 LOADER ERROR: cannot convert colorspace\n"); } jas_cmprof_destroy(clrprof); } else { fprintf(stderr, "JPEG 2000 LOADER ERROR: unable to create colorspace\n"); } } else { result = true; } if (result) { int ncmpts; int cmptlut[3]; if (color) { cmptlut[0] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_RGB_B); cmptlut[1] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_RGB_G); cmptlut[2] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_RGB_R); if (cmptlut[0] < 0 || cmptlut[1] < 0 || cmptlut[0] < 0) { result = false; } ncmpts = 3; } else { cmptlut[0] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_GRAY_Y); if (cmptlut[0] < 0) { result = false; } ncmpts = 1; } if (result) { for (int i = 0; i < ncmpts; i++) { int maxval = 1 << jas_image_cmptprec(image, cmptlut[i]); int offset = jas_image_cmptsgnd(image, cmptlut[i]) ? maxval / 2 : 0; int yend = jas_image_cmptbry(image, cmptlut[i]); int ystep = jas_image_cmptvstep(image, cmptlut[i]); int xend = jas_image_cmptbrx(image, cmptlut[i]); int xstep = jas_image_cmpthstep(image, cmptlut[i]); jas_matrix_t* buffer = jas_matrix_create(yend / ystep, xend / xstep); if (buffer) { if (!jas_image_readcmpt(image, cmptlut[i], 0, 0, xend / xstep, yend / ystep, buffer)) { if (img.depth() == CV_8U) { result = readComponent8u(data + i, buffer, step, cmptlut[i], maxval, offset, ncmpts); } else { result = readComponent16u(((unsigned short*)data) + i, buffer, step / 2, cmptlut[i], maxval, offset, ncmpts); } if (!result) { i = ncmpts; result = false; } } jas_matrix_destroy(buffer); } } } } else { fprintf(stderr, "JPEG2000 LOADER ERROR: colorspace conversion failed\n"); } } close(); return result; }
int imFileFormatJP2::ReadImageInfo(int index) { (void)index; // The counter is started because in Jasper all image reading is done here. BAD! ijp2_counter = this->counter; ijp2_abort = 0; ijp2_message = "Reading JP2..."; this->image = jas_image_decode(this->stream, this->fmtid, 0); ijp2_counter = -1; if (!this->image) return IM_ERR_ACCESS; this->width = jas_image_width(this->image); this->height = jas_image_height(this->image); int clrspc_fam = jas_clrspc_fam(jas_image_clrspc(image)); switch(clrspc_fam) { case JAS_CLRSPC_FAM_GRAY: this->file_color_mode = IM_GRAY; break; case JAS_CLRSPC_FAM_XYZ: this->file_color_mode = IM_XYZ; break; case JAS_CLRSPC_FAM_RGB: this->file_color_mode = IM_RGB; break; case JAS_CLRSPC_FAM_YCBCR: this->file_color_mode = IM_YCBCR; break; case JAS_CLRSPC_FAM_LAB: this->file_color_mode = IM_LAB; break; default: return IM_ERR_DATA; } this->file_data_type = IM_BYTE; int prec = jas_image_cmptprec(image, 0); if (prec > 8) this->file_data_type = IM_USHORT; if (prec < 8) this->convert_bpp = -prec; // just expand to 0-255 if (prec == 1 && this->file_color_mode == IM_GRAY) this->file_color_mode = IM_BINARY; int cmpno = jas_image_getcmptbytype(this->image, JAS_IMAGE_CT_OPACITY); if (cmpno != -1) this->file_color_mode |= IM_ALPHA; this->file_color_mode |= IM_TOPDOWN; if (image->metadata.count > 0) { imAttribTable* attrib_table = AttribTable(); // First write GeoTIFF data jas_metadata_box_t *metabox = &image->metadata.boxes[JAS_IMAGE_BOX_GEO]; if (metabox->size>0 && metabox->buf) attrib_table->Set("GeoTIFFBox", IM_BYTE, metabox->size, metabox->buf); // Check if XMP is there metabox = &image->metadata.boxes[JAS_IMAGE_BOX_XMP]; if (metabox->size>0 && metabox->buf) attrib_table->Set("XMLPacket", IM_BYTE, metabox->size, metabox->buf); } return IM_ERR_NONE; }
int jpg_encode(jas_image_t *image, jas_stream_t *out, char *optstr) { JDIMENSION numscanlines; struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; jas_image_coord_t width; jas_image_coord_t height; jpg_src_t src_mgr_buf; jpg_src_t *src_mgr = &src_mgr_buf; FILE *output_file; int cmptno; jpg_enc_t encbuf; jpg_enc_t *enc = &encbuf; jpg_encopts_t encopts; output_file = 0; if (jpg_parseencopts(optstr, &encopts)) goto error; switch (jas_clrspc_fam(jas_image_clrspc(image))) { case JAS_CLRSPC_FAM_RGB: if (jas_image_clrspc(image) != JAS_CLRSPC_SRGB) jas_eprintf("warning: inaccurate color\n"); enc->numcmpts = 3; if ((enc->cmpts[0] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R))) < 0 || (enc->cmpts[1] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G))) < 0 || (enc->cmpts[2] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B))) < 0) { jas_eprintf("error: missing color component\n"); goto error; } break; case JAS_CLRSPC_FAM_YCBCR: if (jas_image_clrspc(image) != JAS_CLRSPC_SYCBCR) jas_eprintf("warning: inaccurate color\n"); enc->numcmpts = 3; if ((enc->cmpts[0] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_Y))) < 0 || (enc->cmpts[1] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CB))) < 0 || (enc->cmpts[2] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CR))) < 0) { jas_eprintf("error: missing color component\n"); goto error; } break; case JAS_CLRSPC_FAM_GRAY: if (jas_image_clrspc(image) != JAS_CLRSPC_SGRAY) jas_eprintf("warning: inaccurate color\n"); enc->numcmpts = 1; if ((enc->cmpts[0] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y))) < 0) { jas_eprintf("error: missing color component\n"); goto error; } break; default: jas_eprintf("error: JPG format does not support color space\n"); goto error; break; } width = jas_image_width(image); height = jas_image_height(image); for (cmptno = 0; cmptno < enc->numcmpts; ++cmptno) { if (jas_image_cmptwidth(image, enc->cmpts[cmptno]) != width || jas_image_cmptheight(image, enc->cmpts[cmptno]) != height || jas_image_cmpttlx(image, enc->cmpts[cmptno]) != 0 || jas_image_cmpttly(image, enc->cmpts[cmptno]) != 0 || jas_image_cmpthstep(image, enc->cmpts[cmptno]) != 1 || jas_image_cmptvstep(image, enc->cmpts[cmptno]) != 1 || jas_image_cmptprec(image, enc->cmpts[cmptno]) != 8 || jas_image_cmptsgnd(image, enc->cmpts[cmptno]) != jas_false) { jas_eprintf("error: The JPG encoder cannot handle an image with this geometry.\n"); goto error; } } if (!(output_file = tmpfile())) { goto error; } /* Create a JPEG compression object. */ cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); /* Specify data destination for compression */ jpeg_stdio_dest(&cinfo, output_file); cinfo.in_color_space = tojpgcs(jas_image_clrspc(image)); cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = enc->numcmpts; jpeg_set_defaults(&cinfo); src_mgr->error = 0; src_mgr->image = image; src_mgr->data = jas_matrix_create(1, width); src_mgr->buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, (JDIMENSION) width * cinfo.input_components, (JDIMENSION) 1); src_mgr->buffer_height = 1; src_mgr->enc = enc; /* Read the input file header to obtain file size & colorspace. */ jpg_start_input(&cinfo, src_mgr); if (encopts.qual >= 0) { jpeg_set_quality(&cinfo, encopts.qual, jas_true); } /* Now that we know input colorspace, fix colorspace-dependent defaults */ jpeg_default_colorspace(&cinfo); /* Start compressor */ jpeg_start_compress(&cinfo, jas_true ); /* Process data */ while (cinfo.next_scanline < cinfo.image_height) { if ((numscanlines = jpg_get_pixel_rows(&cinfo, src_mgr)) <= 0) { break; } jpeg_write_scanlines(&cinfo, src_mgr->buffer, numscanlines); } /* Finish compression and release memory */ jpg_finish_input(&cinfo, src_mgr); jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); rewind(output_file); jpg_copyfiletostream(out, output_file); fclose(output_file); output_file = 0; return 0; error: if (output_file) { fclose(output_file); } return -1; }
static GstFlowReturn gst_jasper_dec_negotiate (GstJasperDec * dec, jas_image_t * image) { GstFlowReturn flow_ret = GST_FLOW_OK; gint width, height, channels; gint i, j; gboolean negotiate = FALSE; jas_clrspc_t clrspc; GstCaps *allowed_caps, *caps; width = jas_image_width (image); height = jas_image_height (image); channels = jas_image_numcmpts (image); GST_LOG_OBJECT (dec, "%d x %d, %d components", width, height, channels); /* jp2c bitstream has no real colour space info (kept in container), * so decoder may only pretend to know, where it really does not */ if (!jas_clrspc_isunknown (dec->clrspc)) { clrspc = dec->clrspc; GST_DEBUG_OBJECT (dec, "forcing container supplied colour space %d", clrspc); jas_image_setclrspc (image, clrspc); } else clrspc = jas_image_clrspc (image); if (!width || !height || !channels || jas_clrspc_isunknown (clrspc)) goto fail_image; if (dec->width != width || dec->height != height || dec->channels != channels || dec->clrspc != clrspc) negotiate = TRUE; if (channels != 3) goto not_supported; for (i = 0; i < channels; i++) { gint cheight, cwidth, depth, sgnd; cheight = jas_image_cmptheight (image, i); cwidth = jas_image_cmptwidth (image, i); depth = jas_image_cmptprec (image, i); sgnd = jas_image_cmptsgnd (image, i); GST_LOG_OBJECT (dec, "image component %d, %dx%d, depth %d, sgnd %d", i, cwidth, cheight, depth, sgnd); if (depth != 8 || sgnd) goto not_supported; if (dec->cheight[i] != cheight || dec->cwidth[i] != cwidth) { dec->cheight[i] = cheight; dec->cwidth[i] = cwidth; negotiate = TRUE; } } if (!negotiate && dec->format != GST_VIDEO_FORMAT_UNKNOWN) goto done; /* clear and refresh to new state */ flow_ret = GST_FLOW_NOT_NEGOTIATED; dec->format = GST_VIDEO_FORMAT_UNKNOWN; dec->width = width; dec->height = height; dec->channels = channels; /* retrieve allowed caps, and find the first one that reasonably maps * to the parameters of the colourspace */ caps = gst_pad_get_allowed_caps (dec->srcpad); if (!caps) { GST_DEBUG_OBJECT (dec, "... but no peer, using template caps"); /* need to copy because get_allowed_caps returns a ref, and get_pad_template_caps doesn't */ caps = gst_caps_copy (gst_pad_get_pad_template_caps (dec->srcpad)); } /* avoid lists of fourcc, etc */ allowed_caps = gst_caps_normalize (caps); caps = NULL; GST_LOG_OBJECT (dec, "allowed source caps %" GST_PTR_FORMAT, allowed_caps); for (i = 0; i < gst_caps_get_size (allowed_caps); i++) { GstVideoFormat format; gboolean ok; if (caps) gst_caps_unref (caps); caps = gst_caps_copy_nth (allowed_caps, i); /* sigh, ds and _parse_caps need fixed caps for parsing, fixate */ gst_pad_fixate_caps (dec->srcpad, caps); GST_LOG_OBJECT (dec, "checking caps %" GST_PTR_FORMAT, caps); if (!gst_video_format_parse_caps (caps, &format, NULL, NULL)) continue; if (gst_video_format_is_rgb (format) && jas_clrspc_fam (clrspc) == JAS_CLRSPC_FAM_RGB) { GST_DEBUG_OBJECT (dec, "trying RGB"); if ((dec->cmpt[0] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_RGB_R))) < 0 || (dec->cmpt[1] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_RGB_G))) < 0 || (dec->cmpt[2] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_RGB_B))) < 0) { GST_DEBUG_OBJECT (dec, "missing RGB color component"); continue; } } else if (gst_video_format_is_yuv (format) && jas_clrspc_fam (clrspc) == JAS_CLRSPC_FAM_YCBCR) { GST_DEBUG_OBJECT (dec, "trying YUV"); if ((dec->cmpt[0] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_YCBCR_Y))) < 0 || (dec->cmpt[1] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_YCBCR_CB))) < 0 || (dec->cmpt[2] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_YCBCR_CR))) < 0) { GST_DEBUG_OBJECT (dec, "missing YUV color component"); continue; } } else continue; /* match format with validity checks */ ok = TRUE; for (j = 0; j < channels; j++) { gint cmpt; cmpt = dec->cmpt[j]; if (dec->cwidth[cmpt] != gst_video_format_get_component_width (format, j, width) || dec->cheight[cmpt] != gst_video_format_get_component_height (format, j, height)) ok = FALSE; } /* commit to this format */ if (ok) { dec->format = format; break; } } if (caps) gst_caps_unref (caps); gst_caps_unref (allowed_caps); if (dec->format != GST_VIDEO_FORMAT_UNKNOWN) { /* cache some video format properties */ for (j = 0; j < channels; ++j) { dec->offset[j] = gst_video_format_get_component_offset (dec->format, j, dec->width, dec->height); dec->inc[j] = gst_video_format_get_pixel_stride (dec->format, j); dec->stride[j] = gst_video_format_get_row_stride (dec->format, j, dec->width); } dec->image_size = gst_video_format_get_size (dec->format, width, height); dec->alpha = gst_video_format_has_alpha (dec->format); if (dec->buf) g_free (dec->buf); dec->buf = g_new0 (glong, dec->width); caps = gst_video_format_new_caps (dec->format, dec->width, dec->height, dec->framerate_numerator, dec->framerate_denominator, 1, 1); GST_DEBUG_OBJECT (dec, "Set format to %d, size to %dx%d", dec->format, dec->width, dec->height); if (!gst_pad_set_caps (dec->srcpad, caps)) flow_ret = GST_FLOW_NOT_NEGOTIATED; else flow_ret = GST_FLOW_OK; gst_caps_unref (caps); } done: return flow_ret; /* ERRORS */ fail_image: { GST_DEBUG_OBJECT (dec, "Failed to process decoded image."); flow_ret = GST_FLOW_NOT_NEGOTIATED; goto done; } not_supported: { GST_DEBUG_OBJECT (dec, "Decoded image has unsupported colour space."); GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("Unsupported colorspace")); flow_ret = GST_FLOW_ERROR; goto done; } }
static void computeOutputParm(jas_image_t * const jasperP, struct pam * const outpamP, int ** const jasperCmptNoP) { int * jasperCmptNo; /* Malloc'ed array. jaspercmptNo[P] is the component number for use with the Jasper library that corresponds to Plane P of the PAM. */ switch (jas_clrspc_fam(jas_image_clrspc(jasperP))) { case JAS_CLRSPC_FAM_GRAY: outpamP->depth = 1; MALLOCARRAY_NOFAIL(jasperCmptNo, 1); getGrayComponent(&jasperCmptNo[0], jasperP); if (jas_image_cmptprec(jasperP, jasperCmptNo[0]) == 1) { outpamP->format = RPBM_FORMAT; strcpy(outpamP->tuple_type, PAM_PBM_TUPLETYPE); } else { outpamP->format = RPGM_FORMAT; strcpy(outpamP->tuple_type, PAM_PGM_TUPLETYPE); } break; case JAS_CLRSPC_FAM_RGB: outpamP->depth = 3; MALLOCARRAY_NOFAIL(jasperCmptNo, 3); getRgbComponents(jasperCmptNo, jasperP); outpamP->format = RPPM_FORMAT; strcpy(outpamP->tuple_type, PAM_PPM_TUPLETYPE); break; default: outpamP->format = PAM_FORMAT; outpamP->depth = jas_image_numcmpts(jasperP); { unsigned int plane; MALLOCARRAY_NOFAIL(jasperCmptNo, outpamP->depth); for (plane = 0; plane < outpamP->depth; ++plane) jasperCmptNo[plane] = plane; } strcpy(outpamP->tuple_type, ""); if (jas_image_cmptsgnd(jasperP, 0)) pm_message("Warning: Input image has signed sample values. " "They will be represented in the PAM output in " "two's complement."); } outpamP->plainformat = FALSE; outpamP->width = jas_image_cmptwidth(jasperP, 0); outpamP->height = jas_image_cmptheight(jasperP, 0); validateComponentsAlike(jasperP); { unsigned int const maxPrecision = maxJasperComponentPrecision(jasperP); outpamP->maxval = pm_bitstomaxval(maxPrecision); outpamP->bytes_per_sample = (maxPrecision + 7)/8; } *jasperCmptNoP = jasperCmptNo; }
int JPEG2000Dataset::DecodeImage() { if (bAlreadyDecoded) return psImage != NULL; bAlreadyDecoded = TRUE; if ( !( psImage = jas_image_decode(psStream, iFormat, 0) ) ) { CPLDebug( "JPEG2000", "Unable to decode image. Format: %s, %d", jas_image_fmttostr( iFormat ), iFormat ); return FALSE; } /* Case of a JP2 image : check that the properties given by */ /* the JP2 boxes match the ones of the code stream */ if (nBands != 0) { if (nBands != jas_image_numcmpts( psImage )) { CPLError(CE_Failure, CPLE_AppDefined, "The number of components indicated in the IHDR box (%d) mismatch " "the value specified in the code stream (%d)", nBands, jas_image_numcmpts( psImage )); jas_image_destroy( psImage ); psImage = NULL; return FALSE; } if (nRasterXSize != jas_image_cmptwidth( psImage, 0 ) || nRasterYSize != jas_image_cmptheight( psImage, 0 ) ) { CPLError(CE_Failure, CPLE_AppDefined, "The dimensions indicated in the IHDR box (%d x %d) mismatch " "the value specified in the code stream (%d x %d)", nRasterXSize, nRasterYSize, jas_image_cmptwidth( psImage, 0 ), jas_image_cmptheight( psImage, 0 )); jas_image_destroy( psImage ); psImage = NULL; return FALSE; } int iBand; for ( iBand = 0; iBand < nBands; iBand++ ) { JPEG2000RasterBand* poBand = (JPEG2000RasterBand*) GetRasterBand(iBand+1); if (poBand->iDepth != jas_image_cmptprec( psImage, iBand ) || poBand->bSignedness != jas_image_cmptsgnd( psImage, iBand )) { CPLError(CE_Failure, CPLE_AppDefined, "The bit depth of band %d indicated in the IHDR box (%d) mismatch " "the value specified in the code stream (%d)", iBand + 1, poBand->iDepth, jas_image_cmptprec( psImage, iBand )); jas_image_destroy( psImage ); psImage = NULL; return FALSE; } } } /* Ask for YCbCr -> RGB translation */ if ( jas_clrspc_fam( jas_image_clrspc( psImage ) ) == JAS_CLRSPC_FAM_YCBCR ) { jas_image_t *psRGBImage; jas_cmprof_t *psRGBProf; CPLDebug( "JPEG2000", "forcing conversion to sRGB"); if (!(psRGBProf = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB))) { CPLDebug( "JPEG2000", "cannot create sRGB profile"); return TRUE; } if (!(psRGBImage = jas_image_chclrspc(psImage, psRGBProf, JAS_CMXFORM_INTENT_PER))) { CPLDebug( "JPEG2000", "cannot convert to sRGB"); jas_cmprof_destroy(psRGBProf); return TRUE; } jas_image_destroy(psImage); jas_cmprof_destroy(psRGBProf); psImage = psRGBImage; } return TRUE; }
bool GrFmtJpeg2000Reader::ReadData( uchar* data, int step, int color ) { bool result = false; color = color > 0 || ( m_iscolor && color < 0 ); if( m_stream && m_image ) { bool convert; int colorspace; if( color ) { convert = (jas_image_clrspc( m_image ) != JAS_CLRSPC_SRGB); colorspace = JAS_CLRSPC_SRGB; } else { convert = (jas_clrspc_fam( jas_image_clrspc( m_image ) ) != JAS_CLRSPC_FAM_GRAY); colorspace = JAS_CLRSPC_SGRAY; // TODO GENGRAY or SGRAY? } // convert to the desired colorspace if( convert ) { jas_cmprof_t *clrprof = jas_cmprof_createfromclrspc( colorspace ); if( clrprof ) { jas_image_t *img = jas_image_chclrspc( m_image, clrprof, JAS_CMXFORM_INTENT_RELCLR ); if( img ) { jas_image_destroy( m_image ); m_image = img; result = true; } else fprintf(stderr, "JPEG 2000 LOADER ERROR: cannot convert colorspace\n"); jas_cmprof_destroy( clrprof ); } else fprintf(stderr, "JPEG 2000 LOADER ERROR: unable to create colorspace\n"); } else result = true; if( result ) { int ncmpts; int cmptlut[3]; if( color ) { cmptlut[0] = jas_image_getcmptbytype( m_image, JAS_IMAGE_CT_RGB_B ); cmptlut[1] = jas_image_getcmptbytype( m_image, JAS_IMAGE_CT_RGB_G ); cmptlut[2] = jas_image_getcmptbytype( m_image, JAS_IMAGE_CT_RGB_R ); if( cmptlut[0] < 0 || cmptlut[1] < 0 || cmptlut[0] < 0 ) result = false; ncmpts = 3; } else { cmptlut[0] = jas_image_getcmptbytype( m_image, JAS_IMAGE_CT_GRAY_Y ); if( cmptlut[0] < 0 ) result = false; ncmpts = 1; } if( result ) { for( int i = 0; i < ncmpts; i++ ) { int maxval = 1 << jas_image_cmptprec( m_image, cmptlut[i] ); int offset = jas_image_cmptsgnd( m_image, cmptlut[i] ) ? maxval / 2 : 0; int yend = jas_image_cmptbry( m_image, cmptlut[i] ); int ystep = jas_image_cmptvstep( m_image, cmptlut[i] ); int xend = jas_image_cmptbrx( m_image, cmptlut[i] ); int xstep = jas_image_cmpthstep( m_image, cmptlut[i] ); jas_matrix_t *buffer = jas_matrix_create( yend / ystep, xend / xstep ); if( buffer ) { if( !jas_image_readcmpt( m_image, cmptlut[i], 0, 0, xend / xstep, yend / ystep, buffer )) { if( m_bit_depth == 8 || !m_native_depth ) result = ReadComponent8u( data + i, buffer, step, cmptlut[i], maxval, offset, ncmpts ); else result = ReadComponent16u( ((unsigned short *)data) + i, buffer, step / 2, cmptlut[i], maxval, offset, ncmpts ); if( !result ) { i = ncmpts; result = false; } } jas_matrix_destroy( buffer ); } } } } else fprintf(stderr, "JPEG2000 LOADER ERROR: colorspace conversion failed\n" ); } Close(); return result; }
static Image *ReadJP2Image(const ImageInfo *image_info,ExceptionInfo *exception) { Image *image; jas_cmprof_t *cm_profile; jas_iccprof_t *icc_profile; jas_image_t *jp2_image; jas_matrix_t *pixels[4]; jas_stream_t *jp2_stream; long components[4], y; MagickBooleanType status; QuantumAny pixel, *map[4], range; register long i, x; register PixelPacket *q; unsigned long maximum_component_depth, number_components, x_step[4], y_step[4]; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Initialize JPEG 2000 API. */ jp2_stream=JP2StreamManager(image); if (jp2_stream == (jas_stream_t *) NULL) ThrowReaderException(DelegateError,"UnableToManageJP2Stream"); jp2_image=jas_image_decode(jp2_stream,-1,0); if (jp2_image == (jas_image_t *) NULL) { (void) jas_stream_close(jp2_stream); ThrowReaderException(DelegateError,"UnableToDecodeImageFile"); } switch (jas_clrspc_fam(jas_image_clrspc(jp2_image))) { case JAS_CLRSPC_FAM_RGB: { components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_R); components[1]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_G); components[2]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_B); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=3; components[3]=jas_image_getcmptbytype(jp2_image,3); if (components[3] > 0) { image->matte=MagickTrue; number_components++; } break; } case JAS_CLRSPC_FAM_GRAY: { components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_GRAY_Y); if (components[0] < 0) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=1; break; } case JAS_CLRSPC_FAM_YCBCR: { components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_Y); components[1]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CB); components[2]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CR); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=3; components[3]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_UNKNOWN); if (components[3] > 0) { image->matte=MagickTrue; number_components++; } image->colorspace=YCbCrColorspace; break; } default: { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CoderError,"ColorspaceModelIsNotSupported"); } } image->columns=jas_image_width(jp2_image); image->rows=jas_image_height(jp2_image); image->compression=JPEG2000Compression; for (i=0; i < (long) number_components; i++) { unsigned long height, width; width=(unsigned long) (jas_image_cmptwidth(jp2_image,components[i])* jas_image_cmpthstep(jp2_image,components[i])); height=(unsigned long) (jas_image_cmptheight(jp2_image,components[i])* jas_image_cmptvstep(jp2_image,components[i])); x_step[i]=(unsigned int) jas_image_cmpthstep(jp2_image,components[i]); y_step[i]=(unsigned int) jas_image_cmptvstep(jp2_image,components[i]); if ((width != image->columns) || (height != image->rows) || (jas_image_cmpttlx(jp2_image,components[i]) != 0) || (jas_image_cmpttly(jp2_image,components[i]) != 0) || (x_step[i] != 1) || (y_step[i] != 1) || (jas_image_cmptsgnd(jp2_image,components[i]) != MagickFalse)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CoderError,"IrregularChannelGeometryNotSupported"); } } /* Convert JPEG 2000 pixels. */ image->matte=number_components > 3 ? MagickTrue : MagickFalse; maximum_component_depth=0; for (i=0; i < (long) number_components; i++) { maximum_component_depth=(unsigned int) MagickMax((size_t) jas_image_cmptprec(jp2_image,components[i]),(size_t) maximum_component_depth); pixels[i]=jas_matrix_create(1,(int) (image->columns/x_step[i])); if (pixels[i] == (jas_matrix_t *) NULL) { for (--i; i >= 0; i--) jas_matrix_destroy(pixels[i]); jas_image_destroy(jp2_image); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } } image->depth=maximum_component_depth; if (image_info->ping != MagickFalse) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); return(GetFirstImageInList(image)); } for (i=0; i < (long) number_components; i++) { long j; map[i]=(QuantumAny *) AcquireQuantumMemory(MaxMap+1,sizeof(**map)); if (map[i] == (QuantumAny *) NULL) { for (--i; i >= 0; i--) map[i]=(QuantumAny *) RelinquishMagickMemory(map[i]); for (i=0; i < (long) number_components; i++) jas_matrix_destroy(pixels[i]); jas_image_destroy(jp2_image); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } range=GetQuantumRange((unsigned long) jas_image_cmptprec(jp2_image, components[i])); for (j=0; j <= (long) MaxMap; j++) map[i][j]=ScaleQuantumToMap(ScaleAnyToQuantum((QuantumAny) j,range)); } for (y=0; y < (long) image->rows; y++) { q=GetAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (i=0; i < (long) number_components; i++) (void) jas_image_readcmpt(jp2_image,(short) components[i],0, ((unsigned int) y)/y_step[i],((unsigned int) image->columns)/x_step[i], 1,pixels[i]); switch (number_components) { case 1: { /* Grayscale. */ for (x=0; x < (long) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); q->red=(Quantum) map[0][pixel]; q->green=q->red; q->blue=q->red; q++; } break; } case 3: { /* RGB. */ for (x=0; x < (long) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); q->red=(Quantum) map[0][pixel]; pixel=(QuantumAny) jas_matrix_getv(pixels[1],x/x_step[1]); q->green=(Quantum) map[1][pixel]; pixel=(QuantumAny) jas_matrix_getv(pixels[2],x/x_step[2]); q->blue=(Quantum) map[2][pixel]; q++; } break; } case 4: { /* RGBA. */ for (x=0; x < (long) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); q->red=(Quantum) map[0][pixel]; pixel=(QuantumAny) jas_matrix_getv(pixels[1],x/x_step[1]); q->green=(Quantum) map[1][pixel]; pixel=(QuantumAny) jas_matrix_getv(pixels[2],x/x_step[2]); q->blue=(Quantum) map[2][pixel]; pixel=(QuantumAny) jas_matrix_getv(pixels[3],x/x_step[3]); q->opacity=(Quantum) (QuantumRange-map[3][pixel]); q++; } break; } } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; status=SetImageProgress(image,LoadImageTag,y,image->rows); if (status == MagickFalse) break; } for (i=0; i < (long) number_components; i++) map[i]=(QuantumAny *) RelinquishMagickMemory(map[i]); cm_profile=jas_image_cmprof(jp2_image); icc_profile=(jas_iccprof_t *) NULL; if (cm_profile != (jas_cmprof_t *) NULL) icc_profile=jas_iccprof_createfromcmprof(cm_profile); if (icc_profile != (jas_iccprof_t *) NULL) { jas_stream_t *icc_stream; icc_stream=jas_stream_memopen(NULL,0); if ((icc_stream != (jas_stream_t *) NULL) && (jas_iccprof_save(icc_profile,icc_stream) == 0) && (jas_stream_flush(icc_stream) == 0)) { StringInfo *icc_profile, *profile; jas_stream_memobj_t *blob; /* Extract the icc profile, handle errors without much noise. */ blob=(jas_stream_memobj_t *) icc_stream->obj_; if (image->debug != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Profile: ICC, %lu bytes",(unsigned long) blob->len_); profile=AcquireStringInfo(blob->len_); SetStringInfoDatum(profile,blob->buf_); icc_profile=(StringInfo *) GetImageProfile(image,"icc"); if (icc_profile == (StringInfo *) NULL) (void) SetImageProfile(image,"icc",profile); else (void) ConcatenateStringInfo(icc_profile,profile); profile=DestroyStringInfo(profile); (void) jas_stream_close(icc_stream); } } (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); for (i=0; i < (long) number_components; i++) jas_matrix_destroy(pixels[i]); return(GetFirstImageInList(image)); }
bool JP2KLoader::load(const QString& filePath, DImgLoaderObserver* observer) { readMetadata(filePath, DImg::JPEG); FILE* file = fopen(QFile::encodeName(filePath), "rb"); if (!file) { loadingFailed(); return false; } unsigned char header[9]; if (fread(&header, 9, 1, file) != 1) { fclose(file); loadingFailed(); return false; } unsigned char jp2ID[5] = { 0x6A, 0x50, 0x20, 0x20, 0x0D, }; unsigned char jpcID[2] = { 0xFF, 0x4F }; if (memcmp(&header[4], &jp2ID, 5) != 0 && memcmp(&header, &jpcID, 2) != 0) { // not a jpeg2000 file fclose(file); loadingFailed(); return false; } fclose(file); imageSetAttribute("format", "JP2K"); if (!(m_loadFlags & LoadImageData) && !(m_loadFlags & LoadICCData)) { // libjasper will load the full image in memory already when calling jas_image_decode. // This is bad when scanning. See bugs 215458 and 195583. //FIXME: Use Exiv2 or OpenJPEG to extract this info DMetadata metadata(filePath); QSize size = metadata.getImageDimensions(); if (size.isValid()) { imageWidth() = size.width(); imageHeight() = size.height(); } return true; } // ------------------------------------------------------------------- // Initialize JPEG 2000 API. register long i, x, y; int components[4]; unsigned int maximum_component_depth, scale[4], x_step[4], y_step[4]; unsigned long number_components; jas_image_t* jp2_image = 0; jas_stream_t* jp2_stream = 0; jas_matrix_t* pixels[4]; int init = jas_init(); if (init != 0) { kDebug() << "Unable to init JPEG2000 decoder"; loadingFailed(); return false; } jp2_stream = jas_stream_fopen(QFile::encodeName(filePath), "rb"); if (jp2_stream == 0) { kDebug() << "Unable to open JPEG2000 stream"; loadingFailed(); return false; } jp2_image = jas_image_decode(jp2_stream, -1, 0); if (jp2_image == 0) { jas_stream_close(jp2_stream); kDebug() << "Unable to decode JPEG2000 image"; loadingFailed(); return false; } jas_stream_close(jp2_stream); // some pseudo-progress if (observer) { observer->progressInfo(m_image, 0.1F); } // ------------------------------------------------------------------- // Check color space. int colorModel; switch (jas_clrspc_fam(jas_image_clrspc(jp2_image))) { case JAS_CLRSPC_FAM_RGB: { components[0] = jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_RGB_R); components[1] = jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_RGB_G); components[2] = jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_RGB_B); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { jas_image_destroy(jp2_image); kDebug() << "Error parsing JPEG2000 image : Missing Image Channel"; loadingFailed(); return false; } number_components = 3; components[3] = jas_image_getcmptbytype(jp2_image, 3); if (components[3] > 0) { m_hasAlpha = true; ++number_components; } colorModel = DImg::RGB; break; } case JAS_CLRSPC_FAM_GRAY: { components[0] = jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_GRAY_Y); if (components[0] < 0) { jas_image_destroy(jp2_image); kDebug() << "Error parsing JP2000 image : Missing Image Channel"; loadingFailed(); return false; } number_components = 1; colorModel = DImg::GRAYSCALE; break; } case JAS_CLRSPC_FAM_YCBCR: { components[0] = jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_YCBCR_Y); components[1] = jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_YCBCR_CB); components[2] = jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_YCBCR_CR); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { jas_image_destroy(jp2_image); kDebug() << "Error parsing JP2000 image : Missing Image Channel"; loadingFailed(); return false; } number_components = 3; components[3] = jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_UNKNOWN); if (components[3] > 0) { m_hasAlpha = true; ++number_components; } // FIXME : image->colorspace=YCbCrColorspace; colorModel = DImg::YCBCR; break; } default: { jas_image_destroy(jp2_image); kDebug() << "Error parsing JP2000 image : Colorspace Model Is Not Supported"; loadingFailed(); return false; } } // ------------------------------------------------------------------- // Check image geometry. imageWidth() = jas_image_width(jp2_image); imageHeight() = jas_image_height(jp2_image); for (i = 0; i < (long)number_components; ++i) { if ((((jas_image_cmptwidth(jp2_image, components[i])* jas_image_cmpthstep(jp2_image, components[i])) != (long)imageWidth())) || (((jas_image_cmptheight(jp2_image, components[i])* jas_image_cmptvstep(jp2_image, components[i])) != (long)imageHeight())) || (jas_image_cmpttlx(jp2_image, components[i]) != 0) || (jas_image_cmpttly(jp2_image, components[i]) != 0) || (jas_image_cmptsgnd(jp2_image, components[i]) != false)) { jas_image_destroy(jp2_image); kDebug() << "Error parsing JPEG2000 image : Irregular Channel Geometry Not Supported"; loadingFailed(); return false; } x_step[i] = jas_image_cmpthstep(jp2_image, components[i]); y_step[i] = jas_image_cmptvstep(jp2_image, components[i]); } // ------------------------------------------------------------------- // Get image format. m_hasAlpha = number_components > 3; maximum_component_depth = 0; for (i = 0; i < (long)number_components; ++i) { maximum_component_depth = qMax((long)jas_image_cmptprec(jp2_image,components[i]), (long)maximum_component_depth); pixels[i] = jas_matrix_create(1, ((unsigned int)imageWidth())/x_step[i]); if (!pixels[i]) { jas_image_destroy(jp2_image); kDebug() << "Error decoding JPEG2000 image data : Memory Allocation Failed"; loadingFailed(); return false; } } if (maximum_component_depth > 8) { m_sixteenBit = true; } for (i = 0 ; i < (long)number_components ; ++i) { scale[i] = 1; int prec = jas_image_cmptprec(jp2_image, components[i]); if (m_sixteenBit && prec < 16) { scale[i] = (1 << (16 - jas_image_cmptprec(jp2_image, components[i]))); } } // ------------------------------------------------------------------- // Get image data. uchar* data = 0; if (m_loadFlags & LoadImageData) { if (m_sixteenBit) // 16 bits image. { data = new_failureTolerant(imageWidth()*imageHeight()*8); } else { data = new_failureTolerant(imageWidth()*imageHeight()*4); } if (!data) { kDebug() << "Error decoding JPEG2000 image data : Memory Allocation Failed"; jas_image_destroy(jp2_image); for (i = 0 ; i < (long)number_components ; ++i) { jas_matrix_destroy(pixels[i]); } jas_cleanup(); loadingFailed(); return false; } uint checkPoint = 0; uchar* dst = data; unsigned short* dst16 = (unsigned short*)data; for (y = 0 ; y < (long)imageHeight() ; ++y) { for (i = 0 ; i < (long)number_components; ++i) { int ret = jas_image_readcmpt(jp2_image, (short)components[i], 0, ((unsigned int) y) / y_step[i], ((unsigned int) imageWidth()) / x_step[i], 1, pixels[i]); if (ret != 0) { kDebug() << "Error decoding JPEG2000 image data"; delete [] data; jas_image_destroy(jp2_image); for (i = 0 ; i < (long)number_components ; ++i) { jas_matrix_destroy(pixels[i]); } jas_cleanup(); loadingFailed(); return false; } } switch (number_components) { case 1: // Grayscale. { for (x = 0 ; x < (long)imageWidth() ; ++x) { dst[0] = (uchar)(scale[0]*jas_matrix_getv(pixels[0], x/x_step[0])); dst[1] = dst[0]; dst[2] = dst[0]; dst[3] = 0xFF; dst += 4; } break; } case 3: // RGB. { if (!m_sixteenBit) // 8 bits image. { for (x = 0 ; x < (long)imageWidth() ; ++x) { // Blue dst[0] = (uchar)(scale[2]*jas_matrix_getv(pixels[2], x/x_step[2])); // Green dst[1] = (uchar)(scale[1]*jas_matrix_getv(pixels[1], x/x_step[1])); // Red dst[2] = (uchar)(scale[0]*jas_matrix_getv(pixels[0], x/x_step[0])); // Alpha dst[3] = 0xFF; dst += 4; } } else // 16 bits image. { for (x = 0 ; x < (long)imageWidth() ; ++x) { // Blue dst16[0] = (unsigned short)(scale[2]*jas_matrix_getv(pixels[2], x/x_step[2])); // Green dst16[1] = (unsigned short)(scale[1]*jas_matrix_getv(pixels[1], x/x_step[1])); // Red dst16[2] = (unsigned short)(scale[0]*jas_matrix_getv(pixels[0], x/x_step[0])); // Alpha dst16[3] = 0xFFFF; dst16 += 4; } } break; } case 4: // RGBA. { if (!m_sixteenBit) // 8 bits image. { for (x = 0 ; x < (long)imageWidth() ; ++x) { // Blue dst[0] = (uchar)(scale[2] * jas_matrix_getv(pixels[2], x/x_step[2])); // Green dst[1] = (uchar)(scale[1] * jas_matrix_getv(pixels[1], x/x_step[1])); // Red dst[2] = (uchar)(scale[0] * jas_matrix_getv(pixels[0], x/x_step[0])); // Alpha dst[3] = (uchar)(scale[3] * jas_matrix_getv(pixels[3], x/x_step[3])); dst += 4; } } else // 16 bits image. { for (x = 0 ; x < (long)imageWidth() ; ++x) { // Blue dst16[0] = (unsigned short)(scale[2]*jas_matrix_getv(pixels[2], x/x_step[2])); // Green dst16[1] = (unsigned short)(scale[1]*jas_matrix_getv(pixels[1], x/x_step[1])); // Red dst16[2] = (unsigned short)(scale[0]*jas_matrix_getv(pixels[0], x/x_step[0])); // Alpha dst16[3] = (unsigned short)(scale[3]*jas_matrix_getv(pixels[3], x/x_step[3])); dst16 += 4; } } break; } } // use 0-10% and 90-100% for pseudo-progress if (observer && y >= (long)checkPoint) { checkPoint += granularity(observer, y, 0.8F); if (!observer->continueQuery(m_image)) { delete [] data; jas_image_destroy(jp2_image); for (i = 0 ; i < (long)number_components ; ++i) { jas_matrix_destroy(pixels[i]); } jas_cleanup(); loadingFailed(); return false; } observer->progressInfo(m_image, 0.1 + (0.8 * ( ((float)y)/((float)imageHeight()) ))); } } } // ------------------------------------------------------------------- // Get ICC color profile. if (m_loadFlags & LoadICCData) { jas_iccprof_t* icc_profile = 0; jas_stream_t* icc_stream = 0; jas_cmprof_t* cm_profile = 0; cm_profile = jas_image_cmprof(jp2_image); if (cm_profile != 0) { icc_profile = jas_iccprof_createfromcmprof(cm_profile); } if (icc_profile != 0) { icc_stream = jas_stream_memopen(NULL, 0); if (icc_stream != 0) { if (jas_iccprof_save(icc_profile, icc_stream) == 0) { if (jas_stream_flush(icc_stream) == 0) { jas_stream_memobj_t* blob = (jas_stream_memobj_t*) icc_stream->obj_; QByteArray profile_rawdata; profile_rawdata.resize(blob->len_); memcpy(profile_rawdata.data(), blob->buf_, blob->len_); imageSetIccProfile(profile_rawdata); jas_stream_close(icc_stream); } } } } } if (observer) { observer->progressInfo(m_image, 1.0); } imageData() = data; imageSetAttribute("format", "JP2K"); imageSetAttribute("originalColorModel", colorModel); imageSetAttribute("originalBitDepth", maximum_component_depth); imageSetAttribute("originalSize", QSize(imageWidth(), imageHeight())); jas_image_destroy(jp2_image); for (i = 0 ; i < (long)number_components ; ++i) { jas_matrix_destroy(pixels[i]); } jas_cleanup(); return true; }
static Image *ReadJP2Image(const ImageInfo *image_info, ExceptionInfo *exception) { Image *image; long y; jas_image_t *jp2_image; jas_matrix_t *pixels; jas_stream_t *jp2_stream; register long x; register PixelPacket *q; int component, components[4], number_components; Quantum *channel_lut[4]; unsigned int status; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AllocateImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == False) ThrowReaderException(FileOpenError,UnableToOpenFile,image); /* Obtain a JP2 Stream. */ jp2_stream=JP2StreamManager(image); if (jp2_stream == (jas_stream_t *) NULL) ThrowReaderException(DelegateError,UnableToManageJP2Stream,image); jp2_image=jas_image_decode(jp2_stream,-1,0); if (jp2_image == (jas_image_t *) NULL) { (void) jas_stream_close(jp2_stream); ThrowReaderException(DelegateError,UnableToDecodeImageFile,image); } /* Validate that we can handle the image and obtain component indexes. */ switch (jas_clrspc_fam(jas_image_clrspc(jp2_image))) { case JAS_CLRSPC_FAM_RGB: { if (((components[0]= jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R))) < 0) || ((components[1]= jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G))) < 0) || ((components[2]= jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B))) < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,MissingImageChannel,image); } number_components=3; (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Image is in RGB colorspace family"); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "RED is in channel %d, GREEN is in channel %d, BLUE is in channel %d", components[0],components[1],components[2]); if((components[3]=jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_OPACITY))) > 0) { image->matte=MagickTrue; (void) LogMagickEvent(CoderEvent,GetMagickModule(), "OPACITY is in channel %d",components[3]); number_components++; } break; } case JAS_CLRSPC_FAM_GRAY: { if ((components[0]= jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y))) < 0) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,MissingImageChannel,image); } (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Image is in GRAY colorspace family"); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "GRAY is in channel %d",components[0]); number_components=1; break; } case JAS_CLRSPC_FAM_YCBCR: { components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_Y); components[1]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CB); components[2]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CR); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,MissingImageChannel,image); } number_components=3; components[3]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_OPACITY); if (components[3] > 0) { image->matte=True; number_components++; } image->colorspace=YCbCrColorspace; (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Image is in YCBCR colorspace family"); break; } default: { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CoderError,ColorspaceModelIsNotSupported,image); } } image->columns=jas_image_width(jp2_image); image->rows=jas_image_height(jp2_image); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "columns=%lu rows=%lu components=%d",image->columns,image->rows, number_components); for (component=0; component < number_components; component++) { if(((unsigned long) jas_image_cmptwidth(jp2_image,components[component]) != image->columns) || ((unsigned long) jas_image_cmptheight(jp2_image,components[component]) != image->rows) || (jas_image_cmpttlx(jp2_image, components[component]) != 0) || (jas_image_cmpttly(jp2_image, components[component]) != 0) || (jas_image_cmpthstep(jp2_image, components[component]) != 1) || (jas_image_cmptvstep(jp2_image, components[component]) != 1) || (jas_image_cmptsgnd(jp2_image, components[component]) != false)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CoderError,IrregularChannelGeometryNotSupported,image); } } image->matte=number_components > 3; for (component=0; component < number_components; component++) { unsigned int component_depth; component_depth=jas_image_cmptprec(jp2_image,components[component]); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Component[%d] depth is %u",component,component_depth); if (0 == component) image->depth=component_depth; else image->depth=Max(image->depth,component_depth); } (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Image depth is %u",image->depth); if (image_info->ping) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); return(image); } /* Allocate Jasper pixels. */ pixels=jas_matrix_create(1,(unsigned int) image->columns); if (pixels == (jas_matrix_t *) NULL) { jas_image_destroy(jp2_image); ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); } /* Allocate and populate channel LUTs */ for (component=0; component < (long) number_components; component++) { unsigned long component_depth, i, max_value; double scale_to_quantum; component_depth=jas_image_cmptprec(jp2_image,components[component]); max_value=MaxValueGivenBits(component_depth); scale_to_quantum=MaxRGBDouble/max_value; (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Channel %d scale is %g", component, scale_to_quantum); channel_lut[component]=MagickAllocateArray(Quantum *,max_value+1,sizeof(Quantum)); if (channel_lut[component] == (Quantum *) NULL) { for ( --component; component >= 0; --component) MagickFreeMemory(channel_lut[component]); jas_matrix_destroy(pixels); jas_image_destroy(jp2_image); ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); } for(i=0; i <= max_value; i++) (channel_lut[component])[i]=scale_to_quantum*i+0.5; } /* Convert JPEG 2000 pixels. */ for (y=0; y < (long) image->rows; y++) { q=GetImagePixels(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) break; if (1 == number_components) { /* Grayscale */ (void) jas_image_readcmpt(jp2_image,(short) components[0],0, (unsigned int) y, (unsigned int) image->columns,1,pixels); for (x=0; x < (long) image->columns; x++) { q->red=q->green=q->blue=(channel_lut[0])[jas_matrix_getv(pixels,x)]; q->opacity=OpaqueOpacity; q++; } } else { /* Red */ (void) jas_image_readcmpt(jp2_image,(short) components[0],0, (unsigned int) y, (unsigned int) image->columns,1,pixels); for (x=0; x < (long) image->columns; x++) q[x].red=(channel_lut[0])[jas_matrix_getv(pixels,x)]; /* Green */ (void) jas_image_readcmpt(jp2_image,(short) components[1],0, (unsigned int) y, (unsigned int) image->columns,1,pixels); for (x=0; x < (long) image->columns; x++) q[x].green=(channel_lut[1])[jas_matrix_getv(pixels,x)]; /* Blue */ (void) jas_image_readcmpt(jp2_image,(short) components[2],0, (unsigned int) y, (unsigned int) image->columns,1,pixels); for (x=0; x < (long) image->columns; x++) q[x].blue=(channel_lut[2])[jas_matrix_getv(pixels,x)]; /* Opacity */ if (number_components > 3) { (void) jas_image_readcmpt(jp2_image,(short) components[3],0, (unsigned int) y, (unsigned int) image->columns,1,pixels); for (x=0; x < (long) image->columns; x++) q[x].opacity=MaxRGB-(channel_lut[3])[jas_matrix_getv(pixels,x)]; } else { for (x=0; x < (long) image->columns; x++) q[x].opacity=OpaqueOpacity; } } if (!SyncImagePixels(image)) break; if (image->previous == (Image *) NULL) if (QuantumTick(y,image->rows)) if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText, image->filename, image->columns,image->rows)) break; } if (number_components == 1) image->is_grayscale=MagickTrue; { /* Obtain ICC ICM color profile */ jas_cmprof_t *cm_profile; /* Obtain a pointer to the existing jas_cmprof_t profile handle. */ cm_profile=jas_image_cmprof(jp2_image); if (cm_profile != (jas_cmprof_t *) NULL) { jas_iccprof_t *icc_profile; /* Obtain a copy of the jas_iccprof_t ICC profile handle */ icc_profile=jas_iccprof_createfromcmprof(cm_profile); /* or maybe just icc_profile=cm_profile->iccprof */ if (icc_profile != (jas_iccprof_t *) NULL) { jas_stream_t *icc_stream; icc_stream=jas_stream_memopen(NULL,0); if ((icc_stream != (jas_stream_t *) NULL) && (jas_iccprof_save(icc_profile,icc_stream) == 0) && (jas_stream_flush(icc_stream) == 0)) { jas_stream_memobj_t *blob; blob=(jas_stream_memobj_t *) icc_stream->obj_; if (image->logging) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "ICC profile: %lu bytes",(unsigned long) blob->len_); SetImageProfile(image,"ICM",blob->buf_,blob->len_); (void) jas_stream_close(icc_stream); jas_iccprof_destroy(icc_profile); } } } } for (component=0; component < (long) number_components; component++) MagickFreeMemory(channel_lut[component]); jas_matrix_destroy(pixels); (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); return(image); }
(int)jas_image_width(image), (int)jas_image_height(image)); /* sort the colorspace */ if jas_clrspc_isunknown(clrspc) csname = "unknown"; else switch (clrspc) { case JAS_CLRSPC_CIEXYZ: csname = "CIE XYZ"; break; case JAS_CLRSPC_CIELAB: csname = "CIE Lab"; break; case JAS_CLRSPC_SGRAY: csname = "calibrated grayscale"; break; case JAS_CLRSPC_SRGB: csname = "sRGB"; break; case JAS_CLRSPC_SYCBCR: csname = "calibrated YCbCr"; break; case JAS_CLRSPC_GENGRAY: csname = "generic gray"; break; case JAS_CLRSPC_GENRGB: csname = "generic RGB"; break; case JAS_CLRSPC_GENYCBCR: csname = "generic YCbCr"; break; } if_debug3('w',"[w] colorspace is %s (family %d, member %d)\n", csname, jas_clrspc_fam(clrspc), jas_clrspc_mbr(clrspc)); for (i = 0; i < numcmpts; i++) { int type = jas_image_cmpttype(image, i); const char *opacity = (type & JAS_IMAGE_CT_OPACITY) ? " opacity" : ""; const char *name = "unrecognized"; const char *issigned = ""; if (jas_clrspc_fam(clrspc) == JAS_CLRSPC_FAM_GRAY) name = "gray"; else if (jas_clrspc_fam(clrspc) == JAS_CLRSPC_FAM_RGB) switch (JAS_IMAGE_CT_COLOR(type)) { case JAS_IMAGE_CT_RGB_R: name = "red"; break; case JAS_IMAGE_CT_RGB_G: name = "green"; break; case JAS_IMAGE_CT_RGB_B: name = "blue"; break; case JAS_IMAGE_CT_UNKNOWN: default:
static Image *ReadJP2Image(const ImageInfo *image_info,ExceptionInfo *exception) { Image *image; jas_cmprof_t *cm_profile; jas_iccprof_t *icc_profile; jas_image_t *jp2_image; jas_matrix_t *pixels[4]; jas_stream_t *jp2_stream; MagickBooleanType status; QuantumAny pixel, range[4]; register Quantum *q; register ssize_t i, x; size_t maximum_component_depth, number_components, x_step[4], y_step[4]; ssize_t components[4], y; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info,exception); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Initialize JPEG 2000 API. */ jp2_stream=JP2StreamManager(image); if (jp2_stream == (jas_stream_t *) NULL) ThrowReaderException(DelegateError,"UnableToManageJP2Stream"); jp2_image=jas_image_decode(jp2_stream,-1,0); if (jp2_image == (jas_image_t *) NULL) { (void) jas_stream_close(jp2_stream); ThrowReaderException(DelegateError,"UnableToDecodeImageFile"); } image->columns=jas_image_width(jp2_image); image->rows=jas_image_height(jp2_image); image->compression=JPEG2000Compression; switch (jas_clrspc_fam(jas_image_clrspc(jp2_image))) { case JAS_CLRSPC_FAM_RGB: { SetImageColorspace(image,RGBColorspace,exception); components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_R); components[1]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_G); components[2]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_B); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=3; components[3]=jas_image_getcmptbytype(jp2_image,3); if (components[3] > 0) { image->alpha_trait=BlendPixelTrait; number_components++; } break; } case JAS_CLRSPC_FAM_GRAY: { SetImageColorspace(image,GRAYColorspace,exception); components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_GRAY_Y); if (components[0] < 0) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=1; break; } case JAS_CLRSPC_FAM_YCBCR: { SetImageColorspace(image,YCbCrColorspace,exception); components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_Y); components[1]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CB); components[2]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CR); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=3; components[3]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_UNKNOWN); if (components[3] > 0) { image->alpha_trait=BlendPixelTrait; number_components++; } break; } case JAS_CLRSPC_FAM_XYZ: { SetImageColorspace(image,XYZColorspace,exception); components[0]=jas_image_getcmptbytype(jp2_image,0); components[1]=jas_image_getcmptbytype(jp2_image,1); components[2]=jas_image_getcmptbytype(jp2_image,2); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=3; components[3]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_UNKNOWN); if (components[3] > 0) { image->alpha_trait=BlendPixelTrait; number_components++; } break; } case JAS_CLRSPC_FAM_LAB: { SetImageColorspace(image,LabColorspace,exception); components[0]=jas_image_getcmptbytype(jp2_image,0); components[1]=jas_image_getcmptbytype(jp2_image,1); components[2]=jas_image_getcmptbytype(jp2_image,2); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=3; components[3]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_UNKNOWN); if (components[3] > 0) { image->alpha_trait=BlendPixelTrait; number_components++; } break; } default: { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CoderError,"ColorspaceModelIsNotSupported"); } } for (i=0; i < (ssize_t) number_components; i++) { size_t height, width; width=(size_t) (jas_image_cmptwidth(jp2_image,components[i])* jas_image_cmpthstep(jp2_image,components[i])); height=(size_t) (jas_image_cmptheight(jp2_image,components[i])* jas_image_cmptvstep(jp2_image,components[i])); x_step[i]=(unsigned int) jas_image_cmpthstep(jp2_image,components[i]); y_step[i]=(unsigned int) jas_image_cmptvstep(jp2_image,components[i]); if ((width != image->columns) || (height != image->rows) || (jas_image_cmpttlx(jp2_image,components[i]) != 0) || (jas_image_cmpttly(jp2_image,components[i]) != 0) || (jas_image_cmptsgnd(jp2_image,components[i]) != MagickFalse)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CoderError,"IrregularChannelGeometryNotSupported"); } } /* Convert JPEG 2000 pixels. */ image->alpha_trait=number_components > 3 ? BlendPixelTrait : UndefinedPixelTrait; maximum_component_depth=0; for (i=0; i < (ssize_t) number_components; i++) { maximum_component_depth=(unsigned int) MagickMax((size_t) jas_image_cmptprec(jp2_image,components[i]),(size_t) maximum_component_depth); pixels[i]=jas_matrix_create(1,(int) (image->columns/x_step[i])); if (pixels[i] == (jas_matrix_t *) NULL) { for (--i; i >= 0; i--) jas_matrix_destroy(pixels[i]); jas_image_destroy(jp2_image); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } } image->depth=maximum_component_depth; if (image_info->ping != MagickFalse) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); return(GetFirstImageInList(image)); } for (i=0; i < (ssize_t) number_components; i++) range[i]=GetQuantumRange((size_t) jas_image_cmptprec(jp2_image, components[i])); for (y=0; y < (ssize_t) image->rows; y++) { q=GetAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (Quantum *) NULL) break; for (i=0; i < (ssize_t) number_components; i++) (void) jas_image_readcmpt(jp2_image,(short) components[i],0, (jas_image_coord_t) (y/y_step[i]),(jas_image_coord_t) (image->columns/ x_step[i]),1,pixels[i]); switch (number_components) { case 1: { /* Grayscale. */ for (x=0; x < (ssize_t) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); SetPixelGray(image,ScaleAnyToQuantum((QuantumAny) pixel,range[0]),q); q+=GetPixelChannels(image); } break; } case 3: { /* RGB. */ for (x=0; x < (ssize_t) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); SetPixelRed(image,ScaleAnyToQuantum((QuantumAny) pixel,range[0]),q); pixel=(QuantumAny) jas_matrix_getv(pixels[1],x/x_step[1]); SetPixelGreen(image,ScaleAnyToQuantum((QuantumAny) pixel,range[1]),q); pixel=(QuantumAny) jas_matrix_getv(pixels[2],x/x_step[2]); SetPixelBlue(image,ScaleAnyToQuantum((QuantumAny) pixel,range[2]),q); q+=GetPixelChannels(image); } break; } case 4: { /* RGBA. */ for (x=0; x < (ssize_t) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); SetPixelRed(image,ScaleAnyToQuantum((QuantumAny) pixel,range[0]),q); pixel=(QuantumAny) jas_matrix_getv(pixels[1],x/x_step[1]); SetPixelGreen(image,ScaleAnyToQuantum((QuantumAny) pixel,range[1]),q); pixel=(QuantumAny) jas_matrix_getv(pixels[2],x/x_step[2]); SetPixelBlue(image,ScaleAnyToQuantum((QuantumAny) pixel,range[2]),q); pixel=(QuantumAny) jas_matrix_getv(pixels[3],x/x_step[3]); SetPixelAlpha(image,ScaleAnyToQuantum((QuantumAny) pixel,range[3]),q); q+=GetPixelChannels(image); } break; } } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } cm_profile=jas_image_cmprof(jp2_image); icc_profile=(jas_iccprof_t *) NULL; if (cm_profile != (jas_cmprof_t *) NULL) icc_profile=jas_iccprof_createfromcmprof(cm_profile); if (icc_profile != (jas_iccprof_t *) NULL) { jas_stream_t *icc_stream; icc_stream=jas_stream_memopen(NULL,0); if ((icc_stream != (jas_stream_t *) NULL) && (jas_iccprof_save(icc_profile,icc_stream) == 0) && (jas_stream_flush(icc_stream) == 0)) { jas_stream_memobj_t *blob; StringInfo *icc_profile, *profile; /* Extract the icc profile, handle errors without much noise. */ blob=(jas_stream_memobj_t *) icc_stream->obj_; if (image->debug != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Profile: ICC, %.20g bytes",(double) blob->len_); profile=BlobToStringInfo(blob->buf_,blob->len_); if (profile == (StringInfo *) NULL) ThrowReaderException(CorruptImageError,"MemoryAllocationFailed"); icc_profile=(StringInfo *) GetImageProfile(image,"icc"); if (icc_profile == (StringInfo *) NULL) (void) SetImageProfile(image,"icc",profile,exception); else (void) ConcatenateStringInfo(icc_profile,profile); profile=DestroyStringInfo(profile); (void) jas_stream_close(icc_stream); } } (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); for (i=0; i < (ssize_t) number_components; i++) jas_matrix_destroy(pixels[i]); return(GetFirstImageInList(image)); }
int jp2_write_header(jas_image_t *image, jas_stream_t *out) { jp2_box_t *box; jp2_ftyp_t *ftyp; jp2_ihdr_t *ihdr; jas_stream_t *tmpstream; int allcmptssame; jp2_bpcc_t *bpcc; long len; uint_fast16_t cmptno; jp2_colr_t *colr; jp2_cdefchan_t *cdefchanent; jp2_cdef_t *cdef; int i; uint_fast32_t typeasoc; jas_iccprof_t *iccprof; jas_stream_t *iccstream; int pos; int needcdef; int prec; int sgnd; box = 0; tmpstream = 0; allcmptssame = 1; sgnd = jas_image_cmptsgnd(image, 0); prec = jas_image_cmptprec(image, 0); for (i = 1; i < jas_image_numcmpts(image); ++i) { if (jas_image_cmptsgnd(image, i) != sgnd || jas_image_cmptprec(image, i) != prec) { allcmptssame = 0; break; } } /* Output the signature box. */ if (!(box = jp2_box_create(JP2_BOX_JP))) { goto error; } box->data.jp.magic = JP2_JP_MAGIC; if (jp2_box_put(box, out)) { goto error; } jp2_box_destroy(box); box = 0; /* Output the file type box. */ if (!(box = jp2_box_create(JP2_BOX_FTYP))) { goto error; } ftyp = &box->data.ftyp; ftyp->majver = JP2_FTYP_MAJVER; ftyp->minver = JP2_FTYP_MINVER; ftyp->numcompatcodes = 1; ftyp->compatcodes[0] = JP2_FTYP_COMPATCODE; if (jp2_box_put(box, out)) { goto error; } jp2_box_destroy(box); box = 0; /* * Generate the data portion of the JP2 header box. * We cannot simply output the header for this box * since we do not yet know the correct value for the length * field. */ if (!(tmpstream = jas_stream_memopen(0, 0))) { goto error; } /* Generate image header box. */ if (!(box = jp2_box_create(JP2_BOX_IHDR))) { goto error; } ihdr = &box->data.ihdr; ihdr->width = jas_image_width(image); ihdr->height = jas_image_height(image); ihdr->numcmpts = jas_image_numcmpts(image); ihdr->bpc = allcmptssame ? JP2_SPTOBPC(jas_image_cmptsgnd(image, 0), jas_image_cmptprec(image, 0)) : JP2_IHDR_BPCNULL; ihdr->comptype = JP2_IHDR_COMPTYPE; ihdr->csunk = 0; ihdr->ipr = 0; if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; /* Generate bits per component box. */ if (!allcmptssame) { if (!(box = jp2_box_create(JP2_BOX_BPCC))) { goto error; } bpcc = &box->data.bpcc; bpcc->numcmpts = jas_image_numcmpts(image); if (!(bpcc->bpcs = jas_malloc(bpcc->numcmpts * sizeof(uint_fast8_t)))) { goto error; } for (cmptno = 0; cmptno < bpcc->numcmpts; ++cmptno) { bpcc->bpcs[cmptno] = JP2_SPTOBPC(jas_image_cmptsgnd(image, cmptno), jas_image_cmptprec(image, cmptno)); } if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; } /* Generate color specification box. */ if (!(box = jp2_box_create(JP2_BOX_COLR))) { goto error; } colr = &box->data.colr; switch (jas_image_clrspc(image)) { case JAS_CLRSPC_SRGB: case JAS_CLRSPC_SYCBCR: case JAS_CLRSPC_SGRAY: colr->method = JP2_COLR_ENUM; colr->csid = clrspctojp2(jas_image_clrspc(image)); colr->pri = JP2_COLR_PRI; colr->approx = 0; break; default: colr->method = JP2_COLR_ICC; colr->pri = JP2_COLR_PRI; colr->approx = 0; iccprof = jas_iccprof_createfromcmprof(jas_image_cmprof(image)); assert(iccprof); iccstream = jas_stream_memopen(0, 0); assert(iccstream); if (jas_iccprof_save(iccprof, iccstream)) abort(); if ((pos = jas_stream_tell(iccstream)) < 0) abort(); colr->iccplen = pos; colr->iccp = jas_malloc(pos); assert(colr->iccp); jas_stream_rewind(iccstream); if (jas_stream_read(iccstream, colr->iccp, colr->iccplen) != colr->iccplen) abort(); jas_stream_close(iccstream); jas_iccprof_destroy(iccprof); break; } if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; needcdef = 1; switch (jas_clrspc_fam(jas_image_clrspc(image))) { case JAS_CLRSPC_FAM_RGB: if (jas_image_cmpttype(image, 0) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R) && jas_image_cmpttype(image, 1) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G) && jas_image_cmpttype(image, 2) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B)) needcdef = 0; break; case JAS_CLRSPC_FAM_YCBCR: if (jas_image_cmpttype(image, 0) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_Y) && jas_image_cmpttype(image, 1) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CB) && jas_image_cmpttype(image, 2) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CR)) needcdef = 0; break; case JAS_CLRSPC_FAM_GRAY: if (jas_image_cmpttype(image, 0) == JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y)) needcdef = 0; break; default: abort(); break; } if (needcdef) { if (!(box = jp2_box_create(JP2_BOX_CDEF))) { goto error; } cdef = &box->data.cdef; cdef->numchans = jas_image_numcmpts(image); cdef->ents = jas_malloc(cdef->numchans * sizeof(jp2_cdefchan_t)); for (i = 0; i < jas_image_numcmpts(image); ++i) { cdefchanent = &cdef->ents[i]; cdefchanent->channo = i; typeasoc = jp2_gettypeasoc(jas_image_clrspc(image), jas_image_cmpttype(image, i)); cdefchanent->type = typeasoc >> 16; cdefchanent->assoc = typeasoc & 0x7fff; } if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; } /* Determine the total length of the JP2 header box. */ len = jas_stream_tell(tmpstream); jas_stream_rewind(tmpstream); /* * Output the JP2 header box and all of the boxes which it contains. */ if (!(box = jp2_box_create(JP2_BOX_JP2H))) { goto error; } box->len = len + JP2_BOX_HDRLEN; if (jp2_box_put(box, out)) { goto error; } jp2_box_destroy(box); box = 0; if (jas_stream_copy(out, tmpstream, len)) { goto error; } jas_stream_close(tmpstream); tmpstream = 0; return 0; abort(); error: if (box) { jp2_box_destroy(box); } if (tmpstream) { jas_stream_close(tmpstream); } return -1; }
int pgx_encode(jas_image_t *image, jas_stream_t *out, char *optstr) { pgx_hdr_t hdr; uint_fast32_t width; uint_fast32_t height; jas_bool sgnd; int prec; pgx_enc_t encbuf; pgx_enc_t *enc = &encbuf; /* Avoid compiler warnings about unused parameters. */ optstr = 0; switch (jas_clrspc_fam(jas_image_clrspc(image))) { case JAS_CLRSPC_FAM_GRAY: if ((enc->cmpt = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y))) < 0) { jas_eprintf("error: missing color component\n"); return -1; } break; default: jas_eprintf("error: BMP format does not support color space\n"); return -1; break; } width = jas_image_cmptwidth(image, enc->cmpt); height = jas_image_cmptheight(image, enc->cmpt); prec = jas_image_cmptprec(image, enc->cmpt); sgnd = jas_image_cmptsgnd(image, enc->cmpt); /* The PGX format is quite limited in the set of image geometries that it can handle. Here, we check to ensure that the image to be saved can actually be represented reasonably accurately using the PGX format. */ /* There must be exactly one component. */ if (jas_image_numcmpts(image) > 1 || prec > 16) { jas_eprintf("The PNM format cannot be used to represent an image with this geometry.\n"); return -1; } hdr.magic = PGX_MAGIC; hdr.bigendian = jas_true; hdr.sgnd = sgnd; hdr.prec = prec; hdr.width = width; hdr.height = height; #ifdef PGX_DEBUG pgx_dumphdr(&hdr); #endif if (pgx_puthdr(out, &hdr)) { return -1; } if (pgx_putdata(out, &hdr, image, enc->cmpt)) { return -1; } return 0; }