123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253 |
- #include "libbb.h"
- #include "bb_archive.h"
- #ifdef DEBUG
- # define Assert(cond,msg) { if (!(cond)) bb_error_msg(msg); }
- # define Trace(x) fprintf x
- # define Tracev(x) {if (verbose) fprintf x; }
- # define Tracevv(x) {if (verbose > 1) fprintf x; }
- # define Tracec(c,x) {if (verbose && (c)) fprintf x; }
- # define Tracecv(c,x) {if (verbose > 1 && (c)) fprintf x; }
- #else
- # define Assert(cond,msg)
- # define Trace(x)
- # define Tracev(x)
- # define Tracevv(x)
- # define Tracec(c,x)
- # define Tracecv(c,x)
- #endif
- #if CONFIG_GZIP_FAST == 0
- # define SMALL_MEM
- #elif CONFIG_GZIP_FAST == 1
- # define MEDIUM_MEM
- #elif CONFIG_GZIP_FAST == 2
- # define BIG_MEM
- #else
- # error "Invalid CONFIG_GZIP_FAST value"
- #endif
- #ifndef INBUFSIZ
- # ifdef SMALL_MEM
- # define INBUFSIZ 0x2000
- # else
- # define INBUFSIZ 0x8000
- # endif
- #endif
- #ifndef OUTBUFSIZ
- # ifdef SMALL_MEM
- # define OUTBUFSIZ 8192
- # else
- # define OUTBUFSIZ 16384
- # endif
- #endif
- #ifndef DIST_BUFSIZE
- # ifdef SMALL_MEM
- # define DIST_BUFSIZE 0x2000
- # else
- # define DIST_BUFSIZE 0x8000
- # endif
- #endif
- #define ASCII_FLAG 0x01
- #define CONTINUATION 0x02
- #define EXTRA_FIELD 0x04
- #define ORIG_NAME 0x08
- #define COMMENT 0x10
- #define RESERVED 0xC0
- #define UNKNOWN 0xffff
- #define BINARY 0
- #define ASCII 1
- #ifndef WSIZE
- # define WSIZE 0x8000
- #endif
- #define MIN_MATCH 3
- #define MAX_MATCH 258
- #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
- #define MAX_DIST (WSIZE-MIN_LOOKAHEAD)
- #ifndef MAX_PATH_LEN
- # define MAX_PATH_LEN 1024
- #endif
- #define seekable() 0
- #define translate_eol 0
- #ifndef BITS
- # define BITS 16
- #endif
- #define INIT_BITS 9
- #define BIT_MASK 0x1f
- #ifdef MAX_EXT_CHARS
- # define MAX_SUFFIX MAX_EXT_CHARS
- #else
- # define MAX_SUFFIX 30
- #endif
- #ifdef SMALL_MEM
- # define HASH_BITS 13
- #endif
- #ifdef MEDIUM_MEM
- # define HASH_BITS 14
- #endif
- #ifndef HASH_BITS
- # define HASH_BITS 15
-
- #endif
- #define HASH_SIZE (unsigned)(1<<HASH_BITS)
- #define HASH_MASK (HASH_SIZE-1)
- #define WMASK (WSIZE-1)
- #ifndef TOO_FAR
- # define TOO_FAR 4096
- #endif
- typedef uint8_t uch;
- typedef uint16_t ush;
- typedef uint32_t ulg;
- typedef int32_t lng;
- typedef ush Pos;
- typedef unsigned IPos;
- enum {
- WINDOW_SIZE = 2 * WSIZE,
- #if !ENABLE_FEATURE_GZIP_LEVELS
- max_chain_length = 4096,
- max_lazy_match = 258,
- max_insert_length = max_lazy_match,
- good_match = 32,
- nice_match = 258,
- #endif
- };
- struct globals {
- #if ENABLE_FEATURE_GZIP_LEVELS
- unsigned max_chain_length;
- unsigned max_lazy_match;
- unsigned good_match;
- unsigned nice_match;
- #define max_chain_length (G1.max_chain_length)
- #define max_lazy_match (G1.max_lazy_match)
- #define good_match (G1.good_match)
- #define nice_match (G1.nice_match)
- #endif
- lng block_start;
- unsigned ins_h;
- #define H_SHIFT ((HASH_BITS+MIN_MATCH-1) / MIN_MATCH)
- unsigned prev_length;
- unsigned strstart;
- unsigned match_start;
- unsigned lookahead;
- #define DECLARE(type, array, size) \
- type * array
- #define ALLOC(type, array, size) \
- array = xzalloc((size_t)(((size)+1L)/2) * 2*sizeof(type))
- #define FREE(array) \
- do { free(array); array = NULL; } while (0)
-
-
-
- DECLARE(uch, l_buf, INBUFSIZ);
- DECLARE(ush, d_buf, DIST_BUFSIZE);
- DECLARE(uch, outbuf, OUTBUFSIZ);
- DECLARE(uch, window, 2L * WSIZE);
-
- DECLARE(ush, prev, 1L << BITS);
-
- #define head (G1.prev + WSIZE)
- ulg isize;
- #define ifd STDIN_FILENO
- #define ofd STDOUT_FILENO
- #ifdef DEBUG
- unsigned insize;
- #endif
- unsigned outcnt;
- smallint eofile;
- unsigned short bi_buf;
- #undef BUF_SIZE
- #define BUF_SIZE (8 * sizeof(G1.bi_buf))
- int bi_valid;
- #ifdef DEBUG
- ulg bits_sent;
- #endif
-
- uint32_t crc;
- };
- #define G1 (*(ptr_to_globals - 1))
- static void flush_outbuf(void)
- {
- if (G1.outcnt == 0)
- return;
- xwrite(ofd, (char *) G1.outbuf, G1.outcnt);
- G1.outcnt = 0;
- }
- #define put_8bit(c) \
- do { \
- G1.outbuf[G1.outcnt++] = (c); \
- if (G1.outcnt == OUTBUFSIZ) \
- flush_outbuf(); \
- } while (0)
- static void put_16bit(ush w)
- {
-
- unsigned outcnt = G1.outcnt;
- uch *dst = &G1.outbuf[outcnt];
- #if BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN
- if (outcnt < OUTBUFSIZ-2) {
-
- ush *dst16 = (void*) dst;
- *dst16 = w;
- G1.outcnt = outcnt + 2;
- return;
- }
- *dst = (uch)w;
- w >>= 8;
- #else
- *dst = (uch)w;
- w >>= 8;
- if (outcnt < OUTBUFSIZ-2) {
-
- dst[1] = w;
- G1.outcnt = outcnt + 2;
- return;
- }
- #endif
-
- G1.outcnt = ++outcnt;
- if (outcnt == OUTBUFSIZ)
- flush_outbuf();
- put_8bit(w);
- }
- static void put_32bit(ulg n)
- {
- put_16bit(n);
- put_16bit(n >> 16);
- }
- static void updcrc(uch * s, unsigned n)
- {
- G1.crc = crc32_block_endian0(G1.crc, s, n, global_crc32_table );
- }
- static unsigned file_read(void *buf, unsigned size)
- {
- unsigned len;
- Assert(G1.insize == 0, "l_buf not empty");
- len = safe_read(ifd, buf, size);
- if (len == (unsigned)(-1) || len == 0)
- return len;
- updcrc(buf, len);
- G1.isize += len;
- return len;
- }
- static void send_bits(int value, int length)
- {
- #ifdef DEBUG
- Tracev((stderr, " l %2d v %4x ", length, value));
- Assert(length > 0 && length <= 15, "invalid length");
- G1.bits_sent += length;
- #endif
-
- if (G1.bi_valid > (int) BUF_SIZE - length) {
- G1.bi_buf |= (value << G1.bi_valid);
- put_16bit(G1.bi_buf);
- G1.bi_buf = (ush) value >> (BUF_SIZE - G1.bi_valid);
- G1.bi_valid += length - BUF_SIZE;
- } else {
- G1.bi_buf |= value << G1.bi_valid;
- G1.bi_valid += length;
- }
- }
- static unsigned bi_reverse(unsigned code, int len)
- {
- unsigned res = 0;
- while (1) {
- res |= code & 1;
- if (--len <= 0) return res;
- code >>= 1;
- res <<= 1;
- }
- }
- static void bi_windup(void)
- {
- if (G1.bi_valid > 8) {
- put_16bit(G1.bi_buf);
- } else if (G1.bi_valid > 0) {
- put_8bit(G1.bi_buf);
- }
- G1.bi_buf = 0;
- G1.bi_valid = 0;
- #ifdef DEBUG
- G1.bits_sent = (G1.bits_sent + 7) & ~7;
- #endif
- }
- static void copy_block(char *buf, unsigned len, int header)
- {
- bi_windup();
- if (header) {
- put_16bit(len);
- put_16bit(~len);
- #ifdef DEBUG
- G1.bits_sent += 2 * 16;
- #endif
- }
- #ifdef DEBUG
- G1.bits_sent += (ulg) len << 3;
- #endif
- while (len--) {
- put_8bit(*buf++);
- }
- }
- static void fill_window(void)
- {
- unsigned n, m;
- unsigned more = WINDOW_SIZE - G1.lookahead - G1.strstart;
-
-
- if (more == (unsigned) -1) {
-
- more--;
- } else if (G1.strstart >= WSIZE + MAX_DIST) {
-
- Assert(WINDOW_SIZE == 2 * WSIZE, "no sliding with BIG_MEM");
- memcpy(G1.window, G1.window + WSIZE, WSIZE);
- G1.match_start -= WSIZE;
- G1.strstart -= WSIZE;
- G1.block_start -= WSIZE;
- for (n = 0; n < HASH_SIZE; n++) {
- m = head[n];
- head[n] = (Pos) (m >= WSIZE ? m - WSIZE : 0);
- }
- for (n = 0; n < WSIZE; n++) {
- m = G1.prev[n];
- G1.prev[n] = (Pos) (m >= WSIZE ? m - WSIZE : 0);
-
- }
- more += WSIZE;
- }
-
- if (!G1.eofile) {
- n = file_read(G1.window + G1.strstart + G1.lookahead, more);
- if (n == 0 || n == (unsigned) -1) {
- G1.eofile = 1;
- } else {
- G1.lookahead += n;
- }
- }
- }
- static int longest_match(IPos cur_match)
- {
- unsigned chain_length = max_chain_length;
- uch *scan = G1.window + G1.strstart;
- uch *match;
- int len;
- int best_len = G1.prev_length;
- IPos limit = G1.strstart > (IPos) MAX_DIST ? G1.strstart - (IPos) MAX_DIST : 0;
-
- #if HASH_BITS < 8 || MAX_MATCH != 258
- # error Code too clever
- #endif
- uch *strend = G1.window + G1.strstart + MAX_MATCH;
- uch scan_end1 = scan[best_len - 1];
- uch scan_end = scan[best_len];
-
- if (G1.prev_length >= good_match) {
- chain_length >>= 2;
- }
- Assert(G1.strstart <= WINDOW_SIZE - MIN_LOOKAHEAD, "insufficient lookahead");
- do {
- Assert(cur_match < G1.strstart, "no future");
- match = G1.window + cur_match;
-
- if (match[best_len] != scan_end
- || match[best_len - 1] != scan_end1
- || *match != *scan || *++match != scan[1]
- ) {
- continue;
- }
-
- scan += 2, match++;
-
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match && scan < strend);
- len = MAX_MATCH - (int) (strend - scan);
- scan = strend - MAX_MATCH;
- if (len > best_len) {
- G1.match_start = cur_match;
- best_len = len;
- if (len >= nice_match)
- break;
- scan_end1 = scan[best_len - 1];
- scan_end = scan[best_len];
- }
- } while ((cur_match = G1.prev[cur_match & WMASK]) > limit
- && --chain_length != 0);
- return best_len;
- }
- #ifdef DEBUG
- static void check_match(IPos start, IPos match, int length)
- {
-
- if (memcmp(G1.window + match, G1.window + start, length) != 0) {
- bb_error_msg(" start %d, match %d, length %d", start, match, length);
- bb_error_msg("invalid match");
- }
- if (verbose > 1) {
- bb_error_msg("\\[%d,%d]", start - match, length);
- do {
- bb_putchar_stderr(G1.window[start++]);
- } while (--length != 0);
- }
- }
- #else
- # define check_match(start, match, length) ((void)0)
- #endif
- #define MAX_BITS 15
- #define MAX_BL_BITS 7
- #define LENGTH_CODES 29
- #define LITERALS 256
- #define END_BLOCK 256
- #define L_CODES (LITERALS+1+LENGTH_CODES)
- #define D_CODES 30
- #define BL_CODES 19
- static const uint8_t extra_lbits[LENGTH_CODES] ALIGN1 = {
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4,
- 4, 4, 5, 5, 5, 5, 0
- };
- static const uint8_t extra_dbits[D_CODES] ALIGN1 = {
- 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
- 10, 10, 11, 11, 12, 12, 13, 13
- };
- static const uint8_t extra_blbits[BL_CODES] ALIGN1 = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7 };
- static const uint8_t bl_order[BL_CODES] ALIGN1 = {
- 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
- #define STORED_BLOCK 0
- #define STATIC_TREES 1
- #define DYN_TREES 2
- #ifndef LIT_BUFSIZE
- # ifdef SMALL_MEM
- # define LIT_BUFSIZE 0x2000
- # else
- # ifdef MEDIUM_MEM
- # define LIT_BUFSIZE 0x4000
- # else
- # define LIT_BUFSIZE 0x8000
- # endif
- # endif
- #endif
- #ifndef DIST_BUFSIZE
- # define DIST_BUFSIZE LIT_BUFSIZE
- #endif
- #define REP_3_6 16
- #define REPZ_3_10 17
- #define REPZ_11_138 18
- typedef struct ct_data {
- union {
- ush freq;
- ush code;
- } fc;
- union {
- ush dad;
- ush len;
- } dl;
- } ct_data;
- #define Freq fc.freq
- #define Code fc.code
- #define Dad dl.dad
- #define Len dl.len
- #define HEAP_SIZE (2*L_CODES + 1)
- typedef struct tree_desc {
- ct_data *dyn_tree;
- ct_data *static_tree;
- const uint8_t *extra_bits;
- int extra_base;
- int elems;
- int max_length;
- int max_code;
- } tree_desc;
- struct globals2 {
- ush heap[HEAP_SIZE];
- int heap_len;
- int heap_max;
- ct_data dyn_ltree[HEAP_SIZE];
- ct_data dyn_dtree[2 * D_CODES + 1];
- ct_data static_ltree[L_CODES + 2];
- ct_data static_dtree[D_CODES];
- ct_data bl_tree[2 * BL_CODES + 1];
- tree_desc l_desc;
- tree_desc d_desc;
- tree_desc bl_desc;
- ush bl_count[MAX_BITS + 1];
- uch depth[2 * L_CODES + 1];
- uch length_code[MAX_MATCH - MIN_MATCH + 1];
- uch dist_code[512];
- int base_length[LENGTH_CODES];
- int base_dist[D_CODES];
- uch flag_buf[LIT_BUFSIZE / 8];
- unsigned last_lit;
- unsigned last_dist;
- unsigned last_flags;
- uch flags;
- uch flag_bit;
- ulg opt_len;
- ulg static_len;
- ulg compressed_len;
- };
- #define G2ptr ((struct globals2*)(ptr_to_globals))
- #define G2 (*G2ptr)
- static void gen_codes(ct_data * tree, int max_code);
- static void build_tree(tree_desc * desc);
- static void scan_tree(ct_data * tree, int max_code);
- static void send_tree(ct_data * tree, int max_code);
- static int build_bl_tree(void);
- static void send_all_trees(int lcodes, int dcodes, int blcodes);
- static void compress_block(ct_data * ltree, ct_data * dtree);
- #ifndef DEBUG
- # define SEND_CODE(c, tree) send_bits(tree[c].Code, tree[c].Len)
- #else
- # define SEND_CODE(c, tree) \
- { \
- if (verbose > 1) bb_error_msg("\ncd %3d ", (c)); \
- send_bits(tree[c].Code, tree[c].Len); \
- }
- #endif
- #define D_CODE(dist) \
- ((dist) < 256 ? G2.dist_code[dist] : G2.dist_code[256 + ((dist)>>7)])
- static void init_block(void)
- {
- int n;
-
- for (n = 0; n < L_CODES; n++)
- G2.dyn_ltree[n].Freq = 0;
- for (n = 0; n < D_CODES; n++)
- G2.dyn_dtree[n].Freq = 0;
- for (n = 0; n < BL_CODES; n++)
- G2.bl_tree[n].Freq = 0;
- G2.dyn_ltree[END_BLOCK].Freq = 1;
- G2.opt_len = G2.static_len = 0;
- G2.last_lit = G2.last_dist = G2.last_flags = 0;
- G2.flags = 0;
- G2.flag_bit = 1;
- }
- #define SMALLER(tree, n, m) \
- (tree[n].Freq < tree[m].Freq \
- || (tree[n].Freq == tree[m].Freq && G2.depth[n] <= G2.depth[m]))
- static void pqdownheap(ct_data * tree, int k)
- {
- int v = G2.heap[k];
- int j = k << 1;
- while (j <= G2.heap_len) {
-
- if (j < G2.heap_len && SMALLER(tree, G2.heap[j + 1], G2.heap[j]))
- j++;
-
- if (SMALLER(tree, v, G2.heap[j]))
- break;
-
- G2.heap[k] = G2.heap[j];
- k = j;
-
- j <<= 1;
- }
- G2.heap[k] = v;
- }
- static void gen_bitlen(tree_desc * desc)
- {
- ct_data *tree = desc->dyn_tree;
- const uint8_t *extra = desc->extra_bits;
- int base = desc->extra_base;
- int max_code = desc->max_code;
- int max_length = desc->max_length;
- ct_data *stree = desc->static_tree;
- int h;
- int n, m;
- int bits;
- int xbits;
- ush f;
- int overflow = 0;
- for (bits = 0; bits <= MAX_BITS; bits++)
- G2.bl_count[bits] = 0;
-
- tree[G2.heap[G2.heap_max]].Len = 0;
- for (h = G2.heap_max + 1; h < HEAP_SIZE; h++) {
- n = G2.heap[h];
- bits = tree[tree[n].Dad].Len + 1;
- if (bits > max_length) {
- bits = max_length;
- overflow++;
- }
- tree[n].Len = (ush) bits;
-
- if (n > max_code)
- continue;
- G2.bl_count[bits]++;
- xbits = 0;
- if (n >= base)
- xbits = extra[n - base];
- f = tree[n].Freq;
- G2.opt_len += (ulg) f *(bits + xbits);
- if (stree)
- G2.static_len += (ulg) f * (stree[n].Len + xbits);
- }
- if (overflow == 0)
- return;
- Trace((stderr, "\nbit length overflow\n"));
-
-
- do {
- bits = max_length - 1;
- while (G2.bl_count[bits] == 0)
- bits--;
- G2.bl_count[bits]--;
- G2.bl_count[bits + 1] += 2;
- G2.bl_count[max_length]--;
-
- overflow -= 2;
- } while (overflow > 0);
-
- for (bits = max_length; bits != 0; bits--) {
- n = G2.bl_count[bits];
- while (n != 0) {
- m = G2.heap[--h];
- if (m > max_code)
- continue;
- if (tree[m].Len != (unsigned) bits) {
- Trace((stderr, "code %d bits %d->%d\n", m, tree[m].Len, bits));
- G2.opt_len += ((int32_t) bits - tree[m].Len) * tree[m].Freq;
- tree[m].Len = bits;
- }
- n--;
- }
- }
- }
- static void gen_codes(ct_data * tree, int max_code)
- {
- ush next_code[MAX_BITS + 1];
- ush code = 0;
- int bits;
- int n;
-
- for (bits = 1; bits <= MAX_BITS; bits++) {
- next_code[bits] = code = (code + G2.bl_count[bits - 1]) << 1;
- }
-
- Assert(code + G2.bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1,
- "inconsistent bit counts");
- Tracev((stderr, "\ngen_codes: max_code %d ", max_code));
- for (n = 0; n <= max_code; n++) {
- int len = tree[n].Len;
- if (len == 0)
- continue;
-
- tree[n].Code = bi_reverse(next_code[len]++, len);
- Tracec(tree != G2.static_ltree,
- (stderr, "\nn %3d %c l %2d c %4x (%x) ", n,
- (n > ' ' ? n : ' '), len, tree[n].Code,
- next_code[len] - 1));
- }
- }
- #define SMALLEST 1
- #define PQREMOVE(tree, top) \
- do { \
- top = G2.heap[SMALLEST]; \
- G2.heap[SMALLEST] = G2.heap[G2.heap_len--]; \
- pqdownheap(tree, SMALLEST); \
- } while (0)
- static void build_tree(tree_desc * desc)
- {
- ct_data *tree = desc->dyn_tree;
- ct_data *stree = desc->static_tree;
- int elems = desc->elems;
- int n, m;
- int max_code = -1;
- int node = elems;
-
- G2.heap_len = 0;
- G2.heap_max = HEAP_SIZE;
- for (n = 0; n < elems; n++) {
- if (tree[n].Freq != 0) {
- G2.heap[++G2.heap_len] = max_code = n;
- G2.depth[n] = 0;
- } else {
- tree[n].Len = 0;
- }
- }
-
- while (G2.heap_len < 2) {
- int new = G2.heap[++G2.heap_len] = (max_code < 2 ? ++max_code : 0);
- tree[new].Freq = 1;
- G2.depth[new] = 0;
- G2.opt_len--;
- if (stree)
- G2.static_len -= stree[new].Len;
-
- }
- desc->max_code = max_code;
-
- for (n = G2.heap_len / 2; n >= 1; n--)
- pqdownheap(tree, n);
-
- do {
- PQREMOVE(tree, n);
- m = G2.heap[SMALLEST];
- G2.heap[--G2.heap_max] = n;
- G2.heap[--G2.heap_max] = m;
-
- tree[node].Freq = tree[n].Freq + tree[m].Freq;
- G2.depth[node] = MAX(G2.depth[n], G2.depth[m]) + 1;
- tree[n].Dad = tree[m].Dad = (ush) node;
- #ifdef DUMP_BL_TREE
- if (tree == G2.bl_tree) {
- bb_error_msg("\nnode %d(%d), sons %d(%d) %d(%d)",
- node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
- }
- #endif
-
- G2.heap[SMALLEST] = node++;
- pqdownheap(tree, SMALLEST);
- } while (G2.heap_len >= 2);
- G2.heap[--G2.heap_max] = G2.heap[SMALLEST];
-
- gen_bitlen((tree_desc *) desc);
-
- gen_codes((ct_data *) tree, max_code);
- }
- static void scan_tree(ct_data * tree, int max_code)
- {
- int n;
- int prevlen = -1;
- int curlen;
- int nextlen = tree[0].Len;
- int count = 0;
- int max_count = 7;
- int min_count = 4;
- if (nextlen == 0) {
- max_count = 138;
- min_count = 3;
- }
- tree[max_code + 1].Len = 0xffff;
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen;
- nextlen = tree[n + 1].Len;
- if (++count < max_count && curlen == nextlen)
- continue;
- if (count < min_count) {
- G2.bl_tree[curlen].Freq += count;
- } else if (curlen != 0) {
- if (curlen != prevlen)
- G2.bl_tree[curlen].Freq++;
- G2.bl_tree[REP_3_6].Freq++;
- } else if (count <= 10) {
- G2.bl_tree[REPZ_3_10].Freq++;
- } else {
- G2.bl_tree[REPZ_11_138].Freq++;
- }
- count = 0;
- prevlen = curlen;
- max_count = 7;
- min_count = 4;
- if (nextlen == 0) {
- max_count = 138;
- min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6;
- min_count = 3;
- }
- }
- }
- static void send_tree(ct_data * tree, int max_code)
- {
- int n;
- int prevlen = -1;
- int curlen;
- int nextlen = tree[0].Len;
- int count = 0;
- int max_count = 7;
- int min_count = 4;
- if (nextlen == 0)
- max_count = 138, min_count = 3;
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen;
- nextlen = tree[n + 1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- do {
- SEND_CODE(curlen, G2.bl_tree);
- } while (--count);
- } else if (curlen != 0) {
- if (curlen != prevlen) {
- SEND_CODE(curlen, G2.bl_tree);
- count--;
- }
- Assert(count >= 3 && count <= 6, " 3_6?");
- SEND_CODE(REP_3_6, G2.bl_tree);
- send_bits(count - 3, 2);
- } else if (count <= 10) {
- SEND_CODE(REPZ_3_10, G2.bl_tree);
- send_bits(count - 3, 3);
- } else {
- SEND_CODE(REPZ_11_138, G2.bl_tree);
- send_bits(count - 11, 7);
- }
- count = 0;
- prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138;
- min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6;
- min_count = 3;
- } else {
- max_count = 7;
- min_count = 4;
- }
- }
- }
- static int build_bl_tree(void)
- {
- int max_blindex;
-
- scan_tree(G2.dyn_ltree, G2.l_desc.max_code);
- scan_tree(G2.dyn_dtree, G2.d_desc.max_code);
-
- build_tree(&G2.bl_desc);
-
-
- for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {
- if (G2.bl_tree[bl_order[max_blindex]].Len != 0)
- break;
- }
-
- G2.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
- Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", G2.opt_len, G2.static_len));
- return max_blindex;
- }
- static void send_all_trees(int lcodes, int dcodes, int blcodes)
- {
- int rank;
- Assert(lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
- Assert(lcodes <= L_CODES && dcodes <= D_CODES
- && blcodes <= BL_CODES, "too many codes");
- Tracev((stderr, "\nbl counts: "));
- send_bits(lcodes - 257, 5);
- send_bits(dcodes - 1, 5);
- send_bits(blcodes - 4, 4);
- for (rank = 0; rank < blcodes; rank++) {
- Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
- send_bits(G2.bl_tree[bl_order[rank]].Len, 3);
- }
- Tracev((stderr, "\nbl tree: sent %ld", G1.bits_sent));
- send_tree((ct_data *) G2.dyn_ltree, lcodes - 1);
- Tracev((stderr, "\nlit tree: sent %ld", G1.bits_sent));
- send_tree((ct_data *) G2.dyn_dtree, dcodes - 1);
- Tracev((stderr, "\ndist tree: sent %ld", G1.bits_sent));
- }
- static int ct_tally(int dist, int lc)
- {
- G1.l_buf[G2.last_lit++] = lc;
- if (dist == 0) {
-
- G2.dyn_ltree[lc].Freq++;
- } else {
-
- dist--;
- Assert((ush) dist < (ush) MAX_DIST
- && (ush) lc <= (ush) (MAX_MATCH - MIN_MATCH)
- && (ush) D_CODE(dist) < (ush) D_CODES, "ct_tally: bad match"
- );
- G2.dyn_ltree[G2.length_code[lc] + LITERALS + 1].Freq++;
- G2.dyn_dtree[D_CODE(dist)].Freq++;
- G1.d_buf[G2.last_dist++] = dist;
- G2.flags |= G2.flag_bit;
- }
- G2.flag_bit <<= 1;
-
- if ((G2.last_lit & 7) == 0) {
- G2.flag_buf[G2.last_flags++] = G2.flags;
- G2.flags = 0;
- G2.flag_bit = 1;
- }
-
- if ((G2.last_lit & 0xfff) == 0) {
-
- ulg out_length = G2.last_lit * 8L;
- ulg in_length = (ulg) G1.strstart - G1.block_start;
- int dcode;
- for (dcode = 0; dcode < D_CODES; dcode++) {
- out_length += G2.dyn_dtree[dcode].Freq * (5L + extra_dbits[dcode]);
- }
- out_length >>= 3;
- Trace((stderr,
- "\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ",
- G2.last_lit, G2.last_dist, in_length, out_length,
- 100L - out_length * 100L / in_length));
- if (G2.last_dist < G2.last_lit / 2 && out_length < in_length / 2)
- return 1;
- }
- return (G2.last_lit == LIT_BUFSIZE - 1 || G2.last_dist == DIST_BUFSIZE);
-
- }
- static void compress_block(ct_data * ltree, ct_data * dtree)
- {
- unsigned dist;
- int lc;
- unsigned lx = 0;
- unsigned dx = 0;
- unsigned fx = 0;
- uch flag = 0;
- unsigned code;
- int extra;
- if (G2.last_lit != 0) do {
- if ((lx & 7) == 0)
- flag = G2.flag_buf[fx++];
- lc = G1.l_buf[lx++];
- if ((flag & 1) == 0) {
- SEND_CODE(lc, ltree);
- Tracecv(lc > ' ', (stderr, " '%c' ", lc));
- } else {
-
- code = G2.length_code[lc];
- SEND_CODE(code + LITERALS + 1, ltree);
- extra = extra_lbits[code];
- if (extra != 0) {
- lc -= G2.base_length[code];
- send_bits(lc, extra);
- }
- dist = G1.d_buf[dx++];
-
- code = D_CODE(dist);
- Assert(code < D_CODES, "bad d_code");
- SEND_CODE(code, dtree);
- extra = extra_dbits[code];
- if (extra != 0) {
- dist -= G2.base_dist[code];
- send_bits(dist, extra);
- }
- }
- flag >>= 1;
- } while (lx < G2.last_lit);
- SEND_CODE(END_BLOCK, ltree);
- }
- static ulg flush_block(char *buf, ulg stored_len, int eof)
- {
- ulg opt_lenb, static_lenb;
- int max_blindex;
- G2.flag_buf[G2.last_flags] = G2.flags;
-
- build_tree(&G2.l_desc);
- Tracev((stderr, "\nlit data: dyn %ld, stat %ld", G2.opt_len, G2.static_len));
- build_tree(&G2.d_desc);
- Tracev((stderr, "\ndist data: dyn %ld, stat %ld", G2.opt_len, G2.static_len));
-
-
- max_blindex = build_bl_tree();
-
- opt_lenb = (G2.opt_len + 3 + 7) >> 3;
- static_lenb = (G2.static_len + 3 + 7) >> 3;
- Trace((stderr,
- "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ",
- opt_lenb, G2.opt_len, static_lenb, G2.static_len, stored_len,
- G2.last_lit, G2.last_dist));
- if (static_lenb <= opt_lenb)
- opt_lenb = static_lenb;
-
- if (stored_len <= opt_lenb && eof && G2.compressed_len == 0L && seekable()) {
-
- if (buf == NULL)
- bb_error_msg("block vanished");
- copy_block(buf, (unsigned) stored_len, 0);
- G2.compressed_len = stored_len << 3;
- } else if (stored_len + 4 <= opt_lenb && buf != NULL) {
-
-
- send_bits((STORED_BLOCK << 1) + eof, 3);
- G2.compressed_len = (G2.compressed_len + 3 + 7) & ~7L;
- G2.compressed_len += (stored_len + 4) << 3;
- copy_block(buf, (unsigned) stored_len, 1);
- } else if (static_lenb == opt_lenb) {
- send_bits((STATIC_TREES << 1) + eof, 3);
- compress_block((ct_data *) G2.static_ltree, (ct_data *) G2.static_dtree);
- G2.compressed_len += 3 + G2.static_len;
- } else {
- send_bits((DYN_TREES << 1) + eof, 3);
- send_all_trees(G2.l_desc.max_code + 1, G2.d_desc.max_code + 1,
- max_blindex + 1);
- compress_block((ct_data *) G2.dyn_ltree, (ct_data *) G2.dyn_dtree);
- G2.compressed_len += 3 + G2.opt_len;
- }
- Assert(G2.compressed_len == G1.bits_sent, "bad compressed size");
- init_block();
- if (eof) {
- bi_windup();
- G2.compressed_len += 7;
- }
- Tracev((stderr, "\ncomprlen %lu(%lu) ", G2.compressed_len >> 3,
- G2.compressed_len - 7 * eof));
- return G2.compressed_len >> 3;
- }
- #define UPDATE_HASH(h, c) (h = (((h)<<H_SHIFT) ^ (c)) & HASH_MASK)
- #define FLUSH_BLOCK(eof) \
- flush_block( \
- G1.block_start >= 0L \
- ? (char*)&G1.window[(unsigned)G1.block_start] \
- : (char*)NULL, \
- (ulg)G1.strstart - G1.block_start, \
- (eof) \
- )
- #define INSERT_STRING(s, match_head) \
- do { \
- UPDATE_HASH(G1.ins_h, G1.window[(s) + MIN_MATCH-1]); \
- G1.prev[(s) & WMASK] = match_head = head[G1.ins_h]; \
- head[G1.ins_h] = (s); \
- } while (0)
- static ulg deflate(void)
- {
- IPos hash_head;
- IPos prev_match;
- int flush;
- int match_available = 0;
- unsigned match_length = MIN_MATCH - 1;
-
- while (G1.lookahead != 0) {
-
- INSERT_STRING(G1.strstart, hash_head);
-
- G1.prev_length = match_length;
- prev_match = G1.match_start;
- match_length = MIN_MATCH - 1;
- if (hash_head != 0 && G1.prev_length < max_lazy_match
- && G1.strstart - hash_head <= MAX_DIST
- ) {
-
- match_length = longest_match(hash_head);
-
- if (match_length > G1.lookahead)
- match_length = G1.lookahead;
-
- if (match_length == MIN_MATCH && G1.strstart - G1.match_start > TOO_FAR) {
-
- match_length--;
- }
- }
-
- if (G1.prev_length >= MIN_MATCH && match_length <= G1.prev_length) {
- check_match(G1.strstart - 1, prev_match, G1.prev_length);
- flush = ct_tally(G1.strstart - 1 - prev_match, G1.prev_length - MIN_MATCH);
-
- G1.lookahead -= G1.prev_length - 1;
- G1.prev_length -= 2;
- do {
- G1.strstart++;
- INSERT_STRING(G1.strstart, hash_head);
-
- } while (--G1.prev_length != 0);
- match_available = 0;
- match_length = MIN_MATCH - 1;
- G1.strstart++;
- if (flush) {
- FLUSH_BLOCK(0);
- G1.block_start = G1.strstart;
- }
- } else if (match_available) {
-
- Tracevv((stderr, "%c", G1.window[G1.strstart - 1]));
- if (ct_tally(0, G1.window[G1.strstart - 1])) {
- FLUSH_BLOCK(0);
- G1.block_start = G1.strstart;
- }
- G1.strstart++;
- G1.lookahead--;
- } else {
-
- match_available = 1;
- G1.strstart++;
- G1.lookahead--;
- }
- Assert(G1.strstart <= G1.isize && lookahead <= G1.isize, "a bit too far");
-
- while (G1.lookahead < MIN_LOOKAHEAD && !G1.eofile)
- fill_window();
- }
- if (match_available)
- ct_tally(0, G1.window[G1.strstart - 1]);
- return FLUSH_BLOCK(1);
- }
- static void bi_init(void)
- {
- G1.bi_buf = 0;
- G1.bi_valid = 0;
- #ifdef DEBUG
- G1.bits_sent = 0L;
- #endif
- }
- static void lm_init(ush * flagsp)
- {
- unsigned j;
-
- memset(head, 0, HASH_SIZE * sizeof(*head));
-
-
- *flagsp |= 2;
-
- G1.strstart = 0;
- G1.block_start = 0L;
- G1.lookahead = file_read(G1.window,
- sizeof(int) <= 2 ? (unsigned) WSIZE : 2 * WSIZE);
- if (G1.lookahead == 0 || G1.lookahead == (unsigned) -1) {
- G1.eofile = 1;
- G1.lookahead = 0;
- return;
- }
- G1.eofile = 0;
-
- while (G1.lookahead < MIN_LOOKAHEAD && !G1.eofile)
- fill_window();
- G1.ins_h = 0;
- for (j = 0; j < MIN_MATCH - 1; j++)
- UPDATE_HASH(G1.ins_h, G1.window[j]);
-
- }
- static void ct_init(void)
- {
- int n;
- int length;
- int code;
- int dist;
- G2.compressed_len = 0L;
- #ifdef NOT_NEEDED
- if (G2.static_dtree[0].Len != 0)
- return;
- #endif
-
- length = 0;
- for (code = 0; code < LENGTH_CODES - 1; code++) {
- G2.base_length[code] = length;
- for (n = 0; n < (1 << extra_lbits[code]); n++) {
- G2.length_code[length++] = code;
- }
- }
- Assert(length == 256, "ct_init: length != 256");
-
- G2.length_code[length - 1] = code;
-
- dist = 0;
- for (code = 0; code < 16; code++) {
- G2.base_dist[code] = dist;
- for (n = 0; n < (1 << extra_dbits[code]); n++) {
- G2.dist_code[dist++] = code;
- }
- }
- Assert(dist == 256, "ct_init: dist != 256");
- dist >>= 7;
- for (; code < D_CODES; code++) {
- G2.base_dist[code] = dist << 7;
- for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {
- G2.dist_code[256 + dist++] = code;
- }
- }
- Assert(dist == 256, "ct_init: 256+dist != 512");
-
-
- n = 0;
- while (n <= 143) {
- G2.static_ltree[n++].Len = 8;
- G2.bl_count[8]++;
- }
- while (n <= 255) {
- G2.static_ltree[n++].Len = 9;
- G2.bl_count[9]++;
- }
- while (n <= 279) {
- G2.static_ltree[n++].Len = 7;
- G2.bl_count[7]++;
- }
- while (n <= 287) {
- G2.static_ltree[n++].Len = 8;
- G2.bl_count[8]++;
- }
-
- gen_codes((ct_data *) G2.static_ltree, L_CODES + 1);
-
- for (n = 0; n < D_CODES; n++) {
- G2.static_dtree[n].Len = 5;
- G2.static_dtree[n].Code = bi_reverse(n, 5);
- }
-
- init_block();
- }
- static void zip(void)
- {
- ush deflate_flags = 0;
- G1.outcnt = 0;
-
-
-
-
- put_32bit(0x00088b1f);
- put_32bit(0);
-
- G1.crc = ~0;
- bi_init();
- ct_init();
- lm_init(&deflate_flags);
- put_8bit(deflate_flags);
- put_8bit(3);
- deflate();
-
- put_32bit(~G1.crc);
- put_32bit(G1.isize);
- flush_outbuf();
- }
- static
- IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_state_t *xstate UNUSED_PARAM)
- {
-
- G1.outcnt = 0;
- #ifdef DEBUG
- G1.insize = 0;
- #endif
- G1.isize = 0;
-
- memset(&G2, 0, sizeof(G2));
- G2.l_desc.dyn_tree = G2.dyn_ltree;
- G2.l_desc.static_tree = G2.static_ltree;
- G2.l_desc.extra_bits = extra_lbits;
- G2.l_desc.extra_base = LITERALS + 1;
- G2.l_desc.elems = L_CODES;
- G2.l_desc.max_length = MAX_BITS;
-
- G2.d_desc.dyn_tree = G2.dyn_dtree;
- G2.d_desc.static_tree = G2.static_dtree;
- G2.d_desc.extra_bits = extra_dbits;
-
- G2.d_desc.elems = D_CODES;
- G2.d_desc.max_length = MAX_BITS;
-
- G2.bl_desc.dyn_tree = G2.bl_tree;
-
- G2.bl_desc.extra_bits = extra_blbits,
-
- G2.bl_desc.elems = BL_CODES;
- G2.bl_desc.max_length = MAX_BL_BITS;
-
- #if 0
-
- struct stat s;
- s.st_ctime = 0;
- fstat(STDIN_FILENO, &s);
- zip(s.st_ctime);
- #else
- zip();
- #endif
- return 0;
- }
- #if ENABLE_FEATURE_GZIP_LONG_OPTIONS
- static const char gzip_longopts[] ALIGN1 =
- "stdout\0" No_argument "c"
- "to-stdout\0" No_argument "c"
- "force\0" No_argument "f"
- "verbose\0" No_argument "v"
- #if ENABLE_FEATURE_GZIP_DECOMPRESS
- "decompress\0" No_argument "d"
- "uncompress\0" No_argument "d"
- "test\0" No_argument "t"
- #endif
- "quiet\0" No_argument "q"
- "fast\0" No_argument "1"
- "best\0" No_argument "9"
- "no-name\0" No_argument "n"
- ;
- #endif
- int gzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
- #if ENABLE_FEATURE_GZIP_DECOMPRESS
- int gzip_main(int argc, char **argv)
- #else
- int gzip_main(int argc UNUSED_PARAM, char **argv)
- #endif
- {
- unsigned opt;
- #if ENABLE_FEATURE_GZIP_LEVELS
- static const struct {
- uint8_t good;
- uint8_t chain_shift;
- uint8_t lazy2;
- uint8_t nice2;
- } gzip_level_config[6] = {
- {4, 4, 4/2, 16/2},
- {8, 5, 16/2, 32/2},
- {8, 7, 16/2, 128/2},
- {8, 8, 32/2, 128/2},
- {32, 10, 128/2, 258/2},
- {32, 12, 258/2, 258/2},
- };
- #endif
- SET_PTR_TO_GLOBALS((char *)xzalloc(sizeof(struct globals)+sizeof(struct globals2))
- + sizeof(struct globals));
-
- #if ENABLE_FEATURE_GZIP_LONG_OPTIONS
- opt = getopt32long(argv, "cfkv" IF_FEATURE_GZIP_DECOMPRESS("dt") "qn123456789", gzip_longopts);
- #else
- opt = getopt32(argv, "cfkv" IF_FEATURE_GZIP_DECOMPRESS("dt") "qn123456789");
- #endif
- #if ENABLE_FEATURE_GZIP_DECOMPRESS
- if (opt & 0x30)
- return gunzip_main(argc, argv);
- #endif
- #if ENABLE_FEATURE_GZIP_LEVELS
- opt >>= ENABLE_FEATURE_GZIP_DECOMPRESS ? 8 : 6;
- if (opt == 0)
- opt = 1 << 6;
- opt = ffs(opt >> 4);
- max_chain_length = 1 << gzip_level_config[opt].chain_shift;
- good_match = gzip_level_config[opt].good;
- max_lazy_match = gzip_level_config[opt].lazy2 * 2;
- nice_match = gzip_level_config[opt].nice2 * 2;
- #endif
- option_mask32 &= 0xf;
-
- ALLOC(uch, G1.l_buf, INBUFSIZ);
- ALLOC(uch, G1.outbuf, OUTBUFSIZ);
- ALLOC(ush, G1.d_buf, DIST_BUFSIZE);
- ALLOC(uch, G1.window, 2L * WSIZE);
- ALLOC(ush, G1.prev, 1L << BITS);
-
- global_crc32_table = crc32_filltable(NULL, 0);
- argv += optind;
- return bbunpack(argv, pack_gzip, append_ext, "gz");
- }
|