Ejemplo n.º 1
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="block">The block to write.</param>
        /// <param name="index">The quantization table index.</param>
        /// <param name="prevDC">The previous DC value.</param>
        /// <returns></returns>
        private int WriteBlock(Block block, QuantIndex index, int prevDC)
        {
            FDCT.Transform(block);

            // Emit the DC delta.
            int dc = Round(block[0], 8 * this.quant[(int)index][0]);

            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 < Block.BlockSize; zig++)
            {
                int ac = Round(block[Unzig[zig]], 8 * this.quant[(int)index][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);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Writes the descrete quantization tables.
        /// </summary>
        /// <param name="writer">The writer to write to the stream.</param>
        private void WriteDescreteQuantizationTables(EndianBinaryWriter writer)
        {
            byte[] dqt = new byte[134];

            // Write the define quantization table marker. Markers are always prefixed with with 0xff.
            dqt[0] = JpegConstants.Markers.XFF;
            dqt[1] = JpegConstants.Markers.DQT;
            dqt[2] = 0x00;
            dqt[3] = 0x84; // Length 132

            this.fdct = new FDCT(this.quality);

            int offset = 4;
            for (int i = 0; i < 2; i++)
            {
                dqt[offset++] = (byte)i;

                // TODO: Perf. Split and avoid allocation.
                int[] tempArray = this.fdct.Quantum[i];

                for (int j = 0; j < 64; j++)
                {
                    dqt[offset++] = (byte)tempArray[ZigZag.ZigZagMap[j]];
                }
            }

            writer.Write(dqt);
        }