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;
}
Beispiel #2
0
void ReadAllColorMap(const char * c_pszDirName)
{
	struct stat	s;
	char	buf[512 + 1];

	if (stat(c_pszDirName, &s) != 0)
	{
		sys_log(0, "No map directory: %s", c_pszDirName);
		return;
	}

	std::vector <std::string> vtFileList;
	GetFindFileList(c_pszDirName, "*.*", vtFileList);
	
	int n = vtFileList.size();

	for (int i = 0; i < n; i++)
	{
		const char * c_pszFileName = vtFileList[i].c_str();
		const char * p;

		if ((p = strrchr(c_pszFileName, '.')))
		{
			++p;

			if (!strncmp(p, "cmp", 3))
				ReadColorMap(c_pszFileName);
		}
	}
}
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;
}
Beispiel #4
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);
}
Beispiel #5
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;
}
Beispiel #6
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;
}
Beispiel #7
0
int main(int argc, char* argv[]){
    if(argc != 3){
        printf("Useage: input_name output_name");
        exit(0);
    }
    
    char file_answer;
    
    printf("Select mode:\n"
           "1.bin to bmp\n"
           "2.bmp to bmp\n"
           "3.bin to bin\n");
    file_answer=getchar();
    fflush(stdin);
    
    char *Input=argv[1], *Output=argv[2];//retrive input/output name from commandline
    BmpHead *pBmpHeader = new BmpHead;
    unsigned char **pucImageData; 
    char *pcColorMap=NULL;
           
    if((file_answer == '1')||(file_answer == '3')){   //read bin file
        system("cls");
        
        //assign header information courtersy of Lena.bin
	    (*pBmpHeader).bfType=19778;
	    (*pBmpHeader).bfSize=54 + 1024+ 512*512 ; // raw data size = 512*512 = 262144 bytes, modify when necessary
	    (*pBmpHeader).bfReserved=0;
	    (*pBmpHeader).bfOffBits=1078;
	    (*pBmpHeader).biSize=40;
	    (*pBmpHeader).biWidth= 512;		//number of columns of the image
	    (*pBmpHeader).biHeight= 512;		//number of rows of the image
	    (*pBmpHeader).biPlanes=1;
	    (*pBmpHeader).biBitCount=8;
	    (*pBmpHeader).biCompression=0;
	    (*pBmpHeader).biSizeImage= 512*512;	//raw data size = 512*512 = 26144 bytes, modify when necessary, e.g., a 256x256 image: raw data size = 256*256
	    (*pBmpHeader).biXPelsPerMeter=2834;
	    (*pBmpHeader).biYpelsPerMeter=2834;
	    (*pBmpHeader).biClrUsed=0;
	    (*pBmpHeader).biClrImportant=0;
        
        //read provided colormap
        FILE *colormap=NULL;
        pcColorMap = new char [1024];
        if((colormap=fopen("colormap.bin", "rb")) == NULL){
            printf("Failed to find colormap.bin\n");
            exit(0);
        }
        fread(pcColorMap, sizeof(char), pBmpHeader->bfOffBits-64, colormap);
        fclose(colormap);
        
        //read raw data fron input
        pucImageData = ReadImage( Input, pBmpHeader->biWidth, 0);
        
        printf("successfully read raw data from %s.\n\n", Input);
    }
     
    else if(file_answer == '2'){  //read bmp file
        system("cls");
        
        //read input header infomation
        pBmpHeader=ReadBmpHeader(Input);
        printf("raw data size: %d\n", pBmpHeader->biSizeImage);
        printf("Image Width: %d\n", pBmpHeader->biWidth);
        printf("Image Height %d\n", pBmpHeader->biHeight);
	    printf("Header occupies 54 bytes\n");
        printf("Color map occupies 1024 bytes\n");	
        
        //read input colormap
        pcColorMap=ReadColorMap(Input, 1024);
        
        //read raw data from input
                                                    //set offset=1024+54
        pucImageData=ReadImage(Input, pBmpHeader->biWidth, 1078);
        printf("successfully read raw data from %s.\n\n", Input);
    }
    
    srand(time(NULL));//plant random seed
    
    //function menu
    char fx_answer;
    int width, cutoff;
    do{
        printf(
           "Select function:\n"
           "A.Turn Lena upside down\n"
           "B.Turn Lena around\n"
           "C.Rotate Lena by 45 deg clockwise\n"
           "D.Shrink Lena by half\n"
           "E.Invert Lena\n"
           "F.Add normal noise to Lena\n"
           "G.Add impluse noise to Lena\n"
           "H.Moving average filtering\n"
           "I.Midian filtering\n"
           "J.Differential flitering\n"
           "K.LPF\n"
           "L.HPF\n"
           "\n0.Exit\n");
        printf("Your choice: [_]\b\b");
        fx_answer = getchar();
        fx_answer = tolower(fx_answer);
        fflush(stdin);
        
        switch(fx_answer){//savefile(): ask user to save as picture or not
            case 'a':// selected: turn lena upside down
                UpsideDown(pucImageData, pBmpHeader->biWidth);
                savefile(Output, pucImageData, file_answer, pBmpHeader, pcColorMap);
                break;
            
            case 'b'://selected: turn lena around
                LeftRight(pucImageData, pBmpHeader->biWidth);
                savefile(Output, pucImageData, file_answer, pBmpHeader, pcColorMap);
                break;
                 
            case 'c'://selected: rotate lena
                ImgRotate(pucImageData, pBmpHeader->biWidth, 45);
                savefile(Output, pucImageData, file_answer, pBmpHeader, pcColorMap);
                break;
            
            case 'd'://selected: shrink lena
                Shrink(pucImageData, pBmpHeader->biWidth, pBmpHeader, 2);
                savefile(Output, pucImageData, file_answer, pBmpHeader, pcColorMap);
                break;
                 
            case 'e'://selected: invert lena
                Invert(pucImageData, pBmpHeader->biWidth);
                savefile(Output, pucImageData, file_answer, pBmpHeader, pcColorMap);
                break;
                 
            case 'f'://selected: add noise
                NormalNoise(pucImageData, pBmpHeader->biWidth);
                savefile(Output, pucImageData, file_answer, pBmpHeader, pcColorMap);
                break;
                 
            case 'g'://selected: add paper n salt noise
                ImpluseNoise(pucImageData, pBmpHeader->biWidth);
                savefile(Output, pucImageData, file_answer, pBmpHeader, pcColorMap);
                break;
                 
            case 'h'://selected: moving average filter
                //ask user to input sampling width
                printf("Enter sampling width:");
                scanf("%d", &width);
                fflush(stdin);
                MAF(pucImageData, pBmpHeader->biWidth, width);
                savefile(Output, pucImageData, file_answer, pBmpHeader, pcColorMap);
                break;
                 
            case 'i'://selected: moving midian filter
                //ask user to input sampling width
                printf("Enter sampling width:");
                scanf("%d", &width);
                fflush(stdin);
                MF(pucImageData, pBmpHeader->biWidth, width);
                savefile(Output, pucImageData, file_answer, pBmpHeader, pcColorMap);
                break;
                 
            case 'j'://selected: differential filter
                DIF(pucImageData, pBmpHeader->biWidth);
                savefile(Output, pucImageData, file_answer, pBmpHeader, pcColorMap);
                break;
                 
            case 'k'://selected: low-pass filter
                //ask user to input cutoff frequency
                printf("Enter cutoff frenquency(0~%d):", (int)pBmpHeader->biWidth/2);
                scanf("%d", &cutoff);
                fflush(stdin);
                LPF(pucImageData, pBmpHeader->biWidth, cutoff);
                savefile(Output, pucImageData, file_answer, pBmpHeader, pcColorMap);
                break;
                 
            case 'l'://selected: high-pass filter
                //ask user to input cutoff frequency
                printf("Enter cutoff frenquency(0~%d):", (int)pBmpHeader->biWidth/2);
                scanf("%d", &cutoff);
                fflush(stdin);
                HPF(pucImageData, pBmpHeader->biWidth, cutoff);
                savefile(Output, pucImageData, file_answer, pBmpHeader, pcColorMap);
                break;
                 
            case '0'://selected: exit
                //ask one last time whether user want to save or not
                savefile(Output, pucImageData, file_answer, pBmpHeader, pcColorMap);
                break;
                 
            default:
                system("cls");
                printf("Your choice is not in the list!\n");
                break;
            
        }
        
        if(fx_answer == 0)
            break;//selected: exit. break the loop
        
        
    } while(fx_answer != '0');
    
    //returning dynamic allocated memory
    delete [] pcColorMap;
    delete [] pucImageData;
    delete pBmpHeader;
    pcColorMap=NULL;
    pucImageData=NULL;
    pBmpHeader=NULL;
    
    printf("EOP\n");
}
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;
}
Beispiel #9
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;
}
int main(int argc, char* argv[]){
	char file[255],OutFileName[255];
	system("cls");
	printf("請輸入bmp檔名:");
	scanf("%s",file);
	printf("請輸入輸出bmp檔名:");
	scanf("%s",OutFileName);

// Step1:declare a bmp header by using BmpHead

	BmpHead *pBmpHeader;			//bmp檔案包含三部份,此一其中的檔頭,BmpHead為structure
	pBmpHeader = new BmpHead;
		

// Step2: read the information of the bmp header

	pBmpHeader=ReadBmpHeader(file);
	printf("raw data size: %d\n", (*pBmpHeader).biSizeImage);
    printf("Image Width: %d\n", (*pBmpHeader).biWidth);
    printf("Image Height %d\n", (*pBmpHeader).biHeight);
	printf("Header occupies 54 bytes\n");
    printf("Color map occupies 1024 bytes\n");	

//Step3:reading the colormap from the bmp file
	char *pcColorMap;				//此為colormap
	pcColorMap=ReadColorMap(file,1024);
	
    
	
//Step4:reading the raw data (lena.bmp)
// ************** your work ******************範例是用1D-view  
    unsigned char* pucImageData;
    pucImageData = ReadImage(file, (*pBmpHeader).biSizeImage, (*pBmpHeader).bfOffBits);

// image data is stored behind “header” and “colormap”.
// move your file pointer to the end of colormap, e.g., move to 54 + 1024 (by fseek())





//Step5:processing the data, 
// ************** your work ******************


//Step6:write Header
	
	WriteHeader(OutFileName,pBmpHeader); // file: output filename, assigned by yourself


//Step7:write colormap
	WriteColorMap(OutFileName,pcColorMap,1024);

// Step8: write processed data
WriteImageData(OutFileName,pucImageData,(*pBmpHeader).biSizeImage);//write rawdata
printf("Done!!");
// ***************** your work *********************
// (1) !!! move the file pointer to the "end of the opened output file" (or say, to the end of the colormap) (by fseek(): Moves the file pointer to a specified location), 
// and then start to write your data into it
// Or (2)That is, Opens for writing at the end of the file (by the mode specifier of fopen())
 system("pause");
	return 0;
}