/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d F A X I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadFAXImage() reads a Group 3 FAX 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 ReadFAXImage method is:
%
%      Image *ReadFAXImage(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 *ReadFAXImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
    Image
    *image;

    MagickBooleanType
    status;

    /*
      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);
    }
    /*
      Initialize image structure.
    */
    image->storage_class=PseudoClass;
    if (image->columns == 0)
        image->columns=2592;
    if (image->rows == 0)
        image->rows=3508;
    image->depth=8;
    if (AllocateImageColormap(image,2) == MagickFalse)
        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    /*
      Monochrome colormap.
    */
    image->colormap[0].red=QuantumRange;
    image->colormap[0].green=QuantumRange;
    image->colormap[0].blue=QuantumRange;
    image->colormap[1].red=0;
    image->colormap[1].green=0;
    image->colormap[1].blue=0;
    if (image_info->ping != MagickFalse)
    {
        CloseBlob(image);
        return(GetFirstImageInList(image));
    }
    status=HuffmanDecodeImage(image);
    if (status == MagickFalse)
        ThrowReaderException(CorruptImageError,"UnableToReadImageData");
    if (EOFBlob(image) != MagickFalse)
        ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
                           image->filename);
    CloseBlob(image);
    return(GetFirstImageInList(image));
}
Example #2
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d F A X I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method ReadFAXImage reads a Group 3 FAX 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 ReadFAXImage method is:
%
%      Image *ReadFAXImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image:  Method ReadFAXImage 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 *ReadFAXImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  Image
    *image;

  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);
  /*
    Initialize image structure.
  */
  image->storage_class=PseudoClass;
  if (image->columns == 0)
    image->columns=2592;
  if (image->rows == 0)
    image->rows=3508;
  image->depth=8;
  if (!AllocateImageColormap(image,2))
    ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
  /*
    Monochrome colormap.
  */
  image->colormap[0].red=MaxRGB;
  image->colormap[0].green=MaxRGB;
  image->colormap[0].blue=MaxRGB;
  image->colormap[1].red=0;
  image->colormap[1].green=0;
  image->colormap[1].blue=0;
  if (image_info->ping)
    {
      CloseBlob(image);
      return(image);
    }

  if (CheckImagePixelLimits(image, exception) != MagickPass)
    ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);

  status=HuffmanDecodeImage(image);
  if (status == False)
    ThrowReaderException(CorruptImageError,UnableToReadImageData,image);
  if (EOFBlob(image))
    ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
      image->filename);
  CloseBlob(image);
  return(image);
}
Example #3
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d M A C I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method ReadMACImage reads an MAC 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 ReadMACImage method is:
%
%      Image *ReadMACImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image:  Method ReadMACImage 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 *ReadMACImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  Image *image;
  unsigned int y;  
  unsigned char x8, rep, b;
  long ldblk;
  unsigned char *BImgBuff = NULL;
  unsigned char *DataPtr;
  unsigned int status;
  const PixelPacket *q;

	/* 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 MAC image. */
  ldblk = ReadBlobLSBShort(image);
  if((ldblk & 0xFF)!=0)
	ThrowReaderException(CorruptImageError,ImproperImageHeader,image);

  if(ldblk==0)		/* ???? don't know why */
	SeekBlob(image,0x200,SEEK_SET);
  else
	SeekBlob(image,0x280,SEEK_SET);

  image->columns = 576;
  image->rows = 720;
  image->depth = 1;
  image->colors = 1l << image->depth;

  if (!AllocateImageColormap(image,image->colors)) goto NoMemory;

    /* If ping is true, then only set image size and colors without reading any image data. */
  if (image_info->ping) goto DONE_READING;

  /* ----- Load RLE compressed raster ----- */
  ldblk = (image->depth*image->columns) /8;
  BImgBuff = MagickAllocateMemory(unsigned char *, ((size_t)ldblk));
  if(BImgBuff==NULL)
    NoMemory:
      ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
  
  DataPtr = BImgBuff;  
  x8=0; y=0;

  while(y<image->rows)
  {
    rep = ReadBlobByte(image);
    if(EOFBlob(image)) break;

    if( rep>=128 || rep<=0)
    {
      b = ~ReadBlobByte(image);;

      rep = ~rep + 2;
      while(rep>0)
      {
        *DataPtr++ = b;
        x8++;
        rep--;
        if(x8>=ldblk)
	{
	  x8=0;

          q = SetImagePixels(image,0,y,image->columns,1);
          if(q == (PixelPacket *)NULL) break;
          (void)ImportImagePixelArea(image,GrayQuantum,1,BImgBuff,NULL,0);
          if(!SyncImagePixels(image)) break;

	  DataPtr = BImgBuff;
	  y++;
	  if(y>=image->rows)
	  {
	    break;	    
	  }
	}
      }
    }
    else
    {
      rep++;
      while(rep>0)
      {
        b = ~ReadBlobByte(image);
        *DataPtr++ = b;
        x8++;
        rep--;
        if(x8>=ldblk)
        {
 	  x8=0;

          q = SetImagePixels(image,0,y,image->columns,1);
          if(q == (PixelPacket *)NULL) break;
          (void)ImportImagePixelArea(image,GrayQuantum,1,BImgBuff,NULL,0);
          if (!SyncImagePixels(image)) break;

	  DataPtr = BImgBuff;
	  y++;
	  if(y>=image->rows)
	  {
	    break;
	  }
        }
      }
    }
  }
  if(BImgBuff!=NULL)
    MagickFreeMemory(BImgBuff);
  if(EOFBlob(image))
    ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,image->filename);

