static int ReadImageDesc (MG_RWops *area, IMAGEDESC* ImageDesc, GIFSCREEN* GifScreen)
{
    unsigned char buf[16];
    if (!ReadOK (area, buf, 9)) {
        _MG_PRINTF ("EX_CTRL>GIF89a: bad image size\n");
        return -1;
    }

    ImageDesc->Top = LM_to_uint (buf[0], buf[1]);
    ImageDesc->Left = LM_to_uint (buf[2], buf[3]);
    ImageDesc->Width = LM_to_uint (buf[4], buf[5]);
    ImageDesc->Height = LM_to_uint (buf[6], buf[7]);
    ImageDesc->haveColorMap = BitSet (buf[8], LOCALCOLORMAP);

    ImageDesc->bitPixel = 1 << ((buf[8] & 0x07) + 1);

    ImageDesc->interlace = BitSet(buf[8], INTERLACE);

    if (ImageDesc->haveColorMap) {
        _MG_PRINTF ("EX_CTRL>GIF89a: have local colormap\n");
        if (ReadColorMap (area, ImageDesc->bitPixel, ImageDesc->ColorMap) < 0) {
            _MG_PRINTF ("EX_CTRL>GIF89a: bad local colormap\n");
            return -1;
        }
    } else {
        memcpy (ImageDesc->ColorMap, GifScreen->ColorMap, MAXCOLORMAPSIZE*sizeof (RGB));
    }

    return 0;
}
static DFBResult GIFReadHeader( IDirectFBVideoProvider_GIF_data *data )
{
     DFBResult ret;
     u8        buf[7];
     
     ret = FetchData( data->buffer, buf, 6 );
     if (ret) {
          GIFERRORMSG("error reading header");
          return ret;
     }

     if (memcmp( buf, "GIF", 3 )) {
          GIFERRORMSG("bad magic");
          return DFB_UNSUPPORTED;
     }
     
     memcpy( data->Version, &buf[3], 3 );
     data->Version[3] = '\0';
     
     ret = FetchData( data->buffer, buf, 7 );
     if (ret) {
          GIFERRORMSG("error reading screen descriptor");
          return ret;
     }

     data->Width           = LM_to_uint( buf[0], buf[1] );
     data->Height          = LM_to_uint( buf[2], buf[3] );
     data->BitPixel        = 2 << (buf[4] & 0x07);
     data->ColorResolution = (((buf[4] & 0x70) >> 3) + 1);
     data->Background      = buf[5];
     data->AspectRatio     = buf[6];
     if (data->AspectRatio)
          data->AspectRatio = ((data->AspectRatio + 15) << 8) >> 6;
     else
static int DoExtension (MG_RWops *area, int label, GIFSCREEN* GifScreen)
{
    static unsigned char buf[256];

    switch (label) {
    case 0x01:                        /* Plain Text Extension */
        while (GetDataBlock (area, (unsigned char *) buf) != 0);
        break;
    case 0xff:                        /* Application Extension */
        while (GetDataBlock (area, (unsigned char *) buf) != 0);
        break;
    case 0xfe:                        /* Comment Extension */
        while (GetDataBlock (area, (unsigned char *) buf) != 0);
        return 0;
    case 0xf9:                        /* Graphic Control Extension */
        GetDataBlock (area, (unsigned char *) buf);
        GifScreen->disposal = (buf[0] >> 2) & 0x7;//000 000 0 0 the middle 2 bit is disposal
        GifScreen->inputFlag = (buf[0] >> 1) & 0x1;//000 000 0 0 the secand last bit 
                            //is user input flag
        GifScreen->delayTime = LM_to_uint(buf[1], buf[2]);
        if ((buf[0] & 0x1) != 0)// 000 000 0 0 the last bit is transparent flag
            GifScreen->transparent = buf[3];
        else
            GifScreen->transparent = -1;

        while (GetDataBlock (area, (unsigned char *) buf) != 0);
        return 0;
    default:
        while (GetDataBlock (area, (unsigned char *) buf) != 0);
        break;
    }

    return 0;
}
Exemplo n.º 4
0
/*--------------------------------------------------------------------------*/
static int DoExtension( gifdata* gd, int label )
{
	unsigned char buf[256];

	switch ( label )
	{
	  case 0x01:		/* Plain Text Extension */
		break;

	  case 0xff:		/* Application Extension */
		break;

	  case 0xfe:		/* Comment Extension */
		while ( GetDataBlock(gd,buf) != 0 )
			;
		return FALSE;

	  case 0xf9:		/* Graphic Control Extension */
		(void)GetDataBlock( gd, buf );
		gd->g89.disposal	= (buf[0] >> 2) & 0x7;
		gd->g89.inputFlag	= (buf[0] >> 1) & 0x1;
		gd->g89.delayTime	= LM_to_uint(buf[1],buf[2]);
		if ( (buf[0] & 0x1) != 0 )
			gd->g89.transparent = buf[3];

		while ( GetDataBlock(gd,buf) != 0 )
			;
		return FALSE;
	}

	while ( GetDataBlock(gd,buf) != 0 )
		;

	return FALSE;
}
static int ReadGIFGlobal (MG_RWops *area, GIFSCREEN* GifScreen)
{
    unsigned char buf[9];
    unsigned char version[4];

    if (!ReadOK (area, buf, 6))
        return -1;                /* not gif image*/

    if (strncmp((char *) buf, "GIF", 3) != 0)
        return -1;

    strncpy ((char*)version, (char *) buf + 3, 3);
    version [3] = '\0';

    if (strcmp ((const char*)version, "87a") != 0 && strcmp ((const char*)version, "89a") != 0) {
        _MG_PRINTF ("EX_CTRL>GIF89a: GIF version number not 87a or 89a.\n");
        return -1;                /* image loading error*/
    }

    GifScreen->Background = -1;
    GifScreen->transparent = -1;
    GifScreen->delayTime = -1;
    GifScreen->inputFlag = -1;
    GifScreen->disposal = 0;

    if (!ReadOK (area, buf, 7)) {
        _MG_PRINTF ("EX_CTRL>GIF89a: bad screen descriptor\n");
        return -1;                /* image loading error*/
    }
    GifScreen->Width = LM_to_uint (buf[0], buf[1]);
    GifScreen->Height = LM_to_uint (buf[2], buf[3]);
    GifScreen->BitPixel = 2 << (buf[4] & 0x07);
    GifScreen->ColorResolution = (((buf[4] & 0x70) >> 3) + 1);
    GifScreen->Background = buf[5];
    GifScreen->AspectRatio = buf[6];

    if (BitSet(buf[4], LOCALCOLORMAP)) {        /* Global Colormap */
        _MG_PRINTF ("EX_CTRL>GIF89a: have global colormap: %d\n", 
                    GifScreen->Background);
        if (ReadColorMap (area, GifScreen->BitPixel, GifScreen->ColorMap)) {
            _MG_PRINTF ("EX_CTRL>GIF89a: bad global colormap\n");
            return -1;                /* image loading error*/
        }
    }

    return 0;
}
static int DoExtension( IDirectFBVideoProvider_GIF_data *data, int label )
{
     unsigned char buf[256] = { 0 };
     char *str;

     switch (label) {
          case 0x01:              /* Plain Text Extension */
               str = "Plain Text Extension";
               break;
          case 0xff:              /* Application Extension */
               str = "Application Extension";
               break;
          case 0xfe:              /* Comment Extension */
               str = "Comment Extension";
               while (GetDataBlock( data->buffer, (u8*) buf ) != 0)
                    GIFDEBUGMSG("gif comment: %s", buf);
               return false;
          case 0xf9:              /* Graphic Control Extension */
               str = "Graphic Control Extension";
               (void) GetDataBlock( data->buffer, (u8*) buf );
               data->disposal  = (buf[0] >> 2) & 0x7;
               data->inputFlag = (buf[0] >> 1) & 0x1;
               if (LM_to_uint( buf[1], buf[2] ))
                    data->delayTime = LM_to_uint( buf[1], buf[2] ) * 10000;
               if ((buf[0] & 0x1) != 0)
                    data->transparent = buf[3];
               else
                    data->transparent = -1;
               while (GetDataBlock( data->buffer, (u8*) buf ) != 0)
                    ;
               return false;
          default:
               str = (char*) buf;
               snprintf(str, 256, "UNKNOWN (0x%02x)", label);
          break;
     }

     GIFDEBUGMSG("got a '%s' extension", str );

     while (GetDataBlock( data->buffer, (u8*) buf ) != 0);

     return 0;
}
Exemplo n.º 7
0
static int
DoExtension(SDL_RWops *src, int label)
{
    static unsigned char buf[256];
    char *str;

    switch (label) {
    case 0x01:          /* Plain Text Extension */
    str = "Plain Text Extension";
    break;
    case 0xff:          /* Application Extension */
    str = "Application Extension";
    break;
    case 0xfe:          /* Comment Extension */
    str = "Comment Extension";
    while (GetDataBlock(src, (unsigned char *) buf) != 0)
        ;
    return FALSE;
    case 0xf9:          /* Graphic Control Extension */
    str = "Graphic Control Extension";
    (void) GetDataBlock(src, (unsigned char *) buf);
    Gif89.disposal = (buf[0] >> 2) & 0x7;
    Gif89.inputFlag = (buf[0] >> 1) & 0x1;
    Gif89.delayTime = LM_to_uint(buf[1], buf[2]);
    if ((buf[0] & 0x1) != 0)
        Gif89.transparent = buf[3];

    while (GetDataBlock(src, (unsigned char *) buf) != 0)
        ;
    return FALSE;
    default:
    str = (char *)buf;
    SDL_snprintf(str, 256, "UNKNOWN (0x%02x)", label);
    break;
    }

    while (GetDataBlock(src, (unsigned char *) buf) != 0)
    ;

    return FALSE;
}
Exemplo n.º 8
0
static int
DoExtension(GifFrame* frame, SDL_RWops *src, int label)
{
    static unsigned char buf[256];
    char *str;

    switch (label) {
	    case 0x01:			/* Plain Text Extension */
			dbgout("Plain Text Extension\n");
			break;
		case 0xff:			/* Application Extension */
			dbgout("Application Extension\n");
			break;
	    case 0xfe:			/* Comment Extension */
			dbgout("Comment Extension\n");
			while (GetDataBlock(src, (unsigned char *) buf) != 0)
			    ;
			return FALSE;
	    case 0xf9:			/* Graphic Control Extension */
			dbgout("Graphic Control Extension\n");
			(void) GetDataBlock(src, (unsigned char *) buf);
			frame->disposal = (buf[0] >> 2) & 0x7;
			frame->inputFlag = (buf[0] >> 1) & 0x1;
			frame->delayMs = LM_to_uint(buf[1], buf[2]);
			if ((buf[0] & 0x1) != 0)
			    frame->transparent = buf[3];

			while (GetDataBlock(src, (unsigned char *) buf) != 0)
			    ;
			return FALSE;
	    default:
			dbgout("Unknown Extension: %s (0x%02x)\n", (char*)buf, label);
			break;
    }

    while (GetDataBlock(src, (unsigned char *) buf) != 0)
	;

    return FALSE;
}
Exemplo n.º 9
0
Image *
IMG_LoadGIF_RW(SDL_RWops *src)
{
    Sint64 start;
    unsigned char buf[16];
    unsigned char c;
    unsigned char localColorMap[3][MAXCOLORMAPSIZE];
    int grayScale;
    int useGlobalColormap;
    int bitPixel;
    int imageCount = 0;
    char version[4];
    int imageNumber = 1;
    Image *image = NULL;

    if ( src == NULL ) {
    return NULL;
    }
    start = SDL_RWtell(src);

    if (!ReadOK(src, buf, 6)) {
    RWSetMsg("error reading magic number");
        goto done;
    }
    if (SDL_strncmp((char *) buf, "GIF", 3) != 0) {
    RWSetMsg("not a GIF file");
        goto done;
    }
    SDL_memcpy(version, (char *) buf + 3, 3);
    version[3] = '\0';

    if ((SDL_strcmp(version, "87a") != 0) && (SDL_strcmp(version, "89a") != 0)) {
    RWSetMsg("bad version number, not '87a' or '89a'");
        goto done;
    }
    Gif89.transparent = -1;
    Gif89.delayTime = -1;
    Gif89.inputFlag = -1;
    Gif89.disposal = 0;

    if (!ReadOK(src, buf, 7)) {
    RWSetMsg("failed to read screen descriptor");
        goto done;
    }
    GifScreen.Width = LM_to_uint(buf[0], buf[1]);
    GifScreen.Height = LM_to_uint(buf[2], buf[3]);
    GifScreen.BitPixel = 2 << (buf[4] & 0x07);
    GifScreen.ColorResolution = (((buf[4] & 0x70) >> 3) + 1);
    GifScreen.Background = buf[5];
    GifScreen.AspectRatio = buf[6];

    if (BitSet(buf[4], LOCALCOLORMAP)) {    /* Global Colormap */
    if (ReadColorMap(src, GifScreen.BitPixel, GifScreen.ColorMap,
             &GifScreen.GrayScale)) {
        RWSetMsg("error reading global colormap");
            goto done;
    }
    }
    do {
    if (!ReadOK(src, &c, 1)) {
        RWSetMsg("EOF / read error on image data");
            goto done;
    }
    if (c == ';') {     /* GIF terminator */
        if (imageCount < imageNumber) {
        RWSetMsg("only %d image%s found in file",
             imageCount, imageCount > 1 ? "s" : "");
                goto done;
        }
    }
    if (c == '!') {     /* Extension */
        if (!ReadOK(src, &c, 1)) {
        RWSetMsg("EOF / read error on extention function code");
                goto done;
        }
        DoExtension(src, c);
        continue;
    }
    if (c != ',') {     /* Not a valid start character */
        continue;
    }
    ++imageCount;

    if (!ReadOK(src, buf, 9)) {
        RWSetMsg("couldn't read left/top/width/height");
            goto done;
    }
    useGlobalColormap = !BitSet(buf[8], LOCALCOLORMAP);

    bitPixel = 1 << ((buf[8] & 0x07) + 1);

    if (!useGlobalColormap) {
        if (ReadColorMap(src, bitPixel, localColorMap, &grayScale)) {
        RWSetMsg("error reading local colormap");
                goto done;
        }
        image = ReadImage(src, LM_to_uint(buf[4], buf[5]),
                  LM_to_uint(buf[6], buf[7]),
                  bitPixel, localColorMap, grayScale,
                  BitSet(buf[8], INTERLACE),
                  imageCount != imageNumber);
    } else {
        image = ReadImage(src, LM_to_uint(buf[4], buf[5]),
                  LM_to_uint(buf[6], buf[7]),
                  GifScreen.BitPixel, GifScreen.ColorMap,
                  GifScreen.GrayScale, BitSet(buf[8], INTERLACE),
                  imageCount != imageNumber);
    }
    } while (image == NULL);

#ifdef USED_BY_SDL
    if ( Gif89.transparent >= 0 ) {
        SDL_SetColorKey(image, SDL_TRUE, Gif89.transparent);
    }
#endif

done:
    if ( image == NULL ) {
        SDL_RWseek(src, start, RW_SEEK_SET);
    }
    return image;
}
Exemplo n.º 10
0
void ReadGIFInfo(FILE *fd,int *width,int *height)
{
    unsigned char buf[16];
	unsigned char c;
	char version[4];
	char *str;
	
	if (!ReadOK(fd,buf,6)){
	    strcpy(str,"error reading magic number");
	    pm_error(str);
	}
	
	if (strncmp((char*)buf,"GIF",3) != 0){
	    strcpy(str,"not a GIF file");
	    pm_error(str);
	}
	
	strncpy(version,(char*)buf+3,3);
	version[3] = '\0';
	
	if ((strcmp(version,"87a") != 0) && (strcmp(version,"89a") != 0)){
	    strcpy(str,"bad version number, not '87a' or '89a'");
	    pm_error(str);
	}
	
	/*read logical screen*/
	if (!ReadOK(fd,buf,7)){
	    strcpy(str,"failed to read screen descriptor");
	    pm_error(str);
	}
	
	GifScreen.Width 	  = LM_to_uint(buf[0],buf[1]);
	GifScreen.Height	  = LM_to_uint(buf[2],buf[3]);
	GifScreen.BitPixel	  = 2<<(buf[4]&0x07);
	GifScreen.ColorResolution = (((buf[4]&0x70)>>3)+1);
	GifScreen.Background	 = buf[5];
	GifScreen.AspectRatio	 = buf[6];	
	
	if (BitSet(buf[4],LOCALCOLORMAP)){
	    if (ReadColorMap(fd,GifScreen.BitPixel,GifScreen.ColorMap)){
		    strcpy(str,"error reading global color map");
		    pm_error(str);
		}
	}
	
	if (!ReadOK(fd,&c,1)){
	    strcpy(str,"EOF / read error on image data");
	    pm_error(str);
	}
	
	if (c == ';'){/*0x3B, GIF terminator*/
	    return;
	}
	
	if (c == '!'){/*0x21, Extension*/
	    if (!ReadOK(fd,&c,1)){
		    strcpy(str,"OF / read error on extension function code");
		    pm_error(str);
		}
		DoExtension(fd,c);
	}
	
	if (!ReadOK(fd,buf,8)){
	    strcpy(str,"couldn't read left/top/width/height");
	    pm_error(str);
	}
	
	*width = LM_to_uint(buf[4],buf[5]);
	*height = LM_to_uint(buf[6],buf[7]);
	
	return;
}
Exemplo n.º 11
0
/* TODO: (Chase) dump frames into frameset instead of combining into one frame */
int IMG_LoadGIF_RW(SDL_RWops *src, IMG_File* dst)
{
    int start;
    unsigned char buf[16];
    unsigned char c;
    unsigned char localColorMap[3][MAXCOLORMAPSIZE];
    int grayScale;
    int useGlobalColormap;
    int bitPixel;
    int imageCount = 0;
    char version[4];
    int imageNumber = 1; /*<-- I believe this is what we want to control in order to change what frame to grab*/
    int successCount = 0;
	int w = 0;
	int i = 0;
	Uint32 color = 0; 
	SDL_Surface*image = NULL;
	SDL_Surface*nextImage = NULL;
	GifFrame frame;
	GifFrame* frames;
	
    if ( src == NULL ) {
		return 0;
    }
    start = SDL_RWtell(src);

    if (!ReadOK(src, buf, 6)) {
		IMG_SetError("error reading magic number");
        goto done;
    }
    if (strncmp((char *) buf, "GIF", 3) != 0) {
		IMG_SetError("not a GIF file");
        goto done;
    }
    strncpy(version, (char *) buf + 3, 3);
    version[3] = '\0';

    if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) {
		IMG_SetError("bad version number, not '87a' or '89a'");
        goto done;
    }
    frame.transparent = -1;
    frame.delayMs = -1;
    frame.inputFlag = -1;
    frame.disposal = 0;

    if (!ReadOK(src, buf, 7)) {
		IMG_SetError("failed to read screen descriptor");
        goto done;
    }
    GifScreen.Width = LM_to_uint(buf[0], buf[1]);
    GifScreen.Height = LM_to_uint(buf[2], buf[3]);
    GifScreen.BitPixel = 2 << (buf[4] & 0x07);
    GifScreen.ColorResolution = (((buf[4] & 0x70) >> 3) + 1);
    GifScreen.Background = buf[5];
    GifScreen.AspectRatio = buf[6];

    if (BitSet(buf[4], LOCALCOLORMAP)) {	/* Global Colormap */
		if (ReadColorMap(src, GifScreen.BitPixel, GifScreen.ColorMap,
			&GifScreen.GrayScale)) {
			IMG_SetError("error reading global colormap");
	        goto done;
		}
    }
	    
    dbgout("GLOBAL BG COLOR: Index:%i RGB:%i,%i,%i\n", GifScreen.Background,
			GifScreen.ColorMap[CM_RED][GifScreen.Background],
			GifScreen.ColorMap[CM_GREEN][GifScreen.Background], 
			GifScreen.ColorMap[CM_BLUE][GifScreen.Background]);
	
	
	frames = (GifFrame*)malloc(sizeof(GifFrame));
	if (!frames) {
		IMG_SetError("Malloc Failed");
		goto done;
	}
	
    do { /* This loop goes through and reads every image and sends its data to ReadImage, if its the one we want (index 1) it'll output SDL_Surface*/
		/*
			What this SHOULD do...
			METHOD 1 (Lazy):
				Read every image, output an SDL_Surface into a vector
				After loop, count vector images, make a new image which has a w equal to the vector.size() * image width
				Render each image from the vector onto the new image, each one with an x offset of image width * index
				Free all surfaces in the vector, return the new combined one.
			METHOD 2 (hardcore):
				Read every image, count the number of images we get.
				Create a surface with a w equal to count * width
				Go back and read every images data, writing their pixels, leftmost to images x * index
			GENERAL PROBLEM:
				We have no delay info. We'd have to manually set the frame delay... However, this isn't a problem. =3
			Looks like we can have local layer color maps.. of course being able to do this in imageready is a whole other issue.
				But as far as we know.. maybe?
		*/
		
		if (!ReadOK(src, &c, 1)) {
		    IMG_SetError("EOF / read error on image data");
	        goto done;
		} else
			dbgout("%c", c);
			
		if (c == ';') {		/* GIF terminator -0x3b */
		    /*if (imageCount < imageNumber) {
				IMG_SetError("only %d image%s found in file",
					imageCount, imageCount > 1 ? "s" : "");
	            goto done;
		    }*/
		    break;
		}
		if (c == '!') {		/* Extension 0x21 */
		    if (!ReadOK(src, &c, 1)) {
				IMG_SetError("EOF / read error on extention function code");
	            goto done;
		    }
		    DoExtension(&frame, src, c);
		    continue;
		}
		if (c != ',') {		/* Image seperator - 0x2c */
		    continue;
		}
		++imageCount;

		if (!ReadOK(src, buf, 9)) {
		    IMG_SetError("couldn't read left/top/width/height");
			goto done;
		}
/*
Offset   Length   Contents
  0      1 byte   Image Separator (0x2c)
  1      2 bytes  Image Left Position
  3      2 bytes  Image Top Position
  5      2 bytes  Image Width
  7      2 bytes  Image Height
  8      1 byte   bit 0:    Local Color Table Flag (LCTF)
                  bit 1:    Interlace Flag
                  bit 2:    Sort Flag
                  bit 2..3: Reserved
                  bit 4..7: Size of Local Color Table: 2^(1+n)
         ? bytes  Local Color Table(0..255 x 3 bytes) if LCTF is one
         1 byte   LZW Minimum Code Size
[ // Blocks
         1 byte   Block Size (s)
œSx    (s)bytes  Image Data
]*
         1 byte   Block Terminator(0x00)
*/

		useGlobalColormap = !BitSet(buf[8], LOCALCOLORMAP);

		frame.x = LM_to_uint(buf[0], buf[1]);
		frame.y = LM_to_uint(buf[2], buf[3]);
		
		dbgout("X:%i, Y:%i\n", frame.x, frame.y);

		bitPixel = 1 << ((buf[8] & 0x07) + 1);
		dbgout("Checkpoint\n");
		if (!useGlobalColormap) {
		    if (ReadColorMap(src, bitPixel, localColorMap, &grayScale)) {
				IMG_SetError("error reading local colormap");
	            goto done;
		    }
		    image = ReadImage(src, LM_to_uint(buf[4], buf[5]),
				      LM_to_uint(buf[6], buf[7]),
				      bitPixel, localColorMap, grayScale,
				      BitSet(buf[8], INTERLACE),
				      0);
			if (image) color = SDL_MapRGB(image->format,
										localColorMap[CM_RED][frame.transparent], 
										localColorMap[CM_GREEN][frame.transparent], 
										localColorMap[CM_BLUE][frame.transparent]);
		} else {
		    image = ReadImage(src, LM_to_uint(buf[4], buf[5]),
				      LM_to_uint(buf[6], buf[7]),
				      GifScreen.BitPixel, GifScreen.ColorMap,
				      GifScreen.GrayScale, BitSet(buf[8], INTERLACE),
				      0); 
			if (image) color = SDL_MapRGB(image->format,
										GifScreen.ColorMap[CM_RED][frame.transparent], 
										GifScreen.ColorMap[CM_GREEN][frame.transparent], 
										GifScreen.ColorMap[CM_BLUE][frame.transparent]);
		}
		dbgout("Image: %p\n", image);
		if (image) {
			++successCount;
			/*image = convertTo32bit(image); */ /* transform to a 32 bit surface because I HATE palettes*/
			dbgout("Converted Image: %ix%i [%p]\n", image->w, image->h, image);
			if (image) {
			    if ( frame.transparent >= 0 ) {
			        SDL_SetColorKey(image, SDL_SRCCOLORKEY, frame.transparent);
			    }
			    /*if ( frame.transparent >= 0 ) {
			        SDL_SetColorKey(image, SDL_SRCCOLORKEY, color);
			        Uint8 r, g, b;
					SDL_GetRGB(color, image->format, &r, &g, &b);
					dbgout("Local Transparency: %i,%i,%i\n", r, g, b);
			    }*/
				/*Reallocate room for another image in the list*/
				frames = (GifFrame*)realloc(frames, successCount * sizeof(GifFrame));
				if (!frames) { /*realloc failed*/
					IMG_SetError("Realloc Failed");
			        goto done;
				}
				frame.surf = image;
				/* Copy the current state of the GifFrame before the next read loop */
				frames[successCount-1] = frame;
				/*int i = 0;
				while (i < successCount) {
					dbgout("Frames[%i]: %p\n", i, frames[i]);	
					i++;
				}*/
				
				image = NULL;
			}
		}
		
    } while (1); /*let the above ... goto's... handle it*/
    
    SDL_Frame* framesArray;
	if (successCount > 0) 
	{
		dbgout("Mallocing Frames %i\n", successCount);fflush(stdout);
		
		framesArray = IMG_MallocFrames(successCount);

		i = 0;
		
		//first frame
		image = SDL_CreateRGBSurface(SDL_SWSURFACE, GifScreen.Width, 
										GifScreen.Height, 
										32, RMASK, GMASK, BMASK, 0);
				
		color = SDL_MapRGB(image->format,
							GifScreen.ColorMap[CM_RED][frames[0].transparent], 
							GifScreen.ColorMap[CM_GREEN][frames[0].transparent], 
							GifScreen.ColorMap[CM_BLUE][frames[0].transparent]);
		Uint8 r, g, b;
		SDL_GetRGB(color, image->format, &r, &g, &b);
		dbgout("Final Transparency: %i,%i,%i\n", r, g, b);fflush(stdout);
		if (color != 0) /* Ignore 0,0,0 as the transparent color */
		{ 
			SDL_FillRect(image, NULL, color);
			SDL_SetColorKey(image, SDL_SRCCOLORKEY, color); /* use the first frames trans color */
		}

		while (i < successCount) /* render our surfs and clear */
		{
			if (image)
			{
				dbgout("Dimensions: %ix%i: %p\n", image->w, image->h, image);fflush(stdout);

				w = 0;

				SDL_Rect r2, r3; 
				
				dbgout("Adding Frames[%i]: %p Disposal:%i TransIndex: %i Delay: %i Input:%i\n", i, 
						frames[i].surf, frames[i].disposal, frames[i].transparent, frames[i].delayMs,
						frames[i].inputFlag);	fflush(stdout);
						
				/* Print out the overlay at its offset coordinates */
				r2.x = frames[i].x;
				r2.y = frames[i].y; 
				r2.w = frames[i].surf->w;
				r2.h = frames[i].surf->h;
				
				dbgout("Drawing at: %i,%i\n", r2.x, r2.y);fflush(stdout);
				if (SDL_BlitSurface(frames[i].surf, NULL, image, &r2)) 
				{
					/*something bad happened but ignore it for now. */
					dbgout("Drawing Failed: %s\n", IMG_GetError());fflush(stdout);
				}
				dbgout("Setting Crap\n");fflush(stdout);
				//add image to our frames list
				framesArray[i].surf = image;
				framesArray[i].delay = frames[i].delayMs * 10; //HACK: All observed gifs have a delay of say.. 7, which means 70ms.
				framesArray[i].key = NULL;
				
				dbgout("i+1 crap\n");fflush(stdout);
				/*what to do in frame[i+1] before rendering*/
				if (i + 1 < successCount)
				{
					//create next frame so we can do something to it
					nextImage = SDL_CreateRGBSurface(SDL_SWSURFACE, GifScreen.Width, 
										GifScreen.Height, 
										32, RMASK, GMASK, BMASK, 0);
									
					color = SDL_MapRGB(nextImage->format,
										GifScreen.ColorMap[CM_RED][frames[0].transparent], 
										GifScreen.ColorMap[CM_GREEN][frames[0].transparent], 
										GifScreen.ColorMap[CM_BLUE][frames[0].transparent]);
					Uint8 r, g, b;
					SDL_GetRGB(color, nextImage->format, &r, &g, &b);
					dbgout("Final Transparency: %i,%i,%i\n", r, g, b);fflush(stdout);
					if (color != 0) /* Ignore 0,0,0 as the transparent color */
					{ 
						SDL_FillRect(nextImage, NULL, color);
						SDL_SetColorKey(nextImage, SDL_SRCCOLORKEY, color); /* use the first frames trans color */
					}
				
					dbgout("Disposal crap\n");fflush(stdout);
					switch (frames[i].disposal)
					{
						case DISPOSAL_PREVIOUSFRAME: /* 04h - Overwrite graphic with previous graphic */
							dbgout("Doing previous frame\n");fflush(stdout);
							r2.x = 0;
							r2.y = 0;
							r2.w = GifScreen.Width;
							r2.h = GifScreen.Height;
							SDL_BlitSurface(frames[0].surf, NULL, nextImage, &r2); //Since I'm lazy, and haven't seen many gifs use this, it'll just render the original frame
							break;
						case DISPOSAL_UNSPECIFIED: /* DISPOSAL_UNSPECIFIED 00h - Let the viewer decide */
							/*Drop down to donotdispose */
						case DISPOSAL_DONOTDISPOSE: /* 01h - Leave graphic there */
							dbgout("Doing nondispose\n");fflush(stdout);
							/*render a copy of the previous i-1 into i */
							
							r2.w = GifScreen.Width;
							r2.h = GifScreen.Height;
							r2.x = 0;
							r2.y = 0;
							/* r3 = src, r2 = dst */
							r3.w = GifScreen.Width;
							r3.h = GifScreen.Height;
							r3.x = 0;
							r3.y = 0;
							dbgout("r3:(%i,%i)%ix%i r2:(%i,%i)%ix%i\n", r3.x, r3.y, r3.w, r3.h, 
																	  r2.x, r2.y, r2.w, r2.h);fflush(stdout);

							if (SDL_BlitSurface(image, &r3, nextImage, &r2)) {
								dbgout("Drawing Failed: %s\n", IMG_GetError());fflush(stdout);
							}
							break;	
						default: /* This'll default to DISPOSAL_BGCOLORWIPE 
									02h - Overwrite graphic with background color 
									do nothing, next rect is empty already*/
							dbgout("Doing default %i\n", frames[i].disposal);fflush(stdout);
							break;
					}
					image = nextImage;
				}
			}
			i++;
		}
		
		i = 0;
		while (i < successCount) {
			SDL_FreeSurface(frames[i].surf);
			i++;
		}
		free(frames);
		frames = NULL;
	} else {
		image = NULL;
	}
	
done:
	if (frames) { /* We didn't complete successfully, handle any leaks */
		i = 0;
		while (i < successCount) {
			SDL_FreeSurface(frames[i].surf);
			i++;
		}
		free(frames);
		/*if (image) {
			SDL_FreeSurface(image);
			image = NULL; 
		}*/
	}
	
	/*if ( image == NULL ) {
        SDL_RWseek(src, start, SEEK_SET);
    }   */
		
	if (successCount > 0)
	{
		dst->frames = framesArray;
		dst->count = successCount;
		dst->format = IMG_FORMAT_GIF;
		return 1;
	}
	return 0;
		
    //return IMG_SurfaceToFrameset(image, sdlFrames, sdlFrameCount);
}
Exemplo n.º 12
0
/*****
* Name: 		_PLC_GIF_Init
* Return Type: 	void
* Description: 	image initializer for GIF images
* In: 
*	plc:		current PLC 
* Returns:
*	Nothing but PLC is updated.
* Note:
*	As this routine must be fully re-entrant, it needs a lot of checks
*	to make sure we have the data we want fully available.
*	The drawback is that if we are being suspended while doing this
*	initialization, everything must be reset and repeated the next time
*	this routine is called.
*****/
void
_PLC_GIF_Init(PLC *plc)
{
	Byte buf[16], c;
	PLCImageGIF *gif;

	gif = &(plc->object->plc_gif_image);

	_XmHTMLDebug(15, ("plc.c: _PLC_GIF_Init for %s\n", plc->url));

	/* this plc is active */
	plc->plc_status = PLC_ACTIVE;

	/*****
	* When this routine is called, the init method of this PLC has already
	* been called to determine the type of this PLC Image object. Therefore
	* we already have data available and we need to rewind the input buffer
	* back to the beginning.
	*****/
	_PLCRewindInputBuffer(plc);

	/* we know this is a gif image, so skip magic */
	gif->info->type = IMAGE_GIF;
	(void)_PLCReadOK(plc, buf, 6);

	/* read logical screen descriptor */
	(void)_PLCReadOK(plc, buf, 7);

	/* image dimensions */
	gif->width   = LM_to_uint(buf[0],buf[1]);
	gif->height  = LM_to_uint(buf[2],buf[3]);

	/* set colorspace and allocate a colormap */
	gif->colorclass = XmIMAGE_COLORSPACE_INDEXED;
	gif->cmapsize   = 2<<(buf[4]&0x07);

	/*
	* We may have been called before (but returned 'cause not enough data
	* was available).
	*/
	if(gif->cmap == NULL)
		gif->cmap = (XCOLOR*)calloc(gif->cmapsize, sizeof(XCOLOR));

	/* image is initially fully opaque */
	gif->transparency = XmNONE;
	gif->bg_pixel = -1;

	/*
	* Incoming data buffer. This is *way* too much as the incoming data
	* will be compressed (but it does make sure there is enough room)
	*/
	gif->buf_size   = gif->width*gif->height;
	gif->buf_pos    = 0;	/* current pos in data received so far */
	gif->byte_count = 0;	/* size of data received so far */
	if(gif->buffer == NULL)
		gif->buffer = (Byte*)calloc(gif->buf_size + 1, sizeof(Byte));

	/* check if a global colormap is available */
	if(BitSet(buf[4], LOCALCOLORMAP))
	{
		if(!(ReadColormap(plc, gif)))
		{
			/* premature end of data. */
			if(plc->plc_data_status == STREAM_END)
			{
				_XmHTMLWarning(__WFUNC__(gif->owner, "_PLC_GIF_Init"),
					XMHTML_MSG_106, plc->url, "global");
				plc->plc_status = PLC_ABORT;
			}
			return;	/* no global colormap! */
		}
	}

	/* process all extensions */
	c = 0;
	while(c != ',')
	{
		if(!_PLCReadOK(plc, &c, 1))
			return;

		if (c == ';') /* GIF terminator */
		{
			_XmHTMLWarning(__WFUNC__(gif->owner, "_PLC_GIF_Init"),
				XMHTML_MSG_107, plc->url, "pixel data");
			plc->plc_status = PLC_ABORT;
			return;
		}

		if(c == '!') /* Extension */
		{
			if(!_PLCReadOK(plc,&c,1))
			{
				if(plc->plc_data_status == STREAM_END)
				{
					_XmHTMLWarning(__WFUNC__(gif->owner, "_PLC_GIF_Init"),
						XMHTML_MSG_107, plc->url, "extension block type");
					plc->plc_status = PLC_ABORT;
				}
				return;
			}
			if(!(DoExtension(plc, c)))
			{
				if(plc->plc_data_status == STREAM_END)
				{
					_XmHTMLWarning(__WFUNC__(gif->owner, "_PLC_GIF_Init"),
						XMHTML_MSG_107, plc->url, "extension block");
					plc->plc_status = PLC_ABORT;
				}
				return;
			}
			continue;
		}
		if (c != ',')
			continue; /* Not a valid start character */
	}
	/* get image descriptor */
	if(!_PLCReadOK(plc, buf, 9))
		return;

	/* see if we are to use a local colormap */
	if(BitSet(buf[8], LOCALCOLORMAP))
	{
		/* local colormap size */
		gif->ncolors = 1<<((buf[8]&0x07)+1);

		/* do we also have a glocal colormap? */
		if(gif->cmap)
			free(gif->cmap);

		gif->cmapsize = gif->ncolors;
		gif->cmap = (XCOLOR*)calloc(gif->cmapsize, sizeof(XCOLOR));

		if(!(ReadColormap(plc, gif)))
		{
			/* premature end of data. */
			if(plc->plc_data_status == STREAM_END)
			{
				_XmHTMLWarning(__WFUNC__(gif->owner, "_PLC_GIF_Init"),
					XMHTML_MSG_106, plc->url, "local");
				plc->plc_status = PLC_ABORT;
			}
			return;	/* no global colormap! */
		}
	}
	gif->ncolors = gif->cmapsize;

	/* sanity check: image *must* have a colormap */
	if(gif->cmap == NULL)
	{
		_XmHTMLWarning(__WFUNC__(gif->owner, "_PLC_GIF_Init"),
			XMHTML_MSG_106, plc->url, "global or local");
		plc->plc_status = PLC_ABORT;
		return;	/* no global colormap! */
	}

	/* image depth (= codeSize in GIF images, unused in GZF images) */
	if(!(_PLCReadOK(plc, &c, 1)))
		return;

	gif->depth = (int)(c & 0xff);

	/* check interlacing */
	if(BitSet(buf[8], INTERLACE))
	{
		/* interlaced gifs require 4 passes and use an initial rowstride of 8 */
		gif->npasses = 4;
		gif->stride  = 8;
	}
	else
	{
		/* regular gif, 1 pass will get us the entire image */
		gif->npasses = 1;
		gif->stride  = 0;
	}
	gif->curr_pass = 0;
	gif->curr_scanline = 0;

	/*****
	* This routine is also used for GZF images, so before initializing
	* the LZWStream object we need to make sure we have been called for
	* a true GIF image.
	*****/
	if(plc->object->type == plcGIF)
	{
		XmHTMLWidget html  = plc->object->plc_any.owner;

		if(HTML_ATTR(gif_proc) != NULL)
		{
			gif->external_codec = True;
			gif->inflate = HTML_ATTR(gif_proc);
			if((gif->gstream =
				(XmHTMLGIFStream*)malloc(sizeof(XmHTMLGIFStream))) == NULL)
			{
				/* out of memory, too bad then */
				_XmHTMLWarning(__WFUNC__(gif->owner, "_PLC_GIF_Init"),
					XMHTML_MSG_113, plc->url, sizeof(XmHTMLGIFStream));
				plc->plc_status = PLC_ABORT;
				return;
			}

			/* initialize GIFStream object */
			memset(gif->gstream, 0, sizeof(XmHTMLGIFStream));

			gif->gstream->codesize  = (int)c;
			gif->gstream->state     = GIF_STREAM_INIT;
			gif->gstream->next_out  = gif->buffer;
			gif->gstream->avail_out = gif->buf_size + 1;
			gif->gstream->is_progressive = True;
			/*
			* and call external decoder so it can initialize its own data
			* structures
			*/
			if((gif->inflate(gif->gstream)) != GIF_STREAM_OK)
			{
				if(gif->gstream->msg != NULL)
				{
					_XmHTMLWarning(__WFUNC__(gif->owner, "_PLC_GIF_Init"),
						XMHTML_MSG_109, plc->url,
						gif->gstream->msg ? gif->gstream->msg :
						"(unknown error)");
				}
				/* external decoder initalization failed, abort and return */
				plc->plc_status = PLC_ABORT;
				return;
			}
			gif->gstream->state = GIF_STREAM_OK;
		}
		else
		{
			/* initialize local data buffer */
			gif->ib.file   = plc->url;
			gif->ib.buffer = gif->buffer;	
			gif->ib.size   = 0;
			gif->ib.next   = 0;
			gif->ib.type   = IMAGE_GIF;
			gif->ib.depth  = gif->depth;
			gif->ib.may_free = False;

			/* initialize LZWStream object */
			if(gif->lstream == NULL)
			{
				if((gif->lstream = LZWStreamCreate(&(gif->ib),
									html->html.zCmd)) == NULL)
				{
					/* couldn't create stream, abort and return */
					plc->plc_status = PLC_ABORT;
					return;
				}
				/* set read functions */
				gif->lstream->readOK  = _XmHTMLGifReadOK;
				gif->lstream->getData = _XmHTMLGifGetDataBlock;
			}
			/* first byte in buffer is gif codesize */
			gif->ib.buffer[0] = c;
			gif->ib.size = 1;
		}
		/* allocate room for final image data */
		if(gif->data == NULL)
		{
			gif->data = (Byte*)calloc(gif->buf_size + 1, sizeof(Byte));

			/* don't allocate clipmask yet, it's done in the plc code */
		}
		gif->data_size = gif->buf_size;
		gif->data_pos  = 0;
	}

	/* object has been initialized */
	plc->initialized = True;

	plc->curr_obj_func = 0;	/* move to GIF scanline reader */
	return;
}
Exemplo n.º 13
0
static gint
DoExtension (FILE *fd,
             gint  label)
{
  static guchar  buf[256];
  gchar         *str;

  switch (label)
    {
    case 0x01:                  /* Plain Text Extension */
      str = "Plain Text Extension";
#ifdef notdef
      if (GetDataBlock (fd, (guchar *) buf) == 0)
        ;

      lpos       = LM_to_uint (buf[0], buf[1]);
      tpos       = LM_to_uint (buf[2], buf[3]);
      width      = LM_to_uint (buf[4], buf[5]);
      height     = LM_to_uint (buf[6], buf[7]);
      cellw      = buf[8];
      cellh      = buf[9];
      foreground = buf[10];
      background = buf[11];

      while (GetDataBlock (fd, (guchar *) buf) > 0)
        {
          PPM_ASSIGN (image[ypos][xpos],
                      cmap[CM_RED][v],
                      cmap[CM_GREEN][v],
                      cmap[CM_BLUE][v]);
          ++index;
        }

      return FALSE;
#else
      break;
#endif

    case 0xff:                  /* Application Extension */
      str = "Application Extension";
      break;
    case 0xfe:                  /* Comment Extension */
      str = "Comment Extension";
      while (GetDataBlock (fd, (guchar *) buf) > 0)
        {
          gchar *comment = (gchar *) buf;

          if (! g_utf8_validate (comment, -1, NULL))
            continue;

          if (comment_parasite)
            gimp_parasite_free (comment_parasite);

          comment_parasite = gimp_parasite_new ("gimp-comment",
                                                GIMP_PARASITE_PERSISTENT,
                                                strlen (comment) + 1, comment);
        }
      return TRUE;
      break;

    case 0xf9:                  /* Graphic Control Extension */
      str = "Graphic Control Extension";
      (void) GetDataBlock (fd, (guchar *) buf);
      Gif89.disposal  = (buf[0] >> 2) & 0x7;
      Gif89.inputFlag = (buf[0] >> 1) & 0x1;
      Gif89.delayTime = LM_to_uint (buf[1], buf[2]);
      if ((buf[0] & 0x1) != 0)
        Gif89.transparent = buf[3];
      else
        Gif89.transparent = -1;

      while (GetDataBlock (fd, (guchar *) buf) > 0);

      return FALSE;
      break;

    default:
      str = (gchar *)buf;
      sprintf ((gchar *)buf, "UNKNOWN (0x%02x)", label);
      break;
    }

#ifdef GIFDEBUG
  g_print ("GIF: got a '%s'\n", str);
#endif

  while (GetDataBlock (fd, (guchar *) buf) > 0);

  return FALSE;
}
Exemplo n.º 14
0
static gint32
load_image (const gchar  *filename,
            gboolean      thumbnail,
            GError      **error)
{
  FILE     *fd;
  guchar    buf[16];
  guchar    c;
  CMap      localColorMap;
  gint      grayScale;
  gboolean  useGlobalColormap;
  gint      bitPixel;
  gint      imageCount = 0;
  gchar     version[4];
  gint32    image_ID = -1;

  fd = g_fopen (filename, "rb");

  if (! fd)
    {
      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
                   _("Could not open '%s' for reading: %s"),
                   gimp_filename_to_utf8 (filename), g_strerror (errno));
      return -1;
    }

  gimp_progress_init_printf (_("Opening '%s'"),
                             gimp_filename_to_utf8 (filename));

  if (! ReadOK (fd, buf, 6))
    {
      g_message ("Error reading magic number");
      return -1;
    }

  if (strncmp ((gchar *) buf, "GIF", 3) != 0)
    {
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                   "%s", _("This is not a GIF file"));
      return -1;
    }

  strncpy (version, (gchar *) buf + 3, 3);
  version[3] = '\0';

  if ((strcmp (version, "87a") != 0) && (strcmp (version, "89a") != 0))
    {
      g_message ("Bad version number, not '87a' or '89a'");
      return -1;
    }

  if (! ReadOK (fd, buf, 7))
    {
      g_message ("Failed to read screen descriptor");
      return -1;
    }

  GifScreen.Width           = LM_to_uint (buf[0], buf[1]);
  GifScreen.Height          = LM_to_uint (buf[2], buf[3]);
  GifScreen.BitPixel        = 2 << (buf[4] & 0x07);
  GifScreen.ColorResolution = (((buf[4] & 0x70) >> 3) + 1);
  GifScreen.Background      = buf[5];
  GifScreen.AspectRatio     = buf[6];

  if (BitSet (buf[4], LOCALCOLORMAP))
    {
      /* Global Colormap */
      if (! ReadColorMap (fd, GifScreen.BitPixel, GifScreen.ColorMap,
                          &GifScreen.GrayScale))
        {
          g_message ("Error reading global colormap");
          return -1;
        }
    }

  if (GifScreen.AspectRatio != 0 && GifScreen.AspectRatio != 49)
    {
      g_message (_("Non-square pixels.  Image might look squashed."));
    }


  highest_used_index = 0;

  while (TRUE)
    {
      if (! ReadOK (fd, &c, 1))
        {
          g_message ("EOF / read error on image data");
          return image_ID; /* will be -1 if failed on first image! */
        }

      if (c == ';')
        {
          /* GIF terminator */
          return image_ID;
        }

      if (c == '!')
        {
          /* Extension */
          if (! ReadOK (fd, &c, 1))
            {
              g_message ("EOF / read error on extension function code");
              return image_ID; /* will be -1 if failed on first image! */
            }

          DoExtension (fd, c);
          continue;
        }

      if (c != ',')
        {
          /* Not a valid start character */
          g_printerr ("GIF: bogus character 0x%02x, ignoring.\n", (int) c);
          continue;
        }

      ++imageCount;

      if (! ReadOK (fd, buf, 9))
        {
          g_message ("Couldn't read left/top/width/height");
          return image_ID; /* will be -1 if failed on first image! */
        }

      useGlobalColormap = !BitSet (buf[8], LOCALCOLORMAP);

      bitPixel = 1 << ((buf[8] & 0x07) + 1);

      if (! useGlobalColormap)
        {
          if (! ReadColorMap (fd, bitPixel, localColorMap, &grayScale))
            {
              g_message ("Error reading local colormap");
              return image_ID; /* will be -1 if failed on first image! */
            }

          image_ID = ReadImage (fd, filename, LM_to_uint (buf[4], buf[5]),
                                LM_to_uint (buf[6], buf[7]),
                                localColorMap, bitPixel,
                                grayScale,
                                BitSet (buf[8], INTERLACE), imageCount,
                                (guint) LM_to_uint (buf[0], buf[1]),
                                (guint) LM_to_uint (buf[2], buf[3]),
                                GifScreen.Width,
                                GifScreen.Height);
        }
      else
        {
          image_ID = ReadImage (fd, filename, LM_to_uint (buf[4], buf[5]),
                                LM_to_uint (buf[6], buf[7]),
                                GifScreen.ColorMap, GifScreen.BitPixel,
                                GifScreen.GrayScale,
                                BitSet (buf[8], INTERLACE), imageCount,
                                (guint) LM_to_uint (buf[0], buf[1]),
                                (guint) LM_to_uint (buf[2], buf[3]),
                                GifScreen.Width,
                                GifScreen.Height);
        }

      if (comment_parasite != NULL)
        {
          if (! thumbnail)
            gimp_image_attach_parasite (image_ID, comment_parasite);

          gimp_parasite_free (comment_parasite);
          comment_parasite = NULL;
        }

      /* If we are loading a thumbnail, we stop after the first frame. */
      if (thumbnail)
        break;
    }

  return image_ID;
}
Exemplo n.º 15
0
/*--------------------------------------------------------------------------*/
int AG_LoadGIF_RW( SDL_RWops* src, AG_Frame* frames, int maxFrames )
{
	int start;
	unsigned char buf[16];
	unsigned char c;
	int useGlobalColormap;
	int bitPixel;
	int iFrame = 0;
	char version[4];
	SDL_Surface* image = NULL;
	gifdata* gd;

	if ( src == NULL )
		return 0;

	gd = (gifdata *)malloc( sizeof(*gd) );
	memset( gd, 0, sizeof(*gd) );
	gd->src = src;

	start = SDL_RWtell( src );

	if ( !SDL_RWread(src,buf,6,1) )
	{
		SDL_SetError( "error reading magic number" );
		goto done;
	}

	if ( strncmp((char*)buf,"GIF",3) != 0 )
	{
		SDL_SetError( "not a GIF file" );
		goto done;
	}

	strncpy( version, (char*)buf+3, 3 );
	version[3] = '\0';

	if ( (strcmp(version,"87a") != 0) && (strcmp(version,"89a") != 0) )
	{
		SDL_SetError( "bad version number, not '87a' or '89a'" );
		goto done;
	}

	gd->g89.transparent	= -1;
	gd->g89.delayTime	= -1;
	gd->g89.inputFlag	= -1;
	gd->g89.disposal	= AG_DISPOSE_NA;

	if ( !SDL_RWread(src,buf,7,1) )
	{
		SDL_SetError( "failed to read screen descriptor" );
		goto done;
	}

	gd->gs.Width			= LM_to_uint(buf[0],buf[1]);
	gd->gs.Height			= LM_to_uint(buf[2],buf[3]);
	gd->gs.BitPixel			= 2 << (buf[4] & 0x07);
	gd->gs.ColorResolution	= (((buf[4] & 0x70) >> 3) + 1);
	gd->gs.Background		= buf[5];
	gd->gs.AspectRatio		= buf[6];

	if ( BitSet(buf[4],LOCALCOLORMAP) )		/* Global Colormap */
	{
		if ( ReadColorMap(gd,gd->gs.BitPixel,gd->gs.ColorMap) )
		{
			SDL_SetError( "error reading global colormap" );
			goto done;
		}
	}

	do
	{
		if ( !SDL_RWread(src,&c,1,1) )
		{
			SDL_SetError( "EOF / read error on image data" );
			goto done;
		}

		if ( c == ';' )		/* GIF terminator */
			goto done;

		if ( c == '!' )		/* Extension */
		{
			if ( !SDL_RWread(src,&c,1,1) )
			{
				SDL_SetError( "EOF / read error on extention function code" );
				goto done;
			}
			DoExtension( gd, c );
			continue;
		}

		if ( c != ',' )		/* Not a valid start character */
			continue;

		if ( !SDL_RWread(src,buf,9,1) )
		{
			SDL_SetError( "couldn't read left/top/width/height" );
			goto done;
		}

		useGlobalColormap = !BitSet(buf[8],LOCALCOLORMAP);
		bitPixel = 1 << ((buf[8] & 0x07) + 1);

		if ( !useGlobalColormap )
		{
			if ( ReadColorMap(gd,bitPixel,gd->localColorMap) )
			{
				SDL_SetError( "error reading local colormap" );
				goto done;
			}
			image = ReadImage( gd, LM_to_uint(buf[4],buf[5]), LM_to_uint(buf[6],buf[7]), bitPixel, gd->localColorMap, BitSet(buf[8],INTERLACE), (frames==NULL) );
		}
		else
		{
			image = ReadImage( gd, LM_to_uint(buf[4],buf[5]), LM_to_uint(buf[6],buf[7]), gd->gs.BitPixel, gd->gs.ColorMap, BitSet(buf[8],INTERLACE), (frames==NULL) );
		}

		if ( frames )
		{
			if ( image == NULL )
				goto done;

			if ( gd->g89.transparent >= 0 )
				SDL_SetColorKey( image, SDL_SRCCOLORKEY, gd->g89.transparent );

			frames[iFrame].surface	= image;
			frames[iFrame].x		= LM_to_uint(buf[0], buf[1]);
			frames[iFrame].y		= LM_to_uint(buf[2], buf[3]);
			frames[iFrame].disposal	= gd->g89.disposal;
			frames[iFrame].delay	= gd->g89.delayTime*10;
/*			gd->g89.transparent		= -1;			** Hmmm, not sure if this should be reset for each frame? */
		}

		iFrame++;
	} while ( iFrame < maxFrames || frames == NULL );

done:
	if ( image == NULL )
		SDL_RWseek( src, start, SEEK_SET );

	free( gd );

	return iFrame;
}
Exemplo n.º 16
0
static int
DoExtension(byte **inbuf, int label, GifState *g)
{
    char           *str;
    char           *buf = g->ext_buf;

    switch (label) {
    case 0x01:        /* Plain Text Extension */
        str = "Plain Text Extension";
#ifdef notdef
        if (GetDataBlock(inbuf, (unsigned char*) buf, g) == 0)
            ;

        lpos   = LM_to_uint(buf[0], buf[1]);
        tpos   = LM_to_uint(buf[2], buf[3]);
        width  = LM_to_uint(buf[4], buf[5]);
        height = LM_to_uint(buf[6], buf[7]);
        cellw  = buf[8];
        cellh  = buf[9];
        foreground = buf[10];
        background = buf[11];

        while (GetDataBlock(inbuf, (unsigned char*) buf, g) != 0) {
            PPM_ASSIGN(image[ypos][xpos],
                    cmap[CM_RED][v],
                    cmap[CM_GREEN][v],
                    cmap[CM_BLUE][v]);
            ++index;
        }

        return FALSE;
#else
        break;
#endif
    case 0xff:        /* Application Extension */
        str = "Application Extension";
        break;
    case 0xfe:        /* Comment Extension */
        str = "Comment Extension";
        while (GetDataBlock(inbuf, (unsigned char*) buf, g) != 0) {
#ifdef DEBUG
            _gif_message("gif comment: %s", buf );
#endif
        }
        return FALSE;
    case 0xf9:        /* Graphic Control Extension */
        str = "Graphic Control Extension";
        (void) GetDataBlock(inbuf, (unsigned char*) buf, g);
        g->Gif89.disposal    = (buf[0] >> 2) & 0x7;
        g->Gif89.inputFlag   = (buf[0] >> 1) & 0x1;
        g->Gif89.delayTime   = LM_to_uint(buf[1], buf[2]);
        if ((buf[0] & 0x1) != 0)
            g->Gif89.transparent = buf[3];

        while (GetDataBlock(inbuf, (unsigned char*) buf, g) != 0)
            ;
        return FALSE;
    default:
        str = buf;
        sprintf(buf, "UNKNOWN (0x%02x)", label);
        break;
    }

#ifdef DEBUG
    _gif_message("got a '%s' extension", str );
#endif

    while (GetDataBlock(inbuf, (unsigned char*) buf, g) != 0)
        ;

    return FALSE;
}
Exemplo n.º 17
0
Arquivo: gif.c Projeto: guygal/egui
static int gif_get_extension(GifContext *context)
{
	int retval;
	int empty_block = false;

	if (context->extension_flag) {
		if (!context->extension_label &&
				!gif_read(context, &context->extension_label , 1))
			return -1;

		switch (context->extension_label) {
		case 0xf9:			/* Graphic Control Extension */
			retval = get_data_block(context, (euchar *)context->block_buf, NULL);
			if (retval != 0) return retval;

			if (context->frame == NULL) {
				context->gif89.disposal = (context->block_buf[0] >> 2) & 0x7;
				context->gif89.input_flag = (context->block_buf[0] >> 1) & 0x1;
				context->gif89.delay_time = LM_to_uint(context->block_buf[1], context->block_buf[2]);

				if ((context->block_buf[0] & 0x1) != 0)
					context->gif89.transparent = context->block_buf[3];
				else
					context->gif89.transparent = -1;
			}

			/* Now we've successfully loaded this one, we continue on our way */
			context->block_count = 0;
			context->extension_flag = false;
			break;

		case 0xff: /* application extension */
			if (!context->in_loop_extension) { 
				retval = get_data_block(context, (euchar *)context->block_buf, NULL);
				if (retval != 0)
					return retval;
				if (!e_strncmp(context->block_buf, _("NETSCAPE2.0"), 11) ||
						!e_strncmp(context->block_buf, _("ANIMEXTS1.0"), 11)) {
					context->in_loop_extension = true;
				}
				context->block_count = 0;
			}

			if (context->in_loop_extension) {
				do {
					retval = get_data_block(context, (euchar *)context->block_buf, &empty_block);
					if (retval != 0)
						return retval;
					if (context->is_anim && context->block_buf[0] == 0x01) {
						context->anim->loop = context->block_buf[1] + (context->block_buf[2] << 8);
						if (context->anim->loop != 0) 
							context->anim->loop++;
					}
					context->block_count = 0;
				} while (!empty_block);

				context->in_loop_extension = false;
				context->extension_flag = false;
				goto step;
			}
			break;
		default:
			break;
		}
	}
Exemplo n.º 18
0
static int DoExtension(FILE *fd, int label){
	static char	buf[256];
	char		*str;

	switch (label) {
	case 0x01:		/* Plain Text Extension */
		strcpy(str,"Plain Text Extension");
#ifdef notdef
		if (GetDataBlock(fd, (unsigned char*) buf) == 0)
			;

		lpos	= LM_to_uint(buf[0], buf[1]);
		tpos	= LM_to_uint(buf[2], buf[3]);
		width	= LM_to_uint(buf[4], buf[5]);
		height = LM_to_uint(buf[6], buf[7]);
		cellw	= buf[8];
		cellh	= buf[9];
		foreground = buf[10];
		background = buf[11];

		while (GetDataBlock(fd, (unsigned char*) buf) != 0) {
			PPM_ASSIGN(image[ypos][xpos],
					cmap[CM_RED][v],
					cmap[CM_GREEN][v],
					cmap[CM_BLUE][v]);
			++index;
		}

		return FALSE;
#else
		break;
#endif
	case 0xff:		/* Application Extension */
		strcpy(str,"Application Extension");
		GetDataBlock(fd, (unsigned char*) buf);
#if 0
		if (showComment){
			fprintf(stderr, "Application Extension: %c%c%c%c%c%c%c%c ",
				buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]);
			fprintf(stderr, " Authentication Code=)%02x %02x %02x\n",
				buf[8], buf[9], buf[10]);
		}
#endif
		break;
	case 0xfe:		/* Comment Extension */
		strcpy(str,"Comment Extension");
		while (GetDataBlock(fd, (unsigned char*) buf) != 0) {
#if 0
	    	if (showComment)
				fprintf(stderr,"gif comment: %s\n", buf );
#endif
		}
		return FALSE;
	case 0xf9:		/* Graphic Control Extension */
		strcpy(str,"Graphic Control Extension");
		(void) GetDataBlock(fd, (unsigned char*) buf);
		Gif89.disposal    = (buf[0] >> 2) & 0x7;
		Gif89.inputFlag   = (buf[0] >> 1) & 0x1;
		Gif89.delayTime   = LM_to_uint(buf[1],buf[2]);
		if ((buf[0] & 0x1) != 0)
			Gif89.transparent = buf[3];

		while (GetDataBlock(fd, (unsigned char*) buf) != 0)
			;
		return FALSE;
	default:
		str = buf;
		sprintf(buf, "UNKNOWN (0x%02x)", label);
		break;
	}

	fprintf(stderr,"got a '%s' extension\n", str );

	while (GetDataBlock(fd, (unsigned char*) buf) != 0)
		;

	return FALSE;
}
Exemplo n.º 19
0
RageSurfaceUtils::OpenResult RageSurface_Load_GIF( const RString &sPath, RageSurface *&ret, bool bHeaderOnly, RString &error )
{
	unsigned char buf[256];
	int imageCount = 0;
	int imageNumber = 1;
	RageFile f;

	if( !f.Open( sPath ) )
	{
		error = f.GetError();
		return RageSurfaceUtils::OPEN_FATAL_ERROR;
	}
	
	if( !ReadOK(f, buf, 6) )
	{
		error = "error reading magic number";
		return RageSurfaceUtils::OPEN_FATAL_ERROR;
	}
	if( strncmp((char *) buf, "GIF", 3) != 0 )
	{
		error = "not a GIF file";
		return RageSurfaceUtils::OPEN_UNKNOWN_FILE_FORMAT;
	}

	{
		char version[4];
		strncpy(version, (char *) buf + 3, 3);
		version[3] = '\0';

		if( (strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0) )
		{
			error = "bad version number, not '87a' or '89a'";
			return RageSurfaceUtils::OPEN_FATAL_ERROR;
		}
	}

	if( !ReadOK(f, buf, 7) )
	{
		error = "failed to read screen descriptor";
		return RageSurfaceUtils::OPEN_FATAL_ERROR;
	}

	RageSurfaceColor GlobalColorMap[MAXCOLORMAPSIZE];
	unsigned int GlobalBitPixel = 0;

	GlobalBitPixel = 2 << (buf[4] & 0x07);

	if( BitSet(buf[4], LOCALCOLORMAP) )
	{
		/* Global Colormap */
		if( !ReadPalette(f, GlobalBitPixel, GlobalColorMap ) )
		{
			error = "error reading global colormap";
			return RageSurfaceUtils::OPEN_FATAL_ERROR;
		}
	}

	int transparency = -1;

	while(1)
	{
		unsigned char type;
		if( !ReadOK(f, &type, 1) )
		{
			error = "EOF / read error on image data";
			return RageSurfaceUtils::OPEN_FATAL_ERROR;
		}
		switch( type )
		{
		case ';':
		{
			/* GIF terminator */
			if( imageCount < imageNumber )
			{
				error = ssprintf( "only %d image%s found in file",
					imageCount, imageCount > 1 ? "s" : "");
				return RageSurfaceUtils::OPEN_FATAL_ERROR;
			}
		}

		case '!':
		{
			/* Extension */
			unsigned char label;
			if( !ReadOK(f, &label, 1) )
			{
				error = "EOF / read error on extention function code";
				return RageSurfaceUtils::OPEN_FATAL_ERROR;
			}

			switch( label )
			{
			case 0xf9:
				GetDataBlock( f, (unsigned char *) buf );
				if( (buf[0] & 0x1) != 0 )
					transparency  = buf[3];
			}

			while( GetDataBlock(f, (unsigned char *) buf) != 0 )
				;

			continue;
		}
		case ',':
		{
			++imageCount;

			if( !ReadOK(f, buf, 9) )
			{
				error = "couldn't read left/top/width/height";
				return RageSurfaceUtils::OPEN_FATAL_ERROR;
			}

			int bitPixel = 1 << ((buf[8] & 0x07) + 1);
			RageSurfaceColor LocalColorMap[MAXCOLORMAPSIZE];

			if( BitSet(buf[8], LOCALCOLORMAP) )
			{
				if( !ReadPalette(f, bitPixel, LocalColorMap) )
				{
					error = "error reading local colormap";
					return RageSurfaceUtils::OPEN_FATAL_ERROR;
				}
			} else {
				bitPixel = GlobalBitPixel;
				memcpy( LocalColorMap, GlobalColorMap, sizeof(LocalColorMap) );
			}

			ret = ReadImage( f, LM_to_uint(buf[4], buf[5]), LM_to_uint(buf[6], buf[7]),
					LocalColorMap, BitSet(buf[8], INTERLACE),
					imageCount != imageNumber );

			if( !ret )
				continue;

			if( transparency != -1 )
				ret->format->palette->colors[ transparency ].a = 0;

			return RageSurfaceUtils::OPEN_OK;
		}
		default: continue; /* Not a valid start character */
		}
	}

	return RageSurfaceUtils::OPEN_FATAL_ERROR;
}