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
00046
00047
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 }
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
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
00116
00117
00118
00119
00120
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
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 {
00159
00160 state = 0;
00161
00162 }
00163 i = ar.offset;
00164
00165 }else{
00166 dkcMemoryStreamWrite(pms,&tc,sizeof(tc));
00167 state = 0;
00168 i--;
00169
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
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
00201 size_t i = 0;
00202
00203 int r = edk_FAILED;
00204
00205 int tr;
00206
00207
00208
00209
00210
00211
00212
00213
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
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{
00278 if(t <= 1){
00279 goto BACK;
00280 }
00281 memset(p->mTemp,src[i + 1],t);
00282 dkcMemoryStreamWrite(pms,&(p->mTemp),t);
00283
00284
00285 i++;
00286 }
00287 }
00288
00289 return edk_SUCCEEDED;
00290 BACK:
00291
00292 dkcMemoryStreamSeek(pms,old_mem_offset,edkcMemoryStreamSeekSet);
00293
00294 return edk_FAILED;
00295
00296
00297 }