ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_rar5.c File Reference

RAR 5.0 LZ decoder driver: token loop, data filters, public entry. More...

#include "ra8_rar5.h"
#include <string.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_rar5_internal.h"
Include dependency graph for ra8_rar5.c:

Go to the source code of this file.

Functions

static void internal_copy_object (void *dst, const void *src, size_t len)
 Copy an object representation through compatible byte-pointer types.
static uint32_t internal_rd_le32 (const uint8_t *p)
 Read a little-endian uint32 from four unaligned bytes.
static void internal_wr_le32 (uint8_t *p, uint32_t v)
 Write a uint32 as four little-endian 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 uint64_t internal_decode_distance (ra8_rar5_state_t *st)
 Decode an LZ match distance from the distance / low-distance tables.
static uint32_t internal_adjust_length (uint32_t length, uint64_t dist)
 Add the RAR5 distance-dependent bias to a match length.
static void internal_push_dist (ra8_rar5_state_t *st, uint64_t dist)
 Push a fresh match distance onto the recent-distance ring.
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 uint32_t internal_read_filter_data (ra8_rar5_state_t *st)
 Read one length/offset field of a RAR5 filter descriptor.
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.
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 bool internal_x86_is_op (uint8_t op, bool e9)
 Test whether op is an x86 branch opcode this filter transforms.
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 void internal_filter_arm (uint8_t *d, uint32_t len, uint64_t filepos)
 Apply the ARM BL branch-offset filter over d.
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 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 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_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.
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 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 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_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.
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.

Variables

static const char *const s_tag_rar5 = "ra8_rar5"
 Log tag for RAR5 decoder diagnostics.

Detailed Description

RAR 5.0 LZ decoder driver: token loop, data filters, public entry.

Tag
[Ring 4 / Domain] {World: NS}

The upper half of the clean-room RAR 5.0 unpacker (paired with the entropy front-end in ra8_rar5_tables.c). It drives an LZ77 token loop over the Huffman-decoded symbol stream, writing the reconstructed bytes straight into the caller's output buffer (which is also the sliding window), then replays any recorded data filters (delta / x86 / ARM) over their output ranges.

Structure

The front-end (ra8_rar5_tables.c) supplies the four ::ra8_rar5_internal.h primitives this driver calls – priv_rar5_get, priv_rar5_decode_num, priv_rar5_read_block_header, priv_rar5_read_tables – and never calls back.

Conformance note (deliberate, verifiable scope)
The LZ + Huffman container grammar follows the published RAR 5.0 format so a genuine WinRAR-produced member decodes. The delta / x86 / ARM data filters are implemented as reversible transforms self-consistent with this codec's writer; byte-exact equivalence to WinRAR's filter output cannot be cross-checked here (no free RAR compressor exists) and comic JPEG/PNG pages never carry these filters, so that last equivalence is left to an owner-supplied real archive.
Since
Version 0.1.0

Definition in file ra8_rar5.c.

Function Documentation

◆ internal_adjust_length()

uint32_t internal_adjust_length ( uint32_t length,
uint64_t dist )
static

Add the RAR5 distance-dependent bias to a match length.

Distances above 0x100 / 0x2000 / 0x40000 add 1 / 2 / 3 to the length.

Parameters
[in]lengthBase match length.
[in]distMatch distance.
Returns
The biased match length.
Return values
lengthWhen dist <= 0x100.
Precondition
length is a decoded base length.
dist is a decoded distance.
Postcondition
No state is modified (pure function).
The result is >= length.
Note
Thread-safe: pure.
Since
Version 0.1.0

Definition at line 186 of file ra8_rar5.c.

References k_r5_dist_th1, k_r5_dist_th2, k_r5_dist_th3, and RA8_INTERNAL.

Referenced by internal_do_match().

◆ internal_apply_filters()

void internal_apply_filters ( ra8_rar5_state_t * st,
uint8_t * out,
size_t unp )
static

