mirror of
https://github.com/Redot-Engine/redot-engine.git
synced 2025-12-05 23:07:42 -05:00
Merge pull request #821 from Spartan322/add/gif-importer
Add GIF import
This commit is contained in:
@@ -201,6 +201,19 @@ TEST_CASE("[Image] Saving and loading") {
|
||||
image_tga->load_tga_from_buffer(data_tga) == OK,
|
||||
"The TGA image should load successfully.");
|
||||
#endif // MODULE_TGA_ENABLED
|
||||
|
||||
#ifdef MODULE_GIF_ENABLED
|
||||
// Load GIF
|
||||
Ref<Image> image_gif = memnew(Image());
|
||||
Ref<FileAccess> f_gif = FileAccess::open(TestUtils::get_data_path("images/icon.gif"), FileAccess::READ, &err);
|
||||
REQUIRE(f_gif.is_valid());
|
||||
PackedByteArray data_gif;
|
||||
data_gif.resize(f_gif->get_length() + 1);
|
||||
f_gif->get_buffer(data_gif.ptrw(), f_gif->get_length());
|
||||
CHECK_MESSAGE(
|
||||
image_gif->load_gif_from_buffer(data_gif) == OK,
|
||||
"The GIF image should load successfully.");
|
||||
#endif // MODULE_GIF_ENABLED
|
||||
}
|
||||
|
||||
TEST_CASE("[Image] Basic getters") {
|
||||
|
||||
115
tests/core/io/test_image_frames.h
Normal file
115
tests/core/io/test_image_frames.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/**************************************************************************/
|
||||
/* test_image_frames.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* REDOT ENGINE */
|
||||
/* https://redotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2024-present Redot Engine contributors */
|
||||
/* (see REDOT_AUTHORS.md) */
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/io/image.h"
|
||||
#include "core/io/image_frames.h"
|
||||
#include "core/os/os.h"
|
||||
|
||||
#include "tests/test_utils.h"
|
||||
|
||||
#include "modules/modules_enabled.gen.h"
|
||||
|
||||
#include "thirdparty/doctest/doctest.h"
|
||||
|
||||
namespace TestImageFrames {
|
||||
|
||||
TEST_CASE("[ImageFrames] Instantiation") {
|
||||
Vector<Ref<Image>> images = { memnew(Image(8, 4, false, Image::FORMAT_RGBA8)), memnew(Image(16, 8, false, Image::FORMAT_RGBA8)) };
|
||||
Ref<ImageFrames> image_frames = memnew(ImageFrames({ images }));
|
||||
CHECK_MESSAGE(
|
||||
!image_frames->is_empty(),
|
||||
"Image frames created with images should not be empty at first.");
|
||||
|
||||
for (int index = 0; index < image_frames->get_frame_count(); index++) {
|
||||
PackedByteArray image_data = image_frames->get_frame_image(index)->get_data();
|
||||
for (int i = 0; i < image_data.size(); i++) {
|
||||
CHECK_MESSAGE(
|
||||
image_data[i] == 0,
|
||||
"An image of image frames created without data specified should have its data zeroed out.");
|
||||
}
|
||||
}
|
||||
|
||||
Ref<ImageFrames> image_frames_copy = memnew(ImageFrames());
|
||||
CHECK_MESSAGE(
|
||||
image_frames_copy->is_empty(),
|
||||
"Image frames created without any specified images should be empty at first.");
|
||||
image_frames_copy->copy_internals_from(image_frames);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
image_frames->get_frame_count() == image_frames_copy->get_frame_count(),
|
||||
"Duplicated image frames should have the same frame count.");
|
||||
|
||||
for (int index = 0; index < image_frames->get_frame_count(); index++) {
|
||||
CHECK_MESSAGE(
|
||||
image_frames->get_frame_image(index)->get_data() == image_frames_copy->get_frame_image(index)->get_data(),
|
||||
"Duplicated image frames should have the same image data.");
|
||||
|
||||
PackedByteArray image_data = image_frames->get_frame_image(index)->get_data();
|
||||
Ref<Image> image_from_data = memnew(Image(images[index]->get_width(), images[index]->get_height(), images[index]->has_mipmaps(), images[index]->get_format(), image_data));
|
||||
CHECK_MESSAGE(
|
||||
image_frames->get_frame_image(index)->get_data() == image_from_data->get_data(),
|
||||
"An image created from data of an image frame should have the same data of the original image.");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("[ImageFrames] Loading") {
|
||||
[[maybe_unused]] Error err = OK;
|
||||
|
||||
#ifdef MODULE_GIF_ENABLED
|
||||
// Load GIF
|
||||
Ref<ImageFrames> image_frames_gif = memnew(ImageFrames());
|
||||
Ref<FileAccess> f_gif = FileAccess::open(TestUtils::get_data_path("image_frames/icon.gif"), FileAccess::READ, &err);
|
||||
REQUIRE(f_gif.is_valid());
|
||||
PackedByteArray data_gif;
|
||||
data_gif.resize(f_gif->get_length() + 1);
|
||||
f_gif->get_buffer(data_gif.ptrw(), f_gif->get_length());
|
||||
CHECK_MESSAGE(
|
||||
image_frames_gif->load_gif_from_buffer(data_gif) == OK,
|
||||
"The GIF image frame should load successfully.");
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("[ImageFrames] Basic getters") {
|
||||
Vector<Ref<Image>> images = { memnew(Image(8, 4, false, Image::FORMAT_RGBA8)), memnew(Image(16, 8, false, Image::FORMAT_L8)) };
|
||||
Vector<float> delays = { 0.1, 0.2 };
|
||||
Ref<ImageFrames> image_frames = memnew(ImageFrames(images, delays));
|
||||
CHECK(image_frames->get_frame_count() == images.size());
|
||||
CHECK(image_frames->get_loop_count() == 0);
|
||||
for (int index = 0; index < image_frames->get_frame_count(); index++) {
|
||||
CHECK(image_frames->get_frame_image(index) == images[index]);
|
||||
CHECK(image_frames->get_frame_delay(index) == delays[index]);
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace TestImageFrames
|
||||
BIN
tests/data/image_frames/icon.gif
Normal file
BIN
tests/data/image_frames/icon.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.5 KiB |
BIN
tests/data/images/icon.gif
Normal file
BIN
tests/data/images/icon.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.8 KiB |
@@ -32,6 +32,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/io/image_frames.h"
|
||||
#include "scene/resources/sprite_frames.h"
|
||||
|
||||
#include "tests/test_macros.h"
|
||||
@@ -244,4 +245,61 @@ TEST_CASE("[SpriteFrames] Frame addition, removal, and retrieval") {
|
||||
frames.get_frame_count(test_animation_name) == 0,
|
||||
"Clears frames.");
|
||||
}
|
||||
|
||||
TEST_CASE("[SpriteFrames] ImageFrames Animation getter and setter") {
|
||||
Ref<Texture2D> dummy_frame1;
|
||||
dummy_frame1.instantiate();
|
||||
|
||||
SpriteFrames frames;
|
||||
frames.add_animation(test_animation_name);
|
||||
|
||||
frames.add_frame(test_animation_name, dummy_frame1, 1.0, 0);
|
||||
frames.add_frame(test_animation_name, dummy_frame1, 2.0, 1);
|
||||
frames.add_frame(test_animation_name, dummy_frame1, 3.0, 2);
|
||||
|
||||
Ref<ImageFrames> image_frames = frames.make_image_frames(test_animation_name);
|
||||
|
||||
CHECK_MESSAGE(
|
||||
image_frames->get_frame_count() == 3,
|
||||
"ImageFrames frame count is set");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
image_frames->get_loop_count() == 0,
|
||||
"ImageFrames loop count is set");
|
||||
|
||||
for (int i = 0; i < image_frames->get_frame_count(); i++) {
|
||||
CHECK_MESSAGE(
|
||||
image_frames->get_frame_image(i) == dummy_frame1,
|
||||
"ImageFrames image is set");
|
||||
CHECK_MESSAGE(
|
||||
image_frames->get_frame_delay(i) == float(i + 1),
|
||||
"ImageFrames delay is set");
|
||||
}
|
||||
|
||||
Ref<SpriteFrames> new_frames;
|
||||
new_frames.instantiate();
|
||||
|
||||
// These error handling cases should not crash.
|
||||
ERR_PRINT_OFF;
|
||||
new_frames->set_from_image_frames(image_frames, test_animation_name);
|
||||
ERR_PRINT_ON;
|
||||
|
||||
CHECK_MESSAGE(
|
||||
new_frames->has_animation(test_animation_name),
|
||||
"SpriteFrames Animation is set");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
new_frames->get_frame_count(test_animation_name) == 3,
|
||||
"SpriteFrames frame count is set");
|
||||
|
||||
CHECK_MESSAGE(
|
||||
new_frames->get_animation_loop(test_animation_name),
|
||||
"SpriteFrames loop is set");
|
||||
|
||||
for (int i = 0; i < image_frames->get_frame_count(); i++) {
|
||||
CHECK_MESSAGE(
|
||||
new_frames->get_frame_duration(test_animation_name, i) == float(i + 1),
|
||||
"SpriteFrames delay is set");
|
||||
}
|
||||
}
|
||||
} // namespace TestSpriteFrames
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "tests/core/io/test_file_access.h"
|
||||
#include "tests/core/io/test_http_client.h"
|
||||
#include "tests/core/io/test_image.h"
|
||||
#include "tests/core/io/test_image_frames.h"
|
||||
#include "tests/core/io/test_ip.h"
|
||||
#include "tests/core/io/test_json.h"
|
||||
#include "tests/core/io/test_json_native.h"
|
||||
|
||||
Reference in New Issue
Block a user