This repository has been archived by the owner on Aug 6, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
pngquant_tiny.c
108 lines (89 loc) · 2.63 KB
/
pngquant_tiny.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <stdio.h>
#include <stdlib.h>
#include "pngquant/rwpng.h"
#include "pngquant/lib/libimagequant.h"
#include "pngquant/lib/pam.h"
#define GAMMA 0.45455
#define FAST_COMPRESSION 1
void
read_image(liq_attr *attr, FILE *source, png24_image *png, liq_image **image)
{
rwpng_read_image24(source, png);
*image = liq_image_create_rgba_rows(attr, (void **) png->row_pointers,
png->width, png->height, png->gamma);
}
void
prepare_output_image(liq_result *rv, liq_image *image, png8_image *png)
{
unsigned int i;
const liq_palette *palette;
png->width = liq_image_get_width(image);
png->height = liq_image_get_height(image);
png->indexed_data = malloc(png->width * png->height);
png->row_pointers = malloc(png->height * sizeof(png->row_pointers[0]));
for (i = 0;i < png->height;i++) {
png->row_pointers[i] = png->indexed_data + i * png->width;
}
palette = liq_get_palette(rv);
png->num_palette = palette->count;
png->num_trans = 0;
for (i = 0;i < palette->count;i++) {
if (palette->entries[i].a < 255) {
png->num_trans = i + 1;
}
}
}
void
set_palette(liq_result *rv, png8_image *png)
{
unsigned int i;
liq_color px;
const liq_palette *palette;
palette = liq_get_palette(rv);
png->num_palette = palette->count;
png->num_trans = 0;
for (i = 0;i < palette->count;i++) {
px = palette->entries[i];
if (px.a < 255) {
png->num_trans = i + 1;
}
png->palette[i] = (png_color) {.red=px.r, .green=px.g, .blue=px.b};
png->trans[i] = px.a;
}
}
void
png8_image_destroy(png8_image *png)
{
free(png->indexed_data);
png->indexed_data = NULL;
free(png->row_pointers);
png->row_pointers = NULL;
}
void
png24_image_destroy(png24_image *png)
{
free(png->rgba_data);
free(png->row_pointers);
}
void
pngquant_tiny(FILE *src, FILE *dest)
{
liq_attr *attr;
liq_result *rv;
liq_image *input_image = NULL;
png24_image input_png = {};
png8_image output_png = {};
attr = liq_attr_create();
read_image(attr, src, &input_png, &input_image);
rv = liq_quantize_image(attr, input_image);
liq_set_output_gamma(rv, GAMMA);
prepare_output_image(rv, input_image, &output_png);
liq_write_remapped_image_rows(rv, input_image, output_png.row_pointers);
set_palette(rv, &output_png);
output_png.fast_compression = FAST_COMPRESSION;
rwpng_write_image8(dest, &output_png);
liq_result_destroy(rv);
liq_image_destroy(input_image);
png24_image_destroy(&input_png);
png8_image_destroy(&output_png);
}