Skip to content

Commit

Permalink
more cleanup; revert some testing stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
dslatt committed Oct 26, 2024
1 parent 00b0905 commit 5afa701
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 78 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ include(${BOREALIS_LIBRARY}/cmake/toolchain.cmake)
project(nso-icon-tool)
set(VERSION_MAJOR "0")
set(VERSION_MINOR "4")
set(VERSION_ALTER "2")
set(VERSION_ALTER "3")
set(VERSION_BUILD "0")
set(PROJECT_AUTHOR "dslatt")
set(PROJECT_ICON ${CMAKE_CURRENT_SOURCE_DIR}/resources/img/dev.jpg)
Expand Down
10 changes: 8 additions & 2 deletions include/util/image.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@

struct Image
{
unsigned char* img = nullptr;
struct HandleDeleter
{
void operator()(unsigned char *p) const { if (p) std::free(p); }
};

using Handle = std::unique_ptr<unsigned char, HandleDeleter>;
Handle data;
int size = 0; // raw size in bytes
int pixels = 0; // pixel count
int x = 0, y = 0, n = 0;

~Image();
~Image() = default;

Image(const Image &other);
Image(Image &&other) noexcept;
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<img src="https://img.shields.io/static/v1?label=license&message=GPLV3&labelColor=111111&color=0057da&style=for-the-badge&logo=data%3Aimage/png%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHpFAACAgwAA/FcAAIDoAAB5FgAA8QEAADtfAAAcheDStWoAAAFGSURBVHjarJK9LgRhFIafWUuiEH/rJwrJClEq3IELUKgo3IrETWh0FC7BNVih0AoKBQoEydq11qMwm5yMsbPEm3yZd55zvnfO92VQKVhLak09UZeL%2BrsVZ9Qdv2tXnf1NYEndUushZFGthvemuq32FwWuq%2BeZid5DvZGpXambeYGr6qnd9dGldqaudQL3QuFWvVbbmaC6%2BprDr9WbwA4SdQW4BwaABb50CTykfjjwC%2BAx9SPAfOANYDxRCXpOnxNAM4ePA63Ul8NHR4E2QClsGgGG0jUR%2BFjglcAn8/pj4HTwUz/42FPJ68lOSDhCkR/O46XM0Qh3VcRH83jph%2BZefKUosBr8XA%2B%2BmufLAR4Dh6k/CrzWA691YOc/3Ejv6iNM3k59Xw%2B8D3gC9hN1ErjjfzSbqHVg8J8CG2XgBXgL4/9VCdD6HACaHdcHGCRMgQAAAABJRU5ErkJggg%3D%3D" alt=License>
</a>
<a rel="VERSION" href="https://github.com/dslatt/nso-icon-tool">
<img src="https://img.shields.io/static/v1?label=version&message=0.4.2&labelColor=111111&color=06f&style=for-the-badge" alt="Version">
<img src="https://img.shields.io/static/v1?label=version&message=0.4.3&labelColor=111111&color=06f&style=for-the-badge" alt="Version">
</a>
<a rel="BUILD" href="https://github.com/dslatt/nso-icon-tool/actions">
<img src="https://img.shields.io/github/actions/workflow/status/dslatt/nso-icon-tool/build-switch-release.yml?branch=main&labelColor=111111&color=06f&style=for-the-badge" alt=Build>
Expand Down
47 changes: 26 additions & 21 deletions source/util/extract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,26 @@

using namespace brls::literals; // for _i18n
namespace fs = std::filesystem;
using ArchivePtr = std::unique_ptr<struct archive, decltype(&archive_read_free)>;

namespace extract
{
std::tuple<int64_t, int64_t> getFileStats(const std::string &archivePath)
{
std::tuple<int64_t, int64_t> stats{0, 0};
struct archive* archive;
ArchivePtr archive(archive_read_new(), archive_read_free);
struct archive_entry* entry;

archive = archive_read_new();
archive_read_support_format_all(archive);
archive_read_support_filter_all(archive);
archive_read_support_format_all(archive.get());
archive_read_support_filter_all(archive.get());

if(archive_read_open_filename(archive, archivePath.c_str(), 10240) == ARCHIVE_OK) {
while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
if(archive_read_open_filename(archive.get(), archivePath.c_str(), 10240) == ARCHIVE_OK) {
while(archive_read_next_header(archive.get(), &entry) == ARCHIVE_OK) {
std::get<0>(stats) += 1;
std::get<1>(stats) += archive_entry_size(entry);
}
archive_read_close(archive);
}

archive_read_free(archive);
return stats;
}

Expand All @@ -58,26 +56,29 @@ namespace extract

void extract(const std::string &archivePath, const std::string &workingPath, bool overwriteExisting) {
auto start = std::chrono::high_resolution_clock::now();
int count = 0;

try {

auto [totalFiles, totalSize] = getFileStats(archivePath);
ensureAvailableStorage(totalSize);

brls::sync([totalFiles, totalSize]() {
brls::Logger::info("Extracting {} {} entries", totalFiles, totalSize);
brls::Logger::info("Extracting {} entries of size {} bytes", totalFiles, totalSize);
});

ProgressEvent::instance().setTotalSteps(totalFiles);
ProgressEvent::instance().setStep(0);

std::unique_ptr<struct archive, decltype(&archive_read_free)> a(archive_read_new(), archive_read_free);
ArchivePtr archive(archive_read_new(), archive_read_free);
struct archive_entry *entry;
int err = 0, i = 0, count = 0;
int err = 0, i = 0;

archive_read_support_format_all(a.get());
archive_read_support_filter_all(a.get());
archive_read_support_format_all(archive.get());
archive_read_support_filter_all(archive.get());

if ((err = archive_read_open_filename(a.get(), archivePath.c_str(), 10240))) {
brls::sync([err = std::string(archive_error_string(a.get()))]() {
if ((err = archive_read_open_filename(archive.get(), archivePath.c_str(), 10240))) {
brls::sync([err = std::string(archive_error_string(archive.get()))]() {
brls::Logger::error("Error opening archive: {}", err);
});
return;
Expand All @@ -89,13 +90,13 @@ namespace extract
break;
}

err = archive_read_next_header(a.get(), &entry);
err = archive_read_next_header(archive.get(), &entry);
if (err == ARCHIVE_EOF) {
ProgressEvent::instance().setStep(ProgressEvent::instance().getMax());
break;
}
if (err < ARCHIVE_OK)
brls::sync([archivePath, err = std::string(archive_error_string(a.get()))]() {
brls::sync([archivePath, err = std::string(archive_error_string(archive.get()))]() {
brls::Logger::error("Error reading archive entry: {}", err);
});
if (err < ARCHIVE_WARN) {
Expand Down Expand Up @@ -127,19 +128,17 @@ namespace extract
size_t size = 0;
int64_t offset = 0;
int res = -1;
while ((res = archive_read_data_block(a.get(), &buff, &size, &offset)) == ARCHIVE_OK) {
while ((res = archive_read_data_block(archive.get(), &buff, &size, &offset)) == ARCHIVE_OK) {
try {
outfile.write(static_cast<const char*>(buff), size);
} catch(const std::exception& e) {
res = ARCHIVE_FATAL;
outfile.close();
fs::remove(filepath);
break;
}
}

if (res != ARCHIVE_EOF) {
brls::sync([res = std::string(archive_error_string(a.get()))]() {
brls::sync([res = std::string(archive_error_string(archive.get()))]() {
brls::Logger::error("Error writing out archive entry: {}", res);
});
outfile.close();
Expand All @@ -151,6 +150,12 @@ namespace extract
ProgressEvent::instance().setStep(++i);
}

} catch(const std::exception& e) {
brls::sync([e = std::string(e.what())]() {
brls::Logger::error("Unexpected error extracting archive: {}", e);
});
}

auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(end - start).count();

Expand Down
54 changes: 23 additions & 31 deletions source/util/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,43 +15,36 @@

#include <xxhash.h>

Image::~Image() {
if (img) {
free(img); // free() and stbi_image_free() are the same. be sure to only use malloc() or stbi* managed memory for img
img = nullptr;
}
}

Image::Image(const Image &other)
{
auto* data = static_cast<unsigned char*>(malloc(other.size));
if (data && other.img) {
std::memcpy(data, other.img, other.size);
img = data;
data.reset(static_cast<unsigned char*>(malloc(other.size)));
if (data && other.data) {
std::memcpy(data.get(), other.data.get(), other.size);
size = other.size;
pixels = other.pixels;
x = other.x;
y = other.y;
n = other.n;
}
}

Image::Image(Image &&other) noexcept
{
if (img) { free(img); }
img = std::exchange(other.img, nullptr);
data = std::exchange(other.data, nullptr);
size = std::exchange(other.size, 0);
x = std::exchange(other.x, 0);
y = std::exchange(other.y, 0);
n = std::exchange(other.n, 0);
}

Image &Image::operator=(const Image &other)
{
return *this = Image(other);
}

Image &Image::operator=(Image &&other)
{
if (img) { free(img); }
img = std::exchange(other.img, nullptr);
data = std::exchange(other.data, nullptr);
size = std::exchange(other.size, 0);
x = std::exchange(other.x, 0);
y = std::exchange(other.y, 0);
Expand All @@ -65,15 +58,14 @@ Image::Image(int x, int y) : Image(nullptr, x, y, 4) { allocate(); }

bool Image::allocate()
{
if (img) { free(img); }
img = static_cast<unsigned char*>(calloc(size / sizeof(char), sizeof(char)));
data.reset(static_cast<unsigned char*>(calloc(size / sizeof(char), sizeof(char))));

return img != 0;
return (bool)data;
}

Image::Image(unsigned char *buffer, size_t size)
{
this->img = stbi_load_from_memory(buffer, size, &x, &y, &n, 4);
this->data.reset(stbi_load_from_memory(buffer, size, &x, &y, &n, 4));
this->n = 4;
this->pixels = x * y;
this->size = pixels * 4 * sizeof(char);
Expand All @@ -83,14 +75,14 @@ Image::Image(std::string file)
{
stbi_set_unpremultiply_on_load(1);
stbi_convert_iphone_png_to_rgb(1);
this->img = stbi_load(file.c_str(), &x, &y, &n, 4);
this->data.reset(stbi_load(file.c_str(), &x, &y, &n, 4));
this->pixels = x * y;
this->size = pixels * 4 * sizeof(char);
}

Image::Image(unsigned char *img, int x, int y, int n)
{
this->img = img;
this->data.reset(img);
this->x = x;
this->y = y;
this->n = n;
Expand All @@ -102,7 +94,7 @@ void Image::resize(int x, int y)
{
if (this->x != x || this->y != y)
{
auto *resized = stbir_resize_uint8_linear(img, this->x, this->y, 0, nullptr, x, y, 0, stbir_pixel_layout::STBIR_RGBA);
auto *resized = stbir_resize_uint8_linear(data.get(), this->x, this->y, 0, nullptr, x, y, 0, stbir_pixel_layout::STBIR_RGBA);
if (resized)
{
*this = Image(resized, x, y, 4);
Expand All @@ -113,13 +105,13 @@ void Image::resize(int x, int y)
bool Image::writeJpg(std::filesystem::path path)
{
if (path.extension() != ".jpg") path.replace_extension(".jpg");
return stbi_write_jpg(path.c_str(), x, y, 4, img, 90) != 0;
return stbi_write_jpg(path.c_str(), x, y, 4, data.get(), 90) != 0;
}

bool Image::writePng(std::filesystem::path path)
{
if (path.extension() != ".png") path.replace_extension(".png");
return stbi_write_png(path.c_str(), x, y, 4, img, 0) != 0;
return stbi_write_png(path.c_str(), x, y, 4, data.get(), 0) != 0;
}

void Image::applyAlpha(float alpha) {
Expand All @@ -128,9 +120,9 @@ void Image::applyAlpha(float alpha) {

std::string Image::hash()
{
if (img)
if (data)
{
auto xxh = XXH3_64bits(img, pixels * 4 * sizeof(char));
auto xxh = XXH3_64bits(data.get(), pixels * 4 * sizeof(char));
return fmt::format("{}", xxh);
}

Expand Down Expand Up @@ -162,10 +154,10 @@ void Image::merge(Image &frame, Image &character, Image &background, Image &outp
{
auto total = frame.x * frame.y;

std::span frameRef{reinterpret_cast<Pixel*>(frame.img), frame.size / sizeof(Pixel)};
std::span characterRef{reinterpret_cast<Pixel*>(character.img), character.size / sizeof(Pixel)};
std::span backgroundRef{reinterpret_cast<Pixel*>(background.img), background.size / sizeof(Pixel)};
std::span outputRef{reinterpret_cast<Pixel*>(output.img), output.size / sizeof(Pixel)};
std::span frameRef{reinterpret_cast<Pixel*>(frame.data.get()), frame.size / sizeof(Pixel)};
std::span characterRef{reinterpret_cast<Pixel*>(character.data.get()), character.size / sizeof(Pixel)};
std::span backgroundRef{reinterpret_cast<Pixel*>(background.data.get()), background.size / sizeof(Pixel)};
std::span outputRef{reinterpret_cast<Pixel*>(output.data.get()), output.size / sizeof(Pixel)};

for (auto i = 0; i < total; i++)
{
Expand Down Expand Up @@ -195,7 +187,7 @@ void Image::merge(Image &frame, Image &character, Image &background, Image &outp

void Image::applyAlpha(Image& image, float alpha) {
auto total = image.x * image.y;
auto ref = std::span(reinterpret_cast<Pixel*>(image.img), image.size / sizeof(Pixel));
auto ref = std::span(reinterpret_cast<Pixel*>(image.data.get()), image.size / sizeof(Pixel));

for (auto i = 0; i < total; i++) {
ref[i] = Pixel{
Expand Down
10 changes: 5 additions & 5 deletions source/view/collection_grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ RecyclingGridItem *DataSource::cellForRow(RecyclingGrid *recycler, size_t index)
RecyclerCell *item = (RecyclerCell *)recycler->dequeueReusableCell("Cell");
brls::Logger::debug("image: {}", items[index].file);

if (items[index].image.img == nullptr) {
if (items[index].image.data.get() == nullptr) {
items[index].image = Image(items[index].file);
}

item->image->setImageFromMemRGBA(items[index].image.img, items[index].image.x, items[index].image.y);
item->image->setImageFromMemRGBA(items[index].image.data.get(), items[index].image.x, items[index].image.y);
item->img = items[index].file;
return item;
}
Expand All @@ -69,7 +69,7 @@ void DataSource::updateCell(RecyclingGridItem* item, size_t index)
{
auto cell = dynamic_cast<RecyclerCell*>(item);
if (cell) {
cell->image->setImageFromMemRGBA(items[index].image.img, items[index].image.x, items[index].image.y);
cell->image->setImageFromMemRGBA(items[index].image.data.get(), items[index].image.x, items[index].image.y);
}
}

Expand Down Expand Up @@ -132,12 +132,12 @@ CollectionGrid::CollectionGrid(const std::vector<std::string> &files, std::strin
items.push_back(CollectionItem{file, Image{}, false});
}

workingImage->setImageFromMemRGBA(state.working.img, state.working.x, state.working.y);
workingImage->setImageFromMemRGBA(state.working.data.get(), state.working.x, state.working.y);
recycler->registerCell("Cell", [view = workingImage.getView(), &state, onFocused]()
{ return RecyclerCell::create([view, &state, onFocused](std::string path)
{
onFocused(path, state);
view->setImageFromMemRGBA(state.working.img, state.working.x, state.working.y); }); });
view->setImageFromMemRGBA(state.working.data.get(), state.working.x, state.working.y); }); });
auto* data = new collection::DataSource(std::move(items), onSelected, this);
recycler->setDataSource(data);

Expand Down
10 changes: 6 additions & 4 deletions source/view/download_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ void DownloadView::downloadFile()

brls::Logger::info("Download started: {} to {}", url, downloadPath);
ProgressEvent::instance().reset();
if (!std::filesystem::exists(downloadPath))
download::downloadFile(url, downloadPath);
std::filesystem::remove(downloadPath);
download::downloadFile(url, downloadPath);
brls::Logger::info("Download complete");
downloadFinished.test_and_set();

Expand Down Expand Up @@ -112,7 +112,9 @@ void DownloadView::updateProgress()
brls::sync([ASYNC_TOKEN]()
{
ASYNC_RELEASE
this->status_percent->setText(fmt::format("{}%", (int)((ProgressEvent::instance().getStep() * 100 / ProgressEvent::instance().getMax())))); });

this->status_current->setText(fmt::format("{}/{}", ProgressEvent::instance().getStep(), ProgressEvent::instance().getMax()));
this->status_percent->setText(fmt::format("({}%)", (int)((ProgressEvent::instance().getStep() * 100 / ProgressEvent::instance().getMax())))); });
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
{
Expand All @@ -129,7 +131,7 @@ void DownloadView::updateProgress()
}
// CLEANUP
{
//std::filesystem::remove(downloadPath);
std::filesystem::remove(downloadPath);
}

// Add a button to go back after the end of the download
Expand Down
2 changes: 1 addition & 1 deletion source/view/icon_part_select.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ DataSource::DataSource(std::vector<CategoryPart> parts, std::function<void(std::
IconPartSelect::IconPartSelect(const std::vector<CategoryPart> &files, std::string subcategory, const ImageState &state, std::function<void(std::string)> onSelected, std::function<void(std::string, ImageState &state)> onFocused) : workingState(state)
{
this->inflateFromXMLRes("xml/views/icon_part_select.xml");
image->setImageFromMemRGBA(workingState.working.img, workingState.working.x, workingState.working.y);
image->setImageFromMemRGBA(workingState.working.data.get(), workingState.working.x, workingState.working.y);
recycler->registerCell("Cell", []()
{ return RecyclerCell::create(); });
recycler->setDataSource(new DataSource(files, onSelected, onFocused, this, subcategory, workingState));
Expand Down
Loading

0 comments on commit 5afa701

Please sign in to comment.