hdf5/tools/gifconv/gifread.c
Bill Wendling a003adc409 [svn-r6540] Purpose:
Update

Description:
    Updated copyright statement

Platforms tested:
    Linux (Only change in comments...checked if compiles)

Misc. update:
2003-03-31 13:04:52 -05:00

403 lines
12 KiB
C

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by the Board of Trustees of the University of Illinois. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the files COPYING and Copyright.html. COPYING can be found at the root *
* of the source code distribution tree; Copyright.html can be found at the *
* root level of an installed copy of the electronic HDF5 document set and *
* is linked from the top-level documents page. It can also be found at *
* http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <stdio.h>
#include <stdlib.h>
#include "gif.h"
int EndianOrder;
static BYTE *ReadDataSubBlocks(BYTE **MemGif2, WORD *DSize);
WORD
GetWord(BYTE *MemGif)
{
WORD w;
if (EndianOrder == 1) {
/* LittleEndian */
w = (WORD) (*MemGif++ & 0xFF);
w |= (WORD) ((*MemGif++ & 0xFF) << 0x08);
} else {
w = (WORD) (*MemGif++ & 0xFF);
w = ((WORD) (*MemGif++ & 0xFF)) | (w << 0x08);
}
return w;
}
BYTE
GetByte(BYTE *MemGif)
{
return *MemGif;
}
/*
* Read a GIF image BYTE Header.
*
* This function reads the Header, Logical Screen Descriptor, and
* Global Color Table (if any) from a GIF image file. The information
* is stored in a GIFHEAD structure.
*
* Returns: -1 if a FILE stream error occured during the read,
* otherwise 0 if no error occured.
*/
int
ReadGifHeader(GIFHEAD *GifHead, /* Pointer to GIF header structure */
BYTE **MemGif2) /* GIF image file input FILE stream */
{
WORD i; /* Loop counter */
WORD tableSize; /* Number of entires in the Global Color Table */
GifHead->TableSize = 0;
for (i = 0 ; i < 6 ; i++) {
GifHead->HeaderDump[i] = *(*MemGif2)++;
}
if (strncmp((const char *)GifHead->HeaderDump , "GIF" , 3)) {
printf("The file does not appear to be a valid GIF file.\n");
exit(-1);
}
for (i = 0 ; i < 7 ; i++) {
GifHead->LSDDump[i] = *(*MemGif2)++;
}
GifHead->PackedField = GifHead->LSDDump[4];
/* Check if a Global Color Table is present */
if (GifHead->PackedField & 0x80) {
/* Read number of color table entries */
tableSize = (WORD) (1L << ((GifHead->PackedField & 0x07) + 1));
GifHead->TableSize = tableSize;
/* Read the Global Color Table */
/*
* There are some changes made here apart from just reading in the
* global color table as would seem intuitively obvious. The colors
* are stored in the bottom part of the palette as opposed to the top
*/
for (i = 0; i < tableSize; i++) {
GifHead->HDFPalette[i][0] = *(*MemGif2)++;
GifHead->HDFPalette[i][1] = *(*MemGif2)++;
GifHead->HDFPalette[i][2] = *(*MemGif2)++;
}
}
/* Check for a FILE stream error */
#if 0
if (ferror(FpGif))
return -1;
#endif /* 0 */
return 0; /* No FILE stream error occured */
}
/*
** Read a GIF Local Image Descriptor.
**
** This function reads the Local Image Descriptor, and Local Color
** Table (if any) from a GIF image file. The information is stored
** in a GIFIMAGEDESC structure.
**
** Note that the ImageSeparator field value in the GIFIMAGEDESC
** structure is assigned by the function calling ReadGifImageDesc().
**
** Returns: -1 if a FILE stream error occured during the read,
** otherwise 0 if no error occured.
*/
int
ReadGifImageDesc(
GIFIMAGEDESC *GifImageDesc, /* Pointer to GIF image descriptor structure */
BYTE **MemGif2 /* GIF image file input FILE stream */
)
{
WORD i; /* Loop counter */
WORD tableSize; /* Number of entries in the Local Color Table */
/* BYTE Interlace; */ /* PackedField & 0x20 gives information on interlacing */
BYTE *TempPtr;
int ch , ch1;
GifImageDesc->TableSize = 0;
for (i = 0 ; i < 9 ; i++) {
GifImageDesc->GIDDump[i] = *(*MemGif2)++;
}
/*
** Get the relevant fields. I need ImageWidth and Height actively hence I have
** taken information from those fields. I intend to keep the GifImageDesc data
** structure as it is so that anyone needing the rest of the fields can do so
** quickly.
*/
if (EndianOrder == 1) /* LittleEndian */
{
GifImageDesc->ImageWidth = (WORD) (GifImageDesc->GIDDump[4] & 0xFF);
GifImageDesc->ImageWidth |= (WORD) ((GifImageDesc->GIDDump[5] & 0xFF) << 0x08);
GifImageDesc->ImageHeight = (WORD) (GifImageDesc->GIDDump[6] & 0xFF);
GifImageDesc->ImageHeight |= (WORD) ((GifImageDesc->GIDDump[7] & 0xFF) << 0x08);
}
else
{
GifImageDesc->ImageWidth = (WORD) (GifImageDesc->GIDDump[4] & 0xFF);
GifImageDesc->ImageWidth = ((WORD) (GifImageDesc->GIDDump[5] & 0xFF)) | (GifImageDesc->ImageWidth << 0x08);
GifImageDesc->ImageHeight = (WORD) (GifImageDesc->GIDDump[6] & 0xFF);
GifImageDesc->ImageHeight = ((WORD) (GifImageDesc->GIDDump[7] & 0xFF)) | (GifImageDesc->ImageWidth << 0x08);
}
GifImageDesc->PackedField = GifImageDesc->GIDDump[8];
/* Interlace = GifImageDesc->PackedField & 0x20; */
/* Check if a Local Color Table is present */
if (GifImageDesc->PackedField & 0x80)
{
/* Read number of color table entries */
tableSize = (WORD) (1L << ((GifImageDesc->PackedField & 0x07) + 1));
GifImageDesc->TableSize = tableSize;
/* Read the Local Color Table */
for (i = 0; i < tableSize; i++)
{
GifImageDesc->HDFPalette[i][0] = *(*MemGif2)++;
GifImageDesc->HDFPalette[i][1] = *(*MemGif2)++;
GifImageDesc->HDFPalette[i][2] = *(*MemGif2)++;
}
}
/*
** Get LZW minimum Code Size
*/
GifImageDesc->CodeSize = (WORD)*(*MemGif2)++;
/*GifImageDesc->GIFImage = ReadDataSubBlocks(FpGif);*/
if (!(GifImageDesc->GIFImage = (BYTE *)malloc((GifImageDesc->ImageWidth) * (GifImageDesc->ImageHeight)))) {
printf("Out of memory");
exit(-1);
}
TempPtr = GifImageDesc->GIFImage;
do
{
ch = ch1 = (int)*(*MemGif2)++;
while (ch--) *TempPtr++ = *(*MemGif2)++;
}
while (ch1);
return(0); /* No FILE stream error occured */
}
/*
** Read a GIF Graphic Control Extension block.
**
** Note that the Introducer and Label field values in the GIFGRAPHICCONTROL
** structure are assigned by the function calling ReadGifGraphicControl().
**
** Returns: -1 if a FILE stream error occured during the read,
** otherwise 0 if no error occured.
*/
int
ReadGifGraphicControl(
GIFGRAPHICCONTROL *GifGraphicControl, /* Pointer to GC Extension structure */
BYTE **MemGif2 /* GIF image file input FILE stream */
)
{
int i;
for (i = 0 ; i < 5 ; i++) {
GifGraphicControl->GCEDump[i] = *(*MemGif2)++;
}
return(0); /* No FILE stream error occured */
}
/*
** Read a GIF Plain Text Extension block.
**
** Note that the Introducer and Label field values in the GIFLPLAINTEXT
** structure are assigned by the function calling ReadGifPlainText().
**
** Returns: -1 if a FILE stream error occured during the read,
** otherwise 0 if no error occured.
*/
int
ReadGifPlainText(
GIFPLAINTEXT *GifPlainText, /* Pointer to Plain Text Extension structure */
BYTE **MemGif2 /* GIF image file input FILE stream */
)
{
int i;
for (i = 0 ; i < 13 ; i++) {
GifPlainText->PTEDump[i] = *(*MemGif2)++;
}
/* Read in the Plain Text data sub-blocks */
if (!(GifPlainText->PlainTextData = ReadDataSubBlocks(MemGif2 , &(GifPlainText->DataSize))))
return(1);
/*
GifPlainText->Terminator = 0;
*/
/* Check for a FILE stream error */
/*
if (ferror(FpGif))
return(-1);
*/
return(0); /* No FILE stream error occured */
}
/*
** Read a GIF Application Extension block.
**
** Note that the Introducer and Label field values in the GIFAPPLICATION
** structure are assigned by the function calling ReadGifApplication().
**
** Returns: -1 if a FILE stream error occured during the read,
** otherwise 0 if no error occured.
*/
int
ReadGifApplication(
GIFAPPLICATION *GifApplication, /* Pointer to Application Extension structure */
BYTE **MemGif2 /* GIF image file input FILE stream */
)
{
int i;
for (i = 0 ; i < 12 ; i++) {
GifApplication->AEDump[i] = *(*MemGif2)++;
}
/* Read in the Plain Text data sub-blocks */
if (!(GifApplication->ApplicationData = ReadDataSubBlocks(MemGif2 , &(GifApplication->DataSize))))
return(1);
/*
GifApplication->Terminator = 0;
*/
/* Check for a FILE stream error */
/*
if (ferror(FpGif))
return(-1);
*/
return(0); /* No FILE stream error occured */
}
/*
** Read a GIF Comment Extension block.
**
** Note that the Introducer and Label field values in the GIFCOMMENT
** structure are assigned by the function calling ReadGifComment().
**
** Returns: -1 if a FILE stream error occured during the read,
** otherwise 0 if no error occured.
*/
int
ReadGifComment(
GIFCOMMENT *GifComment, /* Pointer to GIF Comment Extension structure */
BYTE **MemGif2 /* GIF image file input FILE stream */
)
{
/* Read in the Plain Text data sub-blocks */
if (!(GifComment->CommentData = ReadDataSubBlocks(MemGif2 , &(GifComment->DataSize))))
return(1);
GifComment->Terminator = 0;
return(0); /* No FILE stream error occured */
}
/*
** Read one or more GIF data sub-blocks and write the information
** to a buffer.
**
** A GIF "sub-block" is a single count byte followed by 1 to 255
** additional data bytes.
**
** Returns: A NULL pointer if a memory allocation error occured,
** otherwise a valid pointer if no error occured.
*/
static BYTE *
ReadDataSubBlocks(BYTE **MemGif2, /* GIF image file input FILE stream */
WORD *DSize)
{
BYTE *ptr1; /* Pointer used to "walk the heap" */
BYTE *ptr2; /* Pointer used to mark the top of the heap */
BYTE dataSize; /* Size of the current data sub-block being read */
WORD bufSize; /* Total size of the Plain Text data buffer */
int tempcount = 0;
bufSize = 0; /* The output buffer is empty */
dataSize = *(*MemGif2)++; /* Get the size of the first sub-block */
/* Allocate initial data buffer */
if (!(ptr1 = ptr2 = (BYTE *) malloc((size_t)dataSize + 1))) {
printf("Out of memory. Allocation of memory for data sub-blocks for\neither Comment, Plain Text or Application Extensions failed");
return((BYTE *) NULL);
}
for (;;)
{
tempcount++;
bufSize += (dataSize); /* Running total of the buffer size */
*DSize = bufSize;
#ifdef COMMENTED_OUT
*ptr1++ = dataSize; /* Write the data count */
#endif /* COMMENTED_OUT */
while (dataSize--) /* Read/write the Plain Text data */
*ptr1++ = *(*MemGif2)++;
/* Check if there is another data sub-block */
if ((dataSize = *(*MemGif2)++) == 0)
break; /* Block Terminator encountered */
/* Increase the buffer size to accomodate the next sub-block */
if (!(ptr1 = ptr2 = (BYTE *) realloc(ptr2, bufSize + dataSize + 1)))
return((BYTE *) NULL);
ptr1 += bufSize; /* Move pointer to the end of the data */
}
*ptr1++ = '\0';
return(ptr2); /* Return a pointer to the sub-block data */
}