Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
4.4 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998
  4. *
  5. * TITLE: RESCALE.CPP
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 10/15/1998
  12. *
  13. * DESCRIPTION: Scale HBITMAPs using StretchBlt
  14. *
  15. *******************************************************************************/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. /*
  19. * ScaleImage: Scale hBmpSrc and store the scaled dib in hBmpTgt
  20. */
  21. HRESULT ScaleImage( HDC hDC, HBITMAP hBmpSrc, HBITMAP &hBmpTgt, const SIZE &sizeTgt )
  22. {
  23. WIA_PUSH_FUNCTION((TEXT("ScaleImage( sizeTgt = [%d,%d] )"), sizeTgt.cx, sizeTgt.cy ));
  24. BITMAPINFO bmi;
  25. BITMAP bm;
  26. HRESULT hr = E_FAIL;
  27. HBITMAP hBmp = NULL;
  28. hBmpTgt = NULL;
  29. GetObject( hBmpSrc, sizeof(BITMAP), &bm );
  30. ZeroMemory( &bmi, sizeof(BITMAPINFO) );
  31. bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  32. bmi.bmiHeader.biWidth = sizeTgt.cx;
  33. bmi.bmiHeader.biHeight = sizeTgt.cy;
  34. bmi.bmiHeader.biPlanes = 1;
  35. bmi.bmiHeader.biBitCount = 24;
  36. bmi.bmiHeader.biCompression = BI_RGB;
  37. HPALETTE hHalftonePalette = CreateHalftonePalette(hDC);
  38. if (hHalftonePalette)
  39. {
  40. PBYTE pBitmapData = NULL;
  41. hBmp = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS, (LPVOID*)&pBitmapData, NULL, 0 );
  42. if (hBmp)
  43. {
  44. // Create the source dc
  45. HDC hMemoryDC = CreateCompatibleDC( hDC );
  46. if (hMemoryDC)
  47. {
  48. HPALETTE hOldMemDCPalette = SelectPalette( hMemoryDC, hHalftonePalette , 0 );
  49. RealizePalette( hMemoryDC );
  50. SetBrushOrgEx( hMemoryDC, 0,0, NULL );
  51. HBITMAP hOldMemDCBitmap = (HBITMAP)SelectObject( hMemoryDC, hBmpSrc );
  52. // Create the target dc
  53. HDC hStretchDC = CreateCompatibleDC( hDC );
  54. if (hStretchDC)
  55. {
  56. HPALETTE hOldStretchDCPalette = SelectPalette( hStretchDC, hHalftonePalette , 0 );
  57. RealizePalette( hStretchDC );
  58. SetBrushOrgEx( hStretchDC, 0,0, NULL );
  59. HBITMAP hOldStretchDCBitmap = (HBITMAP)SelectObject( hStretchDC, hBmp );
  60. INT nOldStretchMode = SetStretchBltMode( hStretchDC, STRETCH_HALFTONE );
  61. SIZE sizeScaled;
  62. // Width is constraining factor
  63. if (sizeTgt.cy*bm.bmWidth > sizeTgt.cx*bm.bmHeight)
  64. {
  65. sizeScaled.cx = sizeTgt.cx;
  66. sizeScaled.cy = WiaUiUtil::MulDivNoRound(bm.bmHeight,sizeTgt.cx,bm.bmWidth);
  67. }
  68. // Height is constraining factor
  69. else
  70. {
  71. sizeScaled.cx = WiaUiUtil::MulDivNoRound(bm.bmWidth,sizeTgt.cy,bm.bmHeight);
  72. sizeScaled.cy = sizeTgt.cy;
  73. }
  74. // Fill the background
  75. RECT rc;
  76. rc.left = rc.top = 0;
  77. rc.right = sizeTgt.cx;
  78. rc.bottom = sizeTgt.cy;
  79. FillRect( hStretchDC, &rc, GetSysColorBrush(COLOR_WINDOW) );
  80. // Paint the image
  81. StretchBlt( hStretchDC, (sizeTgt.cx - sizeScaled.cx) / 2, (sizeTgt.cy - sizeScaled.cy) / 2, sizeScaled.cx, sizeScaled.cy, hMemoryDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY );
  82. // Everything is OK
  83. hBmpTgt = hBmp;
  84. hr = S_OK;
  85. // Restore the dc's state and delete it
  86. SetStretchBltMode( hStretchDC, nOldStretchMode );
  87. SelectObject( hStretchDC, hOldStretchDCBitmap );
  88. SelectPalette( hStretchDC, hOldStretchDCPalette , 0 );
  89. DeleteDC( hStretchDC );
  90. }
  91. // Restore the dc's state
  92. SelectObject( hMemoryDC, hOldMemDCBitmap );
  93. SelectPalette( hMemoryDC, hOldMemDCPalette , 0 );
  94. DeleteDC( hMemoryDC );
  95. }
  96. }
  97. if (hHalftonePalette)
  98. {
  99. DeleteObject( hHalftonePalette );
  100. }
  101. }
  102. // Clean up the new bitmap if there was an error
  103. if (!SUCCEEDED(hr) && hBmp)
  104. DeleteObject( hBmp );
  105. WIA_TRACE((TEXT("hBmpTgt = %p")));
  106. return (hr);
  107. }