Exemple #1
0
static Image *ReadCINImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
#define MonoColorType  1
#define RGBColorType  3

    CINInfo
    cin;

    Image
    *image;

    MagickBooleanType
    status;

    MagickOffsetType
    offset;

    QuantumInfo
    *quantum_info;

    QuantumType
    quantum_type;

    register ssize_t
    i;

    register Quantum
    *q;

    size_t
    length;

    ssize_t
    count,
    y;

    unsigned char
    magick[4],
           *pixels;

    /*
      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);
    }
    /*
      File information.
    */
    offset=0;
    count=ReadBlob(image,4,magick);
    offset+=count;
    if ((count != 4) ||
            ((LocaleNCompare((char *) magick,"\200\052\137\327",4) != 0)))
        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    image->endian=(magick[0] == 0x80) && (magick[1] == 0x2a) &&
                  (magick[2] == 0x5f) && (magick[3] == 0xd7) ? MSBEndian : LSBEndian;
    cin.file.image_offset=ReadBlobLong(image);
    offset+=4;
    cin.file.generic_length=ReadBlobLong(image);
    offset+=4;
    cin.file.industry_length=ReadBlobLong(image);
    offset+=4;
    cin.file.user_length=ReadBlobLong(image);
    offset+=4;
    cin.file.file_size=ReadBlobLong(image);
    offset+=4;
    offset+=ReadBlob(image,sizeof(cin.file.version),(unsigned char *)
                     cin.file.version);
    (void) SetImageProperty(image,"dpx:file.version",cin.file.version,exception);
    offset+=ReadBlob(image,sizeof(cin.file.filename),(unsigned char *)
                     cin.file.filename);
    (void) SetImageProperty(image,"dpx:file.filename",cin.file.filename,
                            exception);
    offset+=ReadBlob(image,sizeof(cin.file.create_date),(unsigned char *)
                     cin.file.create_date);
    (void) SetImageProperty(image,"dpx:file.create_date",cin.file.create_date,
                            exception);
    offset+=ReadBlob(image,sizeof(cin.file.create_time),(unsigned char *)
                     cin.file.create_time);
    (void) SetImageProperty(image,"dpx:file.create_time",cin.file.create_time,
                            exception);
    offset+=ReadBlob(image,sizeof(cin.file.reserve),(unsigned char *)
                     cin.file.reserve);
    /*
      Image information.
    */
    cin.image.orientation=(unsigned char) ReadBlobByte(image);
    offset++;
    if (cin.image.orientation != (unsigned char) (~0U))
        (void) FormatImageProperty(image,"dpx:image.orientation","%d",
                                   cin.image.orientation);
    switch (cin.image.orientation)
    {
    default:
    case 0:
        image->orientation=TopLeftOrientation;
        break;
    case 1:
        image->orientation=TopRightOrientation;
        break;
    case 2:
        image->orientation=BottomLeftOrientation;
        break;
    case 3:
        image->orientation=BottomRightOrientation;
        break;
    case 4:
        image->orientation=LeftTopOrientation;
        break;
    case 5:
        image->orientation=RightTopOrientation;
        break;
    case 6:
        image->orientation=LeftBottomOrientation;
        break;
    case 7:
        image->orientation=RightBottomOrientation;
        break;
    }
    cin.image.number_channels=(unsigned char) ReadBlobByte(image);
    offset++;
    offset+=ReadBlob(image,sizeof(cin.image.reserve1),(unsigned char *)
                     cin.image.reserve1);
    for (i=0; i < 8; i++)
    {
        cin.image.channel[i].designator[0]=(unsigned char) ReadBlobByte(image);
        offset++;
        cin.image.channel[i].designator[1]=(unsigned char) ReadBlobByte(image);
        offset++;
        cin.image.channel[i].bits_per_pixel=(unsigned char) ReadBlobByte(image);
        offset++;
        cin.image.channel[i].reserve=(unsigned char) ReadBlobByte(image);
        offset++;
        cin.image.channel[i].pixels_per_line=ReadBlobLong(image);
        offset+=4;
        cin.image.channel[i].lines_per_image=ReadBlobLong(image);
        offset+=4;
        cin.image.channel[i].min_data=ReadBlobFloat(image);
        offset+=4;
        cin.image.channel[i].min_quantity=ReadBlobFloat(image);
        offset+=4;
        cin.image.channel[i].max_data=ReadBlobFloat(image);
        offset+=4;
        cin.image.channel[i].max_quantity=ReadBlobFloat(image);
        offset+=4;
    }
    cin.image.white_point[0]=ReadBlobFloat(image);
    offset+=4;
    if (IsFloatDefined(cin.image.white_point[0]) != MagickFalse)
        image->chromaticity.white_point.x=cin.image.white_point[0];
    cin.image.white_point[1]=ReadBlobFloat(image);
    offset+=4;
    if (IsFloatDefined(cin.image.white_point[1]) != MagickFalse)
        image->chromaticity.white_point.y=cin.image.white_point[1];
    cin.image.red_primary_chromaticity[0]=ReadBlobFloat(image);
    offset+=4;
    if (IsFloatDefined(cin.image.red_primary_chromaticity[0]) != MagickFalse)
        image->chromaticity.red_primary.x=cin.image.red_primary_chromaticity[0];
    cin.image.red_primary_chromaticity[1]=ReadBlobFloat(image);
    offset+=4;
    if (IsFloatDefined(cin.image.red_primary_chromaticity[1]) != MagickFalse)
        image->chromaticity.red_primary.y=cin.image.red_primary_chromaticity[1];
    cin.image.green_primary_chromaticity[0]=ReadBlobFloat(image);
    offset+=4;
    if (IsFloatDefined(cin.image.green_primary_chromaticity[0]) != MagickFalse)
        image->chromaticity.red_primary.x=cin.image.green_primary_chromaticity[0];
    cin.image.green_primary_chromaticity[1]=ReadBlobFloat(image);
    offset+=4;
    if (IsFloatDefined(cin.image.green_primary_chromaticity[1]) != MagickFalse)
        image->chromaticity.green_primary.y=cin.image.green_primary_chromaticity[1];
    cin.image.blue_primary_chromaticity[0]=ReadBlobFloat(image);
    offset+=4;
    if (IsFloatDefined(cin.image.blue_primary_chromaticity[0]) != MagickFalse)
        image->chromaticity.blue_primary.x=cin.image.blue_primary_chromaticity[0];
    cin.image.blue_primary_chromaticity[1]=ReadBlobFloat(image);
    offset+=4;
    if (IsFloatDefined(cin.image.blue_primary_chromaticity[1]) != MagickFalse)
        image->chromaticity.blue_primary.y=cin.image.blue_primary_chromaticity[1];
    offset+=ReadBlob(image,sizeof(cin.image.label),(unsigned char *)
                     cin.image.label);
    (void) SetImageProperty(image,"dpx:image.label",cin.image.label,exception);
    offset+=ReadBlob(image,sizeof(cin.image.reserve),(unsigned char *)
                     cin.image.reserve);
    /*
      Image data format information.
    */
    cin.data_format.interleave=(unsigned char) ReadBlobByte(image);
    offset++;
    cin.data_format.packing=(unsigned char) ReadBlobByte(image);
    offset++;
    cin.data_format.sign=(unsigned char) ReadBlobByte(image);
    offset++;
    cin.data_format.sense=(unsigned char) ReadBlobByte(image);
    offset++;
    cin.data_format.line_pad=ReadBlobLong(image);
    offset+=4;
    cin.data_format.channel_pad=ReadBlobLong(image);
    offset+=4;
    offset+=ReadBlob(image,sizeof(cin.data_format.reserve),(unsigned char *)
                     cin.data_format.reserve);
    /*
      Image origination information.
    */
    cin.origination.x_offset=(int) ReadBlobLong(image);
    offset+=4;
    if ((size_t) cin.origination.x_offset != ~0UL)
        (void) FormatImageProperty(image,"dpx:origination.x_offset","%.20g",
                                   (double) cin.origination.x_offset);
    cin.origination.y_offset=(ssize_t) ReadBlobLong(image);
    offset+=4;
    if ((size_t) cin.origination.y_offset != ~0UL)
        (void) FormatImageProperty(image,"dpx:origination.y_offset","%.20g",
                                   (double) cin.origination.y_offset);
    offset+=ReadBlob(image,sizeof(cin.origination.filename),(unsigned char *)
                     cin.origination.filename);
    (void) SetImageProperty(image,"dpx:origination.filename",
                            cin.origination.filename,exception);
    offset+=ReadBlob(image,sizeof(cin.origination.create_date),(unsigned char *)
                     cin.origination.create_date);
    (void) SetImageProperty(image,"dpx:origination.create_date",
                            cin.origination.create_date,exception);
    offset+=ReadBlob(image,sizeof(cin.origination.create_time),(unsigned char *)
                     cin.origination.create_time);
    (void) SetImageProperty(image,"dpx:origination.create_time",
                            cin.origination.create_time,exception);
    offset+=ReadBlob(image,sizeof(cin.origination.device),(unsigned char *)
                     cin.origination.device);
    (void) SetImageProperty(image,"dpx:origination.device",
                            cin.origination.device,exception);
    offset+=ReadBlob(image,sizeof(cin.origination.model),(unsigned char *)
                     cin.origination.model);
    (void) SetImageProperty(image,"dpx:origination.model",cin.origination.model,
                            exception);
    offset+=ReadBlob(image,sizeof(cin.origination.serial),(unsigned char *)
                     cin.origination.serial);
    (void) SetImageProperty(image,"dpx:origination.serial",
                            cin.origination.serial,exception);
    cin.origination.x_pitch=ReadBlobFloat(image);
    offset+=4;
    cin.origination.y_pitch=ReadBlobFloat(image);
    offset+=4;
    cin.origination.gamma=ReadBlobFloat(image);
    offset+=4;
    if (IsFloatDefined(cin.origination.gamma) != MagickFalse)
        image->gamma=cin.origination.gamma;
    offset+=ReadBlob(image,sizeof(cin.origination.reserve),(unsigned char *)
                     cin.origination.reserve);
    if ((cin.file.image_offset > 2048) && (cin.file.user_length != 0))
    {
        int
        c;

        /*
          Image film information.
        */
        cin.film.id=ReadBlobByte(image);
        offset++;
        c=cin.film.id;
        if (c != ~0)
            (void) FormatImageProperty(image,"dpx:film.id","%d",cin.film.id);
        cin.film.type=ReadBlobByte(image);
        offset++;
        c=cin.film.type;
        if (c != ~0)
            (void) FormatImageProperty(image,"dpx:film.type","%d",cin.film.type);
        cin.film.offset=ReadBlobByte(image);
        offset++;
        c=cin.film.offset;
        if (c != ~0)
            (void) FormatImageProperty(image,"dpx:film.offset","%d",
                                       cin.film.offset);
        cin.film.reserve1=ReadBlobByte(image);
        offset++;
        cin.film.prefix=ReadBlobLong(image);
        offset+=4;
        if (cin.film.prefix != ~0UL)
            (void) FormatImageProperty(image,"dpx:film.prefix","%.20g",(double)
                                       cin.film.prefix);
        cin.film.count=ReadBlobLong(image);
        offset+=4;
        offset+=ReadBlob(image,sizeof(cin.film.format),(unsigned char *)
                         cin.film.format);
        (void) SetImageProperty(image,"dpx:film.format",cin.film.format,
                                exception);
        cin.film.frame_position=ReadBlobLong(image);
        offset+=4;
        if (cin.film.frame_position != ~0UL)
            (void) FormatImageProperty(image,"dpx:film.frame_position","%.20g",
                                       (double) cin.film.frame_position);
        cin.film.frame_rate=ReadBlobFloat(image);
        offset+=4;
        if (IsFloatDefined(cin.film.frame_rate) != MagickFalse)
            (void) FormatImageProperty(image,"dpx:film.frame_rate","%g",
                                       cin.film.frame_rate);
        offset+=ReadBlob(image,sizeof(cin.film.frame_id),(unsigned char *)
                         cin.film.frame_id);
        (void) SetImageProperty(image,"dpx:film.frame_id",cin.film.frame_id,
                                exception);
        offset+=ReadBlob(image,sizeof(cin.film.slate_info),(unsigned char *)
                         cin.film.slate_info);
        (void) SetImageProperty(image,"dpx:film.slate_info",cin.film.slate_info,
                                exception);
        offset+=ReadBlob(image,sizeof(cin.film.reserve),(unsigned char *)
                         cin.film.reserve);
    }
    if ((cin.file.image_offset > 2048) && (cin.file.user_length != 0))
    {
        StringInfo
        *profile;

        /*
          User defined data.
        */
        profile=BlobToStringInfo((const void *) NULL,cin.file.user_length);
        if (profile == (StringInfo *) NULL)
            ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        offset+=ReadBlob(image,GetStringInfoLength(profile),
                         GetStringInfoDatum(profile));
        (void) SetImageProfile(image,"dpx:user.data",profile,exception);
        profile=DestroyStringInfo(profile);
    }
    for ( ; offset < (MagickOffsetType) cin.file.image_offset; offset++)
        (void) ReadBlobByte(image);
    image->depth=cin.image.channel[0].bits_per_pixel;
    image->columns=cin.image.channel[0].pixels_per_line;
    image->rows=cin.image.channel[0].lines_per_image;
    if (image_info->ping)
    {
        (void) CloseBlob(image);
        return(image);
    }
    /*
      Convert CIN raster image to pixel packets.
    */
    quantum_info=AcquireQuantumInfo(image_info,image);
    if (quantum_info == (QuantumInfo *) NULL)
        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    quantum_info->quantum=32;
    quantum_info->pack=MagickFalse;
    quantum_type=RGBQuantum;
    pixels=GetQuantumPixels(quantum_info);
    length=GetQuantumExtent(image,quantum_info,quantum_type);
    length=GetBytesPerRow(image->columns,3,image->depth,MagickTrue);
    if (cin.image.number_channels == 1)
    {
        quantum_type=GrayQuantum;
        length=GetBytesPerRow(image->columns,1,image->depth,MagickTrue);
    }
    for (y=0; y < (ssize_t) image->rows; y++)
    {
        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
        if (q == (Quantum *) NULL)
            break;
        count=ReadBlob(image,length,pixels);
        if ((size_t) count != length)
            break;
        (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
                                   quantum_type,pixels,exception);
        if (SyncAuthenticPixels(image,exception) == MagickFalse)
            break;
        if (image->previous == (Image *) NULL)
        {
            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
                                    image->rows);
            if (status == MagickFalse)
                break;
        }
    }
    SetQuantumImageType(image,quantum_type);
    quantum_info=DestroyQuantumInfo(quantum_info);
    if (EOFBlob(image) != MagickFalse)
        ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
                           image->filename);
    SetImageColorspace(image,LogColorspace,exception);
    (void) CloseBlob(image);
    return(GetFirstImageInList(image));
}
Exemple #2
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);
}
Exemple #3
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));
}
Exemple #4
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));
}
Exemple #5
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d C A C H E I m a g e                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadMPCImage() reads an Magick Persistent Cache image file and returns
%  it.  It allocates the memory necessary for the new Image structure and
%  returns a pointer to the new image.
%
%  The format of the ReadMPCImage method is:
%
%      Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  Decompression code contributed by Kyle Shorter.
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  char
    cache_filename[MaxTextExtent],
    id[MaxTextExtent],
    keyword[MaxTextExtent],
    *options;

  const unsigned char
    *p;

  GeometryInfo
    geometry_info;

  Image
    *image;

  int
    c;

  LinkedListInfo
    *profiles;

  MagickBooleanType
    status;

  MagickOffsetType
    offset;

  MagickStatusType
    flags;

  register long
    i;

  size_t
    length;

  ssize_t
    count;

  StringInfo
    *profile;

  unsigned long
    depth,
    quantum_depth;

  /*
    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);
    }
  (void) CopyMagickString(cache_filename,image->filename,MaxTextExtent);
  AppendImageFormat("cache",cache_filename);
  c=ReadBlobByte(image);
  if (c == EOF)
    {
      image=DestroyImage(image);
      return((Image *) NULL);
    }
  *id='\0';
  (void) ResetMagickMemory(keyword,0,sizeof(keyword));
  offset=0;
  do
  {
    /*
      Decode image header;  header terminates one character beyond a ':'.
    */
    profiles=(LinkedListInfo *) NULL;
    length=MaxTextExtent;
    options=AcquireString((char *) NULL);
    quantum_depth=MAGICKCORE_QUANTUM_DEPTH;
    image->depth=8;
    image->compression=NoCompression;
    while ((isgraph(c) != MagickFalse) && (c != (int) ':'))
    {
      register char
        *p;

      if (c == (int) '{')
        {
          char
            *comment;

          /*
            Read comment-- any text between { }.
          */
          length=MaxTextExtent;
          comment=AcquireString((char *) NULL);
          for (p=comment; comment != (char *) NULL; p++)
          {
            c=ReadBlobByte(image);
            if ((c == EOF) || (c == (int) '}'))
              break;
            if ((size_t) (p-comment+1) >= length)
              {
                *p='\0';
                length<<=1;
                comment=(char *) ResizeQuantumMemory(comment,length+
                  MaxTextExtent,sizeof(*comment));
                if (comment == (char *) NULL)
                  break;
                p=comment+strlen(comment);
              }
            *p=(char) c;
          }
          if (comment == (char *) NULL)
            ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
          *p='\0';
          (void) SetImageProperty(image,"comment",comment);
          comment=DestroyString(comment);
          c=ReadBlobByte(image);
        }
      else
        if (isalnum(c) != MagickFalse)
          {
            /*
              Get the keyword.
            */
            p=keyword;
            do
            {
              if (isspace((int) ((unsigned char) c)) != 0)
                break;
              if (c == (int) '=')
                break;
              if ((size_t) (p-keyword) < (MaxTextExtent-1))
                *p++=(char) c;
              c=ReadBlobByte(image);
            } while (c != EOF);
            *p='\0';
            p=options;
            while (isspace((int) ((unsigned char) c)) != 0)
              c=ReadBlobByte(image);
            if (c == (int) '=')
              {
                /*
                  Get the keyword value.
                */
                c=ReadBlobByte(image);
                while ((c != (int) '}') && (c != EOF))
                {
                  if ((size_t) (p-options+1) >= length)
                    {
                      *p='\0';
                      length<<=1;
                      options=(char *) ResizeQuantumMemory(options,length+
                        MaxTextExtent,sizeof(*options));
                      if (options == (char *) NULL)
                        break;
                      p=options+strlen(options);
                    }
                  if (options == (char *) NULL)
                    ThrowReaderException(ResourceLimitError,
                      "MemoryAllocationFailed");
                  *p++=(char) c;
                  c=ReadBlobByte(image);
                  if (*options != '{')
                    if (isspace((int) ((unsigned char) c)) != 0)
                      break;
                }
              }
            *p='\0';
            if (*options == '{')
              (void) CopyMagickString(options,options+1,MaxTextExtent);
            /*
              Assign a value to the specified keyword.
            */
            switch (*keyword)
            {
              case 'b':
              case 'B':
              {
                if (LocaleCompare(keyword,"background-color") == 0)
                  {
                    (void) QueryColorDatabase(options,&image->background_color,
                      exception);
                    break;
                  }
                if (LocaleCompare(keyword,"blue-primary") == 0)
                  {
                    flags=ParseGeometry(options,&geometry_info);
                    image->chromaticity.blue_primary.x=geometry_info.rho;
                    image->chromaticity.blue_primary.y=geometry_info.sigma;
                    if ((flags & SigmaValue) == 0)
                      image->chromaticity.blue_primary.y=
                        image->chromaticity.blue_primary.x;
                    break;
                  }
                if (LocaleCompare(keyword,"border-color") == 0)
                  {
                    (void) QueryColorDatabase(options,&image->border_color,
                      exception);
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'c':
              case 'C':
              {
                if (LocaleCompare(keyword,"class") == 0)
                  {
                    long
                      storage_class;

                    storage_class=ParseMagickOption(MagickClassOptions,
                      MagickFalse,options);
                    if (storage_class < 0)
                      break;
                    image->storage_class=(ClassType) storage_class;
                    break;
                  }
                if (LocaleCompare(keyword,"colors") == 0)
                  {
                    image->colors=StringToUnsignedLong(options);
                    break;
                  }
                if (LocaleCompare(keyword,"colorspace") == 0)
                  {
                    long
                      colorspace;

                    colorspace=ParseMagickOption(MagickColorspaceOptions,
                      MagickFalse,options);
                    if (colorspace < 0)
                      break;
                    image->colorspace=(ColorspaceType) colorspace;
                    break;
                  }
                if (LocaleCompare(keyword,"compression") == 0)
                  {
                    long
                      compression;

                    compression=ParseMagickOption(MagickCompressOptions,
                      MagickFalse,options);
                    if (compression < 0)
                      break;
                    image->compression=(CompressionType) compression;
                    break;
                  }
                if (LocaleCompare(keyword,"columns") == 0)
                  {
                    image->columns=StringToUnsignedLong(options);
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'd':
              case 'D':
              {
                if (LocaleCompare(keyword,"delay") == 0)
                  {
                    image->delay=StringToUnsignedLong(options);
                    break;
                  }
                if (LocaleCompare(keyword,"depth") == 0)
                  {
                    image->depth=StringToUnsignedLong(options);
                    break;
                  }
                if (LocaleCompare(keyword,"dispose") == 0)
                  {
                    long
                      dispose;

                    dispose=ParseMagickOption(MagickDisposeOptions,MagickFalse,
                      options);
                    if (dispose < 0)
                      break;
                    image->dispose=(DisposeType) dispose;
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'e':
              case 'E':
              {
                if (LocaleCompare(keyword,"endian") == 0)
                  {
                    long
                      endian;

                    endian=ParseMagickOption(MagickEndianOptions,MagickFalse,
                      options);
                    if (endian < 0)
                      break;
                    image->endian=(EndianType) endian;
                    break;
                  }
                if (LocaleCompare(keyword,"error") == 0)
                  {
                    image->error.mean_error_per_pixel=StringToDouble(options);
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'g':
              case 'G':
              {
                if (LocaleCompare(keyword,"gamma") == 0)
                  {
                    image->gamma=StringToDouble(options);
                    break;
                  }
                if (LocaleCompare(keyword,"green-primary") == 0)
                  {
                    flags=ParseGeometry(options,&geometry_info);
                    image->chromaticity.green_primary.x=geometry_info.rho;
                    image->chromaticity.green_primary.y=geometry_info.sigma;
                    if ((flags & SigmaValue) == 0)
                      image->chromaticity.green_primary.y=
                        image->chromaticity.green_primary.x;
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'i':
              case 'I':
              {
                if (LocaleCompare(keyword,"id") == 0)
                  {
                    (void) CopyMagickString(id,options,MaxTextExtent);
                    break;
                  }
                if (LocaleCompare(keyword,"iterations") == 0)
                  {
                    image->iterations=StringToUnsignedLong(options);
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'm':
              case 'M':
              {
                if (LocaleCompare(keyword,"matte") == 0)
                  {
                    long
                      matte;

                    matte=ParseMagickOption(MagickBooleanOptions,MagickFalse,
                      options);
                    if (matte < 0)
                      break;
                    image->matte=(MagickBooleanType) matte;
                    break;
                  }
                if (LocaleCompare(keyword,"matte-color") == 0)
                  {
                    (void) QueryColorDatabase(options,&image->matte_color,
                      exception);
                    break;
                  }
                if (LocaleCompare(keyword,"maximum-error") == 0)
                  {
                    image->error.normalized_maximum_error=StringToDouble(options);
                    break;
                  }
                if (LocaleCompare(keyword,"mean-error") == 0)
                  {
                    image->error.normalized_mean_error=StringToDouble(options);
                    break;
                  }
                if (LocaleCompare(keyword,"montage") == 0)
                  {
                    (void) CloneString(&image->montage,options);
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'o':
              case 'O':
              {
                if (LocaleCompare(keyword,"opaque") == 0)
                  {
                    long
                      matte;

                    matte=ParseMagickOption(MagickBooleanOptions,MagickFalse,
                      options);
                    if (matte < 0)
                      break;
                    image->matte=(MagickBooleanType) matte;
                    break;
                  }
                if (LocaleCompare(keyword,"orientation") == 0)
                  {
                    long
                      orientation;

                    orientation=ParseMagickOption(MagickOrientationOptions,
                      MagickFalse,options);
                    if (orientation < 0)
                      break;
                    image->orientation=(OrientationType) orientation;
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'p':
              case 'P':
              {
                if (LocaleCompare(keyword,"page") == 0)
                  {
                    char
                      *geometry;

                    geometry=GetPageGeometry(options);
                    (void) ParseAbsoluteGeometry(geometry,&image->page);
                    geometry=DestroyString(geometry);
                    break;
                  }
                if ((LocaleNCompare(keyword,"profile:",8) == 0) ||
                    (LocaleNCompare(keyword,"profile-",8) == 0))
                  {
                    if (profiles == (LinkedListInfo *) NULL)
                      profiles=NewLinkedList(0);
                    (void) AppendValueToLinkedList(profiles,
                      AcquireString(keyword+8));
                    profile=AcquireStringInfo((size_t) StringToLong(options));
                    (void) SetImageProfile(image,keyword+8,profile);
                    profile=DestroyStringInfo(profile);
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'q':
              case 'Q':
              {
                if (LocaleCompare(keyword,"quality") == 0)
                  {
                    image->quality=StringToUnsignedLong(options);
                    break;
                  }
                if (LocaleCompare(keyword,"quantum-depth") == 0)
                  {
                    quantum_depth=StringToUnsignedLong(options);
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'r':
              case 'R':
              {
                if (LocaleCompare(keyword,"red-primary") == 0)
                  {
                    flags=ParseGeometry(options,&geometry_info);
                    image->chromaticity.red_primary.x=geometry_info.rho;
                    if ((flags & SigmaValue) != 0)
                      image->chromaticity.red_primary.y=geometry_info.sigma;
                    break;
                  }
                if (LocaleCompare(keyword,"rendering-intent") == 0)
                  {
                    long
                      rendering_intent;

                    rendering_intent=ParseMagickOption(MagickIntentOptions,
                      MagickFalse,options);
                    if (rendering_intent < 0)
                      break;
                    image->rendering_intent=(RenderingIntent) rendering_intent;
                    break;
                  }
                if (LocaleCompare(keyword,"resolution") == 0)
                  {
                    flags=ParseGeometry(options,&geometry_info);
                    image->x_resolution=geometry_info.rho;
                    image->y_resolution=geometry_info.sigma;
                    if ((flags & SigmaValue) == 0)
                      image->y_resolution=image->x_resolution;
                    break;
                  }
                if (LocaleCompare(keyword,"rows") == 0)
                  {
                    image->rows=StringToUnsignedLong(options);
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 's':
              case 'S':
              {
                if (LocaleCompare(keyword,"scene") == 0)
                  {
                    image->scene=StringToUnsignedLong(options);
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 't':
              case 'T':
              {
                if (LocaleCompare(keyword,"ticks-per-second") == 0)
                  {
                    image->ticks_per_second=(long) StringToLong(options);
                    break;
                  }
                if (LocaleCompare(keyword,"tile-offset") == 0)
                  {
                    char
                      *geometry;

                    geometry=GetPageGeometry(options);
                    (void) ParseAbsoluteGeometry(geometry,&image->tile_offset);
                    geometry=DestroyString(geometry);
                  }
                if (LocaleCompare(keyword,"type") == 0)
                  {
                    long
                      type;

                    type=ParseMagickOption(MagickTypeOptions,MagickFalse,
                      options);
                    if (type < 0)
                      break;
                    image->type=(ImageType) type;
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'u':
              case 'U':
              {
                if (LocaleCompare(keyword,"units") == 0)
                  {
                    long
                      units;

                    units=ParseMagickOption(MagickResolutionOptions,MagickFalse,
                      options);
                    if (units < 0)
                      break;
                    image->units=(ResolutionType) units;
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              case 'w':
              case 'W':
              {
                if (LocaleCompare(keyword,"white-point") == 0)
                  {
                    flags=ParseGeometry(options,&geometry_info);
                    image->chromaticity.white_point.x=geometry_info.rho;
                    image->chromaticity.white_point.y=geometry_info.sigma;
                    if ((flags & SigmaValue) == 0)
                      image->chromaticity.white_point.y=
                        image->chromaticity.white_point.x;
                    break;
                  }
                (void) SetImageProperty(image,keyword,options);
                break;
              }
              default:
              {
                (void) SetImageProperty(image,keyword,options);
                break;
              }
            }
          }
        else
          c=ReadBlobByte(image);
      while (isspace((int) ((unsigned char) c)) != 0)
        c=ReadBlobByte(image);
    }
    options=DestroyString(options);
    (void) ReadBlobByte(image);
    /*
      Verify that required image information is defined.
    */
    if ((LocaleCompare(id,"MagickCache") != 0) ||
        (image->storage_class == UndefinedClass) ||
        (image->compression == UndefinedCompression) || (image->columns == 0) ||
        (image->rows == 0))
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    if (quantum_depth != MAGICKCORE_QUANTUM_DEPTH)
      ThrowReaderException(CacheError,"InconsistentPersistentCacheDepth");
    if (image->montage != (char *) NULL)
      {
        register char
          *p;

        /*
          Image directory.
        */
        length=MaxTextExtent;
        image->directory=AcquireString((char *) NULL);
        p=image->directory;
        do
        {
          *p='\0';
          if ((strlen(image->directory)+MaxTextExtent) >= length)
            {
              /*
                Allocate more memory for the image directory.
              */
              length<<=1;
              image->directory=(char *) ResizeQuantumMemory(image->directory,
                length+MaxTextExtent,sizeof(*image->directory));
              if (image->directory == (char *) NULL)
                ThrowReaderException(CorruptImageError,"UnableToReadImageData");
              p=image->directory+strlen(image->directory);
            }
          c=ReadBlobByte(image);
          *p++=(char) c;
        } while (c != (int) '\0');
      }
    if (profiles != (LinkedListInfo *) NULL)
      {
        const char
          *name;

        const StringInfo
          *profile;

        register unsigned char
          *p;

        /*
          Read image profiles.
        */
        ResetLinkedListIterator(profiles);
        name=(const char *) GetNextValueInLinkedList(profiles);
        while (name != (const char *) NULL)
        {
          profile=GetImageProfile(image,name);
          if (profile != (StringInfo *) NULL)
            {
              p=GetStringInfoDatum(profile);
              count=ReadBlob(image,GetStringInfoLength(profile),p);
            }
          name=(const char *) GetNextValueInLinkedList(profiles);
        }
        profiles=DestroyLinkedList(profiles,RelinquishMagickMemory);
      }
    depth=GetImageQuantumDepth(image,MagickFalse);
    if (image->storage_class == PseudoClass)
      {
        /*
          Create image colormap.
        */
        if (AcquireImageColormap(image,image->colors) == MagickFalse)
          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        if (image->colors != 0)
          {
            size_t
              packet_size;

            unsigned char
              *colormap;

            /*
              Read image colormap from file.
            */
            packet_size=(size_t) (3UL*depth/8UL);
            colormap=(unsigned char *) AcquireQuantumMemory(image->colors,
              packet_size*sizeof(*colormap));
            if (colormap == (unsigned char *) NULL)
              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
            count=ReadBlob(image,packet_size*image->colors,colormap);
            if (count != (ssize_t) (packet_size*image->colors))
              ThrowReaderException(CorruptImageError,
                "InsufficientImageDataInFile");
            p=colormap;
            switch (depth)
            {
              default:
                ThrowReaderException(CorruptImageError,
                  "ImageDepthNotSupported");
              case 8:
              {
                unsigned char
                  pixel;

                for (i=0; i < (long) image->colors; i++)
                {
                  p=PushCharPixel(p,&pixel);
                  image->colormap[i].red=ScaleCharToQuantum(pixel);
                  p=PushCharPixel(p,&pixel);
                  image->colormap[i].green=ScaleCharToQuantum(pixel);
                  p=PushCharPixel(p,&pixel);
                  image->colormap[i].blue=ScaleCharToQuantum(pixel);
                }
                break;
              }
              case 16:
              {
                unsigned short
                  pixel;

                for (i=0; i < (long) image->colors; i++)
                {
                  p=PushShortPixel(MSBEndian,p,&pixel);
                  image->colormap[i].red=ScaleShortToQuantum(pixel);
                  p=PushShortPixel(MSBEndian,p,&pixel);
                  image->colormap[i].green=ScaleShortToQuantum(pixel);
                  p=PushShortPixel(MSBEndian,p,&pixel);
                  image->colormap[i].blue=ScaleShortToQuantum(pixel);
                }
                break;
              }
              case 32:
              {
                unsigned long
                  pixel;

                for (i=0; i < (long) image->colors; i++)
                {
                  p=PushLongPixel(MSBEndian,p,&pixel);
                  image->colormap[i].red=ScaleLongToQuantum(pixel);
                  p=PushLongPixel(MSBEndian,p,&pixel);
                  image->colormap[i].green=ScaleLongToQuantum(pixel);
                  p=PushLongPixel(MSBEndian,p,&pixel);
                  image->colormap[i].blue=ScaleLongToQuantum(pixel);
                }
                break;
              }
            }
            colormap=(unsigned char *) RelinquishMagickMemory(colormap);
          }
      }
    if (EOFBlob(image) != MagickFalse)
      {
        ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
          image->filename);
        break;
      }
    if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
        break;
    /*
      Attach persistent pixel cache.
    */
    status=PersistPixelCache(image,cache_filename,MagickTrue,&offset,exception);
    if (status == MagickFalse)
      ThrowReaderException(CacheError,"UnableToPersistPixelCache");
    /*
      Proceed to next image.
    */
    do
    {
      c=ReadBlobByte(image);
    } while ((isgraph(c) == MagickFalse) && (c != EOF));
    if (c != EOF)
      {
        /*
          Allocate next image structure.
        */
        AcquireNextImage(image_info,image);
        if (GetNextImageInList(image) == (Image *) NULL)
          {
            image=DestroyImageList(image);
            return((Image *) NULL);
          }
        image=SyncNextImageInList(image);
        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
          GetBlobSize(image));
        if (status == MagickFalse)
          break;
      }
  } while (c != EOF);
  (void) CloseBlob(image);
  return(GetFirstImageInList(image));
}