From 78605006b15449514bfaf1671bcced804f16eaea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anger=20J=C3=A9r=C3=A9my?= Date: Sat, 20 Mar 2021 00:15:37 +0100 Subject: [PATCH] collection: Fixed and Offseted image collection (& sharedptr) this is used by the editors, with the following syntax: 2 the sequence #2, the image at position i (current player index) 2@5 the sequence #2, the image at position 5 (fixed) 2@+5 the sequence #2, the image at position i+5 2@-1 the sequence #2, the image at position i-1 --- src/EditGUI.cpp | 2 +- src/ImageCollection.cpp | 16 ++++---- src/ImageCollection.hpp | 89 +++++++++++++++++++++++++++++++++++------ src/Sequence.cpp | 4 +- src/Sequence.hpp | 4 +- src/editors.cpp | 31 +++++++++----- src/editors.hpp | 2 +- src/main.cpp | 2 +- 8 files changed, 114 insertions(+), 36 deletions(-) diff --git a/src/EditGUI.cpp b/src/EditGUI.cpp index e8319e6a..dba4dcf3 100644 --- a/src/EditGUI.cpp +++ b/src/EditGUI.cpp @@ -61,7 +61,7 @@ void EditGUI::validate(Sequence& seq) prog = std::regex_replace(prog, std::regex("\\$" + std::to_string(i+1)), val); } - ImageCollection* collection = create_edited_collection(edittype, prog); + std::shared_ptr collection = create_edited_collection(edittype, prog); if (collection) { seq.collection = collection; } diff --git a/src/ImageCollection.cpp b/src/ImageCollection.cpp index bd0455d4..2700301f 100644 --- a/src/ImageCollection.cpp +++ b/src/ImageCollection.cpp @@ -291,7 +291,7 @@ class NumpyVideoImageCollection : public VideoImageCollection { } }; -static ImageCollection* selectCollection(const std::string& filename) +static std::shared_ptr selectCollection(const std::string& filename) { struct stat st; unsigned char tag[4]; @@ -309,13 +309,13 @@ static ImageCollection* selectCollection(const std::string& filename) fclose(file); if (tag[0] == 'V' && tag[1] == 'P' && tag[2] == 'P' && tag[3] == 0) { - return new VPPVideoImageCollection(filename); + return std::make_shared(filename); } else if (tag[0] == 0x93 && tag[1] == 'N' && tag[2] == 'U' && tag[3] == 'M') { - return new NumpyVideoImageCollection(filename); + return std::make_shared(filename); } end: - return new SingleImageImageCollection(filename); + return std::make_shared(filename); } @@ -327,7 +327,7 @@ bool endswith(std::string const &fullString, std::string const &ending) { } } -ImageCollection* buildImageCollectionFromFilenames(std::vector& filenames) +std::shared_ptr buildImageCollectionFromFilenames(std::vector& filenames) { if (filenames.size() == 1) { return selectCollection(filenames[0]); @@ -335,12 +335,12 @@ ImageCollection* buildImageCollectionFromFilenames(std::vector& fil //!\ here we assume that a sequence composed of multiple files means that each file contains only one image (not true for video files) // the reason is just that it would be slow to check the tag of each file - MultipleImageCollection* collection = new MultipleImageCollection(); + std::shared_ptr collection = std::make_shared(); for (auto& f : filenames) { if (endswith(f, ".npy")) { // TODO: this is ugly, but faster than checking the tag - collection->append(new NumpyVideoImageCollection(f)); + collection->append(std::make_shared(f)); } else { - collection->append(new SingleImageImageCollection(f)); + collection->append(std::make_shared(f)); } } return collection; diff --git a/src/ImageCollection.hpp b/src/ImageCollection.hpp index 2812a789..5a2e2951 100644 --- a/src/ImageCollection.hpp +++ b/src/ImageCollection.hpp @@ -20,10 +20,10 @@ class ImageCollection { virtual void onFileReload(const std::string& filename) = 0; }; -ImageCollection* buildImageCollectionFromFilenames(std::vector& filenames); +std::shared_ptr buildImageCollectionFromFilenames(std::vector& filenames); class MultipleImageCollection : public ImageCollection { - std::vector collections; + std::vector> collections; std::vector lengths; int totalLength; @@ -33,13 +33,10 @@ class MultipleImageCollection : public ImageCollection { } virtual ~MultipleImageCollection() { - for (auto c : collections) { - delete c; - } collections.clear(); } - void append(ImageCollection* ic) { + void append(std::shared_ptr ic) { collections.push_back(ic); int len = ic->getLength(); lengths.push_back(len); @@ -152,19 +149,16 @@ class VideoImageCollection : public ImageCollection { class EditedImageCollection : public ImageCollection { EditType edittype; std::string editprog; - std::vector collections; + std::vector> collections; public: EditedImageCollection(EditType edittype, const std::string& editprog, - const std::vector& collections) + const std::vector>& collections) : edittype(edittype), editprog(editprog), collections(collections) { } virtual ~EditedImageCollection() { - for (auto c : collections) { - delete c; - } collections.clear(); } @@ -205,7 +199,7 @@ class MaskedImageCollection : public ImageCollection { public: - MaskedImageCollection(ImageCollection* parent, int masked) + MaskedImageCollection(std::shared_ptr parent, int masked) : parent(parent), masked(masked) { } @@ -239,3 +233,74 @@ class MaskedImageCollection : public ImageCollection { } }; +class FixedImageCollection : public ImageCollection { + std::shared_ptr parent; + int index; + +public: + + FixedImageCollection(std::shared_ptr parent, int index) + : parent(parent), index(index) { + } + + virtual ~FixedImageCollection() { + } + + const std::string& getFilename(int) const { + return parent->getFilename(index); + } + + std::string getKey(int) const { + return parent->getKey(index); + } + + int getLength() const { + return 1; + } + + std::shared_ptr getImageProvider(int) const { + return parent->getImageProvider(index); + } + + void onFileReload(const std::string& filename) { + parent->onFileReload(filename); + } +}; + +class OffsetedImageCollection : public ImageCollection { + std::shared_ptr parent; + int offset; + +public: + + OffsetedImageCollection(std::shared_ptr parent, int offset) + : parent(parent), offset(offset) { + } + + virtual ~OffsetedImageCollection() { + } + + const std::string& getFilename(int index) const { + index = std::max(0, index + offset); + return parent->getFilename(index); + } + + std::string getKey(int index) const { + index = std::max(0, index + offset); + return parent->getKey(index); + } + + int getLength() const { + return parent->getLength() - offset; + } + + std::shared_ptr getImageProvider(int index) const { + index = std::max(0, index + offset); + return parent->getImageProvider(index); + } + + void onFileReload(const std::string& filename) { + parent->onFileReload(filename); + } +}; + diff --git a/src/Sequence.cpp b/src/Sequence.cpp index 7fbd002e..26c9aeef 100644 --- a/src/Sequence.cpp +++ b/src/Sequence.cpp @@ -130,7 +130,7 @@ void Sequence::loadFilenames() { filenames.push_back("-"); } - ImageCollection* col = buildImageCollectionFromFilenames(filenames); + std::shared_ptr col = buildImageCollectionFromFilenames(filenames); this->collection = col; this->uneditedCollection = col; @@ -502,7 +502,7 @@ void Sequence::removeCurrentFrame() return; } int index = player->frame - 1; - collection = new MaskedImageCollection(uneditedCollection, index); + collection = std::make_shared(uneditedCollection, index); uneditedCollection = collection; editGUI->validate(*this); player->reconfigureBounds(); diff --git a/src/Sequence.hpp b/src/Sequence.hpp index 993658fe..f84feca9 100644 --- a/src/Sequence.hpp +++ b/src/Sequence.hpp @@ -25,7 +25,7 @@ struct Sequence { std::string glob; std::string glob_; - ImageCollection* collection; + std::shared_ptr collection; std::vector svgglobs; std::vector> svgcollection; std::map> scriptSVGs; @@ -41,7 +41,7 @@ struct Sequence { std::shared_ptr image; std::string error; - ImageCollection* uneditedCollection; + std::shared_ptr uneditedCollection; EditGUI* editGUI; Sequence(); diff --git a/src/editors.cpp b/src/editors.cpp index 72d06888..8a47f576 100644 --- a/src/editors.cpp +++ b/src/editors.cpp @@ -229,30 +229,43 @@ std::shared_ptr edit_images(EditType edittype, const std::string& _prog, #include "Sequence.hpp" #include "globals.hpp" -ImageCollection* create_edited_collection(EditType edittype, const std::string& _prog) +std::shared_ptr create_edited_collection(EditType edittype, const std::string& _prog) { char* prog = (char*) _prog.c_str(); - std::vector sequences; + std::vector> collections; while (*prog && *prog != ' ') { char* old = prog; int a = strtol(prog, &prog, 10) - 1; if (prog == old) break; if (a >= 0 && a < gSequences.size()) { - sequences.push_back(gSequences[a]); + Sequence* s = gSequences[a]; + std::shared_ptr c(s->uneditedCollection); + if (*prog == '@') { + prog++; + int relative = *prog == '-' || *prog == '+'; + char* old = prog; + int a = strtol(prog, &prog, 10); + int value = a; + if (prog == old) break; + + printf("relative %d value %d\n", relative, value); + if (relative) { + c = std::make_shared(c, value); + } else { + c = std::make_shared(c, value); + } + } + collections.push_back(c); } if (*prog == ' ') break; if (*prog) prog++; } while (*prog == ' ') prog++; - if (sequences.empty()) { + if (collections.empty()) { return nullptr; } - std::vector collections; - for (auto s : sequences) { - collections.push_back(s->uneditedCollection); - } - return new EditedImageCollection(edittype, std::string(prog), collections); + return std::make_shared(edittype, std::string(prog), collections); } diff --git a/src/editors.hpp b/src/editors.hpp index f045ac98..00df7735 100644 --- a/src/editors.hpp +++ b/src/editors.hpp @@ -16,5 +16,5 @@ std::shared_ptr edit_images(EditType edittype, const std::string& prog, const std::vector>& images, std::string& error); -class ImageCollection* create_edited_collection(EditType edittype, const std::string& prog); +std::shared_ptr create_edited_collection(EditType edittype, const std::string& prog); diff --git a/src/main.cpp b/src/main.cpp index 4588b720..34f9935a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -506,7 +506,7 @@ int main(int argc, char* argv[]) for (auto seq : gSequences) { if (!seq->player) continue; - ImageCollection* collection = seq->collection; + std::shared_ptr collection = seq->collection; if (!collection || collection->getLength() == 0) continue; int frame = (seq->player->frame + i - 1) % collection->getLength();