Skip to content

Commit 177fc26

Browse files
author
Grok Compression
committed
close mercury fast-path eligibility gaps
mercury now takes precincts smaller than the code-block (B.7 clamp), per-component coding styles (COC), main-header progression order changes (POC), and subsampled components in both composite and band callback modes. the matching grok bails are gone. mercury rejects POC and RGN markers found in tile-part headers, which it used to ignore and mis-decode, and grok bails on PPM, RGN, mixed wavelet kernels, and MCT over a subsampled component. seven 9/7 md5 and baseline references move by 1-2 LSB now that those files decode through mercury (issue142, issue411-ycc420/422, _00042, subsampling_1/2, zoo1/2); references are updated separately.
1 parent a2e2785 commit 177fc26

17 files changed

Lines changed: 3479 additions & 388 deletions

‎mercury/README.md‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ single-threaded (no locks inside nodes) and every ring is genuinely SPSC.
7676
loops dispatch through [ffi_dwt.rs](src/ffi_dwt.rs) to the Highway kernels.
7777
- **Merge sink** — joins components (and tile columns), applies the inverse
7878
RCT/ICT when signalled, and hands finished image rows to the host via the
79-
row callback.
79+
row callback. Components with their own `XRsiz`/`YRsiz` emit rows at
80+
different rates, so they take a per-component sink instead, which carries no
81+
color transform (grok skips the MCT on components of different sizes too).
8082

8183
Multi-tile images decode one tile *row* at a time: all tiles of a tile row
8284
run concurrently, tile rows run in sequence with a fresh graph each, so peak
@@ -112,7 +114,9 @@ Grok drives the engine through [include/mercury_capi.h](include/mercury_capi.h):
112114
decodes the image, calling `t1_fn` per code-block and `row_fn` for each finished
113115
full-width row (in order). The i16 entry avoids an i32 staging row when
114116
the final samples fit signed i16. A null `t1_fn` is rejected. The host
115-
must supply tier-1.
117+
must supply tier-1. Components of different sizes have no full-width row,
118+
so those plans take `mercury_weave_comps{,_i16}`, which delivers one
119+
component row per call.
116120

117121
[examples/capi_smoke.c](examples/capi_smoke.c) exercises all three surfaces.
118122

@@ -140,7 +144,7 @@ tile, 9 levels, ~3 GB decoded):
140144
classic whole-image pipeline.
141145
- Fast-path output is byte-identical to the classic pipeline on the
142146
reversible corpus (5/3, all precisions), across multi-tile, multi-component
143-
(RCT), and subsampling-free images.
147+
(RCT), and subsampled images.
144148
- Irreversible 9/7 matches OpenJPEG within final rounding (≤ 1 LSB, i.e.
145149
spec-correct); different valid 9/7 inverse implementations disagree at the
146150
±1 LSB level.
@@ -178,6 +182,7 @@ classic pipeline.
178182
- Full-resolution, full-image decode only. No `-reduce` / decode-window /
179183
region decode (the host handles those on its classic path).
180184
- Rejected at plan time (returned as errors, never mis-decoded, so the host
181-
falls back): COC/POC markers, derived quantization, component subsampling,
182-
precincts smaller than code-blocks, HT/BYPASS/RESTART code-block modes.
185+
falls back): tile-part POC markers, mixed wavelet kernels across components,
186+
derived quantization, precincts smaller than code-blocks,
187+
HT/BYPASS/RESTART code-block modes.
183188
- Decode-only; the host owns compression, color management, and output.

‎mercury/include/mercury_capi.h‎

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ typedef void (*mercury_row_fn)(void* ctx, uint32_t row, const int32_t* const* co
5454
typedef void (*mercury_row_i16_fn)(void* ctx, uint32_t row, const int16_t* const* comps,
5555
uint32_t num_comps, uint64_t width);
5656

57+
/* One component row. samples points at width samples of component comp, valid
58+
* only during the call. Rows of one component arrive in order; components
59+
* interleave in no fixed order. Same value conventions as mercury_row_fn. */
60+
typedef void (*mercury_comp_row_fn)(void* ctx, uint32_t comp, uint32_t row, const int32_t* samples,
61+
uint64_t width);
62+
typedef void (*mercury_comp_row_i16_fn)(void* ctx, uint32_t comp, uint32_t row,
63+
const int16_t* samples, uint64_t width);
64+
5765
/* Main header, parsed by the host codec and handed in; mercury does not parse
5866
* it. Every pointer is borrowed for the mercury_warp_loom{,_fd} call only;
5967
* mercury copies what it keeps. */
@@ -88,6 +96,33 @@ typedef struct MercuryQccOverride
8896
MercuryQuant quant;
8997
} MercuryQccOverride;
9098

