Lazarus

Announcements => Third party => Topic started by: Tomxe on February 16, 2025, 04:07:25 am

Title: libTIFF for Lazarus - reading and writing TIF images
Post by: Tomxe on February 16, 2025, 04:07:25 am
https://github.com/Xelitan/TIFF-for-Delphi-Lazarus-Free-Pascal/
License: MIT

Usage examples

Code: Pascal  [Select][+][-]
  1.   Image1.Picture.LoadFromFile('test.tif');


Code: Pascal  [Select][+][-]
  1. var t: TTifImage;
  2. begin
  3.  Image1.Picture.LoadFromFile('test.bmp');
  4.  
  5.  t := TTifImage.Create;
  6.  t.Assign(Image1.Picture.Bitmap);
  7.  t.SetCompression(COMPRESSION_LZW);
  8.  t.SaveToFile('out.tif');
  9.  t.Free;

- uncompressed
- CCITT3
- CCITT4
- LZW   
- JPEG 
- ADOBE DEFLATE
- PACKBITS
- DEFLATE (aka ZIP)
- LZMA2     //rare
- Zstandard //rare
- WebP      //rare

It can read formats that Lazarus' TIFF library doesn't support, like CCIT3.
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Thaddy on February 16, 2025, 10:25:07 am
Why would we need that?
Tiff support (read and write, most formats) is in fcl-image, so in the default dfistribution. And it is fully native Pascal.
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Tomxe on February 16, 2025, 10:34:37 am
Great question, Thaddy!
I just updated my post. This is the reference TIFF implementation and it supports way more TIFF formats than TIFF library available in Lazarus.
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Hartmut on February 16, 2025, 11:02:21 am
Why would we need that?
Tiff support (read and write, most formats) is in fcl-image, so in the default dfistribution. And it is fully native Pascal.

I see 2 reasons:
1) TIF support in fcl-image cannot read all TIF-Images, only some
2) if you write a TIF-Image with fcl-image, then it cannot be read by fcl-image again (returns Error "Tags must be in ascending order")
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Thaddy on February 16, 2025, 11:04:02 am
CCITT group 3 is - has always been - supported by fcl-image. Only quirkyness is it it implementated at group member level.
It is also less relevant because these are older formats like rle and fax.
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Thaddy on February 16, 2025, 11:06:42 am
2) if you write a TIF-Image with fcl-image, then it cannot be read by fcl-image again (returns Error "Tags must be in ascending order")
I have no opinion about that since I never use any of the TIFF formats myself.
They are also disappearing in the wild.
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Tomxe on February 16, 2025, 11:07:49 am
Test yourself
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Tomxe on February 16, 2025, 11:11:26 am
TIFF in my opinion is a terrible format and people who designed it shouldn't allowed to touch computers. But it is still popular among graphic artists, publishers and academics. Luckily most of them use LZW, None or JPEG compressions. But once in a while you might stumble upon something more exotic and it good to have a solution.
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Packs on February 16, 2025, 04:56:23 pm
your sample contains virus. it is not downloading
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Tomxe on February 16, 2025, 05:28:32 pm
It doesn't contain a virus. You should switch to better antivirus or browser.
https://www.virustotal.com/gui/file/40d28aa23e78f771a7a786e532cd2d49b3cf891d959e4b0454ee148ecd03812f
In case of browser- Firefox is great.

Attached the same archive but without 2 "problematic" files.
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Packs on February 17, 2025, 03:38:24 am
Please share the library and sample for windows.
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: TRon on February 17, 2025, 04:35:47 am
Please share the library and sample for windows.
What exactly do you not understand about repositories ?

libTiff can be build and how it works by reading its API. Pascal header is provided by OP in his repository. Really,  what more is needed ?

On a more general note, this anti virus thing going bananas on something as simple as embedded tags is hilarious 🍌🍌
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Packs on February 17, 2025, 05:24:49 am
Thank you Sir.

It is working .

but image is showing reverse order . I have shared the screen shot
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Tomxe on February 17, 2025, 05:33:17 am
Please edit TifImage.pas and change "if Orient = 0 then" to "if Orient = 1 then"
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: d2010 on February 17, 2025, 06:06:46 am
CCITT group 3 is - has always been - supported by fcl-image. Only quirkyness is it it implementated at group member level.
It is also less relevant because these are older formats like rle and fax.

Can you replace CCITT inside TIFF with PDF ?
I known Lazarus contnin very-good PDF reader or write.
And the file.PDF is good feature for any programming language.
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Packs on February 17, 2025, 06:19:02 am
DecodeFromStream is having orient variable