DONE_READING:
  CloseBlob(image);
  return(image);
}
Example #4
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d J B I G I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadJBIGImage() reads a JBIG 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 ReadJBIGImage method is:
%
%      Image *ReadJBIGImage(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 *ReadJBIGImage(const ImageInfo *image_info,
                            ExceptionInfo *exception)
{
    Image
    *image;

    IndexPacket
    index;

    long
    length,
    y;

    MagickBooleanType
    status;

    register IndexPacket
    *indexes;

    register long
    x;

    register PixelPacket
    *q;

    register unsigned char
    *p;

    ssize_t
    count;

    struct jbg_dec_state
        jbig_info;

    unsigned char
    bit,
    *buffer,
    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=AllocateImage(image_info);
    status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
    if (status == MagickFalse)
    {
        image=DestroyImageList(image);
        return((Image *) NULL);
    }
    /*
      Initialize JBIG toolkit.
    */
    jbg_dec_init(&jbig_info);
    jbg_dec_maxsize(&jbig_info,(unsigned long) image->columns,(unsigned long)
                    image->rows);
    image->columns=jbg_dec_getwidth(&jbig_info);
    image->rows=jbg_dec_getheight(&jbig_info);
    image->depth=8;
    image->storage_class=PseudoClass;
    image->colors=2;
    /*
      Read JBIG file.
    */
    buffer=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferSize,
            sizeof(*buffer));
    if (buffer == (unsigned char *) NULL)
        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    status=JBG_EAGAIN;
    do
    {
        length=(long) ReadBlob(image,MagickMaxBufferSize,buffer);
        if (length == 0)
            break;
        p=buffer;
        count=0;
        while ((length > 0) && ((status == JBG_EAGAIN) || (status == JBG_EOK)))
        {
            size_t
            count;

            status=jbg_dec_in(&jbig_info,p,length,&count);
            p+=count;
            length-=(long) count;
        }
    } while ((status == JBG_EAGAIN) || (status == JBG_EOK));
    /*
      Create colormap.
    */
    image->columns=jbg_dec_getwidth(&jbig_info);
    image->rows=jbg_dec_getheight(&jbig_info);
    if (AllocateImageColormap(image,2) == MagickFalse)
    {
        buffer=(unsigned char *) RelinquishMagickMemory(buffer);
        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    }
    image->colormap[0].red=0;
    image->colormap[0].green=0;
    image->colormap[0].blue=0;
    image->colormap[1].red=QuantumRange;
    image->colormap[1].green=QuantumRange;
    image->colormap[1].blue=QuantumRange;
    image->x_resolution=300;
    image->y_resolution=300;
    if (image_info->ping != MagickFalse)
    {
        (void) CloseBlob(image);
        return(GetFirstImageInList(image));
    }
    /*
      Convert X bitmap image to pixel packets.
    */
    if (SetImageExtent(image,0,0) == MagickFalse)
    {
        InheritException(exception,&image->exception);
        return(DestroyImageList(image));
    }
    p=jbg_dec_getimage(&jbig_info,0);
    for (y=0; y < (long) image->rows; y++)
    {
        q=SetImagePixels(image,0,y,image->columns,1);
        if (q == (PixelPacket *) NULL)
            break;
        indexes=GetIndexes(image);
        bit=0;
        byte=0;
        for (x=0; x < (long) image->columns; x++)
        {
            if (bit == 0)
                byte=(*p++);
            index=(byte & 0x80) ? 0 : 1;
            bit++;
            byte<<=1;
            if (bit == 8)
                bit=0;
            indexes[x]=index;
            *q++=image->colormap[(long) index];
        }
        if (SyncImagePixels(image) == MagickFalse)
            break;
        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;
        }
    }
    /*
      Free scale resource.
    */
    jbg_dec_free(&jbig_info);
    buffer=(unsigned char *) RelinquishMagickMemory(buffer);
    (void) CloseBlob(image);
    return(GetFirstImageInList(image));
}
Example #5
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d V I C A R I m a g e                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadVICARImage() reads a VICAR 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 ReadVICARImage method is:
%
%      Image *ReadVICARImage(const ImageInfo *image_info,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image: Method ReadVICARImage 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 *ReadVICARImage(const ImageInfo *image_info,
  ExceptionInfo *exception)
{
  char
    keyword[MaxTextExtent],
    value[MaxTextExtent];

  Image
    *image;

  int
    c;

  long
    y;

  MagickBooleanType
    status,
    value_expected;

  QuantumInfo
    quantum_info;

  register PixelPacket
    *q;

  ssize_t
    count;

  ssize_t
    length;

  unsigned char
    *scanline;

  /*
    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);
    }
  /*
    Decode image header.
  */
  c=ReadBlobByte(image);
  count=1;
  if (c == EOF)
    {
      image=DestroyImage(image);
      return((Image *) NULL);
    }
  length=0;
  image->columns=0;
  image->rows=0;
  while (isgraph(c) && ((image->columns == 0) || (image->rows == 0)))
  {
    if (isalnum(c) == MagickFalse)
      {
        c=ReadBlobByte(image);
        count++;
      }
    else
      {
        register char
          *p;

        /*
          Determine a keyword and its value.
        */
        p=keyword;
        do
        {
          if ((size_t) (p-keyword) < MaxTextExtent)
            *p++=c;
          c=ReadBlobByte(image);
          count++;
        } while (isalnum(c) || (c == '_'));
        *p='\0';
        value_expected=MagickFalse;
        while ((isspace((int) ((unsigned char) c)) != 0) || (c == '='))
        {
          if (c == '=')
            value_expected=MagickTrue;
          c=ReadBlobByte(image);
          count++;
        }
        if (value_expected == MagickFalse)
          continue;
        p=value;
        while (isalnum(c))
        {
          if ((size_t) (p-value) < MaxTextExtent)
            *p++=c;
          c=ReadBlobByte(image);
          count++;
        }
        *p='\0';
        /*
          Assign a value to the specified keyword.
        */
        if (LocaleCompare(keyword,"Label_RECORDS") == 0)
          length=(ssize_t) atol(value);
        if (LocaleCompare(keyword,"LBLSIZE") == 0)
          length=(ssize_t) atol(value);
        if (LocaleCompare(keyword,"RECORD_BYTES") == 0)
          image->columns=1UL*atol(value);
        if (LocaleCompare(keyword,"NS") == 0)
          image->columns=1UL*atol(value);
        if (LocaleCompare(keyword,"LINES") == 0)
          image->rows=1UL*atol(value);
        if (LocaleCompare(keyword,"NL") == 0)
          image->rows=1UL*atol(value);
      }
    while (isspace((int) ((unsigned char) c)) != 0)
    {
      c=ReadBlobByte(image);
      count++;
    }
  }
  while (count < (ssize_t) length)
  {
    c=ReadBlobByte(image);
    count++;
  }
  if ((image->columns == 0) || (image->rows == 0))
    ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
  image->depth=8;
  if (AllocateImageColormap(image,256) == MagickFalse)
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  if (image_info->ping != MagickFalse)
    {
      (void) CloseBlob(image);
      return(GetFirstImageInList(image));
    }
  /*
    Read VICAR pixels.
  */
  if (SetImageExtent(image,0,0) == MagickFalse)
    {
      InheritException(exception,&image->exception);
      return(DestroyImageList(image));
    }
  GetQuantumInfo(image_info,&quantum_info);
  scanline=(unsigned char *) AcquireQuantumMemory(image->columns,
    sizeof(*scanline));
  if (scanline == (unsigned char *) NULL)
    ThrowReaderException(CorruptImageError,"UnableToReadImageData");
  for (y=0; y < (long) image->rows; y++)
  {
    q=SetImagePixels(image,0,y,image->columns,1);
    if (q == (PixelPacket *) NULL)
      break;
    count=ReadBlob(image,image->columns,scanline);
    (void) ExportQuantumPixels(image,&quantum_info,GrayQuantum,scanline);
    if (SyncImagePixels(image) == MagickFalse)
      break;
    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;
      }
  }
  scanline=(unsigned char *) RelinquishMagickMemory(scanline);
  if (EOFBlob(image) != MagickFalse)
    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
      image->filename);
  (void) CloseBlob(image);
  return(GetFirstImageInList(image));
}
Example #6
0
File: art.c Project: acobus/PDF2TeX
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d A R T I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method ReadARTImage reads an ART 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 ReadARTImage method is:
%
%      Image *ReadARTImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image:  Method ReadARTImage 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 *ReadARTImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  Image *image;
  int i;
  unsigned width,height,dummy;
  long ldblk;
  unsigned char *BImgBuff=NULL;
  unsigned char Padding;
  unsigned int status;
  const PixelPacket *q;

  /*
    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 ART image.
  */
  dummy=ReadBlobLSBShort(image);
  width=ReadBlobLSBShort(image);
  dummy=ReadBlobLSBShort(image);
  height=ReadBlobLSBShort(image);

  ldblk=(long) ((width+7) / 8);
  Padding=(unsigned char) ((-ldblk) & 0x01);

  if(GetBlobSize(image)!=(8+((long)ldblk+Padding)*height))
    ThrowReaderException(CorruptImageError,ImproperImageHeader,image);

  image->columns=width;
  image->rows=height;
  image->depth=1;
  image->colors=1l << image->depth;
 
  /* printf("ART header checked OK %d,%d\n",image->colors,image->depth); */

  if (!AllocateImageColormap(image,image->colors)) goto NoMemory;

  /* If ping is true, then only set image size and colors without reading any image data. */
  if (image_info->ping) goto DONE_READING;

  /* ----- Load RLE compressed raster ----- */
  BImgBuff=MagickAllocateMemory(unsigned char *,((size_t) ldblk));  /*Ldblk was set in the check phase*/
  if(BImgBuff==NULL)
    NoMemory:
  ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);

  for(i=0; i<(int)height; i++)
    {
      (void) ReadBlob(image,(size_t)ldblk,(char *)BImgBuff);
      (void) ReadBlob(image,Padding,(char *)&dummy);      

      q=SetImagePixels(image,0,i,image->columns,1);
      if (q == (PixelPacket *)NULL) break;
      (void)ImportImagePixelArea(image,GrayQuantum,1,BImgBuff,NULL,0);
      if (!SyncImagePixels(image)) break;
    }
  if(BImgBuff!=NULL)
    MagickFreeMemory(BImgBuff);
  if (EOFBlob(image))
    ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
                   image->filename);

