image.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #include ".\image.h"
  2. MLImage::MLImage(void)
  3. {
  4. loader = NULL;
  5. loaderDelete = TRUE;
  6. ResetData();
  7. }
  8. MLImage::MLImage(IMGLOADFUNC loader, BOOL deleteDone)
  9. {
  10. ResetData();
  11. SetLoader(loader, deleteDone, FALSE);
  12. }
  13. MLImage::MLImage(int width, int height)
  14. {
  15. loader = NULL;
  16. ResetData();
  17. Init(width,height);
  18. }
  19. MLImage::~MLImage(void)
  20. {
  21. ResetData();
  22. }
  23. INT_PTR MLImage::SetLoader(IMGLOADFUNC loader, BOOL deleteDone, BOOL forceLoad)
  24. {
  25. this->loader = loader;
  26. this->loaderDelete = deleteDone;
  27. if (loader && forceLoad) Load();
  28. return (loader != NULL) ? (INT_PTR) this : FALSE;
  29. }
  30. BOOL MLImage::Load(void)
  31. {
  32. ResetData();
  33. if (!loader) return FALSE;
  34. HBITMAP hbmpLoaded = loader((INT_PTR)this);
  35. if(hbmpLoaded == NULL) return FALSE;
  36. BITMAP bi;
  37. if (GetObject(hbmpLoaded, sizeof(bi), &bi))
  38. {
  39. hbmp = ConvertTo32BppDIB(hbmpLoaded, bi.bmWidth, bi.bmHeight, &info, &data);
  40. }
  41. if (loaderDelete) DeleteObject(hbmpLoaded);
  42. return (hbmp != NULL);
  43. }
  44. void MLImage::ResetData(void)
  45. {
  46. if (hbmp) DeleteObject(hbmp);
  47. hbmp = NULL;
  48. SecureZeroMemory(&info, sizeof(BITMAPINFO));
  49. data = NULL;
  50. }
  51. BOOL MLImage::Draw(HDC hdcDest, int destX, int destY, int destWidth, int destHeight, int sourceX, int sourceY)
  52. {
  53. if (!hbmp) return FALSE;
  54. int realheight = abs(info.bmiHeader.biHeight);
  55. int rsX = min(sourceX, info.bmiHeader.biWidth);
  56. int rsY = min(sourceY, info.bmiHeader.biWidth);
  57. int height = min(destHeight, realheight - rsY);
  58. BOOL bResult = SetDIBitsToDevice( hdcDest, destX, destY,
  59. min(destWidth, info.bmiHeader.biWidth - rsX), height,
  60. rsX, realheight - height - rsY,
  61. 0, height,
  62. data, &info, DIB_RGB_COLORS);
  63. return bResult;
  64. }
  65. BOOL MLImage::Draw(HDC hdcDest, int destX, int destY)
  66. {
  67. return (!hbmp) ? FALSE : SetDIBitsToDevice( hdcDest, destX, destY,
  68. info.bmiHeader.biWidth, abs(info.bmiHeader.biHeight),
  69. 0, 0,
  70. 0, abs(info.bmiHeader.biHeight),
  71. data, &info, DIB_RGB_COLORS);
  72. }
  73. int MLImage::GetWidth(void) const
  74. {
  75. return (hbmp) ? info.bmiHeader.biWidth : 0;
  76. }
  77. int MLImage::GetHeight(void) const
  78. {
  79. return (hbmp) ? abs(info.bmiHeader.biHeight) : 0;
  80. }
  81. void* MLImage::GetData(void) const
  82. {
  83. return data;
  84. }
  85. HBITMAP MLImage::ConvertTo32BppDIB(HBITMAP bmpHandle, int bmpWidth, int bmpHeight, LPBITMAPINFO bmpInfo, LPVOID *bmpData)
  86. {
  87. HBITMAP hbmpNew = NULL;
  88. HDC hdc = GetWindowDC(NULL);
  89. HDC hdcTmp = CreateCompatibleDC(hdc);
  90. HBITMAP hbmpTmp = CreateCompatibleBitmap(hdc, bmpWidth, bmpHeight);
  91. HBITMAP hbmpOld = (HBITMAP) SelectObject(hdcTmp, hbmpTmp);
  92. // render original bitmap to the temp dc
  93. HDC hdcBmp = CreateCompatibleDC(hdc);
  94. SelectObject(hdcBmp, bmpHandle);
  95. BitBlt(hdcTmp, 0, 0, bmpWidth, bmpHeight, hdcBmp, 0,0, SRCCOPY);
  96. SelectObject(hdcBmp, NULL);
  97. DeleteDC(hdcBmp);
  98. // Create a 32 bit bitmap
  99. BITMAPINFO bih;
  100. // create DIB Section
  101. bih.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  102. bih.bmiHeader.biWidth = bmpWidth;
  103. bih.bmiHeader.biHeight = 0 - bmpHeight;
  104. bih.bmiHeader.biPlanes = 1;
  105. bih.bmiHeader.biBitCount = 32;
  106. bih.bmiHeader.biCompression = BI_RGB;
  107. bih.bmiHeader.biSizeImage = 0;
  108. bih.bmiHeader.biXPelsPerMeter = 0;
  109. bih.bmiHeader.biYPelsPerMeter = 0;
  110. bih.bmiHeader.biClrUsed = 0;
  111. bih.bmiHeader.biClrImportant = 0;
  112. // Create a DC which will be used to get DIB, then create DIBsection
  113. hbmpNew = CreateDIBSection(hdc, (const BITMAPINFO*) &bih, DIB_RGB_COLORS, bmpData, NULL, 0);
  114. DWORD* line = (DWORD*)(*bmpData);
  115. // Copy the bits into our 32 bit dib..
  116. for(int i=0; i<bmpHeight; i++)
  117. {
  118. for(int j=0; j<bmpWidth; j++)
  119. {
  120. line[(i*bmpWidth) + j] = FIXCOLORREF(GetPixel(hdcTmp, j, i));
  121. }
  122. }
  123. SelectObject(hdcTmp, hbmpOld);
  124. ReleaseDC(NULL, hdc);
  125. DeleteDC(hdcTmp);
  126. memcpy(bmpInfo, &bih, sizeof(BITMAPINFO));
  127. return hbmpNew;
  128. }
  129. MLImage* MLImage::Copy(MLImage* destination, const MLImage* original)
  130. {
  131. if (!destination) return NULL;
  132. destination->ResetData();
  133. destination->loader = original->loader;
  134. destination->loaderDelete = original->loaderDelete;
  135. destination->info = original->info;
  136. HDC hdc = GetWindowDC(NULL);
  137. destination->hbmp = CreateDIBSection(hdc, (const BITMAPINFO*) &destination->info, DIB_RGB_COLORS, &destination->data, NULL, 0);
  138. CopyMemory(destination->data, original->data, 4*destination->GetHeight() * destination->GetWidth());
  139. ReleaseDC(NULL, hdc);
  140. return destination;
  141. }
  142. MLImage* MLImage::Init(int width, int height)
  143. {
  144. ResetData();
  145. loader = NULL;
  146. loaderDelete = TRUE;
  147. // create DIB Section
  148. info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  149. info.bmiHeader.biWidth = width;
  150. info.bmiHeader.biHeight = 0 - height;
  151. info.bmiHeader.biPlanes = 1;
  152. info.bmiHeader.biBitCount = 32;
  153. info.bmiHeader.biCompression = BI_RGB;
  154. info.bmiHeader.biSizeImage = 0;
  155. info.bmiHeader.biXPelsPerMeter = 0;
  156. info.bmiHeader.biYPelsPerMeter = 0;
  157. info.bmiHeader.biClrUsed = 0;
  158. info.bmiHeader.biClrImportant = 0;
  159. HDC hdc = GetWindowDC(NULL);
  160. hbmp = CreateDIBSection(hdc, (const BITMAPINFO*) &info, DIB_RGB_COLORS, &data, NULL, 0);
  161. ReleaseDC(NULL, hdc);
  162. return this;
  163. }
  164. MLImage* MLImage::Init(int width, int height, COLORREF color)
  165. {
  166. Init(width, height);
  167. int rColor = FIXCOLORREF(color);
  168. DWORD *line = (DWORD*)(data);
  169. DWORD *end = line + GetHeight() * GetWidth();
  170. for(;line != end; line++) *line = rColor;
  171. return this;
  172. }