/* Write a marker segment to a stream. */ int jpc_putms(jas_stream_t *out, jpc_cstate_t *cstate, jpc_ms_t *ms) { jas_stream_t *tmpstream; int len; /* Output the marker segment type. */ if (jpc_putuint16(out, ms->id)) { return -1; } /* Output the marker segment length and parameters if necessary. */ if (ms->ops->putparms) { /* Create a temporary stream in which to buffer the parameter data. */ if (!(tmpstream = jas_stream_memopen(0, 0))) { return -1; } if ((*ms->ops->putparms)(ms, cstate, tmpstream)) { jas_stream_close(tmpstream); return -1; } /* Get the number of bytes of parameter data written. */ if ((len = jas_stream_tell(tmpstream)) < 0) { jas_stream_close(tmpstream); return -1; } ms->len = len; /* Write the marker segment length and parameter data to the output stream. */ if (jas_stream_seek(tmpstream, 0, SEEK_SET) < 0 || jpc_putuint16(out, (uint_fast16_t)(ms->len + 2)) || jas_stream_copy(out, tmpstream, ms->len) < 0) { jas_stream_close(tmpstream); return -1; } /* Close the temporary stream. */ jas_stream_close(tmpstream); } /* This is a bit of a hack, but I'm not going to define another type of virtual function for this one special case. */ if (ms->id == JPC_MS_SIZ) { cstate->numcomps = ms->parms.siz.numcomps; } /* if (jas_getdbglevel() > 0) { jpc_ms_dump(ms, stderr); } */ return 0; }
void fz_dropjpxd(fz_filter *filter) { fz_jpxd *d = (fz_jpxd*)filter; if (d->stream) jas_stream_close(d->stream); if (d->image) jas_image_destroy(d->image); }
//! This is separated so that it can be called for other file types, such as .icns. ILboolean ilLoadLInternal_JP2(const void *Lump, ILuint Size, ILimage *Image) { ILboolean bRet; jas_stream_t *Stream; if (!JasperInit) { if (jas_init()) { ilSetError(IL_LIB_JP2_ERROR); return IL_FALSE; } JasperInit = IL_TRUE; } Stream = jas_stream_memopen((char*)Lump, Size); if (!Stream) { ilSetError(IL_COULD_NOT_OPEN_FILE); return IL_FALSE; } bRet = iLoadJp2Internal(Stream, Image); // Close the input stream. jas_stream_close(Stream); return bRet; }
int is_jp2(unsigned char *idata, const int ilen) { jas_stream_t *in; int ret; if (jas_init()){ fprintf(stderr, "ERROR : is_jp2: init : jas\n"); return(-1); } /* The input image is to be read from buffer stream. */ in = jas_stream_memopen((char *)idata, ilen); if (in == NULL){ fprintf(stderr, "ERROR : is_jp2: failed to open jas stream\n"); return(-2); } /* Check is JP2 format. */ ret = jas_image_getfmt(in); /* General clean up. */ (void) jas_stream_close(in); return(ret); }
void imFileFormatJP2::Close() { if (this->image) jas_image_destroy(this->image); jas_stream_close(this->stream); }
static void readJpc(const char * const inputFilename, jas_image_t ** const jasperPP) { jas_image_t * jasperP; jas_stream_t *instream; const char * options; if ( strcmp(inputFilename, "-") == 0) { /* The input image is to be read from standard input. */ instream = jas_stream_fdopen(fileno(stdin), "rb"); if (instream == NULL) pm_error("error: cannot reopen standard input"); } else { instream = jas_stream_fopen(inputFilename, "rb"); if (instream == NULL ) pm_error("cannot open input image file '%s'", inputFilename); } if (jas_image_getfmt(instream) != jas_image_strtofmt((char*)"jpc")) pm_error("Input is not JPEG-2000 code stream"); options = ""; jasperP = jas_image_decode(instream, jas_image_strtofmt((char*)"jpc"), (char*)options); if (jasperP == NULL) pm_error("Unable to interpret JPEG-2000 input. " "The Jasper library jas_image_decode() subroutine failed."); jas_stream_close(instream); *jasperPP = jasperP; }
//! Reads an already-opened Jpeg2000 file. ILboolean ilLoadJp2F(ILHANDLE File) { ILuint FirstPos; ILboolean bRet; jas_stream_t *Stream; iSetInputFile(File); FirstPos = itell(); if (jas_init()) { ilSetError(IL_LIB_JP2_ERROR); return IL_FALSE; } Stream = iJp2ReadStream(); if (!Stream) { ilSetError(IL_COULD_NOT_OPEN_FILE); return IL_FALSE; } bRet = iLoadJp2Internal(Stream, NULL); // Close the input stream. jas_stream_close(Stream); iseek(FirstPos, IL_SEEK_SET); return bRet; }
//! Reads a Jpeg2000 file. ILboolean ilLoadJp2(ILconst_string FileName) { // ILHANDLE Jp2File; ILboolean bRet = IL_FALSE; jas_stream_t *Stream; /*Jp2File = iopenr(FileName); if (Jp2File == NULL) { ilSetError(IL_COULD_NOT_OPEN_FILE); return bJp2; } bJp2 = iLoadJp2Internal(); icloser(Jp2File);*/ if (jas_init()) { ilSetError(IL_LIB_JP2_ERROR); return IL_FALSE; } Stream = jas_stream_fopen(FileName, "rb"); if (!Stream) { ilSetError(IL_COULD_NOT_OPEN_FILE); return IL_FALSE; } bRet = iLoadJp2Internal(Stream, NULL); // Close the input stream. jas_stream_close(Stream); return bRet; }
ICCProfile JP2Instance::ReadICCProfile() { CheckOpenStream( !m_path.IsEmpty() && s_jasperInitialized, "ReadICCProfile" ); if ( jas_image_cmprof( m_jp2Image ) == nullptr ) return ICCProfile(); jas_stream_t* iccStream = nullptr; try { // Create a growable memory stream for output iccStream = jas_stream_memopen( 0, 0 ); if ( iccStream == nullptr ) JP2KERROR( "Extracting ICC profile from JPEG2000 image: Unable to create JasPer stream" ); if ( jas_iccprof_save( jas_image_cmprof( m_jp2Image )->iccprof, iccStream ) < 0 ) JP2KERROR( "Extracting ICC profile from JPEG2000 image: Error saving profile to JasPer stream" ); long iccSize = jas_stream_tell( iccStream ); if ( iccSize <= 0 ) JP2KERROR( "Extracting ICC profile from JPEG2000 image: Invalid JasPer stream position" ); ByteArray iccData( iccSize ); jas_stream_rewind( iccStream ); if ( jas_stream_read( iccStream, iccData.Begin(), iccSize ) != iccSize ) JP2KERROR( "Extracting ICC profile from JPEG2000 image: Error reading JasPer stream" ); jas_stream_close( iccStream ), iccStream = nullptr; ICCProfile icc( iccData ); if ( icc.IsProfile() ) Console().WriteLn( "<end><cbr>ICC profile extracted: \'" + icc.Description() + "\', " + String( icc.ProfileSize() ) + " bytes." ); return icc; } catch ( ... ) { if ( iccStream != nullptr ) jas_stream_close( iccStream ); Close(); throw; } }
int main(int argc, char **argv) { int fmtid = 0; jas_image_fmtops_t fmtops; fmtops.decode = jp2_decode; fmtops.encode = NULL; fmtops.validate = jp2_validate; jas_image_addfmt(fmtid, "jp2", "jp2", "JPEG-2000 JP2 File Format Syntax (ISO/IEC 15444-1)", &fmtops); ++fmtid; fmtops.decode = NULL; fmtops.encode = bmp_encode; fmtops.validate = NULL; jas_image_addfmt(fmtid, "bmp", "bmp", "Microsoft Bitmap (BMP)", &fmtops); ++fmtid; jas_stream_t *in = jas_stream_fdopen(STDIN_FILENO, "rb"); assert(in != NULL); jas_stream_t *out = jas_stream_fdopen(STDOUT_FILENO, "w+b"); assert(out != NULL); jas_image_t *image = jas_image_decode(in, 0, NULL); assert(image != NULL); int rc = jas_image_encode(image, out, 1, NULL); assert(rc == 0); jas_stream_flush(out); jas_stream_close(in); jas_stream_close(out); jas_image_destroy(image); return 0; }
void GrFmtJpeg2000Reader::Close() { if( m_stream ) { jas_stream_close( m_stream ); m_stream = 0; } if( m_image ) { jas_image_destroy( m_image ); m_image = 0; } GrFmtReader::Close(); }
JPEG2000Dataset::~JPEG2000Dataset() { FlushCache(); if ( psStream ) jas_stream_close( psStream ); if ( psImage ) jas_image_destroy( psImage ); if ( pszProjection ) CPLFree( pszProjection ); if( nGCPCount > 0 ) { GDALDeinitGCPs( nGCPCount, pasGCPList ); CPLFree( pasGCPList ); } }
bool jasperConvert(jas_image_t* &image, jas_stream_t* &out, const char* data, unsigned size, int outfmt, const char* outopts) { jas_stream_t *in; // kDebug(YAHOO_RAW_DEBUG) << "Got data - size=" << size; if(!(in = jas_stream_memopen(const_cast<char*>(data), size))) { kDebug(YAHOO_RAW_DEBUG) << "Could not open jasper input stream"; return false; } int infmt; infmt = jas_image_getfmt(in); if (infmt < 0) { jas_stream_close(in); kDebug(YAHOO_RAW_DEBUG) << "Failed to recognize input webcam image format"; return false; } if (!(image = jas_image_decode(in, infmt, 0))) { kDebug(YAHOO_RAW_DEBUG) << "Unable to decode image"; jas_stream_close(in); return false; } /* kDebug(YAHOO_RAW_DEBUG) << "jasper: decoded image: " << jas_image_width(image) << "x" << jas_image_height(image) << " bytes: " << jas_image_rawsize(image) << " components:" << jas_image_numcmpts(image); */ char* out_img = NULL; if(!(out = jas_stream_memopen(out_img, 0))) { kDebug(YAHOO_RAW_DEBUG) << "Could not open output stream"; jas_stream_close(in); return false; } if (jas_image_encode(image, out, outfmt, const_cast<char*>(outopts))) { kDebug(YAHOO_RAW_DEBUG) << "Unable to convert image"; jas_stream_close(in); jas_stream_close(out); jas_image_destroy(image); return false; } jas_stream_flush(out); jas_stream_close(in); return true; }
int imFileFormatJP2::Open(const char* file_name) { this->stream = jas_binfile_open(file_name, 0); if (this->stream == NULL) return IM_ERR_OPEN; this->fmtid = jas_image_getfmt(this->stream); if (this->fmtid < 0) { jas_stream_close(this->stream); return IM_ERR_FORMAT; } strcpy(this->compression, "JPEG-2000"); this->image_count = 1; return IM_ERR_NONE; }
int jpeg2k_decode_mem(IMG_DAT **oimg_dat, int *lossyflag, unsigned char *idata, const int ilen) { IMG_DAT *img_dat; jas_image_t *image; jas_stream_t *in; if (jas_init() != 0){ fprintf(stderr, "ERROR : jpeg2k_decode_mem: init : jas\n"); return(-1); } /* The input image is to be read from buffer stream. */ if ((in = jas_stream_memopen((char *)idata, ilen)) == NULL){ fprintf(stderr, "ERROR : jpeg2k_decode_mem: failed to open jas stream\n"); return(-2); } /* Get the input image data. */ if ((image = jas_image_decode(in, -1, (char *)NULL)) == NULL){ fprintf(stderr, "error: cannot load image data\n"); return(-3); } /* Early cleanup--input stream no longer needed. */ (void) jas_stream_close(in); /* Gerenate Image data sturcture. */ if ((img_dat_generate(&img_dat, image)) != 0){ jas_image_destroy(image); fprintf(stderr, "ERROR : jpeg2k_decode_mem: failed to generate img_dat\n"); return(-5); } /* General clean up. */ jas_image_destroy(image); *oimg_dat = img_dat; *lossyflag = 0; return(0); }
bool WebcamImgFormat::forYahoo(QByteArray& result, const QImage* src) { if (!initOk) return false; QByteArray ba; QBuffer buffer(&ba); buffer.open(QIODevice::WriteOnly); if (!src) return false; if (!src->save(&buffer, forYahooFmtQt, 100)) { kDebug(YAHOO_RAW_DEBUG) << "Failed to write intermediary " << forYahooFmtQt << " image"; return false; } jas_image_t* image = NULL; jas_stream_t* out = NULL; /* Note: need to pass the floating number in the current locale so that it can be parsed back. And since somehow I got my dev env with a non-english locale, it took some time to figure that this was the problem :-( */ /* The 'rate' parameter: tested and worked also with rate = 0.0265. In the future - make that a property of this object and change it from some GUI. */ bool r = jasperConvert(image, out, ba.constData(), ba.size(), jpcFmtID, QString("cblkwidth=64 cblkheight=64 numrlvls=4 rate=%L1 prcheight=128 prcwidth=2048 mode=real").arg(0.0165).toAscii().constData()); if (!r) return false; unsigned size = ((jas_stream_memobj_t *)out->obj_)->bufsize_; const char *buf = (const char*)(((jas_stream_memobj_t *)out->obj_)->buf_); result = QByteArray(buf, size); if (out) jas_stream_close(out); if (image) jas_image_destroy(image); return r; }
bool WebcamImgFormat::fromYahoo(QPixmap& pixmap, const char* data, unsigned size) { if (!initOk) return false; jas_image_t* image = NULL; jas_stream_t* out = NULL; bool r = jasperConvert(image, out, data, size, fromYahooFmtID, 0); if (!r) return false; size = ((jas_stream_memobj_t *)out->obj_)->bufsize_; const unsigned char *buf = static_cast<const unsigned char*>(((jas_stream_memobj_t *)out->obj_)->buf_); r = pixmap.loadFromData(buf, size); if (out) jas_stream_close(out); if (image) jas_image_destroy(image); return r; }
void JPCInstance::Close() { if ( m_jp2Stream != nullptr ) jas_stream_close( m_jp2Stream ), m_jp2Stream = nullptr; if ( m_jp2Image != nullptr ) { jas_image_setcmprof( m_jp2Image, nullptr ); // don't destroy embedded profile now jas_image_destroy( m_jp2Image ), m_jp2Image = nullptr; } if ( m_jp2CMProfile != nullptr ) jas_cmprof_destroy( m_jp2CMProfile ), m_jp2CMProfile = nullptr; CleanupJasPer(); m_path.Clear(); m_options.Reset(); m_jp2Options = JPCFormat::DefaultOptions(); m_queriedOptions = false; }
jas_stream_t *jas_stream_memopen(char *buf, int bufsize) { jas_stream_t *stream; jas_stream_memobj_t *obj; if (!(stream = jas_stream_create())) { return 0; } /* A stream associated with a memory buffer is always opened for both reading and writing in binary mode. */ stream->openmode_ = JAS_STREAM_READ | JAS_STREAM_WRITE | JAS_STREAM_BINARY; /* Since the stream data is already resident in memory, buffering is not necessary. */ /* But... It still may be faster to use buffering anyways. */ jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0); /* Select the operations for a memory stream. */ stream->ops_ = &jas_stream_memops; /* Allocate memory for the underlying memory stream object. */ if (!(obj = jas_malloc(sizeof(jas_stream_memobj_t)))) { jas_stream_destroy(stream); return 0; } stream->obj_ = (void *) obj; /* Initialize a few important members of the memory stream object. */ obj->myalloc_ = 0; obj->buf_ = 0; /* If the buffer size specified is nonpositive, then the buffer is allocated internally and automatically grown as needed. */ if (bufsize <= 0) { obj->bufsize_ = 1024; obj->growable_ = 1; } else { obj->bufsize_ = bufsize; obj->growable_ = 0; } if (buf) { obj->buf_ = (unsigned char *) buf; } else { obj->buf_ = jas_malloc(obj->bufsize_ * sizeof(char)); obj->myalloc_ = 1; } if (!obj->buf_) { jas_stream_close(stream); return 0; } if (bufsize > 0 && buf) { /* If a buffer was supplied by the caller and its length is positive, make the associated buffer data appear in the stream initially. */ obj->len_ = bufsize; } else { /* The stream is initially empty. */ obj->len_ = 0; } obj->pos_ = 0; return stream; }
int jp2_write_header(jas_image_t *image, jas_stream_t *out) { jp2_box_t *box; jp2_ftyp_t *ftyp; jp2_ihdr_t *ihdr; jas_stream_t *tmpstream; int allcmptssame; jp2_bpcc_t *bpcc; long len; uint_fast16_t cmptno; jp2_colr_t *colr; jp2_cdefchan_t *cdefchanent; jp2_cdef_t *cdef; int i; uint_fast32_t typeasoc; jas_iccprof_t *iccprof; jas_stream_t *iccstream; int pos; int needcdef; int prec; int sgnd; box = 0; tmpstream = 0; allcmptssame = 1; sgnd = jas_image_cmptsgnd(image, 0); prec = jas_image_cmptprec(image, 0); for (i = 1; i < jas_image_numcmpts(image); ++i) { if (jas_image_cmptsgnd(image, i) != sgnd || jas_image_cmptprec(image, i) != prec) { allcmptssame = 0; break; } } /* Output the signature box. */ if (!(box = jp2_box_create(JP2_BOX_JP))) { goto error; } box->data.jp.magic = JP2_JP_MAGIC; if (jp2_box_put(box, out)) { goto error; } jp2_box_destroy(box); box = 0; /* Output the file type box. */ if (!(box = jp2_box_create(JP2_BOX_FTYP))) { goto error; } ftyp = &box->data.ftyp; ftyp->majver = JP2_FTYP_MAJVER; ftyp->minver = JP2_FTYP_MINVER; ftyp->numcompatcodes = 1; ftyp->compatcodes[0] = JP2_FTYP_COMPATCODE; if (jp2_box_put(box, out)) { goto error; } jp2_box_destroy(box); box = 0; /* * Generate the data portion of the JP2 header box. * We cannot simply output the header for this box * since we do not yet know the correct value for the length * field. */ if (!(tmpstream = jas_stream_memopen(0, 0))) { goto error; } /* Generate image header box. */ if (!(box = jp2_box_create(JP2_BOX_IHDR))) { goto error; } ihdr = &box->data.ihdr; ihdr->width = jas_image_width(image); ihdr->height = jas_image_height(image); ihdr->numcmpts = jas_image_numcmpts(image); ihdr->bpc = allcmptssame ? JP2_SPTOBPC(jas_image_cmptsgnd(image, 0), jas_image_cmptprec(image, 0)) : JP2_IHDR_BPCNULL; ihdr->comptype = JP2_IHDR_COMPTYPE; ihdr->csunk = 0; ihdr->ipr = 0; if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; /* Generate bits per component box. */ if (!allcmptssame) { if (!(box = jp2_box_create(JP2_BOX_BPCC))) { goto error; } bpcc = &box->data.bpcc; bpcc->numcmpts = jas_image_numcmpts(image); if (!(bpcc->bpcs = jas_malloc(bpcc->numcmpts * sizeof(uint_fast8_t)))) { goto error; } for (cmptno = 0; cmptno < bpcc->numcmpts; ++cmptno) { bpcc->bpcs[cmptno] = JP2_SPTOBPC(jas_image_cmptsgnd(image, cmptno), jas_image_cmptprec(image, cmptno)); } if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; } /* Generate color specification box. */ if (!(box = jp2_box_create(JP2_BOX_COLR))) { goto error; } colr = &box->data.colr; switch (jas_image_clrspc(image)) { case JAS_CLRSPC_SRGB: case JAS_CLRSPC_SYCBCR: case JAS_CLRSPC_SGRAY: colr->method = JP2_COLR_ENUM; colr->csid = clrspctojp2(jas_image_clrspc(image)); colr->pri = JP2_COLR_PRI; colr->approx = 0; break; default: colr->method = JP2_COLR_ICC; colr->pri = JP2_COLR_PRI; colr->approx = 0; iccprof = jas_iccprof_createfromcmprof(jas_image_cmprof(image)); assert(iccprof); iccstream = jas_stream_memopen(0, 0); assert(iccstream); if (jas_iccprof_save(iccprof, iccstream)) abort(); if ((pos = jas_stream_tell(iccstream)) < 0) abort(); colr->iccplen = pos; colr->iccp = jas_malloc(pos); assert(colr->iccp); jas_stream_rewind(iccstream); if (jas_stream_read(iccstream, colr->iccp, colr->iccplen) != colr->iccplen) abort(); jas_stream_close(iccstream); jas_iccprof_destroy(iccprof); break; } if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; needcdef = 1; switch (jas_clrspc_fam(jas_image_clrspc(image))) { case JAS_CLRSPC_FAM_RGB: if (jas_image_cmpttype(image, 0) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R) && jas_image_cmpttype(image, 1) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G) && jas_image_cmpttype(image, 2) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B)) needcdef = 0; break; case JAS_CLRSPC_FAM_YCBCR: if (jas_image_cmpttype(image, 0) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_Y) && jas_image_cmpttype(image, 1) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CB) && jas_image_cmpttype(image, 2) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CR)) needcdef = 0; break; case JAS_CLRSPC_FAM_GRAY: if (jas_image_cmpttype(image, 0) == JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y)) needcdef = 0; break; default: abort(); break; } if (needcdef) { if (!(box = jp2_box_create(JP2_BOX_CDEF))) { goto error; } cdef = &box->data.cdef; cdef->numchans = jas_image_numcmpts(image); cdef->ents = jas_malloc(cdef->numchans * sizeof(jp2_cdefchan_t)); for (i = 0; i < jas_image_numcmpts(image); ++i) { cdefchanent = &cdef->ents[i]; cdefchanent->channo = i; typeasoc = jp2_gettypeasoc(jas_image_clrspc(image), jas_image_cmpttype(image, i)); cdefchanent->type = typeasoc >> 16; cdefchanent->assoc = typeasoc & 0x7fff; } if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; } /* Determine the total length of the JP2 header box. */ len = jas_stream_tell(tmpstream); jas_stream_rewind(tmpstream); /* * Output the JP2 header box and all of the boxes which it contains. */ if (!(box = jp2_box_create(JP2_BOX_JP2H))) { goto error; } box->len = len + JP2_BOX_HDRLEN; if (jp2_box_put(box, out)) { goto error; } jp2_box_destroy(box); box = 0; if (jas_stream_copy(out, tmpstream, len)) { goto error; } jas_stream_close(tmpstream); tmpstream = 0; return 0; abort(); error: if (box) { jp2_box_destroy(box); } if (tmpstream) { jas_stream_close(tmpstream); } return -1; }
int enc_jpeg2000(unsigned char *cin,g2int width,g2int height,g2int nbits, g2int ltype, g2int ratio, g2int retry, char *outjpc, g2int jpclen) /*$$$ SUBPROGRAM DOCUMENTATION BLOCK * . . . . * SUBPROGRAM: enc_jpeg2000 Encodes JPEG2000 code stream * PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-12-02 * * ABSTRACT: This Function encodes a grayscale image into a JPEG2000 code stream * specified in the JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) * using JasPer Software version 1.500.4 (or 1.700.2 ) written by the * University of British Columbia, Image Power Inc, and others. * JasPer is available at http://www.ece.uvic.ca/~mdadams/jasper/. * * PROGRAM HISTORY LOG: * 2002-12-02 Gilbert * 2004-12-16 Gilbert - Added retry argument/option to allow option of * increasing the maximum number of guard bits to the * JPEG2000 algorithm. * * USAGE: int enc_jpeg2000(unsigned char *cin,g2int width,g2int height, * g2int nbits, g2int ltype, g2int ratio, * g2int retry, char *outjpc, g2int jpclen) * * INPUT ARGUMENTS: * cin - Packed matrix of Grayscale image values to encode. * width - width of image * height - height of image * nbits - depth (in bits) of image. i.e number of bits * used to hold each data value * ltype - indicator of lossless or lossy compression * = 1, for lossy compression * != 1, for lossless compression * ratio - target compression ratio. (ratio:1) * Used only when ltype == 1. * retry - Pointer to option type. * 1 = try increasing number of guard bits * otherwise, no additional options * jpclen - Number of bytes allocated for new JPEG2000 code stream in * outjpc. * * INPUT ARGUMENTS: * outjpc - Output encoded JPEG2000 code stream * * RETURN VALUES : * > 0 = Length in bytes of encoded JPEG2000 code stream * -3 = Error decode jpeg2000 code stream. * -5 = decoded image had multiple color components. * Only grayscale is expected. * * REMARKS: * * Requires JasPer Software version 1.500.4 or 1.700.2 * * ATTRIBUTES: * LANGUAGE: C * MACHINE: IBM SP * *$$$*/ { int ier,rwcnt; jas_image_t image; jas_stream_t *jpcstream,*istream; jas_image_cmpt_t cmpt,*pcmpt; #define MAXOPTSSIZE 1024 char opts[MAXOPTSSIZE]; /* printf(" enc_jpeg2000:width %ld\n",width); printf(" enc_jpeg2000:height %ld\n",height); printf(" enc_jpeg2000:nbits %ld\n",nbits); printf(" enc_jpeg2000:jpclen %ld\n",jpclen); */ // jas_init(); // // Set lossy compression options, if requested. // if ( ltype != 1 ) { opts[0]=(char)0; } else { #ifdef _SAGA_MSW sprintf(opts,"mode=real\nrate=%f",1.0/(float)ratio); #else snprintf(opts,MAXOPTSSIZE,"mode=real\nrate=%f",1.0/(float)ratio); #endif // _SAGA_MSW } if ( retry == 1 ) { // option to increase number of guard bits strcat(opts,"\nnumgbits=4"); } //printf("SAGopts: %s\n",opts); // // Initialize the JasPer image structure describing the grayscale // image to encode into the JPEG2000 code stream. // image.tlx_=0; image.tly_=0; #ifdef JAS_1_500_4 image.brx_=(uint_fast32_t)width; image.bry_=(uint_fast32_t)height; #endif #ifdef JAS_1_700_2 image.brx_=(jas_image_coord_t)width; image.bry_=(jas_image_coord_t)height; #endif image.numcmpts_=1; image.maxcmpts_=1; #ifdef JAS_1_500_4 image.colormodel_=JAS_IMAGE_CM_GRAY; /* grayscale Image */ #endif #ifdef JAS_1_700_2 image.clrspc_=JAS_CLRSPC_SGRAY; /* grayscale Image */ image.cmprof_=0; #endif image.inmem_=1; cmpt.tlx_=0; cmpt.tly_=0; cmpt.hstep_=1; cmpt.vstep_=1; #ifdef JAS_1_500_4 cmpt.width_=(uint_fast32_t)width; cmpt.height_=(uint_fast32_t)height; #endif #ifdef JAS_1_700_2 cmpt.width_=(jas_image_coord_t)width; cmpt.height_=(jas_image_coord_t)height; cmpt.type_=JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y); #endif cmpt.prec_=nbits; cmpt.sgnd_=0; cmpt.cps_=(nbits+7)/8; pcmpt=&cmpt; image.cmpts_=&pcmpt; // // Open a JasPer stream containing the input grayscale values // istream=jas_stream_memopen((char *)cin,height*width*cmpt.cps_); cmpt.stream_=istream; // // Open an output stream that will contain the encoded jpeg2000 // code stream. // jpcstream=jas_stream_memopen(outjpc,(int)jpclen); // // Encode image. // ier=jpc_encode(&image,jpcstream,opts); if ( ier != 0 ) { printf(" jpc_encode return = %d \n",ier); return -3; } // // Clean up JasPer work structures. // rwcnt=jpcstream->rwcnt_; ier=jas_stream_close(istream); ier=jas_stream_close(jpcstream); // // Return size of jpeg2000 code stream // return (rwcnt); }
int main(int argc, char **argv) { jas_image_t *image; cmdopts_t *cmdopts; jas_stream_t *in; jas_stream_t *out; clock_t startclk; clock_t endclk; long dectime; long enctime; int_fast16_t numcmpts; int i; /* Determine the base name of this command. */ if ((cmdname = strrchr(argv[0], '/'))) { ++cmdname; } else { cmdname = argv[0]; } if (jas_init()) { errprint(0, "error: cannot initialize jasper library\n"); abort(); } /* set our error callback */ jas_set_error_cb(errprint); /* Parse the command line options. */ if (!(cmdopts = cmdopts_parse(argc, argv))) { jas_eprintf("error: cannot parse command line\n"); exit(EXIT_FAILURE); } if (cmdopts->version) { jas_eprintf("%s\n", JAS_VERSION); jas_eprintf("libjasper %s\n", jas_getversion()); exit(EXIT_SUCCESS); } jas_setdbglevel(cmdopts->debug); if (cmdopts->verbose) { cmdinfo(); } /* Open the input image file. */ if (cmdopts->infile) { /* The input image is to be read from a file. */ if (!(in = jas_stream_fopen(cmdopts->infile, "rb"))) { jas_eprintf("error: cannot open input image file %s\n", cmdopts->infile); exit(EXIT_FAILURE); } } else { /* The input image is to be read from standard input. */ if (!(in = jas_stream_fdopen(0, "rb"))) { jas_eprintf("error: cannot open standard input\n"); exit(EXIT_FAILURE); } } /* Open the output image file. */ if (cmdopts->outfile) { /* The output image is to be written to a file. */ if (!(out = jas_stream_fopen(cmdopts->outfile, "w+b"))) { jas_eprintf("error: cannot open output image file %s\n", cmdopts->outfile); exit(EXIT_FAILURE); } } else { /* The output image is to be written to standard output. */ if (!(out = jas_stream_fdopen(1, "w+b"))) { jas_eprintf("error: cannot open standard output\n"); exit(EXIT_FAILURE); } } if (cmdopts->infmt < 0) { if ((cmdopts->infmt = jas_image_getfmt(in)) < 0) { jas_eprintf("error: input image has unknown format\n"); exit(EXIT_FAILURE); } } /* Get the input image data. */ startclk = clock(); if (!(image = jas_image_decode(in, cmdopts->infmt, cmdopts->inopts))) { jas_eprintf("error: cannot load image data\n"); exit(EXIT_FAILURE); } endclk = clock(); dectime = endclk - startclk; /* If requested, throw away all of the components except one. Why might this be desirable? It is a hack, really. None of the image formats other than the JPEG-2000 ones support images with two, four, five, or more components. This hack allows such images to be decoded with the non-JPEG-2000 decoders, one component at a time. */ numcmpts = jas_image_numcmpts(image); if (cmdopts->cmptno >= 0 && cmdopts->cmptno < numcmpts) { for (i = numcmpts - 1; i >= 0; --i) { if (i != cmdopts->cmptno) { jas_image_delcmpt(image, i); } } } if (cmdopts->srgb) { jas_image_t *newimage; jas_cmprof_t *outprof; jas_eprintf("forcing conversion to sRGB\n"); if (!(outprof = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB))) { jas_eprintf("cannot create sRGB profile\n"); exit(EXIT_FAILURE); } if (!(newimage = jas_image_chclrspc(image, outprof, JAS_CMXFORM_INTENT_PER))) { jas_eprintf("cannot convert to sRGB\n"); exit(EXIT_FAILURE); } jas_image_destroy(image); jas_cmprof_destroy(outprof); image = newimage; } /* Generate the output image data. */ startclk = clock(); if (jas_image_encode(image, out, cmdopts->outfmt, cmdopts->outopts)) { jas_eprintf("error: cannot encode image\n"); exit(EXIT_FAILURE); } jas_stream_flush(out); endclk = clock(); enctime = endclk - startclk; if (cmdopts->verbose) { jas_eprintf("decoding time = %f\n", dectime / (double) CLOCKS_PER_SEC); jas_eprintf("encoding time = %f\n", enctime / (double) CLOCKS_PER_SEC); } /* If this fails, we don't care. */ (void) jas_stream_close(in); /* Close the output image stream. */ if (jas_stream_close(out)) { jas_eprintf("error: cannot close output image file\n"); exit(EXIT_FAILURE); } cmdopts_destroy(cmdopts); jas_image_destroy(image); jas_image_clearfmts(); /* Success at last! :-) */ return EXIT_SUCCESS; }
DEFINE_LOADER_PLUGIN_LOAD(p, st, vw #if !defined(IDENTIFY_BEFORE_LOAD) __attribute__((unused)) #endif , c #if !defined(IDENTIFY_BEFORE_LOAD) __attribute__((unused)) #endif , priv #if !defined(IDENTIFY_BEFORE_LOAD) __attribute__((unused)) #endif ) { jas_image_t *ji; jas_stream_t *js; unsigned char *d; char *buf = NULL; int k, cmp[3]; unsigned int i, j; int tlx, tly; int vs, hs; //debug_message("JasPer: load() called\n"); #ifdef IDENTIFY_BEFORE_LOAD { LoaderStatus status; if ((status = identify(p, st, vw, c, priv)) != LOAD_OK) return status; stream_rewind(st); } #endif /* Read whole stream into buffer... */ { char *tmp; int size = 0, len; int bufsize = 65536; for (;;) { if ((tmp = realloc(buf, bufsize)) == NULL) { free(buf); return LOAD_ERROR; } buf = tmp; len = stream_read(st, (unsigned char *)(buf + size), bufsize - size); size += len; if (len < bufsize - size) break; bufsize += 65536; } if ((js = jas_stream_memopen(buf, size)) == NULL) { free(buf); return LOAD_ERROR; } } /* loading... */ if ((ji = jas_image_decode(js, -1, 0)) == NULL) { err_message_fnc("jas_image_decode() failed.\n"); goto error_clear; } /* colorspace conversion */ { jas_cmprof_t *jc; jas_image_t *new_ji; if ((jc = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB)) == NULL) goto error_destroy_free; if ((new_ji = jas_image_chclrspc(ji, jc, JAS_CMXFORM_INTENT_PER)) == NULL) goto error_destroy_free; jas_image_destroy(ji); ji = new_ji; } jas_stream_close(js); free(buf); debug_message("JasPer: jas_image_decode() OK: (%ld,%ld)\n", jas_image_cmptwidth(ji, 0), jas_image_cmptheight(ji, 0)); /* convert to enfle format */ p->bits_per_pixel = 24; p->type = _RGB24; p->depth = 24; cmp[0] = jas_image_getcmptbytype(ji, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R)); cmp[1] = jas_image_getcmptbytype(ji, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G)); cmp[2] = jas_image_getcmptbytype(ji, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B)); /* dimension */ image_width(p) = jas_image_cmptwidth(ji, cmp[0]); image_height(p) = jas_image_cmptheight(ji, cmp[0]); image_left(p) = 0; image_top(p) = 0; image_bpl(p) = image_width(p) * 3; tlx = jas_image_cmpttlx(ji, cmp[0]); tly = jas_image_cmpttly(ji, cmp[0]); vs = jas_image_cmptvstep(ji, cmp[0]); hs = jas_image_cmpthstep(ji, cmp[0]); debug_message("JasPer: tlx %d tly %d vs %d hs %d ncomponents %d\n", tlx, tly, vs, hs, jas_image_numcmpts(ji)); /* memory allocation */ if ((d = memory_alloc(image_image(p), image_bpl(p) * image_height(p))) == NULL) { err_message("No enough memory (%d bytes)\n", image_bpl(p) * image_height(p)); goto error_destroy_free; } for (i = 0; i < image_height(p); i++) { for (j = 0; j < image_width(p); j++) { for (k = 0; k < 3; k++) *d++ = jas_image_readcmptsample(ji, cmp[k], j, i); } } jas_image_destroy(ji); return LOAD_OK; error_destroy_free: jas_image_destroy(ji); error_clear: return LOAD_ERROR; }
static GstFlowReturn gst_jasper_enc_get_data (GstJasperEnc * enc, guint8 * data, GstBuffer ** outbuf) { GstFlowReturn ret = GST_FLOW_OK; jas_stream_t *stream = NULL; gint i; guint size, boxsize; g_return_val_if_fail (outbuf != NULL, GST_FLOW_ERROR); *outbuf = NULL; boxsize = (enc->mode == GST_JP2ENC_MODE_J2C) ? 8 : 0; if (!(stream = jas_stream_memopen (NULL, 0))) goto fail_stream; for (i = 0; i < enc->channels; ++i) { gint x, y, cwidth, cheight, inc, stride, cmpt; guint8 *row_pix, *in_pix; glong *tb; cmpt = i; inc = enc->inc[i]; stride = enc->stride[i]; cheight = enc->cheight[cmpt]; cwidth = enc->cwidth[cmpt]; GST_LOG_OBJECT (enc, "write component %d<=%d, size %dx%d, offset %d, inc %d, stride %d", i, cmpt, cwidth, cheight, enc->offset[i], inc, stride); row_pix = data + enc->offset[i]; for (y = 0; y < cheight; y++) { in_pix = row_pix; tb = enc->buf; for (x = 0; x < cwidth; x++) { *tb = *in_pix; in_pix += inc; tb++; } if (jas_image_writecmpt2 (enc->image, cmpt, 0, y, cwidth, 1, enc->buf)) goto fail_image; row_pix += stride; } } GST_LOG_OBJECT (enc, "all components written"); if (jas_image_encode (enc->image, stream, enc->fmt, (char *) "sop")) goto fail_encode; GST_LOG_OBJECT (enc, "image encoded"); size = jas_stream_length (stream); ret = gst_pad_alloc_buffer_and_set_caps (enc->srcpad, GST_BUFFER_OFFSET_NONE, size + boxsize, GST_PAD_CAPS (enc->srcpad), outbuf); if (ret != GST_FLOW_OK) goto no_buffer; data = GST_BUFFER_DATA (*outbuf); if (jas_stream_flush (stream) || jas_stream_rewind (stream) < 0 || jas_stream_read (stream, data + boxsize, size) < size) goto fail_image_out; if (boxsize) { /* write atom prefix */ GST_WRITE_UINT32_BE (data, size + 8); GST_WRITE_UINT32_LE (data + 4, GST_MAKE_FOURCC ('j', 'p', '2', 'c')); } done: if (stream) jas_stream_close (stream); return ret; /* ERRORS */ fail_stream: { GST_DEBUG_OBJECT (enc, "Failed to create inputstream."); goto fail; } fail_encode: { GST_DEBUG_OBJECT (enc, "Failed to encode image."); goto fail; } fail_image: { GST_DEBUG_OBJECT (enc, "Failed to process input image."); goto fail; } fail_image_out: { GST_DEBUG_OBJECT (enc, "Failed to process encoded image."); goto fail; } fail: { if (*outbuf) gst_buffer_unref (*outbuf); *outbuf = NULL; GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL), (NULL)); ret = GST_FLOW_ERROR; goto done; } no_buffer: { GST_DEBUG_OBJECT (enc, "Failed to create outbuffer - %s", gst_flow_get_name (ret)); goto done; } }
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; }
static GstFlowReturn gst_jasper_dec_get_picture (GstJasperDec * dec, guint8 * data, guint size, GstBuffer ** outbuf) { GstFlowReturn ret = GST_FLOW_OK; jas_stream_t *stream = NULL; jas_image_t *image = NULL; gint i; g_return_val_if_fail (outbuf != NULL, GST_FLOW_ERROR); *outbuf = NULL; if (!(stream = jas_stream_memopen ((gpointer) data, size))) goto fail_stream; if (!(image = jas_image_decode (stream, dec->fmt, (char *) ""))) goto fail_decode; ret = gst_jasper_dec_negotiate (dec, image); if (ret != GST_FLOW_OK) goto fail_negotiate; ret = gst_pad_alloc_buffer_and_set_caps (dec->srcpad, GST_BUFFER_OFFSET_NONE, dec->image_size, GST_PAD_CAPS (dec->srcpad), outbuf); if (ret != GST_FLOW_OK) goto no_buffer; if (dec->alpha) memset (GST_BUFFER_DATA (*outbuf), 0xff, dec->image_size); for (i = 0; i < dec->channels; ++i) { gint x, y, cwidth, cheight, inc, stride, cmpt; guint8 *row_pix, *out_pix; glong *tb; inc = dec->inc[i]; stride = dec->stride[i]; cmpt = dec->cmpt[i]; cheight = dec->cheight[cmpt]; cwidth = dec->cwidth[cmpt]; GST_LOG_OBJECT (dec, "retrieve component %d<=%d, size %dx%d, offset %d, inc %d, stride %d", i, cmpt, cwidth, cheight, dec->offset[i], inc, stride); out_pix = GST_BUFFER_DATA (*outbuf) + dec->offset[i]; for (y = 0; y < cheight; y++) { row_pix = out_pix; tb = dec->buf; if (jas_image_readcmpt2 (image, i, 0, y, cwidth, 1, dec->buf)) goto fail_image; for (x = 0; x < cwidth; x++) { *out_pix = *tb; tb++; out_pix += inc; } out_pix = row_pix + stride; } } GST_LOG_OBJECT (dec, "all components retrieved"); done: if (image) jas_image_destroy (image); if (stream) jas_stream_close (stream); return ret; /* ERRORS */ fail_stream: { GST_DEBUG_OBJECT (dec, "Failed to create inputstream."); goto fail; } fail_decode: { GST_DEBUG_OBJECT (dec, "Failed to decode image."); goto fail; } fail_image: { GST_DEBUG_OBJECT (dec, "Failed to process decoded image."); goto fail; } fail: { if (*outbuf) gst_buffer_unref (*outbuf); *outbuf = NULL; GST_ELEMENT_WARNING (dec, STREAM, DECODE, (NULL), (NULL)); ret = GST_FLOW_OK; goto done; } no_buffer: { GST_DEBUG_OBJECT (dec, "Failed to create outbuffer - %s", gst_flow_get_name (ret)); goto done; } fail_negotiate: { GST_DEBUG_OBJECT (dec, "Failed to determine output caps."); goto done; } }
/* Read a marker segment from a stream. */ jpc_ms_t *jpc_getms(jas_stream_t *in, jpc_cstate_t *cstate) { long file_offset = jas_stream_tell(in); long seek_offset = jas_rtc_SkipMarkerSegment(file_offset); if (seek_offset > 0 && jas_stream_seek(in, seek_offset, SEEK_CUR) < 0) return NULL; jpc_ms_t *ms; jpc_mstabent_t *mstabent; jas_stream_t *tmpstream; if (!(ms = jpc_ms_create(0))) { return 0; } /* Get the marker type. */ if (jpc_getuint16(in, &ms->id) || ms->id < JPC_MS_MIN #ifndef __MINGW32__ || ms->id > JPC_MS_MAX #endif ) { jpc_ms_destroy(ms); return 0; } jas_rtc_MarkerSegment(file_offset, ms->id); mstabent = jpc_mstab_lookup(ms->id); ms->ops = &mstabent->ops; /* Get the marker segment length and parameters if present. */ /* Note: It is tacitly assumed that a marker segment cannot have parameters unless it has a length field. That is, there cannot be a parameters field without a length field and vice versa. */ if (JPC_MS_HASPARMS(ms->id)) { /* Get the length of the marker segment. */ if (jpc_getuint16(in, &ms->len) || ms->len < 3) { jpc_ms_destroy(ms); return 0; } /* Calculate the length of the marker segment parameters. */ ms->len -= 2; /* Create and prepare a temporary memory stream from which to read the marker segment parameters. */ /* Note: This approach provides a simple way of ensuring that we never read beyond the end of the marker segment (even if the marker segment length is errantly set too small). */ if (!(tmpstream = jas_stream_memopen(0, 0))) { jpc_ms_destroy(ms); return 0; } if (jas_stream_copy(tmpstream, in, ms->len) || jas_stream_seek(tmpstream, 0, SEEK_SET) < 0) { jas_stream_close(tmpstream); jpc_ms_destroy(ms); return 0; } /* Get the marker segment parameters. */ if ((*ms->ops->getparms)(ms, cstate, tmpstream)) { ms->ops = 0; jpc_ms_destroy(ms); jas_stream_close(tmpstream); return 0; } #if 0 // JMW if (JAS_CAST(ulong, jas_stream_tell(tmpstream)) != ms->len) { fprintf(stderr, "warning: trailing garbage in marker segment (%ld bytes)\n", ms->len - jas_stream_tell(tmpstream)); } #endif /* Close the temporary stream. */ jas_stream_close(tmpstream); } else { /* There are no marker segment parameters. */ ms->len = 0; } /* Update the code stream state information based on the type of marker segment read. */ /* Note: This is a bit of a hack, but I'm not going to define another type of virtual function for this one special case. */ if (ms->id == JPC_MS_SIZ) { cstate->numcomps = ms->parms.siz.numcomps; } return ms; }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e J P 2 I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method WriteJP2Image writes an image in the JPEG 2000 image format. % % JP2 support originally written by Nathan Brown, [email protected] % % The format of the WriteJP2Image method is: % % MagickPassFail WriteJP2Image(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o status: Method WriteJP2Image return MagickTrue if the image is written. % MagickFalse is returned is there is a memory shortage or if the image file % fails to write. % % o image_info: Specifies a pointer to a ImageInfo structure. % % o image: A pointer to an Image structure. % % */ static MagickPassFail WriteJP2Image(const ImageInfo *image_info,Image *image) { char magick[MaxTextExtent], option_keyval[MaxTextExtent], *options = NULL; int format; long y; jas_image_cmptparm_t component_info; jas_image_t *jp2_image; jas_matrix_t *jp2_pixels; jas_stream_t *jp2_stream; register const PixelPacket *p; register int x; unsigned int rate_specified=False, status; int component, number_components; unsigned short *lut; ImageCharacteristics characteristics; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); /* Ensure that image is in RGB space. */ (void) TransformColorspace(image,RGBColorspace); /* Analyze image to be written. */ if (!GetImageCharacteristics(image,&characteristics, (OptimizeType == image_info->type), &image->exception)) { CloseBlob(image); return MagickFail; } /* Obtain a JP2 stream. */ jp2_stream=JP2StreamManager(image); if (jp2_stream == (jas_stream_t *) NULL) ThrowWriterException(DelegateError,UnableToManageJP2Stream,image); number_components=image->matte ? 4 : 3; if ((image_info->type != TrueColorType) && (characteristics.grayscale)) number_components=1; jp2_image=jas_image_create0(); if (jp2_image == (jas_image_t *) NULL) ThrowWriterException(DelegateError,UnableToCreateImage,image); for (component=0; component < number_components; component++) { (void) memset((void *)&component_info,0,sizeof(jas_image_cmptparm_t)); component_info.tlx=0; /* top left x ordinate */ component_info.tly=0; /* top left y ordinate */ component_info.hstep=1; /* horizontal pixels per step */ component_info.vstep=1; /* vertical pixels per step */ component_info.width=(unsigned int) image->columns; component_info.height=(unsigned int) image->rows; component_info.prec=(unsigned int) Max(2,Min(image->depth,16)); /* bits in range */ component_info.sgnd = false; /* range is signed value? */ if (jas_image_addcmpt(jp2_image, component,&component_info)) { jas_image_destroy(jp2_image); ThrowWriterException(DelegateError,UnableToCreateImageComponent,image); } } /* Allocate and compute LUT. */ { unsigned long i, max_value; double scale_to_component; lut=MagickAllocateArray(unsigned short *,MaxMap+1,sizeof(*lut)); if (lut == (unsigned short *) NULL) { jas_image_destroy(jp2_image); ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); } max_value=MaxValueGivenBits(component_info.prec); scale_to_component=max_value/MaxRGBDouble; for(i=0; i <= MaxMap; i++) lut[i]=scale_to_component*i+0.5; } if (number_components == 1) { /* FIXME: If image has an attached ICC profile, then the profile should be transferred and the image colorspace set to JAS_CLRSPC_GENGRAY */ /* sRGB Grayscale */ (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting SGRAY colorspace"); jas_image_setclrspc(jp2_image, JAS_CLRSPC_SGRAY); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting GRAY channel to channel 0"); jas_image_setcmpttype(jp2_image,0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y)); } else { /* FIXME: If image has an attached ICC profile, then the profile should be transferred and the image colorspace set to JAS_CLRSPC_GENRGB */ /* sRGB */ (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting SRGB colorspace"); jas_image_setclrspc(jp2_image, JAS_CLRSPC_SRGB); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting RED channel to channel 0"); jas_image_setcmpttype(jp2_image,0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R)); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting GREEN channel to channel 1"); jas_image_setcmpttype(jp2_image,1, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G)); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting BLUE channel to channel 2"); jas_image_setcmpttype(jp2_image,2, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B)); if (number_components == 4 ) { (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting OPACITY channel to channel 3"); jas_image_setcmpttype(jp2_image,3, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_OPACITY)); } } /* Convert to JPEG 2000 pixels. */ jp2_pixels=jas_matrix_create(1,(unsigned int) image->columns); if (jp2_pixels == (jas_matrix_t *) NULL) { MagickFreeMemory(lut); jas_image_destroy(jp2_image); ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); } for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; if (number_components == 1) { for (x=0; x < (long) image->columns; x++) jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(PixelIntensityToQuantum(&p[x]))]); (void) jas_image_writecmpt(jp2_image,0,0,(unsigned int) y, (unsigned int) image->columns,1,jp2_pixels); } else { for (x=0; x < (long) image->columns; x++) jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(p[x].red)]); (void) jas_image_writecmpt(jp2_image,0,0,(unsigned int) y, (unsigned int) image->columns,1,jp2_pixels); for (x=0; x < (long) image->columns; x++) jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(p[x].green)]); (void) jas_image_writecmpt(jp2_image,1,0,(unsigned int) y, (unsigned int) image->columns,1,jp2_pixels); for (x=0; x < (long) image->columns; x++) jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(p[x].blue)]); (void) jas_image_writecmpt(jp2_image,2,0,(unsigned int) y, (unsigned int) image->columns,1,jp2_pixels); if (number_components > 3) for (x=0; x < (long) image->columns; x++) jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(MaxRGB-p[x].opacity)]); (void) jas_image_writecmpt(jp2_image,3,0,(unsigned int) y, (unsigned int) image->columns,1,jp2_pixels); } if (image->previous == (Image *) NULL) if (QuantumTick(y,image->rows)) if (!MagickMonitorFormatted(y,image->rows,&image->exception, SaveImageText,image->filename, image->columns,image->rows)) break; } (void) strlcpy(magick,image_info->magick,MaxTextExtent); /* J2C is an alias for JPC but Jasper only supports "JPC". */ if (LocaleCompare(magick,"j2c") == 0) (void) strlcpy(magick,"jpc",sizeof(magick)); LocaleLower(magick); format=jas_image_strtofmt(magick); /* Support passing Jasper options. */ { const char **option_name; static const char *jasper_options[] = { "imgareatlx", "imgareatly", "tilegrdtlx", "tilegrdtly", "tilewidth", "tileheight", "prcwidth", "prcheight", "cblkwidth", "cblkheight", "mode", "ilyrrates", "prg", "nomct", "numrlvls", "sop", "eph", "lazy", "rate", "termall", "segsym", "vcausal", "pterm", "resetprob", "numgbits", NULL }; for (option_name = jasper_options; *option_name != NULL; option_name++) { const char *value; if ((value=AccessDefinition(image_info,"jp2",*option_name)) != NULL) { if(LocaleCompare(*option_name,"rate") == 0) rate_specified=True; FormatString(option_keyval,"%s=%.1024s ",*option_name,value); ConcatenateString(&options,option_keyval); } } } /* Provide an emulation of IJG JPEG "quality" by default. */ if (rate_specified == False) { double rate=1.0; /* A rough approximation to JPEG v1 quality using JPEG-2000. Default "quality" 75 results in a request for 16:1 compression, which results in image sizes approximating that of JPEG v1. */ if ((image_info->quality < 99.5) && (image->rows*image->columns > 2500)) { double header_size, current_size, target_size, d; d=115-image_info->quality; /* Best number is 110-115 */ rate=100.0/(d*d); header_size=550.0; /* Base file size. */ header_size+=(number_components-1)*142; /* Additional components */ /* FIXME: Need to account for any ICC profiles here */ current_size=(double)((image->rows*image->columns*image->depth)/8)* number_components; target_size=(current_size*rate)+header_size; rate=target_size/current_size; } FormatString(option_keyval,"%s=%g ","rate",rate); ConcatenateString(&options,option_keyval); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Compression rate: %g (%3.2f:1)",rate,1.0/rate); } if (options) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Jasper options: \"%s\"", options); (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Encoding image"); status=jas_image_encode(jp2_image,jp2_stream,format,options); (void) jas_stream_close(jp2_stream); MagickFreeMemory(options); MagickFreeMemory(lut); jas_matrix_destroy(jp2_pixels); jas_image_destroy(jp2_image); if (status) ThrowWriterException(DelegateError,UnableToEncodeImageFile,image); return(True); }
static Image *ReadJP2Image(const ImageInfo *image_info, ExceptionInfo *exception) { Image *image; long y; jas_image_t *jp2_image; jas_matrix_t *pixels; jas_stream_t *jp2_stream; register long x; register PixelPacket *q; int component, components[4], number_components; Quantum *channel_lut[4]; unsigned int status; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AllocateImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == False) ThrowReaderException(FileOpenError,UnableToOpenFile,image); /* Obtain a JP2 Stream. */ jp2_stream=JP2StreamManager(image); if (jp2_stream == (jas_stream_t *) NULL) ThrowReaderException(DelegateError,UnableToManageJP2Stream,image); jp2_image=jas_image_decode(jp2_stream,-1,0); if (jp2_image == (jas_image_t *) NULL) { (void) jas_stream_close(jp2_stream); ThrowReaderException(DelegateError,UnableToDecodeImageFile,image); } /* Validate that we can handle the image and obtain component indexes. */ switch (jas_clrspc_fam(jas_image_clrspc(jp2_image))) { case JAS_CLRSPC_FAM_RGB: { if (((components[0]= jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R))) < 0) || ((components[1]= jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G))) < 0) || ((components[2]= jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B))) < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,MissingImageChannel,image); } number_components=3; (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Image is in RGB colorspace family"); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "RED is in channel %d, GREEN is in channel %d, BLUE is in channel %d", components[0],components[1],components[2]); if((components[3]=jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_OPACITY))) > 0) { image->matte=MagickTrue; (void) LogMagickEvent(CoderEvent,GetMagickModule(), "OPACITY is in channel %d",components[3]); number_components++; } break; } case JAS_CLRSPC_FAM_GRAY: { if ((components[0]= jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y))) < 0) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,MissingImageChannel,image); } (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Image is in GRAY colorspace family"); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "GRAY is in channel %d",components[0]); number_components=1; break; } case JAS_CLRSPC_FAM_YCBCR: { components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_Y); components[1]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CB); components[2]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CR); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,MissingImageChannel,image); } number_components=3; components[3]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_OPACITY); if (components[3] > 0) { image->matte=True; number_components++; } image->colorspace=YCbCrColorspace; (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Image is in YCBCR colorspace family"); break; } default: { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CoderError,ColorspaceModelIsNotSupported,image); } } image->columns=jas_image_width(jp2_image); image->rows=jas_image_height(jp2_image); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "columns=%lu rows=%lu components=%d",image->columns,image->rows, number_components); for (component=0; component < number_components; component++) { if(((unsigned long) jas_image_cmptwidth(jp2_image,components[component]) != image->columns) || ((unsigned long) jas_image_cmptheight(jp2_image,components[component]) != image->rows) || (jas_image_cmpttlx(jp2_image, components[component]) != 0) || (jas_image_cmpttly(jp2_image, components[component]) != 0) || (jas_image_cmpthstep(jp2_image, components[component]) != 1) || (jas_image_cmptvstep(jp2_image, components[component]) != 1) || (jas_image_cmptsgnd(jp2_image, components[component]) != false)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CoderError,IrregularChannelGeometryNotSupported,image); } } image->matte=number_components > 3; for (component=0; component < number_components; component++) { unsigned int component_depth; component_depth=jas_image_cmptprec(jp2_image,components[component]); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Component[%d] depth is %u",component,component_depth); if (0 == component) image->depth=component_depth; else image->depth=Max(image->depth,component_depth); } (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Image depth is %u",image->depth); if (image_info->ping) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); return(image); } /* Allocate Jasper pixels. */ pixels=jas_matrix_create(1,(unsigned int) image->columns); if (pixels == (jas_matrix_t *) NULL) { jas_image_destroy(jp2_image); ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); } /* Allocate and populate channel LUTs */ for (component=0; component < (long) number_components; component++) { unsigned long component_depth, i, max_value; double scale_to_quantum; component_depth=jas_image_cmptprec(jp2_image,components[component]); max_value=MaxValueGivenBits(component_depth); scale_to_quantum=MaxRGBDouble/max_value; (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Channel %d scale is %g", component, scale_to_quantum); channel_lut[component]=MagickAllocateArray(Quantum *,max_value+1,sizeof(Quantum)); if (channel_lut[component] == (Quantum *) NULL) { for ( --component; component >= 0; --component) MagickFreeMemory(channel_lut[component]); jas_matrix_destroy(pixels); jas_image_destroy(jp2_image); ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); } for(i=0; i <= max_value; i++) (channel_lut[component])[i]=scale_to_quantum*i+0.5; } /* Convert JPEG 2000 pixels. */ for (y=0; y < (long) image->rows; y++) { q=GetImagePixels(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) break; if (1 == number_components) { /* Grayscale */ (void) jas_image_readcmpt(jp2_image,(short) components[0],0, (unsigned int) y, (unsigned int) image->columns,1,pixels); for (x=0; x < (long) image->columns; x++) { q->red=q->green=q->blue=(channel_lut[0])[jas_matrix_getv(pixels,x)]; q->opacity=OpaqueOpacity; q++; } } else { /* Red */ (void) jas_image_readcmpt(jp2_image,(short) components[0],0, (unsigned int) y, (unsigned int) image->columns,1,pixels); for (x=0; x < (long) image->columns; x++) q[x].red=(channel_lut[0])[jas_matrix_getv(pixels,x)]; /* Green */ (void) jas_image_readcmpt(jp2_image,(short) components[1],0, (unsigned int) y, (unsigned int) image->columns,1,pixels); for (x=0; x < (long) image->columns; x++) q[x].green=(channel_lut[1])[jas_matrix_getv(pixels,x)]; /* Blue */ (void) jas_image_readcmpt(jp2_image,(short) components[2],0, (unsigned int) y, (unsigned int) image->columns,1,pixels); for (x=0; x < (long) image->columns; x++) q[x].blue=(channel_lut[2])[jas_matrix_getv(pixels,x)]; /* Opacity */ if (number_components > 3) { (void) jas_image_readcmpt(jp2_image,(short) components[3],0, (unsigned int) y, (unsigned int) image->columns,1,pixels); for (x=0; x < (long) image->columns; x++) q[x].opacity=MaxRGB-(channel_lut[3])[jas_matrix_getv(pixels,x)]; } else { for (x=0; x < (long) image->columns; x++) q[x].opacity=OpaqueOpacity; } } if (!SyncImagePixels(image)) break; if (image->previous == (Image *) NULL) if (QuantumTick(y,image->rows)) if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText, image->filename, image->columns,image->rows)) break; } if (number_components == 1) image->is_grayscale=MagickTrue; { /* Obtain ICC ICM color profile */ jas_cmprof_t *cm_profile; /* Obtain a pointer to the existing jas_cmprof_t profile handle. */ cm_profile=jas_image_cmprof(jp2_image); if (cm_profile != (jas_cmprof_t *) NULL) { jas_iccprof_t *icc_profile; /* Obtain a copy of the jas_iccprof_t ICC profile handle */ icc_profile=jas_iccprof_createfromcmprof(cm_profile); /* or maybe just icc_profile=cm_profile->iccprof */ if (icc_profile != (jas_iccprof_t *) NULL) { jas_stream_t *icc_stream; icc_stream=jas_stream_memopen(NULL,0); if ((icc_stream != (jas_stream_t *) NULL) && (jas_iccprof_save(icc_profile,icc_stream) == 0) && (jas_stream_flush(icc_stream) == 0)) { jas_stream_memobj_t *blob; blob=(jas_stream_memobj_t *) icc_stream->obj_; if (image->logging) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "ICC profile: %lu bytes",(unsigned long) blob->len_); SetImageProfile(image,"ICM",blob->buf_,blob->len_); (void) jas_stream_close(icc_stream); jas_iccprof_destroy(icc_profile); } } } } for (component=0; component < (long) number_components; component++) MagickFreeMemory(channel_lut[component]); jas_matrix_destroy(pixels); (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); return(image); }
CPL_C_END int dec_jpeg2000(char *injpc,g2int bufsize,g2int *outfld) /*$$$ SUBPROGRAM DOCUMENTATION BLOCK * . . . . * SUBPROGRAM: dec_jpeg2000 Decodes JPEG2000 code stream * PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-12-02 * * ABSTRACT: This Function decodes a JPEG2000 code stream specified in the * JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) using JasPer * Software version 1.500.4 (or 1.700.2) written by the University of British * Columbia and Image Power Inc, and others. * JasPer is available at http://www.ece.uvic.ca/~mdadams/jasper/. * * PROGRAM HISTORY LOG: * 2002-12-02 Gilbert * * USAGE: int dec_jpeg2000(char *injpc,g2int bufsize,g2int *outfld) * * INPUT ARGUMENTS: * injpc - Input JPEG2000 code stream. * bufsize - Length (in bytes) of the input JPEG2000 code stream. * * OUTPUT ARGUMENTS: * outfld - Output matrix of grayscale image values. * * RETURN VALUES : * 0 = Successful decode * -3 = Error decode jpeg2000 code stream. * -5 = decoded image had multiple color components. * Only grayscale is expected. * * REMARKS: * * Requires JasPer Software version 1.500.4 or 1.700.2 * * ATTRIBUTES: * LANGUAGE: C * MACHINE: IBM SP * *$$$*/ { #ifndef HAVE_JASPER // J2K_SUBFILE method // create "memory file" from buffer int fileNumber = 0; VSIStatBufL sStatBuf; CPLString osFileName = "/vsimem/work.jpc"; // ensure we don't overwrite an existing file accidentally while ( VSIStatL( osFileName, &sStatBuf ) == 0 ) { osFileName.Printf( "/vsimem/work%d.jpc", ++fileNumber ); } VSIFCloseL( VSIFileFromMemBuffer( osFileName, (unsigned char*)injpc, bufsize, FALSE ) ); // TRUE to let vsi delete the buffer when done // Open memory buffer for reading GDALDataset* poJ2KDataset = (GDALDataset *) GDALOpen( osFileName, GA_ReadOnly ); if( poJ2KDataset == NULL ) { printf("dec_jpeg2000: Unable to open JPEG2000 image within GRIB file.\n" "Is the JPEG2000 driver available?" ); return -3; } if( poJ2KDataset->GetRasterCount() != 1 ) { printf("dec_jpeg2000: Found color image. Grayscale expected.\n"); return (-5); } // Fulfill administration: initialize parameters required for RasterIO int nXSize = poJ2KDataset->GetRasterXSize(); int nYSize = poJ2KDataset->GetRasterYSize(); int nXOff = 0; int nYOff = 0; int nBufXSize = nXSize; int nBufYSize = nYSize; GDALDataType eBufType = GDT_Int32; // map to type of "outfld" buffer: g2int* int nBandCount = 1; int* panBandMap = NULL; int nPixelSpace = 0; int nLineSpace = 0; int nBandSpace = 0; // Decompress the JPEG2000 into the output integer array. poJ2KDataset->RasterIO( GF_Read, nXOff, nYOff, nXSize, nYSize, outfld, nBufXSize, nBufYSize, eBufType, nBandCount, panBandMap, nPixelSpace, nLineSpace, nBandSpace, NULL ); // close source file, and "unlink" it. GDALClose( poJ2KDataset ); VSIUnlink( osFileName ); return 0; #else // JasPer method int ier; g2int i,j,k; jas_image_t *image=0; jas_stream_t *jpcstream; jas_image_cmpt_t *pcmpt; char *opts=0; jas_matrix_t *data; // jas_init(); ier=0; // // Create jas_stream_t containing input JPEG200 codestream in memory. // jpcstream=jas_stream_memopen(injpc,bufsize); // // Decode JPEG200 codestream into jas_image_t structure. // image=jpc_decode(jpcstream,opts); if ( image == 0 ) { printf(" jpc_decode return = %d \n",ier); return -3; } pcmpt=image->cmpts_[0]; // Expecting jpeg2000 image to be grayscale only. // No color components. // if (image->numcmpts_ != 1 ) { printf("dec_jpeg2000: Found color image. Grayscale expected.\n"); return (-5); } // // Create a data matrix of grayscale image values decoded from // the jpeg2000 codestream. // data=jas_matrix_create(jas_image_height(image), jas_image_width(image)); jas_image_readcmpt(image,0,0,0,jas_image_width(image), jas_image_height(image),data); // // Copy data matrix to output integer array. // k=0; for (i=0; i<pcmpt->height_; i++) for (j=0; j<pcmpt->width_; j++) outfld[k++]=data->rows_[i][j]; // // Clean up JasPer work structures. // jas_matrix_destroy(data); ier=jas_stream_close(jpcstream); jas_image_destroy(image); return 0; #endif }