Replay every queued filter in stream order.

Iterates the recorded filter list front to back, applying each via internal_apply_one_filter; a no-op when no filter was recorded (the comic case).

Parameters
[in,out]stDecoder state (non-NULL).
[in,out]outDecoded output buffer (non-NULL).
[in]unpTotal unpacked length.
Returns
Nothing.
Precondition
out holds unp writable bytes.
st::filter_count <= k_ra8_rar5_max_filters.
Postcondition
Each queued filter has been applied.
No byte past unp is written.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 475 of file ra8_rar5.c.

References internal_apply_one_filter(), and RA8_INTERNAL.

Referenced by ra8_rar5_decompress().

◆ internal_apply_one_filter()

void internal_apply_one_filter ( ra8_rar5_state_t * st,
uint8_t * out,
size_t unp,
const ra8_rar5_filter_t * f )
static

Replay one queued filter over its (clamped) output range.

Clamps the filter's range to the decoded output, then dispatches to the delta / x86 / x86-e8e9 / ARM transform; a range starting past the output end is skipped.

Parameters
[in,out]stDecoder state (non-NULL).
[in,out]outDecoded output buffer (non-NULL).
[in]unpTotal unpacked length (range clamp).
[in]fFilter to apply (non-NULL).
Returns
Nothing.
Precondition
out holds unp writable bytes.
f came from internal_read_filter.
Postcondition
The output range is transformed in place, or skipped if out of range.
No byte outside [f->start, unp) is touched.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 435 of file ra8_rar5.c.

References ra8_rar5_filter_t::channels, internal_filter_arm(), internal_filter_x86(), k_ra8_rar5_filter_delta, k_ra8_rar5_filter_e8, k_ra8_rar5_filter_e8e9, ra8_rar5_filter_t::len, priv_rar5_filter_delta(), RA8_INTERNAL, ra8_rar5_filter_t::start, and ra8_rar5_filter_t::type.

Referenced by internal_apply_filters().

◆ internal_copy_object()

void internal_copy_object ( void * dst,
const void * src,
size_t len )
static

Copy an object representation through compatible byte-pointer types.

Centralizes the decoder's permitted bytewise object copy.

Parameters
[out]dstDestination spanning at least len writable bytes.
[in]srcSource spanning at least len readable bytes.
[in]lenNumber of bytes to copy.
Precondition
dst is writable for len bytes.
src is readable for len bytes and does not overlap dst.
Postcondition
The first len destination bytes equal the source bytes on entry.
No bytes outside the destination span are modified.
Note
Thread-safe when callers provide disjoint storage.
Since
Version 0.1.0

Definition at line 64 of file ra8_rar5.c.

References memcpy(), and RA8_INTERNAL.

Referenced by internal_rd_le32(), and internal_wr_le32().

◆ internal_decode_distance()

uint64_t internal_decode_distance ( ra8_rar5_state_t * st)
static

Decode an LZ match distance from the distance / low-distance tables.

Slots 0-3 give a direct distance; higher slots reconstruct the top bits from the slot and the remaining bits from either extra bits or the low-distance table.

Parameters
[in,out]stDecoder state (non-NULL).
Returns
The decoded 1-based match distance.
Return values
1For distance slot 0.
Precondition
st is a bound decoder state with the DD/LDD tables built.
st scratch tables are usable.
Postcondition
st->consumed advanced past the distance code and extras.
The result is >= 1.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 154 of file ra8_rar5.c.

References priv_rar5_decode_num(), priv_rar5_get(), and RA8_INTERNAL.

Referenced by internal_do_match().

◆ internal_decode_stream()

ra8_err_t internal_decode_stream ( ra8_rar5_state_t * st,
uint8_t * out,
size_t out_cap,
size_t unp )
static

Drive the block + token loops until unp bytes are produced.

