Skip to content

Commit

Permalink
add a fast way to compress/decompress images using SynLZ
Browse files Browse the repository at this point in the history
Also include the asm variants of SynLZCompress
  • Loading branch information
ollydev committed Feb 28, 2024
1 parent d27490a commit 1521c96
Show file tree
Hide file tree
Showing 8 changed files with 696 additions and 376 deletions.
6 changes: 5 additions & 1 deletion Source/Simba.lpi
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@
<PackageName Value="LCL"/>
</Item5>
</RequiredPackages>
<Units Count="123">
<Units Count="124">
<Unit0>
<Filename Value="Simba.lpr"/>
<IsPartOfProject Value="True"/>
Expand Down Expand Up @@ -960,6 +960,10 @@
<Filename Value="script/simba.script_compiler_imagefromstring.pas"/>
<IsPartOfProject Value="True"/>
</Unit122>
<Unit123>
<Filename Value="image/simba.image_fastcompress.pas"/>
<IsPartOfProject Value="True"/>
</Unit123>
</Units>
</ProjectOptions>
<CompilerOptions>
Expand Down
7 changes: 4 additions & 3 deletions Source/image/simba.image.pas
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ interface

TSimbaImageLineStarts = array of PColorBGRA;

PSimbaImage = ^TSimbaImage;
TSimbaImage = class(TSimbaBaseClass)
protected
FWidth: Integer;
Expand Down Expand Up @@ -254,14 +253,16 @@ TSimbaImage = class(TSimbaBaseClass)
function PixelDifferenceTPA(Other: TSimbaImage): TPointArray; overload;
function PixelDifferenceTPA(Other: TSimbaImage; Tolerance: Single): TPointArray; overload;
end;

TSimbaImageArray = array of TSimbaImage;

PSimbaImage = ^TSimbaImage;
PSimbaImageArray = ^TSimbaImageArray;

implementation

