# LibIMG _A lightweight, fast, and minimal library designed to be powerful for my current capabilities. This is a hobby project to learn bit operations and expanded to a full processor between two types --- PPM and JPEG. It's powerful for what it is and it is weak for what it could be._ > [Note] > All documentation is in the code and files itself. So to save myself time I would recommend going through the code itself. > [Warning] > There are a lot of changes you can make to an image but this is not an extensive library to use mainstream. I would hope you understood that already. This is for a self made project learning bitwise for c originally and now has become bigger and cooler than expected. ## Prerequisites 1. This library does require _```libturbojpeg```_ as manually writing the functions for JPEG would take a long time to figure out and I may come back to do later. 2. ```C23 and CMake 4.4.3```, as there are some new features from it. Tested only on my M1 Macbook for compatibility. ## Types Available 1. PPM (Originally just to learn with) 2. JPEG (Added as having only PPM felt wrong) Planned 3. PNG (Planned) 4. SVG (We Shall See) ## Installation You can build manually or pull it into a project _To Build_: ```bash git clone https://git.moomancer.xyz/DarthMooMancer/libimg.git cd libimg cmake -S . -B build && cmake --build build ./build/libimg ``` _To pull, use FetchContent in your ```CMakeLists.txt```:_ ```Make include(FetchContent) FetchContent_Declare(imgproc GIT_REPOSITORY https://git.moomancer.xyz/DarthMooMancer/libimg.git GIT_TAG main GIT_SHALLOW TRUE ) FetchContent_MakeAvailable(imgproc) target_link_libraries( PRIVATE imgproc) ``` ## Example _While it is not an extensive example, it shows many of the patterns for how to use all functions throughout the codebase._ ```c /* * Keep in mind any function that creates a new buffer and returns it can * overwrite the old one, however it is lost. SO create a new variable and free * the old one after use. * * Functions (Specifically filters) that return unsigned int (not pointers) need * to be used as an input to the same point in a buffer. * * For example: * * buf[i] = u32_grayscale(buf[i]); * * The buf[i] is replaced by the output of grayscale at buf[i] */ int main() { // Init base image containers PPM img; JPEG jimg; // Add a file location of image to modify img.name = "../assets/test_2.ppm"; // Load the PPM image unsigned int* buf = ppm_load(img.name, &img); // Check for null image load. In case image doesn't exist or fails to // load if (!buf) { LOGERROR(ERR_BUF_NULL); return ERR_BUF_NULL; } // Blur image and save to new pointer unsigned int* blur = box_blur(buf, &img, 20); // Free old buffer. MUST DO THIS. Maybe not immediately but before // ending or possibly leaking. Also it stays in heap and a large image // can take a lot of memory so better to clear anyways. free(buf); // Check for null image load. In case image doesn't exist or fails to // load if (!blur) { LOGERROR(ERR_BUF_NULL); return ERR_BUF_NULL; } // Loop image and apply filter to each pixel. for (int i = 0; i < img.len; i++) { blur[i] = u32_rotl(blur[i], 4); } // Take the attributes from ppm image so JPEG file can be saved jimg = inherit_from_ppm(&img); // Saves JPEG to location specified jpeg_save(blur, &jimg, "../assets/test_2_new.jpg"); // Make sure to free any buffer still active free(blur); return 0; } ```