static void adjust() { if (gs.vp.width < jas_image_width(gs.image) / gs.sx) { float mnx; float mxx; mnx = jas_image_tlx(gs.image) + 0.5 * gs.vp.width * gs.sx; mxx = jas_image_brx(gs.image) - 0.5 * gs.vp.width * gs.sx; if (gs.vcx < mnx) { gs.vcx = mnx; } else if (gs.vcx > mxx) { gs.vcx = mxx; } } else { gs.vcx = (jas_image_tlx(gs.image) + jas_image_brx(gs.image)) / 2.0; } if (gs.vp.height < jas_image_height(gs.image) / gs.sy) { float mny; float mxy; mny = jas_image_tly(gs.image) + 0.5 * gs.vp.height * gs.sy; mxy = jas_image_bry(gs.image) - 0.5 * gs.vp.height * gs.sy; if (gs.vcy < mny) { gs.vcy = mny; } else if (gs.vcy > mxy) { gs.vcy = mxy; } } else { gs.vcy = (jas_image_tly(gs.image) + jas_image_bry(gs.image)) / 2.0; } }
static void reshape(int w, int h) { if (cmdopts.verbose) { jas_eprintf("reshape(%d, %d)\n", w, h); dumpstate(); } if (pixmap_resize(&gs.vp, w, h)) { cleanupandexit(EXIT_FAILURE); } pixmap_clear(&gs.vp); glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho( 0, w, 0, h, 0.f, 1.f ); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0, 0, 0); glRasterPos2i(0, 0); if (gs.vp.width > jas_image_width(gs.image) / gs.sx) { gs.vcx = (jas_image_tlx(gs.image) + jas_image_brx(gs.image)) / 2.0; } if (gs.vp.height > jas_image_height(gs.image) / gs.sy) { gs.vcy = (jas_image_tly(gs.image) + jas_image_bry(gs.image)) / 2.0; } gs.dirty = 1; }
fz_error fz_processjpxd(fz_filter *filter, fz_buffer *in, fz_buffer *out) { fz_jpxd *d = (fz_jpxd*)filter; int n, bpc, w, h; int i, x, y; switch (d->stage) { case 0: goto input; case 1: goto decode; case 2: goto output; } input: while (in->rp < in->wp) { n = jas_stream_write(d->stream, in->rp, in->wp - in->rp); in->rp += n; } if (!in->eof) return fz_ioneedin; d->stage = 1; decode: jas_stream_seek(d->stream, 0, SEEK_SET); d->image = jas_image_decode(d->stream, -1, nil); if (!d->image) return fz_throw("jasper error: jas_image_decode()"); d->stage = 2; output: w = jas_image_width(d->image); h = jas_image_height(d->image); n = jas_image_numcmpts(d->image); bpc = jas_image_cmptprec(d->image, 0); /* use precision of first component for all... */ while (d->offset < w * h) { y = d->offset / w; x = d->offset - y * w; /* FIXME bpc != 8 */ if (out->wp + n >= out->ep) return fz_ioneedout; for (i = 0; i < n; i++) *out->wp++ = jas_image_readcmptsample(d->image, i, x, y); d->offset ++; } return fz_iodone; }
/* dump information from a jasper image struct for debugging */ static int dump_jas_image(jas_image_t *image) { int i, numcmpts = jas_image_numcmpts(image); int clrspc = jas_image_clrspc(image); const char *csname = "unrecognized vendor space"; if (image == NULL) return 1; if_debug2('w', "[w]JPX image is %d x %d\n", (int)jas_image_width(image), (int)jas_image_height(image)); /* sort the colorspace */ if jas_clrspc_isunknown(clrspc) csname = "unknown"; else switch (clrspc) {
bool GrFmtJpeg2000Reader::ReadHeader() { bool result = false; Close(); m_stream = jas_stream_fopen( m_filename, "rb" ); if( m_stream ) { m_image = jas_image_decode( m_stream, -1, 0 ); if( m_image ) { m_width = jas_image_width( m_image ); m_height = jas_image_height( m_image ); int cntcmpts = 0; // count the known components int numcmpts = jas_image_numcmpts( m_image ); for( int i = 0; i < numcmpts; i++ ) { int depth = jas_image_cmptprec( m_image, i ); if( depth > m_bit_depth ) m_bit_depth = depth; if( m_bit_depth > 8 ) m_bit_depth = 16; if( jas_image_cmpttype( m_image, i ) > 2 ) continue; cntcmpts++; } if( cntcmpts ) { m_iscolor = (cntcmpts > 1); result = true; } } } if( !result ) Close(); return result; }
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); }
CPL_C_END int dec_jpeg2000(char *injpc,g2int bufsize,g2int *outfld) /*$$$ SUBPROGRAM DOCUMENTATION BLOCK * . . . . * SUBPROGRAM: dec_jpeg2000 Decodes JPEG2000 code stream * PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-12-02 * * ABSTRACT: This Function decodes a JPEG2000 code stream specified in the * JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) using JasPer * Software version 1.500.4 (or 1.700.2) written by the University of British * Columbia and Image Power Inc, and others. * JasPer is available at http://www.ece.uvic.ca/~mdadams/jasper/. * * PROGRAM HISTORY LOG: * 2002-12-02 Gilbert * * USAGE: int dec_jpeg2000(char *injpc,g2int bufsize,g2int *outfld) * * INPUT ARGUMENTS: * injpc - Input JPEG2000 code stream. * bufsize - Length (in bytes) of the input JPEG2000 code stream. * * OUTPUT ARGUMENTS: * outfld - Output matrix of grayscale image values. * * RETURN VALUES : * 0 = Successful decode * -3 = Error decode jpeg2000 code stream. * -5 = decoded image had multiple color components. * Only grayscale is expected. * * REMARKS: * * Requires JasPer Software version 1.500.4 or 1.700.2 * * ATTRIBUTES: * LANGUAGE: C * MACHINE: IBM SP * *$$$*/ { #ifndef HAVE_JASPER // J2K_SUBFILE method // create "memory file" from buffer int fileNumber = 0; VSIStatBufL sStatBuf; CPLString osFileName = "/vsimem/work.jpc"; // ensure we don't overwrite an existing file accidentally while ( VSIStatL( osFileName, &sStatBuf ) == 0 ) { osFileName.Printf( "/vsimem/work%d.jpc", ++fileNumber ); } VSIFCloseL( VSIFileFromMemBuffer( osFileName, (unsigned char*)injpc, bufsize, FALSE ) ); // TRUE to let vsi delete the buffer when done // Open memory buffer for reading GDALDataset* poJ2KDataset = (GDALDataset *) GDALOpen( osFileName, GA_ReadOnly ); if( poJ2KDataset == NULL ) { printf("dec_jpeg2000: Unable to open JPEG2000 image within GRIB file.\n" "Is the JPEG2000 driver available?" ); return -3; } if( poJ2KDataset->GetRasterCount() != 1 ) { printf("dec_jpeg2000: Found color image. Grayscale expected.\n"); return (-5); } // Fulfill administration: initialize parameters required for RasterIO int nXSize = poJ2KDataset->GetRasterXSize(); int nYSize = poJ2KDataset->GetRasterYSize(); int nXOff = 0; int nYOff = 0; int nBufXSize = nXSize; int nBufYSize = nYSize; GDALDataType eBufType = GDT_Int32; // map to type of "outfld" buffer: g2int* int nBandCount = 1; int* panBandMap = NULL; int nPixelSpace = 0; int nLineSpace = 0; int nBandSpace = 0; // Decompress the JPEG2000 into the output integer array. poJ2KDataset->RasterIO( GF_Read, nXOff, nYOff, nXSize, nYSize, outfld, nBufXSize, nBufYSize, eBufType, nBandCount, panBandMap, nPixelSpace, nLineSpace, nBandSpace, NULL ); // close source file, and "unlink" it. GDALClose( poJ2KDataset ); VSIUnlink( osFileName ); return 0; #else // JasPer method int ier; g2int i,j,k; jas_image_t *image=0; jas_stream_t *jpcstream; jas_image_cmpt_t *pcmpt; char *opts=0; jas_matrix_t *data; // jas_init(); ier=0; // // Create jas_stream_t containing input JPEG200 codestream in memory. // jpcstream=jas_stream_memopen(injpc,bufsize); // // Decode JPEG200 codestream into jas_image_t structure. // image=jpc_decode(jpcstream,opts); if ( image == 0 ) { printf(" jpc_decode return = %d \n",ier); return -3; } pcmpt=image->cmpts_[0]; // Expecting jpeg2000 image to be grayscale only. // No color components. // if (image->numcmpts_ != 1 ) { printf("dec_jpeg2000: Found color image. Grayscale expected.\n"); return (-5); } // // Create a data matrix of grayscale image values decoded from // the jpeg2000 codestream. // data=jas_matrix_create(jas_image_height(image), jas_image_width(image)); jas_image_readcmpt(image,0,0,0,jas_image_width(image), jas_image_height(image),data); // // Copy data matrix to output integer array. // k=0; for (i=0; i<pcmpt->height_; i++) for (j=0; j<pcmpt->width_; j++) outfld[k++]=data->rows_[i][j]; // // Clean up JasPer work structures. // jas_matrix_destroy(data); ier=jas_stream_close(jpcstream); jas_image_destroy(image); return 0; #endif }
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; }
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; } }
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; }
int jp2_encode(jas_image_t *image, jas_stream_t *out, char *optstr) { 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; char buf[4096]; uint_fast32_t overhead; jp2_cdefchan_t *cdefchanent; jp2_cdef_t *cdef; int i; uint_fast32_t typeasoc; box = 0; tmpstream = 0; /* 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); allcmptssame = 0; 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; colr->method = JP2_COLR_ENUM; colr->pri = JP2_COLR_PRI; colr->approx = 0; colr->csid = (jas_image_colorspace(image) == JAS_IMAGE_CS_RGB) ? JP2_COLR_SRGB : JP2_COLR_SGRAY; if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; if (!(jas_image_colorspace(image) == JAS_IMAGE_CS_RGB && jas_image_numcmpts(image) == 3 && jas_image_getcmptbytype(image, 0) == JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_R) && jas_image_getcmptbytype(image, 1) == JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_G) && jas_image_getcmptbytype(image, 2) == JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_B)) && !(jas_image_colorspace(image) == JAS_IMAGE_CS_YCBCR && jas_image_numcmpts(image) != 3 && jas_image_getcmptbytype(image, 0) == JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_YCBCR_Y) && jas_image_getcmptbytype(image, 1) == JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_YCBCR_CB) && jas_image_getcmptbytype(image, 2) == JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_YCBCR_CR)) && !(jas_image_colorspace(image) == JAS_IMAGE_CS_GRAY && jas_image_numcmpts(image) == 1 && jas_image_getcmptbytype(image, 0) == JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y))) { 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_colorspace(image), jas_image_cmpttype(image, i)); cdefchanent->type = typeasoc >> 16; cdefchanent->assoc = typeasoc & 0x7fff; } 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; /* * Output the contiguous code stream box. */ if (!(box = jp2_box_create(JP2_BOX_JP2C))) { goto error; } box->len = 0; if (jp2_box_put(box, out)) { goto error; } jp2_box_destroy(box); box = 0; /* Output the JPEG-2000 code stream. */ overhead = jas_stream_getrwcount(out); sprintf(buf, "%s\n_jp2overhead=%lu\n", (optstr ? optstr : ""), (unsigned long) overhead); if (jpc_encode(image, out, buf)) { goto error; } return 0; abort(); error: if (box) { jp2_box_destroy(box); } if (tmpstream) { jas_stream_close(tmpstream); } return -1; }
// Internal function used to load the Jpeg2000 stream. ILboolean iLoadJp2Internal(jas_stream_t *Stream, ILimage *Image) { jas_image_t *Jp2Image = NULL; jas_matrix_t *origdata; ILuint x, y, c; ILimage *TempImage; // Decode image Jp2Image = jas_image_decode(Stream, -1, 0); if (!Jp2Image) { ilSetError(IL_ILLEGAL_FILE_VALUE); jas_stream_close(Stream); return IL_FALSE; } // We're not supporting anything other than 8 bits/component yet. if (jas_image_cmptprec(Jp2Image, 0) != 8) { jas_image_destroy(Jp2Image); ilSetError(IL_ILLEGAL_FILE_VALUE); return IL_FALSE; } switch (jas_image_numcmpts(Jp2Image)) { case 3: if (Image == NULL) { ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL); TempImage = iCurImage; } else { ifree(Image->Data); // @TODO: Not really the most efficient way to do this... ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL); TempImage = Image; } break; case 4: if (Image == NULL) { ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL); TempImage = iCurImage; } else { ifree(Image->Data); // @TODO: Not really the most efficient way to do this... ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL); TempImage = Image; } break; default: jas_image_destroy(Jp2Image); ilSetError(IL_ILLEGAL_FILE_VALUE); return IL_FALSE; } TempImage->Origin = IL_ORIGIN_UPPER_LEFT; // JasPer stores the data channels separately. // I am assuming RGBA format. Is it possible for other formats to be included? for (c = 0; c < TempImage->Bpp; c++) { origdata = jas_matrix_create(TempImage->Height, TempImage->Width); if (!origdata) { ilSetError(IL_LIB_JP2_ERROR); return IL_FALSE; // @TODO: Error } // Have to convert data into an intermediate matrix format. if (jas_image_readcmpt(Jp2Image, c, 0, 0, TempImage->Width, TempImage->Height, origdata)) { return IL_FALSE; } for (y = 0; y < TempImage->Height; y++) { for (x = 0; x < TempImage->Width; x++) { TempImage->Data[y * TempImage->Width * TempImage->Bpp + x * TempImage->Bpp + c] = origdata->data_[y * origdata->numcols_ + x]; } } jas_matrix_destroy(origdata); } jas_image_destroy(Jp2Image); ilFixImage(); return IL_TRUE; }
static DFBResult IDirectFBImageProvider_JPEG2000_RenderTo( IDirectFBImageProvider *thiz, IDirectFBSurface *destination, const DFBRectangle *dest_rect ) { IDirectFBSurface_data *dst_data; CoreSurface *dst_surface; CoreSurfaceBufferLock lock; DFBRectangle rect; DFBRegion clip; DIRenderCallbackResult cb_result = DIRCR_OK; DFBResult ret = DFB_OK; DIRECT_INTERFACE_GET_DATA( IDirectFBImageProvider_JPEG2000 ) if (!destination) return DFB_INVARG; dst_data = destination->priv; if (!dst_data || !dst_data->surface) return DFB_DESTROYED; dst_surface = dst_data->surface; if (dest_rect) { if (dest_rect->w < 1 || dest_rect->h < 1) return DFB_INVARG; rect = *dest_rect; rect.x += dst_data->area.wanted.x; rect.y += dst_data->area.wanted.y; } else { rect = dst_data->area.wanted; } dfb_region_from_rectangle( &clip, &dst_data->area.current ); if (!dfb_rectangle_region_intersects( &rect, &clip )) return DFB_OK; ret = dfb_surface_lock_buffer( dst_surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock ); if (ret) return ret; if (!data->buf) { int cmptlut[3]; int width, height; int tlx, tly; int hs, vs; int i, j; bool direct, mono; if (jas_image_numcmpts(data->image) > 1) { cmptlut[0] = jas_image_getcmptbytype(data->image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R)); cmptlut[1] = jas_image_getcmptbytype(data->image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G)); cmptlut[2] = jas_image_getcmptbytype(data->image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B)); if (cmptlut[0] < 0 || cmptlut[1] < 0 || cmptlut[2] < 0) { dfb_surface_unlock_buffer( dst_surface, &lock ); return DFB_UNSUPPORTED; } mono = false; } else { cmptlut[0] = cmptlut[1] = cmptlut[2] = 0; mono = true; } width = jas_image_width(data->image); height = jas_image_height(data->image); tlx = jas_image_cmpttlx(data->image, 0); tly = jas_image_cmpttly(data->image, 0); hs = jas_image_cmpthstep(data->image, 0); vs = jas_image_cmptvstep(data->image, 0); data->buf = D_MALLOC( width*height*4 ); if (!data->buf) { dfb_surface_unlock_buffer( dst_surface, &lock ); return D_OOM(); } direct = (rect.w == width && rect.h == height && data->render_callback); #define GET_SAMPLE( n, x, y ) ({ \ int _s; \ _s = jas_image_readcmptsample(data->image, cmptlut[n], x, y); \ _s >>= jas_image_cmptprec(data->image, cmptlut[n]) - 8; \ if (_s > 255) \ _s = 255; \ else if (_s < 0) \ _s = 0; \ _s; \ }) for (i = 0; i < height; i++) { u32 *dst = data->buf + i * width; int x, y; y = (i - tly) / vs; if (y >= 0 && y < height) { for (j = 0; j < width; j++) { x = (j - tlx) / hs; if (x >= 0 && x < width) { unsigned int r, g, b; if (mono) { r = g = b = GET_SAMPLE(0, x, y); } else { r = GET_SAMPLE(0, x, y); g = GET_SAMPLE(1, x, y); b = GET_SAMPLE(2, x, y); } *dst++ = 0xff000000 | (r << 16) | (g << 8) | b; } else { *dst++ = 0; } } } else { memset( dst, 0, width*4 ); } if (direct) { DFBRectangle r = { rect.x, rect.y+i, width, 1 }; dfb_copy_buffer_32( data->buf + i*width, lock.addr, lock.pitch, &r, dst_surface, &clip ); if (data->render_callback) { r = (DFBRectangle) { 0, i, width, 1 }; cb_result = data->render_callback( &r, data->render_callback_ctx ); if (cb_result != DIRCR_OK) break; } } } if (!direct) { dfb_scale_linear_32( data->buf, width, height, lock.addr, lock.pitch, &rect, dst_surface, &clip ); if (data->render_callback) { DFBRectangle r = { 0, 0, width, height }; data->render_callback( &r, data->render_callback_ctx ); } } if (cb_result != DIRCR_OK) { D_FREE( data->buf ); data->buf = NULL; ret = DFB_INTERRUPTED; } } else { int width = jas_image_width(data->image); int height = jas_image_height(data->image); dfb_scale_linear_32( data->buf, width, height, lock.addr, lock.pitch, &rect, dst_surface, &clip ); if (data->render_callback) { DFBRectangle r = {0, 0, width, height}; data->render_callback( &r, data->render_callback_ctx ); } } dfb_surface_unlock_buffer( dst_surface, &lock ); return ret; }
// Internal function used to load the Jpeg2000 stream. ILboolean iLoadJp2Internal(jas_stream_t *Stream, ILimage *Image) { jas_image_t *Jp2Image = NULL; jas_matrix_t *origdata; ILuint x, y, c, Error; ILimage *TempImage; // Decode image Jp2Image = jas_image_decode(Stream, -1, 0); if (!Jp2Image) { ilSetError(IL_ILLEGAL_FILE_VALUE); jas_stream_close(Stream); return IL_FALSE; } // JasPer likes to buffer a lot, so it may try buffering past the end // of the file. iread naturally sets IL_FILE_READ_ERROR if it tries // reading past the end of the file, but this actually is not an error. Error = ilGetError(); // Put the error back if it is not IL_FILE_READ_ERROR. if (Error != IL_FILE_READ_ERROR) ilSetError(Error); // We're not supporting anything other than 8 bits/component yet. if (jas_image_cmptprec(Jp2Image, 0) != 8) { jas_image_destroy(Jp2Image); ilSetError(IL_ILLEGAL_FILE_VALUE); return IL_FALSE; } switch (jas_image_numcmpts(Jp2Image)) { //@TODO: Can we do alpha data? jas_image_cmpttype always returns 0 for this case. case 1: // Assuming this is luminance data. if (Image == NULL) { ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL); TempImage = iCurImage; } else { ifree(Image->Data); // @TODO: Not really the most efficient way to do this... ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL); TempImage = Image; } break; case 2: // Assuming this is luminance-alpha data. if (Image == NULL) { ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 2, IL_LUMINANCE_ALPHA, IL_UNSIGNED_BYTE, NULL); TempImage = iCurImage; } else { ifree(Image->Data); // @TODO: Not really the most efficient way to do this... ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 2, IL_LUMINANCE_ALPHA, IL_UNSIGNED_BYTE, NULL); TempImage = Image; } break; case 3: if (Image == NULL) { ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL); TempImage = iCurImage; } else { ifree(Image->Data); // @TODO: Not really the most efficient way to do this... ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL); TempImage = Image; } break; case 4: if (Image == NULL) { ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL); TempImage = iCurImage; } else { ifree(Image->Data); // @TODO: Not really the most efficient way to do this... ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL); TempImage = Image; } break; default: jas_image_destroy(Jp2Image); ilSetError(IL_ILLEGAL_FILE_VALUE); return IL_FALSE; } TempImage->Origin = IL_ORIGIN_UPPER_LEFT; // JasPer stores the data channels separately. // I am assuming RGBA format. Is it possible for other formats to be included? for (c = 0; c < TempImage->Bpp; c++) { origdata = jas_matrix_create(TempImage->Height, TempImage->Width); if (!origdata) { ilSetError(IL_LIB_JP2_ERROR); return IL_FALSE; // @TODO: Error } // Have to convert data into an intermediate matrix format. if (jas_image_readcmpt(Jp2Image, c, 0, 0, TempImage->Width, TempImage->Height, origdata)) { return IL_FALSE; } for (y = 0; y < TempImage->Height; y++) { for (x = 0; x < TempImage->Width; x++) { TempImage->Data[y * TempImage->Width * TempImage->Bpp + x * TempImage->Bpp + c] = origdata->data_[y * origdata->numcols_ + x]; } } jas_matrix_destroy(origdata); } jas_image_destroy(Jp2Image); return ilFixImage(); }
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; }
int dec_jpeg2000(char *injpc,g2int bufsize,g2int *outfld) /*$$$ SUBPROGRAM DOCUMENTATION BLOCK * . . . . * SUBPROGRAM: dec_jpeg2000 Decodes JPEG2000 code stream * PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-12-02 * * ABSTRACT: This Function decodes a JPEG2000 code stream specified in the * JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) using JasPer * Software version 1.500.4 (or 1.700.2) written by the University of British * Columbia and Image Power Inc, and others. * JasPer is available at http://www.ece.uvic.ca/~mdadams/jasper/. * * PROGRAM HISTORY LOG: * 2002-12-02 Gilbert * * USAGE: int dec_jpeg2000(char *injpc,g2int bufsize,g2int *outfld) * * INPUT ARGUMENTS: * injpc - Input JPEG2000 code stream. * bufsize - Length (in bytes) of the input JPEG2000 code stream. * * OUTPUT ARGUMENTS: * outfld - Output matrix of grayscale image values. * * RETURN VALUES : * 0 = Successful decode * -3 = Error decode jpeg2000 code stream. * -5 = decoded image had multiple color components. * Only grayscale is expected. * * REMARKS: * * Requires JasPer Software version 1.500.4 or 1.700.2 * * ATTRIBUTES: * LANGUAGE: C * MACHINE: IBM SP * *$$$*/ { int ier; g2int i,j,k; jas_image_t *image=0; jas_stream_t *jpcstream; jas_image_cmpt_t *pcmpt; char *opts=0; jas_matrix_t *data; /* jas_init();*/ ier=0; /* // Create jas_stream_t containing input JPEG200 codestream in memory. */ jpcstream=jas_stream_memopen(injpc,bufsize); /* // Decode JPEG200 codestream into jas_image_t structure. */ image=jpc_decode(jpcstream,opts); if ( image == 0 ) { printf(" jpc_decode return = %d \n",ier); return -3; } pcmpt=image->cmpts_[0]; /* printf(" SAGOUT DECODE:\n"); printf(" tlx %d \n",image->tlx_); printf(" tly %d \n",image->tly_); printf(" brx %d \n",image->brx_); printf(" bry %d \n",image->bry_); printf(" numcmpts %d \n",image->numcmpts_); printf(" maxcmpts %d \n",image->maxcmpts_); #ifdef JAS_1_500_4 printf(" colormodel %d \n",image->colormodel_); #endif #ifdef JAS_1_700_2 printf(" colorspace %d \n",image->clrspc_); #endif printf(" inmem %d \n",image->inmem_); printf(" COMPONENT:\n"); printf(" tlx %d \n",pcmpt->tlx_); printf(" tly %d \n",pcmpt->tly_); printf(" hstep %d \n",pcmpt->hstep_); printf(" vstep %d \n",pcmpt->vstep_); printf(" width %d \n",pcmpt->width_); printf(" height %d \n",pcmpt->height_); printf(" prec %d \n",pcmpt->prec_); printf(" sgnd %d \n",pcmpt->sgnd_); printf(" cps %d \n",pcmpt->cps_); #ifdef JAS_1_700_2 printf(" type %d \n",pcmpt->type_); #endif */ /* Expecting jpeg2000 image to be grayscale only. // No color components. */ if (image->numcmpts_ != 1 ) { printf("dec_jpeg2000: Found color image. Grayscale expected.\n"); return (-5); } /* // Create a data matrix of grayscale image values decoded from // the jpeg2000 codestream. */ data=jas_matrix_create(jas_image_height(image), jas_image_width(image)); jas_image_readcmpt(image,0,0,0,jas_image_width(image), jas_image_height(image),data); /* // Copy data matrix to output integer array. */ k=0; for (i=0;i<pcmpt->height_;i++) for (j=0;j<pcmpt->width_;j++) outfld[k++]=data->rows_[i][j]; /* // Clean up JasPer work structures. */ jas_matrix_destroy(data); ier=jas_stream_close(jpcstream); jas_image_destroy(image); return 0; }
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)); }
static int loadimage() { int reshapeflag; jas_stream_t *in; int scrnwidth; int scrnheight; int vh; int vw; char *pathname; jas_cmprof_t *outprof; assert(!gs.image); assert(!gs.altimage); gs.image = 0; gs.altimage = 0; pathname = cmdopts.filenames[gs.filenum]; if (pathname && pathname[0] != '\0') { #if 1 jas_eprintf("opening %s\n", pathname); #endif /* The input image is to be read from a file. */ if (!(in = jas_stream_fopen(pathname, "rb"))) { jas_eprintf("error: cannot open file %s\n", pathname); goto error; } } else { /* The input image is to be read from standard input. */ in = streamin; } /* Get the input image data. */ if (!(gs.image = jas_image_decode(in, -1, 0))) { jas_eprintf("error: cannot load image data\n"); goto error; } /* Close the input stream. */ if (in != streamin) { jas_stream_close(in); } if (!(outprof = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB))) goto error; if (!(gs.altimage = jas_image_chclrspc(gs.image, outprof, JAS_CMXFORM_INTENT_PER))) goto error; if ((scrnwidth = glutGet(GLUT_SCREEN_WIDTH)) < 0) { scrnwidth = 256; } if ((scrnheight = glutGet(GLUT_SCREEN_HEIGHT)) < 0) { scrnheight = 256; } vw = min(jas_image_width(gs.image), 0.95 * scrnwidth); vh = min(jas_image_height(gs.image), 0.95 * scrnheight); gs.vcx = (jas_image_tlx(gs.image) + jas_image_brx(gs.image)) / 2.0; gs.vcy = (jas_image_tly(gs.image) + jas_image_bry(gs.image)) / 2.0; gs.sx = 1.0; gs.sy = 1.0; if (gs.altimage) { gs.monomode = 0; } else { gs.monomode = 1; gs.cmptno = 0; } #if 1 jas_eprintf("num of components %d\n", jas_image_numcmpts(gs.image)); #endif if (vw < jas_image_width(gs.image)) { gs.sx = jas_image_width(gs.image) / ((float) vw); } if (vh < jas_image_height(gs.image)) { gs.sy = jas_image_height(gs.image) / ((float) vh); } if (gs.sx > gs.sy) { gs.sy = gs.sx; } else if (gs.sx < gs.sy) { gs.sx = gs.sy; } vw = jas_image_width(gs.image) / gs.sx; vh = jas_image_height(gs.image) / gs.sy; gs.dirty = 1; reshapeflag = 0; if (vw != glutGet(GLUT_WINDOW_WIDTH) || vh != glutGet(GLUT_WINDOW_HEIGHT)) { glutReshapeWindow(vw, vh); reshapeflag = 1; } if (cmdopts.title) { glutSetWindowTitle(cmdopts.title); } else { glutSetWindowTitle((pathname && pathname[0] != '\0') ? pathname : "stdin"); } /* If we reshaped the window, GLUT will automatically invoke both the reshape and display callback (in this order). Therefore, we only need to explicitly force the display callback to be invoked if the window was not reshaped. */ if (!reshapeflag) { glutPostRedisplay(); } if (cmdopts.tmout != 0) { glutTimerFunc(cmdopts.tmout, timer, gs.nexttmid); gs.activetmid = gs.nexttmid; ++gs.nexttmid; } return 0; error: unloadimage(); return -1; }
static void special(int key, int x, int y) { if (cmdopts.verbose) { jas_eprintf("special(%d, %d, %d)\n", key, x, y); } switch (key) { case GLUT_KEY_UP: { float oldvcy; float vh; float pan; if (gs.vp.height < jas_image_height(gs.image) / gs.sy) { pan = (glutGetModifiers() & GLUT_ACTIVE_SHIFT) ? BIGPAN : SMALLPAN; oldvcy = gs.vcy; vh = gs.sy * gs.vp.height; gs.vcy = max(gs.vcy - pan * vh, jas_image_tly(gs.image) + 0.5 * vh); if (gs.vcy != oldvcy) { gs.dirty = 1; glutPostRedisplay(); } } } break; case GLUT_KEY_DOWN: { float oldvcy; float vh; float pan; if (gs.vp.height < jas_image_height(gs.image) / gs.sy) { pan = (glutGetModifiers() & GLUT_ACTIVE_SHIFT) ? BIGPAN : SMALLPAN; oldvcy = gs.vcy; vh = gs.sy * gs.vp.height; gs.vcy = min(gs.vcy + pan * vh, jas_image_bry(gs.image) - 0.5 * vh); if (gs.vcy != oldvcy) { gs.dirty = 1; glutPostRedisplay(); } } } break; case GLUT_KEY_LEFT: { float oldvcx; float vw; float pan; if (gs.vp.width < jas_image_width(gs.image) / gs.sx) { pan = (glutGetModifiers() & GLUT_ACTIVE_SHIFT) ? BIGPAN : SMALLPAN; oldvcx = gs.vcx; vw = gs.sx * gs.vp.width; gs.vcx = max(gs.vcx - pan * vw, jas_image_tlx(gs.image) + 0.5 * vw); if (gs.vcx != oldvcx) { gs.dirty = 1; glutPostRedisplay(); } } } break; case GLUT_KEY_RIGHT: { float oldvcx; float vw; float pan; if (gs.vp.width < jas_image_width(gs.image) / gs.sx) { pan = (glutGetModifiers() & GLUT_ACTIVE_SHIFT) ? BIGPAN : SMALLPAN; oldvcx = gs.vcx; vw = gs.sx * gs.vp.width; gs.vcx = min(gs.vcx + pan * vw, jas_image_brx(gs.image) - 0.5 * vw); if (gs.vcx != oldvcx) { gs.dirty = 1; glutPostRedisplay(); } } } break; default: break; } }
return DFB_OK; } static DFBResult IDirectFBImageProvider_JPEG2000_GetSurfaceDescription( IDirectFBImageProvider *thiz, DFBSurfaceDescription *desc ) { DIRECT_INTERFACE_GET_DATA( IDirectFBImageProvider_JPEG2000 ) if (!desc) return DFB_INVARG; desc->flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; desc->width = jas_image_width(data->image); desc->height = jas_image_height(data->image); desc->pixelformat = dfb_primary_layer_pixelformat(); return DFB_OK; } static DFBResult IDirectFBImageProvider_JPEG2000_GetImageDescription( IDirectFBImageProvider *thiz, DFBImageDescription *desc ) { DIRECT_INTERFACE_GET_DATA( IDirectFBImageProvider_JPEG2000 ) if (!desc) return DFB_INVARG; desc->caps = DICAPS_NONE;
int FROM_jpeg2000(char *injpc,int bufsize,unsigned int *outfld) /*$$$ SUBPROGRAM DOCUMENTATION BLOCK * . . . . * SUBPROGRAM: FROM_jpeg2000 Decodes JPEG2000 code stream * PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-12-02 * * ABSTRACT: This Function decodes a JPEG2000 code stream specified in the * JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) using JasPer * Software version 1.700.2 or better written by the University of British * Columbia and Image Power Inc, and others. * JasPer is available at http://www.ece.uvic.ca/~mdadams/jasper/. * * PROGRAM HISTORY LOG: * 2002-12-02 Gilbert * 2015-10-26 M.Valin - removed GRIB library connections, light refactoring, * changed function name * * USAGE: int FROM_jpeg2000(char *injpc,int bufsize,int *outfld) * * INPUT ARGUMENTS: * injpc - Input JPEG2000 code stream. * bufsize - Length (in bytes) of the input JPEG2000 code stream. * * OUTPUT ARGUMENTS: * outfld - Output matrix of grayscale image values. * * RETURN VALUES : * 0 = Successful decode * -3 = Error decode jpeg2000 code stream. * -5 = decoded image had multiple color components. * Only grayscale is allowed. * * REMARKS: * * Requires JasPer Software version 1.700.2 or better * * ATTRIBUTES: * LANGUAGE: C * OS: Linux * *$$$*/ { int ier; int i,j,k; jas_image_t *image=0; jas_stream_t *jpcstream; jas_image_cmpt_t *pcmpt; char *opts=0; jas_matrix_t *data; #define ROW unsigned long // ROW *my_row; unsigned int value; // jas_init(); ier=0; // // Create jas_stream_t containing input JPEG200 codestream in memory. // jpcstream=jas_stream_memopen(injpc,bufsize); // // Decode JPEG200 codestream into jas_image_t structure. // image=jpc_decode(jpcstream,opts); if ( image == 0 ) { printf(" jpc_decode return\n"); return -3; } pcmpt=image->cmpts_[0]; #if defined(DEBUG) printf(" SAGOUT DECODE:\n"); printf(" tlx %d \n",image->tlx_); printf(" tly %d \n",image->tly_); printf(" brx %d \n",image->brx_); printf(" bry %d \n",image->bry_); printf(" numcmpts %d \n",image->numcmpts_); printf(" maxcmpts %d \n",image->maxcmpts_); printf(" colorspace %d \n",image->clrspc_); printf(" inmem %d \n",image->inmem_); printf(" COMPONENT:\n"); printf(" tlx %d \n",pcmpt->tlx_); printf(" tly %d \n",pcmpt->tly_); printf(" hstep %d \n",pcmpt->hstep_); printf(" vstep %d \n",pcmpt->vstep_); printf(" width %d \n",pcmpt->width_); printf(" height %d \n",pcmpt->height_); printf(" prec %d \n",pcmpt->prec_); printf(" sgnd %d \n",pcmpt->sgnd_); printf(" cps %d \n",pcmpt->cps_); printf(" type %d \n",pcmpt->type_); #endif // Expecting jpeg2000 image to be grayscale only. // No color components. // if (image->numcmpts_ != 1 ) { printf("FROM_jpeg2000: Found color image. Grayscale expected.\n"); return (-5); } // // Create a data matrix of grayscale image values decoded from // the jpeg2000 codestream. // data=jas_matrix_create(jas_image_height(image), jas_image_width(image)); jas_image_readcmpt(image,0,0,0,jas_image_width(image), jas_image_height(image),data); // // Copy data matrix to output integer array. // k=0; // printf ("deltap = %d\n",data->rows_[1]-data->rows_[0]); for (i=0;i<pcmpt->height_;i++) { // my_row = (ROW *)data->rows_[i]; // printf ("p = %16p\n",my_row); for (j=0;j<pcmpt->width_;j++) { // value = my_row[j]; // outfld[k++] = my_row[j]; // printf ("%4ld ",my_row[j]); // printf ("%16.16x ",my_row[j]); outfld[k++]=data->rows_[i][j]; } // printf ("%d \n",k); } // // Clean up JasPer work structures. // jas_matrix_destroy(data); ier=jas_stream_close(jpcstream); jas_image_destroy(image); return 0; }
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; }
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)); }