This is readgif.c in view mode; [Download] [Up]
/*
* ReadGIFImage - reads a GIF Image
*
* RCS:
* $Revision: 2.3 $
* $Date: 1996/05/03 02:21:34 $
*
* Security:
* Unclassified
*
* Description:
* Adapted mostly from ImageMagick 3.1
*
* Input Parameters:
* type identifier description
*
* text
*
* Output Parameters:
* type identifier description
*
* text
*
* Return Values:
* value description
*
* Side Effects:
* text
*
* Limitations and Comments:
* text
*
* Development History:
* when who why
* 6/28/94 muquit first cut
*/
#include "combine.h"
#include "defines.h"
#include "errcds.h"
int ReadGIFImage (image)
Image
*image;
{
#define BitSet(byte, bit) (((byte) & (bit)) == (bit))
#define LSBFirstOrder(x, y) (((y) << 8) | (x))
int
rc = 0;
int
pass,
x, y;
short int
transparency_index;
register int
i;
register Runlength
*q;
register unsigned char
*p;
unsigned char
c,
*global_colormap,
header[MaxTextLength],
type[12];
unsigned int
global_colors,
image_count,
interlace,
local_colormap;
FILE
*fp=(FILE *) NULL;
Image
*next_image = (Image *) NULL;
fp = fopen (image->filename, "rb");
if (fp == (FILE *) NULL)
{
fprintf (stderr, "could not open file: %s\n",image->filename);
rc = OPEN_FAILED;
goto ExitProcessing;
}
image->fp = fp;
rc = Read_Data ((char *) type, 1, 6, fp);
if ((rc == 1) || ((strncmp((char *) type, "GIF87", 5) != 0) &&
(strncmp ((char *) type, "GIF89", 5) != 0)))
{
fprintf (stderr, "Not a GIF Image: [%s]\n",image->filename);
rc = NOT_A_GIF_FILE;
goto ExitProcessing;
}
#ifdef DEBUG
fprintf (stderr, " File Type: %s\n",type);
#endif
rc = Read_Data ((char *) header, 1, 7, fp);
if (rc == 1)
{
rc = FAILED_TO_READ_SCREEND;
goto ExitProcessing;
}
global_colors = 0;
global_colormap = (unsigned char *) NULL;
if (BitSet(header[4], 0x80))
{
global_colors = 1 << ((header[4] & 0x07) + 1);
global_colormap = (unsigned char *)
malloc (3*global_colors*sizeof(unsigned char));
if (global_colormap == (unsigned char *) NULL)
{
rc = MALLOC_FAILED;
goto ExitProcessing;
}
(void) Read_Data ((char *) global_colormap, 3, (int) global_colors,
fp);
}
transparency_index = (-1);
image_count = 0;
for ( ; ; )
{
rc = Read_Data ((char *) &c, 1, 1, fp);
if (rc == 1)
{
rc = 0;
break;
}
if (c == ';') /* terminator */
break;
if (c == '!') /* EXTENSION ! */
{
rc = Read_Data ((char *) &c, 1, 1, fp);
if (rc == 1)
{
rc = READ_ERR_EXT_BLOCK;
goto ExitProcessing;
}
switch (c)
{
case 0xf9: /* Transperency */
{
while (ReadDataBlock ((char *) header, fp) !=0)
if ((header[0] * 0x01) == 1)
{
transparency_index = header[3];
}
break;
}
case 0xfe: /* comment extension */
{
int
length;
for ( ; ; )
{
length = ReadDataBlock ((char *) header, fp);
if (length <= 0)
break;
if (image->comments != (char *) NULL)
{
image->comments=(char *) realloc((char *)
image->comments,
(strlen(image->comments)+length+1)*
sizeof(char));
}
else
{
image->comments = (char *) malloc ((length + 1)*
sizeof(char));
if (image->comments != (char *) NULL)
{
*image->comments = '\0';
}
}
if (image->comments == (char *) NULL)
{
rc = MALLOC_FAILED;
goto ExitProcessing;
}
header[length] = '\0';
(void) strcat (image->comments, (char *) header);
#ifdef DEBUG
fprintf (stderr, " GIF: comment: %s\n", image->comments);
#endif
}
break;
}
default:
{
while (ReadDataBlock ((char *) header, fp) != 0);
break;
}
}
}
if (c != ',')
continue;
if (image_count != 0)
{
if (next_image != (Image *) NULL)
DestroyAnyImageStruct(&next_image);
next_image = AllocateImageStruct();
if (next_image == (Image *)NULL)
{
(void) fprintf (stderr,"Unable to Display GIF!\n");
rc=MALLOC_FAILED;
goto ExitProcessing;
}
(void) strcpy(next_image->filename, image->filename);
next_image->fp = fp;
if (image != (Image *) NULL)
DestroyAnyImageStruct(&image);
image=next_image;
}
image_count++;
/*
** can't handle multiple images in one file
*/
/*
** read Header Now
*/
rc = Read_Data ((char *) header, 1, 9, fp);
if (rc == 1)
{
rc = READ_ERR_WIDTH_HEIGHT;
goto ExitProcessing;
}
interlace = BitSet (header[8], 0x40);
local_colormap = BitSet (header[8], 0x80);
image->columns = LSBFirstOrder (header[4], header[5]);
image->rows = LSBFirstOrder (header[6], header[7]);
image->packets = image->columns*image->rows;
if (image->pixels != (Runlength *) NULL)
{
(void) free ((char *) image->pixels);
}
image->pixels = (Runlength *)
malloc (image->packets*sizeof(Runlength));
if (image->pixels == (Runlength *) NULL)
{
rc = MALLOC_FAILED;
goto ExitProcessing;
}
image->class = PseudoClass;
image->colors =
!local_colormap ? global_colors : 1 << ((header[8] & 0x07) + 1);
#ifdef DEBUG
fprintf (stderr, " GIF: no of colors: %d\n", image->colors);
#endif
image->colormap = (RGB *) malloc (image->colors*sizeof(RGB));
if (image->colormap == (RGB *) NULL)
{
rc = MALLOC_FAILED;
goto ExitProcessing;
}
if (!local_colormap)
{
p = global_colormap;
for (i=0; i < image->colors; i++)
{
image->colormap[i].red = (*p++);
image->colormap[i].green = (*p++);
image->colormap[i].blue = (*p++);
}
}
else
{
unsigned char
*colormap;
colormap = (unsigned char *)
malloc (3*image->colors*sizeof(unsigned char));
if (colormap == (unsigned char *) NULL)
{
rc = MALLOC_FAILED;
goto ExitProcessing;
}
(void) Read_Data ((char *) colormap, 3, (int) image->colors,
fp);
p = colormap;
for (i=0; i < image->colors; i++)
{
image->colormap[i].red = (*p++);
image->colormap[i].green = (*p++);
image->colormap[i].blue = (*p++);
}
(void) free ((char *) colormap);
}
rc = LZWDecodeImage (image);
if (interlace)
{
Image
*interlaced_image;
register Runlength
*p;
static int
interlace_rate[4] = { 8, 8, 4, 2 },
interlace_start[4] = { 0, 4, 2, 1 };
#ifdef DEBUG
fprintf (stderr, " GIF: processing Interlaced image\n");
#endif
interlaced_image = DuplicateImage (image, image->columns,
image->rows, True);
if (interlaced_image == (Image *) NULL)
{
rc = MALLOC_FAILED;
/* destroy interlaced_image */
goto ExitProcessing;
}
p = interlaced_image->pixels;
q = image->pixels;
for (pass=0; pass < 4; pass++)
{
y = interlace_start[pass];
while (y < image->rows)
{
q = image->pixels + (y*image->columns);
for (x=0; x < image->columns; x++)
{
*q = (*p);
p++;
q++;
}
y+=interlace_rate[pass];
}
}
DestroyAnyImageStruct (&interlaced_image);
}/*if interlace*/
/*
** handle transparency
*/
if (transparency_index >= 0)
{
/*
** create alpha channel
*/
q=image->pixels;
for(i=0; i < image->packets; i++)
{
if (q->index != (unsigned short) transparency_index)
q->index=Opaque;
else
q->index=Transparent;
q++;
}
transparency_index=(-1);
image->class=DirectClass;
image->alpha=True;
}
if (rc == 1)
{
rc = 0;
(void) fprintf (stderr," Error\n");
break;
}
break;
}/* for (;;) */
if (global_colormap != (unsigned char *) NULL)
{
(void) free ((char *) global_colormap);
}
if (image->pixels == (Runlength *) NULL)
{
rc = CORRUPT_GIF_IMAGE;
goto ExitProcessing;
}
CompressColormap(image);
ExitProcessing:
if (fp != (FILE *) NULL)
(void) fclose ((FILE *) fp);
return (rc);
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.