|
|
| version 1.2, 2001/04/11 17:00:55 | version 1.21.2.2, 2003/01/31 12:34:28 |
|---|---|
| Line 1 | Line 1 |
| /** @file | /** @file |
| Code drawn from ppmtogif.c, from the pbmplus package | Parser: image manipulations impl2. |
| Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com) | |
| Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) | |
| based on: gd | |
| Written by Tom Boutell, 5/94. | |
| Copyright 1994, Cold Spring Harbor Labs. | |
| Permission granted to use this code in any fashion provided | |
| that this notice is retained and any alterations are | |
| labeled as such. It is requested, but not required, that | |
| you share extensions to this module with us so that we | |
| can incorporate them into new versions. | |
| based on: | |
| ** | ** |
| ** Based on GIFENCOD by David Rowley <mgardi@watdscu.waterloo.edu>. A | ** Based on GIFENCOD by David Rowley <mgardi@watdscu.waterloo.edu>. A |
| ** Lempel-Zim compression based on "compress". | ** Lempel-Zim compression based on "compress". |
| Line 21 Code drawn from ppmtogif.c, from the pbm | Line 35 Code drawn from ppmtogif.c, from the pbm |
| ** CompuServe Incorporated. | ** CompuServe Incorporated. |
| */ | */ |
| static const char* IDENT_GIFIO_C="$Date$"; | |
| #include "gif.h" | #include "gif.h" |
| static int colorstobpp(int colors); | static int colorstobpp(int colors); |
| static void Putword(int w, FILE *fp); | |
| void gdImage::Gif(FILE *out) | void gdImage::Gif(Pool& pool, String& out) |
| { | { |
| int BitsPerPixel = colorstobpp(colorsTotal); | int BitsPerPixel = colorstobpp(colorsTotal); |
| /* Clear any old values in statics strewn through the GIF code */ | /* Clear any old values in statics strewn through the GIF code */ |
| gdGifEncoder encoder(pool(), *this); | gdGifEncoder encoder(pool, *this, out); |
| /* All set, let's do it. */ | /* All set, let's do it. */ |
| encoder.encode( | encoder.encode( |
| out, sx, sy, interlace, 0, transparent, BitsPerPixel, | sx, sy, interlace, 0, transparent, BitsPerPixel, |
| red, green, blue); | red, green, blue); |
| } | } |
| Line 70 colorstobpp(int colors) | Line 85 colorstobpp(int colors) |
| * | * |
| *****************************************************************************/ | *****************************************************************************/ |
| #ifndef TRUE | |
| #define TRUE 1 | #define TRUE 1 |
| #endif | |
| #ifndef FALSE | |
| #define FALSE 0 | #define FALSE 0 |
| #endif | |
| /* | /* |
| * Bump the 'curx' and 'cury' to point to the next pixel | * Bump the 'curx' and 'cury' to point to the next pixel |
| Line 152 gdGifEncoder::GIFNextPixel() | Line 171 gdGifEncoder::GIFNextPixel() |
| /* public */ | /* public */ |
| void | void |
| gdGifEncoder::encode(FILE *fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue) | gdGifEncoder::encode(int GWidth, int GHeight, |
| int GInterlace, int Background, int Transparent, int BitsPerPixel, | |
| int *Red, int *Green, int *Blue) | |
| { | { |
| int B; | int B; |
| int RWidth, RHeight; | int RWidth, RHeight; |
| Line 198 gdGifEncoder::encode(FILE *fp, int GWidt | Line 219 gdGifEncoder::encode(FILE *fp, int GWidt |
| /* | /* |
| * Write the Magic header | * Write the Magic header |
| */ | */ |
| fwrite( Transparent < 0 ? "GIF87a" : "GIF89a", 1, 6, fp ); | fp << (Transparent < 0 ? "GIF87a" : "GIF89a"); |
| /* | /* |
| * Write out the screen width and height | * Write out the screen width and height |
| */ | */ |
| Putword( RWidth, fp ); | Putword( RWidth); |
| Putword( RHeight, fp ); | Putword( RHeight); |
| /* | /* |
| * Indicate that there is a global colour map | * Indicate that there is a global colour map |
| Line 224 gdGifEncoder::encode(FILE *fp, int GWidt | Line 245 gdGifEncoder::encode(FILE *fp, int GWidt |
| /* | /* |
| * Write it out | * Write it out |
| */ | */ |
| fputc( B, fp ); | Putbyte(B); |
| /* | /* |
| * Write out the Background colour | * Write out the Background colour |
| */ | */ |
| fputc( Background, fp ); | Putbyte(Background); |
| /* | /* |
| * Byte of 0's(future expansion) | * Byte of 0's(future expansion) |
| */ | */ |
| fputc( 0, fp ); | Putbyte(0); |
| /* | /* |
| * Write out the Global Colour Map | * Write out the Global Colour Map |
| */ | */ |
| for( i=0; i<ColorMapSize; ++i ) { | for( i=0; i<ColorMapSize; ++i ) { |
| fputc( Red[i], fp ); | Putbyte( Red[i]); |
| fputc( Green[i], fp ); | Putbyte( Green[i]); |
| fputc( Blue[i], fp ); | Putbyte( Blue[i]); |
| } | } |
| /* | /* |
| * Write out extension for transparent colour index, if necessary. | * Write out extension for transparent colour index, if necessary. |
| */ | */ |
| if( Transparent >= 0 ) { | if( Transparent >= 0 ) { |
| fputc( '!', fp ); | Putbyte( '!'); |
| fputc( 0xf9, fp ); | Putbyte( 0xf9); |
| fputc( 4, fp ); | Putbyte( 4); |
| fputc( 1, fp ); | Putbyte( 1); |
| fputc( 0, fp ); | Putbyte( 0); |
| fputc( 0, fp ); | Putbyte( 0); |
| fputc((unsigned char) Transparent, fp ); | Putbyte((unsigned char) Transparent); |
| fputc( 0, fp ); | Putbyte( 0); |
| } | } |
| /* | /* |
| * Write an Image separator | * Write an Image separator |
| */ | */ |
| fputc( ',', fp ); | Putbyte( ','); |
| /* | /* |
| * Write the Image header | * Write the Image header |
| */ | */ |
| Putword( LeftOfs, fp ); | Putword( LeftOfs); |
| Putword( TopOfs, fp ); | Putword( TopOfs); |
| Putword( Width, fp ); | Putword( Width); |
| Putword( Height, fp ); | Putword( Height); |
| /* | /* |
| * Write out whether or not the image is interlaced | * Write out whether or not the image is interlaced |
| */ | */ |
| if( Interlace ) | if( Interlace ) |
| fputc( 0x40, fp ); | Putbyte( 0x40); |
| else | else |
| fputc( 0x00, fp ); | Putbyte( 0x00); |
| /* | /* |
| * Write out the initial code size | * Write out the initial code size |
| */ | */ |
| fputc( InitCodeSize, fp ); | Putbyte( InitCodeSize); |
| /* | /* |
| * Go and actually compress the data | * Go and actually compress the data |
| */ | */ |
| compress( InitCodeSize+1, fp); | compress( InitCodeSize+1 ); |
| /* | /* |
| * Write out a Zero-length packet(to end the series) | * Write out a Zero-length packet(to end the series) |
| */ | */ |
| fputc( 0, fp ); | Putbyte( 0); |
| /* | /* |
| * Write the GIF file terminator | * Write the GIF file terminator |
| */ | */ |
| fputc( ';', fp ); | Putbyte( ';'); |
| } | } |
| /* | /* |
| * Write out a byte to the GIF file | |
| */ | |
| void | |
| gdGifEncoder::Putbyte(int c) { | |
| char *p=new(pool) char[1]; | |
| *p=c; | |
| fp.APPEND_AS_IS(p, 1, 0, 0); | |
| } | |
| /* | |
| * Write out a word to the GIF file | * Write out a word to the GIF file |
| */ | */ |
| static void | void |
| Putword(int w, FILE *fp) | gdGifEncoder::Putword(int w) |
| { | { |
| fputc( w & 0xff, fp ); | char *p=new(pool) char[2]; |
| fputc((w / 256) & 0xff, fp ); | p[0]=w & 0xff; |
| p[1]=(w / 256) & 0xff; | |
| fp.APPEND_AS_IS(p, 2, 0, 0); | |
| } | } |
| void gdGifEncoder::Write(void *buf, size_t size) { | |
| char *p=new(pool) char[size]; | |
| memcpy(p, buf, size); | |
| fp.APPEND_AS_IS(p, size, 0, 0); | |
| } | |
| /*************************************************************************** | /*************************************************************************** |
| * | * |
| Line 330 Putword(int w, FILE *fp) | Line 367 Putword(int w, FILE *fp) |
| #ifdef NO_UCHAR | #ifdef NO_UCHAR |
| typedef char char_type; | typedef char char_type; |
| #else /*NO_UCHAR*/ | #else |
| typedef unsigned char char_type; | typedef unsigned char char_type; |
| #endif /*NO_UCHAR*/ | #endif |
| /* | /* |
| * | * |
| Line 348 typedef unsigned char char_type | Line 385 typedef unsigned char char_type |
| * Joe Orost (decvax!vax135!petsd!joe) | * Joe Orost (decvax!vax135!petsd!joe) |
| * | * |
| */ | */ |
| #include <ctype.h> | |
| #ifdef COMPATIBLE /* But wrong! */ | #ifdef COMPATIBLE /* But wrong! */ |
| # define MAXCODE(n_bits) ((code_int) 1 <<(n_bits) - 1) | # define MAXCODE(n_bits) ((code_int) 1 <<(n_bits) - 1) |
| #else /*COMPATIBLE*/ | #else |
| # define MAXCODE(n_bits) (((code_int) 1 <<(n_bits)) - 1) | # define MAXCODE(n_bits) (((code_int) 1 <<(n_bits)) - 1) |
| #endif /*COMPATIBLE*/ | #endif |
| #define HashTabOf(i) htab[i] | #define HashTabOf(i) htab[i] |
| #define CodeTabOf(i) codetab[i] | #define CodeTabOf(i) codetab[i] |
| Line 388 typedef unsigned char char_type | Line 423 typedef unsigned char char_type |
| */ | */ |
| void | void |
| gdGifEncoder::compress(int init_bits, FILE *outfile) | gdGifEncoder::compress(int init_bits) |
| { | { |
| register long fcode; | register long fcode; |
| register code_int i /* = 0 */; | register code_int i /* = 0 */; |
| Line 403 gdGifEncoder::compress(int init_bits, FI | Line 438 gdGifEncoder::compress(int init_bits, FI |
| * g_outfile - pointer to output file | * g_outfile - pointer to output file |
| */ | */ |
| g_init_bits = init_bits; | g_init_bits = init_bits; |
| g_outfile = outfile; | |
| /* | /* |
| * Set up the necessary values | * Set up the necessary values |
| Line 434 gdGifEncoder::compress(int init_bits, FI | Line 468 gdGifEncoder::compress(int init_bits, FI |
| #ifdef SIGNED_COMPARE_SLOW | #ifdef SIGNED_COMPARE_SLOW |
| while((c = GIFNextPixel( )) !=(unsigned) EOF ) { | while((c = GIFNextPixel( )) !=(unsigned) EOF ) { |
| #else /*SIGNED_COMPARE_SLOW*/ | #else |
| while((c = GIFNextPixel( )) != EOF ) { /* } */ | while((c = GIFNextPixel( )) != EOF ) { /* } */ |
| #endif /*SIGNED_COMPARE_SLOW*/ | #endif |
| ++in_count; | |
| fcode =(long)(((long) c << maxbits) + ent); | |
| i =(((code_int)c << hshift) ^ ent); /* xor hashing */ | |
| if( HashTabOf(i) == fcode ) { | ++in_count; |
| ent = CodeTabOf(i); | |
| continue; | fcode =(long)(((long) c << maxbits) + ent); |
| } else if((long)HashTabOf(i) < 0 ) /* empty slot */ | i =(((code_int)c << hshift) ^ ent); /* xor hashing */ |
| goto nomatch; | |
| disp = hsize_reg - i; /* secondary hash(after G. Knott) */ | if( HashTabOf(i) == fcode ) { |
| if( i == 0 ) | ent = CodeTabOf(i); |
| disp = 1; | continue; |
| } else if((long)HashTabOf(i) < 0 ) /* empty slot */ | |
| goto nomatch; | |
| disp = hsize_reg - i; /* secondary hash(after G. Knott) */ | |
| if( i == 0 ) | |
| disp = 1; | |
| probe: | probe: |
| if((i -= disp) < 0 ) | if((i -= disp) < 0 ) |
| i += hsize_reg; | i += hsize_reg; |
| if( HashTabOf(i) == fcode ) { | if( HashTabOf(i) == fcode ) { |
| ent = CodeTabOf(i); | ent = CodeTabOf(i); |
| continue; | continue; |
| } | } |
| if((long)HashTabOf(i) > 0 ) | if((long)HashTabOf(i) > 0 ) |
| goto probe; | goto probe; |
| nomatch: | nomatch: |
| output((code_int) ent ); | output((code_int) ent ); |
| ++out_count; | ++out_count; |
| ent = c; | ent = c; |
| #ifdef SIGNED_COMPARE_SLOW | #ifdef SIGNED_COMPARE_SLOW |
| if((unsigned) free_ent <(unsigned) maxmaxcode) { | if((unsigned) free_ent <(unsigned) maxmaxcode) { |
| #else /*SIGNED_COMPARE_SLOW*/ | #else |
| if( free_ent < maxmaxcode ) { /* } */ | if( free_ent < maxmaxcode ) { /* } */ |
| #endif /*SIGNED_COMPARE_SLOW*/ | #endif |
| CodeTabOf(i) = free_ent++; /* code -> hashtable */ | CodeTabOf(i) = free_ent++; /* code -> hashtable */ |
| HashTabOf(i) = fcode; | HashTabOf(i) = fcode; |
| } else | } else |
| cl_block(); | cl_block(); |
| } | |
| /* | |
| * Put out the final code. | |
| */ | |
| output((code_int)ent ); | |
| ++out_count; | |
| 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 GIFBITS 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. | |
| */ | |
| static unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, | |
| 0x001F, 0x003F, 0x007F, 0x00FF, | |
| 0x01FF, 0x03FF, 0x07FF, 0x0FFF, | |
| 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; | |
| void | |
| gdGifEncoder::output(code_int code) | |
| { | |
| cur_accum &= masks[ cur_bits ]; | |
| if( cur_bits > 0 ) | |
| cur_accum |=((long)code << cur_bits); | |
| else | |
| cur_accum = code; | |
| cur_bits += n_bits; | |
| while( cur_bits >= 8 ) { | |
| char_out((unsigned int)(cur_accum & 0xff) ); | |
| cur_accum >>= 8; | |
| cur_bits -= 8; | |
| } | |
| /* | |
| * If the next entry is going to be too big for the code size, | |
| * then increase it, if possible. | |
| */ | |
| if( free_ent > maxcode || clear_flg ) { | |
| if( clear_flg ) { | |
| maxcode = MAXCODE(n_bits = g_init_bits); | |
| clear_flg = 0; | |
| } else { | |
| ++n_bits; | |
| if( n_bits == maxbits ) | |
| maxcode = maxmaxcode; | |
| else | |
| maxcode = MAXCODE(n_bits); | |
| } | |
| } | |
| if( code == EOFCode ) { | |
| /* | |
| * At EOF, write the rest of the buffer. | |
| */ | |
| while( cur_bits > 0 ) { | |
| char_out((unsigned int)(cur_accum & 0xff) ); | |
| cur_accum >>= 8; | |
| cur_bits -= 8; | |
| } | |
| flush_char(); | |
| fflush( g_outfile ); | |
| if( ferror( g_outfile ) ) | |
| return; | |
| } | |
| } | } |
| /* | /* |
| * Clear out the hash table | * Put out the final code. |
| */ | */ |
| void | output((code_int)ent ); |
| gdGifEncoder::cl_block(void) /* table clear for block compress */ | ++out_count; |
| { | output((code_int) EOFCode ); |
| } | |
| cl_hash((count_int) hsize ); | |
| free_ent = ClearCode + 2; | /***************************************************************** |
| clear_flg = 1; | * TAG( output ) |
| * | |
| output((code_int)ClearCode ); | * 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 GIFBITS 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. | |
| */ | |
| static unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, | |
| 0x001F, 0x003F, 0x007F, 0x00FF, | |
| 0x01FF, 0x03FF, 0x07FF, 0x0FFF, | |
| 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; | |
| void | |
| gdGifEncoder::output(code_int code) | |
| { | |
| cur_accum &= masks[ cur_bits ]; | |
| void | if( cur_bits > 0 ) |
| gdGifEncoder::cl_hash(register count_int hsize) /* reset code table */ | cur_accum |=((long)code << cur_bits); |
| else | |
| { | cur_accum = code; |
| register count_int *htab_p = htab+hsize; | |
| register long i; | |
| register long m1 = -1; | |
| i = hsize - 16; | |
| do { /* might use Sys V memset(3) here */ | |
| *(htab_p-16) = m1; | |
| *(htab_p-15) = m1; | |
| *(htab_p-14) = m1; | |
| *(htab_p-13) = m1; | |
| *(htab_p-12) = m1; | |
| *(htab_p-11) = m1; | |
| *(htab_p-10) = m1; | |
| *(htab_p-9) = m1; | |
| *(htab_p-8) = m1; | |
| *(htab_p-7) = m1; | |
| *(htab_p-6) = m1; | |
| *(htab_p-5) = m1; | |
| *(htab_p-4) = m1; | |
| *(htab_p-3) = m1; | |
| *(htab_p-2) = m1; | |
| *(htab_p-1) = m1; | |
| htab_p -= 16; | |
| } while((i -= 16) >= 0); | |
| for( i += 16; i > 0; --i ) | |
| *--htab_p = m1; | |
| } | |
| /****************************************************************************** | cur_bits += n_bits; |
| * | |
| * GIF Specific routines | |
| * | |
| ******************************************************************************/ | |
| /* | while( cur_bits >= 8 ) { |
| * Set up the 'byte output' routine | char_out((unsigned int)(cur_accum & 0xff) ); |
| */ | cur_accum >>= 8; |
| void | cur_bits -= 8; |
| gdGifEncoder::char_init(void) | |
| { | |
| a_count = 0; | |
| } | } |
| /* | /* |
| * Add a character to the end of the current packet, and if it is 254 | * If the next entry is going to be too big for the code size, |
| * characters, flush the packet to disk. | * then increase it, if possible. |
| */ | */ |
| void | if( free_ent > maxcode || clear_flg ) { |
| gdGifEncoder::char_out(int c) | |
| { | if( clear_flg ) { |
| accum[ a_count++ ] = c; | |
| if( a_count >= 254 ) | maxcode = MAXCODE(n_bits = g_init_bits); |
| flush_char(); | clear_flg = 0; |
| } else { | |
| ++n_bits; | |
| if( n_bits == maxbits ) | |
| maxcode = maxmaxcode; | |
| else | |
| maxcode = MAXCODE(n_bits); | |
| } | |
| } | } |
| if( code == EOFCode ) { | |
| /* | /* |
| * Flush the packet to disk, and reset the accumulator | * At EOF, write the rest of the buffer. |
| */ | */ |
| void | while( cur_bits > 0 ) { |
| gdGifEncoder::flush_char(void) | char_out((unsigned int)(cur_accum & 0xff) ); |
| { | cur_accum >>= 8; |
| if( a_count > 0 ) { | cur_bits -= 8; |
| fputc( a_count, g_outfile ); | |
| fwrite( accum, 1, a_count, g_outfile ); | |
| a_count = 0; | |
| } | } |
| } | |
| flush_char(); | |
| } | |
| } | |
| /* | |
| * Clear out the hash table | |
| */ | |
| void | |
| gdGifEncoder::cl_block(void) /* table clear for block compress */ | |
| { | |
| gdGifEncoder::gdGifEncoder(Pool& pool, gdImage& aim) : Pooled(pool), | cl_hash((count_int) hsize ); |
| im(aim) { | free_ent = ClearCode + 2; |
| /* Some of these are properly initialized later. What I'm doing | clear_flg = 1; |
| here is making sure code that depends on C's initialization | |
| of statics doesn't break when the code gets called more | output((code_int)ClearCode ); |
| than once. */ | } |
| Width = 0; | |
| Height = 0; | void |
| curx = 0; | gdGifEncoder::cl_hash(count_int hsize) /* reset code table */ |
| cury = 0; | |
| CountDown = 0; | { |
| Pass = 0; | |
| Interlace = 0; | |
| a_count = 0; | |
| cur_accum = 0; | |
| cur_bits = 0; | |
| g_init_bits = 0; | |
| g_outfile = 0; | |
| ClearCode = 0; | |
| EOFCode = 0; | |
| free_ent = 0; | |
| clear_flg = 0; | |
| offset = 0; | |
| in_count = 1; | |
| out_count = 0; | |
| hsize = HSIZE; | |
| n_bits = 0; | |
| maxbits = GIFBITS; | |
| maxcode = 0; | |
| maxmaxcode =(code_int)1 << GIFBITS; | |
| } | |
| register count_int *htab_p = htab+hsize; | |
| /* +-------------------------------------------------------------------+ */ | register long i; |
| /* | Copyright 1990, 1991, 1993, David Koblas.(koblas@netcom.com) | */ | register long m1 = -1; |
| /* | Permission to use, copy, modify, and distribute this software | */ | |
| /* | and its documentation for any purpose and without fee is hereby | */ | |
| /* | granted, provided that the above copyright notice appear in all | */ | |
| /* | copies and that both that copyright notice and this permission | */ | |
| /* | notice appear in supporting documentation. This software is | */ | |
| /* | provided "as is" without express or implied warranty. | */ | |
| /* +-------------------------------------------------------------------+ */ | |
| i = hsize - 16; | |
| do { /* might use Sys V memset(3) here */ | |
| *(htab_p-16) = m1; | |
| *(htab_p-15) = m1; | |
| *(htab_p-14) = m1; | |
| *(htab_p-13) = m1; | |
| *(htab_p-12) = m1; | |
| *(htab_p-11) = m1; | |
| *(htab_p-10) = m1; | |
| *(htab_p-9) = m1; | |
| *(htab_p-8) = m1; | |
| *(htab_p-7) = m1; | |
| *(htab_p-6) = m1; | |
| *(htab_p-5) = m1; | |
| *(htab_p-4) = m1; | |
| *(htab_p-3) = m1; | |
| *(htab_p-2) = m1; | |
| *(htab_p-1) = m1; | |
| htab_p -= 16; | |
| } while((i -= 16) >= 0); | |
| for( i += 16; i > 0; --i ) | |
| *--htab_p = m1; | |
| } | |
| /****************************************************************************** | |
| * | |
| * GIF Specific routines | |
| * | |
| ******************************************************************************/ | |
| /* | |
| * Set up the 'byte output' routine | |
| */ | |
| void | |
| gdGifEncoder::char_init(void) | |
| { | |
| a_count = 0; | |
| } | |
| /* | |
| * Add a character to the end of the current packet, and if it is 254 | |
| * characters, flush the packet to disk. | |
| */ | |
| void | |
| gdGifEncoder::char_out(int c) | |
| { | |
| accum[ a_count++ ] = c; | |
| if( a_count >= 254 ) | |
| flush_char(); | |
| } | |
| /* | |
| * Flush the packet to disk, and reset the accumulator | |
| */ | |
| void | |
| gdGifEncoder::flush_char(void) | |
| { | |
| if( a_count > 0 ) { | |
| Putbyte( a_count ); | |
| Write( accum, a_count); | |
| a_count = 0; | |
| } | |
| } | |
| gdGifEncoder::gdGifEncoder(Pool& apool, gdImage& aim, String& afp): pool(apool), | |
| im(aim), | |
| fp(afp) { | |
| /* Some of these are properly initialized later. What I'm doing | |
| here is making sure code that depends on C's initialization | |
| of statics doesn't break when the code gets called more | |
| than once. */ | |
| Width = 0; | |
| Height = 0; | |
| curx = 0; | |
| cury = 0; | |
| CountDown = 0; | |
| Pass = 0; | |
| Interlace = 0; | |
| a_count = 0; | |
| cur_accum = 0; | |
| cur_bits = 0; | |
| g_init_bits = 0; | |
| ClearCode = 0; | |
| EOFCode = 0; | |
| free_ent = 0; | |
| clear_flg = 0; | |
| offset = 0; | |
| in_count = 1; | |
| out_count = 0; | |
| hsize = HSIZE; | |
| n_bits = 0; | |
| maxbits = GIFBITS; | |
| maxcode = 0; | |
| maxmaxcode =(code_int)1 << GIFBITS; | |
| } | |
| /* +-------------------------------------------------------------------+ */ | |
| /* | Copyright 1990, 1991, 1993, David Koblas.(koblas@netcom.com) | */ | |
| /* | Permission to use, copy, modify, and distribute this software | */ | |
| /* | and its documentation for any purpose and without fee is hereby | */ | |
| /* | granted, provided that the above copyright notice appear in all | */ | |
| /* | copies and that both that copyright notice and this permission | */ | |
| /* | notice appear in supporting documentation. This software is | */ | |
| /* | provided "as is" without express or implied warranty. | */ | |
| /* +-------------------------------------------------------------------+ */ | |
| #define MAXCOLORMAPSIZE 256 | #define MAXCOLORMAPSIZE 256 |
| #ifndef TRUE | |
| #define TRUE 1 | #define TRUE 1 |
| #endif | |
| #ifndef FALSE | |
| #define FALSE 0 | #define FALSE 0 |
| #endif | |
| #define CM_RED 0 | #define CM_RED 0 |
| #define CM_GREEN 1 | #define CM_GREEN 1 |
| Line 727 nomatch: | Line 760 nomatch: |
| unsigned int AspectRatio; | unsigned int AspectRatio; |
| }; | }; |
| #endif | #endif |
| /// Graphic Control Extension struct | |
| #ifndef DOXYGEN | |
| struct Gif89 { | struct Gif89 { |
| int transparent; | int transparent; |
| int delayTime; | int delayTime; |
| int inputFlag; | int inputFlag; |
| int disposal; | int disposal; |
| }; | }; |
| #endif | |
| static int ReadColorMap(FILE *fd, int number, unsigned char(*buffer)[256]); | static int ReadColorMap(FILE *fd, int number, unsigned char(*buffer)[256]); |
| static int GetCode(FILE *fd, int code_size, int flag); | static int GetCode(FILE *fd, int code_size, int flag); |