source: trunk/newview_dll/newview.c@ 362

Last change on this file since 362 was 362, checked in by RBRi, 16 years ago

initial checkin

  • Property svn:eol-style set to native
File size: 5.2 KB
Line 
1#define INCL_DOS
2#define INCL_DOSERRORS
3#include <os2.h>
4
5#include <stdio.h>
6#include <stdlib.h>
7
8/********************************************************************
9 * *
10 * LZW decompression *
11 * *
12 *******************************************************************/
13
14/*
15 * This is based on code (W) by Peter Fitzsimmons, pfitz@ican.net.
16 * His liner notes in the original:
17 * has its roots in a June 1990
18 * DDJ article "LZW REVISITED", by Shawn M. Regan
19 * --=>revision history<=--
20 * 1 lzw.c 21-Aug-96,2:24:36,`PLF' ;
21 * 2 lzw.c 24-Aug-96,2:27:24,`PLF' wip
22 *
23 * The code has been modified to take the input not from an
24 * open file, but from any memory region. For this, a double
25 * pointer is used, which must be passed to LZWDecompressBlock.
26 * I've also added a few comments for clarity.
27 *
28 */
29
30/* -- Stuff for LZW decompression -- */
31#define INIT_BITS 9
32#define MAX_BITS 12 /*PLF Tue 95-10-03 02:16:56*/
33#define HASHING_SHIFT MAX_BITS - 8
34
35#if MAX_BITS == 15
36 #define TABLE_SIZE 36768
37#elif MAX_BITS == 14
38 #define TABLE_SIZE 18041
39#elif MAX_BITS == 13
40 #define TABLE_SIZE 9029
41#else
42 #define TABLE_SIZE 5021
43#endif
44
45#define CLEAR_TABLE 256
46#define TERMINATOR 257
47#define FIRST_CODE 258
48#define CHECK_TIME 100
49
50#define MAXVAL(n) (( 1 << (n)) -1)
51
52static unsigned int prefix_code[ TABLE_SIZE ];
53static unsigned char append_character[ TABLE_SIZE ];
54
55static unsigned char decode_stack[4000];
56static int num_bits;
57static int max_code;
58
59/*
60 * decode_string:
61 *
62 */
63char *decode_string(unsigned char *buffer, unsigned int code, BOOL* error)
64{
65 int i = 0;
66 *error = FALSE;
67 while (code > 255) {
68 *buffer++ = append_character[code];
69 code = prefix_code[code];
70 if (i++ >= 4000) {
71 *error = TRUE;
72 return( buffer );
73 }
74 }
75 *buffer = code;
76 return (buffer);
77}
78
79
80
81/*
82 * input_code:
83 * this function reads in bytes from the input
84 * stream.
85 */
86unsigned input_code(PBYTE *ppbInput, unsigned bytes_to_read)
87{
88 unsigned int return_value;
89 static unsigned long bytes_out = 0;
90 static int input_bit_count = 0;
91 static unsigned long input_bit_buffer = 0L;
92
93 while (input_bit_count <= 24) {
94 if (bytes_out <= bytes_to_read) {
95 input_bit_buffer |= (unsigned long)(**ppbInput) << (24 - input_bit_count);
96 (*ppbInput)++;
97 } else
98 input_bit_buffer |= 0x00;
99 bytes_out++;
100 input_bit_count += 8;
101 }
102 return_value = input_bit_buffer >> (32 - num_bits);
103 input_bit_buffer <<= num_bits;
104 input_bit_count -= num_bits;
105 if (bytes_out > bytes_to_read) { /* flush static vars and quit */
106 bytes_out = 0;
107 input_bit_count = 0;
108 input_bit_buffer = 0L;
109 return (TERMINATOR);
110 }
111 else
112 return (return_value);
113}
114
115
116/*
117 * LZWDecompressBlock:
118 * this takes one of the INF bitmap blocks
119 * and decompresses it using LZW algorithms.
120 */
121BOOL APIENTRY LZWDecompressBlock( PBYTE pbInput, // in: compressed data
122 PBYTE pOutput, // out: uncompressed data
123 unsigned int number_bytes, // in: bytes to decompress
124 unsigned long * pBytesOut, // out: bytes decompressed.
125 PBYTE pLastCode) // out: last byte decompressed.
126{
127 unsigned int next_code = FIRST_CODE;
128 unsigned int new_code;
129 unsigned int old_code;
130 int character, clear_flag = 1;
131 unsigned char *string;
132 BOOL error;
133
134 num_bits = INIT_BITS;
135 max_code = MAXVAL(num_bits);
136
137 *pBytesOut = 0;
138
139 while ((new_code = input_code(&pbInput, number_bytes)) != TERMINATOR) {
140 if (clear_flag) {
141 clear_flag = 0;
142 old_code = new_code;
143 character = old_code;
144 *pOutput = (BYTE)old_code;
145 pOutput ++;
146 *pLastCode = (BYTE)old_code;
147 (*pBytesOut) ++;
148 continue;
149 }
150 if (new_code == CLEAR_TABLE) {
151 clear_flag = 1;
152 num_bits = INIT_BITS;
153 next_code = FIRST_CODE;
154 max_code = MAXVAL(num_bits);
155 continue;
156 }
157
158 if (new_code >= next_code) {
159 *decode_stack = character;
160 string = decode_string(decode_stack + 1, old_code, &error);
161 }
162 else
163 string = decode_string(decode_stack, new_code, &error);
164
165 if ( error ) {
166 return FALSE;
167 }
168 character = *string;
169 while (string >= decode_stack) {
170 *pOutput = *string;
171 pOutput ++;
172 string --;
173
174 (*pBytesOut)++;
175 }
176 *pLastCode = *( string+1 );
177
178 if (next_code <= max_code) {
179 prefix_code[next_code] = old_code;
180 append_character[next_code++] = character;
181 if (next_code == max_code && num_bits < MAX_BITS) {
182 max_code = MAXVAL(++num_bits);
183 }
184 }
185 old_code = new_code;
186 }
187 return (TRUE);
188}
Note: See TracBrowser for help on using the repository browser.