Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
Bits.c
Go to the documentation of this file.
1
2/**
3 *
4 * Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
5 * Kai Uwe Rommel and Igor Mandrichenko.
6 * For conditions of distribution and use, see copyright notice in zlib.h
7 *
8 * Changed for ROOT. Functions names have a R__ prepended to differentiate
9 * them from function names in later versions of zlib.
10 */
11
12#include "Bits.h"
13
14#include "zlib.h"
15
16#include <stdio.h>
17#include <assert.h>
18
19/*
20 * bits.c by Jean-loup Gailly and Kai Uwe Rommel.
21 *
22 * This is a new version of im_bits.c originally written by Richard B. Wales
23 *
24 * PURPOSE
25 *
26 * Output variable-length bit strings. Compression can be done
27 * to a file or to memory.
28 *
29 * DISCUSSION
30 *
31 * The PKZIP "deflate" file format interprets compressed file data
32 * as a sequence of bits. Multi-bit strings in the file may cross
33 * byte boundaries without restriction.
34 *
35 * The first bit of each byte is the low-order bit.
36 *
37 * The routines in this file allow a variable-length bit value to
38 * be output right-to-left (useful for literal values). For
39 * left-to-right output (useful for code strings from the tree routines),
40 * the bits must have been reversed first with R__bi_reverse().
41 *
42 * For in-memory compression, the compressed bit stream goes directly
43 * into the requested output buffer. The input data is read in blocks
44 * by the R__mem_read() function. The buffer is limited to 64K on 16 bit
45 * machines.
46 *
47 * INTERFACE
48 *
49 * void R__bi_init (bits_internal_state *state)
50 * Initialize the bit string routines.
51 *
52 * void R__send_bits (int value, int length)
53 * Write out a bit string, taking the source bits right to
54 * left.
55 *
56 * int R__bi_reverse (int value, int length)
57 * Reverse the bits of a bit string, taking the source bits left to
58 * right and emitting them right to left.
59 *
60 * void R__bi_windup (void)
61 * Write out any remaining bits in an incomplete byte.
62 *
63 * void R__copy_block(char far *buf, unsigned len, int header)
64 * Copy a stored block to the zip file, storing first the length and
65 * its one's complement if requested.
66 *
67 * int R__seekable(void)
68 * Return true if the zip file can be seeked.
69 *
70 * ulg R__memcompress (char *tgt, ulg tgtsize, char *src, ulg srcsize);
71 * Compress the source buffer src into the target buffer tgt.
72 */
73
74
75// Global value of the compression level for the old compression algorithm.
76// NOTE: Not thread-safe.
78
79/* ===========================================================================
80 * Prototypes for local functions
81 */
82local void R__flush_outbuf OF((bits_internal_state *state,unsigned w, unsigned size));
83
84
85/* ===========================================================================
86 * Local data used by the "bit string" routines.
87 */
88/* Number of bits used within bi_buf. (bi_buf might be implemented on
89 * more than 16 bits on some systems.)
90 */
91#define Buf_size (8 * 2*sizeof(char))
92
93/* Output a 16 bit value to the bit stream, lower (oldest) byte first */
94#define PUTSHORT(w) \
95{ if (state->out_offset < state->out_size-1) { \
96 state->out_buf[state->out_offset++] = (char) ((w) & 0xff); \
97 state->out_buf[state->out_offset++] = (char) ((ush)(w) >> 8); \
98 } else { \
99 R__flush_outbuf(state,(w),2); \
100 } \
101}
102
103#define PUTBYTE(b) \
104{ if (state->out_offset < state->out_size) { \
105 state->out_buf[state->out_offset++] = (char) (b); \
106 } else { \
107 R__flush_outbuf(state,(b),1); \
108 } \
109}
110
111
112/* ===========================================================================
113 * Prototypes for local functions
114 */
115local void R__flush_outbuf OF((bits_internal_state *state, unsigned w, unsigned bytes));
116
117
118/*
119 * Simple error-printing.
120 *
121 * Note that gBitsVerbose defaults to 0 and is a compilation-time change one
122 * must do to get an error message back.
123 */
124static int gBitsVerbose = 0;
125void R__error(const char *msg)
126{
127 if (gBitsVerbose) fprintf(stderr,"R__zip: %s\n",msg);
128}
129
130
131/* ===========================================================================
132 * Initialize the bit string routines.
133 */
135 /* FILE *zipfile; output zip file, NULL for in-memory compression */
136{
137 state->bi_buf = 0;
138 state->bi_valid = 0;
139 state->error_flag = 0;
140#ifdef DEBUG
141 state->R__bits_sent = 0L;
142#endif
143 return 0;
144}
145
146
147/* ===========================================================================
148 * Send a value on a given number of bits.
149 * IN assertion: length <= 16 and value fits in length bits.
150 */
151void R__send_bits(bits_internal_state *state, int value, int length)
152 /* int value; value to send */
153 /* int length; number of bits */
154{
155#ifdef DEBUG
156 Tracevv((stderr," l %2d v %4x ", length, value));
157 Assert(length > 0 && length <= 15, "invalid length");
158 state->R__bits_sent += (ulg)length;
159#endif
160 /* If not enough room in bi_buf, use (valid) bits from bi_buf and
161 * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
162 * unused bits in value.
163 */
164 if (state->bi_valid > (int)Buf_size - length) {
165 state->bi_buf |= (value << state->bi_valid);
166 PUTSHORT(state->bi_buf);
167 state->bi_buf = (ush)value >> (Buf_size - state->bi_valid);
168 state->bi_valid += length - Buf_size;
169 } else {
170 state->bi_buf |= value << state->bi_valid;
171 state->bi_valid += length;
172 }
173}
174
175
176/* ===========================================================================
177 * Reverse the first len bits of a code, using straightforward code (a faster
178 * method would use a table)
179 * IN assertion: 1 <= len <= 15
180 */
181unsigned R__bi_reverse(unsigned code, int len)
182 /* unsigned code; the value to invert */
183 /* int len; its bit length */
184{
185 register unsigned res = 0;
186 do {
187 res |= code & 1;
188 code >>= 1, res <<= 1;
189 } while (--len > 0);
190 return res >> 1;
191}
192
193
194/* ===========================================================================
195 * Flush the current output buffer.
196 */
197local void R__flush_outbuf(bits_internal_state *state, unsigned w, unsigned bytes)
198 /* unsigned w; value to flush */
199 /* unsigned bytes; number of bytes to flush (0, 1 or 2) */
200{
201 R__error("output buffer too small for in-memory compression");
202 state->error_flag = 1;
203
204 /* Encrypt and write the output buffer: */
205 state->out_offset = 0;
206 if (bytes == 2) {
207 PUTSHORT(w);
208 } else if (bytes == 1) {
209 state->out_buf[state->out_offset++] = (char) (w & 0xff);
210 }
211}
212
213
214/* ===========================================================================
215 * Write out any remaining bits in an incomplete byte.
216 */
218{
219 if (state->bi_valid > 8) {
220 PUTSHORT(state->bi_buf);
221 } else if (state->bi_valid > 0) {
222 PUTBYTE(state->bi_buf);
223 }
224 state->bi_buf = 0;
225 state->bi_valid = 0;
226#ifdef DEBUG
227 state->R__bits_sent = (state->R__bits_sent+7) & ~7;
228#endif
229}
230
231
232/* ===========================================================================
233 * Copy a stored block to the zip file, storing first the length and its
234 * one's complement if requested.
235 */
236void R__copy_block(bits_internal_state *state, char far *buf, unsigned len, int header)
237 /* char far *buf; the input data */
238 /* unsigned len; its length */
239 /* int header; true if block header must be written */
240{
241 R__bi_windup(state); /* align on byte boundary */
242
243 if (header) {
244 PUTSHORT((ush)len);
245 PUTSHORT((ush)~len);
246#ifdef DEBUG
247 R__bits_sent += 2*16;
248#endif
249 }
250 if (state->out_offset + len > state->out_size) {
251 R__error("output buffer too small for in-memory compression");
252 if (gBitsVerbose) fprintf(stderr, "R__zip: out_offset=%d, len=%d, out_size=%d\n",state->out_offset,len,state->out_size);
253 state->error_flag = 1;
254 } else {
255 memcpy(state->out_buf + state->out_offset, buf, len);
256 state->out_offset += len;
257 }
258#ifdef DEBUG
259 state->R__bits_sent += (ulg)len<<3;
260#endif
261}
262
263
264/* ===========================================================================
265 * Return true if the zip file can be seeked. This is used to check if
266 * the local header can be re-rewritten. This function always returns
267 * true for in-memory compression.
268 * IN assertion: the local header has already been written (ftell() > 0).
269 */
271{
272#if 0
273 return (zfile == NULL ||
274 (fseek(zfile, -1L, SEEK_CUR) == 0 &&
275 fseek(zfile, 1L, SEEK_CUR) == 0));
276#endif
277
278 return (0);
279}
280
281
282/* ===========================================================================
283 * In-memory compression. This version can be used only if the entire input
284 * fits in one memory buffer. The compression is then done in a single
285 * call of R__memcompress(). (An extension to allow repeated calls would be
286 * possible but is not needed here.)
287 * The first two bytes of the compressed output are set to a short with the
288 * method used (DEFLATE or STORE). The following four bytes contain the CRC.
289 * The values are stored in little-endian order on all machines.
290 * This function returns the byte size of the compressed output, including
291 * the first six bytes (method and crc).
292 */
293
294ulg R__memcompress(char *tgt, ulg tgtsize, const char *src, ulg srcsize)
295/* char *tgt, *src; target and source buffers */
296/* ulg tgtsize, srcsize; target and source sizes */
297{
298 ush att = (ush)UNKNOWN;
299 ush flags = 0;
300 ulg crc = 0;
301 int method = Z_DEFLATED;
303
304 if (tgtsize <= 6L) { R__error("target buffer too small"); /* errorflag = 1; */ }
305#if 0
306 crc = updcrc((char *)NULL, 0);
307 crc = updcrc(src, (extent) srcsize);
308#endif
309#ifdef DYN_ALLOC
310 state.R__window = 0;
311 state.R__prev = 0;
312#endif
313
314 /* R__read_buf = R__mem_read; */
315 /* assert(R__read_buf == R__mem_read); */
316 state.in_buf = src;
317 state.in_size = (unsigned)srcsize;
318 state.in_offset = 0;
319
320 state.out_buf = tgt;
321 state.out_size = (unsigned)tgtsize;
322 state.out_offset = 2 + 4;
323 state.R__window_size = 0L;
324
325 R__bi_init(&state);
327 R__ct_init(state.t_state, &att, &method);
328 R__lm_init(&state,(gCompressionLevel != 0 ? gCompressionLevel : 1), &flags);
329 R__Deflate(&state,&(state.error_flag));
330 state.R__window_size = 0L; /* was updated by lm_init() */
331
332 /* For portability, force little-endian order on all machines: */
333 tgt[0] = (char)(method & 0xff);
334 tgt[1] = (char)((method >> 8) & 0xff);
335 tgt[2] = (char)(crc & 0xff);
336 tgt[3] = (char)((crc >> 8) & 0xff);
337 tgt[4] = (char)((crc >> 16) & 0xff);
338 tgt[5] = (char)((crc >> 24) & 0xff);
339
340 return (ulg)state.out_offset;
341}
342
343
344/* ===========================================================================
345 * In-memory read function. As opposed to file_read(), this function
346 * does not perform end-of-line translation, and does not update the
347 * crc and input size.
348 * Note that the size of the entire input buffer is an unsigned long,
349 * but the size used in R__mem_read() is only an unsigned int. This makes a
350 * difference on 16 bit machines. R__mem_read() may be called several
351 * times for an in-memory compression.
352 */
353int R__mem_read(bits_internal_state *state,char *b, unsigned bsize)
354{
355 if (state->in_offset < state->in_size) {
356 ulg block_size = state->in_size - state->in_offset;
357 if (block_size > (ulg)bsize) block_size = (ulg)bsize;
358 memcpy(b, state->in_buf + state->in_offset, (unsigned)block_size);
359 state->in_offset += (unsigned)block_size;
360 return (int)block_size;
361 } else {
362 return 0; /* end of input */
363 }
364}
365
int R__seekable()
Definition Bits.c:270
#define Buf_size
Definition Bits.c:91
#define PUTSHORT(w)
Definition Bits.c:94
int R__bi_init(bits_internal_state *state)
Definition Bits.c:134
#define PUTBYTE(b)
Definition Bits.c:103
unsigned R__bi_reverse(unsigned code, int len)
Definition Bits.c:181
int R__copy_block(bits_internal_state *state, char *buf, unsigned len, int header)
Definition Bits.c:236
int R__error(char *msg)
Definition Bits.c:125
static int R__flush_outbuf()
static int gBitsVerbose
Definition Bits.c:124
int R__send_bits(bits_internal_state *state, int value, int length)
Definition Bits.c:151
ulg R__memcompress(char *tgt, ulg tgtsize, char *src, ulg srcsize)
Definition Bits.c:294
int gCompressionLevel
Copyright (C) 1990-1993 Mark Adler, Richard B.
Definition Bits.c:77
int R__bi_windup(bits_internal_state *state)
Definition Bits.c:217
int R__mem_read()
#define b(i)
Definition RSha256.hxx:100
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
#define far
Definition Tailor.h:122
#define OF(a)
Definition Tailor.h:87
unsigned int extent
Definition Tailor.h:178
#define local
Definition ZIP.h:55
ulg R__Deflate()
int R__ct_init()
tree_internal_state * R__get_thread_tree_state()
Definition ZTrees.c:293
#define Assert(cond, msg)
Definition ZIP.h:84
int R__lm_init()
#define UNKNOWN
Definition ZIP.h:61
#define Tracevv(x)
Definition ZIP.h:87
#define NULL
Definition ZInflate.c:15
unsigned short ush
Definition ZInflate.c:225
unsigned long ulg
Definition ZInflate.c:226
unsigned out_size
Definition Bits.h:69
tree_internal_state * t_state
Definition Bits.h:175
uch R__window[2L *((unsigned) 32768)]
Definition Bits.h:94
unsigned out_offset
Definition Bits.h:64
unsigned in_size
Definition Bits.h:69
unsigned in_offset
Definition Bits.h:64
unsigned short bi_buf
Definition Bits.h:48
Pos R__prev[((unsigned) 32768)]
Definition Bits.h:104
char * in_buf
Definition Bits.h:58
char * out_buf
Definition Bits.h:59