public unsafe void CopyColorsTo() { var data = Create8x8FloatData(); Block8x8F block = new Block8x8F(); block.LoadFrom(data); block.MultiplyAllInplace(new Vector4(5, 5, 5, 5)); int stride = 256; int height = 42; int offset = height * 10 + 20; byte[] colorsExpected = new byte[stride * height]; byte[] colorsActual = new byte[stride * height]; Block8x8F temp = new Block8x8F(); ReferenceImplementations.CopyColorsTo(ref block, new MutableSpan <byte>(colorsExpected, offset), stride); block.CopyColorsTo(new MutableSpan <byte>(colorsActual, offset), stride, &temp); // Output.WriteLine("******* EXPECTED: *********"); // PrintLinearData(colorsExpected); // Output.WriteLine("******** ACTUAL: **********"); Assert.Equal(colorsExpected, colorsActual); }
public unsafe void UnzigDivRound(int seed) { Block8x8F block = new Block8x8F(); block.LoadFrom(Create8x8RandomFloatData(-2000, 2000, seed)); Block8x8F qt = new Block8x8F(); qt.LoadFrom(Create8x8RandomFloatData(-2000, 2000, seed)); UnzigData unzig = UnzigData.Create(); int *expectedResults = stackalloc int[Block8x8F.ScalarCount]; ReferenceImplementations.UnZigDivRoundRational(&block, expectedResults, &qt, unzig.Data); Block8x8F actualResults = default(Block8x8F); Block8x8F.UnzigDivRound(&block, &actualResults, &qt, unzig.Data); for (int i = 0; i < Block8x8F.ScalarCount; i++) { int expected = expectedResults[i]; int actual = (int)actualResults[i]; Assert.Equal(expected, actual); } }
public void iDCT2D8x4_RightPart() { float[] sourceArray = Create8x8FloatData(); var expectedDestArray = new float[64]; ReferenceImplementations.LLM_FloatingPoint_DCT.iDCT2D8x4_32f(sourceArray.AsSpan(4), expectedDestArray.AsSpan(4)); var source = new Block8x8F(); source.LoadFrom(sourceArray); var dest = new Block8x8F(); FastFloatingPointDCT.IDCT8x4_RightPart(ref source, ref dest); var actualDestArray = new float[64]; dest.CopyTo(actualDestArray); this.Print8x8Data(expectedDestArray); this.Output.WriteLine("**************"); this.Print8x8Data(actualDestArray); Assert.Equal(expectedDestArray, actualDestArray); }
public void IDCTInto() { float[] sourceArray = Create8x8FloatData(); float[] expectedDestArray = new float[64]; float[] tempArray = new float[64]; ReferenceImplementations.iDCT2D_llm(sourceArray, expectedDestArray, tempArray); //ReferenceImplementations.iDCT8x8_llm_sse(sourceArray, expectedDestArray, tempArray); Block8x8F source = new Block8x8F(); source.LoadFrom(sourceArray); Block8x8F dest = new Block8x8F(); Block8x8F tempBuffer = new Block8x8F(); source.TransformIDCTInto(ref dest, ref tempBuffer); float[] actualDestArray = new float[64]; dest.CopyTo(actualDestArray); Print8x8Data(expectedDestArray); Output.WriteLine("**************"); Print8x8Data(actualDestArray); Assert.Equal(expectedDestArray, actualDestArray, new ApproximateFloatComparer()); Assert.Equal(expectedDestArray, actualDestArray, new ApproximateFloatComparer()); }
public unsafe void Quantize(int seed) { var block = new Block8x8F(); block.LoadFrom(Create8x8RoundedRandomFloatData(-2000, 2000, seed)); var qt = new Block8x8F(); qt.LoadFrom(Create8x8RoundedRandomFloatData(-2000, 2000, seed)); var unzig = ZigZag.CreateUnzigTable(); int *expectedResults = stackalloc int[Block8x8F.Size]; ReferenceImplementations.QuantizeRational(&block, expectedResults, &qt, unzig.Data); var actualResults = default(Block8x8F); Block8x8F.Quantize(&block, &actualResults, &qt, unzig.Data); for (int i = 0; i < Block8x8F.Size; i++) { int expected = expectedResults[i]; int actual = (int)actualResults[i]; Assert.Equal(expected, actual); } }
public void TransformIDCT(int seed) { var sourceArray = Create8x8RandomFloatData(-200, 200, seed); float[] expectedDestArray = new float[64]; float[] tempArray = new float[64]; ReferenceImplementations.iDCT2D_llm(sourceArray, expectedDestArray, tempArray); // ReferenceImplementations.iDCT8x8_llm_sse(sourceArray, expectedDestArray, tempArray); Block8x8F source = new Block8x8F(); source.LoadFrom(sourceArray); Block8x8F dest = new Block8x8F(); Block8x8F tempBuffer = new Block8x8F(); DCT.TransformIDCT(ref source, ref dest, ref tempBuffer); float[] actualDestArray = new float[64]; dest.CopyTo(actualDestArray); this.Print8x8Data(expectedDestArray); this.Output.WriteLine("**************"); this.Print8x8Data(actualDestArray); Assert.Equal(expectedDestArray, actualDestArray, new ApproximateFloatComparer(1f)); Assert.Equal(expectedDestArray, actualDestArray, new ApproximateFloatComparer(1f)); }
public void IDCT8x8_Avx(int seed) { #if SUPPORTS_RUNTIME_INTRINSICS if (!Avx.IsSupported) { this.Output.WriteLine("No AVX present, skipping test!"); } Span <float> src = Create8x8RoundedRandomFloatData(-200, 200, seed); Block8x8F srcBlock = default; srcBlock.LoadFrom(src); Block8x8F destBlock = default; float[] expectedDest = new float[64]; // reference, left part ReferenceImplementations.LLM_FloatingPoint_DCT.IDCT2D8x4_32f(src, expectedDest); // reference, right part ReferenceImplementations.LLM_FloatingPoint_DCT.IDCT2D8x4_32f(src.Slice(4), expectedDest.AsSpan(4)); // testee, whole 8x8 FastFloatingPointDCT.IDCT8x8_Avx(ref srcBlock, ref destBlock); float[] actualDest = new float[64]; destBlock.ScaledCopyTo(actualDest); Assert.Equal(actualDest, expectedDest, new ApproximateFloatComparer(1f)); #endif }
public static Block8x8F TransformFDCT_UpscaleBy8(ref Block8x8F source) { float[] s = new float[64]; source.ScaledCopyTo(s); float[] d = new float[64]; float[] temp = new float[64]; FDCT2D_llm(s, d, temp); Block8x8F result = default; result.LoadFrom(d); return(result); }
public static Block8x8F TransformIDCT(ref Block8x8F source) { float[] s = new float[64]; source.CopyTo(s); float[] d = new float[64]; float[] temp = new float[64]; iDCT2D_llm(s, d, temp); Block8x8F result = default(Block8x8F); result.LoadFrom(d); return(result); }
public void LLM_FDCT_IsEquivalentTo_AccurateImplementation(int seed) { float[] floatData = JpegFixture.Create8x8RandomFloatData(-1000, 1000); Block8x8F source = default; source.LoadFrom(floatData); Block8x8F expected = ReferenceImplementations.AccurateDCT.TransformFDCT(ref source); Block8x8F actual = ReferenceImplementations.LLM_FloatingPoint_DCT.TransformFDCT_UpscaleBy8(ref source); actual /= 8; this.CompareBlocks(expected, actual, 1f); }
/// <summary> /// Convert raw spectral DCT data to color data and copy it to the color buffer <see cref="ColorBuffer"/>. /// </summary> public void CopyBlocksToColorBuffer(int spectralStep) { Buffer2D <Block8x8> spectralBuffer = this.component.SpectralBlocks; float maximumValue = this.frame.MaxColorChannelValue; int destAreaStride = this.ColorBuffer.Width; int yBlockStart = spectralStep * this.blockRowsPerStep; Size subSamplingDivisors = this.component.SubSamplingDivisors; Block8x8F dequantTable = this.rawJpeg.QuantizationTables[this.component.QuantizationTableIndex]; Block8x8F workspaceBlock = default; for (int y = 0; y < this.blockRowsPerStep; y++) { int yBuffer = y * this.blockAreaSize.Height; Span <float> colorBufferRow = this.ColorBuffer.DangerousGetRowSpan(yBuffer); Span <Block8x8> blockRow = spectralBuffer.DangerousGetRowSpan(yBlockStart + y); for (int xBlock = 0; xBlock < spectralBuffer.Width; xBlock++) { // Integer to float workspaceBlock.LoadFrom(ref blockRow[xBlock]); // Dequantize workspaceBlock.MultiplyInPlace(ref dequantTable); // Convert from spectral to color FastFloatingPointDCT.TransformIDCT(ref workspaceBlock); // To conform better to libjpeg we actually NEED TO loose precision here. // This is because they store blocks as Int16 between all the operations. // To be "more accurate", we need to emulate this by rounding! workspaceBlock.NormalizeColorsAndRoundInPlace(maximumValue); // Write to color buffer acording to sampling factors int xColorBufferStart = xBlock * this.blockAreaSize.Width; workspaceBlock.ScaledCopyTo( ref colorBufferRow[xColorBufferStart], destAreaStride, subSamplingDivisors.Width, subSamplingDivisors.Height); } } }
public void TransposeInto() { float[] expected = Create8x8FloatData(); ReferenceImplementations.Transpose8x8(expected); var source = new Block8x8F(); source.LoadFrom(Create8x8FloatData()); var dest = new Block8x8F(); source.TransposeInto(ref dest); float[] actual = new float[64]; dest.CopyTo(actual); Assert.Equal(expected, actual); }
public void FDCT8x4_RightPart(int seed) { Span <float> src = Create8x8RoundedRandomFloatData(-200, 200, seed); var srcBlock = new Block8x8F(); srcBlock.LoadFrom(src); var destBlock = new Block8x8F(); float[] expectedDest = new float[64]; ReferenceImplementations.LLM_FloatingPoint_DCT.fDCT2D8x4_32f(src.Slice(4), expectedDest.AsSpan(4)); FastFloatingPointDCT.FDCT8x4_RightPart(ref srcBlock, ref destBlock); float[] actualDest = new float[64]; destBlock.CopyTo(actualDest); Assert.Equal(actualDest, expectedDest, new ApproximateFloatComparer(1f)); }
public void Load_Store_FloatArray() { float[] data = new float[Block8x8F.ScalarCount]; float[] mirror = new float[Block8x8F.ScalarCount]; for (int i = 0; i < Block8x8F.ScalarCount; i++) { data[i] = i; } Measure(Times, () => { Block8x8F b = new Block8x8F(); b.LoadFrom(data); b.CopyTo(mirror); }); Assert.Equal(data, mirror); //PrintLinearData((MutableSpan<float>)mirror); }
public void FDCT_IsEquivalentTo_AccurateImplementation(int seed) { int[] data = Create8x8RandomIntData(-1000, 1000, seed); Block8x8F source = default; source.LoadFrom(data); Block8x8F expected = ReferenceImplementations.AccurateDCT.TransformFDCT(ref source); source += 128; Block8x8 temp = source.RoundAsInt16Block(); Block8x8 actual8 = ReferenceImplementations.StandardIntegerDCT.Subtract128_TransformFDCT_Upscale8(ref temp); Block8x8F actual = actual8.AsFloatBlock(); actual /= 8; this.CompareBlocks(expected, actual, 1f); }
public void FDCT8x4_RightPart(int seed) { var src = Create8x8RandomFloatData(-200, 200, seed); var srcBlock = new Block8x8F(); srcBlock.LoadFrom(src); var destBlock = new Block8x8F(); var expectedDest = new MutableSpan <float>(64); ReferenceImplementations.fDCT2D8x4_32f(src.Slice(4), expectedDest.Slice(4)); DCT.FDCT8x4_RightPart(ref srcBlock, ref destBlock); var actualDest = new MutableSpan <float>(64); destBlock.CopyTo(actualDest); Assert.Equal(actualDest.Data, expectedDest.Data, new ApproximateFloatComparer(1f)); }
public void TransformFDCT(int seed) { Span <float> src = Create8x8RoundedRandomFloatData(-200, 200, seed); var srcBlock = new Block8x8F(); srcBlock.LoadFrom(src); var destBlock = new Block8x8F(); float[] expectedDest = new float[64]; float[] temp1 = new float[64]; var temp2 = new Block8x8F(); ReferenceImplementations.LLM_FloatingPoint_DCT.fDCT2D_llm(src, expectedDest, temp1, downscaleBy8: true); FastFloatingPointDCT.TransformFDCT(ref srcBlock, ref destBlock, ref temp2, false); float[] actualDest = new float[64]; destBlock.CopyTo(actualDest); Assert.Equal(actualDest, expectedDest, new ApproximateFloatComparer(1f)); }
public void TransformFDCT(int seed) { var src = Create8x8RandomFloatData(-200, 200, seed); var srcBlock = new Block8x8F(); srcBlock.LoadFrom(src); var destBlock = new Block8x8F(); var expectedDest = new MutableSpan <float>(64); var temp1 = new MutableSpan <float>(64); var temp2 = new Block8x8F(); ReferenceImplementations.fDCT2D_llm(src, expectedDest, temp1, downscaleBy8: true); DCT.TransformFDCT(ref srcBlock, ref destBlock, ref temp2, false); var actualDest = new MutableSpan <float>(64); destBlock.CopyTo(actualDest); Assert.Equal(actualDest.Data, expectedDest.Data, new ApproximateFloatComparer(1f)); }
public void TransformByteConvetibleColorValuesInto() { Block8x8F block = new Block8x8F(); var input = Create8x8ColorCropTestData(); block.LoadFrom(input); this.Output.WriteLine("Input:"); this.PrintLinearData(input); Block8x8F dest = new Block8x8F(); block.TransformByteConvetibleColorValuesInto(ref dest); float[] array = new float[64]; dest.CopyTo(array); this.Output.WriteLine("Result:"); this.PrintLinearData(array); foreach (float val in array) { Assert.InRange(val, 0, 255); } }
public unsafe void Load_Store_FloatArray_Ptr() { float[] data = new float[Block8x8F.Size]; float[] mirror = new float[Block8x8F.Size]; for (int i = 0; i < Block8x8F.Size; i++) { data[i] = i; } this.Measure( Times, () => { var b = default(Block8x8F); Block8x8F.LoadFrom(&b, data); Block8x8F.ScaledCopyTo(&b, mirror); }); Assert.Equal(data, mirror); // PrintLinearData((Span<float>)mirror); }
public void Load_Store_FloatArray() { float[] data = new float[Block8x8F.Size]; float[] mirror = new float[Block8x8F.Size]; for (int i = 0; i < Block8x8F.Size; i++) { data[i] = i; } this.Measure( Times, () => { var b = new Block8x8F(); b.LoadFrom(data); b.CopyTo(mirror); }); Assert.Equal(data, mirror); // PrintLinearData((Span<float>)mirror); }
public void Load_Store_IntArray() { var data = new int[Block8x8F.Size]; var mirror = new int[Block8x8F.Size]; for (int i = 0; i < Block8x8F.Size; i++) { data[i] = i; } this.Measure( Times, () => { var v = new Block8x8F(); v.LoadFrom(data); v.CopyTo(mirror); }); Assert.Equal(data, mirror); // PrintLinearData((Span<int>)mirror); }
public void Load_Store_IntArray() { int[] data = new int[Block8x8F.ScalarCount]; int[] mirror = new int[Block8x8F.ScalarCount]; for (int i = 0; i < Block8x8F.ScalarCount; i++) { data[i] = i; } this.Measure( Times, () => { Block8x8F v = new Block8x8F(); v.LoadFrom(data); v.CopyTo(mirror); }); Assert.Equal(data, mirror); // PrintLinearData((MutableSpan<int>)mirror); }
public void iDCT2D8x4_LeftPart() { float[] sourceArray = Create8x8FloatData(); float[] expectedDestArray = new float[64]; ReferenceImplementations.iDCT2D8x4_32f(sourceArray, expectedDestArray); Block8x8F source = new Block8x8F(); source.LoadFrom(sourceArray); Block8x8F dest = new Block8x8F(); source.IDCT8x4_LeftPart(ref dest); float[] actualDestArray = new float[64]; dest.CopyTo(actualDestArray); Print8x8Data(expectedDestArray); Output.WriteLine("**************"); Print8x8Data(actualDestArray); Assert.Equal(expectedDestArray, actualDestArray); }
public void iDCT2D8x4_RightPart() { MutableSpan <float> sourceArray = Create8x8FloatData(); MutableSpan <float> expectedDestArray = new float[64]; ReferenceImplementations.iDCT2D8x4_32f(sourceArray.Slice(4), expectedDestArray.Slice(4)); Block8x8F source = new Block8x8F(); source.LoadFrom(sourceArray); Block8x8F dest = new Block8x8F(); DCT.IDCT8x4_RightPart(ref source, ref dest); float[] actualDestArray = new float[64]; dest.CopyTo(actualDestArray); this.Print8x8Data(expectedDestArray); this.Output.WriteLine("**************"); this.Print8x8Data(actualDestArray); Assert.Equal(expectedDestArray.Data, actualDestArray); }