Esempio n. 1
0
 internal void read(BigEndianBinaryReader reader)
 {
     width = reader.ReadInt32();
     height = reader.ReadInt32();
     bitdepth = reader.ReadByte();
     colortype = (ColorType)reader.ReadByte();
     method = reader.ReadByte();
     filter = reader.ReadByte();
     interlace = reader.ReadByte();
 }
Esempio n. 2
0
        void readImagedata(BigEndianBinaryReader reader, int length)
        {
            int width = ihdr.width;
            int height = ihdr.height;
            int bitDepth = ihdr.bitdepth;
            int samples = ihdr.getSamples();

            bool interlaced = ihdr.isInterlaced();

            SubInputStream sis = new SubInputStream(reader.BaseStream, length);
            InflaterInputStream iis = new InflaterInputStream(sis);
            Defilterer d = new Defilterer(iis, bitDepth, samples, width);

            //todo: interlacing
            imageOutput.start(this);
            d.defilter(0, 0, 1, 1, width, height, imageOutput);
            imageOutput.finish();
        }
Esempio n. 3
0
        void readPLTE(BigEndianBinaryReader reader, int length)
        {
            if(length == 0)
                throw new BadImageFormatException("PLTE chunk cannot be empty");
            if(length % 3 != 0)
                throw new BadImageFormatException("PLTE chunk length indivisible by 3: " + length);

            int size = length / 3;
            if(size > 256)
                throw new BadImageFormatException("Too many palette entries: " + size);

            switch (ihdr.colortype)
            {
                case ColorType.PALETTE:
                    if (size > (1 << ihdr.bitdepth))
                        throw new BadImageFormatException("Too many palette entries: " + size);
                    palette = new byte[length];
                    reader.Read(palette, 0, length);
                    break;
                default:
                    throw new BadImageFormatException("PLTE chunk found in non-palette colorformat image");
            }
        }
Esempio n. 4
0
        public void read(Stream stream, IPngImageOutput imageOutput)
        {
            this.imageOutput = imageOutput;
            CRCInputStream crcstream = new CRCInputStream(stream);
            BigEndianBinaryReader reader = new BigEndianBinaryReader(crcstream);

            //check signature
            if(!IsPng(stream))
                throw new BadImageFormatException("signature invalid");

            //sort of an inefficient way to do it, but at 3:30am itll do fine
            MemoryStream msIDAT = new MemoryStream();

            int state = 0;
            for(; ; ) {
                bool skipChunk = false;

                int chunkLen = reader.ReadInt32();
                crcstream.resetCrc();
                int chunkType = reader.ReadInt32();

                //expect an IHDR
                if(state == 0) {
                    if(chunkType != type_IHDR) throw new BadImageFormatException("did not encounter initial IHDR");
                    ihdr.read(reader);
                    //validate ihdr: do we support interlaced images for now?
                    state = 1;
                } else
                if(state == 1) {
                    switch(chunkType) {
                        case type_IEND:
                            //actually do the imagedata read now
                            msIDAT.Position = 0;
                            readImagedata(new BigEndianBinaryReader(msIDAT), (int)msIDAT.Length);
                            state = 2;
                            break;
                        case type_IHDR:
                            throw new BadImageFormatException("encountered supernumerary IHDR");
                        case type_IDAT:
                            byte[] buf = new byte[chunkLen];
                            reader.BaseStream.Read(buf, 0, chunkLen);
                            msIDAT.Write(buf, 0, chunkLen);
                            break;
                        case type_PLTE:
                            readPLTE(reader, chunkLen);
                            break;

                        default: {
                            skipChunk = true;
                            byte[] bytes = System.BitConverter.GetBytes(chunkType);
                            //debug: which chunk was skipped?
                            //Console.WriteLine("{0}{1}{2}{3}", (char)bytes[3], (char)bytes[2], (char)bytes[1], (char)bytes[0]);
                        }
                        break;
                    }
                }

                //if we skipped the chunk, skip the bytes.
                if(skipChunk) {
                    reader.BaseStream.Position += chunkLen + 4; //+4 for the crc
                } else {
                    //if we didnt skip it, do the crc validation
                    if(!skipChunk) {
                        int actualCrc = (int)crcstream.Value;
                        int targetCrc = reader.ReadInt32();
                        if(actualCrc != targetCrc)
                            throw new BadImageFormatException("Crc failure");
                    }
                }

                if(state == 2) break;
            }
        }