@@ -24,30 +24,29 @@ # import "OFInflateStream.h" #else # import "OFInflate64Stream.h" # define OFInflateStream OFInflate64Stream #endif - -#import "huffman_tree.h" +#import "OFHuffmanTree.h" #import "OFInitializationFailedException.h" #import "OFInvalidFormatException.h" #import "OFNotOpenException.h" #import "OFOutOfMemoryException.h" #ifndef OF_INFLATE64_STREAM_M -# define BUFFER_SIZE OF_INFLATE_STREAM_BUFFER_SIZE +# define bufferSize OFInflateStreamBufferSize #else -# define BUFFER_SIZE OF_INFLATE64_STREAM_BUFFER_SIZE +# define bufferSize OFInflate64StreamBufferSize #endif enum state { - BLOCK_HEADER, - UNCOMPRESSED_BLOCK_HEADER, - UNCOMPRESSED_BLOCK, - HUFFMAN_TREE, - HUFFMAN_BLOCK + StateBlockHeader, + StateUncompressedBlockHeader, + StateUncompressedBlock, + StateHuffmanTree, + StateHuffmanBlock }; enum huffman_state { WRITE_VALUE, AWAIT_CODE, @@ -98,11 +97,11 @@ }; #endif static const uint8_t codeLengthsOrder[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; -static struct of_huffman_tree *fixedLitLenTree, *fixedDistTree; +static OFHuffmanTree *fixedLitLenTree, *fixedDistTree; @implementation OFInflateStream static OF_INLINE bool tryReadBits(OFInflateStream *stream, uint16_t *bits, uint8_t count) { @@ -117,11 +116,11 @@ stream->_byte = stream->_buffer[stream->_bufferIndex++]; else { size_t length = [stream->_stream readIntoBuffer: stream->_buffer - length: BUFFER_SIZE]; + length: bufferSize]; if OF_UNLIKELY (length < 1) { stream->_savedBits = ret; stream->_savedBitsLength = i; return false; @@ -159,16 +158,16 @@ for (uint16_t i = 256; i <= 279; i++) lengths[i] = 7; for (uint16_t i = 280; i <= 287; i++) lengths[i] = 8; - fixedLitLenTree = of_huffman_tree_construct(lengths, 288); + fixedLitLenTree = OFHuffmanTreeNew(lengths, 288); for (uint16_t i = 0; i <= 31; i++) lengths[i] = 5; - fixedDistTree = of_huffman_tree_construct(lengths, 32); + fixedDistTree = OFHuffmanTreeNew(lengths, 32); } + (instancetype)streamWithStream: (OFStream *)stream { return [[[self alloc] initWithStream: stream] autorelease]; @@ -208,23 +207,22 @@ if (_stream != nil) [self close]; OFFreeMemory(_slidingWindow); - if (_state == HUFFMAN_TREE) { + if (_state == StateHuffmanTree) { OFFreeMemory(_context.huffmanTree.lengths); if (_context.huffmanTree.codeLenTree != NULL) - of_huffman_tree_release( - _context.huffmanTree.codeLenTree); + OFHuffmanTreeFree(_context.huffmanTree.codeLenTree); } - if (_state == HUFFMAN_TREE || _state == HUFFMAN_BLOCK) { + if (_state == StateHuffmanTree || _state == StateHuffmanBlock) { if (_context.huffman.litLenTree != fixedLitLenTree) - of_huffman_tree_release(_context.huffman.litLenTree); + OFHuffmanTreeFree(_context.huffman.litLenTree); if (_context.huffman.distTree != fixedDistTree) - of_huffman_tree_release(_context.huffman.distTree); + OFHuffmanTreeFree(_context.huffman.distTree); } [super dealloc]; } @@ -243,11 +241,11 @@ if (_atEndOfStream) return 0; start: switch ((enum state)_state) { - case BLOCK_HEADER: + case StateBlockHeader: if OF_UNLIKELY (_inLastBlock) { [_stream unreadFromBuffer: _buffer + _bufferIndex length: _bufferLength - _bufferIndex]; _bufferIndex = _bufferLength = 0; @@ -261,24 +259,24 @@ _inLastBlock = (bits & 1); switch (bits >> 1) { case 0: /* No compression */ - _state = UNCOMPRESSED_BLOCK_HEADER; + _state = StateUncompressedBlockHeader; _bitIndex = 8; _context.uncompressedHeader.position = 0; memset(_context.uncompressedHeader.length, 0, 4); break; case 1: /* Fixed Huffman */ - _state = HUFFMAN_BLOCK; + _state = StateHuffmanBlock; _context.huffman.state = AWAIT_CODE; _context.huffman.litLenTree = fixedLitLenTree; _context.huffman.distTree = fixedDistTree; _context.huffman.treeIter = fixedLitLenTree; break; case 2: /* Dynamic Huffman */ - _state = HUFFMAN_TREE; + _state = StateHuffmanTree; _context.huffmanTree.lengths = NULL; _context.huffmanTree.receivedCount = 0; _context.huffmanTree.value = 0xFE; _context.huffmanTree.litLenCodesCount = 0xFF; _context.huffmanTree.distCodesCount = 0xFF; @@ -287,11 +285,11 @@ default: @throw [OFInvalidFormatException exception]; } goto start; - case UNCOMPRESSED_BLOCK_HEADER: + case StateUncompressedBlockHeader: #define CTX _context.uncompressedHeader /* FIXME: This can be done more efficiently than unreading */ [_stream unreadFromBuffer: _buffer + _bufferIndex length: _bufferLength - _bufferIndex]; _bufferIndex = _bufferLength = 0; @@ -305,11 +303,11 @@ if OF_UNLIKELY ((CTX.length[0] | (CTX.length[1] << 8)) != (uint16_t)~(CTX.length[2] | (CTX.length[3] << 8))) @throw [OFInvalidFormatException exception]; - _state = UNCOMPRESSED_BLOCK; + _state = StateUncompressedBlock; /* * Do not reorder! _context.uncompressed.position and * _context.uncompressedHeader.length overlap! */ @@ -317,11 +315,11 @@ CTX.length[0] | (CTX.length[1] << 8); _context.uncompressed.position = 0; goto start; #undef CTX - case UNCOMPRESSED_BLOCK: + case StateUncompressedBlock: #define CTX _context.uncompressed if OF_UNLIKELY (length == 0) return bytesWritten; tmp = (length < (size_t)CTX.length - CTX.position @@ -343,15 +341,15 @@ length -= tmp; bytesWritten += tmp; CTX.position += tmp; if OF_UNLIKELY (CTX.position == CTX.length) - _state = BLOCK_HEADER; + _state = StateBlockHeader; goto start; #undef CTX - case HUFFMAN_TREE: + case StateHuffmanTree: #define CTX _context.huffmanTree if OF_LIKELY (CTX.value == 0xFE) { if OF_LIKELY (CTX.litLenCodesCount == 0xFF) { if OF_UNLIKELY (!tryReadBits(self, &bits, 5)) return bytesWritten; @@ -388,12 +386,11 @@ } CTX.lengths[codeLengthsOrder[i]] = bits; } - CTX.codeLenTree = of_huffman_tree_construct( - CTX.lengths, 19); + CTX.codeLenTree = OFHuffmanTreeNew(CTX.lengths, 19); CTX.treeIter = CTX.codeLenTree; OFFreeMemory(CTX.lengths); CTX.lengths = NULL; CTX.receivedCount = 0; @@ -407,11 +404,11 @@ for (uint16_t i = CTX.receivedCount; i < CTX.litLenCodesCount + CTX.distCodesCount + 258;) { uint8_t j, count; if OF_LIKELY (CTX.value == 0xFF) { - if OF_UNLIKELY (!of_huffman_tree_walk(self, + if OF_UNLIKELY (!OFHuffmanTreeWalk(self, tryReadBits, &CTX.treeIter, &value)) { CTX.receivedCount = i; return bytesWritten; } @@ -474,16 +471,16 @@ CTX.lengths[i++] = value; CTX.value = 0xFF; } - of_huffman_tree_release(CTX.codeLenTree); + OFHuffmanTreeFree(CTX.codeLenTree); CTX.codeLenTree = NULL; - CTX.litLenTree = of_huffman_tree_construct(CTX.lengths, + CTX.litLenTree = OFHuffmanTreeNew(CTX.lengths, CTX.litLenCodesCount + 257); - CTX.distTree = of_huffman_tree_construct( + CTX.distTree = OFHuffmanTreeNew( CTX.lengths + CTX.litLenCodesCount + 257, CTX.distCodesCount + 1); OFFreeMemory(CTX.lengths); @@ -490,17 +487,17 @@ /* * litLenTree and distTree are at the same location in * _context.huffman and _context.huffmanTree, thus no need to * set them. */ - _state = HUFFMAN_BLOCK; + _state = StateHuffmanBlock; _context.huffman.state = AWAIT_CODE; _context.huffman.treeIter = CTX.litLenTree; goto start; #undef CTX - case HUFFMAN_BLOCK: + case StateHuffmanBlock: #define CTX _context.huffman for (;;) { uint8_t extraBits, lengthCodeIndex; if OF_UNLIKELY (CTX.state == WRITE_VALUE) { @@ -530,11 +527,11 @@ CTX.treeIter = CTX.distTree; } /* Distance of length distance pair */ if (CTX.state == AWAIT_DISTANCE) { - if OF_UNLIKELY (!of_huffman_tree_walk(self, + if OF_UNLIKELY (!OFHuffmanTreeWalk(self, tryReadBits, &CTX.treeIter, &value)) return bytesWritten; if OF_UNLIKELY (value >= numDistanceCodes) @throw [OFInvalidFormatException @@ -592,22 +589,22 @@ CTX.state = AWAIT_CODE; CTX.treeIter = CTX.litLenTree; } - if OF_UNLIKELY (!of_huffman_tree_walk(self, tryReadBits, + if OF_UNLIKELY (!OFHuffmanTreeWalk(self, tryReadBits, &CTX.treeIter, &value)) return bytesWritten; /* End of block */ if OF_UNLIKELY (value == 256) { if (CTX.litLenTree != fixedLitLenTree) - of_huffman_tree_release(CTX.litLenTree); + OFHuffmanTreeFree(CTX.litLenTree); if (CTX.distTree != fixedDistTree) - of_huffman_tree_release(CTX.distTree); + OFHuffmanTreeFree(CTX.distTree); - _state = BLOCK_HEADER; + _state = StateBlockHeader; goto start; } /* Literal byte */ if OF_LIKELY (value < 256) {