1 | | |
2 | | |
3 | | |
4 | | |
5 | | |
6 | | |
7 | | |
8 | | |
9 | | |
10 | | |
11 | | |
12 | | |
13 | | |
14 | | |
15 | | |
16 | | |
17 | | |
18 | | |
19 | | |
20 | | |
21 | | |
22 | | |
23 | | |
24 | | |
25 | | |
26 | | |
27 | | |
28 | | |
29 | | |
30 | | |
31 | | |
32 | | |
33 | | |
34 | | |
35 | | |
36 | | |
37 | | |
38 | | |
39 | | |
40 | | |
41 | | |
42 | | |
43 | | |
44 | | |
45 | | |
46 | | |
47 | | |
48 | | |
49 | | |
50 | | |
51 | | |
52 | | |
53 | | |
54 | | |
55 | | |
56 | | |
57 | | |
58 | | |
59 | | |
60 | | |
61 | | |
62 | | |
63 | | |
64 | | |
65 | | |
66 | | |
67 | | |
68 | | |
69 | | |
70 | | |
71 | | |
72 | | |
73 | | |
74 | | |
75 | | |
76 | | |
77 | | |
78 | | |
79 | | |
80 | | |
81 | | |
82 | | |
83 | | |
84 | | |
85 | | |
86 | | |
87 | | |
88 | | |
89 | | |
90 | | |
91 | | |
92 | | |
93 | | |
94 | | |
95 | | |
96 | | |
97 | | |
98 | | |
99 | | |
100 | | |
101 | | |
102 | | |
103 | | |
104 | | |
105 | | |
106 | | |
107 | | |
108 | | |
109 | | |
110 | | |
111 | | |
112 | | |
113 | | |
114 | | |
115 | | |
116 | | |
117 | | |
118 | | |
119 | | |
120 | | |
121 | | |
122 | | |
123 | | |
124 | | |
125 | | |
126 | | |
127 | | |
128 | | |
129 | | |
130 | | |
131 | | |
132 | | |
133 | | |
134 | | |
135 | | |
136 | | |
137 | | |
138 | | |
139 | | |
140 | | |
141 | | |
142 | | |
143 | | |
144 | | |
145 | | |
146 | | |
147 | | |
148 | | |
149 | | |
150 | | |
151 | | |
152 | | |
153 | | |
154 | | |
155 | | |
156 | | |
157 | | |
158 | | |
159 | | |
160 | | |
161 | | |
162 | | |
163 | | |
164 | | |
165 | | |
166 | | |
167 | | |
168 | | |
169 | | |
170 | | |
171 | | |
172 | | |
173 | | |
174 | | |
175 | | |
176 | | |
177 | | |
178 | | |
179 | | |
180 | | |
181 | | |
182 | | |
183 | | |
184 | | |
185 | | |
186 | | |
187 | | |
188 | | |
189 | | |
190 | | |
191 | | |
192 | | |
193 | | |
194 | | |
195 | | |
196 | | |
197 | | |
198 | | |
199 | | |
200 | | |
201 | | |
202 | | |
203 | | |
204 | | |
205 | | |
206 | | |
207 | | |
208 | | |
209 | | |
210 | | |
211 | | |
212 | | |
213 | | |
214 | | |
215 | | |
216 | | |
217 | | |
218 | | |
219 | | |
220 | | |
221 | | |
222 | | |
223 | | |
224 | | |
225 | | |
226 | | |
227 | | |
228 | | |
229 | | |
230 | | |
231 | | |
232 | | |
233 | | |
234 | | |
235 | | |
236 | | |
237 | | |
238 | | |
239 | | |
240 | | |
241 | | |
242 | | |
243 | | |
244 | | |
245 | | |
246 | | |
247 | | |
248 | | |
249 | | |
250 | | |
251 | | |
252 | | |
253 | | |
254 | | |
255 | | |
256 | | |
257 | | |
258 | | |
259 | | |
260 | | |
261 | | |
262 | | |
263 | | |
264 | | |
265 | | |
266 | | |
267 | | |
268 | | |
269 | | |
270 | | |
271 | | |
272 | | |
273 | | |
274 | | |
275 | | |
276 | | |
277 | | |
278 | | |
279 | | |
280 | | |
281 | | |
282 | | |
283 | | |
284 | | |
285 | | |
286 | | |
287 | | |
288 | | |
289 | | |
290 | | |
291 | | |
292 | | |
293 | | |
294 | | |
295 | | |
296 | | |
297 | | |
298 | | |
299 | | |
300 | | |
301 | | |
302 | | |
303 | | |
304 | | |
305 | | |
306 | | |
307 | | |
308 | | |
309 | | |
310 | | |
311 | | |
312 | | |
313 | | |
314 | | |
315 | | |
316 | | |
317 | | |
318 | | |
319 | | |
320 | | |
321 | | |
322 | | |
323 | | |
324 | | |
325 | | |
326 | | |
327 | | |
328 | | |
329 | | |
330 | | |
331 | | |
332 | | |
333 | | |
334 | | |
335 | | |
336 | | |
337 | | |
338 | | |
339 | | |
340 | | |
341 | | |
342 | | |
343 | | |
344 | | |
345 | | |
346 | | |
347 | | |
348 | | |
349 | | |
350 | | |
351 | | |
352 | | |
353 | | |
354 | | |
355 | | |
356 | | |
357 | | |
358 | | |
359 | | |
360 | | |
361 | | |
362 | | |
363 | | |
364 | | |
365 | | |
366 | | |
367 | | |
368 | | |
369 | | |
370 | | |
371 | | |
372 | | |
373 | | |
374 | | |
375 | | |
376 | | |
377 | | |
378 | | |
379 | | |
380 | | |
381 | | |
382 | | |
383 | | |
384 | | |
385 | | |
386 | | |
387 | | |
388 | | |
389 | | |
390 | | |
391 | | |
392 | | |
393 | | |
394 | | |
395 | | |
396 | | |
397 | | |
398 | | |
399 | | |
400 | | |
401 | | |
402 | | |
403 | | |
404 | | |
405 | | |
406 | | |
407 | | |
408 | | |
409 | | |
410 | | |
411 | | |
412 | | |
413 | | |
414 | | |
415 | | |
416 | | |
417 | | |
418 | | |
419 | | |
420 | | |
421 | | |
422 | | |
| | | | | | | | static unsigned char swap_bits[256] = | { 0,128,64,192,32,160,96,224,16,144,80,208,48,176,112, | 240,8,136,72,200,40,168,104,232,24,152,88,216,56,184, | 120,248,4,132,68,196,36,164,100,228,20,148,84,212,52, | 180,116,244,12,140,76,204,44,172,108,236,28,156,92,220, | 60,188,124,252,2,130,66,194,34,162,98,226,18,146,82, | 210,50,178,114,242,10,138,74,202,42,170,106,234,26,154, | 90,218,58,186,122,250,6,134,70,198,38,166,102,230,22, | 150,86,214,54,182,118,246,14,142,78,206,46,174,110,238, | 30,158,94,222,62,190,126,254,1,129,65,193,33,161,97, | 225,17,145,81,209,49,177,113,241,9,137,73,201,41,169, | 105,233,25,153,89,217,57,185,121,249,5,133,69,197,37, | 165,101,229,21,149,85,213,53,181,117,245,13,141,77,205, | 45,173,109,237,29,157,93,221,61,189,125,253,3,131,67, | 195,35,163,99,227,19,147,83,211,51,179,115,243,11,139, | 75,203,43,171,107,235,27,155,91,219,59,187,123,251,7, | 135,71,199,39,167,103,231,23,151,87,215,55,183,119,247, | 15,143,79,207,47,175,111,239,31,159,95,223,63,191,127,255}; | | | static void encode_truecolor_24_rgb_swapped( rgb_group *s, | unsigned char *d, | int q, int w ) | { | while(q--) | { | *(d++) = s->b; | *(d++) = s->g; | *(d++) = (s++)->r; | } | } | | static void encode_truecolor_24_rgb( rgb_group *s, | unsigned char *d, | int q, int w ) | { | MEMCPY(d,(unsigned char *)s,q); | } | | static void encode_truecolor_24_rgb_al32_swapped( rgb_group *s, | unsigned char *d, | int q, int w ) | { | int l; | while(q) | { | l=w; | while(l--) | { | *(d++) = s->b; | *(d++) = s->g; | *(d++) = (s++)->r; | q--; | } | d += (4-((w*3)&3))&3; | } | } | | static void encode_truecolor_24_rgb_al32( rgb_group *s, | unsigned char *d, | int q, int w ) | { | int l; | while(q) | { | for(l=0; l<(q/w)/3; l++) | { | MEMCPY(d,(unsigned char *)s,w*3); | d += (w*3+3)&~3; | } | } | } | | | #define encode_truecolor_24_bgr encode_truecolor_24_rgb_swapped | #define encode_truecolor_24_bgr_swapped encode_truecolor_24_rgb | #define encode_truecolor_24_bgr_al32 encode_truecolor_24_rgb_al32_swapped | #define encode_truecolor_24_bgr_al32_swapped encode_truecolor_24_rgb_al32 | | static void encode_truecolor_32_argb_swapped( rgb_group *s, | unsigned char *d, | int q,int w ) | { | int *dp = (int *)d; | #if PIKE_BYTEORDER==1234 | while(q--){ *(dp++) = (s->r<<16) | (s->g<<8) | (s)->b;s++;} | #else | while(q--){ *(dp++) = ((s->r) | (s->g<<8) | (s)->b<<16)<<8;s++;} | #endif | } | | static void encode_truecolor_32_argb( rgb_group *s, | unsigned char *d, | int q,int w ) | { | int *dp = (int *)d; | #if PIKE_BYTEORDER==4321 | while(q--) {*(dp++) = (s->r<<16) | (s->g<<8) | (s)->b;s++;} | #else | while(q--) {*(dp++) = ((s->r) | (s->g<<8) | (s)->b<<16)<<8;s++;} | #endif | } | | static void encode_truecolor_32_abgr( rgb_group *s, | unsigned char *d, | int q,int w ) | { | while(q--) | { | *(d++) = 0; | *(d++) = s->b; | *(d++) = s->g; | *(d++) = (s++)->r; | } | } | | | static void encode_truecolor_32_abgr_swapped( rgb_group *s, | unsigned char *d, | int q,int w ) | { | while(q--) | { | *(d++) = s->r; | *(d++) = s->g; | *(d++) = (s++)->b; | *(d++) = 0; | } | } | | #define ENCODE_8(X,Y,Z) \ | static void encode_truecolor_##X##_##Y( rgb_group *s, unsigned char *d, int q,int w ) \ | { \ | while(q--) \ | {*(d++)=(Z);s++;} \ | } \ | \ | static void encode_truecolor_##X##_##Y##_swapped( rgb_group *s, unsigned char *d, int q ,int w) \ | { \ | while(q--) \ | {*(d++)=(Z);s++;} \ | } | | | #if PIKE_BYTEORDER == 1234 | #define ENCODE_16(X,Y,Z) \ | static void encode_truecolor_##X##_##Y( rgb_group *s, unsigned char *d, int q,int w ) \ | { \ | unsigned short *dp = (unsigned short *)d; \ | while(q--) \ | {*(dp++) = (Z);s++;} \ | } \ | \ | static void encode_truecolor_##X##_##Y##_swapped( rgb_group *s, unsigned char *d, int q ,int w) \ | { \ | while(q--) \ | { \ | unsigned short v = (Z); \ | *(d++)=v&255; \ | *(d++)=v>>8;s++; \ | } \ | } | #else | #define ENCODE_16(X,Y,Z) \ | static void encode_truecolor_##X##_##Y( rgb_group *s, unsigned char *d, int q,int w ) \ | { \ | while(q--) \ | { \ | unsigned short v = (Z); \ | *(d++)=v>>8; \ | *(d++)=v&255;s++; \ | } \ | } \ | \ | static void encode_truecolor_##X##_##Y##_swapped( rgb_group *s, unsigned char *d, int q ,int w) \ | { \ | unsigned short *dp = (unsigned short *)d; \ | while(q--) \ | {*(dp++) = (Z);s++;} \ | } | #endif | | ENCODE_16(565,rgb,(((s->r>>3)<<6) | (s->g>>2))<<5 | (s->b>>3)); | ENCODE_16(565,bgr,(((s->b>>3)<<6) | (s->g>>2))<<5 | (s->r>>3)); | ENCODE_16(555,rgb,(((s->r>>3)<<5) | (s->g>>3))<<5 | (s->b>>3)); | ENCODE_16(555,bgr,(((s->b>>3)<<5) | (s->g>>3))<<5 | (s->r>>3)); | | ENCODE_8(232,rgb,(((s->r>>6)<<3) | (s->g>>5))<<2 | (s->b>>6)); | ENCODE_8(332,rgb,(((s->r>>5)<<3) | (s->g>>5))<<2 | (s->b>>6)); | ENCODE_8(242,rgb,(((s->r>>5)<<4) | (s->g>>4))<<2 | (s->b>>6)); | ENCODE_8(233,rgb,(((s->r>>5)<<3) | (s->g>>4))<<3 | (s->b>>5)); | ENCODE_8(232,bgr,(((s->b>>6)<<3) | (s->g>>5))<<2 | (s->r>>6)); | ENCODE_8(332,bgr,(((s->b>>5)<<3) | (s->g>>5))<<2 | (s->r>>6)); | ENCODE_8(242,bgr,(((s->b>>5)<<4) | (s->g>>4))<<2 | (s->r>>6)); | ENCODE_8(233,bgr,(((s->b>>5)<<3) | (s->g>>4))<<3 | (s->r>>5)); | | | static void encode_truecolor_generic(int rbits, int rshift, int gbits, | int gshift, int bbits, int bshift, | int bpp, int alignbits,int swap_bytes, | struct image *img, unsigned char *dest, | int len) | { | unsigned char *d = dest; | int x,y; | rgb_group *s; | s=img->img; | | if(!alignbits) alignbits=1; | | #define OPTIMIZE(rb,rs,gb,gs,bb,bs,al,fun) do { \ | if(rbits==rb && rshift==rs && gbits==gb && gshift==gs && \ | bbits==bb && bshift==bs && alignbits==al) { \ | DEBUG_PF(("Optimized case %s%s\n", #fun, swap_bytes?"_swapped":"")); \ | if (swap_bytes) \ | fun##_swapped(s, (void *)dest, img->xsize*img->ysize, img->xsize); \ | else \ | fun(s,(void *)dest,img->xsize*img->ysize,img->xsize); \ | return; \ | } \ | } while(0) | | switch(bpp) | { | case 32: | OPTIMIZE(8,16,8,8,8,0,1,encode_truecolor_32_argb); | OPTIMIZE(8,0,8,8,8,16,1,encode_truecolor_32_abgr); | break; | case 24: | OPTIMIZE(8,16,8,8,8,0,32,encode_truecolor_24_rgb_al32); | OPTIMIZE(8,0,8,8,8,16,32,encode_truecolor_24_bgr_al32); | OPTIMIZE(8,16,8,8,8,0,1,encode_truecolor_24_rgb); | OPTIMIZE(8,0,8,8,8,16,1,encode_truecolor_24_bgr); | break; | case 16: | OPTIMIZE(5,11,6,5,5,0,1,encode_truecolor_565_rgb); | OPTIMIZE(5,10,5,5,5,0,1,encode_truecolor_555_rgb); | OPTIMIZE(5,0,6,5,5,11,1,encode_truecolor_565_bgr); | OPTIMIZE(5,0,5,5,5,10,1,encode_truecolor_555_bgr); | break; | case 8: | OPTIMIZE(2,5,3,2,2,0,1,encode_truecolor_232_rgb); | OPTIMIZE(3,5,3,2,2,0,1,encode_truecolor_332_rgb); | OPTIMIZE(2,6,4,2,2,0,1,encode_truecolor_242_rgb); | OPTIMIZE(2,6,3,3,3,0,1,encode_truecolor_233_rgb); | OPTIMIZE(2,0,3,2,2,5,1,encode_truecolor_232_bgr); | OPTIMIZE(3,0,3,2,2,5,1,encode_truecolor_332_bgr); | OPTIMIZE(2,0,4,2,2,6,1,encode_truecolor_242_bgr); | OPTIMIZE(2,0,3,3,3,6,1,encode_truecolor_233_bgr); | break; | } | #undef OPTIMIZE | | DEBUG_PF(("Generic encode_truecolor for r%dxg%dxb%d (%d bpp, shift=r%d,g%d,b%d)\n", | rbits,gbits,bbits,bpp,rshift,gshift,bshift)); | { | int rfmask,gfmask,bfmask; | int rfshift,gfshift,bfshift,rzshift,gzshift,bzshift; | int bpshift,blinemod,bit; | | *d=0; | | rfshift=rshift-(sizeof(COLORTYPE)*8-rbits); | gfshift=gshift-(sizeof(COLORTYPE)*8-gbits); | bfshift=bshift-(sizeof(COLORTYPE)*8-bbits); | if (rfshift<0) rzshift=-rfshift,rfshift=0; else rzshift=0; | if (gfshift<0) gzshift=-gfshift,gfshift=0; else gzshift=0; | if (bfshift<0) bzshift=-bfshift,bfshift=0; else bzshift=0; | | rfmask=(((1<<rbits)-1)<<(sizeof(COLORTYPE)*8-rbits)); | gfmask=(((1<<gbits)-1)<<(sizeof(COLORTYPE)*8-gbits)); | bfmask=(((1<<bbits)-1)<<(sizeof(COLORTYPE)*8-bbits)); | bpshift=sizeof(unsigned long)*8-bpp; | blinemod=alignbits-(((img->xsize*bpp+7)&~7)%alignbits); | if(blinemod==alignbits) | blinemod=0; | else | blinemod>>=3; | | bit=0; | y = img->ysize; | while (y--) | { | int bp; | x=img->xsize; | while (x--) | { | register unsigned long b = | ((((s->r&rfmask)>>rzshift)<<rfshift)| | (((s->g&gfmask)>>gzshift)<<gfshift)| | (((s->b&bfmask)>>bzshift)<<bfshift))<<bpshift; | bp = bpp; | while (bp>8-bit) | { | if(bit) | *d|=(unsigned char)(b>>(24+bit)); | else | *d=(unsigned char)(b>>24); | b<<=8-bit; | bp-=8-bit; | bit=0; | d++; | } | if(bit) | *d|=b>>(24+bit); | else | *d=b>>24; | bit+=bp; | if (bit==8) ++d,bit=0; | s++; | } | if(!y) | break; | if(bit) ++d,bit=0; | bp=blinemod; | while (bp--) *(++d)=0; | } | } | | if (swap_bytes) | { | d=dest; | x=len; | | switch (bpp) | { | case 32: | while (x>=4) | { | d[0]^=d[3],d[3]^=d[0],d[0]^=d[3]; | d[1]^=d[2],d[2]^=d[1],d[1]^=d[2]; | d+=4; | x-=4; | } | break; | case 24: | while (x>=3) | { | d[0]^=d[2],d[2]^=d[0],d[0]^=d[2]; | d+=3; | x-=3; | } | break; | case 16: | while (x>=2) | { | d[0]^=d[1],d[1]^=d[0],d[0]^=d[1]; | d+=2; | x-=2; | } | break; | case 1: | while (x--) {*(d)=swap_bits[*d]; d++; } | break; | } | } | } | | static INLINE void examine_mask(unsigned int x, int *bits,int *shift) | { | *bits=0; | *shift=0; | if (!x) return; | while (!(x&1)) x>>=1,(*shift)++; | while (x&1) x>>=1,(*bits)++; | } | | void pgtk_encode_grey(struct image *i, unsigned char *dest, int bpp, int bpl ) | { | int x, y; | rgb_group *s = i->img; | switch(bpp) | { | case 1: | for(y=0; y<i->ysize; y++) | { | unsigned char *d = dest+y*bpl; | for(x=0; x<i->xsize; x++,s++) | *d = (s->r + (s->g<<1) + s->b)>>2; | } | return; | case 2: | for(y=0; y<i->ysize; y++) | { | unsigned short *d = (unsigned short *)(dest+y*bpl); | for(x=0; x<i->xsize; x++,s++) | *d = (s->r + (s->g<<1) + s->b)<<6; | } | return; | default: | Pike_error("This greyscale is to wide for me!\n"); | } | } | | void pgtk_encode_truecolor_masks(struct image *i, | int bitspp, | int pad, | int byteorder, | unsigned int red_mask, | unsigned int green_mask, | unsigned int blue_mask, | unsigned char *buffer, | int debug_len) | { | int rbits,rshift,gbits,gshift,bbits,bshift; | | examine_mask(red_mask,&rbits,&rshift); | examine_mask(green_mask,&gbits,&gshift); | examine_mask(blue_mask,&bbits,&bshift); | encode_truecolor_generic( rbits, rshift, gbits, gshift, bbits, bshift, | bitspp, pad, byteorder, i, buffer, debug_len ); | | } | | |
|