summaryrefslogtreecommitdiff
path: root/EDK/MiniSetup/TseAdvanced/dogif.c
diff options
context:
space:
mode:
Diffstat (limited to 'EDK/MiniSetup/TseAdvanced/dogif.c')
-rw-r--r--EDK/MiniSetup/TseAdvanced/dogif.c1197
1 files changed, 1197 insertions, 0 deletions
diff --git a/EDK/MiniSetup/TseAdvanced/dogif.c b/EDK/MiniSetup/TseAdvanced/dogif.c
new file mode 100644
index 0000000..0c641eb
--- /dev/null
+++ b/EDK/MiniSetup/TseAdvanced/dogif.c
@@ -0,0 +1,1197 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/TseAdvanced/dogif.c $
+//
+// $Author: Arunsb $
+//
+// $Revision: 8 $
+//
+// $Date: 10/18/12 5:53a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/TseAdvanced/dogif.c $
+//
+// 8 10/18/12 5:53a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 10 10/10/12 12:35p Arunsb
+// Synched the source for v2.16.1232, backup with Aptio
+//
+// 7 3/28/11 9:35p Arunsb
+// [TAG] EIP55548
+// [Category] Improvement
+// [Description] Support to display Multiple GIF and to display other
+// image format when Active animated Gif is displaying
+// [Files] dogif.c and dogifmgr.c
+//
+// 6 3/21/11 1:16a Rajashakerg
+// [TAG] EIP53740
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Animation does not continue after the last frame of the
+// logo.
+// [RootCause] The animation is done upto last frame of the animated
+// image.
+// [Solution] Fixed the issue by handling Gif image data to redraw image
+// if all the frames are completed and if boottimeout is present.
+// [Files] minisetup.h, dogif.c, dogifmgr.c
+//
+// 5 6/17/10 2:59p Madhans
+// Dynamic parsing support in TSE.
+//
+// 4 2/19/10 1:02p Madhans
+// Updated for TSE 2.01. Refer Changelog.log for File change history.
+//
+// 7 2/19/10 8:11a Mallikarjunanv
+// updated year in copyright message
+//
+// 6 2/15/10 10:12p Madhans
+// To avoid warnings
+//
+// 5 1/09/10 4:46a Mallikarjunanv
+// Updated TSE2.01 Release sources with coding standards
+//
+// 4 12/04/09 7:12a Mallikarjunanv
+// Fix for EIP:30263 - Gif Logo Issue
+//
+// 3 6/23/09 7:09p Blaines
+// Coding standard update,
+// Remove spaces from file header to allow proper chm function list
+// creation.
+//
+// 2 6/12/09 7:43p Presannar
+// Initial implementation of coding standards for AMITSE2.0
+//
+// 1 6/04/09 8:05p Madhans
+//
+// 1 4/28/09 11:16p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 1 4/28/09 10:27p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 2 7/06/06 6:38p Arunkumars
+// warn fix
+//
+// 1 1/24/06 3:01a Stefanor
+// quiet boot support
+// implementation of buffering for POST messages
+// gif support
+// support for OEM badging protocol
+// fixed fallback from 100x31 to 80x25
+// cleanup of set graphic/text mode
+// ver 1.17.1051
+//
+//*****************************************************************//
+//*****************************************************************//
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: dogif.c
+//
+// Description: This file contains code for gif image handling
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#include<minisetup.h>
+
+// definitions
+#undef DEBUG
+#undef TRUE
+#undef FALSE
+
+#define DEBUG 0
+#define TIANO 1
+#if TIANO
+#define TRUE 1
+#else
+#define TRUE (-1)
+#endif
+#define FALSE 0
+
+#define MaxColors 256 /* rev 87a */
+
+struct ColorEntry
+ {
+ unsigned char blue, green, red, dummy;
+ };
+
+#if TIANO
+#define short int
+//#define unsigned
+#define huge
+#define far
+unsigned char * blitbuf = 0;
+static struct ColorEntry * pColorMap = 0;
+#else
+#define _FP_SEG(fp) (*((unsigned __far *)&(fp)+1))
+#define _FP_OFF(fp) (*((unsigned __far *)&(fp)))
+#define _MK_FP(seg, offset) (void __far *)(((unsigned long)seg << 16) \
+ + (unsigned long)(unsigned)offset)
+#endif
+
+// variables
+#if TIANO
+int screen_width = 800;
+int screen_height = 600;
+#else
+int screen_width = 640;
+int screen_height = 480;
+#endif
+
+unsigned char huge * pbuf = 0;
+unsigned long lenbuf = 0;
+unsigned long firstframeadd = 0; //EIP: 53740 global decleration such that we access the first frame address of the gif image
+
+static char GIF87signature[] = "GIF87a";
+static char GIF89signature[] = "GIF89a";
+static char GIFversion = 0;
+#define GIF87 1
+#define GIF89 2
+static struct ColorEntry GlobalColorMap[MaxColors] = {{0}};
+static struct ColorEntry LocalColorMap[MaxColors] = {{0}};
+static unsigned int BackdropWidth = 0;
+static unsigned int BackdropHeight = 0;
+static unsigned int LeftMargin = 0;
+static unsigned int TopMargin = 0;
+static unsigned int ColorRez = 0;
+static unsigned int FillColor = 0;
+#if TIANO
+static short DefaultNumColors = 0;
+#else
+static unsigned int DefaultNumColors = 0;
+#endif
+static unsigned int LeftEdge = 0;
+static unsigned int TopEdge = 0;
+static unsigned int Width = 0;
+static unsigned int Height = 0;
+static unsigned int Interlaced = 0;
+#if TIANO
+static short LocalNumColors = 0;
+#else
+static unsigned int LocalNumColors = 0;
+#endif
+static unsigned int RightEdge = 0;
+static unsigned int BottomEdge = 0;
+static unsigned int InterlacePass = 0;
+static unsigned int X = 0;
+static unsigned int Y = 0;
+static short BaseLine[5] = {0, 4, 2, 1, 0};
+static short LineOffset[5] = {8, 8, 4, 2, 0};
+
+unsigned char huge * pcurbuf = 0;
+static unsigned long unreadbuf = 0;
+
+static unsigned int CurrentBank = 0;
+static unsigned long PixelAdd = 0;
+
+static int TransparentColor = -1;
+static int GlobalColorMapActive = FALSE;
+
+static int UnexpectedError = FALSE;
+
+// functions
+#if TIANO
+unsigned long dofirst( unsigned char *, unsigned long );
+unsigned long donext( unsigned char * );
+#else
+unsigned long far _loadds dofirst(void);
+unsigned long far _loadds donext(void);
+#endif
+static int _inline readbuf(void);
+static void _inline writepixel(unsigned char);
+static void setbank(unsigned int);
+static short ReadScreenDesc(void);
+static short ReadImageDesc(void);
+static unsigned long ReadGraphicControlExt(void);
+#if DEBUG
+static short ReadCommentExt(void);
+static short ReadPlainTextExt(void);
+static short ReadApplicationExt(void);
+#endif
+static short SkipObject(void);
+static void SetPalette( struct ColorEntry [], unsigned int );
+static short Expand_Data(void);
+
+extern UINT16 gGifSrcX;
+extern UINT16 gGifSrcY;
+extern UINT16 gGifDestX;
+extern UINT16 gGifDestY;
+extern BOOLEAN GifImageFlag;
+
+// Expander
+struct code_entry
+ {
+ short prefix; /* prefix code */
+ char suffix; /* suffix character */
+ char stack;
+ };
+static short code_size = 0;
+static short clear_code = 0;
+static short eof_code = 0;
+static short first_free = 0;
+static short bit_offset = 0;
+static short byte_offset = 0;
+static short bits_left = 0;
+static short max_code = 0;
+static short free_code = 0;
+static short old_code = 0;
+static short input_code = 0;
+static short code = 0;
+static short suffix_char = 0;
+static short final_char = 0;
+static short bytes_unread = 0;
+static unsigned char code_buffer[64] = {0};
+static struct code_entry code_table[4096] = {0};
+static short mask[12] =
+ {0x001, 0x003, 0x007, 0x00F,
+ 0x01F, 0x03F, 0x07F, 0x0FF,
+ 0x1FF, 0x3FF, 0x7FF, 0xFFF};
+static unsigned int endofdata = 0;
+
+#if TIANO
+unsigned long dofirst( unsigned char * filemem, unsigned long filememlen )
+#else
+unsigned long far _loadds dofirst( )
+#endif
+{
+
+#if TIANO
+ pbuf = filemem;
+ lenbuf = filememlen;
+#endif
+ pcurbuf = pbuf;
+ unreadbuf = lenbuf;
+ if (!ReadScreenDesc())
+ {
+ /* Invalid GIF dataset */
+#if DEBUG
+ printf("\nnot a GIF file - 1\n");
+#endif
+ return 0xffffffffL;
+ }
+#if DEBUG
+ printf("\nscreen width = %d, screen height = %d\n", BackdropWidth, BackdropHeight);
+ printf("# of colors = %d out of %ld\n", DefaultNumColors, (long)(1L << (3*ColorRez)));
+ printf("fill color index = %d\n", FillColor);
+#endif
+
+ SetPalette( GlobalColorMap, DefaultNumColors );
+ GlobalColorMapActive = TRUE;
+
+#if TIANO
+ LeftMargin = 0;
+ TopMargin = 0;
+ screen_width = BackdropWidth;
+ screen_height = BackdropHeight;
+ firstframeadd = (unsigned long)pcurbuf;//EIP:53740 Storing the first frame address and unread buffer length of the first frame to a static global variable
+ return (BackdropWidth << 16) | BackdropHeight;
+#else
+ LeftMargin = ( screen_width - BackdropWidth ) / 2;
+ TopMargin = ( screen_height - BackdropHeight ) / 2;
+#if DEBUG
+ printf("LeftMargin = %d, TopMargin = %d\n", LeftMargin, TopMargin);
+#endif
+ if (FillColor > 0)
+ {
+ /* Set the default color palette. Flood the backdrop region with
+ the FillColor. */
+ setbank( 0 );
+ Width = BackdropWidth;
+ Height = BackdropHeight;
+ LeftEdge = 0;
+ TopEdge = 0;
+ RightEdge = LeftEdge + Width - 1;
+ BottomEdge = TopEdge + Height - 1;
+ Interlaced = 0;
+#if DEBUG
+ printf("LeftEdge = %d, RightEdge = %d, Width = %d\n", LeftEdge, RightEdge, Width);
+ printf("TopEdge = %d, BottomEdge = %d, Height = %d\n", TopEdge, BottomEdge, Height);
+#endif
+ X = LeftEdge;
+ Y = TopEdge;
+ InterlacePass = 0;
+ {
+ PixelAdd = ( Y + TopMargin ) * (unsigned long)screen_width + ( X + LeftMargin );
+ if( CurrentBank != (PixelAdd >> 16) )
+ setbank((unsigned int)(PixelAdd >> 16));
+ }
+ for( ; Y <= BottomEdge ; Y++ )
+ for( ; X <= BottomEdge ; X++ )
+ writepixel( (unsigned char)FillColor );
+ }
+ return donext();
+#endif
+}
+
+#if TIANO
+unsigned long donext( unsigned char * BlitBuf )
+#else
+unsigned long far _loadds donext( )
+#endif
+{
+ unsigned int Done;
+ short Id; /* object identifier */
+ short Status; /* return status code */
+ unsigned long ret = 0;
+
+#if TIANO
+ blitbuf = BlitBuf;
+#endif
+ Done = FALSE;
+ /* Now display one or more GIF objects */
+ while(!Done)
+ {
+ switch (readbuf())
+ {
+ case ';':
+ /* End of the GIF dataset */
+ Done = TRUE;
+ break;
+
+ case ',':
+ /* Start of an image object.
+ Read the image description. */
+ if (!ReadImageDesc())
+ {
+ /* Invalid GIF dataset */
+#if DEBUG
+ printf("\nnot a GIF file - 2\n");
+#endif
+ ret = 0xffffffffL;
+ Done = TRUE;
+ break;
+ }
+ /* Setup the color palette for the image */
+ if (LocalNumColors > 0)
+ {
+ /* Change the palette table */
+ SetPalette( LocalColorMap, LocalNumColors );
+ GlobalColorMapActive = FALSE;
+ }
+ else if (DefaultNumColors > 0)
+ {
+ /* Reset the palette table back to the default setting */
+ if( !GlobalColorMapActive )
+ {
+ SetPalette( GlobalColorMap, DefaultNumColors );
+ GlobalColorMapActive = TRUE;
+ }
+ }
+
+ X = LeftEdge;
+ Y = TopEdge;
+ RightEdge = LeftEdge + Width - 1;
+ BottomEdge = TopEdge + Height - 1;
+
+ ///Need to update the image based on the current frame coordinates.
+ gGifSrcX = (UINT16)LeftEdge;
+ gGifSrcY = (UINT16)TopEdge;
+ if(Width) gGifDestX = (UINT16)Width-1;
+ if(Height) gGifDestY = (UINT16)Height-1;
+ GifImageFlag=1;
+
+#if DEBUG
+ printf("LeftEdge = %d, RightEdge = %d, Width = %d\n", LeftEdge, RightEdge, Width);
+ printf("TopEdge = %d, BottomEdge = %d, Height = %d\n", TopEdge, BottomEdge, Height);
+#endif
+ InterlacePass = 0;
+ {
+ PixelAdd = ( Y + TopMargin ) * (unsigned long)screen_width + ( X + LeftMargin );
+ if( CurrentBank != (PixelAdd >> 16) )
+ setbank((unsigned int)(PixelAdd >> 16));
+
+ }
+
+ Status = Expand_Data();
+
+ if (Status != 0)
+ {
+ /* Error expanding the raster image */
+#if DEBUG
+ printf("\nnot a GIF file - 3\n");
+#endif
+ ret = 0xffffffffL;
+ Done = TRUE;
+ break;
+ }
+ break;
+
+ case '!':
+ /* Start of an extended object (not in rev 87a) */
+ Id = readbuf(); /* Get the object identifier */
+ if (Id < 0)
+ {
+ /* Error reading object identifier */
+#if DEBUG
+ printf("\nnot a GIF file - 4\n");
+#endif
+ ret = 0xffffffffL;
+ Done = TRUE;
+ break;
+ }
+ switch ( Id )
+ {
+ case 0xF9:
+ ret = ReadGraphicControlExt();
+ if( ret != 0 )
+ {
+#if DEBUG
+ if (ret == 0xffffffffL)
+ printf("\nnot a GIF file - 9\n");
+#endif
+ Done = TRUE;
+ }
+ break;
+#if DEBUG
+ case 0xFE:
+ if (!ReadCommentExt())
+ {
+ printf("\nnot a GIF file - 6\n");
+ ret = 0xffffffffL;
+ Done = TRUE;
+ }
+ break;
+ case 0x01:
+ if (!ReadPlainTextExt())
+ {
+ printf("\nnot a GIF file - 7\n");
+ ret = 0xffffffffL;
+ Done = TRUE;
+ }
+ break;
+ case 0xFF:
+ if (!ReadApplicationExt())
+ {
+ printf("\nnot a GIF file - 8\n");
+ ret = 0xffffffffL;
+ Done = TRUE;
+ }
+ break;
+#endif
+ default:
+ /* Since there no extented objects defined in rev 87a, we
+ will just skip over them. In the future, we will handle
+ the extended object here. */
+ if (!SkipObject())
+ {
+#if DEBUG
+ printf("\nnot a GIF file - 5\n");
+#endif
+ ret = 0xffffffffL;
+ Done = TRUE;
+ }
+ break;
+ }
+ break;
+
+ default:
+ /* Error */
+#if DEBUG
+ printf("\nnot a GIF file - 10\n");
+#endif
+ ret = 0xffffffffL;
+ Done = TRUE;
+ break;
+ }
+ }
+#if DEBUG
+ printf("offset = %lx\n", lenbuf-unreadbuf);
+ printf("wait = %ld\n", ret);
+#endif
+ if( (ret > 0) && (ret < 100) )
+ ret = 100;
+ return ret;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: readbuf
+//
+// Description: Read the next byte from buffer
+//
+// Input: None
+//
+// Output: 0 .. 255 the byte
+// -1 end of file
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static int _inline readbuf( )
+{
+
+ if( unreadbuf == 0 )
+ return -1;
+
+ unreadbuf--;
+#if TIANO
+ return (((int)*pcurbuf++)&0xff);
+#else
+ return (int) *pcurbuf++;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: writepixel
+//
+// Description: Write a pixel at (X,Y) on the screen.
+//
+// Input: unsigned char Pixel
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static void _inline writepixel(unsigned char Pixel)
+{
+ unsigned char far * fp;
+ // Display the pixel on the screen
+ if( Pixel != TransparentColor )
+ {
+#if TIANO
+ fp = blitbuf + PixelAdd * 4;
+ *fp++ = pColorMap[Pixel].blue;
+ *fp++ = pColorMap[Pixel].green;
+ *fp++ = pColorMap[Pixel].red;
+ *fp++ = 0;
+#else
+ fp = _MK_FP( 0xa000, PixelAdd );
+ *fp = Pixel;
+#endif
+ }
+ // Advance the point
+ X++;
+ PixelAdd++;
+ if (X > RightEdge)
+ {
+ X = LeftEdge;
+
+ if (Interlaced)
+ {
+ Y += LineOffset[InterlacePass];
+ if (Y > BottomEdge)
+ {
+ InterlacePass++;
+ Y = TopEdge + BaseLine[InterlacePass];
+ }
+ }
+ else
+ Y++;
+ PixelAdd = ( Y + TopMargin ) * (unsigned long)screen_width + ( X + LeftMargin );
+ }
+ if( CurrentBank != (PixelAdd >> 16) )
+ setbank((unsigned int)(PixelAdd >> 16));
+}
+
+static void setbank(unsigned int bank)
+{
+ CurrentBank = bank;
+#if TIANO == 0
+ _asm
+ {
+ mov ax,4f05h
+ mov bx,0
+ mov dx,CurrentBank
+ int 10h
+ /*mov retvesa,ax*/
+ }
+
+ _asm
+ {
+ mov ax,4f05h
+ mov bx,1
+ mov dx,CurrentBank
+ int 10h
+ /*mov retvesa,ax*/
+ }
+
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadScreenDesc
+//
+// Description: Read the signature, the screen description, and the optional
+// default color map.
+//
+// Input: None
+//
+// Output: TRUE/FALSE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static short ReadScreenDesc( )
+{
+ unsigned char Buffer[16];
+
+ short
+ I, J,
+ Status,
+ HaveColorMap,
+ NumPlanes;
+
+ for (I = 0; I < 13; I++)
+ {
+ Status = readbuf();
+ if (Status < 0) return FALSE;
+ Buffer[I] = (unsigned char) Status;
+ }
+
+ for (I = 0; I < 6; I++)
+ if (Buffer[I] != GIF87signature[I])
+ break;
+ if (I >= 6)
+ GIFversion = GIF87;
+ else
+ {
+ for (I = 0; I < 6; I++)
+ if (Buffer[I] != GIF89signature[I])
+ break;
+ if (I >= 6)
+ GIFversion = GIF89;
+ else
+ return FALSE;
+ }
+
+ BackdropWidth = Buffer[6] | Buffer[7] << 8;
+ BackdropHeight = Buffer[8] | Buffer[9] << 8;
+ NumPlanes = (Buffer[10] & 0x07) + 1;
+ ColorRez = ((Buffer[10] & 0x70) >> 4) + 1;
+ HaveColorMap = (Buffer[10] & 0x80) != 0;
+ DefaultNumColors = 1 << NumPlanes;
+ FillColor = Buffer[11];
+
+ if (HaveColorMap)
+ {
+ for (I = 0; I < DefaultNumColors; I++)
+ {
+ for (J = 0; J < 3; J++)
+ {
+ Status = readbuf();
+ if (Status < 0) return FALSE;
+ Buffer[J] = (unsigned char) Status;
+ }
+
+ if (I < MaxColors)
+ {
+ GlobalColorMap[I].red = Buffer[0];
+ GlobalColorMap[I].green = Buffer[1];
+ GlobalColorMap[I].blue = Buffer[2];
+ }
+ }
+ }
+ else
+ DefaultNumColors = 0;
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadImageDesc
+//
+// Description: Read the image description and the optional color map.
+//
+// Input: None
+//
+// Output: TRUE/FALSE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static short ReadImageDesc( )
+{
+ unsigned char Buffer[16];
+
+ short
+ I, J,
+ NumPlanes,
+ HaveColorMap,
+ Status;
+
+ for (I = 0; I < 9; I++)
+ {
+ if ((Status = readbuf()) < 0) return FALSE;
+ Buffer[I] = (unsigned char) Status;
+ }
+
+ LeftEdge = Buffer[0] | Buffer[1] << 8;
+ TopEdge = Buffer[2] | Buffer[3] << 8;
+ Width = Buffer[4] | Buffer[5] << 8;
+ Height = Buffer[6] | Buffer[7] << 8;
+ NumPlanes = (Buffer[8] & 0x07) + 1;
+ LocalNumColors = 1 << NumPlanes;
+ Interlaced = (Buffer[8] & 0x40) != 0;
+ HaveColorMap = (Buffer[8] & 0x80) != 0;
+
+ if (HaveColorMap)
+ {
+ for (I = 0; I < LocalNumColors; I++)
+ {
+ for (J = 0; J < 3; J++)
+ {
+ if ((Status = readbuf()) < 0) return FALSE;
+ Buffer[J] = (unsigned char) Status;
+ }
+
+ if (I < MaxColors)
+ {
+ LocalColorMap[I].red = Buffer[0];
+ LocalColorMap[I].green = Buffer[1];
+ LocalColorMap[I].blue = Buffer[2];
+ }
+ }
+ }
+ else
+ LocalNumColors = 0;
+
+ return TRUE;
+}
+
+static unsigned long ReadGraphicControlExt()
+{
+ unsigned char Buffer[6];
+ short I;
+ short Status;
+ short HaveTransparentColor;
+ unsigned long timewait;
+
+#if DEBUG
+ printf("Graphic Control Extension : ");
+#endif
+ for (I = 0; I < 6; I++)
+ {
+ if ((Status = readbuf()) < 0) return 0xffffffffL;
+ Buffer[I] = (unsigned char) Status;
+ }
+ timewait = (Buffer[2] | Buffer[3] << 8)*10;
+ HaveTransparentColor = (Buffer[1] & 0x01) != 0;
+ if (HaveTransparentColor)
+ TransparentColor = Buffer[4];
+#if DEBUG
+ printf("%ld\n", timewait);
+#endif
+ return timewait;
+}
+
+#if DEBUG
+static short ReadCommentExt()
+{
+ short Count;
+ short c;
+
+ printf("Comment Extension : ");
+ while ((Count = readbuf()) > 0)
+ {
+ printf("\n#");
+ do
+ {
+ if ((c = readbuf()) < 0)
+ return FALSE;
+ printf("%c", c);
+ }while (--Count > 0);
+ printf("#");
+ }
+ if (Count < 0)
+ return FALSE;
+ printf("\n");
+ return TRUE;
+}
+
+static short ReadPlainTextExt()
+{
+ unsigned char Buffer[13];
+ short I;
+ short Status;
+ short Count;
+ short c;
+
+ printf("Plain Text Extension : ");
+ for (I = 0; I < 13; I++)
+ {
+ if ((Status = readbuf()) < 0) return FALSE;
+ Buffer[I] = (unsigned char) Status;
+ }
+ while ((Count = readbuf()) > 0)
+ {
+ printf("\n#");
+ do
+ {
+ if ((c = readbuf()) < 0)
+ return FALSE;
+ printf("%c", c);
+ }while (--Count > 0);
+ printf("#");
+ }
+ if (Count < 0)
+ return FALSE;
+ printf("\n");
+ return TRUE;
+}
+
+static short ReadApplicationExt()
+{
+ unsigned char Buffer[13];
+ short I;
+ short Status;
+ short Count;
+ short c;
+
+ printf("Application Extension : ");
+ for (I = 0; I < 12; I++)
+ {
+ if ((Status = readbuf()) < 0) return FALSE;
+ Buffer[I] = (unsigned char) Status;
+ }
+ for (I = 1; I < 9; I++)
+ printf("%c", Buffer[I]);
+ printf(" ");
+ for (I = 9; I < 12; I++)
+ printf("%c", Buffer[I]);
+ while ((Count = readbuf()) > 0)
+ {
+ printf("\n%2.2X", Count);
+ do
+ {
+ if ((c = readbuf()) < 0)
+ return FALSE;
+ printf("%2.2X", c);
+ }while (--Count > 0);
+ }
+ if (Count < 0)
+ return FALSE;
+ printf("\n");
+ return TRUE;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SkipObject
+//
+// Description: Skip over an extended GIF object.
+//
+// Input: None
+//
+// Output: TRUE/FALSE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static short SkipObject()
+{
+ short Count;
+
+ while ((Count = readbuf()) > 0)
+ do
+ {
+ if (readbuf() < 0)
+ return FALSE;
+ }while (--Count > 0);
+ if (Count < 0)
+ return FALSE;
+ return TRUE;
+}
+
+void SetPalette( struct ColorEntry ColorMap[], unsigned int num_colors )
+{
+#if TIANO
+ pColorMap = ColorMap;
+ num_colors;
+ return;
+#else
+ int i;
+ int bitofcolor;
+ int retvesa;
+ unsigned int segval, offval;
+ unsigned char far * fp;
+
+ _asm
+ {
+ mov ax,4f08h
+ mov bx,0001h
+ int 10h
+ mov retvesa,ax
+ mov bitofcolor,bx
+ }
+ if(retvesa != 0x004f)
+ bitofcolor = 8;
+ else
+ bitofcolor >>= 8;
+ if( 8 != bitofcolor )
+ {
+ if( 8 > bitofcolor )
+ for (i = 0; i < num_colors; i++)
+ {
+ ColorMap[i].red >>= (8 - bitofcolor);
+ ColorMap[i].green >>= (8 - bitofcolor);
+ ColorMap[i].blue >>= (8 - bitofcolor);
+ }
+ else
+ for (i = 0; i < num_colors; i++)
+ {
+ ColorMap[i].red <<= (bitofcolor - 8);
+ ColorMap[i].green <<= (bitofcolor - 8);
+ ColorMap[i].blue <<= (bitofcolor - 8);
+ }
+ }
+ fp = (unsigned char far *)ColorMap;
+ segval = _FP_SEG( fp );
+ offval = _FP_OFF( fp );
+ _asm
+ {
+ push di
+ mov ax,4f09h
+ mov bl,0
+ mov cx,num_colors
+ mov dx,0
+ mov di,segval
+ mov es,di
+ mov di,offval
+ int 10h
+ mov retvesa,ax
+ pop di
+ }
+
+#endif
+}
+
+// Expander
+#if TIANO
+static int _inline init_table(short min_code_size)
+#else
+static int _inline init_table(min_code_size)
+ short min_code_size;
+#endif
+ {
+ code_size = min_code_size + 1;
+ clear_code = 1 << min_code_size;
+ eof_code = clear_code + 1;
+ first_free = clear_code + 2;
+ free_code = first_free;
+ max_code = 1 << code_size;
+ return 0; //WARN FIX
+ }
+
+static int _inline read_code()
+ {
+ short bytes_to_move, i, ch;
+ long temp;
+
+ byte_offset = bit_offset >> 3;
+ bits_left = bit_offset & 7;
+
+ if (byte_offset >= 61)
+ {
+ bytes_to_move = 64 - byte_offset;
+
+ for (i = 0; i < bytes_to_move; i++)
+ code_buffer[i] = code_buffer[byte_offset + i];
+
+ while (i < 64)
+ {
+ if (bytes_unread == 0)
+ {
+ /* Get the length of the next record. A zero-length record
+ * denotes "end of data".
+ */
+ if( endofdata )
+ break;
+
+ if( unreadbuf > 0 )
+ {
+ bytes_unread = *pcurbuf++;
+ unreadbuf--;
+ }
+ else
+ {
+ UnexpectedError = TRUE;
+ return -1;
+ }
+
+ if (bytes_unread == 0) /* end of data */
+ {
+ endofdata = TRUE;
+ break;
+ }
+ }
+
+ if( unreadbuf > 0 )
+ {
+ ch = *pcurbuf++;
+ unreadbuf--;
+ }
+ else
+ {
+ UnexpectedError = TRUE;
+ return -1;
+ }
+
+#if TIANO
+ code_buffer[i++] = (char)ch;
+#else
+ code_buffer[i++] = ch;
+#endif
+ bytes_unread--;
+ }
+
+ bit_offset = bits_left;
+ byte_offset = 0;
+ }
+
+ bit_offset += code_size;
+ temp = (long) code_buffer[byte_offset]
+ | (long) code_buffer[byte_offset + 1] << 8
+ | (long) code_buffer[byte_offset + 2] << 16;
+
+ if (bits_left > 0)
+ temp >>= bits_left;
+
+ return temp & mask[code_size - 1];
+ }
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Expand_Data
+//
+// Description: Decompress a LZW compressed data stream.
+//
+// Input: None
+//
+// Output: 0 OK
+// -1 expected end-of-file
+// -2 cannot allocate memory
+// -3 bad "min_code_size"
+// < -3 error status from the get_byte or put_byte routine
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static short Expand_Data( )
+{
+#if TIANO == 0
+ short i;
+#endif
+ short sp; /* stack ptr */
+#if TIANO == 0
+ short status;
+#endif
+ short min_code_size;
+
+ /* Get the minimum code size (2 to 9) */
+
+ if( unreadbuf > 0 )
+ {
+ min_code_size = *pcurbuf++;
+ unreadbuf--;
+ }
+ else
+ return -4;
+
+ if (min_code_size < 2 || min_code_size > 9)
+ return -3;
+
+ init_table(min_code_size);
+ sp = 0;
+ bit_offset = 64*8; /* force "read_code" to start a new */
+ bytes_unread = 0; /* record */
+ endofdata = FALSE;
+
+ while ((code = read_code()) != eof_code)
+ {
+ if( UnexpectedError )
+ return -4;
+ if (code == clear_code)
+ {
+ init_table(min_code_size);
+ code = read_code();
+ if( UnexpectedError )
+ return -4;
+ old_code = code;
+ suffix_char = code;
+ final_char = code;
+ //(*put_byte)(suffix_char);
+ writepixel((unsigned char)suffix_char);
+ }
+ else
+ {
+ input_code = code;
+
+ if (code >= free_code)
+ {
+ code = old_code;
+#if TIANO
+ code_table[sp++].stack = (char)final_char;
+#else
+ code_table[sp++].stack = final_char;
+#endif
+ }
+
+ while (code >= first_free)
+ {
+ code_table[sp++].stack = code_table[code].suffix;
+ code = code_table[code].prefix;
+ }
+
+ final_char = code;
+ suffix_char = code;
+#if TIANO
+ code_table[sp++].stack = (char)final_char;
+#else
+ code_table[sp++].stack = final_char;
+#endif
+
+ while (sp > 0)
+ //(*put_byte)(code_table[--sp].stack);
+ writepixel((unsigned char)code_table[--sp].stack);
+
+#if TIANO
+ code_table[free_code].suffix = (char)suffix_char;
+#else
+ code_table[free_code].suffix = suffix_char;
+#endif
+ code_table[free_code].prefix = old_code;
+ free_code++;
+ old_code = input_code;
+
+ if (free_code >= max_code)
+ if (code_size < 12)
+ {
+ code_size++;
+ max_code <<= 1;
+ }
+ }
+ }
+
+ return 0;
+ }
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************