1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #ifdef STDC_HEADERS
6 # include <stdlib.h>
7 # include <stddef.h>
8 #else
9 # ifdef HAVE_STDLIB_H
10 # include <stdlib.h>
11 # endif
12 #endif
13
14 #include <stdlib.h>
15 #include <string.h>
16 #include <sys/ipc.h>
17 #include <sys/shm.h>
18
19 #include "ecore_x_private.h"
20 #include "Ecore_X.h"
21
22 #include <X11/extensions/XShm.h>
23 #include <X11/Xutil.h>
24
25 static int _ecore_x_image_shm_can = -1;
26 static int _ecore_x_image_err = 0;
27
28 static int
_ecore_x_image_error_handler(Display * d EINA_UNUSED,XErrorEvent * ev)29 _ecore_x_image_error_handler(Display *d EINA_UNUSED, XErrorEvent *ev)
30 {
31 _ecore_x_image_err = 1;
32 switch (ev->error_code)
33 {
34 case BadRequest: /* bad request code */
35 ERR("BadRequest");
36 break;
37 case BadValue: /* int parameter out of range */
38 ERR("BadValue");
39 break;
40 case BadWindow: /* parameter not a Window */
41 ERR("BadWindow");
42 break;
43 case BadPixmap: /* parameter not a Pixmap */
44 ERR("BadPixmap");
45 break;
46 case BadAtom: /* parameter not an Atom */
47 ERR("BadAtom");
48 break;
49 case BadCursor: /* parameter not a Cursor */
50 ERR("BadCursor");
51 break;
52 case BadFont: /* parameter not a Font */
53 ERR("BadFont");
54 break;
55 case BadMatch: /* parameter mismatch */
56 ERR("BadMatch");
57 break;
58 case BadDrawable: /* parameter not a Pixmap or Window */
59 ERR("BadDrawable");
60 break;
61 case BadAccess: /* depending on context */
62 ERR("BadAccess");
63 break;
64 case BadAlloc: /* insufficient resources */
65 ERR("BadAlloc");
66 break;
67 case BadColor: /* no such colormap */
68 ERR("BadColor");
69 break;
70 case BadGC: /* parameter not a GC */
71 ERR("BadGC");
72 break;
73 case BadIDChoice: /* choice not in range or already used */
74 ERR("BadIDChoice");
75 break;
76 case BadName: /* font or color name doesn't exist */
77 ERR("BadName");
78 break;
79 case BadLength: /* Request length incorrect */
80 ERR("BadLength");
81 break;
82 case BadImplementation: /* server is defective */
83 ERR("BadImplementation");
84 break;
85 }
86 return 0;
87 }
88
89 int
_ecore_x_image_shm_check(void)90 _ecore_x_image_shm_check(void)
91 {
92 XErrorHandler ph;
93 XShmSegmentInfo shminfo;
94 XImage *xim;
95
96 if (_ecore_x_image_shm_can != -1)
97 return _ecore_x_image_shm_can;
98
99 if (!XShmQueryExtension(_ecore_x_disp))
100 {
101 _ecore_x_image_shm_can = 0;
102 return _ecore_x_image_shm_can;
103 }
104
105 XSync(_ecore_x_disp, False);
106 _ecore_x_image_err = 0;
107
108 xim = XShmCreateImage(_ecore_x_disp,
109 DefaultVisual(_ecore_x_disp,
110 DefaultScreen(_ecore_x_disp)),
111 DefaultDepth(_ecore_x_disp,
112 DefaultScreen(_ecore_x_disp)),
113 ZPixmap, NULL,
114 &shminfo, 1, 1);
115 if (_ecore_xlib_sync) ecore_x_sync();
116 if (!xim)
117 {
118 _ecore_x_image_shm_can = 0;
119 return _ecore_x_image_shm_can;
120 }
121
122 shminfo.shmid = shmget(IPC_PRIVATE, xim->bytes_per_line * xim->height,
123 IPC_CREAT | 0600);
124 if (shminfo.shmid == -1)
125 {
126 ERR("%s", strerror(errno));
127 XDestroyImage(xim);
128 _ecore_x_image_shm_can = 0;
129 return _ecore_x_image_shm_can;
130 }
131
132 shminfo.readOnly = False;
133 shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
134 xim->data = shminfo.shmaddr;
135
136 if (xim->data == (char *)-1)
137 {
138 XDestroyImage(xim);
139 _ecore_x_image_shm_can = 0;
140 return _ecore_x_image_shm_can;
141 }
142
143 ph = XSetErrorHandler((XErrorHandler)_ecore_x_image_error_handler);
144 XShmAttach(_ecore_x_disp, &shminfo);
145 XShmGetImage(_ecore_x_disp, DefaultRootWindow(_ecore_x_disp),
146 xim, 0, 0, 0xffffffff);
147 XSync(_ecore_x_disp, False);
148 XSetErrorHandler((XErrorHandler)ph);
149 if (_ecore_x_image_err)
150 {
151 XShmDetach(_ecore_x_disp, &shminfo);
152 XDestroyImage(xim);
153 shmdt(shminfo.shmaddr);
154 shmctl(shminfo.shmid, IPC_RMID, 0);
155 _ecore_x_image_shm_can = 0;
156 return _ecore_x_image_shm_can;
157 }
158
159 XShmDetach(_ecore_x_disp, &shminfo);
160 XDestroyImage(xim);
161 shmdt(shminfo.shmaddr);
162 shmctl(shminfo.shmid, IPC_RMID, 0);
163
164 _ecore_x_image_shm_can = 1;
165 return _ecore_x_image_shm_can;
166 }
167
168 struct _Ecore_X_Image
169 {
170 XShmSegmentInfo shminfo;
171 Ecore_X_Visual vis;
172 XImage *xim;
173 int depth;
174 int w, h;
175 int bpl, bpp, rows;
176 unsigned char *data;
177 Eina_Bool shm : 1;
178 };
179
180 EAPI Ecore_X_Image *
ecore_x_image_new(int w,int h,Ecore_X_Visual vis,int depth)181 ecore_x_image_new(int w,
182 int h,
183 Ecore_X_Visual vis,
184 int depth)
185 {
186 Ecore_X_Image *im;
187
188 im = calloc(1, sizeof(Ecore_X_Image));
189 if (!im)
190 return NULL;
191
192 LOGFN;
193 im->w = w;
194 im->h = h;
195 im->vis = vis;
196 im->depth = depth;
197 if (depth <= 8) im->bpp = 1;
198 else if (depth <= 16) im->bpp = 2;
199 else if (depth <= 24) im->bpp = 3;
200 else im->bpp = 4;
201 _ecore_x_image_shm_check();
202 im->shm = _ecore_x_image_shm_can;
203 return im;
204 }
205
206 EAPI void
ecore_x_image_free(Ecore_X_Image * im)207 ecore_x_image_free(Ecore_X_Image *im)
208 {
209 LOGFN;
210 if (im->shm)
211 {
212 if (im->xim)
213 {
214 XShmDetach(_ecore_x_disp, &(im->shminfo));
215 XDestroyImage(im->xim);
216 shmdt(im->shminfo.shmaddr);
217 shmctl(im->shminfo.shmid, IPC_RMID, 0);
218 }
219 }
220 else if (im->xim)
221 {
222 free(im->xim->data);
223 im->xim->data = NULL;
224 XDestroyImage(im->xim);
225 }
226
227 free(im);
228 }
229
230 static void
_ecore_x_image_finalize(Ecore_X_Image * im)231 _ecore_x_image_finalize(Ecore_X_Image *im)
232 {
233 im->data = (unsigned char *)im->xim->data;
234 im->bpl = im->xim->bytes_per_line;
235 im->rows = im->xim->height;
236 if (im->xim->bits_per_pixel <= 8) im->bpp = 1;
237 else if (im->xim->bits_per_pixel <= 16) im->bpp = 2;
238 else if (im->xim->bits_per_pixel <= 24) im->bpp = 3;
239 else im->bpp = 4;
240 }
241
242 static void
_ecore_x_image_shm_create(Ecore_X_Image * im)243 _ecore_x_image_shm_create(Ecore_X_Image *im)
244 {
245 im->xim = XShmCreateImage(_ecore_x_disp, im->vis, im->depth,
246 ZPixmap, NULL, &(im->shminfo),
247 im->w, im->h);
248 if (!im->xim)
249 return;
250
251 im->shminfo.shmid = shmget(IPC_PRIVATE,
252 im->xim->bytes_per_line * im->xim->height,
253 IPC_CREAT | 0600);
254 if (im->shminfo.shmid == -1)
255 {
256 ERR("shmget failed: %s", strerror(errno));
257 XDestroyImage(im->xim);
258 im->xim = NULL;
259 return;
260 }
261
262 im->shminfo.readOnly = False;
263 im->shminfo.shmaddr = shmat(im->shminfo.shmid, 0, 0);
264 im->xim->data = im->shminfo.shmaddr;
265 if ((im->xim->data == (char *)-1) ||
266 (!im->xim->data))
267 {
268 ERR("shmat failed: %s", strerror(errno));
269 shmdt(im->shminfo.shmaddr);
270 shmctl(im->shminfo.shmid, IPC_RMID, 0);
271 XDestroyImage(im->xim);
272 im->xim = NULL;
273 return;
274 }
275
276 XShmAttach(_ecore_x_disp, &im->shminfo);
277 _ecore_x_image_finalize(im);
278 }
279
280 static void
_ecore_x_image_create(Ecore_X_Image * im)281 _ecore_x_image_create(Ecore_X_Image *im)
282 {
283 im->xim = XCreateImage(_ecore_x_disp, im->vis, im->depth,
284 ZPixmap, 0, NULL, im->w, im->h, 32, 0);
285 if (!im->xim) return;
286 im->xim->data = malloc(im->xim->bytes_per_line * im->h);
287 if (!im->xim->data)
288 {
289 XDestroyImage(im->xim);
290 im->xim = NULL;
291 return;
292 }
293 _ecore_x_image_finalize(im);
294 }
295
296 EAPI Eina_Bool
ecore_x_image_get(Ecore_X_Image * im,Ecore_X_Drawable draw,int x,int y,int sx,int sy,int w,int h)297 ecore_x_image_get(Ecore_X_Image *im,
298 Ecore_X_Drawable draw,
299 int x,
300 int y,
301 int sx,
302 int sy,
303 int w,
304 int h)
305 {
306 Eina_Bool ret = EINA_TRUE;
307 XErrorHandler ph;
308
309 LOGFN;
310 if (im->shm)
311 {
312 if (!im->xim) _ecore_x_image_shm_create(im);
313
314 if (!im->xim)
315 return EINA_FALSE;
316
317 _ecore_x_image_err = 0;
318
319 ecore_x_sync();
320 // optimised path
321 ph = XSetErrorHandler((XErrorHandler)_ecore_x_image_error_handler);
322 if ((sx == 0) && (w == im->w))
323 {
324 im->xim->data = (char *)
325 im->data + (im->xim->bytes_per_line * sy) + (sx * im->bpp);
326 im->xim->width = MIN(w, im->w);
327 im->xim->height = MIN(h, im->h);
328 XGrabServer(_ecore_x_disp);
329 if (!XShmGetImage(_ecore_x_disp, draw, im->xim, x, y, 0xffffffff))
330 ret = EINA_FALSE;
331 XUngrabServer(_ecore_x_disp);
332 ecore_x_sync();
333 }
334 // unavoidable thanks to mit-shm get api - tmp shm buf + copy into it
335 else
336 {
337 Ecore_X_Image *tim;
338 unsigned char *spixels, *sp, *pixels, *p;
339 int bpp, bpl, rows, sbpp, sbpl, srows;
340 int r;
341
342 tim = ecore_x_image_new(w, h, im->vis, im->depth);
343 if (tim)
344 {
345 ret = ecore_x_image_get(tim, draw, x, y, 0, 0, w, h);
346 if (ret)
347 {
348 spixels = ecore_x_image_data_get(tim,
349 &sbpl,
350 &srows,
351 &sbpp);
352 pixels = ecore_x_image_data_get(im, &bpl, &rows, &bpp);
353 if ((pixels) && (spixels))
354 {
355 p = pixels + (sy * bpl) + (sx * bpp);
356 sp = spixels;
357 for (r = srows; r > 0; r--)
358 {
359 memcpy(p, sp, sbpl);
360 p += bpl;
361 sp += sbpl;
362 }
363 }
364 }
365
366 ecore_x_image_free(tim);
367 }
368 }
369
370 XSetErrorHandler((XErrorHandler)ph);
371 if (_ecore_x_image_err)
372 ret = EINA_FALSE;
373 }
374 else
375 {
376 if (!im->xim)
377 _ecore_x_image_create(im);
378
379 if (!im->xim)
380 return EINA_FALSE;
381
382 if (XGetSubImage(_ecore_x_disp, draw, sx, sy, w, h,
383 0xffffffff, ZPixmap, im->xim, x, y) != im->xim)
384 ret = EINA_FALSE;
385 }
386
387 return ret;
388 }
389
390 EAPI void
ecore_x_image_put(Ecore_X_Image * im,Ecore_X_Drawable draw,Ecore_X_GC gc,int x,int y,int sx,int sy,int w,int h)391 ecore_x_image_put(Ecore_X_Image *im,
392 Ecore_X_Drawable draw,
393 Ecore_X_GC gc,
394 int x,
395 int y,
396 int sx,
397 int sy,
398 int w,
399 int h)
400 {
401 Ecore_X_GC tgc = 0;
402
403 LOGFN;
404 if (!gc)
405 {
406 XGCValues gcv;
407 memset(&gcv, 0, sizeof(gcv));
408 gcv.subwindow_mode = IncludeInferiors;
409 tgc = XCreateGC(_ecore_x_disp, draw, GCSubwindowMode, &gcv);
410 if (_ecore_xlib_sync) ecore_x_sync();
411 gc = tgc;
412 }
413 if (!im->xim)
414 {
415 if (im->shm) _ecore_x_image_shm_create(im);
416 else _ecore_x_image_create(im);
417 }
418 if (im->xim)
419 {
420 if (im->shm)
421 XShmPutImage(_ecore_x_disp, draw, gc, im->xim,
422 sx, sy, x, y, w, h, False);
423 else
424 XPutImage(_ecore_x_disp, draw, gc, im->xim,
425 sx, sy, x, y, w, h);
426 if (_ecore_xlib_sync) ecore_x_sync();
427 }
428 if (tgc) ecore_x_gc_free(tgc);
429 }
430
431 EAPI void *
ecore_x_image_data_get(Ecore_X_Image * im,int * bpl,int * rows,int * bpp)432 ecore_x_image_data_get(Ecore_X_Image *im,
433 int *bpl,
434 int *rows,
435 int *bpp)
436 {
437 LOGFN;
438 if (!im->xim)
439 {
440 if (im->shm) _ecore_x_image_shm_create(im);
441 else _ecore_x_image_create(im);
442 if (!im->xim) return NULL;
443 }
444 if (bpl) *bpl = im->bpl;
445 if (rows) *rows = im->rows;
446 if (bpp) *bpp = im->bpp;
447 return im->data;
448 }
449
450 EAPI Eina_Bool
ecore_x_image_is_argb32_get(Ecore_X_Image * im)451 ecore_x_image_is_argb32_get(Ecore_X_Image *im)
452 {
453 Visual *vis = im->vis;
454 if (((vis->class == TrueColor) ||
455 (vis->class == DirectColor)) &&
456 (im->bpp == 4) &&
457 (vis->red_mask == 0xff0000) &&
458 (vis->green_mask == 0x00ff00) &&
459 (vis->blue_mask == 0x0000ff))
460 {
461 #ifdef WORDS_BIGENDIAN
462 if (BitmapBitOrder(_ecore_x_disp) == MSBFirst) return EINA_TRUE;
463 #else
464 if (BitmapBitOrder(_ecore_x_disp) == LSBFirst) return EINA_TRUE;
465 #endif
466 }
467 return EINA_FALSE;
468 }
469
470 EAPI Eina_Bool
ecore_x_image_to_argb_convert(void * src,int sbpp,int sbpl,Ecore_X_Colormap c,Ecore_X_Visual v,int x,int y,int w,int h,unsigned int * dst,int dbpl,int dx,int dy)471 ecore_x_image_to_argb_convert(void *src,
472 int sbpp,
473 int sbpl,
474 Ecore_X_Colormap c,
475 Ecore_X_Visual v,
476 int x,
477 int y,
478 int w,
479 int h,
480 unsigned int *dst,
481 int dbpl,
482 int dx,
483 int dy)
484 {
485 Visual *vis = v;
486 XColor *cols = NULL;
487 int n = 0, nret = 0, i, row;
488 unsigned int pal[256], r, g, b;
489 enum
490 {
491 rgbnone = 0,
492 rgb565,
493 bgr565,
494 rgbx555,
495 rgb888,
496 bgr888,
497 argbx888,
498 abgrx888,
499 rgba888x,
500 bgra888x,
501 argbx666
502 };
503 int mode = 0;
504
505 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
506 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
507
508 sbpp *= 8;
509
510 n = vis->map_entries;
511 if ((n <= 256) &&
512 ((vis->class == PseudoColor) ||
513 (vis->class == StaticColor) ||
514 (vis->class == GrayScale) ||
515 (vis->class == StaticGray)))
516 {
517 if (!c)
518 c = DefaultColormap(_ecore_x_disp,
519 DefaultScreen(_ecore_x_disp));
520 cols = alloca(n * sizeof(XColor));
521 for (i = 0; i < n; i++)
522 {
523 cols[i].pixel = i;
524 cols[i].flags = DoRed | DoGreen | DoBlue;
525 cols[i].red = 0;
526 cols[i].green = 0;
527 cols[i].blue = 0;
528 }
529 XQueryColors(_ecore_x_disp, c, cols, n);
530 for (i = 0; i < n; i++)
531 {
532 pal[i] = 0xff000000 |
533 ((cols[i].red >> 8) << 16) |
534 ((cols[i].green >> 8) << 8) |
535 ((cols[i].blue >> 8));
536 }
537 nret = n;
538 }
539 else if ((vis->class == TrueColor) ||
540 (vis->class == DirectColor))
541 {
542 if (sbpp == 24)
543 {
544 if ((vis->red_mask == 0x00ff0000) &&
545 (vis->green_mask == 0x0000ff00) &&
546 (vis->blue_mask == 0x000000ff))
547 mode = rgb888;
548 else if ((vis->red_mask == 0x000000ff) &&
549 (vis->green_mask == 0x0000ff00) &&
550 (vis->blue_mask == 0x00ff0000))
551 mode = bgr888;
552 else
553 return EINA_FALSE;
554 }
555 else
556 {
557 if ((vis->red_mask == 0x00ff0000) &&
558 (vis->green_mask == 0x0000ff00) &&
559 (vis->blue_mask == 0x000000ff))
560 mode = argbx888;
561 else if ((vis->red_mask == 0x000000ff) &&
562 (vis->green_mask == 0x0000ff00) &&
563 (vis->blue_mask == 0x00ff0000))
564 mode = abgrx888;
565 else if ((vis->red_mask == 0xff000000) &&
566 (vis->green_mask == 0x00ff0000) &&
567 (vis->blue_mask == 0x0000ff00))
568 mode = rgba888x;
569 else if ((vis->red_mask == 0x0000ff00) &&
570 (vis->green_mask == 0x00ff0000) &&
571 (vis->blue_mask == 0xff000000))
572 mode = bgra888x;
573 else if ((vis->red_mask == 0x0003f000) &&
574 (vis->green_mask == 0x00000fc0) &&
575 (vis->blue_mask == 0x0000003f))
576 mode = argbx666;
577 else if ((vis->red_mask == 0x0000f800) &&
578 (vis->green_mask == 0x000007e0) &&
579 (vis->blue_mask == 0x0000001f))
580 mode = rgb565;
581 else if ((vis->red_mask == 0x0000001f) &&
582 (vis->green_mask == 0x000007e0) &&
583 (vis->blue_mask == 0x0000f800))
584 mode = bgr565;
585 else if ((vis->red_mask == 0x00007c00) &&
586 (vis->green_mask == 0x000003e0) &&
587 (vis->blue_mask == 0x0000001f))
588 mode = rgbx555;
589 else
590 return EINA_FALSE;
591 }
592 }
593 for (row = 0; row < h; row++)
594 {
595 unsigned char *s8;
596 unsigned short *s16;
597 unsigned int *s32;
598 unsigned int *dp, *de;
599
600 dp = ((unsigned int *)(((unsigned char *)dst) +
601 ((dy + row) * dbpl))) + dx;
602 de = dp + w;
603 switch (sbpp)
604 {
605 case 8:
606 s8 = ((unsigned char *)(((unsigned char *)src) + ((y + row) * sbpl))) + x;
607 if (nret > 0)
608 {
609 while (dp < de)
610 {
611 *dp = pal[*s8];
612 s8++; dp++;
613 }
614 }
615 else
616 return EINA_FALSE;
617 break;
618
619 case 16:
620 s16 = ((unsigned short *)(((unsigned char *)src) + ((y + row) * sbpl))) + x;
621 switch (mode)
622 {
623 case rgb565:
624 while (dp < de)
625 {
626 r = (*s16 & 0xf800) << 8;
627 g = (*s16 & 0x07e0) << 5;
628 b = (*s16 & 0x001f) << 3;
629 r |= (r >> 5) & 0xff0000;
630 g |= (g >> 6) & 0x00ff00;
631 b |= (b >> 5);
632 *dp = 0xff000000 | r | g | b;
633 s16++; dp++;
634 }
635 break;
636
637 case bgr565:
638 while (dp < de)
639 {
640 r = (*s16 & 0x001f) << 19;
641 g = (*s16 & 0x07e0) << 5;
642 b = (*s16 & 0xf800) >> 8;
643 r |= (r >> 5) & 0xff0000;
644 g |= (g >> 6) & 0x00ff00;
645 b |= (b >> 5);
646 *dp = 0xff000000 | r | g | b;
647 s16++; dp++;
648 }
649 break;
650
651 case rgbx555:
652 while (dp < de)
653 {
654 r = (*s16 & 0x7c00) << 9;
655 g = (*s16 & 0x03e0) << 6;
656 b = (*s16 & 0x001f) << 3;
657 r |= (r >> 5) & 0xff0000;
658 g |= (g >> 5) & 0x00ff00;
659 b |= (b >> 5);
660 *dp = 0xff000000 | r | g | b;
661 s16++; dp++;
662 }
663 break;
664
665 default:
666 return EINA_FALSE;
667 break;
668 }
669 break;
670
671 case 24:
672 s8 = ((unsigned char *)(((unsigned char *)src) + ((y + row) * sbpl))) + (x * (sbpp / 8));
673 switch (mode)
674 {
675 case rgb888:
676 while (dp < de)
677 {
678 *dp = 0xff000000 | (s8[2] << 16) | (s8[1] << 8) | s8[0];
679 s8 += 3; dp++;
680 }
681 break;
682 case bgr888:
683 while (dp < de)
684 {
685 *dp = 0xff000000 | (s8[0] << 16) | (s8[1] << 8) | s8[2];
686 s8 += 3; dp++;
687 }
688 break;
689 default:
690 return EINA_FALSE;
691 break;
692 }
693 break;
694
695 case 32:
696 s32 = ((unsigned int *)(((unsigned char *)src) + ((y + row) * sbpl))) + x;
697 switch (mode)
698 {
699 case argbx888:
700 while (dp < de)
701 {
702 *dp = 0xff000000 | *s32;
703 s32++; dp++;
704 }
705 break;
706
707 case abgrx888:
708 while (dp < de)
709 {
710 r = *s32 & 0x000000ff;
711 g = *s32 & 0x0000ff00;
712 b = *s32 & 0x00ff0000;
713 *dp = 0xff000000 | (r << 16) | (g) | (b >> 16);
714 s32++; dp++;
715 }
716 break;
717
718 case rgba888x:
719 while (dp < de)
720 {
721 *dp = 0xff000000 | (*s32 >> 8);
722 s32++; dp++;
723 }
724 break;
725
726 case bgra888x:
727 while (dp < de)
728 {
729 r = *s32 & 0x0000ff00;
730 g = *s32 & 0x00ff0000;
731 b = *s32 & 0xff000000;
732 *dp = 0xff000000 | (r << 8) | (g >> 8) | (b >> 24);
733 s32++; dp++;
734 }
735 break;
736
737 case argbx666:
738 while (dp < de)
739 {
740 r = (*s32 & 0x3f000) << 6;
741 g = (*s32 & 0x00fc0) << 4;
742 b = (*s32 & 0x0003f) << 2;
743 r |= (r >> 6) & 0xff0000;
744 g |= (g >> 6) & 0x00ff00;
745 b |= (b >> 6);
746 *dp = 0xff000000 | r | g | b;
747 s32++; dp++;
748 }
749 break;
750
751 default:
752 return EINA_FALSE;
753 break;
754 }
755 break;
756
757 default:
758 return EINA_FALSE;
759 break;
760 }
761 }
762 return EINA_TRUE;
763 }
764