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 typedef BYTE Uchar;
00056 #define BYTE_MAX 256
00057
00058
00059 #define packbit(a) (BYTE)((a + 0x80) & 0xff)
00060
00061 #define int2byte(a) (BYTE)(a & 0xff)
00062
00063 int WINAPI dkcRLEPackBitsEncode(DKC_RLE_PACKBITS_HEADER *p,
00064 BYTE *dest,size_t dsize,
00065 const BYTE *src,size_t ssize,
00066 BYTE a_count)
00067 {
00068 BYTE *t = (BYTE *)src;
00069 BYTE *st = t + ssize;
00070 BYTE *out = dest;
00071 int i;
00072
00073 if(dkcCheckOverflowULONG( (ULONG) dest,dsize)){
00074 return edk_FAILED;
00075 }
00076 if(dsize < ssize * 2){
00077 return edk_ArgumentException;
00078 }
00079 if(CHAR_MAX < a_count || a_count <= 2){
00080 return edk_ArgumentException;
00081 }
00082 for(;;){
00083 unsigned int tt = *t;
00084 BYTE *inp = t;
00085 int n = 1;
00086 t++;
00087
00088 for(;t < st && n < CHAR_MAX;t++){
00089 if( *t != tt){
00090 break;
00091 }
00092 n ++;
00093 }
00094 if(n >= a_count){
00095 *out++ = packbit(n) ;
00096
00097 *out++ = (BYTE)(tt & 0xff);
00098
00099
00100 }else{
00101
00102 int c = 1;
00103 BYTE *se = inp;
00104 t = inp;
00105
00106 for(i = 0;se < st && i<CHAR_MAX;i++){
00107 if(c >= a_count){
00108 break;
00109 }
00110 if(t[i] == t[i + 1]){
00111 c++;
00112 }else{
00113 c = 1;
00114 }
00115
00116 se++;
00117 }
00118
00119
00120 if(c >= a_count){
00121 se -= (c - 1);
00122 i -= (c - 1);
00123 }
00124 *out++ = int2byte(i);
00125 for(;t < se;){
00126 *out++ = *t++;
00127 }
00128
00129
00130 }
00131 if(t >= st){
00132 break;
00133 }
00134 }
00135 p->mCompressedSize = out - dest;
00136 p->mOriginSize = ssize;
00137 p->mCount = a_count;
00138 return edk_SUCCEEDED;
00139 }
00140
00141
00142 int WINAPI dkcRLEPackBitsDecode(DKC_RLE_PACKBITS_HEADER *p,
00143 BYTE *dest,size_t dsize,
00144 const BYTE *src,size_t ssize)
00145 {
00146 BYTE *in = (BYTE *)src;
00147 const BYTE *sin = src + ssize;
00148 BYTE *out = dest;
00149 int i;
00150
00151 #ifdef DEBUG
00152 if(dkcCheckOverflowULONG( (ULONG) dest,dsize)){
00153 return edk_FAILED;
00154 }
00155 #endif
00156 if(dsize < p->mOriginSize){
00157 return edk_ArgumentException;
00158 }
00159 if(ssize < p->mCompressedSize){
00160 return edk_ArgumentException;
00161 }
00162 if(CHAR_MAX < p->mCount || p->mCount <= 2){
00163 return edk_ArgumentException;
00164 }
00165 for(;;){
00166 BYTE t = *in++;
00167 int st;
00168 if(t & 0x80){
00169 st = t - 0x80;
00170 for(i=0;i<st;i++){
00171 *out++ = *in;
00172 }
00173 in++;
00174 }else{
00175 st = t;
00176 for(i=0;i<st;i++){
00177 *out++ = *in++;
00178 }
00179 }
00180 if(in >= sin){
00181 break;
00182 }
00183 }
00184 return edk_SUCCEEDED;
00185 }
00186
00187
00188 #if 0 //version 4
00189
00190 int WINAPI dkcRLEPackBitsEncode(DKC_RLE_PACKBITS_HEADER *p,BYTE *dest,size_t dsize,
00191 const BYTE *src,size_t ssize,BYTE a_count)
00192 {
00193 int r = edk_FAILED;
00194 size_t i = 0;
00195 int count = 0;
00196 size_t ti = 0;
00197 size_t break_c = 0;
00198 DKC_MEMORYSTREAM_ADAPTER ad,bd;
00199 BYTE buff[128 + 2];
00200
00201 BYTE t;
00202
00203 dkcMemoryStreamAdapterInit(&ad,dest,dsize);
00204 dkcMemoryStreamAdapterInit(&bd,buff,sizeof(buff));
00205
00206
00207
00208 # define DKC_MSA_PUSH(a,d,s) dkcMemoryStreamAdapterPushBack(a,d,s)
00209 memset(p,0,sizeof(*p));
00210 if(dkcCheckOverflowULONG((ULONG)dest,dsize)){
00211 return edk_FAILED;
00212 }
00213 if(dsize < ssize * 2){
00214 return edk_ArgumentException;
00215 }
00216 if(CHAR_MAX < a_count || a_count <= 1){
00217 return edk_ArgumentException;
00218 }
00219
00220 for(;;){
00221 count = 1;
00222
00223 t = src[i];
00224 ti = i;
00225 i++;
00226 for(;;){
00227
00228 if(t != src[i]){
00229 break;
00230 }
00231
00232 count++;
00233 if(count >= -CHAR_MIN){
00234 break;
00235 }
00236 i++;
00237 if(!(i < ssize)){
00238 r = edk_SUCCEEDED;
00239 break;
00240 }
00241 }
00242
00243 if((size_t)count >= a_count){
00244 dkcMemoryStreamAdapterPushBackMacro(char,&ad,-count);
00245 dkcMemoryStreamAdapterPushBackMacro(BYTE,&ad,t);
00246 }else{
00247 i = ti;
00248 count = 0;
00249 break_c = 1;
00250 if(i != 0){
00251 t = src[i - 1];
00252 }else{
00253 t = (BYTE)(src[i] + 1);
00254 }
00255
00256
00257 for(;;){
00258 if(t == src[i]){
00259 if(1 == break_c){
00260 ti = i - 1;
00261 }
00262 break_c++;
00263 if(break_c >= a_count){
00264
00265 count -= i - ti;
00266 dkcMemoryStreamAdapterPopBack(&bd,i - ti);
00267 i = ti;
00268 break;
00269 }
00270
00271 }else{
00272 break_c = 1;
00273
00274 }
00275 dkcMemoryStreamAdapterPushBackMacro(BYTE,&bd,src[i]);
00276
00277 count++;
00278 if(count >= CHAR_MAX){
00279 break;
00280 }
00281 i++;
00282 if(!(i < ssize)){
00283 r = edk_SUCCEEDED;
00284 break;
00285 }
00286
00287 t = src[i - 1];
00288 }
00289 dkcMemoryStreamAdapterPushBackMacro(BYTE,&ad,count);
00290
00291 DKC_MSA_PUSH(&ad,
00292 dkcMemoryStreamAdapterPointer(&bd),dkcMemoryStreamAdapterGetOffset(&bd)
00293 );
00294 }
00295
00296 bd.mNowOffset = 0;
00297
00298 if(!(i < ssize)){
00299 r = edk_SUCCEEDED;
00300 break;
00301 }
00302 }
00303
00304 # undef DKC_MSA_PUSH
00305 p->mCompressedSize = dkcMemoryStreamAdapterGetOffset(&ad);
00306 p->mOriginSize = ssize;
00307 p->mCount = (int)a_count;
00308 return r;
00309 }
00310
00311 DKC_EXTERN int WINAPI dkcRLEPackBitsDecode(DKC_RLE_PACKBITS_HEADER *p,
00312 BYTE *dest,size_t dsize,
00313 const BYTE *src,size_t ssize)
00314 {
00315 const char *pt;
00316 int a_count = p->mCount;
00317 BYTE *po = dest,*sentinel = dest + dsize;
00318 size_t temp;
00319 size_t i = 0;
00320 int r = edk_FAILED;
00321
00322
00323
00324
00325
00326 if(dsize < p->mOriginSize){
00327 return edk_ArgumentException;
00328 }
00329 for(;;){
00330 pt = (const char *)&src[i];
00331 i++;
00332 if(*pt <= -a_count){
00333 temp = (size_t)(-(*pt));
00334 memset(po,src[i],temp);
00335
00336 po += temp;
00337 i++;
00338 }else{
00339
00340 dkcmNOT_ASSERT(*pt <= 0);
00341 temp = (size_t)(*pt);
00342 memcpy(po,&src[i],temp);
00343 i += temp;
00344 po += temp;
00345 }
00346 if(!(i < ssize)){
00347 r = edk_SUCCEEDED;
00348 break;
00349 }
00350 if(po == sentinel){
00351 break;
00352 }
00353 }
00354 return r;
00355 }
00356
00357 #endif
00358
00359 #if 0 //version 3
00360
00361 int WINAPI dkcRLEPackBitsEncode(DKC_RLE_PACKBITS_HEADER *p,BYTE *dest,size_t dsize,
00362 const BYTE *src,size_t ssize)
00363 {
00364 int r = edk_FAILED;
00365 size_t i = 0;
00366 char count = 0;
00367
00368 BYTE t,*sentinel,*begin = dest;
00369
00370
00371 if(dkcCheckOverflowULONG((ULONG)dest,dsize)){
00372 return edk_FAILED;
00373 }
00374 if(dsize < ssize * 2){
00375 return edk_ArgumentException;
00376 }
00377 sentinel = dest + dsize;
00378
00379 for(;;){
00380 count = -1;
00381 t = src[i];
00382 for(;;){
00383
00384 if(t != src[i + 1]){
00385 if(count != -1){
00386 i++;
00387 }
00388 break;
00389 }
00390 if(!(i < ssize)){
00391 r = edk_SUCCEEDED;
00392 break;
00393 }
00394 if(dest == sentinel){
00395 break;
00396 }
00397 count --;
00398 i++;
00399 if(count <= CHAR_MIN){
00400 break;
00401 }
00402
00403 }
00404
00405 if(count < -1){
00406 dest = setPack(dest,count,t);
00407 }else{
00408 count = 1;
00409 for(;;){
00410 if(!(i < ssize)){
00411 r = edk_SUCCEEDED;
00412 break;
00413 }
00414 if(dest == sentinel){
00415 break;
00416 }
00417 *dest = src[i];
00418
00419 count++;
00420 dest++;
00421 i++;
00422 if(count >= CHAR_MAX){
00423 break;
00424 }
00425 if(t == src[i]){
00426 i-=2;
00427 break;
00428 }
00429 t = src[i - 1];
00430 }
00431 }
00432 if(!(i < ssize)){
00433 break;
00434 }
00435 }
00436 p->mCompressedSize = dest - begin;
00437 p->mOriginSize = ssize;
00438 return r;
00439 }
00440
00441 int WINAPI dkcRLEPackBitsDecode(DKC_RLE_PACKBITS_HEADER *p,BYTE *dest,size_t dsize,
00442 const BYTE *src,size_t ssize)
00443 {
00444 int r = edk_FAILED;
00445 size_t i = 0;
00446 char count = 0;
00447 const char *tc;
00448
00449 BYTE *sentinel;
00450
00451 if(dkcCheckOverflowULONG((ULONG)dest,dsize)){
00452 return edk_FAILED;
00453 }
00454 sentinel = dest + dsize;
00455
00456 for(;;){
00457
00458 tc = (const char *)(src + i);
00459
00460 if(*tc < -1){
00461 count ++;
00462 for(;dest != sentinel;){
00463 if(count <= *tc){
00464 *dest = src[i + 1];
00465 break;
00466 }
00467 *dest = src[i + 1];
00468 count--;
00469 dest++;
00470 if(!(i < ssize)){
00471 break;
00472 }
00473 }
00474
00475
00476 }else{
00477 dkcmNOT_ASSERT(tc == 0);
00478 i++;
00479 count = 1;
00480 for(;dest != sentinel;){
00481 if(count >= *tc){
00482 *dest = src[i];
00483 break;
00484 }
00485 *dest = src[i];
00486 count--;
00487 dest++;
00488
00489
00490 if(!(i < ssize)){
00491 r = edk_SUCCEEDED;
00492 break;
00493 }
00494 i++;
00495 }
00496 }
00497
00498 }
00499 return r;
00500 }
00501
00502 #endif
00503
00504
00505 #if 0 // version 2
00506 static DKC_INLINE size_t store(BYTE *dest,DKC_RLE_COMP *pc,size_t di){
00507 dest[di] = co.length;
00508 di ++;
00509 dest[di] = co.data;
00510 di ++;
00511 return di;
00512 }
00513
00514 static DKC_INLINE int encode(DKC_RLE *p,BYTE *dest,size_t dsize,
00515 const BYTE *src,size_t ssize,BYTE nocomp_id){
00516 size_t i;
00517
00518
00519
00520
00521 int state = 0;
00522 DKC_RLE_COMP co;
00523 DKC_MEMORYSTREAM_ADAPTER adr;
00524 BYTE *td,t;
00525
00526 for(i = 0;i < ssize;i++){
00527 switch(state){
00528 case 0:
00529 co.data = src[i];
00530 co.length = 1;
00531 state = 1;
00532 break;
00533 case 1:
00534 if(co.data == src[i]){
00535 if(co.length >= 255){
00536 di = store(dest,&co,di);
00537 break;
00538 }
00539 co.length ++;
00540
00541 }else{
00542 dkcmNOT_ASSERT(co.length == 0);
00543 di = store(dest,&co,di);
00544 }
00545 break;
00546 }
00547
00548
00549
00550 }
00551
00552 dkcMemoryStreamAdapterInit(&adr,dest,dsize);
00553
00554
00555
00556 state = 0;
00557 dkcmNOT_ASSERT(di % 2 != 0);
00558
00559
00560 size_t ti = 0,j = 0,count = 0;
00561 for(i = 0;i < di;i++){
00562 t = dest[i];
00563 switch(state){
00564 case 0:
00565 if(t == 1){
00566 ti = i;
00567 count = 1;
00568 for(j=i + 2;j<di;j+=2){
00569 if(dest[j] == 1){
00570 count ++;
00571 }else{
00572 break;
00573 }
00574 };
00575 dest[ti] = nocomp_id;
00576 dest[ti + 2] = dest[ti + 1];
00577 dest[ti + 1] = count;
00578 for(j = i;j<count - 1;j++,ti++){
00579 dest[ti + 3] = dest[j * 2];
00580 }
00581
00582
00583
00584
00585 i++
00586
00587
00588
00589 dest[i]
00590 }
00591
00592
00593
00594
00595 }
00596
00597
00598 }
00599
00600 #endif
00601
00602 #if 0 //version 1
00603
00604 static struct ABSResult getABS(DKC_MEMORYSTREAM *pms,const BYTE *src,USHORT ssize,
00605 size_t ai,BYTE nocomp_id)
00606 {
00607
00608
00609
00610
00611
00612 int state = 0;
00613
00614
00615 BYTE t1 = 0;
00616 DKC_RLE_NOCOMP tc;
00617 size_t i = ai;
00618 struct ABSResult r;
00619
00620 r.offset = 0;
00621 r.result = rleABS_FAILED;
00622
00623 DKUTIL_STRUCTURE_INIT(tc);
00624
00625 for(;i < ssize;i++)
00626 {
00627 switch(state)
00628 {
00629 case 0:
00630 t1 = src[i];
00631
00632
00633 tc.length = 1;
00634 tc.sig = nocomp_id;
00635
00636 state = 1;
00637 break;
00638 case 1:
00639 if(t1 == src[i]){
00640 r.offset = (USHORT)(i - 1);
00641 r.result = rleABS_FINDRUN;
00642 state = 2;
00643 break;
00644 }
00645 if(USHRT_MAX <= tc.length){
00646 state = 2;
00647 break;
00648 }
00649 t1 = src[i];
00650 tc.length ++;
00651 break;
00652 case 2:
00653 break;
00654 }
00655 if(2==state){
00656 break;
00657 }
00658 }
00659 if(tc.length != 0)
00660 {
00661 dkcMemoryStreamWrite(pms,&tc,sizeof(tc));
00662 dkcMemoryStreamWrite(pms,&src[i - tc.length],tc.length);
00663 if(r.result != rleABS_FINDRUN)
00664 {
00665 r.result = rleABS_SUCCEEDED;
00666 }
00667 }
00668 r.offset = (USHORT)i;
00669 return r;
00670 }
00671
00672
00673
00674 static int getRLE(DKC_MEMORYSTREAM *pms,const BYTE *src,USHORT ssize,
00675 size_t ai,BYTE nocomp_id,size_t CloseProcessSize,size_t old_mem_offset){
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685 int state = 0;
00686 DKC_RLE_COMP tc;
00687 size_t i = ai;
00688 size_t ti = ai;
00689 struct ABSResult ar;
00690
00691
00692 DKUTIL_STRUCTURE_INIT(tc);
00693
00694 if(ai > ssize){
00695 return edk_FAILED;
00696 }
00697 for(;i < ssize;i++)
00698 {
00699
00700 switch(state)
00701 {
00702 case 0:
00703 tc.data = src[i];
00704 tc.length = 1;
00705 ti = i;
00706 state = 1;
00707 break;
00708 case 1:
00709 if(tc.data == src[i]){
00710 if(tc.length >= 255){
00711 dkcMemoryStreamWrite(pms,&tc,sizeof(tc));
00712 state = 0;
00713 i--;
00714
00715
00716 }
00717 tc.length++;
00718 }else if(tc.length <= 1){
00719 ar = getABS(pms,src,ssize,ti,nocomp_id);
00720 if(ar.result == rleABS_FINDRUN)
00721 {
00722
00723 state = 0;
00724
00725 }
00726 i = ar.offset;
00727
00728 }else{
00729 dkcMemoryStreamWrite(pms,&tc,sizeof(tc));
00730 state = 0;
00731 i--;
00732
00733 }
00734 if(dkcMemoryStreamTell(pms) - old_mem_offset >= CloseProcessSize)
00735 {
00736 return edk_NoValueToProcess;
00737
00738 }
00739 break;
00740 case 2:
00741 dkcmNOT_ASSERT("廃止");
00742
00743
00744 break;
00745 case 3:
00746 dkcmNOT_ASSERT("廃止");
00747
00748 break;
00749 default:
00750 return edk_LogicError;
00751 }
00752 }
00753
00754 return edk_SUCCEEDED;
00755
00756 }
00757
00758 int WINAPI dkcRLEEncode(DKC_RLE *p,DKC_MEMORYSTREAM *pms,
00759 DKC_RLE_HEADER *ph,const BYTE *src,USHORT ssize,
00760 size_t CloseProcessSize,ULONG sig,BYTE aEOF_ID,BYTE aABS_ID)
00761 {
00762
00763
00764 size_t i = 0;
00765
00766 int r = edk_FAILED;
00767
00768 int tr;
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778 size_t old_mem_offset = dkcMemoryStreamTell(pms);
00779
00780 memset(p->mTemp,0,sizeof(p->mTemp));
00781
00782
00783 if( i < ssize){
00784
00785 tr = getRLE(pms,src,ssize,i,aABS_ID,CloseProcessSize,old_mem_offset);
00786 if(DKUTIL_FAILED(tr)){
00787 goto BACK;
00788 }
00789 if(dkcMemoryStreamTell(pms) - old_mem_offset >= CloseProcessSize)
00790 {
00791 return edk_NoValueToProcess;
00792
00793 }
00794 r = edk_SUCCEEDED;
00795 }
00796 ph->mABS = aABS_ID;
00797 ph->mEOF = aEOF_ID;
00798 dkcmNOT_ASSERT(USHRT_MAX < dkcMemoryStreamTell(pms) - old_mem_offset);
00799 ph->mCompressedSize = (USHORT)(dkcMemoryStreamTell(pms) - old_mem_offset);
00800 ph->mOriginSize = ssize;
00801 ph->mSignature = sig;
00802
00803
00804 return r;
00805 BACK:
00806
00807 dkcMemoryStreamSeek(pms,old_mem_offset,edkcMemoryStreamSeekSet);
00808 return r;
00809 }
00810
00811
00812
00813
00814 int WINAPI dkcRLEDecode(DKC_RLE *p,DKC_MEMORYSTREAM *pms,
00815 const DKC_RLE_HEADER *ph,const BYTE *src,USHORT ssize,
00816 ULONG sig)
00817 {
00818
00819 size_t i=0;
00820 BYTE t;
00821
00822 DKC_RLE_NOCOMP nco;
00823
00824 size_t old_mem_offset = dkcMemoryStreamTell(pms);
00825
00826 if(ph->mSignature != sig){
00827 return edk_SignatureException;
00828 }
00829
00830 for(;i<ssize;i++)
00831 {
00832 t = src[i];
00833 if(t==ph->mABS){
00834 memcpy(&nco,&src[i],sizeof(nco));
00835 dkcMemoryStreamWrite(pms,&src[i],nco.length);
00836 }
00837 else if(t == ph->mEOF)
00838 {
00839 break;
00840 }else{
00841 if(t <= 1){
00842 goto BACK;
00843 }
00844 memset(p->mTemp,src[i + 1],t);
00845 dkcMemoryStreamWrite(pms,&(p->mTemp),t);
00846
00847
00848 i++;
00849 }
00850 }
00851
00852 return edk_SUCCEEDED;
00853 BACK:
00854
00855 dkcMemoryStreamSeek(pms,old_mem_offset,edkcMemoryStreamSeekSet);
00856
00857 return edk_FAILED;
00858
00859
00860 }
00861
00862
00863 #endif