1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
// Gmsh - Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle
//
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to <gmsh@geuz.org>.
#include "GmshConfig.h"
#include "gl2png.h"
#if !defined(HAVE_LIBPNG)
void create_png(FILE *file, PixelBuffer *buffer, int quality)
{
Msg::Error("This version of Gmsh was compiled without PNG support");
}
#else
#include <png.h>
#ifndef png_jmpbuf
# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
#endif
void create_png(FILE *file, PixelBuffer *buffer, int quality)
{
if((buffer->getFormat() != GL_RGB && buffer->getFormat() != GL_RGBA) ||
buffer->getType() != GL_UNSIGNED_BYTE){
Msg::Error("PNG only implemented for GL_RGB/GL_RGBA and GL_UNSIGNED_BYTE");
return;
}
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(png_ptr == NULL) {
Msg::Error("Could not create PNG write struct");
return;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if(info_ptr == NULL) {
png_destroy_write_struct(&png_ptr, NULL);
Msg::Error("Could not create PNG info struct");
return;
}
if(setjmp(png_jmpbuf(png_ptr))) {
png_destroy_write_struct(&png_ptr, &info_ptr);
Msg::Error("Could not setjmp in PNG");
return;
}
png_init_io(png_ptr, file);
int height = buffer->getHeight();
int width = buffer->getWidth();
int numcomp = buffer->getNumComp();
// Z_DEFAULT_COMPRESSION, Z_BEST_SPEED, Z_BEST_COMPRESSION, Z_NO_COMPRESSION
png_set_compression_level(png_ptr, Z_DEFAULT_COMPRESSION);
png_set_IHDR(png_ptr, info_ptr, width, height, 8,
(numcomp == 3) ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGBA,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
time_t now;
time(&now);
png_text text_ptr[10];
text_ptr[0].key = (char*)"Creator";
text_ptr[0].text = (char*)"Gmsh";
text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
text_ptr[1].key = (char*)"Date";
text_ptr[1].text = ctime(&now);
text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
png_set_text(png_ptr, info_ptr, text_ptr, 2);
png_write_info(png_ptr, info_ptr);
unsigned char *pixels = (unsigned char *)buffer->getPixels();
for(int row = height - 1; row >= 0; row--) {
unsigned char *row_pointer = &pixels[row * width * numcomp];
png_write_row(png_ptr, (png_bytep)row_pointer);
}
png_write_end(png_ptr, info_ptr);
png_destroy_write_struct(&png_ptr, &info_ptr);
}
#endif
|