⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 giffile.cpp

📁 医学图象处理系统
💻 CPP
📖 第 1 页 / 共 3 页
字号:

		if (sp > stack)
			return *--sp;
	}
	return code;
}   

static BOOL ReadImage(	FILE *fd,
						BYTE  * bigMemBuf,
						int width, int height,
						UCHAR cmap[3][MAXCOLORMAPSIZE],
						int interlace)
{
	UCHAR c;
	int color;
	int xpos=0, ypos=0, pass=0;
	long curidx;

	if (!ReadOK(fd,& c,1))
	{
		return FALSE;
	}

	if (LZWReadByte(fd,TRUE,c)<0) 
	{
		return FALSE;
	}
	
	while ((color = LZWReadByte(fd, FALSE, c)) >= 0 ) 
	{
        curidx=(long)xpos + (long)ypos * (long)width;
        curidx*=3;
        
		*(bigMemBuf+curidx)   = cmap[0][color];
		*(bigMemBuf+curidx+1) = cmap[1][color];
		*(bigMemBuf+curidx+2) = cmap[2][color];				

		++xpos;
		if (xpos==width) 
		{
			xpos=0;
			if (interlace)
			{
				switch (pass) 
				{
				case 0:
				case 1:
					ypos += 8; break;
				case 2:
					ypos += 4; break;
				case 3:
					ypos += 2; break;
				}

				if (ypos>=height) 
				{
					++pass;
					switch (pass)
					{
					case 1: ypos = 4; break;
					case 2: ypos = 2; break;
					case 3: ypos = 1; break;
					default : goto fini;
					}
				}
			} 
			else 
			{
				++ypos;
			}
		}
		if (ypos >=height)
			break;
	}
fini :
	if (LZWReadByte(fd,FALSE,c)>=0) 
	{
	}
	return TRUE;
}
//	gets image dimensions
//	returns -1,-1 on bad read
void GIFFile::GIFGetDimensions(CString path, UINT *width, UINT *height)
{
	UCHAR			buf[16];
	UCHAR			c;
	char			version[4];
	FILE 			*fd;          
	int 			w=0;
	int				h=0;	
	
	if (_access(path,0)!=0) 
	{
		*width=(UINT)-1;*height=(UINT)-1;
		return;
	}
	
	fd=fopen(path,"rb");
	if (fd==NULL) 
	{                       
		*width=(UINT)-1;*height=(UINT)-1;
		return;
	}

	// read GIF file header
	if (!ReadOK(fd,buf,6))
		goto bail;

	// need the string "GIF" in the header
	if (strncmp((char *)buf,"GIF",3)!=0)
		goto bail;

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

	// only handle v 87a and 89a
	if ((strcmp(version,"87a")!=0)&&(strcmp(version,"89a")!=0))
		goto bail;

	// screen description
	if (!ReadOK(fd,buf,7))
		goto bail;

	GifScreen.Width		=	LM_to_uint((UCHAR)buf[0],(UCHAR)buf[1]);
	GifScreen.Height	=	LM_to_uint((UCHAR)buf[2],(UCHAR)buf[3]);
	GifScreen.BitPixel	=	2<<((UCHAR)buf[4]&0x07);
	GifScreen.ColorResolution=((((UCHAR)buf[4]&0x70)>>3)+1);
	GifScreen.BackGround=	(UCHAR)buf[5];									// background color...
	GifScreen.AspectRatio=	(UCHAR)buf[6];
            
	*width  = GifScreen.Width;		
	*height = GifScreen.Height;

	// read colormaps
	if (BitSet((UCHAR)buf[4],LOCALCOLORMAP))
		if (!ReadColorMap(fd,GifScreen.BitPixel,GifScreen.ColorMap))
			goto bail;                                         
 
	if (!ReadOK(fd,&c,1))
		goto bail;

	if (c!=',')
		goto bail;

	// read image header
	if (!ReadOK(fd,buf,9))
		goto bail;                    
	
	//*width=LM_to_uint((UCHAR)buf[4],(UCHAR)buf[5]);		
	//*height=LM_to_uint((UCHAR)buf[6],(UCHAR)buf[7]);
		
	if ((*width<0) || (*height<0))
		goto bail;

	// good
	fclose(fd);
	return;

bail:      
	// bad
	fclose(fd);
	//*width=(UINT)-1;*height=(UINT)-1;
	return;
}

////////////////////////////////////////////////////////////////////////
//
//	This is the writing portion of the GIFFile class.
//	It is based on code from Programming for Graphics Files	by John Levine
//
//	This is free to use and modify provided proper credit is given
//
//	This writes 256 color GIFs version GIF87a.
//
//	see GIFFile.h for example
////////////////////////////////////////////////////////////////////////
////////////
//
//	GIF writing section
//
////////////

