AWARE [SYSTEMS] Imaging expertise for the Delphi developer
AWare Systems, Imaging expertise for the Delphi developer, Home TIFF and LibTiff Mailing List Archive

LibTiff Mailing List

TIFF and LibTiff Mailing List Archive
January 2005

Previous Thread
Next Thread

Previous by Thread
Next by Thread

Previous by Date
Next by Date

Contact

The TIFF Mailing List Homepage
This list is run by Frank Warmerdam
Archive maintained by AWare Systems



Valid HTML 4.01!



Thread

2005.01.23 16:43 "LibTiffDelphi", by <michel.salvagniac@free.fr>
2005.01.24 01:17 "Re: LibTiffDelphi", by <sherlog@t-online.de>
2005.02.08 16:43 "Re: LibTiffDelphi", by Joris Van Damme

2005.01.24 01:17 "Re: LibTiffDelphi", by <sherlog@t-online.de>

--+ in <000b01c5016a$b80f2a90$0501a8c0@MIKO4>:

Strange nick you have. <g>

> LibTiffDelphi.
> ...
>   TIFFSetField(imgtif, TIFFTAG_XRESOLUTION, 150.0);
>   TIFFSetField(imgtif, TIFFTAG_YRESOLUTION, 150.0);
>   TIFFSetField(imgtif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
> ...
>   TIFFClose(imgtif);
> ...
> tiffinfo says :
>   Resolution: 0, 0 pixels/inch

You have set the fields properly and flushed them properly, yet the values
have not appeared in the file. I'd say there is something fishy going on in
the interaction between the Delphi code and the C code - perhaps a runtime
issue. Trace into the TIFFSetField() calls and watch the CPU/FPU windows for
unusual things (you need a special build of LibTiffDelphi for tracing into
the C code). You'll probably find some Delphi/C clashes regarding FPU use.

Have you posted this to Aware Systems? They are providing LibTiffDelphi and
so they should know it better than anybody else; quite probably they can
pinpoint the problem just from the description.

Apart from that, you should rework your pixel transfer code a little. The
only reason that it 'sort of' works now is that you pass a pointer to the
last scanline of the original bitmap to TIFFWriteRawStrip() and since bitmaps
are what they are you are thus effectively passing a pointer to the whole
bitmap data (since the last row on screen is the first row in memory, aka
bottom-up bitmap). 

However, scanlines in bitmap data are required to be aligned on DWORD
boundaries (32 bits) while uncompressed 1-bit TIFF scanlines must be aligned
on byte boundaries. This coincides if ImageWidth is close to multiples of 32
(25..32, 57..64, 89..96 and so on) but for other widths it does not work.
Further, while bottom-up bitmaps are common there are also top-down bitmaps,
so the fact that your code sort of works is mostly an accident.

The copy loop might look like this (put this *after* the code that
initializes the TIFF field values):

|   with ImageBits.Picture.Bitmap do begin
|      assert(Monochrome = true, 'ImageBits.Picture.Bitmap.Monochrome = true');
|      for y := 0 to Height - 1 do
|         if 1 <> TIFFWriteScanLine(imgtif, Scanline[Height - y - 1], y, 0) then
|            raise Exception.Create('meow');  end;

This is for bottom-up bitmaps, of course. You have to search the Borland docs
in order to find out whether Borland expose the bottom-up/top-down property
on their Bitmap object or whether they guarantee that their bitmaps are
always bottom-up or whether they simply let the chips fall where they may as
usual. Note: in a raw Windows bitmap the height field is negative for a
top-down bitmap, there is no separate 'bottom-up/top-down' flag. 

An alternative to antisymmetric writing in the bottom-up case would be
adjusting the 'Orientation' TIFF field to match the bitmap's bottom-up-ness
but then there is no guarantee that simple-minded TIFF consuming programs
will show your image correctly (the atrocity known as Wang/Kodak/Microsoft
Imaging comes to mind).

Luck++,
sherlog
-- 
Sherlog    [Personenkennzahl 250866413515 / Stefan Otto / SO1801-RIPE]