aboutsummaryrefslogtreecommitdiff
path: root/src/png-file.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/png-file.c')
-rw-r--r--src/png-file.c125
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);
+}
+