private 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 = Pngcs.PngHelperInternal.ReadInt4(inputStream); // offset += 4; if (checkCrc) { int crccalc = (int)crcEngine.GetValue(); if (lenLastChunk > 0 && crc != crccalc) { throw new PngjBadCrcException("error reading idat; offset: " + offset); } crcEngine.Reset(); } lenLastChunk = Pngcs.PngHelperInternal.ReadInt4(inputStream); if (lenLastChunk < 0) { throw new PngjInputException("invalid len for chunk: " + lenLastChunk); } toReadThisChunk = lenLastChunk; Pngcs.PngHelperInternal.ReadBytes(inputStream, idLastChunk, 0, 4); offset += 8; ended = !PngCsUtils.arraysEqual4(idLastChunk, Pngcs.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(Stream iStream, int lenFirstChunk, long offset_0) { this.idLastChunk = new byte[4]; this.toReadThisChunk = 0; this.ended = false; this.foundChunksInfo = new List <IdatChunkInfo>(); this.offset = offset_0; checkCrc = true; inputStream = iStream; crcEngine = new CRC32(); this.lenLastChunk = lenFirstChunk; toReadThisChunk = lenFirstChunk; // we know it's a IDAT System.Array.Copy((Array)(Pngcs.Chunks.ChunkHelper.b_IDAT), 0, (Array)(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... } }