// a code_int must be able to hold 2**BITS values of type int, and also -1
static int 				Width, Height;
static int				curx, cury;
static long 			CountDown;
static unsigned long	cur_accum = 0;
static int				cur_bits = 0;
static unsigned char	*buffer;


/*
 * Bump the 'curx' and 'cury' to point to the next pixel
 */
void GIFFile::BumpPixel()
{
    /*
     * Bump the current X position
     */
    ++curx;

    if( curx == Width )
	{
        curx = 0;
		++cury;
    }
}

/*******************************************************************************
* Return the next pixel from the image
*******************************************************************************/

int GIFFile::GIFNextPixel( )
{
    unsigned long index;
    int r;
    
    if( CountDown == 0 )
        return EOF;

    --CountDown;
    
    index= (unsigned long)curx + (unsigned long)cury * (unsigned long)Width;
    
	r = *(buffer+index);

    BumpPixel();

    return r;
}

/*******************************************************************************
*	here's the entry point. 
*	file ptr, screen width, height, background color, bits per pixel and
*	arrays of color values (0-255)
*******************************************************************************/
BOOL GIFFile::GIFWriteFileFrom256Color(unsigned char  * buf,
							CString name,
							int GWidth, 
							int GHeight,
							int BackGround,
							int Red[], int Green[], int Blue[])
{                       
	FILE *fp;
	int B;
	int RWidth, RHeight;
	int LeftOfs, TopOfs;
	int Resolution;
	int ColorMapSize;
	int InitCodeSize;
	int i;
	int BitsPerPixel = 8;

	fp=fopen(name,"wb");
	if (fp==NULL)
	{
		m_GIFErrorText="Can't open GIF for writing";
		return FALSE;
	}
	
	ColorMapSize = 1 << BitsPerPixel;

	buffer=buf;

	RWidth = Width = GWidth;
	RHeight = Height = GHeight;
	LeftOfs = TopOfs = 0;

	cur_accum = 0;
	cur_bits = 0;

	Resolution = BitsPerPixel;

	CountDown = (long)Width * (long) Height;

	if (BitsPerPixel <=1)
	InitCodeSize=2;
	else
	InitCodeSize = BitsPerPixel;

	curx = cury =0;

	fwrite("GIF87a",1,6,fp);

	Putword(RWidth,fp);
	Putword(RHeight,fp);

	B=0x80;
	
	B |=(Resolution -1) << 5;

	B |=(BitsPerPixel - 1);

	fputc(B,fp);

	fputc(BackGround,fp);
	
	fputc(0,fp);

	for(i=0; i<ColorMapSize; ++i) 
	{
		fputc(Red[i],fp);
		fputc(Green[i],fp);
		fputc(Blue[i],fp);
	}

	fputc(',',fp);

	Putword(LeftOfs,fp);
	Putword(TopOfs,fp);
	Putword(Width,fp);
	Putword(Height,fp);

	fputc(0x00,fp);

    /*
     * Write out the initial code size
     */
    fputc( InitCodeSize, fp );
    /*
     * Go and actually compress the data
     */

    compress(  InitCodeSize+1, fp);

    /*
     * Write out a Zero-length packet (to end the series)
     */
    fputc( 0, fp );

    /*
     * Write the GIF file terminator
     */
    fputc( ';', fp );

    /*
     * And close the file
     */
    fclose( fp );

	return TRUE;
}

/*******************************************************************************
 * Write out a word to the GIF file
*******************************************************************************/

void GIFFile::Putword(int w, FILE *fp )
{
    fputc( w & 0xff, fp );
    fputc( (w / 256) & 0xff, fp );
}


/***************************************************************************
 *
 *  GIFCOMPR.C       - GIF Image compression routines
 *
 *  Lempel-Ziv compression based on 'compress'.  GIF modifications by
 *  David Rowley (mgardi@watdcsu.waterloo.edu)
 *
 ***************************************************************************/

/*
 * General DEFINEs
 */

#define BITS    12

#define HSIZE  5003            /* 80% occupancy */

typedef        unsigned char   char_type;

/*
 *
 * GIF Image compression - modified 'compress'
 *
 * Based on: compress.c - File compression ala IEEE Computer, June 1984.
 *
 * By Authors:  Spencer W. Thomas       (decvax!harpo!utah-cs!utah-gr!thomas)
 *              Jim McKie               (decvax!mcvax!jim)
 *              Steve Davies            (decvax!vax135!petsd!peora!srd)
 *              Ken Turkowski           (decvax!decwrl!turtlevax!ken)
 *              James A. Woods          (decvax!ihnp4!ames!jaw)
 *              Joe Orost               (decvax!vax135!petsd!joe)
 *
 */

