Beispiel #1
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;

}
Beispiel #2
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));
}
Beispiel #3
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;
}
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 );

    // 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
}
Beispiel #5
0
static int loadimage()
{
	int reshapeflag;
	jas_stream_t *in;
	int scrnwidth;
	int scrnheight;
	int vh;
	int vw;
	char *pathname;
	jas_cmprof_t *outprof;

	assert(!gs.image);
	assert(!gs.altimage);

	gs.image = 0;
	gs.altimage = 0;

	pathname = cmdopts.filenames[gs.filenum];

	if (pathname && pathname[0] != '\0') {
#if 1
	jas_eprintf("opening %s\n", pathname);
#endif
		/* The input image is to be read from a file. */
		if (!(in = jas_stream_fopen(pathname, "rb"))) {
			jas_eprintf("error: cannot open file %s\n", pathname);
			goto error;
		}
	} else {
		/* The input image is to be read from standard input. */
		in = streamin;
	}

	/* Get the input image data. */
	if (!(gs.image = jas_image_decode(in, -1, 0))) {
		jas_eprintf("error: cannot load image data\n");
		goto error;
	}

	/* Close the input stream. */
	if (in != streamin) {
		jas_stream_close(in);
	}

	if (!(outprof = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB)))
		goto error;
	if (!(gs.altimage = jas_image_chclrspc(gs.image, outprof, JAS_CMXFORM_INTENT_PER)))
		goto error;

	if ((scrnwidth = glutGet(GLUT_SCREEN_WIDTH)) < 0) {
		scrnwidth = 256;
	}
	if ((scrnheight = glutGet(GLUT_SCREEN_HEIGHT)) < 0) {
		scrnheight = 256;
	}

	vw = min(jas_image_width(gs.image), 0.95 * scrnwidth);
	vh = min(jas_image_height(gs.image), 0.95 * scrnheight);

	gs.vcx = (jas_image_tlx(gs.image) + jas_image_brx(gs.image)) / 2.0;
	gs.vcy = (jas_image_tly(gs.image) + jas_image_bry(gs.image)) / 2.0;
	gs.sx = 1.0;
	gs.sy = 1.0;
	if (gs.altimage) {
		gs.monomode = 0;
	} else {
		gs.monomode = 1;
		gs.cmptno = 0;
	}

#if 1
	jas_eprintf("num of components %d\n", jas_image_numcmpts(gs.image));
#endif

	if (vw < jas_image_width(gs.image)) {
		gs.sx = jas_image_width(gs.image) / ((float) vw);
	}
	if (vh < jas_image_height(gs.image)) {
		gs.sy = jas_image_height(gs.image) / ((float) vh);
	}
	if (gs.sx > gs.sy) {
		gs.sy = gs.sx;
	} else if (gs.sx < gs.sy) {
		gs.sx = gs.sy;
	}
	vw = jas_image_width(gs.image) / gs.sx;
	vh = jas_image_height(gs.image) / gs.sy;
	gs.dirty = 1;

	reshapeflag = 0;
	if (vw != glutGet(GLUT_WINDOW_WIDTH) ||
	  vh != glutGet(GLUT_WINDOW_HEIGHT)) {
		glutReshapeWindow(vw, vh);
		reshapeflag = 1;
	}
	if (cmdopts.title) {
		glutSetWindowTitle(cmdopts.title);
	} else {
		glutSetWindowTitle((pathname && pathname[0] != '\0') ? pathname :
		  "stdin");
	}
	/* If we reshaped the window, GLUT will automatically invoke both
	  the reshape and display callback (in this order).  Therefore, we
	  only need to explicitly force the display callback to be invoked
	  if the window was not reshaped. */
	if (!reshapeflag) {
		glutPostRedisplay();
	}

	if (cmdopts.tmout != 0) {
		glutTimerFunc(cmdopts.tmout, timer, gs.nexttmid);
		gs.activetmid = gs.nexttmid;
		++gs.nexttmid;
	}

	return 0;