99+
/* One component's coding style (COC), replacing the COD fields below for that
100+
* component: everything T.800 A.6.2 lets a component carry of its own. */
101+
typedef struct MercuryCocOverride
102+
{
103+
uint32_t comp;
104+
uint8_t num_levels;
105+
uint32_t block_width, block_height;
106+
uint32_t modes;
107+
bool reversible;
108+
const MercuryPrecinct* precincts; /* nullptr => default 2^15 x 2^15 */
109+
uint32_t num_precincts;
110+
} MercuryCocOverride;
111+
112+
/* One POC progression volume (T.800 A.6.6): layers [0, lay_e), resolutions
113+
* [res_s, res_e), components [comp_s, comp_e), every precinct, walked in
114+
* order. Volumes are concatenated; a packet an earlier volume already emitted
115+
* is skipped. */
116+
typedef struct MercuryProgressionVolume
117+
{
118+
uint8_t res_s;
119+
uint16_t comp_s;
120+
uint16_t lay_e;
121+
uint8_t res_e;
122+
uint16_t comp_e;
123+
uint8_t order; /* 0=LRCP 1=RLCP 2=RPCL 3=PCRL 4=CPRL */
124+
} MercuryProgressionVolume;
125+
91126
/* One tile-part's position, from the host's parsed TLM markers. */
92127
typedef struct MercuryTlmEntry
93128
{
@@ -115,6 +150,14 @@ typedef struct MercuryMainHeader
115150
MercuryQuant qcd;
116151
const MercuryQccOverride* qcc;
117152
uint32_t num_qcc;
153+
/* Per-component coding style overrides; the COD fields above are the default
154+
* for every component no COC names. */
155+
const MercuryCocOverride* coc;
156+
uint32_t num_coc;
157+
/* Main-header POC volume list, in order; NULL/0 means the COD order covers
158+
* the whole tile. */
159+
const MercuryProgressionVolume* poc;
160+
uint32_t num_poc;
118161
/* Codestream layout in the file the read_at/fd addresses. */
119162
uint64_t codestream_off; /* absolute file offset of the SOC marker */
120163
uint64_t first_sot_off; /* absolute file offset of the first SOT marker */
@@ -156,7 +199,8 @@ MercuryPlan* mercury_warp_loom_fd(const MercuryMainHeader* hdr, const MercuryDec
156199
int32_t fd, uint8_t* err_buf, size_t err_cap);
157200
#endif
158201

159-
/* width/height are the decoded output dims, i.e. already reduced. */
202+
/* width/height are the decoded output dims on the canvas plane, i.e. already
203+
* reduced. Per-component dims come from mercury_loom_comp_info. */
160204
typedef struct MercuryImageInfo
161205
{
162206
uint32_t width;
@@ -166,8 +210,10 @@ typedef struct MercuryImageInfo
166210
} MercuryImageInfo;
167211

168212
int32_t mercury_loom_info(const MercuryPlan* plan, MercuryImageInfo* out);
213+
/* width/height are that component's own reduced output dims: a subsampled
214+
* component is smaller than MercuryImageInfo. Any out pointer may be NULL. */
169215
int32_t mercury_loom_comp_info(const MercuryPlan* plan, uint32_t comp, uint32_t* prec,
170-
int32_t* is_signed);
216+
int32_t* is_signed, uint32_t* width, uint32_t* height);
171217
void mercury_unwarp_loom(MercuryPlan* plan);
172218

173219
/* t1 NULL = built-in coder in the standalone build; the extern-kernels
@@ -179,6 +225,17 @@ int32_t mercury_weave(MercuryPlan* plan, mercury_t1_fn t1, mercury_row_fn row_fn
179225
int32_t mercury_weave_i16(MercuryPlan* plan, mercury_t1_fn t1, mercury_row_i16_fn row_fn,
180226
void* row_ctx, uint32_t threads);
181227

228+
/* Per-component row delivery. mercury_weave{,_i16} return MERCURY_EBADARG on a
229+
* plan whose components differ in subsampling, because one joint row cannot
230+
* carry components of different sizes; these entries take that plan. They also
231+
* take a plan whose components share a rectangle, unless the codestream
232+
* signals a color transform over components 0-2 (only the joint entry carries
233+
* that, and mercury_weave_comps* then return MERCURY_EDECODE). */
234+
int32_t mercury_weave_comps(MercuryPlan* plan, mercury_t1_fn t1, mercury_comp_row_fn row_fn,
235+
void* row_ctx, uint32_t threads);
236+
int32_t mercury_weave_comps_i16(MercuryPlan* plan, mercury_t1_fn t1,
237+
mercury_comp_row_i16_fn row_fn, void* row_ctx, uint32_t threads);
238+
182239
#ifdef __cplusplus
183240
}
184241
#endif

0 commit comments

Comments
 (0)