// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using SixLabors.ImageSharp.Formats.Jpeg.Components; // ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils; /// /// This class contains simplified (inefficient) reference implementations to produce verification data for unit tests /// Floating point DCT code Ported from https://github.com/norishigefukushima/dct_simd /// internal static partial class ReferenceImplementations { public static void DequantizeBlock(ref Block8x8F block, ref Block8x8F qt, ReadOnlySpan zigzag) { for (int i = 0; i < Block8x8F.Size; i++) { int zig = zigzag[i]; block[zig] *= qt[i]; } } /// /// Transpose 8x8 block stored linearly in a (inplace) /// internal static void Transpose8x8(Span data) { for (int i = 1; i < 8; i++) { int i8 = i * 8; for (int j = 0; j < i; j++) { float tmp = data[i8 + j]; data[i8 + j] = data[(j * 8) + i]; data[(j * 8) + i] = tmp; } } } /// /// Transpose 8x8 block stored linearly in a (inplace) /// internal static void Transpose8x8(Span data) { for (int i = 1; i < 8; i++) { int i8 = i * 8; for (int j = 0; j < i; j++) { short tmp = data[i8 + j]; data[i8 + j] = data[(j * 8) + i]; data[(j * 8) + i] = tmp; } } } /// /// Transpose 8x8 block stored linearly in a /// internal static void Transpose8x8(Span src, Span dest) { for (int i = 0; i < 8; i++) { int i8 = i * 8; for (int j = 0; j < 8; j++) { dest[(j * 8) + i] = src[i8 + j]; } } } /// /// Copies color values from block to the destination image buffer. /// internal static unsafe void CopyColorsTo(ref Block8x8F block, Span buffer, int stride) { fixed (Block8x8F* p = &block) { float* b = (float*)p; for (int y = 0; y < 8; y++) { int y8 = y * 8; int yStride = y * stride; for (int x = 0; x < 8; x++) { float c = b[y8 + x]; if (c < -128) { c = 0; } else if (c > 127) { c = 255; } else { c += 128; } buffer[yStride + x] = (byte)c; } } } } /// /// Reference implementation to test . /// /// The input block. /// The destination block of 16bit integers. /// The quantization table. /// Zig-Zag index sequence span. public static void Quantize(ref Block8x8F src, ref Block8x8 dest, ref Block8x8F qt, ReadOnlySpan zigzag) { for (int i = 0; i < Block8x8F.Size; i++) { int zig = zigzag[i]; dest[i] = (short)Math.Round(src[zig] / qt[zig], MidpointRounding.AwayFromZero); } } }