Skip to main content

Overview

Provides JPEG encoding/decoding capabilities and utilities for image format conversion, masking, and border manipulation. Built on top of TurboJPEG for high-performance compression.

Types

Image

Represents an 8-bit unsigned char image.
typedef struct {
    unsigned char *data;
    int width;
    int height;
    int channels;
} Image;
data
unsigned char*
Pixel data buffer (row-major order)
width
int
Image width in pixels
height
int
Image height in pixels
channels
int
Number of color channels (1 for grayscale, 3 for RGB)

ImageF

Represents a floating-point image.
typedef struct {
    float *data;
    int width;
    int height;
    int channels;
} ImageF;
data
float*
Floating-point pixel data buffer
width
int
Image width in pixels
height
int
Image height in pixels
channels
int
Number of color channels

ImageS

Represents a short integer image.
typedef struct {
    short *data;
    int width;
    int height;
    int channels;
} ImageS;
data
short*
Short integer pixel data buffer
width
int
Image width in pixels
height
int
Image height in pixels
channels
int
Number of color channels

BorderType

Enumeration for border handling modes.
typedef enum {
    BORDER_CONSTANT,
    BORDER_REFLECT
} BorderType;
BORDER_CONSTANT
enum
Fill border with constant value (typically 0)
BORDER_REFLECT
enum
Reflect image pixels at boundaries

Constants

#define RGB_CHANNELS 3
#define GRAY_CHANNELS 1

Functions

decompress_jpeg

Decompresses a JPEG file into an Image structure.
Image decompress_jpeg(const char *filename);
filename
const char*
required
Path to JPEG file to decompress
return
Image
Decompressed image with allocated data buffer
Returns an RGB image (3 channels) regardless of source format. Check img.data != NULL to verify successful loading.

Example

Image img = decompress_jpeg("photo.jpg");
if (img.data != NULL) {
    printf("Loaded %dx%d JPEG\n", img.width, img.height);
    // Process image...
    destroy_image(&img);
} else {
    fprintf(stderr, "Failed to load JPEG\n");
}

compress_jpeg

Compresses an RGB image to JPEG format.
int compress_jpeg(const char *outputFilename, const Image *img, int quality);
outputFilename
const char*
required
Output JPEG file path
img
const Image*
required
Pointer to RGB image to compress (must have 3 channels)
quality
int
required
JPEG quality (1-100, where 100 is best quality)
return
int
1 on success, 0 on failure
The image must have exactly 3 channels (RGB). For grayscale images, use compress_grayscale_jpeg instead.

Example

Image img = create_image("input.jpg");
if (compress_jpeg("output.jpg", &img, 95)) {
    printf("Saved with quality 95\n");
}

compress_grayscale_jpeg

Compresses a grayscale image to JPEG format.
int compress_grayscale_jpeg(const char *outputFilename, const Image *img, int quality);
outputFilename
const char*
required
Output JPEG file path
img
const Image*
required
Pointer to grayscale image (must have 1 channel)
quality
int
required
JPEG quality (1-100)
return
int
1 on success, 0 on failure

Example

Image gray = convert_RGB_to_gray(&img);
compress_grayscale_jpeg("gray.jpg", &gray, 90);
destroy_image(&gray);

convert_RGB_to_gray

Converts an RGB image to grayscale.
Image convert_RGB_to_gray(const Image *img);
img
const Image*
required
Pointer to source RGB image (3 channels)
return
Image
Newly allocated grayscale image (1 channel)
Uses standard luminance conversion: Y = 0.299R + 0.587G + 0.114B

Example

Image rgb = decompress_jpeg("color.jpg");
Image gray = convert_RGB_to_gray(&rgb);
printf("Converted to %d channel(s)\n", gray.channels); // prints 1

create_mask

Creates a horizontal gradient mask for image blending.
Image create_mask(int width, int height, float range, int left, int right);
width
int
required
Mask width in pixels
height
int
required
Mask height in pixels
range
float
required
Gradient transition range as fraction of width (0.0-1.0)
left
int
required
Value for left edge (0 or 1, scaled to 0 or 255)
right
int
required
Value for right edge (0 or 1, scaled to 0 or 255)
return
Image
Grayscale mask image with smooth horizontal gradient
The range parameter controls the transition zone width. For example, 0.1 creates a gradient over 10% of the image width.

Example

// White on left fading to black on right over 20% of width
Image mask = create_mask(1024, 768, 0.2f, 1, 0);

create_vertical_mask

