Skip to content

Commit d9fb3f6

Browse files
committed
Added Z files.
1 parent 8c91b7f commit d9fb3f6

File tree

3 files changed

+355
-0
lines changed

3 files changed

+355
-0
lines changed

tlRender/lib/tlIO/ZFile.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
// Copyright (c) 2021-2024 Darby Johnston
3+
// All rights reserved.
4+
5+
#include <tlIO/ZFile.h>
6+
7+
#include <tlCore/Error.h>
8+
#include <tlCore/String.h>
9+
#include <tlCore/StringFormat.h>
10+
11+
#include <array>
12+
#include <sstream>
13+
14+
namespace tl
15+
{
16+
namespace zfile
17+
{
18+
19+
Plugin::Plugin() {}
20+
21+
std::shared_ptr<Plugin> Plugin::create(
22+
const std::shared_ptr<io::Cache>& cache,
23+
const std::weak_ptr<log::System>& logSystem)
24+
{
25+
auto out = std::shared_ptr<Plugin>(new Plugin);
26+
out->_init(
27+
"zFile",
28+
{
29+
{".z", io::FileType::Sequence},
30+
{".zfile", io::FileType::Sequence},
31+
},
32+
cache, logSystem);
33+
return out;
34+
}
35+
36+
std::shared_ptr<io::IRead>
37+
Plugin::read(const file::Path& path, const io::Options& options)
38+
{
39+
return Read::create(path, options, _cache, _logSystem);
40+
}
41+
42+
std::shared_ptr<io::IRead> Plugin::read(
43+
const file::Path& path, const std::vector<file::MemoryRead>& memory,
44+
const io::Options& options)
45+
{
46+
return Read::create(path, memory, options, _cache, _logSystem);
47+
}
48+
} // namespace zfile
49+
} // namespace tl

tlRender/lib/tlIO/ZFile.h

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
// Copyright (c) 2021-2024 Darby Johnston
3+
// All rights reserved.
4+
5+
#pragma once
6+
7+
#include <zlib.h>
8+
9+
#include <tlIO/SequenceIO.h>
10+
11+
#include <tlCore/FileIO.h>
12+
#include <tlCore/Matrix.h>
13+
14+
namespace tl
15+
{
16+
//! ZFILE image I/O.
17+
//!
18+
//! References:
19+
//! https://github.com/nothings/zfile.git
20+
//!
21+
namespace zfile
22+
{
23+
//! ZFILE reader.
24+
class Read : public io::ISequenceRead
25+
{
26+
protected:
27+
void _init(
28+
const file::Path&, const std::vector<file::MemoryRead>&,
29+
const io::Options&, const std::shared_ptr<io::Cache>&,
30+
const std::weak_ptr<log::System>&);
31+
32+
Read();
33+
34+
public:
35+
virtual ~Read();
36+
37+
//! Create a new reader.
38+
static std::shared_ptr<Read> create(
39+
const file::Path&, const io::Options&,
40+
const std::shared_ptr<io::Cache>&,
41+
const std::weak_ptr<log::System>&);
42+
43+
//! Create a new reader.
44+
static std::shared_ptr<Read> create(
45+
const file::Path&, const std::vector<file::MemoryRead>&,
46+
const io::Options&, const std::shared_ptr<io::Cache>&,
47+
const std::weak_ptr<log::System>&);
48+
49+
protected:
50+
io::Info _getInfo(
51+
const std::string& fileName, const file::MemoryRead*) override;
52+
io::VideoData _readVideo(
53+
const std::string& fileName, const file::MemoryRead*,
54+
const otime::RationalTime&, const io::Options&) override;
55+
};
56+
57+
//! ZFILE plugin.
58+
class Plugin : public io::IPlugin
59+
{
60+
protected:
61+
Plugin();
62+
63+
public:
64+
//! Create a new plugin.
65+
static std::shared_ptr<Plugin> create(
66+
const std::shared_ptr<io::Cache>&,
67+
const std::weak_ptr<log::System>&);
68+
69+
std::shared_ptr<io::IRead> read(
70+
const file::Path&, const io::Options& = io::Options()) override;
71+
std::shared_ptr<io::IRead> read(
72+
const file::Path&, const std::vector<file::MemoryRead>&,
73+
const io::Options& = io::Options()) override;
74+
image::Info getWriteInfo(
75+
const image::Info&,
76+
const io::Options& = io::Options()) const override
77+
{
78+
image::Info out;
79+
return out;
80+
}
81+
std::shared_ptr<io::IWrite> write(
82+
const file::Path&, const io::Info&,
83+
const io::Options& = io::Options()) override
84+
{
85+
std::shared_ptr<io::IWrite> out;
86+
return out;
87+
}
88+
};
89+
} // namespace zfile
90+
} // namespace tl

