home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
600-699
/
ff696.lha
/
IFSLab
/
IFSLab.doc
< prev
next >
Wrap
Text File
|
1992-07-13
|
43KB
|
875 lines
/*******************************************************************\
* *
* IFS Lab - Iterated Function System Encoding/Rendering Program. *
* *
* Written by Nathan Zeldes, 16 Bet Hakerem St., *
* Jerusalem 96343, Israel. *
* *
* Copyright (C) 1992 by Nathan Zeldes. All Rights Reserved. *
* *
* PROGRAM DOCUMENTATION Version 1.0, June 24, 1992 *
* *
* *
\*******************************************************************/
NOTE: This program uses the file requester in the freeware requester
library written by C.W. Fox and Bruce Dawson. The library file,
req.library, should be placed in your libs: directory. If req.library
is missing, the program will still run but file I/O will be disabled.
=========================
Contents of this Doc File
=========================
Part I. Copyright and Distribution
Part II. User Documentation
1. Quick Start
2. Overview
3. Nomenclature
4. Program Operation philosophy
5. Outline Editor Mode Operation
6. Collage Editor Mode Operation
7. Rendering Mode Operation
8. File I/O Operation
Part III. Programmer Notes
1. Coordinate system and Coefficient Ranges
2. Screens and Windows
3. Outline/Collage Window Colour Scheme
4. Gadget ID's
5. Outline Editor
6. Piece Storage
7. Collage Display mechanics
8. Coefficients Window issues
9. Rendering Mechanics
10. Compilation and Linking
11. Known Bugs
==================================
Part I. Copyright and Distribution
==================================
IFSLab is Copyright (C) 1992 by Nathan Zeldes, 16 Bet Hakerem St.,
Jerusalem 96343, Israel.
This program is made available in the hope that it will give enjoyment to Amiga
users. Permission is granted to freely use and distribute IFSLab subject to
the following conditions:
a. No profit is made on it in any way. Nominal charges to cover cost of
media, duplication, shipping, online services, etc are allowed.
b. The package is distributed in its complete form, consisting of the source
(files IFSLab.c and IFSLab.h), the executable (IFSLab), this documentation
file (IFSLab.doc), the requester library files req.library and req.readme,
and the IFS code files in the subdirectory IFScodes.
c. None of the files is modified in any way without the written permission of
the author.
d. Inclusion of IFSLab in any commercial product is not permitted without the
written permission of the author.
DISCLAIMER: Although it has been tested extensively, IFSLab is provided
"as is", without warranty of any kind. In no event will the author be liable
for any direct or indirect damage or loss resulting from the use or misuse of
this program.
ACKNOWLEDGEMENTS
The IFS method has been developed by Dr. Michael Barnsley (see references in
Overview section below).
Thanks to C.W. Fox and Bruce Dawson for the file requester from their excellent
freeware requester library for the Amiga.
===========================
Part II. User Documentation
===========================
1. Quick Start
--------------
Part II of this doc file contains detailed instructions. If you want to get the
full benefit from this program, you should read it all. The present section is
for the impatient and/or knowledgeable, who want to try the program out right
away!
To run IFSLab, you should first copy the file req.library to your libs:
directory (if you don't have it there already). If you don't, you will still
be able to run IFSLab, but without the ability to load or save files.
Start IFSLab by double clicking its icon, or by typing its name in the Shell or
CLI. Now select the HELP item from the ABOUT menu, and read the brief
instructions it will give you on-screen. Then select the DEMO item from the
ABOUT menu. This will launch a demo of generation of the Sierpinski Triangle,
and illustrate the operation of the program.
Next you may want to load some IFS codes by the PROJECT/LOAD FILE/IFS menuitem;
some interesting codes found by the author and by others are in the directory
'IFScodes'. When a code has been loaded, select the RENDER/START menuitem to
render its attractor. After you've tried the codes in the files, you're on
your own - try to build your own IFS codes (here you will probably HAVE to read
the instructions), and have fun!
2. Overview
-----------
This program implements the IFS algorithm described by Barnsley and Sloan to
allow the design and rendering of fractals in a user-friendly environment. It
provides for the convenient sketching of approximate image outlines by a
paint-program-like mouse-driven user interface, and for definition of IFS Codes
either from a mouse-driven Collage editor or by numeric entry from the
keyboard. The Attractors of the resultant IFS Codes can be rendered in black
and white or in grayscale, in a user-defined resolution. Outlines, IFS Codes
and rendered Images can be saved to or read from disk. The program has a very
flexible IFS loader, which can read IFS code files generated by most other IFS
programs, extracting the relevant codes and converting them as necessary to fit
this program's conventions. On reading in a file, or at the user's command at
any time, the program will generate a collage for the current IFS (using its
attractor as the Outline). A facility for modifying an IFS to fit in the full
screen size is also provided.
For more detailed information on the theory and use of IFS, refer to:
a. M. Barnsley and A. Sloan: A Better Way to Compress Images, BYTE, Jan. 88.
b. H.O. Peitgen and D. Saupe, eds.: The Science of Fractal Images, Chapter 5.
Springer-Verlag, 1988.
c. M.Barnsley: Fractals Everywhere, Academic Press, 1988.
3. Nomenclature
---------------
In this document and program, the following terminology is used:
* Outline - a rough sketch of the fractal-to-be, used as the basis for the
reduced images that form the Collage.
* Transformation - a contractive affine transformation.
* IFS (Iterated Function System), used interchangeably with 'IFS Code' -
a set of N Transformations and their associated probabilities.
* Attractor - the exact fractal image represented by the IFS.
* Density - A parameter assigned to each transformation which describes
its probability per unit area, i.e. how bright it will appear in the
rendering process relative to the other transformations. See details in
section 5, "Collage Editor Mode Operation", under "Definition of Piece
Probabilities".
* Collage - an IFS, represented graphically as an overlay of the Transformed
Outlines on the original Outline.
* Piece - A single transformed image of the outline. The Collage is made from
a set of up to 20 Pieces, representing the transformations in the IFS.
* Image - the reconstructed image (Attractor), as rendered from the IFS using
the random iteration algorithm.
* Coordinate Convention: The Top Left corner of the display area is defined as
the Origin, (0,0), with the positive X axis going to the right and the
positive Y axis going downward. The full display area is defined as 1 unit
in width and 0.6775 units in height (for purposes of the translation
coefficients). This convention makes the rectangular window used for editing
represent the top 2/3 (approximately) of a 1x1 square area in the Real plane.
4. Program Operation philosophy
-------------------------------
IFS Lab differs from some other IFS programs in that it focuses on the Collage
Theorem, i.e. on the fact that in an IFS, the attractor is covered exactly by
its transformed copies. Thus, IFS Lab will allow you to create the Collage
directly, Jigsaw-puzzle style, from actual reduced/deformed images of the
Outline that you can manipulate graphically with the mouse. The program will
also create an exact collage (with the Optimize function), and when reading in
an IFS Code file, will create a Collage for the loaded codes.
Another difference is that IFS Lab uses a FIXED window in the Real plane to
draw in (See above, "Coordinate Convention"). Therefore, no use is made of
offset and scaling factors during rendering; the IFS code has to represent an
attractor that falls within this fixed window. This is mostly irrelevant to
the user, since the OPTIMIZE function provided can modify any IFS codes
violating this requirement (mainly those read in from disk files generated by
other IFS programs, or copied from the literature) so that they will in fact
obey it.
This program deals with 3 types of Objects:
a. Outline. This is a rough line sketch of the approximate image, the one to
be reduced and transformed in the Collage operation. It can be drawn in
Outline Editor mode by the user, or loaded from a disk file. An outline must
exist when the program is in Collage Editor mode; if the user fails to draw or
load it, the program will provide a default outline ("Happy Face" image) when
the user enters the Collage Editor mode. The outline is displayed onscreen as
a one-colour image, and can be saved to disk as an IFF one-bitplane ILBM file.
In Collage Editor mode, the user can specify (by the Optimize menuitem) that
the current IFS code be used to generate automatically a full-screen Collage;
this will use the Attractor of the IFS as an Outline.
b. IFS. This is a collection of between 1 and 20 affine transformations of
the outline. The IFS can be displayed by the program as a collage overlay on
the screen, or as the transformations' coefficients themselves, displayed in a
table. The IFS coefficients can be saved to a disk file; such a file can be
loaded from disk, at which point the loaded coefficients are converted
immediately to a collage of their own attractor.
c. Image. This is the Attractor of the current IFS, and can be rendered in a
user-specified resolution and depth. The image can then be saved to an ILBM
file. The image occupies its own screen and can be brought to the front at any
time by the depth gadgets or by a menu selection. It is erased if a new image
file is loaded or if a new rendering operation is started.
The program has three main modes or environments:
a. Outline Editor mode:
Permits the user to draw the approximate outline of the fractal by mouse.
Includes Freestyle draw, Lines, Erase and Fill functions.
b. Collage Editor mode:
Permits the mouse-driven generation of the transformed images (of the
outline) that are placed onto the outline, from which the IFS transformation
codes are computed by the program. Attractor rendering is initiated from
this mode.
c. Rendering mode:
Here the Attractor of the current IFS is reconstructed by the Random
Iteration Algorithm.
5. Outline Editor Mode Operation
--------------------------------
This is the mode you enter when you start IFS Lab; you can also re-enter it
from the Collage Editor later by selecting the EDIT OUTLINE menuitem.
In this mode, you get a 320x200 screen with a gadget strip at the right and a
drawing window for sketching your outline. The top four gadgets are mutually
exclusive. The selected one (framed in red) defines your Drawing Mode:
- FREE is Freestyle Drawing - you press the left mouse button to draw.
- LINE allows you draw straight lines by dragging the mouse.
- XXX (Erase) turns the mouse into a 5x5 pixel eraser.
- FILL allows you to flood-fill areas of your outline by clicking inside the
closed contour you wish to fill.
- The CLR gadget clears (erases) the entire outline.
- The DONE gadget will end the Outline editing session and enter the Collage
Editor. If you haven't drawn anything and you click DONE, a "Default Outline"
(Happy Face) will be drawn automatically before entering the Collage Editor.
The following Menu items are active in Outline Editor mode:
- PROJECT Menu:
NEW - Erases Outline, reverts to startup condition.
LOAD FILE - OUTLINE - Loads an outline from an IFF disk file (see section 7)
- IFS - Forces an exit to Collage mode, loads an IFS code from a
disk file and Optimizes it (see below).
- IMAGE - Loads an Image from IFF file. The image screen remains
in front until you click in it to push it back.
SAVE FILE - IMAGE - Saves the current Image, if any, to an IFF disk file.
QUIT - Exits program.
- DISPLAY Menu:
SHOW IMAGE - brings the image screen, if one exists, to the front.
- ABOUT Menu:
IFS THEORY, HELP, AUTHOR - Opens text screen, displays the appropriate info.
DEMO - Launches a demo of generation of the Sierpinski Triangle.
IMPORTANT: the more pixels you draw in the Outline, the longer it will take
the Collage Editor to compute the transformed images; so don't over-elaborate.
It is probably best to avoid Area Fills altogether.
6. Collage Editor Mode Operation
--------------------------------
You enter this mode after you've drawn your outline, and clicked the DONE
gadget. Your objective now is to cover the Outline with transformed images
of itself ("Pieces") until it is fully covered.
The Outline is displayed in white on a black background. The collage is built
up by adding Pieces - transformed images of the Outline - one by one, and
manipulating them about the screen. At any time one Piece is "Selected", and
it is this Piece (and its transformation) that the user can manipulate. The
selected Piece is shown on the screen in red whereas all deselected Pieces are
green. The Selected Piece is accompanied by a corresponding Khaki-coloured
vector diagram (see below).
- Creating a Piece:
a. The Default Piece is a half-sized copy of the Outline, placed in midscreen.
b. This Default piece is created automatically on entry to Collage Editor mode.
c. The Default Piece is also created when the user attempts to delete all
existing Pieces.
d. A new Default Piece can be created by clicking the ADD gadget.
e. A new Piece can be made in the same shape as the currently Selected
Piece, by clicking the DUP gadget (it will then overlap the parent piece,
until it is modified or dragged off it).
- Selecting a Piece:
a. A newly created Piece is made Selected on creation.
b. The user can change the current Selection by clicking the SEL gadget.
This will make the selected piece advance backwards cyclically.
c. On loading an IFS from file, the last Piece in the file is Selected.
- Deleting a Piece:
a. Clicking the DEL gadget will cause the Selected Piece to be deleted,
and it will disappear from the display.
b. When a Piece is thus deleted, the next Piece will become Selected.
c. If the user deletes the last remaining Piece, or if the CLR gadget is
clicked (deleting all pieces), the Default Piece will be created.
- Manipulating a Piece with the Mouse:
a. The Selected piece can be modified in a number of ways, covering all
possible affine transformations. Consider a cartesian coordinate system
denoted by unit vectors e1, e2 on the x and y axes respectively, with
lengths s1 = 1, s2 = 1 and angles r1 = 0, r2 = 0 relative to the
respective axes. Then in the general case, any affine transformation can
be described by its effect on e1 and e2, i.e. by what it does to change
s1, s2, r1 and r2 as it operates on the unit vectors, and in addition by
its translation of the Origin, denoted by t1, t2 in the x and y directions
respectively. Note that the matrix coefficients commonly used to define
an affine transformation, denoted by a,b,c,d,e,f, are an alternative way
to describe the transformation; e and f are identical with t1 and t2,
while a,b,c,d can be derived from s1,s2,r1,r2 (and vice versa) by simple
formulas.
b. The user-defined transformations in this program consist of combinations of
the following manipulations:
* Drag [Moves the Origin without affecting shape and orientation].
* Define e1 [Sets the endpoint of e1 by setting s1, r1].
* Define e2 [Sets the endpoint of e2 by setting s2, r2].
* Size [Changes the lengths s1 AND s2, leaving their ratio intact].
* Rotate [ Changes r1 AND r2 simultaneously by the same amount].
The first three manipulations suffice to define any transformation; the
last two are provided for the user's convenience.
c. You are able to apply the manipulations to the Selected Piece by
manipulating with the mouse a construct called a Vector Box Diagram. This is
a parallelogram that represents the transformation of the Piece by showing
the image under this transformation of the rectangular frame of the
drawing area on the Outline window. The Origin is denoted by a small
square bearing the letter O at one corner of the parallelogram; similarly
the ends of the (transformed) X and Y axes are denoted by the letters
X and Y, and the last corner by a solid square. You are able to click and
drag any corner of this Box, effecting the following changes in the
Transformation:
* Drag - By dragging the Origin corner of the Box.
* Define e1, Define e2 - By dragging the corner corresponding to the
end of the chosen unit vector.
* Size/Rotate - By dragging the corner opposite the Origin corner.
Dragging it away from the origin corner or towards it will change Box
size; dragging it laterally will rotate the Box about the Origin corner.
A combination of both will achieve the combined effect.
As you drag a corner, a second image of the Box will appear, in
ghosted lines, and will move and deform to show the effect of the dragging.
After you release the corner, the solid Box will move to the new
location/form and the appropriate deformation of the red image of the Piece
will be computed and displayed.
- Modifying a Piece's coefficient values from the Keyboard:
a. The coefficients a-f, the probability parameters Dens and p, and the
geometric parameters (s1,s2,r1,r2,t1,t2) corresponding to the Selected
Transformation can be viewed and manipulated directly by clicking the
NUM gadget. This action brings up a small draggable window with these
fourteen parameters shown in string gadgets, and with a Boolean ENTER
gadget and a Close gadget. When this window is open, the menu of the main
Collage window is disabled but its gadgets remain active. The Vector Box
remains drawn but is inactive.
b. You can modify any parameter from the keyboard by clicking in its
string gadget and inputting the value. Since some of these numbers are
interdependent, the other values will be recomputed as appropriate when
you hit the Return key or select another string gadget.
c. Changing the numbers in the Coefficients window will not affect the Piece
in the collage image until the ENTER gadget is clicked. At that time the
values in the string gadgets are read into the program's variables and the
image of the Piece, as well as its Vector Box, are redrawn accordingly.
d. The ADD, DUP, SEL, DEL and CLR gadgets retain their usual functions,
and will cause the Coefficients window to update its contents to match the
newly selected Piece (which is also redrawn in the collage). This allows
you to modify pieces successively from the Coefficients window, entering
each change by using the ENTER gadget.
e. You can Quit the Num Window (without modifying the piece) by clicking its
Window Close gadget.
- Definition of Piece Probabilities
a. Each Piece i has a probability, p(i), associated with it, which defines the
probability of that transformation being selected at any step in the
rendering process. The probabilities must satisfy 0 < p(i) < 1 for all i,
and their sum must be 1.
b. In this program, the default is that all p(i) are set automatically to be
proportional to det(i) = |ad - bc|, the determinant of the transformation
matrix (except that if det(i)=0 then p(i) is set arbitrarily to 0.01). This
means that p(i) is proportional to the area of the image of each
transformation, giving equal pixel density across the full image during
rendering.
c. To allow the user to meaningfully change the probabilities (which are all
interrelated by the constraint that their sum equal 1) we define another
parameter, Dens(i), the relative density the user wishes to force on a
Piece during rendering. The parameter Dens(i) is essentially the probability
per unit area of the Piece. If all Dens(i) equal 1 (the default), all pieces
retain equal density. If the user sets Dens(k) > Dens(j), then piece k will
receive proportionately higher density than piece j. The probabilities are
computed to be:
p(i) = Dens(i)*det(i) / sum [(Dens(i)*det(i)]
with the sum extending over all currently defined pieces i.
d. When a new Piece is created, its Dens(i) is set to 1, its determinant
det(i) is computed from its matrix and its p(i) is computed as shown above,
as are all the other p(i) in the system.
(Note that when a Piece is DUPed, the new piece receives a density of 1,
regardless of the density of the mother Piece).
e. When the user modifies (e.g. resizes) a Piece, its det(i) is recomputed
and all p(i) are recomputed.
f. You may modify the density of a piece in the numeric entry window.
Whenever you do that, all p(i) are recomputed. The density thus set by you
will remain in effect through subsequent Piece modifications.
g. In a SAVE IFS operation, only the p(i) are saved; during a LOAD IFS they
are read in and the det(i) and Dens(i) are computed and stored in memory.
[ det(i) = |ad-bc| unless this is zero, when it is set to 0.01;
Dens(i) = p(i)/det(i), since in a saved IFS file the sum of p(i) is 1 ].
- The Optimize function
a. The OPTIMIZE menu item performs two actions on the currently defined IFS:
First, it modifies its coefficients so that the Attractor of the IFS will
fill the full size of the window. Since this program uses no scaling or
offset during Rendering but assumes instead that the Rendering window is
of fixed size and location in the Real plane, this means modifying all the
e and f coefficients of the transformations.
b. The second action is to create an Outline from the actual Attractor of the
IFS, and generate a Collage from this attractor. This will naturally be a
perfect Collage, as a result of the Collage Theorem.
The following Menu items are active in Ouline Editor mode:
(NOTE: Menu system is disabled when Coefficients Window is displayed)
- PROJECT Menu:
NEW - Erases Outline & IFS, reverts to startup condition.
EDIT OUTLINE - Erases IFS and enters Outline Editor mode.
LOAD FILE - OUTLINE - Clears the current IFS, enters the Outline Editor,
and loads an outline from an IFF disk file (see section 7).
- IFS - loads an IFS code from a disk file and Optimizes it.
- IMAGE - Loads an Image from IFF file. The image screen remains
in front until you click in it to push it back.
SAVE FILE - IFS - Saves the current IFS coefficients to a disk file.
- IMAGE - Saves the current Image, if any, to an IFF disk file.
OPTIMIZE - Executes the Optimize function (See above), adjusting the IFS
so its attractor fills the Window, and generating its collage
based on the Attractor as an Outline.
QUIT - Exits program.
- DISPLAY Menu:
SHOW CODES - Displays a table of the current IFS Code coefficients.
SHOW IMAGE - brings the image screen, if one exists, to the front.
- RENDER Menu:
RESOLUTION - Sets the screen resolution for the next Rendering operation.
GRAY LEVELS - Sets the number of Gray Levels to be used in rendering.
START - Initiates Rendering of the Attractor of the current IFS.
- ABOUT Menu:
IFS THEORY, HELP, AUTHOR - Opens text screen, displays the appropriate info.
DEMO - Launches a demo of generation of the Sierpinski Triangle.
7. Rendering Mode Operation
---------------------------
Rendering is initiated by the user in Collage Editor mode by the RENDER - START
menu selection. This causes the program to open the Image screen to the depth
and resolution selected by the user via the RENDER menus (or the default, which
is 640X400, 2 Gray Levels). The program freezes all user interaction in the
Collage Editor window (should the user bring it to front) and begins Rendering
of the Fractal encoded by the current IFS, until the user clicks the mouse
anywhere in the Image screen. At that point the rendering stops and the Image
screen remains in front until the user clicks in it again. This second click
causes the Image Screen to be pushed to the back and control is returned to the
Collage Editor user interface. You can later redisplay the Attractor by
selecting the DISPLAY - SHOW IMAGE menu item.
8. File I/O Operation
---------------------
- Load Outline
This reads in an ILBM IFF file and puts BITPLANE 0 of the image into the
Outline of the Outline Editor, ignoring the colours defined in the file.
Additional bitplanes are ignored; images larger than the window are cropped.
- Save IFS
The saved IFS files are straight ASCII files. They list the transformation
coefficients a - f and p, as well as the additional information (which is
ignored by the IFS Load routine) of the density and the Geometrical scalings
and rotations of each transformation. Files are saved with the filename
extension .ifs (added to the filename if necessary by the program).
- Load IFS
a. The IFS Code Loader routine is designed to read in IFS codes from
almost any ASCII file. This permits it to read files generated by most
other IFS programs, regardless of their exact format. The routine will
scan the file on a line by line basis, and will SKIP any line that does not
start with seven consecutive space-delimited numbers. It will read in all
lines that DO so start, interpreting the seven numbers as the coefficients
a - f and the probability for one transformation. Anything on such a line
after the seventh number is also ignored. This means that all headers,
comments, and additional info (e.g. colour information) is ignored. If
the probabilities in the file seem to be cumulative (i.e. the last one is
1.000) the program will convert them to the straight probabilities it needs.
b. After reading in the IFS, the program checks whether its attractor will
fit in the window. If not, it will modify the IFS coefficients so as to
make it fit. This means that IFS codes previously saved by IFSLab will be
read in and not modified, but those generated by other programs - and hence
usually falling outside the window - will be converted to fit it properly.
c. Finally, a Collage is generated from the attractor (this is an invocation
of the second part of the Optimize function) and displayed.
- Save Image
This will save the contents of the Image Screen into an ILBM IFF file.
- Load Image
This will load any ILBM IFF file, Open the Image Screen to the resolution
found in the file, and place the loaded image (including the colours) in
the Image Screen. This is a general IFF viewer; you can display any non-HAM
IFF file, even if it has nothing to do with IFS. The image has no effect
on the IFS part of the program, it just stays in the Image Screen until you
render or load another image.
==========================
Part III. Programmer Notes
==========================
The following is intended for the benefit of those interested in writing IFS
programs; it is not necessary for using IFS Lab. It consists of various
comments and technical notes related to the internal structure and function of
the program, mostly accumulated during development. Note that the source is
included with the program for instruction rather than for compilation; to
compile it you would need the IFF and req.library include and object module
files, which are available in the public domain but are not included in this
distribution.
1. Coordinate system and Coefficient Ranges
-------------------------------------------
a. Coordinate Convention: The Top Left corner of the display area is defined as
the Origin, (0,0), with the positive X axis going to the right and the
positive Y axis going downward. The full display area is defined as 1 unit
in width and 0.6775 units in height (for purposes of the translation
coefficients). This convention makes the rectangular window used for editing
represent the top 2/3 (approximately) of a 1x1 square area in the Real plane.
b. Thus, the transformation coefficients a -- d are all real numbers between
-1 and 1, as are the scalings s1, s2. Coefficients e, f, t1, and t2 are in
the range 0 -- 1. The angles r1, r2 are stored internally in radians in
the range -pi -- +pi, with positive angles denoting clockwise rotation. In
the Coefficients window, however, angles r1 and r2 are displayed in degrees,
between -180 and +180. The program will accept user entry into the
coefficients window of angles outside this range, and will convert them into
it.
2. Screens and Windows
----------------------
The program uses the following screens and windows:
a. A low resolution, 4-bitplane (320X200) screen, with a GZZ Backdrop window
for Outline and Collage generation.
On this screen can also open the Coefficients Window: a narrow window with
fourteen string gadgets where the user can modify the Transformation
parameters.
This screen is where the user interaction takes place; it opens when the
program is run and stays open throughout its operation.
b. A screen for rendering and displaying images, whose resolution and depth are
defined either when the user selects the rendering resolution, or by the ILBM
file bitmap header when an image is loaded from disk. This screen is opened
the first time that the user loads an image file or initiates rendering, and
stays open thereafter until the program is quit or until a new image file
load or render operation is initiated (when it is closed and re-opened to the
potentially different resolution of the new image). The image is displayed in
a GZZ Window in this screen.
c. A 640X200, 2-bitplane screen for Help and Codes table text display. This
screen is opened and then closed each time that the user selects a Help or
Show Codes menuitem. The text appears in a full-screen sized window that
obscures the screen depth gadgets.
3. Outline/Collage Window Colour Scheme
---------------------------------------
Window work area is black.
Outline is drawn in white.
Unselected Collage Pieces are green and the selected one is red.
Vector Box is Khaki (except where it overlaps Outline and/or Pieces).
Overlap of white and green is light green.
0000 Black Background | 1000 Khaki String Gadget borders
0001 Dk Green Deselected Pieces | 1001 Med Green Coeff Window Text
Menu Item Bgnd |
0010 White Outline | 1010 Dk Green Box over Outline
0011 Lt Green D.P. over Outline | 1011 Dk Gray Box over D.P. + Logo Bgnd
Menu/Gadget Text |
|
0100 Red Selected Piece | 1100 White Complement Menu/Gadg Text
0101 Red S.P. over Outline | 1101 Dk Green Ghost Box over Outline
0110 Red S.P. over D.P. | 1110 Dk Gray Complement Menu item Bgnd
0111 Red S.P. over D.P. | 1111 Khaki Complement to Boolean
over Outline | Gadget Bgnd; String Gadget
| Cursor
4. Gadget ID's
--------------
GadgetID's:
0 1 2 3 4 5 6 7 8 9 10 11 12
FREEHAND LINES ERASE FILL CLROUT DONE ADD DUP SEL DELETE CLRIFS NUM ENTER
Plus 14 coefficient string gadgets numbered 21 thru 34:
a - f Dens p s1 s2 r1 r2 t1 t2
21 - 26 27 28 29 30 31 32 33 34
There are also two inert dummy gadgets, one with image render and one with
border render, tacked on to the end of the two gadget lists for the Editor
Window - these are used to place the IFS-Lab logo at the lower right corner of
the window, and make it immune to obliteration by the NUM window when it is
dragged to the right.
5. Outline Editor
-----------------
The Fill function uses the graphic library function Flood() in mode 0, which
fills to the enclosing outline. For some reason I couldn't make Flood() work in
mode 1. The mode 0 fill ran into problems if the filled area touched the edge
of the window in some cases. To solve this, I made the fix of enclosing the
window drawing area in a 1-pixel-wide white border before calling Flood(),
and repainting a black border after the Flood(). This does mean that if you use
Fill, you can't use the outermost pixel around your window for the Outline
drawing.
6. Piece Storage
----------------
- Each Piece (Transformation) is stored as 2 entities:
a. A piece structure denoting all coefficients needed to describe it (with
some redundancy), namely:
double a, b, c, d, e, f Matrix Coefficients
double s1,s2,r1,r2 Geometric coefficients
double dens, p Probability and Density
double det Determinant
UBYTE *piecemap Pointer to the bitplane containing the piece's shape
struct pixel boxo, boxx, boxy, boxz
The last 4 members are the corners of the Vector Box, in GZZ coordinates.
(struct pixel consists of x and y coordinates for a single pixel).
b. A single bitplane in CHIP RAM containing the image of the Piece. The
bitplane is of size Window->Width X Window->GZZHeight pixels; it is
equivalent to the (Full, not inner) Window minus its top and bottom
borders.
- There is an array of 20 pointers to piece structures, pieceptr[MAX_N + 1].
(The number 20 is coded as #define MAX_N 19 ).
- The variable N stores the index of the highest existing Piece. That is,
pointers pieceptr[0] thru pieceptr[N] are used. Note that there are then
N+1 Pieces, and that N =< MAX_N.
- The variable selpiece stores the index of the currently selected Piece.
- The function AllocPiece() allocates memory for a piece structure and
bitplane (checking that memory is available); puts the bitplane pointer in
the structure; and returns a pointer to the piece structure.
- The function FreePiece() takes a pointer to a piece structure and frees the
memory allocated to that structure and to the associated piecemap.
7. Collage Display mechanics
----------------------------
- The 4 Bitplanes of the GZZ bitmap are dedicated to the different elements
of the Collage as follows:
* Plane 0 - Deselected Pieces
* Plane 1 - Outline
* Plane 2 - Selected Piece
* Plane 3 - Vector Box
* On entering Collage mode, bitplane 1 is copied to a buffer (pointed at
by outlinebufptr), which serves as a source for TransformPiece(). This is
needed because when the coefficients window is displayed, Plane 1 cannot be
used as a contiguous source for the outline.
- The DrawCollage() function recreates the display as follows:
* Erase bitplanes 0,2,3 (leaving the Outline intact).
* Blit all Deselected Pieces from their piecemaps to Bitplane 0.
* Blit the currently Selected Piece from its piecemap to Bitplane 2.
* Draw the currently Selected Piece's Vector Box in Bitplane 3 by calling
DrawBox().
- The TransformPiece() function takes pointers to a source bitplane and
a destination piecemap bitplane, and executes the affine transformation
given in a piece structure pointed at by its third argument to map the
source into the destination. If a transformed pixel falls outside the
destination boundary, it is not written, and the function aborts (leaving
the destination piecemap trashed) and returns 0; else it returns 1. The
function skips the source bitplane's top and bottom borders. Use of Integer
math has speeded up this function by a factor of 2.7X relative to FFP.
- The DrawBox() function erases Bitplane 3, then draws the Vector Box of the
currently Selected Piece in Bitplane 3 using the graphics drawing routines,
after write-protecting Bitplanes 0,1,2 in the Rastport mask.
- Modifying the shape of the Selected Piece is done by manipulating its
piecemap and Bitplane 2, without affecting the other Bitplanes:
* User tells program to change shape or position of Piece, using the Vector
Box.
* On releasing the mouse button on the vector box, program computes the
transformed piece image using the Outline buffer as source and putting the
transformed image in the Piecemap of that Piece.
* Before each Pixel is written into the destination, it is checked for
overflow beyond bitmap boundary. If overflow is found, program notifies
user, cancels the operation, and restores the piecemap by copying the
unmodified image from Plane 2 to the piecemap (if Coefficients window is
displayed, the restoration is by re-transforming the outline as plane 2 is
interfered with by the coefficients window).
* If no overflow is met, program blits the transformed piece from piecemap to
Plane 2, and updates the piece structure.
* Vector Box is restored to its Old / New shape depending on whether overflow
has been found or not.
8. Coefficients Window issues
-----------------------------
- Modifying the number in any string gadget requires changing the values of
other coefficients. This is handled by RecomputeCoeffs() which
re-calculates the necessary coefficients based on the one just modified,
which is specified as its parameter. The modified coefficients are placed
in the string gadget buffers, and are then shown in the display by a call
to RefreshGadgets(). This happens when the user presses CR after the entry
in the gadget (a GADGETUP event), or (failing that) when the next gadget is
selected (a GADGETDOWN event). This redraws the gadgets' contents. However,
there is a problem if a gadget is refreshed while the left mouse button is
still pressed within it. To prevent that, the refresh following a
GADGETDOWN event is done gadget by gadget [ using RefreshGList() ] and
skips the last-hit gadget.
- RecomputeCoeffs() also checks that all coefficients currently in the string
gadgets are in their legal ranges. If not, it restores the illegal
coefficient to its previous value, stored in the selected piece's structure.
- numgadgpending holds the gadget ID of the string gadget currently under
modification, i.e. the last one selected and not yet terminated by a CR or
by selecting a subsequent gadget. It is set to -1 if no gadget is pending.
- UpdateNumStrings() loads the coefficients from the Selected piece's structure
into the string gadgets.
- Clicking the ENTER Gadget causes a recomputation of coefficients if needed
(On GADGETDOWN) and then on GADGETUP executes the transformation specified
by the coefficients in the string gadgets, with a check for piece overflow,
and displays the transformed piece and its new Vector Box.
9. Rendering Mechanics
----------------------
- Function RenderImage() calls OpenImageScreen(), which opens the screen as
well as the Backdrop, GZZ Image Window in it (Backdrop used so its title bar
can be placed behing the screen's, leaving the screen depth gadgets visible).
The screen colours are bluish,selected to minimize flicker in Interlace mode.
- In the rendering loop, a random number is compared to the cumulative
probabilities of the transformations and the first one to exceed it sets the
transformation to be used; this is applied to the previous iteration's pixel
and the resultant new pixel is drawn in the window (in 2-gray-level mode) or
incremented one gray level (in a multiple gray level mode).
- Significant speed-up of rendering (40%) has been achieved by using integer
math for transformation and probability computations. The coefficients a--f
are converted in RenderImage(): they are scaled by multiplication by a
million, and converted to long integers. All math is done in these integers,
and the result divided by a million to get the next pixel coordinates. The
Cumulative probabilities are also scaled by RAND_MAX (the top limit of the
random number generator) and converted to integer, and compared directly to
the generator's integer output later on. (The Manx integer random generator,
rand(), is much faster than the floating point generator ran()).
- Pixels are drawn using WritePixel(); direct write into the window's
bitplane achieved negligible speed-up here and was abandoned.
- After each pixel is drawn, the ImageWindow IDCMP is examined for a
mouseclick indicating "stop rendering". When this is detected rendering stops
and upon a further mouseclick the Image screen is pushed back and the collage
screen placed up front.
10. Compilation and Linking
---------------------------
IFSLab was developed under AmigaDOS 1.2, on an Amiga 2000. It has been tested
on Amigas 500, 2000 and 3000 and under AmigaDOS 1.2, 1.3 and 2.0.
This program uses the file requester in the Fox/Dawson requester library,
req.library, which should be present in your libs: directory (otherwise, file
I/O will be disabled).
Compile with Aztec C 5.0, with -ff option (Fast floating point) and -safmnpsu
options (code optimization). Link with +cd option (forces sprite and image data
to load in CHIP RAM). Link with IFF files (from CBM IFF Disk, Fish disk #185),
and with the gluecode module for the Fox/Dawson requester library, thus:
cc -ff -safmnpsu -i IFF -i req IFSLab.c
ln +cd IFSLab.o IFF/putpict.o IFF/ilbmw.o IFF/packer.o IFF/iffw.o
IFF/readpict.o IFF/ilbmr.o IFF/unpacker.o IFF/iffr.o IFF/remalloc.o
req/myreqglue.o mf.lib c.lib
Note that the IFF files on the CBM IFF disk require some fixing to actually
work under Aztec C.
11. Known Bugs
--------------
So far, two obscure bugs have been observed:
a. If Mungwall is run before executing IFSLab,a system crash will occur halfway
through execution of the Demo function. Attempts to trace this bug place it
in a call to SetWindowTitles() from inside SetMode(), which is very puzzling
(SetMode() works fine elsewhere in IFSLab). This bug is not solved; however,
it has never been observed while testing IFSLab on a number of Amigas WITHOUT
Mungwall. Hopefully you will not ever encounter it.
b. UNLESS the -safmnpsu option is used when compiling, the program will crash
when a Save Image operation is attempted. Using these -s options solved this
problem; thus this bug is not present in the executable supplied.