00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <stdio.h>
00035 #include <string.h>
00036 #include <stdlib.h>
00037
00038 #ifdef USE_BZIP
00039 #include <bzlib.h>
00040 #else
00041 #include <zlib.h>
00042 #endif
00043
00044 #include "Compress.hpp"
00045 #include "MemStreamer.hpp"
00046 #include "Input.hpp"
00047 #include "Output.hpp"
00048
00049 #ifdef XMILL
00050 extern unsigned char zlib_compressidx;
00051 #endif
00052
00053
00054
00055 #ifdef ZALLOC_COUNT
00056 unsigned long allocsize=0;
00057 #endif
00058
00059
00060
00061 #ifdef USE_BZIP
00062 void *zalloc(void *opaque,int items,int size)
00063 #else
00064 void *zalloc(void *opaque,unsigned items,unsigned size)
00065 #endif
00066 {
00067 #ifdef ZALLOC_COUNT
00068 void *ptr=malloc(items*size+4);
00069 #else
00070 void *ptr=malloc(items*size);
00071 #endif
00072 if(ptr==NULL)
00073 ExitNoMem();
00074
00075
00076
00077 #ifdef ZALLOC_COUNT
00078 allocsize+=size;
00079 *(unsigned *)ptr=size;
00080 return (void *)(((char *)ptr)+4);
00081 #else
00082 return (void *)ptr;
00083 #endif
00084 }
00085
00086
00087
00088 void zfree(void *opaque,void *ptr)
00089 {
00090 #ifdef ZALLOC_COUNT
00091 allocsize-=*((unsigned *)ptr-1);
00092 free((char *)ptr-4);
00093 #else
00094 free((char *)ptr);
00095 #endif
00096 }
00097
00098
00099
00100
00101
00102
00103 #ifdef XMILL
00104
00105 Compressor::Compressor(Output *myoutput)
00106
00107 {
00108 #ifdef USE_BZIP
00109 state.bzalloc=zalloc;
00110 state.bzfree=zfree;
00111 #else
00112 state.zalloc=zalloc;
00113 state.zfree=zfree;
00114 #endif
00115
00116 isinitialized=0;
00117
00118 output=myoutput;
00119 };
00120
00121 Compressor::~Compressor()
00122
00123 {
00124 if(isinitialized)
00125
00126 {
00127 #ifdef USE_BZIP
00128 bzCompressEnd(&state);
00129 #else
00130 deflateEnd(&state);
00131 #endif
00132
00133
00134 isinitialized=0;
00135 }
00136 }
00137
00138 void Compressor::CompressMemStream(MemStreamer *memstream)
00139
00140
00141 {
00142 MemStreamBlock *curblock=memstream->GetFirstBlock();
00143 char first=1;
00144 int saveavail;
00145
00146
00147 if(memstream->GetSize()==0)
00148 return;
00149
00150 #ifdef USE_BZIP
00151 state.next_out=(char *)output->GetBufPtr((int *)&state.avail_out);
00152 state.next_in=(char *)curblock->data;
00153 #else
00154 state.next_out=(unsigned char *)output->GetBufPtr((int *)&state.avail_out);
00155 state.next_in=(unsigned char *)curblock->data;
00156 #endif
00157
00158
00159 if(state.avail_out==0)
00160 {
00161
00162 output->Flush();
00163
00164
00165 #ifdef USE_BZIP
00166 state.next_out=(char *)output->GetBufPtr((int *)&state.avail_out);
00167 #else
00168 state.next_out=(unsigned char *)output->GetBufPtr((int *)&state.avail_out);
00169 #endif
00170 }
00171
00172
00173
00174
00175 if(isinitialized==0)
00176 {
00177 #ifdef USE_BZIP
00178 if(bzCompressInit(&state,7,0,0)!=BZ_OK)
00179 #else
00180 if(deflateInit(&state,zlib_compressidx)!=Z_OK)
00181 #endif
00182 {
00183 Error("Error while compressing container!");
00184 Exit();
00185 }
00186 state.total_out=0;
00187 state.total_in=0;
00188
00189 isinitialized=1;
00190 }
00191
00192 do
00193 {
00194
00195 #ifdef USE_BZIP
00196 state.next_in=(char *)curblock->data;
00197 #else
00198 state.next_in=(unsigned char *)curblock->data;
00199 #endif
00200 state.avail_in=curblock->cursize;
00201
00202
00203 while(state.avail_in>0)
00204 {
00205 saveavail=state.avail_out;
00206
00207 #ifdef USE_BZIP
00208 if(bzCompress(&state,BZ_RUN)!=BZ_RUN_OK)
00209 #else
00210 if(deflate(&state,Z_NO_FLUSH)!=Z_OK)
00211 #endif
00212 {
00213 Error("Error while compressing container!");
00214 Exit();
00215 }
00216
00217
00218
00219 output->SaveBytes(saveavail-state.avail_out);
00220
00221 if((state.avail_in==0)&&(state.avail_out>0))
00222
00223 break;
00224
00225
00226 output->Flush();
00227
00228
00229 #ifdef USE_BZIP
00230 state.next_out=(char *)output->GetBufPtr((int *)&state.avail_out);
00231 #else
00232 state.next_out=(unsigned char *)output->GetBufPtr((int *)&state.avail_out);
00233 #endif
00234 }
00235
00236
00237 curblock=curblock->next;
00238 }
00239 while(curblock!=NULL);
00240 }
00241
00242 void Compressor::CompressData(unsigned char *ptr,unsigned len)
00243
00244 {
00245 int saveavail;
00246
00247
00248 #ifdef USE_BZIP
00249 state.next_out=output->GetBufPtr((int *)&state.avail_out);
00250 state.next_in=(char *)ptr;
00251 #else
00252 state.next_out=(unsigned char *)output->GetBufPtr((int *)&state.avail_out);
00253 state.next_in=ptr;
00254 #endif
00255
00256 state.avail_in=len;
00257
00258
00259 if(isinitialized==0)
00260 {
00261 #ifdef USE_BZIP
00262 if(bzCompressInit(&state,7,0,0)!=BZ_OK)
00263 #else
00264 if(deflateInit(&state,zlib_compressidx)!=Z_OK)
00265 #endif
00266 {
00267 Error("Error while compressing container!");
00268 Exit();
00269 }
00270 state.total_out=0;
00271 state.total_in=0;
00272 isinitialized=1;
00273 }
00274
00275 do
00276 {
00277 saveavail=state.avail_out;
00278
00279
00280 #ifdef USE_BZIP
00281 if(bzCompress(&state,BZ_RUN)!=BZ_RUN_OK)
00282 #else
00283 if(deflate(&state,Z_NO_FLUSH)!=Z_OK)
00284 #endif
00285 {
00286 Error("Error while compressing container!");
00287 Exit();
00288 }
00289 output->SaveBytes(saveavail-state.avail_out);
00290
00291
00292
00293 if((state.avail_in==0)&&(state.avail_out>0))
00294
00295 break;
00296
00297
00298 output->Flush();
00299
00300
00301 #ifdef USE_BZIP
00302 state.next_out=output->GetBufPtr((int *)&state.avail_out);
00303 #else
00304 state.next_out=(unsigned char *)output->GetBufPtr((int *)&state.avail_out);
00305 #endif
00306 }
00307 while(1);
00308 }
00309
00310 void Compressor::FinishCompress(unsigned long *uncompressedsize,unsigned long *compressedsize)
00311
00312
00313 {
00314 char err;
00315 int saveavail;
00316
00317 do
00318 {
00319
00320 #ifdef USE_BZIP
00321 state.next_out=output->GetBufPtr((int *)&state.avail_out);
00322 #else
00323 state.next_out=(unsigned char *)output->GetBufPtr((int *)&state.avail_out);
00324 #endif
00325
00326 saveavail=state.avail_out;
00327
00328 #ifdef USE_BZIP
00329 err=bzCompress(&state,BZ_FINISH);
00330 #else
00331 err=deflate(&state,Z_FINISH);
00332 #endif
00333
00334 output->SaveBytes(saveavail-state.avail_out);
00335
00336 #ifdef USE_BZIP
00337 if(err==BZ_STREAM_END)
00338 break;
00339 if(err!=BZ_FINISH_OK)
00340 #else
00341 if(err==Z_STREAM_END)
00342 break;
00343 if(err!=Z_OK)
00344 #endif
00345 {
00346 Error("Error while compressing container!");
00347 Exit();
00348 }
00349
00350
00351 output->Flush();
00352 }
00353 while(1);
00354
00355
00356 if(uncompressedsize!=NULL) *uncompressedsize =state.total_in;
00357 if(compressedsize!=NULL) *compressedsize =state.total_out;
00358
00359 state.total_out=0;
00360 state.total_in=0;
00361
00362
00363 #ifdef USE_BZIP
00364 if(bzCompressEnd(&state)!=BZ_OK)
00365 #else
00366 if(deflateReset(&state)!=Z_OK)
00367 #endif
00368 {
00369 Error("Error while compressing container!");
00370 Exit();
00371 }
00372 #ifdef USE_BZIP
00373
00374 isinitialized=0;
00375 #endif
00376 }
00377
00378 #endif // XMILL
00379
00380
00381
00382
00383
00384
00385 #ifdef XDEMILL
00386
00387 char Uncompressor::Uncompress(Input *input,unsigned char *dataptr,unsigned long *len)
00388
00389
00390
00391
00392
00393
00394 {
00395
00396 if(isinitialized==0)
00397 {
00398 #ifdef USE_BZIP
00399 state.bzalloc=zalloc;
00400 state.bzfree=zfree;
00401 #else
00402 state.zalloc=zalloc;
00403 state.zfree=zfree;
00404 #endif
00405
00406 #ifdef USE_BZIP
00407 if(bzDecompressInit(&state,0,0)!=BZ_OK)
00408 #else
00409 if(inflateInit(&state)!=Z_OK)
00410 #endif
00411 {
00412 Error("Error while compressing container!");
00413 Exit();
00414 }
00415
00416 isinitialized=1;
00417 }
00418
00419 int save_in;
00420
00421 #ifdef USE_BZIP
00422 state.next_out=(char *)dataptr;
00423 #else
00424 state.next_out=(unsigned char *)dataptr;
00425 #endif
00426
00427
00428 state.avail_out=*len;
00429
00430
00431 state.avail_in=input->GetCurBlockPtr((char **)&(state.next_in));
00432
00433 do
00434 {
00435
00436
00437
00438 save_in=state.avail_in;
00439
00440
00441 #ifdef USE_BZIP
00442 switch(bzDecompress(&state))
00443 #else
00444 switch(inflate(&state,Z_NO_FLUSH))
00445 #endif
00446 {
00447
00448 #ifdef USE_BZIP
00449 case BZ_STREAM_END:
00450 #else
00451 case Z_STREAM_END:
00452 #endif
00453
00454 input->SkipData(save_in-state.avail_in);
00455
00456
00457 *len=state.total_out;
00458
00459
00460 #ifdef USE_BZIP
00461 if(bzDecompressEnd(&state)!=BZ_OK)
00462 #else
00463 if(inflateReset(&state)!=Z_OK)
00464 #endif
00465 {
00466 Error("Error while compressing container!");
00467 Exit();
00468 }
00469 #ifdef USE_BZIP
00470
00471 isinitialized=0;
00472 #endif
00473 return 0;
00474
00475
00476 #ifdef USE_BZIP
00477 case BZ_OK:
00478 #else
00479 case Z_OK:
00480 #endif
00481
00482
00483 break;
00484
00485 default:
00486
00487 Error("Error while uncompressing container!");
00488 Exit();
00489 }
00490
00491
00492 input->SkipData(save_in-state.avail_in);
00493
00494 if(state.avail_out==0)
00495 return 1;
00496
00497
00498
00499
00500
00501 input->RefillAndGetCurBlockPtr((char **)&(state.next_in),(int *)&(state.avail_in));
00502 }
00503 while(1);
00504 }
00505
00506 #endif // XDEMILL