January 30, 2007

I recently ventured into the Lisp community with a trivial wrapping of a library called FreeImage. I used CFFI for this and was quite pleased– well, except for one thing. That thing would be that I had to specially build the library to not use stdcall. CFFI does not support stdcall, yet (if ever). I generally prefer being able to build libraries without changing the source for a single language. So, I could just post instructions on what is needed to be done to the FreeImage sourcecode and let the user still get the source from the FreeImage web-site or I could always do a build and post it with trivial-freeimage. I have even thought about asking the developers of FreeImage if they would except a patch that would allow a user to use a define of LISP or some such thing to build especially for cffi. I would rather do none of the above. I suppose I will need to create a backend for each Lisp I wish to support– using their respective ffi– and then maybe have a front-end that hides it all away from the end-user of trivial-freeimage. That is rather disappointing as I very much like cffi. I wish cffi had support for stdcall and cdecl like ctypes in python (just found that out today from a co-worker who thought my situation was amusing and wanted to show off ctypes).

The cffi developers are looking into adding support for stdcall. I have offered to help in anyway that I can. I am looking at the source of cffi to try and grok it. I did not mean to come across as one of words and not action. I also did not mean to come across as not appreciating cffi as I do appreciate it very much. CFFI does not have a donate paypal option but if they will institute one I will donate to help out since it will be unlikely I will be up to speed on the source before they finish adding stdcall.

Portable Graphical Widgets

January 20, 2007

Recently, I was advocating using Lisp at work for some utility apps when a co-worker claimed that we should use Java because we needed true cross-platform capabilities. We went back and forth on this for several minutes and I could tell he thought he had me when he brought up that they would need to have GUI’s. We have to have the ability to run our apps on Windows as well as Linux. So, enter wxcl. I think I may be on the way to converting another Java guy…..

update for trivial-freeimage

January 17, 2007

I finished making trivial-freeimage loadable with asdf. I also wrote a macro called with-dib (much thanks to zach for suggesting this).

(asdf:oos 'asdf:load-op :trivial-freeimage)
(use-package :trivial-freeimage)

(with-dib (dib "24.tif")
   (list (get-height dib)
         (get-width dib)))

with-dib will load an image for you and unloads it as well. It uses unwind-protect to ensure the unloading of the image in case of error.


January 14, 2007

It’s been a slow start to the new year; but, here is a new package called trivial-freeimage. It wraps most of the FreeImage Library. I got this to work on Windows with CFFI 0.9.2 by building the FreeImage dll without stdcall linking. It was a simple edit to the header file. Anyway, here is a simple example that has functions to find the top and bottom of an image of text from a tiff-g4 scanned page:

(require 'asdf)
(require 'cffi)
(load "trivial-freeimage.lisp")
(in-package :trivial-freeimage)

(initialize 0)
;load a tiff-g4 image and get it's height and width
;width is divided by 8 due to 1 pixel per bit in tiff-g4 format

(defvar dib (load-image tiff "24.tif" 0))
(defvar height (get-height dib))
(defvar width (/ (get-width dib) 8))

;as soon as we find a black pixel notify
(defun row-has-black? (row)
	(loop for i from 0 upto (- width 1) do
		(if (> (mem-aref row :uchar i) 0)
			(return t))))

;find the top of the frame of text
(defun find-top (dib) 			
	(loop for row from (- height 1) downto 0 do
		(if (row-has-black? (get-scan-line dib row))
			(return (- height row)))))

;find the bottom of the frame
(defun find-bottom (dib) 			
	(loop for row from 0 upto height do
		(if (row-has-black? (get-scan-line dib row))
			(return (- height row)))))

;always unload your dib's or you will never free the memory
(unload-image dib)

Also, note that FreeImage stores DIB’s with the origin being in the bottom left.

One other example– to convert a tiff file to png:

(in-package :trivial-freeimage)
(initialize 0)
(defvar dib (load-image tiff "image.tif" 0))
(save-image png dib "image.png" 0)
(unload-image dib)
(unload-image dib2)

I will be posting more examples while I work on the documentation of how to use the wrapping. Also, I will continue to add more of FreeImage’s API to the wrapping. I plan on adding a higher package for image editing that will make use of trivial-freeimage.

Just another update

January 4, 2007

I have had a few people ask for links, so here they are:


Just an update

January 3, 2007

Today I am working on making a wrapper for freeimage that is nicer than just the trivial cffi wrapping I had already done for it. I am also looking at doing the same for opencv. Although, I guess I could release them as trivials– not sure what the preference in the community is in regards to this. If anyone has an opinion on whether a trivial release would be useful for others to build their own packages on or not please drop a comment.