struct bufferAndSize pngQuant(MagickWand *output){ unsigned long wid = MagickGetImageWidth(output); unsigned long hei = MagickGetImageHeight(output); unsigned char *bmp_buffer; bmp_buffer = (unsigned char*) malloc(wid*hei*4); MagickGetImagePixels(output,0,0,wid,hei,"RGBA",CharPixel,bmp_buffer); liq_attr *attr = liq_attr_create(); liq_image *qimage = liq_image_create_rgba(attr, bmp_buffer, wid, hei, 0); liq_set_max_colors(attr, 255); liq_set_speed(attr, 10); liq_result *res = liq_quantize_image(attr, qimage); int png_buffer_size = wid*hei; unsigned char *png_buffer = malloc(png_buffer_size); liq_write_remapped_image(res, qimage, png_buffer, png_buffer_size); const liq_palette *pal = liq_get_palette(res); LodePNGState state; lodepng_state_init(&state); /*optionally customize the state*/ state.info_png.color.bitdepth = 8; state.info_png.color.colortype = LCT_PALETTE; state.info_raw.colortype = LCT_PALETTE; state.info_raw.bitdepth = 8; state.encoder.auto_convert = 0; state.encoder.add_id = 0; state.encoder.zlibsettings.nicematch = 258; int i = 0; for (i=0; i < pal->count; ++i) { lodepng_palette_add(&state.info_png.color, pal->entries[i].r , pal->entries[i].g, pal->entries[i].b, pal->entries[i].a); lodepng_palette_add(&state.info_raw, pal->entries[i].r , pal->entries[i].g, pal->entries[i].b, pal->entries[i].a); } unsigned char *data; size_t size = 0; lodepng_encode(&data, &size, png_buffer, wid, hei, &state); // writtendata = io_write(size, data); lodepng_state_cleanup(&state); free(bmp_buffer); free(png_buffer); liq_attr_destroy(attr); liq_image_destroy(qimage); liq_result_destroy(res); lodepng_state_cleanup(&state); struct bufferAndSize bs; bs.data = data; bs.size = size; return bs; }
static void test_abort() { liq_attr *attr = liq_attr_create(); unsigned char dummy[4] = {0}; liq_image *img = liq_image_create_rgba(attr, dummy, 1, 1, 0); liq_attr_set_progress_callback(attr, test_abort_callback, magic); liq_result *res = liq_quantize_image(attr, img); assert(!res); liq_attr_destroy(attr); }
static void test_fixed_colors_order() { liq_attr *attr = liq_attr_create(); unsigned char dummy[4] = {0}; liq_image *img = liq_image_create_rgba(attr, dummy, 1, 1, 0); assert(img); liq_color colors[17] = { {0,0,0,0}, {1,1,1,1}, {2,2,2,2}, {3,3,3,3}, {4,4,4,4}, {5,4,4,4}, {6,4,4,4}, {6,7,4,4}, {6,7,8,4}, {6,7,8,9}, {10,7,8,9}, {10,11,8,9}, {10,11,12,9}, {10,11,12,13}, {14,11,12,13}, {14,15,12,13}, {14,15,16,13}, }; for(int i=0; i < 17; i++) { liq_image_add_fixed_color(img, colors[i]); } liq_result *res = liq_quantize_image(attr, img); assert(res); const liq_palette *pal = liq_get_palette(res); assert(pal); assert(pal->count == 17); for(int i=0; i < 17; i++) { assert(pal->entries[i].r == colors[i].r); assert(pal->entries[i].g == colors[i].g); assert(pal->entries[i].b == colors[i].b); assert(pal->entries[i].a == colors[i].a); } liq_set_dithering_level(res, 1.0); char buf[1]; assert(LIQ_OK == liq_write_remapped_image(res, img, buf, 1)); liq_result_set_progress_callback(res, test_abort_callback, magic); assert(LIQ_ABORTED == liq_write_remapped_image(res, img, buf, 1)); liq_result_destroy(res); liq_image_destroy(img); liq_attr_destroy(attr); }
static void test_fixed_colors() { liq_attr *attr = liq_attr_create(); liq_attr_set_progress_callback(attr, test_continue_callback, magic); unsigned char dummy[4] = {0}; liq_image *img = liq_image_create_rgba(attr, dummy, 1, 1, 0); assert(img); liq_image_add_fixed_color(img, (liq_color){0,0,0,0}); liq_result *res = liq_quantize_image(attr, img); assert(res); assert(progress_called); const liq_palette *pal = liq_get_palette(res); assert(pal); assert(pal->count == 1); liq_result_destroy(res); liq_image_destroy(img); liq_attr_destroy(attr); }
void MedianCut32bitQuantizer::process_() { liq_attr *attr = liq_attr_create(); liq_set_speed(attr, 1); liq_image *image = liq_image_create_rgba(attr, reinterpret_cast<void*>(rawsrc_.get()), width_, height_, 0); liq_result *res = liq_quantize_image(attr, image); liq_set_dithering_level(res, 1); liq_write_remapped_image(res, image, reinterpret_cast<void*>(rawdest_.get()), width_ * height_); const liq_palette *pal = liq_get_palette(res); for (size_t i = 0; i < pal->count; ++i) { const liq_color& color = pal->entries[i]; palette_[i].red = color.r; palette_[i].green = color.g; palette_[i].blue = color.b; trans_[i] = color.a; } liq_attr_destroy(attr); liq_image_destroy(image); liq_result_destroy(res); }
int quantize_pngquant( Pixel *pixelData, int width, int height, uint32_t quantPixels, Pixel **palette, uint32_t *paletteLength, uint32_t **quantizedPixels, int withAlpha) { int result = 0; liq_image *image = NULL; liq_attr *attr = NULL; liq_result *remap = NULL; unsigned char *charMatrix = NULL; unsigned char **charMatrixRows = NULL; unsigned int i, y; *palette = NULL; *paletteLength = 0; *quantizedPixels = NULL; /* configure pngquant */ attr = liq_attr_create(); if (!attr) { goto err; } if (quantPixels) { liq_set_max_colors(attr, quantPixels); } /* prepare input image */ image = liq_image_create_rgba( attr, pixelData, width, height, 0.45455 /* gamma */); if (!image) { goto err; } /* quantize the image */ remap = liq_quantize_image(attr, image); if (!remap) { goto err; } liq_set_output_gamma(remap, 0.45455); liq_set_dithering_level(remap, 1); /* write output palette */ const liq_palette *l_palette = liq_get_palette(remap); *paletteLength = l_palette->count; *palette = malloc(sizeof(Pixel) * l_palette->count); if (!*palette) { goto err; } for (i = 0; i < l_palette->count; i++) { (*palette)[i].c.b = l_palette->entries[i].b; (*palette)[i].c.g = l_palette->entries[i].g; (*palette)[i].c.r = l_palette->entries[i].r; (*palette)[i].c.a = l_palette->entries[i].a; } /* write output pixels (pngquant uses char array) */ charMatrix = malloc(width * height); if (!charMatrix) { goto err; } charMatrixRows = malloc(height * sizeof(unsigned char*)); if (!charMatrixRows) { goto err; } for (y = 0; y < height; y++) { charMatrixRows[y] = &charMatrix[y * width]; } if (LIQ_OK != liq_write_remapped_image_rows(remap, image, charMatrixRows)) { goto err; } /* transcribe output pixels (pillow uses uint32_t array) */ *quantizedPixels = malloc(sizeof(uint32_t) * width * height); if (!*quantizedPixels) { goto err; } for (i = 0; i < width * height; i++) { (*quantizedPixels)[i] = charMatrix[i]; } result = 1; err: if (attr) liq_attr_destroy(attr); if (image) liq_image_destroy(image); if (remap) liq_result_destroy(remap); free(charMatrix); free(charMatrixRows); if (!result) { free(*quantizedPixels); free(*palette); } return result; }