Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/tests/core/io/test_image.cpp
45997 views
1
/**************************************************************************/
2
/* test_image.cpp */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
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 "tests/test_macros.h"
32
33
TEST_FORCE_LINK(test_image)
34
35
#include "core/io/file_access.h"
36
#include "core/io/image.h"
37
#include "tests/test_utils.h"
38
39
#include "modules/modules_enabled.gen.h" // For bmp, jpg, svg, webp, tga.
40
41
namespace TestImage {
42
43
TEST_CASE("[Image] Instantiation") {
44
Ref<Image> image = memnew(Image(8, 4, false, Image::FORMAT_RGBA8));
45
CHECK_MESSAGE(
46
!image->is_empty(),
47
"An image created with specified size and format should not be empty at first.");
48
CHECK_MESSAGE(
49
image->is_invisible(),
50
"A newly created image should be invisible.");
51
CHECK_MESSAGE(
52
!image->is_compressed(),
53
"A newly created image should not be compressed.");
54
CHECK(!image->has_mipmaps());
55
56
PackedByteArray image_data = image->get_data();
57
for (int i = 0; i < image_data.size(); i++) {
58
CHECK_MESSAGE(
59
image_data[i] == 0,
60
"An image created without data specified should have its data zeroed out.");
61
}
62
63
Ref<Image> image_copy = memnew(Image());
64
CHECK_MESSAGE(
65
image_copy->is_empty(),
66
"An image created without any specified size and format be empty at first.");
67
image_copy->copy_internals_from(image);
68
69
CHECK_MESSAGE(
70
image->get_data() == image_copy->get_data(),
71
"Duplicated images should have the same data.");
72
73
image_data = image->get_data();
74
Ref<Image> image_from_data = memnew(Image(8, 4, false, Image::FORMAT_RGBA8, image_data));
75
CHECK_MESSAGE(
76
image->get_data() == image_from_data->get_data(),
77
"An image created from data of another image should have the same data of the original image.");
78
}
79
80
TEST_CASE("[Image] Saving and loading") {
81
Ref<Image> image = memnew(Image(4, 4, false, Image::FORMAT_RGBA8));
82
const String save_path_png = TestUtils::get_temp_path("image.png");
83
const String save_path_exr = TestUtils::get_temp_path("image.exr");
84
85
// Save PNG
86
Error err;
87
err = image->save_png(save_path_png);
88
CHECK_MESSAGE(
89
err == OK,
90
"The image should be saved successfully as a .png file.");
91
92
// Only available on editor builds.
93
#ifdef TOOLS_ENABLED
94
// Save EXR
95
err = image->save_exr(save_path_exr, false);
96
CHECK_MESSAGE(
97
err == OK,
98
"The image should be saved successfully as an .exr file.");
99
#endif // TOOLS_ENABLED
100
101
// Load using load()
102
Ref<Image> image_load = memnew(Image());
103
err = image_load->load(save_path_png);
104
CHECK_MESSAGE(
105
err == OK,
106
"The image should load successfully using load().");
107
CHECK_MESSAGE(
108
image->get_data() == image_load->get_data(),
109
"The loaded image should have the same data as the one that got saved.");
110
111
#ifdef MODULE_BMP_ENABLED
112
// Load BMP
113
Ref<Image> image_bmp = memnew(Image());
114
Ref<FileAccess> f_bmp = FileAccess::open(TestUtils::get_data_path("images/icon.bmp"), FileAccess::READ, &err);
115
REQUIRE(f_bmp.is_valid());
116
PackedByteArray data_bmp;
117
data_bmp.resize(f_bmp->get_length() + 1);
118
f_bmp->get_buffer(data_bmp.ptrw(), f_bmp->get_length());
119
CHECK_MESSAGE(
120
image_bmp->load_bmp_from_buffer(data_bmp) == OK,
121
"The BMP image should load successfully.");
122
#endif // MODULE_BMP_ENABLED
123
124
#ifdef MODULE_EXR_ENABLED
125
// Load EXR
126
Ref<Image> image_exr;
127
image_exr.instantiate();
128
Ref<FileAccess> f_exr = FileAccess::open(TestUtils::get_data_path("images/icon.exr"), FileAccess::READ, &err);
129
REQUIRE(f_exr.is_valid());
130
PackedByteArray data_exr;
131
data_exr.resize(f_exr->get_length() + 1);
132
f_exr->get_buffer(data_exr.ptrw(), f_exr->get_length());
133
CHECK_MESSAGE(
134
image_exr->load_exr_from_buffer(data_exr) == OK,
135
"The EXR image should load successfully.");
136
#endif // MODULE_EXR_ENABLED
137
138
#ifdef MODULE_JPG_ENABLED
139
// Load JPG
140
Ref<Image> image_jpg = memnew(Image());
141
Ref<FileAccess> f_jpg = FileAccess::open(TestUtils::get_data_path("images/icon.jpg"), FileAccess::READ, &err);
142
REQUIRE(f_jpg.is_valid());
143
PackedByteArray data_jpg;
144
data_jpg.resize(f_jpg->get_length() + 1);
145
f_jpg->get_buffer(data_jpg.ptrw(), f_jpg->get_length());
146
CHECK_MESSAGE(
147
image_jpg->load_jpg_from_buffer(data_jpg) == OK,
148
"The JPG image should load successfully.");
149
150
Ref<Image> image_grayscale_jpg = memnew(Image());
151
Ref<FileAccess> f_grayscale_jpg = FileAccess::open(TestUtils::get_data_path("images/grayscale.jpg"), FileAccess::READ, &err);
152
REQUIRE(f_grayscale_jpg.is_valid());
153
PackedByteArray data_grayscale_jpg;
154
data_grayscale_jpg.resize(f_grayscale_jpg->get_length() + 1);
155
f_grayscale_jpg->get_buffer(data_grayscale_jpg.ptrw(), f_grayscale_jpg->get_length());
156
CHECK_MESSAGE(
157
image_jpg->load_jpg_from_buffer(data_grayscale_jpg) == OK,
158
"The grayscale JPG image should load successfully.");
159
160
// Save JPG
161
const String save_path_jpg = TestUtils::get_temp_path("image.jpg");
162
CHECK_MESSAGE(image->save_jpg(save_path_jpg) == OK,
163
"The image should be saved successfully as a .jpg file.");
164
165
#ifdef MODULE_SVG_ENABLED
166
// Load SVG with embedded jpg image
167
Ref<Image> image_svg = memnew(Image());
168
Ref<FileAccess> f_svg = FileAccess::open(TestUtils::get_data_path("images/embedded_jpg.svg"), FileAccess::READ, &err);
169
REQUIRE(f_svg.is_valid());
170
PackedByteArray data_svg;
171
data_svg.resize(f_svg->get_length() + 1);
172
f_svg->get_buffer(data_svg.ptrw(), f_svg->get_length());
173
CHECK_MESSAGE(
174
image_svg->load_svg_from_buffer(data_svg) == OK,
175
"The SVG image should load successfully.");
176
#endif // MODULE_SVG_ENABLED
177
#endif // MODULE_JPG_ENABLED
178
179
#ifdef MODULE_WEBP_ENABLED
180
// Load WebP
181
Ref<Image> image_webp = memnew(Image());
182
Ref<FileAccess> f_webp = FileAccess::open(TestUtils::get_data_path("images/icon.webp"), FileAccess::READ, &err);
183
REQUIRE(f_webp.is_valid());
184
PackedByteArray data_webp;
185
data_webp.resize(f_webp->get_length() + 1);
186
f_webp->get_buffer(data_webp.ptrw(), f_webp->get_length());
187
CHECK_MESSAGE(
188
image_webp->load_webp_from_buffer(data_webp) == OK,
189
"The WebP image should load successfully.");
190
#endif // MODULE_WEBP_ENABLED
191
192
// Load PNG
193
Ref<Image> image_png = memnew(Image());
194
Ref<FileAccess> f_png = FileAccess::open(TestUtils::get_data_path("images/icon.png"), FileAccess::READ, &err);
195
REQUIRE(f_png.is_valid());
196
PackedByteArray data_png;
197
data_png.resize(f_png->get_length() + 1);
198
f_png->get_buffer(data_png.ptrw(), f_png->get_length());
199
CHECK_MESSAGE(
200
image_png->load_png_from_buffer(data_png) == OK,
201
"The PNG image should load successfully.");
202
203
#ifdef MODULE_TGA_ENABLED
204
// Load TGA
205
Ref<Image> image_tga = memnew(Image());
206
Ref<FileAccess> f_tga = FileAccess::open(TestUtils::get_data_path("images/icon.tga"), FileAccess::READ, &err);
207
REQUIRE(f_tga.is_valid());
208
PackedByteArray data_tga;
209
data_tga.resize(f_tga->get_length() + 1);
210
f_tga->get_buffer(data_tga.ptrw(), f_tga->get_length());
211
CHECK_MESSAGE(
212
image_tga->load_tga_from_buffer(data_tga) == OK,
213
"The TGA image should load successfully.");
214
#endif // MODULE_TGA_ENABLED
215
}
216
217
TEST_CASE("[Image] Basic getters") {
218
Ref<Image> image = memnew(Image(8, 4, false, Image::FORMAT_LA8));
219
CHECK(image->get_width() == 8);
220
CHECK(image->get_height() == 4);
221
CHECK(image->get_size() == Vector2(8, 4));
222
CHECK(image->get_format() == Image::FORMAT_LA8);
223
CHECK(image->get_used_rect() == Rect2i(0, 0, 0, 0));
224
Ref<Image> image_get_rect = image->get_region(Rect2i(0, 0, 2, 1));
225
CHECK(image_get_rect->get_size() == Vector2(2, 1));
226
}
227
228
TEST_CASE("[Image] Resizing") {
229
Ref<Image> image = memnew(Image(8, 8, false, Image::FORMAT_RGBA8));
230
// Crop
231
image->crop(4, 4);
232
CHECK_MESSAGE(
233
image->get_size() == Vector2(4, 4),
234
"get_size() should return the correct size after cropping.");
235
image->set_pixel(0, 0, Color(1, 1, 1, 1));
236
237
// Resize
238
for (int i = 0; i < 5; i++) {
239
Ref<Image> image_resized = memnew(Image());
240
image_resized->copy_internals_from(image);
241
Image::Interpolation interpolation = static_cast<Image::Interpolation>(i);
242
image_resized->resize(8, 8, interpolation);
243
CHECK_MESSAGE(
244
image_resized->get_size() == Vector2(8, 8),
245
"get_size() should return the correct size after resizing.");
246
CHECK_MESSAGE(
247
image_resized->get_pixel(1, 1).a > 0,
248
"Resizing an image should also affect its content.");
249
}
250
251
// shrink_x2()
252
image->shrink_x2();
253
CHECK_MESSAGE(
254
image->get_size() == Vector2(2, 2),
255
"get_size() should return the correct size after shrink_x2().");
256
257
// resize_to_po2()
258
Ref<Image> image_po_2 = memnew(Image(14, 28, false, Image::FORMAT_RGBA8));
259
image_po_2->resize_to_po2();
260
CHECK_MESSAGE(
261
image_po_2->get_size() == Vector2(16, 32),
262
"get_size() should return the correct size after resize_to_po2().");
263
}
264
265
TEST_CASE("[Image] Modifying pixels of an image") {
266
Ref<Image> image = memnew(Image(3, 3, false, Image::FORMAT_RGBA8));
267
image->set_pixel(0, 0, Color(1, 1, 1, 1));
268
CHECK_MESSAGE(
269
!image->is_invisible(),
270
"Image should not be invisible after drawing on it.");
271
CHECK_MESSAGE(
272
image->get_pixelv(Vector2(0, 0)).is_equal_approx(Color(1, 1, 1, 1)),
273
"Image's get_pixel() should return the same color value as the one being set with set_pixel() in the same position.");
274
CHECK_MESSAGE(
275
image->get_used_rect() == Rect2i(0, 0, 1, 1),
276
"Image's get_used_rect should return the expected value, larger than Rect2i(0, 0, 0, 0) if it's visible.");
277
278
image->set_pixelv(Vector2(0, 0), Color(0.5, 0.5, 0.5, 0.5));
279
Ref<Image> image2 = memnew(Image(3, 3, false, Image::FORMAT_RGBA8));
280
281
// Fill image with color
282
image2->fill(Color(0.5, 0.5, 0.5, 0.5));
283
for (int m = 0; m < image2->get_mipmap_count(); m++) {
284
Ref<Image> mip_image = image2->get_image_from_mipmap(m);
285
286
for (int y = 0; y < mip_image->get_height(); y++) {
287
for (int x = 0; x < mip_image->get_width(); x++) {
288
CHECK_MESSAGE(
289
mip_image->get_pixel(x, y).r > 0.49,
290
"fill() should colorize all pixels of the image.");
291
}
292
}
293
}
294
295
// Fill rect with color
296
{
297
const int img_width = 3;
298
const int img_height = 3;
299
Vector<Rect2i> rects;
300
rects.push_back(Rect2i());
301
rects.push_back(Rect2i(-5, -5, 3, 3));
302
rects.push_back(Rect2i(img_width, 0, 12, 12));
303
rects.push_back(Rect2i(0, img_height, 12, 12));
304
rects.push_back(Rect2i(img_width + 1, img_height + 2, 12, 12));
305
rects.push_back(Rect2i(1, 1, 1, 1));
306
rects.push_back(Rect2i(0, 1, 2, 3));
307
rects.push_back(Rect2i(-5, 0, img_width + 10, 2));
308
rects.push_back(Rect2i(0, -5, 2, img_height + 10));
309
rects.push_back(Rect2i(-1, -1, img_width + 1, img_height + 1));
310
311
for (const Rect2i &rect : rects) {
312
Ref<Image> img = memnew(Image(img_width, img_height, false, Image::FORMAT_RGBA8));
313
img->fill_rect(rect, Color(1, 1, 1, 1));
314
for (int y = 0; y < img->get_height(); y++) {
315
for (int x = 0; x < img->get_width(); x++) {
316
if (rect.abs().has_point(Point2(x, y))) {
317
CHECK_MESSAGE(
318
img->get_pixel(x, y).is_equal_approx(Color(1, 1, 1, 1)),
319
"fill_rect() should colorize all image pixels within rect bounds.");
320
} else {
321
CHECK_MESSAGE(
322
!img->get_pixel(x, y).is_equal_approx(Color(1, 1, 1, 1)),
323
"fill_rect() shouldn't colorize any image pixel out of rect bounds.");
324
}
325
}
326
}
327
}
328
}
329
330
// Blend two images together
331
image->blend_rect(image2, Rect2i(Vector2i(0, 0), image2->get_size()), Vector2i(0, 0));
332
CHECK_MESSAGE(
333
image->get_pixel(0, 0).a > 0.7,
334
"blend_rect() should blend the alpha values of the two images.");
335
CHECK_MESSAGE(
336
image->get_used_rect().size == image->get_size(),
337
"get_used_rect() should return the expected value, its Rect size should be the same as get_size() if there are no transparent pixels.");
338
339
Ref<Image> image3 = memnew(Image(2, 2, false, Image::FORMAT_RGBA8));
340
image3->set_pixel(0, 0, Color(0, 1, 0, 1));
341
342
//blit_rect() two images together
343
image->blit_rect(image3, Rect2i(Vector2i(0, 0), image3->get_size()), Vector2i(0, 0));
344
CHECK_MESSAGE(
345
image->get_pixel(0, 0).is_equal_approx(Color(0, 1, 0, 1)),
346
"blit_rect() should replace old colors and not blend them.");
347
CHECK_MESSAGE(
348
!image->get_pixel(2, 2).is_equal_approx(Color(0, 1, 0, 1)),
349
"blit_rect() should not affect the area of the image that is outside src_rect.");
350
351
// Flip image
352
image3->flip_x();
353
CHECK(image3->get_pixel(1, 0).is_equal_approx(Color(0, 1, 0, 1)));
354
CHECK_MESSAGE(
355
image3->get_pixel(0, 0).is_equal_approx(Color(0, 0, 0, 0)),
356
"flip_x() should not leave old pixels behind.");
357
image3->flip_y();
358
CHECK(image3->get_pixel(1, 1).is_equal_approx(Color(0, 1, 0, 1)));
359
CHECK_MESSAGE(
360
image3->get_pixel(1, 0).is_equal_approx(Color(0, 0, 0, 0)),
361
"flip_y() should not leave old pixels behind.");
362
363
// Pre-multiply Alpha then Convert from RGBA to L8, checking alpha
364
{
365
Ref<Image> gray_image = memnew(Image(3, 3, false, Image::FORMAT_RGBA8));
366
gray_image->fill_rect(Rect2i(0, 0, 3, 3), Color(1, 1, 1, 0));
367
gray_image->set_pixel(1, 1, Color(1, 1, 1, 1));
368
gray_image->set_pixel(1, 2, Color(0.5, 0.5, 0.5, 0.5));
369
gray_image->set_pixel(2, 1, Color(0.25, 0.05, 0.5, 1.0));
370
gray_image->set_pixel(2, 2, Color(0.5, 0.25, 0.95, 0.75));
371
gray_image->premultiply_alpha();
372
gray_image->convert(Image::FORMAT_L8);
373
CHECK_MESSAGE(gray_image->get_pixel(0, 0).is_equal_approx(Color(0, 0, 0, 1)), "convert() RGBA to L8 should be black.");
374
CHECK_MESSAGE(gray_image->get_pixel(0, 1).is_equal_approx(Color(0, 0, 0, 1)), "convert() RGBA to L8 should be black.");
375
CHECK_MESSAGE(gray_image->get_pixel(0, 2).is_equal_approx(Color(0, 0, 0, 1)), "convert() RGBA to L8 should be black.");
376
CHECK_MESSAGE(gray_image->get_pixel(1, 0).is_equal_approx(Color(0, 0, 0, 1)), "convert() RGBA to L8 should be black.");
377
CHECK_MESSAGE(gray_image->get_pixel(1, 1).is_equal_approx(Color(1, 1, 1, 1)), "convert() RGBA to L8 should be white.");
378
CHECK_MESSAGE(gray_image->get_pixel(1, 2).is_equal_approx(Color(0.250980407, 0.250980407, 0.250980407, 1)), "convert() RGBA to L8 should be around 0.250980407 (64).");
379
CHECK_MESSAGE(gray_image->get_pixel(2, 0).is_equal_approx(Color(0, 0, 0, 1)), "convert() RGBA to L8 should be black.");
380
CHECK_MESSAGE(gray_image->get_pixel(2, 1).is_equal_approx(Color(0.121568628, 0.121568628, 0.121568628, 1)), "convert() RGBA to L8 should be around 0.121568628 (31).");
381
CHECK_MESSAGE(gray_image->get_pixel(2, 2).is_equal_approx(Color(0.266666681, 0.266666681, 0.266666681, 1)), "convert() RGBA to L8 should be around 0.266666681 (68).");
382
}
383
}
384
385
TEST_CASE("[Image] Custom mipmaps") {
386
Ref<Image> image = memnew(Image(100, 100, false, Image::FORMAT_RGBA8));
387
388
REQUIRE(!image->has_mipmaps());
389
image->generate_mipmaps();
390
REQUIRE(image->has_mipmaps());
391
392
const int mipmaps = image->get_mipmap_count() + 1;
393
REQUIRE(mipmaps == 7);
394
395
// Initialize reference mipmap data.
396
// Each byte is given value "mipmap_index * 5".
397
398
{
399
PackedByteArray data = image->get_data();
400
uint8_t *data_ptr = data.ptrw();
401
402
for (int mip = 0; mip < mipmaps; mip++) {
403
int64_t mip_offset = 0;
404
int64_t mip_size = 0;
405
image->get_mipmap_offset_and_size(mip, mip_offset, mip_size);
406
407
for (int i = 0; i < mip_size; i++) {
408
data_ptr[mip_offset + i] = mip * 5;
409
}
410
}
411
image->set_data(image->get_width(), image->get_height(), image->has_mipmaps(), image->get_format(), data);
412
}
413
414
// Byte format conversion.
415
416
for (int format = Image::FORMAT_L8; format <= Image::FORMAT_RGBA8; format++) {
417
Ref<Image> image_bytes = memnew(Image());
418
image_bytes->copy_internals_from(image);
419
image_bytes->convert((Image::Format)format);
420
REQUIRE(image_bytes->has_mipmaps());
421
422
PackedByteArray data = image_bytes->get_data();
423
const uint8_t *data_ptr = data.ptr();
424
425
for (int mip = 0; mip < mipmaps; mip++) {
426
int64_t mip_offset = 0;
427
int64_t mip_size = 0;
428
image_bytes->get_mipmap_offset_and_size(mip, mip_offset, mip_size);
429
430
for (int i = 0; i < mip_size; i++) {
431
if (data_ptr[mip_offset + i] != mip * 5) {
432
REQUIRE_MESSAGE(false, "Byte format conversion error.");
433
}
434
}
435
}
436
}
437
438
// Floating point format conversion.
439
440
for (int format = Image::FORMAT_RF; format <= Image::FORMAT_RGBAF; format++) {
441
Ref<Image> image_rgbaf = memnew(Image());
442
image_rgbaf->copy_internals_from(image);
443
image_rgbaf->convert((Image::Format)format);
444
REQUIRE(image_rgbaf->has_mipmaps());
445
446
PackedByteArray data = image_rgbaf->get_data();
447
const uint8_t *data_ptr = data.ptr();
448
449
for (int mip = 0; mip < mipmaps; mip++) {
450
int64_t mip_offset = 0;
451
int64_t mip_size = 0;
452
image_rgbaf->get_mipmap_offset_and_size(mip, mip_offset, mip_size);
453
454
for (int i = 0; i < mip_size; i += 4) {
455
float value = *(float *)(data_ptr + mip_offset + i);
456
if (!Math::is_equal_approx(value * 255.0f, mip * 5)) {
457
REQUIRE_MESSAGE(false, "Floating point conversion error.");
458
}
459
}
460
}
461
}
462
}
463
464
TEST_CASE("[Image] Convert image") {
465
for (int format = Image::FORMAT_RF; format < Image::FORMAT_RGBE9995; format++) {
466
for (int new_format = Image::FORMAT_RF; new_format < Image::FORMAT_RGBE9995; new_format++) {
467
Ref<Image> image = memnew(Image(4, 4, false, (Image::Format)format));
468
image->convert((Image::Format)new_format);
469
String format_string = Image::format_names[(Image::Format)format];
470
String new_format_string = Image::format_names[(Image::Format)new_format];
471
format_string = "Error converting from " + format_string + " to " + new_format_string + ".";
472
CHECK_MESSAGE(image->get_format() == new_format, format_string);
473
}
474
}
475
476
Ref<Image> image = memnew(Image(4, 4, false, Image::FORMAT_RGBA8));
477
PackedByteArray image_data = image->get_data();
478
ERR_PRINT_OFF;
479
image->convert((Image::Format)-1);
480
ERR_PRINT_ON;
481
CHECK_MESSAGE(image->get_data() == image_data, "Image conversion to invalid type (-1) should not alter image.");
482
Ref<Image> image2 = memnew(Image(4, 4, false, Image::FORMAT_RGBA8));
483
image_data = image2->get_data();
484
ERR_PRINT_OFF;
485
image2->convert((Image::Format)(Image::FORMAT_MAX + 1));
486
ERR_PRINT_ON;
487
CHECK_MESSAGE(image2->get_data() == image_data, "Image conversion to invalid type (Image::FORMAT_MAX + 1) should not alter image.");
488
}
489
490
} // namespace TestImage
491
492