TJpegImage is very slow,why? lazarus / 39-Graphics ---------------------------------------------------------------------- yayongm · 2012-08-28 12:35 when open a 640X480X32bit jpeg file, the flowing code is very slow in lazarus(<45/s), but very fast in delphi(>20000/s) ,why and how to fix? var   dTime: DWord;   iCount: Integer;   AMS: TMemoryStream;   AJpg: TJpegImage;   ADlg: TOpenDialog;   sJpg: string; begin   ADlg := TOpenDialog.Create(nil);   AMS := TMemoryStream.Create;   try     if not ADlg.Execute then       Exit;     AMS.LoadFromFile(ADlg.FileName);     SetLength(sJpg, AMS.Size);     AMS.Position := 0;     AMS.Read(sJpg[1], AMS.Size);   finally     FreeAndNil(AMS);     FreeAndNil(ADlg);   end;   dTime := GetTickCount;   iCount := 0;   while (GetTickCount - dTime) < 5000 do   begin     AMS := TMemoryStream.Create;     AJpg := TJpegImage.Create;     try       AMS.Write(sJpg[1], Length(sJpg));       AMS.Position := 0;       AJpg.LoadFromStream(AMS);     finally       FreeAndNil(AJpg);       FreeAndNil(AMS);     end;     Inc(iCount);   end;   Memo1.Lines.Add(Format('JpegFile Result: %f/s', [iCount / 5])); end; ---------------------------------------------------------------------- User137 · 2012-08-28 15:44 I got little different, but similar result with my 640x480 jpg. Code: [Select]Lazarus 1.1 SVN: JpegFile Result: 34,60/s JpegFile Result: 34,60/s -Just file-load: JpegFile Result: 34,40/s JpegFile Result: 34,20/s Code: [Select]Delphi 7: JpegFile Result: 2008,00/s JpegFile Result: 2000,40/s -Just file-load: JpegFile Result: 4726,00/s JpegFile Result: 4747,60/s For that "Just file-load" test i changed the loop to: Code: [Select]  while (GetTickCount - dTime) < 5000 do begin     AJpg := TJpegImage.Create;     AJpg.LoadFromFile('test.jpg');     AJpg.Free;     Inc(iCount);   end; I wish this could be fixed too. Kind of important when dealing with graphics, or games. Have to test with PNG too though... JPG's are a useless relic of old times ---------------------------------------------------------------------- BigChimp · 2012-08-28 15:49 IIRC, the default fpc image handling routines were built for stability, not speed. I seem to remember that being mentioned on some wiki page. I'm sure there must be alternatives, once again, have a look on the wiki. ---------------------------------------------------------------------- User137 · 2012-08-28 15:58 Code: [Select]  while (GetTickCount - dTime) < 5000 do begin     Apng := TPortableNetworkGraphic.Create; // fpc version     Apng.LoadFromFile('test.png');     Apng.Free;     Inc(iCount);   end;   Memo1.Lines.Add(Format('PngFile Result: %f/s', [iCount / 5])); Delphi: Code: [Select]PngFile Result: 45,80/s PngFile Result: 45,80/s Lazarus: Code: [Select]PngFile Result: 24,40/s PngFile Result: 24,40/s No big differences there, but Borland didn't implement it for Delphi 7 so that's 3rd party lib. And on second thought, the speed is enough for game loading times. This cannot be bottleneck, and 24 this big PNG's is a massive pile of pixels. ---------------------------------------------------------------------- marcov · 2012-08-28 16:18 Quote from: BigChimp on August 28, 2012, 05:49:01 pmIIRC, the default fpc image handling routines were built for stability, not speed. I seem to remember that being mentioned on some wiki page. While true, Lazarus iirc doesn't use that but an own type based on FPC's abstract image class. (TlazIntfImage iirc) Lazintfimage doesn't have the main inefficiency of the FPC class, namely that every pixel is 64-bit. ---------------------------------------------------------------------- yayongm · 2012-08-29 01:39 To all:     The code will be run in arm cpu, but it is too slow to cancel...     so, if the performance is not important, why we use native code and lazarus?     sorry... ---------------------------------------------------------------------- BigChimp · 2012-08-29 07:19 @yayongm: have you actually looked at the wiki for other JPEG libraries? I'm sure there are some (e.g. Vampyre)... IIRC, some even in native Pascal. Others will probably use a jpg .dll/.so, but if that offers big speed improvements, and the library in question is very common, it may be worth choosing that. ---------------------------------------------------------------------- yayongm · 2012-08-30 07:12 @BigChimp,Thank you. I have install Vampyre and the code is changed: {$I ImagingOptions.inc} ..... var   dTime: DWord;   iCount: Integer;   AMS: TMemoryStream;   AJpg: TMultiImage;   ADlg: TOpenDialog;   sJpg: string; begin   ADlg := TOpenDialog.Create(nil);   AMS := TMemoryStream.Create;   try     if not ADlg.Execute then       Exit;     AMS.LoadFromFile(ADlg.FileName);     SetLength(sJpg, AMS.Size);     AMS.Position := 0;     AMS.Read(sJpg[1], AMS.Size);   finally     FreeAndNil(AMS);     FreeAndNil(ADlg);   end;   dTime := GetTickCount;   iCount := 0;   while (GetTickCount - dTime) < 5000 do   begin     AMS := TMemoryStream.Create;     AJpg := TMultiImage.Create;     try       AMS.Write(sJpg[1], Length(sJpg));       AMS.Position := 0;       AJpg.LoadMultiFromStream(AMS);     finally       FreeAndNil(AJpg);       FreeAndNil(AMS);     end;     Inc(iCount);   end;   Caption := Format('JpegFile Result: %f/s', [iCount / 5]); end; ================ But the result is:58.20/s ---------------------------------------------------------------------- reinerr · 2012-10-25 00:12 Are you sure its actually working? The code in your loop appears to fill a buffer with the text of a file name and then load a jpeg from this text. Perhaps you wanted to do something like AMS.LoadFromFile(ADlg.FileName); instead of AMS.Write(sJpg[1], Length(sJpg)); ??? Although since your stream doesn't have a valid jpeg header I would have expected it to bomb out much quicker. Code: [Select]    AMS := TMemoryStream.Create;     AJpg := TJpegImage.Create;     try       AMS.Write(sJpg[1], Length(sJpg)); // this is putting the file name text into the stream       AMS.Position := 0;       AJpg.LoadFromStream(AMS); // this is trying to load an image from text ---------------------------------------------------------------------- mdalacu · 2012-10-25 07:58 I also am trying to find a solution to load fast multiple jpgs from stream (from multiple ip cams). I have tried native jpeg image and also vampyre ... both pretty are pretty slow. In 2 years i have not found a solution for this, in Lazarus. Maybe someone competent could look into this issue and solve it, it will have a big impact in many areas. Thank you.