BMPLoader.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #include "BMPLoader.h"
  2. #include "api__bmp.h"
  3. #include <wchar.h>
  4. #include <bfc/platform/strcmp.h>
  5. static bool StringEnds(const wchar_t *a, const wchar_t *b)
  6. {
  7. size_t aLen = wcslen(a);
  8. size_t bLen = wcslen(b);
  9. if (aLen < bLen) return false; // too short
  10. return !_wcsicmp(a + aLen- bLen, b);
  11. }
  12. int BMPLoader::isMine(const wchar_t *filename)
  13. {
  14. return (filename && StringEnds(filename, L".BMP"));
  15. }
  16. const wchar_t *BMPLoader::mimeType()
  17. {
  18. return L"image/bmp";
  19. }
  20. int BMPLoader::getHeaderSize()
  21. {
  22. return 2;
  23. }
  24. int BMPLoader::testData(const void *data, int datalen)
  25. {
  26. if(datalen < 2) return 0;
  27. return *((WORD*)data) == (WORD)'MB';
  28. }
  29. static void writeFile(const wchar_t *file, const void * data, int length) {
  30. FILE *f = _wfopen(file,L"wb");
  31. if(!f) return;
  32. fwrite(data,length,1,f);
  33. fclose(f);
  34. }
  35. ARGB32 *BMPLoader::loadImage(const void *data, int datalen, int *w, int *h, ifc_xmlreaderparams *params)
  36. {
  37. int w0=0,h0=0;
  38. if(!w) w = &w0;
  39. if(!h) h = &h0;
  40. wchar_t file[MAX_PATH] = {0};
  41. GetTempPath(MAX_PATH, file);
  42. GetTempFileName(file,L"wa5bmp",0,file);
  43. writeFile(file,data,datalen);
  44. HBITMAP hbmp = (HBITMAP)LoadImage(0, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
  45. _wunlink(file);
  46. if(!hbmp) return 0;
  47. BITMAP bm;
  48. HDC hMemDC, hMemDC2;
  49. HBITMAP hsrcdib;
  50. void *srcdib;
  51. BITMAPINFO srcbmi = {0, };
  52. if(GetObject(hbmp, sizeof(BITMAP), &bm) == 0) { DeleteObject(hbmp); return 0; }
  53. *w = bm.bmWidth;
  54. *h = abs(bm.bmHeight);
  55. ARGB32 *newbits=NULL;
  56. srcbmi.bmiHeader.biSize = sizeof(srcbmi.bmiHeader);
  57. srcbmi.bmiHeader.biWidth = *w;
  58. srcbmi.bmiHeader.biHeight = -*h;
  59. srcbmi.bmiHeader.biPlanes = 1;
  60. srcbmi.bmiHeader.biBitCount = 32;
  61. srcbmi.bmiHeader.biCompression = BI_RGB;
  62. hMemDC = CreateCompatibleDC(NULL);
  63. hMemDC2 = CreateCompatibleDC(NULL);
  64. hsrcdib = CreateDIBSection(hMemDC, &srcbmi, DIB_RGB_COLORS, &srcdib, NULL, 0);
  65. if(hsrcdib) {
  66. HBITMAP hprev = (HBITMAP) SelectObject(hMemDC, hsrcdib);
  67. HBITMAP hprev2 = (HBITMAP) SelectObject(hMemDC2, hbmp);
  68. BitBlt(hMemDC, 0, 0, *w, *h, hMemDC2, 0, 0, SRCCOPY);
  69. newbits = (ARGB32*)WASABI_API_MEMMGR->sysMalloc((*w) * (*h) * sizeof(ARGB32));
  70. memcpy(newbits, srcdib, (*w)*(*h)*sizeof(ARGB32));
  71. {
  72. // put the alpha channel to 255
  73. unsigned char *b = (unsigned char *)newbits;
  74. int l = (*w) * (*h);
  75. for (int i = 0;i < l;i++)
  76. b[(i*4) + 3] = 0xff;
  77. }
  78. SelectObject(hMemDC, hprev);
  79. SelectObject(hMemDC2, hprev2);
  80. DeleteObject(hsrcdib);
  81. }
  82. DeleteDC(hMemDC2);
  83. DeleteDC(hMemDC);
  84. DeleteObject(hbmp);
  85. return newbits;
  86. }
  87. #define CBCLASS BMPLoader
  88. START_DISPATCH;
  89. CB(ISMINE, isMine);
  90. CB(MIMETYPE, mimeType);
  91. CB(TESTDATA, testData);
  92. CB(GETHEADERSIZE, getHeaderSize);
  93. CB(GETDIMENSIONS, getDimensions);
  94. CB(LOADIMAGE, loadImage);
  95. CB(LOADIMAGEDATA, loadImageData);
  96. END_DISPATCH;
  97. #undef CBCLASS