No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 

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