#include #include #include "types.h" #include "memman.h" #include "mem.h" #include "mgifmem.h" #define MGIF "MGIF" #define LZW_MAX_CODES 16384 #define LZW_BUFFER 64000 MGIF_PROC show_proc; typedef struct double_s { short group,chr,first,next; }DOUBLE_S; typedef DOUBLE_S CODE_TABLE[LZW_MAX_CODES]; DOUBLE_S *compress_dic=NULL; static void *lzw_buffer=NULL; static int clear_code; static int end_code; static int free_code; static int nextgroup; static int bitsize,init_bitsize; char old_value=0; void do_clear_code(void) { int i; old_value=0; nextgroup=free_code; bitsize=init_bitsize; for(i=0;igroup=i;p->chr=-1;p->next=-1;p->first=-1; } } void reinit_lzw(void) { do_clear_code(); } void init_lzw_compressor(int dic_size) { if (compress_dic==NULL) compress_dic=(DOUBLE_S *)getmem(sizeof(CODE_TABLE)); clear_code=1<nx_frame = c; ins->cur_frame = 0; ins->sound_write_pos = 0; ins->accnums[0] = 0; ins->accnums[1] = 0; init_lzw_compressor(8); if (lzw_buffer==NULL) lzw_buffer=getmem(LZW_BUFFER); return ins; } void close_mgif(const void *mgif) //dealokuje buffery pro prehravani { if (mgif) { done_lzw_compressor(); free(lzw_buffer); lzw_buffer=NULL; free((void *)mgif); } } int input_code(const void *source,int32_t *bitepos,int bitsize,int mask) { const uint8_t *esi = source; // mov esi,source int32_t *edi = bitepos; // mov edi,bitepos int ebx = bitsize; // mov ebx,bitsize int edx = mask; // mov edx,mask int ecx = *edi; // mov ecx,[edi] int eax = ecx; // mov eax,ecx eax >>=3; // shr eax,3 eax = esi[eax] | (esi[eax+1] << 8) | (esi[eax+2] << 16) | (esi[eax+3] << 24); // mov eax,[esi+eax] ecx &= 7; // and cl,7 eax >>= ecx; // shr eax,cl eax &= edx; // and eax,edx (*edi) += ebx; // add [edi],ebx return eax; } int de_add_code(int group,int chr,int mask) { DOUBLE_S *q; q=&compress_dic[nextgroup];q->group=group;q->chr=chr;q->first=compress_dic[group].first+1; nextgroup++; if (nextgroup==mask) { mask=(mask<<1)+1; bitsize++; } return mask; } int fast_expand_code(const DOUBLE_S *compress_dic, int code,uint8_t **target, uint8_t *old_value) { int eax = code; //mov eax,code uint8_t ** edi = target; //mov edi,target //cmp eax,256 if (eax < 256) { //jnc expand uint8_t *esi = *edi; //mov esi,[edi] ++(*edi); //inc dword ptr [edi] uint8_t bl = (uint8_t)eax; //mov bl,al uint8_t al = bl + *old_value; //add al,old_value *esi = al; // mov [esi],al *old_value = al; // mov old_value,al return bl; // jmp end } //expand: const DOUBLE_S *ebx = compress_dic; // mov ebx,compress_dic const DOUBLE_S *ecx = ebx+eax; // lea ecx,[eax*8+ebx] eax = ecx->first; // movzx eax,short ptr [ecx+4] // first *target += eax; // add [edi],eax int save_eax = eax; // push eax uint8_t *esi = *edi; // mov esi,[edi] //esi - target ptr do { //eloop: eax = ecx->chr; //movzx eax,short ptr [ecx+2] // chr *esi = (uint8_t)(eax); //mov [esi],al --esi; //dec esi eax = ecx->group; //movzx eax,short ptr [ecx] //group ecx = ebx+eax; //lea ecx,[eax*8+ebx] //cmp eax,256 } while (eax >= 256 ); //jnc eloop uint8_t bl = (uint8_t)eax; //mov bl,al uint8_t al = bl + *old_value; //add al,old_value *esi = al; //mov [esi],al ++(*edi); //inc dword ptr [edi] int ecx2 = save_eax; //pop ecx do { //elp2 ++esi; //inc esi al = al + *esi; //add al,[esi] *esi = al; //mov [esi],al --ecx2; //dec ecx } while (ecx2 > 0); //jnz elp2 *old_value =al; //mov old_value,al return bl; //movzx eax,bl // } #if 0 uint8_t out; uint8_t w; if (code >= 256) { DOUBLE_S *pos = compress_dic+code; uint8_t *t = *target + pos->first; (**target) += pos->first+1; short len = pos->first; short group = pos->group; do{ *t = pos->chr; --t; group = pos->group; pos = compress_dic+group; } while (group >= 256); w=(uint8_t)group; out = w; w += *old_value; *t = w; while (len) { ++t; w = w + *t; *t = w; --len; } *old_value = w; } else { out = (uint8_t) code; w = out + *old_value; *old_value = w; **target = w; (*target)++; } return out; #endif /* _asm { mov eax,code mov edi,target cmp eax,256 jnc expand mov esi,[edi] inc dword ptr [edi] mov bl,al add al,old_value mov [esi],al //esi - target ptr mov old_value,al jmp end expand: mov ebx,compress_dic lea ecx,[eax*8+ebx] movzx eax,short ptr [ecx+4] // first add [edi],eax push eax mov esi,[edi] //esi - target ptr eloop:movzx eax,short ptr [ecx+2] // chr mov [esi],al dec esi movzx eax,short ptr [ecx] //group lea ecx,[eax*8+ebx] cmp eax,256 jnc eloop mov bl,al add al,old_value mov [esi],al inc dword ptr [edi] pop ecx elp2:inc esi add al,[esi] mov [esi],al dec ecx jnz elp2 mov old_value,al end: movzx eax,bl } */ } void lzw_decode(const void *source,char *target) { int32_t bitpos=0; int code; int old,i; int old_first; uint8_t old_value; for(i=0;inx_frame; FRAME_HEADER_T frame_hdr = read_frame_header(&pf); pc = pf; pf += frame_hdr.size; for (uint8_t i = 0; i < frame_hdr.count; ++i) { CHUNK_HEADER_T chunk_hdr = read_chunk_header(&pc); if (chunk_hdr.type == MGIF_LZW || chunk_hdr.type == MGIF_DELTA) { ff=lzw_buffer; lzw_decode(pc,ff); scr_sav=ff; scr_act=chunk_hdr.type; } else if (chunk_hdr.type==MGIF_COPY) { //scr_sav=ff;scr_act=act; //strange code scr_sav = pc; scr_act = chunk_hdr.type; } else { show_proc(hdr,chunk_hdr.type,pc,chunk_hdr.size); } pc+=chunk_hdr.size; } if (scr_act!=-1) show_proc(hdr, scr_act,scr_sav,0); hdr->cur_frame+=1; if (hdr->cur_frame==hdr->frames) return 0; hdr->nx_frame = pf; return 1; } /* acts=*pf++; size=(*(int *)pf) & 0xffffff; pf+=3;pc=pf;pf+=size; if (acts) do { act=*pc++;csize=(*(int *)pc) & 0xffffff;pc+=3; if (act==MGIF_LZW || act==MGIF_DELTA) { ff=lzw_buffer; lzw_decode(pc,ff); scr_sav=ff; scr_act=act; } else if (act==MGIF_COPY) { scr_sav=ff;scr_act=act; } else { ff=pc; show_proc(act,ff,csize); } pc+=csize; } while (--acts); if (scr_act!=-1) show_proc(scr_act,scr_sav,csize); cur_frame+=1; if (cur_frame==mgif_frames) return NULL; return pf; } */