1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef SeekableZStream_h
6 #define SeekableZStream_h
11 * Seekable compressed stream are created by splitting the original
12 * decompressed data in small chunks and compress these chunks
15 * The seekable compressed file format consists in a header defined below,
16 * followed by a table of 32-bits words containing the offsets for each
17 * individual compressed chunk, then followed by the compressed chunks.
21 struct SeekableZStreamHeader
: public Zip::SignedEntity
<SeekableZStreamHeader
>
23 SeekableZStreamHeader()
24 : Zip::SignedEntity
<SeekableZStreamHeader
>(magic
)
25 , totalSize(0), chunkSize(0), dictSize(0), nChunks(0), lastChunkSize(0)
26 , windowBits(0), filter(0) { }
28 /* Reuse Zip::SignedEntity to handle the magic number used in the Seekable
29 * ZStream file format. The magic number is "SeZz". */
30 static const uint32_t magic
= 0x7a5a6553;
32 /* Total size of the stream, including the 4 magic bytes. */
38 /* Size of the dictionary */
41 /* Number of chunks */
44 /* Size of last chunk (> 0, <= Chunk size) */
45 le_uint16 lastChunkSize
;
47 /* windowBits value used when deflating */
48 signed char windowBits
;
55 static_assert(sizeof(SeekableZStreamHeader
) == 5 * 4,
56 "SeekableZStreamHeader should be 5 32-bits words");
59 * Helper class used to decompress Seekable ZStreams.
61 class SeekableZStream
{
63 /* Initialize from the given buffer. Returns whether initialization
64 * succeeded (true) or failed (false). */
65 bool Init(const void *buf
, size_t length
);
67 /* Decompresses starting from the given chunk. The decompressed data is
68 * stored at the given location. The given length, in bytes, indicates
69 * how much data to decompress. If length is 0, then exactly one chunk
71 * Returns whether decompression succeeded (true) or failed (false). */
72 bool Decompress(void *where
, size_t chunk
, size_t length
= 0);
74 /* Decompresses the given chunk at the given address. If a length is given,
75 * only decompresses that amount of data instead of the entire chunk.
76 * Returns whether decompression succeeded (true) or failed (false). */
77 bool DecompressChunk(void *where
, size_t chunk
, size_t length
= 0);
79 /* Returns the uncompressed size of the complete zstream */
80 const size_t GetUncompressedSize() const
82 return (offsetTable
.numElements() - 1) * chunkSize
+ lastChunkSize
;
85 /* Returns the chunk size of the given chunk */
86 const size_t GetChunkSize(size_t chunk
= 0) const {
87 return (chunk
== offsetTable
.numElements() - 1) ? lastChunkSize
: chunkSize
;
90 /* Returns the number of chunks */
91 const size_t GetChunksNum() const {
92 return offsetTable
.numElements();
96 * Filters used to improve compression rate.
98 enum FilterDirection
{
102 typedef void (*ZStreamFilter
)(off_t
, FilterDirection
,
103 unsigned char *, size_t);
112 static ZStreamFilter
GetFilter(FilterId id
);
114 static ZStreamFilter
GetFilter(uint16_t id
) {
115 return GetFilter(static_cast<FilterId
>(id
));
119 /* RAW Seekable SZtream buffer */
120 const unsigned char *buffer
;
122 /* Total size of the stream, including the 4 magic bytes. */
128 /* Size of last chunk (> 0, <= Chunk size) */
129 uint32_t lastChunkSize
;
131 /* windowBits value used when deflating */
135 Array
<le_uint32
> offsetTable
;
138 ZStreamFilter filter
;
140 /* Deflate dictionary */
141 Array
<unsigned char> dictionary
;
145 operator++(SeekableZStream::FilterId
&other
)
147 const int orig
= static_cast<int>(other
);
148 other
= static_cast<SeekableZStream::FilterId
>(orig
+ 1);
151 #endif /* SeekableZStream_h */