« Betsy Markum and the 5 digit spammers | Main | Air Force One Revealed »

April 9, 2006

Textorizer

Max Froumentin wrote a cool application called SVG Textorizer. It searches for the edges of elements in a photograph and rendors them as text. Paul Downey wrote a PHP extension with a web interface that allows you to run SVG Textorizer, without having to download and comile the source code yourself.

There's a second variation called Textorizer II. Textorizer renders a photograph using text, but only renders the edges of elements in the picture. Textorizer II basically renders the entire image, not just the edges.

For Textorizer, you have to compile the source code and Max's directions appear to use GCC (GNU Compiler Collection) to create a linux executable, if I'm not mistaken.

Download: textorizer.c . Compiling requires the libpng 1 library. To compile, type:

gcc -o textorize textorizer.c -lm -lpng

Instructions: type textorizer -h and follow the instructions.

New: a makefile and linux executables are available:

* dynamically linked (20K, MD5 sum )
* statically linked (614K, MD5 sum )

So, I'm not really sure how to get this to run under windows.

There's apparently a product out there called MinGW(Minimalist GNU for Windows). So, possibly this would work, but I'm not clear if it's designed to run under Unix or Windows. The extracts are all .tar files, which is concerning. Apparently, these will work with WInZip, but you have to uncheck the "TAR file smart CR/LF conversion" under WinZip - Options - Configuration.

MinGW would probably work, but before I got too far with it, I found this post on Flickr, and they seem to think that I should use cygwin. I tried installed cygwin. It wanted to know what packages I wanted to install, and it gave me a list of about a zillion, so I just clicked Next for a base installation. It said it installed successfully.

So, I launch it with Start - Programs - Cygwin - Cygwin Bash Shell. But, when I type GCC in the shell, it says:

bash: gcc: command not found

So, I realized that it didn't install GCC. So, I've got to try again. I re-ran the installation, and this time, when it prompted me for the packages to install, I clicked on View until it said "Full", and searched for GCC. I selected the binaries for the GCC Core C compiler in the Devel category.

Then, I launched Cigwin again, and now when I type GCC in the shell, it says:

gcc: no input files

So, this looks like the GCC was installed at least. So, I push on with their suggest command:

gcc -o textorize textorizer.c -lm -lpng

But this gives me a slew of png errors, so I'm sure I don't have the PNG lib that they warned I'd need. So, I got to
http://www.libpng.org/pub/png/libpng.html
. I'm not clear which version to grab, so I get binaries for version 1.2.8 for GnuWin32. Then, from the list, I picked the libpng-1.2.8.exe and downloaded and executed it. It said it would install LibPng to C:\Program Files\GnuWin32. I was like. Sure. OK. Then, it said it was complete.

I'm still getting the same PNG errors though when I run the command "gcc -o textorize textorizer.c -lm -lpng". It appears to be missing the png.h file. But, I search and it finds it. So, apparently it's not in the right place. All of the cygwin .h files are in the folder c:\cygwin\usr\include. So, I probably need to reinstall it or copy the files manually or something. I tried reinstalling to a different location. No dice. So, I'll just try copying in the the files as needed. So, I copied png.h file into the c:\cygwin\usr\include folder.

gcc -o textorize textorizer.c -lm -lpng

/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: cannot find -lpng
collect2: ld returned 1 exit status

Now, I'm getting a different message, so I'm getting closer. So, then I copied all the files from the PNG lib to the cygwin lib folder, and now it seems to be working. :)

So, I copied in the textorizer2.c program, and ran the following command:

gcc -o textorizer2 textorizer2.c -lm -lpng

Miracuously, it appears to have created a textorize.exe file. I tried to run it in the Bash shell using ./textorizer2.exe. It kept me some error messages until I got the following .dll files in the same directory:

cygwin1.dll
libpng13.dll
zlib1.dll

Now, Max Froumentin's Textorizer II seems to be working.

Update: Doh! It wasn't working. At least, it wasn't working right. I could get it to run without any parameters supplied, and it would spit out all the default help text info, but that's all it would do. When I started trying to pass it any parameters, it just hung. So then, I went back and tried to recompile textorizer, I got the same results. Compiling does produce a .exe file, and I can execute it through the Bash shell using ./textorizer.exe, for instance, but then it just hangs when it is supplied any valid parameters. So, I went and copied down this precompiled textorizer.exe program from Paul's Flickr post, and this executable works fine. So, obviously, there's something wrong with what I'm doing in my compile. My textorizer.exe file is noticably smaller than his, I'm not using his Makefile.

When I type Make in the Bash shell, I get: "bash: make: command not found". So now I think that I haven't installed "Make".

