[fpc-pascal] Questions regarding FPImage's TFPMemoryImage.FData variable

Michael Van Canneyt michael at freepascal.org
Thu May 26 13:08:56 CEST 2016



On Thu, 26 May 2016, Graeme Geldenhuys wrote:

> Hi,
>
> The internal FData field variable of TFPMemoryImage is of type
> FPFItegerArray and is defined as follows:
>
>  TFPIntegerArray = array [0..(maxint-1) div sizeof(integer)-1] of integer;
>  PFPIntegerArray = ^TFPIntegerArray;
>
> Unfortunately the FPImage unit is not documented at all. So I have the
> following questions regarding that field variable:
>
> 1) I'm assuming FData is the raw image buffer of TFPMemoryImage where
>   all the image pixel data is stored?
>

Yes.

BUT: 
depending on UsePalette, it contains indexes in the palette or RGB Data.

> 2) Nowhere in TFPMemoryImage is the size of FData being set, it seem
>   it is always a hard-coded size, based on the type declaration
>   shown above. Isn't this inefficient? eg: a small 5x5 image and
>   4000x4000 image uses the same amount of memory for example. It is
>   obviously possible that I'm misunderstanding TFPMemoryImage
>   completely. ;-)

It is definitely possible that you are wrong. 
Line 512 of fpimage, and line 544


>
> 3) The FData image buffer (assuming (1) is correct) uses Integer instead
>   of Byte as it's element size. So I'm assuming a singe Integer hold
>   all the colour information for a single pixel?

No.

>   But then again, I have noticed that TFPColor uses Word size data
>   elements, thus the whole RGBA information per pixel will be 8 bytes
>   of data, and Integer is only 4 bytes large.

Yes. The Pixels array is a palette. The colors array is RGBA.


> 4) What is the order in which the colour channel information is stored
>   in memory? RGB, BGR, RGBA, BGRA, ARGB, ABGR etc?

You should not worry about this. The whole idea is that you do not use the
internal format, but just use the colors array:

       property  Colors [x,y:integer] : TFPColor read GetColor write SetColor; default;


>
> 5) Is the Alpha channel actually stored? I assume it is, because the
>   Integer type is large enough to hold that information.

Alpha is stored.

>
>
> The reason for all these questions. I've got a image loaded in a
> TFPMemoryImage instance. I need to pass the the raw pixel data buffer to
> a 3rd party library for further processing. But I need to tell that
> 3rd party library a bit about the data I'm giving it (colour channel
> size, colour channel order etc).

This is not supported for TFPMemoryImage.

The TFPCustomImage image component does not provide storage. 
It does not care about actual storage, and defines just an 
interface for getting/setting color data (possibly using a palette).

TFPMemoryImage is just a sample implementation of TFPCustomImage, which
supports full 64-bit color specs (3 RGB, 1 Alpha, all of size 16 bit).
The data is private, because it uses a private format, which will be
unusable in most libraries.

Instead, you can use use one of the TFPCompactImgBase descendants: 
they store their data in more compact (and common) formats than TFPMemoryImage.

TFPCompactImgRGBA8Bit
TFPCompactImgRGB8Bit

etc. The data pointer is protected, so you can create a descendent and
access it directly.

Or write your own imaga storage. You just need to override 5 methods.

Michael.



More information about the fpc-pascal mailing list