home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume20 / low-perc / part01 next >
Encoding:
Text File  |  1991-07-17  |  47.9 KB  |  1,504 lines

  1. Newsgroups: comp.sources.misc
  2. From: Radford Neal <radford@ai.toronto.edu>
  3. Subject:  v20i096:  low-perc - Low-precision arithmetic coding routines, Part01/01
  4. Message-ID: <1991Jul16.012844.21809@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: dfa067089e1e1408ffb0cff849157f04
  6. Date: Tue, 16 Jul 1991 01:28:44 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Radford Neal <radford@ai.toronto.edu>
  10. Posting-number: Volume 20, Issue 96
  11. Archive-name: low-perc/part01
  12.  
  13. The following is a README file for the 'shar' archive that follows.
  14.  
  15. The code is also available by anonymous ftp from fsa.cpsc.ucalgary.ca,
  16. in directory pub/arithmetic.coding/low.precision.version. Any updates
  17. will be placed there. 
  18.  
  19.  
  20.             LOW-PRECISION ARITHMETIC CODING IMPLEMENTATION
  21.  
  22.                       Radford M. Neal, July 1991
  23.  
  24.  
  25. This directory contains C source for an implementation of arithmetic
  26. coding using low-precision division. This division can be performed
  27. using shift/add operations, with potential savings in time on any
  28. machine without parallel multiply/divide hardware.
  29.  
  30. The implementation is based on that in the paper of Witten, Neal, and
  31. Cleary published in the June 1987 Communications of the ACM. Anyone
  32. wishing to understand this program is urged to first read that paper.
  33. Differences in this version are as follows:
  34.  
  35.     1) The arithmetic coding operations have been fiddled so that
  36.        the division involved can be done to very low precision.
  37.        There is a tradeoff between precision and compression performance,
  38.        but nearly optimal results are obtained with a precision of
  39.        six bits, and precisions of as low as three, bits give reasonable 
  40.        results. A precision of at least two bits is required for
  41.        correct operation.
  42.  
  43.     2) In order for (1) to be possible, the model is now required
  44.        to produce "partially normalized" frequencies, in which the
  45.        total for all symbols is always more than half the maximum 
  46.        allowed total. This is not onerous, at least for the models
  47.        used here.
  48.  
  49.     3) The model must also now arrainge for the most probable symbol
  50.        to have index 1. This was always the case, but previously
  51.        this was solely a matter of time efficiency. Now, failure
  52.        to do this would impact compression efficiency, though not 
  53.        correct operation.
  54.  
  55.     4) The precision to which symbol frequencies may be held is much
  56.        higher in this implementation - 27 bits with the default
  57.        parameter settings. The CACM implementation was restricted
  58.        to 14 bit frequencies. This is of significance in applications
  59.        where the number of symbols is large, such as with word-based
  60.        models.
  61.  
  62.     5) Encode/decode procedures specialized for use with a two-symbol
  63.        alphabet have been added. These are demonstrated by a simple
  64.        adaptive image compression program.
  65.  
  66.     6) Various minor modifications and structural changes to the
  67.        program have been made.
  68.  
  69. Two versions of the coding procedures are provided - one using C
  70. multiply and divide operators, the other using shifts and adds. These
  71. versions, and the resulting encode/decode programs, are distinguished
  72. by the suffixes "_mul" and "_sft". Which version is fastest will
  73. depend on the particular machine and compiler used. All encode/decode
  74. programs simply read from standard input and write to standard output.
  75.  
  76. The file 'tstpic' contains a test picture for the image
  77. encoding/decoding programs. The format of such pictures may be
  78. discerned by examination of this example, and of the program code.
  79.  
  80. A program for calculating a bound on maximum expected redundancy 
  81. resulting from low-precision division is included. Typical redundancy
  82. is much less than this bound.
  83.  
  84. For the multiply/divide version, the requirement that the model
  85. produce partially normalized frequencies is not really necessary.
  86.  
  87. The program is intended for demonstation purposes. It is not optimized
  88. for time efficiency, and provides little in the way of error checking.
  89.  
  90. This code is public domain, and may be used by anyone for any purpose.
  91. I do, however, expect that distributions utilizing this code will
  92. include an acknowledgement of its source. The program is provided
  93. without any warranty as to correct operation. To the best of my
  94. knowledge, the techniques used are free of any patent complications,
  95. but no guarantees are offered in this respect either.
  96.  
  97. Address comments to:    
  98.    
  99.        Radford Neal
  100.        Dept. of Computer Science
  101.        University of Toronto
  102.        10 King's College Road
  103.        Toronto, Ontario, CANADA
  104.        M5S 1A4
  105.  
  106.        e-mail: radford@ai.toronto.edu
  107.  
  108.  
  109. ---- cut here and feed to sh ----
  110. #! /bin/sh
  111. # This is a shell archive.  Remove anything before this line, then unpack
  112. # it by saving it into a file and typing "sh file".  To overwrite existing
  113. # files, type "sh file -c".  You can also feed this as standard input via
  114. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  115. # will see the following message at the end:
  116. #        "End of shell archive."
  117. # Contents:  Makefile bit_io.c code.h code_mul.c code_sft.c decode.c
  118. #   decpic.c encode.c encpic.c model.c model.h redundancy.c tstpic
  119. # Wrapped by ian@cpsc.ucalgary.ca on Mon Jul  8 14:09:11 1991
  120. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  121. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  122.   echo shar: Will not clobber existing file \"'Makefile'\"
  123. else
  124. echo shar: Extracting \"'Makefile'\" \(1205 characters\)
  125. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  126. XCFLAGS = -O
  127. X
  128. Xall:            encode_mul decode_mul encode_sft decode_sft \
  129. X            encpic_mul decpic_mul encpic_sft decpic_sft
  130. X
  131. X
  132. Xencode_mul:        encode.o model.o bit_io.o code_mul.o
  133. X            cc -O encode.o model.o bit_io.o code_mul.o -o encode_mul
  134. X
  135. Xdecode_mul:        decode.o model.o bit_io.o code_mul.o
  136. X            cc -O decode.o model.o bit_io.o code_mul.o -o decode_mul
  137. X
  138. Xencode_sft:        encode.o model.o bit_io.o code_sft.o
  139. X            cc -O encode.o model.o bit_io.o code_sft.o -o encode_sft
  140. X
  141. Xdecode_sft:        decode.o model.o bit_io.o code_sft.o
  142. X            cc -O decode.o model.o bit_io.o code_sft.o -o decode_sft
  143. X
  144. X
  145. Xencpic_mul:        encpic.o bit_io.o code_mul.o
  146. X            cc -O encpic.o bit_io.o code_mul.o -o encpic_mul
  147. X
  148. Xdecpic_mul:        decpic.o bit_io.o code_mul.o
  149. X            cc -O decpic.o bit_io.o code_mul.o -o decpic_mul
  150. X
  151. Xencpic_sft:        encpic.o bit_io.o code_sft.o
  152. X            cc -O encpic.o bit_io.o code_sft.o -o encpic_sft
  153. X
  154. Xdecpic_sft:        decpic.o bit_io.o code_sft.o
  155. X            cc -O decpic.o bit_io.o code_sft.o -o decpic_sft
  156. X
  157. X
  158. Xencode.o:        encode.c model.h code.h
  159. Xdecode.o:        decode.c model.h code.h
  160. Xmodel.o:        model.c model.h code.h
  161. X
  162. Xencpic.o:        encpic.c model.h code.h
  163. Xdecpic.o:        decpic.c model.h code.h
  164. X
  165. Xcode_mul.o:        code_mul.c code.h
  166. Xcode_sft.o:        code_sft.c code.h
  167. Xbit_io.o:        bit_io.c code.h
  168. END_OF_FILE
  169. if test 1205 -ne `wc -c <'Makefile'`; then
  170.     echo shar: \"'Makefile'\" unpacked with wrong size!
  171. fi
  172. # end of 'Makefile'
  173. fi
  174. if test -f 'bit_io.c' -a "${1}" != "-c" ; then 
  175.   echo shar: Will not clobber existing file \"'bit_io.c'\"
  176. else
  177. echo shar: Extracting \"'bit_io.c'\" \(1690 characters\)
  178. sed "s/^X//" >'bit_io.c' <<'END_OF_FILE'
  179. X/* BIT_IO.C - BIT INPUT/OUTPUT ROUTINES. */
  180. X
  181. X#include <stdio.h>
  182. X
  183. X#include "code.h"
  184. X
  185. X
  186. X/* THE BIT BUFFER. */
  187. X
  188. Xstatic int buffer;        /* Bits waiting to be input                 */
  189. Xstatic int bits_to_go;        /* Number of bits still in buffer           */
  190. X
  191. Xstatic int garbage;        /* Number of garbage bytes after EOF        */
  192. X
  193. X
  194. X/* INITIALIZE FOR BIT OUTPUT. */
  195. X
  196. Xstart_outputing_bits()
  197. X{
  198. X    buffer = 0;                    /* Buffer is empty to start */
  199. X    bits_to_go = 8;                /* with.                    */
  200. X}
  201. X
  202. X
  203. X/* INITIALIZE FOR BIT INPUT. */
  204. X
  205. Xstart_inputing_bits()
  206. X{
  207. X    bits_to_go = 0;                /* Buffer starts out with   */
  208. X    garbage = 0;                /* no bits in it.           */
  209. X}
  210. X
  211. X
  212. X/* OUTPUT A BIT. */
  213. X
  214. Xoutput_bit(bit)
  215. X    int bit;
  216. X{
  217. X    if (bits_to_go==0) {            /* Output buffer if it is   */
  218. X        putc(buffer,stdout);            /* full.                    */
  219. X        bits_to_go = 8;
  220. X    }
  221. X
  222. X    buffer >>= 1;                 /* Put bit in top of buffer.*/
  223. X    if (bit) buffer |= 0x80;
  224. X    bits_to_go -= 1;
  225. X}
  226. X
  227. X
  228. X/* INPUT A BIT. */
  229. X
  230. Xint input_bit()
  231. X{
  232. X    int t;
  233. X
  234. X    if (bits_to_go==0) {            /* Read next byte if no     */
  235. X        buffer = getc(stdin);            /* bits left in the buffer. */
  236. X        bits_to_go = 8;
  237. X        if (buffer==EOF) {              /* Return anything after    */
  238. X            if (garbage*8>=Code_bits) {        /* end-of-file, but not too */
  239. X                fprintf(stderr,"Bad input file (2)\n"); /* much of anything.*/
  240. X                exit(1);
  241. X            }
  242. X            garbage += 1;
  243. X        }
  244. X    }
  245. X
  246. X    t = buffer&1;                /* Return the next bit from */
  247. X    buffer >>= 1;                /* the bottom of the byte.  */
  248. X    bits_to_go -= 1;
  249. X    return t;    
  250. X}
  251. X
  252. X
  253. X/* FLUSH OUT THE LAST BITS. */
  254. X
  255. Xdone_outputing_bits()
  256. X{
  257. X    putc(buffer>>bits_to_go,stdout);
  258. X}
  259. END_OF_FILE
  260. if test 1690 -ne `wc -c <'bit_io.c'`; then
  261.     echo shar: \"'bit_io.c'\" unpacked with wrong size!
  262. fi
  263. # end of 'bit_io.c'
  264. fi
  265. if test -f 'code.h' -a "${1}" != "-c" ; then 
  266.   echo shar: Will not clobber existing file \"'code.h'\"
  267. else
  268. echo shar: Extracting \"'code.h'\" \(1328 characters\)
  269. sed "s/^X//" >'code.h' <<'END_OF_FILE'
  270. X/* CODE.H - DECLARATIONS USED FOR ARITHMETIC ENCODING AND DECODING */
  271. X
  272. X
  273. X/* PRECISION OF CODING VALUES. Coding values are fixed-point binary 
  274. X   fractions in the range [0,1), represented as integers scaled by 
  275. X   2^Code_bits. */
  276. X
  277. X#define Code_bits 32            /* Number of bits for code values   */
  278. X#define Code_quarter (1<<(Code_bits-2))    /* Quarter point for code values    */
  279. X#define Code_half (1<<(Code_bits-1))    /* Halfway point for code values    */
  280. X
  281. Xtypedef unsigned code_value;        /* Data type holding code values    */
  282. X
  283. X
  284. X/* PRECISION OF SYMBOL PROBABILITIES. Symbol probabilities must be partially
  285. X   normalized, so that the total for all symbols is in the range (1/2,1].
  286. X   These probabilities are represented as integers scaled by 2^Freq_bits. */
  287. X
  288. X#define Freq_bits 27            /* Number of bits for frequencies   */
  289. X#define Freq_half (1<<(Freq_bits-1))    /* Halfway point for frequencies    */
  290. X#define Freq_full (1<<Freq_bits)    /* Largest frequency value          */
  291. X
  292. Xtypedef unsigned freq_value;        /* Data type holding frequencies    */
  293. X
  294. X
  295. X/* PRECISION OF DIVISION. Division of a code value by a frequency value 
  296. X   gives a result of precision (Code_bits-Freq_bits), which must be at
  297. X   least two for correct operation (larger differences give smaller code
  298. X   size). */
  299. X
  300. Xtypedef unsigned div_value;        /* Data type for result of division */
  301. END_OF_FILE
  302. if test 1328 -ne `wc -c <'code.h'`; then
  303.     echo shar: \"'code.h'\" unpacked with wrong size!
  304. fi
  305. # end of 'code.h'
  306. fi
  307. if test -f 'code_mul.c' -a "${1}" != "-c" ; then 
  308.   echo shar: Will not clobber existing file \"'code_mul.c'\"
  309. else
  310. echo shar: Extracting \"'code_mul.c'\" \(7887 characters\)
  311. sed "s/^X//" >'code_mul.c' <<'END_OF_FILE'
  312. X/* CODE_MUL.C - ARITHMETIC ENCODING/DECODING, USING MULTIPLY/DIVIDE. */
  313. X
  314. X#include <stdio.h>
  315. X
  316. X#include "code.h"
  317. X
  318. X
  319. X/* CURRENT STATE OF THE ENCODING/DECODING. */
  320. X
  321. Xstatic code_value low;        /* Start of current coding region, in [0,1) */
  322. X
  323. Xstatic code_value range;    /* Size of region, normally kept in the     */
  324. X                /* interval [1/4,1/2]                       */
  325. X
  326. Xstatic code_value value;    /* Currently-seen code value, in [0,1)      */
  327. X
  328. Xstatic int bits_to_follow;    /* Number of opposite bits to output after  */
  329. X                /* the next bit                             */
  330. X
  331. Xstatic div_value F;        /* Common factor used, in interval [1/4,1)  */
  332. X
  333. Xstatic code_value split_region();
  334. X
  335. X
  336. X/* OUTPUT BIT PLUS FOLLOWING OPPOSITE BITS. */
  337. X
  338. X#define bit_plus_follow(bit) \
  339. Xdo { \
  340. X    output_bit(bit);                /* Output the bit.          */\
  341. X    while (bits_to_follow>0) {            /* Output bits_to_follow    */\
  342. X        output_bit(!(bit));            /* opposite bits. Set       */\
  343. X        bits_to_follow -= 1;            /* bits_to_follow to zero.  */\
  344. X    } \
  345. X} while (0) \
  346. X
  347. X
  348. X/* START ENCODING A STREAM OF SYMBOLS. */
  349. X
  350. Xstart_encoding()
  351. X{   
  352. X    low = Code_half;                /* Use half the code region */
  353. X    range = Code_half;                /* (wastes first bit as 1). */
  354. X    bits_to_follow = 0;                /* No opposite bits follow. */
  355. X}
  356. X
  357. X
  358. X/* START DECODING A STREAM OF SYMBOLS. */
  359. X
  360. Xstart_decoding()
  361. X{   
  362. X    int i;
  363. X
  364. X    value = input_bit();            /* Check that first bit     */
  365. X    if (value!=1) {                /* is a 1.                  */
  366. X        fprintf(stderr,"Bad input file (1)\n");
  367. X        exit(1);
  368. X    }
  369. X
  370. X    for (i = 1; i<Code_bits; i++) {         /* Fill the code value with */
  371. X        value += value;                /* input bits.              */
  372. X        value += input_bit();
  373. X    }
  374. X
  375. X    low = Code_half;                /* Use half the code region */
  376. X    range = Code_half;                /* (first bit must be 1).   */
  377. X}
  378. X
  379. X
  380. X/* ENCODE A SYMBOL. */
  381. X
  382. Xencode_symbol(symbol,cum_freq)
  383. X    int symbol;            /* Symbol to encode                         */
  384. X    freq_value cum_freq[];    /* Cumulative symbol frequencies            */
  385. X{
  386. X    narrow_region(cum_freq,symbol,0);        /* Narrow coding region.    */
  387. X    push_out_bits();                /* Output determined bits.  */
  388. X}
  389. X
  390. X
  391. X/* ENCODE A BIT. */
  392. X
  393. Xencode_bit(bit,freq0,freq1)
  394. X    int bit;            /* Bit to encode (0 or 1)                   */
  395. X    freq_value freq0;           /* Frequency for 0 bit                      */
  396. X    freq_value freq1;           /* Frequency for 1 bit                      */
  397. X{
  398. X    code_value split;
  399. X
  400. X    if (freq1>freq0) {                /* Encode bit when most     */
  401. X        split = split_region(freq0,freq1);    /* probable symbol is a 1.  */
  402. X        if (bit) { low += split; range -= split; }
  403. X        else     { range = split;  }
  404. X    }
  405. X
  406. X    else {                    /* Encode bit when most     */
  407. X        split = split_region(freq1,freq0);    /* probable symbol is a 0.  */
  408. X        if (bit) { range = split;  }
  409. X        else     { low += split; range -= split; }
  410. X    }
  411. X
  412. X    push_out_bits();                /* Output determined bits.  */
  413. X}
  414. X
  415. X
  416. X/* DECODE THE NEXT SYMBOL. */
  417. X
  418. Xint decode_symbol(cum_freq)
  419. X    freq_value cum_freq[];    /* Cumulative symbol frequencies            */
  420. X{
  421. X    int symbol;            /* Symbol decoded                           */
  422. X
  423. X    symbol = find_symbol(cum_freq);        /* Find decoded symbol.     */
  424. X    narrow_region(cum_freq,symbol,1);        /* Narrow coding region.    */
  425. X    discard_bits();                /* Discard output bits.     */
  426. X
  427. X    return symbol;
  428. X}
  429. X
  430. X
  431. X/* DECODE A BIT. */
  432. X
  433. Xint decode_bit(freq0,freq1)
  434. X    freq_value freq0;           /* Frequency for 0 bit                      */
  435. X    freq_value freq1;           /* Frequency for 1 bit                      */
  436. X{
  437. X    code_value split;
  438. X    int bit;
  439. X
  440. X    if (freq1>freq0) {                /* Decode bit when most     */
  441. X        split = split_region(freq0,freq1);    /* probable symbol is a 1.  */
  442. X        bit = value-low >= split;
  443. X        if (bit) { low += split; range -= split; }
  444. X        else     { range = split;  }
  445. X    }
  446. X
  447. X    else {                    /* Decode bit when most     */
  448. X        split = split_region(freq1,freq0);    /* probable symbol is a 0.  */
  449. X        bit = value-low < split;
  450. X        if (bit) { range = split;  }
  451. X        else     { low += split; range -= split; }
  452. X    }
  453. X
  454. X    discard_bits();                /* Discard output bits.     */
  455. X
  456. X    return bit;
  457. X}
  458. X
  459. X
  460. X/* DETERMINE DECODED SYMBOL FROM INPUT VALUE. */
  461. X
  462. Xstatic int find_symbol(cum_freq)
  463. X    freq_value cum_freq[];    /* Cumulative symbol frequencies            */
  464. X{
  465. X    freq_value cum;        /* Cumulative frequency calculated          */
  466. X    int symbol;            /* Symbol decoded                           */
  467. X
  468. X    F = range / cum_freq[0];            /* Compute common factor.   */
  469. X
  470. X    cum = (value-low) / F;            /* Compute target cum freq. */
  471. X    for (symbol = 1; cum_freq[symbol]>cum; symbol++) ; /* Then find symbol. */
  472. X
  473. X    return symbol;
  474. X}
  475. X
  476. X
  477. X/* NARROW CODING REGION TO THAT ALLOTTED TO SYMBOL. */
  478. X
  479. Xstatic narrow_region(cum_freq,symbol,have_F)
  480. X    freq_value cum_freq[];    /* Cumulative symbol frequencies            */
  481. X    int symbol;            /* Symbol decoded                           */
  482. X    int have_F;            /* Is F already computed?                   */
  483. X{
  484. X    code_value T;        /* Temporary value                          */
  485. X
  486. X    if (!have_F) F = range / cum_freq[0];    /* Compute common factor.   */
  487. X
  488. X    if (symbol==1) {                /* Narrow range for symbol  */
  489. X        T = F * cum_freq[symbol];        /* at the top.              */
  490. X        low += T;
  491. X        range -= T;
  492. X    }
  493. X
  494. X    else {                    /* Narrow range for symbol  */
  495. X        T = F * cum_freq[symbol];               /* not at the top.          */
  496. X        low += T;
  497. X        range = F * cum_freq[symbol-1] - T; 
  498. X    }
  499. X}
  500. X
  501. X
  502. X/* FIND BINARY SPLIT FOR CODING REGION. */
  503. X
  504. Xstatic code_value split_region(freq_b,freq_t)
  505. X    freq_value freq_b;        /* Frequency for symbol in bottom half      */
  506. X    freq_value freq_t;        /* Frequency for symbol in top half         */
  507. X{
  508. X    return freq_b * (range / (freq_b+freq_t)); 
  509. X}
  510. X
  511. X
  512. X/* OUTPUT BITS THAT ARE NOW DETERMINED. */
  513. X
  514. Xstatic push_out_bits()
  515. X{
  516. X    while (range<=Code_quarter) {
  517. X
  518. X        if (low>=Code_half) {            /* Output 1 if in top half.*/
  519. X            bit_plus_follow(1);
  520. X            low -= Code_half;            /* Subtract offset to top.  */
  521. X        }
  522. X
  523. X        else if (low+range<=Code_half) {    /* Output 0 in bottom half. */
  524. X            bit_plus_follow(0);        
  525. X    } 
  526. X
  527. X        else {                     /* Output an opposite bit   */
  528. X            bits_to_follow += 1;        /* later if in middle half. */
  529. X            low -= Code_quarter;        /* Subtract offset to middle*/
  530. X        } 
  531. X
  532. X        low += low;                /* Scale up code region.    */
  533. X        range += range;
  534. X    }
  535. X}
  536. X
  537. X
  538. X/* DISCARD BITS THE ENCODER WOULD HAVE OUTPUT. */
  539. X
  540. Xstatic discard_bits()
  541. X{
  542. X    while (range<=Code_quarter) {
  543. X
  544. X        if (low>=Code_half) {            /* Expand top half.         */
  545. X            low -= Code_half;            /* Subtract offset to top.  */
  546. X            value -= Code_half;
  547. X        }
  548. X
  549. X        else if (low+range<=Code_half) {    /* Expand bottom half.      */
  550. X            /* nothing */
  551. X    } 
  552. X
  553. X        else {                     /* Expand middle half.      */
  554. X            low -= Code_quarter;        /* Subtract offset to middle*/
  555. X            value -= Code_quarter;
  556. X        } 
  557. X
  558. X        low += low;                /* Scale up code region.    */
  559. X        range += range;
  560. X
  561. X        value += value;                /* Move in next input bit.  */
  562. X        value += input_bit();
  563. X    }
  564. X}
  565. X
  566. X
  567. X/* FINISH ENCODING THE STREAM. */
  568. X
  569. Xdone_encoding()
  570. X{   
  571. X    for (;;) {
  572. X
  573. X        if (low+(range>>1)>=Code_half) {    /* Output a 1 if mostly in  */
  574. X            bit_plus_follow(1);            /* top half.                */
  575. X            range = low+range-Code_half;
  576. X            low = low<Code_half ? 0 : low-Code_half;
  577. X        }
  578. X
  579. X        else {                    /* Output a 0 if mostly in  */
  580. X            bit_plus_follow(0);            /* bottom half.             */
  581. X            if (low+range>Code_half) {
  582. X                range = Code_half-low;
  583. X            }
  584. X        }
  585. X
  586. X        if (range==Code_half) break;        /* Quit when coding region  */
  587. X                        /* becomes entire interval. */
  588. X        low += low;
  589. X        range += range;                /* Scale up code region.    */
  590. X    }
  591. X}
  592. END_OF_FILE
  593. if test 7887 -ne `wc -c <'code_mul.c'`; then
  594.     echo shar: \"'code_mul.c'\" unpacked with wrong size!
  595. fi
  596. # end of 'code_mul.c'
  597. fi
  598. if test -f 'code_sft.c' -a "${1}" != "-c" ; then 
  599.   echo shar: Will not clobber existing file \"'code_sft.c'\"
  600. else
  601. echo shar: Extracting \"'code_sft.c'\" \(11930 characters\)
  602. sed "s/^X//" >'code_sft.c' <<'END_OF_FILE'
  603. X/* CODE_SFT.C - ARITHMETIC ENCODING/DECODING, USING SHIFT/ADD. */
  604. X
  605. X#include <stdio.h>
  606. X
  607. X#include "code.h"
  608. X
  609. X
  610. X/* CURRENT STATE OF THE ENCODING/DECODING. */
  611. X
  612. Xstatic code_value low;        /* Start of current coding region, in [0,1) */
  613. X
  614. Xstatic code_value range;    /* Size of region, normally kept in the     */
  615. X                /* interval [1/4,1/2]                       */
  616. X
  617. Xstatic code_value value;    /* Currently-seen code value, in [0,1)      */
  618. X
  619. Xstatic int bits_to_follow;    /* Number of opposite bits to output after  */
  620. X                /* the next bit                             */
  621. X
  622. Xstatic code_value split_region();
  623. X
  624. X
  625. X/* OUTPUT BIT PLUS FOLLOWING OPPOSITE BITS. */
  626. X
  627. X#define bit_plus_follow(bit) \
  628. Xdo { \
  629. X    output_bit(bit);                /* Output the bit.          */\
  630. X    while (bits_to_follow>0) {            /* Output bits_to_follow    */\
  631. X        output_bit(!(bit));            /* opposite bits. Set       */\
  632. X        bits_to_follow -= 1;            /* bits_to_follow to zero.  */\
  633. X    } \
  634. X} while (0) \
  635. X
  636. X
  637. X/* START ENCODING A STREAM OF SYMBOLS. */
  638. X
  639. Xstart_encoding()
  640. X{   
  641. X    low = Code_half;                /* Use half the code region */
  642. X    range = Code_half;                /* (wastes first bit as 1). */
  643. X    bits_to_follow = 0;                /* No opposite bits follow. */
  644. X}
  645. X
  646. X
  647. X/* START DECODING A STREAM OF SYMBOLS. */
  648. X
  649. Xstart_decoding()
  650. X{   
  651. X    int i;
  652. X
  653. X    value = input_bit();            /* Check that first bit     */
  654. X    if (value!=1) {                /* is a 1.                  */
  655. X        fprintf(stderr,"Bad input file (1)\n");
  656. X        exit(1);
  657. X    }
  658. X
  659. X    for (i = 1; i<Code_bits; i++) {         /* Fill the code value with */
  660. X        value += value;                /* input bits.              */
  661. X        value += input_bit();
  662. X    }
  663. X
  664. X    low = Code_half;                /* Use half the code region */
  665. X    range = Code_half;                /* (first bit must be 1).   */
  666. X}
  667. X
  668. X
  669. X/* ENCODE A SYMBOL. */
  670. X
  671. Xencode_symbol(symbol,cum_freq)
  672. X    int symbol;            /* Symbol to encode                         */
  673. X    freq_value cum_freq[];    /* Cumulative symbol frequencies            */
  674. X{
  675. X    narrow_region(cum_freq,symbol);        /* Narrow coding region.    */
  676. X    push_out_bits();                /* Output determined bits.  */
  677. X}
  678. X
  679. X
  680. X/* ENCODE A BIT. */
  681. X
  682. Xencode_bit(bit,freq0,freq1)
  683. X    int bit;            /* Bit to encode (0 or 1)                   */
  684. X    freq_value freq0;           /* Frequency for 0 bit                      */
  685. X    freq_value freq1;           /* Frequency for 1 bit                      */
  686. X{
  687. X    code_value split;
  688. X
  689. X    if (freq1>freq0) {                /* Encode bit when most     */
  690. X        split = split_region(freq0,freq1);    /* probable symbol is a 1.  */
  691. X        if (bit) { low += split; range -= split; }
  692. X        else     { range = split;  }
  693. X    }
  694. X
  695. X    else {                    /* Encode bit when most     */
  696. X        split = split_region(freq1,freq0);    /* probable symbol is a 0.  */
  697. X        if (bit) { range = split;  }
  698. X        else     { low += split; range -= split; }
  699. X    }
  700. X
  701. X    push_out_bits();                /* Output determined bits.  */
  702. X}
  703. X
  704. X
  705. X/* DECODE THE NEXT SYMBOL. */
  706. X
  707. Xint decode_symbol(cum_freq)
  708. X    freq_value cum_freq[];    /* Cumulative symbol frequencies            */
  709. X{
  710. X    int symbol;            /* Symbol decoded                           */
  711. X
  712. X    symbol = find_symbol(cum_freq);        /* Find decoded symbol.     */
  713. X    narrow_region(cum_freq,symbol);        /* Narrow coding region.    */
  714. X    discard_bits();                /* Discard output bits.     */
  715. X
  716. X    return symbol;
  717. X}
  718. X
  719. X
  720. X/* DECODE A BIT. */
  721. X
  722. Xint decode_bit(freq0,freq1)
  723. X    freq_value freq0;           /* Frequency for 0 bit                      */
  724. X    freq_value freq1;           /* Frequency for 1 bit                      */
  725. X{
  726. X    code_value split;
  727. X    int bit;
  728. X
  729. X    if (freq1>freq0) {                /* Decode bit when most     */
  730. X        split = split_region(freq0,freq1);    /* probable symbol is a 1.  */
  731. X        bit = value-low >= split;
  732. X        if (bit) { low += split; range -= split; }
  733. X        else     { range = split;  }
  734. X    }
  735. X
  736. X    else {                    /* Decode bit when most     */
  737. X        split = split_region(freq1,freq0);    /* probable symbol is a 0.  */
  738. X        bit = value-low < split;
  739. X        if (bit) { range = split;  }
  740. X        else     { low += split; range -= split; }
  741. X    }
  742. X
  743. X    discard_bits();                /* Discard output bits.     */
  744. X
  745. X    return bit;
  746. X}
  747. X
  748. X
  749. X/* DETERMINE DECODED SYMBOL FROM INPUT VALUE. */
  750. X
  751. Xstatic int find_symbol(cum_freq)
  752. X    freq_value cum_freq[];    /* Cumulative symbol frequencies            */
  753. X{
  754. X    int symbol;            /* Symbol decoded                           */
  755. X    freq_value M, P, Q, B;    /* Temporary values                         */
  756. X    div_value F, G;
  757. X    code_value A;    
  758. X
  759. X    A = range;                     /* Compute the value of     */
  760. X    M = cum_freq[0] << (Code_bits-Freq_bits-1); /*   F = range/cum_freq[0]. */
  761. X    F = 0;
  762. X
  763. X    if (A>=M) { A -= M; F += 1; }
  764. X#   if Code_bits-Freq_bits>2
  765. X    A <<= 1; F <<= 1;
  766. X    if (A>=M) { A -= M; F += 1; }
  767. X#   endif
  768. X#   if Code_bits-Freq_bits>3
  769. X    A <<= 1; F <<= 1;
  770. X    if (A>=M) { A -= M; F += 1; }
  771. X#   endif
  772. X#   if Code_bits-Freq_bits>4
  773. X    A <<= 1; F <<= 1;
  774. X    if (A>=M) { A -= M; F += 1; }
  775. X#   endif
  776. X#   if Code_bits-Freq_bits>5
  777. X    A <<= 1; F <<= 1;
  778. X    if (A>=M) { A -= M; F += 1; }
  779. X#   endif
  780. X#   if Code_bits-Freq_bits>6
  781. X    for (i = Code_bits-Freq_bits-6; i>0; i--) {
  782. X        A <<= 1; F <<= 1;
  783. X        if (A>=M) { A -= M; F += 1; }
  784. X    }
  785. X#   endif
  786. X    A <<= 1; F <<= 1;
  787. X    if (A>=M) { F += 1; }
  788. X
  789. X    A = value - low;                  /* Find the symbol that     */
  790. X    B = Freq_half;                /* fits the input. To do    */
  791. X    G = F << (Freq_bits-1);            /* so compute (value-low)/F */
  792. X    P = 0;                                      /* to as many bits as is    */
  793. X    Q = cum_freq[0];                 /* necessary.               */
  794. X    symbol = 1;
  795. X
  796. X    while (cum_freq[symbol]>P) {
  797. X        if (A>=G) {
  798. X            A -= G; 
  799. X            P = P+B; 
  800. X        }
  801. X        else {
  802. X            Q = P+B;
  803. X            while (cum_freq[symbol]>=Q) symbol += 1;
  804. X        }
  805. X        B >>= 1; G >>= 1;
  806. X    }
  807. X
  808. X    return symbol;
  809. X}
  810. X
  811. X
  812. X/* NARROW CODING REGION TO THAT ALLOTTED TO SYMBOL. */
  813. X
  814. Xstatic narrow_region(cum_freq,symbol)
  815. X    freq_value cum_freq[];    /* Cumulative symbol frequencies            */
  816. X    int symbol;            /* Symbol decoded                           */
  817. X{
  818. X    code_value A, Ta, Tb;    /* Temporary values                         */
  819. X    freq_value M, Ba, Bb;
  820. X    int i;
  821. X
  822. X    A = range; 
  823. X    M = cum_freq[0] << (Code_bits-Freq_bits-1);
  824. X
  825. X    if (symbol==1) {                /* Narrow range for symbol  */
  826. X                                                /* at the top.              */
  827. X        Ba = cum_freq[symbol];
  828. X        Ta = 0;                                 /* Compute the value of     */
  829. X                        /*   Ta = cum_freq[symbol]  */
  830. X        if (A>=M) { A -= M; Ta += Ba; }        /*     * (range/cum_freq[0])*/
  831. X#       if Code_bits-Freq_bits>2
  832. X        A <<= 1; Ta <<= 1;
  833. X        if (A>=M) { A -= M; Ta += Ba; }
  834. X#       endif
  835. X#       if Code_bits-Freq_bits>3
  836. X        A <<= 1; Ta <<= 1;
  837. X        if (A>=M) { A -= M; Ta += Ba; }
  838. X#       endif
  839. X#       if Code_bits-Freq_bits>4
  840. X        A <<= 1; Ta <<= 1;
  841. X        if (A>=M) { A -= M; Ta += Ba; }
  842. X#       endif
  843. X#       if Code_bits-Freq_bits>5
  844. X        A <<= 1; Ta <<= 1;
  845. X        if (A>=M) { A -= M; Ta += Ba; }
  846. X#       endif
  847. X#       if Code_bits-Freq_bits>6
  848. X        for (i = Code_bits-Freq_bits-6; i>0; i--) {
  849. X            A <<= 1; Ta <<= 1;
  850. X            if (A>=M) { A -= M; Ta += Ba; }
  851. X        }
  852. X#       endif
  853. X        A <<= 1; Ta <<= 1;
  854. X        if (A>=M) { Ta += Ba; }
  855. X
  856. X        low += Ta;
  857. X        range -= Ta;
  858. X    }
  859. X
  860. X    else {                    /* Narrow range for symbol  */
  861. X                                                /* not at the top.          */
  862. X        Ba = cum_freq[symbol];
  863. X        Bb = cum_freq[symbol-1];            /* Compute the value of     */
  864. X        Ta = Tb = 0;                /*   Ta = cum_freq[symbol]  */
  865. X                        /*     * (range/cum_freq[0])*/
  866. X        if (A>=M) { A -= M; Ta += Ba; Tb += Bb; }/*and of                   */
  867. X#       if Code_bits-Freq_bits>2        /*   Tb = cum_freq[symbol-1]*/
  868. X        A <<= 1; Ta <<= 1; Tb <<= 1;        /*     * (range/cum_freq[0] */
  869. X        if (A>=M) { A -= M; Ta += Ba; Tb += Bb; }
  870. X#       endif
  871. X#       if Code_bits-Freq_bits>3
  872. X        A <<= 1; Ta <<= 1; Tb <<= 1;
  873. X        if (A>=M) { A -= M; Ta += Ba; Tb += Bb; }
  874. X#       endif
  875. X#       if Code_bits-Freq_bits>4
  876. X        A <<= 1; Ta <<= 1; Tb <<= 1;
  877. X        if (A>=M) { A -= M; Ta += Ba; Tb += Bb; }
  878. X#       endif
  879. X#       if Code_bits-Freq_bits>5
  880. X        A <<= 1; Ta <<= 1; Tb <<= 1;
  881. X        if (A>=M) { A -= M; Ta += Ba; Tb += Bb; }
  882. X#       endif
  883. X#       if Code_bits-Freq_bits>6
  884. X        for (i = Code_bits-Freq_bits-6; i>0; i--) {
  885. X            A <<= 1; Ta <<= 1; Tb <<= 1;
  886. X            if (A>=M) { A -= M; Ta += Ba; Tb += Bb; }
  887. X        }
  888. X#       endif
  889. X        A <<= 1; Ta <<= 1; Tb <<= 1;
  890. X        if (A>=M) { Ta += Ba; Tb += Bb; }
  891. X
  892. X        low += Ta;
  893. X        range = Tb - Ta;
  894. X    }
  895. X}
  896. X
  897. X
  898. X/* FIND BINARY SPLIT FOR CODING REGION. */
  899. X
  900. Xstatic code_value split_region(freq_b,freq_t)
  901. X    freq_value freq_b;        /* Frequency for symbol in bottom half      */
  902. X    freq_value freq_t;        /* Frequency for symbol in top half         */
  903. X{
  904. X    code_value A, T;        /* Temporary values                         */
  905. X    freq_value M, B;
  906. X    int i;
  907. X
  908. X    A = range; 
  909. X    M = (freq_b+freq_t) << (Code_bits-Freq_bits-1);
  910. X    B = freq_b;
  911. X    T = 0;                                       /* Compute the value of     */
  912. X                        /* T = freq_b * (range      */
  913. X    if (A>=M) { A -= M; T += B; }        /*       / (freq_b+freq_t)) */
  914. X#   if Code_bits-Freq_bits>2
  915. X    A <<= 1; T <<= 1;
  916. X    if (A>=M) { A -= M; T += B; }
  917. X#   endif
  918. X#   if Code_bits-Freq_bits>3
  919. X    A <<= 1; T <<= 1;
  920. X    if (A>=M) { A -= M; T += B; }
  921. X#   endif
  922. X#   if Code_bits-Freq_bits>4
  923. X    A <<= 1; T <<= 1;
  924. X    if (A>=M) { A -= M; T += B; }
  925. X#   endif
  926. X#   if Code_bits-Freq_bits>5
  927. X    A <<= 1; T <<= 1;
  928. X    if (A>=M) { A -= M; T += B; }
  929. X#   endif
  930. X#   if Code_bits-Freq_bits>6
  931. X    for (i = Code_bits-Freq_bits-6; i>0; i--) {
  932. X        A <<= 1; T <<= 1;
  933. X        if (A>=M) { A -= M; T += B; }
  934. X    }
  935. X#   endif
  936. X    A <<= 1; T <<= 1;
  937. X    if (A>=M) { T += B; }
  938. X
  939. X    return T;
  940. X}
  941. X
  942. X
  943. X/* OUTPUT BITS THAT ARE NOW DETERMINED. */
  944. X
  945. Xstatic push_out_bits()
  946. X{
  947. X    while (range<=Code_quarter) {
  948. X
  949. X        if (low>=Code_half) {            /* Output 1 if in top half.*/
  950. X            bit_plus_follow(1);
  951. X            low -= Code_half;            /* Subtract offset to top.  */
  952. X        }
  953. X
  954. X        else if (low+range<=Code_half) {    /* Output 0 in bottom half. */
  955. X            bit_plus_follow(0);        
  956. X    } 
  957. X
  958. X        else {                     /* Output an opposite bit   */
  959. X            bits_to_follow += 1;        /* later if in middle half. */
  960. X            low -= Code_quarter;        /* Subtract offset to middle*/
  961. X        } 
  962. X
  963. X        low += low;                /* Scale up code region.    */
  964. X        range += range;
  965. X    }
  966. X}
  967. X
  968. X
  969. X/* DISCARD BITS THE ENCODER WOULD HAVE OUTPUT. */
  970. X
  971. Xstatic discard_bits()
  972. X{
  973. X    while (range<=Code_quarter) {
  974. X
  975. X        if (low>=Code_half) {            /* Expand top half.         */
  976. X            low -= Code_half;            /* Subtract offset to top.  */
  977. X            value -= Code_half;
  978. X        }
  979. X
  980. X        else if (low+range<=Code_half) {    /* Expand bottom half.      */
  981. X            /* nothing */
  982. X    } 
  983. X
  984. X        else {                     /* Expand middle half.      */
  985. X            low -= Code_quarter;        /* Subtract offset to middle*/
  986. X            value -= Code_quarter;
  987. X        } 
  988. X
  989. X        low += low;                /* Scale up code region.    */
  990. X        range += range;
  991. X
  992. X        value += value;                /* Move in next input bit.  */
  993. X        value += input_bit();
  994. X    }
  995. X}
  996. X
  997. X
  998. X/* FINISH ENCODING THE STREAM. */
  999. X
  1000. Xdone_encoding()
  1001. X{   
  1002. X    for (;;) {
  1003. X
  1004. X        if (low+(range>>1)>=Code_half) {    /* Output a 1 if mostly in  */
  1005. X            bit_plus_follow(1);            /* top half.                */
  1006. X            range = low+range-Code_half;
  1007. X            low = low<Code_half ? 0 : low-Code_half;
  1008. X        }
  1009. X
  1010. X        else {                    /* Output a 0 if mostly in  */
  1011. X            bit_plus_follow(0);            /* bottom half.             */
  1012. X            if (low+range>Code_half) {
  1013. X                range = Code_half-low;
  1014. X            }
  1015. X        }
  1016. X
  1017. X        if (range==Code_half) break;        /* Quit when coding region  */
  1018. X                        /* becomes entire interval. */
  1019. X        low += low;
  1020. X        range += range;                /* Scale up code region.    */
  1021. X    }
  1022. X}
  1023. END_OF_FILE
  1024. if test 11930 -ne `wc -c <'code_sft.c'`; then
  1025.     echo shar: \"'code_sft.c'\" unpacked with wrong size!
  1026. fi
  1027. # end of 'code_sft.c'
  1028. fi
  1029. if test -f 'decode.c' -a "${1}" != "-c" ; then 
  1030.   echo shar: Will not clobber existing file \"'decode.c'\"
  1031. else
  1032. echo shar: Extracting \"'decode.c'\" \(751 characters\)
  1033. sed "s/^X//" >'decode.c' <<'END_OF_FILE'
  1034. X/* DECODE.C - MAIN PROGRAM FOR DECODING. */
  1035. X
  1036. X#include <stdio.h>
  1037. X
  1038. X#include "code.h"
  1039. X#include "model.h"
  1040. X
  1041. Xmain()
  1042. X{
  1043. X    int symbol;            /* Character to decoded as a symbol index    */
  1044. X    int ch;             /* Character to decoded as a character code  */
  1045. X
  1046. X    start_model();                /* Set up other modules.    */
  1047. X    start_inputing_bits();
  1048. X    start_decoding();
  1049. X
  1050. X    for (;;) {                    /* Loop through characters. */
  1051. X
  1052. X        symbol = decode_symbol(cum_freq);    /* Decode next symbol.      */
  1053. X        if (symbol==EOF_symbol) break;        /* Exit loop if EOF symbol. */
  1054. X        ch = index_to_char[symbol];        /* Translate to a character.*/
  1055. X        putc(ch,stdout);            /* Write that character.    */
  1056. X        update_model(symbol);            /* Update the model.        */
  1057. X    }
  1058. X
  1059. X    exit(0);
  1060. X}
  1061. END_OF_FILE
  1062. if test 751 -ne `wc -c <'decode.c'`; then
  1063.     echo shar: \"'decode.c'\" unpacked with wrong size!
  1064. fi
  1065. # end of 'decode.c'
  1066. fi
  1067. if test -f 'decpic.c' -a "${1}" != "-c" ; then 
  1068.   echo shar: Will not clobber existing file \"'decpic.c'\"
  1069. else
  1070. echo shar: Extracting \"'decpic.c'\" \(1783 characters\)
  1071. sed "s/^X//" >'decpic.c' <<'END_OF_FILE'
  1072. X/* DECPIC.C - MAIN PROGRAM FOR DECODING PICTURES. */
  1073. X
  1074. X#include <stdio.h>
  1075. X
  1076. X#include "code.h"
  1077. X
  1078. X#define Height 40            /* Height of images                 */
  1079. X#define Width 40                        /* Width of images                  */
  1080. X
  1081. Xstatic int image[Height][Width];    /* The image to be encoded          */
  1082. X
  1083. Xstatic int freq0[2][2];            /* Frequencies of '0' in contexts   */
  1084. Xstatic int freq1[2][2];            /* Frequencies of '1' in contexts   */
  1085. X
  1086. Xstatic int inc[2][2];            /* Current increment                */
  1087. X
  1088. Xmain()
  1089. X{   
  1090. X    int i, j, a, l;
  1091. X
  1092. X    start_inputing_bits();
  1093. X    start_decoding();
  1094. X
  1095. X    /* Initialize model. */
  1096. X
  1097. X    for (a = 0; a<2; a++) {
  1098. X        for (l = 0; l<2; l++) {
  1099. X            inc[a][l] = Freq_half;
  1100. X            freq0[a][l] = inc[a][l];        /* Set frequencies of 0's   */
  1101. X            freq1[a][l] = inc[a][l];        /* and 1's to be equal.     */
  1102. X        }
  1103. X    }
  1104. X
  1105. X    /* Decode and write image. */
  1106. X
  1107. X    for (i = 0; i<Height; i++) {
  1108. X        for (j = 0; j<Width; j++) {
  1109. X            a = i==0 ? 0 : image[i-1][j];    /* Find current context.    */
  1110. X            l = j==0 ? 0 : image[i][j-1];
  1111. X            image[i][j] =             /* Decode pixel.            */
  1112. X              decode_bit(freq0[a][l],freq1[a][l]);
  1113. X            printf("%c%c",image[i][j] ? '#' : '.', 
  1114. X                          j==Width-1 ? '\n' : ' ');
  1115. X            if (image[i][j]) {            /* Update frequencies for   */
  1116. X                freq1[a][l] += inc[a][l];       /* this context.            */
  1117. X            }
  1118. X            else {
  1119. X                freq0[a][l] += inc[a][l];
  1120. X            }
  1121. X            if (freq0[a][l]+freq1[a][l]>Freq_full) { 
  1122. X                freq0[a][l] = (freq0[a][l]+1) >> 1; 
  1123. X                freq1[a][l] = (freq1[a][l]+1) >> 1;
  1124. X                if (inc[a][l]>1) inc[a][l] >>= 1;
  1125. X            }
  1126. X        }
  1127. X    }
  1128. X
  1129. X    exit(0);
  1130. X}
  1131. END_OF_FILE
  1132. if test 1783 -ne `wc -c <'decpic.c'`; then
  1133.     echo shar: \"'decpic.c'\" unpacked with wrong size!
  1134. fi
  1135. # end of 'decpic.c'
  1136. fi
  1137. if test -f 'encode.c' -a "${1}" != "-c" ; then 
  1138.   echo shar: Will not clobber existing file \"'encode.c'\"
  1139. else
  1140. echo shar: Extracting \"'encode.c'\" \(899 characters\)
  1141. sed "s/^X//" >'encode.c' <<'END_OF_FILE'
  1142. X/* ENCODE.C - MAIN PROGRAM FOR ENCODING. */
  1143. X
  1144. X#include <stdio.h>
  1145. X
  1146. X#include "code.h"
  1147. X#include "model.h"
  1148. X
  1149. Xmain()
  1150. X{   
  1151. X    int ch;             /* Character to encode as a character code  */
  1152. X    int symbol;            /* Character to encode as a symbol index    */
  1153. X
  1154. X    start_model();                /* Set up other modules.    */
  1155. X    start_outputing_bits();
  1156. X    start_encoding();
  1157. X
  1158. X    for (;;) {                    /* Loop through characters. */
  1159. X
  1160. X        ch = getc(stdin);            /* Read the next character. */
  1161. X        if (ch==EOF) break;            /* Exit loop on end-of-file.*/
  1162. X        symbol = char_to_index[ch];        /* Translate to an index.   */
  1163. X        encode_symbol(symbol,cum_freq);        /* Encode that symbol.      */
  1164. X        update_model(symbol);            /* Update the model.        */
  1165. X    }
  1166. X
  1167. X    encode_symbol(EOF_symbol,cum_freq);        /* Encode the EOF symbol.   */
  1168. X
  1169. X    done_encoding();                /* Send the last few bits.  */
  1170. X    done_outputing_bits();
  1171. X
  1172. X    exit(0);
  1173. X}
  1174. END_OF_FILE
  1175. if test 899 -ne `wc -c <'encode.c'`; then
  1176.     echo shar: \"'encode.c'\" unpacked with wrong size!
  1177. fi
  1178. # end of 'encode.c'
  1179. fi
  1180. if test -f 'encpic.c' -a "${1}" != "-c" ; then 
  1181.   echo shar: Will not clobber existing file \"'encpic.c'\"
  1182. else
  1183. echo shar: Extracting \"'encpic.c'\" \(2283 characters\)
  1184. sed "s/^X//" >'encpic.c' <<'END_OF_FILE'
  1185. X/* ENCPIC.C - MAIN PROGRAM FOR ENCODING PICTURES. */
  1186. X
  1187. X#include <stdio.h>
  1188. X
  1189. X#include "code.h"
  1190. X
  1191. X#define Height 40            /* Height of images                 */
  1192. X#define Width 40                        /* Width of images                  */
  1193. X
  1194. Xstatic int image[Height][Width];    /* The image to be encoded          */
  1195. X
  1196. Xstatic int freq0[2][2];            /* Frequencies of '0' in contexts   */
  1197. Xstatic int freq1[2][2];            /* Frequencies of '1' in contexts   */
  1198. X
  1199. Xstatic int inc[2][2];            /* Current increment                */
  1200. X
  1201. Xmain()
  1202. X{   
  1203. X    int i, j, a, l, ch;
  1204. X
  1205. X    start_outputing_bits();
  1206. X    start_encoding();
  1207. X
  1208. X    /* Read image. */
  1209. X
  1210. X    for (i = 0; i<Height; i++) {
  1211. X        for (j = 0; j<Width; j++) {
  1212. X            do {
  1213. X                ch = getc(stdin);        /* Read the next character, */
  1214. X            } while (ch=='\n' || ch==' ');      /* ignoring whitespace.     */
  1215. X            if (ch!='.' && ch!='#') {           /* Check for bad character. */
  1216. X                fprintf(stderr,"Bad image file\n");
  1217. X                exit(-1);
  1218. X            }
  1219. X            image[i][j] = ch=='#';        /* Convert char to pixel.   */
  1220. X        }
  1221. X    }
  1222. X
  1223. X    /* Initialize model. */
  1224. X
  1225. X    for (a = 0; a<2; a++) {
  1226. X        for (l = 0; l<2; l++) {
  1227. X            inc[a][l] = Freq_half;
  1228. X            freq0[a][l] = inc[a][l];        /* Set frequencies of 0's   */
  1229. X            freq1[a][l] = inc[a][l];        /* and 1's to be equal.     */
  1230. X        }
  1231. X    }
  1232. X
  1233. X    /* Encode image. */
  1234. X
  1235. X    for (i = 0; i<Height; i++) {
  1236. X        for (j = 0; j<Width; j++) {
  1237. X            a = i==0 ? 0 : image[i-1][j];    /* Find current context.    */
  1238. X            l = j==0 ? 0 : image[i][j-1];
  1239. X            encode_bit(image[i][j],             /* Encode pixel.            */
  1240. X                       freq0[a][l],freq1[a][l]);
  1241. X            if (image[i][j]) {            /* Update frequencies for   */
  1242. X                freq1[a][l] += inc[a][l];       /* this context.            */
  1243. X            }
  1244. X            else {
  1245. X                freq0[a][l] += inc[a][l];
  1246. X            }
  1247. X            if (freq0[a][l]+freq1[a][l]>Freq_full) { 
  1248. X                freq0[a][l] = (freq0[a][l]+1) >> 1; 
  1249. X                freq1[a][l] = (freq1[a][l]+1) >> 1;
  1250. X                if (inc[a][l]>1) inc[a][l] >>= 1;
  1251. X            }
  1252. X        }
  1253. X    }
  1254. X
  1255. X    done_encoding();                /* Send the last few bits.  */
  1256. X    done_outputing_bits();
  1257. X
  1258. X    exit(0);
  1259. X}
  1260. END_OF_FILE
  1261. if test 2283 -ne `wc -c <'encpic.c'`; then
  1262.     echo shar: \"'encpic.c'\" unpacked with wrong size!
  1263. fi
  1264. # end of 'encpic.c'
  1265. fi
  1266. if test -f 'model.c' -a "${1}" != "-c" ; then 
  1267.   echo shar: Will not clobber existing file \"'model.c'\"
  1268. else
  1269. echo shar: Extracting \"'model.c'\" \(2318 characters\)
  1270. sed "s/^X//" >'model.c' <<'END_OF_FILE'
  1271. X/* MODEL.C - THE ADAPTIVE SOURCE MODEL */
  1272. X
  1273. X#include <stdio.h>
  1274. X
  1275. X#include "code.h"
  1276. X#include "model.h"
  1277. X
  1278. Xstatic freq_value freq[No_of_symbols+1]; /* Symbol frequencies                */
  1279. Xstatic freq_value inc;                 /* Value to increment frequencies by */
  1280. X
  1281. X
  1282. X/* INITIALIZE THE MODEL. */
  1283. X
  1284. Xstart_model()
  1285. X{   
  1286. X    int i;
  1287. X
  1288. X    for (i = 0; i<No_of_chars; i++) {        /* Set up tables that       */
  1289. X        char_to_index[i] = i+1;            /* translate between symbol */
  1290. X        index_to_char[i+1] = i;            /* indexes and characters.  */
  1291. X    }
  1292. X
  1293. X    inc = 1;
  1294. X    while (inc*No_of_symbols<=Freq_half) {    /* Find increment that puts */
  1295. X        inc *= 2;                /* total in required range. */
  1296. X    }
  1297. X
  1298. X    cum_freq[No_of_symbols] = 0;        /* Set up initial frequency */
  1299. X    for (i = No_of_symbols; i>0; i--) {        /* counts to be equal for   */
  1300. X        freq[i] = inc;                /* all symbols.             */
  1301. X        cum_freq[i-1] = cum_freq[i] + freq[i];    
  1302. X    }
  1303. X
  1304. X    freq[0] = 0;                /* Freq[0] must not be the  */
  1305. X                        /* same as freq[1].         */
  1306. X}
  1307. X
  1308. X
  1309. X/* UPDATE THE MODEL TO ACCOUNT FOR A NEW SYMBOL. */
  1310. X
  1311. Xupdate_model(symbol)
  1312. X    int symbol;            /* Index of new symbol                      */
  1313. X{   
  1314. X    int ch_i, ch_symbol;    /* Temporaries for exchanging symbols       */
  1315. X    int i;
  1316. X
  1317. X    for (i = symbol; freq[i]==freq[i-1]; i--) ;    /* Find symbol's new index. */
  1318. X
  1319. X    if (i<symbol) {
  1320. X        ch_i = index_to_char[i];        /* Update the translation   */
  1321. X        ch_symbol = index_to_char[symbol];    /* tables if the symbol has */
  1322. X        index_to_char[i] = ch_symbol;           /* moved.                   */
  1323. X        index_to_char[symbol] = ch_i;
  1324. X        char_to_index[ch_i] = symbol;
  1325. X        char_to_index[ch_symbol] = i;
  1326. X    }
  1327. X
  1328. X    freq[i] += inc;                /* Increment the frequency  */
  1329. X    while (i>0) {                /* count for the symbol and */
  1330. X        i -= 1;                    /* update the cumulative    */
  1331. X        cum_freq[i] += inc;            /* frequencies.             */
  1332. X    }
  1333. X
  1334. X    if (cum_freq[0]>Freq_full) {        /* See if frequency counts  */
  1335. X        cum_freq[No_of_symbols] = 0;        /* are past their maximum.  */
  1336. X        for (i = No_of_symbols; i>=0; i--) {    /* If so, halve all counts  */
  1337. X            freq[i] = (freq[i]+1) >> 1;        /* (keeping them non-zero). */
  1338. X            cum_freq[i-1] = cum_freq[i] + freq[i]; 
  1339. X        }
  1340. X        if (inc>1) inc >>= 1;            /* Halve increment if can.  */
  1341. X    }
  1342. X}
  1343. END_OF_FILE
  1344. if test 2318 -ne `wc -c <'model.c'`; then
  1345.     echo shar: \"'model.c'\" unpacked with wrong size!
  1346. fi
  1347. # end of 'model.c'
  1348. fi
  1349. if test -f 'model.h' -a "${1}" != "-c" ; then 
  1350.   echo shar: Will not clobber existing file \"'model.h'\"
  1351. else
  1352. echo shar: Extracting \"'model.h'\" \(848 characters\)
  1353. sed "s/^X//" >'model.h' <<'END_OF_FILE'
  1354. X/* MODEL.H - INTERFACE TO THE MODEL. */
  1355. X
  1356. X
  1357. X/* THE SET OF SYMBOLS THAT MAY BE ENCODED. Symbols are indexed by integers
  1358. X   from 1 to No_of_symbols. */
  1359. X
  1360. X#define No_of_chars 256            /* Number of character symbols      */
  1361. X#define EOF_symbol (No_of_chars+1)    /* Index of EOF symbol              */
  1362. X
  1363. X#define No_of_symbols (No_of_chars+1)    /* Total number of symbols          */
  1364. X
  1365. X
  1366. X/* TRANSLATION TABLES BETWEEN CHARACTERS AND SYMBOL INDEXES. */
  1367. X
  1368. Xint char_to_index[No_of_chars];        /* To index from character          */
  1369. Xunsigned char index_to_char[No_of_symbols+1]; /* To character from index    */
  1370. X
  1371. X
  1372. X/* CUMULATIVE FREQUENCY TABLE. Cumulative frequencies are stored as
  1373. X   partially normalized counts. The normalization factor is cum_freq[0],
  1374. X   which must lie in the range (1/2,1]. */
  1375. X
  1376. Xfreq_value cum_freq[No_of_symbols+1];    /* Cumulative symbol frequencies    */
  1377. END_OF_FILE
  1378. if test 848 -ne `wc -c <'model.h'`; then
  1379.     echo shar: \"'model.h'\" unpacked with wrong size!
  1380. fi
  1381. # end of 'model.h'
  1382. fi
  1383. if test -f 'redundancy.c' -a "${1}" != "-c" ; then 
  1384.   echo shar: Will not clobber existing file \"'redundancy.c'\"
  1385. else
  1386. echo shar: Extracting \"'redundancy.c'\" \(1597 characters\)
  1387. sed "s/^X//" >'redundancy.c' <<'END_OF_FILE'
  1388. X/* REDUNDANCY.C - PROGRAM TO CALCULATE MAXIMUM CODING INEFFICIENCY. */
  1389. X
  1390. X#include <stdio.h>
  1391. X#include <math.h>
  1392. X
  1393. X
  1394. X/* This program calculates a bound on the expected number of extra bits
  1395. X   produced as a result of doing arithmetic coding using divides of a given 
  1396. X   precision, expressed as a percentage of the optimal coding size. The
  1397. X   expectation is calculated on the assumption that the model's symbol
  1398. X   probabilities are correct.
  1399. X
  1400. X   The bound assumes that the coding range and total frequencies are such
  1401. X   as to cause maximum truncation in the division, with the minimum true
  1402. X   quotient. The bound varies as a function of the probability, p, of
  1403. X   the most probable symbol. All but at most one of the remaining symbols
  1404. X   are assumed to have probabilities equal to p (this gives minimum optimal
  1405. X   coding size, and hence maximum relative inefficiency). */
  1406. X
  1407. Xmain()
  1408. X{
  1409. X    double p;
  1410. X
  1411. X    printf(
  1412. X     "\nPrecision:    2      3      4      5      6      7      8      9\n\n");
  1413. X   
  1414. X    for (p = 0.001; p<0.0095; p+=0.001) do_p(p);
  1415. X    for (p = 0.010; p<0.9905; p+=0.010) do_p(p);
  1416. X    for (p = 0.991; p<0.9995; p+=0.001) do_p(p);
  1417. X  
  1418. X    exit(0);
  1419. X}
  1420. X
  1421. Xdo_p(p)
  1422. X  double p;
  1423. X{
  1424. X    int precision, n;
  1425. X    double e, opt, excess;
  1426. X
  1427. X    printf("  p=%5.3f ",p);
  1428. X    for (precision = 2; precision<10; precision++) {
  1429. X        e = pow(2.0,-(double)precision)/(0.25+pow(2.0,-(double)precision));
  1430. X        n = (int)(1/p);
  1431. X        opt = - n*p*log(p);
  1432. X        if (n*p!=1) opt -= (1-n*p)*log(1-n*p);
  1433. X        excess = - (1-p)*log(1-e) - p*log(1-e+e/p);
  1434. X        printf("  %5.2f",100*excess/opt);
  1435. X    }
  1436. X    printf("\n");
  1437. X}
  1438. END_OF_FILE
  1439. if test 1597 -ne `wc -c <'redundancy.c'`; then
  1440.     echo shar: \"'redundancy.c'\" unpacked with wrong size!
  1441. fi
  1442. # end of 'redundancy.c'
  1443. fi
  1444. if test -f 'tstpic' -a "${1}" != "-c" ; then 
  1445.   echo shar: Will not clobber existing file \"'tstpic'\"
  1446. else
  1447. echo shar: Extracting \"'tstpic'\" \(3200 characters\)
  1448. sed "s/^X//" >'tstpic' <<'END_OF_FILE'
  1449. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1450. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1451. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1452. X. . . # # . . . . . . . . . . . . . . . . . . . . . . # . . . . . . . . . . . .
  1453. X. . . # # . . . . . . . . . . . . . . . . . . . # . # . . . . . . . . . . . . .
  1454. X. . . # # . . . . . . . . . . . . . . . . . # # # # . . . . . . . . . . . . . .
  1455. X. . . . . . . . . . # # . . . . . . . . . . . . . # . . . . . . . . . . . . . .
  1456. X. . . . . . . . # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1457. X. . . . . . . . . . # . # . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1458. X. . . . . . . . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1459. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1460. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1461. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1462. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1463. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1464. X# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1465. X. . . . . . . . . . . . # # # # . . . . . . . . . . . . . . . . . . . . . . . .
  1466. X. . . . . . . . . . . . . . # . . . . . . . . . . . . . . . . . . . . . . . . .
  1467. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . # # . . . . . . . . . .
  1468. X. . . . . . . . . . . . . . . . . . . . . . . . . . # # # # # # # . . . . . . .
  1469. X. . . . . . . . . . . . . . . . . . . . . . . . . # # # # # # # # . . . . . . .
  1470. X. . . . . . . . . . . . . . . . . . . . . . . . . . # # # # . # # . . . . . . .
  1471. X. . . . . . . . . . . . . . . . . . . . . . . . . . # # # # # # # . . . . . . .
  1472. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # # . . . . . . . .
  1473. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1474. X. . . . . . . . . # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1475. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1476. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1477. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1478. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1479. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1480. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1481. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . . . . . . . .
  1482. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  1483. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . #
  1484. X. . . . . # # # . # # # # . . . . . . . . . . . . . . . . . . . . . . . . . # #
  1485. X. . . . . . . . # . . . . # # . . . . . . . . . . . . . . . . . . . . . . . . #
  1486. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # #
  1487. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # #
  1488. X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # #
  1489. END_OF_FILE
  1490. if test 3200 -ne `wc -c <'tstpic'`; then
  1491.     echo shar: \"'tstpic'\" unpacked with wrong size!
  1492. fi
  1493. # end of 'tstpic'
  1494. fi
  1495. echo shar: End of shell archive.
  1496. exit 0
  1497.  
  1498. exit 0 # Just in case...
  1499. -- 
  1500. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1501. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1502. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1503. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1504.