Recent

Author Topic: Erratic behavior with larger image sizes (SOLVED: Use 64 bit)  (Read 2289 times)

QuinnMartin

  • Jr. Member
  • **
  • Posts: 56
I have an application that has to load a 16000x8000px image at full resolution.  This should be achievable in Lazarus and TBGRABitmap as I can get a map this big to load into a copy of Paint Shop Pro 5 from 1998, and it even loads into the TImage component in Delphi 5 from 1999.

To replicate: Create a 16000x8000px JPG image, load it into TBGRABitmap, and then assign it to TImage.  This crashes the app.

Excerpted code is as follows:

Code: Pascal  [Select][+][-]
  1. var
  2.   bmp : TBGRABitmap;
  3.   Image1 : TImage;
  4.  
  5. begin
  6.   bmp.LoadFromFile('C:\largemap.jpg');
  7.   Application.ProcessMessages; // This was added to try to make sure all internal code was executed
  8.   Image1.Picture.Bitmap.Assign(bmp);   // Assign bmp to Image1 which is for displaying the bitmap visually on a form
  9. end;
  10.  

This crashes on Line 3, on the Assign command, with "failed to create handles".  If I replace the image with a small image, 1000x800px, there is no error and the image appears properly in Image1.  The large image has been tested in D5 and Paint Shop and looks fine.

I am using Lazarus v3.0 and a version of TBGRA downloaded April 21 (not seeing the version at the top of the files or in Project Inspector).
« Last Edit: May 18, 2024, 10:40:12 am by QuinnMartin »

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Erratic behavior with larger image sizes
« Reply #1 on: May 17, 2024, 09:44:05 am »
How much RAM do you got installed?
Should the bmp not created before you LoadFromFile?
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Erratic behavior with larger image sizes
« Reply #2 on: May 17, 2024, 10:15:01 am »
Works when the object is created. Also stretch from TImage works without crashing.
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   bmp: TBGRABitmap;
  4. begin
  5.   bmp := TBGRABitmap.Create('.\!highscale.jpg');
  6.   try
  7.     Label1.Caption := 'Width: ' + IntToStr(bmp.Width);
  8.     Label2.Caption := 'Height: ' + IntToStr(bmp.Height);
  9.     Image1.Picture.Bitmap.Assign(bmp);
  10.   finally
  11.     bmp.Free;
  12.   end;
  13. end;
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

QuinnMartin

  • Jr. Member
  • **
  • Posts: 56
Re: Erratic behavior with larger image sizes
« Reply #3 on: May 18, 2024, 01:23:45 am »
Works when the object is created. Also stretch from TImage works without crashing.

No, it's not working for me.  I don't quite understand why I am getting different results.  I adapted your code, and this crashes with the "failed to create handles" message on the Assign command:

Code: Pascal  [Select][+][-]
  1. procedure TMainForm.TestFunctionClick(Sender: TObject);
  2. var
  3.   bmpx: TBGRABitmap;
  4.   myfilename : string;
  5. begin
  6.   myfilename := 'C:\images\bigfile.jpg';
  7.   bmpx := TBGRABitmap.Create(myfilename);
  8.   try
  9.     Application.ProcessMessages;
  10.     Image1.Picture.Bitmap.Assign(bmpx);
  11.     image1.update;
  12.   finally
  13.     bmpx.Free;
  14.   end;
  15. end;
  16.  
         

I have 32 GB of RAM and am running Win 10.  I think a 32 GB system should be capable of handling this bitmap.  Also in regard to my code in Post #1, the bmp already exists elsewhere in that app.  In my example in this post, I created a new bmp and get the same errors.
« Last Edit: May 18, 2024, 01:32:28 am by QuinnMartin »

QuinnMartin

  • Jr. Member
  • **
  • Posts: 56
Re: Erratic behavior with larger image sizes
« Reply #4 on: May 18, 2024, 01:40:47 am »
I created a completely separate program and still get the crash on the Assign command.  It does report the correct height and width on the file, 16200 and 8100 px.  So I really don't know what to do.

Here is the full program listing.  TImage is placed in a TScrollbox which is placed in one of two TPanels.  Buttons and labels go on the other TPanel.

Code: Pascal  [Select][+][-]
  1. unit graphicstestmain;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
  9.   BGRABitmap;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     Button1: TButton;
  17.     GoButton: TButton;
  18.     Image1: TImage;
  19.     Label1: TLabel;
  20.     Label2: TLabel;
  21.     Label3: TLabel;
  22.     Panel1: TPanel;
  23.     Panel2: TPanel;
  24.     ScrollBox1: TScrollBox;
  25.     procedure Button1Click(Sender: TObject);
  26.     procedure GoButtonClick(Sender: TObject);
  27.   private
  28.  
  29.   public
  30.  
  31.   end;
  32.  
  33. var
  34.   Form1: TForm1;
  35.  
  36. implementation
  37.  
  38. {$R *.lfm}
  39.  
  40. { TForm1 }
  41.  
  42. procedure TForm1.Button1Click(Sender: TObject);
  43. begin
  44.   close;
  45. end;
  46.  
  47. procedure TForm1.GoButtonClick(Sender: TObject);
  48. var
  49.   bmpx: TBGRABitmap;
  50.   myfilename : string;
  51. begin
  52.   label3.Caption :=' Processing...';
  53.   label3.update;
  54.   myfilename := 'C:\images\bigfile.jpg';
  55.   bmpx := TBGRABitmap.Create(myfilename);
  56.   try
  57.     Label1.Caption := 'Width: ' + IntToStr(bmpx.Width);
  58.     Label2.Caption := 'Height: ' + IntToStr(bmpx.Height);
  59.     label3.Caption := 'Assigning bitmap...';
  60.     label3.update;
  61.     Image1.Picture.Bitmap.Assign(bmpx);
  62.     Image1.update;
  63.     label3.Caption := 'Done.';
  64.   finally
  65.     bmpx.Free;
  66.   end;
  67. end;
  68.  
  69. end.
  70.  