Opens the first compressed block, then reads a fresh block header whenever the current block's bits are exhausted, decoding tokens into out until the output is complete, the last block ends, or the packed member (plus a small pad) is fully consumed. Opening the first block before the loop keeps the in-loop block check single-condition – the entry-time !have_block / consumed >= block_end pair was correlated (on the first pass block_end is still zero) and so could never reach MC/DC; hoisting the open removes that correlated compound decision.

Parameters
[in,out]stDecoder state (non-NULL).
[in,out]outOutput/window buffer (non-NULL).
[in]out_capCapacity of out in bytes.
[in]unpTarget unpacked length (<= out_cap, > 0).
Returns
ra8_err_t status.
Return values
k_ra8_okExactly unp bytes were produced.
k_ra8_err_validation_failedTruncated / malformed stream, short output.
Precondition
out holds out_cap writable bytes, unp <= out_cap.
st is a freshly reset decoder state and unp > 0.
Postcondition
On k_ra8_ok, out[0..unp) holds the decoded bytes.
On error the output is incomplete.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 696 of file ra8_rar5.c.

References internal_decode_token(), internal_open_block(), k_r5_byte_bits, k_r5_max_pad_bits, k_ra8_err_validation_failed, and k_ra8_ok.

Referenced by ra8_rar5_decompress().

◆ internal_decode_token()

ra8_err_t internal_decode_token ( ra8_rar5_state_t * st,
uint8_t * out,
size_t * out_pos,
size_t unp )
static

Decode one LZ token: literal, match, repeat-match, or filter.

Classifies the main symbol: below 256 is a literal byte, 256 a filter, 257 the last-match repeat, 258-261 a remembered-distance match, 262+ a length-slot match.

Parameters
[in,out]stDecoder state (non-NULL).
[in,out]outOutput/window buffer (non-NULL).
[in,out]out_posCurrent output length; advanced (non-NULL).
[in]unpTarget unpacked length.
Returns
ra8_err_t status.
Return values
k_ra8_okOne token was decoded.
k_ra8_err_validation_failedA malformed match or filter.
Precondition
st has the LZ tables built.
*out_pos < unp.
Postcondition
On k_ra8_ok, output/filters advanced by exactly one token.
On error no partial token corrupts prior output.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 609 of file ra8_rar5.c.

References internal_do_match(), internal_do_repdist(), internal_do_replast(), internal_read_filter(), k_r5_sym_filter, k_r5_sym_lenbase, k_r5_sym_replast, k_ra8_ok, and priv_rar5_decode_num().

Referenced by internal_decode_stream().

◆ internal_decompress_check()

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 )
static

Validate the non-output arguments of ra8_rar5_decompress.

Null-checks the archive, output, and scratch pointers, then rejects a non-RAR5 archive, an output buffer smaller than the unpacked size, and a zero packed size. Split out so the entry point stays within the function-size budget.

Parameters
[in]rarArchive to decode from.
[in]outOutput buffer.
[in]stDecoder scratch.
[in]out_capOutput-buffer capacity in bytes.
[in]unp_sizeExpected unpacked length.
[in]pack_sizePacked member length.
Returns
ra8_err_t status.
Return values
k_ra8_okArguments are usable.
k_ra8_err_null_ptrrar, out, or st was NULL.
k_ra8_err_invalid_staterar is not a RAR5 archive.
k_ra8_err_no_memout_cap is smaller than unp_size.
k_ra8_err_validation_failedpack_size is zero.
Precondition
got was already validated and cleared by the caller.
The caller forwards its arguments unchanged.
Postcondition
On k_ra8_ok every pointer is safe to dereference.
No state is modified.
Note
Not thread-safe (reads rar fields).
Since
Version 0.1.0

Definition at line 754 of file ra8_rar5.c.

References k_ra8_err_invalid_state, k_ra8_err_no_mem, k_ra8_err_validation_failed, k_ra8_ok, k_ra8_rar_ver_5, RA8_CHECK_NULL_PTR, RA8_INTERNAL, s_tag_rar5, and ra8_rar_t::version.

