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

Clean-room RAR 5.0 ("method 50") decompressor – LZ + Huffman + filters. More...

#include <stddef.h>
#include <stdint.h>
#include "ra8_err.h"
#include "ra8_rar.h"
Include dependency graph for ra8_rar5.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ra8_rar5_dtab_t
 One canonical Huffman decode table (shared by all five RAR5 alphabets). More...
struct  ra8_rar5_filter_t
 One pending RAR5 data filter recorded during decode, applied after. More...
struct  ra8_rar5_state

Typedefs

typedef struct ra8_rar5_state ra8_rar5_state_t

Enumerations

enum  ra8_rar5_dims_t : uint16_t {
  k_ra8_rar5_nc = 306U ,
  k_ra8_rar5_dc = 64U ,
  k_ra8_rar5_ldc = 16U ,
  k_ra8_rar5_rc = 44U ,
  k_ra8_rar5_bc = 20U ,
  k_ra8_rar5_huff_total = 430U ,
  k_ra8_rar5_max_filters = 16U ,
  k_ra8_rar5_refill_bytes = 512U ,
  k_ra8_rar5_delta_scratch = 512U ,
  k_ra8_rar5_old_dist = 4U
}
 Alphabet sizes and fixed scratch dimensions of the RAR5 decoder. More...
enum  ra8_rar5_filter_kind_t : uint8_t {
  k_ra8_rar5_filter_delta = 0U ,
  k_ra8_rar5_filter_e8 = 1U ,
  k_ra8_rar5_filter_e8e9 = 2U ,
  k_ra8_rar5_filter_arm = 3U
}
 The RAR5 data-filter kinds ra8_rar5_filter_t::type can take. More...

Functions

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.

Detailed Description

Clean-room RAR 5.0 ("method 50") decompressor – LZ + Huffman + filters.

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

The compressed half of the .cbr comic path. ra8_rar_next enumerates a RAR5 member and, when it is packed with a RAR compressor rather than stored verbatim, ra8_rar_extract routes the member through ra8_rar5_decompress instead of the STORE memcpy. This unit reconstructs the original bytes from the RAR 5.0 packed bitstream: a Huffman-coded LZ77 token stream (literals, length/distance matches, repeated-distance matches) followed by the optional RAR5 data filters (delta / x86-E8 / x86-E8E9 / ARM branch).

Non-solid, single-member scope (deliberate)
The decoder treats each member independently: LZ back-references resolve inside the member's own already-emitted output (which doubles as the sliding window), so no cross-member dictionary is carried. This is the shape of a non-solid archive – the default WinRAR produces and the only shape comics ship in. A back-reference that would reach before the member start (a solid archive) is rejected as malformed rather than mis-decoded; solid CBR is out of scope.
Zero heap (NASA P10 Rule 3)
All decompressor scratch – the five Huffman decode tables, the pending-filter list, the delta reorder buffer, and the streaming bit-reader refill window – lives in a caller-owned ra8_rar5_state_t (mirroring the miniz static pool the CBZ path routes through). The unpacked output goes straight into the caller's page buffer, which is also the LZ window: no separate dictionary allocation.
Bounded input (streaming)
The bit reader pulls packed bytes on demand through the archive's ra8_rar_read_fn seam into a small fixed refill window, so a multi-megabyte compressed page is decoded without ever making the packed member resident.
Licensing (clean-room, deliberate)
Written from the public RAR 5.0 format description; it vendors no code from RARLAB's unrar (whose license is non-free and forbids building a RAR-compatible archiver) and is first-party MIT, carrying no SBOM entry – the same footing as the ra8_rar_open walker it plugs into.
Note
Not thread-safe; the single-threaded reader loop serialises access.
See also
ra8_rar.h The block walker that locates the packed member.
comic.h The comic facade that turns a decoded page into pixels.
Since
Version 0.1.0

Definition in file ra8_rar5.h.

Typedef Documentation

◆ ra8_rar5_state_t

typedef struct ra8_rar5_state ra8_rar5_state_t

Enumeration Type Documentation

◆ ra8_rar5_dims_t

enum ra8_rar5_dims_t : uint16_t

Alphabet sizes and fixed scratch dimensions of the RAR5 decoder.

The four LZ alphabets (main / distance / low-distance / repeat-length) plus the bit-length pre-table are the canonical RAR 5.0 code counts; the remaining values bound the caller-owned scratch so no allocation is ever needed. k_ra8_rar5_nc is the largest alphabet and therefore the width of every decode table's symbol array.

Since
Version 0.1.0
Enumerator
k_ra8_rar5_nc 

Main alphabet size (literals+len+rep+filter).

k_ra8_rar5_dc 

Distance-slot alphabet size.

k_ra8_rar5_ldc 

Low-distance alphabet size.

k_ra8_rar5_rc 

Repeat-length alphabet size.

k_ra8_rar5_bc 

Bit-length pre-table alphabet size.

k_ra8_rar5_huff_total 

NC+DC+LDC+RC combined length-table size.

k_ra8_rar5_max_filters 

Pending data-filter records per member.

k_ra8_rar5_refill_bytes 

Streaming bit-reader packed-byte window.

k_ra8_rar5_delta_scratch 

Delta-filter reorder buffer (in-place bound).

k_ra8_rar5_old_dist 

Remembered recent match distances.

Definition at line 76 of file ra8_rar5.h.

◆ ra8_rar5_filter_kind_t

enum ra8_rar5_filter_kind_t : uint8_t

The RAR5 data-filter kinds ra8_rar5_filter_t::type can take.

Numbered exactly as the 3-bit filter-type field of the packed stream so the decode reads straight into the enum.

Since
Version 0.1.0
Enumerator
k_ra8_rar5_filter_delta 

Per-channel byte-delta de-interleave.

k_ra8_rar5_filter_e8 

x86 E8 call-target absolute->relative.

k_ra8_rar5_filter_e8e9 

x86 E8+E9 call/jmp-target transform.

k_ra8_rar5_filter_arm 

32-bit ARM BL branch-target transform.

Definition at line 137 of file ra8_rar5.h.

Function Documentation

◆ 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().