mirror of https://github.com/SixLabors/ImageSharp
4 changed files with 1529 additions and 1 deletions
File diff suppressed because it is too large
@ -0,0 +1,256 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.Formats.Jxl.Processing.AcStrategy; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Jxl.Processing.Encoder; |
|||
|
|||
internal static class JxlAcStrategyEncoder |
|||
{ |
|||
private static readonly byte[][] TypeColors = |
|||
[ |
|||
[0xFF, 0xFF, 0x00], // DCT8 | yellow
|
|||
[0xFF, 0x80, 0x80], // HORNUSS | vivid tangerine
|
|||
[0xFF, 0x80, 0x80], // DCT2x2 | vivid tangerine
|
|||
[0xFF, 0x80, 0x80], // DCT4x4 | vivid tangerine
|
|||
[0x80, 0xFF, 0x00], // DCT16x16 | chartreuse
|
|||
[0x00, 0xC0, 0x00], // DCT32x32 | waystone green
|
|||
[0xC0, 0xFF, 0x00], // DCT16x8 | lime
|
|||
[0xC0, 0xFF, 0x00], // DCT8x16 | lime
|
|||
[0x00, 0xFF, 0x00], // DCT32x8 | green
|
|||
[0x00, 0xFF, 0x00], // DCT8x32 | green
|
|||
[0x00, 0xFF, 0x00], // DCT32x16 | green
|
|||
[0x00, 0xFF, 0x00], // DCT16x32 | green
|
|||
[0xFF, 0x80, 0x00], // DCT4x8 | orange juice
|
|||
[0xFF, 0x80, 0x00], // DCT8x4 | orange juice
|
|||
[0xFF, 0xFF, 0x80], // AFV0 | butter
|
|||
[0xFF, 0xFF, 0x80], // AFV1 | butter
|
|||
[0xFF, 0xFF, 0x80], // AFV2 | butter
|
|||
[0xFF, 0xFF, 0x80], // AFV3 | butter
|
|||
[0x00, 0xC0, 0xFF], // DCT64x64 | capri
|
|||
[0x00, 0xFF, 0xFF], // DCT64x32 | aqua
|
|||
[0x00, 0xFF, 0xFF], // DCT32x64 | aqua
|
|||
[0x00, 0x40, 0xFF], // DCT128x128 | rare blue
|
|||
[0x00, 0x80, 0xFF], // DCT128x64 | magic ink
|
|||
[0x00, 0x80, 0xFF], // DCT64x128 | magic ink
|
|||
[0x00, 0x00, 0xC0], // DCT256x256 | keese blue
|
|||
[0x00, 0x00, 0xFF], // DCT256x128 | blue
|
|||
[0x00, 0x00, 0xFF], // DCT128x256 | blue
|
|||
[0x00, 0x00, 0x00] // invalid | black
|
|||
]; |
|||
|
|||
#pragma warning disable // Indentation warnings only
|
|||
|
|||
private static readonly byte[][] Mask = |
|||
[ |
|||
[ |
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
], // DCT8
|
|||
[ |
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 1, 0, 0, 1, 0, 0, //
|
|||
0, 0, 1, 0, 0, 1, 0, 0, //
|
|||
0, 0, 1, 1, 1, 1, 0, 0, //
|
|||
0, 0, 1, 0, 0, 1, 0, 0, //
|
|||
0, 0, 1, 0, 0, 1, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
], // HORNUSS
|
|||
[ |
|||
1, 1, 1, 1, 1, 1, 1, 1, //
|
|||
1, 0, 1, 0, 1, 0, 1, 0, //
|
|||
1, 1, 1, 1, 1, 1, 1, 1, //
|
|||
1, 0, 1, 0, 1, 0, 1, 0, //
|
|||
1, 1, 1, 1, 1, 1, 1, 1, //
|
|||
1, 0, 1, 0, 1, 0, 1, 0, //
|
|||
1, 1, 1, 1, 1, 1, 1, 1, //
|
|||
1, 0, 1, 0, 1, 0, 1, 0, //
|
|||
], // 2x2
|
|||
[ |
|||
0, 0, 0, 0, 1, 0, 0, 0, //
|
|||
0, 0, 0, 0, 1, 0, 0, 0, //
|
|||
0, 0, 0, 0, 1, 0, 0, 0, //
|
|||
0, 0, 0, 0, 1, 0, 0, 0, //
|
|||
1, 1, 1, 1, 1, 1, 1, 1, //
|
|||
0, 0, 0, 0, 1, 0, 0, 0, //
|
|||
0, 0, 0, 0, 1, 0, 0, 0, //
|
|||
0, 0, 0, 0, 1, 0, 0, 0, //
|
|||
], // 4x4
|
|||
[ ], // DCT16x16 (unused)
|
|||
[ ], // DCT32x32 (unused)
|
|||
[ ], // DCT16x8 (unused)
|
|||
[ ], // DCT8x16 (unused)
|
|||
[ ], // DCT32x8 (unused)
|
|||
[ ], // DCT8x32 (unused)
|
|||
[ ], // DCT32x16 (unused)
|
|||
[ ], // DCT16x32 (unused)
|
|||
[ |
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
1, 1, 1, 1, 1, 1, 1, 1, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
], // DCT4x8
|
|||
[ |
|||
0, 0, 0, 0, 1, 0, 0, 0, //
|
|||
0, 0, 0, 0, 1, 0, 0, 0, //
|
|||
0, 0, 0, 0, 1, 0, 0, 0, //
|
|||
0, 0, 0, 0, 1, 0, 0, 0, //
|
|||
0, 0, 0, 0, 1, 0, 0, 0, //
|
|||
0, 0, 0, 0, 1, 0, 0, 0, //
|
|||
0, 0, 0, 0, 1, 0, 0, 0, //
|
|||
0, 0, 0, 0, 1, 0, 0, 0, //
|
|||
], // DCT8x4
|
|||
[ |
|||
1, 1, 1, 1, 1, 0, 0, 0, //
|
|||
1, 1, 1, 1, 0, 0, 0, 0, //
|
|||
1, 1, 1, 0, 0, 0, 0, 0, //
|
|||
1, 1, 0, 0, 0, 0, 0, 0, //
|
|||
1, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
], // AFV0
|
|||
[ |
|||
0, 0, 0, 0, 1, 1, 1, 1, //
|
|||
0, 0, 0, 0, 0, 1, 1, 1, //
|
|||
0, 0, 0, 0, 0, 0, 1, 1, //
|
|||
0, 0, 0, 0, 0, 0, 0, 1, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
], // AFV1
|
|||
[ |
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
1, 0, 0, 0, 0, 0, 0, 0, //
|
|||
1, 1, 0, 0, 0, 0, 0, 0, //
|
|||
1, 1, 1, 0, 0, 0, 0, 0, //
|
|||
1, 1, 1, 1, 0, 0, 0, 0, //
|
|||
], // AFV2
|
|||
[ |
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 0, //
|
|||
0, 0, 0, 0, 0, 0, 0, 1, //
|
|||
0, 0, 0, 0, 0, 0, 1, 1, //
|
|||
0, 0, 0, 0, 0, 1, 1, 1, //
|
|||
], // AFV3
|
|||
[ ] // invalid
|
|||
]; |
|||
|
|||
#pragma warning restore
|
|||
|
|||
public static ReadOnlySpan<byte> TypeColor(int rawStrategy) |
|||
{ |
|||
DebugGuard.IsTrue(JxlAcStrategy.IsRawStrategyValid(rawStrategy), $"Raw strategy must be a valid strategy: {rawStrategy}"); |
|||
rawStrategy = Math.Clamp(rawStrategy, 0, JxlAcStrategy.NumberOfValidStrategies); |
|||
return TypeColors[rawStrategy]; |
|||
} |
|||
|
|||
public static ReadOnlySpan<byte> TypeMask(int rawStrategy) |
|||
{ |
|||
DebugGuard.IsTrue(JxlAcStrategy.IsRawStrategyValid(rawStrategy), $"Raw strategy must be a valid strategy: {rawStrategy}"); |
|||
rawStrategy = Math.Clamp(rawStrategy, 0, JxlAcStrategy.NumberOfValidStrategies); |
|||
return Mask[rawStrategy]; |
|||
} |
|||
|
|||
public static bool MultiBlockTransformCrossesHorizontalBoundary(JxlAcStrategyImage acStrategyImage, int startX, int y, int endX) |
|||
{ |
|||
if (startX >= acStrategyImage.XSize || y >= acStrategyImage.YSize) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (y % 8 == 0) |
|||
{ |
|||
// Nothing crosses 64x64 boundaries, and the memory on the other side
|
|||
// of the 64x64 block may still uninitialized.
|
|||
return false; |
|||
} |
|||
|
|||
endX = Math.Min(endX, acStrategyImage.XSize); |
|||
|
|||
// The first multiblock might be before the start_x, let's adjust it
|
|||
// to point to the first IsFirstBlock() == true block we find by backward
|
|||
// tracing.
|
|||
JxlAcStrategyRow row = acStrategyImage.GetRow(y); |
|||
int startXLimit = startX & ~7; |
|||
|
|||
while (startX != startXLimit && !row[startX].IsFirstBlock) |
|||
{ |
|||
startX--; |
|||
} |
|||
|
|||
for (int x = startX; x < endX;) |
|||
{ |
|||
if (row[x].IsFirstBlock) |
|||
{ |
|||
x += row[x].CoveredBlocksX; |
|||
} |
|||
else |
|||
{ |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
public static bool MultiBlockTransformCrossesVerticalBoundary(JxlAcStrategyImage acStrategyImage, int x, int startY, int endY) |
|||
{ |
|||
if (x >= acStrategyImage.XSize || startY >= acStrategyImage.YSize) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (x % 8 == 0) |
|||
{ |
|||
// Nothing crosses 64x64 boundaries, and the memory on the other side
|
|||
// of the 64x64 block may still uninitialized.
|
|||
return false; |
|||
} |
|||
|
|||
endY = Math.Min(endY, acStrategyImage.YSize); |
|||
|
|||
// The first multiblock might be before the start_y, let's adjust it
|
|||
// to point to the first IsFirstBlock() == true block we find by backward
|
|||
// tracing.
|
|||
int startYLimit = startY & ~7; |
|||
while (startY != startYLimit && !acStrategyImage.GetRow(startY)[x].IsFirstBlock) |
|||
{ |
|||
startY--; |
|||
} |
|||
|
|||
for (int y = startY; y < endY;) |
|||
{ |
|||
JxlAcStrategyRow row = acStrategyImage.GetRow(y); |
|||
|
|||
if (row[x].IsFirstBlock) |
|||
{ |
|||
y += row[x].CoveredBlocksY; |
|||
} |
|||
else |
|||
{ |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue