diff --git a/.gitignore b/.gitignore index 6c496c0..b07bd74 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ /netpbm-10.90.00.tar.xz /netpbm-10.92.00.tar.xz /netpbm-10.93.00.tar.xz +/netpbm-10.94.05.tar.xz diff --git a/netpbm-CAN-2005-2471.patch b/netpbm-CAN-2005-2471.patch index 77a3cd7..ae17d6b 100644 --- a/netpbm-CAN-2005-2471.patch +++ b/netpbm-CAN-2005-2471.patch @@ -1,8 +1,7 @@ -diff --git a/converter/other/pstopnm.c b/converter/other/pstopnm.c -index f534265..2ab48ab 100644 ---- a/converter/other/pstopnm.c -+++ b/converter/other/pstopnm.c -@@ -896,11 +896,11 @@ execGhostscript(int const inputPipeFd, +diff -urNp a/converter/other/pstopnm.c b/converter/other/pstopnm.c +--- a/converter/other/pstopnm.c 2018-07-23 15:14:51.200658026 +0200 ++++ b/converter/other/pstopnm.c 2018-07-23 15:18:12.579910612 +0200 +@@ -896,11 +896,11 @@ execGhostscript(int const ghostscriptProg, arg0, deviceopt, outfileopt, gopt, ropt, textalphabitsopt, "-q", "-dNOPAUSE", @@ -10,10 +9,9 @@ index f534265..2ab48ab 100644 + "-dPARANOIDSAFER", "-"); } -- execl(ghostscriptProg, arg0, deviceopt, outfileopt, gopt, ropt, + execl(ghostscriptProg, arg0, deviceopt, outfileopt, gopt, ropt, - textalphabitsopt, "-q", "-dNOPAUSE", "-dSAFER", "-", NULL); -+ execl(ghostscriptProg, arg0, deviceopt, outfileopt, gopt, ropt, "-q", -+ "-dNOPAUSE", "-dPARANOIDSAFER", "-", NULL); ++ "-q", "-dNOPAUSE", "-dPARANOIDSAFER", "-", NULL); pm_error("execl() of Ghostscript ('%s') failed, errno=%d (%s)", ghostscriptProg, errno, strerror(errno)); diff --git a/netpbm-manfix.patch b/netpbm-manfix.patch index c28beb4..f90130a 100644 --- a/netpbm-manfix.patch +++ b/netpbm-manfix.patch @@ -1,30 +1,25 @@ -diff --git a/userguide/avstopam.html b/userguide/avstopam.html -index eb39766..d104518 100644 ---- a/userguide/avstopam.html -+++ b/userguide/avstopam.html -@@ -2,25 +2,29 @@ +diff -urNp a/userguide/avstopam.html b/userguide/avstopam.html +--- a/userguide/avstopam.html 2021-06-02 12:56:59.584286425 +0200 ++++ b/userguide/avstopam.html 2021-06-02 15:00:33.799300026 +0200 +@@ -2,12 +2,13 @@ Avstopam User Manual

avstopam

-Updated: 07 February 2010 -
+-Table Of Contents + -+

Updated: 7 February 2010

++

Updated: 07 February 2010

+ +

Table Of Contents

-+ - Table Of Contents

NAME

-

avstopam - convert an AVS X image to a Netpbm image +

avstopam - convert an AVS X image to a Netpbm image

-+ --

SYNOPSIS

-+

SYNOPSIS

+

SYNOPSIS

-

avstopam - [avsfile] +@@ -16,40 +17,40 @@ Updated: 07 February 2010

DESCRIPTION

@@ -37,8 +32,11 @@ index eb39766..d104518 100644 +image as output.

avsfile is the input file, which defaults to Standard Input. - Output is always on Standard Output. -@@ -30,26 +34,26 @@ Output is always on Standard Output. +-Output is always on Standard Output. ++Output is always on Standard Output.

+ +

OPTIONS

+

There are no command line options defined specifically for avstopam, but it recognizes the options common to all programs based on libnetpbm (See @@ -48,8 +46,8 @@ index eb39766..d104518 100644

AUTHOR

Copyright © 2010 Scott Pakin, --scott+pbm@pakin.org. -+scott+pbm@pakin.org.

+-scott+pbm@pakin.org ++scott+pbm@pakin.org

SEE ALSO

@@ -69,49 +67,225 @@ index eb39766..d104518 100644 +
  • DESCRIPTION
  • +
  • OPTIONS
  • +
  • AUTHOR
  • -+
  • SEE ALSO
  • ++
  • SEE ALSO
  • -diff --git a/userguide/escp2topbm.html b/userguide/escp2topbm.html -index 9e808b7..33b19a0 100644 ---- a/userguide/escp2topbm.html -+++ b/userguide/escp2topbm.html -@@ -8,6 +8,7 @@ Updated: 14 July 2015 - -

    NAME

    - -+

    NAME

    - escp2topbm - convert an ESC/P2 printer file to a PBM image - -

    SYNOPSIS

    -diff --git a/userguide/faxformat.html b/userguide/faxformat.html -index 44b1ba5..827ffc8 100644 ---- a/userguide/faxformat.html -+++ b/userguide/faxformat.html +diff -urNp a/userguide/faxformat.html b/userguide/faxformat.html +--- a/userguide/faxformat.html 2021-06-02 12:56:59.576286351 +0200 ++++ b/userguide/faxformat.html 2021-06-02 15:02:58.710711998 +0200 @@ -5,10 +5,11 @@ Updated: 03 December 2008
    -+

    SYNOPSIS

    ++

    SYNOPSIS

    This page, part of the Netpbm user's guide, describes FAX formats in relation to Netpbm facilities. - -+

    DESCRIPTION

    ++

    DESCRIPTION

    The ITU (formerly CCITT) publishes standards for operation of fax machines (the idea is to provide a way to be sure that a fax machine is able to receive a fax sent by another). These standards incidentally specify graphics file -diff --git a/userguide/pampaintspill.html b/userguide/pampaintspill.html -index eeb1cac..e42db76 100644 ---- a/userguide/pampaintspill.html -+++ b/userguide/pampaintspill.html +diff -urNp a/userguide/libnetpbm_ug.html b/userguide/libnetpbm_ug.html +--- a/userguide/libnetpbm_ug.html 2021-06-02 12:56:59.584286425 +0200 ++++ b/userguide/libnetpbm_ug.html 2021-06-02 14:36:35.392293125 +0200 +@@ -374,7 +374,7 @@ plain format. +

    Reference

    + +

    The Libnetpbm Netpbm Image +-Processing Manual describes the the libnetpbm functions for ++Processing Manual describes the libnetpbm functions for + processing image data. + +

    The Libnetpbm Utility Manual +diff -urNp a/userguide/pamfunc.html b/userguide/pamfunc.html +--- a/userguide/pamfunc.html 2021-06-02 12:56:59.585286434 +0200 ++++ b/userguide/pamfunc.html 2021-06-02 14:40:09.474375441 +0200 +@@ -60,7 +60,7 @@ output image. + and bit string (such as and with 01001000). For the arithmetic functions, the + function arguments and results are the fraction that a sample is of the + maxval, i.e. normal interpretation of PAM tuples. But for the bit string +-functions, the value is the the bit string whose value as a binary cipher is ++functions, the value is the bit string whose value as a binary cipher is + the sample value, and the maxval indicates the width of the bit string. + +

    Arithmetic functions

    +diff -urNp a/userguide/pammixmulti.html b/userguide/pammixmulti.html +--- a/userguide/pammixmulti.html 2021-06-02 12:56:59.586286443 +0200 ++++ b/userguide/pammixmulti.html 2021-06-02 14:28:03.105311615 +0200 +@@ -7,8 +7,8 @@ Updated: 18 November 2018 + Table Of Contents + + +-

    NAME

    +-

    pammixmulti - blend together multiple PAM images ++

    NAME

    ++

    pammixmulti - blend together multiple PAM images

    + + +

    SYNOPSIS

    +@@ -22,14 +22,14 @@ Updated: 18 November 2018 +

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

    + + +

    DESCRIPTION

    +-

    This file is part of Netpbm. ++

    This file is part of Netpbm.

    + +

    pammixmulti mixes two or more images to produce a new image. The +-program provides multiple ways to interpret "mix." ++program provides multiple ways to interpret "mix."

    + + +

    OPTIONS

    +@@ -37,7 +37,7 @@ program provides multiple ways to interp +

    In addition to the options common to all programs based on libnetpbm + (most notably -quiet, see + Common Options), pammixmulti recognizes the following +-command line options: ++command line options:

    + +
    +
    --blend=average|random|mask
    +@@ -50,7 +50,7 @@ output is produced by selecting the corr + images, chosen at random on a per-pixel basis. With + --blend=mask, each pixel in the output is produced by a + weighted average of the corresponding pixels from all the input images based +-on the grayscale level of an additional mask image. ++on the grayscale level of an additional mask image.

    + + +
    --maskfile=filename
    +@@ -60,7 +60,7 @@ grayscale mask file to control the blend + not grayscale, the first channel is treated as gray). Where the mask file is + black, the first image is selected. Where the mask file is white, the last + image is selected. Intermediate levels of gray select intermediate +-images. ++images.

    + + +
    --stdev=number
    +@@ -77,7 +77,7 @@ that includes roughly equal amounts of t + and 2 but less of the corresponding pixel from image 3. As number + tends towards the number of input images (going beyond that has diminishing + impact), the output tends to look more +-like --blend=average. number defaults to 0.25. ++like --blend=average. number defaults to 0.25.

    + + +
    --randomseed integer +@@ -85,45 +85,45 @@ like --blend=average. numberThis is the seed for the random number generator used with + --blend=random + +-

    Use this to ensure you get the same image on separate invocations. ++

    Use this to ensure you get the same image on separate invocations.

    + +
    + +

    ARGUMENTS

    + +-

    You supply the names of the files to mix as non-option arguments. ++

    You supply the names of the files to mix as non-option arguments.

    + + +

    EXAMPLES

    + +-

    Average a bunch of PPM images to produce a new PAM image: ++

    Average a bunch of PPM images to produce a new PAM image:

    +
    
    +     pammixmulti input*.ppm >output.ppm
    + 
    + +

    Mix these same images by taking each pixel from a randomly selected input +-image: ++image:

    + +
    
    +     pammixmulti --blend=random input*.ppm >output.ppm
    + 
    + +

    Use a mask image to control the fading among input images on a +-pixel-by-pixel basis: ++pixel-by-pixel basis:

    + +
    
    +     pammixmulti --blend=mask --maskfile=mask.pgm >output.pam \
    +        one.pam two.pam three.pam four.pam
    + 
    + +-

    Do the same but with more abrupt transitions: ++

    Do the same but with more abrupt transitions:

    + +
    
    +     pammixmulti --blend=mask --maskfile=mask.pgm --stdev=0.0 >output.pam \
    +        one.pam two.pam three.pam four.pam
    + 
    + +-

    and now with more gradual transitions: ++

    and now with more gradual transitions:

    + +
    
    +     pammixmulti --blend=mask --maskfile=mask.pgm --stdev=1.0 >output.pam \
    +@@ -133,12 +133,12 @@ pixel-by-pixel basis:
    + 
    + 

    HISTORY

    + +-

    pammixmulti was new in Netpbm 10.85 (December 2018). ++

    pammixmulti was new in Netpbm 10.85 (December 2018).

    + + +

    AUTHOR

    + +-

    Copyright 2018 Scott Pakin, scott+pbm@pakin.org. ++

    Copyright 2018 Scott Pakin, scott+pbm@pakin.org.

    + +

    SEE ALSO

    + +@@ -146,20 +146,20 @@ pixel-by-pixel basis: + ppmmix, + pamarith, + pnm, +-pam ++pam

    + + +

    Table Of Contents

    + + + + +diff -urNp a/userguide/pampaintspill.html b/userguide/pampaintspill.html +--- a/userguide/pampaintspill.html 2021-06-02 12:56:59.575286342 +0200 ++++ b/userguide/pampaintspill.html 2021-06-02 15:06:31.354767352 +0200 @@ -2,12 +2,12 @@ Pampaintspill User Manual

    pampaintspill

    --Updated: 09 February 2020 -+

    Updated: 09 February 2020 +-Updated: 06 March 2021 ++

    Updated: 06 March 2021
    -Table Of Contents +Table Of Contents

    @@ -122,12 +296,13 @@ index eeb1cac..e42db76 100644

    SYNOPSIS

    -@@ -16,31 +16,31 @@ pampaintspill - smoothly spill colors into the background - [--bgcolor=color] +@@ -17,17 +17,17 @@ pampaintspill - smoothly spill colors in [--wrap] [--all] [--downsample=number] --[--power=number] [filename] -+[--power=number] [filename]

    + [--power=number] [filename] +-[-randomseed=integer] ++[-randomseed=integer]

    +

    Minimum unique abbreviations of option are acceptable. You may use double hyphens instead of single hyphen to denote options. You may use @@ -142,11 +317,7 @@ index eeb1cac..e42db76 100644

    pampaintspill produces a smooth color gradient from all of the non-background-colored pixels in an input image, effectively "spilling - paint" onto the background. pampaintspill is similar to --pamgradient but differs in the following characteristics: -+pamgradient but differs in the following characteristics:

    - -
      +@@ -38,27 +38,27 @@ paint" onto the background. pampaint
    • pampaintspill accepts any number of paint sources (non-background-colored pixels), which can lie anywhere on the canvas. pamgradient accepts exactly @@ -160,7 +331,9 @@ index eeb1cac..e42db76 100644
    • pampaintspill can produce tileable output and can control how tightly the gradient colors bind to their source -@@ -49,14 +49,14 @@ paint" onto the background. pampaintspill is similar to +- pixels. ++ pixels.
    • +

    Results are generally best when the input image contains just a few, crisp spots of color. Use your drawing program's pencil tool — as opposed to a @@ -177,40 +350,91 @@ index eeb1cac..e42db76 100644

    --bgcolor=color
    -diff --git a/userguide/pamrecolor.html b/userguide/pamrecolor.html -index 3f341d4..a5f2671 100644 ---- a/userguide/pamrecolor.html -+++ b/userguide/pamrecolor.html -@@ -2,12 +2,15 @@ +@@ -107,42 +107,42 @@ command line options: +
    This is the seed for the random number generator that generates the + pixels. + +-

    Use this to ensure you get the same image on separate invocations. ++

    Use this to ensure you get the same image on separate invocations.

    + +-

    This option was new in Netpbm 10.94 (March 2021). ++

    This option was new in Netpbm 10.94 (March 2021).

    +
    + + +

    SEE ALSO

    + + + +

    HISTORY

    + +-

    pampaintspill was new in Netpbm 10.50 (March 2010). ++

    pampaintspill was new in Netpbm 10.50 (March 2010).

    + + + + +

    Copyright © 2010 Scott Pakin, +-scott+pbm@pakin.org. ++scott+pbm@pakin.org.

    + +

    Table Of Contents

    + + + + +diff -urNp a/userguide/pamrecolor.html b/userguide/pamrecolor.html +--- a/userguide/pamrecolor.html 2021-06-02 12:56:59.574286333 +0200 ++++ b/userguide/pamrecolor.html 2021-06-02 15:09:53.837724488 +0200 +@@ -2,9 +2,9 @@ Pamrecolor User Manual

    pamrecolor

    -Updated: 31 July 2010 --
    ++

    Updated: 31 July 2010 +
    -Table Of Contents ++Table Of Contents

    --

    NAME

    --pamrecolor - alter colors without affecting luminance -+

    Updated: 31 July 2010

    -+ -+

    Table Of Contents

    -+ -+ -+

    NAME

    -+ -+

    pamrecolor - alter colors without affecting luminance

    - -

    SYNOPSIS

    - -@@ -22,6 +25,7 @@ pamrecolor - alter colors without affecting luminance +

    NAME

    + pamrecolor - alter colors without affecting luminance +@@ -22,15 +22,15 @@ pamrecolor - alter colors without affect [-randomseed=integer] [infile] +- +

    -

    Minimum unique abbreviation of option is acceptable. You may use double -@@ -30,7 +34,7 @@ space in place of the equals sign to separate an option name from its value. + 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. ++space in place of the equals sign to separate an option name from its value.

    DESCRIPTION

    @@ -219,16 +443,19 @@ index 3f341d4..a5f2671 100644

    pamrecolor changes an image's colors to be as close as possible to given target colors but with the constraint that the -@@ -39,7 +43,7 @@ image will look identical if both are converted to grayscale +@@ -39,17 +39,17 @@ image will look identical if both are co (e.g. with ppmtopgm). You can have pamrecolor select target colors randomly, specify a single hue for the entire image, or take the -target colors from a target image. +target colors from a target image.

    -

    pamrecolor works on pseudo-Netpbm images based on arbitrary - color spaces. You can define the color space explicitly or choose one -@@ -49,7 +53,7 @@ of many that pamrecolor knows by name. +

    In addition to real Netpbm images, pamrecolor works on pseudo-Netpbm + images based on arbitrary color spaces. You can define the color space +-explicitly or choose one of many that pamrecolor knows by name. ++explicitly or choose one of many that pamrecolor knows by name.

    + +

    The output is a PAM image on standard output. Options control the exact format of the PAM. If you want a PNM (PBM, PGM, or PPM) image, use pamtopnm on the output. There is no need to convert if you will use the image as input to a current Netpbm @@ -237,7 +464,7 @@ index 3f341d4..a5f2671 100644

    OPTIONS

    -@@ -57,7 +61,7 @@ program, but many other programs don't know what a PAM is. +@@ -57,7 +57,7 @@ program, but many other programs don't k

    In addition to the options common to all programs based on libnetpbm (most notably -quiet, see Common Options), pamrecolor recognizes the following @@ -246,7 +473,19 @@ index 3f341d4..a5f2671 100644

    -@@ -109,12 +113,12 @@ the format that uses sRGB. +@@ -76,9 +76,9 @@ the raster have different meaning. Many + images actually use a variation with a different color space. For example, + GIMP uses sRGB internally and if you + have GIMP generate a Netpbm image file, it really generates a variation of +-the format that uses sRGB. ++the format that uses sRGB.

    + +-

    pamrecolor knows the following color spaces (name values): ++

    pamrecolor knows the following color spaces (name values):

    + +
    +
    adobe
    +@@ -109,7 +109,7 @@ the format that uses sRGB.

    The default is "ntsc" because this is the color space that the Netpbm formats and many graphics utilities use. As a counterexample, GIMP uses sRGB as its native color @@ -255,1747 +494,1378 @@ index 3f341d4..a5f2671 100644

    The luminance values pamrecolor uses for each of the above come from Bruce Lindbloom's - --Computing RGB-to-XYZ and XYZ-to-RGB matrices page. -+Computing RGB-to-XYZ and XYZ-to-RGB matrices page.

    - -
    --rmult=fraction
    -
    --gmult=fraction
    -@@ -137,7 +141,7 @@ library routine (e.g., "hotpink" or "#ff69b4"). - -

    If you specify neither --targetcolor nor - --colorfile, pamrecolor will randomly select a target color for --each pixel of the input image. -+each pixel of the input image.

    - -

    You may not specify both -targetcolor and -colorfile. - -@@ -154,7 +158,7 @@ image to be repeated in a tile pattern. - -

    If you specify neither --targetcolor nor - --colorfile, pamrecolor will randomly select a target color for --each pixel of the input image. -+each pixel of the input image.

    - -

    You may not specify both -targetcolor and -colorfile. - -@@ -176,23 +180,23 @@ invocations. - -

    EXAMPLES

    - --

    This command tints an image yellow: -+

    This command tints an image yellow:

    - -
    --    pamrecolor --targetcolor=yellow colorpic.pam > yellowpic.pam
    -+    pamrecolor --targetcolor=yellow colorpic.pam > yellowpic.pam
    - 
    - -

    This command takes the colors from colorpicture.ppm and applies --them to graypicture.pgm: -+them to graypicture.pgm:

    - -
    --    pamrecolor --colorfile=colorpic.ppm graypic.pgm > colorizedpic.pam
    -+    pamrecolor --colorfile=colorpic.ppm graypic.pgm > colorizedpic.pam
    - 
    - -

    The grayscale version of colorizedpic.pam will look just like - graypic.pgm. Note that if you use a non-Netpbm tool to do the conversion to - grayscale, you may additionally need to specify an --appropriate --colorspace value for your conversion tool. -+appropriate --colorspace value for your conversion tool.

    - - -

    NOTES

    -@@ -203,25 +207,25 @@ appropriate --colorspace value for your conversion tool. -
      -
    • Specify a color file that is identical to the input image but with - some large, colored text added to it. The text will "magically" --vanish when the image is converted to grayscale. -+vanish when the image is converted to grayscale.
    • - -
    • Provide a low-contrast grayscale image — perhaps a secret - message written in similar shades of gray — as the input file and - a colorful but completely different image as the color file. If done - carefully, the grayscale image can be hidden by the colorful image. - Only people who know to convert the result to grayscale can recover --the original grayscale image. -+the original grayscale image.
    • - -
    • Use --targetcolor=tan to make an image look like an - old-timey photograph (or, more precisely, a - sepia-toned --photograph of the late 1800s). -+photograph of the late 1800s).
    • -
    - - -

    HISTORY

    - --

    Scott Pakin wrote pamrecolor in July 2010. -+

    Scott Pakin wrote pamrecolor in July 2010.

    - -

    pamrecolor was new in Netpbm 10.52 (September 2010). - -@@ -229,7 +233,7 @@ photograph of the late 1800s). -

    AUTHOR

    - -

    Copyright (C) 2010 Scott --Pakin, scott+pbm@pakin.org. -+Pakin, scott+pbm@pakin.org.

    - - -

    SEE ALSO

    -@@ -246,14 +250,14 @@ Pakin, scott+pbm@pakin.org. -

    Table Of Contents

    - - - - -diff --git a/userguide/pamsistoaglyph.html b/userguide/pamsistoaglyph.html -index 1ca53ac..e545986 100644 ---- a/userguide/pamsistoaglyph.html -+++ b/userguide/pamsistoaglyph.html -@@ -1,15 +1,18 @@ - - Pamsistoaglyph User Manual - -+ -

    pamsistoaglyph

    --Updated: 05 April 2009 --
    --Table Of Contents -+ -+

    Updated: 5 April 2009

    -+ -+

    Table Of Contents

    -+ - -

    NAME

    - --pamsistoaglyph - convert a single-image stereogram to a red/cyan --anaglyphic image -+

    pamsistoaglyph - convert a single-image stereogram to a red/cyan -+anaglyphic image

    - - -

    SYNOPSIS

    -@@ -20,11 +23,11 @@ anaglyphic image - [--minsep=number] - [--gray=number] - [in_netpbmfile -- -+

    - -

    All options can be abbreviated to their shortest unique prefix. You - may use either white space or an equals sign between an option name --and its value. -+and its value.

    - - -

    DESCRIPTION

    -@@ -32,7 +35,7 @@ and its value. -

    This program is part of Netpbm. - -

    pamsistoaglyph reads a Netpbm image as input and --produces a Netpbm image as output. -+produces a Netpbm image as output.

    - -

    pamsistoaglyph takes a single-image stereogram - (SIS) such as those produced by

    - Common Options), pamsistoaglyph recognizes the following + Common Options), pbmtog3 recognizes the following -command line options: +command line options:

    -

    For most images, no command-line options need to be specified. The --following options are available, however, for unusual circumstances. -+following options are available, however, for unusual circumstances.

    -
    --
    --invert -+
    --invert
    -
    Swap the left- and right-eye - images. pamsistoaglyph assumes that its input - represents a wall-eyed stereogram and generates the anaglyphic -@@ -71,17 +74,17 @@ following options are available, however, for unusual circumstances. - the page where it should pop out of the page (and vice versa), - this typically implies that the input image represents a - cross-eyed stereogram. Use --invert to correct -- the image depth. -+ the image depth.
    - --
    --sep=number -+
    --sep=number
    -
    Specify the distance in pixels between the left- and right-eye - images. Essentially, this corresponds to the distance between - repetitions of the background pattern. The --sep - option should rarely be necessary - as pamsistoaglyph is fairly good at determining -- automatically the eye-separation distance. -+ automatically the eye-separation distance.
    - --
    --minsep=number -+
    --minsep=number
    -
    This option is similar to --sep but - constrains pamsistoaglyph only to - a minimum eye-separation distance. Any distance larger -@@ -90,9 +93,9 @@ following options are available, however, for unusual circumstances. - as pamsistoaglyph is fairly good at determining - automatically the eye-separation distance. The default value for - the minimum eye-separation distance is 10% of the image width; -- this value seems to work well in practice. -+ this value seems to work well in practice.
    - --
    --gray=number -+
    --gray=number
    -
    Limit the number of gray levels to use when searching for the - optimal eye-separation - distance. Because pamsistoaglyph looks for -@@ -103,7 +106,7 @@ following options are available, however, for unusual circumstances. - unintentional color variations (such as those caused by conversion - from a low-quality JPEG image, for example). The default of 63 - seems to work well so the --gray option should -- rarely be necessary. -+ rarely be necessary.
    -
    - - -@@ -112,22 +115,22 @@ following options are available, however, for unusual circumstances. -

    The registration algorithm used by pamsistoaglyph - was developed specifically for this program. As far as the author - knows, there are no existing algorithms for converting stereograms to --anaglyphs. The algorithm works as follows: -+anaglyphs. The algorithm works as follows:

    - -
      -
    1. Convert the image to grayscale to increase the ability to identify -- matches. -+ matches.
    2. - -
    3. Count the number of pixels that match N pixels ahead in the -- image for all N in [1, width/2]. -+ image for all N in [1, width/2].
    4. - -
    5. Maintain a running mean (μ) and standard deviation (σ) of -- the number of matched pixels. -+ the number of matched pixels.
    6. - -
    7. Store the N corresponding to each spike in the number of - matched pixels. A spike is defined as a tally that exceeds the - mean plus one, two, or three standard deviations. Only the first -- spike of a given standard-deviation multiplier is stored. -+ spike of a given standard-deviation multiplier is stored.
    8. - -
    9. If a tally greater than μ+3σ was encountered, return the - corresponding N. If not, then if a tally greater than -@@ -138,13 +141,13 @@ anaglyphs. The algorithm works as follows: - produces the minimum average distance between matched pixels - (i.e., #matches divided by #pixels). If no - such N exceeds the minimum allowable eye-separation value, -- return zero to indicate failure. -+ return zero to indicate failure.
    10. - -
    11. If the algorithm returned zero, rerun the algorithm independently - on each row of the input image and return the median of - all N that exceed the minimum allowable eye-separation - value. If no such N exists, abort with an error -- message. -+ message.
    12. -
    - -

    HISTORY

    -@@ -156,7 +159,7 @@ in Netpbm in Release 10.47 (June 2009). -

    AUTHOR

    - -

    Copyright (C) 2009 Scott --Pakin, scott+pbm@pakin.org. -+Pakin, scott+pbm@pakin.org.

    - - -

    SEE ALSO

    -@@ -174,13 +177,13 @@ Pakin, scott+pbm@pakin.org. -

    Table Of Contents

    - - - - -diff --git a/userguide/pamtoavs.html b/userguide/pamtoavs.html -index 5d0ae35..bee1a40 100644 ---- a/userguide/pamtoavs.html -+++ b/userguide/pamtoavs.html -@@ -2,13 +2,15 @@ - Pamtoavs User Manual - -

    pamtoavs

    --Updated: 07 February 2010 --
    --Table Of Contents -+ -+

    Updated: 7 February 2010

    -+ -+

    Table Of Contents

    -+ - -

    NAME

    - --

    pamtoavs - convert a Netpbm image to an AVS X image -+

    pamtoavs - convert a Netpbm image to an AVS X image

    - -

    SYNOPSIS

    - -@@ -17,7 +19,7 @@ Updated: 07 February 2010 - -

    DESCRIPTION

    - --

    This program is part of Netpbm. -+

    This program is part of Netpbm.

    - -

    pamtoavs reads a Netpbm image as input and produces a Stardent - AVS -@@ -27,14 +29,14 @@ href="http://www.gnuplot.info/">Gnuplot v4.2 and later can use. -

    netpbmfile is the input file, which defaults to Standard Input. - Output is always on Standard Output. - --

    Try the following: -+

    Try the following:

    - -
    -     gnuplot> plot 'myimage.avs' binary filetype=avs with rgbimage
    - 
    - -

    See the Gnuplot --manual for more information. -+manual for more information.

    - - -

    OPTIONS

    -@@ -42,29 +44,29 @@ manual for more information. -

    There are no command line options defined specifically - for pamtoavs, but it recognizes the options common to all - programs based on libnetpbm (See --Common Options.) -+Common Options.)

    - -

    AUTHOR

    - -

    Copyright © 2010 Scott Pakin, --scott+pbm@pakin.org. -+scott+pbm@pakin.org.

    - -

    SEE ALSO

    - -

    avstopam, - gnuplot, --pam -+pam

    - -
    - -

    Table Of Contents

    - - - - -diff --git a/userguide/pamtooctaveimg.html b/userguide/pamtooctaveimg.html -index 4e09e8e..d2cc50b 100644 ---- a/userguide/pamtooctaveimg.html -+++ b/userguide/pamtooctaveimg.html -@@ -2,13 +2,13 @@ - Pamtooctaveimg User Manual - -

    pamtooctaveimg

    --
    --

    Updated: 27 June 2007
    --Table Of Contents -+ -+

    Updated: 27 June 2007
    -+Table Of Contents

    - -

    NAME

    - --

    pamtooctaveimg - convert a Netpbm image to a GNU Octave image -+

    pamtooctaveimg - convert a Netpbm image to a GNU Octave image

    - -

    SYNOPSIS

    - -@@ -17,7 +17,7 @@ - -

    DESCRIPTION

    - --

    This program is part of Netpbm. -+

    This program is part of Netpbm.

    - -

    pamtooctaveimg reads a Netpbm image as input and produces a GNU Octave image file as output. -@@ -45,7 +45,7 @@ Image Processing chapter of the GNU Octave manual for details. -

    There are no command line options defined specifically - for pamtooctaveimg, but it recognizes the options common to all - programs based on libnetpbm (See --Common Options.) -+Common Options.)

    - -

    ARGUMENTS

    - -@@ -77,7 +77,8 @@ specify netpbmfile, the input is from Standard Input. -

    NOTES

    - -

    There is no octavetopam program. However, GNU Octave's --saveimage command can save images in PPM format. -+saveimage command can save images in PPM format.

    -+ - +
    -reversebits +@@ -80,7 +80,7 @@ You cannot specify both.

    HISTORY

    -@@ -86,7 +87,7 @@ specify netpbmfile, the input is from Standard Input. -

    AUTHOR

    +

    Before Netpbm 10.79 (June 2017), there was a different program by the same +-name in Netpbm, which was written by by Paul Haeberli ++name in Netpbm, which was written by Paul Haeberli + <paul@manray.sgi.com> in 1989 + and then modified extensively by others. -

    Copyright (C) 2007 Scott Pakin, --scott+pbm@pakin.org. -+scott+pbm@pakin.org.

    - -

    SEE ALSO

    - -@@ -98,15 +99,15 @@ href="http://www.gnu.org/software/octave/doc/interpreter/index.html">octaveTable Of Contents - - - -diff --git a/userguide/pnmflip.html b/userguide/pnmflip.html -index 2bd7368..8a1916e 100644 ---- a/userguide/pnmflip.html -+++ b/userguide/pnmflip.html -@@ -5,17 +5,18 @@ - -

    NAME

    - --pnmflip - replaced by pamflip -+

    pnmflip - replaced by pamflip

    - -

    DESCRIPTION

    - --

    This program is part of Netpbm. -+

    This program is part of Netpbm.

    - -

    pnmflip was replaced in Netpbm 10.13 (December 2002) by - pamflip. - -+

    DESCRIPTION

    -

    pamflip is mostly backward compatible with pnmflip, --but works on PAM images too. -+but works on PAM images too.

    - -

    One way pamflip is not backward compatible with pnmflip - is that pnmflip lets you specify any number of basic flip options, -@@ -23,12 +24,12 @@ whereas pamflip requires exactly one. (pamflip provides - the -xform option for requesting multiple transformations, though). - Because of this incompatibility, pnmflip still exists as a - separate program, and all it does is translate its options to pamflip --style and run pamflip. -+style and run pamflip.

    - -

    You should not make any new use of pnmflip and if you modify an - existing use, you should upgrade to pamflip. But note that if you - write a program that might have to be used with very old --Netpbm, pnmflip is the only way to do that. -+Netpbm, pnmflip is the only way to do that.

    - - - -diff --git a/userguide/pnmmercator.html b/userguide/pnmmercator.html -index 998f7fb..65576ac 100644 ---- a/userguide/pnmmercator.html -+++ b/userguide/pnmmercator.html -@@ -18,11 +18,12 @@ projection and vice-versa - [filename] - -

    Minimum unique abbreviation of option is acceptable. --You may use double hyphens instead of single hyphen to denote options. -+You may use double hyphens instead of single hyphen to denote options.

    - -

    DESCRIPTION

    - --

    This program is part of Netpbm. -+

    This program is part of Netpbm.

    - -

    The pnmmercator utility, converts a rectangular projection worldmap - to a Mercator projection format, as used for maps.google.com and many other -@@ -31,34 +32,34 @@ online maps. The map used as input for pnmmercator must have rows for - file will typically be twice as wide as high, but this is not a - requirement. The output file will be using the Mercator --projection and will get double the height of the input file. -+projection and will get double the height of the input file.

    - -

    Maps using the Mercator projection are stretched more the closer a row is - to the North or South Pole. The last few degrees (> 85 or < -85 degrees) - are not part of a Mercator map at all because they would be stretched too much - and the rows close to the edge will show banding, because they originate from --the same row in the original map. -+the same row in the original map.

    - -

    To overcome this, the program will by default do interpolation of pixel - colors, which will eliminate the banding effect, but will cause some blurring - of the output. With the -nomix option, this interpolation of colors isn't - applied. You can obtain the highest quality output by starting with an input - map of high resolution, so that you can follow the pnmmercator --transformation with a pamscale reduction in size. -+transformation with a pamscale reduction in size.

    - -

    This program can also convert a Mercator projection map back to a - rectangular projection based. As said, the Mercator map doesn't have - information about the latitudes close to the poles. Therefore the top rows in - the output image will be identical and copied from the row corresponding with --latitude of 85 degrees. The same at the bottom of the map. -+latitude of 85 degrees. The same at the bottom of the map.

    - -

    Pnmmercator doesn't have any provision for scaling the image. You can scale - by piping the output of the program through Netpbm programs such as --pamscale. -+pamscale.

    - -

    You can find maps to be used as input at flatplanet.sourceforge.net --or uic.edu/pape. -+or uic.edu/pape.

    - -

    The point of a Mercator projection map is that compass directions work on - it. If you draw a straight line northeast from some point on the Mercator -@@ -78,33 +79,33 @@ proportional to angular longitude. -

    PARAMETERS

    - -

    filename is the name of the input file. If you don't specify --this, pnmmercator reads the image from standard Input. -+this, pnmmercator reads the image from standard Input.

    - -

    OPTIONS

    - -

    In addition to the options common to all programs based on libnetpbm - (most notably -quiet, see - Common Options), pnmmercator recognizes the following --command line options: -+command line options:

    - -
    -
    -inverse
    -
    -

    With this option a conversion from Mercator to degrees is applied.The --output image will have half the height of the input map. -+output image will have half the height of the input map.

    -
    -
    -nomix
    -
    -

    Default behaviour is that color blending is applied in between two adjacent - rows. If you specify the -nomix parameter there is no blending. The - consequence is a banding at the top and bottom of the map. With this option, --the output map will also consist of exactly the same colors as the input. -+the output map will also consist of exactly the same colors as the input.

    -
    -
    -verbose and -vverbose
    -
    -

    This parameter outputs some additional information. If you double the 'v', - it will output debug data about the lat/long degree and Mercator --conversions. -+conversions.

    -
    -
    - -@@ -114,25 +115,26 @@ conversions. - ppmglobe - -

    HISTORY

    --

    pnmmercator was new in Netpbm 10.49 (December 2009). -+

    pnmmercator was new in Netpbm 10.49 (December 2009).

    - -

    AUTHORS

    - -

    Willem van Schaik (of - pnmtopng/pngtopnm fame) wrote this program in October 2009 and --suggested it for inclusion in Netpbm. -+suggested it for inclusion in Netpbm.

    - -
    - -

    Table Of Contents

    - - - -diff --git a/userguide/ppmtogif.html b/userguide/ppmtogif.html -index 513133a..fa72e09 100644 ---- a/userguide/ppmtogif.html -+++ b/userguide/ppmtogif.html -@@ -5,17 +5,16 @@ +diff -urNp a/userguide/ppmtogif.html b/userguide/ppmtogif.html +--- a/userguide/ppmtogif.html 2021-06-02 12:56:59.574286333 +0200 ++++ b/userguide/ppmtogif.html 2021-06-02 15:48:19.167930575 +0200 +@@ -5,17 +5,17 @@

    NAME

    -ppmtogif - replaced by pamtogif - -

    DESCRIPTION

    -- --

    This program is part of Netpbm. +

    ppmtogif - replaced by pamtogif

    -+

    This program is part of Netpbm.

    -

    ppmtogif was replaced in Netpbm 10.37 (December 2006) by --pamtogif. -+pamtogif.

    +

    This program is part of Netpbm. +

    SYNOPSIS

    +

    ppmtogif was replaced in Netpbm 10.37 (December 2006) by + pamtogif. +

    pamtogif is mostly backward compatible with ppmtogif. +

    DESCRIPTION

    One way pamtogif is not backward compatible with ppmtogif is that to specify a transparency (alpha) mask with ppmtogif, you supply the transparency as a separate pseudo-PGM image and use the -@@ -77,8 +76,8 @@ the alpha image need not have the same maxval as the input. - ppmtogif interprets the alpha file using the alpha file's - maxval. - --

    You cannot specify both -transparent and -alpha. -+

    You cannot specify both -transparent and -alpha.

    - - -- -- -+ -+ -diff -urNp a/userguide/pamstereogram.html b/userguide/pamstereogram.html ---- a/userguide/pamstereogram.html 2021-01-26 13:41:35.057401508 +0100 -+++ b/userguide/pamstereogram.html 2021-01-26 14:23:22.076294594 +0100 -@@ -9,7 +9,8 @@ - -

    NAME

    - --pamstereogram - create a single-image stereogram from a PAM depth map -+

    pamstereogram - create a single-image stereogram from a PAM -+depth map

    - -

    SYNOPSIS

    - -@@ -39,13 +40,13 @@ pamstereogram - create a single-image st - [-randomseed=integer] - [-tileable] - [infile] +diff -urNp a/userguide/ppmtompeg.html b/userguide/ppmtompeg.html +--- a/userguide/ppmtompeg.html 2021-06-02 12:56:59.580286388 +0200 ++++ b/userguide/ppmtompeg.html 1970-01-01 01:00:00.000000000 +0100 +@@ -1,1294 +0,0 @@ +- +-Ppmtompeg User Manual +- +-

    ppmtompeg

    +-Updated: 23 July 2006 +-
    +-Table Of Contents +- +-

    NAME

    +-ppmtompeg - encode an MPEG-1 bitstream +- +-

    SYNOPSIS

    +- +-ppmtompeg +-[options] +-parameter-file +- +-

    DESCRIPTION

    - -+

    - - - -

    DESCRIPTION

    - -

    This program is part of Netpbm. -+

    This program is part of Netpbm.

    - -

    pamstereogram inputs a depth map (a map of the distances - from your eye of the points in a scene) and outputs a single-image -@@ -55,22 +56,22 @@ eyes. What's exciting about single-image - don't require special glasses to view, although it does require a bit - of practice to train your eyes to unfocus properly. The - pamstereogram program provides a wealth of control over how the --stereogram is generated, including the following: -+stereogram is generated, including the following:

    - -
      --
    • black and white, grayscale, or color output -+
    • black and white, grayscale, or color output
    • - -
    • single-image random-dot stereograms (SIRDS), single-image - stereograms (SIS) using a tiled image, or mapped-texture stereograms --(MTS) -+(MTS)
    • - --
    • images targeting a given device resolution and eye separation -+
    • images targeting a given device resolution and eye separation
    • - --
    • optional guide boxes to assist in focusing -+
    • optional guide boxes to assist in focusing
    • - --
    • the ability to trade off depth levels for easier viewing -+
    • the ability to trade off depth levels for easier viewing
    • - --
    • choice of wall-eyed or cross-eyed stereograms -+
    • choice of wall-eyed or cross-eyed stereograms
    • - -
    -

    The output is a PAM image on standard output. Options control -@@ -80,7 +81,7 @@ if you will use the image as input to a - many other programs don't know what a PAM is. - -

    To make a red/cyan type of stereogram (that you view with 3-D --glasses) instead, see ppm3d. -+glasses) instead, see ppm3d.

    - - -

    OPTIONS

    -@@ -92,32 +93,32 @@ from its value. -

    In addition to the options common to all programs based on libnetpbm - (most notably -quiet, see - Common Options), pamstereogram recognizes the following --command line options: -+command line options:

    - -
    - --
    -verbose -+
    -verbose
    -
    Display messages about image sizes and formats and properties --of the stereogram being generated. -+of the stereogram being generated.
    - --
    -blackandwhite -+
    -blackandwhite
    -
    Produce a single-image random-dot black-and-white stereogram. --This is the default. -+This is the default.
    - --
    -grayscale --
    Produce a single-image random-dot grayscale stereogram. -+
    -grayscale
    -+
    Produce a single-image random-dot grayscale stereogram.
    - --
    -color --
    Produce a single-image random-dot color stereogram. -+
    -color
    -+
    Produce a single-image random-dot color stereogram.
    - --
    -maxval=value -+
    -maxval=value
    -
    Designate the maximum value of each gray/color component, i.e. - the color resolution. Smaller values make the output image have - smaller numbers of unique grays/colors. If you don't specify - -maxval, pamstereogram uses the maxval of the input --image. This option has no effect with -blackandwhite. -+image. This option has no effect with -blackandwhite.
    - --
    -patfile=pamfile -+
    -patfile=pamfile
    -
    Specify an image to use as a repeated background pattern for - the stereogram instead of a random-dot pattern. Intricate images - generally produce a crisper 3-D effect that simpler images. The -@@ -126,9 +127,9 @@ grayscale or color) as the pattern file. - -patfile option along with -blackandwhite, - -grayscale, -color, or -maxval. The - -verbose option will give you information on the ideal --dimensions of the pattern file. -+dimensions of the pattern file.
    - --
    -xbegin=pixels -+
    -xbegin=pixels
    -
    Specify the horizontal coordinate at which to begin stereogram generation. - The background pattern will be minimally distorted at this point and more - distorted at greater distances. Consider using this in conjunction -@@ -136,38 +137,38 @@ with -xshift to align the horizon - horizontal start of stereogram generation. -xbegin is meaningful only - in conjunction with -patfile, -makemask, or -texfile, - and pamstereogram actually ignores it with respect to -texfile --(but may not in a future version of pamstereogram). -+(but may not in a future version of pamstereogram).
    - --

    The default is to begin in the center. -+

    The default is to begin in the center.

    - --

    This option was new in Netpbm 10.71 (June 2015). -+

    This option was new in Netpbm 10.71 (June 2015).

    - --
    -texfile=pamfile -+
    -texfile=pamfile
    -
    Specify an image to use as the texture for a mapped-texture - stereogram. The idea is that the depth-map image provides the depth - values of the 3-D object/scene while the texture image provides the - true-color values. Consequently, the texture image should align with - the depth-map image. (Note that it's required to have the same - dimensions.) The texture image's background color is ignored when --blending colors. -+blending colors.
    - --

    This option was new in Netpbm 10.53 (December 2010). -+

    This option was new in Netpbm 10.53 (December 2010).

    - - --
    -bgcolor=color -+
    -bgcolor=color
    -
    Use color as the texture image's background color instead - of letting pamstereogram determine it automatically. Specify - the color as described for the - argument of the pnm_parsecolor() library - routine. The -bgcolor option is meaningful only in conjunction --with -texfile. -+with -texfile.
    - --

    This option was new in Netpbm 10.53 (December 2010). -+

    This option was new in Netpbm 10.53 (December 2010).

    - - --
    -smoothing=pixels -+
    -smoothing=pixels
    -
    When used without -texfile, attempt to eliminate artifacts --introduced by edges in the depth map if pixels is greater than zero. -+introduced by edges in the depth map if pixels is greater than zero.
    - -

    When used with -texfile, horizontally blur non-background - colors into background pixels up to a distance of pixels pixels. -@@ -176,22 +177,22 @@ by the stereogram's color constraints wh - stereogram. In this case, the -smoothing option is helpful - when the texture image includes smooth color transitions (as in a - photograph) but makes crisp texture images (as in a line drawing) --appear blurry. -+appear blurry.

    - -

    This option was new in Netpbm 10.53 (December 2010). Before --Netpbm 10.61 (December 2012), it has no effect without -texfile. -+Netpbm 10.61 (December 2012), it has no effect without -texfile.

    - - --
    -xshift=pixels -+
    -xshift=pixels
    -
    Shift the pattern image (designated by -patfile) to the --right by pixels pixels (default: 0). +- +-

    ppmtompeg produces an MPEG-1 video stream. MPEG-1 is the +-first great video compression method, and is what is used in Video CDs +-(VCD). ppmtompeg originated in the year 1995. DVD uses a more +-advanced method, MPEG-2. There is an even newer method called MPEG-4 +-which is also called Divx. I don't know where one finds that used. +- +-

    There's technically a difference between a compression method for +-video and an actual file (stream) format for a movie, and I don't know +-if it can be validly said that the format of the stream +-ppmtompeg produces is MPEG-1. +- +-

    Mencoder from the Mplayer +-package is probably superior for most video format generation +-needs, if for no other reason than that it is more popular. +- +-

    The programming library PM2V +-generates MPEG-2 streams. +- +-

    Use Mplayer (not part of Netpbm) +-to do the reverse conversion: to create a series of PNM files from an MPEG +-stream. +- +-

    param_file is a parameter file which includes a list of +-input files and other parameters. The file is described in detail +-below. +- +-

    To understand this program, you need to understand something about +-the complex MPEG-1 format. One source of information about this +-standard format is the section Introduction to MPEG in the Compression FAQ. +- +-

    OPTIONS

    +- +-

    The -gop, -combine_gops, -frames, and +--combine_frames options are all mutually exclusive. +- +-

    +-
    -stat stat_file +- +-
    This option causes ppmtompeg to append the statistics that +-it write to Standard Output to the file stat_file as well. The +-statistics use the following abbreviations: bits per block (bpb), bits +-per frame (bpf), seconds per frame (spf), and bits per second (bps). +- +-

    These statistics include how many I, P, and B frames there were, +-and information about compression and quality. +- +- +-

    -quiet num_seconds +- +-
    causes ppmtompeg not to report remaining time more often +-than every num_seconds seconds (unless the time estimate rises, +-which will happen near the beginning of the run). A negative value +-tells ppmtompeg not to report at all. 0 is the default +-(reports once after each frame). Note that the time remaining is an +-estimate and does not take into account time to read in frames. +- +-
    -realquiet
    causes ppmtompeg to run silently, +-with the only screen output being errors. Particularly useful when +-reading input from stdin. The equivalent of the -quiet +-common option of most other Netpbm programs. +- +-
    +--no_frame_summary +- +-
    This option prevents ppmtompeg from printing a summary +-line for each frame +- +-
    -float_dct +- +-
    forces ppmtompeg to use a more accurate, yet more +-computationally expensive version of the DCT. +- +-
    -gop gop_num +-
    +-causes ppmtompeg to encode only the numbered GOP (first GOP is 0). The +-parameter file is the same as for normal usage. The output file will be +-the normal output file with the suffix .gop.gop_num. +-ppmtompeg does not output any sequence information. +- +-
    -combine_gops +- +-
    causes ppmtompeg simply to combine some GOP files into a +-single MPEG output stream. ppmtompeg inserts a sequence header +-and trailer. In this case, the parameter file needs only to contain +-the SIZE value, an output file, and perhaps a list of input GOP +-files (see below). +- +-If you don't supply a list of input GOP files is used, then +-ppmtompeg assumes you're using the same parameter file you used +-when you created the input (with the -gop option) and +-calculates the corresponding gop filenames itself. If this is not the +-case, you can specify input GOP files in the same manner as normal +-input files -- except instead of using INPUT_DIR, INPUT, and +-END_INPUT, use GOP_INPUT_DIR, GOP_INPUT, and GOP_END_INPUT. If no +-input GOP files are specified, then the default is to use the output +-file name with suffix .gop.gop_num, with gop_num +-starting from 0, as the input files. +- +-

    Thus, unless you're mixing and matching GOP files from different +-sources, you can simply use the same parameter file for creating the +-GOP files (-gop) and for later turning them into an MPEG stream +-(-combine_gops). +- +- +-

    -frames first_frame last_frame +- +-
    This option causes ppmtompeg to encode only the frames numbered +-first_frame to last_frame, inclusive. The parameter +-file is the same as for normal usage. The output will be placed in +-separate files, one per frame, with the file names being the normal +-output file name with the suffix .frame.frame_num. No +-GOP header information is output. (Thus, the parameter file need not +-include the GOP_SIZE value) +- +-

    Use ppmtompeg -combine_frames to combine these frames later into +-an MPEG stream. +- +- +-

    -combine_frames +- +-
    This option causes ppmtompeg simply to combine some +-individual MPEG frames (such as you might have created with an earlier +-run of ppmtompeg -frames) into a single MPEG stream. Sequence +-and GOP headers are inserted appropriately. In this case, the +-parameter file needs to contain only the SIZE value, the GOP_SIZE +-value, an output file, and perhaps a list of frame files (see below). +- +-

    The parameter file may specify input frame files in the same manner +-as normal input files -- except instead of using INPUT_DIR, INPUT, and +-END_INPUT, use FRAME_INPUT_DIR, FRAME_INPUT, and FRAME_END_INPUT. If +-no input frame files are specified, then the default is to use the +-output file name with suffix .frame.frame_num, with +-frame_num starting from 0, as the input files. +- +- +- +-

    -nice +- +-
    This option causes ppmtompeg to run any remote processes +-"nicely," i.e. at low priority. (This is relevant only if you are +-running ppmtompeg in parallel mode. Otherwise, there are no +-remote processes). See 'man nice.' +- +-
    -max_machines num_machines +- +-
    This option causes ppmtompeg to use no more than +-num_machines machines as slaves for use in parallel encoding. +- +-
    -snr +- +-
    This option causes ppmtompeg to include the signal-to-noise +-ratio in the reported statistics. Prints SNR (Y U V) and peak SNR (Y +-U V) for each frame. In summary, prints averages of luminance only +-(Y). SNR is defined as 10*log(variance of original/variance of +-error). Peak SNR is defined as 20*log(255/RMSE). Note that +-ppmtompeg runs a little slower when you use this option. +- +-
    -mse +- +-
    This option causes ppmtompeg to report the mean squared +-error per block. It also automatically reports the quality of the +-images, so there is no need to specify -snr then. +- +-
    -bit_rate_info rate_file +- +-
    This option makes ppmtompeg write bit rate information +-into the file rate_file. Bit rate information is bits per frame, and +-also bits per I-frame-to-I-frame. +- +-
    -mv_histogram +- +-
    This option causes ppmtompeg to print a histogram of the +-motion vectors as part of statistics. There are three histograms -- +-one for P frame, one for forward B frame, and one for backward B frame +-motion vectors. +- +-

    The output is in the form of a matrix, each entry corresponding to one +-motion vector in the search window. The center of the matrix +-represents (0,0) motion vectors. +- +-

    -debug_sockets +- +-
    This option causes ppmtompeg to print to Standard Output +-messages that narrate the communication between the machines when you run +-ppmtompeg in parallel mode. +- +-
    -debug_machines +- +-
    This option causes ppmtompeg to print to Standard Output +-messages that narrate the progress of the conversion on the various +-machines when you run ppmtompeg in parallel +-mode. +- +-
    +- +-

    PARAMETER FILE

    +- +-

    The parameter file must contain the following +-lines (except when using the -combine_gops or -combine_frames +-options): +- +-

    +- +-
    PATTERN pattern +- +-
    This statement specifies the pattern (sequence) of I frames, P frames, +-and B frames. pattern is just a sequence of the letters I, P, and +-B with nothing between. Example: +- +-
    +-    PATTERN IBBPBBPBBPBBPBB
    +-
    +- +-

    See I Frames, P Frames, B Frames. +- +-

    OUTPUT output file +-
    This names the file where the output MPEG stream goes. +- +-
    INPUT_DIR directory +- +-
    This statement tells where the input images (frames) come from. +-If each frame is in a separate file, directory is the directory +-where they all are. You may use . to refer to the current +-directory. A null directory refers to the root directory of the +-system file tree. +- +-

    To have ppmtompeg read all the frames serially from Standard +-Input, specify +-

    +-    INPUT_DIR stdin
    +-
    +- +-
    INPUT +-
    +-This line must be followed by a list of the input files (in display order) +-and then the line END_INPUT. +- +-

    There are three types of lines between INPUT and END_INPUT. First, +-a line may simply be the name of an input file. Second, the line +-may be of the form single_star_expr +-[x-y]. +-single_star_expr can have a single * in it. It is +-replaced by all the numbers between x and y inclusive. So, for +-example, the line tennis*.ppm [12-15] refers to the files +-tennis12.ppm, tennis13.ppm, tennis14.ppm, tennis15.ppm. +- +-

    Uniform zero-padding occurs, as well. For example, the line +-football.*.ppm [001-130] refers to the files football.001.ppm, +-football.002.ppm, ..., football.009.ppm, football.010.ppm, ..., +-football.130.ppm. +- +-

    The third type of line is: single_star_expr +-[x-y+s], where the +-line is treated exactly as above, except that we skip by s. Thus, the +-line football.*.ppm [001-130+4] refers to the files +-football.001.ppm, football.005.ppm, football.009.ppm, +-football.013.ppm, etc. +- +-

    Furthermore, a line may specify a shell command to execute to +-generate lines to be interpreted as described above, as if those lines +-were in the parameter file instead. Use back ticks, like in the +-Bourne Shell, like this: +- +-

    +-    `cat myfilelist`
    +-
    +- -

    --This option is valid only along with -patfile. -+right by pixels pixels (default: 0).

    -+ -+

    This option is valid only along with -patfile.

    - --
    -yshift pixels -+
    -yshift pixels
    -
    Shift the pattern image (designated by -patfile) - downwards by pixels pixels (default: 0). This option is --valid only along with -patfile. -+valid only along with -patfile.
    - -
    -yfillshift pixels
    -
    Shift the pattern image (designated by -patfile) downwards -@@ -200,77 +201,77 @@ population of the pattern. (If used wit - shifts are summed.) A small -yfillshift helps reduce visual - artifacts in the 3-D image. Steer's website, referenced under - SEE ALSO, recommends a shift of approximately --1/16" (6–7 pixels at pamstereogram's default of 100 DPI). -+1/16" (6–7 pixels at pamstereogram's default of 100 DPI).
    - --

    This option was new in Netpbm 10.94 (March 2021). -+

    This option was new in Netpbm 10.94 (March 2021).

    - --
    -magnifypat=scale -+
    -magnifypat=scale
    -
    Magnify each pixel in the pattern file or each random dot by - integral scaling factor scale. Note that - pamstereogram applies the pattern magnification - after pattern shifting (-xshift and ---yshift). -+-yshift).
    - --
    -guidebottom -+
    -guidebottom
    -
    - Draw a pair of black squares on a white background underneath the stereogram - proper. These squares help you guide your eyes into proper focus to view the - 3-D image. The trick is to focus your eyes some distance behind the image, - causing you to see four black squares, then continue altering your focus - distance until the middle two black squares fuse into a single black --square. At that point, a crisp, 3-D image will appear. -+square. At that point, a crisp, 3-D image will appear.
    - -

    This option was new in Netpbm 10.61 (December 2012). Before that, - the presence of -guidesize, with a positive value, has the same --effect. -+effect.

    - - --
    -guidetop -+
    -guidetop
    -
    --Same as -guidebottom, except the guides go at the top of the image. -+Same as -guidebottom, except the guides go at the top of the image.
    - -

    This option was new in Netpbm 10.61 (December 2012). Before that, - the presence of -guidesize, with a negative value, has the same --effect. -+effect.

    - --
    -guidesize=pixels -+
    -guidesize=pixels
    - --
    The size (width and height) of each guide box. -+
    The size (width and height) of each guide box.
    - --

    This is valid only with -guidetop or -guidebottom. -+

    This is valid only with -guidetop or -guidebottom.

    - --

    Default is 20. -+

    Default is 20.

    - -

    Before Netpbm 10.61 (December 2012), if you don't specify this option, - pamstereogram draws no guides. If you specify it with a positive - value, pamstereogram behaves as if you specified -guidebottom - too, and if you specify it with a negative value, it behaves as if you - specified -guidetop and specified guidesize with the absolute --value of that negative value. -+value of that negative value.

    - --
    -dpi=resolution -+
    -dpi=resolution
    -
    Specify the resolution of the output device in dots per inch. - The default is 100 DPI, which represents a fairly crisp screen --resolution. -+resolution.
    - --

    Before Netpbm 10.53 (December 2010), the default was 96 DPI. -+

    Before Netpbm 10.53 (December 2010), the default was 96 DPI.

    - - --
    -crosseyed -+
    -crosseyed
    -
    Invert the gray levels in the depth map (input image) so that the 3-D - image pops out of the page where it would otherwise sink into the page and - vice versa. Some people are unable to diverge their eyes and can only cross - them. The -crosseyed option enables such people to see the 3-D image as - intended. You can also specify the -crosseyed option if you prefer - using depth maps in which darker colors are closer to the eye and lighter --colors are farther from the eye. -+colors are farther from the eye.
    - -

    Before Netpbm 10.53 (December 2010), pamstereogram used higher - (lighter) numbers for things closer to the eye without ---crosseyed and vice versa. -+-crosseyed and vice versa.

    - - --
    -makemask -+
    -makemask
    -
    Instead of a stereogram, output a PAM mask image showing - coloring constraints. New pixels will be taken from the pattern - file where the mask is black. Copies of existing pixels will be -@@ -278,30 +279,30 @@ taken from the pattern file where the ma - -makemask option can be used to help create more - sophisticated pattern files (to use with -patfile) Note that - -makemask ignores -magnifypat; it always produces --masks that assume a pattern magnification of 1. -+masks that assume a pattern magnification of 1.
    - --
    -eyesep=inches -+
    -eyesep=inches
    -
    Specify the separation in inches between your eyes. The - default, 2.5 inches (6.4 cm), should be sufficient for most people --and probably doesn't need to be changed. -+and probably doesn't need to be changed.
    - --
    -depth=fraction -+
    -depth=fraction
    -
    Specify the output image's depth of field. That is, - fraction represents the fractional distance of the near - plane from the far plane. Smaller numbers make the 3-D image easier - to perceive but flatter. Larger numbers make the 3-D image more - difficult to perceive but deeper. The default, 0.3333, generally --works fairly well. -+works fairly well.
    - --
    -planes=near_pixels,far_pixels -+
    -planes=near_pixels,far_pixels
    -
    Explicitly specify the distance between repeated pixels in the near plane - and in the far plane. This is an alternative to - -eyesep and -depth. The following equalities hold: - -
      --
    • eyesep = 2 * far -+
    • eyesep = 2 * far
    • -
    • depth = 2 * (farnear) / -- (2 * farnear) -+ (2 * farnear)
    • -
    - -

    The number of distinct 3-D depths is far -@@ -309,34 +310,35 @@ and in the far plane. This is an altern - and -depth are a more human-friendly way to specify stereoscopic - parameters (distance between eyes and tradeoff between perceptibility - and depth) while -planes is a more computer-centric way (pixel --distances in the resulting stereogram). -+distances in the resulting stereogram).

    - --

    This option was new in Netpbm 10.59 (June 2012). -+

    This option was new in Netpbm 10.59 (June 2012).

    -+
    - - --
    -randomseed=integer -+
    -randomseed=integer
    -
    Specify a seed to be used for the random number generator. - The default is to use a seed based on the time of day, to one second --granularity. -+granularity.
    - -

    It is useful to specify the seed if you want to create reproducible - results. With the same random seed, you should get identical results --every time you run pamstereogram. -+every time you run pamstereogram.

    - -

    This is irrelevant if you use a pattern file (-patfile - option), because there is no random element to pamstereogram's --behavior. -+behavior.

    - --

    This option was new in Netpbm 10.32 (February 2006). -+

    This option was new in Netpbm 10.32 (February 2006).

    - --
    -tileable -+
    -tileable
    - -
    Make the generated image horizontally tileable. This works by - blending a left-to-right rendering (the equivalent - of -xbegin=0) with a right-to-left rendering (the equivalent - of -xbegin=width−1). - --

    This option was new in Netpbm 10.91 (June 2020). -+

    This option was new in Netpbm 10.91 (June 2020).

    - -
    - -@@ -345,21 +347,21 @@ of -xbegin=width−1). - -

    The only parameter, infile, is the name of an input file - that is a depth map image. If you don't specify infile, the --input is from standard input. -+input is from standard input.

    - -

    The input is a PAM image of depth 1. Each sample represents the - distance from the eye that the 3-D image at that location should --be. Lower (darker) numbers mean further from the eye. -+be. Lower (darker) numbers mean further from the eye.

    - -

    NOTES

    - -

    Input Images

    - -

    pamstereogram pays no attention to the image's tuple type and --ignores all planes other than plane 0. -+ignores all planes other than plane 0.

    - -

    Like any Netpbm program, pamstereogram will accept PNM --input as if it were the PAM equivalent. -+input as if it were the PAM equivalent.

    - -

    Mapped-texture Stereograms

    - -@@ -367,12 +369,12 @@ input as if it were the PAM equivalent. - drawn with true colors. Unlike a SIRDS or tiled-image SIS, however, - the image portrayed by an MTS is apparent in normal 2-D viewing. It - appears repeated multiple times and overlapped with itself, but it is --not hidden. -+not hidden.

    - -

    You create an MTS with pamstereogram by passing the filename - of a PAM "texture image" with a -texfile option. A - texture image portrays the same 3-D object as the depth-map image but --indicates the colors that the program should apply to the object. -+indicates the colors that the program should apply to the object.

    - -

    pamstereogram ignores the texture image's background color when it - overlaps copies of the 3-D object. This prevents, for example, a bright-red -@@ -382,32 +384,32 @@ object remains bright red. A consequenc - best when the objects in the texture image have a crisp outline. Smooth - transitions to the background color result in unwanted color artifacts around - edges because the program ignores only exact matches with the --background color. -+background color.

    - -

    You should specify a larger-than-normal value for -eyesep - (and/or -dpi) when producing an MTS. Otherwise, the 3-D object will - repeat so many times that most colored pixels will overlap other colored --pixels, reducing the number of true-colored pixels that remain. -+pixels, reducing the number of true-colored pixels that remain.

    - -

    An MTS can employ a background pattern (-patfile). In this - case, pamstereogram replaces background pixels with pattern pixels in --the final step of generating the image. -+the final step of generating the image.

    - - -

    Miscellaneous

    - -

    A good initial test is to input an image consisting of a solid - shape of distance 0 within a large field of maximum distance (e.g., a --white square on a black background). -+white square on a black background).

    - -

    With the default values for -dpi and -eyesep, pattern --images that are 128 pixels wide can tile seamlessly. -+images that are 128 pixels wide can tile seamlessly.

    - - -

    EXAMPLES

    - -

    Generate a SIRDS out of small, brightly colored squares and --prepare it for display on an 87 DPI monitor: -+prepare it for display on an 87 DPI monitor:

    - -
    -     pamstereogram depthmap.pam \
    -@@ -439,21 +441,21 @@ speckles:
    - 
    - 

    SEE ALSO

    - - - -@@ -461,32 +463,32 @@ URL: AUTHOR --

    Copyright © 2006-2020 Scott Pakin, scott+pbm@pakin.org. -+

    Copyright © 2006-2020 Scott Pakin, scott+pbm@pakin.org.

    - -

    Table Of Contents

    -
      +-If input is from Standard Input (per the INPUT_DIR statement), +-ppmtompeg ignores the INPUT/END_INPUT block, but +-it still must be present. +- +-
      BASE_FILE_FORMAT {PPM | PNM | YUV | +- JPEG | JMOVIE} +- +-
      ppmtompeg must convert all input files to one of the +-following formats as a first step of processing: PNM, YUV, JPEG(v4), +-or JMOVIE. (The conversion may be trivial if your input files are +-already in one of these formats). This line specifies which of the +-four formats. PPM is actually a subset of PNM. The separate +-specification is allowed for backward compatibility. Use PNM instead +-of PPM in new applications. +- +-
      INPUT_CONVERT conversion_command +- +-
      You must specify how to convert a file to the base file format. +-If no conversion is necessary, then you would just say: +- +-
      +-     INPUT_CONVERT *
      +-     
      +- +-

      Otherwise, conversion_command is a shell command that causes +-an image in the format your specified with BASE_FILE_FORMAT to +-be written to Standard Output. ppmtompeg executes the command +-once for each line between INPUT and END_INPUT (which is +-normally, but not necessarily, a file name). In the conversion +-command, ppmtompeg replaces each '*' with the contents of that +-line. +- +- If you had a bunch of gif files, you might say: +-

      +-     INPUT_CONVERT giftopnm *
      +-     
      +- +- If you have a bunch of separate a.Y, a.U, and a.V files (where +- the U and V have already been subsampled), then you might say: +- +-
      +-     INPUT_CONVERT cat *.Y *.U *.V
      +-     
      +- +-

      Input conversion is not allowed with input from stdin, so use +- +-

      +-     INPUT_CONVERT *
      +-     
      +- +-as described above. +- +-
      SIZE widthxheight +- +-
      +- +-

      width and height are the width and height of each +-frame in pixels. +- +-

      When ppmtompeg can get this information from the input image +-files, it ignores the SIZE parameter and you may omit it. +- +-

      When the image files are in YUV format, the files don't contain +-dimension information, so SIZE is required. +- +-

      When ppmtompeg is running in parallel mode, not all of the +-processes in the network have access to the image files, so +-SIZE is required and must give the same dimensions as the +-input image files. +- +-

      YUV_SIZE widthxheight +- +-
      This is an obsolete synonym of SIZE. +- +-
      YUV_FORMAT {ABEKAS | PHILLIPS | UCB | +- EYUV | pattern} +- +-
      This is meaningful only when BASE_FILE_FORMAT specifies +-YUV format, and then it is required. It specifies the sub-format of +-the YUV class. +- +- +-
      GOP_SIZE n +- +-
      n is the number of frames in a Group of Pictures. Except that +-because a GOP must start with an I frame, ppmtompeg makes a GOP as +-much longer than n as it has to to make the next GOP start with an +-I frame. +- +-

      Normally, it makes sense to make your GOP size a multiple of your +-pattern length (the latter is determined by the PATTERN parameter file +-statement). +- +-

      See Group Of Pictures. +- +-

      SLICES_PER_FRAME n +-
      n is roughly the number of slices per frame. Note, at +-least one MPEG player may complain if slices do not start at the left +-side of an image. To ensure this does not happen, make sure the +-number of rows is divisible by SLICES_PER_FRAME. +- +-
      PIXEL {FULL | HALF} +- +-
      use half-pixel motion vectors, or just full-pixel ones It is +-usually important that you use half-pixel motion vectors, because it +-results in both better quality and better compression. +- +- +-
      RANGE n +-
      Use a search range of n pixels in each of the four directions +-from a subject pixel. (So the search window is a square n*2 pixels +-on a side). +- +-
      PSEARCH_ALG {EXHAUSTIVE | TWOLEVEL | +- SUBSAMPLE | LOGARITHMIC} +- +-
      This statement tells ppmtompeg what kind of search +- technique (algorithm) to use for P frames. You select the desired +- combination of speed and compression. EXHAUSTIVE gives the +- best compression, but LOGARITHMIC is the fastest. +- TWOLEVEL is an exhaustive full-pixel search, followed by a +- local half- pixel search around the best full-pixel vector (the +- PIXEL option is ignored for this search technique). +- +-
      BSEARCH_ALG {SIMPLE | CROSS2 | EXHAUSTIVE} +- +-
      This statement tells ppmtompeg what kind of search +- technique (algorithm) to use for B frames. SIMPLE means +- find best forward and backward vectors, then interpolate. +- CROSS2 means find those two vectors, then see what backward +- vector best matches the best forward vector, and vice versa. +- EXHAUSTIVE does an n-squared search and is +- extremely slow in relation to the others (CROSS2 +- is about half as fast as SIMPLE). +- +-
      IQSCALE n +-
      Use n as the qscale for I frames. +- See Qscale. +- +-
      PQSCALE n +-
      Use n as the qscale for P frames. +- See Qscale. +- +-
      BQSCALE n +-
      Use n as the qscale for B frames. +- See Qscale. +- +-
      REFERENCE_FRAME {ORIGINAL | DECODED}
      This +-statement determines whether ppmtompeg uses the original images +-or the decoded images when computing motion vectors. Using decoded +-images is more accurate and should increase the playback quality of +-the output, but it makes the encoding take longer and seems to give +-worse compression. It also causes some complications with parallel +-encoding. (see the section on parallel encoding). One thing you can +-do as a trade-off is select ORIGINAL here, and lower the +-qscale (see QSCALE if the quality is not good enough. +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-
      Original or Decoded? (Normalized)
      ReferenceCompressionSpeedQuality IQuality PQuality B
      Decoded100010001000969919
      Original88513731000912884
      +- +- +- +-
    +- +-

    The following lines are optional: +- +-

    +- +-
    FORCE_ENCODE_LAST_FRAME +- +-
    This statement is obsolete. It does nothing. +- +-

    Before Netpbm 10.26 (January 2005), ppmtompeg would drop +-trailing B frames from your movie, since a movie can't end with a B +-frame. (See I Frames, P Frames, B Frames.) +-You would have to specify FORCE_ENCODE_LAST_FRAME to stop +-that from happening and get the same function that ppmtompeg +-has today. +- +- +-

    NIQTABLE +- +-
    This statement specifies a custom non-intra quantization table. +-If you don't specify this statement, ppmtompeg uses a default +-non-intra quantization table. +- +-

    +-The 8 lines immediately following NIQTABLE specify the quantization +-table. Each line defines a table row and consists of 8 integers, +-whitespace-delimited, which define the table columns. +- +-

    IQTABLE +- +-
    This is analogous to NIQTABLE, but for the intra quantization table. +- +-
    ASPECT_RATIO ratio +- +-
    This statement specifies the aspect ratio for ppmtompeg to +-specify in the MPEG output. I'm not sure what this is used for. +- +-

    ratio must be 1.0, 0.6735, 0.7031, 0.7615, 0.8055, 0.8437, +-0.8935, 0.9157, 0.9815, 1.0255, 1.0695, 1.0950, 1.1575, or 1.2015. +- +-

    FRAME_RATE rate +-
    This specifies the frame rate for ppmtompeg to specify in the +-MPEG output. Some players use this value to determine the playback rate. +- +-

    rate must be 23.976, 24, 25, 29.97, 30, 50, 59.94, or 60. +- +-

    BIT_RATE rate +-
    This specifies the bit rate for Constant Bit Rate (CBR) encoding. +- +-

    rate must be an integer. +- +-

    BUFFER_SIZE size +- +-
    This specifies the value +-ppmtompeg is to specify in the MPEG output for the Video +-Buffering Verifier (VBV) buffer size needed to decode the sequence. +- +-

    A Video Verifying Buffer is a buffer in which a decoder keeps the +-decoded bits in order to match the uneven speed of the decoding with +-the required constant playback speed. +- +-

    As ppmtompeg encodes the image, it simulates the decoding +-process in terms of how many bits would be in the VBV as each frame gets +-decoded, assuming a VBV of the size you indicate. +- +-

    If you specify the WARN_VBV_UNDERFLOW statement, +-ppmtompeg issues a warning each time the simulation underflows +-the buffer, which suggests that an underflow would occur on playback, +-which suggests the buffer is too small. +- +-

    If you specify the WARN_VBV_OVERFLOW statement, +-ppmtompeg issues a warning each time the simulation overflows +-the buffer, which suggests that an overflow would occur on playback, +-which suggests the buffer is too small. +- +-

    WARN_VBV_UNDERFLOW +-
    WARN_VBV_OVERFLOW +- +-
    See BUFFER_SIZE. +- +-

    These options were new in Netpbm 10.26 (January 2005). Before that, +-ppmtompeg issued the warnings always. +- +-

    +- +- +-The following statements apply only to parallel operation: +- +-
    +- +-
    PARALLEL +- +-
    This statement, paired with END PARALLEL, is what causes +-ppmtompeg to operate in parallel mode. See Parallel Operation. +- +-
    END PARALLEL +- +-
    This goes with PARALLEL. +- +-
    PARALLEL_TEST_FRAMES n +- +-
    The master starts off by measuring each slave's speed. It does +-this by giving each slave n frames to encode and noting how +-long the slave takes to finish. These are not just test frames, +-though -- they're real frames and the results become part of the +-output. +-ppmtompeg is old and measures time in undivided seconds, so +-to get useful timings, specify enough frames that it will take at +-least 5 seconds to process them. The default is 10. +- +-

    If you specify FORCE_I_ALIGN, ppmtompeg will increase +-the test frames value enough to maintain the alignment. +- +-

    If there aren't enough frames for every slave to have the indicated +-number of test frames, ppmtompeg will give some slaves fewer. +- +- +-

    PARALLEL_TIME_CHUNKS t +- +-
    When you specify this statement, the master attempts to feed work +-to the slaves in chunks that take t seconds to process. It uses +-the speed measurement it made when it started up (see PARALLEL_TEST_FRAMES) +-to decide how many frames to put in the chunk. This statement obviously +-doesn't affect the first batch of work sent to each slave, which is the +-one used to measure the slave's speed. +- +-

    Smaller values of t increase communication, but improve load +-balancing. The default is 30 seconds. +- +-

    You may specify only one of PARALLEL_TIME_CHUNKS, PARALLEL_CHUNK_TAPER, +-and PARALLEL_PERFECT. PARALLEL_CHUNK_TAPER is usually best. +- +-

    PARALLEL_CHUNK_TAPER +- +-
    When you specify this statement, the master distributes work like +-with PARALLEL_TIME_CHUNKS, except that the master chooses the number +-of seconds for the chunks. It starts with a large number and, as it +-gets closer to finishing the job, reduces it. That way, it reduces +-scheduling overhead when precise scheduling isn't helpful, but still +-prevents a slave from finishing early after all the work has already +-been handed out to the other slaves, and then sitting idle while +-there's still work to do. +- +-

    You may specify only one of PARALLEL_TIME_CHUNKS, PARALLEL_CHUNK_TAPER, +-and PARALLEL_PERFECT. PARALLEL_CHUNK_TAPER is usually best. +- +- +-

    PARALLEL_PERFECT +- +-
    If this statement is present, ppmtompeg schedules on the +-assumption that each machine is about the same speed. The master will +-simply divide up the frames evenly between the slaves -- each +-slave gets the same number of frames. If some slaves are faster than +-others, they will finish first and remain idle while the slower slaves +-continue. +- +-

    This has the advantage of minimal scheduling overhead. Where slaves +-have different speeds, though, it makes inefficient use of the fast +-ones. Where slaves are the same speed, it also has the disadvantage +-that they all finish at the same time and feed their output to the +-single Combine Server in a burst, which makes less efficient use of +-the Combine Server and thus can increase the total elapsed time. +- +-

    You may specify only one of PARALLEL_TIME_CHUNKS, PARALLEL_CHUNK_TAPER, +-and PARALLEL_PERFECT. PARALLEL_CHUNK_TAPER is usually best. +- +-

    RSH remote_shell_command +- +-
    ppmtompeg executes the shell command +-remote_shell_command to start a process on another machine. +-The default command is rsh, and whatever command you specify +-must have compatible semantics. ssh is usually compatible. +-The command ppmtompeg uses is one like this: +-ssh remote.host.com -l username shellcommand. +- +-

    Be sure to set up .rhosts files or SSH key authorizations +-where needed. Otherwise, you'll have to type in passwords. +- +-

    On some HP machines, rsh is the restricted shell, and you want +-to specify remsh. +- +-

    FORCE_I_ALIGN +- +-
    This statement forces each slave to encode a chunk of frames which +-is a multiple of the pattern length (see PATTERN). Since the +-first frame in any pattern is an I frame, this forces each chunk +-encoded by a slave to begin with an I frame. +- +-

    This document used to say there was an argument to +-FORCE_I_ALIGN which was the number of frames ppmtompeg +-would use (and was required to be a multiple of the pattern length). +-But ppmtompeg has apparently always ignored that argument, and +-it does now. +- +-

    KEEP_TEMP_FILES +- +-
    This statement causes ppmtompeg not to delete the temporary +-files it uses to transmit encoded frames to the combine server. This +-means you will be left with a file for each frame, the same as you +-would get with the -frames option. +- +-

    This is mostly useful for debugging. +- +-

    This works only if you're using a shared filesystem to communicate +-between the servers. +- +-

    This option was new in Netpbm 10.26 (January 2005). +- +-

    +- +- +-

    Parameter File Notes

    +- +-

    If you use the -combine_gops option, then you need to specify +-only the SIZE and OUTPUT values in the parameter file. In +-addition, the parameter file may specify input GOP files in the same +-manner as normal input files -- except instead of using INPUT_DIR, +-INPUT, and END_INPUT, use GOP_INPUT_DIR, GOP_INPUT, and GOP_END_INPUT. +-If you specify no input GOP files, then ppmtompeg uses by default the +-output file name with suffix .gop.gop_num, with gop_num +-starting from 0, as the input files. +- +-

    If you use the -combine_frames option, then you need to +-specify only the SIZE, GOP_SIZE, and OUTPUT values in the +-parameter file. In addition, the parameter file may specify input +-frame files in the same manner as normal input files -- except instead +-of using INPUT_DIR, INPUT, and END_INPUT, use FRAME_INPUT_DIR, +-FRAME_INPUT, and FRAME_END_INPUT. If no input frame files are +-specified, then the default is to use the output file name with suffix +-.frame.frame_num, with frame_num starting from 0, +-as the input files. +- +-

    Any number of spaces and tabs may come between each option and value. Lines +-beginning with # are ignored. Any other lines are ignored except for +-those between INPUT and END_INPUT. This allows you to use the same +-parameter file for normal usage and for -combine_gops and +--combine_frames. +- +-

    The file format is case-sensitive so all keywords should be in +-upper case. +- +-

    The statements may appear in any order, except that the order within +-a block statement (such as INPUT ... END INPUT) is significant. +- +-

    ppmtompeg is prepared to handle up to 16 B frames between +-reference frames when encoding with input from stdin. (To build a +-modified ppmtompeg with a higher limit, change the constant +-B_FRAME_RUN in frame.c and recompile). +- +-

    GENERAL USAGE INFORMATION

    +- +-

    Qscale

    +- +-

    The quantization scale values (qscale) give a trade-off between +-quality and compression. Using different Qscale values has very little +-effect on speed. The qscale values can be set separately for I, P, and +-B frames. +- +-

    You select the qscale values with the IQSCALE, +-PQSCALE, and BSCALE parameter file statements. +- +-

    A qscale value is an integer from 1 to 31. Larger numbers give +-better compression, but worse quality. In the following, the quality +-numbers are peak signal-to-noise ratio, defined as: +-signal-to-noise formula +-where MSE is the mean squared error. +- +- +-

    Flower garden tests: +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-
    Qscale vs Quality
    QscaleI FramesP FramesB Frames
    143.246.346.5
    632.634.634.3
    1128.629.530.0
    1626.326.828.6
    2124.725.027.9
    2623.523.927.5
    3122.623.027.3
    +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-
    Qscale vs Compression
    QscaleI FramesP FramesB Frames
    1222
    671015
    11111843
    16152997
    211941173
    262456256
    312873330
    +- +- +-

    Search Techniques

    +- +-

    There are several different motion vector search techniques +-available. There are different techniques available for P frame +-search and B frame search. Using different search techniques present +-little difference in quality, but a large difference in compression +-and speed. +- +-

    There are 4 types of P frame search: Exhaustive, TwoLevel, +-SubSample, and Logarithmic. +- +-

    There are 3 types of B frame search: Exhaustive, Cross2, and +-Simple. +- +-The recommended search techniques are TwoLevel and Logarithmic for +-P frame search, and Cross2 and Simple for B frame search. Here are +-some numbers comparing the different search methods: +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-
    P frame Motion Vector Search (Normalized)
    TechniqueCompression1Speed 2Quality 3
    Exhaustive100010001000
    SubSample100824561000
    TwoLevel100932371000
    Logarithmic10858229998
    +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-
    B frame Motion Vector Search (Normalized)
    TechniqueCompression1Speed2Quality3
    Exhaustive100010001000
    Cross29751000996
    Simple9381765991
    +- +- 1Smaller numbers are better +-compression. +- +- 2Larger numbers mean faster +-execution. +- +- 3Larger numbers mean better quality. +- +-

    For some reason, Simple seems to give better compression, but it +-depends on the image sequence. +- +-

    Select the search techniques with the PSEARCH_ALG and +-BSEARCH_ALG parameter file statements. +- +- +-

    Group Of Pictures (GOP)

    +- +-

    A Group of Pictures (GOP) is a roughly independently decodable +-sequence of frames. An MPEG video stream is made of one or more +-GOP's. You may specify how many frames should be in each GOP with the +-GOP_SIZE parameter file statement. A GOP always starts with an +-I frame. +- +-

    Instead of encoding an entire sequence, you can encode a single +-GOP. To do this, use the -gop command option. You can later +-join the resulting GOP files at any time by running ppmtompeg +-with the -combine_gops command option. +- +- +-

    Slices

    +- +-

    A slice is an independently decodable unit in a frame. It can be +-as small as one macroblock, or it can be as big as the entire frame. +-Barring transmission error, adding slices does not change quality or +-speed; the only effect is slightly worse compression. More slices are +-used for noisy transmission so that errors are more recoverable. Since +-usually errors are not such a problem, we usually just use one slice +-per frame. +- +-

    Control the slice size with the SLICES_PER_FRAME parameter +-file statement. +- +-

    Some MPEG playback systems require that each slice consist of whole +-rows of macroblocks. If you are encoding for this kind of player, if +-the height of the image is H pixels, then you should set the +-SLICES_PER_FRAME to some number which divides H/16. For example, if +-the image is 240 pixels (15 macroblocks) high, then you should use +-only 15, 5, 3, or 1 slices per frame. +- +-

    Note: these MPEG playback systems are really wrong, since the MPEG +-standard says this doesn't have to be so. +- +- +- +-

    Search Window

    +- +-

    The search window is the window in which ppmtompeg searches +-for motion vectors. The window is a square. You can specify the size +-of the square, and whether to allow half-pixel motion vectors or not, +-with the RANGE and PIXEL parameter file statements. +- +-

    I Frames, P Frames, B Frames

    +- +-

    In MPEG-1, a movie is represented as a sequence of MPEG frames, +-each of which is an I Frame, a P Frame, or a B Frame. Each represents +-an actual frame of the movie (don't get confused by the dual use of +-the word "frame." A movie frame is a graphical image. An MPEG frame +-is a set of data that describes a movie frame). +- +-

    An I frame ("intra" frame) describes a movie frame in isolation -- +-without respect to any other frame in the movie. A P frame +-("predictive" frame) describes a movie frame by describing how it +-differs from the movie frame described by the latest preceding I or +-P frame. A B frame ("bidirectional" frame) describes a movie frame by +-describing how it differs from the movie frames described by the +-nearest I or P frame before and after it. +- +-

    Note that the first frame of a movie must be described by an I +-frame (because there is no previous movie frame) and the last movie +-frame must be described by an I or P frame (because there is no +-subsequent movie frame). +- +-

    Beyond that, you can choose which frames are represented by which +-types. You specify a pattern, such as IBPBP and ppmtompeg +-simply repeats it over and over throughout the movie. The pattern +-affects speed, quality, and stream size. Here is a chart which shows +-some of the trade-offs: +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-
    Comparison of I/P/B Frames (Normalized)
    Frame TypeSizeSpeedQuality
    I frames100010001000
    P frames409609969
    B frames72260919
    +- +-(this is with constant qscale) +- +-

    A standard sequence is IBBPBBPBBPBBPBB. +- +-

    Select the sequence with the PATTERN parameter file statement. +- +-

    Since the last MPEG frame cannot be a B frame (see above), if the +-pattern you specify indicates a B frame for the last movie frame of +-the movie, ppmtompeg makes it an I frame instead. +- +-

    Before Netpbm 10.26 (January 2005), ppmtompeg instead drops +-the trailing B frames by default, and you need the +-FORCE_ENCODE_LAST_FRAME parameter file statement to make it do +-this. +- +-

    The MPEG frames don't appear in the MPEG-1 stream in the same order that +-the corresponding movie frames appear in the movie -- the B frames come after +-the I and P frames on which they are based. For example, if the movie is +-4 frames that you will represent with the pattern IBBP, the MPEG-1 stream +-will start with an I frame describing movie frame 0. The next frame in +-the MPEG-1 stream is a P frame describing movie frame 3. The last two +-frames in the MPEG-1 stream are B frames describing movie frames 1 and 2, +-respectively. +- +- +-

    Specifying Input and Output Files

    +- +-

    Specify the input frame images with the INPUT_DIR, +-INPUT, END_INPUT, BASE_FILE_FORMAT, +-SIZE, YUV_FORMAT and INPUT_CONVERT parameter +-file statements. +- +-

    Specify the output file with the OUTPUT parameter file statement. +- +- +-

    Statistics

    +- +-

    ppmtompeg can generate a variety of statistics about the +-encoding. See the -stat, -snr, -mv_histogram, +--quiet, -no_frame_summary, and -bit_rate_info +-options. +- +- +-

    PARALLEL OPERATION

    +- +-

    You can run ppmtompeg on multiple machines at once, encoding +-the same MPEG stream. When you do, the machines are used as shown in +-the following diagram. We call this "parallel mode." +- +-

    ppmtompeg-par.gif +- +-

    To do parallel processing, put the statement +- +-

    +-    PARALLEL
    +-
    +- +-in the parameter file, followed by a listing of the machines, one +-machine per line, then +- +-
    +-    END_PARALLEL
    +-
    +- +-Each of the machine lines must be in one of two forms. If the machine +-has filesystem access to the input files, then the line is: +- +-

    +-machine user executable +- +-

    The executable is normally ppmtompeg (you may need to give +-the complete path if you've built for different architectures). If +-the machine does not have filesystem access to the input files, the line +-is: +- +-

    REMOTE machine user executable +-parameter file +- +-

    The -max_machines command option limits the number of +-machines ppmtompeg will use. If you specify more machines in +-the parameter file than -max_machines allows, ppmtompeg +-uses only the machines listed first. This is handy if you want to +-experiment with different amounts of parallelism. +- +-

    In general, you should use full path file names when describing +-executables and parameter files. This includes the parameter +-file argument on the original invocation of ppmtompeg. +- +-

    All file names must be the same on all systems (so if e.g. you're +-using an NFS filesystem, you must make sure it is mounted at the same +-mountpoint on all systems). +- +-

    Because not all of the processes involved in parallel operation +-have easy access to the input files, you must specify the SIZE +-parameter file statement when you do parallel operation. +- +-

    The machine on which you originally invoke ppmtompeg is the +-master machine. It hosts a "combine server,", a +-"decode server," and a number of "i/o servers," +-all as separate processes. The other machines in the network (listed +-in the parameter file) are slave machines. Each hosts a single +-process that continuously requests work from the master and does it. +-The slave process does the computation to encode MPEG frames. It +-processes frames in batches identified by the master. +- +-

    The master uses a remote shell command to start a process on a +-slave machine. By default, it uses an rsh shell command to do +-this. But use the RSH parameter file statement to control +-this. The shell command the master executes remotely is +-ppmtompeg, but with options to indicate that it is to perform +-slave functions. +- +-

    The various machines talk to each other over TCP connections. Each +-machine finds and binds to a free TCP port number and tells its +-partners the port number. These port numbers are at least 2048. +- +-

    Use the PARALLEL_TEST_FRAMES, PARALLEL_TIME_CHUNKS, and +-PARALLEL_PERFECT parameter file statements to control the way the +-master divides up work among the slaves. +- +-

    Use the -nice command option to cause all slave processes to run +-"nicely," i.e. as low priority processes. That way, this substantial and +-long-running CPU load will have minimal impact on other, possibly +-interactive, users of the systems. +- +-

    SPEED

    +- +-

    Here is a look at ppmtompeg speed, in single-node (not parallel) +-operation: +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-
    Compression Speed
    Machine TypeMacroblocks per second1
    HP 9000/755280
    DEC 3000/400247
    HP 9000/750191
    Sparc 10104
    DEC 500068
    +-1A macroblock is a 16x16 pixel square +- +-

    The measurements in the table are with inputs and outputs via a +-conventional locally attached filesystem. If you are using a network +-filesystem over a single 10 MB/s Ethernet, that constrains your speed more +-than your CPU speed. In that case, don't expect to get better than 4 +-or 5 frames per second no matter how fast your CPUs are. +- +-

    Network speed is even more of a bottleneck when the slaves do not +-have filesystem access to the input files -- i.e. you declare them +-REMOTE. +- +-

    Where I/O is the bottleneck, size of the input frames can make a big +-difference. So YUV input is better than PPM, and JPEG is better than +-both. +- +-

    When you're first trying to get parallel mode working, be sure to +-use the -debug_machines option so you can see what's going on. +-Also, -debug_sockets can help you diagnose communication +-problems. +- +- +-

    AUTHORS

    +- +- +- +-
    +-

    Table Of Contents

    +- - - +-
  • PARAMETER FILE +- +-
  • GENERAL USAGE INFORMATION +- +-
  • PARALLEL OPERATION +-
  • SPEED +-
  • AUTHORS +- +- +- +Binární soubory a/userguide/.pamgradient.html.swp a b/userguide/.pamgradient.html.swp jsou rozdílné diff -urNp a/userguide/pamhomography.html b/userguide/pamhomography.html ---- a/userguide/pamhomography.html 2021-01-26 15:19:07.403345047 +0100 -+++ b/userguide/pamhomography.html 2021-01-26 15:29:36.659652764 +0100 -@@ -9,7 +9,7 @@ - +--- a/userguide/pamhomography.html 2021-06-02 21:32:17.861061500 +0200 ++++ b/userguide/pamhomography.html 2021-06-02 21:43:06.846140198 +0200 +@@ -1,15 +1,7 @@ + +- +- +-pamhomography +- +- +- +- +- ++Pamhomography User Manual - +- -

    pamhomography

    +

    pamhomography

    Updated: 03 January 2021
    -@@ -29,7 +29,7 @@ Updated: 03 January 2021 - [-mapfile=map_file] - [-view=coords] - [-fill=color] -- [pam_file] -+ [pam_file

    ] - -

    You can abbreviate any option to its shortest unique prefix. You can use - two hyphens instead of one to delimit an option. You can separate an option -@@ -42,7 +42,7 @@ from its value with whitespace instead o - of Netpbm.

    - -

    pamhomography transforms a quadrilateral—not necessarily --rectangular—region of an image, producing a new image. -+rectangular—region of an image, producing a new image.

    - -

    You can do any - affine image transformation: translation, reflection, scaling, -@@ -111,9 +111,9 @@ quadrilateral.

    -

    This is the color with which the program fills all pixels that lie outside - of the target quadrilateral. Specify the color as described for the - --argument of the pnm_parsecolor() library routine. -+argument of the pnm_parsecolor() library routine.

    - --

    The default is black, and for images with a transparency plane, transparent. -+

    The default is black, and for images with a transparency plane, transparent.

    - - -
  • -@@ -132,7 +132,7 @@ by map_file.

    - -

    pamhomography's only parameter, pam_file, is the name of the - file containing the input image. If you don't specify pam_file, the -- image comes from Standard Input. -+ image comes from Standard Input.

    - - -

    NOTES

    -@@ -260,23 +260,23 @@ preceding examples:

    -

    SEE ALSO

    - - +@@ -17,8 +9,7 @@ Updated: 03 January 2021 -

    SEE ALSO

    - --

    pamhomography was new in Netpbm 10.94 (March 2021). -+

    pamhomography was new in Netpbm 10.94 (March 2021).

    - - -

    AUTHOR

    -diff -urNp a/userguide/pamhomography.1 b/userguide/pamhomography.1 ---- a/userguide/pamhomography.1 1970-01-01 01:00:00.000000000 +0100 -+++ b/userguide/pamhomography.1 2021-01-26 15:23:06.759944223 +0100 -@@ -0,0 +1,407 @@ -+\ -+.\" This man page was generated by the Netpbm tool 'makeman' from HTML source. -+.\" Do not hand-hack it! If you have bug fixes or improvements, please find -+.\" the corresponding HTML page on the Netpbm website, generate a patch -+.\" against that, and send it to the Netpbm maintainer. -+.TH "pamhomography" 1 "03 January 2021" "netpbm documentation" -+ -+ -+ -+ -+ -+ -+.UN NAME -+.SH NAME -+.PP +

    NAME

    +- +-

    pamhomography - map one arbitrary quadrilateral image region to another

    +pamhomography - map one arbitrary quadrilateral image region to another -+ -+ -+.UN SYNOPSIS -+.SH SYNOPSIS -+.PP -+\fBpamhomography\fP -+ [\fB-from\fP=\fIcoords\fP] -+ [\fB-to\fP=\fIcoords\fP] -+ [\fB-mapfile\fP=\fImap_file\fP] -+ [\fB-view\fP=\fIcoords\fP] -+ [\fB-fill\fP=\fIcolor\fP] -+ [\fIpam_file\fP] -+.PP -+You can abbreviate any option to its shortest unique prefix. You can use -+two hyphens instead of one to delimit an option. You can separate an option -+from its value with whitespace instead of \f(CW=\fP. -+ -+ -+.UN DESCRIPTION -+.SH DESCRIPTION -+.PP -+This program is part -+of -+.UR http://netpbm.sourceforge.net/ -+Netpbm -+.UE -+\&. -+.PP -+\fBpamhomography\fP transforms a quadrilateral-not necessarily -+rectangular-region of an image, producing a new image. -+.PP -+You can do any -+.UR https://en.wikipedia.org/wiki/Affine_transformation#Image_transformation -+affine image transformation -+.UE -+\&: translation, reflection, scaling, -+rotation, and shearing/skewing. However, \fBpamhomography\fP additionally can -+do \fIbilinear\fP transforms, which means it can warp any quadrilateral to any -+other quadrilateral, even when this mapping cannot be described using a single -+set of linear equations. This can be useful, for example, for creating -+perspective views of rectangular images or for reverse-mapping a perspective -+view back to a rectangular projection. -+ -+ -+.UN OPTIONS -+.SH OPTIONS -+.PP -+In addition to the options common to all programs based on libnetpbm (most -+notably \fB-quiet\fP, see -+.UR http://index.html#commonoptions -+Common Options -+.UE -+\&), \fBpamhomography\fP recognizes the following command line -+options: -+ -+ -+ -+
    \fB-from\fP=\fIcoords\fP -+.sp -+This defines the source quadrilateral. \fIcoords\fP is a list of four -+ integer-valued (\fIx\fP, \fIy\fP) coordinates. If you do not -+ specify \fB-from\fP, the source quadrilateral is taken to be the four -+ corners of the input image in clockwise order, starting from the upper -+ left. -+ -+ -+
    \fB-to\fP=\fIcoords\fP -+.sp -+This defines the target quadrilateral. \fIcoords\fP is a list of four -+integer-valued (\fIx\fP, \fIy\fP) coordinates. If you do not -+specify \fB-to\fP, the target quadrilateral is taken to be the four corners -+of the input image in clockwise order, starting from the upper left. -+ -+ -+
    \fB-mapfile\fP=\fImap_file\fP -+.sp -+This names a text file that describes the mapping from the source to the -+target quadrilateral. The file \fImap_file\fP must contain either eight -+integer-valued (\fIx\fP, \fIy\fP) coordinates, being the four source -+coordinates followed by the corresponding four target coordinates, or only -+four (\fIx\fP, \fIy\fP) coordinates, being only the four target -+coordinates. In the latter case, the source quadrilateral is taken to be the -+four corners of the input image in clockwise order, starting from the upper -+left. -+ -+ -+
    \fB-view\fP=\fIcoords\fP -+.sp -+This defines the target view. \fIcoords\fP is a list of two integer-valued -+(\fIx\fP, \fIy\fP) coordinates: the upper left and lower right boundaries, -+respectively, of the pixels that will be visible in the output image. If -+\fB-view\fP is not specified, the target view will fit precisely the target -+quadrilateral. -+ -+ -+
    \fB-fill\fP=\fIcolor\fP -+.sp -+This is the color with which the program fills all pixels that lie outside -+of the target quadrilateral. Specify the color as described for the -+.UR http://libnetpbm_image.html#colorname -+ argument of the pnm_parsecolor() library routine -+.UE -+\&. -+.sp -+The default is black, and for images with a transparency plane, transparent. -+ -+ -+ -+.PP -+Cooordinates should normally be specified in clockwise order. The syntax is -+fairly flexible: all characters other than the plus sign, minus sign, and -+digits are treated as separators. Although coordinates need to be integers, -+they may lie outside the image's boundary. -+.PP -+If you specify \fB-mapfile\fP along with \fB-from\fP and/or \fB-to\fP, -+\fB-from\fP and \fB-to\fP override the quadrilaterals specified -+by \fImap_file\fP. -+ -+ -+.UN PARAMETERS -+.SH PARAMETERS -+.PP -+\fBpamhomography\fP's only parameter, \fIpam_file\fP, is the name of the -+ file containing the input image. If you don't specify \fIpam_file\fP, the -+ image comes from Standard Input. -+ -+ -+.UN NOTES -+.SH NOTES -+.PP -+The output image uses the same Netpbm format as the input image. -+.PP -+Simple transformations are best handled by other Netpbm programs, such as -+those listed in the -+.UR #SEE-ALSO -+\&'SEE ALSO' -+.UE -+\& section -+below. Use \fBpamhomography\fP for more sophisticated transformations such as -+perspective adjustments, rotations around an arbitrary point in the image, -+extraction of non-rectangular quadrilaterals, shearings by coordinates rather -+than by angle, and, in general, all transformations that are most easily -+expressed as mapping four points in one image to four points in another -+image. -+ -+.UN EXAMPLES -+.SH EXAMPLES -+.PP -+The following examples use the -+.UR park_row.ppm -+park_row.ppm -+.UE -+\& test image, which is a -+.UR https://commons.wikimedia.org/wiki/File:15_Park_Row_3.JPG -+ photograph of New York City's Park Row Building -+.UE -+\&, scaled to -+441×640, converted to a PPM file, and redistributed under the terms of -+the -+.UR https://en.wikipedia.org/wiki/GNU_Free_Documentation_License -+ GFDL -+.UE -+\&. -+.PP -+The first example showcases the real power of bilinear transformations. -+Assuming \fIpark_row_rect.map\fP has the following contents: -+ -+.nf\f(CW (147, 51) (316, 105) (402, 595) (92, 560) -+ (0, 0) (440, 0) (440, 639) (0, 639)\fP
    -+.PP -+then -+ -+.nf\f(CW pamhomography -mapfile park_row_rect.map park_row.ppm > park_row_rect.ppm\fP -+.PP -+projects the building's facade from a perspective view to a rectilinear -+front-on view. Remember that \fBpamhomography\fP ignores the parentheses and -+commas used in \fIpark_row_rect.map\fP; they merely make the file more -+human-readable. We equivalently could have written -+ -+.nf\f(CW 147 51 316 105 402 595 92 560 0 0 440 0 440 639 0 639\fP -+.PP -+or any of myriad other variations. -+.PP -+\fBpamhomography\fP can warp the image to a trapezoid to make it look like -+it's leaning backwards in 3-D: -+ -+.nf\f(CW pamhomography -to '50,0 390,0 440,200 0,200' park_row.ppm > park_row_trap.ppm\fP -+.PP -+As a very simple example, -+ -+.nf\f(CW pamhomography -to '440,0 0,0 0,639 440,639' park_row.ppm > park_row_flip.ppm\fP -+.PP -+flips the image left-to-right. Note that in this case the target -+quadrilateral's coordinates are listed in counterclockwise order because -+that represents the correspondence between points (0, 0) ↔ (440, 0) and -+(0, 639) ↔ (639, 0). -+.PP -+Scaling is also straightforward. The following command scales down the -+image from 441×640 to 341×540: -+ -+.nf\f(CW pamhomography -to '0,0 340,0 340,539 0,539' park_row.ppm > park_row_small.ppm\fP -+.PP -+Let's add 100 pixels of tan border to the above. We use \fB-view\fP and -+\fB-fill\fP to accomplish that task: -+ -+.nf\f(CW pamhomography -to '0,0 340,0 340,539 0,539' -view '-100,-100 440,639' -fill tan park_row.ppm > park_row_small_border.ppm\fP -+.PP -+We can add a border without having to scale the image: -+ -+.nf\f(CW pamhomography -view '-100,-100 540,739' -fill tan park_row.ppm > park_row_border.ppm\fP -+.PP -+The \fB-view\fP option can also be used to extract a rectangle out of an -+image, discarding the rest of the image: -+ -+.nf\f(CW pamhomography -view '130,10 205,80' park_row.ppm > park_row_cut.ppm\fP -+.PP -+Specifying the same set of coordinates to \fB-from\fP and \fB-to\fP has -+the same effect but also allows you to extract non-rectangular quadrilaterals -+from an image: -+ -+.nf\f(CW pamhomography -from '185,300 310,325 320,425 180,405' -to '185,300 310,325 320,425 180,405' park_row.ppm > park_row_cut_2.ppm\fP -+.PP -+Rotation is doable but takes some effort. The challenge is that you need to -+compute the rotated coordinates yourself. The matrix expression to rotate -+points \e((x_1, y_1)\e) \e((x_2, y_2)\e), \e((x_3, y_3)\e), and \e((x_4, y_4)\e) -+clockwise by \e(\etheta\e) degrees around point \e((c_x, c_y)\e) is -+.PP -+\e[ \ebegin{bmatrix} 1 & 0 & c_x \e\e 0 & 1 & c_y \e\e 0 & 0 -+& 1 \eend{bmatrix} \ebegin{bmatrix} \ecos \etheta & -\esin \etheta & 0 -+\e\e \esin \etheta & \ecos \etheta & 0 \e\e 0 & 0 & 1 \eend{bmatrix} -+\ebegin{bmatrix} 1 & 0 & -c_x \e\e 0 & 1 & -c_y \e\e 0 & 0 -+& 1 \eend{bmatrix} \ebegin{bmatrix} x_1 & x_2 & x_3 & x_4 \e\e y_1 -+& y_2 & y_3 & y_4 \e\e 1 & 1 & 1 & 1 \eend{bmatrix} -+\equad. \e] -+.PP -+For example, to rotate \fIpark_row.ppm\fP 30° clockwise around (220, -+320) you would compute -+.PP -+\e[ \ebegin{bmatrix} 1 & 0 & 220 \e\e 0 & 1 & 320 \e\e 0 & 0 -+& 1 \eend{bmatrix} \ebegin{bmatrix} \ecos 30^{\ecirc} & -\esin 30^{\ecirc} -+& 0 \e\e \esin 30^{\ecirc} & \ecos 30^{\ecirc} & 0 \e\e 0 & 0 & 1 -+\eend{bmatrix} \ebegin{bmatrix} 1 & 0 & -220 \e\e 0 & 1 & -320 \e\e -+0 & 0 & 1 \eend{bmatrix} \ebegin{bmatrix} 0 & 440 & 440 & 0 -+\e\e 0 & 0 & 639 & 639 \e\e 1 & 1 & 1 & 1 \eend{bmatrix} = -+\ebegin{bmatrix} 189.4744 & 570.5256 & 251.0256 & -130.0256 \e\e -+-67.1281 & 152.8719 & 706.2621 & 486.2621 \e\e 1.0000 & 1.0000 -+& 1.0000 & 1.0000 \eend{bmatrix} \equad, \e] -+.PP -+round these coordinates to integers, transpose the matrix, and produce the -+following map file, \fIpark_row_rot30.map\fP: -+ -+.nf\f(CW 189 -67 -+ 571 153 -+ 251 706 -+ -130 486\fP -+.PP -+(These are the 'to' coordinates; we use the default, full-image -+\&'from' coordinates.) The mapping then works as in all of the -+preceding examples: -+ -+.nf\f(CW pamhomography -mapfile park_row_rot30.map park_row.ppm > park_row_rot30.ppm\fP -+ -+ -+.UN SEE-ALSO -+.SH SEE ALSO -+ -+ -+.IP \(bu -+ -+.BR "pamcut" (1)\c -+\& -+.IP \(bu -+ -+.BR "pamenlarge" (1)\c -+\& -+.IP \(bu -+ -+.BR "pamflip" (1)\c -+\& -+.IP \(bu -+ -+.BR "pamperspective" (1)\c -+\& -+.IP \(bu -+ -+.BR "pamscale" (1)\c -+\& -+.IP \(bu -+ -+.BR "pamstretch" (1)\c -+\& -+.IP \(bu -+ -+.BR "pam" (1)\c -+\& -+.IP \(bu -+ -+.BR "pnmmargin" (1)\c -+\& -+.IP \(bu -+ -+.BR "pnmpad" (1)\c -+\& -+.IP \(bu -+ -+.BR "pnmrotate" (1)\c -+\& -+.IP \(bu -+ -+.BR "pnmshear" (1)\c -+\& -+ -+ -+ -+.UN SEE-ALSO -+.SH SEE ALSO -+.PP -+\fBpamhomography\fP was new in Netpbm 10.94 (March 2021). -+ -+ -+.UN AUTHOR -+.SH AUTHOR -+.PP -+Copyright \(co 2020 Scott -+Pakin, \fIscott+pbm@pakin.org\fP -+ -+ -+.UN index -+.SH Table of Contents -+ -+ -+.IP \(bu -+ -+.UR #SYNOPSIS -+SYNOPSIS -+.UE -+\& -+.IP \(bu -+ -+.UR #DESCRIPTION -+DESCRIPTION -+.UE -+\& -+.IP \(bu -+ -+.UR #OPTIONS -+OPTIONS -+.UE -+\& -+.IP \(bu -+ -+.UR #PARAMETERS -+PARAMETERS -+.UE -+\& -+.IP \(bu -+ -+.UR #NOTES -+NOTES -+.UE -+\& -+.IP \(bu -+ -+.UR #EXAMPLES -+EXAMPLES -+.UE -+\& -+.IP \(bu -+ -+.UR #SEE-ALSO -+SEE ALSO -+.UE -+\& -+.IP \(bu -+ -+.UR #HISTORY -+HISTORY -+.UE -+\& -+.IP \(bu -+ -+.UR #AUTHOR -+AUTHOR -+.UE -+\& -+.SH DOCUMENT SOURCE -+This manual page was generated by the Netpbm tool 'makeman' from HTML -+source. The master documentation is at -+.IP -+.B http://netpbm.sourceforge.net/doc/pamhomography.html -+.PP -\ Chybí znak konce řádku na konci souboru + + +

    SYNOPSIS

    diff --git a/netpbm-manual-pages.patch b/netpbm-manual-pages.patch deleted file mode 100644 index df35cbb..0000000 --- a/netpbm-manual-pages.patch +++ /dev/null @@ -1,1348 +0,0 @@ -diff --git a/userguide/libnetpbm_ug.html b/userguide/libnetpbm_ug.html -index 92df98a..60ccc88 100644 ---- a/userguide/libnetpbm_ug.html -+++ b/userguide/libnetpbm_ug.html -@@ -374,7 +374,7 @@ plain format. -

    Reference

    - -

    The Libnetpbm Netpbm Image --Processing Manual describes the the libnetpbm functions for -+Processing Manual describes the libnetpbm functions for - processing image data. - -

    The Libnetpbm Utility Manual -diff --git a/userguide/pamfunc.html b/userguide/pamfunc.html -index 60d53d6..80f90f2 100644 ---- a/userguide/pamfunc.html -+++ b/userguide/pamfunc.html -@@ -60,7 +60,7 @@ output image. - and bit string (such as and with 01001000). For the arithmetic functions, the - function arguments and results are the fraction that a sample is of the - maxval, i.e. normal interpretation of PAM tuples. But for the bit string --functions, the value is the the bit string whose value as a binary cipher is -+functions, the value is the bit string whose value as a binary cipher is - the sample value, and the maxval indicates the width of the bit string. - -

    Arithmetic functions

    -diff --git a/userguide/pbmtog3.html b/userguide/pbmtog3.html -index 88de765..4590a17 100644 ---- a/userguide/pbmtog3.html -+++ b/userguide/pbmtog3.html -@@ -36,7 +36,7 @@ use those encodings. -

    In addition to the options common to all programs based on libnetpbm - (most notably -quiet, see - Common Options), pbmtog3 recognizes the following --command line options: -+command line options:

    - -
    -
    -reversebits -@@ -80,7 +80,7 @@ You cannot specify both. -

    HISTORY

    - -

    Before Netpbm 10.79 (June 2017), there was a different program by the same --name in Netpbm, which was written by by Paul Haeberli -+name in Netpbm, which was written by Paul Haeberli - <paul@manray.sgi.com> in 1989 - and then modified extensively by others. - -diff --git a/userguide/ppmtompeg.html b/userguide/ppmtompeg.html -deleted file mode 100644 -index af5a8d7..0000000 ---- a/userguide/ppmtompeg.html -+++ /dev/null -@@ -1,1294 +0,0 @@ -- --Ppmtompeg User Manual -- --

    ppmtompeg

    --Updated: 23 July 2006 --
    --Table Of Contents -- --

    NAME

    --ppmtompeg - encode an MPEG-1 bitstream -- --

    SYNOPSIS

    -- --ppmtompeg --[options] --parameter-file -- --

    DESCRIPTION

    -- --

    This program is part of Netpbm. -- --

    ppmtompeg produces an MPEG-1 video stream. MPEG-1 is the --first great video compression method, and is what is used in Video CDs --(VCD). ppmtompeg originated in the year 1995. DVD uses a more --advanced method, MPEG-2. There is an even newer method called MPEG-4 --which is also called Divx. I don't know where one finds that used. -- --

    There's technically a difference between a compression method for --video and an actual file (stream) format for a movie, and I don't know --if it can be validly said that the format of the stream --ppmtompeg produces is MPEG-1. -- --

    Mencoder from the Mplayer --package is probably superior for most video format generation --needs, if for no other reason than that it is more popular. -- --

    The programming library PM2V --generates MPEG-2 streams. -- --

    Use Mplayer (not part of Netpbm) --to do the reverse conversion: to create a series of PNM files from an MPEG --stream. -- --

    param_file is a parameter file which includes a list of --input files and other parameters. The file is described in detail --below. -- --

    To understand this program, you need to understand something about --the complex MPEG-1 format. One source of information about this --standard format is the section Introduction to MPEG in the Compression FAQ. -- --

    OPTIONS

    -- --

    The -gop, -combine_gops, -frames, and ---combine_frames options are all mutually exclusive. -- --

    --
    -stat stat_file -- --
    This option causes ppmtompeg to append the statistics that --it write to Standard Output to the file stat_file as well. The --statistics use the following abbreviations: bits per block (bpb), bits --per frame (bpf), seconds per frame (spf), and bits per second (bps). -- --

    These statistics include how many I, P, and B frames there were, --and information about compression and quality. -- -- --

    -quiet num_seconds -- --
    causes ppmtompeg not to report remaining time more often --than every num_seconds seconds (unless the time estimate rises, --which will happen near the beginning of the run). A negative value --tells ppmtompeg not to report at all. 0 is the default --(reports once after each frame). Note that the time remaining is an --estimate and does not take into account time to read in frames. -- --
    -realquiet
    causes ppmtompeg to run silently, --with the only screen output being errors. Particularly useful when --reading input from stdin. The equivalent of the -quiet --common option of most other Netpbm programs. -- --
    ---no_frame_summary -- --
    This option prevents ppmtompeg from printing a summary --line for each frame -- --
    -float_dct -- --
    forces ppmtompeg to use a more accurate, yet more --computationally expensive version of the DCT. -- --
    -gop gop_num --
    --causes ppmtompeg to encode only the numbered GOP (first GOP is 0). The --parameter file is the same as for normal usage. The output file will be --the normal output file with the suffix .gop.gop_num. --ppmtompeg does not output any sequence information. -- --
    -combine_gops -- --
    causes ppmtompeg simply to combine some GOP files into a --single MPEG output stream. ppmtompeg inserts a sequence header --and trailer. In this case, the parameter file needs only to contain --the SIZE value, an output file, and perhaps a list of input GOP --files (see below). -- --If you don't supply a list of input GOP files is used, then --ppmtompeg assumes you're using the same parameter file you used --when you created the input (with the -gop option) and --calculates the corresponding gop filenames itself. If this is not the --case, you can specify input GOP files in the same manner as normal --input files -- except instead of using INPUT_DIR, INPUT, and --END_INPUT, use GOP_INPUT_DIR, GOP_INPUT, and GOP_END_INPUT. If no --input GOP files are specified, then the default is to use the output --file name with suffix .gop.gop_num, with gop_num --starting from 0, as the input files. -- --

    Thus, unless you're mixing and matching GOP files from different --sources, you can simply use the same parameter file for creating the --GOP files (-gop) and for later turning them into an MPEG stream --(-combine_gops). -- -- --

    -frames first_frame last_frame -- --
    This option causes ppmtompeg to encode only the frames numbered --first_frame to last_frame, inclusive. The parameter --file is the same as for normal usage. The output will be placed in --separate files, one per frame, with the file names being the normal --output file name with the suffix .frame.frame_num. No --GOP header information is output. (Thus, the parameter file need not --include the GOP_SIZE value) -- --

    Use ppmtompeg -combine_frames to combine these frames later into --an MPEG stream. -- -- --

    -combine_frames -- --
    This option causes ppmtompeg simply to combine some --individual MPEG frames (such as you might have created with an earlier --run of ppmtompeg -frames) into a single MPEG stream. Sequence --and GOP headers are inserted appropriately. In this case, the --parameter file needs to contain only the SIZE value, the GOP_SIZE --value, an output file, and perhaps a list of frame files (see below). -- --

    The parameter file may specify input frame files in the same manner --as normal input files -- except instead of using INPUT_DIR, INPUT, and --END_INPUT, use FRAME_INPUT_DIR, FRAME_INPUT, and FRAME_END_INPUT. If --no input frame files are specified, then the default is to use the --output file name with suffix .frame.frame_num, with --frame_num starting from 0, as the input files. -- -- -- --

    -nice -- --
    This option causes ppmtompeg to run any remote processes --"nicely," i.e. at low priority. (This is relevant only if you are --running ppmtompeg in parallel mode. Otherwise, there are no --remote processes). See 'man nice.' -- --
    -max_machines num_machines -- --
    This option causes ppmtompeg to use no more than --num_machines machines as slaves for use in parallel encoding. -- --
    -snr -- --
    This option causes ppmtompeg to include the signal-to-noise --ratio in the reported statistics. Prints SNR (Y U V) and peak SNR (Y --U V) for each frame. In summary, prints averages of luminance only --(Y). SNR is defined as 10*log(variance of original/variance of --error). Peak SNR is defined as 20*log(255/RMSE). Note that --ppmtompeg runs a little slower when you use this option. -- --
    -mse -- --
    This option causes ppmtompeg to report the mean squared --error per block. It also automatically reports the quality of the --images, so there is no need to specify -snr then. -- --
    -bit_rate_info rate_file -- --
    This option makes ppmtompeg write bit rate information --into the file rate_file. Bit rate information is bits per frame, and --also bits per I-frame-to-I-frame. -- --
    -mv_histogram -- --
    This option causes ppmtompeg to print a histogram of the --motion vectors as part of statistics. There are three histograms -- --one for P frame, one for forward B frame, and one for backward B frame --motion vectors. -- --

    The output is in the form of a matrix, each entry corresponding to one --motion vector in the search window. The center of the matrix --represents (0,0) motion vectors. -- --

    -debug_sockets -- --
    This option causes ppmtompeg to print to Standard Output --messages that narrate the communication between the machines when you run --ppmtompeg in parallel mode. -- --
    -debug_machines -- --
    This option causes ppmtompeg to print to Standard Output --messages that narrate the progress of the conversion on the various --machines when you run ppmtompeg in parallel --mode. -- --
    -- --

    PARAMETER FILE

    -- --

    The parameter file must contain the following --lines (except when using the -combine_gops or -combine_frames --options): -- --

    -- --
    PATTERN pattern -- --
    This statement specifies the pattern (sequence) of I frames, P frames, --and B frames. pattern is just a sequence of the letters I, P, and --B with nothing between. Example: -- --
    --    PATTERN IBBPBBPBBPBBPBB
    --
    -- --

    See I Frames, P Frames, B Frames. -- --

    OUTPUT output file --
    This names the file where the output MPEG stream goes. -- --
    INPUT_DIR directory -- --
    This statement tells where the input images (frames) come from. --If each frame is in a separate file, directory is the directory --where they all are. You may use . to refer to the current --directory. A null directory refers to the root directory of the --system file tree. -- --

    To have ppmtompeg read all the frames serially from Standard --Input, specify --

    --    INPUT_DIR stdin
    --
    -- --
    INPUT --
    --This line must be followed by a list of the input files (in display order) --and then the line END_INPUT. -- --

    There are three types of lines between INPUT and END_INPUT. First, --a line may simply be the name of an input file. Second, the line --may be of the form single_star_expr --[x-y]. --single_star_expr can have a single * in it. It is --replaced by all the numbers between x and y inclusive. So, for --example, the line tennis*.ppm [12-15] refers to the files --tennis12.ppm, tennis13.ppm, tennis14.ppm, tennis15.ppm. -- --

    Uniform zero-padding occurs, as well. For example, the line --football.*.ppm [001-130] refers to the files football.001.ppm, --football.002.ppm, ..., football.009.ppm, football.010.ppm, ..., --football.130.ppm. -- --

    The third type of line is: single_star_expr --[x-y+s], where the --line is treated exactly as above, except that we skip by s. Thus, the --line football.*.ppm [001-130+4] refers to the files --football.001.ppm, football.005.ppm, football.009.ppm, --football.013.ppm, etc. -- --

    Furthermore, a line may specify a shell command to execute to --generate lines to be interpreted as described above, as if those lines --were in the parameter file instead. Use back ticks, like in the --Bourne Shell, like this: -- --

    --    `cat myfilelist`
    --
    -- --

    --If input is from Standard Input (per the INPUT_DIR statement), --ppmtompeg ignores the INPUT/END_INPUT block, but --it still must be present. -- --

    BASE_FILE_FORMAT {PPM | PNM | YUV | -- JPEG | JMOVIE} -- --
    ppmtompeg must convert all input files to one of the --following formats as a first step of processing: PNM, YUV, JPEG(v4), --or JMOVIE. (The conversion may be trivial if your input files are --already in one of these formats). This line specifies which of the --four formats. PPM is actually a subset of PNM. The separate --specification is allowed for backward compatibility. Use PNM instead --of PPM in new applications. -- --
    INPUT_CONVERT conversion_command -- --
    You must specify how to convert a file to the base file format. --If no conversion is necessary, then you would just say: -- --
    --     INPUT_CONVERT *
    --     
    -- --

    Otherwise, conversion_command is a shell command that causes --an image in the format your specified with BASE_FILE_FORMAT to --be written to Standard Output. ppmtompeg executes the command --once for each line between INPUT and END_INPUT (which is --normally, but not necessarily, a file name). In the conversion --command, ppmtompeg replaces each '*' with the contents of that --line. -- -- If you had a bunch of gif files, you might say: --

    --     INPUT_CONVERT giftopnm *
    --     
    -- -- If you have a bunch of separate a.Y, a.U, and a.V files (where -- the U and V have already been subsampled), then you might say: -- --
    --     INPUT_CONVERT cat *.Y *.U *.V
    --     
    -- --

    Input conversion is not allowed with input from stdin, so use -- --

    --     INPUT_CONVERT *
    --     
    -- --as described above. -- --
    SIZE widthxheight -- --
    -- --

    width and height are the width and height of each --frame in pixels. -- --

    When ppmtompeg can get this information from the input image --files, it ignores the SIZE parameter and you may omit it. -- --

    When the image files are in YUV format, the files don't contain --dimension information, so SIZE is required. -- --

    When ppmtompeg is running in parallel mode, not all of the --processes in the network have access to the image files, so --SIZE is required and must give the same dimensions as the --input image files. -- --

    YUV_SIZE widthxheight -- --
    This is an obsolete synonym of SIZE. -- --
    YUV_FORMAT {ABEKAS | PHILLIPS | UCB | -- EYUV | pattern} -- --
    This is meaningful only when BASE_FILE_FORMAT specifies --YUV format, and then it is required. It specifies the sub-format of --the YUV class. -- -- --
    GOP_SIZE n -- --
    n is the number of frames in a Group of Pictures. Except that --because a GOP must start with an I frame, ppmtompeg makes a GOP as --much longer than n as it has to to make the next GOP start with an --I frame. -- --

    Normally, it makes sense to make your GOP size a multiple of your --pattern length (the latter is determined by the PATTERN parameter file --statement). -- --

    See Group Of Pictures. -- --

    SLICES_PER_FRAME n --
    n is roughly the number of slices per frame. Note, at --least one MPEG player may complain if slices do not start at the left --side of an image. To ensure this does not happen, make sure the --number of rows is divisible by SLICES_PER_FRAME. -- --
    PIXEL {FULL | HALF} -- --
    use half-pixel motion vectors, or just full-pixel ones It is --usually important that you use half-pixel motion vectors, because it --results in both better quality and better compression. -- -- --
    RANGE n --
    Use a search range of n pixels in each of the four directions --from a subject pixel. (So the search window is a square n*2 pixels --on a side). -- --
    PSEARCH_ALG {EXHAUSTIVE | TWOLEVEL | -- SUBSAMPLE | LOGARITHMIC} -- --
    This statement tells ppmtompeg what kind of search -- technique (algorithm) to use for P frames. You select the desired -- combination of speed and compression. EXHAUSTIVE gives the -- best compression, but LOGARITHMIC is the fastest. -- TWOLEVEL is an exhaustive full-pixel search, followed by a -- local half- pixel search around the best full-pixel vector (the -- PIXEL option is ignored for this search technique). -- --
    BSEARCH_ALG {SIMPLE | CROSS2 | EXHAUSTIVE} -- --
    This statement tells ppmtompeg what kind of search -- technique (algorithm) to use for B frames. SIMPLE means -- find best forward and backward vectors, then interpolate. -- CROSS2 means find those two vectors, then see what backward -- vector best matches the best forward vector, and vice versa. -- EXHAUSTIVE does an n-squared search and is -- extremely slow in relation to the others (CROSS2 -- is about half as fast as SIMPLE). -- --
    IQSCALE n --
    Use n as the qscale for I frames. -- See Qscale. -- --
    PQSCALE n --
    Use n as the qscale for P frames. -- See Qscale. -- --
    BQSCALE n --
    Use n as the qscale for B frames. -- See Qscale. -- --
    REFERENCE_FRAME {ORIGINAL | DECODED}
    This --statement determines whether ppmtompeg uses the original images --or the decoded images when computing motion vectors. Using decoded --images is more accurate and should increase the playback quality of --the output, but it makes the encoding take longer and seems to give --worse compression. It also causes some complications with parallel --encoding. (see the section on parallel encoding). One thing you can --do as a trade-off is select ORIGINAL here, and lower the --qscale (see QSCALE if the quality is not good enough. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    Original or Decoded? (Normalized)
    ReferenceCompressionSpeedQuality IQuality PQuality B
    Decoded100010001000969919
    Original88513731000912884
    -- -- -- --
    -- --

    The following lines are optional: -- --

    -- --
    FORCE_ENCODE_LAST_FRAME -- --
    This statement is obsolete. It does nothing. -- --

    Before Netpbm 10.26 (January 2005), ppmtompeg would drop --trailing B frames from your movie, since a movie can't end with a B --frame. (See I Frames, P Frames, B Frames. --You would have to specify FORCE_ENCODE_LAST_FRAME to stop --that from happening and get the same function that ppmtompeg --has today. -- -- --

    NIQTABLE -- --
    This statement specifies a custom non-intra quantization table. --If you don't specify this statement, ppmtompeg uses a default --non-intra quantization table. -- --

    --The 8 lines immediately following NIQTABLE specify the quantization --table. Each line defines a table row and consists of 8 integers, --whitespace-delimited, which define the table columns. -- --

    IQTABLE -- --
    This is analogous to NIQTABLE, but for the intra quantization table. -- --
    ASPECT_RATIO ratio -- --
    This statement specifies the aspect ratio for ppmtompeg to --specify in the MPEG output. I'm not sure what this is used for. -- --

    ratio must be 1.0, 0.6735, 0.7031, 0.7615, 0.8055, 0.8437, --0.8935, 0.9157, 0.9815, 1.0255, 1.0695, 1.0950, 1.1575, or 1.2015. -- --

    FRAME_RATE rate --
    This specifies the frame rate for ppmtompeg to specify in the --MPEG output. Some players use this value to determine the playback rate. -- --

    rate must be 23.976, 24, 25, 29.97, 30, 50, 59.94, or 60. -- --

    BIT_RATE rate --
    This specifies the bit rate for Constant Bit Rate (CBR) encoding. -- --

    rate must be an integer. -- --

    BUFFER_SIZE size -- --
    This specifies the value --ppmtompeg is to specify in the MPEG output for the Video --Buffering Verifier (VBV) buffer size needed to decode the sequence. -- --

    A Video Verifying Buffer is a buffer in which a decoder keeps the --decoded bits in order to match the uneven speed of the decoding with --the required constant playback speed. -- --

    As ppmtompeg encodes the image, it simulates the decoding --process in terms of how many bits would be in the VBV as each frame gets --decoded, assuming a VBV of the size you indicate. -- --

    If you specify the WARN_VBV_UNDERFLOW statement, --ppmtompeg issues a warning each time the simulation underflows --the buffer, which suggests that an underflow would occur on playback, --which suggests the buffer is too small. -- --

    If you specify the WARN_VBV_OVERFLOW statement, --ppmtompeg issues a warning each time the simulation overflows --the buffer, which suggests that an overflow would occur on playback, --which suggests the buffer is too small. -- --

    WARN_VBV_UNDERFLOW --
    WARN_VBV_OVERFLOW -- --
    See BUFFER_SIZE. -- --

    These options were new in Netpbm 10.26 (January 2005). Before that, --ppmtompeg issued the warnings always. -- --

    -- -- --The following statements apply only to parallel operation: -- --
    -- --
    PARALLEL -- --
    This statement, paired with END PARALLEL, is what causes --ppmtompeg to operate in parallel mode. See Parallel Operation. -- --
    END PARALLEL -- --
    This goes with PARALLEL. -- --
    PARALLEL_TEST_FRAMES n -- --
    The master starts off by measuring each slave's speed. It does --this by giving each slave n frames to encode and noting how --long the slave takes to finish. These are not just test frames, --though -- they're real frames and the results become part of the --output. --ppmtompeg is old and measures time in undivided seconds, so --to get useful timings, specify enough frames that it will take at --least 5 seconds to process them. The default is 10. -- --

    If you specify FORCE_I_ALIGN, ppmtompeg will increase --the test frames value enough to maintain the alignment. -- --

    If there aren't enough frames for every slave to have the indicated --number of test frames, ppmtompeg will give some slaves fewer. -- -- --

    PARALLEL_TIME_CHUNKS t -- --
    When you specify this statement, the master attempts to feed work --to the slaves in chunks that take t seconds to process. It uses --the speed measurement it made when it started up (see PARALLEL_TEST_FRAMES) --to decide how many frames to put in the chunk. This statement obviously --doesn't affect the first batch of work sent to each slave, which is the --one used to measure the slave's speed. -- --

    Smaller values of t increase communication, but improve load --balancing. The default is 30 seconds. -- --

    You may specify only one of PARALLEL_TIME_CHUNKS, PARALLEL_CHUNK_TAPER, --and PARALLEL_PERFECT. PARALLEL_CHUNK_TAPER is usually best. -- --

    PARALLEL_CHUNK_TAPER -- --
    When you specify this statement, the master distributes work like --with PARALLEL_TIME_CHUNKS, except that the master chooses the number --of seconds for the chunks. It starts with a large number and, as it --gets closer to finishing the job, reduces it. That way, it reduces --scheduling overhead when precise scheduling isn't helpful, but still --prevents a slave from finishing early after all the work has already --been handed out to the other slaves, and then sitting idle while --there's still work to do. -- --

    You may specify only one of PARALLEL_TIME_CHUNKS, PARALLEL_CHUNK_TAPER, --and PARALLEL_PERFECT. PARALLEL_CHUNK_TAPER is usually best. -- -- --

    PARALLEL_PERFECT -- --
    If this statement is present, ppmtompeg schedules on the --assumption that each machine is about the same speed. The master will --simply divide up the frames evenly between the slaves -- each --slave gets the same number of frames. If some slaves are faster than --others, they will finish first and remain idle while the slower slaves --continue. -- --

    This has the advantage of minimal scheduling overhead. Where slaves --have different speeds, though, it makes inefficient use of the fast --ones. Where slaves are the same speed, it also has the disadvantage --that they all finish at the same time and feed their output to the --single Combine Server in a burst, which makes less efficient use of --the Combine Server and thus can increase the total elapsed time. -- --

    You may specify only one of PARALLEL_TIME_CHUNKS, PARALLEL_CHUNK_TAPER, --and PARALLEL_PERFECT. PARALLEL_CHUNK_TAPER is usually best. -- --

    RSH remote_shell_command -- --
    ppmtompeg executes the shell command --remote_shell_command to start a process on another machine. --The default command is rsh, and whatever command you specify --must have compatible semantics. ssh is usually compatible. --The command ppmtompeg uses is one like this: --ssh remote.host.com -l username shellcommand. -- --

    Be sure to set up .rhosts files or SSH key authorizations --where needed. Otherwise, you'll have to type in passwords. -- --

    On some HP machines, rsh is the restricted shell, and you want --to specify remsh. -- --

    FORCE_I_ALIGN -- --
    This statement forces each slave to encode a chunk of frames which --is a multiple of the pattern length (see PATTERN). Since the --first frame in any pattern is an I frame, this forces each chunk --encoded by a slave to begin with an I frame. -- --

    This document used to say there was an argument to --FORCE_I_ALIGN which was the number of frames ppmtompeg --would use (and was required to be a multiple of the pattern length). --But ppmtompeg has apparently always ignored that argument, and --it does now. -- --

    KEEP_TEMP_FILES -- --
    This statement causes ppmtompeg not to delete the temporary --files it uses to transmit encoded frames to the combine server. This --means you will be left with a file for each frame, the same as you --would get with the -frames option. -- --

    This is mostly useful for debugging. -- --

    This works only if you're using a shared filesystem to communicate --between the servers. -- --

    This option was new in Netpbm 10.26 (January 2005). -- --

    -- -- --

    Parameter File Notes

    -- --

    If you use the -combine_gops option, then you need to specify --only the SIZE and OUTPUT values in the parameter file. In --addition, the parameter file may specify input GOP files in the same --manner as normal input files -- except instead of using INPUT_DIR, --INPUT, and END_INPUT, use GOP_INPUT_DIR, GOP_INPUT, and GOP_END_INPUT. --If you specify no input GOP files, then ppmtompeg uses by default the --output file name with suffix .gop.gop_num, with gop_num --starting from 0, as the input files. -- --

    If you use the -combine_frames option, then you need to --specify only the SIZE, GOP_SIZE, and OUTPUT values in the --parameter file. In addition, the parameter file may specify input --frame files in the same manner as normal input files -- except instead --of using INPUT_DIR, INPUT, and END_INPUT, use FRAME_INPUT_DIR, --FRAME_INPUT, and FRAME_END_INPUT. If no input frame files are --specified, then the default is to use the output file name with suffix --.frame.frame_num, with frame_num starting from 0, --as the input files. -- --

    Any number of spaces and tabs may come between each option and value. Lines --beginning with # are ignored. Any other lines are ignored except for --those between INPUT and END_INPUT. This allows you to use the same --parameter file for normal usage and for -combine_gops and ---combine_frames. -- --

    The file format is case-sensitive so all keywords should be in --upper case. -- --

    The statements may appear in any order, except that the order within --a block statement (such as INPUT ... END INPUT) is significant. -- --

    ppmtompeg is prepared to handle up to 16 B frames between --reference frames when encoding with input from stdin. (To build a --modified ppmtompeg with a higher limit, change the constant --B_FRAME_RUN in frame.c and recompile). -- --

    GENERAL USAGE INFORMATION

    -- --

    Qscale

    -- --

    The quantization scale values (qscale) give a trade-off between --quality and compression. Using different Qscale values has very little --effect on speed. The qscale values can be set separately for I, P, and --B frames. -- --

    You select the qscale values with the IQSCALE, --PQSCALE, and BSCALE parameter file statements. -- --

    A qscale value is an integer from 1 to 31. Larger numbers give --better compression, but worse quality. In the following, the quality --numbers are peak signal-to-noise ratio, defined as: --signal-to-noise formula --where MSE is the mean squared error. -- -- --

    Flower garden tests: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    Qscale vs Quality
    QscaleI FramesP FramesB Frames
    143.246.346.5
    632.634.634.3
    1128.629.530.0
    1626.326.828.6
    2124.725.027.9
    2623.523.927.5
    3122.623.027.3
    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    Qscale vs Compression
    QscaleI FramesP FramesB Frames
    1222
    671015
    11111843
    16152997
    211941173
    262456256
    312873330
    -- -- --

    Search Techniques

    -- --

    There are several different motion vector search techniques --available. There are different techniques available for P frame --search and B frame search. Using different search techniques present --little difference in quality, but a large difference in compression --and speed. -- --

    There are 4 types of P frame search: Exhaustive, TwoLevel, --SubSample, and Logarithmic. -- --

    There are 3 types of B frame search: Exhaustive, Cross2, and --Simple. -- --The recommended search techniques are TwoLevel and Logarithmic for --P frame search, and Cross2 and Simple for B frame search. Here are --some numbers comparing the different search methods: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    P frame Motion Vector Search (Normalized)
    TechniqueCompression1Speed 2Quality 3
    Exhaustive100010001000
    SubSample100824561000
    TwoLevel100932371000
    Logarithmic10858229998
    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    B frame Motion Vector Search (Normalized)
    TechniqueCompression1Speed2Quality3
    Exhaustive100010001000
    Cross29751000996
    Simple9381765991
    -- -- 1Smaller numbers are better --compression. -- -- 2Larger numbers mean faster --execution. -- -- 3Larger numbers mean better quality. -- --

    For some reason, Simple seems to give better compression, but it --depends on the image sequence. -- --

    Select the search techniques with the PSEARCH_ALG and --BSEARCH_ALG parameter file statements. -- -- --

    Group Of Pictures (GOP)

    -- --

    A Group of Pictures (GOP) is a roughly independently decodable --sequence of frames. An MPEG video stream is made of one or more --GOP's. You may specify how many frames should be in each GOP with the --GOP_SIZE parameter file statement. A GOP always starts with an --I frame. -- --

    Instead of encoding an entire sequence, you can encode a single --GOP. To do this, use the -gop command option. You can later --join the resulting GOP files at any time by running ppmtompeg --with the -combine_gops command option. -- -- --

    Slices

    -- --

    A slice is an independently decodable unit in a frame. It can be --as small as one macroblock, or it can be as big as the entire frame. --Barring transmission error, adding slices does not change quality or --speed; the only effect is slightly worse compression. More slices are --used for noisy transmission so that errors are more recoverable. Since --usually errors are not such a problem, we usually just use one slice --per frame. -- --

    Control the slice size with the SLICES_PER_FRAME parameter --file statement. -- --

    Some MPEG playback systems require that each slice consist of whole --rows of macroblocks. If you are encoding for this kind of player, if --the height of the image is H pixels, then you should set the --SLICES_PER_FRAME to some number which divides H/16. For example, if --the image is 240 pixels (15 macroblocks) high, then you should use --only 15, 5, 3, or 1 slices per frame. -- --

    Note: these MPEG playback systems are really wrong, since the MPEG --standard says this doesn't have to be so. -- -- -- --

    Search Window

    -- --

    The search window is the window in which ppmtompeg searches --for motion vectors. The window is a square. You can specify the size --of the square, and whether to allow half-pixel motion vectors or not, --with the RANGE and PIXEL parameter file statements. -- --

    I Frames, P Frames, B Frames

    -- --

    In MPEG-1, a movie is represented as a sequence of MPEG frames, --each of which is an I Frame, a P Frame, or a B Frame. Each represents --an actual frame of the movie (don't get confused by the dual use of --the word "frame." A movie frame is a graphical image. An MPEG frame --is a set of data that describes a movie frame). -- --

    An I frame ("intra" frame) describes a movie frame in isolation -- --without respect to any other frame in the movie. A P frame --("predictive" frame) describes a movie frame by describing how it --differs from the movie frame described by the latest preceding I or --P frame. A B frame ("bidirectional" frame) describes a movie frame by --describing how it differs from the movie frames described by the --nearest I or P frame before and after it. -- --

    Note that the first frame of a movie must be described by an I --frame (because there is no previous movie frame) and the last movie --frame must be described by an I or P frame (because there is no --subsequent movie frame). -- --

    Beyond that, you can choose which frames are represented by which --types. You specify a pattern, such as IBPBP and ppmtompeg --simply repeats it over and over throughout the movie. The pattern --affects speed, quality, and stream size. Here is a chart which shows --some of the trade-offs: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    Comparison of I/P/B Frames (Normalized)
    Frame TypeSizeSpeedQuality
    I frames100010001000
    P frames409609969
    B frames72260919
    -- --(this is with constant qscale) -- --

    A standard sequence is IBBPBBPBBPBBPBB. -- --

    Select the sequence with the PATTERN parameter file statement. -- --

    Since the last MPEG frame cannot be a B frame (see above), if the --pattern you specify indicates a B frame for the last movie frame of --the movie, ppmtompeg makes it an I frame instead. -- --

    Before Netpbm 10.26 (January 2005), ppmtompeg instead drops --the trailing B frames by default, and you need the --FORCE_ENCODE_LAST_FRAME parameter file statement to make it do --this. -- --

    The MPEG frames don't appear in the MPEG-1 stream in the same order that --the corresponding movie frames appear in the movie -- the B frames come after --the I and P frames on which they are based. For example, if the movie is --4 frames that you will represent with the pattern IBBP, the MPEG-1 stream --will start with an I frame describing movie frame 0. The next frame in --the MPEG-1 stream is a P frame describing movie frame 3. The last two --frames in the MPEG-1 stream are B frames describing movie frames 1 and 2, --respectively. -- -- --

    Specifying Input and Output Files

    -- --

    Specify the input frame images with the INPUT_DIR, --INPUT, END_INPUT, BASE_FILE_FORMAT, --SIZE, YUV_FORMAT and INPUT_CONVERT parameter --file statements. -- --

    Specify the output file with the OUTPUT parameter file statement. -- -- --

    Statistics

    -- --

    ppmtompeg can generate a variety of statistics about the --encoding. See the -stat, -snr, -mv_histogram, ---quiet, -no_frame_summary, and -bit_rate_info --options. -- -- --

    PARALLEL OPERATION

    -- --

    You can run ppmtompeg on multiple machines at once, encoding --the same MPEG stream. When you do, the machines are used as shown in --the following diagram. We call this "parallel mode." -- --

    ppmtompeg-par.gif -- --

    To do parallel processing, put the statement -- --

    --    PARALLEL
    --
    -- --in the parameter file, followed by a listing of the machines, one --machine per line, then -- --
    --    END_PARALLEL
    --
    -- --Each of the machine lines must be in one of two forms. If the machine --has filesystem access to the input files, then the line is: -- --

    --machine user executable -- --

    The executable is normally ppmtompeg (you may need to give --the complete path if you've built for different architectures). If --the machine does not have filesystem access to the input files, the line --is: -- --

    REMOTE machine user executable --parameter file -- --

    The -max_machines command option limits the number of --machines ppmtompeg will use. If you specify more machines in --the parameter file than -max_machines allows, ppmtompeg --uses only the machines listed first. This is handy if you want to --experiment with different amounts of parallelism. -- --

    In general, you should use full path file names when describing --executables and parameter files. This includes the parameter --file argument on the original invocation of ppmtompeg. -- --

    All file names must be the same on all systems (so if e.g. you're --using an NFS filesystem, you must make sure it is mounted at the same --mountpoint on all systems). -- --

    Because not all of the processes involved in parallel operation --have easy access to the input files, you must specify the SIZE --parameter file statement when you do parallel operation. -- --

    The machine on which you originally invoke ppmtompeg is the --master machine. It hosts a "combine server,", a --"decode server," and a number of "i/o servers," --all as separate processes. The other machines in the network (listed --in the parameter file) are slave machines. Each hosts a single --process that continuously requests work from the master and does it. --The slave process does the computation to encode MPEG frames. It --processes frames in batches identified by the master. -- --

    The master uses a remote shell command to start a process on a --slave machine. By default, it uses an rsh shell command to do --this. But use the RSH parameter file statement to control --this. The shell command the master executes remotely is --ppmtompeg, but with options to indicate that it is to perform --slave functions. -- --

    The various machines talk to each other over TCP connections. Each --machine finds and binds to a free TCP port number and tells its --partners the port number. These port numbers are at least 2048. -- --

    Use the PARALLEL_TEST_FRAMES, PARALLEL_TIME_CHUNKS, and --PARALLEL_PERFECT parameter file statements to control the way the --master divides up work among the slaves. -- --

    Use the -nice command option to cause all slave processes to run --"nicely," i.e. as low priority processes. That way, this substantial and --long-running CPU load will have minimal impact on other, possibly --interactive, users of the systems. -- --

    SPEED

    -- --

    Here is a look at ppmtompeg speed, in single-node (not parallel) --operation: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    Compression Speed
    Machine TypeMacroblocks per second1
    HP 9000/755280
    DEC 3000/400247
    HP 9000/750191
    Sparc 10104
    DEC 500068
    --1A macroblock is a 16x16 pixel square -- --

    The measurements in the table are with inputs and outputs via a --conventional locally attached filesystem. If you are using a network --filesystem over a single 10 MB/s Ethernet, that constrains your speed more --than your CPU speed. In that case, don't expect to get better than 4 --or 5 frames per second no matter how fast your CPUs are. -- --

    Network speed is even more of a bottleneck when the slaves do not --have filesystem access to the input files -- i.e. you declare them --REMOTE. -- --

    Where I/O is the bottleneck, size of the input frames can make a big --difference. So YUV input is better than PPM, and JPEG is better than --both. -- --

    When you're first trying to get parallel mode working, be sure to --use the -debug_machines option so you can see what's going on. --Also, -debug_sockets can help you diagnose communication --problems. -- -- --

    AUTHORS

    -- -- -- --
    --

    Table Of Contents

    -- -- -- diff --git a/netpbm-pamtojpeg2k.patch b/netpbm-pamtojpeg2k.patch index 7eeed54..8fbd899 100644 --- a/netpbm-pamtojpeg2k.patch +++ b/netpbm-pamtojpeg2k.patch @@ -1,234 +1,7 @@ -diff --git a/converter/other/jpeg2000/pamtojpeg2k.c b/converter/other/jpeg2000/pamtojpeg2k.c -index 4d73316..a53573f 100644 ---- a/converter/other/jpeg2000/pamtojpeg2k.c -+++ b/converter/other/jpeg2000/pamtojpeg2k.c -@@ -98,7 +98,7 @@ parseCommandLine(int argc, char ** argv, - char * modeOpt; - - unsigned int option_def_index; -- -+ - MALLOCARRAY_NOFAIL(option_def, 100); - - option_def_index = 0; /* incremented by OPTENTRY */ -@@ -134,25 +134,25 @@ parseCommandLine(int argc, char ** argv, - &numrlvlsSpec, 0); - OPTENT3(0, "numgbits", OPT_UINT, &cmdlineP->numgbits, - &numgbitsSpec, 0); -- OPTENT3(0, "nomct", OPT_FLAG, NULL, -+ OPTENT3(0, "nomct", OPT_FLAG, NULL, - &cmdlineP->nomct, 0); -- OPTENT3(0, "sop", OPT_FLAG, NULL, -+ OPTENT3(0, "sop", OPT_FLAG, NULL, - &cmdlineP->sop, 0); -- OPTENT3(0, "eph", OPT_FLAG, NULL, -+ OPTENT3(0, "eph", OPT_FLAG, NULL, - &cmdlineP->eph, 0); -- OPTENT3(0, "lazy", OPT_FLAG, NULL, -+ OPTENT3(0, "lazy", OPT_FLAG, NULL, - &cmdlineP->lazy, 0); -- OPTENT3(0, "termall", OPT_FLAG, NULL, -+ OPTENT3(0, "termall", OPT_FLAG, NULL, - &cmdlineP->termall, 0); -- OPTENT3(0, "segsym", OPT_FLAG, NULL, -+ OPTENT3(0, "segsym", OPT_FLAG, NULL, - &cmdlineP->segsym, 0); -- OPTENT3(0, "vcausal", OPT_FLAG, NULL, -+ OPTENT3(0, "vcausal", OPT_FLAG, NULL, - &cmdlineP->vcausal, 0); -- OPTENT3(0, "pterm", OPT_FLAG, NULL, -+ OPTENT3(0, "pterm", OPT_FLAG, NULL, - &cmdlineP->pterm, 0); -- OPTENT3(0, "resetprob", OPT_FLAG, NULL, -+ OPTENT3(0, "resetprob", OPT_FLAG, NULL, - &cmdlineP->resetprob, 0); -- OPTENT3(0, "verbose", OPT_FLAG, NULL, -+ OPTENT3(0, "verbose", OPT_FLAG, NULL, - &cmdlineP->verbose, 0); - OPTENT3(0, "debuglevel", OPT_UINT, &cmdlineP->debuglevel, - &debuglevelSpec, 0); -@@ -223,7 +223,7 @@ parseCommandLine(int argc, char ** argv, - cmdlineP->inputFilename = strdup("-"); /* he wants stdin */ - else if (argc - 1 == 1) - cmdlineP->inputFilename = strdup(argv[1]); -- else -+ else - pm_error("Too many arguments. The only argument accepted\n" - "is the input file specification"); - -@@ -232,7 +232,7 @@ parseCommandLine(int argc, char ** argv, - - - static void --createJasperRaster(struct pam * const inpamP, -+createJasperRaster(struct pam * const inpamP, - jas_image_t * const jasperP) { - /*---------------------------------------------------------------------------- - Create the raster in the *jasperP object, reading the raster from the -@@ -254,7 +254,7 @@ createJasperRaster(struct pam * const inpamP, - if (matrix[plane] == NULL) - pm_error("Unable to create matrix for plane %u. " - "jas_matrix_create() failed.", plane); -- } -+ } - tuplerow = pnm_allocpamrow(inpamP); - - jasperMaxval = pm_bitstomaxval(pm_maxvaltobits(inpamP->maxval)); -@@ -271,7 +271,7 @@ createJasperRaster(struct pam * const inpamP, - unsigned int jasperSample; - - if (oddMaxval) -- jasperSample = tuplerow[col][plane] * -+ jasperSample = tuplerow[col][plane] * - jasperMaxval / inpamP->maxval; - else - jasperSample = tuplerow[col][plane]; -@@ -279,16 +279,16 @@ createJasperRaster(struct pam * const inpamP, - jas_matrix_set(matrix[plane], 0, col, jasperSample); - } - } -- { -+ { - unsigned int plane; - - for (plane = 0; plane < inpamP->depth; ++plane) { - int rc; -- rc = jas_image_writecmpt(jasperP, plane, 0, row, -+ rc = jas_image_writecmpt(jasperP, plane, 0, row, - inpamP->width, 1, - matrix[plane]); - if (rc != 0) -- pm_error("jas_image_writecmpt() of plane %u failed.", -+ pm_error("jas_image_writecmpt() of plane %u failed.", - plane); - } - } -@@ -297,14 +297,14 @@ createJasperRaster(struct pam * const inpamP, - pnm_freepamrow(tuplerow); - for (plane = 0; plane < inpamP->depth; ++plane) - jas_matrix_destroy(matrix[plane]); -- -+ - free(matrix); - } - - - - static void --createJasperImage(struct pam * const inpamP, -+createJasperImage(struct pam * const inpamP, - jas_image_t ** const jasperPP) { - - jas_image_cmptparm_t * cmptparms; -@@ -322,7 +322,7 @@ createJasperImage(struct pam * const inpamP, - cmptparms[plane].prec = pm_maxvaltobits(inpamP->maxval); - cmptparms[plane].sgnd = 0; - } -- *jasperPP = -+ *jasperPP = - jas_image_create(inpamP->depth, cmptparms, JAS_CLRSPC_UNKNOWN); - if (*jasperPP == NULL) - pm_error("Unable to create jasper image structure. " -@@ -371,7 +371,7 @@ convertToJasperImage(struct pam * const inpamP, - - - static void --writeJpc(jas_image_t * const jasperP, -+writeJpc(jas_image_t * const jasperP, - struct cmdlineInfo const cmdline, - FILE * const ofP) { - -@@ -383,8 +383,8 @@ writeJpc(jas_image_t * const jasperP, - - /* Note: ilyrrates is a hack because we're too lazy to properly parse - command line options to get the information and then compose -- a proper input to Jasper. So the user can screw things up by -- specifying garbage for the -ilyrrates option -+ a proper input to Jasper. So the user can screw things up by -+ specifying garbage for the -ilyrrates option - */ - if (strlen(cmdline.ilyrrates) > 0) - pm_asprintf(&ilyrratesOpt, "ilyrrates=%s", cmdline.ilyrrates); -@@ -410,7 +410,7 @@ writeJpc(jas_image_t * const jasperP, - */ - rateOpt[0] = '\0'; - } -- pm_asprintf(&options, -+ pm_asprintf(&options, - "imgareatlx=%u " - "imgareatly=%u " - "tilegrdtlx=%u " -@@ -428,7 +428,7 @@ writeJpc(jas_image_t * const jasperP, - "numrlvls=%u " - "numgbits=%u " - "%s %s %s %s %s %s %s %s %s", -- -+ - cmdline.imgareatlx, - cmdline.imgareatly, - cmdline.tilegrdtlx, -@@ -471,8 +471,8 @@ writeJpc(jas_image_t * const jasperP, - pm_message("Using Jasper to encode to 'jpc' format with options " - "'%s'", options); - -- rc = jas_image_encode(jasperP, outStreamP, -- jas_image_strtofmt((char*)"jpc"), -+ rc = jas_image_encode(jasperP, outStreamP, -+ jas_image_strtofmt((char*)"jpc"), - (char *)options); - if (rc != 0) - pm_error("jas_image_encode() failed to encode the JPEG 2000 " -@@ -484,11 +484,11 @@ writeJpc(jas_image_t * const jasperP, - int rc; - - rc = jas_stream_close(outStreamP); -- -+ - if (rc != 0) - pm_error("Failed to close output stream, " - "jas_stream_close() rc = %d", rc); -- } -+ } - - jas_image_clearfmts(); - -@@ -506,33 +506,31 @@ main(int argc, char **argv) - jas_image_t * jasperP; - - pnm_init(&argc, argv); -- -+ - parseCommandLine(argc, argv, &cmdline); -- -- { -+ -+ { - int rc; -- -+ - rc = jas_init(); - if ( rc != 0 ) - pm_error("Failed to initialize Jasper library. " - "jas_init() returns rc %d", rc ); - } -- -+ - jas_setdbglevel(cmdline.debuglevel); -- -+ - ifP = pm_openr(cmdline.inputFilename); -- -+ - pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); -- -+ - convertToJasperImage(&inpam, &jasperP); -- -+ - writeJpc(jasperP, cmdline, stdout); -- -+ - jas_image_destroy(jasperP); +diff -up netpbm-10.47.12/converter/other/jpeg2000/pamtojpeg2k.c.pamtojpeg2kfix netpbm-10.47.12/converter/other/jpeg2000/pamtojpeg2k.c +--- netpbm-10.47.12/converter/other/jpeg2000/pamtojpeg2k.c.pamtojpeg2kfix 2010-04-27 15:47:10.000000000 +0200 ++++ netpbm-10.47.12/converter/other/jpeg2000/pamtojpeg2k.c 2010-05-03 15:37:49.934269588 +0200 +@@ -532,7 +532,5 @@ main(int argc, char **argv) pm_close(ifP); diff --git a/netpbm-python3.patch b/netpbm-python3.patch index f611b81..2557933 100644 --- a/netpbm-python3.patch +++ b/netpbm-python3.patch @@ -1,9 +1,28 @@ -diff -urNp old/buildtools/makeman new/buildtools/makeman ---- old/buildtools/makeman 2018-01-03 12:15:55.000000000 +0100 -+++ new/buildtools/makeman 2018-02-26 14:18:39.993760106 +0100 +diff --git a/buildtools/makeman b/buildtools/makeman +index 196dbd0..d73ab76 100755 +--- a/buildtools/makeman ++++ b/buildtools/makeman @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # makeman -- compile netpbm's stereotyped HTML to troff markup # +diff --git a/buildtools/manpage.mk b/buildtools/manpage.mk +index ef1a103..c1badb8 100644 +--- a/buildtools/manpage.mk ++++ b/buildtools/manpage.mk +@@ -126,11 +126,11 @@ reportman: + # to standard error. + %.1 %.3 %.5: $(USERGUIDE)/%.html + @echo Converting $< to $@ +- @python $(MAKEMAN) -d $(USERGUIDE) $(= nl); + overflow_add(nh - nl, 1); -+ MALLOCARRAY(v, (unsigned) (nh - nl + 1)); if (v == NULL) -@@ -85,6 +87,7 @@ matrix (unsigned int const nrl, +@@ -85,6 +86,7 @@ matrix (unsigned int const nrl, assert(nrh >= nrl); /* allocate pointers to rows */ @@ -19,7 +17,7 @@ index c69643e..eae0b42 100644 MALLOCARRAY(m, (unsigned) (nrh - nrl + 1)); if (m == NULL) pm_error("Unable to allocate memory for a matrix."); -@@ -93,6 +96,7 @@ matrix (unsigned int const nrl, +@@ -93,6 +95,7 @@ matrix (unsigned int const nrl, assert (nch >= ncl); @@ -27,330 +25,21 @@ index c69643e..eae0b42 100644 /* allocate rows and set pointers to them */ for (i = nrl; i <= nrh; ++i) { MALLOCARRAY(m[i], (unsigned) (nch - ncl + 1)); -diff --git a/converter/other/gemtopnm.c b/converter/other/gemtopnm.c -index 6bbfcc0..f7d1dc6 100644 ---- a/converter/other/gemtopnm.c -+++ b/converter/other/gemtopnm.c -@@ -36,7 +36,7 @@ - * read 4-plane color IMG files. Therefore changed from PBM to PPM. - * Bryan changed it further to use the PNM facilities so it outputs - * both PBM and PPM in the Netpbm tradition. Name changed from -- * gemtopbm to gemtopnm. -+ * gemtopbm to gemtopnm. - */ +diff -ruNp a/converter/other/gemtopnm.c b/converter/other/gemtopnm.c +--- a/converter/other/gemtopnm.c 2021-06-02 15:53:59.835205659 +0200 ++++ b/converter/other/gemtopnm.c 2021-06-02 16:15:29.598641385 +0200 +@@ -106,6 +106,7 @@ main(argc, argv) - #include -@@ -50,106 +50,107 @@ - char pattern[8]; + pnm_writepnminit( stdout, cols, rows, MAXVAL, type, 0 ); - static void getinit ARGS ((FILE *file, int *colsP, int *rowsP, int *padrightP, -- int *patlenP, int *planesP)); -+ int *patlenP, int *planesP)); - - int - main(argc, argv) -- int argc; -- char *argv[]; -+ int argc; -+ char *argv[]; - { -- int debug = 0; -- FILE *f; -+ int debug = 0; -+ FILE *f; - int row; -- int rows, cols, padright, patlen, planes; -+ int rows, cols, padright, patlen, planes; - /* attributes of input image */ - int type; /* The format type (PBM/PPM) of the output image */ -- bit *bitrow[4]; -+ bit *bitrow[4]; - /* One row of input, one or four planes. (If one, only [0] is defined)*/ - xel * xelrow; /* One row of output */ -- const char * const usage = "[-debug] [gem IMG file]"; -- int argn; -+ const char * const usage = "[-debug] [gem IMG file]"; -+ int argn; - - /* Process multiple planes by maintaining a separate row of bits for each -- * plane. In a single-plane image, all we have to do is write out the -+ * plane. In a single-plane image, all we have to do is write out the - * first plane; in a multiple-plane image, we combine them just before writing - * out the row. - */ -- pnm_init( &argc, argv ); -- -+ pnm_init( &argc, argv ); -+ - argn = 1; - -- while (argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0') -- { -- if (pm_keymatch(argv[1], "-debug", 2)) -- debug = 1; -- else -- pm_usage (usage); -- ++argn; -- } -+ while (argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0') -+ { -+ if (pm_keymatch(argv[1], "-debug", 2)) -+ debug = 1; -+ else -+ pm_usage (usage); -+ ++argn; -+ } - -- if (argc == argn) -- f = stdin; -- else { -- f = pm_openr (argv[argn]); -- ++argn; -- } -+ if (argc == argn) -+ f = stdin; -+ else { -+ f = pm_openr (argv[argn]); -+ ++argn; -+ } - -- if (argn != argc) -- pm_usage (usage); -+ if (argn != argc) -+ pm_usage (usage); - -- getinit (f, &cols, &rows, &padright, &patlen, &planes); -+ getinit (f, &cols, &rows, &padright, &patlen, &planes); - -- if (planes == 1) -+ if (planes == 1) - type = PBM_TYPE; -- else -+ else - type = PPM_TYPE; - -- pnm_writepnminit( stdout, cols, rows, MAXVAL, type, 0 ); -+ pnm_writepnminit( stdout, cols, rows, MAXVAL, type, 0 ); - -- { + overflow_add(cols, padright); -+ { + { /* allocate input row data structure */ int plane; -- for (plane = 0; plane < planes; plane++) -+ for (plane = 0; plane < planes; plane++) - bitrow[plane] = malloc (cols + padright); - } - xelrow = pnm_allocrow(cols+padright); /* Output row */ - -- for (row = 0; row < rows; ) { -+ for (row = 0; row < rows; ) { - int linerep; - int plane; - -- linerep = 1; -- for (plane = 0; plane < planes; plane++) { -+ linerep = 1; -+ for (plane = 0; plane < planes; plane++) { - int col; -- col = 0; -- while (col < cols) { -+ col = 0; -+ while (col < cols) { - int c; -- switch (c = getc(f)) { -- case 0x80: /* Bit String */ -+ switch (c = getc(f)) { -+ case 0x80: /* Bit String */ - { - int j; -- c = getc(f); /* Byte count */ -- if (debug) -+ c = getc(f); /* Byte count */ -+ if (debug) - pm_message("bit string of %d bytes", c); -- -- if (col + c * 8 > cols + padright) -- pm_error ("bad byte count"); -- for (j = 0; j < c; ++j) { -+ -+ if (col + c * 8 > cols + padright) -+ pm_error ("bad byte count"); -+ for (j = 0; j < c; ++j) { - int cc, k; -- cc = getc(f); -- for (k = 0x80; k; k >>= 1) { -- bitrow[plane][col] = (k & cc) ? 0 : 1; -- ++col; -- } -- } -+ cc = getc(f); -+ for (k = 0x80; k; k >>= 1) { -+ bitrow[plane][col] = (k & cc) ? 0 : 1; -+ ++col; -+ } -+ } - } - break; -- case 0: /* Pattern run */ -+ case 0: /* Pattern run */ - { - int j, l; -- c = getc(f); /* Repeat count */ -- if (debug) -- pm_message("pattern run of %d repetitions", c); -+ c = getc(f); /* Repeat count */ -+ if (debug) -+ pm_message("pattern run of %d repetitions", c); - /* line repeat */ - if (c == 0) { - c = getc(f); -@@ -158,25 +159,25 @@ main(argc, argv) - linerep = getc(f); - break; - } -- fread (pattern, 1, patlen, f); -- if (col + c * patlen * 8 > cols + padright) -- pm_error ("bad pattern repeat count"); -- for (j = 0; j < c; ++j) -- for (l = 0; l < patlen; ++l) { -+ fread (pattern, 1, patlen, f); -+ if (col + c * patlen * 8 > cols + padright) -+ pm_error ("bad pattern repeat count"); -+ for (j = 0; j < c; ++j) -+ for (l = 0; l < patlen; ++l) { - int k; -- for (k = 0x80; k; k >>= 1) { -- bitrow[plane][col] = (k & pattern[l]) ? 0 : 1; -- ++col; -- } -+ for (k = 0x80; k; k >>= 1) { -+ bitrow[plane][col] = (k & pattern[l]) ? 0 : 1; -+ ++col; -+ } - } - } - break; - -- default: /* Solid run */ -+ default: /* Solid run */ - { - int l, j; -- if (debug) -- pm_message("solid run of %d bytes %s", c & 0x7f, -+ if (debug) -+ pm_message("solid run of %d bytes %s", c & 0x7f, - c & 0x80 ? "on" : "off" ); - /* each byte had eight bits DSB */ - l = (c & 0x80) ? 0: 1; -@@ -185,23 +186,23 @@ main(argc, argv) - pm_error ("bad solid run repeat count"); - for (j = 0; j < c; ++j) { - bitrow[plane][col] = l; -- ++col; -+ ++col; - } - } -- break; -+ break; - -- case EOF: /* End of file */ -- pm_error( "end of file reached" ); -+ case EOF: /* End of file */ -+ pm_error( "end of file reached" ); - -- } -- } -+ } -+ } - if ( debug ) - pm_message( "EOL plane %d row %d", plane, row ); - if (col != cols + padright) - pm_error( "EOL beyond edge" ); -- } -+ } - -- if (planes == 4) { -+ if (planes == 4) { - /* Construct a pixel from the 4 planes of bits for this row */ - int col; - for (col = 0; col < cols; col++) { -@@ -212,21 +213,21 @@ main(argc, argv) - const int b_bit = !bitrow[2][col]; - i = bitrow[3][col]; - -- /* Deal with weird GEM palette - white/black/gray are -- encoded oddly -+ /* Deal with weird GEM palette - white/black/gray are -+ encoded oddly - */ -- if (r_bit == g_bit && g_bit == b_bit) { -+ if (r_bit == g_bit && g_bit == b_bit) { - /* It's black, white, or gray */ -- if (r_bit && i) r = LIGHT; -- else if (r_bit) r = BLACK; -- else if (i) r = MAXVAL; -- else r = DARK; -- g = b = r; -- } else { -+ if (r_bit && i) r = LIGHT; -+ else if (r_bit) r = BLACK; -+ else if (i) r = MAXVAL; -+ else r = DARK; -+ g = b = r; -+ } else { - /* It's one of the twelve colored colors */ - if (!i) { - /* Low intensity */ -- r = r_bit * LIGHT; -+ r = r_bit * LIGHT; - g = g_bit * LIGHT; - b = b_bit * LIGHT; - } else { -@@ -237,21 +238,21 @@ main(argc, argv) - } - } - PPM_ASSIGN(xelrow[col], r, g, b); -- } -- } else { -+ } -+ } else { - int col; -- for (col = 0; col < cols; col++) -+ for (col = 0; col < cols; col++) - PNM_ASSIGN1(xelrow[col], bitrow[0][col]); - } -- while (linerep--) { -- pnm_writepnmrow( stdout, xelrow, cols, MAXVAL, type, 0 ); -- ++row; -- } -- } -+ while (linerep--) { -+ pnm_writepnmrow( stdout, xelrow, cols, MAXVAL, type, 0 ); -+ ++row; -+ } -+ } - pnm_freerow(xelrow); -- pm_close( f ); -- pm_close( stdout ); -- exit(0); -+ pm_close( f ); -+ pm_close( stdout ); -+ exit(0); - } - - -@@ -303,5 +304,3 @@ getinit (file, colsP, rowsP, padrightP, patlenP, planesP) - } - } - -- -- -diff --git a/converter/other/jpegtopnm.c b/converter/other/jpegtopnm.c -index 98552c0..311298c 100644 ---- a/converter/other/jpegtopnm.c -+++ b/converter/other/jpegtopnm.c -@@ -862,6 +862,8 @@ convertImage(FILE * const ofP, +diff -ruNp a/converter/other/jpegtopnm.c b/converter/other/jpegtopnm.c +--- a/converter/other/jpegtopnm.c 2021-06-02 15:53:59.833205640 +0200 ++++ b/converter/other/jpegtopnm.c 2021-06-02 16:16:28.520206914 +0200 +@@ -862,6 +862,8 @@ convertImage(FILE * /* Calculate output image dimensions so we can allocate space */ jpeg_calc_output_dimensions(cinfoP); @@ -359,10 +48,9 @@ index 98552c0..311298c 100644 /* Start decompressor */ jpeg_start_decompress(cinfoP); -diff --git a/converter/other/pbmtopgm.c b/converter/other/pbmtopgm.c -index 817fb5b..8baaa57 100644 ---- a/converter/other/pbmtopgm.c -+++ b/converter/other/pbmtopgm.c +diff -ruNp a/converter/other/pbmtopgm.c b/converter/other/pbmtopgm.c +--- a/converter/other/pbmtopgm.c 2021-06-02 15:53:59.831205621 +0200 ++++ b/converter/other/pbmtopgm.c 2021-06-02 16:17:14.248645808 +0200 @@ -60,6 +60,7 @@ main(int argc, char *argv[]) { @@ -371,10 +59,9 @@ index 817fb5b..8baaa57 100644 maxval = MIN(PGM_OVERALLMAXVAL, width*height); pgm_writepgminit(stdout, cols, rows, maxval, 0) ; -diff --git a/converter/other/pnmtoddif.c b/converter/other/pnmtoddif.c -index b7b942b..52be0e4 100644 ---- a/converter/other/pnmtoddif.c -+++ b/converter/other/pnmtoddif.c +diff -ruNp a/converter/other/pnmtoddif.c b/converter/other/pnmtoddif.c +--- a/converter/other/pnmtoddif.c 2021-06-02 15:53:59.832205630 +0200 ++++ b/converter/other/pnmtoddif.c 2021-06-02 16:18:17.064248709 +0200 @@ -629,6 +629,7 @@ main(int argc, char *argv[]) { switch (PNM_FORMAT_TYPE(format)) { case PBM_TYPE: @@ -391,592 +78,47 @@ index b7b942b..52be0e4 100644 ip.bytes_per_line = 3 * cols; ip.bits_per_pixel = 24; ip.spectral = 5; -diff --git a/converter/other/pnmtojpeg.c b/converter/other/pnmtojpeg.c -index e345831..757d08d 100644 ---- a/converter/other/pnmtojpeg.c -+++ b/converter/other/pnmtojpeg.c -@@ -9,7 +9,7 @@ - This program is by Bryan Henderson on 2000.03.06, but is derived - with permission from the program cjpeg, which is in the Independent - Jpeg Group's JPEG library package. Under the terms of that permission, -- redistribution of this software is restricted as described in the -+ redistribution of this software is restricted as described in the - file README.JPEG. - - Copyright (C) 1991-1998, Thomas G. Lane. -@@ -84,12 +84,12 @@ struct cmdlineInfo { - struct density density; - }; - --static void --interpret_maxmemory (const char * const maxmemory, -- long int * const max_memory_to_use_p) { -+static void -+interpret_maxmemory (const char * const maxmemory, -+ long int * const max_memory_to_use_p) { - long int lval; - char ch; -- -+ - if (maxmemory == NULL) { - *max_memory_to_use_p = -1; /* unspecified */ - } else if (sscanf(maxmemory, "%ld%c", &lval, &ch) < 1) { -@@ -119,9 +119,9 @@ interpret_restart(const char * const restart, - long lval; - char ch; - unsigned int matches; -- -+ - matches= sscanf(restart, "%ld%c", &lval, &ch); -- if (matches == 0) -+ if (matches == 0) - pm_error("Invalid value for the --restart option : '%s'.", - restart); - else { -@@ -160,7 +160,7 @@ interpret_density(const char * const densityString, - int horiz, vert; - - unitName = malloc(strlen(densityString)+1); -- -+ - matched = sscanf(densityString, "%dx%d%s", &horiz, &vert, unitName); - - if (matched < 2) -@@ -178,7 +178,7 @@ interpret_density(const char * const densityString, - densityP->horiz = horiz; - densityP->vert = vert; - -- if (matched < 3) -+ if (matched < 3) - densityP->unit = DEN_UNSPECIFIED; - else { - if (streq(unitName, "dpi") || streq(unitName, "DPI")) -@@ -235,7 +235,7 @@ parseCommandLine(const int argc, char ** argv, - - option_def_index = 0; /* incremented by OPTENTRY */ - OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); -- OPTENT3(0, "quality", OPT_UINT, &cmdlineP->quality, -+ OPTENT3(0, "quality", OPT_UINT, &cmdlineP->quality, - &qualitySpec, 0); - OPTENT3(0, "baseline", OPT_FLAG, NULL, &cmdlineP->force_baseline, 0); - OPTENT3(0, "progressive", OPT_FLAG, NULL, &cmdlineP->progressive, 0); -@@ -250,14 +250,14 @@ parseCommandLine(const int argc, char ** argv, - OPTENT3(0, "qtables", OPT_STRING, &cmdlineP->qtablefile, NULL, 0); - OPTENT3(0, "sample", OPT_STRING, &cmdlineP->sample, NULL, 0); - OPTENT3(0, "scans", OPT_STRING, &cmdlineP->scans, NULL, 0); -- OPTENT3(0, "smooth", OPT_UINT, &cmdlineP->smoothing_factor, -+ OPTENT3(0, "smooth", OPT_UINT, &cmdlineP->smoothing_factor, - &smoothSpec, 0); - OPTENT3(0, "optimize", OPT_FLAG, NULL, &cmdlineP->optimize, 0); - OPTENT3(0, "optimise", OPT_FLAG, NULL, &cmdlineP->optimize, 0); - OPTENT3(0, "restart", OPT_STRING, &restart, NULL, 0); - OPTENT3(0, "comment", OPT_STRING, &cmdlineP->comment, NULL, 0); - OPTENT3(0, "exif", OPT_STRING, &cmdlineP->exif_filespec, NULL, 0); -- OPTENT3(0, "density", OPT_STRING, &density, -+ OPTENT3(0, "density", OPT_STRING, &density, - &cmdlineP->density_spec, 0); - - /* Set the defaults */ -@@ -295,7 +295,7 @@ parseCommandLine(const int argc, char ** argv, - cmdlineP->input_filespec = strdup("-"); /* he wants stdin */ - else if (argc_parse - 1 == 1) - cmdlineP->input_filespec = strdup(argv_parse[1]); -- else -+ else - pm_error("Too many arguments. The only argument accepted " - "is the input file specification."); - if (dctval == NULL) -@@ -314,15 +314,15 @@ parseCommandLine(const int argc, char ** argv, - interpret_maxmemory(maxmemory, &cmdlineP->max_memory_to_use); - interpret_restart(restart, &cmdlineP->restart_value, - &cmdlineP->restart_unit); -- if (cmdlineP->density_spec) -+ if (cmdlineP->density_spec) - interpret_density(density, &cmdlineP->density); -- -+ - if (cmdlineP->smoothing_factor > 100) - pm_error("Smoothing factor %d is greater than 100 (%%).", - cmdlineP->smoothing_factor); - - if (streq(cmdlineP->input_filespec, "=") && -- cmdlineP->exif_filespec && -+ cmdlineP->exif_filespec && - streq(cmdlineP->exif_filespec, "-")) - - pm_error("Cannot have both input image and exif header be from " -@@ -336,7 +336,7 @@ parseCommandLine(const int argc, char ** argv, - - static void - report_compressor(const struct jpeg_compress_struct cinfo) { -- -+ - if (cinfo.scan_info == NULL) - pm_message("No scan script is being used"); - else { -@@ -346,7 +346,7 @@ report_compressor(const struct jpeg_compress_struct cinfo) { - for (i = 0; i < cinfo.num_scans; i++) { - int j; - pm_message(" Scan %2d: Ss=%2d Se=%2d Ah=%2d Al=%2d " -- "%d components", -+ "%d components", - i, - cinfo.scan_info[i].Ss, - cinfo.scan_info[i].Se, -@@ -364,11 +364,11 @@ report_compressor(const struct jpeg_compress_struct cinfo) { - - - static void --setup_jpeg_source_parameters(struct jpeg_compress_struct * const cinfoP, -- int const width, int const height, -+setup_jpeg_source_parameters(struct jpeg_compress_struct * const cinfoP, -+ int const width, int const height, - int const format) { - /*---------------------------------------------------------------------------- -- Set up in the compressor descriptor *cinfoP the description of the -+ Set up in the compressor descriptor *cinfoP the description of the - source image as required by the compressor. - -----------------------------------------------------------------------------*/ - -@@ -379,7 +379,7 @@ setup_jpeg_source_parameters(struct jpeg_compress_struct * const cinfoP, - cinfoP->input_components = 1; - break; - case PPM_TYPE: -- cinfoP->in_color_space = JCS_RGB; -+ cinfoP->in_color_space = JCS_RGB; - cinfoP->input_components = 3; - break; - default: -@@ -391,7 +391,7 @@ setup_jpeg_source_parameters(struct jpeg_compress_struct * const cinfoP, - - - static void --setup_jpeg_density(struct jpeg_compress_struct * const cinfoP, -+setup_jpeg_density(struct jpeg_compress_struct * const cinfoP, - struct density const density) { - /*---------------------------------------------------------------------------- - Set up in the compressor descriptor *cinfoP the density information -@@ -402,7 +402,7 @@ setup_jpeg_density(struct jpeg_compress_struct * const cinfoP, - case DEN_DOTS_PER_INCH: cinfoP->density_unit = 1; break; - case DEN_DOTS_PER_CM: cinfoP->density_unit = 2; break; - } -- -+ - cinfoP->X_density = density.horiz; - cinfoP->Y_density = density.vert; - } -@@ -411,7 +411,7 @@ setup_jpeg_density(struct jpeg_compress_struct * const cinfoP, - - /*---------------------------------------------------------------------------- - The functions below here are essentially the file rdswitch.c from -- the JPEG library. They perform the functions specified by the following -+ the JPEG library. They perform the functions specifed by the following - pnmtojpeg options: - - -qtables file Read quantization tables from text file -@@ -426,7 +426,7 @@ text_getc (FILE * file) - /* A comment/newline sequence is returned as a newline */ - { - register int ch; -- -+ - ch = getc(file); - if (ch == '#') { - do { -@@ -454,12 +454,12 @@ readTextInteger(FILE * const fileP, - -----------------------------------------------------------------------------*/ - int ch; - boolean retval; -- -+ - /* Skip any leading whitespace, detect EOF */ - do { - ch = text_getc(fileP); - } while (isspace(ch)); -- -+ - if (!isdigit(ch)) - retval = FALSE; - else { -@@ -554,7 +554,7 @@ read_scan_script(j_compress_ptr const cinfo, - ncomps = 1; - while (termchar == ' ') { - if (ncomps >= MAX_COMPS_IN_SCAN) { -- pm_message("Too many components in one scan in file %s", -+ pm_message("Too many components in one scan in file %s", - filename); - fclose(fp); - return FALSE; -@@ -603,10 +603,14 @@ read_scan_script(j_compress_ptr const cinfo, - /* Stash completed scan list in cinfo structure. NOTE: in - this program, JPOOL_IMAGE is the right lifetime for this - data, but if you want to compress multiple images you'd -- want JPOOL_PERMANENT. -+ want JPOOL_PERMANENT. +diff -ruNp a/converter/other/pnmtojpeg.c b/converter/other/pnmtojpeg.c +--- a/converter/other/pnmtojpeg.c 2021-06-02 15:53:59.835205659 +0200 ++++ b/converter/other/pnmtojpeg.c 2021-06-02 19:57:44.413225834 +0200 +@@ -606,7 +606,11 @@ read_scan_script(j_compress_ptr const ci + want JPOOL_PERMANENT. */ const unsigned int scan_info_size = nscans * sizeof(jpeg_scan_info); - jpeg_scan_info * const scan_info = + const jpeg_scan_info * scan_info; -+ ++ + overflow2(nscans, sizeof(jpeg_scan_info)); -+ ++ + scan_info = (jpeg_scan_info *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, scan_info_size); -@@ -656,7 +660,7 @@ read_quant_tables (j_compress_ptr cinfo, char * filename, - if (tblno >= NUM_QUANT_TBLS) { - pm_message("Too many tables in file %s", filename); - error = TRUE; -- } else { -+ } else { - unsigned int table[DCTSIZE2]; - unsigned int i; - -@@ -686,7 +690,7 @@ read_quant_tables (j_compress_ptr cinfo, char * filename, - fclose(fp); - retval = !error; - } -- -+ - return retval; - } - -@@ -717,7 +721,7 @@ set_quant_slots (j_compress_ptr cinfo, char *arg) - return FALSE; - } - cinfo->comp_info[ci].quant_tbl_no = val; -- while (*arg && *arg++ != ',') -+ while (*arg && *arg++ != ',') - /* advance to next segment of arg string */ - ; - } else { -@@ -747,7 +751,7 @@ set_sample_factors (j_compress_ptr cinfo, char *arg) - if ((ch1 != 'x' && ch1 != 'X') || ch2 != ',') /* syntax check */ - return FALSE; - if (val1 <= 0 || val1 > 4) { -- pm_message("Invalid sampling factor: %d. " -+ pm_message("Invalid sampling factor: %d. " - "JPEG sampling factors must be 1..4", val1); - return FALSE; - } -@@ -758,11 +762,11 @@ set_sample_factors (j_compress_ptr cinfo, char *arg) - } - cinfo->comp_info[ci].h_samp_factor = val1; - cinfo->comp_info[ci].v_samp_factor = val2; -- while (*arg && *arg++ != ',') -+ while (*arg && *arg++ != ',') - /* advance to next segment of arg string */ - ; - } else { -- /* reached end of parameter, set remaining components -+ /* reached end of parameter, set remaining components - to 1x1 sampling */ - cinfo->comp_info[ci].h_samp_factor = 1; - cinfo->comp_info[ci].v_samp_factor = 1; -@@ -776,13 +780,13 @@ set_sample_factors (j_compress_ptr cinfo, char *arg) - static void - setup_jpeg(struct jpeg_compress_struct * const cinfoP, - struct jpeg_error_mgr * const jerrP, -- struct cmdlineInfo const cmdline, -+ struct cmdlineInfo const cmdline, - int const width, - int const height, - pixval const maxval, - int const input_fmt, - FILE * const output_file) { -- -+ - int quality; - int q_scale_factor; - -@@ -794,14 +798,14 @@ setup_jpeg(struct jpeg_compress_struct * const cinfoP, - - jpeg_set_defaults(cinfoP); - -- cinfoP->data_precision = BITS_IN_JSAMPLE; -+ cinfoP->data_precision = BITS_IN_JSAMPLE; - /* we always rescale data to this */ - cinfoP->image_width = (unsigned int) width; - cinfoP->image_height = (unsigned int) height; - - cinfoP->arith_code = cmdline.arith_code; - cinfoP->dct_method = cmdline.dct_method; -- if (cmdline.trace_level == 0 && cmdline.verbose) -+ if (cmdline.trace_level == 0 && cmdline.verbose) - cinfoP->err->trace_level = 1; - else cinfoP->err->trace_level = cmdline.trace_level; - if (cmdline.grayscale) -@@ -822,26 +826,26 @@ setup_jpeg(struct jpeg_compress_struct * const cinfoP, - quality = cmdline.quality; - q_scale_factor = jpeg_quality_scaling(cmdline.quality); - } -- if (cmdline.smoothing_factor != -1) -+ if (cmdline.smoothing_factor != -1) - cinfoP->smoothing_factor = cmdline.smoothing_factor; - - /* Set quantization tables for selected quality. */ - /* Some or all may be overridden if user specified --qtables. */ - jpeg_set_quality(cinfoP, quality, cmdline.force_baseline); -- -+ - if (cmdline.qtablefile != NULL) { - if (! read_quant_tables(cinfoP, cmdline.qtablefile, -- q_scale_factor, cmdline.force_baseline)) -+ q_scale_factor, cmdline.force_baseline)) - pm_error("Can't use quantization table file '%s'.", - cmdline.qtablefile); - } -- -+ - if (cmdline.qslots != NULL) { - if (! set_quant_slots(cinfoP, cmdline.qslots)) -- pm_error("Bad quantization-table-selectors parameter string '%s'.", -+ pm_error("Bad quantization-table-selectors parameter string '%s'.", - cmdline.qslots); - } -- -+ - if (cmdline.sample != NULL) { - if (! set_sample_factors(cinfoP, cmdline.sample)) - pm_error("Bad sample-factors parameters string '%s'.", -@@ -878,7 +882,7 @@ write_exif_header(struct jpeg_compress_struct * const cinfoP, - /*---------------------------------------------------------------------------- - Generate an APP1 marker in the JFIF output that is an Exif header. - -- The contents of the Exif header are in the file with filespec -+ The contents of the Exif header are in the file with filespec - 'exif_filespec' (file spec and contents are not validated). - - exif_filespec = "-" means Standard Input. -@@ -888,7 +892,7 @@ write_exif_header(struct jpeg_compress_struct * const cinfoP, - -----------------------------------------------------------------------------*/ - FILE * exif_file; - unsigned short length; -- -+ - exif_file = pm_openr(exif_filespec); - - pm_readbigshort(exif_file, (short*)&length); -@@ -900,7 +904,7 @@ write_exif_header(struct jpeg_compress_struct * const cinfoP, - else { - unsigned char * exif_data; - size_t rc; -- size_t const data_length = length - 2; -+ size_t const data_length = length - 2; - /* Subtract 2 byte length field*/ - - assert(data_length > 0); -@@ -917,16 +921,16 @@ write_exif_header(struct jpeg_compress_struct * const cinfoP, - "%u bytes of data, read only %u", - (unsigned)data_length, (unsigned)rc); - -- jpeg_write_marker(cinfoP, JPEG_APP0+1, -+ jpeg_write_marker(cinfoP, JPEG_APP0+1, - (const JOCTET *) exif_data, data_length); - - free(exif_data); - } -- -+ - pm_close(exif_file); - } - -- -+ - - static void - compute_rescaling_array(JSAMPLE ** const rescale_p, const pixval maxval, -@@ -938,9 +942,11 @@ compute_rescaling_array(JSAMPLE ** const rescale_p, const pixval maxval, +@@ -938,6 +942,9 @@ compute_rescaling_array(JSAMPLE ** const const long half_maxval = maxval / 2; long val; + overflow_add(maxval, 1); + overflow2(maxval+1, sizeof(JSAMPLE)); ++ *rescale_p = (JSAMPLE *) (cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_IMAGE, -- (size_t) (((long) maxval + 1L) * -+ (size_t) (((long) maxval + 1L) * - sizeof(JSAMPLE))); - for (val = 0; val <= maxval; val++) { - /* The multiplication here must be done in 32 bits to avoid overflow */ -@@ -951,9 +957,9 @@ compute_rescaling_array(JSAMPLE ** const rescale_p, const pixval maxval, - - - static void --translate_row(const pixel pnm_buffer[], -- JSAMPLE jpeg_buffer[], -- int const width, -+translate_row(const pixel pnm_buffer[], -+ JSAMPLE jpeg_buffer[], -+ int const width, - int const input_components, - const JSAMPLE translate[]) { - /*---------------------------------------------------------------------------- -@@ -971,16 +977,16 @@ translate_row(const pixel pnm_buffer[], - - switch (input_components) { - case 1: -- for (column = 0; column < width; column++) -+ for (column = 0; column < width; column++) - jpeg_buffer[column] = translate[(int)PNM_GET1(pnm_buffer[column])]; - break; - case 3: - for (column = 0; column < width; column++) { -- jpeg_buffer[column*3+0] = -+ jpeg_buffer[column*3+0] = - translate[(int)PPM_GETR(pnm_buffer[column])]; -- jpeg_buffer[column*3+1] = -+ jpeg_buffer[column*3+1] = - translate[(int)PPM_GETG(pnm_buffer[column])]; -- jpeg_buffer[column*3+2] = -+ jpeg_buffer[column*3+2] = - translate[(int)PPM_GETB(pnm_buffer[column])]; - } - break; -@@ -1000,44 +1006,45 @@ convert_scanlines(struct jpeg_compress_struct * const cinfo_p, - int const input_fmt, - JSAMPLE xlate_table[]){ - /*---------------------------------------------------------------------------- -- Read scan lines from the input file, which is already opened in the -- netpbm library sense and ready for reading, and write them to the -+ Read scan lines from the input file, which is already opened in the -+ netpbm library sense and ready for reading, and write them to the - output JPEG object. Translate the pnm sample values to JPEG sample - values through the thable xlate_table[]. - -----------------------------------------------------------------------------*/ -- xel * pnm_buffer; -+ xel * pnm_buffer; - /* contains the row of the input image currently being processed, - in pnm_readpnmrow format - */ - JSAMPARRAY buffer; -- /* Row 0 of this array contains the row of the output image currently -+ /* Row 0 of this array contains the row of the output image currently - being processed, in JPEG compressor input format. The array only - has that one row. + (size_t) (((long) maxval + 1L) * +@@ -1016,6 +1023,7 @@ convert_scanlines(struct jpeg_compress_s */ /* Allocate the libpnm output and compressor input buffers */ + overflow2(cinfo_p->image_width, cinfo_p->input_components); buffer = (*cinfo_p->mem->alloc_sarray) ((j_common_ptr) cinfo_p, JPOOL_IMAGE, -- (unsigned int) cinfo_p->image_width * cinfo_p->input_components, -+ (unsigned int) cinfo_p->image_width * cinfo_p->input_components, - (unsigned int) 1); -- -+ - pnm_buffer = pnm_allocrow(cinfo_p->image_width); - - while (cinfo_p->next_scanline < cinfo_p->image_height) { -- if (cinfo_p->err->trace_level > 1) -+ if (cinfo_p->err->trace_level > 1) - pm_message("Converting Row %d...", cinfo_p->next_scanline); -- pnm_readpnmrow(input_file, pnm_buffer, cinfo_p->image_width, -+ pnm_readpnmrow(input_file, pnm_buffer, cinfo_p->image_width, - maxval, input_fmt); -- translate_row(pnm_buffer, buffer[0], -+ translate_row(pnm_buffer, buffer[0], - cinfo_p->image_width, cinfo_p->input_components, - xlate_table); - jpeg_write_scanlines(cinfo_p, buffer, 1); -- if (cinfo_p->err->trace_level > 1) -+ if (cinfo_p->err->trace_level > 1) - pm_message("Done."); - } - - pnm_freerow(pnm_buffer); -- /* Don't worry about the compressor input buffer; it gets freed -+ /* Don't worry about the compressor input buffer; it gets freed - automatically - */ - } -@@ -1053,11 +1060,11 @@ main(int argc, - struct jpeg_error_mgr jerr; - FILE * input_file; - FILE * output_file; -- int height; -+ int height; - /* height of the input image in rows, as specified by its header */ -- int width; -+ int width; - /* width of the input image in columns, as specified by its header */ -- pixval maxval; -+ pixval maxval; - /* maximum value of an input pixel component, as specified by header */ - int input_fmt; - /* The input format, as determined by its header. */ -@@ -1081,7 +1088,7 @@ main(int argc, - if (cmdline.verbose) { - pm_message("Input file has format %c%c.\n" - "It has %d rows of %d columns of pixels " -- "with max sample value of %d.", -+ "with max sample value of %d.", - (char) (input_fmt/256), (char) (input_fmt % 256), - height, width, maxval); - } -@@ -1091,13 +1098,13 @@ main(int argc, - - compute_rescaling_array(&rescale, maxval, cinfo); - -- if (cmdline.comment) -- jpeg_write_marker(&cinfo, JPEG_COM, (const JOCTET *) cmdline.comment, -+ if (cmdline.comment) -+ jpeg_write_marker(&cinfo, JPEG_COM, (const JOCTET *) cmdline.comment, - strlen(cmdline.comment)); - - if (cmdline.exif_filespec) - write_exif_header(&cinfo, cmdline.exif_filespec); -- -+ - /* Translate and copy over the actual scanlines */ - convert_scanlines(&cinfo, input_file, maxval, input_fmt, rescale); - -@@ -1110,10 +1117,7 @@ main(int argc, - pm_close(input_file); - - /* Program may have exited with non-zero completion code via -- various function calls above. -+ various function calls above. - */ - return jerr.num_warnings > 0 ? EXIT_WARNING : EXIT_SUCCESS; - } -- -- -- -diff --git a/converter/other/pnmtops.c b/converter/other/pnmtops.c -index 45d856d..09c28d5 100644 ---- a/converter/other/pnmtops.c -+++ b/converter/other/pnmtops.c -@@ -125,8 +125,8 @@ static bool verbose; - - - static void --parseDpi(const char * const dpiOpt, -- unsigned int * const dpiXP, -+parseDpi(const char * const dpiOpt, -+ unsigned int * const dpiXP, - unsigned int * const dpiYP) { - - char *dpistr2; -@@ -253,9 +253,9 @@ parseCommandLine(int argc, const char ** argv, - OPTENT3(0, "showpage", OPT_FLAG, NULL, &showpage, 0); - OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); - OPTENT3(0, "debug", OPT_FLAG, NULL, &cmdlineP->debug, 0); -- OPTENT3(0, "level", OPT_UINT, &cmdlineP->level, -+ OPTENT3(0, "level", OPT_UINT, &cmdlineP->level, - &cmdlineP->levelSpec, 0); -- -+ - opt.opt_table = option_def; - opt.short_allowed = FALSE; - opt.allowNegNum = FALSE; -@@ -293,18 +293,22 @@ parseCommandLine(int argc, const char ** argv, - + (unsigned int) cinfo_p->image_width * cinfo_p->input_components, +diff -ruNp a/converter/other/pnmtops.c b/converter/other/pnmtops.c +--- a/converter/other/pnmtops.c 2021-06-02 15:53:59.835205659 +0200 ++++ b/converter/other/pnmtops.c 2021-06-02 20:02:06.055502227 +0200 +@@ -294,17 +294,21 @@ parseCommandLine(int argc, const char ** validateCompDimension(width, 72, "-width value"); validateCompDimension(height, 72, "-height value"); -- -+ + + overflow2(width, 72); cmdlineP->width = width * 72; + overflow2(height, 72); @@ -996,616 +138,33 @@ index 45d856d..09c28d5 100644 cmdlineP->imageheight = imageheight * 72; } else -@@ -318,7 +322,7 @@ parseCommandLine(int argc, const char ** argv, - if (cmdlineP->bitspersampleSpec) - validateBps_1_2_4_8_12(cmdlineP->bitspersample); - -- if (argc-1 == 0) -+ if (argc-1 == 0) - cmdlineP->inputFileName = "-"; - else if (argc-1 != 1) - pm_error("Program takes zero or one argument (filename). You " -@@ -326,7 +330,7 @@ parseCommandLine(int argc, const char ** argv, - else - cmdlineP->inputFileName = argv[1]; - -- free(option_def); -+ free(option_def); - } - - -@@ -432,7 +436,7 @@ addToPidList(pid_t * const pidList, - /*=========================================================================== - The output encoder - ===========================================================================*/ -- -+ - enum OutputType {AsciiHex, Ascii85}; - - typedef struct { -@@ -453,7 +457,7 @@ bytesPerRow (unsigned int const cols, - -----------------------------------------------------------------------------*/ - unsigned int retval; - -- assert(bitsPerSample==1 || bitsPerSample==2 || bitsPerSample==4 || -+ assert(bitsPerSample==1 || bitsPerSample==2 || bitsPerSample==4 || - bitsPerSample==8 || bitsPerSample==12); - - switch (bitsPerSample) { -@@ -519,7 +523,7 @@ typedef void FilterFn(FILE * const ifP, - /* This is a function that can be run in a separate process to do - arbitrary modifications of the raster data stream. - */ -- -+ - - - #ifndef NOFLATE -@@ -545,7 +549,7 @@ initZlib(z_stream * const strmP) { - - static FilterFn flateFilter; - --static void -+static void - flateFilter(FILE * const ifP, - FILE * const ofP, - OutputEncoder * const oeP) { -@@ -600,12 +604,12 @@ flateFilter(FILE * const ifP, - } while (flush != Z_FINISH); - - free(in); -- free(out); -+ free(out); - deflateEnd(&strm); - fclose(ifP); - fclose(ofP); - #else -- assert(false); /* filter is never used */ -+ assert(false); /* filter is never used */ - #endif - } - -@@ -687,7 +691,7 @@ asciiHexFilter(FILE * const ifP, - unsigned int i; - - for (i = 0; i < readCt; ++i) { -- int const item = inbuff[i]; -+ int const item = inbuff[i]; - outbuff[i*2] = hexits[item >> 4]; - outbuff[i*2+1] = hexits[item & 15]; - } -@@ -736,7 +740,7 @@ ascii85Filter(FILE * const ifP, - ++outcount; - count = 0; - } else if (count == 4) { -- outbuff[4] = value % 85 + 33; value/=85; -+ outbuff[4] = value % 85 + 33; value/=85; - outbuff[3] = value % 85 + 33; value/=85; - outbuff[2] = value % 85 + 33; value/=85; - outbuff[1] = value % 85 + 33; -@@ -745,7 +749,7 @@ ascii85Filter(FILE * const ifP, - writeFileChar(outbuff, count + 1, "ASCII 85 filter", ofP); - - count = value = 0; -- outcount += 5; -+ outcount += 5; - } - - if (outcount > 75) { -@@ -794,9 +798,9 @@ closeAllBut(int const saveFd0, - 'saveFd1', and 'saveFd2'. - - This is helpful because even if this process doesn't touch other file -- descriptors, its very existence will keep the files open. -+ desriptors, its very existence will keep the files open. - -----------------------------------------------------------------------------*/ -- -+ - /* Unix provides no good way to do this; we just assume file descriptors - above 9 are not used in this program; Caller must ensure that is true. - */ -@@ -829,15 +833,15 @@ spawnFilter(FILE * const ofP, - pid_t rc; - - makePipe(pipeFd); -- -+ - rc = fork(); - - if (rc == (pid_t)-1) -- pm_error("fork() of filter process failed. errno=%d (%s)", -+ pm_error("fork() of filter process failed. errno=%d (%s)", - errno, strerror(errno)); - else if (rc == 0) { - /* This is the child process */ -- -+ - FILE * ifP; - - ifP = fdopen(pipeFd[0], "r"); -@@ -892,11 +896,11 @@ addFilter(const char * const description, - pid_t pid; - - spawnFilter(oldFeedFileP, filter, oeP, &newFeedFileP, &pid); -- -+ - if (verbose) - pm_message("%s filter spawned: pid %u", - description, (unsigned)pid); -- -+ - if (debug) { - int const outFd = fileno(oldFeedFileP); - int const supplyFd = fileno(newFeedFileP); -@@ -971,7 +975,7 @@ waitForChildren(const pid_t * const pidList) { - signal is the default), the process' children do not become - zombies. Consequently, waitpid() always fails with ECHILD - but - nonetheless waits for the child to exit. -- -+ - We expect the process not to have the action for SIGCHLD set that - way. - */ -@@ -1004,9 +1008,9 @@ waitForChildren(const pid_t * const pidList) { - - - static void --validateComputableBoundingBox(float const scols, -+validateComputableBoundingBox(float const scols, - float const srows, -- float const llx, -+ float const llx, - float const lly) { - - float const bbWidth = llx + scols + 0.5; -@@ -1036,22 +1040,22 @@ warnUserRescaling(float const scale) { - - - static void --computeImagePosition(int const dpiX, -- int const dpiY, -- int const icols, -+computeImagePosition(int const dpiX, -+ int const dpiY, -+ int const icols, - int const irows, - bool const mustturn, - bool const canturn, - bool const center, -- int const pagewid, -- int const pagehgt, -+ int const pagewid, -+ int const pagehgt, - float const requestedScale, - float const imagewidth, - float const imageheight, - bool const equalpixels, - float * const scolsP, - float * const srowsP, -- float * const llxP, -+ float * const llxP, - float * const llyP, - bool * const turnedP ) { - /*---------------------------------------------------------------------------- -@@ -1091,7 +1095,7 @@ computeImagePosition(int const dpiX, - rotated if applicable - */ - bool shouldturn; /* The image fits the page better if we turn it */ -- -+ - if (icols > irows && pagehgt > pagewid) - shouldturn = TRUE; - else if (irows > icols && pagewid > pagehgt) -@@ -1120,27 +1124,27 @@ computeImagePosition(int const dpiX, - scale = (float) imagewidth/cols; - else - scale = MIN((float)imagewidth/cols, (float)imageheight/rows); -- -+ - *scolsP = cols*scale; - *srowsP = rows*scale; - } else { - /* He didn't give us a bounding box for the image so figure - out output image size from other inputs. - */ -- const int devpixX = dpiX / 72.0 + 0.5; -- const int devpixY = dpiY / 72.0 + 0.5; -+ const int devpixX = dpiX / 72.0 + 0.5; -+ const int devpixY = dpiY / 72.0 + 0.5; - /* How many device pixels make up 1/72 inch, rounded to - nearest integer */ - const float pixfacX = 72.0 / dpiX * devpixX; /* 1, approx. */ - const float pixfacY = 72.0 / dpiY * devpixY; /* 1, approx. */ - float scale; - -- scale = MIN(requestedScale, -+ scale = MIN(requestedScale, - MIN((float)pagewid/cols, (float)pagehgt/rows)); - - *scolsP = scale * cols * pixfacX; - *srowsP = scale * rows * pixfacY; -- -+ - if (scale != requestedScale) - warnUserRescaling(scale); - -@@ -1236,7 +1240,7 @@ defineReadstring(bool const rle) { - static void - setupReadstringNative(bool const rle, - bool const color, -- unsigned int const icols, -+ unsigned int const icols, - unsigned int const bitsPerSample) { - /*---------------------------------------------------------------------------- - Write to Standard Output statements to define /readstring and also -@@ -1247,7 +1251,7 @@ setupReadstringNative(bool const rle, - /* Size of row buffer, padded up to byte boundary. */ - - defineReadstring(rle); -- -+ - if (color) { - printf("/rpicstr %d string def\n", bytesPerRow); - printf("/gpicstr %d string def\n", bytesPerRow); -@@ -1266,18 +1270,18 @@ putFilters(unsigned int const postscriptLevel, - bool const color) { - - assert(postscriptLevel > 1); -- -+ - /* We say to decode flate, then rle, so Caller must ensure it encodes - rel, then flate. - */ - - if (ascii85) - printf("/ASCII85Decode filter "); -- else -+ else - printf("/ASCIIHexDecode filter "); - if (flate) - printf("/FlateDecode filter "); -- if (rle) -+ if (rle) - printf("/RunLengthDecode filter "); - } - -@@ -1311,7 +1315,7 @@ putSetup(unsigned int const dictSize, - if (dictSize > 0) - /* inputf {r,g,b,}pictsr readstring readrlestring rlestring */ - printf("%u dict begin\n", dictSize); -- -+ - if (!psFilter) - setupReadstringNative(rle, color, icols, bitsPerSample); - -@@ -1353,7 +1357,7 @@ putInitPsFilter(unsigned int const postscriptLevel, - putFilters(postscriptLevel, rle, flate, ascii85, color); - - putImage(filterTrue, color); -- -+ - printf(" } exec"); - } - -@@ -1365,7 +1369,7 @@ putInitReadstringNative(bool const color) { - bool const filterFalse = FALSE; - - putReadstringNative(color); -- -+ - putImage(filterFalse, color); - } - -@@ -1373,18 +1377,18 @@ putInitReadstringNative(bool const color) { - - static void - putInit(unsigned int const postscriptLevel, -- char const name[], -- int const icols, -- int const irows, -- float const scols, -+ char const name[], -+ int const icols, -+ int const irows, -+ float const scols, - float const srows, -- float const llx, -+ float const llx, - float const lly, - int const bitsPerSample, -- int const pagewid, -+ int const pagewid, - int const pagehgt, -- bool const color, -- bool const turned, -+ bool const color, -+ bool const turned, - bool const rle, - bool const flate, - bool const ascii85, -@@ -1438,7 +1442,7 @@ putInit(unsigned int const postscriptLevel, - - - static void --putEnd(bool const showpage, -+putEnd(bool const showpage, - bool const psFilter, - bool const ascii85, - unsigned int const dictSize, -@@ -1486,7 +1490,7 @@ validateBpsRequest(unsigned int const bitsPerSampleReq, - "-psfilter, the maximum is 8", bitsPerSampleReq); - } - -- -+ - - static unsigned int - bpsFromInput(unsigned int const bitsRequiredByMaxval, -@@ -1553,7 +1557,7 @@ warnUserAboutReducedDepth(unsigned int const bitsGot, - - static void - computeDepth(xelval const inputMaxval, -- unsigned int const postscriptLevel, -+ unsigned int const postscriptLevel, - bool const psFilter, - unsigned int const bitsPerSampleReq, - unsigned int * const bitsPerSampleP) { -@@ -1584,7 +1588,7 @@ computeDepth(xelval const inputMaxval, - "%u bits per sample, so maxval = %u", - inputMaxval, *bitsPerSampleP, psMaxval); - } --} -+} - - - -@@ -1643,7 +1647,7 @@ ba_add(BitAccumulator * const baP, - /*---------------------------------------------------------------------------- - Combine bit sequences that do not fit into a byte. - -- Used when bitsPerSample =1, 2, 4. -+ Used when bitsPerSample =1, 2, 4. - Logic also works for bitsPerSample = 8, 16. - - The accumulator, baP->value is unsigned int (usually 32 bits), but -@@ -1725,7 +1729,7 @@ flushOutput(BitAccumulator * const baP, - - convertRowNative and convertRowPsFilter are the general converters. - They are quite similar, the differences being: -- (1) Native output separates the color planes: -+ (1) Native output separates the color planes: - (RRR...RRR GGG...GGG BBB...BBB), - whereas psFilter does not: - (RGB RGB RGB RGB ......... RGB). -@@ -1765,10 +1769,10 @@ convertRowPbm(struct pam * const pamP, - - - static void --convertRowNative(struct pam * const pamP, -- tuple * tuplerow, -+convertRowNative(struct pam * const pamP, -+ tuple * tuplerow, - unsigned int const bitsPerSample, -- FILE * const fP) { -+ FILE * const fP) { - - unsigned int const psMaxval = pm_bitstomaxval(bitsPerSample); - -@@ -1795,7 +1799,7 @@ static void - convertRowPsFilter(struct pam * const pamP, - tuple * tuplerow, - unsigned int const bitsPerSample, -- FILE * const fP) { -+ FILE * const fP) { - - unsigned int const psMaxval = pm_bitstomaxval(bitsPerSample); - -@@ -1828,7 +1832,7 @@ selectPostscriptLevel(bool const levelIsGiven, - bool const psFilter, - unsigned int * const postscriptLevelP) { - -- unsigned int const maxPermittedLevel = -+ unsigned int const maxPermittedLevel = - levelIsGiven ? levelGiven : UINT_MAX; - unsigned int minPossibleLevel; - -@@ -1877,7 +1881,7 @@ convertRaster(struct pam * const inpamP, - Read the raster described by *inpamP, and write a bit stream of samples - to *fP. This stream has to be compressed and converted to text before it - can be part of a Postscript program. -- -+ - 'psFilter' means to do the conversion using built in Postscript filters, as - opposed to our own filters via /readstring. - -@@ -1897,7 +1901,7 @@ convertRaster(struct pam * const inpamP, - } else { - tuple *tuplerow; - unsigned int row; -- -+ - tuplerow = pnm_allocpamrow(inpamP); - - for (row = 0; row < inpamP->height; ++row) { -@@ -1920,31 +1924,31 @@ convertRaster(struct pam * const inpamP, - pipe but this program's output, then we don't want it closed when the - filter terminates because we'll need it to be open for the next image - the program converts (with a whole new chain of filters). -- -- To prevent the program output file from getting closed, we pass a -+ -+ To prevent the progam output file from getting closed, we pass a - duplicate of it to spawnFilters() and keep the original open. - */ - - - - static void --convertPage(FILE * const ifP, -- int const turnflag, -- int const turnokflag, -+convertPage(FILE * const ifP, -+ int const turnflag, -+ int const turnokflag, - bool const psFilter, -- bool const rle, -+ bool const rle, - bool const flate, - bool const ascii85, - bool const setpage, - bool const showpage, -- bool const center, -+ bool const center, - float const scale, -- int const dpiX, -- int const dpiY, -- int const pagewid, -+ int const dpiX, -+ int const dpiY, -+ int const pagewid, - int const pagehgt, -- int const imagewidth, -- int const imageheight, -+ int const imagewidth, -+ int const imageheight, - bool const equalpixels, - unsigned int const bitsPerSampleReq, - char const name[], -@@ -1952,7 +1956,7 @@ convertPage(FILE * const ifP, - bool const vmreclaim, - bool const levelIsGiven, - unsigned int const levelGiven) { -- -+ - struct pam inpam; - float scols, srows; - float llx, lly; -@@ -1960,7 +1964,7 @@ convertPage(FILE * const ifP, - bool color; - unsigned int postscriptLevel; - unsigned int bitsPerSample; -- unsigned int dictSize; -+ unsigned int dictSize; - /* Size of Postscript dictionary we should define */ - OutputEncoder oe; - pid_t filterPidList[MAX_FILTER_CT + 1]; -@@ -1974,19 +1978,19 @@ convertPage(FILE * const ifP, - pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); - - validateCompDimension(inpam.width, 16, "Input image width"); -- -+ - if (!STRSEQ(inpam.tuple_type, PAM_PBM_TUPLETYPE) && - !STRSEQ(inpam.tuple_type, PAM_PGM_TUPLETYPE) && - !STRSEQ(inpam.tuple_type, PAM_PPM_TUPLETYPE)) - pm_error("Unrecognized tuple type %s. This program accepts only " -- "PBM, PGM, PPM, and equivalent PAM input images", -+ "PBM, PGM, PPM, and equivalent PAM input images", - inpam.tuple_type); - - color = STRSEQ(inpam.tuple_type, PAM_PPM_TUPLETYPE); -- -- selectPostscriptLevel(levelIsGiven, levelGiven, color, -+ -+ selectPostscriptLevel(levelIsGiven, levelGiven, color, - dict, flate, ascii85, psFilter, &postscriptLevel); -- -+ - if (color) - pm_message("generating color Postscript program."); - -@@ -1996,16 +2000,16 @@ convertPage(FILE * const ifP, - /* In positioning/scaling the image, we treat the input image as if - it has a density of 72 pixels per inch. - */ -- computeImagePosition(dpiX, dpiY, inpam.width, inpam.height, -+ computeImagePosition(dpiX, dpiY, inpam.width, inpam.height, - turnflag, turnokflag, center, - pagewid, pagehgt, scale, imagewidth, imageheight, - equalpixels, - &scols, &srows, &llx, &lly, &turned); - - determineDictionaryRequirement(dict, psFilter, &dictSize); -- -- putInit(postscriptLevel, name, inpam.width, inpam.height, -- scols, srows, llx, lly, bitsPerSample, -+ -+ putInit(postscriptLevel, name, inpam.width, inpam.height, -+ scols, srows, llx, lly, bitsPerSample, - pagewid, pagehgt, color, - turned, rle, flate, ascii85, setpage, psFilter, dictSize); - -@@ -2017,7 +2021,7 @@ convertPage(FILE * const ifP, - /* spawnFilters() closes this. See FILE MANAGEMENT above */ - - spawnFilters(filterChainOfP, &oe, &feedFileP, filterPidList); -- -+ - convertRaster(&inpam, bitsPerSample, psFilter, feedFileP); - - fflush(feedFileP); -@@ -2081,17 +2085,17 @@ main(int argc, const char * argv[]) { - - eof = FALSE; /* There is always at least one image */ - for (imageSeq = 0; !eof; ++imageSeq) { -- convertPage(ifP, cmdline.mustturn, cmdline.canturn, -+ convertPage(ifP, cmdline.mustturn, cmdline.canturn, - cmdline.psfilter, -- cmdline.rle, cmdline.flate, cmdline.ascii85, -+ cmdline.rle, cmdline.flate, cmdline.ascii85, - cmdline.setpage, cmdline.showpage, - cmdline.center, cmdline.scale, - cmdline.dpiX, cmdline.dpiY, -- cmdline.width, cmdline.height, -- cmdline.imagewidth, cmdline.imageheight, -+ cmdline.width, cmdline.height, -+ cmdline.imagewidth, cmdline.imageheight, - cmdline.equalpixels, - cmdline.bitspersampleSpec ? cmdline.bitspersample : 0, -- name, -+ name, - cmdline.dict, cmdline.vmreclaim, - cmdline.levelSpec, cmdline.level); - pnm_nextimage(ifP, &eof); -@@ -2121,7 +2125,7 @@ main(int argc, const char * argv[]) { - ** wrzl@gup.uni-linz.ac.at. - ** - ** July 2011 afu --** row converters rewritten, fast PBM-only row converter added, -+** row convertors rewritten, fast PBM-only row convertor added, - ** rle compression slightly modified, flate compression added - ** ascii85 output end added. - ** -diff --git a/converter/other/rletopnm.c b/converter/other/rletopnm.c -index 97f271d..72b63d3 100644 ---- a/converter/other/rletopnm.c -+++ b/converter/other/rletopnm.c +diff -ruNp a/converter/other/rletopnm.c b/converter/other/rletopnm.c +--- a/converter/other/rletopnm.c 2021-06-02 15:53:59.834205650 +0200 ++++ b/converter/other/rletopnm.c 2021-06-02 20:03:24.864187893 +0200 @@ -19,6 +19,8 @@ * If you modify this software, you should include a notice giving the * name of the person performing the modification, the date of modification, * and the reason for such modification. + * -+ * 2002-12-19: Fix maths wrapping bugs. Alan Cox ++ * 2002-12-19: Fix maths wrapping bugs. Alan Cox */ /* * rletopnm - A conversion program to convert from Utah's "rle" image format -diff --git a/converter/other/sirtopnm.c b/converter/other/sirtopnm.c -index fafcc91..9fe49d0 100644 ---- a/converter/other/sirtopnm.c -+++ b/converter/other/sirtopnm.c +diff -ruNp a/converter/other/sirtopnm.c b/converter/other/sirtopnm.c +--- a/converter/other/sirtopnm.c 2021-06-02 15:53:59.833205640 +0200 ++++ b/converter/other/sirtopnm.c 2021-06-02 20:03:50.280409024 +0200 @@ -69,6 +69,7 @@ char* argv[]; } break; case PPM_TYPE: -+ overflow3(cols, rows, 3); ++ overflow3(cols, rows, 3); picsize = cols * rows * 3; planesize = cols * rows; if ( !( sirarray = (unsigned char*) malloc( picsize ) ) ) -diff --git a/converter/other/tifftopnm.c b/converter/other/tifftopnm.c -index 0c301a4..88c99e7 100644 ---- a/converter/other/tifftopnm.c -+++ b/converter/other/tifftopnm.c -@@ -1372,7 +1372,9 @@ convertRasterByRows(pnmOut * const pnmOutP, +diff -ruNp a/converter/other/tifftopnm.c b/converter/other/tifftopnm.c +--- a/converter/other/tifftopnm.c 2021-06-02 15:53:59.834205650 +0200 ++++ b/converter/other/tifftopnm.c 2021-06-02 20:04:47.721908789 +0200 +@@ -1372,7 +1372,9 @@ convertRasterByRows(pnmOut * const if (scanbuf == NULL) pm_error("can't allocate memory for scanline buffer"); @@ -1616,11 +175,10 @@ index 0c301a4..88c99e7 100644 if (samplebuf == NULL) pm_error("can't allocate memory for row buffer"); -diff --git a/converter/other/xwdtopnm.c b/converter/other/xwdtopnm.c -index a99768b..6e23aa6 100644 ---- a/converter/other/xwdtopnm.c -+++ b/converter/other/xwdtopnm.c -@@ -210,6 +210,10 @@ processX10Header(X10WDFileHeader * const h10P, +diff -ruNp a/converter/other/xwdtopnm.c b/converter/other/xwdtopnm.c +--- a/converter/other/xwdtopnm.c 2021-06-02 15:53:59.833205640 +0200 ++++ b/converter/other/xwdtopnm.c 2021-06-02 20:23:21.807634239 +0200 +@@ -210,6 +210,10 @@ processX10Header(X10WDFileHeader * cons *colorsP = pnm_allocrow(2); PNM_ASSIGN1((*colorsP)[0], 0); PNM_ASSIGN1((*colorsP)[1], *maxvalP); @@ -1631,7 +189,7 @@ index a99768b..6e23aa6 100644 *padrightP = (((h10P->pixmap_width + 15) / 16) * 16 - h10P->pixmap_width) * 8; *bits_per_itemP = 16; -@@ -635,6 +639,7 @@ processX11Header(X11WDFileHeader * const h11P, +@@ -635,6 +639,7 @@ processX11Header(X11WDFileHeader * cons *colsP = h11FixedP->pixmap_width; *rowsP = h11FixedP->pixmap_height; @@ -1639,10 +197,9 @@ index a99768b..6e23aa6 100644 *padrightP = h11FixedP->bytes_per_line * 8 - h11FixedP->pixmap_width * h11FixedP->bits_per_pixel; -diff --git a/converter/pbm/mdatopbm.c b/converter/pbm/mdatopbm.c -index 461b3f8..c8bab6c 100644 ---- a/converter/pbm/mdatopbm.c -+++ b/converter/pbm/mdatopbm.c +diff -ruNp a/converter/pbm/mdatopbm.c b/converter/pbm/mdatopbm.c +--- a/converter/pbm/mdatopbm.c 2021-06-02 15:53:59.826205573 +0200 ++++ b/converter/pbm/mdatopbm.c 2021-06-02 20:23:21.807634239 +0200 @@ -245,10 +245,13 @@ main(int argc, char **argv) { pm_readlittleshort(infile, &yy); nInCols = yy; } @@ -1658,10 +215,9 @@ index 461b3f8..c8bab6c 100644 data = pbm_allocarray(nOutCols, nOutRows); -diff --git a/converter/pbm/mgrtopbm.c b/converter/pbm/mgrtopbm.c -index 9f7004a..60e8477 100644 ---- a/converter/pbm/mgrtopbm.c -+++ b/converter/pbm/mgrtopbm.c +diff -ruNp a/converter/pbm/mgrtopbm.c b/converter/pbm/mgrtopbm.c +--- a/converter/pbm/mgrtopbm.c 2021-06-02 15:53:59.828205592 +0200 ++++ b/converter/pbm/mgrtopbm.c 2021-06-02 20:23:21.808634248 +0200 @@ -65,6 +65,8 @@ readMgrHeader(FILE * const ifP, if (head.h_high < ' ' || head.l_high < ' ') pm_error("Invalid width field in MGR header"); @@ -1671,31 +227,9 @@ index 9f7004a..60e8477 100644 *colsP = (((int)head.h_wide - ' ') << 6) + ((int)head.l_wide - ' '); *rowsP = (((int)head.h_high - ' ') << 6) + ((int) head.l_high - ' '); *padrightP = ( ( *colsP + pad - 1 ) / pad ) * pad - *colsP; -diff --git a/converter/pbm/pbmto4425.c b/converter/pbm/pbmto4425.c -index 1d97ac6..c4c8cbb 100644 ---- a/converter/pbm/pbmto4425.c -+++ b/converter/pbm/pbmto4425.c -@@ -2,6 +2,7 @@ - - #include "nstring.h" - #include "pbm.h" -+#include - - static char bit_table[2][3] = { - {1, 4, 0x10}, -@@ -160,7 +161,7 @@ main(int argc, char * argv[]) { - xres = vmap_width * 2; - yres = vmap_height * 3; - -- vmap = malloc(vmap_width * vmap_height * sizeof(char)); -+ vmap = malloc3(vmap_width, vmap_height, sizeof(char)); - if(vmap == NULL) - { - pm_error( "Cannot allocate memory" ); -diff --git a/converter/pbm/pbmtogem.c b/converter/pbm/pbmtogem.c -index 4fd30e9..c82757d 100644 ---- a/converter/pbm/pbmtogem.c -+++ b/converter/pbm/pbmtogem.c +diff -ruNp a/converter/pbm/pbmtogem.c b/converter/pbm/pbmtogem.c +--- a/converter/pbm/pbmtogem.c 2021-06-02 15:53:59.828205592 +0200 ++++ b/converter/pbm/pbmtogem.c 2021-06-02 20:23:21.809634256 +0200 @@ -79,6 +79,7 @@ putinit (int const rows, int const cols) bitsperitem = 0; bitshift = 7; @@ -1704,10 +238,9 @@ index 4fd30e9..c82757d 100644 outmax = (cols + 7) / 8; outrow = (unsigned char *) pm_allocrow (outmax, sizeof (unsigned char)); lastrow = (unsigned char *) pm_allocrow (outmax, sizeof (unsigned char)); -diff --git a/converter/pbm/pbmtogo.c b/converter/pbm/pbmtogo.c -index 4f84f39..943dc84 100644 ---- a/converter/pbm/pbmtogo.c -+++ b/converter/pbm/pbmtogo.c +diff -ruNp a/converter/pbm/pbmtogo.c b/converter/pbm/pbmtogo.c +--- a/converter/pbm/pbmtogo.c 2021-06-02 15:53:59.826205573 +0200 ++++ b/converter/pbm/pbmtogo.c 2021-06-02 20:23:21.809634256 +0200 @@ -158,6 +158,7 @@ main(int argc, bitrow = pbm_allocrow(cols); @@ -1716,10 +249,9 @@ index 4f84f39..943dc84 100644 rucols = ( cols + 7 ) / 8; bytesperrow = rucols; /* GraphOn uses bytes */ rucols = rucols * 8; -diff --git a/converter/pbm/pbmtolj.c b/converter/pbm/pbmtolj.c -index 3cd7670..0b51932 100644 ---- a/converter/pbm/pbmtolj.c -+++ b/converter/pbm/pbmtolj.c +diff -ruNp a/converter/pbm/pbmtolj.c b/converter/pbm/pbmtolj.c +--- a/converter/pbm/pbmtolj.c 2021-06-02 15:53:59.828205592 +0200 ++++ b/converter/pbm/pbmtolj.c 2021-06-02 20:23:21.810634265 +0200 @@ -120,7 +120,11 @@ parseCommandLine(int argc, char ** argv, static void allocateBuffers(unsigned int const cols) { @@ -1732,10 +264,9 @@ index 3cd7670..0b51932 100644 packBufferSize = rowBufferSize + (rowBufferSize + 127) / 128 + 1; deltaBufferSize = rowBufferSize + rowBufferSize / 8 + 10; -diff --git a/converter/pbm/pbmtomda.c b/converter/pbm/pbmtomda.c -index 3ad5149..9efe5cf 100644 ---- a/converter/pbm/pbmtomda.c -+++ b/converter/pbm/pbmtomda.c +diff -ruNp a/converter/pbm/pbmtomda.c b/converter/pbm/pbmtomda.c +--- a/converter/pbm/pbmtomda.c 2021-06-02 15:53:59.827205582 +0200 ++++ b/converter/pbm/pbmtomda.c 2021-06-02 20:23:21.810634265 +0200 @@ -179,6 +179,7 @@ int main(int argc, char **argv) nOutRowsUnrounded = bScale ? nInRows/2 : nInRows; @@ -1744,10 +275,9 @@ index 3ad5149..9efe5cf 100644 nOutRows = ((nOutRowsUnrounded + 3) / 4) * 4; /* MDA wants rows a multiple of 4 */ nOutCols = nInCols / 8; -diff --git a/converter/pbm/pbmtoppa/pbm.c b/converter/pbm/pbmtoppa/pbm.c -index ae36e0d..1c8d236 100644 ---- a/converter/pbm/pbmtoppa/pbm.c -+++ b/converter/pbm/pbmtoppa/pbm.c +diff -ruNp a/converter/pbm/pbmtoppa/pbm.c b/converter/pbm/pbmtoppa/pbm.c +--- a/converter/pbm/pbmtoppa/pbm.c 2021-06-02 15:53:59.830205611 +0200 ++++ b/converter/pbm/pbmtoppa/pbm.c 2021-06-02 20:23:21.811634274 +0200 @@ -11,185 +11,128 @@ #include #include @@ -1821,18 +351,35 @@ index ae36e0d..1c8d236 100644 - } - return retval; -} +- +int make_pbm_stat(pbm_stat* pbm,FILE* fptr) +{ + char line[1024]; - ++ + pbm->fptr=fptr; + pbm->version=none; + pbm->current_line=0; + pbm->unread = 0; - ++ + if (fgets (line, 1024, fptr) == NULL) + return 0; + line[strlen(line)-1] = 0; ++ ++ if(!strcmp(line,"P1")) pbm->version=P1; ++ if(!strcmp(line,"P4")) pbm->version=P4; ++ if(pbm->version == none) ++ { ++ fprintf(stderr,"pbm_readheader(): unknown PBM magic '%s'\n",line); ++ return 0; ++ } ++ ++ do ++ if (fgets (line, 1024, fptr) == NULL) ++ return 0; ++ while (line[0] == '#'); + ++ if (2 != sscanf (line, "%d %d", &pbm->width, &pbm->height)) ++ return 0; -static int -getbytes(FILE * const ifP, @@ -1871,23 +418,11 @@ index ae36e0d..1c8d236 100644 - retval = 1; - } - return retval; --} -+ if(!strcmp(line,"P1")) pbm->version=P1; -+ if(!strcmp(line,"P4")) pbm->version=P4; -+ if(pbm->version == none) -+ { -+ fprintf(stderr,"pbm_readheader(): unknown PBM magic '%s'\n",line); -+ return 0; -+ } - -+ do -+ if (fgets (line, 1024, fptr) == NULL) -+ return 0; -+ while (line[0] == '#'); - -+ if (2 != sscanf (line, "%d %d", &pbm->width, &pbm->height)) -+ return 0; ++ return 1; + } +- +- -int -pbm_readline(pbm_stat * const pbmStatP, - unsigned char * const data) { @@ -1934,11 +469,6 @@ index ae36e0d..1c8d236 100644 - retval = 0; - } - } -- } -- return retval; -+ return 1; - } - +static int getbytes(FILE *fptr,int width,unsigned char* data) +{ + unsigned char mask,acc,*place; @@ -1963,12 +493,13 @@ index ae36e0d..1c8d236 100644 + acc=0; + mask=0x80; + } -+ } + } +- return retval; + } + if(width%8) + *place=acc; + return 1; -+} + } +/* Reads a single line into data which must be at least (pbm->width+7)/8 + bytes of storage */ @@ -1988,6 +519,16 @@ index ae36e0d..1c8d236 100644 + return 1; + } ++ switch(pbm->version) ++ { ++ case P1: ++ if(getbytes(pbm->fptr,pbm->width,data)) ++ { ++ pbm->current_line++; ++ return 1; ++ } ++ return 0; + -void -pbm_unreadline(pbm_stat * const pbmStatP, - void * const data) { @@ -2001,17 +542,6 @@ index ae36e0d..1c8d236 100644 - pbmStatP->revdata = malloc ((pbmStatP->width+7)/8); - memcpy(pbmStatP->revdata, data, (pbmStatP->width+7)/8); - --pbmStatP->current_line; -+ switch(pbm->version) -+ { -+ case P1: -+ if(getbytes(pbm->fptr,pbm->width,data)) -+ { -+ pbm->current_line++; -+ return 1; - } --} -+ return 0; -+ + case P4: + overflow_add(pbm->width, 7); + tmp=(pbm->width+7)/8; @@ -2020,7 +550,8 @@ index ae36e0d..1c8d236 100644 + { + pbm->current_line++; + return 1; -+ } + } +-} + fprintf(stderr,"pbm_readline(): error reading line data (%d)\n",tmp2); + return 0; @@ -2043,10 +574,9 @@ index ae36e0d..1c8d236 100644 + memcpy (pbm->revdata, data, (pbm->width+7)/8); + pbm->current_line--; +} -diff --git a/converter/pbm/pbmtoppa/pbmtoppa.c b/converter/pbm/pbmtoppa/pbmtoppa.c -index ff4a599..aa510ec 100644 ---- a/converter/pbm/pbmtoppa/pbmtoppa.c -+++ b/converter/pbm/pbmtoppa/pbmtoppa.c +diff -ruNp a/converter/pbm/pbmtoppa/pbmtoppa.c b/converter/pbm/pbmtoppa/pbmtoppa.c +--- a/converter/pbm/pbmtoppa/pbmtoppa.c 2021-06-02 15:53:59.829205601 +0200 ++++ b/converter/pbm/pbmtoppa/pbmtoppa.c 2021-06-02 20:23:21.811634274 +0200 @@ -453,6 +453,7 @@ main(int argc, char *argv[]) { pm_error("main(): unrecognized parameter '%s'", argv[argn]); } @@ -2055,10 +585,9 @@ index ff4a599..aa510ec 100644 Pwidth=(Width+7)/8; printer.fptr=out; -diff --git a/converter/pbm/pbmtoxbm.c b/converter/pbm/pbmtoxbm.c -index ecb72b3..fc0eb9c 100644 ---- a/converter/pbm/pbmtoxbm.c -+++ b/converter/pbm/pbmtoxbm.c +diff -ruNp a/converter/pbm/pbmtoxbm.c b/converter/pbm/pbmtoxbm.c +--- a/converter/pbm/pbmtoxbm.c 2021-06-02 15:53:59.829205601 +0200 ++++ b/converter/pbm/pbmtoxbm.c 2021-06-02 20:23:21.812634282 +0200 @@ -352,6 +352,8 @@ convertRaster(FILE * const ifP, unsigned char * bitrow; @@ -2068,10 +597,29 @@ index ecb72b3..fc0eb9c 100644 putinit(xbmVersion); -diff --git a/converter/pbm/pktopbm.c b/converter/pbm/pktopbm.c -index 712f339..b6fcb02 100644 ---- a/converter/pbm/pktopbm.c -+++ b/converter/pbm/pktopbm.c +diff -ruNp a/converter/pbm/pbmto4425.c b/converter/pbm/pbmto4425.c +--- a/converter/pbm/pbmto4425.c 2021-06-02 15:53:59.827205582 +0200 ++++ b/converter/pbm/pbmto4425.c 2021-06-02 20:23:21.808634248 +0200 +@@ -2,6 +2,7 @@ + + #include "nstring.h" + #include "pbm.h" ++#include + + static char bit_table[2][3] = { + {1, 4, 0x10}, +@@ -160,7 +161,7 @@ main(int argc, char * argv[]) { + xres = vmap_width * 2; + yres = vmap_height * 3; + +- vmap = malloc(vmap_width * vmap_height * sizeof(char)); ++ vmap = malloc3(vmap_width, vmap_height, sizeof(char)); + if(vmap == NULL) + { + pm_error( "Cannot allocate memory" ); +diff -ruNp a/converter/pbm/pktopbm.c b/converter/pbm/pktopbm.c +--- a/converter/pbm/pktopbm.c 2021-06-02 15:53:59.828205592 +0200 ++++ b/converter/pbm/pktopbm.c 2021-06-02 20:23:21.813634291 +0200 @@ -280,6 +280,7 @@ main(int argc, char *argv[]) { if (flagbyte == 7) { /* long form preamble */ integer packetlength = get32() ; /* character packet length */ @@ -2080,10 +628,9 @@ index 712f339..b6fcb02 100644 endofpacket = packetlength + pktopbm_pkloc; /* calculate end of packet */ if ((car >= MAXPKCHAR) || !filename[car]) { -diff --git a/converter/pbm/thinkjettopbm.l b/converter/pbm/thinkjettopbm.l -index 5de4f2b..7f31de5 100644 ---- a/converter/pbm/thinkjettopbm.l -+++ b/converter/pbm/thinkjettopbm.l +diff -ruNp a/converter/pbm/thinkjettopbm.l b/converter/pbm/thinkjettopbm.l +--- a/converter/pbm/thinkjettopbm.l 2021-06-02 15:53:59.828205592 +0200 ++++ b/converter/pbm/thinkjettopbm.l 2021-06-02 20:23:21.813634291 +0200 @@ -114,7 +114,9 @@ DIG [0-9] \033\*b{DIG}+W { int l; @@ -2104,10 +651,9 @@ index 5de4f2b..7f31de5 100644 pbm_writepbminit(stdout, maxRowLength*8, rowCount, 0); packed_bitrow = malloc(maxRowLength); -diff --git a/converter/pbm/ybmtopbm.c b/converter/pbm/ybmtopbm.c -index 2a42908..cf1ff03 100644 ---- a/converter/pbm/ybmtopbm.c -+++ b/converter/pbm/ybmtopbm.c +diff -ruNp a/converter/pbm/ybmtopbm.c b/converter/pbm/ybmtopbm.c +--- a/converter/pbm/ybmtopbm.c 2021-06-02 15:53:59.827205582 +0200 ++++ b/converter/pbm/ybmtopbm.c 2021-06-02 20:23:21.814634300 +0200 @@ -43,6 +43,7 @@ getinit(FILE * const ifP, pm_error("EOF / read error"); @@ -2116,10 +662,9 @@ index 2a42908..cf1ff03 100644 } -diff --git a/converter/pgm/lispmtopgm.c b/converter/pgm/lispmtopgm.c -index 40dd3fb..b5469f7 100644 ---- a/converter/pgm/lispmtopgm.c -+++ b/converter/pgm/lispmtopgm.c +diff -ruNp a/converter/pgm/lispmtopgm.c b/converter/pgm/lispmtopgm.c +--- a/converter/pgm/lispmtopgm.c 2021-06-02 15:53:59.831205621 +0200 ++++ b/converter/pgm/lispmtopgm.c 2021-06-02 20:23:21.814634300 +0200 @@ -58,6 +58,7 @@ main( argc, argv ) pm_error( "depth (%d bits) is too large", depth); @@ -2128,7 +673,7 @@ index 40dd3fb..b5469f7 100644 grayrow = pgm_allocrow( ( cols + 7 ) / 8 * 8 ); for ( row = 0; row < rows; ++row ) -@@ -102,6 +103,8 @@ getinit( file, colsP, rowsP, depthP, padrightP ) +@@ -102,6 +103,8 @@ getinit( file, colsP, rowsP, depthP, pad if ( *depthP == 0 ) *depthP = 1; /* very old file */ @@ -2137,10 +682,9 @@ index 40dd3fb..b5469f7 100644 *padrightP = ( ( *colsP + 31 ) / 32 ) * 32 - *colsP; -diff --git a/converter/pgm/psidtopgm.c b/converter/pgm/psidtopgm.c -index 07417d1..25bb311 100644 ---- a/converter/pgm/psidtopgm.c -+++ b/converter/pgm/psidtopgm.c +diff -ruNp a/converter/pgm/psidtopgm.c b/converter/pgm/psidtopgm.c +--- a/converter/pgm/psidtopgm.c 2021-06-02 15:53:59.830205611 +0200 ++++ b/converter/pgm/psidtopgm.c 2021-06-02 20:23:21.815634309 +0200 @@ -78,6 +78,7 @@ main(int argc, pm_error("bits/sample (%d) is too large.", bitspersample); @@ -2149,23 +693,9 @@ index 07417d1..25bb311 100644 grayrow = pgm_allocrow((cols + 7) / 8 * 8); for (row = 0; row < rows; ++row) { unsigned int col; -diff --git a/converter/ppm/Makefile b/converter/ppm/Makefile -index 003ef8d..b97349d 100644 ---- a/converter/ppm/Makefile -+++ b/converter/ppm/Makefile -@@ -11,7 +11,7 @@ SUBDIRS = hpcdtoppm ppmtompeg - - PORTBINARIES = 411toppm eyuvtoppm gouldtoppm ilbmtoppm imgtoppm \ - leaftoppm mtvtoppm neotoppm \ -- pcxtoppm pc1toppm pi1toppm picttoppm pjtoppm \ -+ pcxtoppm pc1toppm pi1toppm pjtoppm \ - ppmtoacad ppmtoapplevol ppmtoarbtxt ppmtoascii \ - ppmtobmp ppmtoeyuv ppmtogif ppmtoicr ppmtoilbm \ - ppmtoleaf ppmtolj ppmtomitsu ppmtoneo \ -diff --git a/converter/ppm/ilbmtoppm.c b/converter/ppm/ilbmtoppm.c -index b9b8986..f4fe331 100644 ---- a/converter/ppm/ilbmtoppm.c -+++ b/converter/ppm/ilbmtoppm.c +diff -ruNp a/converter/ppm/ilbmtoppm.c b/converter/ppm/ilbmtoppm.c +--- a/converter/ppm/ilbmtoppm.c 2021-06-02 15:53:59.846205765 +0200 ++++ b/converter/ppm/ilbmtoppm.c 2021-06-02 20:23:21.817634326 +0200 @@ -608,6 +608,7 @@ decode_row(FILE * const ifP, rawtype *chp; @@ -2208,7 +738,7 @@ index b9b8986..f4fe331 100644 MALLOCARRAY_NOFAIL(redtable, redmaxval +1); MALLOCARRAY_NOFAIL(greentable, greenmaxval +1); MALLOCARRAY_NOFAIL(bluetable, bluemaxval +1); -@@ -1802,7 +1823,9 @@ PCHG_ConvertSmall(PCHGHeader * const pchgP, +@@ -1802,7 +1823,9 @@ PCHG_ConvertSmall(PCHGHeader * const ChangeCount32 = *data++; remDataSize -= 2; @@ -2236,62 +766,9 @@ index b9b8986..f4fe331 100644 MALLOCARRAY_NOFAIL(ilbmrow, RowBytes(bmhdP->w)); *viewportmodesP |= fakeviewport; /* -isham/-isehb */ -diff --git a/converter/ppm/ilbmtoppm.c.rej b/converter/ppm/ilbmtoppm.c.rej -new file mode 100644 -index 0000000..972cad0 ---- /dev/null -+++ b/converter/ppm/ilbmtoppm.c.rej -@@ -0,0 +1,46 @@ -+--- converter/ppm/ilbmtoppm.c -++++ converter/ppm/ilbmtoppm.c -+@@ -694,6 +695,23 @@ decode_mask(FILE * const ifP, -+ Multipalette handling -+ ****************************************************************************/ -+ -++static void * -++xmalloc2(x, y) -++ int x; -++ int y; -++{ -++ void *mem; -++ -++ overflow2(x,y); -++ if( x * y == 0 ) -++ return NULL; -++ -++ mem = malloc2(x,y); -++ if( mem == NULL ) -++ pm_error("out of memory allocating %d bytes", x * y); -++ return mem; -++} -++ -+ -+ static void -+ multi_adjust(cmap, row, palchange) -+@@ -1356,6 +1374,9 @@ dcol_to_ppm(FILE * const ifP, -+ if( redmaxval != maxval || greenmaxval != maxval || bluemaxval != maxval ) -+ pm_message("scaling colors to %d bits", pm_maxvaltobits(maxval)); -+ -++ overflow_add(redmaxval, 1); -++ overflow_add(greenmaxval, 1); -++ overflow_add(bluemaxval, 1); -+ MALLOCARRAY_NOFAIL(redtable, redmaxval +1); -+ MALLOCARRAY_NOFAIL(greentable, greenmaxval +1); -+ MALLOCARRAY_NOFAIL(bluetable, bluemaxval +1); -+@@ -1785,7 +1806,9 @@ PCHG_ConvertSmall(PCHG, cmap, mask, datasize) -+ ChangeCount32 = *data++; -+ datasize -= 2; -+ -++ overflow_add(ChangeCount16, ChangeCount32); -+ changes = ChangeCount16 + ChangeCount32; -++ overflow_add(changes, 1); -+ for( i = 0; i < changes; i++ ) { -+ if( totalchanges >= PCHG->TotalChanges ) goto fail; -+ if( datasize < 2 ) goto fail; -diff --git a/converter/ppm/imgtoppm.c b/converter/ppm/imgtoppm.c -index 7078b88..eb8509e 100644 ---- a/converter/ppm/imgtoppm.c -+++ b/converter/ppm/imgtoppm.c +diff -ruNp a/converter/ppm/imgtoppm.c b/converter/ppm/imgtoppm.c +--- a/converter/ppm/imgtoppm.c 2021-06-02 15:53:59.845205755 +0200 ++++ b/converter/ppm/imgtoppm.c 2021-06-02 20:23:21.818634335 +0200 @@ -84,6 +84,7 @@ main(int argc, char ** argv) { len = atoi((char*) buf ); if ( fread( buf, len, 1, ifp ) != 1 ) @@ -2308,11 +785,22 @@ index 7078b88..eb8509e 100644 if ( len != cols * rows ) pm_message( "pixel data length (%d) does not match image size (%d)", -diff --git a/converter/ppm/pcxtoppm.c b/converter/ppm/pcxtoppm.c -index e252ba2..270ae3b 100644 ---- a/converter/ppm/pcxtoppm.c -+++ b/converter/ppm/pcxtoppm.c -@@ -409,6 +409,7 @@ pcx_planes_to_pixels(pixels, bitplanes, bytesperline, planes, bitsperpixel) +diff -ruNp a/converter/ppm/Makefile b/converter/ppm/Makefile +--- a/converter/ppm/Makefile 2021-06-02 15:53:59.846205765 +0200 ++++ b/converter/ppm/Makefile 2021-06-02 20:23:21.815634309 +0200 +@@ -11,7 +11,7 @@ SUBDIRS = hpcdtoppm ppmtompeg + + PORTBINARIES = 411toppm eyuvtoppm gouldtoppm ilbmtoppm imgtoppm \ + leaftoppm mtvtoppm neotoppm \ +- pcxtoppm pc1toppm pi1toppm picttoppm pjtoppm \ ++ pcxtoppm pc1toppm pi1toppm pjtoppm \ + ppmtoacad ppmtoapplevol ppmtoarbtxt ppmtoascii \ + ppmtobmp ppmtoeyuv ppmtogif ppmtoicr ppmtoilbm \ + ppmtoleaf ppmtolj ppmtomitsu ppmtoneo \ +diff -ruNp a/converter/ppm/pcxtoppm.c b/converter/ppm/pcxtoppm.c +--- a/converter/ppm/pcxtoppm.c 2021-06-02 15:53:59.846205765 +0200 ++++ b/converter/ppm/pcxtoppm.c 2021-06-02 20:23:21.818634335 +0200 +@@ -409,6 +409,7 @@ pcx_planes_to_pixels(pixels, bitplanes, /* * clear the pixel buffer */ @@ -2328,19 +816,17 @@ index e252ba2..270ae3b 100644 rawcols = BytesPerLine * 8 / BitsPerPixel; if (headerCols > rawcols) { pm_message("warning - BytesPerLine = %d, " -diff --git a/converter/ppm/picttoppm.c b/converter/ppm/picttoppm.c -index 4bc5337..a5a0ad5 100644 ---- a/converter/ppm/picttoppm.c -+++ b/converter/ppm/picttoppm.c +diff -ruNp a/converter/ppm/picttoppm.c b/converter/ppm/picttoppm.c +--- a/converter/ppm/picttoppm.c 2021-06-02 15:53:59.845205755 +0200 ++++ b/converter/ppm/picttoppm.c 2021-06-02 20:23:21.820634352 +0200 @@ -1,3 +1,4 @@ +#error "Unfixable. Don't ship me" /* * picttoppm.c -- convert a MacIntosh PICT file to PPM format. * -diff --git a/converter/ppm/pjtoppm.c b/converter/ppm/pjtoppm.c -index e556803..c458c06 100644 ---- a/converter/ppm/pjtoppm.c -+++ b/converter/ppm/pjtoppm.c +diff -ruNp a/converter/ppm/pjtoppm.c b/converter/ppm/pjtoppm.c +--- a/converter/ppm/pjtoppm.c 2021-06-02 15:53:59.845205755 +0200 ++++ b/converter/ppm/pjtoppm.c 2021-06-02 20:23:21.821634361 +0200 @@ -10,98 +10,66 @@ ** implied warranty. */ @@ -2713,11 +1199,10 @@ index e556803..c458c06 100644 - - - -diff --git a/converter/ppm/ppmtoeyuv.c b/converter/ppm/ppmtoeyuv.c -index f5ce115..6f072be 100644 ---- a/converter/ppm/ppmtoeyuv.c -+++ b/converter/ppm/ppmtoeyuv.c -@@ -114,6 +114,7 @@ create_multiplication_tables(const pixval maxval) { +diff -ruNp a/converter/ppm/ppmtoeyuv.c b/converter/ppm/ppmtoeyuv.c +--- a/converter/ppm/ppmtoeyuv.c 2021-06-02 15:53:59.845205755 +0200 ++++ b/converter/ppm/ppmtoeyuv.c 2021-06-02 20:23:21.821634361 +0200 +@@ -114,6 +114,7 @@ create_multiplication_tables(const pixva int index; @@ -2725,10 +1210,9 @@ index f5ce115..6f072be 100644 MALLOCARRAY_NOFAIL(mult299 , maxval+1); MALLOCARRAY_NOFAIL(mult587 , maxval+1); MALLOCARRAY_NOFAIL(mult114 , maxval+1); -diff --git a/converter/ppm/ppmtolj.c b/converter/ppm/ppmtolj.c -index 7ed814e..b4e7db1 100644 ---- a/converter/ppm/ppmtolj.c -+++ b/converter/ppm/ppmtolj.c +diff -ruNp a/converter/ppm/ppmtolj.c b/converter/ppm/ppmtolj.c +--- a/converter/ppm/ppmtolj.c 2021-06-02 15:53:59.846205765 +0200 ++++ b/converter/ppm/ppmtolj.c 2021-06-02 20:23:21.821634361 +0200 @@ -182,6 +182,7 @@ int main(int argc, char *argv[]) { ppm_readppminit( ifp, &cols, &rows, &maxval, &format ); pixelrow = ppm_allocrow( cols ); @@ -2737,10 +1221,9 @@ index 7ed814e..b4e7db1 100644 obuf = (unsigned char *) pm_allocrow(cols * 3, sizeof(unsigned char)); cbuf = (unsigned char *) pm_allocrow(cols * 6, sizeof(unsigned char)); if (mode == C_TRANS_MODE_DELTA) -diff --git a/converter/ppm/ppmtomitsu.c b/converter/ppm/ppmtomitsu.c -index 50b790d..63d3182 100644 ---- a/converter/ppm/ppmtomitsu.c -+++ b/converter/ppm/ppmtomitsu.c +diff -ruNp a/converter/ppm/ppmtomitsu.c b/converter/ppm/ppmtomitsu.c +--- a/converter/ppm/ppmtomitsu.c 2021-06-02 15:53:59.846205765 +0200 ++++ b/converter/ppm/ppmtomitsu.c 2021-06-02 20:23:21.822634370 +0200 @@ -685,6 +685,8 @@ main(int argc, char * argv[]) { medias = MSize_User; @@ -2750,10 +1233,9 @@ index 50b790d..63d3182 100644 medias.maxcols *= 2; medias.maxrows *= 2; } -diff --git a/converter/ppm/ppmtopcx.c b/converter/ppm/ppmtopcx.c -index 5b7e100..e7b06ff 100644 ---- a/converter/ppm/ppmtopcx.c -+++ b/converter/ppm/ppmtopcx.c +diff -ruNp a/converter/ppm/ppmtopcx.c b/converter/ppm/ppmtopcx.c +--- a/converter/ppm/ppmtopcx.c 2021-06-02 15:53:59.846205765 +0200 ++++ b/converter/ppm/ppmtopcx.c 2021-06-02 20:23:21.823634378 +0200 @@ -31,13 +31,13 @@ #define PCX_MAXVAL (pixval)255 @@ -2791,7 +1273,7 @@ index 5b7e100..e7b06ff 100644 retval.r = PPM_GETR(colorPixel); retval.g = PPM_GETG(colorPixel); -@@ -70,8 +70,8 @@ pcxCmapEntryFromPixel(pixel const colorPixel) { +@@ -70,8 +70,8 @@ pcxCmapEntryFromPixel(pixel const colorP static void @@ -2802,7 +1284,7 @@ index 5b7e100..e7b06ff 100644 /*---------------------------------------------------------------------------- parse program command line described in Unix standard form by argc and argv. Return the information in the options as *cmdlineP. -@@ -82,7 +82,7 @@ parseCommandLine(int argc, const char ** argv, +@@ -82,7 +82,7 @@ parseCommandLine(int argc, const char ** Note that the strings we return are stored in the storage that was passed to us as the argv array. We also trash *argv. -----------------------------------------------------------------------------*/ @@ -2811,7 +1293,7 @@ index 5b7e100..e7b06ff 100644 /* Instructions to pm_optParseOptions3 on how to parse our options. */ optStruct3 opt; -@@ -97,7 +97,7 @@ parseCommandLine(int argc, const char ** argv, +@@ -97,7 +97,7 @@ parseCommandLine(int argc, const char ** OPTENT3(0, "24bit", OPT_FLAG, NULL, &cmdlineP->truecolor, 0); OPTENT3(0, "8bit", OPT_FLAG, NULL, @@ -2820,7 +1302,7 @@ index 5b7e100..e7b06ff 100644 OPTENT3(0, "planes", OPT_UINT, &cmdlineP->planes, &planesSpec, 0); OPTENT3(0, "packed", OPT_FLAG, NULL, -@@ -115,7 +115,7 @@ parseCommandLine(int argc, const char ** argv, +@@ -115,7 +115,7 @@ parseCommandLine(int argc, const char ** opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ @@ -2829,7 +1311,7 @@ index 5b7e100..e7b06ff 100644 /* Uses and sets argc, argv, and some of *cmdline_p and others. */ if (!xposSpec) -@@ -141,7 +141,7 @@ parseCommandLine(int argc, const char ** argv, +@@ -141,7 +141,7 @@ parseCommandLine(int argc, const char ** pm_error("-planes is meaningless with -packed."); if (cmdlineP->truecolor) pm_error("-planes is meaningless with -24bit"); @@ -2838,7 +1320,7 @@ index 5b7e100..e7b06ff 100644 pm_error("-planes is meaningless with -8bit"); } -@@ -151,7 +151,7 @@ parseCommandLine(int argc, const char ** argv, +@@ -151,7 +151,7 @@ parseCommandLine(int argc, const char ** if (!paletteSpec) cmdlineP->palette = NULL; @@ -2847,7 +1329,7 @@ index 5b7e100..e7b06ff 100644 pm_error("You cannot specify both -8bit and -truecolor"); if (argc-1 < 1) -@@ -172,8 +172,8 @@ parseCommandLine(int argc, const char ** argv, +@@ -172,8 +172,8 @@ parseCommandLine(int argc, const char ** * Write out a two-byte little-endian word to the PCX file */ static void @@ -2887,7 +1369,7 @@ index 5b7e100..e7b06ff 100644 /*---------------------------------------------------------------------------- From the image row 'rawrow', which is an array of 'cols' palette indices (as unsigned 8 bit integers), extract plane number 'plane' and return -@@ -224,7 +223,9 @@ extractPlane(unsigned char * const rawrow, +@@ -224,7 +223,9 @@ extractPlane(unsigned char * const rawro cp = buf; /* initial value */ @@ -2898,7 +1380,7 @@ index 5b7e100..e7b06ff 100644 if (rawrow[col] & planeMask) byteUnderConstruction |= (1 << cbit); -@@ -246,17 +247,14 @@ extractPlane(unsigned char * const rawrow, +@@ -246,17 +247,14 @@ extractPlane(unsigned char * const rawro static void @@ -2945,9 +1427,6 @@ index 5b7e100..e7b06ff 100644 - putword(yPos, ofP); /* y1 - image top */ - putword(xPos+cols-1, ofP); /* x2 - image right */ - putword(yPos+rows-1, ofP); /* y2 - image bottom */ -- -- putword(cols, ofP); /* horizontal resolution */ -- putword(rows, ofP); /* vertical resolution */ +write_header(FILE * const fp, + int const cols, + int const rows, @@ -2968,7 +1447,9 @@ index 5b7e100..e7b06ff 100644 + Putword(yPos, fp); /* y1 - image top */ + Putword(xPos+cols-1, fp); /* x2 - image right */ + Putword(yPos+rows-1, fp); /* y2 - image bottom */ -+ + +- putword(cols, ofP); /* horizontal resolution */ +- putword(rows, ofP); /* vertical resolution */ + Putword(cols, fp); /* horizontal resolution */ + Putword(rows, fp); /* vertical resolution */ @@ -3036,7 +1517,7 @@ index 5b7e100..e7b06ff 100644 currentP = buf; previous = *currentP++; -@@ -351,19 +347,19 @@ pcxEncode(FILE * const ofP, +@@ -351,19 +347,19 @@ pcxEncode(FILE * const of else { if (count > 1 || (previous & 0xc0) == 0xc0) { count |= 0xc0; @@ -3153,11 +1634,10 @@ index 5b7e100..e7b06ff 100644 } } } -@@ -439,143 +452,84 @@ writeRaster16Color(FILE * const ofP, +@@ -440,142 +453,83 @@ writeRaster16Color(FILE * const ofP, - --static void + static void -ppmTo16ColorPcx(pixel ** const pixels, - unsigned int const cols, - unsigned int const rows, @@ -3198,7 +1678,7 @@ index 5b7e100..e7b06ff 100644 - - - - static void +-static void ppmTo256ColorPcx(pixel ** const pixels, - unsigned int const cols, - unsigned int const rows, @@ -3272,13 +1752,13 @@ index 5b7e100..e7b06ff 100644 - unsigned char * grnrow; - unsigned char * blurow; - unsigned int row; -+ unsigned char *redrow, *greenrow, *bluerow; -+ int col, row; - +- - MALLOCARRAY(redrow, cols); - MALLOCARRAY(grnrow, cols); - MALLOCARRAY(blurow, cols); -- ++ unsigned char *redrow, *greenrow, *bluerow; ++ int col, row; + - if (!redrow || !grnrow || !blurow) - pm_error("Unable to allocate buffer for a row of %u pixels", cols); + redrow = (unsigned char *)pm_allocrow(cols, sizeof(unsigned char)); @@ -3341,7 +1821,7 @@ index 5b7e100..e7b06ff 100644 stdPalette[] = { { 0, 0, 0 }, { 0, 0, 170 }, -@@ -653,19 +607,20 @@ putPcxColorInHash(colorhash_table const cht, +@@ -653,19 +607,20 @@ putPcxColorInHash(colorhash_table const static void @@ -3368,7 +1848,7 @@ index 5b7e100..e7b06ff 100644 cht = ppm_alloccolorhash(); for (colorIndex = 0; colorIndex < stdPaletteSize; ++colorIndex) { -@@ -692,7 +647,6 @@ generateStandardPalette(struct PcxCmapEntry ** const pcxcmapP, +@@ -692,7 +647,6 @@ generateStandardPalette(struct PcxCmapEn pcxcmap[colorIndex].b = 0; } @@ -3376,7 +1856,7 @@ index 5b7e100..e7b06ff 100644 *chtP = cht; *colorsP = stdPaletteSize; } -@@ -721,10 +675,11 @@ readPpmPalette(const char * const paletteFileName, +@@ -721,10 +675,11 @@ readPpmPalette(const char * const pale *paletteSizeP, MAXCOLORS); { @@ -3392,7 +1872,7 @@ index 5b7e100..e7b06ff 100644 for (col = 0; col < cols; ++col) (*ppmPaletteP)[j++] = pixels[row][col]; } -@@ -735,16 +690,16 @@ readPpmPalette(const char * const paletteFileName, +@@ -735,16 +690,16 @@ readPpmPalette(const char * const pale static void @@ -3412,7 +1892,7 @@ index 5b7e100..e7b06ff 100644 colorhash_table cht; readPpmPalette(paletteFileName, &ppmPalette, &paletteSize); -@@ -777,7 +732,7 @@ readPaletteFromFile(struct PcxCmapEntry ** const pcxcmapP, +@@ -777,7 +732,7 @@ readPaletteFromFile(struct PcxCmapEntry static void moveBlackToIndex0(colorhist_vector const chv, @@ -3421,7 +1901,7 @@ index 5b7e100..e7b06ff 100644 /*---------------------------------------------------------------------------- If black is in the palette, make it at Index 0. -----------------------------------------------------------------------------*/ -@@ -789,7 +744,7 @@ moveBlackToIndex0(colorhist_vector const chv, +@@ -789,7 +744,7 @@ moveBlackToIndex0(colorhist_vector const blackPresent = FALSE; /* initial assumption */ @@ -3430,7 +1910,7 @@ index 5b7e100..e7b06ff 100644 if (PPM_EQUAL(chv[i].color, blackPixel)) blackPresent = TRUE; -@@ -798,11 +753,10 @@ moveBlackToIndex0(colorhist_vector const chv, +@@ -798,11 +753,10 @@ moveBlackToIndex0(colorhist_vector const beginning of the table and if the color is already elsewhere in the table, removes it. */ @@ -3446,7 +1926,7 @@ index 5b7e100..e7b06ff 100644 } } -@@ -810,12 +764,12 @@ moveBlackToIndex0(colorhist_vector const chv, +@@ -810,12 +764,12 @@ moveBlackToIndex0(colorhist_vector const static void makePcxColormapFromImage(pixel ** const pixels, @@ -3463,7 +1943,7 @@ index 5b7e100..e7b06ff 100644 bool * const tooManyColorsP) { /*---------------------------------------------------------------------------- Make a colormap (palette) for the PCX header that can be used -@@ -831,29 +785,29 @@ makePcxColormapFromImage(pixel ** const pixels, +@@ -831,29 +785,29 @@ makePcxColormapFromImage(pixel ** Iff there are too many colors to do that (i.e. more than 256), return *tooManyColorsP == TRUE. -----------------------------------------------------------------------------*/ @@ -3500,7 +1980,7 @@ index 5b7e100..e7b06ff 100644 pixel p; PPM_DEPTH(p, chv[i].color, maxval, PCX_MAXVAL); -@@ -870,9 +824,9 @@ makePcxColormapFromImage(pixel ** const pixels, +@@ -870,9 +824,9 @@ makePcxColormapFromImage(pixel ** pcxcmap[i].b = 0; } @@ -3512,7 +1992,7 @@ index 5b7e100..e7b06ff 100644 ppm_freecolorhist(chv); } -@@ -882,43 +836,43 @@ makePcxColormapFromImage(pixel ** const pixels, +@@ -882,43 +836,43 @@ makePcxColormapFromImage(pixel ** static void ppmToPalettePcx(pixel ** const pixels, @@ -3600,10 +2080,9 @@ index 5b7e100..e7b06ff 100644 ppm_freecolorhash(cht); free(pcxcmap); -diff --git a/converter/ppm/ppmtopict.c b/converter/ppm/ppmtopict.c -index 36464b6..c91ccf2 100644 ---- a/converter/ppm/ppmtopict.c -+++ b/converter/ppm/ppmtopict.c +diff -ruNp a/converter/ppm/ppmtopict.c b/converter/ppm/ppmtopict.c +--- a/converter/ppm/ppmtopict.c 2021-06-02 15:53:59.846205765 +0200 ++++ b/converter/ppm/ppmtopict.c 2021-06-02 20:23:21.824634387 +0200 @@ -450,6 +450,8 @@ main(int argc, const char ** argv) { putShort(stdout, 0); /* mode */ @@ -3613,10 +2092,9 @@ index 36464b6..c91ccf2 100644 outBuf = malloc((unsigned)(cols+cols/MAX_COUNT+1)); for (row = 0, oc = 0; row < rows; ++row) { unsigned int rowSize; -diff --git a/converter/ppm/ppmtopj.c b/converter/ppm/ppmtopj.c -index d116773..fc84cac 100644 ---- a/converter/ppm/ppmtopj.c -+++ b/converter/ppm/ppmtopj.c +diff -ruNp a/converter/ppm/ppmtopj.c b/converter/ppm/ppmtopj.c +--- a/converter/ppm/ppmtopj.c 2021-06-02 15:53:59.845205755 +0200 ++++ b/converter/ppm/ppmtopj.c 2021-06-02 20:23:21.824634387 +0200 @@ -179,6 +179,7 @@ char *argv[]; pixels = ppm_readppm( ifp, &cols, &rows, &maxval ); @@ -3625,10 +2103,9 @@ index d116773..fc84cac 100644 obuf = (unsigned char *) pm_allocrow(cols, sizeof(unsigned char)); cbuf = (unsigned char *) pm_allocrow(cols * 2, sizeof(unsigned char)); -diff --git a/converter/ppm/ppmtopjxl.c b/converter/ppm/ppmtopjxl.c -index 90bcef0..72d0027 100644 ---- a/converter/ppm/ppmtopjxl.c -+++ b/converter/ppm/ppmtopjxl.c +diff -ruNp a/converter/ppm/ppmtopjxl.c b/converter/ppm/ppmtopjxl.c +--- a/converter/ppm/ppmtopjxl.c 2021-06-02 15:53:59.845205755 +0200 ++++ b/converter/ppm/ppmtopjxl.c 2021-06-02 20:23:21.825634396 +0200 @@ -267,6 +267,9 @@ main(int argc, const char * argv[]) { if (maxval > PCL_MAXVAL) pm_error("color range too large; reduce with ppmcscale"); @@ -3662,10 +2139,9 @@ index 90bcef0..72d0027 100644 inrow = (char *)malloc((unsigned)bpp); outrow = (char *)malloc((unsigned)bpp*2); runcnt = (signed char *)malloc((unsigned)bpp); -diff --git a/converter/ppm/ppmtowinicon.c b/converter/ppm/ppmtowinicon.c -index c673798..af2b445 100644 ---- a/converter/ppm/ppmtowinicon.c -+++ b/converter/ppm/ppmtowinicon.c +diff -ruNp a/converter/ppm/ppmtowinicon.c b/converter/ppm/ppmtowinicon.c +--- a/converter/ppm/ppmtowinicon.c 2021-06-02 15:53:59.845205755 +0200 ++++ b/converter/ppm/ppmtowinicon.c 2021-06-02 20:23:21.825634396 +0200 @@ -12,6 +12,7 @@ #include @@ -3674,7 +2150,7 @@ index c673798..af2b445 100644 #include "pm_c_util.h" #include "winico.h" -@@ -214,6 +215,7 @@ createAndBitmap (gray ** const ba, int const cols, int const rows, +@@ -214,6 +215,7 @@ createAndBitmap (gray ** const ba, int c MALLOCARRAY_NOFAIL(rowData, rows); icBitmap->xBytes = xBytes; icBitmap->data = rowData; @@ -3682,7 +2158,7 @@ index c673798..af2b445 100644 icBitmap->size = xBytes * rows; for (y=0;yxBytes = xBytes; icBitmap->data = rowData; @@ -3690,7 +2166,7 @@ index c673798..af2b445 100644 icBitmap->size = xBytes * rows; for (y=0;yxBytes = xBytes; icBitmap->data = rowData; @@ -3698,7 +2174,7 @@ index c673798..af2b445 100644 icBitmap->size = xBytes * rows; for (y=0;ybitcount = bpp; entry->ih = createInfoHeader(entry, xorBitmap, andBitmap); entry->colors = palette->colors; @@ -3711,11 +2187,10 @@ index c673798..af2b445 100644 xorBitmap->size + andBitmap->size + 40 + (4 * entry->color_count); if (verbose) pm_message("entry->size_in_bytes = %d + %d + %d = %d", -diff --git a/converter/ppm/ppmtoxpm.c b/converter/ppm/ppmtoxpm.c -index 0e31692..1b3923f 100644 ---- a/converter/ppm/ppmtoxpm.c -+++ b/converter/ppm/ppmtoxpm.c -@@ -198,6 +198,7 @@ genNumstr(unsigned int const input, int const digits) { +diff -ruNp a/converter/ppm/ppmtoxpm.c b/converter/ppm/ppmtoxpm.c +--- a/converter/ppm/ppmtoxpm.c 2021-06-02 15:53:59.846205765 +0200 ++++ b/converter/ppm/ppmtoxpm.c 2021-06-02 20:23:21.826634405 +0200 +@@ -198,6 +198,7 @@ genNumstr(unsigned int const input, int unsigned int i; /* Allocate memory for printed number. Abort if error. */ @@ -3731,10 +2206,9 @@ index 0e31692..1b3923f 100644 MALLOCARRAY(cmap, cmapSize); if (cmapP == NULL) pm_error("Out of memory allocating %u bytes for a color map.", -diff --git a/converter/ppm/qrttoppm.c b/converter/ppm/qrttoppm.c -index 935463e..653084c 100644 ---- a/converter/ppm/qrttoppm.c -+++ b/converter/ppm/qrttoppm.c +diff -ruNp a/converter/ppm/qrttoppm.c b/converter/ppm/qrttoppm.c +--- a/converter/ppm/qrttoppm.c 2021-06-02 15:53:59.846205765 +0200 ++++ b/converter/ppm/qrttoppm.c 2021-06-02 20:23:21.826634405 +0200 @@ -46,7 +46,7 @@ main( argc, argv ) ppm_writeppminit( stdout, cols, rows, maxval, 0 ); @@ -3744,10 +2218,9 @@ index 935463e..653084c 100644 if ( buf == (unsigned char *) 0 ) pm_error( "out of memory" ); -diff --git a/converter/ppm/sldtoppm.c b/converter/ppm/sldtoppm.c -index 2fef023..1f30cbd 100644 ---- a/converter/ppm/sldtoppm.c -+++ b/converter/ppm/sldtoppm.c +diff -ruNp a/converter/ppm/sldtoppm.c b/converter/ppm/sldtoppm.c +--- a/converter/ppm/sldtoppm.c 2021-06-02 15:53:59.845205755 +0200 ++++ b/converter/ppm/sldtoppm.c 2021-06-02 20:23:21.827634413 +0200 @@ -154,127 +154,85 @@ vscale(int * const px, @@ -3955,10 +2428,9 @@ index 2fef023..1f30cbd 100644 pixels = ppm_allocarray(pixcols = ixdots + 1, pixrows = iydots + 1); PPM_ASSIGN(rgbcolor, 0, 0, 0); ppmd_filledrectangle(pixels, pixcols, pixrows, pixmaxval, 0, 0, -diff --git a/converter/ppm/ximtoppm.c b/converter/ppm/ximtoppm.c -index d839e77..e9083f3 100644 ---- a/converter/ppm/ximtoppm.c -+++ b/converter/ppm/ximtoppm.c +diff -ruNp a/converter/ppm/ximtoppm.c b/converter/ppm/ximtoppm.c +--- a/converter/ppm/ximtoppm.c 2021-06-02 15:53:59.846205765 +0200 ++++ b/converter/ppm/ximtoppm.c 2021-06-02 20:23:21.828634422 +0200 @@ -22,9 +22,7 @@ #include "shhopt.h" #include "nstring.h" @@ -3981,7 +2453,7 @@ index d839e77..e9083f3 100644 /*---------------------------------------------------------------------------- Note that many of the strings that this function returns in the *cmdlineP structure are actually in the supplied argv array. And -@@ -59,7 +57,7 @@ parseCommandLine(int argc, const char ** argv, +@@ -59,7 +57,7 @@ parseCommandLine(int argc, const char ** opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ @@ -4057,7 +2529,7 @@ index d839e77..e9083f3 100644 header->colors = (Color *)calloc((unsigned int)header->ncolors, sizeof(Color)); if (header->colors == NULL) { -@@ -197,8 +215,7 @@ ReadImageChannel(FILE * const infp, +@@ -197,8 +215,7 @@ ReadImageChannel(FILE * const in } /* return to the beginning of the next image's buffer */ if (fseek(infp, marker, 0) == -1) { @@ -4116,11 +2588,10 @@ index d839e77..e9083f3 100644 parseCommandLine(argc, argv, &cmdline); -diff --git a/editor/pamcut.c b/editor/pamcut.c -index 1fc9d9b..ad0e030 100644 ---- a/editor/pamcut.c -+++ b/editor/pamcut.c -@@ -799,6 +799,8 @@ cutOneImage(FILE * const ifP, +diff -ruNp a/editor/pamcut.c b/editor/pamcut.c +--- a/editor/pamcut.c 2021-06-02 15:53:59.809205409 +0200 ++++ b/editor/pamcut.c 2021-06-02 20:23:21.828634422 +0200 +@@ -799,6 +799,8 @@ cutOneImage(FILE * const ifP outpam = inpam; /* Initial value -- most fields should be same */ outpam.file = ofP; @@ -4129,11 +2600,10 @@ index 1fc9d9b..ad0e030 100644 outpam.width = rightcol - leftcol + 1; outpam.height = bottomrow - toprow + 1; -diff --git a/editor/pnmgamma.c b/editor/pnmgamma.c -index 1fdf20e..98b7e90 100644 ---- a/editor/pnmgamma.c -+++ b/editor/pnmgamma.c -@@ -596,6 +596,7 @@ createGammaTables(enum transferFunction const transferFunction, +diff -ruNp a/editor/pnmgamma.c b/editor/pnmgamma.c +--- a/editor/pnmgamma.c 2021-06-02 15:53:59.805205371 +0200 ++++ b/editor/pnmgamma.c 2021-06-02 20:23:21.829634431 +0200 +@@ -596,6 +596,7 @@ createGammaTables(enum transferFunction xelval ** const btableP) { /* Allocate space for the tables. */ @@ -4141,11 +2611,10 @@ index 1fdf20e..98b7e90 100644 MALLOCARRAY(*rtableP, maxval+1); MALLOCARRAY(*gtableP, maxval+1); MALLOCARRAY(*btableP, maxval+1); -diff --git a/editor/pnmhisteq.c b/editor/pnmhisteq.c -index a339f73..c2c85a3 100644 ---- a/editor/pnmhisteq.c -+++ b/editor/pnmhisteq.c -@@ -107,6 +107,7 @@ computeLuminosityHistogram(xel * const * const xels, +diff -ruNp a/editor/pnmhisteq.c b/editor/pnmhisteq.c +--- a/editor/pnmhisteq.c 2021-06-02 15:53:59.800205323 +0200 ++++ b/editor/pnmhisteq.c 2021-06-02 20:23:21.829634431 +0200 +@@ -107,6 +107,7 @@ computeLuminosityHistogram(xel * const * unsigned int pixelCount; unsigned int * lumahist; @@ -4153,10 +2622,9 @@ index a339f73..c2c85a3 100644 MALLOCARRAY(lumahist, maxval + 1); if (lumahist == NULL) pm_error("Out of storage allocating array for %u histogram elements", -diff --git a/editor/pnmindex.csh b/editor/pnmindex.csh -index c6f1e84..c513a84 100755 ---- a/editor/pnmindex.csh -+++ b/editor/pnmindex.csh +diff -ruNp a/editor/pnmindex.csh b/editor/pnmindex.csh +--- a/editor/pnmindex.csh 2021-06-02 15:53:59.801205332 +0200 ++++ b/editor/pnmindex.csh 2021-06-02 20:23:21.829634431 +0200 @@ -1,5 +1,7 @@ #!/bin/csh -f # @@ -4165,10 +2633,9 @@ index c6f1e84..c513a84 100755 # pnmindex - build a visual index of a bunch of anymaps # # Copyright (C) 1991 by Jef Poskanzer. -diff --git a/editor/pnmpad.c b/editor/pnmpad.c -index 55cdcd6..10da3af 100644 ---- a/editor/pnmpad.c -+++ b/editor/pnmpad.c +diff -ruNp a/editor/pnmpad.c b/editor/pnmpad.c +--- a/editor/pnmpad.c 2021-06-02 15:53:59.808205400 +0200 ++++ b/editor/pnmpad.c 2021-06-02 20:23:21.829634431 +0200 @@ -654,6 +654,8 @@ main(int argc, const char ** argv) { computePadSizes(cmdline, cols, rows, &lpad, &rpad, &tpad, &bpad); @@ -4178,11 +2645,10 @@ index 55cdcd6..10da3af 100644 newcols = cols + lpad + rpad; if (cmdline.reportonly) -diff --git a/editor/pnmremap.c b/editor/pnmremap.c -index 0c0096b..8b86cb7 100644 ---- a/editor/pnmremap.c -+++ b/editor/pnmremap.c -@@ -468,6 +468,7 @@ fserr_init(struct pam * const pamP, +diff -ruNp a/editor/pnmremap.c b/editor/pnmremap.c +--- a/editor/pnmremap.c 2021-06-02 15:53:59.809205409 +0200 ++++ b/editor/pnmremap.c 2021-06-02 20:23:21.830634440 +0200 +@@ -470,6 +470,7 @@ fserr_init(struct pam * const pamP, unsigned int const fserrSize = pamP->width + 2; @@ -4190,7 +2656,7 @@ index 0c0096b..8b86cb7 100644 fserrP->width = pamP->width; MALLOCARRAY(fserrP->thiserr, pamP->depth); -@@ -506,6 +507,7 @@ floydInitRow(struct pam * const pamP, +@@ -508,6 +509,7 @@ floydInitRow(struct pam * const pamP, unsigned int col; @@ -4198,27 +2664,10 @@ index 0c0096b..8b86cb7 100644 for (col = 0; col < pamP->width + 2; ++col) { unsigned int plane; for (plane = 0; plane < pamP->depth; ++plane) -diff --git a/editor/pnmremap.c.rej b/editor/pnmremap.c.rej -new file mode 100644 -index 0000000..c627c20 ---- /dev/null -+++ b/editor/pnmremap.c.rej -@@ -0,0 +1,10 @@ -+--- editor/pnmremap.c -++++ editor/pnmremap.c -+@@ -506,6 +507,7 @@ floydInitRow(struct pam * const pamP, struct Fserr * const fserrP) { -+ -+ int col; -+ -++ overflow_add(pamP->width, 2); -+ for (col = 0; col < pamP->width + 2; ++col) { -+ unsigned int plane; -+ for (plane = 0; plane < pamP->depth; ++plane) -diff --git a/editor/pnmscalefixed.c b/editor/pnmscalefixed.c -index 884ca31..747cd8f 100644 ---- a/editor/pnmscalefixed.c -+++ b/editor/pnmscalefixed.c -@@ -214,6 +214,7 @@ compute_output_dimensions(const struct cmdline_info cmdline, +diff -ruNp a/editor/pnmscalefixed.c b/editor/pnmscalefixed.c +--- a/editor/pnmscalefixed.c 2021-06-02 15:53:59.800205323 +0200 ++++ b/editor/pnmscalefixed.c 2021-06-02 20:23:21.830634440 +0200 +@@ -214,6 +214,7 @@ compute_output_dimensions(const struct c const int rows, const int cols, int * newrowsP, int * newcolsP) { @@ -4226,7 +2675,7 @@ index 884ca31..747cd8f 100644 if (cmdline.pixels) { if (rows * cols <= cmdline.pixels) { *newrowsP = rows; -@@ -265,6 +266,8 @@ compute_output_dimensions(const struct cmdline_info cmdline, +@@ -265,6 +266,8 @@ compute_output_dimensions(const struct c if (*newcolsP < 1) *newcolsP = 1; if (*newrowsP < 1) *newrowsP = 1; @@ -4245,11 +2694,10 @@ index 884ca31..747cd8f 100644 sxscale = SCALE * newcols / cols; syscale = SCALE * newrows / rows; -diff --git a/editor/ppmdither.c b/editor/ppmdither.c -index ec1b977..e701e09 100644 ---- a/editor/ppmdither.c -+++ b/editor/ppmdither.c -@@ -356,6 +356,11 @@ dithMatrix(unsigned int const dithPower) { +diff -ruNp a/editor/ppmdither.c b/editor/ppmdither.c +--- a/editor/ppmdither.c 2021-06-02 15:53:59.803205352 +0200 ++++ b/editor/ppmdither.c 2021-06-02 20:23:21.831634448 +0200 +@@ -356,6 +356,11 @@ dithMatrix(unsigned int const dithPower) (dithDim * sizeof(*dithMat)) + /* pointers */ (dithDim * dithDim * sizeof(**dithMat)); /* data */ @@ -4261,10 +2709,9 @@ index ec1b977..e701e09 100644 dithMat = malloc(dithMatSize); if (dithMat == NULL) -diff --git a/editor/specialty/pamoil.c b/editor/specialty/pamoil.c -index 6cb8d3a..6f4bde9 100644 ---- a/editor/specialty/pamoil.c -+++ b/editor/specialty/pamoil.c +diff -ruNp a/editor/specialty/pamoil.c b/editor/specialty/pamoil.c +--- a/editor/specialty/pamoil.c 2021-06-02 15:53:59.817205486 +0200 ++++ b/editor/specialty/pamoil.c 2021-06-02 20:23:21.831634448 +0200 @@ -112,6 +112,7 @@ main(int argc, char *argv[] ) { tuples = pnm_readpam(ifp, &inpam, PAM_STRUCT_SIZE(tuple_type)); pm_close(ifp); @@ -4273,11 +2720,10 @@ index 6cb8d3a..6f4bde9 100644 MALLOCARRAY(hist, inpam.maxval + 1); if (hist == NULL) pm_error("Unable to allocate memory for histogram."); -diff --git a/lib/libpam.c b/lib/libpam.c -index d19534e..ca6250a 100644 ---- a/lib/libpam.c -+++ b/lib/libpam.c -@@ -225,7 +225,8 @@ allocPamRow(const struct pam * const pamP) { +diff -ruNp a/lib/libpam.c b/lib/libpam.c +--- a/lib/libpam.c 2021-06-02 15:53:59.867205967 +0200 ++++ b/lib/libpam.c 2021-06-02 20:23:21.832634457 +0200 +@@ -225,7 +225,8 @@ allocPamRow(const struct pam * const pam unsigned int const bytesPerTuple = allocationDepth(pamP) * sizeof(sample); tuple * tuplerow; @@ -4287,371 +2733,22 @@ index d19534e..ca6250a 100644 if (tuplerow != NULL) { /* Now we initialize the pointers to the individual tuples -diff --git a/lib/libpammap.c b/lib/libpammap.c -index 569156f..ba27a4c 100644 ---- a/lib/libpammap.c -+++ b/lib/libpammap.c -@@ -64,7 +64,7 @@ pnm_createtuplehash(void) { - pm_error("Out of memory allocating tuple hash of size %u", - HASH_SIZE); - -- for (i = 0; i < HASH_SIZE; ++i) -+ for (i = 0; i < HASH_SIZE; ++i) - retval[i] = NULL; - - return retval; -@@ -82,13 +82,13 @@ pnm_destroytuplehash(tuplehash const tuplehash) { - for (i = 0; i < HASH_SIZE; ++i) { - struct tupleint_list_item * p; - struct tupleint_list_item * next; -- -+ - /* Walk this chain, freeing each element */ - for (p = tuplehash[i]; p; p = next) { - next = p->next; - - free(p); -- } -+ } - } - - /* Free the table of chains */ -@@ -98,18 +98,20 @@ pnm_destroytuplehash(tuplehash const tuplehash) { - - - --static struct tupleint_list_item * -+static struct tupleint_list_item * - allocTupleIntListItem(struct pam * const pamP) { - - -- /* This is complicated by the fact that the last element of a -+ /* This is complicated by the fact that the last element of a - tupleint_list_item is of variable length, because the last element -- of _it_ is of variable length -+ of _it_ is of variable length +diff -ruNp a/lib/libpammap.c b/lib/libpammap.c +--- a/lib/libpammap.c 2021-06-02 15:53:59.867205967 +0200 ++++ b/lib/libpammap.c 2021-06-02 20:23:00.658449503 +0200 +@@ -108,6 +108,8 @@ allocTupleIntListItem(struct pam * const */ struct tupleint_list_item * retval; + overflow2(pamP->depth, sizeof(sample)); + overflow_add(sizeof(*retval)-sizeof(retval->tupleint.tuple), pamP->depth*sizeof(sample)); unsigned int const size = -- sizeof(*retval) - sizeof(retval->tupleint.tuple) -+ sizeof(*retval) - sizeof(retval->tupleint.tuple) + sizeof(*retval) - sizeof(retval->tupleint.tuple) + pamP->depth * sizeof(sample); - - retval = (struct tupleint_list_item *) malloc(size); -@@ -121,7 +123,7 @@ allocTupleIntListItem(struct pam * const pamP) { - - void - pnm_addtotuplehash(struct pam * const pamP, -- tuplehash const tuplehash, -+ tuplehash const tuplehash, - tuple const tupletoadd, - int const value, - int * const fitsP) { -@@ -138,7 +140,7 @@ pnm_addtotuplehash(struct pam * const pamP, - *fitsP = FALSE; - else { - unsigned int const hashvalue = pnm_hashtuple(pamP, tupletoadd); -- -+ - *fitsP = TRUE; - - pnm_assigntuple(pamP, listItemP->tupleint.tuple, tupletoadd); -@@ -151,10 +153,10 @@ pnm_addtotuplehash(struct pam * const pamP, - - - void --pnm_lookuptuple(struct pam * const pamP, -- const tuplehash tuplehash, -- const tuple searchval, -- int * const foundP, -+pnm_lookuptuple(struct pam * const pamP, -+ const tuplehash tuplehash, -+ const tuple searchval, -+ int * const foundP, - int * const retvalP) { - /*---------------------------------------------------------------------------- - Return as *revtvalP the index of the tuple value 'searchval' in the -@@ -183,18 +185,18 @@ pnm_lookuptuple(struct pam * const pamP, - - - static void --addColorOccurrenceToHash(tuple const color, -+addColorOccurrenceToHash(tuple const color, - tuplehash const tuplefreqhash, - struct pam * const pamP, - unsigned int const maxsize, - unsigned int * const sizeP, - bool * const fullP) { -- -+ - unsigned int const hashvalue = pnm_hashtuple(pamP, color); -- -+ - struct tupleint_list_item *p; - -- for (p = tuplefreqhash[hashvalue]; -+ for (p = tuplefreqhash[hashvalue]; - p && !pnm_tupleequal(pamP, p->tupleint.tuple, color); - p = p->next); - -@@ -205,7 +207,7 @@ addColorOccurrenceToHash(tuple const color, - } else { - /* It's not in the hash yet, so add it (if allowed) */ - ++(*sizeP); -- if (maxsize > 0 && *sizeP > maxsize) -+ if (maxsize > 0 && *sizeP > maxsize) - *fullP = TRUE; - else { - *fullP = FALSE; -@@ -228,7 +230,7 @@ pnm_addtuplefreqoccurrence(struct pam * const pamP, - tuplehash const tuplefreqhash, - int * const firstOccurrenceP) { - /*---------------------------------------------------------------------------- -- Tally one more occurrence of the tuple value 'value' to the tuple frequency -+ Tally one more occurence of the tuple value 'value' to the tuple frequencey - hash 'tuplefreqhash', adding the tuple to the hash if it isn't there - already. - -@@ -238,10 +240,10 @@ pnm_addtuplefreqoccurrence(struct pam * const pamP, - program. - -----------------------------------------------------------------------------*/ - unsigned int const hashvalue = pnm_hashtuple(pamP, value); -- -+ - struct tupleint_list_item * p; - -- for (p = tuplefreqhash[hashvalue]; -+ for (p = tuplefreqhash[hashvalue]; - p && !pnm_tupleequal(pamP, p->tupleint.tuple, value); - p = p->next); - -@@ -270,8 +272,8 @@ pnm_addtuplefreqoccurrence(struct pam * const pamP, - - static void - computehashrecoverable(struct pam * const pamP, -- tuple ** const tupleArray, -- unsigned int const maxsize, -+ tuple ** const tupleArray, -+ unsigned int const maxsize, - unsigned int const newDepth, - sample const newMaxval, - unsigned int * const sizeP, -@@ -295,20 +297,20 @@ computehashrecoverable(struct pam * const pamP, - - *tuplefreqhashP = pnm_createtuplehash(); - *sizeP = 0; /* initial value */ -- -+ - *rowbufferP = pnm_allocpamrow(pamP); -- -+ - *colorP = pnm_allocpamtuple(pamP); -- -+ - full = FALSE; /* initial value */ -- -+ - /* Go through the entire raster, building a hash table of -- tuple values. -+ tuple values. - */ - for (row = 0; row < pamP->height && !full; ++row) { - unsigned int col; - const tuple * tuplerow; /* The row of tuples we are processing */ -- -+ - if (tupleArray) - tuplerow = tupleArray[row]; - else { -@@ -335,8 +337,8 @@ computehashrecoverable(struct pam * const pamP, - - static tuplehash - computetuplefreqhash(struct pam * const pamP, -- tuple ** const tupleArray, -- unsigned int const maxsize, -+ tuple ** const tupleArray, -+ unsigned int const maxsize, - unsigned int const newDepth, - sample const newMaxval, - unsigned int * const sizeP) { -@@ -350,18 +352,18 @@ computetuplefreqhash(struct pam * const pamP, - - 2) an open PAM file, positioned to the raster. In this case, - 'tupleArray' is NULL. *pamP contains the file descriptor. -- -- We return with the file still open and its position undefined. -+ -+ We return with the file still open and its position undefined. - - In either case, *pamP contains parameters of the tuple array. - - Return the number of unique tuple values found as *sizeP. - -- However, if the number of unique tuple values is greater than 'maxsize', -+ However, if the number of unique tuple values is greater than 'maxsize', - return a null return value and *sizeP undefined. - - The tuple values that index the hash have depth 'newDepth'. We look at -- only the first 'newDepth' planes of the input. Caller must ensure that -+ only the first 'newDepth' planes of the input. Caler must ensure that - the input has at least that many planes. - - The tuple values that index the hash are scaled to a new maxval of -@@ -374,18 +376,18 @@ computetuplefreqhash(struct pam * const pamP, - /* Buffer for a row read from the input file; undefined (but still - allocated) if input is not from a file. - */ -- tuple color; -+ tuple color; - /* The color currently being added, scaled to the new maxval */ - jmp_buf jmpbuf; - jmp_buf * origJmpbufP; -- -+ - /* Initialize to "none" for purposes of error recovery */ - tuplefreqhash = NULL; - rowbuffer = NULL; - color = NULL; - - if (setjmp(jmpbuf) != 0) { -- if (color) -+ if (color) - pnm_freepamtuple(color); - if (rowbuffer) - pnm_freepamrow(rowbuffer); -@@ -413,24 +415,24 @@ pnm_computetuplefreqhash(struct pam * const pamP, - Compute the tuple frequency hash for the tuple array tupleArray[][]. - -----------------------------------------------------------------------------*/ - return computetuplefreqhash(pamP, tupleArray, maxsize, -- pamP->depth, pamP->maxval, -+ pamP->depth, pamP->maxval, - sizeP); - } - - - - static void --alloctupletable(const struct pam * const pamP, -+alloctupletable(const struct pam * const pamP, - unsigned int const size, - tupletable * const tupletableP, - const char ** const errorP) { -- -+ - if (UINT_MAX / sizeof(struct tupleint) < size) - pm_asprintf(errorP, "size %u is too big for arithmetic", size); - else { - unsigned int const mainTableSize = size * sizeof(struct tupleint *); -- unsigned int const tupleIntSize = -- sizeof(struct tupleint) - sizeof(sample) -+ unsigned int const tupleIntSize = -+ sizeof(struct tupleint) - sizeof(sample) - + pamP->depth * sizeof(sample); - - /* To save the enormous amount of time it could take to allocate -@@ -442,7 +444,7 @@ alloctupletable(const struct pam * const pamP, - else { - unsigned int const allocSize = mainTableSize + size * tupleIntSize; - void * pool; -- -+ - pool = malloc(allocSize); - - if (!pool) -@@ -469,7 +471,7 @@ alloctupletable(const struct pam * const pamP, - - - tupletable --pnm_alloctupletable(const struct pam * const pamP, -+pnm_alloctupletable(const struct pam * const pamP, - unsigned int const size) { - - tupletable retval; -@@ -491,8 +493,8 @@ void - pnm_freetupletable(const struct pam * const pamP, - tupletable const tupletable) { - -- /* Note that the address 'tupletable' is, to the operating system, -- the address of a larger block of memory that contains not only -+ /* Note that the address 'tupletable' is, to the operating system, -+ the address of a larger block of memory that contains not only - tupletable, but all the samples to which it points (e.g. - tupletable[0].tuple[0]) - */ -@@ -574,7 +576,7 @@ pnm_tuplehashtotable(const struct pam * const pamP, - - - tuplehash --pnm_computetupletablehash(struct pam * const pamP, -+pnm_computetupletablehash(struct pam * const pamP, - tupletable const tupletable, - unsigned int const tupletableSize) { - /*---------------------------------------------------------------------------- -@@ -591,12 +593,12 @@ pnm_computetupletablehash(struct pam * const pamP, - tuplehash tupletablehash; - unsigned int i; - int fits; -- -+ - tupletablehash = pnm_createtuplehash(); - - fits = TRUE; /* initial assumption */ - for (i = 0; i < tupletableSize && fits; ++i) { -- pnm_addtotuplehash(pamP, tupletablehash, -+ pnm_addtotuplehash(pamP, tupletablehash, - tupletable[i]->tuple, i, &fits); - } - if (!fits) { -@@ -658,7 +660,7 @@ pnm_computetuplefreqtable3(struct pam * const pamP, - "argument (%u) greater than input depth (%u)", - newDepth, pamP->depth); - -- tuplefreqhash = computetuplefreqhash(pamP, tupleArray, maxsize, -+ tuplefreqhash = computetuplefreqhash(pamP, tupleArray, maxsize, - newDepth, newMaxval, &uniqueCount); - if (tuplefreqhash == NULL) - tuplefreqtable = NULL; -@@ -704,8 +706,8 @@ pnm_computetuplefreqtable(struct pam * const pamP, - - - char* --pam_colorname(struct pam * const pamP, -- tuple const color, -+pam_colorname(struct pam * const pamP, -+ tuple const color, - enum colornameFormat const format) { - - unsigned int r, g, b; -@@ -726,9 +728,9 @@ pam_colorname(struct pam * const pamP, - while (!done) { - struct colorfile_entry const ce = pm_colorget(f); - if (ce.colorname) { -- unsigned int const this_diff = -- abs((int)r - (int)ce.r) + -- abs((int)g - (int)ce.g) + -+ unsigned int const this_diff = -+ abs((int)r - (int)ce.r) + -+ abs((int)g - (int)ce.g) + - abs((int)b - (int)ce.b); - - if (this_diff < best_diff) { -@@ -739,7 +741,7 @@ pam_colorname(struct pam * const pamP, - done = TRUE; - } - fclose(f); -- if (best_diff != 32767 && -+ if (best_diff != 32767 && - (best_diff == 0 || format == PAM_COLORNAME_ENGLISH)) - return colorname; - } -diff --git a/lib/libpm.c b/lib/libpm.c -index bc92238..aa67dcd 100644 ---- a/lib/libpm.c -+++ b/lib/libpm.c -@@ -888,5 +888,53 @@ pm_parse_height(const char * const arg) { +diff -ruNp a/lib/libpm.c b/lib/libpm.c +--- a/lib/libpm.c 2021-06-02 15:53:59.867205967 +0200 ++++ b/lib/libpm.c 2021-06-02 20:23:21.832634457 +0200 +@@ -888,5 +888,53 @@ pm_parse_height(const char * const arg) return height; } @@ -4705,11 +2802,10 @@ index bc92238..aa67dcd 100644 + return realloc(a, b*c); +} -diff --git a/lib/pm.h b/lib/pm.h -index 3fc92fb..1e30ce9 100644 ---- a/lib/pm.h -+++ b/lib/pm.h -@@ -441,5 +441,12 @@ pm_parse_height(const char * const arg); +diff -ruNp a/lib/pm.h b/lib/pm.h +--- a/lib/pm.h 2021-06-02 15:53:59.866205957 +0200 ++++ b/lib/pm.h 2021-06-02 20:23:21.833634466 +0200 +@@ -442,5 +442,12 @@ pm_parse_height(const char * const arg); } #endif @@ -4722,463 +2818,10 @@ index 3fc92fb..1e30ce9 100644 + #endif -diff --git a/lib/pm.h.orig b/lib/pm.h.orig -new file mode 100644 -index 0000000..471f445 ---- /dev/null -+++ b/lib/pm.h.orig -@@ -0,0 +1,446 @@ -+/* pm.h - interface to format-independent part of libpbm. -+** -+** Copyright (C) 1988, 1989, 1991 by Jef Poskanzer. -+** -+** Permission to use, copy, modify, and distribute this software and its -+** documentation for any purpose and without fee is hereby granted, provided -+** that the above copyright notice appear in all copies and that both that -+** copyright notice and this permission notice appear in supporting -+** documentation. This software is provided "as is" without express or -+** implied warranty. -+*/ -+ -+#ifndef PM_H_INCLUDED -+#define PM_H_INCLUDED -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+#if 0 -+} /* to fake out automatic code indenters */ -+#endif -+ -+ -+/* Definitions to make Netpbm programs work with either ANSI C or C -+ Classic. -+ -+ This is obsolete, as all compilers recognize the ANSI syntax now. -+ -+ We are slowly removing all the ARGS invocations from the programs -+ (and replacing them with explicit ANSI syntax), but we have a lot -+ of programs where we have removed ARGS from the definition but not -+ the prototype, and we have discovered that the Sun compiler -+ considers the resulting mismatch between definition and prototype -+ to be an error. So we make ARGS create the ANSI syntax -+ unconditionally to avoid having to fix all those mismatches. */ -+ -+#if 0 -+#if __STDC__ -+#define ARGS(alist) alist -+#else /*__STDC__*/ -+#define ARGS(alist) () -+#define const -+#endif /*__STDC__*/ -+#endif -+#define ARGS(alist) alist -+ -+ -+/* PM_GNU_PRINTF_ATTR lets the GNU compiler check pm_message() and pm_error() -+ calls to be sure the arguments match the format string, thus preventing -+ runtime segmentation faults and incorrect messages. -+*/ -+#ifdef __GNUC__ -+#define PM_GNU_PRINTF_ATTR(a,b) __attribute__ ((format (printf, a, b))) -+#else -+#define PM_GNU_PRINTF_ATTR(a,b) -+#endif -+ -+ -+/* PURE_FN_ATTR is the attribute you add to a function declaration -+ that indicates it's a true function -- has no side effects and return -+ value is not influenced by anything except its arguments. -+*/ -+#ifdef __GNUC__ -+#define PURE_FN_ATTR __attribute__ ((const)) -+#else -+#define PURE_FN_ATTR -+#endif -+ -+ -+/* S_IRUSR is POSIX, defined in Some old BSD systems and Windows -+ systems have S_IREAD instead. Most Unix today (2011) has both. In 2011, -+ Android has S_IRUSR and not S_IREAD. -+ -+ Some Windows has _S_IREAD. -+ -+ We're ignoring S_IREAD now to see if anyone misses it. If there are still -+ users that need it, we can handle it here. -+*/ -+#if MSVCRT -+ #define PM_S_IWUSR _S_IWRITE -+ #define PM_S_IRUSR _S_IREAD -+#else -+ #define PM_S_IWUSR S_IWUSR -+ #define PM_S_IRUSR S_IRUSR -+#endif -+ -+ -+ -+typedef struct { -+ /* Coordinates of a pixel within an image. Row 0 is the top row. -+ Column 0 is the left column. -+ */ -+ unsigned int row; -+ unsigned int col; -+} pm_pixelcoord; -+ -+extern int pm_plain_output; -+ /* Output functions are to produce plain (as opposed to raw) format -+ regardless of their 'plainformat' arguments. -+ */ -+extern const char * pm_progname; -+ -+void -+pm_init(const char * const progname, unsigned int const flags); -+ -+void -+pm_proginit(int * const argcP, const char * argv[]); -+ -+void -+pm_setMessage(int const newState, int * const oldStateP); -+ -+int -+pm_getMessage(void); -+ -+FILE * -+pm_tmpfile(void); -+ -+int -+pm_tmpfile_fd(void); -+ -+void -+pm_make_tmpfile(FILE ** const filePP, -+ const char ** const filenameP); -+ -+void -+pm_make_tmpfile_fd(int * const fdP, -+ const char ** const filenameP); -+ -+void -+pm_nextimage(FILE * const file, int * const eofP); -+ -+/* Variable-sized arrays definitions. */ -+ -+char** -+pm_allocarray (int const cols, int const rows, int const size ); -+ -+void * -+pm_allocrow(unsigned int const cols, -+ unsigned int const size); -+ -+void -+pm_freearray (char** const its, int const rows); -+ -+void -+pm_freerow(void * const row); -+ -+ -+/* Obsolete -- use shhopt instead */ -+int -+pm_keymatch(const char * const str, -+ const char * const keyword, -+ int const minchars); -+ -+ -+int PURE_FN_ATTR -+pm_maxvaltobits(int const maxval); -+ -+int PURE_FN_ATTR -+pm_bitstomaxval(int const bits); -+ -+unsigned int PURE_FN_ATTR -+pm_lcm (unsigned int const x, -+ unsigned int const y, -+ unsigned int const z, -+ unsigned int const limit); -+ -+void -+pm_setjmpbuf(jmp_buf * const jmpbufP); -+ -+void -+pm_setjmpbufsave(jmp_buf * const jmpbufP, -+ jmp_buf ** const oldJmpbufPP); -+ -+void -+pm_longjmp(void); -+ -+void -+pm_fork(int * const iAmParentP, -+ pid_t * const childPidP, -+ const char ** const errorP); -+ -+void -+pm_waitpid(pid_t const pid, -+ int * const statusP, -+ int const options, -+ pid_t * const exitedPidP, -+ const char ** const errorP); -+ -+ -+void -+pm_waitpidSimple(pid_t const pid); -+ -+typedef void pm_usermessagefn(const char * msg); -+ -+void -+pm_setusermessagefn(pm_usermessagefn * fn); -+ -+typedef void pm_usererrormsgfn(const char * msg); -+ -+void -+pm_setusererrormsgfn(pm_usererrormsgfn * fn); -+ -+void PM_GNU_PRINTF_ATTR(1,2) -+pm_message (const char format[], ...); -+ -+void PM_GNU_PRINTF_ATTR(1,2) -+pm_errormsg(const char format[], ...); -+ -+void PM_GNU_PRINTF_ATTR(1,2) -+pm_error (const char reason[], ...); -+ -+int -+pm_have_float_format(void); -+ -+/* Obsolete - use shhopt and user's manual instead */ -+void -+pm_usage (const char usage[]); -+ -+FILE* -+pm_openr (const char* const name); -+ -+FILE* -+pm_openw (const char* const name); -+ -+FILE * -+pm_openr_seekable(const char name[]); -+ -+void -+pm_close (FILE* const f); -+ -+void -+pm_closer (FILE* const f); -+ -+void -+pm_closew (FILE* const f); -+ -+ -+ -+void -+pm_readchar(FILE * const ifP, -+ char * const cP); -+ -+static __inline__ void -+pm_readcharu(FILE * const ifP, -+ unsigned char * const cP) { -+ pm_readchar(ifP, (char *) cP); -+} -+ -+void -+pm_writechar(FILE * const ofP, -+ char const c); -+ -+static __inline__ void -+pm_writecharu(FILE * const ofP, -+ unsigned char const c) { -+ pm_writechar(ofP, (char) c); -+} -+ -+int -+pm_readbigshort(FILE * const ifP, -+ short * const sP); -+ -+static __inline__ int -+pm_readbigshortu(FILE* const ifP, -+ unsigned short * const sP) { -+ return pm_readbigshort(ifP, (short *) sP); -+} -+ -+int -+pm_writebigshort(FILE * const ofP, -+ short const s); -+ -+static __inline__ int -+pm_writebigshortu(FILE * const ofP, -+ unsigned short const s) { -+ return pm_writebigshort(ofP, (short) s); -+} -+ -+int -+pm_readbiglong(FILE * const ifP, -+ long * const lP); -+ -+static __inline__ int -+pm_readbiglongu(FILE * const ifP, -+ unsigned long * const lP) { -+ return pm_readbiglong(ifP, (long *) lP); -+} -+ -+int -+pm_readbiglong2(FILE * const ifP, -+ int32_t * const lP); -+ -+static __inline__ int -+pm_readbiglongu2(FILE * const ifP, -+ uint32_t * const lP) { -+ return pm_readbiglong2(ifP, (int32_t *) lP); -+} -+ -+int -+pm_writebiglong(FILE * const ofP, -+ long const l); -+ -+static __inline__ int -+pm_writebiglongu(FILE * const ofP, -+ unsigned long const l) { -+ return pm_writebiglong(ofP, (long) l); -+} -+ -+int -+pm_readlittleshort(FILE * const ifP, -+ short * const sP); -+ -+static __inline__ int -+pm_readlittleshortu(FILE * const ifP, -+ unsigned short * const sP) { -+ return pm_readlittleshort(ifP, (short *) sP); -+} -+ -+int -+pm_writelittleshort(FILE * const ofP, -+ short const s); -+ -+static __inline__ int -+pm_writelittleshortu(FILE * const ofP, -+ unsigned short const s) { -+ return pm_writelittleshort(ofP, (short) s); -+} -+ -+int -+pm_readlittlelong(FILE * const ifP, -+ long * const lP); -+ -+static __inline__ int -+pm_readlittlelongu(FILE * const ifP, -+ unsigned long * const lP) { -+ return pm_readlittlelong(ifP, (long *) lP); -+} -+ -+int -+pm_readlittlelong2(FILE * const ifP, -+ int32_t * const lP); -+ -+static __inline__ int -+pm_readlittlelong2u(FILE * const ifP, -+ uint32_t * const lP) { -+ return pm_readlittlelong2(ifP, (int32_t *) lP); -+} -+ -+int -+pm_writelittlelong(FILE * const ofP, -+ long const l); -+ -+static __inline__ int -+pm_writelittlelongu(FILE * const ofP, -+ unsigned long const l) { -+ return pm_writelittlelong(ofP, (long) l); -+} -+ -+int -+pm_readmagicnumber(FILE * const ifP); -+ -+char* -+pm_read_unknown_size(FILE * const ifP, -+ long * const buf); -+ -+void -+pm_getline(FILE * const ifP, -+ char ** const bufferP, -+ size_t * const bufferSzP, -+ int * const eofP, -+ size_t * const lineLenP); -+ -+short -+pm_bs_short(short const s); -+ -+long -+pm_bs_long(long const l); -+ -+unsigned int -+pm_tell(FILE * const fileP); -+ -+void -+pm_tell2(FILE * const fileP, -+ void * const fileposP, -+ unsigned int const fileposSize); -+ -+void -+pm_seek2(FILE * const fileP, -+ const pm_filepos * const fileposP, -+ unsigned int const fileposSize); -+ -+void -+pm_seek(FILE * const fileP, unsigned long filepos); -+ -+enum pm_check_code { -+ PM_CHECK_OK, -+ PM_CHECK_UNKNOWN_TYPE, -+ PM_CHECK_TOO_LONG, -+ PM_CHECK_UNCHECKABLE, -+ PM_CHECK_TOO_SHORT -+}; -+ -+enum pm_check_type { -+ PM_CHECK_BASIC -+}; -+ -+void -+pm_check(FILE * const file, -+ enum pm_check_type const check_type, -+ pm_filepos const need_raster_size, -+ enum pm_check_code * const retval_p); -+ -+void -+pm_drain(FILE * const fileP, -+ unsigned int const limit, -+ unsigned int * const bytesReadP); -+ -+char * -+pm_arg0toprogname(const char arg0[]); -+ -+unsigned int -+pm_randseed(void); -+ -+unsigned int -+pm_parse_width(const char * const arg); -+ -+unsigned int -+pm_parse_height(const char * const arg); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+ -+#endif -diff --git a/other/pnmcolormap.c b/other/pnmcolormap.c -index 7da3122..dafa390 100644 ---- a/other/pnmcolormap.c -+++ b/other/pnmcolormap.c -@@ -1002,6 +1002,7 @@ colormapToSquare(struct pam * const pamP, +diff -ruNp a/other/pnmcolormap.c b/other/pnmcolormap.c +--- a/other/pnmcolormap.c 2021-06-02 15:53:59.882206111 +0200 ++++ b/other/pnmcolormap.c 2021-06-02 20:23:21.833634466 +0200 +@@ -1002,6 +1002,7 @@ colormapToSquare(struct pam * const pamP pamP->width = intsqrt; else pamP->width = intsqrt + 1; @@ -5186,1686 +2829,9 @@ index 7da3122..dafa390 100644 } { unsigned int const intQuotient = colormap.size / pamP->width; -diff --git a/other/pnmcolormap.c.orig b/other/pnmcolormap.c.orig -new file mode 100644 -index 0000000..7da3122 ---- /dev/null -+++ b/other/pnmcolormap.c.orig -@@ -0,0 +1,1143 @@ -+/****************************************************************************** -+ pnmcolormap.c -+******************************************************************************* -+ -+ Create a colormap file (a PPM image containing one pixel of each of a set -+ of colors). Base the set of colors on an input image. -+ -+ For PGM input, do the equivalent for grayscale and produce a PGM graymap. -+ -+ By Bryan Henderson, San Jose, CA 2001.12.17 -+ -+ Derived from ppmquant, originally by Jef Poskanzer. -+ -+ Copyright (C) 1989, 1991 by Jef Poskanzer. -+ Copyright (C) 2001 by Bryan Henderson. -+ -+ Permission to use, copy, modify, and distribute this software and its -+ documentation for any purpose and without fee is hereby granted, provided -+ that the above copyright notice appear in all copies and that both that -+ copyright notice and this permission notice appear in supporting -+ documentation. This software is provided "as is" without express or -+ implied warranty. -+ -+******************************************************************************/ -+ -+#include -+#include -+ -+#include "pm_config.h" -+#include "pm_c_util.h" -+#include "mallocvar.h" -+#include "nstring.h" -+#include "shhopt.h" -+#include "pam.h" -+#include "pammap.h" -+ -+enum MethodForLargest {LARGE_NORM, LARGE_LUM}; -+ -+enum MethodForRep {REP_CENTER_BOX, REP_AVERAGE_COLORS, REP_AVERAGE_PIXELS}; -+ -+enum MethodForSplit {SPLIT_MAX_PIXELS, SPLIT_MAX_COLORS, SPLIT_MAX_SPREAD}; -+ -+struct Box { -+ unsigned int index; -+ unsigned int colorCt; -+ unsigned int sum; -+ unsigned int maxdim; -+ /* which dimension has the largest spread. RGB plane number. */ -+ sample spread; -+ /* spread in dimension 'maxdim' */ -+}; -+ -+struct BoxVector { -+ struct Box * box; /* malloc'ed array */ -+ unsigned int boxCt; -+ unsigned int capacity; -+}; -+ -+struct CmdlineInfo { -+ /* All the information the user supplied in the command line, -+ in a form easy for the program to use. -+ */ -+ const char * inputFileNm; /* Name of input file */ -+ unsigned int allcolors; /* boolean: select all colors from the input */ -+ unsigned int newcolors; -+ /* Number of colors argument; meaningless if allcolors true */ -+ enum MethodForLargest methodForLargest; -+ /* -spreadintensity/-spreadluminosity options */ -+ enum MethodForRep methodForRep; -+ /* -center/-meancolor/-meanpixel options */ -+ enum MethodForSplit methodForSplit; -+ /* -splitpixelct/-splitcolorct/-splitspread options */ -+ unsigned int sort; -+ unsigned int square; -+ unsigned int verbose; -+}; -+ -+ -+ -+static void -+parseCommandLine (int argc, const char ** argv, -+ struct CmdlineInfo *cmdlineP) { -+/*---------------------------------------------------------------------------- -+ parse program command line described in Unix standard form by argc -+ and argv. Return the information in the options as *cmdlineP. -+ -+ If command line is internally inconsistent (invalid options, etc.), -+ issue error message to stderr and abort program. -+ -+ Note that the strings we return are stored in the storage that -+ was passed to us as the argv array. We also trash *argv. -+-----------------------------------------------------------------------------*/ -+ optEntry *option_def; -+ /* Instructions to pm_optParseOptions3 on how to parse our options. -+ */ -+ optStruct3 opt; -+ -+ unsigned int option_def_index; -+ -+ unsigned int spreadbrightness, spreadluminosity; -+ unsigned int center, meancolor, meanpixel; -+ unsigned int splitpixelct, splitcolorct, splitspread; -+ -+ MALLOCARRAY_NOFAIL(option_def, 100); -+ -+ option_def_index = 0; /* incremented by OPTENT3 */ -+ OPTENT3(0, "spreadbrightness", OPT_FLAG, -+ NULL, &spreadbrightness, 0); -+ OPTENT3(0, "spreadluminosity", OPT_FLAG, -+ NULL, &spreadluminosity, 0); -+ OPTENT3(0, "center", OPT_FLAG, -+ NULL, ¢er, 0); -+ OPTENT3(0, "meancolor", OPT_FLAG, -+ NULL, &meancolor, 0); -+ OPTENT3(0, "meanpixel", OPT_FLAG, -+ NULL, &meanpixel, 0); -+ OPTENT3(0, "splitpixelct", OPT_FLAG, -+ NULL, &splitpixelct, 0); -+ OPTENT3(0, "splitcolorct", OPT_FLAG, -+ NULL, &splitcolorct, 0); -+ OPTENT3(0, "splitspread", OPT_FLAG, -+ NULL, &splitspread, 0); -+ OPTENT3(0, "sort", OPT_FLAG, NULL, -+ &cmdlineP->sort, 0 ); -+ OPTENT3(0, "square", OPT_FLAG, NULL, -+ &cmdlineP->square, 0 ); -+ OPTENT3(0, "verbose", OPT_FLAG, NULL, -+ &cmdlineP->verbose, 0 ); -+ -+ opt.opt_table = option_def; -+ opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ -+ opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ -+ -+ pm_optParseOptions3( &argc, (char **)argv, opt, sizeof(opt), 0 ); -+ /* Uses and sets argc, argv, and some of *cmdline_p and others. */ -+ -+ -+ if (spreadbrightness && spreadluminosity) -+ pm_error("You cannot specify both -spreadbrightness and " -+ "spreadluminosity."); -+ if (spreadluminosity) -+ cmdlineP->methodForLargest = LARGE_LUM; -+ else -+ cmdlineP->methodForLargest = LARGE_NORM; -+ -+ if (center + meancolor + meanpixel > 1) -+ pm_error("You can specify only one of -center, -meancolor, and " -+ "-meanpixel."); -+ if (meancolor) -+ cmdlineP->methodForRep = REP_AVERAGE_COLORS; -+ else if (meanpixel) -+ cmdlineP->methodForRep = REP_AVERAGE_PIXELS; -+ else -+ cmdlineP->methodForRep = REP_CENTER_BOX; -+ -+ if (splitpixelct) -+ cmdlineP->methodForSplit = SPLIT_MAX_PIXELS; -+ else if (splitcolorct) -+ cmdlineP->methodForSplit = SPLIT_MAX_COLORS; -+ else if (splitspread) -+ cmdlineP->methodForSplit = SPLIT_MAX_SPREAD; -+ else -+ cmdlineP->methodForSplit = SPLIT_MAX_PIXELS; -+ -+ if (argc-1 > 2) -+ pm_error("Program takes at most two arguments: number of colors " -+ "and input file specification. " -+ "You specified %d arguments.", argc-1); -+ else { -+ if (argc-1 < 2) -+ cmdlineP->inputFileNm = "-"; -+ else -+ cmdlineP->inputFileNm = argv[2]; -+ -+ if (argc-1 < 1) -+ pm_error("You must specify the number of colors in the " -+ "output as an argument."); -+ else { -+ if (strcmp(argv[1], "all") == 0) -+ cmdlineP->allcolors = TRUE; -+ else { -+ char * tail; -+ long int const newcolors = strtol(argv[1], &tail, 10); -+ if (*tail != '\0') -+ pm_error("The number of colors argument '%s' is not " -+ "a number or 'all'", argv[1]); -+ else if (newcolors < 1) -+ pm_error("The number of colors must be positive"); -+ else if (newcolors == 1) -+ pm_error("The number of colors must be greater than 1."); -+ else { -+ cmdlineP->newcolors = newcolors; -+ cmdlineP->allcolors = FALSE; -+ } -+ } -+ } -+ } -+} -+ -+ -+ -+#ifndef LITERAL_FN_DEF_MATCH -+static qsort_comparison_fn compareplane; -+#endif -+ -+static unsigned int compareplanePlane; -+ /* This is a parameter to compareplane(). We use this global variable -+ so that compareplane() can be called by qsort(), to compare two -+ tuples. qsort() doesn't pass any arguments except the two tuples. -+ */ -+static int -+compareplane(const void * const arg1, -+ const void * const arg2) { -+ -+ const struct tupleint * const * const comparandPP = arg1; -+ const struct tupleint * const * const comparatorPP = arg2; -+ -+ sample const comparandSample = (*comparandPP) ->tuple[compareplanePlane]; -+ sample const comparatorSample = (*comparatorPP)->tuple[compareplanePlane]; -+ -+ return -+ comparandSample < comparatorSample ? -1 : -+ comparandSample > comparatorSample ? 1 : -+ 0; -+} -+ -+ -+ -+#ifndef LITERAL_FN_DEF_MATCH -+static qsort_comparison_fn sumcompare; -+#endif -+ -+static int -+sumcompare(const void * const arg1, -+ const void * const arg2) { -+ -+ struct Box * const comparandP = (struct Box *)arg1; -+ struct Box * const comparatorP = (struct Box *)arg2; -+ -+ return -+ comparatorP->sum < comparandP->sum ? -1 : -+ comparatorP->sum > comparandP->sum ? 1 : -+ 0; -+} -+ -+ -+ -+#ifndef LITERAL_FN_DEF_MATCH -+static qsort_comparison_fn colcompare; -+#endif -+ -+static int -+colcompare(const void * const arg1, -+ const void * const arg2) { -+ -+ struct Box * const comparandP = (struct Box *)arg1; -+ struct Box * const comparatorP = (struct Box *)arg2; -+ -+ return -+ comparatorP->colorCt < comparandP->colorCt ? -1 : -+ comparatorP->colorCt > comparandP->colorCt ? 1 : -+ 0; -+} -+ -+ -+ -+#ifndef LITERAL_FN_DEF_MATCH -+static qsort_comparison_fn spreadcompare; -+#endif -+ -+static int -+spreadcompare(const void * const arg1, -+ const void * const arg2) { -+ -+ struct Box * const comparandP = (struct Box *)arg1; -+ struct Box * const comparatorP = (struct Box *)arg2; -+ -+ return -+ comparatorP->spread < comparandP->spread ? -1 : -+ comparatorP->spread > comparandP->spread ? 1 : -+ 0; -+} -+ -+ -+ -+static void -+sortBoxes(struct BoxVector * const boxVectorP, -+ enum MethodForSplit const methodForSplit) { -+ -+ qsort_comparison_fn * comparisonFn; -+ -+ switch (methodForSplit){ -+ case SPLIT_MAX_PIXELS: comparisonFn = &sumcompare; break; -+ case SPLIT_MAX_COLORS: comparisonFn = &colcompare; break; -+ case SPLIT_MAX_SPREAD: comparisonFn = &spreadcompare; break; -+ } -+ -+ qsort((char*) &boxVectorP->box[0], boxVectorP->boxCt, sizeof(struct Box), -+ comparisonFn); -+} -+ -+ -+ -+/* -+** Here is the fun part, the median-cut colormap generator. This is based -+** on Paul Heckbert's paper "Color Image Quantization for Frame Buffer -+** Display", SIGGRAPH '82 Proceedings, page 297. -+*/ -+ -+static void -+findBoxBoundaries(tupletable2 const colorfreqtable, -+ unsigned int const depth, -+ unsigned int const boxStart, -+ unsigned int const boxSize, -+ sample minval[], -+ sample maxval[]) { -+/*---------------------------------------------------------------------------- -+ Go through the box finding the minimum and maximum of each component - the -+ boundaries of the box. -+-----------------------------------------------------------------------------*/ -+ unsigned int plane; -+ unsigned int i; -+ -+ for (plane = 0; plane < depth; ++plane) { -+ minval[plane] = colorfreqtable.table[boxStart]->tuple[plane]; -+ maxval[plane] = minval[plane]; -+ } -+ -+ for (i = 1; i < boxSize; ++i) { -+ unsigned int plane; -+ for (plane = 0; plane < depth; ++plane) { -+ sample const v = colorfreqtable.table[boxStart + i]->tuple[plane]; -+ if (v < minval[plane]) minval[plane] = v; -+ if (v > maxval[plane]) maxval[plane] = v; -+ } -+ } -+} -+ -+ -+ -+static void -+findPlaneWithLargestSpreadByNorm(sample const minval[], -+ sample const maxval[], -+ unsigned int const depth, -+ unsigned int * const planeP, -+ sample * const spreadP) { -+ -+ unsigned int planeWithLargest; -+ sample largestSpreadSoFar; -+ unsigned int plane; -+ -+ for (plane = 0, largestSpreadSoFar = 0; plane < depth; ++plane) { -+ -+ sample const spread = maxval[plane]-minval[plane]; -+ if (spread > largestSpreadSoFar) { -+ largestSpreadSoFar = spread; -+ planeWithLargest = plane; -+ } -+ } -+ *planeP = planeWithLargest; -+ *spreadP = largestSpreadSoFar; -+} -+ -+ -+ -+static void -+findPlaneWithLargestSpreadByLuminosity(sample const minval[], -+ sample const maxval[], -+ unsigned int const depth, -+ unsigned int * const planeP, -+ sample * const spreadP) { -+/*---------------------------------------------------------------------------- -+ This subroutine presumes that the tuple type is either -+ BLACKANDWHITE, GRAYSCALE, or RGB (which implies pamP->depth is 1 or 3). -+ To save time, we don't actually check it. -+-----------------------------------------------------------------------------*/ -+ if (depth == 1){ -+ *planeP = 0; -+ *spreadP = 0; -+ } else { -+ /* An RGB tuple */ -+ unsigned int planeWithLargest; -+ sample largestSpreadSoFar; -+ unsigned int plane; -+ -+ assert(depth >= 3); -+ -+ for (plane = 0, largestSpreadSoFar = 0; plane < 3; ++plane) { -+ double const spread = -+ pnm_lumin_factor[plane] * (maxval[plane]-minval[plane]); -+ if (spread > largestSpreadSoFar) { -+ largestSpreadSoFar = spread; -+ planeWithLargest = plane; -+ } -+ } -+ *planeP = planeWithLargest; -+ *spreadP = largestSpreadSoFar; -+ } -+} -+ -+ -+ -+static void -+computeBoxSpread(const struct Box * const boxP, -+ tupletable2 const colorfreqtable, -+ unsigned int const depth, -+ enum MethodForLargest const methodForLargest, -+ unsigned int * const planeWithLargestP, -+ sample * const spreadP -+ ) { -+/*---------------------------------------------------------------------------- -+ Find the spread in the dimension in which it is greatest. -+ -+ Return as *planeWithLargestP the number of that plane and as *spreadP the -+ spread in that plane. -+-----------------------------------------------------------------------------*/ -+ sample * minval; /* malloc'ed array */ -+ sample * maxval; /* malloc'ed array */ -+ -+ MALLOCARRAY_NOFAIL(minval, depth); -+ MALLOCARRAY_NOFAIL(maxval, depth); -+ -+ findBoxBoundaries(colorfreqtable, depth, boxP->index, boxP->colorCt, -+ minval, maxval); -+ -+ switch (methodForLargest) { -+ case LARGE_NORM: -+ findPlaneWithLargestSpreadByNorm(minval, maxval, depth, -+ planeWithLargestP, spreadP); -+ break; -+ case LARGE_LUM: -+ findPlaneWithLargestSpreadByLuminosity(minval, maxval, depth, -+ planeWithLargestP, spreadP); -+ break; -+ } -+ free(minval); free(maxval); -+} -+ -+ -+ -+static unsigned int -+freqTotal(tupletable2 const freqtable) { -+ -+ unsigned int i; -+ unsigned int sum; -+ -+ for (i = 0, sum = 0; i < freqtable.size; ++i) -+ sum += freqtable.table[i]->value; -+ -+ return sum; -+} -+ -+ -+ -+static struct BoxVector -+newBoxVector(tupletable2 const colorfreqtable, -+ unsigned int const capacity, -+ unsigned int const depth, -+ enum MethodForLargest const methodForLargest) { -+ -+ unsigned int const colorCt = colorfreqtable.size; -+ unsigned int const sum = freqTotal(colorfreqtable); -+ -+ struct BoxVector boxVector; -+ -+ MALLOCARRAY(boxVector.box, capacity); -+ -+ if (!boxVector.box) -+ pm_error("out of memory allocating box vector table"); -+ -+ /* Set up the initial box. */ -+ boxVector.box[0].index = 0; -+ boxVector.box[0].colorCt = colorCt; -+ boxVector.box[0].sum = sum; -+ -+ computeBoxSpread(&boxVector.box[0], colorfreqtable, depth, -+ methodForLargest, -+ &boxVector.box[0].maxdim, -+ &boxVector.box[0].spread); -+ -+ boxVector.boxCt = 1; -+ boxVector.capacity = capacity; -+ -+ return boxVector; -+} -+ -+ -+ -+static void -+destroyBoxVector(struct BoxVector const boxVector) { -+ -+ free(boxVector.box); -+} -+ -+ -+ -+static void -+centerBox(int const boxStart, -+ int const boxSize, -+ tupletable2 const colorfreqtable, -+ unsigned int const depth, -+ tuple const newTuple) { -+ -+ unsigned int plane; -+ -+ for (plane = 0; plane < depth; ++plane) { -+ int minval, maxval; -+ unsigned int i; -+ -+ minval = maxval = colorfreqtable.table[boxStart]->tuple[plane]; -+ -+ for (i = 1; i < boxSize; ++i) { -+ int const v = colorfreqtable.table[boxStart + i]->tuple[plane]; -+ minval = MIN( minval, v); -+ maxval = MAX( maxval, v); -+ } -+ newTuple[plane] = (minval + maxval) / 2; -+ } -+} -+ -+ -+ -+static tupletable2 -+newColorMap(unsigned int const colorCt, -+ unsigned int const depth) { -+ -+ tupletable2 colormap; -+ unsigned int i; -+ struct pam pam; -+ -+ pam.depth = depth; -+ -+ colormap.table = pnm_alloctupletable(&pam, colorCt); -+ -+ for (i = 0; i < colorCt; ++i) { -+ unsigned int plane; -+ for (plane = 0; plane < depth; ++plane) -+ colormap.table[i]->tuple[plane] = 0; -+ } -+ colormap.size = colorCt; -+ -+ return colormap; -+} -+ -+ -+ -+static void -+averageColors(int const boxStart, -+ int const boxSize, -+ tupletable2 const colorfreqtable, -+ unsigned int const depth, -+ tuple const newTuple) { -+ -+ unsigned int plane; -+ -+ for (plane = 0; plane < depth; ++plane) { -+ sample sum; -+ int i; -+ -+ sum = 0; -+ -+ for (i = 0; i < boxSize; ++i) -+ sum += colorfreqtable.table[boxStart+i]->tuple[plane]; -+ -+ newTuple[plane] = ROUNDDIV(sum, boxSize); -+ } -+} -+ -+ -+ -+static void -+averagePixels(int const boxStart, -+ int const boxSize, -+ tupletable2 const colorfreqtable, -+ unsigned int const depth, -+ tuple const newTuple) { -+ -+ unsigned int n; -+ /* Number of tuples represented by the box */ -+ unsigned int plane; -+ unsigned int i; -+ -+ /* Count the tuples in question */ -+ n = 0; /* initial value */ -+ for (i = 0; i < boxSize; ++i) -+ n += colorfreqtable.table[boxStart + i]->value; -+ -+ -+ for (plane = 0; plane < depth; ++plane) { -+ sample sum; -+ int i; -+ -+ sum = 0; -+ -+ for (i = 0; i < boxSize; ++i) -+ sum += colorfreqtable.table[boxStart+i]->tuple[plane] -+ * colorfreqtable.table[boxStart+i]->value; -+ -+ newTuple[plane] = ROUNDDIV(sum, n); -+ } -+} -+ -+ -+ -+static tupletable2 -+colormapFromBv(unsigned int const colorCt, -+ struct BoxVector const boxVector, -+ tupletable2 const colorfreqtable, -+ unsigned int const depth, -+ enum MethodForRep const methodForRep) { -+ /* -+ ** Ok, we've got enough boxes. Now choose a representative color for -+ ** each box. There are a number of possible ways to make this choice. -+ ** One would be to choose the center of the box; this ignores any structure -+ ** within the boxes. Another method would be to average all the colors in -+ ** the box - this is the method specified in Heckbert's paper. A third -+ ** method is to average all the pixels in the box. -+ */ -+ tupletable2 colormap; -+ unsigned int boxIdx; -+ -+ colormap = newColorMap(colorCt, depth); -+ -+ for (boxIdx = 0; boxIdx < boxVector.boxCt; ++boxIdx) { -+ switch (methodForRep) { -+ case REP_CENTER_BOX: -+ centerBox(boxVector.box[boxIdx].index, -+ boxVector.box[boxIdx].colorCt, -+ colorfreqtable, depth, -+ colormap.table[boxIdx]->tuple); -+ break; -+ case REP_AVERAGE_COLORS: -+ averageColors(boxVector.box[boxIdx].index, -+ boxVector.box[boxIdx].colorCt, -+ colorfreqtable, depth, -+ colormap.table[boxIdx]->tuple); -+ break; -+ case REP_AVERAGE_PIXELS: -+ averagePixels(boxVector.box[boxIdx].index, -+ boxVector.box[boxIdx].colorCt, -+ colorfreqtable, depth, -+ colormap.table[boxIdx]->tuple); -+ break; -+ default: -+ pm_error("Internal error: invalid value of methodForRep: %d", -+ methodForRep); -+ } -+ } -+ return colormap; -+} -+ -+ -+ -+static void -+splitBox(struct BoxVector * const boxVectorP, -+ unsigned int const boxIdx, -+ tupletable2 const colorfreqtable, -+ unsigned int const depth, -+ enum MethodForLargest const methodForLargest, -+ enum MethodForSplit const methodForSplit) { -+/*---------------------------------------------------------------------------- -+ Split Box 'boxIdx' in the box vector 'boxVector' (so that bv contains one -+ more box than it did as input). Split it so that each new box represents -+ about half of the pixels in the distribution given by 'colorfreqtable' for -+ the colors in the original box, but with distinct colors in each of the two -+ new boxes. -+ -+ Assume the box contains at least two colors. -+-----------------------------------------------------------------------------*/ -+ unsigned int const boxStart = boxVectorP->box[boxIdx].index; -+ unsigned int const boxSize = boxVectorP->box[boxIdx].colorCt; -+ unsigned int const sum = boxVectorP->box[boxIdx].sum; -+ -+ unsigned int medianIndex; -+ int lowersum; -+ /* Number of pixels whose value is "less than" the median */ -+ -+ -+ /* Perhaps this sort should go after creating a box, not before splitting. -+ Because you need the sort to use the REP_CENTER_BOX method of choosing -+ a color to represent the final boxes -+ */ -+ -+ /* Set the gross global variable 'compareplanePlane' as a -+ parameter to compareplane(), which is called by qsort(). -+ */ -+ compareplanePlane = boxVectorP->box[boxIdx].maxdim; -+ qsort((char*) &colorfreqtable.table[boxStart], boxSize, -+ sizeof(colorfreqtable.table[boxStart]), -+ compareplane); -+ -+ { -+ /* Find the median based on the counts, so that about half the pixels -+ (not colors, pixels) are in each subdivision. -+ */ -+ unsigned int i; -+ -+ lowersum = colorfreqtable.table[boxStart]->value; /* initial value */ -+ for (i = 1; i < boxSize - 1 && lowersum < sum/2; ++i) { -+ lowersum += colorfreqtable.table[boxStart + i]->value; -+ } -+ medianIndex = i; -+ } -+ /* Split the box, and sort to bring the biggest boxes to the top. */ -+ { -+ struct Box * const oldBoxP = &boxVectorP->box[boxIdx]; -+ -+ oldBoxP->colorCt = medianIndex; -+ oldBoxP->sum = lowersum; -+ computeBoxSpread(oldBoxP, colorfreqtable, depth, methodForLargest, -+ &oldBoxP->maxdim, &oldBoxP->spread); -+ } -+ { -+ struct Box * const newBoxP = &boxVectorP->box[boxVectorP->boxCt]; -+ -+ newBoxP->index = boxStart + medianIndex; -+ newBoxP->colorCt = boxSize - medianIndex; -+ newBoxP->sum = sum - lowersum; -+ computeBoxSpread(newBoxP, colorfreqtable, depth, methodForLargest, -+ &newBoxP->maxdim, &newBoxP->spread); -+ ++boxVectorP->boxCt; -+ } -+ -+ sortBoxes(boxVectorP, methodForSplit); -+} -+ -+ -+ -+static void -+mediancut(tupletable2 const colorfreqtable, -+ unsigned int const depth, -+ int const newcolorCt, -+ enum MethodForLargest const methodForLargest, -+ enum MethodForRep const methodForRep, -+ enum MethodForSplit const methodForSplit, -+ tupletable2 * const colormapP) { -+/*---------------------------------------------------------------------------- -+ Compute a set of only 'newcolorCt' colors that best represent an -+ image whose pixels are summarized by the histogram -+ 'colorfreqtable'. Each tuple in that table has depth 'depth'. -+ colorfreqtable.table[i] tells the number of pixels in the subject image -+ have a particular color. -+ -+ As a side effect, sort 'colorfreqtable'. -+-----------------------------------------------------------------------------*/ -+ struct BoxVector boxVector; -+ bool multicolorBoxesExist; -+ /* There is at least one box that contains at least 2 colors; ergo, -+ there is more splitting we can do. -+ */ -+ -+ boxVector = newBoxVector(colorfreqtable, newcolorCt, depth, -+ methodForLargest); -+ -+ multicolorBoxesExist = (colorfreqtable.size > 1); -+ -+ /* Split boxes until we have enough. */ -+ while (boxVector.boxCt < newcolorCt && multicolorBoxesExist) { -+ unsigned int boxIdx; -+ -+ for (boxIdx = 0; -+ boxIdx < boxVector.boxCt && boxVector.box[boxIdx].colorCt < 2; -+ ++boxIdx); -+ /* Find the first splittable box. */ -+ -+ if (boxIdx >= boxVector.boxCt) -+ multicolorBoxesExist = FALSE; -+ else -+ splitBox(&boxVector, boxIdx, colorfreqtable, depth, -+ methodForLargest, methodForSplit); -+ } -+ *colormapP = colormapFromBv(newcolorCt, boxVector, colorfreqtable, -+ depth, methodForRep); -+ -+ destroyBoxVector(boxVector); -+} -+ -+ -+ -+ -+static void -+validateCompatibleImage(struct pam * const inpamP, -+ struct pam * const firstPamP, -+ unsigned int const imageSeq) { -+ -+ if (inpamP->depth != firstPamP->depth) -+ pm_error("Image %u depth (%u) is not the same as Image 0 (%u)", -+ imageSeq, inpamP->depth, firstPamP->depth); -+ if (inpamP->maxval != firstPamP->maxval) -+ pm_error("Image %u maxval (%u) is not the same as Image 0 (%u)", -+ imageSeq, -+ (unsigned)inpamP->maxval, (unsigned)firstPamP->maxval); -+ if (inpamP->format != firstPamP->format) -+ pm_error("Image %u format (%d) is not the same as Image 0 (%d)", -+ imageSeq, inpamP->format, firstPamP->format); -+ if (!streq(inpamP->tuple_type, firstPamP->tuple_type)) -+ pm_error("Image %u tuple type (%s) is not the same as Image 0 (%s)", -+ imageSeq, inpamP->tuple_type, firstPamP->tuple_type); -+} -+ -+ -+ -+static void -+addImageColorsToHash(struct pam * const pamP, -+ tuplehash const tuplehash, -+ unsigned int * const colorCountP) { -+ -+ tuple * tuplerow; -+ unsigned int row; -+ -+ tuplerow = pnm_allocpamrow(pamP); -+ -+ for (row = 0; row < pamP->height; ++row) { -+ unsigned int col; -+ -+ pnm_readpamrow(pamP, tuplerow); -+ -+ for (col = 0; col < pamP->width; ++col) { -+ int firstOccurrence; -+ -+ pnm_addtuplefreqoccurrence(pamP, tuplerow[col], tuplehash, -+ &firstOccurrence); -+ -+ if (firstOccurrence) -+ ++(*colorCountP); -+ } -+ } -+ pnm_freepamrow(tuplerow); -+} -+ -+ -+ -+static void -+computeHistogram(FILE * const ifP, -+ int * const formatP, -+ struct pam * const freqPamP, -+ tupletable2 * const colorfreqtableP) { -+/*---------------------------------------------------------------------------- -+ Make a histogram of the colors in the image stream in the file '*ifP'. -+ -+ Return as *freqPamP a description of the tuple values in the histogram. -+ Only the fields of *freqPamP that describe individual tuples are -+ meaningful (depth, maxval, tuple type); -+ -+ As a fringe benefit, also return the format of the input file as -+ *formatP. -+----------------------------------------------------------------------------*/ -+ unsigned int imageSeq; -+ struct pam firstPam; -+ tuplehash tuplehash; -+ unsigned int colorCount; -+ int eof; -+ -+ pm_message("making histogram..."); -+ -+ tuplehash = pnm_createtuplehash(); -+ colorCount = 0; -+ -+ eof = FALSE; -+ -+ for (imageSeq = 0; !eof; ++imageSeq) { -+ struct pam inpam; -+ -+ pm_message("Scanning image %u", imageSeq); -+ -+ pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); -+ -+ if (imageSeq == 0) -+ firstPam = inpam; -+ else -+ validateCompatibleImage(&inpam, &firstPam, imageSeq); -+ -+ addImageColorsToHash(&inpam, tuplehash, &colorCount); -+ -+ pm_message("%u colors so far", colorCount); -+ -+ pnm_nextimage(ifP, &eof); -+ } -+ colorfreqtableP->table = -+ pnm_tuplehashtotable(&firstPam, tuplehash, colorCount); -+ colorfreqtableP->size = colorCount; -+ -+ pnm_destroytuplehash(tuplehash); -+ -+ pm_message("%u colors found", colorfreqtableP->size); -+ -+ freqPamP->size = sizeof(*freqPamP); -+ freqPamP->len = PAM_STRUCT_SIZE(tuple_type); -+ freqPamP->maxval = firstPam.maxval; -+ freqPamP->bytes_per_sample = pnm_bytespersample(freqPamP->maxval); -+ freqPamP->depth = firstPam.depth; -+ STRSCPY(freqPamP->tuple_type, firstPam.tuple_type); -+ -+ *formatP = firstPam.format; -+} -+ -+ -+ -+static void -+computeColorMapFromInput(FILE * const ifP, -+ bool const allColors, -+ int const reqColors, -+ enum MethodForLargest const methodForLargest, -+ enum MethodForRep const methodForRep, -+ enum MethodForSplit const methodForSplit, -+ int * const formatP, -+ struct pam * const freqPamP, -+ tupletable2 * const colormapP) { -+/*---------------------------------------------------------------------------- -+ Produce a colormap containing the best colors to represent the -+ image stream in file 'ifP'. Figure it out using the median cut -+ technique. -+ -+ The colormap will have 'reqcolors' or fewer colors in it, unless -+ 'allcolors' is true, in which case it will have all the colors that -+ are in the input. -+ -+ The colormap has the same maxval as the input. -+ -+ Put the colormap in newly allocated storage as a tupletable2 -+ and return its address as *colormapP. Return the number of colors in -+ it as *colorsP and its maxval as *colormapMaxvalP. -+ -+ Return the characteristics of the input file as -+ *formatP and *freqPamP. (This information is not really -+ relevant to our colormap mission; just a fringe benefit). -+-----------------------------------------------------------------------------*/ -+ tupletable2 colorfreqtable; -+ -+ computeHistogram(ifP, formatP, freqPamP, &colorfreqtable); -+ -+ if (allColors) { -+ *colormapP = colorfreqtable; -+ } else { -+ if (colorfreqtable.size <= reqColors) { -+ pm_message("Image already has few enough colors (<=%d). " -+ "Keeping same colors.", reqColors); -+ *colormapP = colorfreqtable; -+ } else { -+ pm_message("choosing %d colors...", reqColors); -+ mediancut(colorfreqtable, freqPamP->depth, -+ reqColors, methodForLargest, methodForRep, -+ methodForSplit, colormapP); -+ pnm_freetupletable2(freqPamP, colorfreqtable); -+ } -+ } -+} -+ -+ -+ -+static void -+sortColormap(tupletable2 const colormap, -+ sample const depth) { -+/*---------------------------------------------------------------------------- -+ Sort the colormap in place, in order of ascending Plane 0 value, -+ the Plane 1 value, etc. -+ -+ Use insertion sort. -+-----------------------------------------------------------------------------*/ -+ int i; -+ -+ pm_message("Sorting %u colors...", colormap.size); -+ -+ for (i = 0; i < colormap.size; ++i) { -+ int j; -+ for (j = i+1; j < colormap.size; ++j) { -+ unsigned int plane; -+ bool iIsGreater, iIsLess; -+ -+ iIsGreater = FALSE; iIsLess = FALSE; -+ for (plane = 0; -+ plane < depth && !iIsGreater && !iIsLess; -+ ++plane) { -+ if (colormap.table[i]->tuple[plane] > -+ colormap.table[j]->tuple[plane]) -+ iIsGreater = TRUE; -+ else if (colormap.table[i]->tuple[plane] < -+ colormap.table[j]->tuple[plane]) -+ iIsLess = TRUE; -+ } -+ if (iIsGreater) { -+ for (plane = 0; plane < depth; ++plane) { -+ sample const temp = colormap.table[i]->tuple[plane]; -+ colormap.table[i]->tuple[plane] = -+ colormap.table[j]->tuple[plane]; -+ colormap.table[j]->tuple[plane] = temp; -+ } -+ } -+ } -+ } -+} -+ -+ -+ -+static void -+colormapToSquare(struct pam * const pamP, -+ tupletable2 const colormap, -+ tuple *** const outputRasterP) { -+ { -+ unsigned int const intsqrt = (int)sqrt((float)colormap.size); -+ if (SQR(intsqrt) == colormap.size) -+ pamP->width = intsqrt; -+ else -+ pamP->width = intsqrt + 1; -+ } -+ { -+ unsigned int const intQuotient = colormap.size / pamP->width; -+ if (pamP->width * intQuotient == colormap.size) -+ pamP->height = intQuotient; -+ else -+ pamP->height = intQuotient + 1; -+ } -+ { -+ tuple ** outputRaster; -+ unsigned int row; -+ unsigned int colormapIndex; -+ -+ outputRaster = pnm_allocpamarray(pamP); -+ -+ colormapIndex = 0; /* initial value */ -+ -+ for (row = 0; row < pamP->height; ++row) { -+ unsigned int col; -+ for (col = 0; col < pamP->width; ++col) { -+ unsigned int plane; -+ for (plane = 0; plane < pamP->depth; ++plane) { -+ outputRaster[row][col][plane] = -+ colormap.table[colormapIndex]->tuple[plane]; -+ } -+ if (colormapIndex < colormap.size-1) -+ ++colormapIndex; -+ } -+ } -+ *outputRasterP = outputRaster; -+ } -+} -+ -+ -+ -+static void -+colormapToSingleRow(struct pam * const pamP, -+ tupletable2 const colormap, -+ tuple *** const outputRasterP) { -+ -+ tuple ** outputRaster; -+ unsigned int col; -+ -+ pamP->width = colormap.size; -+ pamP->height = 1; -+ -+ outputRaster = pnm_allocpamarray(pamP); -+ -+ for (col = 0; col < pamP->width; ++col) { -+ int plane; -+ for (plane = 0; plane < pamP->depth; ++plane) -+ outputRaster[0][col][plane] = colormap.table[col]->tuple[plane]; -+ } -+ *outputRasterP = outputRaster; -+} -+ -+ -+ -+static void -+colormapToImage(int const format, -+ const struct pam * const colormapPamP, -+ tupletable2 const colormap, -+ bool const sort, -+ bool const square, -+ struct pam * const outpamP, -+ tuple *** const outputRasterP) { -+/*---------------------------------------------------------------------------- -+ Create a tuple array and pam structure for an image which includes -+ one pixel of each of the colors in the colormap 'colormap'. -+ -+ May rearrange the contents of 'colormap'. -+-----------------------------------------------------------------------------*/ -+ outpamP->size = sizeof(*outpamP); -+ outpamP->len = PAM_STRUCT_SIZE(tuple_type); -+ outpamP->format = format, -+ outpamP->plainformat = FALSE; -+ outpamP->depth = colormapPamP->depth; -+ outpamP->maxval = colormapPamP->maxval; -+ outpamP->bytes_per_sample = pnm_bytespersample(outpamP->maxval); -+ STRSCPY(outpamP->tuple_type, colormapPamP->tuple_type); -+ -+ if (sort) -+ sortColormap(colormap, outpamP->depth); -+ -+ if (square) -+ colormapToSquare(outpamP, colormap, outputRasterP); -+ else -+ colormapToSingleRow(outpamP, colormap, outputRasterP); -+} -+ -+ -+ -+int -+main(int argc, const char * argv[] ) { -+ -+ struct CmdlineInfo cmdline; -+ FILE * ifP; -+ int format; -+ struct pam colormapPam; -+ struct pam outpam; -+ tuple ** colormapRaster; -+ tupletable2 colormap; -+ -+ pm_proginit(&argc, argv); -+ -+ parseCommandLine(argc, argv, &cmdline); -+ -+ ifP = pm_openr(cmdline.inputFileNm); -+ -+ computeColorMapFromInput(ifP, -+ cmdline.allcolors, cmdline.newcolors, -+ cmdline.methodForLargest, -+ cmdline.methodForRep, -+ cmdline.methodForSplit, -+ &format, &colormapPam, &colormap); -+ -+ pm_close(ifP); -+ -+ colormapToImage(format, &colormapPam, colormap, -+ cmdline.sort, cmdline.square, &outpam, &colormapRaster); -+ -+ if (cmdline.verbose) -+ pm_message("Generating %u x %u image", outpam.width, outpam.height); -+ -+ outpam.file = stdout; -+ -+ pnm_writepam(&outpam, colormapRaster); -+ -+ pnm_freetupletable2(&colormapPam, colormap); -+ -+ pnm_freepamarray(colormapRaster, &outpam); -+ -+ pm_close(stdout); -+ -+ return 0; -+} -+ -+ -+ -diff --git a/urt/Runput.c b/urt/Runput.c -index 3bc562a..645a376 100644 ---- a/urt/Runput.c -+++ b/urt/Runput.c -@@ -202,10 +202,11 @@ RunSetup(rle_hdr * the_hdr) - if ( the_hdr->background != 0 ) - { - register int i; -- register rle_pixel *background = -- (rle_pixel *)malloc( (unsigned)(the_hdr->ncolors + 1) ); -- register int *bg_color; -- /* -+ register rle_pixel *background; -+ register int *bg_color; -+ -+ overflow_add(the_hdr->ncolors,1); -+ background = (rle_pixel *)malloc( (unsigned)(the_hdr->ncolors + 1) ); /* - * If even number of bg color bytes, put out one more to get to - * 16 bit boundary. - */ -@@ -224,7 +225,7 @@ RunSetup(rle_hdr * the_hdr) - /* Big-endian machines are harder */ - register int i, nmap = (1 << the_hdr->cmaplen) * - the_hdr->ncmap; -- register char *h_cmap = (char *)malloc( nmap * 2 ); -+ register char *h_cmap = (char *)malloc2( nmap, 2 ); - if ( h_cmap == NULL ) - { - fprintf( stderr, -diff --git a/urt/rle.h b/urt/rle.h -index 0071774..6a905ba 100644 ---- a/urt/rle.h -+++ b/urt/rle.h -@@ -152,6 +152,17 @@ rle_hdr /* End of typedef. */ - */ - extern rle_hdr rle_dflt_hdr; - -+/* -+ * Provided by pm library -+ */ -+ -+extern void overflow_add(int, int); -+#define overflow2(a,b) __overflow2(a,b) -+extern void __overflow2(int, int); -+extern void overflow3(int, int, int); -+extern void *malloc2(int, int); -+extern void *malloc3(int, int, int); -+extern void *realloc2(void *, int, int); - - /* Declare RLE library routines. */ - -diff --git a/urt/rle.h.orig b/urt/rle.h.orig -new file mode 100644 -index 0000000..59d2670 ---- /dev/null -+++ b/urt/rle.h.orig -@@ -0,0 +1,470 @@ -+/* -+ * This software is copyrighted as noted below. It may be freely copied, -+ * modified, and redistributed, provided that the copyright notice is -+ * preserved on all copies. -+ * -+ * There is no warranty or other guarantee of fitness for this software, -+ * it is provided solely "as is". Bug reports or fixes may be sent -+ * to the author, who may or may not act on them as he desires. -+ * -+ * You may not include this software in a program or other software product -+ * without supplying the source, or without informing the end-user that the -+ * source is available for no extra charge. -+ * -+ * If you modify this software, you should include a notice giving the -+ * name of the person performing the modification, the date of modification, -+ * and the reason for such modification. -+ */ -+/* -+ * rle.h - Global declarations for Utah Raster Toolkit RLE programs. -+ * -+ * Author: Todd W. Fuqua -+ * Computer Science Dept. -+ * University of Utah -+ * Date: Sun Jul 29 1984 -+ * Copyright (c) 1984 Todd W. Fuqua -+ * -+ * $Id: rle.h,v 3.0.1.5 1992/04/30 14:05:56 spencer Exp $ -+ */ -+ -+#ifndef RLE_H -+#define RLE_H -+ -+#include /* Declare FILE. */ -+#include -+ -+enum rle_dispatch { -+ NO_DISPATCH = -1, -+ RUN_DISPATCH = 0 -+}; -+ -+/* **************************************************************** -+ * TAG( rle_pixel rle_map ) -+ * -+ * Typedef for 8-bit (or less) pixel data. -+ * -+ * Typedef for 16-bit color map data. -+ */ -+typedef unsigned char rle_pixel; -+typedef unsigned short rle_map; -+ -+/* -+ * Defines for traditional channel numbers. -+ */ -+#define RLE_RED 0 /* Red channel traditionally here. */ -+#define RLE_GREEN 1 /* Green channel traditionally here. */ -+#define RLE_BLUE 2 /* Blue channel traditionally here. */ -+#define RLE_ALPHA -1 /* Alpha channel here. */ -+ -+/* -+ * Return values from rle_get_setup. -+ */ -+#define RLE_SUCCESS 0 -+#define RLE_NOT_RLE -1 -+#define RLE_NO_SPACE -2 -+#define RLE_EMPTY -3 -+#define RLE_EOF -4 -+ -+/* -+ * "Magic" value for is_init field. Pi * 2^29. -+ */ -+#define RLE_INIT_MAGIC 0x6487ED51L -+ -+/* -+ * TAG( rle_hdr ) -+ * -+ * Definition of header structure used by RLE routines. -+ */ -+ -+#ifndef c_plusplus -+typedef -+#endif -+ struct rle_hdr { -+ enum rle_dispatch dispatch; /* Type of file to create. */ -+ int ncolors; /* Number of color channels. */ -+ int * bg_color; /* Pointer to bg color vector. */ -+ int alpha; /* If !0, save alpha channel. */ -+ int background; /* 0->just save all pixels, */ -+ /* 1->overlay, 2->clear to bg first. */ -+ int xmin; /* Lower X bound (left.) */ -+ int xmax; /* Upper X bound (right.) */ -+ int ymin; /* Lower Y bound (bottom.) */ -+ int ymax; /* Upper Y bound (top.) */ -+ int ncmap; /* Number of color channels in color map. */ -+ /* Map only saved if != 0. */ -+ int cmaplen; /* Log2 of color map length. */ -+ rle_map * cmap; /* Pointer to color map array. */ -+ const char ** comments; /* Pointer to array of pointers to comments. */ -+ FILE * rle_file; /* Input or output file. */ -+ /* -+ * Bit map of channels to read/save. Indexed by (channel mod 256). -+ * Alpha channel sets bit 255. -+ * -+ * Indexing (0 <= c <= 255): -+ * bits[c/8] & (1 << (c%8)) -+ */ -+#define RLE_SET_BIT(glob,bit) \ -+ ((glob).bits[((bit)&0xff)/8] |= (1<<((bit)&0x7))) -+#define RLE_CLR_BIT(glob,bit) \ -+ ((glob).bits[((bit)&0xff)/8] &= ~(1<<((bit)&0x7))) -+#define RLE_BIT(glob,bit) \ -+ ((glob).bits[((bit)&0xff)/8] & (1<<((bit)&0x7))) -+ char bits[256/8]; -+ /* Set to magic pattern if following fields are initialized. */ -+ /* This gives a 2^(-32) chance of missing. */ -+ long int is_init; -+ /* Command, file name and image number for error messages. */ -+ const char *cmd; -+ const char *file_name; -+ int img_num; -+ /* -+ * Local storage for rle_getrow & rle_putrow. -+ * rle_getrow has -+ * scan_y int current Y scanline. -+ * vert_skip int number of lines to skip. -+ * rle_putrow has -+ * nblank int number of blank lines. -+ * brun short(*)[2] Array of background runs. -+ * fileptr long Position in output file. -+ */ -+ union { -+ struct { -+ int scan_y, -+ vert_skip; -+ char is_eof, /* Set when EOF or EofOp encountered. */ -+ is_seek; /* If true, can seek input file. */ -+ } get; -+ struct { -+ int nblank; -+ short (*brun)[2]; -+ long fileptr; -+ } put; -+ } priv; -+ } -+#ifndef c_plusplus -+rle_hdr /* End of typedef. */ -+#endif -+; -+ -+/* -+ * TAG( rle_dflt_hdr ) -+ * -+ * Global variable with possibly useful default values. -+ */ -+extern rle_hdr rle_dflt_hdr; -+ -+ -+/* Declare RLE library routines. */ -+ -+/***************************************************************** -+ * TAG( rle_get_error ) -+ * -+ * Print an error message based on the error code returned by -+ * rle_get_setup. -+ */ -+extern int rle_get_error( int code, -+ const char *pgmname, -+ const char *fname ); -+ -+/* From rle_getrow.c */ -+ -+/***************************************************************** -+ * TAG( rle_debug ) -+ * -+ * Turn RLE debugging on or off. -+ */ -+extern void rle_debug( int on_off ); -+ -+int -+rle_get_setup(rle_hdr * const the_hdr); -+ -+/***************************************************************** -+ * TAG( rle_get_setup_ok ) -+ * -+ * Call rle_get_setup. If it returns an error code, call -+ * rle_get_error to print the error message, then exit with the error -+ * code. -+ */ -+extern void rle_get_setup_ok( rle_hdr *the_hdr, -+ const char *prog_name, -+ const char *file_name); -+ -+/***************************************************************** -+ * TAG( rle_getrow ) -+ * -+ * Read a scanline worth of data from an RLE file. -+ */ -+extern int rle_getrow( rle_hdr * the_hdr, -+ rle_pixel * scanline[] ); -+ -+/* From rle_getskip.c */ -+ -+/***************************************************************** -+ * TAG( rle_getskip ) -+ * Skip a scanline, return the number of the next one. -+ */ -+extern unsigned int rle_getskip( rle_hdr *the_hdr ); -+ -+/* From rle_hdr.c. */ -+ -+/***************************************************************** -+ * TAG( rle_names ) -+ * -+ * Load the command and file names into the rle_hdr. -+ */ -+extern void rle_names( rle_hdr *the_hdr, -+ const char *pgmname, -+ const char *fname, -+ int img_num ); -+ -+/***************************************************************** -+ * TAG( rle_hdr_cp ) -+ * -+ * Make a "safe" copy of a rle_hdr structure. -+ */ -+extern rle_hdr * rle_hdr_cp( rle_hdr *from_hdr, -+ rle_hdr *to_hdr ); -+ -+/***************************************************************** -+ * TAG( rle_hdr_init ) -+ * -+ * Initialize a rle_hdr structure. -+ */ -+extern rle_hdr * rle_hdr_init( rle_hdr *the_hdr ); -+ -+/***************************************************************** -+ * TAG( rle_hdr_clear ) -+ * -+ */ -+extern void rle_hdr_clear( rle_hdr *the_hdr ); -+ -+/* From rle_putrow.c. */ -+ -+/***************************************************************** -+ * TAG( rgb_to_bw ) -+ * -+ * Converts RGB data to gray data via the NTSC Y transform. -+ */ -+extern void rgb_to_bw( rle_pixel *red_row, -+ rle_pixel *green_row, -+ rle_pixel *blue_row, -+ rle_pixel *bw_row, -+ int rowlen ); -+ -+/***************************************************************** -+ * TAG( rle_puteof ) -+ * -+ * Write an End-of-image opcode to the RLE file. -+ */ -+extern void rle_puteof( rle_hdr *the_hdr ); -+ -+/***************************************************************** -+ * TAG( rle_putrow ) -+ * -+ * Write a scanline of data to the RLE file. -+ */ -+extern void rle_putrow( rle_pixel *rows[], int rowlen, rle_hdr *the_hdr ); -+ -+/***************************************************************** -+ * TAG( rle_put_init ) -+ * -+ * Initialize header for output, but don't write it to the file. -+ */ -+extern void rle_put_init( rle_hdr * the_hdr ); -+ -+/***************************************************************** -+ * TAG( rle_put_setup ) -+ * -+ * Write header information to a new RLE image file. -+ */ -+extern void rle_put_setup( rle_hdr * the_hdr ); -+ -+/***************************************************************** -+ * TAG( rle_skiprow ) -+ * -+ * Skip nrow scanlines in the output file. -+ */ -+extern void rle_skiprow( rle_hdr *the_hdr, int nrow ); -+ -+/* From rle_cp.c */ -+/***************************************************************** -+ * TAG( rle_cp ) -+ * Copy image data from input to output with minimal interpretation. -+ */ -+extern void rle_cp( rle_hdr *in_hdr, rle_hdr *out_hdr ); -+ -+/* From rle_row_alc.c. */ -+/***************************************************************** -+ * TAG( rle_row_alloc ) -+ * -+ * Allocate scanline memory for use by rle_getrow. -+ */ -+extern int rle_row_alloc( rle_hdr * the_hdr, -+ rle_pixel *** scanp ); -+ -+/***************************************************************** -+ * TAG( rle_row_free ) -+ * -+ * Free the above. -+ */ -+extern void rle_row_free( rle_hdr *the_hdr, rle_pixel **scanp ); -+ -+/* From buildmap.c. */ -+/* -+ * buildmap - build a more usable colormap from data in the_hdr struct. -+ */ -+extern rle_pixel **buildmap( rle_hdr *the_hdr, -+ int minmap, -+ double orig_gamma, -+ double new_gamma ); -+ -+/* From rle_getcom.c. */ -+/***************************************************************** -+ * TAG( rle_getcom ) -+ * -+ * Get a specific comment from the image comments. -+ */ -+const char * -+rle_getcom(const char * const name, -+ rle_hdr * const the_hdr); -+ -+/* From rle_putcom.c. */ -+ -+/* Delete a specific comment from the image comments. */ -+const char * -+rle_delcom(const char * const name, -+ rle_hdr * const the_hdr); -+ -+/* Put (or replace) a comment into the image comments. */ -+const char * -+rle_putcom(const char * const value, -+ rle_hdr * const the_hdr); -+ -+/* From dither.c. */ -+/***************************************************************** -+ * TAG( bwdithermap ) -+ * Create a color map for ordered dithering in grays. -+ */ -+extern void bwdithermap( int levels, double gamma, int bwmap[], -+ int divN[256], int modN[256], int magic[16][16] ); -+/***************************************************************** -+ * TAG( ditherbw ) -+ * Dither a gray-scale value. -+ */ -+extern int ditherbw( int x, int y, int val, -+ int divN[256], int modN[256], int magic[16][16] ); -+/***************************************************************** -+ * TAG( dithergb ) -+ * Dither a color value. -+ */ -+extern int dithergb( int x, int y, int r, int g, int b, -+ int divN[256], int modN[256], int magic[16][16] ); -+/***************************************************************** -+ * TAG( dithermap ) -+ * Create a color map for ordered dithering in color. -+ */ -+extern void dithermap( int levels, double gamma, int rgbmap[][3], -+ int divN[256], int modN[256], int magic[16][16] ); -+/***************************************************************** -+ * TAG( make_square ) -+ * Make a 16x16 magic square for ordered dithering. -+ */ -+extern void make_square( double N, int divN[256], int modN[256], -+ int magic[16][16] ); -+ -+/* From float_to_exp.c. */ -+/***************************************************************** -+ * TAG( float_to_exp ) -+ * Convert a list of floating point numbers to "exp" format. -+ */ -+extern void float_to_exp( int count, float * floats, rle_pixel * pixels ); -+ -+/* From rle_open_f.c. */ -+/***************************************************************** -+ * TAG( rle_open_f ) -+ * -+ * Open an input/output file with default. -+ */ -+FILE * -+rle_open_f(const char * prog_name, const char * file_name, -+ const char * mode); -+ -+/***************************************************************** -+ * TAG( rle_open_f_noexit ) -+ * -+ * Open an input/output file with default. -+ */ -+FILE * -+rle_open_f_noexit(const char * const prog_name, -+ const char * const file_name, -+ const char * const mode); -+ -+/***************************************************************** -+ * TAG( rle_close_f ) -+ * -+ * Close a file opened by rle_open_f. If the file is stdin or stdout, -+ * it will not be closed. -+ */ -+extern void -+rle_close_f( FILE *fd ); -+ -+/* From colorquant.c. */ -+/***************************************************************** -+ * TAG( colorquant ) -+ * Compute a colormap for quantizing an image to a limited set of colors. -+ */ -+extern int colorquant( rle_pixel *red, rle_pixel *green, rle_pixel *blue, -+ unsigned long pixels, rle_pixel *colormap[3], -+ int colors, int bits, -+ rle_pixel *rgbmap, int fast, int otherimages ); -+ -+/* From rle_addhist.c. */ -+ -+/* Append history information to the HISTORY comment. */ -+void -+rle_addhist(char * argv[], -+ rle_hdr * const in_hdr, -+ rle_hdr * const out_hdr); -+ -+/* From cmd_name.c. */ -+/***************************************************************** -+ * TAG( cmd_name ) -+ * Extract command name from argv. -+ */ -+extern char *cmd_name( char **argv ); -+ -+/* From scanargs.c. */ -+/***************************************************************** -+ * TAG( scanargs ) -+ * Scan command argument list and parse arguments. -+ */ -+extern int scanargs( int argc, -+ char **argv, -+ const char *format, -+ ... ); -+ -+/* From hilbert.c */ -+/***************************************************************** -+ * TAG( hilbert_i2c ) -+ * Convert an index into a Hilbert curve to a set of coordinates. -+ */ -+extern void hilbert_c2i( int n, int m, int a[], long int *r ); -+ -+/***************************************************************** -+ * TAG( hilbert_c2i ) -+ * Convert coordinates of a point on a Hilbert curve to its index. -+ */ -+extern void hilbert_i2c( int n, int m, long int r, int a[] ); -+ -+/* From inv_cmap.c */ -+/***************************************************************** -+ * TAG( inv_cmap ) -+ * Compute an inverse colormap efficiently. -+ */ -+extern void inv_cmap( int colors, -+ unsigned char *colormap[3], -+ int bits, -+ unsigned long *dist_buf, -+ unsigned char *rgbmap ); -+ -+#endif /* RLE_H */ -diff --git a/urt/rle_addhist.c b/urt/rle_addhist.c -index b165175..e09ed94 100644 ---- a/urt/rle_addhist.c -+++ b/urt/rle_addhist.c +diff -ruNp a/urt/rle_addhist.c b/urt/rle_addhist.c +--- a/urt/rle_addhist.c 2021-06-02 15:53:59.825205563 +0200 ++++ b/urt/rle_addhist.c 2021-06-02 20:23:21.834634475 +0200 @@ -70,13 +70,18 @@ rle_addhist(char * argv[], return; @@ -6899,10 +2865,9 @@ index b165175..e09ed94 100644 ++length; /*Cater for the null. */ -diff --git a/urt/rle_getrow.c b/urt/rle_getrow.c -index ae220f5..39010ba 100644 ---- a/urt/rle_getrow.c -+++ b/urt/rle_getrow.c +diff -ruNp a/urt/rle_getrow.c b/urt/rle_getrow.c +--- a/urt/rle_getrow.c 2021-06-02 15:53:59.825205563 +0200 ++++ b/urt/rle_getrow.c 2021-06-02 20:23:21.834634475 +0200 @@ -164,6 +164,7 @@ rle_get_setup(rle_hdr * const the_hdr) { char * cp; @@ -6911,536 +2876,30 @@ index ae220f5..39010ba 100644 evenlen = (comlen + 1) & ~1; /* make it even */ if (evenlen) { MALLOCARRAY(comment_buf, evenlen); -diff --git a/urt/rle_getrow.c.orig b/urt/rle_getrow.c.orig -new file mode 100644 -index 0000000..ae220f5 ---- /dev/null -+++ b/urt/rle_getrow.c.orig -@@ -0,0 +1,520 @@ +diff -ruNp a/urt/rle.h b/urt/rle.h +--- a/urt/rle.h 2021-06-02 15:53:59.825205563 +0200 ++++ b/urt/rle.h 2021-06-02 20:23:21.834634475 +0200 +@@ -153,6 +153,17 @@ rle_hdr /* End of typedef. * + */ + extern rle_hdr rle_dflt_hdr; + +/* -+ * This software is copyrighted as noted below. It may be freely copied, -+ * modified, and redistributed, provided that the copyright notice is -+ * preserved on all copies. -+ * -+ * There is no warranty or other guarantee of fitness for this software, -+ * it is provided solely "as is". Bug reports or fixes may be sent -+ * to the author, who may or may not act on them as he desires. -+ * -+ * You may not include this software in a program or other software product -+ * without supplying the source, or without informing the end-user that the -+ * source is available for no extra charge. -+ * -+ * If you modify this software, you should include a notice giving the -+ * name of the person performing the modification, the date of modification, -+ * and the reason for such modification. -+ * -+ * Modified at BRL 16-May-88 by Mike Muuss to avoid Alliant STDC desire -+ * to have all "void" functions so declared. -+ */ -+/* -+ * rle_getrow.c - Read an RLE file in. -+ * -+ * Author: Spencer W. Thomas -+ * Computer Science Dept. -+ * University of Utah -+ * Date: Wed Apr 10 1985 -+ * Copyright (c) 1985 Spencer W. Thomas -+ * -+ * $Id: rle_getrow.c,v 3.0.1.5 1992/03/04 19:33:08 spencer Exp spencer $ ++ * Provided by pm library + */ + -+#include -+#include -+ -+#include "netpbm/pm.h" -+#include "netpbm/mallocvar.h" -+ -+#include "rle.h" -+#include "rle_code.h" -+#include "vaxshort.h" -+ -+/* Read a two-byte "short" that started in VAX (LITTLE_ENDIAN) order */ -+#define VAXSHORT( var, fp )\ -+ { var = fgetc(fp)&0xFF; var |= (fgetc(fp)) << 8; } -+ -+/* Instruction format -- first byte is opcode, second is datum. */ -+ -+#define OPCODE(inst) (inst[0] & ~LONG) -+#define LONGP(inst) (inst[0] & LONG) -+#define DATUM(inst) (inst[1] & 0xff) /* Make sure it's unsigned. */ -+ -+static int debug_f; /* If non-zero, print debug info. */ -+ -+int -+rle_get_setup(rle_hdr * const the_hdr) { -+/*----------------------------------------------------------------------------- -+ Read the initialization information from an RLE file. -+ Inputs: -+ the_hdr: Contains pointer to the input file. -+ Outputs: -+ the_hdr: Initialized with information from the input file. -+ Returns -+ 0 on success, -+ -1 if the file is not an RLE file, -+ -2 if malloc of the color map failed, -+ -3 if an immediate EOF is hit (empty input file) -+ -4 if an EOF is encountered reading the setup information. -+ Assumptions: -+ infile points to the "magic" number in an RLE file (usually byte 0 -+ in the file). -+ Algorithm: -+ Read in the setup info and fill in the_hdr. -+---------------------------------------------------------------------------- */ -+ struct XtndRsetup setup; -+ short magic; -+ FILE * infile = the_hdr->rle_file; -+ int i; -+ char * comment_buf; -+ -+ /* Clear old stuff out of the header. */ -+ rle_hdr_clear(the_hdr); -+ if (the_hdr->is_init != RLE_INIT_MAGIC) -+ rle_names(the_hdr, "Urt", "some file", 0); -+ ++the_hdr->img_num; /* Count images. */ -+ -+ VAXSHORT(magic, infile); -+ if (feof(infile)) -+ return RLE_EMPTY; -+ if (magic != RLE_MAGIC) -+ return RLE_NOT_RLE; -+ fread(&setup, 1, SETUPSIZE, infile); /* assume VAX packing */ -+ if (feof( infile)) -+ return RLE_EOF; -+ -+ /* Extract information from setup */ -+ the_hdr->ncolors = setup.h_ncolors; -+ for (i = 0; i < the_hdr->ncolors; ++i) -+ RLE_SET_BIT(*the_hdr, i); -+ -+ if (!(setup.h_flags & H_NO_BACKGROUND) && setup.h_ncolors > 0) { -+ rle_pixel * bg_color; -+ -+ MALLOCARRAY(the_hdr->bg_color, setup.h_ncolors); -+ if (!the_hdr->bg_color) -+ pm_error("Failed to allocation array for %u background colors", -+ setup.h_ncolors); -+ MALLOCARRAY(bg_color, 1 + (setup.h_ncolors / 2) * 2); -+ if (!bg_color) -+ pm_error("Failed to allocation array for %u background colors", -+ 1+(setup.h_ncolors / 2) * 2); -+ fread((char *)bg_color, 1, 1 + (setup.h_ncolors / 2) * 2, infile); -+ for (i = 0; i < setup.h_ncolors; ++i) -+ the_hdr->bg_color[i] = bg_color[i]; -+ free(bg_color); -+ } else { -+ getc(infile); /* skip filler byte */ -+ the_hdr->bg_color = NULL; -+ } -+ -+ if (setup.h_flags & H_NO_BACKGROUND) -+ the_hdr->background = 0; -+ else if (setup.h_flags & H_CLEARFIRST) -+ the_hdr->background = 2; -+ else -+ the_hdr->background = 1; -+ if (setup.h_flags & H_ALPHA) { -+ the_hdr->alpha = 1; -+ RLE_SET_BIT( *the_hdr, RLE_ALPHA ); -+ } else -+ the_hdr->alpha = 0; -+ -+ the_hdr->xmin = vax_gshort(setup.hc_xpos); -+ the_hdr->ymin = vax_gshort(setup.hc_ypos); -+ the_hdr->xmax = the_hdr->xmin + vax_gshort(setup.hc_xlen) - 1; -+ the_hdr->ymax = the_hdr->ymin + vax_gshort(setup.hc_ylen) - 1; -+ -+ the_hdr->ncmap = setup.h_ncmap; -+ the_hdr->cmaplen = setup.h_cmaplen; -+ if (the_hdr->ncmap > 0) { -+ int const maplen = the_hdr->ncmap * (1 << the_hdr->cmaplen); -+ -+ int i; -+ char *maptemp; -+ -+ MALLOCARRAY(the_hdr->cmap, maplen); -+ MALLOCARRAY(maptemp, 2 * maplen); -+ if (the_hdr->cmap == NULL || maptemp == NULL) { -+ pm_error("Malloc failed for color map of size %d*%d " -+ "in rle_get_setup, reading '%s'", -+ the_hdr->ncmap, (1 << the_hdr->cmaplen), -+ the_hdr->file_name ); -+ return RLE_NO_SPACE; -+ } -+ fread(maptemp, 2, maplen, infile); -+ for (i = 0; i < maplen; ++i) -+ the_hdr->cmap[i] = vax_gshort(&maptemp[i * 2]); -+ free(maptemp); -+ } -+ -+ /* Check for comments */ -+ if (setup.h_flags & H_COMMENT) { -+ short comlen, evenlen; -+ char * cp; -+ -+ VAXSHORT(comlen, infile); /* get comment length */ -+ evenlen = (comlen + 1) & ~1; /* make it even */ -+ if (evenlen) { -+ MALLOCARRAY(comment_buf, evenlen); -+ -+ if (comment_buf == NULL) { -+ pm_error("Malloc failed for comment buffer of size %d " -+ "in rle_get_setup, reading '%s'", -+ comlen, the_hdr->file_name ); -+ return RLE_NO_SPACE; -+ } -+ fread(comment_buf, 1, evenlen, infile); -+ /* Count the comments */ -+ for (i = 0, cp = comment_buf; cp < comment_buf + comlen; ++cp) -+ if (*cp == '\0') -+ ++i; -+ ++i; /* extra for NULL pointer at end */ -+ /* Get space to put pointers to comments */ -+ MALLOCARRAY(the_hdr->comments, i); -+ if (the_hdr->comments == NULL) { -+ pm_error("Malloc failed for %d comment pointers " -+ "in rle_get_setup, reading '%s'", -+ i, the_hdr->file_name ); -+ return RLE_NO_SPACE; -+ } -+ /* Get pointers to the comments */ -+ *the_hdr->comments = comment_buf; -+ for (i = 1, cp = comment_buf + 1; -+ cp < comment_buf + comlen; -+ ++cp) -+ if (*(cp - 1) == '\0') -+ the_hdr->comments[i++] = cp; -+ the_hdr->comments[i] = NULL; -+ } else -+ the_hdr->comments = NULL; -+ } else -+ the_hdr->comments = NULL; -+ -+ /* Initialize state for rle_getrow */ -+ the_hdr->priv.get.scan_y = the_hdr->ymin; -+ the_hdr->priv.get.vert_skip = 0; -+ the_hdr->priv.get.is_eof = 0; -+ the_hdr->priv.get.is_seek = ftell(infile) > 0; -+ debug_f = 0; -+ -+ if (!feof(infile)) -+ return RLE_SUCCESS; /* success! */ -+ else { -+ the_hdr->priv.get.is_eof = 1; -+ return RLE_EOF; -+ } -+} -+ -+ -+ -+void -+rle_get_setup_ok(rle_hdr * const the_hdr, -+ const char * const prog_name, -+ const char * const file_name) { -+/*----------------------------------------------------------------------------- -+ Read the initialization information from an RLE file. -+ -+ Inputs: -+ the_hdr: Contains pointer to the input file. -+ prog_name: Program name to be printed in the error message. -+ file_name: File name to be printed in the error message. -+ If NULL, the string "stdin" is generated. -+ -+ Outputs: -+ the_hdr: Initialized with information from the input file. -+ If reading the header fails, it prints an error message -+ and exits with the appropriate status code. -+ Algorithm: -+ rle_get_setup does all the work. -+---------------------------------------------------------------------------- */ -+ int code; -+ -+ /* Backwards compatibility: if is_init is not properly set, -+ * initialize the header. -+ */ -+ if (the_hdr->is_init != RLE_INIT_MAGIC) { -+ FILE * const f = the_hdr->rle_file; -+ rle_hdr_init( the_hdr ); -+ the_hdr->rle_file = f; -+ rle_names(the_hdr, prog_name, file_name, 0); -+ } -+ -+ code = rle_get_error(rle_get_setup(the_hdr), -+ the_hdr->cmd, the_hdr->file_name); -+ if (code) -+ exit(code); -+} -+ -+ -+ -+void -+rle_debug( on_off ) -+ int on_off; -+{ -+/*----------------------------------------------------------------------------- -+ Turn RLE debugging on or off. -+ Inputs: -+ on_off: if 0, stop debugging, else start. -+ Outputs: -+ Sets internal debug flag. -+ Assumptions: -+ [None] -+ Algorithm: -+ [None] -+---------------------------------------------------------------------------- */ -+ debug_f = on_off; -+ -+ /* Set line buffering on stderr. Character buffering is the default, and -+ * it is SLOOWWW for large amounts of output. -+ */ -+ setvbuf(stderr, NULL, _IOLBF, 0); -+} -+ -+ -+ -+int -+rle_getrow(rle_hdr * const the_hdr, -+ rle_pixel ** const scanline) { -+/*----------------------------------------------------------------------------- -+ Get a scanline from the input file. -+ Inputs: -+ the_hdr: Header structure containing information about -+ the input file. -+ Outputs: -+ scanline: an array of pointers to the individual color -+ scanlines. Scanline is assumed to have -+ the_hdr->ncolors pointers to arrays of rle_pixel, -+ each of which is at least the_hdr->xmax+1 long. -+ Returns the current scanline number. -+ Assumptions: -+ rle_get_setup has already been called. -+ Algorithm: -+ If a vertical skip is being executed, and clear-to-background is -+ specified (the_hdr->background is true), just set the -+ scanlines to the background color. If clear-to-background is -+ not set, just increment the scanline number and return. -+ -+ Otherwise, read input until a vertical skip is encountered, -+ decoding the instructions into scanline data. -+ -+ If ymax is reached (or, somehow, passed), continue reading and -+ discarding input until end of image. -+---------------------------------------------------------------------------- */ -+ FILE * const infile = the_hdr->rle_file; -+ -+ rle_pixel * scanc; -+ -+ int scan_x; /* current X position */ -+ int max_x; /* End of the scanline */ -+ int channel; /* current color channel */ -+ int ns; /* Number to skip */ -+ int nc; -+ short word, long_data; -+ char inst[2]; -+ -+ scan_x = the_hdr->xmin; /* initial value */ -+ max_x = the_hdr->xmax; /* initial value */ -+ channel = 0; /* initial value */ -+ /* Clear to background if specified */ -+ if (the_hdr->background != 1) { -+ if (the_hdr->alpha && RLE_BIT( *the_hdr, -1)) -+ memset((char *)scanline[-1] + the_hdr->xmin, 0, -+ the_hdr->xmax - the_hdr->xmin + 1); -+ for (nc = 0; nc < the_hdr->ncolors; ++nc) { -+ if (RLE_BIT( *the_hdr, nc)) { -+ /* Unless bg color given explicitly, use 0. */ -+ if (the_hdr->background != 2 || the_hdr->bg_color[nc] == 0) -+ memset((char *)scanline[nc] + the_hdr->xmin, 0, -+ the_hdr->xmax - the_hdr->xmin + 1); -+ else -+ memset((char *)scanline[nc] + the_hdr->xmin, -+ the_hdr->bg_color[nc], -+ the_hdr->xmax - the_hdr->xmin + 1); -+ } -+ } -+ } -+ -+ /* If skipping, then just return */ -+ if (the_hdr->priv.get.vert_skip > 0) { -+ --the_hdr->priv.get.vert_skip; -+ ++the_hdr->priv.get.scan_y; -+ if (the_hdr->priv.get.vert_skip > 0) { -+ if (the_hdr->priv.get.scan_y >= the_hdr->ymax) { -+ int const y = the_hdr->priv.get.scan_y; -+ while (rle_getskip(the_hdr) != 32768) -+ ; -+ return y; -+ } else -+ return the_hdr->priv.get.scan_y; -+ } -+ } -+ -+ /* If EOF has been encountered, return also */ -+ if (the_hdr->priv.get.is_eof) -+ return ++the_hdr->priv.get.scan_y; -+ -+ /* Otherwise, read and interpret instructions until a skipLines -+ instruction is encountered. -+ */ -+ if (RLE_BIT(*the_hdr, channel)) -+ scanc = scanline[channel] + scan_x; -+ else -+ scanc = NULL; -+ for (;;) { -+ inst[0] = getc(infile); -+ inst[1] = getc(infile); -+ if (feof(infile)) { -+ the_hdr->priv.get.is_eof = 1; -+ break; /* <--- one of the exits */ -+ } -+ -+ switch(OPCODE(inst)) { -+ case RSkipLinesOp: -+ if (LONGP(inst)) { -+ VAXSHORT(the_hdr->priv.get.vert_skip, infile); -+ } else -+ the_hdr->priv.get.vert_skip = DATUM(inst); -+ if (debug_f) -+ pm_message("Skip %d Lines (to %d)", -+ the_hdr->priv.get.vert_skip, -+ the_hdr->priv.get.scan_y + -+ the_hdr->priv.get.vert_skip); -+ -+ break; /* need to break for() here, too */ -+ -+ case RSetColorOp: -+ channel = DATUM(inst); /* select color channel */ -+ if (channel == 255) -+ channel = -1; -+ scan_x = the_hdr->xmin; -+ if (RLE_BIT(*the_hdr, channel)) -+ scanc = scanline[channel]+scan_x; -+ if (debug_f) -+ pm_message("Set color to %d (reset x to %d)", -+ channel, scan_x ); -+ break; -+ -+ case RSkipPixelsOp: -+ if (LONGP(inst)) { -+ VAXSHORT(long_data, infile); -+ scan_x += long_data; -+ scanc += long_data; -+ if (debug_f) -+ pm_message("Skip %d pixels (to %d)", long_data, scan_x); -+ } else { -+ scan_x += DATUM(inst); -+ scanc += DATUM(inst); -+ if (debug_f) -+ pm_message("Skip %d pixels (to %d)", DATUM(inst), scan_x); -+ } -+ break; -+ -+ case RByteDataOp: -+ if (LONGP(inst)) { -+ VAXSHORT(nc, infile); -+ } else -+ nc = DATUM(inst); -+ ++nc; -+ if (debug_f) { -+ if (RLE_BIT(*the_hdr, channel)) -+ pm_message("Pixel data %d (to %d):", nc, scan_x + nc); -+ else -+ pm_message("Pixel data %d (to %d)", nc, scan_x + nc); -+ } -+ if (RLE_BIT(*the_hdr, channel)) { -+ /* Don't fill past end of scanline! */ -+ if (scan_x + nc > max_x) { -+ ns = scan_x + nc - max_x - 1; -+ nc -= ns; -+ } else -+ ns = 0; -+ fread((char *)scanc, 1, nc, infile); -+ while (ns-- > 0) -+ getc(infile); -+ if (nc & 0x1) -+ getc(infile); /* throw away odd byte */ -+ } else { -+ if (the_hdr->priv.get.is_seek) -+ fseek(infile, ((nc + 1) / 2) * 2, 1); -+ else { -+ int ii; -+ for (ii = ((nc + 1) / 2) * 2; ii > 0; --ii) -+ getc(infile); /* discard it */ -+ } -+ } -+ scanc += nc; -+ scan_x += nc; -+ if (debug_f && RLE_BIT(*the_hdr, channel)) { -+ rle_pixel * cp; -+ for (cp = scanc - nc; nc > 0; --nc) -+ fprintf(stderr, "%02x", *cp++); -+ putc('\n', stderr); -+ } -+ break; -+ -+ case RRunDataOp: -+ if (LONGP(inst)) { -+ VAXSHORT(nc, infile); -+ } else -+ nc = DATUM(inst); -+ ++nc; -+ scan_x += nc; -+ -+ VAXSHORT(word, infile); -+ if (debug_f) -+ pm_message("Run length %d (to %d), data %02x", -+ nc, scan_x, word); -+ if (RLE_BIT(*the_hdr, channel)) { -+ if (scan_x > max_x) { -+ ns = scan_x - max_x - 1; -+ nc -= ns; -+ } else -+ ns = 0; -+ if (nc >= 10) { /* break point for 785, anyway */ -+ memset((char *)scanc, word, nc); -+ scanc += nc; -+ } else { -+ for (nc--; nc >= 0; --nc, ++scanc) -+ *scanc = word; -+ } -+ } -+ break; -+ -+ case REOFOp: -+ the_hdr->priv.get.is_eof = 1; -+ if (debug_f) -+ pm_message("End of Image"); -+ break; -+ -+ default: -+ pm_error("rle_getrow: Unrecognized opcode: %d, reading %s", -+ inst[0], the_hdr->file_name); -+ } -+ if (OPCODE(inst) == RSkipLinesOp || OPCODE(inst) == REOFOp) -+ break; /* <--- the other loop exit */ -+ } -+ -+ /* If at end, skip the rest of a malformed image. */ -+ if (the_hdr->priv.get.scan_y >= the_hdr->ymax) { -+ int const y = the_hdr->priv.get.scan_y; -+ while (rle_getskip(the_hdr) != 32768 ) -+ ; -+ return y; -+ } -+ -+ return the_hdr->priv.get.scan_y; -+} -+ -+ -+ -diff --git a/urt/rle_hdr.c b/urt/rle_hdr.c -index bdb728d..e3f5330 100644 ---- a/urt/rle_hdr.c -+++ b/urt/rle_hdr.c ++extern void overflow_add(int, int); ++#define overflow2(a,b) __overflow2(a,b) ++extern void __overflow2(int, int); ++extern void overflow3(int, int, int); ++extern void *malloc2(int, int); ++extern void *malloc3(int, int, int); ++extern void *realloc2(void *, int, int); + + /* Declare RLE library routines. */ + +diff -ruNp a/urt/rle_hdr.c b/urt/rle_hdr.c +--- a/urt/rle_hdr.c 2021-06-02 15:53:59.825205563 +0200 ++++ b/urt/rle_hdr.c 2021-06-02 20:23:21.835634483 +0200 @@ -148,7 +148,7 @@ rle_hdr_cp(rle_hdr * const fromHdrP, if (toHdrP->cmap) { size_t const size = @@ -7467,545 +2926,9 @@ index bdb728d..e3f5330 100644 size *= sizeof(char *); toHdrP->comments = malloc(size); if (!toHdrP->comments) -diff --git a/urt/rle_hdr.c.orig b/urt/rle_hdr.c.orig -new file mode 100644 -index 0000000..1edb7a3 ---- /dev/null -+++ b/urt/rle_hdr.c.orig -@@ -0,0 +1,286 @@ -+/* -+ * This software is copyrighted as noted below. It may be freely copied, -+ * modified, and redistributed, provided that the copyright notice is -+ * preserved on all copies. -+ * -+ * There is no warranty or other guarantee of fitness for this software, -+ * it is provided solely "as is". Bug reports or fixes may be sent -+ * to the author, who may or may not act on them as he desires. -+ * -+ * You may not include this software in a program or other software product -+ * without supplying the source, or without informing the end-user that the -+ * source is available for no extra charge. -+ * -+ * If you modify this software, you should include a notice giving the -+ * name of the person performing the modification, the date of modification, -+ * and the reason for such modification. -+ */ -+/* -+ * rle_hdr.c - Functions to manipulate rle_hdr structures. -+ * -+ * Author: Spencer W. Thomas -+ * EECS Dept. -+ * University of Michigan -+ * Date: Mon May 20 1991 -+ * Copyright (c) 1991, University of Michigan -+ */ -+ -+#include -+ -+#include "nstring.h" -+#include "mallocvar.h" -+ -+#include "rle_config.h" -+#include "rle.h" -+ -+ -+ -+void -+rle_names(rle_hdr * const hdrP, -+ const char * const pgmname, -+ const char * const fname, -+ int const imgNum) { -+/*---------------------------------------------------------------------------- -+ * Load program and file names into header. -+ * Inputs: -+ * hdrP: Header to modify. -+ * pgmname: The program name. -+ * fname: The file name. -+ * imgNum: Number of the image within the file. -+ * Outputs: -+ * *hdrP: Modified header. -+-----------------------------------------------------------------------------*/ -+ -+ /* Algorithm: -+ If values previously filled in (by testing is_init field), -+ free them. Make copies of file name and program name, -+ modifying file name for standard i/o. Set is_init field. -+ */ -+ const char * newFname; -+ const char * newPgmname; -+ -+ /* Mark as filled in. */ -+ hdrP->is_init = RLE_INIT_MAGIC; -+ -+ /* Default file name for stdin/stdout. */ -+ if (!fname || streq(fname, "-") || strlen(fname) == 0) -+ newFname = "Standard I/O"; -+ else -+ newFname = fname; -+ -+ if (pgmname) -+ newPgmname = pgmname; -+ else -+ newPgmname = rle_dflt_hdr.cmd; -+ -+ /* Fill in with copies of the strings. */ -+ if (hdrP->cmd != newPgmname) -+ hdrP->cmd = pm_strdup(newPgmname); -+ -+ if (hdrP->file_name != newFname) -+ hdrP->cmd = pm_strdup(newFname); -+ -+ hdrP->img_num = imgNum; -+} -+ -+ -+ -+/* Used by rle_hdr_cp and rle_hdr_init to avoid recursion loops. */ -+static int noRecurse = 0; -+ -+ -+ -+rle_hdr * -+rle_hdr_cp(rle_hdr * const fromHdrP, -+ rle_hdr * const toHdrArgP) { -+/*---------------------------------------------------------------------------- -+ * Make a "safe" copy of a rle_hdr structure. -+ * Inputs: -+ * *fromHdrP: Header to be copied. -+ * Outputs: -+ * *toHdrPd: Copy of from_hdr, with all memory referred to -+ * by pointers copied. Also returned as function -+ * value. If NULL, a static header is used. -+ * Assumptions: -+ * It is safe to call rle_hdr_init on *toHdrP. -+-----------------------------------------------------------------------------*/ -+ /* Algorithm: -+ Initialize *toHdrP, copy *fromHdrP to it, then copy the memory -+ referred to by all non-null pointers. -+ */ -+ static rle_hdr dfltHdr; -+ rle_hdr * toHdrP; -+ const char * cmd; -+ const char * file; -+ unsigned int num; -+ -+ /* Save command, file name, and image number if already initialized. */ -+ if (toHdrArgP && toHdrArgP->is_init == RLE_INIT_MAGIC) { -+ cmd = toHdrArgP->cmd; -+ file = toHdrArgP->file_name; -+ num = toHdrArgP->img_num; -+ } else { -+ cmd = file = NULL; -+ num = 0; -+ } -+ -+ if (!noRecurse) { -+ ++noRecurse; -+ rle_hdr_init(toHdrArgP); -+ --noRecurse; -+ } -+ -+ toHdrP = toHdrArgP ? toHdrArgP : &dfltHdr; -+ -+ *toHdrP = *fromHdrP; -+ -+ if (toHdrP->bg_color) { -+ unsigned int i; -+ -+ MALLOCARRAY(toHdrP->bg_color, toHdrP->ncolors); -+ if (!toHdrP->bg_color) -+ pm_error("Failed to allocate array for %u background colors", -+ toHdrP->ncolors); -+ for (i = 0; i < toHdrP->ncolors; ++i) -+ toHdrP->bg_color[i] = fromHdrP->bg_color[i]; -+ } -+ -+ if (toHdrP->cmap) { -+ size_t const size = -+ toHdrP->ncmap * (1 << toHdrP->cmaplen) * sizeof(rle_map); -+ toHdrP->cmap = malloc(size); -+ if (!toHdrP->cmap) -+ pm_error("Failed to allocate memory for %u color maps " -+ "of length %u", toHdrP->ncmap, 1 << toHdrP->cmaplen); -+ memcpy(toHdrP->cmap, fromHdrP->cmap, size); -+ } -+ -+ /* Only copy array of pointers, as the original comment memory -+ * never gets overwritten. -+ */ -+ if (toHdrP->comments) { -+ unsigned int size; -+ const char ** cp; -+ -+ /* Count the comments. */ -+ for (cp = toHdrP->comments, size = 0; *cp; ++cp) -+ ++size; -+ -+ /* Check if there are really any comments. */ -+ if (size > 0) { -+ ++size; /* Copy the NULL pointer, too. */ -+ size *= sizeof(char *); -+ toHdrP->comments = malloc(size); -+ if (!toHdrP->comments) -+ pm_error("Failed to allocation %u bytes for comments", size); -+ memcpy(toHdrP->comments, fromHdrP->comments, size); -+ } else -+ toHdrP->comments = NULL; /* Blow off empty comment list. */ -+ } -+ -+ /* Restore the names to their original values. */ -+ toHdrP->cmd = cmd; -+ toHdrP->file_name = file; -+ -+ /* Lines above mean nothing much happens if cmd and file are != NULL. */ -+ rle_names(toHdrP, toHdrP->cmd, toHdrP->file_name, num); -+ -+ return toHdrP; -+} -+ -+ -+ -+void -+rle_hdr_clear(rle_hdr * const hdrP) { -+/*---------------------------------------------------------------------------- -+ * Clear out the allocated memory pieces of a header. -+ * -+ * This routine is intended to be used internally by the library, to -+ * clear a header before putting new data into it. It clears all the -+ * fields that would be set by reading in a new image header. -+ * Therefore, it does not clear the program and file names. -+ * -+ * Inputs: -+ * hdrP: To be cleared. -+ * Outputs: -+ * *hdrP: After clearing. -+ * Assumptions: -+ * If is_init field is RLE_INIT_MAGIC, the header has been -+ * properly initialized. This will fail every 2^(-32) times, on -+ * average. -+-----------------------------------------------------------------------------*/ -+ /* Algorithm: -+ Free memory and set to zero all pointers, except program and -+ file name. -+ */ -+ -+ /* Try to free memory. Assume if is_init is properly set that this -+ * header has been previously initialized, therefore it is safe to -+ * free memory. -+ */ -+ if (hdrP && hdrP->is_init == RLE_INIT_MAGIC) { -+ if (hdrP->bg_color ) -+ free(hdrP->bg_color); -+ hdrP->bg_color = NULL; -+ if (hdrP->cmap ) -+ free(hdrP->cmap); -+ hdrP->cmap = NULL; -+ /* Unfortunately, we don't know how to free the comment memory. */ -+ if (hdrP->comments) -+ free(hdrP->comments); -+ hdrP->comments = NULL; -+ } -+} -+ -+ -+ -+rle_hdr * -+rle_hdr_init(rle_hdr * const hdrP) { -+/*---------------------------------------------------------------------------- -+ * Initialize a rle_hdr structure. -+ * Inputs: -+ * hdrP: Header to be initialized. -+ * Outputs: -+ * *hdrP: Initialized header. -+ * Assumptions: -+ * If hdrP->is_init is RLE_INIT_MAGIC, the header has been -+ * previously initialized. -+ * If the_hdr is a copy of another rle_hdr structure, the copy -+ * was made with rle_hdr_cp. -+-----------------------------------------------------------------------------*/ -+ /* Algorithm: -+ Fill in fields of rle_dflt_hdr that could not be set by the loader -+ If the_hdr is rle_dflt_hdr, do nothing else -+ Else: -+ If hdrP is NULL, return a copy of rle_dflt_hdr in static storage -+ If hdrP->is_init is RLE_INIT_MAGIC, free all memory -+ pointed to by non-null pointers. -+ If this is a recursive call to rle_hdr_init, clear *hdrP and -+ return hdrP. -+ Else make a copy of rle_dflt_hdr and return its address. Make the -+ copy in static storage if hdrP is NULL, and in *hdrP otherwise. -+ */ -+ rle_hdr * retval; -+ -+ rle_dflt_hdr.rle_file = stdout; -+ -+ /* The rest of rle_dflt_hdr is set by the loader's data initialization */ -+ -+ if (hdrP == &rle_dflt_hdr) -+ retval = hdrP; -+ else { -+ rle_hdr_clear(hdrP); -+ -+ /* Call rle_hdr_cp only if not called from there. */ -+ if (!noRecurse) { -+ ++noRecurse; -+ retval = rle_hdr_cp(&rle_dflt_hdr, hdrP); -+ --noRecurse; -+ } else -+ retval = hdrP; -+ } -+ return retval; -+} -+ -+ -+ -diff --git a/urt/rle_hdr.c.rej b/urt/rle_hdr.c.rej -new file mode 100644 -index 0000000..62f2fb0 ---- /dev/null -+++ b/urt/rle_hdr.c.rej -@@ -0,0 +1,63 @@ -+--- urt/rle_hdr.c -++++ urt/rle_hdr.c -+@@ -80,7 +80,10 @@ int img_num; -+ /* Fill in with copies of the strings. */ -+ if ( the_hdr->cmd != pgmname ) -+ { -+- char *tmp = (char *)malloc( strlen( pgmname ) + 1 ); -++ char *tmp; -++ -++ overflow_add(strlen(pgmname), 1); -++ tmp = malloc( strlen(pgmname) + 1 ); -+ RLE_CHECK_ALLOC( pgmname, tmp, 0 ); -+ strcpy( tmp, pgmname ); -+ the_hdr->cmd = tmp; -+@@ -88,8 +91,10 @@ int img_num; -+ -+ if ( the_hdr->file_name != fname ) -+ { -+- char *tmp = (char *)malloc( strlen( fname ) + 1 ); -+- RLE_CHECK_ALLOC( pgmname, tmp, 0 ); -++ char *tmp; -++ overflow_add(strlen(fname), 1); -++ tmp = malloc( strlen( fname ) + 1 ); -++ RLE_CHECK_ALLOC( pgmname, tmp, 0 ); -+ strcpy( tmp, fname ); -+ the_hdr->file_name = tmp; -+ } -+@@ -153,6 +158,7 @@ rle_hdr *from_hdr, *to_hdr; -+ if ( to_hdr->bg_color ) -+ { -+ int size = to_hdr->ncolors * sizeof(int); -++ overflow2(to_hdr->ncolors, sizeof(int)); -+ to_hdr->bg_color = (int *)malloc( size ); -+ RLE_CHECK_ALLOC( to_hdr->cmd, to_hdr->bg_color, "background color" ); -+ memcpy( to_hdr->bg_color, from_hdr->bg_color, size ); -+@@ -161,7 +167,7 @@ rle_hdr *from_hdr, *to_hdr; -+ if ( to_hdr->cmap ) -+ { -+ int size = to_hdr->ncmap * (1 << to_hdr->cmaplen) * sizeof(rle_map); -+- to_hdr->cmap = (rle_map *)malloc( size ); -++ to_hdr->cmap = (rle_map *)malloc3( to_hdr->ncmap, 1<cmaplen, sizeof(rle_map)); -+ RLE_CHECK_ALLOC( to_hdr->cmd, to_hdr->cmap, "color map" ); -+ memcpy( to_hdr->cmap, from_hdr->cmap, size ); -+ } -+@@ -173,12 +179,17 @@ rle_hdr *from_hdr, *to_hdr; -+ { -+ int size = 0; -+ CONST_DECL char **cp; -+- for ( cp=to_hdr->comments; *cp; cp++ ) -++ for ( cp=to_hdr->comments; *cp; cp++ ) -++ { -++ overflow_add(size, 1); -+ size++; /* Count the comments. */ -++ } -+ /* Check if there are really any comments. */ -+ if ( size ) -+ { -++ overflow_add(size, 1); -+ size++; /* Copy the NULL pointer, too. */ -++ overflow2(size, sizeof(char *)); -+ size *= sizeof(char *); -+ to_hdr->comments = (CONST_DECL char **)malloc( size ); -+ RLE_CHECK_ALLOC( to_hdr->cmd, to_hdr->comments, "comments" ); -diff --git a/urt/rle_open_f.c b/urt/rle_open_f.c -index 1aeb644..c2ef37d 100644 ---- a/urt/rle_open_f.c -+++ b/urt/rle_open_f.c -@@ -1,7 +1,7 @@ --/* -+/* - * rle_open_f.c - Open a file with defaults. -- * -- * Author : Jerry Winters -+ * -+ * Author : Jerry Winters - * EECS Dept. - * University of Michigan - * Date: 11/14/89 -@@ -37,8 +37,8 @@ - - - static FILE * --my_popen(const char * const cmd, -- const char * const mode, -+my_popen(const char * const cmd, -+ const char * const mode, - int * const pid) { - - FILE *retfile; -@@ -55,7 +55,7 @@ my_popen(const char * const cmd, - - if (pm_pipe(pipefd) < 0 ) - return NULL; -- -+ - /* Flush known files. */ - fflush(stdout); - fflush(stderr); -@@ -86,7 +86,7 @@ my_popen(const char * const cmd, - if ( execl("/bin/sh", "sh", "-c", cmd, NULL) < 0 ) - exit(127); - /* NOTREACHED */ -- } -+ } - - /* Close file descriptors, and gen up a FILE ptr */ - if ( *mode == 'r' ) -@@ -163,72 +163,14 @@ dealWithSubprocess(const char * const file_name, - FILE ** const fpP, - bool * const noSubprocessP, - const char ** const errorP) { -- --#ifdef NO_OPEN_PIPES - *noSubprocessP = TRUE; --#else -- const char *cp; -- -- reapChildren(catchingChildrenP, pids); -- -- /* Real file, not stdin or stdout. If name ends in ".Z", -- * pipe from/to un/compress (depending on r/w mode). -- * -- * If it starts with "|", popen that command. -- */ -- -- cp = file_name + strlen(file_name) - 2; -- /* Pipe case. */ -- if (file_name[0] == '|') { -- pid_t thepid; /* PID from my_popen */ -- -- *noSubprocessP = FALSE; -- -- *fpP = my_popen(file_name + 1, mode, &thepid); -- if (*fpP == NULL) -- *errorP = "%s: can't invoke <<%s>> for %s: "; -- else { -- /* One more child to catch, eventually. */ -- if (*catchingChildrenP < MAX_CHILDREN) -- pids[(*catchingChildrenP)++] = thepid; -- } -- } else if (cp > file_name && *cp == '.' && *(cp + 1) == 'Z' ) { -- /* Compress case. */ -- pid_t thepid; /* PID from my_popen. */ -- const char * command; -- -- *noSubprocessP = FALSE; -- -- if (*mode == 'w') -- pm_asprintf(&command, "compress > %s", file_name); -- else if (*mode == 'a') -- pm_asprintf(&command, "compress >> %s", file_name); -- else -- pm_asprintf(&command, "compress -d < %s", file_name); -- -- *fpP = my_popen(command, mode, &thepid); -- -- if (*fpP == NULL) -- *errorP = "%s: can't invoke 'compress' program, " -- "trying to open %s for %s"; -- else { -- /* One more child to catch, eventually. */ -- if (*catchingChildrenP < MAX_CHILDREN) -- pids[(*catchingChildrenP)++] = thepid; -- } -- pm_strfree(command); -- } else { -- *noSubprocessP = TRUE; -- *errorP = NULL; -- } --#endif - } - - - - --/* -- * Purpose : Open a file for input or output as controlled by the mode -+/* -+ * Purpose : Open a file for input or ouput as controlled by the mode - * parameter. If no file name is specified (ie. file_name is null) then - * a pointer to stdin or stdout will be returned. The calling routine may - * call this routine with a file name of "-". For this case rle_open_f -@@ -246,11 +188,11 @@ dealWithSubprocess(const char * const file_name, - * - * output: - * a file pointer -- * -+ * - */ - FILE * --rle_open_f_noexit(const char * const prog_name, -- const char * const file_name, -+rle_open_f_noexit(const char * const prog_name, -+ const char * const file_name, - const char * const mode ) { - - FILE * retval; -@@ -265,12 +207,12 @@ rle_open_f_noexit(const char * const prog_name, - fp = stdout; /* Set the default value */ - else - fp = stdin; -- -+ - if (file_name != NULL && !streq(file_name, "-")) { - bool noSubprocess; - dealWithSubprocess(file_name, mode, &catching_children, pids, - &fp, &noSubprocess, &err_str); -- -+ - if (!err_str) { - if (noSubprocess) { - /* Ordinary, boring file case. */ -@@ -286,7 +228,7 @@ rle_open_f_noexit(const char * const prog_name, - mode_string[0] = mode[0]; - mode_string[1] = 'b'; - strcpy( mode_string + 2, mode + 1 ); -- -+ - fp = fopen(file_name, mode_string); - if (fp == NULL ) - err_str = "%s: can't open %s for %s: "; -@@ -325,7 +267,7 @@ rle_open_f(const char * prog_name, const char * file_name, const char * mode) - - /***************************************************************** - * TAG( rle_close_f ) -- * -+ * - * Close a file opened by rle_open_f. If the file is stdin or stdout, - * it will not be closed. - * Inputs: -@@ -347,6 +289,3 @@ rle_close_f( fd ) - else - fclose( fd ); - } -- -- -- -diff --git a/urt/rle_putcom.c b/urt/rle_putcom.c -index ab2eb20..ce83615 100644 ---- a/urt/rle_putcom.c -+++ b/urt/rle_putcom.c +diff -ruNp a/urt/rle_putcom.c b/urt/rle_putcom.c +--- a/urt/rle_putcom.c 2021-06-02 15:53:59.824205554 +0200 ++++ b/urt/rle_putcom.c 2021-06-02 20:25:22.620707940 +0200 @@ -98,12 +98,14 @@ rle_putcom(const char * const value, const char * v; const char ** old_comments; @@ -8022,1615 +2945,72 @@ index ab2eb20..ce83615 100644 /* Not found */ /* Can't realloc because somebody else might be pointing to this * comments block. Of course, if this were true, then the -diff --git a/urt/scanargs.c b/urt/scanargs.c -index 1dcdd23..5e114bb 100644 ---- a/urt/scanargs.c -+++ b/urt/scanargs.c -@@ -1,24 +1,24 @@ --/* -+/* - * $Id: scanargs.c,v 3.0.1.3 1992/02/27 21:18:14 spencer Exp $ -- * Version 7 compatible -- * Argument scanner, scans argv style argument list. -- * -- * Some stuff is a kludge because sscanf screws up -- * -- * Gary Newman - 10/4/1979 - Ampex Corp. -- * -- * Modified by Spencer W. Thomas, Univ. of Utah, 5/81 to -- * add args introduced by a flag, add qscanargs call, -- * allow empty flags. -- * -- * If you make improvements we'd like to get them too. -- * Jay Lepreau lepreau@utah-20, decvax!harpo!utah-cs!lepreau -- * Spencer Thomas thomas@utah-20, decvax!harpo!utah-cs!thomas -- * -- * (I know the code is ugly, but it just grew, you see ...) -- * -- * Modified by: Spencer W. Thomas -- * Date: Feb 25 1983 -+ * Version 7 compatible -+ * Argument scanner, scans argv style argument list. -+ * -+ * Some stuff is a kludge because sscanf screws up -+ * -+ * Gary Newman - 10/4/1979 - Ampex Corp. -+ * -+ * Modified by Spencer W. Thomas, Univ. of Utah, 5/81 to -+ * add args introduced by a flag, add qscanargs call, -+ * allow empty flags. -+ * -+ * If you make improvements we'd like to get them too. -+ * Jay Lepreau lepreau@utah-20, decvax!harpo!utah-cs!lepreau -+ * Spencer Thomas thomas@utah-20, decvax!harpo!utah-cs!thomas -+ * -+ * (I know the code is ugly, but it just grew, you see ...) -+ * -+ * Modified by: Spencer W. Thomas -+ * Date: Feb 25 1983 - * 1. Fixed scanning of optional args. Now args introduced by a flag - * must follow the flag which introduces them and precede any other - * flag argument. It is still possible for a flag introduced -@@ -26,11 +26,11 @@ - * earlier in the format string. This implies that flags may not - * be conditional upon other flags, and a message will be generated - * if this is attempted. -- * -+ * - * 2. Usage message can be formatted by inserting newlines, tabs and - * spaces into the format string. This is especially useful for - * long argument lists. -- * -+ * - * 3. Added n/N types for "numeric" args. These args are scanned - * using the C language conventions - a number starting 0x is - * hexadecimal, a number starting with 0 is octal, otherwise it is -@@ -49,7 +49,7 @@ - #include "rle_config.h" - #include "rle.h" - --/* -+/* - * An explicit assumption is made in this code that all pointers look - * alike, except possible char * pointers. - */ -@@ -59,19 +59,18 @@ typedef int *ptr; - #define NO 0 - #define ERROR(msg) {fprintf(stderr, "%s\n", msg); goto error; } - --/* -+/* +diff -ruNp a/urt/Runput.c b/urt/Runput.c +--- a/urt/Runput.c 2021-06-02 15:53:59.825205563 +0200 ++++ b/urt/Runput.c 2021-06-02 20:23:21.834634475 +0200 +@@ -202,10 +202,11 @@ RunSetup(rle_hdr * the_hdr) + if ( the_hdr->background != 0 ) + { + register int i; +- register rle_pixel *background = +- (rle_pixel *)malloc( (unsigned)(the_hdr->ncolors + 1) ); +- register int *bg_color; +- /* ++ register rle_pixel *background; ++ register int *bg_color; ++ ++ overflow_add(the_hdr->ncolors,1); ++ background = (rle_pixel *)malloc( (unsigned)(the_hdr->ncolors + 1) ); /* + * If even number of bg color bytes, put out one more to get to + * 16 bit boundary. + */ +@@ -224,7 +225,7 @@ RunSetup(rle_hdr * the_hdr) + /* Big-endian machines are harder */ + register int i, nmap = (1 << the_hdr->cmaplen) * + the_hdr->ncmap; +- register char *h_cmap = (char *)malloc( nmap * 2 ); ++ register char *h_cmap = (char *)malloc2( nmap, 2 ); + if ( h_cmap == NULL ) + { + fprintf( stderr, +diff -ruNp a/urt/scanargs.c b/urt/scanargs.c +--- a/urt/scanargs.c 2021-06-02 15:53:59.825205563 +0200 ++++ b/urt/scanargs.c 2021-06-02 20:56:36.681068294 +0200 +@@ -62,8 +62,8 @@ typedef int *ptr; + /* * Storage allocation macros */ -#define NEW( type, cnt ) (type *) malloc( (cnt) * sizeof( type ) ) -#define RENEW( type, ptr, cnt ) (type *) realloc( ptr, (cnt) * sizeof( type ) ) -- -+#define NEW( type, cnt ) (type *) malloc2( (cnt) , sizeof( type ) ) -+#define RENEW( type, ptr, cnt ) (type *) realloc2( ptr, (cnt), sizeof( type ) ) ++#define NEW( type, cnt ) (type *) malloc2( (cnt), sizeof( type ) ) ++#define RENEW( type, ptr, cnt ) (type *) realloc2( ptr, (cnt), sizeof( type ) ) + static CONST_DECL char * prformat( CONST_DECL char *, int ); static int isnum( CONST_DECL char *, int, int ); --static int _do_scanargs( int argc, char **argv, CONST_DECL char *format, -- va_list argl ); --void scan_usage( char **, CONST_DECL char * ); -+static int _do_scanargs( int argc, char **argv, CONST_DECL char *format, -+ va_list argl ); -+void scan_usage( char **, CONST_DECL char * ); - --/* -+/* - * Argument list is (argc, argv, format, ... ) - */ - int -@@ -84,8 +83,8 @@ scanargs ( int argc, char **argv, CONST_DECL char *format, ... ) - va_end( argl ); - return retval; - } -- --/* -+ -+/* - * This routine is necessary because of a pyramid compiler botch that - * uses parameter registers in a varargs routine. The extra - * subroutine call isolates the args on the register stack so they -@@ -94,583 +93,583 @@ scanargs ( int argc, char **argv, CONST_DECL char *format, ... ) - - static int - _do_scanargs( argc, argv, format, argl ) --int argc; /* Actual arguments */ -+int argc; /* Actual arguments */ - char **argv; - CONST_DECL char *format; - va_list argl; - { - -- int check; /* check counter to be sure all argvs -- are processed */ -+ int check; /* check counter to be sure all argvs -+ are processed */ - register CONST_DECL char *cp; - int cnt; -- int optarg = 0; /* where optional args start */ -- int nopt = 0; -- char tmpflg, /* temp flag */ -- typchr; /* type char from format string */ -+ int optarg = 0; /* where optional args start */ -+ int nopt = 0; -+ char tmpflg, /* temp flag */ -+ typchr; /* type char from format string */ - char c; -- bool * arg_used; /* array of flags */ -- ptr aptr = 0; /* pointer to return loc */ -+ bool * arg_used; /* array of flags */ -+ ptr aptr = 0; /* pointer to return loc */ +@@ -114,7 +114,7 @@ va_list argl; bool required; -- int excnt; /* which flag is set */ + int excnt; /* which flag is set */ - unsigned int exflag; /* How many of a set of exclusive -- flags is set */ -- -- bool list_of; /* set if parsing off a list of args */ -- bool comma_list; /* set if AT&T style multiple args */ -- bool no_usage; /* If set, don't print usage msg. */ -- bool help = NO; /* If set, always print usage. */ -- int * cnt_arg = 0; /* where to stuff list count */ -- int list_cnt; /* how many in list */ -+ int excnt; /* which flag is set */ -+ bool exflag; /* when set, one of a set of exclusive -+ flags is set */ -+ -+ bool list_of; /* set if parsing off a list of args */ -+ bool comma_list; /* set if AT&T style multiple args */ -+ bool no_usage; /* If set, don't print usage msg. */ -+ bool help = NO; /* If set, always print usage. */ -+ int * cnt_arg = 0; /* where to stuff list count */ -+ int list_cnt; /* how many in list */ - /* These are used to build return lists */ - char ** strlist = 0; - int * intlist = 0; - long * longlist = 0; - float * fltlist = 0; - double *dbllist = 0; -- char * argp; /* Pointer to argument. */ -+ char * argp; /* Pointer to argument. */ ++ bool exflag; /* when set, one of a set of exclusive + flags is set */ -- CONST_DECL char *ncp; /* remember cp during flag scanning */ -- static char cntrl[7] = "% %1s"; /* control string for scanf's */ -- char junk[2]; /* junk buffer for scanf's */ -+ CONST_DECL char *ncp; /* remember cp during flag scanning */ -+ static char cntrl[7] = "% %1s"; /* control string for scanf's */ -+ char junk[2]; /* junk buffer for scanf's */ - - /* Set up for argument counting. */ - arg_used = NEW( bool, argc ); - if (arg_used == NULL) - { -- fprintf(stderr, "malloc failed in scanargs, exiting\n"); -- exit(-1); -+ fprintf(stderr, "malloc failed in scanargs, exiting\n"); -+ exit(-1); - } - else - { -- for (cnt=0; cnt 0 ) -- switch ( *(cp++) ) -- { -- case '(': depth++; break; -- case ')': depth--; break; -- } -- break; -- } -- -- case '!': /* required argument */ -- required = YES; -- case '%': /* not required argument */ --reswitch: /* after finding '*' or ',' */ -- switch (typchr = *(cp++)) -- { -- case ',': /* argument is AT&T list of things */ -- comma_list = YES; -- case '*': /* argument is list of things */ -- list_of = YES; -- list_cnt = 0; /* none yet */ -- cnt_arg = va_arg( argl, int *); /* item count * here */ -- goto reswitch; /* try again */ -- -- case '$': /* "rest" of argument list */ -- while ( argc > 1 && !arg_used[argc-1] ) -- argc--; /* find last used argument */ -- *va_arg( argl, int * ) = argc; -- break; -- -- case '&': /* Return unused args. */ -- /* Count how many. Always include argv[0]. */ -- for ( nopt = cnt = 1; cnt < argc; cnt++ ) -- if ( !arg_used[cnt] ) -- nopt++; -- if ( nopt == 1 ) -- nopt = 0; /* Special case for no args. */ -- if ( nopt > 0 ) -- { -- strlist = NEW( char *, nopt + 1 ); -- /* Copy program name, for sure. */ -- strlist[0] = argv[0]; -- for ( nopt = cnt = 1; cnt < argc; cnt++ ) -- if ( !arg_used[cnt] ) -- { -- strlist[nopt++] = argv[cnt]; -- check += cnt; -- arg_used[cnt] = 1; -- } -- strlist[nopt] = NULL; -- } -- else -- strlist = NULL; /* No args, return empty. */ -- -- /* Return count and arg list. */ -- *va_arg( argl, int * ) = nopt; -- *va_arg( argl, char *** ) = strlist; -- break; -- -- case '-': /* argument is flag */ -- if (optarg > 0) -- ERROR("Format error: flag conditional on flag not allowed"); -- -- /* go back to label */ -- ncp = cp-1; /* remember */ -- cp -= 3; + bool list_of; /* set if parsing off a list of args */ +@@ -258,7 +258,7 @@ reswitch: + /* go back to label */ + ncp = cp-1; /* remember */ + cp -= 3; - for (excnt = exflag = 0 -- ; *cp != ' ' && !(*cp=='-' &&(cp[-1]=='!'||cp[-1]=='%')); -- (--cp, excnt++)) -- { -- for (cnt = optarg+1; cnt < argc; cnt++) -- { -- /* flags all start with - */ -- if (*argv[cnt] == '-' && !arg_used[cnt] && -- !ISDIGIT(argv[cnt][1])) -- if (*(argv[cnt] + 1) == *cp) -- { -- if (*(argv[cnt] + 2) != 0) -- ERROR ("extra flags ignored"); -- if (exflag) -- ERROR ("more than one exclusive flag chosen"); ++ for (excnt = 0, exflag = NO + ; *cp != ' ' && !(*cp=='-' &&(cp[-1]=='!'||cp[-1]=='%')); + (--cp, excnt++)) + { +@@ -273,7 +273,7 @@ reswitch: + ERROR ("extra flags ignored"); + if (exflag) + ERROR ("more than one exclusive flag chosen"); - exflag++; -- required = NO; -- check += cnt; -- arg_used[cnt] = 1; -- nopt = cnt; -- *va_arg( argl, int *) |= (1 << excnt); -- break; -- } -- } -- } -- if (required) -- ERROR ("flag argument missing"); -- cp = ncp; -- /* -- * If none of these flags were found, skip any -- * optional arguments (in the varargs list, too). -- */ -- if (!exflag) -- { -- (void)va_arg( argl, int * );/* skip the arg, too */ -- while (*++cp && ! ISSPACE(*cp)) -- if (*cp == '!' || *cp == '%') -- { -- if ( *++cp == '*' || *cp == ',' ) -- { -- cp++; -- (void)va_arg( argl, int * ); -- } -- /* -- * Assume that char * might be a -- * different size, but that all -- * other pointers are same size. -- */ -- if ( *cp == 's' ) -- (void)va_arg( argl, char * ); -- else -- (void)va_arg( argl, ptr ); -- } -- } -- else -- { -- optarg = nopt; -- cp++; /* skip over - */ -- } -- -- break; -- -- case 's': /* char string */ -- case 'd': /* decimal # */ -- case 'o': /* octal # */ -- case 'x': /* hexadecimal # */ -- case 'n': /* "number" in C syntax */ -- case 'f': /* floating # */ -- case 'D': /* long decimal # */ -- case 'O': /* long octal # */ -- case 'X': /* long hexadecimal # */ -- case 'N': /* long number in C syntax */ -- case 'F': /* double precision floating # */ -+ required = NO; /* reset per-arg flags */ -+ list_of = NO; -+ comma_list = NO; -+ list_cnt = 0; -+ switch (*(cp++)) -+ { -+ default: /* all other chars */ -+ break; -+ case ' ': /* separators */ -+ case '\t': -+ case '\n': -+ optarg = 0; /* end of optional arg string */ -+ break; -+ -+ case '(': /* Surrounds a comment. */ -+ { -+ int depth = 1; /* Count parenthesis depth. */ -+ while ( *cp && depth > 0 ) -+ switch ( *(cp++) ) -+ { -+ case '(': depth++; break; -+ case ')': depth--; break; -+ } -+ break; -+ } -+ -+ case '!': /* required argument */ -+ required = YES; -+ case '%': /* not required argument */ -+reswitch: /* after finding '*' or ',' */ -+ switch (typchr = *(cp++)) -+ { -+ case ',': /* argument is AT&T list of things */ -+ comma_list = YES; -+ case '*': /* argument is list of things */ -+ list_of = YES; -+ list_cnt = 0; /* none yet */ -+ cnt_arg = va_arg( argl, int *); /* item count * here */ -+ goto reswitch; /* try again */ -+ -+ case '$': /* "rest" of argument list */ -+ while ( argc > 1 && !arg_used[argc-1] ) -+ argc--; /* find last used argument */ -+ *va_arg( argl, int * ) = argc; -+ break; -+ -+ case '&': /* Return unused args. */ -+ /* Count how many. Always include argv[0]. */ -+ for ( nopt = cnt = 1; cnt < argc; cnt++ ) -+ if ( !arg_used[cnt] ) -+ nopt++; -+ if ( nopt == 1 ) -+ nopt = 0; /* Special case for no args. */ -+ if ( nopt > 0 ) -+ { -+ strlist = NEW( char *, nopt + 1 ); -+ /* Copy program name, for sure. */ -+ strlist[0] = argv[0]; -+ for ( nopt = cnt = 1; cnt < argc; cnt++ ) -+ if ( !arg_used[cnt] ) -+ { -+ strlist[nopt++] = argv[cnt]; -+ check += cnt; -+ arg_used[cnt] = 1; -+ } -+ strlist[nopt] = NULL; -+ } -+ else -+ strlist = NULL; /* No args, return empty. */ -+ -+ /* Return count and arg list. */ -+ *va_arg( argl, int * ) = nopt; -+ *va_arg( argl, char *** ) = strlist; -+ break; -+ -+ case '-': /* argument is flag */ -+ if (optarg > 0) -+ ERROR("Format error: flag conditional on flag not allowed"); -+ -+ /* go back to label */ -+ ncp = cp-1; /* remember */ -+ cp -= 3; -+ for (excnt = exflag = 0 -+ ; *cp != ' ' && !(*cp=='-' &&(cp[-1]=='!'||cp[-1]=='%')); -+ (--cp, excnt++)) -+ { -+ for (cnt = optarg+1; cnt < argc; cnt++) -+ { -+ /* flags all start with - */ -+ if (*argv[cnt] == '-' && !arg_used[cnt] && -+ !ISDIGIT(argv[cnt][1])) -+ if (*(argv[cnt] + 1) == *cp) -+ { -+ if (*(argv[cnt] + 2) != 0) -+ ERROR ("extra flags ignored"); -+ if (exflag) -+ ERROR ("more than one exclusive flag chosen"); -+ exflag++; -+ required = NO; -+ check += cnt; -+ arg_used[cnt] = 1; -+ nopt = cnt; -+ *va_arg( argl, int *) |= (1 << excnt); -+ break; -+ } -+ } -+ } -+ if (required) -+ ERROR ("flag argument missing"); -+ cp = ncp; -+ /* -+ * If none of these flags were found, skip any -+ * optional arguments (in the varargs list, too). -+ */ -+ if (!exflag) -+ { -+ (void)va_arg( argl, int * );/* skip the arg, too */ -+ while (*++cp && ! ISSPACE(*cp)) -+ if (*cp == '!' || *cp == '%') -+ { -+ if ( *++cp == '*' || *cp == ',' ) -+ { -+ cp++; -+ (void)va_arg( argl, int * ); -+ } -+ /* -+ * Assume that char * might be a -+ * different size, but that all -+ * other pointers are same size. -+ */ -+ if ( *cp == 's' ) -+ (void)va_arg( argl, char * ); -+ else -+ (void)va_arg( argl, ptr ); -+ } -+ } -+ else -+ { -+ optarg = nopt; -+ cp++; /* skip over - */ -+ } -+ -+ break; -+ -+ case 's': /* char string */ -+ case 'd': /* decimal # */ -+ case 'o': /* octal # */ -+ case 'x': /* hexadecimal # */ -+ case 'n': /* "number" in C syntax */ -+ case 'f': /* floating # */ -+ case 'D': /* long decimal # */ -+ case 'O': /* long octal # */ -+ case 'X': /* long hexadecimal # */ -+ case 'N': /* long number in C syntax */ -+ case 'F': /* double precision floating # */ - #if defined(sgi) && !defined(mips) -- /* Fix for broken SGI IRIS 2400/3000 floats */ -- if ( typchr == 'F' ) typchr = 'f'; -+ /* Fix for broken SGI IRIS 2400/3000 floats */ -+ if ( typchr == 'F' ) typchr = 'f'; - #endif /* sgi */ -- for (cnt = optarg+1; cnt < argc; cnt++) -- { -- argp = argv[cnt]; -- -- if ( isnum( argp, typchr, comma_list ) ) -- { -- ; /* it's ok, then */ -- } -- else if ( *argp == '-' && argp[1] != '\0' ) -- if ( optarg > 0 ) /* end optional args? */ -- { -- /* Eat the arg, too, if necessary */ -- if ( list_cnt == 0 ) { -- if ( typchr == 's' ) -- (void)va_arg( argl, char * ); -- else -- (void)va_arg( argl, ptr ); -+ for (cnt = optarg+1; cnt < argc; cnt++) -+ { -+ argp = argv[cnt]; -+ -+ if ( isnum( argp, typchr, comma_list ) ) -+ { -+ ; /* it's ok, then */ -+ } -+ else if ( *argp == '-' && argp[1] != '\0' ) -+ if ( optarg > 0 ) /* end optional args? */ -+ { -+ /* Eat the arg, too, if necessary */ -+ if ( list_cnt == 0 ) { -+ if ( typchr == 's' ) -+ (void)va_arg( argl, char * ); -+ else -+ (void)va_arg( argl, ptr ); - } -- break; -- } -- else -- continue; -- else if ( typchr != 's' ) -- continue; /* not number, keep looking */ -- -- /* -- * Otherwise usable argument may already -- * be used. (Must check this after -- * checking for flag, though.) -- */ -- if (arg_used[cnt]) continue; -- -- /* -- * If it's a comma-and-or-space-separated -- * list then count how many, and separate -- * the list into an array of strings. -- */ -- if ( comma_list ) -- { -- register char * s; -- int pass; -- -- /* -- * Copy the string so we remain nondestructive -- */ -- s = NEW( char, strlen(argp)+1 ); -- strcpy( s, argp ); -- argp = s; -- -- /* -- * On pass 0, just count them. On -- * pass 1, null terminate each string -- */ -- for ( pass = 0; pass <= 1; pass++ ) -- { -- for ( s = argp; *s != '\0'; ) -- { -- if ( pass ) -- strlist[list_cnt] = s; -- while ( (c = *s) != '\0' && c != ' ' && -- c != '\t' && c != ',' ) -- s++; -- if ( pass ) -- *s = '\0'; -- -- list_cnt++; /* count separators */ -- /* -- * Two commas in a row give a null -- * string, but two spaces -- * don't. Also skip spaces -- * after a comma. -- */ -- if ( c != '\0' ) -- while ( *++s == ' ' || *s == '\t' ) -- ; -- } -- if ( pass == 0 ) -- { -- strlist = NEW( char *, list_cnt ); -- list_cnt = 0; -- } -- } -- } -- else if ( list_of ) -- list_cnt++; /* getting them one at a time */ -- /* -- * If it's either type of list, then alloc -- * storage space for the returned values -- * (except that comma-separated string -- * lists already are done). -- */ -- if ( list_of ) -- { -- if ( list_cnt == 1 || comma_list ) -- switch( typchr ) -- { -- case 's': -- if ( !comma_list ) -- strlist = NEW( char *, 1 ); -- aptr = (ptr) &strlist[0]; -- break; -- case 'n': -- case 'd': -- case 'o': -- case 'x': -- intlist = NEW( int, list_cnt ); -- aptr = (ptr) &intlist[0]; -- break; -- case 'N': -- case 'D': -- case 'O': -- case 'X': -- longlist = NEW( long, list_cnt ); -- aptr = (ptr) &longlist[0]; -- break; -- case 'f': -- fltlist = NEW( float, list_cnt ); -- aptr = (ptr) &fltlist[0]; -- break; -- case 'F': -- dbllist = NEW( double, list_cnt ); -- aptr = (ptr) &dbllist[0]; -- break; -- } -- else -- switch( typchr ) -- { -- case 's': -- strlist = RENEW( char *, strlist, -- list_cnt ); -- aptr = (ptr) &strlist[list_cnt-1]; -- break; -- case 'n': -- case 'd': -- case 'o': -- case 'x': -- intlist = RENEW( int, intlist, -- list_cnt ); -- aptr = (ptr) &intlist[list_cnt-1]; -- break; -- case 'N': -- case 'D': -- case 'O': -- case 'X': -- longlist = RENEW( long, longlist, -- list_cnt ); -- aptr = (ptr) &longlist[list_cnt-1]; -- break; -- case 'f': -- fltlist = RENEW( float, fltlist, -- list_cnt ); -- aptr = (ptr) &fltlist[list_cnt-1]; -- break; -- case 'F': -- dbllist = RENEW( double, dbllist, -- list_cnt ); -- aptr = (ptr) &dbllist[list_cnt-1]; -- break; -- } -- } -- else -- aptr = va_arg( argl, ptr ); -- -- if ( typchr == 's' ) -- { -- if ( ! comma_list ) -- *(char **)aptr = argp; -- } -- else -- { -- nopt = 0; -- do { -- /* -- * Need to update aptr if parsing -- * a comma list -- */ -- if ( comma_list && nopt > 0 ) -- { -- argp = strlist[nopt]; -- switch( typchr ) -- { -- case 'n': -- case 'd': -- case 'o': -- case 'x': -- aptr = (ptr) &intlist[nopt]; -- break; -- case 'N': -- case 'D': -- case 'O': -- case 'X': -- aptr = (ptr) &longlist[nopt]; -- break; -- case 'f': -- aptr = (ptr) &fltlist[nopt]; -- break; -- case 'F': -- aptr = (ptr) &dbllist[nopt]; -- break; -- } -- } -- /* -- * Do conversion for n and N types -- */ -- tmpflg = typchr; -- if (typchr == 'n' || typchr == 'N' ) { -- if (*argp != '0') -- tmpflg = 'd'; -- else if (*(argp+1) == 'x' || -- *(argp+1) == 'X') -- { -- tmpflg = 'x'; -- argp += 2; -- } -- else -- tmpflg = 'o'; -+ break; -+ } -+ else -+ continue; -+ else if ( typchr != 's' ) -+ continue; /* not number, keep looking */ -+ -+ /* -+ * Otherwise usable argument may already -+ * be used. (Must check this after -+ * checking for flag, though.) -+ */ -+ if (arg_used[cnt]) continue; -+ -+ /* -+ * If it's a comma-and-or-space-separated -+ * list then count how many, and separate -+ * the list into an array of strings. -+ */ -+ if ( comma_list ) -+ { -+ register char * s; -+ int pass; -+ -+ /* -+ * Copy the string so we remain nondestructive -+ */ -+ s = NEW( char, strlen(argp)+1 ); -+ strcpy( s, argp ); -+ argp = s; -+ -+ /* -+ * On pass 0, just count them. On -+ * pass 1, null terminate each string -+ */ -+ for ( pass = 0; pass <= 1; pass++ ) -+ { -+ for ( s = argp; *s != '\0'; ) -+ { -+ if ( pass ) -+ strlist[list_cnt] = s; -+ while ( (c = *s) != '\0' && c != ' ' && -+ c != '\t' && c != ',' ) -+ s++; -+ if ( pass ) -+ *s = '\0'; -+ -+ list_cnt++; /* count separators */ -+ /* -+ * Two commas in a row give a null -+ * string, but two spaces -+ * don't. Also skip spaces -+ * after a comma. -+ */ -+ if ( c != '\0' ) -+ while ( *++s == ' ' || *s == '\t' ) -+ ; -+ } -+ if ( pass == 0 ) -+ { -+ strlist = NEW( char *, list_cnt ); -+ list_cnt = 0; -+ } -+ } -+ } -+ else if ( list_of ) -+ list_cnt++; /* getting them one at a time */ -+ /* -+ * If it's either type of list, then alloc -+ * storage space for the returned values -+ * (except that comma-separated string -+ * lists already are done). -+ */ -+ if ( list_of ) -+ { -+ if ( list_cnt == 1 || comma_list ) -+ switch( typchr ) -+ { -+ case 's': -+ if ( !comma_list ) -+ strlist = NEW( char *, 1 ); -+ aptr = (ptr) &strlist[0]; -+ break; -+ case 'n': -+ case 'd': -+ case 'o': -+ case 'x': -+ intlist = NEW( int, list_cnt ); -+ aptr = (ptr) &intlist[0]; -+ break; -+ case 'N': -+ case 'D': -+ case 'O': -+ case 'X': -+ longlist = NEW( long, list_cnt ); -+ aptr = (ptr) &longlist[0]; -+ break; -+ case 'f': -+ fltlist = NEW( float, list_cnt ); -+ aptr = (ptr) &fltlist[0]; -+ break; -+ case 'F': -+ dbllist = NEW( double, list_cnt ); -+ aptr = (ptr) &dbllist[0]; -+ break; -+ } -+ else -+ switch( typchr ) -+ { -+ case 's': -+ strlist = RENEW( char *, strlist, -+ list_cnt ); -+ aptr = (ptr) &strlist[list_cnt-1]; -+ break; -+ case 'n': -+ case 'd': -+ case 'o': -+ case 'x': -+ intlist = RENEW( int, intlist, -+ list_cnt ); -+ aptr = (ptr) &intlist[list_cnt-1]; -+ break; -+ case 'N': -+ case 'D': -+ case 'O': -+ case 'X': -+ longlist = RENEW( long, longlist, -+ list_cnt ); -+ aptr = (ptr) &longlist[list_cnt-1]; -+ break; -+ case 'f': -+ fltlist = RENEW( float, fltlist, -+ list_cnt ); -+ aptr = (ptr) &fltlist[list_cnt-1]; -+ break; -+ case 'F': -+ dbllist = RENEW( double, dbllist, -+ list_cnt ); -+ aptr = (ptr) &dbllist[list_cnt-1]; -+ break; -+ } -+ } -+ else -+ aptr = va_arg( argl, ptr ); -+ -+ if ( typchr == 's' ) -+ { -+ if ( ! comma_list ) -+ *(char **)aptr = argp; -+ } -+ else -+ { -+ nopt = 0; -+ do { -+ /* -+ * Need to update aptr if parsing -+ * a comma list -+ */ -+ if ( comma_list && nopt > 0 ) -+ { -+ argp = strlist[nopt]; -+ switch( typchr ) -+ { -+ case 'n': -+ case 'd': -+ case 'o': -+ case 'x': -+ aptr = (ptr) &intlist[nopt]; -+ break; -+ case 'N': -+ case 'D': -+ case 'O': -+ case 'X': -+ aptr = (ptr) &longlist[nopt]; -+ break; -+ case 'f': -+ aptr = (ptr) &fltlist[nopt]; -+ break; -+ case 'F': -+ aptr = (ptr) &dbllist[nopt]; -+ break; -+ } -+ } -+ /* -+ * Do conversion for n and N types -+ */ -+ tmpflg = typchr; -+ if (typchr == 'n' || typchr == 'N' ) { -+ if (*argp != '0') -+ tmpflg = 'd'; -+ else if (*(argp+1) == 'x' || -+ *(argp+1) == 'X') -+ { -+ tmpflg = 'x'; -+ argp += 2; -+ } -+ else -+ tmpflg = 'o'; - } -- if (typchr == 'N') -- tmpflg = toupper( tmpflg ); -- -- -- /* put in conversion */ -- if ( isupper( tmpflg ) ) -- { -- cntrl[1] = 'l'; -- cntrl[2] = tolower( tmpflg ); -- } -- else -- { -- cntrl[1] = tmpflg; -- cntrl[2] = ' '; -- } -- if (sscanf (argp, cntrl, aptr, junk) != 1) -- ERROR ("Bad numeric argument"); -- } while ( comma_list && ++nopt < list_cnt ); -- } -- check += cnt; -- arg_used[cnt] = 1; -- required = NO; -- /* -- * If not looking for multiple args, -- * then done, otherwise, keep looking. -- */ -- if ( !( list_of && !comma_list ) ) -- break; -- else -- continue; -- } -- if (required) -- switch (typchr) -- { -- case 'x': -- case 'X': -- ERROR ("missing hexadecimal argument"); -- case 's': -- ERROR ("missing string argument"); -- case 'o': -- case 'O': -- ERROR ("missing octal argument"); -- case 'd': -- case 'D': -- ERROR ("missing decimal argument"); -- case 'f': -- case 'F': -- ERROR ("missing floating argument"); -- case 'n': -- case 'N': -- ERROR ("missing numeric argument"); -- } -- if ( list_cnt > 0 ) -- { -- *cnt_arg = list_cnt; -- switch ( typchr ) -- { -- case 's': -- *va_arg( argl, char *** ) = strlist; -- break; -- case 'n': -- case 'd': -- case 'o': -- case 'x': -- *va_arg( argl, int ** ) = intlist; -- break; -- case 'N': -- case 'D': -- case 'O': -- case 'X': -- *va_arg( argl, long ** ) = longlist; -- break; -- case 'f': -- *va_arg( argl, float ** ) = fltlist; -- break; -- case 'F': -- *va_arg( argl, double **) = dbllist; -- break; -- } -- if ( typchr != 's' && comma_list ) -- free( (char *) strlist ); -- } -- else if ( cnt >= argc ) -- { -- /* Fell off end looking, so must eat the arg */ -- if ( typchr == 's' ) -- (void)va_arg( argl, char * ); -- else -- (void)va_arg( argl, ptr ); -- } -- break; -- default: /* error */ -- fprintf (stderr, -- "scanargs: Corrupt or invalid format spec\n"); -- return 0; -- } -- } -+ if (typchr == 'N') -+ tmpflg = toupper( tmpflg ); -+ -+ -+ /* put in conversion */ -+ if ( isupper( tmpflg ) ) -+ { -+ cntrl[1] = 'l'; -+ cntrl[2] = tolower( tmpflg ); -+ } -+ else -+ { -+ cntrl[1] = tmpflg; -+ cntrl[2] = ' '; -+ } -+ if (sscanf (argp, cntrl, aptr, junk) != 1) -+ ERROR ("Bad numeric argument"); -+ } while ( comma_list && ++nopt < list_cnt ); -+ } -+ check += cnt; -+ arg_used[cnt] = 1; -+ required = NO; -+ /* -+ * If not looking for multiple args, -+ * then done, otherwise, keep looking. -+ */ -+ if ( !( list_of && !comma_list ) ) -+ break; -+ else -+ continue; -+ } -+ if (required) -+ switch (typchr) -+ { -+ case 'x': -+ case 'X': -+ ERROR ("missing hexadecimal argument"); -+ case 's': -+ ERROR ("missing string argument"); -+ case 'o': -+ case 'O': -+ ERROR ("missing octal argument"); -+ case 'd': -+ case 'D': -+ ERROR ("missing decimal argument"); -+ case 'f': -+ case 'F': -+ ERROR ("missing floating argument"); -+ case 'n': -+ case 'N': -+ ERROR ("missing numeric argument"); -+ } -+ if ( list_cnt > 0 ) -+ { -+ *cnt_arg = list_cnt; -+ switch ( typchr ) -+ { -+ case 's': -+ *va_arg( argl, char *** ) = strlist; -+ break; -+ case 'n': -+ case 'd': -+ case 'o': -+ case 'x': -+ *va_arg( argl, int ** ) = intlist; -+ break; -+ case 'N': -+ case 'D': -+ case 'O': -+ case 'X': -+ *va_arg( argl, long ** ) = longlist; -+ break; -+ case 'f': -+ *va_arg( argl, float ** ) = fltlist; -+ break; -+ case 'F': -+ *va_arg( argl, double **) = dbllist; -+ break; -+ } -+ if ( typchr != 's' && comma_list ) -+ free( (char *) strlist ); -+ } -+ else if ( cnt >= argc ) -+ { -+ /* Fell off end looking, so must eat the arg */ -+ if ( typchr == 's' ) -+ (void)va_arg( argl, char * ); -+ else -+ (void)va_arg( argl, ptr ); -+ } -+ break; -+ default: /* error */ -+ fprintf (stderr, -+ "scanargs: Corrupt or invalid format spec\n"); -+ return 0; -+ } -+ } - } - - /* Count up empty flags */ - for (cnt=1; cnt argv[0] && *cp != '/'; cp-- ) -- ; /* find the last / */ -- if ( *cp == '/' ) -- cp++; -- fprintf( stderr, "%s", cp ); -- -- cp = format + 1; /* reset to where it should be */ -- } -- while (putc (*cp++, stderr) != ' '); -+ if ( *cp == '%' ) -+ { -+ /* -+ * This is bogus, but until everyone can agree on a name -+ * for (rindex/strrchr) .... -+ */ -+ for ( cp = argv[0]; *cp != '\0'; cp++ ) -+ ; /* find the end of the string */ -+ for ( ; cp > argv[0] && *cp != '/'; cp-- ) -+ ; /* find the last / */ -+ if ( *cp == '/' ) -+ cp++; -+ fprintf( stderr, "%s", cp ); -+ -+ cp = format + 1; /* reset to where it should be */ -+ } -+ while (putc (*cp++, stderr) != ' '); - } - else -- fprintf (stderr, "?? "); -+ fprintf (stderr, "?? "); - while (*cp == ' ') -- cp++; -+ cp++; - (void)prformat (cp, NO); - } - - static CONST_DECL char * - prformat (format, recurse) - CONST_DECL char *format; --int recurse; -+int recurse; - { - register CONST_DECL char *cp; - bool required, comma_list; -@@ -721,142 +720,142 @@ int recurse; - - cp = format; - if (recurse) -- putc (' ', stderr); -+ putc (' ', stderr); - - required = NO; - list_of = 0; - comma_list = NO; - while (*cp) - { -- switch (*cp) -- { -- default: -- cp++; -- break; -- case ' ': -- case '\n': -- case '\t': -- /* allow annotations */ -- for ( ; format < cp; format++ ) -- putc( *format, stderr ); -- putc(*cp, stderr); -- format = ++cp; -- break; -- -- case '(': -- /* Parentheses surround an arbitrary (parenthesis -- * balanced) comment. -- */ -- for ( ; format < cp; format++ ) -- putc( *format, stderr ); -- for ( cp++, depth = 1; *cp && depth > 0; ) -- { -- /* Don't print last close paren. */ -- if ( *cp != ')' || depth > 1 ) -- putc( *cp, stderr ); -- switch( *(cp++) ) -- { -- case '(': depth++; break; -- case ')': depth--; break; -- } -- } -- format = cp; -- break; -- -- case '!': -- required = YES; -- case '%': -+ switch (*cp) -+ { -+ default: -+ cp++; -+ break; -+ case ' ': -+ case '\n': -+ case '\t': -+ /* allow annotations */ -+ for ( ; format < cp; format++ ) -+ putc( *format, stderr ); -+ putc(*cp, stderr); -+ format = ++cp; -+ break; -+ -+ case '(': -+ /* Parentheses surround an arbitrary (parenthesis -+ * balanced) comment. -+ */ -+ for ( ; format < cp; format++ ) -+ putc( *format, stderr ); -+ for ( cp++, depth = 1; *cp && depth > 0; ) -+ { -+ /* Don't print last close paren. */ -+ if ( *cp != ')' || depth > 1 ) -+ putc( *cp, stderr ); -+ switch( *(cp++) ) -+ { -+ case '(': depth++; break; -+ case ')': depth--; break; -+ } -+ } -+ format = cp; -+ break; -+ -+ case '!': -+ required = YES; -+ case '%': - reswitch: -- switch (*++cp) -- { -- case ',': -- comma_list = YES; -- case '*': -- list_of++; -- goto reswitch; -- -- case '$': /* "rest" of argument list */ -- if (!required) -- putc ('[', stderr); -- for (; format < cp - 1 - list_of; format++) -- putc (*format, stderr); -- fputs( " ...", stderr ); -- if ( !required ) -- putc( ']', stderr ); -- break; -- -- case '-': /* flags */ -- if (!required) -- putc ('[', stderr); -- putc ('-', stderr); -- -- if (cp - format > 2 + list_of) -- putc ('{', stderr); -- cp = format; -- while (*cp != '%' && *cp != '!') -- putc (*cp++, stderr); -- if (cp - format > 1 + list_of) -- putc ('}', stderr); -- cp += 2; /* skip !- or %- */ -- if (*cp && !ISSPACE(*cp)) -- cp = prformat (cp, YES); -- /* this is a recursive call */ -- -- cp--; /* don't ignore next character */ -- -- if (!required) -- putc (']', stderr); -- break; -- case 's': /* char string */ -- case 'd': /* decimal # */ -- case 'o': /* octal # */ -- case 'x': /* hexadecimal # */ -- case 'f': /* floating # */ -- case 'D': /* long decimal # */ -- case 'O': /* long octal # */ -- case 'X': /* long hexadecimal # */ -- case 'F': /* double precision floating # */ -- case 'n': /* numeric arg (C format) */ -- case 'N': /* long numeric arg */ -- if (!required) -- putc ('[', stderr); -- for (; format < cp - 1 - list_of; format++) -- putc (*format, stderr); -- if ( list_of != 0 ) -- { -- if ( comma_list ) -- putc( ',', stderr ); -- else -- putc( ' ', stderr ); -- fputs( "...", stderr ); -- } -- if (!required) -- putc (']', stderr); -- break; -- default: -- break; -- } -- required = NO; -- list_of = NO; -- comma_list = NO; -- if (*cp) /* check for end of string */ -- format = ++cp; -- if (*cp && !ISSPACE(*cp)) -- putc (' ', stderr); -- } -- if (recurse && ISSPACE(*cp)) -- break; -+ switch (*++cp) -+ { -+ case ',': -+ comma_list++; -+ case '*': -+ list_of++; -+ goto reswitch; -+ -+ case '$': /* "rest" of argument list */ -+ if (!required) -+ putc ('[', stderr); -+ for (; format < cp - 1 - list_of; format++) -+ putc (*format, stderr); -+ fputs( " ...", stderr ); -+ if ( !required ) -+ putc( ']', stderr ); -+ break; -+ -+ case '-': /* flags */ -+ if (!required) -+ putc ('[', stderr); -+ putc ('-', stderr); -+ -+ if (cp - format > 2 + list_of) -+ putc ('{', stderr); -+ cp = format; -+ while (*cp != '%' && *cp != '!') -+ putc (*cp++, stderr); -+ if (cp - format > 1 + list_of) -+ putc ('}', stderr); -+ cp += 2; /* skip !- or %- */ -+ if (*cp && !ISSPACE(*cp)) -+ cp = prformat (cp, YES); -+ /* this is a recursive call */ -+ -+ cp--; /* don't ignore next character */ -+ -+ if (!required) -+ putc (']', stderr); -+ break; -+ case 's': /* char string */ -+ case 'd': /* decimal # */ -+ case 'o': /* octal # */ -+ case 'x': /* hexadecimal # */ -+ case 'f': /* floating # */ -+ case 'D': /* long decimal # */ -+ case 'O': /* long octal # */ -+ case 'X': /* long hexadecimal # */ -+ case 'F': /* double precision floating # */ -+ case 'n': /* numeric arg (C format) */ -+ case 'N': /* long numeric arg */ -+ if (!required) -+ putc ('[', stderr); -+ for (; format < cp - 1 - list_of; format++) -+ putc (*format, stderr); -+ if ( list_of != 0 ) -+ { -+ if ( comma_list ) -+ putc( ',', stderr ); -+ else -+ putc( ' ', stderr ); -+ fputs( "...", stderr ); -+ } -+ if (!required) -+ putc (']', stderr); -+ break; -+ default: -+ break; -+ } -+ required = NO; -+ list_of = NO; -+ comma_list = NO; -+ if (*cp) /* check for end of string */ -+ format = ++cp; -+ if (*cp && !ISSPACE(*cp)) -+ putc (' ', stderr); -+ } -+ if (recurse && ISSPACE(*cp)) -+ break; - } - if (!recurse) - { -- for ( ; format < cp; format++ ) -- putc( *format, stderr ); -- putc ('\n', stderr); -+ for ( ; format < cp; format++ ) -+ putc( *format, stderr ); -+ putc ('\n', stderr); - } - return (cp); - } - --/* -+/* - * isnum - determine whether a string MIGHT represent a number. - * typchr indicates the type of argument we are looking for, and - * determines the legal character set. If comma_list is YES, then -@@ -873,46 +872,46 @@ int comma_list; - - switch( typchr ) - { -- case 'n': -- case 'N': -- allowed = " \t,+-x0123456789abcdefABCDEF"; -- break; -- case 'd': -- case 'D': -- allowed = " \t,+-0123456789"; -- break; -- case 'o': -- case 'O': -- allowed = " \t,01234567"; -- break; -- case 'x': -- case 'X': -- allowed = " \t,0123456789abcdefABCDEF"; -- break; -- case 'f': -- case 'F': -- allowed = " \t,+-eE.0123456789"; -- break; -- case 's': /* only throw out decimal numbers */ -- default: -- allowed = " \t,+-.0123456789"; -- break; -+ case 'n': -+ case 'N': -+ allowed = " \t,+-x0123456789abcdefABCDEF"; -+ break; -+ case 'd': -+ case 'D': -+ allowed = " \t,+-0123456789"; -+ break; -+ case 'o': -+ case 'O': -+ allowed = " \t,01234567"; -+ break; -+ case 'x': -+ case 'X': -+ allowed = " \t,0123456789abcdefABCDEF"; -+ break; -+ case 'f': -+ case 'F': -+ allowed = " \t,+-eE.0123456789"; -+ break; -+ case 's': /* only throw out decimal numbers */ -+ default: -+ allowed = " \t,+-.0123456789"; -+ break; - } - digits = allowed; - while ( *digits != '0' ) -- digits++; -+ digits++; - if ( ! comma_list ) -- allowed += 3; /* then don't allow space, tab, comma */ -+ allowed += 3; /* then don't allow space, tab, comma */ - - while ( *str != '\0' ) - { -- for ( cp = allowed; *cp != '\0' && *cp != *str; cp++ ) -- ; -- if ( *cp == '\0' ) -- return NO; /* if not in allowed chars, not number */ -- if ( cp - digits >= 0 ) -- hasdigit = YES; -- str++; -+ for ( cp = allowed; *cp != '\0' && *cp != *str; cp++ ) -+ ; -+ if ( *cp == '\0' ) -+ return NO; /* if not in allowed chars, not number */ -+ if ( cp - digits >= 0 ) -+ hasdigit = YES; -+ str++; - } - return hasdigit; - } ++ exflag = YES; + required = NO; + check += cnt; + arg_used[cnt] = 1; diff --git a/netpbm-userguide.patch b/netpbm-userguide.patch deleted file mode 100644 index c160e13..0000000 --- a/netpbm-userguide.patch +++ /dev/null @@ -1,150 +0,0 @@ -diff --git a/userguide/pammixmulti.html b/userguide/pammixmulti.html -index 97cf412..d2a2ba0 100755 ---- a/userguide/pammixmulti.html -+++ b/userguide/pammixmulti.html -@@ -2,13 +2,13 @@ - Pammixmulti User Manual - -

    pammixmulti

    --Updated: 18 November 2018
    --
    -+ -+Updated: 18 November 2018
    - Table Of Contents - - --

    NAME

    --

    pammixmulti - blend together multiple PAM images -+

    NAME

    -+

    pammixmulti - blend together multiple PAM images

    - - -

    SYNOPSIS

    -@@ -22,11 +22,11 @@ Updated: 18 November 2018
    -

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

    - - -

    DESCRIPTION

    --

    This file is part of Netpbm. -+

    This file is part of Netpbm.

    - -

    pammixmulti mixes two or more images to produce a new image. The - program provides multiple ways to interpret "mix." -@@ -37,7 +37,7 @@ program provides multiple ways to interpret "mix." -

    In addition to the options common to all programs based on libnetpbm - (most notably -quiet, see - Common Options), pammixmulti recognizes the following --command line options: -+command line options:

    - -
    -
    --blend=average|random|mask
    -@@ -50,7 +50,7 @@ output is produced by selecting the corresponding pixel from one of the input - images, chosen at random on a per-pixel basis. With - --blend=mask, each pixel in the output is produced by a - weighted average of the corresponding pixels from all the input images based --on the grayscale level of an additional mask image. -+on the grayscale level of an additional mask image.

    - - -
    --maskfile=filename
    -@@ -60,7 +60,7 @@ grayscale mask file to control the blending of each pixel. (If the file is - not grayscale, the first channel is treated as gray). Where the mask file is - black, the first image is selected. Where the mask file is white, the last - image is selected. Intermediate levels of gray select intermediate --images. -+images.

    - - -
    --stdev=number
    -@@ -77,7 +77,7 @@ that includes roughly equal amounts of the corresponding pixel from images 1 - and 2 but less of the corresponding pixel from image 3. As number - tends towards the number of input images (going beyond that has diminishing - impact), the output tends to look more --like --blend=average. number defaults to 0.25. -+like --blend=average. number defaults to 0.25.

    - - -
    --randomseed integer -@@ -91,39 +91,39 @@ like --blend=average. number defaults to 0.25. - -

    ARGUMENTS

    - --

    You supply the names of the files to mix as non-option arguments. -+

    You supply the names of the files to mix as non-option arguments.

    - - -

    EXAMPLES

    - --

    Average a bunch of PPM images to produce a new PAM image: -+

    Average a bunch of PPM images to produce a new PAM image:

    -
    
    -     pammixmulti input*.ppm >output.ppm
    - 
    - -

    Mix these same images by taking each pixel from a randomly selected input --image: -+image:

    - -
    
    -     pammixmulti --blend=random input*.ppm >output.ppm
    - 
    - -

    Use a mask image to control the fading among input images on a --pixel-by-pixel basis: -+pixel-by-pixel basis:

    - -
    
    -     pammixmulti --blend=mask --maskfile=mask.pgm >output.pam \
    -        one.pam two.pam three.pam four.pam
    - 
    - --

    Do the same but with more abrupt transitions: -+

    Do the same but with more abrupt transitions:

    - -
    
    -     pammixmulti --blend=mask --maskfile=mask.pgm --stdev=0.0 >output.pam \
    -        one.pam two.pam three.pam four.pam
    - 
    - --

    and now with more gradual transitions: -+

    and now with more gradual transitions:

    - -
    
    -     pammixmulti --blend=mask --maskfile=mask.pgm --stdev=1.0 >output.pam \
    -@@ -138,7 +138,7 @@ pixel-by-pixel basis:
    - 
    - 

    AUTHOR

    - --

    Copyright 2018 Scott Pakin, scott+pbm@pakin.org. -+

    Copyright 2018 Scott Pakin, scott+pbm@pakin.org.

    - -

    SEE ALSO

    - -@@ -152,14 +152,14 @@ pixel-by-pixel basis: -

    Table Of Contents

    - - - - diff --git a/netpbm.spec b/netpbm.spec index 29c2043..a802506 100644 --- a/netpbm.spec +++ b/netpbm.spec @@ -1,7 +1,7 @@ Summary: A library for handling different graphics file formats Name: netpbm -Version: 10.93.00 -Release: 2%{?dist} +Version: 10.94.05 +Release: 1%{?dist} # See copyright_summary for details License: BSD and GPLv2 and IJG and MIT and Public Domain URL: http://netpbm.sourceforge.net/ @@ -27,10 +27,8 @@ Patch12: netpbm-docfix.patch Patch13: netpbm-cmuwtopbm.patch Patch14: netpbm-pamtojpeg2k.patch Patch15: netpbm-manfix.patch -Patch16: netpbm-manual-pages.patch -Patch17: netpbm-jasper.patch -Patch18: netpbm-userguide.patch -Patch19: netpbm-libdir-so.patch +Patch16: netpbm-jasper.patch +Patch17: netpbm-libdir-so.patch BuildRequires: make BuildRequires: libjpeg-devel, libpng-devel, libtiff-devel, flex, gcc, jbigkit-devel @@ -230,8 +228,8 @@ popd %doc userguide/* %changelog -* Fri Apr 16 2021 Mohan Boddu - 10.93.00-2 -- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 +* Thu Jun 03 2021 Josef Ridky - 10.94.05-1 +- Rebase to the new upstream release 10.94.05 (#1967407) * Mon Jan 25 2021 Josef Ridky - 10.93.00-1 - New upstream release 10.93.00 (#1911159) diff --git a/sources b/sources index d5383d7..91750b7 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (netpbm-10.93.00.tar.xz) = 18ff08b1d3672d792dab78b69eb4ef1a9874266b1dfbf5801a53ca172c0dcbbae8d1269297a56e06ed45ccfdff6a6ae5399e60b4bafdcb9d2cb9de800e2bc07c +SHA512 (netpbm-10.94.05.tar.xz) = 58e6cd2e77dddaa99e439380a1db9057f357204074d528d82ad3af5beaa31bdc0e36abe9bc4a8aded5befdc228bca2f96e7c5a103882ce04d144eead398b45b2