mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 02:47:35 +00:00
LibGfx/WebP: Extract an ImageData struct
We'll need the same struct for animation frames.
This commit is contained in:
parent
03b04ed66a
commit
1334bac548
1 changed files with 20 additions and 16 deletions
|
@ -109,6 +109,15 @@ struct ANMFChunk {
|
|||
ReadonlyBytes frame_data;
|
||||
};
|
||||
|
||||
// "For a still image, the image data consists of a single frame, which is made up of:
|
||||
// An optional alpha subchunk.
|
||||
// A bitstream subchunk."
|
||||
struct ImageData {
|
||||
// "This optional chunk contains encoded alpha data for this frame. A frame containing a 'VP8L' chunk SHOULD NOT contain this chunk."
|
||||
Optional<Chunk> alpha_chunk; // 'ALPH'
|
||||
Optional<Chunk> image_data_chunk; // Either 'VP8 ' or 'VP8L'. For 'VP8L', alpha_chunk will not have a value.
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
struct WebPLoadingContext {
|
||||
|
@ -139,13 +148,8 @@ struct WebPLoadingContext {
|
|||
VP8XHeader vp8x_header;
|
||||
};
|
||||
|
||||
// If first_chunk is not a VP8X chunk, then only image_data_chunk is set and all the other Chunks are not set.
|
||||
|
||||
// "For a still image, the image data consists of a single frame, which is made up of:
|
||||
// An optional alpha subchunk.
|
||||
// A bitstream subchunk."
|
||||
Optional<Chunk> alpha_chunk; // 'ALPH'
|
||||
Optional<Chunk> image_data_chunk; // Either 'VP8 ' or 'VP8L'.
|
||||
// If first_chunk is not a VP8X chunk, then only image_data.image_data_chunk is set and all the other Chunks are not set.
|
||||
ImageData image_data;
|
||||
|
||||
Optional<Chunk> animation_header_chunk; // 'ANIM'
|
||||
Vector<Chunk> animation_frame_chunks; // 'ANMF'
|
||||
|
@ -1414,7 +1418,7 @@ static ErrorOr<void> decode_webp_extended(WebPLoadingContext& context, ReadonlyB
|
|||
if (chunk.type == FourCC("ICCP"))
|
||||
store(context.iccp_chunk, chunk);
|
||||
else if (chunk.type == FourCC("ALPH"))
|
||||
store(context.alpha_chunk, chunk);
|
||||
store(context.image_data.alpha_chunk, chunk);
|
||||
else if (chunk.type == FourCC("ANIM"))
|
||||
store(context.animation_header_chunk, chunk);
|
||||
else if (chunk.type == FourCC("ANMF"))
|
||||
|
@ -1424,7 +1428,7 @@ static ErrorOr<void> decode_webp_extended(WebPLoadingContext& context, ReadonlyB
|
|||
else if (chunk.type == FourCC("XMP "))
|
||||
store(context.xmp_chunk, chunk);
|
||||
else if (chunk.type == FourCC("VP8 ") || chunk.type == FourCC("VP8L"))
|
||||
store(context.image_data_chunk, chunk);
|
||||
store(context.image_data.image_data_chunk, chunk);
|
||||
}
|
||||
|
||||
// Validate chunks.
|
||||
|
@ -1447,16 +1451,16 @@ static ErrorOr<void> decode_webp_extended(WebPLoadingContext& context, ReadonlyB
|
|||
// https://developers.google.com/speed/webp/docs/riff_container#alpha
|
||||
// "A frame containing a 'VP8L' chunk SHOULD NOT contain this chunk."
|
||||
// FIXME: Also check in ANMF chunks.
|
||||
if (context.alpha_chunk.has_value() && context.image_data_chunk.has_value() && context.image_data_chunk->type == FourCC("VP8L")) {
|
||||
if (context.image_data.alpha_chunk.has_value() && context.image_data.image_data_chunk.has_value() && context.image_data.image_data_chunk->type == FourCC("VP8L")) {
|
||||
dbgln_if(WEBP_DEBUG, "WebPImageDecoderPlugin: VP8L frames should not have ALPH chunks. Ignoring ALPH chunk.");
|
||||
context.alpha_chunk.clear();
|
||||
context.image_data.alpha_chunk.clear();
|
||||
}
|
||||
|
||||
// https://developers.google.com/speed/webp/docs/riff_container#color_profile
|
||||
// "This chunk MUST appear before the image data."
|
||||
if (context.iccp_chunk.has_value()
|
||||
&& ((context.image_data_chunk.has_value() && context.iccp_chunk->data.data() > context.image_data_chunk->data.data())
|
||||
|| (context.alpha_chunk.has_value() && context.iccp_chunk->data.data() > context.alpha_chunk->data.data())
|
||||
&& ((context.image_data.image_data_chunk.has_value() && context.iccp_chunk->data.data() > context.image_data.image_data_chunk->data.data())
|
||||
|| (context.image_data.alpha_chunk.has_value() && context.iccp_chunk->data.data() > context.image_data.alpha_chunk->data.data())
|
||||
|| (!context.animation_frame_chunks.is_empty() && context.iccp_chunk->data.data() > context.animation_frame_chunks[0].data.data()))) {
|
||||
return context.error("WebPImageDecoderPlugin: ICCP chunk is after image data");
|
||||
}
|
||||
|
@ -1483,7 +1487,7 @@ static ErrorOr<void> read_webp_first_chunk(WebPLoadingContext& context)
|
|||
context.state = WebPLoadingContext::State::FirstChunkRead;
|
||||
|
||||
if (first_chunk.type == FourCC("VP8 ") || first_chunk.type == FourCC("VP8L"))
|
||||
context.image_data_chunk = first_chunk;
|
||||
context.image_data.image_data_chunk = first_chunk;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
@ -1662,9 +1666,9 @@ ErrorOr<ImageFrameDescriptor> WebPImageDecoderPlugin::frame(size_t index)
|
|||
return Error::from_string_literal("WebPImageDecoderPlugin: decoding of animated files not yet implemented");
|
||||
}
|
||||
|
||||
if (m_context->image_data_chunk.has_value() && m_context->image_data_chunk->type == FourCC("VP8L")) {
|
||||
if (m_context->image_data.image_data_chunk.has_value() && m_context->image_data.image_data_chunk->type == FourCC("VP8L")) {
|
||||
if (m_context->state < WebPLoadingContext::State::BitmapDecoded) {
|
||||
TRY(decode_webp_chunk_VP8L(*m_context, m_context->image_data_chunk.value()));
|
||||
TRY(decode_webp_chunk_VP8L(*m_context, m_context->image_data.image_data_chunk.value()));
|
||||
m_context->state = WebPLoadingContext::State::BitmapDecoded;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue