فهرست منبع

LibGfx/WebP: Extract an ImageData struct

We'll need the same struct for animation frames.
Nico Weber 2 سال پیش
والد
کامیت
1334bac548
1فایلهای تغییر یافته به همراه20 افزوده شده و 16 حذف شده
  1. 20 16
      Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp

+ 20 - 16
Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp

@@ -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;
         }