Archive | GTK+ RSS for this section

DMP Photo Booth 1.0

Well, the day has come and gone. DMP Photo Booth’s final test on June 21st went off without issue, and DMP Photo Booth has left Beta and is now considered “production ready”. The initial 1.0 release can be found on GitHub.

The significance of June 21st is the very reason DMP Photo Booth was created; the 21st is the day of my wedding. My wife wanted a photo booth for the reception. We looked into renting a photo booth, but it turns out that they run around $1,000. I turned to open source. Some quick googling turned up some options, but they were all personal projects or out of date. Sure I could get somebody else’s project working, but what’s the fun in that? I decided that we didn’t need to rent one, or download one, I could build it!

In late 2013, I set to work in earnest. I had a couple of months of downtime in school, and since I’m not currently working it was the perfect time. I decided I had three main objectives for this project: get some arduino experience, get some GTK+ experience, and do this all as portably as possible. I had initially decided to mostly ignore GLib and focus on GTK, but slowly I grew to appreciate GLib for what it is: the standard library that C never had. First I used GModule to handle shared libraries in a portable manner. Next I decided to use GLib primitives to keep from having to deal with cross-platform type wonkiness. Next, having grown tired of dealing with return codes, I refactored the project to use GLib’s exception replacement: GError.

Lessons Learned

It’s not all roses and puppies though. There are certainly things I’d do differently. DMP Photo Booth is developed in an Object Oriented style, passing opaque structs with “method” functions that operate on them. Each component of the program are organized into their own source file with file scoped globals scattered throughout. Said globals are protected by mutexes to create a semblance of thread safety. That said, threading issues have been a major thorn in my side. Long story short: I regret this design choice. While I still feel that this is the correct way to structure C code, and that if globals are required, this is the correct way to handle them; I feel that I should have made more of an effort to limit side effects. Recently, I’ve spent some time doing functional programming, and if I could do it again I’d try to write in a more functional style. Fortunately for me, this is something that a little refactoring could help with.

Additionally, one thing I thought would be a major help is something that began to be a major thorn in my side: NetBeans. As the size of the project grew, NetBeans got slower and slower. It seemed that I spent more time fiddling with IDE settings than actually coding. Even worse is that the IDE-generated makefile is so convoluted that it’s extremely difficult to modify by hand in a satisfying way. I’ve always coded with and IDE so I wouldn’t have even considered not using one, but then I spent some time with Haskell. One of Haskell’s “problems” is that it doesn’t have good IDE support. It doesn’t seem like any IDE really handles it well, so most people use Emacs. Personally, I haven’t really warmed up to Emacs, but GEdit has syntax highlighting for Haskell and a built-in terminal for GHCI. GEdit also has syntax highlighting for C. Next time, I will seriously consider using a lighter-weight text editor for a C project. All this said, I think NetBeans for Java remains the way to go.

What’s Next

Like any program, version 1.0 is just one of many versions. There certainly remains a lot of work to do with DMP Photo Booth. Some major items you are likely to see whenever I get around to working on DMP Photo Booth some more:

Options Dialog

I think anybody who has seen it will agree: the options dialog in DMP Photo Booth is bad. It’s poorly organized, and kind of wonky. Personally, I modify settings using the .rc file, which is telling. This is certainly a high-priority improvement.

Functional Refactor

Like I said above, the code could use a pass to limit side effects. Funtions need to have their side effects limited, and globals need to be eliminated unless absolutely necessary. However, C is not a functional language. While one could argue that function pointers enable functional programming in C, this is a very pedantic argument. I won’t be going crazy with functional programming techniques. There will be no Monads, or for loops being turned into mappings of function pointers.

Optional Module API

An idea I’ve had on the back burner for a while is an optional module API. This would be used for very specific quality-of-life things. For instance, a module could provide a GTK widget to be shown in the options dialog. Any module that doesn’t want to implement any or all of the optional API can just ignore it. The module loading function will gracefully handle the dlsym failure, just treating it as it is: declining to implement the API. I have no plans to change the current existing API, so all you module developers can rest easy!

User Interface Module

It occurred to me that it might be good to have a UI module. This would provide the UI, and wouldn’t be tied to the trigger/printer/camera module start/stop system. This module would be loaded at startup and unloaded on shutdown. This would allow the Photo Booth to use different widget toolkits: QT, Curses, Cocoa, WinForms, or whatever else. Under this scheme, the current GTK+ interface would be abstracted into the reference UI Module.

