6c42b44dd4f534341d8e8ef32134ea8bc1dba57a
[wine/hacks.git] / dlls / winedib.drv / primitives_color.c
blob6c42b44dd4f534341d8e8ef32134ea8bc1dba57a
1 /*
2 * DIB Engine color Primitives
4 * Copyright 2009 Massimo Del Fedele
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
22 #include "wine/port.h"
24 #include "dibdrv.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
28 /* ------------------------------------------------------------*/
29 /* BITFIELD HELPERS */
30 static inline DWORD PutField32(DWORD field, int shift, int len)
32 shift = shift - (8 - len);
33 if (len <= 8)
34 field &= (((1 << len) - 1) << (8 - len));
35 if (shift < 0)
36 field >>= -shift;
37 else
38 field <<= shift;
39 return field;
42 static inline WORD PutField16(WORD field, int shift, int len)
44 shift = shift - (8 - len);
45 if (len <= 8)
46 field &= (((1 << len) - 1) << (8 - len));
47 if (shift < 0)
48 field >>= -shift;
49 else
50 field <<= shift;
51 return field;
54 /* ------------------------------------------------------------*/
55 /* COLOR FUNCTIONS */
56 DWORD _DIBDRV_ColorToPixel32_RGB(const DIBDRVBITMAP *dib, COLORREF color)
58 return ( ((color >> 16) & 0xff) | (color & 0xff00) | ((color << 16) & 0xff0000) );
61 DWORD _DIBDRV_ColorToPixel32_BITFIELDS(const DIBDRVBITMAP *dib, COLORREF color)
63 DWORD r,g,b;
65 r = GetRValue(color);
66 g = GetGValue(color);
67 b = GetBValue(color);
69 return PutField32(r, dib->redShift, dib->redLen) |
70 PutField32(g, dib->greenShift, dib->greenLen) |
71 PutField32(b, dib->blueShift, dib->blueLen);
74 DWORD _DIBDRV_ColorToPixel24(const DIBDRVBITMAP *dib, COLORREF color)
76 return ( ((color >> 16) & 0xff) | (color & 0xff00) | ((color << 16) & 0xff0000) );
79 DWORD _DIBDRV_ColorToPixel16_RGB(const DIBDRVBITMAP *dib, COLORREF color)
81 return ( ((color >> 19) & 0x001f) | ((color >> 6) & 0x03e0) | ((color << 7) & 0x7c00) );
84 DWORD _DIBDRV_ColorToPixel16_BITFIELDS(const DIBDRVBITMAP *dib, COLORREF color)
86 DWORD r,g,b;
88 r = GetRValue(color);
89 g = GetGValue(color);
90 b = GetBValue(color);
92 return PutField16(r, dib->redShift, dib->redLen) |
93 PutField16(g, dib->greenShift, dib->greenLen) |
94 PutField16(b, dib->blueShift, dib->blueLen);
97 /* gets nearest color to DIB palette color */
98 DWORD _DIBDRV_GetNearestColor(const DIBDRVBITMAP *dib, COLORREF color)
100 RGBQUAD *c;
102 if(dib->bitCount > 8)
103 return color;
105 c = dib->colorTable + _DIBDRV_GetNearestColorIndex(dib, color);
106 return RGB(c->rgbRed, c->rgbGreen, c->rgbBlue);
110 /* gets nearest color index in DIB palette of a given colorref */
111 DWORD _DIBDRV_GetNearestColorIndex(const DIBDRVBITMAP *dib, COLORREF color)
113 DWORD r, g, b;
114 int i, best_index = 0;
115 DWORD diff, best_diff = 0xffffffff;
117 r = GetRValue(color);
118 g = GetGValue(color);
119 b = GetBValue(color);
121 for(i = 0; i < dib->colorTableSize; i++)
123 RGBQUAD *cur = dib->colorTable + i;
124 diff = (r - cur->rgbRed) * (r - cur->rgbRed)
125 + (g - cur->rgbGreen) * (g - cur->rgbGreen)
126 + (b - cur->rgbBlue) * (b - cur->rgbBlue);
128 if(diff == 0)
130 best_index = i;
131 break;
134 if(diff < best_diff)
136 best_diff = diff;
137 best_index = i;
140 return best_index;
143 DWORD _DIBDRV_ColorToPixelColortable(const DIBDRVBITMAP *dib, COLORREF color)
145 DWORD r, g, b;
147 r = GetRValue(color);
148 g = GetGValue(color);
149 b = GetBValue(color);
151 /* just in case it's being called without color table
152 properly initialized */
153 if(!dib->colorTableGrabbed)
154 return 0;
156 /* for monochrome bitmaps, color is :
157 foreground if matching foreground ctable
158 else background if matching background ctable
159 else foreground ix 0xffffff
160 else background */
161 if(dib->colorTableSize == 2)
163 RGBQUAD *back = dib->colorTable;
164 RGBQUAD *fore = dib->colorTable + 1;
165 if(r == fore->rgbRed && g == fore->rgbGreen && b == fore->rgbBlue)
166 return 1;
167 else if(r == back->rgbRed && g == back->rgbGreen && b == back->rgbBlue)
168 return 0;
169 if((color & 0xffffff) == 0xffffff)
170 return 1;
171 else
172 return 0;
175 /* otherwise looks for nearest color in palette */
176 return _DIBDRV_GetNearestColorIndex(dib, color);