Files
libimg/README.md
T
2026-09-10 02:43:22 -04:00

3.3 KiB

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

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.

Types

Available

  1. PPM (Originally just to learn with)
  2. JPEG (Added as having only PPM felt wrong)

Planned

  1. PNG (Planned)
  2. SVG (We Shall See)

Installation

You can build manually or pull it into a project

To Build:

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:

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(libgl PRIVATE imgproc)

Example

White it is not an extensive example, it shows many of the many logic of how to use all functions throughout the codebase.

/*
 * 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 doesnt 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 doesnt 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;
}