Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2003-07

How to use Linux libraries?

16 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Rainer Hantsch

Hello!

Because I always wrote pascal programs which required no external code, I never had to deal with this and have absolutely no knowledge about how to do such things.
Please, be so kind and help me understanding how I can use external Linux libraries.

What I basically want to do is: Reading images into memory.

Because there are so many different jpg/tif formats, I gave up writing all this code by myself and I would like to use one of the already existing libraries instead.
The program shall simply read in a image file and store it in memory for further processing, then write it out to a file again. WITHOUT ANY GUI.

Please, if somebody of you already has some code which shows me how to do that, how to embed a library, how to call the library functions, etc., leave me some code. It is much easier to understand than reading some highly academic descriptions.

mfg

Ing. Rainer Hantsch

Marco van de Voort
to Rainer Hantsch
Show quoted text 10 lines
never had to deal with this and have absolutely no knowledge about how to do such things. Please, be so kind and help me understanding how I can use external Linux libraries. What I basically want to do is: Reading images into memory. Because there are so many different jpg/tif formats, I gave up writing all this code by myself and I would like to use one of the already existing libraries instead.

A Pascal translation of the jpg library is already included with FPC.

For libraries in general, you have to translate the C header file. This can be done to a certain account by the tool h2pas packaged with FPC, but requires manual intervention afterwards.

Then add

{$linklib <library name>} to your header file unit, and make sure the
<library name>.a file can be found by the compiler (-Fl) options.

There should be quite some info about this in the manual.

Please, if somebody of you already has some code which shows me how to do that, how to embed a library, how to call the library functions, etc., leave me some code. It is much easier to understand than reading some highly

Also don't forget that there are a lot of examples already in the FPC sources. Half of the packages/ hierarchy interfaces to some C library.

Rainer Hantsch
to Marco van de Voort

On Thu, 24 Jul 2003, Marco van de Voort wrote:
| A Pascal translation of the jpg library is already included with FPC.

I am afraid that this is implemented in Delphi Style?

I am one of those old guys who still program in OOP style, so this will possibly become somehow difficult ...

Is there something where you can point me to? Reading a lot of sources is relatively heavy. If you say that jpeg is already impleented - where exactly?

mfg

Ing. Rainer Hantsch

.---------------------------------------------------------------------. | \\|// Ing. Rainer HANTSCH - Hardware + Software | | (o o) Forget Windoze! -- We focus on L-I-N-U-X... | |--oOOo-(_)-oOOo------------------------------------------------------| | Ing. Rainer HANTSCH | mail: | | Khunngasse 21/20 | www: http://www.hantsch.co.at | | A-1030 Vienna | tel: +43-1-79885380 fax: +43-1-798853818 | | ** A u s t r i a ** | handy: +43-664-9194382 UID-Nr: ATU 11134002 | '---------------------------------------------------------------------'
Marco van de Voort
to Rainer Hantsch
| A Pascal translation of the jpg library is already included with FPC. I am afraid that this is implemented in Delphi Style?

I don't expect so. It is a straight C translation, which is not OOP by nature.

The idea was to build classes on top of that.

Show quoted text 6 lines
I am one of those old guys who still program in OOP style, so this will possibly become somehow difficult ... Is there something where you can point me to? Reading a lot of sources is relatively heavy. If you say that jpeg is already impleented - where exactly?

I'm sorry, it is not in FPC, at least I can't find it, I was probably confused with a sister package (paszlib ) which was absorbed into FPC.

Howrever the site is still up:

http://www.nomssi.de/pasjpeg/pasjpeg.html

Michael Van Canneyt
to Rainer Hantsch: | A Pascal translation of the jpg library is already included with FPC. I am afraid that…
Rainer Hantsch wrote 10 lines
On Thu, 24 Jul 2003, Marco van de Voort wrote: | A Pascal translation of the jpg library is already included with FPC. I am afraid that this is implemented in Delphi Style? I am one of those old guys who still program in OOP style, so this will possibly become somehow difficult ... Is there something where you can point me to? Reading a lot of sources is relatively heavy. If you say that jpeg is already impleented - where exactly?

The pasjpeg unit. It is old style.

Michael.

