ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitCommon/OptIO/src/rzipunzip.c
Revision: 1.8
Committed: Tue Sep 22 07:54:34 2009 UTC (15 years, 7 months ago) by loizides
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_032, Mit_031, Mit_025c_branch2, Mit_025c_branch1, Mit_030, Mit_029c, Mit_030_pre1, Mit_029a, Mit_029, Mit_029_pre1, Mit_028a, Mit_025c_branch0, Mit_028, Mit_027a, Mit_027, Mit_026, Mit_025e, Mit_025d, Mit_025c, Mit_025b, Mit_025a, Mit_025, Mit_025pre2, Mit_024b, Mit_025pre1, Mit_024a, Mit_024, Mit_023, Mit_022a, Mit_022, Mit_020d, TMit_020d, Mit_020c, Mit_021, Mit_021pre2, Mit_021pre1, Mit_020b, Mit_020a, Mit_020, Mit_020pre1, Mit_018, Mit_017, Mit_017pre3, Mit_017pre2, Mit_017pre1, V07-05-00, Mit_016, Mit_015b, Mit_015a, Mit_015, Mit_014e, Mit_014d, Mit_014c, Mit_014b, ConvRejection-10-06-09, Mit_014a, Mit_014, Mit_014pre3, Mit_014pre2, Mit_014pre1, Mit_013d, Mit_013c, Mit_013b, Mit_013a, Mit_013, Mit_013pre1, Mit_012i, Mit_012g, Mit_012f, Mit_012e, Mit_012d, Mit_012c, Mit_012b, Mit_012a, Mit_012, Mit_011a, Mit_008, HEAD
Branch point for: Mit_025c_branch
Changes since 1.7: +47 -24 lines
Log Message:
Improved compress/decompress to deal with larger buffer sizes.

File Contents

