mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-10 13:00:29 +03:00
LibGfx/JPEG2000: Read COC marker segments, both in main and tile headers
Not yet used for anything.
This commit is contained in:
parent
8eb3d436e6
commit
b364a58753
Notes:
sideshowbarker
2024-07-16 22:26:05 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/b364a58753 Pull-request: https://github.com/SerenityOS/serenity/pull/24107
@ -334,6 +334,36 @@ static ErrorOr<CodingStyleDefault> read_coding_style_default(ReadonlyBytes data)
|
||||
return cod;
|
||||
}
|
||||
|
||||
// A.6.2 Coding style component (COC)
|
||||
struct CodingStyleComponent {
|
||||
u16 component_index { 0 }; // "Ccoc" in spec.
|
||||
|
||||
// Table A.23 – Coding style parameter values for the Scoc parameter
|
||||
bool has_explicit_precinct_size { false }; // "Scoc" in spec.
|
||||
|
||||
CodingStyleParameters parameters;
|
||||
};
|
||||
|
||||
static ErrorOr<CodingStyleComponent> read_coding_style_component(ReadonlyBytes data, size_t number_of_components)
|
||||
{
|
||||
FixedMemoryStream stream { data };
|
||||
|
||||
// Table A.22 – Coding style component parameter values
|
||||
CodingStyleComponent coc;
|
||||
if (number_of_components < 257)
|
||||
coc.component_index = TRY(stream.read_value<u8>());
|
||||
else
|
||||
coc.component_index = TRY(stream.read_value<BigEndian<u16>>());
|
||||
|
||||
u8 Scoc = TRY(stream.read_value<u8>());
|
||||
coc.has_explicit_precinct_size = Scoc & 1;
|
||||
|
||||
dbgln_if(JPEG2000_DEBUG, "JPEG2000ImageDecoderPlugin: COC marker segment: component_index={}", coc.component_index);
|
||||
coc.parameters = TRY(read_coding_style_parameters(data.slice(TRY(stream.tell())), "COC"sv, coc.has_explicit_precinct_size));
|
||||
|
||||
return coc;
|
||||
}
|
||||
|
||||
// A.6.4 Quantization default (QCD)
|
||||
struct QuantizationDefault {
|
||||
enum QuantizationStyle {
|
||||
@ -479,6 +509,7 @@ struct TilePartData {
|
||||
|
||||
struct TileData {
|
||||
Optional<CodingStyleDefault> cod;
|
||||
Vector<CodingStyleComponent> cocs;
|
||||
Optional<QuantizationDefault> qcd;
|
||||
Vector<QuantizationComponent> qccs;
|
||||
Vector<TilePartData> tile_parts;
|
||||
@ -502,6 +533,7 @@ struct JPEG2000LoadingContext {
|
||||
// Data from marker segments:
|
||||
ImageAndTileSize siz;
|
||||
CodingStyleDefault cod;
|
||||
Vector<CodingStyleComponent> cocs;
|
||||
QuantizationDefault qcd;
|
||||
Vector<QuantizationComponent> qccs;
|
||||
Vector<Comment> coms;
|
||||
@ -587,6 +619,8 @@ static ErrorOr<void> parse_codestream_main_header(JPEG2000LoadingContext& contex
|
||||
return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple COD markers in main header");
|
||||
context.cod = TRY(read_coding_style_default(marker.data.value()));
|
||||
saw_COD_marker = true;
|
||||
} else if (marker.marker == J2K_COC) {
|
||||
context.cocs.append(TRY(read_coding_style_component(marker.data.value(), context.siz.components.size())));
|
||||
} else if (marker.marker == J2K_QCD) {
|
||||
if (saw_QCD_marker)
|
||||
return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple QCD markers in main header");
|
||||
@ -617,7 +651,8 @@ static ErrorOr<void> parse_codestream_main_header(JPEG2000LoadingContext& contex
|
||||
[](Empty) -> size_t { VERIFY_NOT_REACHED(); },
|
||||
[](Vector<QuantizationDefault::ReversibleStepSize> const& step_sizes) { return step_sizes.size(); },
|
||||
[](Vector<QuantizationDefault::IrreversibleStepSize> const& step_sizes) { return step_sizes.size(); });
|
||||
if (context.qcd.quantization_style != QuantizationDefault::ScalarDerived && step_sizes_count < context.cod.number_of_decomposition_levels * 3u + 1u)
|
||||
// FIXME: What if number_of_decomposition_levels is in context.cocs and varies by component?
|
||||
if (context.qcd.quantization_style != QuantizationDefault::ScalarDerived && step_sizes_count < context.cod.parameters.number_of_decomposition_levels * 3u + 1u)
|
||||
return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Not enough step sizes for number of decomposition levels");
|
||||
|
||||
return {};
|
||||
@ -676,6 +711,8 @@ static ErrorOr<void> parse_codestream_tile_header(JPEG2000LoadingContext& contex
|
||||
if (tile.cod.has_value())
|
||||
return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple COD markers in tile header");
|
||||
tile.cod = TRY(read_coding_style_default(marker.data.value()));
|
||||
} else if (marker.marker == J2K_COC) {
|
||||
tile.cocs.append(TRY(read_coding_style_component(marker.data.value(), context.siz.components.size())));
|
||||
} else if (marker.marker == J2K_QCD) {
|
||||
if (tile.qcd.has_value())
|
||||
return Error::from_string_literal("JPEG2000ImageDecoderPlugin: Multiple QCD markers in tile header");
|
||||
|
Loading…
Reference in New Issue
Block a user