|
1096
|
1 /**
|
|
|
2 * Copyright (c) 2006-2012 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 "ImageData.h"
|
|
|
22
|
|
|
23 using love::thread::Lock;
|
|
|
24
|
|
|
25 namespace love
|
|
|
26 {
|
|
|
27 namespace image
|
|
|
28 {
|
|
|
29
|
|
|
30 void *ImageData::getData() const
|
|
|
31 {
|
|
|
32 return data;
|
|
|
33 }
|
|
|
34
|
|
|
35 int ImageData::getSize() const
|
|
|
36 {
|
|
|
37 return getWidth()*getHeight()*sizeof(pixel);
|
|
|
38 }
|
|
|
39
|
|
|
40 int ImageData::getWidth() const
|
|
|
41 {
|
|
|
42 return width;
|
|
|
43 }
|
|
|
44
|
|
|
45 int ImageData::getHeight() const
|
|
|
46 {
|
|
|
47 return height;
|
|
|
48 }
|
|
|
49
|
|
|
50 bool ImageData::inside(int x, int y) const
|
|
|
51 {
|
|
|
52 return x >= 0 && x < getWidth() && y >= 0 && y < getHeight();
|
|
|
53 }
|
|
|
54
|
|
|
55 void ImageData::setPixel(int x, int y, pixel c)
|
|
|
56 {
|
|
|
57 if (!inside(x, y))
|
|
|
58 throw love::Exception("Attempt to set out-of-range pixel!");
|
|
|
59
|
|
|
60 Lock lock(mutex);
|
|
|
61
|
|
|
62 pixel *pixels = (pixel *)getData();
|
|
|
63 pixels[y*getWidth()+x] = c;
|
|
|
64 }
|
|
|
65
|
|
|
66 pixel ImageData::getPixel(int x, int y)
|
|
|
67 {
|
|
|
68 if (!inside(x, y))
|
|
|
69 throw love::Exception("Attempt to get out-of-range pixel!");
|
|
|
70
|
|
|
71 Lock lock(mutex);
|
|
|
72
|
|
|
73 pixel *pixels = (pixel *)getData();
|
|
|
74 return pixels[y*getWidth()+x];
|
|
|
75 }
|
|
|
76
|
|
|
77 void ImageData::paste(ImageData *src, int dx, int dy, int sx, int sy, int sw, int sh)
|
|
|
78 {
|
|
|
79 Lock lock2(src->mutex);
|
|
|
80 Lock lock1(mutex);
|
|
|
81
|
|
|
82 pixel *s = (pixel *)src->getData();
|
|
|
83 pixel *d = (pixel *)getData();
|
|
|
84
|
|
|
85 // Check bounds; if the data ends up completely out of bounds, get out early.
|
|
|
86 if (sx >= src->getWidth() || sx + sw < 0 || sy >= src->getHeight() || sy + sh < 0
|
|
|
87 || dx >= getWidth() || dx + sw < 0 || dy >= getHeight() || dy + sh < 0)
|
|
|
88 return;
|
|
|
89
|
|
|
90 // Normalize values to the inside of both images.
|
|
|
91 if (dx < 0)
|
|
|
92 {
|
|
|
93 sw += dx;
|
|
|
94 sx -= dx;
|
|
|
95 dx = 0;
|
|
|
96 }
|
|
|
97 if (dy < 0)
|
|
|
98 {
|
|
|
99 sh += dy;
|
|
|
100 sy -= dy;
|
|
|
101 dy = 0;
|
|
|
102 }
|
|
|
103 if (sx < 0)
|
|
|
104 {
|
|
|
105 sw += sx;
|
|
|
106 dx -= sx;
|
|
|
107 sx = 0;
|
|
|
108 }
|
|
|
109 if (sy < 0)
|
|
|
110 {
|
|
|
111 sh += sy;
|
|
|
112 dy -= sy;
|
|
|
113 sy = 0;
|
|
|
114 }
|
|
|
115 if (dx + sw > getWidth())
|
|
|
116 {
|
|
|
117 sw = getWidth() - dx;
|
|
|
118 }
|
|
|
119 if (dy + sh > getHeight())
|
|
|
120 {
|
|
|
121 sh = getHeight() - dy;
|
|
|
122 }
|
|
|
123 if (sx + sw > src->getWidth())
|
|
|
124 {
|
|
|
125 sw = src->getWidth() - sx;
|
|
|
126 }
|
|
|
127 if (sy + sh > src->getHeight())
|
|
|
128 {
|
|
|
129 sh = src->getHeight() - sy;
|
|
|
130 }
|
|
|
131
|
|
|
132 // If the dimensions match up, copy the entire memory stream in one go
|
|
|
133 if (sw == getWidth() && getWidth() == src->getWidth()
|
|
|
134 && sh == getHeight() && getHeight() == src->getHeight())
|
|
|
135 memcpy(d, s, sizeof(pixel) * sw * sh);
|
|
|
136 else if (sw > 0 && sh > 0) // Otherwise, copy each row individually
|
|
|
137 {
|
|
|
138 for (int i = 0; i < sh; i++)
|
|
|
139 {
|
|
|
140 memcpy(d + dx + (i + dy) * getWidth(), s + sx + (i + sy) * src->getWidth(), sizeof(pixel) * sw);
|
|
|
141 }
|
|
|
142 }
|
|
|
143 }
|
|
|
144
|
|
|
145 bool ImageData::getConstant(const char *in, ImageData::Format &out)
|
|
|
146 {
|
|
|
147 return formats.find(in, out);
|
|
|
148 }
|
|
|
149
|
|
|
150 bool ImageData::getConstant(ImageData::Format in, const char *&out)
|
|
|
151 {
|
|
|
152 return formats.find(in, out);
|
|
|
153 }
|
|
|
154
|
|
|
155 StringMap<ImageData::Format, ImageData::FORMAT_MAX_ENUM>::Entry ImageData::formatEntries[] =
|
|
|
156 {
|
|
|
157 {"tga", ImageData::FORMAT_TGA},
|
|
|
158 {"bmp", ImageData::FORMAT_BMP},
|
|
|
159 {"gif", ImageData::FORMAT_GIF},
|
|
|
160 {"jpg", ImageData::FORMAT_JPG},
|
|
|
161 {"png", ImageData::FORMAT_PNG},
|
|
|
162 };
|
|
|
163
|
|
|
164 StringMap<ImageData::Format, ImageData::FORMAT_MAX_ENUM> ImageData::formats(ImageData::formatEntries, sizeof(ImageData::formatEntries));
|
|
|
165
|
|
|
166 } // image
|
|
|
167 } // love
|