Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

129 linhas
2.8 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. #if defined USE_SDL_IMAGE
  14. #if defined HAVE_SDL_SDL_H
  15. # include <SDL/SDL.h>
  16. #else
  17. # include <SDL.h>
  18. #endif
  19. #if defined HAVE_SDL_SDL_IMAGE_H
  20. # include <SDL/SDL_image.h>
  21. #else
  22. # include <SDL_image.h>
  23. #endif
  24. #include "core.h"
  25. #include "../../image/image-private.h"
  26. using namespace std;
  27. namespace lol
  28. {
  29. /*
  30. * Image implementation class
  31. */
  32. class SdlImageCodec : public ImageCodec
  33. {
  34. public:
  35. virtual bool Load(Image *image, char const *path);
  36. virtual bool Save(Image *image, char const *path);
  37. static SDL_Surface *Create32BppSurface(ivec2 size);
  38. };
  39. DECLARE_IMAGE_CODEC(SdlImageCodec, 50)
  40. bool SdlImageCodec::Load(Image *image, char const *path)
  41. {
  42. SDL_Surface *surface = nullptr;
  43. array<String> pathlist = System::GetPathList(path);
  44. for (int i = 0; i < pathlist.Count(); i++)
  45. {
  46. surface = IMG_Load(pathlist[i].C());
  47. if (surface)
  48. break;
  49. }
  50. if (!surface)
  51. {
  52. #if !LOL_BUILD_RELEASE
  53. Log::Error("could not load image %s\n", path);
  54. #endif
  55. return false;
  56. }
  57. ivec2 size(surface->w, surface->h);
  58. if (surface->format->BytesPerPixel != 4)
  59. {
  60. SDL_Surface *tmp = Create32BppSurface(size);
  61. SDL_BlitSurface(surface, nullptr, tmp, nullptr);
  62. SDL_FreeSurface(surface);
  63. surface = tmp;
  64. }
  65. image->SetSize(size);
  66. u8vec4 *data = image->Lock<PixelFormat::RGBA_8>();
  67. memcpy(data, surface->pixels, 4 * size.x * size.y);
  68. image->Unlock(data);
  69. SDL_FreeSurface(surface);
  70. return true;
  71. }
  72. bool SdlImageCodec::Save(Image *image, char const *path)
  73. {
  74. ivec2 size = image->GetSize();
  75. SDL_Surface *surface = Create32BppSurface(size);
  76. u8vec4 *data = image->Lock<PixelFormat::RGBA_8>();
  77. memcpy(surface->pixels, data, 4 * size.x * size.y);
  78. image->Unlock(data);
  79. int ret = SDL_SaveBMP(surface, path);
  80. SDL_FreeSurface(surface);
  81. return ret == 0;
  82. }
  83. SDL_Surface *SdlImageCodec::Create32BppSurface(ivec2 size)
  84. {
  85. uint32_t rmask, gmask, bmask, amask;
  86. #if SDL_BYTEORDER == SDL_BIG_ENDIAN
  87. rmask = 0xff000000;
  88. gmask = 0x00ff0000;
  89. bmask = 0x0000ff00;
  90. amask = 0x000000ff;
  91. #else
  92. rmask = 0x000000ff;
  93. gmask = 0x0000ff00;
  94. bmask = 0x00ff0000;
  95. amask = 0xff000000;
  96. #endif
  97. return SDL_CreateRGBSurface(SDL_SWSURFACE, size.x, size.y, 32,
  98. rmask, gmask, bmask, amask);
  99. }
  100. } /* namespace lol */
  101. #endif /* defined USE_SDL_IMAGE */