#include #include #include #include #include "pixels.hpp" // truecolor to palette color (216-color) static inline int t2p(int val) { return round(5 * val / 255.0); } static void write(std::ostream& os, FILE* in) { bool has_truecolor = sc::term::has_truecolor(); struct pam info; pnm_readpaminit(in, &info, PAM_STRUCT_SIZE(tuple_type)); std::unique_ptr row1 {pnm_allocpamrow(&info), pm_freerow}; std::unique_ptr row2 {pnm_allocpamrow(&info), pm_freerow}; for (int y = 0; y < info.height; y += 2) { pnm_readpamrow(&info, row1.get()); pnm_readpamrow(&info, row2.get()); for (int x = 0; x < info.width; ++x) { if (info.depth == 3) { // assume RGB, 1 byte per sample tuple* t1 {row1.get()}; if (has_truecolor) { os << sc::io::truecolorb(t1[x][0], t1[x][1], t1[x][2]); } else { os << sc::io::rgbb(t2p(t1[x][0]), t2p(t1[x][1]), t2p(t1[x][2])); } tuple* t2 {row2.get()}; if (has_truecolor) { os << sc::io::truecolorf(t2[x][0], t2[x][1], t2[x][2]); } else { os << sc::io::rgbf(t2p(t2[x][0]), t2p(t2[x][1]), t2p(t2[x][2])); } os << u8"\u2584"; // unicode lower half block } } os << sc::io::reset << '\n'; } } void write_image(std::ostream& os) { write(os, stdin); } void write_image(std::ostream& os, const std::string& path) { std::unique_ptr infile {pm_openr(path.c_str()), pm_close}; write(os, infile.get()); }