1 /**
2 ** to_png.c: Portable Network Graphics (PNG) converter part of project "hp2xx"
3 ** Michael Schmitz, schmitz@simul.biophys.uni-duesseldorf.de
4 ** Derived from: to_gif.c (GIF module; no longer supported due to copyright
5 ** problems with the GIF-internal LZW compression)
6 ** 94/08/22 V 1.00 MS started from scratch, using to_pbm.c and Tom Boutells
7 ** gd.c gifdraw module; simple merge of both modules :-)
8 ** (see gd.c and gifencod copyright notes below)
9 ** Bresnham line drawing and fonts: own hp2xx code used
10 ** already _before_ this routine is called.
11 **
12 ** 95/09/26 V 1.10 MS Major cleanup; removed unused code portions.
13 ** Routines used from gifdraw code:
14 ** gdImageCreate, gdImageColorAllocate, gdImageSetPixel,
15 ** gdImageBoundsSafe, gdImageGetPixel, gdImageGif,
16 ** gdImageDestroy.
17 ** (gdImageGif in turn uses routines from GIFEncode that
18 ** is part of the pbmplus package.
19 **
20 ** 97/11/26 V 1.0 MS Rewrite to libpng 0.96 using Tom Boutell's pixel
21 ** drawing primitives
22 **
23 **/
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include "bresnham.h"
28 #include "hp2xx.h"
29 #include "to_png.h"
30 #include "pendef.h"
31 #define GGE >>=
32 #define MAXOUTPUTROWS 70
33
34 #define PDNCOL 256
35
36 int pdImageColorAllocate(pdImagePtr, int, int, int);
37
PicBuf_to_PNG(const GEN_PAR * pg,const OUT_PAR * po)38 int PicBuf_to_PNG(const GEN_PAR * pg, const OUT_PAR * po)
39 {
40 FILE *fd;
41 int row_c, /*byte_c, */ x;
42 const RowBuf *row;
43 const PicBuf *pb;
44 int ppm[][3] = { {255, 255, 255}, {0, 0, 0} };
45 /*, {255,0,0}, {0,255,0},
46 {0,0,255},{0,255,255},{255,0,255},{255,255,0}};
47 */
48 int colour;
49
50 /**
51 ** gifdraw-parts
52 **/
53 pdImagePtr im;
54 int pdcol;
55
56 if (pg == NULL || po == NULL)
57 return ERROR;
58 pb = po->picbuf;
59 if (pb == NULL)
60 return ERROR;
61
62 if (!pg->quiet)
63 Eprintf("\nWriting PNG output: %s\n", po->outfile);
64 if (*po->outfile != '-') {
65
66 /*
67 #ifdef VAX
68 if ((fd = fopen(po->outfile, WRITE_BIN, "rfm=var", "mrs=512")) == NULL)
69 #else
70 */
71 if ((fd = fopen(po->outfile, WRITE_BIN)) == NULL)
72 /*
73 #endif
74 */
75 goto ERROR_EXIT;
76 } else
77 fd = stdout;
78
79 /**
80 ** create image structure
81 **/
82 im = pdImageCreate(pb->nc, pb->nr);
83
84 if (pb->depth > 1) {
85 /**
86 ** allocate some colors ( ?? eight colors supported by hp2xx ?? )
87 **/
88 for (colour = 0; colour < PDNCOL; colour++)
89 /* pdcol = pdImageColorAllocate(im, ppm[colour][0], ppm[colour][1],
90 ppm[colour][2]);
91 */
92 pdcol =
93 pdImageColorAllocate(im, pt.clut[colour][0],
94 pt.clut[colour][1],
95 pt.clut[colour][2]);
96 for (row_c = 0; row_c < pb->nr; row_c++) {
97 row = get_RowBuf(pb, pb->nr - row_c - 1);
98 if (row == NULL)
99 continue;
100
101 for (x = 0; x < pb->nc; x++) {
102 colour = index_from_RowBuf(row, x, pb);
103 pdImageSetPixel(im, x, row_c, colour);
104 }
105 if ((!pg->quiet) && (row_c % 10 == 0))
106 /* For the impatients among us ... */
107 Eprintf(".");
108 }
109 } else {
110 /**
111 ** allocate two colors ( ?? eight colors supported by hp2xx ?? )
112 **/
113 for (colour = 0; colour < 2; colour++)
114 pdcol =
115 pdImageColorAllocate(im, ppm[colour][0],
116 ppm[colour][1],
117 ppm[colour][2]);
118
119 for (row_c = 0; row_c < pb->nr; row_c++) {
120 row = get_RowBuf(pb, pb->nr - row_c - 1);
121 if (row == NULL)
122 continue;
123
124 for (x = 0; x < pb->nc; x++) {
125 colour = index_from_RowBuf(row, x, pb);
126 pdImageSetPixel(im, x, row_c, colour);
127 }
128
129 if ((!pg->quiet) && (row_c % 10 == 0))
130 /* For the impatients among us ... */
131 Eprintf(".");
132 }
133 }
134
135 pdImagePNG(im, fd);
136
137 pdImageDestroy(im);
138
139 fflush(fd);
140
141 if (!pg->quiet)
142 Eprintf("\n");
143 if (fd != stdout)
144 fclose(fd);
145 return 0;
146
147 ERROR_EXIT:
148 PError("write_PNG");
149 return ERROR;
150 }
151
152 /**
153 ** PNG image support routines, derived from:
154 **/
155
156 /* gd.c: implementation of the gifdraw module. Version 0.9.
157
158 Written by Tom Boutell, 5/94-6/94.
159 Copyright 1994, Cold Spring Harbor Labs.
160 Permission granted to use this code in any fashion provided
161 that this notice is retained and any alterations are
162 labeled as such. It is requested, but not required, that
163 you share extensions to this module with us so that we
164 can incorporate them into new versions. */
165 /**
166 ** PNG: use sy rows of sx pixels (instead of sx columns of sy pixels)
167 **/
168
pdImageCreate(sx,sy)169 pdImagePtr pdImageCreate(sx, sy)
170 int sx;
171 int sy;
172 {
173 int i;
174 pdImagePtr im;
175 im = (pdImage *) malloc(sizeof(pdImage));
176 im->pixels =
177 (unsigned char **) malloc(sizeof(unsigned char *) * sy);
178 for (i = 0; (i < sy); i++) {
179 im->pixels[i] = (unsigned char *) calloc((size_t) sx,
180 sizeof(unsigned
181 char));
182 }
183 im->sx = sx;
184 im->sy = sy;
185 im->colorsTotal = 0;
186 im->transparent = (-1);
187 return im;
188 }
189
pdImageDestroy(im)190 void pdImageDestroy(im)
191 pdImagePtr im;
192 {
193 int i;
194 for (i = 0; (i < im->sy); i++) {
195 free(im->pixels[i]);
196 }
197 free(im->pixels);
198 free(im);
199 }
200
pdImageColorAllocate(im,r,g,b)201 int pdImageColorAllocate(im, r, g, b)
202 pdImagePtr im;
203 int r;
204 int g;
205 int b;
206 {
207 int i;
208 int ct = (-1);
209 for (i = 0; (i < (im->colorsTotal)); i++) {
210 if (im->open[i]) {
211 ct = i;
212 break;
213 }
214 }
215 if (ct == (-1)) {
216 ct = im->colorsTotal;
217 if (ct == pdMaxColors) {
218 return -1;
219 }
220 im->colorsTotal++;
221 }
222 im->red[ct] = r;
223 im->green[ct] = g;
224 im->blue[ct] = b;
225 im->open[ct] = 0;
226 return ct;
227 }
228
pdImageColorTransparent(im,color)229 void pdImageColorTransparent(im, color)
230 pdImagePtr im;
231 unsigned char color;
232 {
233 im->transparent = color;
234 }
235
pdImageSetPixel(im,x,y,color)236 void pdImageSetPixel(im, x, y, color)
237 pdImagePtr im;
238 int x;
239 int y;
240 unsigned char color;
241 {
242 if (pdImageBoundsSafe(im, x, y)) {
243 im->pixels[y][x] = color;
244 }
245 }
246
pdImageGetPixel(im,x,y)247 int pdImageGetPixel(im, x, y)
248 pdImagePtr im;
249 int x;
250 int y;
251 {
252 if (pdImageBoundsSafe(im, x, y)) {
253 return im->pixels[y][x];
254 } else {
255 return 0;
256 }
257 }
258
pdImageBoundsSafe(im,x,y)259 int pdImageBoundsSafe(im, x, y)
260 pdImagePtr im;
261 int x;
262 int y;
263 {
264 return (!(((y < 0) || (y >= im->sy)) ||
265 ((x < 0) || (x >= im->sx))));
266 }
267