1 /* convert.c - convert RImage to Pixmap
3 * Raster graphics library
5 * Copyright (c) 1997-2000 Alfredo K. Kojima
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <X11/Xutil.h>
39 extern Pixmap
R_CreateXImageMappedPixmap(RContext
*context
, RXImage
*ximage
);
45 extern void x86_PseudoColor_32_to_8(unsigned char *image
,
46 unsigned char *ximage
,
47 char *err
, char *nerr
,
49 int dr
, int dg
, int db
,
50 unsigned long *pixels
,
52 int width
, int height
,
59 extern int x86_check_mmx();
61 extern void x86_mmx_TrueColor_32_to_16(unsigned char *image
,
62 unsigned short *ximage
,
63 short *err
, short *nerr
,
64 short *rtable
, short *gtable
,
66 int dr
, int dg
, int db
,
70 int width
, int height
,
75 #endif /* ASM_X86_MMX */
79 typedef struct RConversionTable
{
80 unsigned short table
[256];
83 struct RConversionTable
*next
;
87 typedef struct RStdConversionTable
{
88 unsigned int table
[256];
93 struct RStdConversionTable
*next
;
94 } RStdConversionTable
;
98 static RConversionTable
*conversionTable
= NULL
;
99 static RStdConversionTable
*stdConversionTable
= NULL
;
102 static unsigned short*
103 computeTable(unsigned short mask
)
105 RConversionTable
*tmp
= conversionTable
;
109 if (tmp
->index
== mask
)
117 tmp
= (RConversionTable
*)malloc(sizeof(RConversionTable
));
122 tmp
->table
[i
] = (i
*mask
+ 0x7f)/0xff;
125 tmp
->next
= conversionTable
;
126 conversionTable
= tmp
;
132 computeStdTable(unsigned int mult
, unsigned int max
)
134 RStdConversionTable
*tmp
= stdConversionTable
;
138 if (tmp
->mult
== mult
&& tmp
->max
== max
)
146 tmp
= (RStdConversionTable
*)malloc(sizeof(RStdConversionTable
));
150 for (i
=0; i
<256; i
++) {
151 tmp
->table
[i
] = (i
*max
)/0xff * mult
;
156 tmp
->next
= stdConversionTable
;
157 stdConversionTable
= tmp
;
162 /***************************************************************************/
166 convertTrueColor_generic(RXImage
*ximg
, RImage
*image
,
167 char *err
, char *nerr
,
171 const int dr
, const int dg
, const int db
,
172 const unsigned short roffs
,
173 const unsigned short goffs
,
174 const unsigned short boffs
)
180 unsigned char *ptr
= image
->data
;
181 int channels
= image
->format
== RRGBAFormat
? 4 : 3;
184 /* convert and dither the image to XImage */
185 for (y
=0; y
<image
->height
; y
++) {
189 for (x
=0; x
<image
->width
; x
++, ptr
+=channels
) {
192 pixel
= *ptr
+ err
[x
];
193 if (pixel
<0) pixel
=0; else if (pixel
>0xff) pixel
=0xff;
199 pixel
= *(ptr
+1) + err
[x
+1];
200 if (pixel
<0) pixel
=0; else if (pixel
>0xff) pixel
=0xff;
206 pixel
= *(ptr
+2) + err
[x
+2];
207 if (pixel
<0) pixel
=0; else if (pixel
>0xff) pixel
=0xff;
213 pixel
= (r
<<roffs
) | (g
<<goffs
) | (b
<<boffs
);
214 XPutPixel(ximg
->image
, x
, y
, pixel
);
216 /* distribute error */
230 nerr
[x
+1+3*1]=ger
-2*g
;
231 nerr
[x
+2+3*1]=ber
-2*b
;
233 /* skip to next line */
244 image2TrueColor(RContext
*ctx
, RImage
*image
)
247 unsigned short rmask
, gmask
, bmask
;
248 unsigned short roffs
, goffs
, boffs
;
249 unsigned short *rtable
, *gtable
, *btable
;
250 int channels
= (image
->format
== RRGBAFormat
? 4 : 3);
252 ximg
= RCreateXImage(ctx
, ctx
->depth
, image
->width
, image
->height
);
257 roffs
= ctx
->red_offset
;
258 goffs
= ctx
->green_offset
;
259 boffs
= ctx
->blue_offset
;
261 rmask
= ctx
->visual
->red_mask
>> roffs
;
262 gmask
= ctx
->visual
->green_mask
>> goffs
;
263 bmask
= ctx
->visual
->blue_mask
>> boffs
;
265 rtable
= computeTable(rmask
);
266 gtable
= computeTable(gmask
);
267 btable
= computeTable(bmask
);
269 if (rtable
==NULL
|| gtable
==NULL
|| btable
==NULL
) {
270 RErrorCode
= RERR_NOMEMORY
;
271 RDestroyXImage(ctx
, ximg
);
280 if (ctx
->attribs
->render_mode
==RBestMatchRendering
) {
284 unsigned char *ptr
= image
->data
;
288 puts("true color match");
290 for (y
=0, ofs
=0; y
< image
->height
; y
++) {
291 for (x
=0; x
< image
->width
; x
++, ofs
+=channels
-3) {
293 r
= rtable
[ptr
[ofs
++]];
294 g
= gtable
[ptr
[ofs
++]];
295 b
= btable
[ptr
[ofs
++]];
296 pixel
= (r
<<roffs
) | (g
<<goffs
) | (b
<<boffs
);
297 XPutPixel(ximg
->image
, x
, y
, pixel
);
302 const int dr
=0xff/rmask
;
303 const int dg
=0xff/gmask
;
304 const int db
=0xff/bmask
;
307 puts("true color dither");
311 if (ctx
->depth
== 16 && image
->format
== RRGBAFormat
312 && x86_check_mmx()) {
316 err
= malloc(8*(image
->width
+3));
317 nerr
= malloc(8*(image
->width
+3));
321 RErrorCode
= RERR_NOMEMORY
;
322 RDestroyXImage(ctx
, ximg
);
325 memset(err
, 0, 8*(image
->width
+3));
326 memset(nerr
, 0, 8*(image
->width
+3));
328 x86_mmx_TrueColor_32_to_16(image
->data
,
329 (unsigned short*)ximg
->image
->data
,
331 rtable
, gtable
, btable
,
334 image
->width
, image
->height
,
335 ximg
->image
->bytes_per_line
- 2*image
->width
);
340 #endif /* ASM_X86_MMX */
344 int ch
= image
->format
== RRGBAFormat
? 4 : 3;
346 err
= malloc(ch
*(image
->width
+2));
347 nerr
= malloc(ch
*(image
->width
+2));
351 RErrorCode
= RERR_NOMEMORY
;
352 RDestroyXImage(ctx
, ximg
);
356 memset(err
, 0, ch
*(image
->width
+2));
357 memset(nerr
, 0, ch
*(image
->width
+2));
359 convertTrueColor_generic(ximg
, image
, err
, nerr
,
360 rtable
, gtable
, btable
,
361 dr
, dg
, db
, roffs
, goffs
, boffs
);
376 /***************************************************************************/
379 convertPseudoColor_to_8(RXImage
*ximg
, RImage
*image
,
380 char *err
, char *nerr
,
384 const int dr
, const int dg
, const int db
,
385 unsigned long *pixels
,
392 unsigned char *ptr
= image
->data
;
393 unsigned char *optr
= ximg
->image
->data
;
394 int channels
= image
->format
== RRGBAFormat
? 4 : 3;
397 /* convert and dither the image to XImage */
398 for (y
=0; y
<image
->height
; y
++) {
402 for (x
=0; x
<image
->width
*3; x
+=3, ptr
+=channels
) {
405 pixel
= *ptr
+ err
[x
];
406 if (pixel
<0) pixel
=0; else if (pixel
>0xff) pixel
=0xff;
412 pixel
= *(ptr
+1) + err
[x
+1];
413 if (pixel
<0) pixel
=0; else if (pixel
>0xff) pixel
=0xff;
419 pixel
= *(ptr
+2) + err
[x
+2];
420 if (pixel
<0) pixel
=0; else if (pixel
>0xff) pixel
=0xff;
425 *optr
++ = pixels
[r
*cpcpc
+ g
*cpc
+ b
];
427 /* distribute error */
442 nerr
[x
+1+3*1]=ger
-2*g
;
443 nerr
[x
+2+3*1]=ber
-2*b
;
445 /* skip to next line */
450 optr
+= ximg
->image
->bytes_per_line
- image
->width
;
457 image2PseudoColor(RContext
*ctx
, RImage
*image
)
460 register int x
, y
, r
, g
, b
;
463 const int cpc
=ctx
->attribs
->colors_per_channel
;
464 const unsigned short rmask
= cpc
-1; /* different sizes could be used */
465 const unsigned short gmask
= rmask
; /* for r,g,b */
466 const unsigned short bmask
= rmask
;
467 unsigned short *rtable
, *gtable
, *btable
;
468 const int cpccpc
= cpc
*cpc
;
469 int channels
= image
->format
== RRGBAFormat
? 4 : 3;
471 ximg
= RCreateXImage(ctx
, ctx
->depth
, image
->width
, image
->height
);
478 /* Tables are same at the moment because rmask==gmask==bmask. */
479 rtable
= computeTable(rmask
);
480 gtable
= computeTable(gmask
);
481 btable
= computeTable(bmask
);
483 if (rtable
==NULL
|| gtable
==NULL
|| btable
==NULL
) {
484 RErrorCode
= RERR_NOMEMORY
;
485 RDestroyXImage(ctx
, ximg
);
489 if (ctx
->attribs
->render_mode
== RBestMatchRendering
) {
492 printf("pseudo color match with %d colors per channel\n", cpc
);
494 for (y
=0; y
<image
->height
; y
++) {
495 for (x
=0; x
<image
->width
; x
++, ptr
+=channels
-1) {
500 pixel
= r
*cpccpc
+ g
*cpc
+ b
;
501 /*data[ofs] = ctx->colors[pixel].pixel;*/
502 XPutPixel(ximg
->image
, x
, y
, ctx
->colors
[pixel
].pixel
);
509 const int dr
=0xff/rmask
;
510 const int dg
=0xff/gmask
;
511 const int db
=0xff/bmask
;
515 printf("pseudo color dithering with %d colors per channel\n", cpc
);
517 err
= malloc(4*(image
->width
+3));
518 nerr
= malloc(4*(image
->width
+3));
522 RErrorCode
= RERR_NOMEMORY
;
523 RDestroyXImage(ctx
, ximg
);
526 memset(err
, 0, 4*(image
->width
+3));
527 memset(nerr
, 0, 4*(image
->width
+3));
531 x86_PseudoColor_32_to_8(image
->data
, ximg
->image
->data
,
534 dr
, dg
, db
, ctx
->pixels
, cpc
,
535 image
->width
, image
->height
,
537 ximg
->image
->bytes_per_line
- image
->width
);
539 convertPseudoColor_to_8(ximg
, image
, err
+4, nerr
+4,
540 rtable
, gtable
, btable
,
541 dr
, dg
, db
, ctx
->pixels
, cpc
);
553 * For standard colormap
556 image2StandardPseudoColor(RContext
*ctx
, RImage
*image
)
559 register int x
, y
, r
, g
, b
;
563 unsigned int *rtable
, *gtable
, *btable
;
564 unsigned int base_pixel
= ctx
->std_rgb_map
->base_pixel
;
565 int channels
= image
->format
== RRGBAFormat
? 4 : 3;
566 /*register unsigned char maxrgb = 0xff;*/
568 ximg
= RCreateXImage(ctx
, ctx
->depth
, image
->width
, image
->height
);
575 data
= (unsigned char *)ximg
->image
->data
;
578 rtable
= computeStdTable(ctx
->std_rgb_map
->red_mult
,
579 ctx
->std_rgb_map
->red_max
);
581 gtable
= computeStdTable(ctx
->std_rgb_map
->green_mult
,
582 ctx
->std_rgb_map
->green_max
);
584 btable
= computeStdTable(ctx
->std_rgb_map
->blue_mult
,
585 ctx
->std_rgb_map
->blue_max
);
587 if (rtable
==NULL
|| gtable
==NULL
|| btable
==NULL
) {
588 RErrorCode
= RERR_NOMEMORY
;
589 RDestroyXImage(ctx
, ximg
);
594 if (ctx
->attribs
->render_mode
== RBestMatchRendering
) {
595 for (y
=0; y
<image
->height
; y
++) {
596 for (x
=0; x
<image
->width
; x
++, ptr
+=channels
) {
598 pixel
= (rtable
[*ptr
] + gtable
[*(ptr
+1)]
599 + btable
[*(ptr
+2)] + base_pixel
) & 0xffffffff;
601 XPutPixel(ximg
->image
, x
, y
, pixel
);
612 printf("pseudo color dithering with %d colors per channel\n", cpc
);
614 err
= (short*)malloc(3*(image
->width
+2)*sizeof(short));
615 nerr
= (short*)malloc(3*(image
->width
+2)*sizeof(short));
621 RErrorCode
= RERR_NOMEMORY
;
622 RDestroyXImage(ctx
, ximg
);
625 for (x
=0, x1
=0; x
<image
->width
*3; x1
+=channels
-3) {
626 err
[x
++] = ptr
[x1
++];
627 err
[x
++] = ptr
[x1
++];
628 err
[x
++] = ptr
[x1
++];
630 err
[x
] = err
[x
+1] = err
[x
+2] = 0;
631 /* convert and dither the image to XImage */
632 for (y
=0, ofs
=0; y
<image
->height
; y
++) {
633 if (y
<image
->height
-1) {
635 for (x
=0, x1
=(y
+1)*image
->width
*channels
;
638 nerr
[x
++] = ptr
[x1
++];
639 nerr
[x
++] = ptr
[x1
++];
640 nerr
[x
++] = ptr
[x1
++];
644 nerr
[x
++] = ptr
[x1
++];
645 nerr
[x
++] = ptr
[x1
++];
646 nerr
[x
++] = ptr
[x1
++];
648 for (x
=0; x
<image
->width
*3; x
+=3, ofs
++) {
650 if (err
[x
]>0xff) err
[x
]=0xff; else if (err
[x
]<0) err
[x
]=0;
651 if (err
[x
+1]>0xff) err
[x
+1]=0xff; else if (err
[x
+1]<0) err
[x
+1]=0;
652 if (err
[x
+2]>0xff) err
[x
+2]=0xff; else if (err
[x
+2]<0) err
[x
+2]=0;
655 g
= gtable
[err
[x
+1]];
656 b
= btable
[err
[x
+2]];
660 data
[ofs
] = base_pixel
+ pixel
;
663 rer
= err
[x
] - (ctx
->colors
[pixel
].red
>>8);
664 ger
= err
[x
+1] - (ctx
->colors
[pixel
].green
>>8);
665 ber
= err
[x
+2] - (ctx
->colors
[pixel
].blue
>>8);
667 /* distribute error */
668 err
[x
+3*1]+=(rer
*7)/16;
669 err
[x
+1+3*1]+=(ger
*7)/16;
670 err
[x
+2+3*1]+=(ber
*7)/16;
673 nerr
[x
+1]+=(ger
*5)/16;
674 nerr
[x
+2]+=(ber
*5)/16;
677 nerr
[x
-3*1]+=(rer
*3)/16;
678 nerr
[x
-3*1+1]+=(ger
*3)/16;
679 nerr
[x
-3*1+2]+=(ber
*3)/16;
683 nerr
[x
+1+3*1]+=ger
/16;
684 nerr
[x
+2+3*1]+=ber
/16;
686 /* skip to next line */
691 ofs
+= ximg
->image
->bytes_per_line
- image
->width
;
696 ximg
->image
->data
= (char*)data
;
704 image2GrayScale(RContext
*ctx
, RImage
*image
)
707 register int x
, y
, g
;
709 const int cpc
=ctx
->attribs
->colors_per_channel
;
710 unsigned short gmask
;
711 unsigned short *table
;
713 int channels
= image
->format
== RRGBAFormat
? 4 : 3;
715 /*register unsigned char maxrgb = 0xff;*/
717 ximg
= RCreateXImage(ctx
, ctx
->depth
, image
->width
, image
->height
);
724 data
= (unsigned char *)ximg
->image
->data
;
726 if (ctx
->vclass
== StaticGray
)
727 gmask
= (1<<ctx
->depth
) - 1; /* use all grays */
729 gmask
= cpc
*cpc
*cpc
-1;
731 table
= computeTable(gmask
);
734 RErrorCode
= RERR_NOMEMORY
;
735 RDestroyXImage(ctx
, ximg
);
739 if (ctx
->attribs
->render_mode
== RBestMatchRendering
) {
742 printf("grayscale match with %d colors per channel\n", cpc
);
744 for (y
=0; y
<image
->height
; y
++) {
745 for (x
=0; x
<image
->width
; x
++) {
747 g
= table
[(*ptr
* 30 + *(ptr
+1) * 59 + *(ptr
+2) * 11)/100];
749 /*data[ofs] = ctx->colors[g].pixel;*/
750 XPutPixel(ximg
->image
, x
, y
, ctx
->colors
[g
].pixel
);
759 const int dg
=0xff/gmask
;
762 printf("grayscale dither with %d colors per channel\n", cpc
);
764 gerr
= (short*)malloc((image
->width
+2)*sizeof(short));
765 ngerr
= (short*)malloc((image
->width
+2)*sizeof(short));
766 if (!gerr
|| !ngerr
) {
769 RErrorCode
= RERR_NOMEMORY
;
770 RDestroyXImage(ctx
, ximg
);
773 for (x
=0; x
<image
->width
; x
++) {
774 gerr
[x
] = (ptr
[x
*3]*30 + ptr
[x
*3+1]*59 + ptr
[x
*3+2]*11)/100;
777 /* convert and dither the image to XImage */
778 for (y
=0; y
<image
->height
; y
++) {
779 if (y
<image
->height
-1) {
781 for (x
=0, x1
=(y
+1)*image
->width
*3; x
<image
->width
; x1
+=channels
) {
782 ngerr
[x
] = (ptr
[x1
]*30 + ptr
[x1
+1]*59 + ptr
[x1
+2]*11)/100;
786 ngerr
[x
] = (ptr
[x1
]*30 + ptr
[x1
+1]*59 + ptr
[x1
+2]*11)/100;
788 for (x
=0; x
<image
->width
; x
++) {
790 if (gerr
[x
]>0xff) gerr
[x
]=0xff; else if (gerr
[x
]<0) gerr
[x
]=0;
794 /*data[ofs] = ctx->colors[g].pixel;*/
795 XPutPixel(ximg
->image
, x
, y
, ctx
->colors
[g
].pixel
);
797 ger
= gerr
[x
] - g
*dg
;
799 /* distribute error */
808 /* skip to next line */
816 ximg
->image
->data
= (char*)data
;
823 image2Bitmap(RContext
*ctx
, RImage
*image
, int threshold
)
826 unsigned char *alpha
;
829 ximg
= RCreateXImage(ctx
, 1, image
->width
, image
->height
);
833 alpha
= image
->data
+3;
835 for (y
= 0; y
< image
->height
; y
++) {
836 for (x
= 0; x
< image
->width
; x
++) {
837 XPutPixel(ximg
->image
, x
, y
, (*alpha
<= threshold
? 0 : 1));
848 RConvertImage(RContext
*context
, RImage
*image
, Pixmap
*pixmap
)
855 assert(context
!=NULL
);
857 assert(pixmap
!=NULL
);
859 /* clear error message */
860 if (context
->vclass
== TrueColor
) {
862 ximg
= image2TrueColor(context
, image
);
864 } else if (context
->vclass
== PseudoColor
865 || context
->vclass
== StaticColor
) {
870 if (context
->attribs
->standard_colormap_mode
!= RIgnoreStdColormap
)
871 ximg
= image2StandardPseudoColor(context
, image
);
873 ximg
= image2PseudoColor(context
, image
);
877 } else if (context
->vclass
== GrayScale
|| context
->vclass
== StaticGray
) {
879 ximg
= image2GrayScale(context
, image
);
887 *pixmap
= XCreatePixmap(context
->dpy
, context
->drawable
, image
->width
,
888 image
->height
, context
->depth
);
891 if (context
->flags
.use_shared_pixmap
&& ximg
->is_shared
)
892 tmp
= R_CreateXImageMappedPixmap(context
, ximg
);
897 * We have to copy the shm Pixmap into a normal Pixmap because
898 * otherwise, we would have to control when Pixmaps are freed so
899 * that we can detach their shm segments. This is a problem if the
900 * program crash, leaving stale shared memory segments in the
901 * system (lots of them). But with some work, we can optimize
902 * things and remove this XCopyArea. This will require
903 * explicitly freeing all pixmaps when exiting or restarting
906 XCopyArea(context
->dpy
, tmp
, *pixmap
, context
->copy_gc
, 0, 0,
907 image
->width
, image
->height
, 0, 0);
908 XFreePixmap(context
->dpy
, tmp
);
910 RPutXImage(context
, *pixmap
, context
->copy_gc
, ximg
, 0, 0, 0, 0,
911 image
->width
, image
->height
);
914 RPutXImage(context
, *pixmap
, context
->copy_gc
, ximg
, 0, 0, 0, 0,
915 image
->width
, image
->height
);
918 RDestroyXImage(context
, ximg
);
925 RConvertImageMask(RContext
*context
, RImage
*image
, Pixmap
*pixmap
,
926 Pixmap
*mask
, int threshold
)
932 assert(context
!=NULL
);
934 assert(pixmap
!=NULL
);
937 if (!RConvertImage(context
, image
, pixmap
))
940 if (image
->format
==RRGBFormat
) {
945 ximg
= image2Bitmap(context
, image
, threshold
);
950 *mask
= XCreatePixmap(context
->dpy
, context
->drawable
, image
->width
,
952 gcv
.foreground
= context
->black
;
953 gcv
.background
= context
->white
;
954 gcv
.graphics_exposures
= False
;
955 gc
= XCreateGC(context
->dpy
, *mask
, GCForeground
|GCBackground
956 |GCGraphicsExposures
, &gcv
);
957 RPutXImage(context
, *mask
, gc
, ximg
, 0, 0, 0, 0,
958 image
->width
, image
->height
);
959 RDestroyXImage(context
, ximg
);
966 RGetClosestXColor(RContext
*context
, RColor
*color
, XColor
*retColor
)
968 if (context
->vclass
== TrueColor
) {
969 unsigned short rmask
, gmask
, bmask
;
970 unsigned short roffs
, goffs
, boffs
;
971 unsigned short *rtable
, *gtable
, *btable
;
973 roffs
= context
->red_offset
;
974 goffs
= context
->green_offset
;
975 boffs
= context
->blue_offset
;
977 rmask
= context
->visual
->red_mask
>> roffs
;
978 gmask
= context
->visual
->green_mask
>> goffs
;
979 bmask
= context
->visual
->blue_mask
>> boffs
;
981 rtable
= computeTable(rmask
);
982 gtable
= computeTable(gmask
);
983 btable
= computeTable(bmask
);
985 retColor
->pixel
= (rtable
[color
->red
]<<roffs
) |
986 (gtable
[color
->green
]<<goffs
) | (btable
[color
->blue
]<<boffs
);
988 retColor
->red
= color
->red
<< 8;
989 retColor
->green
= color
->green
<< 8;
990 retColor
->blue
= color
->blue
<< 8;
991 retColor
->flags
= DoRed
|DoGreen
|DoBlue
;
993 } else if (context
->vclass
== PseudoColor
994 || context
->vclass
== StaticColor
) {
996 if (context
->attribs
->standard_colormap_mode
!= RIgnoreStdColormap
) {
997 unsigned int *rtable
, *gtable
, *btable
;
999 rtable
= computeStdTable(context
->std_rgb_map
->red_mult
,
1000 context
->std_rgb_map
->red_max
);
1002 gtable
= computeStdTable(context
->std_rgb_map
->green_mult
,
1003 context
->std_rgb_map
->green_max
);
1005 btable
= computeStdTable(context
->std_rgb_map
->blue_mult
,
1006 context
->std_rgb_map
->blue_max
);
1008 if (rtable
==NULL
|| gtable
==NULL
|| btable
==NULL
) {
1009 RErrorCode
= RERR_NOMEMORY
;
1013 retColor
->pixel
= (rtable
[color
->red
]
1014 + gtable
[color
->green
]
1015 + btable
[color
->blue
]
1016 + context
->std_rgb_map
->base_pixel
) & 0xffffffff;
1017 retColor
->red
= color
->red
<<8;
1018 retColor
->green
= color
->green
<<8;
1019 retColor
->blue
= color
->blue
<<8;
1020 retColor
->flags
= DoRed
|DoGreen
|DoBlue
;
1023 const int cpc
=context
->attribs
->colors_per_channel
;
1024 const unsigned short rmask
= cpc
-1; /* different sizes could be used */
1025 const unsigned short gmask
= rmask
; /* for r,g,b */
1026 const unsigned short bmask
= rmask
;
1027 unsigned short *rtable
, *gtable
, *btable
;
1028 const int cpccpc
= cpc
*cpc
;
1031 rtable
= computeTable(rmask
);
1032 gtable
= computeTable(gmask
);
1033 btable
= computeTable(bmask
);
1035 if (rtable
==NULL
|| gtable
==NULL
|| btable
==NULL
) {
1036 RErrorCode
= RERR_NOMEMORY
;
1039 index
= rtable
[color
->red
]*cpccpc
+ gtable
[color
->green
]*cpc
1040 + btable
[color
->blue
];
1041 *retColor
= context
->colors
[index
];
1044 } else if (context
->vclass
== GrayScale
|| context
->vclass
== StaticGray
) {
1046 const int cpc
= context
->attribs
->colors_per_channel
;
1047 unsigned short gmask
;
1048 unsigned short *table
;
1051 if (context
->vclass
== StaticGray
)
1052 gmask
= (1<<context
->depth
) - 1; /* use all grays */
1054 gmask
= cpc
*cpc
*cpc
-1;
1056 table
= computeTable(gmask
);
1060 index
= table
[(color
->red
*30 + color
->green
*59 + color
->blue
*11)/100];
1062 *retColor
= context
->colors
[index
];
1064 RErrorCode
= RERR_INTERNAL
;