diff --git a/deps/SimpleProgressBar.hpp b/deps/SimpleProgressBar.hpp new file mode 100644 index 0000000..bf7d9af --- /dev/null +++ b/deps/SimpleProgressBar.hpp @@ -0,0 +1,256 @@ +/* + * MIT License + * + * Copyright (c) 2024 Robert Myers + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file SimpleProgressBar.h + * + * @brief A simple progress bar for console applications. + * + * @author Robert Myers + * Contact: romyers@umich.edu + */ + + #pragma once + + #include + + namespace SimpleProgressBar { + + /** + * A simple progress bar for console applications. + */ + class ProgressBar { + + public: + + /** + * Constructor. + * + * @param totalSteps The total number of progress bar steps. + */ + ProgressBar(unsigned int totalSteps = 100U); + + /** + * Increments the progress displayed by the progress bar by a given + * number of steps (one by default). + * + * If increment() brings the current progress above totalSteps, + * the current progress will be snapped to totalSteps. + * + * @param steps The number of steps by which to increment the displayed + * progress. + */ + void increment(unsigned int steps = 1U); + + /** + * Retrieve the total number of steps in the progress bar. + * + * @return The total number of steps + */ + unsigned int getTotalSteps() const; + + /** + * Prints the progress bar in its current state to a stream. + * Prints to std::cout by default. + * + * @param out The stream to print to. + */ + void print(std::ostream &out = std::cout) const; + + /** + * Sets the width of the progress bar display in number of characters. + * The width of the progress bar is set to 80 characters by default. + * + * REQUIRES: w is at least 2. + * + * @param w The desired width of the progress bar, as a number of + * characters. + */ + void setWidth(unsigned int w); + + /** + * Sets the symbol for the progress bar's left endcap. + * Set to '[' by default. + * + * @param c The new symbol. + */ + void setLeftEndcapSymbol(char c); + + /** + * Sets the symbol for the progress bar's right endcap. + * Set to ']' by default. + * + * @param c The new symbol. + */ + void setRightEndcapSymbol(char c); + + /** + * Sets the symbol indicating completed progress. + * Set to '=' by default. + * + * @param c The new symbol. + */ + void setDoneSymbol(char c); + + /** + * Sets the symbol indicating progress that hasn't been completed yet. + * Set to ' ' by default. + */ + void setTodoSymbol(char c); + + /** + * Sets the progress bar to overwrite the current output line on each + * call to print(). This is equivalent to adding the '\r' character to + * the end of the printed output. + */ + void enableOverwrite(); + + /** + * Sets the progress bar not to overwrite the current output line on + * each call to print(). Successive calls to print will be printed + * one after another. + */ + void disableOverwrite(); + + private: + + unsigned int progress; + unsigned int totalSteps; + + char leftEndcapSymbol; + char rightEndcapSymbol; + char doneSymbol; + char todoSymbol; + + unsigned int width; + + bool overwrite; + + }; + + } + + /////////////////////////////////////////////////////////////////////////////// + /////////////////////////////// IMPLEMENTATION //////////////////////////////// + /////////////////////////////////////////////////////////////////////////////// + + SimpleProgressBar::ProgressBar::ProgressBar(unsigned int totalSteps) : + progress(0), + leftEndcapSymbol('['), + rightEndcapSymbol(']'), + doneSymbol('='), + todoSymbol(' '), + width(80U), + overwrite(true), + totalSteps(totalSteps) {} + + unsigned int SimpleProgressBar::ProgressBar::getTotalSteps() const { + + return totalSteps; + + } + + void SimpleProgressBar::ProgressBar::setLeftEndcapSymbol(char c) { + + leftEndcapSymbol = c; + + } + + void SimpleProgressBar::ProgressBar::setRightEndcapSymbol(char c) { + + rightEndcapSymbol = c; + + } + + void SimpleProgressBar::ProgressBar::setDoneSymbol(char c) { + + doneSymbol = c; + + } + + void SimpleProgressBar::ProgressBar::setTodoSymbol(char c) { + + todoSymbol = c; + + } + + void SimpleProgressBar::ProgressBar::setWidth(unsigned int w) { + + width = w; + + } + + void SimpleProgressBar::ProgressBar::increment(unsigned int steps) { + + progress += steps; + + if(progress > totalSteps) { + + progress = totalSteps; + + } + + } + + void SimpleProgressBar::ProgressBar::print(std::ostream &out) const { + + out << leftEndcapSymbol; + + double proportionalProgress = static_cast(progress) + / static_cast(totalSteps); + + // For nonnegative values, casting to int is equivalent to flooring. + unsigned int numBarChars = static_cast( + proportionalProgress * (width - 2) + ); + + for(unsigned int w = 0; w < numBarChars; ++w) { + + out << doneSymbol; + + } + + for(unsigned int w = numBarChars; w < width - 2; ++w) { + + out << todoSymbol; + + } + + out << rightEndcapSymbol; + out << std::flush; + if(overwrite) out << '\r'; + + } + + void SimpleProgressBar::ProgressBar::enableOverwrite() { + + overwrite = true; + + } + + void SimpleProgressBar::ProgressBar::disableOverwrite() { + + overwrite = false; + + } \ No newline at end of file diff --git a/src/seam-carving.cpp b/src/seam-carving.cpp index 80f3fd9..36a7ca2 100644 --- a/src/seam-carving.cpp +++ b/src/seam-carving.cpp @@ -10,6 +10,7 @@ #include #define STB_IMAGE_WRITE_IMPLEMENTATION #include +#include //Global flag to silent verbose messages bool silent; @@ -206,8 +207,8 @@ int main(int argc, char **argv) { } int curWidth = width; + SimpleProgressBar::ProgressBar bar(nbSeams); for (auto seam=0; seam < nbSeams; seam++) { - std::cout << seam << std::endl; std::vector opt_seam = carving_step_vertical(source_img, carve_output, curWidth, height, nbChannels); // Perform a carving step std::copy(carve_output.begin(), carve_output.end(), source_img.begin()); // Copy output to next input curWidth--; @@ -223,7 +224,10 @@ int main(int argc, char **argv) { complete_blacklist[i*width+j] = true; output[3*(i*width+j)] = 255; } + bar.increment(); + bar.print(); } + std::cout << std::endl; export_image(outputImage.c_str(), output.data(), width, height, nbChannels); @@ -234,12 +238,15 @@ int main(int argc, char **argv) { for (auto i=0; i < width*height*nbChannels; i++) { vect_source[i] = source[i]; } + SimpleProgressBar::ProgressBar bar(nbSeams); for (auto seam=0; seam < nbSeams; seam++) { - std::cout << seam << std::endl; carving_step_vertical(vect_source, output, outWidth, height, nbChannels); std::copy(output.begin(), output.end(), vect_source.begin()); outWidth--; + bar.increment(); + bar.print(); } + std::cout << std::endl; export_image(outputImage.c_str(), vect_source.data(), outWidth, height, nbChannels); }