Esempio n. 1
0
        /// <summary>
        /// Reads chunkd from input stream, adds to ChunksList, and returns it.
        /// If it's skipped, a PngChunkSkipped object is created
        /// </summary>
        /// <returns></returns>
        private AbstractPngChunk ReadChunk(byte[] chunkid, int clen, bool skipforced)
        {
            if (clen < 0)
            {
                throw new PngjInputException("invalid chunk lenght: " + clen);
            }
            // skipChunksByIdSet is created lazyly, if fist IHDR has already been read
            if (skipChunkIdsSet is null && CurrentChunkGroup > ChunksList.CHUNK_GROUP_0_IDHR)
            {
                skipChunkIdsSet = new Dictionary <string, int>();
                if (SkipChunkIds is object)
                {
                    foreach (var id in SkipChunkIds)
                    {
                        skipChunkIdsSet.Add(id, 1);
                    }
                }
            }

            var chunkidstr = ChunkHelper.ToString(chunkid);
            var critical   = ChunkHelper.IsCritical(chunkidstr);
            var skip       = skipforced;

            if (MaxTotalBytesRead > 0 && clen + offset > MaxTotalBytesRead)
            {
                throw new PngjInputException("Maximum total bytes to read exceeeded: " + MaxTotalBytesRead + " offset:"
                                             + offset + " clen=" + clen);
            }
            // an ancillary chunks can be skipped because of several reasons:
            if (CurrentChunkGroup > ChunksList.CHUNK_GROUP_0_IDHR && !ChunkHelper.IsCritical(chunkidstr))
            {
                skip = skip || (SkipChunkMaxSize > 0 && clen >= SkipChunkMaxSize) || skipChunkIdsSet.ContainsKey(chunkidstr) ||
                       (MaxBytesMetadata > 0 && clen > MaxBytesMetadata - bytesChunksLoaded) ||
                       !ChunkHelper.ShouldLoad(chunkidstr, ChunkLoadBehaviour);
            }

            AbstractPngChunk pngChunk;

            if (skip)
            {
                PngHelperInternal.SkipBytes(inputStream, clen);
                PngHelperInternal.ReadInt4(inputStream); // skip - we dont call PngHelperInternal.skipBytes(inputStream, clen + 4) for risk of overflow
                pngChunk = new PngChunkSkipped(chunkidstr, ImgInfo, clen);
            }
            else
            {
                var chunk = new ChunkRaw(clen, chunkid, true);
                _        = chunk.ReadChunkData(inputStream, critical);
                pngChunk = AbstractPngChunk.Factory(chunk, ImgInfo);
                if (!pngChunk.Crit)
                {
                    bytesChunksLoaded += chunk.Len;
                }
            }

            pngChunk.Offset = offset - 8L;
            chunksList.AppendReadChunk(pngChunk, CurrentChunkGroup);
            offset += clen + 4L;
            return(pngChunk);
        }
Esempio n. 2
0
        public PngChunk ReadChunk(byte[] chunkid, int clen, bool skipforced)
        {
            if (clen < 0)
            {
                throw new PngjInputException("invalid chunk lenght: " + clen.ToString());
            }
            if (skipChunkIdsSet == null && CurrentChunkGroup > 0)
            {
                skipChunkIdsSet = new Dictionary <string, int>();
                if (SkipChunkIds != null)
                {
                    string[] skipChunkIds = SkipChunkIds;
                    foreach (string key in skipChunkIds)
                    {
                        skipChunkIdsSet.Add(key, 1);
                    }
                }
            }
            string   text     = ChunkHelper.ToString(chunkid);
            PngChunk pngChunk = null;
            bool     flag     = ChunkHelper.IsCritical(text);
            bool     flag2    = skipforced;

            if (MaxTotalBytesRead > 0 && clen + offset > MaxTotalBytesRead)
            {
                throw new PngjInputException("Maximum total bytes to read exceeeded: " + MaxTotalBytesRead.ToString() + " offset:" + offset.ToString() + " clen=" + clen.ToString());
            }
            if (CurrentChunkGroup > 0 && !ChunkHelper.IsCritical(text))
            {
                flag2 = (flag2 || (SkipChunkMaxSize > 0 && clen >= SkipChunkMaxSize) || skipChunkIdsSet.ContainsKey(text) || (MaxBytesMetadata > 0 && clen > MaxBytesMetadata - bytesChunksLoaded) || !ChunkHelper.ShouldLoad(text, ChunkLoadBehaviour));
            }
            if (flag2)
            {
                PngHelperInternal.SkipBytes(inputStream, clen);
                PngHelperInternal.ReadInt4(inputStream);
                pngChunk = new PngChunkSkipped(text, ImgInfo, clen);
            }
            else
            {
                ChunkRaw chunkRaw = new ChunkRaw(clen, chunkid, alloc: true);
                chunkRaw.ReadChunkData(inputStream, crcEnabled | flag);
                pngChunk = PngChunk.Factory(chunkRaw, ImgInfo);
                if (!pngChunk.Crit)
                {
                    bytesChunksLoaded += chunkRaw.Length;
                }
            }
            pngChunk.Offset = offset - 8;
            chunksList.AppendReadChunk(pngChunk, CurrentChunkGroup);
            offset += (long)clen + 4L;
            return(pngChunk);
        }