メインページ | 構成 | ファイル一覧 | 構成メンバ | ファイルメンバ | 関連ページ

dkcRLE.c

説明を見る。
00001 
00007 #define DKUTILC_RLE_C
00008 #include "dkcRLE.h"
00009 
00010 
00011 
00012 DKC_RLE *WINAPI dkcAllocRLE(){
00013     DKC_RLE *p = (DKC_RLE *)dkcAllocate(sizeof(DKC_RLE));
00014     return p;
00015 }
00016 
00017 int WINAPI dkcFreeRLE(DKC_RLE **pp){
00018     if(NULL==pp){
00019         return edk_FAILED;
00020     }
00021     return dkcFree((void **)pp);
00022 }
00023 
00024 
00025 
00026 
00027 enum{
00029     rleABS_FINDRUN = -2,
00031     rleABS_FAILED = -1,
00033     rleABS_SUCCEEDED = 0,
00034 };
00035 
00036 struct ABSResult{
00037     USHORT offset;
00038     short result;
00039 };
00040 
00041 static struct ABSResult getABS(DKC_MEMORYSTREAM *pms,const BYTE *src,USHORT ssize,
00042                                     size_t ai,BYTE nocomp_id)
00043 {
00044     /*
00045     0 初期状態
00046     1 探し中
00047     2 書き込み中(breakするけど^^;)
00048     */
00049     int state = 0;
00050 
00051     //ラン長検索
00052     BYTE t1 = 0;
00053     DKC_RLE_NOCOMP tc;
00054     size_t i = ai;
00055     struct ABSResult r;
00056 
00057     r.offset = 0;
00058     r.result = rleABS_FAILED;
00059 
00060     DKUTIL_STRUCTURE_INIT(tc);
00061 
00062     for(;i < ssize;i++)
00063     {
00064         switch(state)
00065         {
00066         case 0:
00067             t1 = src[i];
00068 
00069 
00070             tc.length = 1;
00071             tc.sig = nocomp_id;
00072 
00073             state = 1;
00074             break;
00075         case 1:
00076             if(t1 == src[i]){
00077                 r.offset = (USHORT)(i - 1);
00078                 r.result = rleABS_FINDRUN;
00079                 state = 2;
00080                 break;
00081             }
00082             if(USHRT_MAX <= tc.length){
00083                 state = 2;
00084                 break;
00085             }
00086             t1 = src[i];
00087             tc.length ++;
00088             break;
00089         case 2:
00090             break;
00091         }
00092         if(2==state){
00093             break;
00094         }
00095     }//end of for
00096     if(tc.length != 0)
00097     {//すこしでも非圧縮が存在したら・・・書きこむ
00098         dkcMemoryStreamWrite(pms,&tc,sizeof(tc));
00099         dkcMemoryStreamWrite(pms,&src[i - tc.length],tc.length);
00100         if(r.result != rleABS_FINDRUN)
00101         {//とりあえず、全部終了したのなら・・・
00102             r.result = rleABS_SUCCEEDED;
00103         }
00104     }
00105     r.offset = (USHORT)i;
00106     return r;
00107 }
00108 /*
00109 @param ai[in] srcの1byte単位のオフセット
00110 */
00111 static int getRLE(DKC_MEMORYSTREAM *pms,const BYTE *src,USHORT ssize,
00112                                     size_t ai,BYTE nocomp_id,size_t CloseProcessSize,size_t old_mem_offset){
00113 
00114     /*
00115     0 : データをまだ取得していない
00116     1 : データのRun長を求める
00117     2 : 圧縮モードで書きこむ
00118     3 : 非圧縮モードに移行
00119     注意:
00120     state は 0 以外の状態に戻らないこと・・・。
00121     */
00122     int state = 0;
00123     DKC_RLE_COMP tc;
00124     size_t i = ai;
00125     size_t ti = ai;
00126     struct ABSResult ar;
00127 
00128 
00129     DKUTIL_STRUCTURE_INIT(tc);
00130 
00131     if(ai > ssize){
00132         return edk_FAILED;
00133     }
00134     for(;i < ssize;i++)
00135     {
00136         
00137         switch(state)
00138         {
00139         case 0:
00140             tc.data = src[i];
00141             tc.length = 1;
00142             ti = i;
00143             state = 1;
00144             break;
00145         case 1:
00146             if(tc.data == src[i]){
00147                 if(tc.length >= 255){
00148                     dkcMemoryStreamWrite(pms,&tc,sizeof(tc));
00149                     state = 0;
00150                     i--;
00151 
00152                     //state = 2;
00153                 }
00154                 tc.length++;
00155             }else if(tc.length <= 1){//非圧縮モードへ移行
00156                 ar = getABS(pms,src,ssize,ti,nocomp_id);
00157                 if(ar.result == rleABS_FINDRUN)
00158                 {//再びRLE圧縮へ
00159                     //i = ar.offset;
00160                     state = 0;
00161                     //break;
00162                 }
00163                 i = ar.offset;
00164                 //state = 3;
00165             }else{
00166                 dkcMemoryStreamWrite(pms,&tc,sizeof(tc));
00167                 state = 0;
00168                 i--;
00169                 //state = 2;
00170             }
00171             if(dkcMemoryStreamTell(pms) - old_mem_offset >= CloseProcessSize)
00172             {
00173                 return  edk_NoValueToProcess;
00174             
00175             }   
00176             break;
00177         case 2:
00178             dkcmNOT_ASSERT("廃止");
00179             //
00180             //state = 0;
00181             break;
00182         case 3:
00183             dkcmNOT_ASSERT("廃止");
00184             
00185             break;
00186         default:
00187             return edk_LogicError;
00188         }
00189     }
00190 
00191     return edk_SUCCEEDED;
00192 
00193 }
00194 
00195 int WINAPI dkcRLEEncode(DKC_RLE *p,DKC_MEMORYSTREAM *pms,
00196                                                 DKC_RLE_HEADER *ph,const BYTE *src,USHORT ssize,
00197                                                 size_t CloseProcessSize,ULONG sig,BYTE aEOF_ID,BYTE aABS_ID)
00198 {
00199     
00200     //dest couter
00201     size_t i = 0;
00202     //戻り値
00203     int r = edk_FAILED;
00204     //テンポラリ
00205     int tr;
00206 
00207 
00208     /*
00209     0 最初の状態
00210     1 圧縮書きこみ中
00211     2 非圧縮書き込み中
00212     */
00213     //int state = 0;
00214     //今のオフセット
00215     size_t old_mem_offset = dkcMemoryStreamTell(pms);
00216     //全部倒す
00217     memset(p->mTemp,0,sizeof(p->mTemp));
00218 
00219 
00220     if( i < ssize){
00221 
00222         tr = getRLE(pms,src,ssize,i,aABS_ID,CloseProcessSize,old_mem_offset);
00223         if(DKUTIL_FAILED(tr)){
00224             goto BACK;
00225         }
00226         if(dkcMemoryStreamTell(pms) - old_mem_offset >= CloseProcessSize)
00227         {
00228             return  edk_NoValueToProcess;
00229         
00230         }   
00231         r = edk_SUCCEEDED;
00232     }
00233     ph->mABS = aABS_ID;
00234     ph->mEOF = aEOF_ID;
00235     dkcmNOT_ASSERT(USHRT_MAX < dkcMemoryStreamTell(pms) - old_mem_offset);
00236     ph->mCompressedSize = (USHORT)(dkcMemoryStreamTell(pms) - old_mem_offset);
00237     ph->mOriginSize = ssize;
00238     ph->mSignature = sig;
00239 
00240 
00241     return r;
00242 BACK:
00243     //元に戻す・・・。なんか今までの処理が無駄っぽい・・・。゚(゚´Д`゚)゚。
00244     dkcMemoryStreamSeek(pms,old_mem_offset,edkcMemoryStreamSeekSet);
00245     return r;
00246 }
00247 
00248 
00249 
00250 
00251 int WINAPI dkcRLEDecode(DKC_RLE *p,DKC_MEMORYSTREAM *pms,
00252                                                 const DKC_RLE_HEADER *ph,const BYTE *src,USHORT ssize,
00253                                                 ULONG sig)
00254 {
00255 
00256     size_t i=0;
00257     BYTE t;
00258     //DKC_RLE_COMP co;
00259     DKC_RLE_NOCOMP nco;
00260     //今のオフセット
00261     size_t old_mem_offset = dkcMemoryStreamTell(pms);
00262     
00263     if(ph->mSignature != sig){
00264         return edk_SignatureException;
00265     }
00266 
00267     for(;i<ssize;i++)
00268     {
00269         t = src[i];
00270         if(t==ph->mABS){
00271             memcpy(&nco,&src[i],sizeof(nco));
00272             dkcMemoryStreamWrite(pms,&src[i],nco.length);
00273         }
00274         else if(t == ph->mEOF)
00275         {
00276             break;
00277         }else{//compressed
00278             if(t <= 1){
00279                 goto BACK;
00280             }
00281             memset(p->mTemp,src[i + 1],t);
00282             dkcMemoryStreamWrite(pms,&(p->mTemp),t);
00283 
00284             //一つ分update
00285             i++;
00286         }
00287     }//end of for
00288     
00289     return edk_SUCCEEDED;
00290 BACK:
00291 
00292     dkcMemoryStreamSeek(pms,old_mem_offset,edkcMemoryStreamSeekSet);
00293 
00294     return edk_FAILED;
00295 
00296 
00297 }

dkutil_cに対してTue Oct 19 03:34:55 2004に生成されました。 doxygen 1.3.6