コード例 #1
0
ファイル: DCTTests.cs プロジェクト: SixLabors/ImageSharp
                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));
                }
コード例 #2
0
                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));
                }
コード例 #3
0
                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));
                }
コード例 #4
0
        /// <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);
        }
コード例 #5
0
        /// <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);
        }
コード例 #6
0
            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));
            }