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