#include "grid.h" extern "C" { #include "pgm.h" #include "ppm.h" #undef min #undef max } #include #include #include void resize(int xsize, int ysize, grid* out, depth def) { out->resize(xsize); for (int x = 0; x < xsize; ++x) (*out)[x].resize(ysize, def); } static void init() { static int is_init = 0; if (is_init++) return; pm_init("boring", 0); } void read_pgm(char const* filename, grid* out, depth* zsize) { init(); FILE* fp = filename ? fopen(filename, "rb") : stdin; if (fp == NULL) { perror(filename); exit(1); } int cols, rows; gray maxval, **data = pgm_readpgm(fp, &cols, &rows, &maxval); if (filename) fclose(fp); resize(cols, rows, out); for (int x = 0; x < cols; ++x) for (int y = 0; y < rows; ++y) (*out)[x][rows - 1 - y] = data[y][x] ? maxval - data[y][x] : BOTTOM; pgm_freearray(data, rows); if (zsize) *zsize = maxval; } void write_pgm(grid const& in, char const* filename, depth zsize) { init(); FILE* fp = filename ? fopen(filename, "wb") : stdout; if (fp == NULL) { perror(filename); exit(1); } if (zsize == 0) { for (int x = 0; x < xsize(in); ++x) for (int y = 0; y < ysize(in); ++y) if (in[x][y] < BOTTOM && in[x][y] >= zsize) zsize = in[x][y] + 1; } gray** out = pgm_allocarray(xsize(in), ysize(in)); for (int x = 0; x < xsize(in); ++x) for (int y = 0; y < ysize(in); ++y) out[ysize(in) - 1 - y][x] = std::max(0, zsize - in[x][y]); pgm_writepgm(fp, out, xsize(in), ysize(in), zsize, 0); pgm_freearray(out, ysize(in)); if (filename) fclose(fp); } void write_ppm(grid const& in, char const* filename) { init(); FILE* fp = filename ? fopen(filename, "wb") : stdout; if (fp == NULL) { perror(filename); exit(1); } pixel** out = ppm_allocarray(xsize(in), ysize(in)); for (int x = 0; x < xsize(in); ++x) { for (int y = 0; y < ysize(in); ++y) { int outy = ysize(in) - 1 - y; PPM_PUTR(out[outy][x], 0xFF & in[x][y] >> 11 << 3); PPM_PUTG(out[outy][x], 0xFF & in[x][y] >> 5 << 2); PPM_PUTB(out[outy][x], 0xFF & in[x][y] << 3); } } ppm_writeppm(fp, out, xsize(in), ysize(in), 0xFF, 0); ppm_freearray(out, ysize(in)); if (filename) fclose(fp); }