Google Answers Logo
View Question
 
Q: Program reading GIF87a File with Turbo C 3.0 ( No Answer,   1 Comment )
Question  
Subject: Program reading GIF87a File with Turbo C 3.0
Category: Computers > Programming
Asked by: patrickdang-ga
List Price: $20.00
Posted: 19 Oct 2006 07:01 PDT
Expires: 18 Nov 2006 06:01 PST
Question ID: 775007
This following source code is about to display GIF87a Files in
DOS-enviroment, but something crazy happenned! It doesn't display the
image correctly.?
Could you pleased check and point out the mistake?
Here is the source code.


/*************************************************************************
READING GIF87a
DISPLAY IN 320x200x256 VGA MODE
**************************************************************************/



#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <mem.h>
#include <string.h>
#include <conio.h>

#define VIDEO_INT           0x10      /* ngat video cua Bios. */
#define SET_MODE            0x00      /* Ham cua BIOS de dat che do man hinh. */
#define VGA_256_COLOR_MODE  0x13      /* ngat dung de dat che do 256 mau. */
#define TEXT_MODE           0x03      /* su dung de dat che do ky tu 80x25 */

#define PALETTE_INDEX       0x03c8
#define PALETTE_DATA        0x03c9
#define INPUT_STATUS        0x03da
#define VRETRACE            0x08

#define SCREEN_WIDTH        320       /* do rong man hinh trong che do 0x13 */
#define SCREEN_HEIGHT       200       /* chieu cao man hinh trong che do 0x13 */
#define NUM_COLORS          256       /* so mau trong che do 0x13 */

typedef unsigned char  byte;
typedef unsigned short word;
typedef unsigned long  dword;

byte *VGA=(byte *)0xA0000000L;        	/* con tro tro thang vao bo nho man hinh */
typedef struct _IMAGE              		/* cau truc du lieu hinh anh */
{
  	word width;
  	word height;
	byte palette[256*3];
  	byte *data;
	} IMAGE;
	
ReadPcxLine(char *p,FILE *fp);
/*****************************************
THONG TIN HEADER FILE GIF
******************************************/
typedef struct _gifInfoType						// thong tin cua Header file Gif
	{
		char version[7];				// thong tin phien ban GIF89a hay GIF87a ?
		byte gcTable;					// Co ton tai bang mau hay khong? Gia tri 0 hoac 1
		byte bitsPerPixel;				// so bit tren mot pixel
		byte background;				// thuong la 0;
		unsigned int xStart, yStart;	// thuong la 0,0
		int width, height;				// chieu cao cua anh
		byte lcTable;					// bang mau ton tai
		byte interlaced;				// tep interlaced
	} gifInfoType;
/****************************************
Cac bien toan cuc cho file gif.c
*****************************************/
FILE *dataFile;					// file GIF duoc khai baotoan cuc
unsigned long pwr2[17];			// luu tru cac luy thua cua 2
int nBitsIn;					// So bit duoc lay tu mot ky tu
int num;
int	aChar;						// mot ky tu doc duoc tu tep
int blockLength;
long paletteOffset, dataOffset;	//vi tri cua bang mau va du lieu

/**************************************************************************
 *  fskip                                                                 *
 *    Bo qua mot so byte trong 1 tep                                      *
 **************************************************************************/

void fskip(FILE *fp, int num_bytes)
{
   int i;
   for (i=0; i<num_bytes; i++)
      fgetc(fp);
}

/**************************************************************************
 *  set_mode                                                              *
 *     Dat che do do hoa.                                                 *
 **************************************************************************/

void set_mode(byte mode)
{
  union REGS regs;

  regs.h.ah = SET_MODE;
  regs.h.al = mode;
  int86(VIDEO_INT, &regs, &regs);
}
void put_pixel (int x, int y, byte color)
   {
   if (y>=0 && y<200)			// kiem tra xem toa do co hop le hay khong
      if (x>=0 && x<320)
	 VGA[y*320+x] = color;	// truy cap thang vao bo nho man hinh
   }

/**************************************************************************
 *  set_palette                                                           *
 *    Sets all 256 colors of the palette.                                 *
 **************************************************************************/

