about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--GNUmakefile29
-rw-r--r--Makefile.srcdir1
-rw-r--r--Makefile.version4
-rw-r--r--analyzer/Makefile4
-rw-r--r--buildtools/Makefile4
-rwxr-xr-xbuildtools/configure.pl287
-rwxr-xr-xbuildtools/installosf2
-rw-r--r--buildtools/manpage.mk (renamed from buildtools/Makefile.manpage)2
-rw-r--r--common.mk (renamed from Makefile.common)29
-rw-r--r--config.mk.in (renamed from Makefile.config.in)6
-rw-r--r--converter/Makefile4
-rw-r--r--converter/other/Makefile4
-rw-r--r--converter/other/cameratopam/Makefile4
-rw-r--r--converter/other/dithers.h91
-rw-r--r--converter/other/fiasco/Makefile4
-rw-r--r--converter/other/fiasco/codec/Makefile4
-rw-r--r--converter/other/fiasco/input/Makefile4
-rw-r--r--converter/other/fiasco/lib/Makefile4
-rw-r--r--converter/other/fiasco/output/Makefile4
-rw-r--r--converter/other/fitstopnm.c13
-rw-r--r--converter/other/jbig/Makefile4
-rw-r--r--converter/other/jpeg2000/Makefile4
-rw-r--r--converter/other/jpeg2000/libjasper/Makefile4
-rw-r--r--converter/other/jpeg2000/libjasper/base/Makefile4
-rw-r--r--converter/other/jpeg2000/libjasper/common.mk (renamed from converter/other/jpeg2000/libjasper/Makefile.common)3
-rw-r--r--converter/other/jpeg2000/libjasper/jp2/Makefile4
-rw-r--r--converter/other/jpeg2000/libjasper/jpc/Makefile4
-rw-r--r--converter/other/pamtofits.c14
-rw-r--r--converter/other/pamtosvg/Makefile4
-rw-r--r--converter/other/pgmtopbm.c44
-rw-r--r--converter/other/pnmtoddif.c264
-rw-r--r--converter/other/pnmtojpeg.c141
-rw-r--r--converter/other/pnmtopalm/Makefile4
-rw-r--r--converter/other/pnmtorle.c200
-rw-r--r--converter/other/svgtopam.c12
-rw-r--r--converter/pbm/Makefile4
-rw-r--r--converter/pbm/g3topbm.c4
-rw-r--r--converter/pbm/pbmtoppa/Makefile4
-rw-r--r--converter/pgm/Makefile4
-rw-r--r--converter/ppm/Makefile4
-rw-r--r--converter/ppm/hpcdtoppm/Makefile4
-rw-r--r--converter/ppm/ppmtobmp.c509
-rw-r--r--converter/ppm/ppmtoleaf.c259
-rw-r--r--converter/ppm/ppmtompeg/Makefile4
-rw-r--r--converter/ppm/ppmtompeg/file.c351
-rw-r--r--converter/ppm/ppmtompeg/huff.h34
-rw-r--r--converter/ppm/ppmtopjxl.c570
-rw-r--r--doc/HISTORY40
-rw-r--r--doc/INSTALL27
-rw-r--r--doc/README.CYGWIN2
-rw-r--r--doc/README.DJGPP65
-rw-r--r--doc/USERDOC2
-rw-r--r--editor/Makefile4
-rw-r--r--editor/pamditherbw.c77
-rw-r--r--generator/Makefile4
-rw-r--r--generator/pgmnoise.c134
-rw-r--r--lib/Makefile8
-rw-r--r--lib/dithers.h (renamed from editor/dithers.h)3
-rw-r--r--lib/ppmcmap.h8
-rw-r--r--lib/util/Makefile6
-rw-r--r--lib/util/mallocvar.h2
-rw-r--r--other/Makefile4
-rw-r--r--other/pamx/Makefile4
-rw-r--r--srcdir.mk14
-rw-r--r--urt/Makefile4
-rw-r--r--version.mk4
66 files changed, 1776 insertions, 1601 deletions
diff --git a/GNUmakefile b/GNUmakefile
index bb9db4fe..4b01cec2 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -1,6 +1,6 @@
 # Makefile for Netpbm
  
-# Configuration should normally be done in the included file Makefile.config.
+# Configuration should normally be done in the included file config.mk.
 
 # Targets in this file:
 #
@@ -9,7 +9,7 @@
 #   package:      Make a package of Netpbm files ready to install
 #   
 #   The default target is either "merge" or "nonmerge", as determined by
-#   the DEFAULT_TARGET variable set by Makefile.config.
+#   the DEFAULT_TARGET variable set by config.mk.
 
 # About the "merge" target: Normally the Makefiles build separate
 # executables for each program.  However, on some systems (especially
@@ -27,7 +27,7 @@
 # 2949K to 1663K.
 
 # To build a "merge" system, just set DEFAULT_TARGET to "merge" instead
-# of "nomerge" in Makefile.config.  In that case, you should probably also
+# of "nomerge" in config.mk.  In that case, you should probably also
 # set NETPBMLIBTYPE to "unixstatic", since a shared library doesn't do you 
 # much good.
 
@@ -48,16 +48,17 @@ all package install:
 	@echo "You can get a current GNU Make via http://www.gnu.org/software"
 	@echo 
 	@echo "If upgrading is impossible, try modifying GNUMakefile and "
-	@echo "Makefile.common to replace \$(CURDIR) with \$(shell /bin/pwd) "
+	@echo "common.mk to replace \$(CURDIR) with \$(shell /bin/pwd) "
 else
 
 
