23 comments

[ 2.7 ms ] story [ 43.0 ms ] thread
Yep, that sure is a primitive image format.
Yes, but very useful since its easy to parse and trivial to generate. You can always pipe input/output through conversion utilities to your format of choice (pgm, jpg, ...).
You know what’s even more trivial to parse and generate? Arrays of uncompressed binary data.
It basically gives you that. The P6 version (".ppm") is a tiny text header followed by uncompressed RGB pixels in binary format. It's about as simple as you can get for an image. Here, for example is a program to generate a red/green gradient:

    #include <stdio.h>
    int main( int argc, char **argv ) {
        printf( "P6 %d %d 255\n", 128, 128 );
        for ( int y = 0; y < 128; ++y )
            for ( int x = 0; x < 128; ++x )
                printf( "%c%c%c", x * 2, y * 2, 0 );
        return 0;
    }
Boom. Done. I use this format all the time because it's so simple that I can write programs to generate it off the top of my head. No external image libraries to link, or even a need to consult the spec at this point. A few quick lines and I've got my image. If I really need something like a PNG or JPEG, I can just pipe it through ImageMagick:

    ./gradient | convert - gradient.png
It's not a format I'd store my images in long term, but for quick-and-dirty image creation it's hard to beat.
No. Unstructured binary data in arbitrary formats if fundamentally impossible to parse successfully. Oh, your parser works you say? It won't next project after the format change again.

The pbm stuff is an attempt to specify the simplest possible format that can be used robustly in practice.

It seemed like the parent posters in this thread were talking about the plain text version of the format, which is IMO ridiculous for any non-toy use. My response was half-sarcastic; tone doesn’t make it through the internet though I guess.

The binary version is fine, though in general I’d recommend just using PNG, TIF, JPEG, or whatever.

Most early image formats were primitive and I'm glad they were.

The first image reader and writer I wrote was for the .tga format[1]. This was before the Internet and I had no documentation. The only thing to do back then was to look at several different .tga files in a Hex-Editor and try to make sense of what you saw.

If things would have been more complicated I might just have given up - maybe on computers entirely. There was just this "How difficult could it be?" attitude back then I miss a lot today.

[1] https://en.wikipedia.org/wiki/Truevision_TGA

I remember running across the NetPBM format when I was looking at some of the images that are stored in jwz's folder on the CMU AI repository. There's something very nice about storing a bitmap in pure text. (AWK image processing comes to mind.)

http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/l...

wow, nice find. I've never come across any of jwz's actual academic/LISP work in the wild. very cool.
Of course you could use awk or anything else, but for most tasks there are already transforms in the netpbm tools that work well. In addition to being in text format, the meta info always comes first, which facilitates streaming. That in turn means that if you pipe together four transforms you'll use four cores without even trying.
Why are they called Netpbm format when they were invented by Poskanzer years before the NetPBM project was founded?
Stuff usually gets "net" slapped on the front after some attempt has been made to specify or regularize it, that way the documented/maintained version doesn't share the name with any classic implementation, which helps to avoid all kinds of ambiguity.

Not sure where this idiom came from, but seen it used a bunch of times

Nethack? NetBSD? Netatalk?
netatalk is likely just a dir name, like netinet or netns.
"In 1993, Netpbm was developed to replace Pbmplus. Netpbm was nothing more than a new release of Pbmplus, and named for the fact that people all over the world would maintain the package by submitting fixes and enhancements over the Net. This was a time when such worldwide collaboration was still novel."

http://netpbm.sourceforge.net/history.html

I've been using the PFM format (http://netpbm.sourceforge.net/doc/pfm.html) for a project recently.

It's the most obscure member of the Netpbm family. Almost no image viewer understands it, and no image editor can read or write it. Luckily there's the incredible CImg (http://www.cimg.eu/) lib.

PFM is stored in left to right, bottom to top order pixel. It has exactly one or three channels. One pixel is four bytes. There's an obscure "scale/endianness" parameter to tell you the byte order.

I love it, and I hate it.

Which makes it impossible for me not to ask...

Why are you using it for the project? Is it for interoperability with some other component? If so, what sort of thing is using such a format, I'm intrigued.

Good question :)

I needed a quick way to hack the output of 2D float data (pixel annotations to complement some image) into some legacy C without adding dependencies.

Thanks to CImg, I can read and display the PFM files in 10 lines of my own C++. I thought about just writing a width/height-annotated binary blob instead, but then realized that's really what PFM already is.

I have no idea if anything is really using PFM. I certainly have not found any "big" compatible programs.

I recently played around with this and came up with my own variant:

http://cygx.github.io/js-rgba/

Only tested in Firefox, no idea if it works in other browsers...

Works fine in Chrome 46.0 from what I can see.

My image downloader extension even recognizes the results as images and puts save buttons on them. :D

What would be really cool would be to open the source text into a <textarea> so people could play with it, with an "auto-update" checkbox and everything. :D

Also, atm to switch from the rendered result back to the source image, I have to reload the page. Maybe the button could toggle, or the result and source could be on the page simultaneously.