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 /* Convert image to a single channel, one byte per pixel */
9 28994509 2004-04-21 devnull
10 28994509 2004-04-21 devnull static
11 28994509 2004-04-21 devnull int
12 28994509 2004-04-21 devnull notrans(ulong chan)
13 28994509 2004-04-21 devnull {
14 28994509 2004-04-21 devnull switch(chan){
15 28994509 2004-04-21 devnull case GREY1:
16 28994509 2004-04-21 devnull case GREY2:
17 28994509 2004-04-21 devnull case GREY4:
18 28994509 2004-04-21 devnull case CMAP8:
19 28994509 2004-04-21 devnull case GREY8:
20 28994509 2004-04-21 devnull return 1;
21 28994509 2004-04-21 devnull }
22 28994509 2004-04-21 devnull return 0;
23 28994509 2004-04-21 devnull }
24 28994509 2004-04-21 devnull
25 28994509 2004-04-21 devnull static
26 28994509 2004-04-21 devnull int
27 28994509 2004-04-21 devnull easycase(ulong chan)
28 28994509 2004-04-21 devnull {
29 28994509 2004-04-21 devnull switch(chan){
30 28994509 2004-04-21 devnull case RGB16:
31 28994509 2004-04-21 devnull case RGB24:
32 28994509 2004-04-21 devnull case RGBA32:
33 28994509 2004-04-21 devnull case ARGB32:
34 28994509 2004-04-21 devnull return 1;
35 28994509 2004-04-21 devnull }
36 28994509 2004-04-21 devnull return 0;
37 28994509 2004-04-21 devnull }
38 28994509 2004-04-21 devnull
39 28994509 2004-04-21 devnull /*
40 28994509 2004-04-21 devnull * Convert to one byte per pixel, RGBV or grey, depending
41 28994509 2004-04-21 devnull */
42 28994509 2004-04-21 devnull
43 28994509 2004-04-21 devnull static
44 28994509 2004-04-21 devnull uchar*
45 28994509 2004-04-21 devnull load(Image *image, Memimage *memimage)
46 28994509 2004-04-21 devnull {
47 28994509 2004-04-21 devnull uchar *data, *p, *q0, *q1, *q2;
48 28994509 2004-04-21 devnull uchar *rgbv;
49 28994509 2004-04-21 devnull int depth, ndata, dx, dy, i, v;
50 28994509 2004-04-21 devnull ulong chan, pixel;
51 28994509 2004-04-21 devnull Rectangle r;
52 28994509 2004-04-21 devnull Rawimage ri, *nri;
53 28994509 2004-04-21 devnull
54 28994509 2004-04-21 devnull if(memimage == nil){
55 28994509 2004-04-21 devnull r = image->r;
56 28994509 2004-04-21 devnull depth = image->depth;
57 28994509 2004-04-21 devnull chan = image->chan;
58 28994509 2004-04-21 devnull }else{
59 28994509 2004-04-21 devnull r = memimage->r;
60 28994509 2004-04-21 devnull depth = memimage->depth;
61 28994509 2004-04-21 devnull chan = memimage->chan;
62 28994509 2004-04-21 devnull }
63 28994509 2004-04-21 devnull dx = Dx(r);
64 28994509 2004-04-21 devnull dy = Dy(r);
65 28994509 2004-04-21 devnull
66 28994509 2004-04-21 devnull /*
67 28994509 2004-04-21 devnull * Read image data into memory
68 28994509 2004-04-21 devnull * potentially one extra byte on each end of each scan line.
69 28994509 2004-04-21 devnull */
70 28994509 2004-04-21 devnull ndata = dy*(2+bytesperline(r, depth));
71 28994509 2004-04-21 devnull data = malloc(ndata);
72 28994509 2004-04-21 devnull if(data == nil)
73 28994509 2004-04-21 devnull return nil;
74 28994509 2004-04-21 devnull if(memimage != nil)
75 28994509 2004-04-21 devnull ndata = unloadmemimage(memimage, r, data, ndata);
76 28994509 2004-04-21 devnull else
77 28994509 2004-04-21 devnull ndata = unloadimage(image, r, data, ndata);
78 28994509 2004-04-21 devnull if(ndata < 0){
79 28994509 2004-04-21 devnull werrstr("onechan: %r");
80 28994509 2004-04-21 devnull free(data);
81 28994509 2004-04-21 devnull return nil;
82 28994509 2004-04-21 devnull }
83 28994509 2004-04-21 devnull
84 28994509 2004-04-21 devnull /*
85 28994509 2004-04-21 devnull * Repack
86 28994509 2004-04-21 devnull */
87 28994509 2004-04-21 devnull memset(&ri, 0, sizeof(ri));
88 28994509 2004-04-21 devnull ri.r = r;
89 28994509 2004-04-21 devnull ri.cmap = nil;
90 28994509 2004-04-21 devnull ri.cmaplen = 0;
91 28994509 2004-04-21 devnull ri.nchans = 3;
92 28994509 2004-04-21 devnull ri.chanlen = dx*dy;
93 28994509 2004-04-21 devnull ri.chans[0] = malloc(ri.chanlen);
94 28994509 2004-04-21 devnull ri.chans[1] = malloc(ri.chanlen);
95 28994509 2004-04-21 devnull ri.chans[2] = malloc(ri.chanlen);
96 28994509 2004-04-21 devnull if(ri.chans[0]==nil || ri.chans[1]==nil || ri.chans[2]==nil){
97 28994509 2004-04-21 devnull Err:
98 28994509 2004-04-21 devnull free(ri.chans[0]);
99 28994509 2004-04-21 devnull free(ri.chans[1]);
100 28994509 2004-04-21 devnull free(ri.chans[2]);
101 28994509 2004-04-21 devnull free(data);
102 28994509 2004-04-21 devnull return nil;
103 28994509 2004-04-21 devnull }
104 28994509 2004-04-21 devnull ri.chandesc = CRGB;
105 28994509 2004-04-21 devnull
106 28994509 2004-04-21 devnull p = data;
107 28994509 2004-04-21 devnull q0 = ri.chans[0];
108 28994509 2004-04-21 devnull q1 = ri.chans[1];
109 28994509 2004-04-21 devnull q2 = ri.chans[2];
110 28994509 2004-04-21 devnull
111 28994509 2004-04-21 devnull switch(chan){
112 28994509 2004-04-21 devnull default:
113 28994509 2004-04-21 devnull werrstr("can't handle image type 0x%lux", chan);
114 28994509 2004-04-21 devnull goto Err;
115 28994509 2004-04-21 devnull case RGB16:
116 28994509 2004-04-21 devnull for(i=0; i<ri.chanlen; i++, p+=2){
117 28994509 2004-04-21 devnull pixel = (p[1]<<8)|p[0]; /* rrrrrggg gggbbbbb */
118 28994509 2004-04-21 devnull v = (pixel & 0xF800) >> 8;
119 28994509 2004-04-21 devnull *q0++ = v | (v>>5);
120 28994509 2004-04-21 devnull v = (pixel & 0x07E0) >> 3;
121 28994509 2004-04-21 devnull *q1++ = v | (v>>6);
122 28994509 2004-04-21 devnull v = (pixel & 0x001F) << 3;
123 28994509 2004-04-21 devnull *q2++ = v | (v>>5);
124 28994509 2004-04-21 devnull }
125 28994509 2004-04-21 devnull break;
126 28994509 2004-04-21 devnull case RGB24:
127 28994509 2004-04-21 devnull for(i=0; i<ri.chanlen; i++){
128 28994509 2004-04-21 devnull *q2++ = *p++;
129 28994509 2004-04-21 devnull *q1++ = *p++;
130 28994509 2004-04-21 devnull *q0++ = *p++;
131 28994509 2004-04-21 devnull }
132 28994509 2004-04-21 devnull break;
133 28994509 2004-04-21 devnull case RGBA32:
134 28994509 2004-04-21 devnull for(i=0; i<ri.chanlen; i++){
135 28994509 2004-04-21 devnull *q2++ = *p++;
136 28994509 2004-04-21 devnull *q1++ = *p++;
137 28994509 2004-04-21 devnull *q0++ = *p++;
138 28994509 2004-04-21 devnull p++;
139 28994509 2004-04-21 devnull }
140 28994509 2004-04-21 devnull break;
141 28994509 2004-04-21 devnull case ARGB32:
142 28994509 2004-04-21 devnull for(i=0; i<ri.chanlen; i++){
143 28994509 2004-04-21 devnull p++;
144 28994509 2004-04-21 devnull *q2++ = *p++;
145 28994509 2004-04-21 devnull *q1++ = *p++;
146 28994509 2004-04-21 devnull *q0++ = *p++;
147 28994509 2004-04-21 devnull }
148 28994509 2004-04-21 devnull break;
149 28994509 2004-04-21 devnull }
150 28994509 2004-04-21 devnull
151 28994509 2004-04-21 devnull rgbv = nil;
152 28994509 2004-04-21 devnull nri = torgbv(&ri, 1);
153 28994509 2004-04-21 devnull if(nri != nil){
154 28994509 2004-04-21 devnull rgbv = nri->chans[0];
155 28994509 2004-04-21 devnull free(nri);
156 28994509 2004-04-21 devnull }
157 28994509 2004-04-21 devnull
158 28994509 2004-04-21 devnull free(ri.chans[0]);
159 28994509 2004-04-21 devnull free(ri.chans[1]);
160 28994509 2004-04-21 devnull free(ri.chans[2]);
161 28994509 2004-04-21 devnull free(data);
162 28994509 2004-04-21 devnull return rgbv;
163 28994509 2004-04-21 devnull }
164 28994509 2004-04-21 devnull
165 28994509 2004-04-21 devnull Image*
166 28994509 2004-04-21 devnull onechan(Image *i)
167 28994509 2004-04-21 devnull {
168 28994509 2004-04-21 devnull uchar *data;
169 28994509 2004-04-21 devnull Image *ni;
170 28994509 2004-04-21 devnull
171 28994509 2004-04-21 devnull if(notrans(i->chan))
172 28994509 2004-04-21 devnull return i;
173 28994509 2004-04-21 devnull
174 28994509 2004-04-21 devnull if(easycase(i->chan))
175 28994509 2004-04-21 devnull data = load(i, nil);
176 28994509 2004-04-21 devnull else{
177 28994509 2004-04-21 devnull ni = allocimage(display, i->r, RGB24, 0, DNofill);
178 28994509 2004-04-21 devnull if(ni == nil)
179 28994509 2004-04-21 devnull return ni;
180 28994509 2004-04-21 devnull draw(ni, ni->r, i, nil, i->r.min);
181 28994509 2004-04-21 devnull data = load(ni, nil);
182 28994509 2004-04-21 devnull freeimage(ni);
183 28994509 2004-04-21 devnull }
184 28994509 2004-04-21 devnull
185 28994509 2004-04-21 devnull if(data == nil)
186 28994509 2004-04-21 devnull return nil;
187 28994509 2004-04-21 devnull
188 28994509 2004-04-21 devnull ni = allocimage(display, i->r, CMAP8, 0, DNofill);
189 28994509 2004-04-21 devnull if(ni != nil)
190 28994509 2004-04-21 devnull if(loadimage(ni, ni->r, data, Dx(ni->r)*Dy(ni->r)) < 0){
191 28994509 2004-04-21 devnull freeimage(ni);
192 28994509 2004-04-21 devnull ni = nil;
193 28994509 2004-04-21 devnull }
194 28994509 2004-04-21 devnull free(data);
195 28994509 2004-04-21 devnull return ni;
196 28994509 2004-04-21 devnull }
197 28994509 2004-04-21 devnull
198 28994509 2004-04-21 devnull Memimage*
199 28994509 2004-04-21 devnull memonechan(Memimage *i)
200 28994509 2004-04-21 devnull {
201 28994509 2004-04-21 devnull uchar *data;
202 28994509 2004-04-21 devnull Memimage *ni;
203 28994509 2004-04-21 devnull
204 28994509 2004-04-21 devnull if(notrans(i->chan))
205 28994509 2004-04-21 devnull return i;
206 28994509 2004-04-21 devnull
207 28994509 2004-04-21 devnull if(easycase(i->chan))
208 28994509 2004-04-21 devnull data = load(nil, i);
209 28994509 2004-04-21 devnull else{
210 28994509 2004-04-21 devnull ni = allocmemimage(i->r, RGB24);
211 28994509 2004-04-21 devnull if(ni == nil)
212 28994509 2004-04-21 devnull return ni;
213 28994509 2004-04-21 devnull memimagedraw(ni, ni->r, i, i->r.min, nil, ZP, S);
214 28994509 2004-04-21 devnull data = load(nil, ni);
215 28994509 2004-04-21 devnull freememimage(ni);
216 28994509 2004-04-21 devnull }
217 28994509 2004-04-21 devnull
218 28994509 2004-04-21 devnull if(data == nil)
219 28994509 2004-04-21 devnull return nil;
220 28994509 2004-04-21 devnull
221 28994509 2004-04-21 devnull ni = allocmemimage(i->r, CMAP8);
222 28994509 2004-04-21 devnull if(ni != nil)
223 28994509 2004-04-21 devnull if(loadmemimage(ni, ni->r, data, Dx(ni->r)*Dy(ni->r)) < 0){
224 28994509 2004-04-21 devnull freememimage(ni);
225 28994509 2004-04-21 devnull ni = nil;
226 28994509 2004-04-21 devnull }
227 28994509 2004-04-21 devnull free(data);
228 28994509 2004-04-21 devnull return ni;
229 28994509 2004-04-21 devnull }