-include Makefile.srcdir
+# srcdir.mk defines SRCDIR .
+include srcdir.mk
 BUILDDIR = $(CURDIR)
 SUBDIR = 
 VPATH=.:$(SRCDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 PROG_SUBDIRS = converter analyzer editor generator other
 PRODUCT_SUBDIRS = lib $(PROG_SUBDIRS)
@@ -103,10 +104,10 @@ $(PROG_SUBDIRS:%=%/all): lib/all $(SUPPORT_SUBDIRS:%=%/all)
 OMIT_CONFIG_RULE = 1
 OMIT_VERSION_H_RULE = 1
 OMIT_INTTYPES_RULE = 1
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
-$(BUILDDIR)/Makefile.config: $(SRCDIR)/Makefile.config.in
-	$(SRCDIR)/configure $(SRCDIR)/Makefile.config.in
+$(BUILDDIR)/config.mk: $(SRCDIR)/config.mk.in
+	$(SRCDIR)/configure $(SRCDIR)/config.mk.in
 
 
 # typegen is a utility program used by the make file below.
@@ -128,10 +129,10 @@ inttypes_netpbm.h: $(TYPEGEN)
 # cross compiling.
 
 pm_config.h: \
-  $(SRCDIR)/pm_config.in.h Makefile.config inttypes_netpbm.h \
+  $(SRCDIR)/pm_config.in.h config.mk inttypes_netpbm.h \
   $(ENDIANGEN)
 # Note that this rule depends on the effect of the .DELETE_ON_ERROR
-# target we get from Makefile.common
+# target we get from common.mk
 	echo '/* pm_config.h GENERATED BY A MAKE RULE */' >$@
 	echo '#ifndef PM_CONFIG_H' >>$@
 	echo '#define PM_CONFIG_H' >>$@
@@ -158,7 +159,7 @@ endif
 MAJOR := $(NETPBM_MAJOR_RELEASE)
 MINOR := $(NETPBM_MINOR_RELEASE)
 POINT := $(NETPBM_POINT_RELEASE)
-version.h: $(SRCDIR)/Makefile.version
+version.h: $(SRCDIR)/version.mk
 	@rm -f $@
 	@echo "/* Generated by make file rule */" >>$@
 	@echo "#define NETPBM_VERSION" \
@@ -397,14 +398,14 @@ localclean:
 	rm -f netpbm build_started build_complete
 	rm -f pm_config.h inttypes_netpbm.h version.h
 
-# Note that removing Makefile.config must be the last thing we do,
+# Note that removing config.mk must be the last thing we do,
 # because no other makes will work after that is done.
 distclean: localdistclean
 .PHONY: localdistclean
 localdistclean: localclean
 	-rm -f `find -type l`
 	-rm -f TAGS
-	-rm -f Makefile.config
+	-rm -f config.mk
 
 # 'tags' generates/updates an Emacs tags file, anmed TAGS, in the current
 # directory.  Use with Emacs command 'find-tag'.
diff --git a/Makefile.srcdir b/Makefile.srcdir
deleted file mode 100644
index 6a21d9db..00000000
--- a/Makefile.srcdir
+++ /dev/null
@@ -1 +0,0 @@
-SRCDIR = $(CURDIR)
diff --git a/Makefile.version b/Makefile.version
deleted file mode 100644
index cfcf1e13..00000000
--- a/Makefile.version
+++ /dev/null
@@ -1,4 +0,0 @@
-NETPBM_MAJOR_RELEASE = 10
-NETPBM_MINOR_RELEASE = 44
-NETPBM_POINT_RELEASE = 4
-
diff --git a/analyzer/Makefile b/analyzer/Makefile
index 8f8d9d84..9a9a5e10 100644
--- a/analyzer/Makefile
+++ b/analyzer/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = analyzer
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 # We tend to separate out the build targets so that we don't have
 # any more dependencies for a given target than it really needs.
@@ -33,7 +33,7 @@ MERGE_OBJECTS = $(MERGEBINARIES:%=%.o2)
 .PHONY: all
 all: $(BINARIES)
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 install.bin: install.bin.local
 .PHONY: install.bin.local
diff --git a/buildtools/Makefile b/buildtools/Makefile
index 166093ea..9c0ee778 100644
--- a/buildtools/Makefile
+++ b/buildtools/Makefile
@@ -4,7 +4,7 @@ ifeq ($(SRCDIR)x,x)
 endif
 SUBDIR = buildtools
 VPATH = .:$(SRCDIR)/$(SUBDIR)
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 MERGE_OBJECTS =
 
@@ -17,7 +17,7 @@ BINARIES =
 SCRIPTS =
 
 OMIT_BUILDTOOL_RULE = 1
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 ifdef DLLVER
 STRIP_DLL_VERSION=-DDLLVERSTR="\"$(DLLVER)\""
diff --git a/buildtools/configure.pl b/buildtools/configure.pl
index 7f4d554f..efb44ef7 100755
--- a/buildtools/configure.pl
+++ b/buildtools/configure.pl
@@ -13,26 +13,26 @@ use Config;
 
 my ($TRUE, $FALSE) = (1,0);
 
-# This program generates Makefile.config, which is included by all of the
+# This program generates config.mk, which is included by all of the
 # Netpbm makefiles.  You run this program as the first step in building 
 # Netpbm.  (The second step is 'make').
 
 # This program is only a convenience.  It is supported to create 
-# Makefile.config any way you want.  In fact, an easy way is to copy
-# Makefile.config.in and follow the instructions in the comments therein
+# config.mk any way you want.  In fact, an easy way is to copy
+# config.mk.in and follow the instructions in the comments therein
 # to uncomment certain lines and make other changes.
 
 # Note that if you invoke 'make' without having first run 'configure',
 # the make will call 'configure' itself when it finds
-# 'Makefile.config' missing.  That might look a little messy to the
+# 'config.mk' missing.  That might look a little messy to the
 # user, but it isn't the normal build process.
 
-# The argument to this program is the filepath of the Makefile.config.in
-# file.  If unspecified, the default is 'Makefile.config.in' in the 
+# The argument to this program is the filepath of the config.mk.in
+# file.  If unspecified, the default is 'config.mk.in' in the 
 # Netpbm source directory.
 
 # For explanations of the stuff we put in the make files, see the comments
-# in Makefile.config.in.
+# in config.mk.in.
 
 
 # $testCc is the command we use to do test compiles.  Note that test
@@ -254,7 +254,7 @@ sub testCompileLink($$$) {
 sub displayIntroduction() {
     print("This is the Netpbm configurator.  It is an interactive dialog " .
           "that\n");
-    print("helps you build the file 'Makefile.config' and prepare to build ");
+    print("helps you build the file 'config.mk' and prepare to build ");
     print("Netpbm.\n");
     print("\n");
 
@@ -860,7 +860,7 @@ sub getInt64($$) {
 # warning after user has chosen.  Also test links to test the link library.
 
 # It looks like these should all be in the default search paths and were there
-# just to override defaults in Makefile.config.in.  Since Configure now
+# just to override defaults in config.mk.in.  Since Configure now
 # creates a default of "standard search path," I'm guessing we don't need
 # to set these anymore.
 
@@ -1176,8 +1176,8 @@ sub help() {
     print("It is not GNU Configure.\n");
     print("\n");
     print("There is one optional argument to this program:  The " .
-          "name of the file to use as the basis for the Makefile.config " .
-          "file.  Default is 'Makefile.config.in'\n");
+          "name of the file to use as the basis for the config.mk " .
+          "file.  Default is 'config.mk.in'\n");
     print("\n");
     print("Otherwise, the program is interactive.\n");
 }
@@ -1224,7 +1224,7 @@ sub gnuOptimizeOpt($) {
         print("Therefore, I am configuring the build to not do inline \n");
         print("optimization.  This will make some Netpbm programs \n");
         print("noticeably slower.  If I am wrong about your compiler, just\n");
-        print("edit Makefile.config and change -O0 to -O3 near the bottom.\n");
+        print("edit config.mk and change -O0 to -O3 near the bottom.\n");
         print("\n");
         print("The problem is known to exist in the GNU Compiler \n");
         print("release 2.96.  If you upgrade, you will not have this \n");
@@ -1240,6 +1240,26 @@ sub gnuOptimizeOpt($) {
 
 
 
+sub gnuCflags($) {
+    my ($gccCommandName) = @_;
+
+    return("CFLAGS = " . gnuOptimizeOpt($gccCommandName) . " -ffast-math " .
+           " -pedantic -fno-common " . 
+           "-Wall -Wno-uninitialized -Wmissing-declarations -Wimplicit " .
+           "-Wwrite-strings -Wmissing-prototypes -Wundef\n");
+}
+
+
+
+sub makeCompilerGcc($) {
+    my ($config_mkR) = @_;
+    my $compileCommand = 'gcc';
+    push(@{$config_mkR}, "CC = $compileCommand\n");
+    push(@{$config_mkR}, gnuCflags($compileCommand));
+}
+
+
+
 sub findProcessManagement($) {
     my ($dontHaveProcessMgmtR) = @_;
 #-----------------------------------------------------------------------------
@@ -1712,8 +1732,8 @@ if (@ARGV > 0) {
     $configInPathArg = $ARGV[0];
 }
 
-if (stat("Makefile.config")) {
-    print("Discard existing Makefile.config?\n");
+if (stat("config.mk")) {
+    print("Discard existing config.mk?\n");
     print("Y or N (N) ==> ");
 
     my $answer = <STDIN>;
@@ -1736,8 +1756,8 @@ my ($platform, $subplatform) = getPlatform();
 print("\n");
 
 if ($platform eq "NONE") {
-    print("You will have to construct Makefile.config manually.  To do \n");
-    print("this, copy Makefile.config.in as Makefile.config, and then \n");
+    print("You will have to construct config.mk manually.  To do \n");
+    print("this, copy config.mk.in as config.mk, and then \n");
     print("edit it.  Follow the instructions and examples in the file. \n");
     print("Please report your results to the Netpbm maintainer so he \n");
     print("can improve the configure program. \n");
@@ -1750,7 +1770,7 @@ getLinker($platform, $compiler, \my $baseLinker, \my $linkViaCompiler);
 chooseTestCompiler($compiler, \$testCc);
 
 my $netpbmlib_runtime_path;
-    # Undefined if the default from Makefile.config.in is acceptable.
+    # Undefined if the default from config.mk.in is acceptable.
 
 if ($platform eq "SOLARIS" or $platform eq "IRIX" or
     $platform eq "DARWIN" or $platform eq "NETBSD" or
@@ -1910,7 +1930,7 @@ my $defaultConfigInPath;
 if (-f("GNUmakefile")) {
     # He's apparently running us in the source tree or an already set up
     # build directory.
-    $defaultConfigInPath = "Makefile.config.in";
+    $defaultConfigInPath = "config.mk.in";
 } else {
     my $srcdir;
     my $done;
@@ -1935,41 +1955,24 @@ if (-f("GNUmakefile")) {
     unlink("Makefile");
     symlink("$srcdir/Makefile", "Makefile");
 
-    open(SRCDIR, ">Makefile.srcdir");
+    open(SRCDIR, ">srcdir.mk");
     print(SRCDIR "SRCDIR = $srcdir\n");
     close(SRCDIR);
     
-    $defaultConfigInPath = "$srcdir/Makefile.config.in";
-}
-
-sub makeCompilerGcc($) {
-    my ($Makefile_configR) = @_;
-    my $compileCommand = 'gcc';
-    push(@{$Makefile_configR}, "CC = $compileCommand\n");
-    push(@{$Makefile_configR}, gnuCflags($compileCommand));
+    $defaultConfigInPath = "$srcdir/config.mk.in";
 }
 
-
 #******************************************************************************
 #
-#  BUILD Makefile.config
+#  BUILD config.mk
 #
 #*****************************************************************************
 
-sub gnuCflags($) {
-    my ($gccCommandName) = @_;
-
-    return("CFLAGS = " . gnuOptimizeOpt($gccCommandName) . " -ffast-math " .
-           " -pedantic -fno-common " . 
-           "-Wall -Wno-uninitialized -Wmissing-declarations -Wimplicit " .
-           "-Wwrite-strings -Wmissing-prototypes -Wundef\n");
-}
-
-my @Makefile_config;
-    # This is the complete Makefile.config contents.  We construct it here
-    # and ultimately write the whole thing out as Makefile.config.
+my @config_mk;
+    # This is the complete config.mk contents.  We construct it here
+    # and ultimately write the whole thing out as config.mk.
 
-# First, we just read the 'Makefile.config.in' in
+# First, we just read the 'config.mk.in' in
 
 my $configInPath;
 if (defined($configInPathArg)) {
@@ -1980,9 +1983,9 @@ if (defined($configInPathArg)) {
 open (CONFIG_IN,"<$configInPath") or
     die("Unable to open file '$configInPath' for input.");
 
-@Makefile_config = <CONFIG_IN>;
+@config_mk = <CONFIG_IN>;
 
-unshift(@Makefile_config, 
+unshift(@config_mk, 
         "####This file was automatically created by 'configure.'\n",
         "####Many variables are set twice -- a generic setting, then \n",
         "####a system-specific override at the bottom of the file.\n",
@@ -1991,100 +1994,97 @@ unshift(@Makefile_config,
 close(CONFIG_IN);
 
 # Now, add the variable settings that override the default settings that are
-# done by the Makefile.config.in contents.
+# done by the config.mk.in contents.
 
-push(@Makefile_config, "\n\n\n\n");
-push(@Makefile_config, "####Lines above were copied from Makefile.config.in " .
+push(@config_mk, "\n\n\n\n");
+push(@config_mk, "####Lines above were copied from config.mk.in " .
      "by 'configure'.\n");
-push(@Makefile_config, "####Lines below were added by 'configure' based on " .
+push(@config_mk, "####Lines below were added by 'configure' based on " .
      "the $platform platform.\n");
 if (defined($subplatform)) {
-    push(@Makefile_config, "####subplatform '$subplatform'\n");
+    push(@config_mk, "####subplatform '$subplatform'\n");
 }
 
-push(@Makefile_config, "DEFAULT_TARGET = $default_target\n");
+push(@config_mk, "DEFAULT_TARGET = $default_target\n");
 
-push(@Makefile_config, "NETPBMLIBTYPE=$netpbmlibtype\n");
-push(@Makefile_config, "NETPBMLIBSUFFIX=$netpbmlibsuffix\n");
+push(@config_mk, "NETPBMLIBTYPE=$netpbmlibtype\n");
+push(@config_mk, "NETPBMLIBSUFFIX=$netpbmlibsuffix\n");
 if (defined($shlibprefixlist)) {
-    push(@Makefile_config, "SHLIBPREFIXLIST=$shlibprefixlist\n");
+    push(@config_mk, "SHLIBPREFIXLIST=$shlibprefixlist\n");
 }
-push(@Makefile_config, "STATICLIB_TOO=$staticlib_too\n");
+push(@config_mk, "STATICLIB_TOO=$staticlib_too\n");
 
 if (defined($netpbmlib_runtime_path)) {
-    push(@Makefile_config, "NETPBMLIB_RUNTIME_PATH=$netpbmlib_runtime_path\n");
+    push(@config_mk, "NETPBMLIB_RUNTIME_PATH=$netpbmlib_runtime_path\n");
 }
 
 if ($platform eq "GNU") {
-    my $compileCommand;
     if (!commandExists("cc") && commandExists("gcc")) {
-        $compileCommand = "gcc";
-        push(@Makefile_config, "CC = $compileCommand\n");
+        makeCompilerGcc(\@config_mk);
     } else {
-        $compileCommand = "cc";
+        push(@config_mk, gnuCflags('cc'));
     }
-    push(@Makefile_config, gnuCflags($compileCommand));
 # The merged programs have a main_XXX subroutine instead of main(),
 # which would cause a warning with -Wmissing-declarations or 
 # -Wmissing-prototypes.
-    push(@Makefile_config, "CFLAGS_MERGE = " .
+    push(@config_mk, "CFLAGS_MERGE = " .
          "-Wno-missing-declarations -Wno-missing-prototypes\n");
-    push(@Makefile_config, "LDRELOC = ld --reloc\n");
-    push(@Makefile_config, "LINKER_CAN_DO_EXPLICIT_LIBRARY=Y\n");
+    push(@config_mk, "LDRELOC = ld --reloc\n");
+    push(@config_mk, "LINKER_CAN_DO_EXPLICIT_LIBRARY=Y\n");
 } elsif ($platform eq "SOLARIS") {
-    push(@Makefile_config, 'LDSHLIB = -Wl,-Bdynamic,-G,-h,$(SONAME)', "\n");
+    push(@config_mk, 'LDSHLIB = -Wl,-Bdynamic,-G,-h,$(SONAME)', "\n");
 
-    push(@Makefile_config, 'NEED_RUNTIME_PATH = Y', "\n");
+    push(@config_mk, 'NEED_RUNTIME_PATH = Y', "\n");
     if ($compiler eq "cc") {
-        push(@Makefile_config, "CFLAGS = -O\n");
-        push(@Makefile_config, "CFLAGS_SHLIB = -Kpic\n");
+        push(@config_mk, "CFLAGS = -O\n");
+        push(@config_mk, "CFLAGS_SHLIB = -Kpic\n");
     } else {
-        makeCompilerGcc(\@Makefile_config);
+        makeCompilerGcc(\@config_mk);
     }
     # Before Netpbm 10.20 (January 2004), we set this to -R for 
     # $compiler == cc and -rpath otherwise.  But now we know that the GNU
     # compiler can also invoke a linker that needs -R, so we're more flexible.
     if ($baseLinker eq "GNU") {
-        push(@Makefile_config, "RPATHOPTNAME = -rpath\n");
+        push(@config_mk, "RPATHOPTNAME = -rpath\n");
     } else {
-        push(@Makefile_config, "RPATHOPTNAME = -R\n");
+        push(@config_mk, "RPATHOPTNAME = -R\n");
     }
-    push(@Makefile_config, "NETWORKLD = -lsocket -lnsl\n");
+    push(@config_mk, "NETWORKLD = -lsocket -lnsl\n");
 } elsif ($platform eq "HP-UX") {
     if ($compiler eq "gcc") {
-        makeCompilerGcc(\@Makefile_config);
-        push(@Makefile_config, "CFLAGS += -fPIC\n");
-        push(@Makefile_config, "LDSHLIB = -shared -fPIC\n");
-        push(@Makefile_config, 'LDFLAGS += -Wl,+b,/usr/pubsw/lib', "\n");
+        makeCompilerGcc(\@config_mk);
+        push(@config_mk, "CFLAGS += -fPIC\n");
+        push(@config_mk, "LDSHLIB = -shared -fPIC\n");
+        push(@config_mk, 'LDFLAGS += -Wl,+b,/usr/pubsw/lib', "\n");
     } else {
         # We don't know what to do here.  We used to (before 10.20) just
         # just assume the compiler was gcc.  We know that the gcc stuff
         # above does NOT work for HP native compiler.
     }
 } elsif ($platform eq "AIX") {
-    push(@Makefile_config, 'LDFLAGS += -L /usr/pubsw/lib', "\n");
+    push(@config_mk, 'LDFLAGS += -L /usr/pubsw/lib', "\n");
     if ($compiler eq "cc") {
         # Yes, the -L option implies the runtime as well as linktime library
         # search path.  There's no way to specify runtime path independently.
-        push(@Makefile_config, "RPATHOPTNAME = -L\n");
-        push(@Makefile_config, "LDSHLIB = -qmkshrobj\n");
+        push(@config_mk, "RPATHOPTNAME = -L\n");
+        push(@config_mk, "LDSHLIB = -qmkshrobj\n");
     } else {
-        makeCompilerGcc(\@Makefile_config);
-        push(@Makefile_config, "LDSHLIB = -shared\n");
+        makeCompilerGcc(\@config_mk);
+        push(@config_mk, "LDSHLIB = -shared\n");
     }
 } elsif ($platform eq "TRU64") {
-#    push(@Makefile_config, "INSTALL = installbsd\n");
+#    push(@config_mk, "INSTALL = installbsd\n");
     if ($compiler eq "cc") {
-        push(@Makefile_config, 'CFLAGS = -O2 -std1', "\n");
-        push(@Makefile_config, "LDFLAGS = -call_shared -oldstyle_liblookup " .
+        push(@config_mk, 'CFLAGS = -O2 -std1', "\n");
+        push(@config_mk, "LDFLAGS = -call_shared -oldstyle_liblookup " .
              "-L/usr/local/lib\n");
-        push(@Makefile_config, "LDSHLIB = -shared -expect_unresolved \"*\"\n");
+        push(@config_mk, "LDSHLIB = -shared -expect_unresolved \"*\"\n");
     } else {
         # We've never tested this.  This is just here to give a user a 
         # headstart on submitting to us the necessary information.  2002.07.04.
-        push(@Makefile_config, "CC = gcc\n");
-        push(@Makefile_config, 'CFLAGS = -O3', "\n");
-        push(@Makefile_config, "LDSHLIB = -shared\n");
+        push(@config_mk, "CC = gcc\n");
+        push(@config_mk, 'CFLAGS = -O3', "\n");
+        push(@config_mk, "LDSHLIB = -shared\n");
     }
     # Between May 2000 and July 2003, we had -DLONG_32 in these options.
     # We took it out because it generated bad code for a TRU64 user in
@@ -2092,60 +2092,61 @@ if ($platform eq "GNU") {
     # only Ppmtompeg and it isn't clear that using long instead of int is
     # ever right anyway.
 
-    push(@Makefile_config, "OMIT_NETWORK = y\n");
-    push(@Makefile_config, "LINKER_CAN_DO_EXPLICIT_LIBRARY=Y\n");
+    push(@config_mk, "OMIT_NETWORK = y\n");
+    push(@config_mk, "LINKER_CAN_DO_EXPLICIT_LIBRARY=Y\n");
 } elsif ($platform eq "IRIX") {
-#    push(@Makefile_config, "INSTALL = install\n");
-    push(@Makefile_config, "MANPAGE_FORMAT = cat\n");
-    push(@Makefile_config, "RANLIB = true\n");
-    push(@Makefile_config, "CFLAGS = -n32 -O3 -fullwarn\n");
-    push(@Makefile_config, "LDFLAGS = -n32\n");
-    push(@Makefile_config, "LDSHLIB = -shared -n32\n");
+#    push(@config_mk, "INSTALL = install\n");
+    push(@config_mk, "MANPAGE_FORMAT = cat\n");
+    push(@config_mk, "RANLIB = true\n");
+    push(@config_mk, "CFLAGS = -n32 -O3 -fullwarn\n");
+    push(@config_mk, "LDFLAGS = -n32\n");
+    push(@config_mk, "LDSHLIB = -shared -n32\n");
 } elsif ($platform eq "WINDOWS") {
     if ($subplatform eq "cygwin") {
-        makeCompilerGcc(\@Makefile_config);
+        makeCompilerGcc(\@config_mk);
     }
-    push(@Makefile_config, "EXE = .exe\n");
-    push(@Makefile_config, "OMIT_NETWORK = y\n");
+    push(@config_mk, "EXE = .exe\n");
+    push(@config_mk, "OMIT_NETWORK = y\n");
 #    # Though it may not have the link as "ginstall", "install" in a Windows
 #    # Unix environment is usually GNU install.
 #    my $ginstall_result = `ginstall --version 2>/dev/null`;
 #    if (!$ginstall_result) {
 #        # System doesn't have 'ginstall', so use 'install' instead.
-#        push(@Makefile_config, "INSTALL = install\n");
+#        push(@config_mk, "INSTALL = install\n");
 #    }
-    push(@Makefile_config, 'SYMLINK = ', symlink_command(), "\n");
-    push(@Makefile_config, 'DLLVER=$(NETPBM_MAJOR_RELEASE)', "\n");
-    push(@Makefile_config, "LDSHLIB = " . 
+    push(@config_mk, 'SYMLINK = ', symlink_command(), "\n");
+    push(@config_mk, 'DLLVER=$(NETPBM_MAJOR_RELEASE)', "\n");
+    push(@config_mk, "LDSHLIB = " . 
          '-shared -Wl,--image-base=0x10000000 -Wl,--enable-auto-import', "\n");
 } elsif ($platform eq "BEOS") {
-    push(@Makefile_config, "LDSHLIB = -nostart\n");
+    push(@config_mk, "LDSHLIB = -nostart\n");
 } elsif ($platform eq "OPENBSD") {
     # vedge@vedge.com.ar says on 2001.04.29 that there are a ton of 
     # undefined symbols in the Fiasco stuff on OpenBSD.  So we'll just
     # cut it out of the build until someone feels like fixing it.
-    push(@Makefile_config, "BUILD_FIASCO = N\n");
+    push(@config_mk, "BUILD_FIASCO = N\n");
 } elsif ($platform eq "FREEBSD") {
 } elsif ($platform eq "AMIGA") {
-    push(@Makefile_config, "CFLAGS = -m68020-60 -ffast-math -mstackextend\n");
+    push(@config_mk, "CFLAGS = -m68020-60 -ffast-math -mstackextend\n");
 } elsif ($platform eq "UNIXWARE") {
     # Nothing to do.
 } elsif ($platform eq "SCO") {
     # Got this from "John H. DuBois III" <spcecdt@armory.com> 2002.09.27:
-    push(@Makefile_config, "RANLIB = true\n");
+    push(@config_mk, "RANLIB = true\n");
     if ($compiler eq "cc") {
-        push(@Makefile_config, "CFLAGS = -O\n");
-        push(@Makefile_config, "CFLAGS_SHLIB = -O -K pic\n");
-        push(@Makefile_config, "LDSHLIB = -G\n");
-        push(@Makefile_config, "SHLIB_CLIB =\n");
+        push(@config_mk, "CFLAGS = -O\n");
+        push(@config_mk, "CFLAGS_SHLIB = -O -K pic\n");
+        push(@config_mk, "LDSHLIB = -G\n");
+        push(@config_mk, "SHLIB_CLIB =\n");
     } else {
-        makeCompilerGcc(\@Makefile_config);
-        push(@Makefile_config, "LDSHLIB = -shared\n"); 
+        makeCompilerGcc(\@config_mk);
+        push(@config_mk, "LDSHLIB = -shared\n"); 
     }
-    push(@Makefile_config, "NETWORKLD = -lsocket -lresolve\n");
+    push(@config_mk, "NETWORKLD = -lsocket -lresolve\n");
 } elsif ($platform eq "DARWIN") {
-    push(@Makefile_config, "CC = cc -no-cpp-precomp\n");
-    push(@Makefile_config, 'CFLAGS_SHLIB = -fno-common', "\n");
+    push(@config_mk, "CC = cc -no-cpp-precomp\n");
+    push(@config_mk, gnuCflags('cc'));
+    push(@config_mk, 'CFLAGS_SHLIB = -fno-common', "\n");
 
     my $installNameOpt;
     if ($netpbmlib_runtime_path eq '') {
@@ -2154,14 +2155,14 @@ if ($platform eq "GNU") {
         $installNameOpt  =
             '-install_name $(NETPBMLIB_RUNTIME_PATH)/libnetpbm.$(MAJ).dylib';
     }
-    push(@Makefile_config, "LDSHLIB = -dynamiclib $installNameOpt\n");
-#    push(@Makefile_config, "INSTALL = install\n");
+    push(@config_mk, "LDSHLIB = -dynamiclib $installNameOpt\n");
+#    push(@config_mk, "INSTALL = install\n");
 } else {
     die ("Internal error: invalid value for \$platform: '$platform'\n");
 }
 
 if ($linkViaCompiler) {
-    push(@Makefile_config, "LINKERISCOMPILER = Y\n");
+    push(@config_mk, "LINKERISCOMPILER = Y\n");
 }
 
 my $flex_result = `flex --version`;
@@ -2183,7 +2184,7 @@ if (!$flex_result) {
         my $key = <STDIN>;
         print("\n");
 
-        push(@Makefile_config, "LEX=\n");
+        push(@config_mk, "LEX=\n");
     } else {
         print("\n");
         print("Using 'lex' as the pattern matcher generator, " .
@@ -2191,70 +2192,70 @@ if (!$flex_result) {
         print("find 'flex' on your system.\n");
         print("\n");
 
-        push(@Makefile_config, "LEX = lex\n"); 
+        push(@config_mk, "LEX = lex\n"); 
     }
 }
 
 if ($compiler eq 'gcc') {
-    push(@Makefile_config, "CFLAGS_SHLIB += -fPIC\n");
+    push(@config_mk, "CFLAGS_SHLIB += -fPIC\n");
 }
 
 if (defined($tiffhdr_dir)) {
-    push(@Makefile_config, "TIFFHDR_DIR = $tiffhdr_dir\n");
+    push(@config_mk, "TIFFHDR_DIR = $tiffhdr_dir\n");
 }
 if (defined($tifflib)) {
-    push(@Makefile_config, "TIFFLIB = $tifflib\n");
+    push(@config_mk, "TIFFLIB = $tifflib\n");
 }
 
 if (defined($jpeghdr_dir)) {
-    push(@Makefile_config, "JPEGHDR_DIR = $jpeghdr_dir\n");
+    push(@config_mk, "JPEGHDR_DIR = $jpeghdr_dir\n");
 }
 if (defined($jpeglib)) {
-    push(@Makefile_config, "JPEGLIB = $jpeglib\n");
+    push(@config_mk, "JPEGLIB = $jpeglib\n");
 }
 
 if (defined($pnghdr_dir)) {
-    push(@Makefile_config, "PNGHDR_DIR = $pnghdr_dir\n");
+    push(@config_mk, "PNGHDR_DIR = $pnghdr_dir\n");
 }
 if (defined($pnglib)) {
-    push(@Makefile_config, "PNGLIB = $pnglib\n");
+    push(@config_mk, "PNGLIB = $pnglib\n");
 }
 
 if (defined($zhdr_dir)) {
-    push(@Makefile_config, "ZHDR_DIR = $zhdr_dir\n");
+    push(@config_mk, "ZHDR_DIR = $zhdr_dir\n");
 }
 if (defined($zlib)) {
-    push(@Makefile_config, "ZLIB = $zlib\n");
+    push(@config_mk, "ZLIB = $zlib\n");
 }
 
 if (defined($x11hdr_dir)) {
-    push(@Makefile_config, "X11HDR_DIR = $x11hdr_dir\n");
+    push(@config_mk, "X11HDR_DIR = $x11hdr_dir\n");
 }
 if (defined($x11lib)) {
-    push(@Makefile_config, "X11LIB = $x11lib\n");
+    push(@config_mk, "X11LIB = $x11lib\n");
 }
 
 if (defined($linuxsvgahdr_dir)) {
-    push(@Makefile_config, "LINUXSVGAHDR_DIR = $linuxsvgahdr_dir\n");
+    push(@config_mk, "LINUXSVGAHDR_DIR = $linuxsvgahdr_dir\n");
 }
 if (defined($linuxsvgalib)) {
-    push(@Makefile_config, "LINUXSVGALIB = $linuxsvgalib\n");
+    push(@config_mk, "LINUXSVGALIB = $linuxsvgalib\n");
 }
 
 if (defined($netpbm_docurl)) {
-    push(@Makefile_config, "NETPBM_DOCURL = $netpbm_docurl\n");
+    push(@config_mk, "NETPBM_DOCURL = $netpbm_docurl\n");
 }
 
 if ($inttypesHeaderFile ne '<inttypes.h>') {
-    push(@Makefile_config, "INTTYPES_H = $inttypesHeaderFile\n");
+    push(@config_mk, "INTTYPES_H = $inttypesHeaderFile\n");
 }
 
 if ($haveInt64 ne 'Y') {
-    push(@Makefile_config, "HAVE_INT64 = $haveInt64\n");
+    push(@config_mk, "HAVE_INT64 = $haveInt64\n");
 }
 
 if ($dontHaveProcessMgmt) {
-    push(@Makefile_config, "DONT_HAVE_PROCESS_MGMT = Y\n");
+    push(@config_mk, "DONT_HAVE_PROCESS_MGMT = Y\n");
 }
 
 #******************************************************************************
@@ -2263,17 +2264,17 @@ if ($dontHaveProcessMgmt) {
 #
 #*****************************************************************************
 
-open(MAKEFILE_CONFIG, ">Makefile.config") or
-    die("Unable to open Makefile.config for writing in the current " .
+open(config_mk, ">config.mk") or
+    die("Unable to open config.mk for writing in the current " .
         "directory.");
 
-print MAKEFILE_CONFIG @Makefile_config;
+print config_mk @config_mk;
 
-close(MAKEFILE_CONFIG) or
-    die("Error:  Close of Makefile.config failed.\n");
+close(config_mk) or
+    die("Error:  Close of config.mk failed.\n");
 
 print("\n");
-print("We have created the file 'Makefile.config'.  You may want to look \n");
+print("We have created the file 'config.mk'.  You may want to look \n");
 print("at it and edit it to your requirements and taste before doing the \n");
 print("make.\n");
 print("\n");
diff --git a/buildtools/installosf b/buildtools/installosf
index a4e5c262..1d1d61a7 100755
--- a/buildtools/installosf
+++ b/buildtools/installosf
@@ -4,7 +4,7 @@
 # its $(INSTALL) program and invokes OSF1 Install with the proper
 # parameters to effect what the make file wants.  If your system has
 # OSF1 Install on it, you can just set the INSTALL variable in
-# Makefile.config to "installosf" and 'make install' will work for
+# config.mk to "installosf" and 'make install' will work for
 # you.
 
 # Of course, you could also just install Ginstall and forget about this
diff --git a/buildtools/Makefile.manpage b/buildtools/manpage.mk
index b25bc19e..e1c0bce2 100644
--- a/buildtools/Makefile.manpage
+++ b/buildtools/manpage.mk
@@ -1,5 +1,3 @@
-# -*-makefile-*-    <-- an Emacs control
-
 # Make Unix man pages from Netpbm HTML user manual
 
 MAKEMAN = makeman
diff --git a/Makefile.common b/common.mk
index 4b99e17a..c69d3d6b 100644
--- a/Makefile.common
+++ b/common.mk
@@ -1,4 +1,3 @@
-# -*-makefile-*-    <-- an Emacs control
 # This is a make file inclusion, to be included in all the
 # Netpbm make files.
 
@@ -69,7 +68,7 @@
 # for options that are particular to the person doing the build and not
 # specific to Netpbm.
 
-include $(SRCDIR)/Makefile.version
+include $(SRCDIR)/version.mk
 
 # .DELETE_ON_ERROR is a special predefined Make target that says to delete
 # the target if a command in the rule for it fails.  That's important,
@@ -121,7 +120,7 @@ IMPORTINC_ROOT_HEADERS := pm_config.h inttypes_netpbm.h version.h
 IMPORTINC_LIB_HEADERS := \
   pm.h pbm.h pgm.h ppm.h pnm.h pam.h bitio.h pbmfont.h ppmcmap.h \
   pammap.h colorname.h ppmfloyd.h ppmdraw.h pm_system.h ppmdfont.h \
-  pm_gamma.h lum.h
+  pm_gamma.h lum.h dithers.h
 
 IMPORTINC_LIB_UTIL_HEADERS := \
   bitarith.h bitreverse.h filename.h intcode.h mallocvar.h\
@@ -179,7 +178,7 @@ $(BUILDDIR)/version.h:
 endif
 
 ifneq ($(OMIT_CONFIG_RULE),1)
-$(BUILDDIR)/Makefile.config: $(SRCDIR)/Makefile.config.in
+$(BUILDDIR)/config.mk: $(SRCDIR)/config.mk.in
 	$(MAKE) -C $(dir $@) $(notdir $@)
 
 $(BUILDDIR)/pm_config.h:
@@ -192,13 +191,13 @@ $(BUILDDIR)/inttypes_netpbm.h:
 endif
 
 # Note that any time you do a make on a fresh Netpbm source tree,
-# Make notices that 'Makefile.config', which the make files include, does not
-# exist and runs the "Makefile.config" target, which runs Configure.
+# Make notices that 'config.mk', which the make files include, does not
+# exist and runs the "config.mk" target, which runs Configure.
 # If the "config" target were to run Configure as well, it would get run
 # twice in a row if you did a 'make config' on a fresh Netpbm source tree.
 # But we don't want to make "config" just a no-op, because someone might
-# try it after Makefile.config already exists, in order to make a new
-# Makefile.config.  Issuing a message as follows seems to make sense in 
+# try it after config.mk already exists, in order to make a new
+# config.mk.  Issuing a message as follows seems to make sense in 
 # both cases.
 .PHONY: config
 config:
@@ -492,7 +491,7 @@ thisdirclean:
 
 .PHONY: distclean
 distclean: $(SUBDIRS:%=%/distclean) thisdirclean
-	rm -f Makefile.depend
+	rm -f depend.mk
 
 DEP_SOURCES = $(wildcard *.c *.cpp *.cc)
 
@@ -502,7 +501,7 @@ dep: $(SUBDIRS:%=%/dep) importinc
 # before the first make after a clean.
 
 ifneq ($(DEP_SOURCES)x,x)
-	$(CC) -MM -MG $(INCLUDES) $(DEP_SOURCES) >Makefile.depend
+	$(CC) -MM -MG $(INCLUDES) $(DEP_SOURCES) >depend.mk
 endif
 
 # Note: if I stack all these subdirectory targets into one rule, I get
@@ -564,13 +563,13 @@ $(SUBDIRS:%=$(CURDIR)/%) $(DIRS2):
 # The automatic dependency generation is a pain in the butt and
 # totally unnecessary for people just installing the distributed code,
 # so to avoid needless failures in the field and a complex build, the
-# rule to generate Makefile.depend automatically simply creates an
+# rule to generate depend.mk automatically simply creates an
 # empty file.  A developer may do 'make dep' to create a
-# Makefile.depend full of real dependencies.
+# depend.mk full of real dependencies.
 
-Makefile.depend:
-	cat /dev/null >Makefile.depend
+depend.mk:
+	cat /dev/null >$@
 
-include Makefile.depend
+include depend.mk
 
 FORCE:
diff --git a/Makefile.config.in b/config.mk.in
index 66589856..0e061701 100644
--- a/Makefile.config.in
+++ b/config.mk.in
@@ -4,9 +4,9 @@
 # This file is meant to contain variable settings that customize the
 # build for a particular target system configuration.
 
-# The distribution contains the file Makefile.config.in.  You edit
-# Makefile.config.in in ways relevant to your particular environment 
-# to create Makefile.config.  The "configure" program will do this
+# The distribution contains the file config.mk.in.  You edit
+# config.mk.in in ways relevant to your particular environment 
+# to create config.mk.  The "configure" program will do this
 # for you in simple cases.
 
 # Some of the variables that the including make file must set for this
diff --git a/converter/Makefile b/converter/Makefile
index 02cab3be..8c488ee2 100644
--- a/converter/Makefile
+++ b/converter/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = converter
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 SUBDIRS = pbm pgm ppm other
 
@@ -14,4 +14,4 @@ all: $(SUBDIRS:%=%/all)
 SCRIPTS = 
 BINARIES =
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
diff --git a/converter/other/Makefile b/converter/other/Makefile
index 032bb916..61272ab0 100644
--- a/converter/other/Makefile
+++ b/converter/other/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = converter/other
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 ifeq ($(shell xml2-config --version),)
   XML2_LIBS=NONE
@@ -134,7 +134,7 @@ SCRIPTS = anytopnm pnmtoplainpnm
 .PHONY: all
 all:	$(BINARIES) $(SUBDIRS:%=%/all)
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 ifeq ($(NEED_RUNTIME_PATH),Y)
   LIBOPTR = -runtime
diff --git a/converter/other/cameratopam/Makefile b/converter/other/cameratopam/Makefile
index cd38705b..20a95aa2 100644
--- a/converter/other/cameratopam/Makefile
+++ b/converter/other/cameratopam/Makefile
@@ -13,7 +13,7 @@ ifneq ($(JPEGLIB),NONE)
   endif
 endif
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 
 .PHONY: all
@@ -28,7 +28,7 @@ BINARIES = cameratopam
 MERGEBINARIES = 
 SCRIPTS = 
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 cameratopam: $(OBJECTS) $(NETPBMLIB) $(LIBOPT)
 	$(LD) -o $@ \
diff --git a/converter/other/dithers.h b/converter/other/dithers.h
deleted file mode 100644
index 1ced833d..00000000
--- a/converter/other/dithers.h
+++ /dev/null
@@ -1,91 +0,0 @@
-#ifndef DITHERS_H_INCLUDED
-#define DITHERS_H_INCLUDED
-
-/*
-** dithers.h
-**
-** Here are some dithering matrices.  They are all taken from "Digital
-** Halftoning" by Robert Ulichney, MIT Press, ISBN 0-262-21009-6.
-*/
-
-
-#if 0
-/*
-** Order-6 ordered dithering matrix.  Note that smaller ordered dithers
-** have no advantage over larger ones, so use dither8 instead.
-*/
-static int dither6[8][8] = {
-  {  1, 59, 15, 55,  2, 56, 12, 52 },
-  { 33, 17, 47, 31, 34, 18, 44, 28 },
-  {  9, 49,  5, 63, 10, 50,  6, 60 },
-  { 41, 25, 37, 21, 42, 26, 38, 22 },
-  {  3, 57, 13, 53,  0, 58, 14, 54 },
-  { 35, 19, 45, 29, 32, 16, 46, 30 },
-  { 11, 51,  7, 61,  8, 48,  4, 62 },
-  { 43, 27, 39, 23, 40, 24, 36, 20 }
-  };
-#endif
-
-/* Order-8 ordered dithering matrix. */
-static int dither8[16][16] = {
-  {   1,235, 59,219, 15,231, 55,215,  2,232, 56,216, 12,228, 52,212},
-  { 129, 65,187,123,143, 79,183,119,130, 66,184,120,140, 76,180,116},
-  {  33,193, 17,251, 47,207, 31,247, 34,194, 18,248, 44,204, 28,244},
-  { 161, 97,145, 81,175,111,159, 95,162, 98,146, 82,172,108,156, 92},
-  {   9,225, 49,209,  5,239, 63,223, 10,226, 50,210,  6,236, 60,220},
-  { 137, 73,177,113,133, 69,191,127,138, 74,178,114,134, 70,188,124},
-  {  41,201, 25,241, 37,197, 21,255, 42,202, 26,242, 38,198, 22,252},
-  { 169,105,153, 89,165,101,149, 85,170,106,154, 90,166,102,150, 86},
-  {   3,233, 57,217, 13,229, 53,213,  0,234, 58,218, 14,230, 54,214},
-  { 131, 67,185,121,141, 77,181,117,128, 64,186,122,142, 78,182,118},
-  {  35,195, 19,249, 45,205, 29,245, 32,192, 16,250, 46,206, 30,246},
-  { 163, 99,147, 83,173,109,157, 93,160, 96,144, 80,174,110,158, 94},
-  {  11,227, 51,211,  7,237, 61,221,  8,224, 48,208,  4,238, 62,222},
-  { 139, 75,179,115,135, 71,189,125,136, 72,176,112,132, 68,190,126},
-  {  43,203, 27,243, 39,199, 23,253, 40,200, 24,240, 36,196, 20,254},
-  { 171,107,155, 91,167,103,151, 87,168,104,152, 88,164,100,148, 84} 
-};
-
-/* Order-3 clustered dithering matrix. */
-static int cluster3[6][6] = {
-  {  9,11,10, 8, 6, 7},
-  { 12,17,16, 5, 0, 1},
-  { 13,14,15, 4, 3, 2},
-  {  8, 6, 7, 9,11,10},
-  {  5, 0, 1,12,17,16},
-  {  4, 3, 2,13,14,15}
-};
-
-/* Order-4 clustered dithering matrix. */
-static int cluster4[8][8] = {
-  { 18,20,19,16,13,11,12,15},
-  { 27,28,29,22, 4, 3, 2, 9},
-  { 26,31,30,21, 5, 0, 1,10},
-  { 23,25,24,17, 8, 6, 7,14},
-  { 13,11,12,15,18,20,19,16},
-  {  4, 3, 2, 9,27,28,29,22},
-  {  5, 0, 1,10,26,31,30,21},
-  {  8, 6, 7,14,23,25,24,17}
-};
-
-/* Order-8 clustered dithering matrix. */
-static int cluster8[16][16] = {
-   { 64, 69, 77, 87, 86, 76, 68, 67, 63, 58, 50, 40, 41, 51, 59, 60},
-   { 70, 94,100,109,108, 99, 93, 75, 57, 33, 27, 18, 19, 28, 34, 52},
-   { 78,101,114,116,115,112, 98, 83, 49, 26, 13, 11, 12, 15, 29, 44},
-   { 88,110,123,124,125,118,107, 85, 39, 17,  4,  3,  2,  9, 20, 42},
-   { 89,111,122,127,126,117,106, 84, 38, 16,  5,  0,  1, 10, 21, 43},
-   { 79,102,119,121,120,113, 97, 82, 48, 25,  8,  6,  7, 14, 30, 45},
-   { 71, 95,103,104,105, 96, 92, 74, 56, 32, 24, 23, 22, 31, 35, 53},
-   { 65, 72, 80, 90, 91, 81, 73, 66, 62, 55, 47, 37, 36, 46, 54, 61},
-   { 63, 58, 50, 40, 41, 51, 59, 60, 64, 69, 77, 87, 86, 76, 68, 67},
-   { 57, 33, 27, 18, 19, 28, 34, 52, 70, 94,100,109,108, 99, 93, 75},
-   { 49, 26, 13, 11, 12, 15, 29, 44, 78,101,114,116,115,112, 98, 83},
-   { 39, 17,  4,  3,  2,  9, 20, 42, 88,110,123,124,125,118,107, 85},
-   { 38, 16,  5,  0,  1, 10, 21, 43, 89,111,122,127,126,117,106, 84},
-   { 48, 25,  8,  6,  7, 14, 30, 45, 79,102,119,121,120,113, 97, 82},
-   { 56, 32, 24, 23, 22, 31, 35, 53, 71, 95,103,104,105, 96, 92, 74},
-   { 62, 55, 47, 37, 36, 46, 54, 61, 65, 72, 80, 90, 91, 81, 73, 66}
-};
-
-#endif
diff --git a/converter/other/fiasco/Makefile b/converter/other/fiasco/Makefile
index 26b1b4b8..16221d77 100644
--- a/converter/other/fiasco/Makefile
+++ b/converter/other/fiasco/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = converter/other/fiasco
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 COMP_INCLUDES = \
 	-I$(SRCDIR)/$(SUBDIR)/codec -I$(SRCDIR)/$(SUBDIR)/input \
@@ -32,7 +32,7 @@ MERGE_OBJECTS = $(BINARIES:%=%.o2) $(COMMON_OBJECTS)  $(FIASCOLIBS)
 
 SUBDIRS = codec input output lib
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 $(BINARIES):%:%.o $(COMMON_OBJECTS) $(FIASCOLIBS) $(NETPBMLIB) \
    $(LIBOPT)
diff --git a/converter/other/fiasco/codec/Makefile b/converter/other/fiasco/codec/Makefile
index c5f94c28..e3b2a112 100644
--- a/converter/other/fiasco/codec/Makefile
+++ b/converter/other/fiasco/codec/Makefile
@@ -6,7 +6,7 @@ FIASCOSUBDIR = converter/other/fiasco
 SUBDIR = $(FIASCOSUBDIR)/codec
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 COMP_INCLUDES = -I$(SRCDIR)/$(FIASCOSUBDIR) -I$(SRCDIR)/$(FIASCOSUBDIR)/lib \
 	 -I$(SRCDIR)/$(FIASCOSUBDIR)/input -I$(SRCDIR)/$(FIASCOSUBDIR)/output 
@@ -19,7 +19,7 @@ MERGE_OBJECTS = $(OBJECTS)
 
 all: libfiasco_codec.a
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 libfiasco_codec.a: $(OBJECTS)
 	$(AR) -rc $@ $(OBJECTS)
diff --git a/converter/other/fiasco/input/Makefile b/converter/other/fiasco/input/Makefile
index 6cd8e34b..2f8749f6 100644
--- a/converter/other/fiasco/input/Makefile
+++ b/converter/other/fiasco/input/Makefile
@@ -7,7 +7,7 @@ SUBDIR = $(FIASCOSUBDIR)/input
 BUILDDIR = ../../../..
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 OBJECTS =  basis.o matrices.o mc.o nd.o read.o tree.o weights.o
 
@@ -18,7 +18,7 @@ COMP_INCLUDES = -I$(SRCDIR)/$(FIASCOSUBDIR) -I$(SRCDIR)/$(FIASCOSUBDIR)/lib \
 
 all: libfiasco_input.a
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 libfiasco_input.a: $(OBJECTS)
 	$(AR) -rc $@ $(OBJECTS)
diff --git a/converter/other/fiasco/lib/Makefile b/converter/other/fiasco/lib/Makefile
index bd129016..801fd24e 100644
--- a/converter/other/fiasco/lib/Makefile
+++ b/converter/other/fiasco/lib/Makefile
@@ -6,7 +6,7 @@ FIASCOSUBDIR = converter/other/fiasco
 SUBDIR = $(FIASCOSUBDIR)/lib
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 OBJECTS = \
   arith.o \
@@ -25,7 +25,7 @@ COMP_INCLUDES = -I$(SRCDIR)/$(FIASCOSUBDIR)
 
 all: libfiasco_lib.a
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 libfiasco_lib.a: $(OBJECTS)
 	$(AR) -rc $@ $(OBJECTS)
diff --git a/converter/other/fiasco/output/Makefile b/converter/other/fiasco/output/Makefile
index fc1d4155..26b6d924 100644
--- a/converter/other/fiasco/output/Makefile
+++ b/converter/other/fiasco/output/Makefile
@@ -6,7 +6,7 @@ FIASCOSUBDIR = converter/other/fiasco
 SUBDIR = $(FIASCOSUBDIR)/output
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 OBJECTS =  matrices.o mc.o nd.o tree.o weights.o write.o
 
@@ -19,7 +19,7 @@ COMP_INCLUDES = \
 
 all: libfiasco_output.a
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 libfiasco_output.a: $(OBJECTS)
 	$(AR) -rc $@ $(OBJECTS)
diff --git a/converter/other/fitstopnm.c b/converter/other/fitstopnm.c
index 86bdfbb8..9df47be3 100644
--- a/converter/other/fitstopnm.c
+++ b/converter/other/fitstopnm.c
@@ -30,6 +30,12 @@
  ** disabled min max scanning when reading from stdin.
  */
 
+/*
+  The official specification of FITS format (which is for more than
+  just visual images) is at
+  ftp://legacy.gsfc.nasa.gov/fits_info/fits_office/fits_standard.pdf
+*/
+
 #include <string.h>
 #include <float.h>
 
@@ -507,6 +513,13 @@ convertPgmRaster(FILE *             const ifP,
                  double             const datamin,
                  xel **             const xels) {
         
+    /* Note: the FITS specification does not give the association between
+       file position and image position (i.e. is the first pixel in the
+       file the top left, bottom left, etc.).  We use the common sense,
+       popular order of row major, top to bottom, left to right.  This
+       has been the case and accepted since 1989, but in 2008, we discovered
+       that Gimp and ImageMagick do bottom to top.
+    */
     unsigned int image;
 
     pm_message("writing PGM file");
diff --git a/converter/other/jbig/Makefile b/converter/other/jbig/Makefile
index 3b87d1cc..b5f4e14a 100644
--- a/converter/other/jbig/Makefile
+++ b/converter/other/jbig/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = converter/other/jbig
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 LIBJBIG_OBJECTS = jbig.o jbig_tab.o
 
@@ -33,7 +33,7 @@ MERGE_OBJECTS = $(BINARIES:%=%.o2) $(LIBJBIG_OBJECTS)
 
 all: $(BINARIES)
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 $(BINARIES): %: %.o $(JBIGLIB_DEP) $(NETPBMLIB) $(LIBOPT)
 	$(LD) -o $@ $< \
diff --git a/converter/other/jpeg2000/Makefile b/converter/other/jpeg2000/Makefile
index af8be82c..f4fee87f 100644
--- a/converter/other/jpeg2000/Makefile
+++ b/converter/other/jpeg2000/Makefile
@@ -7,7 +7,7 @@ VPATH=.:$(SRCDIR)/$(SUBDIR)
 
 SUBDIRS = libjasper
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 EXTERN_INCLUDES =
 ifneq ($(JASPERHDR_DIR),NONE)
@@ -55,7 +55,7 @@ MERGEBINARIES = $(BINARIES)
 .PHONY: all
 all: $(BINARIES)
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 LIBOPTS = $(shell $(LIBOPT) $(NETPBMLIB) $(JASPERLIB_USE))
 
diff --git a/converter/other/jpeg2000/libjasper/Makefile b/converter/other/jpeg2000/libjasper/Makefile
index ad4fbd8f..34d1860a 100644
--- a/converter/other/jpeg2000/libjasper/Makefile
+++ b/converter/other/jpeg2000/libjasper/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = converter/other/jpeg2000/libjasper
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 SUBDIRS = base jp2 jpc
 LIB_OBJECTS =
@@ -17,7 +17,7 @@ JASPERSRCDIR = $(SRCDIR)/$(SUBDIR)
 
 all: libjasper.a
 
-include $(SRCDIR)/$(SUBDIR)/Makefile.common
+include $(SRCDIR)/$(SUBDIR)/common.mk
 
 # We cheat a bit here -- the real dependencies are all the .o files listed
 # in the part list, but since we don't know what those are, we just do a
diff --git a/converter/other/jpeg2000/libjasper/base/Makefile b/converter/other/jpeg2000/libjasper/base/Makefile
index 0ee65b5e..ad84f043 100644
--- a/converter/other/jpeg2000/libjasper/base/Makefile
+++ b/converter/other/jpeg2000/libjasper/base/Makefile
@@ -7,7 +7,7 @@ VPATH=.:$(SRCDIR)/$(SUBDIR)
 
 JASPERSRCDIR=$(SRCDIR)/$(SUBDIR)/..
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 LIB_OBJECTS = jas_debug.o jas_getopt.o jas_image.o jas_init.o \
 	      jas_malloc.o jas_seq.o jas_stream.o jas_string.o \
@@ -17,5 +17,5 @@ MERGE_OBJECTS =
 
 all: partlist $(LIB_OBJECTS)
 
-include $(JASPERSRCDIR)/Makefile.common
+include $(JASPERSRCDIR)/common.mk
 
diff --git a/converter/other/jpeg2000/libjasper/Makefile.common b/converter/other/jpeg2000/libjasper/common.mk
index af82401a..687a9f3f 100644
--- a/converter/other/jpeg2000/libjasper/Makefile.common
+++ b/converter/other/jpeg2000/libjasper/common.mk
@@ -1,4 +1,3 @@
-# -*-makefile-*-    <-- an Emacs control
 # This is common rules for the libjasper subdirectories.
 #
 # Set the following variables before including this:
@@ -19,7 +18,7 @@ $(SUBDIRS:%=%/partlist): %/partlist: $(CURDIR)/%
 	$(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \
 	    SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) 
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 INCLUDES = -I$(JASPERSRCDIR)/include -Iimportinc
 
diff --git a/converter/other/jpeg2000/libjasper/jp2/Makefile b/converter/other/jpeg2000/libjasper/jp2/Makefile
index 254b7f56..65838cc2 100644
--- a/converter/other/jpeg2000/libjasper/jp2/Makefile
+++ b/converter/other/jpeg2000/libjasper/jp2/Makefile
@@ -7,7 +7,7 @@ VPATH=.:$(SRCDIR)/$(SUBDIR)
 
 JASPERSRCDIR=$(SRCDIR)/$(SUBDIR)/..
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 LIB_OBJECTS = jp2_cod.o jp2_dec.o jp2_enc.o
 
@@ -15,5 +15,5 @@ MERGE_OBJECTS =
 
 all: partlist $(LIB_OBJECTS)
 
-include $(JASPERSRCDIR)/Makefile.common
+include $(JASPERSRCDIR)/common.mk
 
diff --git a/converter/other/jpeg2000/libjasper/jpc/Makefile b/converter/other/jpeg2000/libjasper/jpc/Makefile
index e176bd48..ffc4c64f 100644
--- a/converter/other/jpeg2000/libjasper/jpc/Makefile
+++ b/converter/other/jpeg2000/libjasper/jpc/Makefile
@@ -7,7 +7,7 @@ VPATH=.:$(SRCDIR)/$(SUBDIR)
 
 JASPERSRCDIR=$(SRCDIR)/$(SUBDIR)/..
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 LIB_OBJECTS = jpc_bs.o jpc_cs.o jpc_dec.o jpc_enc.o \
 	jpc_math.o jpc_mct.o jpc_mqcod.o jpc_mqdec.o jpc_mqenc.o \
@@ -18,5 +18,5 @@ MERGE_OBJECTS =
 
 all: partlist $(LIB_OBJECTS)
 
-include $(JASPERSRCDIR)/Makefile.common
+include $(JASPERSRCDIR)/common.mk
 
diff --git a/converter/other/pamtofits.c b/converter/other/pamtofits.c
index 04b43c35..7a71ff56 100644
--- a/converter/other/pamtofits.c
+++ b/converter/other/pamtofits.c
@@ -20,6 +20,12 @@
 ** in the FITS header, but do not cause the data to be rescaled.
 */
 
+/*
+  The official specification of FITS format (which is for more than
+  just visual images) is at
+  ftp://legacy.gsfc.nasa.gov/fits_info/fits_office/fits_standard.pdf
+*/
+
 #include <assert.h>
 #include <string.h>
 #include <stdio.h>
@@ -201,6 +207,14 @@ writeRaster(struct pam * const pamP,
             unsigned int const bitpix,
             int          const offset) {
 
+    /* Note: the FITS specification does not give the association between
+       file position and image position (i.e. is the first pixel in the
+       file the top left, bottom left, etc.).  We use the common sense,
+       popular order of row major, top to bottom, left to right.  This
+       has been the case and accepted since 1989, but in 2008, we discovered
+       that Gimp and ImageMagick do bottom to top.
+    */
+
     unsigned int plane;
 
     for (plane = 0; plane < pamP->depth; ++plane) {
diff --git a/converter/other/pamtosvg/Makefile b/converter/other/pamtosvg/Makefile
index ba03fd68..8b033020 100644
--- a/converter/other/pamtosvg/Makefile
+++ b/converter/other/pamtosvg/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = converter/other/pamtosvg
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 BINARIES = pamtosvg
 
@@ -47,7 +47,7 @@ MERGEBINARIES = $(BINARIES)
 
 all: $(BINARIES)
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 pamtosvg: $(PAMTOSVG_OBJECTS) $(NETPBMLIB) $(LIBOPT)
 	$(LD) -o $@ $(PAMTOSVG_OBJECTS) \
diff --git a/converter/other/pgmtopbm.c b/converter/other/pgmtopbm.c
index 36b39017..34cc2c91 100644
--- a/converter/other/pgmtopbm.c
+++ b/converter/other/pgmtopbm.c
@@ -347,6 +347,10 @@ struct converter {
 
 
 
+/*=============================================================================
+                 Converter: fs
+=============================================================================*/
+
 unsigned int const fs_scale      = 1024;
 unsigned int const half_fs_scale = 512;
 
@@ -469,6 +473,10 @@ createFsConverter(unsigned int const cols,
 
 
 
+/*=============================================================================
+                 Converter: thresh
+=============================================================================*/
+
 struct threshState {
     gray threshval;
 };
@@ -522,16 +530,28 @@ createThreshConverter(unsigned int const cols,
 
 
 
+/*=============================================================================
+                 Converter: dither8
+=============================================================================*/
+
+struct dither8State {
+    int dither8[16][16];
+};
+
+
+
 static void
 dither8ConvertRow(struct converter * const converterP,
                   unsigned int       const row,
                   gray                     grayrow[],
                   bit                      bitrow[]) {
 
+    struct dither8State * const stateP = converterP->stateP;
+
     unsigned int col;
 
     for (col = 0; col < converterP->cols; ++col)
-        if (grayrow[col] > dither8[row % 16][col % 16])
+        if (grayrow[col] > stateP->dither8[row % 16][col % 16])
             bitrow[col] = PBM_WHITE;
         else
             bitrow[col] = PBM_BLACK;
@@ -539,29 +559,47 @@ dither8ConvertRow(struct converter * const converterP,
 
 
 
+static void
+dither8Destroy(struct converter * const converterP) {
+
+    struct dither8State * const stateP = converterP->stateP;
+
+    free(stateP);
+}
+
+
+
 static struct converter
 createDither8Converter(unsigned int const cols, 
                        gray         const maxval) {
 
     struct converter converter;
+    struct dither8State * stateP;
 
     unsigned int row;
 
+    MALLOCVAR_NOFAIL(stateP);
+
     converter.cols = cols;
     converter.convertRow = &dither8ConvertRow;
-    converter.destroy = NULL;
+    converter.destroy = dither8Destroy;
+    converter.stateP = stateP;
 
     /* Scale dither matrix. */
     for (row = 0; row < 16; ++row) {
         unsigned int col;
         for (col = 0; col < 16; ++col)
-            dither8[row][col] = dither8[row][col] * maxval / 256;
+            stateP->dither8[row][col] = dither8[row][col] * maxval / 256;
     }
     return converter;
 }
 
 
 
+/*=============================================================================
+                 Converter: cluster
+=============================================================================*/
+
 struct clusterState {
     unsigned int radius;
     int ** clusterMatrix;
diff --git a/converter/other/pnmtoddif.c b/converter/other/pnmtoddif.c
index b80fba4f..ae8c8524 100644
--- a/converter/other/pnmtoddif.c
+++ b/converter/other/pnmtoddif.c
@@ -1,14 +1,4 @@
 /*
- * $Log: pnmtoddif.c,v $
- * Revision 1.6  1993/01/25  08:14:06  neideck
- * Placed into public use form.
- *
- * Revision 1.5  1992/12/02  08:15:18  neideck
- *  Added RCS id.
- *
- */
-
-/*
  * Author:      Burkhard Neidecker-Lutz
  *              Digital CEC Karlsruhe
  *      neideck@nestvx.enet.dec.com 
@@ -31,6 +21,8 @@
 */
 
 #include <string.h>
+
+#include "mallocvar.h"
 #include "pnm.h"
 
 /* The structure we use to convey all sorts of "magic" data to the DDIF */
@@ -414,21 +406,181 @@ write_trailer(FILE * file)
 
 
 
-int main(int argc, char *argv[])
-{
+
+static void
+convertPbmRaster(FILE *          const ifP,
+                 int             const format,
+                 unsigned int    const cols,
+                 unsigned int    const rows,
+                 FILE *          const ofP,
+                 unsigned int    const bytesPerLine,
+                 unsigned char * const data) {
+                 
+    bit * const pixels = pbm_allocrow(cols);
+
+    unsigned int row;
+
+    for (row = 0; row < rows; ++row) {
+        unsigned int col;
+        unsigned int k;
+        unsigned int mask;
+        unsigned char * p;
+        size_t bytesWritten;
+
+        pbm_readpbmrow(ifP, pixels, cols, format);
+
+        mask = 0x00;
+        p = &data[0];
+        for (col = 0, k = 0; col < cols; ++col) {
+            if (pixels[col] == PBM_BLACK)
+                mask |= 1 << k;
+            if (k == 7) {
+                *p++ = mask;
+                mask = 0x00;
+                k = 0;
+            } else
+                ++k;
+        }
+        if (k != 7)
+            /* Flush the rest of the column */
+            *p = mask;
+
+        bytesWritten =  fwrite(data, 1, bytesPerLine, ofP);
+        if (bytesWritten != bytesPerLine)
+            pm_error("File write error on Row %u", row);
+    }
+
+    pbm_freerow(pixels);
+}
+
+
+
+static void
+convertPgmRaster(FILE *          const ifP,
+                 int             const format,
+                 xelval          const maxval,
+                 unsigned int    const cols,
+                 unsigned int    const rows,
+                 FILE *          const ofP,
+                 unsigned int    const bytesPerLine,
+                 unsigned char * const data) {
+
+    gray * const pixels = pgm_allocrow(cols);
+
+    unsigned int row;
+
+    for (row = 0; row < rows; ++row) {
+        unsigned char * p;
+        unsigned int col;
+        size_t bytesWritten;
+
+        p = &data[0];
+
+        pgm_readpgmrow(ifP, pixels, cols, maxval, format);
+
+        for (col = 0; col < cols; ++col)
+            *p++ = (unsigned char) pixels[col];
+
+        bytesWritten = fwrite(data, 1, bytesPerLine, ofP);
+        if (bytesWritten != bytesPerLine)
+            pm_error("File write error on Row %u", row);
+    }
+    pgm_freerow(pixels);
+}
+
+
+
+
+static void
+convertPpmRaster(FILE *          const ifP,
+                 int             const format,
+                 xelval          const maxval,
+                 unsigned int    const cols,
+                 unsigned int    const rows,
+                 FILE *          const ofP,
+                 unsigned int    const bytesPerLine,
+                 unsigned char * const data) {
+
+    pixel * const pixels = ppm_allocrow(cols);
+
+    unsigned int row;
+
+    for (row = 0; row < rows; ++row) {
+        unsigned char * p;
+        unsigned int col;
+        size_t bytesWritten;
+
+        p = &data[0];
+
+        ppm_readppmrow(ifP, pixels, cols, maxval, format);
+
+        for (col = 0; col < cols; ++col) {
+            *p++ = PPM_GETR(pixels[col]);
+            *p++ = PPM_GETG(pixels[col]);
+            *p++ = PPM_GETB(pixels[col]);
+        }
+        bytesWritten =  fwrite(data, 1, bytesPerLine, ofP);
+        if (bytesWritten != bytesPerLine)
+            pm_error("File write error on Row %u", row);
+    }
+    ppm_freerow(pixels);
+}
+
+
+
+static void
+convertRaster(FILE *       const ifP,
+              int          const format,
+              xelval       const maxval,
+              unsigned int const cols,
+              unsigned int const rows,
+              FILE *       const ofP,
+              unsigned int const bytesPerLine) {
+
+    unsigned char * data;
+    unsigned char * p;
+
+    MALLOCARRAY(data, bytesPerLine);
+
+    if (data == NULL)
+        pm_error("Couldn't allocate %u-byte line buffer", bytesPerLine);
+
+    p = data;  /* initial value */
+
+    switch (PNM_FORMAT_TYPE(format)) {
+    case PBM_TYPE:
+        convertPbmRaster(ifP, format, cols, rows, ofP, bytesPerLine, data);
+        break;
+    case PGM_TYPE:
+        convertPgmRaster(ifP, format, maxval, cols, rows, ofP, bytesPerLine,
+                         data);
+        break;
+    case PPM_TYPE:
+        convertPpmRaster(ifP, format, maxval, cols, rows, ofP, bytesPerLine,
+                         data);
+        break;
+    default:
+        pm_error("INTERNAL ERROR: impossible format value");
+    }
+
+    free(data);
+}
+
+
+
+int
+main(int argc, char *argv[]) {
     FILE           *ifd;
-    FILE       *ofd;
+    FILE           *ofd;
     int             rows, cols;
     xelval          maxval;
     int             format;
     const char     * const usage = "[-resolution x y] [pnmfile [ddiffile]]";
-    int             i, j;
     char           *outfile;
     int       argn;
     int hor_resolution = 75;
     int ver_resolution = 75;
     imageparams ip;
-    unsigned char  *data, *p;
 
     pnm_init(&argc, argv);
 
@@ -512,90 +664,10 @@ int main(int argc, char *argv[])
         exit(1);
     }
 
-    if (!(p = data = (unsigned char*)  malloc(ip.bytes_per_line))) {
-        perror("allocating line buffer");
-        exit(1);
-    }
-
-    switch (PNM_FORMAT_TYPE(format)) {
-    case PBM_TYPE:
-    {
-        bit            *pixels;
-        int             mask;
-        int             k;
-
-        pixels = pbm_allocrow(cols);
-
-        for (i = 0; i < rows; i++) {
-            pbm_readpbmrow(ifd, pixels, cols, format);
-            mask = 0;
-            p = data;
-            for (j = 0, k = 0; j < cols; j++) {
-                if (pixels[j] == PBM_BLACK) {
-                    mask |= 1 << k;
-                }
-                if (k == 7) {
-                    *p++ = mask;
-                    mask = 0;
-                    k = 0;
-                } else {
-                    k++;
-                }
-            }
-            if (k != 7) {       /* Flush the rest of the column */
-                *p = mask;
-            }
-            if (fwrite(data,1,ip.bytes_per_line,ofd) != ip.bytes_per_line) {
-                perror("Writing image data\n");
-                exit(1);
-            }
-        }
-    }
-    break;
-    case PGM_TYPE:
-    {
-        gray          *pixels = pgm_allocrow(cols);
-
-        for (i = 0; i < rows; i++) {
-            p = data;
-            pgm_readpgmrow(ifd, pixels, cols, maxval, format);
-            for (j = 0; j < cols; j++) {
-                *p++ = (unsigned char) pixels[j];
-            }
-            if (fwrite(data,1,ip.bytes_per_line,ofd) != ip.bytes_per_line) {
-                perror("Writing image data\n");
-                exit(1);
-            }
-        }
-        pgm_freerow(pixels);
-    }
-    break;
-    case PPM_TYPE:
-    {
-        pixel          *pixels = ppm_allocrow(cols);
-
-        for (i = 0; i < rows; i++) {
-            p = data;
-            ppm_readppmrow(ifd, pixels, cols, maxval, format);
-            for (j = 0; j < cols; j++) {
-                *p++ = PPM_GETR(pixels[j]);
-                *p++ = PPM_GETG(pixels[j]);
-                *p++ = PPM_GETB(pixels[j]);
-            }
-            if (fwrite(data,1,ip.bytes_per_line,ofd) != ip.bytes_per_line) {
-                perror("Writing image data\n");
-                exit(1);
-            }
-        }
-        ppm_freerow(pixels);
-    }
-    break;
-    }
+    convertRaster(ifd, format, maxval, cols, rows, ofd, ip.bytes_per_line);
 
     pm_close(ifd);
 
-    free(data);
-
     if (!write_trailer(ofd)) {
         perror("Writing trailer");
         exit(1);
diff --git a/converter/other/pnmtojpeg.c b/converter/other/pnmtojpeg.c
index eb57bcc5..3110542d 100644
--- a/converter/other/pnmtojpeg.c
+++ b/converter/other/pnmtojpeg.c
@@ -435,49 +435,56 @@ text_getc (FILE * file)
 
 
 static boolean
-read_text_integer (FILE * file, long * result, int * termchar)
-/* Read an unsigned decimal integer from a file, store it in result */
-/* Reads one trailing character after the integer; returns it in termchar */
-{
-    register int ch;
-    register long val;
+readTextInteger(FILE * const fileP,
+                long * const resultP,
+                int *  const termcharP) {
+/*----------------------------------------------------------------------------
+   Read the next unsigned decimal integer from file 'fileP', skipping
+   white space as necessary.  Return it as *resultP.
+
+   Also read one character after the integer and return it as *termcharP.
+
+   If there is no character after the integer, return *termcharP == EOF.
+
+   Iff the next thing in the file is not a valid unsigned decimal integer,
+   return FALSE.
+-----------------------------------------------------------------------------*/
+    int ch;
+    boolean retval;
   
     /* Skip any leading whitespace, detect EOF */
     do {
-        ch = text_getc(file);
-        if (ch == EOF) {
-            *termchar = ch;
-            return FALSE;
-        }
+        ch = text_getc(fileP);
     } while (isspace(ch));
   
-    if (! isdigit(ch)) {
-        *termchar = ch;
-        return FALSE;
-    }
-
-    val = ch - '0';
-    while ((ch = text_getc(file)) != EOF) {
-        if (! isdigit(ch))
-            break;
-        val *= 10;
-        val += ch - '0';
+    if (!isdigit(ch))
+        retval = FALSE;
+    else {
+        long val;
+        val = ch - '0';  /* initial value */
+        while ((ch = text_getc(fileP)) != EOF) {
+            if (! isdigit(ch))
+                break;
+            val *= 10;
+            val += ch - '0';
+        }
+        *resultP = val;
+        retval = TRUE;
     }
-    *result = val;
-    *termchar = ch;
-    return TRUE;
+    *termcharP = ch;
+    return retval;
 }
 
 
 static boolean
 read_scan_integer (FILE * file, long * result, int * termchar)
-/* Variant of read_text_integer that always looks for a non-space termchar;
+/* Variant of readTextInteger that always looks for a non-space termchar;
  * this simplifies parsing of punctuation in scan scripts.
  */
 {
     register int ch;
 
-    if (! read_text_integer(file, result, termchar))
+    if (! readTextInteger(file, result, termchar))
         return FALSE;
     ch = *termchar;
     while (ch != EOF && isspace(ch))
@@ -625,45 +632,59 @@ read_quant_tables (j_compress_ptr cinfo, char * filename,
  */
 {
     FILE * fp;
-    int tblno, i, termchar;
-    long val;
-    unsigned int table[DCTSIZE2];
+    boolean retval;
 
-    if ((fp = fopen(filename, "rb")) == NULL) {
+    fp = fopen(filename, "rb");
+    if (fp == NULL) {
         pm_message("Can't open table file %s", filename);
-        return FALSE;
-    }
-    tblno = 0;
-
-    while (read_text_integer(fp, &val, &termchar)) {
-        /* read 1st element of table */
-        if (tblno >= NUM_QUANT_TBLS) {
-            pm_message("Too many tables in file %s", filename);
-            fclose(fp);
-            return FALSE;
-        }
-        table[0] = (unsigned int) val;
-        for (i = 1; i < DCTSIZE2; i++) {
-            if (! read_text_integer(fp, &val, &termchar)) {
-                pm_message("Invalid table data in file %s", filename);
-                fclose(fp);
-                return FALSE;
+        retval = FALSE;
+    } else {
+        boolean eof, error;
+        unsigned int tblno;
+
+        for (tblno = 0, eof = FALSE, error = FALSE; !eof && !error; ++tblno) {
+            long val;
+            int termchar;
+            boolean gotOne;
+
+            gotOne = readTextInteger(fp, &val, &termchar);
+            if (gotOne) {
+                /* read 1st element of table */
+                if (tblno >= NUM_QUANT_TBLS) {
+                    pm_message("Too many tables in file %s", filename);
+                    error = TRUE;
+                } else { 
+                    unsigned int table[DCTSIZE2];
+                    unsigned int i;
+
+                    table[0] = (unsigned int) val;
+                    for (i = 1; i < DCTSIZE2 && !error; ++i) {
+                        if (! readTextInteger(fp, &val, &termchar)) {
+                            pm_message("Invalid table data in file %s",
+                                       filename);
+                            error = TRUE;
+                        } else
+                            table[i] = (unsigned int) val;
+                    }
+                    if (!error)
+                        jpeg_add_quant_table(
+                            cinfo, tblno, table, scale_factor, force_baseline);
+                }
+            } else {
+                if (termchar == EOF)
+                    eof = TRUE;
+                else {
+                    pm_message("Non-numeric data in file %s", filename);
+                    error = TRUE;
+                }
             }
-            table[i] = (unsigned int) val;
         }
-        jpeg_add_quant_table(cinfo, tblno, table, scale_factor, 
-                             force_baseline);
-        tblno++;
-    }
 
-    if (termchar != EOF) {
-        pm_message("Non-numeric data in file %s", filename);
         fclose(fp);
-        return FALSE;
+        retval = !error;
     }
-
-    fclose(fp);
-    return TRUE;
+        
+    return retval;
 }
 
 
@@ -1082,7 +1103,7 @@ main(int     argc,
 
     /* Close files, if we opened them */
     if (input_file != stdin)
-        fclose(input_file);
+        pm_close(input_file);
 
     /* Program may have exited with non-zero completion code via
        various function calls above. 
diff --git a/converter/other/pnmtopalm/Makefile b/converter/other/pnmtopalm/Makefile
index ebfa3573..7f99f95a 100644
--- a/converter/other/pnmtopalm/Makefile
+++ b/converter/other/pnmtopalm/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = converter/other/pnmtopalm
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 BINARIES = palmtopnm pnmtopalm
 SCRIPTS =
@@ -16,7 +16,7 @@ DATAFILES = palmcolor8.map palmgray1.map palmgray2.map palmgray4.map
 
 all: $(BINARIES)
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 LIBOPTS = $(shell $(LIBOPT) $(NETPBMLIB))
 
diff --git a/converter/other/pnmtorle.c b/converter/other/pnmtorle.c
index 8c6dc589..180b144f 100644
--- a/converter/other/pnmtorle.c
+++ b/converter/other/pnmtorle.c
@@ -59,8 +59,8 @@ static gray    maxval;
  *                                        Read the pnm image file header.
  */
 static void 
-read_pnm_header()
-{
+read_pnm_header(void) {
+
     pnm_readpnminit(fp, &width, &height, &maxval, &format);
     switch (format) {
     case PBM_FORMAT:
@@ -87,12 +87,12 @@ read_pnm_header()
     if (do_alpha)
         VPRINTF(stderr, "Computing alpha channel...\n");
 }
-/*-----------------------------------------------------------------------------
- *                                             Write the rle image file header.
- */
+
+
+
 static void 
-write_rle_header()
-{
+write_rle_header(void) {
+
     hdr.xmin    = 0;
     hdr.xmax    = width-1;
     hdr.ymin    = 0;
@@ -120,102 +120,107 @@ write_rle_header()
     }
     rle_put_setup(&hdr);
 }
-/*-----------------------------------------------------------------------------
- *                                      Write the rle data portion of the file.
- */
+
+
+
 static void 
-write_rle_data()
-{
-    register int     x;
-    register int     scan;
-    register xel     *xelrow, *pP;
-    rle_pixel        ***scanlines, **scanline;
-/*
- * Allocate some memory.
- */
-    /*xelrow = pnm_allowcrow(width);*/
-    xelrow = (xel*) pm_allocrow( width, sizeof(xel) );
+write_rle_data(void) {
+
+    unsigned int scan;
+    xel * xelrow;
+    rle_pixel *** scanlines;
+
+    MALLOCARRAY(xelrow, width);
     MALLOCARRAY(scanlines, height);
-    RLE_CHECK_ALLOC( hdr.cmd, scanlines, "scanline pointers" );
 
-    for ( scan = 0; scan < height; scan++ )
-        RLE_CHECK_ALLOC( hdr.cmd, (rle_row_alloc(&hdr, &scanlines[scan]) >= 0),
-                         "pixel memory" );
-/*
- * Loop through the pnm files image window, read data and flip vertically.
- */
+    RLE_CHECK_ALLOC(hdr.cmd, scanlines, "scanline pointers");
+
+    for (scan = 0; scan < height; ++scan) {
+        int rc;
+        rc = rle_row_alloc(&hdr, &scanlines[scan]);
+        RLE_CHECK_ALLOC(hdr.cmd, rc >= 0, "pixel memory");
+    }
+    /* Loop through the pnm files image window, read data and flip vertically.
+     */
     switch (format) {
     case PBM_FORMAT:
-    case RPBM_FORMAT:
-        for (scan = 0; scan < height; scan++) {
-            scanline = scanlines[height - scan - 1];
+    case RPBM_FORMAT: {
+        unsigned int scan;
+        for (scan = 0; scan < height; ++scan) {
+            rle_pixel ** const scanline = scanlines[height - scan - 1];
+            unsigned int col;
             pnm_readpnmrow(fp, xelrow, width, maxval, format);
-            for (x = 0, pP = xelrow; x < width; x++, pP++) {
-                scanline[RLE_RED][x]   = (PNM_GET1(*pP) ? 255 : 0);
-                if (do_alpha) {
-                    scanline[RLE_ALPHA][x] = scanline[RLE_RED][x];
-                }
+            for (col = 0; col < width; ++col) {
+                scanline[RLE_RED][col] = PNM_GET1(xelrow[col]) ? 255 : 0;
+                if (do_alpha)
+                    scanline[RLE_ALPHA][col] = scanline[RLE_RED][col];
             }
         }
-        break;
+    } break;
     case PGM_FORMAT:
-    case RPGM_FORMAT:
-        for (scan = 0; scan < height; scan++) {
-            scanline = scanlines[height - scan - 1];
+    case RPGM_FORMAT: {
+        unsigned int scan;
+        for (scan = 0; scan < height; ++scan) {
+            rle_pixel ** const scanline = scanlines[height - scan - 1];
+            unsigned int col;
             pnm_readpnmrow(fp, xelrow, width, maxval, format);
-            for (x = 0, pP = xelrow; x < width; x++, pP++) {
-                scanline[RLE_RED][x]   = PNM_GET1(*pP);
-                if (do_alpha) {
-                    scanline[RLE_ALPHA][x] = (scanline[RLE_RED][x] ? 255 : 0);
-                }
+            for (col = 0; col < width; ++col) {
+                scanline[RLE_RED][col] = PNM_GET1(xelrow[col]);
+                if (do_alpha)
+                    scanline[RLE_ALPHA][col] =
+                        scanline[RLE_RED][col] ? 255 : 0;
             }
         }
-        break;
+    } break;
     case PPM_FORMAT:
-    case RPPM_FORMAT:
+    case RPPM_FORMAT: {
+        unsigned int scan;
         for (scan = 0; scan < height; scan++) {
-            scanline = scanlines[height - scan - 1];
+            rle_pixel ** const scanline = scanlines[height - scan - 1];
+            unsigned int col;
             pnm_readpnmrow(fp, xelrow, width, maxval, format);
-            for (x = 0, pP = xelrow; x < width; x++, pP++) {
-                scanline[RLE_RED][x]   = PPM_GETR(*pP);
-                scanline[RLE_GREEN][x] = PPM_GETG(*pP);
-                scanline[RLE_BLUE][x]  = PPM_GETB(*pP);
-                if (do_alpha) {
-                    scanline[RLE_ALPHA][x] = (scanline[RLE_RED][x] ||
-                                              scanline[RLE_GREEN][x] ||
-                                              scanline[RLE_BLUE][x] ? 255 : 0);
-                }
+            for (col = 0; col < width; ++col) {
+                scanline[RLE_RED][col]   = PPM_GETR(xelrow[col]);
+                scanline[RLE_GREEN][col] = PPM_GETG(xelrow[col]);
+                scanline[RLE_BLUE][col]  = PPM_GETB(xelrow[col]);
+                if (do_alpha)
+                    scanline[RLE_ALPHA][col] =
+                        (scanline[RLE_RED][col] ||
+                         scanline[RLE_GREEN][col] ||
+                         scanline[RLE_BLUE][col] ? 255 : 0);
             }
         }
-        break;
+        } break;
     }
-/*
- * Write out data in URT order (bottom to top).
- */
-    for ( scan = 0; scan < height; scan++ ) {
+    /* Write out data in URT order (bottom to top). */
+    for (scan = 0; scan < height; ++scan)
         rle_putrow(scanlines[scan], width, &hdr);
-        rle_row_free( &hdr, scanlines[scan] );
-    }
-    free( scanlines );
+
+    for (scan = 0; scan < height; ++scan)
+        rle_row_free(&hdr, scanlines[scan]);
+    free(scanlines);
+    free(xelrow);
 
     VPRINTF(stderr, "Done -- write eof to RLE data.\n");
     rle_puteof(&hdr);
 }
 
+
+
 int
-main(argc, argv)
-    int argc;
-    char **argv;
-{
-    char     *pnmname = NULL, *outname = NULL;
-    static char  filename[BUFSIZ];
-    int      oflag, c;
+main(int argc, char **  argv) {
+
+    const char * pnmname;
+    const char * outname;
+    static char filename[BUFSIZ];
+    int oflag;
 
     pnm_init(&argc, argv);
 
-/*
- * Get those options.
- */
+    pnmname = NULL;  /* initial value */
+    outname = NULL;  /* initial value */
+
+    /* Get those options. */
     if (!scanargs(argc,argv,
                   "% v%- h%- a%- o%-outfile!s pnmfile%s\n(\
 \tConvert a PNM file to URT RLE format.\n\
@@ -229,39 +234,34 @@ main(argc, argv)
                   &pnmname))
         exit(-1);
 
-    hdr = *rle_hdr_init( (rle_hdr *)NULL );
-    rle_names( &hdr, cmd_name( argv ), outname, 0 );
-/*
- * Open the file.
- */
+    hdr = *rle_hdr_init(NULL);
+    rle_names(&hdr, cmd_name(argv), outname, 0);
+
+    /* Open the file. */
     if (pnmname == NULL) {
         strcpy(filename, "stdin");
-        fp = stdin;
-    }
-    else {
+        fp = pm_openr("-");
+    } else {
         strcpy(filename, pnmname);
         fp = pm_openr(filename);
     }
 
     hdr.rle_file = rle_open_f( hdr.cmd, outname, "wb" );
-    while ( (c = getc( fp )) != EOF ) {
-        ungetc( c, fp );
-/*
- * Read the PPM file header.
- */
+
+    if (header)
         read_pnm_header();
-        if (header)
-            break;
-/*
- * Write the rle file header.
- */
-        rle_addhist(argv, (rle_hdr *)NULL, &hdr);
-        write_rle_header();
-/*
- * Write the rle file data.
- */
-        write_rle_data();
+    else {
+        int eof;
+        for (eof = 0; !eof; ) {
+            read_pnm_header();
+            rle_addhist(argv, NULL, &hdr);
+            write_rle_header();
+            write_rle_data();
+            
+            pnm_nextimage(fp, &eof);
+        }
     }
-    fclose(fp);
+    pm_close(fp);
+
     return 0;
 }
diff --git a/converter/other/svgtopam.c b/converter/other/svgtopam.c
index 56825a4e..5e276f6c 100644
--- a/converter/other/svgtopam.c
+++ b/converter/other/svgtopam.c
@@ -18,12 +18,12 @@
 
   Implementation notes:
 
-   We've seen a version of <libxml/xmlreader.h> that does not
-   define type 'xmlReaderTypes'.  The system claimed to have
-   Libxml2 2.6.16 installed, but another system that makes that
-   claim _does_ have 'xmlReaderTypes' defined, so I don't know what
-   version actually has the problem.
-
+   A look at Libxml2 Subversion source code change history says the type
+   'xmlReaderTypes' was added (in <libxml/xmlreader.h>) in 2.5.9.  But a MacOS
+   10.3.9 user reports in April 2007 that he has 2.6.16 installed and it
+   doesn't have xmlReaderTypes.  Another MacOS user reported that in December
+   2008.  Apparently that OS has a broken libxml2 installation.
+   
 ============================================================================*/
 
 #define _BSD_SOURCE  /* Make sure strdup() is in <string.h> */
diff --git a/converter/pbm/Makefile b/converter/pbm/Makefile
index f1533ab2..c859b105 100644
--- a/converter/pbm/Makefile
+++ b/converter/pbm/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = converter/pbm
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 PORTBINARIES =	atktopbm brushtopbm cmuwmtopbm ddbugtopbm g3topbm escp2topbm \
 		icontopbm macptopbm mdatopbm mgrtopbm mrftopbm \
@@ -41,7 +41,7 @@ SUBDIRS=pbmtoppa
 .PHONY: all
 all: $(BINARIES) $(SUBDIRS:%=%/all)
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 ifneq ($(LEX)x,x)
 thinkjettopbm.c1:%.c1:%.l
diff --git a/converter/pbm/g3topbm.c b/converter/pbm/g3topbm.c
index 2d2c6a42..3858dc7a 100644
--- a/converter/pbm/g3topbm.c
+++ b/converter/pbm/g3topbm.c
@@ -656,8 +656,8 @@ analyzeLineSize(lineSizeAnalyzer * const analyzerP,
 
 
 /* An empty line means EOF.  An ancient comment in the code said there
-   is supposed to 6 EOL marks in a row to indicate EOF, but the code
-   checked for 3 and considered 2 in row just to mean a zero length
+   is supposed to be 6 EOL marks in a row to indicate EOF, but the code
+   checked for 3 and considered 2 in a row just to mean a zero length
    line.  Starting in Netpbm 10.24 (August 2004), we assume there is
    no valid reason to have an empty line and recognize EOF as any
    empty line.  Alternatively, we could read off and ignore two empty
diff --git a/converter/pbm/pbmtoppa/Makefile b/converter/pbm/pbmtoppa/Makefile
index ba15adaa..5f205230 100644
--- a/converter/pbm/pbmtoppa/Makefile
+++ b/converter/pbm/pbmtoppa/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = converter/pbm/pbmtoppa
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 all: pbmtoppa
 
@@ -16,7 +16,7 @@ MERGEBINARIES = $(BINARIES)
 OBJECTS = pbmtoppa.o ppa.o pbm.o cutswath.o
 MERGE_OBJECTS = pbmtoppa.o2 ppa.o pbm.o cutswath.o
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 pbmtoppa: $(OBJECTS) $(NETPBMLIB) $(LIBOPT)
 	$(LD) -o pbmtoppa $(OBJECTS) \
diff --git a/converter/pgm/Makefile b/converter/pgm/Makefile
index f562fe92..b109683b 100644
--- a/converter/pgm/Makefile
+++ b/converter/pgm/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = converter/pgm
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 PORTBINARIES =	asciitopgm bioradtopgm fstopgm hipstopgm \
 		lispmtopgm pgmtofs pgmtolispm pgmtopgm \
@@ -20,4 +20,4 @@ MERGE_OBJECTS = $(MERGEBINARIES:%=%.o2)
 .PHONY: all
 all: $(BINARIES)
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
diff --git a/converter/ppm/Makefile b/converter/ppm/Makefile
index 31ca826b..adc3a400 100644
--- a/converter/ppm/Makefile
+++ b/converter/ppm/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = converter/ppm
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 SUBDIRS = hpcdtoppm ppmtompeg
 
@@ -42,7 +42,7 @@ MERGE_OBJECTS = $(BINARIES:%=%.o2)
 .PHONY: all
 all: $(BINARIES) $(SUBDIRS:%=%/all)
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 ppmtobmp.o ppmtobmp.o2: bmp.h
 
diff --git a/converter/ppm/hpcdtoppm/Makefile b/converter/ppm/hpcdtoppm/Makefile
index 9a7c67d0..91aefc5b 100644
--- a/converter/ppm/hpcdtoppm/Makefile
+++ b/converter/ppm/hpcdtoppm/Makefile
@@ -5,14 +5,14 @@ endif
 SUBDIR = converter/ppm/hpcdtoppm
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 all: hpcdtoppm
 
 SCRIPTS = hpcdtoppm pcdovtoppm
 MERGE_OBJECTS =
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 install: install.bin.local
 .PHONY: install.bin.local
diff --git a/converter/ppm/ppmtobmp.c b/converter/ppm/ppmtobmp.c
index b9ac063e..0e7a8328 100644
--- a/converter/ppm/ppmtobmp.c
+++ b/converter/ppm/ppmtobmp.c
@@ -18,15 +18,23 @@
 
 #include <assert.h>
 #include <string.h>
-#include "bmp.h"
-#include "ppm.h"
+
+#include "mallocvar.h"
 #include "shhopt.h"
+#include "bmp.h"
 #include "bitio.h"
+#include "ppm.h"
 
 #define MAXCOLORS 256
 
 enum colortype {TRUECOLOR, PALETTE};
 
+struct rgb {
+    unsigned char red;
+    unsigned char grn;
+    unsigned char blu;
+};
+
 typedef struct {
 /*----------------------------------------------------------------------------
    A color map for a BMP file.
@@ -34,13 +42,13 @@ typedef struct {
     unsigned int count;
         /* Number of colors in the map.  The first 'count' elements of these
            arrays are defined; all others are not.
+
+           At most MAXCOLORS.
         */
     colorhash_table cht;
 
-    /* Indices in the following arrays are the same as in 'cht', above. */
-    unsigned char red[MAXCOLORS];
-    unsigned char grn[MAXCOLORS];
-    unsigned char blu[MAXCOLORS];
+    /* Indices in the following array are the same as in 'cht', above. */
+    struct rgb bmpMap[MAXCOLORS];
 } colorMap;
 
 
@@ -54,7 +62,7 @@ freeColorMap(const colorMap * const colorMapP) {
 
 
 
-static struct cmdline_info {
+struct cmdlineInfo {
     /* All the information the user supplied in the command line,
        in a form easy for the program to use.
     */
@@ -62,63 +70,71 @@ static struct cmdline_info {
     int class;  /* C_WIN or C_OS2 */
     unsigned int bppSpec;
     unsigned int bpp;
-} cmdline;
+    const char * mapfile;
+};
 
 
 static void
-parse_command_line(int argc, char ** argv,
-                   struct cmdline_info *cmdline_p) {
+parseCommandLine(int argc, const char ** argv,
+                 struct cmdlineInfo * const cmdlineP) {
 /*----------------------------------------------------------------------------
    Note that many of the strings that this function returns in the
    *cmdline_p structure are actually in the supplied argv array.  And
    sometimes, one of these strings is actually just a suffix of an entry
    in argv!
 -----------------------------------------------------------------------------*/
-    optEntry *option_def = malloc(100*sizeof(optEntry));
+    optEntry * option_def;
         /* Instructions to OptParseOptions3 on how to parse our options.
          */
     optStruct3 opt;
 
-    unsigned int windowsSpec, os2Spec;
+    unsigned int windowsSpec, os2Spec, mapfileSpec;
 
     unsigned int option_def_index;
+    
+    MALLOCARRAY(option_def, 100);
 
     option_def_index = 0;   /* incremented by OPTENTRY */
     OPTENT3('w', "windows",   OPT_FLAG, NULL, &windowsSpec,            0);
     OPTENT3('o', "os2",       OPT_FLAG, NULL, &os2Spec,                0);
-    OPTENT3(0,   "bpp",       OPT_UINT, &cmdline_p->bpp, 
-            &cmdline_p->bppSpec,      0);
+    OPTENT3(0,   "bpp",       OPT_UINT, &cmdlineP->bpp, 
+            &cmdlineP->bppSpec,      0);
+    OPTENT3(0,   "mapfile",   OPT_STRING, &cmdlineP->mapfile, 
+            &mapfileSpec,             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 */
 
-    optParseOptions3(&argc, argv, opt, sizeof(opt), 0);
+    optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
 
     if (windowsSpec && os2Spec) 
         pm_error("Can't specify both -windows and -os2 options.");
     else if (windowsSpec) 
-        cmdline_p->class = C_WIN;
+        cmdlineP->class = C_WIN;
     else if (os2Spec)
-        cmdline_p->class = C_OS2;
+        cmdlineP->class = C_OS2;
     else 
-        cmdline_p->class = C_WIN;
+        cmdlineP->class = C_WIN;
 
 
-    if (cmdline_p->bppSpec) {
-        if (cmdline_p->bpp != 1 && cmdline_p->bpp != 4 && 
-            cmdline_p->bpp != 8 && cmdline_p->bpp != 24)
-        pm_error("Invalid -bpp value specified: %u.  The only values valid\n"
+    if (cmdlineP->bppSpec) {
+        if (cmdlineP->bpp != 1 && cmdlineP->bpp != 4 && 
+            cmdlineP->bpp != 8 && cmdlineP->bpp != 24)
+        pm_error("Invalid -bpp value specified: %u.  The only values valid "
                  "in the BMP format are 1, 4, 8, and 24 bits per pixel",
-                 cmdline_p->bpp);
+                 cmdlineP->bpp);
     }
 
+    if (!mapfileSpec)
+        cmdlineP->mapfile = NULL;
+
     if (argc - 1 == 0)
-        cmdline_p->input_filename = strdup("-");  /* he wants stdin */
+        cmdlineP->input_filename = strdup("-");  /* he wants stdin */
     else if (argc - 1 == 1)
-        cmdline_p->input_filename = strdup(argv[1]);
+        cmdlineP->input_filename = strdup(argv[1]);
     else 
-        pm_error("Too many arguments.  The only argument accepted\n"
+        pm_error("Too many arguments.  The only argument accepted "
                  "is the input file specificaton");
 
 }
@@ -243,7 +259,7 @@ BMPwriteinfoheader(FILE *        const fp,
 
 
 static int
-BMPwritergb(FILE * const fp, 
+BMPwriteRgb(FILE * const fp, 
             int    const class, 
             pixval const R, 
             pixval const G, 
@@ -264,7 +280,7 @@ BMPwritergb(FILE * const fp,
         PutByte(fp, R);
         return 3;
     default:
-        pm_error(er_internal, "BMPwritergb");
+        pm_error(er_internal, "BMPwriteRgb");
     }
     return -1;
 }
@@ -272,101 +288,118 @@ BMPwritergb(FILE * const fp,
 
 
 static int
-BMPwritecolormap(FILE *           const ifP, 
+BMPwriteColormap(FILE *           const ifP, 
                  int              const class, 
                  int              const bpp,
                  const colorMap * const colorMapP) {
 /*----------------------------------------------------------------------------
   Return the number of bytes written, or -1 on error.
 -----------------------------------------------------------------------------*/
-    long const ncolors = (1 << bpp);
+    unsigned int const ncolors = (1 << bpp);
 
-    unsigned int  nbyte;
-    unsigned int  i;
+    unsigned int nbyte;
+    unsigned int i;
 
-    nbyte = 0;
-    for (i = 0; i < colorMapP->count; ++i)
-        nbyte += BMPwritergb(ifP, class,
-                             colorMapP->red[i],
-                             colorMapP->grn[i],
-                             colorMapP->blu[i]);
+    assert(ncolors <= MAXCOLORS);
+    assert(ncolors <= ARRAY_SIZE(colorMapP->bmpMap));
 
+    nbyte = 0;
+    for (i = 0; i < colorMapP->count; ++i) {
+        const struct rgb * const mapEntryP = &colorMapP->bmpMap[i];
+        nbyte += BMPwriteRgb(ifP, class,
+                             mapEntryP->red, mapEntryP->grn, mapEntryP->blu);
+    }
     for (; i < ncolors; ++i)
-        nbyte += BMPwritergb(ifP, class, 0, 0, 0);
+        nbyte += BMPwriteRgb(ifP, class, 0, 0, 0);
 
     return nbyte;
 }
 
 
 
-static int
-BMPwriterow_palette(FILE *          const fp, 
+static void
+lookupColor(colorhash_table const cht,
+            pixel           const color,
+            unsigned int *  const colorIndexP) {
+
+    int rc;
+
+    rc = ppm_lookupcolor(cht, &color);
+
+    if (rc < 0)
+        pm_error("Color (%u,%u,%u) is not in the provided palette",
+                 PPM_GETR(color), PPM_GETG(color), PPM_GETB(color));
+    else
+        *colorIndexP = rc;
+}
+
+
+
+static void
+bmpWriteRow_palette(FILE *          const fp, 
                     const pixel *   const row, 
-                    unsigned long   const cx, 
+                    unsigned int    const cols,
                     unsigned short  const bpp, 
-                    colorhash_table const cht) {
+                    colorhash_table const cht,
+                    unsigned int *  const nBytesP) {
 /*----------------------------------------------------------------------------
-  Return the number of bytes written, or -1 on error.
+   Write a row to the raster in paletted format.
+
+   Return the number of bytes written as *nBytesP.
 -----------------------------------------------------------------------------*/
-    BITSTREAM    b;
-    int retval;
+    BITSTREAM b;
     
     b = pm_bitinit(fp, "w");
     if (b == NULL)
-        retval = -1;
+        pm_error("Failed to initialize output file for output");
     else {
+        int rc;
         unsigned int nbyte;
-        unsigned int x;
-        bool         error;
+        unsigned int col;
         
         nbyte = 0;      /* initial value */
-        error = FALSE;  /* initial value */
         
-        for (x = 0; x < cx && !error; ++x) {
+        for (col = 0; col < cols; ++col) {
+            unsigned int colorIndex;
             int rc;
-            rc = pm_bitwrite(b, bpp, ppm_lookupcolor(cht, &row[x]));
+
+            lookupColor(cht, row[col], &colorIndex);
+
+            rc = pm_bitwrite(b, bpp, colorIndex);
             if (rc == -1)
-                error = TRUE;
+                pm_error("Failed in writing a pixel "
+                         "to the raster in the output file");
             else
                 nbyte += rc;
         }
-        if (error)
-            retval = -1;
-        else {
-            int rc;
 
-            rc = pm_bitfini(b);
-            if (rc == -1)
-                retval = -1;
-            else {
-                nbyte += rc;
+        rc = pm_bitfini(b);
+
+        nbyte += rc;
                 
-                /* Make sure we write a multiple of 4 bytes.  */
-                while (nbyte % 4 != 0) {
-                    PutByte(fp, 0);
-                    ++nbyte;
-                }
-                retval = nbyte;
-            }
+        /* Make sure we write a multiple of 4 bytes.  */
+        while (nbyte % 4 != 0) {
+            PutByte(fp, 0);
+            ++nbyte;
         }
+        *nBytesP = nbyte;
     }
-    return retval;
 }
 
 
 
-static int
-BMPwriterow_truecolor(FILE *        const fp, 
-                      const pixel * const row, 
-                      unsigned long const cols,
-                      pixval        const maxval) {
+static void
+bmpWriteRow_truecolor(FILE *         const fp, 
+                      const pixel *  const row, 
+                      unsigned long  const cols,
+                      pixval         const maxval,
+                      unsigned int * const nBytesP) {
 /*----------------------------------------------------------------------------
   Write a row of a truecolor BMP image to the file 'fp'.  The row is 
   'row', which is 'cols' columns long.
 
-  Return the number of bytes written.
 
-  On error, issue error message and exit program.
+  Return the number of bytes written as *nBytesP.
 -----------------------------------------------------------------------------*/
     /* This works only for 24 bits per pixel.  To implement this for the
        general case (which is only hypothetical -- this program doesn't
@@ -380,7 +413,7 @@ BMPwriterow_truecolor(FILE *        const fp,
     int col;  
         
     nbyte = 0;  /* initial value */
-    for (col = 0; col < cols; col++) {
+    for (col = 0; col < cols; ++col) {
         /* We scale to the BMP maxval, which is always 255. */
         PutByte(fp, PPM_GETB(row[col]) * 255 / maxval);
         PutByte(fp, PPM_GETG(row[col]) * 255 / maxval);
@@ -393,18 +426,18 @@ BMPwriterow_truecolor(FILE *        const fp,
      */
     while (nbyte % 4) {
         PutByte(fp, 0);
-        nbyte++;
+        ++nbyte;
     }
     
-    return nbyte;
+    *nBytesP = nbyte;
 }
 
 
 
 static int
 BMPwritebits(FILE *          const fp, 
-             unsigned long   const cx, 
-             unsigned long   const cy, 
+             unsigned long   const cols, 
+             unsigned long   const rows,
              enum colortype  const colortype,
              unsigned short  const cBitCount, 
              const pixel **  const pixels, 
@@ -413,29 +446,29 @@ BMPwritebits(FILE *          const fp,
 /*----------------------------------------------------------------------------
   Return the number of bytes written, or -1 on error.
 -----------------------------------------------------------------------------*/
-    int  nbyte;
-    long y;
+    unsigned int nbyte;
+    int row;
 
     if (cBitCount > 24)
-        pm_error("cannot handle cBitCount: %d", cBitCount);
+        pm_error("cannot handle cBitCount: %hu", cBitCount);
 
     nbyte = 0;  /* initial value */
 
     /* The picture is stored bottom line first, top line last */
 
-    for (y = cy - 1; y >= 0; --y) {
-        int rc;
+    for (row = rows - 1; row >= 0; --row) {
+        unsigned int nBytesThisRow;
+
         if (colortype == PALETTE)
-            rc = BMPwriterow_palette(fp, pixels[y], cx, 
-                                     cBitCount, cht);
+            bmpWriteRow_palette(fp, pixels[row], cols, 
+                                cBitCount, cht, &nBytesThisRow);
         else 
-            rc = BMPwriterow_truecolor(fp, pixels[y], cx, maxval);
+            bmpWriteRow_truecolor(fp, pixels[row], cols, maxval,
+                                  &nBytesThisRow);
 
-        if (rc == -1)
-            pm_error("couldn't write row %ld", y);
-        if (rc % 4 != 0)
-            pm_error("row had bad number of bytes: %d", rc);
-        nbyte += rc;
+        if (nBytesThisRow % 4 != 0)
+            pm_error("row had bad number of bytes: %u", nBytesThisRow);
+        nbyte += nBytesThisRow;
     }
 
     return nbyte;
@@ -444,10 +477,10 @@ BMPwritebits(FILE *          const fp,
 
 
 static void
-BMPEncode(FILE *           const ifP, 
+bmpEncode(FILE *           const ifP, 
           int              const class, 
           enum colortype   const colortype,
-          int              const bpp,
+          unsigned int     const bpp,
           int              const x, 
           int              const y, 
           const pixel **   const pixels, 
@@ -459,25 +492,25 @@ BMPEncode(FILE *           const ifP,
     unsigned long nbyte;
 
     if (colortype == PALETTE)
-        pm_message("Writing %d bits per pixel with a color palette", bpp);
+        pm_message("Writing %u bits per pixel with a color palette", bpp);
     else
-        pm_message("Writing %d bits per pixel truecolor (no palette)", bpp);
+        pm_message("Writing %u bits per pixel truecolor (no palette)", bpp);
 
     nbyte = 0;  /* initial value */
     nbyte += BMPwritefileheader(ifP, class, bpp, x, y);
     nbyte += BMPwriteinfoheader(ifP, class, bpp, x, y);
     if (colortype == PALETTE)
-        nbyte += BMPwritecolormap(ifP, class, bpp, colorMapP);
+        nbyte += BMPwriteColormap(ifP, class, bpp, colorMapP);
 
     if (nbyte != (BMPlenfileheader(class)
                   + BMPleninfoheader(class)
                   + BMPlencolormap(class, bpp, -1)))
-        pm_error(er_internal, "BMPEncode 1");
+        pm_error(er_internal, "BmpEncode 1");
 
     nbyte += BMPwritebits(ifP, x, y, colortype, bpp, pixels, maxval,
                           colorMapP->cht);
     if (nbyte != BMPlenfile(class, bpp, -1, x, y))
-        pm_error(er_internal, "BMPEncode 2");
+        pm_error(er_internal, "BmpEncode 2");
 }
 
 
@@ -487,18 +520,18 @@ makeBilevelColorMap(colorMap * const colorMapP) {
 
     colorMapP->count  = 2;
     colorMapP->cht    = NULL;
-    colorMapP->red[0] = 0;
-    colorMapP->grn[0] = 0;
-    colorMapP->blu[0] = 0;
-    colorMapP->red[1] = 255;
-    colorMapP->grn[1] = 255;
-    colorMapP->blu[1] = 255;
+    colorMapP->bmpMap[0].red = 0;
+    colorMapP->bmpMap[0].grn = 0;
+    colorMapP->bmpMap[0].blu = 0;
+    colorMapP->bmpMap[1].red = 255;
+    colorMapP->bmpMap[1].grn = 255;
+    colorMapP->bmpMap[1].blu = 255;
 }
 
 
 
 static void
-BMPEncodePBM(FILE *           const ifP, 
+bmpEncodePbm(FILE *           const ifP, 
              int              const class, 
              int              const cols, 
              int              const rows, 
@@ -508,7 +541,7 @@ BMPEncodePBM(FILE *           const ifP,
 -----------------------------------------------------------------------------*/
     /* Note:
        Only PBM input uses this routine.  Color images represented by 1 bpp via
-       color palette use the general BMPEncode().
+       color palette use the general bmpEncode().
     */
     unsigned int const adjustedCols = (cols + 31) / 32 * 32;
     unsigned int const packedBytes  = adjustedCols / 8;
@@ -526,12 +559,12 @@ BMPEncodePBM(FILE *           const ifP,
 
     makeBilevelColorMap(&bilevelColorMap);
 
-    nbyte += BMPwritecolormap(ifP, class, 1, &bilevelColorMap);
+    nbyte += BMPwriteColormap(ifP, class, 1, &bilevelColorMap);
 
     if (nbyte != (BMPlenfileheader(class)
                   + BMPleninfoheader(class)
                   + BMPlencolormap(class, 1, -1)))
-        pm_error(er_internal, "BMPEncodePBM 1");
+        pm_error(er_internal, "bmpEncodePBM 1");
    
     for (row = 0; row < rows; ++row){
         size_t bytesWritten;
@@ -548,23 +581,129 @@ BMPEncodePBM(FILE *           const ifP,
     }
 
     if (nbyte != BMPlenfile(class, 1, -1, cols, rows))
-        pm_error(er_internal, "BMPEncodePBM 2");
+        pm_error(er_internal, "bmpEncodePbm 2");
 }
 
 
 
 static void
-analyze_colors(const pixel **    const pixels, 
-               int               const cols, 
-               int               const rows, 
-               pixval            const maxval, 
-               int *             const minimum_bpp_p,
-               colorMap *        const colorMapP) {
+makeHashFromBmpMap(const struct rgb * const bmpMap,
+                   unsigned int       const nColors,
+                   colorhash_table *  const chtP) {
+
+    colorhist_vector chv;
+    unsigned int i;
+
+    MALLOCARRAY_NOFAIL(chv, nColors);
+
+    for (i = 0; i < nColors; ++i) {
+        const struct rgb * const mapEntryP = &bmpMap[i];
+
+        PPM_ASSIGN(chv[i].color,
+                   mapEntryP->red, mapEntryP->grn, mapEntryP->blu);
+    }
+
+    *chtP = ppm_colorhisttocolorhash(chv, nColors);
+
+    ppm_freecolorhist(chv);
+}
+
+
+
+static unsigned int
+minBmpBitsForColorCount(unsigned int const colorCount) {
+
+    unsigned int const minbits = pm_maxvaltobits(colorCount - 1);
+
+    /* Only 1, 4, 8, and 24 are defined in the BMP spec we
+       implement and other bpp's have in fact been seen to confuse
+       viewers.  There is an extended BMP format that has 16 bpp
+       too, but this program doesn't know how to generate that
+       (see Bmptopnm.c, though).  
+    */
+    if (minbits == 1)
+        return 1;
+    else if (minbits <= 4)
+        return 4;
+    else if (minbits <= 8)
+        return 8;
+    else
+        return 24;
+}
+
+
+
+static void
+getMapFile(const char *   const mapFileName,
+           unsigned int * const minimumBppP,
+           colorMap *     const colorMapP) {
+/*----------------------------------------------------------------------------
+   Get the color map (palette) for the BMP from file 'mapFileName'.
+
+   Return the color map as *colormapP.
+
+   Return as *minimumBppP the minimum number of bits per pixel it will
+   take to represent all the colors in the map in the BMP format.
+-----------------------------------------------------------------------------*/
+
+    FILE * mapFileP;
+    int cols, rows;
+    pixval maxval;
+    pixel ** pixels;
+    unsigned int row;
+    unsigned int count;
+
+    mapFileP = pm_openr(mapFileName);
+
+    pixels = ppm_readppm(mapFileP, &cols, &rows, &maxval);
+
+    if (cols * rows > MAXCOLORS)
+        pm_error("The colormap file you gave (-mapfile) has too "
+                 "many entries for a BMP.  A BMP can have at most "
+                 "%u colors; the file has %u pixels, each of which "
+                 "represents an entry in the color map.",
+                 MAXCOLORS, cols * rows);
+
+    count = 0; /* initial value */
+    
+    for (row = 0; row < rows; ++row) {
+        unsigned int col;
+        for (col = 0; col < cols; ++col) {
+            pixel        const color     = pixels[row][col];
+            struct rgb * const mapEntryP = &colorMapP->bmpMap[count++];
+
+            assert(count <= ARRAY_SIZE(colorMapP->bmpMap));
+
+            mapEntryP->red = PPM_GETR(color) * 255 / maxval;
+            mapEntryP->grn = PPM_GETG(color) * 255 / maxval;
+            mapEntryP->blu = PPM_GETB(color) * 255 / maxval;
+        }
+    }
+    ppm_freearray(pixels, rows);
+
+    colorMapP->count = count;
+
+    makeHashFromBmpMap(colorMapP->bmpMap, colorMapP->count, &colorMapP->cht);
+
+    *minimumBppP = minBmpBitsForColorCount(count);
+
+    pm_close(mapFileP);
+}
+
+
+
+static void
+analyzeColors(const pixel **    const pixels, 
+              int               const cols, 
+              int               const rows, 
+              pixval            const maxval, 
+              unsigned int *    const minimumBppP,
+              colorMap *        const colorMapP) {
 /*----------------------------------------------------------------------------
   Look at the colors in the image 'pixels' and compute values to use in
   representing those colors in a BMP image.  
 
-  First of all, count the distinct colors.  Return as *minimum_bpp_p
+  First of all, count the distinct colors.  Return as *minimumBppP
   the minimum number of bits per pixel it will take to represent all
   the colors in BMP format.
 
@@ -589,37 +728,23 @@ analyze_colors(const pixel **    const pixels,
     colorMapP->count = colorCount;
     if (chv == NULL) {
         pm_message("More than %u colors found", MAXCOLORS);
-        *minimum_bpp_p = 24;
+        *minimumBppP = 24;
         colorMapP->cht = NULL;
     } else {
-        unsigned int const minbits = pm_maxvaltobits(colorMapP->count - 1);
-
         unsigned int i;
 
         pm_message("%u colors found", colorMapP->count);
 
-        /* Only 1, 4, 8, and 24 are defined in the BMP spec we
-           implement and other bpp's have in fact been seen to confuse
-           viewers.  There is an extended BMP format that has 16 bpp
-           too, but this program doesn't know how to generate that
-           (see Bmptopnm.c, though).  
-        */
-        if (minbits == 1)
-            *minimum_bpp_p = 1;
-        else if (minbits <= 4)
-            *minimum_bpp_p = 4;
-        else if (minbits <= 8)
-            *minimum_bpp_p = 8;
-        else
-            *minimum_bpp_p = 24;
+        *minimumBppP = minBmpBitsForColorCount(colorMapP->count);
 
         /*
          * Now scale the maxval to 255 as required by BMP format.
          */
         for (i = 0; i < colorMapP->count; ++i) {
-            colorMapP->red[i] = (pixval) PPM_GETR(chv[i].color) * 255 / maxval;
-            colorMapP->grn[i] = (pixval) PPM_GETG(chv[i].color) * 255 / maxval;
-            colorMapP->blu[i] = (pixval) PPM_GETB(chv[i].color) * 255 / maxval;
+            struct rgb * const mapEntryP = &colorMapP->bmpMap[i];
+            mapEntryP->red = (pixval) PPM_GETR(chv[i].color) * 255 / maxval;
+            mapEntryP->grn = (pixval) PPM_GETG(chv[i].color) * 255 / maxval;
+            mapEntryP->blu = (pixval) PPM_GETB(chv[i].color) * 255 / maxval;
         }
     
         /* And make a hash table for fast lookup. */
@@ -631,38 +756,52 @@ analyze_colors(const pixel **    const pixels,
 
 
 static void
-choose_colortype_bpp(struct cmdline_info const cmdline,
-                     unsigned int        const colors, 
-                     unsigned int        const minimum_bpp,
-                     enum colortype *    const colortype_p, 
-                     unsigned int *      const bits_per_pixel_p) {
+chooseColortypeBpp(bool             const userRequestsBpp,
+                   unsigned int     const requestedBpp,
+                   unsigned int     const minimumBpp,
+                   enum colortype * const colortypeP, 
+                   unsigned int *   const bitsPerPixelP) {
+/*----------------------------------------------------------------------------
+   Determine whether the BMP raster should contain RGB values or palette
+   indices and how many bits is should have for each pixel.
 
-    if (!cmdline.bppSpec) {
+   'userRequestsBpp' says the user has requested a particular number of
+   bits per pixel.  'requestedBpp' is his request, and we assume it's a
+   valid value for a BMP.
+
+   'colors' is how many colors are in the image.
+
+   'minimumBpp' is the minimum number of bits it takes to represent all
+   the colors in the image.  We assume it is valid for a BMP.
+
+   We return our choices as *colortypeP and *bitsPerPixelP.
+-----------------------------------------------------------------------------*/
+    if (!userRequestsBpp) {
         /* User has no preference as to bits per pixel.  Choose the
            smallest number possible for this image.
         */
-        *bits_per_pixel_p = minimum_bpp;
+        *bitsPerPixelP = minimumBpp;
     } else {
-        if (cmdline.bpp < minimum_bpp)
+        if (requestedBpp < minimumBpp)
             pm_error("There are too many colors in the image to "
-                     "represent in the\n"
-                     "number of bits per pixel you requested: %d.\n"
+                     "represent in the "
+                     "number of bits per pixel you requested: %d.  "
                      "You may use Pnmquant to reduce the number of "
                      "colors in the image.",
-                     cmdline.bpp);
+                     requestedBpp);
         else
-            *bits_per_pixel_p = cmdline.bpp;
+            *bitsPerPixelP = requestedBpp;
     }
 
-    assert(*bits_per_pixel_p == 1 || 
-           *bits_per_pixel_p == 4 || 
-           *bits_per_pixel_p == 8 || 
-           *bits_per_pixel_p == 24);
+    assert(*bitsPerPixelP == 1 || 
+           *bitsPerPixelP == 4 || 
+           *bitsPerPixelP == 8 || 
+           *bitsPerPixelP == 24);
 
-    if (*bits_per_pixel_p > 8) 
-        *colortype_p = TRUECOLOR;
+    if (*bitsPerPixelP > 8) 
+        *colortypeP = TRUECOLOR;
     else {
-        *colortype_p = PALETTE;
+        *colortypeP = PALETTE;
     }
 }
 
@@ -676,12 +815,12 @@ doPbm(FILE *       const ifP,
       int          const class,
       FILE *       const ofP) {
     
-    /*  In the PBM case the raster is read directly from the input by 
-        pbm_readpbmrow_packed.  The raster format is almost identical,
-        except that BMP specifies rows to be zero-filled to 32 bit borders 
-        and that in BMP the bottom row comes first in order.
+    /* We read the raster directly from the input with
+        pbm_readpbmrow_packed().  The raster format is almost
+        identical, except that BMP specifies rows to be zero-filled to
+        32 bit borders and that in BMP the bottom row comes first in
+        order.
     */
-
     int const CHARBITS = (sizeof(unsigned char)*8); 
     int const colChars = pbm_packed_bytes(cols);
     int const adjustedCols = (cols+31) /32 * 32;
@@ -709,7 +848,7 @@ doPbm(FILE *       const ifP,
                 thisRow[i] = ~thisRow[i]; /* flip all pixels */
         }
         /* This may seem unnecessary, because the color palette 
-           (RGB[] in BMPEncodePBM) can be inverted for the same effect.
+           (RGB[] in bmpEncodePbm) can be inverted for the same effect.
            However we take this precaution, for there is indication that
            some BMP viewers may get confused with that.
         */
@@ -721,25 +860,28 @@ doPbm(FILE *       const ifP,
         }
     }
 
-    BMPEncodePBM(ofP, class, cols, rows, bitrow);
+    bmpEncodePbm(ofP, class, cols, rows, bitrow);
 }            
 
 
 
 static void
-doPgmPpm(FILE * const ifP,
+doPgmPpm(FILE *       const ifP,
          unsigned int const cols,
          unsigned int const rows,
          pixval       const maxval,
          int          const ppmFormat,
          int          const class,
+         bool         const userRequestsBpp,
+         unsigned int const requestedBpp,
+         const char * const mapFileName,
          FILE *       const ofP) {
 
-    /* PGM and PPM.  The input image is read into a PPM array, scanned
-       for color analysis and converted to a BMP raster.
-       Logic works for PBM.
+    /* PGM and PPM.  We read the input image into a PPM array, scan it
+       to analyze the colors, and convert it to a BMP raster.  Logic
+       works for PBM.
     */
-    int minimumBpp;
+    unsigned int minimumBpp;
     unsigned int bitsPerPixel;
     enum colortype colortype;
     unsigned int row;
@@ -752,13 +894,16 @@ doPgmPpm(FILE * const ifP,
     for (row = 0; row < rows; ++row)
         ppm_readppmrow(ifP, pixels[row], cols, maxval, ppmFormat);
     
-    analyze_colors((const pixel**)pixels, cols, rows, maxval, 
-                   &minimumBpp, &colorMap);
+    if (mapFileName)
+        getMapFile(mapFileName, &minimumBpp, &colorMap);
+    else
+        analyzeColors((const pixel**)pixels, cols, rows, maxval, 
+                      &minimumBpp, &colorMap);
     
-    choose_colortype_bpp(cmdline, colorMap.count, minimumBpp, &colortype, 
-                         &bitsPerPixel);
+    chooseColortypeBpp(userRequestsBpp, requestedBpp, minimumBpp,
+                       &colortype, &bitsPerPixel);
     
-    BMPEncode(stdout, class, colortype, bitsPerPixel,
+    bmpEncode(ofP, class, colortype, bitsPerPixel,
               cols, rows, (const pixel**)pixels, maxval, &colorMap);
     
     freeColorMap(&colorMap);
@@ -767,17 +912,19 @@ doPgmPpm(FILE * const ifP,
 
 
 int
-main(int argc, char **argv) {
+main(int           argc,
+     const char ** argv) {
 
+    struct cmdlineInfo cmdline;
     FILE * ifP;
     int rows;
     int cols;
     pixval maxval;
     int ppmFormat;
 
-    ppm_init(&argc, argv);
+    pm_proginit(&argc, argv);
 
-    parse_command_line(argc, argv, &cmdline);
+    parseCommandLine(argc, argv, &cmdline);
 
     ifP = pm_openr(cmdline.input_filename);
     
@@ -786,7 +933,9 @@ main(int argc, char **argv) {
     if (PPM_FORMAT_TYPE(ppmFormat) == PBM_TYPE)
         doPbm(ifP, cols, rows, ppmFormat, cmdline.class, stdout);
     else
-        doPgmPpm(ifP, cols, rows, maxval, ppmFormat, cmdline.class, stdout);
+        doPgmPpm(ifP, cols, rows, maxval, ppmFormat,
+                 cmdline.class, cmdline.bppSpec, cmdline.bpp, cmdline.mapfile,
+                 stdout);
 
     pm_close(ifP);
     pm_close(stdout);
diff --git a/converter/ppm/ppmtoleaf.c b/converter/ppm/ppmtoleaf.c
index fa5fdaf5..dcff0985 100644
--- a/converter/ppm/ppmtoleaf.c
+++ b/converter/ppm/ppmtoleaf.c
@@ -1,4 +1,4 @@
-/* ppmtoleaf.c - read a portable pixmap and produce a ileaf img file
+/* ppmtoleaf.c - read a PPM and produce a ileaf img file
  *
  * Copyright (C) 1994 by Bill O'Donnell.
  *
@@ -15,57 +15,60 @@
  */
 
 #include <stdio.h>
+
 #include "ppm.h"
 
 #define MAXCOLORS 256
 
-pixel **pixels;
+pixel ** pixels;
 colorhash_table cht;
 
-int Red[MAXCOLORS], Green[MAXCOLORS], Blue[MAXCOLORS];
+static int Red[MAXCOLORS], Green[MAXCOLORS], Blue[MAXCOLORS];
 
 
 
 static int
-colorstobpp( colors )
-int colors;
-{
+colorstobpp(unsigned int const colors) {
+
     int bpp;
     
-    if ( colors <= 2 )
-	bpp = 1;
-    else if ( colors <= 256 )
-	bpp = 8;
+    if (colors <= 2)
+        bpp = 1;
+    else if (colors <= 256)
+        bpp = 8;
     else
-	bpp = 24;
+        bpp = 24;
+
     return bpp;
 }
 
 
 
 static int
-GetPixel( x, y )
-int x, y;
-{
+GetPixel(int const x,
+         int const y) {
+
     int color;
     
-    color = ppm_lookupcolor( cht, &pixels[y][x] );
+    color = ppm_lookupcolor(cht, &pixels[y][x]);
+    
     return color;
 }
 
 
 
-/* OK, this routine is not wicked efficient, but it is simple to follow
-   and it works. */
+
 static void
-leaf_writeimg(width, height, depth, ncolors, maxval)
-int width;
-int height;
-int depth;
-int ncolors;
-{
-    int i,row,col;
-    
+leaf_writeimg(unsigned int const width,
+              unsigned int const height,
+              unsigned int const depth,
+              unsigned int const ncolors,
+              pixval       const maxval) {
+
+    /* OK, this routine is not wicked efficient, but it is simple to follow
+       and it works.
+    */
+
     /* NOTE: byte order in ileaf img file fmt is big-endian, always! */
     
     /* magic */
@@ -115,136 +118,142 @@ int ncolors;
     
     /* format, mono/gray = 0x20000000, RGB=0x29000000 */
     if (depth == 1)
-	fputc(0x20, stdout);
+        fputc(0x20, stdout);
     else
-	fputc(0x29, stdout);
+        fputc(0x29, stdout);
+
     fputc(0x00, stdout);
     fputc(0x00, stdout);
     fputc(0x00, stdout);
     
     /* colormap size */
-    if (depth == 8)
-    {
-	fputc((unsigned char)((ncolors >> 8) & 0x00ff), stdout);
-	fputc((unsigned char)(ncolors  & 0x00ff), stdout);
-	for (i=0; i<256; i++)
-	    fputc((unsigned char) Red[i]*255/maxval, stdout);
-	for (i=0; i<256; i++)
-	    fputc((unsigned char) Green[i]*255/maxval, stdout);
-	for (i=0; i<256; i++)
-	    fputc((unsigned char) Blue[i]*255/maxval, stdout);
-	
-	for (row=0; row<height; row++) 
-	{
-	    for (col=0; col<width; col++) 
-		fputc(GetPixel(col, row), stdout);
-	    if (width % 2)
-		fputc(0x00, stdout); /* pad to 2-bytes */
-	}
+    if (depth == 8) {
+        unsigned int i;
+        unsigned int row;
+
+        fputc((unsigned char)((ncolors >> 8) & 0x00ff), stdout);
+        fputc((unsigned char)(ncolors  & 0x00ff), stdout);
+        for (i = 0; i < 256; ++i)
+            fputc((unsigned char) Red[i]*255/maxval, stdout);
+        for (i=0; i < 256; ++i)
+            fputc((unsigned char) Green[i]*255/maxval, stdout);
+        for (i = 0; i < 256; ++i)
+            fputc((unsigned char) Blue[i]*255/maxval, stdout);
+    
+        for (row=0; row < height; ++row) {
+            unsigned int col;
+            for (col = 0; col < width; ++col) 
+                fputc(GetPixel(col, row), stdout);
+            if ((width % 2) != 0)
+                fputc(0x00, stdout); /* pad to 2-bytes */
+        }
     } else if (depth == 1) {
-	/* mono image */
-	/* no colormap */
-	fputc(0x00, stdout);
-	fputc(0x00, stdout);
-
-	for (row=0; row<height; row++) 
-	{
-	    unsigned char bits = 0;
-	    for (col=0; col<width; col++) {
-		if (GetPixel(col,row))
-		    bits |= (unsigned char) (0x0080 >> (col % 8));
-		if (((col + 1) % 8) == 0)  {
-		    fputc(bits, stdout);
-		    bits = 0;
-		}
-	    }
-	    if ((width % 8) != 0)
-		fputc(bits, stdout);
-	    if ((width % 16) && (width % 16) <= 8)
-		fputc(0x00, stdout);  /* 16 bit pad */
-	}
+        /* mono image */
+        /* no colormap */
+
+        unsigned int row;
+
+        fputc(0x00, stdout);
+        fputc(0x00, stdout);
+
+        for (row = 0; row < height; ++row) {
+            unsigned char bits;
+            unsigned int col;
+            bits = 0;
+            for (col = 0; col < width; ++col) {
+                if (GetPixel(col,row))
+                    bits |= (unsigned char) (0x0080 >> (col % 8));
+                if (((col + 1) % 8) == 0)  {
+                    fputc(bits, stdout);
+                    bits = 0;
+                }
+            }
+            if ((width % 8) != 0)
+                fputc(bits, stdout);
+            if ((width % 16) && (width % 16) <= 8)
+                fputc(0x00, stdout);  /* 16 bit pad */
+        }
     } else {
-	/* no colormap, direct or true color (24 bit) image */
-	fputc(0x00, stdout);
-	fputc(0x00, stdout);
-	
-	for (row=0; row<height; row++) 
-	{
-	    for (col=0; col<width; col++) 
-		fputc(pixels[row][col].r * 255 / maxval, stdout);
-	    if (width % 2)
-		fputc(0x00, stdout); /* pad to 2-bytes */
-	    for (col=0; col<width; col++) 
-		fputc(pixels[row][col].g * 255 / maxval, stdout);
-	    if (width % 2)
-		fputc(0x00, stdout); /* pad to 2-bytes */
-	    for (col=0; col<width; col++) 
-		fputc(pixels[row][col].b * 255 / maxval, stdout);
-	    if (width % 2)
-		fputc(0x00, stdout); /* pad to 2-bytes */
-	}
+        /* no colormap, direct or true color (24 bit) image */
+
+        unsigned int row;
+
+        fputc(0x00, stdout);
+        fputc(0x00, stdout);
+        
+        for (row = 0; row < height; ++row) {
+            unsigned int col;
+            for (col = 0; col < width; ++col) 
+                fputc(pixels[row][col].r * 255 / maxval, stdout);
+            if (width % 2 != 0)
+                fputc(0x00, stdout); /* pad to 2-bytes */
+            for (col = 0; col < width; ++col) 
+                fputc(pixels[row][col].g * 255 / maxval, stdout);
+            if (width % 2 != 0)
+                fputc(0x00, stdout); /* pad to 2-bytes */
+            for (col = 0; col < width; ++col) 
+                fputc(pixels[row][col].b * 255 / maxval, stdout);
+            if (width % 2 != 0)
+                fputc(0x00, stdout); /* pad to 2-bytes */
+        }
     }
 }
 
 
 
 int
-main( argc, argv )
-int argc;
-char *argv[];
-{
-    FILE *ifd;
-    int argn, rows, cols, colors, i, BitsPerPixel;
+main(int argc, const char * argv[]) {
+
+    FILE * ifP;
+    int argn;
+    int rows, cols;
+    unsigned int BitsPerPixel;
+    int colors;
     pixval maxval;
     colorhist_vector chv;
     const char * const usage = "[ppmfile]";
     
-    ppm_init(&argc, argv);
+    pm_proginit(&argc, argv);
     
     argn = 1;
     
-    if ( argn < argc )
-    {
-	ifd = pm_openr( argv[argn] );
-	argn++;
+    if (argn < argc) {
+        ifP = pm_openr(argv[argn]);
+        argn++;
     } else
-	ifd = stdin;
+        ifP = stdin;
     
-    if ( argn != argc )
-	pm_usage( usage );
+    if (argn != argc)
+        pm_usage(usage);
     
-    pixels = ppm_readppm( ifd, &cols, &rows, &maxval );
+    pixels = ppm_readppm(ifP, &cols, &rows, &maxval);
     
-    pm_close( ifd );
+    pm_close(ifP);
     
     /* Figure out the colormap. */
-    fprintf( stderr, "(Computing colormap..." );
-    fflush( stderr );
-    chv = ppm_computecolorhist( pixels, cols, rows, MAXCOLORS, &colors );
-    if ( chv != (colorhist_vector) 0 )
-    {
-	fprintf( stderr, "  Done.  %d colors found.)\n", colors );
-	
-	for ( i = 0; i < colors; i++ )
-	{
-	    Red[i] = (int) PPM_GETR( chv[i].color );
-	    Green[i] = (int) PPM_GETG( chv[i].color );
-	    Blue[i] = (int) PPM_GETB( chv[i].color );
-	}
-	BitsPerPixel = colorstobpp( colors );
-	
-	/* And make a hash table for fast lookup. */
-	cht = ppm_colorhisttocolorhash( chv, colors );
-	ppm_freecolorhist( chv );
+    pm_message("Computing colormap...");
+    chv = ppm_computecolorhist(pixels, cols, rows, MAXCOLORS, &colors);
+    if (chv) {
+        unsigned int i;
+
+        pm_message("... Done.  %u colors found.", colors);
+    
+        for (i = 0; i < colors; ++i) {
+            Red[i]   = (int) PPM_GETR( chv[i].color);
+            Green[i] = (int) PPM_GETG( chv[i].color);
+            Blue[i]  = (int) PPM_GETB( chv[i].color);
+        }
+        BitsPerPixel = colorstobpp(colors);
+    
+        /* And make a hash table for fast lookup. */
+        cht = ppm_colorhisttocolorhash(chv, colors);
+        ppm_freecolorhist(chv);
     } else {
-	BitsPerPixel = 24;
-	fprintf( stderr, "  Done.  24-bit true color %d color image.)\n", colors );
+        BitsPerPixel = 24;
+        pm_message("  ... Done.  24-bit true color %u color image.", colors);
     }
     
     leaf_writeimg(cols, rows, BitsPerPixel, colors, maxval);
     
-    return( 0 );
+    return 0;
 }
-
-
-
diff --git a/converter/ppm/ppmtompeg/Makefile b/converter/ppm/ppmtompeg/Makefile
index e9b57cb0..d3342c9a 100644
--- a/converter/ppm/ppmtompeg/Makefile
+++ b/converter/ppm/ppmtompeg/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = converter/ppm/ppmtompeg
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 ifeq ($(JPEGLIB),NONE)
   # 'nojpeg' is a module that implements all the jpeg access routines as
@@ -76,7 +76,7 @@ SCRIPTS =
 .PHONY: all
 all: ppmtompeg
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 ifeq ($(NEED_RUNTIME_PATH),Y)
   LIBOPTR = -runtime
diff --git a/converter/ppm/ppmtompeg/file.c b/converter/ppm/ppmtompeg/file.c
index ae741962..223170a4 100644
--- a/converter/ppm/ppmtompeg/file.c
+++ b/converter/ppm/ppmtompeg/file.c
@@ -19,17 +19,6 @@
  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  */
 
-/*  
- *  $Header: /n/picasso/project/mm/mpeg/mpeg_dist/mpeg_encode/RCS/file.c,v 1.2 1993/06/30 20:06:09 keving Exp $
- *  $Log: file.c,v $
- * Revision 1.2  1993/06/30  20:06:09  keving
- * nothing
- *
- * Revision 1.1  1993/06/03  21:08:08  keving
- * nothing
- *
- */
-
 #include "tk.h"
 
 #include "all.h"
@@ -40,11 +29,10 @@
 #include <time.h>
 #include <string.h>
 #include <dirent.h>
-#include <strings.h>
 
 #define MAX_FILES   1000
-#define MAX_NAME_LEN	256
-#define MAX_STRING_LEN	MAX_NAME_LEN
+#define MAX_NAME_LEN    256
+#define MAX_STRING_LEN  MAX_NAME_LEN
 
 typedef int boolean;
 #define TRUE 1
@@ -52,77 +40,76 @@ typedef int boolean;
 
 extern char currentPath[MAXPATHLEN];
 
-char	globString[1024];
+char globString[1024];
 
-static DIR *dfd;
+static DIR * dfd;
 
-void	ResetPath(void);
+void ResetPath(void);
 int ListDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
-		  char **argv);
+                  char **argv);
 int ChangeDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
-		  char **argv);
-void	SortFiles(int numStrings, char strings[MAX_FILES][MAX_NAME_LEN],
-		  boolean *dirList, int permute[]);
+                    char **argv);
+void SortFiles(int numStrings, char strings[MAX_FILES][MAX_NAME_LEN],
+               boolean *dirList, int permute[]);
+
+static void UpdatePath(Tcl_Interp *interp, char *directory);
+static boolean MatchesGlob(char *string, char *glob);
 
-static void	UpdatePath(Tcl_Interp *interp, char *directory);
-static boolean	MatchesGlob(char *string, char *glob);
 
 
+void
+ResetPath() {
 
-void	ResetPath()
-{
-    if ( getwd(currentPath) == 0 )
-    {
-	fprintf(stderr, "Error getting pathname!!!\n");
-	exit(1);
+    if (getwd(currentPath) == 0) {
+        fprintf(stderr, "Error getting pathname!!!\n");
+        exit(1);
     }
 
     strcpy(&currentPath[strlen(currentPath)], "/");
 
     dfd = opendir(currentPath);
-    if ( dfd == NULL )
-    {
-	fprintf(stderr, "can't open '%s'\n", currentPath);
-	exit(1);
+    if (dfd == NULL) {
+        fprintf(stderr, "can't open '%s'\n", currentPath);
+        exit(1);
     }
 }
 
 
-static void	UpdatePath(Tcl_Interp *interp, char *directory)
-{
+
+static void
+UpdatePath(Tcl_Interp *interp, char *directory) {
+
     int length;
     char *charPtr;
 
     length = strlen(currentPath);
 
-    if ( strcmp(directory, "./") == 0 )
-	return /* nothing */ ;
-    else if ( strcmp(directory, "../") == 0 )
-    {
-	/* delete backwards up to '/' */
-
-	if ( length < 2 )
-	{
-	    fprintf(stderr, "Error:  backing up from root directory!!!\n");
-	    exit(1);
-	}
-
-	charPtr = &currentPath[length-2];
-	while ( (charPtr != currentPath) && (*charPtr != '/') )
-	    charPtr--;
-	charPtr++;	/* leave the '/' */
-	*charPtr = '\0';
-    }
-    else
-    {
-	strcpy(&currentPath[length], directory);
+    if (streq(directory, "./"))
+        return /* nothing */ ;
+    else if (streq(directory, "../")) {
+        /* delete backwards up to '/' */
+
+        if (length < 2) {
+            fprintf(stderr, "Error:  backing up from root directory!!!\n");
+            exit(1);
+        }
+
+        charPtr = &currentPath[length-2];
+        while ((charPtr != currentPath) && (*charPtr != '/'))
+            --charPtr;
+        ++charPtr;  /* leave the '/' */
+        *charPtr = '\0';
+    } else {
+        strcpy(&currentPath[length], directory);
     }
 }
 
 
-int ChangeDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
-		  char **argv)
-{
+
+int
+ChangeDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
+                char **argv) {
+
     char *directory = argv[1];
 
     UpdatePath(interp, directory);
@@ -130,82 +117,74 @@ int ChangeDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
     fprintf(stdout, "Opening directory: '%s'\n", currentPath);
 
     dfd = opendir(currentPath);
-    if ( dfd == NULL )
-    {
-	fprintf(stderr, "can't open '%s'\n", currentPath);
-	return TCL_OK;	/* shouldn't, really */
+    if (dfd == NULL) {
+        fprintf(stderr, "can't open '%s'\n", currentPath);
+        return TCL_OK;  /* shouldn't, really */
     }
-
+    
     return TCL_OK;
 }
 
 
-int ListDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
-		  char **argv)
-{
-    struct dirent *dp;
+
+int
+ListDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
+              char **argv) {
+
+    struct dirent * dp;
     struct stat stbuf;
     char command[256];
     char fileName[MAX_FILES][MAX_NAME_LEN];
     boolean dirList[MAX_FILES];
     int permute[MAX_FILES];
-    int	fileCount = 0;
-    register int index;
+    int fileCount = 0;
+    int index;
     char fullName[MAXPATHLEN];
-    char    *restPtr;
+    char * restPtr;
 
     sprintf(command, "ShowCurrentDirectory %s", currentPath);
     Tcl_Eval(interp, command, 0, (char **) NULL);
 
-    if ( dfd == NULL )
-    {
-	fprintf(stderr, "TRIED TO LIST NULL DIRECTORY\n");
+    if (dfd == NULL) {
+        fprintf(stderr, "TRIED TO LIST NULL DIRECTORY\n");
 
-	return TCL_OK;
+        return TCL_OK;
     }
 
-/* check if root directory */
-    if ( strlen(currentPath) != 1 )
-    {
-	sprintf(fileName[fileCount], "../");
-	dirList[fileCount] = TRUE;
-	fileCount++;
+    /* check if root directory */
+    if (strlen(currentPath) != 1) {
+        sprintf(fileName[fileCount], "../");
+        dirList[fileCount] = TRUE;
+        ++fileCount;
     }
 
     strcpy(fullName, currentPath);
     restPtr = &fullName[strlen(fullName)];
 
-    while ( (dp = readdir(dfd)) != NULL )
-    {
-	strcpy(restPtr, dp->d_name);
-	stat(fullName, &stbuf);
-
-	if ( dp->d_name[0] != '.' )
-	{
-	    if ( S_ISDIR(stbuf.st_mode) )
-	    {
-		sprintf(fileName[fileCount], "%s/", dp->d_name);
-		dirList[fileCount] = TRUE;
-		fileCount++;
-	    }
-	    else
-	    {
-		if ( MatchesGlob(dp->d_name, globString) )
-		{
-		    strcpy(fileName[fileCount], dp->d_name);
-		    dirList[fileCount] = FALSE;
-		    fileCount++;
-		}
-	    }
-	}
+    while ((dp = readdir(dfd)) != NULL) {
+        strcpy(restPtr, dp->d_name);
+        stat(fullName, &stbuf);
+        
+        if (dp->d_name[0] != '.') {
+            if (S_ISDIR(stbuf.st_mode)) {
+                sprintf(fileName[fileCount], "%s/", dp->d_name);
+                dirList[fileCount] = TRUE;
+                ++fileCount;
+            } else {
+                if (MatchesGlob(dp->d_name, globString)) {
+                    strcpy(fileName[fileCount], dp->d_name);
+                    dirList[fileCount] = FALSE;
+                    ++fileCount;
+                }
+            }
+        }
     }
 
     SortFiles(fileCount, fileName, dirList, permute);
 
-    for ( index = 0; index < fileCount; index++ )
-    {
-	sprintf(command, "AddBrowseFile %s", fileName[permute[index]]);
-	Tcl_Eval(interp, command, 0, (char **) NULL);
+    for (index = 0; index < fileCount; ++index) {
+        sprintf(command, "AddBrowseFile %s", fileName[permute[index]]);
+        Tcl_Eval(interp, command, 0, (char **) NULL);
     }
 
     closedir(dfd);
@@ -214,108 +193,110 @@ int ListDirectory(ClientData nulldata, Tcl_Interp *interp, int argc,
 }
 
 
-void	SortFiles(int numStrings, char strings[MAX_FILES][MAX_NAME_LEN],
-		  boolean *dirList, int permute[])
-{
-    register int i, j;
-    int temp;
-    int	numDirs;
-    int	ptr;
 
-    for ( i = 0; i < numStrings; i++ )
-	permute[i] = i;
+void
+SortFiles(int numStrings, char strings[MAX_FILES][MAX_NAME_LEN],
+          boolean *dirList, int permute[]) {
+
+    int i;
+    int numDirs;
+    int ptr;
+
+    for (i = 0; i < numStrings; ++i)
+        permute[i] = i;
 
     /* put all directories at front */
     numDirs = 0;
     ptr = numStrings-1;
-    while ( numDirs != ptr )
-    {
-	/* go past dirs */
-	while ( (numDirs < ptr) && (dirList[permute[numDirs]]) )
-	    numDirs++;
-
-	/* go past non-dirs */
-	while ( (numDirs < ptr) && (! dirList[permute[ptr]]) )
-	    ptr--;
-
-	if ( numDirs != ptr )
-	{
-	    temp = permute[numDirs];
-	    permute[numDirs] = ptr;
-	    permute[ptr] = temp;
-	}
+    while (numDirs != ptr) {
+        /* go past dirs */
+        while ((numDirs < ptr) && (dirList[permute[numDirs]]))
+            ++numDirs;
+
+        /* go past non-dirs */
+        while ((numDirs < ptr) && (! dirList[permute[ptr]]))
+            --ptr;
+
+        if (numDirs != ptr) {
+            int const temp = permute[numDirs];
+            permute[numDirs] = ptr;
+            permute[ptr] = temp;
+        }
     }
 
-    if ( dirList[permute[numDirs]] )
-	numDirs++;
-
-    for ( i = 0; i < numDirs; i++ )
-	for ( j = i+1; j < numDirs; j++ )
-	{
-	    if ( strcmp(&strings[permute[j]][0], &strings[permute[i]][0]) < 0 )
-	    {
-		temp = permute[j];
-		permute[j] = permute[i];
-		permute[i] = temp;
-	    }
-	}
-
-    for ( i = numDirs; i < numStrings; i++ )
-	for ( j = i+1; j < numStrings; j++ )
-	{
-	    if ( strcmp(&strings[permute[j]][0], &strings[permute[i]][0]) < 0 )
-	    {
-		temp = permute[j];
-		permute[j] = permute[i];
-		permute[i] = temp;
-	    }
-	}
+    if (dirList[permute[numDirs]])
+        ++numDirs;
+
+    for (i = 0; i < numDirs; ++i) {
+        int j;
+        for (j = i + 1; j < numDirs; ++j) {
+            if (strcmp(&strings[permute[j]][0], &strings[permute[i]][0]) < 0) {
+                int const temp = permute[j];
+                permute[j] = permute[i];
+                permute[i] = temp;
+            }
+        }
+    }
+    for (i = numDirs; i < numStrings; ++i) {
+        int j;
+        for (j = i + 1; j < numStrings; ++j) {
+            if (strcmp(&strings[permute[j]][0], &strings[permute[i]][0]) < 0) {
+                int const temp = permute[j];
+                permute[j] = permute[i];
+                permute[i] = temp;
+            }
+        }
+    }
 }
 
 
-int SetBrowseGlob (ClientData nulldata, Tcl_Interp *interp,
-		   int argc, char **argv)
-{
-    if (argc == 2 )
-    {
-	strcpy(globString, argv[1]);
 
-	fprintf(stdout, "GLOB:  %s\n", globString);
+int
+SetBrowseGlob(ClientData nulldata, Tcl_Interp *interp,
+              int argc, char **argv) {
+
+    if (argc == 2) {
+        strcpy(globString, argv[1]);
+
+        fprintf(stdout, "GLOB:  %s\n", globString);
 
-	return TCL_OK;
+        return TCL_OK;
     }
 
-	Tcl_AppendResult (interp, 
-            "wrong args: should be \"", argv[0]," string\"", (char *) NULL);
-	return TCL_ERROR;
+    Tcl_AppendResult(interp, 
+                     "wrong args: should be \"", argv[0]," string\"",
+                     NULL);
+    return TCL_ERROR;
 }
 
 
-static boolean	MatchesGlob(char *string, char *glob)
-{
-    char    *stringRight, *globRight;
 
-    while ( (*glob != '\0') && (*glob != '*') )	    /* match left side */
-    {
-	if ( (*string == '\0') || (*string != *glob) )
-	    return FALSE;
-	string++;
-	glob++;
+static boolean
+MatchesGlob(char *string, char *glob) {
+
+    char * stringRight;
+    char * globRight;
+
+    while ((*glob != '\0') && (*glob != '*')) {
+        /* match left side */
+        if ((*string == '\0') || (*string != *glob))
+            return FALSE;
+        ++string;
+        ++glob;
     }
 
-    if ( *glob == '\0' )	/* no star */
-	return TRUE;
+    if (*glob == '\0')    /* no star */
+        return TRUE;
 
     /* now match right side */
     stringRight = &string[strlen(string)-1];
     globRight = &glob[strlen(glob)-1];
 
-    while ( *globRight != '*' )
-    {
-	if ( (stringRight < string) || (*stringRight != *globRight) )
-	    return FALSE;
-	globRight--;
-	stringRight--;
+    while (*globRight != '*') {
+        if ((stringRight < string) || (*stringRight != *globRight))
+            return FALSE;
+        --globRight;
+        --stringRight;
     }
 
     return TRUE;
diff --git a/converter/ppm/ppmtompeg/huff.h b/converter/ppm/ppmtompeg/huff.h
deleted file mode 100644
index 4d0b8840..00000000
--- a/converter/ppm/ppmtompeg/huff.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 1995 The Regents of the University of California.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice and the following
- * two paragraphs appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
- * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-/*  
- *  $Header: /n/charlie-brown/project/mm/mpeg/mpeg_dist/mpeg_encode/RCS/huff.h,v 1.2 1995/01/19 23:08:28 eyhung Exp $
- */
-
-/*  
- *  THIS FILE IS MACHINE GENERATED!  DO NOT EDIT!
- */
-#define HUFF_MAXRUN	32
-#define HUFF_MAXLEVEL	41
-
-extern int huff_maxlevel[];
-extern uint32 *huff_table[];
-extern int *huff_bits[];
diff --git a/converter/ppm/ppmtopjxl.c b/converter/ppm/ppmtopjxl.c
index 72d299fd..91cd1a45 100644
--- a/converter/ppm/ppmtopjxl.c
+++ b/converter/ppm/ppmtopjxl.c
@@ -1,4 +1,4 @@
-/* ppmtopcl.c - convert portable pixmap into PCL language for HP PaintJet and
+/* ppmtopcl.c - convert PPM into PCL language for HP PaintJet and
  *              PaintJet XL color printers
  * AJCD 12/3/91
  * 
@@ -17,8 +17,8 @@
 #include <string.h>
 
 #include "pm_c_util.h"
-#include "ppm.h"
 #include "nstring.h"
+#include "ppm.h"
 
 #define MAXCOLORS 1024
 
@@ -106,318 +106,306 @@ putbits(b, n) {
       int xo = 0;
       int xc = 0;
       if (cnt+n > 8) {  /* overflowing current byte? */
-	 xc = cnt + n - 8;
-	 xo = (b & ~(-1 << xc)) << (8-xc);
-	 n -= xc;
-	 b >>= xc;
+     xc = cnt + n - 8;
+     xo = (b & ~(-1 << xc)) << (8-xc);
+     n -= xc;
+     b >>= xc;
       }
       cnt += n;
       out |= (b & ~(-1 << n)) << (8-cnt);
       if (cnt >= 8) {
-	 inrow[num++] = out;
-	 out = xo;
-	 cnt = xc;
+     inrow[num++] = out;
+     out = xo;
+     cnt = xc;
       }
    } else { /* flush row */
       int i;
       if (cnt) {
-	 inrow[num++] = out;
-	 out = cnt = 0;
+     inrow[num++] = out;
+     out = cnt = 0;
       }
       for (; num > 0 && inrow[num-1] == 0; num--); /* remove trailing zeros */
       printf("\033*b"); 
       if (num && !nopack) {            /* TIFF 4.0 packbits encoding */
-	 int start = 0;
-	 int next;
-	 runcnt[start] = 0;
-	 for (i = 1; i < num; i++) {
-	    if (inrow[i] == inrow[i-1]) {
-	       if (runcnt[start] <= 0 && runcnt[start] > -127)
-		  runcnt[start]--;
-	       else
-		  runcnt[start = i] = 0;
-	    } else {
-	       if (runcnt[start] >= 0 && runcnt[start] < 127)
-		  runcnt[start]++;
-	       else
-		  runcnt[start = i] = 0;
-	    }
-	 }
-	 start = 0;
-	 for (i = 0; i < num; i = next) {
-	    int count = runcnt[i];
-	    int from = i;
-	    if (count >= 0) { /* merge two-byte runs */
-	       for (;;) {
-		  next = i+1+runcnt[i];
-		  if(next >= num || runcnt[next] < 0 ||
-		     count+runcnt[next]+1 > 127)
-		     break;
-		  count += runcnt[next]+1;
-		  i = next;
-	       }
-	    }
-	    next =  i + 1 + ((runcnt[i] < 0) ? -runcnt[i] : runcnt[i]);
-	    if (next < num && count > 0 &&
-		runcnt[next] < 0 && runcnt[next] > -127) {
-	       count--;
-	       next--;
-	       runcnt[next] = runcnt[next+1]-1;
-	    }
-	    outrow[start++] = count;
-	    if (count >= 0) {
-	       while (count-- >= 0)
-		  outrow[start++] = inrow[from++];
-	    } else
-	       outrow[start++] = inrow[from];
-	 }
-	 if (start < num) {
-	    num = start;
-	    if (!pack) {
-	       printf("2m");
-	       pack = 1;
-	    }
-	 } else {
-	    if (pack) {
-	       printf("0m");
-	       pack = 0;
-	    }
-	 }
+     int start = 0;
+     int next;
+     runcnt[start] = 0;
+     for (i = 1; i < num; i++) {
+        if (inrow[i] == inrow[i-1]) {
+           if (runcnt[start] <= 0 && runcnt[start] > -127)
+          runcnt[start]--;
+           else
+          runcnt[start = i] = 0;
+        } else {
+           if (runcnt[start] >= 0 && runcnt[start] < 127)
+          runcnt[start]++;
+           else
+          runcnt[start = i] = 0;
+        }
+     }
+     start = 0;
+     for (i = 0; i < num; i = next) {
+        int count = runcnt[i];
+        int from = i;
+        if (count >= 0) { /* merge two-byte runs */
+           for (;;) {
+          next = i+1+runcnt[i];
+          if(next >= num || runcnt[next] < 0 ||
+             count+runcnt[next]+1 > 127)
+             break;
+          count += runcnt[next]+1;
+          i = next;
+           }
+        }
+        next =  i + 1 + ((runcnt[i] < 0) ? -runcnt[i] : runcnt[i]);
+        if (next < num && count > 0 &&
+        runcnt[next] < 0 && runcnt[next] > -127) {
+           count--;
+           next--;
+           runcnt[next] = runcnt[next+1]-1;
+        }
+        outrow[start++] = count;
+        if (count >= 0) {
+           while (count-- >= 0)
+          outrow[start++] = inrow[from++];
+        } else
+           outrow[start++] = inrow[from];
+     }
+     if (start < num) {
+        num = start;
+        if (!pack) {
+           printf("2m");
+           pack = 1;
+        }
+     } else {
+        if (pack) {
+           printf("0m");
+           pack = 0;
+        }
+     }
       }
       printf("%dW", num);
       for (i = 0; i < num; i++)
-	 putchar(pack ? outrow[i] : inrow[i]);
+     putchar(pack ? outrow[i] : inrow[i]);
       num = 0; /* new row */
    }
 }
 
+
+
 int
-main(argc, argv)
-     int argc;
-     char *argv[];
-{
-   FILE *ifd;
-   register pixel **pixels, *pixrow;
-   register int  row, col, bpp, i;
-   int rows, cols;
-   pixval maxval;
-   int bpr, bpg, bpb;
-   int render;
-   int colors, pclindex;
-   colorhist_vector chv;
-   colorhash_table cht;
+main(int argc, const char * argv[]) {
+
+    FILE * ifP;
+    pixel ** pixels;
+    unsigned int row;
+    unsigned int bpp;
+    int rows, cols;
+    pixval maxval;
+    int bpr, bpg, bpb;
+    int render;
+    int colors, pclindex;
+    colorhist_vector chv;
+    colorhash_table cht;
    
-   ppm_init( &argc, argv );
-
-   while (argc > 1 && argv[1][0] == '-') {
-      char *c;
-      for (i = 0; i < sizeof(options)/sizeof(struct options); i++) {
-	 if (pm_keymatch(argv[1], options[i].name,
-			 MIN(strlen(argv[1]), strlen(options[i].name)))) {
-	    switch (options[i].type) {
-	    case DIM:
-	       if (++argv, --argc == 1)
-		  pm_usage(usage);
-	       for (c = argv[1]; ISDIGIT(*c); c++);
-	       if (c[0] == 'p' && c[1] == 't') /* points */
-		  *(int *)(options[i].value) = atoi(argv[1])*10;
-	       else if (c[0] == 'd' && c[1] == 'p') /* decipoints */
-		  *(int *)(options[i].value) = atoi(argv[1]);
-	       else if (c[0] == 'i' && c[1] == 'n') /* inches */
-		  *(int *)(options[i].value) = atoi(argv[1])*720;
-	       else if (c[0] == 'c' && c[1] == 'm') /* centimetres */
-		  *(int *)(options[i].value) = atoi(argv[1])*283.46457;
-	       else if (!c[0]) /* dots */
-		  *(int *)(options[i].value) = atoi(argv[1])*4;
-	       else
-		  pm_error("illegal unit of measure %s", c);
-	       break;
-	    case REAL:
-	       if (++argv, --argc == 1)
-		  pm_usage(usage);
-	       *(double *)(options[i].value) = atof(argv[1]);
-	       break;
-	    case BOOL:
-	       *(int *)(options[i].value) = 1;
-	       break;
-	    }
-	    break;
-	 }
-      }
-      if (i >= sizeof(options)/sizeof(struct options))
-	 pm_usage(usage);
-      argv++; argc--;
-   }
-   if (argc > 2)
-      pm_usage(usage);
-   else if (argc == 2)
-      ifd = pm_openr(argv[1]);
-   else
-      ifd = stdin ;
-
-   /* validate arguments */
-   if (diffuse+cluster+dither > 1)
-      pm_error("only one of -diffuse, -dither and -cluster may be used");
-   render = diffuse ? 4 : dither ? 3 : cluster ? 7 : 0;
-
-   if (xsize != 0.0 && xscale != 0.0)
-      pm_error("only one of -xsize and -xscale may be used");
-
-   if (ysize != 0.0 && yscale != 0.0)
-      pm_error("only one of -ysize and -yscale may be used");
-
-   pixels = ppm_readppm( ifd, &cols, &rows, &maxval );
-   pm_close( ifd );
-
-   /* limit checks */
-   if (cols > PCL_MAXWIDTH || rows > PCL_MAXHEIGHT)
-      pm_error("image too large; reduce with ppmscale");
-   if (maxval > PCL_MAXVAL)
-      pm_error("color range too large; reduce with ppmcscale");
-
-   /* Figure out the colormap. */
-   fprintf( stderr, "(Computing colormap..." ); fflush( stderr );
-   chv = ppm_computecolorhist( pixels, cols, rows, MAXCOLORS, &colors );
-   if ( chv == (colorhist_vector) 0 )
-      pm_error("too many colors; reduce with pnmquant");
-   fprintf( stderr, "  Done.  %d colors found.)\n", colors );
-
-   /* And make a hash table for fast lookup. */
-   cht = ppm_colorhisttocolorhash( chv, colors );
-
-   /* work out color downloading mode */
-   pclindex = bitsperpixel(colors);
-   if (pclindex > 8) /* can't use indexed mode */
-      pclindex = 0;
-   else
-      switch (pclindex) { /* round up to 1,2,4,8 */
-      case 0: /* direct mode (no palette) */
-	 bpp = bitsperpixel(maxval); /* bits per pixel */
-	 bpg = bpp; bpb = bpp;
-	 bpp = (bpp*3+7)>>3;     /* bytes per pixel now */
-	 bpr = (bpp<<3)-bpg-bpb; 
-	 bpp *= cols;            /* bytes per row now */
-	 break;
-      case 5:         pclindex++;
-      case 6:         pclindex++;
-      case 3: case 7: pclindex++;
-      default:
-	 bpp = 8/pclindex;
-	 bpp = (cols+bpp-1)/bpp;      /* bytes per row */
-      }
+    pm_proginit(&argc, argv);
 
-   if ((inrow = (char *)malloc((unsigned)bpp)) == NULL ||
-       (outrow = (char *)malloc((unsigned)bpp*2)) == NULL ||
-       (runcnt = (signed char *)malloc((unsigned)bpp)) == NULL)
-      pm_error("can't allocate space for row");
-
-   /* set up image details */
-   if (xscale != 0.0)
-      xsize = cols * xscale * 4;
-   if (yscale != 0.0)
-      ysize = rows * yscale * 4;
-
-#ifdef DEBUG
-   fprintf(stderr, "dark    =%d\n", dark);
-   fprintf(stderr, "diffuse =%d\n", diffuse);
-   fprintf(stderr, "dither  =%d\n", dither);
-   fprintf(stderr, "cluster =%d\n", cluster);
-   fprintf(stderr, "quality =%d\n", quality);
-   fprintf(stderr, "xsize   =%d\n", xsize);
-   fprintf(stderr, "ysize   =%d\n", ysize);
-   fprintf(stderr, "xshift  =%d\n", xshift);
-   fprintf(stderr, "yshift  =%d\n", yshift);
-   fprintf(stderr, "xscale  =%lf\n", xscale);
-   fprintf(stderr, "yscale  =%lf\n", yscale);
-   fprintf(stderr, "gamma   =%lf\n", gamma_val);
-   fprintf(stderr, "pclindex   =%d\n", pclindex);
-   fprintf(stderr, "nopack  =%d\n", nopack);
-#endif
+    while (argc > 1 && argv[1][0] == '-') {
+        unsigned int i;
+        for (i = 0; i < sizeof(options)/sizeof(struct options); i++) {
+            if (pm_keymatch(argv[1], options[i].name,
+                            MIN(strlen(argv[1]), strlen(options[i].name)))) {
+                const char * c;
+                switch (options[i].type) {
+                case DIM:
+                    if (++argv, --argc == 1)
+                        pm_usage(usage);
+                    for (c = argv[1]; ISDIGIT(*c); c++);
+                    if (c[0] == 'p' && c[1] == 't') /* points */
+                        *(int *)(options[i].value) = atoi(argv[1])*10;
+                    else if (c[0] == 'd' && c[1] == 'p') /* decipoints */
+                        *(int *)(options[i].value) = atoi(argv[1]);
+                    else if (c[0] == 'i' && c[1] == 'n') /* inches */
+                        *(int *)(options[i].value) = atoi(argv[1])*720;
+                    else if (c[0] == 'c' && c[1] == 'm') /* centimetres */
+                        *(int *)(options[i].value) = atoi(argv[1])*283.46457;
+                    else if (!c[0]) /* dots */
+                        *(int *)(options[i].value) = atoi(argv[1])*4;
+                    else
+                        pm_error("illegal unit of measure %s", c);
+                    break;
+                case REAL:
+                    if (++argv, --argc == 1)
+                        pm_usage(usage);
+                    *(double *)(options[i].value) = atof(argv[1]);
+                    break;
+                case BOOL:
+                    *(int *)(options[i].value) = 1;
+                    break;
+                }
+                break;
+            }
+        }
+        if (i >= sizeof(options)/sizeof(struct options))
+            pm_usage(usage);
+        argv++; argc--;
+    }
+    if (argc > 2)
+        pm_usage(usage);
+    else if (argc == 2)
+        ifP = pm_openr(argv[1]);
+    else
+        ifP = stdin ;
+
+    /* validate arguments */
+    if (diffuse+cluster+dither > 1)
+        pm_error("only one of -diffuse, -dither and -cluster may be used");
+    render = diffuse ? 4 : dither ? 3 : cluster ? 7 : 0;
+
+    if (xsize != 0.0 && xscale != 0.0)
+        pm_error("only one of -xsize and -xscale may be used");
+
+    if (ysize != 0.0 && yscale != 0.0)
+        pm_error("only one of -ysize and -yscale may be used");
+
+    pixels = ppm_readppm(ifP, &cols, &rows, &maxval);
+    pm_close(ifP);
+
+    /* limit checks */
+    if (cols > PCL_MAXWIDTH || rows > PCL_MAXHEIGHT)
+        pm_error("image too large; reduce with ppmscale");
+    if (maxval > PCL_MAXVAL)
+        pm_error("color range too large; reduce with ppmcscale");
 
-   /* write PCL header */
+    /* Figure out the colormap. */
+    pm_message("Computing colormap...");
+    chv = ppm_computecolorhist(pixels, cols, rows, MAXCOLORS, &colors);
+    if (!chv)
+        pm_error("too many colors; reduce with pnmquant");
+    pm_message("... Done.  %u colors found.", colors);
+
+    /* And make a hash table for fast lookup. */
+    cht = ppm_colorhisttocolorhash(chv, colors);
+
+    /* work out color downloading mode */
+    pclindex = bitsperpixel(colors);
+    if (pclindex > 8) /* can't use indexed mode */
+        pclindex = 0;
+    else {
+        switch (pclindex) { /* round up to 1,2,4,8 */
+        case 0: /* direct mode (no palette) */
+            bpp = bitsperpixel(maxval); /* bits per pixel */
+            bpg = bpp; bpb = bpp;
+            bpp = (bpp*3+7)>>3;     /* bytes per pixel now */
+            bpr = (bpp<<3)-bpg-bpb; 
+            bpp *= cols;            /* bytes per row now */
+            break;
+        case 5:         pclindex++;
+        case 6:         pclindex++;
+        case 3: case 7: pclindex++;
+        default:
+            bpp = 8/pclindex;
+            bpp = (cols+bpp-1)/bpp;      /* bytes per row */
+        }
+    }
+    inrow = (char *)malloc((unsigned)bpp);
+    outrow = (char *)malloc((unsigned)bpp*2);
+    runcnt = (signed char *)malloc((unsigned)bpp);
+    if (inrow == NULL || outrow == NULL || runcnt == NULL)
+        pm_error("can't allocate space for row");
+
+    /* set up image details */
+    if (xscale != 0.0)
+        xsize = cols * xscale * 4;
+    if (yscale != 0.0)
+        ysize = rows * yscale * 4;
+
+    /* write PCL header */
 #if 0
-   printf("\033&l26A");                         /* paper size */
+    printf("\033&l26A");                         /* paper size */
 #endif
-   printf("\033*r%ds%dT", cols, rows);          /* source width, height */
-   if (xshift != 0 || yshift != 0)
-      printf("\033&a%+dh%+dV", xshift, yshift); /* xshift, yshift */
-   if (quality)
-      printf("\033*o%dQ", quality);             /* print quality */
-   printf("\033*t");
-   if (xsize == 0 && ysize == 0)
-      printf("180r");                   /* resolution */
-   else {                               /* destination width, height */
-      if (xsize != 0)
-	 printf("%dh", xsize);
-      if (ysize != 0)
-	 printf("%dv", ysize);
-   }
-   if (gamma_val != 0)
-      printf("%.3fi", gamma_val);                    /* gamma correction */
-   if (dark)
-      printf("%dk", dark);              /* scaling algorithms */
-   printf("%dJ", render);               /* rendering algorithm */
-   printf("\033*v18W");                           /* configure image data */
-      putchar(0); /* relative colors */
-      putchar(pclindex ? 1 : 3); /* index/direct pixel mode */
-      putchar(pclindex); /* ignored in direct pixel mode */
-      if (pclindex) {
-	 putchar(0);
-	 putchar(0);
-	 putchar(0);
-      } else {
-	 putchar(bpr); /* bits per red */
-	 putchar(bpg); /* bits per green */
-	 putchar(bpb); /* bits per blue */
-      }
-      putword(maxval); /* max red reference */
-      putword(maxval); /* max green reference */
-      putword(maxval); /* max blue reference */
-      putword(0); /* min red reference */
-      putword(0); /* min green reference */
-      putword(0); /* min blue reference */
-   if (pclindex) {                        /* set palette */
-      for (i = 0; i < colors; i++) {
-	 int r, g, b;
-	 r = PPM_GETR( chv[i].color );
-	 g = PPM_GETG( chv[i].color );
-	 b = PPM_GETB( chv[i].color );
-	 if (i == 0)
-	    printf("\033*v");
-	 if (r)
-	    printf("%da", r);
-	 if (g)
-	    printf("%db", g);
-	 if (b)
-	    printf("%dc", b);
-	 if (i == colors-1)
-	    printf("%dI", i);    /* assign color index */
-	 else
-	    printf("%di", i);    /* assign color index */
-      }
-   }
-   ppm_freecolorhist( chv );
-
-   /* start raster graphics at CAP */
-   printf("\033*r%dA", (xsize != 0 || ysize != 0) ? 3 : 1);
-
-   for (row = 0; row < rows; row++) {
-      if (pclindex) { /* indexed color mode */
-	 int out, cnt;
-	 out = cnt = 0;
-	 for (col = 0, pixrow=pixels[row]; col < cols; col++, pixrow++) {
-	    putbits(ppm_lookupcolor( cht, pixrow ), pclindex);
-	 }
-	 putbits(0, 0); /* flush row */
-      } else { /* direct color mode */
-	 for (col = 0, pixrow=pixels[row]; col < cols; col++, pixrow++) {
-	    putbits(PPM_GETR( *pixrow ), bpr);
-	    putbits(PPM_GETG( *pixrow ), bpg);
-	    putbits(PPM_GETB( *pixrow ), bpb); /* don't need to flush */
-	 }
-	 putbits(0, 0); /* flush row */
-      }
-   }
-   printf("\033*rC"); /* end raster graphics */
-   exit(0);
+    printf("\033*r%ds%dT", cols, rows);          /* source width, height */
+    if (xshift != 0 || yshift != 0)
+        printf("\033&a%+dh%+dV", xshift, yshift); /* xshift, yshift */
+    if (quality)
+        printf("\033*o%dQ", quality);             /* print quality */
+    printf("\033*t");
+    if (xsize == 0 && ysize == 0)
+        printf("180r");                   /* resolution */
+    else {                               /* destination width, height */
+        if (xsize != 0)
+            printf("%dh", xsize);
+        if (ysize != 0)
+            printf("%dv", ysize);
+    }
+    if (gamma_val != 0)
+        printf("%.3fi", gamma_val);                    /* gamma correction */
+    if (dark)
+        printf("%dk", dark);              /* scaling algorithms */
+    printf("%dJ", render);               /* rendering algorithm */
+    printf("\033*v18W");                           /* configure image data */
+    putchar(0); /* relative colors */
+    putchar(pclindex ? 1 : 3); /* index/direct pixel mode */
+    putchar(pclindex); /* ignored in direct pixel mode */
+    if (pclindex) {
+        putchar(0);
+        putchar(0);
+        putchar(0);
+    } else {
+        putchar(bpr); /* bits per red */
+        putchar(bpg); /* bits per green */
+        putchar(bpb); /* bits per blue */
+    }
+    putword(maxval); /* max red reference */
+    putword(maxval); /* max green reference */
+    putword(maxval); /* max blue reference */
+    putword(0); /* min red reference */
+    putword(0); /* min green reference */
+    putword(0); /* min blue reference */
+    if (pclindex) {                        /* set palette */
+        unsigned int i;
+        for (i = 0; i < colors; ++i) {
+            int const r = PPM_GETR( chv[i].color);
+            int const g = PPM_GETG( chv[i].color);
+            int const b = PPM_GETB( chv[i].color);
+            if (i == 0)
+                printf("\033*v");
+            if (r)
+                printf("%da", r);
+            if (g)
+                printf("%db", g);
+            if (b)
+                printf("%dc", b);
+            if (i == colors-1)
+                printf("%dI", i);    /* assign color index */
+            else
+                printf("%di", i);    /* assign color index */
+        }
+    }
+    ppm_freecolorhist(chv);
+
+    /* start raster graphics at CAP */
+    printf("\033*r%dA", (xsize != 0 || ysize != 0) ? 3 : 1);
+
+    for (row = 0; row < rows; row++) {
+        pixel * const pixrow = pixels[row];
+        if (pclindex) { /* indexed color mode */
+            unsigned int col;
+            for (col = 0; col < cols; ++col)
+                putbits(ppm_lookupcolor(cht, &pixrow[col]), pclindex);
+            putbits(0, 0); /* flush row */
+        } else { /* direct color mode */
+            unsigned int col;
+            for (col = 0; col < cols; ++col) {
+                putbits(PPM_GETR(pixrow[col]), bpr);
+                putbits(PPM_GETG(pixrow[col]), bpg);
+                putbits(PPM_GETB(pixrow[col]), bpb);
+                /* don't need to flush */
+            }
+            putbits(0, 0); /* flush row */
+        }
+    }
+    printf("\033*rC"); /* end raster graphics */
+
+    return 0;
 }
diff --git a/doc/HISTORY b/doc/HISTORY
index 8f9c68c1..b16d131c 100644
--- a/doc/HISTORY
+++ b/doc/HISTORY
@@ -4,36 +4,39 @@ Netpbm.
 CHANGE HISTORY 
 --------------
 
-08.12.17 BJH  Release 10.44.04
+08.12.28 BJH  Release 10.45.00
+
+              pgmnoise: Add -randomseed.
+
+              ppmtobmp: Add -mapfile option.
+
+              pnm_createBlackTuple(): Fix array bounds violation with
+              PBM, PGM.
+
+              pnmtoddif: Fix crash with any PGM input.
+
+              pgmnoise: Fix bug: never generates full white pixel.
+
+              pamditherbw: Fix -value other than .5 with -fs, -atkinson.
 
               Configure: fix crash when Libxml2 is installed, but not new
               enough version.
 
+              Build: Use GNU compile options for Darwin.
+
               Build: Move CFLAGS later in libjasper and librle build so that a
               -I in CFLAGS doesn't interfere with finding the local libjasper
               and Netpbm header files.
 
-              Build: Add source type declarations to make -ansi compile work.
-
-08.12.03 BJH  Release 10.44.03
-
               Build: Move LDFLAGS later so that a -L in LDFLAGS doesn't
               interfere with finding the built libnetpbm.  (The common
-              link rule is already this way in 10.44.02; all the other
+              link rule is already this way in 10.44.00; all the other
               link rules are now the same).
 
-08.10.27 BJH  Release 10.44.02
-
-              pnm_createBlackTuple(): Fix array bounds violation with
-              PBM, PGM.
-
-              pnmtoddif: Fix crash with any PGM input.
+              Build: Rename Makefile.common, Makefile.config, to common.mk,
+              etc.
 
-              pgmnoise: Fix bug: never generates full white pixel.
-
-08.10.12 BJH  Release 10.44.01
-
-              pamditherbw: Fix -value other than .5 with -fs, -atkinson.
+              Build: Add source type declarations to make -ansi compile work.
 
 08.09.27 BJH  Release 10.44.00
 
@@ -236,6 +239,9 @@ CHANGE HISTORY
 
               Fix bug: ppmdraw.h, ppmdfont.h not installed.
 
+              Add -fPIC to all Gcc compiles of library modules, so it works
+              on AMD64, IA64.
+
               Add Windows version of gethostname to ppmtompeg; normal build
               does not use it.
 
diff --git a/doc/INSTALL b/doc/INSTALL
index c34eafd8..17c7b712 100644
--- a/doc/INSTALL
+++ b/doc/INSTALL
@@ -67,11 +67,11 @@ than you need to do and you will be disappointed with Configure's
 unpredictability, especially from one release to the next.  Configure is
 specifically intended to talk to an intelligent human being.
 
-Rather, just write a program to generate the file Makefile.config.  That's
+Rather, just write a program to generate the file config.mk.  That's
 all Configure does in the end anyway.  Like Configure, your program can
-simply copy Makefile.config.in and add overrides to the bottom.  Or you
-can just package up a complete Makefile.config and not run any program at
-all at build time.  Comments in Makefile.config.in explain the entire
+simply copy config.mk.in and add overrides to the bottom.  Or you
+can just package up a complete config.mk and not run any program at
+all at build time.  Comments in config.mk.in explain the entire
 contents.  You can also run Configure interactively and use its output
 as an example.
 
@@ -92,8 +92,7 @@ For notes on building Netpbm on Windows using Cygwin, see the file
 README.CYGWIN.  With Cygwin, you can build Netpbm programs that use
 Cygwin or Netpbm programs that use Mingw.
 
-For notes on building Netpbm on Windows using Djgpp, see the file
-README.DJGPP.
+Netpbm has also been built for Windows using Djgpp, as late as 2001.
 
 See also the general installation instructions above.
 
@@ -124,18 +123,18 @@ CUSTOM BUILDING
 This section explains how to customize the installation in the case
 that your platform is, or your requirements are, not among the simple
 cases that 'configure' understands.  'configure' is really just a
-convenient way to build the Makefile.config file, and in the most
+convenient way to build the config.mk file, and in the most
 general case, you build that file manually.
 
-Makefile.config contains settings for various things that vary from
+config.mk contains settings for various things that vary from
 one system to the next, like file paths.  Start with the distributed
-file Makefile.config.in.  Copy it as Makefile.config, then edit it.
+file config.mk.in.  Copy it as config.mk, then edit it.
 Search for your platform name (Solaris, SunOS, NetBSD, Cygwin, BeOS,
 and Tru64 are among those mentioned) to see recommended settings for
 your platform.
 
 If your system is even too exotic to accomodate with settings in
-Makefile.config, you may need to modify things in the main make files
+config.mk, you may need to modify things in the main make files
 or pm_config.h.in.
 
 If you figure out how to install on other platforms, contact the
@@ -193,8 +192,8 @@ Netpbm build to statically bind the libraries into the Netpbm programs).
 Another thing you can do is forget about library search paths and just
 build into each Netpbm executable the location of the Netpbm shared
 library.  (I'm talking about the classic -R linker option) You set
-this up with variables in Makefile.config.  If you use Configure to
-build Makefile.config, then for some platforms where this method is
+this up with variables in config.mk.  If you use Configure to
+build config.mk, then for some platforms where this method is
 common, the Configure dialog asks you what directory, if any, you want
 built into Netpbm executables.
 
@@ -214,7 +213,7 @@ Since shared libraries can be such a pain, and in fact some systems
 don't even have them, you can build Netpbm with a static library
 instead.  Just answer "static" to the static/shared question when you
 run 'configure' (if you don't use 'configure', set NETPBMLIBTYPE as
-directed in Makefile.config.in).
+directed in config.mk.in).
 
 If you do this, you probably want to do a merge build instead of the
 normal build (there's a question for that in the Configure program).
@@ -257,7 +256,7 @@ MERGE BUILD
 There are two ways to build Netpbm: the standard or nonmerge build,
 and the merge build.  There are different make file targets for them
 and which one is default is controlled by the DEFAULT_TARGET make
-variable in Makefile.config, and its value is one of the choices you
+variable in config.mk, and its value is one of the choices you
 make via the Configure dialog.
 
 The standard build is the conventional one.  The merge build is a way
diff --git a/doc/README.CYGWIN b/doc/README.CYGWIN
index 6c11ff35..a9867aae 100644
--- a/doc/README.CYGWIN
+++ b/doc/README.CYGWIN
@@ -66,7 +66,7 @@ search for include files and link libraries in a different place,
 which is basically just a -mno-cygwin option and -I and -L options.
 
 You can easily add the compiler options you need at the bottom of
-Makefile.config after you create it with the automatic configurator
+config.mk after you create it with the automatic configurator
 ('configure').
 
 Mingw does not have the Unix process management facilities (fork/wait,
diff --git a/doc/README.DJGPP b/doc/README.DJGPP
deleted file mode 100644
index 773a22e7..00000000
--- a/doc/README.DJGPP
+++ /dev/null
@@ -1,65 +0,0 @@
-Warning: The Netpbm distribution uses long filenames, so you can only
-build the package in a W9x environment, with LFN support.
-
-To build Netpbm with DJGPP v2.0x you need:
-
-        - djgpp: gcc, make, and binutils
-        - bash 
-        - fileutils
-        - sed
-        - groff (to convert man pages to cat format)
-        - man and less (to read the converted man pages)
-
-You can fetch all packages on Simtelnet in the DJGPP tree:
-ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/
-
-You need too four external libraries to add tiff, png and jpeg support
-to Netpbm (you can build without them, modifying Makefile.config.djgpp
-but I think it makes Netpbm useless).
-
-        - Libtiff (www.libtiff.org)
-        - Libjpeg (www.ijg.org)
-        - Libpng  (www.libpng.org/pub/png/libpng.html)
-        - Libz    (www.info-zip.org/pub/infozip)
-
-All libraries come with guidelines to compile ok with DJGPP. At this time
-you can get binary packages of libjpeg, libpng and libz on Simtelnet.
-
-
-To build the Netpbm programs do the following:
-
-  Copy Makefile.config.djgpp to Makefile.config
-
-  Run "touch Makefile.config" to prevent Make from updating the file.
-
-  Read the Makefile.config and make any changes you want
-
-  Do "make merge"
-
-  Do "make install-merge" to install binaries and man pages.
-
-  Makefile.config.djgpp is set up to install these in TMPDIR/netpbm
-  (normally /dgjpp/tmp/netpbm).  If everything worked OK, you can
-  move the contents of this directory to your DJGPP production tree.
-
-
-WARNING
-
-There are some problems that have to be addressed if using the
-binaries in pure DOS OS, without long file names, but it works OK
-using "netpbm <utility>" (<utility> is the real Netpbm program to be
-used, for example: 
-
-      netpbm ppmtobmp <testimg.ppm >testimg.bmp
-
-instead of the usual
-
-      ppmtobmp <testimg.ppm >testimg.bmp).
-
-
-
-This procedure and the code to adapt Netpbm to DJGPP was contributed by
-M.Alvarez <malfer@teleline.es> in August 2001.  You can find his 
-current information on using Netpbm with DJGPP and prebuilt binaries
-at <http://www.terra.es/personal/malfer/netpbm/netpbm.htm>.
-
diff --git a/doc/USERDOC b/doc/USERDOC
index 9c224288..3dcfb00d 100644
--- a/doc/USERDOC
+++ b/doc/USERDOC
@@ -60,7 +60,7 @@ to go straight to the Ppmtogif documentation.
 
 Installnetpbm normally installs Manweb and the netpbm.url file that
 Manweb needs to find the Netpbm documentation.  Through the Configure
-dialog, or editing Makefile.config, you determine whether Manweb
+dialog, or editing config.mk, you determine whether Manweb
 accesses the master web copy or a local copy you installed.
 
 Installnetpbm installs the program as 'manweb'.  If you want to invoke
diff --git a/editor/Makefile b/editor/Makefile
index fd145b53..842cf31a 100644
--- a/editor/Makefile
+++ b/editor/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = editor
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 # We tend to separate out the build targets so that we don't have
 # any more dependencies for a given target than it really needs.
@@ -53,7 +53,7 @@ MERGE_OBJECTS = $(MERGEBINARIES:%=%.o2)
 .PHONY: all
 all: $(BINARIES)
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 install.bin: install.bin.local
 
diff --git a/editor/pamditherbw.c b/editor/pamditherbw.c
index 076bec31..769a8d44 100644
--- a/editor/pamditherbw.c
+++ b/editor/pamditherbw.c
@@ -407,8 +407,13 @@ struct fsState {
         */
     bool fs_forward;
         /* We're going forward (left to right) through the current row */
-    samplen threshval;
-        /* The power value we consider to be half white */
+    samplen white;
+        /* The power value we consider to be white (normally 1.0).
+           Constant. */
+    samplen halfWhite;
+        /* The power value we consider to be half white (always half of
+           'white'; carried separately to save computation)
+        */
 };
 
 
@@ -438,37 +443,39 @@ fsConvertRow(struct converter * const converterP,
     }
 
     do {
-        samplen sum;
+        samplen const thisPixelPower =
+            MIN(pm_ungamma709(grayrow[col][0]), stateP->white);
+        samplen accum;
 
-        sum = MIN(2*stateP->threshval, pm_ungamma709(grayrow[col][0])) +
-            thiserr[col + 1];
-        if (sum >= stateP->threshval) {
+        accum = thisPixelPower + thiserr[col + 1];
+
+        if (accum >= stateP->halfWhite) {
             /* We've accumulated enough light (power) to justify a
                white output pixel.
             */
             bitrow[col][0] = PAM_BW_WHITE;
             /* Remove from sum the power of this white output pixel */
-            sum -= 2*stateP->threshval;
+            accum -= stateP->white;
         } else
             bitrow[col][0] = PAM_BLACK;
-        
+
         /* Forward to future output pixels the power from current
            input pixel and the power forwarded from previous input
            pixels to the current pixel, less any power we put into the
            current output pixel.
         */
         if (stateP->fs_forward) {
-            thiserr[col + 2] += (sum * 7) / 16;
-            nexterr[col    ] += (sum * 3) / 16;
-            nexterr[col + 1] += (sum * 5) / 16;
-            nexterr[col + 2] += (sum * 1) / 16;
+            thiserr[col + 2] += (accum * 7) / 16;
+            nexterr[col    ] += (accum * 3) / 16;
+            nexterr[col + 1] += (accum * 5) / 16;
+            nexterr[col + 2] += (accum * 1) / 16;
             
             ++col;
         } else {
-            thiserr[col    ] += (sum * 7) / 16;
-            nexterr[col + 2] += (sum * 3) / 16;
-            nexterr[col + 1] += (sum * 5) / 16;
-            nexterr[col    ] += (sum * 1) / 16;
+            thiserr[col    ] += (accum * 7) / 16;
+            nexterr[col + 2] += (accum * 3) / 16;
+            nexterr[col + 1] += (accum * 5) / 16;
+            nexterr[col    ] += (accum * 1) / 16;
             
             --col;
         }
@@ -519,7 +526,8 @@ createFsConverter(struct pam * const graypamP,
             stateP->thiserr[col] = ((float)rand()/RAND_MAX - 0.5) / 4;
     }
 
-    stateP->threshval  = threshFraction;
+    stateP->halfWhite = threshFraction;
+    stateP->white = 2 * threshFraction;
 
     stateP->fs_forward = TRUE;
 
@@ -540,8 +548,13 @@ struct atkinsonState {
 
            For R == 0, C is a column we haven't done yet.
         */
-    samplen threshval;
-        /* The power value we consider to be half white */
+    samplen white;
+        /* The power value we consider to be white (normally 1.0).
+           Constant. */
+    samplen halfWhite;
+        /* The power value we consider to be half white (always half of
+           'white'; carried separately to save computation)
+        */
 };
 
 
@@ -583,17 +596,16 @@ atkinsonConvertRow(struct converter * const converterP,
     unsigned int col;
 
     for (col = 0; col < converterP->cols; ++col) {
-        samplen sum;
+        samplen accum;
 
-        sum = MIN(2*stateP->threshval, pm_ungamma709(grayrow[col][0])) +
-            error[0][col + 1];
-        if (sum >= stateP->threshval) {
+        accum = pm_ungamma709(grayrow[col][0]) + error[0][col + 1];
+        if (accum >= stateP->halfWhite) {
             /* We've accumulated enough light (power) to justify a
                white output pixel.
             */
             bitrow[col][0] = PAM_BW_WHITE;
-            /* Remove from sum the power of this white output pixel */
-            sum -= 2*stateP->threshval;
+            /* Remove from accum the power of this white output pixel */
+            accum -= stateP->white;
         } else
             bitrow[col][0] = PAM_BLACK;
         
@@ -602,13 +614,13 @@ atkinsonConvertRow(struct converter * const converterP,
            pixels to the current pixel, less any power we put into the
            current output pixel.
         */
-        error[0][col+1] += sum/8;
-        error[0][col+2] += sum/8;
+        error[0][col+1] += accum/8;
+        error[0][col+2] += accum/8;
         if (col > 0)
-            error[1][col-1] += sum/8;
-        error[1][col  ] += sum/8;
-        error[1][col+1] += sum/8;
-        error[2][col  ] += sum/8;
+            error[1][col-1] += accum/8;
+        error[1][col  ] += accum/8;
+        error[1][col+1] += accum/8;
+        error[2][col  ] += accum/8;
     }
     
     moveAtkinsonErrorWindowDown(converterP);
@@ -660,7 +672,8 @@ createAtkinsonConverter(struct pam * const graypamP,
         }
     }
 
-    stateP->threshval  = threshFraction;
+    stateP->halfWhite = threshFraction;
+    stateP->white = 2 * threshFraction;
 
     converter.stateP = stateP;
 
diff --git a/generator/Makefile b/generator/Makefile
index 52de9b10..3c30cdd0 100644
--- a/generator/Makefile
+++ b/generator/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = generator
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 # We tend to separate out the build targets so that we don't have
 # any more dependencies for a given target than it really needs.
@@ -37,4 +37,4 @@ MERGE_OBJECTS = $(MERGEBINARIES:%=%.o2)
 .PHONY: all
 all: $(BINARIES)
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
diff --git a/generator/pgmnoise.c b/generator/pgmnoise.c
index af65a23b..9f6b98c8 100644
--- a/generator/pgmnoise.c
+++ b/generator/pgmnoise.c
@@ -1,66 +1,114 @@
+/*********************************************************************
+   pgmnoise -  create a PGM with white noise
+   Frank Neumann, October 1993
+*********************************************************************/
 
-/*********************************************************************/
-/* pgmnoise -  create a portable graymap with white noise            */
-/* Frank Neumann, October 1993                                       */
-/* V1.1 16.11.1993                                                   */
-/*                                                                   */
-/* version history:                                                  */
-/* V1.0 12.10.1993  first version                                    */
-/* V1.1 16.11.1993  Rewritten to be NetPBM.programming conforming    */
-/*********************************************************************/
-
+#include "mallocvar.h"
+#include "shhopt.h"
 #include "pgm.h"
 
 
-int main(int    argc,
-         char * argv[]) {
-
-    int argn, rows, cols;
-    unsigned int row;
-    gray * destrow;
-
-    const char * const usage = "width height\n        width and height are picture dimensions in pixels\n";
+struct cmdlineInfo {
+    /* All the information the user supplied in the command line,
+       in a form easy for the program to use.
+    */
+    unsigned int width;
+    unsigned int height;
+    unsigned int randomseed;
+    unsigned int randomseedSpec;
+};
+
+
+
+
+static void
+parseCommandLine(int argc, const char ** const argv,
+                 struct cmdlineInfo * const cmdlineP) {
+/*----------------------------------------------------------------------------
+   Note that the file spec array we return is stored in the storage that
+   was passed to us as the argv array.
+-----------------------------------------------------------------------------*/
+    optEntry * option_def;
+        /* Instructions to OptParseOptions3 on how to parse our options.
+         */
+    optStruct3 opt;
+    unsigned int option_def_index;
+
+    MALLOCARRAY_NOFAIL(option_def, 100);
+
+    option_def_index = 0;   /* incremented by OPTENT3 */
+    OPTENT3(0,   "randomseed",   OPT_INT,    &cmdlineP->randomseed,
+            &cmdlineP->randomseedSpec,      0);
+
+    opt.opt_table = option_def;
+    opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
+    opt.allowNegNum = FALSE;  /* We may have parms that are negative numbers */
+
+    optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+        /* Uses and sets argc, argv, and some of *cmdlineP and others. */
+
+    if (argc-1 != 2)
+        pm_error("Wrong number of arguments: %u.  "
+                 "Arguments are width and height of image, in pixels",
+                 argc-1);
+    else {
+        int const width  = atoi(argv[1]);
+        int const height = atoi(argv[2]);
+        
+        if (width <= 0)
+            pm_error("Width must be positive, not %d", width);
+        else
+            cmdlineP->width = width;
+
+        if (height <= 0)
+            pm_error("Height must be positive, not %d", width);
+        else
+            cmdlineP->height = height;
+    }
+}
 
-    /* parse in 'default' parameters */
-    pgm_init(&argc, argv);
 
-    argn = 1;
 
-    /* parse in dim factor */
-    if (argn == argc)
-        pm_usage(usage);
-    if (sscanf(argv[argn], "%d", &cols) != 1)
-        pm_usage(usage);
-    argn++;
-    if (argn == argc)
-        pm_usage(usage);
-    if (sscanf(argv[argn], "%d", &rows) != 1)
-        pm_usage(usage);
 
-    if (cols <= 0 || rows <= 0)
-        pm_error("picture dimensions should be positive numbers");
-    ++argn;
+static void
+pgmnoise(FILE * const ofP,
+         unsigned int const cols,
+         unsigned int const rows,
+         gray         const maxval) {
 
-    if (argn != argc)
-        pm_usage(usage);
+    unsigned int row;
+    gray * destrow;
 
     destrow = pgm_allocrow(cols);
 
-    pgm_writepgminit(stdout, cols, rows, PGM_MAXMAXVAL, 0);
-
-    srand(pm_randseed());
-
-    /* create the (gray) noise */
+    pgm_writepgminit(ofP, cols, rows, maxval, 0);
 
     for (row = 0; row < rows; ++row) {
         unsigned int col;
         for (col = 0; col < cols; ++col)
-            destrow[col] = rand() % (PGM_MAXMAXVAL + 1);
+            destrow[col] = rand() % (maxval + 1);
 
-        pgm_writepgmrow(stdout, destrow, cols, PGM_MAXMAXVAL, 0);
+        pgm_writepgmrow(ofP, destrow, cols, maxval, 0);
     }
 
     pgm_freerow(destrow);
+}
+
+
+
+int main(int          argc,
+         const char * argv[]) {
+    
+    struct cmdlineInfo cmdline;
+
+    pm_proginit(&argc, argv);
+
+    parseCommandLine(argc, argv, &cmdline);
+
+    srand(cmdline.randomseedSpec ? cmdline.randomseed : pm_randseed());
+
+    pgmnoise(stdout, cmdline.width, cmdline.height, PGM_MAXMAXVAL);
 
     return 0;
 }
+
diff --git a/lib/Makefile b/lib/Makefile
index 99629d19..e3dbf97e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = lib
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 DLLTOOL=dlltool
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 ifeq ($(NETPBMLIBTYPE),unixstatic)
 LIBNETPBM = libnetpbm.$(STATICLIBSUFFIX)
@@ -39,7 +39,7 @@ LIBOBJECTS = libpm.o pmfileio.o fileio.o bitio.o colorname.o \
 ifneq (${VMS}x,x)
 LIBOBJECTS += libpbmvms.o
 endif
-# Library objects to be linked but not built by Makefile.common:
+# Library objects to be linked but not built by common.mk:
 LIBOBJECTS_X = \
   util/shhopt.o \
   util/nstring.o \
@@ -65,11 +65,11 @@ SCRIPTS =
 BINARIES = 
 
 OMIT_LIBRARY_RULE = 1
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 INCLUDES = -I$(SRCDIR)/$(SUBDIR) -I. -Iimportinc
 
-# The following must go after Makefile.common because $(LIBNETPBM) may 
+# The following must go after common.mk because $(LIBNETPBM) may 
 # contain a reference to $(NETPBM_MAJOR_RELEASE).
 .PHONY: libnetpbm
 libnetpbm: $(LIBNETPBM)
diff --git a/editor/dithers.h b/lib/dithers.h
index 24a9fb39..05531a32 100644
--- a/editor/dithers.h
+++ b/lib/dithers.h
@@ -1,3 +1,5 @@
+#ifndef DITHERS_H_INCLUDED
+#define DITHERS_H_INCLUDED
 /*
 ** dithers.h
 **
@@ -85,3 +87,4 @@ static int const cluster8[16][16] = {
    { 62, 55, 47, 37, 36, 46, 54, 61, 65, 72, 80, 90, 91, 81, 73, 66}
 };
 
+#endif
diff --git a/lib/ppmcmap.h b/lib/ppmcmap.h
index a39d27c0..dd3e5c14 100644
--- a/lib/ppmcmap.h
+++ b/lib/ppmcmap.h
@@ -36,10 +36,10 @@ ppm_computecolorhist2(FILE * const ifp,
                       const int maxcolors, int * const colorsP );
 
 void
-ppm_addtocolorhist( colorhist_vector chv, 
-                    int * const colorsP, const int maxcolors, 
-                    const pixel * const colorP, 
-                    const int value, const int position );
+ppm_addtocolorhist(colorhist_vector chv, 
+                   int * const colorsP, const int maxcolors, 
+                   const pixel * const colorP, 
+                   const int value, const int position );
 
 void
 ppm_freecolorhist(colorhist_vector const chv);
diff --git a/lib/util/Makefile b/lib/util/Makefile
index 7e4d5378..8b3fa1c1 100644
--- a/lib/util/Makefile
+++ b/lib/util/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = lib/util
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 # nstring is required for asprintf(), etc.  Also some systems don't have
 # snprintf(), e.g. Solaris 2.5.1.  2002.03.29.
@@ -15,7 +15,7 @@ MERGE_OBJECTS =
 
 all: $(UTILOBJECTS)
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 INCLUDES = -I$(SRCDIR)/$(SUBDIR) -I. -Iimportinc
 
@@ -25,5 +25,3 @@ $(UTILOBJECTS):%.o:%.c importinc
 
 testnstring: test.c nstring.h nstring.o
 	$(CC) $(CFLAGS) $(CADD) -o $@ nstring.o $<
-
-include Makefile.depend
diff --git a/lib/util/mallocvar.h b/lib/util/mallocvar.h
index b750e177..1f2be127 100644
--- a/lib/util/mallocvar.h
+++ b/lib/util/mallocvar.h
@@ -87,6 +87,8 @@ reallocProduct(void **      const blockP,
     void * array; \
     array = arrayName; \
     reallocProduct(&array, nElements, sizeof(arrayName[0])); \
+    if (!array) \
+        free(arrayName); \
     arrayName = array; \
 } while (0)
 
diff --git a/other/Makefile b/other/Makefile
index 630f7b4c..a6748347 100644
--- a/other/Makefile
+++ b/other/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = other
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 SUBDIRS = pamx
 
@@ -48,7 +48,7 @@ MERGE_OBJECTS = $(MERGEBINARIES:%=%.o2)
 .PHONY: all
 all: $(BINARIES) $(SUBDIRS:%=%/all)
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 ppmsvgalib: %: %.o $(NETPBMLIB) $(LIBOPT)
 	$(LD) -o $@ $< \
diff --git a/other/pamx/Makefile b/other/pamx/Makefile
index 263e8812..a40ea3a6 100644
--- a/other/pamx/Makefile
+++ b/other/pamx/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = other/pamx
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 EXTERN_INCLUDE =
 ifneq ($(X11LIB),NONE)
@@ -37,7 +37,7 @@ MERGEBINARIES = $(BINARIES)
 
 all: $(BINARIES)
 
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
 
 pamx: $(PAMX_OBJECTS) $(NETPBMLIB) $(LIBOPT)
 	$(LD) -o $@ $(PAMX_OBJECTS) \
diff --git a/srcdir.mk b/srcdir.mk
new file mode 100644
index 00000000..484bb420
--- /dev/null
+++ b/srcdir.mk
@@ -0,0 +1,14 @@
+# This is the version of srcdir.mk that gets used when you build in
+# the source tree.  In contrast, when you build in a separate build tree,
+# you use a version of srcdir.mk that Configure created, which sets SRCDIR
+# to the location of the source tree.
+
+# This is designed to be included by the top level make file, with
+# SRCDIR being passed to all the submakes.  That means that when you
+# build in a separate build tree, you must build from the top; you
+# can't go into a subdirectory and type "make".  When you build in the
+# _source_ tree, local makes work because every local make file checks
+# whether SRCDIR is set, and if it isn't, sets it with the assumption
+# that the build directory and source directory are the same.
+
+SRCDIR = $(CURDIR)
diff --git a/urt/Makefile b/urt/Makefile
index 45972094..b9eacaf9 100644
--- a/urt/Makefile
+++ b/urt/Makefile
@@ -5,7 +5,7 @@ endif
 SUBDIR = urt
 VPATH=.:$(SRCDIR)/$(SUBDIR)
 
-include $(BUILDDIR)/Makefile.config
+include $(BUILDDIR)/config.mk
 
 LIBOBJECTS = Runput.o cmd_name.o \
 	rle_addhist.o rle_error.o rle_getcom.o rle_getrow.o rle_getskip.o \
@@ -31,4 +31,4 @@ BINARIES =
 SCRIPTS =
 
 OMIT_URT_RULE = 1
-include $(SRCDIR)/Makefile.common
+include $(SRCDIR)/common.mk
diff --git a/version.mk b/version.mk
new file mode 100644
index 00000000..a1b6093e
--- /dev/null
+++ b/version.mk
@@ -0,0 +1,4 @@
+NETPBM_MAJOR_RELEASE = 10
+NETPBM_MINOR_RELEASE = 45
+NETPBM_POINT_RELEASE = 0
+