Пример #1
0
        public Gdk.Pixbuf GetPixbuf()
        {
            ChunkInflater ci = new ChunkInflater ();
            Chunk palette = null;
            Chunk transparent = null;

            foreach (Chunk chunk in Chunks) {
                if (chunk.Name == "IDAT")
                    ci.Add (chunk);
                else if (chunk.Name == "PLTE")
                    palette = chunk;
                else if (chunk.Name == "tRNS")
                    transparent = chunk;
            }

            IhdrChunk ihdr = (IhdrChunk) Chunks [0];
            System.Console.WriteLine ("Attempting to to inflate photo {0}.{1}({2}, {3})", ihdr.Color, ihdr.Depth, ihdr.Width, ihdr.Height);
            ScanlineDecoder decoder = new ScanlineDecoder (ci, ihdr.GetScanlineLength (0), ihdr.Height);
            decoder.Fill ();
            //Gdk.Pixbuf pixbuf = decoder.GetPixbuf ();

            //System.Console.WriteLine ("XXXXXXXXXXXXXXXXXXXXXXXXXXX Inflate ############################");

            bool alpha = (ihdr.Color == ColorType.GrayAlpha || ihdr.Color == ColorType.RgbA || transparent != null);

            Gdk.Pixbuf pixbuf = new Gdk.Pixbuf (Gdk.Colorspace.Rgb,
                                alpha, 8, (int)ihdr.Width, (int)ihdr.Height);

            for (int line = 0; line < ihdr.Height; line++) {
                switch (ihdr.Color) {
                case ColorType.Rgb:
                    if (ihdr.Depth == 16) {
                        decoder.ReconstructRow (line, 6);
                        decoder.UnpackRGB16Line (pixbuf, line, 3);
                    } else {
                        decoder.ReconstructRow (line, 3);
                        decoder.UnpackRGB8Line (pixbuf, line, 3);
                    }
                    break;
                case ColorType.RgbA:
                    if (ihdr.Depth == 16) {
                        decoder.ReconstructRow (line, 8);
                        decoder.UnpackRGB16Line (pixbuf, line, 4);
                    } else {
                        decoder.ReconstructRow (line, 4);
                        decoder.UnpackRGB8Line (pixbuf, line, 4);
                    }
                    break;
                case ColorType.GrayAlpha:
                    switch (ihdr.Depth) {
                    case 16:
                        decoder.ReconstructRow (line, 4);
                        decoder.UnpackGray16Line (pixbuf, line, true);
                        break;
                    default:
                        decoder.ReconstructRow (line, 2);
                        decoder.UnpackGrayLine (pixbuf, line, ihdr.Depth, true);
                        break;
                    }
                    break;
                case ColorType.Gray:
                    switch (ihdr.Depth) {
                    case 16:
                        decoder.ReconstructRow (line, 2);
                        decoder.UnpackGray16Line (pixbuf, line, false);
                        break;
                    default:
                        decoder.ReconstructRow (line, 1);
                        decoder.UnpackGrayLine (pixbuf, line, ihdr.Depth, false);
                        break;
                    }
                    break;
                case ColorType.Indexed:
                    decoder.ReconstructRow (line, 1);
                    decoder.UnpackRGBIndexedLine (pixbuf,
                                      line,
                                      ihdr.Depth,
                                      palette.Data,
                                      transparent != null ? transparent.Data : null);
                    break;
                default:
                    throw new System.Exception (System.String.Format ("unhandled color type {0}", ihdr.Color));
                }
            }
            return pixbuf;
        }
Пример #2
0
            public ScanlineDecoder(ChunkInflater inflater, uint width, uint height)
            {
                this.inflater = inflater;
                this.row = 0;
                this.height = (int)height;
                this.width = (int)width;

                buffer = new byte [width * height];

                Fill ();
            }