error:
	unloadimage();
	return -1;
}
   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;

}
Beispiel #7
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));
}
Beispiel #8
0
static void special(int key, int x, int y)
{
	if (cmdopts.verbose) {
		jas_eprintf("special(%d, %d, %d)\n", key, x, y);
	}

	switch (key) {
	case GLUT_KEY_UP:
		{
			float oldvcy;
			float vh;
			float pan;
			if (gs.vp.height < jas_image_height(gs.image) / gs.sy) {
				pan = (glutGetModifiers() & GLUT_ACTIVE_SHIFT) ?
				  BIGPAN : SMALLPAN;
				oldvcy = gs.vcy;
				vh = gs.sy * gs.vp.height;
				gs.vcy = max(gs.vcy - pan * vh, jas_image_tly(gs.image) +
				  0.5 * vh);
				if (gs.vcy != oldvcy) {
					gs.dirty = 1;
					glutPostRedisplay();
				}
			}
		}
		break;
	case GLUT_KEY_DOWN:
		{
			float oldvcy;
			float vh;
			float pan;
			if (gs.vp.height < jas_image_height(gs.image) / gs.sy) {
				pan = (glutGetModifiers() & GLUT_ACTIVE_SHIFT) ?
				  BIGPAN : SMALLPAN;
				oldvcy = gs.vcy;
				vh = gs.sy * gs.vp.height;
				gs.vcy = min(gs.vcy + pan * vh, jas_image_bry(gs.image) -
				  0.5 * vh);
				if (gs.vcy != oldvcy) {
					gs.dirty = 1;
					glutPostRedisplay();
				}
			}
		}
		break;
	case GLUT_KEY_LEFT:
		{
			float oldvcx;
			float vw;
			float pan;
			if (gs.vp.width < jas_image_width(gs.image) / gs.sx) {
				pan = (glutGetModifiers() & GLUT_ACTIVE_SHIFT) ?
				  BIGPAN : SMALLPAN;
				oldvcx = gs.vcx;
				vw = gs.sx * gs.vp.width;
				gs.vcx = max(gs.vcx - pan * vw, jas_image_tlx(gs.image) +
				  0.5 * vw);
				if (gs.vcx != oldvcx) {
					gs.dirty = 1;
					glutPostRedisplay();
				}
			}
		}
		break;
	case GLUT_KEY_RIGHT:
		{
			float oldvcx;
			float vw;
			float pan;
			if (gs.vp.width < jas_image_width(gs.image) / gs.sx) {
				pan = (glutGetModifiers() & GLUT_ACTIVE_SHIFT) ?
				  BIGPAN : SMALLPAN;
				oldvcx = gs.vcx;
				vw = gs.sx * gs.vp.width;
				gs.vcx = min(gs.vcx + pan * vw, jas_image_brx(gs.image) -
				  0.5 * vw);
				if (gs.vcx != oldvcx) {
					gs.dirty = 1;
					glutPostRedisplay();
				}
			}
		}
		break;
	default:
		break;
	}
}
Beispiel #9
0
// Internal function used to load the Jpeg2000 stream.
ILboolean iLoadJp2Internal(jas_stream_t	*Stream, ILimage *Image)
{
	jas_image_t		*Jp2Image = NULL;
	jas_matrix_t	*origdata;
	ILint			x, y, c;
	ILimage			*TempImage;

	// Decode image
	Jp2Image = jas_image_decode(Stream, -1, 0);
	if (!Jp2Image)
	{
		ilSetError(IL_ILLEGAL_FILE_VALUE);
		jas_stream_close(Stream);
		return IL_FALSE;
	}

	// We're not supporting anything other than 8 bits/component yet.
	if (jas_image_cmptprec(Jp2Image, 0) != 8)
	{
		jas_image_destroy(Jp2Image);
		ilSetError(IL_ILLEGAL_FILE_VALUE);
		return IL_FALSE;
	}

	switch (jas_image_numcmpts(Jp2Image))
	{
		case 3:
			if (Image == NULL) {
				ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL);
				TempImage = iCurImage;
			}
			else {
				ifree(Image->Data);  // @TODO: Not really the most efficient way to do this...
				ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL);
				TempImage = Image;
			}
			break;
		case 4:
			if (Image == NULL) {
				ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);
				TempImage = iCurImage;
			}
			else {
				ifree(Image->Data);  // @TODO: Not really the most efficient way to do this...
				ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);
				TempImage = Image;
			}
			break;
		default:
			jas_image_destroy(Jp2Image);
			ilSetError(IL_ILLEGAL_FILE_VALUE);
			return IL_FALSE;
	}
	TempImage->Origin = IL_ORIGIN_UPPER_LEFT;

	// JasPer stores the data channels separately.
	//  I am assuming RGBA format.  Is it possible for other formats to be included?
	for (c = 0; c < TempImage->Bpp; c++)
	{
		origdata = jas_matrix_create(TempImage->Height, TempImage->Width);
		if (!origdata)
		{
			ilSetError(IL_LIB_JP2_ERROR);
			return IL_FALSE;  // @TODO: Error
		}
		// Have to convert data into an intermediate matrix format.
		if (jas_image_readcmpt(Jp2Image, c, 0, 0, TempImage->Width, TempImage->Height, origdata))
		{
			return IL_FALSE;
		}

		for (y = 0; y < TempImage->Height; y++)
		{
			for (x = 0; x < TempImage->Width; x++)
			{
				TempImage->Data[y * TempImage->Width * TempImage->Bpp + x * TempImage->Bpp + c] = origdata->data_[y * origdata->numcols_ + x];
			}
		}

		jas_matrix_destroy(origdata);
	}

	jas_image_destroy(Jp2Image);

	ilFixImage();

	return IL_TRUE;
}
Beispiel #10
0
static GstFlowReturn
gst_jasper_dec_negotiate (GstJasperDec * dec, jas_image_t * image)
{
  GstFlowReturn flow_ret = GST_FLOW_OK;
  gint width, height, channels;
  gint i, j;
  gboolean negotiate = FALSE;
  jas_clrspc_t clrspc;
  GstCaps *allowed_caps, *caps;

  width = jas_image_width (image);
  height = jas_image_height (image);
  channels = jas_image_numcmpts (image);

  GST_LOG_OBJECT (dec, "%d x %d, %d components", width, height, channels);

  /* jp2c bitstream has no real colour space info (kept in container),
   * so decoder may only pretend to know, where it really does not */
  if (!jas_clrspc_isunknown (dec->clrspc)) {
    clrspc = dec->clrspc;
    GST_DEBUG_OBJECT (dec, "forcing container supplied colour space %d",
        clrspc);
    jas_image_setclrspc (image, clrspc);
  } else
    clrspc = jas_image_clrspc (image);

  if (!width || !height || !channels || jas_clrspc_isunknown (clrspc))
    goto fail_image;

  if (dec->width != width || dec->height != height ||
      dec->channels != channels || dec->clrspc != clrspc)
    negotiate = TRUE;

  if (channels != 3)
    goto not_supported;

  for (i = 0; i < channels; i++) {
    gint cheight, cwidth, depth, sgnd;

    cheight = jas_image_cmptheight (image, i);
    cwidth = jas_image_cmptwidth (image, i);
    depth = jas_image_cmptprec (image, i);
    sgnd = jas_image_cmptsgnd (image, i);

    GST_LOG_OBJECT (dec, "image component %d, %dx%d, depth %d, sgnd %d", i,
        cwidth, cheight, depth, sgnd);

    if (depth != 8 || sgnd)
      goto not_supported;

    if (dec->cheight[i] != cheight || dec->cwidth[i] != cwidth) {
      dec->cheight[i] = cheight;
      dec->cwidth[i] = cwidth;
      negotiate = TRUE;
    }
  }

  if (!negotiate && dec->format != GST_VIDEO_FORMAT_UNKNOWN)
    goto done;

  /* clear and refresh to new state */
  flow_ret = GST_FLOW_NOT_NEGOTIATED;
  dec->format = GST_VIDEO_FORMAT_UNKNOWN;
  dec->width = width;
  dec->height = height;
  dec->channels = channels;

  /* retrieve allowed caps, and find the first one that reasonably maps
   * to the parameters of the colourspace */
  caps = gst_pad_get_allowed_caps (dec->srcpad);
  if (!caps) {
    GST_DEBUG_OBJECT (dec, "... but no peer, using template caps");
    /* need to copy because get_allowed_caps returns a ref,
       and get_pad_template_caps doesn't */
    caps = gst_caps_copy (gst_pad_get_pad_template_caps (dec->srcpad));
  }
  /* avoid lists of fourcc, etc */
  allowed_caps = gst_caps_normalize (caps);
  gst_caps_unref (caps);
  caps = NULL;
  GST_LOG_OBJECT (dec, "allowed source caps %" GST_PTR_FORMAT, allowed_caps);

  for (i = 0; i < gst_caps_get_size (allowed_caps); i++) {
    GstVideoFormat format;
    gboolean ok;

    if (caps)
      gst_caps_unref (caps);
    caps = gst_caps_copy_nth (allowed_caps, i);
    /* sigh, ds and _parse_caps need fixed caps for parsing, fixate */
    gst_pad_fixate_caps (dec->srcpad, caps);
    GST_LOG_OBJECT (dec, "checking caps %" GST_PTR_FORMAT, caps);
    if (!gst_video_format_parse_caps (caps, &format, NULL, NULL))
      continue;
    if (gst_video_format_is_rgb (format) &&
        jas_clrspc_fam (clrspc) == JAS_CLRSPC_FAM_RGB) {
      GST_DEBUG_OBJECT (dec, "trying RGB");
      if ((dec->cmpt[0] = jas_image_getcmptbytype (image,
                  JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_RGB_R))) < 0 ||
          (dec->cmpt[1] = jas_image_getcmptbytype (image,
                  JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_RGB_G))) < 0 ||
          (dec->cmpt[2] = jas_image_getcmptbytype (image,
                  JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_RGB_B))) < 0) {
        GST_DEBUG_OBJECT (dec, "missing RGB color component");
        continue;
      }
    } else if (gst_video_format_is_yuv (format) &&
        jas_clrspc_fam (clrspc) == JAS_CLRSPC_FAM_YCBCR) {
      GST_DEBUG_OBJECT (dec, "trying YUV");
      if ((dec->cmpt[0] = jas_image_getcmptbytype (image,
                  JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_YCBCR_Y))) < 0 ||
          (dec->cmpt[1] = jas_image_getcmptbytype (image,
                  JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_YCBCR_CB))) < 0 ||
          (dec->cmpt[2] = jas_image_getcmptbytype (image,
                  JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_YCBCR_CR))) < 0) {
        GST_DEBUG_OBJECT (dec, "missing YUV color component");
        continue;
      }
    } else
      continue;
    /* match format with validity checks */
    ok = TRUE;
    for (j = 0; j < channels; j++) {
      gint cmpt;

      cmpt = dec->cmpt[j];
      if (dec->cwidth[cmpt] != gst_video_format_get_component_width (format, j,
              width) ||
          dec->cheight[cmpt] != gst_video_format_get_component_height (format,
              j, height))
        ok = FALSE;
    }
    /* commit to this format */
    if (ok) {
      dec->format = format;
      break;
    }
  }

  if (caps)
    gst_caps_unref (caps);
  gst_caps_unref (allowed_caps);

  if (dec->format != GST_VIDEO_FORMAT_UNKNOWN) {
    /* cache some video format properties */
    for (j = 0; j < channels; ++j) {
      dec->offset[j] = gst_video_format_get_component_offset (dec->format, j,
          dec->width, dec->height);
      dec->inc[j] = gst_video_format_get_pixel_stride (dec->format, j);
      dec->stride[j] = gst_video_format_get_row_stride (dec->format, j,
          dec->width);
    }
    dec->image_size = gst_video_format_get_size (dec->format, width, height);
    dec->alpha = gst_video_format_has_alpha (dec->format);

    if (dec->buf)
      g_free (dec->buf);
    dec->buf = g_new0 (glong, dec->width);

    caps = gst_video_format_new_caps (dec->format, dec->width, dec->height,
        dec->framerate_numerator, dec->framerate_denominator, 1, 1);

    GST_DEBUG_OBJECT (dec, "Set format to %d, size to %dx%d", dec->format,
        dec->width, dec->height);

    if (!gst_pad_set_caps (dec->srcpad, caps))
      flow_ret = GST_FLOW_NOT_NEGOTIATED;
    else
      flow_ret = GST_FLOW_OK;

    gst_caps_unref (caps);
  }