Referenced by ra8_rar5_decompress().

◆ internal_do_match()

ra8_err_t internal_do_match ( ra8_rar5_state_t * st,
uint32_t slot,
uint8_t * out,
size_t * out_pos,
size_t unp )
static

Decode a length-slot LZ match (main symbol >= 262) into out.

Reads the length from the slot, the distance from the DD/LDD tables, applies the distance-length bias, remembers the distance, and copies the match into the output window.

Parameters
[in,out]stDecoder state (non-NULL).
[in]slotMain symbol (>= k_r5_sym_lenbase).
[in,out]outOutput/window buffer (non-NULL).
[in,out]out_posCurrent output length; advanced (non-NULL).
[in]unpTarget unpacked length.
Returns
ra8_err_t status.
Return values
k_ra8_okThe match was copied.
k_ra8_err_validation_failedAn invalid back-distance.
Precondition
st has the LZ tables built.
*out_pos <= unp.
Postcondition
On k_ra8_ok, *out_pos advanced and the recent-distance ring updated.
On error no output byte is written.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 506 of file ra8_rar5.c.

References internal_adjust_length(), internal_decode_distance(), internal_push_dist(), internal_slot_to_length(), k_r5_sym_lenbase, k_ra8_err_validation_failed, k_ra8_ok, and priv_rar5_copy_match().

Referenced by internal_decode_token().

◆ internal_do_repdist()

ra8_err_t internal_do_repdist ( ra8_rar5_state_t * st,
uint32_t slot,
uint8_t * out,
size_t * out_pos,
size_t unp )
static

Decode a remembered-distance LZ match (main symbols 258..261) into out.

Selects one of the four remembered distances, promotes it to most-recent, reads a repeat length from the RD table, and copies the match.

Parameters
[in,out]stDecoder state (non-NULL).
[in]slotMain symbol in 258..261.
[in,out]outOutput/window buffer (non-NULL).
[in,out]out_posCurrent output length; advanced (non-NULL).
[in]unpTarget unpacked length.
Returns
ra8_err_t status.
Return values
k_ra8_okThe match was copied.
k_ra8_err_validation_failedAn invalid back-distance.
Precondition
st has the LZ tables built.
*out_pos <= unp.
Postcondition
On k_ra8_ok, the chosen distance is promoted to most-recent.
On error no output byte is written.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 540 of file ra8_rar5.c.

References internal_slot_to_length(), k_r5_sym_repdist0, k_ra8_err_validation_failed, k_ra8_ok, priv_rar5_copy_match(), and priv_rar5_decode_num().

Referenced by internal_decode_token().

◆ internal_do_replast()

ra8_err_t internal_do_replast ( ra8_rar5_state_t * st,
uint8_t * out,
size_t * out_pos,
size_t unp )
static

Replay the last match (main symbol 257) into out.

Copies the most-recent match's length at the most-recent distance; a no-op when no match has been seen yet (last length is zero).

Parameters
[in,out]stDecoder state (non-NULL).
[in,out]outOutput/window buffer (non-NULL).
[in,out]out_posCurrent output length; advanced (non-NULL).
[in]unpTarget unpacked length.
Returns
ra8_err_t status.
Return values
k_ra8_okThe repeat was copied (or was a no-op).
k_ra8_err_validation_failedAn invalid back-distance.
Precondition
st is a bound decoder state.
*out_pos <= unp.
Postcondition
On k_ra8_ok, *out_pos advanced by the last length (0 if none yet).
On error no output byte is written.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 577 of file ra8_rar5.c.

References k_ra8_err_validation_failed, k_ra8_ok, and priv_rar5_copy_match().

Referenced by internal_decode_token().

◆ internal_filter_arm()

void internal_filter_arm ( uint8_t * d,
uint32_t len,
uint64_t filepos )
static

