1 /*
2  * This file is part of NetSurf's LibNSGIF, http://www.netsurf-browser.org/
3  * Licensed under the MIT License,
4  *                http://www.opensource.org/licenses/mit-license.php
5  *
6  * Copyright 2017 Michael Drake <michael.drake@codethink.co.uk>
7  */
8 
9 #ifndef LZW_H_
10 #define LZW_H_
11 
12 /**
13  * \file
14  * \brief LZW decompression (interface)
15  *
16  * Decoder for GIF LZW data.
17  */
18 
19 
20 /** Maximum LZW code size in bits */
21 #define LZW_CODE_MAX 12
22 
23 
24 /* Declare lzw internal context structure */
25 struct lzw_ctx;
26 
27 
28 /** LZW decoding response codes */
29 typedef enum lzw_result {
30 	LZW_OK,        /**< Success */
31 	LZW_OK_EOD,    /**< Success; reached zero-length sub-block */
32 	LZW_NO_MEM,    /**< Error: Out of memory */
33 	LZW_NO_DATA,   /**< Error: Out of data */
34 	LZW_EOI_CODE,  /**< Error: End of Information code */
35 	LZW_BAD_ICODE, /**< Error: Bad initial LZW code */
36 	LZW_BAD_CODE,  /**< Error: Bad LZW code */
37 } lzw_result;
38 
39 
40 /**
41  * Create an LZW decompression context.
42  *
43  * \param[out] ctx  Returns an LZW decompression context.  Caller owned,
44  *                  free with lzw_context_destroy().
45  * \return LZW_OK on success, or appropriate error code otherwise.
46  */
47 lzw_result lzw_context_create(
48 		struct lzw_ctx **ctx);
49 
50 /**
51  * Destroy an LZW decompression context.
52  *
53  * \param[in] ctx  The LZW decompression context to destroy.
54  */
55 void lzw_context_destroy(
56 		struct lzw_ctx *ctx);
57 
58 /**
59  * Initialise an LZW decompression context for decoding.
60  *
61  * Caller owns neither `stack_base_out` or `stack_pos_out`.
62  *
63  * \param[in]  ctx                  The LZW decompression context to initialise.
64  * \param[in]  compressed_data      The compressed data.
65  * \param[in]  compressed_data_len  Byte length of compressed data.
66  * \param[in]  compressed_data_pos  Start position in data.  Must be position
67  *                                  of a size byte at sub-block start.
68  * \param[in]  code_size            The initial LZW code size to use.
69  * \param[out] stack_base_out       Returns base of decompressed data stack.
70  * \param[out] stack_pos_out        Returns current stack position.
71  *                                  There are `stack_pos_out - stack_base_out`
72  *                                  current stack entries.
73  * \return LZW_OK on success, or appropriate error code otherwise.
74  */
75 lzw_result lzw_decode_init(
76 		struct lzw_ctx *ctx,
77 		const uint8_t *compressed_data,
78 		uint32_t compressed_data_len,
79 		uint32_t compressed_data_pos,
80 		uint8_t code_size,
81 		const uint8_t ** const stack_base_out,
82 		const uint8_t ** const stack_pos_out);
83 
84 /**
85  * Fill the LZW stack with decompressed data
86  *
87  * Ensure anything on the stack is used before calling this, as anything
88  * on the stack before this call will be trampled.
89  *
90  * Caller does not own `stack_pos_out`.
91  *
92  * \param[in]  ctx            LZW reading context, updated.
93  * \param[out] stack_pos_out  Returns current stack position.
94  *                            Use with `stack_base_out` value from previous
95  *                            lzw_decode_init() call.
96  *                            There are `stack_pos_out - stack_base_out`
97  *                            current stack entries.
98  * \return LZW_OK on success, or appropriate error code otherwise.
99  */
100 lzw_result lzw_decode(
101 		struct lzw_ctx *ctx,
102 		const uint8_t ** const stack_pos_out);
103 
104 
105 #endif
106