diff --git a/.gitattributes b/.gitattributes
index b5f742ab47..1ab893e0a8 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -136,3 +136,6 @@
*.ico filter=lfs diff=lfs merge=lfs -text
*.cur filter=lfs diff=lfs merge=lfs -text
*.ani filter=lfs diff=lfs merge=lfs -text
+*.heic filter=lfs diff=lfs merge=lfs -text
+*.hif filter=lfs diff=lfs merge=lfs -text
+*.avif filter=lfs diff=lfs merge=lfs -text
diff --git a/ImageSharp.sln b/ImageSharp.sln
index 7ccd92c07d..1789a8d5d4 100644
--- a/ImageSharp.sln
+++ b/ImageSharp.sln
@@ -37,8 +37,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{815C0625-CD3
ProjectSection(SolutionItems) = preProject
src\Directory.Build.props = src\Directory.Build.props
src\Directory.Build.targets = src\Directory.Build.targets
- src\README.md = src\README.md
src\ImageSharp.ruleset = src\ImageSharp.ruleset
+ src\README.md = src\README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageSharp", "src\ImageSharp\ImageSharp.csproj", "{2AA31A1F-142C-43F4-8687-09ABCA4B3A26}"
@@ -215,6 +215,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "issues", "issues", "{5C9B68
ProjectSection(SolutionItems) = preProject
tests\Images\Input\Jpg\issues\issue-1076-invalid-subsampling.jpg = tests\Images\Input\Jpg\issues\issue-1076-invalid-subsampling.jpg
tests\Images\Input\Jpg\issues\issue-1221-identify-multi-frame.jpg = tests\Images\Input\Jpg\issues\issue-1221-identify-multi-frame.jpg
+ tests\Images\Input\Jpg\issues\issue-2067-comment.jpg = tests\Images\Input\Jpg\issues\issue-2067-comment.jpg
tests\Images\Input\Jpg\issues\issue1006-incorrect-resize.jpg = tests\Images\Input\Jpg\issues\issue1006-incorrect-resize.jpg
tests\Images\Input\Jpg\issues\issue1049-exif-resize.jpg = tests\Images\Input\Jpg\issues\issue1049-exif-resize.jpg
tests\Images\Input\Jpg\issues\Issue159-MissingFF00-Progressive-Bedroom.jpg = tests\Images\Input\Jpg\issues\Issue159-MissingFF00-Progressive-Bedroom.jpg
@@ -238,7 +239,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "issues", "issues", "{5C9B68
tests\Images\Input\Jpg\issues\issue750-exif-tranform.jpg = tests\Images\Input\Jpg\issues\issue750-exif-tranform.jpg
tests\Images\Input\Jpg\issues\Issue845-Incorrect-Quality99.jpg = tests\Images\Input\Jpg\issues\Issue845-Incorrect-Quality99.jpg
tests\Images\Input\Jpg\issues\issue855-incorrect-colorspace.jpg = tests\Images\Input\Jpg\issues\issue855-incorrect-colorspace.jpg
- tests\Images\Input\Jpg\issues\issue-2067-comment.jpg = tests\Images\Input\Jpg\issues\issue-2067-comment.jpg
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fuzz", "fuzz", "{516A3532-6AC2-417B-AD79-9BD5D0D378A0}"
@@ -661,6 +661,19 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Qoi", "Qoi", "{E801B508-493
tests\Images\Input\Qoi\wikipedia_008.qoi = tests\Images\Input\Qoi\wikipedia_008.qoi
EndProjectSection
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Heif", "Heif", "{BA5D603A-C84C-43E5-B300-8BB886B02936}"
+ ProjectSection(SolutionItems) = preProject
+ tests\Images\Input\Heif\dwsample-heic-640.heic = tests\Images\Input\Heif\dwsample-heic-640.heic
+ tests\Images\Input\Heif\image1.heic = tests\Images\Input\Heif\image1.heic
+ tests\Images\Input\Heif\image2.heic = tests\Images\Input\Heif\image2.heic
+ tests\Images\Input\Heif\image3.heic = tests\Images\Input\Heif\image3.heic
+ tests\Images\Input\Heif\image4.heic = tests\Images\Input\Heif\image4.heic
+ tests\Images\Input\Heif\IMG-20230508-0053.hif = tests\Images\Input\Heif\IMG-20230508-0053.hif
+ tests\Images\Input\Heif\Irvine_CA.avif = tests\Images\Input\Heif\Irvine_CA.avif
+ tests\Images\Input\Heif\jpeg444_xnconvert.avif = tests\Images\Input\Heif\jpeg444_xnconvert.avif
+ tests\Images\Input\Heif\Orange4x4.avif = tests\Images\Input\Heif\Orange4x4.avif
+ EndProjectSection
+EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Icon", "Icon", "{95E45DDE-A67D-48AD-BBA8-5FAA151B860D}"
ProjectSection(SolutionItems) = preProject
tests\Images\Input\Icon\aero_arrow.cur = tests\Images\Input\Icon\aero_arrow.cur
@@ -720,6 +733,7 @@ Global
{670DD46C-82E9-499A-B2D2-00A802ED0141} = {E1C42A6F-913B-4A7B-B1A8-2BB62843B254}
{5DFC394F-136F-4B76-9BCA-3BA786515EFC} = {9DA226A1-8656-49A8-A58A-A8B5C081AD66}
{E801B508-4935-41CD-BA85-CF11BFF55A45} = {9DA226A1-8656-49A8-A58A-A8B5C081AD66}
+ {BA5D603A-C84C-43E5-B300-8BB886B02936} = {9DA226A1-8656-49A8-A58A-A8B5C081AD66}
{95E45DDE-A67D-48AD-BBA8-5FAA151B860D} = {9DA226A1-8656-49A8-A58A-A8B5C081AD66}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
diff --git a/shared-infrastructure b/shared-infrastructure
index 1dbfb576c8..922c5b21e5 160000
--- a/shared-infrastructure
+++ b/shared-infrastructure
@@ -1 +1 @@
-Subproject commit 1dbfb576c83507645265c79e03369b66cdc0379f
+Subproject commit 922c5b21e5dfa02d4ef0d95334ab01c87a7a4309
diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs
index 1d9f3bb85d..228e42bfe4 100644
--- a/src/ImageSharp/Configuration.cs
+++ b/src/ImageSharp/Configuration.cs
@@ -6,6 +6,7 @@
using SixLabors.ImageSharp.Formats.Bmp;
using SixLabors.ImageSharp.Formats.Cur;
using SixLabors.ImageSharp.Formats.Gif;
+using SixLabors.ImageSharp.Formats.Heif;
using SixLabors.ImageSharp.Formats.Ico;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Pbm;
@@ -213,6 +214,7 @@ public void Configure(IImageFormatConfigurationModule configuration)
/// .
/// .
/// .
+ /// .
///
/// The default configuration of .
internal static Configuration CreateDefaultInstance() => new(
@@ -225,6 +227,7 @@ public void Configure(IImageFormatConfigurationModule configuration)
new TiffConfigurationModule(),
new WebpConfigurationModule(),
new QoiConfigurationModule(),
+ new HeifConfigurationModule(),
new IcoConfigurationModule(),
new CurConfigurationModule());
}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1BitDepth.cs b/src/ImageSharp/Formats/Heif/Av1/Av1BitDepth.cs
new file mode 100644
index 0000000000..28d48b13cf
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Av1BitDepth.cs
@@ -0,0 +1,11 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1;
+
+internal enum Av1BitDepth : int
+{
+ EightBit = 0,
+ TenBit = 1,
+ TwelveBit = 2,
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1BitDepthExtensions.cs b/src/ImageSharp/Formats/Heif/Av1/Av1BitDepthExtensions.cs
new file mode 100644
index 0000000000..615ed0b8d5
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Av1BitDepthExtensions.cs
@@ -0,0 +1,11 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1;
+
+internal static class Av1BitDepthExtensions
+{
+ public static int GetBitCount(this Av1BitDepth bitDepth) => 8 + ((int)bitDepth << 1);
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1BitStreamReader.cs b/src/ImageSharp/Formats/Heif/Av1/Av1BitStreamReader.cs
new file mode 100644
index 0000000000..1b96c26d9e
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Av1BitStreamReader.cs
@@ -0,0 +1,157 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1;
+
+internal ref struct Av1BitStreamReader
+{
+ private readonly Span data;
+
+ public Av1BitStreamReader(Span data) => this.data = data;
+
+ public int BitPosition { get; private set; } = 0;
+
+ ///
+ /// Gets the number of bytes in the readers buffer.
+ ///
+ public readonly int Length => this.data.Length;
+
+ public void Reset() => this.BitPosition = 0;
+
+ public void Skip(int bitCount) => this.BitPosition += bitCount;
+
+ public uint ReadLiteral(int bitCount)
+ {
+ DebugGuard.MustBeBetweenOrEqualTo(bitCount, 0, 32, nameof(bitCount));
+
+ uint literal = 0;
+ for (int bit = bitCount - 1; bit >= 0; bit--)
+ {
+ literal |= this.ReadBit() << bit;
+ }
+
+ return literal;
+ }
+
+ internal uint ReadBit()
+ {
+ int byteOffset = Av1Math.DivideBy8Floor(this.BitPosition);
+ byte shift = (byte)(7 - Av1Math.Modulus8(this.BitPosition));
+ this.BitPosition++;
+ return (uint)((this.data[byteOffset] >> shift) & 0x01);
+ }
+
+ internal bool ReadBoolean() => this.ReadLiteral(1) > 0;
+
+ public ulong ReadLittleEndianBytes128(out int length)
+ {
+ // See section 4.10.5 of the AV1-Specification
+ DebugGuard.IsTrue((this.BitPosition & 0x07) == 0, $"Reading of Little Endian 128 value only allowed on byte alignment (offset {this.BitPosition}).");
+
+ ulong value = 0;
+ length = 0;
+ for (int i = 0; i < 56; i += 7)
+ {
+ uint leb128Byte = this.ReadLiteral(8);
+ value |= (leb128Byte & 0x7FUL) << i;
+ length++;
+ if ((leb128Byte & 0x80U) == 0)
+ {
+ break;
+ }
+ }
+
+ return value;
+ }
+
+ public uint ReadUnsignedVariableLength()
+ {
+ // See section 4.10.3 of the AV1-Specification
+ int leadingZerosCount = 0;
+ while (leadingZerosCount < 32)
+ {
+ uint bit = this.ReadLiteral(1);
+ if (bit == 1)
+ {
+ break;
+ }
+
+ leadingZerosCount++;
+ }
+
+ if (leadingZerosCount == 32)
+ {
+ return uint.MaxValue;
+ }
+
+ if (leadingZerosCount != 0)
+ {
+ uint basis = (1U << leadingZerosCount) - 1U;
+ uint value = this.ReadLiteral(leadingZerosCount);
+ return basis + value;
+ }
+
+ return 0;
+ }
+
+ public uint ReadNonSymmetric(uint n)
+ {
+ // See section 4.10.7 of the AV1-Specification
+ if (n <= 1)
+ {
+ return 0;
+ }
+
+ int w = (int)(Av1Math.FloorLog2(n) + 1);
+ uint m = (uint)((1 << w) - n);
+ uint v = this.ReadLiteral(w - 1);
+ if (v < m)
+ {
+ return v;
+ }
+
+ return (v << 1) - m + this.ReadLiteral(1);
+ }
+
+ public int ReadSignedFromUnsigned(int n)
+ {
+ // See section 4.10.6 of the AV1-Specification
+ int signedValue;
+ uint value = this.ReadLiteral(n);
+ uint signMask = 1U << (n - 1);
+ if ((value & signMask) == signMask)
+ {
+ // Prevent overflow by casting to long;
+ signedValue = (int)((long)value - (signMask << 1));
+ }
+ else
+ {
+ signedValue = (int)value;
+ }
+
+ return signedValue;
+ }
+
+ public uint ReadLittleEndian(int n)
+ {
+ // See section 4.10.4 of the AV1-Specification
+ DebugGuard.IsTrue(Av1Math.Modulus8(this.BitPosition) == 0, "Reading of Little Endian value only allowed on byte alignment");
+
+ uint t = 0;
+ for (int i = 0; i < 8 * n; i += 8)
+ {
+ t += this.ReadLiteral(8) << i;
+ }
+
+ return t;
+ }
+
+ public Span GetSymbolReader(int tileDataSize)
+ {
+ DebugGuard.IsTrue(Av1Math.Modulus8(this.BitPosition) == 0, "Symbol reading needs to start on byte boundary.");
+ int bytesRead = Av1Math.DivideBy8Floor(this.BitPosition);
+ Span span = this.data.Slice(bytesRead, tileDataSize);
+ this.Skip(tileDataSize << 3);
+ return span;
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1BitStreamWriter.cs b/src/ImageSharp/Formats/Heif/Av1/Av1BitStreamWriter.cs
new file mode 100644
index 0000000000..687b973331
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Av1BitStreamWriter.cs
@@ -0,0 +1,183 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Memory;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1;
+
+internal ref struct Av1BitStreamWriter
+{
+ private const int WordSize = 8;
+ private readonly AutoExpandingMemory memory;
+ private Span span;
+ private int capacityTrigger;
+ private byte buffer = 0;
+
+ public Av1BitStreamWriter(AutoExpandingMemory memory)
+ {
+ this.memory = memory;
+ this.span = memory.GetEntireSpan();
+ this.capacityTrigger = memory.Capacity - 1;
+ }
+
+ public int BitPosition { get; private set; } = 0;
+
+ public readonly int Capacity => this.memory.Capacity;
+
+ public static int GetLittleEndianBytes128(uint value, Span span)
+ {
+ if (value < 0x80U)
+ {
+ span[0] = (byte)value;
+ return 1;
+ }
+ else if (value < 0x8000U)
+ {
+ span[0] = (byte)((value & 0x7fU) | 0x80U);
+ span[1] = (byte)((value >> 7) & 0xff);
+ return 2;
+ }
+ else if (value < 0x800000U)
+ {
+ span[0] = (byte)((value & 0x7fU) | 0x80U);
+ span[1] = (byte)((value >> 7) & 0xff);
+ span[2] = (byte)((value >> 14) & 0xff);
+ return 3;
+ }
+ else
+ {
+ throw new NotImplementedException("No such large values yet.");
+ }
+ }
+
+ public void Skip(int bitCount)
+ {
+ this.BitPosition += bitCount;
+ while (this.BitPosition >= WordSize)
+ {
+ this.BitPosition -= WordSize;
+ this.WriteBuffer();
+ }
+ }
+
+ public void Flush()
+ {
+ if (Av1Math.Modulus8(this.BitPosition) != 0)
+ {
+ // Flush a partial byte also.
+ this.WriteBuffer();
+ }
+
+ this.BitPosition = 0;
+ }
+
+ public void WriteLiteral(uint value, int bitCount)
+ {
+ for (int bit = bitCount - 1; bit >= 0; bit--)
+ {
+ this.WriteBit((byte)((value >> bit) & 0x1));
+ }
+ }
+
+ internal void WriteBoolean(bool value)
+ {
+ byte boolByte = value ? (byte)1 : (byte)0;
+ this.WriteBit(boolByte);
+ }
+
+ public void WriteSignedFromUnsigned(int signedValue, int n)
+ {
+ // See section 4.10.6 of the AV1-Specification
+ ulong value = (ulong)signedValue;
+ if (signedValue < 0)
+ {
+ value += 1UL << n;
+ }
+
+ this.WriteLiteral((uint)value, n);
+ }
+
+ public void WriteLittleEndianBytes128(uint value)
+ {
+ int bytesWritten = GetLittleEndianBytes128(value, this.span.Slice(this.BitPosition >> 3));
+ this.BitPosition += bytesWritten << 3;
+ }
+
+ internal void WriteNonSymmetric(uint value, uint numberOfSymbols)
+ {
+ // See section 4.10.7 of the AV1-Specification
+ if (numberOfSymbols <= 1)
+ {
+ return;
+ }
+
+ int w = (int)(Av1Math.FloorLog2(numberOfSymbols) + 1);
+ uint m = (uint)((1 << w) - numberOfSymbols);
+ if (value < m)
+ {
+ this.WriteLiteral(value, w - 1);
+ }
+ else
+ {
+ uint extraBit = ((value + m) >> 1) - value;
+ uint k = (value + m - extraBit) >> 1;
+ this.WriteLiteral(k, w - 1);
+ this.WriteLiteral(extraBit, 1);
+ }
+ }
+
+ private void WriteBit(byte value)
+ {
+ int bit = this.BitPosition & 0x07;
+ this.buffer = (byte)(((value << (7 - bit)) & 0xff) | this.buffer);
+ if (bit == 7)
+ {
+ this.WriteBuffer();
+ }
+
+ this.BitPosition++;
+ }
+
+ public void WriteLittleEndian(uint value, int n)
+ {
+ // See section 4.10.4 of the AV1-Specification
+ DebugGuard.IsTrue(Av1Math.Modulus8(this.BitPosition) == 0, "Writing of Little Endian value only allowed on byte alignment");
+
+ uint t = value;
+ for (int i = 0; i < n; i++)
+ {
+ this.WriteLiteral(t & 0xff, 8);
+ t >>= 8;
+ }
+ }
+
+ internal void WriteBlob(Span tileData)
+ {
+ DebugGuard.IsTrue(Av1Math.Modulus8(this.BitPosition) == 0, "Writing of Tile Data only allowed on byte alignment");
+
+ int wordPosition = this.BitPosition >> 3;
+ if (this.span.Length <= wordPosition + tileData.Length)
+ {
+ this.memory.GetSpan(wordPosition + tileData.Length);
+ this.span = this.memory.GetEntireSpan();
+ }
+
+ tileData.CopyTo(this.span[wordPosition..]);
+ this.BitPosition += tileData.Length << 3;
+ }
+
+ private void WriteBuffer()
+ {
+ int wordPosition = Av1Math.DivideBy8Floor(this.BitPosition);
+ if (wordPosition > this.capacityTrigger)
+ {
+ // Expand the memory allocation.
+ this.memory.GetSpan(wordPosition + 1);
+ this.span = this.memory.GetEntireSpan();
+ this.capacityTrigger = this.span.Length - 1;
+ }
+
+ this.span[wordPosition] = this.buffer;
+ this.buffer = 0;
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1BlockSize.cs b/src/ImageSharp/Formats/Heif/Av1/Av1BlockSize.cs
new file mode 100644
index 0000000000..62c4ff59e7
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Av1BlockSize.cs
@@ -0,0 +1,79 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1;
+
+internal enum Av1BlockSize : byte
+{
+ // See sction 6.10.4 of the Av1 Specification.
+
+ /// A block of samples, 4 samples wide and 4 samples high.
+ Block4x4 = 0,
+
+ /// A block of samples, 4 samples wide and 8 samples high.
+ Block4x8 = 1,
+
+ /// A block of samples, 8 samples wide and 4 samples high.
+ Block8x4 = 2,
+
+ /// A block of samples, 8 samples wide and 8 samples high.
+ Block8x8 = 3,
+
+ /// A block of samples, 8 samples wide and 16 samples high.
+ Block8x16 = 4,
+
+ /// A block of samples, 16 samples wide and 8 samples high.
+ Block16x8 = 5,
+
+ /// A block of samples, 16 samples wide and 16 samples high.
+ Block16x16 = 6,
+
+ /// A block of samples, 16 samples wide and 32 samples high.
+ Block16x32 = 7,
+
+ /// A block of samples, 32 samples wide and 16 samples high.
+ Block32x16 = 8,
+
+ /// A block of samples, 32 samples wide and 32 samples high.
+ Block32x32 = 9,
+
+ /// A block of samples, 32 samples wide and 64 samples high.
+ Block32x64 = 10,
+
+ /// A block of samples, 64 samples wide and 32 samples high.
+ Block64x32 = 11,
+
+ /// A block of samples, 64 samples wide and 64 samples high.
+ Block64x64 = 12,
+
+ /// A block of samples, 64 samples wide and 128 samples high.
+ Block64x128 = 13,
+
+ /// A block of samples, 128 samples wide and 64 samples high.
+ Block128x64 = 14,
+
+ /// A block of samples, 128 samples wide and 128 samples high.
+ Block128x128 = 15,
+
+ /// A block of samples, 4 samples wide and 16 samples high.
+ Block4x16 = 16,
+
+ /// A block of samples, 16 samples wide and 4 samples high.
+ Block16x4 = 17,
+
+ /// A block of samples, 8 samples wide and 32 samples high.
+ Block8x32 = 18,
+
+ /// A block of samples, 32 samples wide and 8 samples high.
+ Block32x8 = 19,
+
+ /// A block of samples, 16 samples wide and 64 samples high.
+ Block16x64 = 20,
+
+ /// A block of samples, 64 samples wide and 16 samples high.
+ Block64x16 = 21,
+ AllSizes = 22,
+ SizeS = Block4x16,
+ Invalid = 255,
+ Largest = SizeS - 1,
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1BlockSizeExtensions.cs b/src/ImageSharp/Formats/Heif/Av1/Av1BlockSizeExtensions.cs
new file mode 100644
index 0000000000..df5f533806
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Av1BlockSizeExtensions.cs
@@ -0,0 +1,146 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1;
+
+internal static class Av1BlockSizeExtensions
+{
+ private static readonly int[] SizeWide = [1, 1, 2, 2, 2, 4, 4, 4, 8, 8, 8, 16, 16, 16, 32, 32, 1, 4, 2, 8, 4, 16];
+ private static readonly int[] SizeHigh = [1, 2, 1, 2, 4, 2, 4, 8, 4, 8, 16, 8, 16, 32, 16, 32, 4, 1, 8, 2, 16, 4];
+
+ // The Subsampled_Size table in the spec (Section 5.11.38. Get plane residual size function).
+ private static readonly Av1BlockSize[][][] SubSampled =
+ [
+
+ // ss_x == 0 ss_x == 0 ss_x == 1 ss_x == 1
+ // ss_y == 0 ss_y == 1 ss_y == 0 ss_y == 1
+ [[Av1BlockSize.Block4x4, Av1BlockSize.Block4x4], [Av1BlockSize.Block4x4, Av1BlockSize.Block4x4]],
+ [[Av1BlockSize.Block4x8, Av1BlockSize.Block4x4], [Av1BlockSize.Invalid, Av1BlockSize.Block4x4]],
+ [[Av1BlockSize.Block8x4, Av1BlockSize.Invalid], [Av1BlockSize.Block4x4, Av1BlockSize.Block4x4]],
+ [[Av1BlockSize.Block8x8, Av1BlockSize.Block8x4], [Av1BlockSize.Block4x8, Av1BlockSize.Block4x4]],
+ [[Av1BlockSize.Block8x16, Av1BlockSize.Block8x8], [Av1BlockSize.Invalid, Av1BlockSize.Block4x8]],
+ [[Av1BlockSize.Block16x8, Av1BlockSize.Invalid], [Av1BlockSize.Block8x8, Av1BlockSize.Block8x4]],
+ [[Av1BlockSize.Block16x16, Av1BlockSize.Block16x8], [Av1BlockSize.Block8x16, Av1BlockSize.Block8x8]],
+ [[Av1BlockSize.Block16x32, Av1BlockSize.Block16x16], [Av1BlockSize.Invalid, Av1BlockSize.Block8x16]],
+ [[Av1BlockSize.Block32x16, Av1BlockSize.Invalid], [Av1BlockSize.Block16x16, Av1BlockSize.Block16x8]],
+ [[Av1BlockSize.Block32x32, Av1BlockSize.Block32x16], [Av1BlockSize.Block16x32, Av1BlockSize.Block16x16]],
+ [[Av1BlockSize.Block32x64, Av1BlockSize.Block32x32], [Av1BlockSize.Invalid, Av1BlockSize.Block16x32]],
+ [[Av1BlockSize.Block64x32, Av1BlockSize.Invalid], [Av1BlockSize.Block32x32, Av1BlockSize.Block32x16]],
+ [[Av1BlockSize.Block64x64, Av1BlockSize.Block64x32], [Av1BlockSize.Block32x64, Av1BlockSize.Block32x32]],
+ [[Av1BlockSize.Block64x128, Av1BlockSize.Block64x64], [Av1BlockSize.Invalid, Av1BlockSize.Block32x64]],
+ [[Av1BlockSize.Block128x64, Av1BlockSize.Invalid], [Av1BlockSize.Block64x64, Av1BlockSize.Block64x32]],
+ [[Av1BlockSize.Block128x128, Av1BlockSize.Block128x64], [Av1BlockSize.Block64x128, Av1BlockSize.Block64x64]],
+ [[Av1BlockSize.Block4x16, Av1BlockSize.Block4x8], [Av1BlockSize.Invalid, Av1BlockSize.Block4x8]],
+ [[Av1BlockSize.Block16x4, Av1BlockSize.Invalid], [Av1BlockSize.Block8x4, Av1BlockSize.Block8x4]],
+ [[Av1BlockSize.Block8x32, Av1BlockSize.Block8x16], [Av1BlockSize.Invalid, Av1BlockSize.Block4x16]],
+ [[Av1BlockSize.Block32x8, Av1BlockSize.Invalid], [Av1BlockSize.Block16x8, Av1BlockSize.Block16x4]],
+ [[Av1BlockSize.Block16x64, Av1BlockSize.Block16x32], [Av1BlockSize.Invalid, Av1BlockSize.Block8x32]],
+ [[Av1BlockSize.Block64x16, Av1BlockSize.Invalid], [Av1BlockSize.Block32x16, Av1BlockSize.Block32x8]]
+ ];
+
+ private static readonly Av1TransformSize[] MaxTransformSize = [
+ Av1TransformSize.Size4x4, Av1TransformSize.Size4x8, Av1TransformSize.Size8x4, Av1TransformSize.Size8x8,
+ Av1TransformSize.Size8x16, Av1TransformSize.Size16x8, Av1TransformSize.Size16x16, Av1TransformSize.Size16x32,
+ Av1TransformSize.Size32x16, Av1TransformSize.Size32x32, Av1TransformSize.Size32x64, Av1TransformSize.Size64x32,
+ Av1TransformSize.Size64x64, Av1TransformSize.Size64x64, Av1TransformSize.Size64x64, Av1TransformSize.Size64x64,
+ Av1TransformSize.Size4x16, Av1TransformSize.Size16x4, Av1TransformSize.Size8x32, Av1TransformSize.Size32x8,
+ Av1TransformSize.Size16x64, Av1TransformSize.Size64x16
+ ];
+
+ private static readonly int[] PelsLog2Count =
+ [4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13, 13, 14, 6, 6, 8, 8, 10, 10];
+
+ private static readonly Av1BlockSize[][] HeightWidthToSize = [
+ [Av1BlockSize.Block4x4, Av1BlockSize.Block4x8, Av1BlockSize.Block4x16, Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid],
+ [Av1BlockSize.Block8x4, Av1BlockSize.Block8x8, Av1BlockSize.Block8x16, Av1BlockSize.Block8x32, Av1BlockSize.Invalid, Av1BlockSize.Invalid],
+ [Av1BlockSize.Block16x4, Av1BlockSize.Block16x8, Av1BlockSize.Block16x16, Av1BlockSize.Block16x32, Av1BlockSize.Block16x64, Av1BlockSize.Invalid],
+ [Av1BlockSize.Invalid, Av1BlockSize.Block32x8, Av1BlockSize.Block32x16, Av1BlockSize.Block32x32, Av1BlockSize.Block32x64, Av1BlockSize.Invalid],
+ [Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block64x16, Av1BlockSize.Block64x32, Av1BlockSize.Block64x64, Av1BlockSize.Block64x128],
+ [Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block128x64, Av1BlockSize.Block128x128]
+ ];
+
+ public static int Get4x4WideCount(this Av1BlockSize blockSize) => SizeWide[(int)blockSize];
+
+ public static int Get4x4HighCount(this Av1BlockSize blockSize) => SizeHigh[(int)blockSize];
+
+ ///
+ /// Gets the given by the Log2 of the width and height.
+ ///
+ /// Log2 of the width value.
+ /// Log2 of the height value.
+ /// The .
+ public static Av1BlockSize FromWidthAndHeight(uint widthLog2, uint heightLog2) => HeightWidthToSize[heightLog2][widthLog2];
+
+ ///
+ /// Returns the width of the block in samples.
+ ///
+ public static int GetWidth(this Av1BlockSize blockSize)
+ => Get4x4WideCount(blockSize) << 2;
+
+ ///
+ /// Returns of the height of the block in 4 samples.
+ ///
+ public static int GetHeight(this Av1BlockSize blockSize)
+ => Get4x4HighCount(blockSize) << 2;
+
+ ///
+ /// Returns base 2 logarithm of the width of the block in units of 4 samples.
+ ///
+ public static int Get4x4WidthLog2(this Av1BlockSize blockSize)
+ => Av1Math.Log2(Get4x4WideCount(blockSize));
+
+ ///
+ /// Returns base 2 logarithm of the height of the block in units of 4 samples.
+ ///
+ public static int Get4x4HeightLog2(this Av1BlockSize blockSize)
+ => Av1Math.Log2(Get4x4HighCount(blockSize));
+
+ ///
+ /// Returns the block size of a sub sampled block.
+ ///
+ public static Av1BlockSize GetSubsampled(this Av1BlockSize blockSize, bool subX, bool subY)
+ => GetSubsampled(blockSize, subX ? 1 : 0, subY ? 1 : 0);
+
+ ///
+ /// Returns the block size of a sub sampled block.
+ ///
+ public static Av1BlockSize GetSubsampled(this Av1BlockSize blockSize, int subX, int subY)
+ {
+ if (blockSize == Av1BlockSize.Invalid)
+ {
+ return Av1BlockSize.Invalid;
+ }
+
+ return SubSampled[(int)blockSize][subX][subY];
+ }
+
+ public static Av1TransformSize GetMaxUvTransformSize(this Av1BlockSize blockSize, bool subX, bool subY)
+ {
+ Av1BlockSize planeBlockSize = blockSize.GetSubsampled(subX, subY);
+ Av1TransformSize uvTransformSize = Av1TransformSize.Invalid;
+ if (planeBlockSize < Av1BlockSize.AllSizes)
+ {
+ uvTransformSize = planeBlockSize.GetMaximumTransformSize();
+ }
+
+ return uvTransformSize switch
+ {
+ Av1TransformSize.Size64x64 or Av1TransformSize.Size64x32 or Av1TransformSize.Size32x64 => Av1TransformSize.Size32x32,
+ Av1TransformSize.Size64x16 => Av1TransformSize.Size32x16,
+ Av1TransformSize.Size16x64 => Av1TransformSize.Size16x32,
+ _ => uvTransformSize,
+ };
+ }
+
+ ///
+ /// Returns the largest transform size that can be used for blocks of given size.
+ /// The can be either a square or rectangular block.
+ ///
+ public static Av1TransformSize GetMaximumTransformSize(this Av1BlockSize blockSize)
+ => MaxTransformSize[(int)blockSize];
+
+ public static int GetPelsLog2Count(this Av1BlockSize blockSize)
+ => PelsLog2Count[(int)blockSize];
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1CodecConfiguration.cs b/src/ImageSharp/Formats/Heif/Av1/Av1CodecConfiguration.cs
new file mode 100644
index 0000000000..e0cef47753
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Av1CodecConfiguration.cs
@@ -0,0 +1,63 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+namespace SixLabors.ImageSharp.Formats.Heif.Av1;
+
+///
+/// Implementation of section 2.3.3 of AV1 Codec ISO Media File Format Binding specification v1.2.0.
+/// See https://aomediacodec.github.io/av1-isobmff/v1.2.0.html#av1codecconfigurationbox-syntax.
+///
+internal struct Av1CodecConfiguration
+{
+ public Av1CodecConfiguration(Span boxBuffer)
+ {
+ Av1BitStreamReader reader = new(boxBuffer);
+
+ this.Marker = (byte)reader.ReadLiteral(1);
+ this.Version = (byte)reader.ReadLiteral(7);
+ this.SeqProfile = (byte)reader.ReadLiteral(3);
+ this.SeqLevelIdx0 = (byte)reader.ReadLiteral(5);
+ this.SeqTier0 = (byte)reader.ReadLiteral(1);
+ this.HighBitdepth = (byte)reader.ReadLiteral(1);
+ this.TwelveBit = reader.ReadLiteral(1) == 1;
+ this.MonoChrome = reader.ReadLiteral(1) == 1;
+ this.ChromaSubsamplingX = reader.ReadLiteral(1) == 1;
+ this.ChromaSubsamplingY = reader.ReadLiteral(1) == 1;
+ this.ChromaSamplePosition = (byte)reader.ReadLiteral(2);
+
+ // 3 bits are reserved.
+ reader.ReadLiteral(3);
+
+ this.InitialPresentationDelayPresent = reader.ReadLiteral(1) == 1;
+ if (this.InitialPresentationDelayPresent)
+ {
+ byte initialPresentationDelayMinusOne = (byte)reader.ReadLiteral(4);
+ this.InitialPresentationDelay = (byte)(initialPresentationDelayMinusOne + 1);
+ }
+ }
+
+ public byte Marker { get; }
+
+ public byte Version { get; }
+
+ public byte SeqProfile { get; }
+
+ public byte SeqLevelIdx0 { get; }
+
+ public byte SeqTier0 { get; }
+
+ public byte HighBitdepth { get; }
+
+ public bool TwelveBit { get; }
+
+ public bool MonoChrome { get; }
+
+ public bool ChromaSubsamplingX { get; }
+
+ public bool ChromaSubsamplingY { get; }
+
+ public byte ChromaSamplePosition { get; }
+
+ public bool InitialPresentationDelayPresent { get; }
+
+ public byte InitialPresentationDelay { get; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1ColorFormat.cs b/src/ImageSharp/Formats/Heif/Av1/Av1ColorFormat.cs
new file mode 100644
index 0000000000..07be6a0442
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Av1ColorFormat.cs
@@ -0,0 +1,12 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1;
+
+internal enum Av1ColorFormat
+{
+ Yuv400,
+ Yuv420,
+ Yuv422,
+ Yuv444,
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1Constants.cs b/src/ImageSharp/Formats/Heif/Av1/Av1Constants.cs
new file mode 100644
index 0000000000..acf05bff4c
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Av1Constants.cs
@@ -0,0 +1,205 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1;
+
+internal static class Av1Constants
+{
+ public const ObuSequenceProfile MaxSequenceProfile = ObuSequenceProfile.Professional;
+
+ public const int LevelBits = 5;
+
+ ///
+ /// Number of fractional bits for computing position in upscaling.
+ ///
+ public const int SuperResolutionScaleBits = 14;
+
+ public const int ScaleNumerator = -1;
+
+ ///
+ /// Number of reference frames that can be used for inter prediction.
+ ///
+ public const int ReferencesPerFrame = 7;
+
+ ///
+ /// Maximum area of a tile in units of luma samples.
+ ///
+ public const int MaxTileArea = 4096 * 2304;
+
+ ///
+ /// Maximum width of a tile in units of luma samples.
+ ///
+ public const int MaxTileWidth = 4096;
+
+ ///
+ /// Maximum number of tile columns.
+ ///
+ public const int MaxTileColumnCount = 64;
+
+ ///
+ /// Maximum number of tile rows.
+ ///
+ public const int MaxTileRowCount = 64;
+
+ ///
+ /// Number of frames that can be stored for future reference.
+ ///
+ public const int ReferenceFrameCount = 8;
+
+ ///
+ /// Value of 'PrimaryReferenceFrame' indicating that there is no primary reference frame.
+ ///
+ public const uint PrimaryReferenceFrameNone = 7;
+
+ public const int PimaryReferenceBits = 3;
+
+ ///
+ /// Number of segments allowed in segmentation map.
+ ///
+ public const int MaxSegmentCount = 8;
+
+ ///
+ /// Smallest denominator for upscaling ratio.
+ ///
+ public const int SuperResolutionScaleDenominatorMinimum = 9;
+
+ ///
+ /// Base 2 logarithm of maximum size of a superblock in luma samples.
+ ///
+ public const int MaxSuperBlockSizeLog2 = 7;
+
+ ///
+ /// Base 2 logarithm of smallest size of a mode info block.
+ ///
+ public const int ModeInfoSizeLog2 = 2;
+
+ public const int MaxQ = 255;
+
+ ///
+ /// Number of segmentation features.
+ ///
+ public const int SegmentationLevelMax = 8;
+
+ ///
+ /// Maximum size of a loop restoration tile.
+ ///
+ public const int RestorationMaxTileSize = 256;
+
+ ///
+ /// Number of Wiener coefficients to read.
+ ///
+ public const int WienerCoefficientCount = 3;
+
+ public const int FrameLoopFilterCount = 4;
+
+ ///
+ /// Value indicating alternative encoding of quantizer index delta values.
+ ///
+ public const int DeltaQuantizerSmall = 3;
+
+ ///
+ /// Value indicating alternative encoding of loop filter delta values.
+ ///
+ public const int DeltaLoopFilterSmall = 3;
+
+ ///
+ /// Maximum value used for loop filtering.
+ ///
+ public const int MaxLoopFilter = 63;
+
+ ///
+ /// Maximum magnitude of AngleDeltaY and AngleDeltaUV.
+ ///
+ public const int MaxAngleDelta = 3;
+
+ ///
+ /// Maximum number of color planes.
+ ///
+ public const int MaxPlanes = 3;
+
+ ///
+ /// Number of reference frame types (including intra type).
+ ///
+ public const int TotalReferencesPerFrame = 8;
+
+ ///
+ /// Number of values for palette_size.
+ ///
+ public const int PaletteMaxSize = 8;
+
+ ///
+ /// Maximum transform size categories.
+ ///
+ public const int MaxTransformCategories = 4;
+
+ public const int CoefficientContextCount = 6;
+
+ public const int BaseLevelsCount = 2;
+
+ public const int CoefficientBaseRange = 12;
+
+ public const int MaxTransformSize = 1 << 6;
+
+ public const int MaxTransformSizeUnit = MaxTransformSize >> 2;
+
+ public const int CoefficientContextBitCount = 6;
+
+ public const int CoefficientContextMask = (1 << CoefficientContextBitCount) - 1;
+
+ public const int TransformPadHorizontalLog2 = 2;
+
+ public const int TransformPadHorizontal = 1 << TransformPadHorizontalLog2;
+
+ public const int TransformPadVertical = 6;
+
+ public const int TransformPadEnd = 16;
+
+ public const int TransformPad2d = ((MaxTransformSize + TransformPadHorizontal) * (MaxTransformSize + TransformPadVertical)) + TransformPadEnd;
+
+ public const int TransformPadTop = 2;
+
+ public const int TransformPadBottom = 4;
+
+ public const int BaseRangeSizeMinus1 = 3;
+
+ public const int MaxBaseRange = 15;
+
+ ///
+ /// Log2 of number of values for ChromaFromLuma Alpha U and ChromaFromLuma Alpha V.
+ ///
+ public const int ChromaFromLumaAlphabetSizeLog2 = 4;
+
+ ///
+ /// Total number of Quantification Matrices sets stored.
+ ///
+ public const int QuantificationMatrixLevelCount = 1 << 4;
+
+ public const int AngleStep = 3;
+
+ ///
+ /// Maximum number of stages in a 1-dimensioanl transform function.
+ ///
+ public const int MaxTransformStageNumber = 12;
+
+ public const int PartitionProbabilitySet = 4;
+
+ // Number of transform sizes that use extended transforms.
+ public const int ExtendedTransformCount = 4;
+
+ public const int MaxVarTransform = 2;
+
+ ///
+ /// Maximum number of transform blocks per depth
+ ///
+ public const int MaxTransformBlockCount = 16;
+
+ ///
+ /// Number of items in the enumeration.
+ ///
+ public const int PlaneTypeCount = 2;
+
+ public const int MaxTransformUnitCount = 16;
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1Decoder.cs b/src/ImageSharp/Formats/Heif/Av1/Av1Decoder.cs
new file mode 100644
index 0000000000..3b3663522e
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Av1Decoder.cs
@@ -0,0 +1,62 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1;
+
+internal class Av1Decoder : IAv1TileReader
+{
+ private readonly ObuReader obuReader;
+ private readonly Configuration configuration;
+ private Av1TileReader? tileReader;
+ private Av1FrameDecoder? frameDecoder;
+
+ public Av1Decoder(Configuration configuration)
+ {
+ this.configuration = configuration;
+ this.obuReader = new();
+ }
+
+ public ObuFrameHeader? FrameHeader { get; private set; }
+
+ public ObuSequenceHeader? SequenceHeader { get; private set; }
+
+ public Av1FrameInfo? FrameInfo { get; private set; }
+
+ public Av1FrameBuffer? FrameBuffer { get; private set; }
+
+ public void Decode(Span buffer)
+ {
+ Av1BitStreamReader reader = new(buffer);
+ this.obuReader.ReadAll(ref reader, buffer.Length, () => this, false);
+ Guard.NotNull(this.tileReader, nameof(this.tileReader));
+ Guard.NotNull(this.SequenceHeader, nameof(this.SequenceHeader));
+ Guard.NotNull(this.FrameHeader, nameof(this.FrameHeader));
+
+ this.FrameInfo = this.tileReader.FrameInfo;
+ this.FrameBuffer = new(this.configuration, this.SequenceHeader, this.SequenceHeader.ColorConfig.GetColorFormat(), false);
+ this.frameDecoder = new(this.SequenceHeader, this.FrameHeader, this.FrameInfo, this.FrameBuffer);
+ this.frameDecoder.DecodeFrame();
+ }
+
+ public void ReadTile(Span tileData, int tileNum)
+ {
+ if (this.tileReader == null)
+ {
+ this.SequenceHeader = this.obuReader.SequenceHeader;
+ this.FrameHeader = this.obuReader.FrameHeader;
+ Guard.NotNull(this.tileReader, nameof(this.tileReader));
+ Guard.NotNull(this.SequenceHeader, nameof(this.SequenceHeader));
+ Guard.NotNull(this.FrameHeader, nameof(this.FrameHeader));
+ this.FrameInfo = new(this.SequenceHeader);
+ this.FrameBuffer = new(this.configuration, this.SequenceHeader, this.SequenceHeader.ColorConfig.GetColorFormat(), false);
+ this.frameDecoder = new(this.SequenceHeader, this.FrameHeader, this.FrameInfo, this.FrameBuffer);
+ this.tileReader = new Av1TileReader(this.configuration, this.SequenceHeader, this.FrameHeader, this.frameDecoder);
+ }
+
+ this.tileReader.ReadTile(tileData, tileNum);
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1FrameBuffer.cs b/src/ImageSharp/Formats/Heif/Av1/Av1FrameBuffer.cs
new file mode 100644
index 0000000000..cbeefa2128
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Av1FrameBuffer.cs
@@ -0,0 +1,193 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+using SixLabors.ImageSharp.Memory;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1;
+
+///
+/// Buffer for the pixels of a single frame.
+///
+internal class Av1FrameBuffer : IDisposable
+ where T : struct
+{
+ private const int DecoderPaddingValue = 72;
+ private const int PictureBufferYFlag = 1 << 0;
+ private const int PictureBufferCbFlag = 1 << 1;
+ private const int PictureBufferCrFlag = 1 << 2;
+ private const int PictureBufferLumaMask = PictureBufferYFlag;
+ private const int PictureBufferFullMask = PictureBufferYFlag | PictureBufferCbFlag | PictureBufferCrFlag;
+
+ public Av1FrameBuffer(Configuration configuration, ObuSequenceHeader sequenceHeader, Av1ColorFormat maxColorFormat, bool is16BitPipeline)
+ {
+ Av1ColorFormat colorFormat = sequenceHeader.ColorConfig.IsMonochrome ? Av1ColorFormat.Yuv400 : maxColorFormat;
+ this.MaxWidth = sequenceHeader.MaxFrameWidth;
+ this.MaxHeight = sequenceHeader.MaxFrameHeight;
+ this.BitDepth = sequenceHeader.ColorConfig.BitDepth;
+ int bitsPerPixel = this.BitDepth > Av1BitDepth.EightBit || is16BitPipeline ? 2 : 1;
+ this.ColorFormat = colorFormat;
+ this.BufferEnableMask = sequenceHeader.ColorConfig.IsMonochrome ? PictureBufferLumaMask : PictureBufferFullMask;
+
+ int leftPadding = DecoderPaddingValue;
+ int rightPadding = DecoderPaddingValue;
+ int topPadding = DecoderPaddingValue;
+ int bottomPadding = DecoderPaddingValue;
+
+ this.StartPosition = new Point(leftPadding, topPadding);
+
+ this.Width = this.MaxWidth;
+ this.Height = this.MaxHeight;
+ int strideY = this.MaxWidth + leftPadding + rightPadding;
+ int heightY = this.MaxHeight + topPadding + bottomPadding;
+ this.OriginX = leftPadding;
+ this.OriginY = topPadding;
+ this.OriginOriginY = bottomPadding;
+ int strideChroma = 0;
+ int heightChroma = 0;
+ switch (this.ColorFormat)
+ {
+ case Av1ColorFormat.Yuv420:
+ strideChroma = (strideY + 1) >> 1;
+ heightChroma = (heightY + 1) >> 1;
+ break;
+ case Av1ColorFormat.Yuv422:
+ strideChroma = (strideY + 1) >> 1;
+ heightChroma = heightY;
+ break;
+ case Av1ColorFormat.Yuv444:
+ strideChroma = strideY;
+ heightChroma = heightY;
+ break;
+ }
+
+ this.PackedFlag = false;
+
+ this.BufferY = null;
+ this.BufferCb = null;
+ this.BufferCr = null;
+ if ((this.BufferEnableMask & PictureBufferYFlag) != 0)
+ {
+ this.BufferY = configuration.MemoryAllocator.Allocate2D(strideY * bitsPerPixel, heightY);
+ }
+
+ if ((this.BufferEnableMask & PictureBufferCbFlag) != 0)
+ {
+ this.BufferCb = configuration.MemoryAllocator.Allocate2D(strideChroma * bitsPerPixel, heightChroma);
+ }
+
+ if ((this.BufferEnableMask & PictureBufferCrFlag) != 0)
+ {
+ this.BufferCr = configuration.MemoryAllocator.Allocate2D(strideChroma * bitsPerPixel, heightChroma);
+ }
+
+ this.BitIncrementY = null;
+ this.BitIncrementCb = null;
+ this.BitIncrementCr = null;
+ this.BitIncrementY = null;
+ this.BitIncrementCb = null;
+ this.BitIncrementCr = null;
+ }
+
+ public Point StartPosition { get; private set; }
+
+ ///
+ /// Gets the Y luma buffer.
+ ///
+ public Buffer2D? BufferY { get; private set; }
+
+ ///
+ /// Gets the U chroma buffer.
+ ///
+ public Buffer2D? BufferCb { get; private set; }
+
+ ///
+ /// Gets the V chroma buffer.
+ ///
+ public Buffer2D? BufferCr { get; private set; }
+
+ public Buffer2D? BitIncrementY { get; private set; }
+
+ public Buffer2D? BitIncrementCb { get; private set; }
+
+ public Buffer2D? BitIncrementCr { get; private set; }
+
+ ///
+ /// Gets or sets the horizontal padding distance.
+ ///
+ public int OriginX { get; set; }
+
+ ///
+ /// Gets or sets the vertical padding distance.
+ ///
+ public int OriginY { get; set; }
+
+ ///
+ /// Gets or sets the vertical bottom padding distance
+ ///
+ public int OriginOriginY { get; set; }
+
+ ///
+ /// Gets or sets the Luma picture width, which excludes the padding.
+ ///
+ public int Width { get; set; }
+
+ ///
+ /// Gets or sets the Luma picture height, which excludes the padding.
+ ///
+ public int Height { get; set; }
+
+ ///
+ /// Gets or sets the Lume picture width.
+ ///
+ public int MaxWidth { get; set; }
+
+ ///
+ /// Gets or sets the pixel bit depth.
+ ///
+ public Av1BitDepth BitDepth { get; set; }
+
+ ///
+ /// Gets or sets the chroma subsampling.
+ ///
+ public Av1ColorFormat ColorFormat { get; set; }
+
+ ///
+ /// Gets or sets the Luma picture height.
+ ///
+ public int MaxHeight { get; set; }
+
+ public int LumaSize { get; }
+
+ public int ChromaSize { get; }
+
+ ///
+ /// Gets or sets a value indicating whether the bytes of the buffers are packed.
+ ///
+ public bool PackedFlag { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether film grain parameters are present for this frame.
+ ///
+ public bool FilmGrainFlag { get; set; }
+
+ public int BufferEnableMask { get; set; }
+
+ public bool Is16BitPipeline { get; set; }
+
+ public void Dispose()
+ {
+ this.BufferY?.Dispose();
+ this.BufferY = null;
+ this.BufferCb?.Dispose();
+ this.BufferCb = null;
+ this.BufferCr?.Dispose();
+ this.BufferCr = null;
+ this.BitIncrementY?.Dispose();
+ this.BitIncrementY = null;
+ this.BitIncrementCb?.Dispose();
+ this.BitIncrementCb = null;
+ this.BitIncrementCr?.Dispose();
+ this.BitIncrementCr = null;
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1Math.cs b/src/ImageSharp/Formats/Heif/Av1/Av1Math.cs
new file mode 100644
index 0000000000..e899a7dfcb
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Av1Math.cs
@@ -0,0 +1,205 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System;
+using System.Runtime.InteropServices;
+using System.Security.Cryptography;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1;
+
+internal static class Av1Math
+{
+ public static int MostSignificantBit(uint value)
+ {
+ int log = 0;
+ int i;
+
+ Guard.IsTrue(value != 0, nameof(value), "Must have al least 1 bit set");
+
+ for (i = 4; i >= 0; --i)
+ {
+ int shift = 1 << i;
+ uint x = value >> shift;
+ if (x != 0)
+ {
+ value = x;
+ log += shift;
+ }
+ }
+
+ return log;
+ }
+
+ public static uint Log2(uint n)
+ {
+ uint result = 0U;
+ while ((n >>= 1) > 0)
+ {
+ result++;
+ }
+
+ return result;
+ }
+
+ public static int Log2(int n)
+ {
+ int result = 0;
+ while ((n >>= 1) > 0)
+ {
+ result++;
+ }
+
+ return result;
+ }
+
+ ///
+ /// Long Log 2
+ /// This is a quick adaptation of a Number
+ /// Leading Zeros(NLZ) algorithm to get the log2f of a 32-bit number
+ ///
+ internal static uint Log2_32(uint x)
+ {
+ uint log = 0;
+ int i;
+ for (i = 4; i >= 0; --i)
+ {
+ uint shift = 1u << i;
+ uint n = x >> (int)shift;
+ if (n != 0)
+ {
+ x = n;
+ log += shift;
+ }
+ }
+
+ return log;
+ }
+
+ public static uint FloorLog2(uint value)
+ {
+ uint s = 0;
+ while (value != 0U)
+ {
+ value >>= 1;
+ s++;
+ }
+
+ return s - 1;
+ }
+
+ public static uint CeilLog2(uint value)
+ {
+ if (value < 2)
+ {
+ return 0;
+ }
+
+ uint i = 1;
+ uint p = 2;
+ while (p < value)
+ {
+ i++;
+ p <<= 1;
+ }
+
+ return i;
+ }
+
+ public static uint Clip1(uint value, int bitDepth) =>
+ Clip3(0, (1U << bitDepth) - 1, value);
+
+ public static uint Clip3(uint x, uint y, uint z)
+ {
+ if (z < x)
+ {
+ return x;
+ }
+
+ if (z > y)
+ {
+ return y;
+ }
+
+ return z;
+ }
+
+ public static int Clip3(int x, int y, int z)
+ {
+ if (z < x)
+ {
+ return x;
+ }
+
+ if (z > y)
+ {
+ return y;
+ }
+
+ return z;
+ }
+
+ public static uint Round2(uint value, int n)
+ {
+ if (n == 0)
+ {
+ return value;
+ }
+
+ return (uint)((value + (1 << (n - 1))) >> n);
+ }
+
+ public static int Round2(int value, int n)
+ {
+ if (value < 0)
+ {
+ value = -value;
+ }
+
+ return (int)Round2((uint)value, n);
+ }
+
+ internal static int AlignPowerOf2(int value, int n)
+ {
+ int mask = (1 << n) - 1;
+ return (value + mask) & ~mask;
+ }
+
+ internal static int RoundPowerOf2(int value, int n) => (value + ((1 << n) >> 1)) >> n;
+
+ internal static int Clamp(int value, int low, int high)
+ => value < low ? low : (value > high ? high : value);
+
+ internal static long Clamp(long value, long low, long high)
+ => value < low ? low : (value > high ? high : value);
+
+ internal static int DivideLog2Floor(int value, int n)
+ => value >> n;
+
+ internal static int DivideLog2Ceiling(int value, int n)
+ => (value + (1 << n) - 1) >> n;
+
+ // Last 3 bits are the value of mod 8.
+ internal static int Modulus8(int value) => value & 0x07;
+
+ internal static int DivideBy8Floor(int value) => value >> 3;
+
+ internal static int RoundPowerOf2Signed(int value, int n)
+ => (value < 0) ? -RoundPowerOf2(-value, n) : RoundPowerOf2(value, n);
+
+ internal static int RoundShift(long value, int bit)
+ {
+ DebugGuard.MustBeGreaterThanOrEqualTo(bit, 1, nameof(bit));
+ return (int)((value + (1L << (bit - 1))) >> bit);
+ }
+
+ ///
+ /// implies .
+ ///
+ internal static bool Implies(bool a, bool b) => !a || b;
+
+ internal static int GetBit(int value, int n)
+ => (value & (1 << n)) >> n;
+
+ internal static void SetBit(ref int endOfBlockExtra, int n)
+ => endOfBlockExtra |= 1 << n;
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1PartitionType.cs b/src/ImageSharp/Formats/Heif/Av1/Av1PartitionType.cs
new file mode 100644
index 0000000000..11f973a064
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Av1PartitionType.cs
@@ -0,0 +1,152 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1;
+
+internal enum Av1PartitionType
+{
+ // See section 6.10.4 of Avi Spcification
+
+ ///
+ /// Not partitioned any further.
+ ///
+ ///
+ ///
+ /// ***
+ /// * *
+ /// ***
+ ///
+ ///
+ None = 0,
+
+ ///
+ /// Horizontally split in 2 partitions.
+ ///
+ ///
+ ///
+ /// ***
+ /// * *
+ /// ***
+ /// * *
+ /// ***
+ ///
+ ///
+ Horizontal = 1,
+
+ ///
+ /// Vertically split in 2 partitions.
+ ///
+ ///
+ ///
+ /// *****
+ /// * * *
+ /// *****
+ ///
+ ///
+ Vertical = 2,
+
+ ///
+ /// 4 equally sized partitions.
+ ///
+ ///
+ ///
+ /// *****
+ /// * * *
+ /// *****
+ /// * * *
+ /// *****
+ ///
+ ///
+ Split = 3,
+
+ ///
+ /// Horizontal split and the top partition is split again.
+ ///
+ ///
+ ///
+ /// *****
+ /// * * *
+ /// *****
+ /// * *
+ /// *****
+ ///
+ ///
+ HorizontalA = 4,
+
+ ///
+ /// Horizontal split and the bottom partition is split again.
+ ///
+ ///
+ ///
+ /// *****
+ /// * *
+ /// *****
+ /// * * *
+ /// *****
+ ///
+ ///
+ HorizontalB = 5,
+
+ ///
+ /// Vertical split and the left partition is split again.
+ ///
+ ///
+ ///
+ /// *****
+ /// * * *
+ /// *** *
+ /// * * *
+ /// *****
+ ///
+ ///
+ VerticalA = 6,
+
+ ///
+ /// Vertical split and the right partition is split again.
+ ///
+ ///
+ ///
+ /// *****
+ /// * * *
+ /// * ***
+ /// * * *
+ /// *****
+ ///
+ ///
+ VerticalB = 7,
+
+ ///
+ /// 4:1 horizontal partition.
+ ///
+ ///
+ ///
+ /// ***
+ /// * *
+ /// ***
+ /// * *
+ /// ***
+ /// * *
+ /// ***
+ /// * *
+ /// ***
+ ///
+ ///
+ Horizontal4 = 8,
+
+ ///
+ /// 4:1 vertical partition.
+ ///
+ ///
+ ///
+ /// *********
+ /// * * * * *
+ /// *********
+ ///
+ ///
+ Vertical4 = 9,
+
+ ///
+ /// Invalid value.
+ ///
+ Invalid = 255
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1PartitionTypeExtensions.cs b/src/ImageSharp/Formats/Heif/Av1/Av1PartitionTypeExtensions.cs
new file mode 100644
index 0000000000..99ba78c3ba
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Av1PartitionTypeExtensions.cs
@@ -0,0 +1,104 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1;
+
+internal static class Av1PartitionTypeExtensions
+{
+ private static readonly Av1BlockSize[][] PartitionSubSize = [
+ [
+ Av1BlockSize.Block4x4,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block8x8,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block16x16,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block32x32,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block64x64,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block128x128,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid
+ ], [
+ Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block8x4,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block16x8,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block32x16,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block64x32,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block128x64,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid
+ ], [
+ Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block4x8,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block8x16,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block16x32,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block32x64,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block64x128,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid
+ ], [
+ Av1BlockSize.Block4x4,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block4x4,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block8x8,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block16x16,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block32x32,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block64x64,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid
+ ], [
+ Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block8x4,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block16x8,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block32x16,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block64x32,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block128x64,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid
+ ], [
+ Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block8x4,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block16x8,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block32x16,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block64x32,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block128x64,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid
+ ], [
+ Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block4x8,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block8x16,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block16x32,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block32x64,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block64x128,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid
+ ], [
+ Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block4x8,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block8x16,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block16x32,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block32x64,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block64x128,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid
+ ], [
+ Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block16x4,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block32x8,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block64x16,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid,
+ ], [
+ Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block4x16,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block8x32,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Block16x64,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid,
+ Av1BlockSize.Invalid, Av1BlockSize.Invalid, Av1BlockSize.Invalid,
+ ]
+ ];
+
+ public static Av1BlockSize GetBlockSubSize(this Av1PartitionType partition, Av1BlockSize blockSize)
+ => PartitionSubSize[(int)partition][(int)blockSize];
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1Plane.cs b/src/ImageSharp/Formats/Heif/Av1/Av1Plane.cs
new file mode 100644
index 0000000000..9d73cda42a
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Av1Plane.cs
@@ -0,0 +1,11 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1;
+
+internal enum Av1Plane : int
+{
+ Y = 0,
+ U = 1,
+ V = 2,
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1DefaultDistributions.cs b/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1DefaultDistributions.cs
new file mode 100644
index 0000000000..09efc4ba93
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1DefaultDistributions.cs
@@ -0,0 +1,2269 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Entropy;
+
+internal static class Av1DefaultDistributions
+{
+ public static Av1Distribution[] FrameYMode =>
+ [
+ new(22801, 23489, 24293, 24756, 25601, 26123, 26606, 27418, 27945, 29228, 29685, 30349),
+ new(18673, 19845, 22631, 23318, 23950, 24649, 25527, 27364, 28152, 29701, 29984, 30852),
+ new(19770, 20979, 23396, 23939, 24241, 24654, 25136, 27073, 27830, 29360, 29730, 30659),
+ new(20155, 21301, 22838, 23178, 23261, 23533, 23703, 24804, 25352, 26575, 27016, 28049)
+ ];
+
+ public static Av1Distribution[][] FilterYMode =>
+ [
+ [
+ new(15588, 17027, 19338, 20218, 20682, 21110, 21825, 23244, 24189, 28165, 29093, 30466),
+ new(12016, 18066, 19516, 20303, 20719, 21444, 21888, 23032, 24434, 28658, 30172, 31409),
+ new(10052, 10771, 22296, 22788, 23055, 23239, 24133, 25620, 26160, 29336, 29929, 31567),
+ new(14091, 15406, 16442, 18808, 19136, 19546, 19998, 22096, 24746, 29585, 30958, 32462),
+ new(12122, 13265, 15603, 16501, 18609, 20033, 22391, 25583, 26437, 30261, 31073, 32475)
+ ], [
+ new(10023, 19585, 20848, 21440, 21832, 22760, 23089, 24023, 25381, 29014, 30482, 31436),
+ new(5983, 24099, 24560, 24886, 25066, 25795, 25913, 26423, 27610, 29905, 31276, 31794),
+ new(7444, 12781, 20177, 20728, 21077, 21607, 22170, 23405, 24469, 27915, 29090, 30492),
+ new(8537, 14689, 15432, 17087, 17408, 18172, 18408, 19825, 24649, 29153, 31096, 32210),
+ new(7543, 14231, 15496, 16195, 17905, 20717, 21984, 24516, 26001, 29675, 30981, 31994)
+ ], [
+ new(12613, 13591, 21383, 22004, 22312, 22577, 23401, 25055, 25729, 29538, 30305, 32077),
+ new(9687, 13470, 18506, 19230, 19604, 20147, 20695, 22062, 23219, 27743, 29211, 30907),
+ new(6183, 6505, 26024, 26252, 26366, 26434, 27082, 28354, 28555, 30467, 30794, 32086),
+ new(10718, 11734, 14954, 17224, 17565, 17924, 18561, 21523, 23878, 28975, 30287, 32252),
+ new(9194, 9858, 16501, 17263, 18424, 19171, 21563, 25961, 26561, 30072, 30737, 32463)
+ ], [
+ new(12602, 14399, 15488, 18381, 18778, 19315, 19724, 21419, 25060, 29696, 30917, 32409),
+ new(8203, 13821, 14524, 17105, 17439, 18131, 18404, 19468, 25225, 29485, 31158, 32342),
+ new(8451, 9731, 15004, 17643, 18012, 18425, 19070, 21538, 24605, 29118, 30078, 32018),
+ new(7714, 9048, 9516, 16667, 16817, 16994, 17153, 18767, 26743, 30389, 31536, 32528),
+ new(8843, 10280, 11496, 15317, 16652, 17943, 19108, 22718, 25769, 29953, 30983, 32485)
+ ], [
+ new(12578, 13671, 15979, 16834, 19075, 20913, 22989, 25449, 26219, 30214, 31150, 32477),
+ new(9563, 13626, 15080, 15892, 17756, 20863, 22207, 24236, 25380, 29653, 31143, 32277),
+ new(8356, 8901, 17616, 18256, 19350, 20106, 22598, 25947, 26466, 29900, 30523, 32261),
+ new(10835, 11815, 13124, 16042, 17018, 18039, 18947, 22753, 24615, 29489, 30883, 32482),
+ new(7618, 8288, 9859, 10509, 15386, 18657, 22903, 28776, 29180, 31355, 31802, 32593)
+ ]
+ ];
+
+ public static Av1Distribution[][] UvMode =>
+ [
+ [
+ new(22631, 24152, 25378, 25661, 25986, 26520, 27055, 27923, 28244, 30059, 30941, 31961),
+ new(9513, 26881, 26973, 27046, 27118, 27664, 27739, 27824, 28359, 29505, 29800, 31796),
+ new(9845, 9915, 28663, 28704, 28757, 28780, 29198, 29822, 29854, 30764, 31777, 32029),
+ new(13639, 13897, 14171, 25331, 25606, 25727, 25953, 27148, 28577, 30612, 31355, 32493),
+ new(9764, 9835, 9930, 9954, 25386, 27053, 27958, 28148, 28243, 31101, 31744, 32363),
+ new(11825, 13589, 13677, 13720, 15048, 29213, 29301, 29458, 29711, 31161, 31441, 32550),
+ new(14175, 14399, 16608, 16821, 17718, 17775, 28551, 30200, 30245, 31837, 32342, 32667),
+ new(12885, 13038, 14978, 15590, 15673, 15748, 16176, 29128, 29267, 30643, 31961, 32461),
+ new(12026, 13661, 13874, 15305, 15490, 15726, 15995, 16273, 28443, 30388, 30767, 32416),
+ new(19052, 19840, 20579, 20916, 21150, 21467, 21885, 22719, 23174, 28861, 30379, 32175),
+ new(18627, 19649, 20974, 21219, 21492, 21816, 22199, 23119, 23527, 27053, 31397, 32148),
+ new(17026, 19004, 19997, 20339, 20586, 21103, 21349, 21907, 22482, 25896, 26541, 31819),
+ new(12124, 13759, 14959, 14992, 15007, 15051, 15078, 15166, 15255, 15753, 16039, 16606)
+ ], [
+ new(10407, 11208, 12900, 13181, 13823, 14175, 14899, 15656, 15986, 20086, 20995, 22455, 24212),
+ new(4532, 19780, 20057, 20215, 20428, 21071, 21199, 21451, 22099, 24228, 24693, 27032, 29472),
+ new(5273, 5379, 20177, 20270, 20385, 20439, 20949, 21695, 21774, 23138, 24256, 24703, 26679),
+ new(6740, 7167, 7662, 14152, 14536, 14785, 15034, 16741, 18371, 21520, 22206, 23389, 24182),
+ new(4987, 5368, 5928, 6068, 19114, 20315, 21857, 22253, 22411, 24911, 25380, 26027, 26376),
+ new(5370, 6889, 7247, 7393, 9498, 21114, 21402, 21753, 21981, 24780, 25386, 26517, 27176),
+ new(4816, 4961, 7204, 7326, 8765, 8930, 20169, 20682, 20803, 23188, 23763, 24455, 24940),
+ new(6608, 6740, 8529, 9049, 9257, 9356, 9735, 18827, 19059, 22336, 23204, 23964, 24793),
+ new(5998, 7419, 7781, 8933, 9255, 9549, 9753, 10417, 18898, 22494, 23139, 24764, 25989),
+ new(10660, 11298, 12550, 12957, 13322, 13624, 14040, 15004, 15534, 20714, 21789, 23443, 24861),
+ new(10522, 11530, 12552, 12963, 13378, 13779, 14245, 15235, 15902, 20102, 22696, 23774, 25838),
+ new(10099, 10691, 12639, 13049, 13386, 13665, 14125, 15163, 15636, 19676, 20474, 23519, 25208),
+ new(3144, 5087, 7382, 7504, 7593, 7690, 7801, 8064, 8232, 9248, 9875, 10521, 29048)
+ ]
+ ];
+
+ public static Av1Distribution[] AngleDelta =>
+ [
+ new(2180, 5032, 7567, 22776, 26989, 30217),
+ new(2301, 5608, 8801, 23487, 26974, 30330),
+ new(3780, 11018, 13699, 19354, 23083, 31286),
+ new(4581, 11226, 15147, 17138, 21834, 28397),
+ new(1737, 10927, 14509, 19588, 22745, 28823),
+ new(2664, 10176, 12485, 17650, 21600, 30495),
+ new(2240, 11096, 15453, 20341, 22561, 28917),
+ new(3605, 10428, 12459, 17676, 21244, 30655)
+ ];
+
+ public static Av1Distribution IntraBlockCopy => new(30531);
+
+ public static Av1Distribution[] PartitionTypes =>
+ [
+ new(19132, 25510, 30392),
+ new(13928, 19855, 28540),
+ new(12522, 23679, 28629),
+ new(9896, 18783, 25853),
+ new(15597, 20929, 24571, 26706, 27664, 28821, 29601, 30571, 31902),
+ new(7925, 11043, 16785, 22470, 23971, 25043, 26651, 28701, 29834),
+ new(5414, 13269, 15111, 20488, 22360, 24500, 25537, 26336, 32117),
+ new(2662, 6362, 8614, 20860, 23053, 24778, 26436, 27829, 31171),
+ new(18462, 20920, 23124, 27647, 28227, 29049, 29519, 30178, 31544),
+ new(7689, 9060, 12056, 24992, 25660, 26182, 26951, 28041, 29052),
+ new(6015, 9009, 10062, 24544, 25409, 26545, 27071, 27526, 32047),
+ new(1394, 2208, 2796, 28614, 29061, 29466, 29840, 30185, 31899),
+ new(20137, 21547, 23078, 29566, 29837, 30261, 30524, 30892, 31724),
+ new(6732, 7490, 9497, 27944, 28250, 28515, 28969, 29630, 30104),
+ new(5945, 7663, 8348, 28683, 29117, 29749, 30064, 30298, 32238),
+ new(870, 1212, 1487, 31198, 31394, 31574, 31743, 31881, 32332),
+ new(27899, 28219, 28529, 32484, 32539, 32619, 32639),
+ new(6607, 6990, 8268, 32060, 32219, 32338, 32371),
+ new(5429, 6676, 7122, 32027, 32227, 32531, 32582),
+ new(711, 966, 1172, 32448, 32538, 32617, 32664)
+ ];
+
+ ///
+ /// Gets the skip .
+ ///
+ /// SVT: default_skip_cdfs
+ public static Av1Distribution[] Skip => [new(31671), new(16515), new(4576)];
+
+ ///
+ /// Gets the skip mode .
+ ///
+ /// SVT: default_skip_mode_cdfs
+ public static Av1Distribution[] SkipMode => [new(32621), new(20708), new(8127)];
+
+ public static Av1Distribution DeltaLoopFilterAbsolute => new(28160, 32120, 32677);
+
+ public static Av1Distribution DeltaQuantizerAbsolute => new(28160, 32120, 32677);
+
+ ///
+ /// Gets the Segment identifier .
+ ///
+ /// SVT: default_spatial_pred_seg_tree_cdf
+ public static Av1Distribution[] SegmentId =>
+ [
+ new(5622, 7893, 16093, 18233, 27809, 28373, 32533),
+ new(14274, 18230, 22557, 24935, 29980, 30851, 32344),
+ new(27527, 28487, 28723, 28890, 32397, 32647, 32679),
+ ];
+
+ public static Av1Distribution[][] KeyFrameYMode =>
+ [
+ [
+ new(15588, 17027, 19338, 20218, 20682, 21110, 21825, 23244, 24189, 28165, 29093, 30466),
+ new(12016, 18066, 19516, 20303, 20719, 21444, 21888, 23032, 24434, 28658, 30172, 31409),
+ new(10052, 10771, 22296, 22788, 23055, 23239, 24133, 25620, 26160, 29336, 29929, 31567),
+ new(14091, 15406, 16442, 18808, 19136, 19546, 19998, 22096, 24746, 29585, 30958, 32462),
+ new(12122, 13265, 15603, 16501, 18609, 20033, 22391, 25583, 26437, 30261, 31073, 32475),
+ ], [
+ new(10023, 19585, 20848, 21440, 21832, 22760, 23089, 24023, 25381, 29014, 30482, 31436),
+ new(5983, 24099, 24560, 24886, 25066, 25795, 25913, 26423, 27610, 29905, 31276, 31794),
+ new(7444, 12781, 20177, 20728, 21077, 21607, 22170, 23405, 24469, 27915, 29090, 30492),
+ new(8537, 14689, 15432, 17087, 17408, 18172, 18408, 19825, 24649, 29153, 31096, 32210),
+ new(7543, 14231, 15496, 16195, 17905, 20717, 21984, 24516, 26001, 29675, 30981, 31994)
+ ], [
+ new(12613, 13591, 21383, 22004, 22312, 22577, 23401, 25055, 25729, 29538, 30305, 32077),
+ new(9687, 13470, 18506, 19230, 19604, 20147, 20695, 22062, 23219, 27743, 29211, 30907),
+ new(6183, 6505, 26024, 26252, 26366, 26434, 27082, 28354, 28555, 30467, 30794, 32086),
+ new(10718, 11734, 14954, 17224, 17565, 17924, 18561, 21523, 23878, 28975, 30287, 32252),
+ new(9194, 9858, 16501, 17263, 18424, 19171, 21563, 25961, 26561, 30072, 30737, 32463)
+ ], [
+ new(12602, 14399, 15488, 18381, 18778, 19315, 19724, 21419, 25060, 29696, 30917, 32409),
+ new(8203, 13821, 14524, 17105, 17439, 18131, 18404, 19468, 25225, 29485, 31158, 32342),
+ new(8451, 9731, 15004, 17643, 18012, 18425, 19070, 21538, 24605, 29118, 30078, 32018),
+ new(7714, 9048, 9516, 16667, 16817, 16994, 17153, 18767, 26743, 30389, 31536, 32528),
+ new(8843, 10280, 11496, 15317, 16652, 17943, 19108, 22718, 25769, 29953, 30983, 32485)
+ ], [
+ new(12578, 13671, 15979, 16834, 19075, 20913, 22989, 25449, 26219, 30214, 31150, 32477),
+ new(9563, 13626, 15080, 15892, 17756, 20863, 22207, 24236, 25380, 29653, 31143, 32277),
+ new(8356, 8901, 17616, 18256, 19350, 20106, 22598, 25947, 26466, 29900, 30523, 32261),
+ new(10835, 11815, 13124, 16042, 17018, 18039, 18947, 22753, 24615, 29489, 30883, 32482),
+ new(7618, 8288, 9859, 10509, 15386, 18657, 22903, 28776, 29180, 31355, 31802, 32593)
+ ]
+ ];
+
+ public static Av1Distribution FilterIntraMode => new(8949, 12776, 17211, 29558);
+
+ public static Av1Distribution[] FilterIntra =>
+ [
+ new(4621), new(6743), new(5893), new(7866), new(12551), new(9394),
+ new(12408), new(14301), new(12756), new(22343), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(12770), new(10368),
+ new(20229), new(18101), new(16384), new(16384)
+ ];
+
+ public static Av1Distribution[][] TransformSize =>
+ [
+ [new(19968), new(19968), new(24320)],
+ [new(12272, 30172), new(12272, 30172), new(18677, 30848)],
+ [new(12986, 15180), new(12986, 15180), new(24302, 25602)],
+ [new(5782, 11475), new(5782, 11475), new(16803, 22759)],
+ ];
+
+ private static Av1Distribution[][][] EndOfBlockFlagMulti16 =>
+ [
+ [
+ [new(840, 1039, 1980, 4895), new(370, 671, 1883, 4471)],
+ [new(3247, 4950, 9688, 14563), new(1904, 3354, 7763, 14647)]
+ ],
+ [
+ [new(2125, 2551, 5165, 8946), new(513, 765, 1859, 6339)],
+ [new(7637, 9498, 14259, 19108), new(2497, 4096, 8866, 16993)]
+ ],
+ [
+ [new(4016, 4897, 8881, 14968), new(716, 1105, 2646, 10056)],
+ [new(11139, 13270, 18241, 23566), new(3192, 5032, 10297, 19755)]
+ ],
+ [
+ [new(6708, 8958, 14746, 22133), new(1222, 2074, 4783, 15410)],
+ [new(19575, 21766, 26044, 29709), new(7297, 10767, 19273, 28194)]
+ ]
+ ];
+
+ private static Av1Distribution[][][] EndOfBlockFlagMulti32 =>
+ [
+ [
+ [new(400, 520, 977, 2102, 6542), new(210, 405, 1315, 3326, 7537)],
+ [new(2636, 4273, 7588, 11794, 20401), new(1786, 3179, 6902, 11357, 19054)]
+ ],
+ [
+ [new(989, 1249, 2019, 4151, 10785), new(313, 441, 1099, 2917, 8562)],
+ [new(8394, 10352, 13932, 18855, 26014), new(2578, 4124, 8181, 13670, 24234)]
+ ],
+ [
+ [new(2515, 3003, 4452, 8162, 16041), new(574, 821, 1836, 5089, 13128)],
+ [new(13468, 16303, 20361, 25105, 29281), new(3542, 5502, 10415, 16760, 25644)]
+ ],
+ [
+ [new(4617, 5709, 8446, 13584, 23135), new(1156, 1702, 3675, 9274, 20539)],
+ [new(22086, 24282, 27010, 29770, 31743), new(7699, 10897, 20891, 26926, 31628)]
+ ]
+ ];
+
+ private static Av1Distribution[][][] EndOfBlockFlagMulti64 =>
+ [
+ [
+ [new(329, 498, 1101, 1784, 3265, 7758), new(335, 730, 1459, 5494, 8755, 12997)],
+ [new(3505, 5304, 10086, 13814, 17684, 23370), new(1563, 2700, 4876, 10911, 14706, 22480)],
+ ],
+ [
+ [new(1260, 1446, 2253, 3712, 6652, 13369), new(401, 605, 1029, 2563, 5845, 12626)],
+ [new(8609, 10612, 14624, 18714, 22614, 29024), new(1923, 3127, 5867, 9703, 14277, 27100)]
+ ],
+ [
+ [new(2374, 2772, 4583, 7276, 12288, 19706), new(497, 810, 1315, 3000, 7004, 15641)],
+ [new(15050, 17126, 21410, 24886, 28156, 30726), new(4034, 6290, 10235, 14982, 21214, 28491)]
+ ],
+ [
+ [new(6307, 7541, 12060, 16358, 22553, 27865), new(1289, 2320, 3971, 7926, 14153, 24291)],
+ [new(24212, 25708, 28268, 30035, 31307, 32049), new(8726, 12378, 19409, 26450, 30038, 32462)]
+ ]
+ ];
+
+ private static Av1Distribution[][][] EndOfBlockFlagMulti128 =>
+ [
+ [
+ [new(219, 482, 1140, 2091, 3680, 6028, 12586), new(371, 699, 1254, 4830, 9479, 12562, 17497)],
+ [new(5245, 7456, 12880, 15852, 20033, 23932, 27608), new(2054, 3472, 5869, 14232, 18242, 20590, 26752)]
+ ],
+ [
+ [new(685, 933, 1488, 2714, 4766, 8562, 19254), new(217, 352, 618, 2303, 5261, 9969, 17472)],
+ [new(8045, 11200, 15497, 19595, 23948, 27408, 30938), new(2310, 4160, 7471, 14997, 17931, 20768, 30240)]
+ ],
+ [
+ [new(1366, 1738, 2527, 5016, 9355, 15797, 24643), new(354, 558, 944, 2760, 7287, 14037, 21779)],
+ [new(13627, 16246, 20173, 24429, 27948, 30415, 31863), new(6275, 9889, 14769, 23164, 27988, 30493, 32272)]
+ ],
+ [
+ [new(3472, 4885, 7489, 12481, 18517, 24536, 29635), new(886, 1731, 3271, 8469, 15569, 22126, 28383)],
+ [new(24313, 26062, 28385, 30107, 31217, 31898, 32345), new(9165, 13282, 21150, 30286, 31894, 32571, 32712)]
+ ]
+ ];
+
+ private static Av1Distribution[][][] EndOfBlockFlagMulti256 =>
+ [
+ [
+ [
+ new(310, 584, 1887, 3589, 6168, 8611, 11352, 15652),
+ new(998, 1850, 2998, 5604, 17341, 19888, 22899, 25583),
+ ],
+ [
+ new(2520, 3240, 5952, 8870, 12577, 17558, 19954, 24168),
+ new(2203, 4130, 7435, 10739, 20652, 23681, 25609, 27261)
+ ],
+ ],
+ [
+ [
+ new(1448, 2109, 4151, 6263, 9329, 13260, 17944, 23300),
+ new(399, 1019, 1749, 3038, 10444, 15546, 22739, 27294)
+ ],
+ [
+ new(6402, 8148, 12623, 15072, 18728, 22847, 26447, 29377),
+ new(1674, 3252, 5734, 10159, 22397, 23802, 24821, 30940)
+ ]
+ ],
+ [
+ [
+ new(3089, 3920, 6038, 9460, 14266, 19881, 25766, 29176),
+ new(1084, 2358, 3488, 5122, 11483, 18103, 26023, 29799)
+ ],
+ [
+ new(11514, 13794, 17480, 20754, 24361, 27378, 29492, 31277),
+ new(6571, 9610, 15516, 21826, 29092, 30829, 31842, 32708)
+ ]
+ ],
+ [
+ [
+ new(5348, 7113, 11820, 15924, 22106, 26777, 30334, 31757),
+ new(2453, 4474, 6307, 8777, 16474, 22975, 29000, 31547)
+ ],
+ [
+ new(23110, 24597, 27140, 28894, 30167, 30927, 31392, 32094),
+ new(9998, 17661, 25178, 28097, 31308, 32038, 32403, 32695)
+ ]
+ ]
+ ];
+
+ private static Av1Distribution[][][] EndOfBlockFlagMulti512 =>
+ [
+ [
+ [
+ new(641, 983, 3707, 5430, 10234, 14958, 18788, 23412, 26061),
+ new(3277, 6554, 9830, 13107, 16384, 19661, 22938, 26214, 29491)
+ ],
+ [
+ new(5095, 6446, 9996, 13354, 16017, 17986, 20919, 26129, 29140),
+ new(3277, 6554, 9830, 13107, 16384, 19661, 22938, 26214, 29491)
+ ]
+ ],
+ [
+ [
+ new(1230, 2278, 5035, 7776, 11871, 15346, 19590, 24584, 28749),
+ new(3277, 6554, 9830, 13107, 16384, 19661, 22938, 26214, 29491)
+ ],
+ [
+ new(7265, 9979, 15819, 19250, 21780, 23846, 26478, 28396, 31811),
+ new(3277, 6554, 9830, 13107, 16384, 19661, 22938, 26214, 29491)
+ ]
+ ],
+ [
+ [
+ new(2624, 3936, 6480, 9686, 13979, 17726, 23267, 28410, 31078),
+ new(3277, 6554, 9830, 13107, 16384, 19661, 22938, 26214, 29491)
+ ],
+ [
+ new(12015, 14769, 19588, 22052, 24222, 25812, 27300, 29219, 32114),
+ new(3277, 6554, 9830, 13107, 16384, 19661, 22938, 26214, 29491)
+ ]
+ ],
+ [
+ [
+ new(5927, 7809, 10923, 14597, 19439, 24135, 28456, 31142, 32060),
+ new(3277, 6554, 9830, 13107, 16384, 19661, 22938, 26214, 29491)
+ ],
+ [
+ new(21093, 23043, 25742, 27658, 29097, 29716, 30073, 30820, 31956),
+ new(3277, 6554, 9830, 13107, 16384, 19661, 22938, 26214, 29491)
+ ]
+ ]
+ ];
+
+ private static Av1Distribution[][][] EndOfBlockFlagMulti1024 =>
+ [
+ [
+ [
+ new(393, 421, 751, 1623, 3160, 6352, 13345, 18047, 22571, 25830),
+ new(2979, 5958, 8937, 11916, 14895, 17873, 20852, 23831, 26810, 29789)
+ ],
+ [
+ new(1865, 1988, 2930, 4242, 10533, 16538, 21354, 27255, 28546, 31784),
+ new(2979, 5958, 8937, 11916, 14895, 17873, 20852, 23831, 26810, 29789)
+ ]
+ ],
+ [
+ [
+ new(696, 948, 3145, 5702, 9706, 13217, 17851, 21856, 25692, 28034),
+ new(2979, 5958, 8937, 11916, 14895, 17873, 20852, 23831, 26810, 29789)
+ ],
+ [
+ new(2672, 3591, 9330, 17084, 22725, 24284, 26527, 28027, 28377, 30876),
+ new(2979, 5958, 8937, 11916, 14895, 17873, 20852, 23831, 26810, 29789)
+ ]
+ ],
+ [
+ [
+ new(2784, 3831, 7041, 10521, 14847, 18844, 23155, 26682, 29229, 31045),
+ new(2979, 5958, 8937, 11916, 14895, 17873, 20852, 23831, 26810, 29789)
+ ],
+ [
+ new(9577, 12466, 17739, 20750, 22061, 23215, 24601, 25483, 25843, 32056),
+ new(2979, 5958, 8937, 11916, 14895, 17873, 20852, 23831, 26810, 29789)
+ ]
+ ],
+ [
+ [
+ new(6698, 8334, 11961, 15762, 20186, 23862, 27434, 29326, 31082, 32050),
+ new(2979, 5958, 8937, 11916, 14895, 17873, 20852, 23831, 26810, 29789)
+ ],
+ [
+ new(20569, 22426, 25569, 26859, 28053, 28913, 29486, 29724, 29807, 32570),
+ new(2979, 5958, 8937, 11916, 14895, 17873, 20852, 23831, 26810, 29789)
+ ]
+ ]
+ ];
+
+ private static Av1Distribution[][][][] CoefficientsBaseRange =>
+ [
+ [
+ [
+ [
+ new(14298, 20718, 24174), new(12536, 19601, 23789), new(8712, 15051, 19503),
+ new(6170, 11327, 15434), new(4742, 8926, 12538), new(3803, 7317, 10546),
+ new(1696, 3317, 4871), new(14392, 19951, 22756), new(15978, 23218, 26818),
+ new(12187, 19474, 23889), new(9176, 15640, 20259), new(7068, 12655, 17028),
+ new(5656, 10442, 14472), new(2580, 4992, 7244), new(12136, 18049, 21426),
+ new(13784, 20721, 24481), new(10836, 17621, 21900), new(8372, 14444, 18847),
+ new(6523, 11779, 16000), new(5337, 9898, 13760), new(3034, 5860, 8462)
+ ],
+ [
+ new(15967, 22905, 26286), new(13534, 20654, 24579), new(9504, 16092, 20535),
+ new(6975, 12568, 16903), new(5364, 10091, 14020), new(4357, 8370, 11857),
+ new(2506, 4934, 7218), new(23032, 28815, 30936), new(19540, 26704, 29719),
+ new(15158, 22969, 27097), new(11408, 18865, 23650), new(8885, 15448, 20250),
+ new(7108, 12853, 17416), new(4231, 8041, 11480), new(19823, 26490, 29156),
+ new(18890, 25929, 28932), new(15660, 23491, 27433), new(12147, 19776, 24488),
+ new(9728, 16774, 21649), new(7919, 14277, 19066), new(5440, 10170, 14185)
+ ]
+ ],
+ [
+ [
+ new(14406, 20862, 24414), new(11824, 18907, 23109), new(8257, 14393, 18803),
+ new(5860, 10747, 14778), new(4475, 8486, 11984), new(3606, 6954, 10043),
+ new(1736, 3410, 5048), new(14430, 20046, 22882), new(15593, 22899, 26709),
+ new(12102, 19368, 23811), new(9059, 15584, 20262), new(6999, 12603, 17048),
+ new(5684, 10497, 14553), new(2822, 5438, 7862), new(15785, 21585, 24359),
+ new(18347, 25229, 28266), new(14974, 22487, 26389), new(11423, 18681, 23271),
+ new(8863, 15350, 20008), new(7153, 12852, 17278), new(3707, 7036, 9982)
+ ],
+ [
+ new(15460, 21696, 25469), new(12170, 19249, 23191), new(8723, 15027, 19332),
+ new(6428, 11704, 15874), new(4922, 9292, 13052), new(4139, 7695, 11010),
+ new(2291, 4508, 6598), new(19856, 26920, 29828), new(17923, 25289, 28792),
+ new(14278, 21968, 26297), new(10910, 18136, 22950), new(8423, 14815, 19627),
+ new(6771, 12283, 16774), new(4074, 7750, 11081), new(19852, 26074, 28672),
+ new(19371, 26110, 28989), new(16265, 23873, 27663), new(12758, 20378, 24952),
+ new(10095, 17098, 21961), new(8250, 14628, 19451), new(5205, 9745, 13622)
+ ]
+ ],
+ [
+ [
+ new(10563, 16233, 19763), new(9794, 16022, 19804), new(6750, 11945, 15759),
+ new(4963, 9186, 12752), new(3845, 7435, 10627), new(3051, 6085, 8834),
+ new(1311, 2596, 3830), new(11246, 16404, 19689), new(12315, 18911, 22731),
+ new(10557, 17095, 21289), new(8136, 14006, 18249), new(6348, 11474, 15565),
+ new(5196, 9655, 13400), new(2349, 4526, 6587), new(13337, 18730, 21569),
+ new(19306, 26071, 28882), new(15952, 23540, 27254), new(12409, 19934, 24430),
+ new(9760, 16706, 21389), new(8004, 14220, 18818), new(4138, 7794, 10961)
+ ],
+ [
+ new(10870, 16684, 20949), new(9664, 15230, 18680), new(6886, 12109, 15408),
+ new(4825, 8900, 12305), new(3630, 7162, 10314), new(3036, 6429, 9387),
+ new(1671, 3296, 4940), new(13819, 19159, 23026), new(11984, 19108, 23120),
+ new(10690, 17210, 21663), new(7984, 14154, 18333), new(6868, 12294, 16124),
+ new(5274, 8994, 12868), new(2988, 5771, 8424), new(19736, 26647, 29141),
+ new(18933, 26070, 28984), new(15779, 23048, 27200), new(12638, 20061, 24532),
+ new(10692, 17545, 22220), new(9217, 15251, 20054), new(5078, 9284, 12594)
+ ]
+ ],
+ [
+ [
+ new(2331, 3662, 5244), new(2891, 4771, 6145), new(4598, 7623, 9729),
+ new(3520, 6845, 9199), new(3417, 6119, 9324), new(2601, 5412, 7385),
+ new(600, 1173, 1744), new(7672, 13286, 17469), new(4232, 7792, 10793),
+ new(2915, 5317, 7397), new(2318, 4356, 6152), new(2127, 4000, 5554),
+ new(1850, 3478, 5275), new(977, 1933, 2843), new(18280, 24387, 27989),
+ new(15852, 22671, 26185), new(13845, 20951, 24789), new(11055, 17966, 22129),
+ new(9138, 15422, 19801), new(7454, 13145, 17456), new(3370, 6393, 9013)
+ ],
+ [
+ new(5842, 9229, 10838), new(2313, 3491, 4276), new(2998, 6104, 7496),
+ new(2420, 7447, 9868), new(3034, 8495, 10923), new(4076, 8937, 10975),
+ new(1086, 2370, 3299), new(9714, 17254, 20444), new(8543, 13698, 17123),
+ new(4918, 9007, 11910), new(4129, 7532, 10553), new(2364, 5533, 8058),
+ new(1834, 3546, 5563), new(1473, 2908, 4133), new(15405, 21193, 25619),
+ new(15691, 21952, 26561), new(12962, 19194, 24165), new(10272, 17855, 22129),
+ new(8588, 15270, 20718), new(8682, 14669, 19500), new(4870, 9636, 13205)
+ ]
+ ],
+ [
+ [
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ],
+ [
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ]
+ ]
+ ],
+ [
+ [
+ [
+ new(14995, 21341, 24749), new(13158, 20289, 24601), new(8941, 15326, 19876),
+ new(6297, 11541, 15807), new(4817, 9029, 12776), new(3731, 7273, 10627),
+ new(1847, 3617, 5354), new(14472, 19659, 22343), new(16806, 24162, 27533),
+ new(12900, 20404, 24713), new(9411, 16112, 20797), new(7056, 12697, 17148),
+ new(5544, 10339, 14460), new(2954, 5704, 8319), new(12464, 18071, 21354),
+ new(15482, 22528, 26034), new(12070, 19269, 23624), new(8953, 15406, 20106),
+ new(7027, 12730, 17220), new(5887, 10913, 15140), new(3793, 7278, 10447)
+ ],
+ [
+ new(15571, 22232, 25749), new(14506, 21575, 25374), new(10189, 17089, 21569),
+ new(7316, 13301, 17915), new(5783, 10912, 15190), new(4760, 9155, 13088),
+ new(2993, 5966, 8774), new(23424, 28903, 30778), new(20775, 27666, 30290),
+ new(16474, 24410, 28299), new(12471, 20180, 24987), new(9410, 16487, 21439),
+ new(7536, 13614, 18529), new(5048, 9586, 13549), new(21090, 27290, 29756),
+ new(20796, 27402, 30026), new(17819, 25485, 28969), new(13860, 21909, 26462),
+ new(11002, 18494, 23529), new(8953, 15929, 20897), new(6448, 11918, 16454)
+ ]
+ ],
+ [
+ [
+ new(15999, 22208, 25449), new(13050, 19988, 24122), new(8594, 14864, 19378),
+ new(6033, 11079, 15238), new(4554, 8683, 12347), new(3672, 7139, 10337),
+ new(1900, 3771, 5576), new(15788, 21340, 23949), new(16825, 24235, 27758),
+ new(12873, 20402, 24810), new(9590, 16363, 21094), new(7352, 13209, 17733),
+ new(5960, 10989, 15184), new(3232, 6234, 9007), new(15761, 20716, 23224),
+ new(19318, 25989, 28759), new(15529, 23094, 26929), new(11662, 18989, 23641),
+ new(8955, 15568, 20366), new(7281, 13106, 17708), new(4248, 8059, 11440)
+ ],
+ [
+ new(14899, 21217, 24503), new(13519, 20283, 24047), new(9429, 15966, 20365),
+ new(6700, 12355, 16652), new(5088, 9704, 13716), new(4243, 8154, 11731),
+ new(2702, 5364, 7861), new(22745, 28388, 30454), new(20235, 27146, 29922),
+ new(15896, 23715, 27637), new(11840, 19350, 24131), new(9122, 15932, 20880),
+ new(7488, 13581, 18362), new(5114, 9568, 13370), new(20845, 26553, 28932),
+ new(20981, 27372, 29884), new(17781, 25335, 28785), new(13760, 21708, 26297),
+ new(10975, 18415, 23365), new(9045, 15789, 20686), new(6130, 11199, 15423)
+ ]
+ ],
+ [
+ [
+ new(13549, 19724, 23158), new(11844, 18382, 22246), new(7919, 13619, 17773),
+ new(5486, 10143, 13946), new(4166, 7983, 11324), new(3364, 6506, 9427),
+ new(1598, 3160, 4674), new(15281, 20979, 23781), new(14939, 22119, 25952),
+ new(11363, 18407, 22812), new(8609, 14857, 19370), new(6737, 12184, 16480),
+ new(5506, 10263, 14262), new(2990, 5786, 8380), new(20249, 25253, 27417),
+ new(21070, 27518, 30001), new(16854, 24469, 28074), new(12864, 20486, 25000),
+ new(9962, 16978, 21778), new(8074, 14338, 19048), new(4494, 8479, 11906)
+ ],
+ [
+ new(13960, 19617, 22829), new(11150, 17341, 21228), new(7150, 12964, 17190),
+ new(5331, 10002, 13867), new(4167, 7744, 11057), new(3480, 6629, 9646),
+ new(1883, 3784, 5686), new(18752, 25660, 28912), new(16968, 24586, 28030),
+ new(13520, 21055, 25313), new(10453, 17626, 22280), new(8386, 14505, 19116),
+ new(6742, 12595, 17008), new(4273, 8140, 11499), new(22120, 27827, 30233),
+ new(20563, 27358, 29895), new(17076, 24644, 28153), new(13362, 20942, 25309),
+ new(10794, 17965, 22695), new(9014, 15652, 20319), new(5708, 10512, 14497)
+ ]
+ ],
+ [
+ [
+ new(5705, 10930, 15725), new(7946, 12765, 16115), new(6801, 12123, 16226),
+ new(5462, 10135, 14200), new(4189, 8011, 11507), new(3191, 6229, 9408),
+ new(1057, 2137, 3212), new(10018, 17067, 21491), new(7380, 12582, 16453),
+ new(6068, 10845, 14339), new(5098, 9198, 12555), new(4312, 8010, 11119),
+ new(3700, 6966, 9781), new(1693, 3326, 4887), new(18757, 24930, 27774),
+ new(17648, 24596, 27817), new(14707, 22052, 26026), new(11720, 18852, 23292),
+ new(9357, 15952, 20525), new(7810, 13753, 18210), new(3879, 7333, 10328)
+ ],
+ [
+ new(8278, 13242, 15922), new(10547, 15867, 18919), new(9106, 15842, 20609),
+ new(6833, 13007, 17218), new(4811, 9712, 13923), new(3985, 7352, 11128),
+ new(1688, 3458, 5262), new(12951, 21861, 26510), new(9788, 16044, 20276),
+ new(6309, 11244, 14870), new(5183, 9349, 12566), new(4389, 8229, 11492),
+ new(3633, 6945, 10620), new(3600, 6847, 9907), new(21748, 28137, 30255),
+ new(19436, 26581, 29560), new(16359, 24201, 27953), new(13961, 21693, 25871),
+ new(11544, 18686, 23322), new(9372, 16462, 20952), new(6138, 11210, 15390)
+ ]
+ ],
+ [
+ [
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ],
+ [
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ]
+ ]
+ ],
+ [
+ [
+ [
+ new(16138, 22223, 25509), new(15347, 22430, 26332), new(9614, 16736, 21332),
+ new(6600, 12275, 16907), new(4811, 9424, 13547), new(3748, 7809, 11420),
+ new(2254, 4587, 6890), new(15196, 20284, 23177), new(18317, 25469, 28451),
+ new(13918, 21651, 25842), new(10052, 17150, 21995), new(7499, 13630, 18587),
+ new(6158, 11417, 16003), new(4014, 7785, 11252), new(15048, 21067, 24384),
+ new(18202, 25346, 28553), new(14302, 22019, 26356), new(10839, 18139, 23166),
+ new(8715, 15744, 20806), new(7536, 13576, 18544), new(5413, 10335, 14498)
+ ],
+ [
+ new(17394, 24501, 27895), new(15889, 23420, 27185), new(11561, 19133, 23870),
+ new(8285, 14812, 19844), new(6496, 12043, 16550), new(4771, 9574, 13677),
+ new(3603, 6830, 10144), new(21656, 27704, 30200), new(21324, 27915, 30511),
+ new(17327, 25336, 28997), new(13417, 21381, 26033), new(10132, 17425, 22338),
+ new(8580, 15016, 19633), new(5694, 11477, 16411), new(24116, 29780, 31450),
+ new(23853, 29695, 31591), new(20085, 27614, 30428), new(15326, 24335, 28575),
+ new(11814, 19472, 24810), new(10221, 18611, 24767), new(7689, 14558, 20321)
+ ]
+ ],
+ [
+ [
+ new(16214, 22380, 25770), new(14213, 21304, 25295), new(9213, 15823, 20455),
+ new(6395, 11758, 16139), new(4779, 9187, 13066), new(3821, 7501, 10953),
+ new(2293, 4567, 6795), new(15859, 21283, 23820), new(18404, 25602, 28726),
+ new(14325, 21980, 26206), new(10669, 17937, 22720), new(8297, 14642, 19447),
+ new(6746, 12389, 16893), new(4324, 8251, 11770), new(16532, 21631, 24475),
+ new(20667, 27150, 29668), new(16728, 24510, 28175), new(12861, 20645, 25332),
+ new(10076, 17361, 22417), new(8395, 14940, 19963), new(5731, 10683, 14912)
+ ],
+ [
+ new(14433, 21155, 24938), new(14658, 21716, 25545), new(9923, 16824, 21557),
+ new(6982, 13052, 17721), new(5419, 10503, 15050), new(4852, 9162, 13014),
+ new(3271, 6395, 9630), new(22210, 27833, 30109), new(20750, 27368, 29821),
+ new(16894, 24828, 28573), new(13247, 21276, 25757), new(10038, 17265, 22563),
+ new(8587, 14947, 20327), new(5645, 11371, 15252), new(22027, 27526, 29714),
+ new(23098, 29146, 31221), new(19886, 27341, 30272), new(15609, 23747, 28046),
+ new(11993, 20065, 24939), new(9637, 18267, 23671), new(7625, 13801, 19144)
+ ]
+ ],
+ [
+ [
+ new(14438, 20798, 24089), new(12621, 19203, 23097), new(8177, 14125, 18402),
+ new(5674, 10501, 14456), new(4236, 8239, 11733), new(3447, 6750, 9806),
+ new(1986, 3950, 5864), new(16208, 22099, 24930), new(16537, 24025, 27585),
+ new(12780, 20381, 24867), new(9767, 16612, 21416), new(7686, 13738, 18398),
+ new(6333, 11614, 15964), new(3941, 7571, 10836), new(22819, 27422, 29202),
+ new(22224, 28514, 30721), new(17660, 25433, 28913), new(13574, 21482, 26002),
+ new(10629, 17977, 22938), new(8612, 15298, 20265), new(5607, 10491, 14596)
+ ],
+ [
+ new(13569, 19800, 23206), new(13128, 19924, 23869), new(8329, 14841, 19403),
+ new(6130, 10976, 15057), new(4682, 8839, 12518), new(3656, 7409, 10588),
+ new(2577, 5099, 7412), new(22427, 28684, 30585), new(20913, 27750, 30139),
+ new(15840, 24109, 27834), new(12308, 20029, 24569), new(10216, 16785, 21458),
+ new(8309, 14203, 19113), new(6043, 11168, 15307), new(23166, 28901, 30998),
+ new(21899, 28405, 30751), new(18413, 26091, 29443), new(15233, 23114, 27352),
+ new(12683, 20472, 25288), new(10702, 18259, 23409), new(8125, 14464, 19226)
+ ]
+ ],
+ [
+ [
+ new(9040, 14786, 18360), new(9979, 15718, 19415), new(7913, 13918, 18311),
+ new(5859, 10889, 15184), new(4593, 8677, 12510), new(3820, 7396, 10791),
+ new(1730, 3471, 5192), new(11803, 18365, 22709), new(11419, 18058, 22225),
+ new(9418, 15774, 20243), new(7539, 13325, 17657), new(6233, 11317, 15384),
+ new(5137, 9656, 13545), new(2977, 5774, 8349), new(21207, 27246, 29640),
+ new(19547, 26578, 29497), new(16169, 23871, 27690), new(12820, 20458, 25018),
+ new(10224, 17332, 22214), new(8526, 15048, 19884), new(5037, 9410, 13118)
+ ],
+ [
+ new(12339, 17329, 20140), new(13505, 19895, 23225), new(9847, 16944, 21564),
+ new(7280, 13256, 18348), new(4712, 10009, 14454), new(4361, 7914, 12477),
+ new(2870, 5628, 7995), new(20061, 25504, 28526), new(15235, 22878, 26145),
+ new(12985, 19958, 24155), new(9782, 16641, 21403), new(9456, 16360, 20760),
+ new(6855, 12940, 18557), new(5661, 10564, 15002), new(25656, 30602, 31894),
+ new(22570, 29107, 31092), new(18917, 26423, 29541), new(15940, 23649, 27754),
+ new(12803, 20581, 25219), new(11082, 18695, 23376), new(7939, 14373, 19005)
+ ]
+ ],
+ [
+ [
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ],
+ [
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ]
+ ]
+ ],
+ [
+ [
+ [
+ new(18315, 24289, 27551), new(16854, 24068, 27835), new(10140, 17927, 23173),
+ new(6722, 12982, 18267), new(4661, 9826, 14706), new(3832, 8165, 12294),
+ new(2795, 6098, 9245), new(17145, 23326, 26672), new(20733, 27680, 30308),
+ new(16032, 24461, 28546), new(11653, 20093, 25081), new(9290, 16429, 22086),
+ new(7796, 14598, 19982), new(6502, 12378, 17441), new(21681, 27732, 30320),
+ new(22389, 29044, 31261), new(19027, 26731, 30087), new(14739, 23755, 28624),
+ new(11358, 20778, 25511), new(10995, 18073, 24190), new(9162, 14990, 20617)
+ ],
+ [
+ new(21425, 27952, 30388), new(18062, 25838, 29034), new(11956, 19881, 24808),
+ new(7718, 15000, 20980), new(5702, 11254, 16143), new(4898, 9088, 16864),
+ new(3679, 6776, 11907), new(23294, 30160, 31663), new(24397, 29896, 31836),
+ new(19245, 27128, 30593), new(13202, 19825, 26404), new(11578, 19297, 23957),
+ new(8073, 13297, 21370), new(5461, 10923, 19745), new(27367, 30521, 31934),
+ new(24904, 30671, 31940), new(23075, 28460, 31299), new(14400, 23658, 30417),
+ new(13885, 23882, 28325), new(14746, 22938, 27853), new(5461, 16384, 27307)
+ ]
+ ],
+ [
+ [
+ new(18274, 24813, 27890), new(15537, 23149, 27003), new(9449, 16740, 21827),
+ new(6700, 12498, 17261), new(4988, 9866, 14198), new(4236, 8147, 11902),
+ new(2867, 5860, 8654), new(17124, 23171, 26101), new(20396, 27477, 30148),
+ new(16573, 24629, 28492), new(12749, 20846, 25674), new(10233, 17878, 22818),
+ new(8525, 15332, 20363), new(6283, 11632, 16255), new(20466, 26511, 29286),
+ new(23059, 29174, 31191), new(19481, 27263, 30241), new(15458, 23631, 28137),
+ new(12416, 20608, 25693), new(10261, 18011, 23261), new(8016, 14655, 19666)
+ ],
+ [
+ new(17616, 24586, 28112), new(15809, 23299, 27155), new(10767, 18890, 23793),
+ new(7727, 14255, 18865), new(6129, 11926, 16882), new(4482, 9704, 14861),
+ new(3277, 7452, 11522), new(22956, 28551, 30730), new(22724, 28937, 30961),
+ new(18467, 26324, 29580), new(13234, 20713, 25649), new(11181, 17592, 22481),
+ new(8291, 18358, 24576), new(7568, 11881, 14984), new(24948, 29001, 31147),
+ new(25674, 30619, 32151), new(20841, 26793, 29603), new(14669, 24356, 28666),
+ new(11334, 23593, 28219), new(8922, 14762, 22873), new(8301, 13544, 20535)
+ ]
+ ],
+ [
+ [
+ new(17113, 23733, 27081), new(14139, 21406, 25452), new(8552, 15002, 19776),
+ new(5871, 11120, 15378), new(4455, 8616, 12253), new(3469, 6910, 10386),
+ new(2255, 4553, 6782), new(18224, 24376, 27053), new(19290, 26710, 29614),
+ new(14936, 22991, 27184), new(11238, 18951, 23762), new(8786, 15617, 20588),
+ new(7317, 13228, 18003), new(5101, 9512, 13493), new(22639, 28222, 30210),
+ new(23216, 29331, 31307), new(19075, 26762, 29895), new(15014, 23113, 27457),
+ new(11938, 19857, 24752), new(9942, 17280, 22282), new(7167, 13144, 17752)
+ ],
+ [
+ new(15820, 22738, 26488), new(13530, 20885, 25216), new(8395, 15530, 20452),
+ new(6574, 12321, 16380), new(5353, 10419, 14568), new(4613, 8446, 12381),
+ new(3440, 7158, 9903), new(24247, 29051, 31224), new(22118, 28058, 30369),
+ new(16498, 24768, 28389), new(12920, 21175, 26137), new(10730, 18619, 25352),
+ new(10187, 16279, 22791), new(9310, 14631, 22127), new(24970, 30558, 32057),
+ new(24801, 29942, 31698), new(22432, 28453, 30855), new(19054, 25680, 29580),
+ new(14392, 23036, 28109), new(12495, 20947, 26650), new(12442, 20326, 26214)
+ ]
+ ],
+ [
+ [
+ new(12162, 18785, 22648), new(12749, 19697, 23806), new(8580, 15297, 20346),
+ new(6169, 11749, 16543), new(4836, 9391, 13448), new(3821, 7711, 11613),
+ new(2228, 4601, 7070), new(16319, 24725, 28280), new(15698, 23277, 27168),
+ new(12726, 20368, 25047), new(9912, 17015, 21976), new(7888, 14220, 19179),
+ new(6777, 12284, 17018), new(4492, 8590, 12252), new(23249, 28904, 30947),
+ new(21050, 27908, 30512), new(17440, 25340, 28949), new(14059, 22018, 26541),
+ new(11288, 18903, 23898), new(9411, 16342, 21428), new(6278, 11588, 15944)
+ ],
+ [
+ new(13981, 20067, 23226), new(16922, 23580, 26783), new(11005, 19039, 24487),
+ new(7389, 14218, 19798), new(5598, 11505, 17206), new(6090, 11213, 15659),
+ new(3820, 7371, 10119), new(21082, 26925, 29675), new(21262, 28627, 31128),
+ new(18392, 26454, 30437), new(14870, 22910, 27096), new(12620, 19484, 24908),
+ new(9290, 16553, 22802), new(6668, 14288, 20004), new(27704, 31055, 31949),
+ new(24709, 29978, 31788), new(21668, 29264, 31657), new(18295, 26968, 30074),
+ new(16399, 24422, 29313), new(14347, 23026, 28104), new(12370, 19806, 24477)
+ ]
+ ],
+ [
+ [
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ],
+ [
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ]
+ ]
+ ]
+ ];
+
+ private static Av1Distribution[][][][] CoefficientsBase =>
+ [
+ [
+ [
+ [
+ new(4034, 8930, 12727), new(18082, 29741, 31877), new(12596, 26124, 30493),
+ new(9446, 21118, 27005), new(6308, 15141, 21279), new(2463, 6357, 9783),
+ new(20667, 30546, 31929), new(13043, 26123, 30134), new(8151, 18757, 24778),
+ new(5255, 12839, 18632), new(2820, 7206, 11161), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(15736, 27553, 30604), new(11210, 23794, 28787), new(5947, 13874, 19701),
+ new(4215, 9323, 13891), new(2833, 6462, 10059), new(19605, 30393, 31582),
+ new(13523, 26252, 30248), new(8446, 18622, 24512), new(3818, 10343, 15974),
+ new(1481, 4117, 6796), new(22649, 31302, 32190), new(14829, 27127, 30449),
+ new(8313, 17702, 23304), new(3022, 8301, 12786), new(1536, 4412, 7184),
+ new(22354, 29774, 31372), new(14723, 25472, 29214), new(6673, 13745, 18662),
+ new(2068, 5766, 9322), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ],
+ [
+ new(6302, 16444, 21761), new(23040, 31538, 32475), new(15196, 28452, 31496),
+ new(10020, 22946, 28514), new(6533, 16862, 23501), new(3538, 9816, 15076),
+ new(24444, 31875, 32525), new(15881, 28924, 31635), new(9922, 22873, 28466),
+ new(6527, 16966, 23691), new(4114, 11303, 17220), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(20201, 30770, 32209), new(14754, 28071, 31258), new(8378, 20186, 26517),
+ new(5916, 15299, 21978), new(4268, 11583, 17901), new(24361, 32025, 32581),
+ new(18673, 30105, 31943), new(10196, 22244, 27576), new(5495, 14349, 20417),
+ new(2676, 7415, 11498), new(24678, 31958, 32585), new(18629, 29906, 31831),
+ new(9364, 20724, 26315), new(4641, 12318, 18094), new(2758, 7387, 11579),
+ new(25433, 31842, 32469), new(18795, 29289, 31411), new(7644, 17584, 23592),
+ new(3408, 9014, 15047), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ]
+ ],
+ [
+ [
+ new(4536, 10072, 14001), new(25459, 31416, 32206), new(16605, 28048, 30818),
+ new(11008, 22857, 27719), new(6915, 16268, 22315), new(2625, 6812, 10537),
+ new(24257, 31788, 32499), new(16880, 29454, 31879), new(11958, 25054, 29778),
+ new(7916, 18718, 25084), new(3383, 8777, 13446), new(22720, 31603, 32393),
+ new(14960, 28125, 31335), new(9731, 22210, 27928), new(6304, 15832, 22277),
+ new(2910, 7818, 12166), new(20375, 30627, 32131), new(13904, 27284, 30887),
+ new(9368, 21558, 27144), new(5937, 14966, 21119), new(2667, 7225, 11319),
+ new(23970, 31470, 32378), new(17173, 29734, 32018), new(12795, 25441, 29965),
+ new(8981, 19680, 25893), new(4728, 11372, 16902), new(24287, 31797, 32439),
+ new(16703, 29145, 31696), new(10833, 23554, 28725), new(6468, 16566, 23057),
+ new(2415, 6562, 10278), new(26610, 32395, 32659), new(18590, 30498, 32117),
+ new(12420, 25756, 29950), new(7639, 18746, 24710), new(3001, 8086, 12347),
+ new(25076, 32064, 32580), new(17946, 30128, 32028), new(12024, 24985, 29378),
+ new(7517, 18390, 24304), new(3243, 8781, 13331), new(8192, 16384, 24576)
+ ],
+ [
+ new(6037, 16771, 21957), new(24774, 31704, 32426), new(16830, 28589, 31056),
+ new(10602, 22828, 27760), new(6733, 16829, 23071), new(3250, 8914, 13556),
+ new(25582, 32220, 32668), new(18659, 30342, 32223), new(12546, 26149, 30515),
+ new(8420, 20451, 26801), new(4636, 12420, 18344), new(27581, 32362, 32639),
+ new(18987, 30083, 31978), new(11327, 24248, 29084), new(7264, 17719, 24120),
+ new(3995, 10768, 16169), new(25893, 31831, 32487), new(16577, 28587, 31379),
+ new(10189, 22748, 28182), new(6832, 17094, 23556), new(3708, 10110, 15334),
+ new(25904, 32282, 32656), new(19721, 30792, 32276), new(12819, 26243, 30411),
+ new(8572, 20614, 26891), new(5364, 14059, 20467), new(26580, 32438, 32677),
+ new(20852, 31225, 32340), new(12435, 25700, 29967), new(8691, 20825, 26976),
+ new(4446, 12209, 17269), new(27350, 32429, 32696), new(21372, 30977, 32272),
+ new(12673, 25270, 29853), new(9208, 20925, 26640), new(5018, 13351, 18732),
+ new(27351, 32479, 32713), new(21398, 31209, 32387), new(12162, 25047, 29842),
+ new(7896, 18691, 25319), new(4670, 12882, 18881), new(8192, 16384, 24576)
+ ]
+ ],
+ [
+ [
+ new(5487, 10460, 13708), new(21597, 28303, 30674), new(11037, 21953, 26476),
+ new(8147, 17962, 22952), new(5242, 13061, 18532), new(1889, 5208, 8182),
+ new(26774, 32133, 32590), new(17844, 29564, 31767), new(11690, 24438, 29171),
+ new(7542, 18215, 24459), new(2993, 8050, 12319), new(28023, 32328, 32591),
+ new(18651, 30126, 31954), new(12164, 25146, 29589), new(7762, 18530, 24771),
+ new(3492, 9183, 13920), new(27591, 32008, 32491), new(17149, 28853, 31510),
+ new(11485, 24003, 28860), new(7697, 18086, 24210), new(3075, 7999, 12218),
+ new(28268, 32482, 32654), new(19631, 31051, 32404), new(13860, 27260, 31020),
+ new(9605, 21613, 27594), new(4876, 12162, 17908), new(27248, 32316, 32576),
+ new(18955, 30457, 32075), new(11824, 23997, 28795), new(7346, 18196, 24647),
+ new(3403, 9247, 14111), new(29711, 32655, 32735), new(21169, 31394, 32417),
+ new(13487, 27198, 30957), new(8828, 21683, 27614), new(4270, 11451, 17038),
+ new(28708, 32578, 32731), new(20120, 31241, 32482), new(13692, 27550, 31321),
+ new(9418, 22514, 28439), new(4999, 13283, 19462), new(8192, 16384, 24576)
+ ],
+ [
+ new(5673, 14302, 19711), new(26251, 30701, 31834), new(12782, 23783, 27803),
+ new(9127, 20657, 25808), new(6368, 16208, 21462), new(2465, 7177, 10822),
+ new(29961, 32563, 32719), new(18318, 29891, 31949), new(11361, 24514, 29357),
+ new(7900, 19603, 25607), new(4002, 10590, 15546), new(29637, 32310, 32595),
+ new(18296, 29913, 31809), new(10144, 21515, 26871), new(5358, 14322, 20394),
+ new(3067, 8362, 13346), new(28652, 32470, 32676), new(17538, 30771, 32209),
+ new(13924, 26882, 30494), new(10496, 22837, 27869), new(7236, 16396, 21621),
+ new(30743, 32687, 32746), new(23006, 31676, 32489), new(14494, 27828, 31120),
+ new(10174, 22801, 28352), new(6242, 15281, 21043), new(25817, 32243, 32720),
+ new(18618, 31367, 32325), new(13997, 28318, 31878), new(12255, 26534, 31383),
+ new(9561, 21588, 28450), new(28188, 32635, 32724), new(22060, 32365, 32728),
+ new(18102, 30690, 32528), new(14196, 28864, 31999), new(12262, 25792, 30865),
+ new(24176, 32109, 32628), new(18280, 29681, 31963), new(10205, 23703, 29664),
+ new(7889, 20025, 27676), new(6060, 16743, 23970), new(8192, 16384, 24576)
+ ]
+ ],
+ [
+ [
+ new(5141, 7096, 8260), new(27186, 29022, 29789), new(6668, 12568, 15682),
+ new(2172, 6181, 8638), new(1126, 3379, 4531), new(443, 1361, 2254),
+ new(26083, 31153, 32436), new(13486, 24603, 28483), new(6508, 14840, 19910),
+ new(3386, 8800, 13286), new(1530, 4322, 7054), new(29639, 32080, 32548),
+ new(15897, 27552, 30290), new(8588, 20047, 25383), new(4889, 13339, 19269),
+ new(2240, 6871, 10498), new(28165, 32197, 32517), new(20735, 30427, 31568),
+ new(14325, 24671, 27692), new(5119, 12554, 17805), new(1810, 5441, 8261),
+ new(31212, 32724, 32748), new(23352, 31766, 32545), new(14669, 27570, 31059),
+ new(8492, 20894, 27272), new(3644, 10194, 15204), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ],
+ [
+ new(2461, 7013, 9371), new(24749, 29600, 30986), new(9466, 19037, 22417),
+ new(3584, 9280, 14400), new(1505, 3929, 5433), new(677, 1500, 2736),
+ new(23987, 30702, 32117), new(13554, 24571, 29263), new(6211, 14556, 21155),
+ new(3135, 10972, 15625), new(2435, 7127, 11427), new(31300, 32532, 32550),
+ new(14757, 30365, 31954), new(4405, 11612, 18553), new(580, 4132, 7322),
+ new(1695, 10169, 14124), new(30008, 32282, 32591), new(19244, 30108, 31748),
+ new(11180, 24158, 29555), new(5650, 14972, 19209), new(2114, 5109, 8456),
+ new(31856, 32716, 32748), new(23012, 31664, 32572), new(13694, 26656, 30636),
+ new(8142, 19508, 26093), new(4253, 10955, 16724), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ]
+ ],
+ [
+ [
+ new(601, 983, 1311), new(18725, 23406, 28087), new(5461, 8192, 10923),
+ new(3781, 15124, 21425), new(2587, 7761, 12072), new(106, 458, 810),
+ new(22282, 29710, 31894), new(8508, 20926, 25984), new(3726, 12713, 18083),
+ new(1620, 7112, 10893), new(729, 2236, 3495), new(30163, 32474, 32684),
+ new(18304, 30464, 32000), new(11443, 26526, 29647), new(6007, 15292, 21299),
+ new(2234, 6703, 8937), new(30954, 32177, 32571), new(17363, 29562, 31076),
+ new(9686, 22464, 27410), new(8192, 16384, 21390), new(1755, 8046, 11264),
+ new(31168, 32734, 32748), new(22486, 31441, 32471), new(12833, 25627, 29738),
+ new(6980, 17379, 23122), new(3111, 8887, 13479), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ],
+ [
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ]
+ ]
+ ],
+ [
+ [
+ [
+ new(6041, 11854, 15927), new(20326, 30905, 32251), new(14164, 26831, 30725),
+ new(9760, 20647, 26585), new(6416, 14953, 21219), new(2966, 7151, 10891),
+ new(23567, 31374, 32254), new(14978, 27416, 30946), new(9434, 20225, 26254),
+ new(6658, 14558, 20535), new(3916, 8677, 12989), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(18088, 29545, 31587), new(13062, 25843, 30073), new(8940, 16827, 22251),
+ new(7654, 13220, 17973), new(5733, 10316, 14456), new(22879, 31388, 32114),
+ new(15215, 27993, 30955), new(9397, 19445, 24978), new(3442, 9813, 15344),
+ new(1368, 3936, 6532), new(25494, 32033, 32406), new(16772, 27963, 30718),
+ new(9419, 18165, 23260), new(2677, 7501, 11797), new(1516, 4344, 7170),
+ new(26556, 31454, 32101), new(17128, 27035, 30108), new(8324, 15344, 20249),
+ new(1903, 5696, 9469), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ],
+ [
+ new(8455, 19003, 24368), new(23563, 32021, 32604), new(16237, 29446, 31935),
+ new(10724, 23999, 29358), new(6725, 17528, 24416), new(3927, 10927, 16825),
+ new(26313, 32288, 32634), new(17430, 30095, 32095), new(11116, 24606, 29679),
+ new(7195, 18384, 25269), new(4726, 12852, 19315), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(22822, 31648, 32483), new(16724, 29633, 31929), new(10261, 23033, 28725),
+ new(7029, 17840, 24528), new(4867, 13886, 21502), new(25298, 31892, 32491),
+ new(17809, 29330, 31512), new(9668, 21329, 26579), new(4774, 12956, 18976),
+ new(2322, 7030, 11540), new(25472, 31920, 32543), new(17957, 29387, 31632),
+ new(9196, 20593, 26400), new(4680, 12705, 19202), new(2917, 8456, 13436),
+ new(26471, 32059, 32574), new(18458, 29783, 31909), new(8400, 19464, 25956),
+ new(3812, 10973, 17206), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ]
+ ],
+ [
+ [
+ new(6779, 13743, 17678), new(24806, 31797, 32457), new(17616, 29047, 31372),
+ new(11063, 23175, 28003), new(6521, 16110, 22324), new(2764, 7504, 11654),
+ new(25266, 32367, 32637), new(19054, 30553, 32175), new(12139, 25212, 29807),
+ new(7311, 18162, 24704), new(3397, 9164, 14074), new(25988, 32208, 32522),
+ new(16253, 28912, 31526), new(9151, 21387, 27372), new(5688, 14915, 21496),
+ new(2717, 7627, 12004), new(23144, 31855, 32443), new(16070, 28491, 31325),
+ new(8702, 20467, 26517), new(5243, 13956, 20367), new(2621, 7335, 11567),
+ new(26636, 32340, 32630), new(19990, 31050, 32341), new(13243, 26105, 30315),
+ new(8588, 19521, 25918), new(4717, 11585, 17304), new(25844, 32292, 32582),
+ new(19090, 30635, 32097), new(11963, 24546, 28939), new(6218, 16087, 22354),
+ new(2340, 6608, 10426), new(28046, 32576, 32694), new(21178, 31313, 32296),
+ new(13486, 26184, 29870), new(7149, 17871, 23723), new(2833, 7958, 12259),
+ new(27710, 32528, 32686), new(20674, 31076, 32268), new(12413, 24955, 29243),
+ new(6676, 16927, 23097), new(2966, 8333, 12919), new(8192, 16384, 24576)
+ ],
+ [
+ new(8639, 19339, 24429), new(24404, 31837, 32525), new(16997, 29425, 31784),
+ new(11253, 24234, 29149), new(6751, 17394, 24028), new(3490, 9830, 15191),
+ new(26283, 32471, 32714), new(19599, 31168, 32442), new(13146, 26954, 30893),
+ new(8214, 20588, 26890), new(4699, 13081, 19300), new(28212, 32458, 32669),
+ new(18594, 30316, 32100), new(11219, 24408, 29234), new(6865, 17656, 24149),
+ new(3678, 10362, 16006), new(25825, 32136, 32616), new(17313, 29853, 32021),
+ new(11197, 24471, 29472), new(6947, 17781, 24405), new(3768, 10660, 16261),
+ new(27352, 32500, 32706), new(20850, 31468, 32469), new(14021, 27707, 31133),
+ new(8964, 21748, 27838), new(5437, 14665, 21187), new(26304, 32492, 32698),
+ new(20409, 31380, 32385), new(13682, 27222, 30632), new(8974, 21236, 26685),
+ new(4234, 11665, 16934), new(26273, 32357, 32711), new(20672, 31242, 32441),
+ new(14172, 27254, 30902), new(9870, 21898, 27275), new(5164, 13506, 19270),
+ new(26725, 32459, 32728), new(20991, 31442, 32527), new(13071, 26434, 30811),
+ new(8184, 20090, 26742), new(4803, 13255, 19895), new(8192, 16384, 24576)
+ ]
+ ],
+ [
+ [
+ new(7555, 14942, 18501), new(24410, 31178, 32287), new(14394, 26738, 30253),
+ new(8413, 19554, 25195), new(4766, 12924, 18785), new(2029, 5806, 9207),
+ new(26776, 32364, 32663), new(18732, 29967, 31931), new(11005, 23786, 28852),
+ new(6466, 16909, 23510), new(3044, 8638, 13419), new(29208, 32582, 32704),
+ new(20068, 30857, 32208), new(12003, 25085, 29595), new(6947, 17750, 24189),
+ new(3245, 9103, 14007), new(27359, 32465, 32669), new(19421, 30614, 32174),
+ new(11915, 25010, 29579), new(6950, 17676, 24074), new(3007, 8473, 13096),
+ new(29002, 32676, 32735), new(22102, 31849, 32576), new(14408, 28009, 31405),
+ new(9027, 21679, 27931), new(4694, 12678, 18748), new(28216, 32528, 32682),
+ new(20849, 31264, 32318), new(12756, 25815, 29751), new(7565, 18801, 24923),
+ new(3509, 9533, 14477), new(30133, 32687, 32739), new(23063, 31910, 32515),
+ new(14588, 28051, 31132), new(9085, 21649, 27457), new(4261, 11654, 17264),
+ new(29518, 32691, 32748), new(22451, 31959, 32613), new(14864, 28722, 31700),
+ new(9695, 22964, 28716), new(4932, 13358, 19502), new(8192, 16384, 24576)
+ ],
+ [
+ new(6465, 16958, 21688), new(25199, 31514, 32360), new(14774, 27149, 30607),
+ new(9257, 21438, 26972), new(5723, 15183, 21882), new(3150, 8879, 13731),
+ new(26989, 32262, 32682), new(17396, 29937, 32085), new(11387, 24901, 29784),
+ new(7289, 18821, 25548), new(3734, 10577, 16086), new(29728, 32501, 32695),
+ new(17431, 29701, 31903), new(9921, 22826, 28300), new(5896, 15434, 22068),
+ new(3430, 9646, 14757), new(28614, 32511, 32705), new(19364, 30638, 32263),
+ new(13129, 26254, 30402), new(8754, 20484, 26440), new(4378, 11607, 17110),
+ new(30292, 32671, 32744), new(21780, 31603, 32501), new(14314, 27829, 31291),
+ new(9611, 22327, 28263), new(4890, 13087, 19065), new(25862, 32567, 32733),
+ new(20794, 32050, 32567), new(17243, 30625, 32254), new(13283, 27628, 31474),
+ new(9669, 22532, 28918), new(27435, 32697, 32748), new(24922, 32390, 32714),
+ new(21449, 31504, 32536), new(16392, 29729, 31832), new(11692, 24884, 29076),
+ new(24193, 32290, 32735), new(18909, 31104, 32563), new(12236, 26841, 31403),
+ new(8171, 21840, 29082), new(7224, 17280, 25275), new(8192, 16384, 24576)
+ ]
+ ],
+ [
+ [
+ new(3078, 6839, 9890), new(13837, 20450, 24479), new(5914, 14222, 19328),
+ new(3866, 10267, 14762), new(2612, 7208, 11042), new(1067, 2991, 4776),
+ new(25817, 31646, 32529), new(13708, 26338, 30385), new(7328, 18585, 24870),
+ new(4691, 13080, 19276), new(1825, 5253, 8352), new(29386, 32315, 32624),
+ new(17160, 29001, 31360), new(9602, 21862, 27396), new(5915, 15772, 22148),
+ new(2786, 7779, 12047), new(29246, 32450, 32663), new(18696, 29929, 31818),
+ new(10510, 23369, 28560), new(6229, 16499, 23125), new(2608, 7448, 11705),
+ new(30753, 32710, 32748), new(21638, 31487, 32503), new(12937, 26854, 30870),
+ new(8182, 20596, 26970), new(3637, 10269, 15497), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ],
+ [
+ new(5244, 12150, 16906), new(20486, 26858, 29701), new(7756, 18317, 23735),
+ new(3452, 9256, 13146), new(2020, 5206, 8229), new(1801, 4993, 7903),
+ new(27051, 31858, 32531), new(15988, 27531, 30619), new(9188, 21484, 26719),
+ new(6273, 17186, 23800), new(3108, 9355, 14764), new(31076, 32520, 32680),
+ new(18119, 30037, 31850), new(10244, 22969, 27472), new(4692, 14077, 19273),
+ new(3694, 11677, 17556), new(30060, 32581, 32720), new(21011, 30775, 32120),
+ new(11931, 24820, 29289), new(7119, 17662, 24356), new(3833, 10706, 16304),
+ new(31954, 32731, 32748), new(23913, 31724, 32489), new(15520, 28060, 31286),
+ new(11517, 23008, 28571), new(6193, 14508, 20629), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ]
+ ],
+ [
+ [
+ new(1035, 2807, 4156), new(13162, 18138, 20939), new(2696, 6633, 8755),
+ new(1373, 4161, 6853), new(1099, 2746, 4716), new(340, 1021, 1599),
+ new(22826, 30419, 32135), new(10395, 21762, 26942), new(4726, 12407, 17361),
+ new(2447, 7080, 10593), new(1227, 3717, 6011), new(28156, 31424, 31934),
+ new(16915, 27754, 30373), new(9148, 20990, 26431), new(5950, 15515, 21148),
+ new(2492, 7327, 11526), new(30602, 32477, 32670), new(20026, 29955, 31568),
+ new(11220, 23628, 28105), new(6652, 17019, 22973), new(3064, 8536, 13043),
+ new(31769, 32724, 32748), new(22230, 30887, 32373), new(12234, 25079, 29731),
+ new(7326, 18816, 25353), new(3933, 10907, 16616), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ],
+ [
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ]
+ ]
+ ],
+ [
+ [
+ [
+ new(8896, 16227, 20630), new(23629, 31782, 32527), new(15173, 27755, 31321),
+ new(10158, 21233, 27382), new(6420, 14857, 21558), new(3269, 8155, 12646),
+ new(24835, 32009, 32496), new(16509, 28421, 31579), new(10957, 21514, 27418),
+ new(7881, 15930, 22096), new(5388, 10960, 15918), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(20745, 30773, 32093), new(15200, 27221, 30861), new(13032, 20873, 25667),
+ new(12285, 18663, 23494), new(11563, 17481, 21489), new(26260, 31982, 32320),
+ new(15397, 28083, 31100), new(9742, 19217, 24824), new(3261, 9629, 15362),
+ new(1480, 4322, 7499), new(27599, 32256, 32460), new(16857, 27659, 30774),
+ new(9551, 18290, 23748), new(3052, 8933, 14103), new(2021, 5910, 9787),
+ new(29005, 32015, 32392), new(17677, 27694, 30863), new(9204, 17356, 23219),
+ new(2403, 7516, 12814), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ],
+ [
+ new(10808, 22056, 26896), new(25739, 32313, 32676), new(17288, 30203, 32221),
+ new(11359, 24878, 29896), new(6949, 17767, 24893), new(4287, 11796, 18071),
+ new(27880, 32521, 32705), new(19038, 31004, 32414), new(12564, 26345, 30768),
+ new(8269, 19947, 26779), new(5674, 14657, 21674), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(25742, 32319, 32671), new(19557, 31164, 32454), new(13381, 26381, 30755),
+ new(10101, 21466, 26722), new(9209, 19650, 26825), new(27107, 31917, 32432),
+ new(18056, 28893, 31203), new(10200, 21434, 26764), new(4660, 12913, 19502),
+ new(2368, 6930, 12504), new(26960, 32158, 32613), new(18628, 30005, 32031),
+ new(10233, 22442, 28232), new(5471, 14630, 21516), new(3235, 10767, 17109),
+ new(27696, 32440, 32692), new(20032, 31167, 32438), new(8700, 21341, 28442),
+ new(5662, 14831, 21795), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ]
+ ],
+ [
+ [
+ new(9704, 17294, 21132), new(26762, 32278, 32633), new(18382, 29620, 31819),
+ new(10891, 23475, 28723), new(6358, 16583, 23309), new(3248, 9118, 14141),
+ new(27204, 32573, 32699), new(19818, 30824, 32329), new(11772, 25120, 30041),
+ new(6995, 18033, 25039), new(3752, 10442, 16098), new(27222, 32256, 32559),
+ new(15356, 28399, 31475), new(8821, 20635, 27057), new(5511, 14404, 21239),
+ new(2935, 8222, 13051), new(24875, 32120, 32529), new(15233, 28265, 31445),
+ new(8605, 20570, 26932), new(5431, 14413, 21196), new(2994, 8341, 13223),
+ new(28201, 32604, 32700), new(21041, 31446, 32456), new(13221, 26213, 30475),
+ new(8255, 19385, 26037), new(4930, 12585, 18830), new(28768, 32448, 32627),
+ new(19705, 30561, 32021), new(11572, 23589, 28220), new(5532, 15034, 21446),
+ new(2460, 7150, 11456), new(29874, 32619, 32699), new(21621, 31071, 32201),
+ new(12511, 24747, 28992), new(6281, 16395, 22748), new(3246, 9278, 14497),
+ new(29715, 32625, 32712), new(20958, 31011, 32283), new(11233, 23671, 28806),
+ new(6012, 16128, 22868), new(3427, 9851, 15414), new(8192, 16384, 24576)
+ ],
+ [
+ new(11016, 22111, 26794), new(25946, 32357, 32677), new(17890, 30452, 32252),
+ new(11678, 25142, 29816), new(6720, 17534, 24584), new(4230, 11665, 17820),
+ new(28400, 32623, 32747), new(21164, 31668, 32575), new(13572, 27388, 31182),
+ new(8234, 20750, 27358), new(5065, 14055, 20897), new(28981, 32547, 32705),
+ new(18681, 30543, 32239), new(10919, 24075, 29286), new(6431, 17199, 24077),
+ new(3819, 10464, 16618), new(26870, 32467, 32693), new(19041, 30831, 32347),
+ new(11794, 25211, 30016), new(6888, 18019, 24970), new(4370, 12363, 18992),
+ new(29578, 32670, 32744), new(23159, 32007, 32613), new(15315, 28669, 31676),
+ new(9298, 22607, 28782), new(6144, 15913, 22968), new(28110, 32499, 32669),
+ new(21574, 30937, 32015), new(12759, 24818, 28727), new(6545, 16761, 23042),
+ new(3649, 10597, 16833), new(28163, 32552, 32728), new(22101, 31469, 32464),
+ new(13160, 25472, 30143), new(7303, 18684, 25468), new(5241, 13975, 20955),
+ new(28400, 32631, 32744), new(22104, 31793, 32603), new(13557, 26571, 30846),
+ new(7749, 19861, 26675), new(4873, 14030, 21234), new(8192, 16384, 24576)
+ ]
+ ],
+ [
+ [
+ new(9800, 17635, 21073), new(26153, 31885, 32527), new(15038, 27852, 31006),
+ new(8718, 20564, 26486), new(5128, 14076, 20514), new(2636, 7566, 11925),
+ new(27551, 32504, 32701), new(18310, 30054, 32100), new(10211, 23420, 29082),
+ new(6222, 16876, 23916), new(3462, 9954, 15498), new(29991, 32633, 32721),
+ new(19883, 30751, 32201), new(11141, 24184, 29285), new(6420, 16940, 23774),
+ new(3392, 9753, 15118), new(28465, 32616, 32712), new(19850, 30702, 32244),
+ new(10983, 24024, 29223), new(6294, 16770, 23582), new(3244, 9283, 14509),
+ new(30023, 32717, 32748), new(22940, 32032, 32626), new(14282, 27928, 31473),
+ new(8562, 21327, 27914), new(4846, 13393, 19919), new(29981, 32590, 32695),
+ new(20465, 30963, 32166), new(11479, 23579, 28195), new(5916, 15648, 22073),
+ new(3031, 8605, 13398), new(31146, 32691, 32739), new(23106, 31724, 32444),
+ new(13783, 26738, 30439), new(7852, 19468, 25807), new(3860, 11124, 16853),
+ new(31014, 32724, 32748), new(23629, 32109, 32628), new(14747, 28115, 31403),
+ new(8545, 21242, 27478), new(4574, 12781, 19067), new(8192, 16384, 24576)
+ ],
+ [
+ new(9185, 19694, 24688), new(26081, 31985, 32621), new(16015, 29000, 31787),
+ new(10542, 23690, 29206), new(6732, 17945, 24677), new(3916, 11039, 16722),
+ new(28224, 32566, 32744), new(19100, 31138, 32485), new(12528, 26620, 30879),
+ new(7741, 20277, 26885), new(4566, 12845, 18990), new(29933, 32593, 32718),
+ new(17670, 30333, 32155), new(10385, 23600, 28909), new(6243, 16236, 22407),
+ new(3976, 10389, 16017), new(28377, 32561, 32738), new(19366, 31175, 32482),
+ new(13327, 27175, 31094), new(8258, 20769, 27143), new(4703, 13198, 19527),
+ new(31086, 32706, 32748), new(22853, 31902, 32583), new(14759, 28186, 31419),
+ new(9284, 22382, 28348), new(5585, 15192, 21868), new(28291, 32652, 32746),
+ new(19849, 32107, 32571), new(14834, 26818, 29214), new(10306, 22594, 28672),
+ new(6615, 17384, 23384), new(28947, 32604, 32745), new(25625, 32289, 32646),
+ new(18758, 28672, 31403), new(10017, 23430, 28523), new(6862, 15269, 22131),
+ new(23933, 32509, 32739), new(19927, 31495, 32631), new(11903, 26023, 30621),
+ new(7026, 20094, 27252), new(5998, 18106, 24437), new(8192, 16384, 24576)
+ ]
+ ],
+ [
+ [
+ new(4456, 11274, 15533), new(21219, 29079, 31616), new(11173, 23774, 28567),
+ new(7282, 18293, 24263), new(4890, 13286, 19115), new(1890, 5508, 8659),
+ new(26651, 32136, 32647), new(14630, 28254, 31455), new(8716, 21287, 27395),
+ new(5615, 15331, 22008), new(2675, 7700, 12150), new(29954, 32526, 32690),
+ new(16126, 28982, 31633), new(9030, 21361, 27352), new(5411, 14793, 21271),
+ new(2943, 8422, 13163), new(29539, 32601, 32730), new(18125, 30385, 32201),
+ new(10422, 24090, 29468), new(6468, 17487, 24438), new(2970, 8653, 13531),
+ new(30912, 32715, 32748), new(20666, 31373, 32497), new(12509, 26640, 30917),
+ new(8058, 20629, 27290), new(4231, 12006, 18052), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ],
+ [
+ new(10202, 20633, 25484), new(27336, 31445, 32352), new(12420, 24384, 28552),
+ new(7648, 18115, 23856), new(5662, 14341, 19902), new(3611, 10328, 15390),
+ new(30945, 32616, 32736), new(18682, 30505, 32253), new(11513, 25336, 30203),
+ new(7449, 19452, 26148), new(4482, 13051, 18886), new(32022, 32690, 32747),
+ new(18578, 30501, 32146), new(11249, 23368, 28631), new(5645, 16958, 22158),
+ new(5009, 11444, 16637), new(31357, 32710, 32748), new(21552, 31494, 32504),
+ new(13891, 27677, 31340), new(9051, 22098, 28172), new(5190, 13377, 19486),
+ new(32364, 32740, 32748), new(24839, 31907, 32551), new(17160, 28779, 31696),
+ new(12452, 24137, 29602), new(6165, 15389, 22477), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ]
+ ],
+ [
+ [
+ new(2575, 7281, 11077), new(14002, 20866, 25402), new(6343, 15056, 19658),
+ new(4474, 11858, 17041), new(2865, 8299, 12534), new(1344, 3949, 6391),
+ new(24720, 31239, 32459), new(12585, 25356, 29968), new(7181, 18246, 24444),
+ new(5025, 13667, 19885), new(2521, 7304, 11605), new(29908, 32252, 32584),
+ new(17421, 29156, 31575), new(9889, 22188, 27782), new(5878, 15647, 22123),
+ new(2814, 8665, 13323), new(30183, 32568, 32713), new(18528, 30195, 32049),
+ new(10982, 24606, 29657), new(6957, 18165, 25231), new(3508, 10118, 15468),
+ new(31761, 32736, 32748), new(21041, 31328, 32546), new(12568, 26732, 31166),
+ new(8052, 20720, 27733), new(4336, 12192, 18396), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ],
+ [
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ]
+ ]
+ ],
+ [
+ [
+ [
+ new(7062, 16472, 22319), new(24538, 32261, 32674), new(13675, 28041, 31779),
+ new(8590, 20674, 27631), new(5685, 14675, 22013), new(3655, 9898, 15731),
+ new(26493, 32418, 32658), new(16376, 29342, 32090), new(10594, 22649, 28970),
+ new(8176, 17170, 24303), new(5605, 12694, 19139), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(23888, 31902, 32542), new(18612, 29687, 31987), new(16245, 24852, 29249),
+ new(15765, 22608, 27559), new(19895, 24699, 27510), new(28401, 32212, 32457),
+ new(15274, 27825, 30980), new(9364, 18128, 24332), new(2283, 8193, 15082),
+ new(1228, 3972, 7881), new(29455, 32469, 32620), new(17981, 28245, 31388),
+ new(10921, 20098, 26240), new(3743, 11829, 18657), new(2374, 9593, 15715),
+ new(31068, 32466, 32635), new(20321, 29572, 31971), new(10771, 20255, 27119),
+ new(2795, 10410, 17361), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ],
+ [
+ new(9320, 22102, 27840), new(27057, 32464, 32724), new(16331, 30268, 32309),
+ new(10319, 23935, 29720), new(6189, 16448, 24106), new(3589, 10884, 18808),
+ new(29026, 32624, 32748), new(19226, 31507, 32587), new(12692, 26921, 31203),
+ new(7049, 19532, 27635), new(7727, 15669, 23252), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(28056, 32625, 32748), new(22383, 32075, 32669), new(15417, 27098, 31749),
+ new(18127, 26493, 27190), new(5461, 16384, 21845), new(27982, 32091, 32584),
+ new(19045, 29868, 31972), new(10397, 22266, 27932), new(5990, 13697, 21500),
+ new(1792, 6912, 15104), new(28198, 32501, 32718), new(21534, 31521, 32569),
+ new(11109, 25217, 30017), new(5671, 15124, 26151), new(4681, 14043, 18725),
+ new(28688, 32580, 32741), new(22576, 32079, 32661), new(10627, 22141, 28340),
+ new(9362, 14043, 28087), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ]
+ ],
+ [
+ [
+ new(7754, 16948, 22142), new(25670, 32330, 32691), new(15663, 29225, 31994),
+ new(9878, 23288, 29158), new(6419, 17088, 24336), new(3859, 11003, 17039),
+ new(27562, 32595, 32725), new(17575, 30588, 32399), new(10819, 24838, 30309),
+ new(7124, 18686, 25916), new(4479, 12688, 19340), new(28385, 32476, 32673),
+ new(15306, 29005, 31938), new(8937, 21615, 28322), new(5982, 15603, 22786),
+ new(3620, 10267, 16136), new(27280, 32464, 32667), new(15607, 29160, 32004),
+ new(9091, 22135, 28740), new(6232, 16632, 24020), new(4047, 11377, 17672),
+ new(29220, 32630, 32718), new(19650, 31220, 32462), new(13050, 26312, 30827),
+ new(9228, 20870, 27468), new(6146, 15149, 21971), new(30169, 32481, 32623),
+ new(17212, 29311, 31554), new(9911, 21311, 26882), new(4487, 13314, 20372),
+ new(2570, 7772, 12889), new(30924, 32613, 32708), new(19490, 30206, 32107),
+ new(11232, 23998, 29276), new(6769, 17955, 25035), new(4398, 12623, 19214),
+ new(30609, 32627, 32722), new(19370, 30582, 32287), new(10457, 23619, 29409),
+ new(6443, 17637, 24834), new(4645, 13236, 20106), new(8192, 16384, 24576)
+ ],
+ [
+ new(8626, 20271, 26216), new(26707, 32406, 32711), new(16999, 30329, 32286),
+ new(11445, 25123, 30286), new(6411, 18828, 25601), new(6801, 12458, 20248),
+ new(29918, 32682, 32748), new(20649, 31739, 32618), new(12879, 27773, 31581),
+ new(7896, 21751, 28244), new(5260, 14870, 23698), new(29252, 32593, 32731),
+ new(17072, 30460, 32294), new(10653, 24143, 29365), new(6536, 17490, 23983),
+ new(4929, 13170, 20085), new(28137, 32518, 32715), new(18171, 30784, 32407),
+ new(11437, 25436, 30459), new(7252, 18534, 26176), new(4126, 13353, 20978),
+ new(31162, 32726, 32748), new(23017, 32222, 32701), new(15629, 29233, 32046),
+ new(9387, 22621, 29480), new(6922, 17616, 25010), new(28838, 32265, 32614),
+ new(19701, 30206, 31920), new(11214, 22410, 27933), new(5320, 14177, 23034),
+ new(5049, 12881, 17827), new(27484, 32471, 32734), new(21076, 31526, 32561),
+ new(12707, 26303, 31211), new(8169, 21722, 28219), new(6045, 19406, 27042),
+ new(27753, 32572, 32745), new(20832, 31878, 32653), new(13250, 27356, 31674),
+ new(7718, 21508, 29858), new(7209, 18350, 25559), new(8192, 16384, 24576)
+ ]
+ ],
+ [
+ [
+ new(7876, 16901, 21741), new(24001, 31898, 32625), new(14529, 27959, 31451),
+ new(8273, 20818, 27258), new(5278, 14673, 21510), new(2983, 8843, 14039),
+ new(28016, 32574, 32732), new(17471, 30306, 32301), new(10224, 24063, 29728),
+ new(6602, 17954, 25052), new(4002, 11585, 17759), new(30190, 32634, 32739),
+ new(17497, 30282, 32270), new(10229, 23729, 29538), new(6344, 17211, 24440),
+ new(3849, 11189, 17108), new(28570, 32583, 32726), new(17521, 30161, 32238),
+ new(10153, 23565, 29378), new(6455, 17341, 24443), new(3907, 11042, 17024),
+ new(30689, 32715, 32748), new(21546, 31840, 32610), new(13547, 27581, 31459),
+ new(8912, 21757, 28309), new(5548, 15080, 22046), new(30783, 32540, 32685),
+ new(17540, 29528, 31668), new(10160, 21468, 26783), new(4724, 13393, 20054),
+ new(2702, 8174, 13102), new(31648, 32686, 32742), new(20954, 31094, 32337),
+ new(12420, 25698, 30179), new(7304, 19320, 26248), new(4366, 12261, 18864),
+ new(31581, 32723, 32748), new(21373, 31586, 32525), new(12744, 26625, 30885),
+ new(7431, 20322, 26950), new(4692, 13323, 20111), new(8192, 16384, 24576)
+ ],
+ [
+ new(7833, 18369, 24095), new(26650, 32273, 32702), new(16371, 29961, 32191),
+ new(11055, 24082, 29629), new(6892, 18644, 25400), new(5006, 13057, 19240),
+ new(29834, 32666, 32748), new(19577, 31335, 32570), new(12253, 26509, 31122),
+ new(7991, 20772, 27711), new(5677, 15910, 23059), new(30109, 32532, 32720),
+ new(16747, 30166, 32252), new(10134, 23542, 29184), new(5791, 16176, 23556),
+ new(4362, 10414, 17284), new(29492, 32626, 32748), new(19894, 31402, 32525),
+ new(12942, 27071, 30869), new(8346, 21216, 27405), new(6572, 17087, 23859),
+ new(32035, 32735, 32748), new(22957, 31838, 32618), new(14724, 28572, 31772),
+ new(10364, 23999, 29553), new(7004, 18433, 25655), new(27528, 32277, 32681),
+ new(16959, 31171, 32096), new(10486, 23593, 27962), new(8192, 16384, 23211),
+ new(8937, 17873, 20852), new(27715, 32002, 32615), new(15073, 29491, 31676),
+ new(11264, 24576, 28672), new(2341, 18725, 23406), new(7282, 18204, 25486),
+ new(28547, 32213, 32657), new(20788, 29773, 32239), new(6780, 21469, 30508),
+ new(5958, 14895, 23831), new(16384, 21845, 27307), new(8192, 16384, 24576)
+ ]
+ ],
+ [
+ [
+ new(5992, 14304, 19765), new(22612, 31238, 32456), new(13456, 27162, 31087),
+ new(8001, 20062, 26504), new(5168, 14105, 20764), new(2632, 7771, 12385),
+ new(27034, 32344, 32709), new(15850, 29415, 31997), new(9494, 22776, 28841),
+ new(6151, 16830, 23969), new(3461, 10039, 15722), new(30134, 32569, 32731),
+ new(15638, 29422, 31945), new(9150, 21865, 28218), new(5647, 15719, 22676),
+ new(3402, 9772, 15477), new(28530, 32586, 32735), new(17139, 30298, 32292),
+ new(10200, 24039, 29685), new(6419, 17674, 24786), new(3544, 10225, 15824),
+ new(31333, 32726, 32748), new(20618, 31487, 32544), new(12901, 27217, 31232),
+ new(8624, 21734, 28171), new(5104, 14191, 20748), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ],
+ [
+ new(11206, 21090, 26561), new(28759, 32279, 32671), new(14171, 27952, 31569),
+ new(9743, 22907, 29141), new(6871, 17886, 24868), new(4960, 13152, 19315),
+ new(31077, 32661, 32748), new(19400, 31195, 32515), new(12752, 26858, 31040),
+ new(8370, 22098, 28591), new(5457, 15373, 22298), new(31697, 32706, 32748),
+ new(17860, 30657, 32333), new(12510, 24812, 29261), new(6180, 19124, 24722),
+ new(5041, 13548, 17959), new(31552, 32716, 32748), new(21908, 31769, 32623),
+ new(14470, 28201, 31565), new(9493, 22982, 28608), new(6858, 17240, 24137),
+ new(32543, 32752, 32756), new(24286, 32097, 32666), new(15958, 29217, 32024),
+ new(10207, 24234, 29958), new(6929, 18305, 25652), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ]
+ ],
+ [
+ [
+ new(4137, 10847, 15682), new(17824, 27001, 30058), new(10204, 22796, 28291),
+ new(6076, 15935, 22125), new(3852, 10937, 16816), new(2252, 6324, 10131),
+ new(25840, 32016, 32662), new(15109, 28268, 31531), new(9385, 22231, 28340),
+ new(6082, 16672, 23479), new(3318, 9427, 14681), new(30594, 32574, 32718),
+ new(16836, 29552, 31859), new(9556, 22542, 28356), new(6305, 16725, 23540),
+ new(3376, 9895, 15184), new(29383, 32617, 32745), new(18891, 30809, 32401),
+ new(11688, 25942, 30687), new(7468, 19469, 26651), new(3909, 11358, 17012),
+ new(31564, 32736, 32748), new(20906, 31611, 32600), new(13191, 27621, 31537),
+ new(8768, 22029, 28676), new(5079, 14109, 20906), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ],
+ [
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576),
+ new(8192, 16384, 24576), new(8192, 16384, 24576), new(8192, 16384, 24576)
+ ]
+ ]
+ ]
+ ];
+
+ private static Av1Distribution[][][][] BaseEndOfBlock =>
+ [
+ [
+ [
+ [new(17837, 29055), new(29600, 31446), new(30844, 31878), new(24926, 28948)],
+ [new(21365, 30026), new(30512, 32423), new(31658, 32621), new(29630, 31881)]
+ ],
+ [
+ [new(5717, 26477), new(30491, 31703), new(31550, 32158), new(29648, 31491)],
+ [new(12608, 27820), new(30680, 32225), new(30809, 32335), new(31299, 32423)]
+ ],
+ [
+ [new(1786, 12612), new(30663, 31625), new(32339, 32468), new(31148, 31833)],
+ [new(18857, 23865), new(31428, 32428), new(31744, 32373), new(31775, 32526)]
+ ],
+ [
+ [new(1787, 2532), new(30832, 31662), new(31824, 32682), new(32133, 32569)],
+ [new(13751, 22235), new(32089, 32409), new(27084, 27920), new(29291, 32594)]
+ ],
+ [
+ [new(1725, 3449), new(31102, 31935), new(32457, 32613), new(32412, 32649)],
+ [new(10923, 21845), new(10923, 21845), new(10923, 21845), new(10923, 21845)]
+ ]
+ ],
+ [
+ [
+ [new(17560, 29888), new(29671, 31549), new(31007, 32056), new(27286, 30006)],
+ [new(26594, 31212), new(31208, 32582), new(31835, 32637), new(30595, 32206)]
+ ],
+ [
+ [new(15239, 29932), new(31315, 32095), new(32130, 32434), new(30864, 31996)],
+ [new(26279, 30968), new(31142, 32495), new(31713, 32540), new(31929, 32594)]
+ ],
+ [
+ [new(2644, 25198), new(32038, 32451), new(32639, 32695), new(32166, 32518)],
+ [new(17187, 27668), new(31714, 32550), new(32283, 32678), new(31930, 32563)]
+ ],
+ [
+ [new(1044, 2257), new(30755, 31923), new(32208, 32693), new(32244, 32615)],
+ [new(21317, 26207), new(29133, 30868), new(29311, 31231), new(29657, 31087)]
+ ],
+ [
+ [new(478, 1834), new(31005, 31987), new(32317, 32724), new(30865, 32648)],
+ [new(10923, 21845), new(10923, 21845), new(10923, 21845), new(10923, 21845)]
+ ]
+ ],
+ [
+ [
+ [new(20092, 30774), new(30695, 32020), new(31131, 32103), new(28666, 30870)],
+ [new(27258, 31095), new(31804, 32623), new(31763, 32528), new(31438, 32506)]
+ ],
+ [
+ [new(18049, 30489), new(31706, 32286), new(32163, 32473), new(31550, 32184)],
+ [new(27116, 30842), new(31971, 32598), new(32088, 32576), new(32067, 32664)]
+ ],
+ [
+ [new(12854, 29093), new(32272, 32558), new(32667, 32729), new(32306, 32585)],
+ [new(25476, 30366), new(32169, 32687), new(32479, 32689), new(31673, 32634)]
+ ],
+ [
+ [new(2809, 19301), new(32205, 32622), new(32338, 32730), new(31786, 32616)],
+ [new(22737, 29105), new(30810, 32362), new(30014, 32627), new(30528, 32574)]
+ ],
+ [
+ [new(935, 3382), new(30789, 31909), new(32466, 32756), new(30860, 32513)],
+ [new(10923, 21845), new(10923, 21845), new(10923, 21845), new(10923, 21845)]
+ ]
+ ],
+ [
+ [
+ [new(22497, 31198), new(31715, 32495), new(31606, 32337), new(30388, 31990)],
+ [new(27877, 31584), new(32170, 32728), new(32155, 32688), new(32219, 32702)]
+ ],
+ [
+ [new(21457, 31043), new(31951, 32483), new(32153, 32562), new(31473, 32215)],
+ [new(27558, 31151), new(32020, 32640), new(32097, 32575), new(32242, 32719)]
+ ],
+ [
+ [new(19980, 30591), new(32219, 32597), new(32581, 32706), new(31803, 32287)],
+ [new(26473, 30507), new(32431, 32723), new(32196, 32611), new(31588, 32528)]
+ ],
+ [
+ [new(24647, 30463), new(32412, 32695), new(32468, 32720), new(31269, 32523)],
+ [new(28482, 31505), new(32152, 32701), new(31732, 32598), new(31767, 32712)]
+ ],
+ [
+ [new(12358, 24977), new(31331, 32385), new(32634, 32756), new(30411, 32548)],
+ [new(10923, 21845), new(10923, 21845), new(10923, 21845), new(10923, 21845)]
+ ]
+ ]
+ ];
+
+ private static Av1Distribution[][][] DcSign =>
+ [
+ [
+ [new(128 * 125), new(128 * 102), new(128 * 147)],
+ [new(128 * 119), new(128 * 101), new(128 * 135)]
+ ],
+ [
+ [new(128 * 125), new(128 * 102), new(128 * 147)],
+ [new(128 * 119), new(128 * 101), new(128 * 135)]
+ ],
+ [
+ [new(128 * 125), new(128 * 102), new(128 * 147)],
+ [new(128 * 119), new(128 * 101), new(128 * 135)]
+ ],
+ [
+ [new(128 * 125), new(128 * 102), new(128 * 147)],
+ [new(128 * 119), new(128 * 101), new(128 * 135)]
+ ],
+ ];
+
+ // SVT: av1_default_txb_skip_cdfs
+ private static Av1Distribution[][][] TransformBlockSkip =>
+ [
+ [
+ [
+ new(31849), new(5892), new(12112), new(21935), new(20289), new(27473), new(32487),
+ new(7654), new(19473), new(29984), new(9961), new(30242), new(32117)
+ ],
+ [
+ new(31548), new(1549), new(10130), new(16656), new(18591), new(26308), new(32537),
+ new(5403), new(18096), new(30003), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(29957), new(5391), new(18039), new(23566), new(22431), new(25822), new(32197),
+ new(3778), new(15336), new(28981), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(17920), new(1818), new(7282), new(25273), new(10923), new(31554), new(32624),
+ new(1366), new(15628), new(30462), new(146), new(5132), new(31657)
+ ],
+ [
+ new(6308), new(117), new(1638), new(2161), new(16384), new(10923), new(30247),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(30371), new(7570), new(13155), new(20751), new(20969), new(27067), new(32013),
+ new(5495), new(17942), new(28280), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(31782), new(1836), new(10689), new(17604), new(21622), new(27518), new(32399),
+ new(4419), new(16294), new(28345), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(31901), new(10311), new(18047), new(24806), new(23288), new(27914), new(32296),
+ new(4215), new(15756), new(28341), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(26726), new(1045), new(11703), new(20590), new(18554), new(25970), new(31938),
+ new(5583), new(21313), new(29390), new(641), new(22265), new(31452)
+ ],
+ [
+ new(26584), new(188), new(8847), new(24519), new(22938), new(30583), new(32608),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(29614), new(9068), new(12924), new(19538), new(17737), new(24619), new(30642),
+ new(4119), new(16026), new(25657), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(31957), new(3230), new(11153), new(18123), new(20143), new(26536), new(31986),
+ new(3050), new(14603), new(25155), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(32363), new(10692), new(19090), new(24357), new(24442), new(28312), new(32169),
+ new(3648), new(15690), new(26815), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(30669), new(3832), new(11663), new(18889), new(19782), new(23313), new(31330),
+ new(5124), new(18719), new(28468), new(3082), new(20982), new(29443)
+ ],
+ [
+ new(28573), new(3183), new(17802), new(25977), new(26677), new(27832), new(32387),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(26887), new(6729), new(10361), new(17442), new(15045), new(22478), new(29072),
+ new(2713), new(11861), new(20773), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(31903), new(2044), new(7528), new(14618), new(16182), new(24168), new(31037),
+ new(2786), new(11194), new(20155), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(32510), new(8430), new(17318), new(24154), new(23674), new(28789), new(32139),
+ new(3440), new(13117), new(22702), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(31671), new(2056), new(11746), new(16852), new(18635), new(24715), new(31484),
+ new(4656), new(16074), new(24704), new(1806), new(14645), new(25336)
+ ],
+ [
+ new(31539), new(8433), new(20576), new(27904), new(27852), new(30026), new(32441),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384)
+ ]
+ ]
+ ];
+
+ private static Av1Distribution[][][][] EndOfBlockExtra =>
+ [
+ [
+ [
+ [
+ new(16384), new(16384), new(16384), new(16961), new(17223), new(7621),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(19069), new(22525), new(13377),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(16384), new(16384), new(16384), new(20401), new(17025), new(12845),
+ new(12873), new(14094), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(20681), new(20701), new(15250),
+ new(15017), new(14928), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(16384), new(16384), new(16384), new(23905), new(17194), new(16170),
+ new(17695), new(13826), new(15810), new(12036), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(23959), new(20799), new(19021),
+ new(16203), new(17886), new(14144), new(12010), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(16384), new(16384), new(16384), new(27399), new(16327), new(18071),
+ new(19584), new(20721), new(18432), new(19560), new(10150), new(8805),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(24932), new(20833), new(12027),
+ new(16670), new(19914), new(15106), new(17662), new(13783), new(28756),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(16384), new(16384), new(16384), new(23406), new(21845), new(18432),
+ new(16384), new(17096), new(12561), new(17320), new(22395), new(21370),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ]
+ ],
+ [
+ [
+ [
+ new(16384), new(16384), new(16384), new(17471), new(20223), new(11357),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(20335), new(21667), new(14818),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(16384), new(16384), new(16384), new(20430), new(20662), new(15367),
+ new(16970), new(14657), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(22117), new(22028), new(18650),
+ new(16042), new(15885), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(16384), new(16384), new(16384), new(22409), new(21012), new(15650),
+ new(17395), new(15469), new(20205), new(19511), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(24220), new(22480), new(17737),
+ new(18916), new(19268), new(18412), new(18844), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(16384), new(16384), new(16384), new(25991), new(20314), new(17731),
+ new(19678), new(18649), new(17307), new(21798), new(17549), new(15630),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(26585), new(21469), new(20432),
+ new(17735), new(19280), new(15235), new(20297), new(22471), new(28997),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(16384), new(16384), new(16384), new(26605), new(11304), new(16726),
+ new(16560), new(20866), new(23524), new(19878), new(13469), new(23084),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ]
+ ],
+ [
+ [
+ [
+ new(16384), new(16384), new(16384), new(18983), new(20512), new(14885),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(20090), new(19444), new(17286),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(16384), new(16384), new(16384), new(19139), new(21487), new(18959),
+ new(20910), new(19089), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(20536), new(20664), new(20625),
+ new(19123), new(14862), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(16384), new(16384), new(16384), new(19833), new(21502), new(17485),
+ new(20267), new(18353), new(23329), new(21478), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(22041), new(23434), new(20001),
+ new(20554), new(20951), new(20145), new(15562), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(16384), new(16384), new(16384), new(23312), new(21607), new(16526),
+ new(18957), new(18034), new(18934), new(24247), new(16921), new(17080),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(26579), new(24910), new(18637),
+ new(19800), new(20388), new(9887), new(15642), new(30198), new(24721),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(16384), new(16384), new(16384), new(26998), new(16737), new(17838),
+ new(18922), new(19515), new(18636), new(17333), new(15776), new(22658),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ]
+ ],
+ [
+ [
+ [
+ new(16384), new(16384), new(16384), new(20177), new(20789), new(20262),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(21416), new(20855), new(23410),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(16384), new(16384), new(16384), new(20238), new(21057), new(19159),
+ new(22337), new(20159), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(20125), new(20559), new(21707),
+ new(22296), new(17333), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(16384), new(16384), new(16384), new(19941), new(20527), new(21470),
+ new(22487), new(19558), new(22354), new(20331), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(22752), new(25006), new(22075),
+ new(21576), new(17740), new(21690), new(19211), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(16384), new(16384), new(16384), new(21442), new(22358), new(18503),
+ new(20291), new(19945), new(21294), new(21178), new(19400), new(10556),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(24648), new(24949), new(20708),
+ new(23905), new(20501), new(9558), new(9423), new(30365), new(19253),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ],
+ [
+ [
+ new(16384), new(16384), new(16384), new(26064), new(22098), new(19613),
+ new(20525), new(17595), new(16618), new(20497), new(18989), new(15513),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ],
+ [
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384), new(16384), new(16384),
+ new(16384), new(16384), new(16384), new(16384)
+ ]
+ ]
+ ]
+ ];
+
+ public static Av1Distribution ChromaFromLumaSign => new(1418, 2123, 13340, 18405, 26972, 28343, 32294);
+
+ public static Av1Distribution[] ChromaFromLumaAlpha =>
+ [
+ new(7637, 20719, 31401, 32481, 32657, 32688, 32692, 32696, 32700, 32704, 32708, 32712, 32716, 32720, 32724),
+ new(14365, 23603, 28135, 31168, 32167, 32395, 32487, 32573, 32620, 32647, 32668, 32672, 32676, 32680, 32684),
+ new(11532, 22380, 28445, 31360, 32349, 32523, 32584, 32649, 32673, 32677, 32681, 32685, 32689, 32693, 32697),
+ new(26990, 31402, 32282, 32571, 32692, 32696, 32700, 32704, 32708, 32712, 32716, 32720, 32724, 32728, 32732),
+ new(17248, 26058, 28904, 30608, 31305, 31877, 32126, 32321, 32394, 32464, 32516, 32560, 32576, 32593, 32622),
+ new(14738, 21678, 25779, 27901, 29024, 30302, 30980, 31843, 32144, 32413, 32520, 32594, 32622, 32656, 32660)
+ ];
+
+ public static Av1Distribution[][][] IntraExtendedTransform =>
+ [
+ [
+ [
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0)
+ ],
+ [
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0)
+ ],
+ [
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0)
+ ],
+ [
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0),
+ new(0)
+ ],
+ ],
+ [
+ [
+ new(1535, 8035, 9461, 12751, 23467, 27825),
+ new(564, 3335, 9709, 10870, 18143, 28094),
+ new(672, 3247, 3676, 11982, 19415, 23127),
+ new(5279, 13885, 15487, 18044, 23527, 30252),
+ new(4423, 6074, 7985, 10416, 25693, 29298),
+ new(1486, 4241, 9460, 10662, 16456, 27694),
+ new(439, 2838, 3522, 6737, 18058, 23754),
+ new(1190, 4233, 4855, 11670, 20281, 24377),
+ new(1045, 4312, 8647, 10159, 18644, 29335),
+ new(202, 3734, 4747, 7298, 17127, 24016),
+ new(447, 4312, 6819, 8884, 16010, 23858),
+ new(277, 4369, 5255, 8905, 16465, 22271),
+ new(3409, 5436, 10599, 15599, 19687, 24040)
+ ],
+ [
+ new(1870, 13742, 14530, 16498, 23770, 27698),
+ new(326, 8796, 14632, 15079, 19272, 27486),
+ new(484, 7576, 7712, 14443, 19159, 22591),
+ new(1126, 15340, 15895, 17023, 20896, 30279),
+ new(655, 4854, 5249, 5913, 22099, 27138),
+ new(1299, 6458, 8885, 9290, 14851, 25497),
+ new(311, 5295, 5552, 6885, 16107, 22672),
+ new(883, 8059, 8270, 11258, 17289, 21549),
+ new(741, 7580, 9318, 10345, 16688, 29046),
+ new(110, 7406, 7915, 9195, 16041, 23329),
+ new(363, 7974, 9357, 10673, 15629, 24474),
+ new(153, 7647, 8112, 9936, 15307, 19996),
+ new(3511, 6332, 11165, 15335, 19323, 23594)
+ ],
+ [
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087)
+ ],
+ [
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ new(4681, 9362, 14043, 18725, 23406, 28087),
+ ],
+ ],
+ [
+ [
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214)
+ ],
+ [
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214)
+ ],
+ [
+ new(1127, 12814, 22772, 27483),
+ new(145, 6761, 11980, 26667),
+ new(362, 5887, 11678, 16725),
+ new(385, 15213, 18587, 30693),
+ new(25, 2914, 23134, 27903),
+ new(60, 4470, 11749, 23991),
+ new(37, 3332, 14511, 21448),
+ new(157, 6320, 13036, 17439),
+ new(119, 6719, 12906, 29396),
+ new(47, 5537, 12576, 21499),
+ new(269, 6076, 11258, 23115),
+ new(83, 5615, 12001, 17228),
+ new(1968, 5556, 12023, 18547)
+ ],
+ [
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214),
+ new(6554, 13107, 19661, 26214)
+ ]
+ ],
+ ];
+
+ public static Av1Distribution[][][] GetEndOfBlockFlag(int baseQIndex)
+ {
+ int qContext = GetQContext(baseQIndex);
+ return
+ [
+ EndOfBlockFlagMulti16[qContext],
+ EndOfBlockFlagMulti32[qContext],
+ EndOfBlockFlagMulti64[qContext],
+ EndOfBlockFlagMulti128[qContext],
+ EndOfBlockFlagMulti256[qContext],
+ EndOfBlockFlagMulti512[qContext],
+ EndOfBlockFlagMulti1024[qContext],
+ ];
+ }
+
+ public static Av1Distribution[][][] GetCoefficientsBaseRange(int baseQIndex)
+ => CoefficientsBaseRange[GetQContext(baseQIndex)];
+
+ public static Av1Distribution[][][] GetCoefficientsBase(int baseQIndex)
+ => CoefficientsBase[GetQContext(baseQIndex)];
+
+ public static Av1Distribution[][][] GetBaseEndOfBlock(int baseQIndex)
+ => BaseEndOfBlock[GetQContext(baseQIndex)];
+
+ public static Av1Distribution[][] GetDcSign(int baseQIndex)
+ => DcSign[GetQContext(baseQIndex)];
+
+ public static Av1Distribution[][] GetTransformBlockSkip(int baseQIndex)
+ => TransformBlockSkip[GetQContext(baseQIndex)];
+
+ public static Av1Distribution[][][] GetEndOfBlockExtra(int baseQIndex)
+ => EndOfBlockExtra[GetQContext(baseQIndex)];
+
+ private static int GetQContext(int q)
+ {
+ if (q <= 20)
+ {
+ return 0;
+ }
+
+ if (q <= 60)
+ {
+ return 1;
+ }
+
+ if (q <= 120)
+ {
+ return 2;
+ }
+
+ return 3;
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1Distribution.cs b/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1Distribution.cs
new file mode 100644
index 0000000000..5e00c837c4
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1Distribution.cs
@@ -0,0 +1,129 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Entropy;
+
+///
+/// Class representing the probability distribution used for symbol coding.
+///
+internal class Av1Distribution
+{
+ internal const int ProbabilityTop = 1 << ProbabilityBitCount;
+ internal const int ProbabilityMinimum = 4;
+ internal const int CdfShift = 15 - ProbabilityBitCount;
+ internal const int ProbabilityShift = 6;
+
+ private const int ProbabilityBitCount = 15;
+
+ private readonly uint[] probabilities;
+ private readonly int speed;
+ private int updateCount;
+
+ public Av1Distribution(uint p0)
+ : this([p0, 0], 1)
+ {
+ }
+
+ public Av1Distribution(uint p0, uint p1)
+ : this([p0, p1, 0], 1)
+ {
+ }
+
+ public Av1Distribution(uint p0, uint p1, uint p2)
+ : this([p0, p1, p2, 0], 2)
+ {
+ }
+
+ public Av1Distribution(uint p0, uint p1, uint p2, uint p3)
+ : this([p0, p1, p2, p3, 0], 2)
+ {
+ }
+
+ public Av1Distribution(uint p0, uint p1, uint p2, uint p3, uint p4)
+ : this([p0, p1, p2, p3, p4, 0], 2)
+ {
+ }
+
+ public Av1Distribution(uint p0, uint p1, uint p2, uint p3, uint p4, uint p5)
+ : this([p0, p1, p2, p3, p4, p5, 0], 2)
+ {
+ }
+
+ public Av1Distribution(uint p0, uint p1, uint p2, uint p3, uint p4, uint p5, uint p6)
+ : this([p0, p1, p2, p3, p4, p5, p6, 0], 2)
+ {
+ }
+
+ public Av1Distribution(uint p0, uint p1, uint p2, uint p3, uint p4, uint p5, uint p6, uint p7)
+ : this([p0, p1, p2, p3, p4, p5, p6, p7, 0], 2)
+ {
+ }
+
+ public Av1Distribution(uint p0, uint p1, uint p2, uint p3, uint p4, uint p5, uint p6, uint p7, uint p8)
+ : this([p0, p1, p2, p3, p4, p5, p6, p7, p8, 0], 2)
+ {
+ }
+
+ public Av1Distribution(uint p0, uint p1, uint p2, uint p3, uint p4, uint p5, uint p6, uint p7, uint p8, uint p9)
+ : this([p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, 0], 2)
+ {
+ }
+
+ public Av1Distribution(uint p0, uint p1, uint p2, uint p3, uint p4, uint p5, uint p6, uint p7, uint p8, uint p9, uint p10, uint p11)
+ : this([p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, 0], 2)
+ {
+ }
+
+ public Av1Distribution(uint p0, uint p1, uint p2, uint p3, uint p4, uint p5, uint p6, uint p7, uint p8, uint p9, uint p10, uint p11, uint p12)
+ : this([p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, 0], 2)
+ {
+ }
+
+ public Av1Distribution(uint p0, uint p1, uint p2, uint p3, uint p4, uint p5, uint p6, uint p7, uint p8, uint p9, uint p10, uint p11, uint p12, uint p13, uint p14)
+ : this([p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, 0], 2)
+ {
+ }
+
+ private Av1Distribution(uint[] props, int speed)
+ {
+ // this.probabilities = props;
+ this.probabilities = new uint[props.Length];
+ for (int i = 0; i < props.Length - 1; i++)
+ {
+ this.probabilities[i] = ProbabilityTop - props[i];
+ }
+
+ this.NumberOfSymbols = props.Length;
+ this.speed = speed;
+ }
+
+ public int NumberOfSymbols { get; }
+
+ public uint this[int index] => this.probabilities[index];
+
+ public void Update(int value)
+ {
+ int rate15 = this.updateCount > 15 ? 1 : 0;
+ int rate31 = this.updateCount > 31 ? 1 : 0;
+ int rate = 3 + rate15 + rate31 + this.speed; // + get_msb(nsymbs);
+ int tmp = ProbabilityTop;
+
+ // Single loop (faster)
+ for (int i = 0; i < this.NumberOfSymbols - 1; i++)
+ {
+ tmp = i == value ? 0 : tmp;
+ uint p = this.probabilities[i];
+ if (tmp < p)
+ {
+ this.probabilities[i] -= (ushort)((p - tmp) >> rate);
+ }
+ else
+ {
+ this.probabilities[i] += (ushort)((tmp - p) >> rate);
+ }
+ }
+
+ int rate32 = this.updateCount < 32 ? 1 : 0;
+ this.updateCount += rate32;
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1NzMap.cs b/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1NzMap.cs
new file mode 100644
index 0000000000..d6c951376d
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1NzMap.cs
@@ -0,0 +1,413 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Entropy;
+
+internal static class Av1NzMap
+{
+ // SIG_COEF_CONTEXTS_2D = 26
+ private const int NzMapContext0 = 26;
+ private const int NzMapContext5 = NzMapContext0 + 5;
+ private const int NzMapContext10 = NzMapContext0 + 10;
+
+ private static readonly int[] NzMapContextOffset1d = [
+ NzMapContext0, NzMapContext5, NzMapContext10, NzMapContext10, NzMapContext10, NzMapContext10, NzMapContext10,
+ NzMapContext10, NzMapContext10, NzMapContext10, NzMapContext10, NzMapContext10, NzMapContext10, NzMapContext10,
+ NzMapContext10, NzMapContext10, NzMapContext10, NzMapContext10, NzMapContext10, NzMapContext10, NzMapContext10,
+ NzMapContext10, NzMapContext10, NzMapContext10, NzMapContext10, NzMapContext10, NzMapContext10, NzMapContext10,
+ NzMapContext10, NzMapContext10, NzMapContext10, NzMapContext10,
+ ];
+
+ // The ctx offset table when TX is TX_CLASS_2D.
+ // TX col and row indices are clamped to 4
+ private static readonly int[] NzMapContextOffset4x4 = [
+ 0, 1, 6, 6,
+ 1, 6, 6, 21,
+ 6, 6, 21, 21,
+ 6, 21, 21, 21];
+
+ private static readonly int[] NzMapContextOffset8x8 = [
+ 0, 1, 6, 6, 21, 21, 21, 21,
+ 1, 6, 6, 21, 21, 21, 21, 21,
+ 6, 6, 21, 21, 21, 21, 21, 21,
+ 6, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ ];
+
+ private static readonly int[] NzMapContextOffset16x16 = [
+ 0, 1, 6, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 1, 6, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 6, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ ];
+
+ private static readonly int[] NzMapContextOffset32x32 = [
+ 0, 1, 6, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 1, 6, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 6, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ ];
+
+ private static readonly int[] NzMapContextOffset8x4 = [
+ 0, 16, 6, 6, 21, 21, 21, 21,
+ 16, 16, 6, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21,
+ ];
+
+ private static readonly int[] NzMapContextOffset16x8 = [
+ 0, 16, 6, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ ];
+
+ private static readonly int[] NzMapContextOffset16x32 = [
+ 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 6, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ ];
+
+ private static readonly int[] NzMapContextOffset32x16 = [
+ 0, 16, 6, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ ];
+
+ private static readonly int[] NzMapContextOffset32x64 = [
+ 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 6, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ ];
+
+ private static readonly int[] NzMapContextOffset64x32 = [
+ 0, 16, 6, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ ];
+
+ private static readonly int[] NzMapContextOffset4x16 = [
+ 0, 11, 11, 11,
+ 11, 11, 11, 11,
+ 6, 6, 21, 21,
+ 6, 21, 21, 21,
+ 21, 21, 21, 21,
+ 21, 21, 21, 21,
+ 21, 21, 21, 21,
+ 21, 21, 21, 21,
+ 21, 21, 21, 21,
+ 21, 21, 21, 21,
+ 21, 21, 21, 21,
+ 21, 21, 21, 21,
+ 21, 21, 21, 21,
+ 21, 21, 21, 21,
+ 21, 21, 21, 21,
+ 21, 21, 21, 21,
+ ];
+
+ private static readonly int[] NzMapContextOffset16x4 = [
+ 0, 16, 6, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ ];
+
+ private static readonly int[] NzMapContextOffset8x32 = [
+ 0, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 6, 6, 21, 21, 21, 21, 21, 21,
+ 6, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ ];
+
+ private static readonly int[] NzMapContextOffset32x8 = [
+ 0, 16, 6, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ ];
+
+ private static readonly int[][] NzMapContextOffset = [
+ NzMapContextOffset4x4, // TX_4x4
+ NzMapContextOffset8x8, // TX_8x8
+ NzMapContextOffset16x16, // TX_16x16
+ NzMapContextOffset32x32, // TX_32x32
+ NzMapContextOffset32x32, // TX_32x32
+ NzMapContextOffset4x16, // TX_4x8
+ NzMapContextOffset8x4, // TX_8x4
+ NzMapContextOffset8x32, // TX_8x16
+ NzMapContextOffset16x8, // TX_16x8
+ NzMapContextOffset16x32, // TX_16x32
+ NzMapContextOffset32x16, // TX_32x16
+ NzMapContextOffset32x64, // TX_32x64
+ NzMapContextOffset64x32, // TX_64x32
+ NzMapContextOffset4x16, // TX_4x16
+ NzMapContextOffset16x4, // TX_16x4
+ NzMapContextOffset8x32, // TX_8x32
+ NzMapContextOffset32x8, // TX_32x8
+ NzMapContextOffset16x32, // TX_16x64
+ NzMapContextOffset64x32, // TX_64x16
+ ];
+
+ ///
+ /// SVT: get_nz_mag
+ ///
+ public static int GetNzMagnitude(Av1LevelBuffer levels, Point position, Av1TransformClass transformClass)
+ {
+ int mag;
+ Span row0 = levels.GetRow(position.Y)[position.X..];
+ Span row1 = levels.GetRow(position.Y + 1)[position.X..];
+ Span row2 = levels.GetRow(position.Y + 2)[position.X..];
+
+ // Note: AOMMIN(level, 3) is useless for decoder since level < 3.
+ mag = ClipMax3(row0[1]); // { 0, 1 }
+ mag += ClipMax3(row1[0]); // { 1, 0 }
+
+ switch (transformClass)
+ {
+ case Av1TransformClass.Class2D:
+ mag += ClipMax3(row1[1]); // { 1, 1 }
+ mag += ClipMax3(row0[2]); // { 0, 2 }
+ mag += ClipMax3(row2[0]); // { 2, 0 }
+ break;
+
+ case Av1TransformClass.ClassVertical:
+ Span row3 = levels.GetRow(position.Y + 3)[position.X..];
+ Span row4 = levels.GetRow(position.Y + 4)[position.X..];
+ mag += ClipMax3(row2[0]); // { 2, 0 }
+ mag += ClipMax3(row3[0]); // { 3, 0 }
+ mag += ClipMax3(row4[0]); // { 4, 0 }
+ break;
+ case Av1TransformClass.ClassHorizontal:
+ mag += ClipMax3(row0[2]); // { 0, 2 }
+ mag += ClipMax3(row0[3]); // { 0, 3 }
+ mag += ClipMax3(row0[4]); // { 0, 4 }
+ break;
+ }
+
+ return mag;
+ }
+
+ public static int GetNzMapContextFromStats(int stats, Point position, Av1TransformSize transformSize, Av1TransformClass transformClass)
+ {
+ // tx_class == 0(TX_CLASS_2D)
+ if (position.Y == 0 && ((int)transformClass | position.X) == 0)
+ {
+ return 0;
+ }
+
+ int ctx = (stats + 1) >> 1;
+ ctx = Math.Min(ctx, 4);
+ switch (transformClass)
+ {
+ case Av1TransformClass.Class2D:
+ // This is the algorithm to generate eb_av1_nz_map_ctx_offset[][]
+ // const int width = tx_size_wide[tx_size];
+ // const int height = tx_size_high[tx_size];
+ // if (width < height) {
+ // if (row < 2) return 11 + ctx;
+ // } else if (width > height) {
+ // if (col < 2) return 16 + ctx;
+ // }
+ // if (row + col < 2) return ctx + 1;
+ // if (row + col < 4) return 5 + ctx + 1;
+ // return 21 + ctx;
+ return ctx + GetNzMapContext(transformSize, position);
+ case Av1TransformClass.ClassHorizontal:
+ return ctx + NzMapContextOffset1d[position.X];
+ case Av1TransformClass.ClassVertical:
+ return ctx + NzMapContextOffset1d[position.Y];
+ default:
+ break;
+ }
+
+ return 0;
+ }
+
+ public static int GetNzMapContext(Av1TransformSize transformSize, Point pos) => GetNzMapContext(transformSize, pos.X + (pos.Y * transformSize.GetWidth()));
+
+ public static int GetNzMapContext(Av1TransformSize transformSize, int pos) => NzMapContextOffset[(int)transformSize][pos];
+
+ private static int ClipMax3(int value) => Math.Min(value, 3);
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolContextHelper.cs b/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolContextHelper.cs
new file mode 100644
index 0000000000..563d914a15
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolContextHelper.cs
@@ -0,0 +1,440 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Entropy;
+
+internal static class Av1SymbolContextHelper
+{
+ public static readonly int[][] ExtendedTransformIndices = [
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // DCT only
+ [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Inter set 3
+ [1, 3, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Intra set 2
+ [1, 5, 6, 4, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0], // Intra set 1
+ [3, 4, 5, 8, 6, 7, 9, 10, 11, 0, 1, 2, 0, 0, 0, 0], // Inter set 2
+ [7, 8, 9, 12, 10, 11, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6], // All 16, inter set 1
+ ];
+
+ // Maps tx set types to the distribution indices. INTRA values only
+ private static readonly int[] ExtendedTransformSetToIndex = [0, -1, 2, 1, -1, -1];
+
+ ///
+ /// Section 5.11.48: Transform type syntax
+ ///
+ public static readonly Av1TransformType[][] ExtendedTransformInverse = [
+ [Av1TransformType.DctDct], // DCT only
+ [], // Inter set 3
+ [Av1TransformType.Identity, Av1TransformType.DctDct, Av1TransformType.AdstAdst, Av1TransformType.AdstDct, Av1TransformType.DctAdst], // Intra set 2
+ [Av1TransformType.Identity, Av1TransformType.DctDct, Av1TransformType.VerticalDct, Av1TransformType.HorizontalDct, Av1TransformType.AdstAdst, Av1TransformType.AdstDct, Av1TransformType.DctAdst], // Intra set 1
+ [], // Inter set 2
+ [], // All 16, inter set 1
+ ];
+
+ public static readonly int[] EndOfBlockOffsetBits = [0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+ public static readonly int[] EndOfBlockGroupStart = [0, 1, 2, 3, 5, 9, 17, 33, 65, 129, 257, 513];
+ private static readonly byte[] EndOfBlockToPositionSmall = [
+ 0, 1, 2, // 0-2
+ 3, 3, // 3-4
+ 4, 4, 4, 4, // 5-8
+ 5, 5, 5, 5, 5, 5, 5, 5, // 9-16
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 // 17-32
+ ];
+
+ private static readonly byte[] EndOfBlockToPositionLarge = [
+ 6, // place holder
+ 7, // 33-64
+ 8,
+ 8, // 65-128
+ 9,
+ 9,
+ 9,
+ 9, // 129-256
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10, // 257-512
+ 11 // 513-
+ ];
+
+ internal static Av1TransformSize GetTransformSizeContext(Av1TransformSize originalSize)
+ => (Av1TransformSize)(((int)originalSize.GetSquareSize() + (int)originalSize.GetSquareUpSize() + 1) >> 1);
+
+ internal static int RecordEndOfBlockPosition(int endOfBlockPoint, int endOfBlockExtra)
+ {
+ int endOfBlock = EndOfBlockGroupStart[endOfBlockPoint];
+ if (endOfBlock > 2)
+ {
+ endOfBlock += endOfBlockExtra;
+ }
+
+ return endOfBlock;
+ }
+
+ ///
+ /// SVT: get_lower_levels_ctx_eob
+ ///
+ internal static int GetLowerLevelContextEndOfBlock(Av1LevelBuffer levels, Point position)
+ {
+ if (position.X == 0 && position.Y == 0)
+ {
+ return 0;
+ }
+
+ int total = levels.Size.Height * levels.Size.Width;
+ int index = position.X + (position.Y * levels.Size.Width);
+ if (index <= total >> 3)
+ {
+ return 1;
+ }
+
+ if (index <= total >> 2)
+ {
+ return 2;
+ }
+
+ return 3;
+ }
+
+ ///
+ /// SVT: get_lower_levels_ctx_2d
+ ///
+ internal static int GetLowerLevelsContext2d(Av1LevelBuffer levelBuffer, Point position, Av1TransformSize transformSize)
+ {
+ DebugGuard.MustBeGreaterThan(position.X + position.Y, 0, nameof(position));
+ int mag;
+ Span row0 = levelBuffer.GetRow(position.Y)[position.X..];
+ Span row1 = levelBuffer.GetRow(position.Y + 1)[position.X..];
+ Span row2 = levelBuffer.GetRow(position.Y + 2)[position.X..];
+ mag = Math.Min((int)row0[1], 3); // { 0, 1 }
+ mag += Math.Min((int)row1[0], 3); // { 1, 0 }
+ mag += Math.Min((int)row1[1], 3); // { 1, 1 }
+ mag += Math.Min((int)row0[2], 3); // { 0, 2 }
+ mag += Math.Min((int)row2[0], 3); // { 2, 0 }
+
+ int ctx = Math.Min((mag + 1) >> 1, 4);
+ return ctx + Av1NzMap.GetNzMapContext(transformSize, position);
+ }
+
+ ///
+ /// Section 8.3.2 in the spec, under coeff_br. Optimized for end of block based
+ /// on the fact that {0, 1}, {1, 0}, {1, 1}, {0, 2} and {2, 0} will all be 0 in
+ /// the end of block case.
+ ///
+ internal static int GetBaseRangeContextEndOfBlock(Point pos, Av1TransformClass transformClass)
+ {
+ if (pos.X == 0 && pos.Y == 0)
+ {
+ return 0;
+ }
+
+ if ((transformClass == Av1TransformClass.Class2D && pos.Y < 2 && pos.X < 2) ||
+ (transformClass == Av1TransformClass.ClassHorizontal && pos.X == 0) ||
+ (transformClass == Av1TransformClass.ClassVertical && pos.Y == 0))
+ {
+ return 7;
+ }
+
+ return 14;
+ }
+
+ ///
+ /// SVT: get_br_ctx
+ ///
+ /// Spec section 8.2.3, under 'coeff_br'.
+ internal static int GetBaseRangeContext(Av1LevelBuffer levels, Point position, Av1TransformClass transformClass)
+ {
+ Span row0 = levels.GetRow(position.Y);
+ Span row1 = levels.GetRow(position.Y + 1);
+ int mag = row0[position.X + 1];
+ mag += row1[position.X];
+ switch (transformClass)
+ {
+ case Av1TransformClass.Class2D:
+ mag += row1[position.X + 1];
+ mag = Math.Min((mag + 1) >> 1, 6);
+ if ((position.X + position.Y) == 0)
+ {
+ return mag;
+ }
+
+ if (position.Y < 2 && position.X < 2)
+ {
+ return mag + 7;
+ }
+
+ break;
+ case Av1TransformClass.ClassHorizontal:
+ mag += row0[position.X + 2];
+ mag = Math.Min((mag + 1) >> 1, 6);
+ if ((position.X + position.Y) == 0)
+ {
+ return mag;
+ }
+
+ if (position.X == 0)
+ {
+ return mag + 7;
+ }
+
+ break;
+ case Av1TransformClass.ClassVertical:
+ mag += levels.GetRow(position.Y + 2)[position.X];
+ mag = Math.Min((mag + 1) >> 1, 6);
+ if ((position.X + position.Y) == 0)
+ {
+ return mag;
+ }
+
+ if (position.Y == 0)
+ {
+ return mag + 7;
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ return mag + 14;
+ }
+
+ ///
+ /// SVT: get_br_ctx_2d
+ ///
+ internal static int GetBaseRangeContext2d(Av1LevelBuffer levels, Point position)
+ {
+ DebugGuard.MustBeGreaterThan(position.X + position.Y, 0, nameof(position));
+ Span row0 = levels.GetRow(position.Y);
+ Span row1 = levels.GetRow(position.Y + 1);
+ int mag =
+ Math.Min((int)row0[position.X + 1], Av1Constants.MaxBaseRange) +
+ Math.Min((int)row1[position.X], Av1Constants.MaxBaseRange) +
+ Math.Min((int)row1[position.X + 1], Av1Constants.MaxBaseRange);
+ mag = Math.Min((mag + 1) >> 1, 6);
+ if ((position.Y | position.X) < 2)
+ {
+ return mag + 7;
+ }
+
+ return mag + 14;
+ }
+
+ internal static int GetLowerLevelsContext(Av1LevelBuffer levels, Point position, Av1TransformSize transformSize, Av1TransformClass transformClass)
+ {
+ int stats = Av1NzMap.GetNzMagnitude(levels, position, transformClass);
+ return Av1NzMap.GetNzMapContextFromStats(stats, position, transformSize, transformClass);
+ }
+
+ ///
+ /// SVT: get_ext_tx_set_type
+ ///
+ internal static Av1TransformSetType GetExtendedTransformSetType(Av1TransformSize transformSize, bool useReducedSet)
+ {
+ Av1TransformSize squareUpSize = transformSize.GetSquareUpSize();
+
+ if (squareUpSize >= Av1TransformSize.Size32x32)
+ {
+ return Av1TransformSetType.DctOnly;
+ }
+
+ if (useReducedSet)
+ {
+ return Av1TransformSetType.IntraSet2;
+ }
+
+ Av1TransformSize squareSize = transformSize.GetSquareSize();
+ return squareSize == Av1TransformSize.Size16x16 ? Av1TransformSetType.IntraSet2 : Av1TransformSetType.IntraSet1;
+ }
+
+ internal static Av1TransformType ConvertIntraModeToTransformType(Av1BlockModeInfo modeInfo, Av1PlaneType planeType)
+ {
+ Av1PredictionMode mode = (planeType == Av1PlaneType.Y) ? modeInfo.YMode : modeInfo.UvMode;
+ if (mode == Av1PredictionMode.UvChromaFromLuma)
+ {
+ mode = Av1PredictionMode.DC;
+ }
+
+ return mode.ToTransformType();
+ }
+
+ ///
+ /// SVT: get_nz_map_ctx
+ ///
+ internal static sbyte GetNzMapContext(
+ Av1LevelBuffer levels,
+ Point position,
+ bool isEndOfBlock,
+ Av1TransformSize transformSize,
+ Av1TransformClass transformClass)
+ {
+ if (isEndOfBlock)
+ {
+ return (sbyte)GetLowerLevelContextEndOfBlock(levels, position);
+ }
+
+ int stats = Av1NzMap.GetNzMagnitude(levels, position, transformClass);
+ return (sbyte)Av1NzMap.GetNzMapContextFromStats(stats, position, transformSize, transformClass);
+ }
+
+ ///
+ /// SVT: svt_av1_get_nz_map_contexts_c
+ ///
+ internal static void GetNzMapContexts(
+ Av1LevelBuffer levels,
+ ReadOnlySpan scan,
+ ushort eob,
+ Av1TransformSize transformSize,
+ Av1TransformClass transformClass,
+ Span coefficientContexts)
+ {
+ for (int i = 0; i < eob; ++i)
+ {
+ int pos = scan[i];
+ Point position = levels.GetPosition(pos);
+ coefficientContexts[pos] = GetNzMapContext(levels, position, i == eob - 1, transformSize, transformClass);
+ }
+ }
+
+ ///
+ /// SVT: get_ext_tx_types
+ ///
+ internal static int GetExtendedTransformTypeCount(Av1TransformSetType setType) => ExtendedTransformInverse[(int)setType].Length;
+
+ ///
+ /// SVT: get_ext_tx_set
+ ///
+ internal static int GetExtendedTransformSet(Av1TransformSetType setType) => ExtendedTransformSetToIndex[(int)setType];
+
+ ///
+ /// SVT: set_dc_sign
+ ///
+ internal static void SetDcSign(ref int culLevel, int dcValue)
+ {
+ if (dcValue < 0)
+ {
+ culLevel |= 1 << Av1Constants.CoefficientContextBitCount;
+ }
+ else if (dcValue > 0)
+ {
+ culLevel += 2 << Av1Constants.CoefficientContextBitCount;
+ }
+ }
+
+ ///
+ /// SVT: get_eob_pos_token
+ ///
+ internal static short GetEndOfBlockPosition(ushort endOfBlock, out int extra)
+ {
+ short t;
+ if (endOfBlock < 33)
+ {
+ t = EndOfBlockToPositionSmall[endOfBlock];
+ }
+ else
+ {
+ int e = Math.Min((endOfBlock - 1) >> 5, 16);
+ t = EndOfBlockToPositionLarge[e];
+ }
+
+ extra = endOfBlock - EndOfBlockGroupStart[t];
+ return t;
+ }
+
+ public static int GetSegmentId(Av1PartitionInfo partitionInfo, ObuFrameHeader frameHeader, int[][] segmentIds, int rowIndex, int columnIndex)
+ {
+ int modeInfoOffset = (rowIndex * frameHeader.ModeInfoColumnCount) + columnIndex;
+ int bw4 = partitionInfo.ModeInfo.BlockSize.Get4x4WideCount();
+ int bh4 = partitionInfo.ModeInfo.BlockSize.Get4x4HighCount();
+ int xMin = Math.Min(frameHeader.ModeInfoColumnCount - columnIndex, bw4);
+ int yMin = Math.Min(frameHeader.ModeInfoRowCount - rowIndex, bh4);
+ int segmentId = Av1Constants.MaxSegmentCount - 1;
+ for (int y = 0; y < yMin; y++)
+ {
+ for (int x = 0; x < xMin; x++)
+ {
+ segmentId = Math.Min(segmentId, segmentIds[y][x]);
+ }
+ }
+
+ return segmentId;
+ }
+
+ ///
+ /// SVT: svt_aom_get_segment_id
+ ///
+ public static int GetSegmentId(Av1EncoderCommon cm, ReadOnlySpan segment_ids, Av1BlockSize bsize, Point modeInfoPosition)
+ {
+ int mi_offset = (modeInfoPosition.Y * cm.ModeInfoColumnCount) + modeInfoPosition.X;
+ int bw = bsize.GetWidth();
+ int bh = bsize.GetHeight();
+ int xmis = Math.Min(cm.ModeInfoColumnCount - modeInfoPosition.X, bw);
+ int ymis = Math.Min(cm.ModeInfoRowCount - modeInfoPosition.Y, bh);
+ int segment_id = Av1Constants.MaxSegmentCount;
+
+ for (int y = 0; y < ymis; ++y)
+ {
+ int offset = mi_offset + (y * cm.ModeInfoColumnCount);
+ for (int x = 0; x < xmis; ++x)
+ {
+ segment_id = Math.Min(segment_id, segment_ids[offset + x]);
+ }
+ }
+
+ Guard.IsTrue(segment_id is >= 0 and < Av1Constants.MaxSegmentCount, nameof(segment_id), "Segment ID needs to be in proper range.");
+ return segment_id;
+ }
+
+ public static int NegativeDeinterleave(int diff, int reference, int max)
+ {
+ if (reference == 0)
+ {
+ return diff;
+ }
+
+ if (reference >= max - 1)
+ {
+ return max - diff - 1;
+ }
+
+ if (2 * reference < max)
+ {
+ if (diff <= 2 * reference)
+ {
+ if ((diff & 1) > 0)
+ {
+ return reference + ((diff + 1) >> 1);
+ }
+ else
+ {
+ return reference - (diff >> 1);
+ }
+ }
+
+ return diff;
+ }
+ else
+ {
+ if (diff <= 2 * (max - reference - 1))
+ {
+ if ((diff & 1) > 0)
+ {
+ return reference + ((diff + 1) >> 1);
+ }
+ else
+ {
+ return reference - (diff >> 1);
+ }
+ }
+
+ return max - (diff + 1);
+ }
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolDecoder.cs b/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolDecoder.cs
new file mode 100644
index 0000000000..caf760b2e3
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolDecoder.cs
@@ -0,0 +1,690 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Entropy;
+
+internal ref struct Av1SymbolDecoder
+{
+ private static readonly int[] IntraModeContext = [0, 1, 2, 3, 4, 4, 4, 4, 3, 0, 1, 2, 0];
+ private static readonly int[] AlphaVContexts = [-1, 0, 3, -1, 1, 4, -1, 2, 5];
+
+ private readonly Av1Distribution tileIntraBlockCopy = Av1DefaultDistributions.IntraBlockCopy;
+ private readonly Av1Distribution[] tilePartitionTypes = Av1DefaultDistributions.PartitionTypes;
+ private readonly Av1Distribution[][] keyFrameYMode = Av1DefaultDistributions.KeyFrameYMode;
+ private readonly Av1Distribution[][] uvMode = Av1DefaultDistributions.UvMode;
+ private readonly Av1Distribution[] skip = Av1DefaultDistributions.Skip;
+ private readonly Av1Distribution[] skipMode = Av1DefaultDistributions.SkipMode;
+ private readonly Av1Distribution deltaLoopFilterAbsolute = Av1DefaultDistributions.DeltaLoopFilterAbsolute;
+ private readonly Av1Distribution deltaQuantizerAbsolute = Av1DefaultDistributions.DeltaQuantizerAbsolute;
+ private readonly Av1Distribution[] segmentId = Av1DefaultDistributions.SegmentId;
+ private readonly Av1Distribution[] angleDelta = Av1DefaultDistributions.AngleDelta;
+ private readonly Av1Distribution filterIntraMode = Av1DefaultDistributions.FilterIntraMode;
+ private readonly Av1Distribution[] filterIntra = Av1DefaultDistributions.FilterIntra;
+ private readonly Av1Distribution[][] transformSize = Av1DefaultDistributions.TransformSize;
+ private readonly Av1Distribution[][][] endOfBlockFlag;
+ private readonly Av1Distribution[][][] coefficientsBase;
+ private readonly Av1Distribution[][][] baseEndOfBlock;
+ private readonly Av1Distribution[][] dcSign;
+ private readonly Av1Distribution[][][] coefficientsBaseRange;
+ private readonly Av1Distribution[][] transformBlockSkip;
+ private readonly Av1Distribution[][][] endOfBlockExtra;
+ private readonly Av1Distribution chromaFromLumaSign = Av1DefaultDistributions.ChromaFromLumaSign;
+ private readonly Av1Distribution[] chromaFromLumaAlpha = Av1DefaultDistributions.ChromaFromLumaAlpha;
+ private readonly Av1Distribution[][][] intraExtendedTransform = Av1DefaultDistributions.IntraExtendedTransform;
+ private readonly Configuration configuration;
+ private Av1SymbolReader reader;
+ private readonly int baseQIndex;
+
+ public Av1SymbolDecoder(Configuration configuration, Span tileData, int qIndex)
+ {
+ this.configuration = configuration;
+ this.reader = new Av1SymbolReader(tileData);
+ this.baseQIndex = qIndex;
+ this.endOfBlockFlag = Av1DefaultDistributions.GetEndOfBlockFlag(qIndex);
+ this.coefficientsBase = Av1DefaultDistributions.GetCoefficientsBase(qIndex);
+ this.baseEndOfBlock = Av1DefaultDistributions.GetBaseEndOfBlock(qIndex);
+ this.dcSign = Av1DefaultDistributions.GetDcSign(qIndex);
+ this.coefficientsBaseRange = Av1DefaultDistributions.GetCoefficientsBaseRange(qIndex);
+ this.transformBlockSkip = Av1DefaultDistributions.GetTransformBlockSkip(qIndex);
+ this.endOfBlockExtra = Av1DefaultDistributions.GetEndOfBlockExtra(qIndex);
+ }
+
+ public int ReadCdfStrength(int bitCount)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ return r.ReadLiteral(bitCount);
+ }
+
+ public bool ReadUseIntraBlockCopy()
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ return r.ReadSymbol(this.tileIntraBlockCopy) > 0;
+ }
+
+ public Av1PartitionType ReadPartitionType(int context)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ return (Av1PartitionType)r.ReadSymbol(this.tilePartitionTypes[context]);
+ }
+
+ ///
+ /// SVT: partition_gather_vert_alike
+ ///
+ public Av1PartitionType ReadSplitOrHorizontal(Av1BlockSize blockSize, int context)
+ {
+ Av1Distribution distribution = GetSplitOrHorizontalDistribution(this.tilePartitionTypes, blockSize, context);
+ ref Av1SymbolReader r = ref this.reader;
+ return r.ReadSymbol(distribution) > 0 ? Av1PartitionType.Split : Av1PartitionType.Horizontal;
+ }
+
+ ///
+ /// SVT: partition_gather_horz_alike
+ ///
+ public Av1PartitionType ReadSplitOrVertical(Av1BlockSize blockSize, int context)
+ {
+ Av1Distribution distribution = GetSplitOrVerticalDistribution(this.tilePartitionTypes, blockSize, context);
+ ref Av1SymbolReader r = ref this.reader;
+ return r.ReadSymbol(distribution) > 0 ? Av1PartitionType.Split : Av1PartitionType.Vertical;
+ }
+
+ public Av1PredictionMode ReadYMode(Av1BlockModeInfo? aboveModeInfo, Av1BlockModeInfo? leftModeInfo)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ Av1PredictionMode aboveMode = Av1PredictionMode.DC;
+ if (aboveModeInfo != null)
+ {
+ aboveMode = aboveModeInfo.YMode;
+ }
+
+ Av1PredictionMode leftMode = Av1PredictionMode.DC;
+ if (leftModeInfo != null)
+ {
+ leftMode = leftModeInfo.YMode;
+ }
+
+ int aboveContext = IntraModeContext[(int)aboveMode];
+ int leftContext = IntraModeContext[(int)leftMode];
+ return (Av1PredictionMode)r.ReadSymbol(this.keyFrameYMode[aboveContext][leftContext]);
+ }
+
+ public Av1PredictionMode ReadIntraModeUv(Av1PredictionMode mode, bool chromaFromLumaAllowed)
+ {
+ int chromaForLumaIndex = chromaFromLumaAllowed ? 1 : 0;
+ ref Av1SymbolReader r = ref this.reader;
+ return (Av1PredictionMode)r.ReadSymbol(this.uvMode[chromaForLumaIndex][(int)mode]);
+ }
+
+ public bool ReadSkip(int ctx)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ return r.ReadSymbol(this.skip[ctx]) > 0;
+ }
+
+ public bool ReadSkipMode(Av1BlockSize blockSize)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ return r.ReadSymbol(this.skipMode[(int)blockSize]) > 0;
+ }
+
+ public int ReadDeltaLoopFilter()
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ int deltaLoopFilterAbsolute = r.ReadSymbol(this.deltaLoopFilterAbsolute);
+ if (deltaLoopFilterAbsolute == Av1Constants.DeltaLoopFilterSmall)
+ {
+ int deltaLoopFilterRemainingBits = r.ReadLiteral(3) + 1;
+ int deltaLoopFilterAbsoluteBitCount = r.ReadLiteral(deltaLoopFilterRemainingBits);
+ deltaLoopFilterAbsolute = deltaLoopFilterAbsoluteBitCount + (1 << deltaLoopFilterRemainingBits) + 1;
+ }
+
+ bool deltaLoopFilterSign = true;
+ if (deltaLoopFilterAbsolute != 0)
+ {
+ deltaLoopFilterSign = r.ReadLiteral(1) > 0;
+ }
+
+ return deltaLoopFilterSign ? -deltaLoopFilterAbsolute : deltaLoopFilterAbsolute;
+ }
+
+ ///
+ /// SVT: read_delta_qindex
+ ///
+ public int ReadDeltaQuantizerIndex()
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ int deltaQuantizerAbsolute = r.ReadSymbol(this.deltaQuantizerAbsolute);
+ if (deltaQuantizerAbsolute == Av1Constants.DeltaQuantizerSmall)
+ {
+ int deltaQuantizerRemainingBits = r.ReadLiteral(3) + 1;
+ int deltaQuantizerAbsoluteBase = r.ReadLiteral(deltaQuantizerRemainingBits);
+ deltaQuantizerAbsolute = deltaQuantizerAbsoluteBase + (1 << deltaQuantizerRemainingBits) + 1;
+ }
+
+ bool deltaQuantizerSignBit = true;
+ if (deltaQuantizerAbsolute != 0)
+ {
+ deltaQuantizerSignBit = r.ReadLiteral(1) > 0;
+ }
+
+ return deltaQuantizerSignBit ? -deltaQuantizerAbsolute : deltaQuantizerAbsolute;
+ }
+
+ public int ReadSegmentId(int context)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ return r.ReadSymbol(this.segmentId[context]);
+ }
+
+ public int ReadAngleDelta(Av1PredictionMode mode)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ return r.ReadSymbol(this.angleDelta[(int)mode - 1]);
+ }
+
+ public Av1FilterIntraMode ReadFilterUltraMode(Av1BlockSize blockSize)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ Av1FilterIntraMode filterIntraMode = Av1FilterIntraMode.AllFilterIntraModes;
+ bool useFilterIntra = r.ReadSymbol(this.filterIntra[(int)blockSize]) > 0;
+ if (useFilterIntra)
+ {
+ filterIntraMode = (Av1FilterIntraMode)r.ReadSymbol(this.filterIntraMode);
+ }
+
+ return filterIntraMode;
+ }
+
+ public Av1TransformSize ReadTransformSize(Av1BlockSize blockSize, int context)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ Av1TransformSize maxTransformSize = blockSize.GetMaximumTransformSize();
+ int depth = 0;
+ while (maxTransformSize != Av1TransformSize.Size4x4)
+ {
+ depth++;
+ maxTransformSize = maxTransformSize.GetSubSize();
+ DebugGuard.MustBeLessThan(depth, 10, nameof(depth));
+ }
+
+ DebugGuard.MustBeLessThanOrEqualTo(depth, Av1Constants.MaxTransformCategories, nameof(depth));
+ int category = depth - 1;
+ int value = r.ReadSymbol(this.transformSize[category][context]);
+ Av1TransformSize transformSize = blockSize.GetMaximumTransformSize();
+ for (int d = 0; d < value; ++d)
+ {
+ transformSize = transformSize.GetSubSize();
+ }
+
+ return transformSize;
+ }
+
+ ///
+ /// SVT: parse_transform_type
+ ///
+ public Av1TransformType ReadTransformType(
+ Av1TransformSize transformSize,
+ bool useReducedTransformSet,
+ bool useFilterIntra,
+ int baseQIndex,
+ Av1FilterIntraMode filterIntraMode,
+ Av1PredictionMode intraDirection)
+ {
+ Av1TransformType transformType = Av1TransformType.DctDct;
+
+ /*
+ // No need to read transform type if block is skipped.
+ if (mbmi.Skip ||
+ svt_aom_seg_feature_active(&parse_ctxt->frame_header->segmentation_params, mbmi->segment_id, SEG_LVL_SKIP))
+ return;
+ */
+
+ if (baseQIndex == 0)
+ {
+ return transformType;
+ }
+
+ // Ignoring INTER blocks here, as these should not end up here.
+ // int inter_block = is_inter_block_dec(mbmi);
+ Av1TransformSetType transformSetType = Av1SymbolContextHelper.GetExtendedTransformSetType(transformSize, useReducedTransformSet);
+ if (transformSetType > Av1TransformSetType.DctOnly && baseQIndex > 0)
+ {
+ int extendedSet = Av1SymbolContextHelper.GetExtendedTransformSet(transformSetType);
+ Av1TransformSize squareTransformSize = transformSize.GetSquareSize();
+ Av1PredictionMode intraMode = useFilterIntra
+ ? filterIntraMode.ToIntraDirection()
+ : intraDirection;
+ ref Av1SymbolReader r = ref this.reader;
+ int symbol = r.ReadSymbol(this.intraExtendedTransform[extendedSet][(int)squareTransformSize][(int)intraMode]);
+ transformType = Av1SymbolContextHelper.ExtendedTransformInverse[(int)transformSetType][symbol];
+ }
+
+ return transformType;
+ }
+
+ public bool ReadTransformBlockSkip(Av1TransformSize transformSizeContext, int skipContext)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ return r.ReadSymbol(this.transformBlockSkip[(int)transformSizeContext][skipContext]) > 0;
+ }
+
+ public int ReadChromFromLumaSign()
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ return r.ReadSymbol(this.chromaFromLumaSign);
+ }
+
+ public int ReadChromaFromLumaAlphaU(int jointSignPlus1)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ int context = jointSignPlus1 - 3;
+ return r.ReadSymbol(this.chromaFromLumaAlpha[context]);
+ }
+
+ public int ReadChromaFromLumaAlphaV(int jointSignPlus1)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ int context = AlphaVContexts[jointSignPlus1];
+ return r.ReadSymbol(this.chromaFromLumaAlpha[context]);
+ }
+
+ ///
+ /// SVT: parse_coeffs
+ ///
+ public int ReadCoefficients(
+ Av1BlockModeInfo modeInfo,
+ Point blockPosition,
+ int[] aboveContexts,
+ int[] leftContexts,
+ int aboveOffset,
+ int leftOffset,
+ int plane,
+ int blocksWide,
+ int blocksHigh,
+ Av1TransformBlockContext transformBlockContext,
+ Av1TransformSize transformSize,
+ bool isLossless,
+ bool useReducedTransformSet,
+ Av1TransformInfo transformInfo,
+ int modeBlocksToRightEdge,
+ int modeBlocksToBottomEdge,
+ Span coefficientBuffer)
+ {
+ int width = transformSize.GetWidth();
+ int height = transformSize.GetHeight();
+ Av1TransformSize transformSizeContext = Av1SymbolContextHelper.GetTransformSizeContext(transformSize);
+ Av1PlaneType planeType = (Av1PlaneType)Math.Min(plane, 1);
+ int culLevel = 0;
+
+ Av1LevelBuffer levels = new(this.configuration, new Size(width, height));
+
+ bool allZero = this.ReadTransformBlockSkip(transformSizeContext, transformBlockContext.SkipContext);
+ int endOfBlock;
+ if (allZero)
+ {
+ if (plane == 0)
+ {
+ transformInfo.Type = Av1TransformType.DctDct;
+ transformInfo.CodeBlockFlag = false;
+ }
+
+ UpdateCoefficientContext(modeInfo, aboveContexts, leftContexts, blocksWide, blocksHigh, transformSize, blockPosition, aboveOffset, leftOffset, culLevel, modeBlocksToRightEdge, modeBlocksToBottomEdge);
+ return 0;
+ }
+
+ if (plane == (int)Av1Plane.Y)
+ {
+ transformInfo.Type = this.ReadTransformType(transformSize, useReducedTransformSet, modeInfo.FilterIntraModeInfo.UseFilterIntra, this.baseQIndex, modeInfo.FilterIntraModeInfo.Mode, modeInfo.YMode);
+ }
+
+ transformInfo.Type = ComputeTransformType(planeType, modeInfo, isLossless, transformSize, transformInfo, useReducedTransformSet);
+ Av1TransformClass transformClass = transformInfo.Type.ToClass();
+ Av1ScanOrder scanOrder = Av1ScanOrderConstants.GetScanOrder(transformSize, transformInfo.Type);
+ ReadOnlySpan scan = scanOrder.Scan;
+
+ endOfBlock = this.ReadEndOfBlockPosition(transformSize, transformClass, transformSizeContext, planeType);
+ if (endOfBlock > 1)
+ {
+ levels.Clear();
+ }
+
+ this.ReadCoefficientsEndOfBlock(transformClass, endOfBlock, scan, levels, transformSizeContext, planeType);
+ if (endOfBlock > 1)
+ {
+ if (transformClass == Av1TransformClass.Class2D)
+ {
+ this.ReadCoefficientsReverse2d(transformSize, 1, endOfBlock - 1 - 1, scan, levels, transformSizeContext, planeType);
+ this.ReadCoefficientsReverse(transformSize, transformClass, 0, 0, scan, levels, transformSizeContext, planeType);
+ }
+ else
+ {
+ this.ReadCoefficientsReverse(transformSize, transformClass, 0, endOfBlock - 1 - 1, scan, levels, transformSizeContext, planeType);
+ }
+ }
+
+ DebugGuard.MustBeGreaterThan(scan.Length, 0, nameof(scan));
+ culLevel = this.ReadCoefficientsSign(coefficientBuffer, endOfBlock, scan, levels, transformBlockContext.DcSignContext, planeType);
+ UpdateCoefficientContext(modeInfo, aboveContexts, leftContexts, blocksWide, blocksHigh, transformSize, blockPosition, aboveOffset, leftOffset, culLevel, modeBlocksToRightEdge, modeBlocksToBottomEdge);
+
+ transformInfo.CodeBlockFlag = true;
+ return endOfBlock;
+ }
+
+ public int ReadEndOfBlockPosition(Av1TransformSize transformSize, Av1TransformClass transformClass, Av1TransformSize transformSizeContext, Av1PlaneType planeType)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ int endOfBlockExtra = 0;
+ int endOfBlockPoint = this.ReadEndOfBlockFlag(planeType, transformClass, transformSize);
+ int endOfBlockShift = Av1SymbolContextHelper.EndOfBlockOffsetBits[endOfBlockPoint];
+ if (endOfBlockShift > 0)
+ {
+ int endOfBlockContext = endOfBlockPoint;
+ bool bit = this.ReadEndOfBlockExtra(transformSizeContext, planeType, endOfBlockContext);
+ if (bit)
+ {
+ Av1Math.SetBit(ref endOfBlockExtra, endOfBlockShift - 1);
+ }
+
+ for (int j = 1; j < endOfBlockShift; j++)
+ {
+ if (r.ReadLiteral(1) != 0)
+ {
+ Av1Math.SetBit(ref endOfBlockExtra, endOfBlockShift - 1 - j);
+ }
+ }
+ }
+
+ return Av1SymbolContextHelper.RecordEndOfBlockPosition(endOfBlockPoint, endOfBlockExtra);
+ }
+
+ public void ReadCoefficientsEndOfBlock(Av1TransformClass transformClass, int endOfBlock, ReadOnlySpan scan, Av1LevelBuffer levels, Av1TransformSize transformSizeContext, Av1PlaneType planeType)
+ {
+ int i = endOfBlock - 1;
+ Point position = levels.GetPosition(scan[i]);
+ int coefficientContext = Av1SymbolContextHelper.GetLowerLevelContextEndOfBlock(levels, position);
+ int level = this.ReadBaseEndOfBlock(transformSizeContext, planeType, coefficientContext) + 1;
+ Av1TransformSize limitedTransformSizeContext = (Av1TransformSize)Math.Min((int)transformSizeContext, (int)Av1TransformSize.Size32x32);
+ if (level > Av1Constants.BaseLevelsCount)
+ {
+ int baseRangeContext = Av1SymbolContextHelper.GetBaseRangeContextEndOfBlock(position, transformClass);
+ this.ReadCoefficientsBaseRangeLoop(transformSizeContext, planeType, baseRangeContext, ref level);
+ }
+
+ levels.GetRow(position)[position.X] = (byte)level;
+ }
+
+ public void ReadCoefficientsReverse2d(Av1TransformSize transformSize, int startScanIndex, int endScanIndex, ReadOnlySpan scan, Av1LevelBuffer levels, Av1TransformSize transformSizeContext, Av1PlaneType planeType)
+ {
+ Av1TransformSize limitedTransformSizeContext = (Av1TransformSize)Math.Min((int)transformSizeContext, (int)Av1TransformSize.Size32x32);
+ for (int c = endScanIndex; c >= startScanIndex; --c)
+ {
+ Point position = levels.GetPosition(scan[c]);
+ int coefficientContext = Av1SymbolContextHelper.GetLowerLevelsContext2d(levels, position, transformSize);
+ int level = this.ReadCoefficientsBase(transformSizeContext, planeType, coefficientContext);
+ if (level > Av1Constants.BaseLevelsCount)
+ {
+ int baseRangeContext = Av1SymbolContextHelper.GetBaseRangeContext2d(levels, position);
+ this.ReadCoefficientsBaseRangeLoop(transformSizeContext, planeType, baseRangeContext, ref level);
+ }
+
+ levels.GetRow(position)[position.X] = (byte)level;
+ }
+ }
+
+ public void ReadCoefficientsReverse(Av1TransformSize transformSize, Av1TransformClass transformClass, int startScanIndex, int endScanIndex, ReadOnlySpan scan, Av1LevelBuffer levels, Av1TransformSize transformSizeContext, Av1PlaneType planeType)
+ {
+ Av1TransformSize limitedTransformSizeContext = (Av1TransformSize)Math.Min((int)transformSizeContext, (int)Av1TransformSize.Size32x32);
+ for (int c = endScanIndex; c >= startScanIndex; --c)
+ {
+ int pos = scan[c];
+ Point position = levels.GetPosition(pos);
+ int coefficientContext = Av1SymbolContextHelper.GetLowerLevelsContext(levels, position, transformSize, transformClass);
+ int level = this.ReadCoefficientsBase(transformSizeContext, planeType, coefficientContext);
+ if (level > Av1Constants.BaseLevelsCount)
+ {
+ int baseRangeContext = Av1SymbolContextHelper.GetBaseRangeContext(levels, position, transformClass);
+ this.ReadCoefficientsBaseRangeLoop(transformSizeContext, planeType, baseRangeContext, ref level);
+ }
+
+ levels.GetRow(position)[position.X] = (byte)level;
+ }
+ }
+
+ public int ReadCoefficientsSign(Span coefficientBuffer, int endOfBlock, ReadOnlySpan scan, Av1LevelBuffer levels, int dcSignContext, Av1PlaneType planeType)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ int maxScanLine = 0;
+ int culLevel = 0;
+ int dcValue = 0;
+ coefficientBuffer[0] = endOfBlock;
+ for (int c = 0; c < endOfBlock; c++)
+ {
+ int sign = 0;
+ Point position = levels.GetPosition(c);
+ int level = levels[position];
+ if (level != 0)
+ {
+ maxScanLine = Math.Max(maxScanLine, scan[c]);
+ if (c == 0)
+ {
+ sign = this.ReadDcSign(planeType, dcSignContext);
+ }
+ else
+ {
+ sign = r.ReadLiteral(1);
+ }
+
+ if (level >= Av1Constants.CoefficientBaseRange + Av1Constants.BaseLevelsCount + 1)
+ {
+ level += this.ReadGolomb();
+ }
+
+ if (c == 0)
+ {
+ dcValue = sign != 0 ? -level : level;
+ }
+
+ level &= 0xfffff;
+ culLevel += level;
+ }
+
+ coefficientBuffer[c + 1] = sign != 0 ? -level : level;
+ }
+
+ culLevel = Math.Min(Av1Constants.CoefficientContextMask, culLevel);
+ Av1SymbolContextHelper.SetDcSign(ref culLevel, dcValue);
+
+ return culLevel;
+ }
+
+ private int ReadEndOfBlockFlag(Av1PlaneType planeType, Av1TransformClass transformClass, Av1TransformSize transformSize)
+ {
+ int endOfBlockContext = transformClass == Av1TransformClass.Class2D ? 0 : 1;
+ int endOfBlockMultiSize = transformSize.GetLog2Minus4();
+ ref Av1SymbolReader r = ref this.reader;
+ return r.ReadSymbol(this.endOfBlockFlag[endOfBlockMultiSize][(int)planeType][endOfBlockContext]) + 1;
+ }
+
+ private bool ReadEndOfBlockExtra(Av1TransformSize transformSizeContext, Av1PlaneType planeType, int endOfBlockContext)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ return r.ReadSymbol(this.endOfBlockExtra[(int)transformSizeContext][(int)planeType][endOfBlockContext]) > 0;
+ }
+
+ private int ReadCoefficientsBaseRange(Av1TransformSize transformSizeContext, Av1PlaneType planeType, int baseRangeContext)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ return r.ReadSymbol(this.coefficientsBaseRange[(int)transformSizeContext][(int)planeType][baseRangeContext]);
+ }
+
+ private int ReadDcSign(Av1PlaneType planeType, int dcSignContext)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ return r.ReadSymbol(this.dcSign[(int)planeType][dcSignContext]);
+ }
+
+ private int ReadBaseEndOfBlock(Av1TransformSize transformSizeContext, Av1PlaneType planeType, int coefficientContext)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ return r.ReadSymbol(this.baseEndOfBlock[(int)transformSizeContext][(int)planeType][coefficientContext]);
+ }
+
+ private int ReadCoefficientsBase(Av1TransformSize transformSizeContext, Av1PlaneType planeType, int coefficientContext)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ return r.ReadSymbol(this.coefficientsBase[(int)transformSizeContext][(int)planeType][coefficientContext]);
+ }
+
+ private void ReadCoefficientsBaseRangeLoop(Av1TransformSize transformSizeContext, Av1PlaneType planeType, int baseRangeContext, ref int level)
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ Av1TransformSize limitedTransformSizeContext = (Av1TransformSize)Math.Min((int)transformSizeContext, (int)Av1TransformSize.Size32x32);
+ Av1Distribution distribution = this.coefficientsBaseRange[(int)limitedTransformSizeContext][(int)planeType][baseRangeContext];
+ for (int idx = 0; idx < Av1Constants.CoefficientBaseRange; idx += Av1Constants.BaseRangeSizeMinus1)
+ {
+ int coefficientBaseRange = r.ReadSymbol(distribution);
+ level += coefficientBaseRange;
+ if (coefficientBaseRange < Av1Constants.BaseRangeSizeMinus1)
+ {
+ break;
+ }
+ }
+ }
+
+ internal int ReadGolomb()
+ {
+ ref Av1SymbolReader r = ref this.reader;
+ int x = 1;
+ int length = 0;
+ int i = 0;
+
+ while (i == 0)
+ {
+ i = r.ReadLiteral(1);
+ ++length;
+ if (length > 20)
+ {
+ // SVT_LOG("Invalid length in read_golomb");
+ break;
+ }
+ }
+
+ for (i = 0; i < length - 1; ++i)
+ {
+ x <<= 1;
+ x += r.ReadLiteral(1);
+ }
+
+ return x - 1;
+ }
+
+ private static void UpdateCoefficientContext(
+ Av1BlockModeInfo modeInfo,
+ int[] aboveContexts,
+ int[] leftContexts,
+ int blocksWide,
+ int blocksHigh,
+ Av1TransformSize transformSize,
+ Point blockPosition,
+ int aboveOffset,
+ int leftOffset,
+ int culLevel,
+ int modeBlockToRightEdge,
+ int modeBlockToBottomEdge)
+ {
+ int transformSizeWide = transformSize.Get4x4WideCount();
+ int transformSizeHigh = transformSize.Get4x4HighCount();
+
+ if (modeBlockToRightEdge < 0)
+ {
+ int aboveContextCount = Math.Min(transformSizeWide, blocksWide - aboveOffset);
+ Array.Fill(aboveContexts, culLevel, 0, aboveContextCount);
+ Array.Fill(aboveContexts, 0, aboveContextCount, transformSizeWide - aboveContextCount);
+ }
+ else
+ {
+ Array.Fill(aboveContexts, culLevel, 0, transformSizeWide);
+ }
+
+ if (modeBlockToBottomEdge < 0)
+ {
+ int leftContextCount = Math.Min(transformSizeHigh, blocksHigh - leftOffset);
+ Array.Fill(leftContexts, culLevel, 0, leftContextCount);
+ Array.Fill(leftContexts, 0, leftContextCount, transformSizeWide - leftContextCount);
+ }
+ else
+ {
+ Array.Fill(leftContexts, culLevel, 0, transformSizeHigh);
+ }
+ }
+
+ private static Av1TransformType ComputeTransformType(Av1PlaneType planeType, Av1BlockModeInfo modeInfo, bool isLossless, Av1TransformSize transformSize, Av1TransformInfo transformInfo, bool useReducedTransformSet)
+ {
+ Av1TransformType transformType = Av1TransformType.DctDct;
+ if (isLossless || transformSize.GetSquareUpSize() > Av1TransformSize.Size32x32)
+ {
+ transformType = Av1TransformType.DctDct;
+ }
+ else
+ {
+ if (planeType == Av1PlaneType.Y)
+ {
+ transformType = transformInfo.Type;
+ }
+ else
+ {
+ // In intra mode, uv planes don't share the same prediction mode as y
+ // plane, so the tx_type should not be shared
+ transformType = Av1SymbolContextHelper.ConvertIntraModeToTransformType(modeInfo, Av1PlaneType.Uv);
+ }
+ }
+
+ Av1TransformSetType transformSetType = Av1SymbolContextHelper.GetExtendedTransformSetType(transformSize, useReducedTransformSet);
+ if (!transformType.IsExtendedSetUsed(transformSetType))
+ {
+ transformType = Av1TransformType.DctDct;
+ }
+
+ return transformType;
+ }
+
+ internal static Av1Distribution GetSplitOrHorizontalDistribution(Av1Distribution[] inputs, Av1BlockSize blockSize, int context)
+ {
+ Av1Distribution input = inputs[context];
+ uint p = Av1Distribution.ProbabilityTop;
+ p -= GetElementProbability(input, Av1PartitionType.Horizontal);
+ p -= GetElementProbability(input, Av1PartitionType.Split);
+ p -= GetElementProbability(input, Av1PartitionType.HorizontalA);
+ p -= GetElementProbability(input, Av1PartitionType.HorizontalB);
+ p -= GetElementProbability(input, Av1PartitionType.VerticalA);
+ if (blockSize != Av1BlockSize.Block128x128)
+ {
+ p -= GetElementProbability(input, Av1PartitionType.Horizontal4);
+ }
+
+ return new(Av1Distribution.ProbabilityTop - p);
+ }
+
+ internal static Av1Distribution GetSplitOrVerticalDistribution(Av1Distribution[] inputs, Av1BlockSize blockSize, int context)
+ {
+ Av1Distribution input = inputs[context];
+ uint p = Av1Distribution.ProbabilityTop;
+ p -= GetElementProbability(input, Av1PartitionType.Vertical);
+ p -= GetElementProbability(input, Av1PartitionType.Split);
+ p -= GetElementProbability(input, Av1PartitionType.HorizontalA);
+ p -= GetElementProbability(input, Av1PartitionType.VerticalA);
+ p -= GetElementProbability(input, Av1PartitionType.VerticalB);
+ if (blockSize != Av1BlockSize.Block128x128)
+ {
+ p -= GetElementProbability(input, Av1PartitionType.Vertical4);
+ }
+
+ return new(Av1Distribution.ProbabilityTop - p);
+ }
+
+ private static uint GetElementProbability(Av1Distribution probability, Av1PartitionType element)
+ => probability[(int)element - 1] - probability[(int)element];
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolEncoder.cs b/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolEncoder.cs
new file mode 100644
index 0000000000..4f98f446f4
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolEncoder.cs
@@ -0,0 +1,417 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Buffers;
+using SixLabors.ImageSharp.Formats.Heif.Av1;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Entropy;
+
+internal class Av1SymbolEncoder : IDisposable
+{
+ private readonly Av1Distribution tileIntraBlockCopy = Av1DefaultDistributions.IntraBlockCopy;
+ private readonly Av1Distribution[] tilePartitionTypes = Av1DefaultDistributions.PartitionTypes;
+ private readonly Av1Distribution[][] keyFrameYMode = Av1DefaultDistributions.KeyFrameYMode;
+ private readonly Av1Distribution[][] uvMode = Av1DefaultDistributions.UvMode;
+ private readonly Av1Distribution[][] transformBlockSkip;
+ private readonly Av1Distribution[][][] endOfBlockFlag;
+ private readonly Av1Distribution[][][] coefficientsBaseRange;
+ private readonly Av1Distribution[][][] coefficientsBase;
+ private readonly Av1Distribution[][][] coefficientsBaseEndOfBlock;
+ private readonly Av1Distribution[] filterIntra = Av1DefaultDistributions.FilterIntra;
+ private readonly Av1Distribution filterIntraMode = Av1DefaultDistributions.FilterIntraMode;
+ private readonly Av1Distribution deltaQuantizerAbsolute = Av1DefaultDistributions.DeltaQuantizerAbsolute;
+ private readonly Av1Distribution[][] dcSign;
+ private readonly Av1Distribution[][][] endOfBlockExtra;
+ private readonly Av1Distribution[][][] intraExtendedTransform = Av1DefaultDistributions.IntraExtendedTransform;
+ private readonly Av1Distribution[] segmentId = Av1DefaultDistributions.SegmentId;
+ private readonly Av1Distribution[] angleDelta = Av1DefaultDistributions.AngleDelta;
+ private readonly Av1Distribution[] skip = Av1DefaultDistributions.Skip;
+ private readonly Av1Distribution[] skipMode = Av1DefaultDistributions.SkipMode;
+ private readonly Av1Distribution chromaFromLumaSign = Av1DefaultDistributions.ChromaFromLumaSign;
+ private readonly Av1Distribution[] chromaFromLumaAlpha = Av1DefaultDistributions.ChromaFromLumaAlpha;
+ private bool isDisposed;
+ private readonly Configuration configuration;
+ private Av1SymbolWriter writer;
+ private readonly int baseQIndex;
+
+ public Av1SymbolEncoder(Configuration configuration, int initialSize, int qIndex)
+ {
+ this.transformBlockSkip = Av1DefaultDistributions.GetTransformBlockSkip(qIndex);
+ this.endOfBlockFlag = Av1DefaultDistributions.GetEndOfBlockFlag(qIndex);
+ this.coefficientsBaseRange = Av1DefaultDistributions.GetCoefficientsBaseRange(qIndex);
+ this.coefficientsBase = Av1DefaultDistributions.GetCoefficientsBase(qIndex);
+ this.coefficientsBaseEndOfBlock = Av1DefaultDistributions.GetBaseEndOfBlock(qIndex);
+ this.dcSign = Av1DefaultDistributions.GetDcSign(qIndex);
+ this.endOfBlockExtra = Av1DefaultDistributions.GetEndOfBlockExtra(qIndex);
+ this.configuration = configuration;
+ this.writer = new(configuration, initialSize);
+ this.baseQIndex = qIndex;
+ }
+
+ public void WriteUseIntraBlockCopy(bool value)
+ {
+ ref Av1SymbolWriter w = ref this.writer;
+ w.WriteSymbol(value, this.tileIntraBlockCopy);
+ }
+
+ public void WritePartitionType(Av1PartitionType partitionType, int context)
+ {
+ ref Av1SymbolWriter w = ref this.writer;
+ w.WriteSymbol((int)partitionType, this.tilePartitionTypes[context]);
+ }
+
+ public void WriteSplitOrHorizontal(Av1PartitionType partitionType, Av1BlockSize blockSize, int context)
+ {
+ Av1Distribution distribution = Av1SymbolDecoder.GetSplitOrHorizontalDistribution(this.tilePartitionTypes, blockSize, context);
+ int value = partitionType == Av1PartitionType.Split ? 1 : 0;
+ ref Av1SymbolWriter w = ref this.writer;
+ w.WriteSymbol(value, distribution);
+ }
+
+ public void WriteSplitOrVertical(Av1PartitionType partitionType, Av1BlockSize blockSize, int context)
+ {
+ Av1Distribution distribution = Av1SymbolDecoder.GetSplitOrVerticalDistribution(this.tilePartitionTypes, blockSize, context);
+ int value = partitionType == Av1PartitionType.Split ? 1 : 0;
+ ref Av1SymbolWriter w = ref this.writer;
+ w.WriteSymbol(value, distribution);
+ }
+
+ ///
+ /// SVT: av1_write_coeffs_txb_1d
+ ///
+ public int WriteCoefficients(
+ Av1TransformSize transformSize,
+ Av1TransformType transformType,
+ Av1PredictionMode intraDirection,
+ Span coefficientBuffer,
+ Av1ComponentType componentType,
+ Av1TransformBlockContext transformBlockContext,
+ ushort endOfBlock,
+ bool useReducedTransformSet,
+ Av1FilterIntraMode filterIntraMode)
+ {
+ int c;
+ int width = transformSize.GetWidth();
+ int height = transformSize.GetHeight();
+ Av1TransformClass transformClass = transformType.ToClass();
+ Av1ScanOrder scanOrder = Av1ScanOrderConstants.GetScanOrder(transformSize, transformType);
+ ReadOnlySpan scan = scanOrder.Scan;
+ int blockWidthLog2 = transformSize.GetBlockWidthLog2();
+ Av1TransformSize transformSizeContext = Av1SymbolContextHelper.GetTransformSizeContext(transformSize);
+
+ ref Av1SymbolWriter w = ref this.writer;
+
+ Av1LevelBuffer levels = new(this.configuration, new Size(width, height));
+ Span coefficientContexts = new sbyte[width * height];
+
+ Guard.MustBeLessThan((int)transformSizeContext, (int)Av1TransformSize.AllSizes, nameof(transformSizeContext));
+
+ this.WriteTransformBlockSkip(endOfBlock == 0, transformSizeContext, transformBlockContext.SkipContext);
+
+ if (endOfBlock == 0)
+ {
+ return 0;
+ }
+
+ levels.Initialize(coefficientBuffer);
+ if (componentType == Av1ComponentType.Luminance)
+ {
+ this.WriteTransformType(transformType, transformSize, useReducedTransformSet, this.baseQIndex, filterIntraMode, intraDirection);
+ }
+
+ this.WriteEndOfBlockPosition(endOfBlock, componentType, transformClass, transformSize, transformSizeContext);
+
+ Av1SymbolContextHelper.GetNzMapContexts(levels, scan, endOfBlock, transformSize, transformClass, coefficientContexts);
+ int limitedTransformSizeContext = Math.Min((int)transformSizeContext, (int)Av1TransformSize.Size32x32);
+ for (c = endOfBlock - 1; c >= 0; --c)
+ {
+ short pos = scan[c];
+ int v = coefficientBuffer[pos];
+ short coeffContext = coefficientContexts[pos];
+ Point position = levels.GetPosition(pos);
+ int level = Math.Abs(v);
+
+ if (c == endOfBlock - 1)
+ {
+ w.WriteSymbol(Math.Min(level, 3) - 1, this.coefficientsBaseEndOfBlock[(int)transformSizeContext][(int)componentType][coeffContext]);
+ }
+ else
+ {
+ w.WriteSymbol(Math.Min(level, 3), this.coefficientsBase[(int)transformSizeContext][(int)componentType][coeffContext]);
+ }
+
+ if (level > Av1Constants.BaseLevelsCount)
+ {
+ // level is above 1.
+ int baseRange = level - 1 - Av1Constants.BaseLevelsCount;
+ int baseRangeContext = Av1SymbolContextHelper.GetBaseRangeContext(levels, position, transformClass);
+ for (int idx = 0; idx < Av1Constants.CoefficientBaseRange; idx += Av1Constants.BaseRangeSizeMinus1)
+ {
+ int k = Math.Min(baseRange - idx, Av1Constants.BaseRangeSizeMinus1);
+ w.WriteSymbol(k, this.coefficientsBaseRange[limitedTransformSizeContext][(int)componentType][baseRangeContext]);
+ if (k < Av1Constants.BaseRangeSizeMinus1)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ // Loop to code all signs in the transform block,
+ // starting with the sign of DC (if applicable)
+ int cul_level = 0;
+ for (c = 0; c < endOfBlock; ++c)
+ {
+ short pos = scan[c];
+ int v = coefficientBuffer[pos];
+ int level = Math.Abs(v);
+ cul_level += level;
+
+ uint sign = v < 0 ? 1u : 0u;
+ if (level > 0)
+ {
+ if (c == 0)
+ {
+ w.WriteSymbol((int)sign, this.dcSign[(int)componentType][transformBlockContext.DcSignContext]);
+ }
+ else
+ {
+ w.WriteLiteral(sign, 1);
+ }
+
+ if (level > (Av1Constants.CoefficientBaseRange + Av1Constants.BaseLevelsCount))
+ {
+ this.WriteGolomb(level - Av1Constants.CoefficientBaseRange - 1 - Av1Constants.BaseLevelsCount);
+ }
+ }
+ }
+
+ cul_level = Math.Min(Av1Constants.CoefficientContextMask, cul_level);
+
+ // DC value
+ Av1SymbolContextHelper.SetDcSign(ref cul_level, coefficientBuffer[0]);
+ return cul_level;
+ }
+
+ internal void WriteEndOfBlockPosition(ushort endOfBlock, Av1ComponentType componentType, Av1TransformClass transformClass, Av1TransformSize transformSize, Av1TransformSize transformSizeContext)
+ {
+ short endOfBlockPosition = Av1SymbolContextHelper.GetEndOfBlockPosition(endOfBlock, out int eobExtra);
+ this.WriteEndOfBlockFlag(componentType, transformClass, transformSize, endOfBlockPosition);
+
+ int eobOffsetBitCount = Av1SymbolContextHelper.EndOfBlockOffsetBits[endOfBlockPosition];
+ if (eobOffsetBitCount > 0)
+ {
+ ref Av1SymbolWriter w = ref this.writer;
+ int eobShift = eobOffsetBitCount - 1;
+ int bit = Av1Math.GetBit(eobExtra, eobShift);
+ w.WriteSymbol(bit, this.endOfBlockExtra[(int)transformSizeContext][(int)componentType][endOfBlockPosition]);
+ for (int i = 1; i < eobOffsetBitCount; i++)
+ {
+ eobShift = eobOffsetBitCount - 1 - i;
+ bit = Av1Math.GetBit(eobExtra, eobShift);
+ w.WriteLiteral((uint)bit, 1);
+ }
+ }
+ }
+
+ internal void WriteTransformBlockSkip(bool skip, Av1TransformSize transformSizeContext, int skipContext)
+ {
+ ref Av1SymbolWriter w = ref this.writer;
+ w.WriteSymbol(skip, this.transformBlockSkip[(int)transformSizeContext][skipContext]);
+ }
+
+ public IMemoryOwner Exit()
+ {
+ ref Av1SymbolWriter w = ref this.writer;
+ return w.Exit();
+ }
+
+ public void Dispose()
+ {
+ if (!this.isDisposed)
+ {
+ this.writer.Dispose();
+ this.isDisposed = true;
+ }
+ }
+
+ ///
+ /// SVT: write_golomb
+ ///
+ internal void WriteGolomb(int level)
+ {
+ uint x = (uint)level + 1u;
+ int length = (int)Av1Math.Log2_32(x) + 1;
+
+ Guard.MustBeGreaterThan(length, 0, nameof(length));
+
+ ref Av1SymbolWriter w = ref this.writer;
+ for (int i = 0; i < length - 1; ++i)
+ {
+ w.WriteLiteral(0u, 1);
+ }
+
+ for (int j = length - 1; j >= 0; --j)
+ {
+ w.WriteLiteral((x >> j) & 0x01, 1);
+ }
+ }
+
+ private void WriteEndOfBlockFlag(Av1ComponentType componentType, Av1TransformClass transformClass, Av1TransformSize transformSize, int endOfBlockPosition)
+ {
+ int endOfBlockMultiSize = transformSize.GetLog2Minus4();
+ int endOfBlockContext = transformClass == Av1TransformClass.Class2D ? 0 : 1;
+ ref Av1SymbolWriter w = ref this.writer;
+ w.WriteSymbol(endOfBlockPosition - 1, this.endOfBlockFlag[endOfBlockMultiSize][(int)componentType][endOfBlockContext]);
+ }
+
+ ///
+ /// SVT: av1_write_tx_type
+ ///
+ internal void WriteTransformType(
+ Av1TransformType transformType,
+ Av1TransformSize transformSize,
+ bool useReducedTransformSet,
+ int baseQIndex,
+ Av1FilterIntraMode filterIntraMode,
+ Av1PredictionMode intraDirection)
+ {
+ // bool isInter = mbmi->block_mi.use_intrabc || is_inter_mode(mbmi->block_mi.mode);
+ Av1TransformSetType transformSetType = Av1SymbolContextHelper.GetExtendedTransformSetType(transformSize, useReducedTransformSet);
+ if (Av1SymbolContextHelper.GetExtendedTransformTypeCount(transformSetType) > 1 && baseQIndex > 0)
+ {
+ Av1TransformSize squareTransformSize = transformSize.GetSquareSize();
+ Guard.MustBeLessThanOrEqualTo((int)squareTransformSize, Av1Constants.ExtendedTransformCount, nameof(squareTransformSize));
+
+ int extendedSet = Av1SymbolContextHelper.GetExtendedTransformSet(transformSetType);
+
+ // eset == 0 should correspond to a set with only DCT_DCT and there
+ // is no need to send the tx_type
+ Guard.MustBeGreaterThan(extendedSet, 0, nameof(extendedSet));
+
+ // assert(av1_ext_tx_used[tx_set_type][transformType]);
+ Av1PredictionMode intraDirectionContext;
+ if (filterIntraMode != Av1FilterIntraMode.AllFilterIntraModes)
+ {
+ intraDirectionContext = filterIntraMode.ToIntraDirection();
+ }
+ else
+ {
+ intraDirectionContext = intraDirection;
+ }
+
+ Guard.MustBeLessThan((int)intraDirectionContext, 13, nameof(intraDirectionContext));
+ Guard.MustBeLessThan((int)squareTransformSize, 4, nameof(squareTransformSize));
+ ref Av1SymbolWriter w = ref this.writer;
+ w.WriteSymbol(
+ Av1SymbolContextHelper.ExtendedTransformIndices[(int)transformSetType][(int)transformType],
+ this.intraExtendedTransform[extendedSet][(int)squareTransformSize][(int)intraDirectionContext]);
+ }
+ }
+
+ internal void WriteSegmentId(int segmentId, int context)
+ {
+ ref Av1SymbolWriter w = ref this.writer;
+ w.WriteSymbol(segmentId, this.segmentId[context]);
+ }
+
+ internal void WriteSkip(bool skip, int context)
+ {
+ ref Av1SymbolWriter w = ref this.writer;
+ w.WriteSymbol(skip, this.skip[context]);
+ }
+
+ internal void WriteSkipMode(bool skip, int context)
+ {
+ ref Av1SymbolWriter w = ref this.writer;
+ w.WriteSymbol(skip, this.skipMode[context]);
+ }
+
+ internal void WriteFilterIntraMode(Av1FilterIntraMode filterIntraMode, Av1BlockSize blockSize)
+ {
+ ref Av1SymbolWriter w = ref this.writer;
+ bool useFilter = filterIntraMode != Av1FilterIntraMode.AllFilterIntraModes;
+ w.WriteSymbol(useFilter, this.filterIntra[(int)blockSize]);
+ if (useFilter)
+ {
+ w.WriteSymbol((int)filterIntraMode, this.filterIntraMode);
+ }
+ }
+
+ ///
+ /// SVT: av1_write_delta_q_index
+ ///
+ internal void WriteDeltaQuantizerIndex(int deltaQindex)
+ {
+ ref Av1SymbolWriter w = ref this.writer;
+ bool sign = deltaQindex < 0;
+ int abs = Math.Abs(deltaQindex);
+ bool smallval = abs < Av1Constants.DeltaQuantizerSmall;
+
+ w.WriteSymbol(Math.Min(abs, Av1Constants.DeltaQuantizerSmall), this.deltaQuantizerAbsolute);
+
+ if (!smallval)
+ {
+ int rem_bits = Av1Math.MostSignificantBit((uint)(abs - 1));
+ int threshold = (1 << rem_bits) + 1;
+ w.WriteLiteral((uint)(rem_bits - 1), 3);
+ w.WriteLiteral((uint)(abs - threshold), rem_bits);
+ }
+
+ if (abs > 0)
+ {
+ w.WriteLiteral(sign);
+ }
+ }
+
+ internal void WriteLumaMode(Av1PredictionMode lumaMode, byte topContext, byte leftContext)
+ {
+ ref Av1SymbolWriter w = ref this.writer;
+ w.WriteSymbol((int)lumaMode, this.keyFrameYMode[topContext][leftContext]);
+ }
+
+ internal void WriteAngleDelta(int angleDelta, Av1PredictionMode context)
+ {
+ ref Av1SymbolWriter w = ref this.writer;
+ w.WriteSymbol(angleDelta, this.angleDelta[context - Av1PredictionMode.Vertical]);
+ }
+
+ internal void WriteCdefStrength(int cdefStrength, int bitCount)
+ {
+ ref Av1SymbolWriter w = ref this.writer;
+ w.WriteLiteral((uint)cdefStrength, bitCount);
+ }
+
+ internal void WriteChromaMode(Av1PredictionMode chromaMode, bool isChromaFromLumaAllowed, Av1PredictionMode lumaMode)
+ {
+ ref Av1SymbolWriter w = ref this.writer;
+ int cflAllowed = isChromaFromLumaAllowed ? 1 : 0;
+ w.WriteSymbol((int)chromaMode, this.uvMode[cflAllowed][(int)lumaMode]);
+ }
+
+ internal void WriteChromaFromLumaAlphas(int chromaFromLumaIndex, int joinedSign)
+ {
+ ref Av1SymbolWriter w = ref this.writer;
+ w.WriteSymbol(joinedSign, this.chromaFromLumaSign);
+
+ // Magnitudes are only signaled for nonzero codes.
+ int signU = ((joinedSign + 1) * 11) >> 5;
+ if (signU != 0)
+ {
+ int contextU = chromaFromLumaIndex - 2;
+ int indexU = chromaFromLumaIndex >> Av1Constants.ChromaFromLumaAlphabetSizeLog2;
+ w.WriteSymbol(indexU, this.chromaFromLumaAlpha[contextU]);
+ }
+
+ int signV = (joinedSign + 1) - (3 * signU);
+ if (signV != 0)
+ {
+ int contextV = (signV * 3) - signU - 3;
+ int indexV = chromaFromLumaIndex & ((1 << Av1Constants.ChromaFromLumaAlphabetSizeLog2) - 1);
+ w.WriteSymbol(indexV, this.chromaFromLumaAlpha[contextV]);
+ }
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolReader.cs b/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolReader.cs
new file mode 100644
index 0000000000..9f61999abd
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolReader.cs
@@ -0,0 +1,207 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Entropy;
+
+internal ref struct Av1SymbolReader
+{
+ private const int DecoderWindowsSize = 32;
+ private const int LotsOfBits = 0x4000;
+
+ private readonly Span buffer;
+ private int position;
+
+ /*
+ * The difference between the high end of the current range, (low + rng), and
+ * the coded value, minus 1.
+ * This stores up to OD_EC_WINDOW_SIZE bits of that difference, but the
+ * decoder only uses the top 16 bits of the window to decode the next symbol.
+ * As we shift up during renormalization, if we don't have enough bits left in
+ * the window to fill the top 16, we'll read in more bits of the coded
+ * value.
+ */
+ private uint difference;
+
+ // The number of values in the current range.
+ private uint range;
+
+ // The number of bits in the current value.
+ private int count;
+
+ public Av1SymbolReader(Span span)
+ {
+ this.buffer = span;
+ this.position = 0;
+ this.difference = (1U << (DecoderWindowsSize - 1)) - 1;
+ this.range = 0x8000;
+ this.count = -15;
+ this.Refill();
+ }
+
+ public int ReadSymbol(Av1Distribution distribution)
+ {
+ int value = this.DecodeIntegerQ15(distribution);
+
+ // UpdateCdf(probabilities, value, numberOfSymbols);
+ distribution.Update(value);
+ return value;
+ }
+
+ public int ReadLiteral(int bitCount)
+ {
+ const uint prob = (0x7FFFFFU - (128 << 15) + 128) >> 8;
+ int literal = 0;
+ for (int bit = bitCount - 1; bit >= 0; bit--)
+ {
+ if (this.DecodeBoolQ15(prob))
+ {
+ literal |= 1 << bit;
+ }
+ }
+
+ return literal;
+ }
+
+ ///
+ /// Decode a single binary value.
+ ///
+ /// The probability that the bit is one, scaled by 32768.
+ private bool DecodeBoolQ15(uint frequency)
+ {
+ uint dif;
+ uint vw;
+ uint range;
+ uint newRange;
+ uint v;
+ bool ret;
+
+ // assert(0 < f);
+ // assert(f < 32768U);
+ dif = this.difference;
+ range = this.range;
+
+ // assert(dif >> (DecoderWindowsSize - 16) < r);
+ // assert(32768U <= r);
+ v = ((range >> 8) * (frequency >> Av1Distribution.ProbabilityShift)) >> (7 - Av1Distribution.ProbabilityShift);
+ v += Av1Distribution.ProbabilityMinimum;
+ vw = v << (DecoderWindowsSize - 16);
+ ret = true;
+ newRange = v;
+ if (dif >= vw)
+ {
+ newRange = range - v;
+ dif -= vw;
+ ret = false;
+ }
+
+ this.Normalize(dif, newRange);
+ return ret;
+ }
+
+ ///
+ /// Decodes a symbol given an inverse cumulative distribution function(CDF) table in Q15.
+ ///
+ ///
+ /// CDF_PROB_TOP minus the CDF, such that symbol s falls in the range
+ /// [s > 0 ? (CDF_PROB_TOP - icdf[s - 1]) : 0, CDF_PROB_TOP - icdf[s]).
+ /// The values must be monotonically non - increasing, and icdf[nsyms - 1] must be 0.
+ ///
+ /// The decoded symbol.
+ private int DecodeIntegerQ15(Av1Distribution distribution)
+ {
+ uint c;
+ uint u;
+ uint v;
+ int ret;
+
+ uint dif = this.difference;
+ uint r = this.range;
+ int n = distribution.NumberOfSymbols - 1;
+
+ DebugGuard.MustBeLessThan(dif >> (DecoderWindowsSize - 16), r, nameof(r));
+ DebugGuard.IsTrue(distribution[n] == 0, "Last value in probability array needs to be zero.");
+ DebugGuard.MustBeGreaterThanOrEqualTo(r, 32768U, nameof(r));
+ DebugGuard.MustBeGreaterThanOrEqualTo(7 - Av1Distribution.ProbabilityShift - Av1Distribution.CdfShift, 0, nameof(Av1Distribution.CdfShift));
+ c = dif >> (DecoderWindowsSize - 16);
+ v = r;
+ ret = -1;
+ do
+ {
+ u = v;
+ v = ((r >> 8) * (distribution[++ret] >> Av1Distribution.ProbabilityShift)) >> (7 - Av1Distribution.ProbabilityShift - Av1Distribution.CdfShift);
+ v += (uint)(Av1Distribution.ProbabilityMinimum * (n - ret));
+ }
+ while (c < v);
+
+ DebugGuard.MustBeLessThan(v, u, nameof(v));
+ DebugGuard.MustBeLessThanOrEqualTo(u, r, nameof(u));
+ r = u - v;
+ dif -= v << (DecoderWindowsSize - 16);
+ this.Normalize(dif, r);
+ return ret;
+ }
+
+ ///
+ /// Takes updated dif and range values, renormalizes them so that
+ /// has value between 32768 and 65536 (reading more bytes from the stream into dif if
+ /// necessary), and stores them back in the decoder context.
+ ///
+ private void Normalize(uint dif, uint rng)
+ {
+ int d;
+
+ // assert(rng <= 65535U);
+ /*The number of leading zeros in the 16-bit binary representation of rng.*/
+ d = 15 - Av1Math.MostSignificantBit(rng);
+ /*d bits in dec->dif are consumed.*/
+ this.count -= d;
+ /*This is equivalent to shifting in 1's instead of 0's.*/
+ this.difference = ((dif + 1) << d) - 1;
+ this.range = rng << d;
+ if (this.count < 0)
+ {
+ this.Refill();
+ }
+ }
+
+ private void Refill()
+ {
+ int s;
+ uint dif = this.difference;
+ int cnt = this.count;
+ int position = this.position;
+ int end = this.buffer.Length;
+ s = DecoderWindowsSize - 9 - (cnt + 15);
+ for (; s >= 0 && position < end; s -= 8, position++)
+ {
+ /*Each time a byte is inserted into the window (dif), bptr advances and cnt
+ is incremented by 8, so the total number of consumed bits (the return
+ value of od_ec_dec_tell) does not change.*/
+ DebugGuard.MustBeLessThan(s, DecoderWindowsSize - 8, nameof(s));
+ dif ^= (uint)this.buffer[position] << s;
+ cnt += 8;
+ }
+
+ if (position >= end)
+ {
+ /*
+ * We've reached the end of the buffer. It is perfectly valid for us to need
+ * to fill the window with additional bits past the end of the buffer (and
+ * this happens in normal operation). These bits should all just be taken
+ * as zero. But we cannot increment bptr past 'end' (this is undefined
+ * behavior), so we start to increment dec->tell_offs. We also don't want
+ * to keep testing bptr against 'end', so we set cnt to OD_EC_LOTS_OF_BITS
+ * and adjust dec->tell_offs so that the total number of unconsumed bits in
+ * the window (dec->cnt - dec->tell_offs) does not change. This effectively
+ * puts lots of zero bits into the window, and means we won't try to refill
+ * it from the buffer for a very long time (at which point we'll put lots
+ * of zero bits into the window again).
+ */
+ cnt = LotsOfBits;
+ }
+
+ this.difference = dif;
+ this.count = cnt;
+ this.position = position;
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolWriter.cs b/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolWriter.cs
new file mode 100644
index 0000000000..5c2702ad3c
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolWriter.cs
@@ -0,0 +1,216 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Buffers;
+using SixLabors.ImageSharp.Memory;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Entropy;
+
+internal class Av1SymbolWriter : IDisposable
+{
+ private uint low;
+ private uint rng = 0x8000U;
+
+ // Count is initialized to -9 so that it crosses zero after we've accumulated one byte + one carry bit.
+ private int cnt = -9;
+ private readonly Configuration configuration;
+ private readonly AutoExpandingMemory memory;
+ private int position;
+
+ public Av1SymbolWriter(Configuration configuration, int initialSize)
+ {
+ this.configuration = configuration;
+ this.memory = new AutoExpandingMemory(configuration, (initialSize + 1) >> 1);
+ }
+
+ public void Dispose() => this.memory.Dispose();
+
+ public void WriteSymbol(bool symbol, Av1Distribution distribution)
+ => this.WriteSymbol(symbol ? 1 : 0, distribution);
+
+ public void WriteSymbol(int symbol, Av1Distribution distribution)
+ {
+ DebugGuard.MustBeGreaterThanOrEqualTo(symbol, 0, nameof(symbol));
+ DebugGuard.MustBeLessThan(symbol, distribution.NumberOfSymbols, nameof(symbol));
+ DebugGuard.IsTrue(distribution[distribution.NumberOfSymbols - 1] == 0, "Last entry in Probabilities table needs to be zero.");
+
+ this.EncodeIntegerQ15(symbol, distribution);
+ distribution.Update(symbol);
+ }
+
+ public void WriteLiteral(bool value) => this.WriteLiteral(value ? 1u : 0u, 1);
+
+ public void WriteLiteral(uint value, int bitCount)
+ {
+ const uint p = 0x4000U; // (0x7FFFFFU - (128 << 15) + 128) >> 8;
+ for (int bit = bitCount - 1; bit >= 0; bit--)
+ {
+ bool bitValue = ((value >> bit) & 0x1) > 0;
+ this.EncodeBoolQ15(bitValue, p);
+ }
+ }
+
+ public IMemoryOwner Exit()
+ {
+ // We output the minimum number of bits that ensures that the symbols encoded
+ // thus far will be decoded correctly regardless of the bits that follow.
+ uint l = this.low;
+ int c = this.cnt;
+ int pos = this.position;
+ int s = 10;
+ uint m = 0x3FFFU;
+ uint e = ((l + m) & ~m) | (m + 1);
+ s += c;
+ Span buffer = this.memory.GetSpan(this.position + ((s + 7) >> 3));
+ if (s > 0)
+ {
+ uint n = (1U << (c + 16)) - 1;
+ do
+ {
+ buffer[pos] = (ushort)(e >> (c + 16));
+ pos++;
+ e &= n;
+ s -= 8;
+ c -= 8;
+ n >>= 8;
+ }
+ while (s > 0);
+ }
+
+ c = Math.Max((s + 7) >> 3, 0);
+ IMemoryOwner output = this.configuration.MemoryAllocator.Allocate(pos + c);
+
+ // Perform carry propagation.
+ Span outputSlice = output.GetSpan()[(output.Length() - pos)..];
+ c = 0;
+ while (pos > 0)
+ {
+ pos--;
+ c = buffer[pos] + c;
+ outputSlice[pos] = (byte)c;
+ c >>= 8;
+ }
+
+ return output;
+ }
+
+ ///
+ /// Encode a single binary value.
+ ///
+ /// The value to encode.
+ /// The probability that the value is true, scaled by 32768.
+ private void EncodeBoolQ15(bool val, uint frequency)
+ {
+ uint l;
+ uint r;
+ uint v;
+ DebugGuard.MustBeGreaterThan(frequency, 0U, nameof(frequency));
+ DebugGuard.MustBeLessThanOrEqualTo(frequency, 32768U, nameof(frequency));
+ l = this.low;
+ r = this.rng;
+ DebugGuard.MustBeGreaterThanOrEqualTo(r, 32768U, nameof(r));
+ v = ((r >> 8) * (frequency >> Av1Distribution.ProbabilityShift)) >> (7 - Av1Distribution.ProbabilityShift);
+ v += Av1Distribution.ProbabilityMinimum;
+ if (val)
+ {
+ l += r - v;
+ r = v;
+ }
+ else
+ {
+ r -= v;
+ }
+
+ this.Normalize(l, r);
+ }
+
+ ///
+ /// Encodes a symbol given an inverse cumulative distribution function(CDF) table in Q15.
+ ///
+ /// The value to encode.
+ ///
+ /// CDF_PROB_TOP minus the CDF, such that symbol s falls in the range
+ /// [s > 0 ? (CDF_PROB_TOP - icdf[s - 1]) : 0, CDF_PROB_TOP - icdf[s]).
+ /// The values must be monotonically non - increasing, and icdf[nsyms - 1] must be 0.
+ ///
+ private void EncodeIntegerQ15(int symbol, Av1Distribution distribution)
+ => this.EncodeIntegerQ15(symbol > 0 ? distribution[symbol - 1] : Av1Distribution.ProbabilityTop, distribution[symbol], symbol, distribution.NumberOfSymbols);
+
+ private void EncodeIntegerQ15(uint lowFrequency, uint highFrequency, int symbol, int numberOfSymbols)
+ {
+ const int totalShift = 7 - Av1Distribution.ProbabilityShift - Av1Distribution.CdfShift;
+ uint l = this.low;
+ uint r = this.rng;
+ DebugGuard.MustBeLessThanOrEqualTo(32768U, r, nameof(r));
+ DebugGuard.MustBeLessThanOrEqualTo(highFrequency, lowFrequency, nameof(highFrequency));
+ DebugGuard.MustBeLessThanOrEqualTo(lowFrequency, 32768U, nameof(lowFrequency));
+ DebugGuard.MustBeGreaterThanOrEqualTo(totalShift, 0, nameof(totalShift));
+ int n = numberOfSymbols - 1;
+ if (lowFrequency < Av1Distribution.ProbabilityTop)
+ {
+ uint u;
+ uint v;
+ u = (uint)((((r >> 8) * (lowFrequency >> Av1Distribution.ProbabilityShift)) >> totalShift) +
+ (Av1Distribution.ProbabilityMinimum * (n - (symbol - 1))));
+ v = (uint)((((r >> 8) * (highFrequency >> Av1Distribution.ProbabilityShift)) >> totalShift) +
+ (Av1Distribution.ProbabilityMinimum * (n - symbol)));
+ l += r - u;
+ r = u - v;
+ }
+ else
+ {
+ r -= (uint)((((r >> 8) * (highFrequency >> Av1Distribution.ProbabilityShift)) >> totalShift) +
+ (Av1Distribution.ProbabilityMinimum * (n - symbol)));
+ }
+
+ this.Normalize(l, r);
+ }
+
+ ///
+ /// Takes updated low and range values, renormalizes them so that
+ /// lies between 32768 and 65536 (flushing bytes from low to the pre-carry buffer if necessary),
+ /// and stores them back in the encoder context.
+ ///
+ /// The new value of .
+ /// The new value of .
+ private void Normalize(uint low, uint rng)
+ {
+ int d;
+ int c;
+ int s;
+ c = this.cnt;
+ DebugGuard.MustBeLessThanOrEqualTo(rng, 65535U, nameof(rng));
+ d = 15 - Av1Math.MostSignificantBit(rng);
+ s = c + d;
+ /*TODO: Right now we flush every time we have at least one byte available.
+ Instead we should use an OdEcWindow and flush right before we're about to
+ shift bits off the end of the window.
+ For a 32-bit window this is about the same amount of work, but for a 64-bit
+ window it should be a fair win.*/
+ if (s >= 0)
+ {
+ uint m;
+ Span buffer = this.memory.GetSpan(this.position + 2);
+
+ c += 16;
+ m = (1U << c) - 1;
+ if (s >= 8)
+ {
+ buffer[this.position] = (ushort)(low >> c);
+ this.position++;
+ low &= m;
+ c -= 8;
+ m >>= 8;
+ }
+
+ buffer[this.position] = (ushort)(low >> c);
+ this.position++;
+ s = c + d - 24;
+ low &= m;
+ }
+
+ this.low = low << d;
+ this.rng = rng << d;
+ this.cnt = s;
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/IAv1TileReader.cs b/src/ImageSharp/Formats/Heif/Av1/IAv1TileReader.cs
new file mode 100644
index 0000000000..3bbef50bc7
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/IAv1TileReader.cs
@@ -0,0 +1,19 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1;
+
+///
+/// Interface for reading of image tiles.
+///
+internal interface IAv1TileReader
+{
+ ///
+ /// Read the information for a single tile.
+ ///
+ ///
+ /// The bytes of encoded data in the bitstream dedicated to this tile.
+ ///
+ /// The index of the tile that is to be read.
+ void ReadTile(Span tileData, int tileNum);
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/IAv1TileWriter.cs b/src/ImageSharp/Formats/Heif/Av1/IAv1TileWriter.cs
new file mode 100644
index 0000000000..1e2552b8b3
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/IAv1TileWriter.cs
@@ -0,0 +1,19 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1;
+
+///
+/// Interface for writing of image tiles.
+///
+internal interface IAv1TileWriter
+{
+ ///
+ /// Write the information for a single tile.
+ ///
+ /// The index of the tile that is to be read.
+ ///
+ /// The bytes of encoded data in the bitstream dedicated to this tile.
+ ///
+ Span WriteTile(int tileNum);
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/ModeDecision/Av1BlockGeometry.cs b/src/ImageSharp/Formats/Heif/Av1/ModeDecision/Av1BlockGeometry.cs
new file mode 100644
index 0000000000..af5acbd86c
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/ModeDecision/Av1BlockGeometry.cs
@@ -0,0 +1,111 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.ModeDecision;
+
+internal class Av1BlockGeometry
+{
+ private Av1BlockSize blockSize;
+ private Av1BlockSize blockSizeUv;
+
+ public Av1BlockGeometry()
+ {
+ this.RedunancyList = [];
+ this.TransformOrigin = new Point[Av1Constants.MaxVarTransform + 1][];
+ for (int i = 0; i < this.TransformOrigin.Length; i++)
+ {
+ this.TransformOrigin[i] = new Point[Av1Constants.MaxTransformBlockCount];
+ }
+ }
+
+ public Av1BlockSize BlockSize
+ {
+ get => this.blockSize;
+ internal set
+ {
+ this.blockSize = value;
+ this.BlockWidth = value.GetWidth();
+ this.BlockHeight = value.GetHeight();
+ }
+ }
+
+ public Av1BlockSize BlockSizeUv
+ {
+ get => this.blockSizeUv;
+ internal set
+ {
+ this.blockSizeUv = value;
+ this.BlockWidthUv = value.GetWidth();
+ this.BlockHeightUv = value.GetHeight();
+ }
+ }
+
+ ///
+ /// Gets or sets the Origin point from lop left of the superblock.
+ ///
+ public Point Origin { get; internal set; }
+
+ public bool HasUv { get; internal set; }
+
+ ///
+ /// Gets the blocks width.
+ ///
+ public int BlockWidth { get; private set; }
+
+ ///
+ /// Gets the blocks height.
+ ///
+ public int BlockHeight { get; private set; }
+
+ public int[] TransformBlockCount { get; } = new int[Av1Constants.MaxVarTransform + 1];
+
+ public Av1TransformSize[] TransformSize { get; } = new Av1TransformSize[Av1Constants.MaxVarTransform + 1];
+
+ public Av1TransformSize[] TransformSizeUv { get; } = new Av1TransformSize[Av1Constants.MaxVarTransform + 1];
+
+ public Point[][] TransformOrigin { get; private set; }
+
+ ///
+ /// Gets or sets the blocks index in the Mode Decision scan.
+ ///
+ public int ModeDecisionIndex { get; set; }
+
+ ///
+ /// Gets or sets the offset to the next nsq block (skip remaining d2 blocks).
+ ///
+ public int NextDepthOffset { get; set; }
+
+ ///
+ /// Gets or sets the offset to the next d1 sq block
+ ///
+ public int Depth1Offset { get; set; }
+
+ ///
+ /// Gets a value indicating whether this block is redundant to another.
+ ///
+ public bool IsRedundant => this.RedunancyList.Count > 0;
+
+ ///
+ /// Gets or sets the list where the block is redundant.
+ ///
+ public List RedunancyList { get; internal set; }
+
+ ///
+ /// Gets or sets the non square index within a partition 0..totns-1
+ ///
+ public int NonSquareIndex { get; internal set; }
+
+ public int TotalNonSuareCount { get; internal set; }
+
+ public int BlockWidthUv { get; private set; }
+
+ public int BlockHeightUv { get; private set; }
+
+ public int Depth { get; internal set; }
+
+ public int SequenceSize { get; internal set; }
+
+ public bool IsLastQuadrant { get; internal set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/ModeDecision/Av1BlockGeometryFactory.cs b/src/ImageSharp/Formats/Heif/Av1/ModeDecision/Av1BlockGeometryFactory.cs
new file mode 100644
index 0000000000..6563895bb3
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/ModeDecision/Av1BlockGeometryFactory.cs
@@ -0,0 +1,989 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.ModeDecision;
+
+internal class Av1BlockGeometryFactory
+{
+ private const int MaxBlocksAllocated = 4421;
+ private const int NotUsedValue = 0;
+ private static readonly int[][][] NonSkipQuarterOffMult =
+ [
+
+ // 9 means not used.
+ // | x | | y |
+ /*P=0*/ [[0, 9, 9, 9], [0, 9, 9, 9]],
+ /*P=1*/ [[0, 0, 9, 9], [0, 2, 9, 9]],
+ /*P=2*/ [[0, 2, 9, 9], [0, 0, 9, 9]],
+
+ /*P=7*/ [[0, 0, 0, 0], [0, 1, 2, 3]],
+ /*P=8*/ [[0, 1, 2, 3], [0, 0, 0, 0]],
+
+ /*P=3*/ [[0, 2, 0, 9], [0, 0, 2, 9]],
+ /*P=4*/ [[0, 0, 2, 9], [0, 2, 2, 9]],
+ /*P=5*/ [[0, 0, 2, 9], [0, 2, 0, 9]],
+ /*P=6*/ [[0, 2, 2, 9], [0, 0, 2, 9]]
+ ];
+
+ private static readonly uint[][][] NonSkipSizeMult =
+ [
+
+ // 9 means not used.
+ // | h | | v |
+ /*P=0*/ [[4, 9, 9, 9], [4, 9, 9, 9]],
+ /*P=1*/ [[4, 4, 9, 9], [2, 2, 9, 9]],
+ /*P=2*/ [[2, 2, 9, 9], [4, 4, 9, 9]],
+
+ /*P=7*/ [[4, 4, 4, 4], [1, 1, 1, 1]],
+ /*P=8*/ [[1, 1, 1, 1], [4, 4, 4, 4]],
+
+ /*P=3*/ [[2, 2, 4, 9], [2, 2, 2, 9]],
+ /*P=4*/ [[4, 2, 2, 9], [2, 2, 2, 9]],
+ /*P=5*/ [[2, 2, 2, 9], [2, 2, 4, 9]],
+ /*P=6*/ [[2, 2, 2, 9], [4, 2, 2, 9]]
+ ];
+
+ // gives the index of next quadrant child within a depth
+ private static readonly int[][] NonSkipDepthOffset =
+ [
+ [85, 21, 5, 1, NotUsedValue, NotUsedValue],
+ [105, 25, 5, 1, NotUsedValue, NotUsedValue],
+ [169, 41, 9, 1, NotUsedValue, NotUsedValue],
+ [425, 105, 25, 5, NotUsedValue, NotUsedValue],
+ [681, 169, 41, 9, 1, NotUsedValue],
+ [849, 209, 49, 9, 1, NotUsedValue],
+ [1101, 269, 61, 9, 1, NotUsedValue],
+ [4421, 1101, 269, 61, 9, 1],
+ [2377, 593, 145, 33, 5, NotUsedValue]
+ ];
+
+ // gives the next depth block(first qudrant child) from a given parent square
+ private static readonly int[][] Depth1DepthOffset =
+ [
+ [1, 1, 1, 1, 1, NotUsedValue],
+ [5, 5, 1, 1, 1, NotUsedValue],
+ [5, 5, 5, 1, 1, NotUsedValue],
+ [5, 5, 5, 5, 1, NotUsedValue],
+ [5, 5, 5, 5, 1, NotUsedValue],
+ [13, 13, 13, 5, 1, NotUsedValue],
+ [25, 25, 25, 5, 1, NotUsedValue],
+ [17, 25, 25, 25, 5, 1],
+ [5, 13, 13, 13, 5, NotUsedValue]
+ ];
+
+ private static Av1GeometryIndex geometryIndex;
+ private static int maxSuperblock;
+ private static int maxDepth;
+ private static int maxPart;
+
+ // private static int maxActiveBlockCount;
+ private readonly Av1BlockGeometry[] blockGeometryModeDecisionScan;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// SVT: md_scan_all_blks
+ public Av1BlockGeometryFactory(Av1GeometryIndex geom)
+ {
+ this.blockGeometryModeDecisionScan = new Av1BlockGeometry[MaxBlocksAllocated];
+ int max_block_count;
+ geometryIndex = geom;
+ byte min_nsq_bsize;
+ if (geom == Av1GeometryIndex.Geometry0)
+ {
+ maxSuperblock = 64;
+ maxDepth = 4;
+ maxPart = 1;
+ max_block_count = 85;
+ min_nsq_bsize = 16;
+ }
+ else if (geom == Av1GeometryIndex.Geometry1)
+ {
+ maxSuperblock = 64;
+ maxDepth = 4;
+ maxPart = 3;
+ max_block_count = 105;
+ min_nsq_bsize = 16;
+ }
+ else if (geom == Av1GeometryIndex.Geometry2)
+ {
+ maxSuperblock = 64;
+ maxDepth = 4;
+ maxPart = 3;
+ max_block_count = 169;
+ min_nsq_bsize = 8;
+ }
+ else if (geom == Av1GeometryIndex.Geometry3)
+ {
+ maxSuperblock = 64;
+ maxDepth = 4;
+ maxPart = 3;
+ max_block_count = 425;
+ min_nsq_bsize = 0;
+ }
+ else if (geom == Av1GeometryIndex.Geometry4)
+ {
+ maxSuperblock = 64;
+ maxDepth = 5;
+ maxPart = 3;
+ max_block_count = 681;
+ min_nsq_bsize = 0;
+ }
+ else if (geom == Av1GeometryIndex.Geometry5)
+ {
+ maxSuperblock = 64;
+ maxDepth = 5;
+ maxPart = 5;
+ max_block_count = 849;
+ min_nsq_bsize = 0;
+ }
+ else if (geom == Av1GeometryIndex.Geometry6)
+ {
+ maxSuperblock = 64;
+ maxDepth = 5;
+ maxPart = 9;
+ max_block_count = 1101;
+ min_nsq_bsize = 0;
+ }
+ else if (geom == Av1GeometryIndex.Geometry7)
+ {
+ maxSuperblock = 128;
+ maxDepth = 6;
+ maxPart = 9;
+ max_block_count = 4421;
+ min_nsq_bsize = 0;
+ }
+ else
+ {
+ maxSuperblock = 128;
+ maxDepth = 5;
+ maxPart = 5;
+ max_block_count = 2377;
+ min_nsq_bsize = 0;
+ }
+
+ // (0)compute total number of blocks using the information provided
+ // maxActiveBlockCount = CountTotalNumberOfActiveBlocks(min_nsq_bsize);
+
+ // if (maxActiveBlockCount != max_block_count)
+ // SVT_LOG(" \n\n Error %i blocks\n\n ", maxActiveBlockCount);
+ // (2) Construct md scan blk_geom_mds: use info from dps
+ int idx_mds = 0;
+ this.ScanAllBlocks(ref idx_mds, maxSuperblock, 0, 0, false, 0, min_nsq_bsize);
+ LogRedundancySimilarity(max_block_count);
+ }
+
+ ///
+ /// SVT: count_total_num_of_active_blks
+ ///
+ private static int CountTotalNumberOfActiveBlocks(int min_nsq_bsize)
+ {
+ int depth_scan_idx = 0;
+
+ for (int depthIterator = 0; depthIterator < maxDepth; depthIterator++)
+ {
+ int totalSquareCount = 1 << depthIterator;
+ int sequenceSize = depthIterator == 0 ? maxSuperblock
+ : depthIterator == 1 ? maxSuperblock / 2
+ : depthIterator == 2 ? maxSuperblock / 4
+ : depthIterator == 3 ? maxSuperblock / 8
+ : depthIterator == 4 ? maxSuperblock / 16 : maxSuperblock / 32;
+
+ int max_part_updated = sequenceSize == 128 ? Math.Min(maxPart, maxPart < 9 && maxPart > 3 ? 3 : 7)
+ : sequenceSize == 8 ? Math.Min(maxPart, 3)
+ : sequenceSize == 4 ? 1 : maxPart;
+ if (sequenceSize <= min_nsq_bsize)
+ {
+ max_part_updated = 1;
+ }
+
+ for (int squareIteratorY = 0; squareIteratorY < totalSquareCount; squareIteratorY++)
+ {
+ for (int squareIteratorX = 0; squareIteratorX < totalSquareCount; squareIteratorX++)
+ {
+ for (int partitionIterator = 0; partitionIterator < max_part_updated; partitionIterator++)
+ {
+ int tot_num_ns_per_part = GetNonSquareCountPerPart(partitionIterator, sequenceSize);
+ depth_scan_idx += tot_num_ns_per_part;
+ }
+ }
+ }
+ }
+
+ return depth_scan_idx;
+ }
+
+ ///
+ /// SVT: get_num_ns_per_part
+ ///
+ private static int GetNonSquareCountPerPart(int partitionIterator, int sequenceSize)
+ {
+ int tot_num_ns_per_part = partitionIterator < 1 ? 1 : partitionIterator < 3 ? 2 : partitionIterator < 5 && sequenceSize < 128 ? 4 : 3;
+ return tot_num_ns_per_part;
+ }
+
+ ///
+ /// SVT: log_redundancy_similarity
+ ///
+ private static void LogRedundancySimilarity(int max_block_count)
+ {
+ for (int blockIterator = 0; blockIterator < max_block_count; blockIterator++)
+ {
+ Av1BlockGeometry cur_geom = GetBlockGeometryByModeDecisionScanIndex(blockIterator);
+ cur_geom.RedunancyList.Clear();
+
+ for (int searchIterator = 0; searchIterator < max_block_count; searchIterator++)
+ {
+ Av1BlockGeometry search_geom = GetBlockGeometryByModeDecisionScanIndex(searchIterator);
+
+ if (cur_geom.BlockSize == search_geom.BlockSize &&
+ cur_geom.Origin == search_geom.Origin &&
+ searchIterator != blockIterator)
+ {
+ if (cur_geom.NonSquareIndex == 0 && search_geom.NonSquareIndex == 0 && cur_geom.RedunancyList.Count < 3)
+ {
+ cur_geom.RedunancyList.Add(search_geom.ModeDecisionIndex);
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// SVT: get_blk_geom_mds
+ ///
+ public static Av1BlockGeometry GetBlockGeometryByModeDecisionScanIndex(int modeDecisionScanIndex) => throw new NotImplementedException();
+
+ private void ScanAllBlocks(ref int index, int sequenceSize, int x, int y, bool isLastQuadrant, byte quadIterator, byte minNonSquareBlockSize)
+ {
+ // The input block is the parent square block of size sq_size located at pos (x,y)
+ Guard.MustBeLessThanOrEqualTo(quadIterator, (byte)3, nameof(quadIterator));
+
+ int halfsize = sequenceSize / 2;
+ int quartsize = sequenceSize / 4;
+
+ int max_part_updated = sequenceSize == 128 ? Math.Min(maxPart, maxPart is < 9 and > 3 ? 3 : 7)
+ : sequenceSize == 8 ? Math.Min(maxPart, 3)
+ : sequenceSize == 4 ? 1 : maxPart;
+ if (sequenceSize <= minNonSquareBlockSize)
+ {
+ max_part_updated = 1;
+ }
+
+ int sqi_mds = index;
+
+ for (int partitionIterator = 0; partitionIterator < max_part_updated; partitionIterator++)
+ {
+ int tot_num_ns_per_part = GetNonSquareCountPerPart(partitionIterator, sequenceSize);
+
+ for (int nonSquareIterator = 0; nonSquareIterator < tot_num_ns_per_part; nonSquareIterator++)
+ {
+ this.blockGeometryModeDecisionScan[index].Depth = sequenceSize == maxSuperblock / 1 ? 0
+ : sequenceSize == maxSuperblock / 2 ? 1
+ : sequenceSize == maxSuperblock / 4 ? 2
+ : sequenceSize == maxSuperblock / 8 ? 3
+ : sequenceSize == maxSuperblock / 16 ? 4 : 5;
+
+ this.blockGeometryModeDecisionScan[index].SequenceSize = sequenceSize;
+ this.blockGeometryModeDecisionScan[index].IsLastQuadrant = isLastQuadrant;
+
+ // part_it >= 3 for 128x128 blocks corresponds to HA/HB/VA/VB shapes since H4/V4 are not allowed
+ // for 128x128 blocks. Therefore, need to offset part_it by 2 to not index H4/V4 shapes.
+ int part_it_idx = partitionIterator >= 3 && sequenceSize == 128 ? partitionIterator + 2 : partitionIterator;
+ this.blockGeometryModeDecisionScan[index].Origin = new Point(
+ x + (quartsize * NonSkipQuarterOffMult[part_it_idx][0][nonSquareIterator]),
+ y + (quartsize * NonSkipQuarterOffMult[part_it_idx][1][nonSquareIterator]));
+
+ // These properties aren't used.
+ // this.blockGeometryModeDecisionScan[index].Shape = (Part)part_it_idx;
+ // this.blockGeometryModeDecisionScan[index].QuadIndex = quadIterator;
+ // this.blockGeometryModeDecisionScan[index].d1i = depth1Iterator++;
+ // this.blockGeometryModeDecisionScan[index].sqi_mds = sqi_mds;
+ // this.blockGeometryModeDecisionScan[index].svt_aom_geom_idx = svt_aom_geom_idx;
+ /*
+ this.blockGeometryModeDecisionScan[index].parent_depth_idx_mds = sqi_mds == 0
+ ? 0
+ : (sqi_mds + (3 - quad_it) * ns_depth_offset[svt_aom_geom_idx][this.blockGeometryModeDecisionScan[index].Depth]) -
+ parent_depth_offset[svt_aom_geom_idx][this.blockGeometryModeDecisionScan[index].Depth];*/
+ this.blockGeometryModeDecisionScan[index].Depth1Offset =
+ Depth1DepthOffset[(int)geometryIndex][this.blockGeometryModeDecisionScan[index].Depth];
+ this.blockGeometryModeDecisionScan[index].NextDepthOffset =
+ NonSkipDepthOffset[(int)geometryIndex][this.blockGeometryModeDecisionScan[index].Depth];
+ this.blockGeometryModeDecisionScan[index].TotalNonSuareCount = tot_num_ns_per_part;
+ this.blockGeometryModeDecisionScan[index].NonSquareIndex = nonSquareIterator;
+ uint blockWidth = (uint)quartsize * NonSkipSizeMult[part_it_idx][0][nonSquareIterator];
+ uint blockHeight = (uint)quartsize * NonSkipSizeMult[part_it_idx][1][nonSquareIterator];
+ this.blockGeometryModeDecisionScan[index].BlockSize =
+ Av1BlockSizeExtensions.FromWidthAndHeight(Av1Math.Log2_32(blockWidth) - 2u, Av1Math.Log2_32(blockHeight) - 2u);
+ this.blockGeometryModeDecisionScan[index].BlockSizeUv = this.blockGeometryModeDecisionScan[index].BlockSize.GetSubsampled(true, true);
+
+ // this.blockGeometryModeDecisionScan[index].BlockWidthUv = Math.Max(4, this.blockGeometryModeDecisionScan[index].BlockWidth >> 1);
+ // this.blockGeometryModeDecisionScan[index].BlockHeightUv = Math.Max(4, this.blockGeometryModeDecisionScan[index].BlockHeight >> 1);
+ this.blockGeometryModeDecisionScan[index].HasUv = true;
+
+ if (this.blockGeometryModeDecisionScan[index].BlockWidth == 4 && this.blockGeometryModeDecisionScan[index].BlockHeight == 4)
+ {
+ this.blockGeometryModeDecisionScan[index].HasUv = isLastQuadrant;
+ }
+ else if ((this.blockGeometryModeDecisionScan[index].BlockWidth >> 1) < this.blockGeometryModeDecisionScan[index].BlockWidthUv ||
+ (this.blockGeometryModeDecisionScan[index].BlockHeight >> 1) < this.blockGeometryModeDecisionScan[index].BlockHeightUv)
+ {
+ int num_blk_same_uv = 1;
+ if (this.blockGeometryModeDecisionScan[index].BlockWidth >> 1 < 4)
+ {
+ num_blk_same_uv *= 2;
+ }
+
+ if (this.blockGeometryModeDecisionScan[index].BlockHeight >> 1 < 4)
+ {
+ num_blk_same_uv *= 2;
+ }
+
+ // if (this.blockGeometryModeDecisionScan[index].nsi % 2 == 0)
+ // if (this.blockGeometryModeDecisionScan[index].nsi != (this.blockGeometryModeDecisionScan[index].totns-1) )
+ if (this.blockGeometryModeDecisionScan[index].NonSquareIndex != (num_blk_same_uv - 1) &&
+ this.blockGeometryModeDecisionScan[index].NonSquareIndex != ((2 * num_blk_same_uv) - 1))
+ {
+ this.blockGeometryModeDecisionScan[index].HasUv = false;
+ }
+ }
+
+ // tx_depth 1 geom settings
+ int tx_depth = 0;
+ this.blockGeometryModeDecisionScan[index].TransformBlockCount[tx_depth] = this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block128x128
+ ? 4
+ : this.blockGeometryModeDecisionScan[index].BlockSize is Av1BlockSize.Block128x64 or Av1BlockSize.Block64x128
+ ? 2
+ : 1;
+ for (int transformBlockIterator = 0; transformBlockIterator < this.blockGeometryModeDecisionScan[index].TransformBlockCount[tx_depth]; transformBlockIterator++)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] =
+ GetTransformSize(this.blockGeometryModeDecisionScan[index].BlockSize, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] =
+ GetTransformSize(this.blockGeometryModeDecisionScan[index].BlockSize, 1);
+ if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block128x128)
+ {
+ int offsetx = (transformBlockIterator is 0 or 2) ? 0 : 64;
+ int offsety = (transformBlockIterator is 0 or 1) ? 0 : 64;
+ Size offset = new(offsetx, offsety);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block128x64)
+ {
+ int offsetx = (transformBlockIterator == 0) ? 0 : 64;
+ int offsety = 0;
+ Size offset = new(offsetx, offsety);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block64x128)
+ {
+ int offsetx = 0;
+ int offsety = (transformBlockIterator == 0) ? 0 : 64;
+ Size offset = new(offsetx, offsety);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else
+ {
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin;
+ }
+
+ /*if (this.blockGeometryModeDecisionScan[index].bsize == BLOCK_16X8)
+ SVT_LOG("");
+ this.blockGeometryModeDecisionScan[index].tx_width[tx_depth] =
+ tx_size_wide[this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth]];
+ this.blockGeometryModeDecisionScan[index].tx_height[tx_depth] =
+ tx_size_high[this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth]];
+ this.blockGeometryModeDecisionScan[index].tx_width_uv[tx_depth] =
+ tx_size_wide[this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth]];
+ this.blockGeometryModeDecisionScan[index].tx_height_uv[tx_depth] =
+ tx_size_high[this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth]];*/
+ }
+
+ // tx_depth 1 geom settings
+ tx_depth = 1;
+ this.blockGeometryModeDecisionScan[index].TransformBlockCount[tx_depth] = this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block128x128
+ ? 4
+ : this.blockGeometryModeDecisionScan[index].BlockSize is Av1BlockSize.Block128x64 or Av1BlockSize.Block64x128
+ ? 2
+ : 1;
+
+ if (this.blockGeometryModeDecisionScan[index].BlockSize is Av1BlockSize.Block64x64 or
+ Av1BlockSize.Block32x32 or
+ Av1BlockSize.Block16x16 or
+ Av1BlockSize.Block8x8)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformBlockCount[tx_depth] = 4;
+ }
+
+ if (this.blockGeometryModeDecisionScan[index].BlockSize is Av1BlockSize.Block64x32 or
+ Av1BlockSize.Block32x64 or
+ Av1BlockSize.Block32x16 or
+ Av1BlockSize.Block16x32 or
+ Av1BlockSize.Block16x8 or
+ Av1BlockSize.Block8x16)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformBlockCount[tx_depth] = 2;
+ }
+
+ if (this.blockGeometryModeDecisionScan[index].BlockSize is Av1BlockSize.Block64x16 or
+ Av1BlockSize.Block16x64 or
+ Av1BlockSize.Block32x8 or
+ Av1BlockSize.Block8x32 or
+ Av1BlockSize.Block16x4 or
+ Av1BlockSize.Block4x16)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformBlockCount[tx_depth] = 2;
+ }
+
+ for (int transformBlockIterator = 0; transformBlockIterator < this.blockGeometryModeDecisionScan[index].TransformBlockCount[tx_depth]; transformBlockIterator++)
+ {
+ if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block64x64)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block32x32, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+ int[] offsetx = [0, 32, 0, 32];
+ int[] offsety = [0, 0, 32, 32];
+
+ // 0 1
+ // 2 3
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block64x32)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block32x32, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+ int[] offsetx = [0, 32];
+ int[] offsety = [0, 0];
+
+ // 0 1
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block32x64)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block32x32, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+ int[] offsetx = [0, 0];
+ int[] offsety = [0, 32];
+
+ // 0 1
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block32x32)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block16x16, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+ int[] offsetx = [0, 16, 0, 16];
+ int[] offsety = [0, 0, 16, 16];
+
+ // 0 1
+ // 2 3
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block32x16)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block16x16, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+ int[] offsetx = [0, 16];
+ int[] offsety = [0, 0];
+
+ // 0 1
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block16x32)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block16x16, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+ int[] offsetx = [0, 0];
+ int[] offsety = [0, 16];
+
+ // 0 1
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block16x16)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block8x8, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+ int[] offsetx = [0, 8, 0, 8];
+ int[] offsety = [0, 0, 8, 8];
+
+ // 0 1
+ // 2 3
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block16x8)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block8x8, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+ int[] offsetx = [0, 8];
+ int[] offsety = [0, 0];
+
+ // 0 1
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block8x16)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block8x8, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+ int[] offsetx = [0, 0];
+ int[] offsety = [0, 8];
+
+ // 0 1
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block8x8)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block4x4, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+ int[] offsetx = [0, 4, 0, 4];
+ int[] offsety = [0, 0, 4, 4];
+
+ // 0 1
+ // 2 3
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block64x16)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block32x16, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ int[] offsetx = [0, 32];
+ int[] offsety = [0, 0];
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block16x64)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block16x32, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ int[] offsetx = [0, 0];
+ int[] offsety = [0, 32];
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block32x8)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block16x8, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ int[] offsetx = [0, 16];
+ int[] offsety = [0, 0];
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block8x32)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block8x16, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ // 0 1 2 3
+ int[] offsetx = [0, 0];
+ int[] offsety = [0, 16];
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block16x4)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block8x4, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ int[] offsetx = [0, 8];
+ int[] offsety = [0, 0];
+
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block4x16)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block4x8, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ int[] offsetx = [0, 0];
+ int[] offsety = [0, 8];
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else
+ {
+ if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block128x128)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(
+ this.blockGeometryModeDecisionScan[index].BlockSize, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] =
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ int offsetx = (transformBlockIterator is 0 or 2) ? 0 : 64;
+ int offsety = (transformBlockIterator is 0 or 1) ? 0 : 64;
+ Size offset = new(offsetx, offsety);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block128x64)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(
+ this.blockGeometryModeDecisionScan[index].BlockSize, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] =
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ int offsetx = (transformBlockIterator is 0) ? 0 : 64;
+ int offsety = 0;
+ Size offset = new(offsetx, offsety);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block64x128)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(
+ this.blockGeometryModeDecisionScan[index].BlockSize, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] =
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+ int offsetx = 0;
+ int offsety = (transformBlockIterator is 0) ? 0 : 64;
+ Size offset = new(offsetx, offsety);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(
+ this.blockGeometryModeDecisionScan[index].BlockSize, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] =
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin;
+ }
+ }
+
+ /*this.blockGeometryModeDecisionScan[index].tx_width[tx_depth] =
+ tx_size_wide[this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth]];
+ this.blockGeometryModeDecisionScan[index].tx_height[tx_depth] =
+ tx_size_high[this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth]];
+ this.blockGeometryModeDecisionScan[index].tx_width_uv[tx_depth] = this.blockGeometryModeDecisionScan[index].tx_width_uv[0];
+ this.blockGeometryModeDecisionScan[index].tx_height_uv[tx_depth] = this.blockGeometryModeDecisionScan[index].tx_height_uv[0];*/
+ }
+
+ // tx_depth 2 geom settings
+ tx_depth = 2;
+
+ this.blockGeometryModeDecisionScan[index].TransformBlockCount[tx_depth] = this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block128x128
+ ? 4
+ : this.blockGeometryModeDecisionScan[index].BlockSize is Av1BlockSize.Block128x64 or
+ Av1BlockSize.Block64x128
+ ? 2
+ : 1;
+
+ if (this.blockGeometryModeDecisionScan[index].BlockSize is Av1BlockSize.Block64x64 or
+ Av1BlockSize.Block32x32 or
+ Av1BlockSize.Block16x16)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformBlockCount[tx_depth] = 16;
+ }
+
+ if (this.blockGeometryModeDecisionScan[index].BlockSize is Av1BlockSize.Block64x32 or
+ Av1BlockSize.Block32x64 or
+ Av1BlockSize.Block32x16 or
+ Av1BlockSize.Block16x32 or
+ Av1BlockSize.Block16x8 or
+ Av1BlockSize.Block8x16)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformBlockCount[tx_depth] = 8;
+ }
+
+ if (this.blockGeometryModeDecisionScan[index].BlockSize is Av1BlockSize.Block64x16 or
+ Av1BlockSize.Block16x64 or
+ Av1BlockSize.Block32x8 or
+ Av1BlockSize.Block8x32 or
+ Av1BlockSize.Block16x4 or
+ Av1BlockSize.Block4x16)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformBlockCount[tx_depth] = 4;
+ }
+
+ for (int transformBlockIterator = 0; transformBlockIterator < this.blockGeometryModeDecisionScan[index].TransformBlockCount[tx_depth]; transformBlockIterator++)
+ {
+ if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block64x64)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block16x16, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ int[] offsetx_intra = [0, 16, 32, 48, 0, 16, 32, 48, 0, 16, 32, 48, 0, 16, 32, 48];
+ int[] offsety_intra = [0, 0, 0, 0, 16, 16, 16, 16, 32, 32, 32, 32, 48, 48, 48, 48];
+ Size offset = new(offsetx_intra[transformBlockIterator], offsety_intra[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block64x32)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block16x16, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ int[] offsetx_intra = [0, 16, 32, 48, 0, 16, 32, 48];
+ int[] offsety_intra = [0, 0, 0, 0, 16, 16, 16, 16];
+ Size offset = new(offsetx_intra[transformBlockIterator], offsety_intra[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block32x64)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block16x16, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ int[] offsetx_intra = [0, 16, 0, 16, 0, 16, 0, 16];
+ int[] offsety_intra = [0, 0, 16, 16, 32, 32, 48, 48];
+
+ Size offset = new(offsetx_intra[transformBlockIterator], offsety_intra[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block32x32)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block8x8, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ int[] offsetx_intra = [0, 8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24];
+ int[] offsety_intra = [0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 16, 24, 24, 24, 24];
+
+ Size offset = new(offsetx_intra[transformBlockIterator], offsety_intra[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block32x16)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block8x8, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ int[] offsetx_intra = [0, 8, 16, 24, 0, 8, 16, 24];
+ int[] offsety_intra = [0, 0, 0, 0, 8, 8, 8, 8];
+
+ Size offset = new(offsetx_intra[transformBlockIterator], offsety_intra[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block16x32)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block8x8, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ int[] offsetx_intra = [0, 8, 0, 8, 0, 8, 0, 8];
+ int[] offsety_intra = [0, 0, 8, 8, 16, 16, 24, 24];
+ Size offset = new(offsetx_intra[transformBlockIterator], offsety_intra[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block16x8)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block4x4, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ int[] offsetx_intra = [0, 4, 8, 12, 0, 4, 8, 12];
+ int[] offsety_intra = [0, 0, 0, 0, 4, 4, 4, 4];
+ Size offset = new(offsetx_intra[transformBlockIterator], offsety_intra[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block8x16)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block4x4, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ int[] offsetx_intra = [0, 4, 0, 4, 0, 4, 0, 4];
+ int[] offsety_intra = [0, 0, 4, 4, 8, 8, 12, 12];
+ Size offset = new(offsetx_intra[transformBlockIterator], offsety_intra[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block16x16)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block4x4, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ int[] offsetx_intra = [0, 4, 8, 12, 0, 4, 8, 12, 0, 4, 8, 12, 0, 4, 8, 12];
+ int[] offsety_intra = [0, 0, 0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, 12, 12, 12];
+ Size offset = new(offsetx_intra[transformBlockIterator], offsety_intra[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block64x16)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block16x16, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ // 0 1 2 3
+ int[] offsetx = [0, 16, 32, 48];
+ int[] offsety = [0, 0, 0, 0];
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block16x64)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block16x16, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ // 0 1 2 3
+ int[] offsetx = [0, 0, 0, 0];
+ int[] offsety = [0, 16, 32, 48];
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block32x8)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block8x8, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ // 0 1 2 3
+ int[] offsetx = [0, 8, 16, 24];
+ int[] offsety = [0, 0, 0, 0];
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block8x32)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block8x8, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ // 0 1 2 3
+ int[] offsetx = [0, 0, 0, 0];
+ int[] offsety = [0, 8, 16, 24];
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block16x4)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block4x4, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ // 0 1 2 3
+ int[] offsetx = [0, 4, 8, 12];
+ int[] offsety = [0, 0, 0, 0];
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block4x16)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(Av1BlockSize.Block4x4, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] = this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+
+ // 0 1 2 3
+ int[] offsetx = [0, 0, 0, 0];
+ int[] offsety = [0, 4, 8, 12];
+ Size offset = new(offsetx[transformBlockIterator], offsety[transformBlockIterator]);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else
+ {
+ if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block128x128)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(
+ this.blockGeometryModeDecisionScan[index].BlockSize, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] =
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+ int offsetx = (transformBlockIterator is 0 or 2) ? 0 : 64;
+ int offsety = (transformBlockIterator is 0 or 1) ? 0 : 64;
+ Size offset = new(offsetx, offsety);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block128x64)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(
+ this.blockGeometryModeDecisionScan[index].BlockSize, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] =
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+ int offsetx = (transformBlockIterator is 0) ? 0 : 64;
+ int offsety = 0;
+ Size offset = new(offsetx, offsety);
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin + offset;
+ }
+ else if (this.blockGeometryModeDecisionScan[index].BlockSize == Av1BlockSize.Block64x128)
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(
+ this.blockGeometryModeDecisionScan[index].BlockSize, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] =
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+ int offsetx = 0;
+ int offsety = (transformBlockIterator is 0) ? 0 : 64;
+ Size offset = new(offsetx, offsety);
+ }
+ else
+ {
+ this.blockGeometryModeDecisionScan[index].TransformSize[tx_depth] = GetTransformSize(
+ this.blockGeometryModeDecisionScan[index].BlockSize, 0);
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[tx_depth] =
+ this.blockGeometryModeDecisionScan[index].TransformSizeUv[0];
+ this.blockGeometryModeDecisionScan[index].TransformOrigin[tx_depth][transformBlockIterator] =
+ this.blockGeometryModeDecisionScan[index].Origin;
+ }
+ }
+
+ /*this.blockGeometryModeDecisionScan[index].tx_width[tx_depth] =
+ tx_size_wide[this.blockGeometryModeDecisionScan[index].txsize[tx_depth]];
+ this.blockGeometryModeDecisionScan[index].tx_height[tx_depth] =
+ tx_size_high[this.blockGeometryModeDecisionScan[index].txsize[tx_depth]];
+ this.blockGeometryModeDecisionScan[index].tx_width_uv[tx_depth] = this.blockGeometryModeDecisionScan[index].tx_width_uv[0];
+ this.blockGeometryModeDecisionScan[index].tx_height_uv[tx_depth] = this.blockGeometryModeDecisionScan[index].tx_height_uv[0];*/
+ }
+
+ this.blockGeometryModeDecisionScan[index].ModeDecisionIndex = index;
+ index += 1;
+ }
+ }
+ }
+
+ ///
+ /// SVT: av1_get_tx_size
+ ///
+ private static Av1TransformSize GetTransformSize(Av1BlockSize blockSize, int plane)
+ {
+ // const MbModeInfo* mbmi = xd->mi[0];
+ // if (xd->lossless[mbmi->segment_id]) return TX_4X4;
+ if (plane == 0)
+ {
+ return blockSize.GetMaximumTransformSize();
+ }
+
+ // const MacroblockdPlane *pd = &xd->plane[plane];
+ bool subsampling_x = plane > 0;
+ bool subsampling_y = plane > 0;
+ return blockSize.GetMaxUvTransformSize(subsampling_x, subsampling_y);
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/ModeDecision/Av1GeometryIndex.cs b/src/ImageSharp/Formats/Heif/Av1/ModeDecision/Av1GeometryIndex.cs
new file mode 100644
index 0000000000..5392c3f20d
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/ModeDecision/Av1GeometryIndex.cs
@@ -0,0 +1,16 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.ModeDecision;
+
+internal enum Av1GeometryIndex
+{
+ Geometry0,
+ Geometry1,
+ Geometry2,
+ Geometry3,
+ Geometry4,
+ Geometry5,
+ Geometry6,
+ Geometry7,
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuChromoSamplePosition.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuChromoSamplePosition.cs
new file mode 100644
index 0000000000..bd71ea4334
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuChromoSamplePosition.cs
@@ -0,0 +1,22 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal enum ObuChromoSamplePosition : byte
+{
+ ///
+ /// Unknown.
+ ///
+ Unknown = 0,
+
+ ///
+ /// Horizontally co-located with luma(0, 0) sample, between two vertical samples.
+ ///
+ Vertical = 1,
+
+ ///
+ /// Co-located with luma(0, 0) sample
+ ///
+ Colocated = 2,
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuColorConfig.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuColorConfig.cs
new file mode 100644
index 0000000000..24e7237a29
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuColorConfig.cs
@@ -0,0 +1,67 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuColorConfig
+{
+ private bool isMonochrome;
+
+ public bool IsColorDescriptionPresent { get; set; }
+
+ ///
+ /// Gets the number of color channels in this image. Can have the value 1 or 3.
+ ///
+ public int PlaneCount { get; private set; }
+
+ ///
+ /// Gets or sets a value indicating whether the image has a single greyscale plane, will have
+ /// color planes otherwise.
+ ///
+ public bool IsMonochrome
+ {
+ get => this.isMonochrome;
+ set
+ {
+ this.PlaneCount = value ? 1 : Av1Constants.MaxPlanes;
+ this.isMonochrome = value;
+ }
+ }
+
+ public ObuColorPrimaries ColorPrimaries { get; set; }
+
+ public ObuTransferCharacteristics TransferCharacteristics { get; set; }
+
+ public ObuMatrixCoefficients MatrixCoefficients { get; set; }
+
+ public bool ColorRange { get; set; }
+
+ public bool SubSamplingX { get; set; }
+
+ public bool SubSamplingY { get; set; }
+
+ public bool HasSeparateUvDelta { get; set; }
+
+ public ObuChromoSamplePosition ChromaSamplePosition { get; set; }
+
+ public Av1BitDepth BitDepth { get; set; }
+
+ public Av1ColorFormat GetColorFormat()
+ {
+ Av1ColorFormat format = Av1ColorFormat.Yuv400;
+ if (this.SubSamplingX && this.SubSamplingY)
+ {
+ format = Av1ColorFormat.Yuv420;
+ }
+ else if (this.SubSamplingX & !this.SubSamplingY)
+ {
+ format = Av1ColorFormat.Yuv422;
+ }
+ else if (!this.SubSamplingX && !this.SubSamplingY)
+ {
+ format = Av1ColorFormat.Yuv444;
+ }
+
+ return format;
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuColorPrimaries.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuColorPrimaries.cs
new file mode 100644
index 0000000000..3136bba383
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuColorPrimaries.cs
@@ -0,0 +1,21 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal enum ObuColorPrimaries
+{
+ None = 0,
+ Bt709 = 1,
+ Unspecified = 2,
+ Bt470M = 4,
+ Bt470BG = 5,
+ Bt601 = 6,
+ Smpte240 = 7,
+ GenericFilm = 8,
+ Bt2020 = 9,
+ Xyz = 10,
+ Smpte431 = 11,
+ Smpte432 = 12,
+ Ebu3213 = 22,
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuConstraintDirectionalEnhancementFilterParameters.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuConstraintDirectionalEnhancementFilterParameters.cs
new file mode 100644
index 0000000000..f952fae216
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuConstraintDirectionalEnhancementFilterParameters.cs
@@ -0,0 +1,15 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuConstraintDirectionalEnhancementFilterParameters
+{
+ public int BitCount { get; internal set; }
+
+ public int Damping { get; internal set; }
+
+ public int[] YStrength { get; set; } = new int[16];
+
+ public int[] UvStrength { get; set; } = new int[16];
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuDecoderModelInfo.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuDecoderModelInfo.cs
new file mode 100644
index 0000000000..bc7f96d9ef
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuDecoderModelInfo.cs
@@ -0,0 +1,29 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1;
+
+internal class ObuDecoderModelInfo
+{
+ ///
+ /// Gets or sets BufferDelayLength. Specifies the length of the decoder_buffer_delay and the encoder_buffer_delay
+ /// syntax elements, in bits.
+ ///
+ internal uint BufferDelayLength { get; set; }
+
+ ///
+ /// Gets or sets NumUnitsInDecodingTick. This is the number of time units of a decoding clock operating at the frequency time_scale Hz
+ /// that corresponds to one increment of a clock tick counter.
+ ///
+ internal uint NumUnitsInDecodingTick { get; set; }
+
+ ///
+ /// Gets or sets BufferRemovalTimeLength. Specifies the length of the buffer_removal_time syntax element, in bits.
+ ///
+ internal uint BufferRemovalTimeLength { get; set; }
+
+ ///
+ /// Gets or sets the FramePresentationTimeLength. Specifies the length of the frame_presentation_time syntax element, in bits.
+ ///
+ internal uint FramePresentationTimeLength { get; set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuDeltaParameters.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuDeltaParameters.cs
new file mode 100644
index 0000000000..c92485eaf1
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuDeltaParameters.cs
@@ -0,0 +1,13 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuDeltaParameters
+{
+ public bool IsPresent { get; internal set; }
+
+ public int Resolution { get; internal set; }
+
+ public bool IsMulti { get; internal set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuFilmGrainParameters.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuFilmGrainParameters.cs
new file mode 100644
index 0000000000..42a3b6578d
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuFilmGrainParameters.cs
@@ -0,0 +1,172 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuFilmGrainParameters
+{
+ ///
+ /// Gets or sets a value indicating whether film grain should be added to this frame. A value equal to false specifies that film
+ /// grain should not be added.
+ ///
+ public bool ApplyGrain { get; set; }
+
+ ///
+ /// Gets or sets GrainSeed. This value specifies the starting value for the pseudo-random numbers used during film grain synthesis.
+ ///
+ public uint GrainSeed { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether a new set of parameters should be sent. A value equal to false means that the
+ /// previous set of parameters should be used.
+ ///
+ public bool UpdateGrain { get; set; }
+
+ ///
+ /// Gets or sets FilmGrainParamsRefIdx. Indicates which reference frame contains the film grain parameters to be used for this frame.
+ /// It is a requirement of bitstream conformance that FilmGrainParamsRefIdx is equal to ref_frame_idx[ j ] for some value
+ /// of j in the range 0 to REFS_PER_FRAME - 1.
+ ///
+ public uint FilmGrainParamsRefidx { get; set; }
+
+ ///
+ /// Gets or sets NumYPoints. Specifies the number of points for the piece-wise linear scaling function of the luma component.
+ /// It is a requirement of bitstream conformance that NumYPoints is less than or equal to 14.
+ ///
+ public uint NumYPoints { get; set; }
+
+ ///
+ /// Gets or sets PointYValue. Represents the x (luma value) coordinate for the i-th point of the piecewise linear scaling function for
+ /// luma component.The values are signaled on the scale of 0..255. (In case of 10 bit video, these values correspond to
+ /// luma values divided by 4. In case of 12 bit video, these values correspond to luma values divided by 16.)
+ ///
+ /// If i is greater than 0, it is a requirement of bitstream conformance that point_y_value[ i ] is greater than point_y_value[ i - 1] (this ensures the x coordinates are specified in increasing order).
+ ///
+ public uint[]? PointYValue { get; set; }
+
+ ///
+ /// Gets or sets PointYScaling. Represents the scaling (output) value for the i-th point of the piecewise linear scaling function for luma component.
+ ///
+ public uint[]? PointYScaling { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the chroma scaling is inferred from the luma scaling.
+ ///
+ public bool ChromaScalingFromLuma { get; set; }
+
+ ///
+ /// Gets or sets NumCbPoints. Specifies the number of points for the piece-wise linear scaling function of the cb component.
+ /// It is a requirement of bitstream conformance that NumCbPoints is less than or equal to 10.
+ ///
+ public uint NumCbPoints { get; set; }
+
+ ///
+ /// Gets or sets NumCrPoints. Specifies represents the number of points for the piece-wise linear scaling function of the cr component.
+ /// It is a requirement of bitstream conformance that NumCrPoints is less than or equal to 10.
+ ///
+ public uint NumCrPoints { get; set; }
+
+ ///
+ /// Gets or sets PointCbValue. Represents the x coordinate for the i-th point of the piece-wise linear scaling function for cb
+ /// component.The values are signaled on the scale of 0..255.
+ /// If i is greater than 0, it is a requirement of bitstream conformance that point_cb_value[ i ] is greater than point_cb_value[ i - 1 ].
+ ///
+ public uint[]? PointCbValue { get; set; }
+
+ ///
+ /// Gets or sets PointCbScaling. Represents the scaling (output) value for the i-th point of the piecewise linear scaling function for cb component.
+ ///
+ public uint[]? PointCbScaling { get; set; }
+
+ ///
+ /// Gets or sets PointCrValue. Represents the x coordinate for the i-th point of the piece-wise linear scaling function for cr component.
+ /// The values are signaled on the scale of 0..255.
+ /// If i is greater than 0, it is a requirement of bitstream conformance that point_cr_value[ i ] is greater than point_cr_value[ i - 1 ].
+ ///
+ public uint[]? PointCrValue { get; set; }
+
+ ///
+ /// Gets or sets PointCrScaling. Represents the scaling (output) value for the i-th point of the piecewise linear scaling function for cr component.
+ ///
+ public uint[]? PointCrScaling { get; set; }
+
+ ///
+ /// Gets or sets GrainScalingMinus8. represents the shift – 8 applied to the values of the chroma component. The
+ /// grain_scaling_minus_8 can take values of 0..3 and determines the range and quantization step of the standard deviation of film grain.
+ ///
+ public uint GrainScalingMinus8 { get; set; }
+
+ ///
+ /// Gets or sets ArCoeffLag. Specifies the number of auto-regressive coefficients for luma and chroma.
+ ///
+ public uint ArCoeffLag { get; set; }
+
+ ///
+ /// Gets or sets ArCoeffsYPlus128. Specifies auto-regressive coefficients used for the Y plane.
+ ///
+ public uint[]? ArCoeffsYPlus128 { get; set; }
+
+ ///
+ /// Gets or sets ArCoeffsCbPlus128. Specifies auto-regressive coefficients used for the U plane.
+ ///
+ public uint[]? ArCoeffsCbPlus128 { get; set; }
+
+ ///
+ /// Gets or sets ArCoeffsCrPlus128. Specifies auto-regressive coefficients used for the V plane.
+ ///
+ public uint[]? ArCoeffsCrPlus128 { get; set; }
+
+ ///
+ /// Gets or sets ArCoeffShiftMinus6. Specifies the range of the auto-regressive coefficients. Values of 0, 1, 2, and 3 correspond to the
+ /// ranges for auto-regressive coefficients of[-2, 2), [-1, 1), [-0.5, 0.5) and [-0.25, 0.25) respectively.
+ ///
+ public uint ArCoeffShiftMinus6 { get; set; }
+
+ ///
+ /// Gets or sets GrainScaleShift. Specifies how much the Gaussian random numbers should be scaled down during the grain synthesis process.
+ ///
+ public uint GrainScaleShift { get; set; }
+
+ ///
+ /// Gets or sets CbMult. Represents a multiplier for the cb component used in derivation of the input index to the cb component scaling function.
+ ///
+ public uint CbMult { get; set; }
+
+ ///
+ /// Gets or sets CbLumaMult. Represents a multiplier for the average luma component used in derivation of the input index to the cb component scaling function.
+ ///
+ public uint CbLumaMult { get; set; }
+
+ ///
+ /// Gets or sets CbOffset. Represents an offset used in derivation of the input index to the cb component scaling function.
+ ///
+ public uint CbOffset { get; set; }
+
+ ///
+ /// Gets or sets CrMult. Represents a multiplier for the cr component used in derivation of the input index to the cr component scaling function.
+ ///
+ public uint CrMult { get; set; }
+
+ ///
+ /// Gets or sets CrLumaMult. Represents a multiplier for the average luma component used in derivation of the input index to the cr component scaling function.
+ ///
+ public uint CrLumaMult { get; set; }
+
+ ///
+ /// Gets or sets CrOffset. Represents an offset used in derivation of the input index to the cr component scaling function.
+ ///
+ public uint CrOffset { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the overlap between film grain blocks shall be applied. OverlapFlag equal to false
+ /// indicates that the overlap between film grain blocks shall not be applied.
+ ///
+ public bool OverlapFlag { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether clipping to the restricted (studio) range shall be applied to the sample
+ /// values after adding the film grain(see the semantics for color_range for an explanation of studio swing).
+ /// ClipToRestrictedRange equal to false indicates that clipping to the full range shall be applied to the sample values after adding the film grain.
+ ///
+ public bool ClipToRestrictedRange { get; set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuFrameHeader.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuFrameHeader.cs
new file mode 100644
index 0000000000..adc759267f
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuFrameHeader.cs
@@ -0,0 +1,98 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuFrameHeader
+{
+ public bool ForceIntegerMotionVector { get; set; }
+
+ public bool AllowIntraBlockCopy { get; set; }
+
+ public bool UseReferenceFrameMotionVectors { get; set; }
+
+ public bool AllowHighPrecisionMotionVector { get; set; }
+
+ public ObuTileGroupHeader TilesInfo { get; set; } = new ObuTileGroupHeader();
+
+ public bool CodedLossless { get; set; }
+
+ public bool[] LosslessArray { get; set; } = new bool[Av1Constants.MaxSegmentCount];
+
+ public ObuQuantizationParameters QuantizationParameters { get; set; } = new ObuQuantizationParameters();
+
+ public ObuSegmentationParameters SegmentationParameters { get; set; } = new ObuSegmentationParameters();
+
+ public bool AllLossless { get; set; }
+
+ public bool AllowWarpedMotion { get; set; }
+
+ public ObuReferenceMode ReferenceMode { get; set; }
+
+ public ObuFilmGrainParameters FilmGrainParameters { get; set; } = new ObuFilmGrainParameters();
+
+ public bool UseReducedTransformSet { get; set; }
+
+ public ObuLoopFilterParameters LoopFilterParameters { get; set; } = new ObuLoopFilterParameters();
+
+ public ObuLoopRestorationParameters LoopRestorationParameters { get; set; } = new ObuLoopRestorationParameters();
+
+ public ObuConstraintDirectionalEnhancementFilterParameters CdefParameters { get; set; } = new ObuConstraintDirectionalEnhancementFilterParameters();
+
+ public int ModeInfoStride { get; set; }
+
+ public bool DisableFrameEndUpdateCdf { get; set; }
+
+ public ObuSkipModeParameters SkipModeParameters { get; set; } = new ObuSkipModeParameters();
+
+ public Av1TransformMode TransformMode { get; set; }
+
+ public ObuDeltaParameters DeltaLoopFilterParameters { get; set; } = new ObuDeltaParameters();
+
+ public ObuDeltaParameters DeltaQParameters { get; set; } = new ObuDeltaParameters();
+
+ public bool IsIntra => this.FrameType is ObuFrameType.IntraOnlyFrame or ObuFrameType.KeyFrame;
+
+ internal ObuFrameSize FrameSize { get; set; } = new ObuFrameSize();
+
+ internal int ModeInfoColumnCount { get; set; }
+
+ internal int ModeInfoRowCount { get; set; }
+
+ internal bool ShowExistingFrame { get; set; }
+
+ internal ObuFrameType FrameType { get; set; }
+
+ internal bool[] ReferenceValid { get; set; } = new bool[Av1Constants.ReferenceFrameCount];
+
+ internal bool[] ReferenceOrderHint { get; set; } = new bool[Av1Constants.ReferenceFrameCount];
+
+ internal bool ShowFrame { get; set; }
+
+ internal bool ShowableFrame { get; set; }
+
+ internal uint FrameToShowMapIdx { get; set; }
+
+ internal uint DisplayFrameId { get; set; }
+
+ internal bool ErrorResilientMode { get; set; }
+
+ internal bool AllowScreenContentTools { get; set; }
+
+ internal bool DisableCdfUpdate { get; set; }
+
+ internal uint CurrentFrameId { get; set; }
+
+ internal uint[] ReferenceFrameIndex { get; set; } = new uint[Av1Constants.ReferenceFrameCount];
+
+ internal uint OrderHint { get; set; }
+
+ internal uint PrimaryReferenceFrame { get; set; } = Av1Constants.PrimaryReferenceFrameNone;
+
+ internal uint RefreshFrameFlags { get; set; }
+
+ // 5.9.31. Temporal point info syntax
+ internal uint FramePresentationTime { get; set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuFrameSize.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuFrameSize.cs
new file mode 100644
index 0000000000..7075b50b82
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuFrameSize.cs
@@ -0,0 +1,19 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuFrameSize
+{
+ internal int FrameWidth { get; set; }
+
+ internal int FrameHeight { get; set; }
+
+ internal int SuperResolutionDenominator { get; set; }
+
+ internal int SuperResolutionUpscaledWidth { get; set; }
+
+ internal int RenderWidth { get; set; }
+
+ internal int RenderHeight { get; set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuFrameType.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuFrameType.cs
new file mode 100644
index 0000000000..eb2414edc7
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuFrameType.cs
@@ -0,0 +1,12 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal enum ObuFrameType
+{
+ KeyFrame = 0,
+ InterFrame = 1,
+ IntraOnlyFrame = 2,
+ SwitchFrame = 3,
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuHeader.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuHeader.cs
new file mode 100644
index 0000000000..f55d3eb501
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuHeader.cs
@@ -0,0 +1,21 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuHeader
+{
+ public int Size { get; set; }
+
+ public ObuType Type { get; set; }
+
+ public bool HasSize { get; set; }
+
+ public bool HasExtension { get; set; }
+
+ public int TemporalId { get; set; }
+
+ public int SpatialId { get; set; }
+
+ public int PayloadSize { get; set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuLoopFilterParameters.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuLoopFilterParameters.cs
new file mode 100644
index 0000000000..ad32d0c01d
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuLoopFilterParameters.cs
@@ -0,0 +1,29 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuLoopFilterParameters
+{
+ public ObuLoopFilterParameters()
+ {
+ this.ReferenceDeltas = [1, 0, 0, 0, 0, -1, -1, -1];
+ this.ModeDeltas = [0, 0];
+ }
+
+ public int[] FilterLevel { get; internal set; } = new int[2];
+
+ public int FilterLevelU { get; internal set; }
+
+ public int FilterLevelV { get; internal set; }
+
+ public int SharpnessLevel { get; internal set; }
+
+ public bool ReferenceDeltaModeEnabled { get; internal set; }
+
+ public bool ReferenceDeltaModeUpdate { get; internal set; }
+
+ public int[] ReferenceDeltas { get; }
+
+ public int[] ModeDeltas { get; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuLoopRestorationItem.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuLoopRestorationItem.cs
new file mode 100644
index 0000000000..ade31a6606
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuLoopRestorationItem.cs
@@ -0,0 +1,11 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuLoopRestorationItem
+{
+ internal int Size { get; set; }
+
+ internal ObuRestorationType Type { get; set; } = ObuRestorationType.None;
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuLoopRestorationParameters.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuLoopRestorationParameters.cs
new file mode 100644
index 0000000000..18db716813
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuLoopRestorationParameters.cs
@@ -0,0 +1,25 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuLoopRestorationParameters
+{
+ internal ObuLoopRestorationParameters()
+ {
+ this.Items = new ObuLoopRestorationItem[3];
+ this.Items[0] = new();
+ this.Items[1] = new();
+ this.Items[2] = new();
+ }
+
+ internal bool UsesLoopRestoration { get; set; }
+
+ internal bool UsesChromaLoopRestoration { get; set; }
+
+ internal ObuLoopRestorationItem[] Items { get; }
+
+ internal int UnitShift { get; set; }
+
+ internal int UVShift { get; set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuMatrixCoefficients.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuMatrixCoefficients.cs
new file mode 100644
index 0000000000..e9658997fb
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuMatrixCoefficients.cs
@@ -0,0 +1,22 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal enum ObuMatrixCoefficients
+{
+ Identity = 0,
+ Bt407 = 1,
+ Unspecified = 2,
+ Fcc = 4,
+ Bt470BG = 5,
+ Bt601 = 6,
+ Smpte240 = 7,
+ SmpteYCgCo = 8,
+ Bt2020NonConstantLuminance = 9,
+ Bt2020ConstantLuminance = 10,
+ Smpte2085 = 11,
+ ChromaticityDerivedNonConstantLuminance = 12,
+ ChromaticityDerivedConstandLuminance = 13,
+ Bt2100ICtCp = 14,
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuMetadataType.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuMetadataType.cs
new file mode 100644
index 0000000000..d6788f1745
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuMetadataType.cs
@@ -0,0 +1,13 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal enum ObuMetadataType
+{
+ ItutT35,
+ HdrCll,
+ HdrMdcv,
+ Scalability,
+ Timecode
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuOperatingPoint.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuOperatingPoint.cs
new file mode 100644
index 0000000000..a398124e39
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuOperatingPoint.cs
@@ -0,0 +1,29 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuOperatingPoint
+{
+ internal int OperatorIndex { get; set; }
+
+ internal int SequenceLevelIndex { get; set; }
+
+ internal int SequenceTier { get; set; }
+
+ internal bool IsDecoderModelInfoPresent { get; set; }
+
+ internal bool IsInitialDisplayDelayPresent { get; set; }
+
+ internal uint InitialDisplayDelay { get; set; }
+
+ ///
+ /// Gets or sets of sets the Idc bitmask. The bitmask that indicates which spatial and temporal layers should be decoded for
+ /// operating point i.Bit k is equal to 1 if temporal layer k should be decoded(for k between 0 and 7). Bit j+8 is equal to 1 if
+ /// spatial layer j should be decoded(for j between 0 and 3).
+ /// However, if operating_point_idc[i] is equal to 0 then the coded video sequence has no scalability information in OBU
+ /// extension headers and the operating point applies to the entire coded video sequence.This means that all OBUs must be decoded.
+ /// It is a requirement of bitstream conformance that operating_point_idc[i] is not equal to operating_point_idc[j] for j = 0..(i- 1).
+ ///
+ internal uint Idc { get; set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuOrderHintInfo.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuOrderHintInfo.cs
new file mode 100644
index 0000000000..f540a297fa
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuOrderHintInfo.cs
@@ -0,0 +1,15 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuOrderHintInfo
+{
+ public bool EnableOrderHint { get; internal set; }
+
+ internal bool EnableJointCompound { get; set; }
+
+ internal bool EnableReferenceFrameMotionVectors { get; set; }
+
+ internal int OrderHintBits { get; set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuQuantizationParameters.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuQuantizationParameters.cs
new file mode 100644
index 0000000000..a3924eeeec
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuQuantizationParameters.cs
@@ -0,0 +1,21 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuQuantizationParameters
+{
+ public int BaseQIndex { get; set; }
+
+ public int[] QIndex { get; set; } = new int[Av1Constants.MaxSegmentCount];
+
+ public bool IsUsingQMatrix { get; internal set; }
+
+ public int[] DeltaQDc { get; internal set; } = new int[3];
+
+ public int[] DeltaQAc { get; internal set; } = new int[3];
+
+ public int[] QMatrix { get; internal set; } = new int[3];
+
+ public bool HasSeparateUvDelta { get; internal set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuReader.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuReader.cs
new file mode 100644
index 0000000000..4cf648f0da
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuReader.cs
@@ -0,0 +1,1817 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.Quantification;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+///
+/// Reader for Open Bitstream Units (OBU's).
+///
+internal class ObuReader
+{
+ ///
+ /// Maximum value used for loop filtering.
+ ///
+ private const int MaxLoopFilter = 63;
+
+ ///
+ /// Number of segments allowed in segmentation map.
+ ///
+ private const int MaxSegments = 0;
+
+ ///
+ /// Number of segment features.
+ ///
+ private const int SegLvlMax = 8;
+
+ ///
+ /// Index for reference frame segment feature.
+ ///
+ private const int SegLvlRefFrame = 5;
+
+ private const int PrimaryRefNone = 7;
+
+ private static readonly int[] SegmentationFeatureBits = [8, 6, 6, 6, 6, 3, 0, 0];
+
+ private static readonly int[] SegmentationFeatureSigned = [1, 1, 1, 1, 1, 0, 0, 0];
+
+ private static readonly int[] SegmentationFeatureMax = [255, MaxLoopFilter, MaxLoopFilter, MaxLoopFilter, MaxLoopFilter, 7, 0, 0];
+
+ private IAv1TileReader? decoder;
+
+ public ObuSequenceHeader? SequenceHeader { get; set; }
+
+ public ObuFrameHeader? FrameHeader { get; set; }
+
+ ///
+ /// Decode all OBU's in a frame.
+ ///
+ public void ReadAll(ref Av1BitStreamReader reader, int dataSize, Func creator, bool isAnnexB = false)
+ {
+ bool seenFrameHeader = false;
+ bool frameDecodingFinished = false;
+ while (!frameDecodingFinished)
+ {
+ int lengthSize = 0;
+ int payloadSize = 0;
+ if (isAnnexB)
+ {
+ ReadObuSize(ref reader, out payloadSize, out lengthSize);
+ }
+
+ ObuHeader header = ReadObuHeaderSize(ref reader, out lengthSize);
+ if (isAnnexB)
+ {
+ header.PayloadSize -= header.Size;
+ dataSize -= lengthSize;
+ lengthSize = 0;
+ }
+
+ payloadSize = header.PayloadSize;
+ dataSize -= header.Size + lengthSize;
+ if (isAnnexB && dataSize < payloadSize)
+ {
+ throw new InvalidImageContentException("Corrupt frame");
+ }
+
+ switch (header.Type)
+ {
+ case ObuType.SequenceHeader:
+ this.SequenceHeader = new();
+ ReadSequenceHeader(ref reader, this.SequenceHeader);
+ if (this.SequenceHeader.ColorConfig.BitDepth == Av1BitDepth.TwelveBit)
+ {
+ // TODO: Initialize 12 bit predictors
+ }
+
+ break;
+ case ObuType.FrameHeader:
+ case ObuType.RedundantFrameHeader:
+ case ObuType.Frame:
+ if (header.Type != ObuType.Frame)
+ {
+ // Nothing to do here.
+ }
+ else if (header.Type != ObuType.FrameHeader)
+ {
+ Guard.IsFalse(seenFrameHeader, nameof(seenFrameHeader), "Frame header expected");
+ }
+ else
+ {
+ Guard.IsTrue(seenFrameHeader, nameof(seenFrameHeader), "Already decoded a frame header");
+ }
+
+ if (!seenFrameHeader)
+ {
+ seenFrameHeader = true;
+ this.FrameHeader = new();
+ this.ReadFrameHeader(ref reader, header, header.Type != ObuType.Frame);
+ }
+
+ if (header.Type != ObuType.Frame)
+ {
+ break; // For OBU_TILE_GROUP comes under OBU_FRAME
+ }
+
+ goto TILE_GROUP;
+ case ObuType.TileGroup:
+ TILE_GROUP:
+ if (!seenFrameHeader)
+ {
+ throw new InvalidImageContentException("Corrupt frame");
+ }
+
+ this.decoder ??= creator();
+ this.ReadTileGroup(ref reader, this.decoder, header, out frameDecodingFinished);
+ if (frameDecodingFinished)
+ {
+ seenFrameHeader = false;
+ }
+
+ break;
+ case ObuType.TemporalDelimiter:
+ // 5.6. Temporal delimiter obu syntax.
+ seenFrameHeader = false;
+ break;
+ default:
+ // Ignore unknown OBU types.
+ // throw new InvalidImageContentException($"Unknown OBU header found: {header.Type.ToString()}");
+ break;
+ }
+
+ dataSize -= payloadSize;
+ if (dataSize <= 0)
+ {
+ frameDecodingFinished = true;
+ }
+ }
+ }
+
+ ///
+ /// 5.3.2. OBU header syntax.
+ ///
+ private static ObuHeader ReadObuHeader(ref Av1BitStreamReader reader)
+ {
+ ObuHeader header = new();
+ if (reader.ReadBoolean())
+ {
+ throw new ImageFormatException("Forbidden bit in header should be unset.");
+ }
+
+ header.Size = 1;
+ header.Type = (ObuType)reader.ReadLiteral(4);
+ header.HasExtension = reader.ReadBoolean();
+ header.HasSize = reader.ReadBoolean();
+ if (reader.ReadBoolean())
+ {
+ throw new ImageFormatException("Reserved bit in header should be unset.");
+ }
+
+ if (header.HasExtension)
+ {
+ header.Size++;
+ header.TemporalId = (int)reader.ReadLiteral(3);
+ header.SpatialId = (int)reader.ReadLiteral(2);
+ if (reader.ReadLiteral(3) != 0u)
+ {
+ throw new ImageFormatException("Reserved bits in header extension should be unset.");
+ }
+ }
+ else
+ {
+ header.SpatialId = 0;
+ header.TemporalId = 0;
+ }
+
+ return header;
+ }
+
+ private static void ReadObuSize(ref Av1BitStreamReader reader, out int obuSize, out int lengthSize)
+ {
+ ulong rawSize = reader.ReadLittleEndianBytes128(out lengthSize);
+ if (rawSize > uint.MaxValue)
+ {
+ throw new ImageFormatException("OBU block too large.");
+ }
+
+ obuSize = (int)rawSize;
+ }
+
+ ///
+ /// Read OBU header and size.
+ ///
+ private static ObuHeader ReadObuHeaderSize(ref Av1BitStreamReader reader, out int lengthSize)
+ {
+ ObuHeader header = ReadObuHeader(ref reader);
+ lengthSize = 0;
+ if (header.HasSize)
+ {
+ ReadObuSize(ref reader, out int payloadSize, out lengthSize);
+ header.PayloadSize = payloadSize;
+ }
+
+ return header;
+ }
+
+ ///
+ /// Check that the trailing bits start with a 1 and end with 0s.
+ ///
+ /// Consumes a byte, if already byte aligned before the check.
+ private static void ReadTrailingBits(ref Av1BitStreamReader reader)
+ {
+ int bitsBeforeAlignment = 8 - (reader.BitPosition & 0x7);
+ uint trailing = reader.ReadLiteral(bitsBeforeAlignment);
+ if (trailing != (1U << (bitsBeforeAlignment - 1)))
+ {
+ throw new ImageFormatException("Trailing bits not properly formatted.");
+ }
+ }
+
+ ///
+ /// 5.3.5. Byte alignment syntax.
+ ///
+ private static void AlignToByteBoundary(ref Av1BitStreamReader reader)
+ {
+ while ((reader.BitPosition & 0x7) > 0)
+ {
+ if (reader.ReadBoolean())
+ {
+ throw new ImageFormatException("Incorrect byte alignment padding bits.");
+ }
+ }
+ }
+
+ private void ComputeImageSize(ObuSequenceHeader sequenceHeader)
+ {
+ ObuFrameHeader frameHeader = this.FrameHeader!;
+ frameHeader.ModeInfoColumnCount = 2 * ((frameHeader.FrameSize.FrameWidth + 7) >> 3);
+ frameHeader.ModeInfoRowCount = 2 * ((frameHeader.FrameSize.FrameHeight + 7) >> 3);
+ frameHeader.ModeInfoStride = Av1Math.AlignPowerOf2(sequenceHeader.MaxFrameWidth, Av1Constants.MaxSuperBlockSizeLog2) >> Av1Constants.ModeInfoSizeLog2;
+ }
+
+ ///
+ /// 5.5.1. General sequence header OBU syntax.
+ ///
+ internal static void ReadSequenceHeader(ref Av1BitStreamReader reader, ObuSequenceHeader sequenceHeader)
+ {
+ sequenceHeader.SequenceProfile = (ObuSequenceProfile)reader.ReadLiteral(3);
+ if (sequenceHeader.SequenceProfile > Av1Constants.MaxSequenceProfile)
+ {
+ throw new ImageFormatException("Unknown sequence profile.");
+ }
+
+ sequenceHeader.IsStillPicture = reader.ReadBoolean();
+ sequenceHeader.IsReducedStillPictureHeader = reader.ReadBoolean();
+ if (sequenceHeader.IsReducedStillPictureHeader)
+ {
+ sequenceHeader.TimingInfo = null;
+ sequenceHeader.DecoderModelInfoPresentFlag = false;
+ sequenceHeader.InitialDisplayDelayPresentFlag = false;
+ sequenceHeader.OperatingPoint = new ObuOperatingPoint[1];
+ ObuOperatingPoint operatingPoint = new();
+ sequenceHeader.OperatingPoint[0] = operatingPoint;
+ operatingPoint.OperatorIndex = 0;
+ operatingPoint.SequenceLevelIndex = (int)reader.ReadLiteral(Av1Constants.LevelBits);
+ if (!IsValidSequenceLevel(sequenceHeader.OperatingPoint[0].SequenceLevelIndex))
+ {
+ throw new ImageFormatException("Invalid sequence level.");
+ }
+
+ operatingPoint.SequenceTier = 0;
+ operatingPoint.IsDecoderModelInfoPresent = false;
+ operatingPoint.IsInitialDisplayDelayPresent = false;
+ }
+ else
+ {
+ sequenceHeader.TimingInfoPresentFlag = reader.ReadBoolean();
+ if (sequenceHeader.TimingInfoPresentFlag)
+ {
+ ReadTimingInfo(ref reader, sequenceHeader);
+ sequenceHeader.DecoderModelInfoPresentFlag = reader.ReadBoolean();
+ if (sequenceHeader.DecoderModelInfoPresentFlag)
+ {
+ ReadDecoderModelInfo(ref reader, sequenceHeader);
+ }
+ else
+ {
+ sequenceHeader.DecoderModelInfoPresentFlag = false;
+ }
+ }
+
+ sequenceHeader.InitialDisplayDelayPresentFlag = reader.ReadBoolean();
+ uint operatingPointsCnt = reader.ReadLiteral(5) + 1;
+ sequenceHeader.OperatingPoint = new ObuOperatingPoint[operatingPointsCnt];
+ for (int i = 0; i < operatingPointsCnt; i++)
+ {
+ sequenceHeader.OperatingPoint[i] = new ObuOperatingPoint
+ {
+ Idc = reader.ReadLiteral(12),
+ SequenceLevelIndex = (int)reader.ReadLiteral(5)
+ };
+ if (sequenceHeader.OperatingPoint[i].SequenceLevelIndex > 7)
+ {
+ sequenceHeader.OperatingPoint[i].SequenceTier = (int)reader.ReadLiteral(1);
+ }
+ else
+ {
+ sequenceHeader.OperatingPoint[i].SequenceTier = 0;
+ }
+
+ if (sequenceHeader.DecoderModelInfoPresentFlag)
+ {
+ sequenceHeader.OperatingPoint[i].IsDecoderModelInfoPresent = reader.ReadBoolean();
+ if (sequenceHeader.OperatingPoint[i].IsDecoderModelInfoPresent)
+ {
+ // TODO: operating_parameters_info( i )
+ }
+ }
+ else
+ {
+ sequenceHeader.OperatingPoint[i].IsDecoderModelInfoPresent = false;
+ }
+
+ if (sequenceHeader.InitialDisplayDelayPresentFlag)
+ {
+ sequenceHeader.OperatingPoint[i].IsInitialDisplayDelayPresent = reader.ReadBoolean();
+ if (sequenceHeader.OperatingPoint[i].IsInitialDisplayDelayPresent)
+ {
+ sequenceHeader.OperatingPoint[i].InitialDisplayDelay = reader.ReadLiteral(4) + 1;
+ }
+ }
+ }
+ }
+
+ // Video related flags removed
+
+ // SVT-TODO: int operatingPoint = this.ChooseOperatingPoint();
+ // sequenceHeader.OperatingPointIndex = (int)operatingPointIndices[operatingPoint];
+ sequenceHeader.FrameWidthBits = (int)reader.ReadLiteral(4) + 1;
+ sequenceHeader.FrameHeightBits = (int)reader.ReadLiteral(4) + 1;
+ sequenceHeader.MaxFrameWidth = (int)reader.ReadLiteral(sequenceHeader.FrameWidthBits) + 1;
+ sequenceHeader.MaxFrameHeight = (int)reader.ReadLiteral(sequenceHeader.FrameHeightBits) + 1;
+ if (sequenceHeader.IsReducedStillPictureHeader)
+ {
+ sequenceHeader.IsFrameIdNumbersPresent = false;
+ }
+ else
+ {
+ sequenceHeader.IsFrameIdNumbersPresent = reader.ReadBoolean();
+ }
+
+ if (sequenceHeader.IsFrameIdNumbersPresent)
+ {
+ sequenceHeader.DeltaFrameIdLength = (int)reader.ReadLiteral(4) + 2;
+ sequenceHeader.AdditionalFrameIdLength = reader.ReadLiteral(3) + 1;
+ }
+
+ // Video related flags removed
+ sequenceHeader.Use128x128Superblock = reader.ReadBoolean();
+ sequenceHeader.EnableFilterIntra = reader.ReadBoolean();
+ sequenceHeader.EnableIntraEdgeFilter = reader.ReadBoolean();
+
+ if (sequenceHeader.IsReducedStillPictureHeader)
+ {
+ sequenceHeader.EnableInterIntraCompound = false;
+ sequenceHeader.EnableMaskedCompound = false;
+ sequenceHeader.EnableWarpedMotion = false;
+ sequenceHeader.EnableDualFilter = false;
+ sequenceHeader.OrderHintInfo.EnableJointCompound = false;
+ sequenceHeader.OrderHintInfo.EnableReferenceFrameMotionVectors = false;
+ sequenceHeader.ForceScreenContentTools = 2; // SELECT_SCREEN_CONTENT_TOOLS
+ sequenceHeader.ForceIntegerMotionVector = 2; // SELECT_INTEGER_MV
+ sequenceHeader.OrderHintInfo.OrderHintBits = 0;
+ }
+ else
+ {
+ sequenceHeader.EnableInterIntraCompound = reader.ReadBoolean();
+ sequenceHeader.EnableMaskedCompound = reader.ReadBoolean();
+ sequenceHeader.EnableWarpedMotion = reader.ReadBoolean();
+ sequenceHeader.EnableDualFilter |= reader.ReadBoolean();
+ sequenceHeader.EnableOrderHint = reader.ReadBoolean();
+ if (sequenceHeader.EnableOrderHint)
+ {
+ sequenceHeader.OrderHintInfo.EnableJointCompound = reader.ReadBoolean();
+ sequenceHeader.OrderHintInfo.EnableReferenceFrameMotionVectors = reader.ReadBoolean();
+ }
+ else
+ {
+ sequenceHeader.OrderHintInfo.EnableJointCompound = false;
+ sequenceHeader.OrderHintInfo.EnableReferenceFrameMotionVectors = false;
+ }
+
+ bool seqChooseScreenContentTools = reader.ReadBoolean();
+ if (seqChooseScreenContentTools)
+ {
+ sequenceHeader.ForceScreenContentTools = 2; // SELECT_SCREEN_CONTENT_TOOLS
+ }
+ else
+ {
+ sequenceHeader.ForceScreenContentTools = (int)reader.ReadLiteral(1);
+ }
+
+ if (sequenceHeader.ForceScreenContentTools > 0)
+ {
+ bool seqChooseIntegerMv = reader.ReadBoolean();
+ if (seqChooseIntegerMv)
+ {
+ sequenceHeader.ForceIntegerMotionVector = 2; // SELECT_INTEGER_MV
+ }
+ else
+ {
+ sequenceHeader.ForceIntegerMotionVector = (int)reader.ReadLiteral(1);
+ }
+ }
+ else
+ {
+ sequenceHeader.ForceIntegerMotionVector = 2; // SELECT_INTEGER_MV
+ }
+
+ if (sequenceHeader.EnableOrderHint)
+ {
+ sequenceHeader.OrderHintInfo.OrderHintBits = (int)reader.ReadLiteral(3) + 1;
+ }
+ else
+ {
+ sequenceHeader.OrderHintInfo.OrderHintBits = 0;
+ }
+ }
+
+ // Video related flags removed
+ sequenceHeader.EnableSuperResolution = reader.ReadBoolean();
+ sequenceHeader.EnableCdef = reader.ReadBoolean();
+ sequenceHeader.EnableRestoration = reader.ReadBoolean();
+ sequenceHeader.ColorConfig = ReadColorConfig(ref reader, sequenceHeader);
+ sequenceHeader.AreFilmGrainingParametersPresent = reader.ReadBoolean();
+ ReadTrailingBits(ref reader);
+ }
+
+ ///
+ /// 5.5.2. Color config syntax.
+ ///
+ private static ObuColorConfig ReadColorConfig(ref Av1BitStreamReader reader, ObuSequenceHeader sequenceHeader)
+ {
+ ObuColorConfig colorConfig = new();
+ ReadBitDepth(ref reader, colorConfig, sequenceHeader);
+ colorConfig.IsMonochrome = false;
+ if (sequenceHeader.SequenceProfile != ObuSequenceProfile.High)
+ {
+ colorConfig.IsMonochrome = reader.ReadBoolean();
+ }
+
+ colorConfig.IsColorDescriptionPresent = reader.ReadBoolean();
+ colorConfig.ColorPrimaries = ObuColorPrimaries.Unspecified;
+ colorConfig.TransferCharacteristics = ObuTransferCharacteristics.Unspecified;
+ colorConfig.MatrixCoefficients = ObuMatrixCoefficients.Unspecified;
+ if (colorConfig.IsColorDescriptionPresent)
+ {
+ colorConfig.ColorPrimaries = (ObuColorPrimaries)reader.ReadLiteral(8);
+ colorConfig.TransferCharacteristics = (ObuTransferCharacteristics)reader.ReadLiteral(8);
+ colorConfig.MatrixCoefficients = (ObuMatrixCoefficients)reader.ReadLiteral(8);
+ }
+
+ colorConfig.ColorRange = false;
+ colorConfig.SubSamplingX = false;
+ colorConfig.SubSamplingY = false;
+ colorConfig.ChromaSamplePosition = ObuChromoSamplePosition.Unknown;
+ colorConfig.HasSeparateUvDelta = false;
+ if (colorConfig.IsMonochrome)
+ {
+ colorConfig.ColorRange = reader.ReadBoolean();
+ colorConfig.SubSamplingX = true;
+ colorConfig.SubSamplingY = true;
+ return colorConfig;
+ }
+ else if (
+ colorConfig.ColorPrimaries == ObuColorPrimaries.Bt709 &&
+ colorConfig.TransferCharacteristics == ObuTransferCharacteristics.Srgb &&
+ colorConfig.MatrixCoefficients == ObuMatrixCoefficients.Identity)
+ {
+ colorConfig.ColorRange = true;
+ colorConfig.SubSamplingX = false;
+ colorConfig.SubSamplingY = false;
+ }
+ else
+ {
+ colorConfig.ColorRange = reader.ReadBoolean();
+ switch (sequenceHeader.SequenceProfile)
+ {
+ case ObuSequenceProfile.Main:
+ colorConfig.SubSamplingX = true;
+ colorConfig.SubSamplingY = true;
+ break;
+ case ObuSequenceProfile.High:
+ colorConfig.SubSamplingX = false;
+ colorConfig.SubSamplingY = false;
+ break;
+ case ObuSequenceProfile.Professional:
+ default:
+ if (colorConfig.BitDepth == Av1BitDepth.TwelveBit)
+ {
+ colorConfig.SubSamplingX = reader.ReadBoolean();
+ if (colorConfig.SubSamplingX)
+ {
+ colorConfig.SubSamplingY = reader.ReadBoolean();
+ }
+ }
+ else
+ {
+ colorConfig.SubSamplingX = true;
+ colorConfig.SubSamplingY = false;
+ }
+
+ break;
+ }
+
+ if (colorConfig.SubSamplingX && colorConfig.SubSamplingY)
+ {
+ colorConfig.ChromaSamplePosition = (ObuChromoSamplePosition)reader.ReadLiteral(2);
+ }
+ }
+
+ colorConfig.HasSeparateUvDelta = reader.ReadBoolean();
+ return colorConfig;
+ }
+
+ ///
+ /// 5.5.4. Decoder model info syntax.
+ ///
+ private static void ReadDecoderModelInfo(ref Av1BitStreamReader reader, ObuSequenceHeader sequenceHeader) => sequenceHeader.DecoderModelInfo = new ObuDecoderModelInfo
+ {
+ BufferDelayLength = reader.ReadLiteral(5) + 1,
+ NumUnitsInDecodingTick = reader.ReadLiteral(16),
+ BufferRemovalTimeLength = reader.ReadLiteral(5) + 1,
+ FramePresentationTimeLength = reader.ReadLiteral(5) + 1
+ };
+
+ ///
+ /// 5.5.3. Timing info syntax.
+ ///
+ private static void ReadTimingInfo(ref Av1BitStreamReader reader, ObuSequenceHeader sequenceHeader)
+ {
+ sequenceHeader.TimingInfo = new ObuTimingInfo
+ {
+ NumUnitsInDisplayTick = reader.ReadLiteral(32),
+ TimeScale = reader.ReadLiteral(32),
+ EqualPictureInterval = reader.ReadBoolean()
+ };
+
+ if (sequenceHeader.TimingInfo.EqualPictureInterval)
+ {
+ sequenceHeader.TimingInfo.NumTicksPerPicture = reader.ReadUnsignedVariableLength() + 1;
+ }
+ }
+
+ private static void ReadBitDepth(ref Av1BitStreamReader reader, ObuColorConfig colorConfig, ObuSequenceHeader sequenceHeader)
+ {
+ bool hasHighBitDepth = reader.ReadBoolean();
+ if (sequenceHeader.SequenceProfile == ObuSequenceProfile.Professional && hasHighBitDepth)
+ {
+ colorConfig.BitDepth = reader.ReadBoolean() ? Av1BitDepth.TwelveBit : Av1BitDepth.TenBit;
+ }
+ else if (sequenceHeader.SequenceProfile <= ObuSequenceProfile.Professional)
+ {
+ colorConfig.BitDepth = hasHighBitDepth ? Av1BitDepth.TenBit : Av1BitDepth.EightBit;
+ }
+ else
+ {
+ colorConfig.BitDepth = Av1BitDepth.EightBit;
+ }
+ }
+
+ ///
+ /// 5.9.8. Superres params syntax.
+ ///
+ private void ReadSuperResolutionParameters(ref Av1BitStreamReader reader)
+ {
+ ObuSequenceHeader sequenceHeader = this.SequenceHeader!;
+ ObuFrameHeader frameHeader = this.FrameHeader!;
+ bool useSuperResolution = false;
+ if (sequenceHeader.EnableSuperResolution)
+ {
+ useSuperResolution = reader.ReadBoolean();
+ }
+
+ if (useSuperResolution)
+ {
+ frameHeader.FrameSize.SuperResolutionDenominator = (int)reader.ReadLiteral(Av1Constants.SuperResolutionScaleBits) + Av1Constants.SuperResolutionScaleDenominatorMinimum;
+ }
+ else
+ {
+ frameHeader.FrameSize.SuperResolutionDenominator = Av1Constants.ScaleNumerator;
+ }
+
+ frameHeader.FrameSize.SuperResolutionUpscaledWidth = frameHeader.FrameSize.FrameWidth;
+ frameHeader.FrameSize.FrameWidth =
+ ((frameHeader.FrameSize.SuperResolutionUpscaledWidth * Av1Constants.ScaleNumerator) +
+ (frameHeader.FrameSize.SuperResolutionDenominator / 2)) /
+ frameHeader.FrameSize.SuperResolutionDenominator;
+
+ /*
+ if (frameHeader.FrameSize.SuperResolutionDenominator != Av1Constants.ScaleNumerator)
+ {
+ int manWidth = Math.Min(16, frameHeader.FrameSize.SuperResolutionUpscaledWidth);
+ frameHeader.FrameSize.FrameWidth = Math.Max(manWidth, frameHeader.FrameSize.FrameWidth);
+ }
+ */
+ }
+
+ ///
+ /// 5.9.6. Render size syntax.
+ ///
+ private void ReadRenderSize(ref Av1BitStreamReader reader)
+ {
+ ObuFrameHeader frameHeader = this.FrameHeader!;
+ bool renderSizeAndFrameSizeDifferent = reader.ReadBoolean();
+ if (renderSizeAndFrameSizeDifferent)
+ {
+ frameHeader.FrameSize.RenderWidth = (int)reader.ReadLiteral(16) + 1;
+ frameHeader.FrameSize.RenderHeight = (int)reader.ReadLiteral(16) + 1;
+ }
+ else
+ {
+ frameHeader.FrameSize.RenderWidth = frameHeader.FrameSize.SuperResolutionUpscaledWidth;
+ frameHeader.FrameSize.RenderHeight = frameHeader.FrameSize.FrameHeight;
+ }
+ }
+
+ ///
+ /// 5.9.5. Frame size syntax.
+ ///
+ private void ReadFrameSize(ref Av1BitStreamReader reader, bool frameSizeOverrideFlag)
+ {
+ ObuSequenceHeader sequenceHeader = this.SequenceHeader!;
+ ObuFrameHeader frameHeader = this.FrameHeader!;
+ if (frameSizeOverrideFlag)
+ {
+ frameHeader.FrameSize.FrameWidth = (int)reader.ReadLiteral(sequenceHeader.FrameWidthBits) + 1;
+ frameHeader.FrameSize.FrameHeight = (int)reader.ReadLiteral(sequenceHeader.FrameHeightBits) + 1;
+ }
+ else
+ {
+ frameHeader.FrameSize.FrameWidth = sequenceHeader.MaxFrameWidth;
+ frameHeader.FrameSize.FrameHeight = sequenceHeader.MaxFrameHeight;
+ }
+
+ this.ReadSuperResolutionParameters(ref reader);
+ this.ComputeImageSize(sequenceHeader);
+ }
+
+ ///
+ /// 5.9.15. Tile info syntax.
+ ///
+ private static ObuTileGroupHeader ReadTileInfo(ref Av1BitStreamReader reader, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader)
+ {
+ ObuTileGroupHeader tileInfo = new();
+ int superblockColumnCount;
+ int superblockRowCount;
+ int superblockSizeLog2 = sequenceHeader.SuperblockSizeLog2;
+ int superblockShift = superblockSizeLog2 - Av1Constants.ModeInfoSizeLog2;
+ superblockColumnCount = (frameHeader.ModeInfoColumnCount + sequenceHeader.SuperblockModeInfoSize - 1) >> superblockShift;
+ superblockRowCount = (frameHeader.ModeInfoRowCount + sequenceHeader.SuperblockModeInfoSize - 1) >> superblockShift;
+
+ int maxTileAreaOfSuperBlock = Av1Constants.MaxTileArea >> (superblockSizeLog2 << 1);
+
+ tileInfo.MaxTileWidthSuperblock = Av1Constants.MaxTileWidth >> superblockSizeLog2;
+ tileInfo.MaxTileHeightSuperblock = (Av1Constants.MaxTileArea / Av1Constants.MaxTileWidth) >> superblockSizeLog2;
+ tileInfo.MinLog2TileColumnCount = TileLog2(tileInfo.MaxTileWidthSuperblock, superblockColumnCount);
+ tileInfo.MaxLog2TileColumnCount = (int)Av1Math.CeilLog2((uint)Math.Min(superblockColumnCount, Av1Constants.MaxTileColumnCount));
+ tileInfo.MaxLog2TileRowCount = (int)Av1Math.CeilLog2((uint)Math.Min(superblockRowCount, Av1Constants.MaxTileRowCount));
+ tileInfo.MinLog2TileCount = Math.Max(tileInfo.MinLog2TileColumnCount, TileLog2(maxTileAreaOfSuperBlock, superblockColumnCount * superblockRowCount));
+ tileInfo.HasUniformTileSpacing = reader.ReadBoolean();
+ if (tileInfo.HasUniformTileSpacing)
+ {
+ tileInfo.TileColumnCountLog2 = tileInfo.MinLog2TileColumnCount;
+ while (tileInfo.TileColumnCountLog2 < tileInfo.MaxLog2TileColumnCount)
+ {
+ if (reader.ReadBoolean())
+ {
+ tileInfo.TileColumnCountLog2++;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ int tileWidthSuperblock = Av1Math.DivideLog2Ceiling(superblockColumnCount, tileInfo.TileColumnCountLog2);
+ DebugGuard.MustBeLessThanOrEqualTo(tileWidthSuperblock, tileInfo.MaxTileWidthSuperblock, nameof(tileWidthSuperblock));
+ int i = 0;
+ tileInfo.TileColumnStartModeInfo = new int[superblockColumnCount + 1];
+ for (int startSuperblock = 0; startSuperblock < superblockColumnCount; startSuperblock += tileWidthSuperblock)
+ {
+ tileInfo.TileColumnStartModeInfo[i] = startSuperblock << superblockShift;
+ i++;
+ }
+
+ tileInfo.TileColumnStartModeInfo[i] = frameHeader.ModeInfoColumnCount;
+ tileInfo.TileColumnCount = i;
+
+ tileInfo.MinLog2TileRowCount = Math.Max(tileInfo.MinLog2TileCount - tileInfo.TileColumnCountLog2, 0);
+ tileInfo.TileRowCountLog2 = tileInfo.MinLog2TileRowCount;
+ while (tileInfo.TileRowCountLog2 < tileInfo.MaxLog2TileRowCount)
+ {
+ if (reader.ReadBoolean())
+ {
+ tileInfo.TileRowCountLog2++;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ int tileHeightSuperblock = Av1Math.DivideLog2Ceiling(superblockRowCount, tileInfo.TileRowCountLog2);
+ DebugGuard.MustBeLessThanOrEqualTo(tileHeightSuperblock, tileInfo.MaxTileHeightSuperblock, nameof(tileHeightSuperblock));
+ i = 0;
+ tileInfo.TileRowStartModeInfo = new int[superblockRowCount + 1];
+ for (int startSuperblock = 0; startSuperblock < superblockRowCount; startSuperblock += tileHeightSuperblock)
+ {
+ tileInfo.TileRowStartModeInfo[i] = startSuperblock << superblockShift;
+ i++;
+ }
+
+ tileInfo.TileRowStartModeInfo[i] = frameHeader.ModeInfoRowCount;
+ tileInfo.TileRowCount = i;
+ }
+ else
+ {
+ uint widestTileSuperBlock = 0U;
+ int startSuperBlock = 0;
+ int i = 0;
+ for (; startSuperBlock < superblockColumnCount; i++)
+ {
+ tileInfo.TileColumnStartModeInfo[i] = startSuperBlock << superblockShift;
+ uint maxWidth = (uint)Math.Min(superblockColumnCount - startSuperBlock, tileInfo.MaxTileWidthSuperblock);
+ uint widthInSuperBlocks = reader.ReadNonSymmetric(maxWidth) + 1;
+ widestTileSuperBlock = Math.Max(widthInSuperBlocks, widestTileSuperBlock);
+ startSuperBlock += (int)widthInSuperBlocks;
+ }
+
+ if (startSuperBlock != superblockColumnCount)
+ {
+ throw new ImageFormatException("Super block tiles width does not add up to total width.");
+ }
+
+ tileInfo.TileColumnStartModeInfo[i] = frameHeader.ModeInfoColumnCount;
+ tileInfo.TileColumnCount = i;
+ tileInfo.TileColumnCountLog2 = TileLog2(1, tileInfo.TileColumnCount);
+ if (tileInfo.MinLog2TileCount > 0)
+ {
+ maxTileAreaOfSuperBlock = (superblockRowCount * superblockColumnCount) >> (tileInfo.MinLog2TileCount + 1);
+ }
+ else
+ {
+ maxTileAreaOfSuperBlock = superblockRowCount * superblockColumnCount;
+ }
+
+ DebugGuard.MustBeGreaterThan(widestTileSuperBlock, 0U, nameof(widestTileSuperBlock));
+ tileInfo.MaxTileHeightSuperblock = Math.Max(maxTileAreaOfSuperBlock / (int)widestTileSuperBlock, 1);
+
+ startSuperBlock = 0;
+ for (i = 0; startSuperBlock < superblockRowCount; i++)
+ {
+ tileInfo.TileRowStartModeInfo[i] = startSuperBlock << superblockShift;
+ uint maxHeight = (uint)Math.Min(superblockRowCount - startSuperBlock, tileInfo.MaxTileHeightSuperblock);
+ uint heightInSuperBlocks = reader.ReadNonSymmetric(maxHeight) + 1;
+ startSuperBlock += (int)heightInSuperBlocks;
+ }
+
+ if (startSuperBlock != superblockRowCount)
+ {
+ throw new ImageFormatException("Super block tiles height does not add up to total height.");
+ }
+
+ tileInfo.TileRowStartModeInfo[i] = frameHeader.ModeInfoRowCount;
+ tileInfo.TileRowCount = i;
+ tileInfo.TileRowCountLog2 = TileLog2(1, tileInfo.TileRowCount);
+ }
+
+ if (tileInfo.TileColumnCount > Av1Constants.MaxTileColumnCount || tileInfo.TileRowCount > Av1Constants.MaxTileRowCount)
+ {
+ throw new ImageFormatException("Tile width or height too big.");
+ }
+
+ if (tileInfo.TileColumnCountLog2 > 0 || tileInfo.TileRowCountLog2 > 0)
+ {
+ tileInfo.ContextUpdateTileId = reader.ReadLiteral(tileInfo.TileRowCountLog2 + tileInfo.TileColumnCountLog2);
+ tileInfo.TileSizeBytes = (int)reader.ReadLiteral(2) + 1;
+ }
+ else
+ {
+ tileInfo.ContextUpdateTileId = 0;
+ }
+
+ if (tileInfo.ContextUpdateTileId >= (tileInfo.TileColumnCount * tileInfo.TileRowCount))
+ {
+ throw new ImageFormatException("Context update Tile ID too large.");
+ }
+
+ return tileInfo;
+ }
+
+ ///
+ /// 5.9.2. Uncompressed header syntax.
+ ///
+ private void ReadUncompressedFrameHeader(ref Av1BitStreamReader reader)
+ {
+ ObuSequenceHeader sequenceHeader = this.SequenceHeader!;
+ ObuFrameHeader frameHeader = this.FrameHeader!;
+ int idLength = 0;
+ uint previousFrameId = 0;
+ bool frameSizeOverrideFlag = false;
+ if (sequenceHeader.IsFrameIdNumbersPresent)
+ {
+ idLength = sequenceHeader.FrameIdLength - 1 + sequenceHeader.DeltaFrameIdLength - 2 + 3;
+ DebugGuard.MustBeLessThanOrEqualTo(idLength, 16, nameof(idLength));
+ }
+
+ if (sequenceHeader.IsReducedStillPictureHeader)
+ {
+ frameHeader.ShowExistingFrame = false;
+ frameHeader.FrameType = ObuFrameType.KeyFrame;
+ frameHeader.ShowFrame = true;
+ frameHeader.ShowableFrame = false;
+ frameHeader.ErrorResilientMode = true;
+ }
+ else
+ {
+ frameHeader.ShowExistingFrame = reader.ReadBoolean();
+ if (frameHeader.ShowExistingFrame)
+ {
+ frameHeader.FrameToShowMapIdx = reader.ReadLiteral(3);
+
+ if (sequenceHeader.DecoderModelInfoPresentFlag && sequenceHeader.TimingInfo?.EqualPictureInterval == false)
+ {
+ // 5.9.31. Temporal point info syntax.
+ frameHeader.FramePresentationTime = reader.ReadLiteral((int)sequenceHeader!.DecoderModelInfo!.FramePresentationTimeLength);
+ }
+
+ if (sequenceHeader.IsFrameIdNumbersPresent)
+ {
+ frameHeader.DisplayFrameId = reader.ReadLiteral(idLength);
+ }
+
+ // TODO: This is incomplete here, not sure how we can display an already decoded frame here or if this is really relevent for still pictures.
+ throw new NotImplementedException("ShowExistingFrame is not yet implemented");
+ }
+
+ frameHeader.FrameType = (ObuFrameType)reader.ReadLiteral(2);
+ frameHeader.ShowFrame = reader.ReadBoolean();
+
+ if (frameHeader.ShowFrame && !sequenceHeader.DecoderModelInfoPresentFlag && sequenceHeader.TimingInfo?.EqualPictureInterval == false)
+ {
+ // 5.9.31. Temporal point info syntax.
+ frameHeader.FramePresentationTime = reader.ReadLiteral((int)sequenceHeader!.DecoderModelInfo!.FramePresentationTimeLength);
+ }
+
+ if (frameHeader.ShowFrame)
+ {
+ frameHeader.ShowableFrame = frameHeader.FrameType != ObuFrameType.KeyFrame;
+ }
+ else
+ {
+ frameHeader.ShowableFrame = reader.ReadBoolean();
+ }
+
+ if (frameHeader.FrameType == ObuFrameType.SwitchFrame || (frameHeader.FrameType == ObuFrameType.KeyFrame && frameHeader.ShowFrame))
+ {
+ frameHeader.ErrorResilientMode = true;
+ }
+ else
+ {
+ frameHeader.ErrorResilientMode = reader.ReadBoolean();
+ }
+ }
+
+ if (frameHeader.FrameType == ObuFrameType.KeyFrame && frameHeader.ShowFrame)
+ {
+ frameHeader.ReferenceValid = new bool[Av1Constants.ReferenceFrameCount];
+ frameHeader.ReferenceOrderHint = new bool[Av1Constants.ReferenceFrameCount];
+ Array.Fill(frameHeader.ReferenceValid, false);
+ Array.Fill(frameHeader.ReferenceOrderHint, false);
+ }
+
+ frameHeader.DisableCdfUpdate = reader.ReadBoolean();
+ frameHeader.AllowScreenContentTools = sequenceHeader.ForceScreenContentTools == 2;
+ if (frameHeader.AllowScreenContentTools)
+ {
+ frameHeader.AllowScreenContentTools = reader.ReadBoolean();
+ }
+
+ if (frameHeader.AllowScreenContentTools)
+ {
+ if (sequenceHeader.ForceIntegerMotionVector == 1)
+ {
+ frameHeader.ForceIntegerMotionVector = reader.ReadBoolean();
+ }
+ else
+ {
+ frameHeader.ForceIntegerMotionVector = sequenceHeader.ForceIntegerMotionVector != 0;
+ }
+ }
+ else
+ {
+ frameHeader.ForceIntegerMotionVector = false;
+ }
+
+ if (frameHeader.IsIntra)
+ {
+ frameHeader.ForceIntegerMotionVector = true;
+ }
+
+ bool havePreviousFrameId = !(frameHeader.FrameType == ObuFrameType.KeyFrame && frameHeader.ShowFrame);
+ if (havePreviousFrameId)
+ {
+ previousFrameId = frameHeader.CurrentFrameId;
+ }
+
+ if (sequenceHeader.IsFrameIdNumbersPresent)
+ {
+ frameHeader.CurrentFrameId = reader.ReadLiteral(idLength);
+ if (havePreviousFrameId)
+ {
+ uint diffFrameId = (frameHeader.CurrentFrameId > previousFrameId) ?
+ frameHeader.CurrentFrameId - previousFrameId :
+ (uint)((1 << idLength) + (int)frameHeader.CurrentFrameId - previousFrameId);
+ if (frameHeader.CurrentFrameId == previousFrameId || diffFrameId >= 1 << (idLength - 1))
+ {
+ throw new ImageFormatException("Current frame ID cannot be same as previous Frame ID");
+ }
+ }
+
+ int diffLength = sequenceHeader.DeltaFrameIdLength;
+ for (int i = 0; i < Av1Constants.ReferenceFrameCount; i++)
+ {
+ if (frameHeader.CurrentFrameId > (1U << diffLength))
+ {
+ if ((frameHeader.ReferenceFrameIndex[i] > frameHeader.CurrentFrameId) ||
+ frameHeader.ReferenceFrameIndex[i] > (frameHeader.CurrentFrameId - (1 - diffLength)))
+ {
+ frameHeader.ReferenceValid[i] = false;
+ }
+ }
+ else if (frameHeader.ReferenceFrameIndex[i] > frameHeader.CurrentFrameId &&
+ frameHeader.ReferenceFrameIndex[i] < ((1 << idLength) + (frameHeader.CurrentFrameId - (1 << diffLength))))
+ {
+ frameHeader.ReferenceValid[i] = false;
+ }
+ }
+ }
+ else
+ {
+ frameHeader.CurrentFrameId = 0;
+ }
+
+ if (frameHeader.FrameType == ObuFrameType.SwitchFrame)
+ {
+ frameSizeOverrideFlag = true;
+ }
+ else if (sequenceHeader.IsReducedStillPictureHeader)
+ {
+ frameSizeOverrideFlag = false;
+ }
+ else
+ {
+ frameSizeOverrideFlag = reader.ReadBoolean();
+ }
+
+ frameHeader.OrderHint = reader.ReadLiteral(sequenceHeader.OrderHintInfo.OrderHintBits);
+
+ if (frameHeader.IsIntra || frameHeader.ErrorResilientMode)
+ {
+ frameHeader.PrimaryReferenceFrame = Av1Constants.PrimaryReferenceFrameNone;
+ }
+ else
+ {
+ frameHeader.PrimaryReferenceFrame = reader.ReadLiteral(Av1Constants.PimaryReferenceBits);
+ }
+
+ // Skipping, as no decoder info model present
+ frameHeader.AllowHighPrecisionMotionVector = false;
+ frameHeader.UseReferenceFrameMotionVectors = false;
+ frameHeader.AllowIntraBlockCopy = false;
+ if (frameHeader.FrameType == ObuFrameType.SwitchFrame || (frameHeader.FrameType == ObuFrameType.KeyFrame && frameHeader.ShowFrame))
+ {
+ frameHeader.RefreshFrameFlags = 0xFFU;
+ }
+ else
+ {
+ frameHeader.RefreshFrameFlags = reader.ReadLiteral(8);
+ }
+
+ if (frameHeader.FrameType == ObuFrameType.IntraOnlyFrame)
+ {
+ DebugGuard.IsTrue(frameHeader.RefreshFrameFlags != 0xFFU, nameof(frameHeader.RefreshFrameFlags));
+ }
+
+ if (!frameHeader.IsIntra || (frameHeader.RefreshFrameFlags != 0xFFU))
+ {
+ if (frameHeader.ErrorResilientMode && sequenceHeader.OrderHintInfo != null)
+ {
+ for (int i = 0; i < Av1Constants.ReferenceFrameCount; i++)
+ {
+ int referenceOrderHint = (int)reader.ReadLiteral(sequenceHeader.OrderHintInfo.OrderHintBits);
+ if (referenceOrderHint != (frameHeader.ReferenceOrderHint[i] ? 1U : 0U))
+ {
+ frameHeader.ReferenceValid[i] = false;
+ }
+ }
+ }
+ }
+
+ if (frameHeader.IsIntra)
+ {
+ this.ReadFrameSize(ref reader, frameSizeOverrideFlag);
+ this.ReadRenderSize(ref reader);
+ if (frameHeader.AllowScreenContentTools && frameHeader.FrameSize.RenderWidth != 0)
+ {
+ if (frameHeader.FrameSize.FrameWidth == frameHeader.FrameSize.SuperResolutionUpscaledWidth)
+ {
+ frameHeader.AllowIntraBlockCopy = reader.ReadBoolean();
+ }
+ }
+ }
+ else
+ {
+ // Single image is always Intra.
+ throw new InvalidImageContentException("AVIF image can only contain INTRA frames.");
+ }
+
+ // SetupFrameBufferReferences(sequenceHeader, frameHeader);
+ // CheckAddTemporalMotionVectorBuffer(sequenceHeader, frameHeader);
+
+ // SetupFrameSignBias(sequenceHeader, frameHeader);
+ if (sequenceHeader.IsReducedStillPictureHeader || frameHeader.DisableCdfUpdate)
+ {
+ frameHeader.DisableFrameEndUpdateCdf = true;
+ }
+ else
+ {
+ frameHeader.DisableFrameEndUpdateCdf = reader.ReadBoolean();
+ }
+
+ if (frameHeader.PrimaryReferenceFrame == Av1Constants.PrimaryReferenceFrameNone)
+ {
+ // InitConCoefficientCdfs();
+ // SetupPastIndependence(frameHeader);
+ }
+ else
+ {
+ // LoadCdfs(frameHeader.PrimaryReferenceFrame);
+ // LoadPrevious();
+ throw new NotImplementedException();
+ }
+
+ if (frameHeader.UseReferenceFrameMotionVectors)
+ {
+ // MotionFieldEstimations();
+ throw new NotImplementedException();
+ }
+
+ // GenerateNextReferenceFrameMap(sequenceHeader, frameHeader);
+ frameHeader.TilesInfo = ReadTileInfo(ref reader, sequenceHeader, frameHeader);
+ ReadQuantizationParameters(ref reader, sequenceHeader, frameHeader);
+ ReadSegmentationParameters(ref reader, frameHeader);
+ ReadFrameDeltaQParameters(ref reader, frameHeader);
+ ReadFrameDeltaLoopFilterParameters(ref reader, frameHeader);
+
+ // SetupSegmentationDequantization();
+ if (frameHeader.PrimaryReferenceFrame == Av1Constants.PrimaryReferenceFrameNone)
+ {
+ // ResetParseContext(mainParseContext, frameHeader.QuantizationParameters.BaseQIndex);
+ }
+ else
+ {
+ // LoadPreviousSegmentIds();
+ throw new NotImplementedException();
+ }
+
+ int tilesCount = frameHeader.TilesInfo.TileColumnCount * frameHeader.TilesInfo.TileRowCount;
+ frameHeader.CodedLossless = true;
+ frameHeader.SegmentationParameters.QMLevel[0] = new int[Av1Constants.MaxSegmentCount];
+ frameHeader.SegmentationParameters.QMLevel[1] = new int[Av1Constants.MaxSegmentCount];
+ frameHeader.SegmentationParameters.QMLevel[2] = new int[Av1Constants.MaxSegmentCount];
+ for (int segmentId = 0; segmentId < Av1Constants.MaxSegmentCount; segmentId++)
+ {
+ int qIndex = Av1QuantizationLookup.GetQIndex(frameHeader.SegmentationParameters, segmentId, frameHeader.QuantizationParameters.BaseQIndex);
+ frameHeader.QuantizationParameters.QIndex[segmentId] = qIndex;
+ frameHeader.LosslessArray[segmentId] = qIndex == 0 &&
+ frameHeader.QuantizationParameters.DeltaQDc[(int)Av1Plane.Y] == 0 &&
+ frameHeader.QuantizationParameters.DeltaQAc[(int)Av1Plane.U] == 0 &&
+ frameHeader.QuantizationParameters.DeltaQDc[(int)Av1Plane.U] == 0 &&
+ frameHeader.QuantizationParameters.DeltaQAc[(int)Av1Plane.V] == 0 &&
+ frameHeader.QuantizationParameters.DeltaQDc[(int)Av1Plane.V] == 0;
+ if (!frameHeader.LosslessArray[segmentId])
+ {
+ frameHeader.CodedLossless = false;
+ }
+
+ if (frameHeader.QuantizationParameters.IsUsingQMatrix)
+ {
+ if (frameHeader.LosslessArray[segmentId])
+ {
+ frameHeader.SegmentationParameters.QMLevel[0][segmentId] = 15;
+ frameHeader.SegmentationParameters.QMLevel[1][segmentId] = 15;
+ frameHeader.SegmentationParameters.QMLevel[2][segmentId] = 15;
+ }
+ else
+ {
+ frameHeader.SegmentationParameters.QMLevel[0][segmentId] = frameHeader.QuantizationParameters.QMatrix[(int)Av1Plane.Y];
+ frameHeader.SegmentationParameters.QMLevel[1][segmentId] = frameHeader.QuantizationParameters.QMatrix[(int)Av1Plane.U];
+ frameHeader.SegmentationParameters.QMLevel[2][segmentId] = frameHeader.QuantizationParameters.QMatrix[(int)Av1Plane.V];
+ }
+ }
+ }
+
+ if (frameHeader.CodedLossless)
+ {
+ DebugGuard.IsFalse(frameHeader.DeltaQParameters.IsPresent, nameof(frameHeader.DeltaQParameters.IsPresent), "No Delta Q parameters are allowed for lossless frame.");
+ }
+
+ frameHeader.AllLossless = frameHeader.CodedLossless && frameHeader.FrameSize.FrameWidth == frameHeader.FrameSize.SuperResolutionUpscaledWidth;
+ this.ReadLoopFilterParameters(ref reader, sequenceHeader);
+ ReadCdefParameters(ref reader, sequenceHeader, frameHeader);
+ ReadLoopRestorationParameters(ref reader, sequenceHeader, frameHeader);
+ ReadTransformMode(ref reader, frameHeader);
+
+ frameHeader.ReferenceMode = ReadFrameReferenceMode(ref reader, frameHeader);
+ ReadSkipModeParameters(ref reader, sequenceHeader, frameHeader);
+ if (frameHeader.IsIntra || frameHeader.ErrorResilientMode || !sequenceHeader.EnableWarpedMotion)
+ {
+ frameHeader.AllowWarpedMotion = false;
+ }
+ else
+ {
+ frameHeader.AllowWarpedMotion = reader.ReadBoolean();
+ }
+
+ frameHeader.UseReducedTransformSet = reader.ReadBoolean();
+ ReadGlobalMotionParameters(ref reader, sequenceHeader, frameHeader);
+ frameHeader.FilmGrainParameters = ReadFilmGrainFilterParameters(ref reader, sequenceHeader, frameHeader);
+ }
+
+ private static bool IsSegmentationFeatureActive(ObuSegmentationParameters segmentationParameters, int segmentId, ObuSegmentationLevelFeature feature)
+ => segmentationParameters.Enabled && segmentationParameters.IsFeatureActive(segmentId, feature);
+
+ ///
+ /// 5.9.1. General frame header OBU syntax.
+ ///
+ internal void ReadFrameHeader(ref Av1BitStreamReader reader, ObuHeader header, bool trailingBit)
+ {
+ int startBitPosition = reader.BitPosition;
+ this.ReadUncompressedFrameHeader(ref reader);
+ if (trailingBit)
+ {
+ ReadTrailingBits(ref reader);
+ }
+
+ AlignToByteBoundary(ref reader);
+
+ int endPosition = reader.BitPosition;
+ int headerBytes = (endPosition - startBitPosition) / 8;
+ header.PayloadSize -= headerBytes;
+ }
+
+ ///
+ /// 5.11.1. General tile group OBU syntax.
+ ///
+ private void ReadTileGroup(ref Av1BitStreamReader reader, IAv1TileReader decoder, ObuHeader header, out bool isLastTileGroup)
+ {
+ ObuSequenceHeader sequenceHeader = this.SequenceHeader!;
+ ObuFrameHeader frameHeader = this.FrameHeader!;
+ ObuTileGroupHeader tileInfo = this.FrameHeader!.TilesInfo;
+ int tileCount = tileInfo.TileColumnCount * tileInfo.TileRowCount;
+ int startBitPosition = reader.BitPosition;
+ bool tileStartAndEndPresentFlag = false;
+ if (tileCount > 1)
+ {
+ tileStartAndEndPresentFlag = reader.ReadBoolean();
+ }
+
+ if (header.Type == ObuType.FrameHeader)
+ {
+ DebugGuard.IsFalse(tileStartAndEndPresentFlag, nameof(tileStartAndEndPresentFlag), "Frame header should not set 'tileStartAndEndPresentFlag'.");
+ }
+
+ int tileGroupStart = 0;
+ int tileGroupEnd = tileCount - 1;
+ if (tileCount != 1 && tileStartAndEndPresentFlag)
+ {
+ int tileBits = tileInfo.TileColumnCountLog2 + tileInfo.TileRowCountLog2;
+ tileGroupStart = (int)reader.ReadLiteral(tileBits);
+ tileGroupEnd = (int)reader.ReadLiteral(tileBits);
+ }
+
+ isLastTileGroup = (tileGroupEnd + 1) == tileCount;
+ AlignToByteBoundary(ref reader);
+ int endBitPosition = reader.BitPosition;
+ int headerBytes = (endBitPosition - startBitPosition) / 8;
+ header.PayloadSize -= headerBytes;
+
+ bool noIbc = !frameHeader.AllowIntraBlockCopy;
+ bool doLoopFilter = noIbc && (frameHeader.LoopFilterParameters.FilterLevel[0] != 0 || frameHeader.LoopFilterParameters.FilterLevel[1] != 0);
+ bool doCdef = noIbc && (!frameHeader.CodedLossless &&
+ (frameHeader.CdefParameters.BitCount != 0 ||
+ frameHeader.CdefParameters.YStrength[0] != 0 ||
+ frameHeader.CdefParameters.UvStrength[0] != 0));
+ bool doLoopRestoration = noIbc &&
+ (frameHeader.LoopRestorationParameters.Items[(int)Av1Plane.Y].Type != ObuRestorationType.None ||
+ frameHeader.LoopRestorationParameters.Items[(int)Av1Plane.U].Type != ObuRestorationType.None ||
+ frameHeader.LoopRestorationParameters.Items[(int)Av1Plane.V].Type != ObuRestorationType.None);
+
+ for (int tileNum = tileGroupStart; tileNum <= tileGroupEnd; tileNum++)
+ {
+ bool isLastTile = tileNum == tileGroupEnd;
+ int tileDataSize = header.PayloadSize;
+ if (!isLastTile)
+ {
+ tileDataSize = (int)reader.ReadLittleEndian(tileInfo.TileSizeBytes) + 1;
+ header.PayloadSize -= tileDataSize + tileInfo.TileSizeBytes;
+ }
+
+ Span tileData = reader.GetSymbolReader(tileDataSize);
+ decoder.ReadTile(tileData, tileNum);
+ }
+
+ if (tileGroupEnd != tileCount - 1)
+ {
+ return;
+ }
+
+ // TODO: Share doCdef and doLoopRestoration
+ }
+
+ ///
+ /// 5.9.13. Delta quantizer syntax.
+ ///
+ private static int ReadDeltaQ(ref Av1BitStreamReader reader)
+ {
+ int deltaQ = 0;
+ if (reader.ReadBoolean())
+ {
+ deltaQ = reader.ReadSignedFromUnsigned(7);
+ }
+
+ return deltaQ;
+ }
+
+ ///
+ /// 5.9.17. Quantizer index delta parameters syntax.
+ ///
+ private static void ReadFrameDeltaQParameters(ref Av1BitStreamReader reader, ObuFrameHeader frameHeader)
+ {
+ frameHeader.DeltaQParameters.Resolution = 0;
+ frameHeader.DeltaQParameters.IsPresent = false;
+ if (frameHeader.QuantizationParameters.BaseQIndex > 0)
+ {
+ frameHeader.DeltaQParameters.IsPresent = reader.ReadBoolean();
+ }
+
+ if (frameHeader.DeltaQParameters.IsPresent)
+ {
+ frameHeader.DeltaQParameters.Resolution = (int)reader.ReadLiteral(2);
+ }
+ }
+
+ ///
+ /// 5.9.18. Loop filter delta parameters syntax.
+ ///
+ private static void ReadFrameDeltaLoopFilterParameters(ref Av1BitStreamReader reader, ObuFrameHeader frameHeader)
+ {
+ frameHeader.DeltaLoopFilterParameters.IsPresent = false;
+ frameHeader.DeltaLoopFilterParameters.Resolution = 0;
+ frameHeader.DeltaLoopFilterParameters.IsMulti = false;
+ if (frameHeader.DeltaQParameters.IsPresent)
+ {
+ if (!frameHeader.AllowIntraBlockCopy)
+ {
+ frameHeader.DeltaLoopFilterParameters.IsPresent = reader.ReadBoolean();
+ }
+
+ if (frameHeader.DeltaLoopFilterParameters.IsPresent)
+ {
+ frameHeader.DeltaLoopFilterParameters.Resolution = (int)reader.ReadLiteral(2);
+ frameHeader.DeltaLoopFilterParameters.IsMulti = reader.ReadBoolean();
+ }
+ }
+ }
+
+ ///
+ /// 5.9.12. Quantization params syntax.
+ ///
+ private static void ReadQuantizationParameters(ref Av1BitStreamReader reader, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader)
+ {
+ ObuQuantizationParameters quantParams = frameHeader.QuantizationParameters;
+ ObuColorConfig colorInfo = sequenceHeader.ColorConfig;
+ quantParams.BaseQIndex = (int)reader.ReadLiteral(8);
+ quantParams.DeltaQDc[(int)Av1Plane.Y] = ReadDeltaQ(ref reader);
+ quantParams.DeltaQAc[(int)Av1Plane.Y] = 0;
+ if (colorInfo.PlaneCount > 1)
+ {
+ quantParams.HasSeparateUvDelta = false;
+ if (colorInfo.HasSeparateUvDelta)
+ {
+ quantParams.HasSeparateUvDelta = reader.ReadBoolean();
+ }
+
+ quantParams.DeltaQDc[(int)Av1Plane.U] = ReadDeltaQ(ref reader);
+ quantParams.DeltaQAc[(int)Av1Plane.U] = ReadDeltaQ(ref reader);
+ if (quantParams.HasSeparateUvDelta)
+ {
+ quantParams.DeltaQDc[(int)Av1Plane.V] = ReadDeltaQ(ref reader);
+ quantParams.DeltaQAc[(int)Av1Plane.V] = ReadDeltaQ(ref reader);
+ }
+ else
+ {
+ quantParams.DeltaQDc[(int)Av1Plane.V] = quantParams.DeltaQDc[(int)Av1Plane.U];
+ quantParams.DeltaQAc[(int)Av1Plane.V] = quantParams.DeltaQAc[(int)Av1Plane.U];
+ }
+ }
+ else
+ {
+ quantParams.DeltaQDc[(int)Av1Plane.U] = 0;
+ quantParams.DeltaQAc[(int)Av1Plane.U] = 0;
+ quantParams.DeltaQDc[(int)Av1Plane.V] = 0;
+ quantParams.DeltaQAc[(int)Av1Plane.V] = 0;
+ }
+
+ quantParams.IsUsingQMatrix = reader.ReadBoolean();
+ if (quantParams.IsUsingQMatrix)
+ {
+ quantParams.QMatrix[(int)Av1Plane.Y] = (int)reader.ReadLiteral(4);
+ quantParams.QMatrix[(int)Av1Plane.U] = (int)reader.ReadLiteral(4);
+ if (!colorInfo.HasSeparateUvDelta)
+ {
+ quantParams.QMatrix[(int)Av1Plane.V] = quantParams.QMatrix[(int)Av1Plane.U];
+ }
+ else
+ {
+ quantParams.QMatrix[(int)Av1Plane.V] = (int)reader.ReadLiteral(4);
+ }
+ }
+ else
+ {
+ quantParams.QMatrix[(int)Av1Plane.Y] = 0;
+ quantParams.QMatrix[(int)Av1Plane.U] = 0;
+ quantParams.QMatrix[(int)Av1Plane.V] = 0;
+ }
+ }
+
+ ///
+ /// 5.9.14. Segmentation params syntax.
+ ///
+ private static void ReadSegmentationParameters(ref Av1BitStreamReader reader, ObuFrameHeader frameHeader)
+ {
+ frameHeader.SegmentationParameters.Enabled = reader.ReadBoolean();
+
+ if (frameHeader.SegmentationParameters.Enabled)
+ {
+ if (frameHeader.PrimaryReferenceFrame == PrimaryRefNone)
+ {
+ frameHeader.SegmentationParameters.SegmentationUpdateMap = 1;
+ frameHeader.SegmentationParameters.SegmentationTemporalUpdate = 0;
+ frameHeader.SegmentationParameters.SegmentationUpdateData = 1;
+ }
+ else
+ {
+ frameHeader.SegmentationParameters.SegmentationUpdateMap = reader.ReadBoolean() ? 1 : 0;
+ if (frameHeader.SegmentationParameters.SegmentationUpdateMap == 1)
+ {
+ frameHeader.SegmentationParameters.SegmentationTemporalUpdate = reader.ReadBoolean() ? 1 : 0;
+ }
+
+ frameHeader.SegmentationParameters.SegmentationUpdateData = reader.ReadBoolean() ? 1 : 0;
+ }
+
+ if (frameHeader.SegmentationParameters.SegmentationUpdateData == 1)
+ {
+ for (int i = 0; i < MaxSegments; i++)
+ {
+ for (int j = 0; j < SegLvlMax; j++)
+ {
+ int featureValue = 0;
+ bool featureEnabled = reader.ReadBoolean();
+ frameHeader.SegmentationParameters.FeatureEnabled[i, j] = featureEnabled;
+ int clippedValue = 0;
+ if (featureEnabled)
+ {
+ int bitsToRead = SegmentationFeatureBits[j];
+ int limit = SegmentationFeatureMax[j];
+ if (SegmentationFeatureSigned[j] == 1)
+ {
+ featureValue = reader.ReadSignedFromUnsigned(1 + bitsToRead);
+ clippedValue = Av1Math.Clip3(-limit, limit, featureValue);
+ }
+ else
+ {
+ featureValue = (int)reader.ReadLiteral(bitsToRead);
+ }
+ }
+
+ frameHeader.SegmentationParameters.FeatureData[i, j] = clippedValue;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (int i = 0; i < Av1Constants.MaxSegmentCount; i++)
+ {
+ for (int j = 0; j < Av1Constants.SegmentationLevelMax; j++)
+ {
+ frameHeader.SegmentationParameters.FeatureEnabled[i, j] = false;
+ frameHeader.SegmentationParameters.FeatureData[i, j] = 0;
+ }
+ }
+ }
+
+ frameHeader.SegmentationParameters.SegmentIdPrecedesSkip = false;
+ frameHeader.SegmentationParameters.LastActiveSegmentId = 0;
+ for (int i = 0; i < Av1Constants.MaxSegmentCount; i++)
+ {
+ for (int j = 0; j < Av1Constants.SegmentationLevelMax; j++)
+ {
+ if (frameHeader.SegmentationParameters.FeatureEnabled[i, j])
+ {
+ frameHeader.SegmentationParameters.LastActiveSegmentId = i;
+ if (j >= SegLvlRefFrame)
+ {
+ frameHeader.SegmentationParameters.SegmentIdPrecedesSkip = true;
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// 5.9.11. Loop filter params syntax
+ ///
+ private void ReadLoopFilterParameters(ref Av1BitStreamReader reader, ObuSequenceHeader sequenceHeader)
+ {
+ ObuFrameHeader frameHeader = this.FrameHeader!;
+ if (frameHeader.CodedLossless || frameHeader.AllowIntraBlockCopy)
+ {
+ return;
+ }
+
+ frameHeader.LoopFilterParameters.FilterLevel[0] = (int)reader.ReadLiteral(6);
+ frameHeader.LoopFilterParameters.FilterLevel[1] = (int)reader.ReadLiteral(6);
+
+ if (sequenceHeader.ColorConfig.PlaneCount > 1)
+ {
+ if (frameHeader.LoopFilterParameters.FilterLevel[0] > 0 || frameHeader.LoopFilterParameters.FilterLevel[1] > 0)
+ {
+ frameHeader.LoopFilterParameters.FilterLevelU = (int)reader.ReadLiteral(6);
+ frameHeader.LoopFilterParameters.FilterLevelV = (int)reader.ReadLiteral(6);
+ }
+ }
+
+ frameHeader.LoopFilterParameters.SharpnessLevel = (int)reader.ReadLiteral(3);
+ frameHeader.LoopFilterParameters.ReferenceDeltaModeEnabled = reader.ReadBoolean();
+ if (frameHeader.LoopFilterParameters.ReferenceDeltaModeEnabled)
+ {
+ frameHeader.LoopFilterParameters.ReferenceDeltaModeUpdate = reader.ReadBoolean();
+ if (frameHeader.LoopFilterParameters.ReferenceDeltaModeUpdate)
+ {
+ for (int i = 0; i < Av1Constants.TotalReferencesPerFrame; i++)
+ {
+ if (reader.ReadBoolean())
+ {
+ frameHeader.LoopFilterParameters.ReferenceDeltas[i] = reader.ReadSignedFromUnsigned(7);
+ }
+ }
+
+ for (int i = 0; i < 2; i++)
+ {
+ if (reader.ReadBoolean())
+ {
+ frameHeader.LoopFilterParameters.ModeDeltas[i] = reader.ReadSignedFromUnsigned(7);
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// 5.9.21. TX mode syntax.
+ ///
+ private static void ReadTransformMode(ref Av1BitStreamReader reader, ObuFrameHeader frameHeader)
+ {
+ if (frameHeader.CodedLossless)
+ {
+ frameHeader.TransformMode = Av1TransformMode.Only4x4;
+ }
+ else
+ {
+ if (reader.ReadBoolean())
+ {
+ frameHeader.TransformMode = Av1TransformMode.Select;
+ }
+ else
+ {
+ frameHeader.TransformMode = Av1TransformMode.Largest;
+ }
+ }
+ }
+
+ ///
+ /// See section 5.9.20. Loop restoration params syntax.
+ ///
+ private static void ReadLoopRestorationParameters(ref Av1BitStreamReader reader, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader)
+ {
+ if (frameHeader.CodedLossless || frameHeader.AllowIntraBlockCopy || !sequenceHeader.EnableRestoration)
+ {
+ return;
+ }
+
+ frameHeader.LoopRestorationParameters.UsesLoopRestoration = false;
+ frameHeader.LoopRestorationParameters.UsesChromaLoopRestoration = false;
+ int planesCount = sequenceHeader.ColorConfig.PlaneCount;
+ for (int i = 0; i < planesCount; i++)
+ {
+ frameHeader.LoopRestorationParameters.Items[i].Type = (ObuRestorationType)reader.ReadLiteral(2);
+
+ if (frameHeader.LoopRestorationParameters.Items[i].Type != ObuRestorationType.None)
+ {
+ frameHeader.LoopRestorationParameters.UsesLoopRestoration = true;
+ if (i > 0)
+ {
+ frameHeader.LoopRestorationParameters.UsesChromaLoopRestoration = true;
+ }
+ }
+ }
+
+ if (frameHeader.LoopRestorationParameters.UsesLoopRestoration)
+ {
+ frameHeader.LoopRestorationParameters.UnitShift = (int)reader.ReadLiteral(1);
+ if (sequenceHeader.Use128x128Superblock)
+ {
+ frameHeader.LoopRestorationParameters.UnitShift++;
+ }
+ else
+ {
+ if (reader.ReadBoolean())
+ {
+ frameHeader.LoopRestorationParameters.UnitShift += (int)reader.ReadLiteral(1);
+ }
+ }
+
+ frameHeader.LoopRestorationParameters.Items[0].Size = Av1Constants.RestorationMaxTileSize >> (2 - frameHeader.LoopRestorationParameters.UnitShift);
+ frameHeader.LoopRestorationParameters.UVShift = 0;
+ if (sequenceHeader.ColorConfig.SubSamplingX && sequenceHeader.ColorConfig.SubSamplingY && frameHeader.LoopRestorationParameters.UsesChromaLoopRestoration)
+ {
+ frameHeader.LoopRestorationParameters.UVShift = (int)reader.ReadLiteral(1);
+ }
+
+ frameHeader.LoopRestorationParameters.Items[1].Size = frameHeader.LoopRestorationParameters.Items[0].Size >> frameHeader.LoopRestorationParameters.UVShift;
+ frameHeader.LoopRestorationParameters.Items[2].Size = frameHeader.LoopRestorationParameters.Items[0].Size >> frameHeader.LoopRestorationParameters.UVShift;
+ }
+ }
+
+ ///
+ /// See section 5.9.19. CDEF params syntax.
+ ///
+ private static void ReadCdefParameters(ref Av1BitStreamReader reader, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader)
+ {
+ ObuConstraintDirectionalEnhancementFilterParameters cdefInfo = frameHeader.CdefParameters;
+ bool multiPlane = sequenceHeader.ColorConfig.PlaneCount > 1;
+ if (frameHeader.CodedLossless || frameHeader.AllowIntraBlockCopy || sequenceHeader.CdefLevel == 0)
+ {
+ cdefInfo.BitCount = 0;
+ cdefInfo.YStrength[0] = 0;
+ cdefInfo.YStrength[4] = 0;
+ cdefInfo.UvStrength[0] = 0;
+ cdefInfo.UvStrength[4] = 0;
+ cdefInfo.Damping = 0;
+ return;
+ }
+
+ cdefInfo.Damping = (int)reader.ReadLiteral(2) + 3;
+ cdefInfo.BitCount = (int)reader.ReadLiteral(2);
+ for (int i = 0; i < (1 << frameHeader.CdefParameters.BitCount); i++)
+ {
+ cdefInfo.YStrength[i] = (int)reader.ReadLiteral(6);
+
+ if (multiPlane)
+ {
+ cdefInfo.UvStrength[i] = (int)reader.ReadLiteral(6);
+ }
+ }
+ }
+
+ ///
+ /// 5.9.24. Global motion params syntax.
+ ///
+ private static void ReadGlobalMotionParameters(ref Av1BitStreamReader reader, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader)
+ {
+ _ = reader;
+ _ = sequenceHeader;
+
+ if (frameHeader.IsIntra)
+ {
+ return;
+ }
+
+ // Not applicable for INTRA frames.
+ throw new NotImplementedException();
+ }
+
+ ///
+ /// 5.9.23. Frame reference mode syntax
+ ///
+ private static ObuReferenceMode ReadFrameReferenceMode(ref Av1BitStreamReader reader, ObuFrameHeader frameHeader)
+ {
+ if (frameHeader.IsIntra)
+ {
+ return ObuReferenceMode.SingleReference;
+ }
+
+ return (ObuReferenceMode)reader.ReadLiteral(1);
+ }
+
+ ///
+ /// 5.11.10. Skip mode syntax.
+ ///
+ private static void ReadSkipModeParameters(ref Av1BitStreamReader reader, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader)
+ {
+ if (frameHeader.IsIntra || frameHeader.ReferenceMode == ObuReferenceMode.ReferenceModeSelect || !sequenceHeader.OrderHintInfo.EnableOrderHint)
+ {
+ frameHeader.SkipModeParameters.SkipModeAllowed = false;
+ }
+ else
+ {
+ // Not applicable for INTRA frames.
+ }
+
+ if (frameHeader.SkipModeParameters.SkipModeAllowed)
+ {
+ frameHeader.SkipModeParameters.SkipModeFlag = reader.ReadBoolean();
+ }
+ else
+ {
+ frameHeader.SkipModeParameters.SkipModeFlag = false;
+ }
+ }
+
+ ///
+ /// 5.9.30. Film grain params syntax.
+ ///
+ private static ObuFilmGrainParameters ReadFilmGrainFilterParameters(ref Av1BitStreamReader reader, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader)
+ {
+ ObuFilmGrainParameters grainParams = new();
+ if (!sequenceHeader.AreFilmGrainingParametersPresent || (!frameHeader.ShowFrame && !frameHeader.ShowableFrame))
+ {
+ return grainParams;
+ }
+
+ grainParams.ApplyGrain = reader.ReadBoolean();
+ if (!grainParams.ApplyGrain)
+ {
+ return grainParams;
+ }
+
+ grainParams.GrainSeed = reader.ReadLiteral(16);
+
+ if (frameHeader.FrameType == ObuFrameType.InterFrame)
+ {
+ grainParams.UpdateGrain = reader.ReadBoolean();
+ }
+ else
+ {
+ grainParams.UpdateGrain = false;
+ }
+
+ if (!grainParams.UpdateGrain)
+ {
+ grainParams.FilmGrainParamsRefidx = reader.ReadLiteral(3);
+ uint tempGrainSeed = grainParams.GrainSeed;
+
+ // TODO: implement load_grain_params
+ // load_grain_params(film_grain_params_ref_idx)
+ grainParams.GrainSeed = tempGrainSeed;
+ return grainParams;
+ }
+
+ grainParams.NumYPoints = reader.ReadLiteral(4);
+ grainParams.PointYValue = new uint[grainParams.NumYPoints];
+ grainParams.PointYScaling = new uint[grainParams.NumYPoints];
+ for (int i = 0; i < grainParams.NumYPoints; i++)
+ {
+ grainParams.PointYValue[i] = reader.ReadLiteral(8);
+ grainParams.PointYScaling[i] = reader.ReadLiteral(8);
+ }
+
+ if (sequenceHeader.ColorConfig.IsMonochrome)
+ {
+ grainParams.ChromaScalingFromLuma = false;
+ }
+ else
+ {
+ grainParams.ChromaScalingFromLuma = reader.ReadBoolean();
+ }
+
+ if (sequenceHeader.ColorConfig.IsMonochrome ||
+ grainParams.ChromaScalingFromLuma ||
+ (sequenceHeader.ColorConfig.SubSamplingX && sequenceHeader.ColorConfig.SubSamplingY && grainParams.NumYPoints == 0))
+ {
+ grainParams.NumCbPoints = 0;
+ grainParams.NumCrPoints = 0;
+ }
+ else
+ {
+ grainParams.NumCbPoints = reader.ReadLiteral(4);
+ grainParams.PointCbValue = new uint[grainParams.NumCbPoints];
+ grainParams.PointCbScaling = new uint[grainParams.NumCbPoints];
+ for (int i = 0; i < grainParams.NumCbPoints; i++)
+ {
+ grainParams.PointCbValue[i] = reader.ReadLiteral(8);
+ grainParams.PointCbScaling[i] = reader.ReadLiteral(8);
+ }
+
+ grainParams.NumCrPoints = reader.ReadLiteral(4);
+ grainParams.PointCrValue = new uint[grainParams.NumCrPoints];
+ grainParams.PointCrScaling = new uint[grainParams.NumCrPoints];
+ for (int i = 0; i < grainParams.NumCbPoints; i++)
+ {
+ grainParams.PointCrValue[i] = reader.ReadLiteral(8);
+ grainParams.PointCrScaling[i] = reader.ReadLiteral(8);
+ }
+ }
+
+ grainParams.GrainScalingMinus8 = reader.ReadLiteral(2);
+ grainParams.ArCoeffLag = reader.ReadLiteral(2);
+ uint numPosLuma = 2 * grainParams.ArCoeffLag * (grainParams.ArCoeffLag + 1);
+
+ uint numPosChroma = 0;
+ if (grainParams.NumYPoints != 0)
+ {
+ numPosChroma = numPosLuma + 1;
+ grainParams.ArCoeffsYPlus128 = new uint[numPosLuma];
+ for (int i = 0; i < numPosLuma; i++)
+ {
+ grainParams.ArCoeffsYPlus128[i] = reader.ReadLiteral(8);
+ }
+ }
+ else
+ {
+ numPosChroma = numPosLuma;
+ }
+
+ if (grainParams.ChromaScalingFromLuma || grainParams.NumCbPoints != 0)
+ {
+ grainParams.ArCoeffsCbPlus128 = new uint[numPosChroma];
+ for (int i = 0; i < numPosChroma; i++)
+ {
+ grainParams.ArCoeffsCbPlus128[i] = reader.ReadLiteral(8);
+ }
+ }
+
+ if (grainParams.ChromaScalingFromLuma || grainParams.NumCrPoints != 0)
+ {
+ grainParams.ArCoeffsCrPlus128 = new uint[numPosChroma];
+ for (int i = 0; i < numPosChroma; i++)
+ {
+ grainParams.ArCoeffsCrPlus128[i] = reader.ReadLiteral(8);
+ }
+ }
+
+ grainParams.ArCoeffShiftMinus6 = reader.ReadLiteral(2);
+ grainParams.GrainScaleShift = reader.ReadLiteral(2);
+ if (grainParams.NumCbPoints != 0)
+ {
+ grainParams.CbMult = reader.ReadLiteral(8);
+ grainParams.CbLumaMult = reader.ReadLiteral(8);
+ grainParams.CbOffset = reader.ReadLiteral(9);
+ }
+
+ if (grainParams.NumCrPoints != 0)
+ {
+ grainParams.CrMult = reader.ReadLiteral(8);
+ grainParams.CrLumaMult = reader.ReadLiteral(8);
+ grainParams.CrOffset = reader.ReadLiteral(9);
+ }
+
+ grainParams.OverlapFlag = reader.ReadBoolean();
+ grainParams.ClipToRestrictedRange = reader.ReadBoolean();
+
+ return grainParams;
+ }
+
+ private static bool IsValidSequenceLevel(int sequenceLevelIndex)
+ => sequenceLevelIndex is < 24 or 31;
+
+ ///
+ /// Returns the smallest value for k such that blockSize << k is greater than or equal to target.
+ ///
+ public static int TileLog2(int blockSize, int target)
+ {
+ int k;
+ for (k = 0; (blockSize << k) < target; k++)
+ {
+ }
+
+ return k;
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuReferenceMode.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuReferenceMode.cs
new file mode 100644
index 0000000000..a76bc7601e
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuReferenceMode.cs
@@ -0,0 +1,10 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal enum ObuReferenceMode
+{
+ ReferenceModeSelect,
+ SingleReference,
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuRestorationType.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuRestorationType.cs
new file mode 100644
index 0000000000..bf90f5021d
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuRestorationType.cs
@@ -0,0 +1,12 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal enum ObuRestorationType : uint
+{
+ None = 0,
+ Switchable = 1,
+ Weiner = 2,
+ SgrProj = 3,
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuSegmentationLevelFeature.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuSegmentationLevelFeature.cs
new file mode 100644
index 0000000000..93af8e0a1c
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuSegmentationLevelFeature.cs
@@ -0,0 +1,16 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal enum ObuSegmentationLevelFeature
+{
+ AlternativeQuantizer,
+ AlternativeLoopFilterYVertical,
+ AlternativeLoopFilterYHorizontal,
+ AlternativeLoopFilterU,
+ AlternativeLoopFilterV,
+ ReferenceFrame,
+ Skip,
+ GlobalMotionVector,
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuSegmentationParameters.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuSegmentationParameters.cs
new file mode 100644
index 0000000000..a31235322c
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuSegmentationParameters.cs
@@ -0,0 +1,41 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuSegmentationParameters
+{
+ public int[][] QMLevel { get; internal set; } = new int[3][];
+
+ public bool[,] FeatureEnabled { get; internal set; } = new bool[Av1Constants.MaxSegmentCount, Av1Constants.SegmentationLevelMax];
+
+ public bool Enabled { get; internal set; }
+
+ public int[,] FeatureData { get; internal set; } = new int[Av1Constants.MaxSegmentCount, Av1Constants.SegmentationLevelMax];
+
+ public bool SegmentIdPrecedesSkip { get; internal set; }
+
+ public int LastActiveSegmentId { get; internal set; }
+
+ ///
+ /// Gets or sets the SegmentationUpdateMap. A value of 1 indicates that the segmentation map are updated during the decoding of this
+ /// frame. SegmentationUpdateMap equal to 0 means that the segmentation map from the previous frame is used.
+ ///
+ public int SegmentationUpdateMap { get; internal set; }
+
+ ///
+ /// Gets or sets the SegmentationTemporalUpdate. A value of 1 indicates that the updates to the segmentation map are coded relative to the
+ /// existing segmentation map. SegmentationTemporalUpdate equal to 0 indicates that the new segmentation map is coded
+ /// without reference to the existing segmentation map.
+ ///
+ public int SegmentationTemporalUpdate { get; internal set; }
+
+ ///
+ /// Gets or sets SegmentationUpdateData. A value of 1 indicates that new parameters are about to be specified for each segment.
+ /// SegmentationUpdateData equal to 0 indicates that the segmentation parameters should keep their existing values.
+ ///
+ public int SegmentationUpdateData { get; internal set; }
+
+ internal bool IsFeatureActive(int segmentId, ObuSegmentationLevelFeature feature)
+ => this.FeatureEnabled[segmentId, (int)feature];
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuSequenceHeader.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuSequenceHeader.cs
new file mode 100644
index 0000000000..ac87eefe74
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuSequenceHeader.cs
@@ -0,0 +1,95 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuSequenceHeader
+{
+ private bool use128x128Superblock;
+
+ public bool EnableFilterIntra { get; set; }
+
+ public bool EnableCdef { get; set; }
+
+ public bool IsStillPicture { get; set; }
+
+ public bool IsReducedStillPictureHeader { get; set; }
+
+ public ObuSequenceProfile SequenceProfile { get; set; }
+
+ public ObuOperatingPoint[] OperatingPoint { get; set; } = new ObuOperatingPoint[1];
+
+ public ObuDecoderModelInfo? DecoderModelInfo { get; set; }
+
+ public bool InitialDisplayDelayPresentFlag { get; set; }
+
+ public bool DecoderModelInfoPresentFlag { get; set; }
+
+ public bool TimingInfoPresentFlag { get; set; }
+
+ public ObuTimingInfo? TimingInfo { get; set; }
+
+ public bool IsFrameIdNumbersPresent { get; set; }
+
+ public int FrameWidthBits { get; set; }
+
+ public int FrameHeightBits { get; set; }
+
+ public int MaxFrameWidth { get; set; }
+
+ public int MaxFrameHeight { get; set; }
+
+ public bool Use128x128Superblock
+ {
+ get => this.use128x128Superblock;
+ set
+ {
+ this.use128x128Superblock = value;
+ this.SuperblockSize = value ? Av1BlockSize.Block128x128 : Av1BlockSize.Block64x64;
+ this.SuperblockSizeLog2 = value ? 7 : 6;
+ this.SuperblockModeInfoSize = 1 << (this.SuperblockSizeLog2 - Av1Constants.ModeInfoSizeLog2);
+ }
+ }
+
+ public Av1BlockSize SuperblockSize { get; private set; }
+
+ public int SuperblockModeInfoSize { get; private set; }
+
+ public int SuperblockSizeLog2 { get; private set; }
+
+ public int FilterIntraLevel { get; set; }
+
+ public bool EnableIntraEdgeFilter { get; set; }
+
+ public ObuOrderHintInfo OrderHintInfo { get; set; } = new ObuOrderHintInfo();
+
+ public bool EnableOrderHint { get; set; }
+
+ public bool EnableInterIntraCompound { get; set; }
+
+ public bool EnableMaskedCompound { get; set; }
+
+ public bool EnableWarpedMotion { get; set; }
+
+ public bool EnableDualFilter { get; set; }
+
+ public int ForceIntegerMotionVector { get; set; }
+
+ public int ForceScreenContentTools { get; set; }
+
+ public bool EnableSuperResolution { get; set; }
+
+ public int CdefLevel { get; set; }
+
+ public bool EnableRestoration { get; set; }
+
+ public ObuColorConfig ColorConfig { get; set; } = new ObuColorConfig();
+
+ public bool AreFilmGrainingParametersPresent { get; set; }
+
+ public int FrameIdLength { get; set; }
+
+ public int DeltaFrameIdLength { get; set; }
+
+ public uint AdditionalFrameIdLength { get; set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuSequenceProfile.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuSequenceProfile.cs
new file mode 100644
index 0000000000..f1ac85edb3
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuSequenceProfile.cs
@@ -0,0 +1,11 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal enum ObuSequenceProfile : uint
+{
+ Main = 0,
+ High = 1,
+ Professional = 2,
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuSkipModeParameters.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuSkipModeParameters.cs
new file mode 100644
index 0000000000..29a87a5f23
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuSkipModeParameters.cs
@@ -0,0 +1,11 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuSkipModeParameters
+{
+ public bool SkipModeAllowed { get; set; }
+
+ public bool SkipModeFlag { get; internal set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuTileGroupHeader.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuTileGroupHeader.cs
new file mode 100644
index 0000000000..a5f1867b66
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuTileGroupHeader.cs
@@ -0,0 +1,39 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuTileGroupHeader
+{
+ internal int MaxTileWidthSuperblock { get; set; }
+
+ internal int MaxTileHeightSuperblock { get; set; }
+
+ internal int MinLog2TileColumnCount { get; set; }
+
+ internal int MaxLog2TileColumnCount { get; set; }
+
+ internal int MaxLog2TileRowCount { get; set; }
+
+ internal int MinLog2TileCount { get; set; }
+
+ public bool HasUniformTileSpacing { get; set; }
+
+ internal int TileColumnCountLog2 { get; set; }
+
+ internal int TileColumnCount { get; set; }
+
+ internal int[] TileColumnStartModeInfo { get; set; } = new int[Av1Constants.MaxTileRowCount + 1];
+
+ internal int MinLog2TileRowCount { get; set; }
+
+ internal int TileRowCountLog2 { get; set; }
+
+ internal int[] TileRowStartModeInfo { get; set; } = new int[Av1Constants.MaxTileColumnCount + 1];
+
+ internal int TileRowCount { get; set; }
+
+ internal uint ContextUpdateTileId { get; set; }
+
+ internal int TileSizeBytes { get; set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuTimingInfo.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuTimingInfo.cs
new file mode 100644
index 0000000000..d366157e78
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuTimingInfo.cs
@@ -0,0 +1,33 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuTimingInfo
+{
+ ///
+ /// Gets or sets NumUnitsInDisplayTick. NumUnitsInDisplayTick is the number of time units of a clock operating at the frequency TimeScale Hz that
+ /// corresponds to one increment of a clock tick counter. A display clock tick, in seconds, is equal to
+ /// NumUnitsInDisplayTick divided by TimeScale.
+ ///
+ public uint NumUnitsInDisplayTick { get; set; }
+
+ ///
+ /// Gets or sets TimeScale. TimeScale is the number of time units that pass in one second.
+ /// It is a requirement of bitstream conformance that TimeScale is greater than 0.
+ ///
+ public uint TimeScale { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether that pictures should be displayed according to their output order with the
+ /// number of ticks between two consecutive pictures (without dropping frames) specified by NumTicksPerPicture.
+ /// EqualPictureInterval equal to false indicates that the interval between two consecutive pictures is not specified.
+ ///
+ public bool EqualPictureInterval { get; set; }
+
+ ///
+ /// Gets or sets NumTicksPerPicture. NumTicksPerPicture specifies the number of clock ticks corresponding to output time between two
+ /// consecutive pictures in the output order.
+ ///
+ public uint NumTicksPerPicture { get; set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuTransferCharacteristics.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuTransferCharacteristics.cs
new file mode 100644
index 0000000000..0fa71e5922
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuTransferCharacteristics.cs
@@ -0,0 +1,25 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal enum ObuTransferCharacteristics
+{
+ Bt709 = 1,
+ Unspecified = 2,
+ Bt470M = 4,
+ Bt470BG = 5,
+ Bt601 = 6,
+ Smpte240 = 7,
+ Linear = 8,
+ Log100 = 9,
+ Log100Sqrt10 = 10,
+ Iec61966 = 11,
+ Bt1361 = 12,
+ Srgb = 13,
+ Bt202010Bit = 14,
+ Bt202012Bit = 15,
+ Smpte2084 = 16,
+ Smpte248 = 17,
+ Hlg = 18,
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuType.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuType.cs
new file mode 100644
index 0000000000..34285ef2f0
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuType.cs
@@ -0,0 +1,18 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal enum ObuType
+{
+ None = 0,
+ SequenceHeader = 1,
+ TemporalDelimiter = 2,
+ FrameHeader = 3,
+ RedundantFrameHeader = 7,
+ TileGroup = 4,
+ Metadata = 5,
+ Frame = 6,
+ TileList = 8,
+ Padding = 15,
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuWriter.cs b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuWriter.cs
new file mode 100644
index 0000000000..f718eedd6e
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuWriter.cs
@@ -0,0 +1,862 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+using SixLabors.ImageSharp.Memory;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+internal class ObuWriter
+{
+ private int[] previousQIndex = [];
+ private int[] previousDeltaLoopFilter = [];
+
+ ///
+ /// Encode a single frame into OBU's.
+ ///
+ public void WriteAll(Configuration configuration, Stream stream, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader, IAv1TileWriter tileWriter)
+ {
+ // TODO: Determine inital size dynamically
+ int initialBufferSize = 2000;
+ AutoExpandingMemory buffer = new(configuration, initialBufferSize);
+ Av1BitStreamWriter writer = new(buffer);
+ WriteObuHeaderAndSize(stream, ObuType.TemporalDelimiter, []);
+
+ if (sequenceHeader != null)
+ {
+ WriteSequenceHeader(ref writer, sequenceHeader);
+ int bytesWritten = (writer.BitPosition + 7) >> 3;
+ writer.Flush();
+ WriteObuHeaderAndSize(stream, ObuType.SequenceHeader, buffer.GetSpan(bytesWritten));
+ }
+
+ if (frameHeader != null && sequenceHeader != null)
+ {
+ this.WriteFrameHeader(ref writer, sequenceHeader, frameHeader, false);
+ if (frameHeader.TilesInfo != null)
+ {
+ WriteTileGroup(ref writer, frameHeader.TilesInfo, tileWriter);
+ }
+
+ int bytesWritten = (writer.BitPosition + 7) >> 3;
+ writer.Flush();
+ WriteObuHeaderAndSize(stream, ObuType.Frame, buffer.GetSpan(bytesWritten));
+ }
+ }
+
+ private static void WriteObuHeader(ref Av1BitStreamWriter writer, ObuType type)
+ {
+ writer.WriteBoolean(false); // Forbidden bit
+ writer.WriteLiteral((uint)type, 4);
+ writer.WriteBoolean(false); // Extension
+ writer.WriteBoolean(true); // HasSize
+ writer.WriteBoolean(false); // Reserved
+ }
+
+ private static byte WriteObuHeader(ObuType type) =>
+
+ // 0: Forbidden bit
+ // 1: Type, 4
+ // 5: Extension (false)
+ // 6: HasSize (true)
+ // 7: Reserved (false)
+ (byte)(((byte)type << 3) | 0x02);
+
+ ///
+ /// Read OBU header and size.
+ ///
+ private static void WriteObuHeaderAndSize(Stream stream, ObuType type, Span payload)
+ {
+ stream.WriteByte(WriteObuHeader(type));
+ Span lengthBytes = stackalloc byte[3];
+ int lengthLength = Av1BitStreamWriter.GetLittleEndianBytes128((uint)payload.Length, lengthBytes);
+ stream.Write(lengthBytes, 0, lengthLength);
+ stream.Write(payload);
+ }
+
+ ///
+ /// Write trsainling bits to end on a byte boundary, these trailing bits start with a 1 and end with 0s.
+ ///
+ /// Write an additional byte, if already byte aligned before.
+ private static void WriteTrailingBits(ref Av1BitStreamWriter writer)
+ {
+ int bitsBeforeAlignment = 8 - (writer.BitPosition & 0x7);
+ if (bitsBeforeAlignment != 8)
+ {
+ writer.WriteLiteral(1U << (bitsBeforeAlignment - 1), bitsBeforeAlignment);
+ }
+ }
+
+ private static void AlignToByteBoundary(ref Av1BitStreamWriter writer)
+ {
+ while ((writer.BitPosition & 0x7) > 0)
+ {
+ writer.WriteBoolean(false);
+ }
+ }
+
+ private static bool IsValidObuType(ObuType type) => type switch
+ {
+ ObuType.SequenceHeader or ObuType.TemporalDelimiter or ObuType.FrameHeader or
+ ObuType.TileGroup or ObuType.Metadata or ObuType.Frame or ObuType.RedundantFrameHeader or
+ ObuType.TileList or ObuType.Padding => true,
+ _ => false,
+ };
+
+ private static void WriteSequenceHeader(ref Av1BitStreamWriter writer, ObuSequenceHeader sequenceHeader)
+ {
+ writer.WriteLiteral((uint)sequenceHeader.SequenceProfile, 3);
+ writer.WriteBoolean(true); // IsStillPicture
+ writer.WriteBoolean(true); // IsReducedStillPicture
+ writer.WriteLiteral((uint)sequenceHeader.OperatingPoint[0].SequenceLevelIndex, Av1Constants.LevelBits);
+
+ // Frame width and Height
+ writer.WriteLiteral((uint)sequenceHeader.FrameWidthBits - 1, 4);
+ writer.WriteLiteral((uint)sequenceHeader.FrameHeightBits - 1, 4);
+ writer.WriteLiteral((uint)sequenceHeader.MaxFrameWidth - 1, sequenceHeader.FrameWidthBits);
+ writer.WriteLiteral((uint)sequenceHeader.MaxFrameHeight - 1, sequenceHeader.FrameHeightBits);
+
+ // Video related flags removed
+ writer.WriteBoolean(sequenceHeader.Use128x128Superblock);
+ writer.WriteBoolean(sequenceHeader.EnableFilterIntra);
+ writer.WriteBoolean(sequenceHeader.EnableIntraEdgeFilter);
+
+ // Video related flags removed
+ writer.WriteBoolean(sequenceHeader.EnableSuperResolution);
+ writer.WriteBoolean(sequenceHeader.EnableCdef);
+ writer.WriteBoolean(sequenceHeader.EnableRestoration);
+ WriteColorConfig(ref writer, sequenceHeader);
+ writer.WriteBoolean(sequenceHeader.AreFilmGrainingParametersPresent);
+ WriteTrailingBits(ref writer);
+ }
+
+ private static void WriteColorConfig(ref Av1BitStreamWriter writer, ObuSequenceHeader sequenceHeader)
+ {
+ ObuColorConfig colorConfig = sequenceHeader.ColorConfig;
+ WriteBitDepth(ref writer, colorConfig, sequenceHeader);
+ if (sequenceHeader.SequenceProfile != ObuSequenceProfile.High)
+ {
+ writer.WriteBoolean(colorConfig.IsMonochrome);
+ }
+
+ writer.WriteBoolean(colorConfig.IsColorDescriptionPresent);
+ if (colorConfig.IsColorDescriptionPresent)
+ {
+ writer.WriteLiteral((uint)colorConfig.ColorPrimaries, 8);
+ writer.WriteLiteral((uint)colorConfig.TransferCharacteristics, 8);
+ writer.WriteLiteral((uint)colorConfig.MatrixCoefficients, 8);
+ }
+
+ if (colorConfig.IsMonochrome)
+ {
+ writer.WriteBoolean(colorConfig.ColorRange);
+ return;
+ }
+ else if (
+ colorConfig.ColorPrimaries == ObuColorPrimaries.Bt709 &&
+ colorConfig.TransferCharacteristics == ObuTransferCharacteristics.Srgb &&
+ colorConfig.MatrixCoefficients == ObuMatrixCoefficients.Identity)
+ {
+ colorConfig.ColorRange = true;
+ colorConfig.SubSamplingX = false;
+ colorConfig.SubSamplingY = false;
+ }
+ else
+ {
+ writer.WriteBoolean(colorConfig.ColorRange);
+ if (sequenceHeader.SequenceProfile == ObuSequenceProfile.Professional && colorConfig.BitDepth == Av1BitDepth.TwelveBit)
+ {
+ writer.WriteBoolean(colorConfig.SubSamplingX);
+ if (colorConfig.SubSamplingX)
+ {
+ writer.WriteBoolean(colorConfig.SubSamplingY);
+ }
+ }
+
+ if (colorConfig.SubSamplingX && colorConfig.SubSamplingY)
+ {
+ writer.WriteLiteral((uint)colorConfig.ChromaSamplePosition, 2);
+ }
+ }
+
+ writer.WriteBoolean(colorConfig.HasSeparateUvDelta);
+ }
+
+ private static void WriteBitDepth(ref Av1BitStreamWriter writer, ObuColorConfig colorConfig, ObuSequenceHeader sequenceHeader)
+ {
+ bool hasHighBitDepth = colorConfig.BitDepth > Av1BitDepth.EightBit;
+ writer.WriteBoolean(hasHighBitDepth);
+ if (sequenceHeader.SequenceProfile == ObuSequenceProfile.Professional && hasHighBitDepth)
+ {
+ writer.WriteBoolean(colorConfig.BitDepth == Av1BitDepth.TwelveBit);
+ }
+ }
+
+ private static void WriteSuperResolutionParameters(ref Av1BitStreamWriter writer, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader)
+ {
+ bool useSuperResolution = false;
+ if (sequenceHeader.EnableSuperResolution)
+ {
+ writer.WriteBoolean(useSuperResolution);
+ }
+
+ if (useSuperResolution)
+ {
+ writer.WriteLiteral((uint)frameHeader.FrameSize.SuperResolutionDenominator - Av1Constants.SuperResolutionScaleDenominatorMinimum, Av1Constants.SuperResolutionScaleBits);
+ }
+ }
+
+ private static void WriteRenderSize(ref Av1BitStreamWriter writer, ObuFrameHeader frameHeader)
+ {
+ bool renderSizeAndFrameSizeDifferent = false;
+ writer.WriteBoolean(false);
+ if (renderSizeAndFrameSizeDifferent)
+ {
+ writer.WriteLiteral((uint)frameHeader.FrameSize.RenderWidth - 1, 16);
+ writer.WriteLiteral((uint)frameHeader.FrameSize.RenderHeight - 1, 16);
+ }
+ }
+
+ private static void WriteFrameSizeWithReferences(ref Av1BitStreamWriter writer, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader, bool frameSizeOverrideFlag)
+ {
+ bool foundReference = false;
+ for (int i = 0; i < Av1Constants.ReferencesPerFrame; i++)
+ {
+ writer.WriteBoolean(foundReference);
+ if (foundReference)
+ {
+ // Take values over from reference frame
+ break;
+ }
+ }
+
+ if (!foundReference)
+ {
+ WriteFrameSize(ref writer, sequenceHeader, frameHeader, frameSizeOverrideFlag);
+ WriteRenderSize(ref writer, frameHeader);
+ }
+ else
+ {
+ WriteSuperResolutionParameters(ref writer, sequenceHeader, frameHeader);
+ }
+ }
+
+ private static void WriteFrameSize(ref Av1BitStreamWriter writer, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader, bool frameSizeOverrideFlag)
+ {
+ if (frameSizeOverrideFlag)
+ {
+ writer.WriteLiteral((uint)frameHeader.FrameSize.FrameWidth - 1, sequenceHeader.FrameWidthBits + 1);
+ writer.WriteLiteral((uint)frameHeader.FrameSize.FrameHeight - 1, sequenceHeader.FrameHeightBits + 1);
+ }
+
+ WriteSuperResolutionParameters(ref writer, sequenceHeader, frameHeader);
+ }
+
+ private static void WriteTileInfo(ref Av1BitStreamWriter writer, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader)
+ {
+ ObuTileGroupHeader tileInfo = frameHeader.TilesInfo;
+ int superblockColumnCount;
+ int superblockRowCount;
+ int superblockSizeLog2 = sequenceHeader.SuperblockSizeLog2;
+ int superblockShift = superblockSizeLog2 - Av1Constants.ModeInfoSizeLog2;
+ superblockColumnCount = (frameHeader.ModeInfoColumnCount + sequenceHeader.SuperblockModeInfoSize - 1) >> superblockShift;
+ superblockRowCount = (frameHeader.ModeInfoRowCount + sequenceHeader.SuperblockModeInfoSize - 1) >> superblockShift;
+ int superBlockSize = superblockShift + 2;
+ int maxTileAreaOfSuperBlock = Av1Constants.MaxTileArea >> (2 * superBlockSize);
+
+ tileInfo.MaxTileWidthSuperblock = Av1Constants.MaxTileWidth >> superBlockSize;
+ tileInfo.MaxTileHeightSuperblock = (Av1Constants.MaxTileArea / Av1Constants.MaxTileWidth) >> superBlockSize;
+ tileInfo.MinLog2TileColumnCount = ObuReader.TileLog2(tileInfo.MaxTileWidthSuperblock, superblockColumnCount);
+ tileInfo.MaxLog2TileColumnCount = ObuReader.TileLog2(1, Math.Min(superblockColumnCount, Av1Constants.MaxTileColumnCount));
+ tileInfo.MaxLog2TileRowCount = ObuReader.TileLog2(1, Math.Min(superblockRowCount, Av1Constants.MaxTileRowCount));
+ tileInfo.MinLog2TileCount = Math.Max(tileInfo.MinLog2TileColumnCount, ObuReader.TileLog2(maxTileAreaOfSuperBlock, superblockColumnCount * superblockRowCount));
+
+ int log2TileColumnCount = Av1Math.Log2(tileInfo.TileColumnCount);
+ int log2TileRowCount = Av1Math.Log2(tileInfo.TileRowCount);
+
+ writer.WriteBoolean(tileInfo.HasUniformTileSpacing);
+ if (tileInfo.HasUniformTileSpacing)
+ {
+ // Uniform spaced tiles with power-of-two number of rows and columns
+ // tile columns
+ int ones = log2TileColumnCount - tileInfo.MinLog2TileColumnCount;
+ while (ones-- > 0)
+ {
+ writer.WriteBoolean(true);
+ }
+
+ if (log2TileColumnCount < tileInfo.MaxLog2TileColumnCount)
+ {
+ writer.WriteBoolean(false);
+ }
+
+ // rows
+ tileInfo.MinLog2TileRowCount = Math.Min(tileInfo.MinLog2TileCount - log2TileColumnCount, 0);
+ ones = log2TileRowCount - tileInfo.MinLog2TileRowCount;
+ while (ones-- > 0)
+ {
+ writer.WriteBoolean(true);
+ }
+
+ if (log2TileRowCount < tileInfo.MaxLog2TileRowCount)
+ {
+ writer.WriteBoolean(false);
+ }
+ }
+ else
+ {
+ int startSuperBlock = 0;
+ int i = 0;
+ for (; startSuperBlock < superblockColumnCount; i++)
+ {
+ uint widthInSuperBlocks = (uint)((tileInfo.TileColumnStartModeInfo[i] >> superblockShift) - startSuperBlock);
+ uint maxWidth = (uint)Math.Min(superblockColumnCount - startSuperBlock, tileInfo.MaxTileWidthSuperblock);
+ writer.WriteNonSymmetric(widthInSuperBlocks - 1, maxWidth);
+ startSuperBlock += (int)widthInSuperBlocks;
+ }
+
+ if (startSuperBlock != superblockColumnCount)
+ {
+ throw new ImageFormatException("Super block tiles width does not add up to total width.");
+ }
+
+ startSuperBlock = 0;
+ for (i = 0; startSuperBlock < superblockRowCount; i++)
+ {
+ uint heightInSuperBlocks = (uint)((tileInfo.TileRowStartModeInfo[i] >> superblockShift) - startSuperBlock);
+ uint maxHeight = (uint)Math.Min(superblockRowCount - startSuperBlock, tileInfo.MaxTileHeightSuperblock);
+ writer.WriteNonSymmetric(heightInSuperBlocks - 1, maxHeight);
+ startSuperBlock += (int)heightInSuperBlocks;
+ }
+
+ if (startSuperBlock != superblockRowCount)
+ {
+ throw new ImageFormatException("Super block tiles height does not add up to total height.");
+ }
+ }
+
+ if (tileInfo.TileColumnCountLog2 > 0 || tileInfo.TileRowCountLog2 > 0)
+ {
+ writer.WriteLiteral(tileInfo.ContextUpdateTileId, tileInfo.TileRowCountLog2 + tileInfo.TileColumnCountLog2);
+ writer.WriteLiteral((uint)tileInfo.TileSizeBytes - 1, 2);
+ }
+
+ frameHeader.TilesInfo = tileInfo;
+ }
+
+ private void WriteUncompressedFrameHeader(ref Av1BitStreamWriter writer, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader)
+ {
+ // TODO: Make tile count configurable.
+ int tileCount = 1;
+ int planesCount = sequenceHeader.ColorConfig.PlaneCount;
+ writer.WriteBoolean(frameHeader.DisableCdfUpdate);
+ if (sequenceHeader.ForceScreenContentTools == 2)
+ {
+ writer.WriteBoolean(frameHeader.AllowScreenContentTools);
+ }
+ else
+ {
+ // Guard.IsTrue(frameHeader.AllowScreenContentTools == sequenceHeader.ForceScreenContentTools);
+ }
+
+ if (frameHeader.AllowScreenContentTools)
+ {
+ if (sequenceHeader.ForceIntegerMotionVector == 2)
+ {
+ writer.WriteBoolean(frameHeader.ForceIntegerMotionVector);
+ }
+ else
+ {
+ // Guard.IsTrue(frameHeader.ForceIntegerMotionVector == sequenceHeader.ForceIntegerMotionVector, nameof(frameHeader.ForceIntegerMotionVector), "Frame and sequence must be in sync");
+ }
+ }
+
+ if (frameHeader.FrameType == ObuFrameType.KeyFrame)
+ {
+ if (!frameHeader.ShowFrame)
+ {
+ throw new NotImplementedException("No support for hidden frames.");
+ }
+ }
+ else if (frameHeader.FrameType == ObuFrameType.IntraOnlyFrame)
+ {
+ throw new NotImplementedException("No IntraOnly frames supported.");
+ }
+
+ if (frameHeader.FrameType == ObuFrameType.KeyFrame)
+ {
+ WriteFrameSize(ref writer, sequenceHeader, frameHeader, false);
+ WriteRenderSize(ref writer, frameHeader);
+ if (frameHeader.AllowScreenContentTools)
+ {
+ writer.WriteBoolean(frameHeader.AllowIntraBlockCopy);
+ }
+ }
+ else if (frameHeader.FrameType == ObuFrameType.IntraOnlyFrame)
+ {
+ WriteFrameSize(ref writer, sequenceHeader, frameHeader, false);
+ WriteRenderSize(ref writer, frameHeader);
+ if (frameHeader.AllowScreenContentTools)
+ {
+ writer.WriteBoolean(frameHeader.AllowIntraBlockCopy);
+ }
+ }
+ else
+ {
+ throw new NotImplementedException("Inter frames not applicable for AVIF.");
+ }
+
+ WriteTileInfo(ref writer, sequenceHeader, frameHeader);
+ WriteQuantizationParameters(ref writer, sequenceHeader, frameHeader);
+ WriteSegmentationParameters(ref writer, sequenceHeader, frameHeader);
+
+ if (frameHeader.QuantizationParameters.BaseQIndex > 0)
+ {
+ writer.WriteBoolean(frameHeader.DeltaQParameters.IsPresent);
+ if (frameHeader.DeltaQParameters.IsPresent)
+ {
+ writer.WriteLiteral((uint)frameHeader.DeltaQParameters.Resolution - 1, 2);
+ this.previousQIndex = new int[tileCount];
+ for (int tileIndex = 0; tileIndex < tileCount; tileIndex++)
+ {
+ this.previousQIndex[tileIndex] = frameHeader.QuantizationParameters.BaseQIndex;
+ }
+
+ if (frameHeader.AllowIntraBlockCopy)
+ {
+ Guard.IsFalse(
+ frameHeader.DeltaLoopFilterParameters.IsPresent,
+ nameof(frameHeader.DeltaLoopFilterParameters.IsPresent),
+ "Allow INTRA block copy required Loop Filter.");
+ }
+ else
+ {
+ writer.WriteBoolean(frameHeader.DeltaLoopFilterParameters.IsPresent);
+ }
+
+ if (frameHeader.DeltaLoopFilterParameters.IsPresent)
+ {
+ writer.WriteLiteral((uint)(1 + Av1Math.MostSignificantBit((uint)frameHeader.DeltaLoopFilterParameters.Resolution) - 1), 2);
+ writer.WriteBoolean(frameHeader.DeltaLoopFilterParameters.IsMulti);
+ int frameLoopFilterCount = sequenceHeader.ColorConfig.IsMonochrome ? Av1Constants.FrameLoopFilterCount - 2 : Av1Constants.FrameLoopFilterCount;
+ this.previousDeltaLoopFilter = new int[frameLoopFilterCount];
+ for (int loopFilterId = 0; loopFilterId < frameLoopFilterCount; loopFilterId++)
+ {
+ this.previousDeltaLoopFilter[loopFilterId] = 0;
+ }
+ }
+ }
+ }
+
+ if (frameHeader.AllLossless)
+ {
+ throw new NotImplementedException("No entire lossless supported.");
+ }
+ else
+ {
+ if (!frameHeader.CodedLossless)
+ {
+ WriteLoopFilterParameters(ref writer, sequenceHeader, frameHeader);
+ if (sequenceHeader.CdefLevel > 0)
+ {
+ WriteCdefParameters(ref writer, sequenceHeader, frameHeader);
+ }
+ }
+
+ if (sequenceHeader.EnableRestoration)
+ {
+ WriteLoopRestorationParameters(ref writer, sequenceHeader, frameHeader);
+ }
+ }
+
+ // No Frame Reference mode selection for AVIF
+ WriteTransformMode(ref writer, frameHeader);
+
+ // No compound INTER-INTER for AVIF.
+ WriteFrameReferenceMode(ref writer, frameHeader);
+ WriteSkipModeParameters(ref writer, frameHeader);
+
+ // No warp motion for AVIF.
+ writer.WriteBoolean(frameHeader.UseReducedTransformSet);
+
+ WriteGlobalMotionParameters(ref writer, frameHeader);
+ WriteFilmGrainFilterParameters(ref writer, sequenceHeader, frameHeader);
+ }
+
+ private static bool IsSegmentationFeatureActive(ObuSegmentationParameters segmentationParameters, int segmentId, ObuSegmentationLevelFeature feature)
+ => segmentationParameters.Enabled && segmentationParameters.FeatureEnabled[segmentId, (int)feature];
+
+ private int WriteFrameHeader(ref Av1BitStreamWriter writer, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader, bool writeTrailingBits)
+ {
+ int startBitPosition = writer.BitPosition;
+ this.WriteUncompressedFrameHeader(ref writer, sequenceHeader, frameHeader);
+ if (writeTrailingBits)
+ {
+ WriteTrailingBits(ref writer);
+ }
+
+ int endPosition = writer.BitPosition;
+ int headerBytes = (endPosition - startBitPosition) / 8;
+ return headerBytes;
+ }
+
+ ///
+ /// 5.11.1. General tile group OBU syntax.
+ ///
+ private static int WriteTileGroup(ref Av1BitStreamWriter writer, ObuTileGroupHeader tileInfo, IAv1TileWriter tileWriter)
+ {
+ int tileCount = tileInfo.TileColumnCount * tileInfo.TileRowCount;
+ int startBitPosition = writer.BitPosition;
+ bool tileStartAndEndPresentFlag = tileCount > 1;
+ writer.WriteBoolean(tileStartAndEndPresentFlag);
+
+ uint tileGroupStart = 0U;
+ uint tileGroupEnd = (uint)tileCount - 1U;
+ if (tileCount != 1)
+ {
+ int tileBits = Av1Math.Log2(tileInfo.TileColumnCount) + Av1Math.Log2(tileInfo.TileRowCount);
+ writer.WriteLiteral(tileGroupStart, tileBits);
+ writer.WriteLiteral(tileGroupEnd, tileBits);
+ }
+
+ AlignToByteBoundary(ref writer);
+
+ WriteTileData(ref writer, tileInfo, tileWriter);
+
+ int endBitPosition = writer.BitPosition;
+ int headerBytes = (endBitPosition - startBitPosition) / 8;
+ return headerBytes;
+ }
+
+ private static void WriteTileData(ref Av1BitStreamWriter writer, ObuTileGroupHeader tileInfo, IAv1TileWriter tileWriter)
+ {
+ int tileCount = tileInfo.TileColumnCount * tileInfo.TileRowCount;
+ for (int tileNum = 0; tileNum < tileCount; tileNum++)
+ {
+ Span tileData = tileWriter.WriteTile(tileNum);
+ if (tileNum != tileCount - 1 && tileCount > 1)
+ {
+ writer.WriteLittleEndian((uint)tileData.Length - 1U, tileInfo.TileSizeBytes);
+ }
+
+ writer.WriteBlob(tileData);
+ }
+ }
+
+ private static int WriteDeltaQ(ref Av1BitStreamWriter writer, int deltaQ)
+ {
+ bool isCoded = deltaQ != 0;
+ writer.WriteBoolean(isCoded);
+ if (isCoded)
+ {
+ writer.WriteSignedFromUnsigned(deltaQ, 7);
+ }
+
+ return deltaQ;
+ }
+
+ private static void WriteFrameDeltaQParameters(ref Av1BitStreamWriter writer, ObuFrameHeader frameHeader)
+ {
+ if (frameHeader.QuantizationParameters.BaseQIndex > 0)
+ {
+ writer.WriteBoolean(frameHeader.DeltaQParameters.IsPresent);
+ }
+
+ if (frameHeader.DeltaQParameters.IsPresent)
+ {
+ writer.WriteLiteral((uint)frameHeader.DeltaQParameters.Resolution, 2);
+ }
+ }
+
+ private static void WriteFrameDeltaLoopFilterParameters(ref Av1BitStreamWriter writer, ObuFrameHeader frameHeader)
+ {
+ if (frameHeader.DeltaQParameters.IsPresent)
+ {
+ if (!frameHeader.AllowIntraBlockCopy)
+ {
+ writer.WriteBoolean(frameHeader.DeltaLoopFilterParameters.IsPresent);
+ }
+
+ if (frameHeader.DeltaLoopFilterParameters.IsPresent)
+ {
+ writer.WriteLiteral((uint)frameHeader.DeltaLoopFilterParameters.Resolution, 2);
+ writer.WriteBoolean(frameHeader.DeltaLoopFilterParameters.IsMulti);
+ }
+ }
+ }
+
+ ///
+ /// See section 5.9.12.
+ ///
+ private static void WriteQuantizationParameters(ref Av1BitStreamWriter writer, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader)
+ {
+ ObuQuantizationParameters quantParams = frameHeader.QuantizationParameters;
+ writer.WriteLiteral((uint)quantParams.BaseQIndex, 8);
+ WriteDeltaQ(ref writer, quantParams.DeltaQDc[(int)Av1Plane.Y]);
+ if (sequenceHeader.ColorConfig.PlaneCount > 1)
+ {
+ if (sequenceHeader.ColorConfig.HasSeparateUvDelta)
+ {
+ writer.WriteBoolean(quantParams.HasSeparateUvDelta);
+ }
+
+ WriteDeltaQ(ref writer, quantParams.DeltaQDc[(int)Av1Plane.U]);
+ WriteDeltaQ(ref writer, quantParams.DeltaQAc[(int)Av1Plane.U]);
+ if (quantParams.HasSeparateUvDelta)
+ {
+ WriteDeltaQ(ref writer, quantParams.DeltaQDc[(int)Av1Plane.V]);
+ WriteDeltaQ(ref writer, quantParams.DeltaQAc[(int)Av1Plane.V]);
+ }
+ }
+
+ writer.WriteBoolean(quantParams.IsUsingQMatrix);
+ if (quantParams.IsUsingQMatrix)
+ {
+ writer.WriteLiteral((uint)quantParams.QMatrix[(int)Av1Plane.Y], 4);
+ writer.WriteLiteral((uint)quantParams.QMatrix[(int)Av1Plane.U], 4);
+ if (sequenceHeader.ColorConfig.HasSeparateUvDelta)
+ {
+ writer.WriteLiteral((uint)quantParams.QMatrix[(int)Av1Plane.V], 4);
+ }
+ }
+ }
+
+ private static void WriteSegmentationParameters(ref Av1BitStreamWriter writer, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader)
+ {
+ _ = sequenceHeader;
+ Guard.IsFalse(frameHeader.SegmentationParameters.Enabled, nameof(frameHeader.SegmentationParameters.Enabled), "Segmentation not supported yet.");
+ writer.WriteBoolean(false);
+ }
+
+ ///
+ /// 5.9.11. Loop filter params syntax
+ ///
+ private static void WriteLoopFilterParameters(ref Av1BitStreamWriter writer, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader)
+ {
+ if (frameHeader.CodedLossless || frameHeader.AllowIntraBlockCopy)
+ {
+ return;
+ }
+
+ writer.WriteLiteral((uint)frameHeader.LoopFilterParameters.FilterLevel[0], 6);
+ writer.WriteLiteral((uint)frameHeader.LoopFilterParameters.FilterLevel[1], 6);
+ if (sequenceHeader.ColorConfig.PlaneCount > 1)
+ {
+ if (frameHeader.LoopFilterParameters.FilterLevel[0] > 0 || frameHeader.LoopFilterParameters.FilterLevel[1] > 0)
+ {
+ writer.WriteLiteral((uint)frameHeader.LoopFilterParameters.FilterLevelU, 6);
+ writer.WriteLiteral((uint)frameHeader.LoopFilterParameters.FilterLevelV, 6);
+ }
+ }
+
+ writer.WriteLiteral((uint)frameHeader.LoopFilterParameters.SharpnessLevel, 3);
+ writer.WriteBoolean(frameHeader.LoopFilterParameters.ReferenceDeltaModeEnabled);
+ if (frameHeader.LoopFilterParameters.ReferenceDeltaModeEnabled)
+ {
+ writer.WriteBoolean(frameHeader.LoopFilterParameters.ReferenceDeltaModeUpdate);
+ if (frameHeader.LoopFilterParameters.ReferenceDeltaModeUpdate)
+ {
+ throw new NotImplementedException("Reference update of loop filter not supported yet.");
+ }
+ }
+ }
+
+ ///
+ /// 5.9.21. TX mode syntax.
+ ///
+ private static void WriteTransformMode(ref Av1BitStreamWriter writer, ObuFrameHeader frameHeader)
+ {
+ if (!frameHeader.CodedLossless)
+ {
+ writer.WriteBoolean(frameHeader.TransformMode == Av1TransformMode.Select);
+ }
+ }
+
+ private static void WriteLoopRestorationParameters(ref Av1BitStreamWriter writer, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader)
+ {
+ if (frameHeader.CodedLossless || frameHeader.AllowIntraBlockCopy || !sequenceHeader.EnableRestoration)
+ {
+ return;
+ }
+
+ int planesCount = sequenceHeader.ColorConfig.PlaneCount;
+ for (int i = 0; i < planesCount; i++)
+ {
+ writer.WriteLiteral((uint)frameHeader.LoopRestorationParameters.Items[i].Type, 2);
+ }
+
+ if (frameHeader.LoopRestorationParameters.UsesLoopRestoration)
+ {
+ uint unitShift = (uint)frameHeader.LoopRestorationParameters.UnitShift;
+ if (sequenceHeader.Use128x128Superblock)
+ {
+ writer.WriteLiteral(unitShift - 1, 1);
+ }
+ else
+ {
+ writer.WriteLiteral(unitShift & 0x01, 1);
+ if (unitShift > 0)
+ {
+ writer.WriteLiteral(unitShift - 1, 1);
+ }
+ }
+
+ if (sequenceHeader.ColorConfig.SubSamplingX && sequenceHeader.ColorConfig.SubSamplingY && frameHeader.LoopRestorationParameters.UsesChromaLoopRestoration)
+ {
+ writer.WriteLiteral((uint)frameHeader.LoopRestorationParameters.UVShift, 1);
+ }
+ }
+ }
+
+ private static void WriteCdefParameters(ref Av1BitStreamWriter writer, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader)
+ {
+ _ = writer;
+ _ = sequenceHeader;
+
+ if (frameHeader.CodedLossless || frameHeader.AllowIntraBlockCopy || !sequenceHeader.EnableCdef)
+ {
+ return;
+ }
+
+ throw new NotImplementedException("Didn't implement writing CDEF yet.");
+ }
+
+ private static void WriteGlobalMotionParameters(ref Av1BitStreamWriter writer, ObuFrameHeader frameHeader)
+ {
+ _ = writer;
+
+ if (frameHeader.IsIntra)
+ {
+ // Nothing to be written for INTRA frames.
+ return;
+ }
+
+ throw new InvalidImageContentException("AVIF files can only contain INTRA frames.");
+ }
+
+ private static void WriteFrameReferenceMode(ref Av1BitStreamWriter writer, ObuFrameHeader frameHeader)
+ {
+ _ = writer;
+
+ if (frameHeader.IsIntra)
+ {
+ // Nothing to be written for INTRA frames.
+ return;
+ }
+
+ throw new InvalidImageContentException("AVIF files can only contain INTRA frames.");
+ }
+
+ private static void WriteSkipModeParameters(ref Av1BitStreamWriter writer, ObuFrameHeader frameHeader)
+ {
+ if (frameHeader.SkipModeParameters.SkipModeAllowed)
+ {
+ writer.WriteBoolean(frameHeader.SkipModeParameters.SkipModeFlag);
+ }
+ }
+
+ private static void WriteFilmGrainFilterParameters(ref Av1BitStreamWriter writer, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader)
+ {
+ ObuFilmGrainParameters grainParams = frameHeader.FilmGrainParameters;
+ if (!sequenceHeader.AreFilmGrainingParametersPresent || (!frameHeader.ShowFrame && !frameHeader.ShowableFrame))
+ {
+ return;
+ }
+
+ writer.WriteBoolean(grainParams.ApplyGrain);
+ if (!grainParams.ApplyGrain)
+ {
+ return;
+ }
+
+ writer.WriteLiteral(grainParams.GrainSeed, 16);
+ writer.WriteLiteral(grainParams.NumYPoints, 4);
+ Guard.NotNull(grainParams.PointYValue);
+ Guard.NotNull(grainParams.PointYScaling);
+ for (int i = 0; i < grainParams.NumYPoints; i++)
+ {
+ writer.WriteLiteral(grainParams.PointYValue[i], 8);
+ writer.WriteLiteral(grainParams.PointYScaling[i], 8);
+ }
+
+ if (!sequenceHeader.ColorConfig.IsMonochrome)
+ {
+ writer.WriteBoolean(grainParams.ChromaScalingFromLuma);
+ }
+
+ if (!sequenceHeader.ColorConfig.IsMonochrome &&
+ !grainParams.ChromaScalingFromLuma &&
+ (!sequenceHeader.ColorConfig.SubSamplingX || !sequenceHeader.ColorConfig.SubSamplingY || grainParams.NumYPoints != 0))
+ {
+ writer.WriteLiteral(grainParams.NumCbPoints, 4);
+ Guard.NotNull(grainParams.PointCbValue);
+ Guard.NotNull(grainParams.PointCbScaling);
+ for (int i = 0; i < grainParams.NumCbPoints; i++)
+ {
+ writer.WriteLiteral(grainParams.PointCbValue[i], 8);
+ writer.WriteLiteral(grainParams.PointCbScaling[i], 8);
+ }
+
+ writer.WriteLiteral(grainParams.NumCrPoints, 4);
+ Guard.NotNull(grainParams.PointCrValue);
+ Guard.NotNull(grainParams.PointCrScaling);
+ for (int i = 0; i < grainParams.NumCbPoints; i++)
+ {
+ writer.WriteLiteral(grainParams.PointCrValue[i], 8);
+ writer.WriteLiteral(grainParams.PointCrScaling[i], 8);
+ }
+ }
+
+ writer.WriteLiteral(grainParams.GrainScalingMinus8, 2);
+ writer.WriteLiteral(grainParams.ArCoeffLag, 2);
+ uint numPosLuma = 2 * grainParams.ArCoeffLag * (grainParams.ArCoeffLag + 1);
+
+ uint numPosChroma = 0;
+ if (grainParams.NumYPoints != 0)
+ {
+ numPosChroma = numPosLuma + 1;
+ Guard.NotNull(grainParams.ArCoeffsYPlus128);
+ for (int i = 0; i < numPosLuma; i++)
+ {
+ writer.WriteLiteral(grainParams.ArCoeffsYPlus128[i], 8);
+ }
+ }
+
+ if (grainParams.ChromaScalingFromLuma || grainParams.NumCbPoints != 0)
+ {
+ Guard.NotNull(grainParams.ArCoeffsCbPlus128);
+ for (int i = 0; i < numPosChroma; i++)
+ {
+ writer.WriteLiteral(grainParams.ArCoeffsCbPlus128[i], 8);
+ }
+ }
+
+ if (grainParams.ChromaScalingFromLuma || grainParams.NumCrPoints != 0)
+ {
+ Guard.NotNull(grainParams.ArCoeffsCrPlus128);
+ for (int i = 0; i < numPosChroma; i++)
+ {
+ writer.WriteLiteral(grainParams.ArCoeffsCrPlus128[i], 8);
+ }
+ }
+
+ writer.WriteLiteral(grainParams.ArCoeffShiftMinus6, 2);
+ writer.WriteLiteral(grainParams.GrainScaleShift, 2);
+ if (grainParams.NumCbPoints != 0)
+ {
+ writer.WriteLiteral(grainParams.CbMult, 8);
+ writer.WriteLiteral(grainParams.CbLumaMult, 8);
+ writer.WriteLiteral(grainParams.CbOffset, 9);
+ }
+
+ if (grainParams.NumCrPoints != 0)
+ {
+ writer.WriteLiteral(grainParams.CrMult, 8);
+ writer.WriteLiteral(grainParams.CrLumaMult, 8);
+ writer.WriteLiteral(grainParams.CrOffset, 9);
+ }
+
+ writer.WriteBoolean(grainParams.OverlapFlag);
+ writer.WriteBoolean(grainParams.ClipToRestrictedRange);
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/Av1FrameDecoder.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/Av1FrameDecoder.cs
new file mode 100644
index 0000000000..391e26d52b
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/Av1FrameDecoder.cs
@@ -0,0 +1,171 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.Quantification;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline;
+
+internal class Av1FrameDecoder : IAv1FrameDecoder
+{
+ private readonly ObuSequenceHeader sequenceHeader;
+ private readonly ObuFrameHeader frameHeader;
+ private readonly Av1FrameInfo frameInfo;
+ private readonly Av1FrameBuffer frameBuffer;
+ private readonly Av1InverseQuantizer inverseQuantizer;
+ private readonly Av1DeQuantizationContext deQuants;
+ private readonly Av1BlockDecoder blockDecoder;
+
+ public Av1FrameDecoder(ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader, Av1FrameInfo frameInfo, Av1FrameBuffer frameBuffer)
+ {
+ this.sequenceHeader = sequenceHeader;
+ this.frameHeader = frameHeader;
+ this.frameInfo = frameInfo;
+ this.frameBuffer = frameBuffer;
+ this.inverseQuantizer = new(sequenceHeader, frameHeader);
+ this.deQuants = new(sequenceHeader, frameHeader);
+ this.blockDecoder = new(this.sequenceHeader, this.frameHeader, this.frameInfo, this.frameBuffer);
+ }
+
+ public void DecodeFrame()
+ {
+ for (int column = 0; column < this.frameHeader.TilesInfo.TileColumnCount; column++)
+ {
+ this.DecodeFrameTiles(column);
+ }
+
+ bool doLoopFilterFlag = false;
+ bool doLoopRestoration = false;
+ bool doUpscale = false;
+ if (doLoopFilterFlag)
+ {
+ this.DecodeLoopFilterForFrame();
+ }
+
+ if (doLoopRestoration)
+ {
+ // LoopRestorationSaveBoundaryLines(false);
+ }
+
+ // DecodeCdef();
+ // SuperResolutionUpscaling(doUpscale);
+ if (doLoopRestoration && doUpscale)
+ {
+ // LoopRestorationSaveBoundaryLines(true);
+ }
+
+ // DecodeLoopRestoration(doLoopRestoration);
+ // PadPicture();
+ }
+
+ ///
+ /// SVT: decode_tile
+ ///
+ private void DecodeFrameTiles(int tileColumn)
+ {
+ int tileRowCount = this.frameHeader.TilesInfo.TileRowCount;
+ int tileCount = tileRowCount * this.frameHeader.TilesInfo.TileColumnCount;
+ for (int row = 0; row < tileRowCount; row++)
+ {
+ int superblockRowTileStart = this.frameHeader.TilesInfo.TileRowStartModeInfo[row] << Av1Constants.ModeInfoSizeLog2 >>
+ this.sequenceHeader.SuperblockSizeLog2;
+ int superblockRow = row + superblockRowTileStart;
+
+ int modeInfoRow = superblockRow << this.sequenceHeader.SuperblockSizeLog2 >> Av1Constants.ModeInfoSizeLog2;
+
+ // EbColorConfig* color_config = &dec_mod_ctxt->seq_header->color_config;
+ // svt_cfl_init(&dec_mod_ctxt->cfl_ctx, color_config);
+ this.DecodeTileRow(row, tileColumn, modeInfoRow, superblockRow);
+ }
+ }
+
+ ///
+ /// SVT: decode_tile_row
+ ///
+ private void DecodeTileRow(int tileRow, int tileColumn, int modeInfoRow, int superblockRow)
+ {
+ int superblockModeInfoSizeLog2 = this.sequenceHeader.SuperblockSizeLog2 - Av1Constants.ModeInfoSizeLog2;
+ int superblockRowTileStart = this.frameHeader.TilesInfo.TileRowStartModeInfo[tileRow] << Av1Constants.ModeInfoSizeLog2 >>
+ this.sequenceHeader.SuperblockSizeLog2;
+
+ int superblockRowInTile = superblockRow - superblockRowTileStart;
+
+ ObuTileGroupHeader tileInfo = this.frameHeader.TilesInfo;
+ for (int modeInfoColumn = tileInfo.TileColumnStartModeInfo[tileColumn]; modeInfoColumn < tileInfo.TileColumnStartModeInfo[tileColumn + 1];
+ modeInfoColumn += this.sequenceHeader.SuperblockModeInfoSize)
+ {
+ int superblockColumn = modeInfoColumn << Av1Constants.ModeInfoSizeLog2 >> this.sequenceHeader.SuperblockSizeLog2;
+
+ Av1SuperblockInfo superblockInfo = this.frameInfo.GetSuperblock(new Point(superblockColumn, superblockRow));
+
+ Point modeInfoPosition = new(modeInfoColumn, modeInfoRow);
+ this.DecodeSuperblock(modeInfoPosition, superblockInfo, new Av1TileInfo(tileRow, tileColumn, this.frameHeader));
+ }
+ }
+
+ ///
+ /// SVT: svt_aom_decode_super_block
+ ///
+ public void DecodeSuperblock(Point modeInfoPosition, Av1SuperblockInfo superblockInfo, Av1TileInfo tileInfo)
+ {
+ this.blockDecoder.UpdateSuperblock(superblockInfo);
+ this.inverseQuantizer.UpdateDequant(this.deQuants, superblockInfo);
+ this.DecodePartition(modeInfoPosition, superblockInfo, tileInfo);
+ }
+
+ ///
+ /// SVT: decode_partition
+ ///
+ private void DecodePartition(Point modeInfoPosition, Av1SuperblockInfo superblockInfo, Av1TileInfo tileInfo)
+ {
+ Av1BlockModeInfo modeInfo = superblockInfo.GetModeInfo(modeInfoPosition);
+
+ for (int i = 0; i < superblockInfo.BlockCount; i++)
+ {
+ Point subPosition = modeInfo.PositionInSuperblock;
+ Av1BlockSize subSize = modeInfo.BlockSize;
+ Point globalPosition = new(modeInfoPosition.X, modeInfoPosition.Y);
+ globalPosition.Offset(subPosition);
+ this.blockDecoder.DecodeBlock(modeInfo, globalPosition, subSize, superblockInfo, tileInfo);
+ }
+ }
+
+ private void DecodeLoopFilterForFrame()
+ {
+ int superblockSizeLog2 = this.sequenceHeader.SuperblockSizeLog2;
+ int pictureWidthInSuperblocks = Av1Math.DivideLog2Ceiling(this.frameHeader.FrameSize.FrameWidth, this.sequenceHeader.SuperblockSizeLog2);
+ int pictureHeightInSuperblocks = Av1Math.DivideLog2Ceiling(this.frameHeader.FrameSize.FrameHeight, this.sequenceHeader.SuperblockSizeLog2);
+
+ // Loop over a frame : tregger dec_loop_filter_sb for each SB
+ for (int superblockIndexY = 0; superblockIndexY < pictureHeightInSuperblocks; ++superblockIndexY)
+ {
+ for (int superblockIndexX = 0; superblockIndexX < pictureWidthInSuperblocks; ++superblockIndexX)
+ {
+ int superblockOriginX = superblockIndexX << superblockSizeLog2;
+ int superblockOriginY = superblockIndexY << superblockSizeLog2;
+ bool endOfRowFlag = superblockIndexX == pictureWidthInSuperblocks - 1;
+
+ Point superblockPoint = new(superblockOriginX, superblockOriginY);
+ Av1SuperblockInfo superblockInfo = this.frameInfo.GetSuperblock(superblockPoint);
+
+ // LF function for a SB
+ /*
+ DecodeLoopFilterForSuperblock(
+ superblockInfo,
+ this.frameHeader,
+ this.sequenceHeader,
+ reconstructionFrameBuffer,
+ loopFilterContext,
+ superblockOriginY >> 2,
+ superblockOriginX >> 2,
+ Av1Plane.Y,
+ 3,
+ endOfRowFlag,
+ superblockInfo.SuperblockDeltaLoopFilter);
+ */
+ }
+ }
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/Av1FrameEncoder.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/Av1FrameEncoder.cs
new file mode 100644
index 0000000000..6bdd55ac54
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/Av1FrameEncoder.cs
@@ -0,0 +1,74 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline;
+
+internal class Av1FrameEncoder
+{
+ private readonly Av1FrameBuffer frameBuffer;
+
+ public Av1FrameEncoder(Av1FrameBuffer frameBuffer)
+ {
+ this.frameBuffer = frameBuffer;
+ }
+
+ ///
+ /// SVT: svt_av1_enc_init
+ ///
+ public static void Encode()
+ {
+ /************************************
+ * Thread Handles
+ ************************************/
+
+ // Resource Coordination
+ // Single thread calling svt_aom_resource_coordination_kernel with context enc_handle_ptr->resource_coordination_context_ptr
+ // Multiple threads calling svt_aom_picture_analysis_kernel, with context enc_handle_ptr->picture_analysis_context_ptr_array
+
+ // Picture Decision
+ // Single thread calling svt_aom_picture_decision_kernel with context enc_handle_ptr->picture_decision_context_ptr
+
+ // Motion Estimation
+ // Multiple threads calling svt_aom_motion_estimation_kernel with context enc_handle_ptr->motion_estimation_context_ptr_array
+
+ // Initial Rate Control
+ // Single thread calling svt_aom_initial_rate_control_kernel with context enc_handle_ptr->initial_rate_control_context_ptr
+
+ // Source Based Oprations
+ // source_based_operations_context_ptr_array
+
+ // TPL dispenser
+ // Multiple threads calling svt_aom_tpl_disp_kernel with context enc_handle_ptr->tpl_disp_context_ptr_array
+
+ // Picture Manager
+ // Single thread calling svt_aom_picture_manager_kernel with context enc_handle_ptr->picture_manager_context_ptr
+
+ // Rate Control
+ // Single thread calling svt_aom_rate_control_kernel with context enc_handle_ptr->rate_control_context_ptr
+
+ // Mode Decision Configuration Process
+ // Multiple threads calling svt_aom_mode_decision_configuration_kernel with context enc_handle_ptr->mode_decision_configuration_context_ptr_array
+
+ // EncDec Process
+ // Multiple threads calling svt_aom_mode_decision_kernel enc_handle_ptr->enc_dec_context_ptr_array
+
+ // Dlf Process
+ // Multiple threads calling svt_aom_dlf_kernel with context enc_handle_ptr->dlf_context_ptr_array
+
+ // Cdef Process
+ // Multiple threads calling svt_aom_cdef_kernel enc_handle_ptr->cdef_context_ptr_array
+
+ // Rest Process
+ // Multiple threads calling svt_aom_rest_kernel enc_handle_ptr->rest_context_ptr_array
+
+ // Entropy Coding Process
+ // Multiple threads calling svt_aom_entropy_coding_kernel enc_handle_ptr->entropy_coding_context_ptr_array
+
+ // Packetization
+ // Single thread calling svt_aom_packetization_kernel with context enc_handle_ptr->packetization_context_ptr
+
+ // svt_print_memory_usage();
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/IAv1FrameDecoder.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/IAv1FrameDecoder.cs
new file mode 100644
index 0000000000..1204e8bc1b
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/IAv1FrameDecoder.cs
@@ -0,0 +1,20 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline;
+
+///
+/// Interface for decoder of a single frame.
+///
+internal interface IAv1FrameDecoder
+{
+ ///
+ /// Decode a single superblock.
+ ///
+ /// The top left position of the superblock, in mode info units.
+ /// The superblock to decode
+ /// The tile in whcih the superblock is positioned.
+ void DecodeSuperblock(Point modeInfoPosition, Av1SuperblockInfo superblockInfo, Av1TileInfo tileInfo);
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopFilter/Av1LoopFilterContext.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopFilter/Av1LoopFilterContext.cs
new file mode 100644
index 0000000000..91b036ff6a
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopFilter/Av1LoopFilterContext.cs
@@ -0,0 +1,8 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.LoopFilter;
+
+internal class Av1LoopFilterContext
+{
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopFilter/Av1LoopFilterDecoder.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopFilter/Av1LoopFilterDecoder.cs
new file mode 100644
index 0000000000..bf0c83c956
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/LoopFilter/Av1LoopFilterDecoder.cs
@@ -0,0 +1,68 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.LoopFilter;
+
+internal class Av1LoopFilterDecoder
+{
+ private readonly ObuSequenceHeader sequenceHeader;
+ private readonly ObuFrameHeader frameHeader;
+ private readonly Av1FrameInfo frameInfo;
+ private readonly Av1FrameBuffer frameBuffer;
+ private readonly Av1LoopFilterContext loopFilterContext;
+
+ public Av1LoopFilterDecoder(ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader, Av1FrameInfo frameInfo, Av1FrameBuffer frameBuffer)
+ {
+ this.sequenceHeader = sequenceHeader;
+ this.frameHeader = frameHeader;
+ this.frameInfo = frameInfo;
+ this.frameBuffer = frameBuffer;
+ this.loopFilterContext = new();
+ }
+
+ public void DecodeFrame(bool doLoopFilterFlag)
+ {
+ Guard.NotNull(this.sequenceHeader);
+ Guard.NotNull(this.frameHeader);
+ Guard.NotNull(this.frameInfo);
+
+ if (!doLoopFilterFlag)
+ {
+ return;
+ }
+
+ int superblockSizeLog2 = this.sequenceHeader.SuperblockSizeLog2;
+ int frameWidthInSuperblocks = Av1Math.DivideLog2Ceiling(this.frameHeader.FrameSize.FrameWidth, this.sequenceHeader.SuperblockSizeLog2);
+ int frameHeightInSuperblocks = Av1Math.DivideLog2Ceiling(this.frameHeader.FrameSize.FrameHeight, this.sequenceHeader.SuperblockSizeLog2);
+
+ // Loop over a frame : tregger dec_loop_filter_sb for each SB
+ for (int superblockIndexY = 0; superblockIndexY < frameHeightInSuperblocks; ++superblockIndexY)
+ {
+ for (int superblockIndexX = 0; superblockIndexX < frameWidthInSuperblocks; ++superblockIndexX)
+ {
+ int superblockOriginX = superblockIndexX << superblockSizeLog2;
+ int superblockOriginY = superblockIndexY << superblockSizeLog2;
+ bool endOfRowFlag = superblockIndexX == frameWidthInSuperblocks - 1;
+
+ Point superblockPoint = new(superblockOriginX, superblockOriginY);
+ Av1SuperblockInfo superblockInfo = this.frameInfo.GetSuperblock(superblockPoint);
+ Point superblockOriginInModeInfo = new(superblockOriginX >> 2, superblockOriginY >> 2);
+
+ // LF function for a SB
+ this.DecodeForSuperblock(
+ superblockInfo,
+ superblockOriginInModeInfo,
+ Av1Plane.Y,
+ 3,
+ endOfRowFlag,
+ superblockInfo.SuperblockDeltaLoopFilter);
+ }
+ }
+ }
+
+ private void DecodeForSuperblock(Av1SuperblockInfo superblockInfo, Point modeInfoLocation, Av1Plane startPlane, int endPlane, bool endOfRowFlag, Span superblockDeltaLoopFilter)
+ => throw new NotImplementedException();
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/Quantification/Av1DeQuantizationContext.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/Quantification/Av1DeQuantizationContext.cs
new file mode 100644
index 0000000000..414d28f92f
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/Quantification/Av1DeQuantizationContext.cs
@@ -0,0 +1,49 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.Quantification;
+
+internal class Av1DeQuantizationContext
+{
+ private readonly short[][] dcContent;
+ private readonly short[][] acContent;
+
+ ///
+ /// SVT: svt_aom_setup_segmentation_dequant
+ ///
+ public Av1DeQuantizationContext(ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader)
+ {
+ Av1BitDepth bitDepth = sequenceHeader.ColorConfig.BitDepth;
+ this.dcContent = new short[Av1Constants.MaxSegmentCount][];
+ this.acContent = new short[Av1Constants.MaxSegmentCount][];
+ for (int segmentId = 0; segmentId < Av1Constants.MaxSegmentCount; segmentId++)
+ {
+ this.dcContent[segmentId] = new short[Av1Constants.MaxPlanes];
+ this.acContent[segmentId] = new short[Av1Constants.MaxPlanes];
+ int qindex = Av1QuantizationLookup.GetQIndex(frameHeader.SegmentationParameters, segmentId, frameHeader.QuantizationParameters.BaseQIndex);
+
+ for (int plane = 0; plane < Av1Constants.MaxPlanes; plane++)
+ {
+ int dc_delta_q = frameHeader.QuantizationParameters.DeltaQDc[plane];
+ int ac_delta_q = frameHeader.QuantizationParameters.DeltaQAc[plane];
+
+ this.dcContent[segmentId][plane] = Av1QuantizationLookup.GetDcQuant(qindex, dc_delta_q, bitDepth);
+ this.acContent[segmentId][plane] = Av1QuantizationLookup.GetAcQuant(qindex, ac_delta_q, bitDepth);
+ }
+ }
+ }
+
+ public short GetDc(int segmentId, Av1Plane plane)
+ => this.dcContent[segmentId][(int)plane];
+
+ public short GetAc(int segmentId, Av1Plane plane)
+ => this.acContent[segmentId][(int)plane];
+
+ public void SetAc(int segmentId, Av1Plane plane, short value)
+ => this.dcContent[segmentId][(int)plane] = value;
+
+ public void SetDc(int segmentId, Av1Plane plane, short value)
+ => this.dcContent[segmentId][(int)plane] = value;
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/Quantification/Av1InverseQuantizationLookup.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/Quantification/Av1InverseQuantizationLookup.cs
new file mode 100644
index 0000000000..29c29b44ba
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/Quantification/Av1InverseQuantizationLookup.cs
@@ -0,0 +1,6803 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.Quantification;
+
+internal class Av1InverseQuantizationLookup
+{
+ ///
+ /// Gets 16 sets of quantization matrices for chroma and luma and each TX size.
+ /// Matrices for different TX sizes are in fact sub-sampled from the 32x32 and 16x16 sizes,
+ /// but explicitly defined here for convenience. Intra and inter matrix sets are the
+ /// same but changing DEFAULT_QM_INTER_OFFSET from zero allows for different matrices
+ /// for inter and intra blocks in the same frame.
+ /// Matrices for different QM levels have been rescaled in the frequency domain according
+ /// to different nominal viewing distances.
+ ///
+ private static int[][][][] InverseWeightTable =>
+ [
+ [
+ [
+ /* Luma */
+ /* Size 4x4 */
+ [32, 43, 73, 97, 43, 67, 94, 110, 73, 94, 137, 150, 97, 110, 150, 200],
+ /* Size 8x8 */
+ [32, 32, 38, 51, 68, 84, 95, 109, 32, 35, 40, 49, 63, 76, 89, 102, 38,
+ 40, 54, 65, 78, 91, 98, 106, 51, 49, 65, 82, 97, 111, 113, 121, 68, 63,
+ 78, 97, 117, 134, 138, 142, 84, 76, 91, 111, 134, 152, 159, 168, 95, 89,
+ 98, 113, 138, 159, 183, 199, 109, 102, 106, 121, 142, 168, 199, 220],
+ /* Size 16x16 */
+ [32, 31, 31, 34, 36, 44, 48, 59, 65, 80, 83, 91, 97, 104, 111, 119, 31,
+ 32, 32, 33, 34, 41, 44, 54, 59, 72, 75, 83, 90, 97, 104, 112, 31, 32,
+ 33, 35, 36, 42, 45, 54, 59, 71, 74, 81, 86, 93, 100, 107, 34, 33, 35,
+ 39, 42, 47, 51, 58, 63, 74, 76, 81, 84, 90, 97, 105, 36, 34, 36, 42, 48,
+ 54, 57, 64, 68, 79, 81, 88, 91, 96, 102, 105, 44, 41, 42, 47, 54, 63,
+ 67, 75, 79, 90, 92, 95, 100, 102, 109, 112, 48, 44, 45, 51, 57, 67, 71,
+ 80, 85, 96, 99, 107, 108, 111, 117, 120, 59, 54, 54, 58, 64, 75, 80, 92,
+ 98, 110, 113, 115, 116, 122, 125, 130, 65, 59, 59, 63, 68, 79, 85, 98,
+ 105, 118, 121, 127, 130, 134, 135, 140, 80, 72, 71, 74, 79, 90, 96, 110,
+ 118, 134, 137, 140, 143, 144, 146, 152, 83, 75, 74, 76, 81, 92, 99, 113,
+ 121, 137, 140, 151, 152, 155, 158, 165, 91, 83, 81, 81, 88, 95, 107,
+ 115, 127, 140, 151, 159, 166, 169, 173, 179, 97, 90, 86, 84, 91, 100,
+ 108, 116, 130, 143, 152, 166, 174, 182, 189, 193, 104, 97, 93, 90, 96,
+ 102, 111, 122, 134, 144, 155, 169, 182, 191, 200, 210, 111, 104, 100,
+ 97, 102, 109, 117, 125, 135, 146, 158, 173, 189, 200, 210, 220, 119,
+ 112, 107, 105, 105, 112, 120, 130, 140, 152, 165, 179, 193, 210, 220,
+ 231],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 32, 34, 35, 36, 39, 44, 46, 48, 54, 59, 62, 65, 71,
+ 80, 81, 83, 88, 91, 94, 97, 101, 104, 107, 111, 115, 119, 123, 31, 32,
+ 32, 32, 32, 32, 34, 34, 35, 38, 42, 44, 46, 51, 56, 59, 62, 68, 76, 77,
+ 78, 84, 86, 89, 92, 95, 99, 102, 105, 109, 113, 116, 31, 32, 32, 32, 32,
+ 32, 33, 34, 34, 37, 41, 42, 44, 49, 54, 56, 59, 65, 72, 73, 75, 80, 83,
+ 86, 90, 93, 97, 101, 104, 108, 112, 116, 31, 32, 32, 32, 33, 33, 34, 35,
+ 35, 38, 41, 43, 45, 49, 54, 56, 59, 64, 72, 73, 74, 79, 82, 85, 88, 91,
+ 94, 97, 101, 104, 107, 111, 31, 32, 32, 33, 33, 34, 35, 36, 36, 39, 42,
+ 44, 45, 50, 54, 56, 59, 64, 71, 72, 74, 78, 81, 84, 86, 89, 93, 96, 100,
+ 104, 107, 111, 32, 32, 32, 33, 34, 35, 37, 37, 38, 40, 42, 44, 46, 49,
+ 53, 55, 58, 63, 69, 70, 72, 76, 79, 82, 85, 89, 93, 96, 99, 102, 106,
+ 109, 34, 34, 33, 34, 35, 37, 39, 41, 42, 45, 47, 49, 51, 54, 58, 60, 63,
+ 68, 74, 75, 76, 80, 81, 82, 84, 87, 90, 93, 97, 101, 105, 110, 35, 34,
+ 34, 35, 36, 37, 41, 43, 45, 47, 50, 52, 53, 57, 61, 63, 65, 70, 76, 77,
+ 79, 82, 84, 86, 89, 91, 92, 93, 96, 100, 103, 107, 36, 35, 34, 35, 36,
+ 38, 42, 45, 48, 50, 54, 55, 57, 60, 64, 66, 68, 73, 79, 80, 81, 85, 88,
+ 90, 91, 93, 96, 99, 102, 103, 105, 107, 39, 38, 37, 38, 39, 40, 45, 47,
+ 50, 54, 58, 59, 61, 65, 69, 71, 73, 78, 84, 85, 86, 91, 92, 92, 95, 98,
+ 100, 101, 103, 106, 110, 114, 44, 42, 41, 41, 42, 42, 47, 50, 54, 58,
+ 63, 65, 67, 71, 75, 77, 79, 84, 90, 91, 92, 95, 95, 97, 100, 101, 102,
+ 105, 109, 111, 112, 114, 46, 44, 42, 43, 44, 44, 49, 52, 55, 59, 65, 67,
+ 69, 74, 78, 80, 82, 87, 93, 94, 95, 98, 100, 103, 102, 105, 108, 110,
+ 111, 113, 117, 121, 48, 46, 44, 45, 45, 46, 51, 53, 57, 61, 67, 69, 71,
+ 76, 80, 83, 85, 90, 96, 97, 99, 103, 107, 105, 108, 111, 111, 113, 117,
+ 119, 120, 122, 54, 51, 49, 49, 50, 49, 54, 57, 60, 65, 71, 74, 76, 82,
+ 87, 89, 92, 97, 104, 105, 106, 111, 110, 111, 114, 113, 116, 120, 120,
+ 121, 125, 130, 59, 56, 54, 54, 54, 53, 58, 61, 64, 69, 75, 78, 80, 87,
+ 92, 95, 98, 103, 110, 111, 113, 115, 115, 119, 116, 120, 122, 122, 125,
+ 129, 130, 130, 62, 59, 56, 56, 56, 55, 60, 63, 66, 71, 77, 80, 83, 89,
+ 95, 98, 101, 107, 114, 115, 117, 119, 123, 121, 125, 126, 125, 129, 131,
+ 131, 135, 140, 65, 62, 59, 59, 59, 58, 63, 65, 68, 73, 79, 82, 85, 92,
+ 98, 101, 105, 111, 118, 119, 121, 126, 127, 128, 130, 130, 134, 133,
+ 135, 140, 140, 140, 71, 68, 65, 64, 64, 63, 68, 70, 73, 78, 84, 87, 90,
+ 97, 103, 107, 111, 117, 125, 126, 128, 134, 132, 136, 133, 138, 137,
+ 140, 143, 142, 145, 150, 80, 76, 72, 72, 71, 69, 74, 76, 79, 84, 90, 93,
+ 96, 104, 110, 114, 118, 125, 134, 135, 137, 139, 140, 139, 143, 142,
+ 144, 146, 146, 151, 152, 151, 81, 77, 73, 73, 72, 70, 75, 77, 80, 85,
+ 91, 94, 97, 105, 111, 115, 119, 126, 135, 137, 138, 144, 147, 146, 148,
+ 149, 151, 150, 156, 155, 157, 163, 83, 78, 75, 74, 74, 72, 76, 79, 81,
+ 86, 92, 95, 99, 106, 113, 117, 121, 128, 137, 138, 140, 147, 151, 156,
+ 152, 157, 155, 161, 158, 162, 165, 164, 88, 84, 80, 79, 78, 76, 80, 82,
+ 85, 91, 95, 98, 103, 111, 115, 119, 126, 134, 139, 144, 147, 152, 154,
+ 158, 163, 159, 165, 163, 168, 168, 169, 176, 91, 86, 83, 82, 81, 79, 81,
+ 84, 88, 92, 95, 100, 107, 110, 115, 123, 127, 132, 140, 147, 151, 154,
+ 159, 161, 166, 171, 169, 173, 173, 176, 179, 177, 94, 89, 86, 85, 84,
+ 82, 82, 86, 90, 92, 97, 103, 105, 111, 119, 121, 128, 136, 139, 146,
+ 156, 158, 161, 166, 168, 174, 179, 178, 180, 183, 183, 190, 97, 92, 90,
+ 88, 86, 85, 84, 89, 91, 95, 100, 102, 108, 114, 116, 125, 130, 133, 143,
+ 148, 152, 163, 166, 168, 174, 176, 182, 187, 189, 188, 193, 191, 101,
+ 95, 93, 91, 89, 89, 87, 91, 93, 98, 101, 105, 111, 113, 120, 126, 130,
+ 138, 142, 149, 157, 159, 171, 174, 176, 183, 184, 191, 195, 199, 197,
+ 204, 104, 99, 97, 94, 93, 93, 90, 92, 96, 100, 102, 108, 111, 116, 122,
+ 125, 134, 137, 144, 151, 155, 165, 169, 179, 182, 184, 191, 193, 200,
+ 204, 210, 206, 107, 102, 101, 97, 96, 96, 93, 93, 99, 101, 105, 110,
+ 113, 120, 122, 129, 133, 140, 146, 150, 161, 163, 173, 178, 187, 191,
+ 193, 200, 202, 210, 214, 222, 111, 105, 104, 101, 100, 99, 97, 96, 102,
+ 103, 109, 111, 117, 120, 125, 131, 135, 143, 146, 156, 158, 168, 173,
+ 180, 189, 195, 200, 202, 210, 212, 220, 224, 115, 109, 108, 104, 104,
+ 102, 101, 100, 103, 106, 111, 113, 119, 121, 129, 131, 140, 142, 151,
+ 155, 162, 168, 176, 183, 188, 199, 204, 210, 212, 220, 222, 230, 119,
+ 113, 112, 107, 107, 106, 105, 103, 105, 110, 112, 117, 120, 125, 130,
+ 135, 140, 145, 152, 157, 165, 169, 179, 183, 193, 197, 210, 214, 220,
+ 222, 231, 232, 123, 116, 116, 111, 111, 109, 110, 107, 107, 114, 114,
+ 121, 122, 130, 130, 140, 140, 150, 151, 163, 164, 176, 177, 190, 191,
+ 204, 206, 222, 224, 230, 232, 242],
+ /* Size 4x8 */
+ [32, 42, 75, 91, 33, 42, 69, 86, 37, 58, 84, 91, 49, 71, 103, 110, 65,
+ 84, 125, 128, 80, 97, 142, 152, 91, 100, 145, 178, 104, 112, 146, 190],
+ /* Size 8x4 */
+ [32, 33, 37, 49, 65, 80, 91, 104, 42, 42, 58, 71, 84, 97, 100, 112, 75,
+ 69, 84, 103, 125, 142, 145, 146, 91, 86, 91, 110, 128, 152, 178, 190],
+ /* Size 8x16 */
+ [32, 32, 36, 53, 65, 87, 93, 99, 31, 33, 34, 49, 59, 78, 86, 93, 32, 34,
+ 36, 50, 59, 77, 82, 89, 34, 37, 42, 54, 63, 79, 80, 88, 36, 38, 48, 60,
+ 68, 84, 86, 90, 44, 43, 53, 71, 79, 95, 94, 97, 48, 46, 56, 76, 85, 102,
+ 105, 105, 58, 54, 63, 87, 98, 116, 112, 115, 65, 58, 68, 92, 105, 124,
+ 122, 124, 79, 70, 79, 104, 118, 141, 135, 135, 82, 72, 81, 106, 121,
+ 144, 149, 146, 91, 80, 88, 106, 130, 148, 162, 159, 97, 86, 94, 107,
+ 128, 157, 167, 171, 103, 93, 98, 114, 131, 150, 174, 186, 110, 100, 101,
+ 117, 138, 161, 183, 193, 118, 107, 105, 118, 136, 157, 182, 203],
+ /* Size 16x8 */
+ [32, 31, 32, 34, 36, 44, 48, 58, 65, 79, 82, 91, 97, 103, 110, 118, 32,
+ 33, 34, 37, 38, 43, 46, 54, 58, 70, 72, 80, 86, 93, 100, 107, 36, 34,
+ 36, 42, 48, 53, 56, 63, 68, 79, 81, 88, 94, 98, 101, 105, 53, 49, 50,
+ 54, 60, 71, 76, 87, 92, 104, 106, 106, 107, 114, 117, 118, 65, 59, 59,
+ 63, 68, 79, 85, 98, 105, 118, 121, 130, 128, 131, 138, 136, 87, 78, 77,
+ 79, 84, 95, 102, 116, 124, 141, 144, 148, 157, 150, 161, 157, 93, 86,
+ 82, 80, 86, 94, 105, 112, 122, 135, 149, 162, 167, 174, 183, 182, 99,
+ 93, 89, 88, 90, 97, 105, 115, 124, 135, 146, 159, 171, 186, 193, 203],
+ /* Size 16x32 */
+ [32, 31, 32, 34, 36, 44, 53, 59, 65, 79, 87, 90, 93, 96, 99, 102, 31, 32,
+ 32, 34, 35, 42, 51, 56, 62, 75, 82, 85, 88, 91, 94, 97, 31, 32, 33, 33,
+ 34, 41, 49, 54, 59, 72, 78, 82, 86, 90, 93, 97, 31, 32, 33, 34, 35, 41,
+ 49, 54, 59, 71, 78, 81, 84, 87, 90, 93, 32, 32, 34, 35, 36, 42, 50, 54,
+ 59, 71, 77, 80, 82, 86, 89, 93, 32, 33, 35, 37, 38, 42, 49, 53, 58, 69,
+ 75, 78, 82, 86, 89, 92, 34, 34, 37, 39, 42, 48, 54, 58, 63, 73, 79, 78,
+ 80, 83, 88, 92, 35, 34, 37, 41, 45, 50, 57, 61, 65, 76, 82, 83, 84, 84,
+ 87, 90, 36, 34, 38, 43, 48, 54, 60, 64, 68, 78, 84, 87, 86, 89, 90, 90,
+ 39, 37, 40, 45, 50, 58, 65, 69, 73, 84, 89, 89, 91, 91, 93, 96, 44, 41,
+ 43, 48, 53, 63, 71, 75, 79, 90, 95, 93, 94, 95, 97, 97, 46, 43, 44, 49,
+ 55, 65, 73, 78, 82, 93, 98, 100, 98, 100, 99, 103, 48, 45, 46, 51, 56,
+ 67, 76, 80, 85, 96, 102, 102, 105, 102, 105, 104, 53, 49, 50, 54, 60,
+ 71, 82, 87, 92, 103, 109, 107, 107, 110, 107, 111, 58, 54, 54, 58, 63,
+ 75, 87, 92, 98, 110, 116, 115, 112, 111, 115, 112, 61, 57, 56, 60, 66,
+ 77, 89, 95, 101, 114, 120, 118, 119, 118, 116, 120, 65, 60, 58, 63, 68,
+ 79, 92, 98, 105, 118, 124, 123, 122, 123, 124, 121, 71, 65, 63, 68, 73,
+ 84, 97, 103, 111, 125, 132, 132, 130, 128, 127, 130, 79, 72, 70, 74, 79,
+ 90, 104, 110, 118, 133, 141, 136, 135, 135, 135, 131, 81, 74, 71, 75,
+ 80, 91, 105, 112, 119, 135, 142, 140, 140, 138, 139, 142, 82, 75, 72,
+ 76, 81, 92, 106, 113, 121, 136, 144, 151, 149, 149, 146, 143, 88, 80,
+ 77, 80, 85, 97, 108, 115, 126, 142, 149, 153, 153, 152, 152, 154, 91,
+ 83, 80, 81, 88, 100, 106, 114, 130, 142, 148, 155, 162, 160, 159, 155,
+ 94, 85, 83, 82, 91, 100, 105, 118, 131, 137, 153, 160, 165, 167, 166,
+ 168, 97, 88, 86, 85, 94, 100, 107, 123, 128, 140, 157, 161, 167, 173,
+ 171, 169, 100, 91, 89, 87, 97, 100, 111, 121, 127, 145, 152, 164, 173,
+ 178, 182, 181, 103, 94, 93, 90, 98, 101, 114, 120, 131, 144, 150, 170,
+ 174, 180, 186, 183, 107, 97, 96, 93, 100, 104, 117, 119, 136, 142, 155,
+ 168, 177, 187, 191, 198, 110, 101, 100, 97, 101, 108, 117, 123, 138,
+ 141, 161, 165, 183, 188, 193, 200, 114, 104, 104, 100, 103, 112, 117,
+ 127, 137, 146, 159, 167, 185, 190, 201, 206, 118, 108, 107, 103, 105,
+ 115, 118, 131, 136, 151, 157, 172, 182, 197, 203, 208, 122, 111, 111,
+ 107, 107, 119, 119, 136, 136, 156, 156, 178, 179, 203, 204, 217],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 32, 32, 34, 35, 36, 39, 44, 46, 48, 53, 58, 61, 65, 71,
+ 79, 81, 82, 88, 91, 94, 97, 100, 103, 107, 110, 114, 118, 122, 31, 32,
+ 32, 32, 32, 33, 34, 34, 34, 37, 41, 43, 45, 49, 54, 57, 60, 65, 72, 74,
+ 75, 80, 83, 85, 88, 91, 94, 97, 101, 104, 108, 111, 32, 32, 33, 33, 34,
+ 35, 37, 37, 38, 40, 43, 44, 46, 50, 54, 56, 58, 63, 70, 71, 72, 77, 80,
+ 83, 86, 89, 93, 96, 100, 104, 107, 111, 34, 34, 33, 34, 35, 37, 39, 41,
+ 43, 45, 48, 49, 51, 54, 58, 60, 63, 68, 74, 75, 76, 80, 81, 82, 85, 87,
+ 90, 93, 97, 100, 103, 107, 36, 35, 34, 35, 36, 38, 42, 45, 48, 50, 53,
+ 55, 56, 60, 63, 66, 68, 73, 79, 80, 81, 85, 88, 91, 94, 97, 98, 100,
+ 101, 103, 105, 107, 44, 42, 41, 41, 42, 42, 48, 50, 54, 58, 63, 65, 67,
+ 71, 75, 77, 79, 84, 90, 91, 92, 97, 100, 100, 100, 100, 101, 104, 108,
+ 112, 115, 119, 53, 51, 49, 49, 50, 49, 54, 57, 60, 65, 71, 73, 76, 82,
+ 87, 89, 92, 97, 104, 105, 106, 108, 106, 105, 107, 111, 114, 117, 117,
+ 117, 118, 119, 59, 56, 54, 54, 54, 53, 58, 61, 64, 69, 75, 78, 80, 87,
+ 92, 95, 98, 103, 110, 112, 113, 115, 114, 118, 123, 121, 120, 119, 123,
+ 127, 131, 136, 65, 62, 59, 59, 59, 58, 63, 65, 68, 73, 79, 82, 85, 92,
+ 98, 101, 105, 111, 118, 119, 121, 126, 130, 131, 128, 127, 131, 136,
+ 138, 137, 136, 136, 79, 75, 72, 71, 71, 69, 73, 76, 78, 84, 90, 93, 96,
+ 103, 110, 114, 118, 125, 133, 135, 136, 142, 142, 137, 140, 145, 144,
+ 142, 141, 146, 151, 156, 87, 82, 78, 78, 77, 75, 79, 82, 84, 89, 95, 98,
+ 102, 109, 116, 120, 124, 132, 141, 142, 144, 149, 148, 153, 157, 152,
+ 150, 155, 161, 159, 157, 156, 90, 85, 82, 81, 80, 78, 78, 83, 87, 89,
+ 93, 100, 102, 107, 115, 118, 123, 132, 136, 140, 151, 153, 155, 160,
+ 161, 164, 170, 168, 165, 167, 172, 178, 93, 88, 86, 84, 82, 82, 80, 84,
+ 86, 91, 94, 98, 105, 107, 112, 119, 122, 130, 135, 140, 149, 153, 162,
+ 165, 167, 173, 174, 177, 183, 185, 182, 179, 96, 91, 90, 87, 86, 86, 83,
+ 84, 89, 91, 95, 100, 102, 110, 111, 118, 123, 128, 135, 138, 149, 152,
+ 160, 167, 173, 178, 180, 187, 188, 190, 197, 203, 99, 94, 93, 90, 89,
+ 89, 88, 87, 90, 93, 97, 99, 105, 107, 115, 116, 124, 127, 135, 139, 146,
+ 152, 159, 166, 171, 182, 186, 191, 193, 201, 203, 204, 102, 97, 97, 93,
+ 93, 92, 92, 90, 90, 96, 97, 103, 104, 111, 112, 120, 121, 130, 131, 142,
+ 143, 154, 155, 168, 169, 181, 183, 198, 200, 206, 208, 217],
+ /* Size 4x16 */
+ [31, 44, 79, 96, 32, 41, 72, 90, 32, 42, 71, 86, 34, 48, 73, 83, 34, 54,
+ 78, 89, 41, 63, 90, 95, 45, 67, 96, 102, 54, 75, 110, 111, 60, 79, 118,
+ 123, 72, 90, 133, 135, 75, 92, 136, 149, 83, 100, 142, 160, 88, 100,
+ 140, 173, 94, 101, 144, 180, 101, 108, 141, 188, 108, 115, 151, 197],
+ /* Size 16x4 */
+ [31, 32, 32, 34, 34, 41, 45, 54, 60, 72, 75, 83, 88, 94, 101, 108, 44,
+ 41, 42, 48, 54, 63, 67, 75, 79, 90, 92, 100, 100, 101, 108, 115, 79, 72,
+ 71, 73, 78, 90, 96, 110, 118, 133, 136, 142, 140, 144, 141, 151, 96, 90,
+ 86, 83, 89, 95, 102, 111, 123, 135, 149, 160, 173, 180, 188, 197],
+ /* Size 8x32 */
+ [32, 32, 36, 53, 65, 87, 93, 99, 31, 32, 35, 51, 62, 82, 88, 94, 31, 33,
+ 34, 49, 59, 78, 86, 93, 31, 33, 35, 49, 59, 78, 84, 90, 32, 34, 36, 50,
+ 59, 77, 82, 89, 32, 35, 38, 49, 58, 75, 82, 89, 34, 37, 42, 54, 63, 79,
+ 80, 88, 35, 37, 45, 57, 65, 82, 84, 87, 36, 38, 48, 60, 68, 84, 86, 90,
+ 39, 40, 50, 65, 73, 89, 91, 93, 44, 43, 53, 71, 79, 95, 94, 97, 46, 44,
+ 55, 73, 82, 98, 98, 99, 48, 46, 56, 76, 85, 102, 105, 105, 53, 50, 60,
+ 82, 92, 109, 107, 107, 58, 54, 63, 87, 98, 116, 112, 115, 61, 56, 66,
+ 89, 101, 120, 119, 116, 65, 58, 68, 92, 105, 124, 122, 124, 71, 63, 73,
+ 97, 111, 132, 130, 127, 79, 70, 79, 104, 118, 141, 135, 135, 81, 71, 80,
+ 105, 119, 142, 140, 139, 82, 72, 81, 106, 121, 144, 149, 146, 88, 77,
+ 85, 108, 126, 149, 153, 152, 91, 80, 88, 106, 130, 148, 162, 159, 94,
+ 83, 91, 105, 131, 153, 165, 166, 97, 86, 94, 107, 128, 157, 167, 171,
+ 100, 89, 97, 111, 127, 152, 173, 182, 103, 93, 98, 114, 131, 150, 174,
+ 186, 107, 96, 100, 117, 136, 155, 177, 191, 110, 100, 101, 117, 138,
+ 161, 183, 193, 114, 104, 103, 117, 137, 159, 185, 201, 118, 107, 105,
+ 118, 136, 157, 182, 203, 122, 111, 107, 119, 136, 156, 179, 204],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 32, 32, 34, 35, 36, 39, 44, 46, 48, 53, 58, 61, 65, 71,
+ 79, 81, 82, 88, 91, 94, 97, 100, 103, 107, 110, 114, 118, 122, 32, 32,
+ 33, 33, 34, 35, 37, 37, 38, 40, 43, 44, 46, 50, 54, 56, 58, 63, 70, 71,
+ 72, 77, 80, 83, 86, 89, 93, 96, 100, 104, 107, 111, 36, 35, 34, 35, 36,
+ 38, 42, 45, 48, 50, 53, 55, 56, 60, 63, 66, 68, 73, 79, 80, 81, 85, 88,
+ 91, 94, 97, 98, 100, 101, 103, 105, 107, 53, 51, 49, 49, 50, 49, 54, 57,
+ 60, 65, 71, 73, 76, 82, 87, 89, 92, 97, 104, 105, 106, 108, 106, 105,
+ 107, 111, 114, 117, 117, 117, 118, 119, 65, 62, 59, 59, 59, 58, 63, 65,
+ 68, 73, 79, 82, 85, 92, 98, 101, 105, 111, 118, 119, 121, 126, 130, 131,
+ 128, 127, 131, 136, 138, 137, 136, 136, 87, 82, 78, 78, 77, 75, 79, 82,
+ 84, 89, 95, 98, 102, 109, 116, 120, 124, 132, 141, 142, 144, 149, 148,
+ 153, 157, 152, 150, 155, 161, 159, 157, 156, 93, 88, 86, 84, 82, 82, 80,
+ 84, 86, 91, 94, 98, 105, 107, 112, 119, 122, 130, 135, 140, 149, 153,
+ 162, 165, 167, 173, 174, 177, 183, 185, 182, 179, 99, 94, 93, 90, 89,
+ 89, 88, 87, 90, 93, 97, 99, 105, 107, 115, 116, 124, 127, 135, 139, 146,
+ 152, 159, 166, 171, 182, 186, 191, 193, 201, 203, 204]
+ ],
+ [ /* Chroma */
+ /* Size 4x4 */
+ [35, 46, 57, 66, 46, 60, 69, 71, 57, 69, 90, 90, 66, 71, 90, 109],
+ /* Size 8x8 */
+ [31, 38, 47, 50, 57, 63, 67, 71, 38, 47, 46, 47, 52, 57, 62, 67, 47, 46,
+ 54, 57, 61, 66, 67, 68, 50, 47, 57, 66, 72, 77, 75, 75, 57, 52, 61, 72,
+ 82, 88, 86, 84, 63, 57, 66, 77, 88, 96, 95, 95, 67, 62, 67, 75, 86, 95,
+ 104, 107, 71, 67, 68, 75, 84, 95, 107, 113],
+ /* Size 16x16 */
+ [32, 30, 33, 41, 49, 49, 50, 54, 57, 63, 65, 68, 70, 72, 74, 76, 30, 32,
+ 35, 42, 46, 45, 46, 49, 52, 57, 58, 62, 64, 67, 70, 72, 33, 35, 39, 45,
+ 47, 45, 46, 49, 51, 56, 57, 60, 62, 64, 66, 69, 41, 42, 45, 48, 50, 49,
+ 50, 52, 53, 57, 58, 59, 60, 61, 64, 67, 49, 46, 47, 50, 53, 53, 54, 55,
+ 56, 60, 61, 64, 64, 65, 66, 66, 49, 45, 45, 49, 53, 58, 60, 62, 63, 67,
+ 68, 67, 69, 68, 70, 70, 50, 46, 46, 50, 54, 60, 61, 65, 67, 71, 71, 74,
+ 73, 73, 74, 74, 54, 49, 49, 52, 55, 62, 65, 71, 73, 78, 79, 78, 77, 78,
+ 78, 78, 57, 52, 51, 53, 56, 63, 67, 73, 76, 82, 83, 84, 84, 84, 82, 83,
+ 63, 57, 56, 57, 60, 67, 71, 78, 82, 89, 90, 90, 89, 88, 87, 88, 65, 58,
+ 57, 58, 61, 68, 71, 79, 83, 90, 91, 94, 93, 93, 92, 93, 68, 62, 60, 59,
+ 64, 67, 74, 78, 84, 90, 94, 98, 99, 98, 98, 98, 70, 64, 62, 60, 64, 69,
+ 73, 77, 84, 89, 93, 99, 102, 103, 104, 104, 72, 67, 64, 61, 65, 68, 73,
+ 78, 84, 88, 93, 98, 103, 106, 108, 109, 74, 70, 66, 64, 66, 70, 74, 78,
+ 82, 87, 92, 98, 104, 108, 111, 112, 76, 72, 69, 67, 66, 70, 74, 78, 83,
+ 88, 93, 98, 104, 109, 112, 116],
+ /* Size 32x32 */
+ [32, 31, 30, 32, 33, 36, 41, 45, 49, 48, 49, 50, 50, 52, 54, 56, 57, 60,
+ 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 78, 31, 31, 31, 33,
+ 34, 38, 42, 45, 47, 47, 47, 47, 48, 50, 52, 53, 54, 57, 60, 61, 61, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 74, 30, 31, 32, 33, 35, 40, 42, 44,
+ 46, 45, 45, 45, 46, 47, 49, 51, 52, 54, 57, 58, 58, 61, 62, 63, 64, 66,
+ 67, 68, 70, 71, 72, 74, 32, 33, 33, 35, 37, 41, 43, 45, 47, 46, 45, 46,
+ 46, 47, 49, 50, 51, 54, 57, 57, 58, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 33, 34, 35, 37, 39, 43, 45, 46, 47, 46, 45, 46, 46, 47, 49, 50,
+ 51, 53, 56, 57, 57, 59, 60, 61, 62, 63, 64, 65, 66, 68, 69, 70, 36, 38,
+ 40, 41, 43, 47, 47, 47, 48, 46, 45, 46, 46, 47, 48, 49, 50, 52, 54, 55,
+ 55, 57, 58, 59, 61, 62, 64, 65, 66, 67, 68, 69, 41, 42, 42, 43, 45, 47,
+ 48, 49, 50, 49, 49, 49, 50, 50, 52, 52, 53, 55, 57, 58, 58, 60, 59, 59,
+ 60, 61, 61, 63, 64, 66, 67, 69, 45, 45, 44, 45, 46, 47, 49, 50, 51, 51,
+ 51, 51, 52, 52, 53, 54, 55, 57, 59, 59, 60, 61, 61, 62, 63, 63, 63, 63,
+ 63, 64, 65, 66, 49, 47, 46, 47, 47, 48, 50, 51, 53, 53, 53, 54, 54, 54,
+ 55, 56, 56, 58, 60, 61, 61, 63, 64, 64, 64, 64, 65, 66, 66, 66, 66, 66,
+ 48, 47, 45, 46, 46, 46, 49, 51, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61,
+ 63, 64, 64, 66, 66, 65, 66, 67, 67, 67, 67, 68, 69, 70, 49, 47, 45, 45,
+ 45, 45, 49, 51, 53, 55, 58, 59, 60, 61, 62, 63, 63, 65, 67, 67, 68, 69,
+ 67, 68, 69, 68, 68, 69, 70, 70, 70, 70, 50, 47, 45, 46, 46, 46, 49, 51,
+ 54, 56, 59, 60, 60, 62, 64, 64, 65, 67, 69, 69, 70, 70, 71, 71, 70, 70,
+ 71, 71, 71, 71, 72, 74, 50, 48, 46, 46, 46, 46, 50, 52, 54, 56, 60, 60,
+ 61, 63, 65, 66, 67, 68, 71, 71, 71, 73, 74, 72, 73, 74, 73, 73, 74, 74,
+ 74, 74, 52, 50, 47, 47, 47, 47, 50, 52, 54, 57, 61, 62, 63, 66, 68, 69,
+ 70, 72, 75, 75, 75, 77, 75, 75, 76, 75, 75, 76, 75, 75, 76, 77, 54, 52,
+ 49, 49, 49, 48, 52, 53, 55, 58, 62, 64, 65, 68, 71, 72, 73, 75, 78, 78,
+ 79, 79, 78, 79, 77, 78, 78, 77, 78, 79, 78, 78, 56, 53, 51, 50, 50, 49,
+ 52, 54, 56, 59, 63, 64, 66, 69, 72, 73, 75, 77, 80, 80, 81, 81, 82, 80,
+ 81, 81, 79, 81, 80, 79, 81, 82, 57, 54, 52, 51, 51, 50, 53, 55, 56, 60,
+ 63, 65, 67, 70, 73, 75, 76, 79, 82, 82, 83, 85, 84, 83, 84, 83, 84, 82,
+ 82, 84, 83, 82, 60, 57, 54, 54, 53, 52, 55, 57, 58, 61, 65, 67, 68, 72,
+ 75, 77, 79, 82, 85, 85, 86, 88, 86, 87, 85, 86, 85, 85, 86, 84, 85, 86,
+ 63, 60, 57, 57, 56, 54, 57, 59, 60, 63, 67, 69, 71, 75, 78, 80, 82, 85,
+ 89, 89, 90, 90, 90, 89, 89, 88, 88, 88, 87, 88, 88, 87, 64, 61, 58, 57,
+ 57, 55, 58, 59, 61, 64, 67, 69, 71, 75, 78, 80, 82, 85, 89, 90, 91, 92,
+ 93, 92, 92, 91, 91, 90, 91, 90, 90, 92, 65, 61, 58, 58, 57, 55, 58, 60,
+ 61, 64, 68, 70, 71, 75, 79, 81, 83, 86, 90, 91, 91, 94, 94, 96, 93, 94,
+ 93, 94, 92, 93, 93, 92, 67, 63, 61, 60, 59, 57, 60, 61, 63, 66, 69, 70,
+ 73, 77, 79, 81, 85, 88, 90, 92, 94, 96, 96, 97, 98, 95, 97, 95, 96, 95,
+ 95, 96, 68, 64, 62, 61, 60, 58, 59, 61, 64, 66, 67, 71, 74, 75, 78, 82,
+ 84, 86, 90, 93, 94, 96, 98, 98, 99, 100, 98, 99, 98, 98, 98, 97, 69, 65,
+ 63, 62, 61, 59, 59, 62, 64, 65, 68, 71, 72, 75, 79, 80, 83, 87, 89, 92,
+ 96, 97, 98, 100, 100, 101, 102, 101, 101, 101, 100, 102, 70, 66, 64, 63,
+ 62, 61, 60, 63, 64, 66, 69, 70, 73, 76, 77, 81, 84, 85, 89, 92, 93, 98,
+ 99, 100, 102, 102, 103, 104, 104, 103, 104, 102, 71, 67, 66, 64, 63, 62,
+ 61, 63, 64, 67, 68, 70, 74, 75, 78, 81, 83, 86, 88, 91, 94, 95, 100,
+ 101, 102, 104, 104, 105, 106, 107, 105, 107, 72, 68, 67, 65, 64, 64, 61,
+ 63, 65, 67, 68, 71, 73, 75, 78, 79, 84, 85, 88, 91, 93, 97, 98, 102,
+ 103, 104, 106, 106, 108, 108, 109, 107, 73, 69, 68, 66, 65, 65, 63, 63,
+ 66, 67, 69, 71, 73, 76, 77, 81, 82, 85, 88, 90, 94, 95, 99, 101, 104,
+ 105, 106, 109, 108, 110, 111, 112, 74, 70, 70, 67, 66, 66, 64, 63, 66,
+ 67, 70, 71, 74, 75, 78, 80, 82, 86, 87, 91, 92, 96, 98, 101, 104, 106,
+ 108, 108, 111, 111, 112, 113, 75, 71, 71, 68, 68, 67, 66, 64, 66, 68,
+ 70, 71, 74, 75, 79, 79, 84, 84, 88, 90, 93, 95, 98, 101, 103, 107, 108,
+ 110, 111, 113, 113, 115, 76, 72, 72, 69, 69, 68, 67, 65, 66, 69, 70, 72,
+ 74, 76, 78, 81, 83, 85, 88, 90, 93, 95, 98, 100, 104, 105, 109, 111,
+ 112, 113, 116, 115, 78, 74, 74, 70, 70, 69, 69, 66, 66, 70, 70, 74, 74,
+ 77, 78, 82, 82, 86, 87, 92, 92, 96, 97, 102, 102, 107, 107, 112, 113,
+ 115, 115, 118],
+ /* Size 4x8 */
+ [31, 47, 60, 66, 40, 45, 54, 61, 46, 56, 64, 64, 48, 61, 75, 73, 54, 65,
+ 85, 82, 61, 69, 92, 92, 64, 68, 90, 102, 68, 71, 87, 105],
+ /* Size 8x4 */
+ [31, 40, 46, 48, 54, 61, 64, 68, 47, 45, 56, 61, 65, 69, 68, 71, 60, 54,
+ 64, 75, 85, 92, 90, 87, 66, 61, 64, 73, 82, 92, 102, 105],
+ /* Size 8x16 */
+ [32, 37, 48, 52, 57, 66, 68, 71, 30, 40, 46, 48, 52, 60, 63, 66, 33, 43,
+ 47, 47, 51, 59, 60, 63, 42, 47, 50, 50, 53, 60, 59, 62, 49, 48, 53, 54,
+ 57, 62, 62, 62, 49, 46, 53, 61, 64, 69, 66, 66, 50, 46, 54, 64, 67, 73,
+ 72, 70, 54, 49, 55, 68, 73, 80, 76, 75, 57, 50, 56, 70, 76, 84, 80, 79,
+ 63, 55, 60, 75, 82, 92, 87, 84, 64, 56, 61, 75, 83, 93, 93, 89, 68, 59,
+ 64, 74, 86, 94, 98, 94, 70, 62, 66, 73, 83, 96, 99, 98, 72, 64, 66, 75,
+ 83, 92, 101, 104, 74, 67, 66, 74, 84, 94, 103, 106, 76, 69, 67, 73, 82,
+ 91, 101, 109],
+ /* Size 16x8 */
+ [32, 30, 33, 42, 49, 49, 50, 54, 57, 63, 64, 68, 70, 72, 74, 76, 37, 40,
+ 43, 47, 48, 46, 46, 49, 50, 55, 56, 59, 62, 64, 67, 69, 48, 46, 47, 50,
+ 53, 53, 54, 55, 56, 60, 61, 64, 66, 66, 66, 67, 52, 48, 47, 50, 54, 61,
+ 64, 68, 70, 75, 75, 74, 73, 75, 74, 73, 57, 52, 51, 53, 57, 64, 67, 73,
+ 76, 82, 83, 86, 83, 83, 84, 82, 66, 60, 59, 60, 62, 69, 73, 80, 84, 92,
+ 93, 94, 96, 92, 94, 91, 68, 63, 60, 59, 62, 66, 72, 76, 80, 87, 93, 98,
+ 99, 101, 103, 101, 71, 66, 63, 62, 62, 66, 70, 75, 79, 84, 89, 94, 98,
+ 104, 106, 109],
+ /* Size 16x32 */
+ [32, 31, 37, 42, 48, 49, 52, 54, 57, 63, 66, 67, 68, 69, 71, 72, 31, 31,
+ 38, 42, 47, 47, 50, 52, 54, 60, 63, 64, 65, 66, 67, 68, 30, 32, 40, 42,
+ 46, 45, 48, 50, 52, 57, 60, 62, 63, 65, 66, 68, 32, 34, 41, 44, 46, 45,
+ 48, 49, 51, 57, 59, 61, 62, 63, 64, 65, 33, 36, 43, 45, 47, 46, 47, 49,
+ 51, 56, 59, 60, 60, 62, 63, 65, 37, 40, 47, 47, 47, 45, 47, 48, 50, 54,
+ 57, 58, 60, 61, 62, 63, 42, 43, 47, 48, 50, 49, 50, 52, 53, 57, 60, 58,
+ 59, 60, 62, 63, 45, 44, 47, 49, 51, 51, 52, 54, 55, 59, 61, 61, 61, 60,
+ 61, 61, 49, 46, 48, 50, 53, 53, 54, 55, 57, 60, 62, 63, 62, 63, 62, 62,
+ 48, 46, 47, 50, 53, 56, 57, 59, 60, 64, 66, 65, 65, 64, 64, 65, 49, 45,
+ 46, 49, 53, 58, 61, 62, 64, 67, 69, 67, 66, 66, 66, 65, 49, 46, 46, 49,
+ 53, 59, 62, 64, 65, 69, 71, 70, 68, 68, 67, 68, 50, 46, 46, 50, 54, 59,
+ 64, 65, 67, 71, 73, 72, 72, 70, 70, 69, 52, 48, 47, 50, 54, 61, 66, 68,
+ 71, 75, 77, 74, 73, 73, 71, 72, 54, 50, 49, 52, 55, 62, 68, 71, 73, 78,
+ 80, 78, 76, 74, 75, 73, 55, 51, 49, 52, 56, 63, 69, 72, 75, 80, 82, 80,
+ 79, 78, 76, 77, 57, 52, 50, 53, 56, 64, 70, 73, 76, 82, 84, 82, 80, 80,
+ 79, 77, 60, 54, 52, 55, 58, 65, 72, 75, 79, 85, 88, 86, 84, 82, 81, 81,
+ 63, 57, 55, 58, 60, 67, 75, 78, 82, 89, 92, 88, 87, 85, 84, 81, 64, 58,
+ 55, 58, 61, 68, 75, 78, 82, 89, 92, 90, 89, 87, 86, 86, 64, 59, 56, 58,
+ 61, 68, 75, 79, 83, 90, 93, 95, 93, 91, 89, 87, 67, 61, 58, 60, 63, 69,
+ 76, 79, 85, 92, 95, 96, 94, 92, 91, 91, 68, 62, 59, 60, 64, 71, 74, 78,
+ 86, 91, 94, 96, 98, 96, 94, 91, 69, 62, 60, 60, 65, 70, 72, 79, 85, 88,
+ 95, 98, 99, 98, 97, 96, 70, 63, 62, 60, 66, 69, 73, 81, 83, 89, 96, 97,
+ 99, 101, 98, 97, 71, 64, 63, 61, 67, 68, 74, 79, 82, 90, 93, 98, 102,
+ 102, 102, 101, 72, 65, 64, 62, 66, 68, 75, 78, 83, 89, 92, 100, 101,
+ 103, 104, 102, 73, 66, 65, 63, 66, 69, 75, 76, 84, 87, 93, 98, 102, 105,
+ 106, 107, 74, 67, 67, 64, 66, 70, 74, 77, 84, 86, 94, 96, 103, 105, 106,
+ 107, 75, 68, 68, 65, 66, 71, 74, 78, 83, 87, 93, 96, 103, 105, 109, 109,
+ 76, 69, 69, 66, 67, 72, 73, 80, 82, 88, 91, 97, 101, 107, 109, 110, 77,
+ 70, 70, 67, 67, 73, 73, 81, 81, 90, 90, 99, 99, 108, 108, 113],
+ /* Size 32x16 */
+ [32, 31, 30, 32, 33, 37, 42, 45, 49, 48, 49, 49, 50, 52, 54, 55, 57, 60,
+ 63, 64, 64, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 31, 31, 32, 34,
+ 36, 40, 43, 44, 46, 46, 45, 46, 46, 48, 50, 51, 52, 54, 57, 58, 59, 61,
+ 62, 62, 63, 64, 65, 66, 67, 68, 69, 70, 37, 38, 40, 41, 43, 47, 47, 47,
+ 48, 47, 46, 46, 46, 47, 49, 49, 50, 52, 55, 55, 56, 58, 59, 60, 62, 63,
+ 64, 65, 67, 68, 69, 70, 42, 42, 42, 44, 45, 47, 48, 49, 50, 50, 49, 49,
+ 50, 50, 52, 52, 53, 55, 58, 58, 58, 60, 60, 60, 60, 61, 62, 63, 64, 65,
+ 66, 67, 48, 47, 46, 46, 47, 47, 50, 51, 53, 53, 53, 53, 54, 54, 55, 56,
+ 56, 58, 60, 61, 61, 63, 64, 65, 66, 67, 66, 66, 66, 66, 67, 67, 49, 47,
+ 45, 45, 46, 45, 49, 51, 53, 56, 58, 59, 59, 61, 62, 63, 64, 65, 67, 68,
+ 68, 69, 71, 70, 69, 68, 68, 69, 70, 71, 72, 73, 52, 50, 48, 48, 47, 47,
+ 50, 52, 54, 57, 61, 62, 64, 66, 68, 69, 70, 72, 75, 75, 75, 76, 74, 72,
+ 73, 74, 75, 75, 74, 74, 73, 73, 54, 52, 50, 49, 49, 48, 52, 54, 55, 59,
+ 62, 64, 65, 68, 71, 72, 73, 75, 78, 78, 79, 79, 78, 79, 81, 79, 78, 76,
+ 77, 78, 80, 81, 57, 54, 52, 51, 51, 50, 53, 55, 57, 60, 64, 65, 67, 71,
+ 73, 75, 76, 79, 82, 82, 83, 85, 86, 85, 83, 82, 83, 84, 84, 83, 82, 81,
+ 63, 60, 57, 57, 56, 54, 57, 59, 60, 64, 67, 69, 71, 75, 78, 80, 82, 85,
+ 89, 89, 90, 92, 91, 88, 89, 90, 89, 87, 86, 87, 88, 90, 66, 63, 60, 59,
+ 59, 57, 60, 61, 62, 66, 69, 71, 73, 77, 80, 82, 84, 88, 92, 92, 93, 95,
+ 94, 95, 96, 93, 92, 93, 94, 93, 91, 90, 67, 64, 62, 61, 60, 58, 58, 61,
+ 63, 65, 67, 70, 72, 74, 78, 80, 82, 86, 88, 90, 95, 96, 96, 98, 97, 98,
+ 100, 98, 96, 96, 97, 99, 68, 65, 63, 62, 60, 60, 59, 61, 62, 65, 66, 68,
+ 72, 73, 76, 79, 80, 84, 87, 89, 93, 94, 98, 99, 99, 102, 101, 102, 103,
+ 103, 101, 99, 69, 66, 65, 63, 62, 61, 60, 60, 63, 64, 66, 68, 70, 73,
+ 74, 78, 80, 82, 85, 87, 91, 92, 96, 98, 101, 102, 103, 105, 105, 105,
+ 107, 108, 71, 67, 66, 64, 63, 62, 62, 61, 62, 64, 66, 67, 70, 71, 75,
+ 76, 79, 81, 84, 86, 89, 91, 94, 97, 98, 102, 104, 106, 106, 109, 109,
+ 108, 72, 68, 68, 65, 65, 63, 63, 61, 62, 65, 65, 68, 69, 72, 73, 77, 77,
+ 81, 81, 86, 87, 91, 91, 96, 97, 101, 102, 107, 107, 109, 110, 113],
+ /* Size 4x16 */
+ [31, 49, 63, 69, 32, 45, 57, 65, 36, 46, 56, 62, 43, 49, 57, 60, 46, 53,
+ 60, 63, 45, 58, 67, 66, 46, 59, 71, 70, 50, 62, 78, 74, 52, 64, 82, 80,
+ 57, 67, 89, 85, 59, 68, 90, 91, 62, 71, 91, 96, 63, 69, 89, 101, 65, 68,
+ 89, 103, 67, 70, 86, 105, 69, 72, 88, 107],
+ /* Size 16x4 */
+ [31, 32, 36, 43, 46, 45, 46, 50, 52, 57, 59, 62, 63, 65, 67, 69, 49, 45,
+ 46, 49, 53, 58, 59, 62, 64, 67, 68, 71, 69, 68, 70, 72, 63, 57, 56, 57,
+ 60, 67, 71, 78, 82, 89, 90, 91, 89, 89, 86, 88, 69, 65, 62, 60, 63, 66,
+ 70, 74, 80, 85, 91, 96, 101, 103, 105, 107],
+ /* Size 8x32 */
+ [32, 37, 48, 52, 57, 66, 68, 71, 31, 38, 47, 50, 54, 63, 65, 67, 30, 40,
+ 46, 48, 52, 60, 63, 66, 32, 41, 46, 48, 51, 59, 62, 64, 33, 43, 47, 47,
+ 51, 59, 60, 63, 37, 47, 47, 47, 50, 57, 60, 62, 42, 47, 50, 50, 53, 60,
+ 59, 62, 45, 47, 51, 52, 55, 61, 61, 61, 49, 48, 53, 54, 57, 62, 62, 62,
+ 48, 47, 53, 57, 60, 66, 65, 64, 49, 46, 53, 61, 64, 69, 66, 66, 49, 46,
+ 53, 62, 65, 71, 68, 67, 50, 46, 54, 64, 67, 73, 72, 70, 52, 47, 54, 66,
+ 71, 77, 73, 71, 54, 49, 55, 68, 73, 80, 76, 75, 55, 49, 56, 69, 75, 82,
+ 79, 76, 57, 50, 56, 70, 76, 84, 80, 79, 60, 52, 58, 72, 79, 88, 84, 81,
+ 63, 55, 60, 75, 82, 92, 87, 84, 64, 55, 61, 75, 82, 92, 89, 86, 64, 56,
+ 61, 75, 83, 93, 93, 89, 67, 58, 63, 76, 85, 95, 94, 91, 68, 59, 64, 74,
+ 86, 94, 98, 94, 69, 60, 65, 72, 85, 95, 99, 97, 70, 62, 66, 73, 83, 96,
+ 99, 98, 71, 63, 67, 74, 82, 93, 102, 102, 72, 64, 66, 75, 83, 92, 101,
+ 104, 73, 65, 66, 75, 84, 93, 102, 106, 74, 67, 66, 74, 84, 94, 103, 106,
+ 75, 68, 66, 74, 83, 93, 103, 109, 76, 69, 67, 73, 82, 91, 101, 109, 77,
+ 70, 67, 73, 81, 90, 99, 108],
+ /* Size 32x8 */
+ [32, 31, 30, 32, 33, 37, 42, 45, 49, 48, 49, 49, 50, 52, 54, 55, 57, 60,
+ 63, 64, 64, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 37, 38, 40, 41,
+ 43, 47, 47, 47, 48, 47, 46, 46, 46, 47, 49, 49, 50, 52, 55, 55, 56, 58,
+ 59, 60, 62, 63, 64, 65, 67, 68, 69, 70, 48, 47, 46, 46, 47, 47, 50, 51,
+ 53, 53, 53, 53, 54, 54, 55, 56, 56, 58, 60, 61, 61, 63, 64, 65, 66, 67,
+ 66, 66, 66, 66, 67, 67, 52, 50, 48, 48, 47, 47, 50, 52, 54, 57, 61, 62,
+ 64, 66, 68, 69, 70, 72, 75, 75, 75, 76, 74, 72, 73, 74, 75, 75, 74, 74,
+ 73, 73, 57, 54, 52, 51, 51, 50, 53, 55, 57, 60, 64, 65, 67, 71, 73, 75,
+ 76, 79, 82, 82, 83, 85, 86, 85, 83, 82, 83, 84, 84, 83, 82, 81, 66, 63,
+ 60, 59, 59, 57, 60, 61, 62, 66, 69, 71, 73, 77, 80, 82, 84, 88, 92, 92,
+ 93, 95, 94, 95, 96, 93, 92, 93, 94, 93, 91, 90, 68, 65, 63, 62, 60, 60,
+ 59, 61, 62, 65, 66, 68, 72, 73, 76, 79, 80, 84, 87, 89, 93, 94, 98, 99,
+ 99, 102, 101, 102, 103, 103, 101, 99, 71, 67, 66, 64, 63, 62, 62, 61,
+ 62, 64, 66, 67, 70, 71, 75, 76, 79, 81, 84, 86, 89, 91, 94, 97, 98, 102,
+ 104, 106, 106, 109, 109, 108]
+ ]
+ ],
+ [
+ [ /* Luma */
+ /* Size 4x4 */
+ [32, 41, 69, 92, 41, 63, 88, 103, 69, 88, 127, 140, 92, 103, 140, 184],
+ /* Size 8x8 */
+ [32, 32, 37, 47, 62, 78, 90, 102, 32, 35, 39, 46, 58, 72, 84, 96, 37, 39,
+ 51, 60, 71, 84, 93, 100, 47, 46, 60, 73, 87, 100, 106, 113, 62, 58, 71,
+ 87, 105, 121, 129, 132, 78, 72, 84, 100, 121, 140, 148, 155, 90, 84, 93,
+ 106, 129, 148, 169, 183, 102, 96, 100, 113, 132, 155, 183, 201],
+ /* Size 16x16 */
+ [32, 31, 31, 32, 36, 39, 47, 54, 61, 71, 80, 86, 92, 98, 104, 111, 31,
+ 32, 32, 33, 34, 37, 44, 50, 56, 65, 73, 79, 85, 91, 98, 105, 31, 32, 33,
+ 34, 36, 39, 45, 50, 56, 64, 71, 77, 82, 88, 94, 100, 32, 33, 34, 36, 40,
+ 42, 47, 51, 57, 65, 71, 76, 80, 85, 91, 98, 36, 34, 36, 40, 48, 50, 56,
+ 60, 65, 73, 79, 84, 86, 90, 95, 98, 39, 37, 39, 42, 50, 54, 60, 65, 70,
+ 78, 84, 89, 95, 96, 102, 105, 47, 44, 45, 47, 56, 60, 69, 75, 81, 89,
+ 95, 100, 102, 104, 109, 112, 54, 50, 50, 51, 60, 65, 75, 82, 89, 97,
+ 104, 109, 110, 114, 117, 121, 61, 56, 56, 57, 65, 70, 81, 89, 97, 106,
+ 113, 119, 122, 126, 125, 130, 71, 65, 64, 65, 73, 78, 89, 97, 106, 117,
+ 125, 131, 134, 134, 136, 141, 80, 73, 71, 71, 79, 84, 95, 104, 113, 125,
+ 134, 140, 142, 145, 146, 152, 86, 79, 77, 76, 84, 89, 100, 109, 119,
+ 131, 140, 147, 154, 157, 160, 165, 92, 85, 82, 80, 86, 95, 102, 110,
+ 122, 134, 142, 154, 162, 168, 174, 178, 98, 91, 88, 85, 90, 96, 104,
+ 114, 126, 134, 145, 157, 168, 176, 184, 193, 104, 98, 94, 91, 95, 102,
+ 109, 117, 125, 136, 146, 160, 174, 184, 193, 201, 111, 105, 100, 98, 98,
+ 105, 112, 121, 130, 141, 152, 165, 178, 193, 201, 210],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 32, 32, 34, 36, 38, 39, 44, 47, 49, 54, 59, 61, 65,
+ 71, 76, 80, 83, 86, 89, 92, 95, 98, 101, 104, 108, 111, 114, 31, 32, 32,
+ 32, 32, 32, 33, 34, 35, 37, 38, 42, 45, 47, 51, 56, 58, 62, 68, 72, 76,
+ 78, 82, 85, 88, 90, 93, 96, 99, 102, 105, 109, 31, 32, 32, 32, 32, 32,
+ 33, 33, 34, 36, 37, 41, 44, 46, 50, 54, 56, 60, 65, 70, 73, 76, 79, 82,
+ 85, 88, 91, 95, 98, 101, 105, 109, 31, 32, 32, 32, 32, 33, 33, 34, 35,
+ 36, 38, 41, 44, 45, 49, 54, 56, 59, 65, 69, 72, 75, 78, 81, 84, 86, 89,
+ 92, 95, 98, 101, 104, 31, 32, 32, 32, 33, 34, 34, 35, 36, 38, 39, 42,
+ 45, 46, 50, 54, 56, 59, 64, 68, 71, 74, 77, 79, 82, 85, 88, 91, 94, 97,
+ 100, 104, 32, 32, 32, 33, 34, 35, 36, 37, 38, 39, 40, 42, 45, 46, 49,
+ 53, 55, 58, 63, 66, 69, 72, 74, 78, 81, 84, 87, 90, 93, 96, 99, 102, 32,
+ 33, 33, 33, 34, 36, 36, 38, 40, 41, 42, 44, 47, 48, 51, 55, 57, 60, 65,
+ 68, 71, 73, 76, 78, 80, 82, 85, 88, 91, 95, 98, 102, 34, 34, 33, 34, 35,
+ 37, 38, 39, 42, 44, 45, 47, 50, 51, 54, 58, 60, 63, 68, 71, 74, 76, 79,
+ 82, 85, 86, 87, 88, 90, 93, 96, 99, 36, 35, 34, 35, 36, 38, 40, 42, 48,
+ 50, 50, 54, 56, 57, 60, 64, 65, 68, 73, 76, 79, 81, 84, 86, 86, 88, 90,
+ 93, 95, 97, 98, 100, 38, 37, 36, 36, 38, 39, 41, 44, 50, 51, 52, 56, 58,
+ 60, 63, 67, 68, 71, 76, 79, 82, 84, 87, 87, 90, 93, 94, 95, 96, 100,
+ 103, 106, 39, 38, 37, 38, 39, 40, 42, 45, 50, 52, 54, 58, 60, 62, 65,
+ 69, 70, 73, 78, 81, 84, 86, 89, 92, 95, 95, 96, 99, 102, 104, 105, 106,
+ 44, 42, 41, 41, 42, 42, 44, 47, 54, 56, 58, 63, 66, 68, 71, 75, 77, 79,
+ 84, 88, 90, 92, 95, 97, 97, 99, 102, 103, 103, 106, 109, 113, 47, 45,
+ 44, 44, 45, 45, 47, 50, 56, 58, 60, 66, 69, 71, 75, 79, 81, 84, 89, 92,
+ 95, 97, 100, 100, 102, 105, 104, 106, 109, 111, 112, 113, 49, 47, 46,
+ 45, 46, 46, 48, 51, 57, 60, 62, 68, 71, 73, 77, 81, 83, 87, 92, 95, 98,
+ 100, 103, 105, 107, 106, 109, 112, 112, 113, 117, 120, 54, 51, 50, 49,
+ 50, 49, 51, 54, 60, 63, 65, 71, 75, 77, 82, 87, 89, 92, 97, 101, 104,
+ 106, 109, 112, 110, 113, 114, 114, 117, 121, 121, 121, 59, 56, 54, 54,
+ 54, 53, 55, 58, 64, 67, 69, 75, 79, 81, 87, 92, 94, 98, 103, 107, 110,
+ 113, 116, 114, 117, 118, 117, 121, 122, 122, 125, 129, 61, 58, 56, 56,
+ 56, 55, 57, 60, 65, 68, 70, 77, 81, 83, 89, 94, 97, 101, 106, 110, 113,
+ 116, 119, 120, 122, 121, 126, 124, 125, 130, 130, 130, 65, 62, 60, 59,
+ 59, 58, 60, 63, 68, 71, 73, 79, 84, 87, 92, 98, 101, 105, 111, 115, 118,
+ 121, 124, 128, 125, 129, 128, 131, 133, 132, 135, 139, 71, 68, 65, 65,
+ 64, 63, 65, 68, 73, 76, 78, 84, 89, 92, 97, 103, 106, 111, 117, 122,
+ 125, 128, 131, 131, 134, 132, 134, 136, 136, 140, 141, 140, 76, 72, 70,
+ 69, 68, 66, 68, 71, 76, 79, 81, 88, 92, 95, 101, 107, 110, 115, 122,
+ 127, 130, 133, 136, 136, 138, 139, 141, 140, 145, 143, 146, 151, 80, 76,
+ 73, 72, 71, 69, 71, 74, 79, 82, 84, 90, 95, 98, 104, 110, 113, 118, 125,
+ 130, 134, 137, 140, 146, 142, 146, 145, 149, 146, 150, 152, 151, 83, 78,
+ 76, 75, 74, 72, 73, 76, 81, 84, 86, 92, 97, 100, 106, 113, 116, 121,
+ 128, 133, 137, 140, 144, 147, 152, 148, 154, 151, 156, 155, 156, 162,
+ 86, 82, 79, 78, 77, 74, 76, 79, 84, 87, 89, 95, 100, 103, 109, 116, 119,
+ 124, 131, 136, 140, 144, 147, 150, 154, 159, 157, 160, 160, 162, 165,
+ 162, 89, 85, 82, 81, 79, 78, 78, 82, 86, 87, 92, 97, 100, 105, 112, 114,
+ 120, 128, 131, 136, 146, 147, 150, 155, 156, 161, 166, 165, 167, 169,
+ 169, 175, 92, 88, 85, 84, 82, 81, 80, 85, 86, 90, 95, 97, 102, 107, 110,
+ 117, 122, 125, 134, 138, 142, 152, 154, 156, 162, 163, 168, 173, 174,
+ 174, 178, 176, 95, 90, 88, 86, 85, 84, 82, 86, 88, 93, 95, 99, 105, 106,
+ 113, 118, 121, 129, 132, 139, 146, 148, 159, 161, 163, 169, 170, 176,
+ 180, 183, 181, 187, 98, 93, 91, 89, 88, 87, 85, 87, 90, 94, 96, 102,
+ 104, 109, 114, 117, 126, 128, 134, 141, 145, 154, 157, 166, 168, 170,
+ 176, 178, 184, 188, 193, 188, 101, 96, 95, 92, 91, 90, 88, 88, 93, 95,
+ 99, 103, 106, 112, 114, 121, 124, 131, 136, 140, 149, 151, 160, 165,
+ 173, 176, 178, 184, 186, 192, 196, 203, 104, 99, 98, 95, 94, 93, 91, 90,
+ 95, 96, 102, 103, 109, 112, 117, 122, 125, 133, 136, 145, 146, 156, 160,
+ 167, 174, 180, 184, 186, 193, 194, 201, 204, 108, 102, 101, 98, 97, 96,
+ 95, 93, 97, 100, 104, 106, 111, 113, 121, 122, 130, 132, 140, 143, 150,
+ 155, 162, 169, 174, 183, 188, 192, 194, 201, 202, 210, 111, 105, 105,
+ 101, 100, 99, 98, 96, 98, 103, 105, 109, 112, 117, 121, 125, 130, 135,
+ 141, 146, 152, 156, 165, 169, 178, 181, 193, 196, 201, 202, 210, 211,
+ 114, 109, 109, 104, 104, 102, 102, 99, 100, 106, 106, 113, 113, 120,
+ 121, 129, 130, 139, 140, 151, 151, 162, 162, 175, 176, 187, 188, 203,
+ 204, 210, 211, 219],
+ /* Size 4x8 */
+ [32, 42, 69, 88, 33, 42, 64, 83, 36, 56, 77, 88, 46, 67, 93, 105, 60, 79,
+ 112, 122, 75, 92, 130, 144, 86, 95, 136, 167, 98, 105, 136, 177],
+ /* Size 8x4 */
+ [32, 33, 36, 46, 60, 75, 86, 98, 42, 42, 56, 67, 79, 92, 95, 105, 69, 64,
+ 77, 93, 112, 130, 136, 136, 88, 83, 88, 105, 122, 144, 167, 177],
+ /* Size 8x16 */
+ [32, 32, 36, 47, 65, 79, 90, 96, 31, 32, 35, 44, 60, 72, 84, 90, 32, 34,
+ 36, 45, 59, 71, 80, 87, 32, 35, 40, 47, 60, 71, 78, 85, 36, 37, 48, 56,
+ 68, 78, 83, 87, 39, 40, 50, 60, 73, 84, 91, 94, 47, 45, 56, 69, 84, 95,
+ 101, 101, 53, 50, 60, 75, 92, 103, 108, 110, 61, 56, 65, 81, 100, 113,
+ 116, 118, 71, 64, 73, 89, 111, 125, 129, 129, 79, 70, 79, 95, 118, 133,
+ 142, 138, 86, 76, 84, 100, 124, 140, 153, 150, 92, 82, 89, 101, 121,
+ 148, 157, 161, 98, 88, 93, 108, 124, 141, 163, 174, 104, 94, 95, 110,
+ 129, 151, 171, 181, 110, 100, 98, 111, 127, 147, 169, 188],
+ /* Size 16x8 */
+ [32, 31, 32, 32, 36, 39, 47, 53, 61, 71, 79, 86, 92, 98, 104, 110, 32,
+ 32, 34, 35, 37, 40, 45, 50, 56, 64, 70, 76, 82, 88, 94, 100, 36, 35, 36,
+ 40, 48, 50, 56, 60, 65, 73, 79, 84, 89, 93, 95, 98, 47, 44, 45, 47, 56,
+ 60, 69, 75, 81, 89, 95, 100, 101, 108, 110, 111, 65, 60, 59, 60, 68, 73,
+ 84, 92, 100, 111, 118, 124, 121, 124, 129, 127, 79, 72, 71, 71, 78, 84,
+ 95, 103, 113, 125, 133, 140, 148, 141, 151, 147, 90, 84, 80, 78, 83, 91,
+ 101, 108, 116, 129, 142, 153, 157, 163, 171, 169, 96, 90, 87, 85, 87,
+ 94, 101, 110, 118, 129, 138, 150, 161, 174, 181, 188],
+ /* Size 16x32 */
+ [32, 31, 32, 32, 36, 44, 47, 53, 65, 73, 79, 87, 90, 93, 96, 99, 31, 32,
+ 32, 33, 35, 42, 45, 51, 62, 69, 75, 83, 86, 88, 91, 94, 31, 32, 32, 33,
+ 35, 41, 44, 49, 60, 67, 72, 80, 84, 87, 90, 94, 31, 32, 33, 33, 35, 41,
+ 44, 49, 59, 66, 71, 79, 82, 84, 87, 90, 32, 32, 34, 34, 36, 42, 45, 50,
+ 59, 65, 71, 78, 80, 83, 87, 90, 32, 33, 35, 36, 38, 42, 45, 49, 58, 64,
+ 69, 76, 80, 83, 86, 88, 32, 33, 35, 36, 40, 44, 47, 51, 60, 66, 71, 76,
+ 78, 81, 85, 89, 34, 34, 36, 38, 42, 48, 50, 54, 63, 69, 73, 80, 82, 81,
+ 84, 86, 36, 34, 37, 40, 48, 54, 56, 60, 68, 74, 78, 84, 83, 86, 87, 87,
+ 38, 36, 39, 41, 49, 56, 58, 63, 71, 77, 81, 86, 88, 88, 90, 93, 39, 37,
+ 40, 42, 50, 58, 60, 65, 73, 79, 84, 90, 91, 92, 94, 93, 44, 41, 42, 45,
+ 53, 63, 66, 71, 79, 85, 90, 96, 94, 96, 96, 99, 47, 44, 45, 47, 56, 66,
+ 69, 75, 84, 90, 95, 99, 101, 98, 101, 99, 49, 46, 47, 48, 57, 67, 71,
+ 77, 86, 93, 97, 103, 103, 105, 102, 106, 53, 49, 50, 51, 60, 71, 75, 82,
+ 92, 99, 103, 111, 108, 107, 110, 107, 58, 54, 54, 55, 63, 75, 79, 87,
+ 98, 105, 110, 114, 114, 113, 111, 115, 61, 56, 56, 57, 65, 77, 81, 89,
+ 100, 107, 113, 118, 116, 117, 118, 116, 65, 60, 59, 60, 68, 79, 84, 92,
+ 105, 112, 118, 126, 124, 122, 121, 124, 71, 65, 64, 65, 73, 84, 89, 97,
+ 111, 119, 125, 130, 129, 129, 129, 125, 76, 69, 68, 69, 76, 88, 92, 101,
+ 115, 123, 130, 134, 134, 131, 132, 135, 79, 72, 70, 71, 79, 90, 95, 104,
+ 118, 127, 133, 143, 142, 141, 138, 136, 82, 75, 73, 74, 81, 92, 97, 106,
+ 121, 130, 136, 146, 145, 144, 144, 145, 86, 78, 76, 77, 84, 95, 100,
+ 109, 124, 133, 140, 147, 153, 151, 150, 146, 89, 81, 79, 78, 87, 95, 99,
+ 112, 124, 130, 145, 152, 156, 157, 156, 158, 92, 84, 82, 80, 89, 95,
+ 101, 116, 121, 132, 148, 151, 157, 163, 161, 159, 95, 86, 85, 83, 92,
+ 95, 105, 114, 120, 136, 143, 155, 163, 167, 171, 170, 98, 89, 88, 85,
+ 93, 95, 108, 113, 124, 136, 141, 160, 163, 169, 174, 171, 101, 92, 91,
+ 88, 94, 98, 110, 112, 128, 133, 146, 158, 166, 175, 179, 185, 104, 95,
+ 94, 91, 95, 101, 110, 115, 129, 132, 151, 154, 171, 175, 181, 186, 107,
+ 98, 97, 94, 96, 105, 110, 119, 128, 136, 149, 156, 173, 177, 188, 192,
+ 110, 101, 100, 97, 98, 108, 111, 123, 127, 141, 147, 161, 169, 183, 188,
+ 193, 114, 104, 104, 100, 100, 111, 111, 126, 127, 145, 145, 166, 166,
+ 189, 190, 201],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 32, 32, 32, 34, 36, 38, 39, 44, 47, 49, 53, 58, 61, 65,
+ 71, 76, 79, 82, 86, 89, 92, 95, 98, 101, 104, 107, 110, 114, 31, 32, 32,
+ 32, 32, 33, 33, 34, 34, 36, 37, 41, 44, 46, 49, 54, 56, 60, 65, 69, 72,
+ 75, 78, 81, 84, 86, 89, 92, 95, 98, 101, 104, 32, 32, 32, 33, 34, 35,
+ 35, 36, 37, 39, 40, 42, 45, 47, 50, 54, 56, 59, 64, 68, 70, 73, 76, 79,
+ 82, 85, 88, 91, 94, 97, 100, 104, 32, 33, 33, 33, 34, 36, 36, 38, 40,
+ 41, 42, 45, 47, 48, 51, 55, 57, 60, 65, 69, 71, 74, 77, 78, 80, 83, 85,
+ 88, 91, 94, 97, 100, 36, 35, 35, 35, 36, 38, 40, 42, 48, 49, 50, 53, 56,
+ 57, 60, 63, 65, 68, 73, 76, 79, 81, 84, 87, 89, 92, 93, 94, 95, 96, 98,
+ 100, 44, 42, 41, 41, 42, 42, 44, 48, 54, 56, 58, 63, 66, 67, 71, 75, 77,
+ 79, 84, 88, 90, 92, 95, 95, 95, 95, 95, 98, 101, 105, 108, 111, 47, 45,
+ 44, 44, 45, 45, 47, 50, 56, 58, 60, 66, 69, 71, 75, 79, 81, 84, 89, 92,
+ 95, 97, 100, 99, 101, 105, 108, 110, 110, 110, 111, 111, 53, 51, 49, 49,
+ 50, 49, 51, 54, 60, 63, 65, 71, 75, 77, 82, 87, 89, 92, 97, 101, 104,
+ 106, 109, 112, 116, 114, 113, 112, 115, 119, 123, 126, 65, 62, 60, 59,
+ 59, 58, 60, 63, 68, 71, 73, 79, 84, 86, 92, 98, 100, 105, 111, 115, 118,
+ 121, 124, 124, 121, 120, 124, 128, 129, 128, 127, 127, 73, 69, 67, 66,
+ 65, 64, 66, 69, 74, 77, 79, 85, 90, 93, 99, 105, 107, 112, 119, 123,
+ 127, 130, 133, 130, 132, 136, 136, 133, 132, 136, 141, 145, 79, 75, 72,
+ 71, 71, 69, 71, 73, 78, 81, 84, 90, 95, 97, 103, 110, 113, 118, 125,
+ 130, 133, 136, 140, 145, 148, 143, 141, 146, 151, 149, 147, 145, 87, 83,
+ 80, 79, 78, 76, 76, 80, 84, 86, 90, 96, 99, 103, 111, 114, 118, 126,
+ 130, 134, 143, 146, 147, 152, 151, 155, 160, 158, 154, 156, 161, 166,
+ 90, 86, 84, 82, 80, 80, 78, 82, 83, 88, 91, 94, 101, 103, 108, 114, 116,
+ 124, 129, 134, 142, 145, 153, 156, 157, 163, 163, 166, 171, 173, 169,
+ 166, 93, 88, 87, 84, 83, 83, 81, 81, 86, 88, 92, 96, 98, 105, 107, 113,
+ 117, 122, 129, 131, 141, 144, 151, 157, 163, 167, 169, 175, 175, 177,
+ 183, 189, 96, 91, 90, 87, 87, 86, 85, 84, 87, 90, 94, 96, 101, 102, 110,
+ 111, 118, 121, 129, 132, 138, 144, 150, 156, 161, 171, 174, 179, 181,
+ 188, 188, 190, 99, 94, 94, 90, 90, 88, 89, 86, 87, 93, 93, 99, 99, 106,
+ 107, 115, 116, 124, 125, 135, 136, 145, 146, 158, 159, 170, 171, 185,
+ 186, 192, 193, 201],
+ /* Size 4x16 */
+ [31, 44, 73, 93, 32, 41, 67, 87, 32, 42, 65, 83, 33, 44, 66, 81, 34, 54,
+ 74, 86, 37, 58, 79, 92, 44, 66, 90, 98, 49, 71, 99, 107, 56, 77, 107,
+ 117, 65, 84, 119, 129, 72, 90, 127, 141, 78, 95, 133, 151, 84, 95, 132,
+ 163, 89, 95, 136, 169, 95, 101, 132, 175, 101, 108, 141, 183],
+ /* Size 16x4 */
+ [31, 32, 32, 33, 34, 37, 44, 49, 56, 65, 72, 78, 84, 89, 95, 101, 44, 41,
+ 42, 44, 54, 58, 66, 71, 77, 84, 90, 95, 95, 95, 101, 108, 73, 67, 65,
+ 66, 74, 79, 90, 99, 107, 119, 127, 133, 132, 136, 132, 141, 93, 87, 83,
+ 81, 86, 92, 98, 107, 117, 129, 141, 151, 163, 169, 175, 183],
+ /* Size 8x32 */
+ [32, 32, 36, 47, 65, 79, 90, 96, 31, 32, 35, 45, 62, 75, 86, 91, 31, 32,
+ 35, 44, 60, 72, 84, 90, 31, 33, 35, 44, 59, 71, 82, 87, 32, 34, 36, 45,
+ 59, 71, 80, 87, 32, 35, 38, 45, 58, 69, 80, 86, 32, 35, 40, 47, 60, 71,
+ 78, 85, 34, 36, 42, 50, 63, 73, 82, 84, 36, 37, 48, 56, 68, 78, 83, 87,
+ 38, 39, 49, 58, 71, 81, 88, 90, 39, 40, 50, 60, 73, 84, 91, 94, 44, 42,
+ 53, 66, 79, 90, 94, 96, 47, 45, 56, 69, 84, 95, 101, 101, 49, 47, 57,
+ 71, 86, 97, 103, 102, 53, 50, 60, 75, 92, 103, 108, 110, 58, 54, 63, 79,
+ 98, 110, 114, 111, 61, 56, 65, 81, 100, 113, 116, 118, 65, 59, 68, 84,
+ 105, 118, 124, 121, 71, 64, 73, 89, 111, 125, 129, 129, 76, 68, 76, 92,
+ 115, 130, 134, 132, 79, 70, 79, 95, 118, 133, 142, 138, 82, 73, 81, 97,
+ 121, 136, 145, 144, 86, 76, 84, 100, 124, 140, 153, 150, 89, 79, 87, 99,
+ 124, 145, 156, 156, 92, 82, 89, 101, 121, 148, 157, 161, 95, 85, 92,
+ 105, 120, 143, 163, 171, 98, 88, 93, 108, 124, 141, 163, 174, 101, 91,
+ 94, 110, 128, 146, 166, 179, 104, 94, 95, 110, 129, 151, 171, 181, 107,
+ 97, 96, 110, 128, 149, 173, 188, 110, 100, 98, 111, 127, 147, 169, 188,
+ 114, 104, 100, 111, 127, 145, 166, 190],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 32, 32, 32, 34, 36, 38, 39, 44, 47, 49, 53, 58, 61, 65,
+ 71, 76, 79, 82, 86, 89, 92, 95, 98, 101, 104, 107, 110, 114, 32, 32, 32,
+ 33, 34, 35, 35, 36, 37, 39, 40, 42, 45, 47, 50, 54, 56, 59, 64, 68, 70,
+ 73, 76, 79, 82, 85, 88, 91, 94, 97, 100, 104, 36, 35, 35, 35, 36, 38,
+ 40, 42, 48, 49, 50, 53, 56, 57, 60, 63, 65, 68, 73, 76, 79, 81, 84, 87,
+ 89, 92, 93, 94, 95, 96, 98, 100, 47, 45, 44, 44, 45, 45, 47, 50, 56, 58,
+ 60, 66, 69, 71, 75, 79, 81, 84, 89, 92, 95, 97, 100, 99, 101, 105, 108,
+ 110, 110, 110, 111, 111, 65, 62, 60, 59, 59, 58, 60, 63, 68, 71, 73, 79,
+ 84, 86, 92, 98, 100, 105, 111, 115, 118, 121, 124, 124, 121, 120, 124,
+ 128, 129, 128, 127, 127, 79, 75, 72, 71, 71, 69, 71, 73, 78, 81, 84, 90,
+ 95, 97, 103, 110, 113, 118, 125, 130, 133, 136, 140, 145, 148, 143, 141,
+ 146, 151, 149, 147, 145, 90, 86, 84, 82, 80, 80, 78, 82, 83, 88, 91, 94,
+ 101, 103, 108, 114, 116, 124, 129, 134, 142, 145, 153, 156, 157, 163,
+ 163, 166, 171, 173, 169, 166, 96, 91, 90, 87, 87, 86, 85, 84, 87, 90,
+ 94, 96, 101, 102, 110, 111, 118, 121, 129, 132, 138, 144, 150, 156, 161,
+ 171, 174, 179, 181, 188, 188, 190]
+ ],
+ [ /* Chroma */
+ /* Size 4x4 */
+ [33, 45, 56, 64, 45, 58, 66, 69, 56, 66, 86, 87, 64, 69, 87, 105],
+ /* Size 8x8 */
+ [31, 38, 47, 48, 54, 61, 66, 69, 38, 47, 47, 46, 50, 55, 61, 65, 47, 47,
+ 53, 55, 58, 63, 65, 66, 48, 46, 55, 62, 67, 72, 73, 73, 54, 50, 58, 67,
+ 76, 83, 84, 82, 61, 55, 63, 72, 83, 91, 92, 92, 66, 61, 65, 73, 84, 92,
+ 101, 103, 69, 65, 66, 73, 82, 92, 103, 109],
+ /* Size 16x16 */
+ [32, 30, 33, 38, 49, 48, 50, 52, 55, 60, 63, 66, 68, 70, 72, 74, 30, 31,
+ 35, 41, 46, 46, 46, 48, 51, 55, 58, 60, 63, 65, 68, 70, 33, 35, 39, 44,
+ 47, 46, 46, 47, 50, 53, 56, 58, 60, 62, 65, 67, 38, 41, 44, 47, 49, 48,
+ 47, 48, 50, 53, 55, 58, 58, 60, 62, 65, 49, 46, 47, 49, 53, 53, 54, 54,
+ 56, 58, 60, 62, 62, 63, 64, 64, 48, 46, 46, 48, 53, 54, 56, 57, 59, 61,
+ 63, 65, 67, 66, 68, 68, 50, 46, 46, 47, 54, 56, 61, 63, 65, 68, 70, 72,
+ 71, 71, 72, 72, 52, 48, 47, 48, 54, 57, 63, 66, 69, 72, 75, 76, 75, 76,
+ 76, 76, 55, 51, 50, 50, 56, 59, 65, 69, 73, 77, 79, 81, 81, 81, 80, 80,
+ 60, 55, 53, 53, 58, 61, 68, 72, 77, 82, 85, 87, 87, 85, 84, 85, 63, 58,
+ 56, 55, 60, 63, 70, 75, 79, 85, 89, 91, 91, 90, 89, 90, 66, 60, 58, 58,
+ 62, 65, 72, 76, 81, 87, 91, 94, 96, 95, 95, 95, 68, 63, 60, 58, 62, 67,
+ 71, 75, 81, 87, 91, 96, 99, 100, 100, 100, 70, 65, 62, 60, 63, 66, 71,
+ 76, 81, 85, 90, 95, 100, 103, 104, 105, 72, 68, 65, 62, 64, 68, 72, 76,
+ 80, 84, 89, 95, 100, 104, 107, 108, 74, 70, 67, 65, 64, 68, 72, 76, 80,
+ 85, 90, 95, 100, 105, 108, 111],
+ /* Size 32x32 */
+ [32, 31, 30, 31, 33, 36, 38, 41, 49, 49, 48, 49, 50, 51, 52, 54, 55, 57,
+ 60, 62, 63, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 31, 31, 31, 32,
+ 34, 38, 40, 42, 47, 47, 47, 47, 48, 48, 50, 52, 53, 54, 57, 59, 60, 61,
+ 63, 64, 65, 66, 67, 67, 68, 69, 70, 71, 30, 31, 31, 32, 35, 39, 41, 42,
+ 46, 46, 46, 45, 46, 47, 48, 50, 51, 52, 55, 57, 58, 59, 60, 62, 63, 64,
+ 65, 67, 68, 69, 70, 71, 31, 32, 32, 33, 36, 40, 41, 43, 46, 46, 45, 45,
+ 46, 46, 47, 49, 50, 51, 54, 56, 57, 58, 59, 61, 62, 63, 63, 64, 65, 66,
+ 67, 68, 33, 34, 35, 36, 39, 43, 44, 45, 47, 46, 46, 45, 46, 47, 47, 49,
+ 50, 51, 53, 55, 56, 57, 58, 59, 60, 61, 62, 63, 65, 66, 67, 68, 36, 38,
+ 39, 40, 43, 47, 47, 47, 48, 47, 46, 45, 46, 46, 47, 48, 49, 50, 52, 53,
+ 54, 55, 56, 58, 59, 61, 62, 63, 64, 65, 66, 66, 38, 40, 41, 41, 44, 47,
+ 47, 48, 49, 48, 48, 47, 47, 47, 48, 49, 50, 51, 53, 54, 55, 56, 58, 58,
+ 58, 59, 60, 61, 62, 64, 65, 66, 41, 42, 42, 43, 45, 47, 48, 48, 50, 50,
+ 49, 49, 50, 50, 50, 52, 52, 53, 55, 56, 57, 58, 59, 60, 61, 61, 61, 61,
+ 62, 63, 63, 64, 49, 47, 46, 46, 47, 48, 49, 50, 53, 53, 53, 53, 54, 54,
+ 54, 55, 56, 56, 58, 59, 60, 61, 62, 63, 62, 62, 63, 64, 64, 64, 64, 64,
+ 49, 47, 46, 46, 46, 47, 48, 50, 53, 53, 54, 55, 55, 55, 56, 57, 58, 58,
+ 60, 61, 62, 63, 64, 64, 64, 65, 65, 65, 65, 66, 67, 68, 48, 47, 46, 45,
+ 46, 46, 48, 49, 53, 54, 54, 55, 56, 56, 57, 58, 59, 60, 61, 63, 63, 64,
+ 65, 66, 67, 66, 66, 67, 68, 68, 68, 68, 49, 47, 45, 45, 45, 45, 47, 49,
+ 53, 55, 55, 58, 59, 60, 61, 62, 63, 63, 65, 66, 67, 68, 69, 69, 68, 68,
+ 69, 69, 69, 69, 70, 71, 50, 48, 46, 46, 46, 46, 47, 50, 54, 55, 56, 59,
+ 61, 61, 63, 64, 65, 66, 68, 69, 70, 71, 72, 71, 71, 72, 71, 71, 72, 72,
+ 72, 71, 51, 48, 47, 46, 47, 46, 47, 50, 54, 55, 56, 60, 61, 62, 64, 66,
+ 66, 67, 69, 70, 71, 72, 73, 73, 74, 73, 73, 74, 73, 73, 74, 75, 52, 50,
+ 48, 47, 47, 47, 48, 50, 54, 56, 57, 61, 63, 64, 66, 68, 69, 70, 72, 74,
+ 75, 75, 76, 77, 75, 76, 76, 75, 76, 77, 76, 75, 54, 52, 50, 49, 49, 48,
+ 49, 52, 55, 57, 58, 62, 64, 66, 68, 71, 72, 73, 75, 77, 78, 79, 80, 78,
+ 79, 78, 77, 78, 78, 77, 78, 79, 55, 53, 51, 50, 50, 49, 50, 52, 56, 58,
+ 59, 63, 65, 66, 69, 72, 73, 74, 77, 78, 79, 80, 81, 81, 81, 80, 81, 80,
+ 80, 81, 80, 79, 57, 54, 52, 51, 51, 50, 51, 53, 56, 58, 60, 63, 66, 67,
+ 70, 73, 74, 76, 79, 80, 82, 83, 84, 85, 83, 84, 83, 83, 83, 82, 82, 83,
+ 60, 57, 55, 54, 53, 52, 53, 55, 58, 60, 61, 65, 68, 69, 72, 75, 77, 79,
+ 82, 84, 85, 86, 87, 86, 87, 85, 85, 85, 84, 86, 85, 84, 62, 59, 57, 56,
+ 55, 53, 54, 56, 59, 61, 63, 66, 69, 70, 74, 77, 78, 80, 84, 86, 87, 88,
+ 90, 89, 89, 88, 88, 87, 88, 87, 87, 88, 63, 60, 58, 57, 56, 54, 55, 57,
+ 60, 62, 63, 67, 70, 71, 75, 78, 79, 82, 85, 87, 89, 90, 91, 93, 91, 91,
+ 90, 91, 89, 90, 90, 89, 65, 61, 59, 58, 57, 55, 56, 58, 61, 63, 64, 68,
+ 71, 72, 75, 79, 80, 83, 86, 88, 90, 91, 93, 94, 95, 92, 94, 92, 93, 92,
+ 91, 93, 66, 63, 60, 59, 58, 56, 58, 59, 62, 64, 65, 69, 72, 73, 76, 80,
+ 81, 84, 87, 90, 91, 93, 94, 95, 96, 97, 95, 95, 95, 95, 95, 93, 67, 64,
+ 62, 61, 59, 58, 58, 60, 63, 64, 66, 69, 71, 73, 77, 78, 81, 85, 86, 89,
+ 93, 94, 95, 97, 97, 98, 99, 97, 97, 97, 96, 98, 68, 65, 63, 62, 60, 59,
+ 58, 61, 62, 64, 67, 68, 71, 74, 75, 79, 81, 83, 87, 89, 91, 95, 96, 97,
+ 99, 98, 100, 100, 100, 99, 100, 98, 69, 66, 64, 63, 61, 61, 59, 61, 62,
+ 65, 66, 68, 72, 73, 76, 78, 80, 84, 85, 88, 91, 92, 97, 98, 98, 101,
+ 100, 102, 102, 103, 101, 102, 70, 67, 65, 63, 62, 62, 60, 61, 63, 65,
+ 66, 69, 71, 73, 76, 77, 81, 83, 85, 88, 90, 94, 95, 99, 100, 100, 103,
+ 102, 104, 104, 105, 103, 71, 67, 67, 64, 63, 63, 61, 61, 64, 65, 67, 69,
+ 71, 74, 75, 78, 80, 83, 85, 87, 91, 92, 95, 97, 100, 102, 102, 105, 104,
+ 106, 106, 108, 72, 68, 68, 65, 65, 64, 62, 62, 64, 65, 68, 69, 72, 73,
+ 76, 78, 80, 83, 84, 88, 89, 93, 95, 97, 100, 102, 104, 104, 107, 106,
+ 108, 108, 73, 69, 69, 66, 66, 65, 64, 63, 64, 66, 68, 69, 72, 73, 77,
+ 77, 81, 82, 86, 87, 90, 92, 95, 97, 99, 103, 104, 106, 106, 109, 108,
+ 110, 74, 70, 70, 67, 67, 66, 65, 63, 64, 67, 68, 70, 72, 74, 76, 78, 80,
+ 82, 85, 87, 90, 91, 95, 96, 100, 101, 105, 106, 108, 108, 111, 110, 75,
+ 71, 71, 68, 68, 66, 66, 64, 64, 68, 68, 71, 71, 75, 75, 79, 79, 83, 84,
+ 88, 89, 93, 93, 98, 98, 102, 103, 108, 108, 110, 110, 113],
+ /* Size 4x8 */
+ [31, 47, 57, 65, 40, 45, 52, 61, 46, 55, 61, 63, 47, 60, 70, 72, 52, 64,
+ 79, 81, 59, 68, 87, 90, 63, 66, 88, 99, 66, 69, 85, 102],
+ /* Size 8x4 */
+ [31, 40, 46, 47, 52, 59, 63, 66, 47, 45, 55, 60, 64, 68, 66, 69, 57, 52,
+ 61, 70, 79, 87, 88, 85, 65, 61, 63, 72, 81, 90, 99, 102],
+ /* Size 8x16 */
+ [32, 35, 48, 50, 57, 63, 68, 70, 30, 38, 46, 46, 52, 58, 63, 65, 33, 41,
+ 47, 46, 51, 56, 60, 63, 39, 46, 48, 47, 51, 55, 58, 61, 49, 48, 53, 54,
+ 57, 60, 61, 61, 48, 46, 53, 56, 60, 64, 65, 65, 50, 46, 54, 61, 66, 70,
+ 71, 69, 52, 47, 54, 63, 71, 75, 75, 74, 55, 49, 56, 65, 74, 79, 79, 78,
+ 60, 53, 58, 68, 79, 85, 85, 82, 63, 55, 60, 70, 82, 89, 91, 87, 66, 58,
+ 62, 72, 84, 91, 95, 91, 68, 60, 64, 71, 81, 94, 97, 96, 70, 62, 65, 73,
+ 81, 89, 98, 101, 72, 65, 65, 72, 82, 92, 100, 103, 74, 67, 65, 71, 79,
+ 89, 98, 105],
+ /* Size 16x8 */
+ [32, 30, 33, 39, 49, 48, 50, 52, 55, 60, 63, 66, 68, 70, 72, 74, 35, 38,
+ 41, 46, 48, 46, 46, 47, 49, 53, 55, 58, 60, 62, 65, 67, 48, 46, 47, 48,
+ 53, 53, 54, 54, 56, 58, 60, 62, 64, 65, 65, 65, 50, 46, 46, 47, 54, 56,
+ 61, 63, 65, 68, 70, 72, 71, 73, 72, 71, 57, 52, 51, 51, 57, 60, 66, 71,
+ 74, 79, 82, 84, 81, 81, 82, 79, 63, 58, 56, 55, 60, 64, 70, 75, 79, 85,
+ 89, 91, 94, 89, 92, 89, 68, 63, 60, 58, 61, 65, 71, 75, 79, 85, 91, 95,
+ 97, 98, 100, 98, 70, 65, 63, 61, 61, 65, 69, 74, 78, 82, 87, 91, 96,
+ 101, 103, 105],
+ /* Size 16x32 */
+ [32, 31, 35, 38, 48, 49, 50, 52, 57, 61, 63, 67, 68, 69, 70, 71, 31, 31,
+ 37, 40, 47, 47, 48, 50, 54, 57, 60, 63, 64, 65, 66, 67, 30, 32, 38, 40,
+ 46, 45, 46, 48, 52, 55, 58, 61, 63, 64, 65, 67, 31, 33, 38, 41, 46, 45,
+ 46, 48, 52, 55, 57, 60, 61, 62, 63, 64, 33, 36, 41, 44, 47, 46, 46, 47,
+ 51, 54, 56, 59, 60, 61, 63, 64, 37, 40, 45, 47, 47, 45, 46, 47, 50, 52,
+ 54, 57, 59, 61, 62, 62, 39, 41, 46, 47, 48, 47, 47, 48, 51, 54, 55, 57,
+ 58, 59, 61, 62, 42, 43, 46, 48, 50, 49, 50, 50, 53, 56, 57, 60, 60, 59,
+ 60, 60, 49, 46, 48, 49, 53, 53, 54, 54, 57, 59, 60, 63, 61, 62, 61, 61,
+ 48, 46, 47, 48, 53, 55, 55, 56, 58, 61, 62, 64, 64, 63, 63, 64, 48, 46,
+ 46, 48, 53, 56, 56, 57, 60, 62, 64, 66, 65, 65, 65, 64, 49, 45, 45, 47,
+ 53, 58, 59, 61, 64, 66, 67, 69, 67, 67, 66, 67, 50, 46, 46, 48, 54, 59,
+ 61, 63, 66, 68, 70, 71, 71, 68, 69, 67, 51, 47, 47, 48, 54, 60, 61, 64,
+ 68, 70, 71, 73, 72, 72, 70, 71, 52, 48, 47, 48, 54, 61, 63, 66, 71, 73,
+ 75, 77, 75, 73, 74, 71, 54, 50, 49, 50, 55, 62, 65, 68, 73, 76, 78, 79,
+ 78, 76, 74, 75, 55, 51, 49, 50, 56, 63, 65, 69, 74, 77, 79, 81, 79, 78,
+ 78, 75, 57, 52, 50, 51, 56, 64, 66, 70, 76, 79, 82, 85, 83, 81, 79, 79,
+ 60, 54, 53, 53, 58, 65, 68, 72, 79, 82, 85, 87, 85, 84, 82, 80, 62, 56,
+ 54, 55, 60, 66, 69, 74, 81, 84, 87, 88, 87, 85, 84, 84, 63, 57, 55, 56,
+ 60, 67, 70, 75, 82, 86, 89, 92, 91, 89, 87, 84, 64, 59, 56, 57, 61, 68,
+ 71, 75, 83, 87, 90, 93, 92, 90, 89, 89, 66, 60, 58, 58, 62, 69, 72, 76,
+ 84, 88, 91, 94, 95, 93, 91, 89, 67, 61, 59, 58, 63, 68, 71, 78, 83, 86,
+ 93, 96, 96, 96, 94, 94, 68, 62, 60, 59, 64, 67, 71, 79, 81, 86, 94, 95,
+ 97, 98, 96, 94, 69, 63, 61, 60, 65, 66, 72, 77, 80, 88, 91, 96, 99, 99,
+ 100, 98, 70, 64, 62, 60, 65, 66, 73, 76, 81, 87, 89, 97, 98, 100, 101,
+ 99, 71, 65, 64, 61, 65, 67, 73, 74, 82, 85, 90, 95, 99, 102, 103, 104,
+ 72, 65, 65, 62, 65, 68, 72, 75, 82, 83, 92, 93, 100, 102, 103, 104, 73,
+ 66, 66, 63, 65, 69, 72, 76, 81, 85, 90, 93, 100, 102, 105, 106, 74, 67,
+ 67, 64, 65, 70, 71, 77, 79, 86, 89, 94, 98, 103, 105, 106, 75, 68, 68,
+ 65, 65, 71, 71, 78, 78, 87, 87, 96, 96, 105, 105, 109],
+ /* Size 32x16 */
+ [32, 31, 30, 31, 33, 37, 39, 42, 49, 48, 48, 49, 50, 51, 52, 54, 55, 57,
+ 60, 62, 63, 64, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 31, 31, 32, 33,
+ 36, 40, 41, 43, 46, 46, 46, 45, 46, 47, 48, 50, 51, 52, 54, 56, 57, 59,
+ 60, 61, 62, 63, 64, 65, 65, 66, 67, 68, 35, 37, 38, 38, 41, 45, 46, 46,
+ 48, 47, 46, 45, 46, 47, 47, 49, 49, 50, 53, 54, 55, 56, 58, 59, 60, 61,
+ 62, 64, 65, 66, 67, 68, 38, 40, 40, 41, 44, 47, 47, 48, 49, 48, 48, 47,
+ 48, 48, 48, 50, 50, 51, 53, 55, 56, 57, 58, 58, 59, 60, 60, 61, 62, 63,
+ 64, 65, 48, 47, 46, 46, 47, 47, 48, 50, 53, 53, 53, 53, 54, 54, 54, 55,
+ 56, 56, 58, 60, 60, 61, 62, 63, 64, 65, 65, 65, 65, 65, 65, 65, 49, 47,
+ 45, 45, 46, 45, 47, 49, 53, 55, 56, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68, 69, 68, 67, 66, 66, 67, 68, 69, 70, 71, 50, 48, 46, 46, 46, 46,
+ 47, 50, 54, 55, 56, 59, 61, 61, 63, 65, 65, 66, 68, 69, 70, 71, 72, 71,
+ 71, 72, 73, 73, 72, 72, 71, 71, 52, 50, 48, 48, 47, 47, 48, 50, 54, 56,
+ 57, 61, 63, 64, 66, 68, 69, 70, 72, 74, 75, 75, 76, 78, 79, 77, 76, 74,
+ 75, 76, 77, 78, 57, 54, 52, 52, 51, 50, 51, 53, 57, 58, 60, 64, 66, 68,
+ 71, 73, 74, 76, 79, 81, 82, 83, 84, 83, 81, 80, 81, 82, 82, 81, 79, 78,
+ 61, 57, 55, 55, 54, 52, 54, 56, 59, 61, 62, 66, 68, 70, 73, 76, 77, 79,
+ 82, 84, 86, 87, 88, 86, 86, 88, 87, 85, 83, 85, 86, 87, 63, 60, 58, 57,
+ 56, 54, 55, 57, 60, 62, 64, 67, 70, 71, 75, 78, 79, 82, 85, 87, 89, 90,
+ 91, 93, 94, 91, 89, 90, 92, 90, 89, 87, 67, 63, 61, 60, 59, 57, 57, 60,
+ 63, 64, 66, 69, 71, 73, 77, 79, 81, 85, 87, 88, 92, 93, 94, 96, 95, 96,
+ 97, 95, 93, 93, 94, 96, 68, 64, 63, 61, 60, 59, 58, 60, 61, 64, 65, 67,
+ 71, 72, 75, 78, 79, 83, 85, 87, 91, 92, 95, 96, 97, 99, 98, 99, 100,
+ 100, 98, 96, 69, 65, 64, 62, 61, 61, 59, 59, 62, 63, 65, 67, 68, 72, 73,
+ 76, 78, 81, 84, 85, 89, 90, 93, 96, 98, 99, 100, 102, 102, 102, 103,
+ 105, 70, 66, 65, 63, 63, 62, 61, 60, 61, 63, 65, 66, 69, 70, 74, 74, 78,
+ 79, 82, 84, 87, 89, 91, 94, 96, 100, 101, 103, 103, 105, 105, 105, 71,
+ 67, 67, 64, 64, 62, 62, 60, 61, 64, 64, 67, 67, 71, 71, 75, 75, 79, 80,
+ 84, 84, 89, 89, 94, 94, 98, 99, 104, 104, 106, 106, 109],
+ /* Size 4x16 */
+ [31, 49, 61, 69, 32, 45, 55, 64, 36, 46, 54, 61, 41, 47, 54, 59, 46, 53,
+ 59, 62, 46, 56, 62, 65, 46, 59, 68, 68, 48, 61, 73, 73, 51, 63, 77, 78,
+ 54, 65, 82, 84, 57, 67, 86, 89, 60, 69, 88, 93, 62, 67, 86, 98, 64, 66,
+ 87, 100, 65, 68, 83, 102, 67, 70, 86, 103],
+ /* Size 16x4 */
+ [31, 32, 36, 41, 46, 46, 46, 48, 51, 54, 57, 60, 62, 64, 65, 67, 49, 45,
+ 46, 47, 53, 56, 59, 61, 63, 65, 67, 69, 67, 66, 68, 70, 61, 55, 54, 54,
+ 59, 62, 68, 73, 77, 82, 86, 88, 86, 87, 83, 86, 69, 64, 61, 59, 62, 65,
+ 68, 73, 78, 84, 89, 93, 98, 100, 102, 103],
+ /* Size 8x32 */
+ [32, 35, 48, 50, 57, 63, 68, 70, 31, 37, 47, 48, 54, 60, 64, 66, 30, 38,
+ 46, 46, 52, 58, 63, 65, 31, 38, 46, 46, 52, 57, 61, 63, 33, 41, 47, 46,
+ 51, 56, 60, 63, 37, 45, 47, 46, 50, 54, 59, 62, 39, 46, 48, 47, 51, 55,
+ 58, 61, 42, 46, 50, 50, 53, 57, 60, 60, 49, 48, 53, 54, 57, 60, 61, 61,
+ 48, 47, 53, 55, 58, 62, 64, 63, 48, 46, 53, 56, 60, 64, 65, 65, 49, 45,
+ 53, 59, 64, 67, 67, 66, 50, 46, 54, 61, 66, 70, 71, 69, 51, 47, 54, 61,
+ 68, 71, 72, 70, 52, 47, 54, 63, 71, 75, 75, 74, 54, 49, 55, 65, 73, 78,
+ 78, 74, 55, 49, 56, 65, 74, 79, 79, 78, 57, 50, 56, 66, 76, 82, 83, 79,
+ 60, 53, 58, 68, 79, 85, 85, 82, 62, 54, 60, 69, 81, 87, 87, 84, 63, 55,
+ 60, 70, 82, 89, 91, 87, 64, 56, 61, 71, 83, 90, 92, 89, 66, 58, 62, 72,
+ 84, 91, 95, 91, 67, 59, 63, 71, 83, 93, 96, 94, 68, 60, 64, 71, 81, 94,
+ 97, 96, 69, 61, 65, 72, 80, 91, 99, 100, 70, 62, 65, 73, 81, 89, 98,
+ 101, 71, 64, 65, 73, 82, 90, 99, 103, 72, 65, 65, 72, 82, 92, 100, 103,
+ 73, 66, 65, 72, 81, 90, 100, 105, 74, 67, 65, 71, 79, 89, 98, 105, 75,
+ 68, 65, 71, 78, 87, 96, 105],
+ /* Size 32x8 */
+ [32, 31, 30, 31, 33, 37, 39, 42, 49, 48, 48, 49, 50, 51, 52, 54, 55, 57,
+ 60, 62, 63, 64, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 35, 37, 38, 38,
+ 41, 45, 46, 46, 48, 47, 46, 45, 46, 47, 47, 49, 49, 50, 53, 54, 55, 56,
+ 58, 59, 60, 61, 62, 64, 65, 66, 67, 68, 48, 47, 46, 46, 47, 47, 48, 50,
+ 53, 53, 53, 53, 54, 54, 54, 55, 56, 56, 58, 60, 60, 61, 62, 63, 64, 65,
+ 65, 65, 65, 65, 65, 65, 50, 48, 46, 46, 46, 46, 47, 50, 54, 55, 56, 59,
+ 61, 61, 63, 65, 65, 66, 68, 69, 70, 71, 72, 71, 71, 72, 73, 73, 72, 72,
+ 71, 71, 57, 54, 52, 52, 51, 50, 51, 53, 57, 58, 60, 64, 66, 68, 71, 73,
+ 74, 76, 79, 81, 82, 83, 84, 83, 81, 80, 81, 82, 82, 81, 79, 78, 63, 60,
+ 58, 57, 56, 54, 55, 57, 60, 62, 64, 67, 70, 71, 75, 78, 79, 82, 85, 87,
+ 89, 90, 91, 93, 94, 91, 89, 90, 92, 90, 89, 87, 68, 64, 63, 61, 60, 59,
+ 58, 60, 61, 64, 65, 67, 71, 72, 75, 78, 79, 83, 85, 87, 91, 92, 95, 96,
+ 97, 99, 98, 99, 100, 100, 98, 96, 70, 66, 65, 63, 63, 62, 61, 60, 61,
+ 63, 65, 66, 69, 70, 74, 74, 78, 79, 82, 84, 87, 89, 91, 94, 96, 100,
+ 101, 103, 103, 105, 105, 105]
+ ]
+ ],
+ [
+ [ /* Luma */
+ /* Size 4x4 */
+ [32, 38, 63, 86, 38, 56, 78, 97, 63, 78, 113, 130, 86, 97, 130, 169],
+ /* Size 8x8 */
+ [32, 32, 35, 46, 57, 76, 85, 96, 32, 34, 37, 45, 54, 70, 79, 90, 35, 37,
+ 48, 56, 64, 79, 87, 93, 46, 45, 56, 70, 80, 96, 100, 105, 57, 54, 64,
+ 80, 93, 111, 121, 122, 76, 70, 79, 96, 111, 134, 138, 144, 85, 79, 87,
+ 100, 121, 138, 156, 168, 96, 90, 93, 105, 122, 144, 168, 184],
+ /* Size 16x16 */
+ [32, 31, 31, 32, 34, 39, 44, 49, 58, 65, 71, 81, 87, 93, 98, 104, 31, 32,
+ 32, 32, 34, 38, 41, 46, 54, 60, 66, 75, 81, 86, 92, 98, 31, 32, 33, 34,
+ 36, 39, 42, 46, 53, 59, 64, 73, 78, 83, 88, 94, 32, 32, 34, 35, 37, 40,
+ 42, 46, 52, 58, 63, 71, 75, 80, 86, 92, 34, 34, 36, 37, 42, 47, 50, 53,
+ 59, 65, 70, 77, 82, 85, 89, 92, 39, 38, 39, 40, 47, 54, 58, 62, 68, 73,
+ 78, 85, 90, 90, 96, 98, 44, 41, 42, 42, 50, 58, 63, 68, 74, 79, 84, 91,
+ 96, 98, 102, 104, 49, 46, 46, 46, 53, 62, 68, 73, 81, 87, 92, 99, 103,
+ 107, 109, 112, 58, 54, 53, 52, 59, 68, 74, 81, 90, 97, 102, 110, 114,
+ 118, 117, 121, 65, 60, 59, 58, 65, 73, 79, 87, 97, 105, 111, 120, 125,
+ 125, 126, 130, 71, 66, 64, 63, 70, 78, 84, 92, 102, 111, 117, 127, 133,
+ 134, 136, 141, 81, 75, 73, 71, 77, 85, 91, 99, 110, 120, 127, 137, 143,
+ 145, 148, 152, 87, 81, 78, 75, 82, 90, 96, 103, 114, 125, 133, 143, 150,
+ 156, 160, 163, 93, 86, 83, 80, 85, 90, 98, 107, 118, 125, 134, 145, 156,
+ 163, 169, 177, 98, 92, 88, 86, 89, 96, 102, 109, 117, 126, 136, 148,
+ 160, 169, 176, 184, 104, 98, 94, 92, 92, 98, 104, 112, 121, 130, 141,
+ 152, 163, 177, 184, 191],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 32, 32, 34, 34, 36, 39, 41, 44, 48, 49, 54, 58, 59,
+ 65, 69, 71, 80, 81, 83, 87, 90, 93, 95, 98, 101, 104, 107, 31, 32, 32,
+ 32, 32, 32, 32, 34, 34, 35, 38, 39, 42, 46, 47, 51, 55, 57, 62, 66, 68,
+ 76, 77, 78, 83, 85, 88, 90, 93, 96, 99, 101, 31, 32, 32, 32, 32, 32, 32,
+ 33, 34, 34, 38, 39, 41, 45, 46, 50, 54, 55, 60, 64, 66, 73, 75, 76, 81,
+ 83, 86, 89, 92, 95, 98, 101, 31, 32, 32, 32, 32, 32, 32, 33, 34, 34, 37,
+ 38, 41, 44, 45, 49, 53, 54, 59, 63, 65, 72, 74, 75, 79, 81, 84, 86, 89,
+ 91, 94, 97, 31, 32, 32, 32, 33, 33, 34, 35, 36, 36, 39, 40, 42, 45, 46,
+ 50, 53, 54, 59, 63, 64, 71, 73, 74, 78, 80, 83, 85, 88, 91, 94, 97, 32,
+ 32, 32, 32, 33, 34, 34, 36, 36, 37, 40, 40, 42, 45, 46, 49, 53, 54, 58,
+ 62, 63, 70, 72, 73, 77, 79, 82, 85, 87, 90, 92, 95, 32, 32, 32, 32, 34,
+ 34, 35, 37, 37, 38, 40, 41, 42, 45, 46, 49, 52, 54, 58, 61, 63, 69, 71,
+ 72, 75, 78, 80, 83, 86, 89, 92, 95, 34, 34, 33, 33, 35, 36, 37, 39, 41,
+ 42, 45, 46, 47, 50, 51, 54, 57, 59, 63, 66, 68, 74, 75, 76, 80, 81, 82,
+ 83, 85, 87, 90, 93, 34, 34, 34, 34, 36, 36, 37, 41, 42, 45, 47, 48, 50,
+ 53, 53, 56, 59, 61, 65, 68, 70, 76, 77, 78, 82, 83, 85, 88, 89, 90, 92,
+ 93, 36, 35, 34, 34, 36, 37, 38, 42, 45, 48, 50, 51, 54, 56, 57, 60, 63,
+ 64, 68, 71, 73, 79, 80, 81, 85, 87, 89, 89, 90, 93, 96, 99, 39, 38, 38,
+ 37, 39, 40, 40, 45, 47, 50, 54, 55, 58, 61, 62, 65, 68, 69, 73, 76, 78,
+ 84, 85, 86, 90, 89, 90, 93, 96, 97, 98, 99, 41, 39, 39, 38, 40, 40, 41,
+ 46, 48, 51, 55, 56, 59, 62, 63, 67, 70, 71, 75, 78, 80, 86, 87, 88, 91,
+ 93, 96, 97, 97, 99, 102, 105, 44, 42, 41, 41, 42, 42, 42, 47, 50, 54,
+ 58, 59, 63, 66, 68, 71, 74, 75, 79, 83, 84, 90, 91, 92, 96, 98, 98, 99,
+ 102, 104, 104, 105, 48, 46, 45, 44, 45, 45, 45, 50, 53, 56, 61, 62, 66,
+ 70, 71, 76, 79, 80, 85, 88, 90, 96, 97, 98, 101, 100, 102, 105, 105,
+ 105, 109, 112, 49, 47, 46, 45, 46, 46, 46, 51, 53, 57, 62, 63, 68, 71,
+ 73, 77, 81, 82, 87, 90, 92, 98, 99, 100, 103, 106, 107, 106, 109, 112,
+ 112, 112, 54, 51, 50, 49, 50, 49, 49, 54, 56, 60, 65, 67, 71, 76, 77,
+ 82, 86, 87, 92, 96, 97, 104, 105, 106, 110, 110, 109, 113, 114, 113,
+ 116, 120, 58, 55, 54, 53, 53, 53, 52, 57, 59, 63, 68, 70, 74, 79, 81,
+ 86, 90, 91, 97, 100, 102, 109, 110, 111, 114, 114, 118, 116, 117, 121,
+ 121, 120, 59, 57, 55, 54, 54, 54, 54, 59, 61, 64, 69, 71, 75, 80, 82,
+ 87, 91, 93, 99, 102, 104, 111, 112, 113, 117, 121, 120, 122, 124, 122,
+ 125, 129, 65, 62, 60, 59, 59, 58, 58, 63, 65, 68, 73, 75, 79, 85, 87,
+ 92, 97, 99, 105, 109, 111, 118, 120, 121, 125, 124, 125, 127, 126, 130,
+ 130, 129, 69, 66, 64, 63, 63, 62, 61, 66, 68, 71, 76, 78, 83, 88, 90,
+ 96, 100, 102, 109, 113, 115, 123, 125, 126, 129, 130, 131, 130, 134,
+ 133, 135, 139, 71, 68, 66, 65, 64, 63, 63, 68, 70, 73, 78, 80, 84, 90,
+ 92, 97, 102, 104, 111, 115, 117, 125, 127, 128, 133, 136, 134, 139, 136,
+ 139, 141, 140, 80, 76, 73, 72, 71, 70, 69, 74, 76, 79, 84, 86, 90, 96,
+ 98, 104, 109, 111, 118, 123, 125, 134, 136, 137, 142, 138, 143, 140,
+ 144, 144, 144, 149, 81, 77, 75, 74, 73, 72, 71, 75, 77, 80, 85, 87, 91,
+ 97, 99, 105, 110, 112, 120, 125, 127, 136, 137, 139, 143, 148, 145, 148,
+ 148, 150, 152, 149, 83, 78, 76, 75, 74, 73, 72, 76, 78, 81, 86, 88, 92,
+ 98, 100, 106, 111, 113, 121, 126, 128, 137, 139, 140, 145, 149, 153,
+ 153, 154, 155, 155, 161, 87, 83, 81, 79, 78, 77, 75, 80, 82, 85, 90, 91,
+ 96, 101, 103, 110, 114, 117, 125, 129, 133, 142, 143, 145, 150, 151,
+ 156, 159, 160, 160, 163, 161, 90, 85, 83, 81, 80, 79, 78, 81, 83, 87,
+ 89, 93, 98, 100, 106, 110, 114, 121, 124, 130, 136, 138, 148, 149, 151,
+ 156, 157, 162, 166, 168, 166, 172, 93, 88, 86, 84, 83, 82, 80, 82, 85,
+ 89, 90, 96, 98, 102, 107, 109, 118, 120, 125, 131, 134, 143, 145, 153,
+ 156, 157, 163, 164, 169, 172, 177, 172, 95, 90, 89, 86, 85, 85, 83, 83,
+ 88, 89, 93, 97, 99, 105, 106, 113, 116, 122, 127, 130, 139, 140, 148,
+ 153, 159, 162, 164, 169, 170, 176, 179, 185, 98, 93, 92, 89, 88, 87, 86,
+ 85, 89, 90, 96, 97, 102, 105, 109, 114, 117, 124, 126, 134, 136, 144,
+ 148, 154, 160, 166, 169, 170, 176, 177, 184, 186, 101, 96, 95, 91, 91,
+ 90, 89, 87, 90, 93, 97, 99, 104, 105, 112, 113, 121, 122, 130, 133, 139,
+ 144, 150, 155, 160, 168, 172, 176, 177, 184, 185, 191, 104, 99, 98, 94,
+ 94, 92, 92, 90, 92, 96, 98, 102, 104, 109, 112, 116, 121, 125, 130, 135,
+ 141, 144, 152, 155, 163, 166, 177, 179, 184, 185, 191, 192, 107, 101,
+ 101, 97, 97, 95, 95, 93, 93, 99, 99, 105, 105, 112, 112, 120, 120, 129,
+ 129, 139, 140, 149, 149, 161, 161, 172, 172, 185, 186, 191, 192, 199],
+ /* Size 4x8 */
+ [32, 38, 62, 86, 32, 40, 58, 80, 34, 51, 68, 85, 44, 61, 85, 101, 54, 69,
+ 98, 117, 72, 84, 118, 136, 82, 89, 129, 157, 92, 98, 127, 165],
+ /* Size 8x4 */
+ [32, 32, 34, 44, 54, 72, 82, 92, 38, 40, 51, 61, 69, 84, 89, 98, 62, 58,
+ 68, 85, 98, 118, 129, 127, 86, 80, 85, 101, 117, 136, 157, 165],
+ /* Size 8x16 */
+ [32, 32, 36, 44, 58, 79, 88, 93, 31, 32, 35, 41, 54, 73, 81, 88, 32, 33,
+ 36, 42, 53, 71, 78, 84, 32, 34, 38, 42, 52, 69, 76, 82, 34, 36, 44, 50,
+ 59, 75, 81, 84, 39, 39, 50, 58, 68, 84, 88, 90, 44, 42, 53, 63, 74, 90,
+ 97, 97, 49, 46, 57, 67, 81, 97, 104, 105, 57, 53, 63, 74, 90, 108, 111,
+ 113, 65, 59, 68, 79, 97, 118, 123, 122, 71, 64, 73, 84, 102, 125, 135,
+ 131, 81, 72, 80, 91, 110, 135, 145, 141, 87, 77, 85, 96, 114, 140, 148,
+ 151, 92, 83, 88, 102, 117, 133, 153, 163, 98, 88, 89, 103, 121, 141,
+ 160, 169, 103, 94, 92, 103, 119, 137, 158, 175],
+ /* Size 16x8 */
+ [32, 31, 32, 32, 34, 39, 44, 49, 57, 65, 71, 81, 87, 92, 98, 103, 32, 32,
+ 33, 34, 36, 39, 42, 46, 53, 59, 64, 72, 77, 83, 88, 94, 36, 35, 36, 38,
+ 44, 50, 53, 57, 63, 68, 73, 80, 85, 88, 89, 92, 44, 41, 42, 42, 50, 58,
+ 63, 67, 74, 79, 84, 91, 96, 102, 103, 103, 58, 54, 53, 52, 59, 68, 74,
+ 81, 90, 97, 102, 110, 114, 117, 121, 119, 79, 73, 71, 69, 75, 84, 90,
+ 97, 108, 118, 125, 135, 140, 133, 141, 137, 88, 81, 78, 76, 81, 88, 97,
+ 104, 111, 123, 135, 145, 148, 153, 160, 158, 93, 88, 84, 82, 84, 90, 97,
+ 105, 113, 122, 131, 141, 151, 163, 169, 175],
+ /* Size 16x32 */
+ [32, 31, 32, 32, 36, 39, 44, 53, 58, 65, 79, 81, 88, 90, 93, 96, 31, 32,
+ 32, 32, 35, 38, 42, 51, 55, 62, 75, 77, 83, 86, 88, 91, 31, 32, 32, 32,
+ 35, 38, 41, 50, 54, 60, 73, 75, 81, 84, 88, 91, 31, 32, 32, 33, 34, 37,
+ 41, 49, 53, 59, 72, 74, 79, 82, 84, 87, 32, 32, 33, 34, 36, 39, 42, 50,
+ 53, 59, 71, 72, 78, 81, 84, 87, 32, 32, 34, 34, 37, 40, 42, 49, 53, 58,
+ 70, 71, 77, 80, 83, 85, 32, 33, 34, 35, 38, 40, 42, 49, 52, 58, 69, 70,
+ 76, 78, 82, 86, 34, 34, 35, 37, 42, 45, 48, 54, 57, 63, 73, 75, 79, 79,
+ 81, 83, 34, 34, 36, 37, 44, 47, 50, 56, 59, 65, 75, 77, 81, 83, 84, 84,
+ 36, 34, 37, 38, 48, 51, 54, 60, 63, 68, 78, 80, 85, 85, 86, 89, 39, 37,
+ 39, 40, 50, 54, 58, 65, 68, 73, 84, 85, 88, 89, 90, 89, 40, 38, 40, 41,
+ 51, 55, 59, 67, 70, 75, 85, 87, 91, 92, 92, 95, 44, 41, 42, 43, 53, 58,
+ 63, 71, 74, 79, 90, 91, 97, 94, 97, 95, 47, 44, 45, 46, 56, 61, 66, 75,
+ 79, 85, 95, 97, 99, 101, 98, 102, 49, 46, 46, 47, 57, 62, 67, 77, 81,
+ 86, 97, 99, 104, 102, 105, 102, 53, 49, 50, 50, 60, 65, 71, 82, 86, 92,
+ 103, 105, 109, 108, 106, 110, 57, 53, 53, 53, 63, 68, 74, 86, 90, 97,
+ 108, 110, 111, 112, 113, 110, 59, 54, 54, 54, 64, 69, 75, 87, 91, 98,
+ 111, 112, 119, 117, 115, 118, 65, 60, 59, 58, 68, 73, 79, 92, 97, 105,
+ 118, 119, 123, 123, 122, 119, 69, 63, 62, 62, 71, 76, 83, 96, 100, 109,
+ 122, 124, 127, 125, 125, 128, 71, 65, 64, 63, 73, 78, 84, 97, 102, 111,
+ 125, 127, 135, 134, 131, 129, 79, 72, 71, 70, 79, 84, 90, 104, 109, 118,
+ 133, 135, 137, 136, 136, 137, 81, 74, 72, 71, 80, 85, 91, 105, 110, 120,
+ 135, 137, 145, 143, 141, 138, 82, 75, 73, 72, 81, 86, 92, 106, 111, 121,
+ 136, 139, 147, 148, 147, 149, 87, 79, 77, 76, 85, 90, 96, 110, 114, 125,
+ 140, 143, 148, 154, 151, 149, 90, 82, 80, 78, 87, 89, 99, 108, 113, 129,
+ 135, 146, 153, 157, 160, 159, 92, 84, 83, 81, 88, 90, 102, 106, 117,
+ 128, 133, 150, 153, 158, 163, 160, 95, 87, 85, 83, 88, 92, 103, 105,
+ 120, 125, 137, 148, 155, 164, 168, 173, 98, 89, 88, 85, 89, 95, 103,
+ 108, 121, 124, 141, 144, 160, 164, 169, 174, 100, 92, 91, 88, 90, 98,
+ 103, 111, 120, 127, 139, 146, 161, 165, 175, 179, 103, 94, 94, 90, 92,
+ 101, 103, 114, 119, 131, 137, 150, 158, 170, 175, 180, 106, 97, 97, 93,
+ 93, 104, 104, 118, 118, 135, 135, 154, 155, 175, 176, 187],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 32, 32, 32, 34, 34, 36, 39, 40, 44, 47, 49, 53, 57, 59,
+ 65, 69, 71, 79, 81, 82, 87, 90, 92, 95, 98, 100, 103, 106, 31, 32, 32,
+ 32, 32, 32, 33, 34, 34, 34, 37, 38, 41, 44, 46, 49, 53, 54, 60, 63, 65,
+ 72, 74, 75, 79, 82, 84, 87, 89, 92, 94, 97, 32, 32, 32, 32, 33, 34, 34,
+ 35, 36, 37, 39, 40, 42, 45, 46, 50, 53, 54, 59, 62, 64, 71, 72, 73, 77,
+ 80, 83, 85, 88, 91, 94, 97, 32, 32, 32, 33, 34, 34, 35, 37, 37, 38, 40,
+ 41, 43, 46, 47, 50, 53, 54, 58, 62, 63, 70, 71, 72, 76, 78, 81, 83, 85,
+ 88, 90, 93, 36, 35, 35, 34, 36, 37, 38, 42, 44, 48, 50, 51, 53, 56, 57,
+ 60, 63, 64, 68, 71, 73, 79, 80, 81, 85, 87, 88, 88, 89, 90, 92, 93, 39,
+ 38, 38, 37, 39, 40, 40, 45, 47, 51, 54, 55, 58, 61, 62, 65, 68, 69, 73,
+ 76, 78, 84, 85, 86, 90, 89, 90, 92, 95, 98, 101, 104, 44, 42, 41, 41,
+ 42, 42, 42, 48, 50, 54, 58, 59, 63, 66, 67, 71, 74, 75, 79, 83, 84, 90,
+ 91, 92, 96, 99, 102, 103, 103, 103, 103, 104, 53, 51, 50, 49, 50, 49,
+ 49, 54, 56, 60, 65, 67, 71, 75, 77, 82, 86, 87, 92, 96, 97, 104, 105,
+ 106, 110, 108, 106, 105, 108, 111, 114, 118, 58, 55, 54, 53, 53, 53, 52,
+ 57, 59, 63, 68, 70, 74, 79, 81, 86, 90, 91, 97, 100, 102, 109, 110, 111,
+ 114, 113, 117, 120, 121, 120, 119, 118, 65, 62, 60, 59, 59, 58, 58, 63,
+ 65, 68, 73, 75, 79, 85, 86, 92, 97, 98, 105, 109, 111, 118, 120, 121,
+ 125, 129, 128, 125, 124, 127, 131, 135, 79, 75, 73, 72, 71, 70, 69, 73,
+ 75, 78, 84, 85, 90, 95, 97, 103, 108, 111, 118, 122, 125, 133, 135, 136,
+ 140, 135, 133, 137, 141, 139, 137, 135, 81, 77, 75, 74, 72, 71, 70, 75,
+ 77, 80, 85, 87, 91, 97, 99, 105, 110, 112, 119, 124, 127, 135, 137, 139,
+ 143, 146, 150, 148, 144, 146, 150, 154, 88, 83, 81, 79, 78, 77, 76, 79,
+ 81, 85, 88, 91, 97, 99, 104, 109, 111, 119, 123, 127, 135, 137, 145,
+ 147, 148, 153, 153, 155, 160, 161, 158, 155, 90, 86, 84, 82, 81, 80, 78,
+ 79, 83, 85, 89, 92, 94, 101, 102, 108, 112, 117, 123, 125, 134, 136,
+ 143, 148, 154, 157, 158, 164, 164, 165, 170, 175, 93, 88, 88, 84, 84,
+ 83, 82, 81, 84, 86, 90, 92, 97, 98, 105, 106, 113, 115, 122, 125, 131,
+ 136, 141, 147, 151, 160, 163, 168, 169, 175, 175, 176, 96, 91, 91, 87,
+ 87, 85, 86, 83, 84, 89, 89, 95, 95, 102, 102, 110, 110, 118, 119, 128,
+ 129, 137, 138, 149, 149, 159, 160, 173, 174, 179, 180, 187],
+ /* Size 4x16 */
+ [31, 39, 65, 90, 32, 38, 60, 84, 32, 39, 59, 81, 33, 40, 58, 78, 34, 47,
+ 65, 83, 37, 54, 73, 89, 41, 58, 79, 94, 46, 62, 86, 102, 53, 68, 97,
+ 112, 60, 73, 105, 123, 65, 78, 111, 134, 74, 85, 120, 143, 79, 90, 125,
+ 154, 84, 90, 128, 158, 89, 95, 124, 164, 94, 101, 131, 170],
+ /* Size 16x4 */
+ [31, 32, 32, 33, 34, 37, 41, 46, 53, 60, 65, 74, 79, 84, 89, 94, 39, 38,
+ 39, 40, 47, 54, 58, 62, 68, 73, 78, 85, 90, 90, 95, 101, 65, 60, 59, 58,
+ 65, 73, 79, 86, 97, 105, 111, 120, 125, 128, 124, 131, 90, 84, 81, 78,
+ 83, 89, 94, 102, 112, 123, 134, 143, 154, 158, 164, 170],
+ /* Size 8x32 */
+ [32, 32, 36, 44, 58, 79, 88, 93, 31, 32, 35, 42, 55, 75, 83, 88, 31, 32,
+ 35, 41, 54, 73, 81, 88, 31, 32, 34, 41, 53, 72, 79, 84, 32, 33, 36, 42,
+ 53, 71, 78, 84, 32, 34, 37, 42, 53, 70, 77, 83, 32, 34, 38, 42, 52, 69,
+ 76, 82, 34, 35, 42, 48, 57, 73, 79, 81, 34, 36, 44, 50, 59, 75, 81, 84,
+ 36, 37, 48, 54, 63, 78, 85, 86, 39, 39, 50, 58, 68, 84, 88, 90, 40, 40,
+ 51, 59, 70, 85, 91, 92, 44, 42, 53, 63, 74, 90, 97, 97, 47, 45, 56, 66,
+ 79, 95, 99, 98, 49, 46, 57, 67, 81, 97, 104, 105, 53, 50, 60, 71, 86,
+ 103, 109, 106, 57, 53, 63, 74, 90, 108, 111, 113, 59, 54, 64, 75, 91,
+ 111, 119, 115, 65, 59, 68, 79, 97, 118, 123, 122, 69, 62, 71, 83, 100,
+ 122, 127, 125, 71, 64, 73, 84, 102, 125, 135, 131, 79, 71, 79, 90, 109,
+ 133, 137, 136, 81, 72, 80, 91, 110, 135, 145, 141, 82, 73, 81, 92, 111,
+ 136, 147, 147, 87, 77, 85, 96, 114, 140, 148, 151, 90, 80, 87, 99, 113,
+ 135, 153, 160, 92, 83, 88, 102, 117, 133, 153, 163, 95, 85, 88, 103,
+ 120, 137, 155, 168, 98, 88, 89, 103, 121, 141, 160, 169, 100, 91, 90,
+ 103, 120, 139, 161, 175, 103, 94, 92, 103, 119, 137, 158, 175, 106, 97,
+ 93, 104, 118, 135, 155, 176],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 32, 32, 32, 34, 34, 36, 39, 40, 44, 47, 49, 53, 57, 59,
+ 65, 69, 71, 79, 81, 82, 87, 90, 92, 95, 98, 100, 103, 106, 32, 32, 32,
+ 32, 33, 34, 34, 35, 36, 37, 39, 40, 42, 45, 46, 50, 53, 54, 59, 62, 64,
+ 71, 72, 73, 77, 80, 83, 85, 88, 91, 94, 97, 36, 35, 35, 34, 36, 37, 38,
+ 42, 44, 48, 50, 51, 53, 56, 57, 60, 63, 64, 68, 71, 73, 79, 80, 81, 85,
+ 87, 88, 88, 89, 90, 92, 93, 44, 42, 41, 41, 42, 42, 42, 48, 50, 54, 58,
+ 59, 63, 66, 67, 71, 74, 75, 79, 83, 84, 90, 91, 92, 96, 99, 102, 103,
+ 103, 103, 103, 104, 58, 55, 54, 53, 53, 53, 52, 57, 59, 63, 68, 70, 74,
+ 79, 81, 86, 90, 91, 97, 100, 102, 109, 110, 111, 114, 113, 117, 120,
+ 121, 120, 119, 118, 79, 75, 73, 72, 71, 70, 69, 73, 75, 78, 84, 85, 90,
+ 95, 97, 103, 108, 111, 118, 122, 125, 133, 135, 136, 140, 135, 133, 137,
+ 141, 139, 137, 135, 88, 83, 81, 79, 78, 77, 76, 79, 81, 85, 88, 91, 97,
+ 99, 104, 109, 111, 119, 123, 127, 135, 137, 145, 147, 148, 153, 153,
+ 155, 160, 161, 158, 155, 93, 88, 88, 84, 84, 83, 82, 81, 84, 86, 90, 92,
+ 97, 98, 105, 106, 113, 115, 122, 125, 131, 136, 141, 147, 151, 160, 163,
+ 168, 169, 175, 175, 176]
+ ],
+ [ /* Chroma */
+ /* Size 4x4 */
+ [32, 45, 53, 63, 45, 55, 62, 67, 53, 62, 80, 84, 63, 67, 84, 101],
+ /* Size 8x8 */
+ [31, 36, 47, 48, 52, 60, 64, 67, 36, 43, 47, 46, 49, 55, 59, 63, 47, 47,
+ 53, 54, 55, 60, 63, 64, 48, 46, 54, 61, 65, 70, 71, 71, 52, 49, 55, 65,
+ 71, 78, 81, 79, 60, 55, 60, 70, 78, 89, 89, 89, 64, 59, 63, 71, 81, 89,
+ 97, 99, 67, 63, 64, 71, 79, 89, 99, 104],
+ /* Size 16x16 */
+ [32, 30, 33, 36, 44, 48, 49, 51, 54, 57, 60, 64, 67, 68, 70, 72, 30, 31,
+ 35, 39, 44, 46, 46, 47, 50, 53, 55, 59, 61, 64, 66, 68, 33, 35, 39, 43,
+ 46, 46, 45, 47, 49, 51, 53, 57, 59, 61, 63, 65, 36, 39, 43, 47, 47, 46,
+ 45, 46, 48, 50, 52, 55, 57, 58, 61, 63, 44, 44, 46, 47, 50, 51, 51, 51,
+ 53, 54, 56, 59, 61, 61, 63, 62, 48, 46, 46, 46, 51, 54, 55, 56, 58, 60,
+ 61, 64, 65, 64, 66, 66, 49, 46, 45, 45, 51, 55, 58, 60, 62, 63, 65, 68,
+ 69, 69, 69, 69, 51, 47, 47, 46, 51, 56, 60, 62, 65, 67, 69, 72, 73, 74,
+ 73, 73, 54, 50, 49, 48, 53, 58, 62, 65, 70, 73, 75, 78, 79, 79, 77, 77,
+ 57, 53, 51, 50, 54, 60, 63, 67, 73, 76, 79, 82, 84, 83, 82, 82, 60, 55,
+ 53, 52, 56, 61, 65, 69, 75, 79, 82, 86, 88, 87, 86, 87, 64, 59, 57, 55,
+ 59, 64, 68, 72, 78, 82, 86, 90, 93, 92, 91, 92, 67, 61, 59, 57, 61, 65,
+ 69, 73, 79, 84, 88, 93, 95, 96, 96, 96, 68, 64, 61, 58, 61, 64, 69, 74,
+ 79, 83, 87, 92, 96, 99, 100, 101, 70, 66, 63, 61, 63, 66, 69, 73, 77,
+ 82, 86, 91, 96, 100, 103, 104, 72, 68, 65, 63, 62, 66, 69, 73, 77, 82,
+ 87, 92, 96, 101, 104, 106],
+ /* Size 32x32 */
+ [32, 31, 30, 30, 33, 35, 36, 41, 44, 49, 48, 48, 49, 50, 51, 52, 54, 55,
+ 57, 59, 60, 63, 64, 65, 67, 68, 68, 69, 70, 71, 72, 73, 31, 31, 31, 31,
+ 34, 36, 38, 42, 44, 47, 47, 47, 47, 48, 48, 50, 51, 52, 54, 56, 57, 60,
+ 61, 61, 63, 64, 65, 66, 67, 67, 68, 69, 30, 31, 31, 31, 35, 37, 39, 42,
+ 44, 47, 46, 46, 46, 47, 47, 48, 50, 51, 53, 54, 55, 58, 59, 60, 61, 63,
+ 64, 65, 66, 67, 68, 69, 30, 31, 31, 32, 35, 37, 40, 42, 44, 46, 45, 45,
+ 45, 46, 46, 47, 49, 50, 52, 53, 54, 57, 58, 58, 60, 61, 62, 63, 63, 64,
+ 65, 66, 33, 34, 35, 35, 39, 41, 43, 45, 46, 47, 46, 46, 45, 46, 47, 47,
+ 49, 49, 51, 53, 53, 56, 57, 57, 59, 60, 61, 62, 63, 64, 65, 66, 35, 36,
+ 37, 37, 41, 43, 45, 46, 46, 47, 46, 46, 45, 46, 46, 47, 48, 49, 50, 52,
+ 53, 55, 56, 56, 58, 59, 60, 61, 62, 63, 64, 64, 36, 38, 39, 40, 43, 45,
+ 47, 47, 47, 48, 46, 46, 45, 46, 46, 47, 48, 48, 50, 51, 52, 54, 55, 55,
+ 57, 58, 58, 59, 61, 62, 63, 64, 41, 42, 42, 42, 45, 46, 47, 48, 49, 50,
+ 49, 49, 49, 50, 50, 50, 51, 52, 53, 54, 55, 57, 58, 58, 60, 60, 59, 59,
+ 60, 61, 61, 62, 44, 44, 44, 44, 46, 46, 47, 49, 50, 51, 51, 51, 51, 51,
+ 51, 52, 53, 53, 54, 56, 56, 59, 59, 59, 61, 61, 61, 62, 63, 62, 62, 62,
+ 49, 47, 47, 46, 47, 47, 48, 50, 51, 53, 53, 53, 53, 54, 54, 54, 55, 55,
+ 56, 58, 58, 60, 61, 61, 63, 63, 64, 63, 63, 64, 65, 66, 48, 47, 46, 45,
+ 46, 46, 46, 49, 51, 53, 54, 54, 55, 56, 56, 57, 58, 59, 60, 61, 61, 63,
+ 64, 64, 65, 65, 64, 65, 66, 66, 66, 66, 48, 47, 46, 45, 46, 46, 46, 49,
+ 51, 53, 54, 55, 56, 57, 57, 58, 59, 60, 61, 62, 63, 65, 65, 65, 66, 67,
+ 68, 67, 67, 67, 68, 69, 49, 47, 46, 45, 45, 45, 45, 49, 51, 53, 55, 56,
+ 58, 59, 60, 61, 62, 62, 63, 65, 65, 67, 68, 68, 69, 70, 69, 69, 69, 70,
+ 69, 69, 50, 48, 47, 46, 46, 46, 46, 50, 51, 54, 56, 57, 59, 61, 62, 63,
+ 64, 65, 66, 68, 68, 70, 71, 71, 72, 71, 71, 72, 71, 71, 71, 72, 51, 48,
+ 47, 46, 47, 46, 46, 50, 51, 54, 56, 57, 60, 62, 62, 64, 65, 66, 67, 69,
+ 69, 71, 72, 72, 73, 74, 74, 72, 73, 74, 73, 73, 52, 50, 48, 47, 47, 47,
+ 47, 50, 52, 54, 57, 58, 61, 63, 64, 66, 68, 68, 70, 72, 72, 75, 75, 75,
+ 77, 76, 75, 76, 76, 74, 75, 76, 54, 51, 50, 49, 49, 48, 48, 51, 53, 55,
+ 58, 59, 62, 64, 65, 68, 70, 70, 73, 74, 75, 77, 78, 78, 79, 78, 79, 78,
+ 77, 78, 77, 77, 55, 52, 51, 50, 49, 49, 48, 52, 53, 55, 59, 60, 62, 65,
+ 66, 68, 70, 71, 73, 75, 76, 78, 79, 79, 80, 81, 80, 80, 81, 79, 79, 81,
+ 57, 54, 53, 52, 51, 50, 50, 53, 54, 56, 60, 61, 63, 66, 67, 70, 73, 73,
+ 76, 78, 79, 82, 82, 83, 84, 83, 83, 83, 82, 83, 82, 81, 59, 56, 54, 53,
+ 53, 52, 51, 54, 56, 58, 61, 62, 65, 68, 69, 72, 74, 75, 78, 80, 81, 84,
+ 85, 85, 86, 86, 86, 84, 85, 84, 84, 85, 60, 57, 55, 54, 53, 53, 52, 55,
+ 56, 58, 61, 63, 65, 68, 69, 72, 75, 76, 79, 81, 82, 85, 86, 86, 88, 88,
+ 87, 88, 86, 87, 87, 85, 63, 60, 58, 57, 56, 55, 54, 57, 59, 60, 63, 65,
+ 67, 70, 71, 75, 77, 78, 82, 84, 85, 89, 89, 90, 92, 89, 91, 89, 90, 89,
+ 88, 89, 64, 61, 59, 58, 57, 56, 55, 58, 59, 61, 64, 65, 68, 71, 72, 75,
+ 78, 79, 82, 85, 86, 89, 90, 91, 93, 94, 92, 92, 91, 91, 92, 90, 65, 61,
+ 60, 58, 57, 56, 55, 58, 59, 61, 64, 65, 68, 71, 72, 75, 78, 79, 83, 85,
+ 86, 90, 91, 91, 93, 94, 95, 94, 94, 94, 93, 94, 67, 63, 61, 60, 59, 58,
+ 57, 60, 61, 63, 65, 66, 69, 72, 73, 77, 79, 80, 84, 86, 88, 92, 93, 93,
+ 95, 95, 96, 97, 96, 95, 96, 94, 68, 64, 63, 61, 60, 59, 58, 60, 61, 63,
+ 65, 67, 70, 71, 74, 76, 78, 81, 83, 86, 88, 89, 94, 94, 95, 97, 97, 98,
+ 99, 99, 97, 99, 68, 65, 64, 62, 61, 60, 58, 59, 61, 64, 64, 68, 69, 71,
+ 74, 75, 79, 80, 83, 86, 87, 91, 92, 95, 96, 97, 99, 99, 100, 100, 101,
+ 99, 69, 66, 65, 63, 62, 61, 59, 59, 62, 63, 65, 67, 69, 72, 72, 76, 78,
+ 80, 83, 84, 88, 89, 92, 94, 97, 98, 99, 101, 100, 102, 102, 104, 70, 67,
+ 66, 63, 63, 62, 61, 60, 63, 63, 66, 67, 69, 71, 73, 76, 77, 81, 82, 85,
+ 86, 90, 91, 94, 96, 99, 100, 100, 103, 102, 104, 104, 71, 67, 67, 64,
+ 64, 63, 62, 61, 62, 64, 66, 67, 70, 71, 74, 74, 78, 79, 83, 84, 87, 89,
+ 91, 94, 95, 99, 100, 102, 102, 104, 104, 106, 72, 68, 68, 65, 65, 64,
+ 63, 61, 62, 65, 66, 68, 69, 71, 73, 75, 77, 79, 82, 84, 87, 88, 92, 93,
+ 96, 97, 101, 102, 104, 104, 106, 106, 73, 69, 69, 66, 66, 64, 64, 62,
+ 62, 66, 66, 69, 69, 72, 73, 76, 77, 81, 81, 85, 85, 89, 90, 94, 94, 99,
+ 99, 104, 104, 106, 106, 108],
+ /* Size 4x8 */
+ [31, 47, 54, 64, 38, 46, 50, 60, 46, 53, 57, 62, 46, 56, 66, 71, 50, 59,
+ 74, 79, 57, 64, 82, 88, 61, 65, 85, 97, 65, 67, 82, 99],
+ /* Size 8x4 */
+ [31, 38, 46, 46, 50, 57, 61, 65, 47, 46, 53, 56, 59, 64, 65, 67, 54, 50,
+ 57, 66, 74, 82, 85, 82, 64, 60, 62, 71, 79, 88, 97, 99],
+ /* Size 8x16 */
+ [32, 34, 48, 49, 54, 63, 67, 69, 31, 36, 46, 46, 50, 58, 62, 65, 33, 40,
+ 47, 46, 49, 56, 59, 62, 37, 44, 47, 45, 48, 54, 57, 60, 44, 46, 51, 51,
+ 53, 59, 60, 61, 48, 46, 53, 56, 58, 64, 64, 64, 49, 45, 53, 58, 62, 67,
+ 70, 68, 51, 47, 54, 60, 65, 71, 73, 72, 54, 49, 55, 62, 70, 77, 77, 76,
+ 57, 51, 56, 64, 73, 82, 83, 81, 60, 53, 58, 65, 75, 85, 89, 85, 64, 57,
+ 61, 68, 78, 89, 93, 89, 66, 59, 63, 69, 79, 91, 94, 93, 68, 61, 63, 71,
+ 79, 87, 96, 98, 70, 63, 63, 70, 80, 89, 97, 100, 72, 65, 63, 69, 77, 86,
+ 95, 102],
+ /* Size 16x8 */
+ [32, 31, 33, 37, 44, 48, 49, 51, 54, 57, 60, 64, 66, 68, 70, 72, 34, 36,
+ 40, 44, 46, 46, 45, 47, 49, 51, 53, 57, 59, 61, 63, 65, 48, 46, 47, 47,
+ 51, 53, 53, 54, 55, 56, 58, 61, 63, 63, 63, 63, 49, 46, 46, 45, 51, 56,
+ 58, 60, 62, 64, 65, 68, 69, 71, 70, 69, 54, 50, 49, 48, 53, 58, 62, 65,
+ 70, 73, 75, 78, 79, 79, 80, 77, 63, 58, 56, 54, 59, 64, 67, 71, 77, 82,
+ 85, 89, 91, 87, 89, 86, 67, 62, 59, 57, 60, 64, 70, 73, 77, 83, 89, 93,
+ 94, 96, 97, 95, 69, 65, 62, 60, 61, 64, 68, 72, 76, 81, 85, 89, 93, 98,
+ 100, 102],
+ /* Size 16x32 */
+ [32, 31, 34, 37, 48, 48, 49, 52, 54, 57, 63, 64, 67, 68, 69, 69, 31, 31,
+ 35, 38, 47, 47, 47, 50, 51, 54, 60, 61, 63, 64, 65, 66, 31, 32, 36, 39,
+ 46, 46, 46, 48, 50, 53, 58, 59, 62, 63, 65, 66, 30, 32, 36, 40, 46, 45,
+ 45, 48, 49, 52, 57, 58, 60, 61, 62, 63, 33, 36, 40, 43, 47, 46, 46, 47,
+ 49, 51, 56, 57, 59, 60, 62, 63, 35, 38, 42, 45, 47, 46, 45, 47, 48, 50,
+ 55, 56, 58, 60, 61, 61, 37, 40, 44, 47, 47, 46, 45, 47, 48, 50, 54, 55,
+ 57, 58, 60, 61, 42, 43, 45, 47, 50, 50, 49, 50, 51, 53, 57, 58, 59, 58,
+ 59, 59, 44, 44, 46, 47, 51, 51, 51, 52, 53, 54, 59, 59, 60, 61, 61, 60,
+ 49, 46, 47, 48, 53, 53, 53, 54, 55, 57, 60, 61, 63, 62, 62, 63, 48, 46,
+ 46, 47, 53, 54, 56, 57, 58, 60, 64, 64, 64, 64, 64, 63, 48, 45, 46, 46,
+ 53, 55, 56, 58, 59, 61, 65, 65, 66, 66, 65, 66, 49, 45, 45, 46, 53, 56,
+ 58, 61, 62, 64, 67, 68, 70, 67, 68, 66, 50, 46, 46, 46, 54, 56, 59, 63,
+ 65, 66, 70, 71, 70, 71, 68, 70, 51, 47, 47, 47, 54, 57, 60, 64, 65, 68,
+ 71, 72, 73, 71, 72, 70, 52, 48, 47, 47, 54, 57, 61, 66, 68, 71, 75, 75,
+ 76, 75, 73, 73, 54, 49, 49, 48, 55, 58, 62, 68, 70, 73, 77, 78, 77, 77,
+ 76, 74, 54, 50, 49, 49, 55, 59, 62, 68, 70, 74, 78, 79, 81, 79, 77, 78,
+ 57, 52, 51, 50, 56, 60, 64, 70, 73, 76, 82, 82, 83, 82, 81, 78, 59, 54,
+ 52, 52, 58, 61, 65, 72, 74, 78, 84, 85, 85, 83, 82, 82, 60, 54, 53, 52,
+ 58, 62, 65, 72, 75, 79, 85, 86, 89, 87, 85, 82, 63, 57, 56, 55, 60, 64,
+ 67, 75, 77, 82, 89, 90, 90, 88, 87, 86, 64, 58, 57, 55, 61, 64, 68, 75,
+ 78, 82, 89, 90, 93, 91, 89, 87, 64, 59, 57, 56, 61, 65, 68, 75, 78, 83,
+ 90, 91, 94, 93, 92, 91, 66, 60, 59, 57, 63, 66, 69, 77, 79, 84, 91, 93,
+ 94, 95, 93, 91, 67, 61, 60, 58, 63, 65, 70, 75, 78, 85, 88, 93, 96, 97,
+ 97, 95, 68, 62, 61, 59, 63, 64, 71, 74, 79, 84, 87, 94, 96, 97, 98, 96,
+ 69, 63, 62, 60, 63, 65, 71, 72, 80, 82, 88, 93, 96, 99, 100, 101, 70,
+ 64, 63, 60, 63, 66, 70, 73, 80, 81, 89, 90, 97, 99, 100, 101, 71, 65,
+ 64, 61, 63, 67, 70, 74, 78, 82, 88, 90, 97, 99, 102, 103, 72, 65, 65,
+ 62, 63, 68, 69, 75, 77, 83, 86, 92, 95, 100, 102, 103, 73, 66, 66, 63,
+ 63, 69, 69, 76, 76, 84, 84, 93, 93, 101, 101, 105],
+ /* Size 32x16 */
+ [32, 31, 31, 30, 33, 35, 37, 42, 44, 49, 48, 48, 49, 50, 51, 52, 54, 54,
+ 57, 59, 60, 63, 64, 64, 66, 67, 68, 69, 70, 71, 72, 73, 31, 31, 32, 32,
+ 36, 38, 40, 43, 44, 46, 46, 45, 45, 46, 47, 48, 49, 50, 52, 54, 54, 57,
+ 58, 59, 60, 61, 62, 63, 64, 65, 65, 66, 34, 35, 36, 36, 40, 42, 44, 45,
+ 46, 47, 46, 46, 45, 46, 47, 47, 49, 49, 51, 52, 53, 56, 57, 57, 59, 60,
+ 61, 62, 63, 64, 65, 66, 37, 38, 39, 40, 43, 45, 47, 47, 47, 48, 47, 46,
+ 46, 46, 47, 47, 48, 49, 50, 52, 52, 55, 55, 56, 57, 58, 59, 60, 60, 61,
+ 62, 63, 48, 47, 46, 46, 47, 47, 47, 50, 51, 53, 53, 53, 53, 54, 54, 54,
+ 55, 55, 56, 58, 58, 60, 61, 61, 63, 63, 63, 63, 63, 63, 63, 63, 48, 47,
+ 46, 45, 46, 46, 46, 50, 51, 53, 54, 55, 56, 56, 57, 57, 58, 59, 60, 61,
+ 62, 64, 64, 65, 66, 65, 64, 65, 66, 67, 68, 69, 49, 47, 46, 45, 46, 45,
+ 45, 49, 51, 53, 56, 56, 58, 59, 60, 61, 62, 62, 64, 65, 65, 67, 68, 68,
+ 69, 70, 71, 71, 70, 70, 69, 69, 52, 50, 48, 48, 47, 47, 47, 50, 52, 54,
+ 57, 58, 61, 63, 64, 66, 68, 68, 70, 72, 72, 75, 75, 75, 77, 75, 74, 72,
+ 73, 74, 75, 76, 54, 51, 50, 49, 49, 48, 48, 51, 53, 55, 58, 59, 62, 65,
+ 65, 68, 70, 70, 73, 74, 75, 77, 78, 78, 79, 78, 79, 80, 80, 78, 77, 76,
+ 57, 54, 53, 52, 51, 50, 50, 53, 54, 57, 60, 61, 64, 66, 68, 71, 73, 74,
+ 76, 78, 79, 82, 82, 83, 84, 85, 84, 82, 81, 82, 83, 84, 63, 60, 58, 57,
+ 56, 55, 54, 57, 59, 60, 64, 65, 67, 70, 71, 75, 77, 78, 82, 84, 85, 89,
+ 89, 90, 91, 88, 87, 88, 89, 88, 86, 84, 64, 61, 59, 58, 57, 56, 55, 58,
+ 59, 61, 64, 65, 68, 71, 72, 75, 78, 79, 82, 85, 86, 90, 90, 91, 93, 93,
+ 94, 93, 90, 90, 92, 93, 67, 63, 62, 60, 59, 58, 57, 59, 60, 63, 64, 66,
+ 70, 70, 73, 76, 77, 81, 83, 85, 89, 90, 93, 94, 94, 96, 96, 96, 97, 97,
+ 95, 93, 68, 64, 63, 61, 60, 60, 58, 58, 61, 62, 64, 66, 67, 71, 71, 75,
+ 77, 79, 82, 83, 87, 88, 91, 93, 95, 97, 97, 99, 99, 99, 100, 101, 69,
+ 65, 65, 62, 62, 61, 60, 59, 61, 62, 64, 65, 68, 68, 72, 73, 76, 77, 81,
+ 82, 85, 87, 89, 92, 93, 97, 98, 100, 100, 102, 102, 101, 69, 66, 66, 63,
+ 63, 61, 61, 59, 60, 63, 63, 66, 66, 70, 70, 73, 74, 78, 78, 82, 82, 86,
+ 87, 91, 91, 95, 96, 101, 101, 103, 103, 105],
+ /* Size 4x16 */
+ [31, 48, 57, 68, 32, 46, 53, 63, 36, 46, 51, 60, 40, 46, 50, 58, 44, 51,
+ 54, 61, 46, 54, 60, 64, 45, 56, 64, 67, 47, 57, 68, 71, 49, 58, 73, 77,
+ 52, 60, 76, 82, 54, 62, 79, 87, 58, 64, 82, 91, 60, 66, 84, 95, 62, 64,
+ 84, 97, 64, 66, 81, 99, 65, 68, 83, 100],
+ /* Size 16x4 */
+ [31, 32, 36, 40, 44, 46, 45, 47, 49, 52, 54, 58, 60, 62, 64, 65, 48, 46,
+ 46, 46, 51, 54, 56, 57, 58, 60, 62, 64, 66, 64, 66, 68, 57, 53, 51, 50,
+ 54, 60, 64, 68, 73, 76, 79, 82, 84, 84, 81, 83, 68, 63, 60, 58, 61, 64,
+ 67, 71, 77, 82, 87, 91, 95, 97, 99, 100],
+ /* Size 8x32 */
+ [32, 34, 48, 49, 54, 63, 67, 69, 31, 35, 47, 47, 51, 60, 63, 65, 31, 36,
+ 46, 46, 50, 58, 62, 65, 30, 36, 46, 45, 49, 57, 60, 62, 33, 40, 47, 46,
+ 49, 56, 59, 62, 35, 42, 47, 45, 48, 55, 58, 61, 37, 44, 47, 45, 48, 54,
+ 57, 60, 42, 45, 50, 49, 51, 57, 59, 59, 44, 46, 51, 51, 53, 59, 60, 61,
+ 49, 47, 53, 53, 55, 60, 63, 62, 48, 46, 53, 56, 58, 64, 64, 64, 48, 46,
+ 53, 56, 59, 65, 66, 65, 49, 45, 53, 58, 62, 67, 70, 68, 50, 46, 54, 59,
+ 65, 70, 70, 68, 51, 47, 54, 60, 65, 71, 73, 72, 52, 47, 54, 61, 68, 75,
+ 76, 73, 54, 49, 55, 62, 70, 77, 77, 76, 54, 49, 55, 62, 70, 78, 81, 77,
+ 57, 51, 56, 64, 73, 82, 83, 81, 59, 52, 58, 65, 74, 84, 85, 82, 60, 53,
+ 58, 65, 75, 85, 89, 85, 63, 56, 60, 67, 77, 89, 90, 87, 64, 57, 61, 68,
+ 78, 89, 93, 89, 64, 57, 61, 68, 78, 90, 94, 92, 66, 59, 63, 69, 79, 91,
+ 94, 93, 67, 60, 63, 70, 78, 88, 96, 97, 68, 61, 63, 71, 79, 87, 96, 98,
+ 69, 62, 63, 71, 80, 88, 96, 100, 70, 63, 63, 70, 80, 89, 97, 100, 71,
+ 64, 63, 70, 78, 88, 97, 102, 72, 65, 63, 69, 77, 86, 95, 102, 73, 66,
+ 63, 69, 76, 84, 93, 101],
+ /* Size 32x8 */
+ [32, 31, 31, 30, 33, 35, 37, 42, 44, 49, 48, 48, 49, 50, 51, 52, 54, 54,
+ 57, 59, 60, 63, 64, 64, 66, 67, 68, 69, 70, 71, 72, 73, 34, 35, 36, 36,
+ 40, 42, 44, 45, 46, 47, 46, 46, 45, 46, 47, 47, 49, 49, 51, 52, 53, 56,
+ 57, 57, 59, 60, 61, 62, 63, 64, 65, 66, 48, 47, 46, 46, 47, 47, 47, 50,
+ 51, 53, 53, 53, 53, 54, 54, 54, 55, 55, 56, 58, 58, 60, 61, 61, 63, 63,
+ 63, 63, 63, 63, 63, 63, 49, 47, 46, 45, 46, 45, 45, 49, 51, 53, 56, 56,
+ 58, 59, 60, 61, 62, 62, 64, 65, 65, 67, 68, 68, 69, 70, 71, 71, 70, 70,
+ 69, 69, 54, 51, 50, 49, 49, 48, 48, 51, 53, 55, 58, 59, 62, 65, 65, 68,
+ 70, 70, 73, 74, 75, 77, 78, 78, 79, 78, 79, 80, 80, 78, 77, 76, 63, 60,
+ 58, 57, 56, 55, 54, 57, 59, 60, 64, 65, 67, 70, 71, 75, 77, 78, 82, 84,
+ 85, 89, 89, 90, 91, 88, 87, 88, 89, 88, 86, 84, 67, 63, 62, 60, 59, 58,
+ 57, 59, 60, 63, 64, 66, 70, 70, 73, 76, 77, 81, 83, 85, 89, 90, 93, 94,
+ 94, 96, 96, 96, 97, 97, 95, 93, 69, 65, 65, 62, 62, 61, 60, 59, 61, 62,
+ 64, 65, 68, 68, 72, 73, 76, 77, 81, 82, 85, 87, 89, 92, 93, 97, 98, 100,
+ 100, 102, 102, 101]
+ ]
+ ],
+ [
+ [ /* Luma */
+ /* Size 4x4 */
+ [32, 37, 58, 81, 37, 54, 72, 91, 58, 72, 102, 121, 81, 91, 121, 156],
+ /* Size 8x8 */
+ [32, 32, 35, 42, 53, 68, 78, 90, 32, 33, 36, 42, 51, 64, 74, 84, 35, 36,
+ 46, 52, 60, 72, 80, 87, 42, 42, 52, 63, 73, 84, 92, 98, 53, 51, 60, 73,
+ 86, 100, 109, 114, 68, 64, 72, 84, 100, 117, 128, 133, 78, 74, 80, 92,
+ 109, 128, 140, 155, 90, 84, 87, 98, 114, 133, 155, 168],
+ /* Size 16x16 */
+ [32, 31, 31, 32, 34, 36, 41, 47, 54, 59, 65, 74, 82, 87, 92, 97, 31, 32,
+ 32, 32, 34, 35, 39, 45, 50, 55, 61, 69, 76, 81, 87, 92, 31, 32, 33, 33,
+ 35, 36, 40, 44, 49, 54, 59, 67, 73, 78, 83, 88, 32, 32, 33, 35, 37, 38,
+ 41, 45, 49, 53, 58, 65, 71, 75, 80, 86, 34, 34, 35, 37, 39, 42, 46, 50,
+ 54, 58, 63, 70, 76, 80, 84, 85, 36, 35, 36, 38, 42, 48, 52, 56, 60, 64,
+ 68, 75, 80, 85, 90, 91, 41, 39, 40, 41, 46, 52, 57, 62, 67, 71, 75, 83,
+ 88, 92, 95, 97, 47, 45, 44, 45, 50, 56, 62, 69, 75, 79, 84, 91, 97, 100,
+ 102, 104, 54, 50, 49, 49, 54, 60, 67, 75, 82, 87, 92, 100, 106, 110,
+ 109, 112, 59, 55, 54, 53, 58, 64, 71, 79, 87, 92, 98, 106, 112, 117,
+ 117, 121, 65, 61, 59, 58, 63, 68, 75, 84, 92, 98, 105, 114, 120, 125,
+ 126, 130, 74, 69, 67, 65, 70, 75, 83, 91, 100, 106, 114, 123, 131, 135,
+ 137, 140, 82, 76, 73, 71, 76, 80, 88, 97, 106, 112, 120, 131, 139, 144,
+ 148, 150, 87, 81, 78, 75, 80, 85, 92, 100, 110, 117, 125, 135, 144, 150,
+ 155, 162, 92, 87, 83, 80, 84, 90, 95, 102, 109, 117, 126, 137, 148, 155,
+ 162, 168, 97, 92, 88, 86, 85, 91, 97, 104, 112, 121, 130, 140, 150, 162,
+ 168, 174],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 31, 32, 32, 34, 35, 36, 39, 41, 44, 47, 48, 54, 56,
+ 59, 64, 65, 71, 74, 80, 82, 83, 87, 90, 92, 95, 97, 100, 31, 32, 32, 32,
+ 32, 32, 32, 33, 34, 35, 35, 38, 40, 42, 45, 46, 51, 53, 56, 61, 62, 68,
+ 71, 76, 78, 78, 83, 85, 88, 90, 92, 95, 31, 32, 32, 32, 32, 32, 32, 33,
+ 34, 34, 35, 38, 39, 42, 45, 45, 50, 52, 55, 60, 61, 67, 69, 74, 76, 77,
+ 81, 84, 87, 89, 92, 95, 31, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 37,
+ 38, 41, 44, 44, 49, 51, 54, 58, 59, 65, 68, 72, 74, 75, 79, 81, 84, 86,
+ 88, 90, 31, 32, 32, 32, 33, 33, 33, 34, 35, 36, 36, 39, 40, 42, 44, 45,
+ 49, 51, 54, 58, 59, 64, 67, 71, 73, 74, 78, 80, 83, 85, 88, 90, 31, 32,
+ 32, 32, 33, 33, 34, 34, 35, 36, 36, 39, 40, 42, 45, 45, 50, 51, 54, 58,
+ 59, 64, 67, 71, 73, 74, 78, 80, 82, 84, 86, 89, 32, 32, 32, 32, 33, 34,
+ 35, 36, 37, 38, 38, 40, 41, 42, 45, 46, 49, 51, 53, 57, 58, 63, 65, 69,
+ 71, 72, 75, 78, 80, 83, 86, 89, 32, 33, 33, 33, 34, 34, 36, 36, 38, 39,
+ 40, 42, 43, 44, 47, 47, 51, 53, 55, 59, 60, 65, 67, 71, 73, 73, 77, 78,
+ 80, 82, 84, 86, 34, 34, 34, 33, 35, 35, 37, 38, 39, 42, 42, 45, 46, 47,
+ 50, 51, 54, 56, 58, 62, 63, 68, 70, 74, 76, 76, 80, 82, 84, 85, 85, 86,
+ 35, 35, 34, 34, 36, 36, 38, 39, 42, 46, 47, 49, 50, 52, 55, 55, 59, 60,
+ 62, 66, 67, 72, 74, 78, 79, 80, 83, 84, 85, 87, 90, 92, 36, 35, 35, 34,
+ 36, 36, 38, 40, 42, 47, 48, 50, 52, 54, 56, 57, 60, 61, 64, 67, 68, 73,
+ 75, 79, 80, 81, 85, 87, 90, 91, 91, 92, 39, 38, 38, 37, 39, 39, 40, 42,
+ 45, 49, 50, 54, 55, 58, 60, 61, 65, 66, 69, 72, 73, 78, 80, 84, 86, 86,
+ 90, 91, 91, 92, 95, 97, 41, 40, 39, 38, 40, 40, 41, 43, 46, 50, 52, 55,
+ 57, 60, 62, 63, 67, 69, 71, 75, 75, 80, 83, 86, 88, 89, 92, 93, 95, 97,
+ 97, 98, 44, 42, 42, 41, 42, 42, 42, 44, 47, 52, 54, 58, 60, 63, 66, 67,
+ 71, 73, 75, 79, 79, 84, 86, 90, 92, 92, 96, 98, 98, 98, 101, 104, 47,
+ 45, 45, 44, 44, 45, 45, 47, 50, 55, 56, 60, 62, 66, 69, 70, 75, 77, 79,
+ 83, 84, 89, 91, 95, 97, 97, 100, 99, 102, 105, 104, 104, 48, 46, 45, 44,
+ 45, 45, 46, 47, 51, 55, 57, 61, 63, 67, 70, 71, 76, 78, 80, 84, 85, 90,
+ 93, 96, 98, 99, 102, 106, 106, 105, 108, 111, 54, 51, 50, 49, 49, 50,
+ 49, 51, 54, 59, 60, 65, 67, 71, 75, 76, 82, 84, 87, 91, 92, 97, 100,
+ 104, 106, 106, 110, 108, 109, 112, 112, 111, 56, 53, 52, 51, 51, 51, 51,
+ 53, 56, 60, 61, 66, 69, 73, 77, 78, 84, 86, 89, 93, 94, 100, 102, 106,
+ 108, 109, 112, 113, 115, 114, 116, 119, 59, 56, 55, 54, 54, 54, 53, 55,
+ 58, 62, 64, 69, 71, 75, 79, 80, 87, 89, 92, 97, 98, 103, 106, 110, 112,
+ 113, 117, 118, 117, 121, 121, 119, 64, 61, 60, 58, 58, 58, 57, 59, 62,
+ 66, 67, 72, 75, 79, 83, 84, 91, 93, 97, 102, 103, 109, 112, 116, 118,
+ 119, 122, 121, 125, 123, 125, 128, 65, 62, 61, 59, 59, 59, 58, 60, 63,
+ 67, 68, 73, 75, 79, 84, 85, 92, 94, 98, 103, 105, 111, 114, 118, 120,
+ 121, 125, 129, 126, 129, 130, 129, 71, 68, 67, 65, 64, 64, 63, 65, 68,
+ 72, 73, 78, 80, 84, 89, 90, 97, 100, 103, 109, 111, 117, 120, 125, 127,
+ 128, 133, 130, 134, 133, 133, 137, 74, 71, 69, 68, 67, 67, 65, 67, 70,
+ 74, 75, 80, 83, 86, 91, 93, 100, 102, 106, 112, 114, 120, 123, 128, 131,
+ 131, 135, 137, 137, 138, 140, 137, 80, 76, 74, 72, 71, 71, 69, 71, 74,
+ 78, 79, 84, 86, 90, 95, 96, 104, 106, 110, 116, 118, 125, 128, 134, 136,
+ 137, 142, 141, 142, 143, 143, 147, 82, 78, 76, 74, 73, 73, 71, 73, 76,
+ 79, 80, 86, 88, 92, 97, 98, 106, 108, 112, 118, 120, 127, 131, 136, 139,
+ 139, 144, 147, 148, 147, 150, 148, 83, 78, 77, 75, 74, 74, 72, 73, 76,
+ 80, 81, 86, 89, 92, 97, 99, 106, 109, 113, 119, 121, 128, 131, 137, 139,
+ 140, 145, 150, 152, 155, 152, 157, 87, 83, 81, 79, 78, 78, 75, 77, 80,
+ 83, 85, 90, 92, 96, 100, 102, 110, 112, 117, 122, 125, 133, 135, 142,
+ 144, 145, 150, 151, 155, 158, 162, 158, 90, 85, 84, 81, 80, 80, 78, 78,
+ 82, 84, 87, 91, 93, 98, 99, 106, 108, 113, 118, 121, 129, 130, 137, 141,
+ 147, 150, 151, 156, 156, 161, 164, 169, 92, 88, 87, 84, 83, 82, 80, 80,
+ 84, 85, 90, 91, 95, 98, 102, 106, 109, 115, 117, 125, 126, 134, 137,
+ 142, 148, 152, 155, 156, 162, 162, 168, 170, 95, 90, 89, 86, 85, 84, 83,
+ 82, 85, 87, 91, 92, 97, 98, 105, 105, 112, 114, 121, 123, 129, 133, 138,
+ 143, 147, 155, 158, 161, 162, 168, 168, 174, 97, 92, 92, 88, 88, 86, 86,
+ 84, 85, 90, 91, 95, 97, 101, 104, 108, 112, 116, 121, 125, 130, 133,
+ 140, 143, 150, 152, 162, 164, 168, 168, 174, 175, 100, 95, 95, 90, 90,
+ 89, 89, 86, 86, 92, 92, 97, 98, 104, 104, 111, 111, 119, 119, 128, 129,
+ 137, 137, 147, 148, 157, 158, 169, 170, 174, 175, 181],
+ /* Size 4x8 */
+ [32, 35, 59, 83, 32, 36, 57, 78, 34, 47, 65, 82, 41, 53, 78, 97, 51, 61,
+ 92, 111, 65, 73, 108, 129, 75, 81, 117, 148, 86, 92, 119, 154],
+ /* Size 8x4 */
+ [32, 32, 34, 41, 51, 65, 75, 86, 35, 36, 47, 53, 61, 73, 81, 92, 59, 57,
+ 65, 78, 92, 108, 117, 119, 83, 78, 82, 97, 111, 129, 148, 154],
+ /* Size 8x16 */
+ [32, 31, 35, 44, 53, 65, 82, 90, 31, 32, 34, 41, 50, 61, 76, 85, 31, 33,
+ 35, 42, 49, 59, 73, 81, 32, 34, 37, 42, 49, 58, 71, 79, 34, 35, 41, 48,
+ 54, 63, 76, 81, 36, 36, 46, 54, 60, 68, 80, 87, 41, 40, 49, 60, 67, 76,
+ 88, 93, 47, 44, 53, 66, 75, 84, 97, 101, 53, 50, 57, 71, 82, 92, 106,
+ 108, 58, 54, 61, 75, 87, 98, 112, 116, 65, 59, 66, 79, 92, 105, 120,
+ 124, 74, 67, 73, 86, 100, 113, 131, 134, 82, 73, 79, 92, 105, 120, 139,
+ 142, 87, 78, 83, 96, 110, 125, 144, 153, 92, 83, 84, 97, 114, 132, 150,
+ 157, 97, 88, 86, 97, 111, 128, 147, 163],
+ /* Size 16x8 */
+ [32, 31, 31, 32, 34, 36, 41, 47, 53, 58, 65, 74, 82, 87, 92, 97, 31, 32,
+ 33, 34, 35, 36, 40, 44, 50, 54, 59, 67, 73, 78, 83, 88, 35, 34, 35, 37,
+ 41, 46, 49, 53, 57, 61, 66, 73, 79, 83, 84, 86, 44, 41, 42, 42, 48, 54,
+ 60, 66, 71, 75, 79, 86, 92, 96, 97, 97, 53, 50, 49, 49, 54, 60, 67, 75,
+ 82, 87, 92, 100, 105, 110, 114, 111, 65, 61, 59, 58, 63, 68, 76, 84, 92,
+ 98, 105, 113, 120, 125, 132, 128, 82, 76, 73, 71, 76, 80, 88, 97, 106,
+ 112, 120, 131, 139, 144, 150, 147, 90, 85, 81, 79, 81, 87, 93, 101, 108,
+ 116, 124, 134, 142, 153, 157, 163],
+ /* Size 16x32 */
+ [32, 31, 31, 32, 35, 36, 44, 47, 53, 62, 65, 79, 82, 88, 90, 93, 31, 32,
+ 32, 32, 35, 35, 42, 45, 51, 59, 62, 75, 78, 83, 86, 88, 31, 32, 32, 32,
+ 34, 35, 41, 45, 50, 58, 61, 74, 76, 82, 85, 88, 31, 32, 32, 33, 34, 34,
+ 41, 44, 49, 57, 59, 72, 74, 79, 82, 84, 31, 32, 33, 34, 35, 36, 42, 44,
+ 49, 57, 59, 71, 73, 79, 81, 84, 32, 32, 33, 34, 36, 36, 42, 45, 50, 57,
+ 59, 71, 73, 78, 80, 82, 32, 33, 34, 35, 37, 38, 42, 45, 49, 56, 58, 69,
+ 71, 76, 79, 83, 32, 33, 34, 36, 39, 40, 44, 47, 51, 58, 60, 71, 73, 76,
+ 78, 80, 34, 34, 35, 37, 41, 42, 48, 50, 54, 61, 63, 73, 76, 81, 81, 80,
+ 35, 34, 36, 38, 45, 47, 52, 55, 59, 65, 67, 77, 79, 82, 83, 86, 36, 34,
+ 36, 38, 46, 48, 54, 56, 60, 66, 68, 78, 80, 85, 87, 86, 39, 37, 39, 40,
+ 48, 50, 58, 60, 65, 71, 73, 84, 86, 89, 88, 91, 41, 39, 40, 41, 49, 51,
+ 60, 62, 67, 74, 76, 86, 88, 91, 93, 91, 44, 41, 42, 43, 51, 53, 63, 66,
+ 71, 78, 79, 90, 92, 97, 94, 97, 47, 44, 44, 45, 53, 56, 66, 69, 75, 82,
+ 84, 95, 97, 98, 101, 98, 48, 45, 45, 46, 54, 56, 67, 70, 76, 83, 85, 96,
+ 98, 104, 101, 105, 53, 49, 50, 50, 57, 60, 71, 75, 82, 90, 92, 103, 106,
+ 107, 108, 105, 55, 51, 51, 51, 59, 61, 72, 77, 84, 92, 94, 106, 108,
+ 111, 110, 112, 58, 54, 54, 54, 61, 63, 75, 79, 87, 95, 98, 110, 112,
+ 117, 116, 113, 63, 58, 58, 57, 65, 67, 78, 83, 91, 100, 103, 116, 118,
+ 119, 119, 121, 65, 60, 59, 58, 66, 68, 79, 84, 92, 102, 105, 118, 120,
+ 127, 124, 122, 71, 65, 64, 63, 71, 73, 84, 89, 97, 108, 111, 125, 127,
+ 129, 129, 130, 74, 68, 67, 66, 73, 75, 86, 91, 100, 110, 113, 128, 131,
+ 135, 134, 130, 79, 72, 71, 70, 77, 79, 90, 95, 104, 115, 118, 133, 136,
+ 140, 139, 140, 82, 75, 73, 72, 79, 81, 92, 97, 105, 117, 120, 136, 139,
+ 145, 142, 140, 82, 75, 74, 72, 79, 81, 92, 97, 106, 117, 121, 136, 139,
+ 148, 150, 149, 87, 79, 78, 76, 83, 85, 96, 100, 110, 120, 125, 141, 144,
+ 148, 153, 150, 89, 82, 81, 78, 83, 87, 97, 99, 113, 118, 128, 139, 145,
+ 153, 157, 161, 92, 84, 83, 80, 84, 89, 97, 101, 114, 116, 132, 135, 150,
+ 153, 157, 162, 94, 86, 85, 82, 85, 92, 97, 104, 112, 119, 130, 136, 151,
+ 154, 163, 166, 97, 88, 88, 85, 86, 94, 97, 107, 111, 123, 128, 140, 147,
+ 159, 163, 167, 99, 91, 91, 87, 87, 97, 97, 110, 110, 126, 126, 144, 144,
+ 163, 163, 173],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 31, 32, 32, 32, 34, 35, 36, 39, 41, 44, 47, 48, 53, 55,
+ 58, 63, 65, 71, 74, 79, 82, 82, 87, 89, 92, 94, 97, 99, 31, 32, 32, 32,
+ 32, 32, 33, 33, 34, 34, 34, 37, 39, 41, 44, 45, 49, 51, 54, 58, 60, 65,
+ 68, 72, 75, 75, 79, 82, 84, 86, 88, 91, 31, 32, 32, 32, 33, 33, 34, 34,
+ 35, 36, 36, 39, 40, 42, 44, 45, 50, 51, 54, 58, 59, 64, 67, 71, 73, 74,
+ 78, 81, 83, 85, 88, 91, 32, 32, 32, 33, 34, 34, 35, 36, 37, 38, 38, 40,
+ 41, 43, 45, 46, 50, 51, 54, 57, 58, 63, 66, 70, 72, 72, 76, 78, 80, 82,
+ 85, 87, 35, 35, 34, 34, 35, 36, 37, 39, 41, 45, 46, 48, 49, 51, 53, 54,
+ 57, 59, 61, 65, 66, 71, 73, 77, 79, 79, 83, 83, 84, 85, 86, 87, 36, 35,
+ 35, 34, 36, 36, 38, 40, 42, 47, 48, 50, 51, 53, 56, 56, 60, 61, 63, 67,
+ 68, 73, 75, 79, 81, 81, 85, 87, 89, 92, 94, 97, 44, 42, 41, 41, 42, 42,
+ 42, 44, 48, 52, 54, 58, 60, 63, 66, 67, 71, 72, 75, 78, 79, 84, 86, 90,
+ 92, 92, 96, 97, 97, 97, 97, 97, 47, 45, 45, 44, 44, 45, 45, 47, 50, 55,
+ 56, 60, 62, 66, 69, 70, 75, 77, 79, 83, 84, 89, 91, 95, 97, 97, 100, 99,
+ 101, 104, 107, 110, 53, 51, 50, 49, 49, 50, 49, 51, 54, 59, 60, 65, 67,
+ 71, 75, 76, 82, 84, 87, 91, 92, 97, 100, 104, 105, 106, 110, 113, 114,
+ 112, 111, 110, 62, 59, 58, 57, 57, 57, 56, 58, 61, 65, 66, 71, 74, 78,
+ 82, 83, 90, 92, 95, 100, 102, 108, 110, 115, 117, 117, 120, 118, 116,
+ 119, 123, 126, 65, 62, 61, 59, 59, 59, 58, 60, 63, 67, 68, 73, 76, 79,
+ 84, 85, 92, 94, 98, 103, 105, 111, 113, 118, 120, 121, 125, 128, 132,
+ 130, 128, 126, 79, 75, 74, 72, 71, 71, 69, 71, 73, 77, 78, 84, 86, 90,
+ 95, 96, 103, 106, 110, 116, 118, 125, 128, 133, 136, 136, 141, 139, 135,
+ 136, 140, 144, 82, 78, 76, 74, 73, 73, 71, 73, 76, 79, 80, 86, 88, 92,
+ 97, 98, 106, 108, 112, 118, 120, 127, 131, 136, 139, 139, 144, 145, 150,
+ 151, 147, 144, 88, 83, 82, 79, 79, 78, 76, 76, 81, 82, 85, 89, 91, 97,
+ 98, 104, 107, 111, 117, 119, 127, 129, 135, 140, 145, 148, 148, 153,
+ 153, 154, 159, 163, 90, 86, 85, 82, 81, 80, 79, 78, 81, 83, 87, 88, 93,
+ 94, 101, 101, 108, 110, 116, 119, 124, 129, 134, 139, 142, 150, 153,
+ 157, 157, 163, 163, 163, 93, 88, 88, 84, 84, 82, 83, 80, 80, 86, 86, 91,
+ 91, 97, 98, 105, 105, 112, 113, 121, 122, 130, 130, 140, 140, 149, 150,
+ 161, 162, 166, 167, 173],
+ /* Size 4x16 */
+ [31, 36, 62, 88, 32, 35, 58, 82, 32, 36, 57, 79, 33, 38, 56, 76, 34, 42,
+ 61, 81, 34, 48, 66, 85, 39, 51, 74, 91, 44, 56, 82, 98, 49, 60, 90, 107,
+ 54, 63, 95, 117, 60, 68, 102, 127, 68, 75, 110, 135, 75, 81, 117, 145,
+ 79, 85, 120, 148, 84, 89, 116, 153, 88, 94, 123, 159],
+ /* Size 16x4 */
+ [31, 32, 32, 33, 34, 34, 39, 44, 49, 54, 60, 68, 75, 79, 84, 88, 36, 35,
+ 36, 38, 42, 48, 51, 56, 60, 63, 68, 75, 81, 85, 89, 94, 62, 58, 57, 56,
+ 61, 66, 74, 82, 90, 95, 102, 110, 117, 120, 116, 123, 88, 82, 79, 76,
+ 81, 85, 91, 98, 107, 117, 127, 135, 145, 148, 153, 159],
+ /* Size 8x32 */
+ [32, 31, 35, 44, 53, 65, 82, 90, 31, 32, 35, 42, 51, 62, 78, 86, 31, 32,
+ 34, 41, 50, 61, 76, 85, 31, 32, 34, 41, 49, 59, 74, 82, 31, 33, 35, 42,
+ 49, 59, 73, 81, 32, 33, 36, 42, 50, 59, 73, 80, 32, 34, 37, 42, 49, 58,
+ 71, 79, 32, 34, 39, 44, 51, 60, 73, 78, 34, 35, 41, 48, 54, 63, 76, 81,
+ 35, 36, 45, 52, 59, 67, 79, 83, 36, 36, 46, 54, 60, 68, 80, 87, 39, 39,
+ 48, 58, 65, 73, 86, 88, 41, 40, 49, 60, 67, 76, 88, 93, 44, 42, 51, 63,
+ 71, 79, 92, 94, 47, 44, 53, 66, 75, 84, 97, 101, 48, 45, 54, 67, 76, 85,
+ 98, 101, 53, 50, 57, 71, 82, 92, 106, 108, 55, 51, 59, 72, 84, 94, 108,
+ 110, 58, 54, 61, 75, 87, 98, 112, 116, 63, 58, 65, 78, 91, 103, 118,
+ 119, 65, 59, 66, 79, 92, 105, 120, 124, 71, 64, 71, 84, 97, 111, 127,
+ 129, 74, 67, 73, 86, 100, 113, 131, 134, 79, 71, 77, 90, 104, 118, 136,
+ 139, 82, 73, 79, 92, 105, 120, 139, 142, 82, 74, 79, 92, 106, 121, 139,
+ 150, 87, 78, 83, 96, 110, 125, 144, 153, 89, 81, 83, 97, 113, 128, 145,
+ 157, 92, 83, 84, 97, 114, 132, 150, 157, 94, 85, 85, 97, 112, 130, 151,
+ 163, 97, 88, 86, 97, 111, 128, 147, 163, 99, 91, 87, 97, 110, 126, 144,
+ 163],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 31, 32, 32, 32, 34, 35, 36, 39, 41, 44, 47, 48, 53, 55,
+ 58, 63, 65, 71, 74, 79, 82, 82, 87, 89, 92, 94, 97, 99, 31, 32, 32, 32,
+ 33, 33, 34, 34, 35, 36, 36, 39, 40, 42, 44, 45, 50, 51, 54, 58, 59, 64,
+ 67, 71, 73, 74, 78, 81, 83, 85, 88, 91, 35, 35, 34, 34, 35, 36, 37, 39,
+ 41, 45, 46, 48, 49, 51, 53, 54, 57, 59, 61, 65, 66, 71, 73, 77, 79, 79,
+ 83, 83, 84, 85, 86, 87, 44, 42, 41, 41, 42, 42, 42, 44, 48, 52, 54, 58,
+ 60, 63, 66, 67, 71, 72, 75, 78, 79, 84, 86, 90, 92, 92, 96, 97, 97, 97,
+ 97, 97, 53, 51, 50, 49, 49, 50, 49, 51, 54, 59, 60, 65, 67, 71, 75, 76,
+ 82, 84, 87, 91, 92, 97, 100, 104, 105, 106, 110, 113, 114, 112, 111,
+ 110, 65, 62, 61, 59, 59, 59, 58, 60, 63, 67, 68, 73, 76, 79, 84, 85, 92,
+ 94, 98, 103, 105, 111, 113, 118, 120, 121, 125, 128, 132, 130, 128, 126,
+ 82, 78, 76, 74, 73, 73, 71, 73, 76, 79, 80, 86, 88, 92, 97, 98, 106,
+ 108, 112, 118, 120, 127, 131, 136, 139, 139, 144, 145, 150, 151, 147,
+ 144, 90, 86, 85, 82, 81, 80, 79, 78, 81, 83, 87, 88, 93, 94, 101, 101,
+ 108, 110, 116, 119, 124, 129, 134, 139, 142, 150, 153, 157, 157, 163,
+ 163, 163]
+ ],
+ [ /* Chroma */
+ /* Size 4x4 */
+ [32, 45, 51, 61, 45, 54, 59, 65, 51, 59, 75, 81, 61, 65, 81, 97],
+ /* Size 8x8 */
+ [31, 34, 46, 47, 50, 57, 61, 65, 34, 39, 47, 45, 48, 53, 57, 61, 46, 47,
+ 52, 52, 54, 58, 61, 62, 47, 45, 52, 58, 62, 65, 68, 68, 50, 48, 54, 62,
+ 68, 73, 77, 76, 57, 53, 58, 65, 73, 82, 86, 86, 61, 57, 61, 68, 77, 86,
+ 91, 95, 65, 61, 62, 68, 76, 86, 95, 100],
+ /* Size 16x16 */
+ [32, 31, 33, 36, 41, 49, 49, 50, 52, 54, 57, 61, 64, 67, 68, 70, 31, 31,
+ 34, 39, 42, 47, 46, 47, 49, 51, 53, 57, 60, 62, 64, 66, 33, 34, 37, 42,
+ 44, 47, 46, 46, 47, 49, 51, 55, 57, 59, 61, 63, 36, 39, 42, 47, 47, 48,
+ 46, 46, 47, 48, 50, 53, 55, 57, 59, 61, 41, 42, 44, 47, 48, 50, 49, 50,
+ 50, 52, 53, 56, 58, 60, 61, 60, 49, 47, 47, 48, 50, 53, 53, 54, 54, 55,
+ 56, 59, 61, 63, 64, 64, 49, 46, 46, 46, 49, 53, 55, 57, 59, 60, 61, 64,
+ 66, 67, 67, 67, 50, 47, 46, 46, 50, 54, 57, 61, 63, 64, 66, 69, 70, 72,
+ 71, 71, 52, 49, 47, 47, 50, 54, 59, 63, 66, 68, 70, 73, 75, 77, 75, 75,
+ 54, 51, 49, 48, 52, 55, 60, 64, 68, 71, 73, 76, 79, 80, 79, 79, 57, 53,
+ 51, 50, 53, 56, 61, 66, 70, 73, 76, 80, 82, 84, 83, 84, 61, 57, 55, 53,
+ 56, 59, 64, 69, 73, 76, 80, 84, 87, 89, 88, 88, 64, 60, 57, 55, 58, 61,
+ 66, 70, 75, 79, 82, 87, 91, 93, 93, 93, 67, 62, 59, 57, 60, 63, 67, 72,
+ 77, 80, 84, 89, 93, 95, 96, 97, 68, 64, 61, 59, 61, 64, 67, 71, 75, 79,
+ 83, 88, 93, 96, 99, 100, 70, 66, 63, 61, 60, 64, 67, 71, 75, 79, 84, 88,
+ 93, 97, 100, 102],
+ /* Size 32x32 */
+ [32, 31, 31, 30, 33, 33, 36, 38, 41, 47, 49, 48, 49, 49, 50, 50, 52, 53,
+ 54, 56, 57, 60, 61, 63, 64, 65, 67, 67, 68, 69, 70, 71, 31, 31, 31, 31,
+ 34, 34, 38, 40, 42, 46, 47, 47, 47, 47, 48, 48, 50, 50, 52, 54, 54, 57,
+ 58, 60, 61, 61, 63, 64, 65, 65, 66, 67, 31, 31, 31, 31, 34, 35, 39, 40,
+ 42, 46, 47, 46, 46, 46, 47, 47, 49, 50, 51, 53, 53, 56, 57, 59, 60, 60,
+ 62, 63, 64, 65, 66, 67, 30, 31, 31, 32, 34, 35, 40, 41, 42, 45, 46, 45,
+ 45, 45, 46, 46, 47, 48, 49, 51, 52, 54, 55, 57, 58, 58, 60, 61, 62, 62,
+ 63, 64, 33, 34, 34, 34, 37, 38, 42, 43, 44, 46, 47, 46, 46, 45, 46, 46,
+ 47, 48, 49, 51, 51, 53, 55, 56, 57, 57, 59, 60, 61, 62, 63, 64, 33, 34,
+ 35, 35, 38, 39, 43, 44, 45, 47, 47, 46, 46, 45, 46, 46, 47, 48, 49, 51,
+ 51, 53, 54, 56, 57, 57, 59, 60, 60, 61, 62, 62, 36, 38, 39, 40, 42, 43,
+ 47, 47, 47, 47, 48, 46, 46, 45, 46, 46, 47, 47, 48, 49, 50, 52, 53, 54,
+ 55, 55, 57, 58, 59, 60, 61, 62, 38, 40, 40, 41, 43, 44, 47, 47, 48, 48,
+ 49, 48, 47, 47, 47, 47, 48, 49, 49, 51, 51, 53, 54, 55, 56, 56, 58, 58,
+ 58, 59, 60, 60, 41, 42, 42, 42, 44, 45, 47, 48, 48, 50, 50, 49, 49, 49,
+ 50, 50, 50, 51, 52, 53, 53, 55, 56, 57, 58, 58, 60, 61, 61, 61, 60, 60,
+ 47, 46, 46, 45, 46, 47, 47, 48, 50, 52, 52, 52, 52, 52, 53, 53, 53, 54,
+ 55, 55, 56, 58, 58, 60, 60, 61, 62, 61, 61, 62, 63, 64, 49, 47, 47, 46,
+ 47, 47, 48, 49, 50, 52, 53, 53, 53, 53, 54, 54, 54, 55, 55, 56, 56, 58,
+ 59, 60, 61, 61, 63, 63, 64, 64, 64, 64, 48, 47, 46, 45, 46, 46, 46, 48,
+ 49, 52, 53, 54, 55, 55, 56, 56, 57, 58, 58, 59, 60, 61, 62, 63, 64, 64,
+ 66, 65, 65, 65, 66, 67, 49, 47, 46, 45, 46, 46, 46, 47, 49, 52, 53, 55,
+ 55, 57, 57, 58, 59, 59, 60, 61, 61, 63, 64, 65, 66, 66, 67, 67, 67, 68,
+ 67, 67, 49, 47, 46, 45, 45, 45, 45, 47, 49, 52, 53, 55, 57, 58, 59, 60,
+ 61, 62, 62, 63, 63, 65, 66, 67, 68, 68, 69, 70, 69, 68, 69, 70, 50, 48,
+ 47, 46, 46, 46, 46, 47, 50, 53, 54, 56, 57, 59, 61, 61, 63, 64, 64, 66,
+ 66, 68, 69, 70, 70, 71, 72, 70, 71, 72, 71, 70, 50, 48, 47, 46, 46, 46,
+ 46, 47, 50, 53, 54, 56, 58, 60, 61, 61, 63, 64, 65, 66, 67, 68, 69, 71,
+ 71, 71, 73, 74, 73, 72, 73, 74, 52, 50, 49, 47, 47, 47, 47, 48, 50, 53,
+ 54, 57, 59, 61, 63, 63, 66, 67, 68, 70, 70, 72, 73, 75, 75, 75, 77, 75,
+ 75, 76, 75, 74, 53, 50, 50, 48, 48, 48, 47, 49, 51, 54, 55, 58, 59, 62,
+ 64, 64, 67, 68, 69, 71, 71, 73, 74, 76, 77, 77, 78, 78, 78, 76, 77, 78,
+ 54, 52, 51, 49, 49, 49, 48, 49, 52, 55, 55, 58, 60, 62, 64, 65, 68, 69,
+ 71, 73, 73, 75, 76, 78, 79, 79, 80, 80, 79, 80, 79, 78, 56, 54, 53, 51,
+ 51, 51, 49, 51, 53, 55, 56, 59, 61, 63, 66, 66, 70, 71, 73, 75, 76, 78,
+ 79, 81, 82, 82, 83, 81, 83, 81, 81, 82, 57, 54, 53, 52, 51, 51, 50, 51,
+ 53, 56, 56, 60, 61, 63, 66, 67, 70, 71, 73, 76, 76, 79, 80, 82, 82, 83,
+ 84, 85, 83, 84, 84, 82, 60, 57, 56, 54, 53, 53, 52, 53, 55, 58, 58, 61,
+ 63, 65, 68, 68, 72, 73, 75, 78, 79, 82, 83, 85, 86, 86, 88, 86, 87, 86,
+ 85, 86, 61, 58, 57, 55, 55, 54, 53, 54, 56, 58, 59, 62, 64, 66, 69, 69,
+ 73, 74, 76, 79, 80, 83, 84, 86, 87, 88, 89, 89, 88, 88, 88, 86, 63, 60,
+ 59, 57, 56, 56, 54, 55, 57, 60, 60, 63, 65, 67, 70, 71, 75, 76, 78, 81,
+ 82, 85, 86, 89, 90, 90, 92, 91, 91, 90, 89, 91, 64, 61, 60, 58, 57, 57,
+ 55, 56, 58, 60, 61, 64, 66, 68, 70, 71, 75, 77, 79, 82, 82, 86, 87, 90,
+ 91, 91, 93, 93, 93, 92, 93, 91, 65, 61, 60, 58, 57, 57, 55, 56, 58, 61,
+ 61, 64, 66, 68, 71, 71, 75, 77, 79, 82, 83, 86, 88, 90, 91, 91, 93, 94,
+ 95, 95, 93, 95, 67, 63, 62, 60, 59, 59, 57, 58, 60, 62, 63, 66, 67, 69,
+ 72, 73, 77, 78, 80, 83, 84, 88, 89, 92, 93, 93, 95, 95, 96, 96, 97, 95,
+ 67, 64, 63, 61, 60, 60, 58, 58, 61, 61, 63, 65, 67, 70, 70, 74, 75, 78,
+ 80, 81, 85, 86, 89, 91, 93, 94, 95, 97, 97, 98, 98, 100, 68, 65, 64, 62,
+ 61, 60, 59, 58, 61, 61, 64, 65, 67, 69, 71, 73, 75, 78, 79, 83, 83, 87,
+ 88, 91, 93, 95, 96, 97, 99, 98, 100, 100, 69, 65, 65, 62, 62, 61, 60,
+ 59, 61, 62, 64, 65, 68, 68, 72, 72, 76, 76, 80, 81, 84, 86, 88, 90, 92,
+ 95, 96, 98, 98, 100, 100, 101, 70, 66, 66, 63, 63, 62, 61, 60, 60, 63,
+ 64, 66, 67, 69, 71, 73, 75, 77, 79, 81, 84, 85, 88, 89, 93, 93, 97, 98,
+ 100, 100, 102, 101, 71, 67, 67, 64, 64, 62, 62, 60, 60, 64, 64, 67, 67,
+ 70, 70, 74, 74, 78, 78, 82, 82, 86, 86, 91, 91, 95, 95, 100, 100, 101,
+ 101, 104],
+ /* Size 4x8 */
+ [31, 47, 53, 63, 36, 47, 50, 59, 46, 52, 55, 61, 45, 53, 63, 70, 49, 55,
+ 71, 77, 54, 58, 77, 86, 59, 61, 81, 94, 63, 65, 80, 95],
+ /* Size 8x4 */
+ [31, 36, 46, 45, 49, 54, 59, 63, 47, 47, 52, 53, 55, 58, 61, 65, 53, 50,
+ 55, 63, 71, 77, 81, 80, 63, 59, 61, 70, 77, 86, 94, 95],
+ /* Size 8x16 */
+ [32, 33, 45, 49, 52, 57, 64, 68, 31, 34, 45, 46, 49, 53, 60, 64, 33, 37,
+ 46, 45, 47, 51, 57, 61, 37, 43, 47, 45, 47, 50, 55, 59, 42, 44, 49, 49,
+ 50, 53, 58, 60, 49, 47, 52, 53, 54, 57, 61, 63, 48, 46, 51, 57, 59, 61,
+ 66, 67, 50, 46, 52, 59, 63, 66, 71, 71, 52, 47, 53, 61, 66, 71, 75, 74,
+ 54, 49, 54, 62, 68, 73, 79, 79, 57, 51, 55, 64, 70, 76, 83, 83, 61, 55,
+ 58, 66, 73, 80, 87, 87, 64, 57, 60, 68, 75, 83, 91, 91, 66, 59, 61, 69,
+ 77, 84, 93, 95, 68, 61, 61, 68, 77, 86, 94, 97, 70, 63, 61, 67, 75, 83,
+ 92, 98],
+ /* Size 16x8 */
+ [32, 31, 33, 37, 42, 49, 48, 50, 52, 54, 57, 61, 64, 66, 68, 70, 33, 34,
+ 37, 43, 44, 47, 46, 46, 47, 49, 51, 55, 57, 59, 61, 63, 45, 45, 46, 47,
+ 49, 52, 51, 52, 53, 54, 55, 58, 60, 61, 61, 61, 49, 46, 45, 45, 49, 53,
+ 57, 59, 61, 62, 64, 66, 68, 69, 68, 67, 52, 49, 47, 47, 50, 54, 59, 63,
+ 66, 68, 70, 73, 75, 77, 77, 75, 57, 53, 51, 50, 53, 57, 61, 66, 71, 73,
+ 76, 80, 83, 84, 86, 83, 64, 60, 57, 55, 58, 61, 66, 71, 75, 79, 83, 87,
+ 91, 93, 94, 92, 68, 64, 61, 59, 60, 63, 67, 71, 74, 79, 83, 87, 91, 95,
+ 97, 98],
+ /* Size 16x32 */
+ [32, 31, 33, 37, 45, 48, 49, 50, 52, 56, 57, 63, 64, 67, 68, 68, 31, 31,
+ 34, 38, 45, 47, 47, 48, 50, 53, 54, 60, 61, 63, 64, 65, 31, 32, 34, 39,
+ 45, 46, 46, 47, 49, 52, 53, 59, 60, 62, 64, 65, 30, 32, 35, 40, 44, 46,
+ 45, 46, 48, 51, 52, 57, 58, 60, 61, 62, 33, 35, 37, 42, 46, 47, 45, 46,
+ 47, 50, 51, 56, 57, 60, 61, 62, 33, 36, 38, 43, 46, 47, 46, 46, 47, 50,
+ 51, 56, 57, 59, 60, 60, 37, 40, 43, 47, 47, 47, 45, 46, 47, 49, 50, 54,
+ 55, 57, 59, 61, 39, 41, 43, 47, 48, 48, 47, 47, 48, 50, 51, 55, 56, 57,
+ 58, 59, 42, 43, 44, 47, 49, 50, 49, 50, 50, 53, 53, 57, 58, 60, 60, 59,
+ 47, 46, 46, 48, 51, 52, 53, 53, 53, 55, 56, 60, 61, 61, 61, 62, 49, 46,
+ 47, 48, 52, 53, 53, 54, 54, 56, 57, 60, 61, 63, 63, 62, 48, 46, 46, 47,
+ 51, 53, 56, 56, 57, 59, 60, 64, 64, 65, 64, 65, 48, 45, 46, 46, 51, 53,
+ 57, 57, 59, 61, 61, 65, 66, 66, 67, 65, 49, 45, 45, 46, 51, 53, 58, 59,
+ 61, 63, 64, 67, 68, 70, 67, 68, 50, 46, 46, 46, 52, 54, 59, 61, 63, 65,
+ 66, 70, 71, 70, 71, 68, 50, 46, 46, 46, 52, 54, 59, 61, 64, 66, 67, 71,
+ 71, 73, 71, 72, 52, 48, 47, 47, 53, 54, 61, 63, 66, 70, 71, 75, 75, 75,
+ 74, 72, 53, 49, 48, 48, 53, 55, 61, 64, 67, 71, 72, 76, 77, 77, 75, 76,
+ 54, 50, 49, 49, 54, 55, 62, 65, 68, 72, 73, 78, 79, 80, 79, 76, 56, 51,
+ 51, 50, 55, 56, 63, 66, 70, 74, 76, 81, 82, 81, 80, 80, 57, 52, 51, 50,
+ 55, 56, 64, 66, 70, 75, 76, 82, 83, 85, 83, 80, 60, 54, 54, 52, 57, 58,
+ 65, 68, 72, 77, 79, 85, 86, 86, 85, 84, 61, 56, 55, 53, 58, 59, 66, 69,
+ 73, 79, 80, 86, 87, 89, 87, 84, 63, 57, 56, 55, 59, 60, 67, 70, 75, 80,
+ 82, 89, 90, 91, 89, 89, 64, 58, 57, 56, 60, 61, 68, 71, 75, 81, 83, 90,
+ 91, 93, 91, 89, 64, 59, 58, 56, 60, 61, 68, 71, 75, 81, 83, 90, 91, 94,
+ 94, 93, 66, 60, 59, 57, 61, 63, 69, 72, 77, 82, 84, 92, 93, 94, 95, 93,
+ 67, 61, 60, 58, 61, 63, 69, 70, 78, 80, 85, 90, 93, 96, 97, 97, 68, 62,
+ 61, 59, 61, 64, 68, 71, 77, 79, 86, 88, 94, 96, 97, 98, 69, 63, 62, 59,
+ 61, 65, 68, 72, 76, 80, 85, 88, 94, 95, 99, 99, 70, 63, 63, 60, 61, 66,
+ 67, 73, 75, 81, 83, 89, 92, 97, 98, 99, 70, 64, 64, 61, 61, 67, 67, 74,
+ 74, 82, 82, 90, 90, 98, 98, 102],
+ /* Size 32x16 */
+ [32, 31, 31, 30, 33, 33, 37, 39, 42, 47, 49, 48, 48, 49, 50, 50, 52, 53,
+ 54, 56, 57, 60, 61, 63, 64, 64, 66, 67, 68, 69, 70, 70, 31, 31, 32, 32,
+ 35, 36, 40, 41, 43, 46, 46, 46, 45, 45, 46, 46, 48, 49, 50, 51, 52, 54,
+ 56, 57, 58, 59, 60, 61, 62, 63, 63, 64, 33, 34, 34, 35, 37, 38, 43, 43,
+ 44, 46, 47, 46, 46, 45, 46, 46, 47, 48, 49, 51, 51, 54, 55, 56, 57, 58,
+ 59, 60, 61, 62, 63, 64, 37, 38, 39, 40, 42, 43, 47, 47, 47, 48, 48, 47,
+ 46, 46, 46, 46, 47, 48, 49, 50, 50, 52, 53, 55, 56, 56, 57, 58, 59, 59,
+ 60, 61, 45, 45, 45, 44, 46, 46, 47, 48, 49, 51, 52, 51, 51, 51, 52, 52,
+ 53, 53, 54, 55, 55, 57, 58, 59, 60, 60, 61, 61, 61, 61, 61, 61, 48, 47,
+ 46, 46, 47, 47, 47, 48, 50, 52, 53, 53, 53, 53, 54, 54, 54, 55, 55, 56,
+ 56, 58, 59, 60, 61, 61, 63, 63, 64, 65, 66, 67, 49, 47, 46, 45, 45, 46,
+ 45, 47, 49, 53, 53, 56, 57, 58, 59, 59, 61, 61, 62, 63, 64, 65, 66, 67,
+ 68, 68, 69, 69, 68, 68, 67, 67, 50, 48, 47, 46, 46, 46, 46, 47, 50, 53,
+ 54, 56, 57, 59, 61, 61, 63, 64, 65, 66, 66, 68, 69, 70, 71, 71, 72, 70,
+ 71, 72, 73, 74, 52, 50, 49, 48, 47, 47, 47, 48, 50, 53, 54, 57, 59, 61,
+ 63, 64, 66, 67, 68, 70, 70, 72, 73, 75, 75, 75, 77, 78, 77, 76, 75, 74,
+ 56, 53, 52, 51, 50, 50, 49, 50, 53, 55, 56, 59, 61, 63, 65, 66, 70, 71,
+ 72, 74, 75, 77, 79, 80, 81, 81, 82, 80, 79, 80, 81, 82, 57, 54, 53, 52,
+ 51, 51, 50, 51, 53, 56, 57, 60, 61, 64, 66, 67, 71, 72, 73, 76, 76, 79,
+ 80, 82, 83, 83, 84, 85, 86, 85, 83, 82, 63, 60, 59, 57, 56, 56, 54, 55,
+ 57, 60, 60, 64, 65, 67, 70, 71, 75, 76, 78, 81, 82, 85, 86, 89, 90, 90,
+ 92, 90, 88, 88, 89, 90, 64, 61, 60, 58, 57, 57, 55, 56, 58, 61, 61, 64,
+ 66, 68, 71, 71, 75, 77, 79, 82, 83, 86, 87, 90, 91, 91, 93, 93, 94, 94,
+ 92, 90, 67, 63, 62, 60, 60, 59, 57, 57, 60, 61, 63, 65, 66, 70, 70, 73,
+ 75, 77, 80, 81, 85, 86, 89, 91, 93, 94, 94, 96, 96, 95, 97, 98, 68, 64,
+ 64, 61, 61, 60, 59, 58, 60, 61, 63, 64, 67, 67, 71, 71, 74, 75, 79, 80,
+ 83, 85, 87, 89, 91, 94, 95, 97, 97, 99, 98, 98, 68, 65, 65, 62, 62, 60,
+ 61, 59, 59, 62, 62, 65, 65, 68, 68, 72, 72, 76, 76, 80, 80, 84, 84, 89,
+ 89, 93, 93, 97, 98, 99, 99, 102],
+ /* Size 4x16 */
+ [31, 48, 56, 67, 32, 46, 52, 62, 35, 47, 50, 60, 40, 47, 49, 57, 43, 50,
+ 53, 60, 46, 53, 56, 63, 45, 53, 61, 66, 46, 54, 65, 70, 48, 54, 70, 75,
+ 50, 55, 72, 80, 52, 56, 75, 85, 56, 59, 79, 89, 58, 61, 81, 93, 60, 63,
+ 82, 94, 62, 64, 79, 96, 63, 66, 81, 97],
+ /* Size 16x4 */
+ [31, 32, 35, 40, 43, 46, 45, 46, 48, 50, 52, 56, 58, 60, 62, 63, 48, 46,
+ 47, 47, 50, 53, 53, 54, 54, 55, 56, 59, 61, 63, 64, 66, 56, 52, 50, 49,
+ 53, 56, 61, 65, 70, 72, 75, 79, 81, 82, 79, 81, 67, 62, 60, 57, 60, 63,
+ 66, 70, 75, 80, 85, 89, 93, 94, 96, 97],
+ /* Size 8x32 */
+ [32, 33, 45, 49, 52, 57, 64, 68, 31, 34, 45, 47, 50, 54, 61, 64, 31, 34,
+ 45, 46, 49, 53, 60, 64, 30, 35, 44, 45, 48, 52, 58, 61, 33, 37, 46, 45,
+ 47, 51, 57, 61, 33, 38, 46, 46, 47, 51, 57, 60, 37, 43, 47, 45, 47, 50,
+ 55, 59, 39, 43, 48, 47, 48, 51, 56, 58, 42, 44, 49, 49, 50, 53, 58, 60,
+ 47, 46, 51, 53, 53, 56, 61, 61, 49, 47, 52, 53, 54, 57, 61, 63, 48, 46,
+ 51, 56, 57, 60, 64, 64, 48, 46, 51, 57, 59, 61, 66, 67, 49, 45, 51, 58,
+ 61, 64, 68, 67, 50, 46, 52, 59, 63, 66, 71, 71, 50, 46, 52, 59, 64, 67,
+ 71, 71, 52, 47, 53, 61, 66, 71, 75, 74, 53, 48, 53, 61, 67, 72, 77, 75,
+ 54, 49, 54, 62, 68, 73, 79, 79, 56, 51, 55, 63, 70, 76, 82, 80, 57, 51,
+ 55, 64, 70, 76, 83, 83, 60, 54, 57, 65, 72, 79, 86, 85, 61, 55, 58, 66,
+ 73, 80, 87, 87, 63, 56, 59, 67, 75, 82, 90, 89, 64, 57, 60, 68, 75, 83,
+ 91, 91, 64, 58, 60, 68, 75, 83, 91, 94, 66, 59, 61, 69, 77, 84, 93, 95,
+ 67, 60, 61, 69, 78, 85, 93, 97, 68, 61, 61, 68, 77, 86, 94, 97, 69, 62,
+ 61, 68, 76, 85, 94, 99, 70, 63, 61, 67, 75, 83, 92, 98, 70, 64, 61, 67,
+ 74, 82, 90, 98],
+ /* Size 32x8 */
+ [32, 31, 31, 30, 33, 33, 37, 39, 42, 47, 49, 48, 48, 49, 50, 50, 52, 53,
+ 54, 56, 57, 60, 61, 63, 64, 64, 66, 67, 68, 69, 70, 70, 33, 34, 34, 35,
+ 37, 38, 43, 43, 44, 46, 47, 46, 46, 45, 46, 46, 47, 48, 49, 51, 51, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 45, 45, 45, 44, 46, 46, 47, 48,
+ 49, 51, 52, 51, 51, 51, 52, 52, 53, 53, 54, 55, 55, 57, 58, 59, 60, 60,
+ 61, 61, 61, 61, 61, 61, 49, 47, 46, 45, 45, 46, 45, 47, 49, 53, 53, 56,
+ 57, 58, 59, 59, 61, 61, 62, 63, 64, 65, 66, 67, 68, 68, 69, 69, 68, 68,
+ 67, 67, 52, 50, 49, 48, 47, 47, 47, 48, 50, 53, 54, 57, 59, 61, 63, 64,
+ 66, 67, 68, 70, 70, 72, 73, 75, 75, 75, 77, 78, 77, 76, 75, 74, 57, 54,
+ 53, 52, 51, 51, 50, 51, 53, 56, 57, 60, 61, 64, 66, 67, 71, 72, 73, 76,
+ 76, 79, 80, 82, 83, 83, 84, 85, 86, 85, 83, 82, 64, 61, 60, 58, 57, 57,
+ 55, 56, 58, 61, 61, 64, 66, 68, 71, 71, 75, 77, 79, 82, 83, 86, 87, 90,
+ 91, 91, 93, 93, 94, 94, 92, 90, 68, 64, 64, 61, 61, 60, 59, 58, 60, 61,
+ 63, 64, 67, 67, 71, 71, 74, 75, 79, 80, 83, 85, 87, 89, 91, 94, 95, 97,
+ 97, 99, 98, 98]
+ ]
+ ],
+ [
+ [ /* Luma */
+ /* Size 4x4 */
+ [32, 34, 53, 75, 34, 49, 64, 81, 53, 64, 91, 112, 75, 81, 112, 140],
+ /* Size 8x8 */
+ [32, 32, 34, 39, 50, 62, 76, 84, 32, 33, 35, 40, 48, 59, 71, 79, 34, 35,
+ 39, 46, 53, 63, 74, 81, 39, 40, 46, 56, 65, 75, 86, 92, 50, 48, 53, 65,
+ 78, 90, 101, 106, 62, 59, 63, 75, 90, 105, 118, 123, 76, 71, 74, 86,
+ 101, 118, 134, 142, 84, 79, 81, 92, 106, 123, 142, 153],
+ /* Size 16x16 */
+ [32, 31, 31, 32, 33, 36, 39, 44, 48, 54, 59, 66, 74, 81, 86, 91, 31, 32,
+ 32, 32, 33, 35, 38, 42, 46, 51, 56, 63, 70, 77, 81, 86, 31, 32, 32, 33,
+ 34, 35, 38, 41, 45, 49, 54, 60, 67, 73, 77, 82, 32, 32, 33, 34, 36, 37,
+ 40, 42, 45, 49, 53, 59, 66, 71, 75, 80, 33, 33, 34, 36, 38, 42, 44, 46,
+ 50, 53, 57, 63, 69, 74, 78, 80, 36, 35, 35, 37, 42, 48, 50, 54, 57, 60,
+ 64, 69, 75, 80, 84, 85, 39, 38, 38, 40, 44, 50, 54, 58, 61, 65, 69, 74,
+ 80, 85, 89, 91, 44, 42, 41, 42, 46, 54, 58, 63, 67, 71, 75, 80, 86, 91,
+ 95, 97, 48, 46, 45, 45, 50, 57, 61, 67, 71, 76, 80, 86, 93, 98, 101,
+ 104, 54, 51, 49, 49, 53, 60, 65, 71, 76, 82, 87, 93, 100, 105, 109, 112,
+ 59, 56, 54, 53, 57, 64, 69, 75, 80, 87, 92, 99, 106, 112, 116, 120, 66,
+ 63, 60, 59, 63, 69, 74, 80, 86, 93, 99, 107, 115, 121, 125, 129, 74, 70,
+ 67, 66, 69, 75, 80, 86, 93, 100, 106, 115, 123, 130, 135, 138, 81, 77,
+ 73, 71, 74, 80, 85, 91, 98, 105, 112, 121, 130, 137, 142, 148, 86, 81,
+ 77, 75, 78, 84, 89, 95, 101, 109, 116, 125, 135, 142, 147, 153, 91, 86,
+ 82, 80, 80, 85, 91, 97, 104, 112, 120, 129, 138, 148, 153, 159],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 31, 32, 32, 33, 34, 36, 36, 39, 41, 44, 46, 48, 52,
+ 54, 58, 59, 65, 66, 71, 74, 80, 81, 83, 86, 89, 91, 93, 31, 32, 32, 32,
+ 32, 32, 32, 32, 33, 34, 35, 35, 38, 39, 42, 44, 46, 50, 51, 56, 56, 62,
+ 63, 68, 71, 76, 77, 78, 82, 84, 86, 88, 31, 32, 32, 32, 32, 32, 32, 32,
+ 33, 34, 35, 35, 38, 39, 42, 44, 46, 49, 51, 55, 56, 61, 63, 67, 70, 75,
+ 77, 78, 81, 84, 86, 88, 31, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34,
+ 37, 38, 41, 42, 44, 48, 49, 53, 54, 59, 60, 65, 68, 72, 74, 75, 78, 80,
+ 82, 84, 31, 32, 32, 32, 32, 33, 33, 33, 34, 34, 35, 35, 38, 39, 41, 43,
+ 45, 48, 49, 53, 54, 59, 60, 65, 67, 72, 73, 74, 77, 80, 82, 84, 31, 32,
+ 32, 32, 33, 33, 33, 34, 35, 35, 36, 36, 39, 40, 42, 44, 45, 48, 50, 53,
+ 54, 59, 60, 64, 67, 71, 73, 74, 77, 79, 81, 83, 32, 32, 32, 32, 33, 33,
+ 34, 35, 36, 36, 37, 38, 40, 40, 42, 44, 45, 48, 49, 53, 53, 58, 59, 63,
+ 66, 70, 71, 72, 75, 78, 80, 83, 32, 32, 32, 32, 33, 34, 35, 35, 36, 37,
+ 38, 38, 40, 41, 42, 44, 46, 48, 49, 53, 53, 58, 59, 63, 65, 69, 71, 72,
+ 74, 77, 79, 80, 33, 33, 33, 33, 34, 35, 36, 36, 38, 39, 42, 42, 44, 45,
+ 46, 48, 50, 52, 53, 57, 57, 62, 63, 67, 69, 73, 74, 75, 78, 79, 80, 81,
+ 34, 34, 34, 33, 34, 35, 36, 37, 39, 39, 42, 43, 45, 46, 47, 49, 51, 53,
+ 54, 58, 58, 63, 64, 68, 70, 74, 75, 76, 79, 81, 84, 86, 36, 35, 35, 34,
+ 35, 36, 37, 38, 42, 42, 48, 48, 50, 51, 54, 55, 57, 59, 60, 63, 64, 68,
+ 69, 73, 75, 79, 80, 81, 84, 85, 85, 86, 36, 35, 35, 34, 35, 36, 38, 38,
+ 42, 43, 48, 49, 51, 52, 54, 55, 57, 59, 60, 64, 64, 68, 69, 73, 75, 79,
+ 80, 81, 84, 86, 88, 91, 39, 38, 38, 37, 38, 39, 40, 40, 44, 45, 50, 51,
+ 54, 55, 58, 59, 61, 64, 65, 68, 69, 73, 74, 78, 80, 84, 85, 86, 89, 91,
+ 91, 91, 41, 39, 39, 38, 39, 40, 40, 41, 45, 46, 51, 52, 55, 56, 59, 61,
+ 63, 65, 67, 70, 70, 75, 76, 80, 82, 86, 87, 88, 91, 92, 94, 96, 44, 42,
+ 42, 41, 41, 42, 42, 42, 46, 47, 54, 54, 58, 59, 63, 65, 67, 70, 71, 75,
+ 75, 79, 80, 84, 86, 90, 91, 92, 95, 97, 97, 97, 46, 44, 44, 42, 43, 44,
+ 44, 44, 48, 49, 55, 55, 59, 61, 65, 67, 69, 72, 74, 77, 78, 82, 83, 87,
+ 89, 93, 94, 95, 98, 98, 100, 103, 48, 46, 46, 44, 45, 45, 45, 46, 50,
+ 51, 57, 57, 61, 63, 67, 69, 71, 74, 76, 80, 80, 85, 86, 90, 93, 96, 98,
+ 99, 101, 104, 104, 103, 52, 50, 49, 48, 48, 48, 48, 48, 52, 53, 59, 59,
+ 64, 65, 70, 72, 74, 78, 80, 84, 85, 90, 91, 95, 97, 101, 103, 104, 106,
+ 106, 107, 110, 54, 51, 51, 49, 49, 50, 49, 49, 53, 54, 60, 60, 65, 67,
+ 71, 74, 76, 80, 82, 86, 87, 92, 93, 97, 100, 104, 105, 106, 109, 112,
+ 112, 110, 58, 56, 55, 53, 53, 53, 53, 53, 57, 58, 63, 64, 68, 70, 75,
+ 77, 80, 84, 86, 91, 91, 97, 98, 103, 105, 110, 111, 112, 115, 114, 115,
+ 118, 59, 56, 56, 54, 54, 54, 53, 53, 57, 58, 64, 64, 69, 70, 75, 78, 80,
+ 85, 87, 91, 92, 98, 99, 103, 106, 110, 112, 113, 116, 119, 120, 119, 65,
+ 62, 61, 59, 59, 59, 58, 58, 62, 63, 68, 68, 73, 75, 79, 82, 85, 90, 92,
+ 97, 98, 105, 106, 111, 114, 118, 120, 121, 124, 123, 123, 126, 66, 63,
+ 63, 60, 60, 60, 59, 59, 63, 64, 69, 69, 74, 76, 80, 83, 86, 91, 93, 98,
+ 99, 106, 107, 112, 115, 119, 121, 122, 125, 128, 129, 126, 71, 68, 67,
+ 65, 65, 64, 63, 63, 67, 68, 73, 73, 78, 80, 84, 87, 90, 95, 97, 103,
+ 103, 111, 112, 117, 120, 125, 127, 128, 131, 132, 132, 135, 74, 71, 70,
+ 68, 67, 67, 66, 65, 69, 70, 75, 75, 80, 82, 86, 89, 93, 97, 100, 105,
+ 106, 114, 115, 120, 123, 128, 130, 131, 135, 135, 138, 136, 80, 76, 75,
+ 72, 72, 71, 70, 69, 73, 74, 79, 79, 84, 86, 90, 93, 96, 101, 104, 110,
+ 110, 118, 119, 125, 128, 134, 136, 137, 140, 142, 140, 144, 81, 77, 77,
+ 74, 73, 73, 71, 71, 74, 75, 80, 80, 85, 87, 91, 94, 98, 103, 105, 111,
+ 112, 120, 121, 127, 130, 136, 137, 139, 142, 145, 148, 144, 83, 78, 78,
+ 75, 74, 74, 72, 72, 75, 76, 81, 81, 86, 88, 92, 95, 99, 104, 106, 112,
+ 113, 121, 122, 128, 131, 137, 139, 140, 144, 148, 150, 155, 86, 82, 81,
+ 78, 77, 77, 75, 74, 78, 79, 84, 84, 89, 91, 95, 98, 101, 106, 109, 115,
+ 116, 124, 125, 131, 135, 140, 142, 144, 147, 149, 153, 155, 89, 84, 84,
+ 80, 80, 79, 78, 77, 79, 81, 85, 86, 91, 92, 97, 98, 104, 106, 112, 114,
+ 119, 123, 128, 132, 135, 142, 145, 148, 149, 153, 154, 159, 91, 86, 86,
+ 82, 82, 81, 80, 79, 80, 84, 85, 88, 91, 94, 97, 100, 104, 107, 112, 115,
+ 120, 123, 129, 132, 138, 140, 148, 150, 153, 154, 159, 159, 93, 88, 88,
+ 84, 84, 83, 83, 80, 81, 86, 86, 91, 91, 96, 97, 103, 103, 110, 110, 118,
+ 119, 126, 126, 135, 136, 144, 144, 155, 155, 159, 159, 164],
+ /* Size 4x8 */
+ [32, 35, 51, 77, 32, 36, 50, 72, 34, 42, 54, 75, 38, 51, 67, 87, 48, 59,
+ 80, 103, 60, 68, 92, 119, 72, 79, 104, 135, 81, 86, 112, 144],
+ /* Size 8x4 */
+ [32, 32, 34, 38, 48, 60, 72, 81, 35, 36, 42, 51, 59, 68, 79, 86, 51, 50,
+ 54, 67, 80, 92, 104, 112, 77, 72, 75, 87, 103, 119, 135, 144],
+ /* Size 8x16 */
+ [32, 31, 33, 40, 51, 65, 79, 87, 31, 32, 33, 39, 49, 61, 74, 82, 31, 32,
+ 34, 38, 47, 59, 71, 79, 32, 33, 36, 40, 48, 58, 69, 77, 33, 34, 38, 44,
+ 52, 62, 72, 78, 36, 35, 42, 51, 58, 68, 78, 84, 39, 38, 44, 54, 63, 73,
+ 84, 89, 44, 41, 46, 59, 69, 79, 90, 96, 48, 45, 50, 62, 74, 85, 96, 103,
+ 53, 49, 53, 66, 79, 92, 103, 111, 58, 54, 57, 70, 84, 98, 110, 118, 66,
+ 60, 63, 75, 90, 106, 119, 126, 74, 67, 69, 81, 97, 113, 128, 134, 81,
+ 73, 75, 86, 102, 120, 135, 143, 86, 78, 78, 90, 106, 124, 140, 147, 91,
+ 82, 80, 90, 103, 119, 137, 151],
+ /* Size 16x8 */
+ [32, 31, 31, 32, 33, 36, 39, 44, 48, 53, 58, 66, 74, 81, 86, 91, 31, 32,
+ 32, 33, 34, 35, 38, 41, 45, 49, 54, 60, 67, 73, 78, 82, 33, 33, 34, 36,
+ 38, 42, 44, 46, 50, 53, 57, 63, 69, 75, 78, 80, 40, 39, 38, 40, 44, 51,
+ 54, 59, 62, 66, 70, 75, 81, 86, 90, 90, 51, 49, 47, 48, 52, 58, 63, 69,
+ 74, 79, 84, 90, 97, 102, 106, 103, 65, 61, 59, 58, 62, 68, 73, 79, 85,
+ 92, 98, 106, 113, 120, 124, 119, 79, 74, 71, 69, 72, 78, 84, 90, 96,
+ 103, 110, 119, 128, 135, 140, 137, 87, 82, 79, 77, 78, 84, 89, 96, 103,
+ 111, 118, 126, 134, 143, 147, 151],
+ /* Size 16x32 */
+ [32, 31, 31, 32, 33, 36, 40, 44, 51, 53, 65, 66, 79, 81, 87, 90, 31, 32,
+ 32, 32, 33, 35, 39, 42, 49, 51, 62, 63, 75, 77, 83, 85, 31, 32, 32, 32,
+ 33, 35, 39, 42, 49, 51, 61, 62, 74, 76, 82, 85, 31, 32, 32, 33, 33, 34,
+ 38, 41, 47, 49, 59, 60, 72, 74, 79, 81, 31, 32, 32, 33, 34, 35, 38, 41,
+ 47, 49, 59, 60, 71, 73, 79, 81, 32, 32, 33, 34, 35, 36, 39, 42, 48, 50,
+ 59, 60, 71, 72, 78, 80, 32, 32, 33, 35, 36, 37, 40, 42, 48, 49, 58, 59,
+ 69, 71, 77, 80, 32, 33, 33, 35, 36, 38, 41, 42, 48, 49, 58, 59, 69, 70,
+ 75, 77, 33, 33, 34, 36, 38, 41, 44, 46, 52, 53, 62, 63, 72, 74, 78, 78,
+ 34, 34, 34, 37, 39, 42, 45, 48, 53, 54, 63, 64, 73, 75, 80, 83, 36, 34,
+ 35, 38, 42, 48, 51, 54, 58, 60, 68, 69, 78, 80, 84, 83, 36, 35, 35, 38,
+ 42, 48, 51, 54, 59, 60, 68, 69, 79, 80, 85, 87, 39, 37, 38, 40, 44, 50,
+ 54, 58, 63, 65, 73, 74, 84, 85, 89, 88, 40, 38, 39, 41, 45, 51, 56, 59,
+ 65, 67, 75, 76, 85, 87, 90, 93, 44, 41, 41, 43, 46, 53, 59, 63, 69, 71,
+ 79, 80, 90, 91, 96, 93, 46, 43, 43, 44, 48, 55, 60, 65, 72, 73, 82, 83,
+ 93, 94, 97, 100, 48, 45, 45, 46, 50, 56, 62, 67, 74, 76, 85, 86, 96, 98,
+ 103, 100, 52, 48, 48, 49, 52, 59, 65, 70, 78, 80, 90, 91, 101, 103, 105,
+ 107, 53, 49, 49, 50, 53, 60, 66, 71, 79, 82, 92, 93, 103, 105, 111, 107,
+ 58, 53, 53, 53, 57, 63, 69, 74, 83, 86, 97, 98, 109, 111, 113, 115, 58,
+ 54, 54, 54, 57, 63, 70, 75, 84, 87, 98, 99, 110, 112, 118, 115, 65, 60,
+ 59, 58, 62, 68, 74, 79, 89, 92, 105, 106, 118, 119, 122, 123, 66, 61,
+ 60, 59, 63, 69, 75, 80, 90, 93, 106, 107, 119, 121, 126, 123, 71, 65,
+ 65, 63, 67, 73, 79, 84, 94, 97, 111, 112, 125, 127, 131, 132, 74, 68,
+ 67, 66, 69, 75, 81, 86, 97, 100, 113, 115, 128, 130, 134, 132, 79, 72,
+ 72, 70, 73, 79, 85, 90, 101, 104, 118, 119, 133, 135, 141, 140, 81, 74,
+ 73, 71, 75, 80, 86, 91, 102, 105, 120, 121, 135, 137, 143, 140, 82, 75,
+ 74, 72, 75, 81, 87, 92, 103, 106, 121, 122, 136, 139, 147, 151, 86, 78,
+ 78, 75, 78, 84, 90, 95, 106, 109, 124, 125, 140, 142, 147, 151, 88, 81,
+ 80, 77, 80, 86, 90, 98, 105, 112, 122, 127, 140, 144, 152, 155, 91, 83,
+ 82, 79, 80, 88, 90, 100, 103, 114, 119, 130, 137, 148, 151, 155, 93, 85,
+ 85, 81, 81, 90, 90, 102, 103, 117, 117, 134, 134, 151, 152, 160],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 31, 32, 32, 32, 33, 34, 36, 36, 39, 40, 44, 46, 48, 52,
+ 53, 58, 58, 65, 66, 71, 74, 79, 81, 82, 86, 88, 91, 93, 31, 32, 32, 32,
+ 32, 32, 32, 33, 33, 34, 34, 35, 37, 38, 41, 43, 45, 48, 49, 53, 54, 60,
+ 61, 65, 68, 72, 74, 75, 78, 81, 83, 85, 31, 32, 32, 32, 32, 33, 33, 33,
+ 34, 34, 35, 35, 38, 39, 41, 43, 45, 48, 49, 53, 54, 59, 60, 65, 67, 72,
+ 73, 74, 78, 80, 82, 85, 32, 32, 32, 33, 33, 34, 35, 35, 36, 37, 38, 38,
+ 40, 41, 43, 44, 46, 49, 50, 53, 54, 58, 59, 63, 66, 70, 71, 72, 75, 77,
+ 79, 81, 33, 33, 33, 33, 34, 35, 36, 36, 38, 39, 42, 42, 44, 45, 46, 48,
+ 50, 52, 53, 57, 57, 62, 63, 67, 69, 73, 75, 75, 78, 80, 80, 81, 36, 35,
+ 35, 34, 35, 36, 37, 38, 41, 42, 48, 48, 50, 51, 53, 55, 56, 59, 60, 63,
+ 63, 68, 69, 73, 75, 79, 80, 81, 84, 86, 88, 90, 40, 39, 39, 38, 38, 39,
+ 40, 41, 44, 45, 51, 51, 54, 56, 59, 60, 62, 65, 66, 69, 70, 74, 75, 79,
+ 81, 85, 86, 87, 90, 90, 90, 90, 44, 42, 42, 41, 41, 42, 42, 42, 46, 48,
+ 54, 54, 58, 59, 63, 65, 67, 70, 71, 74, 75, 79, 80, 84, 86, 90, 91, 92,
+ 95, 98, 100, 102, 51, 49, 49, 47, 47, 48, 48, 48, 52, 53, 58, 59, 63,
+ 65, 69, 72, 74, 78, 79, 83, 84, 89, 90, 94, 97, 101, 102, 103, 106, 105,
+ 103, 103, 53, 51, 51, 49, 49, 50, 49, 49, 53, 54, 60, 60, 65, 67, 71,
+ 73, 76, 80, 82, 86, 87, 92, 93, 97, 100, 104, 105, 106, 109, 112, 114,
+ 117, 65, 62, 61, 59, 59, 59, 58, 58, 62, 63, 68, 68, 73, 75, 79, 82, 85,
+ 90, 92, 97, 98, 105, 106, 111, 113, 118, 120, 121, 124, 122, 119, 117,
+ 66, 63, 62, 60, 60, 60, 59, 59, 63, 64, 69, 69, 74, 76, 80, 83, 86, 91,
+ 93, 98, 99, 106, 107, 112, 115, 119, 121, 122, 125, 127, 130, 134, 79,
+ 75, 74, 72, 71, 71, 69, 69, 72, 73, 78, 79, 84, 85, 90, 93, 96, 101,
+ 103, 109, 110, 118, 119, 125, 128, 133, 135, 136, 140, 140, 137, 134,
+ 81, 77, 76, 74, 73, 72, 71, 70, 74, 75, 80, 80, 85, 87, 91, 94, 98, 103,
+ 105, 111, 112, 119, 121, 127, 130, 135, 137, 139, 142, 144, 148, 151,
+ 87, 83, 82, 79, 79, 78, 77, 75, 78, 80, 84, 85, 89, 90, 96, 97, 103,
+ 105, 111, 113, 118, 122, 126, 131, 134, 141, 143, 147, 147, 152, 151,
+ 152, 90, 85, 85, 81, 81, 80, 80, 77, 78, 83, 83, 87, 88, 93, 93, 100,
+ 100, 107, 107, 115, 115, 123, 123, 132, 132, 140, 140, 151, 151, 155,
+ 155, 160],
+ /* Size 4x16 */
+ [31, 36, 53, 81, 32, 35, 51, 76, 32, 35, 49, 73, 32, 37, 49, 71, 33, 41,
+ 53, 74, 34, 48, 60, 80, 37, 50, 65, 85, 41, 53, 71, 91, 45, 56, 76, 98,
+ 49, 60, 82, 105, 54, 63, 87, 112, 61, 69, 93, 121, 68, 75, 100, 130, 74,
+ 80, 105, 137, 78, 84, 109, 142, 83, 88, 114, 148],
+ /* Size 16x4 */
+ [31, 32, 32, 32, 33, 34, 37, 41, 45, 49, 54, 61, 68, 74, 78, 83, 36, 35,
+ 35, 37, 41, 48, 50, 53, 56, 60, 63, 69, 75, 80, 84, 88, 53, 51, 49, 49,
+ 53, 60, 65, 71, 76, 82, 87, 93, 100, 105, 109, 114, 81, 76, 73, 71, 74,
+ 80, 85, 91, 98, 105, 112, 121, 130, 137, 142, 148],
+ /* Size 8x32 */
+ [32, 31, 33, 40, 51, 65, 79, 87, 31, 32, 33, 39, 49, 62, 75, 83, 31, 32,
+ 33, 39, 49, 61, 74, 82, 31, 32, 33, 38, 47, 59, 72, 79, 31, 32, 34, 38,
+ 47, 59, 71, 79, 32, 33, 35, 39, 48, 59, 71, 78, 32, 33, 36, 40, 48, 58,
+ 69, 77, 32, 33, 36, 41, 48, 58, 69, 75, 33, 34, 38, 44, 52, 62, 72, 78,
+ 34, 34, 39, 45, 53, 63, 73, 80, 36, 35, 42, 51, 58, 68, 78, 84, 36, 35,
+ 42, 51, 59, 68, 79, 85, 39, 38, 44, 54, 63, 73, 84, 89, 40, 39, 45, 56,
+ 65, 75, 85, 90, 44, 41, 46, 59, 69, 79, 90, 96, 46, 43, 48, 60, 72, 82,
+ 93, 97, 48, 45, 50, 62, 74, 85, 96, 103, 52, 48, 52, 65, 78, 90, 101,
+ 105, 53, 49, 53, 66, 79, 92, 103, 111, 58, 53, 57, 69, 83, 97, 109, 113,
+ 58, 54, 57, 70, 84, 98, 110, 118, 65, 59, 62, 74, 89, 105, 118, 122, 66,
+ 60, 63, 75, 90, 106, 119, 126, 71, 65, 67, 79, 94, 111, 125, 131, 74,
+ 67, 69, 81, 97, 113, 128, 134, 79, 72, 73, 85, 101, 118, 133, 141, 81,
+ 73, 75, 86, 102, 120, 135, 143, 82, 74, 75, 87, 103, 121, 136, 147, 86,
+ 78, 78, 90, 106, 124, 140, 147, 88, 80, 80, 90, 105, 122, 140, 152, 91,
+ 82, 80, 90, 103, 119, 137, 151, 93, 85, 81, 90, 103, 117, 134, 152],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 31, 32, 32, 32, 33, 34, 36, 36, 39, 40, 44, 46, 48, 52,
+ 53, 58, 58, 65, 66, 71, 74, 79, 81, 82, 86, 88, 91, 93, 31, 32, 32, 32,
+ 32, 33, 33, 33, 34, 34, 35, 35, 38, 39, 41, 43, 45, 48, 49, 53, 54, 59,
+ 60, 65, 67, 72, 73, 74, 78, 80, 82, 85, 33, 33, 33, 33, 34, 35, 36, 36,
+ 38, 39, 42, 42, 44, 45, 46, 48, 50, 52, 53, 57, 57, 62, 63, 67, 69, 73,
+ 75, 75, 78, 80, 80, 81, 40, 39, 39, 38, 38, 39, 40, 41, 44, 45, 51, 51,
+ 54, 56, 59, 60, 62, 65, 66, 69, 70, 74, 75, 79, 81, 85, 86, 87, 90, 90,
+ 90, 90, 51, 49, 49, 47, 47, 48, 48, 48, 52, 53, 58, 59, 63, 65, 69, 72,
+ 74, 78, 79, 83, 84, 89, 90, 94, 97, 101, 102, 103, 106, 105, 103, 103,
+ 65, 62, 61, 59, 59, 59, 58, 58, 62, 63, 68, 68, 73, 75, 79, 82, 85, 90,
+ 92, 97, 98, 105, 106, 111, 113, 118, 120, 121, 124, 122, 119, 117, 79,
+ 75, 74, 72, 71, 71, 69, 69, 72, 73, 78, 79, 84, 85, 90, 93, 96, 101,
+ 103, 109, 110, 118, 119, 125, 128, 133, 135, 136, 140, 140, 137, 134,
+ 87, 83, 82, 79, 79, 78, 77, 75, 78, 80, 84, 85, 89, 90, 96, 97, 103,
+ 105, 111, 113, 118, 122, 126, 131, 134, 141, 143, 147, 147, 152, 151,
+ 152]
+ ],
+ [ /* Chroma */
+ /* Size 4x4 */
+ [32, 46, 49, 58, 46, 53, 55, 62, 49, 55, 70, 78, 58, 62, 78, 91],
+ /* Size 8x8 */
+ [31, 34, 42, 47, 49, 54, 60, 64, 34, 39, 45, 46, 47, 51, 56, 59, 42, 45,
+ 48, 49, 50, 53, 57, 60, 47, 46, 49, 55, 58, 61, 65, 66, 49, 47, 50, 58,
+ 65, 69, 73, 74, 54, 51, 53, 61, 69, 76, 82, 83, 60, 56, 57, 65, 73, 82,
+ 89, 92, 64, 59, 60, 66, 74, 83, 92, 96],
+ /* Size 16x16 */
+ [32, 31, 31, 35, 40, 49, 48, 49, 50, 52, 54, 57, 61, 64, 66, 68, 31, 31,
+ 32, 37, 41, 47, 47, 46, 48, 49, 51, 54, 57, 60, 62, 64, 31, 32, 34, 39,
+ 43, 46, 46, 45, 46, 47, 49, 52, 55, 57, 59, 61, 35, 37, 39, 44, 46, 47,
+ 46, 45, 46, 47, 48, 51, 53, 56, 57, 59, 40, 41, 43, 46, 48, 50, 49, 48,
+ 49, 49, 51, 53, 55, 57, 59, 59, 49, 47, 46, 47, 50, 53, 53, 53, 54, 54,
+ 55, 57, 59, 61, 62, 62, 48, 47, 46, 46, 49, 53, 54, 55, 56, 57, 58, 60,
+ 62, 64, 65, 65, 49, 46, 45, 45, 48, 53, 55, 58, 60, 61, 62, 64, 66, 68,
+ 69, 69, 50, 48, 46, 46, 49, 54, 56, 60, 61, 63, 65, 67, 69, 71, 72, 72,
+ 52, 49, 47, 47, 49, 54, 57, 61, 63, 66, 68, 71, 73, 75, 76, 77, 54, 51,
+ 49, 48, 51, 55, 58, 62, 65, 68, 71, 74, 76, 78, 80, 81, 57, 54, 52, 51,
+ 53, 57, 60, 64, 67, 71, 74, 77, 80, 83, 84, 85, 61, 57, 55, 53, 55, 59,
+ 62, 66, 69, 73, 76, 80, 84, 87, 89, 89, 64, 60, 57, 56, 57, 61, 64, 68,
+ 71, 75, 78, 83, 87, 90, 92, 94, 66, 62, 59, 57, 59, 62, 65, 69, 72, 76,
+ 80, 84, 89, 92, 94, 96, 68, 64, 61, 59, 59, 62, 65, 69, 72, 77, 81, 85,
+ 89, 94, 96, 98],
+ /* Size 32x32 */
+ [32, 31, 31, 30, 31, 33, 35, 36, 40, 41, 49, 49, 48, 48, 49, 50, 50, 52,
+ 52, 54, 54, 57, 57, 60, 61, 63, 64, 65, 66, 67, 68, 69, 31, 31, 31, 31,
+ 32, 34, 37, 38, 41, 42, 47, 47, 47, 47, 47, 47, 48, 49, 50, 52, 52, 54,
+ 55, 57, 58, 60, 61, 61, 63, 64, 64, 65, 31, 31, 31, 31, 32, 35, 37, 39,
+ 41, 42, 47, 47, 47, 46, 46, 47, 48, 49, 49, 51, 51, 54, 54, 56, 57, 59,
+ 60, 61, 62, 63, 64, 65, 30, 31, 31, 32, 33, 35, 38, 40, 42, 42, 46, 46,
+ 45, 45, 45, 45, 46, 47, 47, 49, 49, 52, 52, 54, 55, 57, 58, 58, 60, 61,
+ 61, 62, 31, 32, 32, 33, 34, 37, 39, 41, 43, 43, 46, 46, 46, 45, 45, 46,
+ 46, 47, 47, 49, 49, 51, 52, 54, 55, 57, 57, 58, 59, 60, 61, 62, 33, 34,
+ 35, 35, 37, 39, 41, 43, 44, 45, 47, 47, 46, 46, 45, 46, 46, 47, 47, 49,
+ 49, 51, 51, 53, 54, 56, 57, 57, 58, 59, 60, 61, 35, 37, 37, 38, 39, 41,
+ 44, 46, 46, 46, 47, 47, 46, 46, 45, 46, 46, 47, 47, 48, 48, 50, 51, 52,
+ 53, 55, 56, 56, 57, 58, 59, 61, 36, 38, 39, 40, 41, 43, 46, 47, 47, 47,
+ 48, 47, 46, 46, 45, 46, 46, 46, 47, 48, 48, 50, 50, 52, 53, 54, 55, 55,
+ 56, 57, 58, 58, 40, 41, 41, 42, 43, 44, 46, 47, 48, 48, 50, 49, 49, 49,
+ 48, 49, 49, 49, 49, 51, 51, 52, 53, 54, 55, 57, 57, 58, 59, 59, 59, 59,
+ 41, 42, 42, 42, 43, 45, 46, 47, 48, 48, 50, 50, 49, 49, 49, 49, 50, 50,
+ 50, 52, 52, 53, 53, 55, 56, 57, 58, 58, 59, 60, 61, 62, 49, 47, 47, 46,
+ 46, 47, 47, 48, 50, 50, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 56,
+ 57, 58, 59, 60, 61, 61, 62, 62, 62, 62, 49, 47, 47, 46, 46, 47, 47, 47,
+ 49, 50, 53, 53, 53, 53, 54, 54, 54, 54, 54, 55, 56, 57, 57, 59, 59, 61,
+ 61, 62, 63, 63, 64, 65, 48, 47, 47, 45, 46, 46, 46, 46, 49, 49, 53, 53,
+ 54, 54, 55, 56, 56, 57, 57, 58, 58, 60, 60, 61, 62, 63, 64, 64, 65, 66,
+ 65, 65, 48, 47, 46, 45, 45, 46, 46, 46, 49, 49, 53, 53, 54, 55, 56, 57,
+ 57, 58, 58, 59, 60, 61, 61, 63, 63, 65, 65, 65, 66, 66, 67, 68, 49, 47,
+ 46, 45, 45, 45, 45, 45, 48, 49, 53, 54, 55, 56, 58, 59, 60, 61, 61, 62,
+ 62, 63, 64, 65, 66, 67, 68, 68, 69, 70, 69, 68, 50, 47, 47, 45, 46, 46,
+ 46, 46, 49, 49, 54, 54, 56, 57, 59, 60, 60, 62, 62, 63, 64, 65, 65, 67,
+ 68, 69, 69, 70, 70, 70, 71, 71, 50, 48, 48, 46, 46, 46, 46, 46, 49, 50,
+ 54, 54, 56, 57, 60, 60, 61, 63, 63, 65, 65, 67, 67, 68, 69, 71, 71, 71,
+ 72, 73, 72, 71, 52, 49, 49, 47, 47, 47, 47, 46, 49, 50, 54, 54, 57, 58,
+ 61, 62, 63, 65, 65, 67, 67, 69, 70, 71, 72, 73, 74, 74, 75, 74, 74, 75,
+ 52, 50, 49, 47, 47, 47, 47, 47, 49, 50, 54, 54, 57, 58, 61, 62, 63, 65,
+ 66, 68, 68, 70, 71, 72, 73, 75, 75, 75, 76, 77, 77, 75, 54, 52, 51, 49,
+ 49, 49, 48, 48, 51, 52, 55, 55, 58, 59, 62, 63, 65, 67, 68, 70, 70, 73,
+ 73, 75, 76, 78, 78, 78, 79, 78, 78, 79, 54, 52, 51, 49, 49, 49, 48, 48,
+ 51, 52, 55, 56, 58, 60, 62, 64, 65, 67, 68, 70, 71, 73, 74, 75, 76, 78,
+ 78, 79, 80, 81, 81, 79, 57, 54, 54, 52, 51, 51, 50, 50, 52, 53, 56, 57,
+ 60, 61, 63, 65, 67, 69, 70, 73, 73, 76, 77, 79, 80, 82, 82, 83, 84, 83,
+ 82, 83, 57, 55, 54, 52, 52, 51, 51, 50, 53, 53, 57, 57, 60, 61, 64, 65,
+ 67, 70, 71, 73, 74, 77, 77, 79, 80, 82, 83, 83, 84, 85, 85, 83, 60, 57,
+ 56, 54, 54, 53, 52, 52, 54, 55, 58, 59, 61, 63, 65, 67, 68, 71, 72, 75,
+ 75, 79, 79, 82, 83, 85, 86, 86, 87, 87, 86, 87, 61, 58, 57, 55, 55, 54,
+ 53, 53, 55, 56, 59, 59, 62, 63, 66, 68, 69, 72, 73, 76, 76, 80, 80, 83,
+ 84, 86, 87, 88, 89, 89, 89, 87, 63, 60, 59, 57, 57, 56, 55, 54, 57, 57,
+ 60, 61, 63, 65, 67, 69, 71, 73, 75, 78, 78, 82, 82, 85, 86, 89, 89, 90,
+ 91, 92, 90, 91, 64, 61, 60, 58, 57, 57, 56, 55, 57, 58, 61, 61, 64, 65,
+ 68, 69, 71, 74, 75, 78, 78, 82, 83, 86, 87, 89, 90, 91, 92, 93, 94, 91,
+ 65, 61, 61, 58, 58, 57, 56, 55, 58, 58, 61, 62, 64, 65, 68, 70, 71, 74,
+ 75, 78, 79, 83, 83, 86, 88, 90, 91, 91, 93, 94, 94, 96, 66, 63, 62, 60,
+ 59, 58, 57, 56, 59, 59, 62, 63, 65, 66, 69, 70, 72, 75, 76, 79, 80, 84,
+ 84, 87, 89, 91, 92, 93, 94, 94, 96, 96, 67, 64, 63, 61, 60, 59, 58, 57,
+ 59, 60, 62, 63, 66, 66, 70, 70, 73, 74, 77, 78, 81, 83, 85, 87, 89, 92,
+ 93, 94, 94, 96, 96, 97, 68, 64, 64, 61, 61, 60, 59, 58, 59, 61, 62, 64,
+ 65, 67, 69, 71, 72, 74, 77, 78, 81, 82, 85, 86, 89, 90, 94, 94, 96, 96,
+ 98, 97, 69, 65, 65, 62, 62, 61, 61, 58, 59, 62, 62, 65, 65, 68, 68, 71,
+ 71, 75, 75, 79, 79, 83, 83, 87, 87, 91, 91, 96, 96, 97, 97, 99],
+ /* Size 4x8 */
+ [31, 47, 50, 61, 36, 47, 47, 57, 43, 50, 50, 58, 45, 53, 58, 65, 47, 54,
+ 66, 74, 52, 56, 70, 82, 57, 60, 75, 90, 61, 63, 77, 93],
+ /* Size 8x4 */
+ [31, 36, 43, 45, 47, 52, 57, 61, 47, 47, 50, 53, 54, 56, 60, 63, 50, 47,
+ 50, 58, 66, 70, 75, 77, 61, 57, 58, 65, 74, 82, 90, 93],
+ /* Size 8x16 */
+ [32, 32, 40, 49, 51, 57, 63, 67, 31, 33, 41, 47, 49, 54, 59, 63, 31, 35,
+ 43, 46, 47, 51, 57, 60, 35, 39, 46, 46, 47, 50, 55, 58, 41, 43, 48, 49,
+ 49, 52, 57, 59, 49, 47, 50, 53, 54, 57, 60, 62, 48, 46, 49, 54, 57, 60,
+ 64, 65, 49, 45, 48, 56, 61, 64, 67, 69, 50, 46, 49, 57, 63, 67, 71, 73,
+ 52, 48, 50, 58, 65, 71, 75, 77, 54, 50, 51, 59, 67, 73, 78, 81, 57, 52,
+ 53, 61, 69, 77, 82, 85, 61, 55, 56, 63, 72, 80, 86, 88, 64, 58, 58, 65,
+ 73, 82, 89, 92, 66, 59, 59, 66, 75, 84, 91, 94, 68, 61, 59, 65, 72, 81,
+ 89, 95],
+ /* Size 16x8 */
+ [32, 31, 31, 35, 41, 49, 48, 49, 50, 52, 54, 57, 61, 64, 66, 68, 32, 33,
+ 35, 39, 43, 47, 46, 45, 46, 48, 50, 52, 55, 58, 59, 61, 40, 41, 43, 46,
+ 48, 50, 49, 48, 49, 50, 51, 53, 56, 58, 59, 59, 49, 47, 46, 46, 49, 53,
+ 54, 56, 57, 58, 59, 61, 63, 65, 66, 65, 51, 49, 47, 47, 49, 54, 57, 61,
+ 63, 65, 67, 69, 72, 73, 75, 72, 57, 54, 51, 50, 52, 57, 60, 64, 67, 71,
+ 73, 77, 80, 82, 84, 81, 63, 59, 57, 55, 57, 60, 64, 67, 71, 75, 78, 82,
+ 86, 89, 91, 89, 67, 63, 60, 58, 59, 62, 65, 69, 73, 77, 81, 85, 88, 92,
+ 94, 95],
+ /* Size 16x32 */
+ [32, 31, 32, 37, 40, 48, 49, 49, 51, 52, 57, 58, 63, 64, 67, 67, 31, 31,
+ 33, 38, 41, 47, 47, 47, 49, 50, 54, 55, 60, 61, 63, 64, 31, 31, 33, 38,
+ 41, 47, 47, 47, 49, 49, 54, 54, 59, 60, 63, 64, 30, 32, 33, 40, 42, 46,
+ 45, 45, 47, 48, 52, 52, 57, 58, 60, 61, 31, 33, 35, 41, 43, 46, 46, 45,
+ 47, 48, 51, 52, 57, 57, 60, 61, 33, 36, 37, 43, 44, 47, 46, 46, 47, 47,
+ 51, 52, 56, 57, 59, 60, 35, 38, 39, 45, 46, 47, 46, 45, 47, 47, 50, 51,
+ 55, 56, 58, 60, 37, 40, 41, 47, 47, 47, 46, 45, 46, 47, 50, 50, 54, 55,
+ 57, 58, 41, 42, 43, 47, 48, 49, 49, 48, 49, 50, 52, 53, 57, 57, 59, 58,
+ 42, 43, 43, 47, 48, 50, 49, 49, 50, 50, 53, 54, 57, 58, 60, 61, 49, 46,
+ 47, 48, 50, 53, 53, 53, 54, 54, 57, 57, 60, 61, 62, 61, 49, 46, 47, 48,
+ 50, 53, 53, 54, 54, 55, 57, 57, 61, 61, 63, 64, 48, 46, 46, 47, 49, 53,
+ 54, 56, 57, 57, 60, 60, 64, 64, 65, 64, 48, 45, 46, 46, 49, 53, 55, 56,
+ 58, 58, 61, 61, 65, 65, 66, 67, 49, 45, 45, 46, 48, 53, 56, 58, 61, 61,
+ 64, 64, 67, 68, 69, 67, 49, 46, 46, 46, 49, 53, 57, 59, 62, 62, 65, 66,
+ 69, 69, 70, 70, 50, 46, 46, 46, 49, 54, 57, 59, 63, 64, 67, 67, 71, 71,
+ 73, 71, 51, 47, 47, 47, 49, 54, 58, 61, 64, 66, 69, 70, 73, 74, 74, 74,
+ 52, 48, 48, 47, 50, 54, 58, 61, 65, 66, 71, 71, 75, 75, 77, 74, 54, 50,
+ 49, 48, 51, 55, 59, 62, 67, 68, 73, 73, 77, 78, 78, 78, 54, 50, 50, 49,
+ 51, 55, 59, 62, 67, 68, 73, 74, 78, 78, 81, 78, 57, 52, 52, 50, 52, 56,
+ 60, 64, 69, 70, 76, 77, 82, 82, 83, 82, 57, 52, 52, 51, 53, 57, 61, 64,
+ 69, 71, 77, 77, 82, 83, 85, 82, 60, 54, 54, 52, 55, 58, 62, 65, 71, 72,
+ 79, 79, 85, 86, 87, 86, 61, 56, 55, 53, 56, 59, 63, 66, 72, 73, 80, 81,
+ 86, 87, 88, 86, 63, 57, 57, 55, 57, 60, 64, 67, 73, 75, 82, 82, 89, 90,
+ 92, 90, 64, 58, 58, 55, 58, 61, 65, 68, 73, 75, 82, 83, 89, 90, 92, 90,
+ 64, 59, 58, 56, 58, 61, 65, 68, 74, 75, 83, 83, 90, 91, 94, 95, 66, 60,
+ 59, 57, 59, 62, 66, 69, 75, 76, 84, 85, 91, 92, 94, 95, 67, 61, 60, 58,
+ 59, 63, 66, 70, 74, 77, 82, 85, 91, 93, 96, 96, 68, 62, 61, 58, 59, 64,
+ 65, 71, 72, 78, 81, 86, 89, 94, 95, 96, 68, 62, 62, 59, 59, 65, 65, 71,
+ 71, 79, 79, 87, 87, 95, 95, 98],
+ /* Size 32x16 */
+ [32, 31, 31, 30, 31, 33, 35, 37, 41, 42, 49, 49, 48, 48, 49, 49, 50, 51,
+ 52, 54, 54, 57, 57, 60, 61, 63, 64, 64, 66, 67, 68, 68, 31, 31, 31, 32,
+ 33, 36, 38, 40, 42, 43, 46, 46, 46, 45, 45, 46, 46, 47, 48, 50, 50, 52,
+ 52, 54, 56, 57, 58, 59, 60, 61, 62, 62, 32, 33, 33, 33, 35, 37, 39, 41,
+ 43, 43, 47, 47, 46, 46, 45, 46, 46, 47, 48, 49, 50, 52, 52, 54, 55, 57,
+ 58, 58, 59, 60, 61, 62, 37, 38, 38, 40, 41, 43, 45, 47, 47, 47, 48, 48,
+ 47, 46, 46, 46, 46, 47, 47, 48, 49, 50, 51, 52, 53, 55, 55, 56, 57, 58,
+ 58, 59, 40, 41, 41, 42, 43, 44, 46, 47, 48, 48, 50, 50, 49, 49, 48, 49,
+ 49, 49, 50, 51, 51, 52, 53, 55, 56, 57, 58, 58, 59, 59, 59, 59, 48, 47,
+ 47, 46, 46, 47, 47, 47, 49, 50, 53, 53, 53, 53, 53, 53, 54, 54, 54, 55,
+ 55, 56, 57, 58, 59, 60, 61, 61, 62, 63, 64, 65, 49, 47, 47, 45, 46, 46,
+ 46, 46, 49, 49, 53, 53, 54, 55, 56, 57, 57, 58, 58, 59, 59, 60, 61, 62,
+ 63, 64, 65, 65, 66, 66, 65, 65, 49, 47, 47, 45, 45, 46, 45, 45, 48, 49,
+ 53, 54, 56, 56, 58, 59, 59, 61, 61, 62, 62, 64, 64, 65, 66, 67, 68, 68,
+ 69, 70, 71, 71, 51, 49, 49, 47, 47, 47, 47, 46, 49, 50, 54, 54, 57, 58,
+ 61, 62, 63, 64, 65, 67, 67, 69, 69, 71, 72, 73, 73, 74, 75, 74, 72, 71,
+ 52, 50, 49, 48, 48, 47, 47, 47, 50, 50, 54, 55, 57, 58, 61, 62, 64, 66,
+ 66, 68, 68, 70, 71, 72, 73, 75, 75, 75, 76, 77, 78, 79, 57, 54, 54, 52,
+ 51, 51, 50, 50, 52, 53, 57, 57, 60, 61, 64, 65, 67, 69, 71, 73, 73, 76,
+ 77, 79, 80, 82, 82, 83, 84, 82, 81, 79, 58, 55, 54, 52, 52, 52, 51, 50,
+ 53, 54, 57, 57, 60, 61, 64, 66, 67, 70, 71, 73, 74, 77, 77, 79, 81, 82,
+ 83, 83, 85, 85, 86, 87, 63, 60, 59, 57, 57, 56, 55, 54, 57, 57, 60, 61,
+ 64, 65, 67, 69, 71, 73, 75, 77, 78, 82, 82, 85, 86, 89, 89, 90, 91, 91,
+ 89, 87, 64, 61, 60, 58, 57, 57, 56, 55, 57, 58, 61, 61, 64, 65, 68, 69,
+ 71, 74, 75, 78, 78, 82, 83, 86, 87, 90, 90, 91, 92, 93, 94, 95, 67, 63,
+ 63, 60, 60, 59, 58, 57, 59, 60, 62, 63, 65, 66, 69, 70, 73, 74, 77, 78,
+ 81, 83, 85, 87, 88, 92, 92, 94, 94, 96, 95, 95, 67, 64, 64, 61, 61, 60,
+ 60, 58, 58, 61, 61, 64, 64, 67, 67, 70, 71, 74, 74, 78, 78, 82, 82, 86,
+ 86, 90, 90, 95, 95, 96, 96, 98],
+ /* Size 4x16 */
+ [31, 48, 52, 64, 31, 47, 49, 60, 33, 46, 48, 57, 38, 47, 47, 56, 42, 49,
+ 50, 57, 46, 53, 54, 61, 46, 53, 57, 64, 45, 53, 61, 68, 46, 54, 64, 71,
+ 48, 54, 66, 75, 50, 55, 68, 78, 52, 57, 71, 83, 56, 59, 73, 87, 58, 61,
+ 75, 90, 60, 62, 76, 92, 62, 64, 78, 94],
+ /* Size 16x4 */
+ [31, 31, 33, 38, 42, 46, 46, 45, 46, 48, 50, 52, 56, 58, 60, 62, 48, 47,
+ 46, 47, 49, 53, 53, 53, 54, 54, 55, 57, 59, 61, 62, 64, 52, 49, 48, 47,
+ 50, 54, 57, 61, 64, 66, 68, 71, 73, 75, 76, 78, 64, 60, 57, 56, 57, 61,
+ 64, 68, 71, 75, 78, 83, 87, 90, 92, 94],
+ /* Size 8x32 */
+ [32, 32, 40, 49, 51, 57, 63, 67, 31, 33, 41, 47, 49, 54, 60, 63, 31, 33,
+ 41, 47, 49, 54, 59, 63, 30, 33, 42, 45, 47, 52, 57, 60, 31, 35, 43, 46,
+ 47, 51, 57, 60, 33, 37, 44, 46, 47, 51, 56, 59, 35, 39, 46, 46, 47, 50,
+ 55, 58, 37, 41, 47, 46, 46, 50, 54, 57, 41, 43, 48, 49, 49, 52, 57, 59,
+ 42, 43, 48, 49, 50, 53, 57, 60, 49, 47, 50, 53, 54, 57, 60, 62, 49, 47,
+ 50, 53, 54, 57, 61, 63, 48, 46, 49, 54, 57, 60, 64, 65, 48, 46, 49, 55,
+ 58, 61, 65, 66, 49, 45, 48, 56, 61, 64, 67, 69, 49, 46, 49, 57, 62, 65,
+ 69, 70, 50, 46, 49, 57, 63, 67, 71, 73, 51, 47, 49, 58, 64, 69, 73, 74,
+ 52, 48, 50, 58, 65, 71, 75, 77, 54, 49, 51, 59, 67, 73, 77, 78, 54, 50,
+ 51, 59, 67, 73, 78, 81, 57, 52, 52, 60, 69, 76, 82, 83, 57, 52, 53, 61,
+ 69, 77, 82, 85, 60, 54, 55, 62, 71, 79, 85, 87, 61, 55, 56, 63, 72, 80,
+ 86, 88, 63, 57, 57, 64, 73, 82, 89, 92, 64, 58, 58, 65, 73, 82, 89, 92,
+ 64, 58, 58, 65, 74, 83, 90, 94, 66, 59, 59, 66, 75, 84, 91, 94, 67, 60,
+ 59, 66, 74, 82, 91, 96, 68, 61, 59, 65, 72, 81, 89, 95, 68, 62, 59, 65,
+ 71, 79, 87, 95],
+ /* Size 32x8 */
+ [32, 31, 31, 30, 31, 33, 35, 37, 41, 42, 49, 49, 48, 48, 49, 49, 50, 51,
+ 52, 54, 54, 57, 57, 60, 61, 63, 64, 64, 66, 67, 68, 68, 32, 33, 33, 33,
+ 35, 37, 39, 41, 43, 43, 47, 47, 46, 46, 45, 46, 46, 47, 48, 49, 50, 52,
+ 52, 54, 55, 57, 58, 58, 59, 60, 61, 62, 40, 41, 41, 42, 43, 44, 46, 47,
+ 48, 48, 50, 50, 49, 49, 48, 49, 49, 49, 50, 51, 51, 52, 53, 55, 56, 57,
+ 58, 58, 59, 59, 59, 59, 49, 47, 47, 45, 46, 46, 46, 46, 49, 49, 53, 53,
+ 54, 55, 56, 57, 57, 58, 58, 59, 59, 60, 61, 62, 63, 64, 65, 65, 66, 66,
+ 65, 65, 51, 49, 49, 47, 47, 47, 47, 46, 49, 50, 54, 54, 57, 58, 61, 62,
+ 63, 64, 65, 67, 67, 69, 69, 71, 72, 73, 73, 74, 75, 74, 72, 71, 57, 54,
+ 54, 52, 51, 51, 50, 50, 52, 53, 57, 57, 60, 61, 64, 65, 67, 69, 71, 73,
+ 73, 76, 77, 79, 80, 82, 82, 83, 84, 82, 81, 79, 63, 60, 59, 57, 57, 56,
+ 55, 54, 57, 57, 60, 61, 64, 65, 67, 69, 71, 73, 75, 77, 78, 82, 82, 85,
+ 86, 89, 89, 90, 91, 91, 89, 87, 67, 63, 63, 60, 60, 59, 58, 57, 59, 60,
+ 62, 63, 65, 66, 69, 70, 73, 74, 77, 78, 81, 83, 85, 87, 88, 92, 92, 94,
+ 94, 96, 95, 95]]
+ ],
+ [
+ [ /* Luma */
+ /* Size 4x4 */
+ [32, 34, 49, 72, 34, 48, 60, 79, 49, 60, 82, 104, 72, 79, 104, 134],
+ /* Size 8x8 */
+ [32, 32, 34, 38, 46, 56, 68, 78, 32, 33, 35, 39, 45, 54, 64, 74, 34, 35,
+ 39, 45, 51, 58, 68, 76, 38, 39, 45, 54, 61, 69, 78, 86, 46, 45, 51, 61,
+ 71, 80, 90, 99, 56, 54, 58, 69, 80, 92, 103, 113, 68, 64, 68, 78, 90,
+ 103, 117, 128, 78, 74, 76, 86, 99, 113, 128, 140],
+ /* Size 16x16 */
+ [32, 31, 31, 31, 32, 34, 36, 39, 44, 48, 54, 59, 65, 71, 80, 83, 31, 32,
+ 32, 32, 32, 34, 35, 38, 42, 46, 51, 56, 62, 68, 76, 78, 31, 32, 32, 32,
+ 32, 33, 34, 37, 41, 44, 49, 54, 59, 65, 72, 75, 31, 32, 32, 33, 34, 35,
+ 36, 39, 42, 45, 50, 54, 59, 64, 71, 74, 32, 32, 32, 34, 35, 37, 38, 40,
+ 42, 46, 49, 53, 58, 63, 69, 72, 34, 34, 33, 35, 37, 39, 42, 45, 47, 51,
+ 54, 58, 63, 68, 74, 76, 36, 35, 34, 36, 38, 42, 48, 50, 54, 57, 60, 64,
+ 68, 73, 79, 81, 39, 38, 37, 39, 40, 45, 50, 54, 58, 61, 65, 69, 73, 78,
+ 84, 86, 44, 42, 41, 42, 42, 47, 54, 58, 63, 67, 71, 75, 79, 84, 90, 92,
+ 48, 46, 44, 45, 46, 51, 57, 61, 67, 71, 76, 80, 85, 90, 96, 99, 54, 51,
+ 49, 50, 49, 54, 60, 65, 71, 76, 82, 87, 92, 97, 104, 106, 59, 56, 54,
+ 54, 53, 58, 64, 69, 75, 80, 87, 92, 98, 103, 110, 113, 65, 62, 59, 59,
+ 58, 63, 68, 73, 79, 85, 92, 98, 105, 111, 118, 121, 71, 68, 65, 64, 63,
+ 68, 73, 78, 84, 90, 97, 103, 111, 117, 125, 128, 80, 76, 72, 71, 69, 74,
+ 79, 84, 90, 96, 104, 110, 118, 125, 134, 137, 83, 78, 75, 74, 72, 76,
+ 81, 86, 92, 99, 106, 113, 121, 128, 137, 140],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 31, 31, 32, 32, 34, 34, 36, 36, 39, 39, 44, 44, 48,
+ 48, 54, 54, 59, 59, 65, 65, 71, 71, 80, 80, 83, 83, 87, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 34, 34, 35, 35, 38, 38, 42, 42, 46, 46, 51, 51, 56,
+ 56, 62, 62, 68, 68, 76, 76, 78, 78, 83, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 34, 34, 35, 35, 38, 38, 42, 42, 46, 46, 51, 51, 56, 56, 62, 62, 68,
+ 68, 76, 76, 78, 78, 83, 31, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34,
+ 34, 37, 37, 41, 41, 44, 44, 49, 49, 54, 54, 59, 59, 65, 65, 72, 72, 75,
+ 75, 79, 31, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 37, 37, 41,
+ 41, 44, 44, 49, 49, 54, 54, 59, 59, 65, 65, 72, 72, 75, 75, 79, 31, 32,
+ 32, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 39, 39, 42, 42, 45, 45, 50,
+ 50, 54, 54, 59, 59, 64, 64, 71, 71, 74, 74, 77, 31, 32, 32, 32, 32, 33,
+ 33, 34, 34, 35, 35, 36, 36, 39, 39, 42, 42, 45, 45, 50, 50, 54, 54, 59,
+ 59, 64, 64, 71, 71, 74, 74, 77, 32, 32, 32, 32, 32, 34, 34, 35, 35, 37,
+ 37, 38, 38, 40, 40, 42, 42, 46, 46, 49, 49, 53, 53, 58, 58, 63, 63, 69,
+ 69, 72, 72, 75, 32, 32, 32, 32, 32, 34, 34, 35, 35, 37, 37, 38, 38, 40,
+ 40, 42, 42, 46, 46, 49, 49, 53, 53, 58, 58, 63, 63, 69, 69, 72, 72, 75,
+ 34, 34, 34, 33, 33, 35, 35, 37, 37, 39, 39, 42, 42, 45, 45, 47, 47, 51,
+ 51, 54, 54, 58, 58, 63, 63, 68, 68, 74, 74, 76, 76, 80, 34, 34, 34, 33,
+ 33, 35, 35, 37, 37, 39, 39, 42, 42, 45, 45, 47, 47, 51, 51, 54, 54, 58,
+ 58, 63, 63, 68, 68, 74, 74, 76, 76, 80, 36, 35, 35, 34, 34, 36, 36, 38,
+ 38, 42, 42, 48, 48, 50, 50, 54, 54, 57, 57, 60, 60, 64, 64, 68, 68, 73,
+ 73, 79, 79, 81, 81, 84, 36, 35, 35, 34, 34, 36, 36, 38, 38, 42, 42, 48,
+ 48, 50, 50, 54, 54, 57, 57, 60, 60, 64, 64, 68, 68, 73, 73, 79, 79, 81,
+ 81, 84, 39, 38, 38, 37, 37, 39, 39, 40, 40, 45, 45, 50, 50, 54, 54, 58,
+ 58, 61, 61, 65, 65, 69, 69, 73, 73, 78, 78, 84, 84, 86, 86, 90, 39, 38,
+ 38, 37, 37, 39, 39, 40, 40, 45, 45, 50, 50, 54, 54, 58, 58, 61, 61, 65,
+ 65, 69, 69, 73, 73, 78, 78, 84, 84, 86, 86, 90, 44, 42, 42, 41, 41, 42,
+ 42, 42, 42, 47, 47, 54, 54, 58, 58, 63, 63, 67, 67, 71, 71, 75, 75, 79,
+ 79, 84, 84, 90, 90, 92, 92, 96, 44, 42, 42, 41, 41, 42, 42, 42, 42, 47,
+ 47, 54, 54, 58, 58, 63, 63, 67, 67, 71, 71, 75, 75, 79, 79, 84, 84, 90,
+ 90, 92, 92, 96, 48, 46, 46, 44, 44, 45, 45, 46, 46, 51, 51, 57, 57, 61,
+ 61, 67, 67, 71, 71, 76, 76, 80, 80, 85, 85, 90, 90, 96, 96, 99, 99, 102,
+ 48, 46, 46, 44, 44, 45, 45, 46, 46, 51, 51, 57, 57, 61, 61, 67, 67, 71,
+ 71, 76, 76, 80, 80, 85, 85, 90, 90, 96, 96, 99, 99, 102, 54, 51, 51, 49,
+ 49, 50, 50, 49, 49, 54, 54, 60, 60, 65, 65, 71, 71, 76, 76, 82, 82, 87,
+ 87, 92, 92, 97, 97, 104, 104, 106, 106, 109, 54, 51, 51, 49, 49, 50, 50,
+ 49, 49, 54, 54, 60, 60, 65, 65, 71, 71, 76, 76, 82, 82, 87, 87, 92, 92,
+ 97, 97, 104, 104, 106, 106, 109, 59, 56, 56, 54, 54, 54, 54, 53, 53, 58,
+ 58, 64, 64, 69, 69, 75, 75, 80, 80, 87, 87, 92, 92, 98, 98, 103, 103,
+ 110, 110, 113, 113, 116, 59, 56, 56, 54, 54, 54, 54, 53, 53, 58, 58, 64,
+ 64, 69, 69, 75, 75, 80, 80, 87, 87, 92, 92, 98, 98, 103, 103, 110, 110,
+ 113, 113, 116, 65, 62, 62, 59, 59, 59, 59, 58, 58, 63, 63, 68, 68, 73,
+ 73, 79, 79, 85, 85, 92, 92, 98, 98, 105, 105, 111, 111, 118, 118, 121,
+ 121, 124, 65, 62, 62, 59, 59, 59, 59, 58, 58, 63, 63, 68, 68, 73, 73,
+ 79, 79, 85, 85, 92, 92, 98, 98, 105, 105, 111, 111, 118, 118, 121, 121,
+ 124, 71, 68, 68, 65, 65, 64, 64, 63, 63, 68, 68, 73, 73, 78, 78, 84, 84,
+ 90, 90, 97, 97, 103, 103, 111, 111, 117, 117, 125, 125, 128, 128, 132,
+ 71, 68, 68, 65, 65, 64, 64, 63, 63, 68, 68, 73, 73, 78, 78, 84, 84, 90,
+ 90, 97, 97, 103, 103, 111, 111, 117, 117, 125, 125, 128, 128, 132, 80,
+ 76, 76, 72, 72, 71, 71, 69, 69, 74, 74, 79, 79, 84, 84, 90, 90, 96, 96,
+ 104, 104, 110, 110, 118, 118, 125, 125, 134, 134, 137, 137, 141, 80, 76,
+ 76, 72, 72, 71, 71, 69, 69, 74, 74, 79, 79, 84, 84, 90, 90, 96, 96, 104,
+ 104, 110, 110, 118, 118, 125, 125, 134, 134, 137, 137, 141, 83, 78, 78,
+ 75, 75, 74, 74, 72, 72, 76, 76, 81, 81, 86, 86, 92, 92, 99, 99, 106,
+ 106, 113, 113, 121, 121, 128, 128, 137, 137, 140, 140, 144, 83, 78, 78,
+ 75, 75, 74, 74, 72, 72, 76, 76, 81, 81, 86, 86, 92, 92, 99, 99, 106,
+ 106, 113, 113, 121, 121, 128, 128, 137, 137, 140, 140, 144, 87, 83, 83,
+ 79, 79, 77, 77, 75, 75, 80, 80, 84, 84, 90, 90, 96, 96, 102, 102, 109,
+ 109, 116, 116, 124, 124, 132, 132, 141, 141, 144, 144, 149],
+ /* Size 4x8 */
+ [32, 35, 51, 75, 32, 36, 50, 71, 34, 42, 54, 73, 37, 50, 65, 84, 45, 56,
+ 76, 96, 54, 63, 87, 110, 65, 73, 97, 125, 75, 81, 106, 136],
+ /* Size 8x4 */
+ [32, 32, 34, 37, 45, 54, 65, 75, 35, 36, 42, 50, 56, 63, 73, 81, 51, 50,
+ 54, 65, 76, 87, 97, 106, 75, 71, 73, 84, 96, 110, 125, 136],
+ /* Size 8x16 */
+ [32, 31, 32, 36, 44, 53, 65, 79, 31, 32, 32, 35, 42, 51, 62, 75, 31, 32,
+ 33, 34, 41, 49, 59, 72, 32, 32, 34, 36, 42, 50, 59, 71, 32, 33, 35, 38,
+ 42, 49, 58, 69, 34, 34, 37, 42, 48, 54, 63, 73, 36, 34, 38, 48, 54, 60,
+ 68, 78, 39, 37, 40, 50, 58, 65, 73, 84, 44, 41, 43, 53, 63, 71, 79, 90,
+ 48, 45, 46, 56, 67, 76, 85, 96, 53, 49, 50, 60, 71, 82, 92, 103, 58, 54,
+ 54, 63, 75, 87, 98, 110, 65, 60, 58, 68, 79, 92, 105, 118, 71, 65, 63,
+ 73, 84, 97, 111, 125, 79, 72, 70, 79, 90, 104, 118, 133, 82, 75, 72, 81,
+ 92, 106, 121, 136],
+ /* Size 16x8 */
+ [32, 31, 31, 32, 32, 34, 36, 39, 44, 48, 53, 58, 65, 71, 79, 82, 31, 32,
+ 32, 32, 33, 34, 34, 37, 41, 45, 49, 54, 60, 65, 72, 75, 32, 32, 33, 34,
+ 35, 37, 38, 40, 43, 46, 50, 54, 58, 63, 70, 72, 36, 35, 34, 36, 38, 42,
+ 48, 50, 53, 56, 60, 63, 68, 73, 79, 81, 44, 42, 41, 42, 42, 48, 54, 58,
+ 63, 67, 71, 75, 79, 84, 90, 92, 53, 51, 49, 50, 49, 54, 60, 65, 71, 76,
+ 82, 87, 92, 97, 104, 106, 65, 62, 59, 59, 58, 63, 68, 73, 79, 85, 92,
+ 98, 105, 111, 118, 121, 79, 75, 72, 71, 69, 73, 78, 84, 90, 96, 103,
+ 110, 118, 125, 133, 136],
+ /* Size 16x32 */
+ [32, 31, 31, 32, 32, 36, 36, 44, 44, 53, 53, 65, 65, 79, 79, 87, 31, 32,
+ 32, 32, 32, 35, 35, 42, 42, 51, 51, 62, 62, 75, 75, 82, 31, 32, 32, 32,
+ 32, 35, 35, 42, 42, 51, 51, 62, 62, 75, 75, 82, 31, 32, 32, 33, 33, 34,
+ 34, 41, 41, 49, 49, 59, 59, 72, 72, 78, 31, 32, 32, 33, 33, 34, 34, 41,
+ 41, 49, 49, 59, 59, 72, 72, 78, 32, 32, 32, 34, 34, 36, 36, 42, 42, 50,
+ 50, 59, 59, 71, 71, 77, 32, 32, 32, 34, 34, 36, 36, 42, 42, 50, 50, 59,
+ 59, 71, 71, 77, 32, 33, 33, 35, 35, 38, 38, 42, 42, 49, 49, 58, 58, 69,
+ 69, 75, 32, 33, 33, 35, 35, 38, 38, 42, 42, 49, 49, 58, 58, 69, 69, 75,
+ 34, 34, 34, 37, 37, 42, 42, 48, 48, 54, 54, 63, 63, 73, 73, 79, 34, 34,
+ 34, 37, 37, 42, 42, 48, 48, 54, 54, 63, 63, 73, 73, 79, 36, 34, 34, 38,
+ 38, 48, 48, 54, 54, 60, 60, 68, 68, 78, 78, 84, 36, 34, 34, 38, 38, 48,
+ 48, 54, 54, 60, 60, 68, 68, 78, 78, 84, 39, 37, 37, 40, 40, 50, 50, 58,
+ 58, 65, 65, 73, 73, 84, 84, 89, 39, 37, 37, 40, 40, 50, 50, 58, 58, 65,
+ 65, 73, 73, 84, 84, 89, 44, 41, 41, 43, 43, 53, 53, 63, 63, 71, 71, 79,
+ 79, 90, 90, 95, 44, 41, 41, 43, 43, 53, 53, 63, 63, 71, 71, 79, 79, 90,
+ 90, 95, 48, 45, 45, 46, 46, 56, 56, 67, 67, 76, 76, 85, 85, 96, 96, 102,
+ 48, 45, 45, 46, 46, 56, 56, 67, 67, 76, 76, 85, 85, 96, 96, 102, 53, 49,
+ 49, 50, 50, 60, 60, 71, 71, 82, 82, 92, 92, 103, 103, 109, 53, 49, 49,
+ 50, 50, 60, 60, 71, 71, 82, 82, 92, 92, 103, 103, 109, 58, 54, 54, 54,
+ 54, 63, 63, 75, 75, 87, 87, 98, 98, 110, 110, 116, 58, 54, 54, 54, 54,
+ 63, 63, 75, 75, 87, 87, 98, 98, 110, 110, 116, 65, 60, 60, 58, 58, 68,
+ 68, 79, 79, 92, 92, 105, 105, 118, 118, 124, 65, 60, 60, 58, 58, 68, 68,
+ 79, 79, 92, 92, 105, 105, 118, 118, 124, 71, 65, 65, 63, 63, 73, 73, 84,
+ 84, 97, 97, 111, 111, 125, 125, 132, 71, 65, 65, 63, 63, 73, 73, 84, 84,
+ 97, 97, 111, 111, 125, 125, 132, 79, 72, 72, 70, 70, 79, 79, 90, 90,
+ 104, 104, 118, 118, 133, 133, 141, 79, 72, 72, 70, 70, 79, 79, 90, 90,
+ 104, 104, 118, 118, 133, 133, 141, 82, 75, 75, 72, 72, 81, 81, 92, 92,
+ 106, 106, 121, 121, 136, 136, 144, 82, 75, 75, 72, 72, 81, 81, 92, 92,
+ 106, 106, 121, 121, 136, 136, 144, 87, 79, 79, 76, 76, 84, 84, 96, 96,
+ 109, 109, 124, 124, 141, 141, 149],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 31, 32, 32, 32, 32, 34, 34, 36, 36, 39, 39, 44, 44, 48,
+ 48, 53, 53, 58, 58, 65, 65, 71, 71, 79, 79, 82, 82, 87, 31, 32, 32, 32,
+ 32, 32, 32, 33, 33, 34, 34, 34, 34, 37, 37, 41, 41, 45, 45, 49, 49, 54,
+ 54, 60, 60, 65, 65, 72, 72, 75, 75, 79, 31, 32, 32, 32, 32, 32, 32, 33,
+ 33, 34, 34, 34, 34, 37, 37, 41, 41, 45, 45, 49, 49, 54, 54, 60, 60, 65,
+ 65, 72, 72, 75, 75, 79, 32, 32, 32, 33, 33, 34, 34, 35, 35, 37, 37, 38,
+ 38, 40, 40, 43, 43, 46, 46, 50, 50, 54, 54, 58, 58, 63, 63, 70, 70, 72,
+ 72, 76, 32, 32, 32, 33, 33, 34, 34, 35, 35, 37, 37, 38, 38, 40, 40, 43,
+ 43, 46, 46, 50, 50, 54, 54, 58, 58, 63, 63, 70, 70, 72, 72, 76, 36, 35,
+ 35, 34, 34, 36, 36, 38, 38, 42, 42, 48, 48, 50, 50, 53, 53, 56, 56, 60,
+ 60, 63, 63, 68, 68, 73, 73, 79, 79, 81, 81, 84, 36, 35, 35, 34, 34, 36,
+ 36, 38, 38, 42, 42, 48, 48, 50, 50, 53, 53, 56, 56, 60, 60, 63, 63, 68,
+ 68, 73, 73, 79, 79, 81, 81, 84, 44, 42, 42, 41, 41, 42, 42, 42, 42, 48,
+ 48, 54, 54, 58, 58, 63, 63, 67, 67, 71, 71, 75, 75, 79, 79, 84, 84, 90,
+ 90, 92, 92, 96, 44, 42, 42, 41, 41, 42, 42, 42, 42, 48, 48, 54, 54, 58,
+ 58, 63, 63, 67, 67, 71, 71, 75, 75, 79, 79, 84, 84, 90, 90, 92, 92, 96,
+ 53, 51, 51, 49, 49, 50, 50, 49, 49, 54, 54, 60, 60, 65, 65, 71, 71, 76,
+ 76, 82, 82, 87, 87, 92, 92, 97, 97, 104, 104, 106, 106, 109, 53, 51, 51,
+ 49, 49, 50, 50, 49, 49, 54, 54, 60, 60, 65, 65, 71, 71, 76, 76, 82, 82,
+ 87, 87, 92, 92, 97, 97, 104, 104, 106, 106, 109, 65, 62, 62, 59, 59, 59,
+ 59, 58, 58, 63, 63, 68, 68, 73, 73, 79, 79, 85, 85, 92, 92, 98, 98, 105,
+ 105, 111, 111, 118, 118, 121, 121, 124, 65, 62, 62, 59, 59, 59, 59, 58,
+ 58, 63, 63, 68, 68, 73, 73, 79, 79, 85, 85, 92, 92, 98, 98, 105, 105,
+ 111, 111, 118, 118, 121, 121, 124, 79, 75, 75, 72, 72, 71, 71, 69, 69,
+ 73, 73, 78, 78, 84, 84, 90, 90, 96, 96, 103, 103, 110, 110, 118, 118,
+ 125, 125, 133, 133, 136, 136, 141, 79, 75, 75, 72, 72, 71, 71, 69, 69,
+ 73, 73, 78, 78, 84, 84, 90, 90, 96, 96, 103, 103, 110, 110, 118, 118,
+ 125, 125, 133, 133, 136, 136, 141, 87, 82, 82, 78, 78, 77, 77, 75, 75,
+ 79, 79, 84, 84, 89, 89, 95, 95, 102, 102, 109, 109, 116, 116, 124, 124,
+ 132, 132, 141, 141, 144, 144, 149],
+ /* Size 4x16 */
+ [31, 36, 53, 79, 32, 35, 51, 75, 32, 34, 49, 72, 32, 36, 50, 71, 33, 38,
+ 49, 69, 34, 42, 54, 73, 34, 48, 60, 78, 37, 50, 65, 84, 41, 53, 71, 90,
+ 45, 56, 76, 96, 49, 60, 82, 103, 54, 63, 87, 110, 60, 68, 92, 118, 65,
+ 73, 97, 125, 72, 79, 104, 133, 75, 81, 106, 136],
+ /* Size 16x4 */
+ [31, 32, 32, 32, 33, 34, 34, 37, 41, 45, 49, 54, 60, 65, 72, 75, 36, 35,
+ 34, 36, 38, 42, 48, 50, 53, 56, 60, 63, 68, 73, 79, 81, 53, 51, 49, 50,
+ 49, 54, 60, 65, 71, 76, 82, 87, 92, 97, 104, 106, 79, 75, 72, 71, 69,
+ 73, 78, 84, 90, 96, 103, 110, 118, 125, 133, 136],
+ /* Size 8x32 */
+ [32, 31, 32, 36, 44, 53, 65, 79, 31, 32, 32, 35, 42, 51, 62, 75, 31, 32,
+ 32, 35, 42, 51, 62, 75, 31, 32, 33, 34, 41, 49, 59, 72, 31, 32, 33, 34,
+ 41, 49, 59, 72, 32, 32, 34, 36, 42, 50, 59, 71, 32, 32, 34, 36, 42, 50,
+ 59, 71, 32, 33, 35, 38, 42, 49, 58, 69, 32, 33, 35, 38, 42, 49, 58, 69,
+ 34, 34, 37, 42, 48, 54, 63, 73, 34, 34, 37, 42, 48, 54, 63, 73, 36, 34,
+ 38, 48, 54, 60, 68, 78, 36, 34, 38, 48, 54, 60, 68, 78, 39, 37, 40, 50,
+ 58, 65, 73, 84, 39, 37, 40, 50, 58, 65, 73, 84, 44, 41, 43, 53, 63, 71,
+ 79, 90, 44, 41, 43, 53, 63, 71, 79, 90, 48, 45, 46, 56, 67, 76, 85, 96,
+ 48, 45, 46, 56, 67, 76, 85, 96, 53, 49, 50, 60, 71, 82, 92, 103, 53, 49,
+ 50, 60, 71, 82, 92, 103, 58, 54, 54, 63, 75, 87, 98, 110, 58, 54, 54,
+ 63, 75, 87, 98, 110, 65, 60, 58, 68, 79, 92, 105, 118, 65, 60, 58, 68,
+ 79, 92, 105, 118, 71, 65, 63, 73, 84, 97, 111, 125, 71, 65, 63, 73, 84,
+ 97, 111, 125, 79, 72, 70, 79, 90, 104, 118, 133, 79, 72, 70, 79, 90,
+ 104, 118, 133, 82, 75, 72, 81, 92, 106, 121, 136, 82, 75, 72, 81, 92,
+ 106, 121, 136, 87, 79, 76, 84, 96, 109, 124, 141],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 31, 32, 32, 32, 32, 34, 34, 36, 36, 39, 39, 44, 44, 48,
+ 48, 53, 53, 58, 58, 65, 65, 71, 71, 79, 79, 82, 82, 87, 31, 32, 32, 32,
+ 32, 32, 32, 33, 33, 34, 34, 34, 34, 37, 37, 41, 41, 45, 45, 49, 49, 54,
+ 54, 60, 60, 65, 65, 72, 72, 75, 75, 79, 32, 32, 32, 33, 33, 34, 34, 35,
+ 35, 37, 37, 38, 38, 40, 40, 43, 43, 46, 46, 50, 50, 54, 54, 58, 58, 63,
+ 63, 70, 70, 72, 72, 76, 36, 35, 35, 34, 34, 36, 36, 38, 38, 42, 42, 48,
+ 48, 50, 50, 53, 53, 56, 56, 60, 60, 63, 63, 68, 68, 73, 73, 79, 79, 81,
+ 81, 84, 44, 42, 42, 41, 41, 42, 42, 42, 42, 48, 48, 54, 54, 58, 58, 63,
+ 63, 67, 67, 71, 71, 75, 75, 79, 79, 84, 84, 90, 90, 92, 92, 96, 53, 51,
+ 51, 49, 49, 50, 50, 49, 49, 54, 54, 60, 60, 65, 65, 71, 71, 76, 76, 82,
+ 82, 87, 87, 92, 92, 97, 97, 104, 104, 106, 106, 109, 65, 62, 62, 59, 59,
+ 59, 59, 58, 58, 63, 63, 68, 68, 73, 73, 79, 79, 85, 85, 92, 92, 98, 98,
+ 105, 105, 111, 111, 118, 118, 121, 121, 124, 79, 75, 75, 72, 72, 71, 71,
+ 69, 69, 73, 73, 78, 78, 84, 84, 90, 90, 96, 96, 103, 103, 110, 110, 118,
+ 118, 125, 125, 133, 133, 136, 136, 141]],
+ [ /* Chroma */
+ /* Size 4x4 */
+ [32, 46, 47, 57, 46, 53, 54, 60, 47, 54, 66, 75, 57, 60, 75, 89],
+ /* Size 8x8 */
+ [31, 34, 42, 47, 48, 52, 57, 61, 34, 39, 45, 46, 46, 49, 53, 57, 42, 45,
+ 48, 49, 50, 52, 55, 58, 47, 46, 49, 54, 56, 58, 61, 64, 48, 46, 50, 56,
+ 61, 65, 68, 71, 52, 49, 52, 58, 65, 71, 75, 79, 57, 53, 55, 61, 68, 75,
+ 82, 86, 61, 57, 58, 64, 71, 79, 86, 91],
+ /* Size 16x16 */
+ [32, 31, 30, 33, 36, 41, 49, 48, 49, 50, 52, 54, 57, 60, 63, 65, 31, 31,
+ 31, 34, 38, 42, 47, 47, 47, 48, 50, 52, 54, 57, 60, 61, 30, 31, 32, 35,
+ 40, 42, 46, 45, 45, 46, 47, 49, 52, 54, 57, 58, 33, 34, 35, 39, 43, 45,
+ 47, 46, 45, 46, 47, 49, 51, 53, 56, 57, 36, 38, 40, 43, 47, 47, 48, 46,
+ 45, 46, 47, 48, 50, 52, 54, 55, 41, 42, 42, 45, 47, 48, 50, 49, 49, 50,
+ 50, 52, 53, 55, 57, 58, 49, 47, 46, 47, 48, 50, 53, 53, 53, 54, 54, 55,
+ 56, 58, 60, 61, 48, 47, 45, 46, 46, 49, 53, 54, 55, 56, 57, 58, 60, 61,
+ 63, 64, 49, 47, 45, 45, 45, 49, 53, 55, 58, 60, 61, 62, 63, 65, 67, 68,
+ 50, 48, 46, 46, 46, 50, 54, 56, 60, 61, 63, 65, 67, 68, 71, 71, 52, 50,
+ 47, 47, 47, 50, 54, 57, 61, 63, 66, 68, 70, 72, 75, 75, 54, 52, 49, 49,
+ 48, 52, 55, 58, 62, 65, 68, 71, 73, 75, 78, 79, 57, 54, 52, 51, 50, 53,
+ 56, 60, 63, 67, 70, 73, 76, 79, 82, 83, 60, 57, 54, 53, 52, 55, 58, 61,
+ 65, 68, 72, 75, 79, 82, 85, 86, 63, 60, 57, 56, 54, 57, 60, 63, 67, 71,
+ 75, 78, 82, 85, 89, 90, 65, 61, 58, 57, 55, 58, 61, 64, 68, 71, 75, 79,
+ 83, 86, 90, 91],
+ /* Size 32x32 */
+ [32, 31, 31, 30, 30, 33, 33, 36, 36, 41, 41, 49, 49, 48, 48, 49, 49, 50,
+ 50, 52, 52, 54, 54, 57, 57, 60, 60, 63, 63, 65, 65, 67, 31, 31, 31, 31,
+ 31, 34, 34, 38, 38, 42, 42, 47, 47, 47, 47, 47, 47, 48, 48, 50, 50, 52,
+ 52, 54, 54, 57, 57, 60, 60, 61, 61, 63, 31, 31, 31, 31, 31, 34, 34, 38,
+ 38, 42, 42, 47, 47, 47, 47, 47, 47, 48, 48, 50, 50, 52, 52, 54, 54, 57,
+ 57, 60, 60, 61, 61, 63, 30, 31, 31, 32, 32, 35, 35, 40, 40, 42, 42, 46,
+ 46, 45, 45, 45, 45, 46, 46, 47, 47, 49, 49, 52, 52, 54, 54, 57, 57, 58,
+ 58, 60, 30, 31, 31, 32, 32, 35, 35, 40, 40, 42, 42, 46, 46, 45, 45, 45,
+ 45, 46, 46, 47, 47, 49, 49, 52, 52, 54, 54, 57, 57, 58, 58, 60, 33, 34,
+ 34, 35, 35, 39, 39, 43, 43, 45, 45, 47, 47, 46, 46, 45, 45, 46, 46, 47,
+ 47, 49, 49, 51, 51, 53, 53, 56, 56, 57, 57, 59, 33, 34, 34, 35, 35, 39,
+ 39, 43, 43, 45, 45, 47, 47, 46, 46, 45, 45, 46, 46, 47, 47, 49, 49, 51,
+ 51, 53, 53, 56, 56, 57, 57, 59, 36, 38, 38, 40, 40, 43, 43, 47, 47, 47,
+ 47, 48, 48, 46, 46, 45, 45, 46, 46, 47, 47, 48, 48, 50, 50, 52, 52, 54,
+ 54, 55, 55, 57, 36, 38, 38, 40, 40, 43, 43, 47, 47, 47, 47, 48, 48, 46,
+ 46, 45, 45, 46, 46, 47, 47, 48, 48, 50, 50, 52, 52, 54, 54, 55, 55, 57,
+ 41, 42, 42, 42, 42, 45, 45, 47, 47, 48, 48, 50, 50, 49, 49, 49, 49, 50,
+ 50, 50, 50, 52, 52, 53, 53, 55, 55, 57, 57, 58, 58, 60, 41, 42, 42, 42,
+ 42, 45, 45, 47, 47, 48, 48, 50, 50, 49, 49, 49, 49, 50, 50, 50, 50, 52,
+ 52, 53, 53, 55, 55, 57, 57, 58, 58, 60, 49, 47, 47, 46, 46, 47, 47, 48,
+ 48, 50, 50, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 56, 56, 58,
+ 58, 60, 60, 61, 61, 62, 49, 47, 47, 46, 46, 47, 47, 48, 48, 50, 50, 53,
+ 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 56, 56, 58, 58, 60, 60, 61,
+ 61, 62, 48, 47, 47, 45, 45, 46, 46, 46, 46, 49, 49, 53, 53, 54, 54, 55,
+ 55, 56, 56, 57, 57, 58, 58, 60, 60, 61, 61, 63, 63, 64, 64, 66, 48, 47,
+ 47, 45, 45, 46, 46, 46, 46, 49, 49, 53, 53, 54, 54, 55, 55, 56, 56, 57,
+ 57, 58, 58, 60, 60, 61, 61, 63, 63, 64, 64, 66, 49, 47, 47, 45, 45, 45,
+ 45, 45, 45, 49, 49, 53, 53, 55, 55, 58, 58, 60, 60, 61, 61, 62, 62, 63,
+ 63, 65, 65, 67, 67, 68, 68, 69, 49, 47, 47, 45, 45, 45, 45, 45, 45, 49,
+ 49, 53, 53, 55, 55, 58, 58, 60, 60, 61, 61, 62, 62, 63, 63, 65, 65, 67,
+ 67, 68, 68, 69, 50, 48, 48, 46, 46, 46, 46, 46, 46, 50, 50, 54, 54, 56,
+ 56, 60, 60, 61, 61, 63, 63, 65, 65, 67, 67, 68, 68, 71, 71, 71, 71, 72,
+ 50, 48, 48, 46, 46, 46, 46, 46, 46, 50, 50, 54, 54, 56, 56, 60, 60, 61,
+ 61, 63, 63, 65, 65, 67, 67, 68, 68, 71, 71, 71, 71, 72, 52, 50, 50, 47,
+ 47, 47, 47, 47, 47, 50, 50, 54, 54, 57, 57, 61, 61, 63, 63, 66, 66, 68,
+ 68, 70, 70, 72, 72, 75, 75, 75, 75, 76, 52, 50, 50, 47, 47, 47, 47, 47,
+ 47, 50, 50, 54, 54, 57, 57, 61, 61, 63, 63, 66, 66, 68, 68, 70, 70, 72,
+ 72, 75, 75, 75, 75, 76, 54, 52, 52, 49, 49, 49, 49, 48, 48, 52, 52, 55,
+ 55, 58, 58, 62, 62, 65, 65, 68, 68, 71, 71, 73, 73, 75, 75, 78, 78, 79,
+ 79, 80, 54, 52, 52, 49, 49, 49, 49, 48, 48, 52, 52, 55, 55, 58, 58, 62,
+ 62, 65, 65, 68, 68, 71, 71, 73, 73, 75, 75, 78, 78, 79, 79, 80, 57, 54,
+ 54, 52, 52, 51, 51, 50, 50, 53, 53, 56, 56, 60, 60, 63, 63, 67, 67, 70,
+ 70, 73, 73, 76, 76, 79, 79, 82, 82, 83, 83, 84, 57, 54, 54, 52, 52, 51,
+ 51, 50, 50, 53, 53, 56, 56, 60, 60, 63, 63, 67, 67, 70, 70, 73, 73, 76,
+ 76, 79, 79, 82, 82, 83, 83, 84, 60, 57, 57, 54, 54, 53, 53, 52, 52, 55,
+ 55, 58, 58, 61, 61, 65, 65, 68, 68, 72, 72, 75, 75, 79, 79, 82, 82, 85,
+ 85, 86, 86, 88, 60, 57, 57, 54, 54, 53, 53, 52, 52, 55, 55, 58, 58, 61,
+ 61, 65, 65, 68, 68, 72, 72, 75, 75, 79, 79, 82, 82, 85, 85, 86, 86, 88,
+ 63, 60, 60, 57, 57, 56, 56, 54, 54, 57, 57, 60, 60, 63, 63, 67, 67, 71,
+ 71, 75, 75, 78, 78, 82, 82, 85, 85, 89, 89, 90, 90, 92, 63, 60, 60, 57,
+ 57, 56, 56, 54, 54, 57, 57, 60, 60, 63, 63, 67, 67, 71, 71, 75, 75, 78,
+ 78, 82, 82, 85, 85, 89, 89, 90, 90, 92, 65, 61, 61, 58, 58, 57, 57, 55,
+ 55, 58, 58, 61, 61, 64, 64, 68, 68, 71, 71, 75, 75, 79, 79, 83, 83, 86,
+ 86, 90, 90, 91, 91, 93, 65, 61, 61, 58, 58, 57, 57, 55, 55, 58, 58, 61,
+ 61, 64, 64, 68, 68, 71, 71, 75, 75, 79, 79, 83, 83, 86, 86, 90, 90, 91,
+ 91, 93, 67, 63, 63, 60, 60, 59, 59, 57, 57, 60, 60, 62, 62, 66, 66, 69,
+ 69, 72, 72, 76, 76, 80, 80, 84, 84, 88, 88, 92, 92, 93, 93, 95],
+ /* Size 4x8 */
+ [31, 47, 50, 60, 36, 47, 47, 56, 43, 50, 50, 57, 46, 53, 57, 64, 46, 54,
+ 64, 71, 50, 55, 68, 78, 54, 58, 72, 85, 59, 61, 75, 90],
+ /* Size 8x4 */
+ [31, 36, 43, 46, 46, 50, 54, 59, 47, 47, 50, 53, 54, 55, 58, 61, 50, 47,
+ 50, 57, 64, 68, 72, 75, 60, 56, 57, 64, 71, 78, 85, 90],
+ /* Size 8x16 */
+ [32, 31, 37, 48, 49, 52, 57, 63, 31, 31, 38, 47, 47, 50, 54, 60, 30, 32,
+ 40, 46, 45, 48, 52, 57, 33, 36, 43, 47, 46, 47, 51, 56, 37, 40, 47, 47,
+ 45, 47, 50, 54, 42, 43, 47, 50, 49, 50, 53, 57, 49, 46, 48, 53, 53, 54,
+ 57, 60, 48, 46, 47, 53, 56, 57, 60, 64, 49, 45, 46, 53, 58, 61, 64, 67,
+ 50, 46, 46, 54, 59, 64, 67, 71, 52, 48, 47, 54, 61, 66, 71, 75, 54, 50,
+ 49, 55, 62, 68, 73, 78, 57, 52, 50, 56, 64, 70, 76, 82, 60, 54, 52, 58,
+ 65, 72, 79, 85, 63, 57, 55, 60, 67, 75, 82, 89, 64, 59, 56, 61, 68, 75,
+ 83, 90],
+ /* Size 16x8 */
+ [32, 31, 30, 33, 37, 42, 49, 48, 49, 50, 52, 54, 57, 60, 63, 64, 31, 31,
+ 32, 36, 40, 43, 46, 46, 45, 46, 48, 50, 52, 54, 57, 59, 37, 38, 40, 43,
+ 47, 47, 48, 47, 46, 46, 47, 49, 50, 52, 55, 56, 48, 47, 46, 47, 47, 50,
+ 53, 53, 53, 54, 54, 55, 56, 58, 60, 61, 49, 47, 45, 46, 45, 49, 53, 56,
+ 58, 59, 61, 62, 64, 65, 67, 68, 52, 50, 48, 47, 47, 50, 54, 57, 61, 64,
+ 66, 68, 70, 72, 75, 75, 57, 54, 52, 51, 50, 53, 57, 60, 64, 67, 71, 73,
+ 76, 79, 82, 83, 63, 60, 57, 56, 54, 57, 60, 64, 67, 71, 75, 78, 82, 85,
+ 89, 90],
+ /* Size 16x32 */
+ [32, 31, 31, 37, 37, 48, 48, 49, 49, 52, 52, 57, 57, 63, 63, 66, 31, 31,
+ 31, 38, 38, 47, 47, 47, 47, 50, 50, 54, 54, 60, 60, 63, 31, 31, 31, 38,
+ 38, 47, 47, 47, 47, 50, 50, 54, 54, 60, 60, 63, 30, 32, 32, 40, 40, 46,
+ 46, 45, 45, 48, 48, 52, 52, 57, 57, 60, 30, 32, 32, 40, 40, 46, 46, 45,
+ 45, 48, 48, 52, 52, 57, 57, 60, 33, 36, 36, 43, 43, 47, 47, 46, 46, 47,
+ 47, 51, 51, 56, 56, 59, 33, 36, 36, 43, 43, 47, 47, 46, 46, 47, 47, 51,
+ 51, 56, 56, 59, 37, 40, 40, 47, 47, 47, 47, 45, 45, 47, 47, 50, 50, 54,
+ 54, 57, 37, 40, 40, 47, 47, 47, 47, 45, 45, 47, 47, 50, 50, 54, 54, 57,
+ 42, 43, 43, 47, 47, 50, 50, 49, 49, 50, 50, 53, 53, 57, 57, 60, 42, 43,
+ 43, 47, 47, 50, 50, 49, 49, 50, 50, 53, 53, 57, 57, 60, 49, 46, 46, 48,
+ 48, 53, 53, 53, 53, 54, 54, 57, 57, 60, 60, 62, 49, 46, 46, 48, 48, 53,
+ 53, 53, 53, 54, 54, 57, 57, 60, 60, 62, 48, 46, 46, 47, 47, 53, 53, 56,
+ 56, 57, 57, 60, 60, 64, 64, 66, 48, 46, 46, 47, 47, 53, 53, 56, 56, 57,
+ 57, 60, 60, 64, 64, 66, 49, 45, 45, 46, 46, 53, 53, 58, 58, 61, 61, 64,
+ 64, 67, 67, 69, 49, 45, 45, 46, 46, 53, 53, 58, 58, 61, 61, 64, 64, 67,
+ 67, 69, 50, 46, 46, 46, 46, 54, 54, 59, 59, 64, 64, 67, 67, 71, 71, 73,
+ 50, 46, 46, 46, 46, 54, 54, 59, 59, 64, 64, 67, 67, 71, 71, 73, 52, 48,
+ 48, 47, 47, 54, 54, 61, 61, 66, 66, 71, 71, 75, 75, 77, 52, 48, 48, 47,
+ 47, 54, 54, 61, 61, 66, 66, 71, 71, 75, 75, 77, 54, 50, 50, 49, 49, 55,
+ 55, 62, 62, 68, 68, 73, 73, 78, 78, 80, 54, 50, 50, 49, 49, 55, 55, 62,
+ 62, 68, 68, 73, 73, 78, 78, 80, 57, 52, 52, 50, 50, 56, 56, 64, 64, 70,
+ 70, 76, 76, 82, 82, 84, 57, 52, 52, 50, 50, 56, 56, 64, 64, 70, 70, 76,
+ 76, 82, 82, 84, 60, 54, 54, 52, 52, 58, 58, 65, 65, 72, 72, 79, 79, 85,
+ 85, 88, 60, 54, 54, 52, 52, 58, 58, 65, 65, 72, 72, 79, 79, 85, 85, 88,
+ 63, 57, 57, 55, 55, 60, 60, 67, 67, 75, 75, 82, 82, 89, 89, 92, 63, 57,
+ 57, 55, 55, 60, 60, 67, 67, 75, 75, 82, 82, 89, 89, 92, 64, 59, 59, 56,
+ 56, 61, 61, 68, 68, 75, 75, 83, 83, 90, 90, 93, 64, 59, 59, 56, 56, 61,
+ 61, 68, 68, 75, 75, 83, 83, 90, 90, 93, 66, 60, 60, 57, 57, 63, 63, 69,
+ 69, 77, 77, 84, 84, 92, 92, 95],
+ /* Size 32x16 */
+ [32, 31, 31, 30, 30, 33, 33, 37, 37, 42, 42, 49, 49, 48, 48, 49, 49, 50,
+ 50, 52, 52, 54, 54, 57, 57, 60, 60, 63, 63, 64, 64, 66, 31, 31, 31, 32,
+ 32, 36, 36, 40, 40, 43, 43, 46, 46, 46, 46, 45, 45, 46, 46, 48, 48, 50,
+ 50, 52, 52, 54, 54, 57, 57, 59, 59, 60, 31, 31, 31, 32, 32, 36, 36, 40,
+ 40, 43, 43, 46, 46, 46, 46, 45, 45, 46, 46, 48, 48, 50, 50, 52, 52, 54,
+ 54, 57, 57, 59, 59, 60, 37, 38, 38, 40, 40, 43, 43, 47, 47, 47, 47, 48,
+ 48, 47, 47, 46, 46, 46, 46, 47, 47, 49, 49, 50, 50, 52, 52, 55, 55, 56,
+ 56, 57, 37, 38, 38, 40, 40, 43, 43, 47, 47, 47, 47, 48, 48, 47, 47, 46,
+ 46, 46, 46, 47, 47, 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 57, 48, 47,
+ 47, 46, 46, 47, 47, 47, 47, 50, 50, 53, 53, 53, 53, 53, 53, 54, 54, 54,
+ 54, 55, 55, 56, 56, 58, 58, 60, 60, 61, 61, 63, 48, 47, 47, 46, 46, 47,
+ 47, 47, 47, 50, 50, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 56,
+ 56, 58, 58, 60, 60, 61, 61, 63, 49, 47, 47, 45, 45, 46, 46, 45, 45, 49,
+ 49, 53, 53, 56, 56, 58, 58, 59, 59, 61, 61, 62, 62, 64, 64, 65, 65, 67,
+ 67, 68, 68, 69, 49, 47, 47, 45, 45, 46, 46, 45, 45, 49, 49, 53, 53, 56,
+ 56, 58, 58, 59, 59, 61, 61, 62, 62, 64, 64, 65, 65, 67, 67, 68, 68, 69,
+ 52, 50, 50, 48, 48, 47, 47, 47, 47, 50, 50, 54, 54, 57, 57, 61, 61, 64,
+ 64, 66, 66, 68, 68, 70, 70, 72, 72, 75, 75, 75, 75, 77, 52, 50, 50, 48,
+ 48, 47, 47, 47, 47, 50, 50, 54, 54, 57, 57, 61, 61, 64, 64, 66, 66, 68,
+ 68, 70, 70, 72, 72, 75, 75, 75, 75, 77, 57, 54, 54, 52, 52, 51, 51, 50,
+ 50, 53, 53, 57, 57, 60, 60, 64, 64, 67, 67, 71, 71, 73, 73, 76, 76, 79,
+ 79, 82, 82, 83, 83, 84, 57, 54, 54, 52, 52, 51, 51, 50, 50, 53, 53, 57,
+ 57, 60, 60, 64, 64, 67, 67, 71, 71, 73, 73, 76, 76, 79, 79, 82, 82, 83,
+ 83, 84, 63, 60, 60, 57, 57, 56, 56, 54, 54, 57, 57, 60, 60, 64, 64, 67,
+ 67, 71, 71, 75, 75, 78, 78, 82, 82, 85, 85, 89, 89, 90, 90, 92, 63, 60,
+ 60, 57, 57, 56, 56, 54, 54, 57, 57, 60, 60, 64, 64, 67, 67, 71, 71, 75,
+ 75, 78, 78, 82, 82, 85, 85, 89, 89, 90, 90, 92, 66, 63, 63, 60, 60, 59,
+ 59, 57, 57, 60, 60, 62, 62, 66, 66, 69, 69, 73, 73, 77, 77, 80, 80, 84,
+ 84, 88, 88, 92, 92, 93, 93, 95],
+ /* Size 4x16 */
+ [31, 48, 52, 63, 31, 47, 50, 60, 32, 46, 48, 57, 36, 47, 47, 56, 40, 47,
+ 47, 54, 43, 50, 50, 57, 46, 53, 54, 60, 46, 53, 57, 64, 45, 53, 61, 67,
+ 46, 54, 64, 71, 48, 54, 66, 75, 50, 55, 68, 78, 52, 56, 70, 82, 54, 58,
+ 72, 85, 57, 60, 75, 89, 59, 61, 75, 90],
+ /* Size 16x4 */
+ [31, 31, 32, 36, 40, 43, 46, 46, 45, 46, 48, 50, 52, 54, 57, 59, 48, 47,
+ 46, 47, 47, 50, 53, 53, 53, 54, 54, 55, 56, 58, 60, 61, 52, 50, 48, 47,
+ 47, 50, 54, 57, 61, 64, 66, 68, 70, 72, 75, 75, 63, 60, 57, 56, 54, 57,
+ 60, 64, 67, 71, 75, 78, 82, 85, 89, 90],
+ /* Size 8x32 */
+ [32, 31, 37, 48, 49, 52, 57, 63, 31, 31, 38, 47, 47, 50, 54, 60, 31, 31,
+ 38, 47, 47, 50, 54, 60, 30, 32, 40, 46, 45, 48, 52, 57, 30, 32, 40, 46,
+ 45, 48, 52, 57, 33, 36, 43, 47, 46, 47, 51, 56, 33, 36, 43, 47, 46, 47,
+ 51, 56, 37, 40, 47, 47, 45, 47, 50, 54, 37, 40, 47, 47, 45, 47, 50, 54,
+ 42, 43, 47, 50, 49, 50, 53, 57, 42, 43, 47, 50, 49, 50, 53, 57, 49, 46,
+ 48, 53, 53, 54, 57, 60, 49, 46, 48, 53, 53, 54, 57, 60, 48, 46, 47, 53,
+ 56, 57, 60, 64, 48, 46, 47, 53, 56, 57, 60, 64, 49, 45, 46, 53, 58, 61,
+ 64, 67, 49, 45, 46, 53, 58, 61, 64, 67, 50, 46, 46, 54, 59, 64, 67, 71,
+ 50, 46, 46, 54, 59, 64, 67, 71, 52, 48, 47, 54, 61, 66, 71, 75, 52, 48,
+ 47, 54, 61, 66, 71, 75, 54, 50, 49, 55, 62, 68, 73, 78, 54, 50, 49, 55,
+ 62, 68, 73, 78, 57, 52, 50, 56, 64, 70, 76, 82, 57, 52, 50, 56, 64, 70,
+ 76, 82, 60, 54, 52, 58, 65, 72, 79, 85, 60, 54, 52, 58, 65, 72, 79, 85,
+ 63, 57, 55, 60, 67, 75, 82, 89, 63, 57, 55, 60, 67, 75, 82, 89, 64, 59,
+ 56, 61, 68, 75, 83, 90, 64, 59, 56, 61, 68, 75, 83, 90, 66, 60, 57, 63,
+ 69, 77, 84, 92],
+ /* Size 32x8 */
+ [32, 31, 31, 30, 30, 33, 33, 37, 37, 42, 42, 49, 49, 48, 48, 49, 49, 50,
+ 50, 52, 52, 54, 54, 57, 57, 60, 60, 63, 63, 64, 64, 66, 31, 31, 31, 32,
+ 32, 36, 36, 40, 40, 43, 43, 46, 46, 46, 46, 45, 45, 46, 46, 48, 48, 50,
+ 50, 52, 52, 54, 54, 57, 57, 59, 59, 60, 37, 38, 38, 40, 40, 43, 43, 47,
+ 47, 47, 47, 48, 48, 47, 47, 46, 46, 46, 46, 47, 47, 49, 49, 50, 50, 52,
+ 52, 55, 55, 56, 56, 57, 48, 47, 47, 46, 46, 47, 47, 47, 47, 50, 50, 53,
+ 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 56, 56, 58, 58, 60, 60, 61,
+ 61, 63, 49, 47, 47, 45, 45, 46, 46, 45, 45, 49, 49, 53, 53, 56, 56, 58,
+ 58, 59, 59, 61, 61, 62, 62, 64, 64, 65, 65, 67, 67, 68, 68, 69, 52, 50,
+ 50, 48, 48, 47, 47, 47, 47, 50, 50, 54, 54, 57, 57, 61, 61, 64, 64, 66,
+ 66, 68, 68, 70, 70, 72, 72, 75, 75, 75, 75, 77, 57, 54, 54, 52, 52, 51,
+ 51, 50, 50, 53, 53, 57, 57, 60, 60, 64, 64, 67, 67, 71, 71, 73, 73, 76,
+ 76, 79, 79, 82, 82, 83, 83, 84, 63, 60, 60, 57, 57, 56, 56, 54, 54, 57,
+ 57, 60, 60, 64, 64, 67, 67, 71, 71, 75, 75, 78, 78, 82, 82, 85, 85, 89,
+ 89, 90, 90, 92]]
+ ],
+ [
+ [ /* Luma */
+ /* Size 4x4 */
+ [32, 33, 45, 62, 33, 39, 51, 64, 45, 51, 71, 87, 62, 64, 87, 108],
+ /* Size 8x8 */
+ [31, 32, 32, 35, 42, 51, 59, 69, 32, 32, 33, 35, 41, 49, 56, 65, 32, 33,
+ 35, 38, 43, 49, 56, 64, 35, 35, 38, 48, 54, 59, 66, 73, 42, 41, 43, 54,
+ 63, 71, 77, 85, 51, 49, 49, 59, 71, 81, 89, 97, 59, 56, 56, 66, 77, 89,
+ 98, 108, 69, 65, 64, 73, 85, 97, 108, 119],
+ /* Size 16x16 */
+ [32, 31, 31, 31, 32, 34, 35, 38, 41, 45, 48, 54, 59, 65, 71, 80, 31, 32,
+ 32, 32, 32, 34, 35, 37, 40, 43, 46, 51, 56, 62, 68, 76, 31, 32, 32, 32,
+ 32, 33, 34, 36, 38, 41, 44, 49, 54, 59, 65, 72, 31, 32, 32, 33, 34, 35,
+ 36, 38, 40, 42, 45, 50, 54, 59, 64, 71, 32, 32, 32, 34, 35, 37, 38, 39,
+ 41, 43, 46, 49, 53, 58, 63, 69, 34, 34, 33, 35, 37, 39, 42, 44, 46, 48,
+ 51, 54, 58, 63, 68, 74, 35, 35, 34, 36, 38, 42, 46, 48, 50, 53, 55, 59,
+ 62, 67, 72, 78, 38, 37, 36, 38, 39, 44, 48, 51, 54, 57, 59, 63, 67, 71,
+ 76, 82, 41, 40, 38, 40, 41, 46, 50, 54, 57, 60, 63, 67, 71, 75, 80, 86,
+ 45, 43, 41, 42, 43, 48, 53, 57, 60, 65, 68, 72, 76, 81, 85, 91, 48, 46,
+ 44, 45, 46, 51, 55, 59, 63, 68, 71, 76, 80, 85, 90, 96, 54, 51, 49, 50,
+ 49, 54, 59, 63, 67, 72, 76, 82, 87, 92, 97, 104, 59, 56, 54, 54, 53, 58,
+ 62, 67, 71, 76, 80, 87, 92, 98, 103, 110, 65, 62, 59, 59, 58, 63, 67,
+ 71, 75, 81, 85, 92, 98, 105, 111, 118, 71, 68, 65, 64, 63, 68, 72, 76,
+ 80, 85, 90, 97, 103, 111, 117, 125, 80, 76, 72, 71, 69, 74, 78, 82, 86,
+ 91, 96, 104, 110, 118, 125, 134],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 31, 31, 32, 32, 32, 34, 34, 35, 36, 38, 39, 41, 44,
+ 45, 48, 48, 53, 54, 57, 59, 62, 65, 67, 71, 72, 80, 80, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 34, 34, 35, 35, 37, 38, 40, 42, 43, 46, 46, 51,
+ 52, 55, 56, 59, 62, 64, 68, 69, 76, 76, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 34, 34, 35, 35, 37, 38, 40, 42, 43, 46, 46, 51, 51, 55, 56, 59,
+ 62, 64, 68, 69, 76, 76, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33,
+ 34, 34, 36, 38, 39, 41, 42, 45, 45, 49, 50, 53, 54, 57, 60, 62, 66, 66,
+ 73, 73, 31, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 36, 37,
+ 38, 41, 41, 44, 44, 49, 49, 52, 54, 56, 59, 61, 65, 65, 72, 72, 31, 32,
+ 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 35, 35, 37, 38, 39, 41, 42, 45,
+ 45, 49, 49, 52, 54, 56, 59, 61, 64, 65, 72, 72, 31, 32, 32, 32, 32, 33,
+ 33, 33, 34, 34, 35, 35, 36, 36, 38, 39, 40, 42, 42, 45, 45, 49, 50, 52,
+ 54, 56, 59, 60, 64, 65, 71, 71, 32, 32, 32, 32, 32, 33, 33, 34, 34, 34,
+ 35, 35, 36, 37, 38, 39, 40, 42, 43, 45, 45, 49, 49, 52, 54, 56, 59, 60,
+ 64, 64, 70, 70, 32, 32, 32, 32, 32, 33, 34, 34, 35, 35, 37, 37, 38, 38,
+ 39, 40, 41, 42, 43, 46, 46, 49, 49, 52, 53, 55, 58, 59, 63, 63, 69, 69,
+ 32, 32, 32, 32, 33, 33, 34, 34, 35, 35, 37, 37, 38, 38, 40, 41, 41, 43,
+ 43, 46, 46, 49, 50, 52, 54, 56, 58, 60, 63, 64, 70, 70, 34, 34, 34, 33,
+ 33, 34, 35, 35, 37, 37, 39, 39, 42, 42, 44, 45, 46, 47, 48, 51, 51, 54,
+ 54, 57, 58, 60, 63, 64, 68, 68, 74, 74, 34, 34, 34, 33, 33, 34, 35, 35,
+ 37, 37, 39, 39, 42, 42, 44, 45, 46, 47, 48, 51, 51, 54, 54, 57, 58, 60,
+ 63, 64, 68, 68, 74, 74, 35, 35, 35, 34, 34, 35, 36, 36, 38, 38, 42, 42,
+ 46, 47, 48, 49, 50, 52, 53, 55, 55, 58, 59, 61, 62, 64, 67, 68, 72, 72,
+ 78, 78, 36, 35, 35, 34, 34, 35, 36, 37, 38, 38, 42, 42, 47, 48, 50, 50,
+ 52, 54, 54, 57, 57, 59, 60, 62, 64, 66, 68, 69, 73, 73, 79, 79, 38, 37,
+ 37, 36, 36, 37, 38, 38, 39, 40, 44, 44, 48, 50, 51, 52, 54, 56, 57, 59,
+ 59, 62, 63, 65, 67, 69, 71, 72, 76, 76, 82, 82, 39, 38, 38, 38, 37, 38,
+ 39, 39, 40, 41, 45, 45, 49, 50, 52, 54, 55, 58, 58, 61, 61, 64, 65, 67,
+ 69, 71, 73, 74, 78, 78, 84, 84, 41, 40, 40, 39, 38, 39, 40, 40, 41, 41,
+ 46, 46, 50, 52, 54, 55, 57, 60, 60, 63, 63, 67, 67, 70, 71, 73, 75, 77,
+ 80, 81, 86, 86, 44, 42, 42, 41, 41, 41, 42, 42, 42, 43, 47, 47, 52, 54,
+ 56, 58, 60, 63, 64, 67, 67, 71, 71, 74, 75, 77, 79, 81, 84, 85, 90, 90,
+ 45, 43, 43, 42, 41, 42, 42, 43, 43, 43, 48, 48, 53, 54, 57, 58, 60, 64,
+ 65, 68, 68, 72, 72, 75, 76, 78, 81, 82, 85, 86, 91, 91, 48, 46, 46, 45,
+ 44, 45, 45, 45, 46, 46, 51, 51, 55, 57, 59, 61, 63, 67, 68, 71, 71, 75,
+ 76, 79, 80, 83, 85, 87, 90, 91, 96, 96, 48, 46, 46, 45, 44, 45, 45, 45,
+ 46, 46, 51, 51, 55, 57, 59, 61, 63, 67, 68, 71, 71, 75, 76, 79, 80, 83,
+ 85, 87, 90, 91, 96, 96, 53, 51, 51, 49, 49, 49, 49, 49, 49, 49, 54, 54,
+ 58, 59, 62, 64, 67, 71, 72, 75, 75, 81, 81, 85, 86, 89, 91, 93, 97, 97,
+ 103, 103, 54, 52, 51, 50, 49, 49, 50, 49, 49, 50, 54, 54, 59, 60, 63,
+ 65, 67, 71, 72, 76, 76, 81, 82, 85, 87, 89, 92, 94, 97, 98, 104, 104,
+ 57, 55, 55, 53, 52, 52, 52, 52, 52, 52, 57, 57, 61, 62, 65, 67, 70, 74,
+ 75, 79, 79, 85, 85, 89, 90, 93, 96, 98, 102, 102, 108, 108, 59, 56, 56,
+ 54, 54, 54, 54, 54, 53, 54, 58, 58, 62, 64, 67, 69, 71, 75, 76, 80, 80,
+ 86, 87, 90, 92, 95, 98, 99, 103, 104, 110, 110, 62, 59, 59, 57, 56, 56,
+ 56, 56, 55, 56, 60, 60, 64, 66, 69, 71, 73, 77, 78, 83, 83, 89, 89, 93,
+ 95, 98, 101, 103, 107, 108, 114, 114, 65, 62, 62, 60, 59, 59, 59, 59,
+ 58, 58, 63, 63, 67, 68, 71, 73, 75, 79, 81, 85, 85, 91, 92, 96, 98, 101,
+ 105, 106, 111, 111, 118, 118, 67, 64, 64, 62, 61, 61, 60, 60, 59, 60,
+ 64, 64, 68, 69, 72, 74, 77, 81, 82, 87, 87, 93, 94, 98, 99, 103, 106,
+ 108, 113, 113, 120, 120, 71, 68, 68, 66, 65, 64, 64, 64, 63, 63, 68, 68,
+ 72, 73, 76, 78, 80, 84, 85, 90, 90, 97, 97, 102, 103, 107, 111, 113,
+ 117, 118, 125, 125, 72, 69, 69, 66, 65, 65, 65, 64, 63, 64, 68, 68, 72,
+ 73, 76, 78, 81, 85, 86, 91, 91, 97, 98, 102, 104, 108, 111, 113, 118,
+ 119, 126, 126, 80, 76, 76, 73, 72, 72, 71, 70, 69, 70, 74, 74, 78, 79,
+ 82, 84, 86, 90, 91, 96, 96, 103, 104, 108, 110, 114, 118, 120, 125, 126,
+ 134, 134, 80, 76, 76, 73, 72, 72, 71, 70, 69, 70, 74, 74, 78, 79, 82,
+ 84, 86, 90, 91, 96, 96, 103, 104, 108, 110, 114, 118, 120, 125, 126,
+ 134, 134],
+ /* Size 4x8 */
+ [32, 34, 43, 62, 32, 34, 42, 59, 33, 37, 44, 58, 35, 43, 54, 68, 41, 48,
+ 64, 79, 49, 54, 71, 91, 57, 60, 78, 101, 66, 68, 86, 111],
+ /* Size 8x4 */
+ [32, 32, 33, 35, 41, 49, 57, 66, 34, 34, 37, 43, 48, 54, 60, 68, 43, 42,
+ 44, 54, 64, 71, 78, 86, 62, 59, 58, 68, 79, 91, 101, 111],
+ /* Size 8x16 */
+ [32, 31, 32, 36, 44, 53, 62, 73, 31, 32, 32, 35, 42, 51, 59, 69, 31, 32,
+ 33, 34, 41, 49, 57, 66, 32, 32, 34, 36, 42, 50, 57, 65, 32, 33, 35, 38,
+ 42, 49, 56, 64, 34, 34, 37, 42, 48, 54, 61, 69, 35, 34, 38, 47, 52, 59,
+ 65, 73, 38, 36, 40, 49, 56, 63, 69, 77, 41, 39, 41, 51, 60, 67, 74, 81,
+ 44, 42, 43, 54, 64, 72, 79, 86, 48, 45, 46, 56, 67, 76, 83, 91, 53, 49,
+ 50, 60, 71, 82, 90, 99, 58, 54, 54, 63, 75, 87, 95, 105, 65, 60, 58, 68,
+ 79, 92, 102, 112, 71, 65, 63, 73, 84, 97, 108, 119, 79, 72, 70, 79, 90,
+ 104, 115, 127],
+ /* Size 16x8 */
+ [32, 31, 31, 32, 32, 34, 35, 38, 41, 44, 48, 53, 58, 65, 71, 79, 31, 32,
+ 32, 32, 33, 34, 34, 36, 39, 42, 45, 49, 54, 60, 65, 72, 32, 32, 33, 34,
+ 35, 37, 38, 40, 41, 43, 46, 50, 54, 58, 63, 70, 36, 35, 34, 36, 38, 42,
+ 47, 49, 51, 54, 56, 60, 63, 68, 73, 79, 44, 42, 41, 42, 42, 48, 52, 56,
+ 60, 64, 67, 71, 75, 79, 84, 90, 53, 51, 49, 50, 49, 54, 59, 63, 67, 72,
+ 76, 82, 87, 92, 97, 104, 62, 59, 57, 57, 56, 61, 65, 69, 74, 79, 83, 90,
+ 95, 102, 108, 115, 73, 69, 66, 65, 64, 69, 73, 77, 81, 86, 91, 99, 105,
+ 112, 119, 127],
+ /* Size 16x32 */
+ [32, 31, 31, 32, 32, 34, 36, 38, 44, 44, 53, 53, 62, 65, 73, 79, 31, 32,
+ 32, 32, 32, 34, 35, 37, 42, 43, 51, 51, 60, 62, 70, 75, 31, 32, 32, 32,
+ 32, 34, 35, 37, 42, 43, 51, 51, 59, 62, 69, 75, 31, 32, 32, 32, 32, 33,
+ 35, 36, 41, 42, 50, 50, 58, 60, 67, 73, 31, 32, 32, 32, 33, 33, 34, 36,
+ 41, 41, 49, 49, 57, 59, 66, 72, 31, 32, 32, 33, 33, 34, 35, 37, 41, 42,
+ 49, 49, 57, 59, 66, 71, 32, 32, 32, 33, 34, 35, 36, 38, 42, 43, 50, 50,
+ 57, 59, 65, 71, 32, 32, 32, 34, 34, 35, 37, 38, 42, 43, 49, 49, 56, 59,
+ 65, 70, 32, 32, 33, 34, 35, 37, 38, 39, 42, 43, 49, 49, 56, 58, 64, 69,
+ 32, 33, 33, 34, 35, 37, 39, 40, 43, 44, 50, 50, 56, 58, 64, 69, 34, 34,
+ 34, 36, 37, 39, 42, 44, 48, 48, 54, 54, 61, 63, 69, 73, 34, 34, 34, 36,
+ 37, 39, 42, 44, 48, 48, 54, 54, 61, 63, 69, 73, 35, 34, 34, 37, 38, 42,
+ 47, 48, 52, 53, 59, 59, 65, 67, 73, 77, 36, 35, 34, 37, 38, 43, 48, 49,
+ 54, 54, 60, 60, 66, 68, 74, 78, 38, 36, 36, 38, 40, 44, 49, 51, 56, 57,
+ 63, 63, 69, 71, 77, 81, 39, 38, 37, 40, 40, 45, 50, 52, 58, 58, 65, 65,
+ 71, 73, 79, 84, 41, 39, 39, 41, 41, 46, 51, 54, 60, 60, 67, 67, 74, 76,
+ 81, 86, 44, 41, 41, 42, 43, 48, 53, 56, 63, 64, 71, 71, 78, 79, 85, 90,
+ 44, 42, 42, 43, 43, 48, 54, 56, 64, 64, 72, 72, 79, 81, 86, 91, 48, 45,
+ 45, 46, 46, 51, 56, 59, 67, 67, 76, 76, 83, 85, 91, 96, 48, 45, 45, 46,
+ 46, 51, 56, 59, 67, 67, 76, 76, 83, 85, 91, 96, 53, 49, 49, 49, 49, 54,
+ 59, 62, 71, 71, 81, 81, 89, 91, 98, 103, 53, 50, 49, 50, 50, 54, 60, 63,
+ 71, 72, 82, 82, 90, 92, 99, 103, 57, 53, 52, 52, 52, 57, 62, 65, 74, 75,
+ 85, 85, 94, 96, 103, 108, 58, 54, 54, 54, 54, 58, 63, 67, 75, 76, 87,
+ 87, 95, 98, 105, 110, 61, 57, 57, 56, 56, 60, 66, 69, 77, 78, 89, 89,
+ 98, 101, 108, 114, 65, 60, 60, 59, 58, 63, 68, 71, 79, 80, 92, 92, 102,
+ 105, 112, 118, 67, 62, 61, 60, 60, 64, 69, 72, 81, 82, 94, 94, 103, 106,
+ 114, 120, 71, 66, 65, 64, 63, 68, 73, 76, 84, 85, 97, 97, 108, 111, 119,
+ 125, 72, 66, 66, 64, 64, 68, 73, 76, 85, 86, 98, 98, 108, 111, 119, 125,
+ 79, 73, 72, 71, 70, 74, 79, 82, 90, 91, 104, 104, 115, 118, 127, 133,
+ 79, 73, 72, 71, 70, 74, 79, 82, 90, 91, 104, 104, 115, 118, 127, 133],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 31, 31, 32, 32, 32, 32, 34, 34, 35, 36, 38, 39, 41, 44,
+ 44, 48, 48, 53, 53, 57, 58, 61, 65, 67, 71, 72, 79, 79, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 34, 34, 34, 35, 36, 38, 39, 41, 42, 45, 45, 49,
+ 50, 53, 54, 57, 60, 62, 66, 66, 73, 73, 31, 32, 32, 32, 32, 32, 32, 32,
+ 33, 33, 34, 34, 34, 34, 36, 37, 39, 41, 42, 45, 45, 49, 49, 52, 54, 57,
+ 60, 61, 65, 66, 72, 72, 32, 32, 32, 32, 32, 33, 33, 34, 34, 34, 36, 36,
+ 37, 37, 38, 40, 41, 42, 43, 46, 46, 49, 50, 52, 54, 56, 59, 60, 64, 64,
+ 71, 71, 32, 32, 32, 32, 33, 33, 34, 34, 35, 35, 37, 37, 38, 38, 40, 40,
+ 41, 43, 43, 46, 46, 49, 50, 52, 54, 56, 58, 60, 63, 64, 70, 70, 34, 34,
+ 34, 33, 33, 34, 35, 35, 37, 37, 39, 39, 42, 43, 44, 45, 46, 48, 48, 51,
+ 51, 54, 54, 57, 58, 60, 63, 64, 68, 68, 74, 74, 36, 35, 35, 35, 34, 35,
+ 36, 37, 38, 39, 42, 42, 47, 48, 49, 50, 51, 53, 54, 56, 56, 59, 60, 62,
+ 63, 66, 68, 69, 73, 73, 79, 79, 38, 37, 37, 36, 36, 37, 38, 38, 39, 40,
+ 44, 44, 48, 49, 51, 52, 54, 56, 56, 59, 59, 62, 63, 65, 67, 69, 71, 72,
+ 76, 76, 82, 82, 44, 42, 42, 41, 41, 41, 42, 42, 42, 43, 48, 48, 52, 54,
+ 56, 58, 60, 63, 64, 67, 67, 71, 71, 74, 75, 77, 79, 81, 84, 85, 90, 90,
+ 44, 43, 43, 42, 41, 42, 43, 43, 43, 44, 48, 48, 53, 54, 57, 58, 60, 64,
+ 64, 67, 67, 71, 72, 75, 76, 78, 80, 82, 85, 86, 91, 91, 53, 51, 51, 50,
+ 49, 49, 50, 49, 49, 50, 54, 54, 59, 60, 63, 65, 67, 71, 72, 76, 76, 81,
+ 82, 85, 87, 89, 92, 94, 97, 98, 104, 104, 53, 51, 51, 50, 49, 49, 50,
+ 49, 49, 50, 54, 54, 59, 60, 63, 65, 67, 71, 72, 76, 76, 81, 82, 85, 87,
+ 89, 92, 94, 97, 98, 104, 104, 62, 60, 59, 58, 57, 57, 57, 56, 56, 56,
+ 61, 61, 65, 66, 69, 71, 74, 78, 79, 83, 83, 89, 90, 94, 95, 98, 102,
+ 103, 108, 108, 115, 115, 65, 62, 62, 60, 59, 59, 59, 59, 58, 58, 63, 63,
+ 67, 68, 71, 73, 76, 79, 81, 85, 85, 91, 92, 96, 98, 101, 105, 106, 111,
+ 111, 118, 118, 73, 70, 69, 67, 66, 66, 65, 65, 64, 64, 69, 69, 73, 74,
+ 77, 79, 81, 85, 86, 91, 91, 98, 99, 103, 105, 108, 112, 114, 119, 119,
+ 127, 127, 79, 75, 75, 73, 72, 71, 71, 70, 69, 69, 73, 73, 77, 78, 81,
+ 84, 86, 90, 91, 96, 96, 103, 103, 108, 110, 114, 118, 120, 125, 125,
+ 133, 133],
+ /* Size 4x16 */
+ [31, 34, 44, 65, 32, 34, 43, 62, 32, 33, 41, 59, 32, 35, 43, 59, 32, 37,
+ 43, 58, 34, 39, 48, 63, 34, 42, 53, 67, 36, 44, 57, 71, 39, 46, 60, 76,
+ 42, 48, 64, 81, 45, 51, 67, 85, 50, 54, 72, 92, 54, 58, 76, 98, 60, 63,
+ 80, 105, 66, 68, 85, 111, 73, 74, 91, 118],
+ /* Size 16x4 */
+ [31, 32, 32, 32, 32, 34, 34, 36, 39, 42, 45, 50, 54, 60, 66, 73, 34, 34,
+ 33, 35, 37, 39, 42, 44, 46, 48, 51, 54, 58, 63, 68, 74, 44, 43, 41, 43,
+ 43, 48, 53, 57, 60, 64, 67, 72, 76, 80, 85, 91, 65, 62, 59, 59, 58, 63,
+ 67, 71, 76, 81, 85, 92, 98, 105, 111, 118],
+ /* Size 8x32 */
+ [32, 31, 32, 36, 44, 53, 62, 73, 31, 32, 32, 35, 42, 51, 60, 70, 31, 32,
+ 32, 35, 42, 51, 59, 69, 31, 32, 32, 35, 41, 50, 58, 67, 31, 32, 33, 34,
+ 41, 49, 57, 66, 31, 32, 33, 35, 41, 49, 57, 66, 32, 32, 34, 36, 42, 50,
+ 57, 65, 32, 32, 34, 37, 42, 49, 56, 65, 32, 33, 35, 38, 42, 49, 56, 64,
+ 32, 33, 35, 39, 43, 50, 56, 64, 34, 34, 37, 42, 48, 54, 61, 69, 34, 34,
+ 37, 42, 48, 54, 61, 69, 35, 34, 38, 47, 52, 59, 65, 73, 36, 34, 38, 48,
+ 54, 60, 66, 74, 38, 36, 40, 49, 56, 63, 69, 77, 39, 37, 40, 50, 58, 65,
+ 71, 79, 41, 39, 41, 51, 60, 67, 74, 81, 44, 41, 43, 53, 63, 71, 78, 85,
+ 44, 42, 43, 54, 64, 72, 79, 86, 48, 45, 46, 56, 67, 76, 83, 91, 48, 45,
+ 46, 56, 67, 76, 83, 91, 53, 49, 49, 59, 71, 81, 89, 98, 53, 49, 50, 60,
+ 71, 82, 90, 99, 57, 52, 52, 62, 74, 85, 94, 103, 58, 54, 54, 63, 75, 87,
+ 95, 105, 61, 57, 56, 66, 77, 89, 98, 108, 65, 60, 58, 68, 79, 92, 102,
+ 112, 67, 61, 60, 69, 81, 94, 103, 114, 71, 65, 63, 73, 84, 97, 108, 119,
+ 72, 66, 64, 73, 85, 98, 108, 119, 79, 72, 70, 79, 90, 104, 115, 127, 79,
+ 72, 70, 79, 90, 104, 115, 127],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 31, 31, 32, 32, 32, 32, 34, 34, 35, 36, 38, 39, 41, 44,
+ 44, 48, 48, 53, 53, 57, 58, 61, 65, 67, 71, 72, 79, 79, 31, 32, 32, 32,
+ 32, 32, 32, 32, 33, 33, 34, 34, 34, 34, 36, 37, 39, 41, 42, 45, 45, 49,
+ 49, 52, 54, 57, 60, 61, 65, 66, 72, 72, 32, 32, 32, 32, 33, 33, 34, 34,
+ 35, 35, 37, 37, 38, 38, 40, 40, 41, 43, 43, 46, 46, 49, 50, 52, 54, 56,
+ 58, 60, 63, 64, 70, 70, 36, 35, 35, 35, 34, 35, 36, 37, 38, 39, 42, 42,
+ 47, 48, 49, 50, 51, 53, 54, 56, 56, 59, 60, 62, 63, 66, 68, 69, 73, 73,
+ 79, 79, 44, 42, 42, 41, 41, 41, 42, 42, 42, 43, 48, 48, 52, 54, 56, 58,
+ 60, 63, 64, 67, 67, 71, 71, 74, 75, 77, 79, 81, 84, 85, 90, 90, 53, 51,
+ 51, 50, 49, 49, 50, 49, 49, 50, 54, 54, 59, 60, 63, 65, 67, 71, 72, 76,
+ 76, 81, 82, 85, 87, 89, 92, 94, 97, 98, 104, 104, 62, 60, 59, 58, 57,
+ 57, 57, 56, 56, 56, 61, 61, 65, 66, 69, 71, 74, 78, 79, 83, 83, 89, 90,
+ 94, 95, 98, 102, 103, 108, 108, 115, 115, 73, 70, 69, 67, 66, 66, 65,
+ 65, 64, 64, 69, 69, 73, 74, 77, 79, 81, 85, 86, 91, 91, 98, 99, 103,
+ 105, 108, 112, 114, 119, 119, 127, 127]],
+ [ /* Chroma */
+ /* Size 4x4 */
+ [31, 42, 47, 53, 42, 48, 50, 54, 47, 50, 61, 67, 53, 54, 67, 78],
+ /* Size 8x8 */
+ [31, 32, 38, 48, 47, 50, 53, 57, 32, 35, 42, 47, 45, 47, 50, 54, 38, 42,
+ 47, 48, 45, 47, 49, 52, 48, 47, 48, 53, 53, 54, 56, 58, 47, 45, 45, 53,
+ 58, 61, 63, 65, 50, 47, 47, 54, 61, 66, 69, 72, 53, 50, 49, 56, 63, 69,
+ 73, 77, 57, 54, 52, 58, 65, 72, 77, 82],
+ /* Size 16x16 */
+ [32, 31, 30, 33, 36, 41, 47, 49, 49, 49, 50, 52, 54, 57, 60, 63, 31, 31,
+ 31, 34, 38, 42, 46, 47, 47, 47, 48, 50, 52, 54, 57, 60, 30, 31, 32, 35,
+ 40, 42, 45, 46, 45, 45, 46, 47, 49, 52, 54, 57, 33, 34, 35, 39, 43, 45,
+ 47, 46, 46, 45, 46, 47, 49, 51, 53, 56, 36, 38, 40, 43, 47, 47, 47, 47,
+ 46, 45, 46, 47, 48, 50, 52, 54, 41, 42, 42, 45, 47, 48, 50, 50, 49, 49,
+ 50, 50, 52, 53, 55, 57, 47, 46, 45, 47, 47, 50, 52, 52, 52, 52, 53, 53,
+ 55, 56, 58, 60, 49, 47, 46, 46, 47, 50, 52, 53, 54, 55, 55, 56, 57, 58,
+ 60, 62, 49, 47, 45, 46, 46, 49, 52, 54, 55, 57, 58, 59, 60, 61, 63, 65,
+ 49, 47, 45, 45, 45, 49, 52, 55, 57, 59, 60, 61, 63, 64, 66, 68, 50, 48,
+ 46, 46, 46, 50, 53, 55, 58, 60, 61, 63, 65, 67, 68, 71, 52, 50, 47, 47,
+ 47, 50, 53, 56, 59, 61, 63, 66, 68, 70, 72, 75, 54, 52, 49, 49, 48, 52,
+ 55, 57, 60, 63, 65, 68, 71, 73, 75, 78, 57, 54, 52, 51, 50, 53, 56, 58,
+ 61, 64, 67, 70, 73, 76, 79, 82, 60, 57, 54, 53, 52, 55, 58, 60, 63, 66,
+ 68, 72, 75, 79, 82, 85, 63, 60, 57, 56, 54, 57, 60, 62, 65, 68, 71, 75,
+ 78, 82, 85, 89],
+ /* Size 32x32 */
+ [32, 31, 31, 30, 30, 32, 33, 34, 36, 37, 41, 41, 47, 49, 49, 48, 49, 49,
+ 49, 50, 50, 52, 52, 54, 54, 56, 57, 58, 60, 60, 63, 63, 31, 31, 31, 31,
+ 31, 32, 34, 35, 38, 38, 42, 42, 46, 48, 47, 47, 47, 47, 47, 48, 48, 50,
+ 50, 51, 52, 53, 54, 55, 57, 57, 60, 60, 31, 31, 31, 31, 31, 33, 34, 35,
+ 38, 39, 42, 42, 46, 47, 47, 47, 47, 47, 47, 48, 48, 49, 50, 51, 52, 53,
+ 54, 55, 57, 57, 60, 60, 30, 31, 31, 31, 31, 33, 35, 36, 39, 40, 42, 42,
+ 46, 47, 46, 46, 46, 45, 46, 47, 47, 48, 48, 50, 50, 51, 52, 53, 55, 55,
+ 58, 58, 30, 31, 31, 31, 32, 33, 35, 36, 40, 40, 42, 42, 45, 46, 46, 45,
+ 45, 45, 45, 46, 46, 47, 47, 49, 49, 51, 52, 52, 54, 54, 57, 57, 32, 32,
+ 33, 33, 33, 35, 37, 38, 41, 42, 43, 43, 46, 47, 46, 46, 45, 45, 45, 46,
+ 46, 47, 47, 49, 49, 50, 51, 52, 54, 54, 57, 57, 33, 34, 34, 35, 35, 37,
+ 39, 40, 43, 43, 45, 45, 47, 47, 46, 46, 46, 45, 45, 46, 46, 47, 47, 49,
+ 49, 50, 51, 52, 53, 54, 56, 56, 34, 35, 35, 36, 36, 38, 40, 41, 44, 44,
+ 45, 45, 47, 47, 47, 46, 46, 45, 45, 46, 46, 47, 47, 48, 49, 50, 51, 51,
+ 53, 53, 55, 55, 36, 38, 38, 39, 40, 41, 43, 44, 47, 47, 47, 47, 47, 48,
+ 47, 46, 46, 45, 45, 46, 46, 46, 47, 48, 48, 49, 50, 50, 52, 52, 54, 54,
+ 37, 38, 39, 40, 40, 42, 43, 44, 47, 47, 47, 47, 48, 48, 47, 47, 46, 45,
+ 46, 46, 46, 47, 47, 48, 48, 49, 50, 51, 52, 52, 55, 55, 41, 42, 42, 42,
+ 42, 43, 45, 45, 47, 47, 48, 48, 50, 50, 50, 49, 49, 49, 49, 50, 50, 50,
+ 50, 51, 52, 52, 53, 54, 55, 55, 57, 57, 41, 42, 42, 42, 42, 43, 45, 45,
+ 47, 47, 48, 48, 50, 50, 50, 49, 49, 49, 49, 50, 50, 50, 50, 51, 52, 52,
+ 53, 54, 55, 55, 57, 57, 47, 46, 46, 46, 45, 46, 47, 47, 47, 48, 50, 50,
+ 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 54, 55, 55, 56, 56, 58, 58,
+ 60, 60, 49, 48, 47, 47, 46, 47, 47, 47, 48, 48, 50, 50, 52, 53, 53, 53,
+ 53, 53, 53, 54, 54, 54, 54, 55, 55, 56, 56, 57, 58, 58, 60, 60, 49, 47,
+ 47, 46, 46, 46, 46, 47, 47, 47, 50, 50, 52, 53, 53, 54, 54, 55, 55, 55,
+ 55, 56, 56, 57, 57, 58, 58, 59, 60, 60, 62, 62, 48, 47, 47, 46, 45, 46,
+ 46, 46, 46, 47, 49, 49, 52, 53, 54, 54, 55, 55, 56, 56, 56, 57, 57, 58,
+ 58, 59, 60, 60, 61, 62, 63, 63, 49, 47, 47, 46, 45, 45, 46, 46, 46, 46,
+ 49, 49, 52, 53, 54, 55, 55, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62,
+ 63, 63, 65, 65, 49, 47, 47, 45, 45, 45, 45, 45, 45, 45, 49, 49, 52, 53,
+ 55, 55, 57, 58, 59, 60, 60, 61, 61, 62, 62, 63, 63, 64, 65, 65, 67, 67,
+ 49, 47, 47, 46, 45, 45, 45, 45, 45, 46, 49, 49, 52, 53, 55, 56, 57, 59,
+ 59, 60, 60, 61, 61, 62, 63, 63, 64, 65, 66, 66, 68, 68, 50, 48, 48, 47,
+ 46, 46, 46, 46, 46, 46, 50, 50, 53, 54, 55, 56, 58, 60, 60, 61, 61, 63,
+ 63, 65, 65, 66, 67, 67, 68, 69, 71, 71, 50, 48, 48, 47, 46, 46, 46, 46,
+ 46, 46, 50, 50, 53, 54, 55, 56, 58, 60, 60, 61, 61, 63, 63, 65, 65, 66,
+ 67, 67, 68, 69, 71, 71, 52, 50, 49, 48, 47, 47, 47, 47, 46, 47, 50, 50,
+ 53, 54, 56, 57, 59, 61, 61, 63, 63, 66, 66, 67, 68, 69, 70, 71, 72, 72,
+ 74, 74, 52, 50, 50, 48, 47, 47, 47, 47, 47, 47, 50, 50, 53, 54, 56, 57,
+ 59, 61, 61, 63, 63, 66, 66, 68, 68, 69, 70, 71, 72, 73, 75, 75, 54, 51,
+ 51, 50, 49, 49, 49, 48, 48, 48, 51, 51, 54, 55, 57, 58, 60, 62, 62, 65,
+ 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 77, 54, 52, 52, 50, 49, 49,
+ 49, 49, 48, 48, 52, 52, 55, 55, 57, 58, 60, 62, 63, 65, 65, 68, 68, 70,
+ 71, 72, 73, 74, 75, 76, 78, 78, 56, 53, 53, 51, 51, 50, 50, 50, 49, 49,
+ 52, 52, 55, 56, 58, 59, 61, 63, 63, 66, 66, 69, 69, 71, 72, 73, 75, 75,
+ 77, 77, 80, 80, 57, 54, 54, 52, 52, 51, 51, 51, 50, 50, 53, 53, 56, 56,
+ 58, 60, 61, 63, 64, 67, 67, 70, 70, 72, 73, 75, 76, 77, 79, 79, 82, 82,
+ 58, 55, 55, 53, 52, 52, 52, 51, 50, 51, 54, 54, 56, 57, 59, 60, 62, 64,
+ 65, 67, 67, 71, 71, 73, 74, 75, 77, 78, 80, 80, 83, 83, 60, 57, 57, 55,
+ 54, 54, 53, 53, 52, 52, 55, 55, 58, 58, 60, 61, 63, 65, 66, 68, 68, 72,
+ 72, 74, 75, 77, 79, 80, 82, 82, 85, 85, 60, 57, 57, 55, 54, 54, 54, 53,
+ 52, 52, 55, 55, 58, 58, 60, 62, 63, 65, 66, 69, 69, 72, 73, 75, 76, 77,
+ 79, 80, 82, 82, 85, 85, 63, 60, 60, 58, 57, 57, 56, 55, 54, 55, 57, 57,
+ 60, 60, 62, 63, 65, 67, 68, 71, 71, 74, 75, 77, 78, 80, 82, 83, 85, 85,
+ 89, 89, 63, 60, 60, 58, 57, 57, 56, 55, 54, 55, 57, 57, 60, 60, 62, 63,
+ 65, 67, 68, 71, 71, 74, 75, 77, 78, 80, 82, 83, 85, 85, 89, 89],
+ /* Size 4x8 */
+ [31, 42, 47, 54, 33, 44, 45, 51, 40, 47, 46, 50, 47, 50, 54, 57, 45, 49,
+ 59, 64, 48, 50, 61, 70, 51, 52, 63, 75, 55, 55, 66, 79],
+ /* Size 8x4 */
+ [31, 33, 40, 47, 45, 48, 51, 55, 42, 44, 47, 50, 49, 50, 52, 55, 47, 45,
+ 46, 54, 59, 61, 63, 66, 54, 51, 50, 57, 64, 70, 75, 79],
+ /* Size 8x16 */
+ [32, 31, 37, 48, 49, 52, 56, 61, 31, 31, 38, 47, 47, 50, 53, 57, 30, 32,
+ 40, 46, 45, 48, 51, 55, 33, 36, 43, 47, 46, 47, 50, 54, 37, 40, 47, 47,
+ 45, 47, 49, 52, 42, 43, 47, 50, 49, 50, 53, 56, 47, 46, 48, 52, 53, 53,
+ 55, 58, 48, 46, 47, 53, 55, 56, 58, 61, 48, 45, 46, 53, 57, 59, 61, 63,
+ 49, 45, 46, 53, 58, 62, 64, 66, 50, 46, 46, 54, 59, 64, 66, 69, 52, 48,
+ 47, 54, 61, 66, 70, 73, 54, 50, 49, 55, 62, 68, 72, 76, 57, 52, 50, 56,
+ 64, 70, 75, 79, 60, 54, 52, 58, 65, 72, 77, 82, 63, 57, 55, 60, 67, 75,
+ 80, 86],
+ /* Size 16x8 */
+ [32, 31, 30, 33, 37, 42, 47, 48, 48, 49, 50, 52, 54, 57, 60, 63, 31, 31,
+ 32, 36, 40, 43, 46, 46, 45, 45, 46, 48, 50, 52, 54, 57, 37, 38, 40, 43,
+ 47, 47, 48, 47, 46, 46, 46, 47, 49, 50, 52, 55, 48, 47, 46, 47, 47, 50,
+ 52, 53, 53, 53, 54, 54, 55, 56, 58, 60, 49, 47, 45, 46, 45, 49, 53, 55,
+ 57, 58, 59, 61, 62, 64, 65, 67, 52, 50, 48, 47, 47, 50, 53, 56, 59, 62,
+ 64, 66, 68, 70, 72, 75, 56, 53, 51, 50, 49, 53, 55, 58, 61, 64, 66, 70,
+ 72, 75, 77, 80, 61, 57, 55, 54, 52, 56, 58, 61, 63, 66, 69, 73, 76, 79,
+ 82, 86],
+ /* Size 16x32 */
+ [32, 31, 31, 35, 37, 42, 48, 48, 49, 49, 52, 52, 56, 57, 61, 63, 31, 31,
+ 31, 36, 38, 42, 47, 47, 47, 47, 50, 50, 54, 54, 58, 60, 31, 31, 31, 36,
+ 38, 42, 47, 47, 47, 47, 50, 50, 53, 54, 57, 60, 30, 32, 32, 37, 39, 42,
+ 46, 46, 46, 46, 48, 48, 52, 52, 56, 58, 30, 32, 32, 37, 40, 42, 46, 46,
+ 45, 45, 48, 48, 51, 52, 55, 57, 32, 33, 34, 39, 41, 44, 46, 46, 45, 45,
+ 48, 48, 51, 51, 54, 57, 33, 35, 36, 40, 43, 45, 47, 46, 46, 46, 47, 47,
+ 50, 51, 54, 56, 34, 37, 37, 42, 44, 45, 47, 47, 45, 46, 47, 47, 50, 51,
+ 53, 55, 37, 40, 40, 45, 47, 47, 47, 47, 45, 46, 47, 47, 49, 50, 52, 54,
+ 37, 40, 40, 45, 47, 47, 48, 47, 46, 46, 47, 47, 49, 50, 53, 55, 42, 43,
+ 43, 46, 47, 48, 50, 50, 49, 49, 50, 50, 53, 53, 56, 57, 42, 43, 43, 46,
+ 47, 48, 50, 50, 49, 49, 50, 50, 53, 53, 56, 57, 47, 46, 46, 47, 48, 50,
+ 52, 52, 53, 53, 53, 53, 55, 56, 58, 60, 49, 47, 46, 47, 48, 50, 53, 53,
+ 53, 54, 54, 54, 56, 57, 59, 60, 48, 46, 46, 47, 47, 50, 53, 53, 55, 55,
+ 56, 56, 58, 58, 61, 62, 48, 46, 46, 46, 47, 50, 53, 54, 56, 56, 57, 57,
+ 59, 60, 62, 64, 48, 46, 45, 46, 46, 49, 53, 54, 57, 57, 59, 59, 61, 61,
+ 63, 65, 49, 45, 45, 45, 46, 49, 53, 55, 58, 59, 61, 61, 63, 64, 66, 67,
+ 49, 46, 45, 46, 46, 49, 53, 55, 58, 59, 62, 62, 64, 64, 66, 68, 50, 47,
+ 46, 46, 46, 50, 54, 55, 59, 60, 64, 64, 66, 67, 69, 71, 50, 47, 46, 46,
+ 46, 50, 54, 55, 59, 60, 64, 64, 66, 67, 69, 71, 52, 48, 48, 47, 47, 50,
+ 54, 56, 61, 61, 66, 66, 69, 70, 72, 74, 52, 48, 48, 47, 47, 50, 54, 56,
+ 61, 61, 66, 66, 70, 71, 73, 75, 53, 50, 49, 48, 48, 51, 55, 57, 62, 62,
+ 68, 68, 71, 72, 75, 77, 54, 50, 50, 49, 49, 52, 55, 57, 62, 63, 68, 68,
+ 72, 73, 76, 78, 55, 51, 51, 50, 49, 52, 56, 58, 63, 63, 69, 69, 74, 75,
+ 78, 80, 57, 52, 52, 51, 50, 53, 56, 58, 64, 64, 70, 70, 75, 76, 79, 82,
+ 58, 53, 53, 51, 51, 54, 57, 59, 64, 65, 71, 71, 76, 77, 80, 83, 60, 55,
+ 54, 53, 52, 55, 58, 60, 65, 66, 72, 72, 77, 79, 82, 85, 60, 55, 55, 53,
+ 53, 55, 59, 60, 65, 66, 73, 73, 78, 79, 83, 85, 63, 58, 57, 56, 55, 58,
+ 60, 62, 67, 68, 75, 75, 80, 82, 86, 89, 63, 58, 57, 56, 55, 58, 60, 62,
+ 67, 68, 75, 75, 80, 82, 86, 89],
+ /* Size 32x16 */
+ [32, 31, 31, 30, 30, 32, 33, 34, 37, 37, 42, 42, 47, 49, 48, 48, 48, 49,
+ 49, 50, 50, 52, 52, 53, 54, 55, 57, 58, 60, 60, 63, 63, 31, 31, 31, 32,
+ 32, 33, 35, 37, 40, 40, 43, 43, 46, 47, 46, 46, 46, 45, 46, 47, 47, 48,
+ 48, 50, 50, 51, 52, 53, 55, 55, 58, 58, 31, 31, 31, 32, 32, 34, 36, 37,
+ 40, 40, 43, 43, 46, 46, 46, 46, 45, 45, 45, 46, 46, 48, 48, 49, 50, 51,
+ 52, 53, 54, 55, 57, 57, 35, 36, 36, 37, 37, 39, 40, 42, 45, 45, 46, 46,
+ 47, 47, 47, 46, 46, 45, 46, 46, 46, 47, 47, 48, 49, 50, 51, 51, 53, 53,
+ 56, 56, 37, 38, 38, 39, 40, 41, 43, 44, 47, 47, 47, 47, 48, 48, 47, 47,
+ 46, 46, 46, 46, 46, 47, 47, 48, 49, 49, 50, 51, 52, 53, 55, 55, 42, 42,
+ 42, 42, 42, 44, 45, 45, 47, 47, 48, 48, 50, 50, 50, 50, 49, 49, 49, 50,
+ 50, 50, 50, 51, 52, 52, 53, 54, 55, 55, 58, 58, 48, 47, 47, 46, 46, 46,
+ 47, 47, 47, 48, 50, 50, 52, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55,
+ 55, 56, 56, 57, 58, 59, 60, 60, 48, 47, 47, 46, 46, 46, 46, 47, 47, 47,
+ 50, 50, 52, 53, 53, 54, 54, 55, 55, 55, 55, 56, 56, 57, 57, 58, 58, 59,
+ 60, 60, 62, 62, 49, 47, 47, 46, 45, 45, 46, 45, 45, 46, 49, 49, 53, 53,
+ 55, 56, 57, 58, 58, 59, 59, 61, 61, 62, 62, 63, 64, 64, 65, 65, 67, 67,
+ 49, 47, 47, 46, 45, 45, 46, 46, 46, 46, 49, 49, 53, 54, 55, 56, 57, 59,
+ 59, 60, 60, 61, 61, 62, 63, 63, 64, 65, 66, 66, 68, 68, 52, 50, 50, 48,
+ 48, 48, 47, 47, 47, 47, 50, 50, 53, 54, 56, 57, 59, 61, 62, 64, 64, 66,
+ 66, 68, 68, 69, 70, 71, 72, 73, 75, 75, 52, 50, 50, 48, 48, 48, 47, 47,
+ 47, 47, 50, 50, 53, 54, 56, 57, 59, 61, 62, 64, 64, 66, 66, 68, 68, 69,
+ 70, 71, 72, 73, 75, 75, 56, 54, 53, 52, 51, 51, 50, 50, 49, 49, 53, 53,
+ 55, 56, 58, 59, 61, 63, 64, 66, 66, 69, 70, 71, 72, 74, 75, 76, 77, 78,
+ 80, 80, 57, 54, 54, 52, 52, 51, 51, 51, 50, 50, 53, 53, 56, 57, 58, 60,
+ 61, 64, 64, 67, 67, 70, 71, 72, 73, 75, 76, 77, 79, 79, 82, 82, 61, 58,
+ 57, 56, 55, 54, 54, 53, 52, 53, 56, 56, 58, 59, 61, 62, 63, 66, 66, 69,
+ 69, 72, 73, 75, 76, 78, 79, 80, 82, 83, 86, 86, 63, 60, 60, 58, 57, 57,
+ 56, 55, 54, 55, 57, 57, 60, 60, 62, 64, 65, 67, 68, 71, 71, 74, 75, 77,
+ 78, 80, 82, 83, 85, 85, 89, 89],
+ /* Size 4x16 */
+ [31, 42, 49, 57, 31, 42, 47, 54, 32, 42, 45, 52, 35, 45, 46, 51, 40, 47,
+ 46, 50, 43, 48, 49, 53, 46, 50, 53, 56, 46, 50, 55, 58, 46, 49, 57, 61,
+ 46, 49, 59, 64, 47, 50, 60, 67, 48, 50, 61, 71, 50, 52, 63, 73, 52, 53,
+ 64, 76, 55, 55, 66, 79, 58, 58, 68, 82],
+ /* Size 16x4 */
+ [31, 31, 32, 35, 40, 43, 46, 46, 46, 46, 47, 48, 50, 52, 55, 58, 42, 42,
+ 42, 45, 47, 48, 50, 50, 49, 49, 50, 50, 52, 53, 55, 58, 49, 47, 45, 46,
+ 46, 49, 53, 55, 57, 59, 60, 61, 63, 64, 66, 68, 57, 54, 52, 51, 50, 53,
+ 56, 58, 61, 64, 67, 71, 73, 76, 79, 82],
+ /* Size 8x32 */
+ [32, 31, 37, 48, 49, 52, 56, 61, 31, 31, 38, 47, 47, 50, 54, 58, 31, 31,
+ 38, 47, 47, 50, 53, 57, 30, 32, 39, 46, 46, 48, 52, 56, 30, 32, 40, 46,
+ 45, 48, 51, 55, 32, 34, 41, 46, 45, 48, 51, 54, 33, 36, 43, 47, 46, 47,
+ 50, 54, 34, 37, 44, 47, 45, 47, 50, 53, 37, 40, 47, 47, 45, 47, 49, 52,
+ 37, 40, 47, 48, 46, 47, 49, 53, 42, 43, 47, 50, 49, 50, 53, 56, 42, 43,
+ 47, 50, 49, 50, 53, 56, 47, 46, 48, 52, 53, 53, 55, 58, 49, 46, 48, 53,
+ 53, 54, 56, 59, 48, 46, 47, 53, 55, 56, 58, 61, 48, 46, 47, 53, 56, 57,
+ 59, 62, 48, 45, 46, 53, 57, 59, 61, 63, 49, 45, 46, 53, 58, 61, 63, 66,
+ 49, 45, 46, 53, 58, 62, 64, 66, 50, 46, 46, 54, 59, 64, 66, 69, 50, 46,
+ 46, 54, 59, 64, 66, 69, 52, 48, 47, 54, 61, 66, 69, 72, 52, 48, 47, 54,
+ 61, 66, 70, 73, 53, 49, 48, 55, 62, 68, 71, 75, 54, 50, 49, 55, 62, 68,
+ 72, 76, 55, 51, 49, 56, 63, 69, 74, 78, 57, 52, 50, 56, 64, 70, 75, 79,
+ 58, 53, 51, 57, 64, 71, 76, 80, 60, 54, 52, 58, 65, 72, 77, 82, 60, 55,
+ 53, 59, 65, 73, 78, 83, 63, 57, 55, 60, 67, 75, 80, 86, 63, 57, 55, 60,
+ 67, 75, 80, 86],
+ /* Size 32x8 */
+ [32, 31, 31, 30, 30, 32, 33, 34, 37, 37, 42, 42, 47, 49, 48, 48, 48, 49,
+ 49, 50, 50, 52, 52, 53, 54, 55, 57, 58, 60, 60, 63, 63, 31, 31, 31, 32,
+ 32, 34, 36, 37, 40, 40, 43, 43, 46, 46, 46, 46, 45, 45, 45, 46, 46, 48,
+ 48, 49, 50, 51, 52, 53, 54, 55, 57, 57, 37, 38, 38, 39, 40, 41, 43, 44,
+ 47, 47, 47, 47, 48, 48, 47, 47, 46, 46, 46, 46, 46, 47, 47, 48, 49, 49,
+ 50, 51, 52, 53, 55, 55, 48, 47, 47, 46, 46, 46, 47, 47, 47, 48, 50, 50,
+ 52, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 56, 56, 57, 58, 59,
+ 60, 60, 49, 47, 47, 46, 45, 45, 46, 45, 45, 46, 49, 49, 53, 53, 55, 56,
+ 57, 58, 58, 59, 59, 61, 61, 62, 62, 63, 64, 64, 65, 65, 67, 67, 52, 50,
+ 50, 48, 48, 48, 47, 47, 47, 47, 50, 50, 53, 54, 56, 57, 59, 61, 62, 64,
+ 64, 66, 66, 68, 68, 69, 70, 71, 72, 73, 75, 75, 56, 54, 53, 52, 51, 51,
+ 50, 50, 49, 49, 53, 53, 55, 56, 58, 59, 61, 63, 64, 66, 66, 69, 70, 71,
+ 72, 74, 75, 76, 77, 78, 80, 80, 61, 58, 57, 56, 55, 54, 54, 53, 52, 53,
+ 56, 56, 58, 59, 61, 62, 63, 66, 66, 69, 69, 72, 73, 75, 76, 78, 79, 80,
+ 82, 83, 86, 86]]
+ ],
+ [
+ [ /* Luma */
+ /* Size 4x4 */
+ [32, 33, 42, 55, 33, 38, 46, 57, 42, 46, 63, 75, 55, 57, 75, 92],
+ /* Size 8x8 */
+ [31, 32, 32, 34, 38, 46, 52, 63, 32, 32, 32, 34, 37, 44, 49, 59, 32, 32,
+ 35, 37, 40, 45, 49, 58, 34, 34, 37, 42, 47, 52, 56, 65, 38, 37, 40, 47,
+ 54, 60, 65, 73, 46, 44, 45, 52, 60, 69, 75, 84, 52, 49, 49, 56, 65, 75,
+ 82, 92, 63, 59, 58, 65, 73, 84, 92, 105],
+ /* Size 16x16 */
+ [32, 31, 31, 31, 32, 32, 34, 36, 38, 41, 44, 48, 54, 58, 61, 65, 31, 32,
+ 32, 32, 32, 32, 34, 35, 38, 40, 42, 46, 51, 55, 58, 62, 31, 32, 32, 32,
+ 32, 32, 33, 34, 37, 38, 41, 44, 49, 53, 56, 59, 31, 32, 32, 33, 33, 33,
+ 35, 36, 38, 40, 42, 45, 49, 53, 56, 59, 32, 32, 32, 33, 34, 34, 36, 37,
+ 39, 40, 42, 45, 49, 53, 55, 59, 32, 32, 32, 33, 34, 35, 37, 38, 40, 41,
+ 42, 46, 49, 52, 55, 58, 34, 34, 33, 35, 36, 37, 39, 42, 44, 46, 47, 51,
+ 54, 57, 60, 63, 36, 35, 34, 36, 37, 38, 42, 48, 50, 52, 54, 57, 60, 63,
+ 65, 68, 38, 38, 37, 38, 39, 40, 44, 50, 52, 54, 57, 60, 64, 67, 69, 72,
+ 41, 40, 38, 40, 40, 41, 46, 52, 54, 57, 60, 63, 67, 70, 73, 75, 44, 42,
+ 41, 42, 42, 42, 47, 54, 57, 60, 63, 67, 71, 74, 77, 79, 48, 46, 44, 45,
+ 45, 46, 51, 57, 60, 63, 67, 71, 76, 79, 82, 85, 54, 51, 49, 49, 49, 49,
+ 54, 60, 64, 67, 71, 76, 82, 86, 89, 92, 58, 55, 53, 53, 53, 52, 57, 63,
+ 67, 70, 74, 79, 86, 90, 93, 97, 61, 58, 56, 56, 55, 55, 60, 65, 69, 73,
+ 77, 82, 89, 93, 97, 101, 65, 62, 59, 59, 59, 58, 63, 68, 72, 75, 79, 85,
+ 92, 97, 101, 105],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 33, 34, 34, 36, 36, 38, 39,
+ 41, 44, 44, 47, 48, 50, 54, 54, 58, 59, 61, 65, 65, 70, 31, 31, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 35, 35, 38, 38, 40, 42, 42, 46,
+ 47, 49, 52, 52, 56, 57, 59, 63, 63, 67, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 33, 34, 34, 35, 35, 38, 38, 40, 42, 42, 45, 46, 48, 51, 51,
+ 55, 56, 58, 62, 62, 67, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33,
+ 34, 34, 35, 35, 37, 38, 39, 42, 42, 45, 45, 47, 50, 50, 54, 55, 57, 61,
+ 61, 65, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 34,
+ 37, 37, 38, 41, 41, 44, 44, 46, 49, 49, 53, 54, 56, 59, 59, 64, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 34, 37, 37, 38, 41,
+ 41, 44, 44, 46, 49, 49, 53, 54, 56, 59, 59, 64, 31, 32, 32, 32, 32, 32,
+ 33, 33, 33, 33, 33, 34, 35, 35, 36, 36, 38, 39, 40, 42, 42, 44, 45, 47,
+ 49, 49, 53, 54, 56, 59, 59, 63, 31, 32, 32, 32, 32, 32, 33, 33, 33, 34,
+ 34, 35, 35, 36, 36, 36, 38, 39, 40, 42, 42, 45, 45, 47, 50, 50, 53, 54,
+ 56, 59, 59, 63, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 34, 35, 36, 36,
+ 37, 37, 39, 39, 40, 42, 42, 45, 45, 47, 49, 49, 53, 54, 55, 59, 59, 63,
+ 32, 32, 32, 32, 32, 32, 33, 34, 34, 35, 35, 36, 37, 37, 38, 38, 40, 40,
+ 41, 42, 42, 45, 46, 47, 49, 49, 52, 53, 55, 58, 58, 62, 32, 32, 32, 32,
+ 32, 32, 33, 34, 34, 35, 35, 36, 37, 37, 38, 38, 40, 40, 41, 42, 42, 45,
+ 46, 47, 49, 49, 52, 53, 55, 58, 58, 62, 33, 33, 33, 33, 33, 33, 34, 35,
+ 35, 36, 36, 38, 39, 40, 42, 42, 43, 44, 45, 46, 46, 49, 50, 51, 53, 53,
+ 56, 57, 59, 62, 62, 66, 34, 34, 34, 34, 33, 33, 35, 35, 36, 37, 37, 39,
+ 39, 41, 42, 42, 44, 45, 46, 47, 47, 50, 51, 52, 54, 54, 57, 58, 60, 63,
+ 63, 67, 34, 34, 34, 34, 34, 34, 35, 36, 36, 37, 37, 40, 41, 42, 45, 45,
+ 46, 47, 48, 50, 50, 52, 53, 54, 56, 56, 59, 60, 62, 65, 65, 69, 36, 35,
+ 35, 35, 34, 34, 36, 36, 37, 38, 38, 42, 42, 45, 48, 48, 50, 50, 52, 54,
+ 54, 56, 57, 58, 60, 60, 63, 64, 65, 68, 68, 72, 36, 35, 35, 35, 34, 34,
+ 36, 36, 37, 38, 38, 42, 42, 45, 48, 48, 50, 50, 52, 54, 54, 56, 57, 58,
+ 60, 60, 63, 64, 65, 68, 68, 72, 38, 38, 38, 37, 37, 37, 38, 38, 39, 40,
+ 40, 43, 44, 46, 50, 50, 52, 53, 54, 57, 57, 59, 60, 61, 64, 64, 67, 68,
+ 69, 72, 72, 76, 39, 38, 38, 38, 37, 37, 39, 39, 39, 40, 40, 44, 45, 47,
+ 50, 50, 53, 54, 55, 58, 58, 60, 61, 62, 65, 65, 68, 69, 70, 73, 73, 77,
+ 41, 40, 40, 39, 38, 38, 40, 40, 40, 41, 41, 45, 46, 48, 52, 52, 54, 55,
+ 57, 60, 60, 62, 63, 65, 67, 67, 70, 71, 73, 75, 75, 79, 44, 42, 42, 42,
+ 41, 41, 42, 42, 42, 42, 42, 46, 47, 50, 54, 54, 57, 58, 60, 63, 63, 66,
+ 67, 68, 71, 71, 74, 75, 77, 79, 79, 83, 44, 42, 42, 42, 41, 41, 42, 42,
+ 42, 42, 42, 46, 47, 50, 54, 54, 57, 58, 60, 63, 63, 66, 67, 68, 71, 71,
+ 74, 75, 77, 79, 79, 83, 47, 46, 45, 45, 44, 44, 44, 45, 45, 45, 45, 49,
+ 50, 52, 56, 56, 59, 60, 62, 66, 66, 69, 70, 72, 75, 75, 78, 79, 81, 84,
+ 84, 88, 48, 47, 46, 45, 44, 44, 45, 45, 45, 46, 46, 50, 51, 53, 57, 57,
+ 60, 61, 63, 67, 67, 70, 71, 73, 76, 76, 79, 80, 82, 85, 85, 89, 50, 49,
+ 48, 47, 46, 46, 47, 47, 47, 47, 47, 51, 52, 54, 58, 58, 61, 62, 65, 68,
+ 68, 72, 73, 75, 78, 78, 82, 83, 85, 88, 88, 92, 54, 52, 51, 50, 49, 49,
+ 49, 50, 49, 49, 49, 53, 54, 56, 60, 60, 64, 65, 67, 71, 71, 75, 76, 78,
+ 82, 82, 86, 87, 89, 92, 92, 96, 54, 52, 51, 50, 49, 49, 49, 50, 49, 49,
+ 49, 53, 54, 56, 60, 60, 64, 65, 67, 71, 71, 75, 76, 78, 82, 82, 86, 87,
+ 89, 92, 92, 96, 58, 56, 55, 54, 53, 53, 53, 53, 53, 52, 52, 56, 57, 59,
+ 63, 63, 67, 68, 70, 74, 74, 78, 79, 82, 86, 86, 90, 91, 93, 97, 97, 101,
+ 59, 57, 56, 55, 54, 54, 54, 54, 54, 53, 53, 57, 58, 60, 64, 64, 68, 69,
+ 71, 75, 75, 79, 80, 83, 87, 87, 91, 92, 94, 98, 98, 102, 61, 59, 58, 57,
+ 56, 56, 56, 56, 55, 55, 55, 59, 60, 62, 65, 65, 69, 70, 73, 77, 77, 81,
+ 82, 85, 89, 89, 93, 94, 97, 101, 101, 105, 65, 63, 62, 61, 59, 59, 59,
+ 59, 59, 58, 58, 62, 63, 65, 68, 68, 72, 73, 75, 79, 79, 84, 85, 88, 92,
+ 92, 97, 98, 101, 105, 105, 109, 65, 63, 62, 61, 59, 59, 59, 59, 59, 58,
+ 58, 62, 63, 65, 68, 68, 72, 73, 75, 79, 79, 84, 85, 88, 92, 92, 97, 98,
+ 101, 105, 105, 109, 70, 67, 67, 65, 64, 64, 63, 63, 63, 62, 62, 66, 67,
+ 69, 72, 72, 76, 77, 79, 83, 83, 88, 89, 92, 96, 96, 101, 102, 105, 109,
+ 109, 114],
+ /* Size 4x8 */
+ [32, 32, 42, 56, 32, 33, 41, 53, 32, 35, 42, 52, 34, 37, 50, 59, 38, 40,
+ 58, 68, 44, 45, 66, 78, 50, 50, 71, 86, 61, 58, 79, 97],
+ /* Size 8x4 */
+ [32, 32, 32, 34, 38, 44, 50, 61, 32, 33, 35, 37, 40, 45, 50, 58, 42, 41,
+ 42, 50, 58, 66, 71, 79, 56, 53, 52, 59, 68, 78, 86, 97],
+ /* Size 8x16 */
+ [32, 31, 32, 35, 39, 44, 53, 65, 31, 32, 32, 35, 38, 42, 51, 62, 31, 32,
+ 33, 34, 37, 41, 49, 59, 31, 32, 34, 35, 38, 42, 49, 59, 32, 32, 34, 36,
+ 39, 42, 49, 58, 32, 33, 35, 37, 40, 42, 49, 58, 34, 34, 37, 41, 44, 48,
+ 54, 63, 36, 34, 38, 46, 50, 54, 60, 68, 38, 37, 40, 47, 52, 57, 64, 72,
+ 41, 39, 41, 49, 54, 60, 67, 76, 44, 41, 43, 51, 57, 63, 71, 79, 48, 45,
+ 46, 54, 60, 67, 76, 85, 53, 49, 50, 57, 64, 71, 82, 92, 57, 53, 53, 60,
+ 67, 74, 86, 97, 61, 56, 56, 63, 69, 77, 89, 100, 65, 60, 58, 66, 72, 79,
+ 92, 105],
+ /* Size 16x8 */
+ [32, 31, 31, 31, 32, 32, 34, 36, 38, 41, 44, 48, 53, 57, 61, 65, 31, 32,
+ 32, 32, 32, 33, 34, 34, 37, 39, 41, 45, 49, 53, 56, 60, 32, 32, 33, 34,
+ 34, 35, 37, 38, 40, 41, 43, 46, 50, 53, 56, 58, 35, 35, 34, 35, 36, 37,
+ 41, 46, 47, 49, 51, 54, 57, 60, 63, 66, 39, 38, 37, 38, 39, 40, 44, 50,
+ 52, 54, 57, 60, 64, 67, 69, 72, 44, 42, 41, 42, 42, 42, 48, 54, 57, 60,
+ 63, 67, 71, 74, 77, 79, 53, 51, 49, 49, 49, 49, 54, 60, 64, 67, 71, 76,
+ 82, 86, 89, 92, 65, 62, 59, 59, 58, 58, 63, 68, 72, 76, 79, 85, 92, 97,
+ 100, 105],
+ /* Size 16x32 */
+ [32, 31, 31, 31, 32, 32, 35, 36, 39, 44, 44, 51, 53, 58, 65, 65, 31, 32,
+ 32, 32, 32, 32, 35, 35, 38, 42, 42, 49, 52, 56, 63, 63, 31, 32, 32, 32,
+ 32, 32, 35, 35, 38, 42, 42, 49, 51, 55, 62, 62, 31, 32, 32, 32, 32, 32,
+ 34, 35, 37, 41, 41, 48, 50, 54, 61, 61, 31, 32, 32, 32, 33, 33, 34, 34,
+ 37, 41, 41, 47, 49, 53, 59, 59, 31, 32, 32, 32, 33, 33, 34, 34, 37, 41,
+ 41, 47, 49, 53, 59, 59, 31, 32, 32, 33, 34, 34, 35, 36, 38, 42, 42, 48,
+ 49, 53, 59, 59, 32, 32, 32, 33, 34, 34, 36, 36, 38, 42, 42, 48, 50, 53,
+ 59, 59, 32, 32, 32, 33, 34, 34, 36, 37, 39, 42, 42, 48, 49, 53, 58, 58,
+ 32, 32, 33, 34, 35, 35, 37, 38, 40, 42, 42, 48, 49, 52, 58, 58, 32, 32,
+ 33, 34, 35, 35, 37, 38, 40, 42, 42, 48, 49, 52, 58, 58, 33, 33, 33, 35,
+ 36, 36, 40, 41, 43, 46, 46, 52, 53, 56, 62, 62, 34, 34, 34, 35, 37, 37,
+ 41, 42, 44, 48, 48, 53, 54, 57, 63, 63, 34, 34, 34, 35, 37, 37, 43, 44,
+ 46, 50, 50, 55, 56, 59, 65, 65, 36, 35, 34, 36, 38, 38, 46, 48, 50, 54,
+ 54, 58, 60, 63, 68, 68, 36, 35, 34, 36, 38, 38, 46, 48, 50, 54, 54, 58,
+ 60, 63, 68, 68, 38, 37, 37, 38, 40, 40, 47, 50, 52, 57, 57, 62, 64, 67,
+ 72, 72, 39, 38, 37, 39, 40, 40, 48, 50, 53, 58, 58, 63, 65, 68, 73, 73,
+ 41, 39, 39, 40, 41, 41, 49, 51, 54, 60, 60, 66, 67, 70, 76, 76, 44, 41,
+ 41, 42, 43, 43, 51, 53, 57, 63, 63, 69, 71, 74, 79, 79, 44, 41, 41, 42,
+ 43, 43, 51, 53, 57, 63, 63, 69, 71, 74, 79, 79, 47, 44, 44, 44, 45, 45,
+ 53, 56, 59, 66, 66, 73, 75, 78, 84, 84, 48, 45, 45, 45, 46, 46, 54, 56,
+ 60, 67, 67, 74, 76, 79, 85, 85, 50, 47, 46, 47, 47, 47, 55, 58, 61, 68,
+ 68, 76, 78, 82, 88, 88, 53, 50, 49, 50, 50, 50, 57, 60, 64, 71, 71, 79,
+ 82, 86, 92, 92, 53, 50, 49, 50, 50, 50, 57, 60, 64, 71, 71, 79, 82, 86,
+ 92, 92, 57, 54, 53, 53, 53, 53, 60, 63, 67, 74, 74, 83, 86, 90, 97, 97,
+ 58, 55, 54, 54, 54, 54, 61, 63, 68, 75, 75, 84, 87, 91, 98, 98, 61, 57,
+ 56, 56, 56, 56, 63, 65, 69, 77, 77, 86, 89, 93, 100, 100, 65, 61, 60,
+ 59, 58, 58, 66, 68, 72, 79, 79, 89, 92, 97, 105, 105, 65, 61, 60, 59,
+ 58, 58, 66, 68, 72, 79, 79, 89, 92, 97, 105, 105, 70, 65, 64, 63, 62,
+ 62, 70, 72, 76, 83, 83, 93, 96, 101, 109, 109],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 33, 34, 34, 36, 36, 38, 39,
+ 41, 44, 44, 47, 48, 50, 53, 53, 57, 58, 61, 65, 65, 70, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 35, 35, 37, 38, 39, 41, 41, 44,
+ 45, 47, 50, 50, 54, 55, 57, 61, 61, 65, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 33, 34, 34, 34, 34, 37, 37, 39, 41, 41, 44, 45, 46, 49, 49,
+ 53, 54, 56, 60, 60, 64, 31, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 35,
+ 35, 35, 36, 36, 38, 39, 40, 42, 42, 44, 45, 47, 50, 50, 53, 54, 56, 59,
+ 59, 63, 32, 32, 32, 32, 33, 33, 34, 34, 34, 35, 35, 36, 37, 37, 38, 38,
+ 40, 40, 41, 43, 43, 45, 46, 47, 50, 50, 53, 54, 56, 58, 58, 62, 32, 32,
+ 32, 32, 33, 33, 34, 34, 34, 35, 35, 36, 37, 37, 38, 38, 40, 40, 41, 43,
+ 43, 45, 46, 47, 50, 50, 53, 54, 56, 58, 58, 62, 35, 35, 35, 34, 34, 34,
+ 35, 36, 36, 37, 37, 40, 41, 43, 46, 46, 47, 48, 49, 51, 51, 53, 54, 55,
+ 57, 57, 60, 61, 63, 66, 66, 70, 36, 35, 35, 35, 34, 34, 36, 36, 37, 38,
+ 38, 41, 42, 44, 48, 48, 50, 50, 51, 53, 53, 56, 56, 58, 60, 60, 63, 63,
+ 65, 68, 68, 72, 39, 38, 38, 37, 37, 37, 38, 38, 39, 40, 40, 43, 44, 46,
+ 50, 50, 52, 53, 54, 57, 57, 59, 60, 61, 64, 64, 67, 68, 69, 72, 72, 76,
+ 44, 42, 42, 41, 41, 41, 42, 42, 42, 42, 42, 46, 48, 50, 54, 54, 57, 58,
+ 60, 63, 63, 66, 67, 68, 71, 71, 74, 75, 77, 79, 79, 83, 44, 42, 42, 41,
+ 41, 41, 42, 42, 42, 42, 42, 46, 48, 50, 54, 54, 57, 58, 60, 63, 63, 66,
+ 67, 68, 71, 71, 74, 75, 77, 79, 79, 83, 51, 49, 49, 48, 47, 47, 48, 48,
+ 48, 48, 48, 52, 53, 55, 58, 58, 62, 63, 66, 69, 69, 73, 74, 76, 79, 79,
+ 83, 84, 86, 89, 89, 93, 53, 52, 51, 50, 49, 49, 49, 50, 49, 49, 49, 53,
+ 54, 56, 60, 60, 64, 65, 67, 71, 71, 75, 76, 78, 82, 82, 86, 87, 89, 92,
+ 92, 96, 58, 56, 55, 54, 53, 53, 53, 53, 53, 52, 52, 56, 57, 59, 63, 63,
+ 67, 68, 70, 74, 74, 78, 79, 82, 86, 86, 90, 91, 93, 97, 97, 101, 65, 63,
+ 62, 61, 59, 59, 59, 59, 58, 58, 58, 62, 63, 65, 68, 68, 72, 73, 76, 79,
+ 79, 84, 85, 88, 92, 92, 97, 98, 100, 105, 105, 109, 65, 63, 62, 61, 59,
+ 59, 59, 59, 58, 58, 58, 62, 63, 65, 68, 68, 72, 73, 76, 79, 79, 84, 85,
+ 88, 92, 92, 97, 98, 100, 105, 105, 109],
+ /* Size 4x16 */
+ [31, 32, 44, 58, 32, 32, 42, 55, 32, 33, 41, 53, 32, 34, 42, 53, 32, 34,
+ 42, 53, 32, 35, 42, 52, 34, 37, 48, 57, 35, 38, 54, 63, 37, 40, 57, 67,
+ 39, 41, 60, 70, 41, 43, 63, 74, 45, 46, 67, 79, 50, 50, 71, 86, 54, 53,
+ 74, 90, 57, 56, 77, 93, 61, 58, 79, 97],
+ /* Size 16x4 */
+ [31, 32, 32, 32, 32, 32, 34, 35, 37, 39, 41, 45, 50, 54, 57, 61, 32, 32,
+ 33, 34, 34, 35, 37, 38, 40, 41, 43, 46, 50, 53, 56, 58, 44, 42, 41, 42,
+ 42, 42, 48, 54, 57, 60, 63, 67, 71, 74, 77, 79, 58, 55, 53, 53, 53, 52,
+ 57, 63, 67, 70, 74, 79, 86, 90, 93, 97],
+ /* Size 8x32 */
+ [32, 31, 32, 35, 39, 44, 53, 65, 31, 32, 32, 35, 38, 42, 52, 63, 31, 32,
+ 32, 35, 38, 42, 51, 62, 31, 32, 32, 34, 37, 41, 50, 61, 31, 32, 33, 34,
+ 37, 41, 49, 59, 31, 32, 33, 34, 37, 41, 49, 59, 31, 32, 34, 35, 38, 42,
+ 49, 59, 32, 32, 34, 36, 38, 42, 50, 59, 32, 32, 34, 36, 39, 42, 49, 58,
+ 32, 33, 35, 37, 40, 42, 49, 58, 32, 33, 35, 37, 40, 42, 49, 58, 33, 33,
+ 36, 40, 43, 46, 53, 62, 34, 34, 37, 41, 44, 48, 54, 63, 34, 34, 37, 43,
+ 46, 50, 56, 65, 36, 34, 38, 46, 50, 54, 60, 68, 36, 34, 38, 46, 50, 54,
+ 60, 68, 38, 37, 40, 47, 52, 57, 64, 72, 39, 37, 40, 48, 53, 58, 65, 73,
+ 41, 39, 41, 49, 54, 60, 67, 76, 44, 41, 43, 51, 57, 63, 71, 79, 44, 41,
+ 43, 51, 57, 63, 71, 79, 47, 44, 45, 53, 59, 66, 75, 84, 48, 45, 46, 54,
+ 60, 67, 76, 85, 50, 46, 47, 55, 61, 68, 78, 88, 53, 49, 50, 57, 64, 71,
+ 82, 92, 53, 49, 50, 57, 64, 71, 82, 92, 57, 53, 53, 60, 67, 74, 86, 97,
+ 58, 54, 54, 61, 68, 75, 87, 98, 61, 56, 56, 63, 69, 77, 89, 100, 65, 60,
+ 58, 66, 72, 79, 92, 105, 65, 60, 58, 66, 72, 79, 92, 105, 70, 64, 62,
+ 70, 76, 83, 96, 109],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 33, 34, 34, 36, 36, 38, 39,
+ 41, 44, 44, 47, 48, 50, 53, 53, 57, 58, 61, 65, 65, 70, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 34, 37, 37, 39, 41, 41, 44,
+ 45, 46, 49, 49, 53, 54, 56, 60, 60, 64, 32, 32, 32, 32, 33, 33, 34, 34,
+ 34, 35, 35, 36, 37, 37, 38, 38, 40, 40, 41, 43, 43, 45, 46, 47, 50, 50,
+ 53, 54, 56, 58, 58, 62, 35, 35, 35, 34, 34, 34, 35, 36, 36, 37, 37, 40,
+ 41, 43, 46, 46, 47, 48, 49, 51, 51, 53, 54, 55, 57, 57, 60, 61, 63, 66,
+ 66, 70, 39, 38, 38, 37, 37, 37, 38, 38, 39, 40, 40, 43, 44, 46, 50, 50,
+ 52, 53, 54, 57, 57, 59, 60, 61, 64, 64, 67, 68, 69, 72, 72, 76, 44, 42,
+ 42, 41, 41, 41, 42, 42, 42, 42, 42, 46, 48, 50, 54, 54, 57, 58, 60, 63,
+ 63, 66, 67, 68, 71, 71, 74, 75, 77, 79, 79, 83, 53, 52, 51, 50, 49, 49,
+ 49, 50, 49, 49, 49, 53, 54, 56, 60, 60, 64, 65, 67, 71, 71, 75, 76, 78,
+ 82, 82, 86, 87, 89, 92, 92, 96, 65, 63, 62, 61, 59, 59, 59, 59, 58, 58,
+ 58, 62, 63, 65, 68, 68, 72, 73, 76, 79, 79, 84, 85, 88, 92, 92, 97, 98,
+ 100, 105, 105, 109]],
+ [ /* Chroma */
+ /* Size 4x4 */
+ [31, 41, 46, 51, 41, 48, 48, 51, 46, 48, 58, 62, 51, 51, 62, 71],
+ /* Size 8x8 */
+ [31, 31, 38, 44, 47, 48, 50, 55, 31, 32, 40, 44, 45, 46, 47, 52, 38, 40,
+ 47, 47, 46, 46, 47, 50, 44, 44, 47, 50, 51, 51, 52, 54, 47, 45, 46, 51,
+ 54, 56, 57, 60, 48, 46, 46, 51, 56, 61, 63, 66, 50, 47, 47, 52, 57, 63,
+ 66, 70, 55, 52, 50, 54, 60, 66, 70, 76],
+ /* Size 16x16 */
+ [32, 31, 30, 33, 34, 36, 41, 49, 48, 49, 49, 50, 52, 54, 55, 57, 31, 31,
+ 31, 34, 36, 38, 42, 47, 47, 47, 47, 48, 50, 51, 53, 54, 30, 31, 32, 34,
+ 37, 40, 42, 46, 45, 45, 45, 46, 47, 49, 50, 52, 33, 34, 34, 37, 40, 42,
+ 44, 47, 46, 46, 45, 46, 47, 49, 50, 51, 34, 36, 37, 40, 42, 45, 46, 47,
+ 46, 46, 45, 46, 47, 48, 49, 50, 36, 38, 40, 42, 45, 47, 47, 48, 47, 46,
+ 45, 46, 47, 48, 49, 50, 41, 42, 42, 44, 46, 47, 48, 50, 50, 49, 49, 50,
+ 50, 51, 52, 53, 49, 47, 46, 47, 47, 48, 50, 53, 53, 53, 53, 54, 54, 55,
+ 56, 56, 48, 47, 45, 46, 46, 47, 50, 53, 54, 54, 55, 56, 57, 58, 58, 59,
+ 49, 47, 45, 46, 46, 46, 49, 53, 54, 55, 57, 58, 59, 60, 60, 61, 49, 47,
+ 45, 45, 45, 45, 49, 53, 55, 57, 58, 60, 61, 62, 63, 63, 50, 48, 46, 46,
+ 46, 46, 50, 54, 56, 58, 60, 61, 63, 65, 66, 67, 52, 50, 47, 47, 47, 47,
+ 50, 54, 57, 59, 61, 63, 66, 68, 69, 70, 54, 51, 49, 49, 48, 48, 51, 55,
+ 58, 60, 62, 65, 68, 70, 71, 73, 55, 53, 50, 50, 49, 49, 52, 56, 58, 60,
+ 63, 66, 69, 71, 73, 74, 57, 54, 52, 51, 50, 50, 53, 56, 59, 61, 63, 67,
+ 70, 73, 74, 76],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 30, 30, 33, 33, 34, 36, 36, 40, 41, 44, 49, 49, 48, 48,
+ 49, 49, 49, 50, 50, 51, 52, 52, 54, 54, 55, 57, 57, 59, 31, 31, 31, 31,
+ 31, 31, 33, 34, 36, 38, 38, 41, 42, 44, 48, 48, 47, 47, 47, 47, 47, 48,
+ 49, 49, 50, 50, 52, 52, 53, 55, 55, 57, 31, 31, 31, 31, 31, 31, 34, 34,
+ 36, 38, 38, 41, 42, 44, 47, 47, 47, 47, 47, 47, 47, 48, 48, 49, 50, 50,
+ 51, 52, 53, 54, 54, 56, 31, 31, 31, 31, 31, 31, 34, 35, 36, 39, 39, 41,
+ 42, 44, 47, 47, 46, 46, 46, 46, 46, 47, 47, 48, 49, 49, 50, 51, 52, 53,
+ 53, 55, 30, 31, 31, 31, 32, 32, 34, 35, 37, 40, 40, 42, 42, 44, 46, 46,
+ 45, 45, 45, 45, 45, 46, 46, 47, 47, 47, 49, 49, 50, 52, 52, 54, 30, 31,
+ 31, 31, 32, 32, 34, 35, 37, 40, 40, 42, 42, 44, 46, 46, 45, 45, 45, 45,
+ 45, 46, 46, 47, 47, 47, 49, 49, 50, 52, 52, 54, 33, 33, 34, 34, 34, 34,
+ 37, 38, 40, 42, 42, 44, 44, 45, 47, 47, 46, 46, 46, 45, 45, 46, 46, 47,
+ 47, 47, 49, 49, 50, 51, 51, 53, 33, 34, 34, 35, 35, 35, 38, 39, 40, 43,
+ 43, 44, 45, 46, 47, 47, 46, 46, 46, 45, 45, 46, 46, 47, 47, 47, 49, 49,
+ 50, 51, 51, 53, 34, 36, 36, 36, 37, 37, 40, 40, 42, 45, 45, 45, 46, 46,
+ 47, 47, 46, 46, 46, 45, 45, 46, 46, 47, 47, 47, 48, 49, 49, 50, 50, 52,
+ 36, 38, 38, 39, 40, 40, 42, 43, 45, 47, 47, 47, 47, 47, 48, 48, 47, 46,
+ 46, 45, 45, 46, 46, 46, 47, 47, 48, 48, 49, 50, 50, 51, 36, 38, 38, 39,
+ 40, 40, 42, 43, 45, 47, 47, 47, 47, 47, 48, 48, 47, 46, 46, 45, 45, 46,
+ 46, 46, 47, 47, 48, 48, 49, 50, 50, 51, 40, 41, 41, 41, 42, 42, 44, 44,
+ 45, 47, 47, 48, 48, 49, 50, 50, 49, 49, 49, 48, 48, 49, 49, 49, 49, 49,
+ 51, 51, 51, 52, 52, 54, 41, 42, 42, 42, 42, 42, 44, 45, 46, 47, 47, 48,
+ 48, 49, 50, 50, 50, 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 52, 52, 53,
+ 53, 55, 44, 44, 44, 44, 44, 44, 45, 46, 46, 47, 47, 49, 49, 50, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 52, 52, 53, 53, 54, 54, 54, 56, 49, 48,
+ 47, 47, 46, 46, 47, 47, 47, 48, 48, 50, 50, 51, 53, 53, 53, 53, 53, 53,
+ 53, 54, 54, 54, 54, 54, 55, 55, 56, 56, 56, 58, 49, 48, 47, 47, 46, 46,
+ 47, 47, 47, 48, 48, 50, 50, 51, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54,
+ 54, 54, 55, 55, 56, 56, 56, 58, 48, 47, 47, 46, 45, 45, 46, 46, 46, 47,
+ 47, 49, 50, 51, 53, 53, 54, 54, 54, 55, 55, 56, 56, 56, 57, 57, 58, 58,
+ 58, 59, 59, 60, 48, 47, 47, 46, 45, 45, 46, 46, 46, 46, 46, 49, 49, 51,
+ 53, 53, 54, 54, 55, 55, 55, 56, 56, 57, 57, 57, 58, 58, 59, 60, 60, 61,
+ 49, 47, 47, 46, 45, 45, 46, 46, 46, 46, 46, 49, 49, 51, 53, 53, 54, 55,
+ 55, 57, 57, 57, 58, 58, 59, 59, 60, 60, 60, 61, 61, 63, 49, 47, 47, 46,
+ 45, 45, 45, 45, 45, 45, 45, 48, 49, 51, 53, 53, 55, 55, 57, 58, 58, 59,
+ 60, 60, 61, 61, 62, 62, 63, 63, 63, 65, 49, 47, 47, 46, 45, 45, 45, 45,
+ 45, 45, 45, 48, 49, 51, 53, 53, 55, 55, 57, 58, 58, 59, 60, 60, 61, 61,
+ 62, 62, 63, 63, 63, 65, 50, 48, 48, 47, 46, 46, 46, 46, 46, 46, 46, 49,
+ 50, 51, 54, 54, 56, 56, 57, 59, 59, 61, 61, 62, 63, 63, 64, 64, 65, 66,
+ 66, 67, 50, 49, 48, 47, 46, 46, 46, 46, 46, 46, 46, 49, 50, 51, 54, 54,
+ 56, 56, 58, 60, 60, 61, 61, 62, 63, 63, 65, 65, 66, 67, 67, 68, 51, 49,
+ 49, 48, 47, 47, 47, 47, 47, 46, 46, 49, 50, 51, 54, 54, 56, 57, 58, 60,
+ 60, 62, 62, 63, 65, 65, 66, 66, 67, 68, 68, 70, 52, 50, 50, 49, 47, 47,
+ 47, 47, 47, 47, 47, 49, 50, 52, 54, 54, 57, 57, 59, 61, 61, 63, 63, 65,
+ 66, 66, 68, 68, 69, 70, 70, 72, 52, 50, 50, 49, 47, 47, 47, 47, 47, 47,
+ 47, 49, 50, 52, 54, 54, 57, 57, 59, 61, 61, 63, 63, 65, 66, 66, 68, 68,
+ 69, 70, 70, 72, 54, 52, 51, 50, 49, 49, 49, 49, 48, 48, 48, 51, 51, 53,
+ 55, 55, 58, 58, 60, 62, 62, 64, 65, 66, 68, 68, 70, 70, 71, 73, 73, 74,
+ 54, 52, 52, 51, 49, 49, 49, 49, 49, 48, 48, 51, 52, 53, 55, 55, 58, 58,
+ 60, 62, 62, 64, 65, 66, 68, 68, 70, 71, 72, 73, 73, 75, 55, 53, 53, 52,
+ 50, 50, 50, 50, 49, 49, 49, 51, 52, 54, 56, 56, 58, 59, 60, 63, 63, 65,
+ 66, 67, 69, 69, 71, 72, 73, 74, 74, 76, 57, 55, 54, 53, 52, 52, 51, 51,
+ 50, 50, 50, 52, 53, 54, 56, 56, 59, 60, 61, 63, 63, 66, 67, 68, 70, 70,
+ 73, 73, 74, 76, 76, 78, 57, 55, 54, 53, 52, 52, 51, 51, 50, 50, 50, 52,
+ 53, 54, 56, 56, 59, 60, 61, 63, 63, 66, 67, 68, 70, 70, 73, 73, 74, 76,
+ 76, 78, 59, 57, 56, 55, 54, 54, 53, 53, 52, 51, 51, 54, 55, 56, 58, 58,
+ 60, 61, 63, 65, 65, 67, 68, 70, 72, 72, 74, 75, 76, 78, 78, 80],
+ /* Size 4x8 */
+ [31, 38, 47, 52, 32, 40, 45, 49, 39, 47, 45, 48, 44, 47, 51, 53, 46, 47,
+ 56, 58, 47, 46, 59, 64, 48, 47, 61, 68, 53, 50, 64, 73],
+ /* Size 8x4 */
+ [31, 32, 39, 44, 46, 47, 48, 53, 38, 40, 47, 47, 47, 46, 47, 50, 47, 45,
+ 45, 51, 56, 59, 61, 64, 52, 49, 48, 53, 58, 64, 68, 73],
+ /* Size 8x16 */
+ [32, 31, 37, 45, 48, 49, 52, 57, 31, 31, 38, 45, 47, 47, 50, 54, 30, 32,
+ 40, 44, 45, 45, 48, 52, 33, 35, 42, 46, 46, 45, 47, 51, 35, 37, 44, 46,
+ 46, 45, 47, 51, 37, 40, 47, 47, 47, 45, 47, 50, 42, 43, 47, 49, 50, 49,
+ 50, 53, 49, 46, 48, 52, 53, 53, 54, 57, 48, 46, 47, 51, 54, 55, 57, 59,
+ 48, 45, 46, 51, 54, 57, 59, 61, 49, 45, 46, 51, 55, 58, 61, 64, 50, 46,
+ 46, 52, 56, 59, 64, 67, 52, 48, 47, 53, 57, 61, 66, 71, 54, 49, 48, 54,
+ 58, 62, 68, 73, 55, 51, 49, 54, 58, 63, 69, 74, 57, 52, 50, 55, 59, 64,
+ 70, 76],
+ /* Size 16x8 */
+ [32, 31, 30, 33, 35, 37, 42, 49, 48, 48, 49, 50, 52, 54, 55, 57, 31, 31,
+ 32, 35, 37, 40, 43, 46, 46, 45, 45, 46, 48, 49, 51, 52, 37, 38, 40, 42,
+ 44, 47, 47, 48, 47, 46, 46, 46, 47, 48, 49, 50, 45, 45, 44, 46, 46, 47,
+ 49, 52, 51, 51, 51, 52, 53, 54, 54, 55, 48, 47, 45, 46, 46, 47, 50, 53,
+ 54, 54, 55, 56, 57, 58, 58, 59, 49, 47, 45, 45, 45, 45, 49, 53, 55, 57,
+ 58, 59, 61, 62, 63, 64, 52, 50, 48, 47, 47, 47, 50, 54, 57, 59, 61, 64,
+ 66, 68, 69, 70, 57, 54, 52, 51, 51, 50, 53, 57, 59, 61, 64, 67, 71, 73,
+ 74, 76],
+ /* Size 16x32 */
+ [32, 31, 31, 33, 37, 37, 45, 48, 48, 49, 49, 51, 52, 54, 57, 57, 31, 31,
+ 31, 34, 38, 38, 45, 47, 47, 47, 47, 50, 50, 52, 55, 55, 31, 31, 31, 34,
+ 38, 38, 45, 47, 47, 47, 47, 49, 50, 51, 54, 54, 31, 31, 32, 34, 39, 39,
+ 45, 46, 46, 46, 46, 48, 49, 51, 53, 53, 30, 32, 32, 35, 40, 40, 44, 46,
+ 45, 45, 45, 47, 48, 49, 52, 52, 30, 32, 32, 35, 40, 40, 44, 46, 45, 45,
+ 45, 47, 48, 49, 52, 52, 33, 34, 35, 37, 42, 42, 46, 47, 46, 45, 45, 47,
+ 47, 49, 51, 51, 33, 35, 36, 38, 43, 43, 46, 47, 46, 46, 46, 47, 47, 49,
+ 51, 51, 35, 37, 37, 40, 44, 44, 46, 47, 46, 45, 45, 47, 47, 48, 51, 51,
+ 37, 39, 40, 43, 47, 47, 47, 47, 47, 45, 45, 46, 47, 48, 50, 50, 37, 39,
+ 40, 43, 47, 47, 47, 47, 47, 45, 45, 46, 47, 48, 50, 50, 41, 42, 42, 44,
+ 47, 47, 49, 49, 49, 48, 48, 49, 50, 51, 52, 52, 42, 42, 43, 44, 47, 47,
+ 49, 50, 50, 49, 49, 50, 50, 51, 53, 53, 44, 44, 44, 45, 47, 47, 50, 51,
+ 51, 51, 51, 52, 52, 53, 54, 54, 49, 47, 46, 47, 48, 48, 52, 53, 53, 53,
+ 53, 54, 54, 55, 57, 57, 49, 47, 46, 47, 48, 48, 52, 53, 53, 53, 53, 54,
+ 54, 55, 57, 57, 48, 46, 46, 46, 47, 47, 51, 53, 54, 55, 55, 56, 57, 58,
+ 59, 59, 48, 46, 46, 46, 47, 47, 51, 53, 54, 56, 56, 57, 57, 58, 60, 60,
+ 48, 46, 45, 46, 46, 46, 51, 53, 54, 57, 57, 58, 59, 60, 61, 61, 49, 46,
+ 45, 45, 46, 46, 51, 53, 55, 58, 58, 61, 61, 62, 64, 64, 49, 46, 45, 45,
+ 46, 46, 51, 53, 55, 58, 58, 61, 61, 62, 64, 64, 50, 47, 46, 46, 46, 46,
+ 52, 54, 56, 59, 59, 62, 63, 64, 66, 66, 50, 47, 46, 46, 46, 46, 52, 54,
+ 56, 59, 59, 63, 64, 65, 67, 67, 51, 48, 47, 47, 47, 47, 52, 54, 56, 60,
+ 60, 64, 65, 66, 68, 68, 52, 48, 48, 47, 47, 47, 53, 54, 57, 61, 61, 65,
+ 66, 68, 71, 71, 52, 48, 48, 47, 47, 47, 53, 54, 57, 61, 61, 65, 66, 68,
+ 71, 71, 54, 50, 49, 49, 48, 48, 54, 55, 58, 62, 62, 67, 68, 70, 73, 73,
+ 54, 51, 50, 49, 49, 49, 54, 55, 58, 62, 62, 67, 68, 70, 73, 73, 55, 51,
+ 51, 50, 49, 49, 54, 56, 58, 63, 63, 68, 69, 71, 74, 74, 57, 53, 52, 51,
+ 50, 50, 55, 56, 59, 64, 64, 69, 70, 73, 76, 76, 57, 53, 52, 51, 50, 50,
+ 55, 56, 59, 64, 64, 69, 70, 73, 76, 76, 59, 55, 54, 53, 52, 52, 57, 58,
+ 61, 65, 65, 70, 72, 74, 78, 78],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 30, 30, 33, 33, 35, 37, 37, 41, 42, 44, 49, 49, 48, 48,
+ 48, 49, 49, 50, 50, 51, 52, 52, 54, 54, 55, 57, 57, 59, 31, 31, 31, 31,
+ 32, 32, 34, 35, 37, 39, 39, 42, 42, 44, 47, 47, 46, 46, 46, 46, 46, 47,
+ 47, 48, 48, 48, 50, 51, 51, 53, 53, 55, 31, 31, 31, 32, 32, 32, 35, 36,
+ 37, 40, 40, 42, 43, 44, 46, 46, 46, 46, 45, 45, 45, 46, 46, 47, 48, 48,
+ 49, 50, 51, 52, 52, 54, 33, 34, 34, 34, 35, 35, 37, 38, 40, 43, 43, 44,
+ 44, 45, 47, 47, 46, 46, 46, 45, 45, 46, 46, 47, 47, 47, 49, 49, 50, 51,
+ 51, 53, 37, 38, 38, 39, 40, 40, 42, 43, 44, 47, 47, 47, 47, 47, 48, 48,
+ 47, 47, 46, 46, 46, 46, 46, 47, 47, 47, 48, 49, 49, 50, 50, 52, 37, 38,
+ 38, 39, 40, 40, 42, 43, 44, 47, 47, 47, 47, 47, 48, 48, 47, 47, 46, 46,
+ 46, 46, 46, 47, 47, 47, 48, 49, 49, 50, 50, 52, 45, 45, 45, 45, 44, 44,
+ 46, 46, 46, 47, 47, 49, 49, 50, 52, 52, 51, 51, 51, 51, 51, 52, 52, 52,
+ 53, 53, 54, 54, 54, 55, 55, 57, 48, 47, 47, 46, 46, 46, 47, 47, 47, 47,
+ 47, 49, 50, 51, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 55, 55,
+ 56, 56, 56, 58, 48, 47, 47, 46, 45, 45, 46, 46, 46, 47, 47, 49, 50, 51,
+ 53, 53, 54, 54, 54, 55, 55, 56, 56, 56, 57, 57, 58, 58, 58, 59, 59, 61,
+ 49, 47, 47, 46, 45, 45, 45, 46, 45, 45, 45, 48, 49, 51, 53, 53, 55, 56,
+ 57, 58, 58, 59, 59, 60, 61, 61, 62, 62, 63, 64, 64, 65, 49, 47, 47, 46,
+ 45, 45, 45, 46, 45, 45, 45, 48, 49, 51, 53, 53, 55, 56, 57, 58, 58, 59,
+ 59, 60, 61, 61, 62, 62, 63, 64, 64, 65, 51, 50, 49, 48, 47, 47, 47, 47,
+ 47, 46, 46, 49, 50, 52, 54, 54, 56, 57, 58, 61, 61, 62, 63, 64, 65, 65,
+ 67, 67, 68, 69, 69, 70, 52, 50, 50, 49, 48, 48, 47, 47, 47, 47, 47, 50,
+ 50, 52, 54, 54, 57, 57, 59, 61, 61, 63, 64, 65, 66, 66, 68, 68, 69, 70,
+ 70, 72, 54, 52, 51, 51, 49, 49, 49, 49, 48, 48, 48, 51, 51, 53, 55, 55,
+ 58, 58, 60, 62, 62, 64, 65, 66, 68, 68, 70, 70, 71, 73, 73, 74, 57, 55,
+ 54, 53, 52, 52, 51, 51, 51, 50, 50, 52, 53, 54, 57, 57, 59, 60, 61, 64,
+ 64, 66, 67, 68, 71, 71, 73, 73, 74, 76, 76, 78, 57, 55, 54, 53, 52, 52,
+ 51, 51, 51, 50, 50, 52, 53, 54, 57, 57, 59, 60, 61, 64, 64, 66, 67, 68,
+ 71, 71, 73, 73, 74, 76, 76, 78],
+ /* Size 4x16 */
+ [31, 37, 49, 54, 31, 38, 47, 51, 32, 40, 45, 49, 34, 42, 45, 49, 37, 44,
+ 45, 48, 39, 47, 45, 48, 42, 47, 49, 51, 47, 48, 53, 55, 46, 47, 55, 58,
+ 46, 46, 57, 60, 46, 46, 58, 62, 47, 46, 59, 65, 48, 47, 61, 68, 50, 48,
+ 62, 70, 51, 49, 63, 71, 53, 50, 64, 73],
+ /* Size 16x4 */
+ [31, 31, 32, 34, 37, 39, 42, 47, 46, 46, 46, 47, 48, 50, 51, 53, 37, 38,
+ 40, 42, 44, 47, 47, 48, 47, 46, 46, 46, 47, 48, 49, 50, 49, 47, 45, 45,
+ 45, 45, 49, 53, 55, 57, 58, 59, 61, 62, 63, 64, 54, 51, 49, 49, 48, 48,
+ 51, 55, 58, 60, 62, 65, 68, 70, 71, 73],
+ /* Size 8x32 */
+ [32, 31, 37, 45, 48, 49, 52, 57, 31, 31, 38, 45, 47, 47, 50, 55, 31, 31,
+ 38, 45, 47, 47, 50, 54, 31, 32, 39, 45, 46, 46, 49, 53, 30, 32, 40, 44,
+ 45, 45, 48, 52, 30, 32, 40, 44, 45, 45, 48, 52, 33, 35, 42, 46, 46, 45,
+ 47, 51, 33, 36, 43, 46, 46, 46, 47, 51, 35, 37, 44, 46, 46, 45, 47, 51,
+ 37, 40, 47, 47, 47, 45, 47, 50, 37, 40, 47, 47, 47, 45, 47, 50, 41, 42,
+ 47, 49, 49, 48, 50, 52, 42, 43, 47, 49, 50, 49, 50, 53, 44, 44, 47, 50,
+ 51, 51, 52, 54, 49, 46, 48, 52, 53, 53, 54, 57, 49, 46, 48, 52, 53, 53,
+ 54, 57, 48, 46, 47, 51, 54, 55, 57, 59, 48, 46, 47, 51, 54, 56, 57, 60,
+ 48, 45, 46, 51, 54, 57, 59, 61, 49, 45, 46, 51, 55, 58, 61, 64, 49, 45,
+ 46, 51, 55, 58, 61, 64, 50, 46, 46, 52, 56, 59, 63, 66, 50, 46, 46, 52,
+ 56, 59, 64, 67, 51, 47, 47, 52, 56, 60, 65, 68, 52, 48, 47, 53, 57, 61,
+ 66, 71, 52, 48, 47, 53, 57, 61, 66, 71, 54, 49, 48, 54, 58, 62, 68, 73,
+ 54, 50, 49, 54, 58, 62, 68, 73, 55, 51, 49, 54, 58, 63, 69, 74, 57, 52,
+ 50, 55, 59, 64, 70, 76, 57, 52, 50, 55, 59, 64, 70, 76, 59, 54, 52, 57,
+ 61, 65, 72, 78],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 30, 30, 33, 33, 35, 37, 37, 41, 42, 44, 49, 49, 48, 48,
+ 48, 49, 49, 50, 50, 51, 52, 52, 54, 54, 55, 57, 57, 59, 31, 31, 31, 32,
+ 32, 32, 35, 36, 37, 40, 40, 42, 43, 44, 46, 46, 46, 46, 45, 45, 45, 46,
+ 46, 47, 48, 48, 49, 50, 51, 52, 52, 54, 37, 38, 38, 39, 40, 40, 42, 43,
+ 44, 47, 47, 47, 47, 47, 48, 48, 47, 47, 46, 46, 46, 46, 46, 47, 47, 47,
+ 48, 49, 49, 50, 50, 52, 45, 45, 45, 45, 44, 44, 46, 46, 46, 47, 47, 49,
+ 49, 50, 52, 52, 51, 51, 51, 51, 51, 52, 52, 52, 53, 53, 54, 54, 54, 55,
+ 55, 57, 48, 47, 47, 46, 45, 45, 46, 46, 46, 47, 47, 49, 50, 51, 53, 53,
+ 54, 54, 54, 55, 55, 56, 56, 56, 57, 57, 58, 58, 58, 59, 59, 61, 49, 47,
+ 47, 46, 45, 45, 45, 46, 45, 45, 45, 48, 49, 51, 53, 53, 55, 56, 57, 58,
+ 58, 59, 59, 60, 61, 61, 62, 62, 63, 64, 64, 65, 52, 50, 50, 49, 48, 48,
+ 47, 47, 47, 47, 47, 50, 50, 52, 54, 54, 57, 57, 59, 61, 61, 63, 64, 65,
+ 66, 66, 68, 68, 69, 70, 70, 72, 57, 55, 54, 53, 52, 52, 51, 51, 51, 50,
+ 50, 52, 53, 54, 57, 57, 59, 60, 61, 64, 64, 66, 67, 68, 71, 71, 73, 73,
+ 74, 76, 76, 78]]
+ ],
+ [
+ [ /* Luma */
+ /* Size 4x4 */
+ [32, 32, 38, 51, 32, 35, 40, 49, 38, 40, 54, 64, 51, 49, 64, 81],
+ /* Size 8x8 */
+ [31, 32, 32, 34, 35, 41, 47, 53, 32, 32, 32, 33, 34, 40, 44, 50, 32, 32,
+ 34, 35, 37, 41, 45, 51, 34, 33, 35, 39, 42, 47, 51, 55, 35, 34, 37, 42,
+ 48, 53, 57, 61, 41, 40, 41, 47, 53, 60, 65, 70, 47, 44, 45, 51, 57, 65,
+ 71, 77, 53, 50, 51, 55, 61, 70, 77, 85],
+ /* Size 16x16 */
+ [32, 31, 31, 31, 31, 32, 32, 34, 36, 38, 39, 44, 47, 49, 54, 59, 31, 32,
+ 32, 32, 32, 32, 33, 34, 35, 37, 38, 42, 45, 47, 51, 56, 31, 32, 32, 32,
+ 32, 32, 33, 33, 34, 36, 37, 41, 44, 46, 50, 54, 31, 32, 32, 32, 32, 33,
+ 33, 34, 35, 36, 38, 41, 44, 45, 49, 54, 31, 32, 32, 32, 33, 34, 34, 35,
+ 36, 38, 39, 42, 45, 46, 50, 54, 32, 32, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 42, 45, 46, 49, 53, 32, 33, 33, 33, 34, 36, 36, 38, 40, 41, 42, 44,
+ 47, 48, 51, 55, 34, 34, 33, 34, 35, 37, 38, 39, 42, 44, 45, 47, 50, 51,
+ 54, 58, 36, 35, 34, 35, 36, 38, 40, 42, 48, 50, 50, 54, 56, 57, 60, 64,
+ 38, 37, 36, 36, 38, 39, 41, 44, 50, 51, 52, 56, 58, 60, 63, 67, 39, 38,
+ 37, 38, 39, 40, 42, 45, 50, 52, 54, 58, 60, 62, 65, 69, 44, 42, 41, 41,
+ 42, 42, 44, 47, 54, 56, 58, 63, 66, 68, 71, 75, 47, 45, 44, 44, 45, 45,
+ 47, 50, 56, 58, 60, 66, 69, 71, 75, 79, 49, 47, 46, 45, 46, 46, 48, 51,
+ 57, 60, 62, 68, 71, 73, 77, 81, 54, 51, 50, 49, 50, 49, 51, 54, 60, 63,
+ 65, 71, 75, 77, 82, 87, 59, 56, 54, 54, 54, 53, 55, 58, 64, 67, 69, 75,
+ 79, 81, 87, 92],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 34, 34, 35, 36, 36,
+ 38, 39, 39, 42, 44, 44, 47, 48, 49, 53, 54, 55, 59, 59, 31, 31, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 34, 35, 35, 37, 39, 39, 41,
+ 43, 43, 46, 47, 48, 51, 52, 53, 57, 57, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 33, 34, 34, 34, 35, 35, 37, 38, 38, 41, 42, 43, 45, 46,
+ 47, 51, 51, 53, 56, 56, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 33, 34, 34, 34, 35, 35, 37, 38, 38, 41, 42, 42, 45, 46, 47, 51, 51, 52,
+ 56, 56, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34,
+ 34, 34, 36, 37, 37, 40, 41, 41, 44, 45, 46, 49, 50, 51, 54, 54, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 36, 37,
+ 37, 40, 41, 41, 44, 44, 45, 49, 49, 50, 54, 54, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 35, 35, 36, 38, 38, 40, 41, 41,
+ 44, 45, 45, 49, 49, 50, 54, 54, 31, 32, 32, 32, 32, 32, 32, 33, 33, 33,
+ 34, 34, 34, 35, 35, 35, 36, 36, 38, 39, 39, 41, 42, 42, 44, 45, 46, 49,
+ 50, 51, 54, 54, 31, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35,
+ 35, 36, 36, 36, 38, 39, 39, 41, 42, 42, 45, 45, 46, 49, 50, 51, 54, 54,
+ 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 37, 37,
+ 38, 39, 39, 41, 42, 42, 45, 45, 46, 49, 49, 51, 54, 54, 32, 32, 32, 32,
+ 32, 32, 33, 34, 34, 34, 35, 35, 36, 37, 37, 37, 38, 38, 39, 40, 40, 42,
+ 42, 43, 45, 46, 46, 49, 49, 50, 53, 53, 32, 32, 32, 32, 32, 32, 33, 34,
+ 34, 34, 35, 35, 36, 37, 37, 37, 38, 38, 39, 40, 40, 42, 42, 43, 45, 46,
+ 46, 49, 49, 50, 53, 53, 32, 33, 33, 33, 33, 33, 33, 34, 34, 35, 36, 36,
+ 36, 38, 38, 39, 40, 40, 41, 42, 42, 44, 44, 45, 47, 47, 48, 51, 51, 52,
+ 55, 55, 34, 34, 34, 34, 33, 33, 34, 35, 35, 35, 37, 37, 38, 39, 39, 41,
+ 42, 42, 44, 45, 45, 47, 47, 48, 50, 51, 51, 54, 54, 55, 58, 58, 34, 34,
+ 34, 34, 33, 33, 34, 35, 35, 35, 37, 37, 38, 39, 39, 41, 42, 42, 44, 45,
+ 45, 47, 47, 48, 50, 51, 51, 54, 54, 55, 58, 58, 35, 34, 34, 34, 34, 34,
+ 34, 35, 36, 36, 37, 37, 39, 41, 41, 43, 45, 45, 47, 47, 47, 49, 50, 51,
+ 53, 53, 54, 57, 57, 58, 61, 61, 36, 35, 35, 35, 34, 34, 35, 36, 36, 37,
+ 38, 38, 40, 42, 42, 45, 48, 48, 50, 50, 50, 53, 54, 54, 56, 57, 57, 59,
+ 60, 61, 64, 64, 36, 35, 35, 35, 34, 34, 35, 36, 36, 37, 38, 38, 40, 42,
+ 42, 45, 48, 48, 50, 50, 50, 53, 54, 54, 56, 57, 57, 59, 60, 61, 64, 64,
+ 38, 37, 37, 37, 36, 36, 36, 38, 38, 38, 39, 39, 41, 44, 44, 47, 50, 50,
+ 51, 52, 52, 55, 56, 56, 58, 59, 60, 62, 63, 64, 67, 67, 39, 39, 38, 38,
+ 37, 37, 38, 39, 39, 39, 40, 40, 42, 45, 45, 47, 50, 50, 52, 54, 54, 56,
+ 58, 58, 60, 61, 62, 64, 65, 66, 69, 69, 39, 39, 38, 38, 37, 37, 38, 39,
+ 39, 39, 40, 40, 42, 45, 45, 47, 50, 50, 52, 54, 54, 56, 58, 58, 60, 61,
+ 62, 64, 65, 66, 69, 69, 42, 41, 41, 41, 40, 40, 40, 41, 41, 41, 42, 42,
+ 44, 47, 47, 49, 53, 53, 55, 56, 56, 60, 61, 62, 64, 65, 66, 69, 69, 70,
+ 73, 73, 44, 43, 42, 42, 41, 41, 41, 42, 42, 42, 42, 42, 44, 47, 47, 50,
+ 54, 54, 56, 58, 58, 61, 63, 64, 66, 67, 68, 71, 71, 72, 75, 75, 44, 43,
+ 43, 42, 41, 41, 41, 42, 42, 42, 43, 43, 45, 48, 48, 51, 54, 54, 56, 58,
+ 58, 62, 64, 64, 66, 67, 68, 71, 72, 73, 76, 76, 47, 46, 45, 45, 44, 44,
+ 44, 44, 45, 45, 45, 45, 47, 50, 50, 53, 56, 56, 58, 60, 60, 64, 66, 66,
+ 69, 70, 71, 74, 75, 76, 79, 79, 48, 47, 46, 46, 45, 44, 45, 45, 45, 45,
+ 46, 46, 47, 51, 51, 53, 57, 57, 59, 61, 61, 65, 67, 67, 70, 71, 72, 75,
+ 76, 77, 80, 80, 49, 48, 47, 47, 46, 45, 45, 46, 46, 46, 46, 46, 48, 51,
+ 51, 54, 57, 57, 60, 62, 62, 66, 68, 68, 71, 72, 73, 77, 77, 78, 81, 81,
+ 53, 51, 51, 51, 49, 49, 49, 49, 49, 49, 49, 49, 51, 54, 54, 57, 59, 59,
+ 62, 64, 64, 69, 71, 71, 74, 75, 77, 81, 81, 83, 86, 86, 54, 52, 51, 51,
+ 50, 49, 49, 50, 50, 49, 49, 49, 51, 54, 54, 57, 60, 60, 63, 65, 65, 69,
+ 71, 72, 75, 76, 77, 81, 82, 83, 87, 87, 55, 53, 53, 52, 51, 50, 50, 51,
+ 51, 51, 50, 50, 52, 55, 55, 58, 61, 61, 64, 66, 66, 70, 72, 73, 76, 77,
+ 78, 83, 83, 85, 88, 88, 59, 57, 56, 56, 54, 54, 54, 54, 54, 54, 53, 53,
+ 55, 58, 58, 61, 64, 64, 67, 69, 69, 73, 75, 76, 79, 80, 81, 86, 87, 88,
+ 92, 92, 59, 57, 56, 56, 54, 54, 54, 54, 54, 54, 53, 53, 55, 58, 58, 61,
+ 64, 64, 67, 69, 69, 73, 75, 76, 79, 80, 81, 86, 87, 88, 92, 92],
+ /* Size 4x8 */
+ [32, 32, 37, 52, 32, 33, 36, 49, 32, 34, 38, 49, 34, 37, 44, 54, 35, 38,
+ 49, 60, 40, 42, 55, 69, 46, 46, 59, 76, 52, 51, 64, 83],
+ /* Size 8x4 */
+ [32, 32, 32, 34, 35, 40, 46, 52, 32, 33, 34, 37, 38, 42, 46, 51, 37, 36,
+ 38, 44, 49, 55, 59, 64, 52, 49, 49, 54, 60, 69, 76, 83],
+ /* Size 8x16 */
+ [32, 31, 32, 32, 36, 44, 47, 53, 31, 32, 32, 33, 35, 42, 45, 51, 31, 32,
+ 32, 33, 35, 41, 44, 49, 31, 32, 33, 33, 35, 41, 44, 49, 32, 32, 34, 34,
+ 36, 42, 45, 50, 32, 33, 35, 36, 38, 42, 45, 49, 32, 33, 35, 36, 40, 44,
+ 47, 51, 34, 34, 36, 38, 42, 48, 50, 54, 36, 34, 37, 40, 48, 54, 56, 60,
+ 38, 36, 39, 41, 49, 56, 58, 63, 39, 37, 40, 42, 50, 58, 60, 65, 44, 41,
+ 42, 45, 53, 63, 66, 71, 47, 44, 45, 47, 56, 66, 69, 75, 49, 46, 47, 48,
+ 57, 67, 71, 77, 53, 49, 50, 51, 60, 71, 75, 82, 58, 54, 54, 55, 63, 75,
+ 79, 87],
+ /* Size 16x8 */
+ [32, 31, 31, 31, 32, 32, 32, 34, 36, 38, 39, 44, 47, 49, 53, 58, 31, 32,
+ 32, 32, 32, 33, 33, 34, 34, 36, 37, 41, 44, 46, 49, 54, 32, 32, 32, 33,
+ 34, 35, 35, 36, 37, 39, 40, 42, 45, 47, 50, 54, 32, 33, 33, 33, 34, 36,
+ 36, 38, 40, 41, 42, 45, 47, 48, 51, 55, 36, 35, 35, 35, 36, 38, 40, 42,
+ 48, 49, 50, 53, 56, 57, 60, 63, 44, 42, 41, 41, 42, 42, 44, 48, 54, 56,
+ 58, 63, 66, 67, 71, 75, 47, 45, 44, 44, 45, 45, 47, 50, 56, 58, 60, 66,
+ 69, 71, 75, 79, 53, 51, 49, 49, 50, 49, 51, 54, 60, 63, 65, 71, 75, 77,
+ 82, 87],
+ /* Size 16x32 */
+ [32, 31, 31, 31, 32, 32, 32, 35, 36, 38, 44, 44, 47, 53, 53, 59, 31, 32,
+ 32, 32, 32, 32, 33, 35, 35, 37, 43, 43, 46, 52, 52, 57, 31, 32, 32, 32,
+ 32, 32, 33, 35, 35, 37, 42, 42, 45, 51, 51, 56, 31, 32, 32, 32, 32, 32,
+ 33, 35, 35, 37, 42, 42, 45, 51, 51, 56, 31, 32, 32, 32, 32, 32, 33, 34,
+ 35, 36, 41, 41, 44, 49, 49, 54, 31, 32, 32, 32, 32, 33, 33, 34, 34, 36,
+ 41, 41, 44, 49, 49, 54, 31, 32, 32, 32, 33, 33, 33, 35, 35, 36, 41, 41,
+ 44, 49, 49, 54, 32, 32, 32, 32, 33, 34, 34, 36, 36, 38, 42, 42, 45, 49,
+ 49, 54, 32, 32, 32, 33, 34, 34, 34, 36, 36, 38, 42, 42, 45, 50, 50, 54,
+ 32, 32, 32, 33, 34, 34, 35, 37, 37, 38, 42, 42, 45, 49, 49, 54, 32, 32,
+ 33, 33, 35, 35, 36, 38, 38, 39, 42, 42, 45, 49, 49, 53, 32, 32, 33, 33,
+ 35, 35, 36, 38, 38, 39, 42, 42, 45, 49, 49, 53, 32, 33, 33, 33, 35, 36,
+ 36, 39, 40, 41, 44, 44, 47, 51, 51, 55, 34, 34, 34, 34, 36, 37, 38, 42,
+ 42, 44, 48, 48, 50, 54, 54, 58, 34, 34, 34, 34, 36, 37, 38, 42, 42, 44,
+ 48, 48, 50, 54, 54, 58, 35, 34, 34, 34, 37, 37, 39, 44, 45, 46, 50, 50,
+ 53, 57, 57, 61, 36, 35, 34, 35, 37, 38, 40, 47, 48, 49, 54, 54, 56, 60,
+ 60, 64, 36, 35, 34, 35, 37, 38, 40, 47, 48, 49, 54, 54, 56, 60, 60, 64,
+ 38, 37, 36, 37, 39, 40, 41, 48, 49, 51, 56, 56, 58, 63, 63, 67, 39, 38,
+ 37, 38, 40, 40, 42, 49, 50, 52, 58, 58, 60, 65, 65, 69, 39, 38, 37, 38,
+ 40, 40, 42, 49, 50, 52, 58, 58, 60, 65, 65, 69, 42, 40, 40, 40, 42, 42,
+ 44, 51, 52, 55, 61, 61, 64, 69, 69, 73, 44, 42, 41, 41, 42, 43, 45, 52,
+ 53, 56, 63, 63, 66, 71, 71, 75, 44, 42, 41, 41, 43, 43, 45, 52, 54, 56,
+ 63, 63, 66, 72, 72, 76, 47, 45, 44, 44, 45, 45, 47, 54, 56, 58, 66, 66,
+ 69, 75, 75, 79, 48, 46, 45, 45, 46, 46, 48, 55, 56, 59, 67, 67, 70, 76,
+ 76, 80, 49, 47, 46, 46, 47, 47, 48, 56, 57, 60, 67, 67, 71, 77, 77, 81,
+ 53, 50, 49, 49, 49, 49, 51, 58, 59, 62, 71, 71, 74, 81, 81, 86, 53, 51,
+ 49, 49, 50, 50, 51, 59, 60, 63, 71, 71, 75, 82, 82, 87, 55, 52, 51, 51,
+ 51, 51, 53, 60, 61, 64, 72, 72, 76, 83, 83, 88, 58, 55, 54, 54, 54, 54,
+ 55, 62, 63, 67, 75, 75, 79, 87, 87, 92, 58, 55, 54, 54, 54, 54, 55, 62,
+ 63, 67, 75, 75, 79, 87, 87, 92],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 34, 34, 35, 36, 36,
+ 38, 39, 39, 42, 44, 44, 47, 48, 49, 53, 53, 55, 58, 58, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 34, 35, 35, 37, 38, 38, 40,
+ 42, 42, 45, 46, 47, 50, 51, 52, 55, 55, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 33, 33, 33, 34, 34, 34, 34, 34, 36, 37, 37, 40, 41, 41, 44, 45,
+ 46, 49, 49, 51, 54, 54, 31, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33,
+ 33, 34, 34, 34, 35, 35, 37, 38, 38, 40, 41, 41, 44, 45, 46, 49, 49, 51,
+ 54, 54, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 35, 35, 35, 36, 36, 37,
+ 37, 37, 39, 40, 40, 42, 42, 43, 45, 46, 47, 49, 50, 51, 54, 54, 32, 32,
+ 32, 32, 32, 33, 33, 34, 34, 34, 35, 35, 36, 37, 37, 37, 38, 38, 40, 40,
+ 40, 42, 43, 43, 45, 46, 47, 49, 50, 51, 54, 54, 32, 33, 33, 33, 33, 33,
+ 33, 34, 34, 35, 36, 36, 36, 38, 38, 39, 40, 40, 41, 42, 42, 44, 45, 45,
+ 47, 48, 48, 51, 51, 53, 55, 55, 35, 35, 35, 35, 34, 34, 35, 36, 36, 37,
+ 38, 38, 39, 42, 42, 44, 47, 47, 48, 49, 49, 51, 52, 52, 54, 55, 56, 58,
+ 59, 60, 62, 62, 36, 35, 35, 35, 35, 34, 35, 36, 36, 37, 38, 38, 40, 42,
+ 42, 45, 48, 48, 49, 50, 50, 52, 53, 54, 56, 56, 57, 59, 60, 61, 63, 63,
+ 38, 37, 37, 37, 36, 36, 36, 38, 38, 38, 39, 39, 41, 44, 44, 46, 49, 49,
+ 51, 52, 52, 55, 56, 56, 58, 59, 60, 62, 63, 64, 67, 67, 44, 43, 42, 42,
+ 41, 41, 41, 42, 42, 42, 42, 42, 44, 48, 48, 50, 54, 54, 56, 58, 58, 61,
+ 63, 63, 66, 67, 67, 71, 71, 72, 75, 75, 44, 43, 42, 42, 41, 41, 41, 42,
+ 42, 42, 42, 42, 44, 48, 48, 50, 54, 54, 56, 58, 58, 61, 63, 63, 66, 67,
+ 67, 71, 71, 72, 75, 75, 47, 46, 45, 45, 44, 44, 44, 45, 45, 45, 45, 45,
+ 47, 50, 50, 53, 56, 56, 58, 60, 60, 64, 66, 66, 69, 70, 71, 74, 75, 76,
+ 79, 79, 53, 52, 51, 51, 49, 49, 49, 49, 50, 49, 49, 49, 51, 54, 54, 57,
+ 60, 60, 63, 65, 65, 69, 71, 72, 75, 76, 77, 81, 82, 83, 87, 87, 53, 52,
+ 51, 51, 49, 49, 49, 49, 50, 49, 49, 49, 51, 54, 54, 57, 60, 60, 63, 65,
+ 65, 69, 71, 72, 75, 76, 77, 81, 82, 83, 87, 87, 59, 57, 56, 56, 54, 54,
+ 54, 54, 54, 54, 53, 53, 55, 58, 58, 61, 64, 64, 67, 69, 69, 73, 75, 76,
+ 79, 80, 81, 86, 87, 88, 92, 92],
+ /* Size 4x16 */
+ [31, 32, 38, 53, 32, 32, 37, 51, 32, 32, 36, 49, 32, 33, 36, 49, 32, 34,
+ 38, 50, 32, 35, 39, 49, 33, 36, 41, 51, 34, 37, 44, 54, 35, 38, 49, 60,
+ 37, 40, 51, 63, 38, 40, 52, 65, 42, 43, 56, 71, 45, 45, 58, 75, 47, 47,
+ 60, 77, 51, 50, 63, 82, 55, 54, 67, 87],
+ /* Size 16x4 */
+ [31, 32, 32, 32, 32, 32, 33, 34, 35, 37, 38, 42, 45, 47, 51, 55, 32, 32,
+ 32, 33, 34, 35, 36, 37, 38, 40, 40, 43, 45, 47, 50, 54, 38, 37, 36, 36,
+ 38, 39, 41, 44, 49, 51, 52, 56, 58, 60, 63, 67, 53, 51, 49, 49, 50, 49,
+ 51, 54, 60, 63, 65, 71, 75, 77, 82, 87],
+ /* Size 8x32 */
+ [32, 31, 32, 32, 36, 44, 47, 53, 31, 32, 32, 33, 35, 43, 46, 52, 31, 32,
+ 32, 33, 35, 42, 45, 51, 31, 32, 32, 33, 35, 42, 45, 51, 31, 32, 32, 33,
+ 35, 41, 44, 49, 31, 32, 32, 33, 34, 41, 44, 49, 31, 32, 33, 33, 35, 41,
+ 44, 49, 32, 32, 33, 34, 36, 42, 45, 49, 32, 32, 34, 34, 36, 42, 45, 50,
+ 32, 32, 34, 35, 37, 42, 45, 49, 32, 33, 35, 36, 38, 42, 45, 49, 32, 33,
+ 35, 36, 38, 42, 45, 49, 32, 33, 35, 36, 40, 44, 47, 51, 34, 34, 36, 38,
+ 42, 48, 50, 54, 34, 34, 36, 38, 42, 48, 50, 54, 35, 34, 37, 39, 45, 50,
+ 53, 57, 36, 34, 37, 40, 48, 54, 56, 60, 36, 34, 37, 40, 48, 54, 56, 60,
+ 38, 36, 39, 41, 49, 56, 58, 63, 39, 37, 40, 42, 50, 58, 60, 65, 39, 37,
+ 40, 42, 50, 58, 60, 65, 42, 40, 42, 44, 52, 61, 64, 69, 44, 41, 42, 45,
+ 53, 63, 66, 71, 44, 41, 43, 45, 54, 63, 66, 72, 47, 44, 45, 47, 56, 66,
+ 69, 75, 48, 45, 46, 48, 56, 67, 70, 76, 49, 46, 47, 48, 57, 67, 71, 77,
+ 53, 49, 49, 51, 59, 71, 74, 81, 53, 49, 50, 51, 60, 71, 75, 82, 55, 51,
+ 51, 53, 61, 72, 76, 83, 58, 54, 54, 55, 63, 75, 79, 87, 58, 54, 54, 55,
+ 63, 75, 79, 87],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 34, 34, 35, 36, 36,
+ 38, 39, 39, 42, 44, 44, 47, 48, 49, 53, 53, 55, 58, 58, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 34, 34, 36, 37, 37, 40,
+ 41, 41, 44, 45, 46, 49, 49, 51, 54, 54, 32, 32, 32, 32, 32, 32, 33, 33,
+ 34, 34, 35, 35, 35, 36, 36, 37, 37, 37, 39, 40, 40, 42, 42, 43, 45, 46,
+ 47, 49, 50, 51, 54, 54, 32, 33, 33, 33, 33, 33, 33, 34, 34, 35, 36, 36,
+ 36, 38, 38, 39, 40, 40, 41, 42, 42, 44, 45, 45, 47, 48, 48, 51, 51, 53,
+ 55, 55, 36, 35, 35, 35, 35, 34, 35, 36, 36, 37, 38, 38, 40, 42, 42, 45,
+ 48, 48, 49, 50, 50, 52, 53, 54, 56, 56, 57, 59, 60, 61, 63, 63, 44, 43,
+ 42, 42, 41, 41, 41, 42, 42, 42, 42, 42, 44, 48, 48, 50, 54, 54, 56, 58,
+ 58, 61, 63, 63, 66, 67, 67, 71, 71, 72, 75, 75, 47, 46, 45, 45, 44, 44,
+ 44, 45, 45, 45, 45, 45, 47, 50, 50, 53, 56, 56, 58, 60, 60, 64, 66, 66,
+ 69, 70, 71, 74, 75, 76, 79, 79, 53, 52, 51, 51, 49, 49, 49, 49, 50, 49,
+ 49, 49, 51, 54, 54, 57, 60, 60, 63, 65, 65, 69, 71, 72, 75, 76, 77, 81,
+ 82, 83, 87, 87]],
+ [ /* Chroma */
+ /* Size 4x4 */
+ [31, 38, 47, 49, 38, 47, 46, 46, 47, 46, 54, 57, 49, 46, 57, 66],
+ /* Size 8x8 */
+ [31, 31, 35, 42, 48, 47, 49, 51, 31, 32, 36, 42, 46, 45, 46, 48, 35, 36,
+ 41, 45, 47, 45, 46, 48, 42, 42, 45, 48, 50, 49, 50, 51, 48, 46, 47, 50,
+ 53, 53, 54, 54, 47, 45, 45, 49, 53, 57, 59, 60, 49, 46, 46, 50, 54, 59,
+ 61, 64, 51, 48, 48, 51, 54, 60, 64, 68],
+ /* Size 16x16 */
+ [32, 31, 30, 31, 33, 36, 38, 41, 49, 49, 48, 49, 50, 51, 52, 54, 31, 31,
+ 31, 32, 34, 38, 40, 42, 47, 47, 47, 47, 48, 48, 50, 52, 30, 31, 31, 32,
+ 35, 39, 41, 42, 46, 46, 46, 45, 46, 47, 48, 50, 31, 32, 32, 33, 36, 40,
+ 41, 43, 46, 46, 45, 45, 46, 46, 47, 49, 33, 34, 35, 36, 39, 43, 44, 45,
+ 47, 46, 46, 45, 46, 47, 47, 49, 36, 38, 39, 40, 43, 47, 47, 47, 48, 47,
+ 46, 45, 46, 46, 47, 48, 38, 40, 41, 41, 44, 47, 47, 48, 49, 48, 48, 47,
+ 47, 47, 48, 49, 41, 42, 42, 43, 45, 47, 48, 48, 50, 50, 49, 49, 50, 50,
+ 50, 52, 49, 47, 46, 46, 47, 48, 49, 50, 53, 53, 53, 53, 54, 54, 54, 55,
+ 49, 47, 46, 46, 46, 47, 48, 50, 53, 53, 54, 55, 55, 55, 56, 57, 48, 47,
+ 46, 45, 46, 46, 48, 49, 53, 54, 54, 55, 56, 56, 57, 58, 49, 47, 45, 45,
+ 45, 45, 47, 49, 53, 55, 55, 58, 59, 60, 61, 62, 50, 48, 46, 46, 46, 46,
+ 47, 50, 54, 55, 56, 59, 61, 61, 63, 64, 51, 48, 47, 46, 47, 46, 47, 50,
+ 54, 55, 56, 60, 61, 62, 64, 66, 52, 50, 48, 47, 47, 47, 48, 50, 54, 56,
+ 57, 61, 63, 64, 66, 68, 54, 52, 50, 49, 49, 48, 49, 52, 55, 57, 58, 62,
+ 64, 66, 68, 71],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 30, 30, 31, 33, 33, 34, 36, 36, 38, 41, 41, 45, 49, 49,
+ 49, 48, 48, 49, 49, 49, 50, 50, 51, 52, 52, 53, 54, 54, 31, 31, 31, 31,
+ 31, 31, 31, 34, 34, 35, 38, 38, 39, 42, 42, 45, 48, 48, 47, 47, 47, 47,
+ 47, 47, 49, 49, 49, 50, 50, 51, 53, 53, 31, 31, 31, 31, 31, 31, 32, 34,
+ 34, 35, 38, 38, 40, 42, 42, 45, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48,
+ 48, 49, 50, 50, 52, 52, 31, 31, 31, 31, 31, 31, 32, 34, 34, 36, 38, 38,
+ 40, 42, 42, 45, 47, 47, 47, 47, 47, 47, 46, 47, 48, 48, 48, 49, 49, 50,
+ 52, 52, 30, 31, 31, 31, 31, 31, 32, 35, 35, 36, 39, 39, 41, 42, 42, 44,
+ 46, 46, 46, 46, 46, 45, 45, 45, 46, 47, 47, 48, 48, 48, 50, 50, 30, 31,
+ 31, 31, 31, 32, 32, 35, 35, 36, 40, 40, 41, 42, 42, 44, 46, 46, 46, 45,
+ 45, 45, 45, 45, 46, 46, 46, 47, 47, 48, 49, 49, 31, 31, 32, 32, 32, 32,
+ 33, 35, 36, 37, 40, 40, 41, 43, 43, 44, 46, 46, 46, 45, 45, 45, 45, 45,
+ 46, 46, 46, 47, 47, 48, 49, 49, 33, 34, 34, 34, 35, 35, 35, 38, 38, 40,
+ 43, 43, 43, 44, 44, 46, 47, 47, 46, 46, 46, 45, 45, 45, 46, 46, 47, 47,
+ 47, 48, 49, 49, 33, 34, 34, 34, 35, 35, 36, 38, 39, 40, 43, 43, 44, 45,
+ 45, 46, 47, 47, 46, 46, 46, 45, 45, 45, 46, 46, 47, 47, 47, 48, 49, 49,
+ 34, 35, 35, 36, 36, 36, 37, 40, 40, 41, 44, 44, 45, 45, 45, 46, 47, 47,
+ 47, 46, 46, 45, 45, 45, 46, 46, 46, 47, 47, 48, 49, 49, 36, 38, 38, 38,
+ 39, 40, 40, 43, 43, 44, 47, 47, 47, 47, 47, 47, 48, 48, 47, 46, 46, 45,
+ 45, 45, 46, 46, 46, 46, 47, 47, 48, 48, 36, 38, 38, 38, 39, 40, 40, 43,
+ 43, 44, 47, 47, 47, 47, 47, 47, 48, 48, 47, 46, 46, 45, 45, 45, 46, 46,
+ 46, 46, 47, 47, 48, 48, 38, 39, 40, 40, 41, 41, 41, 43, 44, 45, 47, 47,
+ 47, 48, 48, 48, 49, 49, 48, 48, 48, 47, 47, 47, 47, 47, 47, 48, 48, 48,
+ 49, 49, 41, 42, 42, 42, 42, 42, 43, 44, 45, 45, 47, 47, 48, 48, 48, 49,
+ 50, 50, 50, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 52, 52, 41, 42,
+ 42, 42, 42, 42, 43, 44, 45, 45, 47, 47, 48, 48, 48, 49, 50, 50, 50, 49,
+ 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 52, 52, 45, 45, 45, 45, 44, 44,
+ 44, 46, 46, 46, 47, 47, 48, 49, 49, 50, 51, 51, 51, 51, 51, 51, 51, 51,
+ 52, 52, 52, 52, 52, 52, 53, 53, 49, 48, 47, 47, 46, 46, 46, 47, 47, 47,
+ 48, 48, 49, 50, 50, 51, 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54,
+ 54, 54, 55, 55, 49, 48, 47, 47, 46, 46, 46, 47, 47, 47, 48, 48, 49, 50,
+ 50, 51, 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 54, 55, 55,
+ 49, 47, 47, 47, 46, 46, 46, 46, 46, 47, 47, 47, 48, 50, 50, 51, 53, 53,
+ 53, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, 57, 57, 48, 47, 47, 47,
+ 46, 45, 45, 46, 46, 46, 46, 46, 48, 49, 49, 51, 53, 53, 54, 54, 54, 55,
+ 55, 56, 56, 56, 56, 57, 57, 58, 58, 58, 48, 47, 47, 47, 46, 45, 45, 46,
+ 46, 46, 46, 46, 48, 49, 49, 51, 53, 53, 54, 54, 54, 55, 55, 56, 56, 56,
+ 56, 57, 57, 58, 58, 58, 49, 47, 47, 47, 45, 45, 45, 45, 45, 45, 45, 45,
+ 47, 49, 49, 51, 53, 53, 54, 55, 55, 57, 57, 58, 58, 59, 59, 60, 60, 60,
+ 61, 61, 49, 47, 47, 46, 45, 45, 45, 45, 45, 45, 45, 45, 47, 49, 49, 51,
+ 53, 53, 55, 55, 55, 57, 58, 58, 59, 60, 60, 61, 61, 61, 62, 62, 49, 47,
+ 47, 47, 45, 45, 45, 45, 45, 45, 45, 45, 47, 49, 49, 51, 53, 53, 55, 56,
+ 56, 58, 58, 59, 59, 60, 60, 61, 61, 62, 63, 63, 50, 49, 48, 48, 46, 46,
+ 46, 46, 46, 46, 46, 46, 47, 50, 50, 52, 54, 54, 55, 56, 56, 58, 59, 59,
+ 61, 61, 61, 63, 63, 63, 64, 64, 50, 49, 48, 48, 47, 46, 46, 46, 46, 46,
+ 46, 46, 47, 50, 50, 52, 54, 54, 55, 56, 56, 59, 60, 60, 61, 61, 62, 63,
+ 63, 64, 65, 65, 51, 49, 48, 48, 47, 46, 46, 47, 47, 46, 46, 46, 47, 50,
+ 50, 52, 54, 54, 55, 56, 56, 59, 60, 60, 61, 62, 62, 64, 64, 64, 66, 66,
+ 52, 50, 49, 49, 48, 47, 47, 47, 47, 47, 46, 46, 48, 50, 50, 52, 54, 54,
+ 56, 57, 57, 60, 61, 61, 63, 63, 64, 66, 66, 67, 68, 68, 52, 50, 50, 49,
+ 48, 47, 47, 47, 47, 47, 47, 47, 48, 50, 50, 52, 54, 54, 56, 57, 57, 60,
+ 61, 61, 63, 63, 64, 66, 66, 67, 68, 68, 53, 51, 50, 50, 48, 48, 48, 48,
+ 48, 48, 47, 47, 48, 51, 51, 52, 54, 54, 56, 58, 58, 60, 61, 62, 63, 64,
+ 64, 67, 67, 68, 69, 69, 54, 53, 52, 52, 50, 49, 49, 49, 49, 49, 48, 48,
+ 49, 52, 52, 53, 55, 55, 57, 58, 58, 61, 62, 63, 64, 65, 66, 68, 68, 69,
+ 71, 71, 54, 53, 52, 52, 50, 49, 49, 49, 49, 49, 48, 48, 49, 52, 52, 53,
+ 55, 55, 57, 58, 58, 61, 62, 63, 64, 65, 66, 68, 68, 69, 71, 71],
+ /* Size 4x8 */
+ [31, 38, 47, 50, 31, 40, 46, 48, 36, 44, 47, 47, 42, 47, 50, 50, 47, 48,
+ 53, 54, 46, 46, 54, 60, 48, 46, 55, 64, 50, 48, 56, 67],
+ /* Size 8x4 */
+ [31, 31, 36, 42, 47, 46, 48, 50, 38, 40, 44, 47, 48, 46, 46, 48, 47, 46,
+ 47, 50, 53, 54, 55, 56, 50, 48, 47, 50, 54, 60, 64, 67],
+ /* Size 8x16 */
+ [32, 31, 35, 38, 48, 49, 50, 52, 31, 31, 37, 40, 47, 47, 48, 50, 30, 32,
+ 38, 40, 46, 45, 46, 48, 31, 33, 38, 41, 46, 45, 46, 48, 33, 36, 41, 44,
+ 47, 46, 46, 47, 37, 40, 45, 47, 47, 45, 46, 47, 39, 41, 46, 47, 48, 47,
+ 47, 48, 42, 43, 46, 48, 50, 49, 50, 50, 49, 46, 48, 49, 53, 53, 54, 54,
+ 48, 46, 47, 48, 53, 55, 55, 56, 48, 46, 46, 48, 53, 56, 56, 57, 49, 45,
+ 45, 47, 53, 58, 59, 61, 50, 46, 46, 48, 54, 59, 61, 63, 51, 47, 47, 48,
+ 54, 60, 61, 64, 52, 48, 47, 48, 54, 61, 63, 66, 54, 50, 49, 50, 55, 62,
+ 65, 68],
+ /* Size 16x8 */
+ [32, 31, 30, 31, 33, 37, 39, 42, 49, 48, 48, 49, 50, 51, 52, 54, 31, 31,
+ 32, 33, 36, 40, 41, 43, 46, 46, 46, 45, 46, 47, 48, 50, 35, 37, 38, 38,
+ 41, 45, 46, 46, 48, 47, 46, 45, 46, 47, 47, 49, 38, 40, 40, 41, 44, 47,
+ 47, 48, 49, 48, 48, 47, 48, 48, 48, 50, 48, 47, 46, 46, 47, 47, 48, 50,
+ 53, 53, 53, 53, 54, 54, 54, 55, 49, 47, 45, 45, 46, 45, 47, 49, 53, 55,
+ 56, 58, 59, 60, 61, 62, 50, 48, 46, 46, 46, 46, 47, 50, 54, 55, 56, 59,
+ 61, 61, 63, 65, 52, 50, 48, 48, 47, 47, 48, 50, 54, 56, 57, 61, 63, 64,
+ 66, 68],
+ /* Size 16x32 */
+ [32, 31, 31, 31, 35, 37, 38, 47, 48, 48, 49, 49, 50, 52, 52, 54, 31, 31,
+ 31, 32, 36, 38, 39, 46, 47, 47, 48, 48, 49, 50, 50, 53, 31, 31, 31, 32,
+ 37, 38, 40, 46, 47, 47, 47, 47, 48, 50, 50, 52, 31, 31, 31, 32, 37, 38,
+ 40, 46, 47, 47, 47, 47, 48, 50, 50, 52, 30, 31, 32, 32, 38, 39, 40, 45,
+ 46, 46, 45, 45, 46, 48, 48, 50, 30, 31, 32, 33, 38, 40, 41, 45, 46, 46,
+ 45, 45, 46, 48, 48, 50, 31, 32, 33, 33, 38, 40, 41, 45, 46, 46, 45, 45,
+ 46, 48, 48, 50, 33, 35, 35, 36, 41, 43, 43, 46, 47, 46, 45, 45, 46, 47,
+ 47, 49, 33, 35, 36, 36, 41, 43, 44, 46, 47, 46, 46, 46, 46, 47, 47, 49,
+ 34, 36, 37, 37, 42, 44, 45, 47, 47, 47, 45, 45, 46, 47, 47, 49, 37, 39,
+ 40, 41, 45, 47, 47, 47, 47, 47, 45, 45, 46, 47, 47, 48, 37, 39, 40, 41,
+ 45, 47, 47, 47, 47, 47, 45, 45, 46, 47, 47, 48, 39, 40, 41, 42, 46, 47,
+ 47, 48, 48, 48, 47, 47, 47, 48, 48, 50, 42, 42, 43, 43, 46, 47, 48, 50,
+ 50, 50, 49, 49, 50, 50, 50, 52, 42, 42, 43, 43, 46, 47, 48, 50, 50, 50,
+ 49, 49, 50, 50, 50, 52, 45, 45, 44, 45, 47, 47, 48, 51, 51, 51, 51, 51,
+ 52, 52, 52, 54, 49, 47, 46, 47, 48, 48, 49, 52, 53, 53, 53, 53, 54, 54,
+ 54, 55, 49, 47, 46, 47, 48, 48, 49, 52, 53, 53, 53, 53, 54, 54, 54, 55,
+ 48, 47, 46, 46, 47, 47, 48, 52, 53, 53, 55, 55, 55, 56, 56, 57, 48, 46,
+ 46, 46, 46, 47, 48, 52, 53, 54, 56, 56, 56, 57, 57, 59, 48, 46, 46, 46,
+ 46, 47, 48, 52, 53, 54, 56, 56, 56, 57, 57, 59, 49, 46, 45, 45, 46, 46,
+ 47, 52, 53, 54, 57, 57, 58, 60, 60, 61, 49, 46, 45, 45, 45, 46, 47, 52,
+ 53, 55, 58, 58, 59, 61, 61, 62, 49, 46, 45, 45, 46, 46, 47, 52, 53, 55,
+ 58, 58, 60, 61, 61, 63, 50, 47, 46, 46, 46, 46, 48, 53, 54, 55, 59, 59,
+ 61, 63, 63, 65, 50, 48, 46, 46, 46, 46, 48, 53, 54, 55, 59, 59, 61, 64,
+ 64, 65, 51, 48, 47, 47, 47, 47, 48, 53, 54, 55, 60, 60, 61, 64, 64, 66,
+ 52, 49, 48, 48, 47, 47, 48, 53, 54, 56, 61, 61, 63, 66, 66, 68, 52, 49,
+ 48, 48, 47, 47, 48, 53, 54, 56, 61, 61, 63, 66, 66, 68, 53, 50, 48, 48,
+ 48, 48, 49, 54, 54, 56, 61, 61, 63, 67, 67, 69, 54, 51, 50, 50, 49, 49,
+ 50, 55, 55, 57, 62, 62, 65, 68, 68, 71, 54, 51, 50, 50, 49, 49, 50, 55,
+ 55, 57, 62, 62, 65, 68, 68, 71],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 30, 30, 31, 33, 33, 34, 37, 37, 39, 42, 42, 45, 49, 49,
+ 48, 48, 48, 49, 49, 49, 50, 50, 51, 52, 52, 53, 54, 54, 31, 31, 31, 31,
+ 31, 31, 32, 35, 35, 36, 39, 39, 40, 42, 42, 45, 47, 47, 47, 46, 46, 46,
+ 46, 46, 47, 48, 48, 49, 49, 50, 51, 51, 31, 31, 31, 31, 32, 32, 33, 35,
+ 36, 37, 40, 40, 41, 43, 43, 44, 46, 46, 46, 46, 46, 45, 45, 45, 46, 46,
+ 47, 48, 48, 48, 50, 50, 31, 32, 32, 32, 32, 33, 33, 36, 36, 37, 41, 41,
+ 42, 43, 43, 45, 47, 47, 46, 46, 46, 45, 45, 45, 46, 46, 47, 48, 48, 48,
+ 50, 50, 35, 36, 37, 37, 38, 38, 38, 41, 41, 42, 45, 45, 46, 46, 46, 47,
+ 48, 48, 47, 46, 46, 46, 45, 46, 46, 46, 47, 47, 47, 48, 49, 49, 37, 38,
+ 38, 38, 39, 40, 40, 43, 43, 44, 47, 47, 47, 47, 47, 47, 48, 48, 47, 47,
+ 47, 46, 46, 46, 46, 46, 47, 47, 47, 48, 49, 49, 38, 39, 40, 40, 40, 41,
+ 41, 43, 44, 45, 47, 47, 47, 48, 48, 48, 49, 49, 48, 48, 48, 47, 47, 47,
+ 48, 48, 48, 48, 48, 49, 50, 50, 47, 46, 46, 46, 45, 45, 45, 46, 46, 47,
+ 47, 47, 48, 50, 50, 51, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53,
+ 53, 54, 55, 55, 48, 47, 47, 47, 46, 46, 46, 47, 47, 47, 47, 47, 48, 50,
+ 50, 51, 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 54, 55, 55,
+ 48, 47, 47, 47, 46, 46, 46, 46, 46, 47, 47, 47, 48, 50, 50, 51, 53, 53,
+ 53, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, 57, 57, 49, 48, 47, 47,
+ 45, 45, 45, 45, 46, 45, 45, 45, 47, 49, 49, 51, 53, 53, 55, 56, 56, 57,
+ 58, 58, 59, 59, 60, 61, 61, 61, 62, 62, 49, 48, 47, 47, 45, 45, 45, 45,
+ 46, 45, 45, 45, 47, 49, 49, 51, 53, 53, 55, 56, 56, 57, 58, 58, 59, 59,
+ 60, 61, 61, 61, 62, 62, 50, 49, 48, 48, 46, 46, 46, 46, 46, 46, 46, 46,
+ 47, 50, 50, 52, 54, 54, 55, 56, 56, 58, 59, 60, 61, 61, 61, 63, 63, 63,
+ 65, 65, 52, 50, 50, 50, 48, 48, 48, 47, 47, 47, 47, 47, 48, 50, 50, 52,
+ 54, 54, 56, 57, 57, 60, 61, 61, 63, 64, 64, 66, 66, 67, 68, 68, 52, 50,
+ 50, 50, 48, 48, 48, 47, 47, 47, 47, 47, 48, 50, 50, 52, 54, 54, 56, 57,
+ 57, 60, 61, 61, 63, 64, 64, 66, 66, 67, 68, 68, 54, 53, 52, 52, 50, 50,
+ 50, 49, 49, 49, 48, 48, 50, 52, 52, 54, 55, 55, 57, 59, 59, 61, 62, 63,
+ 65, 65, 66, 68, 68, 69, 71, 71],
+ /* Size 4x16 */
+ [31, 37, 48, 52, 31, 38, 47, 50, 31, 39, 46, 48, 32, 40, 46, 48, 35, 43,
+ 46, 47, 39, 47, 47, 47, 40, 47, 48, 48, 42, 47, 50, 50, 47, 48, 53, 54,
+ 47, 47, 53, 56, 46, 47, 54, 57, 46, 46, 55, 61, 47, 46, 55, 63, 48, 47,
+ 55, 64, 49, 47, 56, 66, 51, 49, 57, 68],
+ /* Size 16x4 */
+ [31, 31, 31, 32, 35, 39, 40, 42, 47, 47, 46, 46, 47, 48, 49, 51, 37, 38,
+ 39, 40, 43, 47, 47, 47, 48, 47, 47, 46, 46, 47, 47, 49, 48, 47, 46, 46,
+ 46, 47, 48, 50, 53, 53, 54, 55, 55, 55, 56, 57, 52, 50, 48, 48, 47, 47,
+ 48, 50, 54, 56, 57, 61, 63, 64, 66, 68],
+ /* Size 8x32 */
+ [32, 31, 35, 38, 48, 49, 50, 52, 31, 31, 36, 39, 47, 48, 49, 50, 31, 31,
+ 37, 40, 47, 47, 48, 50, 31, 31, 37, 40, 47, 47, 48, 50, 30, 32, 38, 40,
+ 46, 45, 46, 48, 30, 32, 38, 41, 46, 45, 46, 48, 31, 33, 38, 41, 46, 45,
+ 46, 48, 33, 35, 41, 43, 47, 45, 46, 47, 33, 36, 41, 44, 47, 46, 46, 47,
+ 34, 37, 42, 45, 47, 45, 46, 47, 37, 40, 45, 47, 47, 45, 46, 47, 37, 40,
+ 45, 47, 47, 45, 46, 47, 39, 41, 46, 47, 48, 47, 47, 48, 42, 43, 46, 48,
+ 50, 49, 50, 50, 42, 43, 46, 48, 50, 49, 50, 50, 45, 44, 47, 48, 51, 51,
+ 52, 52, 49, 46, 48, 49, 53, 53, 54, 54, 49, 46, 48, 49, 53, 53, 54, 54,
+ 48, 46, 47, 48, 53, 55, 55, 56, 48, 46, 46, 48, 53, 56, 56, 57, 48, 46,
+ 46, 48, 53, 56, 56, 57, 49, 45, 46, 47, 53, 57, 58, 60, 49, 45, 45, 47,
+ 53, 58, 59, 61, 49, 45, 46, 47, 53, 58, 60, 61, 50, 46, 46, 48, 54, 59,
+ 61, 63, 50, 46, 46, 48, 54, 59, 61, 64, 51, 47, 47, 48, 54, 60, 61, 64,
+ 52, 48, 47, 48, 54, 61, 63, 66, 52, 48, 47, 48, 54, 61, 63, 66, 53, 48,
+ 48, 49, 54, 61, 63, 67, 54, 50, 49, 50, 55, 62, 65, 68, 54, 50, 49, 50,
+ 55, 62, 65, 68],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 30, 30, 31, 33, 33, 34, 37, 37, 39, 42, 42, 45, 49, 49,
+ 48, 48, 48, 49, 49, 49, 50, 50, 51, 52, 52, 53, 54, 54, 31, 31, 31, 31,
+ 32, 32, 33, 35, 36, 37, 40, 40, 41, 43, 43, 44, 46, 46, 46, 46, 46, 45,
+ 45, 45, 46, 46, 47, 48, 48, 48, 50, 50, 35, 36, 37, 37, 38, 38, 38, 41,
+ 41, 42, 45, 45, 46, 46, 46, 47, 48, 48, 47, 46, 46, 46, 45, 46, 46, 46,
+ 47, 47, 47, 48, 49, 49, 38, 39, 40, 40, 40, 41, 41, 43, 44, 45, 47, 47,
+ 47, 48, 48, 48, 49, 49, 48, 48, 48, 47, 47, 47, 48, 48, 48, 48, 48, 49,
+ 50, 50, 48, 47, 47, 47, 46, 46, 46, 47, 47, 47, 47, 47, 48, 50, 50, 51,
+ 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 54, 55, 55, 49, 48,
+ 47, 47, 45, 45, 45, 45, 46, 45, 45, 45, 47, 49, 49, 51, 53, 53, 55, 56,
+ 56, 57, 58, 58, 59, 59, 60, 61, 61, 61, 62, 62, 50, 49, 48, 48, 46, 46,
+ 46, 46, 46, 46, 46, 46, 47, 50, 50, 52, 54, 54, 55, 56, 56, 58, 59, 60,
+ 61, 61, 61, 63, 63, 63, 65, 65, 52, 50, 50, 50, 48, 48, 48, 47, 47, 47,
+ 47, 47, 48, 50, 50, 52, 54, 54, 56, 57, 57, 60, 61, 61, 63, 64, 64, 66,
+ 66, 67, 68, 68]]
+ ],
+ [
+ [ /* Luma */
+ /* Size 4x4 */
+ [32, 32, 35, 43, 32, 34, 37, 43, 35, 37, 48, 54, 43, 43, 54, 65],
+ /* Size 8x8 */
+ [31, 31, 32, 32, 34, 37, 43, 47, 31, 32, 32, 32, 34, 36, 41, 44, 32, 32,
+ 33, 34, 35, 38, 42, 45, 32, 32, 34, 35, 37, 39, 42, 46, 34, 34, 35, 37,
+ 41, 45, 49, 52, 37, 36, 38, 39, 45, 51, 56, 59, 43, 41, 42, 42, 49, 56,
+ 63, 67, 47, 44, 45, 46, 52, 59, 67, 71],
+ /* Size 16x16 */
+ [32, 31, 31, 31, 31, 31, 32, 32, 34, 35, 36, 39, 41, 44, 47, 48, 31, 32,
+ 32, 32, 32, 32, 32, 33, 34, 35, 35, 38, 40, 42, 45, 46, 31, 32, 32, 32,
+ 32, 32, 32, 33, 34, 34, 35, 38, 39, 42, 45, 45, 31, 32, 32, 32, 32, 32,
+ 32, 33, 33, 34, 34, 37, 38, 41, 44, 44, 31, 32, 32, 32, 33, 33, 33, 34,
+ 35, 36, 36, 39, 40, 42, 44, 45, 31, 32, 32, 32, 33, 33, 34, 34, 35, 36,
+ 36, 39, 40, 42, 45, 45, 32, 32, 32, 32, 33, 34, 35, 36, 37, 38, 38, 40,
+ 41, 42, 45, 46, 32, 33, 33, 33, 34, 34, 36, 36, 38, 39, 40, 42, 43, 44,
+ 47, 47, 34, 34, 34, 33, 35, 35, 37, 38, 39, 42, 42, 45, 46, 47, 50, 51,
+ 35, 35, 34, 34, 36, 36, 38, 39, 42, 46, 47, 49, 50, 52, 55, 55, 36, 35,
+ 35, 34, 36, 36, 38, 40, 42, 47, 48, 50, 52, 54, 56, 57, 39, 38, 38, 37,
+ 39, 39, 40, 42, 45, 49, 50, 54, 55, 58, 60, 61, 41, 40, 39, 38, 40, 40,
+ 41, 43, 46, 50, 52, 55, 57, 60, 62, 63, 44, 42, 42, 41, 42, 42, 42, 44,
+ 47, 52, 54, 58, 60, 63, 66, 67, 47, 45, 45, 44, 44, 45, 45, 47, 50, 55,
+ 56, 60, 62, 66, 69, 70, 48, 46, 45, 44, 45, 45, 46, 47, 51, 55, 57, 61,
+ 63, 67, 70, 71],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 34, 34, 34,
+ 35, 36, 36, 38, 39, 39, 41, 44, 44, 45, 47, 48, 48, 51, 31, 31, 31, 31,
+ 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 34, 35, 35, 35, 37,
+ 39, 39, 40, 43, 43, 44, 46, 47, 47, 50, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 33, 34, 34, 34, 35, 35, 35, 37, 38, 38, 40, 42,
+ 42, 43, 45, 46, 46, 49, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 33, 34, 34, 34, 35, 35, 35, 37, 38, 38, 40, 42, 42, 43, 45, 46,
+ 46, 49, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34,
+ 34, 34, 34, 35, 35, 36, 38, 38, 39, 42, 42, 42, 45, 45, 45, 48, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34,
+ 34, 36, 37, 37, 38, 41, 41, 41, 44, 44, 44, 47, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 34, 36, 37, 37,
+ 38, 41, 41, 41, 44, 44, 44, 47, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 36, 38, 38, 39, 41, 41, 42,
+ 44, 45, 45, 47, 31, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33,
+ 34, 35, 35, 35, 36, 36, 36, 37, 39, 39, 40, 42, 42, 42, 44, 45, 45, 48,
+ 31, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 35, 35, 35,
+ 36, 36, 36, 38, 39, 39, 40, 42, 42, 42, 45, 45, 45, 48, 31, 32, 32, 32,
+ 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 38,
+ 39, 39, 40, 42, 42, 42, 45, 45, 45, 48, 32, 32, 32, 32, 32, 32, 32, 33,
+ 33, 33, 33, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 39, 40, 40, 41, 42,
+ 42, 43, 45, 45, 45, 48, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 35,
+ 35, 35, 36, 37, 37, 37, 38, 38, 38, 39, 40, 40, 41, 42, 42, 43, 45, 46,
+ 46, 48, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 35, 35, 35, 36, 37,
+ 37, 37, 38, 38, 38, 39, 40, 40, 41, 42, 42, 43, 45, 46, 46, 48, 32, 33,
+ 33, 33, 33, 33, 33, 33, 34, 34, 34, 35, 36, 36, 36, 38, 38, 38, 39, 40,
+ 40, 41, 42, 42, 43, 44, 44, 45, 47, 47, 47, 50, 34, 34, 34, 34, 34, 33,
+ 33, 34, 35, 35, 35, 36, 37, 37, 38, 39, 39, 40, 42, 42, 42, 44, 45, 45,
+ 46, 47, 47, 48, 50, 51, 51, 53, 34, 34, 34, 34, 34, 33, 33, 34, 35, 35,
+ 35, 36, 37, 37, 38, 39, 39, 40, 42, 42, 42, 44, 45, 45, 46, 47, 47, 48,
+ 50, 51, 51, 53, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 36, 37, 37,
+ 38, 40, 40, 41, 43, 44, 44, 45, 46, 46, 47, 49, 49, 49, 51, 52, 52, 54,
+ 35, 35, 35, 35, 34, 34, 34, 34, 36, 36, 36, 37, 38, 38, 39, 42, 42, 43,
+ 46, 47, 47, 48, 49, 49, 50, 52, 52, 53, 55, 55, 55, 57, 36, 35, 35, 35,
+ 35, 34, 34, 35, 36, 36, 36, 37, 38, 38, 40, 42, 42, 44, 47, 48, 48, 50,
+ 50, 50, 52, 54, 54, 54, 56, 57, 57, 58, 36, 35, 35, 35, 35, 34, 34, 35,
+ 36, 36, 36, 37, 38, 38, 40, 42, 42, 44, 47, 48, 48, 50, 50, 50, 52, 54,
+ 54, 54, 56, 57, 57, 58, 38, 37, 37, 37, 36, 36, 36, 36, 37, 38, 38, 39,
+ 39, 39, 41, 44, 44, 45, 48, 50, 50, 51, 52, 52, 54, 56, 56, 57, 58, 59,
+ 59, 61, 39, 39, 38, 38, 38, 37, 37, 38, 39, 39, 39, 40, 40, 40, 42, 45,
+ 45, 46, 49, 50, 50, 52, 54, 54, 55, 58, 58, 58, 60, 61, 61, 63, 39, 39,
+ 38, 38, 38, 37, 37, 38, 39, 39, 39, 40, 40, 40, 42, 45, 45, 46, 49, 50,
+ 50, 52, 54, 54, 55, 58, 58, 58, 60, 61, 61, 63, 41, 40, 40, 40, 39, 38,
+ 38, 39, 40, 40, 40, 41, 41, 41, 43, 46, 46, 47, 50, 52, 52, 54, 55, 55,
+ 57, 60, 60, 60, 62, 63, 63, 66, 44, 43, 42, 42, 42, 41, 41, 41, 42, 42,
+ 42, 42, 42, 42, 44, 47, 47, 49, 52, 54, 54, 56, 58, 58, 60, 63, 63, 64,
+ 66, 67, 67, 69, 44, 43, 42, 42, 42, 41, 41, 41, 42, 42, 42, 42, 42, 42,
+ 44, 47, 47, 49, 52, 54, 54, 56, 58, 58, 60, 63, 63, 64, 66, 67, 67, 69,
+ 45, 44, 43, 43, 42, 41, 41, 42, 42, 42, 42, 43, 43, 43, 45, 48, 48, 49,
+ 53, 54, 54, 57, 58, 58, 60, 64, 64, 65, 67, 68, 68, 70, 47, 46, 45, 45,
+ 45, 44, 44, 44, 44, 45, 45, 45, 45, 45, 47, 50, 50, 51, 55, 56, 56, 58,
+ 60, 60, 62, 66, 66, 67, 69, 70, 70, 73, 48, 47, 46, 46, 45, 44, 44, 45,
+ 45, 45, 45, 45, 46, 46, 47, 51, 51, 52, 55, 57, 57, 59, 61, 61, 63, 67,
+ 67, 68, 70, 71, 71, 74, 48, 47, 46, 46, 45, 44, 44, 45, 45, 45, 45, 45,
+ 46, 46, 47, 51, 51, 52, 55, 57, 57, 59, 61, 61, 63, 67, 67, 68, 70, 71,
+ 71, 74, 51, 50, 49, 49, 48, 47, 47, 47, 48, 48, 48, 48, 48, 48, 50, 53,
+ 53, 54, 57, 58, 58, 61, 63, 63, 66, 69, 69, 70, 73, 74, 74, 77],
+ /* Size 4x8 */
+ [31, 32, 35, 43, 32, 33, 34, 41, 32, 34, 36, 42, 32, 35, 38, 42, 34, 37,
+ 43, 49, 37, 40, 49, 56, 42, 43, 53, 63, 46, 46, 56, 67],
+ /* Size 8x4 */
+ [31, 32, 32, 32, 34, 37, 42, 46, 32, 33, 34, 35, 37, 40, 43, 46, 35, 34,
+ 36, 38, 43, 49, 53, 56, 43, 41, 42, 42, 49, 56, 63, 67],
+ /* Size 8x16 */
+ [32, 31, 31, 32, 35, 36, 44, 47, 31, 32, 32, 32, 35, 35, 42, 45, 31, 32,
+ 32, 32, 34, 35, 41, 45, 31, 32, 32, 33, 34, 34, 41, 44, 31, 32, 33, 34,
+ 35, 36, 42, 44, 32, 32, 33, 34, 36, 36, 42, 45, 32, 33, 34, 35, 37, 38,
+ 42, 45, 32, 33, 34, 36, 39, 40, 44, 47, 34, 34, 35, 37, 41, 42, 48, 50,
+ 35, 34, 36, 38, 45, 47, 52, 55, 36, 34, 36, 38, 46, 48, 54, 56, 39, 37,
+ 39, 40, 48, 50, 58, 60, 41, 39, 40, 41, 49, 51, 60, 62, 44, 41, 42, 43,
+ 51, 53, 63, 66, 47, 44, 44, 45, 53, 56, 66, 69, 48, 45, 45, 46, 54, 56,
+ 67, 70],
+ /* Size 16x8 */
+ [32, 31, 31, 31, 31, 32, 32, 32, 34, 35, 36, 39, 41, 44, 47, 48, 31, 32,
+ 32, 32, 32, 32, 33, 33, 34, 34, 34, 37, 39, 41, 44, 45, 31, 32, 32, 32,
+ 33, 33, 34, 34, 35, 36, 36, 39, 40, 42, 44, 45, 32, 32, 32, 33, 34, 34,
+ 35, 36, 37, 38, 38, 40, 41, 43, 45, 46, 35, 35, 34, 34, 35, 36, 37, 39,
+ 41, 45, 46, 48, 49, 51, 53, 54, 36, 35, 35, 34, 36, 36, 38, 40, 42, 47,
+ 48, 50, 51, 53, 56, 56, 44, 42, 41, 41, 42, 42, 42, 44, 48, 52, 54, 58,
+ 60, 63, 66, 67, 47, 45, 45, 44, 44, 45, 45, 47, 50, 55, 56, 60, 62, 66,
+ 69, 70],
+ /* Size 16x32 */
+ [32, 31, 31, 31, 31, 32, 32, 32, 35, 36, 36, 40, 44, 44, 47, 53, 31, 31,
+ 32, 32, 32, 32, 32, 33, 35, 35, 35, 39, 43, 43, 46, 52, 31, 32, 32, 32,
+ 32, 32, 32, 33, 35, 35, 35, 39, 42, 42, 45, 51, 31, 32, 32, 32, 32, 32,
+ 32, 33, 35, 35, 35, 39, 42, 42, 45, 51, 31, 32, 32, 32, 32, 32, 32, 33,
+ 34, 35, 35, 39, 41, 41, 45, 50, 31, 32, 32, 32, 32, 33, 33, 33, 34, 34,
+ 34, 38, 41, 41, 44, 49, 31, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 38,
+ 41, 41, 44, 49, 31, 32, 32, 32, 32, 33, 33, 33, 34, 35, 35, 38, 41, 41,
+ 44, 49, 31, 32, 32, 32, 33, 34, 34, 34, 35, 36, 36, 39, 42, 42, 44, 49,
+ 32, 32, 32, 32, 33, 34, 34, 34, 36, 36, 36, 39, 42, 42, 45, 50, 32, 32,
+ 32, 32, 33, 34, 34, 34, 36, 36, 36, 39, 42, 42, 45, 50, 32, 32, 32, 32,
+ 33, 35, 35, 35, 37, 37, 37, 40, 42, 42, 45, 49, 32, 32, 33, 33, 34, 35,
+ 35, 36, 37, 38, 38, 41, 42, 42, 45, 49, 32, 32, 33, 33, 34, 35, 35, 36,
+ 37, 38, 38, 41, 42, 42, 45, 49, 32, 33, 33, 33, 34, 36, 36, 36, 39, 40,
+ 40, 42, 44, 44, 47, 51, 34, 34, 34, 34, 35, 37, 37, 38, 41, 42, 42, 45,
+ 48, 48, 50, 54, 34, 34, 34, 34, 35, 37, 37, 38, 41, 42, 42, 45, 48, 48,
+ 50, 54, 34, 34, 34, 34, 35, 37, 37, 38, 42, 43, 43, 46, 49, 49, 51, 55,
+ 35, 35, 34, 34, 36, 38, 38, 39, 45, 47, 47, 50, 52, 52, 55, 59, 36, 35,
+ 34, 34, 36, 38, 38, 40, 46, 48, 48, 51, 54, 54, 56, 60, 36, 35, 34, 34,
+ 36, 38, 38, 40, 46, 48, 48, 51, 54, 54, 56, 60, 38, 37, 36, 36, 37, 40,
+ 40, 41, 47, 49, 49, 53, 56, 56, 58, 63, 39, 38, 37, 37, 39, 40, 40, 42,
+ 48, 50, 50, 54, 58, 58, 60, 65, 39, 38, 37, 37, 39, 40, 40, 42, 48, 50,
+ 50, 54, 58, 58, 60, 65, 41, 40, 39, 39, 40, 41, 41, 43, 49, 51, 51, 56,
+ 60, 60, 62, 67, 44, 42, 41, 41, 42, 43, 43, 45, 51, 53, 53, 59, 63, 63,
+ 66, 71, 44, 42, 41, 41, 42, 43, 43, 45, 51, 53, 53, 59, 63, 63, 66, 71,
+ 44, 43, 42, 42, 42, 43, 43, 45, 51, 54, 54, 59, 64, 64, 67, 72, 47, 45,
+ 44, 44, 44, 45, 45, 47, 53, 56, 56, 61, 66, 66, 69, 75, 48, 46, 45, 45,
+ 45, 46, 46, 48, 54, 56, 56, 62, 67, 67, 70, 76, 48, 46, 45, 45, 45, 46,
+ 46, 48, 54, 56, 56, 62, 67, 67, 70, 76, 51, 49, 47, 47, 48, 48, 48, 50,
+ 56, 58, 58, 64, 69, 69, 73, 79],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 34, 34, 34,
+ 35, 36, 36, 38, 39, 39, 41, 44, 44, 44, 47, 48, 48, 51, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 34, 35, 35, 35, 37,
+ 38, 38, 40, 42, 42, 43, 45, 46, 46, 49, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 34, 34, 34, 36, 37, 37, 39, 41,
+ 41, 42, 44, 45, 45, 47, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 33, 33, 33, 34, 34, 34, 34, 34, 34, 36, 37, 37, 39, 41, 41, 42, 44, 45,
+ 45, 47, 31, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 35,
+ 35, 35, 36, 36, 36, 37, 39, 39, 40, 42, 42, 42, 44, 45, 45, 48, 32, 32,
+ 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 37, 37, 37, 38, 38,
+ 38, 40, 40, 40, 41, 43, 43, 43, 45, 46, 46, 48, 32, 32, 32, 32, 32, 33,
+ 33, 33, 34, 34, 34, 35, 35, 35, 36, 37, 37, 37, 38, 38, 38, 40, 40, 40,
+ 41, 43, 43, 43, 45, 46, 46, 48, 32, 33, 33, 33, 33, 33, 33, 33, 34, 34,
+ 34, 35, 36, 36, 36, 38, 38, 38, 39, 40, 40, 41, 42, 42, 43, 45, 45, 45,
+ 47, 48, 48, 50, 35, 35, 35, 35, 34, 34, 34, 34, 35, 36, 36, 37, 37, 37,
+ 39, 41, 41, 42, 45, 46, 46, 47, 48, 48, 49, 51, 51, 51, 53, 54, 54, 56,
+ 36, 35, 35, 35, 35, 34, 34, 35, 36, 36, 36, 37, 38, 38, 40, 42, 42, 43,
+ 47, 48, 48, 49, 50, 50, 51, 53, 53, 54, 56, 56, 56, 58, 36, 35, 35, 35,
+ 35, 34, 34, 35, 36, 36, 36, 37, 38, 38, 40, 42, 42, 43, 47, 48, 48, 49,
+ 50, 50, 51, 53, 53, 54, 56, 56, 56, 58, 40, 39, 39, 39, 39, 38, 38, 38,
+ 39, 39, 39, 40, 41, 41, 42, 45, 45, 46, 50, 51, 51, 53, 54, 54, 56, 59,
+ 59, 59, 61, 62, 62, 64, 44, 43, 42, 42, 41, 41, 41, 41, 42, 42, 42, 42,
+ 42, 42, 44, 48, 48, 49, 52, 54, 54, 56, 58, 58, 60, 63, 63, 64, 66, 67,
+ 67, 69, 44, 43, 42, 42, 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 44, 48,
+ 48, 49, 52, 54, 54, 56, 58, 58, 60, 63, 63, 64, 66, 67, 67, 69, 47, 46,
+ 45, 45, 45, 44, 44, 44, 44, 45, 45, 45, 45, 45, 47, 50, 50, 51, 55, 56,
+ 56, 58, 60, 60, 62, 66, 66, 67, 69, 70, 70, 73, 53, 52, 51, 51, 50, 49,
+ 49, 49, 49, 50, 50, 49, 49, 49, 51, 54, 54, 55, 59, 60, 60, 63, 65, 65,
+ 67, 71, 71, 72, 75, 76, 76, 79],
+ /* Size 4x16 */
+ [31, 32, 36, 44, 32, 32, 35, 42, 32, 32, 35, 41, 32, 33, 34, 41, 32, 34,
+ 36, 42, 32, 34, 36, 42, 32, 35, 38, 42, 33, 36, 40, 44, 34, 37, 42, 48,
+ 35, 38, 47, 52, 35, 38, 48, 54, 38, 40, 50, 58, 40, 41, 51, 60, 42, 43,
+ 53, 63, 45, 45, 56, 66, 46, 46, 56, 67],
+ /* Size 16x4 */
+ [31, 32, 32, 32, 32, 32, 32, 33, 34, 35, 35, 38, 40, 42, 45, 46, 32, 32,
+ 32, 33, 34, 34, 35, 36, 37, 38, 38, 40, 41, 43, 45, 46, 36, 35, 35, 34,
+ 36, 36, 38, 40, 42, 47, 48, 50, 51, 53, 56, 56, 44, 42, 41, 41, 42, 42,
+ 42, 44, 48, 52, 54, 58, 60, 63, 66, 67],
+ /* Size 8x32 */
+ [32, 31, 31, 32, 35, 36, 44, 47, 31, 32, 32, 32, 35, 35, 43, 46, 31, 32,
+ 32, 32, 35, 35, 42, 45, 31, 32, 32, 32, 35, 35, 42, 45, 31, 32, 32, 32,
+ 34, 35, 41, 45, 31, 32, 32, 33, 34, 34, 41, 44, 31, 32, 32, 33, 34, 34,
+ 41, 44, 31, 32, 32, 33, 34, 35, 41, 44, 31, 32, 33, 34, 35, 36, 42, 44,
+ 32, 32, 33, 34, 36, 36, 42, 45, 32, 32, 33, 34, 36, 36, 42, 45, 32, 32,
+ 33, 35, 37, 37, 42, 45, 32, 33, 34, 35, 37, 38, 42, 45, 32, 33, 34, 35,
+ 37, 38, 42, 45, 32, 33, 34, 36, 39, 40, 44, 47, 34, 34, 35, 37, 41, 42,
+ 48, 50, 34, 34, 35, 37, 41, 42, 48, 50, 34, 34, 35, 37, 42, 43, 49, 51,
+ 35, 34, 36, 38, 45, 47, 52, 55, 36, 34, 36, 38, 46, 48, 54, 56, 36, 34,
+ 36, 38, 46, 48, 54, 56, 38, 36, 37, 40, 47, 49, 56, 58, 39, 37, 39, 40,
+ 48, 50, 58, 60, 39, 37, 39, 40, 48, 50, 58, 60, 41, 39, 40, 41, 49, 51,
+ 60, 62, 44, 41, 42, 43, 51, 53, 63, 66, 44, 41, 42, 43, 51, 53, 63, 66,
+ 44, 42, 42, 43, 51, 54, 64, 67, 47, 44, 44, 45, 53, 56, 66, 69, 48, 45,
+ 45, 46, 54, 56, 67, 70, 48, 45, 45, 46, 54, 56, 67, 70, 51, 47, 48, 48,
+ 56, 58, 69, 73],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 34, 34, 34,
+ 35, 36, 36, 38, 39, 39, 41, 44, 44, 44, 47, 48, 48, 51, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 34, 34, 34, 36,
+ 37, 37, 39, 41, 41, 42, 44, 45, 45, 47, 31, 32, 32, 32, 32, 32, 32, 32,
+ 33, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 39, 39, 40, 42,
+ 42, 42, 44, 45, 45, 48, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35,
+ 35, 35, 36, 37, 37, 37, 38, 38, 38, 40, 40, 40, 41, 43, 43, 43, 45, 46,
+ 46, 48, 35, 35, 35, 35, 34, 34, 34, 34, 35, 36, 36, 37, 37, 37, 39, 41,
+ 41, 42, 45, 46, 46, 47, 48, 48, 49, 51, 51, 51, 53, 54, 54, 56, 36, 35,
+ 35, 35, 35, 34, 34, 35, 36, 36, 36, 37, 38, 38, 40, 42, 42, 43, 47, 48,
+ 48, 49, 50, 50, 51, 53, 53, 54, 56, 56, 56, 58, 44, 43, 42, 42, 41, 41,
+ 41, 41, 42, 42, 42, 42, 42, 42, 44, 48, 48, 49, 52, 54, 54, 56, 58, 58,
+ 60, 63, 63, 64, 66, 67, 67, 69, 47, 46, 45, 45, 45, 44, 44, 44, 44, 45,
+ 45, 45, 45, 45, 47, 50, 50, 51, 55, 56, 56, 58, 60, 60, 62, 66, 66, 67,
+ 69, 70, 70, 73]],
+ [ /* Chroma */
+ /* Size 4x4 */
+ [31, 37, 47, 47, 37, 44, 47, 45, 47, 47, 53, 53, 47, 45, 53, 59],
+ /* Size 8x8 */
+ [31, 31, 34, 37, 43, 48, 47, 49, 31, 32, 35, 40, 43, 46, 45, 46, 34, 35,
+ 39, 43, 45, 46, 45, 46, 37, 40, 43, 47, 47, 47, 45, 46, 43, 43, 45, 47,
+ 49, 50, 50, 50, 48, 46, 46, 47, 50, 53, 55, 55, 47, 45, 45, 45, 50, 55,
+ 58, 60, 49, 46, 46, 46, 50, 55, 60, 61],
+ /* Size 16x16 */
+ [32, 31, 31, 30, 33, 33, 36, 38, 41, 47, 49, 48, 49, 49, 50, 50, 31, 31,
+ 31, 31, 34, 34, 38, 40, 42, 46, 47, 47, 47, 47, 48, 48, 31, 31, 31, 31,
+ 34, 35, 39, 40, 42, 46, 47, 46, 46, 46, 47, 47, 30, 31, 31, 32, 34, 35,
+ 40, 41, 42, 45, 46, 45, 45, 45, 46, 46, 33, 34, 34, 34, 37, 38, 42, 43,
+ 44, 46, 47, 46, 46, 45, 46, 46, 33, 34, 35, 35, 38, 39, 43, 44, 45, 47,
+ 47, 46, 46, 45, 46, 46, 36, 38, 39, 40, 42, 43, 47, 47, 47, 47, 48, 46,
+ 46, 45, 46, 46, 38, 40, 40, 41, 43, 44, 47, 47, 48, 48, 49, 48, 47, 47,
+ 47, 47, 41, 42, 42, 42, 44, 45, 47, 48, 48, 50, 50, 49, 49, 49, 50, 50,
+ 47, 46, 46, 45, 46, 47, 47, 48, 50, 52, 52, 52, 52, 52, 53, 53, 49, 47,
+ 47, 46, 47, 47, 48, 49, 50, 52, 53, 53, 53, 53, 54, 54, 48, 47, 46, 45,
+ 46, 46, 46, 48, 49, 52, 53, 54, 55, 55, 56, 56, 49, 47, 46, 45, 46, 46,
+ 46, 47, 49, 52, 53, 55, 55, 57, 57, 58, 49, 47, 46, 45, 45, 45, 45, 47,
+ 49, 52, 53, 55, 57, 58, 59, 60, 50, 48, 47, 46, 46, 46, 46, 47, 50, 53,
+ 54, 56, 57, 59, 61, 61, 50, 48, 47, 46, 46, 46, 46, 47, 50, 53, 54, 56,
+ 58, 60, 61, 61],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 30, 30, 31, 33, 33, 33, 35, 36, 36, 38, 41, 41, 43,
+ 47, 49, 49, 49, 48, 48, 49, 49, 49, 49, 50, 50, 50, 51, 31, 31, 31, 31,
+ 31, 31, 31, 31, 33, 34, 34, 36, 37, 37, 39, 42, 42, 43, 47, 48, 48, 48,
+ 47, 47, 47, 47, 47, 48, 49, 49, 49, 50, 31, 31, 31, 31, 31, 31, 31, 32,
+ 34, 34, 34, 37, 38, 38, 40, 42, 42, 43, 46, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 48, 48, 48, 49, 31, 31, 31, 31, 31, 31, 31, 32, 34, 34, 34, 37,
+ 38, 38, 40, 42, 42, 43, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48,
+ 48, 49, 31, 31, 31, 31, 31, 31, 31, 32, 34, 35, 35, 37, 39, 39, 40, 42,
+ 42, 43, 46, 47, 47, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 48, 30, 31,
+ 31, 31, 31, 32, 32, 32, 34, 35, 35, 38, 40, 40, 41, 42, 42, 43, 45, 46,
+ 46, 46, 45, 45, 45, 45, 45, 45, 46, 46, 46, 47, 30, 31, 31, 31, 31, 32,
+ 32, 32, 34, 35, 35, 38, 40, 40, 41, 42, 42, 43, 45, 46, 46, 46, 45, 45,
+ 45, 45, 45, 45, 46, 46, 46, 47, 31, 31, 32, 32, 32, 32, 32, 33, 35, 36,
+ 36, 38, 40, 40, 41, 43, 43, 43, 46, 46, 46, 46, 45, 45, 45, 45, 45, 45,
+ 46, 46, 46, 47, 33, 33, 34, 34, 34, 34, 34, 35, 37, 38, 38, 41, 42, 42,
+ 43, 44, 44, 45, 46, 47, 47, 46, 46, 46, 46, 45, 45, 45, 46, 46, 46, 47,
+ 33, 34, 34, 34, 35, 35, 35, 36, 38, 39, 39, 41, 43, 43, 44, 45, 45, 45,
+ 47, 47, 47, 46, 46, 46, 46, 45, 45, 45, 46, 46, 46, 47, 33, 34, 34, 34,
+ 35, 35, 35, 36, 38, 39, 39, 41, 43, 43, 44, 45, 45, 45, 47, 47, 47, 46,
+ 46, 46, 46, 45, 45, 45, 46, 46, 46, 47, 35, 36, 37, 37, 37, 38, 38, 38,
+ 41, 41, 41, 44, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 46, 46, 46, 45,
+ 45, 45, 46, 46, 46, 47, 36, 37, 38, 38, 39, 40, 40, 40, 42, 43, 43, 46,
+ 47, 47, 47, 47, 47, 47, 47, 48, 48, 47, 46, 46, 46, 45, 45, 45, 46, 46,
+ 46, 46, 36, 37, 38, 38, 39, 40, 40, 40, 42, 43, 43, 46, 47, 47, 47, 47,
+ 47, 47, 47, 48, 48, 47, 46, 46, 46, 45, 45, 45, 46, 46, 46, 46, 38, 39,
+ 40, 40, 40, 41, 41, 41, 43, 44, 44, 46, 47, 47, 47, 48, 48, 48, 48, 49,
+ 49, 48, 48, 48, 47, 47, 47, 47, 47, 47, 47, 48, 41, 42, 42, 42, 42, 42,
+ 42, 43, 44, 45, 45, 46, 47, 47, 48, 48, 48, 49, 50, 50, 50, 50, 49, 49,
+ 49, 49, 49, 49, 50, 50, 50, 50, 41, 42, 42, 42, 42, 42, 42, 43, 44, 45,
+ 45, 46, 47, 47, 48, 48, 48, 49, 50, 50, 50, 50, 49, 49, 49, 49, 49, 49,
+ 50, 50, 50, 50, 43, 43, 43, 43, 43, 43, 43, 43, 45, 45, 45, 46, 47, 47,
+ 48, 49, 49, 49, 50, 51, 51, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51,
+ 47, 47, 46, 46, 46, 45, 45, 46, 46, 47, 47, 47, 47, 47, 48, 50, 50, 50,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 49, 48, 47, 47,
+ 47, 46, 46, 46, 47, 47, 47, 47, 48, 48, 49, 50, 50, 51, 52, 53, 53, 53,
+ 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 49, 48, 47, 47, 47, 46, 46, 46,
+ 47, 47, 47, 47, 48, 48, 49, 50, 50, 51, 52, 53, 53, 53, 53, 53, 53, 53,
+ 53, 53, 54, 54, 54, 54, 49, 48, 47, 47, 46, 46, 46, 46, 46, 46, 46, 47,
+ 47, 47, 48, 50, 50, 50, 52, 53, 53, 53, 54, 54, 54, 55, 55, 55, 55, 55,
+ 55, 56, 48, 47, 47, 47, 46, 45, 45, 45, 46, 46, 46, 46, 46, 46, 48, 49,
+ 49, 50, 52, 53, 53, 54, 54, 54, 55, 55, 55, 56, 56, 56, 56, 57, 48, 47,
+ 47, 47, 46, 45, 45, 45, 46, 46, 46, 46, 46, 46, 48, 49, 49, 50, 52, 53,
+ 53, 54, 54, 54, 55, 55, 55, 56, 56, 56, 56, 57, 49, 47, 47, 47, 46, 45,
+ 45, 45, 46, 46, 46, 46, 46, 46, 47, 49, 49, 50, 52, 53, 53, 54, 55, 55,
+ 55, 57, 57, 57, 57, 58, 58, 58, 49, 47, 47, 47, 46, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 47, 49, 49, 50, 52, 53, 53, 55, 55, 55, 57, 58, 58, 59,
+ 59, 60, 60, 60, 49, 47, 47, 47, 46, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 47, 49, 49, 50, 52, 53, 53, 55, 55, 55, 57, 58, 58, 59, 59, 60, 60, 60,
+ 49, 48, 47, 47, 46, 45, 45, 45, 45, 45, 45, 45, 45, 45, 47, 49, 49, 50,
+ 52, 53, 53, 55, 56, 56, 57, 59, 59, 59, 60, 60, 60, 61, 50, 49, 48, 48,
+ 47, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 50, 50, 50, 53, 54, 54, 55,
+ 56, 56, 57, 59, 59, 60, 61, 61, 61, 62, 50, 49, 48, 48, 47, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 47, 50, 50, 50, 53, 54, 54, 55, 56, 56, 58, 60,
+ 60, 60, 61, 61, 61, 63, 50, 49, 48, 48, 47, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 47, 50, 50, 50, 53, 54, 54, 55, 56, 56, 58, 60, 60, 60, 61, 61,
+ 61, 63, 51, 50, 49, 49, 48, 47, 47, 47, 47, 47, 47, 47, 46, 46, 48, 50,
+ 50, 51, 53, 54, 54, 56, 57, 57, 58, 60, 60, 61, 62, 63, 63, 64],
+ /* Size 4x8 */
+ [31, 38, 47, 48, 31, 40, 46, 45, 35, 43, 47, 46, 39, 47, 47, 45, 43, 47,
+ 50, 50, 47, 47, 53, 55, 46, 46, 53, 58, 48, 46, 54, 59],
+ /* Size 8x4 */
+ [31, 31, 35, 39, 43, 47, 46, 48, 38, 40, 43, 47, 47, 47, 46, 46, 47, 46,
+ 47, 47, 50, 53, 53, 54, 48, 45, 46, 45, 50, 55, 58, 59],
+ /* Size 8x16 */
+ [32, 31, 33, 37, 45, 48, 49, 50, 31, 31, 34, 38, 45, 47, 47, 48, 31, 32,
+ 34, 39, 45, 46, 46, 47, 30, 32, 35, 40, 44, 46, 45, 46, 33, 35, 37, 42,
+ 46, 47, 45, 46, 33, 36, 38, 43, 46, 47, 46, 46, 37, 40, 43, 47, 47, 47,
+ 45, 46, 39, 41, 43, 47, 48, 48, 47, 47, 42, 43, 44, 47, 49, 50, 49, 50,
+ 47, 46, 46, 48, 51, 52, 53, 53, 49, 46, 47, 48, 52, 53, 53, 54, 48, 46,
+ 46, 47, 51, 53, 56, 56, 48, 45, 46, 46, 51, 53, 57, 57, 49, 45, 45, 46,
+ 51, 53, 58, 59, 50, 46, 46, 46, 52, 54, 59, 61, 50, 46, 46, 46, 52, 54,
+ 59, 61],
+ /* Size 16x8 */
+ [32, 31, 31, 30, 33, 33, 37, 39, 42, 47, 49, 48, 48, 49, 50, 50, 31, 31,
+ 32, 32, 35, 36, 40, 41, 43, 46, 46, 46, 45, 45, 46, 46, 33, 34, 34, 35,
+ 37, 38, 43, 43, 44, 46, 47, 46, 46, 45, 46, 46, 37, 38, 39, 40, 42, 43,
+ 47, 47, 47, 48, 48, 47, 46, 46, 46, 46, 45, 45, 45, 44, 46, 46, 47, 48,
+ 49, 51, 52, 51, 51, 51, 52, 52, 48, 47, 46, 46, 47, 47, 47, 48, 50, 52,
+ 53, 53, 53, 53, 54, 54, 49, 47, 46, 45, 45, 46, 45, 47, 49, 53, 53, 56,
+ 57, 58, 59, 59, 50, 48, 47, 46, 46, 46, 46, 47, 50, 53, 54, 56, 57, 59,
+ 61, 61],
+ /* Size 16x32 */
+ [32, 31, 31, 31, 33, 37, 37, 38, 45, 48, 48, 49, 49, 49, 50, 52, 31, 31,
+ 31, 31, 33, 38, 38, 39, 45, 47, 47, 48, 48, 48, 49, 51, 31, 31, 31, 31,
+ 34, 38, 38, 40, 45, 47, 47, 47, 47, 47, 48, 50, 31, 31, 31, 31, 34, 38,
+ 38, 40, 45, 47, 47, 47, 47, 47, 48, 50, 31, 31, 32, 32, 34, 39, 39, 40,
+ 45, 46, 46, 46, 46, 46, 47, 49, 30, 31, 32, 32, 35, 40, 40, 41, 44, 46,
+ 46, 45, 45, 45, 46, 48, 30, 31, 32, 32, 35, 40, 40, 41, 44, 46, 46, 45,
+ 45, 45, 46, 48, 31, 32, 33, 33, 35, 40, 40, 41, 45, 46, 46, 45, 45, 45,
+ 46, 48, 33, 34, 35, 35, 37, 42, 42, 43, 46, 47, 47, 46, 45, 45, 46, 47,
+ 33, 35, 36, 36, 38, 43, 43, 44, 46, 47, 47, 46, 46, 46, 46, 47, 33, 35,
+ 36, 36, 38, 43, 43, 44, 46, 47, 47, 46, 46, 46, 46, 47, 35, 37, 38, 38,
+ 41, 45, 45, 46, 47, 47, 47, 46, 45, 45, 46, 47, 37, 39, 40, 40, 43, 47,
+ 47, 47, 47, 47, 47, 46, 45, 45, 46, 47, 37, 39, 40, 40, 43, 47, 47, 47,
+ 47, 47, 47, 46, 45, 45, 46, 47, 39, 40, 41, 41, 43, 47, 47, 47, 48, 48,
+ 48, 47, 47, 47, 47, 48, 42, 42, 43, 43, 44, 47, 47, 48, 49, 50, 50, 49,
+ 49, 49, 50, 50, 42, 42, 43, 43, 44, 47, 47, 48, 49, 50, 50, 49, 49, 49,
+ 50, 50, 43, 43, 43, 43, 45, 47, 47, 48, 50, 50, 50, 50, 50, 50, 50, 51,
+ 47, 46, 46, 46, 46, 48, 48, 48, 51, 52, 52, 52, 53, 53, 53, 53, 49, 47,
+ 46, 46, 47, 48, 48, 49, 52, 53, 53, 53, 53, 53, 54, 54, 49, 47, 46, 46,
+ 47, 48, 48, 49, 52, 53, 53, 53, 53, 53, 54, 54, 48, 47, 46, 46, 46, 47,
+ 47, 48, 52, 53, 53, 54, 55, 55, 55, 56, 48, 47, 46, 46, 46, 47, 47, 48,
+ 51, 53, 53, 54, 56, 56, 56, 57, 48, 47, 46, 46, 46, 47, 47, 48, 51, 53,
+ 53, 54, 56, 56, 56, 57, 48, 47, 45, 45, 46, 46, 46, 47, 51, 53, 53, 55,
+ 57, 57, 57, 59, 49, 46, 45, 45, 45, 46, 46, 47, 51, 53, 53, 56, 58, 58,
+ 59, 61, 49, 46, 45, 45, 45, 46, 46, 47, 51, 53, 53, 56, 58, 58, 59, 61,
+ 49, 47, 45, 45, 45, 46, 46, 47, 52, 53, 53, 56, 58, 58, 60, 62, 50, 48,
+ 46, 46, 46, 46, 46, 48, 52, 54, 54, 57, 59, 59, 61, 63, 50, 48, 46, 46,
+ 46, 46, 46, 48, 52, 54, 54, 57, 59, 59, 61, 64, 50, 48, 46, 46, 46, 46,
+ 46, 48, 52, 54, 54, 57, 59, 59, 61, 64, 51, 49, 47, 47, 47, 47, 47, 48,
+ 52, 54, 54, 58, 60, 60, 62, 65],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 31, 30, 30, 31, 33, 33, 33, 35, 37, 37, 39, 42, 42, 43,
+ 47, 49, 49, 48, 48, 48, 48, 49, 49, 49, 50, 50, 50, 51, 31, 31, 31, 31,
+ 31, 31, 31, 32, 34, 35, 35, 37, 39, 39, 40, 42, 42, 43, 46, 47, 47, 47,
+ 47, 47, 47, 46, 46, 47, 48, 48, 48, 49, 31, 31, 31, 31, 32, 32, 32, 33,
+ 35, 36, 36, 38, 40, 40, 41, 43, 43, 43, 46, 46, 46, 46, 46, 46, 45, 45,
+ 45, 45, 46, 46, 46, 47, 31, 31, 31, 31, 32, 32, 32, 33, 35, 36, 36, 38,
+ 40, 40, 41, 43, 43, 43, 46, 46, 46, 46, 46, 46, 45, 45, 45, 45, 46, 46,
+ 46, 47, 33, 33, 34, 34, 34, 35, 35, 35, 37, 38, 38, 41, 43, 43, 43, 44,
+ 44, 45, 46, 47, 47, 46, 46, 46, 46, 45, 45, 45, 46, 46, 46, 47, 37, 38,
+ 38, 38, 39, 40, 40, 40, 42, 43, 43, 45, 47, 47, 47, 47, 47, 47, 48, 48,
+ 48, 47, 47, 47, 46, 46, 46, 46, 46, 46, 46, 47, 37, 38, 38, 38, 39, 40,
+ 40, 40, 42, 43, 43, 45, 47, 47, 47, 47, 47, 47, 48, 48, 48, 47, 47, 47,
+ 46, 46, 46, 46, 46, 46, 46, 47, 38, 39, 40, 40, 40, 41, 41, 41, 43, 44,
+ 44, 46, 47, 47, 47, 48, 48, 48, 48, 49, 49, 48, 48, 48, 47, 47, 47, 47,
+ 48, 48, 48, 48, 45, 45, 45, 45, 45, 44, 44, 45, 46, 46, 46, 47, 47, 47,
+ 48, 49, 49, 50, 51, 52, 52, 52, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52,
+ 48, 47, 47, 47, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 48, 50, 50, 50,
+ 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 48, 47, 47, 47,
+ 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 48, 50, 50, 50, 52, 53, 53, 53,
+ 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 49, 48, 47, 47, 46, 45, 45, 45,
+ 46, 46, 46, 46, 46, 46, 47, 49, 49, 50, 52, 53, 53, 54, 54, 54, 55, 56,
+ 56, 56, 57, 57, 57, 58, 49, 48, 47, 47, 46, 45, 45, 45, 45, 46, 46, 45,
+ 45, 45, 47, 49, 49, 50, 53, 53, 53, 55, 56, 56, 57, 58, 58, 58, 59, 59,
+ 59, 60, 49, 48, 47, 47, 46, 45, 45, 45, 45, 46, 46, 45, 45, 45, 47, 49,
+ 49, 50, 53, 53, 53, 55, 56, 56, 57, 58, 58, 58, 59, 59, 59, 60, 50, 49,
+ 48, 48, 47, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 50, 50, 50, 53, 54,
+ 54, 55, 56, 56, 57, 59, 59, 60, 61, 61, 61, 62, 52, 51, 50, 50, 49, 48,
+ 48, 48, 47, 47, 47, 47, 47, 47, 48, 50, 50, 51, 53, 54, 54, 56, 57, 57,
+ 59, 61, 61, 62, 63, 64, 64, 65],
+ /* Size 4x16 */
+ [31, 37, 48, 49, 31, 38, 47, 47, 31, 39, 46, 46, 31, 40, 46, 45, 34, 42,
+ 47, 45, 35, 43, 47, 46, 39, 47, 47, 45, 40, 47, 48, 47, 42, 47, 50, 49,
+ 46, 48, 52, 53, 47, 48, 53, 53, 47, 47, 53, 56, 47, 46, 53, 57, 46, 46,
+ 53, 58, 48, 46, 54, 59, 48, 46, 54, 59],
+ /* Size 16x4 */
+ [31, 31, 31, 31, 34, 35, 39, 40, 42, 46, 47, 47, 47, 46, 48, 48, 37, 38,
+ 39, 40, 42, 43, 47, 47, 47, 48, 48, 47, 46, 46, 46, 46, 48, 47, 46, 46,
+ 47, 47, 47, 48, 50, 52, 53, 53, 53, 53, 54, 54, 49, 47, 46, 45, 45, 46,
+ 45, 47, 49, 53, 53, 56, 57, 58, 59, 59],
+ /* Size 8x32 */
+ [32, 31, 33, 37, 45, 48, 49, 50, 31, 31, 33, 38, 45, 47, 48, 49, 31, 31,
+ 34, 38, 45, 47, 47, 48, 31, 31, 34, 38, 45, 47, 47, 48, 31, 32, 34, 39,
+ 45, 46, 46, 47, 30, 32, 35, 40, 44, 46, 45, 46, 30, 32, 35, 40, 44, 46,
+ 45, 46, 31, 33, 35, 40, 45, 46, 45, 46, 33, 35, 37, 42, 46, 47, 45, 46,
+ 33, 36, 38, 43, 46, 47, 46, 46, 33, 36, 38, 43, 46, 47, 46, 46, 35, 38,
+ 41, 45, 47, 47, 45, 46, 37, 40, 43, 47, 47, 47, 45, 46, 37, 40, 43, 47,
+ 47, 47, 45, 46, 39, 41, 43, 47, 48, 48, 47, 47, 42, 43, 44, 47, 49, 50,
+ 49, 50, 42, 43, 44, 47, 49, 50, 49, 50, 43, 43, 45, 47, 50, 50, 50, 50,
+ 47, 46, 46, 48, 51, 52, 53, 53, 49, 46, 47, 48, 52, 53, 53, 54, 49, 46,
+ 47, 48, 52, 53, 53, 54, 48, 46, 46, 47, 52, 53, 55, 55, 48, 46, 46, 47,
+ 51, 53, 56, 56, 48, 46, 46, 47, 51, 53, 56, 56, 48, 45, 46, 46, 51, 53,
+ 57, 57, 49, 45, 45, 46, 51, 53, 58, 59, 49, 45, 45, 46, 51, 53, 58, 59,
+ 49, 45, 45, 46, 52, 53, 58, 60, 50, 46, 46, 46, 52, 54, 59, 61, 50, 46,
+ 46, 46, 52, 54, 59, 61, 50, 46, 46, 46, 52, 54, 59, 61, 51, 47, 47, 47,
+ 52, 54, 60, 62],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 31, 30, 30, 31, 33, 33, 33, 35, 37, 37, 39, 42, 42, 43,
+ 47, 49, 49, 48, 48, 48, 48, 49, 49, 49, 50, 50, 50, 51, 31, 31, 31, 31,
+ 32, 32, 32, 33, 35, 36, 36, 38, 40, 40, 41, 43, 43, 43, 46, 46, 46, 46,
+ 46, 46, 45, 45, 45, 45, 46, 46, 46, 47, 33, 33, 34, 34, 34, 35, 35, 35,
+ 37, 38, 38, 41, 43, 43, 43, 44, 44, 45, 46, 47, 47, 46, 46, 46, 46, 45,
+ 45, 45, 46, 46, 46, 47, 37, 38, 38, 38, 39, 40, 40, 40, 42, 43, 43, 45,
+ 47, 47, 47, 47, 47, 47, 48, 48, 48, 47, 47, 47, 46, 46, 46, 46, 46, 46,
+ 46, 47, 45, 45, 45, 45, 45, 44, 44, 45, 46, 46, 46, 47, 47, 47, 48, 49,
+ 49, 50, 51, 52, 52, 52, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 48, 47,
+ 47, 47, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 48, 50, 50, 50, 52, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 49, 48, 47, 47, 46, 45,
+ 45, 45, 45, 46, 46, 45, 45, 45, 47, 49, 49, 50, 53, 53, 53, 55, 56, 56,
+ 57, 58, 58, 58, 59, 59, 59, 60, 50, 49, 48, 48, 47, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 47, 50, 50, 50, 53, 54, 54, 55, 56, 56, 57, 59, 59, 60,
+ 61, 61, 61, 62]]
+ ],
+ [
+ [ /* Luma */
+ /* Size 4x4 */
+ [32, 32, 34, 38, 32, 33, 35, 39, 34, 35, 39, 45, 38, 39, 45, 54],
+ /* Size 8x8 */
+ [31, 31, 32, 32, 33, 34, 37, 41, 31, 32, 32, 32, 33, 34, 36, 39, 32, 32,
+ 32, 33, 34, 35, 37, 40, 32, 32, 33, 34, 35, 36, 38, 41, 33, 33, 34, 35,
+ 37, 39, 41, 44, 34, 34, 35, 36, 39, 43, 46, 49, 37, 36, 37, 38, 41, 46,
+ 51, 54, 41, 39, 40, 41, 44, 49, 54, 58],
+ /* Size 16x16 */
+ [32, 31, 31, 31, 31, 31, 31, 32, 32, 34, 34, 36, 36, 39, 39, 44, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 34, 34, 35, 35, 38, 38, 42, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 34, 34, 35, 35, 38, 38, 42, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 33, 33, 34, 34, 37, 37, 41, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 34, 34, 37, 37, 41, 31, 32, 32, 32, 32, 33, 33, 34, 34, 35,
+ 35, 36, 36, 39, 39, 42, 31, 32, 32, 32, 32, 33, 33, 34, 34, 35, 35, 36,
+ 36, 39, 39, 42, 32, 32, 32, 32, 32, 34, 34, 35, 35, 37, 37, 38, 38, 40,
+ 40, 42, 32, 32, 32, 32, 32, 34, 34, 35, 35, 37, 37, 38, 38, 40, 40, 42,
+ 34, 34, 34, 33, 33, 35, 35, 37, 37, 39, 39, 42, 42, 45, 45, 47, 34, 34,
+ 34, 33, 33, 35, 35, 37, 37, 39, 39, 42, 42, 45, 45, 47, 36, 35, 35, 34,
+ 34, 36, 36, 38, 38, 42, 42, 48, 48, 50, 50, 54, 36, 35, 35, 34, 34, 36,
+ 36, 38, 38, 42, 42, 48, 48, 50, 50, 54, 39, 38, 38, 37, 37, 39, 39, 40,
+ 40, 45, 45, 50, 50, 54, 54, 58, 39, 38, 38, 37, 37, 39, 39, 40, 40, 45,
+ 45, 50, 50, 54, 54, 58, 44, 42, 42, 41, 41, 42, 42, 42, 42, 47, 47, 54,
+ 54, 58, 58, 63],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 33,
+ 34, 34, 34, 35, 36, 36, 36, 37, 39, 39, 39, 41, 44, 44, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 34, 34,
+ 35, 35, 35, 37, 39, 39, 39, 41, 43, 43, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 34, 34, 35, 35, 35, 37,
+ 38, 38, 38, 40, 42, 42, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 34, 34, 34, 34, 35, 35, 35, 37, 38, 38, 38, 40,
+ 42, 42, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 34, 34, 34, 34, 35, 35, 35, 37, 38, 38, 38, 40, 42, 42, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34,
+ 34, 34, 35, 35, 35, 36, 38, 38, 38, 39, 41, 41, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34,
+ 34, 36, 37, 37, 37, 39, 41, 41, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 36, 37, 37,
+ 37, 39, 41, 41, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 36, 37, 37, 37, 39, 41, 41,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 34,
+ 34, 34, 34, 35, 35, 35, 35, 37, 38, 38, 38, 40, 41, 41, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 36,
+ 36, 36, 36, 38, 39, 39, 39, 40, 42, 42, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 36, 36, 36, 36, 38,
+ 39, 39, 39, 40, 42, 42, 31, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33,
+ 33, 33, 34, 34, 34, 34, 35, 35, 35, 36, 36, 36, 36, 38, 39, 39, 39, 40,
+ 42, 42, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34,
+ 34, 35, 36, 36, 36, 36, 37, 37, 37, 38, 40, 40, 40, 41, 42, 42, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 34, 34, 35, 35, 35, 36, 37, 37,
+ 37, 37, 38, 38, 38, 39, 40, 40, 40, 41, 42, 42, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 33, 34, 34, 34, 34, 35, 35, 35, 36, 37, 37, 37, 37, 38, 38,
+ 38, 39, 40, 40, 40, 41, 42, 42, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33,
+ 34, 34, 34, 34, 35, 35, 35, 36, 37, 37, 37, 37, 38, 38, 38, 39, 40, 40,
+ 40, 41, 42, 42, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 35,
+ 36, 36, 36, 37, 38, 38, 38, 39, 40, 40, 40, 41, 42, 42, 42, 44, 45, 45,
+ 34, 34, 34, 34, 34, 34, 33, 33, 33, 34, 35, 35, 35, 36, 37, 37, 37, 38,
+ 39, 39, 39, 41, 42, 42, 42, 44, 45, 45, 45, 46, 47, 47, 34, 34, 34, 34,
+ 34, 34, 33, 33, 33, 34, 35, 35, 35, 36, 37, 37, 37, 38, 39, 39, 39, 41,
+ 42, 42, 42, 44, 45, 45, 45, 46, 47, 47, 34, 34, 34, 34, 34, 34, 33, 33,
+ 33, 34, 35, 35, 35, 36, 37, 37, 37, 38, 39, 39, 39, 41, 42, 42, 42, 44,
+ 45, 45, 45, 46, 47, 47, 35, 34, 34, 34, 34, 34, 34, 34, 34, 35, 36, 36,
+ 36, 36, 37, 37, 37, 39, 41, 41, 41, 43, 45, 45, 45, 46, 47, 47, 47, 49,
+ 50, 50, 36, 35, 35, 35, 35, 35, 34, 34, 34, 35, 36, 36, 36, 37, 38, 38,
+ 38, 40, 42, 42, 42, 45, 48, 48, 48, 49, 50, 50, 50, 52, 54, 54, 36, 35,
+ 35, 35, 35, 35, 34, 34, 34, 35, 36, 36, 36, 37, 38, 38, 38, 40, 42, 42,
+ 42, 45, 48, 48, 48, 49, 50, 50, 50, 52, 54, 54, 36, 35, 35, 35, 35, 35,
+ 34, 34, 34, 35, 36, 36, 36, 37, 38, 38, 38, 40, 42, 42, 42, 45, 48, 48,
+ 48, 49, 50, 50, 50, 52, 54, 54, 37, 37, 37, 37, 37, 36, 36, 36, 36, 37,
+ 38, 38, 38, 38, 39, 39, 39, 41, 44, 44, 44, 46, 49, 49, 49, 51, 52, 52,
+ 52, 54, 56, 56, 39, 39, 38, 38, 38, 38, 37, 37, 37, 38, 39, 39, 39, 40,
+ 40, 40, 40, 42, 45, 45, 45, 47, 50, 50, 50, 52, 54, 54, 54, 56, 58, 58,
+ 39, 39, 38, 38, 38, 38, 37, 37, 37, 38, 39, 39, 39, 40, 40, 40, 40, 42,
+ 45, 45, 45, 47, 50, 50, 50, 52, 54, 54, 54, 56, 58, 58, 39, 39, 38, 38,
+ 38, 38, 37, 37, 37, 38, 39, 39, 39, 40, 40, 40, 40, 42, 45, 45, 45, 47,
+ 50, 50, 50, 52, 54, 54, 54, 56, 58, 58, 41, 41, 40, 40, 40, 39, 39, 39,
+ 39, 40, 40, 40, 40, 41, 41, 41, 41, 44, 46, 46, 46, 49, 52, 52, 52, 54,
+ 56, 56, 56, 58, 60, 60, 44, 43, 42, 42, 42, 41, 41, 41, 41, 41, 42, 42,
+ 42, 42, 42, 42, 42, 45, 47, 47, 47, 50, 54, 54, 54, 56, 58, 58, 58, 60,
+ 63, 63, 44, 43, 42, 42, 42, 41, 41, 41, 41, 41, 42, 42, 42, 42, 42, 42,
+ 42, 45, 47, 47, 47, 50, 54, 54, 54, 56, 58, 58, 58, 60, 63, 63],
+ /* Size 4x8 */
+ [31, 32, 34, 39, 32, 32, 34, 38, 32, 33, 34, 38, 32, 33, 36, 40, 33, 34,
+ 38, 42, 34, 36, 41, 47, 37, 38, 44, 52, 40, 40, 46, 56],
+ /* Size 8x4 */
+ [31, 32, 32, 32, 33, 34, 37, 40, 32, 32, 33, 33, 34, 36, 38, 40, 34, 34,
+ 34, 36, 38, 41, 44, 46, 39, 38, 38, 40, 42, 47, 52, 56],
+ /* Size 8x16 */
+ [32, 31, 31, 32, 32, 36, 36, 44, 31, 32, 32, 32, 32, 35, 35, 42, 31, 32,
+ 32, 32, 32, 35, 35, 42, 31, 32, 32, 33, 33, 34, 34, 41, 31, 32, 32, 33,
+ 33, 34, 34, 41, 32, 32, 32, 34, 34, 36, 36, 42, 32, 32, 32, 34, 34, 36,
+ 36, 42, 32, 33, 33, 35, 35, 38, 38, 42, 32, 33, 33, 35, 35, 38, 38, 42,
+ 34, 34, 34, 37, 37, 42, 42, 48, 34, 34, 34, 37, 37, 42, 42, 48, 36, 34,
+ 34, 38, 38, 48, 48, 54, 36, 34, 34, 38, 38, 48, 48, 54, 39, 37, 37, 40,
+ 40, 50, 50, 58, 39, 37, 37, 40, 40, 50, 50, 58, 44, 41, 41, 43, 43, 53,
+ 53, 63],
+ /* Size 16x8 */
+ [32, 31, 31, 31, 31, 32, 32, 32, 32, 34, 34, 36, 36, 39, 39, 44, 31, 32,
+ 32, 32, 32, 32, 32, 33, 33, 34, 34, 34, 34, 37, 37, 41, 31, 32, 32, 32,
+ 32, 32, 32, 33, 33, 34, 34, 34, 34, 37, 37, 41, 32, 32, 32, 33, 33, 34,
+ 34, 35, 35, 37, 37, 38, 38, 40, 40, 43, 32, 32, 32, 33, 33, 34, 34, 35,
+ 35, 37, 37, 38, 38, 40, 40, 43, 36, 35, 35, 34, 34, 36, 36, 38, 38, 42,
+ 42, 48, 48, 50, 50, 53, 36, 35, 35, 34, 34, 36, 36, 38, 38, 42, 42, 48,
+ 48, 50, 50, 53, 44, 42, 42, 41, 41, 42, 42, 42, 42, 48, 48, 54, 54, 58,
+ 58, 63],
+ /* Size 16x32 */
+ [32, 31, 31, 31, 31, 32, 32, 32, 32, 34, 36, 36, 36, 39, 44, 44, 31, 31,
+ 31, 31, 31, 32, 32, 32, 32, 34, 35, 35, 35, 39, 43, 43, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 34, 35, 35, 35, 38, 42, 42, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 34, 35, 35, 35, 38, 42, 42, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 34, 35, 35, 35, 38, 42, 42, 31, 32, 32, 32, 32, 32, 32, 32, 32, 34,
+ 35, 35, 35, 38, 41, 41, 31, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34,
+ 34, 37, 41, 41, 31, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 37,
+ 41, 41, 31, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 37, 41, 41,
+ 31, 32, 32, 32, 32, 33, 33, 33, 33, 34, 35, 35, 35, 38, 41, 41, 32, 32,
+ 32, 32, 32, 33, 34, 34, 34, 35, 36, 36, 36, 39, 42, 42, 32, 32, 32, 32,
+ 32, 33, 34, 34, 34, 35, 36, 36, 36, 39, 42, 42, 32, 32, 32, 32, 32, 33,
+ 34, 34, 34, 35, 36, 36, 36, 39, 42, 42, 32, 32, 32, 32, 32, 33, 34, 34,
+ 34, 36, 37, 37, 37, 40, 42, 42, 32, 32, 33, 33, 33, 34, 35, 35, 35, 37,
+ 38, 38, 38, 40, 42, 42, 32, 32, 33, 33, 33, 34, 35, 35, 35, 37, 38, 38,
+ 38, 40, 42, 42, 32, 32, 33, 33, 33, 34, 35, 35, 35, 37, 38, 38, 38, 40,
+ 42, 42, 33, 33, 33, 33, 33, 34, 36, 36, 36, 38, 40, 40, 40, 42, 45, 45,
+ 34, 34, 34, 34, 34, 35, 37, 37, 37, 39, 42, 42, 42, 45, 48, 48, 34, 34,
+ 34, 34, 34, 35, 37, 37, 37, 39, 42, 42, 42, 45, 48, 48, 34, 34, 34, 34,
+ 34, 35, 37, 37, 37, 39, 42, 42, 42, 45, 48, 48, 35, 34, 34, 34, 34, 36,
+ 37, 37, 37, 41, 45, 45, 45, 47, 50, 50, 36, 35, 34, 34, 34, 36, 38, 38,
+ 38, 43, 48, 48, 48, 51, 54, 54, 36, 35, 34, 34, 34, 36, 38, 38, 38, 43,
+ 48, 48, 48, 51, 54, 54, 36, 35, 34, 34, 34, 36, 38, 38, 38, 43, 48, 48,
+ 48, 51, 54, 54, 37, 37, 36, 36, 36, 38, 39, 39, 39, 44, 49, 49, 49, 52,
+ 56, 56, 39, 38, 37, 37, 37, 39, 40, 40, 40, 45, 50, 50, 50, 54, 58, 58,
+ 39, 38, 37, 37, 37, 39, 40, 40, 40, 45, 50, 50, 50, 54, 58, 58, 39, 38,
+ 37, 37, 37, 39, 40, 40, 40, 45, 50, 50, 50, 54, 58, 58, 41, 40, 39, 39,
+ 39, 40, 42, 42, 42, 46, 52, 52, 52, 56, 60, 60, 44, 42, 41, 41, 41, 42,
+ 43, 43, 43, 48, 53, 53, 53, 58, 63, 63, 44, 42, 41, 41, 41, 42, 43, 43,
+ 43, 48, 53, 53, 53, 58, 63, 63],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 33,
+ 34, 34, 34, 35, 36, 36, 36, 37, 39, 39, 39, 41, 44, 44, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 34, 34,
+ 35, 35, 35, 37, 38, 38, 38, 40, 42, 42, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 36,
+ 37, 37, 37, 39, 41, 41, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 36, 37, 37, 37, 39,
+ 41, 41, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33,
+ 33, 33, 34, 34, 34, 34, 34, 34, 34, 36, 37, 37, 37, 39, 41, 41, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35,
+ 35, 36, 36, 36, 36, 38, 39, 39, 39, 40, 42, 42, 32, 32, 32, 32, 32, 32,
+ 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 36, 37, 37, 37, 37, 38, 38,
+ 38, 39, 40, 40, 40, 42, 43, 43, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33,
+ 34, 34, 34, 34, 35, 35, 35, 36, 37, 37, 37, 37, 38, 38, 38, 39, 40, 40,
+ 40, 42, 43, 43, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34,
+ 35, 35, 35, 36, 37, 37, 37, 37, 38, 38, 38, 39, 40, 40, 40, 42, 43, 43,
+ 34, 34, 34, 34, 34, 34, 33, 33, 33, 34, 35, 35, 35, 36, 37, 37, 37, 38,
+ 39, 39, 39, 41, 43, 43, 43, 44, 45, 45, 45, 46, 48, 48, 36, 35, 35, 35,
+ 35, 35, 34, 34, 34, 35, 36, 36, 36, 37, 38, 38, 38, 40, 42, 42, 42, 45,
+ 48, 48, 48, 49, 50, 50, 50, 52, 53, 53, 36, 35, 35, 35, 35, 35, 34, 34,
+ 34, 35, 36, 36, 36, 37, 38, 38, 38, 40, 42, 42, 42, 45, 48, 48, 48, 49,
+ 50, 50, 50, 52, 53, 53, 36, 35, 35, 35, 35, 35, 34, 34, 34, 35, 36, 36,
+ 36, 37, 38, 38, 38, 40, 42, 42, 42, 45, 48, 48, 48, 49, 50, 50, 50, 52,
+ 53, 53, 39, 39, 38, 38, 38, 38, 37, 37, 37, 38, 39, 39, 39, 40, 40, 40,
+ 40, 42, 45, 45, 45, 47, 51, 51, 51, 52, 54, 54, 54, 56, 58, 58, 44, 43,
+ 42, 42, 42, 41, 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 42, 45, 48, 48,
+ 48, 50, 54, 54, 54, 56, 58, 58, 58, 60, 63, 63, 44, 43, 42, 42, 42, 41,
+ 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 42, 45, 48, 48, 48, 50, 54, 54,
+ 54, 56, 58, 58, 58, 60, 63, 63],
+ /* Size 4x16 */
+ [31, 32, 34, 39, 32, 32, 34, 38, 32, 32, 34, 38, 32, 32, 33, 37, 32, 32,
+ 33, 37, 32, 33, 35, 39, 32, 33, 35, 39, 32, 34, 37, 40, 32, 34, 37, 40,
+ 34, 35, 39, 45, 34, 35, 39, 45, 35, 36, 43, 51, 35, 36, 43, 51, 38, 39,
+ 45, 54, 38, 39, 45, 54, 42, 42, 48, 58],
+ /* Size 16x4 */
+ [31, 32, 32, 32, 32, 32, 32, 32, 32, 34, 34, 35, 35, 38, 38, 42, 32, 32,
+ 32, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 39, 39, 42, 34, 34, 34, 33,
+ 33, 35, 35, 37, 37, 39, 39, 43, 43, 45, 45, 48, 39, 38, 38, 37, 37, 39,
+ 39, 40, 40, 45, 45, 51, 51, 54, 54, 58],
+ /* Size 8x32 */
+ [32, 31, 31, 32, 32, 36, 36, 44, 31, 31, 31, 32, 32, 35, 35, 43, 31, 32,
+ 32, 32, 32, 35, 35, 42, 31, 32, 32, 32, 32, 35, 35, 42, 31, 32, 32, 32,
+ 32, 35, 35, 42, 31, 32, 32, 32, 32, 35, 35, 41, 31, 32, 32, 33, 33, 34,
+ 34, 41, 31, 32, 32, 33, 33, 34, 34, 41, 31, 32, 32, 33, 33, 34, 34, 41,
+ 31, 32, 32, 33, 33, 35, 35, 41, 32, 32, 32, 34, 34, 36, 36, 42, 32, 32,
+ 32, 34, 34, 36, 36, 42, 32, 32, 32, 34, 34, 36, 36, 42, 32, 32, 32, 34,
+ 34, 37, 37, 42, 32, 33, 33, 35, 35, 38, 38, 42, 32, 33, 33, 35, 35, 38,
+ 38, 42, 32, 33, 33, 35, 35, 38, 38, 42, 33, 33, 33, 36, 36, 40, 40, 45,
+ 34, 34, 34, 37, 37, 42, 42, 48, 34, 34, 34, 37, 37, 42, 42, 48, 34, 34,
+ 34, 37, 37, 42, 42, 48, 35, 34, 34, 37, 37, 45, 45, 50, 36, 34, 34, 38,
+ 38, 48, 48, 54, 36, 34, 34, 38, 38, 48, 48, 54, 36, 34, 34, 38, 38, 48,
+ 48, 54, 37, 36, 36, 39, 39, 49, 49, 56, 39, 37, 37, 40, 40, 50, 50, 58,
+ 39, 37, 37, 40, 40, 50, 50, 58, 39, 37, 37, 40, 40, 50, 50, 58, 41, 39,
+ 39, 42, 42, 52, 52, 60, 44, 41, 41, 43, 43, 53, 53, 63, 44, 41, 41, 43,
+ 43, 53, 53, 63],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 33,
+ 34, 34, 34, 35, 36, 36, 36, 37, 39, 39, 39, 41, 44, 44, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34,
+ 34, 34, 34, 36, 37, 37, 37, 39, 41, 41, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 36,
+ 37, 37, 37, 39, 41, 41, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34,
+ 34, 34, 35, 35, 35, 36, 37, 37, 37, 37, 38, 38, 38, 39, 40, 40, 40, 42,
+ 43, 43, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35,
+ 35, 36, 37, 37, 37, 37, 38, 38, 38, 39, 40, 40, 40, 42, 43, 43, 36, 35,
+ 35, 35, 35, 35, 34, 34, 34, 35, 36, 36, 36, 37, 38, 38, 38, 40, 42, 42,
+ 42, 45, 48, 48, 48, 49, 50, 50, 50, 52, 53, 53, 36, 35, 35, 35, 35, 35,
+ 34, 34, 34, 35, 36, 36, 36, 37, 38, 38, 38, 40, 42, 42, 42, 45, 48, 48,
+ 48, 49, 50, 50, 50, 52, 53, 53, 44, 43, 42, 42, 42, 41, 41, 41, 41, 41,
+ 42, 42, 42, 42, 42, 42, 42, 45, 48, 48, 48, 50, 54, 54, 54, 56, 58, 58,
+ 58, 60, 63, 63]],
+ [ /* Chroma */
+ /* Size 4x4 */
+ [31, 34, 42, 47, 34, 39, 45, 46, 42, 45, 48, 49, 47, 46, 49, 54],
+ /* Size 8x8 */
+ [31, 31, 32, 35, 39, 45, 48, 48, 31, 31, 33, 37, 41, 44, 46, 46, 32, 33,
+ 35, 39, 42, 45, 46, 45, 35, 37, 39, 43, 45, 47, 47, 46, 39, 41, 42, 45,
+ 47, 48, 48, 47, 45, 44, 45, 47, 48, 50, 51, 51, 48, 46, 46, 47, 48, 51,
+ 53, 54, 48, 46, 45, 46, 47, 51, 54, 56],
+ /* Size 16x16 */
+ [32, 31, 31, 30, 30, 33, 33, 36, 36, 41, 41, 49, 49, 48, 48, 49, 31, 31,
+ 31, 31, 31, 34, 34, 38, 38, 42, 42, 47, 47, 47, 47, 47, 31, 31, 31, 31,
+ 31, 34, 34, 38, 38, 42, 42, 47, 47, 47, 47, 47, 30, 31, 31, 32, 32, 35,
+ 35, 40, 40, 42, 42, 46, 46, 45, 45, 45, 30, 31, 31, 32, 32, 35, 35, 40,
+ 40, 42, 42, 46, 46, 45, 45, 45, 33, 34, 34, 35, 35, 39, 39, 43, 43, 45,
+ 45, 47, 47, 46, 46, 45, 33, 34, 34, 35, 35, 39, 39, 43, 43, 45, 45, 47,
+ 47, 46, 46, 45, 36, 38, 38, 40, 40, 43, 43, 47, 47, 47, 47, 48, 48, 46,
+ 46, 45, 36, 38, 38, 40, 40, 43, 43, 47, 47, 47, 47, 48, 48, 46, 46, 45,
+ 41, 42, 42, 42, 42, 45, 45, 47, 47, 48, 48, 50, 50, 49, 49, 49, 41, 42,
+ 42, 42, 42, 45, 45, 47, 47, 48, 48, 50, 50, 49, 49, 49, 49, 47, 47, 46,
+ 46, 47, 47, 48, 48, 50, 50, 53, 53, 53, 53, 53, 49, 47, 47, 46, 46, 47,
+ 47, 48, 48, 50, 50, 53, 53, 53, 53, 53, 48, 47, 47, 45, 45, 46, 46, 46,
+ 46, 49, 49, 53, 53, 54, 54, 55, 48, 47, 47, 45, 45, 46, 46, 46, 46, 49,
+ 49, 53, 53, 54, 54, 55, 49, 47, 47, 45, 45, 45, 45, 45, 45, 49, 49, 53,
+ 53, 55, 55, 58],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 31, 30, 30, 30, 32, 33, 33, 33, 35, 36, 36, 36, 39,
+ 41, 41, 41, 45, 49, 49, 49, 49, 48, 48, 48, 49, 49, 49, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 32, 34, 34, 34, 35, 37, 37, 37, 39, 42, 42, 42, 45,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 33, 34, 34, 34, 36, 38, 38, 38, 40, 42, 42, 42, 45, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 31, 31, 31, 31, 31, 31, 31, 31, 31, 33, 34, 34,
+ 34, 36, 38, 38, 38, 40, 42, 42, 42, 45, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 31, 31, 31, 31, 31, 31, 31, 31, 31, 33, 34, 34, 34, 36, 38, 38,
+ 38, 40, 42, 42, 42, 45, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 33, 35, 35, 35, 37, 39, 39, 39, 41, 42, 42,
+ 42, 44, 47, 47, 47, 46, 46, 46, 46, 46, 46, 46, 30, 31, 31, 31, 31, 31,
+ 32, 32, 32, 33, 35, 35, 35, 37, 40, 40, 40, 41, 42, 42, 42, 44, 46, 46,
+ 46, 46, 45, 45, 45, 45, 45, 45, 30, 31, 31, 31, 31, 31, 32, 32, 32, 33,
+ 35, 35, 35, 37, 40, 40, 40, 41, 42, 42, 42, 44, 46, 46, 46, 46, 45, 45,
+ 45, 45, 45, 45, 30, 31, 31, 31, 31, 31, 32, 32, 32, 33, 35, 35, 35, 37,
+ 40, 40, 40, 41, 42, 42, 42, 44, 46, 46, 46, 46, 45, 45, 45, 45, 45, 45,
+ 32, 32, 33, 33, 33, 33, 33, 33, 33, 35, 37, 37, 37, 39, 41, 41, 41, 42,
+ 43, 43, 43, 45, 47, 47, 47, 46, 46, 46, 46, 45, 45, 45, 33, 34, 34, 34,
+ 34, 35, 35, 35, 35, 37, 39, 39, 39, 41, 43, 43, 43, 44, 45, 45, 45, 46,
+ 47, 47, 47, 47, 46, 46, 46, 46, 45, 45, 33, 34, 34, 34, 34, 35, 35, 35,
+ 35, 37, 39, 39, 39, 41, 43, 43, 43, 44, 45, 45, 45, 46, 47, 47, 47, 47,
+ 46, 46, 46, 46, 45, 45, 33, 34, 34, 34, 34, 35, 35, 35, 35, 37, 39, 39,
+ 39, 41, 43, 43, 43, 44, 45, 45, 45, 46, 47, 47, 47, 47, 46, 46, 46, 46,
+ 45, 45, 35, 35, 36, 36, 36, 37, 37, 37, 37, 39, 41, 41, 41, 43, 45, 45,
+ 45, 45, 46, 46, 46, 47, 47, 47, 47, 47, 46, 46, 46, 46, 45, 45, 36, 37,
+ 38, 38, 38, 39, 40, 40, 40, 41, 43, 43, 43, 45, 47, 47, 47, 47, 47, 47,
+ 47, 47, 48, 48, 48, 47, 46, 46, 46, 46, 45, 45, 36, 37, 38, 38, 38, 39,
+ 40, 40, 40, 41, 43, 43, 43, 45, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48,
+ 48, 47, 46, 46, 46, 46, 45, 45, 36, 37, 38, 38, 38, 39, 40, 40, 40, 41,
+ 43, 43, 43, 45, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 47, 46, 46,
+ 46, 46, 45, 45, 39, 39, 40, 40, 40, 41, 41, 41, 41, 42, 44, 44, 44, 45,
+ 47, 47, 47, 47, 48, 48, 48, 48, 49, 49, 49, 48, 48, 48, 48, 47, 47, 47,
+ 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 45, 45, 45, 46, 47, 47, 47, 48,
+ 48, 48, 48, 49, 50, 50, 50, 50, 49, 49, 49, 49, 49, 49, 41, 42, 42, 42,
+ 42, 42, 42, 42, 42, 43, 45, 45, 45, 46, 47, 47, 47, 48, 48, 48, 48, 49,
+ 50, 50, 50, 50, 49, 49, 49, 49, 49, 49, 41, 42, 42, 42, 42, 42, 42, 42,
+ 42, 43, 45, 45, 45, 46, 47, 47, 47, 48, 48, 48, 48, 49, 50, 50, 50, 50,
+ 49, 49, 49, 49, 49, 49, 45, 45, 45, 45, 45, 44, 44, 44, 44, 45, 46, 46,
+ 46, 47, 47, 47, 47, 48, 49, 49, 49, 50, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 49, 48, 47, 47, 47, 47, 46, 46, 46, 47, 47, 47, 47, 47, 48, 48,
+ 48, 49, 50, 50, 50, 51, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 49, 48,
+ 47, 47, 47, 47, 46, 46, 46, 47, 47, 47, 47, 47, 48, 48, 48, 49, 50, 50,
+ 50, 51, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 49, 48, 47, 47, 47, 47,
+ 46, 46, 46, 47, 47, 47, 47, 47, 48, 48, 48, 49, 50, 50, 50, 51, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53, 49, 48, 47, 47, 47, 46, 46, 46, 46, 46,
+ 47, 47, 47, 47, 47, 47, 47, 48, 50, 50, 50, 51, 53, 53, 53, 53, 53, 53,
+ 53, 54, 54, 54, 48, 48, 47, 47, 47, 46, 45, 45, 45, 46, 46, 46, 46, 46,
+ 46, 46, 46, 48, 49, 49, 49, 51, 53, 53, 53, 53, 54, 54, 54, 55, 55, 55,
+ 48, 48, 47, 47, 47, 46, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 46, 48,
+ 49, 49, 49, 51, 53, 53, 53, 53, 54, 54, 54, 55, 55, 55, 48, 48, 47, 47,
+ 47, 46, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 46, 48, 49, 49, 49, 51,
+ 53, 53, 53, 53, 54, 54, 54, 55, 55, 55, 49, 48, 47, 47, 47, 46, 45, 45,
+ 45, 45, 46, 46, 46, 46, 46, 46, 46, 47, 49, 49, 49, 51, 53, 53, 53, 54,
+ 55, 55, 55, 56, 57, 57, 49, 48, 47, 47, 47, 46, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 47, 49, 49, 49, 51, 53, 53, 53, 54, 55, 55, 55, 57,
+ 58, 58, 49, 48, 47, 47, 47, 46, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 47, 49, 49, 49, 51, 53, 53, 53, 54, 55, 55, 55, 57, 58, 58],
+ /* Size 4x8 */
+ [31, 34, 42, 48, 31, 35, 42, 46, 33, 37, 44, 46, 36, 41, 46, 46, 40, 44,
+ 48, 48, 45, 46, 49, 51, 47, 47, 50, 54, 47, 46, 49, 55],
+ /* Size 8x4 */
+ [31, 31, 33, 36, 40, 45, 47, 47, 34, 35, 37, 41, 44, 46, 47, 46, 42, 42,
+ 44, 46, 48, 49, 50, 49, 48, 46, 46, 46, 48, 51, 54, 55],
+ /* Size 8x16 */
+ [32, 31, 31, 37, 37, 48, 48, 49, 31, 31, 31, 38, 38, 47, 47, 47, 31, 31,
+ 31, 38, 38, 47, 47, 47, 30, 32, 32, 40, 40, 46, 46, 45, 30, 32, 32, 40,
+ 40, 46, 46, 45, 33, 36, 36, 43, 43, 47, 47, 46, 33, 36, 36, 43, 43, 47,
+ 47, 46, 37, 40, 40, 47, 47, 47, 47, 45, 37, 40, 40, 47, 47, 47, 47, 45,
+ 42, 43, 43, 47, 47, 50, 50, 49, 42, 43, 43, 47, 47, 50, 50, 49, 49, 46,
+ 46, 48, 48, 53, 53, 53, 49, 46, 46, 48, 48, 53, 53, 53, 48, 46, 46, 47,
+ 47, 53, 53, 56, 48, 46, 46, 47, 47, 53, 53, 56, 49, 45, 45, 46, 46, 53,
+ 53, 58],
+ /* Size 16x8 */
+ [32, 31, 31, 30, 30, 33, 33, 37, 37, 42, 42, 49, 49, 48, 48, 49, 31, 31,
+ 31, 32, 32, 36, 36, 40, 40, 43, 43, 46, 46, 46, 46, 45, 31, 31, 31, 32,
+ 32, 36, 36, 40, 40, 43, 43, 46, 46, 46, 46, 45, 37, 38, 38, 40, 40, 43,
+ 43, 47, 47, 47, 47, 48, 48, 47, 47, 46, 37, 38, 38, 40, 40, 43, 43, 47,
+ 47, 47, 47, 48, 48, 47, 47, 46, 48, 47, 47, 46, 46, 47, 47, 47, 47, 50,
+ 50, 53, 53, 53, 53, 53, 48, 47, 47, 46, 46, 47, 47, 47, 47, 50, 50, 53,
+ 53, 53, 53, 53, 49, 47, 47, 45, 45, 46, 46, 45, 45, 49, 49, 53, 53, 56,
+ 56, 58],
+ /* Size 16x32 */
+ [32, 31, 31, 31, 31, 33, 37, 37, 37, 42, 48, 48, 48, 48, 49, 49, 31, 31,
+ 31, 31, 31, 34, 37, 37, 37, 42, 47, 47, 47, 48, 48, 48, 31, 31, 31, 31,
+ 31, 34, 38, 38, 38, 42, 47, 47, 47, 47, 47, 47, 31, 31, 31, 31, 31, 34,
+ 38, 38, 38, 42, 47, 47, 47, 47, 47, 47, 31, 31, 31, 31, 31, 34, 38, 38,
+ 38, 42, 47, 47, 47, 47, 47, 47, 31, 31, 32, 32, 32, 35, 39, 39, 39, 42,
+ 46, 46, 46, 46, 46, 46, 30, 31, 32, 32, 32, 35, 40, 40, 40, 42, 46, 46,
+ 46, 45, 45, 45, 30, 31, 32, 32, 32, 35, 40, 40, 40, 42, 46, 46, 46, 45,
+ 45, 45, 30, 31, 32, 32, 32, 35, 40, 40, 40, 42, 46, 46, 46, 45, 45, 45,
+ 32, 33, 34, 34, 34, 37, 41, 41, 41, 44, 46, 46, 46, 46, 45, 45, 33, 34,
+ 36, 36, 36, 39, 43, 43, 43, 45, 47, 47, 47, 46, 46, 46, 33, 34, 36, 36,
+ 36, 39, 43, 43, 43, 45, 47, 47, 47, 46, 46, 46, 33, 34, 36, 36, 36, 39,
+ 43, 43, 43, 45, 47, 47, 47, 46, 46, 46, 35, 36, 38, 38, 38, 41, 45, 45,
+ 45, 46, 47, 47, 47, 46, 45, 45, 37, 38, 40, 40, 40, 43, 47, 47, 47, 47,
+ 47, 47, 47, 46, 45, 45, 37, 38, 40, 40, 40, 43, 47, 47, 47, 47, 47, 47,
+ 47, 46, 45, 45, 37, 38, 40, 40, 40, 43, 47, 47, 47, 47, 47, 47, 47, 46,
+ 45, 45, 39, 40, 41, 41, 41, 44, 47, 47, 47, 48, 49, 49, 49, 48, 47, 47,
+ 42, 42, 43, 43, 43, 45, 47, 47, 47, 48, 50, 50, 50, 50, 49, 49, 42, 42,
+ 43, 43, 43, 45, 47, 47, 47, 48, 50, 50, 50, 50, 49, 49, 42, 42, 43, 43,
+ 43, 45, 47, 47, 47, 48, 50, 50, 50, 50, 49, 49, 45, 45, 44, 44, 44, 46,
+ 47, 47, 47, 49, 51, 51, 51, 51, 51, 51, 49, 48, 46, 46, 46, 47, 48, 48,
+ 48, 50, 53, 53, 53, 53, 53, 53, 49, 48, 46, 46, 46, 47, 48, 48, 48, 50,
+ 53, 53, 53, 53, 53, 53, 49, 48, 46, 46, 46, 47, 48, 48, 48, 50, 53, 53,
+ 53, 53, 53, 53, 48, 47, 46, 46, 46, 47, 47, 47, 47, 50, 53, 53, 53, 54,
+ 54, 54, 48, 47, 46, 46, 46, 46, 47, 47, 47, 50, 53, 53, 53, 54, 56, 56,
+ 48, 47, 46, 46, 46, 46, 47, 47, 47, 50, 53, 53, 53, 54, 56, 56, 48, 47,
+ 46, 46, 46, 46, 47, 47, 47, 50, 53, 53, 53, 54, 56, 56, 48, 47, 45, 45,
+ 45, 46, 46, 46, 46, 49, 53, 53, 53, 55, 57, 57, 49, 47, 45, 45, 45, 45,
+ 46, 46, 46, 49, 53, 53, 53, 56, 58, 58, 49, 47, 45, 45, 45, 45, 46, 46,
+ 46, 49, 53, 53, 53, 56, 58, 58],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 31, 31, 30, 30, 30, 32, 33, 33, 33, 35, 37, 37, 37, 39,
+ 42, 42, 42, 45, 49, 49, 49, 48, 48, 48, 48, 48, 49, 49, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 33, 34, 34, 34, 36, 38, 38, 38, 40, 42, 42, 42, 45,
+ 48, 48, 48, 47, 47, 47, 47, 47, 47, 47, 31, 31, 31, 31, 31, 32, 32, 32,
+ 32, 34, 36, 36, 36, 38, 40, 40, 40, 41, 43, 43, 43, 44, 46, 46, 46, 46,
+ 46, 46, 46, 45, 45, 45, 31, 31, 31, 31, 31, 32, 32, 32, 32, 34, 36, 36,
+ 36, 38, 40, 40, 40, 41, 43, 43, 43, 44, 46, 46, 46, 46, 46, 46, 46, 45,
+ 45, 45, 31, 31, 31, 31, 31, 32, 32, 32, 32, 34, 36, 36, 36, 38, 40, 40,
+ 40, 41, 43, 43, 43, 44, 46, 46, 46, 46, 46, 46, 46, 45, 45, 45, 33, 34,
+ 34, 34, 34, 35, 35, 35, 35, 37, 39, 39, 39, 41, 43, 43, 43, 44, 45, 45,
+ 45, 46, 47, 47, 47, 47, 46, 46, 46, 46, 45, 45, 37, 37, 38, 38, 38, 39,
+ 40, 40, 40, 41, 43, 43, 43, 45, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48,
+ 48, 47, 47, 47, 47, 46, 46, 46, 37, 37, 38, 38, 38, 39, 40, 40, 40, 41,
+ 43, 43, 43, 45, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 47, 47, 47,
+ 47, 46, 46, 46, 37, 37, 38, 38, 38, 39, 40, 40, 40, 41, 43, 43, 43, 45,
+ 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 47, 47, 47, 47, 46, 46, 46,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 44, 45, 45, 45, 46, 47, 47, 47, 48,
+ 48, 48, 48, 49, 50, 50, 50, 50, 50, 50, 50, 49, 49, 49, 48, 47, 47, 47,
+ 47, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 49, 50, 50, 50, 51,
+ 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 48, 47, 47, 47, 47, 46, 46, 46,
+ 46, 46, 47, 47, 47, 47, 47, 47, 47, 49, 50, 50, 50, 51, 53, 53, 53, 53,
+ 53, 53, 53, 53, 53, 53, 48, 47, 47, 47, 47, 46, 46, 46, 46, 46, 47, 47,
+ 47, 47, 47, 47, 47, 49, 50, 50, 50, 51, 53, 53, 53, 53, 53, 53, 53, 53,
+ 53, 53, 48, 48, 47, 47, 47, 46, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46,
+ 46, 48, 50, 50, 50, 51, 53, 53, 53, 54, 54, 54, 54, 55, 56, 56, 49, 48,
+ 47, 47, 47, 46, 45, 45, 45, 45, 46, 46, 46, 45, 45, 45, 45, 47, 49, 49,
+ 49, 51, 53, 53, 53, 54, 56, 56, 56, 57, 58, 58, 49, 48, 47, 47, 47, 46,
+ 45, 45, 45, 45, 46, 46, 46, 45, 45, 45, 45, 47, 49, 49, 49, 51, 53, 53,
+ 53, 54, 56, 56, 56, 57, 58, 58],
+ /* Size 4x16 */
+ [31, 33, 42, 48, 31, 34, 42, 47, 31, 34, 42, 47, 31, 35, 42, 45, 31, 35,
+ 42, 45, 34, 39, 45, 46, 34, 39, 45, 46, 38, 43, 47, 46, 38, 43, 47, 46,
+ 42, 45, 48, 50, 42, 45, 48, 50, 48, 47, 50, 53, 48, 47, 50, 53, 47, 46,
+ 50, 54, 47, 46, 50, 54, 47, 45, 49, 56],
+ /* Size 16x4 */
+ [31, 31, 31, 31, 31, 34, 34, 38, 38, 42, 42, 48, 48, 47, 47, 47, 33, 34,
+ 34, 35, 35, 39, 39, 43, 43, 45, 45, 47, 47, 46, 46, 45, 42, 42, 42, 42,
+ 42, 45, 45, 47, 47, 48, 48, 50, 50, 50, 50, 49, 48, 47, 47, 45, 45, 46,
+ 46, 46, 46, 50, 50, 53, 53, 54, 54, 56],
+ /* Size 8x32 */
+ [32, 31, 31, 37, 37, 48, 48, 49, 31, 31, 31, 37, 37, 47, 47, 48, 31, 31,
+ 31, 38, 38, 47, 47, 47, 31, 31, 31, 38, 38, 47, 47, 47, 31, 31, 31, 38,
+ 38, 47, 47, 47, 31, 32, 32, 39, 39, 46, 46, 46, 30, 32, 32, 40, 40, 46,
+ 46, 45, 30, 32, 32, 40, 40, 46, 46, 45, 30, 32, 32, 40, 40, 46, 46, 45,
+ 32, 34, 34, 41, 41, 46, 46, 45, 33, 36, 36, 43, 43, 47, 47, 46, 33, 36,
+ 36, 43, 43, 47, 47, 46, 33, 36, 36, 43, 43, 47, 47, 46, 35, 38, 38, 45,
+ 45, 47, 47, 45, 37, 40, 40, 47, 47, 47, 47, 45, 37, 40, 40, 47, 47, 47,
+ 47, 45, 37, 40, 40, 47, 47, 47, 47, 45, 39, 41, 41, 47, 47, 49, 49, 47,
+ 42, 43, 43, 47, 47, 50, 50, 49, 42, 43, 43, 47, 47, 50, 50, 49, 42, 43,
+ 43, 47, 47, 50, 50, 49, 45, 44, 44, 47, 47, 51, 51, 51, 49, 46, 46, 48,
+ 48, 53, 53, 53, 49, 46, 46, 48, 48, 53, 53, 53, 49, 46, 46, 48, 48, 53,
+ 53, 53, 48, 46, 46, 47, 47, 53, 53, 54, 48, 46, 46, 47, 47, 53, 53, 56,
+ 48, 46, 46, 47, 47, 53, 53, 56, 48, 46, 46, 47, 47, 53, 53, 56, 48, 45,
+ 45, 46, 46, 53, 53, 57, 49, 45, 45, 46, 46, 53, 53, 58, 49, 45, 45, 46,
+ 46, 53, 53, 58],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 31, 31, 30, 30, 30, 32, 33, 33, 33, 35, 37, 37, 37, 39,
+ 42, 42, 42, 45, 49, 49, 49, 48, 48, 48, 48, 48, 49, 49, 31, 31, 31, 31,
+ 31, 32, 32, 32, 32, 34, 36, 36, 36, 38, 40, 40, 40, 41, 43, 43, 43, 44,
+ 46, 46, 46, 46, 46, 46, 46, 45, 45, 45, 31, 31, 31, 31, 31, 32, 32, 32,
+ 32, 34, 36, 36, 36, 38, 40, 40, 40, 41, 43, 43, 43, 44, 46, 46, 46, 46,
+ 46, 46, 46, 45, 45, 45, 37, 37, 38, 38, 38, 39, 40, 40, 40, 41, 43, 43,
+ 43, 45, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 47, 47, 47, 47, 46,
+ 46, 46, 37, 37, 38, 38, 38, 39, 40, 40, 40, 41, 43, 43, 43, 45, 47, 47,
+ 47, 47, 47, 47, 47, 47, 48, 48, 48, 47, 47, 47, 47, 46, 46, 46, 48, 47,
+ 47, 47, 47, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 49, 50, 50,
+ 50, 51, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 48, 47, 47, 47, 47, 46,
+ 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 49, 50, 50, 50, 51, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53, 49, 48, 47, 47, 47, 46, 45, 45, 45, 45,
+ 46, 46, 46, 45, 45, 45, 45, 47, 49, 49, 49, 51, 53, 53, 53, 54, 56, 56,
+ 56, 57, 58, 58]]
+ ],
+ [
+ [ /* Luma */
+ /* Size 4x4 */
+ [32, 32, 32, 35, 32, 32, 33, 35, 32, 33, 35, 38, 35, 35, 38, 46],
+ /* Size 8x8 */
+ [31, 31, 31, 32, 32, 32, 34, 35, 31, 32, 32, 32, 32, 33, 34, 35, 31, 32,
+ 32, 32, 32, 33, 33, 34, 32, 32, 32, 33, 34, 34, 35, 36, 32, 32, 32, 34,
+ 35, 35, 36, 38, 32, 33, 33, 34, 35, 36, 38, 40, 34, 34, 33, 35, 36, 38,
+ 39, 42, 35, 35, 34, 36, 38, 40, 42, 48],
+ /* Size 16x16 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 33, 34, 34, 36, 36, 31, 31,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 35, 35, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 35, 35, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 34, 34, 35, 35, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 33, 33, 34, 34, 34, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 34, 34, 34, 31, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 34,
+ 35, 35, 36, 36, 31, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 35, 35, 36,
+ 36, 36, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 34, 35, 36, 36, 37, 37,
+ 32, 32, 32, 32, 32, 32, 33, 34, 34, 35, 35, 36, 37, 37, 38, 38, 32, 32,
+ 32, 32, 32, 32, 33, 34, 34, 35, 35, 36, 37, 37, 38, 38, 33, 33, 33, 33,
+ 33, 33, 34, 35, 35, 36, 36, 38, 39, 40, 42, 42, 34, 34, 34, 34, 33, 33,
+ 35, 35, 36, 37, 37, 39, 39, 41, 42, 42, 34, 34, 34, 34, 34, 34, 35, 36,
+ 36, 37, 37, 40, 41, 42, 45, 45, 36, 35, 35, 35, 34, 34, 36, 36, 37, 38,
+ 38, 42, 42, 45, 48, 48, 36, 35, 35, 35, 34, 34, 36, 36, 37, 38, 38, 42,
+ 42, 45, 48, 48],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32,
+ 32, 32, 32, 32, 33, 34, 34, 34, 34, 35, 36, 36, 36, 37, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 33, 34, 34, 34, 34, 35, 35, 35, 35, 37, 31, 31, 31, 31, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 34,
+ 34, 35, 35, 35, 35, 36, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 35,
+ 35, 36, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35, 36, 31, 31,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35, 36, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34,
+ 34, 34, 34, 34, 35, 35, 35, 36, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 34, 34,
+ 34, 34, 34, 35, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 35,
+ 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 35, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33,
+ 33, 33, 33, 33, 34, 34, 34, 34, 34, 35, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34,
+ 34, 35, 35, 35, 35, 36, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 35, 35, 35, 35, 36, 36, 36,
+ 36, 37, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33,
+ 33, 34, 34, 34, 34, 34, 35, 35, 35, 35, 36, 36, 36, 36, 36, 37, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 34, 34, 34,
+ 34, 34, 35, 35, 35, 35, 36, 36, 36, 36, 36, 37, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 35, 35,
+ 35, 35, 36, 36, 36, 36, 36, 37, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 35, 35, 36, 36, 36, 36, 37,
+ 37, 37, 37, 38, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34,
+ 34, 34, 34, 35, 35, 35, 35, 35, 36, 36, 36, 36, 37, 37, 38, 38, 38, 39,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 34, 34, 35,
+ 35, 35, 35, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35, 36,
+ 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35, 36, 36, 37, 37, 37,
+ 37, 38, 38, 38, 38, 39, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 34, 34, 34, 34, 35, 35, 36, 36, 36, 36, 37, 38, 38, 38, 38, 39, 40, 40,
+ 40, 41, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 35, 35, 35,
+ 35, 36, 36, 36, 36, 37, 38, 39, 39, 39, 40, 41, 42, 42, 42, 42, 34, 34,
+ 34, 34, 34, 34, 34, 33, 33, 33, 33, 34, 35, 35, 35, 35, 36, 36, 37, 37,
+ 37, 38, 39, 39, 39, 39, 41, 42, 42, 42, 42, 43, 34, 34, 34, 34, 34, 34,
+ 34, 33, 33, 33, 33, 34, 35, 35, 35, 35, 36, 36, 37, 37, 37, 38, 39, 39,
+ 39, 39, 41, 42, 42, 42, 42, 43, 34, 34, 34, 34, 34, 34, 34, 33, 33, 33,
+ 33, 34, 35, 35, 35, 35, 36, 36, 37, 37, 37, 38, 39, 39, 39, 39, 41, 42,
+ 42, 42, 42, 43, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 36,
+ 36, 36, 36, 37, 37, 37, 37, 38, 40, 41, 41, 41, 42, 44, 45, 45, 45, 45,
+ 35, 35, 35, 35, 35, 35, 34, 34, 34, 34, 34, 35, 36, 36, 36, 36, 37, 37,
+ 38, 38, 38, 39, 41, 42, 42, 42, 44, 46, 47, 47, 47, 48, 36, 35, 35, 35,
+ 35, 35, 35, 34, 34, 34, 34, 35, 36, 36, 36, 36, 37, 38, 38, 38, 38, 40,
+ 42, 42, 42, 42, 45, 47, 48, 48, 48, 49, 36, 35, 35, 35, 35, 35, 35, 34,
+ 34, 34, 34, 35, 36, 36, 36, 36, 37, 38, 38, 38, 38, 40, 42, 42, 42, 42,
+ 45, 47, 48, 48, 48, 49, 36, 35, 35, 35, 35, 35, 35, 34, 34, 34, 34, 35,
+ 36, 36, 36, 36, 37, 38, 38, 38, 38, 40, 42, 42, 42, 42, 45, 47, 48, 48,
+ 48, 49, 37, 37, 36, 36, 36, 36, 36, 35, 35, 35, 35, 36, 37, 37, 37, 37,
+ 38, 39, 39, 39, 39, 41, 42, 43, 43, 43, 45, 48, 49, 49, 49, 50],
+ /* Size 4x8 */
+ [31, 31, 32, 35, 32, 32, 32, 35, 32, 32, 33, 34, 32, 32, 34, 36, 32, 33,
+ 35, 38, 33, 33, 36, 40, 34, 34, 37, 42, 35, 34, 38, 48],
+ /* Size 8x4 */
+ [31, 32, 32, 32, 32, 33, 34, 35, 31, 32, 32, 32, 33, 33, 34, 34, 32, 32,
+ 33, 34, 35, 36, 37, 38, 35, 35, 34, 36, 38, 40, 42, 48],
+ /* Size 8x16 */
+ [32, 31, 31, 31, 32, 32, 35, 36, 31, 32, 32, 32, 32, 32, 35, 35, 31, 32,
+ 32, 32, 32, 32, 35, 35, 31, 32, 32, 32, 32, 32, 34, 35, 31, 32, 32, 32,
+ 33, 33, 34, 34, 31, 32, 32, 32, 33, 33, 34, 34, 31, 32, 32, 33, 34, 34,
+ 35, 36, 32, 32, 32, 33, 34, 34, 36, 36, 32, 32, 32, 33, 34, 34, 36, 37,
+ 32, 32, 33, 34, 35, 35, 37, 38, 32, 32, 33, 34, 35, 35, 37, 38, 33, 33,
+ 33, 35, 36, 36, 40, 41, 34, 34, 34, 35, 37, 37, 41, 42, 34, 34, 34, 35,
+ 37, 37, 43, 44, 36, 35, 34, 36, 38, 38, 46, 48, 36, 35, 34, 36, 38, 38,
+ 46, 48],
+ /* Size 16x8 */
+ [32, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 33, 34, 34, 36, 36, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 35, 35, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 34, 31, 32, 32, 32, 32, 32,
+ 33, 33, 33, 34, 34, 35, 35, 35, 36, 36, 32, 32, 32, 32, 33, 33, 34, 34,
+ 34, 35, 35, 36, 37, 37, 38, 38, 32, 32, 32, 32, 33, 33, 34, 34, 34, 35,
+ 35, 36, 37, 37, 38, 38, 35, 35, 35, 34, 34, 34, 35, 36, 36, 37, 37, 40,
+ 41, 43, 46, 46, 36, 35, 35, 35, 34, 34, 36, 36, 37, 38, 38, 41, 42, 44,
+ 48, 48],
+ /* Size 16x32 */
+ [32, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 33, 35, 36, 36, 36, 31, 31,
+ 31, 31, 31, 31, 32, 32, 32, 32, 32, 33, 35, 35, 35, 35, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 33, 35, 35, 35, 35, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 35, 35, 35, 35, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 33, 35, 35, 35, 35, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 35, 35, 35, 35, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33,
+ 34, 35, 35, 35, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 35,
+ 35, 35, 31, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34,
+ 31, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 31, 32,
+ 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 31, 32, 32, 32,
+ 32, 32, 33, 33, 33, 33, 33, 34, 35, 35, 35, 35, 31, 32, 32, 32, 32, 32,
+ 33, 33, 34, 34, 34, 34, 35, 36, 36, 36, 32, 32, 32, 32, 32, 32, 33, 34,
+ 34, 34, 34, 35, 36, 36, 36, 36, 32, 32, 32, 32, 32, 32, 33, 34, 34, 34,
+ 34, 35, 36, 36, 36, 36, 32, 32, 32, 32, 32, 32, 33, 34, 34, 34, 34, 35,
+ 36, 36, 36, 36, 32, 32, 32, 32, 32, 32, 33, 34, 34, 34, 34, 35, 36, 37,
+ 37, 37, 32, 32, 32, 33, 33, 33, 33, 34, 35, 35, 35, 36, 37, 38, 38, 38,
+ 32, 32, 32, 33, 33, 33, 34, 35, 35, 35, 35, 36, 37, 38, 38, 38, 32, 32,
+ 32, 33, 33, 33, 34, 35, 35, 35, 35, 36, 37, 38, 38, 38, 32, 32, 32, 33,
+ 33, 33, 34, 35, 35, 35, 35, 36, 37, 38, 38, 38, 32, 33, 33, 33, 33, 33,
+ 34, 35, 36, 36, 36, 37, 39, 40, 40, 40, 33, 33, 33, 33, 33, 33, 35, 36,
+ 36, 36, 36, 38, 40, 41, 41, 41, 34, 34, 34, 34, 34, 34, 35, 36, 37, 37,
+ 37, 39, 41, 42, 42, 42, 34, 34, 34, 34, 34, 34, 35, 36, 37, 37, 37, 39,
+ 41, 42, 42, 42, 34, 34, 34, 34, 34, 34, 35, 36, 37, 37, 37, 39, 41, 42,
+ 42, 42, 34, 34, 34, 34, 34, 34, 35, 37, 37, 37, 37, 40, 43, 44, 44, 44,
+ 35, 35, 34, 34, 34, 34, 36, 37, 38, 38, 38, 41, 45, 47, 47, 47, 36, 35,
+ 35, 34, 34, 34, 36, 37, 38, 38, 38, 42, 46, 48, 48, 48, 36, 35, 35, 34,
+ 34, 34, 36, 37, 38, 38, 38, 42, 46, 48, 48, 48, 36, 35, 35, 34, 34, 34,
+ 36, 37, 38, 38, 38, 42, 46, 48, 48, 48, 37, 36, 36, 36, 36, 36, 37, 38,
+ 39, 39, 39, 42, 46, 49, 49, 49],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 33, 34, 34, 34, 34, 35, 36, 36, 36, 37, 31, 31, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33,
+ 33, 34, 34, 34, 34, 35, 35, 35, 35, 36, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 34,
+ 34, 34, 35, 35, 35, 36, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34,
+ 34, 36, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 36, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33,
+ 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 36, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35,
+ 35, 35, 35, 36, 36, 36, 36, 37, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 34, 34, 34, 34, 34, 35, 35, 35, 35, 36, 36, 36, 36, 37, 37,
+ 37, 37, 37, 38, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34,
+ 34, 34, 34, 35, 35, 35, 35, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39,
+ 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 34, 35,
+ 35, 35, 35, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 32, 32, 32, 32,
+ 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 34, 35, 35, 35, 35, 36,
+ 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 34, 34, 35, 35, 35, 35, 36, 36, 36, 36, 37, 38, 39, 39, 39,
+ 40, 41, 42, 42, 42, 42, 35, 35, 35, 35, 35, 35, 34, 34, 34, 34, 34, 35,
+ 35, 36, 36, 36, 36, 37, 37, 37, 37, 39, 40, 41, 41, 41, 43, 45, 46, 46,
+ 46, 46, 36, 35, 35, 35, 35, 35, 35, 35, 34, 34, 34, 35, 36, 36, 36, 36,
+ 37, 38, 38, 38, 38, 40, 41, 42, 42, 42, 44, 47, 48, 48, 48, 49, 36, 35,
+ 35, 35, 35, 35, 35, 35, 34, 34, 34, 35, 36, 36, 36, 36, 37, 38, 38, 38,
+ 38, 40, 41, 42, 42, 42, 44, 47, 48, 48, 48, 49, 36, 35, 35, 35, 35, 35,
+ 35, 35, 34, 34, 34, 35, 36, 36, 36, 36, 37, 38, 38, 38, 38, 40, 41, 42,
+ 42, 42, 44, 47, 48, 48, 48, 49],
+ /* Size 4x16 */
+ [31, 31, 32, 36, 31, 32, 32, 35, 32, 32, 32, 35, 32, 32, 32, 35, 32, 32,
+ 33, 34, 32, 32, 33, 34, 32, 32, 34, 36, 32, 32, 34, 36, 32, 32, 34, 37,
+ 32, 33, 35, 38, 32, 33, 35, 38, 33, 33, 36, 41, 34, 34, 37, 42, 34, 34,
+ 37, 44, 35, 34, 38, 48, 35, 34, 38, 48],
+ /* Size 16x4 */
+ [32, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 35, 35, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 34, 32, 32, 32, 32,
+ 33, 33, 34, 34, 34, 35, 35, 36, 37, 37, 38, 38, 36, 35, 35, 35, 34, 34,
+ 36, 36, 37, 38, 38, 41, 42, 44, 48, 48],
+ /* Size 8x32 */
+ [32, 31, 31, 31, 32, 32, 35, 36, 31, 31, 31, 32, 32, 32, 35, 35, 31, 32,
+ 32, 32, 32, 32, 35, 35, 31, 32, 32, 32, 32, 32, 35, 35, 31, 32, 32, 32,
+ 32, 32, 35, 35, 31, 32, 32, 32, 32, 32, 35, 35, 31, 32, 32, 32, 32, 32,
+ 34, 35, 31, 32, 32, 32, 32, 32, 34, 35, 31, 32, 32, 32, 33, 33, 34, 34,
+ 31, 32, 32, 32, 33, 33, 34, 34, 31, 32, 32, 32, 33, 33, 34, 34, 31, 32,
+ 32, 33, 33, 33, 35, 35, 31, 32, 32, 33, 34, 34, 35, 36, 32, 32, 32, 33,
+ 34, 34, 36, 36, 32, 32, 32, 33, 34, 34, 36, 36, 32, 32, 32, 33, 34, 34,
+ 36, 36, 32, 32, 32, 33, 34, 34, 36, 37, 32, 32, 33, 33, 35, 35, 37, 38,
+ 32, 32, 33, 34, 35, 35, 37, 38, 32, 32, 33, 34, 35, 35, 37, 38, 32, 32,
+ 33, 34, 35, 35, 37, 38, 32, 33, 33, 34, 36, 36, 39, 40, 33, 33, 33, 35,
+ 36, 36, 40, 41, 34, 34, 34, 35, 37, 37, 41, 42, 34, 34, 34, 35, 37, 37,
+ 41, 42, 34, 34, 34, 35, 37, 37, 41, 42, 34, 34, 34, 35, 37, 37, 43, 44,
+ 35, 34, 34, 36, 38, 38, 45, 47, 36, 35, 34, 36, 38, 38, 46, 48, 36, 35,
+ 34, 36, 38, 38, 46, 48, 36, 35, 34, 36, 38, 38, 46, 48, 37, 36, 36, 37,
+ 39, 39, 46, 49],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 33, 34, 34, 34, 34, 35, 36, 36, 36, 37, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33,
+ 33, 34, 34, 34, 34, 34, 35, 35, 35, 36, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 34, 34, 34,
+ 34, 34, 34, 34, 34, 36, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33,
+ 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35, 35, 36, 36, 36,
+ 36, 37, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34,
+ 34, 35, 35, 35, 35, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 32, 32,
+ 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 34, 35, 35, 35,
+ 35, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 35, 35, 35, 35, 35, 35,
+ 34, 34, 34, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37, 39, 40, 41,
+ 41, 41, 43, 45, 46, 46, 46, 46, 36, 35, 35, 35, 35, 35, 35, 35, 34, 34,
+ 34, 35, 36, 36, 36, 36, 37, 38, 38, 38, 38, 40, 41, 42, 42, 42, 44, 47,
+ 48, 48, 48, 49]],
+ [ /* Chroma */
+ /* Size 4x4 */
+ [31, 32, 38, 46, 32, 34, 41, 46, 38, 41, 47, 47, 46, 46, 47, 52],
+ /* Size 8x8 */
+ [31, 31, 30, 34, 36, 39, 42, 48, 31, 31, 31, 34, 37, 40, 42, 47, 30, 31,
+ 32, 35, 39, 41, 42, 46, 34, 34, 35, 39, 42, 44, 45, 47, 36, 37, 39, 42,
+ 46, 47, 47, 47, 39, 40, 41, 44, 47, 47, 48, 49, 42, 42, 42, 45, 47, 48,
+ 48, 50, 48, 47, 46, 47, 47, 49, 50, 53],
+ /* Size 16x16 */
+ [32, 31, 31, 31, 30, 30, 33, 33, 34, 36, 36, 40, 41, 44, 49, 49, 31, 31,
+ 31, 31, 31, 31, 33, 34, 36, 38, 38, 41, 42, 44, 48, 48, 31, 31, 31, 31,
+ 31, 31, 34, 34, 36, 38, 38, 41, 42, 44, 47, 47, 31, 31, 31, 31, 31, 31,
+ 34, 35, 36, 39, 39, 41, 42, 44, 47, 47, 30, 31, 31, 31, 32, 32, 34, 35,
+ 37, 40, 40, 42, 42, 44, 46, 46, 30, 31, 31, 31, 32, 32, 34, 35, 37, 40,
+ 40, 42, 42, 44, 46, 46, 33, 33, 34, 34, 34, 34, 37, 38, 40, 42, 42, 44,
+ 44, 45, 47, 47, 33, 34, 34, 35, 35, 35, 38, 39, 40, 43, 43, 44, 45, 46,
+ 47, 47, 34, 36, 36, 36, 37, 37, 40, 40, 42, 45, 45, 45, 46, 46, 47, 47,
+ 36, 38, 38, 39, 40, 40, 42, 43, 45, 47, 47, 47, 47, 47, 48, 48, 36, 38,
+ 38, 39, 40, 40, 42, 43, 45, 47, 47, 47, 47, 47, 48, 48, 40, 41, 41, 41,
+ 42, 42, 44, 44, 45, 47, 47, 48, 48, 49, 50, 50, 41, 42, 42, 42, 42, 42,
+ 44, 45, 46, 47, 47, 48, 48, 49, 50, 50, 44, 44, 44, 44, 44, 44, 45, 46,
+ 46, 47, 47, 49, 49, 50, 51, 51, 49, 48, 47, 47, 46, 46, 47, 47, 47, 48,
+ 48, 50, 50, 51, 53, 53, 49, 48, 47, 47, 46, 46, 47, 47, 47, 48, 48, 50,
+ 50, 51, 53, 53],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 31, 33, 33, 33, 33, 34, 36,
+ 36, 36, 36, 38, 40, 41, 41, 41, 44, 47, 49, 49, 49, 49, 31, 31, 31, 31,
+ 31, 31, 31, 31, 30, 30, 30, 32, 33, 34, 34, 34, 35, 36, 37, 37, 37, 39,
+ 41, 42, 42, 42, 44, 47, 48, 48, 48, 48, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 32, 33, 34, 34, 34, 36, 37, 38, 38, 38, 39, 41, 42, 42, 42,
+ 44, 46, 48, 48, 48, 47, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32,
+ 34, 34, 34, 34, 36, 37, 38, 38, 38, 40, 41, 42, 42, 42, 44, 46, 47, 47,
+ 47, 47, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 34, 34, 34, 34,
+ 36, 37, 38, 38, 38, 40, 41, 42, 42, 42, 44, 46, 47, 47, 47, 47, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 34, 34, 34, 34, 36, 37, 38, 38,
+ 38, 40, 41, 42, 42, 42, 44, 46, 47, 47, 47, 47, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 33, 34, 35, 35, 35, 36, 38, 39, 39, 39, 40, 41, 42,
+ 42, 42, 44, 46, 47, 47, 47, 47, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 33, 34, 35, 35, 35, 37, 38, 39, 39, 39, 41, 42, 42, 42, 42, 44, 46,
+ 46, 46, 46, 46, 30, 30, 31, 31, 31, 31, 31, 31, 32, 32, 32, 33, 34, 35,
+ 35, 35, 37, 39, 40, 40, 40, 41, 42, 42, 42, 42, 44, 45, 46, 46, 46, 46,
+ 30, 30, 31, 31, 31, 31, 31, 31, 32, 32, 32, 33, 34, 35, 35, 35, 37, 39,
+ 40, 40, 40, 41, 42, 42, 42, 42, 44, 45, 46, 46, 46, 46, 30, 30, 31, 31,
+ 31, 31, 31, 31, 32, 32, 32, 33, 34, 35, 35, 35, 37, 39, 40, 40, 40, 41,
+ 42, 42, 42, 42, 44, 45, 46, 46, 46, 46, 31, 32, 32, 32, 32, 32, 33, 33,
+ 33, 33, 33, 34, 36, 37, 37, 37, 38, 40, 41, 41, 41, 42, 43, 43, 43, 43,
+ 44, 46, 46, 46, 46, 46, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 36,
+ 37, 38, 38, 38, 40, 41, 42, 42, 42, 43, 44, 44, 44, 44, 45, 46, 47, 47,
+ 47, 46, 33, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 37, 38, 39, 39, 39,
+ 40, 42, 43, 43, 43, 44, 44, 45, 45, 45, 46, 47, 47, 47, 47, 47, 33, 34,
+ 34, 34, 34, 34, 35, 35, 35, 35, 35, 37, 38, 39, 39, 39, 40, 42, 43, 43,
+ 43, 44, 44, 45, 45, 45, 46, 47, 47, 47, 47, 47, 33, 34, 34, 34, 34, 34,
+ 35, 35, 35, 35, 35, 37, 38, 39, 39, 39, 40, 42, 43, 43, 43, 44, 44, 45,
+ 45, 45, 46, 47, 47, 47, 47, 47, 34, 35, 36, 36, 36, 36, 36, 37, 37, 37,
+ 37, 38, 40, 40, 40, 40, 42, 44, 45, 45, 45, 45, 45, 46, 46, 46, 46, 47,
+ 47, 47, 47, 47, 36, 36, 37, 37, 37, 37, 38, 38, 39, 39, 39, 40, 41, 42,
+ 42, 42, 44, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 36, 37, 38, 38, 38, 38, 39, 39, 40, 40, 40, 41, 42, 43, 43, 43, 45, 46,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 47, 36, 37, 38, 38,
+ 38, 38, 39, 39, 40, 40, 40, 41, 42, 43, 43, 43, 45, 46, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 48, 48, 48, 47, 36, 37, 38, 38, 38, 38, 39, 39,
+ 40, 40, 40, 41, 42, 43, 43, 43, 45, 46, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 48, 48, 48, 47, 38, 39, 39, 40, 40, 40, 40, 41, 41, 41, 41, 42,
+ 43, 44, 44, 44, 45, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 49, 49,
+ 49, 48, 40, 41, 41, 41, 41, 41, 41, 42, 42, 42, 42, 43, 44, 44, 44, 44,
+ 45, 47, 47, 47, 47, 48, 48, 48, 48, 48, 49, 49, 50, 50, 50, 49, 41, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 44, 45, 45, 45, 46, 47, 47, 47,
+ 47, 48, 48, 48, 48, 48, 49, 50, 50, 50, 50, 50, 41, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 43, 44, 45, 45, 45, 46, 47, 47, 47, 47, 48, 48, 48,
+ 48, 48, 49, 50, 50, 50, 50, 50, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 43, 44, 45, 45, 45, 46, 47, 47, 47, 47, 48, 48, 48, 48, 48, 49, 50,
+ 50, 50, 50, 50, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 46,
+ 46, 46, 46, 47, 47, 47, 47, 48, 49, 49, 49, 49, 50, 51, 51, 51, 51, 51,
+ 47, 47, 46, 46, 46, 46, 46, 46, 45, 45, 45, 46, 46, 47, 47, 47, 47, 47,
+ 47, 47, 47, 48, 49, 50, 50, 50, 51, 52, 52, 52, 52, 52, 49, 48, 48, 47,
+ 47, 47, 47, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 48, 48, 48, 49,
+ 50, 50, 50, 50, 51, 52, 53, 53, 53, 53, 49, 48, 48, 47, 47, 47, 47, 46,
+ 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 48, 48, 48, 49, 50, 50, 50, 50,
+ 51, 52, 53, 53, 53, 53, 49, 48, 48, 47, 47, 47, 47, 46, 46, 46, 46, 46,
+ 47, 47, 47, 47, 47, 47, 48, 48, 48, 49, 50, 50, 50, 50, 51, 52, 53, 53,
+ 53, 53, 49, 48, 47, 47, 47, 47, 47, 46, 46, 46, 46, 46, 46, 47, 47, 47,
+ 47, 47, 47, 47, 47, 48, 49, 50, 50, 50, 51, 52, 53, 53, 53, 53],
+ /* Size 4x8 */
+ [31, 31, 37, 48, 31, 31, 38, 47, 31, 32, 40, 46, 34, 36, 43, 47, 37, 39,
+ 46, 47, 39, 41, 47, 48, 42, 43, 47, 50, 48, 46, 48, 53],
+ /* Size 8x4 */
+ [31, 31, 31, 34, 37, 39, 42, 48, 31, 31, 32, 36, 39, 41, 43, 46, 37, 38,
+ 40, 43, 46, 47, 47, 48, 48, 47, 46, 47, 47, 48, 50, 53],
+ /* Size 8x16 */
+ [32, 31, 31, 33, 37, 37, 45, 48, 31, 31, 31, 34, 38, 38, 45, 47, 31, 31,
+ 31, 34, 38, 38, 45, 47, 31, 31, 32, 34, 39, 39, 45, 46, 30, 32, 32, 35,
+ 40, 40, 44, 46, 30, 32, 32, 35, 40, 40, 44, 46, 33, 34, 35, 37, 42, 42,
+ 46, 47, 33, 35, 36, 38, 43, 43, 46, 47, 35, 37, 37, 40, 44, 44, 46, 47,
+ 37, 39, 40, 43, 47, 47, 47, 47, 37, 39, 40, 43, 47, 47, 47, 47, 41, 42,
+ 42, 44, 47, 47, 49, 49, 42, 42, 43, 44, 47, 47, 49, 50, 44, 44, 44, 45,
+ 47, 47, 50, 51, 49, 47, 46, 47, 48, 48, 52, 53, 49, 47, 46, 47, 48, 48,
+ 52, 53],
+ /* Size 16x8 */
+ [32, 31, 31, 31, 30, 30, 33, 33, 35, 37, 37, 41, 42, 44, 49, 49, 31, 31,
+ 31, 31, 32, 32, 34, 35, 37, 39, 39, 42, 42, 44, 47, 47, 31, 31, 31, 32,
+ 32, 32, 35, 36, 37, 40, 40, 42, 43, 44, 46, 46, 33, 34, 34, 34, 35, 35,
+ 37, 38, 40, 43, 43, 44, 44, 45, 47, 47, 37, 38, 38, 39, 40, 40, 42, 43,
+ 44, 47, 47, 47, 47, 47, 48, 48, 37, 38, 38, 39, 40, 40, 42, 43, 44, 47,
+ 47, 47, 47, 47, 48, 48, 45, 45, 45, 45, 44, 44, 46, 46, 46, 47, 47, 49,
+ 49, 50, 52, 52, 48, 47, 47, 46, 46, 46, 47, 47, 47, 47, 47, 49, 50, 51,
+ 53, 53],
+ /* Size 16x32 */
+ [32, 31, 31, 31, 31, 31, 33, 35, 37, 37, 37, 40, 45, 48, 48, 48, 31, 31,
+ 31, 31, 31, 31, 33, 36, 37, 37, 37, 41, 45, 48, 48, 48, 31, 31, 31, 31,
+ 31, 31, 34, 36, 38, 38, 38, 41, 45, 47, 47, 47, 31, 31, 31, 31, 31, 31,
+ 34, 37, 38, 38, 38, 41, 45, 47, 47, 47, 31, 31, 31, 31, 31, 31, 34, 37,
+ 38, 38, 38, 41, 45, 47, 47, 47, 31, 31, 31, 31, 31, 31, 34, 37, 38, 38,
+ 38, 41, 45, 47, 47, 47, 31, 31, 31, 32, 32, 32, 34, 37, 39, 39, 39, 41,
+ 45, 46, 46, 46, 30, 31, 31, 32, 32, 32, 34, 38, 39, 39, 39, 42, 44, 46,
+ 46, 46, 30, 31, 32, 32, 32, 32, 35, 38, 40, 40, 40, 42, 44, 46, 46, 46,
+ 30, 31, 32, 32, 32, 32, 35, 38, 40, 40, 40, 42, 44, 46, 46, 46, 30, 31,
+ 32, 32, 32, 32, 35, 38, 40, 40, 40, 42, 44, 46, 46, 46, 31, 32, 33, 33,
+ 33, 33, 36, 39, 41, 41, 41, 43, 45, 46, 46, 46, 33, 34, 34, 35, 35, 35,
+ 37, 40, 42, 42, 42, 44, 46, 47, 47, 47, 33, 34, 35, 36, 36, 36, 38, 41,
+ 43, 43, 43, 44, 46, 47, 47, 47, 33, 34, 35, 36, 36, 36, 38, 41, 43, 43,
+ 43, 44, 46, 47, 47, 47, 33, 34, 35, 36, 36, 36, 38, 41, 43, 43, 43, 44,
+ 46, 47, 47, 47, 35, 36, 37, 37, 37, 37, 40, 43, 44, 44, 44, 45, 46, 47,
+ 47, 47, 36, 37, 38, 39, 39, 39, 42, 44, 46, 46, 46, 47, 47, 47, 47, 47,
+ 37, 38, 39, 40, 40, 40, 43, 45, 47, 47, 47, 47, 47, 47, 47, 47, 37, 38,
+ 39, 40, 40, 40, 43, 45, 47, 47, 47, 47, 47, 47, 47, 47, 37, 38, 39, 40,
+ 40, 40, 43, 45, 47, 47, 47, 47, 47, 47, 47, 47, 39, 39, 40, 41, 41, 41,
+ 43, 46, 47, 47, 47, 48, 48, 48, 48, 48, 41, 41, 42, 42, 42, 42, 44, 46,
+ 47, 47, 47, 48, 49, 49, 49, 49, 42, 42, 42, 43, 43, 43, 44, 46, 47, 47,
+ 47, 48, 49, 50, 50, 50, 42, 42, 42, 43, 43, 43, 44, 46, 47, 47, 47, 48,
+ 49, 50, 50, 50, 42, 42, 42, 43, 43, 43, 44, 46, 47, 47, 47, 48, 49, 50,
+ 50, 50, 44, 44, 44, 44, 44, 44, 45, 47, 47, 47, 47, 49, 50, 51, 51, 51,
+ 47, 46, 46, 46, 46, 46, 46, 47, 48, 48, 48, 49, 51, 52, 52, 52, 49, 48,
+ 47, 46, 46, 46, 47, 48, 48, 48, 48, 50, 52, 53, 53, 53, 49, 48, 47, 46,
+ 46, 46, 47, 48, 48, 48, 48, 50, 52, 53, 53, 53, 49, 48, 47, 46, 46, 46,
+ 47, 48, 48, 48, 48, 50, 52, 53, 53, 53, 49, 48, 47, 46, 46, 46, 47, 47,
+ 47, 47, 47, 49, 52, 53, 53, 53],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 31, 33, 33, 33, 33, 35, 36,
+ 37, 37, 37, 39, 41, 42, 42, 42, 44, 47, 49, 49, 49, 49, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 32, 34, 34, 34, 34, 36, 37, 38, 38, 38, 39,
+ 41, 42, 42, 42, 44, 46, 48, 48, 48, 48, 31, 31, 31, 31, 31, 31, 31, 31,
+ 32, 32, 32, 33, 34, 35, 35, 35, 37, 38, 39, 39, 39, 40, 42, 42, 42, 42,
+ 44, 46, 47, 47, 47, 47, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 33,
+ 35, 36, 36, 36, 37, 39, 40, 40, 40, 41, 42, 43, 43, 43, 44, 46, 46, 46,
+ 46, 46, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 33, 35, 36, 36, 36,
+ 37, 39, 40, 40, 40, 41, 42, 43, 43, 43, 44, 46, 46, 46, 46, 46, 31, 31,
+ 31, 31, 31, 31, 32, 32, 32, 32, 32, 33, 35, 36, 36, 36, 37, 39, 40, 40,
+ 40, 41, 42, 43, 43, 43, 44, 46, 46, 46, 46, 46, 33, 33, 34, 34, 34, 34,
+ 34, 34, 35, 35, 35, 36, 37, 38, 38, 38, 40, 42, 43, 43, 43, 43, 44, 44,
+ 44, 44, 45, 46, 47, 47, 47, 47, 35, 36, 36, 37, 37, 37, 37, 38, 38, 38,
+ 38, 39, 40, 41, 41, 41, 43, 44, 45, 45, 45, 46, 46, 46, 46, 46, 47, 47,
+ 48, 48, 48, 47, 37, 37, 38, 38, 38, 38, 39, 39, 40, 40, 40, 41, 42, 43,
+ 43, 43, 44, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 47,
+ 37, 37, 38, 38, 38, 38, 39, 39, 40, 40, 40, 41, 42, 43, 43, 43, 44, 46,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 47, 37, 37, 38, 38,
+ 38, 38, 39, 39, 40, 40, 40, 41, 42, 43, 43, 43, 44, 46, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 48, 48, 48, 48, 47, 40, 41, 41, 41, 41, 41, 41, 42,
+ 42, 42, 42, 43, 44, 44, 44, 44, 45, 47, 47, 47, 47, 48, 48, 48, 48, 48,
+ 49, 49, 50, 50, 50, 49, 45, 45, 45, 45, 45, 45, 45, 44, 44, 44, 44, 45,
+ 46, 46, 46, 46, 46, 47, 47, 47, 47, 48, 49, 49, 49, 49, 50, 51, 52, 52,
+ 52, 52, 48, 48, 47, 47, 47, 47, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 48, 49, 50, 50, 50, 51, 52, 53, 53, 53, 53, 48, 48,
+ 47, 47, 47, 47, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 48, 49, 50, 50, 50, 51, 52, 53, 53, 53, 53, 48, 48, 47, 47, 47, 47,
+ 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 49, 50,
+ 50, 50, 51, 52, 53, 53, 53, 53],
+ /* Size 4x16 */
+ [31, 31, 37, 48, 31, 31, 38, 47, 31, 31, 38, 47, 31, 32, 39, 46, 31, 32,
+ 40, 46, 31, 32, 40, 46, 34, 35, 42, 47, 34, 36, 43, 47, 36, 37, 44, 47,
+ 38, 40, 47, 47, 38, 40, 47, 47, 41, 42, 47, 49, 42, 43, 47, 50, 44, 44,
+ 47, 51, 48, 46, 48, 53, 48, 46, 48, 53],
+ /* Size 16x4 */
+ [31, 31, 31, 31, 31, 31, 34, 34, 36, 38, 38, 41, 42, 44, 48, 48, 31, 31,
+ 31, 32, 32, 32, 35, 36, 37, 40, 40, 42, 43, 44, 46, 46, 37, 38, 38, 39,
+ 40, 40, 42, 43, 44, 47, 47, 47, 47, 47, 48, 48, 48, 47, 47, 46, 46, 46,
+ 47, 47, 47, 47, 47, 49, 50, 51, 53, 53],
+ /* Size 8x32 */
+ [32, 31, 31, 33, 37, 37, 45, 48, 31, 31, 31, 33, 37, 37, 45, 48, 31, 31,
+ 31, 34, 38, 38, 45, 47, 31, 31, 31, 34, 38, 38, 45, 47, 31, 31, 31, 34,
+ 38, 38, 45, 47, 31, 31, 31, 34, 38, 38, 45, 47, 31, 31, 32, 34, 39, 39,
+ 45, 46, 30, 31, 32, 34, 39, 39, 44, 46, 30, 32, 32, 35, 40, 40, 44, 46,
+ 30, 32, 32, 35, 40, 40, 44, 46, 30, 32, 32, 35, 40, 40, 44, 46, 31, 33,
+ 33, 36, 41, 41, 45, 46, 33, 34, 35, 37, 42, 42, 46, 47, 33, 35, 36, 38,
+ 43, 43, 46, 47, 33, 35, 36, 38, 43, 43, 46, 47, 33, 35, 36, 38, 43, 43,
+ 46, 47, 35, 37, 37, 40, 44, 44, 46, 47, 36, 38, 39, 42, 46, 46, 47, 47,
+ 37, 39, 40, 43, 47, 47, 47, 47, 37, 39, 40, 43, 47, 47, 47, 47, 37, 39,
+ 40, 43, 47, 47, 47, 47, 39, 40, 41, 43, 47, 47, 48, 48, 41, 42, 42, 44,
+ 47, 47, 49, 49, 42, 42, 43, 44, 47, 47, 49, 50, 42, 42, 43, 44, 47, 47,
+ 49, 50, 42, 42, 43, 44, 47, 47, 49, 50, 44, 44, 44, 45, 47, 47, 50, 51,
+ 47, 46, 46, 46, 48, 48, 51, 52, 49, 47, 46, 47, 48, 48, 52, 53, 49, 47,
+ 46, 47, 48, 48, 52, 53, 49, 47, 46, 47, 48, 48, 52, 53, 49, 47, 46, 47,
+ 47, 47, 52, 53],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 31, 33, 33, 33, 33, 35, 36,
+ 37, 37, 37, 39, 41, 42, 42, 42, 44, 47, 49, 49, 49, 49, 31, 31, 31, 31,
+ 31, 31, 31, 31, 32, 32, 32, 33, 34, 35, 35, 35, 37, 38, 39, 39, 39, 40,
+ 42, 42, 42, 42, 44, 46, 47, 47, 47, 47, 31, 31, 31, 31, 31, 31, 32, 32,
+ 32, 32, 32, 33, 35, 36, 36, 36, 37, 39, 40, 40, 40, 41, 42, 43, 43, 43,
+ 44, 46, 46, 46, 46, 46, 33, 33, 34, 34, 34, 34, 34, 34, 35, 35, 35, 36,
+ 37, 38, 38, 38, 40, 42, 43, 43, 43, 43, 44, 44, 44, 44, 45, 46, 47, 47,
+ 47, 47, 37, 37, 38, 38, 38, 38, 39, 39, 40, 40, 40, 41, 42, 43, 43, 43,
+ 44, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 47, 37, 37,
+ 38, 38, 38, 38, 39, 39, 40, 40, 40, 41, 42, 43, 43, 43, 44, 46, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 47, 45, 45, 45, 45, 45, 45,
+ 45, 44, 44, 44, 44, 45, 46, 46, 46, 46, 46, 47, 47, 47, 47, 48, 49, 49,
+ 49, 49, 50, 51, 52, 52, 52, 52, 48, 48, 47, 47, 47, 47, 46, 46, 46, 46,
+ 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 49, 50, 50, 50, 51, 52,
+ 53, 53, 53, 53]]
+ ],
+ [
+ [ /* Luma */
+ /* Size 4x4 */
+ [31, 32, 32, 32, 32, 32, 32, 33, 32, 32, 33, 34, 32, 33, 34, 35],
+ /* Size 8x8 */
+ [31, 31, 31, 31, 32, 32, 32, 33, 31, 32, 32, 32, 32, 32, 32, 33, 31, 32,
+ 32, 32, 32, 32, 32, 33, 31, 32, 32, 32, 32, 32, 32, 33, 32, 32, 32, 32,
+ 33, 33, 34, 35, 32, 32, 32, 32, 33, 34, 34, 35, 32, 32, 32, 32, 34, 34,
+ 35, 36, 33, 33, 33, 33, 35, 35, 36, 38],
+ /* Size 16x16 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 34, 31, 31,
+ 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 33, 34, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 33, 34, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 33, 33, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 33, 33, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33,
+ 33, 34, 31, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 34, 35,
+ 31, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 35, 31, 32,
+ 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 35, 32, 32, 32, 32,
+ 32, 32, 32, 33, 33, 33, 33, 34, 35, 35, 35, 36, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 34, 34, 35, 35, 35, 36, 37, 32, 32, 32, 32, 32, 32, 32, 33,
+ 33, 34, 34, 35, 35, 35, 36, 37, 32, 33, 33, 33, 33, 33, 33, 33, 34, 34,
+ 34, 35, 36, 36, 36, 38, 34, 34, 34, 34, 34, 33, 33, 34, 35, 35, 35, 36,
+ 37, 37, 38, 39],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 33, 33, 34, 34, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33,
+ 34, 34, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 31, 31,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 31, 31, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 33, 33, 34, 34, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 33, 33, 34, 34, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34,
+ 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 31, 31, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 31, 31, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 33, 33, 33, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33,
+ 33, 33, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 34, 34, 34, 34, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34,
+ 34, 34, 35, 35, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 35, 35, 35,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33,
+ 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 35, 35, 35, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33,
+ 33, 34, 34, 34, 34, 34, 34, 35, 35, 35, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34,
+ 34, 34, 34, 35, 35, 35, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 35, 35,
+ 35, 35, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33,
+ 33, 33, 33, 33, 33, 34, 34, 34, 35, 35, 35, 35, 35, 35, 36, 36, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34,
+ 34, 34, 34, 35, 35, 35, 35, 35, 35, 36, 36, 36, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 34, 34, 35, 35,
+ 35, 35, 35, 35, 36, 36, 37, 37, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35,
+ 36, 36, 37, 37, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 33, 33, 33, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 36, 36, 37, 37,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 34, 34,
+ 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 36, 36, 37, 37, 32, 32, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 35,
+ 35, 35, 36, 36, 36, 36, 36, 37, 38, 38, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 34, 34, 35, 35, 35, 35, 35, 35, 36, 36, 36,
+ 36, 36, 37, 38, 38, 38, 34, 34, 34, 34, 34, 34, 34, 34, 34, 33, 33, 33,
+ 33, 33, 34, 34, 35, 35, 35, 35, 35, 35, 36, 36, 37, 37, 37, 37, 38, 38,
+ 39, 39, 34, 34, 34, 34, 34, 34, 34, 34, 34, 33, 33, 33, 33, 33, 34, 34,
+ 35, 35, 35, 35, 35, 35, 36, 36, 37, 37, 37, 37, 38, 38, 39, 39],
+ /* Size 4x8 */
+ [31, 31, 32, 32, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 32, 32,
+ 33, 34, 32, 32, 34, 34, 32, 33, 34, 35, 33, 33, 35, 36],
+ /* Size 8x4 */
+ [31, 31, 32, 32, 32, 32, 32, 33, 31, 32, 32, 32, 32, 32, 33, 33, 32, 32,
+ 32, 32, 33, 34, 34, 35, 32, 32, 32, 33, 34, 34, 35, 36],
+ /* Size 8x16 */
+ [32, 31, 31, 31, 31, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 33, 31, 32,
+ 32, 32, 32, 32, 32, 33, 31, 32, 32, 32, 32, 32, 32, 33, 31, 32, 32, 32,
+ 32, 32, 32, 33, 31, 32, 32, 32, 32, 33, 33, 33, 31, 32, 32, 32, 32, 33,
+ 33, 33, 31, 32, 32, 32, 32, 33, 33, 33, 31, 32, 32, 32, 33, 34, 34, 34,
+ 32, 32, 32, 32, 33, 34, 34, 34, 32, 32, 32, 32, 33, 34, 34, 34, 32, 32,
+ 32, 32, 33, 35, 35, 35, 32, 32, 33, 33, 34, 35, 35, 36, 32, 32, 33, 33,
+ 34, 35, 35, 36, 32, 33, 33, 33, 34, 36, 36, 36, 34, 34, 34, 34, 35, 37,
+ 37, 38],
+ /* Size 16x8 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 34, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 31, 32, 32, 32, 32, 32, 32, 32,
+ 33, 33, 33, 33, 34, 34, 34, 35, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34,
+ 34, 35, 35, 35, 36, 37, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35,
+ 35, 35, 36, 37, 32, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 35, 36, 36,
+ 36, 38],
+ /* Size 16x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 34, 31, 31,
+ 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 33, 34, 31, 31, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 33, 34, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 33, 34, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 33, 34, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 33, 34, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 33, 33, 33, 33, 33, 33, 31, 32, 32, 32, 32, 32, 32, 32, 32, 33,
+ 33, 33, 33, 33, 33, 34, 31, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33,
+ 33, 33, 34, 34, 31, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 34, 34,
+ 34, 35, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 34, 34, 35,
+ 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 34, 34, 35, 32, 32,
+ 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 34, 34, 35, 32, 32, 32, 32,
+ 32, 32, 32, 33, 33, 33, 34, 34, 34, 34, 34, 35, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 34, 34, 34, 34, 34, 35, 35, 32, 32, 32, 32, 32, 32, 32, 33,
+ 33, 34, 35, 35, 35, 35, 35, 36, 32, 32, 32, 32, 33, 33, 33, 33, 33, 34,
+ 35, 35, 35, 35, 36, 36, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 35, 35,
+ 35, 35, 36, 37, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 35, 35, 35, 35,
+ 36, 37, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 35, 35, 35, 35, 36, 37,
+ 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, 35, 35, 35, 35, 36, 37, 32, 33,
+ 33, 33, 33, 33, 33, 33, 34, 35, 36, 36, 36, 36, 36, 38, 33, 33, 33, 33,
+ 33, 33, 33, 34, 34, 35, 36, 36, 36, 36, 37, 38, 34, 34, 34, 34, 34, 34,
+ 34, 34, 35, 36, 37, 37, 37, 37, 38, 39, 34, 34, 34, 34, 34, 34, 34, 34,
+ 35, 36, 37, 37, 37, 37, 38, 39],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 31, 31, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 33, 33, 34, 34, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33,
+ 34, 34, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 34, 34, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 34, 34, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33,
+ 33, 33, 33, 33, 33, 33, 34, 34, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 34, 34, 34, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 35, 35,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33,
+ 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 35, 35, 36, 36, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34,
+ 35, 35, 35, 35, 35, 35, 36, 36, 37, 37, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35,
+ 35, 35, 36, 36, 37, 37, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33,
+ 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 36, 36,
+ 37, 37, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33,
+ 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 36, 36, 37, 37, 32, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34,
+ 34, 35, 35, 36, 36, 36, 36, 36, 36, 37, 38, 38, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 33, 33, 33, 33, 33, 34, 34, 35, 35, 35, 35, 35, 35, 36, 36,
+ 37, 37, 37, 37, 38, 38, 39, 39],
+ /* Size 4x16 */
+ [31, 31, 32, 32, 31, 32, 32, 32, 31, 32, 32, 32, 31, 32, 32, 32, 31, 32,
+ 32, 32, 32, 32, 32, 33, 32, 32, 32, 33, 32, 32, 33, 33, 32, 32, 33, 34,
+ 32, 32, 33, 34, 32, 32, 33, 34, 32, 32, 34, 35, 32, 33, 34, 35, 32, 33,
+ 34, 35, 33, 33, 35, 36, 34, 34, 36, 37],
+ /* Size 16x4 */
+ [31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 32, 32, 32, 32,
+ 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 35, 36, 32, 32, 32, 32, 32, 33,
+ 33, 33, 34, 34, 34, 35, 35, 35, 36, 37],
+ /* Size 8x32 */
+ [32, 31, 31, 31, 31, 32, 32, 32, 31, 31, 31, 31, 32, 32, 32, 33, 31, 31,
+ 32, 32, 32, 32, 32, 33, 31, 32, 32, 32, 32, 32, 32, 33, 31, 32, 32, 32,
+ 32, 32, 32, 33, 31, 32, 32, 32, 32, 32, 32, 33, 31, 32, 32, 32, 32, 32,
+ 32, 33, 31, 32, 32, 32, 32, 32, 32, 33, 31, 32, 32, 32, 32, 32, 32, 33,
+ 31, 32, 32, 32, 32, 32, 32, 33, 31, 32, 32, 32, 32, 33, 33, 33, 31, 32,
+ 32, 32, 32, 33, 33, 33, 31, 32, 32, 32, 32, 33, 33, 33, 31, 32, 32, 32,
+ 32, 33, 33, 33, 31, 32, 32, 32, 32, 33, 33, 33, 31, 32, 32, 32, 33, 33,
+ 33, 34, 31, 32, 32, 32, 33, 34, 34, 34, 32, 32, 32, 32, 33, 34, 34, 34,
+ 32, 32, 32, 32, 33, 34, 34, 34, 32, 32, 32, 32, 33, 34, 34, 34, 32, 32,
+ 32, 32, 33, 34, 34, 34, 32, 32, 32, 32, 33, 34, 34, 35, 32, 32, 32, 32,
+ 33, 35, 35, 35, 32, 32, 33, 33, 33, 35, 35, 36, 32, 32, 33, 33, 34, 35,
+ 35, 36, 32, 32, 33, 33, 34, 35, 35, 36, 32, 32, 33, 33, 34, 35, 35, 36,
+ 32, 32, 33, 33, 34, 35, 35, 36, 32, 33, 33, 33, 34, 36, 36, 36, 33, 33,
+ 33, 33, 34, 36, 36, 37, 34, 34, 34, 34, 35, 37, 37, 38, 34, 34, 34, 34,
+ 35, 37, 37, 38],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 31, 31, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33,
+ 33, 33, 33, 33, 34, 34, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33,
+ 34, 34, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 35, 35, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34,
+ 34, 34, 35, 35, 35, 35, 35, 35, 36, 36, 37, 37, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 35, 35,
+ 35, 35, 35, 35, 36, 36, 37, 37, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 35, 35, 36, 36, 36, 36, 36,
+ 36, 37, 38, 38]],
+ [ /* Chroma */
+ /* Size 4x4 */
+ [31, 31, 34, 38, 31, 32, 35, 40, 34, 35, 39, 43, 38, 40, 43, 47],
+ /* Size 8x8 */
+ [31, 31, 31, 30, 34, 35, 37, 40, 31, 31, 31, 31, 34, 35, 38, 41, 31, 31,
+ 31, 31, 35, 36, 39, 41, 30, 31, 31, 32, 35, 36, 40, 42, 34, 34, 35, 35,
+ 39, 40, 43, 44, 35, 35, 36, 36, 40, 41, 44, 45, 37, 38, 39, 40, 43, 44,
+ 47, 47, 40, 41, 41, 42, 44, 45, 47, 48],
+ /* Size 16x16 */
+ [32, 31, 31, 31, 31, 30, 30, 31, 33, 33, 33, 35, 36, 36, 38, 41, 31, 31,
+ 31, 31, 31, 31, 31, 31, 33, 34, 34, 36, 37, 37, 39, 42, 31, 31, 31, 31,
+ 31, 31, 31, 32, 34, 34, 34, 37, 38, 38, 40, 42, 31, 31, 31, 31, 31, 31,
+ 31, 32, 34, 34, 34, 37, 38, 38, 40, 42, 31, 31, 31, 31, 31, 31, 31, 32,
+ 34, 35, 35, 37, 39, 39, 40, 42, 30, 31, 31, 31, 31, 32, 32, 32, 34, 35,
+ 35, 38, 40, 40, 41, 42, 30, 31, 31, 31, 31, 32, 32, 32, 34, 35, 35, 38,
+ 40, 40, 41, 42, 31, 31, 32, 32, 32, 32, 32, 33, 35, 36, 36, 38, 40, 40,
+ 41, 43, 33, 33, 34, 34, 34, 34, 34, 35, 37, 38, 38, 41, 42, 42, 43, 44,
+ 33, 34, 34, 34, 35, 35, 35, 36, 38, 39, 39, 41, 43, 43, 44, 45, 33, 34,
+ 34, 34, 35, 35, 35, 36, 38, 39, 39, 41, 43, 43, 44, 45, 35, 36, 37, 37,
+ 37, 38, 38, 38, 41, 41, 41, 44, 46, 46, 46, 46, 36, 37, 38, 38, 39, 40,
+ 40, 40, 42, 43, 43, 46, 47, 47, 47, 47, 36, 37, 38, 38, 39, 40, 40, 40,
+ 42, 43, 43, 46, 47, 47, 47, 47, 38, 39, 40, 40, 40, 41, 41, 41, 43, 44,
+ 44, 46, 47, 47, 47, 48, 41, 42, 42, 42, 42, 42, 42, 43, 44, 45, 45, 46,
+ 47, 47, 48, 48],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 31, 32, 33, 33,
+ 33, 33, 33, 34, 35, 36, 36, 36, 36, 37, 38, 40, 41, 41, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 31, 32, 33, 34, 34, 34, 34, 35,
+ 36, 37, 37, 37, 37, 37, 39, 40, 42, 42, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 34, 34, 34, 35, 36, 37, 37, 37,
+ 37, 38, 39, 40, 42, 42, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 32, 32, 34, 34, 34, 34, 34, 35, 36, 38, 38, 38, 38, 38, 40, 41,
+ 42, 42, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33,
+ 34, 34, 34, 34, 34, 35, 37, 38, 38, 38, 38, 39, 40, 41, 42, 42, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 34, 34, 34,
+ 34, 35, 37, 38, 38, 38, 38, 39, 40, 41, 42, 42, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 34, 34, 34, 34, 35, 37, 38,
+ 38, 38, 38, 39, 40, 41, 42, 42, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 32, 33, 34, 34, 34, 34, 34, 36, 37, 38, 38, 38, 38, 39,
+ 40, 41, 42, 42, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 32, 33, 34, 35, 35, 35, 35, 36, 37, 38, 39, 39, 39, 39, 40, 41, 42, 42,
+ 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 35,
+ 35, 35, 35, 36, 37, 39, 39, 39, 39, 40, 40, 41, 42, 42, 30, 30, 31, 31,
+ 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 33, 34, 35, 35, 35, 35, 36,
+ 38, 39, 40, 40, 40, 40, 41, 42, 42, 42, 30, 30, 31, 31, 31, 31, 31, 31,
+ 31, 31, 32, 32, 32, 32, 32, 33, 34, 35, 35, 35, 35, 36, 38, 39, 40, 40,
+ 40, 40, 41, 42, 42, 42, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32,
+ 32, 32, 32, 33, 34, 35, 35, 35, 35, 36, 38, 39, 40, 40, 40, 40, 41, 42,
+ 42, 42, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 33,
+ 34, 35, 35, 35, 35, 36, 38, 39, 40, 40, 40, 40, 41, 42, 42, 42, 31, 31,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 36, 36,
+ 36, 37, 38, 40, 40, 40, 40, 41, 41, 42, 43, 43, 32, 32, 32, 32, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 34, 35, 36, 37, 37, 37, 37, 38, 39, 41,
+ 41, 41, 41, 42, 42, 43, 43, 43, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 35, 36, 37, 38, 38, 38, 38, 39, 41, 42, 42, 42, 42, 43,
+ 43, 44, 44, 44, 33, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35,
+ 36, 37, 38, 39, 39, 39, 39, 40, 41, 43, 43, 43, 43, 43, 44, 44, 45, 45,
+ 33, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 36, 37, 38, 39,
+ 39, 39, 39, 40, 41, 43, 43, 43, 43, 43, 44, 44, 45, 45, 33, 34, 34, 34,
+ 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 36, 37, 38, 39, 39, 39, 39, 40,
+ 41, 43, 43, 43, 43, 43, 44, 44, 45, 45, 33, 34, 34, 34, 34, 34, 34, 34,
+ 35, 35, 35, 35, 35, 35, 36, 37, 38, 39, 39, 39, 39, 40, 41, 43, 43, 43,
+ 43, 43, 44, 44, 45, 45, 34, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36,
+ 36, 36, 37, 38, 39, 40, 40, 40, 40, 41, 42, 44, 44, 44, 44, 44, 45, 45,
+ 45, 45, 35, 36, 36, 36, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 39,
+ 41, 41, 41, 41, 41, 42, 44, 45, 46, 46, 46, 46, 46, 46, 46, 46, 36, 37,
+ 37, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 40, 41, 42, 43, 43, 43,
+ 43, 44, 45, 46, 47, 47, 47, 47, 47, 47, 47, 47, 36, 37, 37, 38, 38, 38,
+ 38, 38, 39, 39, 40, 40, 40, 40, 40, 41, 42, 43, 43, 43, 43, 44, 46, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 36, 37, 37, 38, 38, 38, 38, 38, 39, 39,
+ 40, 40, 40, 40, 40, 41, 42, 43, 43, 43, 43, 44, 46, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 36, 37, 37, 38, 38, 38, 38, 38, 39, 39, 40, 40, 40, 40,
+ 40, 41, 42, 43, 43, 43, 43, 44, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 37, 37, 38, 38, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 41, 42, 43, 43,
+ 43, 43, 43, 44, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 38, 39, 39, 40,
+ 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 42, 43, 44, 44, 44, 44, 45,
+ 46, 47, 47, 47, 47, 47, 47, 48, 48, 48, 40, 40, 40, 41, 41, 41, 41, 41,
+ 41, 41, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 46, 47, 47, 47,
+ 47, 47, 48, 48, 48, 48, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 43, 43, 44, 45, 45, 45, 45, 45, 46, 47, 47, 47, 47, 47, 48, 48,
+ 48, 48, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43,
+ 44, 45, 45, 45, 45, 45, 46, 47, 47, 47, 47, 47, 48, 48, 48, 48],
+ /* Size 4x8 */
+ [31, 31, 35, 37, 31, 31, 36, 38, 31, 32, 37, 39, 31, 32, 37, 40, 34, 36,
+ 40, 43, 35, 37, 42, 44, 38, 40, 45, 47, 41, 42, 45, 47],
+ /* Size 8x4 */
+ [31, 31, 31, 31, 34, 35, 38, 41, 31, 31, 32, 32, 36, 37, 40, 42, 35, 36,
+ 37, 37, 40, 42, 45, 45, 37, 38, 39, 40, 43, 44, 47, 47],
+ /* Size 8x16 */
+ [32, 31, 31, 31, 33, 37, 37, 38, 31, 31, 31, 31, 33, 38, 38, 39, 31, 31,
+ 31, 31, 34, 38, 38, 40, 31, 31, 31, 31, 34, 38, 38, 40, 31, 31, 32, 32,
+ 34, 39, 39, 40, 30, 31, 32, 32, 35, 40, 40, 41, 30, 31, 32, 32, 35, 40,
+ 40, 41, 31, 32, 33, 33, 35, 40, 40, 41, 33, 34, 35, 35, 37, 42, 42, 43,
+ 33, 35, 36, 36, 38, 43, 43, 44, 33, 35, 36, 36, 38, 43, 43, 44, 35, 37,
+ 38, 38, 41, 45, 45, 46, 37, 39, 40, 40, 43, 47, 47, 47, 37, 39, 40, 40,
+ 43, 47, 47, 47, 39, 40, 41, 41, 43, 47, 47, 47, 42, 42, 43, 43, 44, 47,
+ 47, 48],
+ /* Size 16x8 */
+ [32, 31, 31, 31, 31, 30, 30, 31, 33, 33, 33, 35, 37, 37, 39, 42, 31, 31,
+ 31, 31, 31, 31, 31, 32, 34, 35, 35, 37, 39, 39, 40, 42, 31, 31, 31, 31,
+ 32, 32, 32, 33, 35, 36, 36, 38, 40, 40, 41, 43, 31, 31, 31, 31, 32, 32,
+ 32, 33, 35, 36, 36, 38, 40, 40, 41, 43, 33, 33, 34, 34, 34, 35, 35, 35,
+ 37, 38, 38, 41, 43, 43, 43, 44, 37, 38, 38, 38, 39, 40, 40, 40, 42, 43,
+ 43, 45, 47, 47, 47, 47, 37, 38, 38, 38, 39, 40, 40, 40, 42, 43, 43, 45,
+ 47, 47, 47, 47, 38, 39, 40, 40, 40, 41, 41, 41, 43, 44, 44, 46, 47, 47,
+ 47, 48],
+ /* Size 16x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 33, 35, 37, 37, 37, 37, 38, 42, 31, 31,
+ 31, 31, 31, 31, 31, 31, 33, 35, 37, 37, 37, 37, 39, 42, 31, 31, 31, 31,
+ 31, 31, 31, 32, 33, 35, 38, 38, 38, 38, 39, 42, 31, 31, 31, 31, 31, 31,
+ 31, 32, 34, 36, 38, 38, 38, 38, 40, 42, 31, 31, 31, 31, 31, 31, 31, 32,
+ 34, 36, 38, 38, 38, 38, 40, 42, 31, 31, 31, 31, 31, 31, 31, 32, 34, 36,
+ 38, 38, 38, 38, 40, 42, 31, 31, 31, 31, 31, 31, 31, 32, 34, 36, 38, 38,
+ 38, 38, 40, 42, 31, 31, 31, 31, 31, 31, 31, 32, 34, 36, 38, 38, 38, 38,
+ 40, 42, 31, 31, 31, 31, 32, 32, 32, 32, 34, 36, 39, 39, 39, 39, 40, 42,
+ 30, 31, 31, 32, 32, 32, 32, 32, 34, 37, 39, 39, 39, 39, 40, 42, 30, 31,
+ 31, 32, 32, 32, 32, 33, 35, 37, 40, 40, 40, 40, 41, 42, 30, 31, 31, 32,
+ 32, 32, 32, 33, 35, 37, 40, 40, 40, 40, 41, 42, 30, 31, 31, 32, 32, 32,
+ 32, 33, 35, 37, 40, 40, 40, 40, 41, 42, 30, 31, 31, 32, 32, 32, 32, 33,
+ 35, 37, 40, 40, 40, 40, 41, 42, 31, 31, 32, 32, 33, 33, 33, 33, 35, 38,
+ 40, 40, 40, 40, 41, 43, 32, 32, 33, 33, 34, 34, 34, 34, 36, 39, 41, 41,
+ 41, 41, 42, 44, 33, 33, 34, 35, 35, 35, 35, 35, 37, 40, 42, 42, 42, 42,
+ 43, 44, 33, 34, 35, 35, 36, 36, 36, 36, 38, 40, 43, 43, 43, 43, 44, 45,
+ 33, 34, 35, 35, 36, 36, 36, 36, 38, 40, 43, 43, 43, 43, 44, 45, 33, 34,
+ 35, 35, 36, 36, 36, 36, 38, 40, 43, 43, 43, 43, 44, 45, 33, 34, 35, 35,
+ 36, 36, 36, 36, 38, 40, 43, 43, 43, 43, 44, 45, 34, 35, 36, 37, 37, 37,
+ 37, 37, 39, 42, 44, 44, 44, 44, 45, 45, 35, 36, 37, 38, 38, 38, 38, 39,
+ 41, 43, 45, 45, 45, 45, 46, 46, 36, 37, 38, 39, 39, 39, 39, 40, 42, 44,
+ 47, 47, 47, 47, 47, 47, 37, 38, 39, 40, 40, 40, 40, 41, 43, 45, 47, 47,
+ 47, 47, 47, 47, 37, 38, 39, 40, 40, 40, 40, 41, 43, 45, 47, 47, 47, 47,
+ 47, 47, 37, 38, 39, 40, 40, 40, 40, 41, 43, 45, 47, 47, 47, 47, 47, 47,
+ 37, 38, 39, 40, 40, 40, 40, 41, 43, 45, 47, 47, 47, 47, 47, 47, 39, 39,
+ 40, 41, 41, 41, 41, 42, 43, 45, 47, 47, 47, 47, 47, 48, 40, 41, 41, 42,
+ 42, 42, 42, 42, 44, 45, 47, 47, 47, 47, 47, 48, 42, 42, 42, 43, 43, 43,
+ 43, 43, 44, 46, 47, 47, 47, 47, 48, 48, 42, 42, 42, 43, 43, 43, 43, 43,
+ 44, 46, 47, 47, 47, 47, 48, 48],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 31, 32, 33, 33,
+ 33, 33, 33, 34, 35, 36, 37, 37, 37, 37, 39, 40, 42, 42, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 34, 34, 34, 35,
+ 36, 37, 38, 38, 38, 38, 39, 41, 42, 42, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 32, 33, 34, 35, 35, 35, 35, 36, 37, 38, 39, 39,
+ 39, 39, 40, 41, 42, 42, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32,
+ 32, 32, 32, 33, 35, 35, 35, 35, 35, 37, 38, 39, 40, 40, 40, 40, 41, 42,
+ 43, 43, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 33, 34,
+ 35, 36, 36, 36, 36, 37, 38, 39, 40, 40, 40, 40, 41, 42, 43, 43, 31, 31,
+ 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 36, 36,
+ 36, 37, 38, 39, 40, 40, 40, 40, 41, 42, 43, 43, 31, 31, 31, 31, 31, 31,
+ 31, 31, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 36, 36, 36, 37, 38, 39,
+ 40, 40, 40, 40, 41, 42, 43, 43, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 33, 33, 33, 33, 33, 34, 35, 36, 36, 36, 36, 37, 39, 40, 41, 41, 41, 41,
+ 42, 42, 43, 43, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35,
+ 35, 36, 37, 38, 38, 38, 38, 39, 41, 42, 43, 43, 43, 43, 43, 44, 44, 44,
+ 35, 35, 35, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 38, 39, 40, 40,
+ 40, 40, 40, 42, 43, 44, 45, 45, 45, 45, 45, 45, 46, 46, 37, 37, 38, 38,
+ 38, 38, 38, 38, 39, 39, 40, 40, 40, 40, 40, 41, 42, 43, 43, 43, 43, 44,
+ 45, 47, 47, 47, 47, 47, 47, 47, 47, 47, 37, 37, 38, 38, 38, 38, 38, 38,
+ 39, 39, 40, 40, 40, 40, 40, 41, 42, 43, 43, 43, 43, 44, 45, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 37, 37, 38, 38, 38, 38, 38, 38, 39, 39, 40, 40,
+ 40, 40, 40, 41, 42, 43, 43, 43, 43, 44, 45, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 37, 37, 38, 38, 38, 38, 38, 38, 39, 39, 40, 40, 40, 40, 40, 41,
+ 42, 43, 43, 43, 43, 44, 45, 47, 47, 47, 47, 47, 47, 47, 47, 47, 38, 39,
+ 39, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 42, 43, 44, 44, 44,
+ 44, 45, 46, 47, 47, 47, 47, 47, 47, 47, 48, 48, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 45, 45, 45, 45, 45, 46, 47,
+ 47, 47, 47, 47, 48, 48, 48, 48],
+ /* Size 4x16 */
+ [31, 31, 35, 37, 31, 31, 35, 38, 31, 31, 36, 38, 31, 31, 36, 38, 31, 32,
+ 36, 39, 31, 32, 37, 40, 31, 32, 37, 40, 31, 33, 38, 40, 33, 35, 40, 42,
+ 34, 36, 40, 43, 34, 36, 40, 43, 36, 38, 43, 45, 38, 40, 45, 47, 38, 40,
+ 45, 47, 39, 41, 45, 47, 42, 43, 46, 47],
+ /* Size 16x4 */
+ [31, 31, 31, 31, 31, 31, 31, 31, 33, 34, 34, 36, 38, 38, 39, 42, 31, 31,
+ 31, 31, 32, 32, 32, 33, 35, 36, 36, 38, 40, 40, 41, 43, 35, 35, 36, 36,
+ 36, 37, 37, 38, 40, 40, 40, 43, 45, 45, 45, 46, 37, 38, 38, 38, 39, 40,
+ 40, 40, 42, 43, 43, 45, 47, 47, 47, 47],
+ /* Size 8x32 */
+ [32, 31, 31, 31, 33, 37, 37, 38, 31, 31, 31, 31, 33, 37, 37, 39, 31, 31,
+ 31, 31, 33, 38, 38, 39, 31, 31, 31, 31, 34, 38, 38, 40, 31, 31, 31, 31,
+ 34, 38, 38, 40, 31, 31, 31, 31, 34, 38, 38, 40, 31, 31, 31, 31, 34, 38,
+ 38, 40, 31, 31, 31, 31, 34, 38, 38, 40, 31, 31, 32, 32, 34, 39, 39, 40,
+ 30, 31, 32, 32, 34, 39, 39, 40, 30, 31, 32, 32, 35, 40, 40, 41, 30, 31,
+ 32, 32, 35, 40, 40, 41, 30, 31, 32, 32, 35, 40, 40, 41, 30, 31, 32, 32,
+ 35, 40, 40, 41, 31, 32, 33, 33, 35, 40, 40, 41, 32, 33, 34, 34, 36, 41,
+ 41, 42, 33, 34, 35, 35, 37, 42, 42, 43, 33, 35, 36, 36, 38, 43, 43, 44,
+ 33, 35, 36, 36, 38, 43, 43, 44, 33, 35, 36, 36, 38, 43, 43, 44, 33, 35,
+ 36, 36, 38, 43, 43, 44, 34, 36, 37, 37, 39, 44, 44, 45, 35, 37, 38, 38,
+ 41, 45, 45, 46, 36, 38, 39, 39, 42, 47, 47, 47, 37, 39, 40, 40, 43, 47,
+ 47, 47, 37, 39, 40, 40, 43, 47, 47, 47, 37, 39, 40, 40, 43, 47, 47, 47,
+ 37, 39, 40, 40, 43, 47, 47, 47, 39, 40, 41, 41, 43, 47, 47, 47, 40, 41,
+ 42, 42, 44, 47, 47, 47, 42, 42, 43, 43, 44, 47, 47, 48, 42, 42, 43, 43,
+ 44, 47, 47, 48],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 31, 32, 33, 33,
+ 33, 33, 33, 34, 35, 36, 37, 37, 37, 37, 39, 40, 42, 42, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 35, 35, 35, 35, 36,
+ 37, 38, 39, 39, 39, 39, 40, 41, 42, 42, 31, 31, 31, 31, 31, 31, 31, 31,
+ 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 36, 36, 36, 37, 38, 39, 40, 40,
+ 40, 40, 41, 42, 43, 43, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32,
+ 32, 32, 33, 34, 35, 36, 36, 36, 36, 37, 38, 39, 40, 40, 40, 40, 41, 42,
+ 43, 43, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 36,
+ 37, 38, 38, 38, 38, 39, 41, 42, 43, 43, 43, 43, 43, 44, 44, 44, 37, 37,
+ 38, 38, 38, 38, 38, 38, 39, 39, 40, 40, 40, 40, 40, 41, 42, 43, 43, 43,
+ 43, 44, 45, 47, 47, 47, 47, 47, 47, 47, 47, 47, 37, 37, 38, 38, 38, 38,
+ 38, 38, 39, 39, 40, 40, 40, 40, 40, 41, 42, 43, 43, 43, 43, 44, 45, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 38, 39, 39, 40, 40, 40, 40, 40, 40, 40,
+ 41, 41, 41, 41, 41, 42, 43, 44, 44, 44, 44, 45, 46, 47, 47, 47, 47, 47,
+ 47, 47, 48, 48]]
+ ],
+ [
+ [ /* Luma */
+ /* Size 4x4 */
+ [31, 31, 31, 32, 31, 32, 32, 32, 31, 32, 32, 32, 32, 32, 32, 33],
+ /* Size 8x8 */
+ [31, 31, 31, 31, 31, 31, 32, 32, 31, 32, 32, 32, 32, 32, 32, 32, 31, 32,
+ 32, 32, 32, 32, 32, 32, 31, 32, 32, 32, 32, 32, 32, 32, 31, 32, 32, 32,
+ 32, 32, 32, 32, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 33, 33, 32, 32, 32, 32, 32, 32, 33, 33],
+ /* Size 16x16 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 31, 31, 31, 31,
+ 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 33, 33, 33, 33, 33, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 33, 33, 33, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33,
+ 33, 33, 33, 33],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31,
+ 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31,
+ 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33],
+ /* Size 4x8 */
+ [31, 31, 31, 32, 31, 32, 32, 32, 31, 32, 32, 32, 31, 32, 32, 32, 31, 32,
+ 32, 32, 31, 32, 32, 33, 32, 32, 32, 33, 32, 32, 32, 33],
+ /* Size 8x4 */
+ [31, 31, 31, 31, 31, 31, 32, 32, 31, 32, 32, 32, 32, 32, 32, 32, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33],
+ /* Size 8x16 */
+ [32, 31, 31, 31, 31, 31, 31, 32, 31, 31, 31, 31, 31, 31, 32, 32, 31, 31,
+ 32, 32, 32, 32, 32, 32, 31, 32, 32, 32, 32, 32, 32, 32, 31, 32, 32, 32,
+ 32, 32, 32, 32, 31, 32, 32, 32, 32, 32, 32, 32, 31, 32, 32, 32, 32, 32,
+ 32, 32, 31, 32, 32, 32, 32, 32, 32, 32, 31, 32, 32, 32, 32, 32, 32, 32,
+ 31, 32, 32, 32, 32, 32, 32, 32, 31, 32, 32, 32, 32, 32, 32, 32, 31, 32,
+ 32, 32, 32, 32, 33, 33, 31, 32, 32, 32, 32, 32, 33, 33, 32, 32, 32, 32,
+ 32, 32, 33, 34, 32, 32, 32, 32, 32, 32, 33, 34, 32, 32, 32, 32, 32, 32,
+ 33, 34],
+ /* Size 16x8 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 31, 31,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33,
+ 33, 33, 33, 33, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34,
+ 34, 34],
+ /* Size 16x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 33, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33,
+ 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 33, 33, 33, 33, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 33, 33, 33, 33, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33,
+ 33, 33, 33, 34, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33,
+ 34, 34, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 33, 33, 34, 34, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 33, 33, 33, 34, 34],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33,
+ 33, 33, 33, 33, 33, 33, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 34, 34, 34, 34, 34, 34, 34, 34],
+ /* Size 4x16 */
+ [31, 31, 31, 32, 31, 31, 31, 32, 31, 32, 32, 32, 31, 32, 32, 32, 31, 32,
+ 32, 32, 31, 32, 32, 32, 31, 32, 32, 32, 31, 32, 32, 32, 31, 32, 32, 32,
+ 31, 32, 32, 32, 31, 32, 32, 32, 32, 32, 32, 33, 32, 32, 32, 33, 32, 32,
+ 32, 33, 32, 32, 32, 33, 32, 32, 32, 33],
+ /* Size 16x4 */
+ [31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 33, 33, 33, 33],
+ /* Size 8x32 */
+ [32, 31, 31, 31, 31, 31, 31, 32, 31, 31, 31, 31, 31, 31, 32, 32, 31, 31,
+ 31, 31, 31, 31, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32,
+ 32, 32, 32, 32, 31, 32, 32, 32, 32, 32, 32, 32, 31, 32, 32, 32, 32, 32,
+ 32, 32, 31, 32, 32, 32, 32, 32, 32, 32, 31, 32, 32, 32, 32, 32, 32, 32,
+ 31, 32, 32, 32, 32, 32, 32, 32, 31, 32, 32, 32, 32, 32, 32, 32, 31, 32,
+ 32, 32, 32, 32, 32, 32, 31, 32, 32, 32, 32, 32, 32, 32, 31, 32, 32, 32,
+ 32, 32, 32, 32, 31, 32, 32, 32, 32, 32, 32, 32, 31, 32, 32, 32, 32, 32,
+ 32, 32, 31, 32, 32, 32, 32, 32, 32, 32, 31, 32, 32, 32, 32, 32, 32, 32,
+ 31, 32, 32, 32, 32, 32, 32, 32, 31, 32, 32, 32, 32, 32, 32, 32, 31, 32,
+ 32, 32, 32, 32, 32, 32, 31, 32, 32, 32, 32, 32, 32, 33, 31, 32, 32, 32,
+ 32, 32, 33, 33, 31, 32, 32, 32, 32, 32, 33, 33, 31, 32, 32, 32, 32, 32,
+ 33, 33, 32, 32, 32, 32, 32, 32, 33, 34, 32, 32, 32, 32, 32, 32, 33, 34,
+ 32, 32, 32, 32, 32, 32, 33, 34, 32, 32, 32, 32, 32, 32, 33, 34, 32, 32,
+ 32, 32, 32, 32, 33, 34, 32, 32, 32, 32, 32, 32, 33, 34, 32, 32, 32, 32,
+ 32, 32, 33, 34],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34,
+ 34, 34, 34, 34]],
+ [ /* Chroma */
+ /* Size 4x4 */
+ [31, 31, 31, 34, 31, 31, 31, 35, 31, 31, 32, 35, 34, 35, 35, 39],
+ /* Size 8x8 */
+ [31, 31, 31, 31, 30, 31, 33, 33, 31, 31, 31, 31, 31, 32, 34, 34, 31, 31,
+ 31, 31, 31, 32, 34, 34, 31, 31, 31, 31, 31, 32, 35, 35, 30, 31, 31, 31,
+ 32, 32, 35, 35, 31, 32, 32, 32, 32, 33, 36, 36, 33, 34, 34, 35, 35, 36,
+ 39, 39, 33, 34, 34, 35, 35, 36, 39, 39],
+ /* Size 16x16 */
+ [32, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 31, 33, 33, 33, 33, 31, 31,
+ 31, 31, 31, 31, 31, 31, 30, 30, 30, 32, 33, 34, 34, 34, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 34, 34, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 32, 34, 34, 34, 34, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 32, 34, 34, 34, 34, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 32, 34, 34, 34, 34, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 33,
+ 34, 35, 35, 35, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 33, 34, 35,
+ 35, 35, 30, 30, 31, 31, 31, 31, 31, 31, 32, 32, 32, 33, 34, 35, 35, 35,
+ 30, 30, 31, 31, 31, 31, 31, 31, 32, 32, 32, 33, 34, 35, 35, 35, 30, 30,
+ 31, 31, 31, 31, 31, 31, 32, 32, 32, 33, 34, 35, 35, 35, 31, 32, 32, 32,
+ 32, 32, 33, 33, 33, 33, 33, 34, 36, 37, 37, 37, 33, 33, 33, 34, 34, 34,
+ 34, 34, 34, 34, 34, 36, 37, 38, 38, 38, 33, 34, 34, 34, 34, 34, 35, 35,
+ 35, 35, 35, 37, 38, 39, 39, 39, 33, 34, 34, 34, 34, 34, 35, 35, 35, 35,
+ 35, 37, 38, 39, 39, 39, 33, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 37,
+ 38, 39, 39, 39],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30,
+ 30, 30, 30, 31, 31, 32, 33, 33, 33, 33, 33, 33, 33, 34, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 30, 30, 31,
+ 31, 32, 33, 33, 33, 33, 33, 33, 33, 34, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 30, 31, 32, 32, 33, 34,
+ 34, 34, 34, 34, 34, 34, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 33, 34, 34, 34, 34, 34,
+ 34, 35, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 32, 33, 33, 34, 34, 34, 34, 34, 34, 35, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 32, 32, 33, 34, 34, 34, 34, 34, 34, 34, 35, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 33,
+ 34, 34, 34, 34, 34, 34, 34, 35, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 33, 34, 34, 34, 34,
+ 34, 34, 34, 35, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 32, 32, 33, 34, 34, 34, 34, 34, 34, 34, 35,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 32, 32, 33, 34, 34, 34, 34, 34, 34, 34, 35, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32,
+ 32, 33, 34, 34, 34, 34, 34, 34, 34, 35, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 33, 34, 35,
+ 35, 35, 35, 35, 35, 35, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 33, 34, 35, 35, 35, 35, 35,
+ 35, 35, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 32, 33, 33, 34, 35, 35, 35, 35, 35, 35, 36, 30, 30,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 32, 33, 34, 34, 35, 35, 35, 35, 35, 35, 36, 30, 30, 30, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 33, 34,
+ 34, 35, 35, 35, 35, 35, 35, 36, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 35, 35, 35,
+ 35, 35, 35, 36, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 35, 35, 35, 35, 35, 35, 36,
+ 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32,
+ 32, 32, 32, 32, 33, 34, 34, 35, 35, 35, 35, 35, 35, 36, 30, 30, 30, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32,
+ 33, 34, 34, 35, 35, 35, 35, 35, 35, 36, 30, 30, 30, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 35,
+ 35, 35, 35, 35, 35, 36, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 35, 36, 36, 36, 36, 36,
+ 36, 37, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 34, 34, 35, 36, 37, 37, 37, 37, 37, 37, 37, 32, 32,
+ 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34,
+ 34, 34, 35, 36, 37, 37, 37, 37, 37, 37, 37, 38, 33, 33, 33, 33, 33, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 36, 37,
+ 37, 38, 38, 38, 38, 38, 38, 39, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 37, 37, 38, 39, 39, 39,
+ 39, 39, 39, 40, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 36, 37, 37, 38, 39, 39, 39, 39, 39, 39, 40,
+ 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 36, 37, 37, 38, 39, 39, 39, 39, 39, 39, 40, 33, 33, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36,
+ 37, 37, 38, 39, 39, 39, 39, 39, 39, 40, 33, 33, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 37, 37, 38, 39,
+ 39, 39, 39, 39, 39, 40, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 37, 37, 38, 39, 39, 39, 39, 39,
+ 39, 40, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 36, 36,
+ 36, 36, 36, 36, 36, 37, 37, 38, 39, 40, 40, 40, 40, 40, 40, 40],
+ /* Size 4x8 */
+ [31, 31, 31, 34, 31, 31, 31, 35, 31, 31, 31, 35, 31, 32, 32, 36, 31, 32,
+ 32, 36, 31, 33, 33, 37, 34, 36, 36, 40, 34, 36, 36, 40],
+ /* Size 8x4 */
+ [31, 31, 31, 31, 31, 31, 34, 34, 31, 31, 31, 32, 32, 33, 36, 36, 31, 31,
+ 31, 32, 32, 33, 36, 36, 34, 35, 35, 36, 36, 37, 40, 40],
+ /* Size 8x16 */
+ [32, 31, 31, 31, 31, 31, 33, 35, 31, 31, 31, 31, 31, 31, 33, 36, 31, 31,
+ 31, 31, 31, 31, 34, 36, 31, 31, 31, 31, 31, 31, 34, 37, 31, 31, 31, 31,
+ 31, 31, 34, 37, 31, 31, 31, 31, 31, 31, 34, 37, 31, 31, 31, 32, 32, 32,
+ 34, 37, 30, 31, 31, 32, 32, 32, 34, 38, 30, 31, 32, 32, 32, 32, 35, 38,
+ 30, 31, 32, 32, 32, 32, 35, 38, 30, 31, 32, 32, 32, 32, 35, 38, 31, 32,
+ 33, 33, 33, 33, 36, 39, 33, 34, 34, 35, 35, 35, 37, 40, 33, 34, 35, 36,
+ 36, 36, 38, 41, 33, 34, 35, 36, 36, 36, 38, 41, 33, 34, 35, 36, 36, 36,
+ 38, 41],
+ /* Size 16x8 */
+ [32, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 31, 33, 33, 33, 33, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 34, 34, 34, 34, 31, 31, 31, 31,
+ 31, 31, 31, 31, 32, 32, 32, 33, 34, 35, 35, 35, 31, 31, 31, 31, 31, 31,
+ 32, 32, 32, 32, 32, 33, 35, 36, 36, 36, 31, 31, 31, 31, 31, 31, 32, 32,
+ 32, 32, 32, 33, 35, 36, 36, 36, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32,
+ 32, 33, 35, 36, 36, 36, 33, 33, 34, 34, 34, 34, 34, 34, 35, 35, 35, 36,
+ 37, 38, 38, 38, 35, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 40, 41,
+ 41, 41],
+ /* Size 16x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 35, 37, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 35, 37, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 36, 37, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 32, 33, 35, 36, 38, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 32, 34, 35, 36, 38, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 33, 34, 35, 37, 38, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 33,
+ 34, 35, 37, 38, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 33, 34, 35,
+ 37, 38, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 33, 34, 35, 37, 38,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 33, 34, 35, 37, 38, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 33, 34, 35, 37, 38, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 33, 34, 35, 37, 38, 31, 31, 31, 31, 31, 32,
+ 32, 32, 32, 32, 32, 33, 34, 36, 37, 39, 31, 31, 31, 31, 31, 32, 32, 32,
+ 32, 32, 32, 33, 34, 36, 37, 39, 30, 31, 31, 31, 31, 32, 32, 32, 32, 32,
+ 32, 33, 34, 36, 38, 39, 30, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 33,
+ 35, 36, 38, 40, 30, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 33, 35, 36,
+ 38, 40, 30, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 33, 35, 36, 38, 40,
+ 30, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 33, 35, 36, 38, 40, 30, 31,
+ 31, 31, 32, 32, 32, 32, 32, 32, 32, 33, 35, 36, 38, 40, 30, 31, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 33, 35, 36, 38, 40, 31, 31, 31, 32, 32, 33,
+ 33, 33, 33, 33, 33, 34, 35, 37, 38, 40, 31, 32, 32, 33, 33, 33, 33, 33,
+ 33, 33, 33, 35, 36, 37, 39, 41, 32, 32, 33, 33, 34, 34, 34, 34, 34, 34,
+ 34, 35, 37, 38, 40, 41, 33, 33, 34, 34, 34, 35, 35, 35, 35, 35, 35, 36,
+ 37, 39, 40, 42, 33, 34, 34, 35, 35, 36, 36, 36, 36, 36, 36, 37, 38, 40,
+ 41, 43, 33, 34, 34, 35, 35, 36, 36, 36, 36, 36, 36, 37, 38, 40, 41, 43,
+ 33, 34, 34, 35, 35, 36, 36, 36, 36, 36, 36, 37, 38, 40, 41, 43, 33, 34,
+ 34, 35, 35, 36, 36, 36, 36, 36, 36, 37, 38, 40, 41, 43, 33, 34, 34, 35,
+ 35, 36, 36, 36, 36, 36, 36, 37, 38, 40, 41, 43, 33, 34, 34, 35, 35, 36,
+ 36, 36, 36, 36, 36, 37, 38, 40, 41, 43, 34, 34, 35, 35, 36, 36, 36, 36,
+ 36, 36, 36, 38, 39, 40, 42, 44],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30,
+ 30, 30, 30, 31, 31, 32, 33, 33, 33, 33, 33, 33, 33, 34, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 32, 32, 33, 34, 34, 34, 34, 34, 34, 34, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 34,
+ 34, 34, 34, 34, 34, 35, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 33, 34, 35, 35, 35, 35, 35,
+ 35, 35, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32,
+ 32, 32, 32, 32, 32, 32, 33, 34, 34, 35, 35, 35, 35, 35, 35, 36, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 34, 35, 36, 36, 36, 36, 36, 36, 36, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34,
+ 35, 36, 36, 36, 36, 36, 36, 36, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34, 35, 36, 36, 36,
+ 36, 36, 36, 36, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 33, 33, 34, 35, 36, 36, 36, 36, 36, 36, 36,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 33, 33, 34, 35, 36, 36, 36, 36, 36, 36, 36, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33,
+ 33, 34, 35, 36, 36, 36, 36, 36, 36, 36, 32, 32, 32, 32, 32, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 35, 35, 36, 37,
+ 37, 37, 37, 37, 37, 38, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 36, 37, 37, 38, 38, 38, 38, 38,
+ 38, 39, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 37, 37, 38, 39, 40, 40, 40, 40, 40, 40, 40, 35, 35,
+ 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38,
+ 38, 38, 39, 40, 40, 41, 41, 41, 41, 41, 41, 42, 37, 37, 37, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, 41, 41,
+ 42, 43, 43, 43, 43, 43, 43, 44],
+ /* Size 4x16 */
+ [31, 31, 31, 34, 31, 31, 31, 34, 31, 31, 31, 35, 31, 31, 31, 35, 31, 31,
+ 31, 35, 31, 31, 31, 35, 31, 32, 32, 36, 31, 32, 32, 36, 31, 32, 32, 36,
+ 31, 32, 32, 36, 31, 32, 32, 36, 32, 33, 33, 37, 33, 35, 35, 39, 34, 36,
+ 36, 40, 34, 36, 36, 40, 34, 36, 36, 40],
+ /* Size 16x4 */
+ [31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 34, 34, 31, 31,
+ 31, 31, 31, 31, 32, 32, 32, 32, 32, 33, 35, 36, 36, 36, 31, 31, 31, 31,
+ 31, 31, 32, 32, 32, 32, 32, 33, 35, 36, 36, 36, 34, 34, 35, 35, 35, 35,
+ 36, 36, 36, 36, 36, 37, 39, 40, 40, 40],
+ /* Size 8x32 */
+ [32, 31, 31, 31, 31, 31, 33, 35, 31, 31, 31, 31, 31, 31, 33, 35, 31, 31,
+ 31, 31, 31, 31, 33, 36, 31, 31, 31, 31, 31, 31, 33, 36, 31, 31, 31, 31,
+ 31, 31, 34, 36, 31, 31, 31, 31, 31, 31, 34, 37, 31, 31, 31, 31, 31, 31,
+ 34, 37, 31, 31, 31, 31, 31, 31, 34, 37, 31, 31, 31, 31, 31, 31, 34, 37,
+ 31, 31, 31, 31, 31, 31, 34, 37, 31, 31, 31, 31, 31, 31, 34, 37, 31, 31,
+ 31, 31, 31, 31, 34, 37, 31, 31, 31, 32, 32, 32, 34, 37, 31, 31, 31, 32,
+ 32, 32, 34, 37, 30, 31, 31, 32, 32, 32, 34, 38, 30, 31, 32, 32, 32, 32,
+ 35, 38, 30, 31, 32, 32, 32, 32, 35, 38, 30, 31, 32, 32, 32, 32, 35, 38,
+ 30, 31, 32, 32, 32, 32, 35, 38, 30, 31, 32, 32, 32, 32, 35, 38, 30, 31,
+ 32, 32, 32, 32, 35, 38, 31, 31, 32, 33, 33, 33, 35, 38, 31, 32, 33, 33,
+ 33, 33, 36, 39, 32, 33, 34, 34, 34, 34, 37, 40, 33, 34, 34, 35, 35, 35,
+ 37, 40, 33, 34, 35, 36, 36, 36, 38, 41, 33, 34, 35, 36, 36, 36, 38, 41,
+ 33, 34, 35, 36, 36, 36, 38, 41, 33, 34, 35, 36, 36, 36, 38, 41, 33, 34,
+ 35, 36, 36, 36, 38, 41, 33, 34, 35, 36, 36, 36, 38, 41, 34, 35, 36, 36,
+ 36, 36, 39, 42],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30,
+ 30, 30, 30, 31, 31, 32, 33, 33, 33, 33, 33, 33, 33, 34, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 32, 33, 34, 34, 34, 34, 34, 34, 34, 35, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 33, 34, 34, 35,
+ 35, 35, 35, 35, 35, 36, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 34, 35, 36, 36, 36, 36, 36,
+ 36, 36, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 33, 33, 34, 35, 36, 36, 36, 36, 36, 36, 36, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 33, 33, 34, 35, 36, 36, 36, 36, 36, 36, 36, 33, 33, 33, 33, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 36, 37,
+ 37, 38, 38, 38, 38, 38, 38, 39, 35, 35, 36, 36, 36, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 39, 40, 40, 41, 41, 41,
+ 41, 41, 41, 42]],
+ ],
+ [
+ [ /* Luma */
+ /* Size 4x4 */
+ [31, 31, 31, 31, 31, 32, 32, 32, 31, 32, 32, 32, 31, 32, 32, 32],
+ /* Size 8x8 */
+ [31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32,
+ 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32,
+ 32, 32, 31, 31, 32, 32, 32, 32, 32, 32],
+ /* Size 16x16 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31,
+ 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32,
+ 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31,
+ 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31,
+ 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31,
+ 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 4x8 */
+ [31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 31, 32, 32, 32, 31, 32,
+ 32, 32, 31, 32, 32, 32, 31, 32, 32, 32, 31, 32, 32, 32],
+ /* Size 8x4 */
+ [31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31,
+ 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32],
+ /* Size 8x16 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 31, 31, 31, 32,
+ 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32,
+ 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32,
+ 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31,
+ 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32,
+ 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32,
+ 32, 32],
+ /* Size 16x8 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32],
+ /* Size 16x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31,
+ 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31,
+ 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32,
+ 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31,
+ 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31,
+ 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31,
+ 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 4x16 */
+ [31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 31, 32,
+ 32, 32, 31, 32, 32, 32, 31, 32, 32, 32, 31, 32, 32, 32, 31, 32, 32, 32,
+ 31, 32, 32, 32, 31, 32, 32, 32, 31, 32, 32, 32, 31, 32, 32, 32, 31, 32,
+ 32, 32, 31, 32, 32, 32, 31, 32, 32, 32],
+ /* Size 16x4 */
+ [31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 8x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32,
+ 32, 32, 31, 31, 31, 32, 32, 32, 32, 32, 31, 31, 31, 32, 32, 32, 32, 32,
+ 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31,
+ 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32,
+ 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32,
+ 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32,
+ 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31,
+ 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32,
+ 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32,
+ 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32,
+ 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31,
+ 32, 32, 32, 32, 32, 32, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 32, 32,
+ 32, 32, 32, 32],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31,
+ 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32]],
+ [ /* Chroma */
+ /* Size 4x4 */
+ [31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31],
+ /* Size 8x8 */
+ [31, 31, 31, 31, 31, 31, 31, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 30, 31, 31, 31, 31, 31, 31, 31],
+ /* Size 16x16 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 30, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 30, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 32],
+ /* Size 32x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 30, 30,
+ 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 32, 32, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32],
+ /* Size 4x8 */
+ [31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 30, 31, 32, 32],
+ /* Size 8x4 */
+ [31, 31, 31, 31, 31, 31, 31, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 32, 32, 31, 31, 31, 31, 31, 31, 32, 32],
+ /* Size 8x16 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 31, 31, 31, 31,
+ 31, 32, 32, 32, 30, 31, 31, 31, 31, 32, 32, 32, 30, 31, 31, 31, 32, 32,
+ 32, 32],
+ /* Size 16x8 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32,
+ 32, 32],
+ /* Size 16x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32,
+ 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32,
+ 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32,
+ 30, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 30, 31,
+ 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 30, 30, 31, 31,
+ 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 30, 30, 31, 31, 31, 31,
+ 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 30, 30, 31, 31, 31, 31, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 32x16 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 4x16 */
+ [31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 31, 31,
+ 32, 32, 31, 31, 32, 32, 30, 31, 32, 32],
+ /* Size 16x4 */
+ [31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 30, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 32, 32, 32, 32],
+ /* Size 8x32 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 31, 31, 31, 31, 31, 32,
+ 32, 32, 31, 31, 31, 31, 31, 32, 32, 32, 31, 31, 31, 31, 31, 32, 32, 32,
+ 30, 31, 31, 31, 31, 32, 32, 32, 30, 31, 31, 31, 31, 32, 32, 32, 30, 31,
+ 31, 31, 32, 32, 32, 32, 30, 31, 31, 31, 32, 32, 32, 32, 30, 31, 31, 31,
+ 32, 32, 32, 32],
+ /* Size 32x8 */
+ [32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32]]
+ ],
+ [
+ [ /* Luma */
+ /* Size 4x4 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 8x8 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 16x16 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32],
+ /* Size 32x32 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 4x8 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 8x4 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 8x16 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32],
+ /* Size 16x8 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32],
+ /* Size 16x32 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 32x16 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 4x16 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 16x4 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 8x32 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32],
+ /* Size 32x8 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32]],
+ [ /* Chroma */
+ /* Size 4x4 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 8x8 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 16x16 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32],
+ /* Size 32x32 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 4x8 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 8x4 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 8x16 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32],
+ /* Size 16x8 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32],
+ /* Size 16x32 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 32x16 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 4x16 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 16x4 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32],
+ /* Size 8x32 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32],
+ /* Size 32x8 */
+ [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32]]
+ ]
+ ];
+
+ public static ReadOnlySpan GetQuantizationMatrix(int level, Av1Plane plane, Av1TransformSize transformSize)
+
+ // Transform size must be adjusted.
+ => InverseWeightTable[level][Math.Min(1, (int)plane)][(int)transformSize];
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/Quantification/Av1InverseQuantizer.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/Quantification/Av1InverseQuantizer.cs
new file mode 100644
index 0000000000..8aa679dabd
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/Quantification/Av1InverseQuantizer.cs
@@ -0,0 +1,117 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.Quantification;
+
+internal class Av1InverseQuantizer
+{
+ private readonly ObuSequenceHeader sequenceHeader;
+ private readonly ObuFrameHeader frameHeader;
+ private Av1DeQuantizationContext deQuantsDeltaQ;
+
+ public Av1InverseQuantizer(ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader)
+ {
+ this.sequenceHeader = sequenceHeader;
+ this.frameHeader = frameHeader;
+ this.deQuantsDeltaQ = new(sequenceHeader, frameHeader);
+ }
+
+ public void UpdateDequant(Av1DeQuantizationContext deQuants, Av1SuperblockInfo superblockInfo)
+ {
+ Av1BitDepth bitDepth = this.sequenceHeader.ColorConfig.BitDepth;
+ Guard.NotNull(deQuants, nameof(deQuants));
+ this.deQuantsDeltaQ = deQuants;
+ if (this.frameHeader.DeltaQParameters.IsPresent)
+ {
+ for (int i = 0; i < Av1Constants.MaxSegmentCount; i++)
+ {
+ int currentQIndex = Av1QuantizationLookup.GetQIndex(this.frameHeader.SegmentationParameters, i, superblockInfo.SuperblockDeltaQ);
+
+ for (Av1Plane plane = 0; (int)plane < Av1Constants.MaxPlanes; plane++)
+ {
+ int dcDeltaQ = this.frameHeader.QuantizationParameters.DeltaQDc[(int)plane];
+ int acDeltaQ = this.frameHeader.QuantizationParameters.DeltaQAc[(int)plane];
+
+ this.deQuantsDeltaQ.SetDc(i, plane, Av1QuantizationLookup.GetDcQuant(currentQIndex, dcDeltaQ, bitDepth));
+ this.deQuantsDeltaQ.SetAc(i, plane, Av1QuantizationLookup.GetAcQuant(currentQIndex, acDeltaQ, bitDepth));
+ }
+ }
+ }
+ }
+
+ ///
+ /// SVT: svt_aom_inverse_quantize
+ ///
+ public int InverseQuantize(Av1BlockModeInfo mode, Span level, Span qCoefficients, Av1TransformType transformType, Av1TransformSize transformSize, Av1Plane plane)
+ {
+ Guard.NotNull(this.deQuantsDeltaQ);
+ Av1ScanOrder scanOrder = Av1ScanOrderConstants.GetScanOrder(transformSize, transformType);
+ ReadOnlySpan scanIndices = scanOrder.Scan;
+ int maxValue = (1 << (7 + this.sequenceHeader.ColorConfig.BitDepth.GetBitCount())) - 1;
+ int minValue = -(1 << (7 + this.sequenceHeader.ColorConfig.BitDepth.GetBitCount()));
+ Av1TransformSize qmTransformSize = transformSize.GetAdjusted();
+ bool usingQuantizationMatrix = this.frameHeader.QuantizationParameters.IsUsingQMatrix;
+ bool lossless = this.frameHeader.LosslessArray[mode.SegmentId];
+ short dequantDc = this.deQuantsDeltaQ.GetDc(mode.SegmentId, plane);
+ short dequantAc = this.deQuantsDeltaQ.GetAc(mode.SegmentId, plane);
+ int qmLevel = lossless || !usingQuantizationMatrix ? Av1ScanOrderConstants.QuantizationMatrixLevelCount - 1 : this.frameHeader.QuantizationParameters.QMatrix[(int)plane];
+ ReadOnlySpan iqMatrix = (transformType.ToClass() == Av1TransformClass.Class2D) ?
+ Av1InverseQuantizationLookup.GetQuantizationMatrix(qmLevel, plane, qmTransformSize)
+ : Av1InverseQuantizationLookup.GetQuantizationMatrix(Av1Constants.QuantificationMatrixLevelCount - 1, Av1Plane.Y, qmTransformSize);
+ int shift = transformSize.GetScale();
+
+ int coefficientCount = level[0];
+ level = level[1..];
+ int lev = level[0];
+ int qCoefficient;
+ if (lev != 0)
+ {
+ int pos = scanIndices[0];
+ qCoefficient = (int)(((long)Math.Abs(lev) * GetDeQuantizedValue(dequantDc, pos, iqMatrix)) & 0xffffff);
+ qCoefficient >>= shift;
+
+ if (lev < 0)
+ {
+ qCoefficient = -qCoefficient;
+ }
+
+ qCoefficients[0] = Av1Math.Clamp(qCoefficient, minValue, maxValue);
+ }
+
+ for (int i = 1; i < coefficientCount; i++)
+ {
+ lev = level[i];
+ if (lev != 0)
+ {
+ int pos = scanIndices[i];
+ qCoefficient = (int)(((long)Math.Abs(lev) * GetDeQuantizedValue(dequantAc, pos, iqMatrix)) & 0xffffff);
+ qCoefficient >>= shift;
+
+ if (lev < 0)
+ {
+ qCoefficient = -qCoefficient;
+ }
+
+ qCoefficients[pos] = Av1Math.Clamp(qCoefficient, minValue, maxValue);
+ }
+ }
+
+ return coefficientCount;
+ }
+
+ ///
+ /// SVT: get_dqv
+ ///
+ private static int GetDeQuantizedValue(short dequant, int coefficientIndex, ReadOnlySpan iqMatrix)
+ {
+ const int bias = 1 << (Av1ScanOrderConstants.QuantizationMatrixLevelBitCount - 1);
+ int deQuantifiedValue = dequant;
+
+ deQuantifiedValue = ((iqMatrix[coefficientIndex] * deQuantifiedValue) + bias) >> Av1ScanOrderConstants.QuantizationMatrixLevelBitCount;
+ return deQuantifiedValue;
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Pipeline/Quantification/Av1QuantizationLookup.cs b/src/ImageSharp/Formats/Heif/Av1/Pipeline/Quantification/Av1QuantizationLookup.cs
new file mode 100644
index 0000000000..205f1f3a19
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Pipeline/Quantification/Av1QuantizationLookup.cs
@@ -0,0 +1,190 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.Quantification;
+
+internal class Av1QuantizationLookup
+{
+ // Coefficient scaling and quantization with AV1 TX are tailored to
+ // the AV1 TX transforms. Regardless of the bit-depth of the input,
+ // the transform stages scale the coefficient values up by a factor of
+ // 8 (3 bits) over the scale of the pixel values. Thus, for 8-bit
+ // input, the coefficients have effectively 11 bits of scale depth
+ // (8+3), 10-bit input pixels result in 13-bit coefficient depth
+ // (10+3) and 12-bit pixels yield 15-bit (12+3) coefficient depth.
+ // All quantizers are built using this invariant of x8, 3-bit scaling,
+ // thus the Q3 suffix.
+
+ // A partial exception to this rule is large transforms; to avoid
+ // overflow, TX blocks with > 256 pels (>16x16) are scaled only
+ // 4-times unity (2 bits) over the pixel depth, and TX blocks with
+ // over 1024 pixels (>32x32) are scaled up only 2x unity (1 bit).
+ // This descaling is found via av1_tx_get_scale(). Thus, 16x32, 32x16
+ // and 32x32 transforms actually return Q2 coefficients, and 32x64,
+ // 64x32 and 64x64 transforms return Q1 coefficients. However, the
+ // quantizers are de-scaled down on-the-fly by the same amount
+ // (av1_tx_get_scale()) during quantization, and as such the
+ // dequantized/decoded coefficients, even for large TX blocks, are always
+ // effectively Q3. Meanwhile, quantized/coded coefficients are Q0
+ // because Qn quantizers are applied to Qn tx coefficients.
+
+ // Note that encoder decision making (which uses the quantizer to
+ // generate several bespoke lamdas for RDO and other heuristics)
+ // expects quantizers to be larger for higher-bitdepth input. In
+ // addition, the minimum allowable quantizer is 4; smaller values will
+ // underflow to 0 in the actual quantization routines.
+ private static readonly short[] AcQlookup8 = [
+ 4, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
+ 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138,
+ 140, 142, 144, 146, 148, 150, 152, 155, 158, 161, 164, 167, 170, 173, 176, 179, 182, 185, 188,
+ 191, 194, 197, 200, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255, 260,
+ 265, 270, 275, 280, 285, 290, 295, 300, 305, 311, 317, 323, 329, 335, 341, 347, 353, 359, 366,
+ 373, 380, 387, 394, 401, 408, 416, 424, 432, 440, 448, 456, 465, 474, 483, 492, 501, 510, 520,
+ 530, 540, 550, 560, 571, 582, 593, 604, 615, 627, 639, 651, 663, 676, 689, 702, 715, 729, 743,
+ 757, 771, 786, 801, 816, 832, 848, 864, 881, 898, 915, 933, 951, 969, 988, 1007, 1026, 1046, 1066,
+ 1087, 1108, 1129, 1151, 1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343, 1369, 1396, 1423, 1451, 1479, 1508, 1537,
+ 1567, 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828,
+ ];
+
+ private static readonly short[] AcQlookup10 = [
+ 4, 9, 11, 13, 16, 18, 21, 24, 27, 30, 33, 37, 40, 44, 48, 51, 55, 59, 63,
+ 67, 71, 75, 79, 83, 88, 92, 96, 100, 105, 109, 114, 118, 122, 127, 131, 136, 140, 145,
+ 149, 154, 158, 163, 168, 172, 177, 181, 186, 190, 195, 199, 204, 208, 213, 217, 222, 226, 231,
+ 235, 240, 244, 249, 253, 258, 262, 267, 271, 275, 280, 284, 289, 293, 297, 302, 306, 311, 315,
+ 319, 324, 328, 332, 337, 341, 345, 349, 354, 358, 362, 367, 371, 375, 379, 384, 388, 392, 396,
+ 401, 409, 417, 425, 433, 441, 449, 458, 466, 474, 482, 490, 498, 506, 514, 523, 531, 539, 547,
+ 555, 563, 571, 579, 588, 596, 604, 616, 628, 640, 652, 664, 676, 688, 700, 713, 725, 737, 749,
+ 761, 773, 785, 797, 809, 825, 841, 857, 873, 889, 905, 922, 938, 954, 970, 986, 1002, 1018, 1038,
+ 1058, 1078, 1098, 1118, 1138, 1158, 1178, 1198, 1218, 1242, 1266, 1290, 1314, 1338, 1362, 1386, 1411, 1435, 1463,
+ 1491, 1519, 1547, 1575, 1603, 1631, 1663, 1695, 1727, 1759, 1791, 1823, 1859, 1895, 1931, 1967, 2003, 2039, 2079,
+ 2119, 2159, 2199, 2239, 2283, 2327, 2371, 2415, 2459, 2507, 2555, 2603, 2651, 2703, 2755, 2807, 2859, 2915, 2971,
+ 3027, 3083, 3143, 3203, 3263, 3327, 3391, 3455, 3523, 3591, 3659, 3731, 3803, 3876, 3952, 4028, 4104, 4184, 4264,
+ 4348, 4432, 4516, 4604, 4692, 4784, 4876, 4972, 5068, 5168, 5268, 5372, 5476, 5584, 5692, 5804, 5916, 6032, 6148,
+ 6268, 6388, 6512, 6640, 6768, 6900, 7036, 7172, 7312,
+ ];
+
+ private static readonly short[] AcQlookup12 = [
+ 4, 13, 19, 27, 35, 44, 54, 64, 75, 87, 99, 112, 126, 139, 154, 168,
+ 183, 199, 214, 230, 247, 263, 280, 297, 314, 331, 349, 366, 384, 402, 420, 438,
+ 456, 475, 493, 511, 530, 548, 567, 586, 604, 623, 642, 660, 679, 698, 716, 735,
+ 753, 772, 791, 809, 828, 846, 865, 884, 902, 920, 939, 957, 976, 994, 1012, 1030,
+ 1049, 1067, 1085, 1103, 1121, 1139, 1157, 1175, 1193, 1211, 1229, 1246, 1264, 1282, 1299, 1317,
+ 1335, 1352, 1370, 1387, 1405, 1422, 1440, 1457, 1474, 1491, 1509, 1526, 1543, 1560, 1577, 1595,
+ 1627, 1660, 1693, 1725, 1758, 1791, 1824, 1856, 1889, 1922, 1954, 1987, 2020, 2052, 2085, 2118,
+ 2150, 2183, 2216, 2248, 2281, 2313, 2346, 2378, 2411, 2459, 2508, 2556, 2605, 2653, 2701, 2750,
+ 2798, 2847, 2895, 2943, 2992, 3040, 3088, 3137, 3185, 3234, 3298, 3362, 3426, 3491, 3555, 3619,
+ 3684, 3748, 3812, 3876, 3941, 4005, 4069, 4149, 4230, 4310, 4390, 4470, 4550, 4631, 4711, 4791,
+ 4871, 4967, 5064, 5160, 5256, 5352, 5448, 5544, 5641, 5737, 5849, 5961, 6073, 6185, 6297, 6410,
+ 6522, 6650, 6778, 6906, 7034, 7162, 7290, 7435, 7579, 7723, 7867, 8011, 8155, 8315, 8475, 8635,
+ 8795, 8956, 9132, 9308, 9484, 9660, 9836, 10028, 10220, 10412, 10604, 10812, 11020, 11228, 11437, 11661,
+ 11885, 12109, 12333, 12573, 12813, 13053, 13309, 13565, 13821, 14093, 14365, 14637, 14925, 15213, 15502, 15806,
+ 16110, 16414, 16734, 17054, 17390, 17726, 18062, 18414, 18766, 19134, 19502, 19886, 20270, 20670, 21070, 21486,
+ 21902, 22334, 22766, 23214, 23662, 24126, 24590, 25070, 25551, 26047, 26559, 27071, 27599, 28143, 28687, 29247,
+ ];
+
+ private static readonly short[] DcQlookup8 = [
+ 4, 8, 8, 9, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23,
+ 24, 25, 26, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 38, 38, 39, 40,
+ 41, 42, 43, 43, 44, 45, 46, 47, 48, 48, 49, 50, 51, 52, 53, 53, 54, 55, 56, 57,
+ 57, 58, 59, 60, 61, 62, 62, 63, 64, 65, 66, 66, 67, 68, 69, 70, 70, 71, 72, 73,
+ 74, 74, 75, 76, 77, 78, 78, 79, 80, 81, 81, 82, 83, 84, 85, 85, 87, 88, 90, 92,
+ 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 108, 110, 111, 113, 114, 116, 117, 118, 120, 121,
+ 123, 125, 127, 129, 131, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 161, 164,
+ 166, 169, 172, 174, 177, 180, 182, 185, 187, 190, 192, 195, 199, 202, 205, 208, 211, 214, 217, 220,
+ 223, 226, 230, 233, 237, 240, 243, 247, 250, 253, 257, 261, 265, 269, 272, 276, 280, 284, 288, 292,
+ 296, 300, 304, 309, 313, 317, 322, 326, 330, 335, 340, 344, 349, 354, 359, 364, 369, 374, 379, 384,
+ 389, 395, 400, 406, 411, 417, 423, 429, 435, 441, 447, 454, 461, 467, 475, 482, 489, 497, 505, 513,
+ 522, 530, 539, 549, 559, 569, 579, 590, 602, 614, 626, 640, 654, 668, 684, 700, 717, 736, 755, 775,
+ 796, 819, 843, 869, 896, 925, 955, 988, 1022, 1058, 1098, 1139, 1184, 1232, 1282, 1336,
+ ];
+
+ private static readonly short[] DcQlookup10 = [
+ 4, 9, 10, 13, 15, 17, 20, 22, 25, 28, 31, 34, 37, 40, 43, 47, 50, 53, 57,
+ 60, 64, 68, 71, 75, 78, 82, 86, 90, 93, 97, 101, 105, 109, 113, 116, 120, 124, 128,
+ 132, 136, 140, 143, 147, 151, 155, 159, 163, 166, 170, 174, 178, 182, 185, 189, 193, 197, 200,
+ 204, 208, 212, 215, 219, 223, 226, 230, 233, 237, 241, 244, 248, 251, 255, 259, 262, 266, 269,
+ 273, 276, 280, 283, 287, 290, 293, 297, 300, 304, 307, 310, 314, 317, 321, 324, 327, 331, 334,
+ 337, 343, 350, 356, 362, 369, 375, 381, 387, 394, 400, 406, 412, 418, 424, 430, 436, 442, 448,
+ 454, 460, 466, 472, 478, 484, 490, 499, 507, 516, 525, 533, 542, 550, 559, 567, 576, 584, 592,
+ 601, 609, 617, 625, 634, 644, 655, 666, 676, 687, 698, 708, 718, 729, 739, 749, 759, 770, 782,
+ 795, 807, 819, 831, 844, 856, 868, 880, 891, 906, 920, 933, 947, 961, 975, 988, 1001, 1015, 1030,
+ 1045, 1061, 1076, 1090, 1105, 1120, 1137, 1153, 1170, 1186, 1202, 1218, 1236, 1253, 1271, 1288, 1306, 1323, 1342,
+ 1361, 1379, 1398, 1416, 1436, 1456, 1476, 1496, 1516, 1537, 1559, 1580, 1601, 1624, 1647, 1670, 1692, 1717, 1741,
+ 1766, 1791, 1817, 1844, 1871, 1900, 1929, 1958, 1990, 2021, 2054, 2088, 2123, 2159, 2197, 2236, 2276, 2319, 2363,
+ 2410, 2458, 2508, 2561, 2616, 2675, 2737, 2802, 2871, 2944, 3020, 3102, 3188, 3280, 3375, 3478, 3586, 3702, 3823,
+ 3953, 4089, 4236, 4394, 4559, 4737, 4929, 5130, 5347,
+ ];
+
+ private static readonly short[] DcQlookup12 = [
+ 4, 12, 18, 25, 33, 41, 50, 60, 70, 80, 91, 103, 115, 127, 140, 153,
+ 166, 180, 194, 208, 222, 237, 251, 266, 281, 296, 312, 327, 343, 358, 374, 390,
+ 405, 421, 437, 453, 469, 484, 500, 516, 532, 548, 564, 580, 596, 611, 627, 643,
+ 659, 674, 690, 706, 721, 737, 752, 768, 783, 798, 814, 829, 844, 859, 874, 889,
+ 904, 919, 934, 949, 964, 978, 993, 1008, 1022, 1037, 1051, 1065, 1080, 1094, 1108, 1122,
+ 1136, 1151, 1165, 1179, 1192, 1206, 1220, 1234, 1248, 1261, 1275, 1288, 1302, 1315, 1329, 1342,
+ 1368, 1393, 1419, 1444, 1469, 1494, 1519, 1544, 1569, 1594, 1618, 1643, 1668, 1692, 1717, 1741,
+ 1765, 1789, 1814, 1838, 1862, 1885, 1909, 1933, 1957, 1992, 2027, 2061, 2096, 2130, 2165, 2199,
+ 2233, 2267, 2300, 2334, 2367, 2400, 2434, 2467, 2499, 2532, 2575, 2618, 2661, 2704, 2746, 2788,
+ 2830, 2872, 2913, 2954, 2995, 3036, 3076, 3127, 3177, 3226, 3275, 3324, 3373, 3421, 3469, 3517,
+ 3565, 3621, 3677, 3733, 3788, 3843, 3897, 3951, 4005, 4058, 4119, 4181, 4241, 4301, 4361, 4420,
+ 4479, 4546, 4612, 4677, 4742, 4807, 4871, 4942, 5013, 5083, 5153, 5222, 5291, 5367, 5442, 5517,
+ 5591, 5665, 5745, 5825, 5905, 5984, 6063, 6149, 6234, 6319, 6404, 6495, 6587, 6678, 6769, 6867,
+ 6966, 7064, 7163, 7269, 7376, 7483, 7599, 7715, 7832, 7958, 8085, 8214, 8352, 8492, 8635, 8788,
+ 8945, 9104, 9275, 9450, 9639, 9832, 10031, 10245, 10465, 10702, 10946, 11210, 11482, 11776, 12081, 12409,
+ 12750, 13118, 13501, 13913, 14343, 14807, 15290, 15812, 16356, 16943, 17575, 18237, 18949, 19718, 20521, 21387,
+ ];
+
+ public static short GetDcQuant(int qIndex, int dcDeltaQ, Av1BitDepth bitDepth)
+ {
+ int qClamped = Av1Math.Clamp(qIndex + dcDeltaQ, 0, Av1Constants.MaxQ);
+ switch (bitDepth)
+ {
+ case Av1BitDepth.EightBit:
+ return DcQlookup8[qClamped];
+ case Av1BitDepth.TenBit:
+ return DcQlookup10[qClamped];
+ case Av1BitDepth.TwelveBit:
+ return DcQlookup12[qClamped];
+ default:
+ Guard.IsFalse(true, nameof(bitDepth), "bit_depth should be EB_EIGHT_BIT, EB_TEN_BIT or EB_TWELVE_BIT");
+ return -1;
+ }
+ }
+
+ public static short GetAcQuant(int qIndex, int dcDeltaQ, Av1BitDepth bitDepth)
+ {
+ int qClamped = Av1Math.Clamp(qIndex + dcDeltaQ, 0, Av1Constants.MaxQ);
+ switch (bitDepth)
+ {
+ case Av1BitDepth.EightBit:
+ return AcQlookup8[qClamped];
+ case Av1BitDepth.TenBit:
+ return AcQlookup10[qClamped];
+ case Av1BitDepth.TwelveBit:
+ return AcQlookup12[qClamped];
+ default:
+ Guard.IsFalse(true, nameof(bitDepth), "bit_depth should be EB_EIGHT_BIT, EB_TEN_BIT or EB_TWELVE_BIT");
+ return -1;
+ }
+ }
+
+ public static int GetQIndex(ObuSegmentationParameters segmentationParameters, int segmentId, int baseQIndex)
+ {
+ if (segmentationParameters.IsFeatureActive(segmentId, ObuSegmentationLevelFeature.AlternativeQuantizer))
+ {
+ int data = segmentationParameters.FeatureData[segmentId, (int)ObuSegmentationLevelFeature.AlternativeQuantizer];
+ int qIndex = baseQIndex + data;
+ return Av1Math.Clamp(qIndex, 0, Av1Constants.MaxQ);
+ }
+ else
+ {
+ return baseQIndex;
+ }
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1BottomRightTopLeftConstants.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1BottomRightTopLeftConstants.cs
new file mode 100644
index 0000000000..a3a3e0bd8b
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1BottomRightTopLeftConstants.cs
@@ -0,0 +1,505 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+
+internal class Av1BottomRightTopLeftConstants
+{
+ // Tables to store if the top-right reference pixels are available. The flags
+ // are represented with bits, packed into 8-bit integers. E.g., for the 32x32
+ // blocks in a 128x128 superblock, the index of the "o" block is 10 (in raster
+ // order), so its flag is stored at the 3rd bit of the 2nd entry in the table,
+ // i.e. (table[10 / 8] >> (10 % 8)) & 1.
+ // . . . .
+ // . . . .
+ // . . o .
+ // . . . .
+ private static readonly byte[] HasTopRight4x4 = [
+ 255, 255, 255, 255, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, 127, 127, 127, 127, 85, 85,
+ 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, 255, 127, 255, 127, 85, 85, 85, 85, 119, 119, 119, 119,
+ 85, 85, 85, 85, 127, 127, 127, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, 255, 255,
+ 255, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, 127, 127, 127, 127, 85, 85, 85, 85,
+ 119, 119, 119, 119, 85, 85, 85, 85, 255, 127, 255, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85,
+ 85, 85, 127, 127, 127, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85,
+ ];
+
+ private static readonly byte[] HasTopRight4x8 = [
+ 255, 255, 255, 255, 119, 119, 119, 119, 127, 127, 127, 127, 119, 119, 119, 119, 255, 127, 255, 127, 119, 119,
+ 119, 119, 127, 127, 127, 127, 119, 119, 119, 119, 255, 255, 255, 127, 119, 119, 119, 119, 127, 127, 127, 127,
+ 119, 119, 119, 119, 255, 127, 255, 127, 119, 119, 119, 119, 127, 127, 127, 127, 119, 119, 119, 119,
+ ];
+
+ private static readonly byte[] HasTopRight8x4 = [
+ 255, 255, 0, 0, 85, 85, 0, 0, 119, 119, 0, 0, 85, 85, 0, 0, 127, 127, 0, 0, 85, 85,
+ 0, 0, 119, 119, 0, 0, 85, 85, 0, 0, 255, 127, 0, 0, 85, 85, 0, 0, 119, 119, 0, 0,
+ 85, 85, 0, 0, 127, 127, 0, 0, 85, 85, 0, 0, 119, 119, 0, 0, 85, 85, 0, 0,
+ ];
+
+ private static readonly byte[] HasTopRight8x8 = [
+ 255, 255, 85, 85, 119, 119, 85, 85, 127, 127, 85, 85, 119, 119, 85, 85,
+ 255, 127, 85, 85, 119, 119, 85, 85, 127, 127, 85, 85, 119, 119, 85, 85,
+ ];
+
+ private static readonly byte[] HasTopRight8x16 = [
+ 255,
+ 255,
+ 119,
+ 119,
+ 127,
+ 127,
+ 119,
+ 119,
+ 255,
+ 127,
+ 119,
+ 119,
+ 127,
+ 127,
+ 119,
+ 119,
+ ];
+
+ private static readonly byte[] HasTopRight16x8 = [
+ 255,
+ 0,
+ 85,
+ 0,
+ 119,
+ 0,
+ 85,
+ 0,
+ 127,
+ 0,
+ 85,
+ 0,
+ 119,
+ 0,
+ 85,
+ 0,
+ ];
+
+ private static readonly byte[] HasTopRight16x16 = [
+ 255,
+ 85,
+ 119,
+ 85,
+ 127,
+ 85,
+ 119,
+ 85,
+ ];
+
+ private static readonly byte[] HasTopRight16x32 = [255, 119, 127, 119];
+ private static readonly byte[] HasTopRight32x16 = [15, 5, 7, 5];
+ private static readonly byte[] HasTopRight32x32 = [95, 87];
+ private static readonly byte[] HasTopRight32x64 = [127];
+ private static readonly byte[] HasTopRight64x32 = [19];
+ private static readonly byte[] HasTopRight64x64 = [7];
+ private static readonly byte[] HasTopRight64x128 = [3];
+ private static readonly byte[] HasTopRight128x64 = [1];
+ private static readonly byte[] HasTopRight128x128 = [1];
+ private static readonly byte[] HasTopRight4x16 = [
+ 255, 255, 255, 255, 127, 127, 127, 127, 255, 127, 255, 127, 127, 127, 127, 127,
+ 255, 255, 255, 127, 127, 127, 127, 127, 255, 127, 255, 127, 127, 127, 127, 127,
+ ];
+
+ private static readonly byte[] HasTopRight16x4 = [
+ 255, 0, 0, 0, 85, 0, 0, 0, 119, 0, 0, 0, 85, 0, 0, 0, 127, 0, 0, 0, 85, 0, 0, 0, 119, 0, 0, 0, 85, 0, 0, 0,
+ ];
+
+ private static readonly byte[] HasTopRight8x32 = [
+ 255,
+ 255,
+ 127,
+ 127,
+ 255,
+ 127,
+ 127,
+ 127,
+ ];
+
+ private static readonly byte[] HasTopRight32x8 = [
+ 15,
+ 0,
+ 5,
+ 0,
+ 7,
+ 0,
+ 5,
+ 0,
+ ];
+
+ private static readonly byte[] HasTopRight16x64 = [255, 127];
+ private static readonly byte[] HasTopRight64x16 = [3, 1];
+
+ private static readonly byte[][] HasTopRightTables = [
+
+ // 4X4
+ HasTopRight4x4,
+
+ // 4X8, 8X4, 8X8
+ HasTopRight4x8,
+ HasTopRight8x4,
+ HasTopRight8x8,
+
+ // 8X16, 16X8, 16X16
+ HasTopRight8x16,
+ HasTopRight16x8,
+ HasTopRight16x16,
+
+ // 16X32, 32X16, 32X32
+ HasTopRight16x32,
+ HasTopRight32x16,
+ HasTopRight32x32,
+
+ // 32X64, 64X32, 64X64
+ HasTopRight32x64,
+ HasTopRight64x32,
+ HasTopRight64x64,
+
+ // 64x128, 128x64, 128x128
+ HasTopRight64x128,
+ HasTopRight128x64,
+ HasTopRight128x128,
+
+ // 4x16, 16x4, 8x32
+ HasTopRight4x16,
+ HasTopRight16x4,
+ HasTopRight8x32,
+
+ // 32x8, 16x64, 64x16
+ HasTopRight32x8,
+ HasTopRight16x64,
+ HasTopRight64x16
+ ];
+
+ private static readonly byte[] HasTopRightVertical8x8 = [
+ 255, 255, 0, 0, 119, 119, 0, 0, 127, 127, 0, 0, 119, 119, 0, 0,
+ 255, 127, 0, 0, 119, 119, 0, 0, 127, 127, 0, 0, 119, 119, 0, 0,
+ ];
+
+ private static readonly byte[] HasTopRightVertical16x16 = [
+ 255,
+ 0,
+ 119,
+ 0,
+ 127,
+ 0,
+ 119,
+ 0,
+ ];
+
+ private static readonly byte[] HasTopRightVertical32x32 = [15, 7];
+ private static readonly byte[] HasTopRightVertical64x64 = [3];
+
+ // The _vert_* tables are like the ordinary tables above, but describe the
+ // order we visit square blocks when doing a PARTITION_VERT_A or
+ // PARTITION_VERT_B. This is the same order as normal except for on the last
+ // split where we go vertically (TL, BL, TR, BR). We treat the rectangular block
+ // as a pair of squares, which means that these tables work correctly for both
+ // mixed vertical partition types.
+ //
+ // There are tables for each of the square sizes. Vertical rectangles (like
+ // BLOCK_16X32) use their respective "non-vert" table
+ private static readonly byte[]?[] HasTopRightVerticalTables = [
+
+ // 4X4
+ null,
+
+ // 4X8, 8X4, 8X8
+ HasTopRight4x8,
+ null,
+ HasTopRightVertical8x8,
+
+ // 8X16, 16X8, 16X16
+ HasTopRight8x16,
+ null,
+ HasTopRightVertical16x16,
+
+ // 16X32, 32X16, 32X32
+ HasTopRight16x32,
+ null,
+ HasTopRightVertical32x32,
+
+ // 32X64, 64X32, 64X64
+ HasTopRight32x64,
+ null,
+ HasTopRightVertical64x64,
+
+ // 64x128, 128x64, 128x128
+ HasTopRight64x128,
+ null,
+ HasTopRight128x128
+ ];
+
+ // Similar to the has_tr_* tables, but store if the bottom-left reference
+ // pixels are available.
+ private static readonly byte[] HasBottomLeft4x4 = [
+ 84, 85, 85, 85, 16, 17, 17, 17, 84, 85, 85, 85, 0, 1, 1, 1, 84, 85, 85, 85, 16, 17, 17, 17, 84, 85,
+ 85, 85, 0, 0, 1, 0, 84, 85, 85, 85, 16, 17, 17, 17, 84, 85, 85, 85, 0, 1, 1, 1, 84, 85, 85, 85,
+ 16, 17, 17, 17, 84, 85, 85, 85, 0, 0, 0, 0, 84, 85, 85, 85, 16, 17, 17, 17, 84, 85, 85, 85, 0, 1,
+ 1, 1, 84, 85, 85, 85, 16, 17, 17, 17, 84, 85, 85, 85, 0, 0, 1, 0, 84, 85, 85, 85, 16, 17, 17, 17,
+ 84, 85, 85, 85, 0, 1, 1, 1, 84, 85, 85, 85, 16, 17, 17, 17, 84, 85, 85, 85, 0, 0, 0, 0,
+ ];
+
+ private static readonly byte[] HasBottomLeft4x8 = [
+ 16, 17, 17, 17, 0, 1, 1, 1, 16, 17, 17, 17, 0, 0, 1, 0, 16, 17, 17, 17, 0, 1, 1, 1, 16, 17, 17, 17, 0, 0, 0, 0,
+ 16, 17, 17, 17, 0, 1, 1, 1, 16, 17, 17, 17, 0, 0, 1, 0, 16, 17, 17, 17, 0, 1, 1, 1, 16, 17, 17, 17, 0, 0, 0, 0,
+ ];
+
+ private static readonly byte[] HasBottomLeft8x4 = [
+ 254, 255, 84, 85, 254, 255, 16, 17, 254, 255, 84, 85, 254, 255, 0, 1, 254, 255, 84, 85, 254, 255,
+ 16, 17, 254, 255, 84, 85, 254, 255, 0, 0, 254, 255, 84, 85, 254, 255, 16, 17, 254, 255, 84, 85,
+ 254, 255, 0, 1, 254, 255, 84, 85, 254, 255, 16, 17, 254, 255, 84, 85, 254, 255, 0, 0,
+ ];
+
+ private static readonly byte[] HasBottomLeft8x8 = [
+ 84, 85, 16, 17, 84, 85, 0, 1, 84, 85, 16, 17, 84, 85, 0, 0,
+ 84, 85, 16, 17, 84, 85, 0, 1, 84, 85, 16, 17, 84, 85, 0, 0,
+ ];
+
+ private static readonly byte[] HasBottomLeft8x16 = [
+ 16,
+ 17,
+ 0,
+ 1,
+ 16,
+ 17,
+ 0,
+ 0,
+ 16,
+ 17,
+ 0,
+ 1,
+ 16,
+ 17,
+ 0,
+ 0,
+ ];
+
+ private static readonly byte[] HasBottomLeft16x8 = [
+ 254,
+ 84,
+ 254,
+ 16,
+ 254,
+ 84,
+ 254,
+ 0,
+ 254,
+ 84,
+ 254,
+ 16,
+ 254,
+ 84,
+ 254,
+ 0,
+ ];
+
+ private static readonly byte[] HasBottomLeft16x16 = [
+ 84,
+ 16,
+ 84,
+ 0,
+ 84,
+ 16,
+ 84,
+ 0,
+ ];
+
+ private static readonly byte[] HasBottomLeft16x32 = [16, 0, 16, 0];
+ private static readonly byte[] HasBottomLeft32x16 = [78, 14, 78, 14];
+ private static readonly byte[] HasBottomLeft32x32 = [4, 4];
+ private static readonly byte[] HasBottomLeft32x64 = [0];
+ private static readonly byte[] HasBottomLeft64x32 = [34];
+ private static readonly byte[] HasBottomLeft64x64 = [0];
+ private static readonly byte[] HasBottomLeft64x128 = [0];
+ private static readonly byte[] HasBottomLeft128x64 = [0];
+ private static readonly byte[] HasBottomLeft128x128 = [0];
+ private static readonly byte[] HasBottomLeft4x16 = [
+ 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0,
+ ];
+
+ private static readonly byte[] HasBottomLeft16x4 = [
+ 254, 254, 254, 84, 254, 254, 254, 16, 254, 254, 254, 84, 254, 254, 254, 0,
+ 254, 254, 254, 84, 254, 254, 254, 16, 254, 254, 254, 84, 254, 254, 254, 0,
+ ];
+
+ private static readonly byte[] HasBottomLeft8x32 = [
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ ];
+
+ private static readonly byte[] HasBottomLeft32x8 = [
+ 238,
+ 78,
+ 238,
+ 14,
+ 238,
+ 78,
+ 238,
+ 14,
+ ];
+
+ private static readonly byte[] HasBottomLeft16x64 = [0, 0];
+ private static readonly byte[] HasBottomLeft64x16 = [42, 42];
+
+ private static readonly byte[][] HasBottomLeftTables = [
+
+ // 4X4
+ HasBottomLeft4x4,
+
+ // 4X8, 8X4, 8X8
+ HasBottomLeft4x8,
+ HasBottomLeft8x4,
+ HasBottomLeft8x8,
+
+ // 8X16, 16X8, 16X16
+ HasBottomLeft8x16,
+ HasBottomLeft16x8,
+ HasBottomLeft16x16,
+
+ // 16X32, 32X16, 32X32
+ HasBottomLeft16x32,
+ HasBottomLeft32x16,
+ HasBottomLeft32x32,
+
+ // 32X64, 64X32, 64X64
+ HasBottomLeft32x64,
+ HasBottomLeft64x32,
+ HasBottomLeft64x64,
+
+ // 64x128, 128x64, 128x128
+ HasBottomLeft64x128,
+ HasBottomLeft128x64,
+ HasBottomLeft128x128,
+
+ // 4x16, 16x4, 8x32
+ HasBottomLeft4x16,
+ HasBottomLeft16x4,
+ HasBottomLeft8x32,
+
+ // 32x8, 16x64, 64x16
+ HasBottomLeft32x8,
+ HasBottomLeft16x64,
+ HasBottomLeft64x16
+ ];
+
+ private static readonly byte[] HasBottomLeftVertical8x8 = [
+ 254, 255, 16, 17, 254, 255, 0, 1, 254, 255, 16, 17, 254, 255, 0, 0,
+ 254, 255, 16, 17, 254, 255, 0, 1, 254, 255, 16, 17, 254, 255, 0, 0,
+ ];
+
+ private static readonly byte[] HasBottomLeftVertical16x16 = [
+ 254,
+ 16,
+ 254,
+ 0,
+ 254,
+ 16,
+ 254,
+ 0,
+ ];
+
+ private static readonly byte[] HasBottomLeftVertical32x32 = [14, 14];
+ private static readonly byte[] HasBottomLeftVertical64x64 = [2];
+
+ // The _vert_* tables are like the ordinary tables above, but describe the
+ // order we visit square blocks when doing a PARTITION_VERT_A or
+ // PARTITION_VERT_B. This is the same order as normal except for on the last
+ // split where we go vertically (TL, BL, TR, BR). We treat the rectangular block
+ // as a pair of squares, which means that these tables work correctly for both
+ // mixed vertical partition types.
+ //
+ // There are tables for each of the square sizes. Vertical rectangles (like
+ // BLOCK_16X32) use their respective "non-vert" table
+ private static readonly byte[]?[] HasBottomLeftVerticalTables = [
+
+ // 4X4
+ null,
+
+ // 4X8, 8X4, 8X8
+ HasBottomLeft4x8,
+ null,
+ HasBottomLeftVertical8x8,
+
+ // 8X16, 16X8, 16X16
+ HasBottomLeft8x16,
+ null,
+ HasBottomLeftVertical16x16,
+
+ // 16X32, 32X16, 32X32
+ HasBottomLeft16x32,
+ null,
+ HasBottomLeftVertical32x32,
+
+ // 32X64, 64X32, 64X64
+ HasBottomLeft32x64,
+ null,
+ HasBottomLeftVertical64x64,
+
+ // 64x128, 128x64, 128x128
+ HasBottomLeft64x128,
+ null,
+ HasBottomLeft128x128];
+
+ public static bool HasTopRight(Av1PartitionType partitionType, Av1BlockSize blockSize, int blockIndex)
+ {
+ int index1 = blockIndex / 8;
+ int index2 = blockIndex % 8;
+ Span hasBottomLeftTable = GetHasTopRightTable(partitionType, blockSize);
+ return ((hasBottomLeftTable[index1] >> index2) & 1) > 0;
+ }
+
+ public static bool HasBottomLeft(Av1PartitionType partitionType, Av1BlockSize blockSize, int blockIndex)
+ {
+ int index1 = blockIndex / 8;
+ int index2 = blockIndex % 8;
+ Span hasBottomLeftTable = GetHasBottomLeftTable(partitionType, blockSize);
+ return ((hasBottomLeftTable[index1] >> index2) & 1) > 0;
+ }
+
+ private static Span GetHasTopRightTable(Av1PartitionType partition, Av1BlockSize blockSize)
+ {
+ byte[]? ret;
+
+ // If this is a mixed vertical partition, look up block size in vertical order.
+ if (partition is Av1PartitionType.VerticalA or Av1PartitionType.VerticalB)
+ {
+ DebugGuard.MustBeLessThan((int)blockSize, (int)Av1BlockSize.SizeS, nameof(blockSize));
+ ret = HasTopRightVerticalTables[(int)blockSize];
+ }
+ else
+ {
+ ret = HasTopRightTables[(int)blockSize];
+ }
+
+ DebugGuard.NotNull(ret, nameof(ret));
+ return ret;
+ }
+
+ private static Span GetHasBottomLeftTable(Av1PartitionType partition, Av1BlockSize blockSize)
+ {
+ byte[]? ret;
+
+ // If this is a mixed vertical partition, look up block size in vertical order.
+ if (partition is Av1PartitionType.VerticalA or Av1PartitionType.VerticalB)
+ {
+ DebugGuard.MustBeLessThan((int)blockSize, (int)Av1BlockSize.SizeS, nameof(blockSize));
+ ret = HasBottomLeftVerticalTables[(int)blockSize];
+ }
+ else
+ {
+ ret = HasBottomLeftTables[(int)blockSize];
+ }
+
+ DebugGuard.NotNull(ret, nameof(ret));
+ return ret;
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DcFillPredictor.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DcFillPredictor.cs
new file mode 100644
index 0000000000..d4340c9c5b
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DcFillPredictor.cs
@@ -0,0 +1,41 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Runtime.CompilerServices;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+
+internal class Av1DcFillPredictor : IAv1Predictor
+{
+ private readonly uint blockWidth;
+ private readonly uint blockHeight;
+
+ public Av1DcFillPredictor(Size blockSize)
+ {
+ this.blockWidth = (uint)blockSize.Width;
+ this.blockHeight = (uint)blockSize.Height;
+ }
+
+ public Av1DcFillPredictor(Av1TransformSize transformSize)
+ {
+ this.blockWidth = (uint)transformSize.GetWidth();
+ this.blockHeight = (uint)transformSize.GetHeight();
+ }
+
+ public static void PredictScalar(Av1TransformSize transformSize, Span destination, nuint stride, Span above, Span left)
+ => new Av1DcFillPredictor(transformSize).PredictScalar(destination, stride, above, left);
+
+ public void PredictScalar(Span destination, nuint stride, Span above, Span left)
+ {
+ const byte expectedDc = 0x80;
+ Guard.MustBeGreaterThanOrEqualTo(stride, this.blockWidth, nameof(stride));
+ Guard.MustBeSizedAtLeast(destination, (int)this.blockHeight * (int)stride, nameof(destination));
+ ref byte destinationRef = ref destination[0];
+ for (uint r = 0; r < this.blockHeight; r++)
+ {
+ Unsafe.InitBlock(ref destinationRef, expectedDc, this.blockWidth);
+ destinationRef = ref Unsafe.Add(ref destinationRef, stride);
+ }
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DcLeftPredictor.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DcLeftPredictor.cs
new file mode 100644
index 0000000000..9237fe751e
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DcLeftPredictor.cs
@@ -0,0 +1,49 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Runtime.CompilerServices;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+
+internal class Av1DcLeftPredictor : IAv1Predictor
+{
+ private readonly uint blockWidth;
+ private readonly uint blockHeight;
+
+ public Av1DcLeftPredictor(Size blockSize)
+ {
+ this.blockWidth = (uint)blockSize.Width;
+ this.blockHeight = (uint)blockSize.Height;
+ }
+
+ public Av1DcLeftPredictor(Av1TransformSize transformSize)
+ {
+ this.blockWidth = (uint)transformSize.GetWidth();
+ this.blockHeight = (uint)transformSize.GetHeight();
+ }
+
+ public static void PredictScalar(Av1TransformSize transformSize, Span destination, nuint stride, Span above, Span left)
+ => new Av1DcLeftPredictor(transformSize).PredictScalar(destination, stride, above, left);
+
+ public void PredictScalar(Span destination, nuint stride, Span above, Span left)
+ {
+ int sum = 0;
+ Guard.MustBeGreaterThanOrEqualTo(stride, this.blockWidth, nameof(stride));
+ Guard.MustBeSizedAtLeast(left, (int)this.blockHeight, nameof(left));
+ Guard.MustBeSizedAtLeast(destination, (int)this.blockHeight * (int)stride, nameof(destination));
+ ref byte leftRef = ref left[0];
+ ref byte destinationRef = ref destination[0];
+ for (uint i = 0; i < this.blockHeight; i++)
+ {
+ sum += Unsafe.Add(ref leftRef, i);
+ }
+
+ byte expectedDc = (byte)((sum + (this.blockHeight >> 1)) / this.blockHeight);
+ for (uint r = 0; r < this.blockHeight; r++)
+ {
+ Unsafe.InitBlock(ref destinationRef, expectedDc, this.blockWidth);
+ destinationRef = ref Unsafe.Add(ref destinationRef, stride);
+ }
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DcPredictor.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DcPredictor.cs
new file mode 100644
index 0000000000..f91735fc7d
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DcPredictor.cs
@@ -0,0 +1,57 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Runtime.CompilerServices;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+
+internal class Av1DcPredictor : IAv1Predictor
+{
+ private readonly uint blockWidth;
+ private readonly uint blockHeight;
+
+ public Av1DcPredictor(Size blockSize)
+ {
+ this.blockWidth = (uint)blockSize.Width;
+ this.blockHeight = (uint)blockSize.Height;
+ }
+
+ public Av1DcPredictor(Av1TransformSize transformSize)
+ {
+ this.blockWidth = (uint)transformSize.GetWidth();
+ this.blockHeight = (uint)transformSize.GetHeight();
+ }
+
+ public static void PredictScalar(Av1TransformSize transformSize, Span destination, nuint stride, Span above, Span left)
+ => new Av1DcPredictor(transformSize).PredictScalar(destination, stride, above, left);
+
+ public void PredictScalar(Span destination, nuint stride, Span above, Span left)
+ {
+ int sum = 0;
+ Guard.MustBeGreaterThanOrEqualTo(stride, this.blockWidth, nameof(stride));
+ Guard.MustBeSizedAtLeast(left, (int)this.blockHeight, nameof(left));
+ Guard.MustBeSizedAtLeast(above, (int)this.blockWidth, nameof(above));
+ Guard.MustBeSizedAtLeast(destination, (int)this.blockHeight * (int)stride, nameof(destination));
+ ref byte leftRef = ref left[0];
+ ref byte aboveRef = ref above[0];
+ ref byte destinationRef = ref destination[0];
+ uint count = this.blockWidth + this.blockHeight;
+ for (uint i = 0; i < this.blockWidth; i++)
+ {
+ sum += Unsafe.Add(ref aboveRef, i);
+ }
+
+ for (uint i = 0; i < this.blockHeight; i++)
+ {
+ sum += Unsafe.Add(ref leftRef, i);
+ }
+
+ byte expectedDc = (byte)((sum + (count >> 1)) / count);
+ for (uint r = 0; r < this.blockHeight; r++)
+ {
+ Unsafe.InitBlock(ref destinationRef, expectedDc, this.blockWidth);
+ destinationRef = ref Unsafe.Add(ref destinationRef, stride);
+ }
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DcTopPredictor.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DcTopPredictor.cs
new file mode 100644
index 0000000000..93c98fcaaf
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1DcTopPredictor.cs
@@ -0,0 +1,49 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Runtime.CompilerServices;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+
+internal class Av1DcTopPredictor : IAv1Predictor
+{
+ private readonly uint blockWidth;
+ private readonly uint blockHeight;
+
+ public Av1DcTopPredictor(Size blockSize)
+ {
+ this.blockWidth = (uint)blockSize.Width;
+ this.blockHeight = (uint)blockSize.Height;
+ }
+
+ public Av1DcTopPredictor(Av1TransformSize transformSize)
+ {
+ this.blockWidth = (uint)transformSize.GetWidth();
+ this.blockHeight = (uint)transformSize.GetHeight();
+ }
+
+ public static void PredictScalar(Av1TransformSize transformSize, Span destination, nuint stride, Span above, Span left)
+ => new Av1DcTopPredictor(transformSize).PredictScalar(destination, stride, above, left);
+
+ public void PredictScalar(Span destination, nuint stride, Span above, Span left)
+ {
+ int sum = 0;
+ Guard.MustBeGreaterThanOrEqualTo(stride, this.blockWidth, nameof(stride));
+ Guard.MustBeSizedAtLeast(above, (int)this.blockWidth, nameof(above));
+ Guard.MustBeSizedAtLeast(destination, (int)this.blockHeight * (int)stride, nameof(destination));
+ ref byte aboveRef = ref above[0];
+ ref byte destinationRef = ref destination[0];
+ for (uint i = 0; i < this.blockWidth; i++)
+ {
+ sum += Unsafe.Add(ref aboveRef, i);
+ }
+
+ byte expectedDc = (byte)((sum + (this.blockWidth >> 1)) / this.blockWidth);
+ for (uint r = 0; r < this.blockHeight; r++)
+ {
+ Unsafe.InitBlock(ref destinationRef, expectedDc, this.blockWidth);
+ destinationRef = ref Unsafe.Add(ref destinationRef, stride);
+ }
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1NeighborNeed.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1NeighborNeed.cs
new file mode 100644
index 0000000000..81408fad31
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1NeighborNeed.cs
@@ -0,0 +1,15 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+
+[Flags]
+internal enum Av1NeighborNeed
+{
+ Nothing = 0,
+ Left = 2,
+ Above = 4,
+ AboveRight = 8,
+ AboveLeft = 16,
+ BottomLeft = 32,
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PredictionDecoder.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PredictionDecoder.cs
new file mode 100644
index 0000000000..483598aa2a
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PredictionDecoder.cs
@@ -0,0 +1,1081 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Runtime.CompilerServices;
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Prediction.ChromaFromLuma;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+
+internal class Av1PredictionDecoder
+{
+ private const int MaxUpsampleSize = 16;
+
+ private readonly ObuSequenceHeader sequenceHeader;
+ private readonly ObuFrameHeader frameHeader;
+ private readonly bool is16BitPipeline;
+
+ public Av1PredictionDecoder(ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader, bool is16BitPipeline)
+ {
+ this.sequenceHeader = sequenceHeader;
+ this.frameHeader = frameHeader;
+ this.is16BitPipeline = is16BitPipeline;
+ }
+
+ ///
+ /// SVT: svt_av1_predict_intra
+ ///
+ public void Decode(
+ Av1PartitionInfo partitionInfo,
+ Av1Plane plane,
+ Av1TransformSize transformSize,
+ Av1TileInfo tileInfo,
+ Span pixelBuffer,
+ int pixelStride,
+ Av1BitDepth bitDepth,
+ int blockModeInfoColumnOffset,
+ int blockModeInfoRowOffset)
+ {
+ int bytesPerPixel = (bitDepth == Av1BitDepth.EightBit && !this.is16BitPipeline) ? 2 : 1;
+ int stride = pixelStride * bytesPerPixel;
+
+ // Deviation from SVT: Buffer starts at PREVIOUS row.
+ Span topNeighbor = pixelBuffer;
+ Span leftNeighbor = pixelBuffer[(stride - 1)..];
+ Span startOfPixels = pixelBuffer[stride..];
+
+ bool is16BitPipeline = this.is16BitPipeline;
+ Av1PredictionMode mode = (plane == Av1Plane.Y) ? partitionInfo.ModeInfo.YMode : partitionInfo.ModeInfo.UvMode;
+
+ if (plane != Av1Plane.Y && partitionInfo.ModeInfo.UvMode == Av1PredictionMode.UvChromaFromLuma)
+ {
+ this.PredictIntraBlock(
+ partitionInfo,
+ plane,
+ transformSize,
+ tileInfo,
+ startOfPixels,
+ stride,
+ topNeighbor,
+ leftNeighbor,
+ stride,
+ mode,
+ blockModeInfoColumnOffset,
+ blockModeInfoRowOffset,
+ bitDepth);
+
+ this.PredictChromaFromLumaBlock(
+ partitionInfo,
+ partitionInfo.ChromaFromLumaContext,
+ startOfPixels,
+ stride,
+ transformSize,
+ plane);
+
+ return;
+ }
+
+ this.PredictIntraBlock(
+ partitionInfo,
+ plane,
+ transformSize,
+ tileInfo,
+ startOfPixels,
+ stride,
+ topNeighbor,
+ leftNeighbor,
+ stride,
+ mode,
+ blockModeInfoColumnOffset,
+ blockModeInfoRowOffset,
+ bitDepth);
+ }
+
+ private void PredictChromaFromLumaBlock(Av1PartitionInfo partitionInfo, Av1ChromaFromLumaContext? chromaFromLumaContext, Span pixelBuffer, int stride, Av1TransformSize transformSize, Av1Plane plane)
+ {
+ Av1BlockModeInfo modeInfo = partitionInfo.ModeInfo;
+ bool isChromaFromLumaAllowedFlag = IsChromaFromLumaAllowedWithFrameHeader(partitionInfo, this.sequenceHeader.ColorConfig, this.frameHeader);
+ DebugGuard.IsTrue(isChromaFromLumaAllowedFlag, "Chroma from Luma should be allowed then computing it.");
+
+ if (chromaFromLumaContext == null)
+ {
+ throw new InvalidOperationException("CFL context should have been defined already.");
+ }
+
+ if (!chromaFromLumaContext.AreParametersComputed)
+ {
+ chromaFromLumaContext.ComputeParameters(transformSize);
+ }
+
+ int alphaQ3 = ChromaFromLumaIndexToAlpha(modeInfo.ChromaFromLumaAlphaIndex, modeInfo.ChromaFromLumaAlphaSign, (Av1Plane)((int)plane - 1));
+
+ // assert((transformSize.GetHeight() - 1) * CFL_BUF_LINE + transformSize.GetWidth() <= CFL_BUF_SQUARE);
+ Av1BitDepth bitDepth = this.sequenceHeader.ColorConfig.BitDepth;
+ if ((bitDepth != Av1BitDepth.EightBit) || this.is16BitPipeline)
+ {
+ /* 16 bit pipeline
+ svt_cfl_predict_hbd(
+ chromaFromLumaContext->recon_buf_q3,
+ (uint16_t*)dst,
+ dst_stride,
+ (uint16_t*)dst,
+ dst_stride,
+ alpha_q3,
+ cc->bit_depth,
+ tx_size_wide[tx_size],
+ tx_size_high[tx_size]);
+ return;*/
+ }
+
+ ChromaFromLumaPredict(
+ chromaFromLumaContext.Q3Buffer!.DangerousGetSingleSpan(),
+ pixelBuffer,
+ stride,
+ pixelBuffer,
+ stride,
+ alphaQ3,
+ bitDepth,
+ transformSize.GetWidth(),
+ transformSize.GetHeight());
+ }
+
+ private static bool IsChromaFromLumaAllowedWithFrameHeader(Av1PartitionInfo partitionInfo, ObuColorConfig colorConfig, ObuFrameHeader frameHeader)
+ {
+ Av1BlockModeInfo modeInfo = partitionInfo.ModeInfo;
+ Av1BlockSize blockSize = modeInfo.BlockSize;
+ DebugGuard.MustBeGreaterThan((int)blockSize, (int)Av1BlockSize.AllSizes, nameof(blockSize));
+ if (frameHeader.LosslessArray[modeInfo.SegmentId])
+ {
+ // In lossless, CfL is available when the partition size is equal to the
+ // transform size.
+ bool subX = colorConfig.SubSamplingX;
+ bool subY = colorConfig.SubSamplingY;
+ Av1BlockSize planeBlockSize = blockSize.GetSubsampled(subX, subY);
+ return planeBlockSize == Av1BlockSize.Block4x4;
+ }
+
+ // Spec: CfL is available to luma partitions lesser than or equal to 32x32
+ return blockSize.GetWidth() <= 32 && blockSize.GetHeight() <= 32;
+ }
+
+ private static int ChromaFromLumaIndexToAlpha(int alphaIndex, int jointSign, Av1Plane plane)
+ {
+ int alphaSign = (plane == Av1Plane.U) ? Av1ChromaFromLumaMath.SignU(jointSign) : Av1ChromaFromLumaMath.SignV(jointSign);
+ if (alphaSign == Av1ChromaFromLumaMath.SignZero)
+ {
+ return 0;
+ }
+
+ int absAlphaQ3 = (plane == Av1Plane.U) ? Av1ChromaFromLumaMath.IndexU(alphaIndex) : Av1ChromaFromLumaMath.IndexV(alphaIndex);
+ return (alphaSign == Av1ChromaFromLumaMath.SignPositive) ? absAlphaQ3 + 1 : -absAlphaQ3 - 1;
+ }
+
+ private static int GetScaledLumaQ0(int alphaQ3, short predictedQ3)
+ {
+ int scaledLumaQ6 = alphaQ3 * predictedQ3;
+ return Av1Math.RoundPowerOf2Signed(scaledLumaQ6, 6);
+ }
+
+ private static void ChromaFromLumaPredict(Span predictedBufferQ3, Span predictedBuffer, int predictedStride, Span destinationBuffer, int destinationStride, int alphaQ3, Av1BitDepth bitDepth, int width, int height)
+ {
+ // TODO: Make SIMD variant of this method.
+ int maxPixelValue = (1 << bitDepth.GetBitCount()) - 1;
+ for (int j = 0; j < height; j++)
+ {
+ for (int i = 0; i < width; i++)
+ {
+ int alphaQ0 = GetScaledLumaQ0(alphaQ3, predictedBufferQ3[i]);
+ destinationBuffer[i] = (byte)Av1Math.Clamp(alphaQ0 + predictedBuffer[i], 0, maxPixelValue);
+ }
+
+ destinationBuffer = destinationBuffer[width..];
+ predictedBuffer = predictedBuffer[width..];
+ predictedBufferQ3 = predictedBufferQ3[width..];
+ }
+ }
+
+ private void PredictIntraBlock(
+ Av1PartitionInfo partitionInfo,
+ Av1Plane plane,
+ Av1TransformSize transformSize,
+ Av1TileInfo tileInfo,
+ Span pixelBuffer,
+ int pixelBufferStride,
+ Span topNeighbor,
+ Span leftNeighbor,
+ int referenceStride,
+ Av1PredictionMode mode,
+ int blockModeInfoColumnOffset,
+ int blockModeInfoRowOffset,
+ Av1BitDepth bitDepth)
+ {
+ // TODO:are_parameters_computed variable for CFL so that cal part for V plane we can skip,
+ // once we compute for U plane, this parameter is block level parameter.
+ ObuColorConfig cc = this.sequenceHeader.ColorConfig;
+ int subX = plane != Av1Plane.Y ? cc.SubSamplingX ? 1 : 0 : 0;
+ int subY = plane != Av1Plane.Y ? cc.SubSamplingY ? 1 : 0 : 0;
+
+ Av1BlockModeInfo modeInfo = partitionInfo.ModeInfo;
+
+ int transformWidth = transformSize.GetWidth();
+ int transformHeight = transformSize.GetHeight();
+
+ bool usePalette = modeInfo.GetPaletteSize(plane) > 0;
+
+ if (usePalette)
+ {
+ return;
+ }
+
+ Av1FilterIntraMode filterIntraMode = (plane == Av1Plane.Y && modeInfo.FilterIntraModeInfo.UseFilterIntra)
+ ? modeInfo.FilterIntraModeInfo.Mode : Av1FilterIntraMode.AllFilterIntraModes;
+
+ int angleDelta = modeInfo.AngleDelta[Math.Min(1, (int)plane)];
+
+ Av1BlockSize blockSize = modeInfo.BlockSize;
+ bool haveTop = blockModeInfoRowOffset > 0 || (subY > 0 ? partitionInfo.AvailableAboveForChroma : partitionInfo.AvailableAbove);
+ bool haveLeft = blockModeInfoColumnOffset > 0 || (subX > 0 ? partitionInfo.AvailableLeftForChroma : partitionInfo.AvailableLeft);
+
+ int modeInfoRow = -partitionInfo.ModeBlockToTopEdge >> (3 + Av1Constants.ModeInfoSizeLog2);
+ int modeInfoColumn = -partitionInfo.ModeBlockToLeftEdge >> (3 + Av1Constants.ModeInfoSizeLog2);
+ int xrOffset = 0;
+ int ydOffset = 0;
+
+ // Distance between right edge of this pred block to frame right edge
+ int xr = (partitionInfo.ModeBlockToRightEdge >> (3 + subX)) + (partitionInfo.WidthInPixels[(int)plane] - (blockModeInfoColumnOffset << Av1Constants.ModeInfoSizeLog2) - transformWidth) -
+ xrOffset;
+
+ // Distance between bottom edge of this pred block to frame bottom edge
+ int yd = (partitionInfo.ModeBlockToBottomEdge >> (3 + subY)) +
+ (partitionInfo.HeightInPixels[(int)plane] - (blockModeInfoRowOffset << Av1Constants.ModeInfoSizeLog2) - transformHeight) - ydOffset;
+ bool rightAvailable = modeInfoColumn + ((blockModeInfoColumnOffset + transformWidth) << subX) < tileInfo.ModeInfoColumnEnd;
+ bool bottomAvailable = (yd > 0) && (modeInfoRow + ((blockModeInfoRowOffset + transformHeight) << subY) < tileInfo.ModeInfoRowEnd);
+
+ Av1PartitionType partition = modeInfo.PartitionType;
+
+ // force 4x4 chroma component block size.
+ blockSize = ScaleChromaBlockSize(blockSize, subX == 1, subY == 1);
+
+ bool haveTopRight = IntraHasTopRight(
+ this.sequenceHeader.SuperblockSize,
+ blockSize,
+ modeInfoRow,
+ modeInfoColumn,
+ haveTop,
+ rightAvailable,
+ partition,
+ transformSize,
+ blockModeInfoRowOffset,
+ blockModeInfoColumnOffset,
+ subX,
+ subY);
+ bool haveBottomLeft = IntraHasBottomLeft(
+ this.sequenceHeader.SuperblockSize,
+ blockSize,
+ modeInfoRow,
+ modeInfoColumn,
+ bottomAvailable,
+ haveLeft,
+ partition,
+ transformSize,
+ blockModeInfoRowOffset,
+ blockModeInfoColumnOffset,
+ subX,
+ subY);
+
+ bool disableEdgeFilter = !this.sequenceHeader.EnableIntraEdgeFilter;
+
+ // Calling all other intra predictors except CFL & pallate...
+ if (bitDepth == Av1BitDepth.EightBit && !this.is16BitPipeline)
+ {
+ this.DecodeBuildIntraPredictors(
+ partitionInfo,
+ topNeighbor,
+ leftNeighbor,
+ (nuint)referenceStride,
+ pixelBuffer,
+ (nuint)pixelBufferStride,
+ mode,
+ angleDelta,
+ filterIntraMode,
+ transformSize,
+ disableEdgeFilter,
+ haveTop ? Math.Min(transformWidth, xr + transformWidth) : 0,
+ haveTopRight ? Math.Min(transformWidth, xr) : 0,
+ haveLeft ? Math.Min(transformHeight, yd + transformHeight) : 0,
+ haveBottomLeft ? Math.Min(transformHeight, yd) : 0,
+ plane);
+ }
+ else
+ {
+ /* 16bit
+ decode_build_intra_predictors_high(xd,
+ (uint16_t*) top_neigh_array, //As per SVT Enc
+ (uint16_t*) left_neigh_array,
+ ref_stride,// As per SVT Enc
+ (uint16_t*) pv_pred_buf,
+ pred_stride,
+ mode,
+ angle_delta,
+ filter_intra_mode,
+ tx_size,
+ disable_edge_filter,
+ have_top? AOMMIN(transformWidth, xr + transformWidth) : 0,
+ have_top_right? AOMMIN(transformWidth, xr) : 0,
+ have_left? AOMMIN(transformHeight, yd + transformHeight) : 0,
+ have_bottom_left? AOMMIN(transformHeight, yd) : 0,
+ plane,
+ bit_depth);
+ */
+ }
+ }
+
+ private static Av1BlockSize ScaleChromaBlockSize(Av1BlockSize blockSize, bool subX, bool subY)
+ {
+ Av1BlockSize bs = blockSize;
+ switch (blockSize)
+ {
+ case Av1BlockSize.Block4x4:
+ if (subX && subY)
+ {
+ bs = Av1BlockSize.Block8x8;
+ }
+ else if (subX)
+ {
+ bs = Av1BlockSize.Block8x4;
+ }
+ else if (subY)
+ {
+ bs = Av1BlockSize.Block4x8;
+ }
+
+ break;
+ case Av1BlockSize.Block4x8:
+ if (subX && subY)
+ {
+ bs = Av1BlockSize.Block8x8;
+ }
+ else if (subX)
+ {
+ bs = Av1BlockSize.Block8x8;
+ }
+ else if (subY)
+ {
+ bs = Av1BlockSize.Block4x8;
+ }
+
+ break;
+ case Av1BlockSize.Block8x4:
+ if (subX && subY)
+ {
+ bs = Av1BlockSize.Block8x8;
+ }
+ else if (subX)
+ {
+ bs = Av1BlockSize.Block8x4;
+ }
+ else if (subY)
+ {
+ bs = Av1BlockSize.Block8x8;
+ }
+
+ break;
+ case Av1BlockSize.Block4x16:
+ if (subX && subY)
+ {
+ bs = Av1BlockSize.Block8x16;
+ }
+ else if (subX)
+ {
+ bs = Av1BlockSize.Block8x16;
+ }
+ else if (subY)
+ {
+ bs = Av1BlockSize.Block4x16;
+ }
+
+ break;
+ case Av1BlockSize.Block16x4:
+ if (subX && subY)
+ {
+ bs = Av1BlockSize.Block16x8;
+ }
+ else if (subX)
+ {
+ bs = Av1BlockSize.Block16x4;
+ }
+ else if (subY)
+ {
+ bs = Av1BlockSize.Block16x8;
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ return bs;
+ }
+
+ private static bool IntraHasBottomLeft(Av1BlockSize superblockSize, Av1BlockSize blockSize, int modeInfoRow, int modeInfoColumn, bool bottomAvailable, bool haveLeft, Av1PartitionType partition, Av1TransformSize transformSize, int blockModeInfoRowOffset, int blockModeInfoColumnOffset, int subX, int subY)
+ {
+ if (!bottomAvailable || !haveLeft)
+ {
+ return false;
+ }
+
+ // Special case for 128x* blocks, when col_off is half the block width.
+ // This is needed because 128x* superblocks are divided into 64x* blocks in
+ // raster order
+ if (blockSize.GetWidth() > 64 && blockModeInfoColumnOffset > 0)
+ {
+ int planeBlockWidthInUnits64 = 64 >> subX;
+ int columnOffset64 = blockModeInfoColumnOffset % planeBlockWidthInUnits64;
+ if (columnOffset64 == 0)
+ {
+ // We are at the left edge of top-right or bottom-right 64x* block.
+ int planeBlockHeightInUnits64 = 64 >> subY;
+ int rowOffset64 = blockModeInfoRowOffset % planeBlockHeightInUnits64;
+ int planeBlockHeightInUnits = Math.Min(blockSize.Get4x4HighCount() >> subY, planeBlockHeightInUnits64);
+
+ // Check if all bottom-left pixels are in the left 64x* block (which is
+ // already coded).
+ return rowOffset64 + transformSize.Get4x4HighCount() < planeBlockHeightInUnits;
+ }
+ }
+
+ if (blockModeInfoColumnOffset > 0)
+ {
+ // Bottom-left pixels are in the bottom-left block, which is not available.
+ return false;
+ }
+ else
+ {
+ int blockHeightInUnits = blockSize.GetHeight() >> Av1TransformSize.Size4x4.GetBlockHeightLog2();
+ int planeBlockHeightInUnits = Math.Max(blockHeightInUnits >> subY, 1);
+ int bottomLeftUnitCount = transformSize.Get4x4HighCount();
+
+ // All bottom-left pixels are in the left block, which is already available.
+ if (blockModeInfoRowOffset + bottomLeftUnitCount < planeBlockHeightInUnits)
+ {
+ return true;
+ }
+
+ int blockWidthInModeInfoLog2 = blockSize.Get4x4WidthLog2();
+ int blockHeightInModeInfoLog2 = blockSize.Get4x4HeightLog2();
+ int superblockModeInfoSize = superblockSize.Get4x4HighCount();
+ int blockRowInSuperblock = (modeInfoRow & (superblockModeInfoSize - 1)) >> blockHeightInModeInfoLog2;
+ int blockColumnInSuperblock = (modeInfoColumn & (superblockModeInfoSize - 1)) >> blockWidthInModeInfoLog2;
+
+ // Leftmost column of superblock: so bottom-left pixels maybe in the left
+ // and/or bottom-left superblocks. But only the left superblock is
+ // available, so check if all required pixels fall in that superblock.
+ if (blockColumnInSuperblock == 0)
+ {
+ int blockStartRowOffset = blockRowInSuperblock << (blockHeightInModeInfoLog2 + Av1Constants.ModeInfoSizeLog2 - Av1TransformSize.Size4x4.GetBlockWidthLog2()) >> subY;
+ int rowOffsetInSuperblock = blockStartRowOffset + blockModeInfoRowOffset;
+ int superblockHeightInUnits = superblockModeInfoSize >> subY;
+ return rowOffsetInSuperblock + bottomLeftUnitCount < superblockHeightInUnits;
+ }
+
+ // Bottom row of superblock (and not the leftmost column): so bottom-left
+ // pixels fall in the bottom superblock, which is not available yet.
+ if (((blockRowInSuperblock + 1) << blockHeightInModeInfoLog2) >= superblockModeInfoSize)
+ {
+ return false;
+ }
+
+ // General case (neither leftmost column nor bottom row): check if the
+ // bottom-left block is coded before the current block.
+ int thisBlockIndex = ((blockRowInSuperblock + 0) << (Av1Constants.MaxSuperBlockSizeLog2 - Av1Constants.ModeInfoSizeLog2 - blockWidthInModeInfoLog2)) + blockColumnInSuperblock + 0;
+ return Av1BottomRightTopLeftConstants.HasBottomLeft(partition, blockSize, thisBlockIndex);
+ }
+ }
+
+ private static bool IntraHasTopRight(Av1BlockSize superblockSize, Av1BlockSize blockSize, int modeInfoRow, int modeInfoColumn, bool haveTop, bool rightAvailable, Av1PartitionType partition, Av1TransformSize transformSize, int blockModeInfoRowOffset, int blockModeInfoColumnOffset, int subX, int subY)
+ {
+ if (!haveTop || !rightAvailable)
+ {
+ return false;
+ }
+
+ int blockWideInUnits = blockSize.GetWidth() >> 2;
+ int planeBlockWidthInUnits = Math.Max(blockWideInUnits >> subX, 1);
+ int topRightUnitCount = transformSize.Get4x4WideCount();
+
+ if (blockModeInfoRowOffset > 0)
+ { // Just need to check if enough pixels on the right.
+ if (blockSize.GetWidth() > 64)
+ {
+ // Special case: For 128x128 blocks, the transform unit whose
+ // top-right corner is at the center of the block does in fact have
+ // pixels available at its top-right corner.
+ if (blockModeInfoRowOffset == 64 >> subY &&
+ blockModeInfoColumnOffset + topRightUnitCount == 64 >> subX)
+ {
+ return true;
+ }
+
+ int planeBlockWidthInUnits64 = 64 >> subX;
+ int blockModeInfoColumnOffset64 = blockModeInfoColumnOffset % planeBlockWidthInUnits64;
+ return blockModeInfoColumnOffset64 + topRightUnitCount < planeBlockWidthInUnits64;
+ }
+
+ return blockModeInfoColumnOffset + topRightUnitCount < planeBlockWidthInUnits;
+ }
+ else
+ {
+ // All top-right pixels are in the block above, which is already available.
+ if (blockModeInfoColumnOffset + topRightUnitCount < planeBlockWidthInUnits)
+ {
+ return true;
+ }
+
+ int blockWidthInModeInfoLog2 = blockSize.Get4x4WidthLog2();
+ int blockHeightInModeInfeLog2 = blockSize.Get4x4HeightLog2();
+ int superBlockModeInfoSize = superblockSize.Get4x4HighCount();
+ int blockRowInSuperblock = (modeInfoRow & (superBlockModeInfoSize - 1)) >> blockHeightInModeInfeLog2;
+ int blockColumnInSuperBlock = (modeInfoColumn & (superBlockModeInfoSize - 1)) >> blockWidthInModeInfoLog2;
+
+ // Top row of superblock: so top-right pixels are in the top and/or
+ // top-right superblocks, both of which are already available.
+ if (blockRowInSuperblock == 0)
+ {
+ return true;
+ }
+
+ // Rightmost column of superblock (and not the top row): so top-right pixels
+ // fall in the right superblock, which is not available yet.
+ if (((blockColumnInSuperBlock + 1) << blockWidthInModeInfoLog2) >= superBlockModeInfoSize)
+ {
+ return false;
+ }
+
+ // General case (neither top row nor rightmost column): check if the
+ // top-right block is coded before the current block.
+ int thisBlockIndex = ((blockRowInSuperblock + 0) << (Av1Constants.MaxSuperBlockSizeLog2 - Av1Constants.ModeInfoSizeLog2 - blockWidthInModeInfoLog2)) + blockColumnInSuperBlock + 0;
+ return Av1BottomRightTopLeftConstants.HasTopRight(partition, blockSize, thisBlockIndex);
+ }
+ }
+
+ private void DecodeBuildIntraPredictors(
+ Av1PartitionInfo partitionInfo,
+ Span aboveNeighbor,
+ Span leftNeighbor,
+ nuint referenceStride,
+ Span destination,
+ nuint destinationStride,
+ Av1PredictionMode mode,
+ int angleDelta,
+ Av1FilterIntraMode filterIntraMode,
+ Av1TransformSize transformSize,
+ bool disableEdgeFilter,
+ int topPixelCount,
+ int topRightPixelCount,
+ int leftPixelCount,
+ int bottomLeftPixelCount,
+ Av1Plane plane)
+ {
+ Span aboveData = stackalloc byte[(Av1Constants.MaxTransformSize * 2) + 32];
+ Span leftData = stackalloc byte[(Av1Constants.MaxTransformSize * 2) + 32];
+ Span aboveRow = aboveData[16..];
+ Span leftColumn = leftData[16..];
+ int transformWidth = transformSize.GetWidth();
+ int transformHeight = transformSize.GetHeight();
+ bool isDirectionalMode = mode.IsDirectional();
+ Av1NeighborNeed need = mode.GetNeighborNeed();
+ bool needLeft = (need & Av1NeighborNeed.Left) == Av1NeighborNeed.Left;
+ bool needAbove = (need & Av1NeighborNeed.Above) == Av1NeighborNeed.Above;
+ bool needAboveLeft = (need & Av1NeighborNeed.AboveLeft) == Av1NeighborNeed.AboveLeft;
+ int angle = 0;
+ bool useFilterIntra = filterIntraMode != Av1FilterIntraMode.AllFilterIntraModes;
+
+ if (isDirectionalMode)
+ {
+ angle = mode.ToAngle() + (angleDelta * Av1Constants.AngleStep);
+ if (angle <= 90)
+ {
+ needAbove = true;
+ needLeft = false;
+ needAboveLeft = true;
+ }
+ else if (angle < 180)
+ {
+ needAbove = true;
+ needLeft = true;
+ needAboveLeft = true;
+ }
+ else
+ {
+ needAbove = false;
+ needLeft = true;
+ needAboveLeft = true;
+ }
+ }
+
+ if (useFilterIntra)
+ {
+ needAbove = true;
+ needLeft = true;
+ needAboveLeft = true;
+ }
+
+ DebugGuard.MustBeGreaterThanOrEqualTo(topPixelCount, 0, nameof(topPixelCount));
+ DebugGuard.MustBeGreaterThanOrEqualTo(topRightPixelCount, 0, nameof(topRightPixelCount));
+ DebugGuard.MustBeGreaterThanOrEqualTo(leftPixelCount, 0, nameof(leftPixelCount));
+ DebugGuard.MustBeGreaterThanOrEqualTo(bottomLeftPixelCount, 0, nameof(bottomLeftPixelCount));
+
+ if ((!needAbove && leftPixelCount == 0) || (!needLeft && topPixelCount == 0))
+ {
+ byte val;
+ if (needLeft)
+ {
+ val = (byte)((topPixelCount > 0) ? aboveNeighbor[0] : 129);
+ }
+ else
+ {
+ val = (byte)((leftPixelCount > 0) ? leftNeighbor[0] : 127);
+ }
+
+ ref byte destinationRef = ref destination[0];
+ for (int i = 0; i < transformHeight; ++i)
+ {
+ Unsafe.InitBlock(ref destinationRef, val, (uint)transformWidth);
+ destinationRef = ref Unsafe.Add(ref destinationRef, destinationStride);
+ }
+
+ return;
+ }
+
+ // NEED_LEFT
+ if (needLeft)
+ {
+ bool needBottom = (need & Av1NeighborNeed.BottomLeft) == Av1NeighborNeed.BottomLeft;
+ if (useFilterIntra)
+ {
+ needBottom = false;
+ }
+
+ if (isDirectionalMode)
+ {
+ needBottom = angle > 180;
+ }
+
+ uint numLeftPixelsNeeded = (uint)(transformHeight + (needBottom ? transformWidth : 0));
+ int i = 0;
+ if (leftPixelCount > 0)
+ {
+ for (; i < leftPixelCount; i++)
+ {
+ leftColumn[i] = leftNeighbor[i * (int)referenceStride];
+ }
+
+ if (needBottom && bottomLeftPixelCount > 0)
+ {
+ Guard.IsTrue(i == transformHeight, nameof(i), string.Empty);
+ for (; i < transformHeight + bottomLeftPixelCount; i++)
+ {
+ leftColumn[i] = leftNeighbor[i * (int)referenceStride];
+ }
+ }
+
+ if (i < numLeftPixelsNeeded)
+ {
+ Unsafe.InitBlock(ref leftColumn[i], leftColumn[i - 1], numLeftPixelsNeeded - (uint)i);
+ }
+ }
+ else
+ {
+ if (topPixelCount > 0)
+ {
+ Unsafe.InitBlock(ref leftColumn[0], aboveNeighbor[0], numLeftPixelsNeeded);
+ }
+ else
+ {
+ Unsafe.InitBlock(ref leftColumn[0], 129, numLeftPixelsNeeded);
+ }
+ }
+ }
+
+ // NEED_ABOVE
+ if (needAbove)
+ {
+ bool needRight = (need & Av1NeighborNeed.AboveRight) == Av1NeighborNeed.AboveRight;
+ if (useFilterIntra)
+ {
+ needRight = false;
+ }
+
+ if (isDirectionalMode)
+ {
+ needRight = angle < 90;
+ }
+
+ uint numTopPixelsNeeded = (uint)(transformWidth + (needRight ? transformHeight : 0));
+ if (topPixelCount > 0)
+ {
+ Unsafe.CopyBlock(ref aboveRow[0], ref aboveNeighbor[0], (uint)topPixelCount);
+ int i = topPixelCount;
+ if (needRight && topPixelCount > 0)
+ {
+ Guard.IsTrue(topPixelCount == transformWidth, nameof(topPixelCount), string.Empty);
+ Unsafe.CopyBlock(ref aboveRow[transformWidth], ref aboveNeighbor[transformWidth], (uint)topPixelCount);
+ i += topPixelCount;
+ }
+
+ if (i < numTopPixelsNeeded)
+ {
+ Unsafe.InitBlock(ref aboveRow[i], aboveRow[i - 1], numTopPixelsNeeded - (uint)i);
+ }
+ }
+ else
+ {
+ if (leftPixelCount > 0)
+ {
+ Unsafe.InitBlock(ref aboveRow[0], leftNeighbor[0], numTopPixelsNeeded);
+ }
+ else
+ {
+ Unsafe.InitBlock(ref aboveRow[0], 127, numTopPixelsNeeded);
+ }
+ }
+ }
+
+ if (needAboveLeft)
+ {
+ if (topPixelCount > 0 && leftPixelCount > 0)
+ {
+ aboveRow[-1] = aboveNeighbor[-1];
+ }
+ else if (topPixelCount > 0)
+ {
+ aboveRow[-1] = aboveNeighbor[0];
+ }
+ else if (leftPixelCount > 0)
+ {
+ aboveRow[-1] = leftNeighbor[0];
+ }
+ else
+ {
+ aboveRow[-1] = 128;
+ }
+
+ leftColumn[-1] = aboveRow[-1];
+ }
+
+ if (useFilterIntra)
+ {
+ Av1PredictorFactory.FilterIntraPredictor(destination, destinationStride, transformSize, aboveRow, leftColumn, filterIntraMode);
+ return;
+ }
+
+ if (isDirectionalMode)
+ {
+ bool upsampleAbove = false;
+ bool upsampleLeft = false;
+ if (!disableEdgeFilter)
+ {
+ bool needRight = angle < 90;
+ bool needBottom = angle > 180;
+
+ bool filterType = GetFilterType(partitionInfo, plane);
+
+ if (angle is not 90 and not 180)
+ {
+ int ab_le = needAboveLeft ? 1 : 0;
+ if (needAbove && needLeft && (transformWidth + transformHeight >= 24))
+ {
+ FilterIntraEdgeCorner(aboveRow, leftColumn);
+ }
+
+ if (needAbove && topPixelCount > 0)
+ {
+ int strength = IntraEdgeFilterStrength(transformWidth, transformHeight, angle - 90, filterType);
+ int pixelCount = topPixelCount + ab_le + (needRight ? transformHeight : 0);
+ FilterIntraEdge(ref Unsafe.Subtract(ref aboveRow[0], ab_le), pixelCount, strength);
+ }
+
+ if (needLeft && leftPixelCount > 0)
+ {
+ int strength = IntraEdgeFilterStrength(transformHeight, transformWidth, angle - 180, filterType);
+ int pixelCount = leftPixelCount + ab_le + (needBottom ? transformWidth : 0);
+ FilterIntraEdge(ref Unsafe.Subtract(ref leftColumn[0], ab_le), pixelCount, strength);
+ }
+ }
+
+ upsampleAbove = UseIntraEdgeUpsample(transformWidth, transformHeight, angle - 90, filterType);
+ if (needAbove && upsampleAbove)
+ {
+ int pixelCount = transformWidth + (needRight ? transformHeight : 0);
+
+ UpsampleIntraEdge(aboveRow, pixelCount);
+ }
+
+ upsampleLeft = UseIntraEdgeUpsample(transformHeight, transformWidth, angle - 180, filterType);
+ if (needLeft && upsampleLeft)
+ {
+ int pixelCount = transformHeight + (needBottom ? transformWidth : 0);
+
+ UpsampleIntraEdge(leftColumn, pixelCount);
+ }
+ }
+
+ Av1PredictorFactory.DirectionalPredictor(destination, destinationStride, transformSize, aboveRow, leftColumn, upsampleAbove, upsampleLeft, angle);
+ return;
+ }
+
+ // predict
+ if (mode == Av1PredictionMode.DC)
+ {
+ Av1PredictorFactory.DcPredictor(leftPixelCount > 0, topPixelCount > 0, transformSize, destination, destinationStride, aboveRow, leftColumn);
+ }
+ else
+ {
+ Av1PredictorFactory.GeneralPredictor(mode, transformSize, destination, destinationStride, aboveRow, leftColumn);
+ }
+ }
+
+ private static void UpsampleIntraEdge(Span buffer, int count)
+ {
+ // TODO: Consider creating SIMD version
+
+ // interpolate half-sample positions
+ Guard.MustBeLessThanOrEqualTo(count, MaxUpsampleSize, nameof(count));
+
+ Span input = stackalloc byte[MaxUpsampleSize + 3];
+ byte beforeBuffer = Unsafe.Subtract(ref buffer[0], 1);
+
+ // copy p[-1..(sz-1)] and extend first and last samples
+ input[0] = beforeBuffer;
+ input[1] = beforeBuffer;
+ for (int i = 0; i < count; i++)
+ {
+ input[i + 2] = buffer[i];
+ }
+
+ input[count + 2] = buffer[count - 1];
+
+ // interpolate half-sample edge positions
+ buffer[-2] = input[0];
+ for (int i = 0; i < count; i++)
+ {
+ int s = -input[i] + (9 * input[i + 1]) + (9 * input[i + 2]) - input[i + 3];
+ s = Av1Math.Clamp((s + 8) >> 4, 0, 255);
+ buffer[(2 * i) - 1] = (byte)s;
+ buffer[2 * i] = input[i + 2];
+ }
+ }
+
+ private static bool UseIntraEdgeUpsample(int width, int height, int delta, bool type)
+ {
+ int d = Math.Abs(delta);
+ int widthHeight = width + height;
+ if (d is <= 0 or >= 40)
+ {
+ return false;
+ }
+
+ return type ? (widthHeight <= 8) : (widthHeight <= 16);
+ }
+
+ private static void FilterIntraEdge(ref byte buffer, int count, int strength)
+ {
+ // TODO: Consider creating SIMD version
+ if (strength == 0)
+ {
+ return;
+ }
+
+ int[][] kernel = [
+ [0, 4, 8, 4, 0], [0, 5, 6, 5, 0], [2, 4, 4, 4, 2]
+ ];
+ int filt = strength - 1;
+ Span edge = stackalloc byte[129];
+
+ Unsafe.CopyBlock(ref edge[0], ref buffer, (uint)count);
+ for (int i = 1; i < count; i++)
+ {
+ int s = 0;
+ for (int j = 0; j < 5; j++)
+ {
+ int k = i - 2 + j;
+ k = (k < 0) ? 0 : k;
+ k = (k > count - 1) ? count - 1 : k;
+ s += edge[k] * kernel[filt][j];
+ }
+
+ s = (s + 8) >> 4;
+ Unsafe.Add(ref buffer, i) = (byte)s;
+ }
+ }
+
+ private static int IntraEdgeFilterStrength(int width, int height, int delta, bool filterType)
+ {
+ int d = Math.Abs(delta);
+ int strength = 0;
+ int widthHeight = width + height;
+ if (!filterType)
+ {
+ if (widthHeight <= 8)
+ {
+ if (d >= 56)
+ {
+ strength = 1;
+ }
+ }
+ else if (widthHeight <= 12)
+ {
+ if (d >= 40)
+ {
+ strength = 1;
+ }
+ }
+ else if (widthHeight <= 16)
+ {
+ if (d >= 40)
+ {
+ strength = 1;
+ }
+ }
+ else if (widthHeight <= 24)
+ {
+ if (d >= 8)
+ {
+ strength = 1;
+ }
+
+ if (d >= 16)
+ {
+ strength = 2;
+ }
+
+ if (d >= 32)
+ {
+ strength = 3;
+ }
+ }
+ else if (widthHeight <= 32)
+ {
+ if (d >= 1)
+ {
+ strength = 1;
+ }
+
+ if (d >= 4)
+ {
+ strength = 2;
+ }
+
+ if (d >= 32)
+ {
+ strength = 3;
+ }
+ }
+ else
+ {
+ if (d >= 1)
+ {
+ strength = 3;
+ }
+ }
+ }
+ else
+ {
+ if (widthHeight <= 8)
+ {
+ if (d >= 40)
+ {
+ strength = 1;
+ }
+
+ if (d >= 64)
+ {
+ strength = 2;
+ }
+ }
+ else if (widthHeight <= 16)
+ {
+ if (d >= 20)
+ {
+ strength = 1;
+ }
+
+ if (d >= 48)
+ {
+ strength = 2;
+ }
+ }
+ else if (widthHeight <= 24)
+ {
+ if (d >= 4)
+ {
+ strength = 3;
+ }
+ }
+ else
+ {
+ if (d >= 1)
+ {
+ strength = 3;
+ }
+ }
+ }
+
+ return strength;
+ }
+
+ private static void FilterIntraEdgeCorner(Span above, Span left)
+ {
+ int[] kernel = [5, 6, 5];
+
+ ref byte aboveRef = ref above[0];
+ ref byte leftRef = ref left[0];
+ ref byte abovePreviousRef = ref Unsafe.Subtract(ref aboveRef, 1);
+ ref byte leftPreviousRef = ref Unsafe.Subtract(ref leftRef, 1);
+ int s = (leftRef * kernel[0]) + (abovePreviousRef * kernel[1]) + (aboveRef * kernel[2]);
+ s = (s + 8) >> 4;
+ abovePreviousRef = (byte)s;
+ leftPreviousRef = (byte)s;
+ }
+
+ private static bool GetFilterType(Av1PartitionInfo partitionInfo, Av1Plane plane)
+ {
+ Av1BlockModeInfo? above;
+ Av1BlockModeInfo? left;
+ if (plane == Av1Plane.Y)
+ {
+ above = partitionInfo.AboveModeInfo;
+ left = partitionInfo.LeftModeInfo;
+ }
+ else
+ {
+ above = partitionInfo.AboveModeInfoForChroma;
+ left = partitionInfo.LeftModeInfoForChroma;
+ }
+
+ bool aboveIsSmooth = (above != null) && IsSmooth(above, plane);
+ bool leftIsSmooth = (left != null) && IsSmooth(left, plane);
+ return aboveIsSmooth || leftIsSmooth;
+ }
+
+ private static bool IsSmooth(Av1BlockModeInfo modeInfo, Av1Plane plane)
+ {
+ if (plane == Av1Plane.Y)
+ {
+ Av1PredictionMode mode = modeInfo.YMode;
+ return mode is Av1PredictionMode.Smooth or
+ Av1PredictionMode.SmoothVertical or
+ Av1PredictionMode.SmoothHorizontal;
+ }
+ else
+ {
+ // Inter mode not supported here.
+ Av1PredictionMode uvMode = modeInfo.UvMode;
+ return uvMode is Av1PredictionMode.Smooth or
+ Av1PredictionMode.SmoothVertical or
+ Av1PredictionMode.SmoothHorizontal;
+ }
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PredictionMode.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PredictionMode.cs
new file mode 100644
index 0000000000..86d9e96c77
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PredictionMode.cs
@@ -0,0 +1,28 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+
+// Inter modes are not defined here, as they do not apply to pictures.
+internal enum Av1PredictionMode
+{
+ DC,
+ Vertical,
+ Horizontal,
+ Directional45Degrees,
+ Directional135Degrees,
+ Directional113Degrees,
+ Directional157Degrees,
+ Directional203Degrees,
+ Directional67Degrees,
+ Smooth,
+ SmoothVertical,
+ SmoothHorizontal,
+ Paeth,
+ UvChromaFromLuma,
+ IntraModeStart = DC,
+ IntraModeEnd = Paeth + 1,
+ IntraModes = Paeth,
+ UvIntraModes = UvChromaFromLuma + 1,
+ IntraInvalid = 25,
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PredictorFactory.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PredictorFactory.cs
new file mode 100644
index 0000000000..9cddf0de38
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PredictorFactory.cs
@@ -0,0 +1,42 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+
+internal class Av1PredictorFactory
+{
+ internal static void DcPredictor(bool hasLeft, bool hasAbove, Av1TransformSize transformSize, Span destination, nuint destinationStride, Span aboveRow, Span leftColumn)
+ {
+ if (hasLeft)
+ {
+ if (hasAbove)
+ {
+ Av1DcPredictor.PredictScalar(transformSize, destination, destinationStride, aboveRow, leftColumn);
+ }
+ else
+ {
+ Av1DcLeftPredictor.PredictScalar(transformSize, destination, destinationStride, aboveRow, leftColumn);
+ }
+ }
+ else
+ {
+ if (hasAbove)
+ {
+ Av1DcTopPredictor.PredictScalar(transformSize, destination, destinationStride, aboveRow, leftColumn);
+ }
+ else
+ {
+ Av1DcFillPredictor.PredictScalar(transformSize, destination, destinationStride, aboveRow, leftColumn);
+ }
+ }
+ }
+
+ internal static void DirectionalPredictor(Span destination, nuint destinationStride, Av1TransformSize transformSize, Span aboveRow, Span leftColumn, bool upsampleAbove, bool upsampleLeft, int angle) => throw new NotImplementedException();
+
+ internal static void FilterIntraPredictor(Span destination, nuint destinationStride, Av1TransformSize transformSize, Span aboveRow, Span leftColumn, Av1FilterIntraMode filterIntraMode) => throw new NotImplementedException();
+
+ internal static void GeneralPredictor(Av1PredictionMode mode, Av1TransformSize transformSize, Span destination, nuint destinationStride, Span aboveRow, Span leftColumn) => throw new NotImplementedException();
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PreditionModeExtensions.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PreditionModeExtensions.cs
new file mode 100644
index 0000000000..2b2ca3e4f3
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/Av1PreditionModeExtensions.cs
@@ -0,0 +1,67 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+
+internal static class Av1PreditionModeExtensions
+{
+ private static readonly Av1TransformType[] IntraPreditionMode2TransformType = [
+ Av1TransformType.DctDct, // DC
+ Av1TransformType.AdstDct, // V
+ Av1TransformType.DctAdst, // H
+ Av1TransformType.DctDct, // D45
+ Av1TransformType.AdstAdst, // D135
+ Av1TransformType.AdstDct, // D117
+ Av1TransformType.DctAdst, // D153
+ Av1TransformType.DctAdst, // D207
+ Av1TransformType.AdstDct, // D63
+ Av1TransformType.AdstAdst, // SMOOTH
+ Av1TransformType.AdstDct, // SMOOTH_V
+ Av1TransformType.DctAdst, // SMOOTH_H
+ Av1TransformType.AdstAdst, // PAETH
+ ];
+
+ private static readonly Av1NeighborNeed[] NeedsMap = [
+ Av1NeighborNeed.Above | Av1NeighborNeed.Left, // DC
+ Av1NeighborNeed.Above, // V
+ Av1NeighborNeed.Left, // H
+ Av1NeighborNeed.Above | Av1NeighborNeed.AboveRight, // D45
+ Av1NeighborNeed.Left | Av1NeighborNeed.Above | Av1NeighborNeed.AboveLeft, // D135
+ Av1NeighborNeed.Left | Av1NeighborNeed.Above | Av1NeighborNeed.AboveLeft, // D113
+ Av1NeighborNeed.Left | Av1NeighborNeed.Above | Av1NeighborNeed.AboveLeft, // D157
+ Av1NeighborNeed.Left | Av1NeighborNeed.BottomLeft, // D203
+ Av1NeighborNeed.Above | Av1NeighborNeed.AboveRight, // D67
+ Av1NeighborNeed.Left | Av1NeighborNeed.Above, // SMOOTH
+ Av1NeighborNeed.Left | Av1NeighborNeed.Above, // SMOOTH_V
+ Av1NeighborNeed.Left | Av1NeighborNeed.Above, // SMOOTH_H
+ Av1NeighborNeed.Left | Av1NeighborNeed.Above | Av1NeighborNeed.AboveLeft, // PAETH
+ ];
+
+ private static readonly int[] AngleMap = [
+ 0,
+ 90,
+ 180,
+ 45,
+ 135,
+ 113,
+ 157,
+ 203,
+ 67,
+ 0,
+ 0,
+ 0,
+ 0,
+ ];
+
+ public static Av1TransformType ToTransformType(this Av1PredictionMode mode) => IntraPreditionMode2TransformType[(int)mode];
+
+ public static bool IsDirectional(this Av1PredictionMode mode)
+ => mode is >= Av1PredictionMode.Vertical and <= Av1PredictionMode.Directional67Degrees;
+
+ public static Av1NeighborNeed GetNeighborNeed(this Av1PredictionMode mode) => NeedsMap[(int)mode];
+
+ public static int ToAngle(this Av1PredictionMode mode) => AngleMap[(int)mode];
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/ChromaFromLuma/Av1ChromaFromLumaContext.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/ChromaFromLuma/Av1ChromaFromLumaContext.cs
new file mode 100644
index 0000000000..c8112028db
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/ChromaFromLuma/Av1ChromaFromLumaContext.cs
@@ -0,0 +1,120 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Runtime.CompilerServices;
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+using SixLabors.ImageSharp.Memory;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction.ChromaFromLuma;
+
+internal class Av1ChromaFromLumaContext
+{
+ private const int BufferLine = 32;
+
+ private int bufferHeight;
+ private int bufferWidth;
+ private readonly bool subX;
+ private readonly bool subY;
+
+ public Av1ChromaFromLumaContext(Configuration configuration, ObuColorConfig colorConfig)
+ {
+ this.subX = colorConfig.SubSamplingX;
+ this.subY = colorConfig.SubSamplingY;
+ this.Q3Buffer = configuration.MemoryAllocator.Allocate2D(new Size(32, 32), AllocationOptions.Clean);
+ }
+
+ public Buffer2D Q3Buffer { get; private set; }
+
+ public bool AreParametersComputed { get; private set; }
+
+ public void ComputeParameters(Av1TransformSize transformSize)
+ {
+ Guard.IsFalse(this.AreParametersComputed, nameof(this.AreParametersComputed), "Do not call cfl_compute_parameters multiple time on the same values.");
+ this.Pad(transformSize.GetWidth(), transformSize.GetHeight());
+ SubtractAverage(ref this.Q3Buffer[0, 0], transformSize);
+ this.AreParametersComputed = true;
+ }
+
+ private void Pad(int width, int height)
+ {
+ int diff_width = width - this.bufferWidth;
+ int diff_height = height - this.bufferHeight;
+
+ if (diff_width > 0)
+ {
+ int min_height = height - diff_height;
+ ref short recon_buf_q3 = ref this.Q3Buffer[width - diff_width, 0];
+ for (int j = 0; j < min_height; j++)
+ {
+ short last_pixel = Unsafe.Subtract(ref recon_buf_q3, 1);
+ Guard.IsTrue(Unsafe.IsAddressLessThan(ref Unsafe.Add(ref recon_buf_q3, diff_width), ref this.Q3Buffer[BufferLine, BufferLine]), nameof(recon_buf_q3), "Shall stay within bounds.");
+ for (int i = 0; i < diff_width; i++)
+ {
+ Unsafe.Add(ref recon_buf_q3, i) = last_pixel;
+ }
+
+ recon_buf_q3 += BufferLine;
+ }
+
+ this.bufferWidth = width;
+ }
+
+ if (diff_height > 0)
+ {
+ ref short recon_buf_q3 = ref this.Q3Buffer[0, height - diff_height];
+ for (int j = 0; j < diff_height; j++)
+ {
+ ref short last_row_q3 = ref Unsafe.Subtract(ref recon_buf_q3, BufferLine);
+ Guard.IsTrue(Unsafe.IsAddressLessThan(ref Unsafe.Add(ref recon_buf_q3, diff_width), ref this.Q3Buffer[BufferLine, BufferLine]), nameof(recon_buf_q3), "Shall stay within bounds.");
+ for (int i = 0; i < width; i++)
+ {
+ Unsafe.Add(ref recon_buf_q3, i) = Unsafe.Add(ref last_row_q3, i);
+ }
+
+ recon_buf_q3 += BufferLine;
+ }
+
+ this.bufferHeight = height;
+ }
+ }
+
+ /************************************************************************************************
+ * svt_subtract_average_c
+ * Calculate the DC value by averaging over all sample. Subtract DC value to get AC values In C
+ ************************************************************************************************/
+ private static void SubtractAverage(ref short pred_buf_q3, Av1TransformSize transformSize)
+ {
+ int width = transformSize.GetWidth();
+ int height = transformSize.GetHeight();
+ int roundOffset = (width * height) >> 1;
+ int pelCountLog2 = transformSize.GetBlockWidthLog2() + transformSize.GetBlockHeightLog2();
+ int sum_q3 = 0;
+ ref short pred_buf = ref pred_buf_q3;
+ for (int j = 0; j < height; j++)
+ {
+ // assert(pred_buf_q3 + tx_width <= cfl->pred_buf_q3 + CFL_BUF_SQUARE);
+ for (int i = 0; i < width; i++)
+ {
+ sum_q3 += Unsafe.Add(ref pred_buf, i);
+ }
+
+ pred_buf += BufferLine;
+ }
+
+ int avg_q3 = (sum_q3 + roundOffset) >> pelCountLog2;
+
+ // Loss is never more than 1/2 (in Q3)
+ // assert(abs((avg_q3 * (1 << num_pel_log2)) - sum_q3) <= 1 << num_pel_log2 >>
+ // 1);
+ for (int j = 0; j < height; j++)
+ {
+ for (int i = 0; i < width; i++)
+ {
+ Unsafe.Add(ref pred_buf_q3, i) -= (short)avg_q3;
+ }
+
+ pred_buf_q3 += BufferLine;
+ }
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/ChromaFromLuma/Av1ChromaFromLumaMath.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/ChromaFromLuma/Av1ChromaFromLumaMath.cs
new file mode 100644
index 0000000000..8f3fce0164
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/ChromaFromLuma/Av1ChromaFromLumaMath.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction.ChromaFromLuma;
+
+internal static class Av1ChromaFromLumaMath
+{
+ private const int Signs = 3;
+ private const int AlphabetSizeLog2 = 4;
+
+ public const int SignZero = 0;
+ public const int SignNegative = 1;
+ public const int SignPositive = 2;
+
+ public static int SignU(int jointSign) => ((jointSign + 1) * 11) >> 5;
+
+ public static int SignV(int jointSign) => (jointSign + 1) - (Signs * SignU(jointSign));
+
+ public static int IndexU(int index) => index >> AlphabetSizeLog2;
+
+ public static int IndexV(int index) => index & (AlphabetSizeLog2 - 1);
+
+ public static int ContextU(int jointSign) => jointSign + 1 - Signs;
+
+ public static int ContextV(int jointSign) => (SignV(jointSign) * Signs) + SignU(jointSign) - Signs;
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Prediction/IAv1Predictor.cs b/src/ImageSharp/Formats/Heif/Av1/Prediction/IAv1Predictor.cs
new file mode 100644
index 0000000000..567e6c6520
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Prediction/IAv1Predictor.cs
@@ -0,0 +1,19 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+
+///
+/// Interface for predictor implementations.
+///
+internal interface IAv1Predictor
+{
+ ///
+ /// Predict using scalar logic within the 8-bit pipeline.
+ ///
+ /// The destination to write to.
+ /// The stride of the destination buffer.
+ /// Pointer to the first element of the block above.
+ /// Pointer to the first element of the block to the left.
+ public void PredictScalar(Span destination, nuint stride, Span above, Span left);
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Readme.md b/src/ImageSharp/Formats/Heif/Av1/Readme.md
new file mode 100644
index 0000000000..9f658e90c8
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Readme.md
@@ -0,0 +1,73 @@
+# Open Bitstream Unit
+
+An OBU unit is a unit of parameters encoded in a bitstream format. In AVIF, it contains a single frame.
+This frame is coded using no other frame as reference, it is a so called INTRA frame. AV1 movie encoding also defines INTER frames,
+which are predictions of one or more other frames. INTER frames are not used in AVIF and therefore this coded ignores INTER frames.
+
+An OBU section for AVIF consists of the following headers:
+
+## Temporal delimiter
+
+In AV1 movies this is a time point. Although irrelevant for AVIF, most implementtions write one such delimiter at the start of the section.
+
+## Sequence header
+
+Common herader for a list (or sequence) of frames. For AVIF, this is exaclty 1 frame. For AVIF, this header can be reduced in size when its `ReducedStillPictureHerader` parameter is true.
+This setting is recommended, as all the extra parameters are not applicable for AVIF.
+
+## Frame header
+
+Can be 3 different OBU types, which define a single INTRA frame in AVIF files.
+
+## Tile group
+
+Defines the tiling parameters and contains the parameters its tile using a different coding.
+
+# Tiling
+
+In AV1 a frame is made up of 1 or more tiles. The parameters for each tile are entropy encoded using the context aware symbol coding.
+These parameters are contained in an OBU tile group header.
+
+## Superblock
+
+A tile consists of one or more superblocks. Superblocks can be either 64x64 or 128x128 pixels in size.
+This choice is made per frame, and is specified in the `ObuFrameHeader`.
+A superblock contains one or more partitions, to further devide the area.
+
+## Partition
+
+A superblock contains one or more Partitions. The partition Type determines the number of partitions it is further split in.
+Paritions can contain other partitions and blocks.
+
+## Block
+
+
+## Transform Block
+
+A Transform Block is the smallest area of the image, which has the same transformation parameters. A block contains ore or more ModeInfos.
+
+
+## ModeInfo
+
+The smallest unit in the frame. It determines the parameters for an area of 4 by 4 pixels.
+
+# References
+
+[AV1 embedded in HEIF](https://aomediacodec.github.io/av1-isobmff)
+
+[AV1 specification](https://aomediacodec.github.io/av1-spec/av1-spec.pdf)
+
+[AVIF specification](https://aomediacodec.github.io/av1-avif)
+
+[AV1/AVIF reference implementation](http://gitlab.com/AOMediaCodec/SVT-AV1)
+
+[AOM's original development implementation](https://github.com/AOMediaCodec/libavif)
+
+[Paper describing the techniques used in AV1](https://arxiv.org/pdf/2008.06091)
+
+# Test images
+
+[Netflix image repository](http://download.opencontent.netflix.com/?prefix=AV1/)
+
+[AVIF sample images](https://github.com/link-u/avif-sample-images)
+
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1BlockModeInfo.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1BlockModeInfo.cs
new file mode 100644
index 0000000000..3f04731506
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1BlockModeInfo.cs
@@ -0,0 +1,70 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1BlockModeInfo
+{
+ private int[] paletteSize;
+
+ public Av1BlockModeInfo(int numPlanes, Av1BlockSize blockSize, Point positionInSuperblock)
+ {
+ this.BlockSize = blockSize;
+ this.PositionInSuperblock = positionInSuperblock;
+ this.AngleDelta = new int[numPlanes - 1];
+ this.paletteSize = new int[numPlanes - 1];
+ this.FilterIntraModeInfo = new();
+ this.FirstTransformLocation = new int[numPlanes - 1];
+ this.TransformUnitsCount = new int[numPlanes - 1];
+ }
+
+ public Av1BlockSize BlockSize { get; }
+
+ ///
+ /// Gets or sets the for the luminance channel.
+ ///
+ public Av1PredictionMode YMode { get; set; }
+
+ public bool Skip { get; set; }
+
+ public Av1PartitionType PartitionType { get; set; }
+
+ public bool SkipMode { get; set; }
+
+ public int SegmentId { get; set; }
+
+ ///
+ /// Gets or sets the for the chroma channels.
+ ///
+ public Av1PredictionMode UvMode { get; set; }
+
+ public bool UseUltraBlockCopy { get; set; }
+
+ public int ChromaFromLumaAlphaIndex { get; set; }
+
+ public int ChromaFromLumaAlphaSign { get; set; }
+
+ public int[] AngleDelta { get; set; }
+
+ ///
+ /// Gets the position relative to the Superblock, counted in mode info (4x4 pixels).
+ ///
+ public Point PositionInSuperblock { get; }
+
+ public Av1IntraFilterModeInfo FilterIntraModeInfo { get; internal set; }
+
+ ///
+ /// Gets the index of the first of this Mode Info in the .
+ ///
+ public int[] FirstTransformLocation { get; }
+
+ public int[] TransformUnitsCount { get; internal set; }
+
+ public int GetPaletteSize(Av1Plane plane) => this.paletteSize[Math.Min(1, (int)plane)];
+
+ public int GetPaletteSize(Av1PlaneType planeType) => this.paletteSize[(int)planeType];
+
+ public void SetPaletteSizes(int ySize, int uvSize) => this.paletteSize = [ySize, uvSize];
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ComponentType.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ComponentType.cs
new file mode 100644
index 0000000000..b8546e72bf
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ComponentType.cs
@@ -0,0 +1,14 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal enum Av1ComponentType
+{
+ Luminance = 0, // luma
+ Chroma = 1, // chroma (Cb+Cr)
+ ChromaCb = 2, // chroma Cb
+ ChromaCr = 3, // chroma Cr
+ All = 4, // Y+Cb+Cr
+ None = 15
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1EncoderBlockModeInfo.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1EncoderBlockModeInfo.cs
new file mode 100644
index 0000000000..482b5c26ba
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1EncoderBlockModeInfo.cs
@@ -0,0 +1,31 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1EncoderBlockModeInfo
+{
+ public Av1BlockSize BlockSize { get; }
+
+ public Av1PredictionMode PredictionMode { get; }
+
+ public Av1PartitionType PartitionType { get; }
+
+ public Av1PredictionMode UvPredictionMode { get; }
+
+ public bool Skip { get; } = true;
+
+ public bool SkipMode { get; } = true;
+
+ public bool UseIntraBlockCopy { get; } = true;
+
+ public int SegmentId { get; }
+
+ public int TransformDepth { get; internal set; }
+
+ public Av1PredictionMode Mode { get; internal set; }
+
+ public Av1PredictionMode UvMode { get; internal set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1EncoderBlockStruct.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1EncoderBlockStruct.cs
new file mode 100644
index 0000000000..cd988c96e1
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1EncoderBlockStruct.cs
@@ -0,0 +1,23 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1EncoderBlockStruct
+{
+ public Av1TransformUnit[] TransformBlocks { get; } = new Av1TransformUnit[Av1Constants.MaxTransformUnitCount];
+
+ public required Av1MacroBlockD MacroBlock { get; set; }
+
+ public int ModeDecisionScanIndex { get; set; }
+
+ public int QuantizationIndex { get; set; }
+
+ public int SegmentId { get; set; }
+
+ public Av1FilterIntraMode FilterIntraMode { get; set; }
+
+ public required int[] PaletteSize { get; internal set; }
+
+ public required Av1EncoderPredictionUnit[] PredictionUnits { get; internal set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1EncoderCommon.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1EncoderCommon.cs
new file mode 100644
index 0000000000..6efa091280
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1EncoderCommon.cs
@@ -0,0 +1,19 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1EncoderCommon
+{
+ public int ModeInfoRowCount { get; internal set; }
+
+ public int ModeInfoColumnCount { get; internal set; }
+
+ public int ModeInfoStride { get; internal set; }
+
+ public required ObuFrameSize FrameSize { get; internal set; }
+
+ public required ObuTileGroupHeader TilesInfo { get; internal set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1EncoderPredictionUnit.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1EncoderPredictionUnit.cs
new file mode 100644
index 0000000000..5b46389ef9
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1EncoderPredictionUnit.cs
@@ -0,0 +1,13 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1EncoderPredictionUnit
+{
+ public required byte[] AngleDelta { get; set; }
+
+ public int ChromaFromLumaIndex { get; internal set; }
+
+ public int ChromaFromLumaSigns { get; internal set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1EntropyCodingContext.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1EntropyCodingContext.cs
new file mode 100644
index 0000000000..ead8f44623
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1EntropyCodingContext.cs
@@ -0,0 +1,18 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal partial class Av1TileWriter
+{
+ internal class Av1EntropyCodingContext
+ {
+ public required Av1MacroBlockModeInfo MacroBlockModeInfo { get; internal set; }
+
+ public Point SuperblockOrigin { get; internal set; }
+
+ public int CodedAreaSuperblock { get; internal set; }
+
+ public int CodedAreaSuperblockUv { get; internal set; }
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FilterIntraMode.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FilterIntraMode.cs
new file mode 100644
index 0000000000..f536982e01
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FilterIntraMode.cs
@@ -0,0 +1,14 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal enum Av1FilterIntraMode
+{
+ DC,
+ Vertical,
+ Horizontal,
+ Directional157,
+ Paeth,
+ AllFilterIntraModes,
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FilterIntraModeExtensions.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FilterIntraModeExtensions.cs
new file mode 100644
index 0000000000..0a2e2e8325
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FilterIntraModeExtensions.cs
@@ -0,0 +1,15 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal static class Av1FilterIntraModeExtensions
+{
+ private static readonly Av1PredictionMode[] IntraDirection =
+ [Av1PredictionMode.DC, Av1PredictionMode.Vertical, Av1PredictionMode.Horizontal, Av1PredictionMode.Directional157Degrees, Av1PredictionMode.DC];
+
+ public static Av1PredictionMode ToIntraDirection(this Av1FilterIntraMode mode)
+ => IntraDirection[(int)mode];
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FrameInfo.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FrameInfo.cs
new file mode 100644
index 0000000000..a61f14657a
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FrameInfo.cs
@@ -0,0 +1,220 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+///
+/// Collection of all information for a single frame.
+///
+internal partial class Av1FrameInfo
+{
+ // Number of Coefficients in a single ModeInfo 4x4 block of pixels (1 length + 4 x 4).
+ public const int CoefficientCountPerModeInfo = 1 + 16;
+
+ private readonly int[] coefficientsY = [];
+ private readonly int[] coefficientsU = [];
+ private readonly int[] coefficientsV = [];
+ private readonly int modeInfoSizePerSuperblock;
+ private readonly int modeInfoCountPerSuperblock;
+ private readonly int superblockColumnCount;
+ private readonly int superblockRowCount;
+ private readonly int subsamplingFactor;
+ private readonly Av1SuperblockInfo[] superblockInfos;
+ private readonly Av1BlockModeInfo[] modeInfos;
+ private readonly Av1FrameModeInfoMap modeInfoMap;
+ private readonly Av1TransformInfo[] transformInfosY;
+ private readonly Av1TransformInfo[] transformInfosUv;
+ private readonly int[] deltaQ;
+ private readonly int cdefStrengthFactorLog2;
+ private readonly int[] cdefStrength;
+ private readonly int deltaLoopFactorLog2 = 2;
+ private readonly int[] deltaLoopFilter;
+
+ public Av1FrameInfo(ObuSequenceHeader sequenceHeader)
+ {
+ // init_main_frame_ctxt
+ int superblockSizeLog2 = sequenceHeader.SuperblockSizeLog2;
+ int superblockAlignedWidth = Av1Math.AlignPowerOf2(sequenceHeader.MaxFrameWidth, superblockSizeLog2);
+ int superblockAlignedHeight = Av1Math.AlignPowerOf2(sequenceHeader.MaxFrameHeight, superblockSizeLog2);
+ this.superblockColumnCount = superblockAlignedWidth >> superblockSizeLog2;
+ this.superblockRowCount = superblockAlignedHeight >> superblockSizeLog2;
+ int superblockCount = this.superblockColumnCount * this.superblockRowCount;
+ this.modeInfoSizePerSuperblock = 1 << (superblockSizeLog2 - Av1Constants.ModeInfoSizeLog2);
+ this.modeInfoCountPerSuperblock = this.modeInfoSizePerSuperblock * this.modeInfoSizePerSuperblock;
+ int numPlanes = sequenceHeader.ColorConfig.IsMonochrome ? 1 : Av1Constants.MaxPlanes;
+
+ // Allocate the arrays.
+ this.superblockInfos = new Av1SuperblockInfo[superblockCount];
+ this.modeInfos = new Av1BlockModeInfo[superblockCount * this.modeInfoCountPerSuperblock];
+ this.modeInfoMap = new Av1FrameModeInfoMap(new Size(this.modeInfoSizePerSuperblock * this.superblockColumnCount, this.modeInfoSizePerSuperblock * this.superblockRowCount), superblockSizeLog2);
+ this.transformInfosY = new Av1TransformInfo[superblockCount * this.modeInfoCountPerSuperblock];
+ this.transformInfosUv = new Av1TransformInfo[2 * superblockCount * this.modeInfoCountPerSuperblock];
+
+ // Initialize the arrays.
+ int i = 0;
+ for (int y = 0; y < this.superblockRowCount; y++)
+ {
+ for (int x = 0; x < this.superblockColumnCount; x++)
+ {
+ Point point = new(x, y);
+ this.superblockInfos[i] = new(this, point);
+ for (int j = 0; j < this.modeInfoCountPerSuperblock; j++)
+ {
+ this.transformInfosY[j] = new Av1TransformInfo();
+ this.transformInfosUv[j] = new Av1TransformInfo();
+ }
+
+ i++;
+ }
+ }
+
+ bool subX = sequenceHeader.ColorConfig.SubSamplingX;
+ bool subY = sequenceHeader.ColorConfig.SubSamplingY;
+
+ // Factor: 444 => 0, 422 => 1, 420 => 2.
+ this.subsamplingFactor = (subX && subY) ? 2 : (subX && !subY) ? 1 : (!subX && !subY) ? 0 : -1;
+ Guard.IsFalse(this.subsamplingFactor == -1, nameof(this.subsamplingFactor), "Invalid combination of subsampling.");
+ this.coefficientsY = new int[superblockCount * this.modeInfoCountPerSuperblock * CoefficientCountPerModeInfo];
+ this.coefficientsU = new int[(this.modeInfoCountPerSuperblock * CoefficientCountPerModeInfo) >> this.subsamplingFactor];
+ this.coefficientsV = new int[(this.modeInfoCountPerSuperblock * CoefficientCountPerModeInfo) >> this.subsamplingFactor];
+ this.deltaQ = new int[superblockCount];
+
+ // Superblock size: 128x128 has sizelog2 = 7, 64x64 = 6. Factor should be 128x128 => 4 and 64x64 => 1.
+ this.cdefStrengthFactorLog2 = (superblockSizeLog2 - 6) << 2;
+ this.cdefStrength = new int[superblockCount << this.cdefStrengthFactorLog2];
+ Array.Fill(this.cdefStrength, -1);
+ this.deltaLoopFilter = new int[superblockCount << this.deltaLoopFactorLog2];
+ }
+
+ ///
+ /// Gets the number of mode info blocks in a single superblock.
+ ///
+ public int ModeInfoCount => this.modeInfos.Length;
+
+ ///
+ /// Gets the Width or height of a single superblock, counted in mode info blocks.
+ ///
+ public int SuperblockModeInfoSize => this.modeInfoSizePerSuperblock;
+
+ public Av1SuperblockInfo GetSuperblock(Point index)
+ {
+ Span span = this.superblockInfos;
+ int i = (index.Y * this.superblockColumnCount) + index.X;
+ return span[i];
+ }
+
+ public Av1BlockModeInfo GetModeInfo(Point superblockIndex)
+ {
+ Span span = this.modeInfos;
+ int superblock = (superblockIndex.Y * this.superblockColumnCount) + superblockIndex.X;
+ return span[superblock * this.modeInfoCountPerSuperblock];
+ }
+
+ public Av1BlockModeInfo GetModeInfo(Point superblockIndex, Point modeInfoIndex)
+ {
+ Point location = this.GetModeInfoPosition(superblockIndex, modeInfoIndex);
+ int index = this.modeInfoMap[location];
+ return this.modeInfos[index];
+ }
+
+ public Span GetSuperblockTransform(int plane, Point index)
+ {
+ if (plane == 0)
+ {
+ return this.GetSuperblockTransformY(index);
+ }
+
+ return this.GetSuperblockTransformUv(index);
+ }
+
+ public Span GetSuperblockTransformY(Point index)
+ {
+ Span span = this.transformInfosY;
+ int offset = ((index.Y * this.superblockColumnCount) + index.X) * this.modeInfoCountPerSuperblock;
+ return span.Slice(offset, this.modeInfoCountPerSuperblock);
+ }
+
+ public Span GetSuperblockTransformUv(Point index)
+ {
+ Span span = this.transformInfosUv;
+ int offset = (((index.Y * this.superblockColumnCount) + index.X) * this.modeInfoCountPerSuperblock) << 1;
+ return span.Slice(offset, this.modeInfoCountPerSuperblock);
+ }
+
+ public Span GetCoefficients(int plane) =>
+ plane switch
+ {
+ 0 => (Span)this.coefficientsY,
+ 1 => (Span)this.coefficientsY,
+ 2 => (Span)this.coefficientsY,
+ _ => null,
+ };
+
+ public Span GetCoefficientsY(Point index)
+ {
+ Span span = this.coefficientsY;
+ int i = ((index.Y * this.modeInfoCountPerSuperblock) + index.X) * CoefficientCountPerModeInfo;
+ return span.Slice(i, CoefficientCountPerModeInfo);
+ }
+
+ public Span GetCoefficientsU(Point index)
+ {
+ Span span = this.coefficientsU;
+ int i = ((index.Y * this.modeInfoCountPerSuperblock) + index.X) * CoefficientCountPerModeInfo;
+ return span.Slice(i >> this.subsamplingFactor, CoefficientCountPerModeInfo);
+ }
+
+ public Span GetCoefficientsV(Point index)
+ {
+ Span span = this.coefficientsV;
+ int i = ((index.Y * this.modeInfoCountPerSuperblock) + index.X) * CoefficientCountPerModeInfo;
+ return span.Slice(i >> this.subsamplingFactor, CoefficientCountPerModeInfo);
+ }
+
+ public ref int GetDeltaQuantizationIndex(Point index)
+ {
+ Span span = this.deltaQ;
+ int i = (index.Y * this.superblockColumnCount) + index.X;
+ return ref span[i];
+ }
+
+ public Span GetCdefStrength(Point index)
+ {
+ Span span = this.cdefStrength;
+ int i = ((index.Y * this.superblockColumnCount) + index.X) << this.cdefStrengthFactorLog2;
+ return span.Slice(i, 1 << this.cdefStrengthFactorLog2);
+ }
+
+ internal void ClearCdef(Point index)
+ {
+ Span cdefs = this.GetCdefStrength(index);
+ for (int i = 0; i < cdefs.Length; i++)
+ {
+ cdefs[i] = -1;
+ }
+ }
+
+ public Span GetDeltaLoopFilter(Point index)
+ {
+ Span span = this.deltaLoopFilter;
+ int i = ((index.Y * this.superblockColumnCount) + index.X) << this.deltaLoopFactorLog2;
+ return span.Slice(i, 1 << this.deltaLoopFactorLog2);
+ }
+
+ public void ClearDeltaLoopFilter() => Array.Fill(this.deltaLoopFilter, 0);
+
+ public void UpdateModeInfo(Av1BlockModeInfo modeInfo, Av1SuperblockInfo superblockInfo)
+ {
+ this.modeInfos[this.modeInfoMap.NextIndex] = modeInfo;
+ this.modeInfoMap.Update(this.GetModeInfoPosition(superblockInfo.Position, modeInfo.PositionInSuperblock), modeInfo.BlockSize);
+ }
+
+ private Point GetModeInfoPosition(Point superblockPosition, Point positionInSuperblock)
+ {
+ int x = (superblockPosition.X * this.modeInfoCountPerSuperblock) + positionInSuperblock.X;
+ int y = (superblockPosition.Y * this.modeInfoCountPerSuperblock) + positionInSuperblock.Y;
+ return new Point(x, y);
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FrameModeInfoMap.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FrameModeInfoMap.cs
new file mode 100644
index 0000000000..d13b1592a4
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FrameModeInfoMap.cs
@@ -0,0 +1,63 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal partial class Av1FrameInfo
+{
+ ///
+ /// Mapping of instances, from position to index into the .
+ ///
+ ///
+ /// For a visual representation of how this map looks in practice, see
+ ///
+ public class Av1FrameModeInfoMap
+ {
+ private readonly ushort[] offsets;
+ private Size alignedModeInfoCount;
+
+ public Av1FrameModeInfoMap(Size modeInfoCount, int superblockSizeLog2)
+ {
+ this.alignedModeInfoCount = new Size(
+ modeInfoCount.Width * (1 << (superblockSizeLog2 - Av1Constants.ModeInfoSizeLog2)),
+ modeInfoCount.Height * (1 << (superblockSizeLog2 - Av1Constants.ModeInfoSizeLog2)));
+ this.NextIndex = 0;
+ this.offsets = new ushort[this.alignedModeInfoCount.Width * this.alignedModeInfoCount.Height];
+ }
+
+ ///
+ /// Gets the next index to use.
+ ///
+ public int NextIndex { get; private set; }
+
+ ///
+ /// Gets the mapped index for the given location.
+ ///
+ public int this[Point location]
+ {
+ get
+ {
+ int index = (location.Y * this.alignedModeInfoCount.Width) + location.X;
+ return this.offsets[index];
+ }
+ }
+
+ public void Update(Point modeInfoLocation, Av1BlockSize blockSize)
+ {
+ // Equivalent in SVT-Av1: EbDecNbr.c svt_aom_update_block_nbrs
+ int bw4 = blockSize.Get4x4WideCount();
+ int bh4 = blockSize.Get4x4HighCount();
+ DebugGuard.MustBeGreaterThanOrEqualTo(modeInfoLocation.Y, 0, nameof(modeInfoLocation));
+ DebugGuard.MustBeLessThanOrEqualTo(modeInfoLocation.Y + bh4, this.alignedModeInfoCount.Height, nameof(modeInfoLocation));
+ DebugGuard.MustBeGreaterThanOrEqualTo(modeInfoLocation.X, 0, nameof(modeInfoLocation));
+ DebugGuard.MustBeLessThanOrEqualTo(modeInfoLocation.X + bw4, this.alignedModeInfoCount.Width, nameof(modeInfoLocation));
+ /* Update 4x4 nbr offset map */
+ for (int i = modeInfoLocation.Y; i < modeInfoLocation.Y + bh4; i++)
+ {
+ Array.Fill(this.offsets, (ushort)this.NextIndex, (i * this.alignedModeInfoCount.Width) + modeInfoLocation.X, bw4);
+ }
+
+ this.NextIndex++;
+ }
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1IntraFilterModeInfo.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1IntraFilterModeInfo.cs
new file mode 100644
index 0000000000..649a069b0b
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1IntraFilterModeInfo.cs
@@ -0,0 +1,11 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1IntraFilterModeInfo
+{
+ public bool UseFilterIntra { get; set; }
+
+ public Av1FilterIntraMode Mode { get; set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1LevelBuffer.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1LevelBuffer.cs
new file mode 100644
index 0000000000..a21116b6f4
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1LevelBuffer.cs
@@ -0,0 +1,80 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System;
+using System.Buffers;
+using System.Runtime.CompilerServices;
+using SixLabors.ImageSharp.Memory;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal sealed class Av1LevelBuffer : IDisposable
+{
+ private IMemoryOwner? memory;
+
+ public Av1LevelBuffer(Configuration configuration)
+ : this(configuration, new Size(Av1Constants.MaxTransformSize, Av1Constants.MaxTransformSize))
+ {
+ }
+
+ public Av1LevelBuffer(Configuration configuration, Size size)
+ {
+ this.Size = size;
+ int totalHeight = Av1Constants.TransformPadTop + size.Height + Av1Constants.TransformPadBottom;
+ this.Stride = Av1Constants.TransformPadHorizontal + size.Width;
+ this.memory = configuration.MemoryAllocator.Allocate(this.Stride * totalHeight, AllocationOptions.Clean);
+ }
+
+ public Size Size { get; }
+
+ public int Stride { get; }
+
+ public int this[Point position] => this.GetRow(position.Y)[position.X];
+
+ public void Initialize(Span coefficientBuffer)
+ {
+ ObjectDisposedException.ThrowIf(this.memory == null, this);
+ ArgumentOutOfRangeException.ThrowIfLessThan(coefficientBuffer.Length, this.Size.Width * this.Size.Height, nameof(coefficientBuffer));
+ for (int y = 0; y < this.Size.Height; y++)
+ {
+ ref byte destRef = ref this.GetRow(y)[0];
+ ref int sourceRef = ref coefficientBuffer[y * this.Size.Width];
+ for (int x = 0; x < this.Size.Width; x++)
+ {
+ destRef = (byte)Av1Math.Clamp(sourceRef, 0, byte.MaxValue);
+ destRef = ref Unsafe.Add(ref destRef, 1);
+ sourceRef = ref Unsafe.Add(ref sourceRef, 1);
+ }
+ }
+ }
+
+ public Point GetPosition(int index)
+ {
+ int x = index % this.Size.Width;
+ int y = index / this.Size.Width;
+ return new Point(x, y);
+ }
+
+ public Span GetRow(Point pos)
+ => this.GetRow(pos.Y);
+
+ public Span GetRow(int y)
+ {
+ ObjectDisposedException.ThrowIf(this.memory == null, this);
+ ArgumentOutOfRangeException.ThrowIfLessThan(y, -Av1Constants.TransformPadTop);
+ int row = y + Av1Constants.TransformPadTop;
+ return this.memory.Memory.Span.Slice(row * this.Stride, this.Size.Width + Av1Constants.TransformPadHorizontal);
+ }
+
+ public void Dispose()
+ {
+ this.memory?.Dispose();
+ this.memory = null;
+ }
+
+ internal void Clear()
+ {
+ ObjectDisposedException.ThrowIf(this.memory == null, this);
+ this.memory.Memory.Span.Clear();
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1MacroBlockD.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1MacroBlockD.cs
new file mode 100644
index 0000000000..bb69f9ee8c
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1MacroBlockD.cs
@@ -0,0 +1,55 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1MacroBlockD
+{
+ private Av1ModeInfo[] modeInfo = [];
+
+ public required Span ModeInfo
+ {
+ get => this.modeInfo;
+ internal set
+ {
+ this.modeInfo = new Av1ModeInfo[value.Length];
+ value.CopyTo(this.modeInfo);
+ }
+ }
+
+ public required Av1TileInfo Tile { get; internal set; }
+
+ public bool IsUpAvailable { get; internal set; }
+
+ public bool IsLeftAvailable { get; internal set; }
+
+ public Av1MacroBlockModeInfo? AboveMacroBlock { get; internal set; }
+
+ public Av1MacroBlockModeInfo? LeftMacroBlock { get; internal set; }
+
+ public int ModeInfoStride { get; internal set; }
+
+ ///
+ /// Gets or sets the number of macro blocks until the top edge.
+ ///
+ public int ToTopEdge { get; internal set; }
+
+ ///
+ /// Gets or sets the number of macro blocks until the bottom edge.
+ ///
+ public int ToBottomEdge { get; internal set; }
+
+ ///
+ /// Gets or sets the number of macro blocks until the left edge.
+ ///
+ public int ToLeftEdge { get; internal set; }
+
+ ///
+ /// Gets or sets the number of macro blocks until the right edge.
+ ///
+ public int ToRightEdge { get; internal set; }
+
+ public Size N8Size { get; internal set; }
+
+ public bool IsSecondRectangle { get; internal set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1MacroBlockModeInfo.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1MacroBlockModeInfo.cs
new file mode 100644
index 0000000000..1d916a531f
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1MacroBlockModeInfo.cs
@@ -0,0 +1,13 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1MacroBlockModeInfo
+{
+ public required Av1EncoderBlockModeInfo Block { get; internal set; }
+
+ public required Av1PaletteLumaModeInfo Palette { get; internal set; }
+
+ public int CdefStrength { get; internal set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ModeInfo.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ModeInfo.cs
new file mode 100644
index 0000000000..ba6f3b0843
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ModeInfo.cs
@@ -0,0 +1,9 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1ModeInfo
+{
+ public required Av1MacroBlockModeInfo MacroBlockModeInfo { get; internal set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1NeighborArrayUnit.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1NeighborArrayUnit.cs
new file mode 100644
index 0000000000..f4e2957a51
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1NeighborArrayUnit.cs
@@ -0,0 +1,170 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Numerics;
+using System.Runtime.CompilerServices;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1NeighborArrayUnit
+ where T : struct, IMinMaxValue
+{
+ public static readonly T InvalidNeighborData = T.MaxValue;
+
+ private readonly T[] left;
+ private readonly T[] top;
+ private readonly T[] topLeft;
+
+ public Av1NeighborArrayUnit(int leftSize, int topSize, int topLeftSize)
+ {
+ this.left = new T[leftSize];
+ this.top = new T[topSize];
+ this.topLeft = new T[topLeftSize];
+ }
+
+ [Flags]
+ public enum UnitMask
+ {
+ Left = 1,
+ Top = 2,
+ TopLeft = 4,
+ }
+
+ public Span Left => this.left;
+
+ public Span Top => this.top;
+
+ public Span TopLeft => this.topLeft;
+
+ public required int GranularityNormalLog2 { get; set; }
+
+ public required int GranularityTopLeftLog2 { get; set; }
+
+ public int UnitSize { get; private set; }
+
+ public int GetLeftIndex(Point loc) => loc.Y >> this.GranularityNormalLog2;
+
+ public int GetTopIndex(Point loc) => loc.X >> this.GranularityNormalLog2;
+
+ public int GetTopLeftIndex(Point loc)
+ => this.left.Length + (loc.X >> this.GranularityTopLeftLog2) - (loc.Y >> this.GranularityTopLeftLog2);
+
+ public void UnitModeWrite(ReadOnlySpan value, Point origin, Size blockSize, UnitMask mask)
+ {
+ int idx, j;
+
+ int count;
+ int na_offset;
+ int na_unit_size;
+
+ na_unit_size = this.UnitSize;
+
+ if ((mask & UnitMask.Top) == UnitMask.Top)
+ {
+ // Top Neighbor Array
+ // ----------12345678---------------------
+ // ^ ^
+ // | |
+ // | |
+ // xxxxxxxx
+ // x x
+ // x x
+ // 12345678
+ //
+ // The top neighbor array is updated with the samples from the
+ // bottom row of the source block
+ //
+ // Index = org_x
+ na_offset = this.GetTopIndex(origin);
+
+ ref T dst_ptr = ref this.Top[na_offset * na_unit_size];
+
+ count = blockSize.Width >> this.GranularityNormalLog2;
+
+ for (idx = 0; idx < count; ++idx)
+ {
+ /* svt_memcpy less that 10 bytes*/
+ for (j = 0; j < na_unit_size; ++j)
+ {
+ dst_ptr = value[j];
+ dst_ptr = Unsafe.Add(ref dst_ptr, 1);
+ }
+ }
+ }
+
+ if ((mask & UnitMask.Left) == UnitMask.Left)
+ {
+ // Left Neighbor Array
+ //
+ // |
+ // |
+ // 1 xxxxxxx1
+ // 2 <---- x 2
+ // 3 <---- x 3
+ // 4 xxxxxxx4
+ // |
+ // |
+ //
+ // The left neighbor array is updated with the samples from the
+ // right column of the source block
+ //
+ // Index = org_y
+ na_offset = this.GetLeftIndex(origin);
+
+ ref T dst_ptr = ref this.Left[na_offset * na_unit_size];
+
+ count = blockSize.Height >> this.GranularityNormalLog2;
+
+ for (idx = 0; idx < count; ++idx)
+ {
+ /* svt_memcpy less that 10 bytes*/
+ for (j = 0; j < na_unit_size; ++j)
+ {
+ dst_ptr = value[j];
+ dst_ptr = Unsafe.Add(ref dst_ptr, 1);
+ }
+ }
+ }
+
+ if ((mask & UnitMask.TopLeft) == UnitMask.TopLeft)
+ {
+ // Top-left Neighbor Array
+ //
+ // 4-5--6--7------------
+ // 3 \ \
+ // 2 \ \
+ // 1 \ \
+ // |\ xxxxxx7
+ // | \ x 6
+ // | \ x 5
+ // | \1x2x3x4
+ // |
+ //
+ // The top-left neighbor array is updated with the reversed samples
+ // from the right column and bottom row of the source block
+ //
+ // Index = org_x - org_y
+ Point topLeft = origin;
+ topLeft.Offset(0, blockSize.Height - 1);
+ na_offset = this.GetTopLeftIndex(topLeft);
+
+ // Copy bottom-row + right-column
+ // *Note - start from the bottom-left corner
+ ref T dst_ptr = ref this.TopLeft[na_offset * na_unit_size];
+
+ count = ((blockSize.Width + blockSize.Height) >> this.GranularityTopLeftLog2) - 1;
+
+ for (idx = 0; idx < count; ++idx)
+ {
+ /* svt_memcpy less that 10 bytes*/
+ for (j = 0; j < na_unit_size; ++j)
+ {
+ dst_ptr = value[j];
+ dst_ptr = Unsafe.Add(ref dst_ptr, 1);
+ }
+ }
+ }
+ }
+
+ internal void UnitModeWrite(Span dcSignSpan, Point blockOrigin, Size blockSize, Av1NeighborArrayUnit.UnitMask unitMask) => throw new NotImplementedException();
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PaletteLumaModeInfo.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PaletteLumaModeInfo.cs
new file mode 100644
index 0000000000..aa1e1e94f7
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PaletteLumaModeInfo.cs
@@ -0,0 +1,8 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1PaletteLumaModeInfo
+{
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseAboveNeighbor4x4Context.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseAboveNeighbor4x4Context.cs
new file mode 100644
index 0000000000..0f6c4149cd
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseAboveNeighbor4x4Context.cs
@@ -0,0 +1,93 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1ParseAboveNeighbor4x4Context
+{
+ /* Buffer holding the sign of the DC coefficients and the
+ cumulative sum of the coefficient levels of the above 4x4
+ blocks corresponding to the current super block row. */
+ private readonly int[][] aboveContext = new int[Av1Constants.MaxPlanes][];
+
+ /* Buffer holding the seg_id_predicted of the previous 4x4 block row. */
+ private readonly int[] aboveSegmentIdPredictionContext;
+
+ /* Value of base colors for Y, U, and V */
+ private readonly int[][] abovePaletteColors = new int[Av1Constants.MaxPlanes][];
+
+ private readonly int[] aboveCompGroupIndex;
+
+ public Av1ParseAboveNeighbor4x4Context(int planesCount, int modeInfoColumnCount)
+ {
+ int wide64x64Count = Av1BlockSize.Block64x64.Get4x4WideCount();
+ this.AboveTransformWidth = new int[modeInfoColumnCount];
+ this.AbovePartitionWidth = new int[modeInfoColumnCount];
+ for (int i = 0; i < planesCount; i++)
+ {
+ this.aboveContext[i] = new int[modeInfoColumnCount];
+ this.abovePaletteColors[i] = new int[wide64x64Count * Av1Constants.PaletteMaxSize];
+ }
+
+ this.aboveSegmentIdPredictionContext = new int[modeInfoColumnCount];
+ this.aboveCompGroupIndex = new int[modeInfoColumnCount];
+ }
+
+ ///
+ /// Gets a buffer holding the partition context of the previous 4x4 block row.
+ ///
+ public int[] AbovePartitionWidth { get; }
+
+ ///
+ /// Gets a buffer holding the transform sizes of the previous 4x4 block row.
+ ///
+ public int[] AboveTransformWidth { get; }
+
+ public int[] GetContext(int plane) => this.aboveContext[plane];
+
+ public void Clear(ObuSequenceHeader sequenceHeader, int modeInfoColumnStart, int modeInfoColumnEnd)
+ {
+ int planeCount = sequenceHeader.ColorConfig.PlaneCount;
+ int width = modeInfoColumnEnd - modeInfoColumnStart;
+ Array.Fill(this.AboveTransformWidth, Av1TransformSize.Size64x64.GetWidth(), 0, width);
+ Array.Fill(this.AbovePartitionWidth, 0, 0, width);
+ for (int i = 0; i < planeCount; i++)
+ {
+ Array.Fill(this.aboveContext[i], 0, 0, width);
+ Array.Fill(this.abovePaletteColors[i], 0, 0, width);
+ }
+
+ Array.Fill(this.aboveSegmentIdPredictionContext, 0, 0, width);
+ Array.Fill(this.aboveCompGroupIndex, 0, 0, width);
+ }
+
+ public void UpdatePartition(Point modeInfoLocation, Av1TileInfo tileInfo, Av1BlockSize subSize, Av1BlockSize blockSize)
+ {
+ int startIndex = modeInfoLocation.X - tileInfo.ModeInfoColumnStart;
+ int bw = blockSize.Get4x4WideCount();
+ int value = Av1PartitionContext.GetAboveContext(subSize);
+
+ DebugGuard.MustBeLessThanOrEqualTo(startIndex, this.AboveTransformWidth.Length - bw, nameof(startIndex));
+ Array.Fill(this.AbovePartitionWidth, value, startIndex, bw);
+ }
+
+ public void UpdateTransformation(Point modeInfoLocation, Av1TileInfo tileInfo, Av1TransformSize transformSize, Av1BlockSize blockSize, bool skip)
+ {
+ int startIndex = modeInfoLocation.X - tileInfo.ModeInfoColumnStart;
+ int transformWidth = transformSize.GetWidth();
+ int n4w = blockSize.Get4x4WideCount();
+ if (skip)
+ {
+ transformWidth = n4w << Av1Constants.ModeInfoSizeLog2;
+ }
+
+ DebugGuard.MustBeLessThanOrEqualTo(startIndex, this.AboveTransformWidth.Length - n4w, nameof(startIndex));
+ Array.Fill(this.AboveTransformWidth, transformWidth, startIndex, n4w);
+ }
+
+ internal void ClearContext(int plane, int offset, int length)
+ => Array.Fill(this.aboveContext[plane], 0, offset, length);
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseLeftNeighbor4x4Context.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseLeftNeighbor4x4Context.cs
new file mode 100644
index 0000000000..70f846d856
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseLeftNeighbor4x4Context.cs
@@ -0,0 +1,94 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1ParseLeftNeighbor4x4Context
+{
+ /* Buffer holding the sign of the DC coefficients and the
+ cumulative sum of the coefficient levels of the left 4x4
+ blocks corresponding to the current super block row. */
+ private readonly int[][] leftContext = new int[Av1Constants.MaxPlanes][];
+
+ /* Buffer holding the seg_id_predicted of the previous 4x4 block row. */
+ private readonly int[] leftSegmentIdPredictionContext;
+
+ /* Value of base colors for Y, U, and V */
+ private readonly int[][] leftPaletteColors = new int[Av1Constants.MaxPlanes][];
+
+ private readonly int[] leftCompGroupIndex;
+
+ public Av1ParseLeftNeighbor4x4Context(int planesCount, int superblockModeInfoSize)
+ {
+ this.LeftTransformHeight = new int[superblockModeInfoSize];
+ this.LeftPartitionHeight = new int[superblockModeInfoSize];
+ for (int i = 0; i < planesCount; i++)
+ {
+ this.leftContext[i] = new int[superblockModeInfoSize];
+ this.leftPaletteColors[i] = new int[superblockModeInfoSize * Av1Constants.PaletteMaxSize];
+ }
+
+ this.leftSegmentIdPredictionContext = new int[superblockModeInfoSize];
+ this.leftCompGroupIndex = new int[superblockModeInfoSize];
+ }
+
+ ///
+ /// Gets a buffer holding the partition context of the left 4x4 blocks corresponding
+ /// to the current super block row.
+ ///
+ public int[] LeftPartitionHeight { get; }
+
+ ///
+ /// Gets a buffer holding the transform sizes of the left 4x4 blocks corresponding
+ /// to the current super block row.
+ ///
+ public int[] LeftTransformHeight { get; }
+
+ public void Clear(ObuSequenceHeader sequenceHeader)
+ {
+ int blockCount = sequenceHeader.SuperblockModeInfoSize;
+ int planeCount = sequenceHeader.ColorConfig.PlaneCount;
+ int neighbor4x4Count = sequenceHeader.SuperblockModeInfoSize;
+ Array.Fill(this.LeftTransformHeight, Av1TransformSize.Size64x64.GetHeight(), 0, blockCount);
+ Array.Fill(this.LeftPartitionHeight, 0, 0, blockCount);
+ for (int i = 0; i < planeCount; i++)
+ {
+ Array.Fill(this.leftContext[i], 0, 0, blockCount);
+ Array.Fill(this.leftPaletteColors[i], 0, 0, blockCount);
+ }
+
+ Array.Fill(this.leftSegmentIdPredictionContext, 0, 0, blockCount);
+ Array.Fill(this.leftCompGroupIndex, 0, 0, blockCount);
+ }
+
+ public void UpdatePartition(Point modeInfoLocation, Av1SuperblockInfo superblockInfo, Av1BlockSize subSize, Av1BlockSize blockSize)
+ {
+ int startIndex = (modeInfoLocation.Y - superblockInfo.ModeInfoPosition.Y) & Av1PartitionContext.Mask;
+ int bh = blockSize.Get4x4HighCount();
+ int value = Av1PartitionContext.GetLeftContext(subSize);
+ DebugGuard.MustBeLessThanOrEqualTo(startIndex, this.LeftPartitionHeight.Length - bh, nameof(startIndex));
+ Array.Fill(this.LeftPartitionHeight, value, startIndex, bh);
+ }
+
+ public void UpdateTransformation(Point modeInfoLocation, Av1SuperblockInfo superblockInfo, Av1TransformSize transformSize, Av1BlockSize blockSize, bool skip)
+ {
+ int startIndex = modeInfoLocation.Y - superblockInfo.ModeInfoPosition.Y;
+ int transformHeight = transformSize.GetHeight();
+ int n4h = blockSize.Get4x4HighCount();
+ if (skip)
+ {
+ transformHeight = n4h << Av1Constants.ModeInfoSizeLog2;
+ }
+
+ DebugGuard.MustBeLessThanOrEqualTo(startIndex, this.LeftTransformHeight.Length - n4h, nameof(startIndex));
+ Array.Fill(this.LeftTransformHeight, transformHeight, startIndex, n4h);
+ }
+
+ internal void ClearContext(int plane, int offset, int length)
+ => Array.Fill(this.leftContext[plane], 0, offset, length);
+
+ internal int[] GetContext(int plane) => this.leftContext[plane];
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PartitionContext.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PartitionContext.cs
new file mode 100644
index 0000000000..73b3d67570
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PartitionContext.cs
@@ -0,0 +1,39 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Numerics;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+// Generates 5 bit field in which each bit set to 1 represents
+// a BlockSize partition 11111 means we split 128x128, 64x64, 32x32, 16x16
+// and 8x8. 10000 means we just split the 128x128 to 64x64
+internal struct Av1PartitionContext : IMinMaxValue
+{
+ private static readonly int[] AboveLookup =
+ [31, 31, 30, 30, 30, 28, 28, 28, 24, 24, 24, 16, 16, 16, 0, 0, 31, 28, 30, 24, 28, 16];
+
+ private static readonly int[] LeftLookup =
+ [31, 30, 31, 30, 28, 30, 28, 24, 28, 24, 16, 24, 16, 0, 16, 0, 28, 31, 24, 30, 16, 28];
+
+ // Mask to extract ModeInfo offset within max ModeInfoBlock
+ public const int Mask = (1 << (7 - 2)) - 1;
+
+ public Av1PartitionContext(byte above, byte left)
+ {
+ this.Above = above;
+ this.Left = left;
+ }
+
+ public static Av1PartitionContext MaxValue => throw new NotImplementedException();
+
+ public static Av1PartitionContext MinValue => throw new NotImplementedException();
+
+ public byte Left { get; internal set; }
+
+ public byte Above { get; internal set; }
+
+ public static int GetAboveContext(Av1BlockSize blockSize) => AboveLookup[(int)blockSize];
+
+ public static int GetLeftContext(Av1BlockSize blockSize) => LeftLookup[(int)blockSize];
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PartitionInfo.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PartitionInfo.cs
new file mode 100644
index 0000000000..470f0cd538
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PartitionInfo.cs
@@ -0,0 +1,148 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Prediction.ChromaFromLuma;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1PartitionInfo
+{
+ public Av1PartitionInfo(Av1BlockModeInfo modeInfo, Av1SuperblockInfo superblockInfo, bool isChroma, Av1PartitionType partitionType)
+ {
+ this.ModeInfo = modeInfo;
+ this.SuperblockInfo = superblockInfo;
+ this.IsChroma = isChroma;
+ this.Type = partitionType;
+ this.CdefStrength = [];
+ this.ReferenceFrame = [-1, -1];
+ this.WidthInPixels = new int[3];
+ this.HeightInPixels = new int[3];
+ }
+
+ public Av1BlockModeInfo ModeInfo { get; }
+
+ ///
+ /// Gets the this partition resides inside.
+ ///
+ public Av1SuperblockInfo SuperblockInfo { get; }
+
+ public bool IsChroma { get; }
+
+ public Av1PartitionType Type { get; }
+
+ ///
+ /// Gets or sets a value indicating whether the information from the block above can be used on the luma plane.
+ ///
+ public bool AvailableAbove { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the information from the block left can be used on the luma plane.
+ ///
+ public bool AvailableLeft { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the information from the block above can be used on the chroma plane.
+ ///
+ public bool AvailableAboveForChroma { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the information from the block left can be used on the chroma plane.
+ ///
+ public bool AvailableLeftForChroma { get; set; }
+
+ ///
+ /// Gets or sets the horizontal location of the block in units of 4x4 luma samples.
+ ///
+ public int ColumnIndex { get; set; }
+
+ ///
+ /// Gets or sets the vertical location of the block in units of 4x4 luma samples.
+ ///
+ public int RowIndex { get; set; }
+
+ public Av1BlockModeInfo? AboveModeInfo { get; set; }
+
+ public Av1BlockModeInfo? LeftModeInfo { get; set; }
+
+ public Av1BlockModeInfo? AboveModeInfoForChroma { get; set; }
+
+ public Av1BlockModeInfo? LeftModeInfoForChroma { get; set; }
+
+ public int[] CdefStrength { get; set; }
+
+ public int[] ReferenceFrame { get; set; }
+
+ public int ModeBlockToLeftEdge { get; private set; }
+
+ public int ModeBlockToRightEdge { get; private set; }
+
+ public int ModeBlockToTopEdge { get; private set; }
+
+ public int ModeBlockToBottomEdge { get; private set; }
+
+ public int[] WidthInPixels { get; private set; }
+
+ public int[] HeightInPixels { get; private set; }
+
+ public Av1ChromaFromLumaContext? ChromaFromLumaContext { get; internal set; }
+
+ public void ComputeBoundaryOffsets(Configuration configuration, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader, Av1TileInfo tileInfo)
+ {
+ Av1BlockSize blockSize = this.ModeInfo.BlockSize;
+ int bw4 = blockSize.Get4x4WideCount();
+ int bh4 = blockSize.Get4x4HighCount();
+ int subX = sequenceHeader.ColorConfig.SubSamplingX ? 1 : 0;
+ int subY = sequenceHeader.ColorConfig.SubSamplingY ? 1 : 0;
+ this.AvailableAbove = this.RowIndex > tileInfo.ModeInfoRowStart;
+ this.AvailableLeft = this.ColumnIndex > tileInfo.ModeInfoColumnStart;
+ this.AvailableAboveForChroma = this.AvailableAbove;
+ this.AvailableLeftForChroma = this.AvailableLeft;
+
+ int shift = Av1Constants.ModeInfoSizeLog2 + 3;
+ this.ModeBlockToLeftEdge = -this.ColumnIndex << shift;
+ this.ModeBlockToRightEdge = (frameHeader.ModeInfoColumnCount - bw4 - this.ColumnIndex) << shift;
+ this.ModeBlockToTopEdge = -this.RowIndex << shift;
+ this.ModeBlockToBottomEdge = (frameHeader.ModeInfoRowCount - bh4 - this.RowIndex) << shift;
+
+ // Block Size width & height in pixels.
+ // For Luma bock
+ const int modeInfoSize = 1 << Av1Constants.ModeInfoSizeLog2;
+ this.WidthInPixels[0] = bw4 * modeInfoSize;
+ this.HeightInPixels[0] = bh4 * modeInfoSize;
+
+ // For U plane chroma bock
+ this.WidthInPixels[1] = Math.Max(1, bw4 >> subX) * modeInfoSize;
+ this.HeightInPixels[1] = Math.Max(1, bh4 >> subY) * modeInfoSize;
+
+ // For V plane chroma bock
+ this.WidthInPixels[2] = Math.Max(1, bw4 >> subX) * modeInfoSize;
+ this.HeightInPixels[2] = Math.Max(1, bh4 >> subY) * modeInfoSize;
+
+ this.ChromaFromLumaContext = new Av1ChromaFromLumaContext(configuration, sequenceHeader.ColorConfig);
+ }
+
+ public int GetMaxBlockWide(Av1BlockSize blockSize, bool subX)
+ {
+ int maxBlockWide = blockSize.GetWidth();
+ if (this.ModeBlockToRightEdge < 0)
+ {
+ int shift = subX ? 4 : 3;
+ maxBlockWide += this.ModeBlockToRightEdge >> shift;
+ }
+
+ return maxBlockWide >> 2;
+ }
+
+ public int GetMaxBlockHigh(Av1BlockSize blockSize, bool subY)
+ {
+ int maxBlockHigh = blockSize.GetHeight();
+ if (this.ModeBlockToBottomEdge < 0)
+ {
+ int shift = subY ? 4 : 3;
+ maxBlockHigh += this.ModeBlockToBottomEdge >> shift;
+ }
+
+ return maxBlockHigh >> 2;
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PictureControlSet.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PictureControlSet.cs
new file mode 100644
index 0000000000..7e6978edaf
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PictureControlSet.cs
@@ -0,0 +1,89 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1PictureControlSet
+{
+ public required Av1NeighborArrayUnit[] PartitionContexts { get; internal set; }
+
+ public required Av1NeighborArrayUnit[] LuminanceDcSignLevelCoefficientNeighbors { get; internal set; }
+
+ public required Av1NeighborArrayUnit[] CrDcSignLevelCoefficientNeighbors { get; internal set; }
+
+ public required Av1NeighborArrayUnit[] CbDcSignLevelCoefficientNeighbors { get; internal set; }
+
+ public required Av1NeighborArrayUnit[] TransformFunctionContexts { get; internal set; }
+
+ public required Av1SequenceControlSet Sequence { get; internal set; }
+
+ public required Av1PictureParentControlSet Parent { get; internal set; }
+
+ public required byte[] SegmentationNeighborMap { get; internal set; }
+
+ public Av1ModeInfo[][] ModeInfoGrid { get; } = [];
+
+ public required Av1ModeInfo[] Mip { get; internal set; }
+
+ public int ModeInfoStride { get; internal set; }
+
+ // true if 4x4 blocks are disallowed for all frames, and NSQ is disabled (since granularity is
+ // needed for 8x8 NSQ blocks). Used to compute the offset for mip.
+ public bool Disallow4x4AllFrames { get; internal set; }
+
+ public required int[][] CdefPreset { get; internal set; }
+
+ public Span GetFromModeInfoGrid(Point position)
+ => this.ModeInfoGrid[(position.Y * this.ModeInfoStride) + position.X];
+
+ public void SetModeInfoGridRow(Point position, Span span)
+ => this.SetModeInfoGridRow((position.Y * this.ModeInfoStride) + position.X, span);
+
+ public void SetModeInfoGridRow(int offset, Span span)
+ {
+ this.ModeInfoGrid[offset] = new Av1ModeInfo[span.Length];
+ span.CopyTo(this.ModeInfoGrid[offset]);
+ }
+
+ ///
+ /// SVT: get_mbmi
+ ///
+ internal Av1MacroBlockModeInfo GetMacroBlockModeInfo(Point blockOrigin)
+ {
+ int modeInfoStride = this.ModeInfoStride;
+ int offset = (blockOrigin.Y * modeInfoStride) + blockOrigin.X;
+
+ // Reset the mi_grid (needs to be done here in case it was changed for NSQ blocks during MD - svt_aom_init_xd())
+ // mip offset may be different from grid offset when 4x4 blocks are disallowed
+ int disallow4x4 = this.Disallow4x4AllFrames ? 1 : 0;
+ int mipOffset = ((blockOrigin.Y >> disallow4x4) * (modeInfoStride >> disallow4x4)) + (blockOrigin.X >> disallow4x4);
+ this.SetModeInfoGridRow(offset, ((Span)this.Mip)[mipOffset..]);
+
+ // use idx 0 as that's the first MacroBlockModeInfo in the block.
+ Av1ModeInfo modeInfo = this.ModeInfoGrid[offset][0];
+ return modeInfo.MacroBlockModeInfo;
+ }
+
+ ///
+ /// SVT: svt_av1_update_segmentation_map
+ ///
+ internal void UpdateSegmentation(Av1BlockSize blockSize, Point origin, int segmentId)
+ {
+ Av1EncoderCommon cm = this.Parent.Common;
+ Span segment_ids = this.SegmentationNeighborMap;
+ int mi_col = origin.X >> Av1Constants.ModeInfoSizeLog2;
+ int mi_row = origin.Y >> Av1Constants.ModeInfoSizeLog2;
+ int mi_offset = (mi_row * cm.ModeInfoColumnCount) + mi_col;
+ int bw = blockSize.GetWidth();
+ int bh = blockSize.GetHeight();
+ int xmis = Math.Min(cm.ModeInfoColumnCount - mi_col, bw);
+ int ymis = Math.Min(cm.ModeInfoRowCount - mi_row, bh);
+ for (int y = 0; y < ymis; ++y)
+ {
+ int offset = mi_offset + (y * cm.ModeInfoColumnCount);
+ segment_ids.Slice(offset, xmis).Fill((byte)segmentId);
+ }
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PictureParentControlSet.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PictureParentControlSet.cs
new file mode 100644
index 0000000000..2317f97f74
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PictureParentControlSet.cs
@@ -0,0 +1,23 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1PictureParentControlSet
+{
+ public required Av1EncoderCommon Common { get; internal set; }
+
+ public required ObuFrameHeader FrameHeader { get; internal set; }
+
+ public required int[] PreviousQIndex { get; internal set; }
+
+ public int PaletteLevel { get; internal set; }
+
+ public int AlignedWidth { get; internal set; }
+
+ public int AlignedHeight { get; internal set; }
+
+ public required Av1SuperblockGeometry[] SuperblockGeometry { get; internal set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PlaneType.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PlaneType.cs
new file mode 100644
index 0000000000..3c790f5092
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PlaneType.cs
@@ -0,0 +1,10 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal enum Av1PlaneType : int
+{
+ Y,
+ Uv
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SequenceControlSet.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SequenceControlSet.cs
new file mode 100644
index 0000000000..e19b7ba7b4
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SequenceControlSet.cs
@@ -0,0 +1,13 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1SequenceControlSet
+{
+ public required ObuSequenceHeader SequenceHeader { get; internal set; }
+
+ public int MaxBlockCount { get; internal set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1Superblock.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1Superblock.cs
new file mode 100644
index 0000000000..a4d1465951
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1Superblock.cs
@@ -0,0 +1,17 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using static SixLabors.ImageSharp.Formats.Heif.Av1.Tiling.Av1TileWriter;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1Superblock
+{
+ public required Av1EncoderBlockStruct[] FinalBlocks { get; set; }
+
+ public required Av1TileInfo TileInfo { get; set; }
+
+ public required Av1PartitionType[] CodingUnitPartitionTypes { get; internal set; }
+
+ public int Index { get; internal set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SuperblockGeometry.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SuperblockGeometry.cs
new file mode 100644
index 0000000000..6422b88cde
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SuperblockGeometry.cs
@@ -0,0 +1,9 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1SuperblockGeometry
+{
+ public bool IsComplete { get; internal set; }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SuperblockInfo.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SuperblockInfo.cs
new file mode 100644
index 0000000000..4f84d21a76
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SuperblockInfo.cs
@@ -0,0 +1,59 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1SuperblockInfo
+{
+ private readonly Av1FrameInfo frameInfo;
+
+ public Av1SuperblockInfo(Av1FrameInfo frameInfo, Point position)
+ {
+ this.Position = position;
+ this.frameInfo = frameInfo;
+ }
+
+ ///
+ /// Gets the position of this superblock inside the tile, counted in superblocks.
+ ///
+ public Point Position { get; }
+
+ ///
+ /// Gets the position of this superblock inside the tile, counted in mode info blocks (of 4x4 pixels).
+ ///
+ public Point ModeInfoPosition => this.Position * this.frameInfo.SuperblockModeInfoSize;
+
+ public ref int SuperblockDeltaQ => ref this.frameInfo.GetDeltaQuantizationIndex(this.Position);
+
+ public Av1BlockModeInfo SuperblockModeInfo => this.GetModeInfo(new Point(0, 0));
+
+ public Span CoefficientsY => this.frameInfo.GetCoefficientsY(this.Position);
+
+ public Span CoefficientsU => this.frameInfo.GetCoefficientsU(this.Position);
+
+ public Span CoefficientsV => this.frameInfo.GetCoefficientsV(this.Position);
+
+ public Span CdefStrength => this.frameInfo.GetCdefStrength(this.Position);
+
+ public Span SuperblockDeltaLoopFilter => this.frameInfo.GetDeltaLoopFilter(this.Position);
+
+ public int TransformInfoIndexY { get; internal set; }
+
+ public int TransformInfoIndexUv { get; internal set; }
+
+ public int BlockCount { get; internal set; }
+
+ public Span GetTransformInfoY() => this.frameInfo.GetSuperblockTransformY(this.Position);
+
+ public Span GetTransformInfoUv() => this.frameInfo.GetSuperblockTransformUv(this.Position);
+
+ public Av1BlockModeInfo GetModeInfo(Point index) => this.frameInfo.GetModeInfo(this.Position, index);
+
+ public Span GetCoefficients(Av1Plane plane) => plane switch
+ {
+ Av1Plane.Y => this.CoefficientsY,
+ Av1Plane.U => this.CoefficientsU,
+ Av1Plane.V => this.CoefficientsV,
+ _ => []
+ };
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileInfo.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileInfo.cs
new file mode 100644
index 0000000000..52a6d0d709
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileInfo.cs
@@ -0,0 +1,52 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1TileInfo
+{
+ public Av1TileInfo(int row, int column, ObuFrameHeader frameHeader)
+ {
+ this.SetTileRow(frameHeader.TilesInfo, frameHeader.ModeInfoRowCount, row);
+ this.SetTileColumn(frameHeader.TilesInfo, frameHeader.ModeInfoColumnCount, column);
+ }
+
+ public Av1TileInfo(Av1TileInfo tileInfo)
+ {
+ this.ModeInfoColumnStart = tileInfo.ModeInfoColumnStart;
+ this.ModeInfoColumnEnd = tileInfo.ModeInfoColumnEnd;
+ this.ModeInfoRowStart = tileInfo.ModeInfoRowStart;
+ this.ModeInfoRowEnd = tileInfo.ModeInfoRowEnd;
+ this.TileIndex = tileInfo.TileIndex;
+ }
+
+ public int ModeInfoRowStart { get; private set; }
+
+ public int ModeInfoRowEnd { get; private set; }
+
+ public int ModeInfoColumnStart { get; private set; }
+
+ public int ModeInfoColumnEnd { get; private set; }
+
+ public Point TileIndex { get; private set; }
+
+ public void SetTileRow(ObuTileGroupHeader tileGroupHeader, int modeInfoRowCount, int row)
+ {
+ this.ModeInfoRowStart = tileGroupHeader.TileRowStartModeInfo[row];
+ this.ModeInfoRowEnd = Math.Min(tileGroupHeader.TileRowStartModeInfo[row + 1], modeInfoRowCount);
+ Point loc = this.TileIndex;
+ loc.Y = row;
+ this.TileIndex = loc;
+ }
+
+ public void SetTileColumn(ObuTileGroupHeader tileGroupHeader, int modeInfoColumnCount, int column)
+ {
+ this.ModeInfoColumnStart = tileGroupHeader.TileColumnStartModeInfo[column];
+ this.ModeInfoColumnEnd = Math.Min(tileGroupHeader.TileColumnStartModeInfo[column + 1], modeInfoColumnCount);
+ Point loc = this.TileIndex;
+ loc.X = column;
+ this.TileIndex = loc;
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileReader.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileReader.cs
new file mode 100644
index 0000000000..c6acbb6505
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileReader.cs
@@ -0,0 +1,1383 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Runtime.CompilerServices;
+using SixLabors.ImageSharp.Formats.Heif.Av1;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Entropy;
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal class Av1TileReader : IAv1TileReader
+{
+ private static readonly int[] SgrprojXqdMid = [-32, 31];
+ private static readonly int[] WienerTapsMid = [3, -7, 15];
+ private static readonly int[] Signs = [0, -1, 1];
+ private static readonly int[] DcSignContexts = [
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2];
+
+ private static readonly int[][] SkipContexts = [
+ [1, 2, 2, 2, 3], [1, 4, 4, 4, 5], [1, 4, 4, 4, 5], [1, 4, 4, 4, 5], [1, 4, 4, 4, 6]];
+
+ private int[][] referenceSgrXqd = [];
+ private int[][][] referenceLrWiener = [];
+ private readonly Av1ParseAboveNeighbor4x4Context aboveNeighborContext;
+ private readonly Av1ParseLeftNeighbor4x4Context leftNeighborContext;
+ private int currentQuantizerIndex;
+ private readonly int[][] segmentIds = [];
+ private readonly int[][] transformUnitCount;
+ private readonly int[] firstTransformOffset = new int[2];
+ private readonly int[] coefficientIndex = [];
+ private readonly Configuration configuration;
+ private readonly IAv1FrameDecoder frameDecoder;
+
+ public Av1TileReader(Configuration configuration, ObuSequenceHeader sequenceHeader, ObuFrameHeader frameHeader, IAv1FrameDecoder frameDecoder)
+ {
+ this.FrameHeader = frameHeader;
+ this.configuration = configuration;
+ this.SequenceHeader = sequenceHeader;
+ this.frameDecoder = frameDecoder;
+
+ // init_main_frame_ctxt
+ this.FrameInfo = new(this.SequenceHeader);
+ this.segmentIds = new int[this.FrameHeader.ModeInfoRowCount][];
+ for (int y = 0; y < this.FrameHeader.ModeInfoRowCount; y++)
+ {
+ this.segmentIds[y] = new int[this.FrameHeader.ModeInfoColumnCount];
+ }
+
+ // reallocate_parse_context_memory
+ // Hard code number of threads to 1 for now.
+ int planesCount = sequenceHeader.ColorConfig.PlaneCount;
+ int superblockColumnCount =
+ Av1Math.AlignPowerOf2(sequenceHeader.MaxFrameWidth, sequenceHeader.SuperblockSizeLog2) >> sequenceHeader.SuperblockSizeLog2;
+ int modeInfoWideColumnCount = superblockColumnCount * sequenceHeader.SuperblockModeInfoSize;
+ modeInfoWideColumnCount = Av1Math.AlignPowerOf2(modeInfoWideColumnCount, sequenceHeader.SuperblockSizeLog2 - Av1Constants.ModeInfoSizeLog2);
+ this.aboveNeighborContext = new Av1ParseAboveNeighbor4x4Context(planesCount, modeInfoWideColumnCount);
+ this.leftNeighborContext = new Av1ParseLeftNeighbor4x4Context(planesCount, sequenceHeader.SuperblockModeInfoSize);
+ this.transformUnitCount = new int[Av1Constants.MaxPlanes][];
+ this.transformUnitCount[0] = new int[this.FrameInfo.ModeInfoCount];
+ this.transformUnitCount[1] = new int[this.FrameInfo.ModeInfoCount];
+ this.transformUnitCount[2] = new int[this.FrameInfo.ModeInfoCount];
+ this.coefficientIndex = new int[Av1Constants.MaxPlanes];
+ }
+
+ public ObuFrameHeader FrameHeader { get; }
+
+ public ObuSequenceHeader SequenceHeader { get; }
+
+ public Av1FrameInfo FrameInfo { get; }
+
+ ///
+ /// SVT: parse_tile
+ ///
+ public void ReadTile(Span tileData, int tileNum)
+ {
+ Av1SymbolDecoder reader = new(this.configuration, tileData, this.FrameHeader.QuantizationParameters.BaseQIndex);
+ int tileColumnIndex = tileNum % this.FrameHeader.TilesInfo.TileColumnCount;
+ int tileRowIndex = tileNum / this.FrameHeader.TilesInfo.TileColumnCount;
+
+ int modeInfoColumnStart = this.FrameHeader.TilesInfo.TileColumnStartModeInfo[tileColumnIndex];
+ int modeInfoColumnEnd = this.FrameHeader.TilesInfo.TileColumnStartModeInfo[tileColumnIndex + 1];
+ int modeInfoRowStart = this.FrameHeader.TilesInfo.TileRowStartModeInfo[tileRowIndex];
+ int modeInfoRowEnd = this.FrameHeader.TilesInfo.TileRowStartModeInfo[tileRowIndex + 1];
+ this.aboveNeighborContext.Clear(this.SequenceHeader, modeInfoColumnStart, modeInfoColumnEnd);
+ this.ClearLoopFilterDelta();
+ int planesCount = this.SequenceHeader.ColorConfig.PlaneCount;
+
+ // Default initialization of Wiener and SGR Filter.
+ this.referenceSgrXqd = new int[planesCount][];
+ this.referenceLrWiener = new int[planesCount][][];
+ for (int plane = 0; plane < planesCount; plane++)
+ {
+ this.referenceSgrXqd[plane] = new int[2];
+ Array.Copy(SgrprojXqdMid, this.referenceSgrXqd[plane], SgrprojXqdMid.Length);
+ this.referenceLrWiener[plane] = new int[2][];
+ for (int pass = 0; pass < 2; pass++)
+ {
+ this.referenceLrWiener[plane][pass] = new int[Av1Constants.WienerCoefficientCount];
+ Array.Copy(WienerTapsMid, this.referenceLrWiener[plane][pass], WienerTapsMid.Length);
+ }
+ }
+
+ Av1TileInfo tileInfo = new(tileRowIndex, tileColumnIndex, this.FrameHeader);
+ Av1BlockSize superBlockSize = this.SequenceHeader.SuperblockSize;
+ int superBlock4x4Size = this.SequenceHeader.SuperblockSize.Get4x4WideCount();
+ int superBlockSizeLog2 = this.SequenceHeader.SuperblockSizeLog2;
+ for (int row = modeInfoRowStart; row < modeInfoRowEnd; row += superBlock4x4Size)
+ {
+ int superBlockRow = (row << Av1Constants.ModeInfoSizeLog2) >> superBlockSizeLog2;
+ this.leftNeighborContext.Clear(this.SequenceHeader);
+ for (int column = modeInfoColumnStart; column < modeInfoColumnEnd; column += superBlock4x4Size)
+ {
+ int superBlockColumn = (column << Av1Constants.ModeInfoSizeLog2) >> superBlockSizeLog2;
+ Point superblockPosition = new(superBlockColumn, superBlockRow);
+ Av1SuperblockInfo superblockInfo = this.FrameInfo.GetSuperblock(superblockPosition);
+
+ Point modeInfoPosition = new(column, row);
+ this.FrameInfo.ClearCdef(superblockPosition);
+ this.firstTransformOffset[0] = 0;
+ this.firstTransformOffset[1] = 0;
+ this.ReadLoopRestoration(modeInfoPosition, superBlockSize);
+ this.ParsePartition(ref reader, modeInfoPosition, superBlockSize, superblockInfo, tileInfo);
+
+ // decoding of the superblock
+ this.frameDecoder.DecodeSuperblock(modeInfoPosition, superblockInfo, tileInfo);
+ }
+ }
+ }
+
+ private void ClearLoopFilterDelta()
+ => this.FrameInfo.ClearDeltaLoopFilter();
+
+ private void ReadLoopRestoration(Point modeInfoLocation, Av1BlockSize superBlockSize)
+ {
+ int planesCount = this.SequenceHeader.ColorConfig.PlaneCount;
+ for (int plane = 0; plane < planesCount; plane++)
+ {
+ if (this.FrameHeader.LoopRestorationParameters.Items[plane].Type != ObuRestorationType.None)
+ {
+ // TODO: Implement.
+ throw new NotImplementedException("No loop restoration filter support.");
+ }
+ }
+ }
+
+ ///
+ /// 5.11.4. Decode partition syntax.
+ ///
+ private void ParsePartition(ref Av1SymbolDecoder reader, Point modeInfoLocation, Av1BlockSize blockSize, Av1SuperblockInfo superblockInfo, Av1TileInfo tileInfo)
+ {
+ int columnIndex = modeInfoLocation.X;
+ int rowIndex = modeInfoLocation.Y;
+ if (modeInfoLocation.Y >= this.FrameHeader.ModeInfoRowCount || modeInfoLocation.X >= this.FrameHeader.ModeInfoColumnCount)
+ {
+ return;
+ }
+
+ int block4x4Size = blockSize.Get4x4WideCount();
+ int halfBlock4x4Size = block4x4Size >> 1;
+ int quarterBlock4x4Size = halfBlock4x4Size >> 1;
+ bool hasRows = (modeInfoLocation.Y + halfBlock4x4Size) < this.FrameHeader.ModeInfoRowCount;
+ bool hasColumns = (modeInfoLocation.X + halfBlock4x4Size) < this.FrameHeader.ModeInfoColumnCount;
+ Av1PartitionType partitionType = Av1PartitionType.None;
+ if (blockSize >= Av1BlockSize.Block8x8)
+ {
+ int ctx = this.GetPartitionPlaneContext(modeInfoLocation, blockSize, tileInfo, superblockInfo);
+ partitionType = Av1PartitionType.Split;
+ if (blockSize < Av1BlockSize.Block8x8)
+ {
+ partitionType = Av1PartitionType.None;
+ }
+ else if (hasRows && hasColumns)
+ {
+ partitionType = reader.ReadPartitionType(ctx);
+ }
+ else if (hasColumns)
+ {
+ partitionType = reader.ReadSplitOrHorizontal(blockSize, ctx);
+ }
+ else if (hasRows)
+ {
+ partitionType = reader.ReadSplitOrVertical(blockSize, ctx);
+ }
+ }
+
+ Av1BlockSize subSize = partitionType.GetBlockSubSize(blockSize);
+ Av1BlockSize splitSize = Av1PartitionType.Split.GetBlockSubSize(blockSize);
+ switch (partitionType)
+ {
+ case Av1PartitionType.Split:
+ Point loc1 = new(modeInfoLocation.X + halfBlock4x4Size, modeInfoLocation.Y);
+ Point loc2 = new(modeInfoLocation.X, modeInfoLocation.Y + halfBlock4x4Size);
+ Point loc3 = new(modeInfoLocation.X + halfBlock4x4Size, modeInfoLocation.Y + halfBlock4x4Size);
+ this.ParsePartition(ref reader, modeInfoLocation, subSize, superblockInfo, tileInfo);
+ this.ParsePartition(ref reader, loc1, subSize, superblockInfo, tileInfo);
+ this.ParsePartition(ref reader, loc2, subSize, superblockInfo, tileInfo);
+ this.ParsePartition(ref reader, loc3, subSize, superblockInfo, tileInfo);
+ break;
+ case Av1PartitionType.None:
+ this.ParseBlock(ref reader, modeInfoLocation, subSize, superblockInfo, tileInfo, Av1PartitionType.None);
+ break;
+ case Av1PartitionType.Horizontal:
+ this.ParseBlock(ref reader, modeInfoLocation, subSize, superblockInfo, tileInfo, Av1PartitionType.Horizontal);
+ if (hasRows)
+ {
+ Point halfLocation = new(columnIndex, rowIndex + halfBlock4x4Size);
+ this.ParseBlock(ref reader, halfLocation, subSize, superblockInfo, tileInfo, Av1PartitionType.Horizontal);
+ }
+
+ break;
+ case Av1PartitionType.Vertical:
+ this.ParseBlock(ref reader, modeInfoLocation, subSize, superblockInfo, tileInfo, Av1PartitionType.Vertical);
+ if (hasColumns)
+ {
+ Point halfLocation = new(columnIndex + halfBlock4x4Size, rowIndex);
+ this.ParseBlock(ref reader, halfLocation, subSize, superblockInfo, tileInfo, Av1PartitionType.Vertical);
+ }
+
+ break;
+ case Av1PartitionType.HorizontalA:
+ this.ParseBlock(ref reader, modeInfoLocation, splitSize, superblockInfo, tileInfo, Av1PartitionType.HorizontalA);
+ Point locHorA1 = new(columnIndex + halfBlock4x4Size, rowIndex);
+ this.ParseBlock(ref reader, locHorA1, splitSize, superblockInfo, tileInfo, Av1PartitionType.HorizontalA);
+ Point locHorA2 = new(columnIndex, rowIndex + halfBlock4x4Size);
+ this.ParseBlock(ref reader, locHorA2, subSize, superblockInfo, tileInfo, Av1PartitionType.HorizontalA);
+ break;
+ case Av1PartitionType.HorizontalB:
+ this.ParseBlock(ref reader, modeInfoLocation, subSize, superblockInfo, tileInfo, Av1PartitionType.HorizontalB);
+ Point locHorB1 = new(columnIndex, rowIndex + halfBlock4x4Size);
+ this.ParseBlock(ref reader, locHorB1, splitSize, superblockInfo, tileInfo, Av1PartitionType.HorizontalB);
+ Point locHorB2 = new(columnIndex + halfBlock4x4Size, rowIndex + halfBlock4x4Size);
+ this.ParseBlock(ref reader, locHorB2, splitSize, superblockInfo, tileInfo, Av1PartitionType.HorizontalB);
+ break;
+ case Av1PartitionType.VerticalA:
+ this.ParseBlock(ref reader, modeInfoLocation, splitSize, superblockInfo, tileInfo, Av1PartitionType.VerticalA);
+ Point locVertA1 = new(columnIndex, rowIndex + halfBlock4x4Size);
+ this.ParseBlock(ref reader, locVertA1, splitSize, superblockInfo, tileInfo, Av1PartitionType.VerticalA);
+ Point locVertA2 = new(columnIndex + halfBlock4x4Size, rowIndex);
+ this.ParseBlock(ref reader, locVertA2, subSize, superblockInfo, tileInfo, Av1PartitionType.VerticalA);
+ break;
+ case Av1PartitionType.VerticalB:
+ this.ParseBlock(ref reader, modeInfoLocation, subSize, superblockInfo, tileInfo, Av1PartitionType.VerticalB);
+ Point locVertB1 = new(columnIndex + halfBlock4x4Size, rowIndex);
+ this.ParseBlock(ref reader, locVertB1, splitSize, superblockInfo, tileInfo, Av1PartitionType.VerticalB);
+ Point locVertB2 = new(columnIndex + halfBlock4x4Size, rowIndex + halfBlock4x4Size);
+ this.ParseBlock(ref reader, locVertB2, splitSize, superblockInfo, tileInfo, Av1PartitionType.VerticalB);
+ break;
+ case Av1PartitionType.Horizontal4:
+ for (int i = 0; i < 4; i++)
+ {
+ int currentBlockRow = rowIndex + (i * quarterBlock4x4Size);
+ if (i > 0 && currentBlockRow >= this.FrameHeader.ModeInfoRowCount)
+ {
+ break;
+ }
+
+ Point currentLocation = new(modeInfoLocation.X, currentBlockRow);
+ this.ParseBlock(ref reader, currentLocation, subSize, superblockInfo, tileInfo, Av1PartitionType.Horizontal4);
+ }
+
+ break;
+ case Av1PartitionType.Vertical4:
+ for (int i = 0; i < 4; i++)
+ {
+ int currentBlockColumn = columnIndex + (i * quarterBlock4x4Size);
+ if (i > 0 && currentBlockColumn >= this.FrameHeader.ModeInfoColumnCount)
+ {
+ break;
+ }
+
+ Point currentLocation = new(currentBlockColumn, modeInfoLocation.Y);
+ this.ParseBlock(ref reader, currentLocation, subSize, superblockInfo, tileInfo, Av1PartitionType.Vertical4);
+ }
+
+ break;
+ default:
+ throw new NotImplementedException($"Partition type: {partitionType} is not supported.");
+ }
+
+ this.UpdatePartitionContext(new Point(columnIndex, rowIndex), tileInfo, superblockInfo, subSize, blockSize, partitionType);
+ }
+
+ private void ParseBlock(ref Av1SymbolDecoder reader, Point modeInfoLocation, Av1BlockSize blockSize, Av1SuperblockInfo superblockInfo, Av1TileInfo tileInfo, Av1PartitionType partitionType)
+ {
+ int rowIndex = modeInfoLocation.Y;
+ int columnIndex = modeInfoLocation.X;
+ int block4x4Width = blockSize.Get4x4WideCount();
+ int block4x4Height = blockSize.Get4x4HighCount();
+ int planesCount = this.SequenceHeader.ColorConfig.PlaneCount;
+ int subX = this.SequenceHeader.ColorConfig.SubSamplingX ? 1 : 0;
+ int subY = this.SequenceHeader.ColorConfig.SubSamplingY ? 1 : 0;
+ Point superblockLocation = superblockInfo.Position * this.SequenceHeader.SuperblockModeInfoSize;
+ Point locationInSuperblock = new Point(modeInfoLocation.X - superblockLocation.X, modeInfoLocation.Y - superblockLocation.Y);
+ Av1BlockModeInfo blockModeInfo = new(planesCount, blockSize, locationInSuperblock);
+ blockModeInfo.PartitionType = partitionType;
+ blockModeInfo.FirstTransformLocation[0] = this.firstTransformOffset[0];
+ blockModeInfo.FirstTransformLocation[1] = this.firstTransformOffset[1];
+ bool hasChroma = HasChroma(this.SequenceHeader, modeInfoLocation, blockSize);
+ Av1PartitionInfo partitionInfo = new(blockModeInfo, superblockInfo, hasChroma, partitionType);
+ partitionInfo.ColumnIndex = columnIndex;
+ partitionInfo.RowIndex = rowIndex;
+ superblockInfo.BlockCount++;
+ partitionInfo.ComputeBoundaryOffsets(this.configuration, this.SequenceHeader, this.FrameHeader, tileInfo);
+ if (hasChroma)
+ {
+ if (this.SequenceHeader.ColorConfig.SubSamplingY && block4x4Height == 1)
+ {
+ partitionInfo.AvailableAboveForChroma = this.IsInside(rowIndex - 2, columnIndex);
+ }
+
+ if (this.SequenceHeader.ColorConfig.SubSamplingX && block4x4Width == 1)
+ {
+ partitionInfo.AvailableLeftForChroma = this.IsInside(rowIndex, columnIndex - 2);
+ }
+ }
+
+ if (partitionInfo.AvailableAbove)
+ {
+ partitionInfo.AboveModeInfo = superblockInfo.GetModeInfo(new Point(rowIndex - 1, columnIndex));
+ }
+
+ if (partitionInfo.AvailableLeft)
+ {
+ partitionInfo.LeftModeInfo = superblockInfo.GetModeInfo(new Point(rowIndex, columnIndex - 1));
+ }
+
+ if (partitionInfo.AvailableAboveForChroma)
+ {
+ partitionInfo.AboveModeInfoForChroma = superblockInfo.GetModeInfo(new Point(rowIndex & ~subY, columnIndex | subX));
+ }
+
+ if (partitionInfo.AvailableLeftForChroma)
+ {
+ partitionInfo.LeftModeInfoForChroma = superblockInfo.GetModeInfo(new Point(rowIndex | subY, columnIndex & ~subX));
+ }
+
+ this.ReadModeInfo(ref reader, partitionInfo);
+ ReadPaletteTokens(ref reader, partitionInfo);
+ this.ReadBlockTransformSize(ref reader, modeInfoLocation, partitionInfo, superblockInfo, tileInfo);
+ if (partitionInfo.ModeInfo.Skip)
+ {
+ this.ResetSkipContext(partitionInfo, tileInfo);
+ }
+
+ this.Residual(ref reader, partitionInfo, superblockInfo, tileInfo, blockSize);
+
+ // Update the Frame buffer for this ModeInfo.
+ this.FrameInfo.UpdateModeInfo(blockModeInfo, superblockInfo);
+ }
+
+ ///
+ /// SVT: reset_skip_context
+ ///
+ private void ResetSkipContext(Av1PartitionInfo partitionInfo, Av1TileInfo tileInfo)
+ {
+ int planesCount = this.SequenceHeader.ColorConfig.PlaneCount;
+ for (int i = 0; i < planesCount; i++)
+ {
+ int subX = (i > 0 && this.SequenceHeader.ColorConfig.SubSamplingX) ? 1 : 0;
+ int subY = (i > 0 && this.SequenceHeader.ColorConfig.SubSamplingY) ? 1 : 0;
+ Av1BlockSize planeBlockSize = partitionInfo.ModeInfo.BlockSize.GetSubsampled(subX, subY);
+ DebugGuard.IsTrue(planeBlockSize != Av1BlockSize.Invalid, nameof(planeBlockSize));
+ int txsWide = planeBlockSize.GetWidth() >> 2;
+ int txsHigh = planeBlockSize.GetHeight() >> 2;
+ int aboveOffset = (partitionInfo.ColumnIndex - tileInfo.ModeInfoColumnStart) >> subX;
+ int leftOffset = (partitionInfo.RowIndex - partitionInfo.SuperblockInfo.ModeInfoPosition.Y) >> subY;
+ this.aboveNeighborContext.ClearContext(i, aboveOffset, txsWide);
+ this.leftNeighborContext.ClearContext(i, leftOffset, txsHigh);
+ }
+ }
+
+ ///
+ /// 5.11.34. Residual syntax.
+ ///
+ private void Residual(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo, Av1SuperblockInfo superblockInfo, Av1TileInfo tileInfo, Av1BlockSize blockSize)
+ {
+ int maxBlocksWide = partitionInfo.GetMaxBlockWide(blockSize, false);
+ int maxBlocksHigh = partitionInfo.GetMaxBlockHigh(blockSize, false);
+ Av1BlockSize maxUnitSize = Av1BlockSize.Block64x64;
+ int modeUnitBlocksWide = maxUnitSize.GetWidth() >> 2;
+ int modeUnitBlocksHigh = maxUnitSize.GetHeight() >> 2;
+ modeUnitBlocksWide = Math.Min(maxBlocksWide, modeUnitBlocksWide);
+ modeUnitBlocksHigh = Math.Min(maxBlocksHigh, modeUnitBlocksHigh);
+ int planeCount = this.SequenceHeader.ColorConfig.PlaneCount;
+ bool isLossless = this.FrameHeader.LosslessArray[partitionInfo.ModeInfo.SegmentId];
+ bool isLosslessBlock = isLossless && (blockSize >= Av1BlockSize.Block64x64) && (blockSize <= Av1BlockSize.Block128x128);
+ int subSampling = (this.SequenceHeader.ColorConfig.SubSamplingX ? 1 : 0) + (this.SequenceHeader.ColorConfig.SubSamplingY ? 1 : 0);
+ int chromaTransformUnitCount = isLosslessBlock ? ((maxBlocksWide * maxBlocksHigh) >> subSampling) : partitionInfo.ModeInfo.TransformUnitsCount[(int)Av1PlaneType.Uv];
+
+ int[] transformInfoIndices = new int[3];
+ transformInfoIndices[0] = superblockInfo.TransformInfoIndexY + partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Y];
+ transformInfoIndices[1] = superblockInfo.TransformInfoIndexUv + partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Uv];
+ transformInfoIndices[2] = transformInfoIndices[1] + chromaTransformUnitCount;
+ int forceSplitCount = 0;
+
+ for (int row = 0; row < maxBlocksHigh; row += modeUnitBlocksHigh)
+ {
+ for (int column = 0; column < maxBlocksWide; column += modeUnitBlocksWide)
+ {
+ for (int plane = 0; plane < planeCount; ++plane)
+ {
+ int totalTransformUnitCount;
+ int transformUnitCount;
+ int subX = (plane > 0 && this.SequenceHeader.ColorConfig.SubSamplingX) ? 1 : 0;
+ int subY = (plane > 0 && this.SequenceHeader.ColorConfig.SubSamplingY) ? 1 : 0;
+
+ if (plane != 0 && !partitionInfo.IsChroma)
+ {
+ continue;
+ }
+
+ Span transformInfoSpan = (plane == 0) ? superblockInfo.GetTransformInfoY() : superblockInfo.GetTransformInfoUv();
+ if (isLosslessBlock)
+ {
+ // TODO: Implement.
+ int unitHeight = Av1Math.RoundPowerOf2(Math.Min(modeUnitBlocksHigh + row, maxBlocksHigh), 0);
+ int unitWidth = Av1Math.RoundPowerOf2(Math.Min(modeUnitBlocksWide + column, maxBlocksWide), 0);
+ DebugGuard.IsTrue(transformInfoSpan[transformInfoIndices[plane]].Size == Av1TransformSize.Size4x4, "Lossless frame shall have transform units of size 4x4.");
+ transformUnitCount = ((unitWidth - column) * (unitHeight - row)) >> (subX + subY);
+ }
+ else
+ {
+ totalTransformUnitCount = partitionInfo.ModeInfo.TransformUnitsCount[Math.Min(1, plane)];
+ transformUnitCount = this.transformUnitCount[plane][forceSplitCount];
+
+ DebugGuard.IsFalse(totalTransformUnitCount == 0, nameof(totalTransformUnitCount), string.Empty);
+ DebugGuard.IsTrue(
+ totalTransformUnitCount ==
+ this.transformUnitCount[plane][0] + this.transformUnitCount[plane][1] +
+ this.transformUnitCount[plane][2] + this.transformUnitCount[plane][3],
+ nameof(totalTransformUnitCount),
+ string.Empty);
+ }
+
+ DebugGuard.IsFalse(transformUnitCount == 0, nameof(transformUnitCount), string.Empty);
+ for (int tu = 0; tu < transformUnitCount; tu++)
+ {
+ Av1TransformInfo transformInfo = transformInfoSpan[transformInfoIndices[plane]];
+ DebugGuard.MustBeLessThanOrEqualTo(transformInfo.OffsetX, maxBlocksWide, nameof(transformInfo));
+ DebugGuard.MustBeLessThanOrEqualTo(transformInfo.OffsetY, maxBlocksHigh, nameof(transformInfo));
+
+ int coefficientIndex = this.coefficientIndex[plane];
+ int endOfBlock = 0;
+ int blockColumn = transformInfo.OffsetX;
+ int blockRow = transformInfo.OffsetY;
+ int startX = (partitionInfo.ColumnIndex >> subX) + blockColumn;
+ int startY = (partitionInfo.RowIndex >> subY) + blockRow;
+
+ if (startX >= (this.FrameHeader.ModeInfoColumnCount >> subX) ||
+ startY >= (this.FrameHeader.ModeInfoRowCount >> subY))
+ {
+ return;
+ }
+
+ if (!partitionInfo.ModeInfo.Skip)
+ {
+ endOfBlock = this.ParseTransformBlock(ref reader, partitionInfo, coefficientIndex, transformInfo, plane, blockColumn, blockRow, startX, startY, transformInfo.Size, subX != 0, subY != 0);
+ }
+
+ if (endOfBlock != 0)
+ {
+ this.coefficientIndex[plane] += endOfBlock + 1;
+ transformInfo.CodeBlockFlag = true;
+ }
+ else
+ {
+ transformInfo.CodeBlockFlag = false;
+ }
+
+ transformInfoIndices[plane]++;
+ }
+ }
+
+ forceSplitCount++;
+ }
+ }
+ }
+
+ public static bool HasChroma(ObuSequenceHeader sequenceHeader, Point modeInfoLocation, Av1BlockSize blockSize)
+ {
+ int blockWide = blockSize.Get4x4WideCount();
+ int blockHigh = blockSize.Get4x4HighCount();
+ bool subX = sequenceHeader.ColorConfig.SubSamplingX;
+ bool subY = sequenceHeader.ColorConfig.SubSamplingY;
+ bool hasChroma = ((modeInfoLocation.Y & 0x01) != 0 || (blockHigh & 0x01) == 0 || !subY) &&
+ ((modeInfoLocation.X & 0x01) != 0 || (blockWide & 0x01) == 0 || !subX);
+ return hasChroma;
+ }
+
+ ///
+ /// 5.11.35. Transform block syntax.
+ ///
+ ///
+ /// The implementation is taken from SVT-AV1 library, which deviates from the code flow in the specification.
+ ///
+ private int ParseTransformBlock(
+ ref Av1SymbolDecoder reader,
+ Av1PartitionInfo partitionInfo,
+ int coefficientIndex,
+ Av1TransformInfo transformInfo,
+ int plane,
+ int blockColumn,
+ int blockRow,
+ int startX,
+ int startY,
+ Av1TransformSize transformSize,
+ bool subX,
+ bool subY)
+ {
+ int endOfBlock = 0;
+ Av1BlockSize planeBlockSize = partitionInfo.ModeInfo.BlockSize.GetSubsampled(subX, subY);
+ int transformBlockUnitWideCount = transformSize.Get4x4WideCount();
+ int transformBlockUnitHighCount = transformSize.Get4x4HighCount();
+
+ if (partitionInfo.ModeBlockToRightEdge < 0)
+ {
+ int blocksWide = partitionInfo.GetMaxBlockWide(planeBlockSize, subX);
+ transformBlockUnitWideCount = Math.Min(transformBlockUnitWideCount, blocksWide - blockColumn);
+ }
+
+ if (partitionInfo.ModeBlockToBottomEdge < 0)
+ {
+ int blocksHigh = partitionInfo.GetMaxBlockHigh(planeBlockSize, subY);
+ transformBlockUnitHighCount = Math.Min(transformBlockUnitHighCount, blocksHigh - blockRow);
+ }
+
+ Av1TransformBlockContext transformBlockContext = this.GetTransformBlockContext(transformSize, plane, planeBlockSize, transformBlockUnitHighCount, transformBlockUnitWideCount, startY, startX);
+ endOfBlock = this.ParseCoefficients(ref reader, partitionInfo, startY, startX, blockRow, blockColumn, plane, transformBlockContext, transformSize, coefficientIndex, transformInfo);
+
+ return endOfBlock;
+ }
+
+ ///
+ /// 5.11.39. Coefficients syntax.
+ ///
+ ///
+ /// The implementation is taken from SVT-AV1 library, which deviates from the code flow in the specification.
+ ///
+ private int ParseCoefficients(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo, int blockRow, int blockColumn, int aboveOffset, int leftOffset, int plane, Av1TransformBlockContext transformBlockContext, Av1TransformSize transformSize, int coefficientIndex, Av1TransformInfo transformInfo)
+ {
+ Span coefficientBuffer = this.FrameInfo.GetCoefficients(plane);
+ int width = transformSize.GetWidth();
+ int height = transformSize.GetHeight();
+ Av1TransformSize transformSizeContext = Av1SymbolContextHelper.GetTransformSizeContext(transformSize);
+ Av1PlaneType planeType = (Av1PlaneType)Math.Min(plane, 1);
+ Point blockPosition = new(blockColumn, blockRow);
+ bool isLossless = this.FrameHeader.LosslessArray[partitionInfo.ModeInfo.SegmentId];
+ bool subX = this.SequenceHeader.ColorConfig.SubSamplingX;
+ bool subY = this.SequenceHeader.ColorConfig.SubSamplingY;
+ Av1BlockSize planeBlockSize = partitionInfo.ModeInfo.BlockSize.GetSubsampled(subX, subY);
+ int blocksWide = partitionInfo.GetMaxBlockWide(planeBlockSize, subX);
+ int blocksHigh = partitionInfo.GetMaxBlockHigh(planeBlockSize, subY);
+
+ return reader.ReadCoefficients(partitionInfo.ModeInfo, blockPosition, this.aboveNeighborContext.GetContext(plane), this.leftNeighborContext.GetContext(plane), aboveOffset, leftOffset, plane, blocksWide, blocksHigh, transformBlockContext, transformSize, isLossless, this.FrameHeader.UseReducedTransformSet, transformInfo, partitionInfo.ModeBlockToRightEdge, partitionInfo.ModeBlockToBottomEdge, coefficientBuffer);
+ }
+
+ private Av1TransformBlockContext GetTransformBlockContext(Av1TransformSize transformSize, int plane, Av1BlockSize planeBlockSize, int transformBlockUnitHighCount, int transformBlockUnitWideCount, int startY, int startX)
+ {
+ Av1TransformBlockContext transformBlockContext = new();
+ int[] aboveContext = this.aboveNeighborContext.GetContext(plane);
+ int[] leftContext = this.leftNeighborContext.GetContext(plane);
+ int dcSign = 0;
+ int k = 0;
+ int mask = (1 << Av1Constants.CoefficientContextBitCount) - 1;
+
+ do
+ {
+ uint sign = (uint)aboveContext[k] >> Av1Constants.CoefficientContextBitCount;
+ DebugGuard.MustBeLessThanOrEqualTo(sign, 2U, nameof(sign));
+ dcSign += Signs[sign];
+ }
+ while (++k < transformBlockUnitWideCount);
+
+ k = 0;
+ do
+ {
+ uint sign = (uint)leftContext[k] >> Av1Constants.CoefficientContextBitCount;
+ DebugGuard.MustBeLessThanOrEqualTo(sign, 2U, nameof(sign));
+ dcSign += Signs[sign];
+ }
+ while (++k < transformBlockUnitHighCount);
+
+ transformBlockContext.DcSignContext = DcSignContexts[dcSign + (Av1Constants.MaxTransformSizeUnit << 1)];
+
+ if (plane == 0)
+ {
+ if (planeBlockSize == transformSize.ToBlockSize())
+ {
+ transformBlockContext.SkipContext = 0;
+ }
+ else
+ {
+ int top = 0;
+ int left = 0;
+
+ k = 0;
+ do
+ {
+ top |= aboveContext[k];
+ }
+ while (++k < transformBlockUnitWideCount);
+ top &= mask;
+
+ k = 0;
+ do
+ {
+ left |= leftContext[k];
+ }
+ while (++k < transformBlockUnitHighCount);
+ left &= mask;
+
+ int max = Math.Min(top | left, 4);
+ int min = Math.Min(Math.Min(top, left), 4);
+
+ transformBlockContext.SkipContext = SkipContexts[min][max];
+ }
+ }
+ else
+ {
+ int contextBase = GetEntropyContext(transformSize, aboveContext, leftContext);
+ int contextOffset = planeBlockSize.GetPelsLog2Count() > transformSize.ToBlockSize().GetPelsLog2Count() ? 10 : 7;
+ transformBlockContext.SkipContext = contextBase + contextOffset;
+ }
+
+ return transformBlockContext;
+ }
+
+ private static int GetEntropyContext(Av1TransformSize transformSize, int[] above, int[] left)
+ {
+ bool aboveEntropyContext = false;
+ bool leftEntropyContext = false;
+
+ switch (transformSize)
+ {
+ case Av1TransformSize.Size4x4:
+ aboveEntropyContext = above[0] != 0;
+ leftEntropyContext = left[0] != 0;
+ break;
+ case Av1TransformSize.Size4x8:
+ aboveEntropyContext = above[0] != 0;
+ leftEntropyContext = (left[0] & (left[1] << 8)) != 0; // !!*(const uint16_t*)left;
+ break;
+ case Av1TransformSize.Size8x4:
+ aboveEntropyContext = (above[0] & (above[1] << 8)) != 0; // !!*(const uint16_t*)above;
+ leftEntropyContext = left[0] != 0;
+ break;
+ case Av1TransformSize.Size8x16:
+ aboveEntropyContext = (above[0] & (above[1] << 8)) != 0; // !!*(const uint16_t*)above;
+ leftEntropyContext = (left[0] & (left[1] << 8) & (left[2] << 16) & (left[3] << 24)) != 0; // !!*(const uint32_t*)left;
+ break;
+ case Av1TransformSize.Size16x8:
+ aboveEntropyContext = (above[0] & (above[1] << 8) & (above[2] << 16) & (above[3] << 24)) != 0; // !!*(const uint32_t*)above;
+ leftEntropyContext = (left[0] & (left[1] << 8)) != 0; // !!*(const uint16_t*)left;
+ break;
+ case Av1TransformSize.Size16x32:
+ aboveEntropyContext = (above[0] & (above[1] << 8) & (above[2] << 16) & (above[3] << 24)) != 0; // !!*(const uint32_t*)above;
+ leftEntropyContext =
+ (left[0] & (left[1] << 8) & (left[2] << 16) & (left[3] << 24)) != 0 ||
+ (left[4] & (left[5] << 8) & (left[6] << 16) & (left[7] << 24)) != 0; // !!*(const uint64_t*)left;
+ break;
+ case Av1TransformSize.Size32x16:
+ aboveEntropyContext =
+ (above[0] & (above[1] << 8) & (above[2] << 16) & (above[3] << 24)) != 0 ||
+ (above[4] & (above[5] << 8) & (above[6] << 16) & (above[7] << 24)) != 0; // !!*(const uint64_t*)above;
+ leftEntropyContext = (left[0] & (left[1] << 8) & (left[2] << 16) & (left[3] << 24)) != 0; // !!*(const uint32_t*)left;
+ break;
+ case Av1TransformSize.Size8x8:
+ aboveEntropyContext = (above[0] & (above[1] << 8)) != 0; // !!*(const uint16_t*)above;
+ leftEntropyContext = (left[0] & (left[1] << 8)) != 0; // !!*(const uint16_t*)left;
+ break;
+ case Av1TransformSize.Size16x16:
+ aboveEntropyContext = (above[0] & (above[1] << 8) & (above[2] << 16) & (above[3] << 24)) != 0; // !!*(const uint32_t*)above;
+ leftEntropyContext = (left[0] & (left[1] << 8) & (left[2] << 16) & (left[3] << 24)) != 0; // !!*(const uint32_t*)left;
+ break;
+ case Av1TransformSize.Size32x32:
+ aboveEntropyContext =
+ (above[0] & (above[1] << 8) & (above[2] << 16) & (above[3] << 24)) != 0 ||
+ (above[4] & (above[5] << 8) & (above[6] << 16) & (above[7] << 24)) != 0; // !!*(const uint64_t*)above;
+ leftEntropyContext =
+ (left[0] & (left[1] << 8) & (left[2] << 16) & (left[3] << 24)) != 0 ||
+ (left[4] & (left[5] << 8) & (left[6] << 16) & (left[7] << 24)) != 0; // !!*(const uint64_t*)left;
+ break;
+ case Av1TransformSize.Size64x64:
+ aboveEntropyContext =
+ (above[0] & (above[1] << 8) & (above[2] << 16) & (above[3] << 24)) != 0 ||
+ (above[4] & (above[5] << 8) & (above[6] << 16) & (above[7] << 24)) != 0 ||
+ (above[8] & (above[9] << 8) & (above[10] << 16) & (above[11] << 24)) != 0 ||
+ (above[12] & (above[13] << 8) & (above[14] << 16) & (above[15] << 24)) != 0; // !!(*(const uint64_t*)above | *(const uint64_t*)(above + 8));
+ leftEntropyContext =
+ (left[0] & (left[1] << 8) & (left[2] << 16) & (left[3] << 24)) != 0 ||
+ (left[4] & (left[5] << 8) & (left[6] << 16) & (left[7] << 24)) != 0 ||
+ (left[8] & (left[9] << 8) & (left[10] << 16) & (left[11] << 24)) != 0 ||
+ (left[12] & (left[13] << 8) & (left[14] << 16) & (left[15] << 24)) != 0; // !!(*(const uint64_t*)left | *(const uint64_t*)(left + 8));
+ break;
+ case Av1TransformSize.Size32x64:
+ aboveEntropyContext =
+ (above[0] & (above[1] << 8) & (above[2] << 16) & (above[3] << 24)) != 0 ||
+ (above[4] & (above[5] << 8) & (above[6] << 16) & (above[7] << 24)) != 0; // !!*(const uint64_t*)above;
+ leftEntropyContext =
+ (left[0] & (left[1] << 8) & (left[2] << 16) & (left[3] << 24)) != 0 ||
+ (left[4] & (left[5] << 8) & (left[6] << 16) & (left[7] << 24)) != 0 ||
+ (left[8] & (left[9] << 8) & (left[10] << 16) & (left[11] << 24)) != 0 ||
+ (left[12] & (left[13] << 8) & (left[14] << 16) & (left[15] << 24)) != 0; // !!(*(const uint64_t*)left | *(const uint64_t*)(left + 8));
+ break;
+ case Av1TransformSize.Size64x32:
+ aboveEntropyContext =
+ (above[0] & (above[1] << 8) & (above[2] << 16) & (above[3] << 24)) != 0 ||
+ (above[4] & (above[5] << 8) & (above[6] << 16) & (above[7] << 24)) != 0 ||
+ (above[8] & (above[9] << 8) & (above[10] << 16) & (above[11] << 24)) != 0 ||
+ (above[12] & (above[13] << 8) & (above[14] << 16) & (above[15] << 24)) != 0; // !!(*(const uint64_t*)above | *(const uint64_t*)(above + 8));
+ leftEntropyContext =
+ (left[0] & (left[1] << 8) & (left[2] << 16) & (left[3] << 24)) != 0 ||
+ (left[4] & (left[5] << 8) & (left[6] << 16) & (left[7] << 24)) != 0; // !!*(const uint64_t*)left;
+ break;
+ case Av1TransformSize.Size4x16:
+ aboveEntropyContext = above[0] != 0;
+ leftEntropyContext = (left[0] & (left[1] << 8) & (left[2] << 16) & (left[3] << 24)) != 0; // !!*(const uint32_t*)left;
+ break;
+ case Av1TransformSize.Size16x4:
+ aboveEntropyContext = (above[0] & (above[1] << 8) & (above[2] << 16) & (above[3] << 24)) != 0; // !!*(const uint32_t*)above;
+ leftEntropyContext = left[0] != 0;
+ break;
+ case Av1TransformSize.Size8x32:
+ aboveEntropyContext = (above[0] & (above[1] << 8)) != 0; // !!*(const uint16_t*)above;
+ leftEntropyContext =
+ (left[0] & (left[1] << 8) & (left[2] << 16) & (left[3] << 24)) != 0 ||
+ (left[4] & (left[5] << 8) & (left[6] << 16) & (left[7] << 24)) != 0; // !!*(const uint64_t*)left;
+ break;
+ case Av1TransformSize.Size32x8:
+ aboveEntropyContext =
+ (above[0] & (above[1] << 8) & (above[2] << 16) & (above[3] << 24)) != 0 ||
+ (above[4] & (above[5] << 8) & (above[6] << 16) & (above[7] << 24)) != 0; // !!*(const uint64_t*)above;
+ leftEntropyContext = (left[0] & (left[1] << 8)) != 0; // !!*(const uint16_t*)left;
+ break;
+ case Av1TransformSize.Size16x64:
+ aboveEntropyContext = (above[0] & (above[1] << 8) & (above[2] << 16) & (above[3] << 24)) != 0; // !!*(const uint32_t*)above;
+ leftEntropyContext =
+ (left[0] & (left[1] << 8) & (left[2] << 16) & (left[3] << 24)) != 0 ||
+ (left[4] & (left[5] << 8) & (left[6] << 16) & (left[7] << 24)) != 0 ||
+ (left[8] & (left[9] << 8) & (left[10] << 16) & (left[11] << 24)) != 0 ||
+ (left[12] & (left[13] << 8) & (left[14] << 16) & (left[15] << 24)) != 0; // !!(*(const uint64_t*)left | *(const uint64_t*)(left + 8));
+ break;
+ case Av1TransformSize.Size64x16:
+ aboveEntropyContext =
+ (above[0] & (above[1] << 8) & (above[2] << 16) & (above[3] << 24)) != 0 ||
+ (above[4] & (above[5] << 8) & (above[6] << 16) & (above[7] << 24)) != 0 ||
+ (above[8] & (above[9] << 8) & (above[10] << 16) & (above[11] << 24)) != 0 ||
+ (above[12] & (above[13] << 8) & (above[14] << 16) & (above[15] << 24)) != 0; // !!(*(const uint64_t*)above | *(const uint64_t*)(above + 8));
+ leftEntropyContext = (left[0] & (left[1] << 8) & (left[2] << 16) & (left[3] << 24)) != 0; // !!*(const uint32_t*)left;
+ break;
+ default:
+ Guard.IsTrue(false, nameof(transformSize), "Invalid transform size.");
+ break;
+ }
+
+ return (aboveEntropyContext ? 1 : 0) + (leftEntropyContext ? 1 : 0);
+ }
+
+ ///
+ /// 5.11.15. TX size syntax.
+ ///
+ private Av1TransformSize ReadTransformSize(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo, Av1SuperblockInfo superblockInfo, Av1TileInfo tileInfo, bool allowSelect)
+ {
+ Av1BlockModeInfo modeInfo = partitionInfo.ModeInfo;
+ if (this.FrameHeader.LosslessArray[modeInfo.SegmentId])
+ {
+ return Av1TransformSize.Size4x4;
+ }
+
+ if (modeInfo.BlockSize > Av1BlockSize.Block4x4 && allowSelect && this.FrameHeader.TransformMode == Av1TransformMode.Select)
+ {
+ return this.ReadSelectedTransformSize(ref reader, partitionInfo, superblockInfo, tileInfo);
+ }
+
+ return modeInfo.BlockSize.GetMaximumTransformSize();
+ }
+
+ private Av1TransformSize ReadSelectedTransformSize(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo, Av1SuperblockInfo superblockInfo, Av1TileInfo tileInfo)
+ {
+ int context = 0;
+ Av1TransformSize maxTransformSize = partitionInfo.ModeInfo.BlockSize.GetMaximumTransformSize();
+ int aboveWidth = this.aboveNeighborContext.AboveTransformWidth[partitionInfo.ColumnIndex - tileInfo.ModeInfoColumnStart];
+ int above = (aboveWidth >= maxTransformSize.GetWidth()) ? 1 : 0;
+ int leftHeight = this.leftNeighborContext.LeftTransformHeight[partitionInfo.RowIndex - superblockInfo.ModeInfoPosition.Y];
+ int left = (leftHeight >= maxTransformSize.GetHeight()) ? 1 : 0;
+ bool hasAbove = partitionInfo.AvailableAbove;
+ bool hasLeft = partitionInfo.AvailableLeft;
+
+ if (hasAbove && hasLeft)
+ {
+ context = above + left;
+ }
+ else if (hasAbove)
+ {
+ context = above;
+ }
+ else if (hasLeft)
+ {
+ context = left;
+ }
+ else
+ {
+ context = 0;
+ }
+
+ return reader.ReadTransformSize(partitionInfo.ModeInfo.BlockSize, context);
+ }
+
+ ///
+ /// Section 5.11.16. Block TX size syntax.
+ ///
+ private void ReadBlockTransformSize(ref Av1SymbolDecoder reader, Point modeInfoLocation, Av1PartitionInfo partitionInfo, Av1SuperblockInfo superblockInfo, Av1TileInfo tileInfo)
+ {
+ Av1BlockSize blockSize = partitionInfo.ModeInfo.BlockSize;
+ int block4x4Width = blockSize.Get4x4WideCount();
+ int block4x4Height = blockSize.Get4x4HighCount();
+
+ // First condition in spec is for INTER frames, implemented only the INTRA condition.
+ Av1TransformSize transformSize = this.ReadTransformSize(ref reader, partitionInfo, superblockInfo, tileInfo, true);
+ this.aboveNeighborContext.UpdateTransformation(modeInfoLocation, tileInfo, transformSize, blockSize, false);
+ this.leftNeighborContext.UpdateTransformation(modeInfoLocation, superblockInfo, transformSize, blockSize, false);
+ this.UpdateTransformInfo(partitionInfo, superblockInfo, blockSize, transformSize);
+ }
+
+ private unsafe void UpdateTransformInfo(Av1PartitionInfo partitionInfo, Av1SuperblockInfo superblockInfo, Av1BlockSize blockSize, Av1TransformSize transformSize)
+ {
+ int transformInfoYIndex = partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Y];
+ int transformInfoUvIndex = partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Uv];
+ Span lumaTransformInfo = superblockInfo.GetTransformInfoY();
+ Span chromaTransformInfo = superblockInfo.GetTransformInfoUv();
+ int totalLumaTransformUnitCount = 0;
+ int totalChromaTransformUnitCount = 0;
+ int forceSplitCount = 0;
+ bool subX = this.SequenceHeader.ColorConfig.SubSamplingX;
+ bool subY = this.SequenceHeader.ColorConfig.SubSamplingY;
+ int maxBlockWide = partitionInfo.GetMaxBlockWide(blockSize, false);
+ int maxBlockHigh = partitionInfo.GetMaxBlockHigh(blockSize, false);
+ int width = 64 >> 2;
+ int height = 64 >> 2;
+ width = Math.Min(width, maxBlockWide);
+ height = Math.Min(height, maxBlockHigh);
+
+ bool isLossLess = this.FrameHeader.LosslessArray[partitionInfo.ModeInfo.SegmentId];
+ Av1TransformSize transformSizeUv = isLossLess ? Av1TransformSize.Size4x4 : blockSize.GetMaxUvTransformSize(subX, subY);
+
+ for (int idy = 0; idy < maxBlockHigh; idy += height)
+ {
+ for (int idx = 0; idx < maxBlockWide; idx += width, forceSplitCount++)
+ {
+ int lumaTransformUnitCount = 0;
+ int chromaTransformUnitCount = 0;
+
+ // Update Luminance Transform Info.
+ int stepColumn = transformSize.Get4x4WideCount();
+ int stepRow = transformSize.Get4x4HighCount();
+
+ int unitHeight = Av1Math.RoundPowerOf2(Math.Min(height + idy, maxBlockHigh), 0);
+ int unitWidth = Av1Math.RoundPowerOf2(Math.Min(width + idx, maxBlockWide), 0);
+ for (int blockRow = idy; blockRow < unitHeight; blockRow += stepRow)
+ {
+ for (int blockColumn = idx; blockColumn < unitWidth; blockColumn += stepColumn)
+ {
+ lumaTransformInfo[transformInfoYIndex] = new Av1TransformInfo(
+ transformSize, blockColumn, blockRow);
+ transformInfoYIndex++;
+ lumaTransformUnitCount++;
+ totalLumaTransformUnitCount++;
+ }
+ }
+
+ this.transformUnitCount[(int)Av1Plane.Y][forceSplitCount] = lumaTransformUnitCount;
+
+ if (this.SequenceHeader.ColorConfig.IsMonochrome || !partitionInfo.IsChroma)
+ {
+ continue;
+ }
+
+ // Update Chroma Transform Info.
+ stepColumn = transformSizeUv.Get4x4WideCount();
+ stepRow = transformSizeUv.Get4x4HighCount();
+
+ unitHeight = Av1Math.RoundPowerOf2(Math.Min(height + idx, maxBlockHigh), subY ? 1 : 0);
+ unitWidth = Av1Math.RoundPowerOf2(Math.Min(width + idx, maxBlockWide), subX ? 1 : 0);
+ for (int blockRow = idy; blockRow < unitHeight; blockRow += stepRow)
+ {
+ for (int blockColumn = idx; blockColumn < unitWidth; blockColumn += stepColumn)
+ {
+ chromaTransformInfo[transformInfoUvIndex] = new Av1TransformInfo(
+ transformSizeUv, blockColumn, blockRow);
+ transformInfoUvIndex++;
+ chromaTransformUnitCount++;
+ totalChromaTransformUnitCount++;
+ }
+ }
+
+ this.transformUnitCount[(int)Av1Plane.U][forceSplitCount] = chromaTransformUnitCount;
+ this.transformUnitCount[(int)Av1Plane.V][forceSplitCount] = chromaTransformUnitCount;
+ }
+ }
+
+ // Cr Transform Info Update from Cb.
+ if (totalChromaTransformUnitCount != 0)
+ {
+ DebugGuard.IsTrue(
+ (transformInfoUvIndex - totalChromaTransformUnitCount) ==
+ partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Uv],
+ nameof(totalChromaTransformUnitCount));
+ int originalIndex = transformInfoUvIndex - totalChromaTransformUnitCount;
+ ref Av1TransformInfo originalInfo = ref chromaTransformInfo[originalIndex];
+ ref Av1TransformInfo infoV = ref chromaTransformInfo[transformInfoUvIndex];
+ for (int i = 0; i < totalChromaTransformUnitCount; i++)
+ {
+ infoV = originalInfo;
+ originalInfo = ref Unsafe.Add(ref originalInfo, 1);
+ infoV = ref Unsafe.Add(ref infoV, 1);
+ }
+ }
+
+ partitionInfo.ModeInfo.TransformUnitsCount[(int)Av1PlaneType.Y] = totalLumaTransformUnitCount;
+ partitionInfo.ModeInfo.TransformUnitsCount[(int)Av1PlaneType.Uv] = totalChromaTransformUnitCount;
+
+ this.firstTransformOffset[(int)Av1PlaneType.Y] += totalLumaTransformUnitCount;
+ this.firstTransformOffset[(int)Av1PlaneType.Uv] += totalChromaTransformUnitCount << 1;
+ }
+
+ ///
+ /// 5.11.49. Palette tokens syntax.
+ ///
+ private static void ReadPaletteTokens(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo)
+ {
+ if (partitionInfo.ModeInfo.GetPaletteSize(Av1PlaneType.Y) != 0)
+ {
+ // TODO: Implement.
+ throw new NotImplementedException();
+ }
+
+ if (partitionInfo.ModeInfo.GetPaletteSize(Av1PlaneType.Uv) != 0)
+ {
+ // TODO: Implement.
+ throw new NotImplementedException();
+ }
+ }
+
+ ///
+ /// 5.11.6. Mode info syntax.
+ ///
+ private void ReadModeInfo(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo)
+ {
+ DebugGuard.IsTrue(this.FrameHeader.FrameType is ObuFrameType.KeyFrame or ObuFrameType.IntraOnlyFrame, "Only INTRA frames supported.");
+ this.ReadIntraFrameModeInfo(ref reader, partitionInfo);
+ }
+
+ ///
+ /// 5.11.7. Intra frame mode info syntax.
+ ///
+ private void ReadIntraFrameModeInfo(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo)
+ {
+ if (this.FrameHeader.SegmentationParameters.SegmentIdPrecedesSkip)
+ {
+ this.IntraSegmentId(ref reader, partitionInfo);
+ }
+
+ // this.skipMode = false;
+ partitionInfo.ModeInfo.Skip = this.ReadSkip(ref reader, partitionInfo);
+ if (!this.FrameHeader.SegmentationParameters.SegmentIdPrecedesSkip)
+ {
+ this.IntraSegmentId(ref reader, partitionInfo);
+ }
+
+ this.ReadCdef(ref reader, partitionInfo);
+
+ if (this.FrameHeader.DeltaQParameters.IsPresent)
+ {
+ this.ReadDeltaQuantizerIndex(ref reader, partitionInfo);
+ this.ReadDeltaLoopFilter(ref reader, partitionInfo);
+ }
+
+ partitionInfo.ReferenceFrame[0] = 0; // IntraFrame;
+ partitionInfo.ReferenceFrame[1] = -1; // None;
+ partitionInfo.ModeInfo.SetPaletteSizes(0, 0);
+ bool useIntraBlockCopy = false;
+ if (this.AllowIntraBlockCopy())
+ {
+ useIntraBlockCopy = reader.ReadUseIntraBlockCopy();
+ }
+
+ if (useIntraBlockCopy)
+ {
+ partitionInfo.ModeInfo.YMode = Av1PredictionMode.DC;
+ partitionInfo.ModeInfo.UvMode = Av1PredictionMode.DC;
+ }
+ else
+ {
+ // this.IsInter = false;
+ partitionInfo.ModeInfo.YMode = reader.ReadYMode(partitionInfo.AboveModeInfo, partitionInfo.LeftModeInfo);
+
+ // 5.11.42.Intra angle info luma syntax.
+ partitionInfo.ModeInfo.AngleDelta[(int)Av1PlaneType.Y] = IntraAngleInfo(ref reader, partitionInfo.ModeInfo.YMode, partitionInfo.ModeInfo.BlockSize);
+ if (partitionInfo.IsChroma && !this.SequenceHeader.ColorConfig.IsMonochrome)
+ {
+ partitionInfo.ModeInfo.UvMode = reader.ReadIntraModeUv(partitionInfo.ModeInfo.YMode, this.IsChromaForLumaAllowed(partitionInfo));
+ if (partitionInfo.ModeInfo.UvMode == Av1PredictionMode.UvChromaFromLuma)
+ {
+ ReadChromaFromLumaAlphas(ref reader, partitionInfo.ModeInfo);
+ }
+
+ // 5.11.43.Intra angle info chroma syntax.
+ partitionInfo.ModeInfo.AngleDelta[(int)Av1PlaneType.Uv] = IntraAngleInfo(ref reader, partitionInfo.ModeInfo.UvMode, partitionInfo.ModeInfo.BlockSize);
+ }
+ else
+ {
+ partitionInfo.ModeInfo.UvMode = Av1PredictionMode.DC;
+ }
+
+ if (partitionInfo.ModeInfo.BlockSize >= Av1BlockSize.Block8x8 &&
+ partitionInfo.ModeInfo.BlockSize.GetWidth() <= 64 &&
+ partitionInfo.ModeInfo.BlockSize.GetHeight() <= 64 &&
+ this.FrameHeader.AllowScreenContentTools)
+ {
+ this.PaletteModeInfo(ref reader, partitionInfo);
+ }
+
+ this.FilterIntraModeInfo(ref reader, partitionInfo);
+ }
+ }
+
+ private bool AllowIntraBlockCopy()
+ => (this.FrameHeader.FrameType is ObuFrameType.KeyFrame or ObuFrameType.IntraOnlyFrame) &&
+ (this.SequenceHeader.ForceScreenContentTools > 0) &&
+ this.FrameHeader.AllowIntraBlockCopy;
+
+ private bool IsChromaForLumaAllowed(Av1PartitionInfo partitionInfo)
+ {
+ if (this.FrameHeader.LosslessArray[partitionInfo.ModeInfo.SegmentId])
+ {
+ // In lossless, CfL is available when the partition size is equal to the
+ // transform size.
+ bool subX = this.SequenceHeader.ColorConfig.SubSamplingX;
+ bool subY = this.SequenceHeader.ColorConfig.SubSamplingY;
+ Av1BlockSize planeBlockSize = partitionInfo.ModeInfo.BlockSize.GetSubsampled(subX, subY);
+ return planeBlockSize == Av1BlockSize.Block4x4;
+ }
+
+ // Spec: CfL is available to luma partitions lesser than or equal to 32x32
+ return partitionInfo.ModeInfo.BlockSize.GetWidth() <= 32 && partitionInfo.ModeInfo.BlockSize.GetHeight() <= 32;
+ }
+
+ private void FilterIntraModeInfo(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo)
+ {
+ partitionInfo.ModeInfo.FilterIntraModeInfo.UseFilterIntra = false;
+ if (this.SequenceHeader.EnableFilterIntra &&
+ partitionInfo.ModeInfo.YMode == Av1PredictionMode.DC &&
+ partitionInfo.ModeInfo.GetPaletteSize(Av1PlaneType.Y) == 0 &&
+ Math.Max(partitionInfo.ModeInfo.BlockSize.GetWidth(), partitionInfo.ModeInfo.BlockSize.GetHeight()) <= 32)
+ {
+ Av1FilterIntraMode filterIntraMode = reader.ReadFilterUltraMode(partitionInfo.ModeInfo.BlockSize);
+ if (filterIntraMode != Av1FilterIntraMode.AllFilterIntraModes)
+ {
+ partitionInfo.ModeInfo.FilterIntraModeInfo.UseFilterIntra = true;
+ partitionInfo.ModeInfo.FilterIntraModeInfo.Mode = filterIntraMode;
+ }
+ }
+ }
+
+ ///
+ /// 5.11.46. Palette mode info syntax.
+ ///
+ private void PaletteModeInfo(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo) =>
+
+ // TODO: Implement.
+ throw new NotImplementedException();
+
+ ///
+ /// 5.11.45. Read CFL alphas syntax.
+ ///
+ private static void ReadChromaFromLumaAlphas(ref Av1SymbolDecoder reader, Av1BlockModeInfo modeInfo)
+ {
+ int jointSignPlus1 = reader.ReadChromFromLumaSign() + 1;
+ int index = 0;
+ if (jointSignPlus1 >= 3)
+ {
+ index = reader.ReadChromaFromLumaAlphaU(jointSignPlus1) << Av1Constants.ChromaFromLumaAlphabetSizeLog2;
+ }
+
+ if (jointSignPlus1 % 3 != 0)
+ {
+ index += reader.ReadChromaFromLumaAlphaV(jointSignPlus1);
+ }
+
+ modeInfo.ChromaFromLumaAlphaSign = jointSignPlus1 - 1;
+ modeInfo.ChromaFromLumaAlphaIndex = index;
+ }
+
+ ///
+ /// 5.11.42. and 5.11.43.
+ ///
+ private static int IntraAngleInfo(ref Av1SymbolDecoder reader, Av1PredictionMode mode, Av1BlockSize blockSize)
+ {
+ int angleDelta = 0;
+ if (blockSize >= Av1BlockSize.Block8x8 && IsDirectionalMode(mode))
+ {
+ int symbol = reader.ReadAngleDelta(mode);
+ angleDelta = symbol - Av1Constants.MaxAngleDelta;
+ }
+
+ return angleDelta;
+ }
+
+ private static bool IsDirectionalMode(Av1PredictionMode mode)
+ => mode is >= Av1PredictionMode.Vertical and <= Av1PredictionMode.Directional67Degrees;
+
+ ///
+ /// 5.11.8. Intra segment ID syntax.
+ ///
+ private void IntraSegmentId(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo)
+ {
+ if (this.FrameHeader.SegmentationParameters.Enabled)
+ {
+ this.ReadSegmentId(ref reader, partitionInfo);
+ }
+
+ int blockWidth4x4 = partitionInfo.ModeInfo.BlockSize.Get4x4WideCount();
+ int blockHeight4x4 = partitionInfo.ModeInfo.BlockSize.Get4x4HighCount();
+ int modeInfoCountX = Math.Min(this.FrameHeader.ModeInfoColumnCount - partitionInfo.ColumnIndex, blockWidth4x4);
+ int modeInfoCountY = Math.Min(this.FrameHeader.ModeInfoRowCount - partitionInfo.RowIndex, blockHeight4x4);
+ int segmentId = partitionInfo.ModeInfo.SegmentId;
+ for (int y = 0; y < modeInfoCountY; y++)
+ {
+ int[] segmentRow = this.segmentIds[partitionInfo.RowIndex + y];
+ for (int x = 0; x < modeInfoCountX; x++)
+ {
+ segmentRow[partitionInfo.ColumnIndex + x] = segmentId;
+ }
+ }
+ }
+
+ ///
+ /// 5.11.9. Read segment ID syntax.
+ ///
+ private void ReadSegmentId(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo)
+ {
+ int predictor;
+ int prevUL = -1;
+ int prevU = -1;
+ int prevL = -1;
+ int columnIndex = partitionInfo.ColumnIndex;
+ int rowIndex = partitionInfo.RowIndex;
+ if (partitionInfo.AvailableAbove && partitionInfo.AvailableLeft)
+ {
+ prevUL = Av1SymbolContextHelper.GetSegmentId(partitionInfo, this.FrameHeader, this.segmentIds, rowIndex - 1, columnIndex - 1);
+ }
+
+ if (partitionInfo.AvailableAbove)
+ {
+ prevU = Av1SymbolContextHelper.GetSegmentId(partitionInfo, this.FrameHeader, this.segmentIds, rowIndex - 1, columnIndex);
+ }
+
+ if (partitionInfo.AvailableLeft)
+ {
+ prevU = Av1SymbolContextHelper.GetSegmentId(partitionInfo, this.FrameHeader, this.segmentIds, rowIndex, columnIndex - 1);
+ }
+
+ if (prevU == -1)
+ {
+ predictor = prevL == -1 ? 0 : prevL;
+ }
+ else if (prevL == -1)
+ {
+ predictor = prevU;
+ }
+ else
+ {
+ predictor = prevU == prevUL ? prevU : prevL;
+ }
+
+ if (partitionInfo.ModeInfo.Skip)
+ {
+ partitionInfo.ModeInfo.SegmentId = predictor;
+ }
+ else
+ {
+ int ctx = prevUL < 0 ? 0 /* Edge cases */
+ : prevUL == prevU && prevUL == prevL ? 2
+ : prevUL == prevU || prevUL == prevL || prevU == prevL ? 1 : 0;
+ int lastActiveSegmentId = this.FrameHeader.SegmentationParameters.LastActiveSegmentId;
+ partitionInfo.ModeInfo.SegmentId = Av1SymbolContextHelper.NegativeDeinterleave(reader.ReadSegmentId(ctx), predictor, lastActiveSegmentId + 1);
+ }
+ }
+
+ ///
+ /// 5.11.56. Read CDEF syntax.
+ ///
+ /// SVT: read_cdef
+ private void ReadCdef(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo)
+ {
+ if (partitionInfo.ModeInfo.Skip || this.FrameHeader.CodedLossless || !this.SequenceHeader.EnableCdef || this.FrameHeader.AllowIntraBlockCopy)
+ {
+ return;
+ }
+
+ int cdefSize4 = Av1BlockSize.Block64x64.Get4x4WideCount();
+ int row = partitionInfo.RowIndex & cdefSize4;
+ int col = partitionInfo.ColumnIndex & cdefSize4;
+ int index = this.SequenceHeader.SuperblockSize == Av1BlockSize.Block128x128 ? Math.Max(1, col) + (Math.Max(1, row) << 1) : 0;
+ if (partitionInfo.CdefStrength[index] == -1)
+ {
+ int cdfStrength = reader.ReadCdfStrength(this.FrameHeader.CdefParameters.BitCount);
+ partitionInfo.CdefStrength[index] = cdfStrength;
+
+ // Populate to nearby 64x64s if needed based on h4 & w4
+ if (this.SequenceHeader.SuperblockSize == Av1BlockSize.Block128x128)
+ {
+ int w4 = partitionInfo.ModeInfo.BlockSize.Get4x4WideCount();
+ int h4 = partitionInfo.ModeInfo.BlockSize.Get4x4HighCount();
+ for (int i = row; i < row + h4; i += cdefSize4)
+ {
+ for (int j = col; j < col + w4; j += cdefSize4)
+ {
+ partitionInfo.CdefStrength[Math.Max(1, j & cdefSize4) + (Math.Max(1, i & cdefSize4) << 1)] = cdfStrength;
+ }
+ }
+ }
+ }
+ }
+
+ private void ReadDeltaLoopFilter(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo)
+ {
+ Av1BlockSize superBlockSize = this.SequenceHeader.Use128x128Superblock ? Av1BlockSize.Block128x128 : Av1BlockSize.Block64x64;
+ if (this.FrameHeader.DeltaLoopFilterParameters.IsPresent ||
+ (partitionInfo.ModeInfo.BlockSize == superBlockSize && partitionInfo.ModeInfo.Skip))
+ {
+ return;
+ }
+
+ if (this.FrameHeader.DeltaLoopFilterParameters.IsPresent)
+ {
+ int frameLoopFilterCount = 1;
+ if (this.FrameHeader.DeltaLoopFilterParameters.IsMulti)
+ {
+ frameLoopFilterCount = this.SequenceHeader.ColorConfig.PlaneCount > 1 ? Av1Constants.FrameLoopFilterCount : Av1Constants.FrameLoopFilterCount - 2;
+ }
+
+ Span currentDeltaLoopFilter = partitionInfo.SuperblockInfo.SuperblockDeltaLoopFilter;
+ for (int i = 0; i < frameLoopFilterCount; i++)
+ {
+ int reducedDeltaLoopFilterLevel = reader.ReadDeltaLoopFilter();
+ int deltaLoopFilterResolution = this.FrameHeader.DeltaLoopFilterParameters.Resolution;
+ currentDeltaLoopFilter[i] = Av1Math.Clip3(-Av1Constants.MaxLoopFilter, Av1Constants.MaxLoopFilter, currentDeltaLoopFilter[i] + (reducedDeltaLoopFilterLevel << deltaLoopFilterResolution));
+ }
+ }
+ }
+
+ private bool ReadSkip(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo)
+ {
+ int segmentId = partitionInfo.ModeInfo.SegmentId;
+ if (this.FrameHeader.SegmentationParameters.SegmentIdPrecedesSkip &&
+ this.FrameHeader.SegmentationParameters.IsFeatureActive(segmentId, ObuSegmentationLevelFeature.Skip))
+ {
+ return true;
+ }
+ else
+ {
+ int aboveSkip = partitionInfo.AboveModeInfo != null && partitionInfo.AboveModeInfo.Skip ? 1 : 0;
+ int leftSkip = partitionInfo.LeftModeInfo != null && partitionInfo.LeftModeInfo.Skip ? 1 : 0;
+ return reader.ReadSkip(aboveSkip + leftSkip);
+ }
+ }
+
+ ///
+ /// SVT: read_delta_qindex
+ ///
+ private void ReadDeltaQuantizerIndex(ref Av1SymbolDecoder reader, Av1PartitionInfo partitionInfo)
+ {
+ Av1BlockSize superBlockSize = this.SequenceHeader.Use128x128Superblock ? Av1BlockSize.Block128x128 : Av1BlockSize.Block64x64;
+ if (!this.FrameHeader.DeltaQParameters.IsPresent ||
+ (partitionInfo.ModeInfo.BlockSize == superBlockSize && partitionInfo.ModeInfo.Skip))
+ {
+ return;
+ }
+
+ if (partitionInfo.ModeInfo.BlockSize != this.SequenceHeader.SuperblockSize || !partitionInfo.ModeInfo.Skip)
+ {
+ int reducedDeltaQuantizerIndex = reader.ReadDeltaQuantizerIndex();
+ int deltaQuantizerResolution = this.FrameHeader.DeltaQParameters.Resolution;
+ this.currentQuantizerIndex = Av1Math.Clip3(1, 255, this.currentQuantizerIndex + (reducedDeltaQuantizerIndex << deltaQuantizerResolution));
+ partitionInfo.SuperblockInfo.SuperblockDeltaQ = this.currentQuantizerIndex;
+ }
+ }
+
+ private bool IsInside(int rowIndex, int columnIndex) =>
+ columnIndex >= this.FrameHeader.TilesInfo.TileColumnCount &&
+ columnIndex < this.FrameHeader.TilesInfo.TileColumnCount &&
+ rowIndex >= this.FrameHeader.TilesInfo.TileRowCount &&
+ rowIndex < this.FrameHeader.TilesInfo.TileRowCount;
+
+ /*
+ private static bool IsChroma(int rowIndex, int columnIndex, Av1BlockModeInfo blockMode, bool subSamplingX, bool subSamplingY)
+ {
+ int block4x4Width = blockMode.BlockSize.Get4x4WideCount();
+ int block4x4Height = blockMode.BlockSize.Get4x4HighCount();
+ bool xPos = (columnIndex & 0x1) > 0 || (block4x4Width & 0x1) > 0 || !subSamplingX;
+ bool yPos = (rowIndex & 0x1) > 0 || (block4x4Height & 0x1) > 0 || !subSamplingY;
+ return xPos && yPos;
+ }*/
+
+ ///
+ /// SVT: partition_plane_context
+ ///
+ private int GetPartitionPlaneContext(Point location, Av1BlockSize blockSize, Av1TileInfo tileInfo, Av1SuperblockInfo superblockInfo)
+ {
+ // Maximum partition point is 8x8. Offset the log value occordingly.
+ int aboveCtx = this.aboveNeighborContext.AbovePartitionWidth[location.X - tileInfo.ModeInfoColumnStart];
+ int leftCtx = this.leftNeighborContext.LeftPartitionHeight[(location.Y - superblockInfo.ModeInfoPosition.Y) & Av1PartitionContext.Mask];
+ int blockSizeLog = blockSize.Get4x4WidthLog2() - Av1BlockSize.Block8x8.Get4x4WidthLog2();
+ int above = (aboveCtx >> blockSizeLog) & 0x1;
+ int left = (leftCtx >> blockSizeLog) & 0x1;
+ DebugGuard.IsTrue(blockSize.Get4x4WidthLog2() == blockSize.Get4x4HeightLog2(), "Blocks should be square");
+ DebugGuard.MustBeGreaterThanOrEqualTo(blockSizeLog, 0, nameof(blockSizeLog));
+ return ((left << 1) + above) + (blockSizeLog * Av1Constants.PartitionProbabilitySet);
+ }
+
+ private void UpdatePartitionContext(Point modeInfoLocation, Av1TileInfo tileLoc, Av1SuperblockInfo superblockInfo, Av1BlockSize subSize, Av1BlockSize blockSize, Av1PartitionType partition)
+ {
+ if (blockSize >= Av1BlockSize.Block8x8)
+ {
+ int hbs = blockSize.Get4x4WideCount() / 2;
+ Av1BlockSize blockSize2 = Av1PartitionType.Split.GetBlockSubSize(blockSize);
+ switch (partition)
+ {
+ case Av1PartitionType.Split:
+ if (blockSize != Av1BlockSize.Block8x8)
+ {
+ break;
+ }
+
+ goto PARTITIONS;
+ case Av1PartitionType.None:
+ case Av1PartitionType.Horizontal:
+ case Av1PartitionType.Vertical:
+ case Av1PartitionType.Horizontal4:
+ case Av1PartitionType.Vertical4:
+ PARTITIONS:
+ this.aboveNeighborContext.UpdatePartition(modeInfoLocation, tileLoc, subSize, blockSize);
+ this.leftNeighborContext.UpdatePartition(modeInfoLocation, superblockInfo, subSize, blockSize);
+ break;
+ case Av1PartitionType.HorizontalA:
+ this.aboveNeighborContext.UpdatePartition(modeInfoLocation, tileLoc, blockSize2, subSize);
+ this.leftNeighborContext.UpdatePartition(modeInfoLocation, superblockInfo, blockSize2, subSize);
+ Point locHorizontalA = new(modeInfoLocation.X, modeInfoLocation.Y + hbs);
+ this.aboveNeighborContext.UpdatePartition(locHorizontalA, tileLoc, subSize, subSize);
+ this.leftNeighborContext.UpdatePartition(locHorizontalA, superblockInfo, subSize, subSize);
+ break;
+ case Av1PartitionType.HorizontalB:
+ this.aboveNeighborContext.UpdatePartition(modeInfoLocation, tileLoc, subSize, subSize);
+ this.leftNeighborContext.UpdatePartition(modeInfoLocation, superblockInfo, subSize, subSize);
+ Point locHorizontalB = new(modeInfoLocation.X, modeInfoLocation.Y + hbs);
+ this.aboveNeighborContext.UpdatePartition(locHorizontalB, tileLoc, blockSize2, subSize);
+ this.leftNeighborContext.UpdatePartition(locHorizontalB, superblockInfo, blockSize2, subSize);
+ break;
+ case Av1PartitionType.VerticalA:
+ this.aboveNeighborContext.UpdatePartition(modeInfoLocation, tileLoc, blockSize2, subSize);
+ this.leftNeighborContext.UpdatePartition(modeInfoLocation, superblockInfo, blockSize2, subSize);
+ Point locVerticalA = new(modeInfoLocation.X + hbs, modeInfoLocation.Y);
+ this.aboveNeighborContext.UpdatePartition(locVerticalA, tileLoc, subSize, subSize);
+ this.leftNeighborContext.UpdatePartition(locVerticalA, superblockInfo, subSize, subSize);
+ break;
+ case Av1PartitionType.VerticalB:
+ this.aboveNeighborContext.UpdatePartition(modeInfoLocation, tileLoc, subSize, subSize);
+ this.leftNeighborContext.UpdatePartition(modeInfoLocation, superblockInfo, subSize, subSize);
+ Point locVerticalB = new(modeInfoLocation.X, modeInfoLocation.Y + hbs);
+ this.aboveNeighborContext.UpdatePartition(locVerticalB, tileLoc, blockSize2, subSize);
+ this.leftNeighborContext.UpdatePartition(locVerticalB, superblockInfo, blockSize2, subSize);
+ break;
+ default:
+ throw new InvalidImageContentException($"Unknown partition type: {partition}");
+ }
+ }
+ }
+}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileWriter.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileWriter.cs
new file mode 100644
index 0000000000..2ee25e9bd2
--- /dev/null
+++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileWriter.cs
@@ -0,0 +1,1426 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Runtime.InteropServices;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Entropy;
+using SixLabors.ImageSharp.Formats.Heif.Av1.ModeDecision;
+using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Prediction;
+using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
+
+namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
+
+internal partial class Av1TileWriter
+{
+ // Generates 5 bit field in which each bit set to 1 represents
+ // a BlockSize partition 11111 means we split 128x128, 64x64, 32x32, 16x16
+ // and 8x8. 10000 means we just split the 128x128 to 64x64
+ private static readonly Av1PartitionContext[] PartitionContextLookup =
+ [
+ new(31, 31), // 4X4 - {0b11111, 0b11111}
+ new(31, 30), // 4X8 - {0b11111, 0b11110}
+ new(30, 31), // 8X4 - {0b11110, 0b11111}
+ new(30, 30), // 8X8 - {0b11110, 0b11110}
+ new(30, 28), // 8X16 - {0b11110, 0b11100}
+ new(28, 30), // 16X8 - {0b11100, 0b11110}
+ new(28, 28), // 16X16 - {0b11100, 0b11100}
+ new(28, 24), // 16X32 - {0b11100, 0b11000}
+ new(24, 28), // 32X16 - {0b11000, 0b11100}
+ new(24, 24), // 32X32 - {0b11000, 0b11000}
+ new(24, 16), // 32X64 - {0b11000, 0b10000}
+ new(16, 24), // 64X32 - {0b10000, 0b11000}
+ new(16, 16), // 64X64 - {0b10000, 0b10000}
+ new(16, 0), // 64X128- {0b10000, 0b00000}
+ new(0, 16), // 128X64- {0b00000, 0b10000}
+ new(0, 0), // 128X128-{0b00000, 0b00000}
+ new(31, 28), // 4X16 - {0b11111, 0b11100}
+ new(28, 31), // 16X4 - {0b11100, 0b11111}
+ new(30, 24), // 8X32 - {0b11110, 0b11000}
+ new(24, 30), // 32X8 - {0b11000, 0b11110}
+ new(28, 16), // 16X64 - {0b11100, 0b10000}
+ new(16, 28), // 64X16 - {0b10000, 0b11100}
+ ];
+
+ private static readonly byte[] IntraModeContextLookup = [0, 1, 2, 3, 4, 4, 4, 4, 3, 0, 1, 2, 0];
+
+ ///
+ /// SVT: svt_aom_write_sb
+ ///
+ public static void WriteSuperblock(
+ Av1PictureControlSet pcs,
+ Av1EntropyCodingContext ec_ctx,
+ ref Av1SymbolEncoder writer,
+ Av1Superblock superblock,
+ Av1FrameBuffer frameBuffer,
+ ushort tileIndex)
+ {
+ Av1SequenceControlSet scs = pcs.Sequence;
+ Av1NeighborArrayUnit partitionContextNeighbors = pcs.PartitionContexts[tileIndex];
+
+ // CU Varaiables
+ int blockIndex = 0;
+ uint finalBlockIndex = 0;
+
+ ec_ctx.CodedAreaSuperblock = 0;
+ ec_ctx.CodedAreaSuperblockUv = 0;
+ Av1SuperblockGeometry sb_geom = pcs.Parent.SuperblockGeometry[superblock.Index];
+ bool check_blk_out_of_bound = !sb_geom.IsComplete;
+ do
+ {
+ bool code_blk_cond = true; // Code cu only if it is inside the picture
+ Av1EncoderBlockStruct blk_ptr = superblock.FinalBlocks[finalBlockIndex];
+ Av1BlockGeometry blk_geom = Av1BlockGeometryFactory.GetBlockGeometryByModeDecisionScanIndex(blockIndex);
+
+ Av1BlockSize bsize = blk_geom.BlockSize;
+ Point blockOrigin = blk_geom.Origin;
+ Guard.IsTrue(bsize < Av1BlockSize.AllSizes, nameof(bsize), "Block size must be a valid value.");
+
+ // assert(blk_geom->shape == PART_N);
+ if (check_blk_out_of_bound)
+ {
+ code_blk_cond = (((blockOrigin.X + (blk_geom.BlockWidth / 2)) < pcs.Parent.AlignedWidth) ||
+ ((blockOrigin.Y + (blk_geom.BlockHeight / 2)) < pcs.Parent.AlignedHeight)) &&
+ (blockOrigin.X < pcs.Parent.AlignedWidth && blockOrigin.Y < pcs.Parent.AlignedHeight);
+ }
+
+ if (code_blk_cond)
+ {
+ int hbs = bsize.Get4x4WideCount() >> 1;
+ int quarter_step = bsize.Get4x4WideCount() >> 2;
+ Av1EncoderCommon cm = pcs.Parent.Common;
+ int mi_row = blockOrigin.Y >> Av1Constants.ModeInfoSizeLog2;
+ int mi_col = blockOrigin.X >> Av1Constants.ModeInfoSizeLog2;
+
+ if (bsize >= Av1BlockSize.Block8x8)
+ {
+ for (int plane = 0; plane < 3; ++plane)
+ {
+ /* TODO: Implement
+ if (svt_av1_loop_restoration_corners_in_sb(cm,
+ scs.SequenceHeader,
+ plane,
+ mi_row,
+ mi_col,
+ bsize,
+ out int rcol0,
+ out int rcol1,
+ out int rrow0,
+ out int rrow1,
+ out int tile_tl_idx))
+ {
+ int rstride = pcs.RestorationInfos[plane].HorizontalUnitCountPerTile;
+ for (int rrow = rrow0; rrow < rrow1; ++rrow)
+ {
+ for (int rcol = rcol0; rcol < rcol1; ++rcol)
+ {
+ int runit_idx = tile_tl_idx + rcol + (rrow * rstride);
+ Av1RestorationUnitInfo rui = pcs.RestorationUnitInfos[plane].UnitInfo[runit_idx];
+ loop_restoration_write_sb_coeffs(
+ pcs,
+ ref writer,
+ tileIndex,
+ rui,
+ plane);
+ }
+ }
+ }*/
+ }
+
+ // Code Split Flag
+ EncodePartition(
+ pcs,
+ ref writer,
+ bsize,
+ superblock.CodingUnitPartitionTypes[blockIndex],
+ blockOrigin,
+ partitionContextNeighbors);
+ }
+
+ // assert(blk_geom.Shape == PART_N);
+ Guard.IsTrue(Av1Math.Implies(bsize == Av1BlockSize.Block4x4, superblock.CodingUnitPartitionTypes[blockIndex] == Av1PartitionType.None), nameof(bsize), string.Empty);
+ switch (superblock.CodingUnitPartitionTypes[blockIndex])
+ {
+ case Av1PartitionType.None:
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+ break;
+
+ case Av1PartitionType.Horizontal:
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+
+ if (mi_row + hbs < cm.ModeInfoRowCount)
+ {
+ finalBlockIndex++;
+ blk_ptr = superblock.FinalBlocks[finalBlockIndex];
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+ }
+
+ break;
+
+ case Av1PartitionType.Vertical:
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+ if (mi_col + hbs < cm.ModeInfoColumnCount)
+ {
+ finalBlockIndex++;
+ blk_ptr = superblock.FinalBlocks[finalBlockIndex];
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+ }
+
+ break;
+ case Av1PartitionType.Split:
+ break;
+ case Av1PartitionType.HorizontalA:
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+
+ finalBlockIndex++;
+ blk_ptr = superblock.FinalBlocks[finalBlockIndex];
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+
+ finalBlockIndex++;
+ blk_ptr = superblock.FinalBlocks[finalBlockIndex];
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+
+ break;
+ case Av1PartitionType.HorizontalB:
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+
+ finalBlockIndex++;
+ blk_ptr = superblock.FinalBlocks[finalBlockIndex];
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+
+ finalBlockIndex++;
+ blk_ptr = superblock.FinalBlocks[finalBlockIndex];
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+
+ break;
+ case Av1PartitionType.VerticalA:
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+
+ finalBlockIndex++;
+ blk_ptr = superblock.FinalBlocks[finalBlockIndex];
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+
+ finalBlockIndex++;
+ blk_ptr = superblock.FinalBlocks[finalBlockIndex];
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+
+ break;
+ case Av1PartitionType.VerticalB:
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+
+ finalBlockIndex++;
+ blk_ptr = superblock.FinalBlocks[finalBlockIndex];
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+
+ finalBlockIndex++;
+ blk_ptr = superblock.FinalBlocks[finalBlockIndex];
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+
+ break;
+ case Av1PartitionType.Horizontal4:
+ for (int i = 0; i < 4; ++i)
+ {
+ int this_mi_row = mi_row + (i * quarter_step);
+ if (i > 0 && this_mi_row >= cm.ModeInfoRowCount)
+ {
+ // Only the last block is able to be outside the picture boundary. If one of the first
+ // 3 blocks is outside the boundary, H4 is not a valid partition (see AV1 spec 5.11.4)
+ Guard.IsTrue(i == 3, nameof(i), "Only the last block can be partial");
+ break;
+ }
+
+ if (i > 0)
+ {
+ finalBlockIndex++;
+ blk_ptr = superblock.FinalBlocks[finalBlockIndex];
+ }
+
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+ }
+
+ break;
+ case Av1PartitionType.Vertical4:
+ for (int i = 0; i < 4; ++i)
+ {
+ int this_mi_col = mi_col + (i * quarter_step);
+ if (i > 0 && this_mi_col >= cm.ModeInfoColumnCount)
+ {
+ // Only the last block is able to be outside the picture boundary. If one of the first
+ // 3 blocks is outside the boundary, H4 is not a valid partition (see AV1 spec 5.11.4)
+ Guard.IsTrue(i == 3, nameof(i), "Only the last block can be partial");
+ break;
+ }
+
+ if (i > 0)
+ {
+ finalBlockIndex++;
+ blk_ptr = superblock.FinalBlocks[finalBlockIndex];
+ }
+
+ WriteModesBlock(pcs, ec_ctx, ref writer, superblock, blk_ptr, tileIndex, frameBuffer);
+ }
+
+ break;
+ }
+
+ if (superblock.CodingUnitPartitionTypes[blockIndex] != Av1PartitionType.Split)
+ {
+ finalBlockIndex++;
+ blockIndex += blk_geom.NextDepthOffset;
+ }
+ else
+ {
+ blockIndex += blk_geom.Depth1Offset;
+ }
+ }
+ else
+ {
+ blockIndex += blk_geom.Depth1Offset;
+ }
+ }
+ while (blockIndex < scs.MaxBlockCount);
+ }
+
+ ///
+ /// SVT: encode_partition_av1
+ ///
+ private static void EncodePartition(
+ Av1PictureControlSet pcs,
+ ref Av1SymbolEncoder writer,
+ Av1BlockSize blockSize,
+ Av1PartitionType partitionType,
+ Point blockOrigin,
+ Av1NeighborArrayUnit partition_context_na)
+ {
+ bool is_partition_point = blockSize >= Av1BlockSize.Block8x8;
+
+ if (!is_partition_point)
+ {
+ return;
+ }
+
+ int hbs = (blockSize.Get4x4WideCount() << 2) >> 1;
+ bool has_rows = (blockOrigin.Y + hbs) < pcs.Parent.AlignedHeight;
+ bool has_cols = (blockOrigin.X + hbs) < pcs.Parent.AlignedWidth;
+
+ int partition_context_left_neighbor_index = partition_context_na.GetLeftIndex(blockOrigin);
+ int partition_context_top_neighbor_index = partition_context_na.GetTopIndex(blockOrigin);
+
+ int context_index = 0;
+
+ byte above_ctx =
+ (byte)(partition_context_na.Top[partition_context_top_neighbor_index].Above == byte.MaxValue
+ ? 0
+ : partition_context_na.Top[partition_context_top_neighbor_index].Above);
+ byte left_ctx =
+ (byte)(partition_context_na.Left[partition_context_left_neighbor_index].Left == byte.MaxValue
+ ? 0
+ : partition_context_na.Left[partition_context_left_neighbor_index].Left);
+
+ int blockSizeLog2 = blockSize.Get4x4WidthLog2() - 1;
+ int above = (above_ctx >> blockSizeLog2) & 1, left = (left_ctx >> blockSizeLog2) & 1;
+
+ Guard.IsTrue(blockSize.Get4x4WidthLog2() == blockSize.Get4x4HeightLog2(), nameof(blockSize), "Blocks need to be square.");
+ Guard.IsTrue(blockSizeLog2 >= 0, nameof(blockSizeLog2), "bsl needs to be a positive integer.");
+
+ context_index = ((left * 2) + above) + (blockSizeLog2 * Av1Constants.PartitionProbabilitySet);
+
+ if (!has_rows && !has_cols)
+ {
+ Guard.IsTrue(partitionType == Av1PartitionType.Split, nameof(partitionType), "Partition outside frame boundaries should have Split type.");
+ return;
+ }
+
+ if (has_rows && has_cols)
+ {
+ writer.WritePartitionType(partitionType, context_index);
+ }
+ else if (!has_rows && has_cols)
+ {
+ writer.WriteSplitOrVertical(partitionType, blockSize, context_index);
+ }
+ else
+ {
+ writer.WriteSplitOrHorizontal(partitionType, blockSize, context_index);
+ }
+
+ return;
+ }
+
+ ///
+ /// SVT: write_modes_b
+ ///
+ private static void WriteModesBlock(
+ Av1PictureControlSet pcs,
+ Av1EntropyCodingContext entropyCodingContext,
+ ref Av1SymbolEncoder writer,
+ Av1Superblock tb_ptr,
+ Av1EncoderBlockStruct blk_ptr,
+ ushort tile_idx,
+ Av1FrameBuffer coeff_ptr)
+ {
+ Av1SequenceControlSet scs = pcs.Sequence;
+ ObuFrameHeader frm_hdr = pcs.Parent.FrameHeader;
+ Av1NeighborArrayUnit luma_dc_sign_level_coeff_na = pcs.LuminanceDcSignLevelCoefficientNeighbors[tile_idx];
+ Av1NeighborArrayUnit cr_dc_sign_level_coeff_na = pcs.CrDcSignLevelCoefficientNeighbors[tile_idx];
+ Av1NeighborArrayUnit cb_dc_sign_level_coeff_na = pcs.CbDcSignLevelCoefficientNeighbors[tile_idx];
+ Av1NeighborArrayUnit txfm_context_array = pcs.TransformFunctionContexts[tile_idx];
+ Av1BlockGeometry blockGeometry = Av1BlockGeometryFactory.GetBlockGeometryByModeDecisionScanIndex(blk_ptr.ModeDecisionScanIndex);
+ Point blockOrigin = Point.Add(entropyCodingContext.SuperblockOrigin, (Size)blockGeometry.Origin);
+ Av1BlockSize blockSize = blockGeometry.BlockSize;
+ Av1MacroBlockModeInfo macroBlockModeInfo = pcs.GetMacroBlockModeInfo(blockOrigin);
+ bool skipWritingCoefficients = macroBlockModeInfo.Block.Skip;
+ entropyCodingContext.MacroBlockModeInfo = macroBlockModeInfo;
+
+ bool skip_mode = macroBlockModeInfo.Block.SkipMode;
+
+ Guard.MustBeLessThan((int)blockSize, (int)Av1BlockSize.AllSizes, nameof(blockSize));
+ int mi_row = blockOrigin.Y >> Av1Constants.ModeInfoSizeLog2;
+ int mi_col = blockOrigin.X >> Av1Constants.ModeInfoSizeLog2;
+ int mi_stride = pcs.Parent.Common.ModeInfoStride;
+ int offset = (mi_row * mi_stride) + mi_col;
+ Point modeInfoPosition = new(mi_col, mi_row);
+ blk_ptr.MacroBlock.ModeInfo = pcs.ModeInfoGrid[offset];
+ blk_ptr.MacroBlock.Tile = new Av1TileInfo(tb_ptr.TileInfo);
+ blk_ptr.MacroBlock.IsUpAvailable = modeInfoPosition.Y > tb_ptr.TileInfo.ModeInfoRowStart;
+ blk_ptr.MacroBlock.IsLeftAvailable = modeInfoPosition.X > tb_ptr.TileInfo.ModeInfoColumnStart;
+
+ if (blk_ptr.MacroBlock.IsUpAvailable)
+ {
+ blk_ptr.MacroBlock.AboveMacroBlock = blk_ptr.MacroBlock.ModeInfo[-mi_stride].MacroBlockModeInfo;
+ }
+ else
+ {
+ blk_ptr.MacroBlock.AboveMacroBlock = null;
+ }
+
+ if (blk_ptr.MacroBlock.IsLeftAvailable)
+ {
+ blk_ptr.MacroBlock.LeftMacroBlock = blk_ptr.MacroBlock.ModeInfo[-1].MacroBlockModeInfo;
+ }
+ else
+ {
+ blk_ptr.MacroBlock.LeftMacroBlock = null;
+ }
+
+ // Not required, part of Av1SymbolEncoder.
+ // blk_ptr.MacroBlock.tile_ctx = frame_context;
+ SetModeInfoRowAndColumn(
+ pcs,
+ blk_ptr.MacroBlock,
+ blk_ptr.MacroBlock.Tile,
+ modeInfoPosition,
+ blockSize,
+ mi_stride,
+ pcs.Parent.Common.ModeInfoRowCount,
+ pcs.Parent.Common.ModeInfoColumnCount);
+
+ // if (pcs.slice_type == I_SLICE)
+ // We implement only INTRA frames.
+ {
+ // const int32_t skip = write_skip(cm, xd, mbmi->segment_id, mi, w)
+ if (pcs.Parent.FrameHeader.SegmentationParameters.Enabled && pcs.Parent.FrameHeader.SegmentationParameters.SegmentIdPrecedesSkip)
+ {
+ WriteSegmentId(pcs, ref writer, blockGeometry.BlockSize, blockOrigin, blk_ptr, skipWritingCoefficients);
+ }
+
+ EncodeSkipCoefficients(ref writer, blk_ptr, skipWritingCoefficients);
+
+ if (pcs.Parent.FrameHeader.SegmentationParameters.Enabled && !pcs.Parent.FrameHeader.SegmentationParameters.SegmentIdPrecedesSkip)
+ {
+ WriteSegmentId(pcs, ref writer, blockGeometry.BlockSize, blockOrigin, blk_ptr, skipWritingCoefficients);
+ }
+
+ WriteCdef(
+ scs,
+ pcs,
+ ref writer,
+ tile_idx,
+ skipWritingCoefficients,
+ blockOrigin << Av1Constants.ModeInfoSizeLog2);
+
+ if (pcs.Parent.FrameHeader.DeltaQParameters.IsPresent)
+ {
+ int current_q_index = blk_ptr.QuantizationIndex;
+ bool super_block_upper_left = (((blockOrigin.Y >> 2) & (scs.SequenceHeader.SuperblockModeInfoSize - 1)) == 0) &&
+ (((blockOrigin.X >> 2) & (scs.SequenceHeader.SuperblockModeInfoSize - 1)) == 0);
+ if ((blockSize != scs.SequenceHeader.SuperblockSize || !skipWritingCoefficients) && super_block_upper_left)
+ {
+ Guard.MustBeGreaterThan(current_q_index, 0, nameof(current_q_index));
+ int reduced_delta_qindex = (current_q_index - pcs.Parent.PreviousQIndex[tile_idx]) /
+ frm_hdr.DeltaQParameters.Resolution;
+
+ writer.WriteDeltaQuantizerIndex(reduced_delta_qindex);
+ pcs.Parent.PreviousQIndex[tile_idx] = current_q_index;
+ }
+ }
+
+ Av1PredictionMode intra_luma_mode = macroBlockModeInfo.Block.Mode;
+ Av1PredictionMode intra_chroma_mode = macroBlockModeInfo.Block.UvMode;
+ if (IsIntraBlockCopyAllowed(pcs.Parent.FrameHeader/*, pcs.Parent.SliceType*/))
+ {
+ WriteIntraBlockCopyInfo(ref writer, macroBlockModeInfo, blk_ptr);
+ }
+
+ if (!macroBlockModeInfo.Block.UseIntraBlockCopy)
+ {
+ EncodeIntraLumaMode(ref writer, macroBlockModeInfo, blk_ptr, blockSize, intra_luma_mode);
+ }
+
+ if (!macroBlockModeInfo.Block.UseIntraBlockCopy)
+ {
+ if (blockGeometry.HasUv)
+ {
+ EncodeIntraChromaMode(
+ ref writer,
+ macroBlockModeInfo,
+ blk_ptr,
+ blockSize,
+ intra_luma_mode,
+ intra_chroma_mode,
+ blockGeometry.BlockWidth <= 32 && blockGeometry.BlockHeight <= 32);
+ }
+ }
+
+ if (!macroBlockModeInfo.Block.UseIntraBlockCopy && IsPaletteAllowed(frm_hdr.AllowScreenContentTools, blockGeometry.BlockSize))
+ {
+ WritePaletteModeInfo(
+ scs,
+ ref writer,
+ macroBlockModeInfo,
+ blk_ptr,
+ blockGeometry.BlockSize,
+ blockOrigin >> Av1Constants.ModeInfoSizeLog2);
+ }
+
+ if (!macroBlockModeInfo.Block.UseIntraBlockCopy &&
+ IsFilterIntraAllowed(scs.SequenceHeader.FilterIntraLevel > 0, blockSize, blk_ptr.PaletteSize[0], intra_luma_mode))
+ {
+ writer.WriteFilterIntraMode(blk_ptr.FilterIntraMode, blockSize);
+ }
+
+ if (!macroBlockModeInfo.Block.UseIntraBlockCopy)
+ {
+ Guard.IsTrue(blk_ptr.PaletteSize[1] == 0, nameof(blk_ptr), "Palette of chroma plane shall be empty.");
+
+ // TOKENEXTRA tok = entropyCodingContext.tok;
+ for (int plane = 0; plane < 2; ++plane)
+ {
+ int palette_size_plane = blk_ptr.PaletteSize[plane];
+ if (palette_size_plane > 0)
+ {
+ throw new NotImplementedException("Tokenizing palette not implemented.");
+ /*
+ Av1TransformSize tx_size =
+ blockGeometry.TransformSize[macroBlockModeInfo.Block.TransformDepth]; // inherit tx_size from 1st transform block;
+ svt_av1_tokenize_color_map(
+ frame_context,
+ blk_ptr,
+ plane,
+ tok,
+ blockSize,
+ tx_size,
+ PALETTE_MAP,
+ 0); // NO CDF update in entropy, the update will take place in arithmetic encode
+ assert(macroBlockModeInfo.Block.UseIntraBlockCopy);
+ assert(IsPaletteAllowed(pcs.Parent.FrameHeader.AllowScreenContentTools, blockGeometry.BlockSize));
+ svt_aom_get_block_dimensions(blockGeometry.BlockSize, plane, blk_ptr.MacroBlock, null, null, out int rowCount, out int columnCount);
+ pack_map_tokens(ref writer, ref entropyCodingContext.tok, palette_size_plane, rowCount * columnCount);
+
+ // advance the pointer
+ entropyCodingContext.tok = tok;
+ */
+ }
+ }
+ }
+
+ if (frm_hdr.TransformMode == Av1TransformMode.Select)
+ {
+ // TODO: Implement when Selecting transform block size is supported.
+ // CodeTransformSize(
+ // pcs,
+ // ref writer,
+ // blockOrigin,
+ // blk_ptr,
+ // blockGeometry,
+ // txfm_context_array,
+ // skipWritingCoefficients);
+ }
+
+ if (!skipWritingCoefficients)
+ {
+ // SVT: av1_encode_coeff_1d
+ EncodeCoefficients1d(
+ pcs,
+ entropyCodingContext,
+ ref writer,
+ entropyCodingContext.MacroBlockModeInfo,
+ blk_ptr,
+ blockOrigin,
+ intra_luma_mode,
+ blockSize,
+ coeff_ptr,
+ luma_dc_sign_level_coeff_na,
+ cr_dc_sign_level_coeff_na,
+ cb_dc_sign_level_coeff_na);
+ }
+ }
+
+ // Update the neighbors
+ UpdateNeighbors(pcs, entropyCodingContext, blockOrigin, blk_ptr, tile_idx, blockSize);
+
+ if (IsPaletteAllowed(pcs.Parent.PaletteLevel, blockGeometry.BlockSize))
+ {
+ /*
+ // free ENCDEC palette info buffer
+ assert(blk_ptr.palette_info.color_idx_map != null && "free palette:Null");
+ EB_FREE(blk_ptr.palette_info.color_idx_map);
+ blk_ptr.palette_info.color_idx_map = null;
+ EB_FREE(blk_ptr.palette_info);*/
+ }
+ }
+
+ private static void EncodeIntraChromaMode(
+ ref Av1SymbolEncoder writer,
+ Av1MacroBlockModeInfo macroBlockModeInfo,
+ Av1EncoderBlockStruct blk_ptr,
+ Av1BlockSize blockSize,
+ Av1PredictionMode lumaMode,
+ Av1PredictionMode chromaMode,
+ bool isChromaFromLumaAllowed)
+ {
+ writer.WriteChromaMode(chromaMode, isChromaFromLumaAllowed, lumaMode);
+
+ if (chromaMode == Av1PredictionMode.UvChromaFromLuma)
+ {
+ writer.WriteChromaFromLumaAlphas(
+ blk_ptr.PredictionUnits[0].ChromaFromLumaIndex,
+ blk_ptr.PredictionUnits[0].ChromaFromLumaSigns);
+ }
+
+ if (blockSize >= Av1BlockSize.Block8x8 && macroBlockModeInfo.Block.UvMode.IsDirectional())
+ {
+ writer.WriteAngleDelta(blk_ptr.PredictionUnits[0].AngleDelta[(int)Av1PlaneType.Uv] + Av1Constants.MaxAngleDelta, chromaMode);
+ }
+ }
+
+ ///
+ /// Get the contexts (left and top) for writing the intra luma mode for key frames.
+ /// Intended to be used for key frame only.
+ ///
+ /// SVT: svt_aom_get_kf_y_mode_ctx
+ private static void GetYModeContext(Av1MacroBlockD xd, out byte above_ctx, out byte left_ctx)
+ {
+ Av1PredictionMode intraLumaLeftMode = Av1PredictionMode.DC;
+ Av1PredictionMode intraLumaTopMode = Av1PredictionMode.DC;
+ if (xd.IsLeftAvailable)
+ {
+ // When called for key frame, neighbouring mode should be intra
+ // assert(!is_inter_block(&xd->mi[-1]->mbmi.block_mi) || is_intrabc_block(&xd->mi[-1]->mbmi.block_mi));
+ intraLumaLeftMode = xd.ModeInfo[-1].MacroBlockModeInfo.Block.Mode;
+ }
+
+ if (xd.IsUpAvailable)
+ {
+ // When called for key frame, neighbouring mode should be intra
+ // assert(!is_inter_block(&xd->mi[-xd->mi_stride]->mbmi.block_mi) ||
+ // is_intrabc_block(&xd->mi[-xd->mi_stride]->mbmi.block_mi));
+ intraLumaTopMode = xd.ModeInfo[-xd.ModeInfoStride].MacroBlockModeInfo.Block.Mode;
+ }
+
+ above_ctx = IntraModeContextLookup[(int)intraLumaTopMode];
+ left_ctx = IntraModeContextLookup[(int)intraLumaLeftMode];
+ }
+
+ ///
+ /// SVT: encode_intra_luma_mode_kf_av1
+ ///
+ private static void EncodeIntraLumaMode(
+ ref Av1SymbolEncoder writer,
+ Av1MacroBlockModeInfo macroBlockModeInfo,
+ Av1EncoderBlockStruct blk_ptr,
+ Av1BlockSize blockSize,
+ Av1PredictionMode lumaMode)
+ {
+ GetYModeContext(blk_ptr.MacroBlock, out byte topContext, out byte leftContext);
+ writer.WriteLumaMode(lumaMode, topContext, leftContext);
+
+ if (blockSize >= Av1BlockSize.Block8x8 && macroBlockModeInfo.Block.Mode.IsDirectional())
+ {
+ writer.WriteAngleDelta(blk_ptr.PredictionUnits[0].AngleDelta[(int)Av1PlaneType.Y] + Av1Constants.MaxAngleDelta, lumaMode);
+ }
+ }
+
+ private static void WritePaletteModeInfo(
+ Av1SequenceControlSet scs,
+ ref Av1SymbolEncoder writer,
+ Av1MacroBlockModeInfo macroBlockModeInfo,
+ Av1EncoderBlockStruct blk_ptr,
+ Av1BlockSize blockSize,
+ Point point)
+ {/*
+ Av1PredictionMode intra_luma_mode = macroBlockModeInfo.Mode;
+ Av1PredictionMode intra_chroma_mode = macroBlockModeInfo.ModeUv;
+
+ Av1PaletteModeInfo pmi = blk_ptr.PaletteInfo.pmi;
+ int bsize_ctx = svt_aom_get_palette_bsize_ctx(bsize);
+ Guard.MustBeGreaterThanOrEqualTo(bsize_ctx, 0, nameof(bsize_ctx));
+ if (intra_luma_mode == Av1PredictionMode.DC)
+ {
+ int n = blk_ptr.PaletteSize[0];
+ int palette_y_mode_ctx = svt_aom_get_palette_mode_ctx(blk_ptr->av1xd);
+ writer.WriteYMode(n > 0, bsize_ctx, palette_y_mode_ctx);
+ if (n > 0)
+ {
+ writer.WriteYSize(n - PALETTE_MIN_SIZE, bsize_ctx);
+ write_palette_colors_y(blk_ptr.MacroBlock, pmi, scs.StaticConfig.EncoderBitDepth, ref writer, n);
+ }
+ }
+
+ bool uv_dc_pred = intra_chroma_mode == Av1PredictionMode.DC && is_chroma_reference(point, blockSize, 1, 1);
+ if (uv_dc_pred)
+ {
+ // assert(blk_ptr->palette_size[1] == 0); //remove when chroma is on
+ bool palette_uv_mode_ctx = blk_ptr.PaletteSize[0] > 0;
+ writer.WriteUvMode(false, palette_uv_mode_ctx);
+ }*/
+ throw new NotImplementedException("Palette mode encoding not implemented.");
+ }
+
+ ///
+ /// SVT: svt_aom_filter_intra_allowed
+ ///
+ private static bool IsFilterIntraAllowed(
+ bool enableFilterIntra,
+ Av1BlockSize blockSize,
+ int paletteSize,
+ Av1PredictionMode mode)
+ => mode == Av1PredictionMode.DC && paletteSize == 0 && IsFilterIntraAllowedBlockSize(enableFilterIntra, blockSize);
+
+ ///
+ /// SVT: svt_aom_filter_intra_allowed_bsize
+ ///
+ private static bool IsFilterIntraAllowedBlockSize(bool enableFilterIntra, Av1BlockSize blockSize)
+ {
+ if (!enableFilterIntra)
+ {
+ return false;
+ }
+
+ return blockSize.GetWidth() <= 32 && blockSize.GetHeight() <= 32;
+ }
+
+ ///
+ /// SVT: write_intrabc_info
+ ///
+ private static void WriteIntraBlockCopyInfo(
+ ref Av1SymbolEncoder writer,
+ Av1MacroBlockModeInfo macroBlockModeInfo,
+ Av1EncoderBlockStruct block)
+ {
+ bool use_intrabc = macroBlockModeInfo.Block.UseIntraBlockCopy;
+ writer.WriteUseIntraBlockCopy(use_intrabc);
+ if (use_intrabc)
+ {
+ throw new NotImplementedException("Intra block code encoding not implemented.");
+ /*
+ //assert(mbmi->mode == DC_PRED);
+ //assert(mbmi->uv_mode == UV_DC_PRED);
+ //assert(mbmi->motion_mode == SIMPLE_TRANSLATION);
+ IntMv dv_ref = block->predmv[0]; // mbmi_ext->ref_mv_stack[INTRA_FRAME][0].this_mv;
+ MV mv;
+ mv = macroBlockModeInfo.Block.mv[INTRA_FRAME].as_mv;
+ svt_av1_encode_dv(w, &mv, &dv_ref.as_mv, &ec_ctx->ndvc);*/
+ }
+ }
+
+ ///
+ /// SVT: svt_aom_allow_intrabc
+ ///
+ private static bool IsIntraBlockCopyAllowed(ObuFrameHeader frameHeader)
+ => frameHeader.AllowScreenContentTools && frameHeader.AllowIntraBlockCopy;
+
+ ///
+ /// SVT: ec_update_neighbors
+ ///
+ private static void UpdateNeighbors(
+ Av1PictureControlSet pcs,
+ Av1EntropyCodingContext entropyCodingContext,
+ Point blockOrigin,
+ Av1EncoderBlockStruct blk_ptr,
+ ushort tile_idx,
+ Av1BlockSize blockSize)
+ {
+ Av1NeighborArrayUnit partition_context_na = pcs.PartitionContexts[tile_idx];
+ Av1NeighborArrayUnit luma_dc_sign_level_coeff_na = pcs.LuminanceDcSignLevelCoefficientNeighbors[tile_idx];
+ Av1NeighborArrayUnit cr_dc_sign_level_coeff_na = pcs.CrDcSignLevelCoefficientNeighbors[tile_idx];
+ Av1NeighborArrayUnit cb_dc_sign_level_coeff_na = pcs.CbDcSignLevelCoefficientNeighbors[tile_idx];
+ Av1BlockGeometry blk_geom = Av1BlockGeometryFactory.GetBlockGeometryByModeDecisionScanIndex(blk_ptr.ModeDecisionScanIndex);
+ Av1MacroBlockModeInfo mbmi = pcs.GetMacroBlockModeInfo(blockOrigin);
+ bool skip_coeff = mbmi.Block.Skip;
+
+ // Update the Leaf Depth Neighbor Array
+ Av1PartitionContext partition = new(
+ PartitionContextLookup[(int)blockSize].Above,
+ PartitionContextLookup[(int)blockSize].Left);
+ Size size = new(blk_geom.BlockWidth, blk_geom.BlockHeight);
+ Span partitionSpan = new(ref partition);
+ partition_context_na.UnitModeWrite(
+ partitionSpan,
+ blockOrigin,
+ size,
+ Av1NeighborArrayUnit.UnitMask.Left | Av1NeighborArrayUnit.UnitMask.Top);
+ if (skip_coeff)
+ {
+ byte dcSignLevelCoefficient = 0;
+ Span dcSignSpan = new(ref dcSignLevelCoefficient);
+
+ luma_dc_sign_level_coeff_na.UnitModeWrite(
+ dcSignSpan,
+ blockOrigin,
+ size,
+ Av1NeighborArrayUnit.UnitMask.Left | Av1NeighborArrayUnit.UnitMask.Top);
+
+ if (blk_geom.HasUv)
+ {
+ cb_dc_sign_level_coeff_na.UnitModeWrite(
+ dcSignSpan,
+ ((blockOrigin >> 3) << 3) >> 1,
+ size,
+ Av1NeighborArrayUnit.UnitMask.Left | Av1NeighborArrayUnit.UnitMask.Top);
+ cr_dc_sign_level_coeff_na.UnitModeWrite(
+ dcSignSpan,
+ ((blockOrigin >> 3) << 3) >> 1,
+ size,
+ Av1NeighborArrayUnit.UnitMask.Left | Av1NeighborArrayUnit.UnitMask.Top);
+ entropyCodingContext.CodedAreaSuperblockUv += blk_geom.BlockWidthUv * blk_geom.BlockHeightUv;
+ }
+
+ entropyCodingContext.CodedAreaSuperblock += blk_geom.BlockWidth * blk_geom.BlockHeight;
+ }
+ }
+
+ ///
+ /// SVT: svt_av1_allow_palette
+ ///
+ private static bool IsPaletteAllowed(int allowPalette, Av1BlockSize blockSize)
+ {
+ Guard.MustBeLessThan((int)blockSize, (int)Av1BlockSize.AllSizes, nameof(blockSize));
+ return allowPalette != 0 &&
+ blockSize.GetWidth() <= 64 &&
+ blockSize.GetHeight() <= 64 &&
+ blockSize >= Av1BlockSize.Block8x8;
+ }
+
+ ///
+ /// SVT: svt_aom_allow_palette
+ ///
+ private static bool IsPaletteAllowed(bool allowScreenContentTools, Av1BlockSize blockSize)
+ => allowScreenContentTools &&
+ blockSize.GetWidth() <= 64 &&
+ blockSize.GetHeight() <= 64 &&
+ blockSize >= Av1BlockSize.Block8x8;
+
+ ///
+ /// SVT: write_cdef
+ ///
+ private static void WriteCdef(
+ Av1SequenceControlSet scs,
+ Av1PictureControlSet pcs,
+ ref Av1SymbolEncoder writer,
+ int tileIndex,
+ bool skip,
+ Point modeInfoPosition)
+ {
+ Av1EncoderCommon cm = pcs.Parent.Common;
+ ObuFrameHeader frameHeader = pcs.Parent.FrameHeader;
+
+ if (frameHeader.CodedLossless || frameHeader.AllowIntraBlockCopy)
+ {
+ // Initialize to indicate no CDEF for safety.
+ frameHeader.CdefParameters.BitCount = 0;
+ frameHeader.CdefParameters.YStrength[0] = 0;
+ frameHeader.CdefParameters.UvStrength[0] = 0;
+
+ // pcs.Parent.nb_cdef_strengths = 1;
+ return;
+ }
+
+ // int m = ~((1 << (6 - Av1Constants.ModeInfoSizeLog2)) - 1);
+ // cm->mi_grid_visible[(mi_row & m) * cm->mi_stride + (mi_col & m)];
+ Av1ModeInfo mi = pcs.GetFromModeInfoGrid(modeInfoPosition)[0];
+
+ // Initialise when at top left part of the superblock
+ if ((modeInfoPosition.Y & (scs.SequenceHeader.SuperblockModeInfoSize - 1)) == 0 &&
+ (modeInfoPosition.X & (scs.SequenceHeader.SuperblockModeInfoSize - 1)) == 0)
+ {
+ // Top left?
+ pcs.CdefPreset[tileIndex][0] = -1;
+ pcs.CdefPreset[tileIndex][1] = -1;
+ pcs.CdefPreset[tileIndex][2] = -1;
+ pcs.CdefPreset[tileIndex][3] = -1;
+ }
+
+ // Emit CDEF param at first non-skip coding block
+ int mask = 1 << (6 - Av1Constants.ModeInfoSizeLog2);
+ int index = scs.SequenceHeader.Use128x128Superblock ? Math.Max(1, modeInfoPosition.X & mask) + (2 * Math.Max(1, modeInfoPosition.Y & mask)) : 0;
+
+ if (pcs.CdefPreset[tileIndex][index] == -1 && !skip)
+ {
+ writer.WriteCdefStrength(mi.MacroBlockModeInfo.CdefStrength, frameHeader.CdefParameters.BitCount);
+ pcs.CdefPreset[tileIndex][index] = mi.MacroBlockModeInfo.CdefStrength;
+ }
+ }
+
+ ///
+ /// SVT: set_mi_row_col
+ ///
+ private static void SetModeInfoRowAndColumn(
+ Av1PictureControlSet pcs,
+ Av1MacroBlockD macroBlock,
+ Av1TileInfo tile,
+ Point modeInfoPosition,
+ Av1BlockSize blockSize,
+ int modeInfoStride,
+ int modeInfoRowCount,
+ int modeInfoColumnCount)
+ {
+ macroBlock.ToTopEdge = -((modeInfoPosition.Y << Av1Constants.ModeInfoSizeLog2) << 3);
+ macroBlock.ToBottomEdge = ((modeInfoRowCount - blockSize.GetHeight() - modeInfoPosition.Y) << Av1Constants.ModeInfoSizeLog2) << 3;
+ macroBlock.ToLeftEdge = -((modeInfoPosition.X << Av1Constants.ModeInfoSizeLog2) << 3);
+ macroBlock.ToRightEdge = ((modeInfoColumnCount - blockSize.GetWidth() - modeInfoPosition.X) << Av1Constants.ModeInfoSizeLog2) << 3;
+
+ macroBlock.ModeInfoStride = modeInfoStride;
+
+ // Are edges available for intra prediction?
+ macroBlock.IsUpAvailable = modeInfoPosition.Y > tile.ModeInfoRowStart;
+ macroBlock.IsLeftAvailable = modeInfoPosition.X > tile.ModeInfoColumnStart;
+ macroBlock.ModeInfo = pcs.GetFromModeInfoGrid(modeInfoPosition);
+
+ if (macroBlock.IsUpAvailable)
+ {
+ macroBlock.AboveMacroBlock = macroBlock.ModeInfo[-modeInfoStride].MacroBlockModeInfo;
+ }
+ else
+ {
+ macroBlock.AboveMacroBlock = null;
+ }
+
+ if (macroBlock.IsLeftAvailable)
+ {
+ macroBlock.LeftMacroBlock = macroBlock.ModeInfo[-1].MacroBlockModeInfo;
+ }
+ else
+ {
+ macroBlock.LeftMacroBlock = null;
+ }
+
+ macroBlock.N8Size = new Size(blockSize.GetWidth(), blockSize.GetHeight());
+ macroBlock.IsSecondRectangle = false;
+ if (macroBlock.N8Size.Width < macroBlock.N8Size.Height)
+ {
+ // Only mark is_sec_rect as 1 for the last block.
+ // For PARTITION_VERT_4, it would be (0, 0, 0, 1);
+ // For other partitions, it would be (0, 1).
+ if (((modeInfoPosition.X + macroBlock.N8Size.Width) & (macroBlock.N8Size.Height - 1)) == 0)
+ {
+ macroBlock.IsSecondRectangle = true;
+ }
+ }
+
+ if (macroBlock.N8Size.Width > macroBlock.N8Size.Height)
+ {
+ if ((modeInfoPosition.Y & (macroBlock.N8Size.Width - 1)) > 0)
+ {
+ macroBlock.IsSecondRectangle = true;
+ }
+ }
+ }
+
+ ///
+ /// SVT: av1_encode_coeff_1d
+ ///
+ private static void EncodeCoefficients1d(
+ Av1PictureControlSet pcs,
+ Av1EntropyCodingContext ec_ctx,
+ ref Av1SymbolEncoder writer,
+ Av1MacroBlockModeInfo mbmi,
+ Av1EncoderBlockStruct blk_ptr,
+ Point blockOrigin,
+ Av1PredictionMode intraLumaDir,
+ Av1BlockSize planeBlockSize,
+ Av1FrameBuffer coeff_ptr,
+ Av1NeighborArrayUnit luma_dc_sign_level_coeff_na,
+ Av1NeighborArrayUnit cr_dc_sign_level_coeff_na,
+ Av1NeighborArrayUnit cb_dc_sign_level_coeff_na)
+ {
+ if (mbmi.Block.TransformDepth != 0)
+ {
+ EncodeTransformCoefficientsY(
+ pcs,
+ ec_ctx,
+ ref writer,
+ mbmi,
+ blk_ptr,
+ blockOrigin,
+ intraLumaDir,
+ planeBlockSize,
+ coeff_ptr,
+ luma_dc_sign_level_coeff_na);
+
+ EncodeTransformCoefficientsUv(
+ pcs,
+ ec_ctx,
+ ref writer,
+ mbmi,
+ blk_ptr,
+ blockOrigin,
+ intraLumaDir,
+ planeBlockSize,
+ coeff_ptr,
+ cr_dc_sign_level_coeff_na,
+ cb_dc_sign_level_coeff_na);
+ }
+ else
+ {
+ throw new NotImplementedException("Only capable to encode Largest transform mode.");
+ }
+ }
+
+ ///
+ /// SVT: av1_encode_tx_coef_y
+ ///
+ public static void EncodeTransformCoefficientsY(
+ Av1PictureControlSet pcs,
+ Av1EntropyCodingContext entropyCodingContext,
+ ref Av1SymbolEncoder writer,
+ Av1MacroBlockModeInfo mbmi,
+ Av1EncoderBlockStruct blk_ptr,
+ Point blockOrigin,
+ Av1PredictionMode intraLumaDir,
+ Av1BlockSize plane_bsize,
+ Av1FrameBuffer coeff_ptr,
+ Av1NeighborArrayUnit luma_dc_sign_level_coeff_na)
+ {
+ // Removed any code related to INTER frames.
+ Av1BlockGeometry blockGeometry = Av1BlockGeometryFactory.GetBlockGeometryByModeDecisionScanIndex(blk_ptr.ModeDecisionScanIndex);
+ int tx_depth = mbmi.Block.TransformDepth;
+ int txb_count = blockGeometry.TransformBlockCount[mbmi.Block.TransformDepth];
+ ObuFrameHeader frameHeader = pcs.Parent.FrameHeader;
+
+ for (int tx_index = 0; tx_index < txb_count; tx_index++)
+ {
+ int txb_itr = tx_index;
+
+ Av1TransformSize tx_size = blockGeometry.TransformSize[tx_depth];
+
+ int coeff1d_offset = entropyCodingContext.CodedAreaSuperblock;
+ Span coeff_buffer = coeff_ptr.BufferY!.DangerousGetSingleSpan()[coeff1d_offset..];
+
+ Av1TransformBlockContext blockContext = new();
+ Point transformOrigin = blockGeometry.TransformOrigin[tx_depth][txb_itr];
+ GetTransformBlockContexts(
+ pcs,
+ Av1ComponentType.Luminance,
+ luma_dc_sign_level_coeff_na,
+ blockOrigin + (Size)transformOrigin - (Size)blockGeometry.Origin,
+ plane_bsize,
+ tx_size,
+ blockContext);
+
+ Av1TransformType tx_type = blk_ptr.TransformBlocks[txb_itr].TransformType[(int)Av1ComponentType.Luminance];
+ int eob = blk_ptr.TransformBlocks[txb_itr].NzCoefficientCount[0];
+ if (eob == 0)
+ {
+ // INTRA
+ tx_type = blk_ptr.TransformBlocks[txb_itr].TransformType[(int)Av1PlaneType.Y] = Av1TransformType.DctDct;
+ Guard.IsTrue(tx_type == Av1TransformType.DctDct, nameof(tx_type), string.Empty);
+ }
+
+ int cul_level_y = writer.WriteCoefficients(
+ tx_size,
+ tx_type,
+ intraLumaDir,
+ coeff_buffer,
+ Av1ComponentType.Luminance,
+ blockContext,
+ (ushort)eob,
+ frameHeader.UseReducedTransformSet,
+ blk_ptr.FilterIntraMode);
+
+ // Update the luma Dc Sign Level Coeff Neighbor Array
+ Span culLevelSpan = new(ref cul_level_y);
+ ReadOnlySpan dc_sign_level_coeff = MemoryMarshal.AsBytes(culLevelSpan);
+
+ int transformWidth = blockGeometry.TransformSize[tx_depth].GetWidth();
+ int transformHeight = blockGeometry.TransformSize[tx_depth].GetHeight();
+ luma_dc_sign_level_coeff_na.UnitModeWrite(
+ dc_sign_level_coeff,
+ blockOrigin + (Size)transformOrigin - (Size)blockGeometry.Origin,
+ new Size(transformWidth, transformHeight),
+ Av1NeighborArrayUnit.UnitMask.Top | Av1NeighborArrayUnit.UnitMask.Left);
+
+ entropyCodingContext.CodedAreaSuperblock += transformWidth * transformHeight;
+ }
+ }
+
+ ///
+ /// SVT: av1_encode_tx_coef_uv
+ ///
+ private static void EncodeTransformCoefficientsUv(
+ Av1PictureControlSet pcs,
+ Av1EntropyCodingContext entropyCodingContext,
+ ref Av1SymbolEncoder writer,
+ Av1MacroBlockModeInfo mbmi,
+ Av1EncoderBlockStruct blk_ptr,
+ Point blockOrigin,
+ Av1PredictionMode intraLumaDir,
+ Av1BlockSize plane_bsize,
+ Av1FrameBuffer coeff_ptr,
+ Av1NeighborArrayUnit cr_dc_sign_level_coeff_na,
+ Av1NeighborArrayUnit cb_dc_sign_level_coeff_na)
+ {
+ Av1BlockGeometry blockGeometry = Av1BlockGeometryFactory.GetBlockGeometryByModeDecisionScanIndex(blk_ptr.ModeDecisionScanIndex);
+
+ if (!blockGeometry.HasUv)
+ {
+ return;
+ }
+
+ int tx_depth = mbmi.Block.TransformDepth;
+ uint txb_count = 1;
+ ObuFrameHeader frameHeader = pcs.Parent.FrameHeader;
+ int transformWidth = blockGeometry.TransformSize[tx_depth].GetWidth();
+ int transformHeight = blockGeometry.TransformSize[tx_depth].GetHeight();
+
+ for (uint tx_index = 0; tx_index < txb_count; ++tx_index)
+ {
+ Av1TransformSize chroma_tx_size = blockGeometry.TransformSizeUv[tx_depth];
+
+ if (blockGeometry.HasUv)
+ {
+ // cb
+ Span coeff_buffer = coeff_ptr.BufferCb!.DangerousGetSingleSpan().Slice(entropyCodingContext.CodedAreaSuperblockUv);
+ Av1TransformBlockContext blockContext = new();
+ Point transformOrigin = blockGeometry.TransformOrigin[tx_depth][tx_index];
+ GetTransformBlockContexts(
+ pcs,
+ Av1ComponentType.Chroma,
+ cb_dc_sign_level_coeff_na,
+ RoundUv(blockOrigin + (Size)transformOrigin - (Size)blockGeometry.Origin) >> 1,
+ blockGeometry.BlockSizeUv,
+ chroma_tx_size,
+ blockContext);
+ Av1TransformType chroma_tx_type = blk_ptr.TransformBlocks[tx_index].TransformType[(int)Av1ComponentType.Chroma];
+ int endOfBlockCb = blk_ptr.TransformBlocks[tx_index].NzCoefficientCount[1];
+ int cul_level_cb = writer.WriteCoefficients(
+ chroma_tx_size,
+ chroma_tx_type,
+ intraLumaDir,
+ coeff_buffer,
+ Av1ComponentType.Chroma,
+ blockContext,
+ (ushort)endOfBlockCb,
+ frameHeader.UseReducedTransformSet,
+ blk_ptr.FilterIntraMode);
+
+ // cr
+ coeff_buffer = coeff_ptr.BufferCr!.DangerousGetSingleSpan().Slice(entropyCodingContext.CodedAreaSuperblockUv);
+ blockContext = new();
+ int endOfBlockCr = blk_ptr.TransformBlocks[tx_index].NzCoefficientCount[2];
+
+ GetTransformBlockContexts(
+ pcs,
+ Av1ComponentType.Chroma,
+ cr_dc_sign_level_coeff_na,
+ RoundUv(blockOrigin + (Size)transformOrigin - (Size)blockGeometry.Origin) >> 1,
+ blockGeometry.BlockSizeUv,
+ chroma_tx_size,
+ blockContext);
+
+ int cul_level_cr = writer.WriteCoefficients(
+ chroma_tx_size,
+ chroma_tx_type,
+ intraLumaDir,
+ coeff_buffer,
+ Av1ComponentType.Chroma,
+ blockContext,
+ (ushort)endOfBlockCr,
+ frameHeader.UseReducedTransformSet,
+ blk_ptr.FilterIntraMode);
+
+ // Update the cb Dc Sign Level Coeff Neighbor Array
+ Span culLevelCbSpan = new(ref cul_level_cb);
+ ReadOnlySpan dc_sign_level_coeff = MemoryMarshal.AsBytes(culLevelCbSpan);
+ cb_dc_sign_level_coeff_na.UnitModeWrite(
+ dc_sign_level_coeff,
+ RoundUv(transformOrigin) >> 1,
+ new Size(transformWidth, transformHeight),
+ Av1NeighborArrayUnit.UnitMask.Top | Av1NeighborArrayUnit.UnitMask.Left);
+
+ // Update the cr DC Sign Level Coeff Neighbor Array
+ Span