Professional Documents
Culture Documents
P 0009 Thesis
P 0009 Thesis
I would like to thank my thesis supervisor, Dr. Vaughan Clarkson, for his thoughts and
input in making this a successful project. With his input, this project has certainly
resulted in a better product that is much more suitable to a professional involved in
image processing.
I would also like to thank the users of the newsgroup comp.lang.java.programmer for
their input in solving some programming problems.
Image processing tools are being rapidly developed for different operating system
platforms. These tools are usually big in size, not completely portable across different
platforms and lack an ability to be efficiently fielded on the Internet.
The purpose of this project is to research current image processing tools and create a
simple, easy and flexible image processing widget based on the Java Advanced Imaging
(JAI) API. This widget will address the above-mentioned general problems associated
with most image processing tools. Some popular image processing applications are
discussed, including their strengths and weaknesses and their popularity. This is
followed by a more detailed discussion on creating a java widget based on JAI. The
features that make this widget easy to use to the average user, as well as any software
developer wanting to expand it, are discussed. Further advantages and disadvantages of
this widget are also discussed.
INTRODUCTION.............................................................................................................7
PROJECT........................................................................................................................21
PROBLEM DESCRIPTION.......................................................................................21
IMPORTANCE OF THIS PROJECT.........................................................................21
RESEARCH AND ANALYSIS - USABILITY .........................................................22
STANDARD TOOLBAR .......................................................................................22
DESIGN AREA ......................................................................................................23
MODIFIER TOOLBAR .........................................................................................24
RESEARCH AND ANALYSIS - EXTENSIBILITY ................................................24
RESEARCH AND ANALYSIS - EXPANDABILITY..............................................29
OVERVIEW. ..............................................................................................................34
NOTES....................................................................................................................35
NOTATION. ...........................................................................................................35
DECLARATIONS. .....................................................................................................37
CONFIGURATION CONSTANTS AND VARIABLES. .....................................37
EXCEPTIONS. .......................................................................................................38
Exception Messages: ...........................................................................................38
Warning Messages: .............................................................................................38
CONCLUSION ...............................................................................................................68
APPENDIX .....................................................................................................................70
BIBLIOGRAPHY .......................................................................................................87
The word extensibility is used to describe the addition extra features to the core
component or application itself. This would be analogous to adding an “undo” feature to
a component, that is, the component has been extended. This would require
programming in the core component.
The word expandability is used to describe the addition of toolsets, plug-ins and runtime
libraries. This does not require any programming changes to the core component.
ABREVIATIONS
OS Operating System
Image processing is the ability to extract information from images. This is the shortest
and simplest definition of image processing. To extract information of any kind from an
image, the image has to be first transformed into a data set. Mathematical operations [1]
can now be applied on to this data set. This thesis starts off with an introduction to
image processing.
Java Advanced Imaging (JAI) is the Java Application Programming Interface (API) for
handling complex graphics. Unlike other graphics libraries, which are known to have
portability problems, JAI does not have this problem as JAI has been almost
completely1 written in Java and thus is as portable as Java itself. Consequently, this
1
The actual processing is delegated to native libraries that come with the JAI API, which are specific to
the Operating System platform. The user has no interaction with these libraries and only interacts with the
JAI API.
This project requires a graphical component that is based on JAI. A whole chapter is
dedicated to discussing the project. This chapter starts with a formal problem
description with possible enhancements that can be made. This is followed discussions
on the areas that were researched for this project. Why these areas were deemed
important, sample scenarios and some sample solutions are also discussed.
This is followed by a formal specification for the component. The specification mainly
defines the state machine for such a component. Component behaviour, event
generation and response are also defined.
In the next chapter, this specification is developed into a design in Universal Modelling
Language (UML). This design shows how objects interact with other objects and the
relationships as well.
The final chapter is the conclusion. The degree of success achieved by this project is
discussed here. Further improvements are suggested.
This is followed by a partial code listing in the appendix. All the interfaces used in the
implementation are given, but no source code is included.
The primary goal of this project is to create a component that will allow fast and easy
access to image processing tools, while being lightweight and portable across multiple
operating system platforms.
The brief definition of image processing is the ability to retrieve information from
images. This is achieved by, first transforming the image into a data set. Mathematical
operations can be done on this new format. Different kinds of information are retrieved
by the different operations that are performed on the data set. It is important to note that
the reverse, constructing an image from data, is also image processing.
A simple example: how do we find out the differences between two images? We
execute an “Arithmetic Subtraction” operation [2] on both images. As the name implies,
subtraction leaves the difference, the resulting image would contain the differences
between the two images.
Image processing is used in many different fields. In medicine (the ultrasound machine,
X-ray machine), astronomy (Hubbles telescope taking photographs in X-rays, Gamma
rays, Infrared) and military (image maps used in ground hugging missiles), these are
just a few of the fields in which image processing is widely used.
Image processing is also used in every day items (digital cameras) to mission critical
systems.
PENTIUM MMX
DESCRIPTION
Therefore, image processing using MMX can receive a tremendous boost in processing
speed over non-MMX processing.
USABILITY
It is not possible for non-MMX applications to use the power of MMX. This means that
applications have to be specifically written for MMX. On a higher level, this means that
the source code will have to be recompiled with a compiler that can generate and
optimise MMX instructions.
COMPATIBILITY
Most of the microprocessors that came out after the introduction of MMX, support the
MMX instruction set. Currently, nearly all major computer microprocessor
manufacturers, including Intel, AMD and Cyrix, support MMX. Therefore,
programmers are almost guaranteed of MMX supported hardware (at least for the
desktop computers).
MICROSOFT DIRECTX
DESCRIPTION
Microsoft describes [14] DirectX as an advanced suite of multimedia APIs built into the
Windows Operating System. Introduced in 1995 and recognized as a standard on the
DirectX provides developers with a common set of instructions and components, across
all Windows based platforms. At the same time, DirectX also takes advantage of high
performance hardware such as dedicated 3D graphics cards. DirectX achieves this by
providing a "hardware abstraction layer" (HAL), which uses software drivers to
communicate between computer software and computer hardware. As a result,
developers can use DirectX to write a single version of their product for the wide range
of hardware devices and configurations that exist and at the same get high performance.
DirectX provides another layer called the “hardware emulation layer” (HEL). This layer
acts as software-based drivers for actual hardware when hardware is unavailable. For
example, HEL could emulate 3D graphics when there is no 3D graphics available.
PORTABILITY
DirectX is only available for the Windows platform. Therefore, programmers wanting
to port their programs to other Operating Systems, will have to re-write their program.
However, DirectX applications are completely portable across all2 Windows platforms.
This is because all Windows platforms use the same DirectX drivers.
2
Windows NT only supports DirectX 3.0a. It is expected that this will be fixed with the newer versions.
DESCRIPTION
Matlab is one of the most popular image processing applications available. Matlab
allows manipulations at the lowest level, such as the modification of a single value in a
data set. Many extended functions for image processing are available.
USABILITY
Image processing in Matlab is the same as using Matlab for any other problem.
Matlab usage requires a user entering commands at the prompt to ask Matlab to do
things. This is very similar to the command shell in Unix or Linux. The user can enter a
single command to do something or write a script file (or even multiple files) to do a
more complex task. In Matlab, this script file would be called an “M” file.
USER LEVEL
Image processing in Matlab requires a user who already understands how to use Matlab.
The user must also know how to write scripts in Matlab to get the best result. Further,
the commands used are short and technical requiring the user know what the commands
do.
Thus, image processing in Matlab is mostly aimed for professionals [18], as it requires a
skilled user.
EXPANDABILITY
Most of the image-processing functions available in Matlab are scripts, which are
(usually) available for viewing and modification. Even if it were not, Matlab still allows
the user to use them in writing new functions. These new functions can then be used to
do more image processing.
This means that Matlab provides, almost unlimited expandability. Moreover, as the
functions are just script files, functions are easily copied over to other machines
decreasing wasted time and increasing efficiency.
PORTABILITY
Matlab has not been designed to be used over the Internet. Matlab requires a lot of
processing and system resources and thus is unsuitable to be used over the Internet.
Though it is conceivable that applications written in Matlab may be used over the
Internet, it is unlikely as there are more suitable image-processing libraries for this
specific purpose.
AUTOMATION
Matlab provides complete automation for all purposes. A user could write a script to
perform a common image-processing sequence or even compile it as an application. The
application can now be used by anyone to perform the image-processing sequence.
IMAGEMAGICK
DESCRIPTION
ImageMagick is a collection of tools that can be used to read, write and manipulate
images. The latest version ImageMagick can manipulate over 68 [15] image formats
including TIFF, JPEG, PNG, PDF and GIF. A lot of operations that can be performed
on images are already available to the user.
USABILITY
Usage of ImageMagick is through the command prompt. The user types ImageMagick
commands with the required options to manipulate images. ImageMagick can display
any of the supported graphics formats but requires a suitable graphics server (the X
server for Linux) be running at the time.
USER LEVEL
To make really good use of ImageMagick, the user should also know some command
line scripting language of the Operating System the user is using. For example, batch
programming in Windows and shell programming in Linux or Unix.
The source code for the whole ImageMagick application is available for free. This
allows a user to change or modify the code, add new functions and recompile the code.
Thus ImageMagick is extensible.
However, usually, users would rather use a script to do a series of commands that are
available from ImageMagick to get the desired result. This requires less time and is
much more simple. Thus ImageMagick is also expandable.
PORTABILITY
ImageMagick was primarily designed for the Unix/Linux machines. But today, there are
ports of ImageMagick available for other popular Operating Systems including
Windows 95/98/2000, Macintosh and OS/2 [15].
ImageMagick is well suited for web applications. It allows the dynamic creation of
images and multiple APIs (C, C++, Java, Python and PERL) are available, any of which
can be used be used to field a web application [15].
AUTOMATION
Massive automation can be achieved on platforms that allow good scripting. In this
regard, Unix and Linux scripts can automatically and easily modify images as per the
conditions set by the user.
This is also one of the reasons for ImageMagicks’ suitability as a back end for a an
image processing web application.
ADOBE PHOTOSHOP
DESCRIPTION
Photoshop is one of the most powerful and popular graphics applications in the
(Windows) market today [6]. The current version (version 6) is the latest in this series
of products and has built on the stability and performance of its predecessors.
Photoshop can also be obtained in a suite of (Adobe Systems Incorporated) applications
that allow a high degree of flexibility and collaboration within the applications
contained in the suite.
Photoshop is not a “true” image processing application. Photoshop has been primarily
designed for “creative arts” or artists or for users aspiring to be a similar profession.
Photoshop has been included in the study because it offers an enormous amount of
image processing functions to assist the user in getting better “artistic” results.
A Photoshop user would be faced with a GUI that is familiar to any Windows user.
Photoshop contains similar menu systems (menus file, edit, …) and toolbars (standard
toolbar – tool buttons new, open, save, …) as any standard windows application. Thus
in Photoshop, most users would not be spending additional time learning basic
operations as they are identical to standard Windows applications.
USER LEVEL
Users are not required to write any code to perform any image processing functions.
This makes Photoshop ideal to the novice user. Users without a mathematical
background and theories involved in image processing will also like what Photoshop
has to offer. This is because Photoshop offers all image processing functions with a GUI
front-end. A typical result of selecting an image processing function will give the user a
dialog window (if it is not already open) with (possibly) all the options that that function
offers. The user can change any values in these options until such time as the user is
completely satisfied. Usually, the user would be able to preview the changes in real time
from within the function itself. This improves the usability of the software.
To expand Photoshop, that is, to add more image processing functionality, a user would
have to install a plug-in. This would be additional software that can be run from within
the Photoshop environment. With the enormous popularity of Photoshop, there are a
number of plug-ins available both from the maker of Photoshop and third party vendors.
These plug-ins are available as both commercial software which a user will have to buy
and free software.
Writing a plug-in
Photoshop comes with its own collection of APIs for programmers wanting to write
plug-ins. Plug-ins are thus written to conform to these APIs. This involves intimate
knowledge of programming (usually C, C++ or other languages). Further, the
programmer must be familiar with the image processing libraries and the functions it
contains to effectively leverage the power behind the Photoshop image-processing
engine. The programmer must also be familiar with at least some of the mathematics
involved image processing.
In conclusion, writing plug-ins is not something that the average user or even an
advanced user could achieve with ease. It is more suitable, to buy commercial plug-ins
or contract another company to write a plug-in that is suited to the users’ needs.
Using a plug-in
A plug-in would install itself quite easily if it were correctly written. After installation,
the plug-in tool appears and behaves just as a native tool would. A user familiar with
Photoshop itself should not find a big difference between using native tools and the
plug-in.
EXTENSIBILITY
Therefore, a feature such as “a particular print order” that is not supported by Photoshop
could not be added by a third person, user or programmer. Only Adobe can add such
features.
PORTABILITY
Photoshop is available only for the Windows platform. This makes it virtually
impossible for a user relying on another operating system to make an attempt at using
Photoshop for image processing needs because it is unlikely that the user would dual
boot or run another operating system on a virtual machine for the sole purpose of using
Photoshop.
Photoshop uses two methods for image processing. A user could make changes directly
to the image. Simple operations such as image transformations are usually done with
direct image manipulation. The second method, which is much more powerful and
flexible, is to use layers. A layer is simply a set of modifications that can be individually
altered. An image seen through that layer would be modified as per the settings on that
layer. To make additional changes, a user could modify, add or delete the layers
properties or apply another layer on top. Layers are also used to achieve image
animations.
PROBLEM DESCRIPTION
Specifically, this component will be based on the JAI API, which is the Java extension
that provides complex image processing functions. Further, this component would be a
graphical component and should provide a rapid application development environment
(in image processing terms). A user should be able to “draw” up a sequence of changes
by placing image processing tools and connecting them in the order that the user wants.
Further areas of relevance include the ability to field this component or field an
application containing this component on the Internet, both easily and efficiently. The
ability to use this component just as any other Java component (buttons, labels and so
on), gives a Java programmer quick access to this component without involving any
undue hardship.
JAI in its current form is a collection of Java classes that are designed to do image
processing [7]. At the moment, JAI does not have a GUI, which can be used to access
the image-processing tools available in JAI. Code has to be written to do this job. This
is the first time that GUI has been designed for JAI. Further, JAI has the highest chance
of becoming a cross platform image-processing library that is lightweight.
This project would create a graphical component that can be used to access the image-
processing tools available in JAI. Instead of writing code, users would be able to just
“drag and drop” the required tools on to a canvas and graphically connect them in the
order the user desires. Users can see the changes on the spot by “double clicking” any
tool. Further, for the JAI tools that allow user input (such as Convolution, Threshold),
This component can also be fielded on the Internet in the form of a Java Applet. The
advantage here is that much of the processing power already resides on the users
computer (in the form of a JVM and JAI API) and this component would be acting as a
front-end to this existing resource base. Where these resources are not available, they
have to be downloaded only once and are available from the Internet for free.
This component has also been designed with the future in mind. As the JAI API is
upgraded, the newer tools can be added without modifying and recompiling this
component. This component can also be extended easily to add newer features such as
the “undo” function. This is done by providing a clear step-by-step instruction guide to
the developer on achieving this.
This involves making the component easy and intuitive to use to the average user. Since
this component would have a graphical interface, standard graphical interfaces were
looked at. This component was divided into three main sub-components and each of
these sub-components were looked at individually.
STANDARD TOOLBAR
Most current graphical applications have common standard tools. The most basic of
these would be the “standard toolbar”. Usually this toolbar is always visible and is
located at the top of the window. This toolbar contains the most basic operations
including file operations (new, open, save, print), clipboard operations (cut, copy, paste)
and other commonly used tools such as “undo” and “redo”.
Most of these operations would be included in our component and thus a standard
toolbar was included at the top of the component. Operations that were included in this
toolbar are file operations (new, open, save), clipboard operations (cut, copy, paste), a
DESIGN AREA
This would be the area in which the user would create an “image processing design”.
This process would involve pasting image-processing tools and moving them around
within this area. It would also require a “connector” object that will connect the tools on
this area to form a logical sequence of modifications for the input image(s). Further,
design environments (for designing anything) provide some common and basic features
that help the user. These include a visual grid and the ability to automatically “snap”
objects to particular grid locations. This forces the tools and objects on the design area
to be aligned to the grid and evenly spaced. These features are visually appealing to the
user.
The design area had to be appealing and easy to use. A visual grid and the ability to
automatically “snap” objects to the grid were added to the drawing area. Further, the
requirement to be able to move all objects on this area required that a “drag” feature be
built into this sub-component that would handle the moving of all objects within this
design area.
• The easy differentiating of the selected object from the rest of the objects on
this area.
• Messages to the status bar to inform the user of what has happened in
response to a user event.
This toolbar contains the tools specific to our component and image processing. Thus,
there is nothing to compare this toolbar with. The following reasoning has been used to
design this toolbar.
Some tools, notably the ones that are not associated with JAI, would be used more
frequently. These include, an input tool (used to select the image to process in the
design), a connector tool (used to connect the tools on the design area), an output tool
(to declare where the design ends) and a viewer tool (a help tool to display the image at
that point in the design). These tools would be visible to the user at all times.
The tools associated with JAI would be divided into logical categories. This would help
in un-congesting this toolbar. The user would be able to select different JAI tools by
selecting the corresponding category from a “combobox”. This would load the
appropriate tools onto the toolbar. For example, the image processing operations “Add”,
“Subtract”, “Multiply” and “Divide” would be in a category called “Arithmetic” as
these are all arithmetic operations.
Thus, this toolbar would contain the most frequently used tools followed by a
“combobox” which would allow the user to select a category of JAI tools the user wants
to use.
The method of adding these tools to the design area would be to click the tool on the
toolbar and then by clicking on the point in the design area where you want to add the
tool. This would add the tool that was clicked on to the design area, at the point (the
closest “snap” to point) the user clicked.
Extensibility would be one of the key areas of importance in building this component.
Extensibility requires the addition of extra features to the core component and this
should be achieved relatively quick and easy. For example, if it was decided to add an
This area is important because a need may arise in the future for a particular feature in
the core component. The ability to quickly upgrade the component is an increase in
productivity (or even revenue if releasing commercially).
Extensibility involves adding code to the core component. For a person (programmer)
not involved in building this component and not knowing what kind of data structures
and relations are used, this might seem to be a difficult task. This problem is similar to a
programmer writing a program to communicate or extend an existing program. Most of
the current applications in the world come with their own APIs to alleviate this problem.
The programmer would write the program conforming to this API and it is the API that
communicates with the core component. Thus, it protects the programmer from having
to know any internal, implementation specific details.
This general method [8] can be applied to our component on a smaller scale. Whilst
APIs are generally quite big, our component is quite small and this makes it even easier.
However, there is one major difference. For our component, we would need to write the
source code for the “core component” as well (as stated in the above API comparison).
To achieve this, we would be using interfaces to communicate between the major sub-
components in our image-processing component.
Lets look at the example raised previously, that is, the addition of an “undo” function
and lets assume that this function is going to be added to the standard toolbar. We know
that interfaces are used to communicate between the major sub-components. If we look
at the interface used by the standard toolbar we would see all the methods used by the
standard toolbar to communicate to the other sub-components. To this interface we add
the method that will be used to handle the undo function. Further, we’ll have to add
some code to the standard toolbar sub-component, possibly to create a button
conforming to the formatting used in the standard toolbar and calling the “undo”
method in the interface in response to a user event (clicking on the button). This would
be the part that is visible to the user (the button on the toolbar). Next, we take a look at
the sub-component that implements the standard toolbar interface, that is, the sub-
component that actually contains the code for the methods in the standard toolbar
1) Determine the function and its behaviour that is going to be added to our
component.
4) Add the appropriate method to this interface that will be used by the
function that is going to be added.
5) Add the appropriate code to the sub-component that uses this interface so
that a user would be able to generate that event. For our component, this
event would be usually generated by a button. Most of the formatting will
be automatically set on button creation. The programmer will have to
connect the event generated when the user clicks on this button to the
method from the interface.
By following this procedure, extra features can be added to the core component. This
highly modular design also provides additional advantages such as programming in
parallel by multiple programmers. In all, three files are modified. When a function to be
added is finalised and added to the appropriate interface, other programmers can
simultaneously write the code for the other two files. These programmers are able to
Practical Example: adding an undo function. Note: the example shows where the code
would go but not the complete code itself.
File one:
File three:
This area was of particular interest because our component was being based on the JAI
API. Any API was going to change with time. There could be slight updates to major
overhauls of the whole API. Whole sets of new functions could have been added in a
newer version. Therefore, the initial conclusion was that the part of our component that
communicated with JAI had to be at least made extremely flexible so that more
functions could be added later.
This same problem could be looked at from a different perspective. How would a
programmer be able to add more image-processing tools without disturbing any of the
existing tools or the core component? The solution to this problem was to make all
image-processing tools separate from the core component. That is, all image-processing
tools would be loaded by the core component at runtime. Thus, in contrast to
extensibility, expandability does not require the addition or modification of the core
component or any existing tools. The programmer is only “expanding” our component.
In solving this problem what has been achieved is the complete separation of the core
component from the JAI tools. This means the core component can exist without any
JAI tools. Of course the user could not do any image processing, as there are no JAI
based tools. But the user could still experiment with our component by adding and
connecting the basic tools (image input, viewers and connectors). This is another
example of the highly modular design of our component.
1) Determine the category and the tools that will be contained in the module.
2) Extend the class provided by the core component to implement the JAI
tools. As stated earlier, the tools on the design area have certain formatting
and properties. Extending the class gives the new JAI tool the same
formatting and properties. The JAI tool itself only have to implement a few
methods.
4) Create the configuration file. This is a text file and should be named the
same as the module name followed by a “.config”. The first line should
contain the string that will become the category name. The following lines
should contain the full path to the JAI tools contained within the module.
The order of listing of the JAI tools would be the order of appearance of the
tools on the toolbar.
Following this procedure, makes it quick and easy to add more image processing tools.
Much of the work required is already done for the programmer. The highly modular
design results in the following advantages. The programmers are only allowed to create
and modify the files within the modules they are creating, which allows them to add
extras to the JAI tools that they are writing while at the same time not changing any of
the existing tools or the core component. This maintains consistency among all the
tools. Multiple programmers can work simultaneously on different modules or even the
This usage of modules has one other important advantage. Namely, modules can be
traded commercially.
File one:
Note: The JAI tool extends the class supplied by the core component. The programmer
can have any number of helper classes.
File two: The configuration file, category name and full path class name of all JAI tools
contained in the module
Threshold
JAI_Threshold
Faculty: Engineering.
University of Queensland.
October 2001.
Software specifications are nearly always very abstract. The specification does not talk
about implementing data structures, even less, the implementing language. However,
this specification requires a component, similar to a re-usable Unix widget, for the Java
Advanced Imaging (JAI) Application Programming Interface (API). Thus, we already
know what language this component would be implemented in and hence have a good
idea of the final product. In Java, such components are implemented as a JavaBean (or
bean for short). Hence, the title of this specification. Despite the fact that we already
have prior knowledge of the final product, the specification is kept as abstract as
possible.
The Image Processing Bean (IPB) is a JavaBeans component, which brings together the
many image processing features present in the JAI API. The IPB would have a fully
featured Graphical User Interface (GUI). The IPB would not have any keyboard
shortcuts. This is in part because the IPB is not a full application and due to the fact that
a shortcut key in the IPB may conflict with another shortcut key in the host application.
However, this issue is raised in the expected changes section.
The aim of the IPB would be to shorten the time taken to modify an image (or streaming
images) by providing the user with a friendly GUI based environment that allows the
user to see what's being modified/created approximately on the fly. It is approximate
because the user will have to design and run it to see the output.
As all JavaBeans, the IPB would be fully compatible with all java graphical
components. For example: the IPB could be added to Sun Microsystems' Forte software
suite and be used as one would use a java button.
The methodology used in referencing objects and their properties is based on the Object
Oriented Development (OOD) concept. For example: ipb.pathfilename_GV.value
refers to the value of the pathfilename_GV property of the ipb object.
Some properties have been overloaded. For example: a string.value property would be
the literal value of the string but clipboard.value property would be whatever is
contained in the clipboard. In the latter case, value is used in the abstract and is to be
used logically. The details of such properties or objects are left to the higher-level
designer/implementer.
Event names used are logical names and has been used to show that an event of that
type has occurred. The higher-level designers/implementers are not explicitly tied to
using these names in their schemas, as specific situations may not warrant such names.
This specification talks “drag and drop” in abstract. The designer or the programmer
may choose to implement it in a similar but not exact way. For example, clicking a
button and clicking the canvas may create the desired tool at the clicked position, which
gives the desired drag and drop effect.
NOTATION.
Symbol Description
The following rules are used to name constants, variables and types.
panel_T pnl_Main
Identifier Formatting
This section specifies the constants, warnings, exceptions and events that are going to
be used in the IPB. Respective values and descriptions are given in the following
subsections.
This section lists and describes the all the global constants and global variables used in
the IPB. All global constants and global variables are in lowercase, post fixed with
"_GC" for constants and post fixed with "_GV" for variables.
projectdirty_GV boolean_T
modulesdirectory_GV string_T
projectdirty_GV string_T
This section lists and describes all possible messages that a user may get during
interaction with the IPB. All message identifiers are lowercase, post fixed with "_EM"
for exception messages or "_WM" for warning messages.
Exception Messages:
Warning Messages:
This section lists and describes all possible events that may be triggered by a user
during interaction with the IPB.
INPUTS:
cmd_delete cmd_execute
connector_T modifier_T
• Event generated by double clicking any of the following objects on the canvas:
modifier_T
modifier_T
STATE VARIABLE[S]:
Ipb IPB_T
/* the following variables are used (as shorthand) throughout this specification */
INITIAL STATE:
while (true) do
case click_new
if (not cnv.projectdirty_GV.value) or else
(cnv.dlgWarning(ProjectDirty_WM))) then
cnv.projectdirty_GV.value := false
cnv.pathfilename_GV.value := null
cnv.setInitState()
end if
case click_open
if (not cnv.projectdirty_GV.value) or else
(cnv.dlgWarning(ProjectDirty_WM))) then
string_T fn := openDialogBox()
if (fn != null) then
cnv.projectdirty_GV.value := false
cnv := cnv.readFromDisk(fn)
cnv.pathfilename_GV := fn
end if
end if
case click_save
if (cnv.projectdirty_GV.value) then
if (cnv.pathfilename_GV.value == null) then
cnv.pathfilename_GV.value := saveDialogBox()
if (cnv.pathfilename_GV.value != null) then
cnv.writeToDisk(ipb.pathfilename_GV.value)
case click_cut
if (cnv.selected.value != null)) and then (cnv.selected.type == modifier_T)
then
modifier_T mt := cnv.selected.value
removeHandles(mt)
stb.clp_clipboard.value := mt
cnv.selected.value := null
cnv.mod_modifiers.remove(mt)
end if
case click_copy
if (cnv.selected.value != null)) and then (cnv.selected.type == modifier_T)
then
modifier_T mt := new modifier(ipb.selected.value)
removeHandles(mt)
stb.clp_clipboard.value := mt
end if
case click_paste
if (stb.clp_clipboard.value != null) and then (stb.clp_clipboard.value.type
== modifier_T) then
modifier_T mt := stb.clp_clipboard.value
cnv.mod_modifiers.add(mt)
end if
case click_execute
if (cnv.checkProjectValidity()) then
cnv.showResult()
case drag_media_in
media_T mt := new media_in()
cnv.med_incomings.add(mt)
case drag_media_out
if (cnv.media_out.value != null) then
cnv.dlgException(MediaOut_EM)
exit procedure
end if
media_T mt := new media_out()
cnv.media_out.value := mt
case drag_connector
connector_T ct := new connector()
cnv.con_connectors.add(ct)
case drag_viewer
viewer_T vt := new viewer()
cnv.vwr_viewers.add(vt)
case drag_modifier
modifier_T mt := new this.modifier()
cnv.mod_modifiers.add(mt)
case change_category
string_T st := this.category
mtb.mod_modifiers := mtb.tbr_modifiers.getModifiers(st)
end case
end while
The methods add() and remove() are general methods whose functions are to add and
remove the supplied object from the object on which this method is called on.
cnv.setInitState()
cnv.med_incomings.count := 0
cnv.med_outgoing.value := null
cnv.vwr_viewers.count := 0
cnv.mod_modifiers.count := 0
cnv.con_connectors.count := 0
cnv.selected.value := null
mtb.isModuleValid(module_T) : boolean_T
A module represents a logical group of modifiers. This method checks that the
supplied module_T object is a valid module and returns true if it is valid, or false
if it is not.
mtb.tbr_modifiers.add(COLLECTION OF modifier_T)
Adds the supplied collection of modifier_T objects to this collection. Each such
supplied collection is assumed to correspond to one category only and the
category name is used to retrieve its’ corresponding collection of modifier tools.
This method reads the supplied module object and returns the collection of
modifier_T objects contained in them. The supplied module object is assumed to
be valid.
mtb.getCategory(file_T) : string_T
Returns the name of the category that this module file_T object represents. The
supplied module file_T object is assumed to be a valid.
mtb.cmb_category.append(string_T)
Adds the category name represented by the supplied string_T object to the
cmb_category “combobox”.
cnv.dlgWarning(string_T) : boolean_T
Displays a warning message, in the form of a dialog box with options to press
‘Yes’ or ‘No’. The former would indicate a willingness to proceed without regard
to consequences and returns true to the caller while the latter would indicate a
willingness to immediately abort the action and returns false to the caller. The
message displayed depends on the supplied value.
openDialogBox() : string_T
Opens a standard "open dialog box" to select a file to open. Returns a string_T
object representing the file selected or null if nothing was selected by the user.
Reads from disk the file represented by the supplied value. If the file is a valid
canvas_T file, create the canvas_T object and return it. If the file selected is
invalid, give an appropriate exception message and return null.
saveDialogBox() : string_T
cnv.writeToDisk(string_T)
Writes to the file represented by the supplied string_T object, the current canvas
object.
removeHandles(Object_T ob)
cnv.dlgException(string_T)
cnv.checkProjectValidity() : boolean_T
Checks the canvas for any hanging objects and that all connectors are connected.
Give an appropriate exception message to all cases that violate these rules. If there
are no violations return a true, otherwise a false.
cnv.showResult() : window_T
Returns a new window_T object containing all attached viewers and the output.
Note: some of the methods and functions that are needed to do this have been
hidden. It is expected that this would be handled in a later stage. An example of
such a method would be the method that returns the modified image, which would
be contained in all modifier_T objects.
updatePosition()
Updates the position of the object on which this method was called. This is in
response to user moving objects around on the canvas.
cnv.objectAt(position_T) : object_T
Returns the object that is present at the supplied position on the canvas. Returns
null if no object is present.
openProperties()
Opens a dialog box which will allow the user to manipulate the properties of the
object this method was called on.
COMPONENT TYPES.
handle_T : tuple of
phd_placeholder placeholder_T
hdl_other handle_T
pos_position position_T
These are the entities that link objects on the canvas to each other. A handle contains a
link to another handle attached to another object, there by creating a link between these
two objects.
connector_T : tuple of
hdl_handle1 handle_T
hdl_handle2 handle_T
input_T : tuple of
med_incoming media_T
bdr_border border_T
pos_position position_T
This is a special class that handles the graphic/media to be modified. It is the bridge
between the external input and the IPB.
The border is shown if it is clicked (to show that it has been selected) and then can be
deleted.
output_T : tuple of
med_outgoing media_T
bdr_border border_T
pos_position position_T
The border is shown if it is clicked (to show that it has been selected) and then can be
deleted.
viewer_T : tuple of
bdr_border border_T
pos_position position_T
hdl_incoming handle_T
hdl_outgoing handle_T
This is a user help tool. The viewer does not modify the image in anyway.
The border is shown if it is clicked (to show that it has been selected) and then can be
deleted.
modifier_T : tuple of
bdr_border border_T
pos_position position_T
All image modifiers (eg: lenses, distortions, ...) are of this type.
The border is shown if it is clicked (to show that it has been selected) and then can be
deleted. For modifiers only, when selected, it can be "cut" or "copied" to the clipboard.
canvas_T : tuple of
projectdirty_GV boolean_T
modulesdirectory_GV string_T
pathfilename_GV string_T
med_media_out output_T
standardtoolbar_T : tuple of
cmd_new button_T
cmd_open button_T
cmd_save button_T
cmd_cut button_T
cmd_copy button_T
cmd_paste button_T
cmd_delete button_T
cmd_execute button_T
lbl_status label_T
This is the standard toolbar which lies at the top of the IPB and contains the standard
tool options similar to any other GUI. A label masquerades as a status bar filling the rest
of the space on this toolbar.
modifiertoolbar_T : tuple of
cmd_input button_T
cmd_output button_T
cmd_viewer button_T
cmd_deselector button_T
cmb_categories combobox_T
This is the modifier toolbar that lies at the bottom of the IPB and contains the tools used
to modify and manipulate images. This toolbar also contains media in/out buttons,
viewers and connectors, and a “combobox” which lists the logical categories into which
the modifier tools are divided.
The modifier tools that are currently available are contained in mod_modifiers.
tbr_modifiers is a collection of toolbars, each toolbar containing a logical category of
modifier tools. A toolbar in tbr_modifiers is retrieved when the corresponding category
is selected from the cmb_categories “combobox”.
IPB_T : tuple of
tlb_standard standardtoolbar_T
tlb_modifier modifiertoolbar_T
pnl_canvas canvas_T
This is the IPB. The IPB consists of a standard toolbar on top, an image modifying
toolbar at the bottom and a drawing canvas between them and environment variables.
This section specifies the general types used in the IPB. The details of these types is left
for the higher level designer or programmer.
Type Description
this is a unique setting which shows that the object has been
border_T
selected
string_T a string
integer_T an integer
boolean_T a Boolean
• Undo/Redo facility.
• Keyboard shortcuts for commands.
• A check to disallow a connector be connected to both ends of the same object
• A checking algorithm that checks that images have not been connected in a cyclic
fashion.
The following design illustrations have been done in Universal Modelling Language
(UML). To understand these illustrations, a working knowledge of UML and Object
Oriented Programming is required.
The below UML diagram shows how the objects on the drawing area is designed [12].
All the tools (buttons) on the drawing area must be implementations of CanvasButton
interface. This interface is an extension of the CanvasObject interface and defines the
common properties of all drawing area buttons, namely handles from connecters have to
be added and removed, the image represented by this tool has to be set, updated and
returned, the image state has to be set and returned, the handles that are incoming and
outgoing have to be returned.
The below UML diagram shows how the drawing area is designed [12]. The drawing
area implements four interfaces, which are used to interact with their corresponding
calling objects.
The GridOperations interface controls how the drawing area is seen to the user. The
grid width, style and colours are set using this interface. The grid also drawing by this
interface.
A module consists of multiple tools. Each tool must implement the ModifierInterface
which used by “clipboard operations” such as “cut and copy”. All modifier tools are
extensions of the AbstractCanvasButton class and only implements the methods that
need to be updated (different) from the parent class.
PRODUCT EVALUATION
A final product was created to the specification and design given above in this
document. The product met all requirements given in the above specification. However,
only a few (six) JAI operations were implemented for the final testing of the product.
These six operations were divided into two categories and thus were in two different
modules.
The component was tested with no modules, with one module and two modules. Each
time, the component loaded correctly with the available tools (if available). Each tool
button on each toolbar was tested individually. The drawing area was tested with a
variable number of tools and connectors on them, and checked if mouse operations
(drag, move and click) worked correctly for all objects on the drawing area. Clipboard
functions were tested for modifier tools on the drawing area. Property setting functions
for modifier tools (all six) were checked. All of these tests passed.
The component was also tested with invalid modules. The component executed
correctly by dumping the module when an error state was reached.
Finally a simple design was created on the drawing area. The design executed correctly
giving the expected output. More complex designs were created and they also gave the
correct output.
It should be noted that the “save” and “open” function were not completed for this
component. The completed part for both of these functions worked correctly.
One very important feature that was not in the specification was implemented. This was
an “on the fly check” of the modified image. This involved double clicking any tool on
the drawing area, which, if connected correctly, opened up the properties window with
the modified image up to that point. Further, modifier tools with custom properties were
made to show real-time image modification in response to changes the user makes to
its’ settings. Thus, less time was wasted in running the whole design.
FUTURE DEVELOPMENT
The above mentioned “on the fly check” could be extended to show changes to images
that lie higher up on the hierarchy, such as the final output. Thus, a user would be able
to see real-time changes, say, of the final output by changing settings on other tools.
This would further boost productivity.
Scripting ability could also be added to the component. This would be the major
change, if I were to do a future version of this product. The specification and the
resulting design had no requirement for scripting capability to be built into the
component. Therefore, it is expected that this change may result in significantly more
work than a simple extension or an addition of a feature. This would also allow the
component to be used in a non-graphical sense, to create a design from within the script,
and get the final output.
The parts that were not finished, saving a design and opening a design, is expected to be
implemented in the next upgrade of the product or in a new release.
Other “standard” features can be added to this component. These include “undo” and
“redo” functions and the ability to handle multiple designs.
/**
* @file HandleObject.java
* @created August 2001
* @modified September 2001
*/
package rmanchu.thesis.ipb;
import java.awt.Point;
/**
* This interface represents the API used to manipulate handles.
*
* @author rmanchu
* @version 1.0
* @see Connector
* @see CanvasButton
*/
public interface HandleObject
{
/**
* Type "Incoming" handle. Attached to the input side of a
* <code>CanvasButtonInterface</code> object.
*/
public final static int INCOMING = 0;
/**
* Type "Outgoing" handle. Attached to the output side of a
* <code>CanvasButtonInterface</code> object.
*/
public final static int OUTGOING = 1;
/**
* Type "Hanging" handle. Not Attached to a
* <code>CanvasButtonInterface</code> object.
*/
public final static int HANGING = 2;
/**
* Returns the handle to which this object is linked to. This method is
* used to go through the "tree" which is the design the user has
* drawn up on the drawing canvas.
*
* @return The handle to which this object is linked to.
* @see #setNext
*/
public HandleObject getNext();
/**
* Same method as found in <code>Componenet</code>. Put here to get access
* to this method.
*
* @param p The point to set the location of this handle object on.
* @see java.awt.Component#setLocation
*/
public void setLocation(Point p);
/**
* Same method as found in <code>Componenet</code>. Put here to get access
* to this method.
*
* @return The point representing location of this handle object.
* @see java.awt.Component#getLocation
*/
public Point getLocation();
/**
* Centers this handle to the supplied location. Gives a more
* "attached" feel when seen on the drawing canvas.
*
* @param p The point to center this handle on.
* @see #getCenteredLocation
*/
public void setCenteredLocation(Point p);
/**
* Sets the <code>CanvasButton</code> object that this handle
* is attached to.
*
* @param cb The <code>CanvasButton</code> object that this handle
* will be attached to.
* @see #getAttachedTo
*/
public void setAttachedTo(CanvasButton cb);
/**
* Returns the <code>CanvasButton</code> object that this handle
* is attached to.
*
* @param The <code>CanvasButton</code> object that this handle
* is attached to.
* @see #setAttachedTo
*/
public CanvasButton getAttachedTo();
/**
* Sets the type of this handle object. The types could be <P>
* <UL>
* <LI>HandleObject.INCOMING</LI>
* <LI>HandleObject.OUTGOING</LI>
* <LI>HandleObject.HANGING</LI>
* </UL>
* <P>
*
* @param type The type of this handle object.
* @throws IllegalArgumentException if "type" does not corresspond to the
* above values.
* @see #getType
*/
public void setType(int type) throws IllegalArgumentException;
/**
* @file GridOperations.java
* @created August 2001
* @modified August 2001
*/
package rmanchu.thesis.ipb;
import java.awt.Color;
import java.awt.Stroke;
import java.awt.Graphics2D;
/**
* The API used to manipulate the grid properties on the drawing canvas.
*
* @author rmanchu
* @version 1.0
*/
public interface GridOperations {
/**
* Sets the stroke to be used when painting the grid.
*
* @param stk The stroke to be used when painting the grid.
*/
public void setGridStroke(Stroke stk);
/**
* Sets the grid spacing to the supplied value.
*
* @param gs The new grid spacing length.
*/
public void setGridSpacing(int gs);
/**
* Returns the spacing length used for this grid.
*
* @return The grid spacing length.
*/
public int getGridSpacing();
/**
* Draws the grid using the grid properties
*
* @param g2 The graphics object used to draw the grid.
*/
public void paintGrid(Graphics2D g2);
package rmanchu.thesis.ipb;
import java.awt.Point;
/**
* The API used by the standard toolbar to interface with the drawing canvas.
*
* @author rmanchu
* @version 1.0
*/
public interface DrawingCanvasMouseOperations {
/**
* Sets the supplied canvas object as the object that's selected on the
* drawing canvas.
*
* @param obj The object to be be set as selected.
*/
public void setSelected(CanvasObject co);
/**
* Returns the selected canvas object on the drawing canvas.
*
* @return The canvas object that's selected.
*/
public CanvasObject getSelected();
/**
* Sets the supplied <code>state</code> as the modified state of the project.
* If a <code>true</code> is supplied it means the project has been
* modified and is in need of saving and vice versa.
*
* @param state The new state of the project. A <code>true</code> if
* the project has been modified and is in need of saving.
* @see getProjectModified
*/
public void setProjectModified(boolean state);
/**
* Adds the ready object to the drawing canvas. If there is no ready
* object nothing is added.
*
* @param xPos Position on x-axis to add the object.
* @param yPos Position on y-zxix to add the object.
*/
public boolean addObjectToAdd(double xPos, double yPos);
/**
* Returns the closest point in the grid corresponding to the supplied point.
*
* @param xPos The x-axis position.
* @param yPos The y-axis position.
* @return The point that corresponds closest to the supplied position valus.
*/
public Point snapToGrid(double xPos, double yPos);
/**
* Instructs to redraw the whole drawing canvas.
*/
public void reDraw();
/**
* Returns true if a connector was clicked after setting the connector as
* the selected object.
*
* @param xPos The x-axis position of click.
* @param yPos The y-axis position of click.
*/
public boolean clickedConnector(double xPos, double yPos);
/**
* Unselects any selected object on the drawing canvas.
*/
public void clearSelected();
package rmanchu.thesis.ipb;
import java.awt.Point;
import java.util.Vector;
import javax.swing.JComponent;
/**
* This interface represents the API used by all objects on the drawing
* canvas.
*
* @author rmanchu
* @version 1.0
*/
public interface CanvasObject {
/**
* Sets the selected state of this object. A selected is seen different
* from an unselected object.
*
* @param state The new selected state of this object.
*/
public void setSelected(boolean state);
/**
* Returns the selected state of this object. If a <code>true</code>
* is returned, this object is selected.
*
* @return The selected state of this object.
*/
public boolean getSelected();
/**
* Returns <code>true</code> if object statisfies all references. Every
* object has a minimum set of links to other objects on the drawing
* canvas and meeting this requirment returns a <code>true</code>.
*
* @return Returns true if object satisfies all references.
*/
public boolean isReferencesValid();
/**
* Removes this object from its parent component and from the list of
* such components.
*
* @see add
*/
public void remove();
/**
* Clears all references from this object and to this object. This
* essentially makes this object ready for garbage collection.
*/
public void clearAllReferences();
package rmanchu.thesis.ipb;
import java.awt.Rectangle;
import java.util.Enumeration;
import javax.swing.Icon;
import javax.media.jai.PlanarImage;
/**
* This interface extends the <code>CanvasObjectInterface</code> for
* the button tools that are added to the drawing canvas and adds
* more methods to handle them.
*
* @author rmanchu
* @version 1.0
* @see CanvasObjectInterface
* @see CanvasButton
*/
public interface CanvasButton
extends CanvasObject
{
/**
* Attaches the supplied handle to this object using the <code>xPos</code>
* value to determine whether its an incoming handle or an outgoing handle.
* If <code>xPos</code> is less than half the width of this object then
* the supplied handle is made an incoming handle and attached or
* vice versa.
*
* @param hi The handle to add to this canvas button.
* @param xPos The x-axis position.
* @see HandleObject
*/
public void addHandle(HandleObject hi, int xPos);
/**
* Sets the modified graphic at this object according to the users design
* on the drawing canvas. This <code>image</code> is constructed from
* the preceeding <code>CanvasButtonInterface</code> objects and with
* any custom properties of this object.
*
* @param image The new internal graphic image for this object.
* @see #getImage
*/
public void setImage(PlanarImage image);
/**
* Returns the modified graphic at this object according to the users design
* on the drawing canvas.
*
* @return The Icon representing the internal graphic for the project.
* @see #setImage
*/
public PlanarImage getImage();
/**
* Sets the updated state of the internal graphic. If a <code>true</code>
* is supplied image does not need updation and thus no preceeding
* <code>CanvasButtonInterface</code> objects needs updation as well. If a
* <code>false</code is supplied, all preceeding
* <code>CanvasButtonInterface</code> objects are checked and updated
* if necessary.
*
* @param state The new internal graphic updated state.
* @see #getImageUpdateState
*/
public void setImageUpdateState(boolean state);
/**
* Returns the updated state of the internal graphic.
*
* @return <code>true</code> if internal graphics needs no updating.
* @see #setImageUpdateState
*/
/**
* Same method as found in <code>Componenet</code>. Put here to get access
* to this method.
*
* @param r The rectangle representing the new bounds for this object.
* @see java.awt.Component#setBounds
*/
public void setBounds(Rectangle r);
/**
* Same method as found in <code>Componenet</code>. Put here to get access
* to this method.
*
* @return The rectangle representing the bounds of this object.
* @see java.awt.Component#getBounds
*/
public Rectangle getBounds();
/**
* Updates the supplied handle position only so that the handle appear
* correctly with respect to this object. This method is for efficiency.
*
* @param hi The handle to update.
*/
public void updateHandle(HandleObject hi);
/**
* Updates all the handle positions so that the handles appear correctly with
* respect to this object.
*/
public void updateHandles();
/**
* Updates the internal graphic at this object according to the users design
* on the drawing canvas. Updation occurs by going through and updating all
* preceeding <code>CanvasButtonInterface</code> objects and updating
* them as well.
*/
public void updateImage();
/**
* Sets the custom properties of this object. Expected to be implemented
* separately for each tool.
*/
public void setProperties();
/**
* Returns an enumeration of all attached incoming handles.
*
* @return An enumeration of all incoming handles.
*/
public Enumeration getIncomingHandles();
/**
* Returns an enumeration of all attached outgoing handles.
*
* @return An enumeration of all outgoing handles.
*/
public Enumeration getOutgoingHandles();
/**
* @file CanvasButtonInterface.java
* @created October 2001
* @modified October 2001
*/
package rmanchu.thesis.ipb;
/**
* @author rmanchu
* @version 1.0
* @see ModifierToolbar
*/
public interface CanvasButtonInterface {
/**
* Updates the drawing canvas from the supplied cb.
*
* @param cb The object to parse the tree on.
*/
public boolean updateCanvas(CanvasButton cb);
/**
* Sets all tools on the drawing canvas as not updated.
*/
public boolean validateCanvas(CanvasButton cb);
/**
* @file StandardToolbarOperations.java
* @created August 2001
* @modified August 2001
*/
package rmanchu.thesis.ipb;
/**
* The API used by the standard toolbar to interface with the drawing canvas.
*
* @author rmanchu
* @version 1.0
*/
public interface StandardToolbarOperations {
/**
* Executes the actions associated with the clicking of the <B>new</B>
* standard tool button.
*/
public void execNew();
/**
* Executes the actions associated with the clicking of the <B>open</B>
* standard tool button.
*/
public void execOpen();
/**
* Executes the actions associated with the clicking of the <B>save</B>
* standard tool button.
*/
public void execSave();
/**
* Executes the actions associated with the clicking of the <B>cut</B>
* standard tool button.
*/
public void execCut();
/**
* Executes the actions associated with the clicking of the <B>copy</B>
* standard tool button.
*/
public void execCopy();
/**
* Executes the actions associated with the clicking of the <B>delete</B>
* standard tool button.
*/
public void execDelete();
/**
* Executes the actions associated with the clicking of the <B>execute</B>
* standard tool button.
*/
public void execExecute();
/**
* @file ModifierToolbarOperations.java
* @created August 2001
* @modified September 2001
*/
package rmanchu.thesis.ipb;
/**
* This interface represents the API used by the all the tools on
* the modifier toolbar. These tools are<br>
* The standard tools:<br>
* <ul>
* <li>Media Input</li>
* <li>Connector</li>
* <li>Media Output</li>
* <li>Image Viewer</li>
* <li>De-Selector</li>
* </ul>
* The modifier tools: All the modifier tools.
*
* @author rmanchu
* @version 1.0
* @see ModifierToolbar
*/
public interface ModifierToolbarInterface {
/**
* Returns the <code>CanvasObject</code> that has been readied to be added
* to the drawing canvas. A <code>null</code> is returned if no
* <code>CanvasObject</code> is ready to be added.
*
* @return The object to be added to the drawing canvas.
*/
public CanvasObject getCanvasObjectToAdd();
/**
* Sets the supplied <code>state</code> as the modified state of the project.
* If a <code>true</code> is supplied it means the project has been
* modified and is in need of saving and vice versa.
*
* @param state The new state of the project. A <code>true</code> if
* the project has been modified and is in need of saving.
* @see getProjectModified
*/
public void setProjectModified(boolean state);
/**
* Returns the modified state of the project. If a <code>true</code> is
* returned, the project is in need of being saved and vice versa.
*
* @return The current modified state of the project.
* @see setProjectModified
*/
public boolean getProjectModified();
package rmanchu.thesis.ipb;
[1] Theo Pavlidis, Algorithms for Graphics and Image Processing, Computer Science
Press, 1982.
[2] John C. Russ, The Image Processing Handbook, CRC Press, 1995.
[4] David Bistry [et al.], Complete Guide to MMX Technology, McGraw-Hill 1997.
[5] Joe King, Matlab for Engineers – Second Edition, Addison-Wesley Publishing
Co., 1998.
[6] Barry Haynes, Photoshop 6 Artistry – Mastering the Digital Image, New Riders
Publishing, 2001.
[9] Mitchell Waite [et al.], Data Structures and Algorithms in Java, Waite Group
Press, 1999.
[12] C. T. Arrington, Enterprise Java with UML, John Wiley and Sons, 2001.
[13] www.intel.com
[14] www.microsoft.com
[16] www.adobe.com
[17] java.sun.com
[18] www.mathworks.com