Contents of file 'epsimg.tex':
\input cwebmac
% File: epsimg.w [CWEB source code]
% Last change: February 21, 2004
% Author: Fredrik Jonsson
% Description: CWEB source code for the EPSIMG program. Given a matrix of
% numerical values stored in a regular ASCII text file, the
% EPSIMG program creates a grey-scale Encapsulated PostScript
% image of the matrix using its elements as specification of
% the brightness of the corresponding pixels in the image.
% For information on the CWEB programming language, see
% http://www.literateprogramming.com.
% Compilation: Compile this program by using the enclosed Makefile, or use
% the blocks of the Makefile as listed in section five of the
% documentation (file epsimg.ps or epsimg.pdf). The C source
% code (as generated from this CWEB code) conforms to the ANSI
% standard for the C programming language (which is equivalent
% to the ISO C89 standard for C).
%
% Copyright (C) 2004, Fredrik Jonsson
%
\def\version{1.6}
\def\lastrevdate{February 21, 2004}
\input epsf
\font\eightcmr=cmr8
\font\tensc=cmcsc10
\font\eightcmssq=cmssq8
\font\eightcmssqi=cmssqi8
\font\twentycmcsc=cmcsc10 at 20 truept
\def\epsimg{{\eightcmr EPSIMG\spacefactor1000}}
\def\CEE{{\eightcmr C\spacefactor1000}} % The C programming language
\def\CWEB{{\eightcmr CWEB\spacefactor1000}} % The CWEB programming language
\def\MATLAB{{\eightcmr MATLAB\spacefactor1000}} % The MATLAB ditto
\def\endalg{\vrule height 1.4ex width .6ex depth .4ex} % Rectangular bullet
%
% Define a handy macro for listing the steps of an algorithm.
%
\newdimen\aitemindent \aitemindent=26pt
\newdimen\aitemleftskip \aitemleftskip=36pt
\def\aitem[#1]{\smallbreak\noindent\hbox to 10pt{}%
\hbox to\aitemindent{\bf #1\hfill}%
\hangindent\aitemleftskip\ignorespaces}
%
% Define a handy macro for the list of program revisions.
%
\newdimen\citemindent \citemindent=80pt
\newdimen\citemleftskip \citemleftskip=90pt
\def\citem[#1]{\smallbreak\noindent\hbox to 10pt{}%
\hbox to\citemindent{\bf #1\hfill}%
\hangindent\citemleftskip\ignorespaces}
%
% Define a handy macro for listing of operator descriptions.
%
\newdimen\oitemindent \oitemindent=66pt
\newdimen\oitemleftskip \oitemleftskip=76pt
\def\oitem[#1]{\smallbreak\noindent\hbox to 10pt{}%
\hbox to\oitemindent{\bf #1\hfill}%
\hangindent\oitemleftskip\ignorespaces}
\datethis
\N{1}{1}Introduction.
\vskip 120pt
\centerline{\twentycmcsc Epsimg}
\vskip 20pt
\centerline{Creates grey-scale Encapsulated PostScript images of matrices
of numerical data}
\vskip 2pt
\centerline{(Version \version\ of \lastrevdate)}
\vskip 10pt
\centerline{Written by Fredrik Jonsson}
\vskip 80pt
\noindent
Given a matrix of floating-point numbers stored in a regular ASCII text file,
this \CWEB\footnote{${}ˆ\dagger$}{For information on the \CWEB\ programming
language by Donald E.˜Knuth, as well as samples of \CWEB\ programs, see
{\tt http://www-cs-faculty.stanford.edu/\˜\ \kern -5pt knuth/cweb.html}.
For general information on literate programming, see
{\tt http://www.literateprogramming.com}.} program creates a grey-scale
Encapsulated PostScript (EPS) image of the matrix using its elements as
specification of the brightness of the corresponding pixels in the image.
I do by no means claim to have written a program that generates fully
optimized
Encapsulated PostScript. The output images are in many cases large, and can
in many cases be considerably reduced in size, in particular for binary or
few-level grayscale images, for which run-length encoding easily can be
applied. (In run-length encoding a long row of
identical pixels is parametrized as a loop, without the need of individual
specification of each pixel.) However, for my purposes it works fine, since
I often only is concerned with the evaluation of gray-scale images, generated
by mathematical means and often with no a priori specification of the number
of intensity levels.
Of course, there are other ways of generating Encapsulated PostScript images
of sampled of simulated data, as for example using the {\tt image()} function
of \MATLAB. An advantage with using a stand-alone program, however, is that
it is easily incorporated in scripts for batch processing. In addition, the
\epsimg\ program is provided free of charge.
\bigskip
\noindent Copyright \copyright\ Fredrik Jonsson, 2004.
All rights reserved.
\vfill
\fi
\N{1}{2}Revision history of the program.
\medskip
\citem[2004-01-26]{[v.1.0]} {\tt <jonsson@uni-wuppertal.de>}\hfill\break
First properly working version of the \epsimg\ program. I have now for a
longer time had in my mind that it would be useful to write a stand-alone
program that is capable of generating Encapsulated PostScript images of
data matrices, in similar to the {\tt image()} built-in function of \MATLAB.
In particular, I have lately encountered some problems involving the optical
analysis of diffraction patterns, and in order to visualize my generated data
(without having to use \MATLAB\ every time) I this evening started the coding
in \CWEB.
\citem[2004-01-27]{[v.1.1]} {\tt <jonsson@uni-wuppertal.de>}\hfill\break
Continued with cleaning up the code and adding some features, such as the
possibility of letting the program add a frame outlining the bounding box
of the Encapsulated PostScript image, and a scaling of the $x$- or $y$-axis
to leave the aspect ratio of the square pixels invariant even for non-square
input matrices. Also changed the precision of the coordinates and gray scale
specifications in order to get really smooth images. However, there still seem
to remain some bug that causes the program to refuse to accept data files
containing lines with trailing blank spaces and additional line feeds.
[Coding finished at 00:45, 2004-01-28]
\citem[2004-01-28]{[v.1.2]} {\tt <jonsson@uni-wuppertal.de>}\hfill\break
This morning fixed the remaining bug from yesterday, and wrote a basic example
({\tt example1}) as a block in the {\tt Makefile}, using AWK to generate a
simple interference pattern that is visualized with the help of the \epsimg\
program. Also wrote blocks that provide a proper rescaling of the image
width or height whenever either the width or height is larger than their
respective maximum values. Wrote an example ({\tt example2}) in the
{\tt Makefile} that illustrates this automatic rescaling of the image.
\citem[2004-01-30]{[v.1.3]} {\tt <jonsson@uni-wuppertal.de>}\hfill\break
This evening (time is now 01:55 Saturday morning) I started to sketch on
a partitioning scheme for the reduction of data neccessary to save to disk.
For many of my diffraction images, there are large areas that are of equal
shade, and since they have considerable extent in the $x$- as well as
$y$-direction, a run-length encoding (of the type used in the ancient program
for generation of fractals that I wrote together with Tommy Ekola in 1996)
of the Encapsulated PostScript will not fix the problem to any greater extent.
Therefore, I started formulating a recursive scheme for the partitioning of
data into smaller and smaller sub-blocks of the user-supplied matrix, which
I for the sake of simplicity so far have assumed to be square, of size
$[2ˆM\times 2ˆM]$ for some integer $M$.
Wrote a MetaPost figure {\tt matfig.mp} that illustrates the partition scheme.
\citem[2004-02-07]{[v.1.4]} {\tt <jonsson@uni-wuppertal.de>}\hfill\break
[Athens, Greece] Noticed that when viewed using Ghostview, the figures could
not be zoomed properly. This was corrected by letting the program explicitly
state {\tt \%\%!PS-Adobe-2.0 EPSF-1.2}, and by also explicitly stating the
number of pages (that is to say, one) of the figure in the Encapsulated
PostScript preamble, using {\tt \%\%Pages: 1}.
\citem[2004-02-20]{[v.1.5]} {\tt <jonsson@uni-wuppertal.de>}\hfill\break
[\"Ostergarn, Gotland] Added the command-line options
{\tt --commmented\_postscript} and {\tt --uncommmented\_postscript},
explicitly forcing the program either to include comments on PostScript
routines directly into the generated code (default),
or forcing the program to suppress these comments (giving a slightly reduced
size on disk).
\citem[2004-02-21]{[v.1.6]} {\tt <jonsson@uni-wuppertal.de>}\hfill\break
[\"Ostergarn, Gotland] Wrote the final blocks of a major revision of the
program, concerning the algorithm for generation of individual pixels.
While the program previously explicitly stated the pixel boundaries as paths,
I have now replaced this by a PostScript routine {\tt drawpixel} that takes
a pixel bounding box given by the lower left and upper right corners
$(\langle\PB{\\{llx}}\rangle,\langle\PB{\\{lly}}\rangle)$ and
$(\langle\PB{\\{urx}}\rangle,\langle\PB{\\{ury}}\rangle)$ and draws and fills
the pixel
with a specified gray value.
The syntax for this PostScript routine is (in the PostScript language)
simply {\tt drawpixel} $\langle\PB{\\{llx}}\rangle$ $\langle\PB{\\{lly}}%
\rangle$
$\langle\PB{\\{urx}}\rangle$ $\langle\PB{\\{ury}}\rangle$ $\langle\PB{\|w}%
\rangle$, where
$\langle\PB{\|w}\rangle\in[0,1]$ is the whiteness of the actual pixel.
I did, however, keep the possibility of generating the previous, more
extensive
form of PostScript, and in order to be able to switch the program into
either mode, the options {\tt --compactified\_pixelcode} and
{\tt --extensive\_pixelcode} were added as parts of the startup syntax.
When applied to the previously written example with a $64\times64$-sized
matrix of real numbers, the size of the generated was radically reduced
from 590.3 kB to 152.4 kB, hence corresponding to a reduction by 74\%!
However, there still remain to optimize the code, especially to write
PostScript routines that takes the image matrix and automatically loops
over the indices, instead of the current approach, where the bounding box
of each individual pixel still is specified in the code. (The image generated
by the {\tt image()} routine of \MATLAB\ is still considerably smaller in
size than what the now optimized algorithm provides; so far the generated
PostScript takes approximately 37 byte per pixel, which is far too much
even for ``educational purpose''.)
What remains now is to also include the more clever partitioning of the
image for cases with many adjacent pixels of identical gray value.
\medskip
\centerline{\epsfxsize=40.0mm\epsfbox{examples/example1-compact.eps}}
\medskip\nobreak
\centerline{Figure R1. The example $64\times64$ image used in evaluating
size reduction 2004-02-21.}
\fi
\N{1}{3}Compiling the source code. The program is written in \CWEB, generating
ANSI-C conforming source code and documentation as \TeX-source, and is to
be compiled using the enclosed Makefile, leaving an executable
file {\tt epsimg}\footnote{$\dagger$}{On platforms running Windows NT,
Windows 2000, or any other operating system by Microsoft, the executable
file will instead automatically be called {\tt epsimg.exe}.} and a
PostScript file {\tt epsimg.ps} (the document you currently are reading),
which contains the full documentation of the program:
\bigskip
{\obeyspaces\obeylines\tt
˜ \#
˜ \# Makefile designed for use with ctangle, cweave, gcc, and plain TeX.
˜ \#
˜ \# Copyright (C) 2004, Fredrik Jonsson <jonsson@uni-wuppertal.de>
˜ \#
˜ CTANGLE = ctangle
˜ CC = gcc
˜ CCOPTS = -O2 -Wall -ansi -pedantic \# follow ISO C89 (ANSI) strictly
˜ LNOPTS = -lm
˜ CWEAVE = cweave
˜ TEX = tex
˜ DVIPS = dvips
˜ DVIPSOPT = -ta4 -D1200
˜ ˜
˜ all: epsimg.exe epsimg.ps
˜ ˜
˜ epsimg.exe: epsimg.o \# generate the executable file
˜ \$(CC) \$(CCOPTS) -o epsimg epsimg.o \$(LNOPTS)
˜ ˜
˜ epsimg.o: epsimg.c \# generate the object file
˜ \$(CC) \$(CCOPTS) -c epsimg.c
˜ ˜
˜ epsimg.c: epsimg.w \# generate C code from the CWEB source
˜ \$(CTANGLE) epsimg
˜ ˜
˜ epsimg.ps: epsimg.dvi \# generate the PostScript documentation
˜ \$(DVIPS) \$(DVIPSOPT) epsimg.dvi -o epsimg.ps
˜ ˜
˜ epsimg.dvi: epsimg.tex \# generate the device-independent documentation
˜ \$(TEX) epsimg.tex
˜ ˜
˜ epsimg.tex: epsimg.w \# generate plain TeX code from the CWEB source
˜ \$(CWEAVE) epsimg
˜ ˜
˜ clean:
˜ ˜ -rm -Rf *.c *.o *.exe *.aux *.log *.toc *.idx *.scn *.tex *.dvi}
\bigskip
\fi
\N{1}{4}Running the program. The program is entirely controlled by the command
line options supplied when invoking the program, and the syntax is simply:
\medskip
{\obeyspaces\obeylines\tt
˜ epsimg -i <infile> -o <outfile>
}
\medskip
\noindent
where {\tt <infile>} is a regular text file containing the matrix of numerical
data, and {\tt <outfile>} is the name of the Encapsulated PostScript image
that is to be generated.
Instead of {\tt -i} and {\tt -o}, the switches can equivalently be specified
in their longer forms {\tt --inputfile} and {\tt --outputfile}, respectively.
Several options may additionally be specified; to see a listing of all
available options, simply invoke \epsimg\ with the help switch {\tt -h}
(or, equivalently, {\tt --help} in a longer form), as
\medskip
{\obeyspaces\obeylines\tt
˜ epsimg -h
}
\medskip
\noindent
\fi
\N{1}{5}Compressing the size of the generated Encapsulated Postscript.
In a general sense, the input to the \epsimg\ program is just an arbitrary
matrix of numbers, with no a priori assumption on their individual values
or their ordering.
In many images, however, there are large areas of equal colour (or brightness,
if we stick to the fact that the \epsimg\ program primarily is designed for
the visualization of gray scale images), and instead of sequentially writing
a large list of identical squares, of the same shading but slightly displaced
with respect to one another, one may start thinking that there must be a more
efficient method of saving the image to file.
One possibility is to check the structure sequentially in the order the
squares
are written, and in case many boxes of the same shade appear, say in the
row direction of the supplied matrix, a rectangle with this shade and with
a length corresponding to the number of equal squares is to be drawn instead.
This, however, may be an inefficient method as well, since any directionality
in the image in the column direction of the matrix will be left unnoticed.
In addition, if there are large fields of equal shade, a lot of neighbouring
rows should be possible to further reduce, for example by instead drawing
general rectangles which no longer need to be of the same height as the
basic pixels.
The question therefore arises: Would it not be possible to make a relatively
simple divide-and-conquer description of the matrix, partitioning the matrix
into rectangular building blocks of equal shade?
In Fig.˜1, on possibility of a partitioning scheme for the reduction of the
data needed to save to disk is illustrated.
\bigskip
\centerline{\epsfxsize=107.55mm\epsfbox{matfig/matfig.1}}\medskip\nobreak
\centerline{Figure 1. A possible partitioning scheme for square matrices
of size $[2ˆM\times 2ˆM]$.}
\fi
\N{1}{6}The main program. Here follows the general outline of the main
program.
For the flags that are internally used, for the settings of desired program
actions, the significance of the flags are:
\PB{\.{COMPACTIFIED\_PIXELCODE}} If set to a positive nonzero integer value,
this flag causes the program to generate a
compactified PostScript code for the definitions of the individual boxes
of the image, i.e. the individual pixels.
In order to have one single and generic output stream, the \PB{\.{OUTSTREAM}}
definition provides an easy solution to switching the output from file
to terminal output, depending on which options that are detected at the
command line during startup of the program.
\Y\B\8\#\&{include} \.{<math.h>}\6
\8\#\&{include} \.{<stdio.h>}\6
\8\#\&{include} \.{<stddef.h>}\6
\8\#\&{include} \.{<stdlib.h>}\6
\8\#\&{include} \.{<string.h>}\6
\8\#\&{include} \.{<time.h>}\C{ to get automatically generated timestamp in EPS
header }\6
\8\#\&{define} \.{VERSION\_NUMBER} \5\.{"1.6"}\6
\8\#\&{define} \.{A4\_PAGE\_WIDTH} \5(\T{594})\C{ A4 page width in pt (1/72 in)
}\6
\8\#\&{define} \.{A4\_PAGE\_HEIGHT} \5(\T{841})\C{ A4 page height in pt (1/72
in) }\6
\8\#\&{define} \.{MAXIMUM\_IMAGE\_WIDTH} \5${}(\.{A4\_PAGE\_WIDTH}-\T{144}{}$)%
\C{ 1.0 inch default margin }\6
\8\#\&{define} \.{MAXIMUM\_IMAGE\_HEIGHT} \5${}(\.{A4\_PAGE\_HEIGHT}-%
\T{144}{}$)\C{ 1.0 inch default margin }\6
\8\#\&{define} \.{DEFAULT\_IMAGE\_WIDTH} \5${}(\T{0.8}*\.{MAXIMUM\_IMAGE%
\_WIDTH}){}$\6
\8\#\&{define} \.{DEFAULT\_IMAGE\_XCENTER} \5${}(\.{A4\_PAGE\_WIDTH}/\T{2}){}$\6
\8\#\&{define} \.{DEFAULT\_IMAGE\_YCENTER} \5${}(\.{A4\_PAGE\_HEIGHT}/\T{2}){}$%
\6
\8\#\&{define} \.{DEFAULT\_LINETHICKNESS} \5\T{1}\C{ default line thickness in
pt (1/72 in) }\6
\8\#\&{define} \.{OUTSTREAM} \5${}(\\{outfile\_specified}\?\\{fpout}:%
\\{stdout}){}$\6
\8\#\&{define} \.{SUCCESS} \5\T{0}\C{ Return code for successful program
termination }\6
\8\#\&{define} \.{FAILURE} \5\T{1}\C{ Return code for program termination
caused by failure }\6
\8\#\&{define} \.{COMPACTIFIED\_PIXELCODE} \5\T{1}\6
\8\#\&{define} \.{EXTENSIVE\_PIXELCODE} \5\T{2}\6
\X7:Global variables\X\6
\X8:Subroutines\X\7
\&{int} \\{main}(\&{int} \\{argc}${},\39{}$\&{char} ${}{*}\\{argv}[\,]){}$\1\1%
\2\2\6
${}\{{}$\1\6
\X17:Local variables\X\6
\X18:Parse command line\X\6
\X20:Open files\X\6
\X21:Load text file into image matrix\X\6
\X22:Normalize image matrix\X\6
\X23:Initialize parameters of Encapsulated PostScript image\X\6
\X24:Write preamble of Encapsulated PostScript image\X\6
\X25:Write body of Encapsulated PostScript image\X\6
\X28:Write closing of Encapsulated PostScript image\X\6
\X29:Deallocate image matrix\X\6
\X30:Close files\X\6
\&{return} (\.{SUCCESS});\6
\4${}\}{}$\2\par
\fi
\N{1}{7}Declaration of global variables. The only global variables allowed in
my programs are \PB{\\{optarg}}, which is the string of characters that
specified
the call from the command line, and \PB{\\{progname}}, which simply is the
string
containing the name of the program, as it was invoked from the command line.
\Y\B\4\X7:Global variables\X${}\E{}$\6
\&{extern} \&{char} ${}{*}\\{optarg}{}$;\C{ command line string }\6
\&{char} ${}{*}\\{progname}{}$;\C{ name of the program as invoked from command
line }\par
\U6.\fi
\N{1}{8}Declarations of subroutines used by the program.
\Y\B\4\X8:Subroutines\X${}\E{}$\6
\X9:Display help message\X\6
\X10:Routine for allocation of double vectors\X\6
\X11:Routine for allocation of double matrices\X\6
\X12:Routine for deallocation of double vectors\X\6
\X13:Routine for deallocation of double matrices\X\6
\X14:Routine for checking alphanumeric characters\X\6
\X15:Routine for loading matrix data from text file\X\6
\X16:Routine for unloading matrix data previously loaded from text file\X\par
\U6.\fi
\M{9}Routine for displaying a help message at the screen.
\Y\B\4\X9:Display help message\X${}\E{}$\6
\&{void} \\{showsomehelp}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
${}\\{fprintf}(\\{stderr},\39\.{"Usage:\ \%s\ -i\ infile}\)\.{\ [options]\ [-o\
outfi}\)\.{le]\\n"},\39\\{progname});{}$\6
${}\\{fprintf}(\\{stderr},\39\.{"Options:\\n"});{}$\6
${}\\{fprintf}(\\{stderr},\39\.{"\ \ -i,\ --inputfile\ <}\)\.{str>\ \ \
Specifies\ the}\)\.{\ file\ where\ to\ find\ }\)\.{the\ intensity\\n"}\.{"\ \ \
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ \ \ response\ for\ }\)\.{the\
actual\ property.}\)\.{\\n"});{}$\6
${}\\{fprintf}(\\{stderr},\39\.{"\ \ -o,\ --outputfile\ }\)\.{<str>\ \
Specifies\ the}\)\.{\ file\ where\ to\ save\ }\)\.{the\ trans-\\n"}\.{"\ \ \ \ %
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ \ \ mitted\ optica}\)\.{l\ pulse\
shape.\ Whene}\)\.{ver\ this\\n"});{}$\6
${}\\{fprintf}(\\{stderr},\39\.{"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ }\)\.{\ %
\ \ \ \ \ \ option\ is\ not}\)\.{\ present\ at\ the\ comm}\)\.{and\ line,\\n"}%
\.{"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ \ \ the\ generated}\)%
\.{\ time\ series\ will\ be}\)\.{\ written\\n"}\.{"\ \ \ \ \ \ \ \ \ \ \ \ \ \ %
\ \ \ \ \ }\)\.{\ \ \ \ \ \ \ to\ standard\ t}\)\.{erminal\ output\ inste}\)%
\.{ad,\ in\\n"}\.{"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ \ \
which\ case\ an}\)\.{y\ set\ verbose\ mode\ w}\)\.{ill\ be\ turned\\n"}\.{"\ \ %
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ \ \ off\ (see\ -v\ o}\)%
\.{ption).\\n"});{}$\6
${}\\{fprintf}(\\{stderr},\39\.{"\ \ -s,\ --sequential\ }\)\.{\ \ \ \ \ \ \
Toggle\ sequen}\)\.{tial\ mode.\ Default:\ }\)\.{off.\\n"}\.{"\ \ \ \ \ \ \ \ \
\ \ \ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ \ \ When\ generati}\)\.{ng\ the\
Encapsulated\ }\)\.{PostScript,\\n"}\.{"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ }%
\)\.{\ \ \ \ \ \ \ in\ sequential}\)\.{\ mode,\ the\ data\\n"});{}$\6
${}\\{fprintf}(\\{stderr},\39\.{"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ }\)\.{\ %
\ \ \ \ \ \ is\ scanned\ co}\)\.{lumn/row-wise,\ with\ }\)\.{an\ individual%
\\n"}\.{"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ \ \ pixel\
written}\)\.{\ for\ each\ data\ point}\)\.{\ of\ the\ input\\n"}\.{"\ \ \ \ \ \
\ \ \ \ \ \ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ \ \ matrix.\ In\ th}\)\.{is\ mode\
the\ program\ }\)\.{will\ ignore\\n"}\.{"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\)\.{\ \ \ \ \ \ \ any\ possibili}\)\.{ties\ of\ reducing\ the}\)\.{\ data\
through\\n"}\.{"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ \ \ a\
more\ effici}\)\.{ent\ partitioning\ of\ }\)\.{the\ input\\n"}\.{"\ \ \ \ \ \ \
\ \ \ \ \ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ \ \ matrix.\\n"});{}$\6
${}\\{fprintf}(\\{stderr},\39\.{"\ \ -v,\ --verbose\ \ \ \ }\)\.{\ \ \ \ \ \ \
Toggle\ verbos}\)\.{e\ mode.\ If\ no\ output}\)\.{\ filename\ was\\n"}\.{"\ \ \
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ \ \ specified\ at\ }\)\.{the\
command\ line,\ ve}\)\.{rbose\ mode\\n"}\.{"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
\ }\)\.{\ \ \ \ \ \ \ will\ automati}\)\.{cally\ be\ turned\ off,}\)\.{\ in\
order\ for\\n"}\.{"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ \ \
output\ messag}\)\.{es\ not\ to\ interfere\ }\)\.{with\ the\\n"}\.{"\ \ \ \ \ \
\ \ \ \ \ \ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ \ \ generated\ Enc}\)\.{apsulated\
PostScript}\)\.{\ code.\\n"}\.{"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ }\)\.{\ \
\ \ \ \ \ Default:\ off\\}\)\.{n"});{}$\6
${}\\{fprintf}(\\{stderr},\39\.{"\ \ -h,\ --help\ \ \ \ \ \ \ }\)\.{\ Display\
this\ help\ m}\)\.{essage\ and\ exit\ clea}\)\.{n\\n"});{}$\6
${}\\{fprintf}(\\{stderr},\39\.{"Copyright\ (C)\ 2004\ }\)\.{Fredrik\ Jonsson\
<jon}\)\.{sson@uni-wuppertal.d}\)\.{e>\\n"});{}$\6
\4${}\}{}$\2\par
\U8.\fi
\M{10}The \PB{\\{dvector}(\,)} routine allocate a real-valued vector of double
precision,
with vector index ranging from \PB{\\{nl}} to \PB{\\{nh}}.
\Y\B\4\X10:Routine for allocation of double vectors\X${}\E{}$\6
\&{double} ${}{*}{}$\\{dvector}(\&{long} \\{nl}${},\39{}$\&{long} \\{nh})\1\1\2%
\2\6
${}\{{}$\1\6
\&{double} ${}{*}\|v;{}$\7
${}\|v\K{}$(\&{double} ${}{*}){}$ \\{malloc}${}((\&{size\_t})((\\{nh}-\\{nl}+%
\T{2})*\&{sizeof}(\&{double})));{}$\6
\&{if} ${}(\R\|v){}$\5
${}\{{}$\1\6
${}\\{fprintf}(\\{stderr},\39\.{"Error:\ Allocation\ f}\)\.{ailure\ in\
dvector()\\}\)\.{n"});{}$\6
\\{exit}(\.{FAILURE});\6
\4${}\}{}$\2\6
\&{return} \|v${}-\\{nl}+\T{1};{}$\6
\4${}\}{}$\2\par
\U8.\fi
\M{11}The \PB{\\{dmatrix}(\,)} routine allocate a real-valued matrix of double
precision,
with row index ranging from \PB{\\{nrl}} to \PB{\\{nrh}}, and column index
ranging from
\PB{\\{ncl}} to \PB{\\{nch}}.
\Y\B\4\X11:Routine for allocation of double matrices\X${}\E{}$\6
\&{double} ${}{*}{*}{}$\\{dmatrix}(\&{long} \\{nrl}${},\39{}$\&{long} %
\\{nrh}${},\39{}$\&{long} \\{ncl}${},\39{}$\&{long} \\{nch})\1\1\2\2\6
${}\{{}$\1\6
\&{long} \|i${},{}$ \\{nrow}${}\K\\{nrh}-\\{nrl}+\T{1},{}$ \\{ncol}${}\K%
\\{nch}-\\{ncl}+\T{1};{}$\6
\&{double} ${}{*}{*}\|m;{}$\7
${}\|m\K{}$(\&{double} ${}{*}{*}){}$ \\{malloc}${}((\&{size\_t})((\\{nrow}+%
\T{1})*{}$\&{sizeof}(\&{double} ${}{*})));{}$\6
\&{if} ${}(\R\|m){}$\5
${}\{{}$\1\6
${}\\{fprintf}(\\{stderr},\39\.{"\%s:\ Allocation\ fail}\)\.{ure\ 1\ in\
dmatrix()\ r}\)\.{outine!\\n"},\39\\{progname});{}$\6
\\{exit}(\.{FAILURE});\6
\4${}\}{}$\2\6
${}\|m\MRL{+{\K}}\T{1};{}$\6
${}\|m\MRL{-{\K}}\\{nrl};{}$\6
${}\|m[\\{nrl}]\K{}$(\&{double} ${}{*}){}$ \\{malloc}${}((\&{size\_t})((%
\\{nrow}*\\{ncol}+\T{1})*\&{sizeof}(\&{double})));{}$\6
\&{if} ${}(\R\|m[\\{nrl}]){}$\5
${}\{{}$\1\6
${}\\{fprintf}(\\{stderr},\39\.{"\%s:\ Allocation\ fail}\)\.{ure\ 2\ in\
dmatrix()\ r}\)\.{outine!\\n"},\39\\{progname});{}$\6
\\{exit}(\.{FAILURE});\6
\4${}\}{}$\2\6
${}\|m[\\{nrl}]\MRL{+{\K}}\T{1};{}$\6
${}\|m[\\{nrl}]\MRL{-{\K}}\\{ncl};{}$\6
\&{for} ${}(\|i\K\\{nrl}+\T{1};{}$ ${}\|i\Z\\{nrh};{}$ ${}\|i\PP){}$\1\5
${}\|m[\|i]\K\|m[\|i-\T{1}]+\\{ncol};{}$\2\6
\&{return} \|m;\6
\4${}\}{}$\2\par
\U8.\fi
\M{12}The \PB{\\{free\_dvector}(\,)} routine release the memory occupied by
the
real-valued vector \PB{$\|v[\\{nl}\MRL{{.}{.}}\\{nh}]$}.
\Y\B\4\X12:Routine for deallocation of double vectors\X${}\E{}$\6
\&{void} \\{free\_dvector}(\&{double} ${}{*}\|v,\39{}$\&{long} \\{nl}${},\39{}$%
\&{long} \\{nh})\1\1\2\2\6
${}\{{}$\1\6
\\{free}((\&{char} ${}{*})(\|v+\\{nl}-\T{1}));{}$\6
\4${}\}{}$\2\par
\U8.\fi
\M{13}The \PB{\\{free\_dmatrix}(\,)} routine release the memory occupied by
the
real-valued matrix \PB{$\|m[\\{nrl}\MRL{{.}{.}}\\{nrh}][\\{ncl}\MRL{{.}{.}}%
\\{nch}]$}.
\Y\B\4\X13:Routine for deallocation of double matrices\X${}\E{}$\6
\&{void} \\{free\_dmatrix}(\&{double} ${}{*}{*}\|m,\39{}$\&{long} \\{nrl}${},%
\39{}$\&{long} \\{nrh}${},\39{}$\&{long} \\{ncl}${},\39{}$\&{long} \\{nch})\1\1%
\2\2\6
${}\{{}$\1\6
\\{free}((\&{char} ${}{*})(\|m[\\{nrl}]+\\{ncl}-\T{1}));{}$\6
\\{free}((\&{char} ${}{*})(\|m+\\{nrl}-\T{1}));{}$\6
\4${}\}{}$\2\par
\U8.\fi
\M{14}The \PB{\\{alphanumeric}(\,)} routine takes one character \PB{\\{ch}} as
argument, and
returns 1 (`true') if the character is a sign, numeric, or alphabetical
character; otherwise 0 (`false') is returned.
Of course, this routine could be written in a much simpler manner, using
the corresponding intervals for the ASCII codes of the characters, but
at least this explicit form clearly displays which characters that are
part or not part of the check.
\Y\B\4\X14:Routine for checking alphanumeric characters\X${}\E{}$\6
\&{int} \\{alphanumeric}(\&{char} \\{ch})\1\1\2\2\6
${}\{{}$\1\6
\&{if} ${}((\\{ch}\E\.{'0'})\V(\\{ch}\E\.{'1'})\V(\\{ch}\E\.{'2'})\V(\\{ch}\E%
\.{'3'})\V(\\{ch}\E\.{'4'})\V(\\{ch}\E\.{'5'})\V(\\{ch}\E\.{'6'})\V(\\{ch}\E%
\.{'7'})\V(\\{ch}\E\.{'8'})\V(\\{ch}\E\.{'9'})\V(\\{ch}\E\.{'+'})\V(\\{ch}\E%
\.{'-'})\V(\\{ch}\E\.{'a'})\V(\\{ch}\E\.{'b'})\V(\\{ch}\E\.{'c'})\V(\\{ch}\E%
\.{'d'})\V(\\{ch}\E\.{'e'})\V(\\{ch}\E\.{'f'})\V(\\{ch}\E\.{'g'})\V(\\{ch}\E%
\.{'h'})\V(\\{ch}\E\.{'i'})\V(\\{ch}\E\.{'j'})\V(\\{ch}\E\.{'k'})\V(\\{ch}\E%
\.{'l'})\V(\\{ch}\E\.{'m'})\V(\\{ch}\E\.{'n'})\V(\\{ch}\E\.{'o'})\V(\\{ch}\E%
\.{'p'})\V(\\{ch}\E\.{'q'})\V(\\{ch}\E\.{'r'})\V(\\{ch}\E\.{'s'})\V(\\{ch}\E%
\.{'t'})\V(\\{ch}\E\.{'u'})\V(\\{ch}\E\.{'v'})\V(\\{ch}\E\.{'w'})\V(\\{ch}\E%
\.{'x'})\V(\\{ch}\E\.{'y'})\V(\\{ch}\E\.{'z'})\V(\\{ch}\E\.{'A'})\V(\\{ch}\E%
\.{'B'})\V(\\{ch}\E\.{'C'})\V(\\{ch}\E\.{'D'})\V(\\{ch}\E\.{'E'})\V(\\{ch}\E%
\.{'F'})\V(\\{ch}\E\.{'G'})\V(\\{ch}\E\.{'H'})\V(\\{ch}\E\.{'I'})\V(\\{ch}\E%
\.{'J'})\V(\\{ch}\E\.{'K'})\V(\\{ch}\E\.{'L'})\V(\\{ch}\E\.{'M'})\V(\\{ch}\E%
\.{'N'})\V(\\{ch}\E\.{'O'})\V(\\{ch}\E\.{'P'})\V(\\{ch}\E\.{'Q'})\V(\\{ch}\E%
\.{'R'})\V(\\{ch}\E\.{'S'})\V(\\{ch}\E\.{'T'})\V(\\{ch}\E\.{'U'})\V(\\{ch}\E%
\.{'V'})\V(\\{ch}\E\.{'W'})\V(\\{ch}\E\.{'X'})\V(\\{ch}\E\.{'Y'})\V(\\{ch}\E%
\.{'Z'})\V(\\{ch}\E\.{'.'})){}$\5
${}\{{}$\1\6
\&{return} (\T{1});\C{ yes, this is a sign, a letter, or numeric character }\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
\&{return} (\T{0});\C{ no, this is not a sign, a letter, or numeric character }%
\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U8.\fi
\M{15}The \PB{\\{load\_matrix}(\,)} routine takes as input a character string
\PB{\\{inputfilename}}, specifying a regular text file of ASCII data stored
as a matrix, and returns a pointer \PB{\|m} to a matrix of double precision,
containing the numerical values as appearing if the text file.
The routine also automatically scans the input matrix size, and returns the
number of rows in \PB{\\{nr}} and the number of columns in \PB{\\{nc}}.
The number of columns is determined as the number of elements in the first
row of data of the supplied text file. All subsequent rows are assumed to
contain exactly the same number of elements; if this is not the case, an
error message will be displayed on standard terminal output.
The minimum and maximum elements found in the matrix are returned in the
variables \PB{\\{min}} and \PB{\\{max}}, respectively.
Example of usage:
\medskip
{\obeyspaces\obeylines\tt
˜ double **imagematrix,min,max;
˜ long int nr,nc;
˜ imagematrix=load\_matrix("image.dat",\&nr,\&nc,\&min,\&max);
˜ fprintf(stdout,"Detected \%ld rows and \%ld columns of data.\\n",nr,nc);
˜ fprintf(stdout,"Minimum element: \%f\\n",min);
˜ fprintf(stdout,"Maximum element: \%f\\n",max);
}
\bigskip
\Y\B\4\X15:Routine for loading matrix data from text file\X${}\E{}$\6
\&{double} ${}{*}{*}{}$\\{load\_matrix}(\&{char} \\{inputfilename}[\,]${},%
\39{}$\&{long} ${}{*}\\{nr},\39{}$\&{long} ${}{*}\\{nc},\39{}$\&{double} ${}{*}%
\\{min},\39{}$\&{double} ${}{*}\\{max}){}$\1\1\2\2\6
${}\{{}$\1\6
\&{FILE} ${}{*}\\{fpin}\K\NULL;{}$\6
\&{char} \\{tmpch};\6
\&{long} \|j${},{}$ \|k${},{}$ \\{nrt}${},{}$ \\{nct};\6
\&{double} \\{tmpd}${},{}$ ${}{*}{*}\|m,{}$ \\{tmin}${},{}$ \\{tmax};\7
\&{if} ${}((\\{fpin}\K\\{fopen}(\\{inputfilename},\39\.{"r"}))\E\NULL){}$\5
${}\{{}$\1\6
${}\\{fprintf}(\\{stderr},\39\.{"\%s:\ Could\ not\ open\ }\)\.{file\ \%s\ for\
reading!}\)\.{\\n"},\39\\{progname},\39\\{inputfilename});{}$\6
\\{exit}(\.{FAILURE});\6
\4${}\}{}$\2\6
${}\\{fseek}(\\{fpin},\39\T{0\$L},\39\.{SEEK\_SET});{}$\6
${}\\{fscanf}(\\{fpin},\39\.{"\%lf"},\39{\AND}\\{tmpd});{}$\6
${}\\{tmin}\K\\{tmpd}{}$;\C{ initialize memory for minimum element }\6
${}\\{tmax}\K\\{tmpd}{}$;\C{ initialize memory for maximum element }\6
${}\\{fseek}(\\{fpin},\39\T{0\$L},\39\.{SEEK\_SET});{}$\6
${}\\{nct}\K\T{0}{}$;\C{ initialize column counter }\6
\&{while} ${}((\\{tmpch}\K\\{getc}(\\{fpin}))\I\.{'\\n'}){}$\5
${}\{{}$\C{ determine column size \PB{\\{nc}} }\1\6
${}\\{ungetc}(\\{tmpch},\39\\{fpin});{}$\6
\&{while} ${}((\\{tmpch}\K\\{getc}(\\{fpin}))\E\.{'\ '}){}$\1\5
;\C{ get rid of any leading blanks }\2\6
${}\\{ungetc}(\\{tmpch},\39\\{fpin});{}$\6
\&{while} ${}(\\{alphanumeric}(\\{tmpch}\K\\{getc}(\\{fpin}))){}$\1\5
;\C{ scan pass field }\2\6
${}\\{ungetc}(\\{tmpch},\39\\{fpin});{}$\6
${}\\{nct}\PP;{}$\6
\&{while} ${}((\\{tmpch}\K\\{getc}(\\{fpin}))\E\.{'\ '}){}$\1\5
;\C{ get read of any trailing blanks }\2\6
${}\\{ungetc}(\\{tmpch},\39\\{fpin});{}$\6
\4${}\}{}$\2\6
${}\\{fseek}(\\{fpin},\39\T{0\$L},\39\.{SEEK\_SET});{}$\6
${}\\{nrt}\K\T{0}{}$;\C{ initialize row counter }\6
\&{while} ${}((\\{tmpch}\K\\{getc}(\\{fpin}))\I\.{EOF}){}$\5
${}\{{}$\C{ determine row size \PB{\\{nr}} }\1\6
${}\\{ungetc}(\\{tmpch},\39\\{fpin});{}$\6
\&{for} ${}(\|k\K\T{1};{}$ ${}\|k\Z\\{nct};{}$ ${}\|k\PP){}$\1\5
${}\\{fscanf}(\\{fpin},\39\.{"\%lf"},\39{\AND}\\{tmpd});{}$\2\6
${}\\{nrt}\PP;{}$\6
${}\\{tmpch}\K\\{getc}(\\{fpin});{}$\6
\&{while} ${}((\\{tmpch}\E\.{'\ '})\V(\\{tmpch}\E\.{'\\n'})){}$\1\5
${}\\{tmpch}\K\\{getc}(\\{fpin});{}$\2\6
\&{if} ${}(\\{tmpch}\I\.{EOF}){}$\1\5
${}\\{ungetc}(\\{tmpch},\39\\{fpin});{}$\2\6
\4${}\}{}$\2\6
${}\|m\K\\{dmatrix}(\T{1},\39\\{nrt},\39\T{1},\39\\{nct});{}$\6
${}\\{fseek}(\\{fpin},\39\T{0\$L},\39\.{SEEK\_SET});{}$\6
\&{for} ${}(\|j\K\T{1};{}$ ${}\|j\Z\\{nrt};{}$ ${}\|j\PP){}$\5
${}\{{}$\C{ for all rows, ... }\1\6
\&{for} ${}(\|k\K\T{1};{}$ ${}\|k\Z\\{nct};{}$ ${}\|k\PP){}$\5
${}\{{}$\C{ and for all columns, ... }\1\6
${}\\{fscanf}(\\{fpin},\39\.{"\%lf"},\39{\AND}\\{tmpd});{}$\6
${}\|m[\|j][\|k]\K\\{tmpd};{}$\6
\&{if} ${}(\\{tmpd}<\\{tmin}){}$\1\5
${}\\{tmin}\K\\{tmpd};{}$\2\6
\&{else} \&{if} ${}(\\{tmpd}>\\{tmax}){}$\1\5
${}\\{tmax}\K\\{tmpd};{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\\{fclose}(\\{fpin});\6
${}{*}\\{nr}\K\\{nrt};{}$\6
${}{*}\\{nc}\K\\{nct};{}$\6
${}{*}\\{min}\K\\{tmin};{}$\6
${}{*}\\{max}\K\\{tmax};{}$\6
\&{return} \|m;\6
\4${}\}{}$\2\par
\U8.\fi
\M{16}The \PB{\\{unload\_matrix}(\,)} routine simply releases memory previously
allocated
by the \PB{\\{load\_matrix}(\,)} routine.
\Y\B\4\X16:Routine for unloading matrix data previously loaded from text file%
\X${}\E{}$\6
\&{void} \\{unload\_matrix}(\&{double} ${}{*}{*}\|m,\39{}$\&{long} \\{nr}${},%
\39{}$\&{long} \\{nc})\1\1\2\2\6
${}\{{}$\1\6
${}\\{free\_dmatrix}(\|m,\39\T{1},\39\\{nr},\39\T{1},\39\\{nc}){}$;\C{ yes, it
is this simple... }\6
\4${}\}{}$\2\par
\U8.\fi
\N{1}{17}Declaration of local variables of the \PB{\\{main}} program.
\Y\B\4\X17:Local variables\X${}\E{}$\6
\&{double} ${}{*}{*}\\{imagematrix},{}$ \\{min}${},{}$ \\{max}${},{}$ %
\\{dx}${},{}$ \\{dy}${},{}$ \\{llx}${},{}$ \\{lly}${},{}$ \\{urx}${},{}$ %
\\{ury};\6
\&{double} \\{imagewidth}${},{}$ \\{imageheight}${},{}$ \\{imagexcenter}${},{}$
\\{imageycenter};\6
\&{double} \\{linethickness}${}\K\.{DEFAULT\_LINETHICKNESS};{}$\6
\&{time\_t} \\{now}${}\K\\{time}(\NULL);{}$\6
\&{long} \&{int} \|j${},{}$ \|k${},{}$ \\{nr}${},{}$ \\{nc};\6
\&{int} \\{no\_arg}${},{}$ \\{bbllx}${},{}$ \\{bblly}${},{}$ \\{bburx}${},{}$ %
\\{bbury};\6
\&{FILE} ${}{*}\\{fpout}\K\NULL;{}$\6
\&{char} \\{inputfilename}[\T{256}]${}\K\.{""},{}$ \\{outputfilename}[%
\T{256}]${}\K\.{""};{}$\6
\&{short} \\{verbose}${}\K\T{0},{}$ \\{write\_floatform}${}\K\T{0},{}$ \\{write%
\_frame}${}\K\T{1};{}$\6
\&{short} \\{infile\_specified}${}\K\T{0},{}$ \\{outfile\_specified}${}\K%
\T{0},{}$ \\{parse\_data\_sequentially}${}\K\T{1},{}$ \\{write\_title}${}\K%
\T{0},{}$ \\{write\_xlabel}${}\K\T{0},{}$ \\{write\_ylabel}${}\K\T{0},{}$ %
\\{pixel\_generation\_mode}${}\K\.{COMPACTIFIED\_PIXELCODE},{}$ \\{comments\_in%
\_postscript}${}\K\T{1}{}$;\par
\U6.\fi
\N{1}{18}Parsing command line options. All input parameters are passed to the
program through command line options and arguments to the program.
The syntax of command line options is listed
whenever the program is invoked without any options, or if the {\tt --help}
option is specified at startup.
\Y\B\4\X18:Parse command line\X${}\E{}$\6
${}\{{}$\1\6
${}\\{progname}\K\\{argv}[\T{0}];{}$\6
${}\\{no\_arg}\K\\{argc};{}$\6
\&{while} ${}(\MM\\{argc}){}$\5
${}\{{}$\1\6
\&{if} ${}(\R\\{strcmp}(\\{argv}[\\{no\_arg}-\\{argc}],\39\.{"-o"})\V\R%
\\{strcmp}(\\{argv}[\\{no\_arg}-\\{argc}],\39\.{"--outputfile"})){}$\5
${}\{{}$\1\6
${}\MM\\{argc};{}$\6
${}\\{strcpy}(\\{outputfilename},\39\\{argv}[\\{no\_arg}-\\{argc}]);{}$\6
${}\\{outfile\_specified}\K\T{1};{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\R\\{strcmp}(\\{argv}[\\{no\_arg}-\\{argc}],\39\.{"-i"})\V%
\R\\{strcmp}(\\{argv}[\\{no\_arg}-\\{argc}],\39\.{"--inputfile"})){}$\5
${}\{{}$\1\6
${}\MM\\{argc};{}$\6
${}\\{strcpy}(\\{inputfilename},\39\\{argv}[\\{no\_arg}-\\{argc}]);{}$\6
${}\\{infile\_specified}\K\T{1};{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}((\R\\{strcmp}(\\{argv}[\\{no\_arg}-\\{argc}],\39\.{"-f"}))%
\V(\R\\{strcmp}(\\{argv}[\\{no\_arg}-\\{argc}],\39\.{"--floatform"}))){}$\5
${}\{{}$\1\6
${}\\{write\_floatform}\K(\\{write\_floatform}\?\T{0}:\T{1});{}$\6
\&{if} (\\{verbose})\1\5
${}\\{fprintf}(\\{stdout},\39\.{"\%s:\ Using\ floating\ }\)\.{number\ output.%
\\n"},\39\\{progname});{}$\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}((\R\\{strcmp}(\\{argv}[\\{no\_arg}-\\{argc}],\39\.{"-r"}))%
\V(\R\\{strcmp}(\\{argv}[\\{no\_arg}-\\{argc}],\39\.{"--writeframe"}))){}$\5
${}\{{}$\1\6
${}\\{write\_frame}\K(\\{write\_frame}\?\T{0}:\T{1});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\R\\{strcmp}(\\{argv}[\\{no\_arg}-\\{argc}],\39%
\.{"--commmented\_postsc}\)\.{ript"})){}$\5
${}\{{}$\1\6
${}\\{comments\_in\_postscript}\K\T{1};{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\R\\{strcmp}(\\{argv}[\\{no\_arg}-\\{argc}],\39%
\.{"--uncommmented\_post}\)\.{script"})){}$\5
${}\{{}$\1\6
${}\\{comments\_in\_postscript}\K\T{0};{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\R\\{strcmp}(\\{argv}[\\{no\_arg}-\\{argc}],\39%
\.{"--compactified\_pixe}\)\.{lcode"})){}$\5
${}\{{}$\1\6
${}\\{pixel\_generation\_mode}\K\.{COMPACTIFIED\_PIXELCODE};{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\R\\{strcmp}(\\{argv}[\\{no\_arg}-\\{argc}],\39%
\.{"--extensive\_pixelco}\)\.{de"})){}$\5
${}\{{}$\1\6
${}\\{pixel\_generation\_mode}\K\.{EXTENSIVE\_PIXELCODE};{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\R\\{strcmp}(\\{argv}[\\{no\_arg}-\\{argc}],\39\.{"-v"})\V%
\R\\{strcmp}(\\{argv}[\\{no\_arg}-\\{argc}],\39\.{"--verbose"})){}$\5
${}\{{}$\1\6
${}\\{verbose}\K(\\{verbose}\?\T{0}:\T{1});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\R\\{strcmp}(\\{argv}[\\{no\_arg}-\\{argc}],\39\.{"-s"})\V%
\R\\{strcmp}(\\{argv}[\\{no\_arg}-\\{argc}],\39\.{"--sequential"})){}$\5
${}\{{}$\1\6
${}\\{parse\_data\_sequentially}\K(\\{parse\_data\_sequentially}\?\T{0}:%
\T{1});{}$\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
${}\\{fprintf}(\\{stderr},\39\.{"\%s:\ Unknown\ option\ }\)\.{'\%s'.\\n"},\39%
\\{progname},\39\\{argv}[\\{no\_arg}-\\{argc}]);{}$\6
\\{exit}(\.{FAILURE});\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{if} ${}(\R\\{outfile\_specified}){}$\1\5
${}\\{verbose}\K\T{0}{}$;\C{ terminal output EPS should be clean }\2\6
\4${}\}{}$\2\par
\U6.\fi
\N{1}{19}Opening and closing files for data output.
\fi
\M{20}Open files for reading and writing.
\Y\B\4\X20:Open files\X${}\E{}$\6
${}\{{}$\1\6
\&{if} (\\{outfile\_specified})\5
${}\{{}$\1\6
\&{if} ${}((\\{fpout}\K\\{fopen}(\\{outputfilename},\39\.{"w"}))\E\NULL){}$\5
${}\{{}$\1\6
${}\\{fprintf}(\\{stderr},\39\.{"\%s:\ Could\ not\ open\ }\)\.{file\ \%s\ for\
writing!}\)\.{\\n"},\39\\{progname},\39\\{outputfilename});{}$\6
\\{exit}(\.{FAILURE});\6
\4${}\}{}$\2\6
${}\\{fseek}(\\{fpout},\39\T{0\$L},\39\.{SEEK\_SET});{}$\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
\&{if} (\\{verbose})\1\5
${}\\{fprintf}(\\{stdout},\39\.{"\%s:\ No\ output\ file\ }\)\.{specified.\
(Writing\ }\)\.{to\ stdout).\\n"},\39\\{progname});{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U6.\fi
\M{21}Loading the text file into memory. In this first step, the specified
input
text file is opened, and is loaded into memory allocated by the \PB{%
\\{dmatrix}}
routine. The memory area is accessed via the pointer \PB{${*}{*}%
\\{imagematrix}$}, which
is the basic variable used later on by the blocks that write the Encapsulated
PostScript image to file. After the data is loaded, the input file is closed.
\Y\B\4\X21:Load text file into image matrix\X${}\E{}$\6
${}\{{}$\1\6
\&{if} (\\{infile\_specified})\5
${}\{{}$\1\6
\&{if} (\\{verbose})\1\5
${}\\{fprintf}(\\{stderr},\39\.{"\%s:\ Loading\ data\ fr}\)\.{om\ file\ \%s.%
\\n"},\39\\{progname},\39\\{inputfilename});{}$\2\6
${}\\{imagematrix}\K\\{load\_matrix}(\\{inputfilename},\39{\AND}\\{nr},\39{%
\AND}\\{nc},\39{\AND}\\{min},\39{\AND}\\{max});{}$\6
\&{if} (\\{verbose})\5
${}\{{}$\1\6
${}\\{fprintf}(\\{stdout},\39\.{"\%s:\ Detected\ \%ld\ ro}\)\.{ws\ and\ \%ld\
columns\ o}\)\.{f\ data\ in\ file\ '\%s'.}\)\.{\\n"},\39\\{progname},\39\\{nr},%
\39\\{nc},\39\\{inputfilename});{}$\6
${}\\{fprintf}(\\{stdout},\39\.{"\%s:\ Maximum\ element}\)\.{\ in\ '\%s':\ \%f%
\\n"},\39\\{progname},\39\\{inputfilename},\39\\{max});{}$\6
${}\\{fprintf}(\\{stdout},\39\.{"\%s:\ Minimum\ element}\)\.{\ in\ '\%s':\ \%f%
\\n"},\39\\{progname},\39\\{inputfilename},\39\\{min});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
${}\\{fprintf}(\\{stderr},\39\.{"\%s:\ Error:\ Specify\ }\)\.{an\ input\
filename.\\n}\)\.{"},\39\\{progname});{}$\6
\\{showsomehelp}(\,);\6
\\{exit}(\.{FAILURE});\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U6.\fi
\M{22}Normalize the image matrix. In order to write a properly scaled
Encapsulated
PostScript image to file, the loaded data need to be normalized, so that the
elements arenumerical values between 0 and 1.
\Y\B\4\X22:Normalize image matrix\X${}\E{}$\6
${}\{{}$\1\6
\&{if} (\\{verbose})\1\5
${}\\{fprintf}(\\{stdout},\39\.{"\%s:\ Normalizing\ ima}\)\.{ge\ matrix.\\n"},%
\39\\{progname});{}$\2\6
\&{for} ${}(\|j\K\T{1};{}$ ${}\|j\Z\\{nr};{}$ ${}\|j\PP){}$\5
${}\{{}$\C{ for all rows, ... }\1\6
\&{for} ${}(\|k\K\T{1};{}$ ${}\|k\Z\\{nc};{}$ ${}\|k\PP){}$\5
${}\{{}$\C{ and for all columns, ... }\1\6
${}\\{imagematrix}[\|j][\|k]\K\\{imagematrix}[\|j][\|k]-\\{min};{}$\6
${}\\{imagematrix}[\|j][\|k]\K\\{imagematrix}[\|j][\|k]/(\\{max}-\\{min});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U6.\fi
\M{23}Initialize the parameters to be used for the Encapsulated PostScript
image.
The parameters to be set prior to the calculation of positioning of the
individual pixels of the image are the corner coordinates for the bounding
box.
The $x$-height and $y$-width of the image are generally scaled such that
the aspect ratio of the image is left invariant under scaling of any of the
coordinate axes.
By default, the program will use the width as reference for scaling the height
of the image, to give an aspect ratio (height/width) that leaves the
individual
pixels as squares. If, however, the program finds that the calculated image
height exceed the maximum allowed, then the height will be fixed to its
maximum
value, instead scaling the width of the image (to still give an equal aspect
ratio).
The values here used for the maximum extents of the picture are based on that
for an A4 paper, the limiting bounding box is between the lower left corner
at˜$(0,0)$ pt and upper right corner at˜$(594,841)$ pt.
\bigskip
\centerline{\epsfxsize=114.58mm\epsfbox{pagelayt/pagelayt.1}}\medskip\nobreak
\centerline{Figure 2. The page layout and definitions as used for the
initialization of the Encapsulated PostScript image.}
\Y\B\4\X23:Initialize parameters of Encapsulated PostScript image\X${}\E{}$\6
${}\{{}$\1\6
${}\\{imagewidth}\K((\&{double})(\.{DEFAULT\_IMAGE\_WIDTH}));{}$\6
${}\\{imageheight}\K{}$(((\&{double}) \\{nr})${}/{}$((\&{double}) %
\\{nc}))${}*((\&{double})(\.{DEFAULT\_IMAGE\_WIDTH}));{}$\6
${}\\{imagexcenter}\K\.{DEFAULT\_IMAGE\_XCENTER};{}$\6
${}\\{imageycenter}\K\.{DEFAULT\_IMAGE\_YCENTER};{}$\6
\&{if} ${}(\\{imageheight}>\.{MAXIMUM\_IMAGE\_HEIGHT}){}$\5
${}\{{}$\1\6
\&{if} (\\{verbose})\5
${}\{{}$\1\6
${}\\{fprintf}(\\{stdout},\39\.{"\%s:\ Warning.\ I\ foun}\)\.{d\ that\ the\
height\ of}\)\.{\ "},\39\\{progname});{}$\6
${}\\{fprintf}(\\{stdout},\39\.{"the\ image\ exceeds\ i}\)\.{ts\ maximum%
\\n"});{}$\6
${}\\{fprintf}(\\{stdout},\39\.{"\%s:\ value\ of\ \%d\ pt.}\)\.{\\n"},\39%
\\{progname},\39{}$((\&{int}) \.{MAXIMUM\_IMAGE\_HEIGHT}));\6
${}\\{fprintf}(\\{stdout},\39\.{"\%s:\ Will\ now\ instea}\)\.{d\ scale\ the\
width\ of}\)\.{\ the\ image.\\n"},\39\\{progname});{}$\6
\4${}\}{}$\2\6
${}\\{imageheight}\K\.{MAXIMUM\_IMAGE\_HEIGHT};{}$\6
${}\\{imagewidth}\K{}$(((\&{double}) \\{nc})${}/{}$((\&{double}) \\{nr}))${}*%
\\{imageheight};{}$\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
\&{if} (\\{verbose})\5
${}\{{}$\1\6
${}\\{fprintf}(\\{stdout},\39\.{"\%s:\ Image\ height\ au}\)\.{tomatically\
scaled\ t}\)\.{o\ "},\39\\{progname});{}$\6
${}\\{fprintf}(\\{stdout},\39\.{"width\ (to\ give\ equa}\)\.{l\ aspect\ ratio).%
\\n"});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
${}\\{bbllx}\K\\{imagexcenter}-\\{imagewidth}/\T{2.0};{}$\6
${}\\{bblly}\K\\{imageycenter}-\\{imageheight}/\T{2.0};{}$\6
${}\\{bburx}\K\\{imagexcenter}+\\{imagewidth}/\T{2.0};{}$\6
${}\\{bbury}\K\\{imageycenter}+\\{imageheight}/\T{2.0};{}$\6
\4${}\}{}$\2\par
\U6.\fi
\M{24}Write the leading blocks of Encapsulated PostScript code.
If the flag \PB{\\{pixel\_generation\_mode}} is set to \PB{\.{COMPACTIFIED}%
\.{PIXELCODE}}, then
an additional routine for the generation of the individual pixels will be
added just after the comments in the preamble; otherwise, the generated code
will be self-contained in the sense that the individual pixels are defined
as free-standing drawing statements in the code.
Notice that the type of output stream (terminal output or file pointer,
depending on the options present at the command line at startup of the
program) is determined by the current definition provided by \PB{%
\.{OUTSTREAM}}.
Notice that the string returned by the \PB{\\{ctime}(\,)} routine ends with a
linefeeed.
The blocks dealing with the definition of the PostScript routine for a
more ``compactified'' output code clearly deserves some more detailed
description.
The syntax for drawing an individual pixel, determined by the bounding box
given by its lower left and upper right corners $(x_{\rm ll},y_{\rm ll})$
and $(x_{\rm ur},y_{\rm ur})$ is\par\medskip
{\narrower\narrower{\tt /drawpixel} $\langle\PB{\\{llx}}\rangle$ $\langle\PB{%
\\{lly}}\rangle$
$\langle\PB{\\{urx}}\rangle$ $\langle\PB{\\{ury}}\rangle$ $\langle\PB{\|w}%
\rangle$,\par}
\medskip\noindent
where $\PB{\\{llx}}=x_{\rm ll}$, $\PB{\\{lly}}=y_{\rm ll}$,
$\PB{\\{urx}}=x_{\rm ur}$, and $\PB{\\{ury}}=y_{\rm ur}$.
This definition is illustrated in Fig.˜3 below.
In this description of the syntax, $\PB{\|w}\in[0,1]$ is the whiteness value
of
the pixel, with 0 corresponding to black, and 1 corresponding to white.
\bigskip
\centerline{\epsfxsize=45.0mm\epsfbox{pixbb/pixbb.1}}\medskip\nobreak
\centerline{Figure 3. Illustration of the definition of a pixel in terms
of its lower left and upper right corners.}
\bigskip
In the PostScript routine {\tt /drawpixel}, the following commands of the
PostScript languange are used for manipulation of the stack:
\medskip
\oitem[{\tt dup}]{Duplicates the bottom element in the stack, and then pushes
it into the stack. This operation is similar to the ENTER as used in reverse
polish notation employed in, for example, Hewlett--Packard calculators.}
\oitem[{\tt exch}]{Interchanges the two bottom-most elements in the stack.
This operation is identical to SWAP.}
\oitem[$\langle m\rangle$ $\langle n\rangle$ {\tt roll}]{Rolls down the˜$m$
bottom-most elements of the stack $n$ times, that is to say, applying cyclic
permutation $n$ times on the first $m$ elements.
In analogy with the ROLLD operation of reverse polish notation of
Hewlett--Packard calculators, this is identical to executing the operation
``$m$ ROLLD'' exactly $n$ times.
Notice that $\langle m\rangle$ $\langle m\rangle$ {\tt roll} always just gives
the identity operation on the stack for arbitrary $m$ (of course provided
that˜$m$ is not greater than the number of elements that currently are present
in the stack).
\Y\B\4\X24:Write preamble of Encapsulated PostScript image\X${}\E{}$\6
${}\{{}$\1\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%!PS-Adobe-2.0\ EPS}\)\.{F-1.2\\n"});{}$%
\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\%\%BoundingBox:\ \%d}\)\.{\ \%d\ \%d\ %
\%d\\n"},\39\\{bbllx},\39\\{bblly},\39\\{bburx},\39\\{bbury});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\%\%Creator:\ epsimg}\)\.{\ \%s"},\39%
\.{VERSION\_NUMBER});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ Copyright\ (C)\ 2004}\)\.{\ Fredrik\
Jonsson\\n"});{}$\6
\&{if} (\\{outfile\_specified})\1\5
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\%\%Title:\ \%s\\n"},\39%
\\{outputfilename});{}$\2\6
\&{else}\1\5
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\%\%Title:\ (image\ w}\)\.{ritten\ to\
stdout)\\n"});{}$\2\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\%\%CreationDate:\ \%}\)\.{s"},\39%
\\{ctime}({\AND}\\{now}));{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\%\%Pages:\ 1\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\%\%EndProlog\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\%\%Pages:\ 1\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\%\%Page:\ 1\ 1\\n"});{}$\6
\&{if} ${}(\\{pixel\_generation\_mode}\E\.{COMPACTIFIED\_PIXELCODE}){}$\5
${}\{{}$\1\6
\&{if} (\\{comments\_in\_postscript})\5
${}\{{}$\1\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\ Routine\ for\ dupl}\)\.{icating\ the\
bottom-m}\)\.{ost\ pair"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ of\ elements\ in\ the}\)\.{\
stack."});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\\n"});{}$\6
\4${}\}{}$\2\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"/dupc\ \{dup\ 3\ 2\ roll}\)\.{\ dup\ 4\ 1\
roll\ exch\}\ }\)\.{bind\ def"});{}$\6
\&{if} (\\{comments\_in\_postscript})\5
${}\{{}$\1\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\ Routine\ for\ calc}\)\.{ulating\ the\
lower\ ri}\)\.{ght\ corner"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ coordinates\ of\ the}\)\.{\ pixel.%
\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\ The\ syntax\ is\ si}\)\.{mply\ '<llx>%
\ <lly>\ <u}\)\.{rx>\ <ury>\ "});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ lrc',\ where\ (<llx>}\)\.{,<lly>)%
\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\ and\ (<urx>,<ury>}\)\.{)\ are\
the"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ lower\ left\ and\ upp}\)\.{er\ right\
corner\ coor}\)\.{dinates\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\ of\ the\ pixel.\ Th}\)\.{e\ resulting%
\ (<lrx>,<}\)\.{lry>)\ pair"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ are\ after\ the\ calc}\)\.{ulation\\n\%\%%
\ pushed\ o}\)\.{nto\ the"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ stack,\ preserving\ }\)\.{the\ previously%
\ prese}\)\.{nt\ stack"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ at\ above\\n\%\%\ level}\)\.{s.\\n"});{}$%
\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\\n"});{}$\6
\4${}\}{}$\2\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"/lrc\ \{4\ 1\ roll\ dup\ }\)\.{5\ 2\ roll\
dup\ 5\ -1\ ro}\)\.{ll\ exch"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ 4\ 2\ roll\ 6\ 2\ roll\}}\)\.{\ bind\ def%
\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"/ulc\ \{4\ 3\ roll\ dup\ }\)\.{5\ 2\ roll\
dup\ 6\ -1\ ro}\)\.{ll\ exch\}"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ bind\ def\\n"});{}$\6
\&{if} (\\{comments\_in\_postscript})\5
${}\{{}$\1\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\ Routine\ for\ draw}\)\.{ing\
individual\ pixel}\)\.{s\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\\n"});{}$\6
\4${}\}{}$\2\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"/pixelstack\ \{lrc\ 6\ }\)\.{2\ roll\ ulc\
4\ 2\ roll\ }\)\.{8\ 4\ roll"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ dupc\ 10\ 2\ roll\}\ bi}\)\.{nd\ def%
\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"/drawpixel\ \{setgray}\)\.{\ pixelstack\
newpath\ }\)\.{moveto\ lineto\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ lineto\ lineto\ line}\)\.{to\ closepath\
fill\}\ b}\)\.{ind\ def\\n"});{}$\6
\&{if} (\\{comments\_in\_postscript})\5
${}\{{}$\1\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\ The\ dp\ routine\ i}\)\.{s\
short-hand\ for\ dra}\)\.{wpixel\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\\n"});{}$\6
\4${}\}{}$\2\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"/dp\ \{drawpixel\}\ bin}\)\.{d\ def%
\\n"});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U6.\fi
\M{25}Write the body of Encapsulated PostScript code.
\Y\B\4\X25:Write body of Encapsulated PostScript image\X${}\E{}$\6
${}\{{}$\1\6
\&{if} (\\{parse\_data\_sequentially})\5
${}\{{}$\1\6
\X26:Write body of sequential Encapsulated PostScript image\X\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
\X27:Write body of partitioned Encapsulated PostScript image\X\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U6.\fi
\M{26}Write sequential body of Encapsulated PostScript code.
The {\tt moveto} sets the current starting point of each pixel.
The path of the boundary of each pixel is traversed in counter-clockwise
direction, starting in the lower left corner of each pixel.
Here \PB{$(\\{llx},\\{lly})$} give the $(x,y)$-coordinates of the lower left
corner of
the pixel, while \PB{$(\\{urx},\\{ury})$} give the $(x,y)$-coordinates of the
upper right
corner.
\Y\B\4\X26:Write body of sequential Encapsulated PostScript image\X${}\E{}$\6
${}\{{}$\1\6
${}\\{dx}\K((\&{double})(\\{bburx}-\\{bbllx}))/{}$((\&{double}) \\{nc});\6
${}\\{dy}\K((\&{double})(\\{bbury}-\\{bblly}))/{}$((\&{double}) \\{nr});\6
\&{for} ${}(\|j\K\T{1};{}$ ${}\|j\Z\\{nr};{}$ ${}\|j\PP){}$\5
${}\{{}$\1\6
${}\\{lly}\K{}$((\&{double}) \\{bblly})${}+((\&{double})(\|j-\T{1}))*\\{dy};{}$%
\6
${}\\{ury}\K\\{lly}+\\{dy}*(\T{1.0}+\T{8.0\_-2});{}$\6
;\6
\&{for} ${}(\|k\K\T{1};{}$ ${}\|k\Z\\{nc};{}$ ${}\|k\PP){}$\5
${}\{{}$\1\6
${}\\{llx}\K\\{bbllx}+((\&{double})(\|k-\T{1})*\\{dx});{}$\6
${}\\{urx}\K\\{llx}+\\{dx}*(\T{1.0}+\T{8.0\_-2});{}$\6
\&{if} ${}(\\{pixel\_generation\_mode}\E\.{COMPACTIFIED\_PIXELCODE}){}$\5
${}\{{}$\1\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%1.2f\ \%1.2f\ \%1.2f\ \%}\)\.{1.2f\ %
\%1.3f\ dp\\n"},\39\\{llx},\39\\{lly},\39\\{urx},\39\\{ury},\39\\{imagematrix}[%
\|j][\|k]);{}$\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%1.3f\ setgray\\n"},\39\\{imagematrix}[%
\|j][\|k]);{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"newpath\ \%1.2f\ \%1.2f}\)\.{\ moveto\\n"},%
\39\\{llx},\39\\{lly});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ \%1.2f\ \%1.2f\ lineto}\)\.{"},\39%
\\{urx},\39\\{lly});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ \%1.2f\ \%1.2f\ lineto}\)\.{\\n"},\39%
\\{urx},\39\\{ury});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ \%1.2f\ \%1.2f\ lineto}\)\.{"},\39%
\\{llx},\39\\{ury});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ \%1.2f\ \%1.2f\ lineto}\)\.{\ closepath\
fill\\n"},\39\\{llx},\39\\{lly});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{if} ${}(\T{0}\E\T{1}){}$\5
${}\{{}$\C{ for debugging purposes only }\1\6
\&{for} ${}(\|j\K\T{1};{}$ ${}\|j\Z\\{nr};{}$ ${}\|j\PP){}$\5
${}\{{}$\1\6
\&{for} ${}(\|k\K\T{1};{}$ ${}\|k\Z\\{nc};{}$ ${}\|k\PP){}$\5
${}\{{}$\1\6
${}\\{fprintf}(\\{stdout},\39\.{"\%2.4f\ \ "},\39\\{imagematrix}[\|j][\|k]);{}$%
\6
\4${}\}{}$\2\6
${}\\{fprintf}(\\{stdout},\39\.{"\\n"});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U25.\fi
\M{27}Write partitioned body of Encapsulated PostScript code.
\Y\B\4\X27:Write body of partitioned Encapsulated PostScript image\X${}\E{}$\6
${}\{{}$\1\6
${}\\{fprintf}(\\{stdout},\39\.{"Not\ yet\ finished\ wi}\)\.{th\ non-sequential%
\ pa}\)\.{rtitioning\ of\ data\\n}\)\.{"});{}$\6
${}\\{exit}({-}\T{1});{}$\6
\4${}\}{}$\2\par
\U25.\fi
\M{28}Write the blocks ending the Encapsulated PostScript code.
\Y\B\4\X28:Write closing of Encapsulated PostScript image\X${}\E{}$\6
${}\{{}$\1\6
\&{if} (\\{write\_frame})\5
${}\{{}$\C{ write frame corresponding to bounding box }\1\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"0\ setgray\ 0\ \%1.2f\ d}\)\.{transform\
truncate\ "},\39\\{linethickness});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"idtransform\ setline}\)\.{width\ pop%
\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ []\ 0\ setdash\ 1\ set}\)\.{linejoin\ 10\
setmiter}\)\.{limit\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"newpath\ \%d\ \%d\ movet}\)\.{o\\n"},\39%
\\{bbllx},\39\\{bblly});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ \%d\ \%d\ lineto"},\39\\{bburx},\39%
\\{bblly});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ \%d\ \%d\ lineto\\n"},\39\\{bburx},\39%
\\{bbury});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ \%d\ \%d\ lineto"},\39\\{bbllx},\39%
\\{bbury});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\ \%d\ \%d\ lineto\ close}\)\.{path\ stroke%
\\n"},\39\\{bbllx},\39\\{bblly});{}$\6
\4${}\}{}$\2\6
\&{if} (\\{write\_title})\5
${}\{{}$\1\6
${}\\{fprintf}(\\{stderr},\39\.{"Still\ to\ be\ finishe}\)\.{d!!\\n"});{}$\6
${}\\{exit}({-}\T{1});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%IncludeResource:\ }\)\.{font\ Helvetica%
\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"/Helvetica\ /Windows}\)\.{Latin1Encoding\
120\ F}\)\.{MSR\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"2345\ 2372\ moveto\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"(Intensity\ distribu}\)\.{tion\ in\
observation\ }\)\.{plane)\ s\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"504\ 2372\ moveto\ -90}\)\.{\ rotate%
\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"(y\ [)\ s\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"90\ rotate\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%IncludeResource:\ }\)\.{font\ Symbol%
\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"/Symbol\ /WindowsLat}\)\.{in1Encoding\ 120\
FMSR}\)\.{\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"504\ 2540\ moveto\ -90}\)\.{\ rotate%
\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"(m)\ s\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"90\ rotate\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"504\ 2372\ moveto\ -90}\)\.{\ rotate%
\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"(])\ s\\n"}){}$;\C{ AND SO ON, IN THIS
STYLE .... }\6
\4${}\}{}$\2\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"showpage\\n"});{}$\6
${}\\{fprintf}(\.{OUTSTREAM},\39\.{"\%\%\%\%EOF\\n"});{}$\6
\4${}\}{}$\2\par
\U6.\fi
\M{29}Deallocate memory occupied by the image matrix.
\Y\B\4\X29:Deallocate image matrix\X${}\E{}$\6
${}\{{}$\1\6
${}\\{unload\_matrix}(\\{imagematrix},\39\\{nr},\39\\{nc});{}$\6
\4${}\}{}$\2\par
\U6.\fi
\M{30}Close all open files.
\Y\B\4\X30:Close files\X${}\E{}$\6
${}\{{}$\1\6
\\{fclose}(\\{fpout});\6
\4${}\}{}$\2\par
\U6.\fi
\N{1}{31}Index.
\fi
\inx
\fin
\con