DONE_READING:
  CloseBlob(image);
  return(image);
}
Example #7
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 long
      rows,
      columns,
      subrows;

    long
      x_offset,
      y_offset;

    float
      x_bits_per_pixel,
      y_bits_per_pixel;

    unsigned long
      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;

  long
    y;

  MagickBooleanType
    status;

  MagickSizeType
    number_pixels;

  register IndexPacket
    *indexes;

  register long
    x;

  register PixelPacket
    *q;

  register long
    i;

  register unsigned char
    *p;

  ssize_t
    count;

  unsigned char
    buffer[7],
    *viff_pixels;

  unsigned long
    bytes_per_pixel,
    lsb_first,
    max_packets,
    quantum;

  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=AllocateImage(image_info);
  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);
    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=(long) ReadBlobLSBLong(image);
        viff_info.y_offset=(long) 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=(long) ReadBlobMSBLong(image);
        viff_info.y_offset=(long) 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 (AllocateImageColormap(image,image->colors) == 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 (AllocateImageColormap(image,image->colors) == 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 < (long) (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 < (long) 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 < (long) (2*image->colors))
              image->colormap[i % image->colors].green=
                ScaleCharToQuantum((unsigned char) value);
            else
              if (i < (long) (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->matte=viff_info.number_data_bands == 4 ? MagickTrue : MagickFalse;
    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;
    if (SetImageExtent(image,0,0) == MagickFalse)
      {
        InheritException(exception,&image->exception);
        return(DestroyImageList(image));
      }
    /*
      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=(unsigned long) (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 < (long) 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=(MagickRealType) QuantumRange/min_value;
              min_value=0;
            }
          else
            scale_factor=(MagickRealType) QuantumRange/(max_value-min_value);
      }
    /*
      Convert pixels to Quantum size.
    */
    p=(unsigned char *) viff_pixels;
    for (i=0; i < (long) 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);
        (void) SetImageType(image,PaletteType);
        for (y=0; y < (long) image->rows; y++)
        {
          q=SetImagePixels(image,0,y,image->columns,1);
          if (q == (PixelPacket *) NULL)
            break;
          indexes=GetIndexes(image);
          for (x=0; x < (long) (image->columns-7); x+=8)
          {
            for (bit=0; bit < 8; bit++)
              if (PixelIntensity(q) < ((MagickRealType) QuantumRange/2.0))
                {
                  quantum=(unsigned long) indexes[x+bit];
                  quantum|=0x01;
                  indexes[x+bit]=(IndexPacket) quantum;
                }
            p++;
          }
          if ((image->columns % 8) != 0)
            {
              for (bit=0; bit < (long) (image->columns % 8); bit++)
                if (PixelIntensity(q) < ((MagickRealType) QuantumRange/2.0))
                  {
                    quantum=(unsigned long) indexes[x+bit];
                    quantum|=0x01;
                    indexes[x+bit]=(IndexPacket) quantum;
                  }
              p++;
            }
          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;
              }
        }
      }
    else
      if (image->storage_class == PseudoClass)
        for (y=0; y < (long) image->rows; y++)
        {
          q=SetImagePixels(image,0,y,image->columns,1);
          if (q == (PixelPacket *) NULL)
            break;
          indexes=GetIndexes(image);
          for (x=0; x < (long) image->columns; x++)
            indexes[x]=(IndexPacket) (*p++);
          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;
              }
        }
      else
        {
          /*
            Convert DirectColor scanline.
          */
          number_pixels=(MagickSizeType) image->columns*image->rows;
          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++)
            {
              q->red=ScaleCharToQuantum(*p);
              q->green=ScaleCharToQuantum(*(p+number_pixels));
              q->blue=ScaleCharToQuantum(*(p+2*number_pixels));
              if (image->colors != 0)
                {
                  q->red=image->colormap[(long) q->red].red;
                  q->green=image->colormap[(long) q->green].green;
                  q->blue=image->colormap[(long) q->blue].blue;
                }
              q->opacity=(Quantum) (image->matte ? QuantumRange-
                ScaleCharToQuantum(*(p+number_pixels*3)) : OpaqueOpacity);
              p++;
              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;
                }
          }
        }
    viff_pixels=(unsigned char *) RelinquishMagickMemory(viff_pixels);
    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;
    count=ReadBlob(image,1,&viff_info.identifier);
    if ((count != 0) && (viff_info.identifier == 0xab))
      {
        /*
          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 ((count != 0) && (viff_info.identifier == 0xab));
Example #8
0
File: otb.c Project: scuddalo/cq
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d O T B I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadOTBImage() reads a on-the-air (level 0) bitmap 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 ReadOTBImage method is:
%
%      Image *ReadOTBImage(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 *ReadOTBImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
#define GetBit(a,i) (((a) >> (i)) & 1L)

  Image
    *image;

  int
    byte;

  long
    y;

  MagickBooleanType
    status;

  register IndexPacket
    *indexes;

  register long
    x;

  register PixelPacket
    *q;

  unsigned char
    bit,
    info,
    depth;

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  image=AllocateImage(image_info);
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    {
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  /*
    Initialize image structure.
  */
  info=(unsigned char) ReadBlobByte(image);
  if (GetBit(info,4) == 0)
    {
      image->columns=(unsigned long) ReadBlobByte(image);
      image->rows=(unsigned long) ReadBlobByte(image);
    }
  else
    {
      image->columns=(unsigned long) ReadBlobMSBShort(image);
      image->rows=(unsigned long) ReadBlobMSBShort(image);
    }
  if ((image->columns == 0) || (image->rows == 0))
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  depth=(unsigned char) ReadBlobByte(image);
  if (depth != 1)
    ThrowReaderException(CoderError,"OnlyLevelZerofilesSupported");
  if (AllocateImageColormap(image,2) == MagickFalse)
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  if (image_info->ping != MagickFalse)
    {
      CloseBlob(image);
      return(GetFirstImageInList(image));
    }
  if (SetImageExtent(image,0,0) == MagickFalse)
    {
      InheritException(exception,&image->exception);
      return(DestroyImageList(image));
    }
  /*
    Convert bi-level image to pixel packets.
  */
  for (y=0; y < (long) image->rows; y++)
  {
    q=SetImagePixels(image,0,y,image->columns,1);
    if (q == (PixelPacket *) NULL)
      break;
    indexes=GetIndexes(image);
    bit=0;
    byte=0;
    for (x=0; x < (long) image->columns; x++)
    {
      if (bit == 0)
        {
          byte=ReadBlobByte(image);
          if (byte == EOF)
            ThrowReaderException(CorruptImageError,"CorruptImage");
        }
      indexes[x]=(IndexPacket) ((byte & (0x01 << (7-bit))) ? 0x00 : 0x01);
      bit++;
      if (bit == 8)
        bit=0;
    }
    if (SyncImagePixels(image) == MagickFalse)
      break;
    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;
      }
  }
  (void) SyncImage(image);
  if (EOFBlob(image) != MagickFalse)
    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
      image->filename);
  CloseBlob(image);
  return(GetFirstImageInList(image));
}
Example #9
0
static Image *ReadXPMImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  char
    key[MaxTextExtent],
    target[MaxTextExtent],
    *xpm_buffer;

  Image
    *image;

  long
    j,
    y;

  MagickBooleanType
    active,
    status;

  register char
    *p,
    *q,
    *next;

  register IndexPacket
    *indexes;

  register long
    i,
    x;

  register PixelPacket
    *r;

  size_t
    length;

  SplayTreeInfo
    *xpm_colors;

  ssize_t
    count;

  unsigned long
    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 XPM file.
  */
  length=MaxTextExtent;
  xpm_buffer=(char *) AcquireQuantumMemory((size_t) length,sizeof(*xpm_buffer));
  p=xpm_buffer;
  if (xpm_buffer != (char *) NULL)
    while (ReadBlobString(image,p) != (char *) NULL)
    {
      if ((*p == '#') && ((p == xpm_buffer) || (*(p-1) == '\n')))
        continue;
      if ((*p == '}') && (*(p+1) == ';'))
        break;
      p+=strlen(p);
      if ((size_t) (p-xpm_buffer+MaxTextExtent) < length)
        continue;
      length<<=1;
      xpm_buffer=(char *) ResizeQuantumMemory(xpm_buffer,length+MaxTextExtent,
        sizeof(*xpm_buffer));
      if (xpm_buffer == (char *) NULL)
        break;
      p=xpm_buffer+strlen(xpm_buffer);
    }
  if (xpm_buffer == (char *) NULL)
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  /*
    Remove comments.
  */
  count=0;
  for (p=xpm_buffer; *p != '\0'; p++)
  {
    if (*p != '"')
      continue;
    count=(ssize_t) sscanf(p+1,"%lu %lu %lu %lu",&image->columns,&image->rows,
      &image->colors,&width);
    if (count == 4)
      break;
  }
  if ((count != 4) || (width > 10) || (image->columns == 0) ||
      (image->rows == 0) || (image->colors == 0))
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  image->depth=16;
  /*
    Remove unquoted characters.
  */
  i=0;
  active=MagickFalse;
  q=xpm_buffer;
  while (*p != '\0')
  {
    if (*p++ == '"')
      {
        if (active != MagickFalse)
          *q++='\n';
        active=active != MagickFalse ? MagickFalse : MagickTrue;
      }
    if (active != MagickFalse)
      *q++=(*p);
  }
  *q='\0';
  /*
    Initialize image structure.
  */
  xpm_colors=NewSplayTree(CompareXPMColor,RelinquishMagickMemory,
    (void *(*)(void *)) NULL);
  if (AllocateImageColormap(image,image->colors) == MagickFalse)
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  /*
    Read image colormap.
  */
  i=1;
  next=NextXPMLine(xpm_buffer);
  for (j=0; (j < (long) image->colors) && (next != (char*) NULL); j++)
  {
    p=next;
    next=NextXPMLine(p);
    (void) CopyXPMColor(key,p,MagickMin((size_t) width,MaxTextExtent));
    status=AddValueToSplayTree(xpm_colors,ConstantString(key),(void *) j);
    /*
      Parse color.
    */
    (void) CopyMagickString(target,"gray",MaxTextExtent);
    q=ParseXPMColor(p+width);
    if (q != (char *) NULL)
      {
        while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
          q++;
        if (next != (char *) NULL)
          (void) CopyXPMColor(target,q,MagickMin((size_t) (next-q),
            MaxTextExtent));
        else
          (void) CopyMagickString(target,q,MaxTextExtent);
        q=ParseXPMColor(target);
        if (q != (char *) NULL)
          *q='\0';
      }
    StripString(target);
    if (LocaleCompare(target,"none") == 0)
      {
        image->storage_class=DirectClass;
        image->matte=MagickTrue;
      }
    if (QueryColorDatabase(target,&image->colormap[j],exception) == MagickFalse)
      break;
  }
  if (j < (long) image->colors)
    ThrowReaderException(CorruptImageError,"CorruptImage");
  j=0;
  if (image_info->ping == MagickFalse)
    {
      /*
        Read image pixels.
      */
      if (SetImageExtent(image,0,0) == MagickFalse)
        {
          InheritException(exception,&image->exception);
          return(DestroyImageList(image));
        }
      for (y=0; y < (long) image->rows; y++)
      {
        p=NextXPMLine(p);
        if (p == (char *) NULL)
          break;
        r=SetImagePixels(image,0,y,image->columns,1);
        if (r == (PixelPacket *) NULL)
          break;
        indexes=GetIndexes(image);
        for (x=0; x < (long) image->columns; x++)
        {
          (void) CopyXPMColor(key,p,(size_t) width);
          j=(long) GetValueFromSplayTree(xpm_colors,key);
          if (image->storage_class == PseudoClass)
            indexes[x]=(IndexPacket) j;
          *r=image->colormap[j];
          r++;
          p+=width;
        }
        if (SyncImagePixels(image) == MagickFalse)
          break;
      }
      if (y < (long) image->rows)
        ThrowReaderException(CorruptImageError,"NotEnoughPixelData");
    }
  /*
    Relinquish resources.
  */
  xpm_colors=DestroySplayTree(xpm_colors);
  (void) CloseBlob(image);
  return(GetFirstImageInList(image));
}
Example #10
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%  R e a d T I M I m a g e                                                    %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method ReadTIMImage reads a PSX TIM image file and returns it.  It
%  allocates the memory necessary for the new Image structure and returns a
%  pointer to the new image.
%
%  Contributed by [email protected].
%
%  The format of the ReadTIMImage method is:
%
%      Image *ReadTIMImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image:  Method ReadTIMImage 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 *ReadTIMImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  typedef struct _TIMInfo
  {
    unsigned long
      id,
      flag;
  } TIMInfo;

  TIMInfo
    tim_info;

  Image
    *image;

  int
    bits_per_pixel,
    has_clut;

  long
    y;

  register IndexPacket
    *indexes;

  register long
    x;

  register PixelPacket
    *q;

  register long
    i;

  register unsigned char
    *p;

  unsigned char
    *tim_data,
    *tim_pixels;

  unsigned short
    word;

  unsigned int
    status;

  size_t
    bytes_per_line,
    image_size;

  unsigned long
    height,
    pixel_mode,
    width;

  /*
    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);
  /*
    Determine if this is a TIM file.
  */
  tim_info.id=ReadBlobLSBLong(image);
  do
  {
    /*
      Verify TIM identifier.
    */
    if (tim_info.id != 0x00000010)
      ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
    tim_info.flag=ReadBlobLSBLong(image);
    has_clut=!!(tim_info.flag & (1 << 3));
    pixel_mode=tim_info.flag & 0x07;
    switch ((int) pixel_mode)
    {
      case 0: bits_per_pixel=4; break;
      case 1: bits_per_pixel=8; break;
      case 2: bits_per_pixel=16; break;
      case 3: bits_per_pixel=24; break;
      default: bits_per_pixel=4; break;
    }
    image->depth=8;
    if (has_clut)
      {
        unsigned char
          *tim_colormap;

        /*
          Read TIM raster colormap.
        */
        (void)ReadBlobLSBLong(image);
        (void)ReadBlobLSBShort(image);
        (void)ReadBlobLSBShort(image);
        /* width= */ (void)ReadBlobLSBShort(image);
        /* height= */ (void)ReadBlobLSBShort(image);
        if (!AllocateImageColormap(image,pixel_mode == 1 ? 256 : 16))
          ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
            image);
        tim_colormap=MagickAllocateMemory(unsigned char *,image->colors*2);
        if (tim_colormap == (unsigned char *) NULL)
          ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
            image);
        (void) ReadBlob(image,2*image->colors,(char *) tim_colormap);
        p=tim_colormap;
        for (i=0; i < (long) image->colors; i++)
        {
          word=(*p++);
          word|=(unsigned short) (*p++ << 8U);
          image->colormap[i].blue=ScaleCharToQuantum(ScaleColor5to8((word >> 10U) & 0x1fU));
          image->colormap[i].green=ScaleCharToQuantum(ScaleColor5to8((word >> 5U) & 0x1fU));
          image->colormap[i].red=ScaleCharToQuantum(ScaleColor5to8(word & 0x1fU));
        }
        MagickFreeMemory(tim_colormap);
      }

    /*
      Read image data.
    */
    (void) ReadBlobLSBLong(image);
    (void) ReadBlobLSBShort(image);
    (void) ReadBlobLSBShort(image);
    if (EOFBlob(image))
      ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
    width=ReadBlobLSBShort(image);
    height=ReadBlobLSBShort(image);
    image_size=MagickArraySize(2,MagickArraySize(width,height));
    bytes_per_line=MagickArraySize(width,2);
    width=(unsigned long)(MagickArraySize(width,16))/bits_per_pixel;
    /*
      Initialize image structure.
    */
    image->columns=width;
    image->rows=height;

    if (image_info->ping && (image_info->subrange != 0))
      if (image->scene >= (image_info->subimage+image_info->subrange-1))
        break;

    if (CheckImagePixelLimits(image, exception) != MagickPass)
      ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);

    tim_data=MagickAllocateMemory(unsigned char *,image_size);
    if (tim_data == (unsigned char *) NULL)
      ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
    (void) ReadBlob(image,image_size,(char *) tim_data);
    tim_pixels=tim_data;

    /*
      Convert TIM raster image to pixel packets.
    */
    switch (bits_per_pixel)
    {
      case 4:
      {
        /*
          Convert PseudoColor scanline.
        */
        for (y=(long) image->rows-1; y >= 0; y--)
        {
          q=SetImagePixelsEx(image,0,y,image->columns,1,exception);
          if (q == (PixelPacket *) NULL)
            break;
          indexes=AccessMutableIndexes(image);
          p=tim_pixels+y*bytes_per_line;
          for (x=0; x < ((long) image->columns-1); x+=2)
          {
            indexes[x]=(*p) & 0xf;
            indexes[x+1]=(*p >> 4) & 0xf;
            p++;
          }
          if ((image->columns % 2) != 0)
            {
              indexes[x]=(*p >> 4) & 0xf;
              p++;
            }
          if (!SyncImagePixelsEx(image,exception))
            break;
          if (QuantumTick(y,image->rows))
            {
              status=MagickMonitorFormatted(image->rows-y-1,image->rows,
                                            exception,LoadImageText,
                                            image->filename,
					    image->columns,image->rows);
              if (status == False)
                break;
            }
        }
        break;
      }
      case 8:
      {
        /*
          Convert PseudoColor scanline.
        */
        for (y=(long) image->rows-1; y >= 0; y--)
        {
          q=SetImagePixelsEx(image,0,y,image->columns,1,exception);
          if (q == (PixelPacket *) NULL)
            break;
          indexes=AccessMutableIndexes(image);
          p=tim_pixels+y*bytes_per_line;
          for (x=0; x < (long) image->columns; x++)
            indexes[x]=(*p++);
          if (!SyncImagePixelsEx(image,exception))
            break;
          if (QuantumTick(y,image->rows))
            {
              status=MagickMonitorFormatted(image->rows-y-1,image->rows,
                                            exception,LoadImageText,
                                            image->filename,
					    image->columns,image->rows);
              if (status == False)
                break;
            }
        }
        break;
      }
      case 16:
      {
        /*
          Convert DirectColor scanline.
        */
        for (y=(long) image->rows-1; y >= 0; y--)
        {
          p=tim_pixels+y*bytes_per_line;
          q=SetImagePixelsEx(image,0,y,image->columns,1,exception);
          if (q == (PixelPacket *) NULL)
            break;
          for (x=0; x < (long) image->columns; x++)
          {
            word=(*p++);
            word|=(*p++ << 8);
            q->blue=ScaleCharToQuantum(ScaleColor5to8((word >> 10) & 0x1f));
            q->green=ScaleCharToQuantum(ScaleColor5to8((word >> 5) & 0x1f));
            q->red=ScaleCharToQuantum(ScaleColor5to8(word & 0x1f));
            q++;
          }
          if (!SyncImagePixelsEx(image,exception))
            break;
          if (QuantumTick(y,image->rows))
            {
              status=MagickMonitorFormatted(image->rows-y-1,image->rows,
                                            exception,LoadImageText,
                                            image->filename,
					    image->columns,image->rows);
              if (status == False)
                break;
            }
        }
        break;
      }
      case 24:
      {
        /*
          Convert DirectColor scanline.
        */
        for (y=(long) image->rows-1; y >= 0; y--)
        {
          p=tim_pixels+y*bytes_per_line;
          q=SetImagePixelsEx(image,0,y,image->columns,1,exception);
          if (q == (PixelPacket *) NULL)
            break;
          for (x=0; x < (long) image->columns; x++)
          {
            q->red=ScaleCharToQuantum(*p++);
            q->green=ScaleCharToQuantum(*p++);
            q->blue=ScaleCharToQuantum(*p++);
            q++;
          }
          if (!SyncImagePixelsEx(image,exception))
            break;
          if (QuantumTick(y,image->rows))
            {
              status=MagickMonitorFormatted(image->rows-y-1,image->rows,
                                            exception,LoadImageText,
                                            image->filename,
					    image->columns,image->rows);
              if (status == False)
                break;
            }
        }
        break;
      }
      default:
        ThrowReaderException(CorruptImageError,ImproperImageHeader,image)
    }
    if (image->storage_class == PseudoClass)
      (void) SyncImage(image);
    MagickFreeMemory(tim_pixels);
    if (EOFBlob(image))
      {
        ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
          image->filename);
        break;
      }
    /*
      Proceed to next image.
    */
    tim_info.id=ReadBlobLSBLong(image);
    if (tim_info.id == 0x00000010)
      {
        /*
          Allocate next image structure.
        */
        AllocateNextImage(image_info,image);
        if (image->next == (Image *) NULL)
          {
            DestroyImageList(image);
            return((Image *) NULL);
          }
        image=SyncNextImageInList(image);
        status=MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),
                                      exception,LoadImagesText,
                                      image->filename);
        if (status == False)
          break;
      }
  } while (tim_info.id == 0x00000010);
