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.
trivial-freeimage
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)
(de-initialize)
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)
(de-initialize)
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.
CLORB: CORBA for Lisp
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*
(CORBA:ORB_init
(list "-ORBInitRef" "NameService=corbaloc::10.85.90.144:2809/NameService")))
(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"
utput "syph.lisp")
Then in CLISP on my Windows box I replaced
(corba:idl "syph.idl")
with
(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!