Provided by: netpbm_11.07.00-2_amd64 bug

NAME

       pamscale - scale a Netpbm image

SYNOPSIS

          pamscale
             [
                scale_factor
                |
                {-xyfit | -xyfill | -xysize}
                  cols rows
                |
                -reduce reduction_factor
                |
                [-xsize=cols | -width=cols | -xscale=factor]
                [-ysize=rows | -height=rows | -yscale=factor]
                |
                -pixels n
             ]
             [
                -nomix
                |
                -filter=functionName [-window=functionName]
             ]
             [-linear]
             [-reportonly]
             [-verbose]

             [pnmfile]

       Minimum unique abbreviation of option is acceptable.  You may use double hyphens instead of single hyphen
       to denote options.  You may use white space in place of the equals sign to separate an option  name  from
       its value.

DESCRIPTION

       This program is part of Netpbm(1).

       pamscale  scales a Netpbm image by a specified factor, or scales individually horizontally and vertically
       by specified factors.

       You can either enlarge (scale factor > 1) or reduce (scale factor < 1).

       pamscale works on multi-image streams, scaling each one independently.  But before Netpbm 10.49 (December
       2009), it scales only the first image and ignores the rest of the stream.

   The Scale Factors
       The  options  -width,  -height,  -xsize,  -ysize, -xscale, -yscale, -xyfit, -xyfill, -reduce, and -pixels
       control the amount of scaling.  For backward compatibility, there are also -xysize and  the  scale_factor
       argument, but you shouldn't use those.

       -width  and -height specify the width and height in pixels you want the resulting image to be.  See below
       for rules when you specify one and not the other.

       -xsize and -ysize are synonyms for -width and -height, respectively.

       -xscale and -yscale tell the factor by which you want the width and height of the image  to  change  from
       source  to result (e.g.  -xscale 2 means you want to double the width; -xscale .5 means you want to halve
       it).  See below for rules when you specify one and not the other.

       When you specify an absolute size or scale factor for both dimensions,  pamscale  scales  each  dimension
       independently without consideration of the aspect ratio.

       If  you  specify one dimension as a pixel size and don't specify the other dimension, pamscale scales the
       unspecified dimension to preserve the aspect ratio.

       If you specify one dimension as a scale factor and don't specify the other dimension, pamscale leaves the
       unspecified dimension unchanged from the input.

       If you specify the scale_factor parameter instead of dimension options, that is the scale factor for both
       dimensions.  It is equivalent to -xscale=scale_factor -yscale=scale_factor.

       Specifying the -reduce reduction_factor option is equivalent to specifying the  scale_factor   parameter,
       where scale_factor is the reciprocal of reduction_factor.

       -xyfit  specifies  a  bounding box.  pamscale scales the input image to the largest size that fits within
       the box, while preserving its aspect ratio.  -xysize is a synonym for this.  Before Netpbm 10.20 (January
       2004), -xyfit did not exist, but -xysize did.

       -xyfill  is  similar,  but pamscale scales the input image to the smallest size that completely fills the
       box, while preserving its aspect ratio.  This option has existed since Netpbm 10.20 (January 2004).

       -pixels specifies a maximum total number of output pixels.  pamscale scales the image down to that number
       of  pixels.   If  the  input  image  is already no more than that many pixels, pamscale just copies it as
       output; pamscale does not scale up with -pixels.

       If you enlarge by a factor of 3 or more, you should probably add a pnmsmooth step; otherwise, you can see
       the original pixels in the resulting image.

       -reportonly

       The  option  -reportonly causes pamscale not to scale the image, but instead to report to Standard Output
       what scaling the options and the input image dimensions indicate.  For example, if you specify
           -xyfill 100 100 -reportonly

       and the input image is 500 x 400, pamscale tells you that this means scaling by .25 to end up with a  125
       x 100 image.

       You  can  use  this  information  with  other  programs,  such  as pamscalefixed, that don't have as rich
       facilities as pamscale for choosing scale factors.

       The output is intended to be convenient for machine processing.  In the example above, it would be

           500 400 0.250000 0.250000 125 100

       The output is a single line of text per input image, with blank-separated tokens as follows.

       •      input width in pixels, decimal unsigned integer

       •      input height in pixels, decimal unsigned integer

       •      horizontal scale factor, floating point decimal, unsigned

       •      vertical scale factor, floating point decimal, unsigned

       •      output width in pixels, decimal unsigned integer

       •      output height in pixels, decimal unsigned integer

       -reportonly was new in Netpbm 10.86 (March 2019).

   Usage Notes
       A useful application of pamscale is to blur an image.  Scale it down (without  -nomix)  to  discard  some
       information, then scale it back up using pamstretch.

       Or scale it back up with pamscale and create a "pixelized" image, which is sort of a computer-age version
       of blurring.

   Transparency
       pamscale understands transparency and properly mixes pixels considering the pixels' transparency.

       Proper mixing does not mean just mixing the transparency value and the color component values separately.
       In  a  PAM  image,  a  pixel which is not opaque represents a color that contains light of the foreground
       color indicated explicitly in the PAM and light of a  background  color  to  be  named  later.   But  the
       numerical  scale  of  a color component sample in a PAM is as if the pixel is opaque.  So a pixel that is
       supposed to contain half-strength red light for the foreground plus some light from the background has  a
       red  color  sample  that  says  full red and a transparency sample that says 50% opaque.  In order to mix
       pixels, you have to first convert the color sample values to  numbers  that  represent  amount  of  light
       directly (i.e. multiply by the opaqueness) and after mixing, convert back (divide by the opaqueness).

   Input And Output Image Types
       pamscale produces output of the same type (and tuple type if the type is PAM) as the input, except if the
       input is PBM.  In that case, the output is PGM with  maxval  255.   The  purpose  of  this  is  to  allow
       meaningful  pixel  mixing.  Note that there is no equivalent exception when the input is PAM.  If the PAM
       input tuple type is BLACKANDWHITE, the PAM output tuple type  is  also  BLACKANDWHITE,  and  you  get  no
       meaningful pixel mixing.

       If  you  want  PBM  output  with  PBM  input,  use pamditherbw to convert pamscale's output to PBM.  Also
       consider pbmreduce.

       pamscale's function is essentially undefined for PAM input  images  that  are  not  of  tuple  type  RGB,
       GRAYSCALE, BLACKANDWHITE, or the _ALPHA variations of those.  (By standard Netpbm backward compatibility,
       this includes PBM, PGM, and PPM images).

       You might think  it  would  have  an  obvious  effect  on  other  tuple  types,  but  remember  that  the
       aforementioned  tuple  types  have  gamma-adjusted  sample  values,  and  pamscale  uses that fact in its
       calculations.  And it treats a transparency plane different from any other plane.

       pamscale does not simply reject unrecognized tuple types because  there's  a  possibility  that  just  by
       coincidence you can get useful function out of it with some other tuple type and the right combination of
       options (consider -linear in particular).

   Methods Of Scaling
       There are numerous ways to scale an image.  pamscale implements a bunch of them; you  select  among  them
       with invocation options.

       Pixel Mixing

       Pamscale's  default  method is pixel mixing.  To understand this, imagine the source image as composed of
       square tiles.  Each tile is a pixel and has uniform color.  The tiles are all the same size.  Now take  a
       transparent  sheet  the  size  of  the  target  image,  marked with a square grid of tiles the same size.
       Stretch or compress the source image to the size of the sheet and lay the sheet over the source.

       Each cell in the overlay grid stands for a pixel of the target image.  For example, if you are scaling  a
       100x200  image up by 1.5, the source image is 100 x 200 tiles, and the transparent sheet is marked off in
       150 x 300 cells.

       Each cell covers parts of multiple tiles.  To make the target image, just color in  each  cell  with  the
       color  which  is  the  average  of  the colors the cell covers -- weighted by the amount of that color it
       covers.  A cell in our example might cover 4/9 of a blue tile, 2/9 of a red tile, 2/9 of  a  green  tile,
       and 1/9 of a white tile.  So the target pixel would be somewhat unsaturated blue.

       When  you  are  scaling  up  or  down by an integer, the results are simple.  When scaling up, pixels get
       duplicated.  When scaling down, pixels get thrown away.  In either case, the colors in the  target  image
       are a subset of those in the source image.

       When  the  scale  factor  is weirder than that, the target image can have colors that didn't exist in the
       original.  For example, a red pixel next to a white pixel in the source might become a red pixel, a  pink
       pixel, and a white pixel in the target.

       This  method  tends  to  replicate  what the human eye does as it moves closer to or further away from an
       image.  It also tends to replicate what the human eye sees, when far enough away to make the pixelization
       disappear, if an image is not made of pixels and simply stretches or shrinks.

       Discrete Sampling

       Discrete  sampling is basically the same thing as pixel mixing except that, in the model described above,
       instead of averaging the colors of the tiles the cell covers, you pick the one color that covers the most
       area.

       The result you see is that when you enlarge an image, pixels get duplicated and when you reduce an image,
       some pixels get discarded.

       The advantage of this is that you end up with an image made from the same color palette as the  original.
       Sometimes that's important.

       The  disadvantage is that it distorts the picture.  If you scale up by 1.5 horizontally, for example, the
       even numbered input pixels are doubled in the output and the odd numbered ones are copied singly.  If you
       have  a  bunch of one pixel wide lines in the source, you may find that some of them stretch to 2 pixels,
       others remain 1 pixel when you enlarge.  When you reduce, you may find that some of the  lines  disappear
       completely.

       You select discrete sampling with pamscale's -nomix option.

       Actually,  -nomix  doesn't  do exactly what I described above.  It does the scaling in two passes - first
       horizontal, then vertical.  This can produce slightly different results.

       There is one common case in which one often finds it burdensome to have  pamscale  make  up  colors  that
       weren't there originally: Where one is working with an image format such as GIF that has a limited number
       of possible colors per image.  If you take a GIF with 256 colors, convert it to PPM, scale by  .625,  and
       convert  back  to  GIF,  you  will probably find that the reduced image has way more than 256 colors, and
       therefore cannot be converted to GIF.  One way to solve this problem is to do the reduction with discrete
       sampling  instead  of  pixel  mixing.   Probably  a  better way is to do the pixel mixing, but then color
       quantize the result with pnmquant before converting to GIF.

       When the scale factor is an integer (which means you're scaling up), discrete sampling and  pixel  mixing
       are  identical  --  output  pixels  are  always just N copies of the input pixels.  In this case, though,
       consider using pamstretch instead of pamscale to get the added pixels interpolated instead of just copied
       and thereby get a smoother enlargement.

       pamscale's  discrete  sampling  is  faster than pixel mixing, but pamenlarge is faster still.  pamenlarge
       works only on integer enlargements.

       discrete sampling (-nomix) was new in Netpbm 9.24 (January 2002).

       Resampling

       Resampling assumes that the source image is a discrete sampling of some original continuous image.   That
       is,  it  assumes  there is some non-pixelized original image and each pixel of the source image is simply
       the color of that image at a particular point.  Those points,  naturally,  are  the  intersections  of  a
       square grid.

       The idea of resampling is just to compute that original image, then sample it at a different frequency (a
       grid of a different scale).

       The problem, of course, is that sampling necessarily throws away the information you need to rebuild  the
       original image.  So we have to make a bunch of assumptions about the makeup of the original image.

       You  tell  pamscale  to  use  the  resampling method by specifying the -filter option.  The value of this
       option is the name of a function, from the set listed below.

       To explain resampling, we are going to talk about a simple one dimensional scaling --  scaling  a  single
       row  of grayscale pixels horizontally.  If you can understand that, you can easily understand how to do a
       whole image: Scale each of the rows of the image, then scale each of the resulting  columns.   And  scale
       each of the color component planes separately.

       As  a  first  step  in  resampling,  pamscale converts the source image, which is a set of discrete pixel
       values, into a continuous step function.  A step function is a function  whose  graph  is  a  staircase-y
       thing.

       Now,  we convolve the step function with a proper scaling of the filter function that you identified with
       -filter.  If you don't know what the  mathematical  concept  of  convolution  (convolving)  is,  you  are
       officially  lost.   You  cannot  understand  this  explanation.   The  result  of this convolution is the
       imaginary original continuous image we've been talking about.

       Finally, we make target pixels by picking values from that function.

       To understand what is going on, we use Fourier analysis:

       The idea is that the only difference between our step  function  and  the  original  continuous  function
       (remember  that we constructed the step function from the source image, which is itself a sampling of the
       original continuous function) is that the step function has a bunch of high frequency Fourier  components
       added.   If  we  could  chop  out all the higher frequency components of the step function, and know that
       they're all higher than any frequency in the original function, we'd have the original function back.

       The resampling method assumes that the original function was sampled at a high enough frequency to form a
       perfect  sampling.   A perfect sampling is one from which you can recover exactly the original continuous
       function.  The Nyquist theorem says that as long as your sample  rate  is  at  least  twice  the  highest
       frequency  in your original function, the sampling is perfect.  So we assume that the image is a sampling
       of something whose highest frequency is half the sample rate (pixel resolution) or less.  Given that, our
       filtering does in fact recover the original continuous image from the samples (pixels).

       To  chop  out all the components above a certain frequency, we just multiply the Fourier transform of the
       step function by a rectangle function.

       We could find the Fourier transform of the step function, multiply it by a rectangle function,  and  then
       Fourier transform the result back, but there's an easier way.  Mathematicians tell us that multiplying in
       the frequency domain is equivalent to convolving in the time domain.  That means multiplying the  Fourier
       transform  of  F  by  a rectangle function R is the same as convolving F with the Fourier transform of R.
       It's a lot better to take the Fourier transform of R, and build it into pamscale than  to  have  pamscale
       take the Fourier transform of the input image dynamically.

       That  leaves  only  one  question:  What is the Fourier transform of a rectangle function?  Answer: sinc.
       Recall from math that sinc is defined as sinc(x) = sin(PI*x)/PI*x.

       Hence, when you specify -filter=sinc, you are effectively passing the step function of the  source  image
       through a low pass frequency filter and recovering a good approximation of the original continuous image.

       Refiltering

       There's another twist: If you simply sample the reconstructed original continuous image at the new sample
       rate, and that new sample rate isn't at least twice the highest  frequency  in  the  original  continuous
       image,  you  won't get a perfect sampling.  In fact, you'll get something with ugly aliasing in it.  Note
       that this can't be a problem when you're scaling up (increasing the sample rate), because the  fact  that
       the  old  sample rate was above the Nyquist level means so is the new one.  But when scaling down, it's a
       problem.  Obviously, you have to give up image quality when scaling down, but aliasing is  not  the  best
       way  to  do  it.  It's better just to remove high frequency components from the original continuous image
       before sampling, and then get a perfect sampling of that.

       Therefore, pamscale filters out frequencies above half  the  new  sample  rate  before  picking  the  new
       samples.

       Approximations

       Unfortunately,  pamscale doesn't do the convolution precisely.  Instead of evaluating the filter function
       at every point, it samples it -- assumes that it doesn't change any more often  than  the  step  function
       does.   pamscale  could  actually  do the true integration fairly easily.  Since the filter functions are
       built into the program, the integrals of them could be too.  Maybe someday it will.

       There is one more complication with the Fourier analysis.  sinc has nonzero values on out to infinity and
       minus  infinity.   That  makes  it  hard  to compute a convolution with it.  So instead, there are filter
       functions that approximate sinc but are nonzero only within  a  manageable  range.   To  get  those,  you
       multiply  the  sinc  function  by  a window function, which you select with the -window option.  The same
       holds for other filter functions that go on forever like sinc.  By default, for a  filter  that  needs  a
       window  function,  the  window  function  is  the  Blackman  function.   Hanning, Hamming, and Kaiser are
       alternatives.

       Filter Functions Besides Sinc

       The math described above works only with sinc as the filter function.  pamscale offers many other  filter
       functions,  though.   Some of these approximate sinc and are faster to compute.  For most of them, I have
       no idea of the mathematical explanation for them, but people do find they give  pleasing  results.   They
       may  not be based on resampling at all, but just exploit the convolution that is coincidentally part of a
       resampling calculation.

       For some filter functions, you can tell just by looking at the convolution how they vary  the  resampling
       process from the perfect one based on sinc:

       The  impulse filter assumes that the original continuous image is in fact a step function -- the very one
       we computed as the first step in the resampling.  This  is  mathematically  equivalent  to  the  discrete
       sampling method.

       The  box  (rectangle)  filter  assumes the original image is a piecewise linear function.  Its graph just
       looks like straight lines connecting the pixel values.  This is mathematically equivalent  to  the  pixel
       mixing  method  (but mixing brightness, not light intensity, so like pamscale -linear) when scaling down,
       and interpolation (ala pamstretch) when scaling up.

       Gamma

       pamscale assumes the underlying continuous function is a function of  brightness  (as  opposed  to  light
       intensity),  and  therefore  does  all  this  math using the gamma-adjusted numbers found in a PNM or PAM
       image.  The -linear option is not available with resampling (it causes  pamscale  to  fail),  because  it
       wouldn't be useful enough to justify the implementation effort.

       Resampling (-filter) was new in Netpbm 10.20 (January 2004).

       The filter and window functions

       Here is a list of the function names you can specify for the -filter or -windowoption.  For most of them,
       you're on your own to figure out just what the function is and what kind of scaling it does.   These  are
       common  functions from mathematics.  Note that some of these make sense only as filter functions and some
       make sense only as window functions.

       point  The graph of this is a single point at X=0, Y=1.

       box    The graph of this is a rectangle sitting on the X axis and centered on the Y axis  with  height  1
              and base 1.

       triangle
              The  graph  of this is an isosceles triangle sitting on the X axis and centered on the Y axis with
              height 1 and base 2.

       quadratic

       cubic

       catrom

       mitchell

       gauss

       sinc

       bessel

       hanning

       hamming

       blackman

       kaiser

       normal

       hermite

       lanczos
              Not documented

   Linear vs Gamma-adjusted
       The pixel mixing scaling method described above  involves  intensities  of  pixels  (more  precisely,  it
       involves  individual  intensities of primary color components of pixels).  But the PNM and PNM-equivalent
       PAM image formats represent intensities with gamma-adjusted numbers that are not linearly proportional to
       intensity.   So  pamscale, by default, performs a calculation on each sample read from its input and each
       sample written to its output to convert between these  gamma-adjusted  numbers  and  internal  intensity-
       proportional numbers.

       Sometimes  you  are  not  working with true PNM or PAM images, but rather a variation in which the sample
       values are in fact directly proportional to intensity.  If so, use the -linear option  to  tell  pamscale
       this.  pamscale then will skip the conversions.

       The conversion takes time.  In one experiment, it increased by a factor of 10 the time required to reduce
       an image.  And the difference between intensity-proportional values  and  gamma-adjusted  values  may  be
       small  enough  that you would barely see a difference in the result if you just pretended that the gamma-
       adjusted values were in fact intensity-proportional.  So just to save time, at the expense of some  image
       quality, you can specify -linear even when you have true PPM input and expect true PPM output.

       For  the  first  13  years  of  Netpbm's  life, until Netpbm 10.20 (January 2004), pamscale's predecessor
       pnmscale always treated the PPM samples as intensity-proportional even though they were not, and drew few
       complaints.   So using -linear as a lie is a reasonable thing to do if speed is important to you.  But if
       speed is important, you also should consider the -nomix option and pnmscalefixed.

       Another technique to consider is to convert your PNM image to the linear  variation  with  pnmgamma,  run
       pamscale  on it and other transformations that like linear PNM, and then convert it back to true PNM with
       pnmgamma -ungamma.  pnmgamma is often faster than pamscale in doing the conversion.

       With -nomix, -linear has no effect.  That's because pamscale does not concern itself with the meaning  of
       the sample values in this method; pamscale just copies numbers from its input to its output.

   Precision
       pamscale  uses  floating  point  arithmetic internally.  There is a speed cost associated with this.  For
       some images, you can get the acceptable results  (in  fact,  sometimes  identical  results)  faster  with
       pnmscalefixed,  which  uses  fixed  point  arithmetic.   pnmscalefixed may, however, distort your image a
       little.  See the pnmscalefixed user manual for a complete discussion of the difference.

OPTIONS

       In addition to the options common to all programs based on libnetpbm (most notably -quiet, see
        Common Options ⟨index.html#commonoptions⟩ ), pamscale recognizes the following command line options:

       -width

       -height

       -xsize

       -ysize

       -xscale

       -yscale

       -xyfit

       -xyfill

       -reduce

       -pixels

       -xysize
                These options determine the horizontal and vertical scale factors.

                See The Scale Factors ⟨#scalefactor⟩ .

       -reportonly
                This causes pamscale not to scale the image, but instead to
                report to Standard Output what scaling the options and the input image
                dimensions indicate.

                See -reportonly ⟨#reportonly⟩ .

       -nomix
                This option selects discrete sampling ⟨#sampling⟩  as the

              method of scaling ⟨#methods⟩ .

       -filter=functionName
                This option selects resampling ⟨#resampling⟩  as the

              method of scaling ⟨#methods⟩ .

       -window=functionName
                This option selects a window function to modify the filter function
                specified with -filter.

              See Resampling ⟨#resampling⟩ .

       -verbose
                This option causes pamscale to issue messages to Standard Error about
                the scaling.

SEE ALSO

       pnmscalefixed(1),   pamstretch(1),   pamstretch-gen(1),   pamditherbw(1),   pbmreduce(1),   pbmpscale(1),
       pamenlarge(1), pnmsmooth(1), pamcut(1), pnmgamma(1), pnmscale(1), pnm(1), pam(1)

HISTORY

       pamscale  was  new  in  Netpbm  10.20  (January  2004).   It  was  adapted from, and obsoleted, pnmscale.
       pamscale's primary difference from pnmscale is that  it  handles  the  PAM  format  and  uses  the  "pam"
       facilities  of the Netpbm programming library.  But it also added the resampling class of scaling method.
       Furthermore, it properly does its pixel  mixing  arithmetic  (by  default)  using  intensity-proportional
       values  instead  of the gamma-adjusted values the pnmscale uses.  To get the old pnmscale arithmetic, you
       can specify the -linear option.

       The intensity proportional stuff came out of suggestions by Adam M Costello in January 2004.

       The resampling algorithms are mostly taken from code contributed by Michael Reinelt in December 2003.

       The version of pnmscale from which pamscale was derived, itself  evolved  out  of  the  original  Pbmplus
       version of pnmscale by Jef Poskanzer (1989, 1991).  But none of that original code remains.

DOCUMENT SOURCE

       This  manual  page was generated by the Netpbm tool 'makeman' from HTML source.  The master documentation
       is at

              http://netpbm.sourceforge.net/doc/pamscale.html