Apply the ARM BL branch-offset filter over d.

For each 4-byte word whose top byte is the BL opcode, subtracts the word position from the 24-bit branch offset – the inverse of the writer's add.

Parameters
[in,out]dOutput range to transform (non-NULL).
[in]lenRange length in bytes.
[in]fileposAbsolute output offset of d[0].
Returns
Nothing.
Precondition
d holds len writable bytes.
len >= 4 to transform anything.
Postcondition
Each BL offset is relative-decoded in place.
Non-BL words are unchanged.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 397 of file ra8_rar5.c.

References k_r5_arm_bl, k_r5_arm_off_mask, k_r5_byte_bits, k_r5_byte_mask, and RA8_INTERNAL.

Referenced by internal_apply_one_filter().

◆ internal_filter_x86()

void internal_filter_x86 ( uint8_t * d,
uint32_t len,
uint64_t filepos,
bool e9 )
static

Apply the x86 CALL/JMP relative-address filter over d.

For each transformed branch, subtracts the operand's stream position from the stored 32-bit operand – the inverse of the writer's add.

Parameters
[in,out]dOutput range to transform (non-NULL).
[in]lenRange length in bytes.
[in]fileposAbsolute output offset of d[0].
[in]e9Whether 0xE9 JMP is transformed too.
Returns
Nothing.
Precondition
d holds len writable bytes.
len fits an x86 instruction (>= 5) to transform anything.
Postcondition
Each transformed operand is relative-decoded in place.
Non-branch bytes are unchanged.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 363 of file ra8_rar5.c.

References internal_rd_le32(), internal_wr_le32(), internal_x86_is_op(), k_r5_x86_ilen, and RA8_INTERNAL.

Referenced by internal_apply_one_filter().

◆ internal_open_block()

ra8_err_t internal_open_block ( ra8_rar5_state_t * st,
uint64_t * end_bit,
bool * last )
static

Open the next compressed block: header, tables, and its bit-end.

Reads and validates the block header, rejects a zero-size block, computes the block's end bit position, and (re)builds the Huffman tables when the block carries them – else requires that a prior block already did.

Parameters
[in,out]stDecoder state (non-NULL).
[out]end_bitReceives the block's absolute end bit position (non-NULL).
[out]lastReceives whether this is the last block (non-NULL).
Returns
ra8_err_t status.
Return values
k_ra8_okBlock opened and tables ready.
k_ra8_err_validation_failedA bad header, zero-size block, or no tables.
Precondition
st is a bound decoder state.
end_bit and last are writable.
Postcondition
On k_ra8_ok, *end_bit is the block's end and tables are usable.
On error the decode is abandoned.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 648 of file ra8_rar5.c.

References k_r5_byte_bits, k_ra8_err_validation_failed, k_ra8_ok, r5_block_t::last, r5_block_t::last_bits, priv_rar5_read_block_header(), priv_rar5_read_tables(), r5_block_t::size, and r5_block_t::tables.

Referenced by internal_decode_stream().

◆ internal_push_dist()

void internal_push_dist ( ra8_rar5_state_t * st,
uint64_t dist )
static

Push a fresh match distance onto the recent-distance ring.

Shifts the four remembered distances down by one and stores dist at the front, so a later remembered-distance symbol can reuse it.

Parameters
[in,out]stDecoder state (non-NULL).
[in]distDistance to remember.
Returns
Nothing.
Precondition
st is a bound decoder state.
st::old_dist has k_ra8_rar5_old_dist entries.
Postcondition
st->old_dist[0] == dist and the older entries shift down.
The oldest remembered distance is discarded.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 215 of file ra8_rar5.c.

References k_ra8_rar5_old_dist, and RA8_INTERNAL.

Referenced by internal_do_match().

◆ internal_rd_le32()

uint32_t internal_rd_le32 ( const uint8_t * p)
static

