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 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.


December 31, 2006

Well, I thought about it for awhile and decided I would post something about CLORB in particular. Where I work we use CORBA as the transport for our grids. I have always wanted to be able to use Lisp as a client– yay! CLORB. Now, I know there are other CORBA implementations for Lisp– but this one is free. That last word there– free– is very, very important when you are trying to establish a foothold for Lisp in the corporate IT world. I use SBCL on Linux and CLISP on Windows because they are free. That means I don’t have to go through the entire process of requesting funds for LispWorks or ACL. Which, also means, I don’t have to justify an expense for something no one else in the company for which I work is using. So, now that I have free Lisp tools and CLORB I can interoperate with all of the other services that have been developed in other languages at the company I work. The interesting thing about this use of free tools is that once I have a few projects/services in place using Lisp I can justify actually buying LispWorks or ACL if needed. Now back to CLORB– I was very happy at how easy it was to get a client up and talking to a python service. I am using OmniNames as my nameservice. The following snippet will enable the connection and use of a corba service– in this case the python corba service provides a single method called getsyphs.

(require :asdf)
(require :sb-bsd-sockets)
(require :clorb)

(defvar *orb*
         (list "-ORBInitRef" "NameService=corbaloc::")))

(corba:idl "syph.idl")

(defvar *obj*
        (op:resolve_initial_references *orb* "NameService"))

(defvar *rc*
        (op:narrow 'cosnaming:namingcontextext *obj*))

(defvar syph
        (op:resolve "BCS.syph/BCSSyph.Object"))

(defvar rt
        (op:narrow 'BCS:Syph syph))

(op:getsyphs rt "014600AIR CANADA")

The only downside I have experienced with CLORB is that it depends on cpp to preprocess idl. This is a small problem if you are on Windows and don’t have a cpp. I got around it by having CLORB generate all of the Lisp code to a single file for the idl on Linux.

(CORBA:IDL "syph.idl" :output "syph.lisp")

Then in CLISP on my Windows box I replaced

(corba:idl "syph.idl")


(load "syph.lisp")

and all was happy.

good-bye 2006

December 31, 2006

Well, another year is coming to a close. This has been a good year for me in terms of programming Lisp professionally. I became a Team Leader for a group of developers and we were charged with developing a new ocr system. We used several languages– right tool for the job mentality. My boss was so pleased with what we accomplished and the time-frame in which it took that I have now been given the task to design and replace a large legacy system. All of this success has been because I do not believe in one language for every task. I firmly believe in the right tool for the job. I also believe in rapid-prototyping. Following these beliefs has put me in the position that I can use Lisp in an enterprise I.T. setting. What have I been using Lisp for? I can’t give too many details at this point– but I can tell what packages I have been using or have created. I have wrapped FreeImage and OpenCV in the last month– I’ll be releasing them in the next month. I have also recently started looking at CLORB. I have gotten CLORB clients talking to omniORB python servents. I am also using wxcl. Right now I am working on a Name Utility that will list CORBA bindings in a wxcl gui. I will post the code on this site in about a week. Have a Happy New Year!