Code: Pascal  [Select][+][-]
  1. // for  rotation problem
  2.        if Orient = 0 then
  3.          Orient := 1 ;
  4.       //
  5.  
  6.       if Orient = 0 then
  7.  
  8.           for y:=AHeight-1 downto 0 do begin
  9.             P := FBmp.Scanline[y];
  10.  
  11.             for x:=0 to AWidth-1 do begin
  12.               P[4*x+2] := SrcPtr^; Inc(SrcPtr);
  13.               P[4*x+1] := SrcPtr^; Inc(SrcPtr);
  14.               P[4*x  ] := SrcPtr^; Inc(SrcPtr);
  15.               P[4*x+3] := SrcPtr^; Inc(SrcPtr); //alfa
  16.             end;
  17.           end
  18.       else
  19.           for y:=0 to AHeight-1 do begin
  20.             P := FBmp.Scanline[y];
  21.  
  22.             for x:=0 to AWidth-1 do begin
  23.               P[4*x+2] := SrcPtr^; Inc(SrcPtr);
  24.               P[4*x+1] := SrcPtr^; Inc(SrcPtr);
  25.               P[4*x  ] := SrcPtr^; Inc(SrcPtr);
  26.               P[4*x+3] := SrcPtr^; Inc(SrcPtr); //alfa
  27.             end;
  28.           end;
  29.  

I have added inside DecodeFromStream not working
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: bytebites on February 17, 2025, 06:42:29 am
Code: Pascal  [Select][+][-]
  1.       if Orient = 1 then
  2.  
  3.           for y:=AHeight-1 downto 0 do begin
  4.             P := FBmp.Scanline[y];
  5.  
  6.             for x:=0 to AWidth-1 do begin
  7.               P[4*x+2] := SrcPtr^; Inc(SrcPtr);
  8.               P[4*x+1] := SrcPtr^; Inc(SrcPtr);
  9.               P[4*x  ] := SrcPtr^; Inc(SrcPtr);
  10.               P[4*x+3] := SrcPtr^; Inc(SrcPtr); //alfa
  11.             end;
  12.           end
  13.       else
  14.           for y:=0 to AHeight-1 do begin
  15.             P := FBmp.Scanline[y];
  16.  
  17.             for x:=0 to AWidth-1 do begin
  18.               P[4*x+2] := SrcPtr^; Inc(SrcPtr);
  19.               P[4*x+1] := SrcPtr^; Inc(SrcPtr);
  20.               P[4*x  ] := SrcPtr^; Inc(SrcPtr);
  21.               P[4*x+3] := SrcPtr^; Inc(SrcPtr); //alfa
  22.             end;
  23.           end;
  24.  
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Packs on February 17, 2025, 06:55:58 am
Thank you sir . it is working
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Packs on February 18, 2025, 05:58:09 am
try to create TTIF with compression COMPRESSION_CCITT4

it is giving following error message .

Code: Pascal  [Select][+][-]
  1.  In file 'TifImage.pas' at line 310:
  2. raise Exception.CreateFmt('Error writing row %d', [y]);
  3.  
  4. var
  5.   t: TTifImage;
  6. begin
  7.  
  8.   Image1.Picture.LoadFromFile('demo.jpg');
  9.  
  10.   t := TTifImage.Create;
  11.   t.Assign(Image1.Picture.Bitmap);
  12.   t.SetCompression(COMPRESSION_CCITT4);
  13.   t.SaveToFile('out.tif');
  14.   t.Free;
  15.  

how to set dpi . I want image should be 200 dpi.
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Tomxe on February 18, 2025, 09:00:53 am
1) Download new version:
https://github.com/Xelitan/TIFF-for-Delphi-Lazarus-Free-Pascal/blob/main/TifImage.pas
2) Make sure your image in Image1 is TBitmap with PixelFormat = pf1bit. If it's not you need convert.

Setting DPI is not supported right now.
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Packs on February 19, 2025, 05:33:35 pm
Code: Pascal  [Select][+][-]
  1.  In file 'TifImage.pas' at line 321:
  2. raise Exception.CreateFmt('Error writing row %d', [y]);
  3.  
  4.  
  5.  
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Tomxe on February 19, 2025, 05:53:12 pm
Seems your image is not pf1bit. You need to convert it to pf1bit.
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Packs on February 19, 2025, 06:57:19 pm
Code: Pascal  [Select][+][-]
  1. var
  2.   t: TTifImage;
  3. begin
  4.  
  5.   Image1.Picture.LoadFromFile('demo.jpg');
  6.   Image1.Picture.Bitmap.PixelFormat:=  pf1bit;
  7.  
  8.   t := TTifImage.Create;
  9.   t.Assign(Image1.Picture.Bitmap);
  10.   t.SetCompression(COMPRESSION_CCITT4);
  11.   t.SaveToFile('out.tif');
  12.   t.Free;  
  13.  

