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

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

Added MMX rgb conversion function

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