Aug 2007
etu: Hitting a Crossroad in a Simple ProgramOr another way of saying if the route to take seems obvious then
it is probably the correct route [1]. When
dealing with a software system the obvious route may not always
seem so simple. In fact, one might need to go back to the beginning
of their particular project to see what route might be either the
best or at least most correct. In this text, a program
called etu is examined. This tiny program (at least by
itself) came upon a crossroad of sorts and the simplest answers
turned out to be the best route to take.
A while ago the first pass at creating a jpeg thumb-nailer that
leveraged the enlightenment
epeg API was written as a demonstration program. The
little (and fast) thumb utility that could turned out to be
pretty handy. So, etu received a few small upgrades
such as:
... and etu was happy, until one day, someone
asked:
Why does it only do jpegs?
The immediate answer was:
Because that is what it was designed to do in the beginning ...
Taking a look back at the original program, however, it became
obvious that even with the small enhancements it had received
already, the program had grown from doing one image file to a
directory full of N files. So why should it not support
other formats? The enlightenment suite of software
addresses thumb-nailing and scaling by default. Adding
support for an ad-hoc image scaling program should not be too
difficult.
There were three goals that emerged in order to accommodate non
jpeg image format support in etu:
etu needed to be in sync
with how other enlightenment software is built.enlightenment APIs that could do
the scaling and hence remain consistent with the overall goal of
the program.A lot of software requires something to stand it up before it
can be built. Usually standing up
means something like
bootstrapping, however, in the case of etu it only
needed to conform to the enlightenment method of
building software. The etu program could already be
built from a very plain Makefile. The motivation for
integrating it into how other enlightenment software
is built was simple:
If it happens twice, it will happen again...
Qualifier; someone asked one question already which created
the two former goals - if the software continues to work
(hopefully it works well) there is a high probability of more
questions; ergo more changes. To better track the nuances of a
developing software system such as enlightenment it is
a far wiser thing to make sure etu can plug in and
leverage the pre-existing infrastructure of the
entire software system.
Understanding the concept of adapting to someone (or some
persons) software system configuration is key and requires a degree
of adaptability; whether the adaptation consists of how it is built
or something as simple as comment style. It is especially important
in larger groups where the outside code is being created long after
the system itself was started (which was the case with
etu [3].
Regardless of motivation, the actual work while somewhat tedious
was relatively simple. Using a pre existing eapp that
was fairly small provided a basic framework pieces for the
directory layout, auto-configuration and flag/library options.
After discussing the issue with a C-hacker friend, the first approach to image type decoding was to actually use a two pass algorithm:
Determine type by extension
If (jpg,jpeg,JPG,JPEG,Jpeg...)
Load image into epeg
If fail
Determine type using UNIX magic_number
call non-epeg scaler
Else
call epeg-scalar
Else
call non-epeg scaler
The two passes being if it is and oh nuts it
is not.
There is a serious logic flaw in the above. Efficiency: if the image is not jpeg format, what if it is still a format that will not work? Do all of the formats have to be explicitly checked for? How much work in this tiny program would be expended doing so? Imagine having to build an internal translation table for magic numbers. The possibility of having to do all of that work not only seemed ugly but counterintuitive to the whole point of the program which is:
Leverage Enlightenment developed software at every possible turn to create a simple yet powerful ad-hoc image scaling program.
An obvious answer arrived simply by digging around the entire
e17 repository - Imlib2 could determine
the image type in a few relatively simple steps. The plus,
etu only cares if the image is a jpeg or
_not_ which makes the logic extraordinarily simple:
Load image into Imlib2
Get Image type
Free Image from Imlib2
If image is jpeg
call epeg-scaler
Else
call non-epeg scaler
Much better, much simpler and hopefully faster.
The last piece of the puzzle was the fall through to a non jpeg
image. Of course long time users of Enlightenment already know the
answer but at the time, the mentality was use anything and
everything that already exists and is specific to the new(er)
Enlightenment software system.
Instead of taking the obvious
route, the first route was to do something else altogether.
There exist with the ever-changing enlightenment
system several libraries that do image scaling. The first pass of
non-jpeg support for etu used one of them. As it
turned out, that API was designed only for cache style systems, not
ad-hoc resizing. Several hours of trying to shoehorn in another API
finally resulted in abandoning the idea. The search almost led to
abandoning non-jpeg support at all.
Then the obvious struck .... Imlib2 can do it,
actually it already had code designed for that very
purpose the difference between the existing code and
etu is that etu can do larger grouped operations and
has somewhat finer control. With the last piece of the puzzle in
place, the rest was pretty simple.
Sometimes the answer is staring you right in the face, so much
so that you actually used the same answer for a different
problem. It is said the road less travelled is more
interesting
(or something to that effect), however, if someone
else has been down the road, and has a map, and a guide to the best
places to eat - then you might want to take advantage of that
information - ultimately it could save a lot of time.
the simplest solution is often the correct one.
style or config conformityunique to the Enlightenment Foundation. All of the BSD projects and the Linux kernel (and many more) have guides that cover everything from style to API design.
I would be remiss if I did not acknowledge the help I received
from Rasterman himself (who
basically steered me) and my good friend Gleicon da Silveira
Moraes (aka Tuna) who was (and often is) the sounding board for
my C past times.