« Last Edit: May 18, 2024, 01:42:38 am by QuinnMartin »

Josh

  • Hero Member
  • *****
  • Posts: 1344
Re: Erratic behavior with larger image sizes
« Reply #5 on: May 18, 2024, 04:51:41 am »
Hi

Just some thoughts,

I assume your compiling a 64bit app?

bgrabitmap 16200x1800 is over half a GB, which is not much, but timage,picture will be the same size, the timage canvas could be the same size, the scrollbox canvas could be similar size, and also the tpanel canvas the scrollbox is in, so if your creating a 32bit exe, you could be hitting the memory limit

If I remember correctly, TImage is a hybrid component, in that it stores the original image bitmap, and displays a seperate copy of it, so a large image in a timage will be bigger than you think? Any image processing like stretch draw, amOn etc, could cause it to choke.





« Last Edit: May 18, 2024, 04:56:28 am by Josh »
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

QuinnMartin

  • Jr. Member
  • **
  • Posts: 56
Re: Erratic behavior with larger image sizes
« Reply #6 on: May 18, 2024, 06:08:22 am »
The compiler is i386-win32-win32/64.  In compiler options it's not really clear what's going on since Target Platform is all "default", and I don't know what default is, but "Win32 gui application" is checked and Current LCL widgetset is "win32".  So I'm guessing this is 32-bit.

Sorry I am not 100% clear on this but I'm a bit new to Lazarus and 64-bit programming.

If I uninstall Lazarus 32-bit and go to 64-bit, will this stuff usually compile ok or will I be taking on new problems?  I would hate to go to 64-bit and then find out some polygon drawing function in TBGRABitmap doesn't work anymore or won't cross compile for Linux.  I'll probably run some tests though.

Hi

Just some thoughts,

I assume your compiling a 64bit app?

bgrabitmap 16200x1800 is over half a GB, which is not much, but timage,picture will be the same size, the timage canvas could be the same size, the scrollbox canvas could be similar size, and also the tpanel canvas the scrollbox is in, so if your creating a 32bit exe, you could be hitting the memory limit

If I remember correctly, TImage is a hybrid component, in that it stores the original image bitmap, and displays a seperate copy of it, so a large image in a timage will be bigger than you think? Any image processing like stretch draw, amOn etc, could cause it to choke.

QuinnMartin

  • Jr. Member
  • **
  • Posts: 56
Re: Erratic behavior with larger image sizes
« Reply #7 on: May 18, 2024, 10:39:47 am »
UPDATE: I removed 32-bit Lazarus and installed x86_64-win64-win32/win64 and the error seems to have gone away, and it is showing the Image1 normally.  So maybe it was a 32-bit problem?

Question though: Should I still have "Win32 gui application" checkmarked?  I am not sure where that is appropriate.  Also I am not clear if I needed to remove the old TBGRABitmap from the installation and download it again to enable the 64-bit library, or if that's all automatic.

dseligo

  • Hero Member
  • *****
  • Posts: 1408
Re: Erratic behavior with larger image sizes
« Reply #8 on: May 18, 2024, 12:23:09 pm »
Question though: Should I still have "Win32 gui application" checkmarked?  I am not sure where that is appropriate. 

Leave "Win32 gui application" checked. If you uncheck it, when running program, console window will also be opened (besides gui forms of your application). You can try it to see what I mean (then you can use WriteLn in your otherwise Windows program).
You can choose if you will compile 64 or 32 bit program under Target platform: Target OS and Target CPU family (leave Target processor at default). Either Win64/x86_64 or Win32/i386 combination. You may need to install cross-compiler (depending on your version of Lazarus go to downloads, add-ons).

Quote
Also I am not clear if I needed to remove the old TBGRABitmap from the installation and download it again to enable the 64-bit library, or if that's all automatic.

It will be automatic. But you know that you can install packages from 'Online Package Manager' (menu Package, Online Package Manager)?

circular

  • Hero Member
  • *****
  • Posts: 4356
    • Personal webpage
Re: Erratic behavior with larger image sizes (SOLVED: Use 64 bit)
« Reply #9 on: May 20, 2024, 10:04:10 pm »
It is confusing but indeed Win32 is the widgetset and it is still called that way with 64 bit processor. So it is totally ok that Lazarus and your app are 64-bits and still have the Win32 widgetset.

32-bit processor cannot address more than 4 GB because because memory addresses are stored in one native number and 4 billion is the maximum. It is even less than that for standard Win32 applications. They are limited to 2 GB unless marked as "large address aware".

So the 16200x1800 image is by itself more than one quarter of all the memory available to a 32-bit application. So even in the best case, it is not possible to have more than 3 instances of this image. As Josh mentions, the image can be duplicated for various reasons. For example when converting between different pixel encodings.
Conscience is the debugger of the mind

 

TinyPortal © 2005-2018