Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

212 строки
4.7 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://www.wtfpl.net/ for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #include "core.h"
  14. #include "image-private.h"
  15. using namespace std;
  16. namespace lol
  17. {
  18. /* HACK: We cannot make this an ImageCodec member function, because the
  19. * REGISTER_IMAGE_CODEC macro forward-declares free functions from
  20. * the "lol" namespace. An apparent bug in Visual Studio's compiler
  21. * makes it think these functions are actually in the top-level
  22. * namespace when the forward declaration is in a class member function.
  23. * To avoid the problem, we make the forward declaration in a free
  24. * function.
  25. * The bug was reported to Microsoft and fixed by them, but the fix
  26. * is not yet available.
  27. * https://connect.microsoft.com/VisualStudio/feedback/details/730878/ */
  28. static bool RegisterAllCodecs(Array<ImageCodec *> &codeclist)
  29. {
  30. #if defined __ANDROID__
  31. REGISTER_IMAGE_CODEC(AndroidImageCodec)
  32. #endif
  33. REGISTER_IMAGE_CODEC(DummyImageCodec)
  34. #if defined USE_GDIPLUS
  35. REGISTER_IMAGE_CODEC(GdiPlusImageCodec)
  36. #endif
  37. #if defined __APPLE__ && defined __MACH__ && defined __arm__
  38. REGISTER_IMAGE_CODEC(IosImageCodec)
  39. #endif
  40. #if defined __CELLOS_LV2__
  41. REGISTER_IMAGE_CODEC(Ps3ImageCodec)
  42. #endif
  43. #if defined USE_SDL_IMAGE
  44. REGISTER_IMAGE_CODEC(SdlImageCodec)
  45. #endif
  46. REGISTER_IMAGE_CODEC(ZedImageCodec)
  47. REGISTER_IMAGE_CODEC(ZedPaletteImageCodec)
  48. return true;
  49. }
  50. /*
  51. * Our static image loader
  52. */
  53. static class ImageBank
  54. {
  55. public:
  56. ImageBank();
  57. bool Load(Image *image, char const *path);
  58. bool Save(Image *image, char const *path);
  59. private:
  60. Array<ImageCodec *> m_codecs;
  61. Map<String, Image *> m_images;
  62. }
  63. g_image_bank;
  64. ImageBank::ImageBank()
  65. {
  66. RegisterAllCodecs(m_codecs);
  67. }
  68. bool ImageBank::Load(Image *image, char const *path)
  69. {
  70. /* FIXME: priority is ignored */
  71. for (auto codec : m_codecs)
  72. if (codec->Load(image, path))
  73. return true;
  74. return false;
  75. }
  76. bool ImageBank::Save(Image *image, char const *path)
  77. {
  78. /* FIXME: priority is ignored */
  79. for (auto codec : m_codecs)
  80. if (codec->Save(image, path))
  81. return true;
  82. return false;
  83. }
  84. /*
  85. * Public Image class
  86. */
  87. Image::Image()
  88. : m_data(new ImageData())
  89. {
  90. }
  91. Image::Image(char const *path)
  92. : m_data(new ImageData())
  93. {
  94. Load(path);
  95. }
  96. Image::Image(ivec2 size)
  97. : m_data(new ImageData())
  98. {
  99. SetSize(size);
  100. }
  101. Image::~Image()
  102. {
  103. delete m_data;
  104. }
  105. bool Image::Load(char const *path)
  106. {
  107. return g_image_bank.Load(this, path);
  108. }
  109. bool Image::Save(char const *path)
  110. {
  111. return g_image_bank.Save(this, path);
  112. }
  113. ivec2 Image::GetSize() const
  114. {
  115. return m_data->m_size;
  116. }
  117. void Image::SetSize(ivec2 size)
  118. {
  119. if (m_data->m_size != size)
  120. {
  121. /* FIXME: delete data or resize it */
  122. if (m_data->m_format != PixelFormat::Unknown)
  123. {
  124. m_data->m_pixels.Remove((int)m_data->m_format);
  125. }
  126. }
  127. m_data->m_size = size;
  128. /* FIXME: don’t do this! */
  129. if (m_data->m_format != PixelFormat::Unknown)
  130. {
  131. Lock<PixelFormat::RGBA_8>();
  132. Unlock();
  133. }
  134. }
  135. PixelFormat Image::GetFormat() const
  136. {
  137. return m_data->m_format;
  138. }
  139. /* The Lock() method and its explicit specialisations */
  140. template<PixelFormat T>
  141. typename PixelType<T>::type *Image::Lock()
  142. {
  143. /* TODO: convert data if this doesn’t match */
  144. ASSERT(m_data->m_format == T || m_data->m_format == PixelFormat::Unknown);
  145. m_data->m_format = (PixelFormat)T;
  146. if (!m_data->m_pixels.HasKey((int)T))
  147. {
  148. m_data->m_pixels[(int)T] =
  149. new typename PixelType<T>::type[m_data->m_size.x * m_data->m_size.y];
  150. }
  151. return (typename PixelType<T>::type *)m_data->m_pixels[(int)T];
  152. }
  153. template PixelType<PixelFormat::Y_8>::type *
  154. Image::Lock<PixelFormat::Y_8>();
  155. template PixelType<PixelFormat::RGB_8>::type *
  156. Image::Lock<PixelFormat::RGB_8>();
  157. template PixelType<PixelFormat::RGBA_8>::type *
  158. Image::Lock<PixelFormat::RGBA_8>();
  159. /* Special case for the "any" format */
  160. template<>
  161. void *Image::Lock<PixelFormat::Unknown>()
  162. {
  163. ASSERT(m_data->m_format != PixelFormat::Unknown);
  164. return m_data->m_pixels[(int)m_data->m_format];
  165. }
  166. void Image::Unlock()
  167. {
  168. /* TODO: ensure we are actually unlocking something we locked */
  169. ASSERT(m_data->m_pixels.HasKey((int)m_data->m_format));
  170. }
  171. bool Image::RetrieveTiles(Array<ivec2, ivec2>& tiles) const
  172. {
  173. /* TODO: re-implement this */
  174. //return m_data->m_codecdata->RetrieveTiles(tiles);
  175. return false;
  176. }
  177. } /* namespace lol */