00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "zlib.h"
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 local int R__mem_read OF((char *buf, unsigned size));
00082 local void R__flush_outbuf OF((unsigned w, unsigned size));
00083
00084
00085
00086
00087
00088 local FILE *zfile;
00089
00090 local unsigned short bi_buf;
00091
00092
00093
00094
00095 #define Buf_size (8 * 2*sizeof(char))
00096
00097
00098
00099
00100 local int bi_valid;
00101
00102
00103
00104
00105 local char *in_buf, *out_buf;
00106
00107
00108
00109
00110 local unsigned in_offset, out_offset;
00111
00112
00113
00114
00115 local unsigned in_size, out_size;
00116
00117
00118 int (*R__read_buf) OF((char *buf, unsigned size)) = R__mem_read;
00119
00120
00121 #ifdef DEBUG
00122 ulg R__bits_sent;
00123 #endif
00124
00125
00126 #define PUTSHORT(w) \
00127 { if (out_offset < out_size-1) { \
00128 out_buf[out_offset++] = (char) ((w) & 0xff); \
00129 out_buf[out_offset++] = (char) ((ush)(w) >> 8); \
00130 } else { \
00131 R__flush_outbuf((w),2); \
00132 } \
00133 }
00134
00135 #define PUTBYTE(b) \
00136 { if (out_offset < out_size) { \
00137 out_buf[out_offset++] = (char) (b); \
00138 } else { \
00139 R__flush_outbuf((b),1); \
00140 } \
00141 }
00142
00143
00144
00145
00146
00147
00148 int R__ZipMode = 1;
00149
00150
00151
00152
00153 local int R__mem_read OF((char *b, unsigned bsize));
00154 local void R__flush_outbuf OF((unsigned w, unsigned bytes));
00155
00156
00157
00158
00159 void R__SetZipMode(int mode)
00160 {
00161 R__ZipMode = mode;
00162 }
00163
00164
00165
00166
00167 void R__bi_init (FILE *zipfile)
00168
00169 {
00170 zfile = zipfile;
00171 bi_buf = 0;
00172 bi_valid = 0;
00173 #ifdef DEBUG
00174 R__bits_sent = 0L;
00175 #endif
00176 }
00177
00178
00179
00180
00181
00182 void R__send_bits(int value, int length)
00183
00184
00185 {
00186 #ifdef DEBUG
00187 Tracevv((stderr," l %2d v %4x ", length, value));
00188 Assert(length > 0 && length <= 15, "invalid length");
00189 R__bits_sent += (ulg)length;
00190 #endif
00191
00192
00193
00194
00195 if (bi_valid > (int)Buf_size - length) {
00196 bi_buf |= (value << bi_valid);
00197 PUTSHORT(bi_buf);
00198 bi_buf = (ush)value >> (Buf_size - bi_valid);
00199 bi_valid += length - Buf_size;
00200 } else {
00201 bi_buf |= value << bi_valid;
00202 bi_valid += length;
00203 }
00204 }
00205
00206
00207
00208
00209
00210
00211 unsigned R__bi_reverse(unsigned code, int len)
00212
00213
00214 {
00215 register unsigned res = 0;
00216 do {
00217 res |= code & 1;
00218 code >>= 1, res <<= 1;
00219 } while (--len > 0);
00220 return res >> 1;
00221 }
00222
00223
00224
00225
00226 local void R__flush_outbuf(unsigned w, unsigned bytes)
00227
00228
00229 {
00230 R__error("output buffer too small for in-memory compression");
00231
00232
00233 out_offset = 0;
00234 if (bytes == 2) {
00235 PUTSHORT(w);
00236 } else if (bytes == 1) {
00237 out_buf[out_offset++] = (char) (w & 0xff);
00238 }
00239 }
00240
00241
00242
00243
00244 void R__bi_windup()
00245 {
00246 if (bi_valid > 8) {
00247 PUTSHORT(bi_buf);
00248 } else if (bi_valid > 0) {
00249 PUTBYTE(bi_buf);
00250 }
00251 if (zfile != (FILE *) NULL) {
00252 R__flush_outbuf(0, 0);
00253 }
00254 bi_buf = 0;
00255 bi_valid = 0;
00256 #ifdef DEBUG
00257 R__bits_sent = (R__bits_sent+7) & ~7;
00258 #endif
00259 }
00260
00261
00262
00263
00264
00265 void R__copy_block(char far *buf, unsigned len, int header)
00266
00267
00268
00269 {
00270 R__bi_windup();
00271
00272 if (header) {
00273 PUTSHORT((ush)len);
00274 PUTSHORT((ush)~len);
00275 #ifdef DEBUG
00276 R__bits_sent += 2*16;
00277 #endif
00278 }
00279 if (out_offset + len > out_size) {
00280 R__error("output buffer too small for in-memory compression");
00281 if (verbose) fprintf(stderr, "R__zip: out_offset=%d, len=%d, out_size=%d\n",out_offset,len,out_size);
00282 } else {
00283 memcpy(out_buf + out_offset, buf, len);
00284 out_offset += len;
00285 }
00286 #ifdef DEBUG
00287 R__bits_sent += (ulg)len<<3;
00288 #endif
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298 int R__seekable()
00299 {
00300 #if 0
00301 return (zfile == NULL ||
00302 (fseek(zfile, -1L, SEEK_CUR) == 0 &&
00303 fseek(zfile, 1L, SEEK_CUR) == 0));
00304 #endif
00305
00306 return (0);
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 ulg R__memcompress(char *tgt, ulg tgtsize, char *src, ulg srcsize)
00322
00323
00324 {
00325 ush att = (ush)UNKNOWN;
00326 ush flags = 0;
00327 ulg crc = 0;
00328 int method = Z_DEFLATED;
00329
00330 if (tgtsize <= 6L) R__error("target buffer too small");
00331 #if 0
00332 crc = updcrc((char *)NULL, 0);
00333 crc = updcrc(src, (extent) srcsize);
00334 #endif
00335 R__read_buf = R__mem_read;
00336 in_buf = src;
00337 in_size = (unsigned)srcsize;
00338 in_offset = 0;
00339
00340 out_buf = tgt;
00341 out_size = (unsigned)tgtsize;
00342 out_offset = 2 + 4;
00343 R__window_size = 0L;
00344
00345 R__bi_init((FILE *)NULL);
00346 R__ct_init(&att, &method);
00347 R__lm_init((level != 0 ? level : 1), &flags);
00348 R__Deflate();
00349 R__window_size = 0L;
00350
00351
00352 tgt[0] = (char)(method & 0xff);
00353 tgt[1] = (char)((method >> 8) & 0xff);
00354 tgt[2] = (char)(crc & 0xff);
00355 tgt[3] = (char)((crc >> 8) & 0xff);
00356 tgt[4] = (char)((crc >> 16) & 0xff);
00357 tgt[5] = (char)((crc >> 24) & 0xff);
00358
00359 return (ulg)out_offset;
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 local int R__mem_read(char *b, unsigned bsize)
00372 {
00373 if (in_offset < in_size) {
00374 ulg block_size = in_size - in_offset;
00375 if (block_size > (ulg)bsize) block_size = (ulg)bsize;
00376 memcpy(b, in_buf + in_offset, (unsigned)block_size);
00377 in_offset += (unsigned)block_size;
00378 return (int)block_size;
00379 } else {
00380 return 0;
00381 }
00382 }
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 #define HDRSIZE 9
00403 static int error_flag;
00404
00405 void R__zip(int cxlevel, int *srcsize, char *src, int *tgtsize, char *tgt, int *irep)
00406
00407
00408
00409
00410 {
00411 int err;
00412 int method = Z_DEFLATED;
00413
00414 if (R__ZipMode != 0) {
00415 z_stream stream;
00416 *irep = 0;
00417
00418 error_flag = 0;
00419 if (*tgtsize <= HDRSIZE) R__error("target buffer too small");
00420 if (error_flag != 0) return;
00421 if (*srcsize > 0xffffff) R__error("source buffer too big");
00422 if (error_flag != 0) return;
00423
00424
00425 stream.next_in = (Bytef*)src;
00426 stream.avail_in = (uInt)(*srcsize);
00427
00428 stream.next_out = (Bytef*)(&tgt[HDRSIZE]);
00429 stream.avail_out = (uInt)(*tgtsize);
00430
00431 stream.zalloc = (alloc_func)0;
00432 stream.zfree = (free_func)0;
00433 stream.opaque = (voidpf)0;
00434
00435 err = deflateInit(&stream, cxlevel);
00436 if (err != Z_OK) {
00437 printf("error %d in deflateInit (zlib)\n",err);
00438 return;
00439 }
00440
00441 err = deflate(&stream, Z_FINISH);
00442 if (err != Z_STREAM_END) {
00443 deflateEnd(&stream);
00444
00445
00446
00447
00448 return;
00449 }
00450
00451 err = deflateEnd(&stream);
00452
00453 tgt[0] = 'Z';
00454 tgt[1] = 'L';
00455 tgt[2] = (char) method;
00456
00457 in_size = (unsigned) (*srcsize);
00458 out_size = stream.total_out;
00459 tgt[3] = (char)(out_size & 0xff);
00460 tgt[4] = (char)((out_size >> 8) & 0xff);
00461 tgt[5] = (char)((out_size >> 16) & 0xff);
00462
00463 tgt[6] = (char)(in_size & 0xff);
00464 tgt[7] = (char)((in_size >> 8) & 0xff);
00465 tgt[8] = (char)((in_size >> 16) & 0xff);
00466
00467 *irep = stream.total_out + HDRSIZE;
00468 } else {
00469 ush att = (ush)UNKNOWN;
00470 ush flags = 0;
00471 level = cxlevel;
00472
00473 *irep = 0;
00474 error_flag = 0;
00475 if (*tgtsize <= HDRSIZE) R__error("target buffer too small");
00476 if (error_flag != 0) return;
00477 if (*srcsize > 0xffffff) R__error("source buffer too big");
00478 if (error_flag != 0) return;
00479
00480 R__read_buf = R__mem_read;
00481 in_buf = src;
00482 in_size = (unsigned) (*srcsize);
00483 in_offset = 0;
00484
00485 out_buf = tgt;
00486 out_size = (unsigned) (*tgtsize);
00487 out_offset = HDRSIZE;
00488 R__window_size = 0L;
00489
00490 R__bi_init((FILE *)NULL);
00491 if (error_flag != 0) return;
00492 R__ct_init(&att, &method);
00493 if (error_flag != 0) return;
00494 R__lm_init(level, &flags);
00495 if (error_flag != 0) return;
00496 R__Deflate();
00497 if (error_flag != 0) return;
00498
00499 tgt[0] = 'C';
00500 tgt[1] = 'S';
00501 tgt[2] = (char) method;
00502
00503 out_size = out_offset - HDRSIZE;
00504 tgt[3] = (char)(out_size & 0xff);
00505 tgt[4] = (char)((out_size >> 8) & 0xff);
00506 tgt[5] = (char)((out_size >> 16) & 0xff);
00507
00508 tgt[6] = (char)(in_size & 0xff);
00509 tgt[7] = (char)((in_size >> 8) & 0xff);
00510 tgt[8] = (char)((in_size >> 16) & 0xff);
00511
00512 *irep = out_offset;
00513 return;
00514 }
00515 }
00516
00517 void R__error(char *msg)
00518 {
00519 if (verbose) fprintf(stderr,"R__zip: %s\n",msg);
00520 error_flag = 1;
00521 }
00522