public void ProcessChunk(string fourCc, byte[] payload)
        {
            switch (fourCc)
            {
            case "EXIF":
            {
                // We have seen WebP images with and without the preamble here. It's likely that some software incorrectly
                // copied an entire JPEG segment into the WebP image. Regardless, we can handle it here.
                var reader = ExifReader.StartsWithJpegExifPreamble(payload)
                        ? new ByteArrayReader(payload, ExifReader.JpegSegmentPreambleLength)
                        : new ByteArrayReader(payload);
                _directories.AddRange(new ExifReader().Extract(reader));
                break;
            }

            case "ICCP":
            {
                _directories.Add(new IccReader().Extract(new ByteArrayReader(payload)));
                break;
            }

            case "XMP ":
            {
                _directories.Add(new XmpReader().Extract(payload));
                break;
            }

            case "VP8X":
            {
                if (payload.Length != 10)
                {
                    break;
                }

                string?error          = null;
                var    reader         = new ByteArrayReader(payload, isMotorolaByteOrder: false);
                var    isAnimation    = false;
                var    hasAlpha       = false;
                var    widthMinusOne  = -1;
                var    heightMinusOne = -1;
                try
                {
                    // Flags
                    // bit 0: has fragments
                    // bit 1: is animation
                    // bit 2: has XMP
                    // bit 3: has Exif
                    // bit 4: has alpha
                    // big 5: has ICC
                    isAnimation = reader.GetBit(1);
                    hasAlpha    = reader.GetBit(4);

                    // Image size
                    widthMinusOne  = reader.GetInt24(4);
                    heightMinusOne = reader.GetInt24(7);
                }
                catch (IOException e)
                {
                    error = "Exception reading WebpRiff chunk 'VP8X' : " + e.Message;
                }

                var directory = new WebPDirectory();
                if (error == null)
                {
                    directory.Set(WebPDirectory.TagImageWidth, widthMinusOne + 1);
                    directory.Set(WebPDirectory.TagImageHeight, heightMinusOne + 1);
                    directory.Set(WebPDirectory.TagHasAlpha, hasAlpha);
                    directory.Set(WebPDirectory.TagIsAnimation, isAnimation);
                }
                else
                {
                    directory.AddError(error);
                }
                _directories.Add(directory);
                break;
            }

            case "VP8L":
            {
                if (payload.Length < 5)
                {
                    break;
                }

                var reader = new ByteArrayReader(payload, isMotorolaByteOrder: false);

                string?error          = null;
                var    widthMinusOne  = -1;
                var    heightMinusOne = -1;
                try
                {
                    // https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification#2_riff_header

                    // Expect the signature byte
                    if (reader.GetByte(0) != 0x2F)
                    {
                        break;
                    }
                    var b1 = reader.GetByte(1);
                    var b2 = reader.GetByte(2);
                    var b3 = reader.GetByte(3);
                    var b4 = reader.GetByte(4);
                    // 14 bits for width
                    widthMinusOne = (b2 & 0x3F) << 8 | b1;
                    // 14 bits for height
                    heightMinusOne = (b4 & 0x0F) << 10 | b3 << 2 | (b2 & 0xC0) >> 6;
                }
                catch (IOException e)
                {
                    error = "Exception reading WebpRiff chunk 'VP8L' : " + e.Message;
                }

                var directory = new WebPDirectory();
                if (error == null)
                {
                    directory.Set(WebPDirectory.TagImageWidth, widthMinusOne + 1);
                    directory.Set(WebPDirectory.TagImageHeight, heightMinusOne + 1);
                }
                else
                {
                    directory.AddError(error);
                }
                _directories.Add(directory);
                break;
            }

            case "VP8 ":
            {
                if (payload.Length < 10)
                {
                    break;
                }

                var reader = new ByteArrayReader(payload, isMotorolaByteOrder: false);

                string?error  = null;
                var    width  = 0;
                var    height = 0;
                try
                {
                    // https://tools.ietf.org/html/rfc6386#section-9.1
                    // https://github.com/webmproject/libwebp/blob/master/src/enc/syntax.c#L115

                    // Expect the signature bytes
                    if (reader.GetByte(3) != 0x9D ||
                        reader.GetByte(4) != 0x01 ||
                        reader.GetByte(5) != 0x2A)
                    {
                        break;
                    }
                    width  = reader.GetUInt16(6);
                    height = reader.GetUInt16(8);
                }
                catch (IOException e)
                {
                    error = "Exception reading WebpRiff chunk 'VP8' : " + e.Message;
                }

                var directory = new WebPDirectory();
                if (error == null)
                {
                    directory.Set(WebPDirectory.TagImageWidth, width);
                    directory.Set(WebPDirectory.TagImageHeight, height);
                }
                else
                {
                    directory.AddError(error);
                }
                _directories.Add(directory);
                break;
            }
            }
        }
        public void ProcessChunk(string fourCc, byte[] payload)
        {
            switch (fourCc)
            {
            case "EXIF":
            {
                _directories.AddRange(new ExifReader().Extract(new ByteArrayReader(payload)));
                break;
            }

            case "ICCP":
            {
                _directories.Add(new IccReader().Extract(new ByteArrayReader(payload)));
                break;
            }

            case "XMP ":
            {
                _directories.Add(new XmpReader().Extract(payload));
                break;
            }

            case "VP8X":
            {
                if (payload.Length != 10)
                {
                    break;
                }

                string error          = null;
                var    reader         = new ByteArrayReader(payload, isMotorolaByteOrder: false);
                var    isAnimation    = false;
                var    hasAlpha       = false;
                var    widthMinusOne  = -1;
                var    heightMinusOne = -1;
                try
                {
                    // Flags
//                      var hasFragments = reader.GetBit(0);
                    isAnimation = reader.GetBit(1);
//                      var hasXmp = reader.GetBit(2);
//                      var hasExif = reader.GetBit(3);
                    hasAlpha = reader.GetBit(4);
//                      var hasIcc = reader.GetBit(5);
                    // Image size
                    widthMinusOne  = reader.GetInt24(4);
                    heightMinusOne = reader.GetInt24(7);
                }
                catch (IOException e)
                {
                    error = "Exception reading WebpRiff chunk 'VP8X' : " + e.Message;
                }

                var directory = new WebPDirectory();
                if (error == null)
                {
                    directory.Set(WebPDirectory.TagImageWidth, widthMinusOne + 1);
                    directory.Set(WebPDirectory.TagImageHeight, heightMinusOne + 1);
                    directory.Set(WebPDirectory.TagHasAlpha, hasAlpha);
                    directory.Set(WebPDirectory.TagIsAnimation, isAnimation);
                }
                else
                {
                    directory.AddError(error);
                }
                _directories.Add(directory);
                break;
            }

            case "VP8L":
            {
                if (payload.Length < 5)
                {
                    break;
                }

                var reader = new ByteArrayReader(payload, isMotorolaByteOrder: false);

                string error          = null;
                var    widthMinusOne  = -1;
                var    heightMinusOne = -1;
                try
                {
                    // https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification#2_riff_header

                    // Expect the signature byte
                    if (reader.GetByte(0) != 0x2F)
                    {
                        break;
                    }
                    var b1 = reader.GetByte(1);
                    var b2 = reader.GetByte(2);
                    var b3 = reader.GetByte(3);
                    var b4 = reader.GetByte(4);
                    // 14 bits for width
                    widthMinusOne = (b2 & 0x3F) << 8 | b1;
                    // 14 bits for height
                    heightMinusOne = (b4 & 0x0F) << 10 | b3 << 2 | (b2 & 0xC0) >> 6;
                }
                catch (IOException e)
                {
                    error = "Exception reading WebpRiff chunk 'VP8L' : " + e.Message;
                }

                var directory = new WebPDirectory();
                if (error == null)
                {
                    directory.Set(WebPDirectory.TagImageWidth, widthMinusOne + 1);
                    directory.Set(WebPDirectory.TagImageHeight, heightMinusOne + 1);
                }
                else
                {
                    directory.AddError(error);
                }
                _directories.Add(directory);
                break;
            }

            case "VP8 ":
            {
                if (payload.Length < 10)
                {
                    break;
                }

                var reader = new ByteArrayReader(payload, isMotorolaByteOrder: false);

                string error  = null;
                var    width  = 0;
                var    height = 0;
                try
                {
                    // https://tools.ietf.org/html/rfc6386#section-9.1
                    // https://github.com/webmproject/libwebp/blob/master/src/enc/syntax.c#L115

                    // Expect the signature bytes
                    if (reader.GetByte(3) != 0x9D ||
                        reader.GetByte(4) != 0x01 ||
                        reader.GetByte(5) != 0x2A)
                    {
                        break;
                    }
                    width  = reader.GetUInt16(6);
                    height = reader.GetUInt16(8);
                }
                catch (IOException e)
                {
                    error = "Exception reading WebpRiff chunk 'VP8' : " + e.Message;
                }

                var directory = new WebPDirectory();
                if (error == null)
                {
                    directory.Set(WebPDirectory.TagImageWidth, width);
                    directory.Set(WebPDirectory.TagImageHeight, height);
                }
                else
                {
                    directory.AddError(error);
                }
                _directories.Add(directory);
                break;
            }
            }
        }