diff options
Diffstat (limited to 'tools/gifconv/gifread.c')
-rw-r--r-- | tools/gifconv/gifread.c | 382 |
1 files changed, 382 insertions, 0 deletions
diff --git a/tools/gifconv/gifread.c b/tools/gifconv/gifread.c new file mode 100644 index 0000000..1196241 --- /dev/null +++ b/tools/gifconv/gifread.c @@ -0,0 +1,382 @@ +#include <stdio.h> +#include <stdlib.h> +#include "gif.h" + +int EndianOrder; +int i; + + +WORD +GetWord (MemGif) +BYTE *MemGif; +{ + register 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 (MemGif) +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, MemGif2) +GIFHEAD *GifHead; /* Pointer to GIF header structure */ +BYTE **MemGif2; /* GIF image file input FILE stream */ +{ + register 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(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 (ferror(FpGif)) + return(-1); + */ + + 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, MemGif2) +GIFIMAGEDESC *GifImageDesc; /* Pointer to GIF image descriptor structure */ +BYTE **MemGif2; /* GIF image file input FILE stream */ +{ + register 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, MemGif2) +GIFGRAPHICCONTROL *GifGraphicControl; /* Pointer to GC Extension structure */ +BYTE **MemGif2; /* GIF image file input FILE stream */ +{ + + + 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, MemGif2) +GIFPLAINTEXT *GifPlainText; /* Pointer to Plain Text Extension structure */ +BYTE **MemGif2; /* GIF image file input FILE stream */ +{ + 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, MemGif2) +GIFAPPLICATION *GifApplication; /* Pointer to Application Extension structure */ +BYTE **MemGif2; /* GIF image file input FILE stream */ +{ + 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, MemGif2) +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(MemGif2 , DSize) +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(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; + + /* *ptr1++ = dataSize; /* Write the data count */ + 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++ = (BYTE) NULL; /* Add NULL to simulate Terminator value */ + *ptr1++ = '\0'; + + return(ptr2); /* Return a pointer to the sub-block data */ +} + + + + + |