How a PNG is put together
A PNG opens with an eight-byte signature, a fixed fingerprint that lets any program confirm the file really is a PNG. Everything after it is a series of chunks, and each chunk is a tidy little package: a length, a four-letter type, the data itself, and a four-byte checksum.
Three chunk types carry the whole image. IHDR comes first and stores the essentials: width, height, bit depth, and color type. IDAT holds the compressed image data, sometimes split across several IDAT chunks in a row. IEND is a tiny end marker that says the file is complete. Inside the IDAT chunks, the pixels are compressed with deflate, the same algorithm ZIP uses, one continuous stream from the top row of the image to the bottom.
A PNG, front to back: a signature, a header with the dimensions, the compressed image data, and an end marker.
The detail that makes PNG special is the checksum on every chunk. It is a CRC-32, computed over the chunk's type and data, and it turns the format into something that constantly audits itself. That is why a PNG can point to its own damage with a precision most formats can't manage.
The damage a PNG can shrug off
Because each chunk is self-checking and self-describing, a whole category of PNG damage has a clean, deterministic fix: the correct answer is knowable, not guessed.
A wrong checksum, right data
The gentlest case: a chunk's data is fine but its stored CRC no longer matches, so strict decoders reject the file. Recomputing the CRC from the data and writing it back makes the file valid again with zero loss. The checksum was the only thing wrong.
Zeroed or wrong dimensions
If the width or height in IHDR gets zeroed or scrambled, no decoder can set up a canvas and the file won't open. But IHDR carries its own CRC, computed back when the dimensions were correct. That lets a repair tool brute-force the answer: try candidate width and height values, recompute the checksum for each, and stop when it matches the stored CRC. The original dimensions fall straight out of the math, no guessing involved.
Newlines mangled in transfer
A classic: a PNG sent through a system that "helpfully" converts line endings, an old FTP client in text mode, or a script that rewrote the file as text. It swaps every carriage-return-and-line-feed pair for a lone line feed, or the reverse, corrupting bytes throughout. The PNG signature itself is designed to catch exactly this, and when the mangling is a consistent, reversible substitution, the transform can be undone and the original bytes restored.
Truncation: the top rows come back
Truncation is the most common way PNGs break: a download that stopped at 80 percent, a copy interrupted when a drive was pulled, a file saved by a program that crashed mid-write. The front of the file is intact and the tail is simply absent, usually including the IEND marker, which is why so many viewers complain the file is incomplete.
A truncated PNG: the header and the top of the image data survived; the rest of the stream and the end marker never arrived.
Because the image is written top to bottom, a truncated PNG salvages into the upper part of the picture: real pixels, down to the point where the data ends. A repair rewrites a valid end so a decoder will accept the file and draw what survived. The rows below the cut are not damaged, they are absent, so they cannot be returned. This is an honest partial, the same shape of result a truncated JPEG gives on the photo repair side.
Mid-stream damage: why the rows below are gone
Damage that lands in the middle of the IDAT data, rather than at the end, is the hard case, and the reason is deflate. Deflate compresses the image as one continuous stream where each part depends on what came before it. It has no periodic markers to resynchronize on, so once the decoder hits a corrupted byte, it loses the thread and cannot recover it. Everything after the damage decodes as noise.
In practice that means a single bad byte partway down can cost you every row beneath it, not just one line. The picture is clean above the hit and garbage below it. A repair can still salvage the rows that decoded before the damage, which is genuinely worth having, but it cannot stitch the stream back together past the break. Compare this with formats that store an index separately from their data: there, rebuilding the index can rescue the whole thing. PNG keeps its pixels in one indivisible deflate stream, so a mid-stream wound is permanent below the cut.
What's recoverable, in one honest list
Sort your broken PNG into one of these and you know the prognosis before you spend any effort:
- Checksum mismatch, data intact. Deterministic fix, no loss. Recompute the CRC and the file is valid again.
- Zeroed or scrambled dimensions. Deterministic fix in most cases. The stored IHDR checksum reveals the original size.
- Newline mangling from transfer. Reversible when the substitution was consistent. Undo the transform, restore the bytes.
- Truncated file. Partial. The top of the image comes back; the missing tail does not.
- Mid-stream IDAT corruption. Partial at best. Clean above the damage, gone below it, because deflate can't resync.
- Zero bytes or all zeros. Not a repair case. There is no image in the file to rebuild; that is a recovery problem.
PNG repair sits alongside the other format tools in the repair tool index. Whichever bucket your file lands in, a good tool tells you the truth about it rather than promising the grey rows back.
FAQ
Why won't my PNG open?
Usually one of three things: the eight-byte signature at the very front is damaged, so viewers don't recognize the file as a PNG at all; the header chunk (IHDR) that stores the image dimensions is wrong or zeroed, so a decoder can't set up a canvas; or the compressed image data was truncated or corrupted partway. The first two are often deterministic fixes because PNG stores a checksum for every chunk. The third is where the honest limits begin: whatever image rows were not in the file cannot be brought back.
What does a PNG CRC error mean?
Every chunk in a PNG ends with a four-byte CRC-32 checksum computed over that chunk's type and data. When a decoder recomputes the checksum and it doesn't match the stored value, it reports a CRC error, which means the bytes in that chunk changed since the file was written. If only the checksum itself is wrong and the data is fine, recomputing it fixes the file outright. If the data changed, the CRC is doing its job by warning you, and how recoverable the image is depends on which chunk was hit.
Can a truncated PNG be recovered?
Partially, and only the top. PNG compresses its image with deflate and writes the rows from top to bottom, so a file that was cut short decodes cleanly down to the point where the data ends, then stops. You get the upper portion of the image back as real pixels. The rows below the cut were never in the file, so no tool can restore them. A repaired truncated PNG is an honest partial: your real image, as far down as the bytes go.
Why is the bottom of my PNG missing or garbled?
Because deflate, the compression PNG uses, is a continuous stream with no way to resynchronize after damage. If the corruption lands in the middle of the image data rather than at the end, the decoder loses the thread at that byte and everything after it decodes as noise, not just the single damaged row. That is why mid-stream damage typically costs you every row below the hit, while clean truncation at least leaves the top intact.
A photo that opens to a grey lower half has a close cousin in the JPEG world: why half your JPEG is grey.