Aug 2007
etu: Hitting a Crossroad in a Simple Program
Or 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.
(based on last 2 months log reports)