void set_palette(byte *palette)
{
  int i;
  outp(PALETTE_INDEX,0);              /* tell the VGA that palette
data is coming. */
  for(i=0;i<256*3;i++)
    outp(PALETTE_DATA,palette[i]);    /* write the data */
}
/******************************************
* khoitao
* Khoi tao cac gia tri cho ham show_gif
*******************************************/
void khoitao(void)
{
	int i;
	nBitsIn = 8;		// dat so bit doc ra la 8
	num = 0;
	pwr2[0]=1;			// khoi tao bang luy thua cua 2
	for (i=1;i<17;i++) pwr2[i]=pwr2[i-1]*2;
}
/******************************************
* get_bit
* Doc 1 bit tu tep
* Tra ve gia tri doc duoc, 0 hoac 1
******************************************/
int get_bit(void)
{
	nBitsIn++;			// tang bo dem so bit duoc doc vao
	if (nBitsIn == 9)	// kiem tra xem doc xong 1 ky tu hay chua?
	{
		aChar = fgetc(dataFile);	//doc 1 ky tu
		nBitsIn = 1;				//dat so bit doc vao thanh 1 (9-8 =1)
		num++;
		if (num == blockLength)
		{
			blockLength = aChar + 1;
			aChar = fgetc(dataFile);
			num = 1;
		}
	}
	if ((aChar & pwr2[nBitsIn-1])==0) return 0;
	else return 1;
}
/******************************************
* read_code
* doc mot ma tu tep
* Se goi ham get_bit de khoi tao ra ma duoc yeu cau
*******************************************/
int read_code (int codesize)
{
	int i, code = 0;	//Khoi tao gia tri
	for (i=0;i<codesize;i++)
			code +=get_bit()*pwr2[i];	//chuyen doi tu nhi phan sang thap phan
	return code;
}

/***************************************************
* read_gif_info
* Doc thong tin tu header cua file GIF
* tra lai gia tri 1 neu gap loi
***************************************************/
int read_gif_info (FILE *dataFile, gifInfoType *gifInfo)
{
	int i;
	char abyte;		//bien tam thoi
	khoitao();		//khoi tao cac gia tri can thiet
	for (i=0; i<6; i++) gifInfo->version[i]=fgetc(dataFile);
	gifInfo->version[6]='\0';			//Doc 6 byte phien ban
	for (i=0;i<4;i++) (void) fgetc(dataFile);	//bo qua thong tin chieu cao va rong
	abyte = fgetc(dataFile);			//doc byte tiep theo va luu
	gifInfo->gcTable = ((abyte&128)==128);	//Bang mau co ton tai hay khong?
	gifInfo->bitsPerPixel = (abyte & 7)+1;	//So bit tren 1 pixel
	gifInfo->background = fgetc(dataFile);	//doc mau nen
	abyte = fgetc(dataFile);				//byte tiep theo luon la 0
	if (abyte!=0) return 1;					//khac 0 => khong phai tep GIF
	fgetpos(dataFile,&paletteOffset);		//bo qua bang mau
	
	//doc thong tin cua hinh anh
	fseek (dataFile, pwr2[gifInfo->bitsPerPixel]*3,SEEK_CUR);
	abyte= fgetc(dataFile);				//bo qua byte tiep theo
	fread(&gifInfo->xStart,2,1,dataFile);
	fread(&gifInfo->yStart,2,1,dataFile);
	fread(&gifInfo->width,2,1,dataFile);
	fread(&gifInfo->height,2,1,dataFile);
	abyte=fgetc(dataFile);
	gifInfo->lcTable=(((abyte&128)==128) ? 1 : 0);		//local color table?
	gifInfo->interlaced = (((abyte & 64) == 64) ? 1:0);	//interlaced image?
	fgetpos(dataFile,&dataOffset);
	return 0; 		//successful
}
/************************************************
* show_gif
* Giai nen file gif ra mot mang du lieu de hien thi trong chuong trinh chinh
* Tra lai gia tri neu hinh anh khong hien thi duoc
*************************************************/
int load_gif(char *file,IMAGE *img)
{
	gifInfoType gifInfo;
	byte abyte;
	byte r,g,b;
	int i;
	int size;
	int codeSize, code, inCode, curCode, oldCode, prefix[4096],
suffix[4096];	//de giai nen LZW
	int clearCode, eofCode, freeCode, firstFree, maxCode, initCodesize,
bitMask, finChar, outCount, outCode[1025];	//giai thuat LZW bien the
	int x, y;			//vi tri cua pixel
	dataFile = fopen(file,"rb");
	if (dataFile == NULL) return 6;	//khong mo tep duoc
	if (read_gif_info(dataFile,&gifInfo)!=0)
	{	fclose(dataFile); return 5;}	//tep khong hop le
	if (strcmpi(gifInfo.version, "GIF89a")==0)
	{	fclose(dataFile); return 1;}	//dinh dang khong ho tro
	else if (strcmpi(gifInfo.version, "GIF87a") !=0)
	{	fclose(dataFile); return 4;}	//header khong hop le
	if (gifInfo.gcTable == 0)			//khong the thao tac thieu bang mau
	{	fclose(dataFile);return 2;}
	if (gifInfo.lcTable !=0)			//khong xu ly bang mau dia phuong duoc
	{	fclose(dataFile); return 3;}
	if (gifInfo.interlaced !=0)			//khong xu ly tep ket noi duoc
	{	fclose(dataFile); return 4;}
	
	//Doc bang mau
	fseek(dataFile, paletteOffset, SEEK_SET);		//Nhay toi vi tri bang mau
	for (i=0;i<pwr2[gifInfo.bitsPerPixel];i++)		//doc bang mau
	{
		img->palette[(int)(i*3+2)] = fgetc(dataFile) >> 2;
		img->palette[(int)(i*3+1)] = fgetc(dataFile) >> 2;
		img->palette[(int)(i*3+0)] = fgetc(dataFile) >> 2;
	}
	set_palette(img->palette); 
	//Xin cap phat o nho
	img->width=gifInfo.width;
	img->height=gifInfo.height;
	size=gifInfo.width*gifInfo.height;
	if((img->data=(byte
*)malloc((word)(gifInfo.width*gifInfo.height)))==NULL) //Khong cap
phat bo nho duoc
								return 7;
	//Doc du lieu
	fseek(dataFile, dataOffset, SEEK_SET);				//nhay toi vi tri bat dau
du lieu hinh anh
	codeSize = fgetc(dataFile);							//doc kich co ma
	clearCode = pwr2[codeSize];							//ma clear = 2^codeSize
	eofCode = clearCode +1;								// ma ket thuc File
	freeCode = firstFree = clearCode +2;				// ma tu do
	codeSize++;											// kich co that cua so ma
	initCodesize = codeSize;							// khoi tao gia tri
	maxCode = pwr2[codeSize];
	bitMask = pwr2[gifInfo.bitsPerPixel]-1;			// giai nen cac bit
	blockLength = fgetc(dataFile) + 1;
	outCount = 0;										// so cai pixel nen
	x = gifInfo.xStart;									//toa do x va y cho mot pixel
	y = gifInfo.yStart;

	//Bat dau giai nen du lieu
	do
	{
		code = read_code(codeSize);			// doc ma co kich thuoc CodeSize
		if (code == eofCode) break;			// ket thuc tep?
		if (code == clearCode)				// ma Clear?
		{
			codeSize = initCodesize;		// bat dau khoi tao kich co CodeSize
			maxCode = pwr2[codeSize];
			freeCode = firstFree;
			code = read_code(codeSize);		// Doc ma tiep theo
			oldCode = curCode = code;		// danh dau hien tai va bit cu
			finChar = code & bitMask;		// giai nen cac bit
			img->data[y*gifInfo.width+(x++)] = finChar;		// Ghi du lieu vao bo dem
			put_pixel (x, y, outCode[i]);
			if (x>= gifInfo.width) { x=0; y++;}	//Hang tiep theo
		}
		else
		{
			inCode = curCode = code;		// chua hieu
			
			if (code >= freeCode)			// khong trong bang?
			{
				curCode = oldCode;
				outCode [outCount++]=finChar;
			}
			if (curCode > bitMask)
				do {
					outCode[outCount++] = suffix[curCode];
					curCode = prefix[curCode];
			} while (curCode > bitMask);
			finChar = curCode & bitMask;		//giai nen cac bit
			outCode [outCount++] = finChar;		// luu lai
			for (i=outCount - 1;i>=0;i--)		// in ra cac pixel da duoc luu
			{
				img->data[y*gifInfo.width+(x++)]=outCode[i];
				put_pixel (x, y, outCode[i]);
				if (x>= gifInfo.width) {x=0; y++;}
			}
			outCount = 0;
			prefix[freeCode] = oldCode;
			suffix[freeCode++] = finChar;
			oldCode = inCode;
			if(freeCode >=maxCode && codeSize <12)
			{	codeSize++; maxCode *=12;	}
		}
	} while (code != eofCode);		// EOF? Thoat
	fclose(dataFile);
    return 0;
}

