71namespace ca_gif_detail {
82 out.put(
static_cast<char>(
value & 0xffu));
83 out.put(
static_cast<char>((
value >> 8) & 0xffu));
88 const int dr =
static_cast<int>(a.r) -
static_cast<int>(b.r);
89 const int dg =
static_cast<int>(a.g) -
static_cast<int>(b.g);
90 const int db =
static_cast<int>(a.b) -
static_cast<int>(b.b);
91 return static_cast<std::uint32_t
>(dr * dr + dg * dg +
db *
db);
96 for (std::size_t i = 0; i <
palette.size(); ++i)
98 return static_cast<std::uint8_t
>(i);
102 return static_cast<std::uint8_t
>(
palette.size() - 1);
105 std::size_t
best = 0;
106 std::uint32_t
best_d = std::numeric_limits<std::uint32_t>::max();
107 for (std::size_t i = 0; i <
palette.size(); ++i)
116 return static_cast<std::uint8_t
>(
best);
124 const RGB8 c)
noexcept
126 for (std::size_t i = 0; i <
palette.size(); ++i)
128 return static_cast<std::uint8_t
>(i);
130 std::size_t
best = 0;
131 std::uint32_t
best_d = std::numeric_limits<std::uint32_t>::max();
132 for (std::size_t i = 0; i <
palette.size(); ++i)
141 return static_cast<std::uint8_t
>(
best);
187 const unsigned end = clear + 1u;
189 unsigned next_code = end + 1u;
194 for (std::size_t i = 0; i <
indices.size(); ++i)
202 if (next_code < 4096u)
216 while (pos < bytes.
size())
218 const std::size_t n = std::min<std::size_t>(255, bytes.
size() - pos);
219 out.put(
static_cast<char>(n));
220 out.write(
reinterpret_cast<const char *
>(&bytes.
base() + pos),
static_cast<std::streamsize
>(n));
230 for (
const Frame &f : frames)
231 for (std::size_t i = 0; i < f.pixels.size(); ++i)
259 const ca_size_t height = frames(0).height;
261 for (
const auto &f : frames)
263 <<
"write_gif: all frames must have identical dimensions";
272 out.write(
"GIF89a", 6);
276 out.put(
static_cast<char>(0x80u | 0x70u |
gct_code));
279 for (std::size_t i = 0; i <
palette.size(); ++i)
282 out.put(
static_cast<char>(c.r));
283 out.put(
static_cast<char>(c.g));
284 out.put(
static_cast<char>(c.b));
292 out.write(
"NETSCAPE2.0", 11);
299 for (
const auto &frame : frames)
306 for (std::size_t i = 0; i < frame.pixels.size(); ++i)
335template <
typename Mapper>
358 template <
typename Lattice>
363 static_assert(
Lattice::rank == 2,
"Gif_Frame_Sink requires rank-2 frames");
376 <<
"Gif_Frame_Sink::accept: frame dimensions changed";
385 if (
const auto parent = path_.parent_path();
not parent.empty())
386 std::filesystem::create_directories(parent);
387 std::ofstream
out(path_, std::ios::binary);
397 return frames_.
size();
401template <
typename Mapper>
Exception handling system with formatted messages for Aleph-w.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
#define ah_runtime_error_if(C)
Throws std::runtime_error if condition holds.
size_t size_t int32_t value
size_t size_t int32_t * out
File-format readers and writers for cellular-automata frames.
Simple dynamic array with automatic resizing and functional operations.
constexpr size_t size() const noexcept
Return the number of elements stored in the stack.
constexpr bool is_empty() const noexcept
Checks if the container is empty.
T & base()
Return a reference to the first element of array.
T & append(const T &data)
Append a copy of data
void reserve(size_t cap)
Reserves cap cells into the array.
Sink that buffers frames and writes an animated GIF on flush.
Gif_Frame_Sink(std::filesystem::path path, Mapper mapper, GIF_Write_Options opts={})
Build a GIF frame sink.
Array< ca_gif_detail::Frame > frames_
void accept(const std::size_t step, const Lattice &frame)
Collect one frame.
std::filesystem::path path_
std::size_t size() const noexcept
Return buffered frame count.
void flush() const
Write the animated GIF.
Lattice that adds boundary-aware access on top of a storage.
typename Storage::coord_type coord_type
static constexpr std::size_t rank
ca_size_t size() const noexcept
state_type at(const coord_type &c) const
Strict access: throws if c is out of range.
void write(const unsigned code, const unsigned width)
Array< std::uint8_t > finish()
Array< std::uint8_t > bytes_
Storage + topology that carries the cell values.
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
std::uint8_t palette_index(Array< RGB8 > &palette, const RGB8 c)
unsigned ceil_log2(std::size_t n)
std::uint8_t lookup_palette_index(const Array< RGB8 > &palette, const RGB8 c) noexcept
Read-only lookup variant: assumes the palette is already finalised (every colour either present or to...
Array< RGB8 > build_palette(const Array< Frame > &frames)
void write_subblocks(std::ostream &out, const Array< std::uint8_t > &bytes)
std::uint32_t dist2(const RGB8 a, const RGB8 b) noexcept
void put_le16(std::ostream &out, const std::uint16_t value)
Array< std::uint8_t > lzw_bytes(const Array< std::uint8_t > &indices, const unsigned min_code_size)
void write_gif(std::ostream &out, const Array< ca_gif_detail::Frame > &frames, const GIF_Write_Options &opts={})
Write a sequence of RGB frames as an animated GIF.
std::ptrdiff_t ca_index_t
Signed coordinate component used by lattices and neighborhoods.
std::size_t ca_size_t
Unsigned size component used for extents and counts.
Main namespace for Aleph-w library functions.
size_t size(Node *root) noexcept
and
Check uniqueness with explicit hash + equality functors.
std::string code(Node *root)
Compute a string with the Lukasiewicz`s word of a tree.
Options for animated GIF output.
bool loop
add Netscape infinite-loop extension
unsigned delay_cs
frame delay in centiseconds
RGB byte triplet used by PPM exporters.
Array< RGB8 > pixels
row-major RGB pixels
Dynamic array container with automatic resizing.
C++20 concepts for the Cellular Automata module.