66 (void)
memcpy(dst, src, len);
129 uint32_t length = 2U;
131 return length + slot;
133 const uint32_t lbits = (slot / 4U) - 1U;
134 length += (4U | (slot & 3U)) << lbits;
158 return (uint64_t)1U + slot;
160 const uint32_t dbits = (slot / 2U) - 1U;
161 uint64_t dist = UINT64_C(1) + ((UINT64_C(2) | (uint64_t)(slot & 1U)) << dbits);
188 uint32_t adjusted = length;
218 st->old_dist[i] = st->old_dist[i - 1U];
220 st->old_dist[0] = dist;
227 size_t pos = *out_pos;
228 if ((dist == 0U) || (dist > (uint64_t)pos)) {
231 const size_t back = (size_t)dist;
232 for (uint32_t k = 0U; (k < length) && (pos < unp); ++k) {
233 out[pos] = out[pos - back];
259 for (uint32_t i = 0U; i < bc; ++i) {
292 uint32_t channels = 1U;
297 f->
start = (uint64_t)out_pos + (uint64_t)rel;
299 f->
type = (uint8_t)type;
301 st->filter_count += 1U;
312 (void)
memcpy(st->delta, d, (
size_t)len);
314 for (uint32_t ch = 0U; ch < channels; ++ch) {
316 for (uint32_t i = ch; i < len; i += channels) {
317 prev = (uint8_t)(prev - st->delta[dpos]);
372 const uint32_t off = i + 1U;
373 const uint32_t pos = (uint32_t)(filepos + (uint64_t)off);
402 const uint32_t limit = len - 4U;
406 uint32_t v = (uint32_t)d[i] | ((uint32_t)d[i + 1U] <<
k_r5_byte_bits) |
408 const uint32_t p = (uint32_t)((filepos + (uint64_t)i) >> 2U);
440 if (f->
start >= (uint64_t)unp) {
443 const uint64_t avail = (uint64_t)unp - f->
start;
444 const uint32_t len = ((uint64_t)f->
len > avail) ? (uint32_t)avail : f->
len;
448 uint8_t* d = &out[(size_t)f->
start];
477 for (uint16_t f = 0U; f < st->filter_count; ++f) {
512 st->last_length = length;
543 const uint64_t dist = st->old_dist[idx];
544 for (uint32_t i = idx; i > 0U; --i) {
545 st->old_dist[i] = st->old_dist[i - 1U];
547 st->old_dist[0] = dist;
550 st->last_length = length;
579 if (st->last_length == 0U) {
613 out[*out_pos] = (uint8_t)slot;
655 if (blk.
size == 0U) {
658 const uint64_t start = st->consumed;
664 if (!st->tables_ready) {
701 uint64_t block_end = 0U;
707 while ((out_pos < unp) && (st->consumed <= cap_bits)) {
708 if (st->consumed >= block_end) {
723 if (out_pos != unp) {
767 if (unp_size > (uint64_t)out_cap) {
770 if (pack_size == 0U) {
794 st->packlen = pack_size;
795 if (unp_size == 0U) {
803 *got = (size_t)unp_size;
Annotation-attribute framework macros for ra8-firmware.
#define RA8_PRIV
Module-private helper: shared across TUs but only inside one library.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
@ k_ra8_err_validation_failed
Validation rule failed (caller-supplied invariant not satisfied).
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
static uint32_t internal_rd_le32(const uint8_t *p)
Read a little-endian uint32 from four unaligned bytes.
static uint32_t internal_slot_to_length(ra8_rar5_state_t *st, uint32_t slot)
Convert an LZ length slot into a match length, reading any extra bits.
static void internal_wr_le32(uint8_t *p, uint32_t v)
Write a uint32 as four little-endian bytes.
static void internal_apply_one_filter(ra8_rar5_state_t *st, uint8_t *out, size_t unp, const ra8_rar5_filter_t *f)
Replay one queued filter over its (clamped) output range.
static ra8_err_t internal_decompress_check(const ra8_rar_t *rar, const uint8_t *out, const ra8_rar5_state_t *st, size_t out_cap, uint64_t unp_size, uint64_t pack_size)
Validate the non-output arguments of ra8_rar5_decompress.
static uint64_t internal_decode_distance(ra8_rar5_state_t *st)
Decode an LZ match distance from the distance / low-distance tables.
ra8_err_t ra8_rar5_decompress(const ra8_rar_t *rar, uint64_t data_off, uint64_t pack_size, uint8_t *out, size_t out_cap, uint64_t unp_size, ra8_rar5_state_t *st, size_t *got)
Decompress one RAR5-packed member into the caller's output buffer.
static void internal_push_dist(ra8_rar5_state_t *st, uint64_t dist)
Push a fresh match distance onto the recent-distance ring.
static ra8_err_t internal_open_block(ra8_rar5_state_t *st, uint64_t *end_bit, bool *last)
Open the next compressed block: header, tables, and its bit-end.
static void internal_apply_filters(ra8_rar5_state_t *st, uint8_t *out, size_t unp)
Replay every queued filter in stream order.
static ra8_err_t internal_do_match(ra8_rar5_state_t *st, uint32_t slot, uint8_t *out, size_t *out_pos, size_t unp)
Decode a length-slot LZ match (main symbol >= 262) into out.
static void internal_filter_arm(uint8_t *d, uint32_t len, uint64_t filepos)
Apply the ARM BL branch-offset filter over d.
static ra8_err_t internal_decode_token(ra8_rar5_state_t *st, uint8_t *out, size_t *out_pos, size_t unp)
Decode one LZ token: literal, match, repeat-match, or filter.
static void internal_filter_x86(uint8_t *d, uint32_t len, uint64_t filepos, bool e9)
Apply the x86 CALL/JMP relative-address filter over d.
static ra8_err_t internal_decode_stream(ra8_rar5_state_t *st, uint8_t *out, size_t out_cap, size_t unp)
Drive the block + token loops until unp bytes are produced.
static ra8_err_t internal_do_repdist(ra8_rar5_state_t *st, uint32_t slot, uint8_t *out, size_t *out_pos, size_t unp)
Decode a remembered-distance LZ match (main symbols 258..261) into out.
static ra8_err_t internal_read_filter(ra8_rar5_state_t *st, size_t out_pos)
Read one filter descriptor and queue it for post-decode replay.
static uint32_t internal_adjust_length(uint32_t length, uint64_t dist)
Add the RAR5 distance-dependent bias to a match length.
static uint32_t internal_read_filter_data(ra8_rar5_state_t *st)
Read one length/offset field of a RAR5 filter descriptor.
bool priv_rar5_copy_match(uint8_t *out, size_t *out_pos, size_t unp, uint32_t length, uint64_t dist)
Implementation of priv_rar5_copy_match() – self-overlapping back-copy.
static bool internal_x86_is_op(uint8_t op, bool e9)
Test whether op is an x86 branch opcode this filter transforms.
static void internal_copy_object(void *dst, const void *src, size_t len)
Copy an object representation through compatible byte-pointer types.
void priv_rar5_filter_delta(ra8_rar5_state_t *st, uint8_t *d, uint32_t len, uint32_t channels)
Implementation of priv_rar5_filter_delta() – per-channel running byte-sum.
static const char *const s_tag_rar5
Log tag for RAR5 decoder diagnostics.
static ra8_err_t internal_do_replast(ra8_rar5_state_t *st, uint8_t *out, size_t *out_pos, size_t unp)
Replay the last match (main symbol 257) into out.
Clean-room RAR 5.0 ("method 50") decompressor – LZ + Huffman + filters.
@ k_ra8_rar5_max_filters
Pending data-filter records per member.
@ k_ra8_rar5_delta_scratch
Delta-filter reorder buffer (in-place bound).
@ k_ra8_rar5_old_dist
Remembered recent match distances.
@ k_ra8_rar5_filter_delta
Per-channel byte-delta de-interleave.
@ k_ra8_rar5_filter_arm
32-bit ARM BL branch-target transform.
@ k_ra8_rar5_filter_e8e9
x86 E8+E9 call/jmp-target transform.
@ k_ra8_rar5_filter_e8
x86 E8 call-target absolute->relative.
Cross-TU seam between the RAR5 entropy front-end and the LZ decoder.
ra8_err_t priv_rar5_read_tables(ra8_rar5_state_t *st)
Parse a table block: build the BD pre-table then the four LZ tables.
uint32_t priv_rar5_get(ra8_rar5_state_t *st, uint32_t n)
Peek and consume n bits from the streaming reader in one step.
@ k_r5_x86_ilen
CALL/JMP instruction width.
@ k_r5_arm_bl
ARM BL opcode byte.
@ k_r5_x86_jmp
x86 near JMP opcode.
@ k_r5_x86_call
x86 near CALL opcode.
@ k_r5_byte_mask
Single-byte mask.
uint32_t priv_rar5_decode_num(ra8_rar5_state_t *st, const ra8_rar5_dtab_t *d)
Decode one Huffman symbol from d, consuming its code bits.
@ k_r5_byte_bits
Bits per packed byte.
ra8_err_t priv_rar5_read_block_header(ra8_rar5_state_t *st, r5_block_t *b)
Read and validate one RAR5 block header at the current bit position.
@ k_r5_sym_filter
Read one data filter.
@ k_r5_sym_lenbase
First LZ length slot.
@ k_r5_sym_replast
Repeat the last match.
@ k_r5_sym_repdist0
First remembered distance.
@ k_r5_arm_off_mask
ARM BL 24-bit word offset.
@ k_r5_ftype_bits
Filter-type field width.
@ k_r5_fchan_bits
Delta channel-count field width.
@ k_r5_max_pad_bits
Bit slack past the packed member end.
@ k_r5_dist_th2
+1 more above this distance.
@ k_r5_dist_th3
+1 more above this distance.
@ k_r5_dist_th1
+1 length above this distance.
@ k_ra8_rar_ver_5
RAR 5.0 block format ("RAR5").
Decoded fields of one RAR5 compressed-block header.
uint32_t last_bits
Valid bits in the block's last byte.
bool last
Block is the last in the file.
bool tables
Block carries fresh Huffman tables.
uint64_t size
Block size in bytes from BlockStart.
One pending RAR5 data filter recorded during decode, applied after.
uint8_t channels
Delta channel count (1..32); unused otherwise.
uint32_t len
Length of the transformed range in bytes.
uint8_t type
Filter kind (ra8_rar5_filter_kind_t).
uint64_t start
Absolute output offset the filter transforms from.
Caller-owned zero-heap scratch for one ra8_rar5_decompress call.
One open RAR archive: the backing plus the detected generation.
ra8_rar_version_t version
Detected container generation.