Rainer Hantsch
to Marco van de Voort: I don't expect so. It is a straight C translation, which is not OOP by nature. The idea…

Hi, Marco!

On Thu, 24 Jul 2003, Marco van de Voort wrote:
| Howrever the site is still up:
|
| http://www.nomssi.de/pasjpeg/pasjpeg.html

I know this site, and I know 'pasjpeg' from its name. I tried multiple times to get it working, but I always had the same problems, it does not compile. In the silent hope that this "toolbox" may have changed in the last year, I downloaded version 1.1 today.

Well, the author still has some "problems" with upper/lowercase in his ZIP's (everything extract as uppercase, but he references the files in lowercase inside his code), a typical identification that the files were created in a DOS environment. So I am not surprised that the code is primarily for WINDOWS and does not compile on Linux. :-/

mfg

Ing. Rainer Hantsch

Michael Van Canneyt
to Rainer Hantsch
Rainer Hantsch wrote 17 lines
Hi, Marco! On Thu, 24 Jul 2003, Marco van de Voort wrote: | Howrever the site is still up: | | http://www.nomssi.de/pasjpeg/pasjpeg.html I know this site, and I know 'pasjpeg' from its name. I tried multiple times to get it working, but I always had the same problems, it does not compile. In the silent hope that this "toolbox" may have changed in the last year, I downloaded version 1.1 today. Well, the author still has some "problems" with upper/lowercase in his ZIP's (everything extract as uppercase, but he references the files in lowercase inside his code), a typical identification that the files were created in a DOS environment. So I am not surprised that the code is primarily for WINDOWS and does not compile on Linux. :-/

It uses some windows bitmap structures, and cannot be compiled on Linux as is. For the rest it compiles 100% fine. You could cut&paste the needed definitions from the windows unit and put them between {$ifndef win32}..{$endif}

But you will not find it to your liking. Contrary to my earlier statement (based on the paszlib units) it is not TP style, but uses Delphi style to do the streaming.

Michael.

Rainer Hantsch
to Michael Van Canneyt

On Fri, 25 Jul 2003, Michael Van Canneyt wrote:
| It uses some windows bitmap structures, and cannot be compiled on Linux as | is. For the rest it compiles 100% fine. You could cut&paste the needed | definitions from the windows unit and put them between {$ifndef | win32}..{$endif}

So, in fact, the whole 'pasjpeg' does not exist at all, because converting such a thing will require that knowledge which I currently do not have. The only way to learn from source code is to analyze a _working_ one. It makes no sense to analyze windows-dependent code when Linux code is (so I guess) nearely the opposite -- otherwise it would not be so complicated to port Windoze-Software to Linux...

So I return to my initial question in the hope that somebody has already done such things...

What I need for my first steps, is some source code which compiles without any change on Linux and uses Linux' shared libraries for reading/writing data from/to image files in jpeg/gif/tif/... format.
I definitely prefer procedural and/or OOP style before Delphi Style, because this is easier to understand and also matches better to my already existing code.

A good sample for doing first steps would be a program which reads a little JPEG image into RAM, hereby decoding it into a simple structure (i.e. an array of pixels, one for every color, so that I can get the RGB or CMYK values out easily for every pixel.
Next step would be to store this structure back into a file.

With this two steps I can start. Nobody here who can help?

Ing. Rainer Hantsch

James Mills
to Rainer Hantsch
Rainer Hantsch wrote 31 lines
On Fri, 25 Jul 2003, Michael Van Canneyt wrote: | It uses some windows bitmap structures, and cannot be compiled on Linux as | is. For the rest it compiles 100% fine. You could cut&paste the needed | definitions from the windows unit and put them between {$ifndef | win32}..{$endif} So, in fact, the whole 'pasjpeg' does not exist at all, because converting such a thing will require that knowledge which I currently do not have. The only way to learn from source code is to analyze a _working_ one. It makes no sense to analyze windows-dependent code when Linux code is (so I guess) nearely the opposite -- otherwise it would not be so complicated to port Windoze-Software to Linux... So I return to my initial question in the hope that somebody has already done such things... What I need for my first steps, is some source code which compiles without any change on Linux and uses Linux' shared libraries for reading/writing data from/to image files in jpeg/gif/tif/... format. I definitely prefer procedural and/or OOP style before Delphi Style, because this is easier to understand and also matches better to my already existing code. A good sample for doing first steps would be a program which reads a little JPEG image into RAM, hereby decoding it into a simple structure (i.e. an array of pixels, one for every color, so that I can get the RGB or CMYK values out easily for every pixel. Next step would be to store this structure back into a file. With this two steps I can start. Nobody here who can help?

I could write you up a set of such procedures or classes to do this, however I'm starting semester :)
Anyway, I'm sure there are others here on this mailing list that could do the same.

Question: Why can't you do it yourself ?
It isn't that hard to grab the specs of the JPEG image format and learn it and write your own data structures to contain the jpeg image data, decode it into pixel arrays... It's all there in the specs :)

