版主
  
主题
帖子
积分10609
阅读权限200
注册时间2008-11-22
最后登录1970-1-1
在线时间 小时
|

楼主 |
发表于 2009-4-13 20:46
|
显示全部楼层
研究了好一段时间了终于明白了8成的原理了!这个东西可能没有多少人会看上的可能太复杂的吧呵呵,没所谓吧反正这个以后可以自己重温一下!下面是这个的C语言:
8 t, e9 |, d- z ( X1 t+ z2 K1 Y9 I
$ [1 t }& E3 T3 K
/* DECODE.C - An LZW decoder for GIF- x0 g' j s; |/ Z" p' A
* Copyright (C) 1987, by Steven A. Bennett
+ F! i& V+ h! u8 y) P) E *' M* o1 J! l) v% p4 L
* Permission is given by the author to freely redistribute and include; K+ |) c# M! c/ o+ Z: [
* this code in any program as long as this credit is given where due.
! |, N/ @7 J- T/ D *( I r- N6 g) D: c
* In accordance with the above, I want to credit Steve Wilhite who wrote$ T9 m0 e3 g4 Y' j
* the code which this is heavily inspired by...
+ B. t' C& h- q" r *; x) h0 `2 w5 u6 F1 p$ m2 z, p( V
* GIF and 'Graphics Interchange Format' are trademarks (tm) of
: i0 I7 C) F* z: t * Compuserve, Incorporated, an H&R Block Company.0 C' h8 y! ]& I0 }1 h& c- X( ^+ Z
*, J+ C9 o& m9 q x
* Release Notes: This file contains a decoder routine for GIF images
" [" R7 t2 j: f/ D+ Q$ s * which is similar, structurally, to the original routine by Steve Wilhite.! Y( K% R3 s u4 I1 q
* It is, however, somewhat noticably faster in most cases.
8 v9 n1 B3 m$ V4 ?% [ *
( X2 M* J0 U$ w" h */! H# V0 ~2 _/ N' w
$ A& t! n1 E/ D+ g2 f#include "std.h"! p: R9 `9 d! o& i& D0 t( T
#include "errs.h"; z6 r/ ^: k, ~: Y' q. x9 K# h# V
. c! Z& c2 a' _ p0 P a
IMPORT TEXT *malloc(); /* Standard C library allocation */! L% U0 t3 _8 N0 q2 O. V
% c' C/ q- o5 w3 O$ |9 L* @
/* IMPORT INT get_byte()2 t* G0 \6 f% A6 L. y; a7 l
*
; ?6 F! Z& [: m! E * - This external (machine specific) function is expected to return
) o% ~+ U! A5 D2 Z * either the next byte from the GIF file, or a negative number, as4 h' H- O% O. b0 r
* defined in ERRS.H.. Q. o) i: B( u6 p" r% k
*/$ D5 D" v8 v! ]! r4 o
IMPORT INT get_byte();) w6 K; Z# e6 s* a) P
. z7 n4 p( ?4 E( M' U
/* IMPORT INT out_line(pixels, linelen): s+ H7 E; r+ r
* UBYTE pixels[];
" M1 S2 S' p7 q- F, S) { R * INT linelen;; U, d. J& X. e) X
*7 G3 A/ _% ]9 z' a, }
* - This function takes a full line of pixels (one byte per pixel) and
9 H0 e( M2 O/ ]$ @: M * displays them (or does whatever your program wants with them...). It
2 }+ h' d' C6 y9 U * should return zero, or negative if an error or some other event occurs
6 i6 Y( A3 Q1 M, V0 G6 Q C * which would require aborting the decode process... Note that the length
& R1 R: k" t3 S/ f/ t4 d. t! N * passed will almost always be equal to the line length passed to the
7 G7 f! X$ f) O+ F2 d * decoder function, with the sole exception occurring when an ending code
3 H7 Y$ u0 T& o$ {2 P0 J% t * occurs in an odd place in the GIF file... In any case, linelen will be0 U) C+ N/ Q* d2 Z! ?* e
* equal to the number of pixels passed...
/ ^4 `. f6 T$ m$ j *// t7 t) H* U6 C
IMPORT INT out_line();. s* q5 _8 C( O/ ^- w& t# }
?% [' D/ S1 Y, a/* IMPORT INT bad_code_count;$ G8 ^- v% }4 d2 |4 t
*; ?, Y% v* s* O- v/ p" _
* This value is the only other global required by the using program, and
9 z! U6 p5 D1 y- j5 }& z * is incremented each time an out of range code is read by the decoder.
+ j \: D% R6 a( q * When this value is non-zero after a decode, your GIF file is probably7 g' l! G- {+ B4 M5 U
* corrupt in some way...
- ], o8 v2 g! u' v */: y+ p3 D1 m6 G( M+ [7 x& E" T! s
IMPORT INT bad_code_count;# Z" H( g2 Q2 Z, R: x7 F* ~
1 T% D. a3 z( W" S9 M#define NULL 0L# t; s( w6 C1 ]; x+ f& v
#define MAX_CODES 4095
T" L1 {6 l' Z8 T& q% I( ]8 ?5 O- M. w# x* j) n+ l
/* Static variables */
0 H7 C u7 b- LLOCAL WORD curr_size; /* The current code size */; ~8 H; w- H/ F- ], w9 @
LOCAL WORD clear; /* Value for a clear code */
Y% [+ [8 K. y9 d9 e% @( @LOCAL WORD ending; /* Value for a ending code */
" j2 H) V. \" B2 jLOCAL WORD newcodes; /* First available code */, ^; t/ e7 {% k" G
LOCAL WORD top_slot; /* Highest code for current size */
* L$ j2 }0 f; P3 s4 P8 ?LOCAL WORD slot; /* Last read code */& r7 \+ [7 z3 y' R3 K8 e
' Y2 }3 S; {& x+ W: R* |/* The following static variables are used
" c C0 q0 E3 t2 n [. {4 V8 U6 @ * for seperating out codes
4 {$ R4 t" Y* S: a/ F; c */
; P$ V9 W+ k' h/ u: zLOCAL WORD navail_bytes = 0; /* # bytes left in block */, z1 Q* O9 Z* S! T
LOCAL WORD nbits_left = 0; /* # bits left in current byte */
2 D6 W" B$ w1 ^& Q8 Y! [ g$ iLOCAL UTINY b1; /* Current byte */
+ J. R& Y% ~3 \: x: J! W( r4 {LOCAL UTINY byte_buff[257]; /* Current block */
4 ~/ {, H8 o# n7 t- y3 KLOCAL UTINY *pbytes; /* Pointer to next byte in block */
3 u% K( R& t5 \+ ~$ |- X3 o1 A w$ F3 G7 T
LOCAL LONG code_mask[13] = {
% O6 ?; b, H3 `1 F( n) W6 p( r 0,1 R* P" R5 z# _1 q
0x0001, 0x0003,6 x& e5 ^4 o& W. h3 z4 J* S, F
0x0007, 0x000F,
! t; o1 T6 U) e) a* R% Q( l, }) }2 _ 0x001F, 0x003F,
0 i! n! r! `4 C" r 0x007F, 0x00FF,3 E$ y; Z5 {* c4 j
0x01FF, 0x03FF,
' I% ]; F% s, T; p7 E0 C- s' U 0x07FF, 0x0FFF- Q+ w3 V3 C3 }
};
% w/ G" n; h: W4 t: Q. r5 m. B
) Z$ B6 j; s( L( w$ W( |
: X: u% p( U2 s/ g: n/* This function initializes the decoder for reading a new image.1 \. D$ D2 o) t' B
*/+ ~( [$ O2 z3 ?6 t$ W" R& F
LOCAL WORD init_exp(size)) R- M/ l# M% [! I( ~+ o
WORD size;
* L1 p, Q$ S! Z {4 Y5 c+ H/ ^8 m) S, j( Q2 m
curr_size = size + 1;
9 D5 v# a0 f) G. K: Q; y+ E top_slot = 1 << curr_size;; u/ g: Q' o) { b4 H$ R. t
clear = 1 << size;
8 P! Y/ l1 U+ M) u/ A& d" S ending = clear + 1;
9 I1 Y( |3 f5 E. P, c3 e slot = newcodes = ending + 1;
: m: m& I- m/ P4 | navail_bytes = nbits_left = 0;
7 n- r( e+ x9 N4 ^; t return(0);
: a0 G( N4 k1 C }6 d0 G, l5 _& [9 y! X7 l
% @- R( _! b' f0 u! W' e9 e" Q6 ]/* get_next_code()
5 k9 r3 o" Q" L * - gets the next code from the GIF file. Returns the code, or else0 P1 u w8 c8 a7 ?9 c% |" H. X
* a negative number in case of file errors...
5 Z( {* d: O3 V3 A- ] */
! J* E0 c3 U" ^8 f- }$ R" |$ TLOCAL WORD get_next_code()
- M) j2 `, j, i4 p- r) h* o {
0 Y* G# [' h% I0 F WORD i, x;- V* L) z$ L, |* m# f4 k
ULONG ret;
1 {! ]0 V- V' d" _4 N3 X+ F/ b5 j8 h
if (nbits_left == 0)* U( ^1 h; R! E8 W
{
8 T" X- B' T, s& F0 _ ~5 E if (navail_bytes <= 0)- x4 |( d! F5 u6 ^
{
$ `$ x6 B6 K" y# d/ f+ b7 z, J" H4 X( [& U/ P
/* Out of bytes in current block, so read next block. I V7 n4 y" ~" [% g$ m
*/! `* A7 `7 _+ D8 j! a' g
pbytes = byte_buff;9 n4 p: ]3 Y6 u! \6 V
if ((navail_bytes = get_byte()) < 0)
2 }- O) f7 f" C: d return(navail_bytes);
8 j! ^! c d- P+ H& T else if (navail_bytes)3 K4 c7 F2 J7 B
{* b# Y( |- n9 @
for (i = 0; i < navail_bytes; ++i)! Y% o! ~5 i4 t* F
{# Q N9 o% }- J: |9 [
if ((x = get_byte()) < 0)
1 ~9 e1 J2 |# M5 e; A* G return(x);& {+ V7 e7 k$ }
byte_buff = x;
( O6 _# K0 X( L |0 {$ x5 P& R }* I0 }1 }$ v8 g$ J, C6 R$ ?
}
4 y4 _. b# K( K9 ^) h8 L }
: F T% t% B3 p" D, @ b1 = *pbytes++;9 d+ L- b8 `1 ~. d) s$ N! Z
nbits_left = 8;
) Z" Y$ j, f; U --navail_bytes;
! Y- Y. j% Y: \ J; b }
& p F5 B2 P; h0 I0 `- M0 d/ I
# V# v( y8 r' w' E ret = b1 >> (8 - nbits_left);8 T9 g7 N9 }) N
while (curr_size > nbits_left)
! c4 E) _+ k7 @- ^+ j9 l {5 x4 k8 [: `6 C! U4 |6 }; S" O
if (navail_bytes <= 0)
, w7 `2 ]: d* Y, S6 f* T) e {
; u5 U% _/ ^$ m. J! N2 ]1 z6 F# ]) d5 f6 `/ ?' ]( ]) j( x& {
/* Out of bytes in current block, so read next block
3 I/ y0 ^3 t8 S% V3 c */% {; v" B6 N4 P7 u
pbytes = byte_buff;3 h# J" a9 N0 k' U% O- E' ?* p
if ((navail_bytes = get_byte()) < 0) ~2 J5 o3 ^* l' r) E
return(navail_bytes);
& s) U( d2 v& V) r; \ else if (navail_bytes)8 Z) v/ k2 r0 A2 ^& A
{9 W! w) `& A ?) c( g0 H
for (i = 0; i < navail_bytes; ++i)
6 y8 [- B" Y7 |8 q: G {$ G0 e; E3 V) m ^$ r* t# ~
if ((x = get_byte()) < 0)
6 v4 Y0 N4 b5 z1 X6 Y T return(x);
8 ?8 W1 R0 Y% R byte_buff = x;: u5 [6 \7 c- @; ^6 C7 N+ u
}
6 ^. c$ b9 l& O4 z$ Y( E }
5 K( p- Z5 M% ^ }
. S# Z' V4 f- F* q' _ b1 = *pbytes++;: z* o" f! M. j
ret |= b1 << nbits_left;% I7 K9 }- F' r5 o3 {
nbits_left += 8;
( g* E: [4 C2 W) Y. X --navail_bytes;$ ~2 @5 U) B6 P- d
}
6 p/ y" Q5 v, y! \ nbits_left -= curr_size;0 `4 J# M Y9 S& ?" P/ C
ret &= code_mask[curr_size];
1 N& _; m$ O1 m- }' R9 p% ] return((WORD)(ret));
( ~! N/ k# a, A7 t' r }
/ z. s3 N+ ^; z$ G
/ r6 j+ B6 q7 t- m3 G0 s' \; l$ _! r# s8 x/ ~7 H
/* The reason we have these seperated like this instead of using# Z. B: J" @4 h) O' M6 n6 p; R5 H ]
* a structure like the original Wilhite code did, is because this
7 ~& c* L# H& S/ I6 I * stuff generally produces significantly faster code when compiled...
9 A4 n. b, m8 f! w E/ T- N7 \ * This code is full of similar speedups... (For a good book on writing
6 z0 f" B& i$ _+ V' ^" C * C for speed or for space optomisation, see Efficient C by Tom Plum,$ {4 G" X! z" d# l7 j; s
* published by Plum-Hall Associates...)
' e; r. c+ O: e& N: I* j9 Y */
) z7 @* H5 Q3 gLOCAL UTINY stack[MAX_CODES + 1]; /* Stack for storing pixels */. R( i$ T1 O( r! Z' n6 _
LOCAL UTINY suffix[MAX_CODES + 1]; /* Suffix table */9 j8 T6 f" W$ {2 w4 \3 w5 I
LOCAL UWORD prefix[MAX_CODES + 1]; /* Prefix linked list */5 Q7 g" |' ^+ ~
; o ]# O4 |# r/ E) W0 `
/* WORD decoder(linewidth)& Q# _- C! ]1 r7 r. o. }+ H3 m
* WORD linewidth; * Pixels per line of image *& ?. O" d0 f, g$ B* f# w' X
*' Q( ]4 G% T f% p: e
* - This function decodes an LZW image, according to the method used4 n- y P6 h' A( W3 e
* in the GIF spec. Every *linewidth* "characters" (ie. pixels) decoded
( e5 B' a) L" f, W4 I$ b b; I+ p" b * will generate a call to out_line(), which is a user specific function/ T( M* F$ E2 e3 v& W3 v) [
* to display a line of pixels. The function gets it's codes from% S( d. G( `$ C4 S# v
* get_next_code() which is responsible for reading blocks of data and. o1 g3 L2 [5 K
* seperating them into the proper size codes. Finally, get_byte() is
" a1 @( x# P# ~$ D: R * the global routine to read the next byte from the GIF file.
! ]+ _% K* L9 T" N2 N1 ]- ~ *8 @3 |' Q+ |& M" W
* It is generally a good idea to have linewidth correspond to the actual, N# d: h& G0 N8 Z
* width of a line (as specified in the Image header) to make your own y5 v6 ]! g& T, _7 ~0 H0 e3 Z' ]8 X
* code a bit simpler, but it isn't absolutely necessary.1 X, R* M g! Z+ f$ H8 g' M
* C" W/ O/ S' A: @! Q, c
* Returns: 0 if successful, else negative. (See ERRS.H)
! x$ a) Z: h0 i4 X+ m *! W) _4 k; w6 `7 V$ e
*/
4 P9 f6 w7 Y1 q) p
5 Z, |. [0 g! Z! E( l* u. E* {WORD decoder(linewidth)! a/ o; [2 e0 B& y* H4 `
WORD linewidth;
9 c2 a% z1 t4 U: |" { {
% j9 `# s1 m4 u) ]6 F FAST UTINY *sp, *bufptr;/ d( U1 E& Z$ R v! u
UTINY *buf;9 O% o$ q5 }4 X# I4 q
FAST WORD code, fc, oc, bufcnt;
7 C; E0 S; T5 e2 f* j+ S- @8 S WORD c, size, ret;) {( G3 D6 G- m: c0 a
: D4 [ z8 U9 s r- H S /* Initialize for decoding a new image...) D+ ^5 W; W+ k/ P) x
*/+ s4 @$ Y& Z# c
if ((size = get_byte()) < 0)
! d; N4 S3 k. L' c4 M, D1 r' O return(size);
5 M% o$ O+ W' N; H$ F if (size < 2 || 9 < size)
8 A3 C9 w$ R- a0 \ return(BAD_CODE_SIZE);' C) [# \" [+ c0 G+ ?8 R
init_exp(size);
+ X3 F% M' |* P3 R4 D0 I3 ~% }" |4 U" k: X6 C4 w x
/* Initialize in case they forgot to put in a clear code.
! j3 ]$ I8 C& }. n * (This shouldn't happen, but we'll try and decode it anyway...)- i8 x2 g d+ t" w( B" h4 E
*/! ~9 p( U/ z% s
oc = fc = 0;
" v- U# d2 j$ |* w( e! _3 t1 K& e/ a3 I0 E
/* Allocate space for the decode buffer
7 }: f$ K# M4 n5 H# x* N: x @6 g */( t T. n( u+ ]5 W% Q. D0 R
if ((buf = (UTINY *)malloc(linewidth + 1)) == NULL)
/ ^' ^5 Z4 D2 _% D# K return(OUT_OF_MEMORY);
4 a* T5 ~: w0 }; Q( s
( p/ B/ G- ]+ r8 h: \ /* Set up the stack pointer and decode buffer pointer) |/ @( L. | X1 U
*/
9 o' M7 k( L A6 t) K& C sp = stack;
: q* ]( z3 O( l' a8 P5 ^ bufptr = buf;
$ C' ] A8 H, V7 t- u0 e bufcnt = linewidth;
2 d% h0 {/ r( d& o
; ~& [9 x4 J# D/ q Y5 O" c9 i/ ] /* This is the main loop. For each code we get we pass through the4 t1 s9 `: P* ^% a* u. W$ p9 L4 k' {
* linked list of prefix codes, pushing the corresponding "character" for
$ D. L% V+ n. ~* r4 a) t& k1 W& F( J * each code onto the stack. When the list reaches a single "character"4 p5 U$ T( d: j7 o' X7 z! r
* we push that on the stack too, and then start unstacking each$ G. O, A& K/ y4 z& ?
* character for output in the correct order. Special handling is" b7 o" E7 M6 r$ t
* included for the clear code, and the whole thing ends when we get9 i; U9 s! b/ ?
* an ending code.
9 w" X, H* O4 ~1 w( ~' D8 r; u4 L */ C. L7 V( ]) k2 D! ~9 d1 w
while ((c = get_next_code()) != ending)( C% C6 |' J- S2 }- B, b* W# _% V- d
{
$ v& F' Q) C' E
5 L; n# K) Z- N) t /* If we had a file error, return without completing the decode
2 s0 I# |' o6 s */
3 X! N6 w, }/ ~2 n) b if (c < 0)5 ]$ R3 f$ q7 m0 `
{
4 @+ F( _0 G' ~% N5 h free(buf);# b' g% M/ u/ O4 `; e! @ k
return(0);: c: @& y b5 @6 q/ _
}
6 I Q& h8 F! z" ~. F' P1 L4 w+ |. ?5 R* r8 V% ?
/* If the code is a clear code, reinitialize all necessary items./ _; r5 F& M& R o
*/. B. \: o# S% h, z
if (c == clear)
3 S, }, x$ M' l {
3 @+ j) ^$ p2 M7 F2 d curr_size = size + 1;
( c; Y5 o* N8 e! F+ G z slot = newcodes;% k2 {: P( ?4 D0 t1 r0 f7 `
top_slot = 1 << curr_size;
2 S! H) w( y& E1 F4 \0 D: S# G9 ?1 _2 |0 k4 z
/* Continue reading codes until we get a non-clear code( o0 T$ U/ \. Y: }
* (Another unlikely, but possible case...)
+ N a m e; }; w J */
5 a( v! p% V/ A while ((c = get_next_code()) == clear)
& O: e( N/ l \# p$ _, G! h ;
: e4 q1 p* O; [' F: P$ N
& {' y9 M" a' l- B4 E% f8 B/ G /* If we get an ending code immediately after a clear code
! t/ F. V d" t * (Yet another unlikely case), then break out of the loop.
7 U: I" F5 R! {6 }6 Q* H5 }- \ */5 @2 v# n2 G5 k
if (c == ending)" E8 q. ^3 t: P2 l
break;
. ^& q, ?3 S* | {- n( w0 ]7 Z5 E+ G: E& ?
/* Finally, if the code is beyond the range of already set codes,% ?- f% F/ H) r; Z- P$ K) [$ p
* (This one had better NOT happen... I have no idea what will0 m! y+ X S3 m3 W* ]" u
* result from this, but I doubt it will look good...) then set it( V2 |4 G9 r/ ^9 `3 L
* to color zero.8 j7 h2 m6 ~ z- h! A
*/0 `4 B3 ^5 U! j
if (c >= slot)) t8 ^% ]2 b4 M* k
c = 0;
0 M5 a5 j( a1 \- Z/ t' q6 \5 P) E% G% e n/ T3 Y
oc = fc = c;: _1 A* I: D5 S' v( p0 t
0 I) k- s5 d5 @6 [7 i /* And let us not forget to put the char into the buffer... And
9 E! A7 k) [# `6 f! \ * if, on the off chance, we were exactly one pixel from the end! n8 C8 k/ Y# B& \
* of the line, we have to send the buffer to the out_line()
. O0 W% x# M3 n( W * routine...
" X9 S6 N0 N9 o+ j */
3 L3 U3 a! \! w. T; w1 X1 g *bufptr++ = c;
; b! U- I+ r1 x. \ if (--bufcnt == 0)7 ^0 G( F+ E# _. E; e; F! I- M4 p
{' S4 i# Z u: f2 r9 a/ p Y
if ((ret = out_line(buf, linewidth)) < 0)
- q- C" I* y& J# P: j9 u/ f {
! |1 d4 H7 q7 h. u3 Q" m8 J, ^% A free(buf);
% M" |% P# w9 R! ` return(ret);
. N6 `1 [; ?8 g5 u }* }+ u+ V8 Y% ?
bufptr = buf;, y* M! E' @2 T+ }; M# S+ e1 y1 ?
bufcnt = linewidth;: O+ k4 A1 H2 Q5 j
}
/ B+ b8 I* b2 w) p' {' D }
' V# R- G0 T7 R' D2 {( ?0 h else1 |0 t/ B) ?& Q8 V& a+ g
{6 E( a+ e5 J& f! q
# W' B( I2 k( `' k9 t& c6 C% } y6 }
/* In this case, it's not a clear code or an ending code, so
. H+ @: ?+ ^' L * it must be a code code... So we can now decode the code into
# q% Y# ]7 n) m* l# U+ v8 N( Y * a stack of character codes. (Clear as mud, right?)
* \; i& z6 ?7 g( A */
9 U' f# j5 z7 }% n% h code = c;* Z* x9 C7 w1 e# S3 T
, K, |8 z/ D* _, X0 Y, H /* Here we go again with one of those off chances... If, on the! U% O& W" D- f
* off chance, the code we got is beyond the range of those already7 B2 a) u K9 Z: J; Y j* v& n( V
* set up (Another thing which had better NOT happen...) we trick
$ k7 }+ D: `8 R+ N2 g * the decoder into thinking it actually got the last code read.1 G8 ?9 A) M$ p
* (Hmmn... I'm not sure why this works... But it does...)4 F4 M9 z( b4 r3 h
*/
# Y9 X4 @+ V* Z! `) p, r* \ if (code >= slot)
( H6 a0 b7 H; p {
; G) b/ K1 F' ^4 n if (code > slot)
$ Q6 j3 N6 `" M% S- F' n2 S ++bad_code_count;
0 ]+ M( }7 A. {0 {) t0 ? code = oc;
- Z/ ?. J+ f4 R$ \ *sp++ = fc;) ^% n- ^6 e; ^/ ?
}
% U% [6 P; K, \6 T, @, ^+ s6 t3 y; b& N+ X1 v
/* Here we scan back along the linked list of prefixes, pushing7 P3 U; n; u" u+ s! x* v) F
* helpless characters (ie. suffixes) onto the stack as we do so.2 y4 l1 Y2 c0 C# h
*/
( B5 b8 d/ q) \6 M6 s, N while (code >= newcodes)( F7 F) D1 i& h! J& H
{$ |0 `3 S0 w/ X' ]6 T
*sp++ = suffix[code];% }! u) w7 _4 T5 Q
code = prefix[code];5 Z% ^; A" g- I/ v$ i e* ~2 b
}
8 E8 O, Q4 o8 B" X5 j% u, z
3 A2 A+ }0 S5 {6 ?% p8 g /* Push the last character on the stack, and set up the new
0 v0 E* \% f% F" W. T2 @ * prefix and suffix, and if the required slot number is greater4 c5 J, q6 V$ E* |) J
* than that allowed by the current bit size, increase the bit
! D! x# {- Q" u2 W, x * size. (NOTE - If we are all full, we *don't* save the new
, e W: k8 G S, j * suffix and prefix... I'm not certain if this is correct...- c/ d2 z4 m+ j l
* it might be more proper to overwrite the last code...
! @; [0 I' {" l# O* f. v) }7 G5 p */
& E. Y3 P' F5 A *sp++ = code;% c' h# _3 N8 O. [) a% S4 @
if (slot < top_slot)8 v& l! f8 A. d; I
{7 C( U- N# b: ~0 e
suffix[slot] = fc = code;
8 M; q& c( k |/ @ prefix[slot++] = oc;
- z) |0 S0 z) [" [( l Q0 } oc = c;9 g( }% c* ~, o+ e$ j, f2 ]
}6 z. o' p/ W( K+ c+ ] I
if (slot >= top_slot)/ p5 l! F9 k" l% D
if (curr_size < 12)
$ R; T+ C) F$ i, x, B {
9 J& v% ?' x4 X. |) ^ top_slot <<= 1;
# Z, G# f: o$ z0 U" ]/ Z; X ++curr_size;2 T* N6 t/ N6 J
} : e9 t( {4 }& Q! k- x3 f% m) w) _
( L# H8 X; Q& b) Y& T3 b
/* Now that we've pushed the decoded string (in reverse order)
' S, @' U9 j# A: }) v5 p * onto the stack, lets pop it off and put it into our decode& r) ~5 S# K% x5 O+ A! c7 s
* buffer... And when the decode buffer is full, write another
; G+ s) p K/ u, `: o" [, S * line...# F0 e. `; ?% y0 d% J6 p( _
*/9 e6 b2 R" N3 \) ^5 g- P
while (sp > stack)
. J8 M8 [, T0 n {
9 R( {! O: a d: {1 _+ y *bufptr++ = *(--sp);- W4 ]! b( V) D8 a( R
if (--bufcnt == 0)
( `# A+ ]: L6 r3 b0 @( o% v' {! H {/ C2 r4 |$ a+ X3 i+ J
if ((ret = out_line(buf, linewidth)) < 0)3 j& F# d: R$ M3 a
{+ t# B9 f' N! A3 w1 D7 v
free(buf);
O1 k6 v9 ~. `5 _, x) z: f return(ret);, r1 o3 o/ m( _0 h" J
}
C! l7 l3 g8 F% @/ {. R5 z4 E bufptr = buf;' v9 c% {0 ^3 @: i5 f; ]6 a
bufcnt = linewidth;7 o; N4 t1 Z* _4 J( W+ o$ _
}
5 A# X Y j6 Z9 U# X3 J1 p }( Q& N# O. L+ Y
}
: Z# t' Y$ ?: N }- l0 p# X9 S4 ?6 v
ret = 0;
! s8 \1 p) r% J$ q& @6 o if (bufcnt != linewidth)
4 @4 O/ n7 M+ y% T+ g* h ret = out_line(buf, (linewidth - bufcnt));% K+ S8 a m N/ E1 o
free(buf);
1 T0 r8 u9 L4 t1 E return(ret);/ L; I! B5 a5 f% L0 n6 W# t E
} |
|