done:
  return flow_ret;

  /* ERRORS */
fail_image:
  {
    GST_DEBUG_OBJECT (dec, "Failed to process decoded image.");
    flow_ret = GST_FLOW_NOT_NEGOTIATED;
    goto done;
  }
not_supported:
  {
    GST_DEBUG_OBJECT (dec, "Decoded image has unsupported colour space.");
    GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("Unsupported colorspace"));
    flow_ret = GST_FLOW_ERROR;
    goto done;
  }
}
Beispiel #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;
}
Beispiel #12
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_alloc2(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_alloc2(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(false);
    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;
}
Beispiel #13
0
// Internal function used to load the Jpeg2000 stream.
ILboolean iLoadJp2Internal(jas_stream_t	*Stream, ILimage *Image)
{
	jas_image_t		*Jp2Image = NULL;
	jas_matrix_t	*origdata;
	ILuint			x, y, c, Error;
	ILimage			*TempImage;

	// Decode image
	Jp2Image = jas_image_decode(Stream, -1, 0);
	if (!Jp2Image)
	{
		ilSetError(IL_ILLEGAL_FILE_VALUE);
		jas_stream_close(Stream);
		return IL_FALSE;
	}

	// JasPer likes to buffer a lot, so it may try buffering past the end
	//  of the file.  iread naturally sets IL_FILE_READ_ERROR if it tries
	//  reading past the end of the file, but this actually is not an error.
	Error = ilGetError();
	// Put the error back if it is not IL_FILE_READ_ERROR.
	if (Error != IL_FILE_READ_ERROR)
		ilSetError(Error);


	// We're not supporting anything other than 8 bits/component yet.
	if (jas_image_cmptprec(Jp2Image, 0) != 8)
	{
		jas_image_destroy(Jp2Image);
		ilSetError(IL_ILLEGAL_FILE_VALUE);
		return IL_FALSE;
	}

	switch (jas_image_numcmpts(Jp2Image))
	{
		//@TODO: Can we do alpha data?  jas_image_cmpttype always returns 0 for this case.
		case 1:  // Assuming this is luminance data.
			if (Image == NULL) {
				ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL);
				TempImage = iCurImage;
			}
			else {
				ifree(Image->Data);  // @TODO: Not really the most efficient way to do this...
				ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL);
				TempImage = Image;
			}
			break;

		case 2:  // Assuming this is luminance-alpha data.
			if (Image == NULL) {
				ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 2, IL_LUMINANCE_ALPHA, IL_UNSIGNED_BYTE, NULL);
				TempImage = iCurImage;
			}
			else {
				ifree(Image->Data);  // @TODO: Not really the most efficient way to do this...
				ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 2, IL_LUMINANCE_ALPHA, IL_UNSIGNED_BYTE, NULL);
				TempImage = Image;
			}
			break;

		case 3:
			if (Image == NULL) {
				ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL);
				TempImage = iCurImage;
			}
			else {
				ifree(Image->Data);  // @TODO: Not really the most efficient way to do this...
				ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL);
				TempImage = Image;
			}
			break;
		case 4:
			if (Image == NULL) {
				ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);
				TempImage = iCurImage;
			}
			else {
				ifree(Image->Data);  // @TODO: Not really the most efficient way to do this...
				ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);
				TempImage = Image;
			}
			break;
		default:
			jas_image_destroy(Jp2Image);
			ilSetError(IL_ILLEGAL_FILE_VALUE);
			return IL_FALSE;
	}
	TempImage->Origin = IL_ORIGIN_UPPER_LEFT;

	// JasPer stores the data channels separately.
	//  I am assuming RGBA format.  Is it possible for other formats to be included?
	for (c = 0; c < TempImage->Bpp; c++)
	{
		origdata = jas_matrix_create(TempImage->Height, TempImage->Width);
		if (!origdata)
		{
			ilSetError(IL_LIB_JP2_ERROR);
			return IL_FALSE;  // @TODO: Error
		}
		// Have to convert data into an intermediate matrix format.
		if (jas_image_readcmpt(Jp2Image, c, 0, 0, TempImage->Width, TempImage->Height, origdata))
		{
			return IL_FALSE;
		}

		for (y = 0; y < TempImage->Height; y++)
		{
			for (x = 0; x < TempImage->Width; x++)
			{
				TempImage->Data[y * TempImage->Width * TempImage->Bpp + x * TempImage->Bpp + c] = origdata->data_[y * origdata->numcols_ + x];
			}
		}

		jas_matrix_destroy(origdata);
	}

	jas_image_destroy(Jp2Image);

	return ilFixImage();
}