/**************************************************************************
 *  draw_image                                                            *
 *    Draws an image.                                                     *
 **************************************************************************/

void draw_image(IMAGE img)
{

  int j,k;
  j=k=0;
  for(j=0;j<img.height;j++)
	for(k=0;k<img.width;k++)
		put_pixel(k,j,img.data[j*img.width+k]);
}


/**************************************************************************
 *  Main                                                                  *
 *    Draws a bitmap and then rotates the palette.                        *
 **************************************************************************/

void main()
{
  IMAGE img;
   set_mode(VGA_256_COLOR_MODE);       /* set the video mode. */
			/* set the palette */
 load_gif("a.gif",&img);          /* open the file */
  draw_image(img);
  free(&img.data);                     /* free up memory used */
  getch();
  set_mode(TEXT_MODE);                /* set the video mode back to	text mode. */
  return;
}
Answer  
There is no answer at this time.

Comments  
Subject: Re: Program reading GIF87a File with Turbo C 3.0
From: srinifinance-ga on 01 Nov 2006 14:03 PST
 
Your program is not reading the following correctly, open the gif in
pbrush and hard code the width and height and it should display
correctly.

	fread(&gifInfo->xStart,2,1,dataFile); // if correct location
	fread(&gifInfo->yStart,2,1,dataFile); // if correct location
	fread(&gifInfo->width,2,1,dataFile); // if correct location
	fread(&gifInfo->height,2,1,dataFile); // check if correct location

        // check with something like this and correct the above code
	gifInfo->xStart=0;
	gifInfo->yStart=0;
	gifInfo->width=27; 
	gifInfo->height=36;

hope fully that helps.

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy