97 lines
2.1 KiB
C++
97 lines
2.1 KiB
C++
#include <string>
|
|
#include <numeric>
|
|
#include <vector>
|
|
|
|
#include <imgui.h>
|
|
#include <imgui_stdlib.h>
|
|
|
|
#include "app.hh"
|
|
#include "input.hh"
|
|
|
|
#define STB_IMAGE_IMPLEMENTATION
|
|
#include <stb_image.h>
|
|
|
|
|
|
namespace pg {
|
|
namespace {
|
|
|
|
class ImgSeq final : public App, public Input::Data {
|
|
public:
|
|
static inline TypeInfo kType = TypeInfo::Create<ImgSeq>("Input_ImgSeq");
|
|
|
|
ImgSeq() noexcept : Data("imgseq") {
|
|
}
|
|
~ImgSeq() noexcept {
|
|
DropCache();
|
|
}
|
|
void DropCache() noexcept {
|
|
for (auto& frame : frames_) {
|
|
stbi_image_free(const_cast<uint8_t*>(frame.second.rgba));
|
|
}
|
|
frames_.clear();
|
|
}
|
|
|
|
void Update() noexcept override {
|
|
const auto id = std::to_string(index())+" Input_ImgSeq | "+
|
|
std::to_string(reinterpret_cast<uintptr_t>(this));
|
|
|
|
if (ImGui::Begin(id.c_str())) {
|
|
bool mod = false;
|
|
mod |= ImGui::InputText("dir", &path_);
|
|
mod |= ImGui::DragInt("start", &st_, 1, 0, 1024);
|
|
mod |= ImGui::DragInt("end", &ed_, 1, 0, 1024);
|
|
if (mod) DropCache();
|
|
|
|
if (msg_.size() > 0) {
|
|
ImGui::TextUnformatted(msg_.c_str());
|
|
}
|
|
}
|
|
ImGui::End();
|
|
}
|
|
|
|
Frame Fetch(size_t n) noexcept override
|
|
try {
|
|
n += static_cast<size_t>(st_);
|
|
if (n >= static_cast<size_t>(ed_)) {
|
|
throw "frame number out of range";
|
|
}
|
|
|
|
auto itr = frames_.find(n);
|
|
if (itr != frames_.end()) return itr->second;
|
|
|
|
const auto fname = path_+"/"+std::to_string(n)+".png";
|
|
|
|
int w, h, comp;
|
|
uint8_t* buf = stbi_load(fname.c_str(), &w, &h, &comp, 4);
|
|
if (buf == nullptr) {
|
|
throw stbi_failure_reason();
|
|
}
|
|
|
|
const Frame ret = {
|
|
.w = static_cast<size_t>(w),
|
|
.h = static_cast<size_t>(h),
|
|
.rgba = buf,
|
|
};
|
|
frames_[n] = ret;
|
|
return ret;
|
|
} catch (const char* msg) {
|
|
msg_ = msg;
|
|
return {.w = 0, .h = 0, .rgba = nullptr};
|
|
}
|
|
size_t frames() noexcept override {
|
|
if (ed_ <= st_) return 0;
|
|
return static_cast<size_t>(ed_-st_);
|
|
}
|
|
|
|
private:
|
|
std::string path_;
|
|
int st_ = 1, ed_ = 100;
|
|
|
|
std::string msg_;
|
|
|
|
std::unordered_map<size_t, Frame> frames_;
|
|
};
|
|
|
|
}
|
|
} // namespace pg
|