Example #11
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d M A P I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadMAPImage() reads an image of raw RGB colormap and colormap index
%  bytes 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 ReadMAPImage method is:
%
%      Image *ReadMAPImage(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 *ReadMAPImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
    Image
    *image;

    IndexPacket
    index;

    long
    y;

    MagickBooleanType
    status;

    register IndexPacket
    *indexes;

    register long
    x;

    register PixelPacket
    *q;

    register long
    i;

    register unsigned char
    *p;

    size_t
    packet_size;

    ssize_t
    count;

    unsigned char
    *colormap,
    *pixels;

    unsigned long
    depth,
    quantum;

    /*
      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);
    if ((image->columns == 0) || (image->rows == 0))
        ThrowReaderException(OptionError,"MustSpecifyImageSize");
    status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
    if (status == MagickFalse)
    {
        image=DestroyImageList(image);
        return((Image *) NULL);
    }
    /*
      Initialize image structure.
    */
    image->storage_class=PseudoClass;
    status=AllocateImageColormap(image,(unsigned long)
                                 (image->offset != 0 ? image->offset : 256));
    if (status == MagickFalse)
        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    depth=GetImageQuantumDepth(image,MagickTrue);
    packet_size=(size_t) (depth/8);
    pixels=(unsigned char *) AcquireQuantumMemory(image->columns,packet_size*
            sizeof(*pixels));
    packet_size=(size_t) (image->colors > 256 ? 6UL : 3UL);
    colormap=(unsigned char *) AcquireQuantumMemory(image->colors,packet_size*
             sizeof(*colormap));
    if ((pixels == (unsigned char *) NULL) ||
            (colormap == (unsigned char *) NULL))
        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    /*
      Read image colormap.
    */
    count=ReadBlob(image,packet_size*image->colors,colormap);
    if (count != (ssize_t) (packet_size*image->colors))
        ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
    p=colormap;
    if (image->depth <= 8)
        for (i=0; i < (long) image->colors; i++)
        {
            image->colormap[i].red=ScaleCharToQuantum(*p++);
            image->colormap[i].green=ScaleCharToQuantum(*p++);
            image->colormap[i].blue=ScaleCharToQuantum(*p++);
        }
    else
        for (i=0; i < (long) image->colors; i++)
        {
            quantum=(*p++ << 8);
            quantum|=(*p++);
            image->colormap[i].red=(Quantum) quantum;
            quantum=(*p++ << 8);
            quantum|=(*p++);
            image->colormap[i].green=(Quantum) quantum;
            quantum=(*p++ << 8);
            quantum|=(*p++);
            image->colormap[i].blue=(Quantum) quantum;
        }
    colormap=(unsigned char *) RelinquishMagickMemory(colormap);
    if (image_info->ping != MagickFalse)
    {
        CloseBlob(image);
        return(GetFirstImageInList(image));
    }
    /*
      Read image pixels.
    */
    if (SetImageExtent(image,0,0) == MagickFalse)
    {
        InheritException(exception,&image->exception);
        return(DestroyImageList(image));
    }
    packet_size=(size_t) (depth/8);
    for (y=0; y < (long) image->rows; y++)
    {
        p=pixels;
        q=SetImagePixels(image,0,y,image->columns,1);
        if (q == (PixelPacket *) NULL)
            break;
        indexes=GetIndexes(image);
        count=ReadBlob(image,(size_t) packet_size*image->columns,pixels);
        if (count != (ssize_t) (packet_size*image->columns))
            break;
        for (x=0; x < (long) image->columns; x++)
        {
            index=ConstrainColormapIndex(image,*p);
            p++;
            if (image->colors > 256)
            {
                index=ConstrainColormapIndex(image,((unsigned long) index << 8)+(*p));
                p++;
            }
            indexes[x]=(IndexPacket) index;
            *q++=image->colormap[(long) index];
        }
        if (SyncImagePixels(image) == MagickFalse)
            break;
    }
    pixels=(unsigned char *) RelinquishMagickMemory(pixels);
    if (y < (long) image->rows)
        ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
                           image->filename);
    CloseBlob(image);
    return(GetFirstImageInList(image));
}
Example #12
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d X C I m a g e                                                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadXCImage creates a constant image and initializes it to the
%  X server color as specified by the filename.  It allocates the memory
%  necessary for the new Image structure and returns a pointer to the new
%  image.
%
%  The format of the ReadXCImage method is:
%
%      Image *ReadXCImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image:  The image.
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *ReadXCImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  Image
    *image;

  IndexPacket
    *indexes;

  MagickBooleanType
    status;

  MagickPixelPacket
    color;

  long
    y;

  register long
    x;

  register PixelPacket
    *q;

  /*
    Initialize Image structure.
  */
  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);
  if (image->columns == 0)
    image->columns=1;
  if (image->rows == 0)
    image->rows=1;
  (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent);
  status=QueryMagickColor((char *) image_info->filename,&color,exception);
  if (status == MagickFalse)
    {
      image=DestroyImage(image);
      return((Image *) NULL);
    }
  image->colorspace=color.colorspace;
  image->matte=color.matte;
  if ((image->colorspace == RGBColorspace) && (image->matte == MagickFalse))
    {
      if (AllocateImageColormap(image,1) == MagickFalse)
        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
      (void) QueryColorDatabase((char *) image_info->filename,
        &image->background_color,exception);
      image->colormap[0]=image->background_color;
      color.index=0.0;
    }
  if (SetImageExtent(image,0,0) == MagickFalse)
    {
      InheritException(exception,&image->exception);
      return(DestroyImageList(image));
    }
  for (y=0; y < (long) image->rows; y++)
  {
    q=GetImagePixels(image,0,y,image->columns,1);
    if (q == (PixelPacket *) NULL)
      break;
    indexes=GetIndexes(image);
    for (x=0; x < (long) image->columns; x++)
    {
      q->red=RoundToQuantum(color.red);
      q->green=RoundToQuantum(color.green);
      q->blue=RoundToQuantum(color.blue);
      if (image->matte)
        q->opacity=RoundToQuantum(color.opacity);
      if ((image->storage_class == PseudoClass) ||
          (image->colorspace == CMYKColorspace))
        indexes[x]=(IndexPacket) RoundToQuantum(color.index);
      q++;
    }
    if (SyncImagePixels(image) == MagickFalse)
      break;
  }
  return(GetFirstImageInList(image));
}
Example #13
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d V I C A R I m a g e                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method ReadVICARImage reads a VICAR 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 ReadVICARImage method is:
%
%      Image *ReadVICARImage(const ImageInfo *image_info,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image: Method ReadVICARImage 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 *ReadVICARImage(const ImageInfo *image_info,
  ExceptionInfo *exception)
{
  char
    keyword[MaxTextExtent],
    value[MaxTextExtent];

  Image
    *image;

  int
    c,
    y;

  long
    count;

  unsigned char
    *scanline;

  unsigned int
    status,
    value_expected;

  unsigned long
    length;

  /*
    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);
  /*
    Decode image header.
  */
  c=ReadBlobByte(image);
  count=1;
  if (c == EOF)
    {
      DestroyImage(image);
      return((Image *) NULL);
    }
  length=0;
  image->columns=0;
  image->rows=0;
  while (isgraph(c) && ((image->columns == 0) || (image->rows == 0)))
  {
    if (!isalnum(c))
      {
        c=ReadBlobByte(image);
        count++;
      }
    else
      {
        register char
          *p;

        /*
          Determine a keyword and its value.
        */
        p=keyword;
        do
        {
          if ((p-keyword) < (MaxTextExtent-1))
            *p++=c;
          c=ReadBlobByte(image);
          count++;
        } while (isalnum(c) || (c == '_'));
        *p='\0';
        value_expected=False;
        while (isspace(c) || (c == '='))
        {
          if (c == '=')
            value_expected=True;
          c=ReadBlobByte(image);
          count++;
        }
        if (value_expected == False)
          continue;
        p=value;
        while (isalnum(c))
        {
          if ((p-value) < (MaxTextExtent-1))
            *p++=c;
          c=ReadBlobByte(image);
          count++;
        }
        *p='\0';
        /*
          Assign a value to the specified keyword.
        */
        if (LocaleCompare(keyword,"Label_RECORDS") == 0)
          length=MagickAtoL(value);
        if (LocaleCompare(keyword,"LBLSIZE") == 0)
          length=MagickAtoL(value);
        if (LocaleCompare(keyword,"RECORD_BYTES") == 0)
          image->columns= MagickAtoL(value);
        if (LocaleCompare(keyword,"NS") == 0)
          image->columns= MagickAtoL(value);
        if (LocaleCompare(keyword,"LINES") == 0)
          image->rows= MagickAtoL(value);
        if (LocaleCompare(keyword,"NL") == 0)
          image->rows= MagickAtoL(value);
      }
    while (isspace(c))
    {
      c=ReadBlobByte(image);
      count++;
    }
  }
  while (count < (long) length)
  {
    c=ReadBlobByte(image);
    count++;
  }
  if ((image->columns == 0) || (image->rows == 0))
    ThrowReaderException(CorruptImageError,NegativeOrZeroImageSize,image);
  image->depth=8;
  if (!AllocateImageColormap(image,256))
    ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
  if (image_info->ping)
    {
      CloseBlob(image);
      return(image);
    }
  /*
    Read VICAR pixels.
  */
  scanline=MagickAllocateMemory(unsigned char *,image->columns);
  if (scanline == (unsigned char *) NULL)
    ThrowReaderException(CorruptImageError,UnableToReadImageData,image);
  for (y=0; y < (long) image->rows; y++)
  {
    if (!SetImagePixels(image,0,y,image->columns,1))
      break;
    (void) ReadBlob(image,image->columns,scanline);
    (void) ImportImagePixelArea(image,GrayQuantum,image->depth,scanline,0,0);
    if (!SyncImagePixels(image))
      break;
    if (QuantumTick(y,image->rows))
      if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
                                  image->filename,
				  image->columns,image->rows))
        break;
  }
  MagickFreeMemory(scanline);
  if (EOFBlob(image))
    ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
      image->filename);
  CloseBlob(image);
  return(image);
}
Example #14
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d S T E G A N O I m a g e                                           %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadSTEGANOImage() reads a steganographic image hidden within another
%  image type.  It allocates the memory necessary for the new Image structure
%  and returns a pointer to the new image.
%
%  The format of the ReadSTEGANOImage method is:
%
%      Image *ReadSTEGANOImage(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 *ReadSTEGANOImage(const ImageInfo *image_info,
  ExceptionInfo *exception)
{
#define GetBit(alpha,i) (((unsigned long) (alpha) >> (unsigned long) \
  (i)) & 0x01)
