1 | // xImaPal.cpp : Palette and Pixel functions
|
---|
2 | /* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
|
---|
3 | * CxImage version 6.0.0 02/Feb/2008
|
---|
4 | */
|
---|
5 |
|
---|
6 | #include "ximage.h"
|
---|
7 |
|
---|
8 | ////////////////////////////////////////////////////////////////////////////////
|
---|
9 | /**
|
---|
10 | * returns the palette dimension in byte
|
---|
11 | */
|
---|
12 | DWORD CxImage::GetPaletteSize()
|
---|
13 | {
|
---|
14 | return (head.biClrUsed * sizeof(RGBQUAD));
|
---|
15 | }
|
---|
16 | ////////////////////////////////////////////////////////////////////////////////
|
---|
17 | void CxImage::SetPaletteColor(BYTE idx, BYTE r, BYTE g, BYTE b, BYTE alpha)
|
---|
18 | {
|
---|
19 | if ((pDib)&&(head.biClrUsed)){
|
---|
20 | BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
|
---|
21 | if (idx<head.biClrUsed){
|
---|
22 | long ldx=idx*sizeof(RGBQUAD);
|
---|
23 | iDst[ldx++] = (BYTE) b;
|
---|
24 | iDst[ldx++] = (BYTE) g;
|
---|
25 | iDst[ldx++] = (BYTE) r;
|
---|
26 | iDst[ldx] = (BYTE) alpha;
|
---|
27 | info.last_c_isvalid = false;
|
---|
28 | }
|
---|
29 | }
|
---|
30 | }
|
---|
31 | ////////////////////////////////////////////////////////////////////////////////
|
---|
32 | void CxImage::SetPaletteColor(BYTE idx, RGBQUAD c)
|
---|
33 | {
|
---|
34 | if ((pDib)&&(head.biClrUsed)){
|
---|
35 | BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
|
---|
36 | if (idx<head.biClrUsed){
|
---|
37 | long ldx=idx*sizeof(RGBQUAD);
|
---|
38 | iDst[ldx++] = (BYTE) c.rgbBlue;
|
---|
39 | iDst[ldx++] = (BYTE) c.rgbGreen;
|
---|
40 | iDst[ldx++] = (BYTE) c.rgbRed;
|
---|
41 | iDst[ldx] = (BYTE) c.rgbReserved;
|
---|
42 | info.last_c_isvalid = false;
|
---|
43 | }
|
---|
44 | }
|
---|
45 | }
|
---|
46 | ////////////////////////////////////////////////////////////////////////////////
|
---|
47 | void CxImage::SetPaletteColor(BYTE idx, COLORREF cr)
|
---|
48 | {
|
---|
49 | if ((pDib)&&(head.biClrUsed)){
|
---|
50 | BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
|
---|
51 | if (idx<head.biClrUsed){
|
---|
52 | long ldx=idx*sizeof(RGBQUAD);
|
---|
53 | iDst[ldx++] = (BYTE) GetBValue(cr);
|
---|
54 | iDst[ldx++] = (BYTE) GetGValue(cr);
|
---|
55 | iDst[ldx++] = (BYTE) GetRValue(cr);
|
---|
56 | iDst[ldx] = (BYTE) 0;
|
---|
57 | info.last_c_isvalid = false;
|
---|
58 | }
|
---|
59 | }
|
---|
60 | }
|
---|
61 | ////////////////////////////////////////////////////////////////////////////////
|
---|
62 | /**
|
---|
63 | * returns the pointer to the first palette index
|
---|
64 | */
|
---|
65 | RGBQUAD* CxImage::GetPalette() const
|
---|
66 | {
|
---|
67 | if ((pDib)&&(head.biClrUsed))
|
---|
68 | return (RGBQUAD*)((BYTE*)pDib + sizeof(BITMAPINFOHEADER));
|
---|
69 | return NULL;
|
---|
70 | }
|
---|
71 | ////////////////////////////////////////////////////////////////////////////////
|
---|
72 | /**
|
---|
73 | * Returns the color of the specified index.
|
---|
74 | */
|
---|
75 | RGBQUAD CxImage::GetPaletteColor(BYTE idx)
|
---|
76 | {
|
---|
77 | RGBQUAD rgb = {0,0,0,0};
|
---|
78 | if ((pDib)&&(head.biClrUsed)){
|
---|
79 | BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
|
---|
80 | if (idx<head.biClrUsed){
|
---|
81 | long ldx=idx*sizeof(RGBQUAD);
|
---|
82 | rgb.rgbBlue = iDst[ldx++];
|
---|
83 | rgb.rgbGreen=iDst[ldx++];
|
---|
84 | rgb.rgbRed =iDst[ldx++];
|
---|
85 | rgb.rgbReserved = iDst[ldx];
|
---|
86 | }
|
---|
87 | }
|
---|
88 | return rgb;
|
---|
89 | }
|
---|
90 | ////////////////////////////////////////////////////////////////////////////////
|
---|
91 | /**
|
---|
92 | * Returns the palette index of the specified pixel.
|
---|
93 | */
|
---|
94 | BYTE CxImage::GetPixelIndex(long x,long y)
|
---|
95 | {
|
---|
96 | if ((pDib==NULL)||(head.biClrUsed==0)) return 0;
|
---|
97 |
|
---|
98 | if ((x<0)||(y<0)||(x>=head.biWidth)||(y>=head.biHeight)) {
|
---|
99 | if (info.nBkgndIndex >= 0) return (BYTE)info.nBkgndIndex;
|
---|
100 | else return *info.pImage;
|
---|
101 | }
|
---|
102 | if (head.biBitCount==8){
|
---|
103 | return info.pImage[y*info.dwEffWidth + x];
|
---|
104 | } else {
|
---|
105 | BYTE pos;
|
---|
106 | BYTE iDst= info.pImage[y*info.dwEffWidth + (x*head.biBitCount >> 3)];
|
---|
107 | if (head.biBitCount==4){
|
---|
108 | pos = (BYTE)(4*(1-x%2));
|
---|
109 | iDst &= (0x0F<<pos);
|
---|
110 | return (BYTE)(iDst >> pos);
|
---|
111 | } else if (head.biBitCount==1){
|
---|
112 | pos = (BYTE)(7-x%8);
|
---|
113 | iDst &= (0x01<<pos);
|
---|
114 | return (BYTE)(iDst >> pos);
|
---|
115 | }
|
---|
116 | }
|
---|
117 | return 0;
|
---|
118 | }
|
---|
119 | ////////////////////////////////////////////////////////////////////////////////
|
---|
120 | BYTE CxImage::BlindGetPixelIndex(const long x,const long y)
|
---|
121 | {
|
---|
122 | #ifdef _DEBUG
|
---|
123 | if ((pDib==NULL) || (head.biClrUsed==0) || !IsInside(x,y))
|
---|
124 | #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
|
---|
125 | throw 0;
|
---|
126 | #else
|
---|
127 | return 0;
|
---|
128 | #endif
|
---|
129 | #endif
|
---|
130 |
|
---|
131 | if (head.biBitCount==8){
|
---|
132 | return info.pImage[y*info.dwEffWidth + x];
|
---|
133 | } else {
|
---|
134 | BYTE pos;
|
---|
135 | BYTE iDst= info.pImage[y*info.dwEffWidth + (x*head.biBitCount >> 3)];
|
---|
136 | if (head.biBitCount==4){
|
---|
137 | pos = (BYTE)(4*(1-x%2));
|
---|
138 | iDst &= (0x0F<<pos);
|
---|
139 | return (BYTE)(iDst >> pos);
|
---|
140 | } else if (head.biBitCount==1){
|
---|
141 | pos = (BYTE)(7-x%8);
|
---|
142 | iDst &= (0x01<<pos);
|
---|
143 | return (BYTE)(iDst >> pos);
|
---|
144 | }
|
---|
145 | }
|
---|
146 | return 0;
|
---|
147 | }
|
---|
148 | ////////////////////////////////////////////////////////////////////////////////
|
---|
149 | RGBQUAD CxImage::GetPixelColor(long x,long y, bool bGetAlpha)
|
---|
150 | {
|
---|
151 | // RGBQUAD rgb={0,0,0,0};
|
---|
152 | RGBQUAD rgb=info.nBkgndColor; //<mpwolski>
|
---|
153 | if ((pDib==NULL)||(x<0)||(y<0)||
|
---|
154 | (x>=head.biWidth)||(y>=head.biHeight)){
|
---|
155 | if (info.nBkgndIndex >= 0){
|
---|
156 | if (head.biBitCount<24) return GetPaletteColor((BYTE)info.nBkgndIndex);
|
---|
157 | else return info.nBkgndColor;
|
---|
158 | } else if (pDib) return GetPixelColor(0,0);
|
---|
159 | return rgb;
|
---|
160 | }
|
---|
161 |
|
---|
162 | if (head.biClrUsed){
|
---|
163 | rgb = GetPaletteColor(BlindGetPixelIndex(x,y));
|
---|
164 | } else {
|
---|
165 | BYTE* iDst = info.pImage + y*info.dwEffWidth + x*3;
|
---|
166 | rgb.rgbBlue = *iDst++;
|
---|
167 | rgb.rgbGreen= *iDst++;
|
---|
168 | rgb.rgbRed = *iDst;
|
---|
169 | }
|
---|
170 | #if CXIMAGE_SUPPORT_ALPHA
|
---|
171 | if (pAlpha && bGetAlpha) rgb.rgbReserved = BlindAlphaGet(x,y);
|
---|
172 | #else
|
---|
173 | rgb.rgbReserved = 0;
|
---|
174 | #endif //CXIMAGE_SUPPORT_ALPHA
|
---|
175 | return rgb;
|
---|
176 | }
|
---|
177 | ////////////////////////////////////////////////////////////////////////////////
|
---|
178 | /**
|
---|
179 | * This is (a bit) faster version of GetPixelColor.
|
---|
180 | * It tests bounds only in debug mode (_DEBUG defined).
|
---|
181 | *
|
---|
182 | * It is an error to request out-of-borders pixel with this method.
|
---|
183 | * In DEBUG mode an exception will be thrown, and data will be violated in non-DEBUG mode.
|
---|
184 | * \author ***bd*** 2.2004
|
---|
185 | */
|
---|
186 | RGBQUAD CxImage::BlindGetPixelColor(const long x,const long y, bool bGetAlpha)
|
---|
187 | {
|
---|
188 | RGBQUAD rgb;
|
---|
189 | #ifdef _DEBUG
|
---|
190 | if ((pDib==NULL) || !IsInside(x,y))
|
---|
191 | #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
|
---|
192 | throw 0;
|
---|
193 | #else
|
---|
194 | {rgb.rgbReserved = 0; return rgb;}
|
---|
195 | #endif
|
---|
196 | #endif
|
---|
197 |
|
---|
198 | if (head.biClrUsed){
|
---|
199 | rgb = GetPaletteColor(BlindGetPixelIndex(x,y));
|
---|
200 | } else {
|
---|
201 | BYTE* iDst = info.pImage + y*info.dwEffWidth + x*3;
|
---|
202 | rgb.rgbBlue = *iDst++;
|
---|
203 | rgb.rgbGreen= *iDst++;
|
---|
204 | rgb.rgbRed = *iDst;
|
---|
205 | rgb.rgbReserved = 0; //needed for images without alpha layer
|
---|
206 | }
|
---|
207 | #if CXIMAGE_SUPPORT_ALPHA
|
---|
208 | if (pAlpha && bGetAlpha) rgb.rgbReserved = BlindAlphaGet(x,y);
|
---|
209 | #else
|
---|
210 | rgb.rgbReserved = 0;
|
---|
211 | #endif //CXIMAGE_SUPPORT_ALPHA
|
---|
212 | return rgb;
|
---|
213 | }
|
---|
214 | ////////////////////////////////////////////////////////////////////////////////
|
---|
215 | BYTE CxImage::GetPixelGray(long x, long y)
|
---|
216 | {
|
---|
217 | RGBQUAD color = GetPixelColor(x,y);
|
---|
218 | return (BYTE)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue);
|
---|
219 | }
|
---|
220 | ////////////////////////////////////////////////////////////////////////////////
|
---|
221 | void CxImage::BlindSetPixelIndex(long x,long y,BYTE i)
|
---|
222 | {
|
---|
223 | #ifdef _DEBUG
|
---|
224 | if ((pDib==NULL)||(head.biClrUsed==0)||
|
---|
225 | (x<0)||(y<0)||(x>=head.biWidth)||(y>=head.biHeight))
|
---|
226 | #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
|
---|
227 | throw 0;
|
---|
228 | #else
|
---|
229 | return;
|
---|
230 | #endif
|
---|
231 | #endif
|
---|
232 |
|
---|
233 | if (head.biBitCount==8){
|
---|
234 | info.pImage[y*info.dwEffWidth + x]=i;
|
---|
235 | return;
|
---|
236 | } else {
|
---|
237 | BYTE pos;
|
---|
238 | BYTE* iDst= info.pImage + y*info.dwEffWidth + (x*head.biBitCount >> 3);
|
---|
239 | if (head.biBitCount==4){
|
---|
240 | pos = (BYTE)(4*(1-x%2));
|
---|
241 | *iDst &= ~(0x0F<<pos);
|
---|
242 | *iDst |= ((i & 0x0F)<<pos);
|
---|
243 | return;
|
---|
244 | } else if (head.biBitCount==1){
|
---|
245 | pos = (BYTE)(7-x%8);
|
---|
246 | *iDst &= ~(0x01<<pos);
|
---|
247 | *iDst |= ((i & 0x01)<<pos);
|
---|
248 | return;
|
---|
249 | }
|
---|
250 | }
|
---|
251 | }
|
---|
252 | ////////////////////////////////////////////////////////////////////////////////
|
---|
253 | void CxImage::SetPixelIndex(long x,long y,BYTE i)
|
---|
254 | {
|
---|
255 | if ((pDib==NULL)||(head.biClrUsed==0)||
|
---|
256 | (x<0)||(y<0)||(x>=head.biWidth)||(y>=head.biHeight)) return ;
|
---|
257 |
|
---|
258 | if (head.biBitCount==8){
|
---|
259 | info.pImage[y*info.dwEffWidth + x]=i;
|
---|
260 | return;
|
---|
261 | } else {
|
---|
262 | BYTE pos;
|
---|
263 | BYTE* iDst= info.pImage + y*info.dwEffWidth + (x*head.biBitCount >> 3);
|
---|
264 | if (head.biBitCount==4){
|
---|
265 | pos = (BYTE)(4*(1-x%2));
|
---|
266 | *iDst &= ~(0x0F<<pos);
|
---|
267 | *iDst |= ((i & 0x0F)<<pos);
|
---|
268 | return;
|
---|
269 | } else if (head.biBitCount==1){
|
---|
270 | pos = (BYTE)(7-x%8);
|
---|
271 | *iDst &= ~(0x01<<pos);
|
---|
272 | *iDst |= ((i & 0x01)<<pos);
|
---|
273 | return;
|
---|
274 | }
|
---|
275 | }
|
---|
276 | }
|
---|
277 | ////////////////////////////////////////////////////////////////////////////////
|
---|
278 | void CxImage::SetPixelColor(long x,long y,COLORREF cr)
|
---|
279 | {
|
---|
280 | SetPixelColor(x,y,RGBtoRGBQUAD(cr));
|
---|
281 | }
|
---|
282 | ////////////////////////////////////////////////////////////////////////////////
|
---|
283 | void CxImage::BlindSetPixelColor(long x,long y,RGBQUAD c, bool bSetAlpha)
|
---|
284 | {
|
---|
285 | #ifdef _DEBUG
|
---|
286 | if ((pDib==NULL)||(x<0)||(y<0)||
|
---|
287 | (x>=head.biWidth)||(y>=head.biHeight))
|
---|
288 | #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
|
---|
289 | throw 0;
|
---|
290 | #else
|
---|
291 | return;
|
---|
292 | #endif
|
---|
293 | #endif
|
---|
294 | if (head.biClrUsed)
|
---|
295 | BlindSetPixelIndex(x,y,GetNearestIndex(c));
|
---|
296 | else {
|
---|
297 | BYTE* iDst = info.pImage + y*info.dwEffWidth + x*3;
|
---|
298 | *iDst++ = c.rgbBlue;
|
---|
299 | *iDst++ = c.rgbGreen;
|
---|
300 | *iDst = c.rgbRed;
|
---|
301 | }
|
---|
302 | #if CXIMAGE_SUPPORT_ALPHA
|
---|
303 | if (bSetAlpha) AlphaSet(x,y,c.rgbReserved);
|
---|
304 | #endif //CXIMAGE_SUPPORT_ALPHA
|
---|
305 | }
|
---|
306 | ////////////////////////////////////////////////////////////////////////////////
|
---|
307 | void CxImage::SetPixelColor(long x,long y,RGBQUAD c, bool bSetAlpha)
|
---|
308 | {
|
---|
309 | if ((pDib==NULL)||(x<0)||(y<0)||
|
---|
310 | (x>=head.biWidth)||(y>=head.biHeight)) return;
|
---|
311 | if (head.biClrUsed)
|
---|
312 | BlindSetPixelIndex(x,y,GetNearestIndex(c));
|
---|
313 | else {
|
---|
314 | BYTE* iDst = info.pImage + y*info.dwEffWidth + x*3;
|
---|
315 | *iDst++ = c.rgbBlue;
|
---|
316 | *iDst++ = c.rgbGreen;
|
---|
317 | *iDst = c.rgbRed;
|
---|
318 | }
|
---|
319 | #if CXIMAGE_SUPPORT_ALPHA
|
---|
320 | if (bSetAlpha) AlphaSet(x,y,c.rgbReserved);
|
---|
321 | #endif //CXIMAGE_SUPPORT_ALPHA
|
---|
322 | }
|
---|
323 | ////////////////////////////////////////////////////////////////////////////////
|
---|
324 | /**
|
---|
325 | * Blends the current pixel color with a new color.
|
---|
326 | * \param x,y = pixel
|
---|
327 | * \param c = new color
|
---|
328 | * \param blend = can be from 0 (no effect) to 1 (full effect).
|
---|
329 | * \param bSetAlpha = if true, blends also the alpha component stored in c.rgbReserved
|
---|
330 | */
|
---|
331 | void CxImage::BlendPixelColor(long x,long y,RGBQUAD c, float blend, bool bSetAlpha)
|
---|
332 | {
|
---|
333 | if ((pDib==NULL)||(x<0)||(y<0)||
|
---|
334 | (x>=head.biWidth)||(y>=head.biHeight)) return;
|
---|
335 |
|
---|
336 | int a0 = (int)(256*blend);
|
---|
337 | int a1 = 256 - a0;
|
---|
338 |
|
---|
339 | RGBQUAD c0 = BlindGetPixelColor(x,y);
|
---|
340 | c.rgbRed = (BYTE)((c.rgbRed * a0 + c0.rgbRed * a1)>>8);
|
---|
341 | c.rgbBlue = (BYTE)((c.rgbBlue * a0 + c0.rgbBlue * a1)>>8);
|
---|
342 | c.rgbGreen = (BYTE)((c.rgbGreen * a0 + c0.rgbGreen * a1)>>8);
|
---|
343 |
|
---|
344 | if (head.biClrUsed)
|
---|
345 | BlindSetPixelIndex(x,y,GetNearestIndex(c));
|
---|
346 | else {
|
---|
347 | BYTE* iDst = info.pImage + y*info.dwEffWidth + x*3;
|
---|
348 | *iDst++ = c.rgbBlue;
|
---|
349 | *iDst++ = c.rgbGreen;
|
---|
350 | *iDst = c.rgbRed;
|
---|
351 | #if CXIMAGE_SUPPORT_ALPHA
|
---|
352 | if (bSetAlpha) AlphaSet(x,y,c.rgbReserved);
|
---|
353 | #endif //CXIMAGE_SUPPORT_ALPHA
|
---|
354 | }
|
---|
355 | }
|
---|
356 | ////////////////////////////////////////////////////////////////////////////////
|
---|
357 | /**
|
---|
358 | * Returns the best palette index that matches a specified color.
|
---|
359 | */
|
---|
360 | BYTE CxImage::GetNearestIndex(RGBQUAD c)
|
---|
361 | {
|
---|
362 | if ((pDib==NULL)||(head.biClrUsed==0)) return 0;
|
---|
363 |
|
---|
364 | // <RJ> check matching with the previous result
|
---|
365 | if (info.last_c_isvalid && (*(long*)&info.last_c == *(long*)&c)) return info.last_c_index;
|
---|
366 | info.last_c = c;
|
---|
367 | info.last_c_isvalid = true;
|
---|
368 |
|
---|
369 | BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
|
---|
370 | long distance=200000;
|
---|
371 | int i,j = 0;
|
---|
372 | long k,l;
|
---|
373 | int m = (int)(head.biClrImportant==0 ? head.biClrUsed : head.biClrImportant);
|
---|
374 | for(i=0,l=0;i<m;i++,l+=sizeof(RGBQUAD)){
|
---|
375 | k = (iDst[l]-c.rgbBlue)*(iDst[l]-c.rgbBlue)+
|
---|
376 | (iDst[l+1]-c.rgbGreen)*(iDst[l+1]-c.rgbGreen)+
|
---|
377 | (iDst[l+2]-c.rgbRed)*(iDst[l+2]-c.rgbRed);
|
---|
378 | // k = abs(iDst[l]-c.rgbBlue)+abs(iDst[l+1]-c.rgbGreen)+abs(iDst[l+2]-c.rgbRed);
|
---|
379 | if (k==0){
|
---|
380 | j=i;
|
---|
381 | break;
|
---|
382 | }
|
---|
383 | if (k<distance){
|
---|
384 | distance=k;
|
---|
385 | j=i;
|
---|
386 | }
|
---|
387 | }
|
---|
388 | info.last_c_index = (BYTE)j;
|
---|
389 | return (BYTE)j;
|
---|
390 | }
|
---|
391 | ////////////////////////////////////////////////////////////////////////////////
|
---|
392 | /**
|
---|
393 | * swaps the blue and red components (for RGB images)
|
---|
394 | * \param buffer : pointer to the pixels
|
---|
395 | * \param length : number of bytes to swap. lenght may not exceed the scan line.
|
---|
396 | */
|
---|
397 | void CxImage::RGBtoBGR(BYTE *buffer, int length)
|
---|
398 | {
|
---|
399 | if (buffer && (head.biClrUsed==0)){
|
---|
400 | BYTE temp;
|
---|
401 | length = min(length,(int)info.dwEffWidth);
|
---|
402 | length = min(length,(int)(3*head.biWidth));
|
---|
403 | for (int i=0;i<length;i+=3){
|
---|
404 | temp = buffer[i]; buffer[i] = buffer[i+2]; buffer[i+2] = temp;
|
---|
405 | }
|
---|
406 | }
|
---|
407 | }
|
---|
408 | ////////////////////////////////////////////////////////////////////////////////
|
---|
409 | RGBQUAD CxImage::RGBtoRGBQUAD(COLORREF cr)
|
---|
410 | {
|
---|
411 | RGBQUAD c;
|
---|
412 | c.rgbRed = GetRValue(cr); /* get R, G, and B out of DWORD */
|
---|
413 | c.rgbGreen = GetGValue(cr);
|
---|
414 | c.rgbBlue = GetBValue(cr);
|
---|
415 | c.rgbReserved=0;
|
---|
416 | return c;
|
---|
417 | }
|
---|
418 | ////////////////////////////////////////////////////////////////////////////////
|
---|
419 | COLORREF CxImage::RGBQUADtoRGB (RGBQUAD c)
|
---|
420 | {
|
---|
421 | return RGB(c.rgbRed,c.rgbGreen,c.rgbBlue);
|
---|
422 | }
|
---|
423 | ////////////////////////////////////////////////////////////////////////////////
|
---|
424 | /**
|
---|
425 | * Returns the color of the specified index.
|
---|
426 | * \param i = palette index
|
---|
427 | * \param r, g, b = output color channels
|
---|
428 | */
|
---|
429 | bool CxImage::GetPaletteColor(BYTE i, BYTE* r, BYTE* g, BYTE* b)
|
---|
430 | {
|
---|
431 | RGBQUAD* ppal=GetPalette();
|
---|
432 | if (ppal) {
|
---|
433 | *r = ppal[i].rgbRed;
|
---|
434 | *g = ppal[i].rgbGreen;
|
---|
435 | *b = ppal[i].rgbBlue;
|
---|
436 | return true;
|
---|
437 | }
|
---|
438 | return false;
|
---|
439 | }
|
---|
440 | ////////////////////////////////////////////////////////////////////////////////
|
---|
441 | void CxImage::SetPalette(DWORD n, BYTE *r, BYTE *g, BYTE *b)
|
---|
442 | {
|
---|
443 | if ((!r)||(pDib==NULL)||(head.biClrUsed==0)) return;
|
---|
444 | if (!g) g = r;
|
---|
445 | if (!b) b = g;
|
---|
446 | RGBQUAD* ppal=GetPalette();
|
---|
447 | DWORD m=min(n,head.biClrUsed);
|
---|
448 | for (DWORD i=0; i<m;i++){
|
---|
449 | ppal[i].rgbRed=r[i];
|
---|
450 | ppal[i].rgbGreen=g[i];
|
---|
451 | ppal[i].rgbBlue=b[i];
|
---|
452 | }
|
---|
453 | info.last_c_isvalid = false;
|
---|
454 | }
|
---|
455 | ////////////////////////////////////////////////////////////////////////////////
|
---|
456 | void CxImage::SetPalette(rgb_color *rgb,DWORD nColors)
|
---|
457 | {
|
---|
458 | if ((!rgb)||(pDib==NULL)||(head.biClrUsed==0)) return;
|
---|
459 | RGBQUAD* ppal=GetPalette();
|
---|
460 | DWORD m=min(nColors,head.biClrUsed);
|
---|
461 | for (DWORD i=0; i<m;i++){
|
---|
462 | ppal[i].rgbRed=rgb[i].r;
|
---|
463 | ppal[i].rgbGreen=rgb[i].g;
|
---|
464 | ppal[i].rgbBlue=rgb[i].b;
|
---|
465 | }
|
---|
466 | info.last_c_isvalid = false;
|
---|
467 | }
|
---|
468 | ////////////////////////////////////////////////////////////////////////////////
|
---|
469 | void CxImage::SetPalette(RGBQUAD* pPal,DWORD nColors)
|
---|
470 | {
|
---|
471 | if ((pPal==NULL)||(pDib==NULL)||(head.biClrUsed==0)) return;
|
---|
472 | memcpy(GetPalette(),pPal,min(GetPaletteSize(),nColors*sizeof(RGBQUAD)));
|
---|
473 | info.last_c_isvalid = false;
|
---|
474 | }
|
---|
475 | ////////////////////////////////////////////////////////////////////////////////
|
---|
476 | /**
|
---|
477 | * Sets (or replaces) the palette to gray scale palette.
|
---|
478 | * The function doesn't change the pixels; for standard
|
---|
479 | * gray scale conversion use GrayScale().
|
---|
480 | */
|
---|
481 | void CxImage::SetGrayPalette()
|
---|
482 | {
|
---|
483 | if ((pDib==NULL)||(head.biClrUsed==0)) return;
|
---|
484 | RGBQUAD* pal=GetPalette();
|
---|
485 | for (DWORD ni=0;ni<head.biClrUsed;ni++)
|
---|
486 | pal[ni].rgbBlue=pal[ni].rgbGreen = pal[ni].rgbRed = (BYTE)(ni*(255/(head.biClrUsed-1)));
|
---|
487 | }
|
---|
488 | ////////////////////////////////////////////////////////////////////////////////
|
---|
489 | /**
|
---|
490 | * Colorize the palette.
|
---|
491 | * \sa Colorize
|
---|
492 | */
|
---|
493 | void CxImage::BlendPalette(COLORREF cr,long perc)
|
---|
494 | {
|
---|
495 | if ((pDib==NULL)||(head.biClrUsed==0)) return;
|
---|
496 | BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
|
---|
497 | DWORD i,r,g,b;
|
---|
498 | RGBQUAD* pPal=(RGBQUAD*)iDst;
|
---|
499 | r = GetRValue(cr);
|
---|
500 | g = GetGValue(cr);
|
---|
501 | b = GetBValue(cr);
|
---|
502 | if (perc>100) perc=100;
|
---|
503 | for(i=0;i<head.biClrUsed;i++){
|
---|
504 | pPal[i].rgbBlue=(BYTE)((pPal[i].rgbBlue*(100-perc)+b*perc)/100);
|
---|
505 | pPal[i].rgbGreen =(BYTE)((pPal[i].rgbGreen*(100-perc)+g*perc)/100);
|
---|
506 | pPal[i].rgbRed =(BYTE)((pPal[i].rgbRed*(100-perc)+r*perc)/100);
|
---|
507 | }
|
---|
508 | }
|
---|
509 | ////////////////////////////////////////////////////////////////////////////////
|
---|
510 | /**
|
---|
511 | * Returns true if the image has 256 colors and a linear grey scale palette.
|
---|
512 | */
|
---|
513 | bool CxImage::IsGrayScale()
|
---|
514 | {
|
---|
515 | RGBQUAD* ppal=GetPalette();
|
---|
516 | if(!(pDib && ppal && head.biClrUsed)) return false;
|
---|
517 | for(DWORD i=0;i<head.biClrUsed;i++){
|
---|
518 | if (ppal[i].rgbBlue!=i || ppal[i].rgbGreen!=i || ppal[i].rgbRed!=i) return false;
|
---|
519 | }
|
---|
520 | return true;
|
---|
521 | }
|
---|
522 | ////////////////////////////////////////////////////////////////////////////////
|
---|
523 | /**
|
---|
524 | * swap two indexes in the image and their colors in the palette
|
---|
525 | */
|
---|
526 | void CxImage::SwapIndex(BYTE idx1, BYTE idx2)
|
---|
527 | {
|
---|
528 | RGBQUAD* ppal=GetPalette();
|
---|
529 | if(!(pDib && ppal)) return;
|
---|
530 | //swap the colors
|
---|
531 | RGBQUAD tempRGB=GetPaletteColor(idx1);
|
---|
532 | SetPaletteColor(idx1,GetPaletteColor(idx2));
|
---|
533 | SetPaletteColor(idx2,tempRGB);
|
---|
534 | //swap the pixels
|
---|
535 | BYTE idx;
|
---|
536 | for(long y=0; y < head.biHeight; y++){
|
---|
537 | for(long x=0; x < head.biWidth; x++){
|
---|
538 | idx=BlindGetPixelIndex(x,y);
|
---|
539 | if (idx==idx1) BlindSetPixelIndex(x,y,idx2);
|
---|
540 | if (idx==idx2) BlindSetPixelIndex(x,y,idx1);
|
---|
541 | }
|
---|
542 | }
|
---|
543 | }
|
---|
544 | ////////////////////////////////////////////////////////////////////////////////
|
---|
545 | /**
|
---|
546 | * swap Red and Blue colors
|
---|
547 | */
|
---|
548 | void CxImage::SwapRGB2BGR()
|
---|
549 | {
|
---|
550 | if (!pDib) return;
|
---|
551 |
|
---|
552 | if (head.biClrUsed){
|
---|
553 | RGBQUAD* ppal=GetPalette();
|
---|
554 | BYTE b;
|
---|
555 | if(!ppal) return;
|
---|
556 | for(WORD a=0;a<head.biClrUsed;a++){
|
---|
557 | b=ppal[a].rgbBlue; ppal[a].rgbBlue=ppal[a].rgbRed; ppal[a].rgbRed=b;
|
---|
558 | }
|
---|
559 | } else {
|
---|
560 | for(long y=0;y<head.biHeight;y++){
|
---|
561 | RGBtoBGR(GetBits(y),3*head.biWidth);
|
---|
562 | }
|
---|
563 | }
|
---|
564 | }
|
---|
565 | ////////////////////////////////////////////////////////////////////////////////
|
---|
566 | bool CxImage::IsTransparent(long x, long y)
|
---|
567 | {
|
---|
568 | if (!pDib) return false;
|
---|
569 |
|
---|
570 | if (info.nBkgndIndex>=0){
|
---|
571 | if (head.biClrUsed){
|
---|
572 | if (GetPixelIndex(x,y) == info.nBkgndIndex) return true;
|
---|
573 | } else {
|
---|
574 | RGBQUAD ct = info.nBkgndColor;
|
---|
575 | RGBQUAD c = GetPixelColor(x,y,false);
|
---|
576 | if (*(long*)&c==*(long*)&ct) return true;
|
---|
577 | }
|
---|
578 | }
|
---|
579 |
|
---|
580 | #if CXIMAGE_SUPPORT_ALPHA
|
---|
581 | if (pAlpha) return AlphaGet(x,y)==0;
|
---|
582 | #endif
|
---|
583 |
|
---|
584 | return false;
|
---|
585 | }
|
---|
586 | ////////////////////////////////////////////////////////////////////////////////
|
---|
587 | bool CxImage::GetTransparentMask(CxImage* iDst)
|
---|
588 | {
|
---|
589 | if (!pDib) return false;
|
---|
590 |
|
---|
591 | CxImage tmp;
|
---|
592 | tmp.Create(head.biWidth, head.biHeight, 1, GetType());
|
---|
593 | tmp.SetStdPalette();
|
---|
594 | tmp.Clear(0);
|
---|
595 |
|
---|
596 | for(long y=0; y<head.biHeight; y++){
|
---|
597 | for(long x=0; x<head.biWidth; x++){
|
---|
598 | if (IsTransparent(x,y)){
|
---|
599 | tmp.BlindSetPixelIndex(x,y,1);
|
---|
600 | }
|
---|
601 | }
|
---|
602 | }
|
---|
603 |
|
---|
604 | if (iDst) iDst->Transfer(tmp);
|
---|
605 | else Transfer(tmp);
|
---|
606 |
|
---|
607 | return true;
|
---|
608 | }
|
---|
609 | ////////////////////////////////////////////////////////////////////////////////
|
---|
610 | /**
|
---|
611 | * Checks if image has the same palette, if any.
|
---|
612 | * \param img = image to compare.
|
---|
613 | * \param bCheckAlpha = check also the rgbReserved field.
|
---|
614 | */
|
---|
615 | bool CxImage::IsSamePalette(CxImage &img, bool bCheckAlpha)
|
---|
616 | {
|
---|
617 | if (head.biClrUsed != img.head.biClrUsed)
|
---|
618 | return false;
|
---|
619 | if (head.biClrUsed == 0)
|
---|
620 | return false;
|
---|
621 |
|
---|
622 | RGBQUAD c1,c2;
|
---|
623 | for (DWORD n=0; n<head.biClrUsed; n++){
|
---|
624 | c1 = GetPaletteColor((BYTE)n);
|
---|
625 | c2 = img.GetPaletteColor((BYTE)n);
|
---|
626 | if (c1.rgbRed != c2.rgbRed) return false;
|
---|
627 | if (c1.rgbBlue != c2.rgbBlue) return false;
|
---|
628 | if (c1.rgbGreen != c2.rgbGreen) return false;
|
---|
629 | if (bCheckAlpha && (c1.rgbReserved != c2.rgbReserved)) return false;
|
---|
630 | }
|
---|
631 | return true;
|
---|
632 | }
|
---|
633 | ////////////////////////////////////////////////////////////////////////////////
|
---|
634 | /**
|
---|
635 | * \sa SetClrImportant
|
---|
636 | */
|
---|
637 | DWORD CxImage::GetClrImportant() const
|
---|
638 | {
|
---|
639 | return head.biClrImportant;
|
---|
640 | }
|
---|
641 | ////////////////////////////////////////////////////////////////////////////////
|
---|
642 | /**
|
---|
643 | * sets the maximum number of colors that some functions like
|
---|
644 | * DecreaseBpp() or GetNearestIndex() will use on indexed images
|
---|
645 | * \param ncolors should be less than 2^bpp,
|
---|
646 | * or 0 if all the colors are important.
|
---|
647 | */
|
---|
648 | void CxImage::SetClrImportant(DWORD ncolors)
|
---|
649 | {
|
---|
650 | if (ncolors==0 || ncolors>256) {
|
---|
651 | head.biClrImportant = 0;
|
---|
652 | return;
|
---|
653 | }
|
---|
654 |
|
---|
655 | switch(head.biBitCount){
|
---|
656 | case 1:
|
---|
657 | head.biClrImportant = min(ncolors,2);
|
---|
658 | break;
|
---|
659 | case 4:
|
---|
660 | head.biClrImportant = min(ncolors,16);
|
---|
661 | break;
|
---|
662 | case 8:
|
---|
663 | head.biClrImportant = ncolors;
|
---|
664 | break;
|
---|
665 | }
|
---|
666 | return;
|
---|
667 | }
|
---|
668 | ////////////////////////////////////////////////////////////////////////////////
|
---|
669 | /**
|
---|
670 | * Returns pointer to pixel. Currently implemented only for truecolor images.
|
---|
671 | *
|
---|
672 | * \param x,y - coordinates
|
---|
673 | *
|
---|
674 | * \return pointer to first byte of pixel data
|
---|
675 | *
|
---|
676 | * \author ***bd*** 2.2004
|
---|
677 | */
|
---|
678 | void* CxImage::BlindGetPixelPointer(const long x, const long y)
|
---|
679 | {
|
---|
680 | #ifdef _DEBUG
|
---|
681 | if ((pDib==NULL) || !IsInside(x,y))
|
---|
682 | #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
|
---|
683 | throw 0;
|
---|
684 | #else
|
---|
685 | return 0;
|
---|
686 | #endif
|
---|
687 | #endif
|
---|
688 | if (!IsIndexed())
|
---|
689 | return info.pImage + y*info.dwEffWidth + x*3;
|
---|
690 | else
|
---|
691 | return 0;
|
---|
692 | }
|
---|
693 | ////////////////////////////////////////////////////////////////////////////////
|
---|
694 | void CxImage::DrawLine(int StartX, int EndX, int StartY, int EndY, COLORREF cr)
|
---|
695 | {
|
---|
696 | DrawLine(StartX, EndX, StartY, EndY, RGBtoRGBQUAD(cr));
|
---|
697 | }
|
---|
698 | ////////////////////////////////////////////////////////////////////////////////
|
---|
699 | void CxImage::DrawLine(int StartX, int EndX, int StartY, int EndY, RGBQUAD color, bool bSetAlpha)
|
---|
700 | {
|
---|
701 | if (!pDib) return;
|
---|
702 | //////////////////////////////////////////////////////
|
---|
703 | // Draws a line using the Bresenham line algorithm
|
---|
704 | // Thanks to Jordan DeLozier <JDL>
|
---|
705 | //////////////////////////////////////////////////////
|
---|
706 | int x1 = StartX;
|
---|
707 | int y1 = StartY;
|
---|
708 | int x = x1; // Start x off at the first pixel
|
---|
709 | int y = y1; // Start y off at the first pixel
|
---|
710 | int x2 = EndX;
|
---|
711 | int y2 = EndY;
|
---|
712 |
|
---|
713 | int xinc1,xinc2,yinc1,yinc2; // Increasing values
|
---|
714 | int den, num, numadd,numpixels;
|
---|
715 | int deltax = abs(x2 - x1); // The difference between the x's
|
---|
716 | int deltay = abs(y2 - y1); // The difference between the y's
|
---|
717 |
|
---|
718 | // Get Increasing Values
|
---|
719 | if (x2 >= x1) { // The x-values are increasing
|
---|
720 | xinc1 = 1;
|
---|
721 | xinc2 = 1;
|
---|
722 | } else { // The x-values are decreasing
|
---|
723 | xinc1 = -1;
|
---|
724 | xinc2 = -1;
|
---|
725 | }
|
---|
726 |
|
---|
727 | if (y2 >= y1) { // The y-values are increasing
|
---|
728 | yinc1 = 1;
|
---|
729 | yinc2 = 1;
|
---|
730 | } else { // The y-values are decreasing
|
---|
731 | yinc1 = -1;
|
---|
732 | yinc2 = -1;
|
---|
733 | }
|
---|
734 |
|
---|
735 | // Actually draw the line
|
---|
736 | if (deltax >= deltay) // There is at least one x-value for every y-value
|
---|
737 | {
|
---|
738 | xinc1 = 0; // Don't change the x when numerator >= denominator
|
---|
739 | yinc2 = 0; // Don't change the y for every iteration
|
---|
740 | den = deltax;
|
---|
741 | num = deltax / 2;
|
---|
742 | numadd = deltay;
|
---|
743 | numpixels = deltax; // There are more x-values than y-values
|
---|
744 | }
|
---|
745 | else // There is at least one y-value for every x-value
|
---|
746 | {
|
---|
747 | xinc2 = 0; // Don't change the x for every iteration
|
---|
748 | yinc1 = 0; // Don't change the y when numerator >= denominator
|
---|
749 | den = deltay;
|
---|
750 | num = deltay / 2;
|
---|
751 | numadd = deltax;
|
---|
752 | numpixels = deltay; // There are more y-values than x-values
|
---|
753 | }
|
---|
754 |
|
---|
755 | for (int curpixel = 0; curpixel <= numpixels; curpixel++)
|
---|
756 | {
|
---|
757 | // Draw the current pixel
|
---|
758 | SetPixelColor(x,y,color,bSetAlpha);
|
---|
759 |
|
---|
760 | num += numadd; // Increase the numerator by the top of the fraction
|
---|
761 | if (num >= den) // Check if numerator >= denominator
|
---|
762 | {
|
---|
763 | num -= den; // Calculate the new numerator value
|
---|
764 | x += xinc1; // Change the x as appropriate
|
---|
765 | y += yinc1; // Change the y as appropriate
|
---|
766 | }
|
---|
767 | x += xinc2; // Change the x as appropriate
|
---|
768 | y += yinc2; // Change the y as appropriate
|
---|
769 | }
|
---|
770 | }
|
---|
771 | ////////////////////////////////////////////////////////////////////////////////
|
---|
772 | /**
|
---|
773 | * Sets a palette with standard colors for 1, 4 and 8 bpp images.
|
---|
774 | */
|
---|
775 | void CxImage::SetStdPalette()
|
---|
776 | {
|
---|
777 | if (!pDib) return;
|
---|
778 | switch (head.biBitCount){
|
---|
779 | case 8:
|
---|
780 | {
|
---|
781 | const BYTE pal256[1024] = {0,0,0,0,0,0,128,0,0,128,0,0,0,128,128,0,128,0,0,0,128,0,128,0,128,128,0,0,192,192,192,0,
|
---|
782 | 192,220,192,0,240,202,166,0,212,240,255,0,177,226,255,0,142,212,255,0,107,198,255,0,
|
---|
783 | 72,184,255,0,37,170,255,0,0,170,255,0,0,146,220,0,0,122,185,0,0,98,150,0,0,74,115,0,0,
|
---|
784 | 50,80,0,212,227,255,0,177,199,255,0,142,171,255,0,107,143,255,0,72,115,255,0,37,87,255,0,0,
|
---|
785 | 85,255,0,0,73,220,0,0,61,185,0,0,49,150,0,0,37,115,0,0,25,80,0,212,212,255,0,177,177,255,0,
|
---|
786 | 142,142,255,0,107,107,255,0,72,72,255,0,37,37,255,0,0,0,254,0,0,0,220,0,0,0,185,0,0,0,150,0,
|
---|
787 | 0,0,115,0,0,0,80,0,227,212,255,0,199,177,255,0,171,142,255,0,143,107,255,0,115,72,255,0,
|
---|
788 | 87,37,255,0,85,0,255,0,73,0,220,0,61,0,185,0,49,0,150,0,37,0,115,0,25,0,80,0,240,212,255,0,
|
---|
789 | 226,177,255,0,212,142,255,0,198,107,255,0,184,72,255,0,170,37,255,0,170,0,255,0,146,0,220,0,
|
---|
790 | 122,0,185,0,98,0,150,0,74,0,115,0,50,0,80,0,255,212,255,0,255,177,255,0,255,142,255,0,255,107,255,0,
|
---|
791 | 255,72,255,0,255,37,255,0,254,0,254,0,220,0,220,0,185,0,185,0,150,0,150,0,115,0,115,0,80,0,80,0,
|
---|
792 | 255,212,240,0,255,177,226,0,255,142,212,0,255,107,198,0,255,72,184,0,255,37,170,0,255,0,170,0,
|
---|
793 | 220,0,146,0,185,0,122,0,150,0,98,0,115,0,74,0,80,0,50,0,255,212,227,0,255,177,199,0,255,142,171,0,
|
---|
794 | 255,107,143,0,255,72,115,0,255,37,87,0,255,0,85,0,220,0,73,0,185,0,61,0,150,0,49,0,115,0,37,0,
|
---|
795 | 80,0,25,0,255,212,212,0,255,177,177,0,255,142,142,0,255,107,107,0,255,72,72,0,255,37,37,0,254,0,
|
---|
796 | 0,0,220,0,0,0,185,0,0,0,150,0,0,0,115,0,0,0,80,0,0,0,255,227,212,0,255,199,177,0,255,171,142,0,
|
---|
797 | 255,143,107,0,255,115,72,0,255,87,37,0,255,85,0,0,220,73,0,0,185,61,0,0,150,49,0,0,115,37,0,
|
---|
798 | 0,80,25,0,0,255,240,212,0,255,226,177,0,255,212,142,0,255,198,107,0,255,184,72,0,255,170,37,0,
|
---|
799 | 255,170,0,0,220,146,0,0,185,122,0,0,150,98,0,0,115,74,0,0,80,50,0,0,255,255,212,0,255,255,177,0,
|
---|
800 | 255,255,142,0,255,255,107,0,255,255,72,0,255,255,37,0,254,254,0,0,220,220,0,0,185,185,0,0,150,150,0,
|
---|
801 | 0,115,115,0,0,80,80,0,0,240,255,212,0,226,255,177,0,212,255,142,0,198,255,107,0,184,255,72,0,
|
---|
802 | 170,255,37,0,170,255,0,0,146,220,0,0,122,185,0,0,98,150,0,0,74,115,0,0,50,80,0,0,227,255,212,0,
|
---|
803 | 199,255,177,0,171,255,142,0,143,255,107,0,115,255,72,0,87,255,37,0,85,255,0,0,73,220,0,0,61,185,0,
|
---|
804 | 0,49,150,0,0,37,115,0,0,25,80,0,0,212,255,212,0,177,255,177,0,142,255,142,0,107,255,107,0,72,255,72,0,
|
---|
805 | 37,255,37,0,0,254,0,0,0,220,0,0,0,185,0,0,0,150,0,0,0,115,0,0,0,80,0,0,212,255,227,0,177,255,199,0,
|
---|
806 | 142,255,171,0,107,255,143,0,72,255,115,0,37,255,87,0,0,255,85,0,0,220,73,0,0,185,61,0,0,150,49,0,0,
|
---|
807 | 115,37,0,0,80,25,0,212,255,240,0,177,255,226,0,142,255,212,0,107,255,198,0,72,255,184,0,37,255,170,0,
|
---|
808 | 0,255,170,0,0,220,146,0,0,185,122,0,0,150,98,0,0,115,74,0,0,80,50,0,212,255,255,0,177,255,255,0,
|
---|
809 | 142,255,255,0,107,255,255,0,72,255,255,0,37,255,255,0,0,254,254,0,0,220,220,0,0,185,185,0,0,
|
---|
810 | 150,150,0,0,115,115,0,0,80,80,0,242,242,242,0,230,230,230,0,218,218,218,0,206,206,206,0,194,194,194,0,
|
---|
811 | 182,182,182,0,170,170,170,0,158,158,158,0,146,146,146,0,134,134,134,0,122,122,122,0,110,110,110,0,
|
---|
812 | 98,98,98,0,86,86,86,0,74,74,74,0,62,62,62,0,50,50,50,0,38,38,38,0,26,26,26,0,14,14,14,0,240,251,255,0,
|
---|
813 | 164,160,160,0,128,128,128,0,0,0,255,0,0,255,0,0,0,255,255,0,255,0,0,0,255,0,255,0,255,255,0,0,255,255,255,0};
|
---|
814 | memcpy(GetPalette(),pal256,1024);
|
---|
815 | break;
|
---|
816 | }
|
---|
817 | case 4:
|
---|
818 | {
|
---|
819 | const BYTE pal16[64]={0,0,0,0,0,0,128,0,0,128,0,0,0,128,128,0,128,0,0,0,128,0,128,0,128,128,0,0,192,192,192,0,
|
---|
820 | 128,128,128,0,0,0,255,0,0,255,0,0,0,255,255,0,255,0,0,0,255,0,255,0,255,255,0,0,255,255,255,0};
|
---|
821 | memcpy(GetPalette(),pal16,64);
|
---|
822 | break;
|
---|
823 | }
|
---|
824 | case 1:
|
---|
825 | {
|
---|
826 | const BYTE pal2[8]={0,0,0,0,255,255,255,0};
|
---|
827 | memcpy(GetPalette(),pal2,8);
|
---|
828 | break;
|
---|
829 | }
|
---|
830 | }
|
---|
831 | info.last_c_isvalid = false;
|
---|
832 | return;
|
---|
833 | }
|
---|
834 | ////////////////////////////////////////////////////////////////////////////////
|
---|