uses
Math, FPImage,
simba.files, simba.zip, simba.box, simba.quad, simba.geometry, simba.nativeinterface,
simba.zip, simba.box, simba.quad, simba.geometry, simba.nativeinterface,
simba.matrix_float, simba.matrix_int, simba.array_point, simba.arraybuffer, simba.algo_sort,
simba.image_lazbridge, simba.image_integral, simba.image_gaussblur,
simba.image_bitmaparealoader, simba.image_stringconv;
Expand Down
82 changes: 82 additions & 0 deletions Source/image/simba.image_fastcompress.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
Author: Raymond van Venetië and Merlijn Wajer
Project: Simba (https://github.com/MerlijnWajer/Simba)
License: GNU General Public License (https://www.gnu.org/licenses/gpl-3.0)
--------------------------------------------------------------------------
Compress images fast using SynLZ.
}
unit simba.image_fastcompress;

{$i simba.inc}

interface

uses
Classes, SysUtils,
simba.base, simba.image;

procedure SimbaImage_FastCompress(Images: TSimbaImageArray; var Data: Pointer; out DataSize: SizeUInt);
function SimbaImage_FastDeCompress(Data: Pointer; DataLen: SizeUInt): TSimbaImageArray;

implementation

uses
SynLZ;

type
PImageHeader = ^TImageHeader;
TImageHeader = packed record
Size: SizeUInt; // compressed size in bytes
Width, Height: Integer;
end;

procedure SimbaImage_FastCompress(Images: TSimbaImageArray; var Data: Pointer; out DataSize: SizeUInt);
var
TotalSize: SizeUInt;
I: Integer;
Ptr: PByte;
begin
DataSize := 0;
TotalSize := SizeOf(Integer) + (Length(Images) * SizeOf(TImageHeader));
for I := 0 to High(Images) do
Inc(TotalSize, Images[I].DataSize);

if (Data = nil) or (MemSize(Data) < SynLZcompressdestlen(TotalSize)) then
ReAllocMem(Data, SynLZcompressdestlen(TotalSize));

Ptr := Data;
PInteger(Ptr)^ := Length(Images);
Inc(Ptr, SizeOf(Integer) + (Length(Images) * SizeOf(TImageHeader)));

for I := 0 to High(Images) do
with PImageHeader(Data + SizeOf(Integer) + (I * SizeOf(TImageHeader)))^ do
begin
Width := Images[I].Width;
Height := Images[I].Height;
Size := SynLZcompress(PByte(Images[I].Data), Images[I].DataSize, Ptr);
Inc(Ptr, Size);
Inc(DataSize, Size);
end;
end;

function SimbaImage_FastDeCompress(Data: Pointer; DataLen: SizeUInt): TSimbaImageArray;
var
Ptr: PByte;
I: Integer;
begin
Ptr := Data;
SetLength(Result, PInteger(Ptr)^);
Inc(Ptr, SizeOf(Integer) + (Length(Result) * SizeOf(TImageHeader)));

for I := 0 to High(Result) do
with PImageHeader(Data + SizeOf(Integer) + (I * SizeOf(TImageHeader)))^ do
begin
Result[I] := TSimbaImage.Create(Width, Height);
SynLZdecompress(Ptr, Size, PByte(Result[I].Data));
Inc(Ptr, Size);
end;
end;

end.

5 changes: 5 additions & 0 deletions Source/image/simba.image_utils.pas
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
{
Author: Raymond van Venetië and Merlijn Wajer
Project: Simba (https://github.com/MerlijnWajer/Simba)
License: GNU General Public License (https://www.gnu.org/licenses/gpl-3.0)
}
unit simba.image_utils;

{$i simba.inc}
Expand Down
6 changes: 3 additions & 3 deletions Source/script/imports/simba.import_encoding.pas
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ procedure _LapeZDecompressString(const Params: PParamArray; const Result: Pointe
*)
procedure _LapeSynLZCompress(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PInteger(Result)^ := SynLZcompress1pas(PPAnsiChar(Params^[0])^, PInteger(Params^[1])^, PPAnsiChar(Params^[2])^);
PInteger(Result)^ := SynLZcompress(PPointer(Params^[0])^, PInteger(Params^[1])^, PPointer(Params^[2])^);
end;

(*
Expand All @@ -235,7 +235,7 @@ procedure _LapeSynLZCompress(const Params: PParamArray; const Result: Pointer);
*)
procedure _LapeSynLZDecompress(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PInteger(Result)^ := SynLZdecompress1pas(PPAnsiChar(Params^[0])^, PInteger(Params^[1])^, PPAnsiChar(Params^[2])^);
PInteger(Result)^ := SynLZdecompress(PPointer(Params^[0])^, PInteger(Params^[1])^, PPointer(Params^[2])^);
end;

(*
Expand All @@ -255,7 +255,7 @@ procedure _LapeSynLZCompressDestLen(const Params: PParamArray; const Result: Poi
*)
procedure _LapeSynLZDecompressDestLen(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PInteger(Result)^ := SynLZdecompressdestlen(PPAnsiChar(Params^[0])^);
PInteger(Result)^ := SynLZdecompressdestlen(PPointer(Params^[0])^);
end;

procedure _LapeLZCompressionThread_Create(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
Expand Down
15 changes: 14 additions & 1 deletion Source/script/imports/simba.import_image.pas
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ implementation
uses
Graphics,
lptypes,
simba.image, simba.image_textdrawer;
simba.image, simba.image_textdrawer, simba.image_fastcompress;

type
PBitmap = ^TBitmap;
Expand Down Expand Up @@ -1254,6 +1254,16 @@ procedure _LapeImage_DrawCircleAA(const Params: PParamArray); LAPE_WRAPPER_CALLI
PSimbaImage(Params^[0])^.DrawCircleAA(PPoint(Params^[1])^, Pinteger(Params^[2])^, PColor(Params^[3])^, PSingle(Params^[4])^);
end;

procedure _LapeFastCompressImages(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
SimbaImage_FastCompress(TSimbaImageArray(Params^[0]^), PPointer(Params^[1])^, PSizeUInt(Params^[2])^);
end;

procedure _LapeFastDeCompressImages(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
TSimbaImageArray(Result^) := SimbaImage_FastDeCompress(PPointer(Params^[0])^, PSizeUInt(Params^[1])^);
end;

(*
TImage.Finder
-------------
Expand Down Expand Up @@ -1466,6 +1476,9 @@ procedure ImportSimbaImage(Compiler: TSimbaScript_Compiler);
addGlobalFunc('procedure TImage.DrawEllipseAA(ACenter: TPoint; XRadius, YRadius: Integer; Color: TColor; Thickness: Single = 1.5);', @_LapeImage_DrawEllipseAA);
addGlobalFunc('procedure TImage.DrawCircleAA(ACenter: TPoint; Radius: Integer; Color: TColor; Thickness: Single = 1.5);', @_LapeImage_DrawCircleAA);

addGlobalFunc('procedure FastCompressImages(Images: TImageArray; var Data: Pointer; out DataSize: SizeUInt);', @_LapeFastCompressImages);
addGlobalFunc('function FastDeCompressImages(Data: Pointer; out DataLen: SizeUInt): TImageArray', @_LapeFastDeCompressImages);

ImportingSection := '';
end;
end;
Expand Down
7 changes: 6 additions & 1 deletion Source/simba.compress.pas
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
{
Author: Raymond van Venetië and Merlijn Wajer
Project: Simba (https://github.com/MerlijnWajer/Simba)
License: GNU General Public License (https://www.gnu.org/licenses/gpl-3.0)
}
unit simba.compress;

{$i simba.inc}
Expand Down Expand Up @@ -138,7 +143,7 @@ function TCompressingStream.Write(const Buffer; Count: LongInt): LongInt;
Capacity := NeededCapacity;

TimeUsed := HighResolutionTime();
Result := SynLZcompress1pas(Pointer(Buffer), Count, Self.Memory);
Result := SynLZcompress(Pointer(Buffer), Count, Self.Memory);
TimeUsed := HighResolutionTime() - TimeUsed;
end;

Expand Down

0 comments on commit 1521c96

Please sign in to comment.