doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CDIB.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
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.
13 
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.
18 
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/>.
21 
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.
23 
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.
25 
26 ===========================================================================
27 */
28 
29 #include "../../idlib/precompiled.h"
30 #pragma hdrstop
31 
32 #ifdef ID_DEBUG_MEMORY
33 #undef new
34 #endif
35 
36 #include "math.h"
37 #include "CDIB.h"
38 
39 // Original ColorPicker/DIB source by Rajiv Ramachandran <rrajivram@hotmail.com>
40 // included with Permission from the author
41 
42 #define BIG_DISTANCE 10000000L
43 
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)))
48 
49 
50 static unsigned char masktable[] = { 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 };
51 
52 
53 
54 CDIB::CDIB(HANDLE hDib,int nBits)
55 {
56  m_pVoid = NULL;
57  m_pLinePtr = NULL;
59  width=height=0;
60  if(hDib)
61  {
62  CreateFromHandle(hDib,nBits);
63  }
64 }
65 
67 {
68  DestroyDIB();
69 }
70 
72 {
73  if(m_pVoid) free(m_pVoid);
74  m_pVoid = NULL;
75  if(m_pLinePtr) free(m_pLinePtr);
76  m_pLinePtr = NULL;
77 }
78 
79 
81 {
82  /*
83  Free existing image
84  */
85  DestroyDIB();
86 // ASSERT(bits == 24 || bits == 8);
87 
88 BITMAPINFOHEADER bmInfo;
89 
90  memset(&bmInfo,0,sizeof(BITMAPINFOHEADER));
91  bmInfo.biSize = sizeof(BITMAPINFOHEADER);
92  bmInfo.biWidth = width;
93  bmInfo.biHeight = height;
94  bmInfo.biPlanes = 1;
95  bmInfo.biBitCount = bits;
96  bmInfo.biCompression = BI_RGB;
97  return Create(bmInfo);
98 }
99 
100 BOOL CDIB::Create(BITMAPINFOHEADER& bmInfo)
101 {
102  bytes = (bmInfo.biBitCount*bmInfo.biWidth)>>3;
103  height = bmInfo.biHeight;
104  width = bmInfo.biWidth;
105 // bmInfo.biHeight *= -1;
106  while(bytes%4) bytes++;
107 
108  int size;
109  size = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*GetPaletteSize(bmInfo) + bytes*height;
110  m_pVoid = (void *)malloc(size);
111  if(!m_pVoid) return FALSE;
112 
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();
117 
118 int i;
119 BYTE **ptr;
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++)
123  {
124  //*ptr = (int)(m_pBits)+(i*bytes);
125  //*ptr = (int)GetLinePtr(i);
126  *ptr = m_pBits + (height-i-1)*bytes;
127  }
128  m_nFlags = 0;
129  return TRUE;
130 }
131 
132 void CDIB::SetPalette(unsigned char *palette)
133 {
134 int i,size;
135 RGBQUAD *rgb;
136  if(!palette) return;
137  size = GetPaletteSize();
138  for(i=0,rgb = m_pRGB; i < size; i++,rgb++,palette+=3)
139  {
140  if(m_bUseGamma)
141  {
142  rgb->rgbRed = Gamma[palette[0]];
143  rgb->rgbGreen = Gamma[palette[1]];
144  rgb->rgbBlue = Gamma[palette[2]];
145  }
146  else
147  {
148  rgb->rgbRed = palette[0];
149  rgb->rgbGreen = palette[1];
150  rgb->rgbBlue = palette[2];
151  }
152  rgb->rgbReserved = (BYTE)0;
153  }
154 }
155 
156 void CDIB::SetPalette(RGBQUAD *pRGB)
157 {
158 int size;
159  if(!pRGB) return;
160  size = GetPaletteSize();
161  memcpy(m_pRGB,pRGB,size*sizeof(RGBQUAD));
162 }
163 
164 
166 {
167  return GetPaletteSize(m_pInfo->bmiHeader);
168 }
169 
170 
171 int CDIB::GetPaletteSize(BITMAPINFOHEADER& bmInfo)
172 {
173  switch(bmInfo.biBitCount)
174  {
175  case 1:
176  return 2;
177  case 4:
178  return 16;
179  case 8:
180  return 256;
181  default:
182  return 0;
183  }
184 }
185 
186 
187 void CDIB::SetPixel(int x,int y,COLORREF color)
188 {
189 unsigned char *ptr;
190  ASSERT(x >= 0 && y >=0);
191  ASSERT(x < width && y < height);
192 
193 // ptr = m_pBits + (y*bytes) + x * 3;
194  ptr = (unsigned char *)m_pLinePtr[y];
195  ptr += x*3;
196  *ptr++ = (unsigned char)GetBValue(color);
197  *ptr++ = (unsigned char)GetGValue(color);
198  *ptr++ = (unsigned char)GetRValue(color);
199 }
200 
201 void CDIB::SetPixel8(int x,int y,unsigned char color)
202 {
203 unsigned char *ptr,*aptr;
204  ASSERT(x >= 0 && y >=0);
205  ASSERT(x < width && y < height);
206 
207 // ptr = m_pBits + (y*bytes) + x ;
208 // ptr = (unsigned char *)m_pLinePtr[y] ;
209  ptr = GetLinePtr(y);
210  aptr = ptr;
211  ptr += x;
212  *ptr = color;
213 }
214 
215 
216 COLORREF CDIB::GetPixel(int x,int y)
217 {
218 unsigned char *ptr;
219 COLORREF color;
220  ASSERT(x >= 0 && y >=0);
221  ASSERT(x < width && y < height);
222 
223 // ptr = m_pBits + (y*bytes) + x * 3;
224  ptr = GetLinePtr(y);
225  ptr += (x*3);
226  color = RGB(*(ptr+2),*(ptr+1),*ptr);
227  return color;
228 }
229 
230 CBitmap *CDIB::GetTempBitmap(CDC& dc)
231 {
232 HBITMAP hBitmap;
233 CBitmap *temp;
234  ASSERT(m_pVoid != NULL);
235  hBitmap = CreateDIBitmap(dc.m_hDC,
236  (PBITMAPINFOHEADER)m_pInfo,
237  CBM_INIT,
238  (const void *)m_pBits,
239  m_pInfo,
240  DIB_RGB_COLORS);
241 
242  if(hBitmap == NULL) return NULL;
243  temp = CBitmap::FromHandle(hBitmap);
244  return temp;
245 }
246 
247 CBitmap *CDIB::GetBitmap(CDC& dc)
248 {
249 HBITMAP hBitmap;
250 CBitmap *temp;
251  ASSERT(m_pVoid != NULL);
252  hBitmap = CreateDIBitmap(dc.m_hDC,
253  (PBITMAPINFOHEADER)m_pInfo,
254  CBM_INIT,
255  (const void *)m_pBits,
256  m_pInfo,
257  DIB_RGB_COLORS);
258 
259  if(hBitmap == NULL) return NULL;
260  temp = CBitmap::FromHandle(hBitmap);
261  if(temp)
262  {
263  BITMAP bmp;
264  LPVOID lpVoid;
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);
272  free(lpVoid);
273  return newBmp;
274  }
275  else return NULL;
276 
277 }
278 
279 void CDIB::CopyLine(int source,int dest)
280 {
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);
288 }
289 
290 void CDIB::InitDIB(COLORREF color)
291 {
292 int i,j;
293 unsigned char *ptr;
294 
295  if(m_pInfo->bmiHeader.biBitCount == 24)
296  {
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++)
302  {
303  ptr = m_pBits + i*bytes;
304  for(j=0; j < width ; j++,ptr+=3)
305  {
306  memcpy(ptr,col,3);
307  }
308  }
309  }
310  else
311  {
312  for(i=0,ptr = m_pBits; i < height; i++,ptr+=bytes)
313  {
314  memset(ptr,(BYTE)color,bytes);
315  }
316  }
317 }
318 
319 
320 void CDIB::BitBlt(HDC hDest,int nXDest,int nYDest,int nWidth,int nHeight,int xSrc,int ySrc)
321 {
322  SetDIBitsToDevice(hDest,nXDest,nYDest,nWidth,nHeight,xSrc,Height()-ySrc-nHeight,0,Height(),m_pBits,m_pInfo,DIB_RGB_COLORS);
323 }
324 
325 void CDIB::StretchBlt(HDC hDest,int nXDest,int nYDest,int nDWidth,int nDHeight,int xSrc,int ySrc,int nSWidth,int nSHeight)
326 {
327  int err;
328  err = StretchDIBits(hDest,nXDest,nYDest,nDWidth,nDHeight,xSrc,ySrc,nSWidth,nSHeight,m_pBits,(CONST BITMAPINFO * )&m_pInfo->bmiHeader,DIB_RGB_COLORS,SRCCOPY);
329 }
330 
331 void CDIB::ExpandBlt(int nXDest,int nYDest,int xRatio,int yRatio,CDIB& dibSrc,int xSrc,int ySrc,int nSWidth,int nSHeight)
332 {
333  SetPalette(dibSrc.m_pRGB);
334 
335  nSWidth = xSrc+nSWidth > dibSrc.width ? dibSrc.width-xSrc : nSWidth;
336  nSHeight = ySrc+nSHeight > dibSrc.height? dibSrc.height-ySrc : nSHeight;
337 
338  Expand(nXDest,nYDest,xRatio,yRatio,dibSrc,xSrc,ySrc,nSWidth,nSHeight);
339 }
340 
341 void CDIB::Expand(int nXDest,int nYDest,int xRatio,int yRatio,CDIB& dibSrc,int xSrc,int ySrc,int nSWidth,int nSHeight)
342 {
343 int xNum,yNum,xErr,yErr;
344 int nDWidth,nDHeight;
345 
346  nDWidth = nSWidth*xRatio;
347  nDHeight = nSHeight*yRatio;
348 
349  nDWidth = nXDest+nDWidth > width ? width-nXDest : nDWidth ;
350  nDHeight = nYDest+nDHeight > height ? height-nYDest : nDHeight;
351 
352  xNum = nDWidth/xRatio;
353  yNum = nDHeight/yRatio;
354  xErr = nDWidth%xRatio;
355  yErr = nDHeight%yRatio;
356 
357 unsigned char *buffer,*srcPtr,*destPtr,*ptr;
358 int i,j,k;
359 
360  buffer = (unsigned char *)malloc(nDWidth+20);
361  if(!buffer) return;
362 
363  for(i=0; i < yNum; i++,ySrc++)
364  {
365  srcPtr = dibSrc.GetLinePtr(ySrc) + xSrc;
366  ptr = buffer;
367  for(j=0; j < xNum; j++,ptr+=xRatio)
368  {
369  memset(ptr,*(srcPtr+j),xRatio);
370  k=*(srcPtr+j);
371  }
372  memset(ptr,(unsigned char)k,xErr);
373  for(j=0; j < yRatio ; j++,nYDest++)
374  {
375  destPtr = GetLinePtr(nYDest) + nXDest;
376  memcpy(destPtr,buffer,nDWidth);
377  }
378  }
379  for(j=0; j < yErr; j++,nYDest++)
380  {
381  destPtr = GetLinePtr(nYDest) + nXDest;
382  memcpy(destPtr,buffer,nDWidth);
383  }
384  free(buffer);
385 }
386 
387 void CDIB::StretchBlt(int nXDest,int nYDest,int nDWidth,int nDHeight,CDIB& dibSrc,int xSrc,int ySrc,int nSWidth,int nSHeight)
388 {
389  SetPalette(dibSrc.m_pRGB);
390  nDWidth = nXDest+nDWidth > width ? width-nXDest : nDWidth ;
391  nDHeight = nYDest+nDHeight > height ? height-nYDest : nDHeight;
392 
393  nSWidth = xSrc+nSWidth > dibSrc.width ? dibSrc.width-xSrc : nSWidth;
394  nSHeight = ySrc+nSHeight > dibSrc.height? dibSrc.height-ySrc : nSHeight;
395 
396 int xDiv,yDiv;
397 int xMod,yMod;
398 
399  xDiv = nDWidth/nSWidth;
400  xMod = nDWidth%nSWidth;
401 
402  yDiv = nDHeight/nSHeight;
403  yMod = nDHeight%nSHeight;
404 
405  if(!xMod && !yMod && xDiv > 0 && yDiv > 0)
406  {
407  ExpandBlt(nXDest,nYDest,xDiv,yDiv,dibSrc,xSrc,ySrc,nSWidth,nSHeight);
408  return;
409  }
410 
411 unsigned char *tempPtr,*srcPix,*destPix,*q;
412  tempPtr = (unsigned char *)malloc(nDWidth+20);
413 int i,j,k,l,x,y,m;
414 int xErr,yErr;
415  for(i=yErr=m=0; i < nSHeight; i++)
416  {
417  srcPix = dibSrc.GetLinePtr(i+ySrc) + xSrc;
418  q = tempPtr;
419  for(j=l=xErr=0; j < nSWidth; j++,srcPix++)
420  {
421  k = xDiv;
422  xErr += xMod;
423  if(xErr >= nSWidth)
424  {
425  k++;
426  xErr%=nSWidth;
427  }
428  x=0;
429  while(l < nDWidth && x < k)
430  {
431  *q++ = *srcPix;
432  l++;
433  x++;
434  }
435  }
436  while(l < nDWidth)
437  {
438  *q++=*srcPix;
439  l++;
440  }
441  k= yDiv;
442  yErr += yMod;
443  if(yErr >= nSHeight)
444  {
445  k++;
446  yErr%=nSHeight;
447  }
448  y=0;
449  while(m < nDHeight && y < k)
450  {
451  destPix = GetLinePtr(m+nYDest) + nXDest;
452  memcpy(destPix,tempPtr,nDWidth);
453  m++;
454  y++;
455  }
456  }
457  while(m < nDHeight )
458  {
459  destPix = GetLinePtr(m+nYDest) + nXDest;
460  memcpy(destPix,tempPtr,nDWidth);
461  m++;
462  }
463  free(tempPtr);
464 }
465 
466 void CDIB::BitBlt(int nXDest,int nYDest,int nWidth,int nHeight,CDIB& dibSrc,int nSrcX,int nSrcY,BYTE *colors)
467 {
468  SetPalette(dibSrc.m_pRGB);
469  if(nXDest < 0)
470  {
471  nSrcX -= nXDest;
472  nWidth += nXDest;
473  nXDest=0;
474  }
475  if(nYDest < 0)
476  {
477  nSrcY -= nYDest;
478  nHeight += nYDest;
479  nYDest=0;
480  }
481  if(nSrcX < 0)
482  {
483  nXDest -= nSrcX;
484  nWidth += nSrcX;
485  nSrcX=0;
486  }
487  if(nSrcY < 0)
488  {
489  nYDest -= nSrcY;
490  nHeight += nSrcY;
491  nSrcY=0;
492  }
493  nWidth = nXDest+nWidth > width ? width-nXDest : nWidth ;
494  nHeight = nYDest+nHeight > height ? height-nYDest : nHeight;
495 
496  nWidth = nSrcX+nWidth > dibSrc.width ? dibSrc.width-nSrcX : nWidth;
497  nHeight = nSrcY+nHeight > dibSrc.height? dibSrc.height-nSrcY : nHeight;
498 
499  nWidth = __max(0,nWidth);
500  nHeight = __max(0,nHeight);
501 int i,k,l,j;
502 unsigned char *srcPtr,*destPtr;
503  if(!colors)
504  {
505  for(i=0,k=nSrcY,l=nYDest; i < nHeight; i++,k++,l++)
506  {
507  if(k < 0 || l < 0)
508  {
509  continue;
510  }
511  else
512  {
513  srcPtr = dibSrc.GetLinePtr(k);
514  destPtr = GetLinePtr(l);
515  memcpy(destPtr+nXDest,srcPtr+nSrcX,nWidth);
516  }
517  }
518  }
519  else
520  {
521  for(i=0,k=nSrcY,l=nYDest; i < nHeight; i++,k++,l++)
522  {
523  if(k < 0 || l < 0)
524  {
525  continue;
526  }
527  else
528  {
529  srcPtr = dibSrc.GetLinePtr(k)+nXDest;
530  destPtr = GetLinePtr(l)+nSrcX;
531  for(j=0; j < nWidth; j++,srcPtr++,destPtr++)
532  {
533  if(colors[*srcPtr]) *destPtr=*srcPtr;
534  }
535  }
536  }
537  }
538 }
539 
540 unsigned char *CDIB::GetLinePtr(int line)
541 {
542 /*unsigned char *ptr;
543  ptr = m_pBits + (height-line-1)*bytes;
544  return ptr;*/
545  return m_pLinePtr[line];
546 }
547 
549 {
550  if(Create(dib.m_pInfo->bmiHeader))
551  {
552  SetPalette(dib.m_pRGB);
553  memcpy(m_pBits,dib.m_pBits,height*bytes);
554  return TRUE;
555  }
556  return FALSE;
557 }
558 
559 void CDIB::ReplaceColor(unsigned char oldColor,unsigned char newColor)
560 {
561 int i,j;
562 unsigned char *ptr;
563  for(i=0; i < height; i++)
564  {
565  ptr = GetLinePtr(i);
566  for(j=0; j < width; j++)
567  {
568  if(ptr[j] == oldColor) ptr[j] = newColor;
569  }
570  }
571 }
572 
573 
575 {
576  CopyDIB(dib);
577  return *this;
578 }
579 
580 HANDLE CDIB::GetDIBits(int nStartX,int nStartY,int nCx,int nCy)
581 {
582  if(nStartX == -1)
583  {
584  nStartX = nStartY=0;
585  nCx = width;
586  nCy = height;
587  CDIB dib;
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();
592  }
593  return DIBHandle();
594 }
595 
597 {
598  return sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*GetPaletteSize() + bytes*height;
599 }
600 
602 {
603 int nSize;
604 HANDLE hMem;
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;
610 RGBQUAD *pRgb;
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);
619  return hMem;
620 }
621 
623 {
624  DestroyDIB();
625 UCHAR *lpVoid,*pBits;
626 LPBITMAPINFOHEADER pHead;
627 RGBQUAD *pRgb;
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)
634  {
635  GlobalUnlock(lpVoid);
636  return FALSE;
637  }
638  if(pHead->biBitCount >= 15)
639  {
640  if(pHead->biBitCount != 24)
641  {
642  GlobalUnlock(lpVoid);
643  return FALSE;
644  }
645  }
646  if(!Create(*pHead))
647  {
648  GlobalUnlock(lpVoid);
649  return FALSE;
650  }
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);
656  return TRUE;
657 }
658 
659 void CDIB::UseGamma(float fg,BOOL bUse)
660 {
661  m_bUseGamma = bUse;
663  m_fGamma = fg;
665 }
666 
667 
669 {
670 int i;
671  for(i=0;i<256;++i)
672  {
673  Gamma[i]=(int)(255 * powf((double)i/255,m_fGamma) + (double)0.5);
674  }
675 }
676 
677 
678 
679 void CDIB::GetPixel(UINT x,UINT y,int& pixel)
680 {
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];
686 }
687 
689 {
690 int nBits;
691  ASSERT(Width() == dib.Width());
692  ASSERT(Height() == dib.Height());
693  nBits = dib.GetBitCount();
694  switch(nBits)
695  {
696  case 1:
697  return SwitchFromOne(dib);
698  break;
699  case 4:
700  return SwitchFromFour(dib);
701  break;
702  case 8:
703  return SwitchPalette(dib);
704  break;
705  case 24:
706  return SwitchFrom24(dib);
707  break;
708  default:
709  return FALSE;
710  }
711  return FALSE;
712 }
713 
714 /*
715 BOOL CDIB::SwitchFrom24(CDIB& dib)
716 {
717 int i,j,w,h;
718 unsigned char *sPtr,*dPtr;
719  w = Width();
720  h = Height();
721  memset(CachePtr,0,sizeof(CachePtr));
722  for(i=0; i < h; i++)
723  {
724  dPtr = GetLinePtr(i);
725  sPtr = dib.GetLinePtr(i);
726  for(j=0 ; j < w; j++,dPtr++,sPtr+=3)
727  {
728  *dPtr = ClosestColor((RGBQUAD *)sPtr);
729  }
730  }
731  return TRUE;
732 }
733 */
734 
735 
737 {
738 int i,j,w,h;
739 unsigned char *sPtr,*dPtr;
740 unsigned char cols[2];
741  w = Width();
742  h = Height();
743  memset(CachePtr,0,sizeof(CachePtr));
744  cols[0]=ClosestColor(dib.m_pRGB);
745  cols[1]=ClosestColor(dib.m_pRGB+1);
746  for(i=0; i < h; i++)
747  {
748  dPtr = GetLinePtr(i);
749  sPtr = dib.GetLinePtr(i);
750  for(j=0 ; j < w; j++,dPtr++)
751  {
752  if(!(sPtr[j>>3] & masktable[j&7])) *dPtr = cols[0];
753  else *dPtr = cols[1];
754  }
755  }
756  return TRUE;
757 }
758 
760 {
761 int i,n,j,w,h;
762 unsigned char *sPtr,*dPtr;
763 unsigned char cols[16];
764  w = Width();
765  h = Height();
766  memset(CachePtr,0,sizeof(CachePtr));
767  for(i=0; i < 16; i++)
768  {
769  cols[i]=ClosestColor(dib.m_pRGB+i);
770  }
771  for(i=0; i < h; i++)
772  {
773  dPtr = GetLinePtr(i);
774  sPtr = dib.GetLinePtr(i);
775  for(j=0 ; j < w; j++,dPtr++)
776  {
777  if(!(j&1)) n = (*sPtr & 0xf0)>>4;
778  else
779  {
780  n = *sPtr & 0x0f;
781  sPtr++;
782  }
783  *dPtr = cols[n];
784  }
785  }
786  return TRUE;
787 }
788 
790 {
791 int i,j,w,h;
792 unsigned char *sPtr,*dPtr;
793 unsigned char cols[256];
794  w = Width();
795  h = Height();
796  memset(CachePtr,0,sizeof(CachePtr));
797  for(i=0; i < 256; i++)
798  {
799  cols[i]=ClosestColor(dib.m_pRGB+i);
800  }
801  for(i=0; i < h; i++)
802  {
803  dPtr = GetLinePtr(i);
804  sPtr = dib.GetLinePtr(i);
805  for(j=0 ; j < w; j++,sPtr++,dPtr++)
806  {
807  *dPtr = cols[*sPtr];
808  }
809  }
810  return TRUE;
811 }
812 
813 
814 int CDIB::ClosestColor(RGBQUAD *pRgb)
815 {
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++)
820  {
821  if(CachePtr[i])
822  {
823  if(!memcmp((void *)&CacheQuad[i],(void *)pRgb,3))
824  {
825  return i;
826  }
827  }
828  }
829  for(i=0; i < pSize; i++,pQuad++)
830  {
831  d = Distance(*pRgb,*pQuad);
832  if(!d)
833  {
834  CacheQuad[i]=*pRgb;
835  CachePtr[i]=1;
836  return i;
837  }
838  if(dist > d)
839  {
840  c = i;
841  dist = d;
842  }
843  }
844  CacheQuad[c]=*pRgb;
845  CachePtr[c]=1;
846  return c;
847 }
848 
849 unsigned int CDIB::Distance(RGBQUAD& rgb1,RGBQUAD& rgb2)
850 {
851 unsigned int d;
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));
855  return d;
856 }
857 
858 BOOL CDIB::OpenDIB(CString& csFileName)
859 {
860 CFile file;
861  if(!file.Open(csFileName,CFile::modeRead | CFile::typeBinary))
862  {
863  return FALSE;
864  }
865  file.Close();
866  if(OpenBMP(csFileName)) return TRUE;
867  return FALSE;
868 }
869 
870 
871 
872 BOOL CDIB::SaveDIB(CString& csFileName,BitmapType type)
873 {
874 CFile file;
875  if(!file.Open(csFileName,CFile::modeCreate | CFile::typeBinary))
876  {
877  return FALSE;
878  }
879  file.Close();
880  switch(type)
881  {
882  case BMP:
883  return SaveBMP(csFileName);
884  default:
885  return FALSE;
886  }
887  return FALSE;
888 }
889 
890 BOOL CDIB::SaveBMP(CString& csFileName)
891 {
892 BITMAPFILEHEADER bFile;
893 CFile file;
894  if(!file.Open(csFileName,CFile::modeWrite | CFile::typeBinary))
895  {
896  return FALSE;
897  }
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());
904  file.Close();
905  return TRUE;
906 
907 }
908 
909 BOOL CDIB::OpenBMP(CString& csFileName)
910 {
911 BITMAPFILEHEADER bFile;
912 BITMAPINFOHEADER head;
913 CFile file;
914  if(!file.Open(csFileName,CFile::modeRead | CFile::typeBinary))
915  {
916  return FALSE;
917  }
918  file.Read(&bFile,sizeof(bFile));
919  if(memcmp((void *)&bFile.bfType,"BM",2))
920  {
921  file.Close();
922  return FALSE;
923  }
924  file.Read(&head,sizeof(head));
925  if(!Create(head))
926  {
927  file.Close();
928  return FALSE;
929  }
930  file.Read(m_pRGB,sizeof(RGBQUAD)*GetPaletteSize());
931  file.Seek(bFile.bfOffBits,CFile::begin);
932  file.Read(m_pBits,height*bytes);
933  file.Close();
934  return TRUE;
935 
936 }
937 
938 
940 {
941  ASSERT(GetBitCount()==8);
942 BYTE colors[256],*ptr;
943 int nNum=0,i,j,w,d;
944  w = Width();
945  d = Height();
946  memset(colors,0,256);
947  for(i=0; i < d; i++)
948  {
949  ptr = GetLinePtr(i);
950  for(j=0; j < w; j++,ptr++)
951  {
952  if(!colors[*ptr])
953  {
954  colors[*ptr]=1;
955  nNum++;
956  }
957  }
958  }
959  return nNum;
960 }
961 
962 int CDIB::EnumColors(BYTE *array)
963 {
964  ASSERT(GetBitCount()==8);
965 BYTE *ptr;
966 int nNum=0,i,j,w,d;
967  w = Width();
968  d = Height();
969  memset(array,0,256);
970  for(i=0; i < d; i++)
971  {
972  ptr = GetLinePtr(i);
973  for(j=0; j < w; j++,ptr++)
974  {
975  if(!array[*ptr])
976  {
977  array[*ptr]=1;
978  nNum++;
979  }
980  }
981  }
982  return nNum;
983 }
984 
985 COLORREF CDIB::PaletteColor(int nIndex)
986 {
987  ASSERT(nIndex < 256);
988 RGBQUAD *pRGB= m_pRGB+nIndex;
989  return RGB(pRGB->rgbRed,pRGB->rgbGreen,pRGB->rgbBlue);
990 }
991 
993 {
994 int i,j,w,h,c;
995 unsigned char *sPtr,*dPtr;
996 BYTE *index_ptr=NULL;
997 RGBQUAD rgb;
998  w = Width();
999  h = Height();
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++)
1004  {
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);
1009  }
1010  for(i=0; i < h; i++)
1011  {
1012  dPtr = GetLinePtr(i);
1013  sPtr = dib.GetLinePtr(i);
1014  for(j=0 ; j < w; j++,dPtr++,sPtr+=3)
1015  {
1016  c = (*sPtr >> 3) | ((*(sPtr+1) >> 3) << 5) | ((*(sPtr+2) >> 3) << 10);
1017  *dPtr = index_ptr[c];
1018  }
1019  }
1020  free(index_ptr);
1021  return TRUE;
1022 }
GLdouble GLdouble GLdouble GLdouble q
Definition: glext.h:2959
byte color[4]
Definition: MegaTexture.cpp:54
int width
Definition: CDIB.h:110
BOOL OpenBMP(CString &csFileName)
Definition: CDIB.cpp:909
HANDLE DIBHandle()
Definition: CDIB.cpp:601
void SetPalette(unsigned char *palette)
Definition: CDIB.cpp:132
BOOL CopyDIB(CDIB &dib)
Definition: CDIB.cpp:548
static unsigned int Distance(RGBQUAD &rgb1, RGBQUAD &rgb2)
Definition: CDIB.cpp:849
void DestroyDIB()
Definition: CDIB.cpp:71
int int int int int int ySrc
Definition: wglext.h:335
CONST PIXELFORMATDESCRIPTOR UINT
Definition: win_qgl.cpp:47
RGBQUAD * m_pRGB
Definition: CDIB.h:105
COLORREF GetPixel(int x, int y)
Definition: CDIB.cpp:216
virtual ~CDIB()
Definition: CDIB.cpp:66
int Height()
Definition: CDIB.h:79
const HANDLE const LPVOID const DWORD * pSize
Definition: wglext.h:574
DWORD
Definition: win_qgl.cpp:61
GLenum GLint GLint y
Definition: glext.h:2849
GLenum GLsizei n
Definition: glext.h:3705
case const int
Definition: Callbacks.cpp:52
typedef HANDLE(WINAPI *PFNWGLCREATEBUFFERREGIONARBPROC)(HDC hDC
PBITMAPINFO m_pInfo
Definition: CDIB.h:104
int height
Definition: CDIB.h:108
BOOL SwitchFromFour(CDIB &dib)
Definition: CDIB.cpp:759
float m_fGamma
Definition: CDIB.h:114
int GetBitCount()
Definition: CDIB.h:82
void StretchBlt(HDC hDest, int nXDest, int nYDest, int nDWidth, int nDHeight, int xSrc, int ySrc, int nSWidth, int nSHeight)
Definition: CDIB.cpp:325
void UseGamma(float fg, BOOL bUse=TRUE)
Definition: CDIB.cpp:659
HANDLE GetDIBits(int nStartX=-1, int nStartY=-1, int nCx=-1, int nCy=-1)
Definition: CDIB.cpp:580
GLuint GLuint GLsizei GLenum type
Definition: glext.h:2845
GLuint src
Definition: glext.h:5390
GLenum GLint x
Definition: glext.h:2849
int i
Definition: process.py:33
#define BOOL
Definition: mprintf.c:71
unsigned char * GetLinePtr(int line)
Definition: CDIB.cpp:540
int ClosestColor(RGBQUAD *pRgb)
Definition: CDIB.cpp:814
void SetPixel8(int x, int y, unsigned char color)
Definition: CDIB.cpp:201
void * m_pVoid
Definition: CDIB.h:106
BOOL Make8Bit(CDIB &dib)
Definition: CDIB.cpp:688
list l
Definition: prepare.py:17
unsigned char Gamma[256]
Definition: CDIB.h:116
GLsizei GLsizei GLcharARB * source
Definition: glext.h:3633
BOOL SwitchFromOne(CDIB &dib)
Definition: CDIB.cpp:736
GLuint dst
Definition: glext.h:5285
BOOL OpenDIB(CString &fileName)
Definition: CDIB.cpp:858
void ReplaceColor(unsigned char oldColor, unsigned char newColor)
Definition: CDIB.cpp:559
BOOL SwitchPalette(CDIB &dib)
Definition: CDIB.cpp:789
void Expand(int nXDest, int nYDest, int xRatio, int yRatio, CDIB &dibSrc, int xSrc, int ySrc, int nSWidth, int nSHeight)
Definition: CDIB.cpp:341
int m_nBits
Definition: CDIB.h:111
const GLubyte * c
Definition: glext.h:4677
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3454
BOOL SaveBMP(CString &csFileName)
Definition: CDIB.cpp:890
BitmapType
Definition: CDIB.h:37
void CopyLine(int source, int dest)
Definition: CDIB.cpp:279
unsigned char * m_pBits
Definition: CDIB.h:103
#define NULL
Definition: Lib.h:88
int GetPaletteSize()
Definition: CDIB.cpp:165
GLuint buffer
Definition: glext.h:3108
COLORREF PaletteColor(int index)
Definition: CDIB.cpp:985
int m_nFlags
Definition: CDIB.h:112
#define BIG_DISTANCE
Definition: CDIB.cpp:42
void BitBlt(HDC hDest, int nXDest, int nYDest, int nWidth, int nHeight, int xSrc, int ySrc)
Definition: CDIB.cpp:320
void SetPixel(int x, int y, COLORREF color)
Definition: CDIB.cpp:187
GLenum GLsizei width
Definition: glext.h:2846
typedef HDC(WINAPI *PFNWGLGETCURRENTREADDCARBPROC)(void)
int EnumColors(BYTE *colors)
Definition: CDIB.cpp:962
Definition: CDIB.h:38
GLenum GLsizei GLsizei height
Definition: glext.h:2856
int bytes
Definition: CDIB.h:109
void ExpandBlt(int nXDest, int nYDest, int xRatio, int yRatio, CDIB &dibSrc, int xSrc, int ySrc, int nSWidth, int nSHeight)
Definition: CDIB.cpp:331
void InitDIB(COLORREF color)
Definition: CDIB.cpp:290
CDIB & operator=(CDIB &dib)
Definition: CDIB.cpp:574
#define bits
Definition: Unzip.cpp:3797
BOOL SwitchFrom24(CDIB &dib)
Definition: CDIB.cpp:992
static WindowRef ValidModeCallbackProc inCallback OSStatus err
void CreateGammaCurve()
Definition: CDIB.cpp:668
int Width()
Definition: CDIB.h:80
GLsizeiptr size
Definition: glext.h:3112
int int int int int xSrc
Definition: wglext.h:335
BOOL Create(int width, int height, int bits=24)
Definition: CDIB.cpp:80
float m_fOldGamma
Definition: CDIB.h:115
Definition: CDIB.h:35
typedef LPVOID(WINAPI *PFNWGLCREATEIMAGEBUFFERI3DPROC)(HDC hDC
char CachePtr[256]
Definition: CDIB.h:118
#define FALSE
Definition: mprintf.c:70
BYTE ** m_pLinePtr
Definition: CDIB.h:107
DWORD GetDIBSize()
Definition: CDIB.cpp:596
#define TRUE
Definition: mprintf.c:69
GLint j
Definition: qgl.h:264
CBitmap * GetBitmap(CDC &dc)
Definition: CDIB.cpp:247
CBitmap * GetTempBitmap(CDC &dc)
Definition: CDIB.cpp:230
CDIB(HANDLE hDib=NULL, int nBits=8)
Definition: CDIB.cpp:54
BOOL CreateFromHandle(HANDLE hDib, int nBits)
Definition: CDIB.cpp:622
BOOL SaveDIB(CString &fileName, BitmapType type)
Definition: CDIB.cpp:872
BOOL m_bUseGamma
Definition: CDIB.h:113
int CountColors()
Definition: CDIB.cpp:939
RGBQUAD CacheQuad[256]
Definition: CDIB.h:117