FastLED 3.9.15
Loading...
Searching...
No Matches

◆ lzw__read_code()

static lzw_result fl::third_party::lzw__read_code ( struct lzw_read_ctx * ctx,
fl::u16 code_size,
fl::u16 * code_out )
inlinestatic

Get the next LZW code of given size from the raw input data.

Reads codes from the input data stream coping with GIF data sub-blocks.

Parameters
[in]ctxLZW reading context, updated.
[in]code_sizeSize of LZW code to get from data.
[out]code_outReturns an LZW code on success.
Returns
LZW_OK or LZW_OK_EOD on success, appropriate error otherwise.

Definition at line 167 of file lzw.cpp.hpp.

171{
172 fl::u32 code = 0;
173 fl::u32 current_bit = ctx->sb_bit & 0x7;
174
175 if (ctx->sb_bit + 24 <= ctx->sb_bit_count) {
176 /* Fast path: read three bytes from this sub-block */
177 const fl::u8 *data = ctx->sb_data + (ctx->sb_bit >> 3);
178 code |= static_cast<fl::u32>(*data++) << 0;
179 code |= static_cast<fl::u32>(*data++) << 8;
180 code |= static_cast<fl::u32>(*data) << 16;
181 ctx->sb_bit += code_size;
182 } else {
183 /* Slow path: code spans sub-blocks */
184 fl::u8 byte_advance = (current_bit + code_size) >> 3;
185 fl::u8 byte = 0;
186 fl::u8 bits_remaining_0 = (code_size < (8u - current_bit)) ?
187 code_size : (8u - current_bit);
188 fl::u8 bits_remaining_1 = code_size - bits_remaining_0;
189 fl::u8 bits_used[3] = {
190 bits_remaining_0,
191 (fl::u8)(bits_remaining_1 < 8 ? bits_remaining_1 : 8),
192 (fl::u8)(bits_remaining_1 - 8),
193 };
194
195 FL_ASSERT(byte_advance <= 2, "Byte advance too large");
196
197 while (true) {
198 const fl::u8 *data = ctx->sb_data;
199 lzw_result res;
200
201 /* Get any data from end of this sub-block */
202 while (byte <= byte_advance &&
203 ctx->sb_bit < ctx->sb_bit_count) {
204 code |= data[ctx->sb_bit >> 3] << (byte << 3);
205 ctx->sb_bit += bits_used[byte];
206 byte++;
207 }
208
209 /* Check if we have all we need */
210 if (byte > byte_advance) {
211 break;
212 }
213
214 /* Move to next sub-block */
215 res = lzw__block_advance(ctx);
216 if (res != LZW_OK) {
217 return res;
218 }
219 }
220 }
221
222 *code_out = (code >> current_bit) & ((1 << code_size) - 1);
223 return LZW_OK;
224}
#define FL_ASSERT(x, MSG)
Definition assert.h:6
uint8_t byte
Definition midi_Defs.h:36
unsigned char u8
Definition s16x16x4.h:132
unsigned char u8
Definition coder.h:132
lzw_result
LZW decoding response codes.
Definition lzw.h:33
@ LZW_OK
Success.
Definition lzw.h:34
static lzw_result lzw__block_advance(struct lzw_read_ctx *ctx) FL_NOEXCEPT
Advance the context to the next sub-block in the input data.
Definition lzw.cpp.hpp:127
const fl::u8 * sb_data
Pointer to current sub-block in data.
Definition lzw.cpp.hpp:47
fl::u32 sb_bit_count
Bit count in sub-block.
Definition lzw.cpp.hpp:49
fl::size sb_bit
Current bit offset in sub-block.
Definition lzw.cpp.hpp:48
unsigned char u8
Definition stdint.h:131

References FL_ASSERT, FL_NOEXCEPT, lzw__block_advance(), and LZW_OK.

Referenced by lzw__decode(), and lzw__handle_clear().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: