1 /*
2  *******************************************************************************************
3  * Dgame (a D game framework) - Copyright (c) Randy Schütt
4  * 
5  * This software is provided 'as-is', without any express or implied warranty.
6  * In no event will the authors be held liable for any damages arising from
7  * the use of this software.
8  * 
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  * 
13  * 1. The origin of this software must not be misrepresented; you must not claim
14  *    that you wrote the original software. If you use this software in a product,
15  *    an acknowledgment in the product documentation would be appreciated but is
16  *    not required.
17  * 
18  * 2. Altered source versions must be plainly marked as such, and must not be
19  *    misrepresented as being the original software.
20  * 
21  * 3. This notice may not be removed or altered from any source distribution.
22  *******************************************************************************************
23  */
24 module Dgame.Graphics.Image;
25 
26 private {
27 	import Dgame.Graphics.Surface;
28 	import Dgame.Graphics.Color;
29 	import Dgame.Math.Rect;
30 
31 	import Dgame.Internal.Unique;
32 }
33 
34 public import Dgame.Graphics.Texture;
35 
36 /**
37  * Image is the class for loading and manipulating images.
38  * It extends Texture of the feature to load images by filename 
39  * and save the (current) image into a file.
40  *
41  * Author: rschuett
42  */
43 class Image : Texture {
44 final:
45 	/**
46 	 * CTor
47 	 */
48 	this() {
49 		super();
50 	}
51 	
52 	/**
53 	 * CTor
54 	 */
55 	this(string filename, Texture.Format t_fmt = Texture.Format.None) {
56 		this.loadFromFile(filename, t_fmt);
57 	}
58 	
59 	/**
60 	 * CTor
61 	 */
62 	this(ref const Texture tex, Texture.Format t_fmt = Texture.Format.None) {
63 		super(tex, t_fmt);
64 	}
65 	
66 	/**
67 	 * CTor
68 	 */
69 	this(ref Surface srfc, Texture.Format t_fmt = Texture.Format.None) {
70 		if (t_fmt == Texture.Format.None
71 		    && !srfc.isMask(Surface.Mask.Red, 0x000000ff))
72 		{
73 			t_fmt = srfc.bits == 24 ? Texture.Format.BGR : Texture.Format.BGRA;
74 		}
75 		
76 		super.loadFromMemory(srfc.pixels, srfc.width, srfc.height, srfc.bits, t_fmt);
77 	}
78 	
79 	/**
80 	 * Load the image from filename.
81 	 */
82 	void loadFromFile(string filename, Texture.Format t_fmt = Texture.Format.None) {
83 		Surface img = Surface(filename);
84 		enforce(img.pixels !is null, "Cannot load image with no memory.");
85 
86 		super.loadFromMemory(img.pixels, img.width, img.height, img.bits, t_fmt); 
87 	}
88 	
89 	/**
90 	 * Load the image from filename.
91 	 */
92 	void loadFromFile(string filename, const Color* col = null, Texture.Format t_fmt = Texture.Format.None) {
93 		Surface img = Surface(filename);
94 		enforce(img.pixels !is null, "Cannot load image with no memory.");
95 
96 		if (col !is null)
97 			img.setColorkey(*col);
98 
99 		super.loadFromMemory(img.pixels, img.width, img.height, img.bits, t_fmt); 
100 	}
101 	
102 	/**
103 	 * Save the (current) image into filename.
104 	 */
105 	void saveToFile(string filename) {
106 		const size_t msize = super.width * super.height * (super.depth / 8);
107 		unique_ptr!(void) mem = allocate_unique!(void)(msize);
108 
109 		void[] memory = super.getMemory(mem[0 .. msize]);
110 		enforce(memory !is null, "Cannot save image with no memory.");
111 		
112 		Surface img = Surface.make(&memory[0], super.width, super.height, super.depth);
113 		img.saveToFile(filename);
114 	}
115 	
116 	/**
117 	 * Alias for subTexture.
118 	 */
119 	alias subImage = subTexture;
120 }
121