2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
26 ===========================================================================
29 #include "../../idlib/precompiled.h"
32 #ifdef ID_DEBUG_MEMORY
39 // Original ColorPicker/DIB source by Rajiv Ramachandran <rrajivram@hotmail.com>
40 // included with Permission from the author
42 #define BIG_DISTANCE 10000000L
44 #define DIST(r1,g1,b1,r2,g2,b2) \
45 (long) (3L*(long)((r1)-(r2))*(long)((r1)-(r2)) + \
46 4L*(long)((g1)-(g2))*(long)((g1)-(g2)) + \
47 2L*(long)((b1)-(b2))*(long)((b1)-(b2)))
50 static unsigned char masktable[] = { 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 };
54 CDIB::CDIB(HANDLE hDib,int nBits)
62 CreateFromHandle(hDib,nBits);
71 void CDIB::DestroyDIB()
73 if(m_pVoid) free(m_pVoid);
75 if(m_pLinePtr) free(m_pLinePtr);
80 BOOL CDIB::Create(int width,int height,int bits)
86 // ASSERT(bits == 24 || bits == 8);
88 BITMAPINFOHEADER bmInfo;
90 memset(&bmInfo,0,sizeof(BITMAPINFOHEADER));
91 bmInfo.biSize = sizeof(BITMAPINFOHEADER);
92 bmInfo.biWidth = width;
93 bmInfo.biHeight = height;
95 bmInfo.biBitCount = bits;
96 bmInfo.biCompression = BI_RGB;
97 return Create(bmInfo);
100 BOOL CDIB::Create(BITMAPINFOHEADER& bmInfo)
102 bytes = (bmInfo.biBitCount*bmInfo.biWidth)>>3;
103 height = bmInfo.biHeight;
104 width = bmInfo.biWidth;
105 // bmInfo.biHeight *= -1;
106 while(bytes%4) bytes++;
109 size = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*GetPaletteSize(bmInfo) + bytes*height;
110 m_pVoid = (void *)malloc(size);
111 if(!m_pVoid) return FALSE;
113 m_pInfo = (PBITMAPINFO )m_pVoid;
114 memcpy((void *)&m_pInfo->bmiHeader,(void *)&bmInfo,sizeof(BITMAPINFOHEADER));
115 m_pRGB = (RGBQUAD *)((unsigned char *)m_pVoid + sizeof(BITMAPINFOHEADER)) ;
116 m_pBits = (unsigned char *)(m_pVoid) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*GetPaletteSize();
120 m_pLinePtr = (BYTE **)malloc(sizeof(BYTE *)*height);
121 if(!m_pLinePtr) return FALSE;
122 for(i=0,ptr=m_pLinePtr; i < height; i++,ptr++)
124 //*ptr = (int)(m_pBits)+(i*bytes);
125 //*ptr = (int)GetLinePtr(i);
126 *ptr = m_pBits + (height-i-1)*bytes;
132 void CDIB::SetPalette(unsigned char *palette)
137 size = GetPaletteSize();
138 for(i=0,rgb = m_pRGB; i < size; i++,rgb++,palette+=3)
142 rgb->rgbRed = Gamma[palette[0]];
143 rgb->rgbGreen = Gamma[palette[1]];
144 rgb->rgbBlue = Gamma[palette[2]];
148 rgb->rgbRed = palette[0];
149 rgb->rgbGreen = palette[1];
150 rgb->rgbBlue = palette[2];
152 rgb->rgbReserved = (BYTE)0;
156 void CDIB::SetPalette(RGBQUAD *pRGB)
160 size = GetPaletteSize();
161 memcpy(m_pRGB,pRGB,size*sizeof(RGBQUAD));
165 int CDIB::GetPaletteSize()
167 return GetPaletteSize(m_pInfo->bmiHeader);
171 int CDIB::GetPaletteSize(BITMAPINFOHEADER& bmInfo)
173 switch(bmInfo.biBitCount)
187 void CDIB::SetPixel(int x,int y,COLORREF color)
190 ASSERT(x >= 0 && y >=0);
191 ASSERT(x < width && y < height);
193 // ptr = m_pBits + (y*bytes) + x * 3;
194 ptr = (unsigned char *)m_pLinePtr[y];
196 *ptr++ = (unsigned char)GetBValue(color);
197 *ptr++ = (unsigned char)GetGValue(color);
198 *ptr++ = (unsigned char)GetRValue(color);
201 void CDIB::SetPixel8(int x,int y,unsigned char color)
203 unsigned char *ptr,*aptr;
204 ASSERT(x >= 0 && y >=0);
205 ASSERT(x < width && y < height);
207 // ptr = m_pBits + (y*bytes) + x ;
208 // ptr = (unsigned char *)m_pLinePtr[y] ;
216 COLORREF CDIB::GetPixel(int x,int y)
220 ASSERT(x >= 0 && y >=0);
221 ASSERT(x < width && y < height);
223 // ptr = m_pBits + (y*bytes) + x * 3;
226 color = RGB(*(ptr+2),*(ptr+1),*ptr);
230 CBitmap *CDIB::GetTempBitmap(CDC& dc)
234 ASSERT(m_pVoid != NULL);
235 hBitmap = CreateDIBitmap(dc.m_hDC,
236 (PBITMAPINFOHEADER)m_pInfo,
238 (const void *)m_pBits,
242 if(hBitmap == NULL) return NULL;
243 temp = CBitmap::FromHandle(hBitmap);
247 CBitmap *CDIB::GetBitmap(CDC& dc)
251 ASSERT(m_pVoid != NULL);
252 hBitmap = CreateDIBitmap(dc.m_hDC,
253 (PBITMAPINFOHEADER)m_pInfo,
255 (const void *)m_pBits,
259 if(hBitmap == NULL) return NULL;
260 temp = CBitmap::FromHandle(hBitmap);
265 temp->GetBitmap(&bmp);
266 lpVoid = malloc(bmp.bmWidthBytes*bmp.bmHeight);
267 if(!lpVoid) return NULL;
268 temp->GetBitmapBits(bmp.bmWidthBytes*bmp.bmHeight,lpVoid);
269 CBitmap *newBmp = new CBitmap;
270 newBmp->CreateBitmapIndirect(&bmp);
271 newBmp->SetBitmapBits(bmp.bmWidthBytes*bmp.bmHeight,lpVoid);
279 void CDIB::CopyLine(int source,int dest)
281 unsigned char *src,*dst;
282 ASSERT(source <= height && source >= 0);
283 ASSERT(dest <= height && dest >= 0);
284 if(source == dest) return;
285 src = GetLinePtr(source);
286 dst = GetLinePtr(dest);
287 memcpy(dst,src,bytes);
290 void CDIB::InitDIB(COLORREF color)
295 if(m_pInfo->bmiHeader.biBitCount == 24)
297 unsigned char col[3];
298 col[0]=GetBValue(color);
299 col[1]=GetGValue(color);
300 col[2]=GetRValue(color);
301 for(i=0,ptr = m_pBits; i < height; i++)
303 ptr = m_pBits + i*bytes;
304 for(j=0; j < width ; j++,ptr+=3)
312 for(i=0,ptr = m_pBits; i < height; i++,ptr+=bytes)
314 memset(ptr,(BYTE)color,bytes);
320 void CDIB::BitBlt(HDC hDest,int nXDest,int nYDest,int nWidth,int nHeight,int xSrc,int ySrc)
322 SetDIBitsToDevice(hDest,nXDest,nYDest,nWidth,nHeight,xSrc,Height()-ySrc-nHeight,0,Height(),m_pBits,m_pInfo,DIB_RGB_COLORS);
325 void CDIB::StretchBlt(HDC hDest,int nXDest,int nYDest,int nDWidth,int nDHeight,int xSrc,int ySrc,int nSWidth,int nSHeight)
328 err = StretchDIBits(hDest,nXDest,nYDest,nDWidth,nDHeight,xSrc,ySrc,nSWidth,nSHeight,m_pBits,(CONST BITMAPINFO * )&m_pInfo->bmiHeader,DIB_RGB_COLORS,SRCCOPY);
331 void CDIB::ExpandBlt(int nXDest,int nYDest,int xRatio,int yRatio,CDIB& dibSrc,int xSrc,int ySrc,int nSWidth,int nSHeight)
333 SetPalette(dibSrc.m_pRGB);
335 nSWidth = xSrc+nSWidth > dibSrc.width ? dibSrc.width-xSrc : nSWidth;
336 nSHeight = ySrc+nSHeight > dibSrc.height? dibSrc.height-ySrc : nSHeight;
338 Expand(nXDest,nYDest,xRatio,yRatio,dibSrc,xSrc,ySrc,nSWidth,nSHeight);
341 void CDIB::Expand(int nXDest,int nYDest,int xRatio,int yRatio,CDIB& dibSrc,int xSrc,int ySrc,int nSWidth,int nSHeight)
343 int xNum,yNum,xErr,yErr;
344 int nDWidth,nDHeight;
346 nDWidth = nSWidth*xRatio;
347 nDHeight = nSHeight*yRatio;
349 nDWidth = nXDest+nDWidth > width ? width-nXDest : nDWidth ;
350 nDHeight = nYDest+nDHeight > height ? height-nYDest : nDHeight;
352 xNum = nDWidth/xRatio;
353 yNum = nDHeight/yRatio;
354 xErr = nDWidth%xRatio;
355 yErr = nDHeight%yRatio;
357 unsigned char *buffer,*srcPtr,*destPtr,*ptr;
360 buffer = (unsigned char *)malloc(nDWidth+20);
363 for(i=0; i < yNum; i++,ySrc++)
365 srcPtr = dibSrc.GetLinePtr(ySrc) + xSrc;
367 for(j=0; j < xNum; j++,ptr+=xRatio)
369 memset(ptr,*(srcPtr+j),xRatio);
372 memset(ptr,(unsigned char)k,xErr);
373 for(j=0; j < yRatio ; j++,nYDest++)
375 destPtr = GetLinePtr(nYDest) + nXDest;
376 memcpy(destPtr,buffer,nDWidth);
379 for(j=0; j < yErr; j++,nYDest++)
381 destPtr = GetLinePtr(nYDest) + nXDest;
382 memcpy(destPtr,buffer,nDWidth);
387 void CDIB::StretchBlt(int nXDest,int nYDest,int nDWidth,int nDHeight,CDIB& dibSrc,int xSrc,int ySrc,int nSWidth,int nSHeight)
389 SetPalette(dibSrc.m_pRGB);
390 nDWidth = nXDest+nDWidth > width ? width-nXDest : nDWidth ;
391 nDHeight = nYDest+nDHeight > height ? height-nYDest : nDHeight;
393 nSWidth = xSrc+nSWidth > dibSrc.width ? dibSrc.width-xSrc : nSWidth;
394 nSHeight = ySrc+nSHeight > dibSrc.height? dibSrc.height-ySrc : nSHeight;
399 xDiv = nDWidth/nSWidth;
400 xMod = nDWidth%nSWidth;
402 yDiv = nDHeight/nSHeight;
403 yMod = nDHeight%nSHeight;
405 if(!xMod && !yMod && xDiv > 0 && yDiv > 0)
407 ExpandBlt(nXDest,nYDest,xDiv,yDiv,dibSrc,xSrc,ySrc,nSWidth,nSHeight);
411 unsigned char *tempPtr,*srcPix,*destPix,*q;
412 tempPtr = (unsigned char *)malloc(nDWidth+20);
415 for(i=yErr=m=0; i < nSHeight; i++)
417 srcPix = dibSrc.GetLinePtr(i+ySrc) + xSrc;
419 for(j=l=xErr=0; j < nSWidth; j++,srcPix++)
429 while(l < nDWidth && x < k)
449 while(m < nDHeight && y < k)
451 destPix = GetLinePtr(m+nYDest) + nXDest;
452 memcpy(destPix,tempPtr,nDWidth);
459 destPix = GetLinePtr(m+nYDest) + nXDest;
460 memcpy(destPix,tempPtr,nDWidth);
466 void CDIB::BitBlt(int nXDest,int nYDest,int nWidth,int nHeight,CDIB& dibSrc,int nSrcX,int nSrcY,BYTE *colors)
468 SetPalette(dibSrc.m_pRGB);
493 nWidth = nXDest+nWidth > width ? width-nXDest : nWidth ;
494 nHeight = nYDest+nHeight > height ? height-nYDest : nHeight;
496 nWidth = nSrcX+nWidth > dibSrc.width ? dibSrc.width-nSrcX : nWidth;
497 nHeight = nSrcY+nHeight > dibSrc.height? dibSrc.height-nSrcY : nHeight;
499 nWidth = __max(0,nWidth);
500 nHeight = __max(0,nHeight);
502 unsigned char *srcPtr,*destPtr;
505 for(i=0,k=nSrcY,l=nYDest; i < nHeight; i++,k++,l++)
513 srcPtr = dibSrc.GetLinePtr(k);
514 destPtr = GetLinePtr(l);
515 memcpy(destPtr+nXDest,srcPtr+nSrcX,nWidth);
521 for(i=0,k=nSrcY,l=nYDest; i < nHeight; i++,k++,l++)
529 srcPtr = dibSrc.GetLinePtr(k)+nXDest;
530 destPtr = GetLinePtr(l)+nSrcX;
531 for(j=0; j < nWidth; j++,srcPtr++,destPtr++)
533 if(colors[*srcPtr]) *destPtr=*srcPtr;
540 unsigned char *CDIB::GetLinePtr(int line)
542 /*unsigned char *ptr;
543 ptr = m_pBits + (height-line-1)*bytes;
545 return m_pLinePtr[line];
548 BOOL CDIB::CopyDIB(CDIB& dib)
550 if(Create(dib.m_pInfo->bmiHeader))
552 SetPalette(dib.m_pRGB);
553 memcpy(m_pBits,dib.m_pBits,height*bytes);
559 void CDIB::ReplaceColor(unsigned char oldColor,unsigned char newColor)
563 for(i=0; i < height; i++)
566 for(j=0; j < width; j++)
568 if(ptr[j] == oldColor) ptr[j] = newColor;
574 CDIB& CDIB::operator=(CDIB& dib)
580 HANDLE CDIB::GetDIBits(int nStartX,int nStartY,int nCx,int nCy)
588 dib.Create(nCx,nCy,8);
589 dib.BitBlt(0,0,nCx,nCy,*this,0,0);
590 dib.SetPalette(m_pRGB);
591 return dib.DIBHandle();
596 DWORD CDIB::GetDIBSize()
598 return sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*GetPaletteSize() + bytes*height;
601 HANDLE CDIB::DIBHandle()
605 nSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*GetPaletteSize() + bytes*height;
606 hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE,nSize);
607 if(hMem == NULL) return NULL;
608 UCHAR *lpVoid,*pBits;
609 LPBITMAPINFOHEADER pHead;
611 lpVoid = (UCHAR *)GlobalLock(hMem);
612 pHead = (LPBITMAPINFOHEADER )lpVoid;
613 memcpy(pHead,&m_pInfo->bmiHeader,sizeof(BITMAPINFOHEADER));
614 pRgb = (RGBQUAD *)(lpVoid + sizeof(BITMAPINFOHEADER) );
615 memcpy(pRgb,m_pRGB,sizeof(RGBQUAD)*GetPaletteSize());
616 pBits = lpVoid + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*GetPaletteSize();
617 memcpy(pBits,m_pBits,height*bytes);
618 GlobalUnlock(lpVoid);
622 BOOL CDIB::CreateFromHandle(HANDLE hMem,int bits)
625 UCHAR *lpVoid,*pBits;
626 LPBITMAPINFOHEADER pHead;
628 lpVoid = (UCHAR *)GlobalLock(hMem);
629 pHead = (LPBITMAPINFOHEADER )lpVoid;
630 width = pHead->biWidth;
631 height = pHead->biHeight;
632 m_nBits = pHead->biBitCount;
633 if(pHead->biCompression != BI_RGB)
635 GlobalUnlock(lpVoid);
638 if(pHead->biBitCount >= 15)
640 if(pHead->biBitCount != 24)
642 GlobalUnlock(lpVoid);
648 GlobalUnlock(lpVoid);
651 pRgb = (RGBQUAD *)(lpVoid + sizeof(BITMAPINFOHEADER) );
652 memcpy(m_pRGB,pRgb,sizeof(RGBQUAD)*GetPaletteSize());
653 pBits = lpVoid + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*GetPaletteSize();
654 memcpy(m_pBits,pBits,height*bytes);
655 GlobalUnlock(lpVoid);
659 void CDIB::UseGamma(float fg,BOOL bUse)
662 m_fOldGamma = m_fGamma;
668 void CDIB::CreateGammaCurve()
673 Gamma[i]=(int)(255 * powf((double)i/255,m_fGamma) + (double)0.5);
679 void CDIB::GetPixel(UINT x,UINT y,int& pixel)
681 ASSERT(x < (UINT)Width());
682 ASSERT(y < (UINT)Height());
683 if(x >= (UINT)Width()) return;
684 if(y >= (UINT)Height()) return;
685 pixel=(GetLinePtr(y))[x];
688 BOOL CDIB::Make8Bit(CDIB& dib)
691 ASSERT(Width() == dib.Width());
692 ASSERT(Height() == dib.Height());
693 nBits = dib.GetBitCount();
697 return SwitchFromOne(dib);
700 return SwitchFromFour(dib);
703 return SwitchPalette(dib);
706 return SwitchFrom24(dib);
715 BOOL CDIB::SwitchFrom24(CDIB& dib)
718 unsigned char *sPtr,*dPtr;
721 memset(CachePtr,0,sizeof(CachePtr));
724 dPtr = GetLinePtr(i);
725 sPtr = dib.GetLinePtr(i);
726 for(j=0 ; j < w; j++,dPtr++,sPtr+=3)
728 *dPtr = ClosestColor((RGBQUAD *)sPtr);
736 BOOL CDIB::SwitchFromOne(CDIB& dib)
739 unsigned char *sPtr,*dPtr;
740 unsigned char cols[2];
743 memset(CachePtr,0,sizeof(CachePtr));
744 cols[0]=ClosestColor(dib.m_pRGB);
745 cols[1]=ClosestColor(dib.m_pRGB+1);
748 dPtr = GetLinePtr(i);
749 sPtr = dib.GetLinePtr(i);
750 for(j=0 ; j < w; j++,dPtr++)
752 if(!(sPtr[j>>3] & masktable[j&7])) *dPtr = cols[0];
753 else *dPtr = cols[1];
759 BOOL CDIB::SwitchFromFour(CDIB& dib)
762 unsigned char *sPtr,*dPtr;
763 unsigned char cols[16];
766 memset(CachePtr,0,sizeof(CachePtr));
767 for(i=0; i < 16; i++)
769 cols[i]=ClosestColor(dib.m_pRGB+i);
773 dPtr = GetLinePtr(i);
774 sPtr = dib.GetLinePtr(i);
775 for(j=0 ; j < w; j++,dPtr++)
777 if(!(j&1)) n = (*sPtr & 0xf0)>>4;
789 BOOL CDIB::SwitchPalette(CDIB& dib)
792 unsigned char *sPtr,*dPtr;
793 unsigned char cols[256];
796 memset(CachePtr,0,sizeof(CachePtr));
797 for(i=0; i < 256; i++)
799 cols[i]=ClosestColor(dib.m_pRGB+i);
803 dPtr = GetLinePtr(i);
804 sPtr = dib.GetLinePtr(i);
805 for(j=0 ; j < w; j++,sPtr++,dPtr++)
814 int CDIB::ClosestColor(RGBQUAD *pRgb)
816 unsigned int dist=BIG_DISTANCE,i,d,c;
817 RGBQUAD *pQuad=m_pRGB;
818 unsigned int pSize=GetPaletteSize();
819 for(i=0; i < pSize;i++)
823 if(!memcmp((void *)&CacheQuad[i],(void *)pRgb,3))
829 for(i=0; i < pSize; i++,pQuad++)
831 d = Distance(*pRgb,*pQuad);
849 unsigned int CDIB::Distance(RGBQUAD& rgb1,RGBQUAD& rgb2)
852 d = 3*(unsigned)((rgb1.rgbRed)-(rgb2.rgbRed))*(unsigned)((rgb1.rgbRed)-(rgb2.rgbRed));
853 d += 4*(unsigned)((rgb1.rgbGreen)-(rgb2.rgbGreen))*(unsigned)((rgb1.rgbGreen)-(rgb2.rgbGreen)) ;
854 d += 2*(unsigned)((rgb1.rgbBlue)-(rgb2.rgbBlue))*(unsigned)((rgb1.rgbBlue)-(rgb2.rgbBlue));
858 BOOL CDIB::OpenDIB(CString& csFileName)
861 if(!file.Open(csFileName,CFile::modeRead | CFile::typeBinary))
866 if(OpenBMP(csFileName)) return TRUE;
872 BOOL CDIB::SaveDIB(CString& csFileName,BitmapType type)
875 if(!file.Open(csFileName,CFile::modeCreate | CFile::typeBinary))
883 return SaveBMP(csFileName);
890 BOOL CDIB::SaveBMP(CString& csFileName)
892 BITMAPFILEHEADER bFile;
894 if(!file.Open(csFileName,CFile::modeWrite | CFile::typeBinary))
898 ::ZeroMemory(&bFile,sizeof(bFile));
899 memcpy((void *)&bFile.bfType,"BM",2);
900 bFile.bfSize = GetDIBSize() + sizeof(bFile);
901 bFile.bfOffBits = sizeof(BITMAPINFOHEADER) + GetPaletteSize()*sizeof(RGBQUAD) + sizeof(BITMAPFILEHEADER);
902 file.Write(&bFile,sizeof(bFile));
903 file.Write(m_pVoid,GetDIBSize());
909 BOOL CDIB::OpenBMP(CString& csFileName)
911 BITMAPFILEHEADER bFile;
912 BITMAPINFOHEADER head;
914 if(!file.Open(csFileName,CFile::modeRead | CFile::typeBinary))
918 file.Read(&bFile,sizeof(bFile));
919 if(memcmp((void *)&bFile.bfType,"BM",2))
924 file.Read(&head,sizeof(head));
930 file.Read(m_pRGB,sizeof(RGBQUAD)*GetPaletteSize());
931 file.Seek(bFile.bfOffBits,CFile::begin);
932 file.Read(m_pBits,height*bytes);
939 int CDIB::CountColors()
941 ASSERT(GetBitCount()==8);
942 BYTE colors[256],*ptr;
946 memset(colors,0,256);
950 for(j=0; j < w; j++,ptr++)
962 int CDIB::EnumColors(BYTE *array)
964 ASSERT(GetBitCount()==8);
973 for(j=0; j < w; j++,ptr++)
985 COLORREF CDIB::PaletteColor(int nIndex)
987 ASSERT(nIndex < 256);
988 RGBQUAD *pRGB= m_pRGB+nIndex;
989 return RGB(pRGB->rgbRed,pRGB->rgbGreen,pRGB->rgbBlue);
992 BOOL CDIB::SwitchFrom24(CDIB& dib)
995 unsigned char *sPtr,*dPtr;
996 BYTE *index_ptr=NULL;
1000 index_ptr = (BYTE *)malloc(0x7FFF+1);
1001 if(!index_ptr) return FALSE;
1002 memset(CachePtr,0,sizeof(CachePtr));
1003 for(i=0; i <= 0x7FFF; i++)
1005 rgb.rgbRed = (((i & 0x7C00)>>10) << 3) | 0x07;
1006 rgb.rgbGreen = (((i & 0x3e0)>>5) << 3) | 0x07;
1007 rgb.rgbBlue = ((i & 0x1F)<<3) | 0x07;
1008 index_ptr[i] = ClosestColor(&rgb);
1010 for(i=0; i < h; i++)
1012 dPtr = GetLinePtr(i);
1013 sPtr = dib.GetLinePtr(i);
1014 for(j=0 ; j < w; j++,dPtr++,sPtr+=3)
1016 c = (*sPtr >> 3) | ((*(sPtr+1) >> 3) << 5) | ((*(sPtr+2) >> 3) << 10);
1017 *dPtr = index_ptr[c];