# User Rev Content
1 loizides 1.8 // $Id: rzipunzip.c,v 1.7 2009/09/21 19:30:00 loizides Exp $
2 loizides 1.1
3     #include "MitCommon/OptIO/src/rzipunzip.h"
4     #include "MitCommon/OptIO/src/zlib.h"
5     #include "MitCommon/OptIO/src/bzlib.h"
6     #include "MitCommon/OptIO/src/lzo/lzo1x.h"
7     #include "MitCommon/OptIO/src/rle.h"
8 loizides 1.2 #include "MitCommon/OptIO/src/LzmaEnc.h"
9     #include "MitCommon/OptIO/src/LzmaDec.h"
10 loizides 1.4 #include "MitCommon/OptIO/src/fpc.h"
11 loizides 1.1
12     #include <stdio.h>
13     #include <stdlib.h>
14     #include <string.h>
15    
16     #ifndef HDRSIZE
17     #define HDRSIZE 9
18     #else
19     #error "HDRSIZE already defined."
20     #endif
21    
22     #ifndef MYSIZE
23     #define MYSIZE 5*1024*1024
24     #else
25     #error "MYSIZE already defined."
26     #endif
27    
28     typedef unsigned char uch; /* code assumes unsigned bytes; these type- */
29    
30     extern int R__ZipMode;
31     char mymem[MYSIZE];
32     char *myptr = mymem;
33    
34 loizides 1.6 // the following will be set to one if code was activated
35     int activated = 0;
36    
37 loizides 1.1 // the following can be changed using the OptInt interface
38     double lzipfrac = 1;
39     double gzipfrac = 1;
40     double bzipfrac = 1;
41 loizides 1.2 double lzmafrac = 1;
42 loizides 1.1 int myverbose = 0;
43     int mystaticm = 0;
44    
45     //--------------------------------------------------------------------------------------------------
46     void *mymalloc(size_t size)
47     {
48     if(!mystaticm || size>MYSIZE)
49     return malloc(size);
50    
51     if(myptr-mymem>MYSIZE-size) {
52     myptr=mymem;
53     }
54    
55     void *v=(void*)myptr;
56     myptr+=size;
57     return v;
58     }
59    
60     //--------------------------------------------------------------------------------------------------
61 loizides 1.2 void mymfree(void *ptr)
62 loizides 1.1 {
63     if (mystaticm && (char*)ptr>=mymem && (char*)ptr<mymem+MYSIZE)
64     return;
65     free(ptr);
66     }
67    
68 loizides 1.7 //--------------------------------------------------------------------------------------------------
69 loizides 1.2 static void *SzAlloc(void *p, size_t size) { p = p; return mymalloc(size); }
70 loizides 1.7
71     //--------------------------------------------------------------------------------------------------
72 loizides 1.2 static void SzFree(void *p, void *address) { p = p; mymfree(address); }
73 loizides 1.7
74     //--------------------------------------------------------------------------------------------------
75 loizides 1.2 static ISzAlloc g_Alloc = { SzAlloc, SzFree };
76 loizides 1.7
77     //--------------------------------------------------------------------------------------------------
78 loizides 1.3 static void* my_balloc (void* opaque, int items, int size)
79     {
80     opaque = opaque;
81     return mymalloc(items*size);
82     }
83 loizides 1.7
84     //--------------------------------------------------------------------------------------------------
85 loizides 1.3 static void my_bfree (void* opaque, void* addr)
86     {
87     opaque = opaque;
88     mymfree(addr);
89     }
90 loizides 1.7
91     //--------------------------------------------------------------------------------------------------
92 loizides 1.3 static voidpf my_zalloc OF((voidpf opaque, unsigned items, unsigned size))
93     {
94     opaque = opaque;
95     return mymalloc(items*size);
96     }
97 loizides 1.7
98     //--------------------------------------------------------------------------------------------------
99 loizides 1.3 static void my_zfree OF((voidpf opaque, voidpf ptr))
100     {
101     opaque = opaque;
102     mymfree(ptr);
103     }
104    
105     //--------------------------------------------------------------------------------------------------
106     void delta_encode(char *buffer, int length)
107     {
108     char t = 0;
109     char original;
110     int i;
111     for (i=0; i < length; ++i) {
112     original = buffer[i];
113     buffer[i] -= t;
114     t = original;
115     }
116     }
117    
118 loizides 1.7 //--------------------------------------------------------------------------------------------------
119 loizides 1.3 void delta_decode(char *buffer, int length)
120     {
121     char t = 0;
122     int i;
123     for (i=0; i < length; ++i) {
124     buffer[i] += t;
125     t = buffer[i];
126     }
127     }
128    
129 loizides 1.1 //--------------------------------------------------------------------------------------------------
130 loizides 1.8 void R__myzip(int cxlevel, int *srcsize, char *src, int *tgtsize, char *tgt, int *irep, int la)
131 loizides 1.1 /* int cxlevel; compression level */
132     /* int *srcsize, *tgtsize, *irep; source and target sizes, replay */
133     /* char *tgt, *src; source and target buffers */
134     {
135     int err = 0;
136     int method = 0;
137     unsigned int in_size = 0;
138     unsigned int out_size = 0;
139    
140 loizides 1.8 int hsize = HDRSIZE;
141     if (la)
142     hsize += 2;
143    
144     if (*tgtsize <= hsize) {
145     printf("target buffer too small %d %d\n",*tgtsize, hsize);
146 loizides 1.1 return;
147     }
148 loizides 1.8
149     if ((la && *srcsize > 0xffffffff) || (!la && *srcsize > 0xffffff)) {
150     printf("source buffer too big %d",*srcsize);
151 loizides 1.1 return;
152     }
153    
154     *irep = 0;
155     in_size = (unsigned)(*srcsize); /* decompressed size */
156 loizides 1.8 char *tgtptr = tgt+hsize; /* compress data */
157 loizides 1.1
158 loizides 1.2 if (R__ZipMode == 99) { /*determine best of all methods*/
159 loizides 1.4 int cont = 1;
160     int msize = -1;
161     int zmode = -1;
162     int tgtlen = 2*in_size+64*1024;
163 loizides 1.1 char *mptr1 = mymalloc(tgtlen);
164     char *mptr2 = mymalloc(tgtlen);
165     char *mptr = 0;
166     char *mdum = 0;
167    
168     if (cont) {
169     zmode = 4;
170     msize = RLE_Compress(src, mptr1, in_size);
171     mptr = mptr1;
172     mdum = mptr2;
173     }
174    
175     if (cont && lzipfrac>0) {
176     err = lzo_init();
177     if ( err == LZO_E_OK) {
178     lzo_uint outlen = tgtlen;
179     char *lwmem = mymalloc(LZO1X_999_MEM_COMPRESS);
180     err = lzo1x_999_compress(src,in_size,mdum,&outlen,lwmem);
181     if (err == LZO_E_OK) {
182     if (outlen<lzipfrac*msize) {
183     msize = outlen;
184     zmode = 3;
185     char *tmp = mptr;
186     mptr = mdum;
187     mdum = tmp;
188     }
189     }
190 loizides 1.2 mymfree(lwmem);
191 loizides 1.1 }
192     }
193    
194     if (cont && gzipfrac>0) {
195 loizides 1.2 int outlen = *tgtsize;
196 loizides 1.1 z_stream stream;
197     stream.next_in = (Bytef*)src;
198     stream.avail_in = (uInt)(in_size);
199     stream.next_out = (Bytef*)(mdum);
200 loizides 1.2 stream.avail_out = (uInt)(outlen);
201 loizides 1.1 stream.zalloc = (alloc_func)0;
202     stream.zfree = (free_func)0;
203     stream.opaque = (voidpf)0;
204    
205     err = deflateInit(&stream, cxlevel);
206     if (err == Z_OK) {
207     err = deflate(&stream, Z_FINISH);
208     if (err == Z_STREAM_END) {
209     err = deflateEnd(&stream);
210     int outlen = stream.total_out;
211     if (outlen<gzipfrac*msize) {
212     msize = outlen;
213     zmode = 1;
214     char *tmp = mptr;
215     mptr = mdum;
216     mdum = tmp;
217     }
218     }
219     }
220     }
221    
222     if (cont && bzipfrac>0) {
223 loizides 1.2 int outlen = *tgtsize;
224 loizides 1.1 bz_stream stream;
225     stream.next_in = src;
226     stream.avail_in = (uInt)(in_size);
227     stream.next_out = mdum;
228 loizides 1.2 stream.avail_out = (uInt)(outlen);
229 loizides 1.1 stream.bzalloc = 0;
230     stream.bzfree = 0;
231     stream.opaque = 0;
232    
233     err = BZ2_bzCompressInit(&stream, 9, 0, 1);
234     if (err == BZ_OK) {
235     err = BZ2_bzCompress(&stream, BZ_FINISH);
236     if (err == BZ_STREAM_END) {
237     BZ2_bzCompressEnd(&stream);
238     }
239     int outlen = stream.total_out_lo32;
240     if (outlen<bzipfrac*msize) {
241     msize = outlen;
242     zmode = 2;
243     char *tmp = mptr;
244     mptr = mdum;
245     mdum = tmp;
246     }
247     }
248     }
249 loizides 1.2 if (cont && lzmafrac>0) {
250     CLzmaEncHandle enc = LzmaEnc_Create(&g_Alloc);
251     if (enc) {
252     CLzmaEncProps props;
253     LzmaEncProps_Init(&props);
254     props.level = cxlevel;
255 bendavid 1.5 props.dictSize = (1<<24);
256     props.lc = 0;
257     props.lp = 2;
258 loizides 1.2 SRes res = LzmaEnc_SetProps(enc, &props);
259     if (res == SZ_OK) {
260     SizeT outlen = *tgtsize;
261 loizides 1.3 res = LzmaEnc_MemEncode(enc, mdum, &outlen, src, in_size,
262 loizides 1.2 0, NULL, &g_Alloc, &g_Alloc);
263     if (res == SZ_OK) {
264     if (outlen<lzmafrac*msize) {
265     msize = outlen;
266     zmode = 5;
267     char *tmp = mptr;
268     mptr = mdum;
269     mdum = tmp;
270     }
271     }
272     }
273     }
274 loizides 1.3 LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
275 loizides 1.2 }
276 loizides 1.1
277 loizides 1.2 // determine best candidate
278 loizides 1.1 if (msize>=in_size) {
279     out_size = in_size;
280     memcpy(tgtptr,src,out_size);
281     tgt[0] = 'X'; /* signature xx */
282     tgt[1] = 'X';
283     method = 0;
284     } else {
285     switch (zmode) {
286     case 1:
287     tgt[0] = 'Z'; /* signature zlib */
288     tgt[1] = 'L';
289     method = Z_DEFLATED; //==8
290     break;
291     case 2:
292     tgt[0] = 'B'; /* signature bzlib */
293     tgt[1] = 'Z';
294     method = 2;
295     break;
296     case 3:
297     tgt[0] = 'L'; /* signature lzolib */
298     tgt[1] = 'O';
299     method = 19;
300     break;
301     case 4:
302     tgt[0] = 'R'; /* signature rlelib */
303     tgt[1] = 'E';
304     method = 4;
305 loizides 1.3 break;
306 loizides 1.2 case 5:
307     tgt[0] = 'L'; /* signature lzma */
308     tgt[1] = 'M';
309     method = 3;
310 loizides 1.1 break;
311     }
312     out_size = msize;
313     memcpy(tgtptr,mptr,out_size);
314     }
315 loizides 1.2 mymfree(mptr1);
316     mymfree(mptr2);
317     } else if (R__ZipMode == 5) { /*lzma*/
318     CLzmaEncHandle enc = LzmaEnc_Create(&g_Alloc);
319     if (enc == 0) {
320     printf("error %d - LzmaEnc_Create()\n", SZ_ERROR_MEM);
321     return;
322     }
323     CLzmaEncProps props;
324     LzmaEncProps_Init(&props);
325     props.level = cxlevel;
326 bendavid 1.5 props.dictSize = (1<<24);
327     props.lc = 0;
328     props.lp = 2;
329 loizides 1.2 SRes res = LzmaEnc_SetProps(enc, &props);
330     if (res != SZ_OK) {
331     printf("error %d - LzmaEnc_SetProps()\n", res);
332 loizides 1.3 LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
333 loizides 1.2 return;
334     }
335     res = LzmaEnc_MemEncode(enc, tgtptr, tgtsize, src, in_size,
336     0, NULL, &g_Alloc, &g_Alloc);
337     if (res != SZ_OK) {
338     printf("error %d - LzmaEnc_MemEncode", res);
339 loizides 1.3 LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
340 loizides 1.2 return;
341     }
342     LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
343     out_size = *tgtsize; /* compressed size */
344     if (out_size>=lzmafrac*in_size) {
345     out_size = in_size;
346     memcpy(tgtptr,src,out_size);
347     tgt[0] = 'X'; /* signature xx */
348     tgt[1] = 'X';
349     method = 0;
350     } else {
351     tgt[0] = 'L'; /* signature lzma */
352     tgt[1] = 'M';
353     method = 3;
354     }
355 loizides 1.1 } else if (R__ZipMode == 4) { /*rle*/
356     int tgtlen = 2*in_size+1;
357     char *lmem1 = mymalloc(tgtlen);
358    
359     out_size = RLE_Compress(src, lmem1, in_size);
360     if (out_size>=in_size) {
361     out_size = in_size;
362     memcpy(tgtptr,src,out_size);
363     tgt[0] = 'X'; /* signature xx */
364     tgt[1] = 'X';
365     method = 0;
366     } else {
367     memcpy(tgtptr,lmem1,out_size);
368     tgt[0] = 'R'; /* signature rlelib */
369     tgt[1] = 'E';
370     method = 4;
371     }
372 loizides 1.2 mymfree(lmem1);
373 loizides 1.1 } else if (R__ZipMode == 3) { /*lzo*/
374     err = lzo_init();
375     if ( err != LZO_E_OK) {
376     printf("error %d - lzo_init()\n", err);
377 loizides 1.2 return;
378 loizides 1.1 }
379    
380     lzo_uint tgtlen = 2*in_size+64*1024;
381     char *lmem1 = mymalloc(tgtlen);
382     char *lmem2 = 0;
383     if (cxlevel<=1) {
384     lmem2 = mymalloc(LZO1X_1_11_MEM_COMPRESS);
385     err = lzo1x_1_11_compress(src,in_size,lmem1,&tgtlen,lmem2);
386     method = 11;
387     } else if (cxlevel==2) {
388     lmem2 = mymalloc(LZO1X_1_12_MEM_COMPRESS);
389     err = lzo1x_1_12_compress(src,in_size,lmem1,&tgtlen,lmem2);
390     method = 12;
391     } else if (cxlevel<=5) {
392     lmem2 = mymalloc(LZO1X_1_15_MEM_COMPRESS);
393     err = lzo1x_1_15_compress(src,in_size,lmem1,&tgtlen,lmem2);
394     method = 15;
395     } else {
396     lmem2 = mymalloc(LZO1X_999_MEM_COMPRESS);
397     err = lzo1x_999_compress(src,in_size,lmem1,&tgtlen,lmem2);
398     method = 19;
399     }
400     if (err != LZO_E_OK) {
401 loizides 1.2 mymfree(lmem1);
402     mymfree(lmem2);
403 loizides 1.1 return;
404     }
405    
406     if (tgtlen>=lzipfrac*in_size) {
407     out_size = in_size;
408     memcpy(tgtptr,src,out_size);
409     tgt[0] = 'X'; /* signature xx */
410     tgt[1] = 'X';
411     method = 0;
412     } else {
413     out_size = tgtlen; /* compressed size */
414     memcpy(tgtptr,lmem1,out_size);
415     tgt[0] = 'L'; /* signature lzolib */
416     tgt[1] = 'O';
417     }
418 loizides 1.2 mymfree(lmem1);
419     mymfree(lmem2);
420 loizides 1.1 } else if (R__ZipMode == 2) { /*bzip*/
421     bz_stream stream;
422     stream.next_in = src;
423     stream.avail_in = (uInt)(in_size);
424     stream.next_out = tgtptr;
425     stream.avail_out = (uInt)(*tgtsize);
426     stream.bzalloc = 0;
427     stream.bzfree = 0;
428     stream.opaque = 0;
429    
430     err = BZ2_bzCompressInit(&stream, 9, 0, 1+(9-cxlevel)*25);
431     if (err != BZ_OK) {
432     printf("error %d in BZ2_bzCompressInit (bzlib)\n",err);
433     return;
434     }
435     err = BZ2_bzCompress(&stream, BZ_FINISH);
436     if (err != BZ_STREAM_END) {
437     BZ2_bzCompressEnd(&stream);
438     //printf("error %d in BZ2_bzCompress (bzlib) is not = %d\n",err,BZ_STREAM_END);
439     return;
440     }
441     err = BZ2_bzCompressEnd(&stream);
442    
443     out_size = stream.total_out_lo32; /* compressed size */
444     if (out_size>=bzipfrac*in_size) {
445     out_size = in_size;
446     memcpy(tgtptr,src,out_size);
447     tgt[0] = 'X'; /* signature xx */
448     tgt[1] = 'X';
449     method = 0;
450     } else {
451     tgt[0] = 'B'; /* signature bzlib */
452     tgt[1] = 'Z';
453     method = 2;
454     }
455     } else if (R__ZipMode == 1) { /*zip*/
456     z_stream stream;
457     stream.next_in = (Bytef*)src;
458     stream.avail_in = (uInt)(in_size);
459     stream.next_out = (Bytef*)(tgtptr);
460     stream.avail_out = (uInt)(*tgtsize);
461     stream.zalloc = (alloc_func)0;
462     stream.zfree = (free_func)0;
463     stream.opaque = (voidpf)0;
464    
465     err = deflateInit(&stream, cxlevel);
466     if (err != Z_OK) {
467     printf("error %d in deflateInit (zlib)\n",err);
468     return;
469     }
470     err = deflate(&stream, Z_FINISH);
471     if (err != Z_STREAM_END) {
472     deflateEnd(&stream);
473     //printf("error %d in deflate (zlib) is not = %d\n",err,Z_STREAM_END);
474     return;
475     }
476     err = deflateEnd(&stream);
477    
478     out_size = stream.total_out; /* compressed size */
479     if (out_size>=gzipfrac*in_size) {
480     out_size = in_size;
481     memcpy(tgtptr,src,out_size);
482     tgt[0] = 'X'; /* signature xx */
483     tgt[1] = 'X';
484     method = 0;
485     } else {
486     tgt[0] = 'Z'; /* signature zlib */
487     tgt[1] = 'L';
488     method = Z_DEFLATED;
489     }
490     } else if (R__ZipMode == 0) {
491     printf("error: Old zip method not supported in this patch.");
492     return;
493     }
494    
495     // fill rest of header
496     tgt[2] = (char)method;
497     tgt[3] = (char)(out_size & 0xff);
498     tgt[4] = (char)((out_size >> 8) & 0xff);
499     tgt[5] = (char)((out_size >> 16) & 0xff);
500 loizides 1.8 int off = 0;
501     if (la) {
502     tgt[6] = (char)((out_size >> 24) & 0xff);
503     tgt[10] = (char)((in_size >> 24) & 0xff);
504     off = 1;
505     }
506     tgt[6+off] = (char)(in_size & 0xff);
507     tgt[7+off] = (char)((in_size >> 8) & 0xff);
508     tgt[8+off] = (char)((in_size >> 16) & 0xff);
509    
510     *irep = out_size + hsize;
511 loizides 1.1
512     if (myverbose==1||myverbose>9) {
513 loizides 1.7 printf("R__myzip:: zm=%d m=%d cl=%d: %c%c compressed %lu bytes into %lu bytes -> %.3f%%\n",
514 loizides 1.1 R__ZipMode, method, cxlevel, tgt[0], tgt[1],
515     (unsigned long)in_size, (unsigned long)out_size, (double)out_size/in_size*100.);
516     }
517     }
518    
519     //--------------------------------------------------------------------------------------------------
520 loizides 1.7 void R__zip(int cxlevel, int *srcsize, char *src, int *tgtsize, char *tgt, int *irep)
521     {
522     // Overwrite ROOT R__zip.
523    
524 loizides 1.8 R__myzip(cxlevel, srcsize, src, tgtsize, tgt, irep, 0);
525 loizides 1.7 }
526    
527     //--------------------------------------------------------------------------------------------------
528 loizides 1.8 void R__myunzip(int *srcsize, uch *src, int *tgtsize, uch *tgt, int *irep, int la)
529 loizides 1.1 /* Input: scrsize - size of input buffer */
530     /* src - input buffer */
531     /* tgtsize - size of target buffer */
532     /* Output: tgt - target buffer (decompressed) */
533     /* irep - size of decompressed data */
534     /* 0 - if error */
535     {
536     unsigned int osize = 0;
537     unsigned int ibufcnt = 0, obufcnt = 0;
538 loizides 1.8 unsigned char *ibufptr = 0, *obufptr = 0;
539 loizides 1.1 *irep = 0L;
540    
541 loizides 1.8 int hsize = HDRSIZE;
542     if (la)
543     hsize += 2;
544    
545 loizides 1.1 /* C H E C K H E A D E R */
546 loizides 1.8 if (*srcsize < hsize) {
547     fprintf(stderr,"R__myunzip: too small source %d %d\n",*srcsize,hsize);
548 loizides 1.1 return;
549     }
550    
551     char method = src[2];
552 loizides 1.2 if (method!=0 && method!= 2 && method!= 3 && method!= 4 && method!=Z_DEFLATED &&
553     method!=11 && method!=12 && method!=15 && method!=19) {
554 loizides 1.7 fprintf(stderr,"R__myunzip: error in header -> unknown method %d\n", method);
555 loizides 1.1 return;
556     }
557    
558     if ((method==0 && (src[0] != 'X' || src[1] != 'X')) ||
559     (method==2 && (src[0] != 'B' || src[1] != 'Z')) ||
560 loizides 1.2 (method==3 && (src[0] != 'L' || src[1] != 'M')) ||
561 loizides 1.1 (method==4 && (src[0] != 'R' || src[1] != 'E')) ||
562     (method==Z_DEFLATED && ((src[0] != 'C' || src[1] != 'S') &&
563     (src[0] != 'Z' || src[1] != 'L'))) ||
564     ((method==11 || method==12 || method==15 || method==19) &&
565     (src[0] != 'L' || src[1] != 'O'))) {
566 loizides 1.7 fprintf(stderr,"R__myunzip: error in header -> m=%d with %c%c\n",
567 loizides 1.1 method, src[0], src[1]);
568     return;
569     }
570    
571 loizides 1.8 ibufptr = src + hsize;
572     if (la) {
573     ibufcnt = (unsigned int)src[3] | ((unsigned int)src[4] << 8) |
574     ((unsigned int)src[5] << 16) | ((unsigned int)src[6] << 24);
575     osize = (unsigned int)src[7] | ((unsigned int)src[8] << 8) |
576     ((unsigned int)src[9] << 16) | ((unsigned int)src[10] << 24);
577     } else {
578     ibufcnt = (unsigned int)src[3] | ((unsigned int)src[4] << 8) | ((unsigned int)src[5] << 16);
579     osize = (unsigned int)src[6] | ((unsigned int)src[7] << 8) | ((unsigned int)src[8] << 16);
580     }
581 loizides 1.1 obufptr = tgt;
582     obufcnt = *tgtsize;
583    
584     if (obufcnt < osize) {
585 loizides 1.8 fprintf(stderr,"R__myunzip: too small target %d %d\n",obufcnt,osize);
586 loizides 1.1 return;
587     }
588    
589 loizides 1.8 if (ibufcnt + hsize != *srcsize) {
590     fprintf(stderr,"R__myunzip: discrepancy in source length %d %d\n",ibufcnt + hsize,*srcsize);
591 loizides 1.1 return;
592     }
593    
594     if (myverbose==2 || myverbose>9) {
595 loizides 1.7 printf("R__myunzip:: zm=%d m=%d: %c%c uncompressed %lu bytes from %lu bytes (%.3f%%)\n",
596 loizides 1.1 R__ZipMode, method, src[0], src[1], osize, ibufcnt, (double)ibufcnt/osize*100.);
597     }
598    
599     if (method==0) { // apparently this is not reached since underlying ROOT code catches this
600     if (ibufcnt!=osize) {
601 loizides 1.7 fprintf(stderr,"R__myunzip: error in header -> input should be output %d!=%d\n",
602 loizides 1.1 ibufcnt, osize);
603     return;
604     }
605     memcpy(obufptr,ibufptr,osize);
606     *irep = obufcnt;
607     return;
608     }
609    
610     /* D E C O M P R E S S D A T A */
611 loizides 1.2
612     if (src[0] == 'L' && src[1] == 'M') { /* lzma format */
613     CLzmaEncHandle enc = LzmaEnc_Create(&g_Alloc);
614     if (enc == 0) {
615 loizides 1.4 printf("error %d - LzmaEnc_Create (lzma)\n", SZ_ERROR_MEM);
616 loizides 1.2 return;
617     }
618     CLzmaEncProps props;
619     LzmaEncProps_Init(&props);
620 bendavid 1.5 props.dictSize = (1<<24);
621     props.lc = 0;
622     props.lp = 2;
623 loizides 1.2 SRes res = LzmaEnc_SetProps(enc, &props);
624     if (res != SZ_OK) {
625 loizides 1.4 printf("error %d - LzmaEnc_SetProps (lzma)\n", res);
626 loizides 1.3 LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
627 loizides 1.2 return;
628     }
629     size_t hsize = LZMA_PROPS_SIZE;
630     char *hptr = mymalloc(hsize);
631     res = LzmaEnc_WriteProperties(enc, hptr, &hsize);
632     if (res != SZ_OK) {
633 loizides 1.4 printf("error %d - LzmaEnc_WriteProperties (lzma)\n", res);
634 loizides 1.3 mymfree(hptr);
635     LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
636 loizides 1.2 return;
637     }
638    
639     SizeT new_len = obufcnt;
640     ELzmaStatus status;
641     res = LzmaDecode(obufptr, &obufcnt, ibufptr, &new_len, hptr, hsize,
642     LZMA_FINISH_END, &status, &g_Alloc);
643 loizides 1.4 if (res!=SZ_OK) {
644 loizides 1.7 fprintf(stderr,"R__myunzip: error %d in LzmaDecode (lzolib)\n", res);
645 loizides 1.4 mymfree(hptr);
646     return;
647     }
648 loizides 1.2 mymfree(hptr);
649 loizides 1.3 LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
650 loizides 1.2 *irep = obufcnt;
651     } else if (src[0] == 'R' && src[1] == 'E') { /* rle format */
652 loizides 1.1 RLE_Uncompress(ibufptr, obufptr, ibufcnt);
653     *irep = obufcnt;
654     } else if (src[0] == 'L' && src[1] == 'O') { /* lolib format */
655    
656     int err = lzo_init();
657     if ( err != LZO_E_OK) {
658 loizides 1.7 fprintf(stderr,"R__myunzip: error %d in lzo_init (lzolib)\n",err);
659 loizides 1.1 return;
660     }
661     lzo_uint new_len = obufcnt;
662     err = lzo1x_decompress(ibufptr,ibufcnt,obufptr,&new_len, NULL);
663     if ((err != LZO_E_OK) || (new_len!=osize)) {
664 loizides 1.7 fprintf(stderr,"R__myunzip: error %d (%d,%d) in lzo1x_decompress (lzolib)\n",
665 loizides 1.1 err, new_len, osize);
666     return;
667     }
668     *irep = obufcnt;
669     } else if (src[0] == 'B' && src[1] == 'Z') { /* bzlib format */
670     bz_stream stream; /* decompression stream */
671     stream.next_in = ibufptr;
672     stream.avail_in = ibufcnt;
673     stream.next_out = obufptr;
674     stream.avail_out = obufcnt;
675 loizides 1.4 stream.bzalloc = my_balloc;
676     stream.bzfree = my_bfree;
677 loizides 1.1 stream.opaque = 0;
678    
679     int err = BZ2_bzDecompressInit(&stream,0,0);
680     if (err != BZ_OK) {
681 loizides 1.7 fprintf(stderr,"R__myunzip: error %d in BZ2_bzDecompressInit (bzlib)\n",err);
682 loizides 1.1 return;
683     }
684     err = BZ2_bzDecompress(&stream);
685     if (err != BZ_STREAM_END) {
686 loizides 1.7 fprintf(stderr,"R__myunzip: error %d inBZ2_bzDecompress (bzlib)\n",err);
687 loizides 1.1 BZ2_bzDecompressEnd(&stream);
688     return;
689     }
690     BZ2_bzDecompressEnd(&stream);
691     *irep = stream.total_out_lo32;
692     } else if (src[0] == 'Z' && src[1] == 'L') { /* zlib format */
693     z_stream stream; /* decompression stream */
694 loizides 1.8 stream.next_in = (Bytef*)(&src[hsize]);
695 loizides 1.1 stream.avail_in = (uInt)(*srcsize);
696     stream.next_out = (Bytef*)tgt;
697     stream.avail_out = (uInt)(*tgtsize);
698 loizides 1.4 stream.zalloc = my_zalloc;
699     stream.zfree = my_zfree;
700 loizides 1.1 stream.opaque = (voidpf)0;
701    
702     int err = inflateInit(&stream);
703     if (err != Z_OK) {
704 loizides 1.7 fprintf(stderr,"R__myunzip: error %d in inflateInit (zlib)\n",err);
705 loizides 1.1 return;
706     }
707     err = inflate(&stream, Z_FINISH);
708     if (err != Z_STREAM_END) {
709     inflateEnd(&stream);
710 loizides 1.7 fprintf(stderr,"R__myunzip: error %d in inflate (zlib)\n",err);
711 loizides 1.1 return;
712     }
713     inflateEnd(&stream);
714     *irep = stream.total_out;
715     } else if (src[0] == 'C' && src[1] == 'S') { /* old zlib format */
716     if (R__Inflate(&ibufptr, &ibufcnt, &obufptr, &obufcnt)) {
717 loizides 1.7 fprintf(stderr,"R__myunzip: error during decompression\n");
718 loizides 1.1 return;
719     }
720    
721     /* if (obufptr - tgt != osize) {
722     There are some rare cases when a few more bytes are required */
723     if (obufptr - tgt > *tgtsize) {
724 loizides 1.7 fprintf(stderr,"R__myunzip: discrepancy (%ld) with initial size: %ld, tgtsize=%d\n",
725 loizides 1.1 (long)(obufptr - tgt),osize,*tgtsize);
726     *irep = obufptr - tgt;
727     return;
728     }
729     *irep = osize;
730 loizides 1.3 return;
731 loizides 1.1 } else {
732 loizides 1.7 fprintf(stderr,"R__myunzip: Format not supported -> m=%d with %d%d", method, src[0], src[1]);
733 loizides 1.1 return;
734     }
735     }
736 loizides 1.7
737     //--------------------------------------------------------------------------------------------------
738     void R__unzip(int *srcsize, uch *src, int *tgtsize, uch *tgt, int *irep)
739     {
740     // Overwrite ROOT R__unzip.
741    
742 loizides 1.8 R__myunzip(srcsize, src, tgtsize, tgt, irep, 0);
743 loizides 1.7 }