#include #include #include #include #define MIN_MATCH 3 #define MAX_MATCH 258 #define WS_SMALL 1023 #define WS_LARGE 131071 #define HASH_SIZE 65536 #define HASH_MASK (HASH_SIZE - 1) #define BLOCK_SIZE 65536 #define RING_BITS 18 #define RING_SIZE ((size_t)1 << RING_BITS) static inline size_t ridx(int64_t base, uint64_t p) { return (size_t)((int64_t)(p) - base); } #define REP_SIZE 4 static const int REP_INIT[REP_SIZE]={1,8,32,128}; // ========= FILE MAGIC + VERSION (v2.2: slots killed the window flag) ========= // v2.0d and older: 12B (len+adler), no magic. v2.1: magic + version 1 // (REP-4 + LE + DS32). v2.2: version 2 = lzip-style slots 0-33 with // Huffman-coded selector, no window flag, no remap. Strict accept, // clear reject, no guessing. #define LZSS_MAGIC 0x53535A4Cu /* "LZSS" LE: bytes 4C 5A 53 53 */ #define LZSS_VERSION 2u /* 2 = v2.1 + slot distances */ #define LZSS_HEADER_LEN 20 /* magic u32 + version u32 + len u64 + adler u32 */ // ========= ENDIAN SAFE LE64/LE32 (fixes v2.0d bug on BE) ========= static void write_le32(FILE *f, uint32_t v){ uint8_t b[4]; b[0]=(uint8_t)(v); b[1]=(uint8_t)(v>>8); b[2]=(uint8_t)(v>>16); b[3]=(uint8_t)(v>>24); fwrite(b,1,4,f); } static void write_le64(FILE *f, uint64_t v){ uint8_t b[8]; b[0]=(uint8_t)(v); b[1]=(uint8_t)(v>>8); b[2]=(uint8_t)(v>>16); b[3]=(uint8_t)(v>>24); b[4]=(uint8_t)(v>>32); b[5]=(uint8_t)(v>>40); b[6]=(uint8_t)(v>>48); b[7]=(uint8_t)(v>>56); fwrite(b,1,8,f); } static int read_le32(FILE *f, uint32_t *out){ uint8_t b[4]; if(fread(b,1,4,f)!=4) return 0; *out = ((uint32_t)b[0]) | ((uint32_t)b[1]<<8) | ((uint32_t)b[2]<<16) | ((uint32_t)b[3]<<24); return 1; } static int read_le64(FILE *f, uint64_t *out){ uint8_t b[8]; if(fread(b,1,8,f)!=8) return 0; *out = ((uint64_t)b[0]) | ((uint64_t)b[1]<<8) | ((uint64_t)b[2]<<16) | ((uint64_t)b[3]<<24) | ((uint64_t)b[4]<<32) | ((uint64_t)b[5]<<40) | ((uint64_t)b[6]<<48) | ((uint64_t)b[7]<<56); return 1; } // ---- 20B header: magic + version + total_len + adler (all LE) ---- static void write_header_placeholder(FILE *f){ write_le32(f, LZSS_MAGIC); write_le32(f, LZSS_VERSION); write_le64(f, 0); write_le32(f, 0); } static void write_header_backpatch(FILE *f, uint64_t total_len, uint32_t adler){ write_le32(f, LZSS_MAGIC); write_le32(f, LZSS_VERSION); write_le64(f, total_len); write_le32(f, adler); } // returns 0 ok, 1 bad-magic (incl. legacy magic-less files), 2 newer version, // 3 truncated, 4 older version (use older binary or re-compress) static int read_header(FILE *f, uint64_t *total_len, uint32_t *adler){ uint32_t magic = 0, version = 0; if(!read_le32(f, &magic)) return 3; // Legacy detect: v2.0d and older start with total_len u64 LE, no magic. // A legacy len < 2^32 has low byte != 0x4C or second dword != version range, // but instead of heuristics: strict magic check, clear message. if(magic != LZSS_MAGIC) return 1; if(!read_le32(f, &version)) return 3; if(version > LZSS_VERSION) return 2; if(version < LZSS_VERSION) return 4; if(!read_le64(f, total_len)) return 3; if(!read_le32(f, adler)) return 3; return 0; } uint32_t calcular_adler32(const uint8_t *data, size_t len){ uint32_t a=1,b=0; for(size_t i=0;i> 1) & 1) typedef struct { uint32_t freq; int sym; } FreqSym; typedef struct { uint32_t freq; int left; int right; int sym; } HNode; static int cmp_freq(const void *a, const void *b){ const FreqSym *fa=a,*fb=b; if(fa->freq!=fb->freq) return (fa->freqfreq)?-1:1; return fa->sym-fb->sym; } static void huff_assign_depth(HNode *nodes,int idx,int depth,uint8_t *lens){ if(idx<0) return; if(nodes[idx].sym>=0){if(depth<1) depth=1; if(depth>15) depth=16; lens[nodes[idx].sym]=(uint8_t)depth; return;} huff_assign_depth(nodes,nodes[idx].left,depth+1,lens); huff_assign_depth(nodes,nodes[idx].right,depth+1,lens); } static int build_huffman_lengths(const uint32_t *freq,uint8_t *lens){ memset(lens,0,256); FreqSym fs[256]; int n=0; for(int i=0;i<256;i++) if(freq[i]){fs[n].freq=freq[i]; fs[n].sym=i; n++;} if(n==0) return 0; if(n==1){lens[fs[0].sym]=1; return 1;} qsort(fs,n,sizeof(FreqSym),cmp_freq); HNode nodes[511]; for(int i=0;i1){int m1=-1,m2=-1; for(int i=0;i=511) break;} int root=avail[0]; huff_assign_depth(nodes,root,0,lens); int cnt=0; for(int i=0;i<256;i++) if(lens[i]){if(lens[i]>15) return -1; cnt++;} return cnt; } static void build_canonical(const uint8_t *lens,uint32_t *codes){ memset(codes,0,256*sizeof(uint32_t)); int bl_count[16]={0}; for(int i=0;i<256;i++) if(lens[i]) bl_count[lens[i]]++; uint32_t code=0; uint32_t next_code[16]={0}; for(int bits=1;bits<=15;bits++){code=(code+bl_count[bits-1])<<1; next_code[bits]=code;} int order[256]; int on=0; for(int l=1;l<=15;l++) for(int s=0;s<256;s++) if(lens[s]==l) order[on++]=s; for(int i=0;ilens,lens,256); build_canonical(lens,d->codes); d->nsyms=0; for(int i=0;i<256;i++) if(lens[i]) d->nsyms++;} typedef struct { FILE *f; uint8_t cur; int nbits; } BitWriter; void bw_init(BitWriter *w,FILE *f){w->f=f; w->cur=0; w->nbits=0;} void bw_write_bit(BitWriter *w,int bit){w->cur=(uint8_t)((w->cur<<1)|(bit&1)); w->nbits++; if(w->nbits==8){fputc(w->cur,w->f); w->cur=0; w->nbits=0;}} void bw_write_bits(BitWriter *w,uint32_t v,int n){for(int i=n-1;i>=0;i--) bw_write_bit(w,(v>>i)&1);} void bw_flush(BitWriter *w){if(w->nbits>0){w->cur<<=(8-w->nbits); fputc(w->cur,w->f); w->cur=0; w->nbits=0;}} typedef struct { FILE *f; uint8_t buf; int cnt; int eof; } BitReader; void br_init(BitReader *r,FILE *f){r->f=f; r->buf=0; r->cnt=0; r->eof=0;} int br_read_bit(BitReader *r){if(r->cnt==0){int c=fgetc(r->f); if(c==EOF){r->eof=1; return 0;} r->buf=(uint8_t)c; r->cnt=8;} r->cnt--; return (r->buf>>r->cnt)&1;} uint32_t br_read_bits(BitReader *r,int n){uint32_t v=0; for(int i=0;icnt=0;} static int huffdec_decode(BitReader *r,HuffDec *d){uint32_t code=0; for(int len=1;len<=15;len++){if(r->eof) return -1; code=(code<<1)|(uint32_t)br_read_bit(r); for(int s=0;s<256;s++) if(d->lens[s]==len&&d->codes[s]==code) return s;} return -1;} #define NSLOTS 34 // lzip-style slots for real distance d in [1,131071] (z=d-1) // slot on zero-based z: 0..3 direct; else (msb_pos-1)*2+nextbit (lzip table) static inline int get_slot(uint32_t d){ uint32_t z = d - 1; if(z < 4) return (int)z; int m = 0; uint32_t v = z; while(v){ m++; v >>= 1; } return (m - 1) * 2 + (int)((z >> (m - 2)) & 1); } static inline int slot_footer_bits(int s){ return (s < 4) ? 0 : ((s >> 1) - 1); } static inline uint32_t slot_base(int s){ return ((2u | ((uint32_t)(s & 1))) << (uint32_t)((s >> 1) - 1)); } // s>=4 static inline uint32_t quick_hash(const uint8_t *ptr){return ((uint32_t)(ptr[0]<<8) ^ (uint32_t)(ptr[1]<<4) ^ (uint32_t)ptr[2]) & HASH_MASK;} // DS32 BE-safe match: uses memcmp (endian agnostic) not uint64 compare int find_match_ds32(uint8_t *in,int64_t rbase,uint64_t tab_epoch,uint64_t global_pos,uint64_t block_end,int32_t *head,int32_t *prev,int *best_off,int *use_large){ int best_len_s=0,best_off_s=0,best_len_l=0,best_off_l=0; if(block_end<=global_pos) return 0; uint64_t remain=block_end-global_pos; uint64_t max=remain>MAX_MATCH?MAX_MATCH:remain; if(max=global_pos) break; uint64_t distance=global_pos-match_pos; if(distance>(uint64_t)WS_LARGE) break; if(distance==0) break; int l=0; // BE-safe fast path: memcmp 8 bytes (not uint64 equality that is ok but pedantic) while((uint64_t)l+8<=max){ if(memcmp(&in[ridx(rbase,match_pos+l)], &in[ridx(rbase,global_pos+l)], 8)!=0) break; l+=8; } while((uint64_t)l=MIN_MATCH && l>best_len_s){best_len_s=l; best_off_s=(int)distance; if(best_len_s==MAX_MATCH){best_len_l=best_len_s; best_off_l=best_off_s; break;}} if(l>=MIN_MATCH && l>best_len_l){best_len_l=l; best_off_l=(int)distance; if(best_len_l==MAX_MATCH) break;} craw=prev[match_pos & (uint64_t)WS_LARGE]; } if(best_len_s7){*best_off=best_off_l; *use_large=1; return best_len_l;} else {*best_off=best_off_s; *use_large=0; return best_len_s;} } static void hash_insert(uint8_t *buf,int64_t rbase,uint64_t ring_lim,uint64_t pos,int32_t *head,int32_t *prev){ if(pos+MIN_MATCH>ring_lim) return; uint32_t h=quick_hash(&buf[ridx(rbase,pos)]); prev[pos & (uint64_t)WS_LARGE]=head[h]; head[h]=(int32_t)pos; } int executar_compressao(const char* entrada,const char* saida){ FILE *fin=fopen(entrada,"rb"); if(!fin){printf("Error opening input.\n"); return 1;} uint8_t *buf=malloc(RING_SIZE); int32_t *head=malloc(HASH_SIZE*sizeof(int32_t)); int32_t *prev=malloc((WS_LARGE+1)*sizeof(int32_t)); Tok17 *toks=malloc(BLOCK_SIZE*sizeof(Tok17)); if(!buf||!head||!prev||!toks){printf("Memory allocation failure.\n"); fclose(fin); free(buf); free(head); free(prev); free(toks); return 1;} uint32_t ad_a=1,ad_b=0; uint64_t total_len=0; FILE *fout=fopen(saida,"wb"); if(!fout){printf("Error creating output.\n"); fclose(fin); free(buf); free(head); free(prev); free(toks); return 1;} write_header_placeholder(fout); // 20B: magic + version + len + adler memset(head,0xFF,HASH_SIZE*sizeof(int32_t)); memset(prev,0xFF,(WS_LARGE+1)*sizeof(int32_t)); uint64_t tab_epoch=0; BitWriter bw; bw_init(&bw,fout); int64_t ring_base=0; uint64_t ring_end=0; int input_eof=0; uint64_t global_p=0; while(1){ uint64_t block_start=global_p; if((block_start & 0xFFFFFFFF00000000ULL)!=tab_epoch){tab_epoch=block_start & 0xFFFFFFFF00000000ULL; memset(head,0xFF,HASH_SIZE*sizeof(int32_t)); memset(prev,0xFF,(WS_LARGE+1)*sizeof(int32_t));} {uint64_t hist=block_start>(uint64_t)WS_LARGE?(uint64_t)WS_LARGE:block_start; uint64_t want_start=block_start-hist; if(want_start>(uint64_t)ring_base){size_t have=(size_t)(ring_end-(uint64_t)ring_base); size_t drop=(size_t)(want_start-(uint64_t)ring_base); if(dropblock_start)?(size_t)(ring_end-block_start):0; if(avail==0) break; uint32_t block_raw_len=avail>=BLOCK_SIZE?BLOCK_SIZE:(uint32_t)avail; uint64_t block_end=block_start+block_raw_len; for(uint64_t _p=block_start;_p=MIN_MATCH && use_large && off<=1023) use_large=0; int cur_cost=0,cur_save=-1000000; if(ml>=MIN_MATCH){int bits_offset=3+slot_footer_bits(get_slot((uint32_t)off)); cur_cost=(ml>=10)?(1+3+bits_offset+8):(1+3+bits_offset); cur_save=ml*9-cur_cost;} if(ml>=MIN_MATCH && cur_save>0){ hash_insert(buf,ring_base,ring_end,internal_p,head,prev); int off2=0,use_large2=0,ml2=0; if(internal_p+1+MIN_MATCH<=block_end) ml2=find_match_ds32(buf,ring_base,tab_epoch,internal_p+1,block_end,head,prev,&off2,&use_large2); if(ml2>=MIN_MATCH && use_large2 && off2<=1023) use_large2=0; if(ml2>=MIN_MATCH){int bits2=3+slot_footer_bits(get_slot((uint32_t)off2)); int cost2=(ml2>=10)?(1+3+bits2+8):(1+3+bits2); int save2=ml2*9-cost2; if(save2>cur_save){toks[ntoks].flg=0; toks[ntoks].lit=buf[ridx(ring_base,internal_p)]; ntoks++; freq[buf[ridx(ring_base,internal_p)]]++; fixed_payload_bits+=9; internal_p++; continue;}} toks[ntoks].flg=1; toks[ntoks].off=(uint32_t)off; toks[ntoks].flg|=(uint8_t)(use_large<<1); toks[ntoks].len=(uint16_t)ml; sfreq[get_slot((uint32_t)off)]++; ntoks++; fixed_payload_bits+=(size_t)cur_cost; internal_p++; for(int k=1;k0) build_canonical(slens,scodes); // slot table (empty ok: block needs no slot coding) int rep_en=0; {int rh[REP_SIZE]; for(int i=0;i0){int tmp=rh[code]; for(int r=code;r>0;r--) rh[r]=rh[r-1]; rh[0]=tmp;}} else {for(int r=REP_SIZE-1;r>0;r--) rh[r]=rh[r-1]; rh[0]=o;}} size_t overhead=nm*1+1; if(save_bits>overhead) rep_en=1;} /* v2.2 slots: remap needs window flag, removed. has_slots skips the slot tree when no match needs slot coding (all literals, or rep-hits only). */ int has_slots=0; {int rhs[REP_SIZE]; for(int i=0;i0){int tmp=rhs[code]; for(int r=code;r>0;r--) rhs[r]=rhs[r-1]; rhs[0]=tmp;}} else {for(int r=REP_SIZE-1;r>0;r--) rhs[r]=rhs[r-1]; rhs[0]=o;}} } uint8_t lens[256]; uint32_t codes[256]; int nsyms=build_huffman_lengths(freq,lens); size_t huff_payload_bits=0,huff_overhead_bits=0; if(nsyms>0){build_canonical(lens,codes); for(size_t t=0;t=10)?(1+3+bo+8):(1+3+bo)); if(rep_en) base+=1; huff_payload_bits+=base;}} if(rep_en){int rh2[REP_SIZE]; for(int i=0;i0){int tmp=rh2[code]; for(int r=code;r>0;r--) rh2[r]=rh2[r-1]; rh2[0]=tmp;}} else {for(int r=REP_SIZE-1;r>0;r--) rh2[r]=rh2[r-1]; rh2[0]=o;}}} huff_payload_bits+=2; huff_overhead_bits=1+256+(size_t)nsyms*4+(has_slots?34+(size_t)snsyms*4:0);} else {huff_payload_bits=fixed_payload_bits; huff_overhead_bits=(size_t)1<<30;} {size_t fp=0; int rh3[REP_SIZE]; for(int i=0;i=10)?(1+3+bo+8):(1+3+bo)); if(rep_en) fp+=1; int o=toks[t].off; int hit=0; for(int r=0;r0){int tmp=rh3[code]; for(int r=code;r>0;r--) rh3[r]=rh3[r-1]; rh3[0]=tmp;}} else {for(int r=REP_SIZE-1;r>0;r--) rh3[r]=rh3[r-1]; rh3[0]=o;}}} fp+=2; fixed_payload_bits=fp;} size_t fixed_block_bits=1+32+1+fixed_payload_bits+(has_slots?34+(size_t)snsyms*4:0); size_t huff_block_bits=1+32+huff_overhead_bits+huff_payload_bits; int fixed_beats_raw=(fixed_payload_bits+7)/8 < block_raw_len; int mode_huff=0; if(nsyms>0 && huff_block_bits=0){ bw_write_bit(&bw,1); bw_write_bits(&bw,block_raw_len,32); if(mode_huff==1){ bw_write_bit(&bw,1); bw_write_bit(&bw,rep_en); bw_write_bit(&bw,has_slots); for(int s=0;s<256;s++) bw_write_bit(&bw,lens[s]?1:0); for(int s=0;s<256;s++) if(lens[s]) bw_write_bits(&bw,lens[s],4); if(has_slots){for(int s=0;s=0){bw_write_bit(&bw,0); bw_write_bits(&bw,(uint32_t)code,2); if(code>0){int tmp=rhe[code]; for(int r=code;r>0;r--) rhe[r]=rhe[r-1]; rhe[0]=tmp;}} else {bw_write_bit(&bw,1); for(int r=REP_SIZE-1;r>0;r--) rhe[r]=rhe[r-1]; rhe[0]=o;} } else { bw_write_bit(&bw,1); for(int r=REP_SIZE-1;r>0;r--) rhe[r]=rhe[r-1]; rhe[0]=o; } if(toks[t].len<10) bw_write_bits(&bw,toks[t].len-3,3); else bw_write_bits(&bw,7,3); if(!(rep_en&&code>=0)){int _s=get_slot(toks[t].off); bw_write_bits(&bw,scodes[_s],slens[_s]); {uint32_t _z=toks[t].off-1; int _n=slot_footer_bits(_s); uint32_t _e=(_n==0)?0:(_z-slot_base(_s)); bw_write_bits(&bw,_e,_n);}} if(toks[t].len>=10) bw_write_bits(&bw,toks[t].len-3,8); } } } else { bw_write_bit(&bw,0); bw_write_bit(&bw,rep_en); bw_write_bit(&bw,has_slots); if(has_slots){for(int s=0;s=0){bw_write_bit(&bw,0); bw_write_bits(&bw,(uint32_t)code,2); if(code>0){int tmp=rhf[code]; for(int r=code;r>0;r--) rhf[r]=rhf[r-1]; rhf[0]=tmp;}} else {bw_write_bit(&bw,1); for(int r=REP_SIZE-1;r>0;r--) rhf[r]=rhf[r-1]; rhf[0]=o;} } else { bw_write_bit(&bw,1); for(int r=REP_SIZE-1;r>0;r--) rhf[r]=rhf[r-1]; rhf[0]=o; } if(toks[t].len<10) bw_write_bits(&bw,toks[t].len-3,3); else bw_write_bits(&bw,7,3); if(!(rep_en&&code>=0)){int _s=get_slot(toks[t].off); bw_write_bits(&bw,scodes[_s],slens[_s]); {uint32_t _z=toks[t].off-1; int _n=slot_footer_bits(_s); uint32_t _e=(_n==0)?0:(_z-slot_base(_s)); bw_write_bits(&bw,_e,_n);}} if(toks[t].len>=10) bw_write_bits(&bw,toks[t].len-3,8); } } } } if(mode_huff<0){bw_write_bit(&bw,0); bw_flush(&bw); write_le32(fout,block_raw_len); fwrite(&buf[ridx(ring_base,block_start)],1,block_raw_len,fout);} global_p=block_end; total_len=global_p; } bw_flush(&bw); {uint32_t checksum=(ad_b<<16)|ad_a; if(fseek(fout,0,SEEK_SET)==0){write_header_backpatch(fout,total_len,checksum);}} fclose(fout); fclose(fin); free(buf); free(head); free(prev); free(toks); printf("LZSS v2.2 SLOTS STREAM engine complete (lzip-style slots 0-33, Huffman selector, no window flag).\n"); return 0; } int executar_descompressao(const char* entrada,const char* saida){ FILE *fin=fopen(entrada,"rb"); if(!fin){printf("Error opening compressed file.\n"); return 1;} uint64_t total_original_len=0; uint32_t checksum_original=0; { int hr = read_header(fin, &total_original_len, &checksum_original); if(hr == 3){printf("Header fault: truncated header (need %dB magic+version+len+adler).\n", LZSS_HEADER_LEN); fclose(fin); return 1;} if(hr == 1){printf("Bad magic: not an LZSS v2.1+ file.\n" "This decoder needs magic 'LZSS' + version %u.\n" "v2.0d and older files have no magic (12B len+adler header)\n" "and a different token format: decode them with the\n" "matching older binary, or re-compress with this one.\n", LZSS_VERSION); fclose(fin); return 1;} if(hr == 2){printf("Unsupported version: file needs a newer decoder (this one writes v%u).\n", LZSS_VERSION); fclose(fin); return 1;} if(hr == 4){printf("Older version: file predates v%u (slot distances arrived in v2).\n" "Re-compress with this binary, or decode with the older binary.\n", LZSS_VERSION); fclose(fin); return 1;} } uint8_t *buf=NULL; FILE *fout=NULL; uint32_t da=1,db=0; int64_t ring_base=0; if(total_original_len>0){buf=malloc(RING_SIZE); if(!buf){printf("Memory fail.\n"); fclose(fin); return 1;} fout=fopen(saida,"wb"); if(!fout){printf("Error creating output.\n"); fclose(fin); free(buf); return 1;}} else {fclose(fin); FILE *f=fopen(saida,"wb"); if(f) fclose(f); uint32_t c=calcular_adler32((uint8_t*)"",0); if(c==checksum_original){printf("Decompression Complete. Status: 100%% INTEGRAL (Adler-32 Checked).\n"); return 0;} else {printf("CRITICAL VALIDATION ERROR.\n"); return 2;}} BitReader br; br_init(&br,fin); uint64_t global_p=0; while(global_pBLOCK_SIZE||global_p+decomp_len>total_original_len){printf("Invalid decomp_len.\n"); free(buf); fclose(fin); fclose(fout); return 1;} int huff_flag=br_read_bit(&br); int rep_en_d=br_read_bit(&br); int has_slots_d=br_read_bit(&br); HuffDec hd; memset(&hd,0,sizeof(hd)); if(huff_flag==1){uint8_t lens[256]={0}; for(int s=0;s<256;s++) lens[s]=(uint8_t)br_read_bit(&br); uint8_t ll[256]={0}; for(int s=0;s<256;s++) if(lens[s]){ll[s]=(uint8_t)br_read_bits(&br,4); if(br.eof||ll[s]==0||ll[s]>15){printf("Invalid huff lens.\n"); free(buf); fclose(fin); fclose(fout); return 1;}} huffdec_build(&hd,ll); if(hd.nsyms==0){printf("Empty huffman table.\n"); free(buf); fclose(fin); fclose(fout); return 1;}} HuffDec sd; memset(&sd,0,sizeof(sd)); if(has_slots_d){uint8_t slm[256]={0}; for(int s=0;s15){printf("Invalid slot lens.\n"); free(buf); fclose(fin); fclose(fout); return 1;}} huffdec_build(&sd,sll);} uint64_t block_end_p=global_p+decomp_len; uint64_t blk_start=global_p; {uint64_t h=blk_start>(uint64_t)WS_LARGE?(uint64_t)WS_LARGE:blk_start; uint64_t nb=blk_start-h; size_t have=(size_t)(global_p-(uint64_t)ring_base); size_t drop=(size_t)(nb-(uint64_t)ring_base); memmove(buf,buf+drop,have-drop); ring_base=(int64_t)nb;} int rhd[REP_SIZE]; for(int i=0;i=NSLOTS){printf("Slot decode fault.\n"); free(buf); fclose(fin); fclose(fout); return 1;} int _n=slot_footer_bits(_sc); uint32_t _e=_n?br_read_bits(&br,_n):0; uint32_t _z=(_sc<4)?(uint32_t)_sc:(slot_base(_sc)+_e); offset=_z+1;} if(br.eof){printf("Truncated match.\n"); free(buf); fclose(fin); fclose(fout); return 1;} if(offset==0||offset>global_p||offset>(uint32_t)(WS_LARGE+1)){printf("CRITICAL GUARD: Pointer underflow blocked!\n"); free(buf); fclose(fin); fclose(fout); return 1;} uint32_t ml=(len_code<7)?(len_code+3):(br_read_bits(&br,8)+3); if(mlMAX_MATCH){printf("Invalid match length.\n"); free(buf); fclose(fin); fclose(fout); return 1;} if(global_p+ml>block_end_p){printf("Match overruns block.\n"); free(buf); fclose(fin); fclose(fout); return 1;} if(is_rep_d){if(repcode_d>0){int tmp=rhd[repcode_d]; for(int r=repcode_d;r>0;r--) rhd[r]=rhd[r-1]; rhd[0]=tmp;}} else {for(int r=REP_SIZE-1;r>0;r--) rhd[r]=rhd[r-1]; rhd[0]=(int)offset;} uint64_t start_pos=global_p-offset; for(uint32_t i=0;iBLOCK_SIZE||global_p+raw_len>total_original_len){printf("Invalid stored len.\n"); free(buf); fclose(fin); fclose(fout); return 1;} {uint64_t nb=global_p>(uint64_t)WS_LARGE?global_p-(uint64_t)WS_LARGE:0; size_t have=(size_t)(global_p-(uint64_t)ring_base); size_t drop=(size_t)(nb-(uint64_t)ring_base); memmove(buf,buf+drop,have-drop); ring_base=(int64_t)nb; uint32_t got=0; while(got \n Decompress: %s -d \n",argv[0],argv[0]); return 1;} if(strcmp(argv[1],"-c")==0) return executar_compressao(argv[2],argv[3]); if(strcmp(argv[1],"-d")==0) return executar_descompressao(argv[2],argv[3]); printf("Invalid layout mode.\n"); return 1; }