static void RunTest(string serialized) { int seed = FeatureTestRunner.Deserialize <int>(serialized); Span <float> src = Create8x8RoundedRandomFloatData(MinAllowedValue, MaxAllowedValue, seed); var block = default(Block8x8F); block.LoadFrom(src); float[] expectedDest = new float[64]; float[] temp1 = new float[64]; // reference ReferenceImplementations.LLM_FloatingPoint_DCT.FDCT2D_llm(src, expectedDest, temp1, downscaleBy8: true); // testee // Second transpose call is done by Quantize step // Do this manually here just to be complient to the reference implementation FastFloatingPointDCT.TransformFDCT(ref block); block.TransposeInplace(); // Part of the IDCT calculations is fused into the quantization step // We must multiply input block with adjusted no-quantization matrix // after applying FDCT Block8x8F quantMatrix = CreateBlockFromScalar(1); FastFloatingPointDCT.AdjustToFDCT(ref quantMatrix); block.MultiplyInPlace(ref quantMatrix); float[] actualDest = block.ToArray(); Assert.Equal(expectedDest, actualDest, new ApproximateFloatComparer(1f)); }
static void RunTest(string serialized) { int seed = FeatureTestRunner.Deserialize <int>(serialized); Span <float> src = Create8x8RoundedRandomFloatData(-200, 200, seed); var block = default(Block8x8F); block.LoadFrom(src); float[] expectedDest = new float[64]; float[] temp1 = new float[64]; // reference ReferenceImplementations.LLM_FloatingPoint_DCT.FDCT2D_llm(src, expectedDest, temp1, downscaleBy8: true); // testee // Part of the FDCT calculations is fused into the quantization step // We must multiply transformed block with reciprocal values from FastFloatingPointDCT.ANN_DCT_reciprocalAdjustmen FastFloatingPointDCT.TransformFDCT(ref block); for (int i = 0; i < 64; i++) { block[i] = block[i] * FastFloatingPointDCT.DctReciprocalAdjustmentCoefficients[i]; } float[] actualDest = block.ToArray(); Assert.Equal(expectedDest, actualDest, new ApproximateFloatComparer(1f)); }
static void RunTest(string serialized) { int seed = FeatureTestRunner.Deserialize <int>(serialized); Span <float> src = Create8x8RoundedRandomFloatData(-200, 200, seed); var srcBlock = default(Block8x8F); srcBlock.LoadFrom(src); var destBlock = default(Block8x8F); var expectedDest = new float[64]; var temp1 = new float[64]; var temp2 = default(Block8x8F); // reference ReferenceImplementations.LLM_FloatingPoint_DCT.FDCT2D_llm(src, expectedDest, temp1, downscaleBy8: true); // testee FastFloatingPointDCT.TransformFDCT(ref srcBlock, ref destBlock, ref temp2, false); var actualDest = new float[64]; destBlock.ScaledCopyTo(actualDest); Assert.Equal(actualDest, expectedDest, new ApproximateFloatComparer(1f)); }
/// <summary> /// Writes a block of pixel data using the given quantization table, /// returning the post-quantized DC value of the DCT-transformed block. /// The block is in natural (not zig-zag) order. /// </summary> /// <param name="index">The quantization table index.</param> /// <param name="prevDC">The previous DC value.</param> /// <param name="src">Source block</param> /// <param name="tempDest1">Temporal block to be used as FDCT Destination</param> /// <param name="tempDest2">Temporal block 2</param> /// <param name="quant">Quantization table</param> /// <param name="unzigPtr">The 8x8 Unzig block pointer</param> /// <returns> /// The <see cref="int"/> /// </returns> private int WriteBlock( QuantIndex index, int prevDC, Block8x8F *src, Block8x8F *tempDest1, Block8x8F *tempDest2, Block8x8F *quant, byte *unzigPtr) { FastFloatingPointDCT.TransformFDCT(ref *src, ref *tempDest1, ref *tempDest2); Block8x8F.Quantize(tempDest1, tempDest2, quant, unzigPtr); float *unziggedDestPtr = (float *)tempDest2; int dc = (int)unziggedDestPtr[0]; // Emit the DC delta. this.EmitHuffRLE((HuffIndex)((2 * (int)index) + 0), 0, dc - prevDC); // Emit the AC components. var h = (HuffIndex)((2 * (int)index) + 1); int runLength = 0; for (int zig = 1; zig < Block8x8F.Size; zig++) { int ac = (int)unziggedDestPtr[zig]; if (ac == 0) { runLength++; } else { while (runLength > 15) { this.EmitHuff(h, 0xf0); runLength -= 16; } this.EmitHuffRLE(h, runLength, ac); runLength = 0; } } if (runLength > 0) { this.EmitHuff(h, 0x00); } return(dc); }
/// <summary> /// Writes a block of pixel data using the given quantization table, /// returning the post-quantized DC value of the DCT-transformed block. /// The block is in natural (not zig-zag) order. /// </summary> /// <param name="index">The quantization table index.</param> /// <param name="prevDC">The previous DC value.</param> /// <param name="src">Source block</param> /// <param name="tempDest1">Temporal block to be used as FDCT Destination</param> /// <param name="tempDest2">Temporal block 2</param> /// <param name="quant">Quantization table</param> /// <param name="unZig">The 8x8 Unzig block.</param> /// <param name="emitBufferBase">The reference to the emit buffer.</param> /// <returns>The <see cref="int"/>.</returns> private int WriteBlock( QuantIndex index, int prevDC, ref Block8x8F src, ref Block8x8F tempDest1, ref Block8x8F tempDest2, ref Block8x8F quant, ref ZigZag unZig, ref byte emitBufferBase) { FastFloatingPointDCT.TransformFDCT(ref src, ref tempDest1, ref tempDest2); Block8x8F.Quantize(ref tempDest1, ref tempDest2, ref quant, ref unZig); int dc = (int)tempDest2[0]; // Emit the DC delta. this.EmitHuffRLE((HuffIndex)((2 * (int)index) + 0), 0, dc - prevDC, ref emitBufferBase); // Emit the AC components. var h = (HuffIndex)((2 * (int)index) + 1); int runLength = 0; for (int zig = 1; zig < Block8x8F.Size; zig++) { int ac = (int)tempDest2[zig]; if (ac == 0) { runLength++; } else { while (runLength > 15) { this.EmitHuff(h, 0xf0, ref emitBufferBase); runLength -= 16; } this.EmitHuffRLE(h, runLength, ac, ref emitBufferBase); runLength = 0; } } if (runLength > 0) { this.EmitHuff(h, 0x00, ref emitBufferBase); } return(dc); }
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)); }