Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-or-later
3 : *
4 : * This file is part of colopresso
5 : *
6 : * Copyright (C) 2025 COLOPL, Inc.
7 : *
8 : * Author: Go Kudo <g-kudo@colopl.co.jp>
9 : * Developed with AI (LLM) code assistance. See `NOTICE` for details.
10 : */
11 :
12 : #ifndef COLOPRESSO_INTERNAL_PNGX_H
13 : #define COLOPRESSO_INTERNAL_PNGX_H
14 :
15 : #include <colopresso.h>
16 :
17 : #include <assert.h>
18 : #include <stdbool.h>
19 : #include <stddef.h>
20 : #include <stdint.h>
21 :
22 : #include <png.h>
23 :
24 : #define PNGX_CHROMA_BUCKET_BITS 4
25 : #define PNGX_CHROMA_BUCKET_COUNT (PNGX_CHROMA_BUCKET_DIM * PNGX_CHROMA_BUCKET_DIM * PNGX_CHROMA_BUCKET_DIM)
26 : #define PNGX_CHROMA_BUCKET_DIM 16
27 : #define PNGX_CHROMA_BUCKET_SHIFT (8 - PNGX_CHROMA_BUCKET_BITS)
28 : #define PNGX_FULL_CHANNEL_BITS 8
29 : #define PNGX_IMPORTANCE_SCALE 65535.0f
30 : #define PNGX_LIMITED_RGBA4444_BITS 4
31 : #define PNGX_MAX_DERIVED_COLORS 48
32 : #define PNGX_PALETTE256_GRADIENT_PROFILE_DITHER_FLOOR 0.78f
33 : #define PNGX_PALETTE256_GRADIENT_PROFILE_GRADIENT_MEAN_MAX 0.16f
34 : #define PNGX_PALETTE256_GRADIENT_PROFILE_OPAQUE_RATIO_THRESHOLD 0.90f
35 : #define PNGX_PALETTE256_GRADIENT_PROFILE_SATURATION_MEAN_MAX 0.42f
36 : #define PNGX_PALETTE256_TUNE_GRADIENT_MEAN_MAX 0.14f
37 : #define PNGX_PALETTE256_TUNE_OPAQUE_RATIO_THRESHOLD 0.90f
38 : #define PNGX_PALETTE256_TUNE_QUALITY_MAX_TARGET 100
39 : #define PNGX_PALETTE256_TUNE_QUALITY_MIN_FLOOR 90
40 : #define PNGX_PALETTE256_TUNE_SATURATION_MEAN_MAX 0.35f
41 : #define PNGX_PALETTE256_TUNE_SPEED_MAX 1
42 : #define PNGX_POSTPROCESS_DISABLE_DITHER_THRESHOLD 0.25f
43 : #define PNGX_POSTPROCESS_MAX_COLOR_DISTANCE_SQ 900
44 : #define PNGX_REDUCED_ALPHA_DETAIL_WEIGHT 0.5f
45 : #define PNGX_REDUCED_ALPHA_LEVEL_LIMIT_FEW 4u
46 : #define PNGX_REDUCED_ALPHA_MIN_DITHER_FACTOR 0.04f
47 : #define PNGX_REDUCED_ALPHA_NEAR_TRANSPARENT 8u
48 : #define PNGX_REDUCED_ALPHA_OPAQUE_LIMIT 0.985f
49 : #define PNGX_REDUCED_ALPHA_RATIO_FEW 0.15f
50 : #define PNGX_REDUCED_ALPHA_RATIO_LOW 0.1f
51 : #define PNGX_REDUCED_ALPHA_RATIO_MINIMAL 0.07f
52 : #define PNGX_REDUCED_ALPHA_SIMPLE_DEFAULT_OPAQUE 1.0f
53 : #define PNGX_REDUCED_ALPHA_SIMPLE_DEFAULT_TRANSLUCENT 0.0f
54 : #define PNGX_REDUCED_ALPHA_SIMPLE_OPAQUE_RANGE 0.1f
55 : #define PNGX_REDUCED_ALPHA_SIMPLE_OPAQUE_REF 0.9f
56 : #define PNGX_REDUCED_ALPHA_SIMPLE_OPAQUE_WEIGHT 0.6f
57 : #define PNGX_REDUCED_ALPHA_SIMPLE_TRANSLUCENT_RANGE 0.12f
58 : #define PNGX_REDUCED_ALPHA_SIMPLE_TRANSLUCENT_REF 0.12f
59 : #define PNGX_REDUCED_ALPHA_SIMPLE_TRANSLUCENT_WEIGHT 0.4f
60 : #define PNGX_REDUCED_ALPHA_TRANSLUCENT_LIMIT 0.06f
61 : #define PNGX_REDUCED_HEAD_DOMINANCE_LIMIT 64
62 : #define PNGX_REDUCED_IMPORTANCE_LEVEL_FULL 232
63 : #define PNGX_REDUCED_IMPORTANCE_LEVEL_HIGH 184
64 : #define PNGX_REDUCED_IMPORTANCE_LEVEL_LOW 96
65 : #define PNGX_REDUCED_IMPORTANCE_LEVEL_MEDIUM 136
66 : #define PNGX_REDUCED_IMPORTANCE_SCALE_DENOM 255.0f
67 : #define PNGX_REDUCED_IMPORTANCE_SCALE_MIN 0.25f
68 : #define PNGX_REDUCED_IMPORTANCE_SCALE_RANGE 0.50f
69 : #define PNGX_REDUCED_IMPORTANCE_WEIGHT_BONUS_HIGH 2u
70 : #define PNGX_REDUCED_IMPORTANCE_WEIGHT_BONUS_MEDIUM 1u
71 : #define PNGX_REDUCED_IMPORTANCE_WEIGHT_BONUS_STRONG 3u
72 : #define PNGX_REDUCED_IMPORTANCE_WEIGHT_CAP 16u
73 : #define PNGX_REDUCED_IMPORTANCE_WEIGHT_SHIFT 5u
74 : #define PNGX_REDUCED_IMPORTANCE_WEIGHT_THRESHOLD_HIGH 150
75 : #define PNGX_REDUCED_IMPORTANCE_WEIGHT_THRESHOLD_MEDIUM 80
76 : #define PNGX_REDUCED_IMPORTANCE_WEIGHT_THRESHOLD_STRONG 220
77 : #define PNGX_REDUCED_LOW_WEIGHT_DIVISOR 2048u
78 : #define PNGX_REDUCED_LOW_WEIGHT_MAX 2048u
79 : #define PNGX_REDUCED_LOW_WEIGHT_MIN 32u
80 : #define PNGX_REDUCED_PASSTHROUGH_DEFAULT_GRADIENT 0.22f
81 : #define PNGX_REDUCED_PASSTHROUGH_DEFAULT_SATURATION 0.28f
82 : #define PNGX_REDUCED_PASSTHROUGH_DEFAULT_VIBRANT 0.06f
83 : #define PNGX_REDUCED_PASSTHROUGH_GRADIENT_WEIGHT 0.55f
84 : #define PNGX_REDUCED_PASSTHROUGH_RATIO_BASE 0.82f
85 : #define PNGX_REDUCED_PASSTHROUGH_RATIO_CAP 0.95f
86 : #define PNGX_REDUCED_PASSTHROUGH_RATIO_GAIN 0.10f
87 : #define PNGX_REDUCED_PASSTHROUGH_SATURATION_WEIGHT 0.30f
88 : #define PNGX_REDUCED_PASSTHROUGH_VIBRANT_WEIGHT 0.15f
89 : #define PNGX_REDUCED_PRIORITY_DETAIL_WEIGHT 0.4f
90 : #define PNGX_REDUCED_PRIORITY_MASS_WEIGHT 0.15f
91 : #define PNGX_REDUCED_PRIORITY_SPAN_WEIGHT 0.45f
92 : #define PNGX_REDUCED_RGBA32_PASSTHROUGH_GRID_DIVISOR 4
93 : #define PNGX_REDUCED_RGBA32_PASSTHROUGH_MIN_COLORS 512
94 : #define PNGX_REDUCED_ROUNDING_OFFSET 0.5f
95 : #define PNGX_REDUCED_STATS_FLAT_DEFAULT_GRADIENT 0.2f
96 : #define PNGX_REDUCED_STATS_FLAT_DEFAULT_SATURATION 0.25f
97 : #define PNGX_REDUCED_STATS_FLAT_DEFAULT_VIBRANT 0.05f
98 : #define PNGX_REDUCED_STATS_FLAT_GRADIENT_REF 0.18f
99 : #define PNGX_REDUCED_STATS_FLAT_GRADIENT_WEIGHT 0.5f
100 : #define PNGX_REDUCED_STATS_FLAT_SATURATION_REF 0.24f
101 : #define PNGX_REDUCED_STATS_FLAT_SATURATION_WEIGHT 0.35f
102 : #define PNGX_REDUCED_STATS_FLAT_VIBRANT_WEIGHT 0.15f
103 : #define PNGX_REDUCED_TARGET_ALPHA_SIMPLE_CLAMP 0.12f
104 : #define PNGX_REDUCED_TARGET_ALPHA_SIMPLE_SCALE 0.12f
105 : #define PNGX_REDUCED_TARGET_ALPHA_SIMPLE_THRESHOLD 0.1f
106 : #define PNGX_REDUCED_TARGET_BASE_MIN 512.0f
107 : #define PNGX_REDUCED_TARGET_COMBINED_CUT_BASE 0.45f
108 : #define PNGX_REDUCED_TARGET_COMBINED_CUT_CLAMP 0.28f
109 : #define PNGX_REDUCED_TARGET_DENSITY_GAP_CLAMP 0.15f
110 : #define PNGX_REDUCED_TARGET_DENSITY_GAP_SCALE 0.5f
111 : #define PNGX_REDUCED_TARGET_DENSITY_HIGH_SCALE 1.15f
112 : #define PNGX_REDUCED_TARGET_DENSITY_HIGH_THRESHOLD 0.35f
113 : #define PNGX_REDUCED_TARGET_DENSITY_LOW_SCALE 0.85f
114 : #define PNGX_REDUCED_TARGET_DENSITY_LOW_THRESHOLD 0.08f
115 : #define PNGX_REDUCED_TARGET_DENSITY_THRESHOLD 0.27f
116 : #define PNGX_REDUCED_TARGET_DETAIL_BOOST_CLAMP 0.10f
117 : #define PNGX_REDUCED_TARGET_DETAIL_BOOST_SCALE 0.25f
118 : #define PNGX_REDUCED_TARGET_DETAIL_PRESSURE_ALPHA_LIMIT 0.45f
119 : #define PNGX_REDUCED_TARGET_DETAIL_PRESSURE_BOOST 0.38f
120 : #define PNGX_REDUCED_TARGET_DETAIL_PRESSURE_DENSITY_LIMIT 0.35f
121 : #define PNGX_REDUCED_TARGET_DETAIL_PRESSURE_FLAT_LIMIT 0.32f
122 : #define PNGX_REDUCED_TARGET_DETAIL_PRESSURE_GENTLE_LIMIT 0.5f
123 : #define PNGX_REDUCED_TARGET_DETAIL_PRESSURE_HEAD_LIMIT 0.45f
124 : #define PNGX_REDUCED_TARGET_DETAIL_PRESSURE_STRONG_LIMIT 0.42f
125 : #define PNGX_REDUCED_TARGET_DETAIL_PRESSURE_TAIL_LIMIT 0.35f
126 : #define PNGX_REDUCED_TARGET_DETAIL_RELIEF_BASE 0.45f
127 : #define PNGX_REDUCED_TARGET_DETAIL_RELIEF_CLAMP 0.2f
128 : #define PNGX_REDUCED_TARGET_DETAIL_RELIEF_SCALE 0.35f
129 : #define PNGX_REDUCED_TARGET_DOMINANCE_GAIN_CLAMP 0.32f
130 : #define PNGX_REDUCED_TARGET_DOMINANCE_GAIN_SCALE 1.35f
131 : #define PNGX_REDUCED_TARGET_FLATNESS_CLAMP 0.18f
132 : #define PNGX_REDUCED_TARGET_FLATNESS_SCALE 0.18f
133 : #define PNGX_REDUCED_TARGET_FLATNESS_THRESHOLD 0.05f
134 : #define PNGX_REDUCED_TARGET_GENTLE_CLAMP 0.16f
135 : #define PNGX_REDUCED_TARGET_GENTLE_COLOR_RANGE 384.0f
136 : #define PNGX_REDUCED_TARGET_GENTLE_MAX_COLORS 1024u
137 : #define PNGX_REDUCED_TARGET_GENTLE_MIN_COLORS 640u
138 : #define PNGX_REDUCED_TARGET_GENTLE_SCALE 0.22f
139 : #define PNGX_REDUCED_TARGET_GRADIENT_RELIEF_DEFAULT 0.5f
140 : #define PNGX_REDUCED_TARGET_GRADIENT_RELIEF_REF 0.22f
141 : #define PNGX_REDUCED_TARGET_GRADIENT_RELIEF_SECONDARY_DEFAULT 0.35f
142 : #define PNGX_REDUCED_TARGET_GRADIENT_RELIEF_SECONDARY_REF 0.24f
143 : #define PNGX_REDUCED_TARGET_HEAD_CUT_BASE 0.32f
144 : #define PNGX_REDUCED_TARGET_HEAD_CUT_CLAMP 0.18f
145 : #define PNGX_REDUCED_TARGET_HEAD_CUT_RELIEF 0.28f
146 : #define PNGX_REDUCED_TARGET_HEAD_DOMINANCE_BUCKETS 48u
147 : #define PNGX_REDUCED_TARGET_HEAD_DOMINANCE_STRONG 0.58f
148 : #define PNGX_REDUCED_TARGET_HEAD_DOMINANCE_THRESHOLD 0.6f
149 : #define PNGX_REDUCED_TARGET_LOW_WEIGHT_RATIO_STRONG 0.46f
150 : #define PNGX_REDUCED_TARGET_LOW_WEIGHT_REDUCTION_BASE 0.26f
151 : #define PNGX_REDUCED_TARGET_LOW_WEIGHT_REDUCTION_CLAMP 0.18f
152 : #define PNGX_REDUCED_TARGET_LOW_WEIGHT_REDUCTION_DETAIL 0.12f
153 : #define PNGX_REDUCED_TARGET_LOW_WEIGHT_REDUCTION_START 0.38f
154 : #define PNGX_REDUCED_TARGET_RELIEF_CLAMP 0.2f
155 : #define PNGX_REDUCED_TARGET_RELIEF_GRADIENT_WEIGHT 0.65f
156 : #define PNGX_REDUCED_TARGET_RELIEF_SATURATION_WEIGHT 0.35f
157 : #define PNGX_REDUCED_TARGET_RELIEF_SCALE 0.25f
158 : #define PNGX_REDUCED_TARGET_SATURATION_RELIEF_DEFAULT 0.25f
159 : #define PNGX_REDUCED_TARGET_SATURATION_RELIEF_REF 0.3f
160 : #define PNGX_REDUCED_TARGET_TAIL_CUT_CLAMP 0.12f
161 : #define PNGX_REDUCED_TARGET_TAIL_GAIN_BASE 0.34f
162 : #define PNGX_REDUCED_TARGET_TAIL_GAIN_CLAMP 0.18f
163 : #define PNGX_REDUCED_TARGET_TAIL_GAIN_RELIEF 0.28f
164 : #define PNGX_REDUCED_TARGET_TAIL_RATIO_THRESHOLD 0.52f
165 : #define PNGX_REDUCED_TARGET_TAIL_WIDTH_BASE 0.4f
166 : #define PNGX_REDUCED_TARGET_TAIL_WIDTH_SCALE 0.65f
167 : #define PNGX_REDUCED_TARGET_UNIQUE_BASE_SCALE 12.0f
168 : #define PNGX_REDUCED_TARGET_UNIQUE_COLOR_THRESHOLD 1024u
169 : #define PNGX_REDUCED_TRIM_ALPHA_SIMPLE_CLAMP 0.08f
170 : #define PNGX_REDUCED_TRIM_ALPHA_SIMPLE_SCALE 0.08f
171 : #define PNGX_REDUCED_TRIM_ALPHA_SIMPLE_THRESHOLD 0.1f
172 : #define PNGX_REDUCED_TRIM_DENSITY_CLAMP 0.12f
173 : #define PNGX_REDUCED_TRIM_DENSITY_SCALE 0.25f
174 : #define PNGX_REDUCED_TRIM_DENSITY_THRESHOLD 0.22f
175 : #define PNGX_REDUCED_TRIM_DETAIL_PRESSURE_FLAT_LIMIT 0.42f
176 : #define PNGX_REDUCED_TRIM_DETAIL_PRESSURE_HEAD_LIMIT 0.48f
177 : #define PNGX_REDUCED_TRIM_DETAIL_PRESSURE_TAIL_LIMIT 0.52f
178 : #define PNGX_REDUCED_TRIM_FLATNESS_CLAMP 0.08f
179 : #define PNGX_REDUCED_TRIM_FLATNESS_SCALE 0.15f
180 : #define PNGX_REDUCED_TRIM_FLATNESS_THRESHOLD 0.08f
181 : #define PNGX_REDUCED_TRIM_FLATNESS_WEIGHT 0.45f
182 : #define PNGX_REDUCED_TRIM_HEAD_CLAMP 0.32f
183 : #define PNGX_REDUCED_TRIM_HEAD_DOMINANCE_THRESHOLD 0.58f
184 : #define PNGX_REDUCED_TRIM_HEAD_WEIGHT 0.55f
185 : #define PNGX_REDUCED_TRIM_MIN_COLOR_DIFF 64u
186 : #define PNGX_REDUCED_TRIM_MIN_COLOR_MARGIN 32u
187 : #define PNGX_REDUCED_TRIM_MIN_TRIGGER 0.03f
188 : #define PNGX_REDUCED_TRIM_TAIL_BASE_WEIGHT 0.4f
189 : #define PNGX_REDUCED_TRIM_TAIL_CLAMP 0.2f
190 : #define PNGX_REDUCED_TRIM_TAIL_DETAIL_WEIGHT 0.3f
191 : #define PNGX_REDUCED_TRIM_TAIL_RATIO_THRESHOLD 0.42f
192 : #define PNGX_REDUCED_TRIM_TOTAL_CLAMP 0.38f
193 : #define PNGX_REDUCED_TUNE_DEFAULT_GRADIENT 0.2f
194 : #define PNGX_REDUCED_TUNE_DEFAULT_OPAQUE 1.0f
195 : #define PNGX_REDUCED_TUNE_DEFAULT_SATURATION 0.3f
196 : #define PNGX_REDUCED_TUNE_DEFAULT_TRANSLUCENT 0.0f
197 : #define PNGX_REDUCED_TUNE_DEFAULT_VIBRANT 0.05f
198 : #define PNGX_REDUCED_TUNE_FLAT_GRADIENT_THRESHOLD 0.15f
199 : #define PNGX_REDUCED_TUNE_FLAT_SATURATION_THRESHOLD 0.28f
200 : #define PNGX_REDUCED_TUNE_FLAT_VIBRANT_THRESHOLD 0.08f
201 : #define PNGX_REDUCED_TUNE_VERY_FLAT_GRADIENT 0.08f
202 : #define PNGX_REDUCED_TUNE_VERY_FLAT_SATURATION 0.18f
203 : #define PNGX_REDUCED_VIBRANT_RATIO_LOW 0.04f
204 : #define PNGX_RGBA_CHANNELS 4
205 :
206 : #ifdef __cplusplus
207 : extern "C" {
208 : #endif
209 :
210 : typedef enum {
211 : PNGX_BRIDGE_RESULT_SUCCESS = 0,
212 : PNGX_BRIDGE_RESULT_INVALID_INPUT = 1,
213 : PNGX_BRIDGE_RESULT_OPTIMIZATION_FAILED = 2,
214 : PNGX_BRIDGE_RESULT_IO_ERROR = 3,
215 : } PngxBridgeResult;
216 :
217 : typedef enum {
218 : PNGX_BRIDGE_QUANT_STATUS_OK = 0,
219 : PNGX_BRIDGE_QUANT_STATUS_QUALITY_TOO_LOW = 1,
220 : PNGX_BRIDGE_QUANT_STATUS_ERROR = 2,
221 : } PngxBridgeQuantStatus;
222 :
223 : typedef enum {
224 : PNGX_LOSSY_TYPE_PALETTE256 = COLOPRESSO_PNGX_LOSSY_TYPE_PALETTE256,
225 : PNGX_LOSSY_TYPE_LIMITED_RGBA4444 = COLOPRESSO_PNGX_LOSSY_TYPE_LIMITED_RGBA4444,
226 : PNGX_LOSSY_TYPE_REDUCED_RGBA32 = COLOPRESSO_PNGX_LOSSY_TYPE_REDUCED_RGBA32,
227 : } pngx_lossy_type_t;
228 :
229 : typedef struct {
230 : uint8_t optimization_level;
231 : bool strip_safe;
232 : bool optimize_alpha;
233 : } PngxBridgeOptions;
234 :
235 : typedef struct {
236 : uint8_t optimization_level;
237 : bool strip_safe;
238 : bool optimize_alpha;
239 : } PngxBridgeLosslessOptions;
240 :
241 : typedef struct {
242 : int32_t speed;
243 : uint8_t quality_min;
244 : uint8_t quality_max;
245 : uint32_t max_colors;
246 : int32_t min_posterization;
247 : float dithering_level;
248 : const uint8_t *importance_map;
249 : size_t importance_map_len;
250 : const cpres_rgba_color_t *fixed_colors;
251 : size_t fixed_colors_len;
252 : bool remap;
253 : } PngxBridgeQuantParams;
254 :
255 : typedef struct {
256 : cpres_rgba_color_t *palette;
257 : size_t palette_len;
258 : uint8_t *indices;
259 : size_t indices_len;
260 : int32_t quality;
261 : } PngxBridgeQuantOutput;
262 :
263 : typedef struct {
264 : PngxBridgeOptions bridge;
265 : bool lossy_enable;
266 : uint8_t lossy_type;
267 : uint16_t lossy_max_colors;
268 : int32_t lossy_reduced_colors;
269 : uint8_t lossy_reduced_bits_rgb;
270 : uint8_t lossy_reduced_alpha_bits;
271 : uint8_t lossy_quality_min;
272 : uint8_t lossy_quality_max;
273 : uint8_t lossy_speed;
274 : float lossy_dither_level;
275 : bool lossy_dither_auto;
276 : const cpres_rgba_color_t *protected_colors;
277 : int32_t protected_colors_count;
278 : bool saliency_map_enable;
279 : bool chroma_anchor_enable;
280 : bool adaptive_dither_enable;
281 : bool gradient_boost_enable;
282 : bool chroma_weight_enable;
283 : bool postprocess_smooth_enable;
284 : float postprocess_smooth_importance_cutoff;
285 : bool palette256_gradient_profile_enable;
286 : float palette256_gradient_profile_dither_floor;
287 : bool palette256_alpha_bleed_enable;
288 : uint16_t palette256_alpha_bleed_max_distance;
289 : uint8_t palette256_alpha_bleed_opaque_threshold;
290 : uint8_t palette256_alpha_bleed_soft_limit;
291 : float palette256_profile_opaque_ratio_threshold;
292 : float palette256_profile_gradient_mean_max;
293 : float palette256_profile_saturation_mean_max;
294 : float palette256_tune_opaque_ratio_threshold;
295 : float palette256_tune_gradient_mean_max;
296 : float palette256_tune_saturation_mean_max;
297 : int16_t palette256_tune_speed_max;
298 : int16_t palette256_tune_quality_min_floor;
299 : int16_t palette256_tune_quality_max_target;
300 : } pngx_options_t;
301 :
302 : typedef struct {
303 : uint8_t *data;
304 : size_t size;
305 : size_t capacity;
306 : } png_memory_buffer_t;
307 :
308 : typedef struct {
309 : uint8_t *rgba;
310 : png_uint_32 width;
311 : png_uint_32 height;
312 : size_t pixel_count;
313 : } pngx_rgba_image_t;
314 :
315 : typedef struct {
316 : float gradient_mean;
317 : float gradient_max;
318 : float saturation_mean;
319 : float opaque_ratio;
320 : float translucent_ratio;
321 : float vibrant_ratio;
322 : } pngx_image_stats_t;
323 :
324 : typedef struct {
325 : uint8_t *importance_map;
326 : size_t importance_map_len;
327 : cpres_rgba_color_t *derived_colors;
328 : size_t derived_colors_len;
329 : cpres_rgba_color_t *combined_fixed_colors;
330 : size_t combined_fixed_len;
331 : uint8_t *bit_hint_map;
332 : size_t bit_hint_len;
333 : } pngx_quant_support_t;
334 :
335 : /* from pngx_bridge rust library */
336 : extern PngxBridgeResult pngx_bridge_optimize_lossless(const uint8_t *input_data, size_t input_size, uint8_t **output_data, size_t *output_size, const PngxBridgeLosslessOptions *options);
337 : extern PngxBridgeQuantStatus pngx_bridge_quantize(const cpres_rgba_color_t *pixels, size_t pixel_count, uint32_t width, uint32_t height, const PngxBridgeQuantParams *params,
338 : PngxBridgeQuantOutput *output);
339 : extern void pngx_bridge_free(uint8_t *ptr);
340 : extern uint32_t pngx_bridge_oxipng_version(void);
341 : extern uint32_t pngx_bridge_libimagequant_version(void);
342 : extern bool pngx_bridge_init_threads(int num_threads);
343 :
344 : #define PNGX_DEFINE_CLAMP(type) \
345 : static inline type clamp_##type(type value, type min_value, type max_value) { \
346 : assert(min_value <= max_value); \
347 : \
348 : if (value < min_value) { \
349 : return min_value; \
350 : } \
351 : \
352 : if (value > max_value) { \
353 : return max_value; \
354 : } \
355 : \
356 : return value; \
357 : }
358 :
359 24 : PNGX_DEFINE_CLAMP(int32_t);
360 24 : PNGX_DEFINE_CLAMP(uint32_t);
361 37 : PNGX_DEFINE_CLAMP(uint16_t);
362 159 : PNGX_DEFINE_CLAMP(uint8_t);
363 488 : PNGX_DEFINE_CLAMP(float);
364 :
365 : extern bool pngx_quantize_palette256(const uint8_t *png_data, size_t png_size, const pngx_options_t *opts, uint8_t **out_data, size_t *out_size, int *quant_quality);
366 : extern bool pngx_quantize_limited4444(const uint8_t *png_data, size_t png_size, const pngx_options_t *opts, uint8_t **out_data, size_t *out_size);
367 : extern bool pngx_quantize_reduced_rgba32(const uint8_t *png_data, size_t png_size, const pngx_options_t *opts, uint32_t *resolved_target, uint32_t *applied_colors, uint8_t **out_data,
368 : size_t *out_size);
369 :
370 : extern void pngx_fill_pngx_options(pngx_options_t *opts, const cpres_config_t *config);
371 : extern bool pngx_run_quantization(const uint8_t *png_data, size_t png_size, const pngx_options_t *opts, uint8_t **out_data, size_t *out_size, int *quant_quality);
372 : extern bool pngx_run_lossless_optimization(const uint8_t *png_data, size_t png_size, const pngx_options_t *opts, uint8_t **out_data, size_t *out_size);
373 : extern bool pngx_should_attempt_quantization(const pngx_options_t *opts);
374 : extern bool pngx_quantization_better(size_t baseline_size, size_t candidate_size);
375 :
376 : extern int pngx_get_last_error(void);
377 : extern void pngx_set_last_error(int error_code);
378 :
379 : #ifdef __cplusplus
380 : }
381 : #endif
382 :
383 : #endif /* COLOPRESSO_INTERNAL_PNGX_H */
|