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

            string   chunkidstr = ChunkHelper.ToString(chunkid);
            PngChunk pngChunk   = null;
            bool     critical   = ChunkHelper.IsCritical(chunkidstr);
            bool     skip       = skipforced;

            if (MaxTotalBytesRead > 0 && clen + offset > MaxTotalBytesRead)
            {
                throw new IO.IOException($"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);
            }

            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
            {
                ChunkRaw chunk = new ChunkRaw(clen, chunkid, true);
                chunk.ReadChunkData(inputStream, crcEnabled || critical);
                pngChunk = PngChunk.Factory(chunk, ImgInfo);
                if (!pngChunk.Crit)
                {
                    bytesChunksLoaded += chunk.Len;
                }
            }
            pngChunk.Offset = offset - 8L;
            chunksList.AppendReadChunk(pngChunk, CurrentChunkGroup);
            offset += clen + 4L;
            return(pngChunk);
        }
Exemple #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);
        }