#define SetBit(alpha,i,set) (alpha)=(Quantum) ((set) != 0 ? (unsigned long) \
  (alpha) | (1UL << (unsigned long) (i)) : (unsigned long) (alpha) & \
  ~(1UL << (unsigned long) (i)))

  Image
    *image,
    *watermark;

  ImageInfo
    *read_info;

  long
    c,
    i,
    j,
    k,
    y;

  MagickBooleanType
    status;

  PixelPacket
    pixel;

  register IndexPacket
    *indexes;

  register long
    x;

  register PixelPacket
    *q;

  /*
    Initialize Image structure.
  */
  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);
  if ((image->columns == 0) || (image->rows == 0))
    ThrowReaderException(OptionError,"MustSpecifyImageSize");
  read_info=CloneImageInfo(image_info);
  SetImageInfoBlob(read_info,(void *) NULL,0);
  *read_info->magick='\0';
  watermark=ReadImage(read_info,exception);
  read_info=DestroyImageInfo(read_info);
  if (watermark == (Image *) NULL)
    return((Image *) NULL);
  watermark->depth=MAGICKCORE_QUANTUM_DEPTH;
  if (AllocateImageColormap(image,MaxColormapSize) == MagickFalse)
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  if (image_info->ping != MagickFalse)
    {
      CloseBlob(image);
      return(GetFirstImageInList(image));
    }
  /*
    Get hidden watermark from low-order bits of image.
  */
  c=0;
  i=0;
  j=0;
  k=image->offset;
  for (i=MAGICKCORE_QUANTUM_DEPTH-1; (i >= 0) && (j < MAGICKCORE_QUANTUM_DEPTH); i--)
  {
    for (y=0; (y < (long) image->rows) && (j < MAGICKCORE_QUANTUM_DEPTH); y++)
    {
      for (x=0; (x < (long) image->columns) && (j < MAGICKCORE_QUANTUM_DEPTH); x++)
      {
        pixel=AcquireOnePixel(watermark,k % (long) watermark->columns,
          k/(long) watermark->columns,exception);
        q=GetImagePixels(image,x,y,1,1);
        if (q == (PixelPacket *) NULL)
          break;
        indexes=GetIndexes(image);
        switch (c)
        {
          case 0:
          {
            SetBit(*indexes,i,GetBit(pixel.red,j));
            break;
          }
          case 1:
          {
            SetBit(*indexes,i,GetBit(pixel.green,j));
            break;
          }
          case 2:
          {
            SetBit(*indexes,i,GetBit(pixel.blue,j));
            break;
          }
        }
        if (SyncImagePixels(image) == MagickFalse)
          break;
        c++;
        if (c == 3)
          c=0;
        k++;
        if (k == (long) (watermark->columns*watermark->columns))
          k=0;
        if (k == image->offset)
          j++;
      }
    }
    if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
        (QuantumTick(i,MAGICKCORE_QUANTUM_DEPTH) != MagickFalse))
      {
        status=image->progress_monitor(LoadImagesTag,i,MAGICKCORE_QUANTUM_DEPTH,
          image->client_data);
        if (status == MagickFalse)
          break;
      }
  }
  watermark=DestroyImage(watermark);
  (void) SyncImage(image);
  return(GetFirstImageInList(image));
}
Example #15
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);
Example #16
0
File: sgi.c Project: scuddalo/cq
static Image *ReadSGIImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  Image
    *image;

  long
    y,
    z;

  MagickBooleanType
    status;

  MagickSizeType
    number_pixels;

  register IndexPacket
    *indexes;

  register long
    i,
    x;

  register PixelPacket
    *q;

  register unsigned char
    *p;

  ssize_t
    count;

  SGIInfo
    iris_info;

  size_t
    bytes_per_pixel;

  unsigned char
    *iris_pixels;

  unsigned long
    quantum;

  /*
    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 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);
    image->columns=iris_info.columns;
    image->rows=iris_info.rows;
    image->depth=(unsigned long) MagickMin(iris_info.depth,MAGICKCORE_QUANTUM_DEPTH);
    if (iris_info.pixel_format == 0)
      image->depth=(unsigned long) MagickMin((size_t) 8*
        iris_info.bytes_per_pixel,MAGICKCORE_QUANTUM_DEPTH);
    if (iris_info.depth < 3)
      {
        image->storage_class=PseudoClass;
        image->colors=256;
      }
    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));
      }
    /*
      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");
    iris_pixels=(unsigned char *) AcquireQuantumMemory(iris_info.columns,
      iris_info.rows*4*bytes_per_pixel*sizeof(*iris_pixels));
    if (iris_pixels == (unsigned char *) NULL)
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    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 < (long) iris_info.depth; z++)
        {
          p=iris_pixels+bytes_per_pixel*z;
          for (y=0; y < (long) 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 < (long) iris_info.columns; x++)
              {
                *p=scanline[2*x];
                *(p+1)=scanline[2*x+1];
                p+=8;
              }
            else
              for (x=0; x < (long) iris_info.columns; x++)
              {
                *p=scanline[x];
                p+=4;
              }
          }
        }
        scanline=(unsigned char *) RelinquishMagickMemory(scanline);
      }
    else
      {
        ssize_t
          offset,
          *offsets;

        unsigned char
          *packets;

        unsigned int
          data_order;

        unsigned long
          *runlength;

        /*
          Read runlength-encoded image format.
        */
        offsets=(ssize_t *) AcquireQuantumMemory((size_t) iris_info.rows,
          iris_info.depth*sizeof(*offsets));
        packets=(unsigned char *) AcquireQuantumMemory((size_t)
          iris_info.columns+10UL,4UL*sizeof(*packets));
        runlength=(unsigned long *) AcquireQuantumMemory(iris_info.rows,
          iris_info.depth*sizeof(*runlength));
        if ((offsets == (ssize_t *) NULL) ||
            (packets == (unsigned char *) NULL) ||
            (runlength == (unsigned long *) NULL))
          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        for (i=0; i < (long) (iris_info.rows*iris_info.depth); i++)
          offsets[i]=(ssize_t) ReadBlobMSBLong(image);
        for (i=0; i < (long) (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 < (long) iris_info.rows) && (data_order == 0)); y++)
          for (z=0; ((z < (long) 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 < (long) iris_info.depth; z++)
            {
              p=iris_pixels;
              for (y=0; y < (long) iris_info.rows; y++)
              {
                if (offset != offsets[y+z*iris_info.rows])
                  {
                    offset=offsets[y+z*iris_info.rows];
                    offset=(ssize_t) SeekBlob(image,(long) offset,SEEK_SET);
                  }
                count=ReadBlob(image,(size_t) runlength[y+z*iris_info.rows],
                  packets);
                if (EOFBlob(image) != MagickFalse)
                  break;
                offset+=runlength[y+z*iris_info.rows];
                status=SGIDecode(bytes_per_pixel,(long)
                  (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=iris_pixels;
            for (y=0; y < (long) iris_info.rows; y++)
            {
              for (z=0; z < (long) iris_info.depth; z++)
              {
                if (offset != offsets[y+z*iris_info.rows])
                  {
                    offset=offsets[y+z*iris_info.rows];
                    offset=(ssize_t) SeekBlob(image,(long) offset,SEEK_SET);
                  }
                count=ReadBlob(image,(size_t) runlength[y+z*iris_info.rows],
                  packets);
                if (EOFBlob(image) != MagickFalse)
                  break;
                offset+=runlength[y+z*iris_info.rows];
                status=SGIDecode(bytes_per_pixel,(long)
                  (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);
          }
        runlength=(unsigned long *) RelinquishMagickMemory(runlength);
        packets=(unsigned char *) RelinquishMagickMemory(packets);
        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 < (long) image->rows; y++)
            {
              p=iris_pixels+(image->rows-y-1)*8*image->columns;
              q=SetImagePixels(image,0,y,image->columns,1);
              if (q == (PixelPacket *) NULL)
                break;
              for (x=0; x < (long) image->columns; x++)
              {
                q->red=ScaleShortToQuantum((unsigned short)
                  ((*(p+0) << 8) | (*(p+1))));
                q->green=ScaleShortToQuantum((unsigned short)
                  ((*(p+2) << 8) | (*(p+3))));
                q->blue=ScaleShortToQuantum((unsigned short)
                  ((*(p+4) << 8) | (*(p+5))));
                q->opacity=OpaqueOpacity;
                if (image->matte != MagickFalse)
                  q->opacity=(Quantum) (QuantumRange-ScaleShortToQuantum(
                    (unsigned short) ((*(p+6) << 8) | (*(p+7)))));
                p+=8;
                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;
                  }
            }
          }
        else
          for (y=0; y < (long) image->rows; y++)
          {
            p=iris_pixels+(image->rows-y-1)*4*image->columns;
            q=SetImagePixels(image,0,y,image->columns,1);
            if (q == (PixelPacket *) NULL)
              break;
            for (x=0; x < (long) image->columns; x++)
            {
              q->red=ScaleCharToQuantum(*p);
              q->green=ScaleCharToQuantum(*(p+1));
              q->blue=ScaleCharToQuantum(*(p+2));
              q->opacity=OpaqueOpacity;
              if (image->matte != MagickFalse)
                q->opacity=(Quantum) (QuantumRange-ScaleCharToQuantum(*(p+3)));
              p+=4;
              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;
                }
          }
      }
    else
      {
        /*
          Create grayscale map.
        */
        if (AllocateImageColormap(image,image->colors) == MagickFalse)
          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        /*
          Convert SGI image to PseudoClass pixel packets.
        */
        if (bytes_per_pixel == 2)
          {
            for (y=0; y < (long) image->rows; y++)
            {
              p=iris_pixels+(image->rows-y-1)*8*image->columns;
              q=SetImagePixels(image,0,y,image->columns,1);
              if (q == (PixelPacket *) NULL)
                break;
              indexes=GetIndexes(image);
              for (x=0; x < (long) image->columns; x++)
              {
                quantum=(*p << 8);
                quantum|=(*(p+1));
                indexes[x]=(IndexPacket) quantum;
                p+=8;
                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;
                  }
            }
          }
        else
          for (y=0; y < (long) image->rows; y++)
          {
            p=iris_pixels+(image->rows-y-1)*4*image->columns;
            q=SetImagePixels(image,0,y,image->columns,1);
            if (q == (PixelPacket *) NULL)
              break;
            indexes=GetIndexes(image);
            for (x=0; x < (long) image->columns; x++)
            {
              indexes[x]=(IndexPacket) (*p);
              p+=4;
              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;
                }
          }
        (void) SyncImage(image);
      }
    iris_pixels=(unsigned char *) RelinquishMagickMemory(iris_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;
    iris_info.magic=ReadBlobMSBShort(image);
    if (iris_info.magic == 0x01DA)
      {
        /*
          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 (iris_info.magic == 0x01DA);
  CloseBlob(image);
  return(GetFirstImageInList(image));
}