1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stddef.h>
4 #include <string.h>
5 #include <errno.h>
6 #include <png.h>
7 #include <setjmp.h>
8
9 #include "readers.h"
10 #include "writers.h"
11 #include "viewer.h"
12
13 /* ---------------------------------------------------------------------- */
14 /* save */
15
16 static int
png_write(FILE * fp,struct ida_image * img)17 png_write(FILE *fp, struct ida_image *img)
18 {
19 png_structp png_ptr = NULL;
20 png_infop info_ptr = NULL;
21 png_bytep row;
22 unsigned int y;
23
24 /* Create and initialize the png_struct with the desired error handler
25 * functions. If you want to use the default stderr and longjump method,
26 * you can supply NULL for the last three parameters. We also check that
27 * the library version is compatible with the one used at compile time,
28 * in case we are using dynamically linked libraries. REQUIRED.
29 */
30 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
31 if (png_ptr == NULL)
32 goto oops;
33
34 /* Allocate/initialize the image information data. REQUIRED */
35 info_ptr = png_create_info_struct(png_ptr);
36 if (info_ptr == NULL)
37 goto oops;
38 if (setjmp(png_jmpbuf(png_ptr)))
39 goto oops;
40
41 png_init_io(png_ptr, fp);
42 png_set_IHDR(png_ptr, info_ptr, img->i.width, img->i.height, 8,
43 PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
44 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
45 if (img->i.dpi) {
46 png_set_pHYs(png_ptr, info_ptr,
47 res_inch_to_m(img->i.dpi),
48 res_inch_to_m(img->i.dpi),
49 PNG_RESOLUTION_METER);
50 }
51 png_write_info(png_ptr, info_ptr);
52 png_set_packing(png_ptr);
53
54 for (y = 0; y < img->i.height; y++) {
55 row = ida_image_scanline(img, y);
56 png_write_rows(png_ptr, &row, 1);
57 }
58 png_write_end(png_ptr, info_ptr);
59 png_destroy_write_struct(&png_ptr, &info_ptr);
60 return 0;
61
62 oops:
63 fprintf(stderr,"can't save image: libpng error\n");
64 if (png_ptr)
65 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
66 return -1;
67 }
68
69 static struct ida_writer png_writer = {
70 label: "PNG",
71 ext: { "png", NULL},
72 write: png_write,
73 };
74
init_wr(void)75 static void __init init_wr(void)
76 {
77 write_register(&png_writer);
78 }
79