Esempio n. 1
0
/**
 * \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;
}
Esempio n. 2
0
/**
 * \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);
  }
}