Blame


1 28994509 2004-04-21 devnull #include <u.h>
2 28994509 2004-04-21 devnull #include <libc.h>
3 28994509 2004-04-21 devnull #include <draw.h>
4 28994509 2004-04-21 devnull #include <memdraw.h>
5 28994509 2004-04-21 devnull #include <bio.h>
6 28994509 2004-04-21 devnull #include "imagefile.h"
7 28994509 2004-04-21 devnull
8 28994509 2004-04-21 devnull #define MAXLINE 70
9 28994509 2004-04-21 devnull
10 28994509 2004-04-21 devnull /*
11 28994509 2004-04-21 devnull * Write data
12 28994509 2004-04-21 devnull */
13 28994509 2004-04-21 devnull static
14 28994509 2004-04-21 devnull char*
15 28994509 2004-04-21 devnull writedata(Biobuf *fd, Image *image, Memimage *memimage)
16 28994509 2004-04-21 devnull {
17 28994509 2004-04-21 devnull char *err;
18 28994509 2004-04-21 devnull uchar *data;
19 28994509 2004-04-21 devnull int i, x, y, ndata, depth, col, pix, xmask, pmask;
20 28994509 2004-04-21 devnull ulong chan;
21 28994509 2004-04-21 devnull Rectangle r;
22 28994509 2004-04-21 devnull
23 28994509 2004-04-21 devnull if(memimage != nil){
24 28994509 2004-04-21 devnull r = memimage->r;
25 28994509 2004-04-21 devnull depth = memimage->depth;
26 28994509 2004-04-21 devnull chan = memimage->chan;
27 28994509 2004-04-21 devnull }else{
28 28994509 2004-04-21 devnull r = image->r;
29 28994509 2004-04-21 devnull depth = image->depth;
30 28994509 2004-04-21 devnull chan = image->chan;
31 28994509 2004-04-21 devnull }
32 28994509 2004-04-21 devnull
33 28994509 2004-04-21 devnull /*
34 28994509 2004-04-21 devnull * Read image data into memory
35 28994509 2004-04-21 devnull * potentially one extra byte on each end of each scan line
36 28994509 2004-04-21 devnull */
37 28994509 2004-04-21 devnull ndata = Dy(r)*(2+Dx(r)*depth/8);
38 28994509 2004-04-21 devnull data = malloc(ndata);
39 28994509 2004-04-21 devnull if(data == nil)
40 28994509 2004-04-21 devnull return "WritePPM: malloc failed";
41 28994509 2004-04-21 devnull if(memimage != nil)
42 28994509 2004-04-21 devnull ndata = unloadmemimage(memimage, r, data, ndata);
43 28994509 2004-04-21 devnull else
44 28994509 2004-04-21 devnull ndata = unloadimage(image, r, data, ndata);
45 28994509 2004-04-21 devnull if(ndata < 0){
46 28994509 2004-04-21 devnull err = malloc(ERRMAX);
47 28994509 2004-04-21 devnull if(err == nil)
48 28994509 2004-04-21 devnull return "WritePPM: malloc failed";
49 28994509 2004-04-21 devnull snprint(err, ERRMAX, "WriteGIF: %r");
50 28994509 2004-04-21 devnull free(data);
51 28994509 2004-04-21 devnull return err;
52 28994509 2004-04-21 devnull }
53 28994509 2004-04-21 devnull
54 28994509 2004-04-21 devnull /* Encode and emit the data */
55 28994509 2004-04-21 devnull col = 0;
56 28994509 2004-04-21 devnull switch(chan){
57 28994509 2004-04-21 devnull case GREY1:
58 28994509 2004-04-21 devnull case GREY2:
59 28994509 2004-04-21 devnull case GREY4:
60 28994509 2004-04-21 devnull pmask = (1<<depth)-1;
61 28994509 2004-04-21 devnull xmask = 7>>drawlog2[depth];
62 28994509 2004-04-21 devnull for(y=r.min.y; y<r.max.y; y++){
63 28994509 2004-04-21 devnull i = (y-r.min.y)*bytesperline(r, depth);
64 28994509 2004-04-21 devnull for(x=r.min.x; x<r.max.x; x++){
65 28994509 2004-04-21 devnull pix = (data[i]>>depth*((xmask-x)&xmask))&pmask;
66 28994509 2004-04-21 devnull if(((x+1)&xmask) == 0)
67 28994509 2004-04-21 devnull i++;
68 28994509 2004-04-21 devnull col += Bprint(fd, "%d ", pix);
69 28994509 2004-04-21 devnull if(col >= MAXLINE-(2+1)){
70 28994509 2004-04-21 devnull Bprint(fd, "\n");
71 28994509 2004-04-21 devnull col = 0;
72 28994509 2004-04-21 devnull }else
73 28994509 2004-04-21 devnull col += Bprint(fd, " ");
74 28994509 2004-04-21 devnull }
75 28994509 2004-04-21 devnull }
76 28994509 2004-04-21 devnull break;
77 28994509 2004-04-21 devnull case GREY8:
78 28994509 2004-04-21 devnull for(i=0; i<ndata; i++){
79 28994509 2004-04-21 devnull col += Bprint(fd, "%d ", data[i]);
80 28994509 2004-04-21 devnull if(col >= MAXLINE-(4+1)){
81 28994509 2004-04-21 devnull Bprint(fd, "\n");
82 28994509 2004-04-21 devnull col = 0;
83 28994509 2004-04-21 devnull }else
84 28994509 2004-04-21 devnull col += Bprint(fd, " ");
85 28994509 2004-04-21 devnull }
86 28994509 2004-04-21 devnull break;
87 28994509 2004-04-21 devnull case RGB24:
88 28994509 2004-04-21 devnull for(i=0; i<ndata; i+=3){
89 28994509 2004-04-21 devnull col += Bprint(fd, "%d %d %d", data[i+2], data[i+1], data[i]);
90 28994509 2004-04-21 devnull if(col >= MAXLINE-(4+4+4+1)){
91 28994509 2004-04-21 devnull Bprint(fd, "\n");
92 28994509 2004-04-21 devnull col = 0;
93 28994509 2004-04-21 devnull }else
94 28994509 2004-04-21 devnull col += Bprint(fd, " ");
95 28994509 2004-04-21 devnull }
96 28994509 2004-04-21 devnull break;
97 28994509 2004-04-21 devnull default:
98 28994509 2004-04-21 devnull return "WritePPM: can't handle channel type";
99 28994509 2004-04-21 devnull }
100 28994509 2004-04-21 devnull
101 28994509 2004-04-21 devnull return nil;
102 28994509 2004-04-21 devnull }
103 28994509 2004-04-21 devnull
104 28994509 2004-04-21 devnull static
105 28994509 2004-04-21 devnull char*
106 28994509 2004-04-21 devnull writeppm0(Biobuf *fd, Image *image, Memimage *memimage, Rectangle r, int chan, char *comment)
107 28994509 2004-04-21 devnull {
108 28994509 2004-04-21 devnull char *err;
109 28994509 2004-04-21 devnull
110 28994509 2004-04-21 devnull switch(chan){
111 28994509 2004-04-21 devnull case GREY1:
112 28994509 2004-04-21 devnull Bprint(fd, "P1\n");
113 28994509 2004-04-21 devnull break;
114 28994509 2004-04-21 devnull case GREY2:
115 28994509 2004-04-21 devnull case GREY4:
116 28994509 2004-04-21 devnull case GREY8:
117 28994509 2004-04-21 devnull Bprint(fd, "P2\n");
118 28994509 2004-04-21 devnull break;
119 28994509 2004-04-21 devnull case RGB24:
120 28994509 2004-04-21 devnull Bprint(fd, "P3\n");
121 28994509 2004-04-21 devnull break;
122 28994509 2004-04-21 devnull default:
123 28994509 2004-04-21 devnull return "WritePPM: can't handle channel type";
124 28994509 2004-04-21 devnull }
125 28994509 2004-04-21 devnull
126 28994509 2004-04-21 devnull if(comment!=nil && comment[0]!='\0'){
127 28994509 2004-04-21 devnull Bprint(fd, "# %s", comment);
128 28994509 2004-04-21 devnull if(comment[strlen(comment)-1] != '\n')
129 28994509 2004-04-21 devnull Bprint(fd, "\n");
130 28994509 2004-04-21 devnull }
131 28994509 2004-04-21 devnull Bprint(fd, "%d %d\n", Dx(r), Dy(r));
132 28994509 2004-04-21 devnull
133 28994509 2004-04-21 devnull /* maximum pixel value */
134 28994509 2004-04-21 devnull switch(chan){
135 28994509 2004-04-21 devnull case GREY2:
136 28994509 2004-04-21 devnull Bprint(fd, "%d\n", 3);
137 28994509 2004-04-21 devnull break;
138 28994509 2004-04-21 devnull case GREY4:
139 28994509 2004-04-21 devnull Bprint(fd, "%d\n", 15);
140 28994509 2004-04-21 devnull break;
141 28994509 2004-04-21 devnull case GREY8:
142 28994509 2004-04-21 devnull case RGB24:
143 28994509 2004-04-21 devnull Bprint(fd, "%d\n", 255);
144 28994509 2004-04-21 devnull break;
145 28994509 2004-04-21 devnull }
146 28994509 2004-04-21 devnull
147 28994509 2004-04-21 devnull err = writedata(fd, image, memimage);
148 28994509 2004-04-21 devnull
149 28994509 2004-04-21 devnull Bprint(fd, "\n");
150 28994509 2004-04-21 devnull Bflush(fd);
151 28994509 2004-04-21 devnull return err;
152 28994509 2004-04-21 devnull }
153 28994509 2004-04-21 devnull
154 28994509 2004-04-21 devnull char*
155 28994509 2004-04-21 devnull writeppm(Biobuf *fd, Image *image, char *comment)
156 28994509 2004-04-21 devnull {
157 28994509 2004-04-21 devnull return writeppm0(fd, image, nil, image->r, image->chan, comment);
158 28994509 2004-04-21 devnull }
159 28994509 2004-04-21 devnull
160 28994509 2004-04-21 devnull char*
161 28994509 2004-04-21 devnull memwriteppm(Biobuf *fd, Memimage *memimage, char *comment)
162 28994509 2004-04-21 devnull {
163 28994509 2004-04-21 devnull return writeppm0(fd, nil, memimage, memimage->r, memimage->chan, comment);
164 28994509 2004-04-21 devnull }