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

Last change on this file since 6823 was 6692, checked in by sandervl, 24 years ago

DPtoLP & StretchDIBits fixes

File size: 24.8 KB
Line 
1/* $Id: blit.cpp,v 1.34 2001-09-10 11:02:40 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);
25ULONG 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) ROP %x",
37 hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, dwRop));
38 dprintf(("GDI32: StretchBlt Src : %x (%d, %d) size (%d, %d)\n",
39 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc));
40 SetLastError(ERROR_SUCCESS);
41 if(DIBSection::getSection() != NULL)
42 {
43 DIBSection *dsect = DIBSection::findHDC(hdcSrc);
44 if(dsect)
45 {
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,
58 int nXDest,
59 int nYDest,
60 int nWidth,
61 int nHeight,
62 HDC hdcSrc,
63 int nXSrc,
64 int nYSrc,
65 DWORD dwRop)
66{
67 BOOL rc;
68
69 SetLastError(ERROR_SUCCESS);
70 if(DIBSection::getSection() != NULL)
71 {
72 DIBSection *dsect = DIBSection::findHDC(hdcSrc);
73 if(dsect)
74 {
75 return dsect->BitBlt(hdcDest,
76 nXDest,
77 nYDest,
78 nWidth,
79 nHeight,
80 nXSrc,
81 nYSrc,
82 nWidth,
83 nHeight,
84 dwRop);
85 }
86 }
87 dprintf(("GDI32: BitBlt to hdc %X from hdc %x (%d,%d) to (%d,%d), (%d,%d) rop %X\n",
88 hdcDest, hdcSrc, nXSrc, nYSrc, nXDest, nYDest, nWidth, nHeight, dwRop));
89 return O32_BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop);
90}
91//******************************************************************************
92//******************************************************************************
93static INT SetDIBitsToDevice_(HDC hdc, INT xDest, INT yDest, DWORD cx,
94 DWORD cy, INT xSrc, INT ySrc,
95 UINT startscan, UINT lines, LPCVOID bits,
96 const BITMAPINFO *info, UINT coloruse)
97{
98 INT result, imgsize, palsize, height, width;
99 char *ptr;
100 ULONG compression = 0, bmpsize;
101 WORD *newbits = NULL;
102 DWORD bitfields[3];
103
104 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",
105 hdc, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, (LPVOID) bits, (PBITMAPINFO)info, coloruse));
106
107 SetLastError(ERROR_SUCCESS);
108 if(info == NULL) {
109 goto invalid_parameter;
110 }
111 height = info->bmiHeader.biHeight;
112 width = info->bmiHeader.biWidth;
113
114 if (height < 0) height = -height;
115 if (!lines || (startscan >= height)) {
116 goto invalid_parameter;
117 }
118 if (startscan + lines > height) lines = height - startscan;
119
120 if (ySrc < startscan) ySrc = startscan;
121 else if (ySrc >= startscan + lines) goto invalid_parameter;
122
123 if (xSrc >= width) goto invalid_parameter;
124
125 if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
126
127 if (xSrc + cx >= width) cx = width - xSrc;
128
129 if (!cx || !cy) goto invalid_parameter;
130
131 //SvL: RP7's bitmap size is not correct; fix it here or else
132 // the blit is messed up in Open32
133 imgsize = CalcBitmapSize(info->bmiHeader.biBitCount,
134 info->bmiHeader.biWidth, info->bmiHeader.biHeight);
135 bmpsize = info->bmiHeader.biSizeImage;
136 if(info->bmiHeader.biCompression == 0 && info->bmiHeader.biSizeImage &&
137 info->bmiHeader.biSizeImage < imgsize)
138 {
139 ((BITMAPINFO *)info)->bmiHeader.biSizeImage = imgsize;
140 }
141
142 switch(info->bmiHeader.biBitCount) {
143 case 15:
144 case 16: //Default if BI_BITFIELDS not set is RGB 555
145 bitfields[0] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
146 bitfields[1] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
147 bitfields[2] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
148 break;
149 case 32:
150 bitfields[0] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
151 bitfields[1] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0xff00;
152 bitfields[2] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0xff;
153 break;
154 default:
155 bitfields[0] = 0;
156 bitfields[1] = 0;
157 bitfields[2] = 0;
158 break;
159 }
160
161 if(bitfields[1] == 0x3E0)
162 {//RGB 555?
163 dprintf(("RGB 555->565 conversion required %x %x %x", bitfields[0], bitfields[1], bitfields[2]));
164
165 newbits = (WORD *)malloc(imgsize);
166 if(CPUFeatures & CPUID_MMX) {
167 RGB555to565MMX(newbits, (WORD *)bits, imgsize/sizeof(WORD));
168 }
169 else RGB555to565(newbits, (WORD *)bits, imgsize/sizeof(WORD));
170 bits = newbits;
171 }
172
173 //SvL: Ignore BI_BITFIELDS type (SetDIBitsToDevice fails otherwise)
174 if(info->bmiHeader.biCompression == BI_BITFIELDS) {
175 ((BITMAPINFO *)info)->bmiHeader.biCompression = 0;
176 compression = BI_BITFIELDS;
177
178 }
179 if(startscan != 0 || lines != info->bmiHeader.biHeight) {
180 dprintf(("WARNING: SetDIBitsToDevice startscan != 0 || lines != info->bmiHeader.biHeight"));
181 }
182
183 result = O32_StretchDIBits(hdc, xDest, yDest, cx, cy, xSrc, ySrc,
184 cx, cy, (void *)bits,
185 (PBITMAPINFO)info, coloruse, SRCCOPY);
186
187 //Open32 always returns height of bitmap (regardless of how many scanlines were copied)
188 if(result != info->bmiHeader.biHeight) {
189 dprintf(("SetDIBitsToDevice failed with rc %x", result));
190 }
191 else
192 {
193 result = info->bmiHeader.biHeight;
194
195 DIBSection *destdib = DIBSection::findHDC(hdc);
196 if(destdib) {
197 if(cx == info->bmiHeader.biWidth && cy == info->bmiHeader.biHeight &&
198 destdib->GetBitCount() == info->bmiHeader.biBitCount &&
199 destdib->GetBitCount() == 8)
200 {
201 destdib->sync(xDest, yDest, cx, cy, (PVOID)bits);
202 }
203 else destdib->sync(hdc, yDest, cy);
204 }
205 }
206 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",
207 hdc, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, (LPVOID) bits, (PBITMAPINFO)info, coloruse, result));
208 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));
209
210 if(compression == BI_BITFIELDS) {
211 ((BITMAPINFO *)info)->bmiHeader.biCompression = BI_BITFIELDS;
212 }
213 if(newbits) free(newbits);
214 ((BITMAPINFO *)info)->bmiHeader.biSizeImage = bmpsize;
215 return result;
216
217invalid_parameter:
218 SetLastError(ERROR_INVALID_PARAMETER);
219 return 0;
220}
221//******************************************************************************
222//******************************************************************************
223INT WIN32API SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
224 DWORD cy, INT xSrc, INT ySrc,
225 UINT startscan, UINT lines, LPCVOID bits,
226 const BITMAPINFO *info, UINT coloruse)
227{
228 if(info->bmiHeader.biHeight < 0 && info->bmiHeader.biBitCount != 8 && info->bmiHeader.biCompression == 0) {
229 // upside down
230 INT rc = 0;
231 BITMAPINFO newInfo;
232 newInfo.bmiHeader = info->bmiHeader;
233 long lLineByte = ((newInfo.bmiHeader.biWidth * (info->bmiHeader.biBitCount == 15 ? 16 : info->bmiHeader.biBitCount) + 31) / 32) * 4;
234 long lHeight = -newInfo.bmiHeader.biHeight;
235 newInfo.bmiHeader.biHeight = -info->bmiHeader.biHeight;
236
237 char *newBits = (char *)malloc( lLineByte * lHeight );
238 if(newBits) {
239 unsigned char *pbSrc = (unsigned char *)bits + lLineByte * (lHeight - 1);
240 unsigned char *pbDst = (unsigned char *)newBits;
241 for(int y = 0; y < lHeight; y++) {
242 memcpy( pbDst, pbSrc, lLineByte );
243 pbDst += lLineByte;
244 pbSrc -= lLineByte;
245 }
246 rc = SetDIBitsToDevice_( hdc, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, (void *)newBits, &newInfo, DIB_RGB_COLORS );
247 free( newBits );
248 }
249 return rc;
250 }
251//SvL: Breaks startup bitmap of Acrobat Reader 4.05
252#if 0
253 else
254 if(info->bmiHeader.biBitCount == 8 && info->bmiHeader.biCompression == 0 && !(GetDeviceCaps( hdc, RASTERCAPS ) & RC_PALETTE)) {
255 INT rc = 0;
256 // convert 8bit to 24bit
257
258 BITMAPINFO newInfo;
259 newInfo.bmiHeader = info->bmiHeader;
260 newInfo.bmiHeader.biBitCount = 24;
261 long lLineByte24 = ((newInfo.bmiHeader.biWidth * 24 + 31) / 32) * 4;
262 long lLineByte8 = ((newInfo.bmiHeader.biWidth * 8 + 31) / 32) * 4;
263 long lHeight = newInfo.bmiHeader.biHeight;
264 if(lHeight < 0) lHeight = -lHeight;
265
266 char *newBits = (char *)malloc( lLineByte24 * lHeight );
267 if(newBits) {
268 //
269 // Get Palette Entries
270 //
271 PALETTEENTRY aEntries[256];
272 LOGPALETTE *pLog = (LOGPALETTE *)malloc( sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * 256 );
273 pLog->palVersion = 0x300;
274 pLog->palNumEntries = 256;
275
276 HPALETTE hPaletteDummy = CreatePalette( pLog );
277 free( pLog );
278 HPALETTE hPalette = SelectPalette( hdc, hPaletteDummy, FALSE );
279 GetPaletteEntries( hPalette, 0, 255, aEntries );
280 SelectPalette( hdc, hPalette, FALSE );
281 DeleteObject( hPaletteDummy );
282
283 //
284 // convert 8bit to 24bit
285 //
286 if(newInfo.bmiHeader.biHeight > 0) {
287 unsigned char *pbSrc = (unsigned char *)bits;
288 unsigned char *pbDst = (unsigned char *)newBits;
289 for(int y = 0; y < lHeight; y++) {
290 for(int x = 0; x < newInfo.bmiHeader.biWidth; x++) {
291 PALETTEENTRY src = aEntries[pbSrc[x]];
292 pbDst[x * 3 + 0] = src.peBlue;
293 pbDst[x * 3 + 1] = src.peGreen;
294 pbDst[x * 3 + 2] = src.peRed;
295 }
296 pbDst += lLineByte24;
297 pbSrc += lLineByte8;
298 }
299 } else {
300 // upside down
301 newInfo.bmiHeader.biHeight = -info->bmiHeader.biHeight;
302 unsigned char *pbSrc = (unsigned char *)bits + lLineByte8 * (lHeight - 1);
303 unsigned char *pbDst = (unsigned char *)newBits;
304 for(int y = 0; y < lHeight; y++) {
305 for(int x = 0; x < newInfo.bmiHeader.biWidth; x++) {
306 PALETTEENTRY src = aEntries[pbSrc[x]];
307 pbDst[x * 3 + 0] = src.peBlue;
308 pbDst[x * 3 + 1] = src.peGreen;
309 pbDst[x * 3 + 2] = src.peRed;
310 }
311 pbDst += lLineByte24;
312 pbSrc -= lLineByte8;
313 }
314 }
315 rc = SetDIBitsToDevice_( hdc, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, (void *)newBits, &newInfo, DIB_RGB_COLORS );
316 free( newBits );
317 }
318 return rc;
319 }
320#endif
321 else {
322 return SetDIBitsToDevice_( hdc, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, bits, info, coloruse );
323 }
324}
325//******************************************************************************
326//******************************************************************************
327BOOL WIN32API PatBlt(HDC hdc,int nXLeft,int nYLeft,int nWidth,int nHeight,DWORD dwRop)
328{
329 BOOL rc;
330
331 dprintf(("PatBlt %x (%d,%d)(%d,%d) %x", hdc, nXLeft,nYLeft,nWidth,nHeight, dwRop));
332 //CB: Open32 bug: negative width/height not supported!
333 if (nWidth < 0)
334 {
335 nXLeft += nWidth+1;
336 nWidth = -nWidth;
337 }
338 if (nHeight < 0)
339 {
340 nYLeft += nHeight+1;
341 nHeight = -nHeight;
342 }
343 rc = O32_PatBlt(hdc,nXLeft,nYLeft,nWidth,nHeight,dwRop);
344 if(rc) {
345 DIBSection *destdib = DIBSection::findHDC(hdc);
346 if(destdib) {
347 destdib->sync(hdc, nYLeft, nHeight);
348 }
349 }
350
351 dprintf(("GDI32: PatBlt hdc %x (%d,%d) (%d,%d) returned %d\n",hdc, nXLeft,nYLeft,nWidth,nHeight,rc));
352 return(rc);
353}
354//******************************************************************************
355//******************************************************************************
356BOOL 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)
357{
358 dprintf(("GDI32: MaskBlt"));
359 return O32_MaskBlt(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
360}
361//******************************************************************************
362//******************************************************************************
363BOOL WIN32API PlgBlt(HDC hdcDest, CONST POINT *lpPoint, HDC hdcSrc, int nXSrc,
364 int nYSrc, int nWidth, int nHeight, HBITMAP hbmMask,
365 int xMast, int yMask)
366{
367 dprintf(("GDI32: PlgBlt, not implemented\n"));
368 return(FALSE);
369}
370//******************************************************************************
371//******************************************************************************
372static INT StretchDIBits_(HDC hdc, INT xDst, INT yDst, INT widthDst,
373 INT heightDst, INT xSrc, INT ySrc, INT widthSrc,
374 INT heightSrc, const void *bits,
375 const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
376{
377 INT rc;
378 DWORD bitfields[3], compression = 0;
379 WORD *newbits = NULL;
380
381 dprintf(("GDI32: StretchDIBits %x to (%d,%d) (%d,%d) from (%d,%d) (%d,%d), %x %x %x %x", hdc, xDst, yDst, widthDst, heightDst, xSrc, ySrc, widthSrc, heightSrc, bits, info, wUsage, dwRop));
382
383 if(info->bmiHeader.biBitCount == 1) {
384 dprintf(("WARNING: StretchDIBits does NOT work correctly for 1 bpp bitmaps!!"));
385 }
386
387 if(wUsage == DIB_PAL_COLORS && info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
388 {
389 // workaround for open32 bug.
390 // If syscolors > 256 and wUsage == DIB_PAL_COLORS.
391
392 int i;
393 USHORT *pColorIndex = (USHORT *)info->bmiColors;
394 RGBQUAD *pColors = (RGBQUAD *) alloca(info->bmiHeader.biClrUsed *
395 sizeof(RGBQUAD));
396 BITMAPINFO *infoLoc = (BITMAPINFO *) alloca(sizeof(BITMAPINFO) +
397 info->bmiHeader.biClrUsed * sizeof(RGBQUAD));
398
399 memcpy(infoLoc, info, sizeof(BITMAPINFO));
400
401 if(GetDIBColorTable(hdc, 0, info->bmiHeader.biClrUsed, pColors) == 0) {
402 dprintf(("ERROR: StretchDIBits: GetDIBColorTable failed!!"));
403 return FALSE;
404 }
405 for(i=0;i<info->bmiHeader.biClrUsed;i++, pColorIndex++)
406 {
407 infoLoc->bmiColors[i] = pColors[*pColorIndex];
408 }
409
410 rc = O32_StretchDIBits(hdc, xDst, yDst, widthDst, heightDst, xSrc, ySrc,
411 widthSrc, heightSrc, (void *)bits,
412 (PBITMAPINFO)infoLoc, DIB_RGB_COLORS, dwRop);
413
414 //Open32 always returns height of bitmap (regardless of how many scanlines were copied)
415 if(rc != heightSrc && rc != infoLoc->bmiHeader.biHeight) {
416 dprintf(("StretchDIBits failed with rc %x", rc));
417 }
418 else {
419 rc = heightSrc;
420
421 DIBSection *destdib = DIBSection::findHDC(hdc);
422 if(destdib) {
423 if(widthDst == widthSrc && heightDst == heightSrc &&
424 destdib->GetBitCount() == infoLoc->bmiHeader.biBitCount &&
425 destdib->GetBitCount() == 8)
426 {
427 destdib->sync(xDst, yDst, widthDst, heightDst, (PVOID)bits);
428 }
429 else destdib->sync(hdc, yDst, heightDst);
430 }
431 }
432
433 return rc;
434 }
435
436 switch(info->bmiHeader.biBitCount) {
437 case 15:
438 case 16: //Default if BI_BITFIELDS not set is RGB 555
439 bitfields[0] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
440 bitfields[1] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
441 bitfields[2] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
442 break;
443 case 32:
444 bitfields[0] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
445 bitfields[1] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0xff00;
446 bitfields[2] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0xff;
447 break;
448 default:
449 bitfields[0] = 0;
450 bitfields[1] = 0;
451 bitfields[2] = 0;
452 break;
453 }
454 if(bitfields[1] == 0x3E0)
455 {//RGB 555?
456 dprintf(("RGB 555->565 conversion required %x %x %x", bitfields[0], bitfields[1], bitfields[2]));
457
458 int imgsize = CalcBitmapSize(info->bmiHeader.biBitCount,
459 info->bmiHeader.biWidth, info->bmiHeader.biHeight);
460
461 newbits = (WORD *)malloc(imgsize);
462 if(CPUFeatures & CPUID_MMX) {
463 RGB555to565MMX(newbits, (WORD *)bits, imgsize/sizeof(WORD));
464 }
465 else RGB555to565(newbits, (WORD *)bits, imgsize/sizeof(WORD));
466 bits = newbits;
467 }
468 //SvL: Ignore BI_BITFIELDS type (SetDIBitsToDevice fails otherwise)
469 if(info->bmiHeader.biCompression == BI_BITFIELDS) {
470 ((BITMAPINFO *)info)->bmiHeader.biCompression = 0;
471 compression = BI_BITFIELDS;
472
473 }
474
475 rc = O32_StretchDIBits(hdc, xDst, yDst, widthDst, heightDst, xSrc, ySrc,
476 widthSrc, heightSrc, (void *)bits,
477 (PBITMAPINFO)info, wUsage, dwRop);
478
479 if(compression == BI_BITFIELDS) {
480 ((BITMAPINFO *)info)->bmiHeader.biCompression = BI_BITFIELDS;
481 }
482 if(newbits) free(newbits);
483
484 //Open32 always returns height of bitmap (regardless of how many scanlines were copied)
485 if(rc != heightSrc && rc != info->bmiHeader.biHeight) {
486 dprintf(("StretchDIBits failed with rc %x", rc));
487 }
488 else
489 {
490 rc = heightSrc;
491
492 DIBSection *destdib = DIBSection::findHDC(hdc);
493 if(destdib) {
494 if(widthDst == widthSrc && heightDst == heightSrc &&
495 destdib->GetBitCount() == info->bmiHeader.biBitCount &&
496 destdib->GetBitCount() == 8)
497 {
498 destdib->sync(xDst, yDst, widthDst, heightDst, (PVOID)bits);
499 }
500 else destdib->sync(hdc, yDst, heightDst);
501 }
502 }
503
504 return rc;
505}
506//******************************************************************************
507//******************************************************************************
508INT WIN32API StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst,
509 INT heightDst, INT xSrc, INT ySrc, INT widthSrc,
510 INT heightSrc, const void *bits,
511 const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
512{
513
514 if(info->bmiHeader.biHeight < 0) {
515 // upside down
516 INT rc = 0;
517 BITMAPINFO newInfo;
518 newInfo.bmiHeader = info->bmiHeader;
519 long lLineByte = ((newInfo.bmiHeader.biWidth * (info->bmiHeader.biBitCount == 15 ? 16 : info->bmiHeader.biBitCount) + 31) / 32) * 4;
520 long lHeight = -newInfo.bmiHeader.biHeight;
521 newInfo.bmiHeader.biHeight = -newInfo.bmiHeader.biHeight;
522
523 //TODO: doesn't work if memory is readonly!!
524 ((BITMAPINFO *)info)->bmiHeader.biHeight = -info->bmiHeader.biHeight;
525
526 char *newBits = (char *)malloc( lLineByte * lHeight );
527 if(newBits) {
528 unsigned char *pbSrc = (unsigned char *)bits + lLineByte * (lHeight - 1);
529 unsigned char *pbDst = (unsigned char *)newBits;
530 for(int y = 0; y < lHeight; y++) {
531 memcpy( pbDst, pbSrc, lLineByte );
532 pbDst += lLineByte;
533 pbSrc -= lLineByte;
534 }
535 rc = StretchDIBits_(hdc, xDst, yDst, widthDst, heightDst, xSrc, ySrc, widthSrc, heightSrc, newBits, info, wUsage, dwRop);
536 free( newBits );
537 }
538
539 //TODO: doesn't work if memory is readonly!!
540 ((BITMAPINFO *)info)->bmiHeader.biHeight = -info->bmiHeader.biHeight;
541 return rc;
542 } else {
543 return StretchDIBits_(hdc, xDst, yDst, widthDst, heightDst, xSrc, ySrc, widthSrc, heightSrc, bits, info, wUsage, dwRop);
544 }
545}
546//******************************************************************************
547//******************************************************************************
548int WIN32API SetStretchBltMode( HDC arg1, int arg2)
549{
550 dprintf(("GDI32: SetStretchBltMode 0x%08X, 0x%08X\n",arg1, arg2));
551
552 if(DIBSection::getSection() != NULL)
553 {
554 DIBSection *dsect = DIBSection::findHDC(arg1);
555 if(dsect)
556 {
557 dprintf((" - DC is DIBSection\n"));
558 }
559 }
560 return O32_SetStretchBltMode(arg1, arg2);
561}
562//******************************************************************************
563//******************************************************************************
564int WIN32API GetStretchBltMode( HDC arg1)
565{
566 dprintf(("GDI32: GetStretchBltMode"));
567 return O32_GetStretchBltMode(arg1);
568}
569//******************************************************************************
570//******************************************************************************
571static ULONG QueryPaletteSize(BITMAPINFOHEADER *pBHdr)
572{
573 ULONG cbPalette;
574
575 switch (pBHdr->biBitCount)
576 {
577 case 1:
578 case 4:
579 case 8:
580 cbPalette = (1 << pBHdr->biBitCount) * sizeof(RGBQUAD);
581 break;
582
583 case 16:
584 case 24:
585 case 32:
586 cbPalette = 0;
587 break;
588
589 default:
590 dprintf(("QueryPaletteSize: error pBHdr->biBitCount = %d", pBHdr->biBitCount));
591 cbPalette = -1;
592 }
593
594 return cbPalette;
595}
596//******************************************************************************
597//******************************************************************************
598ULONG CalcBitmapSize(ULONG cBits, LONG cx, LONG cy)
599{
600 ULONG alignment;
601 ULONG factor;
602 BOOL flag = TRUE; //true: '*' false: '/'
603
604 cy = cy < 0 ? -cy : cy;
605
606 switch(cBits)
607 {
608 case 1:
609 factor = 8;
610 flag = FALSE;
611 break;
612
613 case 4:
614 factor = 2;
615 flag = FALSE;
616 break;
617
618 case 8:
619 factor = 1;
620 break;
621
622 case 16:
623 factor = 2;
624 break;
625
626 case 24:
627 factor = 3;
628 break;
629
630 case 32:
631 return cx*cy;
632
633 default:
634 return 0;
635 }
636
637 if (flag)
638 alignment = (cx = (cx*factor)) % 4;
639 else
640 alignment = (cx = ((cx+factor-1)/factor)) % 4;
641
642 if (alignment != 0)
643 cx += 4 - alignment;
644
645 return cx*cy;
646}
647//******************************************************************************
648//******************************************************************************
Note: See TracBrowser for help on using the repository browser.