colopresso 12.2.0__cp310-abi3-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,669 @@
1
+ Metadata-Version: 2.4
2
+ Name: colopresso
3
+ Version: 12.2.0
4
+ Summary: PNG conversion and compression library
5
+ Author: COLOPL, Inc.
6
+ License-Expression: GPL-3.0-or-later
7
+ Classifier: Development Status :: 5 - Production/Stable
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Operating System :: POSIX :: Linux
10
+ Classifier: Operating System :: MacOS
11
+ Classifier: Operating System :: Microsoft :: Windows
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Multimedia :: Graphics :: Graphics Conversion
18
+ Requires-Python: >=3.10
19
+ Provides-Extra: dev
20
+ Requires-Dist: pytest>=8.0; extra == "dev"
21
+ Requires-Dist: pillow>=10.0; extra == "dev"
22
+ Description-Content-Type: text/markdown
23
+
24
+ # Colopresso Python Bindings
25
+
26
+ Python bindings for the colopresso image compression library. Encode PNG images to WebP, AVIF, or optimized PNG (PNGX) formats.
27
+
28
+ ## Table of Contents
29
+
30
+ - [Requirements](#requirements)
31
+ - [Installation](#installation)
32
+ - [Quick Start](#quick-start)
33
+ - [API Reference](#api-reference)
34
+ - [Encoding Functions](#encoding-functions)
35
+ - [Config Class](#config-class)
36
+ - [PngxLossyType Enum](#pngxlossytype-enum)
37
+ - [Configuration Parameters](#configuration-parameters)
38
+ - [Utility Functions](#utility-functions)
39
+ - [Exception Classes](#exception-classes)
40
+ - [Examples](#examples)
41
+ - [Building Wheels](#building-wheels)
42
+
43
+ ## Requirements
44
+
45
+ > [!IMPORTANT]
46
+ > **AVX2 instruction set support is required on x86_64 (amd64) platforms.**
47
+ > Intel Haswell (2013) or later, or AMD Excavator or later processors are required.
48
+
49
+ | Platform | Architecture | Requirements |
50
+ |----------|--------------|--------------|
51
+ | Windows | x64 | AVX2 support |
52
+ | Windows | ARM64 | NEON (ASIMD) |
53
+ | macOS | x86_64 | AVX2 support |
54
+ | macOS | arm64 (Apple Silicon) | NEON (ASIMD) |
55
+ | Linux (glibc) | x86_64 | AVX2 support |
56
+ | Linux (glibc) | aarch64 | NEON (ASIMD) |
57
+ | Linux (musl) | x86_64 | AVX2 support |
58
+ | Linux (musl) | aarch64 | NEON (ASIMD) |
59
+
60
+ ## Installation
61
+
62
+ ### From PyPI
63
+
64
+ ```bash
65
+ pip install "colopresso"
66
+ ```
67
+
68
+ ### From source (requires CMake, Rust, and C compiler)
69
+
70
+ ```bash
71
+ cd python
72
+ pip install .
73
+ ```
74
+
75
+ ### Development installation
76
+
77
+ ```bash
78
+ cd python
79
+ pip install -e ".[dev]"
80
+ ```
81
+
82
+ ## Quick Start
83
+
84
+ ```python
85
+ import colopresso
86
+
87
+ # Read PNG file
88
+ with open("input.png", "rb") as f:
89
+ png_data = f.read()
90
+
91
+ # Convert to WebP
92
+ webp_data = colopresso.encode_webp(png_data)
93
+ with open("output.webp", "wb") as f:
94
+ f.write(webp_data)
95
+
96
+ # Convert to AVIF
97
+ avif_data = colopresso.encode_avif(png_data)
98
+ with open("output.avif", "wb") as f:
99
+ f.write(avif_data)
100
+
101
+ # Optimize PNG
102
+ optimized_png = colopresso.encode_pngx(png_data)
103
+ with open("output.png", "wb") as f:
104
+ f.write(optimized_png)
105
+ ```
106
+
107
+ ---
108
+
109
+ ## API Reference
110
+
111
+ ### Encoding Functions
112
+
113
+ #### `encode_webp(png_data, config=None) -> bytes`
114
+
115
+ Encode PNG data to WebP format.
116
+
117
+ **Parameters:**
118
+ - `png_data` (bytes): Raw PNG file data
119
+ - `config` (Config, optional): Encoding configuration. Uses defaults if not provided.
120
+
121
+ **Returns:**
122
+ - bytes: WebP encoded data
123
+
124
+ **Raises:**
125
+ - `ColopressoError`: If encoding fails
126
+
127
+ **Example:**
128
+ ```python
129
+ import colopresso
130
+
131
+ with open("input.png", "rb") as f:
132
+ png_data = f.read()
133
+
134
+ # Default settings
135
+ webp_data = colopresso.encode_webp(png_data)
136
+
137
+ # Custom quality
138
+ config = colopresso.Config(webp_quality=90.0)
139
+ webp_data = colopresso.encode_webp(png_data, config)
140
+ ```
141
+
142
+ ---
143
+
144
+ #### `encode_avif(png_data, config=None) -> bytes`
145
+
146
+ Encode PNG data to AVIF format.
147
+
148
+ **Parameters:**
149
+ - `png_data` (bytes): Raw PNG file data
150
+ - `config` (Config, optional): Encoding configuration. Uses defaults if not provided.
151
+
152
+ **Returns:**
153
+ - bytes: AVIF encoded data
154
+
155
+ **Raises:**
156
+ - `ColopressoError`: If encoding fails (including when output is larger than input)
157
+
158
+ **Example:**
159
+ ```python
160
+ import colopresso
161
+
162
+ with open("input.png", "rb") as f:
163
+ png_data = f.read()
164
+
165
+ config = colopresso.Config(avif_quality=70.0, avif_speed=4)
166
+ avif_data = colopresso.encode_avif(png_data, config)
167
+ ```
168
+
169
+ ---
170
+
171
+ #### `encode_pngx(png_data, config=None) -> bytes`
172
+
173
+ Optimize PNG data using the PNGX encoder. Supports both lossless and lossy compression.
174
+
175
+ **Parameters:**
176
+ - `png_data` (bytes): Raw PNG file data
177
+ - `config` (Config, optional): Encoding configuration. Uses defaults if not provided.
178
+
179
+ **Returns:**
180
+ - bytes: Optimized PNG data
181
+
182
+ **Raises:**
183
+ - `ColopressoError`: If encoding fails
184
+
185
+ **Example:**
186
+ ```python
187
+ import colopresso
188
+
189
+ with open("input.png", "rb") as f:
190
+ png_data = f.read()
191
+
192
+ # 256-color palette optimization
193
+ config = colopresso.Config(
194
+ pngx_lossy_enable=True,
195
+ pngx_lossy_type=colopresso.PngxLossyType.PALETTE256,
196
+ pngx_lossy_max_colors=256
197
+ )
198
+ optimized = colopresso.encode_pngx(png_data, config)
199
+ ```
200
+
201
+ ---
202
+
203
+ ### Config Class
204
+
205
+ The `Config` dataclass holds all encoder settings.
206
+
207
+ ```python
208
+ @dataclass
209
+ class Config:
210
+ # WebP settings
211
+ webp_quality: float = 80.0
212
+ webp_lossless: bool = False
213
+ webp_method: int = 6
214
+
215
+ # AVIF settings
216
+ avif_quality: float = 50.0
217
+ avif_alpha_quality: int = 100
218
+ avif_lossless: bool = False
219
+ avif_speed: int = 6
220
+ avif_threads: int = 1
221
+
222
+ # PNGX settings
223
+ pngx_level: int = 5
224
+ pngx_strip_safe: bool = True
225
+ pngx_optimize_alpha: bool = True
226
+ pngx_lossy_enable: bool = True
227
+ pngx_lossy_type: PngxLossyType = PngxLossyType.PALETTE256
228
+ pngx_lossy_max_colors: int = 256
229
+ pngx_lossy_quality_min: int = 80
230
+ pngx_lossy_quality_max: int = 95
231
+ pngx_lossy_speed: int = 3
232
+ pngx_lossy_dither_level: float = 0.6
233
+ pngx_threads: int = 1
234
+ ```
235
+
236
+ ---
237
+
238
+ ### PngxLossyType Enum
239
+
240
+ Specifies the type of lossy compression for PNGX.
241
+
242
+ ```python
243
+ class PngxLossyType(IntEnum):
244
+ PALETTE256 = 0 # 256-color indexed palette
245
+ LIMITED_RGBA4444 = 1 # RGBA4444 limited (16-bit color)
246
+ REDUCED_RGBA32 = 2 # Reduced color RGBA32
247
+ ```
248
+
249
+ | Value | Description | Use Case |
250
+ |---|---|---|
251
+ | `PALETTE256` | Convert to 256-color indexed palette | Icons, illustrations with few colors |
252
+ | `LIMITED_RGBA4444` | Limit each RGBA channel to 4 bits | Prevents banding artifacts in RGBA16bit and RGBA4444 |
253
+ | `REDUCED_RGBA32` | Reduce colors while keeping RGBA32 | When PALETTE256 is not acceptable |
254
+
255
+ ---
256
+
257
+ ### Configuration Parameters
258
+
259
+ #### WebP Settings
260
+
261
+ | Parameter | Type | Default | Description |
262
+ |---|---|---|---|
263
+ | `webp_quality` | float | 80.0 | Quality (0.0-100.0). Higher = better quality, larger size |
264
+ | `webp_lossless` | bool | False | True: lossless compression, False: lossy compression |
265
+ | `webp_method` | int | 6 | Compression method (0-6). Higher = better compression, slower |
266
+
267
+ **Advanced WebP Parameters:**
268
+
269
+ | Parameter | Type | Default | Description |
270
+ |---|---|---|---|
271
+ | `webp_target_size` | int | 0 | Target file size in bytes. 0 = disabled |
272
+ | `webp_target_psnr` | float | 0.0 | Target PSNR in dB. 0 = disabled |
273
+ | `webp_segments` | int | 4 | Number of segments (1-4) |
274
+ | `webp_sns_strength` | int | 50 | Spatial noise shaping strength (0-100) |
275
+ | `webp_filter_strength` | int | 60 | Deblocking filter strength (0-100) |
276
+ | `webp_filter_sharpness` | int | 0 | Filter sharpness (0-7). 0 = sharpest |
277
+ | `webp_filter_type` | int | 1 | Filter type. 0 = simple, 1 = strong |
278
+ | `webp_autofilter` | bool | True | Auto-adjust filter strength |
279
+ | `webp_alpha_compression` | bool | True | Compress alpha channel |
280
+ | `webp_alpha_filtering` | int | 1 | Alpha filtering (0-2) |
281
+ | `webp_alpha_quality` | int | 100 | Alpha channel quality (0-100) |
282
+ | `webp_pass` | int | 1 | Number of encoding passes (1-10) |
283
+ | `webp_preprocessing` | int | 0 | Preprocessing. 0=none, 1=segment-smooth, 2=pseudo-random dither |
284
+ | `webp_partitions` | int | 0 | Number of partitions (0-3) |
285
+ | `webp_partition_limit` | int | 0 | Partition size limit (0-100) |
286
+ | `webp_emulate_jpeg_size` | bool | False | Emulate JPEG output size |
287
+ | `webp_thread_level` | int | 0 | Thread level (0-1) |
288
+ | `webp_low_memory` | bool | False | Low memory mode |
289
+ | `webp_near_lossless` | int | 100 | Near-lossless preprocessing (0-100). 100 = off |
290
+ | `webp_exact` | bool | False | Preserve RGB values in transparent areas |
291
+ | `webp_use_delta_palette` | bool | False | Use delta palette (experimental) |
292
+ | `webp_use_sharp_yuv` | bool | False | Use sharp RGB to YUV conversion |
293
+
294
+ ---
295
+
296
+ #### AVIF Settings
297
+
298
+ | Parameter | Type | Default | Description |
299
+ |---|---|---|---|
300
+ | `avif_quality` | float | 50.0 | Quality (0.0-100.0). Higher = better quality, larger size |
301
+ | `avif_alpha_quality` | int | 100 | Alpha channel quality (0-100) |
302
+ | `avif_lossless` | bool | False | True: lossless compression, False: lossy compression |
303
+ | `avif_speed` | int | 6 | Encoding speed (0-10). 0 = best quality/slowest, 10 = lowest quality/fastest |
304
+ | `avif_threads` | int | 1 | Number of threads for encoding |
305
+
306
+ **Recommended Settings:**
307
+
308
+ | Use Case | quality | speed | Description |
309
+ |---|---|---|---|
310
+ | High Quality | 80-90 | 4 | High quality web images |
311
+ | Balanced | 50-60 | 6 | General purpose |
312
+ | Fast | 40-50 | 8-10 | Batch processing, previews |
313
+
314
+ ---
315
+
316
+ #### PNGX Settings
317
+
318
+ ##### Basic Settings
319
+
320
+ | Parameter | Type | Default | Description |
321
+ |---|---|---|---|
322
+ | `pngx_level` | int | 5 | Compression level (1-6). Higher = better compression |
323
+ | `pngx_strip_safe` | bool | True | Remove safely removable metadata |
324
+ | `pngx_optimize_alpha` | bool | True | Optimize color info in transparent pixels |
325
+ | `pngx_threads` | int | 1 | Number of threads for processing |
326
+
327
+ ##### Lossy Compression Settings
328
+
329
+ | Parameter | Type | Default | Description |
330
+ |---|---|---|---|
331
+ | `pngx_lossy_enable` | bool | True | Enable lossy compression |
332
+ | `pngx_lossy_type` | PngxLossyType | PALETTE256 | Type of lossy compression |
333
+ | `pngx_lossy_max_colors` | int | 256 | Maximum colors for palette mode (2-256) |
334
+ | `pngx_lossy_quality_min` | int | 80 | Minimum quality (0-100) |
335
+ | `pngx_lossy_quality_max` | int | 95 | Maximum quality (0-100) |
336
+ | `pngx_lossy_speed` | int | 3 | Quantization speed (1-10). Higher = faster, lower quality |
337
+ | `pngx_lossy_dither_level` | float | 0.6 | Dithering strength (0.0-1.0) |
338
+
339
+ ##### PALETTE256 Mode Settings
340
+
341
+ | Parameter | Type | Default | Description |
342
+ |---|---|---|---|
343
+ | `pngx_lossy_reduced_colors` | int | -1 | Target color count after reduction. -1 = auto |
344
+ | `pngx_saliency_map_enable` | bool | True | Adaptive quantization using saliency map |
345
+ | `pngx_chroma_anchor_enable` | bool | True | Preserve chroma anchor points |
346
+ | `pngx_adaptive_dither_enable` | bool | True | Adaptive dithering |
347
+ | `pngx_gradient_boost_enable` | bool | True | Gradient enhancement |
348
+ | `pngx_chroma_weight_enable` | bool | True | Apply chroma weighting |
349
+ | `pngx_postprocess_smooth_enable` | bool | True | Post-processing smoothing |
350
+ | `pngx_postprocess_smooth_importance_cutoff` | float | 0.6 | Smoothing importance cutoff |
351
+ | `pngx_palette256_gradient_profile_enable` | bool | True | Enable gradient profile |
352
+ | `pngx_palette256_gradient_dither_floor` | float | 0.78 | Gradient dither floor |
353
+ | `pngx_palette256_alpha_bleed_enable` | bool | False | Enable alpha bleed |
354
+ | `pngx_palette256_alpha_bleed_max_distance` | int | 64 | Maximum bleed distance in pixels |
355
+ | `pngx_palette256_alpha_bleed_opaque_threshold` | int | 248 | Opaque threshold |
356
+ | `pngx_palette256_alpha_bleed_soft_limit` | int | 160 | Soft bleed limit |
357
+
358
+ ##### LIMITED_RGBA4444 Mode Settings
359
+
360
+ | Parameter | Type | Default | Description |
361
+ |---|---|---|---|
362
+ | `pngx_lossy_reduced_bits_rgb` | int | 4 | RGB channel bit depth (1-8) |
363
+ | `pngx_lossy_reduced_alpha_bits` | int | 4 | Alpha channel bit depth (1-8) |
364
+
365
+ ---
366
+
367
+ ### Utility Functions
368
+
369
+ #### Version Information
370
+
371
+ ```python
372
+ def get_version() -> int
373
+ ```
374
+ Get the colopresso version number.
375
+
376
+ ```python
377
+ def get_libwebp_version() -> int
378
+ ```
379
+ Get the libwebp version number (e.g., 67072 = 1.4.0).
380
+
381
+ ```python
382
+ def get_libpng_version() -> int
383
+ ```
384
+ Get the libpng version number.
385
+
386
+ ```python
387
+ def get_libavif_version() -> int
388
+ ```
389
+ Get the libavif version number.
390
+
391
+ ```python
392
+ def get_pngx_oxipng_version() -> int
393
+ ```
394
+ Get the oxipng version number.
395
+
396
+ ```python
397
+ def get_pngx_libimagequant_version() -> int
398
+ ```
399
+ Get the libimagequant version number.
400
+
401
+ #### Build Information
402
+
403
+ ```python
404
+ def get_buildtime() -> int
405
+ ```
406
+ Get the build timestamp (Unix time).
407
+
408
+ ```python
409
+ def get_compiler_version_string() -> str
410
+ ```
411
+ Get the C compiler version string.
412
+
413
+ ```python
414
+ def get_rust_version_string() -> str
415
+ ```
416
+ Get the Rust compiler version string.
417
+
418
+ #### Thread Information
419
+
420
+ ```python
421
+ def is_threads_enabled() -> bool
422
+ ```
423
+ Check if multithreading is enabled.
424
+
425
+ ```python
426
+ def get_default_thread_count() -> int
427
+ ```
428
+ Get the default number of threads.
429
+
430
+ ```python
431
+ def get_max_thread_count() -> int
432
+ ```
433
+ Get the maximum available thread count.
434
+
435
+ ---
436
+
437
+ ### Exception Classes
438
+
439
+ #### ColopressoError
440
+
441
+ ```python
442
+ class ColopressoError(Exception):
443
+ code: int # Error code
444
+ message: str # Error message
445
+ ```
446
+
447
+ **Error Codes:**
448
+
449
+ | Code | Name | Description |
450
+ |---|---|---|
451
+ | 0 | OK | Success |
452
+ | 1 | File not found | File not found |
453
+ | 2 | Invalid PNG | Invalid PNG data |
454
+ | 3 | Invalid format | Invalid format |
455
+ | 4 | Out of memory | Memory allocation failed |
456
+ | 5 | Encode failed | Encoding failed |
457
+ | 6 | Decode failed | Decoding failed |
458
+ | 7 | IO error | Input/output error |
459
+ | 8 | Invalid parameter | Invalid parameter |
460
+ | 9 | Output not smaller | Output is not smaller than input |
461
+
462
+ **Example:**
463
+ ```python
464
+ import colopresso
465
+
466
+ try:
467
+ result = colopresso.encode_avif(png_data)
468
+ except colopresso.ColopressoError as e:
469
+ if e.code == 9:
470
+ print("AVIF compression was not effective. Using original PNG.")
471
+ else:
472
+ print(f"Error: {e.message}")
473
+ ```
474
+
475
+ ---
476
+
477
+ ## Examples
478
+
479
+ ### WebP Conversion with Quality Settings
480
+
481
+ ```python
482
+ import colopresso
483
+
484
+ with open("photo.png", "rb") as f:
485
+ png_data = f.read()
486
+
487
+ # High quality WebP
488
+ config = colopresso.Config(
489
+ webp_quality=95.0,
490
+ webp_method=6,
491
+ webp_use_sharp_yuv=True
492
+ )
493
+ high_quality = colopresso.encode_webp(png_data, config)
494
+
495
+ # High compression WebP
496
+ config = colopresso.Config(
497
+ webp_quality=60.0,
498
+ webp_method=6
499
+ )
500
+ compressed = colopresso.encode_webp(png_data, config)
501
+
502
+ # Lossless WebP
503
+ config = colopresso.Config(webp_lossless=True)
504
+ lossless = colopresso.encode_webp(png_data, config)
505
+ ```
506
+
507
+ ### AVIF with Multithreading
508
+
509
+ ```python
510
+ import colopresso
511
+
512
+ with open("large_image.png", "rb") as f:
513
+ png_data = f.read()
514
+
515
+ # Multithreaded high-speed encoding
516
+ config = colopresso.Config(
517
+ avif_quality=70.0,
518
+ avif_speed=6,
519
+ avif_threads=4
520
+ )
521
+ avif_data = colopresso.encode_avif(png_data, config)
522
+ ```
523
+
524
+ ### PNG Optimization (256-Color Palette)
525
+
526
+ ```python
527
+ import colopresso
528
+
529
+ with open("icon.png", "rb") as f:
530
+ png_data = f.read()
531
+
532
+ config = colopresso.Config(
533
+ pngx_lossy_enable=True,
534
+ pngx_lossy_type=colopresso.PngxLossyType.PALETTE256,
535
+ pngx_lossy_max_colors=256,
536
+ pngx_lossy_quality_min=85,
537
+ pngx_lossy_quality_max=100,
538
+ pngx_lossy_dither_level=0.8
539
+ )
540
+ optimized = colopresso.encode_pngx(png_data, config)
541
+
542
+ print(f"Original: {len(png_data)} bytes")
543
+ print(f"Optimized: {len(optimized)} bytes")
544
+ print(f"Reduction: {(1 - len(optimized)/len(png_data))*100:.1f}%")
545
+ ```
546
+
547
+ ### PNG Lossless Optimization
548
+
549
+ ```python
550
+ import colopresso
551
+
552
+ with open("screenshot.png", "rb") as f:
553
+ png_data = f.read()
554
+
555
+ config = colopresso.Config(
556
+ pngx_lossy_enable=False, # Disable lossy compression
557
+ pngx_level=6, # Maximum compression level
558
+ pngx_strip_safe=True, # Remove metadata
559
+ pngx_optimize_alpha=True # Optimize alpha
560
+ )
561
+ optimized = colopresso.encode_pngx(png_data, config)
562
+ ```
563
+
564
+ ### Game Texture PNG (RGBA4444)
565
+
566
+ ```python
567
+ import colopresso
568
+
569
+ with open("texture.png", "rb") as f:
570
+ png_data = f.read()
571
+
572
+ # RGBA4444 format (16-bit color)
573
+ config = colopresso.Config(
574
+ pngx_lossy_enable=True,
575
+ pngx_lossy_type=colopresso.PngxLossyType.LIMITED_RGBA4444,
576
+ pngx_lossy_reduced_bits_rgb=4,
577
+ pngx_lossy_reduced_alpha_bits=4
578
+ )
579
+ optimized = colopresso.encode_pngx(png_data, config)
580
+ ```
581
+
582
+ ### Batch Processing
583
+
584
+ ```python
585
+ import colopresso
586
+ from pathlib import Path
587
+ from concurrent.futures import ThreadPoolExecutor
588
+
589
+ def convert_to_webp(png_path: Path) -> tuple[Path, int, int]:
590
+ """Convert PNG to WebP and return size info"""
591
+ with open(png_path, "rb") as f:
592
+ png_data = f.read()
593
+
594
+ config = colopresso.Config(webp_quality=80.0)
595
+ webp_data = colopresso.encode_webp(png_data, config)
596
+
597
+ webp_path = png_path.with_suffix(".webp")
598
+ with open(webp_path, "wb") as f:
599
+ f.write(webp_data)
600
+
601
+ return webp_path, len(png_data), len(webp_data)
602
+
603
+ # Parallel conversion
604
+ png_files = list(Path("images").glob("*.png"))
605
+ with ThreadPoolExecutor(max_workers=4) as executor:
606
+ results = list(executor.map(convert_to_webp, png_files))
607
+
608
+ for path, original, converted in results:
609
+ print(f"{path.name}: {original} -> {converted} ({(1-converted/original)*100:.1f}% reduction)")
610
+ ```
611
+
612
+ ### Error Handling
613
+
614
+ ```python
615
+ import colopresso
616
+
617
+ def safe_encode(png_data: bytes, format: str = "webp") -> bytes | None:
618
+ """Encode with error handling"""
619
+ config = colopresso.Config()
620
+
621
+ try:
622
+ if format == "webp":
623
+ return colopresso.encode_webp(png_data, config)
624
+ elif format == "avif":
625
+ return colopresso.encode_avif(png_data, config)
626
+ elif format == "pngx":
627
+ return colopresso.encode_pngx(png_data, config)
628
+ else:
629
+ raise ValueError(f"Unknown format: {format}")
630
+
631
+ except colopresso.ColopressoError as e:
632
+ if e.code == 2:
633
+ print("Error: Input is not a valid PNG")
634
+ elif e.code == 9:
635
+ print(f"{format.upper()} compression was not effective")
636
+ return png_data # Return original data
637
+ else:
638
+ print(f"Encoding error: {e.message}")
639
+ return None
640
+
641
+ # Usage
642
+ with open("input.png", "rb") as f:
643
+ png_data = f.read()
644
+
645
+ result = safe_encode(png_data, "avif")
646
+ if result:
647
+ with open("output.avif", "wb") as f:
648
+ f.write(result)
649
+ ```
650
+
651
+ ---
652
+
653
+ ## Building Wheels
654
+
655
+ ```bash
656
+ cd python
657
+ pip install build
658
+ python -m build --wheel
659
+ ```
660
+
661
+ The wheel will be created in `python/dist/`.
662
+
663
+ ---
664
+
665
+ ## License
666
+
667
+ colopresso is licensed under GPL-3.0-or-later.
668
+
669
+ Copyright (C) 2026 COLOPL, Inc.
@@ -0,0 +1,8 @@
1
+ colopresso/__init__.py,sha256=tga5NFjmtRR0iuM0K8qBXtA-Rfq9_pdwcEhPtREt9nE,1238
2
+ colopresso/core.py,sha256=Mv_XUZ1-hM0eUBrmqjWUwgUil_s1zzWgFD0JSvLbBe4,7985
3
+ colopresso/_colopresso.abi3.so,sha256=7pjDZwYK9CaWEAvv5M4uWsTx03n8S0W3aXFjBTgm6gs,8858528
4
+ colopresso/py.typed,sha256=i3wkBOk9Q7xp5kklt6_1NIFjZnebgaVe7sO7s3bPi9Q,1846
5
+ colopresso/_colopresso_ext.c,sha256=5QlOnXm8dQqz_0xdReQDHnzyjUDccc1Z1w-cCFXdUt8,23930
6
+ colopresso-12.2.0.dist-info/RECORD,,
7
+ colopresso-12.2.0.dist-info/WHEEL,sha256=FbrIo26KQn9Hpr63lMXrAB6KAWuEl6ilUnUS4VtFpl8,140
8
+ colopresso-12.2.0.dist-info/METADATA,sha256=JU5lzk2m5hRFW7lVzHFAtS8DvYzPQz3XRM0ENEw7PzQ,18258
@@ -0,0 +1,6 @@
1
+ Wheel-Version: 1.0
2
+ Generator: scikit-build-core 0.11.6
3
+ Root-Is-Purelib: false
4
+ Tag: cp310-abi3-macosx_11_0_arm64
5
+ Generator: delocate 0.13.0
6
+