- Timestamp:
- Oct 7, 2000, 11:03:50 AM (25 years ago)
- Location:
- trunk/src/gdi32
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gdi32/dibsect.cpp
r4354 r4447 1 /* $Id: dibsect.cpp,v 1. 39 2000-10-01 21:16:17 phallerExp $ */1 /* $Id: dibsect.cpp,v 1.40 2000-10-07 09:03:49 hugh Exp $ */ 2 2 3 3 /* … … 31 31 #include "rgbcvt.h" 32 32 33 #define DBG_LOCALLOG 33 #define DBG_LOCALLOG DBG_dibsect 34 34 #include "dbglocal.h" 35 35 … … 52 52 { 53 53 case 1: 54 55 56 54 bmpsize = ((bmpsize + 31) & ~31) / 8; 55 palsize = ((1 << pbmi->biBitCount))*sizeof(RGB2); 56 os2bmphdrsize += palsize; 57 57 break; 58 58 case 4: 59 59 bmpsize = ((bmpsize + 7) & ~7) / 2; 60 60 palsize = ((1 << pbmi->biBitCount))*sizeof(RGB2); 61 61 os2bmphdrsize += palsize; 62 62 break; 63 63 case 8: 64 65 66 64 palsize = ((1 << pbmi->biBitCount))*sizeof(RGB2); 65 os2bmphdrsize += palsize; 66 bmpsize = (bmpsize + 3) & ~3; 67 67 break; 68 68 case 16: 69 69 bmpsize *= 2; 70 70 bmpsize = (bmpsize + 3) & ~3; 71 71 break; 72 72 case 24: 73 73 bmpsize *= 3; 74 74 bmpsize = (bmpsize + 3) & ~3; 75 75 break; 76 76 case 32: 77 77 bmpsize *= 4; 78 78 break; 79 80 81 82 79 default: 80 dprintf(("Unsupported nr of bits %d", pbmi->biBitCount)); 81 DebugInt3(); 82 break; 83 83 } 84 84 … … 86 86 this->dwOffset = dwOffset; 87 87 if(hSection) { 88 89 90 91 92 88 bmpBits = (char *)MapViewOfFile(hSection, FILE_MAP_ALL_ACCESS_W, 0, dwOffset, bmpsize*pbmi->biHeight); 89 if(!bmpBits) { 90 dprintf(("Dibsection: mapViewOfFile %x failed!", hSection)); 91 DebugInt3(); 92 } 93 93 } 94 94 if(!bmpBits) { 95 95 DosAllocMem((PPVOID)&bmpBits, bmpsize*pbmi->biHeight, PAG_READ|PAG_WRITE|PAG_COMMIT); 96 96 } 97 97 memset(bmpBits, 0, bmpsize*pbmi->biHeight); … … 111 111 //SvL: Ignore BI_BITFIELDS_W type (GpiDrawBits fails otherwise) 112 112 if(pOS2bmp->ulCompression == BI_BITFIELDS_W) { 113 113 pOS2bmp->ulCompression = 0; 114 114 } 115 115 pOS2bmp->cbImage = pbmi->biSizeImage; … … 142 142 { 143 143 dibinfo.dsBitfields[0] = dibinfo.dsBitfields[1] = dibinfo.dsBitfields[2] = 0; 144 145 146 144 if(palsize) { 145 SetDIBColorTable(0, (1 << pbmi->biBitCount), (RGBQUAD *)(pbmi+1)); 146 } 147 147 } 148 148 else { 149 150 149 switch(pbmi->biBitCount) 150 { 151 151 case 16: 152 153 154 155 152 dibinfo.dsBitfields[0] = (pbmi->biCompression == BI_BITFIELDS_W) ? *(DWORD *)pColors : 0x7c00; 153 dibinfo.dsBitfields[1] = (pbmi->biCompression == BI_BITFIELDS_W) ? *((DWORD *)pColors + 1) : 0x03e0; 154 dibinfo.dsBitfields[2] = (pbmi->biCompression == BI_BITFIELDS_W) ? *((DWORD *)pColors + 2) : 0x001f; 155 break; 156 156 157 157 case 24: 158 159 160 161 158 dibinfo.dsBitfields[0] = 0xff; 159 dibinfo.dsBitfields[1] = 0xff00; 160 dibinfo.dsBitfields[2] = 0xff0000; 161 break; 162 162 163 163 case 32: 164 165 166 167 168 169 170 171 172 164 dibinfo.dsBitfields[0] = (pbmi->biCompression == BI_BITFIELDS_W) ? *(DWORD *)pColors : 0xff; 165 dibinfo.dsBitfields[1] = (pbmi->biCompression == BI_BITFIELDS_W) ? *((DWORD *)pColors + 1) : 0xff00; 166 dibinfo.dsBitfields[2] = (pbmi->biCompression == BI_BITFIELDS_W) ? *((DWORD *)pColors + 2) : 0xff0000; 167 if(dibinfo.dsBitfields[0] != 0xff && dibinfo.dsBitfields[1] != 0xff00 && dibinfo.dsBitfields[2] != 0xff0000) { 168 dprintf(("DIBSection: unsupported bitfields for 32 bits bitmap!!")); 169 } 170 break; 171 } 172 dprintf(("BI_BITFIELDS_W %x %x %x", dibinfo.dsBitfields[0], dibinfo.dsBitfields[1], dibinfo.dsBitfields[2])); 173 173 } 174 174 //double buffer for rgb 555 dib sections (for conversion) or flipped sections 175 175 if(dibinfo.dsBitfields[1] == 0x03e0 || (fFlip & FLIP_VERT)) { 176 176 DosAllocMem((PPVOID)&bmpBitsDblBuffer, bmpsize*pbmi->biHeight, PAG_READ|PAG_WRITE|PAG_COMMIT); 177 177 } 178 178 … … 209 209 210 210 if(hSection) { 211 211 UnmapViewOfFile(bmpBits); 212 212 } 213 213 else … … 216 216 217 217 if(bmpBitsDblBuffer) 218 218 DosFreeMem(bmpBitsDblBuffer); 219 219 220 220 if(pOS2bmp) … … 282 282 //SvL: TODO: Correct?? 283 283 if(!hSection && pOS2bmp->cx != pbmi->biWidth && pOS2bmp->cy != pbmi->biHeight && 284 pOS2bmp->cBitCount != pbmi->biBitCount) 284 pOS2bmp->cBitCount != pbmi->biBitCount) 285 285 { 286 287 288 289 290 291 286 char *oldbits = bmpBits; 287 int oldsize = dibinfo.dsBm.bmWidthBytes * dibinfo.dsBm.bmHeight; 288 289 DosAllocMem((PPVOID)&bmpBits, bmpsize*pbmi->biHeight, PAG_READ|PAG_WRITE|PAG_COMMIT); 290 memcpy(bmpBits, oldbits, min(oldsize, bmpsize*pbmi->biHeight)); 291 DosFreeMem(oldbits); 292 292 } 293 293 pOS2bmp = (BITMAPINFO2 *)realloc(pOS2bmp, os2bmphdrsize); … … 321 321 } 322 322 else { 323 324 325 326 323 char *pColors = (char *)pbmi + 1; 324 325 switch(pbmi->biBitCount) 326 { 327 327 case 16: 328 329 330 331 328 dibinfo.dsBitfields[0] = (pbmi->biCompression == BI_BITFIELDS_W) ? *(DWORD *)pColors : 0x7c00; 329 dibinfo.dsBitfields[1] = (pbmi->biCompression == BI_BITFIELDS_W) ? *((DWORD *)pColors + 1) : 0x03e0; 330 dibinfo.dsBitfields[2] = (pbmi->biCompression == BI_BITFIELDS_W) ? *((DWORD *)pColors + 2) : 0x001f; 331 break; 332 332 333 333 case 24: 334 335 336 337 334 dibinfo.dsBitfields[0] = 0xff; 335 dibinfo.dsBitfields[1] = 0xff00; 336 dibinfo.dsBitfields[2] = 0xff0000; 337 break; 338 338 339 339 case 32: 340 341 342 343 344 345 346 347 348 340 dibinfo.dsBitfields[0] = (pbmi->biCompression == BI_BITFIELDS_W) ? *(DWORD *)pColors : 0xff; 341 dibinfo.dsBitfields[1] = (pbmi->biCompression == BI_BITFIELDS_W) ? *((DWORD *)pColors + 1) : 0xff00; 342 dibinfo.dsBitfields[2] = (pbmi->biCompression == BI_BITFIELDS_W) ? *((DWORD *)pColors + 2) : 0xff0000; 343 if(dibinfo.dsBitfields[0] != 0xff && dibinfo.dsBitfields[1] != 0xff00 && dibinfo.dsBitfields[2] != 0xff0000) { 344 dprintf(("DIBSection: unsupported bitfields for 32 bits bitmap!!")); 345 } 346 break; 347 } 348 dprintf(("BI_BITFIELDS_W %x %x %x", dibinfo.dsBitfields[0], dibinfo.dsBitfields[1], dibinfo.dsBitfields[2])); 349 349 } 350 350 351 351 //double buffer for rgb 555 dib sections (for conversion) or flipped sections 352 352 if(dibinfo.dsBitfields[1] == 0x03e0 || (fFlip & FLIP_VERT)) { 353 354 355 356 353 if(bmpBitsDblBuffer) { 354 DosFreeMem(bmpBitsDblBuffer); 355 } 356 DosAllocMem((PPVOID)&bmpBitsDblBuffer, dibinfo.dsBm.bmWidthBytes*pbmi->biHeight, PAG_READ|PAG_WRITE|PAG_COMMIT); 357 357 } 358 358 359 359 dprintf(("DIBSection::SetDIBits (%d,%d), %d %d", pbmi->biWidth, pbmi->biHeight, pbmi->biBitCount, pbmi->biCompression)); 360 360 if(palsize) { 361 361 SetDIBColorTable(0, 1 << pbmi->biBitCount, (RGBQUAD *)(pbmi+1)); 362 362 } 363 363 364 364 if(bits) 365 365 { 366 367 366 int size = bmpsize*lines; 367 memcpy(bmpBits+bmpsize*startscan, bits, size); 368 368 } 369 369 return(lines); … … 417 417 hwndDest = WindowFromDC(hdcDest); //could return desktop window, so check that 418 418 if(hwndDest && pHps->hwnd && !pHps->isClient) { 419 419 fFrameWindowDC = TRUE; 420 420 } 421 421 … … 425 425 426 426 if(hwndDest) { 427 428 429 430 431 432 elseGetClientRect(hwndDest, &rect);433 434 427 RECT rect; 428 429 if(fFrameWindowDC) { 430 GetWindowRect(hwndDest, &rect); 431 } 432 else GetClientRect(hwndDest, &rect); 433 hdcHeight = rect.bottom - rect.top; 434 hdcWidth = rect.right - rect.left; 435 435 } 436 436 else { 437 hdcHeight = pOS2bmp->cy; 438 hdcWidth = pOS2bmp->cx; 437 DIBSection *dsect = DIBSection::findHDC(hdcDest); 438 if(dsect) 439 { 440 hdcHeight = dsect->GetHeight(); 441 hdcWidth = dsect->GetWidth(); 442 } 443 else 444 { 445 hdcHeight = pOS2bmp->cy; 446 hdcWidth = pOS2bmp->cx; 447 } 439 448 } 440 449 … … 442 451 //source rectangle is non-inclusive (top, right not included) 443 452 //destination rectangle is incl.-inclusive (everything included) 453 444 454 if(nXdest + nDestWidth > hdcWidth) { 445 nDestWidth = hdcWidth - nXdest; 446 } 455 nDestWidth = hdcWidth - nXdest; 456 } 457 447 458 if(nYdest + nDestHeight > hdcHeight) { 448 nDestHeight = hdcHeight - nYdest; 449 } 459 nDestHeight = hdcHeight - nYdest; 460 } 461 450 462 point[0].x = nXdest; 451 463 point[0].y = hdcHeight - nYdest - nDestHeight; … … 455 467 //target rectangle is inclusive-inclusive 456 468 if(nXsrc + nSrcWidth > pOS2bmp->cx) { 457 469 nSrcWidth = pOS2bmp->cx - nXsrc; 458 470 } 459 471 if(nYsrc + nSrcHeight > pOS2bmp->cy) { 460 472 nSrcHeight = pOS2bmp->cy - nYsrc; 461 473 } 462 474 point[2].x = nXsrc; … … 473 485 if(hwndDest != 0) 474 486 { 475 487 hps = WinGetPS(hwndDest); 476 488 } 477 489 */ 478 490 oldyinversion = GpiQueryYInversion(hps); 479 491 if(oldyinversion != 0) { 480 481 492 GpiEnableYInversion(hps, 0); 493 fRestoryYInversion = TRUE; 482 494 } 483 495 484 496 if(fFlip & FLIP_HOR) 485 497 { 486 487 488 489 498 ULONG x; 499 x = point[0].x; 500 point[0].x = point[1].x; 501 point[1].x = x; 490 502 } 491 503 … … 496 508 switch(winmode) { 497 509 case BLACKONWHITE_W: 498 499 510 os2mode = BBO_AND; 511 break; 500 512 case WHITEONBLACK_W: 501 513 case HALFTONE_W: //TODO: 502 503 514 os2mode = BBO_OR; 515 break; 504 516 case COLORONCOLOR_W: 505 506 517 os2mode = BBO_IGNORE; 518 break; 507 519 } 508 520 if(fFlip & FLIP_VERT) { 509 510 511 512 513 514 515 516 517 521 //manually reverse bitmap data 522 char *src = bmpBits + (pOS2bmp->cy-1)*dibinfo.dsBm.bmWidthBytes; 523 char *dst = bmpBitsDblBuffer; 524 for(int i=0;i<pOS2bmp->cy;i++) { 525 memcpy(dst, src, dibinfo.dsBm.bmWidthBytes); 526 dst += dibinfo.dsBm.bmWidthBytes; 527 src -= dibinfo.dsBm.bmWidthBytes; 528 } 529 bitmapBits = bmpBitsDblBuffer; 518 530 } 519 531 else bitmapBits = bmpBits; … … 521 533 //SvL: Optimize this.. (don't convert entire bitmap if only a part will be blitted to the dc) 522 534 if(dibinfo.dsBitfields[1] == 0x3E0) {//RGB 555? 523 524 525 526 527 535 dprintf(("DIBSection::BitBlt; convert rgb 555 to 565 (old y inv. = %d)", oldyinversion)); 536 537 if(bmpBitsDblBuffer == NULL) 538 DebugInt3(); 539 528 540 // PH 2000/10/01 - Fix for Beyond Compare 1.9d 529 541 // Note: according to documentation, cmImage can be zero for … … 532 544 if (iLength == 0) 533 545 iLength = pOS2bmp->cx * pOS2bmp->cy * (pOS2bmp->cBitCount >> 3); 534 546 535 547 if (iLength > 0) 536 548 { 537 if(CPUFeatures & CPUID_MMX) 549 if(CPUFeatures & CPUID_MMX) 538 550 RGB555to565MMX((WORD *)bmpBitsDblBuffer, (WORD *)bitmapBits, iLength/sizeof(WORD)); 539 else 551 else 540 552 RGB555to565((WORD *)bmpBitsDblBuffer, (WORD *)bitmapBits, iLength/sizeof(WORD)); 541 553 } … … 549 561 rc = GpiDrawBits(hps, bmpBitsDblBuffer, pOS2bmp, 4, &point[0], ROP_SRCCOPY, os2mode); 550 562 } 551 else 563 else rc = GpiDrawBits(hps, bitmapBits, pOS2bmp, 4, &point[0], ROP_SRCCOPY, os2mode); 552 564 553 565 /* … … 558 570 */ 559 571 if(rc == GPI_OK) { 560 572 DIBSection *destdib = DIBSection::findHDC(hdcDest); 561 573 if(destdib) { 562 574 destdib->sync(hps, nYdest, nDestHeight); 563 575 } 564 565 566 567 568 576 //restore old y inversion height 577 if(fRestoryYInversion) GpiEnableYInversion(hps, oldyinversion); 578 SetLastError(ERROR_SUCCESS_W); 579 580 return(TRUE); 569 581 } 570 582 if(fRestoryYInversion) GpiEnableYInversion(hps, oldyinversion); … … 575 587 } 576 588 //****************************************************************************** 577 int WIN32API GetDIBits(HDC hdc, HBITMAP hBitmap, UINT uStartScan, UINT cScanLines, 589 int WIN32API GetDIBits(HDC hdc, HBITMAP hBitmap, UINT uStartScan, UINT cScanLines, 578 590 void *lpvBits, BITMAPINFO_W * lpbi, UINT uUsage); 579 591 580 592 //****************************************************************************** 581 void DIBSection::sync(HDC hdc, DWORD nYdest, DWORD nDestHeight) 593 void DIBSection::sync(HDC hdc, DWORD nYdest, DWORD nDestHeight) 582 594 { 583 595 APIRET rc; … … 594 606 #ifdef DEBUG_PALETTE 595 607 if(rc && tmphdr->bmiHeader.biBitCount <= 8) { 596 597 598 599 608 for(int i=0;i<(1<<tmphdr->bmiHeader.biBitCount);i++) 609 { 610 dprintf2(("Index %d : 0x%08X\n",i, *((ULONG*)(&tmphdr->bmiColors[i])) )); 611 } 600 612 } 601 613 #endif … … 606 618 607 619 if(fFlip & FLIP_VERT) { 608 620 destBuf = bmpBitsDblBuffer + nYdest*dibinfo.dsBm.bmWidthBytes; 609 621 610 622 rc = GpiQueryBitmapBits(hdc, nYdest, nDestHeight, destBuf, 611 623 tmphdr); 612 613 614 615 616 617 618 619 624 //manually reverse bitmap data 625 char *src = destBuf; 626 char *dst = GetDIBObject() + (nYdest+nDestHeight-1)*dibinfo.dsBm.bmWidthBytes; 627 for(int i=0;i<nDestHeight;i++) { 628 memcpy(dst, src, dibinfo.dsBm.bmWidthBytes); 629 dst -= dibinfo.dsBm.bmWidthBytes; 630 src += dibinfo.dsBm.bmWidthBytes; 631 } 620 632 } 621 633 else { 622 634 destBuf = GetDIBObject() + nYdest*dibinfo.dsBm.bmWidthBytes; 623 635 rc = GpiQueryBitmapBits(hdc, nYdest, nDestHeight, destBuf, 624 636 tmphdr); 625 637 #ifdef DEBUG_PALETTE 626 627 628 629 630 631 638 if(rc != GPI_ALTERROR && tmphdr->cBitCount <= 8) { 639 for(int i=0;i<(1<<tmphdr->cBitCount);i++) 640 { 641 dprintf2(("Index %d : 0x%08X\n",i, *((ULONG*)(&tmphdr->argbColor[i])) )); 642 } 643 } 632 644 #endif 633 645 } … … 635 647 #if 0 636 648 if(dibinfo.dsBitfields[1] == 0x3E0) {//RGB 555? 637 638 639 640 641 642 643 644 elseRGB565to555((WORD *)destBuf, (WORD *)destBuf, (nDestHeight*dibinfo.dsBm.bmWidthBytes)/sizeof(WORD));649 dprintf(("DIBSection::sync: convert RGB 565 to RGB 555")); 650 651 destBuf = GetDIBObject() + nYdest*dibinfo.dsBm.bmWidthBytes; 652 653 if(CPUFeatures & CPUID_MMX) { 654 RGB565to555MMX((WORD *)destBuf, (WORD *)destBuf, (nDestHeight*dibinfo.dsBm.bmWidthBytes)/sizeof(WORD)); 655 } 656 else RGB565to555((WORD *)destBuf, (WORD *)destBuf, (nDestHeight*dibinfo.dsBm.bmWidthBytes)/sizeof(WORD)); 645 657 } 646 658 #endif 647 659 free(tmphdr); 648 660 if(rc != nDestHeight) { 649 661 DebugInt3(); 650 662 } 651 663 } 652 664 //****************************************************************************** 653 665 //manual sync if no stretching and bpp is the same 654 //WARNING: this also assumes the colortables are the same 666 //WARNING: this also assumes the colortables are the same 655 667 //****************************************************************************** 656 668 void DIBSection::sync(DWORD xDst, DWORD yDst, DWORD widthDst, DWORD heightDst, PVOID bits) … … 659 671 int linesize; 660 672 661 srcbuf = (char *)bits + dibinfo.dsBm.bmWidthBytes*yDst + 673 srcbuf = (char *)bits + dibinfo.dsBm.bmWidthBytes*yDst + 662 674 (xDst*dibinfo.dsBm.bmWidthBytes)/pOS2bmp->cx; 663 destbuf = (char *)GetDIBObject() + dibinfo.dsBm.bmWidthBytes*yDst + 675 destbuf = (char *)GetDIBObject() + dibinfo.dsBm.bmWidthBytes*yDst + 664 676 (xDst*dibinfo.dsBm.bmWidthBytes)/pOS2bmp->cx; 665 677 linesize = (widthDst*dibinfo.dsBm.bmWidthBytes)/pOS2bmp->cx; 666 678 for(int i=0;i<heightDst;i++) { 667 668 669 679 memcpy(destbuf, srcbuf, linesize); 680 destbuf += dibinfo.dsBm.bmWidthBytes; 681 srcbuf += linesize; 670 682 } 671 683 } … … 689 701 if(dsect->handle == handle) 690 702 { 691 692 703 dibMutex.leave(); 704 return(dsect); 693 705 } 694 706 dsect = dsect->next; … … 734 746 if(iSize == sizeof(DIBSECTION)) 735 747 { 736 748 memcpy(pDIBSection, &dibinfo, sizeof(dibinfo)); 737 749 return sizeof(DIBSECTION); 738 750 } … … 740 752 if(iSize == sizeof(BITMAP_W)) 741 753 { 742 743 754 memcpy(dsBm, &dibinfo.dsBm, sizeof(dibinfo.dsBm)); 755 return sizeof(BITMAP_W); 744 756 } 745 757 return 0; … … 766 778 //****************************************************************************** 767 779 //****************************************************************************** 780 int DIBSection::GetWidth() 781 { 782 if(pOS2bmp == NULL) 783 return 0; 784 else 785 return pOS2bmp->cx; 786 } 787 //****************************************************************************** 788 //****************************************************************************** 768 789 DIBSection *DIBSection::section = NULL; -
trunk/src/gdi32/dibsect.h
r4127 r4447 1 /* $Id: dibsect.h,v 1.2 0 2000-08-30 18:05:24 sandervlExp $ */1 /* $Id: dibsect.h,v 1.21 2000-10-07 09:03:50 hugh Exp $ */ 2 2 3 3 /* … … 50 50 51 51 typedef struct { 52 53 RGBQUADbmiColors[1];52 BITMAPINFOHEADER_W bmiHeader; 53 RGBQUAD bmiColors[1]; 54 54 } BITMAPINFO_W; 55 55 typedef BITMAPINFO *LPBITMAPINFO; … … 79 79 int GetBitCount(); 80 80 int GetHeight(); 81 int GetWidth(); 81 82 void UnSelectDIBObject() { this->hdc = 0; }; 82 83 83 DWORD GetBitmapHandle(){ return handle; };84 DWORD GetBitmapHandle() { return handle; }; 84 85 void SetBitmapHandle(DWORD bmphandle) { handle = bmphandle; }; 85 86 DWORD GetRGBUsage() { return iUsage; }; 86 87 87 88 BOOL BitBlt(HDC hdcDest, int nXdest, int nYDest,
Note:
See TracChangeset
for help on using the changeset viewer.