diff options
author | 53hornet <53hornet@gmail.com> | 2019-02-02 23:33:15 -0500 |
---|---|---|
committer | 53hornet <53hornet@gmail.com> | 2019-02-02 23:33:15 -0500 |
commit | db072ad4dc181eca5a1458656b130beb43f475bf (patch) | |
tree | a3c03c7f5497cb70503e2486662fa85cfb53415a /hw2/src/imageIO.ppm.cpp | |
download | csci427-master.tar.xz csci427-master.zip |
Diffstat (limited to 'hw2/src/imageIO.ppm.cpp')
-rw-r--r-- | hw2/src/imageIO.ppm.cpp | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/hw2/src/imageIO.ppm.cpp b/hw2/src/imageIO.ppm.cpp new file mode 100644 index 0000000..28dbc31 --- /dev/null +++ b/hw2/src/imageIO.ppm.cpp @@ -0,0 +1,106 @@ +/******************************************************************/ +/* This file is part of the homework assignments for CSCI-427/527 */ +/* at The College of William & Mary and authored by Pieter Peers. */ +/* No part of this file, whether altered or in original form, can */ +/* be distributed or used outside the context of CSCI-427/527 */ +/* without consent of either the College of William & Mary or */ +/* Pieter Peers. */ +/******************************************************************/ +#include "imageIO.ppm.h" +#include "errorMessage.h" + +#include <memory> +#include <cassert> +#include <cstdint> +#include <fstream> +#include <algorithm> + +////////////////////// +// Helper functions // +////////////////////// +static void skipToNewline(std::ifstream& ifs) +{ + while(ifs.get() != '\n' && ifs.good()); +} + +static void skipComments(std::ifstream& ifs) +{ + while(!ifs.eof() && ifs.peek() == '#') skipToNewline(ifs); +} + + +//////////////// +// Import PPM // +//////////////// +void importPPM(const std::string& name, image& img) +{ + // open file + std::ifstream ifs(name.c_str()); + if(!ifs.is_open()) errorMessage("Unable to open file: '%s'.", name.c_str()); + + // read header + std::string magicMark; + ifs >> magicMark; + skipToNewline(ifs); + if(magicMark != "P6") errorMessage("Unsupported PPM format (%s).", magicMark.c_str()); + + // read width & height + image::size_type width, height; + skipComments(ifs); + ifs >> width >> height; + skipToNewline(ifs); + + // allocate + img = image(width, height); + + // check magic number (again) + skipComments(ifs); + ifs >> magicMark; + skipToNewline(ifs); + if(magicMark != "255") errorMessage("Unsupported bit-depth in PPM file (%s).", magicMark.c_str()); + + // read char buffer + std::unique_ptr<uint8_t[]> tempBuffer(new uint8_t[img.size() * 3]); + ifs.read((char *)(tempBuffer.get()), img.size() * 3); + + // convert to image + std::transform(tempBuffer.get(), tempBuffer.get() + (img.size()*3), img.begin()->begin(), [](uint8_t val) + { + return (float)(val) / 255.0f; + }); + + // Done. +} + + +//////////////// +// Export PPM // +//////////////// +void exportPPM(const std::string& name, const image& img) +{ + // sanity check + assert(img.width() != 0 && img.height() != 0); + + // open file + std::ofstream ofs(name.c_str()); + if(!ofs.is_open()) errorMessage("Unable to open file: '%s'.", name.c_str()); + + // write header + ofs << "P6\n" << img.width() << " " << img.height() << "\n" << "255\n"; + + // convert to char buffer + std::unique_ptr<uint8_t[]> tempBuffer(new uint8_t[img.size() * 3]); + std::transform(img.begin()->begin(), img.end()->begin(), tempBuffer.get(), [](float val) + { + return (val < 0.0f) ? 0 : + (val > 1.0f) ? 255 : + uint8_t(val*255); + }); + + // write body + ofs.write((const char*)(tempBuffer.get()), img.size() * 3); + + // Done. +} + + |