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;
}
Example #2
0
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);
}
Example #3
0
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);
}
Example #4
0
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);
}
Example #6
0
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;
}