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"
8 28994509 2004-04-21 devnull /* Convert image to a single channel, one byte per pixel */
12 28994509 2004-04-21 devnull notrans(ulong chan)
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;
22 28994509 2004-04-21 devnull return 0;
27 28994509 2004-04-21 devnull easycase(ulong chan)
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;
36 28994509 2004-04-21 devnull return 0;
40 28994509 2004-04-21 devnull * Convert to one byte per pixel, RGBV or grey, depending
45 28994509 2004-04-21 devnull load(Image *image, Memimage *memimage)
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;
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;
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;
63 28994509 2004-04-21 devnull dx = Dx(r);
64 28994509 2004-04-21 devnull dy = Dy(r);
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.
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);
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;
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){
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;
104 28994509 2004-04-21 devnull ri.chandesc = CRGB;
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];
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);
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++;
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++;
141 28994509 2004-04-21 devnull case ARGB32:
142 28994509 2004-04-21 devnull for(i=0; i<ri.chanlen; i++){
144 28994509 2004-04-21 devnull *q2++ = *p++;
145 28994509 2004-04-21 devnull *q1++ = *p++;
146 28994509 2004-04-21 devnull *q0++ = *p++;
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);
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;
166 28994509 2004-04-21 devnull onechan(Image *i)
168 28994509 2004-04-21 devnull uchar *data;
169 28994509 2004-04-21 devnull Image *ni;
171 28994509 2004-04-21 devnull if(notrans(i->chan))
172 28994509 2004-04-21 devnull return i;
174 28994509 2004-04-21 devnull if(easycase(i->chan))
175 28994509 2004-04-21 devnull data = load(i, nil);
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);
185 28994509 2004-04-21 devnull if(data == nil)
186 28994509 2004-04-21 devnull return nil;
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;
194 28994509 2004-04-21 devnull free(data);
195 28994509 2004-04-21 devnull return ni;
198 28994509 2004-04-21 devnull Memimage*
199 28994509 2004-04-21 devnull memonechan(Memimage *i)
201 28994509 2004-04-21 devnull uchar *data;
202 28994509 2004-04-21 devnull Memimage *ni;
204 28994509 2004-04-21 devnull if(notrans(i->chan))
205 28994509 2004-04-21 devnull return i;
207 28994509 2004-04-21 devnull if(easycase(i->chan))
208 28994509 2004-04-21 devnull data = load(nil, i);
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);
218 28994509 2004-04-21 devnull if(data == nil)
219 28994509 2004-04-21 devnull return nil;
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;
227 28994509 2004-04-21 devnull free(data);
228 28994509 2004-04-21 devnull return ni;