Skip to content

Commit

Permalink
It is now possible to import images as a separate resource, closes #5738
Browse files Browse the repository at this point in the history
 and likely many others
  • Loading branch information
reduz committed Jul 29, 2018
1 parent 7b63c63 commit 317dee9
Show file tree
Hide file tree
Showing 8 changed files with 307 additions and 36 deletions.
80 changes: 80 additions & 0 deletions core/io/image_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,83 @@ void ImageLoader::add_image_format_loader(ImageFormatLoader *p_loader) {
ERR_FAIL_COND(loader_count >= MAX_LOADERS);
loader[loader_count++] = p_loader;
}

/////////////////

RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error) {

FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
if (r_error) {
*r_error = ERR_CANT_OPEN;
}
memdelete(f);
return RES();
}

uint8_t header[4] = { 0, 0, 0, 0 };
f->get_buffer(header, 4);

bool unrecognized = header[0] != 'G' || header[1] != 'D' || header[2] != 'I' || header[3] != 'M';
if (unrecognized) {
memdelete(f);
if (r_error) {
*r_error = ERR_FILE_UNRECOGNIZED;
}
ERR_FAIL_V(RES());
}

String extension = f->get_pascal_string();

int idx = -1;

for (int i = 0; i < ImageLoader::loader_count; i++) {
if (ImageLoader::loader[i]->recognize(extension)) {
idx = i;
break;
}
}

if (idx == -1) {
memdelete(f);
if (r_error) {
*r_error = ERR_FILE_UNRECOGNIZED;
}
ERR_FAIL_V(RES());
}

Ref<Image> image;
image.instance();

Error err = ImageLoader::loader[idx]->load_image(image, f, false, 1.0);

memdelete(f);

if (err != OK) {
if (r_error) {
*r_error = err;
}
return RES();
}

if (r_error) {
*r_error = OK;
}

return image;
}

void ResourceFormatLoaderImage::get_recognized_extensions(List<String> *p_extensions) const {

p_extensions->push_back("image");
}

bool ResourceFormatLoaderImage::handles_type(const String &p_type) const {

return p_type == "Image";
}

String ResourceFormatLoaderImage::get_resource_type(const String &p_path) const {

return "Image";
}
13 changes: 12 additions & 1 deletion core/io/image_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@
#define IMAGE_LOADER_H

#include "image.h"
#include "io/resource_loader.h"
#include "list.h"
#include "os/file_access.h"
#include "ustring.h"

/**
@author Juan Linietsky <reduzio@gmail.com>
*/
Expand All @@ -55,6 +57,7 @@ class ImageLoader;

