{"record":{"id":"23fbae31ff275d94","repo":"NickeManarin/ScreenToGif","slug":"missing-ihdr-chunk","errorCode":null,"errorMessage":"Missing IHDR chunk.","messagePattern":"Missing IHDR chunk\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"ScreenToGif.Util/Codification/Apng/Chunks/IhdrChunk.cs","lineNumber":37,"sourceCode":"    internal byte CompressionMethod { get; private set; }\n\n    internal byte FilterMethod { get; private set; }\n\n    internal byte InterlaceMethod { get; private set; }\n        \n    /// <summary>\n    /// Attempts to read 25 bytes of the stream.\n    /// </summary>\n    internal static IhdrChunk Read(Stream stream)\n    {\n        var chunk = new IhdrChunk\n        {\n            Length = BitHelper.ConvertEndian(stream.ReadUInt32()), //Chunk length, 4 bytes.\n            ChunkType = Encoding.ASCII.GetString(stream.ReadBytes(4)) //Chunk type, 4 bytes.\n        };\n\n        if (chunk.ChunkType != \"IHDR\")\n            throw new Exception(\"Missing IHDR chunk.\");\n\n        //var pos = stream.Position;\n        //chunk.ChunkData = stream.ReadBytes(chunk.Length);\n        //stream.Position = pos;\n\n        //Chunk details + CRC, 13 bytes + 4 bytes.\n        chunk.Width = BitHelper.ConvertEndian(stream.ReadUInt32());\n        chunk.Height = BitHelper.ConvertEndian(stream.ReadUInt32());\n        chunk.BitDepth = (byte) stream.ReadByte();\n        chunk.ColorType = (byte) stream.ReadByte();\n        chunk.CompressionMethod = (byte) stream.ReadByte();\n        chunk.FilterMethod = (byte) stream.ReadByte();\n        chunk.InterlaceMethod = (byte) stream.ReadByte();\n        chunk.Crc = BitHelper.ConvertEndian(stream.ReadUInt32());\n\n        return chunk;\n    }\n","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/NickeManarin/ScreenToGif/blob/a4d0a67c2131cd048ceec86cd40afc2f1a06f2fd/ScreenToGif.Util/Codification/Apng/Chunks/IhdrChunk.cs#L19-L55","documentation":"Thrown by IhdrChunk.Read when the chunk type string (bytes 5-8 after the 4-byte length prefix) is not 'IHDR'. Per the PNG spec, the IHDR chunk must immediately follow the 8-byte PNG signature. A mismatch means the file is malformed or the stream position is wrong.","triggerScenarios":"After reading the 8-byte PNG header successfully, the next 4 bytes decoded as ASCII do not spell 'IHDR'. This happens with truncated PNGs, files with extra bytes between the header and IHDR, or non-standard PNG-like formats.","commonSituations":"PNG file is truncated and only contains the signature. An APNG that was incorrectly assembled by the encoder. Extra metadata or bytes were prepended before the actual PNG data (e.g., in a container format). Stream position was off by a few bytes from a prior read error.","solutions":["Re-export or re-download the PNG/APNG file from the source.","Verify the stream is positioned exactly at byte offset 8 (immediately after the PNG signature) before calling IhdrChunk.Read.","Use a PNG validation tool (e.g., pngcheck) to inspect the file's chunk structure.","Handle the exception and skip/reject the frame rather than crashing the entire encoding pipeline."],"exampleFix":"// before\nif (chunk.ChunkType != \"IHDR\")\n    throw new Exception(\"Missing IHDR chunk.\");\n\n// after: include stream position and chunk type for diagnostics\nif (chunk.ChunkType != \"IHDR\")\n    throw new FormatException($\"Missing IHDR chunk. Found '{chunk.ChunkType}' at stream position {stream.Position}.\");","handlingStrategy":"validation","validationCode":"// After reading the PNG signature, peek at the chunk type\nstream.Position = 8;\nstream.ReadUInt32(); // length\nvar chunkTypeBytes = new byte[4];\nstream.Read(chunkTypeBytes, 0, 4);\nstream.Position = 8; // reset\nvar chunkType = Encoding.ASCII.GetString(chunkTypeBytes);\nif (chunkType != \"IHDR\")\n    throw new FormatException($\"Expected IHDR chunk, found '{chunkType}'\");","typeGuard":"static bool HasValidIhdr(Stream stream)\n{\n    if (stream.Length < 25) return false;\n    var pos = stream.Position;\n    stream.Position = 12; // 8 (sig) + 4 (length)\n    var type = Encoding.ASCII.GetString(stream.ReadBytes(4));\n    stream.Position = pos;\n    return type == \"IHDR\";\n}","tryCatchPattern":"try\n{\n    Ihdr = IhdrChunk.Read(InternalStream);\n}\ncatch (Exception ex) when (ex.Message.Contains(\"IHDR\"))\n{\n    LogWriter.Log(ex, \"Corrupt or invalid PNG: missing IHDR chunk\");\n    return false; // treat as non-APNG\n}","preventionTips":["Use pngcheck or a similar tool to validate PNG files before processing.","Ensure the stream hasn't been partially consumed before calling IhdrChunk.Read.","Handle the exception per-frame so one corrupt frame doesn't abort the entire encoding."],"tags":["apng","png","ihdr","binary-parsing","image-format"],"backgroundTag":null,"analyzedSha":"a4d0a67c2131cd048ceec86cd40afc2f1a06f2fd","analyzedAt":"2026-08-13T11:12:06.147Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}