/// <summary> Called after setting data, before writing to os </summary> int ComputeCrc() { Zlib.CRC32 crcengine = PngHelperInternal.GetCRC(); crcengine.Reset(); crcengine.Update(IdBytes, 0, 4); if (Len > 0) { crcengine.Update(Data, 0, Len); } return((int)crcengine.GetValue()); }
public override void Close() => base.Close(); // nothing void EndChunkGoForNext() { // Called after readging the last byte of chunk // Checks CRC, and read ID from next CHUNK // Those values are left in idLastChunk / lenLastChunk // Skips empty IDATS do { int crc = PngHelperInternal.ReadInt4(inputStream); offset += 4; if (checkCrc) { int crccalc = (int)crcEngine.GetValue(); if (lenLastChunk > 0 && crc != crccalc) { throw new System.Exception($"error reading idat; offset: {offset}"); } crcEngine.Reset(); } lenLastChunk = PngHelperInternal.ReadInt4(inputStream); if (lenLastChunk < 0) { throw new System.IO.IOException($"invalid len for chunk: {lenLastChunk}"); } toReadThisChunk = lenLastChunk; PngHelperInternal.ReadBytes(inputStream, idLastChunk, 0, 4); offset += 8; ended = !PngCsUtils.UnSafeEquals(idLastChunk, Chunks.ChunkHelper.b_IDAT); if (!ended) { foundChunksInfo.Add(new PngIDatChunkInputStream.IdatChunkInfo(lenLastChunk, offset - 8)); if (checkCrc) { crcEngine.Update(idLastChunk, 0, 4); } } // PngHelper.logdebug("IDAT ended. next len= " + lenLastChunk + " idat?" + // (!ended)); }while(lenLastChunk == 0 && !ended); // rarely condition is true (empty IDAT ??) }
/// <summary> /// Constructor must be called just after reading length and id of first IDAT /// chunk /// </summary> public PngIDatChunkInputStream(System.IO.Stream iStream, int lenFirstChunk, long offset_0) { this.idLastChunk = new byte[4]; this.toReadThisChunk = 0; this.ended = false; this.foundChunksInfo = new System.Collections.Generic.List <IdatChunkInfo>(); this.offset = offset_0; checkCrc = true; inputStream = iStream; crcEngine = new Zlib.CRC32(); this.lenLastChunk = lenFirstChunk; toReadThisChunk = lenFirstChunk; // we know it's a IDAT System.Array.Copy(Chunks.ChunkHelper.b_IDAT, 0, idLastChunk, 0, 4); crcEngine.Update(idLastChunk, 0, 4); foundChunksInfo.Add( new PngIDatChunkInputStream.IdatChunkInfo(lenLastChunk, offset_0 - 8) ); // PngHelper.logdebug("IDAT Initial fragment: len=" + lenLastChunk); if (this.lenLastChunk == 0) { EndChunkGoForNext(); // rare, but... } }