At The Gates Of Valhalla

In my post the other day, I talked about using Valgrind and GProf to debug DMP Photo Booth. As tends to be the way of most articles on the Internet, I didn’t actually spend any time talking about how to use said programs. You are, however, on notice that they are Good.

Well, I promised I’d tell you how to use them. I may be many things, but a liar I am not. Today, I’ll start with Valgrind.

Valgrind

Installation

First things first, we need to install. Once again, Ubuntu comes through for us. It’s just a simple matter of …

sudo apt-get install valgrind

… and we’re off to the races. Unfortunately for those of you in the audience running Windows, Valgrind is not available for Windows.

Valgrind Vs. GLib

You may remember in my last post a lot of talk about difficulties with GTK. Per the Gnome Wiki, the recommended way to launch Valgrind with a GLib/GTK application is:

G_DEBUG=resident-modules valgrind \ --tool=memcheck \ --leak-check=full \ --leak-resolution=high \ --num-callers=20 \ --log-file=vgdump \ [your-program]

Let’s talk about these options.

  • G_DEBUG=resident-modules
    • This is not actually an argument to Valgrind, but an environment variable. This is used by GLib. You need to use this if your application makes use of GModule. For instance, if you’re implementing a module-based Photo Booth application. If you don’t use this, your modules may get unloaded prematurely. If this doesn’t apply to your application, feel free to omit this.
  • valgrind
    • Calls valgrind
  • –tool=memcheck
    • Valgrind is actually a suite of tools. Memcheck is the tool that checks for memory leaks
  • –leak-check=full
    • Enables searching for leaks on exit
  • –leak-resolution=high
    • Sets the detail level of leak stack traces
  • –num-callers=20
    • This sets the depth of the stack traces. For instance, setting this to 20 will show: foo() called by bar() … and so on up to 20 times
  • –log-file=vgdump
    • The file to output to. In its current configuration, a file named vgdump will be placed in the current directory
  • [your-program]
    • Finally, your program. Place in whatever command you’d call to start your program.

…so you do all that and execute your program. Valgrind will monitor your program while you interact with it. Go ahead and run some test cases. It’ll be a little slow due to the monitoring, but that’s ok. Finally, when you’re done, exit your program and open the log file. The first thing you should notice is that it is long. Really long.

This is due to GTK. GTK doesn’t clean up after itself on exit, instead relying on the OS to clean up on process termination. While this behavior is considered to be fine by most, it makes this step difficult. On the Gnome Wiki, you’ll find a Suppression file that is used to mitigate some of this. My experience with this is that it doesn’t do much.

The best way I’ve found is to just search for “definitely lost”. These are most likely to be caused by your program. You can go line by line and check each possibly lost section, but I’ve found that this isn’t practical as 99/100 of these originate from gtk_main().

DMP Photo Booth: Underwater

You’ve heard it before: “Premature optimization is the root of all Evil.” Capital Evil. So you go on about your day, arranging the ones and zeros in pretty christmas tree shapes and suddenly the day arrives: your program is slow as molasses. What are you going to do now?

Last monday was that day for me, and I’ve been underwater ever since. “Why is this happening to me?!” I thought. While not prematurely optimizing, I thought I did things right. I have no nested for loops. I’m not using an array when I need a list. Threads aren’t modifying the UI willy-nilly. Why has God forsaken me?

The Symptoms

I first noticed it while working on the printer module. After the program is open for some length of time, my whole computer begins to lag. Not just a little bit either; things completely fall apart. In the space of about 5 minutes, the computer becomes unusably slow. Killing the Photo Booth process doesn’t help; only physically shutting the computer off helps. Of course, the computer is so slow that I can’t use the shutdown option; I have to press The Button.

At this point, I feel some context is in order. I had been trying to figure out how to make my printer print on photo paper. Apparently printing is one of the areas Linux still hasn’t caught up to windows on, so this was proving to be difficult. After printing a few strips, I realized that my low-res photo strips weren’t going to cut it, so I bumped the resolution from 100 pixels wide to 1000. It was then that I noticed things were off.