Read a little-endian uint32 from four unaligned bytes.

memcpy-based so the source may sit at any alignment on a little-endian host/target.

Parameters
[in]pPointer to four readable bytes (non-NULL).
Returns
The decoded value.
Return values
0When all four bytes are zero.
Precondition
p addresses at least four readable bytes.
The host is little-endian.
Postcondition
No state is modified (pure read).
The result is a pure function of the four bytes.
Note
Thread-safe: pure read.
Since
Version 0.1.0

Definition at line 85 of file ra8_rar5.c.

References internal_copy_object(), and RA8_INTERNAL.

Referenced by internal_filter_x86().

◆ internal_read_filter()

ra8_err_t internal_read_filter ( ra8_rar5_state_t * st,
size_t out_pos )
static

Read one filter descriptor and queue it for post-decode replay.

Records the transform's absolute output start (relative offset plus the current output position), its length, kind, and delta channel count.

Parameters
[in,out]stDecoder state (non-NULL).
[in]out_posCurrent output position (filter start base).
Returns
ra8_err_t status.
Return values
k_ra8_okThe filter was queued.
k_ra8_err_validation_failedThe filter list is full or the kind is invalid.
Precondition
st is a bound decoder state.
out_pos is the current output length.
Postcondition
On k_ra8_ok, st->filter_count incremented by one.
st->consumed advanced past the descriptor.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 281 of file ra8_rar5.c.

References ra8_rar5_filter_t::channels, internal_read_filter_data(), k_r5_fchan_bits, k_r5_ftype_bits, k_ra8_err_validation_failed, k_ra8_ok, k_ra8_rar5_filter_arm, k_ra8_rar5_filter_delta, k_ra8_rar5_max_filters, ra8_rar5_filter_t::len, priv_rar5_get(), RA8_INTERNAL, ra8_rar5_filter_t::start, and ra8_rar5_filter_t::type.

Referenced by internal_decode_token().

◆ internal_read_filter_data()

uint32_t internal_read_filter_data ( ra8_rar5_state_t * st)
static

Read one length/offset field of a RAR5 filter descriptor.

A 2-bit byte count selects 1..4 little-endian bytes of the value.

Parameters
[in,out]stDecoder state (non-NULL).
Returns
The decoded field value.
Return values
0When the encoded bytes are all zero.
Precondition
st is a bound decoder state at a filter descriptor.
st has bits remaining or pads with zero.
Postcondition
st->consumed advanced past the field.
The result fits 32 bits.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 255 of file ra8_rar5.c.

References k_r5_byte_bits, priv_rar5_get(), and RA8_INTERNAL.

Referenced by internal_read_filter().

◆ internal_slot_to_length()

uint32_t internal_slot_to_length ( ra8_rar5_state_t * st,
uint32_t slot )
static

Convert an LZ length slot into a match length, reading any extra bits.

Slots 0-7 map to lengths 2-9 directly; higher slots add (4 | slot&3) << (slot/4 - 1) plus that many extra bits.

Parameters
[in,out]stDecoder state (non-NULL).
[in]slotLength slot value.
Returns
The decoded match length.
Return values
2For length slot 0.
Precondition
st is a bound decoder state.
slot is a valid length slot.
Postcondition
st->consumed advanced by the extra-bit count.
The result is >= 2.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 127 of file ra8_rar5.c.

References priv_rar5_get(), and RA8_INTERNAL.

Referenced by internal_do_match(), and internal_do_repdist().

◆ internal_wr_le32()

void internal_wr_le32 ( uint8_t * p,
uint32_t v )
static

Write a uint32 as four little-endian bytes.

memcpy-based so the destination may sit at any alignment.

Parameters
[out]pPointer to four writable bytes (non-NULL).
[in]vValue to store.
Returns
Nothing.
Precondition
p addresses at least four writable bytes.
The host is little-endian.
Postcondition
p[0..4) holds v in little-endian order.
No other state is modified.
Note
Thread-safe: writes only through p.
Since
Version 0.1.0