Creates a vertical gradient mask for image blending.
Image create_vertical_mask(int width, int height, float range, int top, int bottom);
width
int
required
Mask width in pixels
height
int
required
Mask height in pixels
range
float
required
Gradient transition range as fraction of height (0.0-1.0)
top
int
required
Value for top edge (0 or 1)
bottom
int
required
Value for bottom edge (0 or 1)
return
Image
Grayscale mask image with smooth vertical gradient

Example

// Black on top fading to white on bottom
Image vmask = create_vertical_mask(1024, 768, 0.15f, 0, 1);

add_border_to_image

Adds border padding to an image.
void add_border_to_image(Image *img,
                         int borderTop, int borderBottom, 
                         int borderLeft, int borderRight,
                         int channels, BorderType borderType);
img
Image*
required
Pointer to image (modified in-place)
borderTop
int
required
Pixels to add on top
borderBottom
int
required
Pixels to add on bottom
borderLeft
int
required
Pixels to add on left
borderRight
int
required
Pixels to add on right
channels
int
required
Number of channels in the image
borderType
BorderType
required
Border fill method (BORDER_CONSTANT or BORDER_REFLECT)
Modifies the image structure in-place by reallocating the data buffer with expanded dimensions.

Example

Image img = decompress_jpeg("photo.jpg");
// Add 10-pixel reflective border on all sides
add_border_to_image(&img, 10, 10, 10, 10, img.channels, BORDER_REFLECT);
printf("New size: %dx%d\n", img.width, img.height);

convert_image_to_image_f

Converts unsigned char image to floating-point format.
void convert_image_to_image_f(Image* in, ImageF *out);
in
Image*
required
Source image (unsigned char)
out
ImageF*
required
Destination image (must be pre-allocated with same dimensions)
The out image must already be allocated with matching dimensions. Values are converted from [0, 255] to [0.0, 255.0].

Example

Image img = decompress_jpeg("photo.jpg");
ImageF imgf = create_empty_image_f(img.width, img.height, img.channels);
convert_image_to_image_f(&img, &imgf);

convert_image_to_image_s

Converts unsigned char image to short integer format.
void convert_image_to_image_s(Image* in, ImageS *out);
in
Image*
required
Source image (unsigned char)
out
ImageS*
required
Destination image (must be pre-allocated)

convert_imagef_to_image

Converts floating-point image to unsigned char format.
void convert_imagef_to_image(ImageF* in, Image *out);
in
ImageF*
required
Source float image
out
Image*
required
Destination image (must be pre-allocated)
Values are clamped to [0, 255] range during conversion.

convert_images_to_image

Converts short integer image to unsigned char format.
void convert_images_to_image(ImageS* in, Image *out);
in
ImageS*
required
Source short image
out
Image*
required
Destination image (must be pre-allocated)

crop_image_buf

Crops an image buffer by removing borders.
void crop_image_buf(Image *img, int cut_top, int cut_bottom, 
                    int cut_left, int cut_right, int channels);
img
Image*
required
Pointer to image to crop (modified in-place)
cut_top
int
required
Pixels to remove from top
cut_bottom
int
required
Pixels to remove from bottom
cut_left
int
required
Pixels to remove from left
cut_right
int
required
Pixels to remove from right
channels
int
required
Number of channels

Complete Usage Example

#include "jpeg.h"
#include "image_operations.h"

void process_jpeg() {
    // Load JPEG
    Image img = decompress_jpeg("input.jpg");
    if (img.data == NULL) {
        fprintf(stderr, "Failed to load image\n");
        return;
    }
    
    // Convert to grayscale
    Image gray = convert_RGB_to_gray(&img);
    
    // Add reflective border
    add_border_to_image(&gray, 20, 20, 20, 20, 
                        gray.channels, BORDER_REFLECT);
    
    // Convert to float for processing
    ImageF grayf = create_empty_image_f(gray.width, gray.height, 
                                        gray.channels);
    convert_image_to_image_f(&gray, &grayf);
    
    // Process float image...
    // ...
    
    // Convert back to unsigned char
    Image result = create_empty_image(grayf.width, grayf.height, 
                                      grayf.channels);
    convert_imagef_to_image(&grayf, &result);
    
    // Save result
    compress_grayscale_jpeg("output.jpg", &result, 95);
    
    // Cleanup
    destroy_image(&img);
    destroy_image(&gray);
    destroy_image_f(&grayf);
    destroy_image(&result);
}

Build docs developers (and LLMs) love