/******************************************************************/ /* 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 #include #include #include #include ////////////////////// // 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(), std::ifstream::binary); 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 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(), std::ofstream::binary); 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 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. }