cheers
James

Show quoted text 9 lines
Ing. Rainer Hantsch _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
- -Zero Defect Software Engineers Group - ZDSEG - -You need only two tools. WD-40 and duct tape. -If it doesn't move and it should, use WD-40. -If it moves and shouldn't, use the tape.
Rainer Hantsch
to James Mills

Hello, James!

On Sat, 26 Jul 2003, James Mills wrote:
| I could write you up a set of such procedures or classes to do this, | however I'm starting semester :)

Good success at Uni! What are you studying?

| Anyway, I'm sure there are others here on this mailing list that could | do the same.
Possibly, yes. But you are the _first_ one who answered, so the number of people still seems to be very small... ;-)

| Question: Why can't you do it yourself ? It isn't that hard to grab the | specs of the JPEG image format and learn it and write your own data | structures to contain the jpeg image data, decode it into pixel arrays... | It's all there in the specs :)

Something about me: I started programming in Pascal roughly 15 years ago, on CP/M (Z80 CPU, 4MB RAM, 10MB HDD,...), later I changed to DOS with finally Borland Pascal, but I kept consequently away from Windoze programming. Finally I changed to Linux, which is more what I like DOS, than Windoze...

But all this years I never wrote one line in assembly language, nor was there any need for me to include external code. I did everything in plain Pascal language, without any hacking and tweaking, which was perfect for writing all this userspecific software.

So my primary problem is that I never got experience about how to solve such things like linking to external libraries. Of course, I could sit down and hope to find it out by myself with trial & error, but this is extremely inefficient and time consuming. Also success will be very low in this case. Another thing is: Why should I start re-inventing the wheel and writing my own JPEG/TIFF/.../units from scratch, when there exist a lot of ready made libraries? Isn't it the purpose of libraries to do exactly this?

So I am looking for some help in form of _working_ samples which I can analyze and try to understand. It will also be very helpful if there would be somebody who could "teach" me a little bit and guide me to my first success.

mfg

Ing. Rainer Hantsch

Micha? Kamburelis
to Rainer Hantsch

Hi Rainer

Pasjpeg is basically just a Pascal translation of sources originally written in ANSI C by IJG, Independent JPEG Group. You can find this C code with documentation at http://www.ijg.org/. At these URL there are also some informations about JPEG file coding (actually JFIF, JPEG is a standard for compressing image data and JFIF is a file format that uses JPEG compression; JFIF stands for "JPEG File Interchange Format"). But you will not find there a complete specification of JPEG format and, to be honest, I don't know where you can find it on the internet. Definitely, coding JPEG [de]compression by yourself is really an advanced topic and I would not advice you this.

Besides, Pasjpeg can really do all that you want. Pasjpeg contains some extra units not found in IJG code - mainly Jeg.pas and Pasjpeg.pas.

