1 /* Copyright 2013 Google Inc. All Rights Reserved.
2 
3    Distributed under MIT license.
4    See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 */
6 
7 /* API for Brotli decompression */
8 
9 #ifndef BROTLI_DEC_DECODE_H_
10 #define BROTLI_DEC_DECODE_H_
11 
12 #include "./types.h"
13 
14 #if defined(__cplusplus) || defined(c_plusplus)
15 extern "C" {
16 #endif
17 
18 typedef struct BrotliStateStruct BrotliState;
19 
20 typedef enum {
21   /* Decoding error, e.g. corrupt input or memory allocation problem */
22   BROTLI_RESULT_ERROR = 0,
23   /* Decoding successfully completed */
24   BROTLI_RESULT_SUCCESS = 1,
25   /* Partially done; should be called again with more input */
26   BROTLI_RESULT_NEEDS_MORE_INPUT = 2,
27   /* Partially done; should be called again with more output */
28   BROTLI_RESULT_NEEDS_MORE_OUTPUT = 3
29 } BrotliResult;
30 
31 #define BROTLI_ERROR_CODES_LIST(BROTLI_ERROR_CODE, SEPARATOR)              \
32   BROTLI_ERROR_CODE(_, NO_ERROR, 0) SEPARATOR                              \
33   /* Same as BrotliResult values */                                        \
34   BROTLI_ERROR_CODE(_, SUCCESS, 1) SEPARATOR                               \
35   BROTLI_ERROR_CODE(_, NEEDS_MORE_INPUT, 2) SEPARATOR                      \
36   BROTLI_ERROR_CODE(_, NEEDS_MORE_OUTPUT, 3) SEPARATOR                     \
37                                                                            \
38   /* Errors caused by invalid input */                                     \
39   BROTLI_ERROR_CODE(_ERROR_FORMAT_, EXUBERANT_NIBBLE, -1) SEPARATOR        \
40   BROTLI_ERROR_CODE(_ERROR_FORMAT_, RESERVED, -2) SEPARATOR                \
41   BROTLI_ERROR_CODE(_ERROR_FORMAT_, EXUBERANT_META_NIBBLE, -3) SEPARATOR   \
42   BROTLI_ERROR_CODE(_ERROR_FORMAT_, SIMPLE_HUFFMAN_ALPHABET, -4) SEPARATOR \
43   BROTLI_ERROR_CODE(_ERROR_FORMAT_, SIMPLE_HUFFMAN_SAME, -5) SEPARATOR     \
44   BROTLI_ERROR_CODE(_ERROR_FORMAT_, CL_SPACE, -6) SEPARATOR                \
45   BROTLI_ERROR_CODE(_ERROR_FORMAT_, HUFFMAN_SPACE, -7) SEPARATOR           \
46   BROTLI_ERROR_CODE(_ERROR_FORMAT_, CONTEXT_MAP_REPEAT, -8) SEPARATOR      \
47   BROTLI_ERROR_CODE(_ERROR_FORMAT_, BLOCK_LENGTH_1, -9) SEPARATOR          \
48   BROTLI_ERROR_CODE(_ERROR_FORMAT_, BLOCK_LENGTH_2, -10) SEPARATOR         \
49   BROTLI_ERROR_CODE(_ERROR_FORMAT_, TRANSFORM, -11) SEPARATOR              \
50   BROTLI_ERROR_CODE(_ERROR_FORMAT_, DICTIONARY, -12) SEPARATOR             \
51   BROTLI_ERROR_CODE(_ERROR_FORMAT_, WINDOW_BITS, -13) SEPARATOR            \
52   BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_1, -14) SEPARATOR              \
53   BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_2, -15) SEPARATOR              \
54                                                                            \
55   /* -16..-20 codes are reserved */                                        \
56                                                                            \
57   /* Memory allocation problems */                                         \
58   BROTLI_ERROR_CODE(_ERROR_ALLOC_, CONTEXT_MODES, -21) SEPARATOR           \
59   /* Literal, insert and distance trees together */                        \
60   BROTLI_ERROR_CODE(_ERROR_ALLOC_, TREE_GROUPS, -22) SEPARATOR             \
61   /* -23..-24 codes are reserved for distinct tree groups */               \
62   BROTLI_ERROR_CODE(_ERROR_ALLOC_, CONTEXT_MAP, -25) SEPARATOR             \
63   BROTLI_ERROR_CODE(_ERROR_ALLOC_, RING_BUFFER_1, -26) SEPARATOR           \
64   BROTLI_ERROR_CODE(_ERROR_ALLOC_, RING_BUFFER_2, -27) SEPARATOR           \
65   /* -28..-29 codes are reserved for dynamic ringbuffer allocation */      \
66   BROTLI_ERROR_CODE(_ERROR_ALLOC_, BLOCK_TYPE_TREES, -30) SEPARATOR        \
67                                                                            \
68   /* "Impossible" states */                                                \
69   BROTLI_ERROR_CODE(_ERROR_, UNREACHABLE, -31)
70 
71 typedef enum {
72 #define _BROTLI_COMMA ,
73 #define _BROTLI_ERROR_CODE_ENUM_ITEM(PREFIX, NAME, CODE) \
74     BROTLI ## PREFIX ## NAME = CODE
75   BROTLI_ERROR_CODES_LIST(_BROTLI_ERROR_CODE_ENUM_ITEM, _BROTLI_COMMA)
76 #undef _BROTLI_ERROR_CODE_ENUM_ITEM
77 #undef _BROTLI_COMMA
78 } BrotliErrorCode;
79 
80 #define BROTLI_LAST_ERROR_CODE BROTLI_ERROR_UNREACHABLE
81 
82 /* Creates the instance of BrotliState and initializes it. |alloc_func| and
83    |free_func| MUST be both zero or both non-zero. In the case they are both
84    zero, default memory allocators are used. |opaque| is passed to |alloc_func|
85    and |free_func| when they are called. */
86 BrotliState* BrotliCreateState(
87     brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque);
88 
89 /* Deinitializes and frees BrotliState instance. */
90 void BrotliDestroyState(BrotliState* state);
91 
92 /* Sets |*decoded_size| to the decompressed size of the given encoded stream.
93    This function only works if the encoded buffer has a single meta block,
94    or if it has two meta-blocks, where the first is uncompressed and the
95    second is empty.
96    Returns 1 on success, 0 on failure. */
97 int BrotliDecompressedSize(size_t encoded_size,
98                            const uint8_t* encoded_buffer,
99                            size_t* decoded_size);
100 
101 /* Decompresses the data in |encoded_buffer| into |decoded_buffer|, and sets
102    |*decoded_size| to the decompressed length. */
103 BrotliResult BrotliDecompressBuffer(size_t encoded_size,
104                                     const uint8_t* encoded_buffer,
105                                     size_t* decoded_size,
106                                     uint8_t* decoded_buffer);
107 
108 /* Decompresses the data. Supports partial input and output.
109 
110    Must be called with an allocated input buffer in |*next_in| and an allocated
111    output buffer in |*next_out|. The values |*available_in| and |*available_out|
112    must specify the allocated size in |*next_in| and |*next_out| respectively.
113 
114    After each call, |*available_in| will be decremented by the amount of input
115    bytes consumed, and the |*next_in| pointer will be incremented by that
116    amount. Similarly, |*available_out| will be decremented by the amount of
117    output bytes written, and the |*next_out| pointer will be incremented by that
118    amount. |total_out|, if it is not a null-pointer, will be set to the number
119    of bytes decompressed since the last state initialization.
120 
121    Input is never overconsumed, so |next_in| and |available_in| could be passed
122    to the next consumer after decoding is complete. */
123 BrotliResult BrotliDecompressStream(size_t* available_in,
124                                     const uint8_t** next_in,
125                                     size_t* available_out,
126                                     uint8_t** next_out,
127                                     size_t* total_out,
128                                     BrotliState* s);
129 
130 /* Fills the new state with a dictionary for LZ77, warming up the ringbuffer,
131    e.g. for custom static dictionaries for data formats.
132    Not to be confused with the built-in transformable dictionary of Brotli.
133    |size| should be less or equal to 2^24 (16MiB), otherwise the dictionary will
134    be ignored. The dictionary must exist in memory until decoding is done and
135    is owned by the caller. To use:
136     1) Allocate and initialize state with BrotliCreateState
137     2) Use BrotliSetCustomDictionary
138     3) Use BrotliDecompressStream
139     4) Clean up and free state with BrotliDestroyState
140 */
141 void BrotliSetCustomDictionary(
142     size_t size, const uint8_t* dict, BrotliState* s);
143 
144 /* Returns 1, if s is in a state where we have not read any input bytes yet,
145    and 0 otherwise */
146 int BrotliStateIsStreamStart(const BrotliState* s);
147 
148 /* Returns 1, if s is in a state where we reached the end of the input and
149    produced all of the output, and 0 otherwise. */
150 int BrotliStateIsStreamEnd(const BrotliState* s);
151 
152 /* Returns detailed error code after BrotliDecompressStream returns
153    BROTLI_RESULT_ERROR. */
154 BrotliErrorCode BrotliGetErrorCode(const BrotliState* s);
155 
156 const char* BrotliErrorString(BrotliErrorCode c);
157 
158 #if defined(__cplusplus) || defined(c_plusplus)
159 } /* extern "C" */
160 #endif
161 
162 #endif  /* BROTLI_DEC_DECODE_H_ */
163