Skip to content
/ Netpbm Public

A study on the Netpbm image format. Turned into a single header file

Notifications You must be signed in to change notification settings

lcox74/Netpbm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Netpbm Study

I found a simple image format that I wanted to try and implement.

The examples and format is described on its wiki page. There are a couple of different modes refered to as Magic Number these being:

  • P1 Portable BitMap (Ascii) -> Black or White
  • P2 Portable GrayMap (Ascii) -> Greyscale
  • P3 Portable PixMap (Ascii) -> RGB
  • P4 Portable BitMap (Binary) -> Black or White
  • P5 Portable GrayMap (Binary) -> Greyscale
  • P6 Portable PixMap (Binary) -> RGB

P1, P2 and P3 wot be supported as they are ascii derivatives and use more storage than it otherwise would.

Each of these modes have their own file format:

  • Portable BitMap .pbm
  • Portable GrayMap .pgm
  • Portable PixMap .ppm

There is also an extension mode called Portable Arbitrary Map (.pam) which uses P7 as the magic number. This mode allows a more dynamic image types and can support all three previous modes as well as the addition of transparency by setting the TUPLTYPE value in the file.

More information on PAM here.

Using this

I've created a single header file netpbm.h which will allow easy implementation into projects. Due to the HSV support, compiling with this header will require -lm added to your compile settings as it uses fmap and fabs in the calculations.

The following lines of code is a full implementation of setting colours for a buffer before creating an Portable PixMap (out.ppm). This file can be opened in GIMP and Photoshop.

#include <stdio.h>
#include "netpbm.h"

int main() {
    size_t width = 800, height = 600;
    float hue, saturation, value;
    
    /* Initialise a image buffer called `pixels` with width and height */
    INIT_PPM_BUF(pixels, width, height);

    /* Loop through every pixel in image */
    for (u32 y = 0; y < height; ++y) {
        for (u32 x = 0; x < width; ++x) {

            /* Precalc HSV values */
            hue = (x / (float)width) * 360.0f;
            saturation = 1.0f;
            value = 1.0f - (y / (float)height);

            /* Set pixel colour */
            pixels[y * width + x] = HSV888(hue, saturation, value);
        
        }
    }

    /* Write pixel buffer to image file */
    return construct_ppm_image("out.ppm", pixels, width, height);
}

Below is the image output from the code above:

test image

The image used to show on markdown is the result of opening the image in GIMP and exporting it to .png so markdown can view it.

About

A study on the Netpbm image format. Turned into a single header file

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages