source: trunk/src/gdi32/blit.cpp@ 2600

Last change on this file since 2600 was 2600, checked in by sandervl, 26 years ago

RGB 555 conversion in SetDIBitsToDevice + quake 2 BitBlt fix

File size: 11.2 KB
Line 
1/* $Id: blit.cpp,v 1.2 2000-02-02 23:45:06 sandervl Exp $ */
2
3/*
4 * GDI32 blit code
5 *
6 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
7 * Copyright 1998 Patrick Haller
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#include <os2win.h>
13#include <stdlib.h>
14#include <stdarg.h>
15#include <string.h>
16#include "misc.h"
17#include "dibsect.h"
18
19static ULONG QueryPaletteSize(BITMAPINFOHEADER *pBHdr);
20static ULONG CalcBitmapSize(ULONG cBits, LONG cx, LONG cy);
21
22//******************************************************************************
23//******************************************************************************
24BOOL WIN32API StretchBlt(HDC hdcDest, int nXOriginDest, int nYOriginDest,
25 int nWidthDest, int nHeightDest,
26 HDC hdcSrc, int nXOriginSrc, int nYOriginSrc,
27 int nWidthSrc, int nHeightSrc, DWORD dwRop)
28{
29 BOOL rc;
30
31 dprintf(("GDI32: StretchBlt Dest: %x (%d, %d) size (%d, %d)\n",
32 hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest));
33 dprintf(("GDI32: StretchBlt Src : %x (%d, %d) size (%d, %d)\n",
34 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc));
35 if(DIBSection::getSection() != NULL)
36 {
37 DIBSection *dsect = DIBSection::findHDC(hdcSrc);
38 if(dsect)
39 {
40 dprintf((" Do stretched DIB Blt\n"));
41 rc = dsect->BitBlt( hdcDest,
42 nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
43 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
44 dwRop);
45 return rc;
46 }
47 }
48 return O32_StretchBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, dwRop);
49}
50//******************************************************************************
51//******************************************************************************
52BOOL WIN32API BitBlt(HDC hdcDest, int arg2, int arg3, int arg4, int arg5, HDC hdcSrc, int arg7, int arg8, DWORD arg9)
53{
54 BOOL rc;
55
56 if(DIBSection::getSection() != NULL) {
57 DIBSection *dsect = DIBSection::findHDC(hdcSrc);
58 if(dsect) {
59 rc = dsect->BitBlt(hdcDest, arg2, arg3, arg4, arg5, arg7, arg8, arg4, arg5, arg9);
60 if(rc) {
61 BITMAPINFO bmpinfo = {0};
62 DIBSection *dest = DIBSection::findHDC(hdcDest);
63 if(dest) {
64 dprintf(("Sync dest DIB section"));
65 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
66 GetDIBits(hdcDest, dest->GetBitmapHandle(), 0, 300, 0, &bmpinfo, dest->GetRGBUsage());
67 dprintf(("height %d", bmpinfo.bmiHeader.biHeight));
68 dprintf(("width %d", bmpinfo.bmiHeader.biWidth));
69 dprintf(("biBitCount %d", bmpinfo.bmiHeader.biBitCount));
70 GetDIBits(hdcDest, dest->GetBitmapHandle(), 0, 300, dest->GetDIBObject(), &bmpinfo, dest->GetRGBUsage());
71 }
72 }
73 return rc;
74 }
75 }
76 dprintf(("GDI32: BitBlt to hdc %X from (%d,%d) to (%d,%d), (%d,%d) rop %X\n", hdcDest, arg7, arg8, arg2, arg3, arg4, arg5, arg9));
77 return O32_BitBlt(hdcDest, arg2, arg3, arg4, arg5, hdcSrc, arg7, arg8, arg9);
78}
79//******************************************************************************
80//******************************************************************************
81INT WIN32API SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
82 DWORD cy, INT xSrc, INT ySrc,
83 UINT startscan, UINT lines, LPCVOID bits,
84 const BITMAPINFO *info, UINT coloruse)
85{
86 INT result, imgsize, palsize, height, width;
87 char *ptr;
88 ULONG compression = 0;
89 WORD *newbits = 0;
90
91 SetLastError(0);
92 if(info == NULL) {
93 goto invalid_parameter;
94 }
95 height = info->bmiHeader.biHeight;
96 width = info->bmiHeader.biWidth;
97
98 if (height < 0) height = -height;
99 if (!lines || (startscan >= height)) {
100 goto invalid_parameter;
101 }
102 if (startscan + lines > height) lines = height - startscan;
103
104 if (ySrc < startscan) ySrc = startscan;
105 else if (ySrc >= startscan + lines) goto invalid_parameter;
106
107 if (xSrc >= width) goto invalid_parameter;
108
109 if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
110
111 if (xSrc + cx >= width) cx = width - xSrc;
112
113 if (!cx || !cy) goto invalid_parameter;
114
115 // EB: ->>> Crazy. Nobody seen this Open32 bug ?
116 // Dont't like dirty pointers, but Open32 needs a bit help.
117 // Only tested with winmine.
118 palsize = QueryPaletteSize((BITMAPINFOHEADER*)&info->bmiHeader);
119 imgsize = CalcBitmapSize(info->bmiHeader.biBitCount,
120 info->bmiHeader.biWidth, info->bmiHeader.biHeight);
121 ptr = ((char *)info) + palsize + sizeof(BITMAPINFOHEADER);
122 if(bits >= ptr && bits < ptr + imgsize)
123 {
124 bits = (char *)bits - imgsize +
125 CalcBitmapSize(info->bmiHeader.biBitCount,
126 info->bmiHeader.biWidth, lines);
127 }
128 // EB: <<<-
129
130 //SvL: Ignore BI_BITFIELDS type (SetDIBitsToDevice fails otherwise)
131 if(info->bmiHeader.biCompression == BI_BITFIELDS) {
132 DWORD *bitfields = (DWORD *)info->bmiColors;
133
134 dprintf(("BI_BITFIELDS compression %x %x %x", *bitfields, *(bitfields+1), *(bitfields+2)));
135 ((BITMAPINFO *)info)->bmiHeader.biCompression = 0;
136 compression = BI_BITFIELDS;
137 if(*(bitfields+1) == 0x3E0) {//RGB 555?
138 WORD *dstbits, *srcbits;
139 WORD pixel;
140
141 newbits = dstbits = (WORD *)malloc(imgsize);
142 srcbits = (WORD *)bits;
143 for(int i=0;i<imgsize/sizeof(WORD);i++) {
144 pixel = *dstbits = *srcbits++;
145 *dstbits &= 0x1F;
146 pixel &= 0x7FE0;
147 pixel <<= 1;
148 *dstbits = *dstbits | pixel;
149 dstbits++;
150 }
151 bits = newbits;
152 }
153 }
154
155 if(info->bmiHeader.biHeight < 0)
156 ((BITMAPINFO *)info)->bmiHeader.biHeight = -info->bmiHeader.biHeight;
157
158 result = O32_SetDIBitsToDevice(hdc, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, (PVOID) bits, (PBITMAPINFO)info, coloruse);
159 //SvL: Wrong Open32 return value
160 result = (result == TRUE) ? lines : 0;
161
162 dprintf(("GDI32: SetDIBitsToDevice hdc:%X xDest:%d yDest:%d, cx:%d, cy:%d, xSrc:%d, ySrc:%d, startscan:%d, lines:%d \nGDI32: bits:%X, info%X, coloruse:%d returned %d",
163 hdc, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, (LPVOID) bits, (PBITMAPINFO)info, coloruse, result));
164 dprintf(("GDI32: SetDIBitsToDevice %d %d %d %d %x %d", info->bmiHeader.biWidth, info->bmiHeader.biHeight, info->bmiHeader.biPlanes, info->bmiHeader.biBitCount, info->bmiHeader.biCompression, info->bmiHeader.biSizeImage));
165
166 if(compression == BI_BITFIELDS) {
167 ((BITMAPINFO *)info)->bmiHeader.biCompression = BI_BITFIELDS;
168 if(newbits) free(newbits);
169 }
170 return result;
171
172invalid_parameter:
173 SetLastError(ERROR_INVALID_PARAMETER);
174 return 0;
175}
176//******************************************************************************
177//******************************************************************************
178BOOL WIN32API PatBlt(HDC hdc,int nXLeft,int nYLeft,int nWidth,int nHeight,DWORD dwRop)
179{
180 BOOL rc;
181
182 //CB: Open32 bug: negative width/height not supported!
183 if (nWidth < 0)
184 {
185 nXLeft += nWidth+1;
186 nWidth = -nWidth;
187 }
188 if (nHeight < 0)
189 {
190 nYLeft += nHeight+1;
191 nHeight = -nHeight;
192 }
193 rc = O32_PatBlt(hdc,nXLeft,nYLeft,nWidth,nHeight,dwRop);
194 dprintf(("GDI32: PatBlt (%d,%d) (%d,%d) returned %d\n",nXLeft,nYLeft,nWidth,nHeight,rc));
195 return(rc);
196}
197//******************************************************************************
198//******************************************************************************
199BOOL WIN32API MaskBlt( HDC arg1, int arg2, int arg3, int arg4, int arg5, HDC arg6, int arg7, int arg8, HBITMAP arg9, int arg10, int arg11, DWORD arg12)
200{
201 dprintf(("GDI32: MaskBlt"));
202 return O32_MaskBlt(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
203}
204//******************************************************************************
205//******************************************************************************
206BOOL WIN32API PlgBlt(HDC hdcDest, CONST POINT *lpPoint, HDC hdcSrc, int nXSrc,
207 int nYSrc, int nWidth, int nHeight, HBITMAP hbmMask,
208 int xMast, int yMask)
209{
210 dprintf(("GDI32: PlgBlt, not implemented\n"));
211 return(FALSE);
212}
213//******************************************************************************
214//******************************************************************************
215int WIN32API SetStretchBltMode( HDC arg1, int arg2)
216{
217 dprintf(("GDI32: SetStretchBltMode 0x%08X, 0x%08X\n",arg1, arg2));
218
219 if(DIBSection::getSection() != NULL)
220 {
221 DIBSection *dsect = DIBSection::findHDC(arg1);
222 if(dsect)
223 {
224 dprintf((" - DC is DIBSection\n"));
225 }
226 }
227 return O32_SetStretchBltMode(arg1, arg2);
228}
229//******************************************************************************
230//******************************************************************************
231int WIN32API GetStretchBltMode( HDC arg1)
232{
233 dprintf(("GDI32: GetStretchBltMode"));
234 return O32_GetStretchBltMode(arg1);
235}
236//******************************************************************************
237//******************************************************************************
238static ULONG QueryPaletteSize(BITMAPINFOHEADER *pBHdr)
239{
240 ULONG cbPalette;
241
242 switch (pBHdr->biBitCount)
243 {
244 case 1:
245 case 4:
246 case 8:
247 cbPalette = (1 << pBHdr->biBitCount) * sizeof(RGBQUAD);
248 break;
249
250 case 16:
251 case 24:
252 case 32:
253 cbPalette = 0;
254 break;
255
256 default:
257 dprintf(("QueryPaletteSize: error pBHdr->biBitCount = %d", pBHdr->biBitCount));
258 cbPalette = -1;
259 }
260
261 return cbPalette;
262}
263//******************************************************************************
264//******************************************************************************
265static ULONG CalcBitmapSize(ULONG cBits, LONG cx, LONG cy)
266{
267 ULONG alignment;
268 ULONG factor;
269 BOOL flag = TRUE; //true: '*' false: '/'
270
271 cy = cy < 0 ? -cy : cy;
272
273 switch(cBits)
274 {
275 case 1:
276 factor = 8;
277 flag = FALSE;
278 break;
279
280 case 4:
281 factor = 2;
282 flag = FALSE;
283 break;
284
285 case 8:
286 factor = 1;
287 break;
288
289 case 16:
290 factor = 2;
291 break;
292
293 case 24:
294 factor = 3;
295 break;
296
297 case 32:
298 return cx*cy;
299
300 default:
301 return 0;
302 }
303
304 if (flag)
305 alignment = (cx = (cx*factor)) % 4;
306 else
307 alignment = (cx = ((cx+factor-1)/factor)) % 4;
308
309 if (alignment != 0)
310 cx += 4 - alignment;
311
312 return cx*cy;
313}
314//******************************************************************************
315//******************************************************************************
Note: See TracBrowser for help on using the repository browser.