#include #include #include #include #include #include #include #include #include #include #include #include "gif_lib.h" #define ARCHIVO_Abrir 10 #define ARCHIVO_Cerrar 11 #define MEMORIA 50 #define DECODING 60 #define TAMANYO 70 #define DESCRIPCION 80 #define OK 00 typedef unsigned char DacPalette256[256][3]; void setvgapalette256(DacPalette256 *PalBuf); extern int far _Cdecl Svga256_fdriver[]; int huge DetectVGA256(){ return 2; } int MuestraGif( char *file, int PosX, int PosY ); extern unsigned int _stklen = 16384; /* Increase default stack size. */ /****************************************************************************** * Interpret the command line and scan the given GIF file. * ******************************************************************************/ void main(int argc, char **argv) { /* Make some variables global, so we could access them faster: */ int GraphDriver, GraphMode; char Str[80]; struct text_info TextInfo; /* So we can restore starting text mode. */ installuserdriver("Svga256",DetectVGA256); gettextinfo(&TextInfo); /* Save current mode so we can recover. */ GraphDriver = DETECT; initgraph(&GraphDriver, &GraphMode, ""); MuestraGif( argv[1], 0, 0 ); while( !kbhit() ); closegraph(); textmode(TextInfo.currmode); } /**************************************************************************\ |* *| |* MuestraGif *| |* *| |* Descripcion: *| |* Dado el nombre del .GIF, y la posici¢n de inicio f¡sica *| |* decodifica y muestra est‚ en pantalla... *| |* *| |* Entradas: *| |* Nombre de Archivo, Posiciones iniciales X, Y *| |* Salidas: *| |* OK *| |* C¢digos de Errores *| |* *| \*************************************************************************/ #define MIN(x, y) ((x) < (y) ? (x) : (y)) int MuestraGif( char *file, int PosX, int PosY ) { // int k, sum; int i, j, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode, ColorMapSize; DacPalette256 Palette256; int RecX, // ImageNum = 0, // BackGround = 0, // ForeGround = 1, /* As close to white as possible. */ MaximumScreenHeight, // DeviceMaxX = 640, DeviceMaxY = 400, /* Physical device dimensions. */ // ScreenWidth = 320, ScreenHeight = 200, /* Gif image screen size. */ InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */ InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */ GifColorType *ColorMap; GifRecordType RecordType; GifByteType *Extension; GifRowType *ScreenBuffer; GifFileType *GifFile; if ((GifFile = DGifOpenFileName( file )) == NULL) { return ARCHIVO_Abrir; } if ((ScreenBuffer = (GifRowType *) malloc( sizeof(GifRowType *))) == NULL) return MEMORIA; Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes of one row.*/ if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */ { free( ScreenBuffer ); return MEMORIA; } for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */ ScreenBuffer[0][i] = GifFile -> SBackGroundColor; MaximumScreenHeight = GifFile -> SHeight - 1; /* Scan the content of the GIF file and load the image(s) in: */ do { for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */ ScreenBuffer[0][i] = GifFile -> SBackGroundColor; if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) break; switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(GifFile) == GIF_ERROR) return DESCRIPCION; Row = GifFile -> ITop; /* Image Position relative to Screen. */ Col = GifFile -> ILeft; Width = GifFile -> IWidth; Height = GifFile -> IHeight; if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth || GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) { free( ScreenBuffer[0] ); free( ScreenBuffer ); return TAMANYO; } if (GifFile -> IInterlace) { /* Need to perform 4 passes on the images: */ for ( i = 0; i < 4; i++) for (j = Row + InterlacedOffset[i]; j < Row + Height; j += InterlacedJumps[i]) { if (DGifGetLine(GifFile, &ScreenBuffer[/*MIN(j, MaximumScreenHeight)*/0][Col], Width) == GIF_ERROR) { free( ScreenBuffer[0] ); free( ScreenBuffer ); return DECODING; } ///////////////////////////////////////////////// ///Procesa linea obtenida//////////////////////// ///////////////////////////////////////////////// for ( i = 0; i < Width; i ++ ) putpixel( RecX+PosX, j+PosY, ScreenBuffer[/*MIN(j, MaximumScreenHeight)*/0][RecX] ); ///////////////////////////////////////////////// ///////////////////////////////////////////////// } } else { for (i = 0; i < Height; i++, Row++) { if (DGifGetLine(GifFile, &ScreenBuffer[/*MIN(Row, MaximumScreenHeight)*/0][Col], Width) == GIF_ERROR) { MaximumScreenHeight = MIN(i - 1, MaximumScreenHeight); } ///////////////////////////////////////////////// ///Procesa linea obtenida//////////////////////// ///////////////////////////////////////////////// for ( RecX = 0; RecX < Width; RecX ++ ) putpixel( RecX+PosX, Row+PosY, ScreenBuffer[/*MIN(j, MaximumScreenHeight)*/0][RecX] ); ///////////////////////////////////////////////// ///////////////////////////////////////////////// } } break; case EXTENSION_RECORD_TYPE: /* Skip any extension blocks in file: */ if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) { free( ScreenBuffer[0] ); free( ScreenBuffer ); return DECODING; } while (Extension != NULL) { if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) { free( ScreenBuffer[0] ); free( ScreenBuffer ); return DECODING; } } break; case TERMINATE_RECORD_TYPE: break; default: /* Should be traps by DGifGetRecordType. */ break; } } while (RecordType != TERMINATE_RECORD_TYPE); /* Lets display it - set the global variables required and do it: */ ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap : GifFile -> SColorMap); ColorMapSize = 1 << (GifFile -> IColorMap ? GifFile -> IBitsPerPixel : GifFile -> SBitsPerPixel); /* Initialize hardware pallete and also select fore/background color. */ /* Sum = ((int) ColorMap[1].Red) + ((int) ColorMap[1].Green) + ((int) ColorMap[1].Blue); j = k = Sum; */ for (i = 0; i < ColorMapSize; i++) { Palette256[i][0] = ColorMap[i].Red >> 2; Palette256[i][1] = ColorMap[i].Green >> 2; Palette256[i][2] = ColorMap[i].Blue >> 2; /* Sum = ((int) ColorMap[i].Red) + ((int) ColorMap[i].Green) + ((int) ColorMap[i].Blue); if (i != 0 && Sum > j) // * Dont use color 0. * { ForeGround = i; j = Sum; } if (i != 0 && Sum <= k) // * Dont use color 0. * { BackGround = i; k = Sum; } */ } setvgapalette256( &Palette256 ); /* ScreenWidth = GifFile -> SWidth; ScreenHeight = MIN(GifFile -> SHeight, MaximumScreenHeight); */ if (DGifCloseFile(GifFile) == GIF_ERROR) { free( ScreenBuffer[0] ); free( ScreenBuffer ); // closegraph(); return ARCHIVO_Cerrar; } free( ScreenBuffer[0] ); free( ScreenBuffer ); return OK; } /* Setvgapalette256 sets the entire 256 color palette */ /* PalBuf contains RGB values for all 256 colors */ /* R,G,B values range from 0 to 63 */ /* Usage: */ /* DacPalette256 dac256; */ /* */ /* setvgapalette256(&dac256); */ void setvgapalette256(DacPalette256 *PalBuf) { struct REGPACK reg; reg.r_ax = 0x1012; reg.r_bx = 0; reg.r_cx = 256; reg.r_es = FP_SEG(PalBuf); reg.r_dx = FP_OFF(PalBuf); intr(0x10,®); }