summaryrefslogtreecommitdiff
path: root/hw2/src/imageIO.ppm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'hw2/src/imageIO.ppm.cpp')
-rw-r--r--hw2/src/imageIO.ppm.cpp106
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.
+}
+
+