Skip to content

Commit 573f2db

Browse files
authored
Expand decoder docs (#163) [skip-ci]
1 parent 24110bb commit 573f2db

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

docs/decode.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,82 @@ enum spng_decode_flags
6464

6565
The `SPNG_DECODE_PROGRESSIVE` flag is supported in all cases.
6666

67+
# Error handling
68+
69+
Decoding errors are divided into critical and non-critical errors.
70+
71+
See also: [General error handling](errors.md)
72+
73+
Critical errors are not recoverable, it should be assumed that decoding has
74+
failed completely and any partial image output is invalid, although corrupted
75+
PNG's may appear to decode to the same partial image every time this cannot be guaranteed.
76+
77+
A critical error will stop any further parsing, invalidate the context and return the
78+
relevant error code, most functions check for a valid context state and return
79+
`SPNG_EBADSTATE` for subsequent calls to prevent undefined behavior.
80+
It is strongly recommended to check all return values.
81+
82+
Non-critical errors in a decoding context refers to file corruption issues
83+
that can be handled in a deterministic manner either by ignoring checksums
84+
or discarding invalid chunks.
85+
The image is extracted consistently but may have lost color accuracy,
86+
transparency, etc.
87+
88+
The default behavior is meant to emulate libpng for compatibility reasons
89+
with existing images in the wild, most non-critical errors are ignored.
90+
Configuring decoder strictness is currently limited to checksums.
91+
92+
* Invalid palette indices are handled as black, opaque pixels
93+
* `tEXt`, `zTXt` chunks with non-Latin characters are considered valid
94+
* Non-critical chunks are discarded if the:
95+
* Chunk CRC is invalid (`SPNG_CRC_DISCARD` is the default for ancillary chunks)
96+
* Chunk has an invalid DEFLATE stream, by default this includes Adler-32 checksum errors
97+
* Chunk has errors specific to the chunk type: unexpected length, out-of-range values, etc
98+
* Critical chunks with either chunk CRC or Adler-32 errors will stop parsing (unless configured otherwise)
99+
* Extra trailing image data is silently discarded
100+
* No parsing or validation is done past the `IEND` end-of-file marker
101+
102+
Truncated PNG's and truncated image data is always handled as a critical error,
103+
getting a partial image is possible with progressive decoding but is not
104+
guaranteed to work in all cases. The decoder issues read callbacks that
105+
can span multiple rows or even the whole image, partial reads are not processed.
106+
107+
Some limitations apply, spng will stop decoding if:
108+
109+
* An image row is larger than 4 GB
110+
* Something causes arithmetic overflow (limited to extreme cases on 32-bit)
111+
112+
## Checksums
113+
114+
There are two types of checksums used in PNG's: 32-bit CRC's for chunk data and Adler-32
115+
in DEFLATE streams.
116+
117+
Creating a context with the `SPNG_CTX_IGNORE_ADLER32` flag will cause Adler-32
118+
checksums to be ignored by zlib, both in compressed metadata and image data.
119+
Note this is only supported with zlib >= 1.2.11 and is not available when compiled against miniz.
120+
121+
Chunk CRC handling is configured with `spng_set_crc_action()`,
122+
when `SPNG_CRC_USE` is used for either chunk types the Adler-32 checksums in DEFLATE streams
123+
will be also ignored.
124+
When set for both chunk types it has the same effect as `SPNG_CTX_IGNORE_ADLER32`,
125+
this does not apply vice-versa.
126+
127+
Currently there are no distinctions made between Adler-32 checksum- and other errors
128+
in DEFLATE streams, they're all mapped to the `SPNG_EZLIB` error code.
129+
130+
The libpng equivalent of `spng_set_crc_action()` is `png_set_crc_action()`,
131+
it implements a subset of its features:
132+
133+
| libpng | spng | Notes |
134+
|------------------------|--------------------|-------------------------|
135+
| `PNG_CRC_ERROR_QUIT` | `SPNG_CRC_ERROR` | Will not abort on error |
136+
| `PNG_CRC_WARN_DISCARD` | `SPNG_CRC_DISCARD` | No warning system |
137+
| `PNG_CRC_QUIET_USE` | `SPNG_CRC_USE` | |
138+
139+
140+
The `SPNG_CTX_IGNORE_ADLER32` context flag has the same effect as `PNG_IGNORE_ADLER32`
141+
used with `png_set_option()`.
142+
67143
# API
68144

69145
# spng_set_png_buffer()

0 commit comments

Comments
 (0)