Changeset 10486 for trunk/src/gdi32/blit.cpp
- Timestamp:
- Feb 27, 2004, 7:56:12 PM (21 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gdi32/blit.cpp
r10373 r10486 1 /* $Id: blit.cpp,v 1.4 6 2004-01-11 11:42:08sandervl Exp $ */1 /* $Id: blit.cpp,v 1.47 2004-02-27 18:56:12 sandervl Exp $ */ 2 2 3 3 /* … … 110 110 const BITMAPINFO *info, UINT coloruse) 111 111 { 112 INT result, imgsize, palsize , height, width;112 INT result, imgsize, palsize; 113 113 char *ptr; 114 114 ULONG compression = 0, bmpsize; … … 118 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 119 hdc, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, (LPVOID) bits, (PBITMAPINFO)info, coloruse)); 120 121 SetLastError(ERROR_SUCCESS);122 if(info == NULL) {123 goto invalid_parameter;124 }125 height = info->bmiHeader.biHeight;126 width = info->bmiHeader.biWidth;127 128 if (height < 0) height = -height;129 if (!lines || (startscan >= height)) {130 goto invalid_parameter;131 }132 if (startscan + lines > height) lines = height - startscan;133 134 if (ySrc < startscan) ySrc = startscan;135 else if (ySrc >= startscan + lines) goto invalid_parameter;136 137 if (xSrc >= width) goto invalid_parameter;138 139 if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;140 141 if (xSrc + cx >= width) cx = width - xSrc;142 143 if (!cx || !cy) goto invalid_parameter;144 120 145 121 //SvL: RP7's bitmap size is not correct; fix it here or else … … 219 195 ((BITMAPINFO *)info)->bmiHeader.biSizeImage = bmpsize; 220 196 return result; 221 222 invalid_parameter:223 SetLastError(ERROR_INVALID_PARAMETER);224 return 0;225 197 } 226 198 //****************************************************************************** … … 232 204 { 233 205 static BOOL fMatrox32BppBug = FALSE; 234 INT rc = 0; 206 INT height, width; 207 INT rc = 0; 235 208 char *newBits = NULL; 236 209 … … 239 212 } 240 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 241 238 //If upside down, reverse scanlines and call SetDIBitsToDevice again 242 // if(info->bmiHeader.biHeight < 0 && info->bmiHeader.biBitCount != 8 && info->bmiHeader.biCompression == 0) {243 239 if(info->bmiHeader.biHeight < 0 && (info->bmiHeader.biCompression == BI_RGB || 244 240 info->bmiHeader.biCompression == BI_BITFIELDS)) … … 246 242 // upside down 247 243 INT rc = -1; 248 long lLineByte = DIB_GetDIBWidthBytes(info->bmiHeader.biWidth, info->bmiHeader.biBitCount); 249 long lHeight = -info->bmiHeader.biHeight; 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); 250 260 251 261 //TODO: doesn't work if memory is readonly!! … … 254 264 char *newBits = (char *)malloc( lLineByte * lHeight ); 255 265 if(newBits) { 256 unsigned char *pbSrc = (unsigned char *)bits + x Src + lLineByte * (ySrc + lHeight - 1);257 unsigned char *pbDst = (unsigned char *)newBits ;258 for(int y = 0; y < lHeight; y++) {259 memcpy( pbDst, pbSrc, lLine Byte);260 pb Dst+= lLineByte;261 pb Src-= lLineByte;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; 262 272 } 263 273 //We only convert the necessary data so xSrc & ySrc are now 0 264 rc = SetDIBitsToDevice( hdc, xDest, yDest, cx, cy, 0, 0, startscan, lines, (void *)newBits, info, coloruse ); 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 ); 265 276 free( newBits ); 266 277 } … … 272 283 return rc; 273 284 } 274 275 //We must convert 32 bpp bitmap data to 24 bpp on systems with the Matrox276 //display driver. (GpiDrawBits for 32 bpp fails with insufficient memory error)277 if(info->bmiHeader.biBitCount == 32 && fMatrox32BppBug)278 {279 BITMAPINFO newInfo;280 newInfo.bmiHeader = info->bmiHeader;281 282 long lLineWidth;283 long lHeight = (newInfo.bmiHeader.biHeight > 0) ? newInfo.bmiHeader.biHeight : -newInfo.bmiHeader.biHeight;284 long lWidth = newInfo.bmiHeader.biWidth;285 286 newInfo.bmiHeader.biBitCount = 24;287 newInfo.bmiHeader.biSizeImage = CalcBitmapSize(24, newInfo.bmiHeader.biWidth,288 newInfo.bmiHeader.biHeight);289 290 lLineWidth = newInfo.bmiHeader.biSizeImage / lHeight;291 292 //convert 32 bits bitmap data to 24 bits293 newBits = (char *)malloc(newInfo.bmiHeader.biSizeImage+16); //extra room needed for copying (too much)294 if(!newBits) {295 DebugInt3();296 return -1;297 }298 unsigned char *pbSrc = (unsigned char *)bits;299 unsigned char *pbDst = (unsigned char *)newBits;300 //not very efficient301 for(int i = 0; i < lHeight; i++) {302 for(int j=0;j<lWidth;j++) {303 *(DWORD *)pbDst = *(DWORD *)pbSrc;304 pbSrc += 4;305 pbDst += 3;306 }307 //24 bpp scanline must be aligned at 4 byte boundary308 pbDst += (lLineWidth - 3*lWidth);309 }310 rc = SetDIBitsToDevice_( hdc, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, newBits, &newInfo, coloruse );311 free(newBits);312 return rc;313 }314 285 rc = SetDIBitsToDevice_( hdc, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, bits, info, coloruse ); 315 286 316 if(rc == -1 && info->bmiHeader.biBitCount == 32 && !fMatrox32BppBug)317 {318 //The Matrox driver seems to have some difficulty blitting 32bpp319 //data. (out of memory error) The same operation works fine with SDD.320 fMatrox32BppBug = TRUE;321 return SetDIBitsToDevice(hdc, xDest, yDest, cx,322 cy, xSrc, ySrc,323 startscan, lines, bits,324 info, coloruse);325 }326 287 return rc; 288 289 invalid_parameter: 290 SetLastError(ERROR_INVALID_PARAMETER); 291 return 0; 327 292 } 328 293 //****************************************************************************** … … 389 354 dprintf(("WARNING: StretchDIBits does NOT work correctly for 1 bpp bitmaps!!")); 390 355 } 391 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) 392 361 if(wUsage == DIB_PAL_COLORS && info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER)) 393 362 { … … 396 365 397 366 int i; 367 UINT biClrUsed; 398 368 USHORT *pColorIndex = (USHORT *)info->bmiColors; 399 RGBQUAD *pColors = (RGBQUAD *) alloca(info->bmiHeader.biClrUsed * 400 sizeof(RGBQUAD)); 401 BITMAPINFO *infoLoc = (BITMAPINFO *) alloca(sizeof(BITMAPINFO) + 402 info->bmiHeader.biClrUsed * sizeof(RGBQUAD)); 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)); 403 376 404 377 memcpy(infoLoc, info, sizeof(BITMAPINFO)); 405 378 406 if(GetDIBColorTable(hdc, 0, info->bmiHeader.biClrUsed, pColors) == 0) { 407 dprintf(("ERROR: StretchDIBits: GetDIBColorTable failed!!")); 408 return FALSE; 409 } 410 for(i=0;i<info->bmiHeader.biClrUsed;i++, pColorIndex++) 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++) 411 385 { 412 386 infoLoc->bmiColors[i] = pColors[*pColorIndex]; 413 387 } 414 388 … … 429 403 return rc; 430 404 } 431 405 #endif 432 406 switch(info->bmiHeader.biBitCount) { 433 407 case 15:
Note:
See TracChangeset
for help on using the changeset viewer.