Pillow

Форк
0
/
QuantPngQuant.c 
133 строки · 3.1 Кб
1
/*
2
 * The Python Imaging Library
3
 * $Id$
4
 *
5
 * quantization using libimagequant, a part of pngquant.
6
 *
7
 * Copyright (c) 2016 Marcin Kurczewski <rr-@sakuya.pl>
8
 *
9
 */
10

11
#include <stdio.h>
12
#include <stdlib.h>
13
#include <string.h>
14

15
#include "QuantPngQuant.h"
16

17
#ifdef HAVE_LIBIMAGEQUANT
18
#include "libimagequant.h"
19

20
int
21
quantize_pngquant(
22
    Pixel *pixelData,
23
    unsigned int width,
24
    unsigned int height,
25
    uint32_t quantPixels,
26
    Pixel **palette,
27
    uint32_t *paletteLength,
28
    uint32_t **quantizedPixels,
29
    int withAlpha
30
) {
31
    int result = 0;
32
    liq_image *image = NULL;
33
    liq_attr *attr = NULL;
34
    liq_result *remap = NULL;
35
    unsigned char *charMatrix = NULL;
36
    unsigned char **charMatrixRows = NULL;
37
    unsigned int i, y;
38
    *palette = NULL;
39
    *paletteLength = 0;
40
    *quantizedPixels = NULL;
41

42
    /* configure pngquant */
43
    attr = liq_attr_create();
44
    if (!attr) {
45
        goto err;
46
    }
47
    if (quantPixels) {
48
        liq_set_max_colors(attr, quantPixels);
49
    }
50

51
    /* prepare input image */
52
    image = liq_image_create_rgba(attr, pixelData, width, height, 0.45455 /* gamma */);
53
    if (!image) {
54
        goto err;
55
    }
56

57
    /* quantize the image */
58
    remap = liq_quantize_image(attr, image);
59
    if (!remap) {
60
        goto err;
61
    }
62
    liq_set_output_gamma(remap, 0.45455);
63
    liq_set_dithering_level(remap, 1);
64

65
    /* write output palette */
66
    const liq_palette *l_palette = liq_get_palette(remap);
67
    *paletteLength = l_palette->count;
68
    *palette = malloc(sizeof(Pixel) * l_palette->count);
69
    if (!*palette) {
70
        goto err;
71
    }
72
    for (i = 0; i < l_palette->count; i++) {
73
        (*palette)[i].c.b = l_palette->entries[i].b;
74
        (*palette)[i].c.g = l_palette->entries[i].g;
75
        (*palette)[i].c.r = l_palette->entries[i].r;
76
        (*palette)[i].c.a = l_palette->entries[i].a;
77
    }
78

79
    /* write output pixels (pngquant uses char array) */
80
    charMatrix = malloc(width * height);
81
    if (!charMatrix) {
82
        goto err;
83
    }
84
    charMatrixRows = malloc(height * sizeof(unsigned char *));
85
    if (!charMatrixRows) {
86
        goto err;
87
    }
88
    for (y = 0; y < height; y++) {
89
        charMatrixRows[y] = &charMatrix[y * width];
90
    }
91
    if (LIQ_OK != liq_write_remapped_image_rows(remap, image, charMatrixRows)) {
92
        goto err;
93
    }
94

95
    /* transcribe output pixels (pillow uses uint32_t array) */
96
    *quantizedPixels = malloc(sizeof(uint32_t) * width * height);
97
    if (!*quantizedPixels) {
98
        goto err;
99
    }
100
    for (i = 0; i < width * height; i++) {
101
        (*quantizedPixels)[i] = charMatrix[i];
102
    }
103

104
    result = 1;
105

106
err:
107
    if (attr) {
108
        liq_attr_destroy(attr);
109
    }
110
    if (image) {
111
        liq_image_destroy(image);
112
    }
113
    if (remap) {
114
        liq_result_destroy(remap);
115
    }
116
    free(charMatrix);
117
    free(charMatrixRows);
118
    if (!result) {
119
        free(*quantizedPixels);
120
        free(*palette);
121
    }
122
    return result;
123
}
124

125
const char *
126
ImagingImageQuantVersion(void) {
127
    static char version[20];
128
    int number = liq_version();
129
    sprintf(version, "%d.%d.%d", number / 10000, (number / 100) % 100, number % 100);
130
    return version;
131
}
132

133
#endif
134

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.