Ten years of troubleshooting experience kicked in: “what changed?” I thought. The obvious answer was the image size. Clearly my photo strip assembly algorithm was operating at O(n^n^n) or something. What can be done?

Doing It Wrong

I took a look at my assemble strips function. After poking around for a while, I zeroed in on something that had been bugging me for a while. I had been using a function MagickResetImagePage combined with MagickCoalesceImages to composite images over each other. I had decided to use these functions before I knew this operation was called “compositing”, and I had found them in a tutorial on making animated .gif files in MagickWand. At the time, I was never really happy with this implementation, so I went back to the API docs to see if there was a function with “composite” in its name. There was.

MagickCompositeImage is a lot more intuitive to use than MagickResetImagePage. It doesn’t have that Magickal formatting string that MagickResetImagePage uses, it just takes coordinates. Perhaps this was the solution to my problem. I refactored, and recompiled.

Still broke.

Measure, Don’t Guess

That old gem: I’m sure you’ve heard it too. I decided that maybe this was my best course of action. I decided it was time to learn how to use this Valgrind thing all the Cool Kids are talking about these days. For those of you not in the know, Valgrind is a utility that will tell you various things about your program. The most important/most well-known thing that it can do for you is identify memory leaks. Thinking that prehaps I have a memory leak, I installed Valgrind and got to work.

It turns out that GTK has more than a few memory leaks. Allegedly this is due to the fact that it doesn’t cleanup on exit, relying on the OS to free the memory on program termination. While the general consensus is that this is fine, it doesn’t help us. The folks at Gnome are aware of this, and there is even a Wiki page on ways to mitigate this. The cliff’s notes version of that page being: “Just search for ‘definitely lost'”.

Armed with this piece of wisdom, I set off. I ran the Photo Booth in Valgrind, and examined the results. Valgrind actually turned up some memory leaks, which I corrected. Maybe now we’re set!

Nope.

Breaking Out The Profiler

This is what they usually want you to do when they tell you to Measure. Unfortunately for me, NetBeans’ built-in profiler is only for Java. After some google searching, I found gprof. Gprof is a pretty bare-bones profiler. It does what it says and not much else, which is fine. I hooked my program into the profiler and got to work. The results? Nothing. My two GTK idle functions ran some 7 million times, returning basically immediately each time as expected. Every other function performed as expected.

What now?

Trying The Process Monitor

Having run through Valgrind and GProf, coming out empty-handed, I was at a loss. I got into development because I wanted to fix my own broken code instead of mitigate somebody else’s, and fix it I will. Luckily I have 10 years of sysadmin experience to fall back on. I dusted off my process monitor and got to work.

I fired up DMP Photo Booth, and watched it in the process monitor. I pushed the button. I pushed it again. And again. memory use rose and fell predictably as the strip was assembled, but CPU usage stayed relatively low. Then boom!

I tried again, this time doing literally nothing. Still my computer sputtered and died. I killed the process, but again it was too late.

But wait, isn’t the OS supposed to clean up after me when my process ends? Something fishy is going on.

Have I Mentioned That Threads Are Hard?

Having eliminated all other possibilities, I was forced to consider that I was having a threading issue. “But I was so careful!” I thought. Shortly thereafter I noticed it: I was getting random pthread mutex errors on my console. Clearly I had a threading issue on my hand. Was I spawning extra threads? Was something not releasing its lock? Was I being victimized by gremlins? I set a break point on line one of main() and fired up my debugger. It was time to see just what was being done when nothing was being done.

So, I stepped through my program. Whenever I got to a g_thread_new call, I made sure the thread function was solid. Finally, I got to my g_idle_add calls. I had two of them, one to monitor the status indicators, and one to retrieve photo strip thumbnails. Both of these functions pop from a result from a GAsyncQueue. These Queues are fed by worker threads. I thought back to my profiler output and remembered how often these are called. Looking a few lines down I saw a call to g_timeout_add_seconds. This function is basically adds an idle function, but is only called at most X seconds. Maybe replacing the g_idle_add calls with g_timeout_add_seconds was my answer. I refactored and reran.

Nope.

Well, crud. “Are these functions even my problem?” I thought. I commented them out, recompiled and reran.

Fixed.

