/** * \brief encode an image to RGB(A) PNG format * \private \memberof mapcache_image_format_png * \sa mapcache_image_format::write() */ mapcache_buffer* _mapcache_imageio_png_encode(mapcache_context *ctx, mapcache_image *img, mapcache_image_format *format) { png_infop info_ptr; int color_type; size_t row; mapcache_buffer *buffer = NULL; int compression = ((mapcache_image_format_png*)format)->compression_level; png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL,NULL); if (!png_ptr) { ctx->set_error(ctx, 500, "failed to allocate png_struct structure"); return NULL; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); ctx->set_error(ctx, 500, "failed to allocate png_info structure"); return NULL; } if (setjmp(png_jmpbuf(png_ptr))) { ctx->set_error(ctx, 500, "failed to setjmp(png_jmpbuf(png_ptr))"); png_destroy_write_struct(&png_ptr, &info_ptr); return NULL; } buffer = mapcache_buffer_create(5000,ctx->pool); png_set_write_fn(png_ptr, buffer, _mapcache_imageio_png_write_func, _mapcache_imageio_png_flush_func); if(mapcache_image_has_alpha(img)) color_type = PNG_COLOR_TYPE_RGB_ALPHA; else color_type = PNG_COLOR_TYPE_RGB; png_set_IHDR(png_ptr, info_ptr, img->w, img->h, 8, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); if(compression == MAPCACHE_COMPRESSION_BEST) png_set_compression_level (png_ptr, Z_BEST_COMPRESSION); else if(compression == MAPCACHE_COMPRESSION_FAST) png_set_compression_level (png_ptr, Z_BEST_SPEED); png_write_info(png_ptr, info_ptr); if(color_type == PNG_COLOR_TYPE_RGB) png_set_filler(png_ptr, 255, PNG_FILLER_AFTER); png_bytep rowptr = img->data; for(row=0;row<img->h;row++) { png_write_row(png_ptr,rowptr); rowptr += img->stride; } png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); return buffer; }
/** * \brief encode an image to mixed format * depending on the transparency of the provided image, use either one * of the two member encoding formats. * Intended to be used for creating png when transparency is present, and jpeg * when fully opaque * \sa mapcache_image_format::write() */ static mapcache_buffer* _mapcache_imageio_mixed_encode( mapcache_context *ctx, mapcache_image *image, mapcache_image_format *format) { mapcache_image_format_mixed *f = (mapcache_image_format_mixed*)format; if(mapcache_image_has_alpha(image)) { return f->transparent->write(ctx,image,f->transparent); } else { return f->opaque->write(ctx,image,f->opaque); } }