LAB7_PIXELMANCY: The Final Quest¶
Due date: 2026-04-27 23:59.
Pixelmancy¶
Pixelmancy is a C++ project that can generate GIF files, as shown below. It's designed as a practice exercise for C++ students and should not be treated as a template for optimal project structure. The project intentionally contains bugs for you to fix, starting with the Color Problem. If you are already familiar with CMake, you may begin with that task instead.
Download The Provided Files¶
You can get the files from here: Pixelmancy_v1.0.1.zip
Few problems are fixed in v1.0.1.
- Library conflict with local installed libraries. eg: libfmt
- Not being able to diff file paths with spaces
- Library conflict with local installed libraries. eg: libfmt
- Not being able to diff file paths with spaces
Old version: Pixelmancy.zip
Project structure¶
This project comprises a standalone application and a test suite. The root CMakeLists.txt builds the
Pixelmancy library and links it to the 'standalone' project. The standalone project generates an executable, PixelmancyExample, which executes the evaluation code for this assignment.Dependencies¶
- cmake
- g++
Libraries used¶
All libraries reside in libs folder and you don't have to install anything.
- LodePNG - PNG image decoder and encoder
- cgif - GIF encoder written in C
- cxxopts - Lightweight C++ command line option parser
- {fmt} - A modern formatting library
How to build and run¶
Recommended steps¶
- First time use these commands
make config_debug
make build
./build/standalone/PixelmancyExample -h
- After a code change
make build
./build/standalone/PixelmancyExample -h
- For cleaning
make clean
- From scratch again
make forced_clean
make config_debug
make build
./build/standalone/PixelmancyExample -h
Using Makefile¶
To build, first use CMake to configure and generate the build system. The top-level Makefile provides various configuration options.
- use
make config_debugto configure a debug build. You need use this for debugging and running valgrind. - use
make config_releaseto configure the relase type build we run in the lovelace server. - use
make config_asanto configure the address sanitizer build. - use
make config_teststo enable tests project.
Once the build system is configured, use the following command to build the executables.
- use
make build
Note! : If you navigate into the build folder at this point or after configuring, you'll find another Makefile (build/Makefile) generated by CMake specifically for the project.
This Makefile within the build directory provides more granular build targets.
For example:
For example:
make PixelmancyExample -j 4make PixelmancyTests -j 4make clean
Executable targets¶
Depending on your configuration, one or two executables will be created.
- use
./build/standalone/PixelmancyExampleto run the program - eg:
./build/standalone/PixelmancyExample -h
- use
./build/tests/PixelmancyTeststo run the test program - eg:
./build/tests/PixelmancyTests [color] - eg:
./build/tests/PixelmancyTests "test color distance" - eg:
./build/tests/PixelmancyTests -h
cmake - Build system generator¶
CMake is essential for building this project. Please ensure it is installed on your system. We utilize CMake to generate the project's build system, which defaults to a Makefile on Linux. This section provides informational details about CMake; you don't need to read it to complete the basic build process.
- For a comprehensive CMake tutorial, please refer to: cmake.org/cmake/help/v3.30/guide/tutorial
Simple usage¶
- Create a build directory: Within the project's root directory, create a build directory (e.g., mybuild).
- Navigate to the build directory: Change your current directory to the newly created mybuild folder.
- Configure the build system: Execute the command cmake ... This command instructs CMake to use the CMakeLists.txt file located in the parent directory to generate the build system (typically a Makefile on Linux).
- Build the project: While still inside the mybuild folder, run the command make. This will compile the project.
The resulting executable, PixelmancyExample, will be located in ./standalone/ within the mybuild directory. It is built from the source file standalone/main.cpp.
mkdir mybuild cd mybuild cmake .. -DPIXELMANCY_BUILD_TESTS=OFF make -j 4 ./standalone/PixelmancyExample -h
You can delete the mybuild directory and repeat the process, optionally choosing a different name for the build directory. After making code changes, simply run make again from within the build folder to recompile. Re-running cmake .. is generally not necessary unless you have made significant modifications to the CMakeLists.txt files. In such cases, a clean build (deleting the mybuild directory and starting over) might be required.
You can also generate a Ninja build system in a similar manner:
mkdir mybuild cd mybuild cmake -G ninja .. ninja ./standalone/PixelmancyExample -h
Some cmake magic¶
Examine the include directives in standalone/main.cpp. You'll notice the inclusion of "config.hpp". Locate this file within the build directory (mybuild in our example) where you executed cmake ... You can use the find command mentioned below if needed. Inspect the contents of config.hpp. This file is automatically generated during the CMake configuration step.
Now, open the template file standalone/config.hpp.in located in the source directory and add a line, for example: #define MY_DEBUG 1. After saving the changes to config.hpp.in, go back to your mybuild directory and run make. Did you need to run
cmake .. again for this change to take effect? Verify if your newly added line (#define MY_DEBUG 1) now appears in the generated config.hpp file.find . -name config.hpp
Color Problem¶
Color is a straightforward structure containing four 8-bit unsigned integer members: red, green, blue, and alpha. These members represent the RGBA color components for our Pixelmancy project, with each value ranging from 0 to 255.
The color functionality is specifically tested within the colorProblem function located in the standalone/main.cpp file.
To verify its correct operation, execute the PixelmancyExample executable with the -c flag:
To verify its correct operation, execute the PixelmancyExample executable with the -c flag:
Your task is to ensure that running this command produces no error messages related to color handling and that the colorProblem function confirms the successful addition of thirteen unique colors to a map, resulting in a map size of thirteen.
Distance problem¶
The ColorSpaceDistance class is designed to calculate the Euclidean distance of an RGB color from the origin within the 3D color space.
Running the PixelmancyExample executable with the -d flag will currently reveal some errors related to this calculation.
Your goal is to modify the ColorSpaceDistance class so that the distanceProblem function in standalone/main.cpp no longer outputs any error messages to the terminal. Please ensure that all previously identified issues have also been resolved before tackling this problem.
Image problem¶
The Image class utilizes a ColorPalette to manage its colors. Instead of storing the full RGBA color for each pixel, the image data stores an index value. This index corresponds to a specific color entry within the ColorPalette. Therefore, to determine the actual color of a pixel, you look up the color at the pixel's stored index within the image's palette.
You can test the functionality related to the Image class and its ColorPalette by running the PixelmancyExample executable with the -i flag:
Two errors reported in the "image problem" log relate to how img and img2 are being handled when added to the images std::array. The code attempts to copy img and move img2. The errors indicate that img2 still appears to hold data after the move operation (even though a cleanup is intended to mark it as moved).
HINT: If you are stuck check the operator used for comparison.
HINT: Consider if a compiler-generated copy assignment operator would be suitable.
HINT: Consider if a compiler-generated copy assignment operator would be suitable.
Three PNG boxes problem¶
In this exercise, you will create three PNG images, which should consist of three boxes. To begin, run the PixelmancyExample executable with the -p flag:
Check why the images are not matching with reference images.
First GIF¶
In this exercise, you will create the first GIF animation using this project, which should consist of three frames. To begin, run the PixelmancyExample executable with the -t flag:
Start by addressing the segmentation fault that occurs when running the GIF generation. Once this crash is resolved, examine the threeBoxes function. Ensure the generated GIF output matches the reference GIF.
The generated GIF will be saved as data/output/three_boxes.gif, and the reference GIF for comparison is located at data/three_boxes.gif.
The generated GIF will be saved as data/output/three_boxes.gif, and the reference GIF for comparison is located at data/three_boxes.gif.
Hint: Ensure that you have successfully fixed the Color Problem exercise before attempting this one, as it might be a prerequisite.
Image Resize Problem¶
The GIF format we are working with has a limitation of supporting only 256 colors, defined by its color palette. One technique we employ to potentially reduce the number of distinct colors in an image is image resizing. For this resizing operation, we are using the nearest neighbor algorithm.
To begin, run the PixelmancyExample executable with the -r flag:
Your task is to correct the existing Image Image::resize(double percentage) const function. The goal is to ensure that when this function is used for downscaling, the program's output images closely match the expected reference images.
We will also explore another method of image manipulation, which involves directly modifying the image's color palette.
Ultimately, we aim to transform the image data/tree.png (which has dimensions of 400x400 pixels) into the following target image with dimensions of 200x200 pixels."
Draw on image¶
Create any creative GIF you want. To begin, run the PixelmancyExample executable with the -g flag:
As far as your GIF does not match the given GIF you will get full marks for this.
As far as your GIF does not match the given GIF you will get full marks for this.
Good luck!¶
Author¶
Rukshan Perrera
Anna palautetta
Kommentteja tehtävästä?