rusty-ppm
A crate to provide writing and reading functionality for .ppm images.
The library provides:
- The
canvasmodule: Contains theCanvasstruct which holds the pixel data of the image you are working on, as well as the functions necessary to access and mutate its data. - The
ppm_writermodule: Contains functions to write your canvas into a.ppmimage. - The
ppm_readermodule: Contains functions to read.ppmimages and convert it into aCanvas. - The
utilsmodule: Contains functions to create sample.ppmimages as well as helper functions.
Inner workings
The Canvas struct is implemented as a single array as opposed to a 2D array. After running some tests, this method did allow for a small performance improvement. The ppm_writer module provides the writing functions, which takes a Canvas and writes it to a binary or plain text .ppm file. The ppm_reader module provides the reading functions, which can take either a plain text .ppm image, or a binary .ppm image and convert it into a Canvas to be used by the user.
The pixel data inside the Canvas is made up of Vector3<u8>, using the cgmath crate Vector3 struct. In order to interact with the image, you will most likely need to import the cgmath crate.
The Canvas can give access to individual pixels through the get and get_mut functions, using rows and columns as indexes. The iter and iter_mut functions will give an iterator over the whole image, starting from the top left corner, and scanning from left to right, up to down.
Example Benchmarks
Machine specs:
OS: Pop!_OS 22.04 LTS x86_64
Host: 20QNS00Q00 ThinkPad P53
CPU: Intel i5-9400H (8) @ 4.300GHz
GPU1: Intel CoffeLake-H GT2 [UHD Graphics 630]
GPU2: NVIDIA Quadro T1000 Mobile
Testing methodology: Each function was timed and ran for a total of 10 times each. Results were averaged.
Writing/Reading a 4k(3840 × 2160) image (8,294,400 Pixels):
- Average
read_ppmspeed (plain text.ppmimage): 277.071ms - Average
read_ppmspeed (binary.ppmimage): 35.603ms - Average
write_ppmspeed: 48.378ms
Writing/Reading a 10,000 x 10,000 image (100,000,000 Pixels):
- Average
read_ppmspeed (plain text.ppmimage): 3.928s - Average
read_ppmspeed (binary.ppmimage): 570.408ms - Average
write_ppmspeed: 655.232ms
Motivation
First encountered the .ppm format while reading "Raytracing in one weekend" ebook and created this crate to help me deal with it. But otherwise, I still think there's something nice about the simplicity of the format.
It also turns out that this is my first crate and I thought it would be a great way to initiate myself to publishing process.
Notes
I haven't tested the performance of using Vector3<u8> as opposed to other integer type, but from my understanding, it is possible that certain CPU architecture might perform better with different types of intger, such as u32.