1 /**
2  * Copyright (c) 2006-2016 LOVE Development Team
3  *
4  * This software is provided 'as-is', without any express or implied
5  * warranty.  In no event will the authors be held liable for any damages
6  * arising from the use of this software.
7  *
8  * Permission is granted to anyone to use this software for any purpose,
9  * including commercial applications, and to alter it and redistribute it
10  * freely, subject to the following restrictions:
11  *
12  * 1. The origin of this software must not be misrepresented; you must not
13  *    claim that you wrote the original software. If you use this software
14  *    in a product, an acknowledgment in the product documentation would be
15  *    appreciated but is not required.
16  * 2. Altered source versions must be plainly marked as such, and must not be
17  *    misrepresented as being the original software.
18  * 3. This notice may not be removed or altered from any source distribution.
19  **/
20 
21 #include "wrap_Image.h"
22 
23 #include "common/Data.h"
24 #include "common/StringMap.h"
25 
26 #include "magpie/Image.h"
27 
28 #include "filesystem/wrap_Filesystem.h"
29 
30 namespace love
31 {
32 namespace image
33 {
34 
35 #define instance() (Module::getInstance<Image>(Module::M_IMAGE))
36 
w_newImageData(lua_State * L)37 int w_newImageData(lua_State *L)
38 {
39 	// Case 1: Integers.
40 	if (lua_isnumber(L, 1))
41 	{
42 		int w = (int) luaL_checknumber(L, 1);
43 		int h = (int) luaL_checknumber(L, 2);
44 		if (w <= 0 || h <= 0)
45 			return luaL_error(L, "Invalid image size.");
46 
47 		size_t numbytes = 0;
48 		const char *bytes = nullptr;
49 
50 		if (!lua_isnoneornil(L, 3))
51 			bytes = luaL_checklstring(L, 3, &numbytes);
52 
53 		ImageData *t = nullptr;
54 		luax_catchexcept(L, [&](){ t = instance()->newImageData(w, h); });
55 
56 		if (bytes)
57 		{
58 			if (numbytes != t->getSize())
59 			{
60 				t->release();
61 				return luaL_error(L, "The size of the raw byte string must match the ImageData's actual size in bytes.");
62 			}
63 
64 			memcpy(t->getData(), bytes, t->getSize());
65 		}
66 
67 		luax_pushtype(L, IMAGE_IMAGE_DATA_ID, t);
68 		t->release();
69 		return 1;
70 	}
71 	else if (filesystem::luax_cangetfiledata(L, 1)) // Case 2: File(Data).
72 	{
73 		filesystem::FileData *data = love::filesystem::luax_getfiledata(L, 1);
74 
75 		ImageData *t = nullptr;
76 		luax_catchexcept(L,
77 			[&]() { t = instance()->newImageData(data); },
78 			[&](bool) { data->release(); }
79 		);
80 
81 		luax_pushtype(L, IMAGE_IMAGE_DATA_ID, t);
82 		t->release();
83 		return 1;
84 	}
85 	else
86 	{
87 		return luax_typerror(L, 1, "value");
88 	}
89 }
90 
w_newCompressedData(lua_State * L)91 int w_newCompressedData(lua_State *L)
92 {
93 	love::filesystem::FileData *data = love::filesystem::luax_getfiledata(L, 1);
94 
95 	CompressedImageData *t = nullptr;
96 	luax_catchexcept(L,
97 		[&]() { t = instance()->newCompressedData(data); },
98 		[&](bool) { data->release(); }
99 	);
100 
101 	luax_pushtype(L, IMAGE_COMPRESSED_IMAGE_DATA_ID, t);
102 	t->release();
103 	return 1;
104 }
105 
w_isCompressed(lua_State * L)106 int w_isCompressed(lua_State *L)
107 {
108 	love::filesystem::FileData *data = love::filesystem::luax_getfiledata(L, 1);
109 	bool compressed = instance()->isCompressed(data);
110 	data->release();
111 
112 	luax_pushboolean(L, compressed);
113 	return 1;
114 }
115 
116 // List of functions to wrap.
117 static const luaL_Reg functions[] =
118 {
119 	{ "newImageData",  w_newImageData },
120 	{ "newCompressedData", w_newCompressedData },
121 	{ "isCompressed", w_isCompressed },
122 	{ 0, 0 }
123 };
124 
125 static const lua_CFunction types[] =
126 {
127 	luaopen_imagedata,
128 	luaopen_compressedimagedata,
129 	0
130 };
131 
luaopen_love_image(lua_State * L)132 extern "C" int luaopen_love_image(lua_State *L)
133 {
134 	Image *instance = instance();
135 	if (instance == nullptr)
136 	{
137 		luax_catchexcept(L, [&](){ instance = new love::image::magpie::Image(); });
138 	}
139 	else
140 		instance->retain();
141 
142 	WrappedModule w;
143 	w.module = instance;
144 	w.name = "image";
145 	w.type = MODULE_IMAGE_ID;
146 	w.functions = functions;
147 	w.types = types;
148 
149 	return luax_register_module(L, w);
150 }
151 
152 } // image
153 } // love
154