load.hpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #pragma once
  2. namespace nall {
  3. inline auto image::loadBMP(const string& filename) -> bool {
  4. if(!file::exists(filename)) return false;
  5. auto buffer = file::read(filename);
  6. return loadBMP(buffer.data(), buffer.size());
  7. }
  8. inline auto image::loadBMP(const uint8_t* bmpData, uint bmpSize) -> bool {
  9. Decode::BMP source;
  10. if(!source.load(bmpData, bmpSize)) return false;
  11. allocate(source.width(), source.height());
  12. const uint32_t* sp = source.data();
  13. uint8_t* dp = _data;
  14. for(uint y = 0; y < _height; y++) {
  15. for(uint x = 0; x < _width; x++) {
  16. uint32_t color = *sp++;
  17. uint64_t a = normalize((uint8_t)(color >> 24), 8, _alpha.depth());
  18. uint64_t r = normalize((uint8_t)(color >> 16), 8, _red.depth());
  19. uint64_t g = normalize((uint8_t)(color >> 8), 8, _green.depth());
  20. uint64_t b = normalize((uint8_t)(color >> 0), 8, _blue.depth());
  21. write(dp, (a << _alpha.shift()) | (r << _red.shift()) | (g << _green.shift()) | (b << _blue.shift()));
  22. dp += stride();
  23. }
  24. }
  25. return true;
  26. }
  27. inline auto image::loadPNG(const string& filename) -> bool {
  28. if(!file::exists(filename)) return false;
  29. auto buffer = file::read(filename);
  30. return loadPNG(buffer.data(), buffer.size());
  31. }
  32. inline auto image::loadPNG(const uint8_t* pngData, uint pngSize) -> bool {
  33. Decode::PNG source;
  34. if(!source.load(pngData, pngSize)) return false;
  35. allocate(source.info.width, source.info.height);
  36. const uint8_t* sp = source.data;
  37. uint8_t* dp = _data;
  38. auto decode = [&]() -> uint64_t {
  39. uint64_t p, r, g, b, a;
  40. switch(source.info.colorType) {
  41. case 0: //L
  42. r = g = b = source.readbits(sp);
  43. a = (1 << source.info.bitDepth) - 1;
  44. break;
  45. case 2: //R,G,B
  46. r = source.readbits(sp);
  47. g = source.readbits(sp);
  48. b = source.readbits(sp);
  49. a = (1 << source.info.bitDepth) - 1;
  50. break;
  51. case 3: //P
  52. p = source.readbits(sp);
  53. r = source.info.palette[p][0];
  54. g = source.info.palette[p][1];
  55. b = source.info.palette[p][2];
  56. a = (1 << source.info.bitDepth) - 1;
  57. break;
  58. case 4: //L,A
  59. r = g = b = source.readbits(sp);
  60. a = source.readbits(sp);
  61. break;
  62. case 6: //R,G,B,A
  63. r = source.readbits(sp);
  64. g = source.readbits(sp);
  65. b = source.readbits(sp);
  66. a = source.readbits(sp);
  67. break;
  68. }
  69. a = normalize(a, source.info.bitDepth, _alpha.depth());
  70. r = normalize(r, source.info.bitDepth, _red.depth());
  71. g = normalize(g, source.info.bitDepth, _green.depth());
  72. b = normalize(b, source.info.bitDepth, _blue.depth());
  73. return (a << _alpha.shift()) | (r << _red.shift()) | (g << _green.shift()) | (b << _blue.shift());
  74. };
  75. for(uint y = 0; y < _height; y++) {
  76. for(uint x = 0; x < _width; x++) {
  77. write(dp, decode());
  78. dp += stride();
  79. }
  80. }
  81. return true;
  82. }
  83. }