Home / Alt manpages / pamfunc(1)

  • pamfunc(1)
  • User command
  • linux

Adjust Netpbm Image Values Safely with pamfunc

pamfunc applies a repeatable brightness change, clamps samples to a range, or edits bit fields in a Netpbm image, one function per run. The examples use Netpbm 11.5.2, installed from Debian's netpbm package. Allow about 10 minutes if you already have a PGM, PPM or PAM file to test against.

Before you start

You need a shell, the pamfunc command, and a Netpbm image. Check the installed version and command path first:

command -v pamfunc
pamfunc -version 2>&1 | sed -n '1,2p'

On the system used for this guide, the second command reports Netpbm Version 11.5.2. The manpage itself is dated 9 September 2020, while the installed binary identifies itself separately, so if your package is older, check its local manpage before relying on newer options such as -changemaxval.

Checkpoint

You have a readable input image and know where the result will land. pamfunc writes the transformed image to standard output, so redirect it to a new file while testing, and never redirect over your only copy.

1. Apply one arithmetic function

Choose exactly one transfer function. For ordinary image adjustments, the useful starting points are -multiplier, -divisor, -adder, -subtractor, -min and -max. This example doubles the normalised sample values and saves a new PGM:

pamfunc -multiplier=2 input.pgm > brighter.pgm
  • The multiplier must be non-negative. Results above the normalised maximum of 1 are clipped, so a value already at full brightness just stays there.
  • To darken by half, use the equivalent divisor instead of a fractional multiplier.
pamfunc -divisor=2 input.pgm > darker.pgm

For a fixed shift, the integer is measured in samples relative to the input's maxval. With an input maxval of 100, -adder=10 adds 0.1 to each normalised sample, clipped at both zero and one.

pamfunc -adder=10 input.pgm > lifted.pgm
pamfunc -subtractor=10 input.pgm > lowered.pgm

Checkpoint

Inspect the result rather than trusting the filename. Netpbm's pnmtoplainpnm converts a PGM or PPM result to readable text:

pnmtoplainpnm brighter.pgm | sed -n '1,8p'

Example

For a two-by-two PGM with maxval 100 and samples 0 25 50 100, doubling produces samples 0 50 100 100. The image type and dimensions stay PGM and two by two. A malformed or unsupported input normally causes an error, so keep the shell's exit status when checking a pipeline:

set -o pipefail
if pamfunc -multiplier=2 input.pgm > brighter.pgm; then
    pnmtoplainpnm brighter.pgm | sed -n '1,8p'
else
    printf '%s\n' 'pamfunc did not produce a trusted result' >&2
fi

2. Clamp without changing contrast

Use -min to raise a floor or -max to impose a ceiling. Their arguments are whole sample values, not percentages. This raises every sample below 20 to 20, and caps every sample above 240 at 240, when the input maxval is 255:

pamfunc -min=20 input.pgm > floor.pgm
pamfunc -max=240 input.pgm > ceiling.pgm

These operations do not stretch the remaining range, they only replace samples outside the boundary you set. The argument is compared against the input's maxval, so check that first before picking a number:

pnmtoplainpnm input.pgm | sed -n '1,6p'

3. Preserve precision when reducing values

By default pamfunc keeps the input maxval and rounds the transformed samples into that range. For a division by one or more, -changemaxval can instead change the output maxval and leave sample values scaled with greater precision:

pamfunc -divisor=2 -changemaxval input.pgm > precise-half.pgm
pnmtoplainpnm precise-half.pgm | sed -n '1,6p'

For an input maxval of 100, the verified example reports an output maxval of 200 while a sample such as 50 stays 50, so its normalised brightness is halved as intended. This option is not guaranteed to use the changed-maxval method for every operation, and Netpbm formats cap maxval at 65535 regardless. If another program downstream expects the original maxval, skip the option and accept the normal rounding instead.

4. Use bit masks only on bit-shaped data

The mask and shift functions treat each sample as a bit string. In this mode, maxval must be one less than a power of two, such as 15 or 255, and the mask must fit within that width. This keeps the low four bits of a 4-bit sample:

pamfunc -andmask=0f bits.pgm > low-nibble.pgm
pnmtoplainpnm low-nibble.pgm | sed -n '1,6p'

Example

For samples 0 5 10 15 with maxval 15, the result is the same sequence, since every sample already fits the mask. A wider mask, or a shift count greater than the bit width, is an error.

  • -ormask sets bits.
  • -xormask toggles them.
  • -not inverts them.
  • -shiftleft or -shiftright moves them.

Warning

Do not use these bit operations as a substitute for normal brightness adjustment, they work on the raw bit pattern, not the normalised sample.

Common traps and recovery

  • PBM black and white values can look backwards. pamfunc operates on the PAM equivalent, where black is 0 and white is 1, regardless of PBM's on-disk convention.
  • Do not mix arithmetic and bit-string assumptions. Arithmetic arguments use normalised samples; masks use the maxval as a bit width.
  • Do not overwrite the source until you have checked dimensions, format and sample values. If a result is wrong, just discard the new output and rerun the command from the unchanged source.
  • When feeding a pipeline, redirect to a temporary filename first and inspect it before renaming into place. No elevated privileges are required unless your chosen destination is not writable by your user.

Done means

  • You checked the command and package version.
  • You picked one verified function for the change you actually needed.
  • The result was written to a new file and inspected with pnmtoplainpnm.
  • You considered the input maxval, especially for -changemaxval and bit masks.
  • The original file is still there for recovery.