“So, what’s the difference?” I wondered. All three of these functions rely on the same basic behavior: pop from a GAsyncQueue some result placed there by a worker thread. I looked at the three threads: the thread that was working properly calls g_async_queue_ref/unref, and the two that don’t work do not take a reference, instead accessing the static global variable in their module. I refactored all thread functions that access a GAsyncQueue to take a reference and work on their local copy only. I recompiled, reran, and went to bed. 46,100 seconds later, everything was humming along just fine.

Wait, So I Just Had To Increment A Reference Count?

It certainly seemed odd. That’s like your car not starting if the headlights are out. Sure, they’re important, but the car should still start right?

Looking through the source of glib didn’t help. So far as I can tell, all that does is increment the reference count, and return a pointer. I turned to the documentation, which says “… Whenever another thread is creating a new reference of (that is, pointer to) the queue, it has to increase the reference count (using g_async_queue_ref()). Also, before removing this reference, the reference count has to be decreased (using g_async_queue_unref()). …” While not definitive, this certainly seems to indicate that taking a reference is important.

Frankly, I’m not happy about this answer. This is just the sort of magic solution that I hate; it’s fixed, but I’m not sure why. For the time being, I won’t dwell on it. Moving forward, I’ll be sure that my threads take a reference of a GAsyncQueue before calling methods on it. At some point when all of this is said and done, perhaps I’ll investigate this mysterious reference count.

I have taken away from this a new appreciation of just how brittle threads are. Sure, they are powerful, but shooting yourself in the foot with a 50 cal hurts a lot more than with a 9 mm. I’ll have to be more careful.

It was also a good introduction to GProf and Valgrind. Expect blog posts on the usage of each of these tools soon!

DMP Photo Booth: Deep Magick

After working on DMP Photo Booth for a few months, the day came when I needed to implement actual functionality. It’s the day we all dread, but for me this was no longer some looming menace; it was time to stop fiddling around in my framework and actually build on it.

More specifically, it was time to figure out how to turn ~5 images and a background into a photo strip. After checking to make sure GLib and GTK didn’t provide this functionality (GdkPixbuf almost cuts it, but as far as I can tell, it can’t layer images over each other), I turned to google. After some time, I settled on my library: ImageMagick.

ImageMagick bills itself as sort of a command-line PhotoShop. I was suspicious as well, but that’s neither here nor there. The thing about ImageMagick that interested me is its language bindings. ImageMagick provides a library for many languages, including two for C: MagickCore for “Wizard-level developers” and MagickWand for us chumps. Being a chump, I decided to go with MagickWand.

NetBeans configuration

This was relatively straightforward. If you got GTK set up, this should be no problem for you. First, ensure you have the WagickWand development headers. On Ubuntu, this can be accomplished by the following command:

sudo apt-get install libmagickwand5 libmagickwand-dev

On my system, libmagickwand5 was already installed, so I downloaded the headers and got to work.

Next, in NetBeans click Tools->Options, click on the C/C++ tab, and click on Code Assistance. Add the location of the ImageMagick headers (/usr/include/ImageMagick for me). Click OK.

Next, we need to set up our project. Right click your project and click Properties. Click Build->C Compiler. Under Additional Options, add MagickWand to your pkg-config --cflags string. Click Build->Linker and do the same with your pkg-config --libs string.

You are now ready to conjure some magick!

Conjuring Some Magick

Now, let us put on our robes and wizard hats; it’s time to do some magick! Let’s go over a function that will overlay a resized image over a larger background. You can find the actual production photo strip function on Github.

