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
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 }
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
00189
00190
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
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 }
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 }
00295 }
00296 if(!(i < ssize)){
00297 break;
00298 }
00299 }
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 }
00363 return r;
00364 }
00365
00366 #endif
00367
00368
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
00383
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 }
00411
00412
00413
00414 }
00415
00416 dkcMemoryStreamAdapterInit(&adr,dest,dsize);
00417
00418
00419
00420 state = 0;
00421 dkcmNOT_ASSERT(di % 2 != 0);
00422
00423
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
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
00473
00474
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 }
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
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
00543
00544
00545
00546
00547
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
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 {
00586
00587 state = 0;
00588
00589 }
00590 i = ar.offset;
00591
00592 }else{
00593 dkcMemoryStreamWrite(pms,&tc,sizeof(tc));
00594 state = 0;
00595 i--;
00596
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
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
00628 size_t i = 0;
00629
00630 int r = edk_FAILED;
00631
00632 int tr;
00633
00634
00635
00636
00637
00638
00639
00640
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
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{
00705 if(t <= 1){
00706 goto BACK;
00707 }
00708 memset(p->mTemp,src[i + 1],t);
00709 dkcMemoryStreamWrite(pms,&(p->mTemp),t);
00710
00711
00712 i++;
00713 }
00714 }
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