tlRender/lib/tlIO/ZFileRead.cpp

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
// Copyright (c) 2021-2024 Darby Johnston
3+
// All rights reserved.
4+
5+
#include <tlIO/Normalize.h>
6+
#include <tlIO/ZFile.h>
7+
8+
#include <tlCore/StringFormat.h>
9+
10+
namespace tl
11+
{
12+
namespace
13+
{
14+
template<class T>
15+
inline T
16+
byteswap(T n)
17+
{
18+
unsigned char* c = reinterpret_cast<unsigned char*>(&n);
19+
if (sizeof(T) == 2) {
20+
std::swap(c[0], c[1]);
21+
} else if (sizeof(T) == 4) {
22+
std::swap(c[0], c[3]);
23+
std::swap(c[1], c[2]);
24+
} else if (sizeof(T) == 8) {
25+
std::swap(c[0], c[7]);
26+
std::swap(c[1], c[6]);
27+
std::swap(c[2], c[5]);
28+
std::swap(c[3], c[4]);
29+
}
30+
return n;
31+
}
32+
33+
template<class T>
34+
inline void
35+
swap_endian(T* vals, int len = 1)
36+
{
37+
for (int i = 0; i < len; ++i)
38+
vals[i] = byteswap(vals[i]);
39+
}
40+
41+
}
42+
43+
44+
namespace zfile
45+
{
46+
namespace
47+
{
48+
49+
static const int kMagic = 0x2f0867ab;
50+
static const int kMagicEndian = 0xab67082f;
51+
52+
//! Struct used for header of a Pixar shadow map file
53+
struct Header
54+
{
55+
unsigned int magic;
56+
short width;
57+
short height;
58+
math::Matrix4x4f worldToScreen;
59+
math::Matrix4x4f worldToCamera;
60+
};
61+
62+
class File
63+
{
64+
public:
65+
File(const std::string& fileName)
66+
{
67+
image::Info info;
68+
int res = 0, w = 0, h = 0, n = 0, bits = 8;
69+
70+
_gz = gzopen(fileName.c_str(), "rb");
71+
if (!_gz)
72+
{
73+
throw std::runtime_error(string::Format("{0}: {1}")
74+
.arg(fileName)
75+
.arg("Coult not open fileName"));
76+
}
77+
78+
Header header;
79+
gzread(_gz, &header, sizeof(header));
80+
81+
if (header.magic != kMagic && header.magic != kMagicEndian)
82+
{
83+
throw std::runtime_error(string::Format("{0}: {1}")
84+
.arg(fileName)
85+
.arg("Not a valid Pixar's Zfile"));
86+
}
87+
88+
_swapEndian = (header.magic == kMagicEndian);
89+
90+
info.size.w = header.width;
91+
info.size.h = header.height;
92+
info.pixelType = image::PixelType::L_F32;
93+
94+
if (_swapEndian)
95+
{
96+
swap_endian(&info.size.w);
97+
swap_endian(&info.size.h);
98+
swap_endian((float*)header.worldToScreen.e, sizeof(math::Matrix4x4f));
99+
swap_endian((float*)header.worldToCamera.e, sizeof(math::Matrix4x4f));
100+
}
101+
102+
_worldToScreen = header.worldToScreen;
103+
_worldToCamera = header.worldToCamera;
104+
105+
_info.video.push_back(info);
106+
}
107+
108+
~File()
109+
{
110+
if (_gz)
111+
{
112+
gzclose(_gz);
113+
_gz = 0;
114+
}
115+
}
116+
117+
const io::Info& getInfo() const { return _info; }
118+
119+
io::VideoData read(
120+
const std::string& fileName,
121+
const otime::RationalTime& time)
122+
{
123+
io::VideoData out;
124+
out.time = time;
125+
126+
const image::Info& info = _info.video[0];
127+
out.image = image::Image::create(info);
128+
129+
gzread(_gz, out.image->getData(), info.size.w * info.size.h * sizeof(float));
130+
131+
if (_swapEndian)
132+
{
133+
swap_endian(reinterpret_cast<float*>(out.image->getData()),
134+
info.size.w * info.size.h);
135+
}
136+
137+
{
138+
std::stringstream o;
139+
o << _worldToScreen;
140+
_info.tags["worldToScreen"] = o.str();
141+
}
142+
143+
{
144+
std::stringstream o;
145+
o << _worldToCamera;
146+
_info.tags["worldToCamera"] = o.str();
147+
}
148+
149+
out.image->setTags(_info.tags);
150+
151+
return out;
152+
}
153+
154+
private:
155+
io::Info _info;
156+
bool _swapEndian = false;
157+
gzFile _gz; ///< Handle for compressed files
158+
math::Matrix4x4f _worldToScreen;
159+
math::Matrix4x4f _worldToCamera;
160+
};
161+
} // namespace
162+
163+
void Read::_init(
164+
const file::Path& path, const std::vector<file::MemoryRead>& memory,
165+
const io::Options& options, const std::shared_ptr<io::Cache>& cache,
166+
const std::weak_ptr<log::System>& logSystem)
167+
{
168+
ISequenceRead::_init(path, memory, options, cache, logSystem);
169+
}
170+
171+
Read::Read() {}
172+
173+
Read::~Read()
174+
{
175+
_finish();
176+
}
177+
178+
std::shared_ptr<Read> Read::create(
179+
const file::Path& path, const io::Options& options,
180+
const std::shared_ptr<io::Cache>& cache,
181+
const std::weak_ptr<log::System>& logSystem)
182+
{
183+
auto out = std::shared_ptr<Read>(new Read);
184+
out->_init(path, {}, options, cache, logSystem);
185+
return out;
186+
}
187+
188+
std::shared_ptr<Read> Read::create(
189+
const file::Path& path, const std::vector<file::MemoryRead>& memory,
190+
const io::Options& options, const std::shared_ptr<io::Cache>& cache,
191+
const std::weak_ptr<log::System>& logSystem)
192+
{
193+
auto out = std::shared_ptr<Read>(new Read);
194+
out->_init(path, memory, options, cache, logSystem);
195+
return out;
196+
}
197+
198+
io::Info Read::_getInfo(
199+
const std::string& fileName, const file::MemoryRead* memory)
200+
{
201+
io::Info out = File(fileName).getInfo();
202+
out.videoTime =
203+
otime::TimeRange::range_from_start_end_time_inclusive(
204+
otime::RationalTime(_startFrame, _defaultSpeed),
205+
otime::RationalTime(_endFrame, _defaultSpeed));
206+
return out;
207+
}
208+
209+
io::VideoData Read::_readVideo(
210+
const std::string& fileName, const file::MemoryRead* memory,
211+
const otime::RationalTime& time, const io::Options&)
212+
{
213+
return File(fileName).read(fileName, time);
214+
}
215+
} // namespace stb
216+
} // namespace tl

0 commit comments

Comments
 (0)