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

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

Added new logging feature

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