Автор: Гребнов Илья,
30 августа 2004 года в 17:02:30
В ответ на : Re: Distance Coding от Phil Andrey
в 30 августа 2004 года в 14:48:22:
Попробуй вот этот выриант WFC. Скорость где-то в 4.5 раза ниже, чем у MTF, зато степень сжатия выше на 2-3%.#define WFC_MaxByte 256 #define WFC_Val0 131072 #define WFC_Val1 114688 #define WFC_Val2 7272 #define WFC_Val3 4240 #define WFC_Val4 2364 #define WFC_Val5 1263 #define WFC_Val6 649 #define WFC_Val7 320 #define WFC_Val8 153 #define WFC_Val9 70 #define WFC_Val10 31 #define WFC_Val11 14 #define WFC_Val12 8 #define WFC_Pos1 1 #define WFC_Pos2 2 #define WFC_Pos3 4 #define WFC_Pos4 8 #define WFC_Pos5 16 #define WFC_Pos6 32 #define WFC_Pos7 64 #define WFC_Pos8 128 #define WFC_Pos9 256 #define WFC_Pos10 512 #define WFC_Pos11 1024 #define WFC_Pos12 2048 #define WFC_Init() \ uint8 * TmpBuf=(uint8 *)malloc(Size); \ if (TmpBuf==NULL) return (GRZ_NOT_ENOUGH_MEMORY); \ \ sint32 WFC_List[WFC_MaxByte+1]; \ sint32 Char2Index[WFC_MaxByte+1]; \ sint32 CharWeight[WFC_MaxByte+1]; \ sint32 i; \ for (i=0;iW) \ { \ Char2Index[WFC_List[j]=WFC_List[j+1]]=j; \ j++; \ } \ WFC_List[j]=c; \ Char2Index[c]=j; \ } #define Update_Weight_Full(Weight,Pos) \ if (i>=Pos) \ { \ uint8 c=TmpBuf[i-Pos];Update_Weight(c,Weight); \ } \ sint32 WFC_Encode(uint8 * Input,sint32 Size) { WFC_Init(); for (i=0;(i { uint8 c=TmpBuf[i]=Input[i]; Input[i]=Char2Index[c]; Update_Weight0(c); Update_Weight_Full(WFC_Val1,WFC_Pos1); Update_Weight_Full(WFC_Val2,WFC_Pos2); Update_Weight_Full(WFC_Val3,WFC_Pos3); Update_Weight_Full(WFC_Val4,WFC_Pos4); Update_Weight_Full(WFC_Val5,WFC_Pos5); Update_Weight_Full(WFC_Val6,WFC_Pos6); Update_Weight_Full(WFC_Val7,WFC_Pos7); Update_Weight_Full(WFC_Val8,WFC_Pos8); Update_Weight_Full(WFC_Val9,WFC_Pos9); Update_Weight_Full(WFC_Val10,WFC_Pos10); Update_Weight_Full(WFC_Val11,WFC_Pos11); Update_Weight_Full(WFC_Val12,WFC_Pos12); } for (;i { uint8 c=TmpBuf[i]=Input[i]; Input[i]=Char2Index[c]; Update_Weight0(c); c=TmpBuf[i-WFC_Pos1]; Update_Weight(c,WFC_Val1); c=TmpBuf[i-WFC_Pos2]; Update_Weight(c,WFC_Val2); c=TmpBuf[i-WFC_Pos3]; Update_Weight(c,WFC_Val3); c=TmpBuf[i-WFC_Pos4]; Update_Weight(c,WFC_Val4); c=TmpBuf[i-WFC_Pos5]; Update_Weight(c,WFC_Val5); c=TmpBuf[i-WFC_Pos6]; Update_Weight(c,WFC_Val6); c=TmpBuf[i-WFC_Pos7]; Update_Weight(c,WFC_Val7); c=TmpBuf[i-WFC_Pos8]; Update_Weight(c,WFC_Val8); c=TmpBuf[i-WFC_Pos9]; Update_Weight(c,WFC_Val9); c=TmpBuf[i-WFC_Pos10]; Update_Weight(c,WFC_Val10); c=TmpBuf[i-WFC_Pos11]; Update_Weight(c,WFC_Val11); c=TmpBuf[i-WFC_Pos12]; Update_Weight(c,WFC_Val12); } WFC_Finish(); return (GRZ_NO_ERROR); }sint32 WFC_Decode(uint8 * Input, sint32 Size) { WFC_Init(); for (i=0;(i { uint8 c=WFC_List[Input[i]];TmpBuf[i]=Input[i]=c; Update_Weight0(c); Update_Weight_Full(WFC_Val1,WFC_Pos1); Update_Weight_Full(WFC_Val2,WFC_Pos2); Update_Weight_Full(WFC_Val3,WFC_Pos3); Update_Weight_Full(WFC_Val4,WFC_Pos4); Update_Weight_Full(WFC_Val5,WFC_Pos5); Update_Weight_Full(WFC_Val6,WFC_Pos6); Update_Weight_Full(WFC_Val7,WFC_Pos7); Update_Weight_Full(WFC_Val8,WFC_Pos8); Update_Weight_Full(WFC_Val9,WFC_Pos9); Update_Weight_Full(WFC_Val10,WFC_Pos10); Update_Weight_Full(WFC_Val11,WFC_Pos11); Update_Weight_Full(WFC_Val12,WFC_Pos12); } for (;i { uint8 c=WFC_List[Input[i]];TmpBuf[i]=Input[i]=c; Update_Weight0(c); c=TmpBuf[i-WFC_Pos1]; Update_Weight(c,WFC_Val1); c=TmpBuf[i-WFC_Pos2]; Update_Weight(c,WFC_Val2); c=TmpBuf[i-WFC_Pos3]; Update_Weight(c,WFC_Val3); c=TmpBuf[i-WFC_Pos4]; Update_Weight(c,WFC_Val4); c=TmpBuf[i-WFC_Pos5]; Update_Weight(c,WFC_Val5); c=TmpBuf[i-WFC_Pos6]; Update_Weight(c,WFC_Val6); c=TmpBuf[i-WFC_Pos7]; Update_Weight(c,WFC_Val7); c=TmpBuf[i-WFC_Pos8]; Update_Weight(c,WFC_Val8); c=TmpBuf[i-WFC_Pos9]; Update_Weight(c,WFC_Val9); c=TmpBuf[i-WFC_Pos10]; Update_Weight(c,WFC_Val10); c=TmpBuf[i-WFC_Pos11]; Update_Weight(c,WFC_Val11); c=TmpBuf[i-WFC_Pos12]; Update_Weight(c,WFC_Val12); } WFC_Finish(); return (GRZ_NO_ERROR); }sint32 GRZip_AWFC_Encode(uint8 * Input, sint32 Size) { uint8 * TmpBuf=(uint8 *)malloc(Size); if (TmpBuf==NULL) return (GRZ_NOT_ENOUGH_MEMORY); sint32 i,TmpBufSize=0; uint8 Pred=0; for (i=0;i if (Input[i]!=Pred) Pred=TmpBuf[TmpBufSize++]=Input[i]; if (WFC_Encode(TmpBuf,TmpBufSize)==GRZ_NOT_ENOUGH_MEMORY) { free(TmpBuf); return (GRZ_NOT_ENOUGH_MEMORY); } Pred=0; TmpBufSize=0; for (i=0;i if (Input[i]!=Pred) { Pred=Input[i]; Input[i]=TmpBuf[TmpBufSize++]; } else Input[i]=0; free(TmpBuf); return (GRZ_NO_ERROR); }sint32 GRZip_AWFC_Decode(uint8 * Input,sint32 Size) { uint8 * TmpBuf=(uint8 *)malloc(Size); if (TmpBuf==NULL) return (GRZ_NOT_ENOUGH_MEMORY); uint8 Pred=0; sint32 i,TmpBufSize=0; for (i=0;i if (Input[i]) TmpBuf[TmpBufSize++]=Input[i]; if (WFC_Decode(TmpBuf,TmpBufSize)==GRZ_NOT_ENOUGH_MEMORY) { free(TmpBuf); return (GRZ_NOT_ENOUGH_MEMORY); } TmpBufSize=0; for (i=0;i if (Input[i]==0) Input[i]=Pred; else Pred=Input[i]=TmpBuf[TmpBufSize++]; free(TmpBuf); return (GRZ_NO_ERROR); }#undef WFC_MaxByte #undef WFC_Init #undef WFC_Finish #undef Update_Weight #undef Update_Weight0 #undef Update_Weight_Full #undef WFC_Val0 #undef WFC_Val1 #undef WFC_Val2 #undef WFC_Val3 #undef WFC_Val4 #undef WFC_Val5 #undef WFC_Val6 #undef WFC_Val7 #undef WFC_Val8 #undef WFC_Val9 #undef WFC_Val10 #undef WFC_Val11 #undef WFC_Val12 #undef WFC_Pos1 #undef WFC_Pos2 #undef WFC_Pos3 #undef WFC_Pos4 #undef WFC_Pos5 #undef WFC_Pos6 #undef WFC_Pos7 #undef WFC_Pos8 #undef WFC_Pos9 #undef WFC_Pos10 #undef WFC_Pos11 #undef WFC_Pos12
|