/// <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); }
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); }