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 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); }
//! 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; }
fz_error fz_newjpxd(fz_filter **fp, fz_obj *params) { int err; FZ_NEWFILTER(fz_jpxd, d, jpxd); err = jas_init(); if (err) { fz_free(d); return fz_throw("jasper error: jas_init()"); } d->stream = jas_stream_memopen(nil, 0); if (!d->stream) { fz_free(d); return fz_throw("jasper error: jas_stream_memopen()"); } d->image = nil; d->offset = 0; d->stage = 0; return fz_okay; }
/* 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; }
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 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); }
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 }
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) { 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 || ms->id > JPC_MS_MAX) { jpc_ms_destroy(ms); return 0; } 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 (jas_getdbglevel() > 0) { jpc_ms_dump(ms, stderr); } if (JAS_CAST(unsigned long, jas_stream_tell(tmpstream)) != ms->len) { fprintf(stderr, "warning: trailing garbage in marker segment (%ld bytes)\n", ms->len - jas_stream_tell(tmpstream)); } /* Close the temporary stream. */ jas_stream_close(tmpstream); } else {
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; }
/* Encode a single code block. */ int jpc_enc_enccblk(jpc_enc_t *enc, jas_stream_t *out, jpc_enc_tcmpt_t *tcmpt, jpc_enc_band_t *band, jpc_enc_cblk_t *cblk) { jpc_enc_pass_t *pass; jpc_enc_pass_t *endpasses; int bitpos; int n; int adjust; int ret; int passtype; int t; jpc_bitstream_t *bout; jpc_enc_pass_t *termpass; jpc_enc_rlvl_t *rlvl; int vcausal; int segsym; int termmode; int c; bout = 0; rlvl = band->rlvl; cblk->stream = jas_stream_memopen(0, 0); assert(cblk->stream); cblk->mqenc = jpc_mqenc_create(JPC_NUMCTXS, cblk->stream); assert(cblk->mqenc); jpc_mqenc_setctxs(cblk->mqenc, JPC_NUMCTXS, jpc_mqctxs); cblk->numpasses = (cblk->numbps > 0) ? (3 * cblk->numbps - 2) : 0; if (cblk->numpasses > 0) { cblk->passes = jas_malloc(cblk->numpasses * sizeof(jpc_enc_pass_t)); assert(cblk->passes); } else { cblk->passes = 0; } endpasses = &cblk->passes[cblk->numpasses]; for (pass = cblk->passes; pass != endpasses; ++pass) { pass->start = 0; pass->end = 0; pass->term = JPC_ISTERMINATED(pass - cblk->passes, 0, cblk->numpasses, (tcmpt->cblksty & JPC_COX_TERMALL) != 0, (tcmpt->cblksty & JPC_COX_LAZY) != 0); pass->type = JPC_SEGTYPE(pass - cblk->passes, 0, (tcmpt->cblksty & JPC_COX_LAZY) != 0); pass->lyrno = -1; if (pass == endpasses - 1) { assert(pass->term == 1); pass->term = 1; } } cblk->flags = jas_matrix_create(jas_matrix_numrows(cblk->data) + 2, jas_matrix_numcols(cblk->data) + 2); assert(cblk->flags); bitpos = cblk->numbps - 1; pass = cblk->passes; n = cblk->numpasses; while (--n >= 0) { if (pass->type == JPC_SEG_MQ) { /* NOP */ } else { assert(pass->type == JPC_SEG_RAW); if (!bout) { bout = jpc_bitstream_sopen(cblk->stream, "w"); assert(bout); } } #if 1 passtype = (pass - cblk->passes + 2) % 3; #else passtype = JPC_PASSTYPE(pass - cblk->passes + 2); #endif pass->start = jas_stream_tell(cblk->stream); #if 0 assert(jas_stream_tell(cblk->stream) == jas_stream_getrwcount(cblk->stream)); #endif assert(bitpos >= 0); vcausal = (tcmpt->cblksty & JPC_COX_VSC) != 0; segsym = (tcmpt->cblksty & JPC_COX_SEGSYM) != 0; if (pass->term) { termmode = ((tcmpt->cblksty & JPC_COX_PTERM) ? JPC_MQENC_PTERM : JPC_MQENC_DEFTERM) + 1; } else { termmode = 0; } switch (passtype) { case JPC_SIGPASS: ret = (pass->type == JPC_SEG_MQ) ? jpc_encsigpass(cblk->mqenc, bitpos, band->orient, vcausal, cblk->flags, cblk->data, termmode, &pass->nmsedec) : jpc_encrawsigpass(bout, bitpos, vcausal, cblk->flags, cblk->data, termmode, &pass->nmsedec); break; case JPC_REFPASS: ret = (pass->type == JPC_SEG_MQ) ? jpc_encrefpass(cblk->mqenc, bitpos, vcausal, cblk->flags, cblk->data, termmode, &pass->nmsedec) : jpc_encrawrefpass(bout, bitpos, vcausal, cblk->flags, cblk->data, termmode, &pass->nmsedec); break; case JPC_CLNPASS: assert(pass->type == JPC_SEG_MQ); ret = jpc_encclnpass(cblk->mqenc, bitpos, band->orient, vcausal, segsym, cblk->flags, cblk->data, termmode, &pass->nmsedec); break; default: assert(0); break; } if (pass->type == JPC_SEG_MQ) { if (pass->term) { jpc_mqenc_init(cblk->mqenc); } jpc_mqenc_getstate(cblk->mqenc, &pass->mqencstate); pass->end = jas_stream_tell(cblk->stream); if (tcmpt->cblksty & JPC_COX_RESET) { jpc_mqenc_setctxs(cblk->mqenc, JPC_NUMCTXS, jpc_mqctxs); } } else { if (pass->term) { if (jpc_bitstream_pending(bout)) { jpc_bitstream_outalign(bout, 0x2a); } jpc_bitstream_close(bout); bout = 0; pass->end = jas_stream_tell(cblk->stream); } else { pass->end = jas_stream_tell(cblk->stream) + jpc_bitstream_pending(bout); /* NOTE - This will not work. need to adjust by # of pending output bytes */ } } #if 0 /* XXX - This assertion fails sometimes when various coding modes are used. This seems to be harmless, but why does it happen at all? */ assert(jas_stream_tell(cblk->stream) == jas_stream_getrwcount(cblk->stream)); #endif pass->wmsedec = jpc_fixtodbl(band->rlvl->tcmpt->synweight) * jpc_fixtodbl(band->rlvl->tcmpt->synweight) * jpc_fixtodbl(band->synweight) * jpc_fixtodbl(band->synweight) * jpc_fixtodbl(band->absstepsize) * jpc_fixtodbl(band->absstepsize) * ((double) (1 << bitpos)) * ((double)(1 << bitpos)) * jpc_fixtodbl(pass->nmsedec); pass->cumwmsedec = pass->wmsedec; if (pass != cblk->passes) { pass->cumwmsedec += pass[-1].cumwmsedec; } if (passtype == JPC_CLNPASS) { --bitpos; } ++pass; } #if 0 dump_passes(cblk->passes, cblk->numpasses, cblk); #endif n = 0; endpasses = &cblk->passes[cblk->numpasses]; for (pass = cblk->passes; pass != endpasses; ++pass) { if (pass->start < n) { pass->start = n; } if (pass->end < n) { pass->end = n; } if (!pass->term) { termpass = pass; while (termpass - pass < cblk->numpasses && !termpass->term) { ++termpass; } if (pass->type == JPC_SEG_MQ) { t = (pass->mqencstate.lastbyte == 0xff) ? 1 : 0; if (pass->mqencstate.ctreg >= 5) { adjust = 4 + t; } else { adjust = 5 + t; } pass->end += adjust; } if (pass->end > termpass->end) { pass->end = termpass->end; } if ((c = getthebyte(cblk->stream, pass->end - 1)) == EOF) { abort(); } if (c == 0xff) { ++pass->end; } n = JAS_MAX(n, pass->end); } else { n = JAS_MAX(n, pass->end); } } #if 0 dump_passes(cblk->passes, cblk->numpasses, cblk); #endif if (bout) { jpc_bitstream_close(bout); } return 0; }
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; }
int main(int argc, char **argv) { jas_image_t *image; cmdopts_t *cmdopts; jas_stream_t *in; jas_stream_t *out; jas_tmr_t dectmr; jas_tmr_t enctmr; double dectime; double 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()) { abort(); } /* Parse the command line options. */ if (!(cmdopts = cmdopts_parse(argc, argv))) { fprintf(stderr, "error: cannot parse command line\n"); exit(EXIT_FAILURE); } if (cmdopts->version) { printf("%s\n", JAS_VERSION); fprintf(stderr, "libjasper %s\n", jas_getversion()); exit(EXIT_SUCCESS); } jas_setdbglevel(cmdopts->debug); if (cmdopts->verbose) { cmdinfo(); } #ifndef _GEM /* 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"))) { fprintf(stderr, "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"))) { fprintf(stderr, "error: cannot open standard input\n"); exit(EXIT_FAILURE); } } #else if (!(in = jas_stream_memopen(input_file, INPUT_FILE_LEN))) { fprintf(stderr, "error: cannot read hardcoded image buffer\n"); exit(EXIT_FAILURE); } #endif /* 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"))) { fprintf(stderr, "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"))) { fprintf(stderr, "error: cannot open standard output\n"); exit(EXIT_FAILURE); } } if (cmdopts->infmt < 0) { if ((cmdopts->infmt = jas_image_getfmt(in)) < 0) { fprintf(stderr, "error: input image has unknown format\n"); exit(EXIT_FAILURE); } } /* Get the input image data. */ jas_tmr_start(&dectmr); if (!(image = jas_image_decode(in, cmdopts->infmt, cmdopts->inopts))) { fprintf(stderr, "error: cannot load image data\n"); exit(EXIT_FAILURE); } jas_tmr_stop(&dectmr); dectime = jas_tmr_get(&dectmr); /* 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. */ jas_tmr_start(&enctmr); if (jas_image_encode(image, out, cmdopts->outfmt, cmdopts->outopts)) { fprintf(stderr, "error: cannot encode image\n"); exit(EXIT_FAILURE); } jas_stream_flush(out); jas_tmr_stop(&enctmr); enctime = jas_tmr_get(&enctmr); if (cmdopts->verbose) { fprintf(stderr, "decoding time = %f\n", dectime); fprintf(stderr, "encoding time = %f\n", enctime); } /* If this fails, we don't care. */ (void) jas_stream_close(in); /* Close the output image stream. */ if (jas_stream_close(out)) { fprintf(stderr, "error: cannot close output image file\n"); exit(EXIT_FAILURE); } cmdopts_destroy(cmdopts); jas_image_destroy(image); jas_image_clearfmts(); /* Success at last! :-) */ return EXIT_SUCCESS; }
static 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 dec_jpeg2000(char *injpc,g2int bufsize,g2int *outfld) /*$$$ SUBPROGRAM DOCUMENTATION BLOCK * . . . . * SUBPROGRAM: dec_jpeg2000 Decodes JPEG2000 code stream * PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-12-02 * * ABSTRACT: This Function decodes a JPEG2000 code stream specified in the * JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) using JasPer * Software version 1.500.4 (or 1.700.2) written by the University of British * Columbia and Image Power Inc, and others. * JasPer is available at http://www.ece.uvic.ca/~mdadams/jasper/. * * PROGRAM HISTORY LOG: * 2002-12-02 Gilbert * * USAGE: int dec_jpeg2000(char *injpc,g2int bufsize,g2int *outfld) * * INPUT ARGUMENTS: * injpc - Input JPEG2000 code stream. * bufsize - Length (in bytes) of the input JPEG2000 code stream. * * OUTPUT ARGUMENTS: * outfld - Output matrix of grayscale image values. * * RETURN VALUES : * 0 = Successful decode * -3 = Error decode jpeg2000 code stream. * -5 = decoded image had multiple color components. * Only grayscale is expected. * * REMARKS: * * Requires JasPer Software version 1.500.4 or 1.700.2 * * ATTRIBUTES: * LANGUAGE: C * MACHINE: IBM SP * *$$$*/ { int ier; g2int i,j,k; jas_image_t *image=0; jas_stream_t *jpcstream; jas_image_cmpt_t *pcmpt; char *opts=0; jas_matrix_t *data; /* jas_init();*/ ier=0; /* // Create jas_stream_t containing input JPEG200 codestream in memory. */ jpcstream=jas_stream_memopen(injpc,bufsize); /* // Decode JPEG200 codestream into jas_image_t structure. */ image=jpc_decode(jpcstream,opts); if ( image == 0 ) { printf(" jpc_decode return = %d \n",ier); return -3; } pcmpt=image->cmpts_[0]; /* printf(" SAGOUT DECODE:\n"); printf(" tlx %d \n",image->tlx_); printf(" tly %d \n",image->tly_); printf(" brx %d \n",image->brx_); printf(" bry %d \n",image->bry_); printf(" numcmpts %d \n",image->numcmpts_); printf(" maxcmpts %d \n",image->maxcmpts_); #ifdef JAS_1_500_4 printf(" colormodel %d \n",image->colormodel_); #endif #ifdef JAS_1_700_2 printf(" colorspace %d \n",image->clrspc_); #endif printf(" inmem %d \n",image->inmem_); printf(" COMPONENT:\n"); printf(" tlx %d \n",pcmpt->tlx_); printf(" tly %d \n",pcmpt->tly_); printf(" hstep %d \n",pcmpt->hstep_); printf(" vstep %d \n",pcmpt->vstep_); printf(" width %d \n",pcmpt->width_); printf(" height %d \n",pcmpt->height_); printf(" prec %d \n",pcmpt->prec_); printf(" sgnd %d \n",pcmpt->sgnd_); printf(" cps %d \n",pcmpt->cps_); #ifdef JAS_1_700_2 printf(" type %d \n",pcmpt->type_); #endif */ /* Expecting jpeg2000 image to be grayscale only. // No color components. */ if (image->numcmpts_ != 1 ) { printf("dec_jpeg2000: Found color image. Grayscale expected.\n"); return (-5); } /* // Create a data matrix of grayscale image values decoded from // the jpeg2000 codestream. */ data=jas_matrix_create(jas_image_height(image), jas_image_width(image)); jas_image_readcmpt(image,0,0,0,jas_image_width(image), jas_image_height(image),data); /* // Copy data matrix to output integer array. */ k=0; for (i=0;i<pcmpt->height_;i++) for (j=0;j<pcmpt->width_;j++) outfld[k++]=data->rows_[i][j]; /* // Clean up JasPer work structures. */ jas_matrix_destroy(data); ier=jas_stream_close(jpcstream); jas_image_destroy(image); return 0; }
static Image *ReadJP2Image(const ImageInfo *image_info,ExceptionInfo *exception) { Image *image; jas_cmprof_t *cm_profile; jas_iccprof_t *icc_profile; jas_image_t *jp2_image; jas_matrix_t *pixels[4]; jas_stream_t *jp2_stream; long components[4], y; MagickBooleanType status; QuantumAny pixel, *map[4], range; register long i, x; register PixelPacket *q; unsigned long maximum_component_depth, number_components, x_step[4], y_step[4]; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Initialize JPEG 2000 API. */ jp2_stream=JP2StreamManager(image); if (jp2_stream == (jas_stream_t *) NULL) ThrowReaderException(DelegateError,"UnableToManageJP2Stream"); jp2_image=jas_image_decode(jp2_stream,-1,0); if (jp2_image == (jas_image_t *) NULL) { (void) jas_stream_close(jp2_stream); ThrowReaderException(DelegateError,"UnableToDecodeImageFile"); } switch (jas_clrspc_fam(jas_image_clrspc(jp2_image))) { case JAS_CLRSPC_FAM_RGB: { components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_R); components[1]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_G); components[2]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_B); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=3; components[3]=jas_image_getcmptbytype(jp2_image,3); if (components[3] > 0) { image->matte=MagickTrue; number_components++; } break; } case JAS_CLRSPC_FAM_GRAY: { components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_GRAY_Y); if (components[0] < 0) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=1; break; } case JAS_CLRSPC_FAM_YCBCR: { components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_Y); components[1]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CB); components[2]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CR); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=3; components[3]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_UNKNOWN); if (components[3] > 0) { image->matte=MagickTrue; number_components++; } image->colorspace=YCbCrColorspace; break; } default: { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CoderError,"ColorspaceModelIsNotSupported"); } } image->columns=jas_image_width(jp2_image); image->rows=jas_image_height(jp2_image); image->compression=JPEG2000Compression; for (i=0; i < (long) number_components; i++) { unsigned long height, width; width=(unsigned long) (jas_image_cmptwidth(jp2_image,components[i])* jas_image_cmpthstep(jp2_image,components[i])); height=(unsigned long) (jas_image_cmptheight(jp2_image,components[i])* jas_image_cmptvstep(jp2_image,components[i])); x_step[i]=(unsigned int) jas_image_cmpthstep(jp2_image,components[i]); y_step[i]=(unsigned int) jas_image_cmptvstep(jp2_image,components[i]); if ((width != image->columns) || (height != image->rows) || (jas_image_cmpttlx(jp2_image,components[i]) != 0) || (jas_image_cmpttly(jp2_image,components[i]) != 0) || (x_step[i] != 1) || (y_step[i] != 1) || (jas_image_cmptsgnd(jp2_image,components[i]) != MagickFalse)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CoderError,"IrregularChannelGeometryNotSupported"); } } /* Convert JPEG 2000 pixels. */ image->matte=number_components > 3 ? MagickTrue : MagickFalse; maximum_component_depth=0; for (i=0; i < (long) number_components; i++) { maximum_component_depth=(unsigned int) MagickMax((size_t) jas_image_cmptprec(jp2_image,components[i]),(size_t) maximum_component_depth); pixels[i]=jas_matrix_create(1,(int) (image->columns/x_step[i])); if (pixels[i] == (jas_matrix_t *) NULL) { for (--i; i >= 0; i--) jas_matrix_destroy(pixels[i]); jas_image_destroy(jp2_image); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } } image->depth=maximum_component_depth; if (image_info->ping != MagickFalse) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); return(GetFirstImageInList(image)); } for (i=0; i < (long) number_components; i++) { long j; map[i]=(QuantumAny *) AcquireQuantumMemory(MaxMap+1,sizeof(**map)); if (map[i] == (QuantumAny *) NULL) { for (--i; i >= 0; i--) map[i]=(QuantumAny *) RelinquishMagickMemory(map[i]); for (i=0; i < (long) number_components; i++) jas_matrix_destroy(pixels[i]); jas_image_destroy(jp2_image); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } range=GetQuantumRange((unsigned long) jas_image_cmptprec(jp2_image, components[i])); for (j=0; j <= (long) MaxMap; j++) map[i][j]=ScaleQuantumToMap(ScaleAnyToQuantum((QuantumAny) j,range)); } for (y=0; y < (long) image->rows; y++) { q=GetAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (i=0; i < (long) number_components; i++) (void) jas_image_readcmpt(jp2_image,(short) components[i],0, ((unsigned int) y)/y_step[i],((unsigned int) image->columns)/x_step[i], 1,pixels[i]); switch (number_components) { case 1: { /* Grayscale. */ for (x=0; x < (long) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); q->red=(Quantum) map[0][pixel]; q->green=q->red; q->blue=q->red; q++; } break; } case 3: { /* RGB. */ for (x=0; x < (long) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); q->red=(Quantum) map[0][pixel]; pixel=(QuantumAny) jas_matrix_getv(pixels[1],x/x_step[1]); q->green=(Quantum) map[1][pixel]; pixel=(QuantumAny) jas_matrix_getv(pixels[2],x/x_step[2]); q->blue=(Quantum) map[2][pixel]; q++; } break; } case 4: { /* RGBA. */ for (x=0; x < (long) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); q->red=(Quantum) map[0][pixel]; pixel=(QuantumAny) jas_matrix_getv(pixels[1],x/x_step[1]); q->green=(Quantum) map[1][pixel]; pixel=(QuantumAny) jas_matrix_getv(pixels[2],x/x_step[2]); q->blue=(Quantum) map[2][pixel]; pixel=(QuantumAny) jas_matrix_getv(pixels[3],x/x_step[3]); q->opacity=(Quantum) (QuantumRange-map[3][pixel]); q++; } break; } } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; status=SetImageProgress(image,LoadImageTag,y,image->rows); if (status == MagickFalse) break; } for (i=0; i < (long) number_components; i++) map[i]=(QuantumAny *) RelinquishMagickMemory(map[i]); cm_profile=jas_image_cmprof(jp2_image); icc_profile=(jas_iccprof_t *) NULL; if (cm_profile != (jas_cmprof_t *) NULL) icc_profile=jas_iccprof_createfromcmprof(cm_profile); if (icc_profile != (jas_iccprof_t *) NULL) { jas_stream_t *icc_stream; icc_stream=jas_stream_memopen(NULL,0); if ((icc_stream != (jas_stream_t *) NULL) && (jas_iccprof_save(icc_profile,icc_stream) == 0) && (jas_stream_flush(icc_stream) == 0)) { StringInfo *icc_profile, *profile; jas_stream_memobj_t *blob; /* Extract the icc profile, handle errors without much noise. */ blob=(jas_stream_memobj_t *) icc_stream->obj_; if (image->debug != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Profile: ICC, %lu bytes",(unsigned long) blob->len_); profile=AcquireStringInfo(blob->len_); SetStringInfoDatum(profile,blob->buf_); icc_profile=(StringInfo *) GetImageProfile(image,"icc"); if (icc_profile == (StringInfo *) NULL) (void) SetImageProfile(image,"icc",profile); else (void) ConcatenateStringInfo(icc_profile,profile); profile=DestroyStringInfo(profile); (void) jas_stream_close(icc_stream); } } (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); for (i=0; i < (long) number_components; i++) jas_matrix_destroy(pixels[i]); return(GetFirstImageInList(image)); }
/* 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; }
int FROM_jpeg2000(char *injpc,int bufsize,unsigned int *outfld) /*$$$ SUBPROGRAM DOCUMENTATION BLOCK * . . . . * SUBPROGRAM: FROM_jpeg2000 Decodes JPEG2000 code stream * PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-12-02 * * ABSTRACT: This Function decodes a JPEG2000 code stream specified in the * JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) using JasPer * Software version 1.700.2 or better written by the University of British * Columbia and Image Power Inc, and others. * JasPer is available at http://www.ece.uvic.ca/~mdadams/jasper/. * * PROGRAM HISTORY LOG: * 2002-12-02 Gilbert * 2015-10-26 M.Valin - removed GRIB library connections, light refactoring, * changed function name * * USAGE: int FROM_jpeg2000(char *injpc,int bufsize,int *outfld) * * INPUT ARGUMENTS: * injpc - Input JPEG2000 code stream. * bufsize - Length (in bytes) of the input JPEG2000 code stream. * * OUTPUT ARGUMENTS: * outfld - Output matrix of grayscale image values. * * RETURN VALUES : * 0 = Successful decode * -3 = Error decode jpeg2000 code stream. * -5 = decoded image had multiple color components. * Only grayscale is allowed. * * REMARKS: * * Requires JasPer Software version 1.700.2 or better * * ATTRIBUTES: * LANGUAGE: C * OS: Linux * *$$$*/ { int ier; int i,j,k; jas_image_t *image=0; jas_stream_t *jpcstream; jas_image_cmpt_t *pcmpt; char *opts=0; jas_matrix_t *data; #define ROW unsigned long // ROW *my_row; unsigned int value; // jas_init(); ier=0; // // Create jas_stream_t containing input JPEG200 codestream in memory. // jpcstream=jas_stream_memopen(injpc,bufsize); // // Decode JPEG200 codestream into jas_image_t structure. // image=jpc_decode(jpcstream,opts); if ( image == 0 ) { printf(" jpc_decode return\n"); return -3; } pcmpt=image->cmpts_[0]; #if defined(DEBUG) printf(" SAGOUT DECODE:\n"); printf(" tlx %d \n",image->tlx_); printf(" tly %d \n",image->tly_); printf(" brx %d \n",image->brx_); printf(" bry %d \n",image->bry_); printf(" numcmpts %d \n",image->numcmpts_); printf(" maxcmpts %d \n",image->maxcmpts_); printf(" colorspace %d \n",image->clrspc_); printf(" inmem %d \n",image->inmem_); printf(" COMPONENT:\n"); printf(" tlx %d \n",pcmpt->tlx_); printf(" tly %d \n",pcmpt->tly_); printf(" hstep %d \n",pcmpt->hstep_); printf(" vstep %d \n",pcmpt->vstep_); printf(" width %d \n",pcmpt->width_); printf(" height %d \n",pcmpt->height_); printf(" prec %d \n",pcmpt->prec_); printf(" sgnd %d \n",pcmpt->sgnd_); printf(" cps %d \n",pcmpt->cps_); printf(" type %d \n",pcmpt->type_); #endif // Expecting jpeg2000 image to be grayscale only. // No color components. // if (image->numcmpts_ != 1 ) { printf("FROM_jpeg2000: Found color image. Grayscale expected.\n"); return (-5); } // // Create a data matrix of grayscale image values decoded from // the jpeg2000 codestream. // data=jas_matrix_create(jas_image_height(image), jas_image_width(image)); jas_image_readcmpt(image,0,0,0,jas_image_width(image), jas_image_height(image),data); // // Copy data matrix to output integer array. // k=0; // printf ("deltap = %d\n",data->rows_[1]-data->rows_[0]); for (i=0;i<pcmpt->height_;i++) { // my_row = (ROW *)data->rows_[i]; // printf ("p = %16p\n",my_row); for (j=0;j<pcmpt->width_;j++) { // value = my_row[j]; // outfld[k++] = my_row[j]; // printf ("%4ld ",my_row[j]); // printf ("%16.16x ",my_row[j]); outfld[k++]=data->rows_[i][j]; } // printf ("%d \n",k); } // // Clean up JasPer work structures. // jas_matrix_destroy(data); ier=jas_stream_close(jpcstream); jas_image_destroy(image); return 0; }
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 TO_jpeg2000(unsigned char *cin,int width,int height,int nbits, int ltype, float ratio, int retry, char *outjpc, int jpclen) /*$$$ SUBPROGRAM DOCUMENTATION BLOCK * . . . . * SUBPROGRAM: TO_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.700.2 or better 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. * 2015-10-26 M.Valin - removed GRIB library connections, light refactoring, * changed function name * * USAGE: int TO_jpeg2000(unsigned char *cin,int width,int height, * int nbits, int ltype, int ratio, * int retry, char *outjpc, int jpclen) * * INPUT ARGUMENTS: * cin - Packed matrix of Grayscale image values to encode. * (byte stream, MSB first, LSB last for each multibyte item) * 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 encoding jpeg2000 code stream. * * REMARKS: * * Requires JasPer Software version 1.700.2 or better * * ATTRIBUTES: * LANGUAGE: C * OS: Linux * *$$$*/ { 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(" TO_jpeg2000:width %ld\n",width); printf(" TO_jpeg2000:height %ld\n",height); printf(" TO_jpeg2000:nbits %ld\n",nbits); printf(" TO_jpeg2000:jpclen %ld\n",jpclen); */ // jas_init(); // // Set lossy compression options, if requested. // if ( ltype != 1 ) { opts[0]=(char)0; } else { // snprintf(opts,MAXOPTSSIZE,"mode=real\nrate=%f",1.0/(float)ratio); snprintf(opts,MAXOPTSSIZE,"mode=real\nrate=%f",1.0/ratio); fprintf(stderr,"using lossy compression\n"); } 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; image.brx_=(jas_image_coord_t)width; image.bry_=(jas_image_coord_t)height; image.numcmpts_=1; image.maxcmpts_=1; image.clrspc_=JAS_CLRSPC_SGRAY; /* grayscale Image */ image.cmprof_=0; image.inmem_=1; cmpt.tlx_=0; cmpt.tly_=0; cmpt.hstep_=1; cmpt.vstep_=1; 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); cmpt.prec_=nbits; cmpt.sgnd_=0; cmpt.cps_=(nbits+7)/8; pcmpt=&cmpt; image.cmpts_=&pcmpt; #if defined(DEBUG) printf(" SAGOUT ENCODE:\n"); printf(" tlx %d \n",image.tlx_); printf(" tly %d \n",image.tly_); printf(" brx %d \n",image.brx_); printf(" bry %d \n",image.bry_); printf(" numcmpts %d \n",image.numcmpts_); printf(" maxcmpts %d \n",image.maxcmpts_); printf(" colorspace %d \n",image.clrspc_); printf(" inmem %d \n",image.inmem_); printf(" COMPONENT:\n"); printf(" tlx %d \n",pcmpt->tlx_); printf(" tly %d \n",pcmpt->tly_); printf(" hstep %d \n",pcmpt->hstep_); printf(" vstep %d \n",pcmpt->vstep_); printf(" width %d \n",pcmpt->width_); printf(" height %d \n",pcmpt->height_); printf(" prec %d \n",pcmpt->prec_); printf(" sgnd %d \n",pcmpt->sgnd_); printf(" cps %d \n",pcmpt->cps_); printf(" type %d \n",pcmpt->type_); #endif // // 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 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); }
static Image *ReadJP2Image(const ImageInfo *image_info,ExceptionInfo *exception) { Image *image; jas_cmprof_t *cm_profile; jas_iccprof_t *icc_profile; jas_image_t *jp2_image; jas_matrix_t *pixels[4]; jas_stream_t *jp2_stream; MagickBooleanType status; QuantumAny pixel, range[4]; register Quantum *q; register ssize_t i, x; size_t maximum_component_depth, number_components, x_step[4], y_step[4]; ssize_t components[4], y; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info,exception); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Initialize JPEG 2000 API. */ jp2_stream=JP2StreamManager(image); if (jp2_stream == (jas_stream_t *) NULL) ThrowReaderException(DelegateError,"UnableToManageJP2Stream"); jp2_image=jas_image_decode(jp2_stream,-1,0); if (jp2_image == (jas_image_t *) NULL) { (void) jas_stream_close(jp2_stream); ThrowReaderException(DelegateError,"UnableToDecodeImageFile"); } image->columns=jas_image_width(jp2_image); image->rows=jas_image_height(jp2_image); image->compression=JPEG2000Compression; switch (jas_clrspc_fam(jas_image_clrspc(jp2_image))) { case JAS_CLRSPC_FAM_RGB: { SetImageColorspace(image,RGBColorspace,exception); components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_R); components[1]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_G); components[2]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_B); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=3; components[3]=jas_image_getcmptbytype(jp2_image,3); if (components[3] > 0) { image->alpha_trait=BlendPixelTrait; number_components++; } break; } case JAS_CLRSPC_FAM_GRAY: { SetImageColorspace(image,GRAYColorspace,exception); components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_GRAY_Y); if (components[0] < 0) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=1; break; } case JAS_CLRSPC_FAM_YCBCR: { SetImageColorspace(image,YCbCrColorspace,exception); components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_Y); components[1]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CB); components[2]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CR); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=3; components[3]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_UNKNOWN); if (components[3] > 0) { image->alpha_trait=BlendPixelTrait; number_components++; } break; } case JAS_CLRSPC_FAM_XYZ: { SetImageColorspace(image,XYZColorspace,exception); components[0]=jas_image_getcmptbytype(jp2_image,0); components[1]=jas_image_getcmptbytype(jp2_image,1); components[2]=jas_image_getcmptbytype(jp2_image,2); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=3; components[3]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_UNKNOWN); if (components[3] > 0) { image->alpha_trait=BlendPixelTrait; number_components++; } break; } case JAS_CLRSPC_FAM_LAB: { SetImageColorspace(image,LabColorspace,exception); components[0]=jas_image_getcmptbytype(jp2_image,0); components[1]=jas_image_getcmptbytype(jp2_image,1); components[2]=jas_image_getcmptbytype(jp2_image,2); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=3; components[3]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_UNKNOWN); if (components[3] > 0) { image->alpha_trait=BlendPixelTrait; number_components++; } break; } default: { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CoderError,"ColorspaceModelIsNotSupported"); } } for (i=0; i < (ssize_t) number_components; i++) { size_t height, width; width=(size_t) (jas_image_cmptwidth(jp2_image,components[i])* jas_image_cmpthstep(jp2_image,components[i])); height=(size_t) (jas_image_cmptheight(jp2_image,components[i])* jas_image_cmptvstep(jp2_image,components[i])); x_step[i]=(unsigned int) jas_image_cmpthstep(jp2_image,components[i]); y_step[i]=(unsigned int) jas_image_cmptvstep(jp2_image,components[i]); if ((width != image->columns) || (height != image->rows) || (jas_image_cmpttlx(jp2_image,components[i]) != 0) || (jas_image_cmpttly(jp2_image,components[i]) != 0) || (jas_image_cmptsgnd(jp2_image,components[i]) != MagickFalse)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CoderError,"IrregularChannelGeometryNotSupported"); } } /* Convert JPEG 2000 pixels. */ image->alpha_trait=number_components > 3 ? BlendPixelTrait : UndefinedPixelTrait; maximum_component_depth=0; for (i=0; i < (ssize_t) number_components; i++) { maximum_component_depth=(unsigned int) MagickMax((size_t) jas_image_cmptprec(jp2_image,components[i]),(size_t) maximum_component_depth); pixels[i]=jas_matrix_create(1,(int) (image->columns/x_step[i])); if (pixels[i] == (jas_matrix_t *) NULL) { for (--i; i >= 0; i--) jas_matrix_destroy(pixels[i]); jas_image_destroy(jp2_image); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } } image->depth=maximum_component_depth; if (image_info->ping != MagickFalse) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); return(GetFirstImageInList(image)); } for (i=0; i < (ssize_t) number_components; i++) range[i]=GetQuantumRange((size_t) jas_image_cmptprec(jp2_image, components[i])); for (y=0; y < (ssize_t) image->rows; y++) { q=GetAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (Quantum *) NULL) break; for (i=0; i < (ssize_t) number_components; i++) (void) jas_image_readcmpt(jp2_image,(short) components[i],0, (jas_image_coord_t) (y/y_step[i]),(jas_image_coord_t) (image->columns/ x_step[i]),1,pixels[i]); switch (number_components) { case 1: { /* Grayscale. */ for (x=0; x < (ssize_t) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); SetPixelGray(image,ScaleAnyToQuantum((QuantumAny) pixel,range[0]),q); q+=GetPixelChannels(image); } break; } case 3: { /* RGB. */ for (x=0; x < (ssize_t) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); SetPixelRed(image,ScaleAnyToQuantum((QuantumAny) pixel,range[0]),q); pixel=(QuantumAny) jas_matrix_getv(pixels[1],x/x_step[1]); SetPixelGreen(image,ScaleAnyToQuantum((QuantumAny) pixel,range[1]),q); pixel=(QuantumAny) jas_matrix_getv(pixels[2],x/x_step[2]); SetPixelBlue(image,ScaleAnyToQuantum((QuantumAny) pixel,range[2]),q); q+=GetPixelChannels(image); } break; } case 4: { /* RGBA. */ for (x=0; x < (ssize_t) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); SetPixelRed(image,ScaleAnyToQuantum((QuantumAny) pixel,range[0]),q); pixel=(QuantumAny) jas_matrix_getv(pixels[1],x/x_step[1]); SetPixelGreen(image,ScaleAnyToQuantum((QuantumAny) pixel,range[1]),q); pixel=(QuantumAny) jas_matrix_getv(pixels[2],x/x_step[2]); SetPixelBlue(image,ScaleAnyToQuantum((QuantumAny) pixel,range[2]),q); pixel=(QuantumAny) jas_matrix_getv(pixels[3],x/x_step[3]); SetPixelAlpha(image,ScaleAnyToQuantum((QuantumAny) pixel,range[3]),q); q+=GetPixelChannels(image); } break; } } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } cm_profile=jas_image_cmprof(jp2_image); icc_profile=(jas_iccprof_t *) NULL; if (cm_profile != (jas_cmprof_t *) NULL) icc_profile=jas_iccprof_createfromcmprof(cm_profile); if (icc_profile != (jas_iccprof_t *) NULL) { jas_stream_t *icc_stream; icc_stream=jas_stream_memopen(NULL,0); if ((icc_stream != (jas_stream_t *) NULL) && (jas_iccprof_save(icc_profile,icc_stream) == 0) && (jas_stream_flush(icc_stream) == 0)) { jas_stream_memobj_t *blob; StringInfo *icc_profile, *profile; /* Extract the icc profile, handle errors without much noise. */ blob=(jas_stream_memobj_t *) icc_stream->obj_; if (image->debug != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Profile: ICC, %.20g bytes",(double) blob->len_); profile=BlobToStringInfo(blob->buf_,blob->len_); if (profile == (StringInfo *) NULL) ThrowReaderException(CorruptImageError,"MemoryAllocationFailed"); icc_profile=(StringInfo *) GetImageProfile(image,"icc"); if (icc_profile == (StringInfo *) NULL) (void) SetImageProfile(image,"icc",profile,exception); else (void) ConcatenateStringInfo(icc_profile,profile); profile=DestroyStringInfo(profile); (void) jas_stream_close(icc_stream); } } (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); for (i=0; i < (ssize_t) number_components; i++) jas_matrix_destroy(pixels[i]); return(GetFirstImageInList(image)); }
int jp2_write_header(jas_image_t *image, jas_stream_t *out) { jp2_box_t *box; jp2_ftyp_t *ftyp; jp2_ihdr_t *ihdr; jas_stream_t *tmpstream; int allcmptssame; jp2_bpcc_t *bpcc; long len; uint_fast16_t cmptno; jp2_colr_t *colr; jp2_cdefchan_t *cdefchanent; jp2_cdef_t *cdef; int i; uint_fast32_t typeasoc; jas_iccprof_t *iccprof; jas_stream_t *iccstream; int pos; int needcdef; int prec; int sgnd; box = 0; tmpstream = 0; allcmptssame = 1; sgnd = jas_image_cmptsgnd(image, 0); prec = jas_image_cmptprec(image, 0); for (i = 1; i < jas_image_numcmpts(image); ++i) { if (jas_image_cmptsgnd(image, i) != sgnd || jas_image_cmptprec(image, i) != prec) { allcmptssame = 0; break; } } /* Output the signature box. */ if (!(box = jp2_box_create(JP2_BOX_JP))) { goto error; } box->data.jp.magic = JP2_JP_MAGIC; if (jp2_box_put(box, out)) { goto error; } jp2_box_destroy(box); box = 0; /* Output the file type box. */ if (!(box = jp2_box_create(JP2_BOX_FTYP))) { goto error; } ftyp = &box->data.ftyp; ftyp->majver = JP2_FTYP_MAJVER; ftyp->minver = JP2_FTYP_MINVER; ftyp->numcompatcodes = 1; ftyp->compatcodes[0] = JP2_FTYP_COMPATCODE; if (jp2_box_put(box, out)) { goto error; } jp2_box_destroy(box); box = 0; /* * Generate the data portion of the JP2 header box. * We cannot simply output the header for this box * since we do not yet know the correct value for the length * field. */ if (!(tmpstream = jas_stream_memopen(0, 0))) { goto error; } /* Generate image header box. */ if (!(box = jp2_box_create(JP2_BOX_IHDR))) { goto error; } ihdr = &box->data.ihdr; ihdr->width = jas_image_width(image); ihdr->height = jas_image_height(image); ihdr->numcmpts = jas_image_numcmpts(image); ihdr->bpc = allcmptssame ? JP2_SPTOBPC(jas_image_cmptsgnd(image, 0), jas_image_cmptprec(image, 0)) : JP2_IHDR_BPCNULL; ihdr->comptype = JP2_IHDR_COMPTYPE; ihdr->csunk = 0; ihdr->ipr = 0; if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; /* Generate bits per component box. */ if (!allcmptssame) { if (!(box = jp2_box_create(JP2_BOX_BPCC))) { goto error; } bpcc = &box->data.bpcc; bpcc->numcmpts = jas_image_numcmpts(image); if (!(bpcc->bpcs = jas_malloc(bpcc->numcmpts * sizeof(uint_fast8_t)))) { goto error; } for (cmptno = 0; cmptno < bpcc->numcmpts; ++cmptno) { bpcc->bpcs[cmptno] = JP2_SPTOBPC(jas_image_cmptsgnd(image, cmptno), jas_image_cmptprec(image, cmptno)); } if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; } /* Generate color specification box. */ if (!(box = jp2_box_create(JP2_BOX_COLR))) { goto error; } colr = &box->data.colr; switch (jas_image_clrspc(image)) { case JAS_CLRSPC_SRGB: case JAS_CLRSPC_SYCBCR: case JAS_CLRSPC_SGRAY: colr->method = JP2_COLR_ENUM; colr->csid = clrspctojp2(jas_image_clrspc(image)); colr->pri = JP2_COLR_PRI; colr->approx = 0; break; default: colr->method = JP2_COLR_ICC; colr->pri = JP2_COLR_PRI; colr->approx = 0; iccprof = jas_iccprof_createfromcmprof(jas_image_cmprof(image)); assert(iccprof); iccstream = jas_stream_memopen(0, 0); assert(iccstream); if (jas_iccprof_save(iccprof, iccstream)) abort(); if ((pos = jas_stream_tell(iccstream)) < 0) abort(); colr->iccplen = pos; colr->iccp = jas_malloc(pos); assert(colr->iccp); jas_stream_rewind(iccstream); if (jas_stream_read(iccstream, colr->iccp, colr->iccplen) != colr->iccplen) abort(); jas_stream_close(iccstream); jas_iccprof_destroy(iccprof); break; } if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; needcdef = 1; switch (jas_clrspc_fam(jas_image_clrspc(image))) { case JAS_CLRSPC_FAM_RGB: if (jas_image_cmpttype(image, 0) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R) && jas_image_cmpttype(image, 1) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G) && jas_image_cmpttype(image, 2) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B)) needcdef = 0; break; case JAS_CLRSPC_FAM_YCBCR: if (jas_image_cmpttype(image, 0) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_Y) && jas_image_cmpttype(image, 1) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CB) && jas_image_cmpttype(image, 2) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CR)) needcdef = 0; break; case JAS_CLRSPC_FAM_GRAY: if (jas_image_cmpttype(image, 0) == JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y)) needcdef = 0; break; default: abort(); break; } if (needcdef) { if (!(box = jp2_box_create(JP2_BOX_CDEF))) { goto error; } cdef = &box->data.cdef; cdef->numchans = jas_image_numcmpts(image); cdef->ents = jas_malloc(cdef->numchans * sizeof(jp2_cdefchan_t)); for (i = 0; i < jas_image_numcmpts(image); ++i) { cdefchanent = &cdef->ents[i]; cdefchanent->channo = i; typeasoc = jp2_gettypeasoc(jas_image_clrspc(image), jas_image_cmpttype(image, i)); cdefchanent->type = typeasoc >> 16; cdefchanent->assoc = typeasoc & 0x7fff; } if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; } /* Determine the total length of the JP2 header box. */ len = jas_stream_tell(tmpstream); jas_stream_rewind(tmpstream); /* * Output the JP2 header box and all of the boxes which it contains. */ if (!(box = jp2_box_create(JP2_BOX_JP2H))) { goto error; } box->len = len + JP2_BOX_HDRLEN; if (jp2_box_put(box, out)) { goto error; } jp2_box_destroy(box); box = 0; if (jas_stream_copy(out, tmpstream, len)) { goto error; } jas_stream_close(tmpstream); tmpstream = 0; return 0; abort(); error: if (box) { jp2_box_destroy(box); } if (tmpstream) { jas_stream_close(tmpstream); } return -1; }
int 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; }