The first one implements a class that loads a jpeg image into a TGraphic class descendant from Graphics unit. Graphics unit comes from Delphi's VCL and it's not available with FPC - but I know Lazarus tries to implement library compatible with VCL (but Lazarus does it for FPC and for many platforms FPC supports), so maybe you could integrate Jpeg with Lazarus (I don't know, maybe they even already did that in Lazarus ?). So that's the first option you can try.

The second option is to take Jpeg unit and tweak it so that it is capable of reading and storing jpeg images in your preferable format, like simple two-dimensional array of RGB. For that you will definitely need IJG documentation to understand how Jpeg unit works - it's really too big subject to describe it in this letter.

Third option is probably the easiest one - you can use Pasjpeg unit to convert jpeg files into BMP files. Than you can learn how to read BMP files, it's really simple, and after doing that you will be able to read both BMP and JPEG images in quite the same way, you will only have to "filter" JPEG images through Pasjpeg. Not very elegant way to read JPEG images, but simple and working.

There is also a forth option, probably the hardets one : read IJG documentation and write your own code to handle pasjpeg library without Pasjpeg and Jpeg units (I hope you don't get confused when I sometimes use "pasjpeg" to name the whole "pasjpeg library" and sometimes to name the specific unit named "Pasjpeg.pas" in that library). Actually, if you learn how to do that you will not need pasjpeg library - under Linux there is usually a libjpeg.so shared library that contains whole IJG code, so you will not have to use pasjpeg library - just link dynamically to libjpeg.so (or statically to libjpeg.a).

Final words : what do I advise : take the easiest way - learn how to read BMP images and than use Pasjpeg unit. Also, there is a question - do you really need the JPEG format ? If you want just ANY image format than thinking about JPEG is a big mistake - there are many image formats MUCH easier to read. E.g. PPM (the simplest possible image format, you can handle it with a few lines of code), PNG (nice format with lots of capabilities and lossless compression (you DO know that JPEG compression is lossy, do you?), very easily readable with libpng) and so on. BMP format is somewhere between, it's a bit more complicated and a bit more functional than PPM - if you don't care about JPEGs anymore I would advice you PPM (or more general PNM) or PNG formats.

And remember there are many programs that can convert JPEG images into other formats (like PPM and PNG).

Oh, one more thing - Pasjpeg unit uses TStream classes and you said you dont like Classes. But, really, they are so simple - I guarantee that you will be glad when you learn how to use them and when you see what TStream and it's descendants can do for you.

Hope this helps,

James Mills
to Rainer Hantsch: Hello, James! | I could write you up a set of such procedures or classes to do this, |…
Rainer Hantsch wrote 7 lines
Hello, James! On Sat, 26 Jul 2003, James Mills wrote: | I could write you up a set of such procedures or classes to do this, | however I'm starting semester :) Good success at Uni! What are you studying?

Bachelor of Engineering in Software Engineering at Griffith University (Australia, QLD)

Show quoted text 35 lines
| Anyway, I'm sure there are others here on this mailing list that could | do the same. Possibly, yes. But you are the _first_ one who answered, so the number of people still seems to be very small... ;-) | Question: Why can't you do it yourself ? It isn't that hard to grab the | specs of the JPEG image format and learn it and write your own data | structures to contain the jpeg image data, decode it into pixel arrays... | It's all there in the specs :) Something about me: I started programming in Pascal roughly 15 years ago, on CP/M (Z80 CPU, 4MB RAM, 10MB HDD,...), later I changed to DOS with finally Borland Pascal, but I kept consequently away from Windoze programming. Finally I changed to Linux, which is more what I like DOS, than Windoze... But all this years I never wrote one line in assembly language, nor was there any need for me to include external code. I did everything in plain Pascal language, without any hacking and tweaking, which was perfect for writing all this userspecific software. So my primary problem is that I never got experience about how to solve such things like linking to external libraries. Of course, I could sit down and hope to find it out by myself with trial & error, but this is extremely inefficient and time consuming. Also success will be very low in this case. Another thing is: Why should I start re-inventing the wheel and writing my own JPEG/TIFF/.../units from scratch, when there exist a lot of ready made libraries? Isn't it the purpose of libraries to do exactly this? So I am looking for some help in form of _working_ samples which I can analyze and try to understand. It will also be very helpful if there would be somebody who could "teach" me a little bit and guide me to my first success.

As you'll read in other posts just recently there are jpeg units for pascal that do this. I probably have some myself that I'm unaware of :)

cheers
James

Show quoted text 12 lines
mfg Ing. Rainer Hantsch _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
- -Zero Defect Software Engineers Group - ZDSEG - -You need only two tools. WD-40 and duct tape. -If it doesn't move and it should, use WD-40. -If it moves and shouldn't, use the tape.
Rainer Hantsch
to Micha? Kamburelis: Hi Rainer Pasjpeg is basically just a Pascal translation of sources originally written in…

