private PngChunk 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 == 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 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);
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;
}