Example #1
0
        /// Encodes the image as a raw VP8L bitstream.
        static void WriteImageBitstream(BitWriter b, Image image)
        {
            var analysis = Analysis.AnalyzeImage(image);

            WriteHeader(b, image.Width, image.Height, analysis.HasAlpha);

            if (analysis.PaletteOrNull != null)
            {
                image = Transform.PaletteTransform(b, image, analysis.PaletteOrNull);
            }
            if (analysis.UseSubtractGreen)
            {
                image = Transform.SubtractGreenTransform(b, image);
            }
            if (analysis.UsePredict)
            {
                image = Transform.PredictTransform(b, image);
            }
            b.WriteBits(0, 1);

            ImageData.WriteImageData(b, image, true, analysis.ColorCacheBits);
        }
Example #2
0
        /// Encodes the image into entropy-coded bitstream. The isRecursive flag
        /// must be true iff the data represents the main ARGB image.
        internal static void WriteImageData(BitWriter b, Image image,
                                            bool isRecursive, int colorCacheBits = 0)
        {
            if (colorCacheBits > 0)
            {
                if (colorCacheBits > 11)
                {
                    throw new ArgumentException("Too many color cache bits");
                }
                b.WriteBits(1, 1);
                b.WriteBits(colorCacheBits, 4);
            }
            else
            {
                b.WriteBits(0, 1);
            }

            if (isRecursive)
            {
                b.WriteBits(0, 1); // no meta-Huffman image
            }

            var encoded = EncodeImageData(image, colorCacheBits);
            var histos  = new List <Histogram> {
                new Histogram(256 + 24 + (colorCacheBits > 0 ? (1 << colorCacheBits) : 0)),
                new Histogram(256),
                new Histogram(256),
                new Histogram(256),
                new Histogram(40),
            };

            for (int i = 0; i < encoded.Count; ++i)
            {
                histos[0].Hit(encoded[i]);
                if (encoded[i] < 256)
                {
                    histos[1].Hit(encoded[i + 1]);
                    histos[2].Hit(encoded[i + 2]);
                    histos[3].Hit(encoded[i + 3]);
                    i += 3;
                }
                else if (encoded[i] < 256 + 24)
                {
                    histos[4].Hit(encoded[i + 2]);
                    i += 3;
                }
            }

            var codess = new List <List <Huffman.Code> >();

            for (int i = 0; i < 5; ++i)
            {
                var codes = Huffman.BuildCodes(histos[i], 16);
                CodeLengths.WriteCodeLengths(b, codes);
                codess.Add(codes);
            }

            for (int i = 0; i < encoded.Count; ++i)
            {
                b.WriteCode(codess[0][encoded[i]]);
                if (encoded[i] < 256)
                {
                    b.WriteCode(codess[1][encoded[i + 1]]);
                    b.WriteCode(codess[2][encoded[i + 2]]);
                    b.WriteCode(codess[3][encoded[i + 3]]);
                    i += 3;
                }
                else if (encoded[i] < 256 + 24)
                {
                    b.WriteBits(encoded[i + 1], ExtraBitsCount(encoded[i] - 256));
                    b.WriteCode(codess[4][encoded[i + 2]]);
                    b.WriteBits(encoded[i + 3], ExtraBitsCount(encoded[i + 2]));
                    i += 3;
                }
            }
        }