Fanbase

ppm/ppm

version 1.0

P3 (ASCII) and P6 (raw) PPMs with 8-bit and 16-bit samples, header comments and whitespace

Format
Portable Pixmap (ppm)
Authors
The Fandango Fuzzer Team
License
Apache-2.0
Fandango
>=1.3
Extensions
ppm
Media type
image/x-portable-pixmap
Specification
http://netpbm.sourceforge.net/doc/ppm.html
Its files should decode
always
In the registry
specs/ppm/ppm/ppm.fan

Use it

fanbase install ppm
fandango fuzz -F ppm -n 10

How it does

accepts 100%, covers 23.1%, 46/s. 1000 inputs, seed 1.

ParserAcceptsVersion
ffmpeg100%ffmpeg version 7.1.5-0+deb13u1
ffmpeg-pnm-cov100%FFmpeg (PNM family, for PPM) 9.0.2
imagemagick100%Version: ImageMagick 7.1.1-43 Q16 x86_64 22550
pillow100%12.3.0

The spec says its files decode always: as expected.

ffmpeg-pnm-cov

lines reached
23.1% of 516
real files reach
34.1%
only the generated files
1 lines
only the real files
58 lines
17.2% after 1 inputs, 23.1% after 1000real files: 34.1%

Cite it

@software{fanbase_ppm_ppm_1_0,
  author  = {{The Fandango Fuzzer Team}},
  title   = {Portable Pixmap (ppm/ppm), a Fandango input specification},
  version = {1.0},
  url     = {https://github.com/fandango-fuzzer/fanbase},
  note    = {Fanbase registry, specs/ppm/ppm/ppm.fan, sha256 3a07301be3e7},
}

Source

Source (34 lines)
# PPM (Netpbm): P3 (plain ASCII) and P6 (raw binary) rasters, 8-bit and
# 16-bit big-endian samples, header comments, and the whitespace rule that
# a comment counts as whitespace anywhere one is legal.

<start> ::= <p6_8> | <p6_16> | <p3>

# P6, raw 8-bit: 3 bytes per pixel
<p6_8> ::= "P6" <ws> <comments> <width> <ws> <height> <ws> "255" <onews> <raster8>
where len(<raster8>) == int(str(<width>)) * int(str(<height>)) * 3

# P6, raw 16-bit: 6 bytes per pixel (2 BE bytes per sample)
<p6_16> ::= "P6" <ws> <comments> <width> <ws> <height> <ws> "65535" <onews> <raster16>
where len(<raster16>) == int(str(<width>)) * int(str(<height>)) * 6

# P3, plain ASCII: 3 decimal samples per pixel
<p3> ::= "P3" <ws> <comments> <width> <ws> <height> <ws> "255" <ws> <p3data>
where len(<p3data>) == int(str(<width>)) * int(str(<height>)) * 3

# shared header tokens
<width>  ::= r'[1-8]'
<height> ::= r'[1-8]'
<ws>     ::= r'[ \t\r\n]+'
<onews>  ::= "\n"
<comments> ::= <comment>*
<comment>  ::= r'#[^\n\r]*' "\n"

# raster bodies
<raster8>  ::= <byte>*
<raster16> ::= <byte>*
<byte> ::= rb'[\x00-\xff]'

<p3data>   ::= <p3sample>*
<p3sample> ::= <p3num> " "
<p3num>    ::= r'0|[1-9][0-9]?|1[0-9][0-9]|2[0-4][0-9]|25[0-5]'