Hi, Micha, and thanks for your detailled answer.

In fact, you are right. I do not force JPEG. Though, it is one of the most common file formats.
I also thought about using an external program to convert any type of image into one easy to read format and then reading this one in. This 'quick and dirty method' may be ok as a workaround, but is not very optimal for permanent usage, because I have to load&execute i.e. Imagemagick's 'convert' for every particular picture. This is slow and causing a relatively high activity on the harddisk, therefore I discontinued this thought very soon.

The better solution will definitely be to convert data inside my application, because it loads once and then can convert continuously picture by picture (I plan to use a WEB-CAM for something like a simple motion detection, i.e., so I will have to convert permanently, not only once at program start).

What I am not understanding is:
-------------------------------
Most programs I can see in SuSE Linux use shared object libraries. These libraries are ready to use modules, can be used within multiple programs, and save me from re-inventing all this basic stuff again and again. There already was somebody who wrote these libraries and solved all problems with time, so why should I decide to do the same bloody way? (I also use the MySQL library without starting to analyze and re-code the whole communication protocol!)

What (in addition) is making me think is:
I have a friend who writes (with FPC) his own graphical applications for Windoze - with complete GUI support. He wrote once a library to simplify the API of Windoze, and now he can use Windoze in a procedural way. Looks relatively easy. He simply uses existing Windoze *.dll files to do all this basic stuff and also does not have to worry about how to read in a JPG in detail. The *.dll's do this job, and he simply has to call them the right way.

I may be totally wrong, but as far as I understand, Linux' *.so files are the same as Windoze' *.dll files in their meaning. So shouldn't it be possible to use them in the same manner, by loading them and talking to them?

| Oh, one more thing - Pasjpeg unit uses TStream classes and you said you | dont like Classes. But, really, they are so simple - I guarantee that | you will be glad when you learn how to use them and when you see what | TStream and it's descendants can do for you.

Classes are possibly fine, otherwise they would not be such common. But as far as I understand, you cannot mix Class Style programming and OOP programming in one program (would also make life not easier, even when this would work). This means that I would have to re-write a lot of code only to be able to use it longer. --> Makes no real sense to me.

mfg

Ing. Rainer Hantsch

Iván Montes
to Rainer Hantsch

----- Original Message -----

