diff options
Diffstat (limited to 'src/png-file.c')
-rw-r--r-- | src/png-file.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/png-file.c b/src/png-file.c new file mode 100644 index 0000000..09925a7 --- /dev/null +++ b/src/png-file.c @@ -0,0 +1,125 @@ +/* + * png-file.c + * + * PNG output + * + * (c) 2006-2007 Thomas White <taw27@cam.ac.uk> + * + * synth2d - Two-Dimensional Crystallographic Fourier Synthesis + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <png.h> +#include <math.h> +#include <stdlib.h> +#include <fftw3.h> + +#include "data.h" +#include "colwheel.h" +#include "renderer.h" + +int png_write_real(const char *filename, fftw_complex *out, double brightness, double gamma_angle, int width, int height, int nx, int ny) { + + FILE *fh; + png_structp png_ptr; + png_infop info_ptr; + png_bytep *row_pointers; + int xn, yn; + int width_n, height_n; + ComplexArray cxar; + + fh = fopen(filename, "wb"); + if (!fh) { + fprintf(stderr, "Couldn't open output file.\n"); + return 1; + } + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if ( !png_ptr ) { + fprintf(stderr, "Couldn't create PNG write structure.\n"); + fclose(fh); + return 1; + } + info_ptr = png_create_info_struct(png_ptr); + if ( !info_ptr ) { + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + fprintf(stderr, "Couldn't create PNG info structure.\n"); + fclose(fh); + return 1; + } + if ( setjmp(png_jmpbuf(png_ptr)) ) { + png_destroy_write_struct(&png_ptr, &info_ptr); + fclose(fh); + fprintf(stderr, "PNG write failed.\n"); + return 1; + } + png_init_io(png_ptr, fh); + + width_n = (int)renderer_width(width, height, gamma_angle, nx, ny); + height_n = (int)renderer_height(width, height, gamma_angle, nx, ny); + cxar = renderer_draw(out, width, height, gamma_angle, nx, ny); + + png_set_IHDR(png_ptr, info_ptr, width_n, height_n, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + /* Write the image data */ + row_pointers = malloc(height_n*sizeof(png_bytep *)); + + for ( yn=0; yn<height_n; yn++ ) { + + row_pointers[yn] = malloc(width_n*3); + for ( xn=0; xn<width_n; xn++ ) { + row_pointers[yn][3*xn] = 0; + row_pointers[yn][3*xn+1] = 0; + row_pointers[yn][3*xn+2] = 0; + } + + } + + for ( yn=0; yn<height_n; yn++ ) { + for ( xn=0; xn<width_n; xn++ ) { + + double re, im, am, ph; + + re = cxar.re[xn+width_n*yn]; + im = cxar.im[xn+width_n*yn]; + am = sqrt(re*re + im*im) / brightness; + ph = atan2(im, re); + if ( am > 1 ) am = 1; + + row_pointers[yn][3*xn] = (png_byte)255*colwheel_red(am, ph); + row_pointers[yn][3*xn+1] = (png_byte)255*colwheel_green(am, ph); + row_pointers[yn][3*xn+2] = (png_byte)255*colwheel_blue(am, ph); + + } + } + + for ( yn=0; yn<height_n/2+1; yn++ ) { + png_bytep scratch; + scratch = row_pointers[yn]; + row_pointers[yn] = row_pointers[height_n-yn-1]; + row_pointers[height_n-yn-1] = scratch; + } + + png_set_rows(png_ptr, info_ptr, row_pointers); + png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); + + png_destroy_write_struct(&png_ptr, &info_ptr); + for ( yn=0; yn<height_n; yn++ ) { + free(row_pointers[yn]); + } + free(row_pointers); + fclose(fh); + + return 0; + +} + +int png_write(const char *filename, fftw_complex *out, double norm, int nx, int ny) { + return png_write_real(filename, out, norm, data_gamma(), data_width(), data_height(), nx, ny); +} + |