Introduction


Calibre is handy for organising eBooks.
Stanza is really handy for reading eBooks on the iPad.
Calibre can act as an eBook server.
Stanza is capable of using this functionality to transfer books from your PC to your iPad.
Hooray, all my book-reading requirements are fulfilled!

*sigh*, of course not.

Stanza had a lot going for it: it was free; it could decode numerous eBook formats; it could download books from Calibre.
Sadly, it now has some issue: it is no longer available; with newer versions of iOS it has a bug where you can't navigate away from resized pages (well, you can, but it's a pain in the gluteus maximus).

As I personally only read books at home (not on holiday) I also found it a waste to have the eBook stored on my device, not only because of the space usage, but the Calibre-connection was really intermittent and unreliable and I'd rather count dust-bunnies on the floor than use iTunes to sync data.

The Stupid Idea


It is thus that I came up with another almost-patented stupid idea:
Make a remote Calibre eBook viewer, almost like a Calibre-VNC.
Make a tiny web-server that reads the Calibre database and feeds book information using JSON, and use a tiny WebApp that requests pages as images.
All processing happens on the server, so PDF pages are rendered to an image of the desired size and fed up as high-quality JPEG/PNG images to the WebApp.

This means that I no longer need to download books to my device, nor do I need to rely on the viewing application to cater for the format I want, as I can simply implement it on the server.
In theory, it means you could also read all your books from anywhere in the world via the internet, even if you forgot to sync it with your device.

The Prototype


As always, when I want to prototype something quickly, I turned to FreePascal/Lazarus.
Lazarus had everything I needed to test the idea:
  • a web-server class to server the JSON and images
  • a zlib class to open a test CBZ comic book
  • image classes to quickly load and resize JPEG images

Next I made a very hacky jQuery powered WebApp page thing to list books and navigate through a chosen book.
The web request "API" was very simple, you could ask how many pages a book had (/info/?id=10) or ask for a page from a book (/view/?id=10&page=13).
Next I made sure that the /view/ "command" supplied the dimensions of the current viewport so that became the native 1:1 "scale" for pages from the book.
The idea was that you could then zoom the 1:1 image locally in JavaScript, perhaps pan it around a bit, and then make another request to the server with a zoom factor, to clear the image up a bit.

I was set, it was all working pretty sweetly, so I went ahead and used libmupdf to test processing of PDF files, and... awesome.
It still has a minor issue where drawing the image to an HTML5 canvas results in it being blurry (despite setting the CSS dimensions to match, despite setting some custom moz and webkit filters), but -hey-, good enough for now.

The Proper Version


So, now it comes to making the "proper" version for people of the world to use, and I'm stuck.
I could make it in Python, but then people would have to install Python to get it to work... perhaps a non-issue?
I could make it in Mono just for my own fun, but again, it's another framework people need to install.
I could simply clean up the Lazarus version I guess, but there are a few niggly weird bits that I'd have to work around, and the resulting executable would be quite large.
I could make a plugin for Calibre, maybe?
I could make a plugin for Sumatra, maybe?
I'm tempted to do a very tiny version in C/C++ using the Mongoose web server library (Lua webpages? Woohoo!), JPEG compressor library and libmupdf... buuut that kind of thing always takes quite long to do properly.

This is all assuming that people would want to use this kind of thing and that I need to take it beyond the prototype...
But coding is fuuuun... can't... stop... self...


permalink print article