Earlier message 93 lines
From: "Rainer Hantsch" To: Sent: Saturday, July 26, 2003 9:06 AM Subject: Re: [fpc-pascal]How to use Linux libraries? > The better solution will definitely be to convert data inside my application, > because it loads once and then can convert continuously picture by picture (I > plan to use a WEB-CAM for something like a simple motion detection, i.e., so I > will have to convert permanently, not only once at program start). if you want to capture the data from a web-cam the best would be to directly collect the data from it, it might be in a yuv color space which would be a pain in the ass to convert. You could use v4l perhaps? I don't know how to do it though. Haven't touch a linux system in years :( > I may be totally wrong, but as far as I understand, Linux' *.so files are the > same as Windoze' *.dll files in their meaning. So shouldn't it be possible to > use them in the same manner, by loading them and talking to them? Yes Rainer, .dll and .so are the same. Generally speaking they are files that contains code fragments (functions) much like an executable but that can be loaded use an .so library you need to load it in your program. Check the FPC docs (http://www.freepascal.org/docs-html/prog/progch11.html#x197-19900011) Under windows you can use LoadLibrary, GetProcAddress (to load functions) and FreeLibrary, these functions are defined in the windows unit. Under Linux you have to use dlopen, dlsym, dlclose which are in the shared library 'dl'. As far as I know there is no interface to this library but they are really easy to setup in your program: //taken from the FPC OpenGL package by Sebastian Guenther (?) const RTLD_LAZY = $001; RTLD_NOW = $002; RTLD_BINDING_MASK = $003; function dlopen(Name: PChar; Flags: LongInt) : Pointer; extdecl; external 'dl'; function dlsym(Lib: Pointer; Name: PChar) : Pointer; extdecl; external 'dl'; function dlclose(Lib: Pointer): LongInt; extdecl; external 'dl'; function LoadLibrary(Name: PChar): THandle; begin Result := THandle(dlopen(Name, RTLD_LAZY)); end; function GetProcAddress(Lib: THandle; ProcName: PChar): Pointer; begin Result := dlsym(Pointer(Lib), ProcName); end; function FreeLibrary(Lib: THandle): Boolean; begin if Lib = 0 then Result := False else Result := dlClose(Pointer(Lib)) = 0; end; //THandle should be defined in SysUtils but a 32bit integer should do the job if you don't want to include the unit. With those functions you can actually load dynamic (shared) libraries into your program but you'll still need an interface to use that libraries functions. In that interface you declare the data types and functions without implementing them, sort of the 'interface' section of a pascal unit or a C's .h file. It's worth noticing that there are two main calling mechanism for functions STDCALL and CDECL, under linux I guess you'll find mainly the CDECL type. Check the zLib and OpenGL packages (among others) for FPC, they are available on the FPC site. There you'll see how it works. btw if you need a pascal interface to the libjpeg.so then you should translate the libjpeg.h or whatever it's called to pascal. You can use the h2pas util as a start. as a final note, check thoroughly (sp?) the FPC docs, they are awesome and they cover almost everything in a lot of detail. Check also the packages sources and the contributed units, a lot of good tips can be learn from there and they are usually very easy (short) to read sources. I hope this long email has been of some help :) ciao, Ivan
Marco van de Voort
to Iván Montes
Show quoted text 13 lines
to > use them in the same manner, by loading them and talking to them? Yes Rainer, .dll and .so are the same. Generally speaking they are files that contains code fragments (functions) much like an executable but that can be loaded dynamically at runtime. To use an .so library you need to load it in your program. Check the FPC docs (http://www.freepascal.org/docs-html/prog/progch11.html#x197-19900011) Under windows you can use LoadLibrary, GetProcAddress (to load functions) and FreeLibrary, these functions are defined in the windows unit. Under Linux you have to use dlopen, dlsym, dlclose which are in the shared library 'dl'. As far as I know there is no interface to this library but they are really easy to setup in your program:

Don't! Use unit dynlibs. (there are some examples in docs/dynlibex)

Dynlibs is basically a very small wrapper that encapsulates this. However it will avoid quite a few platform dependant ifdef's.

Show quoted text 11 lines
//taken from the FPC OpenGL package by Sebastian Guenther (?) const RTLD_LAZY = $001; RTLD_NOW = $002; RTLD_BINDING_MASK = $003; function dlopen(Name: PChar; Flags: LongInt) : Pointer; extdecl; external 'dl'; function dlsym(Lib: Pointer; Name: PChar) : Pointer; extdecl; external 'dl'; function dlclose(Lib: Pointer): LongInt; extdecl; external 'dl';

Since e.g. these are exactly the same on BSD, just in lib 'c'.

etc etc.

Unknown author
to Rainer Hantsch: Hi, Micha, and thanks for your detailled answer. In fact, you are right. I do not force…
Rainer Hantsch wrote
I may be totally wrong, but as far as I understand, Linux' *.so files are the same as Windoze' *.dll files in their meaning. So shouldn't it be possible to use them in the same manner, by loading them and talking to them?

You can. Using them statically (i.e. the system loads the needed library) is transparant on all systems. See the manual, chapter I advised you. It describes exactly what you need.

To load libraries dynamically, you can use the dynlibs unit. It contains cross-platform handling of shared libraries.

Show quoted text 8 lines
| Oh, one more thing - Pasjpeg unit uses TStream classes and you said you | dont like Classes. But, really, they are so simple - I guarantee that | you will be glad when you learn how to use them and when you see what | TStream and it's descendants can do for you. Classes are possibly fine, otherwise they would not be such common. But as far as I understand, you cannot mix Class Style programming and OOP programming in one program (would also make life not easier, even when this would work).

It _IS_ possible to do so. Only you cannot do the following:

  TA = Object
   ...
  end;

and then
TB = Class(TA)
...

  end;

i.e. you cannot mix class/object descendents. But you can use them together in 1 program, without problem.

Michael.