Пример #1
0
bool jasperConvert(jas_image_t* &image, jas_stream_t* &out, const char* data, unsigned size, int outfmt, const char* outopts)
{
	jas_stream_t *in;

	// kDebug(YAHOO_RAW_DEBUG) << "Got data - size=" << size;

	if(!(in = jas_stream_memopen(const_cast<char*>(data), size)))
	{
		kDebug(YAHOO_RAW_DEBUG) << "Could not open jasper input stream";
		return false;
	}

	int infmt;
	infmt = jas_image_getfmt(in);

	if (infmt < 0)
	{
		jas_stream_close(in);
		kDebug(YAHOO_RAW_DEBUG) << "Failed to recognize input webcam image format";
		return false;
	}

	if (!(image = jas_image_decode(in, infmt, 0)))
	{
		kDebug(YAHOO_RAW_DEBUG) << "Unable to decode image";
		jas_stream_close(in);
		return false;
	}
	/* kDebug(YAHOO_RAW_DEBUG) << "jasper: decoded image: " << jas_image_width(image) << "x" << jas_image_height(image) << " bytes: " <<
		jas_image_rawsize(image) << " components:" << jas_image_numcmpts(image);
	*/

	char* out_img = NULL;
	if(!(out = jas_stream_memopen(out_img, 0)))
	{
		kDebug(YAHOO_RAW_DEBUG) << "Could not open output stream";
		jas_stream_close(in);
		return false;
	}

	if (jas_image_encode(image, out, outfmt, const_cast<char*>(outopts)))
	{
		kDebug(YAHOO_RAW_DEBUG) << "Unable to convert image";
		jas_stream_close(in);
		jas_stream_close(out);
		jas_image_destroy(image);
		return false;
	}
	jas_stream_flush(out);
	jas_stream_close(in);
	return true;
}
Пример #2
0
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);
}
Пример #3
0
//! 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;
}
Пример #4
0
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;
}
Пример #5
0
/* 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;
}
Пример #6
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;
   }
}
Пример #7
0
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);
}
Пример #8
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
}
Пример #9
0
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;
  }
}
Пример #10
0
/* 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 {
Пример #11
0
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;
}
Пример #12
0
/* 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;
}
Пример #13
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;
}
Пример #14
0
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;
}
Пример #15
0
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);
}
Пример #16
0
   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;

}
Пример #17
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));
}
Пример #18
0
/* 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;
}
Пример #19
0
   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;

}
Пример #20
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;
    }
}
Пример #21
0
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);

}
Пример #22
0
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);

}
Пример #23
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;

  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));
}
Пример #24
0
int jp2_write_header(jas_image_t *image, jas_stream_t *out)
{
	jp2_box_t *box;
	jp2_ftyp_t *ftyp;
	jp2_ihdr_t *ihdr;
	jas_stream_t *tmpstream;
	int allcmptssame;
	jp2_bpcc_t *bpcc;
	long len;
	uint_fast16_t cmptno;
	jp2_colr_t *colr;
	jp2_cdefchan_t *cdefchanent;
	jp2_cdef_t *cdef;
	int i;
	uint_fast32_t typeasoc;
jas_iccprof_t *iccprof;
jas_stream_t *iccstream;
int pos;
int needcdef;
int prec;
int sgnd;

	box = 0;
	tmpstream = 0;

	allcmptssame = 1;
	sgnd = jas_image_cmptsgnd(image, 0);
	prec = jas_image_cmptprec(image, 0);
	for (i = 1; i < jas_image_numcmpts(image); ++i) {
		if (jas_image_cmptsgnd(image, i) != sgnd ||
		  jas_image_cmptprec(image, i) != prec) {
			allcmptssame = 0;
			break;
		}
	}

	/* Output the signature box. */

	if (!(box = jp2_box_create(JP2_BOX_JP))) {
		goto error;
	}
	box->data.jp.magic = JP2_JP_MAGIC;
	if (jp2_box_put(box, out)) {
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	/* Output the file type box. */

	if (!(box = jp2_box_create(JP2_BOX_FTYP))) {
		goto error;
	}
	ftyp = &box->data.ftyp;
	ftyp->majver = JP2_FTYP_MAJVER;
	ftyp->minver = JP2_FTYP_MINVER;
	ftyp->numcompatcodes = 1;
	ftyp->compatcodes[0] = JP2_FTYP_COMPATCODE;
	if (jp2_box_put(box, out)) {
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	/*
	 * Generate the data portion of the JP2 header box.
	 * We cannot simply output the header for this box
	 * since we do not yet know the correct value for the length
	 * field.
	 */

	if (!(tmpstream = jas_stream_memopen(0, 0))) {
		goto error;
	}

	/* Generate image header box. */

	if (!(box = jp2_box_create(JP2_BOX_IHDR))) {
		goto error;
	}
	ihdr = &box->data.ihdr;
	ihdr->width = jas_image_width(image);
	ihdr->height = jas_image_height(image);
	ihdr->numcmpts = jas_image_numcmpts(image);
	ihdr->bpc = allcmptssame ? JP2_SPTOBPC(jas_image_cmptsgnd(image, 0),
	  jas_image_cmptprec(image, 0)) : JP2_IHDR_BPCNULL;
	ihdr->comptype = JP2_IHDR_COMPTYPE;
	ihdr->csunk = 0;
	ihdr->ipr = 0;
	if (jp2_box_put(box, tmpstream)) {
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	/* Generate bits per component box. */

	if (!allcmptssame) {
		if (!(box = jp2_box_create(JP2_BOX_BPCC))) {
			goto error;
		}
		bpcc = &box->data.bpcc;
		bpcc->numcmpts = jas_image_numcmpts(image);
		if (!(bpcc->bpcs = jas_malloc(bpcc->numcmpts *
		  sizeof(uint_fast8_t)))) {
			goto error;
		}
		for (cmptno = 0; cmptno < bpcc->numcmpts; ++cmptno) {
			bpcc->bpcs[cmptno] = JP2_SPTOBPC(jas_image_cmptsgnd(image,
			  cmptno), jas_image_cmptprec(image, cmptno));
		}
		if (jp2_box_put(box, tmpstream)) {
			goto error;
		}
		jp2_box_destroy(box);
		box = 0;
	}

	/* Generate color specification box. */

	if (!(box = jp2_box_create(JP2_BOX_COLR))) {
		goto error;
	}
	colr = &box->data.colr;
	switch (jas_image_clrspc(image)) {
	case JAS_CLRSPC_SRGB:
	case JAS_CLRSPC_SYCBCR:
	case JAS_CLRSPC_SGRAY:
		colr->method = JP2_COLR_ENUM;
		colr->csid = clrspctojp2(jas_image_clrspc(image));
		colr->pri = JP2_COLR_PRI;
		colr->approx = 0;
		break;
	default:
		colr->method = JP2_COLR_ICC;
		colr->pri = JP2_COLR_PRI;
		colr->approx = 0;
		iccprof = jas_iccprof_createfromcmprof(jas_image_cmprof(image));
		assert(iccprof);
		iccstream = jas_stream_memopen(0, 0);
		assert(iccstream);
		if (jas_iccprof_save(iccprof, iccstream))
			abort();
		if ((pos = jas_stream_tell(iccstream)) < 0)
			abort();
		colr->iccplen = pos;
		colr->iccp = jas_malloc(pos);
		assert(colr->iccp);
		jas_stream_rewind(iccstream);
		if (jas_stream_read(iccstream, colr->iccp, colr->iccplen) != colr->iccplen)
			abort();
		jas_stream_close(iccstream);
		jas_iccprof_destroy(iccprof);
		break;
	}
	if (jp2_box_put(box, tmpstream)) {
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	needcdef = 1;
	switch (jas_clrspc_fam(jas_image_clrspc(image))) {
	case JAS_CLRSPC_FAM_RGB:
		if (jas_image_cmpttype(image, 0) ==
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R) &&
		  jas_image_cmpttype(image, 1) ==
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G) &&
		  jas_image_cmpttype(image, 2) ==
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B))
			needcdef = 0;
		break;
	case JAS_CLRSPC_FAM_YCBCR:
		if (jas_image_cmpttype(image, 0) ==
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_Y) &&
		  jas_image_cmpttype(image, 1) ==
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CB) &&
		  jas_image_cmpttype(image, 2) ==
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CR))
			needcdef = 0;
		break;
	case JAS_CLRSPC_FAM_GRAY:
		if (jas_image_cmpttype(image, 0) ==
		  JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y))
			needcdef = 0;
		break;
	default:
		abort();
		break;
	}

	if (needcdef) {
		if (!(box = jp2_box_create(JP2_BOX_CDEF))) {
			goto error;
		}
		cdef = &box->data.cdef;
		cdef->numchans = jas_image_numcmpts(image);
		cdef->ents = jas_malloc(cdef->numchans * sizeof(jp2_cdefchan_t));
		for (i = 0; i < jas_image_numcmpts(image); ++i) {
			cdefchanent = &cdef->ents[i];
			cdefchanent->channo = i;
			typeasoc = jp2_gettypeasoc(jas_image_clrspc(image), jas_image_cmpttype(image, i));
			cdefchanent->type = typeasoc >> 16;
			cdefchanent->assoc = typeasoc & 0x7fff;
		}
		if (jp2_box_put(box, tmpstream)) {
			goto error;
		}
		jp2_box_destroy(box);
		box = 0;
	}

	/* Determine the total length of the JP2 header box. */

	len = jas_stream_tell(tmpstream);
	jas_stream_rewind(tmpstream);

	/*
	 * Output the JP2 header box and all of the boxes which it contains.
	 */

	if (!(box = jp2_box_create(JP2_BOX_JP2H))) {
		goto error;
	}
	box->len = len + JP2_BOX_HDRLEN;
	if (jp2_box_put(box, out)) {
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	if (jas_stream_copy(out, tmpstream, len)) {
		goto error;
	}

	jas_stream_close(tmpstream);
	tmpstream = 0;

	return 0;
	abort();

error:

	if (box) {
		jp2_box_destroy(box);
	}
	if (tmpstream) {
		jas_stream_close(tmpstream);
	}
	return -1;
}
Пример #25
0
int jp2_encode(jas_image_t *image, jas_stream_t *out, char *optstr)
{
	jp2_box_t *box;
	jp2_ftyp_t *ftyp;
	jp2_ihdr_t *ihdr;
	jas_stream_t *tmpstream;
	int allcmptssame;
	jp2_bpcc_t *bpcc;
	long len;
	uint_fast16_t cmptno;
	jp2_colr_t *colr;
	char buf[4096];
	uint_fast32_t overhead;
	jp2_cdefchan_t *cdefchanent;
	jp2_cdef_t *cdef;
	int i;
	uint_fast32_t typeasoc;

	box = 0;
	tmpstream = 0;

	/* Output the signature box. */

	if (!(box = jp2_box_create(JP2_BOX_JP))) {
		goto error;
	}
	box->data.jp.magic = JP2_JP_MAGIC;
	if (jp2_box_put(box, out)) {
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	/* Output the file type box. */

	if (!(box = jp2_box_create(JP2_BOX_FTYP))) {
		goto error;
	}
	ftyp = &box->data.ftyp;
	ftyp->majver = JP2_FTYP_MAJVER;
	ftyp->minver = JP2_FTYP_MINVER;
	ftyp->numcompatcodes = 1;
	ftyp->compatcodes[0] = JP2_FTYP_COMPATCODE;
	if (jp2_box_put(box, out)) {
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	/*
	 * Generate the data portion of the JP2 header box.
	 * We cannot simply output the header for this box
	 * since we do not yet know the correct value for the length
	 * field.
	 */

	if (!(tmpstream = jas_stream_memopen(0, 0))) {
		goto error;
	}

	/* Generate image header box. */

	if (!(box = jp2_box_create(JP2_BOX_IHDR))) {
		goto error;
	}
	ihdr = &box->data.ihdr;
	ihdr->width = jas_image_width(image);
	ihdr->height = jas_image_height(image);
	ihdr->numcmpts = jas_image_numcmpts(image);
	allcmptssame = 0;
	ihdr->bpc = allcmptssame ? JP2_SPTOBPC(jas_image_cmptsgnd(image, 0),
	  jas_image_cmptprec(image, 0)) : JP2_IHDR_BPCNULL;
	ihdr->comptype = JP2_IHDR_COMPTYPE;
	ihdr->csunk = 0;
	ihdr->ipr = 0;
	if (jp2_box_put(box, tmpstream)) {
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	/* Generate bits per component box. */

	if (!allcmptssame) {
		if (!(box = jp2_box_create(JP2_BOX_BPCC))) {
			goto error;
		}
		bpcc = &box->data.bpcc;
		bpcc->numcmpts = jas_image_numcmpts(image);
		if (!(bpcc->bpcs = jas_malloc(bpcc->numcmpts *
		  sizeof(uint_fast8_t)))) {
			goto error;
		}
		for (cmptno = 0; cmptno < bpcc->numcmpts; ++cmptno) {
			bpcc->bpcs[cmptno] = JP2_SPTOBPC(jas_image_cmptsgnd(image,
			  cmptno), jas_image_cmptprec(image, cmptno));
		}
		if (jp2_box_put(box, tmpstream)) {
			goto error;
		}
		jp2_box_destroy(box);
		box = 0;
	}

	/* Generate color specification box. */

	if (!(box = jp2_box_create(JP2_BOX_COLR))) {
		goto error;
	}
	colr = &box->data.colr;
	colr->method = JP2_COLR_ENUM;
	colr->pri = JP2_COLR_PRI;
	colr->approx = 0;
	colr->csid = (jas_image_colorspace(image) == JAS_IMAGE_CS_RGB) ? JP2_COLR_SRGB :
	  JP2_COLR_SGRAY;
	if (jp2_box_put(box, tmpstream)) {
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	if (!(jas_image_colorspace(image) == JAS_IMAGE_CS_RGB &&
	  jas_image_numcmpts(image) == 3 &&
	  jas_image_getcmptbytype(image, 0) ==
	  JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_R) &&
	  jas_image_getcmptbytype(image, 1) ==
	  JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_G) &&
	  jas_image_getcmptbytype(image, 2) ==
	  JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_B)) &&
	  !(jas_image_colorspace(image) == JAS_IMAGE_CS_YCBCR &&
	  jas_image_numcmpts(image) != 3 &&
	  jas_image_getcmptbytype(image, 0) ==
	  JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_YCBCR_Y) &&
	  jas_image_getcmptbytype(image, 1) ==
	  JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_YCBCR_CB) &&
	  jas_image_getcmptbytype(image, 2) ==
	  JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_YCBCR_CR)) &&
	  !(jas_image_colorspace(image) == JAS_IMAGE_CS_GRAY &&
	  jas_image_numcmpts(image) == 1 &&
	  jas_image_getcmptbytype(image, 0) ==
	  JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y))) {

		if (!(box = jp2_box_create(JP2_BOX_CDEF))) {
			goto error;
		}
		cdef = &box->data.cdef;
		cdef->numchans = jas_image_numcmpts(image);
		cdef->ents = jas_malloc(cdef->numchans * sizeof(jp2_cdefchan_t));
		for (i = 0; i < jas_image_numcmpts(image); ++i) {
			cdefchanent = &cdef->ents[i];
			cdefchanent->channo = i;
			typeasoc = jp2_gettypeasoc(jas_image_colorspace(image), jas_image_cmpttype(image, i));
			cdefchanent->type = typeasoc >> 16;
			cdefchanent->assoc = typeasoc & 0x7fff;
		}
		jp2_box_destroy(box);
		box = 0;
	}

	/* Determine the total length of the JP2 header box. */

	len = jas_stream_tell(tmpstream);
	jas_stream_rewind(tmpstream);

	/*
	 * Output the JP2 header box and all of the boxes which it contains.
	 */

	if (!(box = jp2_box_create(JP2_BOX_JP2H))) {
		goto error;
	}
	box->len = len + JP2_BOX_HDRLEN;
	if (jp2_box_put(box, out)) {
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	if (jas_stream_copy(out, tmpstream, len)) {
		goto error;
	}

	jas_stream_close(tmpstream);
	tmpstream = 0;

	/*
	 * Output the contiguous code stream box.
	 */

	if (!(box = jp2_box_create(JP2_BOX_JP2C))) {
		goto error;
	}
	box->len = 0;
	if (jp2_box_put(box, out)) {
		goto error;
	}
	jp2_box_destroy(box);
	box = 0;

	/* Output the JPEG-2000 code stream. */

	overhead = jas_stream_getrwcount(out);
	sprintf(buf, "%s\n_jp2overhead=%lu\n", (optstr ? optstr : ""),
	  (unsigned long) overhead);

	if (jpc_encode(image, out, buf)) {
		goto error;
	}

	return 0;
	abort();

error:

	if (box) {
		jp2_box_destroy(box);
	}
	if (tmpstream) {
		jas_stream_close(tmpstream);
	}
	return -1;
}