1 module gfm.sdl2.sdlimage;
2 
3 import std.string;
4 
5 import derelict.util.exception,
6        derelict.sdl2.sdl,
7        derelict.sdl2.image;
8 
9 import std.logger;
10 
11 import gfm.core.text,
12        gfm.sdl2.sdl, 
13        gfm.sdl2.surface;
14 
15 /// Load images using SDL_image, a SDL companion library able to load various image formats.
16 final class SDLImage
17 {
18     public
19     {
20         /// Loads the SDL_image library.
21         /// SDL must be already initialized.
22         /// Throws: $(D SDL2Exception) on error.
23         this(SDL2 sdl2, int flags = IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF | IMG_INIT_WEBP)
24         {
25             _sdl2 = sdl2; // force loading of SDL first
26             _logger = sdl2._logger;
27             _SDLImageInitialized = false;
28             
29             try
30             {
31                 DerelictSDL2Image.load();
32             }
33             catch(DerelictException e)
34             {
35                 throw new SDL2Exception(e.msg);
36             }
37 
38             int inited = IMG_Init(flags);
39 
40             if ((inited & IMG_INIT_JPG) != 0)
41                 _logger.infof("SDL_image: JPG loading enabled.");
42 
43             if ((inited & IMG_INIT_PNG) != 0)
44                 _logger.infof("SDL_image: PNG loading enabled.");
45 
46             if ((inited & IMG_INIT_TIF) != 0)
47                 _logger.infof("SDL_image: TIF loading enabled.");
48 
49             if ((inited & IMG_INIT_WEBP) != 0)
50                 _logger.infof("SDL_image: WebP loading enabled.");
51 
52             _SDLImageInitialized = true;
53 
54         }
55 
56         ~this()
57         {
58             close();
59         }
60 
61         /// Releases the SDL resource. 
62         void close()
63         {
64             if (_SDLImageInitialized)
65             {
66                 _SDLImageInitialized = false;
67                 IMG_Quit();
68             }
69 
70             DerelictSDL2Image.unload();
71         }
72 
73         /// Load an image.
74         /// Returns: A SDL surface with loaded content.
75         /// Throws: $(D SDL2Exception) on error.
76         SDL2Surface load(string path)
77         {
78             immutable(char)* pathz = toStringz(path);
79             SDL_Surface* surface = IMG_Load(pathz);
80             if (surface is null)
81                 throwSDL2ImageException("IMG_Load");
82 
83             return new SDL2Surface(_sdl2, surface, SDL2Surface.Owned.YES);
84         }
85     }
86 
87     private
88     {
89         Logger _logger;
90         SDL2 _sdl2;
91         bool _SDLImageInitialized;
92 
93         void throwSDL2ImageException(string callThatFailed)
94         {
95             string message = format("%s failed: %s", callThatFailed, getErrorString());
96             throw new SDL2Exception(message);
97         }
98 
99         string getErrorString()
100         {
101             return sanitizeUTF8(IMG_GetError(), _logger, "SDL_Image error string");
102         }
103     }
104 }