class ImageFormatLoader {
friend class ImageLoader;
friend class ResourceFormatLoaderImage;

protected:
virtual Error load_image(Ref<Image> p_image, FileAccess *p_fileaccess, bool p_force_linear, float p_scale) = 0;
Expand All @@ -70,7 +73,7 @@ class ImageLoader {
enum {
MAX_LOADERS = 8
};

friend class ResourceFormatLoaderImage;
static ImageFormatLoader *loader[MAX_LOADERS];
static int loader_count;

Expand All @@ -83,4 +86,12 @@ class ImageLoader {
static void add_image_format_loader(ImageFormatLoader *p_loader);
};

class ResourceFormatLoaderImage : public ResourceFormatLoader {
public:
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
};

#endif
9 changes: 9 additions & 0 deletions core/register_core_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "input_map.h"
#include "io/config_file.h"
#include "io/http_client.h"
#include "io/image_loader.h"
#include "io/marshalls.h"
#include "io/multiplayer_api.h"
#include "io/networked_multiplayer_peer.h"
Expand All @@ -60,11 +61,14 @@
#include "path_remap.h"
#include "project_settings.h"
#include "translation.h"

#include "undo_redo.h"
static ResourceFormatSaverBinary *resource_saver_binary = NULL;
static ResourceFormatLoaderBinary *resource_loader_binary = NULL;
static ResourceFormatImporter *resource_format_importer = NULL;

static ResourceFormatLoaderImage *resource_format_image = NULL;

static _ResourceLoader *_resource_loader = NULL;
static _ResourceSaver *_resource_saver = NULL;
static _OS *_os = NULL;
Expand Down Expand Up @@ -111,6 +115,9 @@ void register_core_types() {
resource_format_importer = memnew(ResourceFormatImporter);
ResourceLoader::add_resource_format_loader(resource_format_importer);

resource_format_image = memnew(ResourceFormatLoaderImage);
ResourceLoader::add_resource_format_loader(resource_format_image);

ClassDB::register_class<Object>();

ClassDB::register_virtual_class<Script>();
Expand Down Expand Up @@ -237,6 +244,8 @@ void unregister_core_types() {

memdelete(_geometry);

if (resource_format_image)
memdelete(resource_format_image);
if (resource_saver_binary)
memdelete(resource_saver_binary);
if (resource_loader_binary)
Expand Down
5 changes: 5 additions & 0 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
#include "editor/import/editor_scene_importer_gltf.h"
#include "editor/import/resource_importer_bitmask.h"
#include "editor/import/resource_importer_csv_translation.h"
#include "editor/import/resource_importer_image.h"
#include "editor/import/resource_importer_obj.h"
#include "editor/import/resource_importer_scene.h"
#include "editor/import/resource_importer_texture.h"
Expand Down Expand Up @@ -4664,6 +4665,10 @@ EditorNode::EditorNode() {
import_texture.instance();
ResourceFormatImporter::get_singleton()->add_importer(import_texture);

Ref<ResourceImporterImage> import_image;
import_image.instance();
ResourceFormatImporter::get_singleton()->add_importer(import_image);

Ref<ResourceImporterCSVTranslation> import_csv_translation;
import_csv_translation.instance();
ResourceFormatImporter::get_singleton()->add_importer(import_csv_translation);
Expand Down
79 changes: 79 additions & 0 deletions editor/import/resource_importer_image.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#include "resource_importer_image.h"

#include "io/image_loader.h"
#include "io/resource_saver.h"
#include "os/file_access.h"
#include "scene/resources/texture.h"

String ResourceImporterImage::get_importer_name() const {

return "image";
}

String ResourceImporterImage::get_visible_name() const {

return "Image";
}
void ResourceImporterImage::get_recognized_extensions(List<String> *p_extensions) const {

ImageLoader::get_recognized_extensions(p_extensions);
}

String ResourceImporterImage::get_save_extension() const {
return "image";
}

String ResourceImporterImage::get_resource_type() const {

return "Image";
}

bool ResourceImporterImage::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {

return true;
}

int ResourceImporterImage::get_preset_count() const {
return 0;
}
String ResourceImporterImage::get_preset_name(int p_idx) const {

return String();
}

void ResourceImporterImage::get_import_options(List<ImportOption> *r_options, int p_preset) const {
}

Error ResourceImporterImage::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) {

FileAccess *f = FileAccess::open(p_source_file, FileAccess::READ);
if (!f) {
ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
}

size_t len = f->get_len();

Vector<uint8_t> data;
data.resize(len);

f->get_buffer(data.ptrw(), len);

memdelete(f);

f = FileAccess::open(p_save_path + ".image", FileAccess::WRITE);

//save the header GDIM
const uint8_t header[4] = { 'G', 'D', 'I', 'M' };
f->store_buffer(header, 4);
//SAVE the extension (so it can be recognized by the loader later
f->store_pascal_string(p_source_file.get_extension().to_lower());
//SAVE the actual image
f->store_buffer(data.ptr(), len);

memdelete(f);

return OK;
}

ResourceImporterImage::ResourceImporterImage() {
}
27 changes: 27 additions & 0 deletions editor/import/resource_importer_image.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef RESOURCE_IMPORTER_IMAGE_H
#define RESOURCE_IMPORTER_IMAGE_H

#include "image.h"
#include "io/resource_import.h"

class ResourceImporterImage : public ResourceImporter {
GDCLASS(ResourceImporterImage, ResourceImporter)
public:
virtual String get_importer_name() const;
virtual String get_visible_name() const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual String get_save_extension() const;
virtual String get_resource_type() const;

virtual int get_preset_count() const;
virtual String get_preset_name(int p_idx) const;

virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;

virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL);

ResourceImporterImage();
};

#endif // RESOURCE_IMPORTER_IMAGE_H
Loading

0 comments on commit 317dee9

Please sign in to comment.