void cast_magick_spell() { MagickWandGenesis(); ...

Before we can do anything, we must initialize MagickWand. “MagickWandGenesis()”, you ask? Of course the function would be called MagickWandGenesis, what kind of silly question is that?

... MagickWand * background_wand = NewMagickWand(); MagickWand * working_wand = NewMagickWand(); MagickWand * final_wand = NULL; ...

The MagickWand * is the main object passed around in a MagickWand application. Working with MagickWand requires some juggling of these pointers, which is why we have 3 of them.

... if (!MagickReadImage(background_wand, "/tmp/background.jpg") { ...

This function reads an image from a file. It returns MagickTrue on success, and MagickFalse on failure. If it returns MagickFalse, we have some clean-up to do…

... ExceptionType exception_error_code; char * exception_message = MagickGetException( background_wand, &exception_error_code); ...

MagickWand makes use of “Exceptions” throughout, so if a function fails, you can most likely pull an exception out of it using MagickGetException. Like any exception, it is up to you what to do with them. Since I’m using GLib, I’ve been wrapping them in a GError and propagating them up. This is actually very easy to do; your error code and message are already there. All you need to do is G_DEFINE_QUARK your error quark and throw it in there. For the purposes of this function, I’m just going to use printf, do some cleanup, and return.

... printf("Oh no! Exception %d: %s\n", exception_error_code, exception_message); MagickRelinquishMemory(exception_message); DestroyMagickWand(background_wand); DestroyMagickWand(working_wand); return; } ...

Nothing particularly shocking here. We printf our message, free the exception_message string using MagickRelinquishMemory, free our MagickWands using DestroyMagickWand, and return.

Assuming we make it past this block, background_wand now contains the background image. Next, we load the foreground image:

... if (!MagickReadImage(working_wand, "/tmp/foreground.jpg") { /* * Exception handling omitted * for brevity. You should still * do it here... */ } if (!MagickResizeImage(working_wand, [WIDTH], [HEIGHT], LanczosFilter, [BLUR])); { /* More error checking... */ } ...

After loading the foreground image, and doing our error checking we attempt to resize the image using MagickResizeImage. This function takes several parameters:

  • MagickWand * working_wand: The MagickWand to operate on
  • size_t [WIDTH]: the width to set the image to
  • size_t [HEIGHT]: the height to set the image to
  • FilterTypes LanczosFilter: the filter to use to resize. There are a list of them in the API documentation. Discussion of these is outside the scope of this post.
  • double [BLUR]: The blur factor to apply. 1.0 is no change. The further 1.0, the blurrier the resulting image.

Like many calls in this library, this function can return MagickTrue or MagickFalse. If it returns MagickFalse, something threw… Next, we adjust the position of the image…

... if (!MagickResetImagePage(working_wand, [RELATIVE_PAGE_SPECIFIER])) { /* * You'd think one of these wizards * could have written a function that * doesn't throw... */ } ...

This function takes some explaining. The second parameter: char * [RELATIVE_PAGE_SPECIFIER] is what’s doing the work here. This is a Magickally formatted string that looks like this: "100x100+15+15!". Let’s examine this as a printf formatting string:

"%dx%d+%d+%d!"

We have 4 integer tokens here. The first token is canvas width, and the second is the canvas height. Note that these will not resize the image, so don’t get any bright ideas about eliminating the previous resize call. The third and fourth tokens are offset from X and Y respectively. These are what we’re really concerned about here. This will allow us to position our foreground image over the background.

Also, don’t forget to check for exceptions!

... MagickSetLastIterator(background_wand); if (!MagickAddImage(background_wand, working_wand)) { /* exceptional! */ } ...

We’re almost there! Now we have to add the images from working_wand to background_wand. These MagickWand objects are lists of images. Like most lists, they have iterators. The call to MagickSetLastIterator sets background_wand’s iterator to the last image in the list. Any images add will be added after this image. next we call MagickAddImage which adds copies of working_wand’s images into background_wand. As before, don’t forget to check for exceptions.

... final_wand=MagickCoalesceImages(background_wand); if (!final_wand) { /* You guessed it! */ } MagickSetLastIterator(final_wand); ...

Now we need to combine all our images into one single image. This is accomplished by calling MagickCoalesceImages which returns a new MagickWand with all of our images combined into 1. The MagickWand used for this call remains unaffected. Obviously, if final_wand == NULL, something threw.

After this is done, we need to set the iterator of final_wand to the Last Iterator, or the next step doesn’t work as advertised…

... if (!MagickWriteImage(final_wand, "/tmp/final.jpg")) { /* wait for it! */ } ...

Shockingly, this function writes your new image to a file. Make sure you check your exceptions.

... DestroyMagickWand(background_wand); DestroyMagickWand(working_wand); DestroyMagickWand(final_wand); MagickWandTerminus(); }

…and were done! Clean up your pointers and call MagickWandTerminus to finalize the MagickWand library. If you browse to /tmp, you should have a newly created final.jpg if all was well!

Would I Do It Again?

Sure.

ImageMagick was a decently easy to work with library. The documentation wasn’t amazing, but it was tolerable. I’m still a little hazy on the use of the [RELATIVE_PAGE_SPECIFIER], but it’s working so far. One nice thing about the docs is that there are many examples. If the docs don’t explain something, you can look up an example and get an idea of how things work.

The only really big issue I have with this library is how it handles exceptions. This is an issue that I’ve touched on before; it is all too easy to forget to check a return code. I went down that road with DMP Photo Booth, and I’ve since rejected it. I spent an entire day refactoring my program to use GError.

MagickWand has exceptions, they’re just really easy to ignore. While writing this blog post, I caught several instances of unchecked return values in my 1 function that uses MagickWand. Tomorrow I plan to fix this, but it’s time I could be spending on something else.

If GError is Java’s checked exceptions with all it’s order and verbosity, then MagickWand’s exceptions are the Wild Wild West of C++’s unchecked exceptions. If you’ve spent any time working with C++, this has almost certainly bit you; some function doesn’t document if it throws, and your program magickally starts crashing because you didn’t catch something. Bad times are had by all. Sure, you could throw a try/catch block in main() and catch all exceptions to keep from crashing, but at that point your program is a dead man walking. Best to put it out of its misery…

Personally, if I ever write a personal project in C++ again, I’m likely to disable exceptions in my program; they’re just more effort than they’re worth. Maybe I’d even use GError in my C++ app if I could convince myself that I’m not a bad person for using a C library in C++.

Regardless, one blemish on an otherwise pleasant experience is no big deal. Here’s to a successful foray into the land of High Adventure!

DMP Photo Booth: an Experimental GHashTable Transplant

DMP Photo Booth has had a problem; it has been battered by the club of poor design choices. Deep in the bowels of user_interface.c, there was a terrible cancer. There was a struct called dmp_pb_ui_cb_user_data that started life as an innocent little struct to be passed into GTK callbacks. Since the same pointer must be used for all callbacks to pass user data around, this was my solution. The only problem? Scalability.

At first, there was one member to worry about. One member to initialize, one member to free. Then there were 2. Then 4. Then 8. Things began to take a turn for the worse as my user data registration function ballooned to over 300 lines. Dozens of members to track, to new and destroy. Fearing that my poor user_interface.c file would end up on The Daily WTF I prepared for surgery. The cancer must go.

Easier said than done, right? It turns out, not so much.

GHashTable to the Rescue

Once again, GLib has the answer. After some thought, GLib’s Hash Table implementation offers the solution.

A hash table is a collection that associates a key with a value. You can pass in an integer, a string, or any other arbitrary type as a key, and get its associated value. In my case, I have ready-made keys: the Glade widget name. I can use these names as keys and associate them with their respective components as they are pulled out of the GtkBuilder. The filled hash can then be passed in as the user data pointer to gtk callbacks.

Let’s go over some of the details that make this is a good choice for DMP Photo Booth:

g_hash_table_new_full

This is, of course, the GHashTable constructor. Let’s examine an example, straight out of the new implementation:

dmp_pb_user_data = g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, (GDestroyNotify) gtk_widget_destroy );

This constructor takes 4 arguments: a hashing function, an equality function, a key destruction function, and a value destruction function. The hashing function is probably the most important of these. Hash tables generate a hash based on the key to find the value, this function implements the hash on a given type. GLib provides 3 ready-made hashing functions, g_str_hash (for char arrays), g_int_hash (for integers), and g_direct_hash (for void pointers). You can implement your own if you like, just make sure it’s fast. This function is called on all lookups, a slow hash function will destroy your program’s performance.

Next is the equality function. This function is used to test keys for equality.

Finally, we have the key and value destruction functions. These functions are responsible for ensuring memory is cleaned up. These functions will be called on destruction of the GHashTable, ensuring all memory is cleaned up properly. This is the reason we are using g_hash_table_new_full, and not g_hash_table_new. Without these functions, you have to manually empty the hash table and free all values if you want to avoid a memory leak.

g_hash_table_lookup

Next, is our lookup function. This function takes a pointer to a GHashTable, and a key. A pointer to the key’s value is returned, or NULL if the key does not exist. Pretty straight forward.

The Prognosis

Favorable. The new GHashTable is humming along, and dmp_pb_ui_register_user_data has shed hundred of lines. With a little diet and excercise, the patient should make a full recovery.

DMP Photo Booth: First Commit

Well, it’s been a long time coming, but this weekend 45 days of work has culminated in my first milestone: DMP Photo Booth has received its first commit. If you go to this page, you’ll find the newly created Github repository for it. Feel free to go judge all the choices I made, I’ll wait…

…done? Good, now I’d like to use this post to talk about it.

The Story So Far

dmp_photo_booth_screenshot

So far, most of the work is done in the core. There are module stubs for each module, and they are loadable and “function”, but they don’t do much of anything. However, the UI for the core is, for the most part, done. If you build the core (Either open the projects in NetBeans or cd into its directory and enter make build), and run it (as of this writing, it must be run from the project root directory, since the supporting files are located here and referenced by relative paths) it will launch. At this point, you can launch the about window, the config window, or exit the program. From the config window you can load your modules (built stub modules are included for your convenience), and the status indicators on the main window will detect it.

All this is fine and good, but the real story here is the plumbing that has been laid.

Said Plumbing

Not much works at the moment, but the groundwork has been laid for things to come. Going down the list:

Global Defines

In this header, you’ll find all the magic integer constant return values used throughout DMP Photo Booth and friends. I touched on this topic briefly in a previous post, but the cliff’s notes version is that I feel that using a bare integer instead of an enum reduces the burden on module developers, and that the benefits of an enum aren’t great enough to justify this burden.

As this header has no accompanying .c file, it can be #included by module developers so they can make use of it if they like. I do this in my modules.

Module

One of the first things I worked on was module handling. This header holds all the functions required for the loading and unloading of modules, and the calling of module functions. At first I was implementing all of this with POSIX calls, but it occurred to me that I was defeating the purpose of my modular architecture by using non-portable calls. For this reason, I switched to GModule for module handling. I wrote a post about this if you want to hear more.

Module Callbacks

This header contains functions that will be added to modules as callbacks. Currently, this is the function that will be called when the user presses “the button”, and the function that will be called to push a message to the console queue.

Error Handling

My general approach to function design is that functions should not return void. All functions that would, instead return gint. This way, I have a mechanism to detect error conditions. In a language without Exception Handling, this is a nice thing to have. This header contains functions to extend this. Since sometimes you can’t return gint, I’ve created a facility to log error codes, similar to how the POSIX errno function works.

Console Queue

This header contains a thread safe queue to store messages to print to the console. Currently, this is implemented with a GQueue and mutex locking, but I made that choice before I knew about GAsyncQueue. I may refactor this at some point to use GAsyncQueue, but for now it works fine, and I see no immediate issue with my implementation.

The idea behind the console queue is that there should be a generic way to store messages. Currently the console is a GtkTextBuffer, but if I build around this, it limits future functionality. Suppose I wanted to support a command line only option? It’d be silly to require GTK for that, wouldn’t it?

That said, the default implementation uses a function placed in the GtkMainLoop to pop all messages out of the queue and place them into the GtkTextBuffer.

Module Status Watchdog

This header file is in charge of keeping those fancy module status indicators up to date. There are two main moving parts here: a thread that polls the module status, and a function run by the GtkMainLoop.

The Thread polls the modules every 3 seconds and pushes any status changes to a GAsyncQueue. Meanwhile the GtkMainLoop checks the GAsyncQueue for updates, and sets the indicator status accordingly. Why doesn’t the GtkMainLoop just check the module status you ask? I wanted to make sure the GtkMainLoop does as little work as possible. Currently the calls to check module status are pretty trivial, but there is no guarantee that they will stay that way. Since nobody likes an unresponsive interface, I kept them separate.

User Interface

This rather hefty header contains two things: a function to build and launch the UI, and all the callbacks called by said UI. All the callbacks are named according to their glade widget name to maintain some semblance of readability.

The Next Step

Obviously, looking through the User Interface source, there are signals to be hooked up. But aside from that, the core is coming along. The one big portion of the core remaining to be done is the photo booth strip logic. The camera module will take X pictures and download them. At this point it is up to the core to assemble them into on image file to be printed.

For now, I will continue to hook up signals and refine the existing portions of the core. While I do this, I will research image handling libraries. I’d like to keep things within the GLib family, but failing this, I will try to keep it limited to libraries shipped with Ubuntu (The default platform). Windows compatibility will come, but version 1.0 will work on Ubuntu.

Also looming on the horizon are the modules. I have a general idea of how I will deal with these, but nothing is set in stone. The first module that I will likely handle is the trigger module. I plan to implement the trigger module using Arduino. This is a topic that interest me, but I’ve never had a good project idea. Whenever I get tired of dealing with GTK, it should be a nice change of pace.

Introducing DMP Photo Booth

In June of 2014, I will be getting married. One problem: I am currently an unemployed student, and my fiancee Liz is also between jobs. Recent studies show that the average couple in this day and age spends an average of Twenty Four Bajillion Dollars on their wedding. Capital Bajillion. Italicised. Even were I still employed, this would pose a problem for me. Needless to say, we began looking for costs to cut. Liz really wants a photo booth, and I think it sounds fun. Unfortunatley photo booths run from $750-1000 to rent. The solution: DMP Photo Booth.

On Reinventing The Wheel

DMP Photo Booth wasn’t actually my first thought. That would be “well, there must be some open-source photo booth software we can use!” It turns out that there is. People like me who’ve had this issue and whipped something up for themselves. Some of these projects even have fancy websites. Unfortunately, none of these seem to have reached the level of maturity where you can just grab them and go. No, we’re talking old-school Linux status projects. If I’m going to have to put that much effort into making this work, I might as well roll my own. Besides, it will be good experience.

Requirements

The photo booth must do the usual photo booth stuff; it should programatically take 3-4 pictures, arrange them in a vertical strip with a background picture, and print them on photo paper. This should all work with the user only having to press a button(not a key on the laptop, an actual button), and there should be some sort of indicator when the pictures are going to be taken.

Some reasearch turns up the existence of a Picture Transfer Protocol, or PTP, that has been “supported” by the major camera vendors since 2002 or so. PTP allows you to programatically control a digital camera, and should serve nicely. I own a printer that can print on photo paper; it seems likely that I will be able to use the operating system’s printing facilities to handle this. Finally, I will construct a button and indicator thingamabober using Arduino.

Architecture

I have decided to go with a modular architecture. There will be four components: a Camera Module, a Printer Module, a Trigger Module, and the Core Application.

Core

The Core Application will bring the GUI, tenatively planned to be implemented using GTK+3, and will interface with the component modules. The core expects the component modules to implement specific functions that will be called to handle their operation. The component modules will be dynamic libraries that can be swapped out at runtime.

Camera Module

The Camera Module will handle the operation of the camera. The Camera Module currently is expected to implement two functions:

int dmp_cm_capture(); int dmp_cm_download(char * location);

These two functions do what they say: the first takes a picture, and the second downloads the picture to the passed-in path. The reference Camera Module will use libgphoto2 to implement these functions, but this module exists to provide the capability to use any method. A module that uses some other PTP library, or some custom protocol, or a dummy module that uses a picture on the filesystem, or uses a scanner, or anything else can be swapped in at runtime and this will all be transparent to the Core.

Printer Module

Shockingly, the Printer Module will handle printing. The Printer Module is currently expected to implement one function:

int dmp_pm_print(char * to_print);

This function prints the file at the path that is passed into the function. This module prevents the Core from needing to know how to print. The Core tells the Printer Module to print, and the Printer Module can figure out how to print in Linux, or Mac OSX, or how to print to a Game Boy Printer, or whatever. The Core doesn’t care.

Trigger Module

The Trigger Module is the module that knows how to operate the custom photo booth equipment. The Trigger Module currently is expected to implement two functions:

int dmp_tm_add_trigger_handler(void (*th)()); int dmp_tm_set_countdown(int current);

The first function adds a callback function that will be called by the Trigger Module when it detects that the button has been pressed. The second function updates the countdown indicator. Since some dealybopper that I made out of Arduino is basically the definition of non-portable, I decided to create a module for it. The reference implementation will be written for my equipment, but this module can be replaced with one that uses some other input device with minimal effort.

Moving Forward

DMP Photo Booth represents my first major open source project, and it has many moving parts. With this groundwork laid, I have broken the project down into more manageable chunks. I have four main components that each represent different challenges: GUI programming in the Core, poorly documented mystery libraries in the Camera Module, Learning to Arduino to finish the Trigger Module, and learning the Linux printing system for the Printer Module.

Rome wasn’t built in a day, but it was started in one. There will surely be many challenges and roadblocks on the way. Expect to hear all about them here!

%d bloggers like this: