Пример #1
0
        public void defilter(int xOffset, int yOffset,
								int xStep, int yStep,
								int passWidth, int passHeight, IPngImageOutput output)
        {
            if (passWidth == 0 || passHeight == 0)
            return;

            int bytesPerRow = (bitDepth * samples * passWidth + 7) / 8;
            bool isShort = bitDepth == 16;

            int rowSize = bytesPerRow + bpp;
            byte[] prev = new byte[rowSize];
            byte[] cur = new byte[rowSize];

            for (int srcY = 0, dstY = yOffset; srcY < passHeight; srcY++, dstY += yStep) {
            int filterType = stream.ReadByte();
            if(filterType == -1)
                throw new EndOfStreamException();
            fillBuffer(cur, bpp, bytesPerRow);
            defilter(cur, prev, bpp, filterType);
            output.writeLine(cur, bpp);

            byte[] tmp = cur;
            cur = prev;
            prev = tmp;
            }
        }
Пример #2
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;
            }
        }