1 /*************************************************************************/
2 /*  image.cpp                                                            */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
10 /*                                                                       */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the       */
13 /* "Software"), to deal in the Software without restriction, including   */
14 /* without limitation the rights to use, copy, modify, merge, publish,   */
15 /* distribute, sublicense, and/or sell copies of the Software, and to    */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions:                                             */
18 /*                                                                       */
19 /* The above copyright notice and this permission notice shall be        */
20 /* included in all copies or substantial portions of the Software.       */
21 /*                                                                       */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
29 /*************************************************************************/
30 
31 #include "image.h"
32 
33 #include "core/error_macros.h"
34 #include "core/hash_map.h"
35 #include "core/io/image_loader.h"
36 #include "core/io/resource_loader.h"
37 #include "core/math/math_funcs.h"
38 #include "core/os/copymem.h"
39 #include "core/print_string.h"
40 
41 #include "thirdparty/misc/hq2x.h"
42 
43 #include <stdio.h>
44 
45 const char *Image::format_names[Image::FORMAT_MAX] = {
46 	"Lum8", //luminance
47 	"LumAlpha8", //luminance-alpha
48 	"Red8",
49 	"RedGreen",
50 	"RGB8",
51 	"RGBA8",
52 	"RGBA4444",
53 	"RGBA5551",
54 	"RFloat", //float
55 	"RGFloat",
56 	"RGBFloat",
57 	"RGBAFloat",
58 	"RHalf", //half float
59 	"RGHalf",
60 	"RGBHalf",
61 	"RGBAHalf",
62 	"RGBE9995",
63 	"DXT1 RGB8", //s3tc
64 	"DXT3 RGBA8",
65 	"DXT5 RGBA8",
66 	"RGTC Red8",
67 	"RGTC RedGreen8",
68 	"BPTC_RGBA",
69 	"BPTC_RGBF",
70 	"BPTC_RGBFU",
71 	"PVRTC2", //pvrtc
72 	"PVRTC2A",
73 	"PVRTC4",
74 	"PVRTC4A",
75 	"ETC", //etc1
76 	"ETC2_R11", //etc2
77 	"ETC2_R11S", //signed", NOT srgb.
78 	"ETC2_RG11",
79 	"ETC2_RG11S",
80 	"ETC2_RGB8",
81 	"ETC2_RGBA8",
82 	"ETC2_RGB8A1",
83 
84 };
85 
86 SavePNGFunc Image::save_png_func = NULL;
87 SaveEXRFunc Image::save_exr_func = NULL;
88 
89 SavePNGBufferFunc Image::save_png_buffer_func = NULL;
90 
_put_pixelb(int p_x,int p_y,uint32_t p_pixelsize,uint8_t * p_data,const uint8_t * p_pixel)91 void Image::_put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_data, const uint8_t *p_pixel) {
92 
93 	uint32_t ofs = (p_y * width + p_x) * p_pixelsize;
94 
95 	for (uint32_t i = 0; i < p_pixelsize; i++) {
96 		p_data[ofs + i] = p_pixel[i];
97 	}
98 }
99 
_get_pixelb(int p_x,int p_y,uint32_t p_pixelsize,const uint8_t * p_data,uint8_t * p_pixel)100 void Image::_get_pixelb(int p_x, int p_y, uint32_t p_pixelsize, const uint8_t *p_data, uint8_t *p_pixel) {
101 
102 	uint32_t ofs = (p_y * width + p_x) * p_pixelsize;
103 
104 	for (uint32_t i = 0; i < p_pixelsize; i++) {
105 		p_pixel[i] = p_data[ofs + i];
106 	}
107 }
108 
get_format_pixel_size(Format p_format)109 int Image::get_format_pixel_size(Format p_format) {
110 
111 	switch (p_format) {
112 		case FORMAT_L8:
113 			return 1; //luminance
114 		case FORMAT_LA8:
115 			return 2; //luminance-alpha
116 		case FORMAT_R8: return 1;
117 		case FORMAT_RG8: return 2;
118 		case FORMAT_RGB8: return 3;
119 		case FORMAT_RGBA8: return 4;
120 		case FORMAT_RGBA4444: return 2;
121 		case FORMAT_RGBA5551: return 2;
122 		case FORMAT_RF:
123 			return 4; //float
124 		case FORMAT_RGF: return 8;
125 		case FORMAT_RGBF: return 12;
126 		case FORMAT_RGBAF: return 16;
127 		case FORMAT_RH:
128 			return 2; //half float
129 		case FORMAT_RGH: return 4;
130 		case FORMAT_RGBH: return 6;
131 		case FORMAT_RGBAH: return 8;
132 		case FORMAT_RGBE9995: return 4;
133 		case FORMAT_DXT1:
134 			return 1; //s3tc bc1
135 		case FORMAT_DXT3:
136 			return 1; //bc2
137 		case FORMAT_DXT5:
138 			return 1; //bc3
139 		case FORMAT_RGTC_R:
140 			return 1; //bc4
141 		case FORMAT_RGTC_RG:
142 			return 1; //bc5
143 		case FORMAT_BPTC_RGBA:
144 			return 1; //btpc bc6h
145 		case FORMAT_BPTC_RGBF:
146 			return 1; //float /
147 		case FORMAT_BPTC_RGBFU:
148 			return 1; //unsigned float
149 		case FORMAT_PVRTC2:
150 			return 1; //pvrtc
151 		case FORMAT_PVRTC2A: return 1;
152 		case FORMAT_PVRTC4: return 1;
153 		case FORMAT_PVRTC4A: return 1;
154 		case FORMAT_ETC:
155 			return 1; //etc1
156 		case FORMAT_ETC2_R11:
157 			return 1; //etc2
158 		case FORMAT_ETC2_R11S:
159 			return 1; //signed: return 1; NOT srgb.
160 		case FORMAT_ETC2_RG11: return 1;
161 		case FORMAT_ETC2_RG11S: return 1;
162 		case FORMAT_ETC2_RGB8: return 1;
163 		case FORMAT_ETC2_RGBA8: return 1;
164 		case FORMAT_ETC2_RGB8A1: return 1;
165 		case FORMAT_MAX: {
166 		}
167 	}
168 	return 0;
169 }
170 
get_format_min_pixel_size(Format p_format,int & r_w,int & r_h)171 void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) {
172 
173 	switch (p_format) {
174 		case FORMAT_DXT1: //s3tc bc1
175 		case FORMAT_DXT3: //bc2
176 		case FORMAT_DXT5: //bc3
177 		case FORMAT_RGTC_R: //bc4
178 		case FORMAT_RGTC_RG: { //bc5		case case FORMAT_DXT1:
179 
180 			r_w = 4;
181 			r_h = 4;
182 		} break;
183 		case FORMAT_PVRTC2:
184 		case FORMAT_PVRTC2A: {
185 
186 			r_w = 16;
187 			r_h = 8;
188 		} break;
189 		case FORMAT_PVRTC4A:
190 		case FORMAT_PVRTC4: {
191 
192 			r_w = 8;
193 			r_h = 8;
194 		} break;
195 		case FORMAT_ETC: {
196 
197 			r_w = 4;
198 			r_h = 4;
199 		} break;
200 		case FORMAT_BPTC_RGBA:
201 		case FORMAT_BPTC_RGBF:
202 		case FORMAT_BPTC_RGBFU: {
203 
204 			r_w = 4;
205 			r_h = 4;
206 		} break;
207 		case FORMAT_ETC2_R11: //etc2
208 		case FORMAT_ETC2_R11S: //signed: NOT srgb.
209 		case FORMAT_ETC2_RG11:
210 		case FORMAT_ETC2_RG11S:
211 		case FORMAT_ETC2_RGB8:
212 		case FORMAT_ETC2_RGBA8:
213 		case FORMAT_ETC2_RGB8A1: {
214 
215 			r_w = 4;
216 			r_h = 4;
217 
218 		} break;
219 
220 		default: {
221 			r_w = 1;
222 			r_h = 1;
223 		} break;
224 	}
225 }
226 
get_format_pixel_rshift(Format p_format)227 int Image::get_format_pixel_rshift(Format p_format) {
228 
229 	if (p_format == FORMAT_DXT1 || p_format == FORMAT_RGTC_R || p_format == FORMAT_PVRTC4 || p_format == FORMAT_PVRTC4A || p_format == FORMAT_ETC || p_format == FORMAT_ETC2_R11 || p_format == FORMAT_ETC2_R11S || p_format == FORMAT_ETC2_RGB8 || p_format == FORMAT_ETC2_RGB8A1)
230 		return 1;
231 	else if (p_format == FORMAT_PVRTC2 || p_format == FORMAT_PVRTC2A)
232 		return 2;
233 	else
234 		return 0;
235 }
236 
get_format_block_size(Format p_format)237 int Image::get_format_block_size(Format p_format) {
238 
239 	switch (p_format) {
240 		case FORMAT_DXT1: //s3tc bc1
241 		case FORMAT_DXT3: //bc2
242 		case FORMAT_DXT5: //bc3
243 		case FORMAT_RGTC_R: //bc4
244 		case FORMAT_RGTC_RG: { //bc5		case case FORMAT_DXT1:
245 
246 			return 4;
247 		}
248 		case FORMAT_PVRTC2:
249 		case FORMAT_PVRTC2A: {
250 
251 			return 4;
252 		}
253 		case FORMAT_PVRTC4A:
254 		case FORMAT_PVRTC4: {
255 
256 			return 4;
257 		}
258 		case FORMAT_ETC: {
259 
260 			return 4;
261 		}
262 		case FORMAT_BPTC_RGBA:
263 		case FORMAT_BPTC_RGBF:
264 		case FORMAT_BPTC_RGBFU: {
265 
266 			return 4;
267 		}
268 		case FORMAT_ETC2_R11: //etc2
269 		case FORMAT_ETC2_R11S: //signed: NOT srgb.
270 		case FORMAT_ETC2_RG11:
271 		case FORMAT_ETC2_RG11S:
272 		case FORMAT_ETC2_RGB8:
273 		case FORMAT_ETC2_RGBA8:
274 		case FORMAT_ETC2_RGB8A1: {
275 
276 			return 4;
277 		}
278 		default: {
279 		}
280 	}
281 
282 	return 1;
283 }
284 
_get_mipmap_offset_and_size(int p_mipmap,int & r_offset,int & r_width,int & r_height) const285 void Image::_get_mipmap_offset_and_size(int p_mipmap, int &r_offset, int &r_width, int &r_height) const {
286 
287 	int w = width;
288 	int h = height;
289 	int ofs = 0;
290 
291 	int pixel_size = get_format_pixel_size(format);
292 	int pixel_rshift = get_format_pixel_rshift(format);
293 	int block = get_format_block_size(format);
294 	int minw, minh;
295 	get_format_min_pixel_size(format, minw, minh);
296 
297 	for (int i = 0; i < p_mipmap; i++) {
298 		int bw = w % block != 0 ? w + (block - w % block) : w;
299 		int bh = h % block != 0 ? h + (block - h % block) : h;
300 
301 		int s = bw * bh;
302 
303 		s *= pixel_size;
304 		s >>= pixel_rshift;
305 		ofs += s;
306 		w = MAX(minw, w >> 1);
307 		h = MAX(minh, h >> 1);
308 	}
309 
310 	r_offset = ofs;
311 	r_width = w;
312 	r_height = h;
313 }
314 
get_mipmap_offset(int p_mipmap) const315 int Image::get_mipmap_offset(int p_mipmap) const {
316 
317 	ERR_FAIL_INDEX_V(p_mipmap, get_mipmap_count() + 1, -1);
318 
319 	int ofs, w, h;
320 	_get_mipmap_offset_and_size(p_mipmap, ofs, w, h);
321 	return ofs;
322 }
323 
get_mipmap_offset_and_size(int p_mipmap,int & r_ofs,int & r_size) const324 void Image::get_mipmap_offset_and_size(int p_mipmap, int &r_ofs, int &r_size) const {
325 
326 	int ofs, w, h;
327 	_get_mipmap_offset_and_size(p_mipmap, ofs, w, h);
328 	int ofs2;
329 	_get_mipmap_offset_and_size(p_mipmap + 1, ofs2, w, h);
330 	r_ofs = ofs;
331 	r_size = ofs2 - ofs;
332 }
333 
get_mipmap_offset_size_and_dimensions(int p_mipmap,int & r_ofs,int & r_size,int & w,int & h) const334 void Image::get_mipmap_offset_size_and_dimensions(int p_mipmap, int &r_ofs, int &r_size, int &w, int &h) const {
335 
336 	int ofs;
337 	_get_mipmap_offset_and_size(p_mipmap, ofs, w, h);
338 	int ofs2, w2, h2;
339 	_get_mipmap_offset_and_size(p_mipmap + 1, ofs2, w2, h2);
340 	r_ofs = ofs;
341 	r_size = ofs2 - ofs;
342 }
343 
get_width() const344 int Image::get_width() const {
345 
346 	return width;
347 }
348 
get_height() const349 int Image::get_height() const {
350 
351 	return height;
352 }
353 
get_size() const354 Vector2 Image::get_size() const {
355 
356 	return Vector2(width, height);
357 }
358 
has_mipmaps() const359 bool Image::has_mipmaps() const {
360 
361 	return mipmaps;
362 }
363 
get_mipmap_count() const364 int Image::get_mipmap_count() const {
365 
366 	if (mipmaps)
367 		return get_image_required_mipmaps(width, height, format);
368 	else
369 		return 0;
370 }
371 
372 //using template generates perfectly optimized code due to constant expression reduction and unused variable removal present in all compilers
373 template <uint32_t read_bytes, bool read_alpha, uint32_t write_bytes, bool write_alpha, bool read_gray, bool write_gray>
_convert(int p_width,int p_height,const uint8_t * p_src,uint8_t * p_dst)374 static void _convert(int p_width, int p_height, const uint8_t *p_src, uint8_t *p_dst) {
375 
376 	uint32_t max_bytes = MAX(read_bytes, write_bytes);
377 
378 	for (int y = 0; y < p_height; y++) {
379 		for (int x = 0; x < p_width; x++) {
380 
381 			const uint8_t *rofs = &p_src[((y * p_width) + x) * (read_bytes + (read_alpha ? 1 : 0))];
382 			uint8_t *wofs = &p_dst[((y * p_width) + x) * (write_bytes + (write_alpha ? 1 : 0))];
383 
384 			uint8_t rgba[4];
385 
386 			if (read_gray) {
387 				rgba[0] = rofs[0];
388 				rgba[1] = rofs[0];
389 				rgba[2] = rofs[0];
390 			} else {
391 
392 				for (uint32_t i = 0; i < max_bytes; i++) {
393 
394 					rgba[i] = (i < read_bytes) ? rofs[i] : 0;
395 				}
396 			}
397 
398 			if (read_alpha || write_alpha) {
399 				rgba[3] = read_alpha ? rofs[read_bytes] : 255;
400 			}
401 
402 			if (write_gray) {
403 				//TODO: not correct grayscale, should use fixed point version of actual weights
404 				wofs[0] = uint8_t((uint16_t(rofs[0]) + uint16_t(rofs[1]) + uint16_t(rofs[2])) / 3);
405 			} else {
406 				for (uint32_t i = 0; i < write_bytes; i++) {
407 
408 					wofs[i] = rgba[i];
409 				}
410 			}
411 
412 			if (write_alpha) {
413 				wofs[write_bytes] = rgba[3];
414 			}
415 		}
416 	}
417 }
418 
convert(Format p_new_format)419 void Image::convert(Format p_new_format) {
420 
421 	if (data.size() == 0)
422 		return;
423 
424 	if (p_new_format == format)
425 		return;
426 
427 	ERR_FAIL_COND_MSG(write_lock.ptr(), "Cannot convert image when it is locked.");
428 
429 	if (format > FORMAT_RGBE9995 || p_new_format > FORMAT_RGBE9995) {
430 
431 		ERR_FAIL_MSG("Cannot convert to <-> from compressed formats. Use compress() and decompress() instead.");
432 
433 	} else if (format > FORMAT_RGBA8 || p_new_format > FORMAT_RGBA8) {
434 
435 		//use put/set pixel which is slower but works with non byte formats
436 		Image new_img(width, height, 0, p_new_format);
437 		lock();
438 		new_img.lock();
439 
440 		for (int i = 0; i < width; i++) {
441 			for (int j = 0; j < height; j++) {
442 
443 				new_img.set_pixel(i, j, get_pixel(i, j));
444 			}
445 		}
446 
447 		unlock();
448 		new_img.unlock();
449 
450 		if (has_mipmaps()) {
451 			new_img.generate_mipmaps();
452 		}
453 
454 		_copy_internals_from(new_img);
455 
456 		return;
457 	}
458 
459 	Image new_img(width, height, 0, p_new_format);
460 
461 	PoolVector<uint8_t>::Read r = data.read();
462 	PoolVector<uint8_t>::Write w = new_img.data.write();
463 
464 	const uint8_t *rptr = r.ptr();
465 	uint8_t *wptr = w.ptr();
466 
467 	int conversion_type = format | p_new_format << 8;
468 
469 	switch (conversion_type) {
470 
471 		case FORMAT_L8 | (FORMAT_LA8 << 8): _convert<1, false, 1, true, true, true>(width, height, rptr, wptr); break;
472 		case FORMAT_L8 | (FORMAT_R8 << 8): _convert<1, false, 1, false, true, false>(width, height, rptr, wptr); break;
473 		case FORMAT_L8 | (FORMAT_RG8 << 8): _convert<1, false, 2, false, true, false>(width, height, rptr, wptr); break;
474 		case FORMAT_L8 | (FORMAT_RGB8 << 8): _convert<1, false, 3, false, true, false>(width, height, rptr, wptr); break;
475 		case FORMAT_L8 | (FORMAT_RGBA8 << 8): _convert<1, false, 3, true, true, false>(width, height, rptr, wptr); break;
476 		case FORMAT_LA8 | (FORMAT_L8 << 8): _convert<1, true, 1, false, true, true>(width, height, rptr, wptr); break;
477 		case FORMAT_LA8 | (FORMAT_R8 << 8): _convert<1, true, 1, false, true, false>(width, height, rptr, wptr); break;
478 		case FORMAT_LA8 | (FORMAT_RG8 << 8): _convert<1, true, 2, false, true, false>(width, height, rptr, wptr); break;
479 		case FORMAT_LA8 | (FORMAT_RGB8 << 8): _convert<1, true, 3, false, true, false>(width, height, rptr, wptr); break;
480 		case FORMAT_LA8 | (FORMAT_RGBA8 << 8): _convert<1, true, 3, true, true, false>(width, height, rptr, wptr); break;
481 		case FORMAT_R8 | (FORMAT_L8 << 8): _convert<1, false, 1, false, false, true>(width, height, rptr, wptr); break;
482 		case FORMAT_R8 | (FORMAT_LA8 << 8): _convert<1, false, 1, true, false, true>(width, height, rptr, wptr); break;
483 		case FORMAT_R8 | (FORMAT_RG8 << 8): _convert<1, false, 2, false, false, false>(width, height, rptr, wptr); break;
484 		case FORMAT_R8 | (FORMAT_RGB8 << 8): _convert<1, false, 3, false, false, false>(width, height, rptr, wptr); break;
485 		case FORMAT_R8 | (FORMAT_RGBA8 << 8): _convert<1, false, 3, true, false, false>(width, height, rptr, wptr); break;
486 		case FORMAT_RG8 | (FORMAT_L8 << 8): _convert<2, false, 1, false, false, true>(width, height, rptr, wptr); break;
487 		case FORMAT_RG8 | (FORMAT_LA8 << 8): _convert<2, false, 1, true, false, true>(width, height, rptr, wptr); break;
488 		case FORMAT_RG8 | (FORMAT_R8 << 8): _convert<2, false, 1, false, false, false>(width, height, rptr, wptr); break;
489 		case FORMAT_RG8 | (FORMAT_RGB8 << 8): _convert<2, false, 3, false, false, false>(width, height, rptr, wptr); break;
490 		case FORMAT_RG8 | (FORMAT_RGBA8 << 8): _convert<2, false, 3, true, false, false>(width, height, rptr, wptr); break;
491 		case FORMAT_RGB8 | (FORMAT_L8 << 8): _convert<3, false, 1, false, false, true>(width, height, rptr, wptr); break;
492 		case FORMAT_RGB8 | (FORMAT_LA8 << 8): _convert<3, false, 1, true, false, true>(width, height, rptr, wptr); break;
493 		case FORMAT_RGB8 | (FORMAT_R8 << 8): _convert<3, false, 1, false, false, false>(width, height, rptr, wptr); break;
494 		case FORMAT_RGB8 | (FORMAT_RG8 << 8): _convert<3, false, 2, false, false, false>(width, height, rptr, wptr); break;
495 		case FORMAT_RGB8 | (FORMAT_RGBA8 << 8): _convert<3, false, 3, true, false, false>(width, height, rptr, wptr); break;
496 		case FORMAT_RGBA8 | (FORMAT_L8 << 8): _convert<3, true, 1, false, false, true>(width, height, rptr, wptr); break;
497 		case FORMAT_RGBA8 | (FORMAT_LA8 << 8): _convert<3, true, 1, true, false, true>(width, height, rptr, wptr); break;
498 		case FORMAT_RGBA8 | (FORMAT_R8 << 8): _convert<3, true, 1, false, false, false>(width, height, rptr, wptr); break;
499 		case FORMAT_RGBA8 | (FORMAT_RG8 << 8): _convert<3, true, 2, false, false, false>(width, height, rptr, wptr); break;
500 		case FORMAT_RGBA8 | (FORMAT_RGB8 << 8): _convert<3, true, 3, false, false, false>(width, height, rptr, wptr); break;
501 	}
502 
503 	r.release();
504 	w.release();
505 
506 	bool gen_mipmaps = mipmaps;
507 
508 	_copy_internals_from(new_img);
509 
510 	if (gen_mipmaps)
511 		generate_mipmaps();
512 }
513 
get_format() const514 Image::Format Image::get_format() const {
515 
516 	return format;
517 }
518 
_bicubic_interp_kernel(double x)519 static double _bicubic_interp_kernel(double x) {
520 
521 	x = ABS(x);
522 
523 	double bc = 0;
524 
525 	if (x <= 1)
526 		bc = (1.5 * x - 2.5) * x * x + 1;
527 	else if (x < 2)
528 		bc = ((-0.5 * x + 2.5) * x - 4) * x + 2;
529 
530 	return bc;
531 }
532 
533 template <int CC, class T>
_scale_cubic(const uint8_t * __restrict p_src,uint8_t * __restrict p_dst,uint32_t p_src_width,uint32_t p_src_height,uint32_t p_dst_width,uint32_t p_dst_height)534 static void _scale_cubic(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, uint32_t p_src_width, uint32_t p_src_height, uint32_t p_dst_width, uint32_t p_dst_height) {
535 
536 	// get source image size
537 	int width = p_src_width;
538 	int height = p_src_height;
539 	double xfac = (double)width / p_dst_width;
540 	double yfac = (double)height / p_dst_height;
541 	// coordinates of source points and coefficients
542 	double ox, oy, dx, dy, k1, k2;
543 	int ox1, oy1, ox2, oy2;
544 	// destination pixel values
545 	// width and height decreased by 1
546 	int ymax = height - 1;
547 	int xmax = width - 1;
548 	// temporary pointer
549 
550 	for (uint32_t y = 0; y < p_dst_height; y++) {
551 		// Y coordinates
552 		oy = (double)y * yfac - 0.5f;
553 		oy1 = (int)oy;
554 		dy = oy - (double)oy1;
555 
556 		for (uint32_t x = 0; x < p_dst_width; x++) {
557 			// X coordinates
558 			ox = (double)x * xfac - 0.5f;
559 			ox1 = (int)ox;
560 			dx = ox - (double)ox1;
561 
562 			// initial pixel value
563 
564 			T *__restrict dst = ((T *)p_dst) + (y * p_dst_width + x) * CC;
565 
566 			double color[CC];
567 			for (int i = 0; i < CC; i++) {
568 				color[i] = 0;
569 			}
570 
571 			for (int n = -1; n < 3; n++) {
572 				// get Y coefficient
573 				k1 = _bicubic_interp_kernel(dy - (double)n);
574 
575 				oy2 = oy1 + n;
576 				if (oy2 < 0)
577 					oy2 = 0;
578 				if (oy2 > ymax)
579 					oy2 = ymax;
580 
581 				for (int m = -1; m < 3; m++) {
582 					// get X coefficient
583 					k2 = k1 * _bicubic_interp_kernel((double)m - dx);
584 
585 					ox2 = ox1 + m;
586 					if (ox2 < 0)
587 						ox2 = 0;
588 					if (ox2 > xmax)
589 						ox2 = xmax;
590 
591 					// get pixel of original image
592 					const T *__restrict p = ((T *)p_src) + (oy2 * p_src_width + ox2) * CC;
593 
594 					for (int i = 0; i < CC; i++) {
595 						if (sizeof(T) == 2) { //half float
596 							color[i] = Math::half_to_float(p[i]);
597 						} else {
598 							color[i] += p[i] * k2;
599 						}
600 					}
601 				}
602 			}
603 
604 			for (int i = 0; i < CC; i++) {
605 				if (sizeof(T) == 1) { //byte
606 					dst[i] = CLAMP(Math::fast_ftoi(color[i]), 0, 255);
607 				} else if (sizeof(T) == 2) { //half float
608 					dst[i] = Math::make_half_float(color[i]);
609 				} else {
610 					dst[i] = color[i];
611 				}
612 			}
613 		}
614 	}
615 }
616 
617 template <int CC, class T>
_scale_bilinear(const uint8_t * __restrict p_src,uint8_t * __restrict p_dst,uint32_t p_src_width,uint32_t p_src_height,uint32_t p_dst_width,uint32_t p_dst_height)618 static void _scale_bilinear(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, uint32_t p_src_width, uint32_t p_src_height, uint32_t p_dst_width, uint32_t p_dst_height) {
619 
620 	enum {
621 		FRAC_BITS = 8,
622 		FRAC_LEN = (1 << FRAC_BITS),
623 		FRAC_HALF = (FRAC_LEN >> 1),
624 		FRAC_MASK = FRAC_LEN - 1
625 	};
626 
627 	for (uint32_t i = 0; i < p_dst_height; i++) {
628 		// Add 0.5 in order to interpolate based on pixel center
629 		uint32_t src_yofs_up_fp = (i + 0.5) * p_src_height * FRAC_LEN / p_dst_height;
630 		// Calculate nearest src pixel center above current, and truncate to get y index
631 		uint32_t src_yofs_up = src_yofs_up_fp >= FRAC_HALF ? (src_yofs_up_fp - FRAC_HALF) >> FRAC_BITS : 0;
632 		uint32_t src_yofs_down = (src_yofs_up_fp + FRAC_HALF) >> FRAC_BITS;
633 		if (src_yofs_down >= p_src_height) {
634 			src_yofs_down = p_src_height - 1;
635 		}
636 		// Calculate distance to pixel center of src_yofs_up
637 		uint32_t src_yofs_frac = src_yofs_up_fp & FRAC_MASK;
638 		src_yofs_frac = src_yofs_frac >= FRAC_HALF ? src_yofs_frac - FRAC_HALF : src_yofs_frac + FRAC_HALF;
639 
640 		uint32_t y_ofs_up = src_yofs_up * p_src_width * CC;
641 		uint32_t y_ofs_down = src_yofs_down * p_src_width * CC;
642 
643 		for (uint32_t j = 0; j < p_dst_width; j++) {
644 			uint32_t src_xofs_left_fp = (j + 0.5) * p_src_width * FRAC_LEN / p_dst_width;
645 			uint32_t src_xofs_left = src_xofs_left_fp >= FRAC_HALF ? (src_xofs_left_fp - FRAC_HALF) >> FRAC_BITS : 0;
646 			uint32_t src_xofs_right = (src_xofs_left_fp + FRAC_HALF) >> FRAC_BITS;
647 			if (src_xofs_right >= p_src_width) {
648 				src_xofs_right = p_src_width - 1;
649 			}
650 			uint32_t src_xofs_frac = src_xofs_left_fp & FRAC_MASK;
651 			src_xofs_frac = src_xofs_frac >= FRAC_HALF ? src_xofs_frac - FRAC_HALF : src_xofs_frac + FRAC_HALF;
652 
653 			src_xofs_left *= CC;
654 			src_xofs_right *= CC;
655 
656 			for (uint32_t l = 0; l < CC; l++) {
657 
658 				if (sizeof(T) == 1) { //uint8
659 					uint32_t p00 = p_src[y_ofs_up + src_xofs_left + l] << FRAC_BITS;
660 					uint32_t p10 = p_src[y_ofs_up + src_xofs_right + l] << FRAC_BITS;
661 					uint32_t p01 = p_src[y_ofs_down + src_xofs_left + l] << FRAC_BITS;
662 					uint32_t p11 = p_src[y_ofs_down + src_xofs_right + l] << FRAC_BITS;
663 
664 					uint32_t interp_up = p00 + (((p10 - p00) * src_xofs_frac) >> FRAC_BITS);
665 					uint32_t interp_down = p01 + (((p11 - p01) * src_xofs_frac) >> FRAC_BITS);
666 					uint32_t interp = interp_up + (((interp_down - interp_up) * src_yofs_frac) >> FRAC_BITS);
667 					interp >>= FRAC_BITS;
668 					p_dst[i * p_dst_width * CC + j * CC + l] = interp;
669 				} else if (sizeof(T) == 2) { //half float
670 
671 					float xofs_frac = float(src_xofs_frac) / (1 << FRAC_BITS);
672 					float yofs_frac = float(src_yofs_frac) / (1 << FRAC_BITS);
673 					const T *src = ((const T *)p_src);
674 					T *dst = ((T *)p_dst);
675 
676 					float p00 = Math::half_to_float(src[y_ofs_up + src_xofs_left + l]);
677 					float p10 = Math::half_to_float(src[y_ofs_up + src_xofs_right + l]);
678 					float p01 = Math::half_to_float(src[y_ofs_down + src_xofs_left + l]);
679 					float p11 = Math::half_to_float(src[y_ofs_down + src_xofs_right + l]);
680 
681 					float interp_up = p00 + (p10 - p00) * xofs_frac;
682 					float interp_down = p01 + (p11 - p01) * xofs_frac;
683 					float interp = interp_up + ((interp_down - interp_up) * yofs_frac);
684 
685 					dst[i * p_dst_width * CC + j * CC + l] = Math::make_half_float(interp);
686 				} else if (sizeof(T) == 4) { //float
687 
688 					float xofs_frac = float(src_xofs_frac) / (1 << FRAC_BITS);
689 					float yofs_frac = float(src_yofs_frac) / (1 << FRAC_BITS);
690 					const T *src = ((const T *)p_src);
691 					T *dst = ((T *)p_dst);
692 
693 					float p00 = src[y_ofs_up + src_xofs_left + l];
694 					float p10 = src[y_ofs_up + src_xofs_right + l];
695 					float p01 = src[y_ofs_down + src_xofs_left + l];
696 					float p11 = src[y_ofs_down + src_xofs_right + l];
697 
698 					float interp_up = p00 + (p10 - p00) * xofs_frac;
699 					float interp_down = p01 + (p11 - p01) * xofs_frac;
700 					float interp = interp_up + ((interp_down - interp_up) * yofs_frac);
701 
702 					dst[i * p_dst_width * CC + j * CC + l] = interp;
703 				}
704 			}
705 		}
706 	}
707 }
708 
709 template <int CC, class T>
_scale_nearest(const uint8_t * __restrict p_src,uint8_t * __restrict p_dst,uint32_t p_src_width,uint32_t p_src_height,uint32_t p_dst_width,uint32_t p_dst_height)710 static void _scale_nearest(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, uint32_t p_src_width, uint32_t p_src_height, uint32_t p_dst_width, uint32_t p_dst_height) {
711 
712 	for (uint32_t i = 0; i < p_dst_height; i++) {
713 
714 		uint32_t src_yofs = i * p_src_height / p_dst_height;
715 		uint32_t y_ofs = src_yofs * p_src_width * CC;
716 
717 		for (uint32_t j = 0; j < p_dst_width; j++) {
718 
719 			uint32_t src_xofs = j * p_src_width / p_dst_width;
720 			src_xofs *= CC;
721 
722 			for (uint32_t l = 0; l < CC; l++) {
723 
724 				const T *src = ((const T *)p_src);
725 				T *dst = ((T *)p_dst);
726 
727 				T p = src[y_ofs + src_xofs + l];
728 				dst[i * p_dst_width * CC + j * CC + l] = p;
729 			}
730 		}
731 	}
732 }
733 
734 #define LANCZOS_TYPE 3
735 
_lanczos(float p_x)736 static float _lanczos(float p_x) {
737 	return Math::abs(p_x) >= LANCZOS_TYPE ? 0 : Math::sincn(p_x) * Math::sincn(p_x / LANCZOS_TYPE);
738 }
739 
740 template <int CC, class T>
_scale_lanczos(const uint8_t * __restrict p_src,uint8_t * __restrict p_dst,uint32_t p_src_width,uint32_t p_src_height,uint32_t p_dst_width,uint32_t p_dst_height)741 static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, uint32_t p_src_width, uint32_t p_src_height, uint32_t p_dst_width, uint32_t p_dst_height) {
742 
743 	int32_t src_width = p_src_width;
744 	int32_t src_height = p_src_height;
745 	int32_t dst_height = p_dst_height;
746 	int32_t dst_width = p_dst_width;
747 
748 	uint32_t buffer_size = src_height * dst_width * CC;
749 	float *buffer = memnew_arr(float, buffer_size); // Store the first pass in a buffer
750 
751 	{ // FIRST PASS (horizontal)
752 
753 		float x_scale = float(src_width) / float(dst_width);
754 
755 		float scale_factor = MAX(x_scale, 1); // A larger kernel is required only when downscaling
756 		int32_t half_kernel = LANCZOS_TYPE * scale_factor;
757 
758 		float *kernel = memnew_arr(float, half_kernel * 2);
759 
760 		for (int32_t buffer_x = 0; buffer_x < dst_width; buffer_x++) {
761 
762 			// The corresponding point on the source image
763 			float src_x = (buffer_x + 0.5f) * x_scale; // Offset by 0.5 so it uses the pixel's center
764 			int32_t start_x = MAX(0, int32_t(src_x) - half_kernel + 1);
765 			int32_t end_x = MIN(src_width - 1, int32_t(src_x) + half_kernel);
766 
767 			// Create the kernel used by all the pixels of the column
768 			for (int32_t target_x = start_x; target_x <= end_x; target_x++)
769 				kernel[target_x - start_x] = _lanczos((target_x + 0.5f - src_x) / scale_factor);
770 
771 			for (int32_t buffer_y = 0; buffer_y < src_height; buffer_y++) {
772 
773 				float pixel[CC] = { 0 };
774 				float weight = 0;
775 
776 				for (int32_t target_x = start_x; target_x <= end_x; target_x++) {
777 
778 					float lanczos_val = kernel[target_x - start_x];
779 					weight += lanczos_val;
780 
781 					const T *__restrict src_data = ((const T *)p_src) + (buffer_y * src_width + target_x) * CC;
782 
783 					for (uint32_t i = 0; i < CC; i++) {
784 						if (sizeof(T) == 2) //half float
785 							pixel[i] += Math::half_to_float(src_data[i]) * lanczos_val;
786 						else
787 							pixel[i] += src_data[i] * lanczos_val;
788 					}
789 				}
790 
791 				float *dst_data = ((float *)buffer) + (buffer_y * dst_width + buffer_x) * CC;
792 
793 				for (uint32_t i = 0; i < CC; i++)
794 					dst_data[i] = pixel[i] / weight; // Normalize the sum of all the samples
795 			}
796 		}
797 
798 		memdelete_arr(kernel);
799 	} // End of first pass
800 
801 	{ // SECOND PASS (vertical + result)
802 
803 		float y_scale = float(src_height) / float(dst_height);
804 
805 		float scale_factor = MAX(y_scale, 1);
806 		int32_t half_kernel = LANCZOS_TYPE * scale_factor;
807 
808 		float *kernel = memnew_arr(float, half_kernel * 2);
809 
810 		for (int32_t dst_y = 0; dst_y < dst_height; dst_y++) {
811 
812 			float buffer_y = (dst_y + 0.5f) * y_scale;
813 			int32_t start_y = MAX(0, int32_t(buffer_y) - half_kernel + 1);
814 			int32_t end_y = MIN(src_height - 1, int32_t(buffer_y) + half_kernel);
815 
816 			for (int32_t target_y = start_y; target_y <= end_y; target_y++)
817 				kernel[target_y - start_y] = _lanczos((target_y + 0.5f - buffer_y) / scale_factor);
818 
819 			for (int32_t dst_x = 0; dst_x < dst_width; dst_x++) {
820 
821 				float pixel[CC] = { 0 };
822 				float weight = 0;
823 
824 				for (int32_t target_y = start_y; target_y <= end_y; target_y++) {
825 
826 					float lanczos_val = kernel[target_y - start_y];
827 					weight += lanczos_val;
828 
829 					float *buffer_data = ((float *)buffer) + (target_y * dst_width + dst_x) * CC;
830 
831 					for (uint32_t i = 0; i < CC; i++)
832 						pixel[i] += buffer_data[i] * lanczos_val;
833 				}
834 
835 				T *dst_data = ((T *)p_dst) + (dst_y * dst_width + dst_x) * CC;
836 
837 				for (uint32_t i = 0; i < CC; i++) {
838 					pixel[i] /= weight;
839 
840 					if (sizeof(T) == 1) //byte
841 						dst_data[i] = CLAMP(Math::fast_ftoi(pixel[i]), 0, 255);
842 					else if (sizeof(T) == 2) //half float
843 						dst_data[i] = Math::make_half_float(pixel[i]);
844 					else // float
845 						dst_data[i] = pixel[i];
846 				}
847 			}
848 		}
849 
850 		memdelete_arr(kernel);
851 	} // End of second pass
852 
853 	memdelete_arr(buffer);
854 }
855 
_overlay(const uint8_t * __restrict p_src,uint8_t * __restrict p_dst,float p_alpha,uint32_t p_width,uint32_t p_height,uint32_t p_pixel_size)856 static void _overlay(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, float p_alpha, uint32_t p_width, uint32_t p_height, uint32_t p_pixel_size) {
857 
858 	uint16_t alpha = MIN((uint16_t)(p_alpha * 256.0f), 256);
859 
860 	for (uint32_t i = 0; i < p_width * p_height * p_pixel_size; i++) {
861 
862 		p_dst[i] = (p_dst[i] * (256 - alpha) + p_src[i] * alpha) >> 8;
863 	}
864 }
865 
is_size_po2() const866 bool Image::is_size_po2() const {
867 	return uint32_t(width) == next_power_of_2(width) && uint32_t(height) == next_power_of_2(height);
868 }
869 
resize_to_po2(bool p_square)870 void Image::resize_to_po2(bool p_square) {
871 
872 	ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot resize in compressed or custom image formats.");
873 
874 	int w = next_power_of_2(width);
875 	int h = next_power_of_2(height);
876 	if (p_square) {
877 		w = h = MAX(w, h);
878 	}
879 
880 	if (w == width && h == height) {
881 
882 		if (!p_square || w == h)
883 			return; //nothing to do
884 	}
885 
886 	resize(w, h);
887 }
888 
resize(int p_width,int p_height,Interpolation p_interpolation)889 void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
890 
891 	ERR_FAIL_COND_MSG(data.size() == 0, "Cannot resize image before creating it, use create() or create_from_data() first.");
892 	ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot resize in compressed or custom image formats.");
893 	ERR_FAIL_COND_MSG(write_lock.ptr(), "Cannot resize image when it is locked.");
894 
895 	bool mipmap_aware = p_interpolation == INTERPOLATE_TRILINEAR /* || p_interpolation == INTERPOLATE_TRICUBIC */;
896 
897 	ERR_FAIL_COND_MSG(p_width <= 0, "Image width must be greater than 0.");
898 	ERR_FAIL_COND_MSG(p_height <= 0, "Image height must be greater than 0.");
899 	ERR_FAIL_COND_MSG(p_width > MAX_WIDTH, "Image width cannot be greater than " + itos(MAX_WIDTH) + ".");
900 	ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT, "Image height cannot be greater than " + itos(MAX_HEIGHT) + ".");
901 
902 	if (p_width == width && p_height == height)
903 		return;
904 
905 	Image dst(p_width, p_height, 0, format);
906 
907 	// Setup mipmap-aware scaling
908 	Image dst2;
909 	int mip1 = 0;
910 	int mip2 = 0;
911 	float mip1_weight = 0;
912 	if (mipmap_aware) {
913 		float avg_scale = ((float)p_width / width + (float)p_height / height) * 0.5f;
914 		if (avg_scale >= 1.0f) {
915 			mipmap_aware = false;
916 		} else {
917 			float level = Math::log(1.0f / avg_scale) / Math::log(2.0f);
918 			mip1 = CLAMP((int)Math::floor(level), 0, get_mipmap_count());
919 			mip2 = CLAMP((int)Math::ceil(level), 0, get_mipmap_count());
920 			mip1_weight = 1.0f - (level - mip1);
921 		}
922 	}
923 	bool interpolate_mipmaps = mipmap_aware && mip1 != mip2;
924 	if (interpolate_mipmaps) {
925 		dst2.create(p_width, p_height, 0, format);
926 	}
927 
928 	bool had_mipmaps = mipmaps;
929 	if (interpolate_mipmaps && !had_mipmaps) {
930 		generate_mipmaps();
931 	}
932 	// --
933 
934 	PoolVector<uint8_t>::Read r = data.read();
935 	const unsigned char *r_ptr = r.ptr();
936 
937 	PoolVector<uint8_t>::Write w = dst.data.write();
938 	unsigned char *w_ptr = w.ptr();
939 
940 	switch (p_interpolation) {
941 
942 		case INTERPOLATE_NEAREST: {
943 
944 			if (format >= FORMAT_L8 && format <= FORMAT_RGBA8) {
945 				switch (get_format_pixel_size(format)) {
946 					case 1: _scale_nearest<1, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
947 					case 2: _scale_nearest<2, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
948 					case 3: _scale_nearest<3, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
949 					case 4: _scale_nearest<4, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
950 				}
951 			} else if (format >= FORMAT_RF && format <= FORMAT_RGBAF) {
952 				switch (get_format_pixel_size(format)) {
953 					case 4: _scale_nearest<1, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
954 					case 8: _scale_nearest<2, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
955 					case 12: _scale_nearest<3, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
956 					case 16: _scale_nearest<4, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
957 				}
958 
959 			} else if (format >= FORMAT_RH && format <= FORMAT_RGBAH) {
960 				switch (get_format_pixel_size(format)) {
961 					case 2: _scale_nearest<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
962 					case 4: _scale_nearest<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
963 					case 6: _scale_nearest<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
964 					case 8: _scale_nearest<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
965 				}
966 			}
967 
968 		} break;
969 		case INTERPOLATE_BILINEAR:
970 		case INTERPOLATE_TRILINEAR: {
971 
972 			for (int i = 0; i < 2; ++i) {
973 				int src_width;
974 				int src_height;
975 				const unsigned char *src_ptr;
976 
977 				if (!mipmap_aware) {
978 					if (i == 0) {
979 						// Standard behavior
980 						src_width = width;
981 						src_height = height;
982 						src_ptr = r_ptr;
983 					} else {
984 						// No need for a second iteration
985 						break;
986 					}
987 				} else {
988 					if (i == 0) {
989 						// Read from the first mipmap that will be interpolated
990 						// (if both levels are the same, we will not interpolate, but at least we'll sample from the right level)
991 						int offs;
992 						_get_mipmap_offset_and_size(mip1, offs, src_width, src_height);
993 						src_ptr = r_ptr + offs;
994 					} else if (!interpolate_mipmaps) {
995 						// No need generate a second image
996 						break;
997 					} else {
998 						// Switch to read from the second mipmap that will be interpolated
999 						int offs;
1000 						_get_mipmap_offset_and_size(mip2, offs, src_width, src_height);
1001 						src_ptr = r_ptr + offs;
1002 						// Switch to write to the second destination image
1003 						w = dst2.data.write();
1004 						w_ptr = w.ptr();
1005 					}
1006 				}
1007 
1008 				if (format >= FORMAT_L8 && format <= FORMAT_RGBA8) {
1009 					switch (get_format_pixel_size(format)) {
1010 						case 1: _scale_bilinear<1, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
1011 						case 2: _scale_bilinear<2, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
1012 						case 3: _scale_bilinear<3, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
1013 						case 4: _scale_bilinear<4, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
1014 					}
1015 				} else if (format >= FORMAT_RF && format <= FORMAT_RGBAF) {
1016 					switch (get_format_pixel_size(format)) {
1017 						case 4: _scale_bilinear<1, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
1018 						case 8: _scale_bilinear<2, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
1019 						case 12: _scale_bilinear<3, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
1020 						case 16: _scale_bilinear<4, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
1021 					}
1022 				} else if (format >= FORMAT_RH && format <= FORMAT_RGBAH) {
1023 					switch (get_format_pixel_size(format)) {
1024 						case 2: _scale_bilinear<1, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
1025 						case 4: _scale_bilinear<2, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
1026 						case 6: _scale_bilinear<3, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
1027 						case 8: _scale_bilinear<4, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
1028 					}
1029 				}
1030 			}
1031 
1032 			if (interpolate_mipmaps) {
1033 				// Switch to read again from the first scaled mipmap to overlay it over the second
1034 				r = dst.data.read();
1035 				_overlay(r.ptr(), w.ptr(), mip1_weight, p_width, p_height, get_format_pixel_size(format));
1036 			}
1037 
1038 		} break;
1039 		case INTERPOLATE_CUBIC: {
1040 
1041 			if (format >= FORMAT_L8 && format <= FORMAT_RGBA8) {
1042 				switch (get_format_pixel_size(format)) {
1043 					case 1: _scale_cubic<1, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1044 					case 2: _scale_cubic<2, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1045 					case 3: _scale_cubic<3, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1046 					case 4: _scale_cubic<4, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1047 				}
1048 			} else if (format >= FORMAT_RF && format <= FORMAT_RGBAF) {
1049 				switch (get_format_pixel_size(format)) {
1050 					case 4: _scale_cubic<1, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1051 					case 8: _scale_cubic<2, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1052 					case 12: _scale_cubic<3, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1053 					case 16: _scale_cubic<4, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1054 				}
1055 			} else if (format >= FORMAT_RH && format <= FORMAT_RGBAH) {
1056 				switch (get_format_pixel_size(format)) {
1057 					case 2: _scale_cubic<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1058 					case 4: _scale_cubic<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1059 					case 6: _scale_cubic<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1060 					case 8: _scale_cubic<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1061 				}
1062 			}
1063 		} break;
1064 		case INTERPOLATE_LANCZOS: {
1065 
1066 			if (format >= FORMAT_L8 && format <= FORMAT_RGBA8) {
1067 				switch (get_format_pixel_size(format)) {
1068 					case 1: _scale_lanczos<1, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1069 					case 2: _scale_lanczos<2, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1070 					case 3: _scale_lanczos<3, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1071 					case 4: _scale_lanczos<4, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1072 				}
1073 			} else if (format >= FORMAT_RF && format <= FORMAT_RGBAF) {
1074 				switch (get_format_pixel_size(format)) {
1075 					case 4: _scale_lanczos<1, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1076 					case 8: _scale_lanczos<2, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1077 					case 12: _scale_lanczos<3, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1078 					case 16: _scale_lanczos<4, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1079 				}
1080 			} else if (format >= FORMAT_RH && format <= FORMAT_RGBAH) {
1081 				switch (get_format_pixel_size(format)) {
1082 					case 2: _scale_lanczos<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1083 					case 4: _scale_lanczos<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1084 					case 6: _scale_lanczos<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1085 					case 8: _scale_lanczos<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
1086 				}
1087 			}
1088 		} break;
1089 	}
1090 
1091 	r.release();
1092 	w.release();
1093 
1094 	if (interpolate_mipmaps) {
1095 		dst._copy_internals_from(dst2);
1096 	}
1097 
1098 	if (had_mipmaps)
1099 		dst.generate_mipmaps();
1100 
1101 	_copy_internals_from(dst);
1102 }
1103 
crop_from_point(int p_x,int p_y,int p_width,int p_height)1104 void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) {
1105 
1106 	ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot crop in compressed or custom image formats.");
1107 
1108 	ERR_FAIL_COND_MSG(p_x < 0, "Start x position cannot be smaller than 0.");
1109 	ERR_FAIL_COND_MSG(p_y < 0, "Start y position cannot be smaller than 0.");
1110 	ERR_FAIL_COND_MSG(p_width <= 0, "Width of image must be greater than 0.");
1111 	ERR_FAIL_COND_MSG(p_height <= 0, "Height of image must be greater than 0.");
1112 	ERR_FAIL_COND_MSG(p_x + p_width > MAX_WIDTH, "End x position cannot be greater than " + itos(MAX_WIDTH) + ".");
1113 	ERR_FAIL_COND_MSG(p_y + p_height > MAX_HEIGHT, "End y position cannot be greater than " + itos(MAX_HEIGHT) + ".");
1114 
1115 	/* to save memory, cropping should be done in-place, however, since this function
1116 	   will most likely either not be used much, or in critical areas, for now it won't, because
1117 	   it's a waste of time. */
1118 
1119 	if (p_width == width && p_height == height && p_x == 0 && p_y == 0)
1120 		return;
1121 
1122 	uint8_t pdata[16]; //largest is 16
1123 	uint32_t pixel_size = get_format_pixel_size(format);
1124 
1125 	Image dst(p_width, p_height, 0, format);
1126 
1127 	{
1128 		PoolVector<uint8_t>::Read r = data.read();
1129 		PoolVector<uint8_t>::Write w = dst.data.write();
1130 
1131 		int m_h = p_y + p_height;
1132 		int m_w = p_x + p_width;
1133 		for (int y = p_y; y < m_h; y++) {
1134 
1135 			for (int x = p_x; x < m_w; x++) {
1136 
1137 				if ((x >= width || y >= height)) {
1138 					for (uint32_t i = 0; i < pixel_size; i++)
1139 						pdata[i] = 0;
1140 				} else {
1141 					_get_pixelb(x, y, pixel_size, r.ptr(), pdata);
1142 				}
1143 
1144 				dst._put_pixelb(x - p_x, y - p_y, pixel_size, w.ptr(), pdata);
1145 			}
1146 		}
1147 	}
1148 
1149 	if (has_mipmaps())
1150 		dst.generate_mipmaps();
1151 	_copy_internals_from(dst);
1152 }
1153 
crop(int p_width,int p_height)1154 void Image::crop(int p_width, int p_height) {
1155 
1156 	crop_from_point(0, 0, p_width, p_height);
1157 }
1158 
flip_y()1159 void Image::flip_y() {
1160 
1161 	ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot flip_y in compressed or custom image formats.");
1162 
1163 	bool used_mipmaps = has_mipmaps();
1164 	if (used_mipmaps) {
1165 		clear_mipmaps();
1166 	}
1167 
1168 	{
1169 		PoolVector<uint8_t>::Write w = data.write();
1170 		uint8_t up[16];
1171 		uint8_t down[16];
1172 		uint32_t pixel_size = get_format_pixel_size(format);
1173 
1174 		for (int y = 0; y < height / 2; y++) {
1175 
1176 			for (int x = 0; x < width; x++) {
1177 
1178 				_get_pixelb(x, y, pixel_size, w.ptr(), up);
1179 				_get_pixelb(x, height - y - 1, pixel_size, w.ptr(), down);
1180 
1181 				_put_pixelb(x, height - y - 1, pixel_size, w.ptr(), up);
1182 				_put_pixelb(x, y, pixel_size, w.ptr(), down);
1183 			}
1184 		}
1185 	}
1186 
1187 	if (used_mipmaps) {
1188 		generate_mipmaps();
1189 	}
1190 }
1191 
flip_x()1192 void Image::flip_x() {
1193 
1194 	ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot flip_x in compressed or custom image formats.");
1195 
1196 	bool used_mipmaps = has_mipmaps();
1197 	if (used_mipmaps) {
1198 		clear_mipmaps();
1199 	}
1200 
1201 	{
1202 		PoolVector<uint8_t>::Write w = data.write();
1203 		uint8_t up[16];
1204 		uint8_t down[16];
1205 		uint32_t pixel_size = get_format_pixel_size(format);
1206 
1207 		for (int y = 0; y < height; y++) {
1208 
1209 			for (int x = 0; x < width / 2; x++) {
1210 
1211 				_get_pixelb(x, y, pixel_size, w.ptr(), up);
1212 				_get_pixelb(width - x - 1, y, pixel_size, w.ptr(), down);
1213 
1214 				_put_pixelb(width - x - 1, y, pixel_size, w.ptr(), up);
1215 				_put_pixelb(x, y, pixel_size, w.ptr(), down);
1216 			}
1217 		}
1218 	}
1219 
1220 	if (used_mipmaps) {
1221 		generate_mipmaps();
1222 	}
1223 }
1224 
_get_dst_image_size(int p_width,int p_height,Format p_format,int & r_mipmaps,int p_mipmaps)1225 int Image::_get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps) {
1226 
1227 	int size = 0;
1228 	int w = p_width;
1229 	int h = p_height;
1230 	int mm = 0;
1231 
1232 	int pixsize = get_format_pixel_size(p_format);
1233 	int pixshift = get_format_pixel_rshift(p_format);
1234 	int block = get_format_block_size(p_format);
1235 	//technically, you can still compress up to 1 px no matter the format, so commenting this
1236 	//int minw, minh;
1237 	//get_format_min_pixel_size(p_format, minw, minh);
1238 	int minw = 1, minh = 1;
1239 
1240 	while (true) {
1241 
1242 		int bw = w % block != 0 ? w + (block - w % block) : w;
1243 		int bh = h % block != 0 ? h + (block - h % block) : h;
1244 
1245 		int s = bw * bh;
1246 
1247 		s *= pixsize;
1248 		s >>= pixshift;
1249 
1250 		size += s;
1251 
1252 		if (p_mipmaps >= 0 && mm == p_mipmaps)
1253 			break;
1254 
1255 		if (p_mipmaps >= 0) {
1256 
1257 			w = MAX(minw, w >> 1);
1258 			h = MAX(minh, h >> 1);
1259 		} else {
1260 			if (w == minw && h == minh)
1261 				break;
1262 			w = MAX(minw, w >> 1);
1263 			h = MAX(minh, h >> 1);
1264 		}
1265 		mm++;
1266 	};
1267 
1268 	r_mipmaps = mm;
1269 	return size;
1270 }
1271 
_can_modify(Format p_format) const1272 bool Image::_can_modify(Format p_format) const {
1273 
1274 	return p_format <= FORMAT_RGBE9995;
1275 }
1276 
1277 template <class Component, int CC, bool renormalize,
1278 		void (*average_func)(Component &, const Component &, const Component &, const Component &, const Component &),
1279 		void (*renormalize_func)(Component *)>
_generate_po2_mipmap(const Component * p_src,Component * p_dst,uint32_t p_width,uint32_t p_height)1280 static void _generate_po2_mipmap(const Component *p_src, Component *p_dst, uint32_t p_width, uint32_t p_height) {
1281 
1282 	//fast power of 2 mipmap generation
1283 	uint32_t dst_w = MAX(p_width >> 1, 1);
1284 	uint32_t dst_h = MAX(p_height >> 1, 1);
1285 
1286 	int right_step = (p_width == 1) ? 0 : CC;
1287 	int down_step = (p_height == 1) ? 0 : (p_width * CC);
1288 
1289 	for (uint32_t i = 0; i < dst_h; i++) {
1290 
1291 		const Component *rup_ptr = &p_src[i * 2 * down_step];
1292 		const Component *rdown_ptr = rup_ptr + down_step;
1293 		Component *dst_ptr = &p_dst[i * dst_w * CC];
1294 		uint32_t count = dst_w;
1295 
1296 		while (count) {
1297 			count--;
1298 			for (int j = 0; j < CC; j++) {
1299 				average_func(dst_ptr[j], rup_ptr[j], rup_ptr[j + right_step], rdown_ptr[j], rdown_ptr[j + right_step]);
1300 			}
1301 
1302 			if (renormalize) {
1303 				renormalize_func(dst_ptr);
1304 			}
1305 
1306 			dst_ptr += CC;
1307 			rup_ptr += right_step * 2;
1308 			rdown_ptr += right_step * 2;
1309 		}
1310 	}
1311 }
1312 
expand_x2_hq2x()1313 void Image::expand_x2_hq2x() {
1314 
1315 	ERR_FAIL_COND(!_can_modify(format));
1316 
1317 	bool used_mipmaps = has_mipmaps();
1318 	if (used_mipmaps) {
1319 		clear_mipmaps();
1320 	}
1321 
1322 	Format current = format;
1323 
1324 	if (current != FORMAT_RGBA8)
1325 		convert(FORMAT_RGBA8);
1326 
1327 	PoolVector<uint8_t> dest;
1328 	dest.resize(width * 2 * height * 2 * 4);
1329 
1330 	{
1331 		PoolVector<uint8_t>::Read r = data.read();
1332 		PoolVector<uint8_t>::Write w = dest.write();
1333 
1334 		ERR_FAIL_COND(!r.ptr());
1335 
1336 		hq2x_resize((const uint32_t *)r.ptr(), width, height, (uint32_t *)w.ptr());
1337 	}
1338 
1339 	width *= 2;
1340 	height *= 2;
1341 	data = dest;
1342 
1343 	if (current != FORMAT_RGBA8)
1344 		convert(current);
1345 
1346 	// FIXME: This is likely meant to use "used_mipmaps" as defined above, but if we do,
1347 	// we end up with a regression: GH-22747
1348 	if (mipmaps) {
1349 		generate_mipmaps();
1350 	}
1351 }
1352 
shrink_x2()1353 void Image::shrink_x2() {
1354 
1355 	ERR_FAIL_COND(data.size() == 0);
1356 
1357 	if (mipmaps) {
1358 
1359 		//just use the lower mipmap as base and copy all
1360 		PoolVector<uint8_t> new_img;
1361 
1362 		int ofs = get_mipmap_offset(1);
1363 
1364 		int new_size = data.size() - ofs;
1365 		new_img.resize(new_size);
1366 		ERR_FAIL_COND(new_img.size() == 0);
1367 
1368 		{
1369 			PoolVector<uint8_t>::Write w = new_img.write();
1370 			PoolVector<uint8_t>::Read r = data.read();
1371 
1372 			copymem(w.ptr(), &r[ofs], new_size);
1373 		}
1374 
1375 		width = MAX(width / 2, 1);
1376 		height = MAX(height / 2, 1);
1377 		data = new_img;
1378 
1379 	} else {
1380 
1381 		PoolVector<uint8_t> new_img;
1382 
1383 		ERR_FAIL_COND(!_can_modify(format));
1384 		int ps = get_format_pixel_size(format);
1385 		new_img.resize((width / 2) * (height / 2) * ps);
1386 		ERR_FAIL_COND(new_img.size() == 0);
1387 		ERR_FAIL_COND(data.size() == 0);
1388 
1389 		{
1390 			PoolVector<uint8_t>::Write w = new_img.write();
1391 			PoolVector<uint8_t>::Read r = data.read();
1392 
1393 			switch (format) {
1394 
1395 				case FORMAT_L8:
1396 				case FORMAT_R8: _generate_po2_mipmap<uint8_t, 1, false, Image::average_4_uint8, Image::renormalize_uint8>(r.ptr(), w.ptr(), width, height); break;
1397 				case FORMAT_LA8: _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(r.ptr(), w.ptr(), width, height); break;
1398 				case FORMAT_RG8: _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(r.ptr(), w.ptr(), width, height); break;
1399 				case FORMAT_RGB8: _generate_po2_mipmap<uint8_t, 3, false, Image::average_4_uint8, Image::renormalize_uint8>(r.ptr(), w.ptr(), width, height); break;
1400 				case FORMAT_RGBA8: _generate_po2_mipmap<uint8_t, 4, false, Image::average_4_uint8, Image::renormalize_uint8>(r.ptr(), w.ptr(), width, height); break;
1401 
1402 				case FORMAT_RF: _generate_po2_mipmap<float, 1, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r.ptr()), reinterpret_cast<float *>(w.ptr()), width, height); break;
1403 				case FORMAT_RGF: _generate_po2_mipmap<float, 2, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r.ptr()), reinterpret_cast<float *>(w.ptr()), width, height); break;
1404 				case FORMAT_RGBF: _generate_po2_mipmap<float, 3, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r.ptr()), reinterpret_cast<float *>(w.ptr()), width, height); break;
1405 				case FORMAT_RGBAF: _generate_po2_mipmap<float, 4, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r.ptr()), reinterpret_cast<float *>(w.ptr()), width, height); break;
1406 
1407 				case FORMAT_RH: _generate_po2_mipmap<uint16_t, 1, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r.ptr()), reinterpret_cast<uint16_t *>(w.ptr()), width, height); break;
1408 				case FORMAT_RGH: _generate_po2_mipmap<uint16_t, 2, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r.ptr()), reinterpret_cast<uint16_t *>(w.ptr()), width, height); break;
1409 				case FORMAT_RGBH: _generate_po2_mipmap<uint16_t, 3, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r.ptr()), reinterpret_cast<uint16_t *>(w.ptr()), width, height); break;
1410 				case FORMAT_RGBAH: _generate_po2_mipmap<uint16_t, 4, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r.ptr()), reinterpret_cast<uint16_t *>(w.ptr()), width, height); break;
1411 
1412 				case FORMAT_RGBE9995: _generate_po2_mipmap<uint32_t, 1, false, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(reinterpret_cast<const uint32_t *>(r.ptr()), reinterpret_cast<uint32_t *>(w.ptr()), width, height); break;
1413 				default: {
1414 				}
1415 			}
1416 		}
1417 
1418 		width /= 2;
1419 		height /= 2;
1420 		data = new_img;
1421 	}
1422 }
1423 
normalize()1424 void Image::normalize() {
1425 
1426 	bool used_mipmaps = has_mipmaps();
1427 	if (used_mipmaps) {
1428 		clear_mipmaps();
1429 	}
1430 
1431 	lock();
1432 
1433 	for (int y = 0; y < height; y++) {
1434 
1435 		for (int x = 0; x < width; x++) {
1436 
1437 			Color c = get_pixel(x, y);
1438 			Vector3 v(c.r * 2.0 - 1.0, c.g * 2.0 - 1.0, c.b * 2.0 - 1.0);
1439 			v.normalize();
1440 			c.r = v.x * 0.5 + 0.5;
1441 			c.g = v.y * 0.5 + 0.5;
1442 			c.b = v.z * 0.5 + 0.5;
1443 			set_pixel(x, y, c);
1444 		}
1445 	}
1446 
1447 	unlock();
1448 
1449 	if (used_mipmaps) {
1450 		generate_mipmaps(true);
1451 	}
1452 }
1453 
generate_mipmaps(bool p_renormalize)1454 Error Image::generate_mipmaps(bool p_renormalize) {
1455 
1456 	ERR_FAIL_COND_V_MSG(!_can_modify(format), ERR_UNAVAILABLE, "Cannot generate mipmaps in compressed or custom image formats.");
1457 
1458 	ERR_FAIL_COND_V_MSG(format == FORMAT_RGBA4444 || format == FORMAT_RGBA5551, ERR_UNAVAILABLE, "Cannot generate mipmaps in custom image formats.");
1459 
1460 	ERR_FAIL_COND_V_MSG(width == 0 || height == 0, ERR_UNCONFIGURED, "Cannot generate mipmaps with width or height equal to 0.");
1461 
1462 	int mmcount;
1463 
1464 	int size = _get_dst_image_size(width, height, format, mmcount);
1465 
1466 	data.resize(size);
1467 
1468 	PoolVector<uint8_t>::Write wp = data.write();
1469 
1470 	int prev_ofs = 0;
1471 	int prev_h = height;
1472 	int prev_w = width;
1473 
1474 	for (int i = 1; i <= mmcount; i++) {
1475 
1476 		int ofs, w, h;
1477 		_get_mipmap_offset_and_size(i, ofs, w, h);
1478 
1479 		switch (format) {
1480 
1481 			case FORMAT_L8:
1482 			case FORMAT_R8: _generate_po2_mipmap<uint8_t, 1, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); break;
1483 			case FORMAT_LA8:
1484 			case FORMAT_RG8: _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); break;
1485 			case FORMAT_RGB8:
1486 				if (p_renormalize)
1487 					_generate_po2_mipmap<uint8_t, 3, true, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h);
1488 				else
1489 					_generate_po2_mipmap<uint8_t, 3, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h);
1490 
1491 				break;
1492 			case FORMAT_RGBA8:
1493 				if (p_renormalize)
1494 					_generate_po2_mipmap<uint8_t, 4, true, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h);
1495 				else
1496 					_generate_po2_mipmap<uint8_t, 4, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h);
1497 				break;
1498 			case FORMAT_RF:
1499 				_generate_po2_mipmap<float, 1, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h);
1500 				break;
1501 			case FORMAT_RGF:
1502 				_generate_po2_mipmap<float, 2, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h);
1503 				break;
1504 			case FORMAT_RGBF:
1505 				if (p_renormalize)
1506 					_generate_po2_mipmap<float, 3, true, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h);
1507 				else
1508 					_generate_po2_mipmap<float, 3, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h);
1509 
1510 				break;
1511 			case FORMAT_RGBAF:
1512 				if (p_renormalize)
1513 					_generate_po2_mipmap<float, 4, true, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h);
1514 				else
1515 					_generate_po2_mipmap<float, 4, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h);
1516 
1517 				break;
1518 			case FORMAT_RH:
1519 				_generate_po2_mipmap<uint16_t, 1, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h);
1520 				break;
1521 			case FORMAT_RGH:
1522 				_generate_po2_mipmap<uint16_t, 2, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h);
1523 				break;
1524 			case FORMAT_RGBH:
1525 				if (p_renormalize)
1526 					_generate_po2_mipmap<uint16_t, 3, true, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h);
1527 				else
1528 					_generate_po2_mipmap<uint16_t, 3, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h);
1529 
1530 				break;
1531 			case FORMAT_RGBAH:
1532 				if (p_renormalize)
1533 					_generate_po2_mipmap<uint16_t, 4, true, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h);
1534 				else
1535 					_generate_po2_mipmap<uint16_t, 4, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h);
1536 
1537 				break;
1538 			case FORMAT_RGBE9995:
1539 				if (p_renormalize)
1540 					_generate_po2_mipmap<uint32_t, 1, true, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(reinterpret_cast<const uint32_t *>(&wp[prev_ofs]), reinterpret_cast<uint32_t *>(&wp[ofs]), prev_w, prev_h);
1541 				else
1542 					_generate_po2_mipmap<uint32_t, 1, false, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(reinterpret_cast<const uint32_t *>(&wp[prev_ofs]), reinterpret_cast<uint32_t *>(&wp[ofs]), prev_w, prev_h);
1543 
1544 				break;
1545 			default: {
1546 			}
1547 		}
1548 
1549 		prev_ofs = ofs;
1550 		prev_w = w;
1551 		prev_h = h;
1552 	}
1553 
1554 	mipmaps = true;
1555 
1556 	return OK;
1557 }
1558 
clear_mipmaps()1559 void Image::clear_mipmaps() {
1560 
1561 	if (!mipmaps)
1562 		return;
1563 
1564 	if (empty())
1565 		return;
1566 
1567 	int ofs, w, h;
1568 	_get_mipmap_offset_and_size(1, ofs, w, h);
1569 	data.resize(ofs);
1570 
1571 	mipmaps = false;
1572 }
1573 
empty() const1574 bool Image::empty() const {
1575 
1576 	return (data.size() == 0);
1577 }
1578 
get_data() const1579 PoolVector<uint8_t> Image::get_data() const {
1580 
1581 	return data;
1582 }
1583 
create(int p_width,int p_height,bool p_use_mipmaps,Format p_format)1584 void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_format) {
1585 	ERR_FAIL_COND_MSG(p_width <= 0, "Image width must be greater than 0.");
1586 	ERR_FAIL_COND_MSG(p_height <= 0, "Image height must be greater than 0.");
1587 	ERR_FAIL_COND_MSG(p_width > MAX_WIDTH, "Image width cannot be greater than " + itos(MAX_WIDTH) + ".");
1588 	ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT, "Image height cannot be greater than " + itos(MAX_HEIGHT) + ".");
1589 	ERR_FAIL_COND_MSG(write_lock.ptr(), "Cannot create image when it is locked.");
1590 
1591 	int mm = 0;
1592 	int size = _get_dst_image_size(p_width, p_height, p_format, mm, p_use_mipmaps ? -1 : 0);
1593 	data.resize(size);
1594 	{
1595 		PoolVector<uint8_t>::Write w = data.write();
1596 		zeromem(w.ptr(), size);
1597 	}
1598 
1599 	width = p_width;
1600 	height = p_height;
1601 	mipmaps = p_use_mipmaps;
1602 	format = p_format;
1603 }
1604 
create(int p_width,int p_height,bool p_use_mipmaps,Format p_format,const PoolVector<uint8_t> & p_data)1605 void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const PoolVector<uint8_t> &p_data) {
1606 	ERR_FAIL_COND_MSG(p_width <= 0, "Image width must be greater than 0.");
1607 	ERR_FAIL_COND_MSG(p_height <= 0, "Image height must be greater than 0.");
1608 	ERR_FAIL_COND_MSG(p_width > MAX_WIDTH, "Image width cannot be greater than " + itos(MAX_WIDTH) + ".");
1609 	ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT, "Image height cannot be greater than " + itos(MAX_HEIGHT) + ".");
1610 
1611 	int mm;
1612 	int size = _get_dst_image_size(p_width, p_height, p_format, mm, p_use_mipmaps ? -1 : 0);
1613 
1614 	ERR_FAIL_COND_MSG(p_data.size() != size, "Expected data size of " + itos(size) + " bytes in Image::create(), got instead " + itos(p_data.size()) + " bytes.");
1615 
1616 	height = p_height;
1617 	width = p_width;
1618 	format = p_format;
1619 	data = p_data;
1620 	mipmaps = p_use_mipmaps;
1621 }
1622 
create(const char ** p_xpm)1623 void Image::create(const char **p_xpm) {
1624 
1625 	int size_width = 0;
1626 	int size_height = 0;
1627 	int pixelchars = 0;
1628 	mipmaps = false;
1629 	bool has_alpha = false;
1630 
1631 	enum Status {
1632 		READING_HEADER,
1633 		READING_COLORS,
1634 		READING_PIXELS,
1635 		DONE
1636 	};
1637 
1638 	Status status = READING_HEADER;
1639 	int line = 0;
1640 
1641 	HashMap<String, Color> colormap;
1642 	int colormap_size = 0;
1643 	uint32_t pixel_size = 0;
1644 	PoolVector<uint8_t>::Write w;
1645 
1646 	while (status != DONE) {
1647 
1648 		const char *line_ptr = p_xpm[line];
1649 
1650 		switch (status) {
1651 
1652 			case READING_HEADER: {
1653 
1654 				String line_str = line_ptr;
1655 				line_str.replace("\t", " ");
1656 
1657 				size_width = line_str.get_slicec(' ', 0).to_int();
1658 				size_height = line_str.get_slicec(' ', 1).to_int();
1659 				colormap_size = line_str.get_slicec(' ', 2).to_int();
1660 				pixelchars = line_str.get_slicec(' ', 3).to_int();
1661 				ERR_FAIL_COND(colormap_size > 32766);
1662 				ERR_FAIL_COND(pixelchars > 5);
1663 				ERR_FAIL_COND(size_width > 32767);
1664 				ERR_FAIL_COND(size_height > 32767);
1665 				status = READING_COLORS;
1666 			} break;
1667 			case READING_COLORS: {
1668 
1669 				String colorstring;
1670 				for (int i = 0; i < pixelchars; i++) {
1671 
1672 					colorstring += *line_ptr;
1673 					line_ptr++;
1674 				}
1675 				//skip spaces
1676 				while (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == 0) {
1677 					if (*line_ptr == 0)
1678 						break;
1679 					line_ptr++;
1680 				}
1681 				if (*line_ptr == 'c') {
1682 
1683 					line_ptr++;
1684 					while (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == 0) {
1685 						if (*line_ptr == 0)
1686 							break;
1687 						line_ptr++;
1688 					}
1689 
1690 					if (*line_ptr == '#') {
1691 						line_ptr++;
1692 						uint8_t col_r = 0;
1693 						uint8_t col_g = 0;
1694 						uint8_t col_b = 0;
1695 						//uint8_t col_a=255;
1696 
1697 						for (int i = 0; i < 6; i++) {
1698 
1699 							char v = line_ptr[i];
1700 
1701 							if (v >= '0' && v <= '9')
1702 								v -= '0';
1703 							else if (v >= 'A' && v <= 'F')
1704 								v = (v - 'A') + 10;
1705 							else if (v >= 'a' && v <= 'f')
1706 								v = (v - 'a') + 10;
1707 							else
1708 								break;
1709 
1710 							switch (i) {
1711 								case 0: col_r = v << 4; break;
1712 								case 1: col_r |= v; break;
1713 								case 2: col_g = v << 4; break;
1714 								case 3: col_g |= v; break;
1715 								case 4: col_b = v << 4; break;
1716 								case 5: col_b |= v; break;
1717 							};
1718 						}
1719 
1720 						// magenta mask
1721 						if (col_r == 255 && col_g == 0 && col_b == 255) {
1722 
1723 							colormap[colorstring] = Color(0, 0, 0, 0);
1724 							has_alpha = true;
1725 						} else {
1726 
1727 							colormap[colorstring] = Color(col_r / 255.0, col_g / 255.0, col_b / 255.0, 1.0);
1728 						}
1729 					}
1730 				}
1731 				if (line == colormap_size) {
1732 
1733 					status = READING_PIXELS;
1734 					create(size_width, size_height, 0, has_alpha ? FORMAT_RGBA8 : FORMAT_RGB8);
1735 					w = data.write();
1736 					pixel_size = has_alpha ? 4 : 3;
1737 				}
1738 			} break;
1739 			case READING_PIXELS: {
1740 
1741 				int y = line - colormap_size - 1;
1742 				for (int x = 0; x < size_width; x++) {
1743 
1744 					char pixelstr[6] = { 0, 0, 0, 0, 0, 0 };
1745 					for (int i = 0; i < pixelchars; i++)
1746 						pixelstr[i] = line_ptr[x * pixelchars + i];
1747 
1748 					Color *colorptr = colormap.getptr(pixelstr);
1749 					ERR_FAIL_COND(!colorptr);
1750 					uint8_t pixel[4];
1751 					for (uint32_t i = 0; i < pixel_size; i++) {
1752 						pixel[i] = CLAMP((*colorptr)[i] * 255, 0, 255);
1753 					}
1754 					_put_pixelb(x, y, pixel_size, w.ptr(), pixel);
1755 				}
1756 
1757 				if (y == (size_height - 1))
1758 					status = DONE;
1759 			} break;
1760 			default: {
1761 			}
1762 		}
1763 
1764 		line++;
1765 	}
1766 }
1767 #define DETECT_ALPHA_MAX_THRESHOLD 254
1768 #define DETECT_ALPHA_MIN_THRESHOLD 2
1769 
1770 #define DETECT_ALPHA(m_value)                          \
1771 	{                                                  \
1772 		uint8_t value = m_value;                       \
1773 		if (value < DETECT_ALPHA_MIN_THRESHOLD)        \
1774 			bit = true;                                \
1775 		else if (value < DETECT_ALPHA_MAX_THRESHOLD) { \
1776                                                        \
1777 			detected = true;                           \
1778 			break;                                     \
1779 		}                                              \
1780 	}
1781 
1782 #define DETECT_NON_ALPHA(m_value) \
1783 	{                             \
1784 		uint8_t value = m_value;  \
1785 		if (value > 0) {          \
1786                                   \
1787 			detected = true;      \
1788 			break;                \
1789 		}                         \
1790 	}
1791 
is_invisible() const1792 bool Image::is_invisible() const {
1793 
1794 	if (format == FORMAT_L8 ||
1795 			format == FORMAT_RGB8 || format == FORMAT_RG8)
1796 		return false;
1797 
1798 	int len = data.size();
1799 
1800 	if (len == 0)
1801 		return true;
1802 
1803 	int w, h;
1804 	_get_mipmap_offset_and_size(1, len, w, h);
1805 
1806 	PoolVector<uint8_t>::Read r = data.read();
1807 	const unsigned char *data_ptr = r.ptr();
1808 
1809 	bool detected = false;
1810 
1811 	switch (format) {
1812 
1813 		case FORMAT_LA8: {
1814 
1815 			for (int i = 0; i < (len >> 1); i++) {
1816 				DETECT_NON_ALPHA(data_ptr[(i << 1) + 1]);
1817 			}
1818 
1819 		} break;
1820 		case FORMAT_RGBA8: {
1821 
1822 			for (int i = 0; i < (len >> 2); i++) {
1823 				DETECT_NON_ALPHA(data_ptr[(i << 2) + 3])
1824 			}
1825 
1826 		} break;
1827 
1828 		case FORMAT_PVRTC2A:
1829 		case FORMAT_PVRTC4A:
1830 		case FORMAT_DXT3:
1831 		case FORMAT_DXT5: {
1832 			detected = true;
1833 		} break;
1834 		default: {
1835 		}
1836 	}
1837 
1838 	return !detected;
1839 }
1840 
detect_alpha() const1841 Image::AlphaMode Image::detect_alpha() const {
1842 
1843 	int len = data.size();
1844 
1845 	if (len == 0)
1846 		return ALPHA_NONE;
1847 
1848 	int w, h;
1849 	_get_mipmap_offset_and_size(1, len, w, h);
1850 
1851 	PoolVector<uint8_t>::Read r = data.read();
1852 	const unsigned char *data_ptr = r.ptr();
1853 
1854 	bool bit = false;
1855 	bool detected = false;
1856 
1857 	switch (format) {
1858 
1859 		case FORMAT_LA8: {
1860 
1861 			for (int i = 0; i < (len >> 1); i++) {
1862 				DETECT_ALPHA(data_ptr[(i << 1) + 1]);
1863 			}
1864 
1865 		} break;
1866 		case FORMAT_RGBA8: {
1867 
1868 			for (int i = 0; i < (len >> 2); i++) {
1869 				DETECT_ALPHA(data_ptr[(i << 2) + 3])
1870 			}
1871 
1872 		} break;
1873 		case FORMAT_PVRTC2A:
1874 		case FORMAT_PVRTC4A:
1875 		case FORMAT_DXT3:
1876 		case FORMAT_DXT5: {
1877 			detected = true;
1878 		} break;
1879 		default: {
1880 		}
1881 	}
1882 
1883 	if (detected)
1884 		return ALPHA_BLEND;
1885 	else if (bit)
1886 		return ALPHA_BIT;
1887 	else
1888 		return ALPHA_NONE;
1889 }
1890 
load(const String & p_path)1891 Error Image::load(const String &p_path) {
1892 #ifdef DEBUG_ENABLED
1893 	if (p_path.begins_with("res://") && ResourceLoader::exists(p_path)) {
1894 		WARN_PRINTS("Loaded resource as image file, this will not work on export: '" + p_path + "'. Instead, import the image file as an Image resource and load it normally as a resource.");
1895 	}
1896 #endif
1897 	return ImageLoader::load_image(p_path, this);
1898 }
1899 
save_png(const String & p_path) const1900 Error Image::save_png(const String &p_path) const {
1901 
1902 	if (save_png_func == NULL)
1903 		return ERR_UNAVAILABLE;
1904 
1905 	return save_png_func(p_path, Ref<Image>((Image *)this));
1906 }
1907 
save_png_to_buffer() const1908 PoolVector<uint8_t> Image::save_png_to_buffer() const {
1909 	if (save_png_buffer_func == NULL) {
1910 		return PoolVector<uint8_t>();
1911 	}
1912 
1913 	return save_png_buffer_func(Ref<Image>((Image *)this));
1914 }
1915 
save_exr(const String & p_path,bool p_grayscale) const1916 Error Image::save_exr(const String &p_path, bool p_grayscale) const {
1917 
1918 	if (save_exr_func == NULL)
1919 		return ERR_UNAVAILABLE;
1920 
1921 	return save_exr_func(p_path, Ref<Image>((Image *)this), p_grayscale);
1922 }
1923 
get_image_data_size(int p_width,int p_height,Format p_format,bool p_mipmaps)1924 int Image::get_image_data_size(int p_width, int p_height, Format p_format, bool p_mipmaps) {
1925 
1926 	int mm;
1927 	return _get_dst_image_size(p_width, p_height, p_format, mm, p_mipmaps ? -1 : 0);
1928 }
1929 
get_image_required_mipmaps(int p_width,int p_height,Format p_format)1930 int Image::get_image_required_mipmaps(int p_width, int p_height, Format p_format) {
1931 
1932 	int mm;
1933 	_get_dst_image_size(p_width, p_height, p_format, mm, -1);
1934 	return mm;
1935 }
1936 
get_image_mipmap_offset(int p_width,int p_height,Format p_format,int p_mipmap)1937 int Image::get_image_mipmap_offset(int p_width, int p_height, Format p_format, int p_mipmap) {
1938 
1939 	if (p_mipmap <= 0) {
1940 		return 0;
1941 	}
1942 	int mm;
1943 	return _get_dst_image_size(p_width, p_height, p_format, mm, p_mipmap - 1);
1944 }
1945 
is_compressed() const1946 bool Image::is_compressed() const {
1947 	return format > FORMAT_RGBE9995;
1948 }
1949 
decompress()1950 Error Image::decompress() {
1951 
1952 	if (format >= FORMAT_DXT1 && format <= FORMAT_RGTC_RG && _image_decompress_bc)
1953 		_image_decompress_bc(this);
1954 	else if (format >= FORMAT_BPTC_RGBA && format <= FORMAT_BPTC_RGBFU && _image_decompress_bptc)
1955 		_image_decompress_bptc(this);
1956 	else if (format >= FORMAT_PVRTC2 && format <= FORMAT_PVRTC4A && _image_decompress_pvrtc)
1957 		_image_decompress_pvrtc(this);
1958 	else if (format == FORMAT_ETC && _image_decompress_etc1)
1959 		_image_decompress_etc1(this);
1960 	else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RGB8A1 && _image_decompress_etc2)
1961 		_image_decompress_etc2(this);
1962 	else
1963 		return ERR_UNAVAILABLE;
1964 	return OK;
1965 }
1966 
compress(CompressMode p_mode,CompressSource p_source,float p_lossy_quality)1967 Error Image::compress(CompressMode p_mode, CompressSource p_source, float p_lossy_quality) {
1968 
1969 	switch (p_mode) {
1970 
1971 		case COMPRESS_S3TC: {
1972 
1973 			ERR_FAIL_COND_V(!_image_compress_bc_func, ERR_UNAVAILABLE);
1974 			_image_compress_bc_func(this, p_lossy_quality, p_source);
1975 		} break;
1976 		case COMPRESS_PVRTC2: {
1977 
1978 			ERR_FAIL_COND_V(!_image_compress_pvrtc2_func, ERR_UNAVAILABLE);
1979 			_image_compress_pvrtc2_func(this);
1980 		} break;
1981 		case COMPRESS_PVRTC4: {
1982 
1983 			ERR_FAIL_COND_V(!_image_compress_pvrtc4_func, ERR_UNAVAILABLE);
1984 			_image_compress_pvrtc4_func(this);
1985 		} break;
1986 		case COMPRESS_ETC: {
1987 
1988 			ERR_FAIL_COND_V(!_image_compress_etc1_func, ERR_UNAVAILABLE);
1989 			_image_compress_etc1_func(this, p_lossy_quality);
1990 		} break;
1991 		case COMPRESS_ETC2: {
1992 
1993 			ERR_FAIL_COND_V(!_image_compress_etc2_func, ERR_UNAVAILABLE);
1994 			_image_compress_etc2_func(this, p_lossy_quality, p_source);
1995 		} break;
1996 		case COMPRESS_BPTC: {
1997 
1998 			ERR_FAIL_COND_V(!_image_compress_bptc_func, ERR_UNAVAILABLE);
1999 			_image_compress_bptc_func(this, p_lossy_quality, p_source);
2000 		} break;
2001 	}
2002 
2003 	return OK;
2004 }
2005 
Image(const char ** p_xpm)2006 Image::Image(const char **p_xpm) {
2007 
2008 	width = 0;
2009 	height = 0;
2010 	mipmaps = false;
2011 	format = FORMAT_L8;
2012 
2013 	create(p_xpm);
2014 }
2015 
Image(int p_width,int p_height,bool p_use_mipmaps,Format p_format)2016 Image::Image(int p_width, int p_height, bool p_use_mipmaps, Format p_format) {
2017 
2018 	width = 0;
2019 	height = 0;
2020 	mipmaps = p_use_mipmaps;
2021 	format = FORMAT_L8;
2022 
2023 	create(p_width, p_height, p_use_mipmaps, p_format);
2024 }
2025 
Image(int p_width,int p_height,bool p_mipmaps,Format p_format,const PoolVector<uint8_t> & p_data)2026 Image::Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const PoolVector<uint8_t> &p_data) {
2027 
2028 	width = 0;
2029 	height = 0;
2030 	mipmaps = p_mipmaps;
2031 	format = FORMAT_L8;
2032 
2033 	create(p_width, p_height, p_mipmaps, p_format, p_data);
2034 }
2035 
get_used_rect() const2036 Rect2 Image::get_used_rect() const {
2037 
2038 	if (format != FORMAT_LA8 && format != FORMAT_RGBA8 && format != FORMAT_RGBAF && format != FORMAT_RGBAH && format != FORMAT_RGBA4444 && format != FORMAT_RGBA5551)
2039 		return Rect2(Point2(), Size2(width, height));
2040 
2041 	int len = data.size();
2042 
2043 	if (len == 0)
2044 		return Rect2();
2045 
2046 	const_cast<Image *>(this)->lock();
2047 	int minx = 0xFFFFFF, miny = 0xFFFFFFF;
2048 	int maxx = -1, maxy = -1;
2049 	for (int j = 0; j < height; j++) {
2050 		for (int i = 0; i < width; i++) {
2051 
2052 			if (!(get_pixel(i, j).a > 0))
2053 				continue;
2054 			if (i > maxx)
2055 				maxx = i;
2056 			if (j > maxy)
2057 				maxy = j;
2058 			if (i < minx)
2059 				minx = i;
2060 			if (j < miny)
2061 				miny = j;
2062 		}
2063 	}
2064 
2065 	const_cast<Image *>(this)->unlock();
2066 
2067 	if (maxx == -1)
2068 		return Rect2();
2069 	else
2070 		return Rect2(minx, miny, maxx - minx + 1, maxy - miny + 1);
2071 }
2072 
get_rect(const Rect2 & p_area) const2073 Ref<Image> Image::get_rect(const Rect2 &p_area) const {
2074 
2075 	Ref<Image> img = memnew(Image(p_area.size.x, p_area.size.y, mipmaps, format));
2076 	img->blit_rect(Ref<Image>((Image *)this), p_area, Point2(0, 0));
2077 	return img;
2078 }
2079 
blit_rect(const Ref<Image> & p_src,const Rect2 & p_src_rect,const Point2 & p_dest)2080 void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest) {
2081 
2082 	ERR_FAIL_COND_MSG(p_src.is_null(), "It's not a reference to a valid Image object.");
2083 	int dsize = data.size();
2084 	int srcdsize = p_src->data.size();
2085 	ERR_FAIL_COND(dsize == 0);
2086 	ERR_FAIL_COND(srcdsize == 0);
2087 	ERR_FAIL_COND(format != p_src->format);
2088 	ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot blit_rect in compressed or custom image formats.");
2089 
2090 	Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect);
2091 
2092 	if (p_dest.x < 0)
2093 		clipped_src_rect.position.x = ABS(p_dest.x);
2094 	if (p_dest.y < 0)
2095 		clipped_src_rect.position.y = ABS(p_dest.y);
2096 
2097 	if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
2098 		return;
2099 
2100 	Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
2101 	Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
2102 
2103 	PoolVector<uint8_t>::Write wp = data.write();
2104 	uint8_t *dst_data_ptr = wp.ptr();
2105 
2106 	PoolVector<uint8_t>::Read rp = p_src->data.read();
2107 	const uint8_t *src_data_ptr = rp.ptr();
2108 
2109 	int pixel_size = get_format_pixel_size(format);
2110 
2111 	for (int i = 0; i < dest_rect.size.y; i++) {
2112 
2113 		for (int j = 0; j < dest_rect.size.x; j++) {
2114 
2115 			int src_x = clipped_src_rect.position.x + j;
2116 			int src_y = clipped_src_rect.position.y + i;
2117 
2118 			int dst_x = dest_rect.position.x + j;
2119 			int dst_y = dest_rect.position.y + i;
2120 
2121 			const uint8_t *src = &src_data_ptr[(src_y * p_src->width + src_x) * pixel_size];
2122 			uint8_t *dst = &dst_data_ptr[(dst_y * width + dst_x) * pixel_size];
2123 
2124 			for (int k = 0; k < pixel_size; k++) {
2125 				dst[k] = src[k];
2126 			}
2127 		}
2128 	}
2129 }
2130 
blit_rect_mask(const Ref<Image> & p_src,const Ref<Image> & p_mask,const Rect2 & p_src_rect,const Point2 & p_dest)2131 void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest) {
2132 
2133 	ERR_FAIL_COND_MSG(p_src.is_null(), "It's not a reference to a valid Image object.");
2134 	ERR_FAIL_COND_MSG(p_mask.is_null(), "It's not a reference to a valid Image object.");
2135 	int dsize = data.size();
2136 	int srcdsize = p_src->data.size();
2137 	int maskdsize = p_mask->data.size();
2138 	ERR_FAIL_COND(dsize == 0);
2139 	ERR_FAIL_COND(srcdsize == 0);
2140 	ERR_FAIL_COND(maskdsize == 0);
2141 	ERR_FAIL_COND_MSG(p_src->width != p_mask->width, "Source image width is different from mask width.");
2142 	ERR_FAIL_COND_MSG(p_src->height != p_mask->height, "Source image height is different from mask height.");
2143 	ERR_FAIL_COND(format != p_src->format);
2144 
2145 	Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect);
2146 
2147 	if (p_dest.x < 0)
2148 		clipped_src_rect.position.x = ABS(p_dest.x);
2149 	if (p_dest.y < 0)
2150 		clipped_src_rect.position.y = ABS(p_dest.y);
2151 
2152 	if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
2153 		return;
2154 
2155 	Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
2156 	Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
2157 
2158 	PoolVector<uint8_t>::Write wp = data.write();
2159 	uint8_t *dst_data_ptr = wp.ptr();
2160 
2161 	PoolVector<uint8_t>::Read rp = p_src->data.read();
2162 	const uint8_t *src_data_ptr = rp.ptr();
2163 
2164 	int pixel_size = get_format_pixel_size(format);
2165 
2166 	Ref<Image> msk = p_mask;
2167 	msk->lock();
2168 
2169 	for (int i = 0; i < dest_rect.size.y; i++) {
2170 
2171 		for (int j = 0; j < dest_rect.size.x; j++) {
2172 
2173 			int src_x = clipped_src_rect.position.x + j;
2174 			int src_y = clipped_src_rect.position.y + i;
2175 
2176 			if (msk->get_pixel(src_x, src_y).a != 0) {
2177 
2178 				int dst_x = dest_rect.position.x + j;
2179 				int dst_y = dest_rect.position.y + i;
2180 
2181 				const uint8_t *src = &src_data_ptr[(src_y * p_src->width + src_x) * pixel_size];
2182 				uint8_t *dst = &dst_data_ptr[(dst_y * width + dst_x) * pixel_size];
2183 
2184 				for (int k = 0; k < pixel_size; k++) {
2185 					dst[k] = src[k];
2186 				}
2187 			}
2188 		}
2189 	}
2190 
2191 	msk->unlock();
2192 }
2193 
blend_rect(const Ref<Image> & p_src,const Rect2 & p_src_rect,const Point2 & p_dest)2194 void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest) {
2195 
2196 	ERR_FAIL_COND_MSG(p_src.is_null(), "It's not a reference to a valid Image object.");
2197 	int dsize = data.size();
2198 	int srcdsize = p_src->data.size();
2199 	ERR_FAIL_COND(dsize == 0);
2200 	ERR_FAIL_COND(srcdsize == 0);
2201 	ERR_FAIL_COND(format != p_src->format);
2202 
2203 	Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect);
2204 
2205 	if (p_dest.x < 0)
2206 		clipped_src_rect.position.x = ABS(p_dest.x);
2207 	if (p_dest.y < 0)
2208 		clipped_src_rect.position.y = ABS(p_dest.y);
2209 
2210 	if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
2211 		return;
2212 
2213 	Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
2214 	Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
2215 
2216 	lock();
2217 	Ref<Image> img = p_src;
2218 	img->lock();
2219 
2220 	for (int i = 0; i < dest_rect.size.y; i++) {
2221 
2222 		for (int j = 0; j < dest_rect.size.x; j++) {
2223 
2224 			int src_x = clipped_src_rect.position.x + j;
2225 			int src_y = clipped_src_rect.position.y + i;
2226 
2227 			int dst_x = dest_rect.position.x + j;
2228 			int dst_y = dest_rect.position.y + i;
2229 
2230 			Color sc = img->get_pixel(src_x, src_y);
2231 			if (sc.a != 0) {
2232 				Color dc = get_pixel(dst_x, dst_y);
2233 				dc = dc.blend(sc);
2234 				set_pixel(dst_x, dst_y, dc);
2235 			}
2236 		}
2237 	}
2238 
2239 	img->unlock();
2240 	unlock();
2241 }
2242 
blend_rect_mask(const Ref<Image> & p_src,const Ref<Image> & p_mask,const Rect2 & p_src_rect,const Point2 & p_dest)2243 void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest) {
2244 
2245 	ERR_FAIL_COND_MSG(p_src.is_null(), "It's not a reference to a valid Image object.");
2246 	ERR_FAIL_COND_MSG(p_mask.is_null(), "It's not a reference to a valid Image object.");
2247 	int dsize = data.size();
2248 	int srcdsize = p_src->data.size();
2249 	int maskdsize = p_mask->data.size();
2250 	ERR_FAIL_COND(dsize == 0);
2251 	ERR_FAIL_COND(srcdsize == 0);
2252 	ERR_FAIL_COND(maskdsize == 0);
2253 	ERR_FAIL_COND_MSG(p_src->width != p_mask->width, "Source image width is different from mask width.");
2254 	ERR_FAIL_COND_MSG(p_src->height != p_mask->height, "Source image height is different from mask height.");
2255 	ERR_FAIL_COND(format != p_src->format);
2256 
2257 	Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect);
2258 
2259 	if (p_dest.x < 0)
2260 		clipped_src_rect.position.x = ABS(p_dest.x);
2261 	if (p_dest.y < 0)
2262 		clipped_src_rect.position.y = ABS(p_dest.y);
2263 
2264 	if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
2265 		return;
2266 
2267 	Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
2268 	Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
2269 
2270 	lock();
2271 	Ref<Image> img = p_src;
2272 	Ref<Image> msk = p_mask;
2273 	img->lock();
2274 	msk->lock();
2275 
2276 	for (int i = 0; i < dest_rect.size.y; i++) {
2277 
2278 		for (int j = 0; j < dest_rect.size.x; j++) {
2279 
2280 			int src_x = clipped_src_rect.position.x + j;
2281 			int src_y = clipped_src_rect.position.y + i;
2282 
2283 			// If the mask's pixel is transparent then we skip it
2284 			//Color c = msk->get_pixel(src_x, src_y);
2285 			//if (c.a == 0) continue;
2286 			if (msk->get_pixel(src_x, src_y).a != 0) {
2287 
2288 				int dst_x = dest_rect.position.x + j;
2289 				int dst_y = dest_rect.position.y + i;
2290 
2291 				Color sc = img->get_pixel(src_x, src_y);
2292 				if (sc.a != 0) {
2293 					Color dc = get_pixel(dst_x, dst_y);
2294 					dc = dc.blend(sc);
2295 					set_pixel(dst_x, dst_y, dc);
2296 				}
2297 			}
2298 		}
2299 	}
2300 
2301 	msk->unlock();
2302 	img->unlock();
2303 	unlock();
2304 }
2305 
fill(const Color & c)2306 void Image::fill(const Color &c) {
2307 	ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill in compressed or custom image formats.");
2308 
2309 	lock();
2310 
2311 	PoolVector<uint8_t>::Write wp = data.write();
2312 	uint8_t *dst_data_ptr = wp.ptr();
2313 
2314 	int pixel_size = get_format_pixel_size(format);
2315 
2316 	// put first pixel with the format-aware API
2317 	set_pixel(0, 0, c);
2318 
2319 	for (int y = 0; y < height; y++) {
2320 
2321 		for (int x = 0; x < width; x++) {
2322 
2323 			uint8_t *dst = &dst_data_ptr[(y * width + x) * pixel_size];
2324 
2325 			for (int k = 0; k < pixel_size; k++) {
2326 				dst[k] = dst_data_ptr[k];
2327 			}
2328 		}
2329 	}
2330 
2331 	unlock();
2332 }
2333 
2334 ImageMemLoadFunc Image::_png_mem_loader_func = NULL;
2335 ImageMemLoadFunc Image::_jpg_mem_loader_func = NULL;
2336 ImageMemLoadFunc Image::_webp_mem_loader_func = NULL;
2337 ImageMemLoadFunc Image::_tga_mem_loader_func = NULL;
2338 
2339 void (*Image::_image_compress_bc_func)(Image *, float, Image::CompressSource) = NULL;
2340 void (*Image::_image_compress_bptc_func)(Image *, float, Image::CompressSource) = NULL;
2341 void (*Image::_image_compress_pvrtc2_func)(Image *) = NULL;
2342 void (*Image::_image_compress_pvrtc4_func)(Image *) = NULL;
2343 void (*Image::_image_compress_etc1_func)(Image *, float) = NULL;
2344 void (*Image::_image_compress_etc2_func)(Image *, float, Image::CompressSource) = NULL;
2345 void (*Image::_image_decompress_pvrtc)(Image *) = NULL;
2346 void (*Image::_image_decompress_bc)(Image *) = NULL;
2347 void (*Image::_image_decompress_bptc)(Image *) = NULL;
2348 void (*Image::_image_decompress_etc1)(Image *) = NULL;
2349 void (*Image::_image_decompress_etc2)(Image *) = NULL;
2350 
2351 PoolVector<uint8_t> (*Image::lossy_packer)(const Ref<Image> &, float) = NULL;
2352 Ref<Image> (*Image::lossy_unpacker)(const PoolVector<uint8_t> &) = NULL;
2353 PoolVector<uint8_t> (*Image::lossless_packer)(const Ref<Image> &) = NULL;
2354 Ref<Image> (*Image::lossless_unpacker)(const PoolVector<uint8_t> &) = NULL;
2355 
_set_data(const Dictionary & p_data)2356 void Image::_set_data(const Dictionary &p_data) {
2357 
2358 	ERR_FAIL_COND(!p_data.has("width"));
2359 	ERR_FAIL_COND(!p_data.has("height"));
2360 	ERR_FAIL_COND(!p_data.has("format"));
2361 	ERR_FAIL_COND(!p_data.has("mipmaps"));
2362 	ERR_FAIL_COND(!p_data.has("data"));
2363 
2364 	int dwidth = p_data["width"];
2365 	int dheight = p_data["height"];
2366 	String dformat = p_data["format"];
2367 	bool dmipmaps = p_data["mipmaps"];
2368 	PoolVector<uint8_t> ddata = p_data["data"];
2369 	Format ddformat = FORMAT_MAX;
2370 	for (int i = 0; i < FORMAT_MAX; i++) {
2371 		if (dformat == get_format_name(Format(i))) {
2372 			ddformat = Format(i);
2373 			break;
2374 		}
2375 	}
2376 
2377 	ERR_FAIL_COND(ddformat == FORMAT_MAX);
2378 
2379 	create(dwidth, dheight, dmipmaps, ddformat, ddata);
2380 }
2381 
_get_data() const2382 Dictionary Image::_get_data() const {
2383 
2384 	Dictionary d;
2385 	d["width"] = width;
2386 	d["height"] = height;
2387 	d["format"] = get_format_name(format);
2388 	d["mipmaps"] = mipmaps;
2389 	d["data"] = data;
2390 	return d;
2391 }
2392 
lock()2393 void Image::lock() {
2394 
2395 	ERR_FAIL_COND(data.size() == 0);
2396 	write_lock = data.write();
2397 }
2398 
unlock()2399 void Image::unlock() {
2400 
2401 	write_lock.release();
2402 }
2403 
get_pixelv(const Point2 & p_src) const2404 Color Image::get_pixelv(const Point2 &p_src) const {
2405 	return get_pixel(p_src.x, p_src.y);
2406 }
2407 
get_pixel(int p_x,int p_y) const2408 Color Image::get_pixel(int p_x, int p_y) const {
2409 
2410 	uint8_t *ptr = write_lock.ptr();
2411 #ifdef DEBUG_ENABLED
2412 	ERR_FAIL_COND_V_MSG(!ptr, Color(), "Image must be locked with 'lock()' before using get_pixel().");
2413 
2414 	ERR_FAIL_INDEX_V(p_x, width, Color());
2415 	ERR_FAIL_INDEX_V(p_y, height, Color());
2416 
2417 #endif
2418 
2419 	uint32_t ofs = p_y * width + p_x;
2420 
2421 	switch (format) {
2422 		case FORMAT_L8: {
2423 			float l = ptr[ofs] / 255.0;
2424 			return Color(l, l, l, 1);
2425 		}
2426 		case FORMAT_LA8: {
2427 			float l = ptr[ofs * 2 + 0] / 255.0;
2428 			float a = ptr[ofs * 2 + 1] / 255.0;
2429 			return Color(l, l, l, a);
2430 		}
2431 		case FORMAT_R8: {
2432 
2433 			float r = ptr[ofs] / 255.0;
2434 			return Color(r, 0, 0, 1);
2435 		}
2436 		case FORMAT_RG8: {
2437 
2438 			float r = ptr[ofs * 2 + 0] / 255.0;
2439 			float g = ptr[ofs * 2 + 1] / 255.0;
2440 			return Color(r, g, 0, 1);
2441 		}
2442 		case FORMAT_RGB8: {
2443 			float r = ptr[ofs * 3 + 0] / 255.0;
2444 			float g = ptr[ofs * 3 + 1] / 255.0;
2445 			float b = ptr[ofs * 3 + 2] / 255.0;
2446 			return Color(r, g, b, 1);
2447 		}
2448 		case FORMAT_RGBA8: {
2449 			float r = ptr[ofs * 4 + 0] / 255.0;
2450 			float g = ptr[ofs * 4 + 1] / 255.0;
2451 			float b = ptr[ofs * 4 + 2] / 255.0;
2452 			float a = ptr[ofs * 4 + 3] / 255.0;
2453 			return Color(r, g, b, a);
2454 		}
2455 		case FORMAT_RGBA4444: {
2456 			uint16_t u = ((uint16_t *)ptr)[ofs];
2457 			float r = ((u >> 12) & 0xF) / 15.0;
2458 			float g = ((u >> 8) & 0xF) / 15.0;
2459 			float b = ((u >> 4) & 0xF) / 15.0;
2460 			float a = (u & 0xF) / 15.0;
2461 			return Color(r, g, b, a);
2462 		}
2463 		case FORMAT_RGBA5551: {
2464 
2465 			uint16_t u = ((uint16_t *)ptr)[ofs];
2466 			float r = ((u >> 11) & 0x1F) / 15.0;
2467 			float g = ((u >> 6) & 0x1F) / 15.0;
2468 			float b = ((u >> 1) & 0x1F) / 15.0;
2469 			float a = (u & 0x1) / 1.0;
2470 			return Color(r, g, b, a);
2471 		}
2472 		case FORMAT_RF: {
2473 
2474 			float r = ((float *)ptr)[ofs];
2475 			return Color(r, 0, 0, 1);
2476 		}
2477 		case FORMAT_RGF: {
2478 
2479 			float r = ((float *)ptr)[ofs * 2 + 0];
2480 			float g = ((float *)ptr)[ofs * 2 + 1];
2481 			return Color(r, g, 0, 1);
2482 		}
2483 		case FORMAT_RGBF: {
2484 
2485 			float r = ((float *)ptr)[ofs * 3 + 0];
2486 			float g = ((float *)ptr)[ofs * 3 + 1];
2487 			float b = ((float *)ptr)[ofs * 3 + 2];
2488 			return Color(r, g, b, 1);
2489 		}
2490 		case FORMAT_RGBAF: {
2491 
2492 			float r = ((float *)ptr)[ofs * 4 + 0];
2493 			float g = ((float *)ptr)[ofs * 4 + 1];
2494 			float b = ((float *)ptr)[ofs * 4 + 2];
2495 			float a = ((float *)ptr)[ofs * 4 + 3];
2496 			return Color(r, g, b, a);
2497 		}
2498 		case FORMAT_RH: {
2499 
2500 			uint16_t r = ((uint16_t *)ptr)[ofs];
2501 			return Color(Math::half_to_float(r), 0, 0, 1);
2502 		}
2503 		case FORMAT_RGH: {
2504 
2505 			uint16_t r = ((uint16_t *)ptr)[ofs * 2 + 0];
2506 			uint16_t g = ((uint16_t *)ptr)[ofs * 2 + 1];
2507 			return Color(Math::half_to_float(r), Math::half_to_float(g), 0, 1);
2508 		}
2509 		case FORMAT_RGBH: {
2510 
2511 			uint16_t r = ((uint16_t *)ptr)[ofs * 3 + 0];
2512 			uint16_t g = ((uint16_t *)ptr)[ofs * 3 + 1];
2513 			uint16_t b = ((uint16_t *)ptr)[ofs * 3 + 2];
2514 			return Color(Math::half_to_float(r), Math::half_to_float(g), Math::half_to_float(b), 1);
2515 		}
2516 		case FORMAT_RGBAH: {
2517 
2518 			uint16_t r = ((uint16_t *)ptr)[ofs * 4 + 0];
2519 			uint16_t g = ((uint16_t *)ptr)[ofs * 4 + 1];
2520 			uint16_t b = ((uint16_t *)ptr)[ofs * 4 + 2];
2521 			uint16_t a = ((uint16_t *)ptr)[ofs * 4 + 3];
2522 			return Color(Math::half_to_float(r), Math::half_to_float(g), Math::half_to_float(b), Math::half_to_float(a));
2523 		}
2524 		case FORMAT_RGBE9995: {
2525 			return Color::from_rgbe9995(((uint32_t *)ptr)[ofs]);
2526 		}
2527 		default: {
2528 			ERR_FAIL_V_MSG(Color(), "Can't get_pixel() on compressed image, sorry.");
2529 		}
2530 	}
2531 }
2532 
set_pixelv(const Point2 & p_dst,const Color & p_color)2533 void Image::set_pixelv(const Point2 &p_dst, const Color &p_color) {
2534 	set_pixel(p_dst.x, p_dst.y, p_color);
2535 }
2536 
set_pixel(int p_x,int p_y,const Color & p_color)2537 void Image::set_pixel(int p_x, int p_y, const Color &p_color) {
2538 
2539 	uint8_t *ptr = write_lock.ptr();
2540 #ifdef DEBUG_ENABLED
2541 	ERR_FAIL_COND_MSG(!ptr, "Image must be locked with 'lock()' before using set_pixel().");
2542 
2543 	ERR_FAIL_INDEX(p_x, width);
2544 	ERR_FAIL_INDEX(p_y, height);
2545 
2546 #endif
2547 
2548 	uint32_t ofs = p_y * width + p_x;
2549 
2550 	switch (format) {
2551 		case FORMAT_L8: {
2552 			ptr[ofs] = uint8_t(CLAMP(p_color.get_v() * 255.0, 0, 255));
2553 		} break;
2554 		case FORMAT_LA8: {
2555 			ptr[ofs * 2 + 0] = uint8_t(CLAMP(p_color.get_v() * 255.0, 0, 255));
2556 			ptr[ofs * 2 + 1] = uint8_t(CLAMP(p_color.a * 255.0, 0, 255));
2557 		} break;
2558 		case FORMAT_R8: {
2559 
2560 			ptr[ofs] = uint8_t(CLAMP(p_color.r * 255.0, 0, 255));
2561 		} break;
2562 		case FORMAT_RG8: {
2563 
2564 			ptr[ofs * 2 + 0] = uint8_t(CLAMP(p_color.r * 255.0, 0, 255));
2565 			ptr[ofs * 2 + 1] = uint8_t(CLAMP(p_color.g * 255.0, 0, 255));
2566 		} break;
2567 		case FORMAT_RGB8: {
2568 			ptr[ofs * 3 + 0] = uint8_t(CLAMP(p_color.r * 255.0, 0, 255));
2569 			ptr[ofs * 3 + 1] = uint8_t(CLAMP(p_color.g * 255.0, 0, 255));
2570 			ptr[ofs * 3 + 2] = uint8_t(CLAMP(p_color.b * 255.0, 0, 255));
2571 		} break;
2572 		case FORMAT_RGBA8: {
2573 			ptr[ofs * 4 + 0] = uint8_t(CLAMP(p_color.r * 255.0, 0, 255));
2574 			ptr[ofs * 4 + 1] = uint8_t(CLAMP(p_color.g * 255.0, 0, 255));
2575 			ptr[ofs * 4 + 2] = uint8_t(CLAMP(p_color.b * 255.0, 0, 255));
2576 			ptr[ofs * 4 + 3] = uint8_t(CLAMP(p_color.a * 255.0, 0, 255));
2577 
2578 		} break;
2579 		case FORMAT_RGBA4444: {
2580 
2581 			uint16_t rgba = 0;
2582 
2583 			rgba = uint16_t(CLAMP(p_color.r * 15.0, 0, 15)) << 12;
2584 			rgba |= uint16_t(CLAMP(p_color.g * 15.0, 0, 15)) << 8;
2585 			rgba |= uint16_t(CLAMP(p_color.b * 15.0, 0, 15)) << 4;
2586 			rgba |= uint16_t(CLAMP(p_color.a * 15.0, 0, 15));
2587 
2588 			((uint16_t *)ptr)[ofs] = rgba;
2589 
2590 		} break;
2591 		case FORMAT_RGBA5551: {
2592 
2593 			uint16_t rgba = 0;
2594 
2595 			rgba = uint16_t(CLAMP(p_color.r * 31.0, 0, 31)) << 11;
2596 			rgba |= uint16_t(CLAMP(p_color.g * 31.0, 0, 31)) << 6;
2597 			rgba |= uint16_t(CLAMP(p_color.b * 31.0, 0, 31)) << 1;
2598 			rgba |= uint16_t(p_color.a > 0.5 ? 1 : 0);
2599 
2600 			((uint16_t *)ptr)[ofs] = rgba;
2601 
2602 		} break;
2603 		case FORMAT_RF: {
2604 
2605 			((float *)ptr)[ofs] = p_color.r;
2606 		} break;
2607 		case FORMAT_RGF: {
2608 
2609 			((float *)ptr)[ofs * 2 + 0] = p_color.r;
2610 			((float *)ptr)[ofs * 2 + 1] = p_color.g;
2611 		} break;
2612 		case FORMAT_RGBF: {
2613 
2614 			((float *)ptr)[ofs * 3 + 0] = p_color.r;
2615 			((float *)ptr)[ofs * 3 + 1] = p_color.g;
2616 			((float *)ptr)[ofs * 3 + 2] = p_color.b;
2617 		} break;
2618 		case FORMAT_RGBAF: {
2619 
2620 			((float *)ptr)[ofs * 4 + 0] = p_color.r;
2621 			((float *)ptr)[ofs * 4 + 1] = p_color.g;
2622 			((float *)ptr)[ofs * 4 + 2] = p_color.b;
2623 			((float *)ptr)[ofs * 4 + 3] = p_color.a;
2624 		} break;
2625 		case FORMAT_RH: {
2626 
2627 			((uint16_t *)ptr)[ofs] = Math::make_half_float(p_color.r);
2628 		} break;
2629 		case FORMAT_RGH: {
2630 
2631 			((uint16_t *)ptr)[ofs * 2 + 0] = Math::make_half_float(p_color.r);
2632 			((uint16_t *)ptr)[ofs * 2 + 1] = Math::make_half_float(p_color.g);
2633 		} break;
2634 		case FORMAT_RGBH: {
2635 
2636 			((uint16_t *)ptr)[ofs * 3 + 0] = Math::make_half_float(p_color.r);
2637 			((uint16_t *)ptr)[ofs * 3 + 1] = Math::make_half_float(p_color.g);
2638 			((uint16_t *)ptr)[ofs * 3 + 2] = Math::make_half_float(p_color.b);
2639 		} break;
2640 		case FORMAT_RGBAH: {
2641 
2642 			((uint16_t *)ptr)[ofs * 4 + 0] = Math::make_half_float(p_color.r);
2643 			((uint16_t *)ptr)[ofs * 4 + 1] = Math::make_half_float(p_color.g);
2644 			((uint16_t *)ptr)[ofs * 4 + 2] = Math::make_half_float(p_color.b);
2645 			((uint16_t *)ptr)[ofs * 4 + 3] = Math::make_half_float(p_color.a);
2646 		} break;
2647 		case FORMAT_RGBE9995: {
2648 
2649 			((uint32_t *)ptr)[ofs] = p_color.to_rgbe9995();
2650 
2651 		} break;
2652 		default: {
2653 			ERR_FAIL_MSG("Can't set_pixel() on compressed image, sorry.");
2654 		}
2655 	}
2656 }
2657 
get_detected_channels()2658 Image::DetectChannels Image::get_detected_channels() {
2659 
2660 	ERR_FAIL_COND_V(data.size() == 0, DETECTED_RGBA);
2661 	ERR_FAIL_COND_V(is_compressed(), DETECTED_RGBA);
2662 	bool r = false, g = false, b = false, a = false, c = false;
2663 	lock();
2664 	for (int i = 0; i < width; i++) {
2665 		for (int j = 0; j < height; j++) {
2666 
2667 			Color col = get_pixel(i, j);
2668 
2669 			if (col.r > 0.001)
2670 				r = true;
2671 			if (col.g > 0.001)
2672 				g = true;
2673 			if (col.b > 0.001)
2674 				b = true;
2675 			if (col.a < 0.999)
2676 				a = true;
2677 
2678 			if (col.r != col.b || col.r != col.g || col.b != col.g) {
2679 				c = true;
2680 			}
2681 		}
2682 	}
2683 
2684 	unlock();
2685 
2686 	if (!c && !a)
2687 		return DETECTED_L;
2688 	if (!c && a)
2689 		return DETECTED_LA;
2690 
2691 	if (r && !g && !b && !a)
2692 		return DETECTED_R;
2693 
2694 	if (r && g && !b && !a)
2695 		return DETECTED_RG;
2696 
2697 	if (r && g && b && !a)
2698 		return DETECTED_RGB;
2699 
2700 	return DETECTED_RGBA;
2701 }
2702 
optimize_channels()2703 void Image::optimize_channels() {
2704 	switch (get_detected_channels()) {
2705 		case DETECTED_L: convert(FORMAT_L8); break;
2706 		case DETECTED_LA: convert(FORMAT_LA8); break;
2707 		case DETECTED_R: convert(FORMAT_R8); break;
2708 		case DETECTED_RG: convert(FORMAT_RG8); break;
2709 		case DETECTED_RGB: convert(FORMAT_RGB8); break;
2710 		case DETECTED_RGBA: convert(FORMAT_RGBA8); break;
2711 	}
2712 }
2713 
_bind_methods()2714 void Image::_bind_methods() {
2715 
2716 	ClassDB::bind_method(D_METHOD("get_width"), &Image::get_width);
2717 	ClassDB::bind_method(D_METHOD("get_height"), &Image::get_height);
2718 	ClassDB::bind_method(D_METHOD("get_size"), &Image::get_size);
2719 	ClassDB::bind_method(D_METHOD("has_mipmaps"), &Image::has_mipmaps);
2720 	ClassDB::bind_method(D_METHOD("get_format"), &Image::get_format);
2721 	ClassDB::bind_method(D_METHOD("get_data"), &Image::get_data);
2722 
2723 	ClassDB::bind_method(D_METHOD("convert", "format"), &Image::convert);
2724 
2725 	ClassDB::bind_method(D_METHOD("get_mipmap_offset", "mipmap"), &Image::get_mipmap_offset);
2726 
2727 	ClassDB::bind_method(D_METHOD("resize_to_po2", "square"), &Image::resize_to_po2, DEFVAL(false));
2728 	ClassDB::bind_method(D_METHOD("resize", "width", "height", "interpolation"), &Image::resize, DEFVAL(INTERPOLATE_BILINEAR));
2729 	ClassDB::bind_method(D_METHOD("shrink_x2"), &Image::shrink_x2);
2730 	ClassDB::bind_method(D_METHOD("expand_x2_hq2x"), &Image::expand_x2_hq2x);
2731 
2732 	ClassDB::bind_method(D_METHOD("crop", "width", "height"), &Image::crop);
2733 	ClassDB::bind_method(D_METHOD("flip_x"), &Image::flip_x);
2734 	ClassDB::bind_method(D_METHOD("flip_y"), &Image::flip_y);
2735 	ClassDB::bind_method(D_METHOD("generate_mipmaps", "renormalize"), &Image::generate_mipmaps, DEFVAL(false));
2736 	ClassDB::bind_method(D_METHOD("clear_mipmaps"), &Image::clear_mipmaps);
2737 
2738 	ClassDB::bind_method(D_METHOD("create", "width", "height", "use_mipmaps", "format"), &Image::_create_empty);
2739 	ClassDB::bind_method(D_METHOD("create_from_data", "width", "height", "use_mipmaps", "format", "data"), &Image::_create_from_data);
2740 
2741 	ClassDB::bind_method(D_METHOD("is_empty"), &Image::empty);
2742 
2743 	ClassDB::bind_method(D_METHOD("load", "path"), &Image::load);
2744 	ClassDB::bind_method(D_METHOD("save_png", "path"), &Image::save_png);
2745 	ClassDB::bind_method(D_METHOD("save_png_to_buffer"), &Image::save_png_to_buffer);
2746 	ClassDB::bind_method(D_METHOD("save_exr", "path", "grayscale"), &Image::save_exr, DEFVAL(false));
2747 
2748 	ClassDB::bind_method(D_METHOD("detect_alpha"), &Image::detect_alpha);
2749 	ClassDB::bind_method(D_METHOD("is_invisible"), &Image::is_invisible);
2750 
2751 	ClassDB::bind_method(D_METHOD("compress", "mode", "source", "lossy_quality"), &Image::compress);
2752 	ClassDB::bind_method(D_METHOD("decompress"), &Image::decompress);
2753 	ClassDB::bind_method(D_METHOD("is_compressed"), &Image::is_compressed);
2754 
2755 	ClassDB::bind_method(D_METHOD("fix_alpha_edges"), &Image::fix_alpha_edges);
2756 	ClassDB::bind_method(D_METHOD("premultiply_alpha"), &Image::premultiply_alpha);
2757 	ClassDB::bind_method(D_METHOD("srgb_to_linear"), &Image::srgb_to_linear);
2758 	ClassDB::bind_method(D_METHOD("normalmap_to_xy"), &Image::normalmap_to_xy);
2759 	ClassDB::bind_method(D_METHOD("rgbe_to_srgb"), &Image::rgbe_to_srgb);
2760 	ClassDB::bind_method(D_METHOD("bumpmap_to_normalmap", "bump_scale"), &Image::bumpmap_to_normalmap, DEFVAL(1.0));
2761 
2762 	ClassDB::bind_method(D_METHOD("blit_rect", "src", "src_rect", "dst"), &Image::blit_rect);
2763 	ClassDB::bind_method(D_METHOD("blit_rect_mask", "src", "mask", "src_rect", "dst"), &Image::blit_rect_mask);
2764 	ClassDB::bind_method(D_METHOD("blend_rect", "src", "src_rect", "dst"), &Image::blend_rect);
2765 	ClassDB::bind_method(D_METHOD("blend_rect_mask", "src", "mask", "src_rect", "dst"), &Image::blend_rect_mask);
2766 	ClassDB::bind_method(D_METHOD("fill", "color"), &Image::fill);
2767 
2768 	ClassDB::bind_method(D_METHOD("get_used_rect"), &Image::get_used_rect);
2769 	ClassDB::bind_method(D_METHOD("get_rect", "rect"), &Image::get_rect);
2770 
2771 	ClassDB::bind_method(D_METHOD("copy_from", "src"), &Image::copy_internals_from);
2772 
2773 	ClassDB::bind_method(D_METHOD("_set_data", "data"), &Image::_set_data);
2774 	ClassDB::bind_method(D_METHOD("_get_data"), &Image::_get_data);
2775 
2776 	ClassDB::bind_method(D_METHOD("lock"), &Image::lock);
2777 	ClassDB::bind_method(D_METHOD("unlock"), &Image::unlock);
2778 	ClassDB::bind_method(D_METHOD("get_pixelv", "src"), &Image::get_pixelv);
2779 	ClassDB::bind_method(D_METHOD("get_pixel", "x", "y"), &Image::get_pixel);
2780 	ClassDB::bind_method(D_METHOD("set_pixelv", "dst", "color"), &Image::set_pixelv);
2781 	ClassDB::bind_method(D_METHOD("set_pixel", "x", "y", "color"), &Image::set_pixel);
2782 
2783 	ClassDB::bind_method(D_METHOD("load_png_from_buffer", "buffer"), &Image::load_png_from_buffer);
2784 	ClassDB::bind_method(D_METHOD("load_jpg_from_buffer", "buffer"), &Image::load_jpg_from_buffer);
2785 	ClassDB::bind_method(D_METHOD("load_webp_from_buffer", "buffer"), &Image::load_webp_from_buffer);
2786 	ClassDB::bind_method(D_METHOD("load_tga_from_buffer", "buffer"), &Image::load_tga_from_buffer);
2787 
2788 	ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "_set_data", "_get_data");
2789 
2790 	BIND_CONSTANT(MAX_WIDTH);
2791 	BIND_CONSTANT(MAX_HEIGHT);
2792 
2793 	BIND_ENUM_CONSTANT(FORMAT_L8); //luminance
2794 	BIND_ENUM_CONSTANT(FORMAT_LA8); //luminance-alpha
2795 	BIND_ENUM_CONSTANT(FORMAT_R8);
2796 	BIND_ENUM_CONSTANT(FORMAT_RG8);
2797 	BIND_ENUM_CONSTANT(FORMAT_RGB8);
2798 	BIND_ENUM_CONSTANT(FORMAT_RGBA8);
2799 	BIND_ENUM_CONSTANT(FORMAT_RGBA4444);
2800 	BIND_ENUM_CONSTANT(FORMAT_RGBA5551);
2801 	BIND_ENUM_CONSTANT(FORMAT_RF); //float
2802 	BIND_ENUM_CONSTANT(FORMAT_RGF);
2803 	BIND_ENUM_CONSTANT(FORMAT_RGBF);
2804 	BIND_ENUM_CONSTANT(FORMAT_RGBAF);
2805 	BIND_ENUM_CONSTANT(FORMAT_RH); //half float
2806 	BIND_ENUM_CONSTANT(FORMAT_RGH);
2807 	BIND_ENUM_CONSTANT(FORMAT_RGBH);
2808 	BIND_ENUM_CONSTANT(FORMAT_RGBAH);
2809 	BIND_ENUM_CONSTANT(FORMAT_RGBE9995);
2810 	BIND_ENUM_CONSTANT(FORMAT_DXT1); //s3tc bc1
2811 	BIND_ENUM_CONSTANT(FORMAT_DXT3); //bc2
2812 	BIND_ENUM_CONSTANT(FORMAT_DXT5); //bc3
2813 	BIND_ENUM_CONSTANT(FORMAT_RGTC_R);
2814 	BIND_ENUM_CONSTANT(FORMAT_RGTC_RG);
2815 	BIND_ENUM_CONSTANT(FORMAT_BPTC_RGBA); //btpc bc6h
2816 	BIND_ENUM_CONSTANT(FORMAT_BPTC_RGBF); //float /
2817 	BIND_ENUM_CONSTANT(FORMAT_BPTC_RGBFU); //unsigned float
2818 	BIND_ENUM_CONSTANT(FORMAT_PVRTC2); //pvrtc
2819 	BIND_ENUM_CONSTANT(FORMAT_PVRTC2A);
2820 	BIND_ENUM_CONSTANT(FORMAT_PVRTC4);
2821 	BIND_ENUM_CONSTANT(FORMAT_PVRTC4A);
2822 	BIND_ENUM_CONSTANT(FORMAT_ETC); //etc1
2823 	BIND_ENUM_CONSTANT(FORMAT_ETC2_R11); //etc2
2824 	BIND_ENUM_CONSTANT(FORMAT_ETC2_R11S); //signed ); NOT srgb.
2825 	BIND_ENUM_CONSTANT(FORMAT_ETC2_RG11);
2826 	BIND_ENUM_CONSTANT(FORMAT_ETC2_RG11S);
2827 	BIND_ENUM_CONSTANT(FORMAT_ETC2_RGB8);
2828 	BIND_ENUM_CONSTANT(FORMAT_ETC2_RGBA8);
2829 	BIND_ENUM_CONSTANT(FORMAT_ETC2_RGB8A1);
2830 	BIND_ENUM_CONSTANT(FORMAT_MAX);
2831 
2832 	BIND_ENUM_CONSTANT(INTERPOLATE_NEAREST);
2833 	BIND_ENUM_CONSTANT(INTERPOLATE_BILINEAR);
2834 	BIND_ENUM_CONSTANT(INTERPOLATE_CUBIC);
2835 	BIND_ENUM_CONSTANT(INTERPOLATE_TRILINEAR);
2836 	BIND_ENUM_CONSTANT(INTERPOLATE_LANCZOS);
2837 
2838 	BIND_ENUM_CONSTANT(ALPHA_NONE);
2839 	BIND_ENUM_CONSTANT(ALPHA_BIT);
2840 	BIND_ENUM_CONSTANT(ALPHA_BLEND);
2841 
2842 	BIND_ENUM_CONSTANT(COMPRESS_S3TC);
2843 	BIND_ENUM_CONSTANT(COMPRESS_PVRTC2);
2844 	BIND_ENUM_CONSTANT(COMPRESS_PVRTC4);
2845 	BIND_ENUM_CONSTANT(COMPRESS_ETC);
2846 	BIND_ENUM_CONSTANT(COMPRESS_ETC2);
2847 
2848 	BIND_ENUM_CONSTANT(COMPRESS_SOURCE_GENERIC);
2849 	BIND_ENUM_CONSTANT(COMPRESS_SOURCE_SRGB);
2850 	BIND_ENUM_CONSTANT(COMPRESS_SOURCE_NORMAL);
2851 }
2852 
set_compress_bc_func(void (* p_compress_func)(Image *,float,CompressSource))2853 void Image::set_compress_bc_func(void (*p_compress_func)(Image *, float, CompressSource)) {
2854 
2855 	_image_compress_bc_func = p_compress_func;
2856 }
2857 
set_compress_bptc_func(void (* p_compress_func)(Image *,float,CompressSource))2858 void Image::set_compress_bptc_func(void (*p_compress_func)(Image *, float, CompressSource)) {
2859 
2860 	_image_compress_bptc_func = p_compress_func;
2861 }
2862 
normalmap_to_xy()2863 void Image::normalmap_to_xy() {
2864 
2865 	convert(Image::FORMAT_RGBA8);
2866 
2867 	{
2868 		int len = data.size() / 4;
2869 		PoolVector<uint8_t>::Write wp = data.write();
2870 		unsigned char *data_ptr = wp.ptr();
2871 
2872 		for (int i = 0; i < len; i++) {
2873 
2874 			data_ptr[(i << 2) + 3] = data_ptr[(i << 2) + 0]; //x to w
2875 			data_ptr[(i << 2) + 0] = data_ptr[(i << 2) + 1]; //y to xz
2876 			data_ptr[(i << 2) + 2] = data_ptr[(i << 2) + 1];
2877 		}
2878 	}
2879 
2880 	convert(Image::FORMAT_LA8);
2881 }
2882 
rgbe_to_srgb()2883 Ref<Image> Image::rgbe_to_srgb() {
2884 
2885 	if (data.size() == 0)
2886 		return Ref<Image>();
2887 
2888 	ERR_FAIL_COND_V(format != FORMAT_RGBE9995, Ref<Image>());
2889 
2890 	Ref<Image> new_image;
2891 	new_image.instance();
2892 	new_image->create(width, height, 0, Image::FORMAT_RGB8);
2893 
2894 	lock();
2895 
2896 	new_image->lock();
2897 
2898 	for (int row = 0; row < height; row++) {
2899 		for (int col = 0; col < width; col++) {
2900 			new_image->set_pixel(col, row, get_pixel(col, row).to_srgb());
2901 		}
2902 	}
2903 
2904 	unlock();
2905 	new_image->unlock();
2906 
2907 	if (has_mipmaps()) {
2908 		new_image->generate_mipmaps();
2909 	}
2910 
2911 	return new_image;
2912 }
2913 
bumpmap_to_normalmap(float bump_scale)2914 void Image::bumpmap_to_normalmap(float bump_scale) {
2915 	ERR_FAIL_COND(!_can_modify(format));
2916 	convert(Image::FORMAT_RF);
2917 
2918 	PoolVector<uint8_t> result_image; //rgba output
2919 	result_image.resize(width * height * 4);
2920 
2921 	{
2922 		PoolVector<uint8_t>::Read rp = data.read();
2923 		PoolVector<uint8_t>::Write wp = result_image.write();
2924 
2925 		ERR_FAIL_COND(!rp.ptr());
2926 
2927 		unsigned char *write_ptr = wp.ptr();
2928 		float *read_ptr = (float *)rp.ptr();
2929 
2930 		for (int ty = 0; ty < height; ty++) {
2931 			int py = ty + 1;
2932 			if (py >= height) py -= height;
2933 
2934 			for (int tx = 0; tx < width; tx++) {
2935 				int px = tx + 1;
2936 				if (px >= width) px -= width;
2937 				float here = read_ptr[ty * width + tx];
2938 				float to_right = read_ptr[ty * width + px];
2939 				float above = read_ptr[py * width + tx];
2940 				Vector3 up = Vector3(0, 1, (here - above) * bump_scale);
2941 				Vector3 across = Vector3(1, 0, (to_right - here) * bump_scale);
2942 
2943 				Vector3 normal = across.cross(up);
2944 				normal.normalize();
2945 
2946 				write_ptr[((ty * width + tx) << 2) + 0] = (127.5 + normal.x * 127.5);
2947 				write_ptr[((ty * width + tx) << 2) + 1] = (127.5 + normal.y * 127.5);
2948 				write_ptr[((ty * width + tx) << 2) + 2] = (127.5 + normal.z * 127.5);
2949 				write_ptr[((ty * width + tx) << 2) + 3] = 255;
2950 			}
2951 		}
2952 	}
2953 	format = FORMAT_RGBA8;
2954 	data = result_image;
2955 }
2956 
srgb_to_linear()2957 void Image::srgb_to_linear() {
2958 
2959 	if (data.size() == 0)
2960 		return;
2961 
2962 	static const uint8_t srgb2lin[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 26, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 33, 34, 35, 36, 36, 37, 38, 38, 39, 40, 41, 42, 42, 43, 44, 45, 46, 47, 47, 48, 49, 50, 51, 52, 53, 54, 55, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83, 84, 85, 87, 88, 89, 90, 92, 93, 94, 95, 97, 98, 99, 101, 102, 103, 105, 106, 107, 109, 110, 112, 113, 114, 116, 117, 119, 120, 122, 123, 125, 126, 128, 129, 131, 132, 134, 135, 137, 139, 140, 142, 144, 145, 147, 148, 150, 152, 153, 155, 157, 159, 160, 162, 164, 166, 167, 169, 171, 173, 175, 176, 178, 180, 182, 184, 186, 188, 190, 192, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 218, 220, 222, 224, 226, 228, 230, 232, 235, 237, 239, 241, 243, 245, 248, 250, 252, 255 };
2963 
2964 	ERR_FAIL_COND(format != FORMAT_RGB8 && format != FORMAT_RGBA8);
2965 
2966 	if (format == FORMAT_RGBA8) {
2967 
2968 		int len = data.size() / 4;
2969 		PoolVector<uint8_t>::Write wp = data.write();
2970 		unsigned char *data_ptr = wp.ptr();
2971 
2972 		for (int i = 0; i < len; i++) {
2973 
2974 			data_ptr[(i << 2) + 0] = srgb2lin[data_ptr[(i << 2) + 0]];
2975 			data_ptr[(i << 2) + 1] = srgb2lin[data_ptr[(i << 2) + 1]];
2976 			data_ptr[(i << 2) + 2] = srgb2lin[data_ptr[(i << 2) + 2]];
2977 		}
2978 
2979 	} else if (format == FORMAT_RGB8) {
2980 
2981 		int len = data.size() / 3;
2982 		PoolVector<uint8_t>::Write wp = data.write();
2983 		unsigned char *data_ptr = wp.ptr();
2984 
2985 		for (int i = 0; i < len; i++) {
2986 
2987 			data_ptr[(i * 3) + 0] = srgb2lin[data_ptr[(i * 3) + 0]];
2988 			data_ptr[(i * 3) + 1] = srgb2lin[data_ptr[(i * 3) + 1]];
2989 			data_ptr[(i * 3) + 2] = srgb2lin[data_ptr[(i * 3) + 2]];
2990 		}
2991 	}
2992 }
2993 
premultiply_alpha()2994 void Image::premultiply_alpha() {
2995 
2996 	if (data.size() == 0)
2997 		return;
2998 
2999 	if (format != FORMAT_RGBA8)
3000 		return; //not needed
3001 
3002 	PoolVector<uint8_t>::Write wp = data.write();
3003 	unsigned char *data_ptr = wp.ptr();
3004 
3005 	for (int i = 0; i < height; i++) {
3006 		for (int j = 0; j < width; j++) {
3007 
3008 			uint8_t *ptr = &data_ptr[(i * width + j) * 4];
3009 
3010 			ptr[0] = (uint16_t(ptr[0]) * uint16_t(ptr[3])) >> 8;
3011 			ptr[1] = (uint16_t(ptr[1]) * uint16_t(ptr[3])) >> 8;
3012 			ptr[2] = (uint16_t(ptr[2]) * uint16_t(ptr[3])) >> 8;
3013 		}
3014 	}
3015 }
3016 
fix_alpha_edges()3017 void Image::fix_alpha_edges() {
3018 
3019 	if (data.size() == 0)
3020 		return;
3021 
3022 	if (format != FORMAT_RGBA8)
3023 		return; //not needed
3024 
3025 	PoolVector<uint8_t> dcopy = data;
3026 	PoolVector<uint8_t>::Read rp = dcopy.read();
3027 	const uint8_t *srcptr = rp.ptr();
3028 
3029 	PoolVector<uint8_t>::Write wp = data.write();
3030 	unsigned char *data_ptr = wp.ptr();
3031 
3032 	const int max_radius = 4;
3033 	const int alpha_threshold = 20;
3034 	const int max_dist = 0x7FFFFFFF;
3035 
3036 	for (int i = 0; i < height; i++) {
3037 		for (int j = 0; j < width; j++) {
3038 
3039 			const uint8_t *rptr = &srcptr[(i * width + j) * 4];
3040 			uint8_t *wptr = &data_ptr[(i * width + j) * 4];
3041 
3042 			if (rptr[3] >= alpha_threshold)
3043 				continue;
3044 
3045 			int closest_dist = max_dist;
3046 			uint8_t closest_color[3];
3047 
3048 			int from_x = MAX(0, j - max_radius);
3049 			int to_x = MIN(width - 1, j + max_radius);
3050 			int from_y = MAX(0, i - max_radius);
3051 			int to_y = MIN(height - 1, i + max_radius);
3052 
3053 			for (int k = from_y; k <= to_y; k++) {
3054 				for (int l = from_x; l <= to_x; l++) {
3055 
3056 					int dy = i - k;
3057 					int dx = j - l;
3058 					int dist = dy * dy + dx * dx;
3059 					if (dist >= closest_dist)
3060 						continue;
3061 
3062 					const uint8_t *rp2 = &srcptr[(k * width + l) << 2];
3063 
3064 					if (rp2[3] < alpha_threshold)
3065 						continue;
3066 
3067 					closest_dist = dist;
3068 					closest_color[0] = rp2[0];
3069 					closest_color[1] = rp2[1];
3070 					closest_color[2] = rp2[2];
3071 				}
3072 			}
3073 
3074 			if (closest_dist != max_dist) {
3075 
3076 				wptr[0] = closest_color[0];
3077 				wptr[1] = closest_color[1];
3078 				wptr[2] = closest_color[2];
3079 			}
3080 		}
3081 	}
3082 }
3083 
get_format_name(Format p_format)3084 String Image::get_format_name(Format p_format) {
3085 
3086 	ERR_FAIL_INDEX_V(p_format, FORMAT_MAX, String());
3087 	return format_names[p_format];
3088 }
3089 
load_png_from_buffer(const PoolVector<uint8_t> & p_array)3090 Error Image::load_png_from_buffer(const PoolVector<uint8_t> &p_array) {
3091 	return _load_from_buffer(p_array, _png_mem_loader_func);
3092 }
3093 
load_jpg_from_buffer(const PoolVector<uint8_t> & p_array)3094 Error Image::load_jpg_from_buffer(const PoolVector<uint8_t> &p_array) {
3095 	return _load_from_buffer(p_array, _jpg_mem_loader_func);
3096 }
3097 
load_webp_from_buffer(const PoolVector<uint8_t> & p_array)3098 Error Image::load_webp_from_buffer(const PoolVector<uint8_t> &p_array) {
3099 	return _load_from_buffer(p_array, _webp_mem_loader_func);
3100 }
3101 
load_tga_from_buffer(const PoolVector<uint8_t> & p_array)3102 Error Image::load_tga_from_buffer(const PoolVector<uint8_t> &p_array) {
3103 	ERR_FAIL_NULL_V_MSG(_tga_mem_loader_func, ERR_UNAVAILABLE, "TGA module was not installed.");
3104 	return _load_from_buffer(p_array, _tga_mem_loader_func);
3105 }
3106 
_load_from_buffer(const PoolVector<uint8_t> & p_array,ImageMemLoadFunc p_loader)3107 Error Image::_load_from_buffer(const PoolVector<uint8_t> &p_array, ImageMemLoadFunc p_loader) {
3108 	int buffer_size = p_array.size();
3109 
3110 	ERR_FAIL_COND_V(buffer_size == 0, ERR_INVALID_PARAMETER);
3111 	ERR_FAIL_COND_V(!p_loader, ERR_INVALID_PARAMETER);
3112 
3113 	PoolVector<uint8_t>::Read r = p_array.read();
3114 
3115 	Ref<Image> image = p_loader(r.ptr(), buffer_size);
3116 	ERR_FAIL_COND_V(!image.is_valid(), ERR_PARSE_ERROR);
3117 
3118 	copy_internals_from(image);
3119 
3120 	return OK;
3121 }
3122 
average_4_uint8(uint8_t & p_out,const uint8_t & p_a,const uint8_t & p_b,const uint8_t & p_c,const uint8_t & p_d)3123 void Image::average_4_uint8(uint8_t &p_out, const uint8_t &p_a, const uint8_t &p_b, const uint8_t &p_c, const uint8_t &p_d) {
3124 	p_out = static_cast<uint8_t>((p_a + p_b + p_c + p_d + 2) >> 2);
3125 }
3126 
average_4_float(float & p_out,const float & p_a,const float & p_b,const float & p_c,const float & p_d)3127 void Image::average_4_float(float &p_out, const float &p_a, const float &p_b, const float &p_c, const float &p_d) {
3128 	p_out = (p_a + p_b + p_c + p_d) * 0.25f;
3129 }
3130 
average_4_half(uint16_t & p_out,const uint16_t & p_a,const uint16_t & p_b,const uint16_t & p_c,const uint16_t & p_d)3131 void Image::average_4_half(uint16_t &p_out, const uint16_t &p_a, const uint16_t &p_b, const uint16_t &p_c, const uint16_t &p_d) {
3132 	p_out = Math::make_half_float((Math::half_to_float(p_a) + Math::half_to_float(p_b) + Math::half_to_float(p_c) + Math::half_to_float(p_d)) * 0.25f);
3133 }
3134 
average_4_rgbe9995(uint32_t & p_out,const uint32_t & p_a,const uint32_t & p_b,const uint32_t & p_c,const uint32_t & p_d)3135 void Image::average_4_rgbe9995(uint32_t &p_out, const uint32_t &p_a, const uint32_t &p_b, const uint32_t &p_c, const uint32_t &p_d) {
3136 	p_out = ((Color::from_rgbe9995(p_a) + Color::from_rgbe9995(p_b) + Color::from_rgbe9995(p_c) + Color::from_rgbe9995(p_d)) * 0.25f).to_rgbe9995();
3137 }
3138 
renormalize_uint8(uint8_t * p_rgb)3139 void Image::renormalize_uint8(uint8_t *p_rgb) {
3140 	Vector3 n(p_rgb[0] / 255.0, p_rgb[1] / 255.0, p_rgb[2] / 255.0);
3141 	n *= 2.0;
3142 	n -= Vector3(1, 1, 1);
3143 	n.normalize();
3144 	n += Vector3(1, 1, 1);
3145 	n *= 0.5;
3146 	n *= 255;
3147 	p_rgb[0] = CLAMP(int(n.x), 0, 255);
3148 	p_rgb[1] = CLAMP(int(n.y), 0, 255);
3149 	p_rgb[2] = CLAMP(int(n.z), 0, 255);
3150 }
3151 
renormalize_float(float * p_rgb)3152 void Image::renormalize_float(float *p_rgb) {
3153 	Vector3 n(p_rgb[0], p_rgb[1], p_rgb[2]);
3154 	n.normalize();
3155 	p_rgb[0] = n.x;
3156 	p_rgb[1] = n.y;
3157 	p_rgb[2] = n.z;
3158 }
3159 
renormalize_half(uint16_t * p_rgb)3160 void Image::renormalize_half(uint16_t *p_rgb) {
3161 	Vector3 n(Math::half_to_float(p_rgb[0]), Math::half_to_float(p_rgb[1]), Math::half_to_float(p_rgb[2]));
3162 	n.normalize();
3163 	p_rgb[0] = Math::make_half_float(n.x);
3164 	p_rgb[1] = Math::make_half_float(n.y);
3165 	p_rgb[2] = Math::make_half_float(n.z);
3166 }
3167 
renormalize_rgbe9995(uint32_t * p_rgb)3168 void Image::renormalize_rgbe9995(uint32_t *p_rgb) {
3169 	// Never used
3170 }
3171 
Image(const uint8_t * p_mem_png_jpg,int p_len)3172 Image::Image(const uint8_t *p_mem_png_jpg, int p_len) {
3173 
3174 	width = 0;
3175 	height = 0;
3176 	mipmaps = false;
3177 	format = FORMAT_L8;
3178 
3179 	if (_png_mem_loader_func) {
3180 		copy_internals_from(_png_mem_loader_func(p_mem_png_jpg, p_len));
3181 	}
3182 
3183 	if (empty() && _jpg_mem_loader_func) {
3184 		copy_internals_from(_jpg_mem_loader_func(p_mem_png_jpg, p_len));
3185 	}
3186 }
3187 
duplicate(bool p_subresources) const3188 Ref<Resource> Image::duplicate(bool p_subresources) const {
3189 
3190 	Ref<Image> copy;
3191 	copy.instance();
3192 	copy->_copy_internals_from(*this);
3193 	return copy;
3194 }
3195 
Image()3196 Image::Image() {
3197 
3198 	width = 0;
3199 	height = 0;
3200 	mipmaps = false;
3201 	format = FORMAT_L8;
3202 }
3203 
~Image()3204 Image::~Image() {
3205 
3206 	if (write_lock.ptr()) {
3207 		unlock();
3208 	}
3209 }
3210