I typed "which make" and it says "make command not found". I typed "echo $PATH"(note: echo $path doesn't work - watch case here) and it showed me the path, but I can't find "make" anywhere on my system.

http://www.cygwin.com/ml/cygwin/2003-08/msg00715.html

You're missing the "make" package. In the future, if you'd like to find
out which package contains a particular command, use the package search
page at and search for, in this example,
"bin/make(.exe| )".

So, I run c:\cygwin\setup.exe (again) hit "Next" until I get to the Select Packages section, click on View until it says "Full", and then look for a package called "Make: The GNU version of the make utility." in the category of Devel. I selected the binaries for version 3.80-1. Then, click Next and it installs. Hopefully, I'll have a Make utility after the install completes. Then, I should be able to use Paul's Makefile to make my executable. I'm guessing he statically linked in some things, which made his executable larger. The install said it completed successfully.

Now, I type "which make" in the bash shell at it says "/usr/bin/make". This is extremely confusing to me in that, the slashes are going the wrong way, and when I go to /usr/bin, I see the file named "make". However, I don't see a c:\usr\bin\make. So, this is confusing to me. OK. Now, I see what the deal is. The "root" directory is the folder you installed Cygwin into. In my case, c:\cygwin. So, in the Bash shell, "/home/Rob" is really "c:\cygwin\home\rob". Got it.

Now, I type "Make", and it spits out the following error message(s):

$ make
gcc -static -I/usr/src/libpng-1.2.8 -o textorizer textorizer.c -L/usr/src/libpng
-1.2.8 -lpng -lz -lcygwin
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../libpng.a(pngrutil.o):pngrutil.c:(.tex
t+0x125a): undefined reference to `__imp___iob'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../libpng.a(pngrutil.o):pngrutil.c:(.tex
t+0x1c4f): undefined reference to `__imp___iob'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../libpng.a(pngrutil.o):pngrutil.c:(.tex
t+0x1c92): undefined reference to `__imp___iob'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../libpng.a(pngrutil.o):pngrutil.c:(.tex
t+0x2047): undefined reference to `__imp___iob'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../libpng.a(pngerror.o):pngerror.c:(.tex
t+0x242): undefined reference to `__imp___iob'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../libpng.a(pngerror.o):pngerror.c:(.tex
t+0x2ed): more undefined references to `__imp___iob' follow
collect2: ld returned 1 exit status
make: *** [textorizer] Error 1

My guess is that it can't find this folder "LIBPNG=/usr/src/libpng-1.2.8", because it doesn't exist. And, the Makefile is definitely looking for it.

So, I reinstalled libpng-1.2.8 (again). I ran c:\cygwin\libpng\libpng-1.2.8.exe to run the install again, and pointed it to install to "c:\cygwin\usr\src\libpng-1.2.8", which will equate to "/usr/src/libpng-1.2.8" in the Bash shell. It ran and installed and I see it there now. So, we'll try running the Make again, but I get the same error messages. Seems to be related to PNG somehow (surprise). Message says "undefined reference to `__imp___iob'".

So, maybe there is a problem because I didn't install Cygwin's Perl, or possibly a problem with the systemC Parser?

I typed "which gcc", and it says "/usr/bin/gcc". So, not sure what that means.


The PHP Extension "Wrapper"

But, Paul Downey wrote a wrapper named Texturize around Max's earlier Texturizer program. There is currently no similar wrapper written around Texturizer II. So, I'd like to try to update Paul's wrapper to work with Texturizer II.

So, I created a new folder and copied down all of Paul's code I could find:
* textorize.php
* textorize.c
* php_textorize.h
* config.m4

So, apparently I need to compile the program textorize.c. Somehow, he managed to make it into a file named textorize.so. Not 100% sure how that happens.

This post indicates what I was afraid of. The .so is basically a Dynamic Linked Library in Unix. So, a .so in Unix is loosely equivalent to a .dll in Windows. And one of the things Cygwin isn't so stellar at is dealing with the dynamic linked libraries. Go figure.

To create a .so file, it looks like I need to run some commands somewhat similar to this:

#create .o file
g++ -c -w -I$(JAVA_INCLUDE) -I$(JAVA_INCLUDE_SOLARIS) -o Hello.o Hello.C

#create .so file
gcc -o libHello.so -shared Hello.o -lgcc

So, I copied the php_texturize.h into the c:\cygwin\usr\include folder and launch the Cygwin Bash shell (Start - Programs - Cygwin - Cygwin BashShell and try the following command:

g++ -c -w -o textorize.o textorize.c

It doesn't like the g++ command.

bash: g++: command not found

So, I try it again, only using gcc instead of g++. Now, it's spitting out a bunch of errors about files it can't find:

textorize.c:23:17: php.h: No such file or directory
textorize.c:24:21: php_ini.h: No such file or directory
textorize.c:25:31: ext/standard/info.h: No such file or directory
textorize.c:26:40: ext/standard/php_smart_str.h: No such file or directory


From reading some posts, I'm begining to believe I have to complie Cygwin for Apache. Or maybe compile Cygwin for PHP. Not 100% sure. I already have Apache and PHP working on my box, so I'm not sure exactly how this Cygwin fits in. Maybe I just need to tell Cygwin when I compile the PHP extension to use the windows DLL's for PHP.


Hmmm. I'm noticing now the config.m4 file Paul has provided. This describes the function of the config.m4 file in some detail.

OK. According to Wikipedia, the .h files are header files for C programs. Aha. I looked at the php_textorize.h file, and it does appear to have some logic in there that checks to see if it's running under windows.


One of the files I could never find was php_smart_str.h. But, I finally found a copy of it here. No clue what it is. So, I saved it into C:\cygwin\usr\include\php_smart_str.h.

I modified the textorize.c program as follows:

/* #include "ext/standard/php_smart_str.h" */
#include "c:\cygwin\usr\include\php_smart_str.h" /* rak 04/10/06 */

And I'm getting different error messages now. So, it's finding the php_smart_str.h C header, for what it's worth.
But, try as I might, I just can't find php.h or php_ini.h. So, I'm not sure what the deal is here. Maybe these files are for unix only and since I installed, Cygwin, I can't get them. Maybe I need to get something else like phpdev.

Posted by Peenie Wallie on April 9, 2006 at 4:31 PM