1 /* -*- Mode: C; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // -------------------------------------------------------------------------*/
11 * Generic inflation interface.
16 #ifndef SQUIRRELJME_INFLATE_H
17 #define SQUIRRELJME_INFLATE_H
19 #include "sjme/stdTypes.h"
20 #include "sjme/error.h"
25 #ifndef SJME_CXX_IS_EXTERNED
26 #define SJME_CXX_IS_EXTERNED
27 #define SJME_CXX_SQUIRRELJME_INFLATE_H
30 #endif /* #ifdef SJME_CXX_IS_EXTERNED */
31 #endif /* #ifdef __cplusplus */
33 /*--------------------------------------------------------------------------*/
35 /** The size of the input/output buffer. */
36 #define SJME_INFLATE_IO_BUFFER_SIZE 2048
38 /** The mask for the input/output buffer position. */
39 #define SJME_INFLATE_IO_BUFFER_MASK 2047
41 /** When the output buffer is considered saturated. */
42 #define SJME_INFLATE_IO_BUFFER_SATURATED 1700
44 /** The maximum window size. */
45 #define SJME_INFLATE_WINDOW_MAX_SIZE 32768
47 /** The window size. */
48 #define SJME_INFLATE_WINDOW_SIZE 16384
50 /** The window mask. */
51 #define SJME_INFLATE_WINDOW_MASK 32768
53 /** Maximum huffman tree size. */
54 #define SJME_INFLATE_HUFF_STORAGE_SIZE 16383
56 /** The limit for code lengths. */
57 #define SJME_INFLATE_CODE_LEN_LIMIT 19
59 /** The maximum number of bits in the code length tree. */
60 #define SJME_INFLATE_CODE_LEN_MAX_BITS 15
62 /** The number of codes. */
63 #define SJME_INFLATE_NUM_CODES 288
65 /** The maximum number of literal lengths. */
66 #define SJME_INFLATE_NUM_LIT_LENS 287
68 /** The maximum number of distance lengths. */
69 #define SJME_INFLATE_NUM_DIST_LENS 33
73 * Zip bit reading mode.
77 typedef enum sjme_inflate_order
79 /** Least significant bit. */
82 /** Most significant bit. */
87 * Used to either peek or pop from the bit stream.
91 typedef enum sjme_inflate_peek
101 * Which type of node is this in the tree?
105 typedef enum sjme_inflate_huffNodeType
108 SJME_INFLATE_UNKNOWN
,
115 } sjme_inflate_huffNodeType
;
118 * The inflation step.
122 typedef enum sjme_inflate_step
124 /** Parse BTYPE and determine how to continue. */
125 SJME_INFLATE_STEP_CHECK_BTYPE
,
127 /** Literal uncompressed data header. */
128 SJME_INFLATE_STEP_LITERAL_HEADER
,
130 /** Literal uncompressed data. */
131 SJME_INFLATE_STEP_LITERAL_DATA
,
133 /** Load in dynamic huffman table. */
134 SJME_INFLATE_STEP_DYNAMIC_TABLE_LOAD
,
136 /** Load in dynamic huffman table: Code length tree. */
137 SJME_INFLATE_STEP_DYNAMIC_TABLE_LOAD_CODE_LEN
,
139 /** Load in dynamic huffman table: Literal. */
140 SJME_INFLATE_STEP_DYNAMIC_TABLE_LOAD_LITERAL
,
142 /** Load in dynamic huffman table: Distance tree. */
143 SJME_INFLATE_STEP_DYNAMIC_TABLE_LOAD_DISTANCE
,
145 /** Fixed static huffman table. */
146 SJME_INFLATE_STEP_FIXED_TABLE_INFLATE
,
148 /** Inflate from a given huffman tree. */
149 SJME_INFLATE_STEP_INFLATE_FROM_TREE
,
151 /** Finished, nothing is left. */
152 SJME_INFLATE_STEP_FINISHED
,
156 * Inflation buffer state.
160 typedef struct sjme_inflate_buffer
162 /** The amount of data that is ready for processing. */
165 /** The current read head. */
168 /** The current write head. */
171 /** The buffer storage. */
172 sjme_jubyte buffer
[SJME_INFLATE_IO_BUFFER_SIZE
];
174 /** Was EOF hit in this buffer? */
175 sjme_jboolean hitEof
;
177 /** The current bit buffer. */
178 sjme_juint bitBuffer
;
180 /** The amount of bits in the buffer. */
182 } sjme_inflate_buffer
;
185 * The window for output inflated data.
189 typedef struct sjme_inflate_window
191 /** The number of bytes in the window. */
194 /** The end position of the window. */
197 /** The window buffer. */
198 sjme_jubyte window
[SJME_INFLATE_WINDOW_SIZE
];
199 } sjme_inflate_window
;
202 * Initial code length huffman tree building values.
206 typedef struct sjme_inflate_huffInit
208 /** Literal length. */
211 /** Distance length. */
214 /** The code length count. */
217 /** The raw code length bit values. */
218 sjme_juint rawCodeLens
[SJME_INFLATE_CODE_LEN_LIMIT
];
219 } sjme_inflate_huffInit
;
222 * Huffman tree building parameters, used as input.
226 typedef struct sjme_inflate_huffParam
228 /** Code lengths to input. */
231 /** The number of code lengths. */
233 } sjme_inflate_huffParam
;
240 typedef struct sjme_align64 sjme_inflate_huffNode
241 sjme_inflate_huffNode
;
243 struct sjme_align64 sjme_inflate_huffNode
248 /** Data if a leaf. */
252 sjme_inflate_huffNode
* zero
;
255 sjme_inflate_huffNode
* one
;
258 /** Data if a node. */
261 /** The code stored here. */
266 /** Which type of node is this? */
267 sjme_inflate_huffNodeType type
;
271 * Huffman tree parameters.
275 typedef struct sjme_inflate_huffTree
277 /** The root node. */
278 sjme_inflate_huffNode
* root
;
279 } sjme_inflate_huffTree
;
282 * Storage for huffman tree nodes.
286 typedef struct sjme_inflate_huffTreeStorage
288 /** Storage for the huffman tree nodes. */
289 sjme_align64 sjme_jubyte storage
[SJME_INFLATE_HUFF_STORAGE_SIZE
];
291 /** Next free node. */
292 sjme_inflate_huffNode
* next
;
294 /** Final end of tree. */
295 sjme_inflate_huffNode
* finalEnd
;
296 } sjme_inflate_huffTreeStorage
;
303 typedef struct sjme_inflate_state sjme_inflate_state
;
306 * Reads a code from the input.
308 * @param state The state to read from.
309 * @param outCode The resultant code which was read.
310 * @return On any error, if any.
313 typedef sjme_errorCode (*sjme_inflate_readCodeFunc
)(
314 sjme_attrInNotNull sjme_inflate_state
* state
,
315 sjme_attrOutNotNull sjme_juint
* outCode
);
318 * Reads a distance code from the input.
320 * @param state The state to read from.
321 * @param outDist The resultant distance code which was read.
322 * @return On any error, if any.
325 typedef sjme_errorCode (*sjme_inflate_readDistFunc
)(
326 sjme_attrInNotNull sjme_inflate_state
* state
,
327 sjme_attrOutNotNull sjme_juint
* outDist
);
334 struct sjme_inflate_state
336 /** The current step in inflation. */
337 sjme_inflate_step step
;
339 /** Was the final block hit? */
340 sjme_jboolean finalHit
;
342 /** Is the input data corrupted? */
343 sjme_jboolean invalidInput
;
345 /** The output window. */
346 sjme_inflate_window window
;
348 /** The amount of literal bytes left to read. */
349 sjme_jint literalLeft
;
351 /** Initialization data for the initial huffman tree. */
352 sjme_inflate_huffInit huffInit
;
354 /** The function for reading codes. */
355 sjme_inflate_readCodeFunc readCode
;
357 /** The function for reading distances. */
358 sjme_inflate_readDistFunc readDist
;
360 /** Huffman tree node storage. */
361 sjme_inflate_huffTreeStorage huffStorage
;
363 /** Code length tree. */
364 sjme_inflate_huffTree codeLenTree
;
366 /** Distance tree. */
367 sjme_inflate_huffTree distanceTree
;
369 /** Literal tree, not literally. */
370 sjme_inflate_huffTree literalTree
;
372 /** The input buffer. */
373 sjme_inflate_buffer input
;
375 /** The output buffer. */
376 sjme_inflate_buffer output
;
380 * Inflate stream initialization.
384 typedef struct sjme_inflate_init
386 /** The compressed data stream. */
387 sjme_stream_input handle
;
389 /** Decompression state. */
390 sjme_inflate_state
* handleTwo
;
393 sjme_errorCode
sjme_inflate_bitIn(
394 sjme_attrInNotNull sjme_inflate_buffer
* buffer
,
395 sjme_attrInValue sjme_inflate_order order
,
396 sjme_attrInValue sjme_inflate_peek popPeek
,
397 sjme_attrInRange(1, 32) sjme_juint bitCount
,
398 sjme_attrOutNotNull sjme_juint
* readValue
);
400 sjme_errorCode
sjme_inflate_bitInCodeLen(
401 sjme_attrInNotNull sjme_inflate_buffer
* inBuffer
,
402 sjme_attrInNotNull sjme_inflate_huffTree
* codeLenTree
,
403 sjme_attrInOutNotNull sjme_juint
* index
,
404 sjme_attrOutNotNull sjme_juint
* outLengths
,
405 sjme_attrInPositive sjme_juint count
);
407 sjme_errorCode
sjme_inflate_bitInTree(
408 sjme_attrInNotNull sjme_inflate_buffer
* inBuffer
,
409 sjme_attrInNotNull sjme_inflate_huffTree
* fromTree
,
410 sjme_attrOutNotNull sjme_juint
* outValue
);
412 sjme_errorCode
sjme_inflate_bitNeed(
413 sjme_attrInNotNull sjme_inflate_buffer
* buffer
,
414 sjme_attrInPositiveNonZero sjme_jint bitCount
);
416 sjme_errorCode
sjme_inflate_bitOut(
417 sjme_attrInNotNull sjme_inflate_buffer
* buffer
,
418 sjme_attrInValue sjme_inflate_order order
,
419 sjme_attrOutNotNull sjme_inflate_window
* window
,
420 sjme_attrInRange(1, 32) sjme_juint bitCount
,
421 sjme_attrOutNotNull sjme_juint writeValue
);
423 sjme_errorCode
sjme_inflate_bufferArea(
424 sjme_attrInNotNull sjme_inflate_buffer
* buffer
,
425 sjme_attrOutNotNull sjme_jint
* outRemainder
,
426 sjme_attrOutNotNull sjme_pointer
* outBufOpPos
,
427 sjme_attrOutNotNull sjme_jint
* outBufOpLen
);
429 sjme_errorCode
sjme_inflate_bufferConsume(
430 sjme_attrInNotNull sjme_inflate_buffer
* buffer
,
431 sjme_attrInPositiveNonZero sjme_jint count
);
433 sjme_errorCode
sjme_inflate_bufferGive(
434 sjme_attrInNotNull sjme_inflate_buffer
* buffer
,
435 sjme_attrInPositiveNonZero sjme_jint count
);
437 sjme_errorCode
sjme_inflate_decode(
438 sjme_attrInNotNull sjme_inflate_state
* state
);
440 sjme_errorCode
sjme_inflate_decodeBType(
441 sjme_attrInNotNull sjme_inflate_state
* state
);
443 sjme_errorCode
sjme_inflate_decodeDynLoad(
444 sjme_attrInNotNull sjme_inflate_state
* state
);
446 sjme_errorCode
sjme_inflate_decodeDynLoadCodeLen(
447 sjme_attrInNotNull sjme_inflate_state
* state
);
449 sjme_errorCode
sjme_inflate_decodeDynLoadLitDist(
450 sjme_attrInNotNull sjme_inflate_state
* state
,
451 sjme_attrInPositive sjme_juint count
,
452 sjme_attrInNotNull sjme_inflate_huffTree
* outTree
,
453 sjme_attrInPositiveNonZero sjme_juint maxCount
);
455 sjme_errorCode
sjme_inflate_decodeLiteralData(
456 sjme_attrInNotNull sjme_inflate_state
* state
);
458 sjme_errorCode
sjme_inflate_decodeLiteralHeader(
459 sjme_attrInNotNull sjme_inflate_state
* state
);
461 sjme_errorCode
sjme_inflate_buildTree(
462 sjme_attrInNotNull sjme_inflate_state
* state
,
463 sjme_attrInNotNull sjme_inflate_huffParam
* param
,
464 sjme_attrInNotNull sjme_inflate_huffTree
* outTree
,
465 sjme_attrInNotNull sjme_inflate_huffTreeStorage
* inStorage
);
467 sjme_errorCode
sjme_inflate_buildTreeInsert(
468 sjme_attrInNotNull sjme_inflate_state
* state
,
469 sjme_attrInNotNull sjme_inflate_huffTree
* outTree
,
470 sjme_attrInNotNull sjme_inflate_huffTreeStorage
* inStorage
,
471 sjme_attrInPositive sjme_juint code
,
472 sjme_attrInValue sjme_juint sym
,
473 sjme_attrInPositiveNonZero sjme_juint symMask
);
475 sjme_errorCode
sjme_inflate_buildTreeInsertNext(
476 sjme_attrInNotNull sjme_inflate_huffTree
* outTree
,
477 sjme_attrInNotNull sjme_inflate_huffTreeStorage
* inStorage
,
478 sjme_attrOutNotNull sjme_inflate_huffNode
** outNode
);
480 sjme_errorCode
sjme_inflate_processCodes(
481 sjme_attrInNotNull sjme_inflate_state
* state
);
483 sjme_errorCode
sjme_inflate_processDistance(
484 sjme_attrInNotNull sjme_inflate_state
* state
,
485 sjme_attrInNotNull sjme_inflate_buffer
* inBuffer
,
486 sjme_attrInRange(257, 285) sjme_juint origCode
,
487 sjme_attrOutNotNull sjme_juint
* outDist
);
489 sjme_errorCode
sjme_inflate_processLength(
490 sjme_attrInNotNull sjme_inflate_state
* state
,
491 sjme_attrInNotNull sjme_inflate_buffer
* inBuffer
,
492 sjme_attrInRange(257, 285) sjme_juint code
,
493 sjme_attrOutNotNull sjme_juint
* outLength
);
495 sjme_errorCode
sjme_inflate_processWindow(
496 sjme_attrInNotNull sjme_inflate_state
* state
,
497 sjme_attrInNotNull sjme_inflate_buffer
* outBuffer
,
498 sjme_attrInNotNull sjme_inflate_window
* window
,
499 sjme_attrInPositive sjme_juint windowDist
,
500 sjme_attrInPositive sjme_juint windowLen
);
502 sjme_errorCode
sjme_inflate_readCodeDynamic(
503 sjme_attrInNotNull sjme_inflate_state
* state
,
504 sjme_attrOutNotNull sjme_juint
* outCode
);
506 sjme_errorCode
sjme_inflate_readDistDynamic(
507 sjme_attrInNotNull sjme_inflate_state
* state
,
508 sjme_attrOutNotNull sjme_juint
* outDist
);
510 sjme_errorCode
sjme_inflate_readCodeFixed(
511 sjme_attrInNotNull sjme_inflate_state
* state
,
512 sjme_attrOutNotNull sjme_juint
* outCode
);
514 sjme_errorCode
sjme_inflate_readDistFixed(
515 sjme_attrInNotNull sjme_inflate_state
* state
,
516 sjme_attrOutNotNull sjme_juint
* outDist
);
518 /*--------------------------------------------------------------------------*/
522 #ifdef SJME_CXX_SQUIRRELJME_INFLATE_H
524 #undef SJME_CXX_SQUIRRELJME_INFLATE_H
525 #undef SJME_CXX_IS_EXTERNED
526 #endif /* #ifdef SJME_CXX_SQUIRRELJME_INFLATE_H */
527 #endif /* #ifdef __cplusplus */
529 #endif /* SQUIRRELJME_INFLATE_H */