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

Last change on this file since 10486 was 10486, checked in by sandervl, 21 years ago

SetDIBitsToDevice & StretchDIBits fixes + cleanup

File size: 23.0 KB
Line 
1/* $Id: blit.cpp,v 1.47 2004-02-27 18:56:12 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 <winuser32.h>
18#include <dbglog.h>
19#include "oslibgpi.h"
20#include <dcdata.h>
21#include "dibsect.h"
22#include "rgbcvt.h"
23
24#define DBG_LOCALLOG DBG_blit
25#include "dbglocal.h"
26
27static ULONG QueryPaletteSize(BITMAPINFOHEADER *pBHdr);
28ULONG CalcBitmapSize(ULONG cBits, LONG cx, LONG cy);
29
30//******************************************************************************
31//******************************************************************************
32BOOL WIN32API StretchBlt(HDC hdcDest, int nXOriginDest, int nYOriginDest,
33 int nWidthDest, int nHeightDest,
34 HDC hdcSrc, int nXOriginSrc, int nYOriginSrc,
35 int nWidthSrc, int nHeightSrc, DWORD dwRop)
36{
37 BOOL rc;
38
39 dprintf(("GDI32: StretchBlt Dest: %x (%d, %d) size (%d, %d) ROP %x",
40 hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, dwRop));
41 dprintf(("GDI32: StretchBlt Src : %x (%d, %d) size (%d, %d)\n",
42 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc));
43
44 SetLastError(ERROR_SUCCESS);
45 if(DIBSection::getSection() != NULL)
46 {
47 DIBSection *dsect = DIBSection::findHDC(hdcSrc);
48 if(dsect)
49 {
50 rc = dsect->BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
51 nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, dwRop);
52 goto blitdone;
53 }
54 }
55 rc = O32_StretchBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, dwRop);
56
57blitdone:
58 DIBSECTION_MARK_INVALID(hdcDest);
59
60 if(rc == FALSE) {
61 dprintf(("!WARNING!: GDI32: StretchBlt returned FALSE; last error %x", rc, GetLastError()));
62 }
63 return rc;
64}
65//******************************************************************************
66//******************************************************************************
67BOOL WIN32API BitBlt(HDC hdcDest,
68 int nXDest,
69 int nYDest,
70 int nWidth,
71 int nHeight,
72 HDC hdcSrc,
73 int nXSrc,
74 int nYSrc,
75 DWORD dwRop)
76{
77 BOOL rc;
78
79#ifdef DEBUG
80 POINT point1, point2;
81 GetViewportOrgEx(hdcDest, &point1);
82 GetViewportOrgEx(hdcSrc, &point2);
83 dprintf(("BitBlt: Viewport origin dest (%d,%d) src (%d,%d)", point1.x, point1.y, point2.x, point2.y));
84#endif
85
86 SetLastError(ERROR_SUCCESS);
87 if(DIBSection::getSection() != NULL)
88 {
89 DIBSection *dsect = DIBSection::findHDC(hdcSrc);
90 if(dsect)
91 {
92 rc = dsect->BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, nXSrc, nYSrc, nWidth, nHeight, dwRop);
93 goto blitdone;
94 }
95 }
96 dprintf(("GDI32: BitBlt to hdc %X from hdc %x (%d,%d) to (%d,%d), (%d,%d) rop %X\n",
97 hdcDest, hdcSrc, nXSrc, nYSrc, nXDest, nYDest, nWidth, nHeight, dwRop));
98
99 rc = O32_BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop);
100
101blitdone:
102 DIBSECTION_MARK_INVALID(hdcDest);
103 return rc;
104}
105//******************************************************************************
106//******************************************************************************
107static INT SetDIBitsToDevice_(HDC hdc, INT xDest, INT yDest, DWORD cx,
108 DWORD cy, INT xSrc, INT ySrc,
109 UINT startscan, UINT lines, LPCVOID bits,
110 const BITMAPINFO *info, UINT coloruse)
111{
112 INT result, imgsize, palsize;
113 char *ptr;
114 ULONG compression = 0, bmpsize;
115 WORD *newbits = NULL;
116 DWORD bitfields[3];
117
118 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",
119 hdc, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, (LPVOID) bits, (PBITMAPINFO)info, coloruse));
120
121 //SvL: RP7's bitmap size is not correct; fix it here or else
122 // the blit is messed up in Open32
123 imgsize = CalcBitmapSize(info->bmiHeader.biBitCount,
124 info->bmiHeader.biWidth, info->bmiHeader.biHeight);
125 bmpsize = info->bmiHeader.biSizeImage;
126 if(info->bmiHeader.biCompression == 0 && info->bmiHeader.biSizeImage &&
127 info->bmiHeader.biSizeImage < imgsize)
128 {
129 ((BITMAPINFO *)info)->bmiHeader.biSizeImage = imgsize;
130 }
131
132 switch(info->bmiHeader.biBitCount) {
133 case 15:
134 case 16: //Default if BI_BITFIELDS not set is RGB 555
135 bitfields[0] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : DEFAULT_16BPP_RED_MASK;
136 bitfields[1] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : DEFAULT_16BPP_GREEN_MASK;
137 bitfields[2] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : DEFAULT_16BPP_BLUE_MASK;
138 break;
139
140 case 24:
141 case 32:
142 bitfields[0] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : DEFAULT_24BPP_RED_MASK;
143 bitfields[1] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : DEFAULT_24BPP_GREEN_MASK;
144 bitfields[2] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : DEFAULT_24BPP_BLUE_MASK;
145 break;
146 default:
147 bitfields[0] = 0;
148 bitfields[1] = 0;
149 bitfields[2] = 0;
150 break;
151 }
152
153 if(bitfields[1] == 0x3E0)
154 {//RGB 555?
155 dprintf(("RGB 555->565 conversion required %x %x %x", bitfields[0], bitfields[1], bitfields[2]));
156
157 newbits = (WORD *)malloc(imgsize);
158 pRGB555to565(newbits, (WORD *)bits, imgsize/sizeof(WORD));
159 bits = newbits;
160 }
161
162 //SvL: Ignore BI_BITFIELDS type (SetDIBitsToDevice fails otherwise)
163 if(info->bmiHeader.biCompression == BI_BITFIELDS) {
164 ((BITMAPINFO *)info)->bmiHeader.biCompression = 0;
165 compression = BI_BITFIELDS;
166 }
167 if(startscan != 0 || lines != info->bmiHeader.biHeight) {
168 dprintf(("WARNING: SetDIBitsToDevice startscan != 0 || lines != info->bmiHeader.biHeight"));
169 dprintf(("info bmp (%d,%d)", info->bmiHeader.biWidth, info->bmiHeader.biHeight));
170 }
171
172 result = O32_StretchDIBits(hdc, xDest, yDest, cx, cy, xSrc, ySrc,
173 cx, cy, (void *)bits,
174 (PBITMAPINFO)info, coloruse, SRCCOPY);
175
176 //Open32 always returns height of bitmap (regardless of how many scanlines were copied)
177 if(result != info->bmiHeader.biHeight) {
178 dprintf(("SetDIBitsToDevice failed with rc %x", result));
179 }
180 else
181 {
182 result = info->bmiHeader.biHeight;
183
184 DIBSECTION_MARK_INVALID(hdc);
185 }
186 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",
187 hdc, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, (LPVOID) bits, (PBITMAPINFO)info, coloruse, result));
188 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));
189
190 if(compression == BI_BITFIELDS) {
191 ((BITMAPINFO *)info)->bmiHeader.biCompression = BI_BITFIELDS;
192 }
193 if(newbits) free(newbits);
194
195 ((BITMAPINFO *)info)->bmiHeader.biSizeImage = bmpsize;
196 return result;
197}
198//******************************************************************************
199//******************************************************************************
200INT WIN32API SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
201 DWORD cy, INT xSrc, INT ySrc,
202 UINT startscan, UINT lines, LPCVOID bits,
203 const BITMAPINFO *info, UINT coloruse)
204{
205 static BOOL fMatrox32BppBug = FALSE;
206 INT height, width;
207 INT rc = 0;
208 char *newBits = NULL;
209
210 if(startscan != 0 || lines != abs(info->bmiHeader.biHeight)) {
211 dprintf(("WARNING: SetDIBitsToDevice: startscan != 0 || lines != abs(info->bmiHeader.biHeight"));
212 }
213
214 SetLastError(ERROR_SUCCESS);
215 if(info == NULL) {
216 goto invalid_parameter;
217 }
218 height = info->bmiHeader.biHeight;
219 width = info->bmiHeader.biWidth;
220
221 if (height < 0) height = -height;
222 if (!lines || (startscan >= height)) {
223 goto invalid_parameter;
224 }
225 if (startscan + lines > height) lines = height - startscan;
226
227 if (ySrc < startscan) ySrc = startscan;
228 else if (ySrc >= startscan + lines) goto invalid_parameter;
229
230 if (xSrc >= width) goto invalid_parameter;
231
232 if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
233
234 if (xSrc + cx >= width) cx = width - xSrc;
235
236 if (!cx || !cy) goto invalid_parameter;
237
238 //If upside down, reverse scanlines and call SetDIBitsToDevice again
239 if(info->bmiHeader.biHeight < 0 && (info->bmiHeader.biCompression == BI_RGB ||
240 info->bmiHeader.biCompression == BI_BITFIELDS))
241 {
242 // upside down
243 INT rc = -1;
244
245 UINT lLineByte = DIB_GetDIBWidthBytes(info->bmiHeader.biWidth, info->bmiHeader.biBitCount);
246 UINT lLineCopy, xOffset;
247 UINT lHeight = -info->bmiHeader.biHeight;
248
249 xOffset = (xSrc*info->bmiHeader.biBitCount)/8;
250 xSrc = (xSrc*info->bmiHeader.biBitCount)%8;
251 ySrc -= startscan;
252
253 // Calculate destination line width
254 lLineCopy = cx;
255 if(xSrc + cx > info->bmiHeader.biWidth)
256 lLineCopy = info->bmiHeader.biWidth - xSrc;
257
258 // Plus xSrc in case rounding makes us start at a smaller x coordinate
259 lLineCopy = DIB_GetDIBWidthBytes(lLineCopy+xSrc, info->bmiHeader.biBitCount);
260
261 //TODO: doesn't work if memory is readonly!!
262 ((BITMAPINFO *)info)->bmiHeader.biHeight = -info->bmiHeader.biHeight;
263
264 char *newBits = (char *)malloc( lLineByte * lHeight );
265 if(newBits) {
266 unsigned char *pbSrc = (unsigned char *)bits + xOffset + lLineByte * ySrc;
267 unsigned char *pbDst = (unsigned char *)newBits + lLineByte * (lHeight - 1);
268 for(int y = 0; y < min(cy, min(lHeight, lines)); y++) {
269 memcpy( pbDst, pbSrc, lLineCopy);
270 pbSrc += lLineByte;
271 pbDst -= lLineByte;
272 }
273 //We only convert the necessary data so xSrc & ySrc are now 0
274 //xSrc can be non-zero for < 8bpp bitmap where it starts at the wrong boundary
275 rc = SetDIBitsToDevice( hdc, xDest, yDest, cx, cy, xSrc, 0, startscan, lines, (void *)newBits, info, coloruse );
276 free( newBits );
277 }
278 else DebugInt3();
279
280 //TODO: doesn't work if memory is readonly!!
281 ((BITMAPINFO *)info)->bmiHeader.biHeight = -info->bmiHeader.biHeight;
282
283 return rc;
284 }
285 rc = SetDIBitsToDevice_( hdc, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, bits, info, coloruse );
286
287 return rc;
288
289invalid_parameter:
290 SetLastError(ERROR_INVALID_PARAMETER);
291 return 0;
292}
293//******************************************************************************
294//******************************************************************************
295BOOL WIN32API PatBlt(HDC hdc,int nXLeft,int nYLeft,int nWidth,int nHeight,DWORD dwRop)
296{
297 BOOL rc;
298
299 dprintf(("PatBlt %x (%d,%d)(%d,%d) %x", hdc, nXLeft,nYLeft,nWidth,nHeight, dwRop));
300 //CB: Open32 bug: negative width/height not supported!
301 if (nWidth < 0)
302 {
303 nXLeft += nWidth+1;
304 nWidth = -nWidth;
305 }
306 if (nHeight < 0)
307 {
308 nYLeft += nHeight+1;
309 nHeight = -nHeight;
310 }
311 rc = O32_PatBlt(hdc,nXLeft,nYLeft,nWidth,nHeight,dwRop);
312 if(rc) {
313 DIBSECTION_MARK_INVALID(hdc);
314 }
315 return(rc);
316}
317//******************************************************************************
318//******************************************************************************
319BOOL WIN32API MaskBlt( HDC hdcDest, int arg2, int arg3, int arg4, int arg5, HDC hdcSrc, int arg7, int arg8, HBITMAP arg9, int arg10, int arg11, DWORD arg12)
320{
321 BOOL ret;
322
323 DIBSECTION_CHECK_IF_DIRTY(hdcSrc);
324
325 ret = O32_MaskBlt(hdcDest, arg2, arg3, arg4, arg5, hdcSrc, arg7, arg8, arg9, arg10, arg11, arg12);
326 if(ret) {
327 DIBSECTION_MARK_INVALID(hdcDest);
328 }
329 return ret;
330}
331//******************************************************************************
332//******************************************************************************
333BOOL WIN32API PlgBlt(HDC hdcDest, CONST POINT *lpPoint, HDC hdcSrc, int nXSrc,
334 int nYSrc, int nWidth, int nHeight, HBITMAP hbmMask,
335 int xMast, int yMask)
336{
337 dprintf(("GDI32: PlgBlt, not implemented\n"));
338 return(FALSE);
339}
340//******************************************************************************
341//******************************************************************************
342static INT StretchDIBits_(HDC hdc, INT xDst, INT yDst, INT widthDst,
343 INT heightDst, INT xSrc, INT ySrc, INT widthSrc,
344 INT heightSrc, const void *bits,
345 const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
346{
347 INT rc;
348 DWORD bitfields[3], compression = 0;
349 WORD *newbits = NULL;
350
351 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));
352
353 if(info->bmiHeader.biBitCount == 1) {
354 dprintf(("WARNING: StretchDIBits does NOT work correctly for 1 bpp bitmaps!!"));
355 }
356#if 0
357 // SvL: I'm not sure what this was supposed to fix, but it breaks one
358 // application here
359 // SetDIBitsToDevice works with palette indexes, so this should not
360 // be necessary (anymore)
361 if(wUsage == DIB_PAL_COLORS && info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
362 {
363 // workaround for open32 bug.
364 // If syscolors > 256 and wUsage == DIB_PAL_COLORS.
365
366 int i;
367 UINT biClrUsed;
368 USHORT *pColorIndex = (USHORT *)info->bmiColors;
369 RGBQUAD *pColors;
370 BITMAPINFO *infoLoc;
371
372 biClrUsed = (info->bmiHeader.biClrUsed) ? info->bmiHeader.biClrUsed : (1<<info->bmiHeader.biBitCount);
373
374 pColors = (RGBQUAD *) alloca(biClrUsed * sizeof(RGBQUAD));
375 infoLoc = (BITMAPINFO *) alloca(sizeof(BITMAPINFO) + biClrUsed * sizeof(RGBQUAD));
376
377 memcpy(infoLoc, info, sizeof(BITMAPINFO));
378
379 if(GetDIBColorTable(hdc, 0, biClrUsed, pColors) == 0)
380 {
381 dprintf(("ERROR: StretchDIBits: GetDIBColorTable failed!!"));
382 return FALSE;
383 }
384 for(i=0;i<biClrUsed;i++, pColorIndex++)
385 {
386 infoLoc->bmiColors[i] = pColors[*pColorIndex];
387 }
388
389 rc = O32_StretchDIBits(hdc, xDst, yDst, widthDst, heightDst, xSrc, ySrc,
390 widthSrc, heightSrc, (void *)bits,
391 (PBITMAPINFO)infoLoc, DIB_RGB_COLORS, dwRop);
392
393 //Open32 always returns height of bitmap (regardless of how many scanlines were copied)
394 if(rc != heightSrc && rc != infoLoc->bmiHeader.biHeight) {
395 dprintf(("StretchDIBits failed with rc %x", rc));
396 }
397 else {
398 rc = heightSrc;
399
400 DIBSECTION_MARK_INVALID(hdc);
401 }
402
403 return rc;
404 }
405#endif
406 switch(info->bmiHeader.biBitCount) {
407 case 15:
408 case 16: //Default if BI_BITFIELDS not set is RGB 555
409 bitfields[0] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : DEFAULT_16BPP_RED_MASK;
410 bitfields[1] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : DEFAULT_16BPP_GREEN_MASK;
411 bitfields[2] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : DEFAULT_16BPP_BLUE_MASK;
412 break;
413 case 24:
414 case 32:
415 bitfields[0] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : DEFAULT_24BPP_RED_MASK;
416 bitfields[1] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : DEFAULT_24BPP_GREEN_MASK;
417 bitfields[2] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : DEFAULT_24BPP_BLUE_MASK;
418 break;
419 default:
420 bitfields[0] = 0;
421 bitfields[1] = 0;
422 bitfields[2] = 0;
423 break;
424 }
425
426 if(bitfields[1] == RGB555_GREEN_MASK)
427 {//RGB 555?
428 dprintf(("RGB 555->565 conversion required %x %x %x", bitfields[0], bitfields[1], bitfields[2]));
429
430 ULONG imgsize = CalcBitmapSize(info->bmiHeader.biBitCount,
431 abs(info->bmiHeader.biWidth), heightSrc);
432 ULONG offset = CalcBitmapSize(info->bmiHeader.biBitCount,
433 abs(info->bmiHeader.biWidth), ySrc)/sizeof(WORD);
434 newbits = (WORD *) HeapAlloc(GetProcessHeap(), 0, imgsize);
435
436 //we still convert too much
437 pRGB555to565(newbits, (WORD *)bits+offset, imgsize/sizeof(WORD));
438 bits = newbits;
439
440 ySrc = 0;
441 }
442 //SvL: Ignore BI_BITFIELDS type (StretchDIBits fails otherwise)
443 if(info->bmiHeader.biCompression == BI_BITFIELDS) {
444 ((BITMAPINFO *)info)->bmiHeader.biCompression = 0;
445 compression = BI_BITFIELDS;
446 }
447
448 rc = O32_StretchDIBits(hdc, xDst, yDst, widthDst, heightDst, xSrc, ySrc,
449 widthSrc, heightSrc, (void *)bits,
450 (PBITMAPINFO)info, wUsage, dwRop);
451
452 if(compression == BI_BITFIELDS) {
453 ((BITMAPINFO *)info)->bmiHeader.biCompression = BI_BITFIELDS;
454 }
455 if(newbits) HeapFree(GetProcessHeap(), 0, newbits);
456
457 //Open32 always returns height of bitmap (regardless of how many scanlines were copied)
458 if(rc != heightSrc && rc != info->bmiHeader.biHeight) {
459 dprintf(("StretchDIBits failed with rc %x", rc));
460 }
461 else
462 {
463 rc = heightSrc;
464
465 DIBSECTION_MARK_INVALID(hdc);
466 }
467
468 return rc;
469}
470//******************************************************************************
471//******************************************************************************
472INT WIN32API StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst,
473 INT heightDst, INT xSrc, INT ySrc, INT widthSrc,
474 INT heightSrc, const void *bits,
475 const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
476{
477 if(info->bmiHeader.biHeight < 0) {
478 // upside down
479 INT rc = 0;
480 BITMAPINFO newInfo;
481 newInfo.bmiHeader = info->bmiHeader;
482 long lLineByte = ((newInfo.bmiHeader.biWidth * (info->bmiHeader.biBitCount == 15 ? 16 : info->bmiHeader.biBitCount) + 31) / 32) * 4;
483 long lHeight = -newInfo.bmiHeader.biHeight;
484 newInfo.bmiHeader.biHeight = -newInfo.bmiHeader.biHeight;
485
486 //TODO: doesn't work if memory is readonly!!
487 ((BITMAPINFO *)info)->bmiHeader.biHeight = -info->bmiHeader.biHeight;
488
489 char *newBits = (char *)malloc( lLineByte * lHeight );
490 if(newBits) {
491 unsigned char *pbSrc = (unsigned char *)bits + lLineByte * (lHeight - 1);
492 unsigned char *pbDst = (unsigned char *)newBits;
493 for(int y = 0; y < lHeight; y++) {
494 memcpy( pbDst, pbSrc, lLineByte );
495 pbDst += lLineByte;
496 pbSrc -= lLineByte;
497 }
498 rc = StretchDIBits_(hdc, xDst, yDst, widthDst, heightDst, xSrc, ySrc, widthSrc, heightSrc, newBits, info, wUsage, dwRop);
499 free( newBits );
500 }
501
502 //TODO: doesn't work if memory is readonly!!
503 ((BITMAPINFO *)info)->bmiHeader.biHeight = -info->bmiHeader.biHeight;
504 return rc;
505 } else {
506 return StretchDIBits_(hdc, xDst, yDst, widthDst, heightDst, xSrc, ySrc, widthSrc, heightSrc, bits, info, wUsage, dwRop);
507 }
508}
509//******************************************************************************
510//******************************************************************************
511int WIN32API SetStretchBltMode( HDC arg1, int arg2)
512{
513#ifdef DEBUG
514 if(DIBSection::getSection() != NULL)
515 {
516 DIBSection *dsect = DIBSection::findHDC(arg1);
517 if(dsect)
518 {
519 dprintf((" - DC is DIBSection\n"));
520 }
521 }
522#endif
523 return O32_SetStretchBltMode(arg1, arg2);
524}
525//******************************************************************************
526//******************************************************************************
527int WIN32API GetStretchBltMode( HDC arg1)
528{
529 return O32_GetStretchBltMode(arg1);
530}
531//******************************************************************************
532//******************************************************************************
533static ULONG QueryPaletteSize(BITMAPINFOHEADER *pBHdr)
534{
535 ULONG cbPalette;
536
537 switch (pBHdr->biBitCount)
538 {
539 case 1:
540 case 4:
541 case 8:
542 cbPalette = (1 << pBHdr->biBitCount) * sizeof(RGBQUAD);
543 break;
544
545 case 16:
546 case 24:
547 case 32:
548 cbPalette = 0;
549 break;
550
551 default:
552 dprintf(("QueryPaletteSize: error pBHdr->biBitCount = %d", pBHdr->biBitCount));
553 cbPalette = -1;
554 }
555
556 return cbPalette;
557}
558//******************************************************************************
559//******************************************************************************
560ULONG CalcBitmapSize(ULONG cBits, LONG cx, LONG cy)
561{
562 ULONG alignment;
563 ULONG factor;
564 BOOL flag = TRUE; //true: '*' false: '/'
565
566 cy = cy < 0 ? -cy : cy;
567
568 switch(cBits)
569 {
570 case 1:
571 factor = 8;
572 flag = FALSE;
573 break;
574
575 case 4:
576 factor = 2;
577 flag = FALSE;
578 break;
579
580 case 8:
581 factor = 1;
582 break;
583
584 case 16:
585 factor = 2;
586 break;
587
588 case 24:
589 factor = 3;
590 break;
591
592 case 32:
593 return cx*cy*4;
594
595 default:
596 return 0;
597 }
598
599 if (flag)
600 alignment = (cx = (cx*factor)) % 4;
601 else
602 alignment = (cx = ((cx+factor-1)/factor)) % 4;
603
604 if (alignment != 0)
605 cx += 4 - alignment;
606
607 return cx*cy;
608}
609//******************************************************************************
610//******************************************************************************
Note: See TracBrowser for help on using the repository browser.