static void ReadJP2KImage( GenericImage<P>& img, jas_stream_t* jp2Stream, jas_image_t* jp2Image ) { int width = jas_image_cmptwidth( jp2Image, 0 ); int height = jas_image_cmptheight( jp2Image, 0 ); int numberOfChannels = jas_image_numcmpts( jp2Image ); jas_matrix_t* pixels = nullptr; try { pixels = jas_matrix_create( 1, width ); if ( pixels == nullptr ) throw Error( "Memory allocation error reading JPEG2000 image" ); // Allocate pixel data img.AllocateData( width, height, numberOfChannels, (jas_clrspc_fam( jas_image_clrspc( jp2Image ) ) == JAS_CLRSPC_FAM_GRAY) ? ColorSpace::Gray : ColorSpace::RGB ); for ( int c = 0; c < numberOfChannels; ++c ) { int n = jas_image_cmptprec( jp2Image, c ); bool s = jas_image_cmptsgnd( jp2Image, c ) != 0; for ( int y = 0; y < height; ++y ) { jas_image_readcmpt( jp2Image, c, 0, y, width, 1, pixels ); typename P::sample* f = img.ScanLine( y, c ); if ( n == 8 ) { if ( s ) for ( int x = 0; x < width; ++x ) *f++ = P::ToSample( int8( jas_matrix_get( pixels, 0, x ) ) ); else for ( int x = 0; x < width; ++x ) *f++ = P::ToSample( uint8( jas_matrix_get( pixels, 0, x ) ) ); } else { if ( s ) for ( int x = 0; x < width; ++x ) *f++ = P::ToSample( int16( jas_matrix_get( pixels, 0, x ) ) ); else for ( int x = 0; x < width; ++x ) *f++ = P::ToSample( uint16( jas_matrix_get( pixels, 0, x ) ) ); } } } jas_matrix_destroy( pixels ), pixels = nullptr; } catch ( ... ) { if ( pixels != nullptr ) jas_matrix_destroy( pixels ); throw; } }
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; }
static unsigned int maxJasperComponentPrecision(jas_image_t * const jasperP) { int cmptNo; unsigned int max; max = 1; for (cmptNo = 0; cmptNo < jas_image_numcmpts(jasperP); ++cmptNo) max = MAX(max, jas_image_cmptprec(jasperP, cmptNo)); return max; }
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 void computeComponentMaxval(struct pam * const outpamP, jas_image_t * const jasperP, int const jasperCmpt[], sample ** const jasperMaxvalP, bool * const singleMaxvalP) { sample * jasperMaxval; unsigned int plane; MALLOCARRAY(jasperMaxval, outpamP->depth); *singleMaxvalP = TRUE; /* initial assumption */ for (plane = 0; plane < outpamP->depth; ++plane) { jasperMaxval[plane] = pm_bitstomaxval(jas_image_cmptprec(jasperP, jasperCmpt[plane])); if (jasperMaxval[plane] != jasperMaxval[0]) *singleMaxvalP = FALSE; } *jasperMaxvalP = jasperMaxval; }
int jas_image_render2(jas_image_t *image, int cmptno, float vtlx, float vtly, float vsx, float vsy, int vw, int vh, GLshort *vdata) { int i; int j; int x; int y; int v; GLshort *vdatap; if (cmptno < 0 || cmptno >= image->numcmpts_) { jas_eprintf("bad parameter\n"); goto error; } for (i = 0; i < vh; ++i) { vdatap = &vdata[(vh - 1 - i) * (4 * vw)]; for (j = 0; j < vw; ++j) { x = vctocc(j, jas_image_cmpttlx(image, cmptno), jas_image_cmpthstep(image, cmptno), vtlx, vsx); y = vctocc(i, jas_image_cmpttly(image, cmptno), jas_image_cmptvstep(image, cmptno), vtly, vsy); v = (x >= 0 && x < jas_image_cmptwidth(image, cmptno) && y >=0 && y < jas_image_cmptheight(image, cmptno)) ? jas_image_readcmptsample(image, cmptno, x, y) : 0; v <<= 16 - jas_image_cmptprec(image, cmptno); if (v < 0) { v = 0; } else if (v > 65535) { v = 65535; } *vdatap++ = v; *vdatap++ = v; *vdatap++ = v; *vdatap++ = 0; } } return 0; error: 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; }
int main(int argc, char **argv) { int fmtid; int id; char *infile; jas_stream_t *instream; jas_image_t *image; int width; int height; int depth; int numcmpts; int verbose; char *fmtname; if (jas_init()) { errprint(0, "error: cannot initialize jasper library\n"); abort(); } /* set our error callback */ jas_set_error_cb(errprint); cmdname = argv[0]; infile = 0; verbose = 0; /* Parse the command line options. */ while ((id = jas_getopt(argc, argv, opts)) >= 0) { switch (id) { case OPT_VERBOSE: verbose = 1; break; case OPT_VERSION: printf("%s\n", JAS_VERSION); exit(EXIT_SUCCESS); break; case OPT_INFILE: infile = jas_optarg; break; case OPT_HELP: default: usage(); break; } } /* Open the image file. */ if (infile) { /* The image is to be read from a file. */ if (!(instream = jas_stream_fopen(infile, "rb"))) { jas_eprintf("cannot open input image file %s\n", infile); exit(EXIT_FAILURE); } } else { /* The image is to be read from standard input. */ if (!(instream = jas_stream_fdopen(0, "rb"))) { jas_eprintf("cannot open standard input\n"); exit(EXIT_FAILURE); } } if ((fmtid = jas_image_getfmt(instream)) < 0) { jas_eprintf("unknown image format\n"); } /* Decode the image. */ if (!(image = jas_image_decode(instream, fmtid, 0))) { jas_eprintf("cannot load image\n"); return EXIT_FAILURE; } /* Close the image file. */ jas_stream_close(instream); numcmpts = jas_image_numcmpts(image); width = jas_image_cmptwidth(image, 0); height = jas_image_cmptheight(image, 0); depth = jas_image_cmptprec(image, 0); if (!(fmtname = jas_image_fmttostr(fmtid))) { abort(); } jas_eprintf("%s %d %d %d %d %ld\n", fmtname, numcmpts, width, height, depth, (long) jas_image_rawsize(image)); jas_image_destroy(image); jas_image_clearfmts(); return EXIT_SUCCESS; }
int pgx_encode(jas_image_t *image, jas_stream_t *out, char *optstr) { pgx_hdr_t hdr; uint_fast32_t width; uint_fast32_t height; jas_bool sgnd; int prec; pgx_enc_t encbuf; pgx_enc_t *enc = &encbuf; /* Avoid compiler warnings about unused parameters. */ optstr = 0; switch (jas_clrspc_fam(jas_image_clrspc(image))) { case JAS_CLRSPC_FAM_GRAY: if ((enc->cmpt = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y))) < 0) { jas_eprintf("error: missing color component\n"); return -1; } break; default: jas_eprintf("error: BMP format does not support color space\n"); return -1; break; } width = jas_image_cmptwidth(image, enc->cmpt); height = jas_image_cmptheight(image, enc->cmpt); prec = jas_image_cmptprec(image, enc->cmpt); sgnd = jas_image_cmptsgnd(image, enc->cmpt); /* The PGX format is quite limited in the set of image geometries that it can handle. Here, we check to ensure that the image to be saved can actually be represented reasonably accurately using the PGX format. */ /* There must be exactly one component. */ if (jas_image_numcmpts(image) > 1 || prec > 16) { jas_eprintf("The PNM format cannot be used to represent an image with this geometry.\n"); return -1; } hdr.magic = PGX_MAGIC; hdr.bigendian = jas_true; hdr.sgnd = sgnd; hdr.prec = prec; hdr.width = width; hdr.height = height; #ifdef PGX_DEBUG pgx_dumphdr(&hdr); #endif if (pgx_puthdr(out, &hdr)) { return -1; } if (pgx_putdata(out, &hdr, image, enc->cmpt)) { return -1; } return 0; }
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, 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(); }
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 Image *ReadJP2Image(const ImageInfo *image_info, ExceptionInfo *exception) { Image *image; long y; jas_image_t *jp2_image; jas_matrix_t *pixels; jas_stream_t *jp2_stream; register long x; register PixelPacket *q; int component, components[4], number_components; Quantum *channel_lut[4]; unsigned int status; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AllocateImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == False) ThrowReaderException(FileOpenError,UnableToOpenFile,image); /* Obtain a JP2 Stream. */ jp2_stream=JP2StreamManager(image); if (jp2_stream == (jas_stream_t *) NULL) ThrowReaderException(DelegateError,UnableToManageJP2Stream,image); jp2_image=jas_image_decode(jp2_stream,-1,0); if (jp2_image == (jas_image_t *) NULL) { (void) jas_stream_close(jp2_stream); ThrowReaderException(DelegateError,UnableToDecodeImageFile,image); } /* Validate that we can handle the image and obtain component indexes. */ switch (jas_clrspc_fam(jas_image_clrspc(jp2_image))) { case JAS_CLRSPC_FAM_RGB: { if (((components[0]= jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R))) < 0) || ((components[1]= jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G))) < 0) || ((components[2]= jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B))) < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,MissingImageChannel,image); } number_components=3; (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Image is in RGB colorspace family"); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "RED is in channel %d, GREEN is in channel %d, BLUE is in channel %d", components[0],components[1],components[2]); if((components[3]=jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_OPACITY))) > 0) { image->matte=MagickTrue; (void) LogMagickEvent(CoderEvent,GetMagickModule(), "OPACITY is in channel %d",components[3]); number_components++; } break; } case JAS_CLRSPC_FAM_GRAY: { if ((components[0]= jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y))) < 0) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,MissingImageChannel,image); } (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Image is in GRAY colorspace family"); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "GRAY is in channel %d",components[0]); number_components=1; break; } case JAS_CLRSPC_FAM_YCBCR: { components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_Y); components[1]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CB); components[2]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CR); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,MissingImageChannel,image); } number_components=3; components[3]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_OPACITY); if (components[3] > 0) { image->matte=True; number_components++; } image->colorspace=YCbCrColorspace; (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Image is in YCBCR colorspace family"); break; } default: { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CoderError,ColorspaceModelIsNotSupported,image); } } image->columns=jas_image_width(jp2_image); image->rows=jas_image_height(jp2_image); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "columns=%lu rows=%lu components=%d",image->columns,image->rows, number_components); for (component=0; component < number_components; component++) { if(((unsigned long) jas_image_cmptwidth(jp2_image,components[component]) != image->columns) || ((unsigned long) jas_image_cmptheight(jp2_image,components[component]) != image->rows) || (jas_image_cmpttlx(jp2_image, components[component]) != 0) || (jas_image_cmpttly(jp2_image, components[component]) != 0) || (jas_image_cmpthstep(jp2_image, components[component]) != 1) || (jas_image_cmptvstep(jp2_image, components[component]) != 1) || (jas_image_cmptsgnd(jp2_image, components[component]) != false)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CoderError,IrregularChannelGeometryNotSupported,image); } } image->matte=number_components > 3; for (component=0; component < number_components; component++) { unsigned int component_depth; component_depth=jas_image_cmptprec(jp2_image,components[component]); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Component[%d] depth is %u",component,component_depth); if (0 == component) image->depth=component_depth; else image->depth=Max(image->depth,component_depth); } (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Image depth is %u",image->depth); if (image_info->ping) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); return(image); } /* Allocate Jasper pixels. */ pixels=jas_matrix_create(1,(unsigned int) image->columns); if (pixels == (jas_matrix_t *) NULL) { jas_image_destroy(jp2_image); ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); } /* Allocate and populate channel LUTs */ for (component=0; component < (long) number_components; component++) { unsigned long component_depth, i, max_value; double scale_to_quantum; component_depth=jas_image_cmptprec(jp2_image,components[component]); max_value=MaxValueGivenBits(component_depth); scale_to_quantum=MaxRGBDouble/max_value; (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Channel %d scale is %g", component, scale_to_quantum); channel_lut[component]=MagickAllocateArray(Quantum *,max_value+1,sizeof(Quantum)); if (channel_lut[component] == (Quantum *) NULL) { for ( --component; component >= 0; --component) MagickFreeMemory(channel_lut[component]); jas_matrix_destroy(pixels); jas_image_destroy(jp2_image); ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); } for(i=0; i <= max_value; i++) (channel_lut[component])[i]=scale_to_quantum*i+0.5; } /* Convert JPEG 2000 pixels. */ for (y=0; y < (long) image->rows; y++) { q=GetImagePixels(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) break; if (1 == number_components) { /* Grayscale */ (void) jas_image_readcmpt(jp2_image,(short) components[0],0, (unsigned int) y, (unsigned int) image->columns,1,pixels); for (x=0; x < (long) image->columns; x++) { q->red=q->green=q->blue=(channel_lut[0])[jas_matrix_getv(pixels,x)]; q->opacity=OpaqueOpacity; q++; } } else { /* Red */ (void) jas_image_readcmpt(jp2_image,(short) components[0],0, (unsigned int) y, (unsigned int) image->columns,1,pixels); for (x=0; x < (long) image->columns; x++) q[x].red=(channel_lut[0])[jas_matrix_getv(pixels,x)]; /* Green */ (void) jas_image_readcmpt(jp2_image,(short) components[1],0, (unsigned int) y, (unsigned int) image->columns,1,pixels); for (x=0; x < (long) image->columns; x++) q[x].green=(channel_lut[1])[jas_matrix_getv(pixels,x)]; /* Blue */ (void) jas_image_readcmpt(jp2_image,(short) components[2],0, (unsigned int) y, (unsigned int) image->columns,1,pixels); for (x=0; x < (long) image->columns; x++) q[x].blue=(channel_lut[2])[jas_matrix_getv(pixels,x)]; /* Opacity */ if (number_components > 3) { (void) jas_image_readcmpt(jp2_image,(short) components[3],0, (unsigned int) y, (unsigned int) image->columns,1,pixels); for (x=0; x < (long) image->columns; x++) q[x].opacity=MaxRGB-(channel_lut[3])[jas_matrix_getv(pixels,x)]; } else { for (x=0; x < (long) image->columns; x++) q[x].opacity=OpaqueOpacity; } } if (!SyncImagePixels(image)) break; if (image->previous == (Image *) NULL) if (QuantumTick(y,image->rows)) if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText, image->filename, image->columns,image->rows)) break; } if (number_components == 1) image->is_grayscale=MagickTrue; { /* Obtain ICC ICM color profile */ jas_cmprof_t *cm_profile; /* Obtain a pointer to the existing jas_cmprof_t profile handle. */ cm_profile=jas_image_cmprof(jp2_image); if (cm_profile != (jas_cmprof_t *) NULL) { jas_iccprof_t *icc_profile; /* Obtain a copy of the jas_iccprof_t ICC profile handle */ icc_profile=jas_iccprof_createfromcmprof(cm_profile); /* or maybe just icc_profile=cm_profile->iccprof */ if (icc_profile != (jas_iccprof_t *) NULL) { jas_stream_t *icc_stream; icc_stream=jas_stream_memopen(NULL,0); if ((icc_stream != (jas_stream_t *) NULL) && (jas_iccprof_save(icc_profile,icc_stream) == 0) && (jas_stream_flush(icc_stream) == 0)) { jas_stream_memobj_t *blob; blob=(jas_stream_memobj_t *) icc_stream->obj_; if (image->logging) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "ICC profile: %lu bytes",(unsigned long) blob->len_); SetImageProfile(image,"ICM",blob->buf_,blob->len_); (void) jas_stream_close(icc_stream); jas_iccprof_destroy(icc_profile); } } } } for (component=0; component < (long) number_components; component++) MagickFreeMemory(channel_lut[component]); jas_matrix_destroy(pixels); (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); return(image); }
int 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; }
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 drawview(jas_image_t *image, float vtlx, float vtly, float sx, float sy, pixmap_t *p) { int i; int j; int k; int red; int grn; int blu; int lum; GLshort *datap; int x; int y; int *cmptlut; int numcmpts; int v[4]; int u[4]; int color; cmptlut = gs.cmptlut; switch (jas_image_colorspace(gs.image)) { case JAS_IMAGE_CS_RGB: case JAS_IMAGE_CS_YCBCR: color = 1; numcmpts = 3; break; case JAS_IMAGE_CS_GRAY: default: numcmpts = 1; color = 0; break; } for (i = 0; i < p->height; ++i) { datap = &p->data[(p->height - 1 - i) * (4 * p->width)]; for (j = 0; j < p->width; ++j) { if (!gs.monomode && color) { for (k = 0; k < numcmpts; ++k) { x = vctocc(j, jas_image_cmpttlx(gs.image, cmptlut[k]), jas_image_cmpthstep(gs.image, cmptlut[k]), vtlx, sx); y = vctocc(i, jas_image_cmpttly(gs.image, cmptlut[k]), jas_image_cmptvstep(gs.image, cmptlut[k]), vtly, sy); v[k] = (x >= 0 && x < jas_image_cmptwidth(gs.image, cmptlut[k]) && y >=0 && y < jas_image_cmptheight(gs.image, cmptlut[k])) ? jas_matrix_get(gs.cmpts[cmptlut[k]], y, x) : 0; v[k] <<= 16 - jas_image_cmptprec(gs.image, cmptlut[k]); } switch (jas_image_colorspace(gs.image)) { case JAS_IMAGE_CS_RGB: break; case JAS_IMAGE_CS_YCBCR: u[0] = (1/1.772) * (v[0] + 1.402 * v[2]); u[1] = (1/1.772) * (v[0] - 0.34413 * v[1] - 0.71414 * v[2]); u[2] = (1/1.772) * (v[0] + 1.772 * v[1]); v[0] = u[0]; v[1] = u[1]; v[2] = u[2]; break; } } else { x = vctocc(j, jas_image_cmpttlx(gs.image, gs.cmptno), jas_image_cmpthstep(gs.image, gs.cmptno), vtlx, sx); y = vctocc(i, jas_image_cmpttly(gs.image, gs.cmptno), jas_image_cmptvstep(gs.image, gs.cmptno), vtly, sy); v[0] = (x >= 0 && x < jas_image_cmptwidth(gs.image, gs.cmptno) && y >=0 && y < jas_image_cmptheight(gs.image, gs.cmptno)) ? jas_matrix_get(gs.cmpts[gs.cmptno], y, x) : 0; v[0] <<= 16 - jas_image_cmptprec(gs.image, gs.cmptno); v[1] = v[0]; v[2] = v[0]; v[3] = 0; } for (k = 0; k < 3; ++k) { if (v[k] < 0) { v[k] = 0; } else if (v[k] > 65535) { v[k] = 65535; } } *datap++ = v[0]; *datap++ = v[1]; *datap++ = v[2]; *datap++ = 0; } } }
static int jas_image_render(jas_image_t *image, float vtlx, float vtly, float vsx, float vsy, int vw, int vh, GLshort *vdata) { int i; int j; int k; int x; int y; int v[3]; GLshort *vdatap; int cmptlut[3]; int width; int height; int hs; int vs; int tlx; int tly; if ((cmptlut[0] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R))) < 0 || (cmptlut[1] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G))) < 0 || (cmptlut[2] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B))) < 0) goto error; width = jas_image_cmptwidth(image, cmptlut[0]); height = jas_image_cmptheight(image, cmptlut[0]); tlx = jas_image_cmpttlx(image, cmptlut[0]); tly = jas_image_cmpttly(image, cmptlut[0]); vs = jas_image_cmptvstep(image, cmptlut[0]); hs = jas_image_cmpthstep(image, cmptlut[0]); for (i = 1; i < 3; ++i) { if (jas_image_cmptwidth(image, cmptlut[i]) != width || jas_image_cmptheight(image, cmptlut[i]) != height) goto error; } for (i = 0; i < vh; ++i) { vdatap = &vdata[(vh - 1 - i) * (4 * vw)]; for (j = 0; j < vw; ++j) { x = vctocc(j, tlx, hs, vtlx, vsx); y = vctocc(i, tly, vs, vtly, vsy); if (x >= 0 && x < width && y >= 0 && y < height) { for (k = 0; k < 3; ++k) { v[k] = jas_image_readcmptsample(image, cmptlut[k], x, y); v[k] <<= 16 - jas_image_cmptprec(image, cmptlut[k]); if (v[k] < 0) { v[k] = 0; } else if (v[k] > 65535) { v[k] = 65535; } } } else { v[0] = 0; v[1] = 0; v[2] = 0; } *vdatap++ = v[0]; *vdatap++ = v[1]; *vdatap++ = v[2]; *vdatap++ = 0; } } return 0; error: return -1; }
static GstFlowReturn gst_jasper_dec_negotiate (GstJasperDec * dec, jas_image_t * image) { GstFlowReturn flow_ret = GST_FLOW_OK; gint width, height, channels; gint i, j; gboolean negotiate = FALSE; jas_clrspc_t clrspc; GstCaps *allowed_caps, *caps; width = jas_image_width (image); height = jas_image_height (image); channels = jas_image_numcmpts (image); GST_LOG_OBJECT (dec, "%d x %d, %d components", width, height, channels); /* jp2c bitstream has no real colour space info (kept in container), * so decoder may only pretend to know, where it really does not */ if (!jas_clrspc_isunknown (dec->clrspc)) { clrspc = dec->clrspc; GST_DEBUG_OBJECT (dec, "forcing container supplied colour space %d", clrspc); jas_image_setclrspc (image, clrspc); } else clrspc = jas_image_clrspc (image); if (!width || !height || !channels || jas_clrspc_isunknown (clrspc)) goto fail_image; if (dec->width != width || dec->height != height || dec->channels != channels || dec->clrspc != clrspc) negotiate = TRUE; if (channels != 3) goto not_supported; for (i = 0; i < channels; i++) { gint cheight, cwidth, depth, sgnd; cheight = jas_image_cmptheight (image, i); cwidth = jas_image_cmptwidth (image, i); depth = jas_image_cmptprec (image, i); sgnd = jas_image_cmptsgnd (image, i); GST_LOG_OBJECT (dec, "image component %d, %dx%d, depth %d, sgnd %d", i, cwidth, cheight, depth, sgnd); if (depth != 8 || sgnd) goto not_supported; if (dec->cheight[i] != cheight || dec->cwidth[i] != cwidth) { dec->cheight[i] = cheight; dec->cwidth[i] = cwidth; negotiate = TRUE; } } if (!negotiate && dec->format != GST_VIDEO_FORMAT_UNKNOWN) goto done; /* clear and refresh to new state */ flow_ret = GST_FLOW_NOT_NEGOTIATED; dec->format = GST_VIDEO_FORMAT_UNKNOWN; dec->width = width; dec->height = height; dec->channels = channels; /* retrieve allowed caps, and find the first one that reasonably maps * to the parameters of the colourspace */ caps = gst_pad_get_allowed_caps (dec->srcpad); if (!caps) { GST_DEBUG_OBJECT (dec, "... but no peer, using template caps"); /* need to copy because get_allowed_caps returns a ref, and get_pad_template_caps doesn't */ caps = gst_caps_copy (gst_pad_get_pad_template_caps (dec->srcpad)); } /* avoid lists of fourcc, etc */ allowed_caps = gst_caps_normalize (caps); caps = NULL; GST_LOG_OBJECT (dec, "allowed source caps %" GST_PTR_FORMAT, allowed_caps); for (i = 0; i < gst_caps_get_size (allowed_caps); i++) { GstVideoFormat format; gboolean ok; if (caps) gst_caps_unref (caps); caps = gst_caps_copy_nth (allowed_caps, i); /* sigh, ds and _parse_caps need fixed caps for parsing, fixate */ gst_pad_fixate_caps (dec->srcpad, caps); GST_LOG_OBJECT (dec, "checking caps %" GST_PTR_FORMAT, caps); if (!gst_video_format_parse_caps (caps, &format, NULL, NULL)) continue; if (gst_video_format_is_rgb (format) && jas_clrspc_fam (clrspc) == JAS_CLRSPC_FAM_RGB) { GST_DEBUG_OBJECT (dec, "trying RGB"); if ((dec->cmpt[0] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_RGB_R))) < 0 || (dec->cmpt[1] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_RGB_G))) < 0 || (dec->cmpt[2] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_RGB_B))) < 0) { GST_DEBUG_OBJECT (dec, "missing RGB color component"); continue; } } else if (gst_video_format_is_yuv (format) && jas_clrspc_fam (clrspc) == JAS_CLRSPC_FAM_YCBCR) { GST_DEBUG_OBJECT (dec, "trying YUV"); if ((dec->cmpt[0] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_YCBCR_Y))) < 0 || (dec->cmpt[1] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_YCBCR_CB))) < 0 || (dec->cmpt[2] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_YCBCR_CR))) < 0) { GST_DEBUG_OBJECT (dec, "missing YUV color component"); continue; } } else continue; /* match format with validity checks */ ok = TRUE; for (j = 0; j < channels; j++) { gint cmpt; cmpt = dec->cmpt[j]; if (dec->cwidth[cmpt] != gst_video_format_get_component_width (format, j, width) || dec->cheight[cmpt] != gst_video_format_get_component_height (format, j, height)) ok = FALSE; } /* commit to this format */ if (ok) { dec->format = format; break; } } if (caps) gst_caps_unref (caps); gst_caps_unref (allowed_caps); if (dec->format != GST_VIDEO_FORMAT_UNKNOWN) { /* cache some video format properties */ for (j = 0; j < channels; ++j) { dec->offset[j] = gst_video_format_get_component_offset (dec->format, j, dec->width, dec->height); dec->inc[j] = gst_video_format_get_pixel_stride (dec->format, j); dec->stride[j] = gst_video_format_get_row_stride (dec->format, j, dec->width); } dec->image_size = gst_video_format_get_size (dec->format, width, height); dec->alpha = gst_video_format_has_alpha (dec->format); if (dec->buf) g_free (dec->buf); dec->buf = g_new0 (glong, dec->width); caps = gst_video_format_new_caps (dec->format, dec->width, dec->height, dec->framerate_numerator, dec->framerate_denominator, 1, 1); GST_DEBUG_OBJECT (dec, "Set format to %d, size to %dx%d", dec->format, dec->width, dec->height); if (!gst_pad_set_caps (dec->srcpad, caps)) flow_ret = GST_FLOW_NOT_NEGOTIATED; else flow_ret = GST_FLOW_OK; gst_caps_unref (caps); } done: return flow_ret; /* ERRORS */ fail_image: { GST_DEBUG_OBJECT (dec, "Failed to process decoded image."); flow_ret = GST_FLOW_NOT_NEGOTIATED; goto done; } not_supported: { GST_DEBUG_OBJECT (dec, "Decoded image has unsupported colour space."); GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("Unsupported colorspace")); flow_ret = GST_FLOW_ERROR; goto done; } }
bool CxImageJAS::Decode(CxFile *hFile, uint32_t imagetype) { if (hFile == NULL) return false; jas_image_t *image=0; jas_stream_t *in=0; jas_matrix_t **bufs=0; int32_t i,error=0; int32_t fmt; //jas_setdbglevel(0); cx_try { if (jas_init()) cx_throw("cannot initialize jasper"); in = jas_stream_fdopen(0, "rb"); if (!in) cx_throw("error: cannot open standard input"); CxFileJas src(hFile,in); fmt = jas_image_getfmt(in); if (fmt<0) cx_throw("error: unknowm format"); image = jas_image_decode(in, fmt, 0); if (!image){ fmt = -1; cx_throw("error: cannot load image data"); } char szfmt[4]; *szfmt = '\0'; strncpy(szfmt,jas_image_fmttostr(fmt),3); szfmt[3] = '\0'; fmt = -1; #if CXIMAGE_SUPPORT_JP2 if (strcmp(szfmt,"jp2")==0) fmt = CXIMAGE_FORMAT_JP2; #endif #if CXIMAGE_SUPPORT_JPC if (strcmp(szfmt,"jpc")==0) fmt = CXIMAGE_FORMAT_JPC; #endif #if CXIMAGE_SUPPORT_RAS if (strcmp(szfmt,"ras")==0) fmt = CXIMAGE_FORMAT_RAS; #endif #if CXIMAGE_SUPPORT_PNM if (strcmp(szfmt,"pnm")==0) fmt = CXIMAGE_FORMAT_PNM; #endif #if CXIMAGE_SUPPORT_PGX if (strcmp(szfmt,"pgx")==0) fmt = CXIMAGE_FORMAT_PGX; #endif //if (fmt<0) // cx_throw("error: unknowm format"); int32_t x,y,w,h,depth,cmptno; w = jas_image_cmptwidth(image,0); h = jas_image_cmptheight(image,0); depth = jas_image_cmptprec(image,0); if (info.nEscape == -1){ head.biWidth = w; head.biHeight= h; info.dwType = fmt<0 ? 0 : fmt; cx_throw("output dimensions returned"); } if (image->numcmpts_ > 64 || image->numcmpts_ < 0) cx_throw("error: too many components"); // <LD> 01/Jan/2005: Always force conversion to sRGB. Seems to be required for many types of JPEG2000 file. // if (depth!=1 && depth!=4 && depth!=8) if (image->numcmpts_>=3 && depth <=8) { jas_image_t *newimage; jas_cmprof_t *outprof; //jas_eprintf("forcing conversion to sRGB\n"); outprof = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB); if (!outprof) { cx_throw("cannot create sRGB profile"); } newimage = jas_image_chclrspc(image, outprof, JAS_CMXFORM_INTENT_PER); if (!newimage) { jas_cmprof_destroy(outprof); // <LD> 01/Jan/2005: Destroy color profile on error. cx_throw("cannot convert to sRGB"); } jas_image_destroy(image); jas_cmprof_destroy(outprof); image = newimage; } bufs = (jas_matrix_t **)calloc(image->numcmpts_, sizeof(jas_matrix_t**)); for (i = 0; i < image->numcmpts_; ++i) { bufs[i] = jas_matrix_create(1, w); if (!bufs[i]) { cx_throw("error: cannot allocate memory"); } } int32_t nshift = (depth>8) ? (depth-8) : 0; if (image->numcmpts_==3 && image->cmpts_[0]->width_ == image->cmpts_[1]->width_ && image->cmpts_[1]->width_ == image->cmpts_[2]->width_ && image->cmpts_[0]->height_ == image->cmpts_[1]->height_ && image->cmpts_[1]->height_ == image->cmpts_[2]->height_ && image->cmpts_[0]->prec_ == image->cmpts_[1]->prec_ && image->cmpts_[1]->prec_ == image->cmpts_[2]->prec_ ) { if(!Create(w,h,24,fmt)) cx_throw(""); RGBQUAD c; for (y=0; y<h; y++) { for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) { jas_image_readcmpt(image, cmptno, 0, y, w, 1, bufs[cmptno]); } for (x=0; x<w; x++){ c.rgbRed = (uint8_t)((jas_matrix_getv(bufs[0], x)>>nshift)); c.rgbGreen = (uint8_t)((jas_matrix_getv(bufs[1], x)>>nshift)); c.rgbBlue = (uint8_t)((jas_matrix_getv(bufs[2], x)>>nshift)); SetPixelColor(x,h-1-y,c); } } } else { info.nNumFrames = image->numcmpts_; if ((info.nFrame<0)||(info.nFrame>=info.nNumFrames)){ cx_throw("wrong frame!"); } for (cmptno=0; cmptno<=info.nFrame; cmptno++) { w = jas_image_cmptwidth(image,cmptno); h = jas_image_cmptheight(image,cmptno); depth = jas_image_cmptprec(image,cmptno); if (depth>8) depth=8; if(!Create(w,h,depth,imagetype)) cx_throw(""); SetGrayPalette(); for (y=0; y<h; y++) { jas_image_readcmpt(image, cmptno, 0, y, w, 1, bufs[0]); for (x=0; x<w; x++){ SetPixelIndex(x,h-1-y,(uint8_t)((jas_matrix_getv(bufs[0], x)>>nshift))); } } } } } cx_catch {
int jpg_encode(jas_image_t *image, jas_stream_t *out, char *optstr) { JDIMENSION numscanlines; struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; jas_image_coord_t width; jas_image_coord_t height; jpg_src_t src_mgr_buf; jpg_src_t *src_mgr = &src_mgr_buf; FILE *output_file; int cmptno; jpg_enc_t encbuf; jpg_enc_t *enc = &encbuf; jpg_encopts_t encopts; output_file = 0; if (jpg_parseencopts(optstr, &encopts)) goto error; switch (jas_clrspc_fam(jas_image_clrspc(image))) { case JAS_CLRSPC_FAM_RGB: if (jas_image_clrspc(image) != JAS_CLRSPC_SRGB) jas_eprintf("warning: inaccurate color\n"); enc->numcmpts = 3; if ((enc->cmpts[0] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R))) < 0 || (enc->cmpts[1] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G))) < 0 || (enc->cmpts[2] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B))) < 0) { jas_eprintf("error: missing color component\n"); goto error; } break; case JAS_CLRSPC_FAM_YCBCR: if (jas_image_clrspc(image) != JAS_CLRSPC_SYCBCR) jas_eprintf("warning: inaccurate color\n"); enc->numcmpts = 3; if ((enc->cmpts[0] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_Y))) < 0 || (enc->cmpts[1] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CB))) < 0 || (enc->cmpts[2] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CR))) < 0) { jas_eprintf("error: missing color component\n"); goto error; } break; case JAS_CLRSPC_FAM_GRAY: if (jas_image_clrspc(image) != JAS_CLRSPC_SGRAY) jas_eprintf("warning: inaccurate color\n"); enc->numcmpts = 1; if ((enc->cmpts[0] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y))) < 0) { jas_eprintf("error: missing color component\n"); goto error; } break; default: jas_eprintf("error: JPG format does not support color space\n"); goto error; break; } width = jas_image_width(image); height = jas_image_height(image); for (cmptno = 0; cmptno < enc->numcmpts; ++cmptno) { if (jas_image_cmptwidth(image, enc->cmpts[cmptno]) != width || jas_image_cmptheight(image, enc->cmpts[cmptno]) != height || jas_image_cmpttlx(image, enc->cmpts[cmptno]) != 0 || jas_image_cmpttly(image, enc->cmpts[cmptno]) != 0 || jas_image_cmpthstep(image, enc->cmpts[cmptno]) != 1 || jas_image_cmptvstep(image, enc->cmpts[cmptno]) != 1 || jas_image_cmptprec(image, enc->cmpts[cmptno]) != 8 || jas_image_cmptsgnd(image, enc->cmpts[cmptno]) != jas_false) { jas_eprintf("error: The JPG encoder cannot handle an image with this geometry.\n"); goto error; } } if (!(output_file = tmpfile())) { goto error; } /* Create a JPEG compression object. */ cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); /* Specify data destination for compression */ jpeg_stdio_dest(&cinfo, output_file); cinfo.in_color_space = tojpgcs(jas_image_clrspc(image)); cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = enc->numcmpts; jpeg_set_defaults(&cinfo); src_mgr->error = 0; src_mgr->image = image; src_mgr->data = jas_matrix_create(1, width); src_mgr->buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, (JDIMENSION) width * cinfo.input_components, (JDIMENSION) 1); src_mgr->buffer_height = 1; src_mgr->enc = enc; /* Read the input file header to obtain file size & colorspace. */ jpg_start_input(&cinfo, src_mgr); if (encopts.qual >= 0) { jpeg_set_quality(&cinfo, encopts.qual, jas_true); } /* Now that we know input colorspace, fix colorspace-dependent defaults */ jpeg_default_colorspace(&cinfo); /* Start compressor */ jpeg_start_compress(&cinfo, jas_true ); /* Process data */ while (cinfo.next_scanline < cinfo.image_height) { if ((numscanlines = jpg_get_pixel_rows(&cinfo, src_mgr)) <= 0) { break; } jpeg_write_scanlines(&cinfo, src_mgr->buffer, numscanlines); } /* Finish compression and release memory */ jpg_finish_input(&cinfo, src_mgr); jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); rewind(output_file); jpg_copyfiletostream(out, output_file); fclose(output_file); output_file = 0; return 0; error: if (output_file) { fclose(output_file); } return -1; }
static gboolean query_jp2 (const gchar *path, gint *width, gint *height, gint *depth, jas_image_t **jas_image) { gboolean ret; jas_stream_t *in; int image_fmt; jas_image_t *image; jas_cmprof_t *output_profile; jas_image_t *cimage; int numcmpts; int i; gboolean b; in = NULL; cimage = image = NULL; output_profile = NULL; ret = FALSE; do { in = jas_stream_fopen (path, "rb"); if (!in) { g_warning ("Unable to open image file '%s'", path); break; } image_fmt = jas_image_getfmt (in); if (image_fmt < 0) { g_warning (_("Unknown JPEG-2000 image format in '%s'"), path); break; } image = jas_image_decode (in, image_fmt, NULL); if (!image) { g_warning (_("Unable to open JPEG-2000 image in '%s'"), path); break; } output_profile = jas_cmprof_createfromclrspc (JAS_CLRSPC_SRGB); if (!output_profile) { g_warning (_("Unable to create output color profile for '%s'"), path); break; } cimage = jas_image_chclrspc (image, output_profile, JAS_CMXFORM_INTENT_PER); if (!cimage) { g_warning (_("Unable to convert image to sRGB color space " "when processing '%s'"), path); break; } numcmpts = jas_image_numcmpts (cimage); if (numcmpts != 3) { g_warning (_("Unsupported non-RGB JPEG-2000 file with " "%d components in '%s'"), numcmpts, path); break; } *width = jas_image_cmptwidth (cimage, 0); *height = jas_image_cmptheight (cimage, 0); *depth = jas_image_cmptprec (cimage, 0); if ((*depth != 8) && (*depth != 16)) { g_warning (_("Unsupported JPEG-2000 file with depth %d in '%s'"), *depth, path); break; } b = FALSE; for (i = 1; i < 3; i++) { if ((jas_image_cmptprec (cimage, i) != *depth) || (jas_image_cmptwidth (cimage, i) != *width) || (jas_image_cmptheight (cimage, i) != *height)) { g_warning (_("Components of input image '%s' don't match"), path); b = TRUE; break; } } if (b) break; ret = TRUE; } while (FALSE); /* structured goto */ if (jas_image) *jas_image = cimage; else if (cimage) jas_image_destroy (cimage); if (image) jas_image_destroy (image); if (output_profile) jas_cmprof_destroy (output_profile); if (in) jas_stream_close (in); return ret; }
bool Jpeg2KDecoder::readData(Mat& img) { bool result = false; int color = img.channels() > 1; uchar* data = img.data; int step = img.step; jas_stream_t* stream = (jas_stream_t*)m_stream; jas_image_t* image = (jas_image_t*)m_image; if (stream && image) { bool convert; int colorspace; if (color) { convert = (jas_image_clrspc(image) != JAS_CLRSPC_SRGB); colorspace = JAS_CLRSPC_SRGB; } else { convert = (jas_clrspc_fam(jas_image_clrspc(image)) != JAS_CLRSPC_FAM_GRAY); colorspace = JAS_CLRSPC_SGRAY; // TODO GENGRAY or SGRAY? } // convert to the desired colorspace if (convert) { jas_cmprof_t* clrprof = jas_cmprof_createfromclrspc(colorspace); if (clrprof) { jas_image_t* _img = jas_image_chclrspc(image, clrprof, JAS_CMXFORM_INTENT_RELCLR); if (_img) { jas_image_destroy(image); m_image = image = _img; result = true; } else { fprintf(stderr, "JPEG 2000 LOADER ERROR: cannot convert colorspace\n"); } jas_cmprof_destroy(clrprof); } else { fprintf(stderr, "JPEG 2000 LOADER ERROR: unable to create colorspace\n"); } } else { result = true; } if (result) { int ncmpts; int cmptlut[3]; if (color) { cmptlut[0] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_RGB_B); cmptlut[1] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_RGB_G); cmptlut[2] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_RGB_R); if (cmptlut[0] < 0 || cmptlut[1] < 0 || cmptlut[0] < 0) { result = false; } ncmpts = 3; } else { cmptlut[0] = jas_image_getcmptbytype(image, JAS_IMAGE_CT_GRAY_Y); if (cmptlut[0] < 0) { result = false; } ncmpts = 1; } if (result) { for (int i = 0; i < ncmpts; i++) { int maxval = 1 << jas_image_cmptprec(image, cmptlut[i]); int offset = jas_image_cmptsgnd(image, cmptlut[i]) ? maxval / 2 : 0; int yend = jas_image_cmptbry(image, cmptlut[i]); int ystep = jas_image_cmptvstep(image, cmptlut[i]); int xend = jas_image_cmptbrx(image, cmptlut[i]); int xstep = jas_image_cmpthstep(image, cmptlut[i]); jas_matrix_t* buffer = jas_matrix_create(yend / ystep, xend / xstep); if (buffer) { if (!jas_image_readcmpt(image, cmptlut[i], 0, 0, xend / xstep, yend / ystep, buffer)) { if (img.depth() == CV_8U) { result = readComponent8u(data + i, buffer, step, cmptlut[i], maxval, offset, ncmpts); } else { result = readComponent16u(((unsigned short*)data) + i, buffer, step / 2, cmptlut[i], maxval, offset, ncmpts); } if (!result) { i = ncmpts; result = false; } } jas_matrix_destroy(buffer); } } } } else { fprintf(stderr, "JPEG2000 LOADER ERROR: colorspace conversion failed\n"); } } close(); return result; }
bool GrFmtJpeg2000Reader::ReadData( uchar* data, int step, int color ) { bool result = false; color = color > 0 || ( m_iscolor && color < 0 ); if( m_stream && m_image ) { bool convert; int colorspace; if( color ) { convert = (jas_image_clrspc( m_image ) != JAS_CLRSPC_SRGB); colorspace = JAS_CLRSPC_SRGB; } else { convert = (jas_clrspc_fam( jas_image_clrspc( m_image ) ) != JAS_CLRSPC_FAM_GRAY); colorspace = JAS_CLRSPC_SGRAY; // TODO GENGRAY or SGRAY? } // convert to the desired colorspace if( convert ) { jas_cmprof_t *clrprof = jas_cmprof_createfromclrspc( colorspace ); if( clrprof ) { jas_image_t *img = jas_image_chclrspc( m_image, clrprof, JAS_CMXFORM_INTENT_RELCLR ); if( img ) { jas_image_destroy( m_image ); m_image = img; result = true; } else fprintf(stderr, "JPEG 2000 LOADER ERROR: cannot convert colorspace\n"); jas_cmprof_destroy( clrprof ); } else fprintf(stderr, "JPEG 2000 LOADER ERROR: unable to create colorspace\n"); } else result = true; if( result ) { int ncmpts; int cmptlut[3]; if( color ) { cmptlut[0] = jas_image_getcmptbytype( m_image, JAS_IMAGE_CT_RGB_B ); cmptlut[1] = jas_image_getcmptbytype( m_image, JAS_IMAGE_CT_RGB_G ); cmptlut[2] = jas_image_getcmptbytype( m_image, JAS_IMAGE_CT_RGB_R ); if( cmptlut[0] < 0 || cmptlut[1] < 0 || cmptlut[0] < 0 ) result = false; ncmpts = 3; } else { cmptlut[0] = jas_image_getcmptbytype( m_image, JAS_IMAGE_CT_GRAY_Y ); if( cmptlut[0] < 0 ) result = false; ncmpts = 1; } if( result ) { for( int i = 0; i < ncmpts; i++ ) { int maxval = 1 << jas_image_cmptprec( m_image, cmptlut[i] ); int offset = jas_image_cmptsgnd( m_image, cmptlut[i] ) ? maxval / 2 : 0; int yend = jas_image_cmptbry( m_image, cmptlut[i] ); int ystep = jas_image_cmptvstep( m_image, cmptlut[i] ); int xend = jas_image_cmptbrx( m_image, cmptlut[i] ); int xstep = jas_image_cmpthstep( m_image, cmptlut[i] ); jas_matrix_t *buffer = jas_matrix_create( yend / ystep, xend / xstep ); if( buffer ) { if( !jas_image_readcmpt( m_image, cmptlut[i], 0, 0, xend / xstep, yend / ystep, buffer )) { if( m_bit_depth == 8 || !m_native_depth ) result = ReadComponent8u( data + i, buffer, step, cmptlut[i], maxval, offset, ncmpts ); else result = ReadComponent16u( ((unsigned short *)data) + i, buffer, step / 2, cmptlut[i], maxval, offset, ncmpts ); if( !result ) { i = ncmpts; result = false; } } jas_matrix_destroy( buffer ); } } } } else fprintf(stderr, "JPEG2000 LOADER ERROR: colorspace conversion failed\n" ); } Close(); return result; }
int main(int argc, char **argv) { char *origpath; char *reconpath; int verbose; char *metricname; int metric; int id; jas_image_t *origimage; jas_image_t *reconimage; jas_matrix_t *origdata; jas_matrix_t *recondata; jas_image_t *diffimage; jas_stream_t *diffstream; int width; int height; int depth; int numcomps; double d; double maxdist; double mindist; int compno; jas_stream_t *origstream; jas_stream_t *reconstream; char *diffpath; int maxonly; int minonly; int fmtid; verbose = 0; origpath = 0; reconpath = 0; metricname = 0; metric = metricid_none; diffpath = 0; maxonly = 0; minonly = 0; if (jas_init()) { errprint(0, "error: cannot initialize jasper library\n"); abort(); } /* set our error callback */ jas_set_error_cb(errprint); cmdname = argv[0]; /* Parse the command line options. */ while ((id = jas_getopt(argc, argv, opts)) >= 0) { switch (id) { case OPT_MAXONLY: maxonly = 1; break; case OPT_MINONLY: minonly = 1; break; case OPT_METRIC: metricname = jas_optarg; break; case OPT_ORIG: origpath = jas_optarg; break; case OPT_RECON: reconpath = jas_optarg; break; case OPT_VERBOSE: verbose = 1; break; case OPT_DIFFIMAGE: diffpath = jas_optarg; break; case OPT_VERSION: printf("%s\n", JAS_VERSION); exit(EXIT_SUCCESS); break; case OPT_HELP: default: usage(); break; } } if (verbose) { cmdinfo(); } /* Ensure that files are given for both the original and reconstructed images. */ if (!origpath || !reconpath) { usage(); } /* If a metric was specified, process it. */ if (metricname) { if ((metric = (jas_taginfo_nonull(jas_taginfos_lookup(metrictab, metricname))->id)) < 0) { usage(); } } /* Open the original image file. */ if (!(origstream = jas_stream_fopen(origpath, "rb"))) { jas_eprintf("cannot open %s\n", origpath); return EXIT_FAILURE; } /* Open the reconstructed image file. */ if (!(reconstream = jas_stream_fopen(reconpath, "rb"))) { jas_eprintf("cannot open %s\n", reconpath); return EXIT_FAILURE; } /* Decode the original image. */ if (!(origimage = jas_image_decode(origstream, -1, 0))) { jas_eprintf("cannot load original image\n"); return EXIT_FAILURE; } /* Decoder the reconstructed image. */ if (!(reconimage = jas_image_decode(reconstream, -1, 0))) { jas_eprintf("cannot load reconstructed image\n"); return EXIT_FAILURE; } /* Close the original image file. */ jas_stream_close(origstream); /* Close the reconstructed image file. */ jas_stream_close(reconstream); /* Ensure that both images have the same number of components. */ numcomps = jas_image_numcmpts(origimage); if (jas_image_numcmpts(reconimage) != numcomps) { jas_eprintf("number of components differ\n"); return EXIT_FAILURE; } /* Compute the difference for each component. */ maxdist = 0; mindist = FLT_MAX; for (compno = 0; compno < numcomps; ++compno) { width = jas_image_cmptwidth(origimage, compno); height = jas_image_cmptheight(origimage, compno); depth = jas_image_cmptprec(origimage, compno); if (jas_image_cmptwidth(reconimage, compno) != width || jas_image_cmptheight(reconimage, compno) != height) { jas_eprintf("image dimensions differ\n"); return EXIT_FAILURE; } if (jas_image_cmptprec(reconimage, compno) != depth) { jas_eprintf("precisions differ\n"); return EXIT_FAILURE; } if (!(origdata = jas_matrix_create(height, width))) { jas_eprintf("internal error\n"); return EXIT_FAILURE; } if (!(recondata = jas_matrix_create(height, width))) { jas_eprintf("internal error\n"); return EXIT_FAILURE; } if (jas_image_readcmpt(origimage, compno, 0, 0, width, height, origdata)) { jas_eprintf("cannot read component data\n"); return EXIT_FAILURE; } if (jas_image_readcmpt(reconimage, compno, 0, 0, width, height, recondata)) { jas_eprintf("cannot read component data\n"); return EXIT_FAILURE; } if (diffpath) { if (!(diffstream = jas_stream_fopen(diffpath, "rwb"))) { jas_eprintf("cannot open diff stream\n"); return EXIT_FAILURE; } if (!(diffimage = makediffimage(origdata, recondata))) { jas_eprintf("cannot make diff image\n"); return EXIT_FAILURE; } fmtid = jas_image_strtofmt("pnm"); if (jas_image_encode(diffimage, diffstream, fmtid, 0)) { jas_eprintf("cannot save\n"); return EXIT_FAILURE; } jas_stream_close(diffstream); jas_image_destroy(diffimage); } if (metric != metricid_none) { d = getdistortion(origdata, recondata, depth, metric); if (d > maxdist) { maxdist = d; } if (d < mindist) { mindist = d; } if (!maxonly && !minonly) { if (metric == metricid_pae || metric == metricid_equal) { printf("%ld\n", (long) ceil(d)); } else { printf("%f\n", d); } } } jas_matrix_destroy(origdata); jas_matrix_destroy(recondata); } if (metric != metricid_none && (maxonly || minonly)) { if (maxonly) { d = maxdist; } else if (minonly) { d = mindist; } else { abort(); } if (metric == metricid_pae || metric == metricid_equal) { jas_eprintf("%ld\n", (long) ceil(d)); } else { jas_eprintf("%f\n", d); } } jas_image_destroy(origimage); jas_image_destroy(reconimage); jas_image_clearfmts(); return EXIT_SUCCESS; }
int img_dat_generate(IMG_DAT **oimg_dat, jas_image_t *image) { IMG_DAT *img_dat; int i; int cmptscnt; int rwcnt; int max_hor, max_vrt; /* Allocate memory for image data structure. */ img_dat = (IMG_DAT *)calloc(1, sizeof(IMG_DAT)); if(img_dat == NULL){ fprintf(stderr, "ERROR : img_dat_generate : " "calloc : img_dat (%lu bytes)\n", (unsigned long)sizeof(IMG_DAT)); return(-2); } /* Get component count. */ cmptscnt = jas_image_numcmpts(image); /* Initialize img_dat info */ img_dat->max_width = jas_image_brx(image); img_dat->max_height = jas_image_bry(image); img_dat->ppi = -1; img_dat->intrlv = 0; img_dat->n_cmpnts = cmptscnt; img_dat->cmpnt_depth = jas_image_cmptprec(image, 0); max_hor = -1; max_vrt = -1; img_dat->pix_depth = 0; for(i = 0; i < cmptscnt; i++){ int cdepth; img_dat->hor_sampfctr[i] = 1; img_dat->vrt_sampfctr[i] = 1; cdepth = jas_image_cmptprec(image, i); img_dat->pix_depth += cdepth; if (cdepth != img_dat->cmpnt_depth) { fprintf(stderr, "WARNING : img_dat_generate: " "unequal component depths, 0: %d and %d: %d\n", i, cdepth, jas_image_cmptprec(image, i)); } if(max_hor < img_dat->hor_sampfctr[i]) max_hor = img_dat->hor_sampfctr[i]; if(max_vrt < img_dat->vrt_sampfctr[i]) max_vrt = img_dat->vrt_sampfctr[i]; } for(i = 0; i < img_dat->n_cmpnts; i++){ img_dat->samp_width[i] = (int)ceil(img_dat->max_width * (img_dat->hor_sampfctr[i]/(double)max_hor)); img_dat->samp_height[i] = (int)ceil(img_dat->max_height * (img_dat->vrt_sampfctr[i]/(double)max_vrt)); } /* Put the image raw pixels to image data sturcture component plains. */ cmptscnt = jas_image_numcmpts(image); for (i = 0; i < cmptscnt; i++){ jas_stream_rewind(image->cmpts_[i]->stream_); rwcnt = jas_stream_getrwcount(image->cmpts_[i]->stream_) - 1; img_dat->image[i] = (unsigned char *)malloc(rwcnt * sizeof(unsigned char)); if(img_dat->image[i] == NULL){ fprintf(stderr, "ERROR : get_raw_image: " "calloc : img_dat->image[%d] (%lu bytes)\n", i, (unsigned long)(rwcnt * sizeof(unsigned char))); return(-3); } jas_stream_read(image->cmpts_[i]->stream_, img_dat->image[i], rwcnt); } *oimg_dat = img_dat; return(0); }
static void computeOutputParm(jas_image_t * const jasperP, struct pam * const outpamP, int ** const jasperCmptNoP) { int * jasperCmptNo; /* Malloc'ed array. jaspercmptNo[P] is the component number for use with the Jasper library that corresponds to Plane P of the PAM. */ switch (jas_clrspc_fam(jas_image_clrspc(jasperP))) { case JAS_CLRSPC_FAM_GRAY: outpamP->depth = 1; MALLOCARRAY_NOFAIL(jasperCmptNo, 1); getGrayComponent(&jasperCmptNo[0], jasperP); if (jas_image_cmptprec(jasperP, jasperCmptNo[0]) == 1) { outpamP->format = RPBM_FORMAT; strcpy(outpamP->tuple_type, PAM_PBM_TUPLETYPE); } else { outpamP->format = RPGM_FORMAT; strcpy(outpamP->tuple_type, PAM_PGM_TUPLETYPE); } break; case JAS_CLRSPC_FAM_RGB: outpamP->depth = 3; MALLOCARRAY_NOFAIL(jasperCmptNo, 3); getRgbComponents(jasperCmptNo, jasperP); outpamP->format = RPPM_FORMAT; strcpy(outpamP->tuple_type, PAM_PPM_TUPLETYPE); break; default: outpamP->format = PAM_FORMAT; outpamP->depth = jas_image_numcmpts(jasperP); { unsigned int plane; MALLOCARRAY_NOFAIL(jasperCmptNo, outpamP->depth); for (plane = 0; plane < outpamP->depth; ++plane) jasperCmptNo[plane] = plane; } strcpy(outpamP->tuple_type, ""); if (jas_image_cmptsgnd(jasperP, 0)) pm_message("Warning: Input image has signed sample values. " "They will be represented in the PAM output in " "two's complement."); } outpamP->plainformat = FALSE; outpamP->width = jas_image_cmptwidth(jasperP, 0); outpamP->height = jas_image_cmptheight(jasperP, 0); validateComponentsAlike(jasperP); { unsigned int const maxPrecision = maxJasperComponentPrecision(jasperP); outpamP->maxval = pm_bitstomaxval(maxPrecision); outpamP->bytes_per_sample = (maxPrecision + 7)/8; } *jasperCmptNoP = jasperCmptNo; }
int JPEG2000Dataset::DecodeImage() { if (bAlreadyDecoded) return psImage != NULL; bAlreadyDecoded = TRUE; if ( !( psImage = jas_image_decode(psStream, iFormat, 0) ) ) { CPLDebug( "JPEG2000", "Unable to decode image. Format: %s, %d", jas_image_fmttostr( iFormat ), iFormat ); return FALSE; } /* Case of a JP2 image : check that the properties given by */ /* the JP2 boxes match the ones of the code stream */ if (nBands != 0) { if (nBands != jas_image_numcmpts( psImage )) { CPLError(CE_Failure, CPLE_AppDefined, "The number of components indicated in the IHDR box (%d) mismatch " "the value specified in the code stream (%d)", nBands, jas_image_numcmpts( psImage )); jas_image_destroy( psImage ); psImage = NULL; return FALSE; } if (nRasterXSize != jas_image_cmptwidth( psImage, 0 ) || nRasterYSize != jas_image_cmptheight( psImage, 0 ) ) { CPLError(CE_Failure, CPLE_AppDefined, "The dimensions indicated in the IHDR box (%d x %d) mismatch " "the value specified in the code stream (%d x %d)", nRasterXSize, nRasterYSize, jas_image_cmptwidth( psImage, 0 ), jas_image_cmptheight( psImage, 0 )); jas_image_destroy( psImage ); psImage = NULL; return FALSE; } int iBand; for ( iBand = 0; iBand < nBands; iBand++ ) { JPEG2000RasterBand* poBand = (JPEG2000RasterBand*) GetRasterBand(iBand+1); if (poBand->iDepth != jas_image_cmptprec( psImage, iBand ) || poBand->bSignedness != jas_image_cmptsgnd( psImage, iBand )) { CPLError(CE_Failure, CPLE_AppDefined, "The bit depth of band %d indicated in the IHDR box (%d) mismatch " "the value specified in the code stream (%d)", iBand + 1, poBand->iDepth, jas_image_cmptprec( psImage, iBand )); jas_image_destroy( psImage ); psImage = NULL; return FALSE; } } } /* Ask for YCbCr -> RGB translation */ if ( jas_clrspc_fam( jas_image_clrspc( psImage ) ) == JAS_CLRSPC_FAM_YCBCR ) { jas_image_t *psRGBImage; jas_cmprof_t *psRGBProf; CPLDebug( "JPEG2000", "forcing conversion to sRGB"); if (!(psRGBProf = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB))) { CPLDebug( "JPEG2000", "cannot create sRGB profile"); return TRUE; } if (!(psRGBImage = jas_image_chclrspc(psImage, psRGBProf, JAS_CMXFORM_INTENT_PER))) { CPLDebug( "JPEG2000", "cannot convert to sRGB"); jas_cmprof_destroy(psRGBProf); return TRUE; } jas_image_destroy(psImage); jas_cmprof_destroy(psRGBProf); psImage = psRGBImage; } return TRUE; }
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)); }