long jas_stream_seek(jas_stream_t *stream, long offset, int origin) { long newpos; /* The buffer cannot be in use for both reading and writing. */ assert(!((stream->bufmode_ & JAS_STREAM_RDBUF) && (stream->bufmode_ & JAS_STREAM_WRBUF))); /* Reset the EOF indicator (since we may not be at the EOF anymore). */ stream->flags_ &= ~JAS_STREAM_EOF; if (stream->bufmode_ & JAS_STREAM_RDBUF) { if (origin == SEEK_CUR) { offset -= stream->cnt_; } } else if (stream->bufmode_ & JAS_STREAM_WRBUF) { if (jas_stream_flush(stream)) { return -1; } } stream->cnt_ = 0; stream->ptr_ = stream->bufstart_; stream->bufmode_ &= ~(JAS_STREAM_RDBUF | JAS_STREAM_WRBUF); if ((newpos = (*stream->ops_->seek_)(stream->obj_, offset, origin)) < 0) { return -1; } return newpos; }
int imFileFormatJP2::WriteImageData(void* data) { int count = imFileLineBufferCount(this); imCounterTotal(this->counter, count, "Writing JP2..."); /* first time count */ int depth = imColorModeDepth(this->file_color_mode); if (imColorModeHasAlpha(this->user_color_mode) && imColorModeHasAlpha(this->file_color_mode)) { jas_image_setcmpttype(image, depth-1, JAS_IMAGE_CT_OPACITY); depth--; } for (int d = 0; d < depth; d++) jas_image_setcmpttype(image, d, JAS_IMAGE_CT_COLOR(d)); int row = 0, plane = 0; for (int i = 0; i < count; i++) { imFileLineBufferWrite(this, data, row, plane); int ret = 1; if (this->file_data_type == IM_BYTE) ret = iJP2WriteLine(image, row, plane, (imbyte*)this->line_buffer); else ret = iJP2WriteLine(image, row, plane, (imushort*)this->line_buffer); if (!ret) return IM_ERR_ACCESS; if (!imCounterInc(this->counter)) return IM_ERR_COUNTER; imFileLineBufferInc(this, &row, &plane); } char outopts[512] = ""; imAttribTable* attrib_table = AttribTable(); float* ratio = (float*)attrib_table->Get("CompressionRatio"); if (ratio) sprintf(outopts, "rate=%g", (double)(1.0 / *ratio)); // The counter continuous because in Jasper all image writing is done here. BAD! ijp2_counter = this->counter; ijp2_abort = 0; ijp2_message = NULL; /* other counts */ int err = jas_image_encode(image, stream, 0 /*JP2 format always */, outopts); ijp2_counter = -1; if (err) return IM_ERR_ACCESS; jas_stream_flush(stream); return IM_ERR_NONE; }
int jas_stream_close(jas_stream_t *stream) { /* Flush buffer if necessary. */ jas_stream_flush(stream); /* Close the underlying stream object. */ (*stream->ops_->close_)(stream->obj_); jas_stream_destroy(stream); return 0; }
bool jasperConvert(jas_image_t* &image, jas_stream_t* &out, const char* data, unsigned size, int outfmt, const char* outopts) { jas_stream_t *in; // kDebug(YAHOO_RAW_DEBUG) << "Got data - size=" << size; if(!(in = jas_stream_memopen(const_cast<char*>(data), size))) { kDebug(YAHOO_RAW_DEBUG) << "Could not open jasper input stream"; return false; } int infmt; infmt = jas_image_getfmt(in); if (infmt < 0) { jas_stream_close(in); kDebug(YAHOO_RAW_DEBUG) << "Failed to recognize input webcam image format"; return false; } if (!(image = jas_image_decode(in, infmt, 0))) { kDebug(YAHOO_RAW_DEBUG) << "Unable to decode image"; jas_stream_close(in); return false; } /* kDebug(YAHOO_RAW_DEBUG) << "jasper: decoded image: " << jas_image_width(image) << "x" << jas_image_height(image) << " bytes: " << jas_image_rawsize(image) << " components:" << jas_image_numcmpts(image); */ char* out_img = NULL; if(!(out = jas_stream_memopen(out_img, 0))) { kDebug(YAHOO_RAW_DEBUG) << "Could not open output stream"; jas_stream_close(in); return false; } if (jas_image_encode(image, out, outfmt, const_cast<char*>(outopts))) { kDebug(YAHOO_RAW_DEBUG) << "Unable to convert image"; jas_stream_close(in); jas_stream_close(out); jas_image_destroy(image); return false; } jas_stream_flush(out); jas_stream_close(in); return true; }
int jas_stream_close(jas_stream_t *stream) { /* Flush buffer if necessary. */ jas_stream_flush(stream); /* Close the underlying stream object. */ if (!(stream->openmode_ & JAS_STREAM_NOCLOSE)) { (*stream->ops_->close_)(stream->obj_); } jas_stream_destroy(stream); return 0; }
int main(int argc, char **argv) { int fmtid = 0; jas_image_fmtops_t fmtops; fmtops.decode = jp2_decode; fmtops.encode = NULL; fmtops.validate = jp2_validate; jas_image_addfmt(fmtid, "jp2", "jp2", "JPEG-2000 JP2 File Format Syntax (ISO/IEC 15444-1)", &fmtops); ++fmtid; fmtops.decode = NULL; fmtops.encode = bmp_encode; fmtops.validate = NULL; jas_image_addfmt(fmtid, "bmp", "bmp", "Microsoft Bitmap (BMP)", &fmtops); ++fmtid; jas_stream_t *in = jas_stream_fdopen(STDIN_FILENO, "rb"); assert(in != NULL); jas_stream_t *out = jas_stream_fdopen(STDOUT_FILENO, "w+b"); assert(out != NULL); jas_image_t *image = jas_image_decode(in, 0, NULL); assert(image != NULL); int rc = jas_image_encode(image, out, 1, NULL); assert(rc == 0); jas_stream_flush(out); jas_stream_close(in); jas_stream_close(out); jas_image_destroy(image); return 0; }
int main(int argc, char **argv) { jas_image_t *image; cmdopts_t *cmdopts; jas_stream_t *in; jas_stream_t *out; clock_t startclk; clock_t endclk; long dectime; long enctime; int_fast16_t numcmpts; int i; /* Determine the base name of this command. */ if ((cmdname = strrchr(argv[0], '/'))) { ++cmdname; } else { cmdname = argv[0]; } if (jas_init()) { errprint(0, "error: cannot initialize jasper library\n"); abort(); } /* set our error callback */ jas_set_error_cb(errprint); /* Parse the command line options. */ if (!(cmdopts = cmdopts_parse(argc, argv))) { jas_eprintf("error: cannot parse command line\n"); exit(EXIT_FAILURE); } if (cmdopts->version) { jas_eprintf("%s\n", JAS_VERSION); jas_eprintf("libjasper %s\n", jas_getversion()); exit(EXIT_SUCCESS); } jas_setdbglevel(cmdopts->debug); if (cmdopts->verbose) { cmdinfo(); } /* Open the input image file. */ if (cmdopts->infile) { /* The input image is to be read from a file. */ if (!(in = jas_stream_fopen(cmdopts->infile, "rb"))) { jas_eprintf("error: cannot open input image file %s\n", cmdopts->infile); exit(EXIT_FAILURE); } } else { /* The input image is to be read from standard input. */ if (!(in = jas_stream_fdopen(0, "rb"))) { jas_eprintf("error: cannot open standard input\n"); exit(EXIT_FAILURE); } } /* Open the output image file. */ if (cmdopts->outfile) { /* The output image is to be written to a file. */ if (!(out = jas_stream_fopen(cmdopts->outfile, "w+b"))) { jas_eprintf("error: cannot open output image file %s\n", cmdopts->outfile); exit(EXIT_FAILURE); } } else { /* The output image is to be written to standard output. */ if (!(out = jas_stream_fdopen(1, "w+b"))) { jas_eprintf("error: cannot open standard output\n"); exit(EXIT_FAILURE); } } if (cmdopts->infmt < 0) { if ((cmdopts->infmt = jas_image_getfmt(in)) < 0) { jas_eprintf("error: input image has unknown format\n"); exit(EXIT_FAILURE); } } /* Get the input image data. */ startclk = clock(); if (!(image = jas_image_decode(in, cmdopts->infmt, cmdopts->inopts))) { jas_eprintf("error: cannot load image data\n"); exit(EXIT_FAILURE); } endclk = clock(); dectime = endclk - startclk; /* If requested, throw away all of the components except one. Why might this be desirable? It is a hack, really. None of the image formats other than the JPEG-2000 ones support images with two, four, five, or more components. This hack allows such images to be decoded with the non-JPEG-2000 decoders, one component at a time. */ numcmpts = jas_image_numcmpts(image); if (cmdopts->cmptno >= 0 && cmdopts->cmptno < numcmpts) { for (i = numcmpts - 1; i >= 0; --i) { if (i != cmdopts->cmptno) { jas_image_delcmpt(image, i); } } } if (cmdopts->srgb) { jas_image_t *newimage; jas_cmprof_t *outprof; jas_eprintf("forcing conversion to sRGB\n"); if (!(outprof = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB))) { jas_eprintf("cannot create sRGB profile\n"); exit(EXIT_FAILURE); } if (!(newimage = jas_image_chclrspc(image, outprof, JAS_CMXFORM_INTENT_PER))) { jas_eprintf("cannot convert to sRGB\n"); exit(EXIT_FAILURE); } jas_image_destroy(image); jas_cmprof_destroy(outprof); image = newimage; } /* Generate the output image data. */ startclk = clock(); if (jas_image_encode(image, out, cmdopts->outfmt, cmdopts->outopts)) { jas_eprintf("error: cannot encode image\n"); exit(EXIT_FAILURE); } jas_stream_flush(out); endclk = clock(); enctime = endclk - startclk; if (cmdopts->verbose) { jas_eprintf("decoding time = %f\n", dectime / (double) CLOCKS_PER_SEC); jas_eprintf("encoding time = %f\n", enctime / (double) CLOCKS_PER_SEC); } /* If this fails, we don't care. */ (void) jas_stream_close(in); /* Close the output image stream. */ if (jas_stream_close(out)) { jas_eprintf("error: cannot close output image file\n"); exit(EXIT_FAILURE); } cmdopts_destroy(cmdopts); jas_image_destroy(image); jas_image_clearfmts(); /* Success at last! :-) */ return EXIT_SUCCESS; }
static GstFlowReturn gst_jasper_enc_get_data (GstJasperEnc * enc, guint8 * data, GstBuffer ** outbuf) { GstFlowReturn ret = GST_FLOW_OK; jas_stream_t *stream = NULL; gint i; guint size, boxsize; g_return_val_if_fail (outbuf != NULL, GST_FLOW_ERROR); *outbuf = NULL; boxsize = (enc->mode == GST_JP2ENC_MODE_J2C) ? 8 : 0; if (!(stream = jas_stream_memopen (NULL, 0))) goto fail_stream; for (i = 0; i < enc->channels; ++i) { gint x, y, cwidth, cheight, inc, stride, cmpt; guint8 *row_pix, *in_pix; glong *tb; cmpt = i; inc = enc->inc[i]; stride = enc->stride[i]; cheight = enc->cheight[cmpt]; cwidth = enc->cwidth[cmpt]; GST_LOG_OBJECT (enc, "write component %d<=%d, size %dx%d, offset %d, inc %d, stride %d", i, cmpt, cwidth, cheight, enc->offset[i], inc, stride); row_pix = data + enc->offset[i]; for (y = 0; y < cheight; y++) { in_pix = row_pix; tb = enc->buf; for (x = 0; x < cwidth; x++) { *tb = *in_pix; in_pix += inc; tb++; } if (jas_image_writecmpt2 (enc->image, cmpt, 0, y, cwidth, 1, enc->buf)) goto fail_image; row_pix += stride; } } GST_LOG_OBJECT (enc, "all components written"); if (jas_image_encode (enc->image, stream, enc->fmt, (char *) "sop")) goto fail_encode; GST_LOG_OBJECT (enc, "image encoded"); size = jas_stream_length (stream); ret = gst_pad_alloc_buffer_and_set_caps (enc->srcpad, GST_BUFFER_OFFSET_NONE, size + boxsize, GST_PAD_CAPS (enc->srcpad), outbuf); if (ret != GST_FLOW_OK) goto no_buffer; data = GST_BUFFER_DATA (*outbuf); if (jas_stream_flush (stream) || jas_stream_rewind (stream) < 0 || jas_stream_read (stream, data + boxsize, size) < size) goto fail_image_out; if (boxsize) { /* write atom prefix */ GST_WRITE_UINT32_BE (data, size + 8); GST_WRITE_UINT32_LE (data + 4, GST_MAKE_FOURCC ('j', 'p', '2', 'c')); } done: if (stream) jas_stream_close (stream); return ret; /* ERRORS */ fail_stream: { GST_DEBUG_OBJECT (enc, "Failed to create inputstream."); goto fail; } fail_encode: { GST_DEBUG_OBJECT (enc, "Failed to encode image."); goto fail; } fail_image: { GST_DEBUG_OBJECT (enc, "Failed to process input image."); goto fail; } fail_image_out: { GST_DEBUG_OBJECT (enc, "Failed to process encoded image."); goto fail; } fail: { if (*outbuf) gst_buffer_unref (*outbuf); *outbuf = NULL; GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL), (NULL)); ret = GST_FLOW_ERROR; goto done; } no_buffer: { GST_DEBUG_OBJECT (enc, "Failed to create outbuffer - %s", gst_flow_get_name (ret)); goto done; } }
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); }
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)); }
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 void writeJpc(jas_image_t * const jasperP, struct cmdlineInfo const cmdline, FILE * const ofP) { jas_stream_t * outStreamP; const char * options; const char * ilyrratesOpt; const char * prgValue; char rateOpt[20+1]; /* Note: ilyrrates is a hack because we're too lazy to properly parse command line options to get the information and then compose a proper input to Jasper. So the user can screw things up by specifying garbage for the -ilyrrates option */ if (strlen(cmdline.ilyrrates) > 0) asprintfN(&ilyrratesOpt, "ilyrrates=%s", cmdline.ilyrrates); else ilyrratesOpt = strdup(""); switch(cmdline.progression) { case PROG_LRCP: prgValue = "lrcp"; break; case PROG_RLCP: prgValue = "rlcp"; break; case PROG_RPCL: prgValue = "rcpc"; break; case PROG_PCRL: prgValue = "pcrl"; break; case PROG_CPRL: prgValue = "cprl"; break; } /* Note that asprintfN() doesn't understand %f, but sprintf() does */ sprintf(rateOpt, "%1.9f", 1.0/cmdline.compressionRatio); asprintfN(&options, "imgareatlx=%u " "imgareatly=%u " "tilegrdtlx=%u " "tilegrdtly=%u " "tilewidth=%u " "tileheight=%u " "prcwidth=%u " "prcheight=%u " "cblkwidth=%u " "cblkheight=%u " "mode=%s " "rate=%s " "%s " "prg=%s " "numrlvls=%u " "numgbits=%u " "%s %s %s %s %s %s %s %s %s", cmdline.imgareatlx, cmdline.imgareatly, cmdline.tilegrdtlx, cmdline.tilegrdtlx, cmdline.tilewidth, cmdline.tileheight, cmdline.prcwidth, cmdline.prcheight, cmdline.cblkwidth, cmdline.cblkheight, cmdline.compmode == COMPMODE_INTEGER ? "int" : "real", rateOpt, ilyrratesOpt, prgValue, cmdline.numrlvls, cmdline.numgbits, cmdline.nomct ? "nomct" : "", cmdline.sop ? "sop" : "", cmdline.eph ? "eph" : "", cmdline.lazy ? "lazy" : "", cmdline.termall ? "termall" : "", cmdline.segsym ? "segsym" : "", cmdline.vcausal ? "vcausal" : "", cmdline.pterm ? "pterm" : "", cmdline.resetprob ? "resetprob" : "" ); strfree(ilyrratesOpt); /* Open the output image file (Standard Output) */ outStreamP = jas_stream_fdopen(fileno(ofP), "w+b"); if (outStreamP == NULL) pm_error("Unable to open output stream. jas_stream_fdopen() " "failed"); { int rc; if (cmdline.verbose) pm_message("Using Jasper to encode to 'jpc' format with options " "'%s'", options); rc = jas_image_encode(jasperP, outStreamP, jas_image_strtofmt((char*)"jpc"), (char*)options); if (rc != 0) pm_error("jas_image_encode() failed to encode the JPEG 2000 " "image. Rc=%d", rc); } jas_stream_flush(outStreamP); { int rc; rc = jas_stream_close(outStreamP); if (rc != 0) pm_error("Failed to close output stream, " "jas_stream_close() rc = %d", rc); } jas_image_clearfmts(); strfree(options); }