void generator::save_image(const bitmap& bm) { FILE* fp = fopen(string(font_name_ + ".png").c_str(), "wb"); if(!fp) { throw runtime_error("Can't open png output file."); } png_structp png_ptr = NULL; png_infop info_ptr = NULL; png_byte ** row_pointers = NULL; int status = -1; int pixel_size = 4; int depth = 8; png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { throw runtime_error("Can't open png output structure."); } info_ptr = png_create_info_struct (png_ptr); if (info_ptr == NULL) { throw runtime_error("Can't create png info struct."); } png_set_IHDR (png_ptr, info_ptr, bm.get_width(), bm.get_height(), depth, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); row_pointers = static_cast<png_byte**>(png_malloc (png_ptr, bm.get_height() * sizeof (png_byte *))); for (uint32_t y = 0; y < bm.get_height(); ++y) { png_byte *row = static_cast<png_byte*>(png_malloc (png_ptr, sizeof (uint8_t) * bm.get_width() * pixel_size)); row_pointers[y] = row; for (uint32_t x = 0; x < bm.get_width(); ++x) { pixel p = bm.get_pixel(x, y); *row++ = p.red; *row++ = p.green; *row++ = p.blue; *row++ = p.alpha; } } png_init_io (png_ptr, fp); png_set_rows (png_ptr, info_ptr, row_pointers); png_write_png (png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); status = 0; for (size_t y = 0; y < bm.get_height(); y++) { png_free (png_ptr, row_pointers[y]); } png_free (png_ptr, row_pointers); png_destroy_write_struct (&png_ptr, &info_ptr); fclose (fp); }