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 . 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
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
etu was happy, until one day, someone
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
There were three goals that emerged in order to accommodate non
jpeg image format support in
etuneeded to be in sync with how other
enlightenmentsoftware is built.
enlightenmentAPIs 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
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
Regardless of motivation, the actual work while somewhat tedious
was relatively simple. Using a pre existing
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
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
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
C past times.