[fpc-pascal] FPImage and mult-page TIFF support

Marco van de Voort marcov at stack.nl
Fri Dec 9 13:51:46 CET 2016

In our previous episode, Mattias Gaertner said:
> > Are there still no ways around the 64-bit storage format? I thought
> > TLazintfImage was meant to be a step in that direction?
> There are various image formats (TLazintfImage,
> TFPCompactImgRGBA8Bit, TFPCompactImgGrayAlpha8Bit, ..), so memory
> consumption is as good as you want.

I had meanwhile revisited the source, and it came back to me.

The issues are (for e.g. fpreadbmp)
- 1 method call per pixel to setpixel/setcolor
- 1 virtual call per pixel to setpixel.
- mandatory going through the various tfpcolor routines for shifting etc.
- this all in a for loop without any optimization whatsoever.

PCs are fast, but if you things like this and 64-bit arithmetic on millions
of pixels individually you get already noticable delays in the human range.
That said, I wouldn't change it. It is an existing interface and does cover
many if not all cases. I would rather allow some bypasses for some extremely
common cases in an extensible way. (so that people with special needs can
$!@@ well implement their own)

I thought about it a few years back, and the idea back then was to have
something like:

1. have a event function that gets some src data and dest data info,
   and it is to return true if it is match. The match even could call
   information methods in the reader/writer and tcustimage again.
   The tfpcustimage level must implement this, and init it to nil (don't use)
   or some default for common cases.
2. if it is a match, it must return another event or adapter class that act
   for read as the  readscanline/writescanline part of the bmpreader. This
   transfer class can also maintain its own custom buffer (readbmp.linebuf like)
3. the TFPCustomImage class needs some form of getlinepointer(y:integer) and
    maybe a way to check if it is safe to call. (since it might not make
    sense for some forms of images)

However back then I was in a hurry, and I simply ported the PNG support
subset that I need over, and didn't pursue or refine it further. I never
looked beyond bmp and png needs to begin with. 

For me BMP is the base format because it works really well as a standarized
header for raw pixel data.  I only use png as a longer term storage format
because of its compression in slower applications. (that can spare the time
for compression)


I've had long term sustained write speeds in excess of 100MByte/s in 2MB
images on a Pentium D with a 15K raid array with only a mild buffer in its
own thread. (Windows updating directory information might hold they system
hundreds of ms, so you need to have some buffering at 50fps) with a setup
much like this and a write format that matched pixeldata.

More information about the fpc-pascal mailing list