From df3d323677f4cf5e9743a2154f3fc942d5e620dc Mon Sep 17 00:00:00 2001 From: Joshua Minor Date: Sat, 9 Nov 2024 21:03:35 -0800 Subject: [PATCH 01/10] Added minizip-ng submodule Signed-off-by: Joshua Minor --- .gitmodules | 3 +++ libs/minizip-ng | 1 + 2 files changed, 4 insertions(+) create mode 160000 libs/minizip-ng diff --git a/.gitmodules b/.gitmodules index 1c493e5..a425b63 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "libs/ImGuiColorTextEdit"] path = libs/ImGuiColorTextEdit url = https://github.com/jminor/ImGuiColorTextEdit.git +[submodule "libs/minizip-ng"] + path = libs/minizip-ng + url = https://github.com/zlib-ng/minizip-ng.git diff --git a/libs/minizip-ng b/libs/minizip-ng new file mode 160000 index 0000000..fe5fedc --- /dev/null +++ b/libs/minizip-ng @@ -0,0 +1 @@ +Subproject commit fe5fedc365f7824ada0cf9a84fb79b30d5fc97a8 From 6edf5e502aa9a4b5cbd70ae9c8e95d01b83c123d Mon Sep 17 00:00:00 2001 From: Joshua Minor Date: Sat, 9 Nov 2024 21:41:24 -0800 Subject: [PATCH 02/10] Stubs for loading OTIOZ Signed-off-by: Joshua Minor --- app.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/app.cpp b/app.cpp index e26e4ee..188a47c 100644 --- a/app.cpp +++ b/app.cpp @@ -1,5 +1,6 @@ // Raven NLE +#include #include #include #include @@ -271,9 +272,7 @@ void LoadString(std::string json) { elapsed_seconds); } -void LoadFile(std::string path) { - auto start = std::chrono::high_resolution_clock::now(); - +otio::Timeline* LoadOTIOFile(std::string path) { otio::ErrorStatus error_status; auto timeline = dynamic_cast( otio::Timeline::from_json_file(path, &error_status)); @@ -282,9 +281,44 @@ void LoadFile(std::string path) { "Error loading \"%s\": %s", path.c_str(), otio_error_string(error_status).c_str()); + return nullptr; + } + return timeline; +} + +otio::Timeline* LoadOTIOZFile(std::string path) { + return nullptr; +} + +std::string FileExtension(std::string path) { + return path.substr(path.find_last_of(".") + 1); +} + +std::string LowerCase(std::string str) { + std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) { return std::tolower(c); }); // 🙄 + return str; +} + +void LoadFile(std::string path) { + otio::Timeline* timeline = nullptr; + + auto start = std::chrono::high_resolution_clock::now(); + + auto ext = LowerCase(FileExtension(path)); + if (ext == "otio") { + timeline = LoadOTIOFile(path); + } else if (ext == "otioz") { + timeline = LoadOTIOZFile(path); + } else { + Message( + "Unsupported file type \"%s\"", + ext.c_str()); return; } + if (!timeline) + return; + LoadTimeline(timeline); appState.file_path = path; @@ -335,11 +369,13 @@ void MainInit(int argc, char** argv, int initial_width, int initial_height) { LoadFonts(); + // Load an empty timeline if no file is provided + // or if loading the file fails for some reason. + auto tl = new otio::Timeline(); + LoadTimeline(tl); + if (argc > 1) { LoadFile(argv[1]); - } else { - auto tl = new otio::Timeline(); - LoadTimeline(tl); } } @@ -348,7 +384,7 @@ void MainCleanup() { } // Validate that a file has the .otio extension bool is_valid_file(const std::string& filepath) { size_t last_dot = filepath.find_last_of('.'); - + // If no dot is found, it's not a valid file if (last_dot == std::string::npos) { return false; @@ -863,7 +899,7 @@ void DrawDroppedFilesPrompt() { // Modal window for confirmation if (ImGui::BeginPopupModal("Open File?", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { ImGui::Text("Open file \n%s?", prompt_dropped_file.c_str()); - + if (ImGui::Button("Yes")) { LoadFile(prompt_dropped_file); prompt_dropped_file = ""; From d3759077a5d6f59fac34e22abf6da862e021e32c Mon Sep 17 00:00:00 2001 From: Joshua Minor Date: Sat, 9 Nov 2024 21:41:39 -0800 Subject: [PATCH 03/10] Build and link minizip-ng Signed-off-by: Joshua Minor --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index efcebde..80eae96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,6 +66,8 @@ if(NOT EMSCRIPTEN AND NOT WIN32) add_subdirectory("libs/glfw") endif() +add_subdirectory("libs/minizip-ng") + if(NOT EMSCRIPTEN) add_custom_command( OUTPUT "${PROJECT_SOURCE_DIR}/fonts/embedded_font.inc" @@ -81,6 +83,7 @@ target_compile_definitions(raven target_link_libraries(raven PUBLIC OTIO::opentimelineio IMGUI + MINIZIP::minizip ) if (APPLE) From 0c0b918a19895045ca38b14a55cf78d0a683e7a9 Mon Sep 17 00:00:00 2001 From: Joshua Minor Date: Sat, 9 Nov 2024 22:36:34 -0800 Subject: [PATCH 04/10] Reads content.otio from OTIOZ files Signed-off-by: Joshua Minor --- app.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/app.cpp b/app.cpp index 188a47c..fd008f9 100644 --- a/app.cpp +++ b/app.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -16,6 +17,11 @@ #include "nfd.h" #endif +#include "mz.h" +#include "mz_zip.h" +#include "mz_strm.h" +#include "mz_zip_rw.h" + #include "fonts/embedded_font.inc" #include @@ -287,7 +293,75 @@ otio::Timeline* LoadOTIOFile(std::string path) { } otio::Timeline* LoadOTIOZFile(std::string path) { - return nullptr; + otio::Timeline* timeline = nullptr; + + void *zip_reader = mz_zip_reader_create(); + + auto status = mz_zip_reader_open_file(zip_reader, path.c_str()); + if (status != MZ_OK) { + Message( + "Error opening \"%s\": %d", + path.c_str(), + status); + } else { + status = mz_zip_reader_locate_entry(zip_reader, "content.otio", 1); + if (status != MZ_OK) { + Message( + "Invalid OTIOZ: \"%s\": \"content.otio\" not found in archive.", + path.c_str()); + } else { + mz_zip_file *file_info = NULL; + status = mz_zip_reader_entry_get_info(zip_reader, &file_info); + if (status != MZ_OK) { + Message( + "Invalid OTIOZ: \"%s\": Error getting entry info: %d", + path.c_str(), + status); + } else { + status = mz_zip_reader_entry_open(zip_reader); + if (status != MZ_OK) { + Message( + "Invalid OTIOZ: \"%s\": Unable to open entry: %d", + path.c_str(), + status); + } else { + char* buf = (char*)malloc(file_info->uncompressed_size + 1); + char* buf_cursor = buf; + int64_t bytes_remaining = file_info->uncompressed_size; + int32_t bytes_read = 0; + while (bytes_remaining > 0) { + int32_t chunk_size = bytes_remaining < INT32_MAX ? bytes_remaining : INT32_MAX; + bytes_read = mz_zip_reader_entry_read(zip_reader, buf_cursor, chunk_size); + if (bytes_read > 0) { + bytes_remaining -= bytes_read; + buf_cursor += bytes_read; + } else { + break; + } + } + if (bytes_remaining != 0) { + Message( + "Invalid OTIOZ: \"%s\": Error reading entry: %ld", + path.c_str(), + bytes_remaining); + } else { + // Add a null terminator + buf[file_info->uncompressed_size] = '\0'; + std::string json(buf); + timeline = dynamic_cast( + otio::Timeline::from_json_string(json)); + } + mz_zip_reader_entry_close(zip_reader); + } + } + } + + mz_zip_reader_close(zip_reader); + } + + mz_zip_reader_delete(&zip_reader); + + return timeline; } std::string FileExtension(std::string path) { From 96cc8ddff5695e2f550d45c7f4962653ba77652c Mon Sep 17 00:00:00 2001 From: Joshua Minor Date: Sat, 9 Nov 2024 22:59:56 -0800 Subject: [PATCH 05/10] Free memory allocated during OTIOZ decompression. Signed-off-by: Joshua Minor --- app.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/app.cpp b/app.cpp index fd008f9..decd8ec 100644 --- a/app.cpp +++ b/app.cpp @@ -351,6 +351,7 @@ otio::Timeline* LoadOTIOZFile(std::string path) { timeline = dynamic_cast( otio::Timeline::from_json_string(json)); } + free(buf); mz_zip_reader_entry_close(zip_reader); } } From b2ef4a9bbb6f2884cf76a912d6d9ccd080ba6b7a Mon Sep 17 00:00:00 2001 From: Joshua Minor Date: Sun, 10 Nov 2024 20:24:24 -0800 Subject: [PATCH 06/10] Turned off majority of minizip-ng options to reduce unwanted dependencies Signed-off-by: Joshua Minor --- CMakeLists.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 80eae96..f4a7feb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,6 +66,17 @@ if(NOT EMSCRIPTEN AND NOT WIN32) add_subdirectory("libs/glfw") endif() +set(MZ_BZIP2 OFF) +set(MZ_LZMA OFF) +set(MZ_ZSTD OFF) +set(MZ_LIBCOMP OFF) +set(MZ_FETCH_LIBS OFF) +set(MZ_PKCRYPT OFF) +set(MZ_WZAES OFF) +set(MZ_OPENSSL OFF) +set(MZ_BCRYPT OFF) +set(MZ_LIBBSD OFF) +set(MZ_ICONV OFF) add_subdirectory("libs/minizip-ng") if(NOT EMSCRIPTEN) From 04ea39319f62a104f813a41fa5f9f6fe0ea40a36 Mon Sep 17 00:00:00 2001 From: Joshua Minor Date: Wed, 13 Nov 2024 22:05:27 -0800 Subject: [PATCH 07/10] Attempting to fix Windows build Signed-off-by: Joshua Minor --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index f4a7feb..1bb2753 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,8 @@ set(MZ_OPENSSL OFF) set(MZ_BCRYPT OFF) set(MZ_LIBBSD OFF) set(MZ_ICONV OFF) +set(MZ_ZLIB ON) +set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) add_subdirectory("libs/minizip-ng") if(NOT EMSCRIPTEN) From 63eb43de9b3ba4a24c068bbd96b99151349e88e7 Mon Sep 17 00:00:00 2001 From: Joshua Minor Date: Wed, 13 Nov 2024 22:23:57 -0800 Subject: [PATCH 08/10] Validate input file path Signed-off-by: Joshua Minor --- app.cpp | 51 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/app.cpp b/app.cpp index decd8ec..af0ca6b 100644 --- a/app.cpp +++ b/app.cpp @@ -25,7 +25,7 @@ #include "fonts/embedded_font.inc" #include -#include +#include void DrawMenu(); void DrawToolbar(ImVec2 buttonSize); @@ -374,11 +374,39 @@ std::string LowerCase(std::string str) { return str; } +// Validate that a file has the .otio or .otioz extension +bool SupportedFileType(const std::string& filepath) { + size_t last_dot = filepath.find_last_of('.'); + + // If no dot is found, it's not a valid file + if (last_dot == std::string::npos) { + return false; + } + + // Get and check the extension + std::string extension = filepath.substr(last_dot + 1); + return extension == "otio" || extension == "otioz"; +} + void LoadFile(std::string path) { otio::Timeline* timeline = nullptr; auto start = std::chrono::high_resolution_clock::now(); + if (!std::filesystem::exists(path)) { + Message( + "File not found \"%s\"", + path.c_str()); + return; + } + + if (!SupportedFileType(path)) { + Message( + "Unsuported file type \"%s\"", + path.c_str()); + return; + } + auto ext = LowerCase(FileExtension(path)); if (ext == "otio") { timeline = LoadOTIOFile(path); @@ -403,7 +431,7 @@ void LoadFile(std::string path) { double elapsed_seconds = elapsed.count(); Message( "Loaded \"%s\" in %.3f seconds", - timeline->name().c_str(), + path.c_str(), elapsed_seconds); } @@ -456,20 +484,6 @@ void MainInit(int argc, char** argv, int initial_width, int initial_height) { void MainCleanup() { } -// Validate that a file has the .otio extension -bool is_valid_file(const std::string& filepath) { - size_t last_dot = filepath.find_last_of('.'); - - // If no dot is found, it's not a valid file - if (last_dot == std::string::npos) { - return false; - } - - // Get and check the extension - std::string extension = filepath.substr(last_dot + 1); - return extension == "otio"; -} - // Accept and open a file path void FileDropCallback(int count, const char** filepaths) { if (count > 1){ @@ -483,14 +497,13 @@ void FileDropCallback(int count, const char** filepaths) { std::string file_path = filepaths[0]; - if (!is_valid_file(file_path)){ - Message("Invalid file: %s", file_path.c_str()); + if (!SupportedFileType(file_path)){ + Message("Unsupported file type: %s", file_path.c_str()); return; } // Loading is done in DrawDroppedFilesPrompt() prompt_dropped_file = file_path; - } // Make a button using the fancy icon font From cb245b8fd19e9666c769f09d0c0ed4959e3aaa76 Mon Sep 17 00:00:00 2001 From: Joshua Minor Date: Thu, 14 Nov 2024 07:35:57 -0800 Subject: [PATCH 09/10] Tweaking Windows build settings Signed-off-by: Joshua Minor --- CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1bb2753..e7a9e49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,6 +66,12 @@ if(NOT EMSCRIPTEN AND NOT WIN32) add_subdirectory("libs/glfw") endif() +# minizip-ng +set(BUILD_SHARED_LIBS OFF) +set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) +set(MZ_FETCH_LIBS ON) +set(MZ_ZLIB ON) +# OTIOZ doesn't need any of these set(MZ_BZIP2 OFF) set(MZ_LZMA OFF) set(MZ_ZSTD OFF) @@ -77,8 +83,6 @@ set(MZ_OPENSSL OFF) set(MZ_BCRYPT OFF) set(MZ_LIBBSD OFF) set(MZ_ICONV OFF) -set(MZ_ZLIB ON) -set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) add_subdirectory("libs/minizip-ng") if(NOT EMSCRIPTEN) From 86be63e43ce9407d3bb4471b2fd3a72e987db0a4 Mon Sep 17 00:00:00 2001 From: Joshua Minor Date: Thu, 14 Nov 2024 10:13:37 -0800 Subject: [PATCH 10/10] Removed incorrect toggle Signed-off-by: Joshua Minor --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e7a9e49..93382c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,7 +76,6 @@ set(MZ_BZIP2 OFF) set(MZ_LZMA OFF) set(MZ_ZSTD OFF) set(MZ_LIBCOMP OFF) -set(MZ_FETCH_LIBS OFF) set(MZ_PKCRYPT OFF) set(MZ_WZAES OFF) set(MZ_OPENSSL OFF)