summaryrefslogtreecommitdiffstats
path: root/tools/gifconv/gifread.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gifconv/gifread.c')
-rw-r--r--tools/gifconv/gifread.c382
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 */
+}
+
+
+
+
+