code is working . it is creating tiff image but it is black colour.
I am attaching demo.jpg file
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Tomxe on February 19, 2025, 11:18:34 pm
Your code would work in Delphi but PixelFormat isn't finished in Lazarus. That's why you get a black picture. Add "Math" to your uses.


Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   t: TTifImage;
  4.   Bmp,Bmp2: TBitmap;
  5.   x,y,i: Integer;
  6.   G,B: Byte;
  7.   P,R: PByteArray;
  8. begin
  9.  
  10.   Image1.Picture.LoadFromFile('demo.jpg');
  11.  
  12.   Bmp := TBitmap.Create;
  13.   Bmp.PixelFormat := pf32bit;
  14.   Bmp.SetSize(Image1.Picture.Graphic.Width, Image1.Picture.Graphic.Height);
  15.   Bmp.Canvas.Draw(0,0, Image1.Picture.Graphic);
  16.  
  17.   for y:=0 to Bmp.Height-1 do begin
  18.     P := Bmp.Scanline[y];
  19.     for x:=0 to Bmp.Width-1 do begin
  20.       G := (P^[4*x] + P^[4*x+1] + P^[4*x+2]) div 3;
  21.       if G > 127 then G := 1
  22.       else            G := 0;
  23.  
  24.       P^[4*x  ] := G;
  25.     end;
  26.   end;
  27.  
  28.   Bmp2 := TBitmap.Create;
  29.   Bmp2.PixelFormat := pf1bit;
  30.   Bmp2.SetSize(Bmp.Width, Bmp.Height);
  31.  
  32.   for y:=0 to Bmp2.Height-1 do begin
  33.     P := Bmp2.Scanline[y];
  34.     R := Bmp.Scanline[y];
  35.     for x:=0 to Ceil(Bmp2.Width/8)-1 do begin
  36.  
  37.       B := 0;
  38.       for i:=0 to 7 do begin
  39.         G := R^[4*(8*x+i)];
  40.         B := B + (G shl (7-i));
  41.       end;
  42.  
  43.       P^[x] := B;
  44.     end;
  45.   end;
  46.  
  47.   t := TTifImage.Create;
  48.   t.Assign(Bmp2);
  49.   t.SetCompression(COMPRESSION_CCITT4);
  50.   t.SaveToFile('out.tif');
  51.   t.Free;
  52.   Bmp2.Free;
  53.   Bmp.Free;
  54. end;  
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Packs on February 20, 2025, 05:10:37 am
Thank you Sir. 🙏🙏🙏

it is working .

can you explain me in detail. why you are using for loop. what you have done .

My last requirement in tiff image is DPI.

Please guide me .
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Packs on February 20, 2025, 07:26:00 am
Dear sir,

can we use this link for create DPI https://forum.lazarus.freepascal.org/index.php?topic=40663.0
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Tomxe on February 20, 2025, 02:21:50 pm
Please download new version:
https://github.com/Xelitan/TIFF-for-Delphi-Lazarus-Free-Pascal/blob/main/TifImage.pas

And you can set dpi like this:

Code: Pascal  [Select][+][-]
  1. var T: TTiffImage;
  2. begin
  3. ...
  4. T.SetDpi(300);

Explanation of the code posted before:

Code: Pascal  [Select][+][-]
  1. for y:=0 to Bmp.Height-1 do begin
  2.     P := Bmp.Scanline[y];
  3.     for x:=0 to Bmp.Width-1 do begin
  4.       G := (P^[4*x] + P^[4*x+1] + P^[4*x+2]) div 3;
  5.       if G > 127 then G := 1
  6.       else            G := 0;
  7.  
  8.       P^[4*x  ] := G;
  9.     end;
  10.   end;;

The above code changes image to grayscale by averaging Red, Green and Blue colors.
And then if the resulting gray pixel has value > 127 it makes it white  and if not- makes it black.
So this converts picture to black and white only.

Code: Pascal  [Select][+][-]
  1. for y:=0 to Bmp2.Height-1 do begin
  2.     P := Bmp2.Scanline[y];
  3.     R := Bmp.Scanline[y];
  4.     for x:=0 to Ceil(Bmp2.Width/8)-1 do begin
  5.  
  6.       B := 0;
  7.       for i:=0 to 7 do begin
  8.         G := R^[4*(8*x+i)];
  9.         B := B + (G shl (7-i));
  10.       end;
  11.  
  12.       P^[x] := B;
  13.     end;
  14.   end;

The code above is packing 8 pixels into 1 Byte.
Title: Re: libTIFF for Lazarus - reading and writing TIF images
Post by: Packs on February 21, 2025, 11:40:18 am
Thank You so much. 🙏🙏🙏🙏

it is working .
TinyPortal © 2005-2018