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.
 
 
 

162 lines
3.3 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright © 2010—2020 Sam Hocevar <sam@hocevar.net>
  5. //
  6. // Lol Engine is free software. It comes without any warranty, to
  7. // the extent permitted by applicable law. You can redistribute it
  8. // and/or modify it under the terms of the Do What the Fuck You Want
  9. // to Public License, Version 2, as published by the WTFPL Task Force.
  10. // See http://www.wtfpl.net/ for more details.
  11. //
  12. #pragma once
  13. //
  14. // The image class
  15. // ———————————————
  16. //
  17. #include "pixel.h"
  18. #include <lol/narray> // lol::array2d
  19. #include <lol/vector> // lol::ivec2
  20. #include <memory> // std::shared_ptr
  21. #include <string> // std::string
  22. #include <unordered_set> // std::unordered_set
  23. namespace lol
  24. {
  25. template<pixel::format T> class image_t;
  26. using image = image_t<pixel::format::rgba_u8>;
  27. class image_data
  28. {
  29. virtual ~image_data() {}
  30. };
  31. // Codec class for loading and saving images
  32. class image_codec
  33. {
  34. public:
  35. virtual bool test(std::string const &path) = 0;
  36. virtual bool load(std::string const &path, image &im) = 0;
  37. virtual bool save(std::string const &path, image &im) = 0;
  38. static void add(std::shared_ptr<image_codec> codec)
  39. {
  40. codecs().insert(codec);
  41. }
  42. static std::unordered_set<std::shared_ptr<class image_codec>> codecs()
  43. {
  44. static std::unordered_set<std::shared_ptr<image_codec>> instance;
  45. return instance;
  46. };
  47. };
  48. // The generic image class
  49. template<pixel::format T> class image_t
  50. {
  51. public:
  52. using pixel_type = typename pixel::type<T>::value;
  53. image_t<T>() = default;
  54. image_t<T>(int width, int height)
  55. : m_pixels(width, height)
  56. {}
  57. image_t<T>(ivec2 size)
  58. : m_pixels(size)
  59. {}
  60. // Build from another image
  61. template<pixel::format U>
  62. image_t<T>(image_t<U> const &other)
  63. : m_pixels(other.size)
  64. {
  65. auto src = other.pixels();
  66. auto dst = pixels();
  67. for (size_t i = 0; i < src.size(); ++i)
  68. dst[i] = pixel::convert<U, T>(src[i]);
  69. }
  70. // Load and save image
  71. bool load(std::string const &path)
  72. {
  73. for (auto &codec : image_codec::codecs())
  74. if (codec->load(path, *this))
  75. return true;
  76. return false;
  77. }
  78. bool save(std::string const &path)
  79. {
  80. for (auto &codec : image_codec::codecs())
  81. if (codec->save(path, *this))
  82. return true;
  83. return false;
  84. }
  85. // Pixel array properties
  86. ivec2 size() const { return m_pixels.sizes(); }
  87. size_t bytes() const { return m_pixels.bytes(); }
  88. // Direct access to pixels
  89. span2d<pixel_type> pixels()
  90. {
  91. return m_pixels.span();
  92. }
  93. span2d<pixel_type const> pixels() const
  94. {
  95. return m_pixels.span();
  96. }
  97. private:
  98. array2d<pixel_type> m_pixels;
  99. std::shared_ptr<image_data> m_data;
  100. };
  101. using image = image_t<pixel::format::rgba_u8>;
  102. enum class WrapMode : uint8_t
  103. {
  104. Clamp,
  105. Repeat,
  106. };
  107. enum class ScanMode : uint8_t
  108. {
  109. Raster,
  110. Serpentine,
  111. };
  112. enum class ResampleAlgorithm : uint8_t
  113. {
  114. Bicubic,
  115. Bresenham,
  116. };
  117. enum class EdiffAlgorithm : uint8_t
  118. {
  119. FloydSteinberg,
  120. JaJuNi,
  121. Atkinson,
  122. Fan,
  123. ShiauFan,
  124. ShiauFan2,
  125. Stucki,
  126. Burkes,
  127. Sierra,
  128. Sierra2,
  129. Lite,
  130. };
  131. } // namespace lol