256bmp.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include <windows.h>
  19. #include <windowsx.h>
  20. #include <alloc.h>
  21. DWORD GetDibInfoHeaderSize (BYTE huge *);
  22. WORD GetDibWidth (BYTE huge *);
  23. WORD GetDibHeight (BYTE huge *);
  24. BYTE huge * GetDibBitsAddr (BYTE huge *);
  25. BYTE huge * ReadDib(char *);
  26. //-------------------------------------------------------------//
  27. DWORD GetDibInfoHeaderSize (BYTE huge * lpDib)
  28. {
  29. return ((BITMAPINFOHEADER huge *) lpDib)->biSize ;
  30. }
  31. WORD GetDibWidth (BYTE huge * lpDib)
  32. {
  33. if (GetDibInfoHeaderSize (lpDib) == sizeof (BITMAPCOREHEADER))
  34. return (WORD) (((BITMAPCOREHEADER huge *) lpDib)->bcWidth) ;
  35. else
  36. return (WORD) (((BITMAPINFOHEADER huge *) lpDib)->biWidth) ;
  37. }
  38. WORD GetDibHeight (BYTE huge * lpDib)
  39. {
  40. if (GetDibInfoHeaderSize (lpDib) == sizeof (BITMAPCOREHEADER))
  41. return (WORD) (((BITMAPCOREHEADER huge *) lpDib)->bcHeight) ;
  42. else
  43. return (WORD) (((BITMAPINFOHEADER huge *) lpDib)->biHeight) ;
  44. }
  45. BYTE huge * GetDibBitsAddr (BYTE huge * lpDib)
  46. {
  47. DWORD dwNumColors, dwColorTableSize ;
  48. WORD wBitCount ;
  49. if (GetDibInfoHeaderSize (lpDib) == sizeof (BITMAPCOREHEADER))
  50. {
  51. wBitCount = ((BITMAPCOREHEADER huge *) lpDib)->bcBitCount ;
  52. if (wBitCount != 24)
  53. dwNumColors = 1L << wBitCount ;
  54. else
  55. dwNumColors = 0 ;
  56. dwColorTableSize = dwNumColors * sizeof (RGBTRIPLE) ;
  57. }
  58. else
  59. {
  60. wBitCount = ((BITMAPINFOHEADER huge *) lpDib)->biBitCount ;
  61. if (GetDibInfoHeaderSize (lpDib) >= 36)
  62. dwNumColors = ((BITMAPINFOHEADER huge *) lpDib)->biClrUsed ;
  63. else
  64. dwNumColors = 0 ;
  65. if (dwNumColors == 0)
  66. {
  67. if (wBitCount != 24)
  68. dwNumColors = 1L << wBitCount ;
  69. else
  70. dwNumColors = 0 ;
  71. }
  72. dwColorTableSize = dwNumColors * sizeof (RGBQUAD) ;
  73. }
  74. return lpDib + GetDibInfoHeaderSize (lpDib) + dwColorTableSize ;
  75. }
  76. // Read a DIB from a file into memory
  77. BYTE huge * ReadDib (char * szFileName)
  78. {
  79. BITMAPFILEHEADER bmfh ;
  80. BYTE huge * lpDib ;
  81. DWORD dwDibSize, dwOffset, dwHeaderSize ;
  82. int hFile ;
  83. WORD wDibRead ;
  84. if (-1 == (hFile = _lopen (szFileName, OF_READ | OF_SHARE_DENY_WRITE)))
  85. return NULL ;
  86. if (_lread (hFile, (LPSTR) &bmfh, sizeof (BITMAPFILEHEADER)) !=
  87. sizeof (BITMAPFILEHEADER))
  88. {
  89. _lclose (hFile) ;
  90. return NULL ;
  91. }
  92. if (bmfh.bfType != * (WORD *) "BM")
  93. {
  94. _lclose (hFile) ;
  95. return NULL ;
  96. }
  97. dwDibSize = bmfh.bfSize - sizeof (BITMAPFILEHEADER) ;
  98. lpDib = (BYTE huge * ) GlobalAllocPtr (GMEM_MOVEABLE, dwDibSize) ;
  99. if (lpDib == NULL)
  100. {
  101. _lclose (hFile) ;
  102. return NULL ;
  103. }
  104. dwOffset = 0 ;
  105. while (dwDibSize > 0)
  106. {
  107. wDibRead = (WORD) min (32768ul, dwDibSize) ;
  108. if (wDibRead != _lread (hFile, (LPSTR) (lpDib + dwOffset), wDibRead))
  109. {
  110. _lclose (hFile) ;
  111. return NULL ;
  112. }
  113. dwDibSize -= wDibRead ;
  114. dwOffset += wDibRead ;
  115. }
  116. _lclose (hFile) ;
  117. dwHeaderSize = GetDibInfoHeaderSize (lpDib) ;
  118. if (dwHeaderSize < 12 || (dwHeaderSize > 12 && dwHeaderSize < 16))
  119. return NULL ;
  120. return lpDib ;
  121. }
  122. long FAR PASCAL _export MainWndProc(HWND hWnd,UINT message,UINT wParam,LONG lParam)
  123. {
  124. PAINTSTRUCT ps;
  125. HDC hdc;
  126. RECT rect;
  127. unsigned char r,g,b,x;
  128. FILE *fi;
  129. int i;
  130. static BYTE huge *lpDib;
  131. static BYTE huge *lpDibBits;
  132. static int cxDib, cyDib;
  133. static LPLOGPALETTE LogPal;
  134. static HPALETTE hLogPal;
  135. switch(message)
  136. {
  137. case WM_CREATE:
  138. fi=fopen("somefile.bmp","r");
  139. if(fi==NULL)
  140. return 0;
  141. LogPal=(LPLOGPALETTE)farmalloc(sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*256);
  142. LogPal->palVersion=0x300;
  143. LogPal->palNumEntries=256;
  144. fseek(fi,54L,0);
  145. for(i=0;i<256;i++)
  146. {
  147. fscanf(fi,"%c%c%c%c",&b,&g,&r,&x);
  148. LogPal->palPalEntry[i].peRed=r;
  149. LogPal->palPalEntry[i].peGreen=g;
  150. LogPal->palPalEntry[i].peBlue=b;
  151. LogPal->palPalEntry[i].peFlags=x;
  152. }
  153. fclose(fi);
  154. hLogPal=CreatePalette(LogPal);
  155. return 0;
  156. case WM_PAINT:
  157. hdc=BeginPaint(hWnd,&ps);
  158. GetClientRect(hWnd,&rect);
  159. SelectPalette(hdc,hLogPal,0);
  160. RealizePalette(hdc);
  161. SetStretchBltMode(hdc,COLORONCOLOR);
  162. lpDib=ReadDib(bmp_fname);
  163. lpDibBits=GetDibBitsAddr(lpDib);
  164. cxDib=GetDibWidth(lpDib);
  165. cyDib=GetDibHeight(lpDib);
  166. StretchDIBits(hdc,0,0,rect.right,rect.bottom,0,0,cxDib,cyDib,(LPSTR)lpDibBits,
  167. (LPBITMAPINFO)lpDib,DIB_RGB_COLORS,SRCCOPY);
  168. EndPaint(hWnd,&ps);
  169. break;
  170. case WM_DESTROY:
  171. farfree(LogPal);
  172. DeleteObject(hLogPal);
  173. PostQuitMessage(0);
  174. break;
  175. default:
  176. return (DefWindowProc(hWnd,message,wParam,lParam));
  177. }
  178. return (DefWindowProc(hWnd,message,wParam,lParam));
  179. }