[95] | 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 | ////////////////////////////////////////////////////////////////////////////////
|
---|