1/* SPDX-License-Identifier: BSD-2-Clause */ 
2#ifndef SPNG_H 
3#define SPNG_H 
4 
5#ifdef __cplusplus 
6extern "C"
7#endif 
8 
9#define SPNG_STATIC 
10 
11#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(SPNG_STATIC) 
12 #if defined(SPNG__BUILD) 
13 #define SPNG_API __declspec(dllexport) 
14 #else 
15 #define SPNG_API __declspec(dllimport) 
16 #endif 
17#else 
18 #define SPNG_API 
19#endif 
20 
21#if defined(_MSC_VER) 
22 #define SPNG_CDECL __cdecl 
23#else 
24 #define SPNG_CDECL 
25#endif 
26 
27#include <stdlib.h> 
28#include <stdint.h> 
29#include <stdio.h> 
30 
31#define SPNG_VERSION_MAJOR 0 
32#define SPNG_VERSION_MINOR 7 
33#define SPNG_VERSION_PATCH 4 
34 
35enum spng_errno 
36
37 SPNG_IO_ERROR = -2
38 SPNG_IO_EOF = -1
39 SPNG_OK = 0
40 SPNG_EINVAL
41 SPNG_EMEM
42 SPNG_EOVERFLOW
43 SPNG_ESIGNATURE
44 SPNG_EWIDTH
45 SPNG_EHEIGHT
46 SPNG_EUSER_WIDTH
47 SPNG_EUSER_HEIGHT
48 SPNG_EBIT_DEPTH
49 SPNG_ECOLOR_TYPE
50 SPNG_ECOMPRESSION_METHOD
51 SPNG_EFILTER_METHOD
52 SPNG_EINTERLACE_METHOD
53 SPNG_EIHDR_SIZE
54 SPNG_ENOIHDR
55 SPNG_ECHUNK_POS
56 SPNG_ECHUNK_SIZE
57 SPNG_ECHUNK_CRC
58 SPNG_ECHUNK_TYPE
59 SPNG_ECHUNK_UNKNOWN_CRITICAL
60 SPNG_EDUP_PLTE
61 SPNG_EDUP_CHRM
62 SPNG_EDUP_GAMA
63 SPNG_EDUP_ICCP
64 SPNG_EDUP_SBIT
65 SPNG_EDUP_SRGB
66 SPNG_EDUP_BKGD
67 SPNG_EDUP_HIST
68 SPNG_EDUP_TRNS
69 SPNG_EDUP_PHYS
70 SPNG_EDUP_TIME
71 SPNG_EDUP_OFFS
72 SPNG_EDUP_EXIF
73 SPNG_ECHRM
74 SPNG_EPLTE_IDX
75 SPNG_ETRNS_COLOR_TYPE
76 SPNG_ETRNS_NO_PLTE
77 SPNG_EGAMA
78 SPNG_EICCP_NAME
79 SPNG_EICCP_COMPRESSION_METHOD
80 SPNG_ESBIT
81 SPNG_ESRGB
82 SPNG_ETEXT
83 SPNG_ETEXT_KEYWORD
84 SPNG_EZTXT
85 SPNG_EZTXT_COMPRESSION_METHOD
86 SPNG_EITXT
87 SPNG_EITXT_COMPRESSION_FLAG
88 SPNG_EITXT_COMPRESSION_METHOD
89 SPNG_EITXT_LANG_TAG
90 SPNG_EITXT_TRANSLATED_KEY
91 SPNG_EBKGD_NO_PLTE
92 SPNG_EBKGD_PLTE_IDX
93 SPNG_EHIST_NO_PLTE
94 SPNG_EPHYS
95 SPNG_ESPLT_NAME
96 SPNG_ESPLT_DUP_NAME
97 SPNG_ESPLT_DEPTH
98 SPNG_ETIME
99 SPNG_EOFFS
100 SPNG_EEXIF
101 SPNG_EIDAT_TOO_SHORT
102 SPNG_EIDAT_STREAM
103 SPNG_EZLIB
104 SPNG_EFILTER
105 SPNG_EBUFSIZ
106 SPNG_EIO
107 SPNG_EOF
108 SPNG_EBUF_SET
109 SPNG_EBADSTATE
110 SPNG_EFMT
111 SPNG_EFLAGS
112 SPNG_ECHUNKAVAIL
113 SPNG_ENCODE_ONLY
114 SPNG_EOI
115 SPNG_ENOPLTE
116 SPNG_ECHUNK_LIMITS
117 SPNG_EZLIB_INIT
118 SPNG_ECHUNK_STDLEN
119 SPNG_EINTERNAL
120 SPNG_ECTXTYPE
121 SPNG_ENOSRC
122 SPNG_ENODST
123 SPNG_EOPSTATE
124 SPNG_ENOTFINAL
125}; 
126 
127enum spng_text_type 
128
129 SPNG_TEXT = 1
130 SPNG_ZTXT = 2
131 SPNG_ITXT = 3 
132}; 
133 
134enum spng_color_type 
135
136 SPNG_COLOR_TYPE_GRAYSCALE = 0
137 SPNG_COLOR_TYPE_TRUECOLOR = 2
138 SPNG_COLOR_TYPE_INDEXED = 3
139 SPNG_COLOR_TYPE_GRAYSCALE_ALPHA = 4
140 SPNG_COLOR_TYPE_TRUECOLOR_ALPHA = 6 
141}; 
142 
143enum spng_filter 
144
145 SPNG_FILTER_NONE = 0
146 SPNG_FILTER_SUB = 1
147 SPNG_FILTER_UP = 2
148 SPNG_FILTER_AVERAGE = 3
149 SPNG_FILTER_PAETH = 4 
150}; 
151 
152enum spng_filter_choice 
153
154 SPNG_DISABLE_FILTERING = 0
155 SPNG_FILTER_CHOICE_NONE = 8
156 SPNG_FILTER_CHOICE_SUB = 16
157 SPNG_FILTER_CHOICE_UP = 32
158 SPNG_FILTER_CHOICE_AVG = 64
159 SPNG_FILTER_CHOICE_PAETH = 128
160 SPNG_FILTER_CHOICE_ALL = (8|16|32|64|128
161}; 
162 
163enum spng_interlace_method 
164
165 SPNG_INTERLACE_NONE = 0
166 SPNG_INTERLACE_ADAM7 = 1 
167}; 
168 
169/* Channels are always in byte-order */ 
170enum spng_format 
171
172 SPNG_FMT_RGBA8 = 1
173 SPNG_FMT_RGBA16 = 2
174 SPNG_FMT_RGB8 = 4
175 
176 /* Partially implemented, see documentation */ 
177 SPNG_FMT_GA8 = 16
178 SPNG_FMT_GA16 = 32
179 SPNG_FMT_G8 = 64
180 
181 /* No conversion or scaling */ 
182 SPNG_FMT_PNG = 256
183 SPNG_FMT_RAW = 512 /* big-endian (everything else is host-endian) */ 
184}; 
185 
186enum spng_ctx_flags 
187
188 SPNG_CTX_IGNORE_ADLER32 = 1, /* Ignore checksum in DEFLATE streams */ 
189 SPNG_CTX_ENCODER = 2 /* Create an encoder context */ 
190}; 
191 
192enum spng_decode_flags 
193
194 SPNG_DECODE_USE_TRNS = 1, /* Deprecated */ 
195 SPNG_DECODE_USE_GAMA = 2, /* Deprecated */ 
196 SPNG_DECODE_USE_SBIT = 8, /* Undocumented */ 
197 
198 SPNG_DECODE_TRNS = 1, /* Apply transparency */ 
199 SPNG_DECODE_GAMMA = 2, /* Apply gamma correction */ 
200 SPNG_DECODE_PROGRESSIVE = 256 /* Initialize for progressive reads */ 
201}; 
202 
203enum spng_crc_action 
204
205 /* Default for critical chunks */ 
206 SPNG_CRC_ERROR = 0
207 
208 /* Discard chunk, invalid for critical chunks. 
209 Since v0.6.2: default for ancillary chunks */ 
210 SPNG_CRC_DISCARD = 1
211 
212 /* Ignore and don't calculate checksum. 
213 Since v0.6.2: also ignores checksums in DEFLATE streams */ 
214 SPNG_CRC_USE = 2 
215}; 
216 
217enum spng_encode_flags 
218
219 SPNG_ENCODE_PROGRESSIVE = 1, /* Initialize for progressive writes */ 
220 SPNG_ENCODE_FINALIZE = 2, /* Finalize PNG after encoding image */ 
221}; 
222 
223struct spng_ihdr 
224
225 uint32_t width
226 uint32_t height
227 uint8_t bit_depth
228 uint8_t color_type
229 uint8_t compression_method
230 uint8_t filter_method
231 uint8_t interlace_method
232}; 
233 
234struct spng_plte_entry 
235
236 uint8_t red
237 uint8_t green
238 uint8_t blue
239 
240 uint8_t alpha; /* Reserved for internal use */ 
241}; 
242 
243struct spng_plte 
244
245 uint32_t n_entries
246 struct spng_plte_entry entries[256]; 
247}; 
248 
249struct spng_trns 
250
251 uint16_t gray
252 
253 uint16_t red
254 uint16_t green
255 uint16_t blue
256 
257 uint32_t n_type3_entries
258 uint8_t type3_alpha[256]; 
259}; 
260 
261struct spng_chrm_int 
262
263 uint32_t white_point_x
264 uint32_t white_point_y
265 uint32_t red_x
266 uint32_t red_y
267 uint32_t green_x
268 uint32_t green_y
269 uint32_t blue_x
270 uint32_t blue_y
271}; 
272 
273struct spng_chrm 
274
275 double white_point_x
276 double white_point_y
277 double red_x
278 double red_y
279 double green_x
280 double green_y
281 double blue_x
282 double blue_y
283}; 
284 
285struct spng_iccp 
286
287 char profile_name[80]; 
288 size_t profile_len
289 char *profile
290}; 
291 
292struct spng_sbit 
293
294 uint8_t grayscale_bits
295 uint8_t red_bits
296 uint8_t green_bits
297 uint8_t blue_bits
298 uint8_t alpha_bits
299}; 
300 
301struct spng_text 
302
303 char keyword[80]; 
304 int type
305 
306 size_t length
307 char *text
308 
309 uint8_t compression_flag; /* iTXt only */ 
310 uint8_t compression_method; /* iTXt, ztXt only */ 
311 char *language_tag; /* iTXt only */ 
312 char *translated_keyword; /* iTXt only */ 
313}; 
314 
315struct spng_bkgd 
316
317 uint16_t gray; /* Only for gray/gray alpha */ 
318 uint16_t red
319 uint16_t green
320 uint16_t blue
321 uint16_t plte_index; /* Only for indexed color */ 
322}; 
323 
324struct spng_hist 
325
326 uint16_t frequency[256]; 
327}; 
328 
329struct spng_phys 
330
331 uint32_t ppu_x, ppu_y
332 uint8_t unit_specifier
333}; 
334 
335struct spng_splt_entry 
336
337 uint16_t red
338 uint16_t green
339 uint16_t blue
340 uint16_t alpha
341 uint16_t frequency
342}; 
343 
344struct spng_splt 
345
346 char name[80]; 
347 uint8_t sample_depth
348 uint32_t n_entries
349 struct spng_splt_entry *entries
350}; 
351 
352struct spng_time 
353
354 uint16_t year
355 uint8_t month
356 uint8_t day
357 uint8_t hour
358 uint8_t minute
359 uint8_t second
360}; 
361 
362struct spng_offs 
363
364 int32_t x, y
365 uint8_t unit_specifier
366}; 
367 
368struct spng_exif 
369
370 size_t length
371 char *data
372}; 
373 
374struct spng_chunk 
375
376 size_t offset
377 uint32_t length
378 uint8_t type[4]; 
379 uint32_t crc
380}; 
381 
382enum spng_location 
383
384 SPNG_AFTER_IHDR = 1
385 SPNG_AFTER_PLTE = 2
386 SPNG_AFTER_IDAT = 8
387}; 
388 
389struct spng_unknown_chunk 
390
391 uint8_t type[4]; 
392 size_t length
393 void *data
394 enum spng_location location
395}; 
396 
397enum spng_option 
398
399 SPNG_KEEP_UNKNOWN_CHUNKS = 1
400 
401 SPNG_IMG_COMPRESSION_LEVEL
402 SPNG_IMG_WINDOW_BITS
403 SPNG_IMG_MEM_LEVEL
404 SPNG_IMG_COMPRESSION_STRATEGY
405 
406 SPNG_TEXT_COMPRESSION_LEVEL
407 SPNG_TEXT_WINDOW_BITS
408 SPNG_TEXT_MEM_LEVEL
409 SPNG_TEXT_COMPRESSION_STRATEGY
410 
411 SPNG_FILTER_CHOICE
412 SPNG_CHUNK_COUNT_LIMIT
413 SPNG_ENCODE_TO_BUFFER
414}; 
415 
416typedef void* SPNG_CDECL spng_malloc_fn(size_t size); 
417typedef void* SPNG_CDECL spng_realloc_fn(void* ptr, size_t size); 
418typedef void* SPNG_CDECL spng_calloc_fn(size_t count, size_t size); 
419typedef void SPNG_CDECL spng_free_fn(void* ptr); 
420 
421struct spng_alloc 
422
423 spng_malloc_fn *malloc_fn
424 spng_realloc_fn *realloc_fn
425 spng_calloc_fn *calloc_fn
426 spng_free_fn *free_fn
427}; 
428 
429struct spng_row_info 
430
431 uint32_t scanline_idx
432 uint32_t row_num; /* deinterlaced row index */ 
433 int pass
434 uint8_t filter
435}; 
436 
437typedef struct spng_ctx spng_ctx
438 
439typedef int spng_read_fn(spng_ctx *ctx, void *user, void *dest, size_t length); 
440typedef int spng_write_fn(spng_ctx *ctx, void *user, void *src, size_t length); 
441 
442typedef int spng_rw_fn(spng_ctx *ctx, void *user, void *dst_src, size_t length); 
443 
444SPNG_API spng_ctx *spng_ctx_new(int flags); 
445SPNG_API spng_ctx *spng_ctx_new2(struct spng_alloc *alloc, int flags); 
446SPNG_API void spng_ctx_free(spng_ctx *ctx); 
447 
448SPNG_API int spng_set_png_buffer(spng_ctx *ctx, const void *buf, size_t size); 
449SPNG_API int spng_set_png_stream(spng_ctx *ctx, spng_rw_fn *rw_func, void *user); 
450SPNG_API int spng_set_png_file(spng_ctx *ctx, FILE *file); 
451 
452SPNG_API void *spng_get_png_buffer(spng_ctx *ctx, size_t *len, int *error); 
453 
454SPNG_API int spng_set_image_limits(spng_ctx *ctx, uint32_t width, uint32_t height); 
455SPNG_API int spng_get_image_limits(spng_ctx *ctx, uint32_t *width, uint32_t *height); 
456 
457SPNG_API int spng_set_chunk_limits(spng_ctx *ctx, size_t chunk_size, size_t cache_size); 
458SPNG_API int spng_get_chunk_limits(spng_ctx *ctx, size_t *chunk_size, size_t *cache_size); 
459 
460SPNG_API int spng_set_crc_action(spng_ctx *ctx, int critical, int ancillary); 
461 
462SPNG_API int spng_set_option(spng_ctx *ctx, enum spng_option option, int value); 
463SPNG_API int spng_get_option(spng_ctx *ctx, enum spng_option option, int *value); 
464 
465SPNG_API int spng_decoded_image_size(spng_ctx *ctx, int fmt, size_t *len); 
466 
467/* Decode */ 
468SPNG_API int spng_decode_image(spng_ctx *ctx, void *out, size_t len, int fmt, int flags); 
469 
470/* Progressive decode */ 
471SPNG_API int spng_decode_scanline(spng_ctx *ctx, void *out, size_t len); 
472SPNG_API int spng_decode_row(spng_ctx *ctx, void *out, size_t len); 
473SPNG_API int spng_decode_chunks(spng_ctx *ctx); 
474 
475/* Encode/decode */ 
476SPNG_API int spng_get_row_info(spng_ctx *ctx, struct spng_row_info *row_info); 
477 
478/* Encode */ 
479SPNG_API int spng_encode_image(spng_ctx *ctx, const void *img, size_t len, int fmt, int flags); 
480 
481/* Progressive encode */ 
482SPNG_API int spng_encode_scanline(spng_ctx *ctx, const void *scanline, size_t len); 
483SPNG_API int spng_encode_row(spng_ctx *ctx, const void *row, size_t len); 
484SPNG_API int spng_encode_chunks(spng_ctx *ctx); 
485 
486SPNG_API int spng_get_ihdr(spng_ctx *ctx, struct spng_ihdr *ihdr); 
487SPNG_API int spng_get_plte(spng_ctx *ctx, struct spng_plte *plte); 
488SPNG_API int spng_get_trns(spng_ctx *ctx, struct spng_trns *trns); 
489SPNG_API int spng_get_chrm(spng_ctx *ctx, struct spng_chrm *chrm); 
490SPNG_API int spng_get_chrm_int(spng_ctx *ctx, struct spng_chrm_int *chrm_int); 
491SPNG_API int spng_get_gama(spng_ctx *ctx, double *gamma); 
492SPNG_API int spng_get_gama_int(spng_ctx *ctx, uint32_t *gama_int); 
493SPNG_API int spng_get_iccp(spng_ctx *ctx, struct spng_iccp *iccp); 
494SPNG_API int spng_get_sbit(spng_ctx *ctx, struct spng_sbit *sbit); 
495SPNG_API int spng_get_srgb(spng_ctx *ctx, uint8_t *rendering_intent); 
496SPNG_API int spng_get_text(spng_ctx *ctx, struct spng_text *text, uint32_t *n_text); 
497SPNG_API int spng_get_bkgd(spng_ctx *ctx, struct spng_bkgd *bkgd); 
498SPNG_API int spng_get_hist(spng_ctx *ctx, struct spng_hist *hist); 
499SPNG_API int spng_get_phys(spng_ctx *ctx, struct spng_phys *phys); 
500SPNG_API int spng_get_splt(spng_ctx *ctx, struct spng_splt *splt, uint32_t *n_splt); 
501SPNG_API int spng_get_time(spng_ctx *ctx, struct spng_time *time); 
502SPNG_API int spng_get_unknown_chunks(spng_ctx *ctx, struct spng_unknown_chunk *chunks, uint32_t *n_chunks); 
503 
504/* Official extensions */ 
505SPNG_API int spng_get_offs(spng_ctx *ctx, struct spng_offs *offs); 
506SPNG_API int spng_get_exif(spng_ctx *ctx, struct spng_exif *exif); 
507 
508 
509SPNG_API int spng_set_ihdr(spng_ctx *ctx, struct spng_ihdr *ihdr); 
510SPNG_API int spng_set_plte(spng_ctx *ctx, struct spng_plte *plte); 
511SPNG_API int spng_set_trns(spng_ctx *ctx, struct spng_trns *trns); 
512SPNG_API int spng_set_chrm(spng_ctx *ctx, struct spng_chrm *chrm); 
513SPNG_API int spng_set_chrm_int(spng_ctx *ctx, struct spng_chrm_int *chrm_int); 
514SPNG_API int spng_set_gama(spng_ctx *ctx, double gamma); 
515SPNG_API int spng_set_gama_int(spng_ctx *ctx, uint32_t gamma); 
516SPNG_API int spng_set_iccp(spng_ctx *ctx, struct spng_iccp *iccp); 
517SPNG_API int spng_set_sbit(spng_ctx *ctx, struct spng_sbit *sbit); 
518SPNG_API int spng_set_srgb(spng_ctx *ctx, uint8_t rendering_intent); 
519SPNG_API int spng_set_text(spng_ctx *ctx, struct spng_text *text, uint32_t n_text); 
520SPNG_API int spng_set_bkgd(spng_ctx *ctx, struct spng_bkgd *bkgd); 
521SPNG_API int spng_set_hist(spng_ctx *ctx, struct spng_hist *hist); 
522SPNG_API int spng_set_phys(spng_ctx *ctx, struct spng_phys *phys); 
523SPNG_API int spng_set_splt(spng_ctx *ctx, struct spng_splt *splt, uint32_t n_splt); 
524SPNG_API int spng_set_time(spng_ctx *ctx, struct spng_time *time); 
525SPNG_API int spng_set_unknown_chunks(spng_ctx *ctx, struct spng_unknown_chunk *chunks, uint32_t n_chunks); 
526 
527/* Official extensions */ 
528SPNG_API int spng_set_offs(spng_ctx *ctx, struct spng_offs *offs); 
529SPNG_API int spng_set_exif(spng_ctx *ctx, struct spng_exif *exif); 
530 
531 
532SPNG_API const char *spng_strerror(int err); 
533SPNG_API const char *spng_version_string(void); 
534 
535#ifdef __cplusplus 
536
537#endif 
538 
539#endif /* SPNG_H */ 
540