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