public int WriteResidualBlock(int[] coeffLevel, int[] coeffRun, ResidualBlockInfo residualBlock)
 {
     return entropyOutputStream.WriteResidualBlock(coeffLevel, coeffRun, residualBlock);
 }
        private int ForwardTransform(int[][] mrSrc, int[][] m4Dst, int[][] mrDst)
        {
            const int maxNumDcCoeff = 16;
            const int maxNumAcCoeff = 15;
            var acCoeff = 0;

            for (var blockY = 0; blockY < mbHeight; blockY += 4)
                for (var blockX = 0; blockX < mbWidth; blockX += 4)
                    transform.Forward4X4(mrSrc, mrDst, blockY, blockX);

            for (var j = 0; j < dcHeight; j++)
                for (var i = 0; i < dcWidth; i++)
                    m4Dst[j][i] = mrDst[j << 2][i << 2];

            transform.Hadamard4X4(m4Dst, m4Dst);
            var nonZeroCoeff = quantizer.Quantization4X4DC(m4Dst, m4Dst);
            var blockInfo = new ResidualBlockInfo(ResidualBlockType.Intra16X16LumaDCLevel, maxNumDcCoeff, nonZeroCoeff);
            info.LumaDcBlockInfo = blockInfo;

            for (var blockY = 0; blockY < mbHeight; blockY += 4)
            {
                for (var blockX = 0; blockX < mbHeight; blockX += 4)
                {
                    nonZeroCoeff = quantizer.Quantization4X4AC(mrDst, mrDst, blockY, blockX);
                    blockInfo = new ResidualBlockInfo(ResidualBlockType.Intra16X16LumaACLevel, maxNumAcCoeff,
                                                      nonZeroCoeff);
                    info.SetLumaAcBlockInfo(blockX >> 2, blockY >> 2, blockInfo);
                    if (nonZeroCoeff > 0)
                        acCoeff = 15;
                }
            }
            return acCoeff;
        }