Esempio n. 1
0
static MagickBooleanType load_hierarchy(Image *image,XCFDocInfo *inDocInfo,
   XCFLayerInfo *inLayer, ExceptionInfo *exception)
{
  MagickOffsetType
    saved_pos,
    offset,
    junk;

  size_t
    width,
    height,
    bytes_per_pixel;

  width=ReadBlobMSBLong(image);
  (void) width;
  height=ReadBlobMSBLong(image);
  (void) height;
  bytes_per_pixel=inDocInfo->bytes_per_pixel=ReadBlobMSBLong(image);
  (void) bytes_per_pixel;

  /* load in the levels...we make sure that the number of levels
   *  calculated when the TileManager was created is the same
   *  as the number of levels found in the file.
   */
  offset=(MagickOffsetType) ReadBlobMSBLong(image);  /* top level */

  /* discard offsets for layers below first, if any.
   */
  do
  {
    junk=(MagickOffsetType) ReadBlobMSBLong(image);
  }
  while (junk != 0);

  /* save the current position as it is where the
   *  next level offset is stored.
   */
  saved_pos=TellBlob(image);

  /* seek to the level offset */
  offset=SeekBlob(image, offset, SEEK_SET);

  /* read in the level */
  if (load_level (image, inDocInfo, inLayer, exception) == 0)
    return(MagickFalse);
  /* restore the saved position so we'll be ready to
   *  read the next offset.
   */
  offset=SeekBlob(image, saved_pos, SEEK_SET);
  return(MagickTrue);
}
Esempio n. 2
0
static char *ReadBlobStringWithLongSize(Image *image,char *string,size_t max)
{
  int
    c;

  MagickOffsetType
    offset;

  register ssize_t
    i;

  size_t
    length;

  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  assert(max != 0);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  length=ReadBlobMSBLong(image);
  for (i=0; i < (ssize_t) MagickMin(length,max-1); i++)
  {
    c=ReadBlobByte(image);
    if (c == EOF)
      return((char *) NULL);
    string[i]=(char) c;
  }
  string[i]='\0';
  offset=SeekBlob(image,(MagickOffsetType) (length-i),SEEK_CUR);
  if (offset < 0)
    (void) ThrowMagickException(&image->exception,GetMagickModule(),
      CorruptImageError,"ImproperImageHeader","`%s'",image->filename);
  return(string);
}
Esempio n. 3
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d A V S I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadAVSImage() reads an AVS X 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 ReadAVSImage method is:
%
%      Image *ReadAVSImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *ReadAVSImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  Image
    *image;

  MagickBooleanType
    status;

  register PixelPacket
    *q;

  register ssize_t
    x;

  register unsigned char
    *p;

  size_t
    height,
    length,
    width;

  ssize_t
    count,
    y;

  unsigned char
    *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);
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    {
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  /*
    Read AVS X image.
  */
  width=ReadBlobMSBLong(image);
  height=ReadBlobMSBLong(image);
  if (EOFBlob(image) != MagickFalse)
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  if ((width == 0UL) || (height == 0UL))
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  do
  {
    /*
      Convert AVS raster image to pixel packets.
    */
    image->columns=width;
    image->rows=height;
    image->depth=8;
    if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
        break;
    pixels=(unsigned char *) AcquireQuantumMemory(image->columns,
      4*sizeof(*pixels));
    if (pixels == (unsigned char *) NULL) 
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    length=(size_t) 4*image->columns;
    for (y=0; y < (ssize_t) image->rows; y++)
    {
      count=ReadBlob(image,length,pixels);
      if ((size_t) count != length)
        ThrowReaderException(CorruptImageError,"UnableToReadImageData");
      p=pixels;
      q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
      if (q == (PixelPacket *) NULL)
        break;
      for (x=0; x < (ssize_t) image->columns; x++)
      {
        SetPixelAlpha(q,ScaleCharToQuantum(*p++));
        SetPixelRed(q,ScaleCharToQuantum(*p++));
        SetPixelGreen(q,ScaleCharToQuantum(*p++));
        SetPixelBlue(q,ScaleCharToQuantum(*p++));
        if (q->opacity != OpaqueOpacity)
          image->matte=MagickTrue;
        q++;
      }
      if (SyncAuthenticPixels(image,exception) == MagickFalse)
        break;
      if (image->previous == (Image *) NULL)
        {
          status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
            image->rows);
          if (status == MagickFalse)
            break;
        }
    }
    pixels=(unsigned char *) RelinquishMagickMemory(pixels);
    if (EOFBlob(image) != MagickFalse)
      {
        ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
          image->filename);
        break;
      }
    /*
      Proceed to next image.
    */
    if (image_info->number_scenes != 0)
      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
        break;
    width=ReadBlobMSBLong(image);
    height=ReadBlobMSBLong(image);
    if ((width != 0UL) && (height != 0UL))
      {
        /*
          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 ((width != 0UL) && (height != 0UL));
  (void) CloseBlob(image);
  return(GetFirstImageInList(image));
}
Esempio n. 4
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d V I F F I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadVIFFImage() reads a Khoros Visualization 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 ReadVIFFImage method is:
%
%      Image *ReadVIFFImage(const ImageInfo *image_info,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image: Method ReadVIFFImage returns a pointer to the image after
%      reading.  A null image is returned if there is a memory shortage or if
%      the image cannot be read.
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *ReadVIFFImage(const ImageInfo *image_info,
                            ExceptionInfo *exception)
{
#define VFF_CM_genericRGB  15
#define VFF_CM_ntscRGB  1
#define VFF_CM_NONE  0
#define VFF_DEP_DECORDER  0x4
#define VFF_DEP_NSORDER  0x8
#define VFF_DES_RAW  0
#define VFF_LOC_IMPLICIT  1
#define VFF_MAPTYP_NONE  0
#define VFF_MAPTYP_1_BYTE  1
#define VFF_MAPTYP_2_BYTE  2
#define VFF_MAPTYP_4_BYTE  4
#define VFF_MAPTYP_FLOAT  5
#define VFF_MAPTYP_DOUBLE  7
#define VFF_MS_NONE  0
#define VFF_MS_ONEPERBAND  1
#define VFF_MS_SHARED  3
#define VFF_TYP_BIT  0
#define VFF_TYP_1_BYTE  1
#define VFF_TYP_2_BYTE  2
#define VFF_TYP_4_BYTE  4
#define VFF_TYP_FLOAT  5
#define VFF_TYP_DOUBLE  9

    typedef struct _ViffInfo
    {
        unsigned char
        identifier,
        file_type,
        release,
        version,
        machine_dependency,
        reserve[3];

        char
        comment[512];

        unsigned int
        rows,
        columns,
        subrows;

        int
        x_offset,
        y_offset;

        float
        x_bits_per_pixel,
        y_bits_per_pixel;

        unsigned int
        location_type,
        location_dimension,
        number_of_images,
        number_data_bands,
        data_storage_type,
        data_encode_scheme,
        map_scheme,
        map_storage_type,
        map_rows,
        map_columns,
        map_subrows,
        map_enable,
        maps_per_cycle,
        color_space_model;
    } ViffInfo;

    double
    min_value,
    scale_factor,
    value;

    Image
    *image;

    int
    bit;

    MagickBooleanType
    status;

    MagickSizeType
    number_pixels;

    register ssize_t
    x;

    register Quantum
    *q;

    register ssize_t
    i;

    register unsigned char
    *p;

    size_t
    bytes_per_pixel,
    lsb_first,
    max_packets,
    quantum;

    ssize_t
    count,
    y;

    unsigned char
    buffer[7],
           *viff_pixels;

    ViffInfo
    viff_info;

    /*
      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);
    }
    /*
      Read VIFF header (1024 bytes).
    */
    count=ReadBlob(image,1,&viff_info.identifier);
    do
    {
        /*
          Verify VIFF identifier.
        */
        if ((count == 0) || ((unsigned char) viff_info.identifier != 0xab))
            ThrowReaderException(CorruptImageError,"NotAVIFFImage");
        /*
          Initialize VIFF image.
        */
        count=ReadBlob(image,7,buffer);
        viff_info.file_type=buffer[0];
        viff_info.release=buffer[1];
        viff_info.version=buffer[2];
        viff_info.machine_dependency=buffer[3];
        count=ReadBlob(image,512,(unsigned char *) viff_info.comment);
        viff_info.comment[511]='\0';
        if (strlen(viff_info.comment) > 4)
            (void) SetImageProperty(image,"comment",viff_info.comment,exception);
        if ((viff_info.machine_dependency == VFF_DEP_DECORDER) ||
                (viff_info.machine_dependency == VFF_DEP_NSORDER))
        {
            viff_info.rows=ReadBlobLSBLong(image);
            viff_info.columns=ReadBlobLSBLong(image);
            viff_info.subrows=ReadBlobLSBLong(image);
            viff_info.x_offset=(int) ReadBlobLSBLong(image);
            viff_info.y_offset=(int) ReadBlobLSBLong(image);
            viff_info.x_bits_per_pixel=(float) ReadBlobLSBLong(image);
            viff_info.y_bits_per_pixel=(float) ReadBlobLSBLong(image);
            viff_info.location_type=ReadBlobLSBLong(image);
            viff_info.location_dimension=ReadBlobLSBLong(image);
            viff_info.number_of_images=ReadBlobLSBLong(image);
            viff_info.number_data_bands=ReadBlobLSBLong(image);
            viff_info.data_storage_type=ReadBlobLSBLong(image);
            viff_info.data_encode_scheme=ReadBlobLSBLong(image);
            viff_info.map_scheme=ReadBlobLSBLong(image);
            viff_info.map_storage_type=ReadBlobLSBLong(image);
            viff_info.map_rows=ReadBlobLSBLong(image);
            viff_info.map_columns=ReadBlobLSBLong(image);
            viff_info.map_subrows=ReadBlobLSBLong(image);
            viff_info.map_enable=ReadBlobLSBLong(image);
            viff_info.maps_per_cycle=ReadBlobLSBLong(image);
            viff_info.color_space_model=ReadBlobLSBLong(image);
        }
        else
        {
            viff_info.rows=ReadBlobMSBLong(image);
            viff_info.columns=ReadBlobMSBLong(image);
            viff_info.subrows=ReadBlobMSBLong(image);
            viff_info.x_offset=(int) ReadBlobMSBLong(image);
            viff_info.y_offset=(int) ReadBlobMSBLong(image);
            viff_info.x_bits_per_pixel=(float) ReadBlobMSBLong(image);
            viff_info.y_bits_per_pixel=(float) ReadBlobMSBLong(image);
            viff_info.location_type=ReadBlobMSBLong(image);
            viff_info.location_dimension=ReadBlobMSBLong(image);
            viff_info.number_of_images=ReadBlobMSBLong(image);
            viff_info.number_data_bands=ReadBlobMSBLong(image);
            viff_info.data_storage_type=ReadBlobMSBLong(image);
            viff_info.data_encode_scheme=ReadBlobMSBLong(image);
            viff_info.map_scheme=ReadBlobMSBLong(image);
            viff_info.map_storage_type=ReadBlobMSBLong(image);
            viff_info.map_rows=ReadBlobMSBLong(image);
            viff_info.map_columns=ReadBlobMSBLong(image);
            viff_info.map_subrows=ReadBlobMSBLong(image);
            viff_info.map_enable=ReadBlobMSBLong(image);
            viff_info.maps_per_cycle=ReadBlobMSBLong(image);
            viff_info.color_space_model=ReadBlobMSBLong(image);
        }
        for (i=0; i < 420; i++)
            (void) ReadBlobByte(image);
        image->columns=viff_info.rows;
        image->rows=viff_info.columns;
        image->depth=viff_info.x_bits_per_pixel <= 8 ? 8UL :
                     MAGICKCORE_QUANTUM_DEPTH;
        /*
          Verify that we can read this VIFF image.
        */
        number_pixels=(MagickSizeType) viff_info.columns*viff_info.rows;
        if (number_pixels != (size_t) number_pixels)
            ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        if (number_pixels == 0)
            ThrowReaderException(CoderError,"ImageColumnOrRowSizeIsNotSupported");
        if ((viff_info.number_data_bands < 1) || (viff_info.number_data_bands > 4))
            ThrowReaderException(CorruptImageError,"ImproperImageHeader");
        if ((viff_info.data_storage_type != VFF_TYP_BIT) &&
                (viff_info.data_storage_type != VFF_TYP_1_BYTE) &&
                (viff_info.data_storage_type != VFF_TYP_2_BYTE) &&
                (viff_info.data_storage_type != VFF_TYP_4_BYTE) &&
                (viff_info.data_storage_type != VFF_TYP_FLOAT) &&
                (viff_info.data_storage_type != VFF_TYP_DOUBLE))
            ThrowReaderException(CoderError,"DataStorageTypeIsNotSupported");
        if (viff_info.data_encode_scheme != VFF_DES_RAW)
            ThrowReaderException(CoderError,"DataEncodingSchemeIsNotSupported");
        if ((viff_info.map_storage_type != VFF_MAPTYP_NONE) &&
                (viff_info.map_storage_type != VFF_MAPTYP_1_BYTE) &&
                (viff_info.map_storage_type != VFF_MAPTYP_2_BYTE) &&
                (viff_info.map_storage_type != VFF_MAPTYP_4_BYTE) &&
                (viff_info.map_storage_type != VFF_MAPTYP_FLOAT) &&
                (viff_info.map_storage_type != VFF_MAPTYP_DOUBLE))
            ThrowReaderException(CoderError,"MapStorageTypeIsNotSupported");
        if ((viff_info.color_space_model != VFF_CM_NONE) &&
                (viff_info.color_space_model != VFF_CM_ntscRGB) &&
                (viff_info.color_space_model != VFF_CM_genericRGB))
            ThrowReaderException(CoderError,"ColorspaceModelIsNotSupported");
        if (viff_info.location_type != VFF_LOC_IMPLICIT)
            ThrowReaderException(CoderError,"LocationTypeIsNotSupported");
        if (viff_info.number_of_images != 1)
            ThrowReaderException(CoderError,"NumberOfImagesIsNotSupported");
        if (viff_info.map_rows == 0)
            viff_info.map_scheme=VFF_MS_NONE;
        switch ((int) viff_info.map_scheme)
        {
        case VFF_MS_NONE:
        {
            if (viff_info.number_data_bands < 3)
            {
                /*
                  Create linear color ramp.
                */
                image->colors=image->depth <= 8 ? 256UL : 65536UL;
                if (viff_info.data_storage_type == VFF_TYP_BIT)
                    image->colors=2;
                if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
                    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
            }
            break;
        }
        case VFF_MS_ONEPERBAND:
        case VFF_MS_SHARED:
        {
            unsigned char
            *viff_colormap;

            /*
              Allocate VIFF colormap.
            */
            switch ((int) viff_info.map_storage_type)
            {
            case VFF_MAPTYP_1_BYTE:
                bytes_per_pixel=1;
                break;
            case VFF_MAPTYP_2_BYTE:
                bytes_per_pixel=2;
                break;
            case VFF_MAPTYP_4_BYTE:
                bytes_per_pixel=4;
                break;
            case VFF_MAPTYP_FLOAT:
                bytes_per_pixel=4;
                break;
            case VFF_MAPTYP_DOUBLE:
                bytes_per_pixel=8;
                break;
            default:
                bytes_per_pixel=1;
                break;
            }
            image->colors=viff_info.map_columns;
            if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
                ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
            viff_colormap=(unsigned char *) AcquireQuantumMemory(image->colors,
                          viff_info.map_rows*bytes_per_pixel*sizeof(*viff_colormap));
            if (viff_colormap == (unsigned char *) NULL)
                ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
            /*
              Read VIFF raster colormap.
            */
            count=ReadBlob(image,bytes_per_pixel*image->colors*viff_info.map_rows,
                           viff_colormap);
            lsb_first=1;
            if (*(char *) &lsb_first &&
                    ((viff_info.machine_dependency != VFF_DEP_DECORDER) &&
                     (viff_info.machine_dependency != VFF_DEP_NSORDER)))
                switch ((int) viff_info.map_storage_type)
                {
                case VFF_MAPTYP_2_BYTE:
                {
                    MSBOrderShort(viff_colormap,(bytes_per_pixel*image->colors*
                                                 viff_info.map_rows));
                    break;
                }
                case VFF_MAPTYP_4_BYTE:
                case VFF_MAPTYP_FLOAT:
                {
                    MSBOrderLong(viff_colormap,(bytes_per_pixel*image->colors*
                                                viff_info.map_rows));
                    break;
                }
                default:
                    break;
                }
            for (i=0; i < (ssize_t) (viff_info.map_rows*image->colors); i++)
            {
                switch ((int) viff_info.map_storage_type)
                {
                case VFF_MAPTYP_2_BYTE:
                    value=1.0*((short *) viff_colormap)[i];
                    break;
                case VFF_MAPTYP_4_BYTE:
                    value=1.0*((int *) viff_colormap)[i];
                    break;
                case VFF_MAPTYP_FLOAT:
                    value=((float *) viff_colormap)[i];
                    break;
                case VFF_MAPTYP_DOUBLE:
                    value=((double *) viff_colormap)[i];
                    break;
                default:
                    value=1.0*viff_colormap[i];
                    break;
                }
                if (i < (ssize_t) image->colors)
                {
                    image->colormap[i].red=ScaleCharToQuantum((unsigned char) value);
                    image->colormap[i].green=
                        ScaleCharToQuantum((unsigned char) value);
                    image->colormap[i].blue=ScaleCharToQuantum((unsigned char) value);
                }
                else if (i < (ssize_t) (2*image->colors))
                    image->colormap[i % image->colors].green=
                        ScaleCharToQuantum((unsigned char) value);
                else if (i < (ssize_t) (3*image->colors))
                    image->colormap[i % image->colors].blue=
                        ScaleCharToQuantum((unsigned char) value);
            }
            viff_colormap=(unsigned char *) RelinquishMagickMemory(viff_colormap);
            break;
        }
        default:
            ThrowReaderException(CoderError,"ColormapTypeNotSupported");
        }
        /*
          Initialize image structure.
        */
        image->alpha_trait=viff_info.number_data_bands == 4 ? BlendPixelTrait :
                           UndefinedPixelTrait;
        image->storage_class=(viff_info.number_data_bands < 3 ? PseudoClass :
                              DirectClass);
        image->columns=viff_info.rows;
        image->rows=viff_info.columns;
        if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
            if (image->scene >= (image_info->scene+image_info->number_scenes-1))
                break;
        /*
          Allocate VIFF pixels.
        */
        switch ((int) viff_info.data_storage_type)
        {
        case VFF_TYP_2_BYTE:
            bytes_per_pixel=2;
            break;
        case VFF_TYP_4_BYTE:
            bytes_per_pixel=4;
            break;
        case VFF_TYP_FLOAT:
            bytes_per_pixel=4;
            break;
        case VFF_TYP_DOUBLE:
            bytes_per_pixel=8;
            break;
        default:
            bytes_per_pixel=1;
            break;
        }
        if (viff_info.data_storage_type == VFF_TYP_BIT)
            max_packets=((image->columns+7UL) >> 3UL)*image->rows;
        else
            max_packets=(size_t) (number_pixels*viff_info.number_data_bands);
        viff_pixels=(unsigned char *) AcquireQuantumMemory(max_packets,
                    bytes_per_pixel*sizeof(*viff_pixels));
        if (viff_pixels == (unsigned char *) NULL)
            ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        count=ReadBlob(image,bytes_per_pixel*max_packets,viff_pixels);
        lsb_first=1;
        if (*(char *) &lsb_first &&
                ((viff_info.machine_dependency != VFF_DEP_DECORDER) &&
                 (viff_info.machine_dependency != VFF_DEP_NSORDER)))
            switch ((int) viff_info.data_storage_type)
            {
            case VFF_TYP_2_BYTE:
            {
                MSBOrderShort(viff_pixels,bytes_per_pixel*max_packets);
                break;
            }
            case VFF_TYP_4_BYTE:
            case VFF_TYP_FLOAT:
            {
                MSBOrderLong(viff_pixels,bytes_per_pixel*max_packets);
                break;
            }
            default:
                break;
            }
        min_value=0.0;
        scale_factor=1.0;
        if ((viff_info.data_storage_type != VFF_TYP_1_BYTE) &&
                (viff_info.map_scheme == VFF_MS_NONE))
        {
            double
            max_value;

            /*
              Determine scale factor.
            */
            switch ((int) viff_info.data_storage_type)
            {
            case VFF_TYP_2_BYTE:
                value=1.0*((short *) viff_pixels)[0];
                break;
            case VFF_TYP_4_BYTE:
                value=1.0*((int *) viff_pixels)[0];
                break;
            case VFF_TYP_FLOAT:
                value=((float *) viff_pixels)[0];
                break;
            case VFF_TYP_DOUBLE:
                value=((double *) viff_pixels)[0];
                break;
            default:
                value=1.0*viff_pixels[0];
                break;
            }
            max_value=value;
            min_value=value;
            for (i=0; i < (ssize_t) max_packets; i++)
            {
                switch ((int) viff_info.data_storage_type)
                {
                case VFF_TYP_2_BYTE:
                    value=1.0*((short *) viff_pixels)[i];
                    break;
                case VFF_TYP_4_BYTE:
                    value=1.0*((int *) viff_pixels)[i];
                    break;
                case VFF_TYP_FLOAT:
                    value=((float *) viff_pixels)[i];
                    break;
                case VFF_TYP_DOUBLE:
                    value=((double *) viff_pixels)[i];
                    break;
                default:
                    value=1.0*viff_pixels[i];
                    break;
                }
                if (value > max_value)
                    max_value=value;
                else if (value < min_value)
                    min_value=value;
            }
            if ((min_value == 0) && (max_value == 0))
                scale_factor=0;
            else if (min_value == max_value)
            {
                scale_factor=(double) QuantumRange/min_value;
                min_value=0;
            }
            else
                scale_factor=(double) QuantumRange/(max_value-min_value);
        }
        /*
          Convert pixels to Quantum size.
        */
        p=(unsigned char *) viff_pixels;
        for (i=0; i < (ssize_t) max_packets; i++)
        {
            switch ((int) viff_info.data_storage_type)
            {
            case VFF_TYP_2_BYTE:
                value=1.0*((short *) viff_pixels)[i];
                break;
            case VFF_TYP_4_BYTE:
                value=1.0*((int *) viff_pixels)[i];
                break;
            case VFF_TYP_FLOAT:
                value=((float *) viff_pixels)[i];
                break;
            case VFF_TYP_DOUBLE:
                value=((double *) viff_pixels)[i];
                break;
            default:
                value=1.0*viff_pixels[i];
                break;
            }
            if (viff_info.map_scheme == VFF_MS_NONE)
            {
                value=(value-min_value)*scale_factor;
                if (value > QuantumRange)
                    value=QuantumRange;
                else if (value < 0)
                    value=0;
            }
            *p=(unsigned char) value;
            p++;
        }
        /*
          Convert VIFF raster image to pixel packets.
        */
        p=(unsigned char *) viff_pixels;
        if (viff_info.data_storage_type == VFF_TYP_BIT)
        {
            /*
              Convert bitmap scanline.
            */
            (void) SetImageType(image,BilevelType,exception);
            (void) SetImageType(image,PaletteType,exception);
            for (y=0; y < (ssize_t) image->rows; y++)
            {
                q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
                if (q == (Quantum *) NULL)
                    break;
                for (x=0; x < (ssize_t) (image->columns-7); x+=8)
                {
                    for (bit=0; bit < 8; bit++)
                    {
                        if (GetPixelLuma(image,q) < (QuantumRange/2.0))
                        {
                            quantum=(size_t) GetPixelIndex(image,q);
                            quantum|=0x01;
                            SetPixelIndex(image,quantum,q);
                        }
                        q+=GetPixelChannels(image);
                    }
                    p++;
                }
                if ((image->columns % 8) != 0)
                {
                    for (bit=0; bit < (ssize_t) (image->columns % 8); bit++)
                        if (GetPixelLuma(image,q) < (QuantumRange/2.0))
                        {
                            quantum=(size_t) GetPixelIndex(image,q);
                            quantum|=0x01;
                            SetPixelIndex(image,quantum,q);
                            q+=GetPixelChannels(image);
                        }
                    p++;
                }
                if (SyncAuthenticPixels(image,exception) == MagickFalse)
                    break;
                if (image->previous == (Image *) NULL)
                {
                    status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
                                            image->rows);
                    if (status == MagickFalse)
                        break;
                }
            }
        }
        else if (image->storage_class == PseudoClass)
            for (y=0; y < (ssize_t) image->rows; y++)
            {
                q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
                if (q == (Quantum *) NULL)
                    break;
                for (x=0; x < (ssize_t) image->columns; x++)
                {
                    SetPixelIndex(image,*p++,q);
                    q+=GetPixelChannels(image);
                }
                if (SyncAuthenticPixels(image,exception) == MagickFalse)
                    break;
                if (image->previous == (Image *) NULL)
                {
                    status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
                                            image->rows);
                    if (status == MagickFalse)
                        break;
                }
            }
        else
        {
            /*
              Convert DirectColor scanline.
            */
            number_pixels=(MagickSizeType) image->columns*image->rows;
            for (y=0; y < (ssize_t) image->rows; y++)
            {
                q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
                if (q == (Quantum *) NULL)
                    break;
                for (x=0; x < (ssize_t) image->columns; x++)
                {
                    SetPixelRed(image,ScaleCharToQuantum(*p),q);
                    SetPixelGreen(image,ScaleCharToQuantum(*(p+number_pixels)),q);
                    SetPixelBlue(image,ScaleCharToQuantum(*(p+2*number_pixels)),q);
                    if (image->colors != 0)
                    {
                        SetPixelRed(image,image->colormap[(ssize_t)
                                                          GetPixelRed(image,q)].red,q);
                        SetPixelGreen(image,image->colormap[(ssize_t)
                                                            GetPixelGreen(image,q)].green,q);
                        SetPixelBlue(image,image->colormap[(ssize_t)
                                                           GetPixelBlue(image,q)].blue,q);
                    }
                    SetPixelAlpha(image,image->alpha_trait == BlendPixelTrait ?
                                  ScaleCharToQuantum(*(p+number_pixels*3)) : OpaqueAlpha,q);
                    p++;
                    q+=GetPixelChannels(image);
                }
                if (SyncAuthenticPixels(image,exception) == MagickFalse)
                    break;
                if (image->previous == (Image *) NULL)
                {
                    status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
                                            image->rows);
                    if (status == MagickFalse)
                        break;
                }
            }
        }
        viff_pixels=(unsigned char *) RelinquishMagickMemory(viff_pixels);
        if (image->storage_class == PseudoClass)
            (void) SyncImage(image,exception);
        if (EOFBlob(image) != MagickFalse)
        {
            ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
                               image->filename);
            break;
        }
        /*
          Proceed to next image.
        */
        if (image_info->number_scenes != 0)
            if (image->scene >= (image_info->scene+image_info->number_scenes-1))
                break;
        count=ReadBlob(image,1,&viff_info.identifier);
        if ((count != 0) && (viff_info.identifier == 0xab))
        {
            /*
              Allocate next image structure.
            */
            AcquireNextImage(image_info,image,exception);
            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 ((count != 0) && (viff_info.identifier == 0xab));
Esempio n. 5
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d P I X I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadPIXImage() reads a Alias/Wavefront RLE 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 ReadPIXImage method is:
%
%      Image *ReadPIXImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
%
*/
static Image *ReadPIXImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  Image
    *image;

  IndexPacket
    index;

  MagickBooleanType
    status;

  Quantum
    blue,
    green,
    red;

  register IndexPacket
    *indexes;

  register ssize_t
    x;

  register PixelPacket
    *q;

  size_t
    bits_per_pixel,
    height,
    length,
    width;

  ssize_t
    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);
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    {
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  /*
    Read PIX image.
  */
  width=ReadBlobMSBShort(image);
  height=ReadBlobMSBShort(image);
  (void) ReadBlobMSBShort(image);  /* x-offset */
  (void) ReadBlobMSBShort(image);  /* y-offset */
  bits_per_pixel=ReadBlobMSBShort(image);
  if ((width == 0UL) || (height == 0UL) || ((bits_per_pixel != 8) &&
      (bits_per_pixel != 24)))
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  do
  {
    /*
      Initialize image structure.
    */
    image->columns=width;
    image->rows=height;
    if (bits_per_pixel == 8)
      if (AcquireImageColormap(image,256) == MagickFalse)
        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
        break;
    /*
      Convert PIX raster image to pixel packets.
    */
    red=(Quantum) 0;
    green=(Quantum) 0;
    blue=(Quantum) 0;
    index=(IndexPacket) 0;
    length=0;
    for (y=0; y < (ssize_t) image->rows; y++)
    {
      q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
      if (q == (PixelPacket *) NULL)
        break;
      indexes=GetAuthenticIndexQueue(image);
      for (x=0; x < (ssize_t) image->columns; x++)
      {
        if (length == 0)
          {
            length=(size_t) ReadBlobByte(image);
            if (bits_per_pixel == 8)
              index=ScaleCharToQuantum((unsigned char) ReadBlobByte(image));
            else
              {
                blue=ScaleCharToQuantum((unsigned char) ReadBlobByte(image));
                green=ScaleCharToQuantum((unsigned char) ReadBlobByte(image));
                red=ScaleCharToQuantum((unsigned char) ReadBlobByte(image));
              }
          }
        if (image->storage_class == PseudoClass)
          SetPixelIndex(indexes+x,index);
        SetPixelBlue(q,blue);
        SetPixelGreen(q,green);
        SetPixelRed(q,red);
        length--;
        q++;
      }
      if (SyncAuthenticPixels(image,exception) == MagickFalse)
        break;
      if (image->previous == (Image *) NULL)
        {
          status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
            image->rows);
          if (status == MagickFalse)
            break;
        }
    }
    if (image->storage_class == PseudoClass)
      (void) SyncImage(image);
    if (EOFBlob(image) != MagickFalse)
      {
        ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
          image->filename);
        break;
      }
    /*
      Proceed to next image.
    */
    if (image_info->number_scenes != 0)
      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
        break;
    width=ReadBlobMSBLong(image);
    height=ReadBlobMSBLong(image);
    (void) ReadBlobMSBShort(image);
    (void) ReadBlobMSBShort(image);
    bits_per_pixel=ReadBlobMSBShort(image);
    status=(width != 0UL) && (height == 0UL) && ((bits_per_pixel == 8) ||
      (bits_per_pixel == 24)) ? MagickTrue : MagickFalse;
    if (status == MagickTrue)
      {
        /*
          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 (status == MagickTrue);
  (void) CloseBlob(image);
  return(GetFirstImageInList(image));
}
Esempio n. 6
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d X C F I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadXCFImage() reads a GIMP (GNU Image Manipulation Program) 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 ReadXCFImage method is:
%
%      image=ReadXCFImage(image_info)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
%
*/
static Image *ReadXCFImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  char
    magick[14];

  Image
    *image;

  int
    foundPropEnd = 0;

  MagickBooleanType
    status;

  MagickOffsetType
    offset;

  register ssize_t
    i;

  size_t
    length;

  ssize_t
    count;

  size_t
    image_type;

  XCFDocInfo
    doc_info;

  /*
    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);
    }
  count=ReadBlob(image,14,(unsigned char *) magick);
  if ((count == 0) ||
      (LocaleNCompare((char *) magick,"gimp xcf",8) != 0))
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  (void) ResetMagickMemory(&doc_info,0,sizeof(XCFDocInfo));
  doc_info.exception=exception;
  doc_info.width=ReadBlobMSBLong(image);
  doc_info.height=ReadBlobMSBLong(image);
  if ((doc_info.width > 262144) || (doc_info.height > 262144))
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  doc_info.image_type=ReadBlobMSBLong(image);
  /*
    Initialize image attributes.
  */
  image->columns=doc_info.width;
  image->rows=doc_info.height;
  image_type=doc_info.image_type;
  doc_info.file_size=GetBlobSize(image);
  image->compression=NoCompression;
  image->depth=8;
  if (image_type == GIMP_RGB)
    image->colorspace=RGBColorspace;
  else
    if (image_type == GIMP_GRAY)
      image->colorspace=GRAYColorspace;
    else
      if (image_type == GIMP_INDEXED)
        ThrowReaderException(CoderError,"ColormapTypeNotSupported");
  (void) SetImageBackgroundColor(image);
  image->matte=MagickTrue;
  /*
    Read properties.
  */
  while ((foundPropEnd == MagickFalse) && (EOFBlob(image) == MagickFalse))
  {
    PropType prop_type = (PropType) ReadBlobMSBLong(image);
    size_t prop_size = ReadBlobMSBLong(image);

    switch (prop_type)
    {
      case PROP_END:
        foundPropEnd=1;
        break;
      case PROP_COLORMAP:
      {
        /* Cannot rely on prop_size here--the value is set incorrectly
           by some Gimp versions.
        */
        size_t num_colours = ReadBlobMSBLong(image);
        for (i=0; i < (ssize_t) (3L*num_colours); i++ )
          (void) ReadBlobByte(image);
    /*
      if (info->file_version == 0)
      {
        gint i;

        g_message (_("XCF warning: version 0 of XCF file format\n"
           "did not save indexed colormaps correctly.\n"
           "Substituting grayscale map."));
        info->cp +=
          xcf_read_int32 (info->fp, (guint32*) &gimage->num_cols, 1);
        gimage->cmap = g_new (guchar, gimage->num_cols*3);
        xcf_seek_pos (info, info->cp + gimage->num_cols);
        for (i = 0; i<gimage->num_cols; i++)
          {
            gimage->cmap[i*3+0] = i;
            gimage->cmap[i*3+1] = i;
            gimage->cmap[i*3+2] = i;
          }
      }
      else
      {
        info->cp +=
          xcf_read_int32 (info->fp, (guint32*) &gimage->num_cols, 1);
        gimage->cmap = g_new (guchar, gimage->num_cols*3);
        info->cp +=
          xcf_read_int8 (info->fp,
                   (guint8*) gimage->cmap, gimage->num_cols*3);
      }
     */
        break;
      }
      case PROP_COMPRESSION:
      {
        doc_info.compression = ReadBlobByte(image);
        if ((doc_info.compression != COMPRESS_NONE) &&
            (doc_info.compression != COMPRESS_RLE) &&
            (doc_info.compression != COMPRESS_ZLIB) &&
            (doc_info.compression != COMPRESS_FRACTAL))
          ThrowReaderException(CorruptImageError,"UnrecognizedImageCompression");
      }
      break;

      case PROP_GUIDES:
      {
         /* just skip it - we don't care about guides */
        for (i=0; i < (ssize_t) prop_size; i++ )
          if (ReadBlobByte(image) == EOF)
            ThrowFileException(exception,CorruptImageError,
              "UnexpectedEndOfFile",image->filename);
      }
      break;

    case PROP_RESOLUTION:
      {
        /* float xres = (float) */ (void) ReadBlobMSBLong(image);
        /* float yres = (float) */ (void) ReadBlobMSBLong(image);

        /*
        if (xres < GIMP_MIN_RESOLUTION || xres > GIMP_MAX_RESOLUTION ||
            yres < GIMP_MIN_RESOLUTION || yres > GIMP_MAX_RESOLUTION)
        {
        g_message ("Warning, resolution out of range in XCF file");
        xres = gimage->gimp->config->default_xresolution;
        yres = gimage->gimp->config->default_yresolution;
        }
        */


        /* BOGUS: we don't write these yet because we aren't
              reading them properly yet :(
              image->x_resolution = xres;
              image->y_resolution = yres;
        */
      }
      break;

    case PROP_TATTOO:
      {
        /* we need to read it, even if we ignore it */
        /*size_t  tattoo_state = */ (void) ReadBlobMSBLong(image);
      }
      break;

    case PROP_PARASITES:
      {
        /* BOGUS: we may need these for IPTC stuff */
        for (i=0; i < (ssize_t) prop_size; i++ )
          if (ReadBlobByte(image) == EOF)
            ThrowFileException(exception,CorruptImageError,
              "UnexpectedEndOfFile",image->filename);

        /*
      gssize_t         base = info->cp;
      GimpParasite *p;

      while (info->cp - base < prop_size)
        {
          p = xcf_load_parasite (info);
          gimp_image_parasite_attach (gimage, p);
          gimp_parasite_free (p);
        }
      if (info->cp - base != prop_size)
        g_message ("Error detected while loading an image's parasites");
      */
          }
      break;

    case PROP_UNIT:
      {
        /* BOGUS: ignore for now... */
      /*size_t unit =  */ (void) ReadBlobMSBLong(image);
      }
      break;

    case PROP_PATHS:
      {
      /* BOGUS: just skip it for now */
        for (i=0; i< (ssize_t) prop_size; i++ )
          if (ReadBlobByte(image) == EOF)
            ThrowFileException(exception,CorruptImageError,
              "UnexpectedEndOfFile",image->filename);

        /*
      PathList *paths = xcf_load_bzpaths (gimage, info);
      gimp_image_set_paths (gimage, paths);
      */
      }
      break;

    case PROP_USER_UNIT:
      {
        char  unit_string[1000];
        /*BOGUS: ignored for now */
        /*float  factor = (float) */ (void) ReadBlobMSBLong(image);
        /* size_t digits =  */ (void) ReadBlobMSBLong(image);
        for (i=0; i<5; i++)
         (void) ReadBlobStringWithLongSize(image, unit_string,
           sizeof(unit_string));
      }
     break;

      default:
      {
        int buf[16];
        ssize_t amount;

      /* read over it... */
      while ((prop_size > 0) && (EOFBlob(image) == MagickFalse))
      {
        amount=(ssize_t) MagickMin(16, prop_size);
        amount=(ssize_t) ReadBlob(image,(size_t) amount,(unsigned char *) &buf);
        if (!amount)
          ThrowReaderException(CorruptImageError,"CorruptImage");
        prop_size -= (size_t) MagickMin(16,(size_t) amount);
      }
    }
    break;
  }
  }
  if (foundPropEnd == MagickFalse)
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");

  if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
    {
      ; /* do nothing, were just pinging! */
    }
  else
    {
      int
        current_layer = 0,
        foundAllLayers = MagickFalse,
        number_layers = 0;

      MagickOffsetType
        oldPos=TellBlob(image);

      XCFLayerInfo
        *layer_info;

      /* 
        the read pointer
      */
      do
      {
        ssize_t offset = (ssize_t) ReadBlobMSBLong(image);
        if (offset == 0)
          foundAllLayers=MagickTrue;
        else
          number_layers++;
        if (EOFBlob(image) != MagickFalse)
          {
            ThrowFileException(exception,CorruptImageError,
              "UnexpectedEndOfFile",image->filename);
            break;
          }
    } while (foundAllLayers == MagickFalse);
    offset=SeekBlob(image,oldPos,SEEK_SET); /* restore the position! */
    if (offset < 0)
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    /* allocate our array of layer info blocks */
    length=(size_t) number_layers;
    layer_info=(XCFLayerInfo *) AcquireQuantumMemory(length,
      sizeof(*layer_info));
    if (layer_info == (XCFLayerInfo *) NULL)
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    (void) ResetMagickMemory(layer_info,0,number_layers*sizeof(XCFLayerInfo));
    for ( ; ; )
    {
      MagickBooleanType
        layer_ok;

      MagickOffsetType
        offset,
        saved_pos;

      /* read in the offset of the next layer */
      offset=(MagickOffsetType) ReadBlobMSBLong(image);
      /* if the offset is 0 then we are at the end
      *  of the layer list.
      */
      if (offset == 0)
        break;
      /* save the current position as it is where the
      *  next layer offset is stored.
      */
      saved_pos=TellBlob(image);
      /* seek to the layer offset */
      offset=SeekBlob(image,offset,SEEK_SET);
      /* read in the layer */
      layer_ok=ReadOneLayer(image,&doc_info,&layer_info[current_layer]);
      if (layer_ok == MagickFalse)
        {
          int j;

          for (j=0; j < current_layer; j++)
            layer_info[j].image=DestroyImage(layer_info[j].image);
        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
      }
      /* restore the saved position so we'll be ready to
      *  read the next offset.
      */
      offset=SeekBlob(image, saved_pos, SEEK_SET);
      current_layer++;
    }
    if (number_layers == 1)
      {
        /*
          Composite the layer data onto the main image, dispose the layer.
        */
        (void) CompositeImage(image,OverCompositeOp,layer_info[0].image,
          layer_info[0].offset_x,layer_info[0].offset_y);
        layer_info[0].image =DestroyImage( layer_info[0].image);
      }
    else
      {
#if 0
        {
        /* NOTE: XCF layers are REVERSED from composite order! */
        signed int  j;
        for (j=number_layers-1; j>=0; j--) {
          /* BOGUS: need to consider layer blending modes!! */

          if ( layer_info[j].visible ) { /* only visible ones, please! */
            CompositeImage(image, OverCompositeOp, layer_info[j].image,
                     layer_info[j].offset_x, layer_info[j].offset_y );
             layer_info[j].image =DestroyImage( layer_info[j].image );

            /* Bob says that if we do this, we'll get REAL gray images! */
            if ( image_type == GIMP_GRAY ) {
              QuantizeInfo  qi;
              GetQuantizeInfo(&qi);
              qi.colorspace = GRAYColorspace;
              QuantizeImage( &qi, layer_info[j].image );
            }
          }
        }
      }
#else
      {
        /* NOTE: XCF layers are REVERSED from composite order! */
        signed int  j;

        /* first we copy the last layer on top of the main image */
        (void) CompositeImage(image,CopyCompositeOp,
          layer_info[number_layers-1].image,
          layer_info[number_layers-1].offset_x,
          layer_info[number_layers-1].offset_y);
          layer_info[number_layers-1].image=DestroyImage(
            layer_info[number_layers-1].image);

        /* now reverse the order of the layers as they are put
           into subimages
        */
        j=number_layers-2;
        image->next=layer_info[j].image;
        layer_info[j].image->previous=image;
        layer_info[j].image->page.x=layer_info[j].offset_x;
        layer_info[j].image->page.y=layer_info[j].offset_y;
        layer_info[j].image->page.width=layer_info[j].width;
        layer_info[j].image->page.height=layer_info[j].height;
        for (j=number_layers-3; j>=0; j--)
        {
          if (j > 0)
            layer_info[j].image->next=layer_info[j-1].image;
          if (j < (number_layers-1))
            layer_info[j].image->previous=layer_info[j+1].image;
          layer_info[j].image->page.x=layer_info[j].offset_x;
          layer_info[j].image->page.y=layer_info[j].offset_y;
          layer_info[j].image->page.width=layer_info[j].width;
          layer_info[j].image->page.height=layer_info[j].height;
        }
      }
#endif
    }

    layer_info=(XCFLayerInfo *) RelinquishMagickMemory(layer_info);

#if 0  /* BOGUS: do we need the channels?? */
    while (MagickTrue)
    {
      /* read in the offset of the next channel */
      info->cp += xcf_read_int32 (info->fp, &offset, 1);

      /* if the offset is 0 then we are at the end
      *  of the channel list.
      */
      if (offset == 0)
        break;

      /* save the current position as it is where the
      *  next channel offset is stored.
      */
      saved_pos = info->cp;

      /* seek to the channel offset */
      xcf_seek_pos (info, offset);

      /* read in the layer */
      channel = xcf_load_channel (info, gimage);
      if (channel == 0)
        goto error;

      num_successful_elements++;

      /* add the channel to the image if its not the selection */
      if (channel != gimage->selection_mask)
        gimp_image_add_channel (gimage, channel, -1);

      /* restore the saved position so we'll be ready to
      *  read the next offset.
      */
      xcf_seek_pos (info, saved_pos);
    }
#endif
  }

  (void) CloseBlob(image);
  if (image_type == GIMP_GRAY)
    image->type=GrayscaleType;
  return(GetFirstImageInList(image));
}
Esempio n. 7
0
static MagickBooleanType ReadOneLayer(Image* image,XCFDocInfo* inDocInfo,
  XCFLayerInfo *outLayer )
{
  ssize_t
    i;

  MagickOffsetType
    offset;

  unsigned int
    foundPropEnd = 0;

  size_t
    hierarchy_offset,
    layer_mask_offset;

  /* clear the block! */
  (void) ResetMagickMemory( outLayer, 0, sizeof( XCFLayerInfo ) );
  /* read in the layer width, height, type and name */
  outLayer->width = ReadBlobMSBLong(image);
  outLayer->height = ReadBlobMSBLong(image);
  outLayer->type = ReadBlobMSBLong(image);
  (void) ReadBlobStringWithLongSize(image, outLayer->name,
    sizeof(outLayer->name));
  /* allocate the image for this layer */
  outLayer->image=CloneImage(image,outLayer->width, outLayer->height,MagickTrue,
     &image->exception);
  if (outLayer->image == (Image *) NULL)
    return MagickFalse;
  /* read the layer properties! */
  foundPropEnd = 0;
  while ( (foundPropEnd == MagickFalse) && (EOFBlob(image) == MagickFalse) ) {
  PropType    prop_type = (PropType) ReadBlobMSBLong(image);
  size_t  prop_size = ReadBlobMSBLong(image);
    switch (prop_type)
    {
    case PROP_END:
      foundPropEnd = 1;
      break;
    case PROP_ACTIVE_LAYER:
      outLayer->active = 1;
      break;
    case PROP_FLOATING_SELECTION:
      outLayer->floating_offset = ReadBlobMSBLong(image);
      break;
    case PROP_OPACITY:
      outLayer->opacity = ReadBlobMSBLong(image);
      break;
    case PROP_VISIBLE:
      outLayer->visible = ReadBlobMSBLong(image);
      break;
    case PROP_LINKED:
      outLayer->linked = ReadBlobMSBLong(image);
      break;
    case PROP_PRESERVE_TRANSPARENCY:
      outLayer->preserve_trans = ReadBlobMSBLong(image);
      break;
    case PROP_APPLY_MASK:
      outLayer->apply_mask = ReadBlobMSBLong(image);
      break;
    case PROP_EDIT_MASK:
      outLayer->edit_mask = ReadBlobMSBLong(image);
      break;
    case PROP_SHOW_MASK:
      outLayer->show_mask = ReadBlobMSBLong(image);
      break;
    case PROP_OFFSETS:
      outLayer->offset_x = (ssize_t) ReadBlobMSBLong(image);
      outLayer->offset_y = (ssize_t) ReadBlobMSBLong(image);
      break;
    case PROP_MODE:
      outLayer->mode = ReadBlobMSBLong(image);
      break;
    case PROP_TATTOO:
      outLayer->preserve_trans = ReadBlobMSBLong(image);
      break;
     case PROP_PARASITES:
     {
        for (i=0; i < (ssize_t) prop_size; i++ )
          (void) ReadBlobByte(image);

        /*
       ssize_t base = info->cp;
       GimpParasite *p;
       while (info->cp - base < prop_size)
       {
       p = xcf_load_parasite(info);
       gimp_drawable_parasite_attach(GIMP_DRAWABLE(layer), p);
       gimp_parasite_free(p);
       }
       if (info->cp - base != prop_size)
       g_message ("Error detected while loading a layer's parasites");
       */
     }
     break;
    default:
      /* g_message ("unexpected/unknown layer property: %d (skipping)",
         prop_type); */

      {
      int buf[16];
      ssize_t amount;

      /* read over it... */
      while ((prop_size > 0) && (EOFBlob(image) == MagickFalse))
        {
        amount = (ssize_t) MagickMin(16, prop_size);
        amount = ReadBlob(image, (size_t) amount, (unsigned char *) &buf);
        if (!amount)
          ThrowBinaryException(CorruptImageError,"CorruptImage",
            image->filename);
        prop_size -= (size_t) MagickMin(16, (size_t) amount);
        }
      }
      break;
    }
  }

  if (foundPropEnd == MagickFalse)
    return(MagickFalse);
  /* clear the image based on the layer opacity */
  outLayer->image->background_color.opacity=
    ScaleCharToQuantum((unsigned char) (255-outLayer->opacity));    
  (void) SetImageBackgroundColor(outLayer->image);

  /* set the compositing mode */
  outLayer->image->compose = GIMPBlendModeToCompositeOperator( outLayer->mode );
  if ( outLayer->visible == MagickFalse )
    {
      /* BOGUS: should really be separate member var! */
      outLayer->image->compose = NoCompositeOp;
    }

  /* read the hierarchy and layer mask offsets */
  hierarchy_offset = ReadBlobMSBLong(image);
  layer_mask_offset = ReadBlobMSBLong(image);

  /* read in the hierarchy */
  offset=SeekBlob(image, (MagickOffsetType) hierarchy_offset, SEEK_SET);
  if (offset < 0)
    (void) ThrowMagickException(&image->exception,GetMagickModule(),
      CorruptImageError,"InvalidImageHeader","`%s'",image->filename);
  if (load_hierarchy (image, inDocInfo, outLayer) == 0)
    return(MagickFalse);

  /* read in the layer mask */
  if (layer_mask_offset != 0)
    {
      offset=SeekBlob(image, (MagickOffsetType) layer_mask_offset, SEEK_SET);

#if 0  /* BOGUS: support layer masks! */
      layer_mask = xcf_load_layer_mask (info, gimage);
      if (layer_mask == 0)
  goto error;

      /* set the offsets of the layer_mask */
      GIMP_DRAWABLE (layer_mask)->offset_x = GIMP_DRAWABLE (layer)->offset_x;
      GIMP_DRAWABLE (layer_mask)->offset_y = GIMP_DRAWABLE (layer)->offset_y;

      gimp_layer_add_mask (layer, layer_mask, MagickFalse);

      layer->mask->apply_mask = apply_mask;
      layer->mask->edit_mask  = edit_mask;
      layer->mask->show_mask  = show_mask;
#endif
  }

  /* attach the floating selection... */
#if 0  /* BOGUS: we may need to read this, even if we don't support it! */
  if (add_floating_sel)
    {
      GimpLayer *floating_sel;

      floating_sel = info->floating_sel;
      floating_sel_attach (floating_sel, GIMP_DRAWABLE (layer));
    }
#endif

  return MagickTrue;
}
Esempio n. 8
0
static MagickBooleanType load_level(Image *image,XCFDocInfo *inDocInfo,
  XCFLayerInfo *inLayerInfo)
{
  ExceptionInfo
    *exception;

  int
    destLeft = 0,
    destTop = 0;

  Image*
    tile_image;

  MagickBooleanType
    status;

  MagickOffsetType
    saved_pos,
    offset,
    offset2;

  register ssize_t
    i;

  size_t
    width,
    height,
    ntiles,
    ntile_rows,
    ntile_cols,
    tile_image_width,
    tile_image_height;

  /* start reading the data */
  exception=inDocInfo->exception;
  width=ReadBlobMSBLong(image);
  height=ReadBlobMSBLong(image);

  /* read in the first tile offset.
   *  if it is '0', then this tile level is empty
   *  and we can simply return.
   */
  offset=(MagickOffsetType) ReadBlobMSBLong(image);
  if (offset == 0)
    return(MagickTrue);
  /* Initialise the reference for the in-memory tile-compression
   */
  ntile_rows=(height+TILE_HEIGHT-1)/TILE_HEIGHT;
  ntile_cols=(width+TILE_WIDTH-1)/TILE_WIDTH;
  ntiles=ntile_rows*ntile_cols;
  for (i = 0; i < (ssize_t) ntiles; i++)
  {
    status=MagickFalse;
    if (offset == 0)
      ThrowBinaryException(CorruptImageError,"NotEnoughTiles",image->filename);
    /* save the current position as it is where the
     *  next tile offset is stored.
     */
    saved_pos=TellBlob(image);
    /* read in the offset of the next tile so we can calculate the amount
       of data needed for this tile*/
    offset2=(MagickOffsetType)ReadBlobMSBLong(image);
    /* if the offset is 0 then we need to read in the maximum possible
       allowing for negative compression */
    if (offset2 == 0)
      offset2=(MagickOffsetType) (offset + TILE_WIDTH * TILE_WIDTH * 4* 1.5);
    /* seek to the tile offset */
    offset=SeekBlob(image, offset, SEEK_SET);

      /* allocate the image for the tile
        NOTE: the last tile in a row or column may not be a full tile!
      */
      tile_image_width=(size_t) (destLeft == (int) ntile_cols-1 ?
        (int) width % TILE_WIDTH : TILE_WIDTH);
      if (tile_image_width == 0) tile_image_width=TILE_WIDTH;
      tile_image_height = (size_t) (destTop == (int) ntile_rows-1 ?
        (int) height % TILE_HEIGHT : TILE_HEIGHT);
      if (tile_image_height == 0) tile_image_height=TILE_HEIGHT;
      tile_image=CloneImage(inLayerInfo->image,tile_image_width,
        tile_image_height,MagickTrue,exception);

      /* read in the tile */
      switch (inDocInfo->compression)
      {
        case COMPRESS_NONE:
          if (load_tile(image,tile_image,inDocInfo,inLayerInfo,(size_t) (offset2-offset)) == 0)
            status=MagickTrue;
          break;
        case COMPRESS_RLE:
          if (load_tile_rle (image,tile_image,inDocInfo,inLayerInfo,
              (int) (offset2-offset)) == 0)
            status=MagickTrue;
          break;
        case COMPRESS_ZLIB:
          ThrowBinaryException(CoderError,"ZipCompressNotSupported",
            image->filename)
        case COMPRESS_FRACTAL:
          ThrowBinaryException(CoderError,"FractalCompressNotSupported",
            image->filename)
      }

      /* composite the tile onto the layer's image, and then destroy it */
      (void) CompositeImage(inLayerInfo->image,CopyCompositeOp,tile_image,
        destLeft * TILE_WIDTH,destTop*TILE_HEIGHT);
      tile_image=DestroyImage(tile_image);

      /* adjust tile position */
      destLeft++;
      if (destLeft >= (int) ntile_cols)
        {
          destLeft = 0;
          destTop++;
        }
      if (status != MagickFalse)
        return(MagickFalse);
      /* restore the saved position so we'll be ready to
       *  read the next offset.
       */
      offset=SeekBlob(image, saved_pos, SEEK_SET);
      /* read in the offset of the next tile */
      offset=(MagickOffsetType) ReadBlobMSBLong(image);
    }
  if (offset != 0)
    ThrowBinaryException(CorruptImageError,"CorruptImage",image->filename)
  return(MagickTrue);
}
Esempio n. 9
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d R L A I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadRLAImage() reads a run-length encoded Wavefront RLA image file
%  and returns it.  It allocates the memory necessary for the new Image
%  structure and returns a pointer to the new image.
%
%  Note:  This module was contributed by Lester Vecsey ([email protected]).
%
%  The format of the ReadRLAImage method is:
%
%      Image *ReadRLAImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *ReadRLAImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  typedef struct _WindowFrame
  {
    short
      left,
      right,
      bottom,
      top;
  } WindowFrame;

  typedef struct _RLAInfo
  {
    WindowFrame
      window,
      active_window;

    short
      frame,
      storage_type,
      number_channels,
      number_matte_channels,
      number_auxiliary_channels,
      revision;

    char
      gamma[16],
      red_primary[24],
      green_primary[24],
      blue_primary[24],
      white_point[24];

    ssize_t
      job_number;

    char
      name[128],
      description[128],
      program[64],
      machine[32],
      user[32],
      date[20],
      aspect[24],
      aspect_ratio[8],
      chan[32];

    short
      field;

    char
      time[12],
      filter[32];

    short
      bits_per_channel,
      matte_type,
      matte_bits,
      auxiliary_type,
      auxiliary_bits;

    char
      auxiliary[32],
      space[36];

    ssize_t
      next;
  } RLAInfo;

  Image
    *image;

  int
    channel,
    length,
    runlength;

  MagickBooleanType
    status;

  MagickOffsetType
    offset;

  register ssize_t
    i,
    x;

  register PixelPacket
    *q;

  ssize_t
    count,
    *scanlines,
    y;

  RLAInfo
    rla_info;

  unsigned char
    byte;

  /*
    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);
    }
  rla_info.window.left=(short) ReadBlobMSBShort(image);
  rla_info.window.right=(short) ReadBlobMSBShort(image);
  rla_info.window.bottom=(short) ReadBlobMSBShort(image);
  rla_info.window.top=(short) ReadBlobMSBShort(image);
  rla_info.active_window.left=(short) ReadBlobMSBShort(image);
  rla_info.active_window.right=(short) ReadBlobMSBShort(image);
  rla_info.active_window.bottom=(short) ReadBlobMSBShort(image);
  rla_info.active_window.top=(short) ReadBlobMSBShort(image);
  rla_info.frame=(short) ReadBlobMSBShort(image);
  rla_info.storage_type=(short) ReadBlobMSBShort(image);
  rla_info.number_channels=(short) ReadBlobMSBShort(image);
  rla_info.number_matte_channels=(short) ReadBlobMSBShort(image);
  if (rla_info.number_channels == 0)
    rla_info.number_channels=3;
  rla_info.number_channels+=rla_info.number_matte_channels;
  rla_info.number_auxiliary_channels=(short) ReadBlobMSBShort(image);
  rla_info.revision=(short) ReadBlobMSBShort(image);
  count=ReadBlob(image,16,(unsigned char *) rla_info.gamma);
  count=ReadBlob(image,24,(unsigned char *) rla_info.red_primary);
  count=ReadBlob(image,24,(unsigned char *) rla_info.green_primary);
  count=ReadBlob(image,24,(unsigned char *) rla_info.blue_primary);
  count=ReadBlob(image,24,(unsigned char *) rla_info.white_point);
  rla_info.job_number=(int) ReadBlobMSBLong(image);
  count=ReadBlob(image,128,(unsigned char *) rla_info.name);
  count=ReadBlob(image,128,(unsigned char *) rla_info.description);
  count=ReadBlob(image,64,(unsigned char *) rla_info.program);
  count=ReadBlob(image,32,(unsigned char *) rla_info.machine);
  count=ReadBlob(image,32,(unsigned char *) rla_info.user);
  count=ReadBlob(image,20,(unsigned char *) rla_info.date);
  count=ReadBlob(image,24,(unsigned char *) rla_info.aspect);
  count=ReadBlob(image,8,(unsigned char *) rla_info.aspect_ratio);
  count=ReadBlob(image,32,(unsigned char *) rla_info.chan);
  rla_info.field=(short) ReadBlobMSBShort(image);
  count=ReadBlob(image,12,(unsigned char *) rla_info.time);
  count=ReadBlob(image,32,(unsigned char *) rla_info.filter);
  rla_info.bits_per_channel=(short) ReadBlobMSBShort(image);
  rla_info.matte_type=(short) ReadBlobMSBShort(image);
  rla_info.matte_bits=(short) ReadBlobMSBShort(image);
  rla_info.auxiliary_type=(short) ReadBlobMSBShort(image);
  rla_info.auxiliary_bits=(short) ReadBlobMSBShort(image);
  count=ReadBlob(image,32,(unsigned char *) rla_info.auxiliary);
  count=ReadBlob(image,36,(unsigned char *) rla_info.space);
  if ((size_t) count != 36)
    ThrowReaderException(CorruptImageError,"UnableToReadImageData");
  rla_info.next=(int) ReadBlobMSBLong(image);
  /*
    Initialize image structure.
  */
  image->matte=rla_info.number_matte_channels != 0 ? MagickTrue : MagickFalse;
  image->columns=1UL*rla_info.active_window.right-rla_info.active_window.left+1;
  image->rows=1UL*rla_info.active_window.top-rla_info.active_window.bottom+1;
  if (image_info->ping != MagickFalse)
    {
      (void) CloseBlob(image);
      return(GetFirstImageInList(image));
    }
  scanlines=(ssize_t *) AcquireQuantumMemory(image->rows,sizeof(*scanlines));
  if (scanlines == (ssize_t *) NULL)
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  if (*rla_info.description != '\0')
    (void) SetImageProperty(image,"comment",rla_info.description);
  /*
    Read offsets to each scanline data.
  */
  for (i=0; i < (ssize_t) image->rows; i++)
    scanlines[i]=(int) ReadBlobMSBLong(image);
  /*
    Read image data.
  */
  x=0;
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    offset=SeekBlob(image,scanlines[image->rows-y-1],SEEK_SET);
    if (offset < 0)
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    for (channel=0; channel < (int) rla_info.number_channels; channel++)
    {
      length=(int) ReadBlobMSBShort(image);
      while (length > 0)
      {
        byte=(unsigned char) ReadBlobByte(image);
        runlength=byte;
        if (byte > 127)
          runlength=byte-256;
        length--;
        if (length == 0)
          break;
        if (runlength < 0)
          {
            while (runlength < 0)
            {
              q=GetAuthenticPixels(image,(ssize_t) (x % image->columns),
                (ssize_t) (y % image->rows),1,1,exception);
              if (q == (PixelPacket *) NULL)
                break;
              byte=(unsigned char) ReadBlobByte(image);
              length--;
              switch (channel)
              {
                case 0:
                {
                  SetPixelRed(q,ScaleCharToQuantum(byte));
                  break;
                }
                case 1:
                {
                  SetPixelGreen(q,ScaleCharToQuantum(byte));
                  break;
                }
                case 2:
                {
                  SetPixelBlue(q,ScaleCharToQuantum(byte));
                  break;
                }
                case 3:
                default:
                {
                  SetPixelAlpha(q,ScaleCharToQuantum(byte));
                  break;
                }
              }
              if (SyncAuthenticPixels(image,exception) == MagickFalse)
                break;
              x++;
              runlength++;
            }
            continue;
          }
        byte=(unsigned char) ReadBlobByte(image);
        length--;
        runlength++;
        do
        {
          q=GetAuthenticPixels(image,(ssize_t) (x % image->columns),
            (ssize_t) (y % image->rows),1,1,exception);
          if (q == (PixelPacket *) NULL)
            break;
          switch (channel)
          {
            case 0:
            {
              SetPixelRed(q,ScaleCharToQuantum(byte));
              break;
            }
            case 1:
            {
              SetPixelGreen(q,ScaleCharToQuantum(byte));
              break;
            }
            case 2:
            {
              SetPixelBlue(q,ScaleCharToQuantum(byte));
              break;
            }
            case 3:
            default:
            {
              SetPixelAlpha(q,ScaleCharToQuantum(byte));
              break;
            }
          }
          if (SyncAuthenticPixels(image,exception) == MagickFalse)
            break;
          x++;
          runlength--;
        }
        while (runlength > 0);
      }
    }
    status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
      image->rows);
    if (status == MagickFalse)
      break;
  }
  if (EOFBlob(image) != MagickFalse)
    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
      image->filename);
  (void) CloseBlob(image);
  return(GetFirstImageInList(image));
}
Esempio n. 10
0
File: sgi.c Progetto: acal/alchemy
static Image *ReadSGIImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  Image
    *image;

  MagickBooleanType
    status;

  MagickSizeType
    number_pixels;

  MemoryInfo
    *pixel_info;

  register IndexPacket
    *indexes;

  register PixelPacket
    *q;

  register ssize_t
    i,
    x;

  register unsigned char
    *p;

  SGIInfo
    iris_info;

  size_t
    bytes_per_pixel,
    quantum;

  ssize_t
    count,
    y,
    z;

  unsigned char
    *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);
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    {
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  /*
    Read SGI raster header.
  */
  iris_info.magic=ReadBlobMSBShort(image);
  do
  {
    /*
      Verify SGI identifier.
    */
    if (iris_info.magic != 0x01DA)
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    iris_info.storage=(unsigned char) ReadBlobByte(image);
    switch (iris_info.storage)
    {
      case 0x00: image->compression=NoCompression; break;
      case 0x01: image->compression=RLECompression; break;
      default:
        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    }
    iris_info.bytes_per_pixel=(unsigned char) ReadBlobByte(image);
    if ((iris_info.bytes_per_pixel == 0) || (iris_info.bytes_per_pixel > 2))
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    iris_info.dimension=ReadBlobMSBShort(image);
    iris_info.columns=ReadBlobMSBShort(image);
    iris_info.rows=ReadBlobMSBShort(image);
    iris_info.depth=ReadBlobMSBShort(image);
    if ((iris_info.depth == 0) || (iris_info.depth > 4))
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    iris_info.minimum_value=ReadBlobMSBLong(image);
    iris_info.maximum_value=ReadBlobMSBLong(image);
    iris_info.sans=ReadBlobMSBLong(image);
    (void) ReadBlob(image,sizeof(iris_info.name),(unsigned char *)
      iris_info.name);
    iris_info.name[sizeof(iris_info.name)-1]='\0';
    if (*iris_info.name != '\0')
      (void) SetImageProperty(image,"label",iris_info.name);
    iris_info.pixel_format=ReadBlobMSBLong(image);
    if (iris_info.pixel_format != 0)
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    count=ReadBlob(image,sizeof(iris_info.filler),iris_info.filler);
    (void) count;
    image->columns=iris_info.columns;
    image->rows=iris_info.rows;
    image->depth=(size_t) MagickMin(iris_info.depth,MAGICKCORE_QUANTUM_DEPTH);
    if (iris_info.pixel_format == 0)
      image->depth=(size_t) MagickMin((size_t) 8*
        iris_info.bytes_per_pixel,MAGICKCORE_QUANTUM_DEPTH);
    if (iris_info.depth < 3)
      {
        image->storage_class=PseudoClass;
        image->colors=iris_info.bytes_per_pixel > 1 ? 65535 : 256;
      }
    if ((image_info->ping != MagickFalse)  && (image_info->number_scenes != 0))
      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
        break;
    status=SetImageExtent(image,image->columns,image->rows);
    if (status == MagickFalse)
      {
        InheritException(exception,&image->exception);
        return(DestroyImageList(image));
      }
    /*
      Allocate SGI pixels.
    */
    bytes_per_pixel=(size_t) iris_info.bytes_per_pixel;
    number_pixels=(MagickSizeType) iris_info.columns*iris_info.rows;
    if ((4*bytes_per_pixel*number_pixels) != ((MagickSizeType) (size_t)
        (4*bytes_per_pixel*number_pixels)))
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    pixel_info=AcquireVirtualMemory(iris_info.columns,iris_info.rows*4*
      bytes_per_pixel*sizeof(*pixels));
    if (pixel_info == (MemoryInfo *) NULL)
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
    if ((int) iris_info.storage != 0x01)
      {
        unsigned char
          *scanline;

        /*
          Read standard image format.
        */
        scanline=(unsigned char *) AcquireQuantumMemory(iris_info.columns,
          bytes_per_pixel*sizeof(*scanline));
        if (scanline == (unsigned char *) NULL)
          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        for (z=0; z < (ssize_t) iris_info.depth; z++)
        {
          p=pixels+bytes_per_pixel*z;
          for (y=0; y < (ssize_t) iris_info.rows; y++)
          {
            count=ReadBlob(image,bytes_per_pixel*iris_info.columns,scanline);
            if (EOFBlob(image) != MagickFalse)
              break;
            if (bytes_per_pixel == 2)
              for (x=0; x < (ssize_t) iris_info.columns; x++)
              {
                *p=scanline[2*x];
                *(p+1)=scanline[2*x+1];
                p+=8;
              }
            else
              for (x=0; x < (ssize_t) iris_info.columns; x++)
              {
                *p=scanline[x];
                p+=4;
              }
          }
        }
        scanline=(unsigned char *) RelinquishMagickMemory(scanline);
      }
    else
      {
        MemoryInfo
          *packet_info;

        size_t
          *runlength;

        ssize_t
          offset,
          *offsets;

        unsigned char
          *packets;

        unsigned int
          data_order;

        /*
          Read runlength-encoded image format.
        */
        offsets=(ssize_t *) AcquireQuantumMemory((size_t) iris_info.rows,
          iris_info.depth*sizeof(*offsets));
        runlength=(size_t *) AcquireQuantumMemory(iris_info.rows,
          iris_info.depth*sizeof(*runlength));
        packet_info=AcquireVirtualMemory((size_t) iris_info.columns+10UL,4UL*
          sizeof(*packets));
        if ((offsets == (ssize_t *) NULL) ||
            (runlength == (size_t *) NULL) ||
            (packet_info == (MemoryInfo *) NULL))
          {
            if (offsets == (ssize_t *) NULL)
              offsets=(ssize_t *) RelinquishMagickMemory(offsets);
            if (runlength == (size_t *) NULL)
              runlength=(size_t *) RelinquishMagickMemory(runlength);
            if (packet_info == (MemoryInfo *) NULL)
              packet_info=RelinquishVirtualMemory(packet_info);
            ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
          }
        packets=(unsigned char *) GetVirtualMemoryBlob(packet_info);
        for (i=0; i < (ssize_t) (iris_info.rows*iris_info.depth); i++)
          offsets[i]=(int) ReadBlobMSBLong(image);
        for (i=0; i < (ssize_t) (iris_info.rows*iris_info.depth); i++)
        {
          runlength[i]=ReadBlobMSBLong(image);
          if (runlength[i] > (4*(size_t) iris_info.columns+10))
            ThrowReaderException(CorruptImageError,"ImproperImageHeader");
        }
        /*
          Check data order.
        */
        offset=0;
        data_order=0;
        for (y=0; ((y < (ssize_t) iris_info.rows) && (data_order == 0)); y++)
          for (z=0; ((z < (ssize_t) iris_info.depth) && (data_order == 0)); z++)
          {
            if (offsets[y+z*iris_info.rows] < offset)
              data_order=1;
            offset=offsets[y+z*iris_info.rows];
          }
        offset=(ssize_t) TellBlob(image);
        if (data_order == 1)
          {
            for (z=0; z < (ssize_t) iris_info.depth; z++)
            {
              p=pixels;
              for (y=0; y < (ssize_t) iris_info.rows; y++)
              {
                if (offset != offsets[y+z*iris_info.rows])
                  {
                    offset=offsets[y+z*iris_info.rows];
                    offset=(ssize_t) SeekBlob(image,(ssize_t) offset,SEEK_SET);
                  }
                count=ReadBlob(image,(size_t) runlength[y+z*iris_info.rows],
                  packets);
                if (EOFBlob(image) != MagickFalse)
                  break;
                offset+=(ssize_t) runlength[y+z*iris_info.rows];
                status=SGIDecode(bytes_per_pixel,(ssize_t)
                  (runlength[y+z*iris_info.rows]/bytes_per_pixel),packets,
                  1L*iris_info.columns,p+bytes_per_pixel*z);
                if (status == MagickFalse)
                  ThrowReaderException(CorruptImageError,"ImproperImageHeader");
                p+=(iris_info.columns*4*bytes_per_pixel);
              }
            }
          }
        else
          {
            MagickOffsetType
              position;

            position=TellBlob(image);
            p=pixels;
            for (y=0; y < (ssize_t) iris_info.rows; y++)
            {
              for (z=0; z < (ssize_t) iris_info.depth; z++)
              {
                if (offset != offsets[y+z*iris_info.rows])
                  {
                    offset=offsets[y+z*iris_info.rows];
                    offset=(ssize_t) SeekBlob(image,(ssize_t) offset,SEEK_SET);
                  }
                count=ReadBlob(image,(size_t) runlength[y+z*iris_info.rows],
                  packets);
                if (EOFBlob(image) != MagickFalse)
                  break;
                offset+=(ssize_t) runlength[y+z*iris_info.rows];
                status=SGIDecode(bytes_per_pixel,(ssize_t)
                  (runlength[y+z*iris_info.rows]/bytes_per_pixel),packets,
                  1L*iris_info.columns,p+bytes_per_pixel*z);
                if (status == MagickFalse)
                  ThrowReaderException(CorruptImageError,"ImproperImageHeader");
              }
              p+=(iris_info.columns*4*bytes_per_pixel);
            }
            offset=(ssize_t) SeekBlob(image,position,SEEK_SET);
          }
        packet_info=RelinquishVirtualMemory(packet_info);
        runlength=(size_t *) RelinquishMagickMemory(runlength);
        offsets=(ssize_t *) RelinquishMagickMemory(offsets);
      }
    /*
      Initialize image structure.
    */
    image->matte=iris_info.depth == 4 ? MagickTrue : MagickFalse;
    image->columns=iris_info.columns;
    image->rows=iris_info.rows;
    /*
      Convert SGI raster image to pixel packets.
    */
    if (image->storage_class == DirectClass)
      {
        /*
          Convert SGI image to DirectClass pixel packets.
        */
        if (bytes_per_pixel == 2)
          {
            for (y=0; y < (ssize_t) image->rows; y++)
            {
              p=pixels+(image->rows-y-1)*8*image->columns;
              q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
              if (q == (PixelPacket *) NULL)
                break;
              for (x=0; x < (ssize_t) image->columns; x++)
              {
                SetPixelRed(q,ScaleShortToQuantum((unsigned short)
                  ((*(p+0) << 8) | (*(p+1)))));
                SetPixelGreen(q,ScaleShortToQuantum((unsigned short)
                  ((*(p+2) << 8) | (*(p+3)))));
                SetPixelBlue(q,ScaleShortToQuantum((unsigned short)
                  ((*(p+4) << 8) | (*(p+5)))));
                SetPixelOpacity(q,OpaqueOpacity);
                if (image->matte != MagickFalse)
                  SetPixelAlpha(q,ScaleShortToQuantum((unsigned short)
                    ((*(p+6) << 8) | (*(p+7)))));
                p+=8;
                q++;
              }
              if (SyncAuthenticPixels(image,exception) == MagickFalse)
                break;
              if (image->previous == (Image *) NULL)
                {
                  status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
                    y,image->rows);
                  if (status == MagickFalse)
                    break;
                }
            }
          }
        else
          for (y=0; y < (ssize_t) image->rows; y++)
          {
            p=pixels+(image->rows-y-1)*4*image->columns;
            q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
            if (q == (PixelPacket *) NULL)
              break;
            for (x=0; x < (ssize_t) image->columns; x++)
            {
              SetPixelRed(q,ScaleCharToQuantum(*p));
              q->green=ScaleCharToQuantum(*(p+1));
              q->blue=ScaleCharToQuantum(*(p+2));
              SetPixelOpacity(q,OpaqueOpacity);
              if (image->matte != MagickFalse)
                SetPixelAlpha(q,ScaleCharToQuantum(*(p+3)));
              p+=4;
              q++;
            }
            if (SyncAuthenticPixels(image,exception) == MagickFalse)
              break;
            if (image->previous == (Image *) NULL)
              {
                status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
                image->rows);
                if (status == MagickFalse)
                  break;
              }
          }
      }
    else
      {
        /*
          Create grayscale map.
        */
        if (AcquireImageColormap(image,image->colors) == MagickFalse)
          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        /*
          Convert SGI image to PseudoClass pixel packets.
        */
        if (bytes_per_pixel == 2)
          {
            for (y=0; y < (ssize_t) image->rows; y++)
            {
              p=pixels+(image->rows-y-1)*8*image->columns;
              q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
              if (q == (PixelPacket *) NULL)
                break;
              indexes=GetAuthenticIndexQueue(image);
              for (x=0; x < (ssize_t) image->columns; x++)
              {
                quantum=(*p << 8);
                quantum|=(*(p+1));
                SetPixelIndex(indexes+x,quantum);
                p+=8;
                q++;
              }
              if (SyncAuthenticPixels(image,exception) == MagickFalse)
                break;
              if (image->previous == (Image *) NULL)
                {
                  status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
                    y,image->rows);
                  if (status == MagickFalse)
                    break;
                }
            }
          }
        else
          for (y=0; y < (ssize_t) image->rows; y++)
          {
            p=pixels+(image->rows-y-1)*4*image->columns;
            q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
            if (q == (PixelPacket *) NULL)
              break;
            indexes=GetAuthenticIndexQueue(image);
            for (x=0; x < (ssize_t) image->columns; x++)
            {
              SetPixelIndex(indexes+x,*p);
              p+=4;
              q++;
            }
            if (SyncAuthenticPixels(image,exception) == MagickFalse)
              break;
            if (image->previous == (Image *) NULL)
              {
                status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
                image->rows);
                if (status == MagickFalse)
                  break;
              }
          }
        (void) SyncImage(image);
      }
    pixel_info=RelinquishVirtualMemory(pixel_info);
    if (EOFBlob(image) != MagickFalse)
      {
        ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
          image->filename);
        break;
      }
    /*
      Proceed to next image.
    */
    if (image_info->number_scenes != 0)
      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
        break;
    iris_info.magic=ReadBlobMSBShort(image);
    if (iris_info.magic == 0x01DA)
      {
        /*
          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 (iris_info.magic == 0x01DA);
  (void) CloseBlob(image);
  return(GetFirstImageInList(image));
}
Esempio n. 11
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d A V S I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadAVSImage() reads an AVS X 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 ReadAVSImage method is:
%
%      Image *ReadAVSImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: The image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *ReadAVSImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  Image
    *image;

  long
    y;

  MagickBooleanType
    status;

  register long
    x;

  register PixelPacket
    *q;

  register unsigned char
    *p;

  ssize_t
    count;

  size_t
    length;

  unsigned char
    *pixels;

  unsigned long
    height,
    width;

  /*
    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=AllocateImage(image_info);
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    {
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  /*
    Read AVS X image.
  */
  width=ReadBlobMSBLong(image);
  height=ReadBlobMSBLong(image);
  if ((width == ~0UL) || (height == ~0UL))
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  do
  {
    /*
      Convert AVS raster image to pixel packets.
    */
    image->columns=width;
    image->rows=height;
    image->depth=8;
    if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
        break;
    if (SetImageExtent(image,0,0) == MagickFalse)
      {
        InheritException(exception,&image->exception);
        return(DestroyImageList(image));
      }
    length=(size_t) image->columns;
    pixels=(unsigned char *) AcquireQuantumMemory(length,4*sizeof(*pixels));
    if (pixels == (unsigned char *) NULL) 
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    length*=4*sizeof(*pixels);
    for (y=0; y < (long) image->rows; y++)
    {
      count=ReadBlob(image,length,pixels);
      if ((size_t) count != length)
        ThrowReaderException(CorruptImageError,"UnableToReadImageData");
      p=pixels;
      q=SetImagePixels(image,0,y,image->columns,1);
      if (q == (PixelPacket *) NULL)
        break;
      for (x=0; x < (long) image->columns; x++)
      {
        q->opacity=(Quantum) (QuantumRange-ScaleCharToQuantum(*p++));
        q->red=ScaleCharToQuantum(*p++);
        q->green=ScaleCharToQuantum(*p++);
        q->blue=ScaleCharToQuantum(*p++);
        if (q->opacity != OpaqueOpacity)
          image->matte=MagickTrue;
        q++;
      }
      if (SyncImagePixels(image) == MagickFalse)
        break;
      if (image->previous == (Image *) NULL)
        if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
            (QuantumTick(y,image->rows) != MagickFalse))
          {
            status=image->progress_monitor(LoadImageTag,y,image->rows,
              image->client_data);
            if (status == MagickFalse)
              break;
          }
    }
    pixels=(unsigned char *) RelinquishMagickMemory(pixels);
    if (EOFBlob(image) != MagickFalse)
      {
        ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
          image->filename);
        break;
      }
    /*
      Proceed to next image.
    */
    if (image_info->number_scenes != 0)
      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
        break;
    width=ReadBlobMSBLong(image);
    height=ReadBlobMSBLong(image);
    if ((width != ~0UL) && (height != ~0UL))
      {
        /*
          Allocate next image structure.
        */
        AllocateNextImage(image_info,image);
        if (GetNextImageInList(image) == (Image *) NULL)
          {
            image=DestroyImageList(image);
            return((Image *) NULL);
          }
        image=SyncNextImageInList(image);
        if (image->progress_monitor != (MagickProgressMonitor) NULL)
          {
            status=image->progress_monitor(LoadImagesTag,TellBlob(image),
              GetBlobSize(image),image->client_data);
            if (status == MagickFalse)
              break;
          }
      }
  } while ((width != ~0UL) && (height != ~0UL));
  CloseBlob(image);
  return(GetFirstImageInList(image));
}
Esempio n. 12
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d S U N I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method ReadSUNImage reads a SUN 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 ReadSUNImage method is:
%
%      Image *ReadSUNImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image:  Method ReadSUNImage returns a pointer to the image after
%      reading.  A null image is returned if there is a memory shortage or
%      if the image cannot be read.
%
%    o image_info: Specifies a pointer to a ImageInfo structure.
%
%    o exception: return any errors or warnings in this structure.
%
%
*/
static Image *ReadSUNImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  Image
    *image;

  int
    bit;

  long
    y;

  register IndexPacket
    *indexes;

  register long
    x;

  register PixelPacket
    *q;

  register long
    i;

  register unsigned char
    *p;

  size_t
    bytes_per_image,
    bytes_per_line,
    count,
    sun_data_length;

  SUNInfo
    sun_info;

  unsigned char
    *sun_data,
    *sun_pixels;

  unsigned int
    index;

  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);
  /*
    Read SUN raster header.
  */
  (void) memset(&sun_info,0,sizeof(sun_info));
  sun_info.magic=ReadBlobMSBLong(image);
  do
  {
    /*
      Verify SUN identifier.
    */
    if (sun_info.magic != 0x59a66a95)
      ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
    sun_info.width=ReadBlobMSBLong(image);
    sun_info.height=ReadBlobMSBLong(image);
    sun_info.depth=ReadBlobMSBLong(image);
    sun_info.length=ReadBlobMSBLong(image);
    sun_info.type=ReadBlobMSBLong(image);
    sun_info.maptype=ReadBlobMSBLong(image);
    sun_info.maplength=ReadBlobMSBLong(image);
    LogSUNInfo(&sun_info);
    if (EOFBlob(image))
      ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
    /*
      Verify that header values are in positive numeric range of a
      32-bit 'int' even though we store them in an unsigned value.
    */
    if ((sun_info.magic | sun_info.width | sun_info.height | sun_info.depth |
         sun_info.type | sun_info.maptype | sun_info.maplength) & (1U << 31))
      ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
    /*
      Verify that we support the image sub-type
    */
    if ((sun_info.type != RT_STANDARD) &&
        (sun_info.type != RT_ENCODED) &&
        (sun_info.type != RT_FORMAT_RGB))
      ThrowReaderException(CoderError,DataEncodingSchemeIsNotSupported,image);
    /*
      Verify that we support the colormap type
    */
    if ((sun_info.maptype != RMT_NONE) &&
        (sun_info.maptype != RMT_EQUAL_RGB))
      ThrowReaderException(CoderError,ColormapTypeNotSupported,image);
    /*
      Insist that map length is zero if there is no colormap.
    */
    if ((sun_info.maptype == RMT_NONE) && (sun_info.maplength != 0))
      ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
    /*
      Insist on a supported depth
    */
    if ((sun_info.depth != 1) &&
        (sun_info.depth != 8) &&
        (sun_info.depth != 24) &&
        (sun_info.depth != 32))
      ThrowReaderException(CorruptImageError,ImproperImageHeader,image);

    image->columns=sun_info.width;
    image->rows=sun_info.height;
    if (((unsigned long) ((long) image->columns) != image->columns) ||
        ((unsigned long) ((long) image->rows) != image->rows))
      ThrowReaderException(CoderError,ImageColumnOrRowSizeIsNotSupported,image);
    if (CheckImagePixelLimits(image, exception) != MagickPass)
        ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
    image->depth=sun_info.depth <= 8 ? 8 : QuantumDepth;
    if (sun_info.depth < 24)
      {
        image->colors=sun_info.maplength;
        if (sun_info.maptype == RMT_NONE)
          image->colors=1 << sun_info.depth;
        if (sun_info.maptype == RMT_EQUAL_RGB)
          image->colors=sun_info.maplength/3;
      }

    switch (sun_info.maptype)
    {
      case RMT_NONE:
      {
        if (sun_info.depth < 24)
          {
            /*
              Create linear color ramp.
            */
            if (!AllocateImageColormap(image,image->colors))
              ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
                image);
          }
        break;
      }
      case RMT_EQUAL_RGB:
      {
        unsigned char
          *sun_colormap;

        /*
          Read SUN raster colormap.
        */
        if (!AllocateImageColormap(image,image->colors))
          ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
            image);
        sun_colormap=MagickAllocateMemory(unsigned char *,image->colors);
        if (sun_colormap == (unsigned char *) NULL)
          ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
                               image);
        do
          {
            if (ReadBlob(image,image->colors,(char *) sun_colormap) !=
                image->colors)
              {
                status = MagickFail;
                break;
              }
            for (i=0; i < (long) image->colors; i++)
              image->colormap[i].red=ScaleCharToQuantum(sun_colormap[i]);
            if (ReadBlob(image,image->colors,(char *) sun_colormap) !=
                image->colors)
              {
                status = MagickFail;
                break;
              }
            for (i=0; i < (long) image->colors; i++)
              image->colormap[i].green=ScaleCharToQuantum(sun_colormap[i]);
            if (ReadBlob(image,image->colors,(char *) sun_colormap) !=
                image->colors)
              {
                status = MagickFail;
                break;
              }
            for (i=0; i < (long) image->colors; i++)
              image->colormap[i].blue=ScaleCharToQuantum(sun_colormap[i]);
            break;
          } while (1);
        MagickFreeMemory(sun_colormap);
        if (MagickFail == status)
          ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
        break;
      }
      case RMT_RAW:
      {
        unsigned char
          *sun_colormap;

        /*
          Read SUN raster colormap.
        */
        if (!AllocateImageColormap(image,image->colors))
          ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
                               image);
        sun_colormap=MagickAllocateMemory(unsigned char *,sun_info.maplength);
        if (sun_colormap == (unsigned char *) NULL)
          ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
            image);
        if (ReadBlob(image,sun_info.maplength,(char *) sun_colormap) !=
            sun_info.maplength)
          status = MagickFail;
        MagickFreeMemory(sun_colormap);
        if (MagickFail == status)
          ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
        break;
      }
      default:
        ThrowReaderException(CoderError,ColormapTypeNotSupported,image)
    } 
    image->matte=(sun_info.depth == 32);
    image->columns=sun_info.width;
    image->rows=sun_info.height;
    image->depth=8;
    if (sun_info.depth < 8)
      image->depth=sun_info.depth;

    /*
      Compute bytes per line and bytes per image for an unencoded
      image.

      "The width of a scan line is always 16-bits, padded when necessary."
    */
    bytes_per_line=MagickArraySize(sun_info.width,sun_info.depth)/8;
    if ((bytes_per_line != 0) && (sun_info.depth == 1))
      bytes_per_line += sun_info.width % 8 ? 1 : 0;
    if (bytes_per_line != 0)
      bytes_per_line=RoundUpToAlignment(bytes_per_line,2);

    bytes_per_image=MagickArraySize(sun_info.height,bytes_per_line);

    if (bytes_per_line == 0)
      ThrowReaderException(CorruptImageError,ImproperImageHeader,image);

    if (bytes_per_image == 0)
      ThrowReaderException(CorruptImageError,ImproperImageHeader,image);

    if ((sun_info.type == RT_STANDARD) || (sun_info.type == RT_FORMAT_RGB))
      if (bytes_per_image > sun_info.length)
        ThrowReaderException(CorruptImageError,ImproperImageHeader,image);

    if (image_info->ping)
      {
        CloseBlob(image);
        return(image);
      }
    if (sun_info.type == RT_ENCODED)
      sun_data_length=(size_t) sun_info.length;
    else
      sun_data_length=bytes_per_image;
    sun_data=MagickAllocateMemory(unsigned char *,sun_data_length);
    if (sun_data == (unsigned char *) NULL)
      ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
    if ((count=ReadBlob(image,sun_data_length,(char *) sun_data))
        != sun_data_length)
      {
        MagickFreeMemory(sun_data);
        ThrowReaderException(CorruptImageError,UnableToReadImageData,image);
      }
    sun_pixels=sun_data;
    if (sun_info.type == RT_ENCODED)
      {
        /*
          Read run-length encoded raster pixels (padded to 16-bit boundary).
        */
        sun_pixels=MagickAllocateMemory(unsigned char *,bytes_per_image);
        if (sun_pixels == (unsigned char *) NULL)
          ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
            image);
        status &= DecodeImage(sun_data,sun_data_length,sun_pixels,bytes_per_image);
        MagickFreeMemory(sun_data);
        if (status != MagickPass)
          {
            MagickFreeMemory(sun_pixels);
            ThrowReaderException(CorruptImageError,UnableToRunlengthDecodeImage,image);
          }
      }
    /*
      Convert SUN raster image to pixel packets.
    */
    p=sun_pixels;
    if (sun_info.depth == 1)
      /*
        Bilevel
      */
      for (y=0; y < (long) image->rows; y++)
      {
        q=SetImagePixels(image,0,y,image->columns,1);
        if (q == (PixelPacket *) NULL)
          break;
        indexes=AccessMutableIndexes(image);
        for (x=0; x < ((long) image->columns-7); x+=8)
        {
          for (bit=7; bit >= 0; bit--)
            {
              index=((*p) & (0x01 << bit) ? 0x01 : 0x00);
              indexes[x+7-bit]=index;
              q[x+7-bit]=image->colormap[index];
            }
          p++;
        }
        if ((image->columns % 8) != 0)
          {
            for (bit=7; bit >= (long) (8-(image->columns % 8)); bit--)
              {
                index=((*p) & (0x01 << bit) ? 0x01 : 0x00);
                indexes[x+7-bit]=index;
                q[x+7-bit]=image->colormap[index];
              }
            p++;
          }
        if ((((image->columns/8)+(image->columns % 8 ? 1 : 0)) % 2) != 0)
          p++;
        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;
      }
    else
      if (image->storage_class == PseudoClass)
        {
          /*
            Colormapped
          */
          for (y=0; y < (long) image->rows; y++)
          {
            q=SetImagePixels(image,0,y,image->columns,1);
            if (q == (PixelPacket *) NULL)
              break;
            indexes=AccessMutableIndexes(image);
            for (x=0; x < (long) image->columns; x++)
              {
                index=(*p++);
                VerifyColormapIndex(image,index);
                indexes[x]=index;
                q[x]=image->colormap[index];
              }
            if ((image->columns % 2) != 0)
              p++;
            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;
          }
	}
      else
        {
          /*
            (A)BGR or (A)RGB
          */
          for (y=0; y < (long) image->rows; y++)
          {
            q=SetImagePixels(image,0,y,image->columns,1);
            if (q == (PixelPacket *) NULL)
              break;
            for (x=0; x < (long) image->columns; x++)
            {
              if (image->matte)
                q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(*p++));
              if (sun_info.type == RT_STANDARD)
                {
                  q->blue=ScaleCharToQuantum(*p++);
                  q->green=ScaleCharToQuantum(*p++);
                  q->red=ScaleCharToQuantum(*p++);
                }
              else
                {
                  q->red=ScaleCharToQuantum(*p++);
                  q->green=ScaleCharToQuantum(*p++);
                  q->blue=ScaleCharToQuantum(*p++);
                }
              if (image->colors != 0)
                {
                  q->red=image->colormap[q->red].red;
                  q->green=image->colormap[q->green].green;
                  q->blue=image->colormap[q->blue].blue;
                }
              q++;
            }
            if (((image->columns % 2) != 0) && (image->matte == False))
              p++;
            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;
          }
	}
    MagickFreeMemory(sun_pixels);
    if (EOFBlob(image))
      {
        ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
          image->filename);
        break;
      }
    /*
      Proceed to next image.
    */
    if (image_info->subrange != 0)
      if (image->scene >= (image_info->subimage+image_info->subrange-1))
        break;
    sun_info.magic=ReadBlobMSBLong(image);
    if (sun_info.magic == 0x59a66a95)
      {
        /*
          Allocate next image structure.
        */
        AllocateNextImage(image_info,image);
        if (image->next == (Image *) NULL)
          {
            DestroyImageList(image);
            return((Image *) NULL);
          }
        image=SyncNextImageInList(image);
        if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),
                                    exception,LoadImagesText,
                                    image->filename))
          break;
      }
  } while (sun_info.magic == 0x59a66a95);