bmp.hpp 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. #pragma once
  2. namespace nall::Encode {
  3. struct BMP {
  4. static auto create(const string& filename, const void* data, uint pitch, uint width, uint height, bool alpha) -> bool {
  5. auto fp = file::open(filename, file::mode::write);
  6. if(!fp) return false;
  7. uint bitsPerPixel = alpha ? 32 : 24;
  8. uint bytesPerPixel = bitsPerPixel / 8;
  9. uint alignedWidth = width * bytesPerPixel;
  10. uint paddingLength = 0;
  11. uint imageSize = alignedWidth * height;
  12. uint fileSize = 0x36 + imageSize;
  13. while(alignedWidth % 4) alignedWidth++, paddingLength++;
  14. fp.writel(0x4d42, 2); //signature
  15. fp.writel(fileSize, 4); //file size
  16. fp.writel(0, 2); //reserved
  17. fp.writel(0, 2); //reserved
  18. fp.writel(0x36, 4); //offset
  19. fp.writel(40, 4); //DIB size
  20. fp.writel(width, 4); //width
  21. fp.writel(-height, 4); //height
  22. fp.writel(1, 2); //color planes
  23. fp.writel(bitsPerPixel, 2); //bits per pixel
  24. fp.writel(0, 4); //compression method (BI_RGB)
  25. fp.writel(imageSize, 4); //image data size
  26. fp.writel(3780, 4); //horizontal resolution
  27. fp.writel(3780, 4); //vertical resolution
  28. fp.writel(0, 4); //palette size
  29. fp.writel(0, 4); //important color count
  30. pitch >>= 2;
  31. for(auto y : range(height)) {
  32. auto p = (const uint32_t*)data + y * pitch;
  33. for(auto x : range(width)) fp.writel(*p++, bytesPerPixel);
  34. if(paddingLength) fp.writel(0, paddingLength);
  35. }
  36. return true;
  37. }
  38. };
  39. }