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

dkcRLE.c

説明を見る。
00001 
00007 #define DKUTIL_C_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 
00042 
00043 static BYTE * setPack(BYTE *dest,char count,BYTE data){
00044     char *tc;
00045     tc = (char *)dest;
00046     *tc = count;
00047     dest++;
00048     *dest = data;
00049     dest++;
00050     return dest;
00051 }
00052 
00053 
00054 
00055 
00056 int WINAPI dkcRLEPackBitsEncode(DKC_RLE_PACKBITS_HEADER *p,BYTE *dest,size_t dsize,
00057                                                                 const BYTE *src,size_t ssize,BYTE a_count)
00058 {   
00059     int r = edk_FAILED;
00060     size_t i = 0;
00061     int count = 0;
00062     size_t ti = 0;
00063     size_t break_c = 0;
00064     DKC_MEMORYSTREAM_ADAPTER ad,bd;
00065     BYTE buff[128 + 2];
00066     //size_t bc = 0;
00067     BYTE t;
00068     
00069     dkcMemoryStreamAdapterInit(&ad,dest,dsize);
00070     dkcMemoryStreamAdapterInit(&bd,buff,sizeof(buff));
00071 
00072 
00073 
00074 #   define DKC_MSA_PUSH(a,d,s) dkcMemoryStreamAdapterPushBack(a,d,s)
00075     memset(p,0,sizeof(*p));
00076     if(dkcCheckOverflowULONG((ULONG)dest,dsize)){
00077         return edk_FAILED;
00078     }
00079     if(dsize < ssize * 2){
00080         return edk_ArgumentException;
00081     }
00082     if(CHAR_MAX < a_count || a_count <= 1){
00083         return edk_ArgumentException;
00084     }
00085 
00086     for(;;){
00087         count = 1;
00088         
00089         t = src[i];
00090         ti = i;
00091         i++;
00092         for(;;){
00093             
00094             if(t != src[i]){
00095                 break;
00096             }
00097             
00098             count++;
00099             if(count >= -CHAR_MIN){
00100                 break;
00101             }
00102             i++;
00103             if(!(i < ssize)){
00104                 r = edk_SUCCEEDED;
00105                 break;
00106             }
00107         }
00108 
00109         if((size_t)count >= a_count){
00110             dkcMemoryStreamAdapterPushBackMacro(char,&ad,-count);
00111             dkcMemoryStreamAdapterPushBackMacro(BYTE,&ad,t);
00112         }else{
00113             i = ti;
00114             count = 0;
00115             break_c = 1;
00116             if(i != 0){
00117                 t = src[i - 1];
00118             }else{
00119                 t = (BYTE)(src[i] + 1);
00120             }
00121 
00122 
00123             for(;;){
00124                 if(t == src[i]){
00125                     if(1 == break_c){
00126                         ti = i - 1;
00127                     }
00128                     break_c++;
00129                     if(break_c >= a_count){
00130                         
00131                         count -= i - ti;
00132                         dkcMemoryStreamAdapterPopBack(&bd,i - ti);
00133                         i = ti;
00134                         break;
00135                     }
00136                     
00137                 }else{
00138                     break_c = 1;
00139                     
00140                 }
00141                 dkcMemoryStreamAdapterPushBackMacro(BYTE,&bd,src[i]);
00142 
00143                 count++;
00144                 if(count >= CHAR_MAX){
00145                     break;
00146                 }
00147                 i++;
00148                 if(!(i < ssize)){
00149                     r = edk_SUCCEEDED;
00150                     break;
00151                 }
00152                 
00153                 t = src[i - 1];
00154             }
00155             dkcMemoryStreamAdapterPushBackMacro(BYTE,&ad,count);
00156             
00157             DKC_MSA_PUSH(&ad,
00158                 dkcMemoryStreamAdapterPointer(&bd),dkcMemoryStreamAdapterGetOffset(&bd)
00159             );
00160         }
00161         
00162         bd.mNowOffset = 0;
00163 
00164         if(!(i < ssize)){
00165             r = edk_SUCCEEDED;
00166             break;
00167         }
00168     }//end of for
00169 
00170 #   undef DKC_MSA_PUSH
00171     p->mCompressedSize = dkcMemoryStreamAdapterGetOffset(&ad);
00172     p->mOriginSize = ssize;
00173     p->mCount = (int)a_count;
00174     return r;
00175 }
00176 
00177 DKC_EXTERN int WINAPI dkcRLEPackBitsDecode(DKC_RLE_PACKBITS_HEADER *p,
00178                                                                                      BYTE *dest,size_t dsize,
00179                                                                 const BYTE *src,size_t ssize)
00180 {
00181     const char *pt;
00182     int a_count = p->mCount;
00183     BYTE *po = dest,*sentinel = dest + dsize;
00184     size_t temp;
00185     size_t i = 0;
00186     int r = edk_FAILED;
00187 
00188     //DKC_MEMORYSTREAM_ADAPTER ad,bd;
00189 
00190     //dkcMemoryStreamAdapterInit(&ad,dest,dsize);
00191 
00192     if(dsize < p->mOriginSize){
00193         return edk_ArgumentException;
00194     }
00195     for(;;){
00196         pt = (const char *)&src[i];
00197         i++;
00198         if(*pt <= -a_count){
00199             temp = (size_t)(-(*pt));
00200             memset(po,src[i],temp);
00201             
00202             po += temp;
00203             i++;
00204         }else{
00205             //dkcmNOT_ASSERT(*pt == 0);
00206             dkcmNOT_ASSERT(*pt <= 0);
00207             temp = (size_t)(*pt);
00208             memcpy(po,&src[i],temp);
00209             i += temp;
00210             po += temp;
00211         }
00212         if(!(i < ssize)){
00213             r = edk_SUCCEEDED;
00214             break;
00215         }
00216         if(po == sentinel){
00217             break;
00218         }
00219     }//end of for
00220     return r;
00221 }
00222 
00223 #if 0
00224 
00225 int WINAPI dkcRLEPackBitsEncode(DKC_RLE_PACKBITS_HEADER *p,BYTE *dest,size_t dsize,
00226                                                                 const BYTE *src,size_t ssize)
00227 {   
00228     int r = edk_FAILED;
00229     size_t i = 0;
00230     char count = 0;
00231     
00232     BYTE t,*sentinel,*begin = dest;
00233 
00234 
00235     if(dkcCheckOverflowULONG((ULONG)dest,dsize)){
00236         return edk_FAILED;
00237     }
00238     if(dsize < ssize * 2){
00239         return edk_ArgumentException;
00240     }
00241     sentinel = dest + dsize;
00242 
00243     for(;;){
00244         count = -1;
00245         t = src[i];
00246         for(;;){
00247             
00248             if(t != src[i + 1]){
00249                 if(count != -1){
00250                     i++;
00251                 }
00252                 break;
00253             }
00254             if(!(i < ssize)){
00255                 r = edk_SUCCEEDED;
00256                 break;
00257             }
00258             if(dest == sentinel){
00259                 break;
00260             }
00261             count --;
00262             i++;
00263             if(count <= CHAR_MIN){
00264                 break;
00265             }
00266 
00267         }
00268 
00269         if(count < -1){
00270             dest = setPack(dest,count,t);
00271         }else{
00272             count = 1;
00273             for(;;){
00274                 if(!(i < ssize)){
00275                     r = edk_SUCCEEDED;
00276                     break;
00277                 }
00278                 if(dest == sentinel){
00279                     break;
00280                 }
00281                 *dest = src[i];
00282 
00283                 count++;
00284                 dest++;
00285                 i++;
00286                 if(count >= CHAR_MAX){
00287                     break;
00288                 }
00289                 if(t == src[i]){
00290                     i-=2;
00291                     break;
00292                 }
00293                 t = src[i - 1];
00294             }//end of for
00295         }
00296         if(!(i < ssize)){
00297             break;
00298         }
00299     }//end of for
00300     p->mCompressedSize = dest - begin;
00301     p->mOriginSize = ssize;
00302     return r;
00303 }
00304 
00305 int WINAPI dkcRLEPackBitsDecode(DKC_RLE_PACKBITS_HEADER *p,BYTE *dest,size_t dsize,
00306                                                                 const BYTE *src,size_t ssize)
00307 {
00308     int r = edk_FAILED;
00309     size_t i = 0;
00310     char count = 0;
00311     const char *tc;
00312     
00313     BYTE *sentinel;
00314     
00315     if(dkcCheckOverflowULONG((ULONG)dest,dsize)){
00316         return edk_FAILED;
00317     }
00318     sentinel = dest + dsize;
00319 
00320     for(;;){
00321         
00322         tc = (const char *)(src + i);
00323 
00324         if(*tc < -1){//圧縮
00325             count ++;
00326             for(;dest != sentinel;){
00327                 if(count <= *tc){
00328                     *dest = src[i + 1];
00329                     break;
00330                 }
00331                 *dest = src[i + 1];
00332                 count--;
00333                 dest++;
00334                 if(!(i < ssize)){
00335                     break;
00336                 }
00337             }
00338             
00339             
00340         }else{//非圧縮
00341             dkcmNOT_ASSERT(tc == 0);
00342             i++;
00343             count = 1;
00344             for(;dest != sentinel;){
00345                 if(count >= *tc){
00346                     *dest = src[i];
00347                     break;
00348                 }
00349                 *dest = src[i];
00350                 count--;
00351                 dest++;
00352 
00353 
00354                 if(!(i < ssize)){
00355                     r = edk_SUCCEEDED;
00356                     break;
00357                 }
00358                 i++;
00359             }
00360         }
00361         
00362     }//end of for
00363     return r;
00364 }
00365 
00366 #endif
00367 
00368 //static DKC_INLINE int zero_rle(DKC_RLE *p,BYTE *dest,size_t dsize,
00369 #if 0
00370 static DKC_INLINE size_t store(BYTE *dest,DKC_RLE_COMP *pc,size_t di){
00371     dest[di] = co.length;
00372     di ++;
00373     dest[di] = co.data;
00374     di ++;
00375     return di;
00376 }
00377 
00378 static DKC_INLINE int encode(DKC_RLE *p,BYTE *dest,size_t dsize,
00379                                                          const BYTE *src,size_t ssize,BYTE nocomp_id){
00380     size_t i;
00381     /*
00382     0 初期
00383     1 ラン長を求めるか 書きこみ処理
00384     */
00385     int state = 0;
00386     DKC_RLE_COMP co;
00387     DKC_MEMORYSTREAM_ADAPTER adr;
00388     BYTE *td,t;
00389 
00390     for(i = 0;i < ssize;i++){
00391         switch(state){
00392         case 0:
00393             co.data = src[i];
00394             co.length = 1;
00395             state = 1;
00396             break;
00397         case 1:
00398             if(co.data == src[i]){
00399                 if(co.length >= 255){
00400                     di = store(dest,&co,di);
00401                     break;
00402                 }
00403                 co.length ++;
00404                 
00405             }else{
00406                 dkcmNOT_ASSERT(co.length == 0);
00407                 di = store(dest,&co,di);
00408             }
00409             break;
00410         }//end of switch
00411 
00412 
00413 
00414     }//end of for
00415 
00416     dkcMemoryStreamAdapterInit(&adr,dest,dsize);
00417     /*
00418     0 : 調べ中
00419     */
00420     state = 0;
00421     dkcmNOT_ASSERT(di % 2 != 0);
00422 
00423     //td = dest;
00424     size_t ti = 0,j = 0,count = 0;
00425     for(i = 0;i < di;i++){
00426         t = dest[i];
00427         switch(state){
00428         case 0:
00429             if(t == 1){
00430                 ti = i;
00431                 count = 1;
00432                 for(j=i + 2;j<di;j+=2){
00433                     if(dest[j] == 1){
00434                         count ++;
00435                     }else{
00436                         break;
00437                     }
00438                 };
00439                 dest[ti] = nocomp_id;
00440                 dest[ti + 2] = dest[ti + 1];
00441                 dest[ti + 1] = count;
00442                 for(j = i;j<count - 1;j++,ti++){
00443                     dest[ti + 3] = dest[j * 2];
00444                 }
00445 
00446                 
00447                 
00448                 
00449                 i++
00450             
00451             
00452                 //dest[i]
00453                 dest[i] 
00454             }
00455 
00456         
00457 
00458 
00459     }
00460 
00461 
00462 }
00463 
00464 #endif
00465 
00466 #if 0
00467 
00468 static struct ABSResult getABS(DKC_MEMORYSTREAM *pms,const BYTE *src,USHORT ssize,
00469                                     size_t ai,BYTE nocomp_id)
00470 {
00471     /*
00472     0 初期状態
00473     1 探し中
00474     2 書き込み中(breakするけど^^;)
00475     */
00476     int state = 0;
00477 
00478     //ラン長検索
00479     BYTE t1 = 0;
00480     DKC_RLE_NOCOMP tc;
00481     size_t i = ai;
00482     struct ABSResult r;
00483 
00484     r.offset = 0;
00485     r.result = rleABS_FAILED;
00486 
00487     DKUTIL_STRUCTURE_INIT(tc);
00488 
00489     for(;i < ssize;i++)
00490     {
00491         switch(state)
00492         {
00493         case 0:
00494             t1 = src[i];
00495 
00496 
00497             tc.length = 1;
00498             tc.sig = nocomp_id;
00499 
00500             state = 1;
00501             break;
00502         case 1:
00503             if(t1 == src[i]){
00504                 r.offset = (USHORT)(i - 1);
00505                 r.result = rleABS_FINDRUN;
00506                 state = 2;
00507                 break;
00508             }
00509             if(USHRT_MAX <= tc.length){
00510                 state = 2;
00511                 break;
00512             }
00513             t1 = src[i];
00514             tc.length ++;
00515             break;
00516         case 2:
00517             break;
00518         }
00519         if(2==state){
00520             break;
00521         }
00522     }//end of for
00523     if(tc.length != 0)
00524     {//すこしでも非圧縮が存在したら・・・書きこむ
00525         dkcMemoryStreamWrite(pms,&tc,sizeof(tc));
00526         dkcMemoryStreamWrite(pms,&src[i - tc.length],tc.length);
00527         if(r.result != rleABS_FINDRUN)
00528         {//とりあえず、全部終了したのなら・・・
00529             r.result = rleABS_SUCCEEDED;
00530         }
00531     }
00532     r.offset = (USHORT)i;
00533     return r;
00534 }
00535 /*
00536 @param ai[in] srcの1byte単位のオフセット
00537 */
00538 static int getRLE(DKC_MEMORYSTREAM *pms,const BYTE *src,USHORT ssize,
00539                                     size_t ai,BYTE nocomp_id,size_t CloseProcessSize,size_t old_mem_offset){
00540 
00541     /*
00542     0 : データをまだ取得していない
00543     1 : データのRun長を求める
00544     2 : 圧縮モードで書きこむ
00545     3 : 非圧縮モードに移行
00546     注意:
00547     state は 0 以外の状態に戻らないこと・・・。
00548     */
00549     int state = 0;
00550     DKC_RLE_COMP tc;
00551     size_t i = ai;
00552     size_t ti = ai;
00553     struct ABSResult ar;
00554 
00555 
00556     DKUTIL_STRUCTURE_INIT(tc);
00557 
00558     if(ai > ssize){
00559         return edk_FAILED;
00560     }
00561     for(;i < ssize;i++)
00562     {
00563         
00564         switch(state)
00565         {
00566         case 0:
00567             tc.data = src[i];
00568             tc.length = 1;
00569             ti = i;
00570             state = 1;
00571             break;
00572         case 1:
00573             if(tc.data == src[i]){
00574                 if(tc.length >= 255){
00575                     dkcMemoryStreamWrite(pms,&tc,sizeof(tc));
00576                     state = 0;
00577                     i--;
00578 
00579                     //state = 2;
00580                 }
00581                 tc.length++;
00582             }else if(tc.length <= 1){//非圧縮モードへ移行
00583                 ar = getABS(pms,src,ssize,ti,nocomp_id);
00584                 if(ar.result == rleABS_FINDRUN)
00585                 {//再びRLE圧縮へ
00586                     //i = ar.offset;
00587                     state = 0;
00588                     //break;
00589                 }
00590                 i = ar.offset;
00591                 //state = 3;
00592             }else{
00593                 dkcMemoryStreamWrite(pms,&tc,sizeof(tc));
00594                 state = 0;
00595                 i--;
00596                 //state = 2;
00597             }
00598             if(dkcMemoryStreamTell(pms) - old_mem_offset >= CloseProcessSize)
00599             {
00600                 return  edk_NoValueToProcess;
00601             
00602             }   
00603             break;
00604         case 2:
00605             dkcmNOT_ASSERT("廃止");
00606             //
00607             //state = 0;
00608             break;
00609         case 3:
00610             dkcmNOT_ASSERT("廃止");
00611             
00612             break;
00613         default:
00614             return edk_LogicError;
00615         }
00616     }
00617 
00618     return edk_SUCCEEDED;
00619 
00620 }
00621 
00622 int WINAPI dkcRLEEncode(DKC_RLE *p,DKC_MEMORYSTREAM *pms,
00623                                                 DKC_RLE_HEADER *ph,const BYTE *src,USHORT ssize,
00624                                                 size_t CloseProcessSize,ULONG sig,BYTE aEOF_ID,BYTE aABS_ID)
00625 {
00626     
00627     //dest couter
00628     size_t i = 0;
00629     //戻り値
00630     int r = edk_FAILED;
00631     //テンポラリ
00632     int tr;
00633 
00634 
00635     /*
00636     0 最初の状態
00637     1 圧縮書きこみ中
00638     2 非圧縮書き込み中
00639     */
00640     //int state = 0;
00641     //今のオフセット
00642     size_t old_mem_offset = dkcMemoryStreamTell(pms);
00643     //全部倒す
00644     memset(p->mTemp,0,sizeof(p->mTemp));
00645 
00646 
00647     if( i < ssize){
00648 
00649         tr = getRLE(pms,src,ssize,i,aABS_ID,CloseProcessSize,old_mem_offset);
00650         if(DKUTIL_FAILED(tr)){
00651             goto BACK;
00652         }
00653         if(dkcMemoryStreamTell(pms) - old_mem_offset >= CloseProcessSize)
00654         {
00655             return  edk_NoValueToProcess;
00656         
00657         }   
00658         r = edk_SUCCEEDED;
00659     }
00660     ph->mABS = aABS_ID;
00661     ph->mEOF = aEOF_ID;
00662     dkcmNOT_ASSERT(USHRT_MAX < dkcMemoryStreamTell(pms) - old_mem_offset);
00663     ph->mCompressedSize = (USHORT)(dkcMemoryStreamTell(pms) - old_mem_offset);
00664     ph->mOriginSize = ssize;
00665     ph->mSignature = sig;
00666 
00667 
00668     return r;
00669 BACK:
00670     //元に戻す・・・。なんか今までの処理が無駄っぽい・・・。゚(゚´Д`゚)゚。
00671     dkcMemoryStreamSeek(pms,old_mem_offset,edkcMemoryStreamSeekSet);
00672     return r;
00673 }
00674 
00675 
00676 
00677 
00678 int WINAPI dkcRLEDecode(DKC_RLE *p,DKC_MEMORYSTREAM *pms,
00679                                                 const DKC_RLE_HEADER *ph,const BYTE *src,USHORT ssize,
00680                                                 ULONG sig)
00681 {
00682 
00683     size_t i=0;
00684     BYTE t;
00685     //DKC_RLE_COMP co;
00686     DKC_RLE_NOCOMP nco;
00687     //今のオフセット
00688     size_t old_mem_offset = dkcMemoryStreamTell(pms);
00689     
00690     if(ph->mSignature != sig){
00691         return edk_SignatureException;
00692     }
00693 
00694     for(;i<ssize;i++)
00695     {
00696         t = src[i];
00697         if(t==ph->mABS){
00698             memcpy(&nco,&src[i],sizeof(nco));
00699             dkcMemoryStreamWrite(pms,&src[i],nco.length);
00700         }
00701         else if(t == ph->mEOF)
00702         {
00703             break;
00704         }else{//compressed
00705             if(t <= 1){
00706                 goto BACK;
00707             }
00708             memset(p->mTemp,src[i + 1],t);
00709             dkcMemoryStreamWrite(pms,&(p->mTemp),t);
00710 
00711             //一つ分update
00712             i++;
00713         }
00714     }//end of for
00715     
00716     return edk_SUCCEEDED;
00717 BACK:
00718 
00719     dkcMemoryStreamSeek(pms,old_mem_offset,edkcMemoryStreamSeekSet);
00720 
00721     return edk_FAILED;
00722 
00723 
00724 }
00725 
00726 
00727 #endif

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