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; }
bool sprite_file_export(int spriteIndex, const char *outPath) { rct_g1_element *spriteHeader; rct_drawpixelinfo dpi; uint8 *pixels; int pixelBufferSize; spriteHeader = &spriteFileEntries[spriteIndex]; pixelBufferSize = spriteHeader->width * spriteHeader->height; pixels = malloc(pixelBufferSize); memset(pixels, 0, pixelBufferSize); dpi.bits = pixels; dpi.x = 0; dpi.y = 0; dpi.width = spriteHeader->width; dpi.height = spriteHeader->height; dpi.pitch = 0; dpi.zoom_level = 0; memcpy(spriteFilePalette, _standardPalette, 256 * 4); gfx_rle_sprite_to_buffer(spriteHeader->offset, pixels, (uint8*)spriteFilePalette, &dpi, IMAGE_TYPE_NO_BACKGROUND, 0, spriteHeader->height, 0, spriteHeader->width); LodePNGState pngState; unsigned int pngError; unsigned char* pngData; size_t pngSize; lodepng_state_init(&pngState); pngState.info_raw.colortype = LCT_PALETTE; lodepng_palette_add(&pngState.info_raw, 0, 0, 0, 0); for (int i = 1; i < 256; i++) { lodepng_palette_add( &pngState.info_raw, spriteFilePalette[i].r, spriteFilePalette[i].g, spriteFilePalette[i].b, 255 ); } pngError = lodepng_encode(&pngData, &pngSize, pixels, spriteHeader->width, spriteHeader->height, &pngState); if (pngError != 0) { free(pngData); fprintf(stderr, "Error creating PNG data, %u: %s", pngError, lodepng_error_text(pngError)); return false; } else { lodepng_save_file(pngData, pngSize, outPath); free(pngData); return true; } }
int screenshot_dump_png() { int i, index, width, height, stride; char path[MAX_PATH] = ""; unsigned char r, g, b, a = 255; unsigned char* png; size_t pngSize; LodePNGState state; // Get a free screenshot path if ((index = screenshot_get_next_path(path, ".png")) == -1) return -1; lodepng_state_init(&state); state.info_raw.colortype = LCT_PALETTE; // Get image size width = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16); height = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16); stride = (width + 3) & 0xFFFFFFFC; for (i = 0; i < 246; i++) { b = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 0]; g = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 1]; r = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 2]; lodepng_palette_add(&state.info_raw, r, g, b, a); } rct_drawpixelinfo *dpi = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo); unsigned int error = lodepng_encode(&png, &pngSize, dpi->bits, stride, dpi->height, &state); if (!error) lodepng_save_file(png, pngSize, path); if (error) { fprintf(stderr, "error: %u: %s\n", error, lodepng_error_text(error)); index = -1; } free(png); return index; }