Skip to content

Commit

Permalink
refactor image saving functions, remove toojpeg in favor of built-in …
Browse files Browse the repository at this point in the history
…jpg saver
  • Loading branch information
nikitalita committed Nov 1, 2024
1 parent a5f04f6 commit 66c70ac
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 836 deletions.
1 change: 0 additions & 1 deletion SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,4 @@ env_gdsdecomp.add_source_files(env.modules_sources, "editor/*.cpp")
env_gdsdecomp.add_source_files(env.modules_sources, "exporters/*.cpp")
env_gdsdecomp.add_source_files(env.modules_sources, "utility/*.cpp")

env_gdsdecomp.add_source_files(env.modules_sources, "external/toojpeg/*.cpp")
env_gdsdecomp.add_source_files(env.modules_sources, "external/tga/*.cpp")
8 changes: 4 additions & 4 deletions exporters/texture_exporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ Error TextureExporter::_convert_bitmap(const String &p_path, const String &dest_
ERR_FAIL_COND_V_MSG(err != OK, err, "Failed to create dirs for " + dest_path);
String dest_ext = dest_path.get_extension().to_lower();
if (dest_ext == "jpg" || dest_ext == "jpeg") {
err = gdreutil::save_image_as_jpeg(dest_path, img);
err = gdre::save_image_as_jpeg(dest_path, img);
} else if (dest_ext == "webp") {
err = gdreutil::save_image_as_webp(dest_path, img, lossy);
err = gdre::save_image_as_webp(dest_path, img, lossy);
} else if (dest_ext == "png") {
err = img->save_png(dest_path);
} else {
Expand Down Expand Up @@ -115,9 +115,9 @@ Error TextureExporter::_convert_tex(const String &p_path, const String &dest_pat
}
String dest_ext = dest_path.get_extension().to_lower();
if (dest_ext == "jpg" || dest_ext == "jpeg") {
err = gdreutil::save_image_as_jpeg(dest_path, img);
err = gdre::save_image_as_jpeg(dest_path, img);
} else if (dest_ext == "webp") {
err = gdreutil::save_image_as_webp(dest_path, img, lossy);
err = gdre::save_image_as_webp(dest_path, img, lossy);
} else if (dest_ext == "png") {
err = img->save_png(dest_path);
} else if (dest_ext == "tga") {
Expand Down
2 changes: 0 additions & 2 deletions external/toojpeg/.clang-format

This file was deleted.

10 changes: 0 additions & 10 deletions external/toojpeg/LICENSE

This file was deleted.

665 changes: 0 additions & 665 deletions external/toojpeg/toojpeg.cpp

This file was deleted.

62 changes: 0 additions & 62 deletions external/toojpeg/toojpeg.h

This file was deleted.

52 changes: 47 additions & 5 deletions utility/common.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "utility/common.h"
#include "core/error/error_list.h"
#include "core/io/dir_access.h"
#include "core/io/file_access.h"
#include "core/io/image.h"
Expand Down Expand Up @@ -65,13 +66,14 @@ class GodotFileInterface : public tga::FileInterface {
Error gdre::save_image_as_tga(const String &p_path, const Ref<Image> &p_img) {
Vector<uint8_t> buffer;
Ref<Image> source_image = p_img->duplicate();

Error err = OK;
if (source_image->is_compressed()) {
source_image->decompress();
err = source_image->decompress();
if (err == ERR_UNAVAILABLE) {
return err;
}
ERR_FAIL_COND_V_MSG(err, err, "Failed to decompress image.");
}

ERR_FAIL_COND_V(source_image->is_compressed(), FAILED);

int width = source_image->get_width();
int height = source_image->get_height();
bool isRGB = true;
Expand Down Expand Up @@ -124,4 +126,44 @@ Error gdre::save_image_as_tga(const String &p_path, const Ref<Image> &p_img) {
encoder.writeImage(header, tga_image);
encoder.writeFooter();
return OK;
}

Error gdre::save_image_as_webp(const String &p_path, const Ref<Image> &p_img, bool lossy) {
Ref<Image> source_image = p_img->duplicate();
Error err = OK;
if (source_image->is_compressed()) {
err = source_image->decompress();
if (err == ERR_UNAVAILABLE) {
return err;
}
ERR_FAIL_COND_V_MSG(err, err, "Failed to decompress image.");
}
Vector<uint8_t> buffer;
if (lossy) {
buffer = Image::webp_lossy_packer(source_image, 1);
} else {
buffer = Image::webp_lossless_packer(source_image);
}
Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::WRITE, &err);
ERR_FAIL_COND_V_MSG(err, err, vformat("Can't save WEBP at path: '%s'.", p_path));

file->store_buffer(buffer.ptr(), buffer.size());
if (file->get_error() != OK && file->get_error() != ERR_FILE_EOF) {
return ERR_CANT_CREATE;
}
return OK;
}

Error gdre::save_image_as_jpeg(const String &p_path, const Ref<Image> &p_img) {
Vector<uint8_t> buffer;
Ref<Image> source_image = p_img->duplicate();
Error err = OK;
if (source_image->is_compressed()) {
err = source_image->decompress();
if (err == ERR_UNAVAILABLE) {
return err;
}
ERR_FAIL_COND_V_MSG(err, err, "Failed to decompress image.");
}
return source_image->save_jpg(p_path, 1.0f);
}
5 changes: 4 additions & 1 deletion utility/common.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@

#include "core/io/file_access.h"
#include "core/io/marshalls.h"

class Image;
namespace gdre {
bool check_header(const Vector<uint8_t> &p_buffer, const char *p_expected_header, int p_expected_len);
Error ensure_dir(const String &dst_dir);
Error save_image_as_tga(const String &p_path, const Ref<Image> &p_img);

Error save_image_as_webp(const String &p_path, const Ref<Image> &p_img, bool lossy = false);
Error save_image_as_jpeg(const String &p_path, const Ref<Image> &p_img);
static Ref<FileAccess> _____tmp_file;
} // namespace gdre

// Can only pass in string literals
Expand Down
4 changes: 3 additions & 1 deletion utility/import_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,9 @@ Error ImportInfoModern::save_md5_file(const String &output_dir) {
if (src_md5.is_empty()) {
String src_path = export_dest.is_empty() ? get_source_file() : export_dest;
src_md5 = FileAccess::get_md5(output_dir.path_join(src_path.replace_first("res://", "")));
ERR_FAIL_COND_V_MSG(src_md5.is_empty(), ERR_FILE_BAD_PATH, "Can't open exported resource to check md5!");
if (src_md5.is_empty()) {
ERR_FAIL_COND_V_MSG(src_md5.is_empty(), ERR_FILE_BAD_PATH, "Can't open exported resource to check md5!");
}
}
Ref<FileAccess> md5_file = FileAccess::open(md5_file_path, FileAccess::WRITE);
ERR_FAIL_COND_V_MSG(md5_file.is_null(), ERR_FILE_CANT_OPEN, "Can't open exported resource to check md5!");
Expand Down
85 changes: 0 additions & 85 deletions utility/util_functions.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#ifndef GDRE_UTIL_FUNCTIONS_H
#define GDRE_UTIL_FUNCTIONS_H

#include "external/toojpeg/toojpeg.h"

#include "core/io/dir_access.h"
#include "core/io/file_access.h"
#include "core/io/resource.h"
Expand Down Expand Up @@ -43,89 +41,6 @@ static Vector<String> get_recursive_dir_list(const String dir, const Vector<Stri
return ret;
}

static Ref<FileAccess> _____tmp_file;

static Error save_image_as_webp(const String &p_path, const Ref<Image> &p_img, bool lossy = false) {
Ref<Image> source_image = p_img->duplicate();
Vector<uint8_t> buffer;
if (lossy) {
buffer = Image::webp_lossy_packer(source_image, 1);
} else {
buffer = Image::webp_lossless_packer(source_image);
}
Error err;
Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::WRITE, &err);
ERR_FAIL_COND_V_MSG(err, err, vformat("Can't save WEBP at path: '%s'.", p_path));

file->store_buffer(buffer.ptr(), buffer.size());
if (file->get_error() != OK && file->get_error() != ERR_FILE_EOF) {
return ERR_CANT_CREATE;
}
return OK;
}

static Error save_image_as_jpeg(const String &p_path, const Ref<Image> &p_img) {
Vector<uint8_t> buffer;
Ref<Image> source_image = p_img->duplicate();

if (source_image->is_compressed()) {
source_image->decompress();
}

ERR_FAIL_COND_V(source_image->is_compressed(), FAILED);

int width = source_image->get_width();
int height = source_image->get_height();
bool isRGB;
if (source_image->detect_alpha()) {
WARN_PRINT("Alpha channel detected, will not be saved to jpeg...");
}
switch (source_image->get_format()) {
case Image::FORMAT_L8:
isRGB = false;
break;
case Image::FORMAT_LA8:
isRGB = false;
source_image->convert(Image::FORMAT_L8);
break;
case Image::FORMAT_RGB8:
isRGB = true;
break;
case Image::FORMAT_RGBA8:
default:
source_image->convert(Image::FORMAT_RGB8);
isRGB = true;
break;
}

const Vector<uint8_t> image_data = source_image->get_data();
// we may be passed a buffer with existing content we're expected to append to
Error err;
_____tmp_file = FileAccess::open(p_path, FileAccess::WRITE, &err);
ERR_FAIL_COND_V_MSG(err, err, vformat("Can't save JPEG at path: '%s'.", p_path));

bool success = false;
{ // scope writer lifetime
success = TooJpeg::writeJpeg([](unsigned char oneByte) {
_____tmp_file->store_8(oneByte);
},
image_data.ptr(), width, height, isRGB, 100, false);
if (!success) {
_____tmp_file = Ref<FileAccess>();
}
ERR_FAIL_COND_V_MSG(!success, ERR_BUG, "Failed to convert image to JPEG");
}

if (_____tmp_file->get_error() != OK && _____tmp_file->get_error() != ERR_FILE_EOF) {
_____tmp_file = Ref<FileAccess>();
;
return ERR_CANT_CREATE;
}
_____tmp_file->flush();
_____tmp_file = Ref<FileAccess>();
return OK;
}

} //namespace gdreutil

#endif //GDRE_UTIL_FUNCTIONS_H

0 comments on commit 66c70ac

Please sign in to comment.