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

Last change on this file since 3302 was 3302, checked in by sandervl, 25 years ago

dib sync bugfixes

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