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.

195 lines
3.8 KiB

  1. #include "header.h"
  2. #include "DibCls.H"
  3. #define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc)
  4. #include <urlmon.h>
  5. #define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
  6. //=--------------------------------------------------------------------------=
  7. // DIB Utitilty Classes
  8. //=--------------------------------------------------------------------------=
  9. // Not wholey generic but getting there...
  10. //
  11. // Notes:
  12. //
  13. CDibFile::CDibFile()
  14. {
  15. m_headerSize = 0;
  16. m_bmi.p = 0;
  17. }
  18. CDibFile::~CDibFile()
  19. {
  20. if( m_bmi.p )
  21. delete m_bmi.p;
  22. }
  23. DWORD CDibFile::CalcImageSize()
  24. {
  25. DWORD & dw = m_bmi.p->bmiHeader.biSizeImage;
  26. if( dw == 0)
  27. dw = WIDTHBYTES((DWORD)m_bmi.p->bmiHeader.biWidth *
  28. m_bmi.p->bmiHeader.biBitCount) * m_bmi.p->bmiHeader.biHeight;
  29. return(dw);
  30. }
  31. HRESULT CDibFile::GetInfoHeader( IStream * strm )
  32. {
  33. HRESULT hr = S_OK;
  34. m_bmi.bytes = new unsigned char[ m_headerSize ];
  35. if( !m_bmi.bytes )
  36. hr = E_OUTOFMEMORY;
  37. if( SUCCEEDED(hr) )
  38. hr = strm->Read(m_bmi.bytes,m_headerSize,0);
  39. if( SUCCEEDED(hr) )
  40. CalcImageSize();
  41. return(hr);
  42. }
  43. HRESULT CDibFile::GetFileHeader(IStream * strm)
  44. {
  45. BITMAPFILEHEADER bmfh;
  46. HRESULT hr = strm->Read(&bmfh,sizeof(bmfh),0);
  47. if( SUCCEEDED(hr) && (bmfh.bfType != 0x4d42 ))
  48. hr = E_UNEXPECTED;
  49. if( SUCCEEDED(hr) )
  50. m_headerSize = bmfh.bfOffBits - sizeof(bmfh);
  51. return(hr);
  52. }
  53. CDibSection::CDibSection()
  54. {
  55. m_bitsBase = 0;
  56. m_current = 0;
  57. m_memDC = 0;
  58. m_handle =
  59. m_oldBitmap = 0;
  60. m_w =
  61. m_h = 32; // totally arbitrary
  62. }
  63. CDibSection::~CDibSection()
  64. {
  65. if( m_memDC )
  66. {
  67. if( m_oldBitmap )
  68. ::SelectObject( m_memDC, m_oldBitmap );
  69. ::DeleteDC(m_memDC);
  70. }
  71. if( m_handle )
  72. ::DeleteObject(m_handle);
  73. }
  74. HRESULT CDibSection::Create(CDibFile& dibFile)
  75. {
  76. HRESULT hr = S_OK;
  77. BITMAPINFOHEADER * bmih = dibFile; // will convert itself
  78. m_handle = ::CreateDIBSection(
  79. m_memDC, // handle to device context
  80. dibFile, // pointer to structure containing bitmap size,
  81. // format, and color data
  82. DIB_RGB_COLORS, // color data type indicator: RGB values or
  83. // palette indices
  84. (void **)&m_bitsBase, // pointer to variable to receive a pointer
  85. // to the bitmap's bit values
  86. 0, // optional handle to a file mapping object
  87. 0 // offset to the bitmap bit values
  88. // within the file mapping object
  89. );
  90. if( !m_handle )
  91. hr = E_FAIL;
  92. if( SUCCEEDED(hr) )
  93. {
  94. m_oldBitmap = ::SelectObject( m_memDC, m_handle );
  95. if( !m_oldBitmap )
  96. hr = E_FAIL;
  97. }
  98. if( SUCCEEDED(hr) )
  99. {
  100. m_current = m_bitsBase;
  101. m_w = bmih->biWidth;
  102. m_h = bmih->biHeight;
  103. if( m_h < 0 )
  104. m_h *= -1;
  105. }
  106. return(hr);
  107. }
  108. HRESULT CDibSection::ReadFrom( IStream * strm, DWORD amount )
  109. {
  110. DWORD dwRead = 0;
  111. DWORD dwReadTotal = 0;
  112. HRESULT hr;
  113. do
  114. {
  115. hr = strm->Read(m_current,amount,&dwRead);
  116. if( SUCCEEDED(hr) || hr == E_PENDING )
  117. {
  118. m_current += dwRead;
  119. dwReadTotal += dwRead;
  120. }
  121. }
  122. while ( (hr == S_OK) && (dwReadTotal <= amount) );
  123. return (hr);
  124. }
  125. HRESULT CDibSection::Setup(HDC hdc)
  126. {
  127. m_memDC = ::CreateCompatibleDC(hdc);
  128. return( m_memDC ? NOERROR : E_FAIL );
  129. }
  130. HRESULT CDibSection::PaintTo(HDC hdc, int x, int y)
  131. {
  132. BOOL b = BitBlt(
  133. hdc, // handle to destination device context
  134. x, // x-coordinate of destination rectangle's upper-left corner
  135. y, // x-coordinate of destination rectangle's upper-left corner
  136. m_w, // width of destination rectangle
  137. m_h, // height of destination rectangle
  138. m_memDC, // handle to source device context
  139. 0, // x-coordinate of source rectangle's upper-left corner
  140. 0, // y-coordinate of source rectangle's upper-left corner
  141. SRCCOPY // raster operation code
  142. );
  143. return( b ? NOERROR : E_FAIL );
  144. }
  145. HRESULT CDibSection::GetSize(SIZEL &sz)
  146. {
  147. sz.cx = m_w;
  148. sz.cy = m_h;
  149. return(S_OK);
  150. }