Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

943 lines
23 KiB

  1. /* ppmtogif.c - read a portable pixmap and produce a GIF file
  2. **
  3. ** Based on GIFENCOD by David Rowley <mgardi@watdscu.waterloo.edu>.A
  4. ** Lempel-Zim compression based on "compress".
  5. **
  6. ** Modified by Marcel Wijkstra <wijkstra@fwi.uva.nl>
  7. */
  8. #include "ppm.h"
  9. #include "ppmcmap.h"
  10. #define MAXCOLORS 256
  11. /*
  12. * Pointer to function returning an int
  13. */
  14. typedef int (* ifunptr) ARGS((int, int));
  15. /*
  16. * a code_int must be able to hold 2**BITS values of type int, and also -1
  17. */
  18. typedef int code_int;
  19. #ifdef SIGNED_COMPARE_SLOW
  20. typedef unsigned long int count_int;
  21. typedef unsigned short int count_short;
  22. #else /*SIGNED_COMPARE_SLOW*/
  23. typedef long int count_int;
  24. #endif /*SIGNED_COMPARE_SLOW*/
  25. static int colorstobpp ARGS(( int colors ));
  26. static int GetPixel ARGS(( int x, int y ));
  27. static void BumpPixel ARGS(( void ));
  28. static int GIFNextPixel ARGS(( ifunptr getpixel ));
  29. static void GIFEncode ARGS(( FILE* fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int* Red, int* Green, int* Blue, ifunptr GetPixel ));
  30. int Red[MAXCOLORS],Green[MAXCOLORS],Blue[MAXCOLORS],perm[MAXCOLORS],permi[MAXCOLORS];
  31. int colors;
  32. pixval maxtmp;
  33. static void Putword ARGS(( int w, FILE* fp ));
  34. static void compress ARGS(( int init_bits, FILE* outfile, ifunptr ReadValue ));
  35. static void output ARGS(( code_int code ));
  36. static void cl_block ARGS(( void ));
  37. static void cl_hash ARGS(( count_int hsize ));
  38. static void writeerr ARGS(( void ));
  39. static void char_init ARGS(( void ));
  40. static void char_out ARGS(( int c ));
  41. static void flush_char ARGS(( void ));
  42. static int sqr ARGS((int x));
  43. static int closestcolor ARGS((pixel color));
  44. static pixel** pixels;
  45. static colorhash_table cht;
  46. int
  47. main( argc, argv )
  48. int argc;
  49. char* argv[];
  50. {
  51. FILE* ifp;
  52. int argn, rows, cols, i,j,k, BitsPerPixel;
  53. int interlace, sort, map, transparent;
  54. pixel transcolor;
  55. char *mapfile;
  56. pixval maxval;
  57. colorhist_vector chv;
  58. char* usage = "[-interlace] [-sort] [-map mapfile] [-transparent color] [ppmfile]";
  59. ppm_init( &argc, argv );
  60. argn = 1;
  61. interlace = 0;
  62. sort = 0;
  63. map = 0;
  64. transparent = -1;
  65. while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  66. {
  67. if ( pm_keymatch( argv[argn], "-interlace", 2 ) )
  68. interlace = 1;
  69. else if ( pm_keymatch( argv[argn], "-nointerlace", 2 ) )
  70. interlace = 0;
  71. else if ( pm_keymatch( argv[argn], "-sort", 2 ) )
  72. sort = 1;
  73. else if ( pm_keymatch( argv[argn], "-map", 2 ) ) {
  74. map = 1;
  75. if (++argn < argc)
  76. mapfile = argv[argn];
  77. else pm_usage(usage); }
  78. else if ( pm_keymatch( argv[argn], "-transparent", 2 ) ) {
  79. transparent = 1;
  80. if (++argn < argc)
  81. transcolor = ppm_parsecolor( argv[argn], 255 );
  82. else
  83. pm_usage(usage);
  84. }
  85. else
  86. pm_usage( usage );
  87. ++argn;
  88. }
  89. /* Read the colormap from another file. */
  90. if (map) {
  91. ifp = pm_openr(mapfile);
  92. pixels = ppm_readppm( ifp, &cols, &rows, &maxval );
  93. pm_close( ifp );
  94. /* Figure out the colormap from the <mapfile>. */
  95. pm_message( "computing other colourmap..." );
  96. chv = ppm_computecolorhist( pixels, cols, rows, MAXCOLORS, &colors );
  97. ppm_freearray(pixels,rows); }
  98. if ( argn < argc )
  99. {
  100. ifp = pm_openr( argv[argn] );
  101. ++argn;
  102. }
  103. else
  104. ifp = stdin;
  105. if ( argn != argc )
  106. pm_usage( usage );
  107. pixels = ppm_readppm( ifp, &cols, &rows, &maxtmp );
  108. if (!map)
  109. maxval=maxtmp;
  110. pm_close( ifp );
  111. /* Figure out the colormap. */
  112. if (!map) {
  113. pm_message( "computing colourmap..." );
  114. chv = ppm_computecolorhist( pixels, cols, rows, MAXCOLORS, &colors ); }
  115. if ( chv == (colorhist_vector) 0 )
  116. pm_error(
  117. "too many colors - try doing a 'ppmquant %d'", MAXCOLORS );
  118. pm_message( "%d colours found", colors );
  119. /* Now turn the ppm colormap into the appropriate GIF colormap. */
  120. if ( maxval > 255 )
  121. pm_message(
  122. "maxval is not 255 - automatically rescaling colors" );
  123. for ( i = 0; i < colors; ++i )
  124. {
  125. if ( maxval == 255 )
  126. {
  127. Red[i] = PPM_GETR( chv[i].color );
  128. Green[i] = PPM_GETG( chv[i].color );
  129. Blue[i] = PPM_GETB( chv[i].color );
  130. }
  131. else
  132. {
  133. Red[i] = (int) PPM_GETR( chv[i].color ) * 255 / maxval;
  134. Green[i] = (int) PPM_GETG( chv[i].color ) * 255 / maxval;
  135. Blue[i] = (int) PPM_GETB( chv[i].color ) * 255 / maxval;
  136. }
  137. }
  138. /* Sort the colormap */
  139. for (i=0;i<colors;i++)
  140. permi[i]=i;
  141. if (sort) {
  142. pm_message("sorting colourmap");
  143. for (i=0;i<colors;i++)
  144. for (j=i+1;j<colors;j++)
  145. if (((Red[i]*MAXCOLORS)+Green[i])*MAXCOLORS+Blue[i] >
  146. ((Red[j]*MAXCOLORS)+Green[j])*MAXCOLORS+Blue[j]) {
  147. k=permi[i]; permi[i]=permi[j]; permi[j]=k;
  148. k=Red[i]; Red[i]=Red[j]; Red[j]=k;
  149. k=Green[i]; Green[i]=Green[j]; Green[j]=k;
  150. k=Blue[i]; Blue[i]=Blue[j]; Blue[j]=k; } }
  151. for (i=0;i<colors;i++)
  152. perm[permi[i]]=i;
  153. BitsPerPixel = colorstobpp( colors );
  154. /* And make a hash table for fast lookup. */
  155. cht = ppm_colorhisttocolorhash( chv, colors );
  156. ppm_freecolorhist( chv );
  157. /* figure out the transparent colour index */
  158. if (transparent > 0) {
  159. transparent = ppm_lookupcolor( cht, &transcolor );
  160. if (transparent == -1)
  161. transparent = closestcolor( transcolor );
  162. else
  163. transparent = perm[transparent];
  164. }
  165. /* All set, let's do it. */
  166. GIFEncode(
  167. stdout, cols, rows, interlace, 0, transparent, BitsPerPixel,
  168. Red, Green, Blue, GetPixel );
  169. exit( 0 );
  170. }
  171. static int
  172. colorstobpp( colors )
  173. int colors;
  174. {
  175. int bpp;
  176. if ( colors <= 2 )
  177. bpp = 1;
  178. else if ( colors <= 4 )
  179. bpp = 2;
  180. else if ( colors <= 8 )
  181. bpp = 3;
  182. else if ( colors <= 16 )
  183. bpp = 4;
  184. else if ( colors <= 32 )
  185. bpp = 5;
  186. else if ( colors <= 64 )
  187. bpp = 6;
  188. else if ( colors <= 128 )
  189. bpp = 7;
  190. else if ( colors <= 256 )
  191. bpp = 8;
  192. else
  193. pm_error( "can't happen" );
  194. return bpp;
  195. }
  196. static int
  197. sqr(x)
  198. int x;
  199. {
  200. return x*x;
  201. }
  202. static int
  203. closestcolor(color)
  204. pixel color;
  205. {
  206. int i,r,g,b,d,
  207. imin,dmin;
  208. r=(int)PPM_GETR(color)*255/maxtmp;
  209. g=(int)PPM_GETG(color)*255/maxtmp;
  210. b=(int)PPM_GETB(color)*255/maxtmp;
  211. dmin=1000000;
  212. for (i=0;i<colors;i++) {
  213. d=sqr(r-Red[i])+sqr(g-Green[i])+sqr(b-Blue[i]);
  214. if (d<dmin) {
  215. dmin=d;
  216. imin=i; } }
  217. ppm_addtocolorhash(cht,&color,permi[imin]);
  218. return imin;
  219. }
  220. static int
  221. GetPixel( x, y )
  222. int x, y;
  223. {
  224. int color;
  225. color = ppm_lookupcolor( cht, &pixels[y][x] );
  226. if (color == -1)
  227. color = closestcolor(pixels[y][x]);
  228. else
  229. color=perm[color];
  230. return color;
  231. }
  232. /*****************************************************************************
  233. *
  234. * GIFENCODE.C - GIF Image compression interface
  235. *
  236. * GIFEncode( FName, GHeight, GWidth, GInterlace, Background, Transparent,
  237. * BitsPerPixel, Red, Green, Blue, GetPixel )
  238. *
  239. *****************************************************************************/
  240. #define TRUE 1
  241. #define FALSE 0
  242. static int Width, Height;
  243. static int curx, cury;
  244. static long CountDown;
  245. static int Pass = 0;
  246. static int Interlace;
  247. /*
  248. * Bump the 'curx' and 'cury' to point to the next pixel
  249. */
  250. static void
  251. BumpPixel()
  252. {
  253. /*
  254. * Bump the current X position
  255. */
  256. ++curx;
  257. /*
  258. * If we are at the end of a scan line, set curx back to the beginning
  259. * If we are interlaced, bump the cury to the appropriate spot,
  260. * otherwise, just increment it.
  261. */
  262. if( curx == Width ) {
  263. curx = 0;
  264. if( !Interlace )
  265. ++cury;
  266. else {
  267. switch( Pass ) {
  268. case 0:
  269. cury += 8;
  270. if( cury >= Height ) {
  271. ++Pass;
  272. cury = 4;
  273. }
  274. break;
  275. case 1:
  276. cury += 8;
  277. if( cury >= Height ) {
  278. ++Pass;
  279. cury = 2;
  280. }
  281. break;
  282. case 2:
  283. cury += 4;
  284. if( cury >= Height ) {
  285. ++Pass;
  286. cury = 1;
  287. }
  288. break;
  289. case 3:
  290. cury += 2;
  291. break;
  292. }
  293. }
  294. }
  295. }
  296. /*
  297. * Return the next pixel from the image
  298. */
  299. static int
  300. GIFNextPixel( getpixel )
  301. ifunptr getpixel;
  302. {
  303. int r;
  304. if( CountDown == 0 )
  305. return EOF;
  306. --CountDown;
  307. r = ( * getpixel )( curx, cury );
  308. BumpPixel();
  309. return r;
  310. }
  311. /* public */
  312. static void
  313. GIFEncode( fp, GWidth, GHeight, GInterlace, Background, Transparent,
  314. BitsPerPixel, Red, Green, Blue, GetPixel )
  315. FILE* fp;
  316. int GWidth, GHeight;
  317. int GInterlace;
  318. int Background;
  319. int Transparent;
  320. int BitsPerPixel;
  321. int Red[], Green[], Blue[];
  322. ifunptr GetPixel;
  323. {
  324. int B;
  325. int RWidth, RHeight;
  326. int LeftOfs, TopOfs;
  327. int Resolution;
  328. int ColorMapSize;
  329. int InitCodeSize;
  330. int i;
  331. Interlace = GInterlace;
  332. ColorMapSize = 1 << BitsPerPixel;
  333. RWidth = Width = GWidth;
  334. RHeight = Height = GHeight;
  335. LeftOfs = TopOfs = 0;
  336. Resolution = BitsPerPixel;
  337. /*
  338. * Calculate number of bits we are expecting
  339. */
  340. CountDown = (long)Width * (long)Height;
  341. /*
  342. * Indicate which pass we are on (if interlace)
  343. */
  344. Pass = 0;
  345. /*
  346. * The initial code size
  347. */
  348. if( BitsPerPixel <= 1 )
  349. InitCodeSize = 2;
  350. else
  351. InitCodeSize = BitsPerPixel;
  352. /*
  353. * Set up the current x and y position
  354. */
  355. curx = cury = 0;
  356. /*
  357. * Write the Magic header
  358. */
  359. fwrite( Transparent < 0 ? "GIF87a" : "GIF89a", 1, 6, fp );
  360. /*
  361. * Write out the screen width and height
  362. */
  363. Putword( RWidth, fp );
  364. Putword( RHeight, fp );
  365. /*
  366. * Indicate that there is a global colour map
  367. */
  368. B = 0x80; /* Yes, there is a color map */
  369. /*
  370. * OR in the resolution
  371. */
  372. B |= (Resolution - 1) << 5;
  373. /*
  374. * OR in the Bits per Pixel
  375. */
  376. B |= (BitsPerPixel - 1);
  377. /*
  378. * Write it out
  379. */
  380. fputc( B, fp );
  381. /*
  382. * Write out the Background colour
  383. */
  384. fputc( Background, fp );
  385. /*
  386. * Byte of 0's (future expansion)
  387. */
  388. fputc( 0, fp );
  389. /*
  390. * Write out the Global Colour Map
  391. */
  392. for( i=0; i<ColorMapSize; ++i ) {
  393. fputc( Red[i], fp );
  394. fputc( Green[i], fp );
  395. fputc( Blue[i], fp );
  396. }
  397. /*
  398. * Write out extension for transparent colour index, if necessary.
  399. */
  400. if ( Transparent >= 0 ) {
  401. fputc( '!', fp );
  402. fputc( 0xf9, fp );
  403. fputc( 4, fp );
  404. fputc( 1, fp );
  405. fputc( 0, fp );
  406. fputc( 0, fp );
  407. fputc( Transparent, fp );
  408. fputc( 0, fp );
  409. }
  410. /*
  411. * Write an Image separator
  412. */
  413. fputc( ',', fp );
  414. /*
  415. * Write the Image header
  416. */
  417. Putword( LeftOfs, fp );
  418. Putword( TopOfs, fp );
  419. Putword( Width, fp );
  420. Putword( Height, fp );
  421. /*
  422. * Write out whether or not the image is interlaced
  423. */
  424. if( Interlace )
  425. fputc( 0x40, fp );
  426. else
  427. fputc( 0x00, fp );
  428. /*
  429. * Write out the initial code size
  430. */
  431. fputc( InitCodeSize, fp );
  432. /*
  433. * Go and actually compress the data
  434. */
  435. compress( InitCodeSize+1, fp, GetPixel );
  436. /*
  437. * Write out a Zero-length packet (to end the series)
  438. */
  439. fputc( 0, fp );
  440. /*
  441. * Write the GIF file terminator
  442. */
  443. fputc( ';', fp );
  444. /*
  445. * And close the file
  446. */
  447. fclose( fp );
  448. }
  449. /*
  450. * Write out a word to the GIF file
  451. */
  452. static void
  453. Putword( w, fp )
  454. int w;
  455. FILE* fp;
  456. {
  457. fputc( w & 0xff, fp );
  458. fputc( (w / 256) & 0xff, fp );
  459. }
  460. /***************************************************************************
  461. *
  462. * GIFCOMPR.C - GIF Image compression routines
  463. *
  464. * Lempel-Ziv compression based on 'compress'. GIF modifications by
  465. * David Rowley (mgardi@watdcsu.waterloo.edu)
  466. *
  467. ***************************************************************************/
  468. /*
  469. * General DEFINEs
  470. */
  471. #define BITS 12
  472. #define HSIZE 5003 /* 80% occupancy */
  473. #ifdef NO_UCHAR
  474. typedef char char_type;
  475. #else /*NO_UCHAR*/
  476. typedef unsigned char char_type;
  477. #endif /*NO_UCHAR*/
  478. /*
  479. *
  480. * GIF Image compression - modified 'compress'
  481. *
  482. * Based on: compress.c - File compression ala IEEE Computer, June 1984.
  483. *
  484. * By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
  485. * Jim McKie (decvax!mcvax!jim)
  486. * Steve Davies (decvax!vax135!petsd!peora!srd)
  487. * Ken Turkowski (decvax!decwrl!turtlevax!ken)
  488. * James A. Woods (decvax!ihnp4!ames!jaw)
  489. * Joe Orost (decvax!vax135!petsd!joe)
  490. *
  491. */
  492. #include <ctype.h>
  493. #define ARGVAL() (*++(*argv) || (--argc && *++argv))
  494. static int n_bits; /* number of bits/code */
  495. static int maxbits = BITS; /* user settable max # bits/code */
  496. static code_int maxcode; /* maximum code, given n_bits */
  497. static code_int maxmaxcode = (code_int)1 << BITS; /* should NEVER generate this code */
  498. #ifdef COMPATIBLE /* But wrong! */
  499. # define MAXCODE(n_bits) ((code_int) 1 << (n_bits) - 1)
  500. #else /*COMPATIBLE*/
  501. # define MAXCODE(n_bits) (((code_int) 1 << (n_bits)) - 1)
  502. #endif /*COMPATIBLE*/
  503. static count_int htab [HSIZE];
  504. static unsigned short codetab [HSIZE];
  505. #define HashTabOf(i) htab[i]
  506. #define CodeTabOf(i) codetab[i]
  507. static code_int hsize = HSIZE; /* for dynamic table sizing */
  508. /*
  509. * To save much memory, we overlay the table used by compress() with those
  510. * used by decompress(). The tab_prefix table is the same size and type
  511. * as the codetab. The tab_suffix table needs 2**BITS characters. We
  512. * get this from the beginning of htab. The output stack uses the rest
  513. * of htab, and contains characters. There is plenty of room for any
  514. * possible stack (stack used to be 8000 characters).
  515. */
  516. #define tab_prefixof(i) CodeTabOf(i)
  517. #define tab_suffixof(i) ((char_type*)(htab))[i]
  518. #define de_stack ((char_type*)&tab_suffixof((code_int)1<<BITS))
  519. static code_int free_ent = 0; /* first unused entry */
  520. /*
  521. * block compression parameters -- after all codes are used up,
  522. * and compression rate changes, start over.
  523. */
  524. static int clear_flg = 0;
  525. static int offset;
  526. static long int in_count = 1; /* length of input */
  527. static long int out_count = 0; /* # of codes output (for debugging) */
  528. /*
  529. * compress stdin to stdout
  530. *
  531. * Algorithm: use open addressing double hashing (no chaining) on the
  532. * prefix code / next character combination. We do a variant of Knuth's
  533. * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
  534. * secondary probe. Here, the modular division first probe is gives way
  535. * to a faster exclusive-or manipulation. Also do block compression with
  536. * an adaptive reset, whereby the code table is cleared when the compression
  537. * ratio decreases, but after the table fills. The variable-length output
  538. * codes are re-sized at this point, and a special CLEAR code is generated
  539. * for the decompressor. Late addition: construct the table according to
  540. * file size for noticeable speed improvement on small files. Please direct
  541. * questions about this implementation to ames!jaw.
  542. */
  543. static int g_init_bits;
  544. static FILE* g_outfile;
  545. static int ClearCode;
  546. static int EOFCode;
  547. static void
  548. compress( init_bits, outfile, ReadValue )
  549. int init_bits;
  550. FILE* outfile;
  551. ifunptr ReadValue;
  552. {
  553. register long fcode;
  554. register code_int i /* = 0 */;
  555. register int c;
  556. register code_int ent;
  557. register code_int disp;
  558. register code_int hsize_reg;
  559. register int hshift;
  560. /*
  561. * Set up the globals: g_init_bits - initial number of bits
  562. * g_outfile - pointer to output file
  563. */
  564. g_init_bits = init_bits;
  565. g_outfile = outfile;
  566. /*
  567. * Set up the necessary values
  568. */
  569. offset = 0;
  570. out_count = 0;
  571. clear_flg = 0;
  572. in_count = 1;
  573. maxcode = MAXCODE(n_bits = g_init_bits);
  574. ClearCode = (1 << (init_bits - 1));
  575. EOFCode = ClearCode + 1;
  576. free_ent = ClearCode + 2;
  577. char_init();
  578. ent = GIFNextPixel( ReadValue );
  579. hshift = 0;
  580. for ( fcode = (long) hsize; fcode < 65536L; fcode *= 2L )
  581. ++hshift;
  582. hshift = 8 - hshift; /* set hash code range bound */
  583. hsize_reg = hsize;
  584. cl_hash( (count_int) hsize_reg); /* clear hash table */
  585. output( (code_int)ClearCode );
  586. #ifdef SIGNED_COMPARE_SLOW
  587. while ( (c = GIFNextPixel( ReadValue )) != (unsigned) EOF ) {
  588. #else /*SIGNED_COMPARE_SLOW*/
  589. while ( (c = GIFNextPixel( ReadValue )) != EOF ) { /* } */
  590. #endif /*SIGNED_COMPARE_SLOW*/
  591. ++in_count;
  592. fcode = (long) (((long) c << maxbits) + ent);
  593. i = (((code_int)c << hshift) ^ ent); /* xor hashing */
  594. if ( HashTabOf (i) == fcode ) {
  595. ent = CodeTabOf (i);
  596. continue;
  597. } else if ( (long)HashTabOf (i) < 0 ) /* empty slot */
  598. goto nomatch;
  599. disp = hsize_reg - i; /* secondary hash (after G. Knott) */
  600. if ( i == 0 )
  601. disp = 1;
  602. probe:
  603. if ( (i -= disp) < 0 )
  604. i += hsize_reg;
  605. if ( HashTabOf (i) == fcode ) {
  606. ent = CodeTabOf (i);
  607. continue;
  608. }
  609. if ( (long)HashTabOf (i) > 0 )
  610. goto probe;
  611. nomatch:
  612. output ( (code_int) ent );
  613. ++out_count;
  614. ent = c;
  615. #ifdef SIGNED_COMPARE_SLOW
  616. if ( (unsigned) free_ent < (unsigned) maxmaxcode) {
  617. #else /*SIGNED_COMPARE_SLOW*/
  618. if ( free_ent < maxmaxcode ) { /* } */
  619. #endif /*SIGNED_COMPARE_SLOW*/
  620. CodeTabOf (i) = free_ent++; /* code -> hashtable */
  621. HashTabOf (i) = fcode;
  622. } else
  623. cl_block();
  624. }
  625. /*
  626. * Put out the final code.
  627. */
  628. output( (code_int)ent );
  629. ++out_count;
  630. output( (code_int) EOFCode );
  631. }
  632. /*****************************************************************
  633. * TAG( output )
  634. *
  635. * Output the given code.
  636. * Inputs:
  637. * code: A n_bits-bit integer. If == -1, then EOF. This assumes
  638. * that n_bits =< (long)wordsize - 1.
  639. * Outputs:
  640. * Outputs code to the file.
  641. * Assumptions:
  642. * Chars are 8 bits long.
  643. * Algorithm:
  644. * Maintain a BITS character long buffer (so that 8 codes will
  645. * fit in it exactly). Use the VAX insv instruction to insert each
  646. * code in turn. When the buffer fills up empty it and start over.
  647. */
  648. static unsigned long cur_accum = 0;
  649. static int cur_bits = 0;
  650. static unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F,
  651. 0x001F, 0x003F, 0x007F, 0x00FF,
  652. 0x01FF, 0x03FF, 0x07FF, 0x0FFF,
  653. 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
  654. static void
  655. output( code )
  656. code_int code;
  657. {
  658. cur_accum &= masks[ cur_bits ];
  659. if( cur_bits > 0 )
  660. cur_accum |= ((long)code << cur_bits);
  661. else
  662. cur_accum = code;
  663. cur_bits += n_bits;
  664. while( cur_bits >= 8 ) {
  665. char_out( (unsigned int)(cur_accum & 0xff) );
  666. cur_accum >>= 8;
  667. cur_bits -= 8;
  668. }
  669. /*
  670. * If the next entry is going to be too big for the code size,
  671. * then increase it, if possible.
  672. */
  673. if ( free_ent > maxcode || clear_flg ) {
  674. if( clear_flg ) {
  675. maxcode = MAXCODE (n_bits = g_init_bits);
  676. clear_flg = 0;
  677. } else {
  678. ++n_bits;
  679. if ( n_bits == maxbits )
  680. maxcode = maxmaxcode;
  681. else
  682. maxcode = MAXCODE(n_bits);
  683. }
  684. }
  685. if( code == EOFCode ) {
  686. /*
  687. * At EOF, write the rest of the buffer.
  688. */
  689. while( cur_bits > 0 ) {
  690. char_out( (unsigned int)(cur_accum & 0xff) );
  691. cur_accum >>= 8;
  692. cur_bits -= 8;
  693. }
  694. flush_char();
  695. fflush( g_outfile );
  696. if( ferror( g_outfile ) )
  697. writeerr();
  698. }
  699. }
  700. /*
  701. * Clear out the hash table
  702. */
  703. static void
  704. cl_block () /* table clear for block compress */
  705. {
  706. cl_hash ( (count_int) hsize );
  707. free_ent = ClearCode + 2;
  708. clear_flg = 1;
  709. output( (code_int)ClearCode );
  710. }
  711. static void
  712. cl_hash(hsize) /* reset code table */
  713. register count_int hsize;
  714. {
  715. register count_int *htab_p = htab+hsize;
  716. register long i;
  717. register long m1 = -1;
  718. i = hsize - 16;
  719. do { /* might use Sys V memset(3) here */
  720. *(htab_p-16) = m1;
  721. *(htab_p-15) = m1;
  722. *(htab_p-14) = m1;
  723. *(htab_p-13) = m1;
  724. *(htab_p-12) = m1;
  725. *(htab_p-11) = m1;
  726. *(htab_p-10) = m1;
  727. *(htab_p-9) = m1;
  728. *(htab_p-8) = m1;
  729. *(htab_p-7) = m1;
  730. *(htab_p-6) = m1;
  731. *(htab_p-5) = m1;
  732. *(htab_p-4) = m1;
  733. *(htab_p-3) = m1;
  734. *(htab_p-2) = m1;
  735. *(htab_p-1) = m1;
  736. htab_p -= 16;
  737. } while ((i -= 16) >= 0);
  738. for ( i += 16; i > 0; --i )
  739. *--htab_p = m1;
  740. }
  741. static void
  742. writeerr()
  743. {
  744. pm_error( "error writing output file" );
  745. }
  746. /******************************************************************************
  747. *
  748. * GIF Specific routines
  749. *
  750. ******************************************************************************/
  751. /*
  752. * Number of characters so far in this 'packet'
  753. */
  754. static int a_count;
  755. /*
  756. * Set up the 'byte output' routine
  757. */
  758. static void
  759. char_init()
  760. {
  761. a_count = 0;
  762. }
  763. /*
  764. * Define the storage for the packet accumulator
  765. */
  766. static char accum[ 256 ];
  767. /*
  768. * Add a character to the end of the current packet, and if it is 254
  769. * characters, flush the packet to disk.
  770. */
  771. static void
  772. char_out( c )
  773. int c;
  774. {
  775. accum[ a_count++ ] = c;
  776. if( a_count >= 254 )
  777. flush_char();
  778. }
  779. /*
  780. * Flush the packet to disk, and reset the accumulator
  781. */
  782. static void
  783. flush_char()
  784. {
  785. if( a_count > 0 ) {
  786. fputc( a_count, g_outfile );
  787. fwrite( accum, 1, a_count, g_outfile );
  788. a_count = 0;
  789. }
  790. }
  791. /* The End */