1275793eaSopenharmony_ci/* blast.c 2275793eaSopenharmony_ci * Copyright (C) 2003, 2012, 2013 Mark Adler 3275793eaSopenharmony_ci * For conditions of distribution and use, see copyright notice in blast.h 4275793eaSopenharmony_ci * version 1.3, 24 Aug 2013 5275793eaSopenharmony_ci * 6275793eaSopenharmony_ci * blast.c decompresses data compressed by the PKWare Compression Library. 7275793eaSopenharmony_ci * This function provides functionality similar to the explode() function of 8275793eaSopenharmony_ci * the PKWare library, hence the name "blast". 9275793eaSopenharmony_ci * 10275793eaSopenharmony_ci * This decompressor is based on the excellent format description provided by 11275793eaSopenharmony_ci * Ben Rudiak-Gould in comp.compression on August 13, 2001. Interestingly, the 12275793eaSopenharmony_ci * example Ben provided in the post is incorrect. The distance 110001 should 13275793eaSopenharmony_ci * instead be 111000. When corrected, the example byte stream becomes: 14275793eaSopenharmony_ci * 15275793eaSopenharmony_ci * 00 04 82 24 25 8f 80 7f 16275793eaSopenharmony_ci * 17275793eaSopenharmony_ci * which decompresses to "AIAIAIAIAIAIA" (without the quotes). 18275793eaSopenharmony_ci */ 19275793eaSopenharmony_ci 20275793eaSopenharmony_ci/* 21275793eaSopenharmony_ci * Change history: 22275793eaSopenharmony_ci * 23275793eaSopenharmony_ci * 1.0 12 Feb 2003 - First version 24275793eaSopenharmony_ci * 1.1 16 Feb 2003 - Fixed distance check for > 4 GB uncompressed data 25275793eaSopenharmony_ci * 1.2 24 Oct 2012 - Add note about using binary mode in stdio 26275793eaSopenharmony_ci * - Fix comparisons of differently signed integers 27275793eaSopenharmony_ci * 1.3 24 Aug 2013 - Return unused input from blast() 28275793eaSopenharmony_ci * - Fix test code to correctly report unused input 29275793eaSopenharmony_ci * - Enable the provision of initial input to blast() 30275793eaSopenharmony_ci */ 31275793eaSopenharmony_ci 32275793eaSopenharmony_ci#include <stddef.h> /* for NULL */ 33275793eaSopenharmony_ci#include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */ 34275793eaSopenharmony_ci#include "blast.h" /* prototype for blast() */ 35275793eaSopenharmony_ci 36275793eaSopenharmony_ci#define local static /* for local function definitions */ 37275793eaSopenharmony_ci#define MAXBITS 13 /* maximum code length */ 38275793eaSopenharmony_ci#define MAXWIN 4096 /* maximum window size */ 39275793eaSopenharmony_ci 40275793eaSopenharmony_ci/* input and output state */ 41275793eaSopenharmony_cistruct state { 42275793eaSopenharmony_ci /* input state */ 43275793eaSopenharmony_ci blast_in infun; /* input function provided by user */ 44275793eaSopenharmony_ci void *inhow; /* opaque information passed to infun() */ 45275793eaSopenharmony_ci unsigned char *in; /* next input location */ 46275793eaSopenharmony_ci unsigned left; /* available input at in */ 47275793eaSopenharmony_ci int bitbuf; /* bit buffer */ 48275793eaSopenharmony_ci int bitcnt; /* number of bits in bit buffer */ 49275793eaSopenharmony_ci 50275793eaSopenharmony_ci /* input limit error return state for bits() and decode() */ 51275793eaSopenharmony_ci jmp_buf env; 52275793eaSopenharmony_ci 53275793eaSopenharmony_ci /* output state */ 54275793eaSopenharmony_ci blast_out outfun; /* output function provided by user */ 55275793eaSopenharmony_ci void *outhow; /* opaque information passed to outfun() */ 56275793eaSopenharmony_ci unsigned next; /* index of next write location in out[] */ 57275793eaSopenharmony_ci int first; /* true to check distances (for first 4K) */ 58275793eaSopenharmony_ci unsigned char out[MAXWIN]; /* output buffer and sliding window */ 59275793eaSopenharmony_ci}; 60275793eaSopenharmony_ci 61275793eaSopenharmony_ci/* 62275793eaSopenharmony_ci * Return need bits from the input stream. This always leaves less than 63275793eaSopenharmony_ci * eight bits in the buffer. bits() works properly for need == 0. 64275793eaSopenharmony_ci * 65275793eaSopenharmony_ci * Format notes: 66275793eaSopenharmony_ci * 67275793eaSopenharmony_ci * - Bits are stored in bytes from the least significant bit to the most 68275793eaSopenharmony_ci * significant bit. Therefore bits are dropped from the bottom of the bit 69275793eaSopenharmony_ci * buffer, using shift right, and new bytes are appended to the top of the 70275793eaSopenharmony_ci * bit buffer, using shift left. 71275793eaSopenharmony_ci */ 72275793eaSopenharmony_cilocal int bits(struct state *s, int need) 73275793eaSopenharmony_ci{ 74275793eaSopenharmony_ci int val; /* bit accumulator */ 75275793eaSopenharmony_ci 76275793eaSopenharmony_ci /* load at least need bits into val */ 77275793eaSopenharmony_ci val = s->bitbuf; 78275793eaSopenharmony_ci while (s->bitcnt < need) { 79275793eaSopenharmony_ci if (s->left == 0) { 80275793eaSopenharmony_ci s->left = s->infun(s->inhow, &(s->in)); 81275793eaSopenharmony_ci if (s->left == 0) longjmp(s->env, 1); /* out of input */ 82275793eaSopenharmony_ci } 83275793eaSopenharmony_ci val |= (int)(*(s->in)++) << s->bitcnt; /* load eight bits */ 84275793eaSopenharmony_ci s->left--; 85275793eaSopenharmony_ci s->bitcnt += 8; 86275793eaSopenharmony_ci } 87275793eaSopenharmony_ci 88275793eaSopenharmony_ci /* drop need bits and update buffer, always zero to seven bits left */ 89275793eaSopenharmony_ci s->bitbuf = val >> need; 90275793eaSopenharmony_ci s->bitcnt -= need; 91275793eaSopenharmony_ci 92275793eaSopenharmony_ci /* return need bits, zeroing the bits above that */ 93275793eaSopenharmony_ci return val & ((1 << need) - 1); 94275793eaSopenharmony_ci} 95275793eaSopenharmony_ci 96275793eaSopenharmony_ci/* 97275793eaSopenharmony_ci * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of 98275793eaSopenharmony_ci * each length, which for a canonical code are stepped through in order. 99275793eaSopenharmony_ci * symbol[] are the symbol values in canonical order, where the number of 100275793eaSopenharmony_ci * entries is the sum of the counts in count[]. The decoding process can be 101275793eaSopenharmony_ci * seen in the function decode() below. 102275793eaSopenharmony_ci */ 103275793eaSopenharmony_cistruct huffman { 104275793eaSopenharmony_ci short *count; /* number of symbols of each length */ 105275793eaSopenharmony_ci short *symbol; /* canonically ordered symbols */ 106275793eaSopenharmony_ci}; 107275793eaSopenharmony_ci 108275793eaSopenharmony_ci/* 109275793eaSopenharmony_ci * Decode a code from the stream s using huffman table h. Return the symbol or 110275793eaSopenharmony_ci * a negative value if there is an error. If all of the lengths are zero, i.e. 111275793eaSopenharmony_ci * an empty code, or if the code is incomplete and an invalid code is received, 112275793eaSopenharmony_ci * then -9 is returned after reading MAXBITS bits. 113275793eaSopenharmony_ci * 114275793eaSopenharmony_ci * Format notes: 115275793eaSopenharmony_ci * 116275793eaSopenharmony_ci * - The codes as stored in the compressed data are bit-reversed relative to 117275793eaSopenharmony_ci * a simple integer ordering of codes of the same lengths. Hence below the 118275793eaSopenharmony_ci * bits are pulled from the compressed data one at a time and used to 119275793eaSopenharmony_ci * build the code value reversed from what is in the stream in order to 120275793eaSopenharmony_ci * permit simple integer comparisons for decoding. 121275793eaSopenharmony_ci * 122275793eaSopenharmony_ci * - The first code for the shortest length is all ones. Subsequent codes of 123275793eaSopenharmony_ci * the same length are simply integer decrements of the previous code. When 124275793eaSopenharmony_ci * moving up a length, a one bit is appended to the code. For a complete 125275793eaSopenharmony_ci * code, the last code of the longest length will be all zeros. To support 126275793eaSopenharmony_ci * this ordering, the bits pulled during decoding are inverted to apply the 127275793eaSopenharmony_ci * more "natural" ordering starting with all zeros and incrementing. 128275793eaSopenharmony_ci */ 129275793eaSopenharmony_cilocal int decode(struct state *s, struct huffman *h) 130275793eaSopenharmony_ci{ 131275793eaSopenharmony_ci int len; /* current number of bits in code */ 132275793eaSopenharmony_ci int code; /* len bits being decoded */ 133275793eaSopenharmony_ci int first; /* first code of length len */ 134275793eaSopenharmony_ci int count; /* number of codes of length len */ 135275793eaSopenharmony_ci int index; /* index of first code of length len in symbol table */ 136275793eaSopenharmony_ci int bitbuf; /* bits from stream */ 137275793eaSopenharmony_ci int left; /* bits left in next or left to process */ 138275793eaSopenharmony_ci short *next; /* next number of codes */ 139275793eaSopenharmony_ci 140275793eaSopenharmony_ci bitbuf = s->bitbuf; 141275793eaSopenharmony_ci left = s->bitcnt; 142275793eaSopenharmony_ci code = first = index = 0; 143275793eaSopenharmony_ci len = 1; 144275793eaSopenharmony_ci next = h->count + 1; 145275793eaSopenharmony_ci while (1) { 146275793eaSopenharmony_ci while (left--) { 147275793eaSopenharmony_ci code |= (bitbuf & 1) ^ 1; /* invert code */ 148275793eaSopenharmony_ci bitbuf >>= 1; 149275793eaSopenharmony_ci count = *next++; 150275793eaSopenharmony_ci if (code < first + count) { /* if length len, return symbol */ 151275793eaSopenharmony_ci s->bitbuf = bitbuf; 152275793eaSopenharmony_ci s->bitcnt = (s->bitcnt - len) & 7; 153275793eaSopenharmony_ci return h->symbol[index + (code - first)]; 154275793eaSopenharmony_ci } 155275793eaSopenharmony_ci index += count; /* else update for next length */ 156275793eaSopenharmony_ci first += count; 157275793eaSopenharmony_ci first <<= 1; 158275793eaSopenharmony_ci code <<= 1; 159275793eaSopenharmony_ci len++; 160275793eaSopenharmony_ci } 161275793eaSopenharmony_ci left = (MAXBITS+1) - len; 162275793eaSopenharmony_ci if (left == 0) break; 163275793eaSopenharmony_ci if (s->left == 0) { 164275793eaSopenharmony_ci s->left = s->infun(s->inhow, &(s->in)); 165275793eaSopenharmony_ci if (s->left == 0) longjmp(s->env, 1); /* out of input */ 166275793eaSopenharmony_ci } 167275793eaSopenharmony_ci bitbuf = *(s->in)++; 168275793eaSopenharmony_ci s->left--; 169275793eaSopenharmony_ci if (left > 8) left = 8; 170275793eaSopenharmony_ci } 171275793eaSopenharmony_ci return -9; /* ran out of codes */ 172275793eaSopenharmony_ci} 173275793eaSopenharmony_ci 174275793eaSopenharmony_ci/* 175275793eaSopenharmony_ci * Given a list of repeated code lengths rep[0..n-1], where each byte is a 176275793eaSopenharmony_ci * count (high four bits + 1) and a code length (low four bits), generate the 177275793eaSopenharmony_ci * list of code lengths. This compaction reduces the size of the object code. 178275793eaSopenharmony_ci * Then given the list of code lengths length[0..n-1] representing a canonical 179275793eaSopenharmony_ci * Huffman code for n symbols, construct the tables required to decode those 180275793eaSopenharmony_ci * codes. Those tables are the number of codes of each length, and the symbols 181275793eaSopenharmony_ci * sorted by length, retaining their original order within each length. The 182275793eaSopenharmony_ci * return value is zero for a complete code set, negative for an over- 183275793eaSopenharmony_ci * subscribed code set, and positive for an incomplete code set. The tables 184275793eaSopenharmony_ci * can be used if the return value is zero or positive, but they cannot be used 185275793eaSopenharmony_ci * if the return value is negative. If the return value is zero, it is not 186275793eaSopenharmony_ci * possible for decode() using that table to return an error--any stream of 187275793eaSopenharmony_ci * enough bits will resolve to a symbol. If the return value is positive, then 188275793eaSopenharmony_ci * it is possible for decode() using that table to return an error for received 189275793eaSopenharmony_ci * codes past the end of the incomplete lengths. 190275793eaSopenharmony_ci */ 191275793eaSopenharmony_cilocal int construct(struct huffman *h, const unsigned char *rep, int n) 192275793eaSopenharmony_ci{ 193275793eaSopenharmony_ci int symbol; /* current symbol when stepping through length[] */ 194275793eaSopenharmony_ci int len; /* current length when stepping through h->count[] */ 195275793eaSopenharmony_ci int left; /* number of possible codes left of current length */ 196275793eaSopenharmony_ci short offs[MAXBITS+1]; /* offsets in symbol table for each length */ 197275793eaSopenharmony_ci short length[256]; /* code lengths */ 198275793eaSopenharmony_ci 199275793eaSopenharmony_ci /* convert compact repeat counts into symbol bit length list */ 200275793eaSopenharmony_ci symbol = 0; 201275793eaSopenharmony_ci do { 202275793eaSopenharmony_ci len = *rep++; 203275793eaSopenharmony_ci left = (len >> 4) + 1; 204275793eaSopenharmony_ci len &= 15; 205275793eaSopenharmony_ci do { 206275793eaSopenharmony_ci length[symbol++] = len; 207275793eaSopenharmony_ci } while (--left); 208275793eaSopenharmony_ci } while (--n); 209275793eaSopenharmony_ci n = symbol; 210275793eaSopenharmony_ci 211275793eaSopenharmony_ci /* count number of codes of each length */ 212275793eaSopenharmony_ci for (len = 0; len <= MAXBITS; len++) 213275793eaSopenharmony_ci h->count[len] = 0; 214275793eaSopenharmony_ci for (symbol = 0; symbol < n; symbol++) 215275793eaSopenharmony_ci (h->count[length[symbol]])++; /* assumes lengths are within bounds */ 216275793eaSopenharmony_ci if (h->count[0] == n) /* no codes! */ 217275793eaSopenharmony_ci return 0; /* complete, but decode() will fail */ 218275793eaSopenharmony_ci 219275793eaSopenharmony_ci /* check for an over-subscribed or incomplete set of lengths */ 220275793eaSopenharmony_ci left = 1; /* one possible code of zero length */ 221275793eaSopenharmony_ci for (len = 1; len <= MAXBITS; len++) { 222275793eaSopenharmony_ci left <<= 1; /* one more bit, double codes left */ 223275793eaSopenharmony_ci left -= h->count[len]; /* deduct count from possible codes */ 224275793eaSopenharmony_ci if (left < 0) return left; /* over-subscribed--return negative */ 225275793eaSopenharmony_ci } /* left > 0 means incomplete */ 226275793eaSopenharmony_ci 227275793eaSopenharmony_ci /* generate offsets into symbol table for each length for sorting */ 228275793eaSopenharmony_ci offs[1] = 0; 229275793eaSopenharmony_ci for (len = 1; len < MAXBITS; len++) 230275793eaSopenharmony_ci offs[len + 1] = offs[len] + h->count[len]; 231275793eaSopenharmony_ci 232275793eaSopenharmony_ci /* 233275793eaSopenharmony_ci * put symbols in table sorted by length, by symbol order within each 234275793eaSopenharmony_ci * length 235275793eaSopenharmony_ci */ 236275793eaSopenharmony_ci for (symbol = 0; symbol < n; symbol++) 237275793eaSopenharmony_ci if (length[symbol] != 0) 238275793eaSopenharmony_ci h->symbol[offs[length[symbol]]++] = symbol; 239275793eaSopenharmony_ci 240275793eaSopenharmony_ci /* return zero for complete set, positive for incomplete set */ 241275793eaSopenharmony_ci return left; 242275793eaSopenharmony_ci} 243275793eaSopenharmony_ci 244275793eaSopenharmony_ci/* 245275793eaSopenharmony_ci * Decode PKWare Compression Library stream. 246275793eaSopenharmony_ci * 247275793eaSopenharmony_ci * Format notes: 248275793eaSopenharmony_ci * 249275793eaSopenharmony_ci * - First byte is 0 if literals are uncoded or 1 if they are coded. Second 250275793eaSopenharmony_ci * byte is 4, 5, or 6 for the number of extra bits in the distance code. 251275793eaSopenharmony_ci * This is the base-2 logarithm of the dictionary size minus six. 252275793eaSopenharmony_ci * 253275793eaSopenharmony_ci * - Compressed data is a combination of literals and length/distance pairs 254275793eaSopenharmony_ci * terminated by an end code. Literals are either Huffman coded or 255275793eaSopenharmony_ci * uncoded bytes. A length/distance pair is a coded length followed by a 256275793eaSopenharmony_ci * coded distance to represent a string that occurs earlier in the 257275793eaSopenharmony_ci * uncompressed data that occurs again at the current location. 258275793eaSopenharmony_ci * 259275793eaSopenharmony_ci * - A bit preceding a literal or length/distance pair indicates which comes 260275793eaSopenharmony_ci * next, 0 for literals, 1 for length/distance. 261275793eaSopenharmony_ci * 262275793eaSopenharmony_ci * - If literals are uncoded, then the next eight bits are the literal, in the 263275793eaSopenharmony_ci * normal bit order in the stream, i.e. no bit-reversal is needed. Similarly, 264275793eaSopenharmony_ci * no bit reversal is needed for either the length extra bits or the distance 265275793eaSopenharmony_ci * extra bits. 266275793eaSopenharmony_ci * 267275793eaSopenharmony_ci * - Literal bytes are simply written to the output. A length/distance pair is 268275793eaSopenharmony_ci * an instruction to copy previously uncompressed bytes to the output. The 269275793eaSopenharmony_ci * copy is from distance bytes back in the output stream, copying for length 270275793eaSopenharmony_ci * bytes. 271275793eaSopenharmony_ci * 272275793eaSopenharmony_ci * - Distances pointing before the beginning of the output data are not 273275793eaSopenharmony_ci * permitted. 274275793eaSopenharmony_ci * 275275793eaSopenharmony_ci * - Overlapped copies, where the length is greater than the distance, are 276275793eaSopenharmony_ci * allowed and common. For example, a distance of one and a length of 518 277275793eaSopenharmony_ci * simply copies the last byte 518 times. A distance of four and a length of 278275793eaSopenharmony_ci * twelve copies the last four bytes three times. A simple forward copy 279275793eaSopenharmony_ci * ignoring whether the length is greater than the distance or not implements 280275793eaSopenharmony_ci * this correctly. 281275793eaSopenharmony_ci */ 282275793eaSopenharmony_cilocal int decomp(struct state *s) 283275793eaSopenharmony_ci{ 284275793eaSopenharmony_ci int lit; /* true if literals are coded */ 285275793eaSopenharmony_ci int dict; /* log2(dictionary size) - 6 */ 286275793eaSopenharmony_ci int symbol; /* decoded symbol, extra bits for distance */ 287275793eaSopenharmony_ci int len; /* length for copy */ 288275793eaSopenharmony_ci unsigned dist; /* distance for copy */ 289275793eaSopenharmony_ci int copy; /* copy counter */ 290275793eaSopenharmony_ci unsigned char *from, *to; /* copy pointers */ 291275793eaSopenharmony_ci static int virgin = 1; /* build tables once */ 292275793eaSopenharmony_ci static short litcnt[MAXBITS+1], litsym[256]; /* litcode memory */ 293275793eaSopenharmony_ci static short lencnt[MAXBITS+1], lensym[16]; /* lencode memory */ 294275793eaSopenharmony_ci static short distcnt[MAXBITS+1], distsym[64]; /* distcode memory */ 295275793eaSopenharmony_ci static struct huffman litcode = {litcnt, litsym}; /* length code */ 296275793eaSopenharmony_ci static struct huffman lencode = {lencnt, lensym}; /* length code */ 297275793eaSopenharmony_ci static struct huffman distcode = {distcnt, distsym};/* distance code */ 298275793eaSopenharmony_ci /* bit lengths of literal codes */ 299275793eaSopenharmony_ci static const unsigned char litlen[] = { 300275793eaSopenharmony_ci 11, 124, 8, 7, 28, 7, 188, 13, 76, 4, 10, 8, 12, 10, 12, 10, 8, 23, 8, 301275793eaSopenharmony_ci 9, 7, 6, 7, 8, 7, 6, 55, 8, 23, 24, 12, 11, 7, 9, 11, 12, 6, 7, 22, 5, 302275793eaSopenharmony_ci 7, 24, 6, 11, 9, 6, 7, 22, 7, 11, 38, 7, 9, 8, 25, 11, 8, 11, 9, 12, 303275793eaSopenharmony_ci 8, 12, 5, 38, 5, 38, 5, 11, 7, 5, 6, 21, 6, 10, 53, 8, 7, 24, 10, 27, 304275793eaSopenharmony_ci 44, 253, 253, 253, 252, 252, 252, 13, 12, 45, 12, 45, 12, 61, 12, 45, 305275793eaSopenharmony_ci 44, 173}; 306275793eaSopenharmony_ci /* bit lengths of length codes 0..15 */ 307275793eaSopenharmony_ci static const unsigned char lenlen[] = {2, 35, 36, 53, 38, 23}; 308275793eaSopenharmony_ci /* bit lengths of distance codes 0..63 */ 309275793eaSopenharmony_ci static const unsigned char distlen[] = {2, 20, 53, 230, 247, 151, 248}; 310275793eaSopenharmony_ci static const short base[16] = { /* base for length codes */ 311275793eaSopenharmony_ci 3, 2, 4, 5, 6, 7, 8, 9, 10, 12, 16, 24, 40, 72, 136, 264}; 312275793eaSopenharmony_ci static const char extra[16] = { /* extra bits for length codes */ 313275793eaSopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8}; 314275793eaSopenharmony_ci 315275793eaSopenharmony_ci /* set up decoding tables (once--might not be thread-safe) */ 316275793eaSopenharmony_ci if (virgin) { 317275793eaSopenharmony_ci construct(&litcode, litlen, sizeof(litlen)); 318275793eaSopenharmony_ci construct(&lencode, lenlen, sizeof(lenlen)); 319275793eaSopenharmony_ci construct(&distcode, distlen, sizeof(distlen)); 320275793eaSopenharmony_ci virgin = 0; 321275793eaSopenharmony_ci } 322275793eaSopenharmony_ci 323275793eaSopenharmony_ci /* read header */ 324275793eaSopenharmony_ci lit = bits(s, 8); 325275793eaSopenharmony_ci if (lit > 1) return -1; 326275793eaSopenharmony_ci dict = bits(s, 8); 327275793eaSopenharmony_ci if (dict < 4 || dict > 6) return -2; 328275793eaSopenharmony_ci 329275793eaSopenharmony_ci /* decode literals and length/distance pairs */ 330275793eaSopenharmony_ci do { 331275793eaSopenharmony_ci if (bits(s, 1)) { 332275793eaSopenharmony_ci /* get length */ 333275793eaSopenharmony_ci symbol = decode(s, &lencode); 334275793eaSopenharmony_ci len = base[symbol] + bits(s, extra[symbol]); 335275793eaSopenharmony_ci if (len == 519) break; /* end code */ 336275793eaSopenharmony_ci 337275793eaSopenharmony_ci /* get distance */ 338275793eaSopenharmony_ci symbol = len == 2 ? 2 : dict; 339275793eaSopenharmony_ci dist = decode(s, &distcode) << symbol; 340275793eaSopenharmony_ci dist += bits(s, symbol); 341275793eaSopenharmony_ci dist++; 342275793eaSopenharmony_ci if (s->first && dist > s->next) 343275793eaSopenharmony_ci return -3; /* distance too far back */ 344275793eaSopenharmony_ci 345275793eaSopenharmony_ci /* copy length bytes from distance bytes back */ 346275793eaSopenharmony_ci do { 347275793eaSopenharmony_ci to = s->out + s->next; 348275793eaSopenharmony_ci from = to - dist; 349275793eaSopenharmony_ci copy = MAXWIN; 350275793eaSopenharmony_ci if (s->next < dist) { 351275793eaSopenharmony_ci from += copy; 352275793eaSopenharmony_ci copy = dist; 353275793eaSopenharmony_ci } 354275793eaSopenharmony_ci copy -= s->next; 355275793eaSopenharmony_ci if (copy > len) copy = len; 356275793eaSopenharmony_ci len -= copy; 357275793eaSopenharmony_ci s->next += copy; 358275793eaSopenharmony_ci do { 359275793eaSopenharmony_ci *to++ = *from++; 360275793eaSopenharmony_ci } while (--copy); 361275793eaSopenharmony_ci if (s->next == MAXWIN) { 362275793eaSopenharmony_ci if (s->outfun(s->outhow, s->out, s->next)) return 1; 363275793eaSopenharmony_ci s->next = 0; 364275793eaSopenharmony_ci s->first = 0; 365275793eaSopenharmony_ci } 366275793eaSopenharmony_ci } while (len != 0); 367275793eaSopenharmony_ci } 368275793eaSopenharmony_ci else { 369275793eaSopenharmony_ci /* get literal and write it */ 370275793eaSopenharmony_ci symbol = lit ? decode(s, &litcode) : bits(s, 8); 371275793eaSopenharmony_ci s->out[s->next++] = symbol; 372275793eaSopenharmony_ci if (s->next == MAXWIN) { 373275793eaSopenharmony_ci if (s->outfun(s->outhow, s->out, s->next)) return 1; 374275793eaSopenharmony_ci s->next = 0; 375275793eaSopenharmony_ci s->first = 0; 376275793eaSopenharmony_ci } 377275793eaSopenharmony_ci } 378275793eaSopenharmony_ci } while (1); 379275793eaSopenharmony_ci return 0; 380275793eaSopenharmony_ci} 381275793eaSopenharmony_ci 382275793eaSopenharmony_ci/* See comments in blast.h */ 383275793eaSopenharmony_ciint blast(blast_in infun, void *inhow, blast_out outfun, void *outhow, 384275793eaSopenharmony_ci unsigned *left, unsigned char **in) 385275793eaSopenharmony_ci{ 386275793eaSopenharmony_ci struct state s; /* input/output state */ 387275793eaSopenharmony_ci int err; /* return value */ 388275793eaSopenharmony_ci 389275793eaSopenharmony_ci /* initialize input state */ 390275793eaSopenharmony_ci s.infun = infun; 391275793eaSopenharmony_ci s.inhow = inhow; 392275793eaSopenharmony_ci if (left != NULL && *left) { 393275793eaSopenharmony_ci s.left = *left; 394275793eaSopenharmony_ci s.in = *in; 395275793eaSopenharmony_ci } 396275793eaSopenharmony_ci else 397275793eaSopenharmony_ci s.left = 0; 398275793eaSopenharmony_ci s.bitbuf = 0; 399275793eaSopenharmony_ci s.bitcnt = 0; 400275793eaSopenharmony_ci 401275793eaSopenharmony_ci /* initialize output state */ 402275793eaSopenharmony_ci s.outfun = outfun; 403275793eaSopenharmony_ci s.outhow = outhow; 404275793eaSopenharmony_ci s.next = 0; 405275793eaSopenharmony_ci s.first = 1; 406275793eaSopenharmony_ci 407275793eaSopenharmony_ci /* return if bits() or decode() tries to read past available input */ 408275793eaSopenharmony_ci if (setjmp(s.env) != 0) /* if came back here via longjmp(), */ 409275793eaSopenharmony_ci err = 2; /* then skip decomp(), return error */ 410275793eaSopenharmony_ci else 411275793eaSopenharmony_ci err = decomp(&s); /* decompress */ 412275793eaSopenharmony_ci 413275793eaSopenharmony_ci /* return unused input */ 414275793eaSopenharmony_ci if (left != NULL) 415275793eaSopenharmony_ci *left = s.left; 416275793eaSopenharmony_ci if (in != NULL) 417275793eaSopenharmony_ci *in = s.left ? s.in : NULL; 418275793eaSopenharmony_ci 419275793eaSopenharmony_ci /* write any leftover output and update the error code if needed */ 420275793eaSopenharmony_ci if (err != 1 && s.next && s.outfun(s.outhow, s.out, s.next) && err == 0) 421275793eaSopenharmony_ci err = 1; 422275793eaSopenharmony_ci return err; 423275793eaSopenharmony_ci} 424275793eaSopenharmony_ci 425275793eaSopenharmony_ci#ifdef TEST 426275793eaSopenharmony_ci/* Example of how to use blast() */ 427275793eaSopenharmony_ci#include <stdio.h> 428275793eaSopenharmony_ci#include <stdlib.h> 429275793eaSopenharmony_ci 430275793eaSopenharmony_ci#define CHUNK 16384 431275793eaSopenharmony_ci 432275793eaSopenharmony_cilocal unsigned inf(void *how, unsigned char **buf) 433275793eaSopenharmony_ci{ 434275793eaSopenharmony_ci static unsigned char hold[CHUNK]; 435275793eaSopenharmony_ci 436275793eaSopenharmony_ci *buf = hold; 437275793eaSopenharmony_ci return fread(hold, 1, CHUNK, (FILE *)how); 438275793eaSopenharmony_ci} 439275793eaSopenharmony_ci 440275793eaSopenharmony_cilocal int outf(void *how, unsigned char *buf, unsigned len) 441275793eaSopenharmony_ci{ 442275793eaSopenharmony_ci return fwrite(buf, 1, len, (FILE *)how) != len; 443275793eaSopenharmony_ci} 444275793eaSopenharmony_ci 445275793eaSopenharmony_ci/* Decompress a PKWare Compression Library stream from stdin to stdout */ 446275793eaSopenharmony_ciint main(void) 447275793eaSopenharmony_ci{ 448275793eaSopenharmony_ci int ret; 449275793eaSopenharmony_ci unsigned left; 450275793eaSopenharmony_ci 451275793eaSopenharmony_ci /* decompress to stdout */ 452275793eaSopenharmony_ci left = 0; 453275793eaSopenharmony_ci ret = blast(inf, stdin, outf, stdout, &left, NULL); 454275793eaSopenharmony_ci if (ret != 0) 455275793eaSopenharmony_ci fprintf(stderr, "blast error: %d\n", ret); 456275793eaSopenharmony_ci 457275793eaSopenharmony_ci /* count any leftover bytes */ 458275793eaSopenharmony_ci while (getchar() != EOF) 459275793eaSopenharmony_ci left++; 460275793eaSopenharmony_ci if (left) 461275793eaSopenharmony_ci fprintf(stderr, "blast warning: %u unused bytes of input\n", left); 462275793eaSopenharmony_ci 463275793eaSopenharmony_ci /* return blast() error code */ 464275793eaSopenharmony_ci return ret; 465275793eaSopenharmony_ci} 466275793eaSopenharmony_ci#endif 467