Definition at line 105 of file ra8_rar5.c.

References internal_copy_object(), and RA8_INTERNAL.

Referenced by internal_filter_x86().

◆ internal_x86_is_op()

bool internal_x86_is_op ( uint8_t op,
bool e9 )
static

Test whether op is an x86 branch opcode this filter transforms.

CALL (0xE8) always; JMP (0xE9) only when e9 is set (E8E9 variant).

Parameters
[in]opInstruction opcode byte.
[in]e9Whether 0xE9 is also transformed.
Returns
Whether op is a transformed branch.
Return values
trueop is CALL, or JMP with e9 set.
falseAny other opcode.
Precondition
op is the candidate opcode byte.
e9 selects the E8E9 variant.
Postcondition
No state is modified (pure function).
Only 0xE8 / (0xE9 with e9) return true.
Note
Thread-safe: pure.
Since
Version 0.1.0

Definition at line 339 of file ra8_rar5.c.

References k_r5_x86_call, k_r5_x86_jmp, and RA8_INTERNAL.

Referenced by internal_filter_x86().

◆ priv_rar5_copy_match()

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.

Copy an LZ match of length bytes at back-distance dist into out.

Definition at line 225 of file ra8_rar5.c.

Referenced by internal_do_match(), internal_do_repdist(), and internal_do_replast().

◆ priv_rar5_filter_delta()

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.

Apply the per-channel byte-delta filter over d.

Definition at line 307 of file ra8_rar5.c.

References k_ra8_rar5_delta_scratch, and memcpy().

Referenced by internal_apply_one_filter().

◆ ra8_rar5_decompress()

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 )
nodiscard

Decompress one RAR5-packed member into the caller's output buffer.

Streams the packed bytes at [data_off, data_off + pack_size) through the archive reader, decodes the RAR 5.0 Huffman-coded LZ token stream into out (which is also the LZ sliding window), then replays any filters the stream recorded. Produces exactly unp_size bytes on success. Malformed, truncated, or hostile input is rejected without reading or writing out of bounds – never a crash.

Parameters
[in]rarArchive bound by ra8_rar_open (non-NULL).
[in]data_offAbsolute offset of the packed member data (< rar->size).
[in]pack_sizePacked member length in bytes (> 0).
[out]outDestination and LZ window (non-NULL, out_cap writable).
[in]out_capCapacity of out in bytes; must be >= unp_size.
[in]unp_sizeExpected unpacked length in bytes.
[in,out]stCaller-owned decoder scratch (non-NULL).
[out]gotReceives bytes written (non-NULL).
Returns
ra8_err_t Error code.
Return values
k_ra8_okMember decoded; *got == unp_size.
k_ra8_err_null_ptrA required pointer argument was NULL.
k_ra8_err_invalid_staterar was never bound by ra8_rar_open.
k_ra8_err_no_memout_cap is smaller than unp_size.
k_ra8_err_validation_failedMalformed / truncated / solid-reference stream.
Precondition
rar was populated by ra8_rar_open (version 5).
out holds at least out_cap writable bytes.
Postcondition
On k_ra8_ok, out[0..*got) holds the member's original bytes.
On any error *got == 0 and out contents are unspecified.
Note
Not thread-safe; drives the archive reader and mutates st.
See also
ra8_rar_extract()
Since
Version 0.1.0

Definition at line 776 of file ra8_rar5.c.

References internal_apply_filters(), internal_decode_stream(), internal_decompress_check(), k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag_rar5.

Referenced by ra8_rar_extract().

Variable Documentation

◆ s_tag_rar5

const char* const s_tag_rar5 = "ra8_rar5"
static

Log tag for RAR5 decoder diagnostics.

Definition at line 49 of file ra8_rar5.c.

Referenced by internal_decompress_check(), and ra8_rar5_decompress().