static int n_bits;                        /* number of bits/code */
static int maxbits = BITS;                /* user settable max # bits/code */
static code_int maxcode;                  /* maximum code, given n_bits */
static code_int maxmaxcode = (code_int)1 << BITS; /* should NEVER generate this
code */

#define MAXCODE(n_bits)        (((code_int) 1 << (n_bits)) - 1)

static count_int htab [HSIZE];
static unsigned short codetab [HSIZE];
#define HashTabOf(i)       htab[i]
#define CodeTabOf(i)    codetab[i]

static code_int free_ent = 0;                  /* first unused entry */

/*
 * block compression parameters -- after all codes are used up,
 * and compression rate changes, start over.
 */
static int clear_flg = 0;

/*
 * compress pixels to GIF packets
 *
 * Algorithm:  use open addressing double hashing (no chaining) on the
 * prefix code / next character combination.  We do a variant of Knuth's
 * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
 * secondary probe.  Here, the modular division first probe is gives way
 * to a faster exclusive-or manipulation.  Also do block compression with
 * an adaptive reset, whereby the code table is cleared when the compression
 * ratio decreases, but after the table fills.  The variable-length output
 * codes are re-sized at this point, and a special CLEAR code is generated
 * for the decompressor.  Late addition:  construct the table according to
 * file size for noticeable speed improvement on small files.  Please direct
 * questions about this implementation to ames!jaw.
 */

static int g_init_bits;
static FILE* g_outfile;

static int ClearCode;
static int EOFCode;

/*******************************************************************************
*
*******************************************************************************/

void GIFFile::compress( int init_bits, FILE* outfile)
{
    register long fcode;
    register code_int i /* = 0 */;
    register int c;
    register code_int ent;
    register code_int disp;
    register int hshift;

    /*
     * Set up the globals:  g_init_bits - initial number of bits
     *                      g_outfile   - pointer to output file
     */
    g_init_bits = init_bits;
    g_outfile = outfile;

    /*
     * Set up the necessary values
     */
    clear_flg = 0;
    maxcode = MAXCODE(n_bits = g_init_bits);

    ClearCode = (1 << (init_bits - 1));
    EOFCode = ClearCode + 1;
    free_ent = ClearCode + 2;

    char_init();

    ent = GIFNextPixel( );

    hshift = 0;
    for ( fcode = (long) HSIZE;  fcode < 65536L; fcode *= 2L )
        ++hshift;
    hshift = 8 - hshift;                /* set hash code range bound */

    cl_hash( (count_int) HSIZE);            /* clear hash table */

    output( (code_int)ClearCode );

    while ( (c = GIFNextPixel( )) != EOF ) 
	{	/* } */

        fcode = (long) (((long) c << maxbits) + ent);
        i = (((code_int)c << hshift) ^ ent);    /* xor hashing */

        if ( HashTabOf (i) == fcode ) 
		{
            ent = CodeTabOf (i);
            continue;
        } else if ( (long)HashTabOf (i) < 0 )      /* empty slot */
            goto nomatch;
        disp = HSIZE - i;           /* secondary hash (after G. Knott) */
        if ( i == 0 )
            disp = 1;
probe:
        if ( (i -= disp) < 0 )
            i += HSIZE;

        if ( HashTabOf (i) == fcode ) 
		{
            ent = CodeTabOf (i);
            continue;
        }
        if ( (long)HashTabOf (i) > 0 )
            goto probe;
nomatch:
        output ( (code_int) ent );
        ent = c;
        if ( free_ent < maxmaxcode ) 
		{	/* } */
            CodeTabOf (i) = free_ent++; /* code -> hashtable */
            HashTabOf (i) = fcode;
        } else
                cl_block();
    }
    /*
     * Put out the final code.
     */
    output( (code_int)ent );
    output( (code_int) EOFCode );
}

/*****************************************************************
 * TAG( output )
 *
 * Output the given code.
 * Inputs:
 *      code:   A n_bits-bit integer.  If == -1, then EOF.  This assumes
 *              that n_bits =< (long)wordsize - 1.
 * Outputs:
 *      Outputs code to the file.
 * Assumptions:
 *      Chars are 8 bits long.
 * Algorithm:
 *      Maintain a BITS character long buffer (so that 8 codes will
 * fit in it exactly).  Use the VAX insv instruction to insert each
 * code in turn.  When the buffer fills up empty it and start over.
 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -