diff --git a/Projects/SAMufasaGUI/project1.lpi b/Projects/SAMufasaGUI/project1.lpi index 7efe446..f9381de 100644 --- a/Projects/SAMufasaGUI/project1.lpi +++ b/Projects/SAMufasaGUI/project1.lpi @@ -7,7 +7,7 @@ <UseXPManifest Value="True"/> - <ActiveEditorIndexAtStart Value="5"/> + <ActiveEditorIndexAtStart Value="4"/> </General> <VersionInfo> <ProjectVersion Value=""/> @@ -172,7 +172,7 @@ <UnitName Value="TestUnit"/> <CursorPos X="24" Y="264"/> <TopLine Value="250"/> - <EditorIndex Value="6"/> + <EditorIndex Value="5"/> <UsageCount Value="56"/> <Loaded Value="True"/> </Unit18> @@ -302,9 +302,9 @@ <Filename Value="../../Units/MMLCore/client.pas"/> <IsPartOfProject Value="True"/> <UnitName Value="Client"/> - <CursorPos X="73" Y="23"/> + <CursorPos X="29" Y="12"/> <TopLine Value="1"/> - <EditorIndex Value="5"/> + <EditorIndex Value="4"/> <UsageCount Value="55"/> <Loaded Value="True"/> </Unit37> @@ -330,8 +330,8 @@ <IsPartOfProject Value="True"/> <UnitName Value="files"/> <CursorPos X="25" Y="64"/> - <TopLine Value="30"/> - <EditorIndex Value="10"/> + <TopLine Value="34"/> + <EditorIndex Value="9"/> <UsageCount Value="56"/> <Loaded Value="True"/> </Unit40> @@ -341,7 +341,7 @@ <UnitName Value="Window"/> <CursorPos X="40" Y="263"/> <TopLine Value="263"/> - <EditorIndex Value="11"/> + <EditorIndex Value="10"/> <UsageCount Value="55"/> <Loaded Value="True"/> </Unit41> @@ -364,7 +364,7 @@ <UnitName Value="windowutil"/> <CursorPos X="96" Y="86"/> <TopLine Value="75"/> - <EditorIndex Value="12"/> + <EditorIndex Value="11"/> <UsageCount Value="18"/> <Loaded Value="True"/> </Unit44> @@ -390,9 +390,7 @@ <UnitName Value="Graphics"/> <CursorPos X="17" Y="1353"/> <TopLine Value="1341"/> - <EditorIndex Value="21"/> <UsageCount Value="15"/> - <Loaded Value="True"/> </Unit47> <Unit48> <Filename Value="../../Units/MMLAddon/mmlthread.pas"/> @@ -414,7 +412,7 @@ <UnitName Value="mmlpsthread"/> <CursorPos X="31" Y="132"/> <TopLine Value="107"/> - <EditorIndex Value="7"/> + <EditorIndex Value="6"/> <UsageCount Value="44"/> <Loaded Value="True"/> </Unit50> @@ -429,9 +427,7 @@ <Filename Value="../../../FPC/FPCCheckout/rtl/objpas/classes/classesh.inc"/> <CursorPos X="30" Y="260"/> <TopLine Value="244"/> - <EditorIndex Value="4"/> <UsageCount Value="15"/> - <Loaded Value="True"/> </Unit52> <Unit53> <Filename Value="../../../FPC/FPCCheckout/rtl/objpas/types.pp"/> @@ -457,7 +453,7 @@ <Unit56> <Filename Value="project1.lrs"/> <CursorPos X="70" Y="41"/> - <TopLine Value="7"/> + <TopLine Value="11"/> <EditorIndex Value="1"/> <UsageCount Value="22"/> <Loaded Value="True"/> @@ -529,7 +525,7 @@ <Filename Value="../../Units/MMLAddon/PSInc/pscompile.inc"/> <CursorPos X="31" Y="10"/> <TopLine Value="1"/> - <EditorIndex Value="8"/> + <EditorIndex Value="7"/> <UsageCount Value="16"/> <Loaded Value="True"/> </Unit66> @@ -551,7 +547,7 @@ <UnitName Value="bitmaps"/> <CursorPos X="33" Y="84"/> <TopLine Value="74"/> - <EditorIndex Value="14"/> + <EditorIndex Value="12"/> <UsageCount Value="34"/> <Loaded Value="True"/> </Unit69> @@ -572,8 +568,8 @@ <Filename Value="../../Units/MMLAddon/PSInc/Wrappers/bitmap.inc"/> <IsPartOfProject Value="True"/> <CursorPos X="13" Y="43"/> - <TopLine Value="9"/> - <EditorIndex Value="9"/> + <TopLine Value="13"/> + <EditorIndex Value="8"/> <UsageCount Value="33"/> <Loaded Value="True"/> </Unit72> @@ -609,17 +605,13 @@ <UnitName Value="FPimage"/> <CursorPos X="17" Y="129"/> <TopLine Value="112"/> - <EditorIndex Value="15"/> <UsageCount Value="14"/> - <Loaded Value="True"/> </Unit77> <Unit78> <Filename Value="../../../FPC/FPCCheckout/packages/fcl-image/src/fpimage.inc"/> <CursorPos X="3" Y="44"/> <TopLine Value="40"/> - <EditorIndex Value="16"/> <UsageCount Value="14"/> - <Loaded Value="True"/> </Unit78> <Unit79> <Filename Value="../../../lazarus/lcl/lclintf.pas"/> @@ -633,18 +625,14 @@ <UnitName Value="IntfGraphics"/> <CursorPos X="84" Y="1334"/> <TopLine Value="1334"/> - <EditorIndex Value="19"/> <UsageCount Value="14"/> - <Loaded Value="True"/> </Unit80> <Unit81> <Filename Value="../../../lazarus/lcl/graphtype.pp"/> <UnitName Value="GraphType"/> <CursorPos X="19" Y="634"/> <TopLine Value="630"/> - <EditorIndex Value="13"/> <UsageCount Value="15"/> - <Loaded Value="True"/> </Unit81> <Unit82> <Filename Value="../../../FPC/FPCCheckout/packages/fcl-image/src/fpcolors.inc"/> @@ -681,9 +669,7 @@ <Filename Value="../../../lazarus/lcl/include/custombitmap.inc"/> <CursorPos X="3" Y="98"/> <TopLine Value="96"/> - <EditorIndex Value="22"/> <UsageCount Value="13"/> - <Loaded Value="True"/> </Unit87> <Unit88> <Filename Value="../../../Compilertje/Units/CogatUnits/compmaths.pas"/> @@ -697,28 +683,22 @@ <UnitName Value="math"/> <CursorPos X="1" Y="1"/> <TopLine Value="1"/> - <EditorIndex Value="20"/> <UsageCount Value="13"/> - <Loaded Value="True"/> </Unit89> <Unit90> <Filename Value="../../../FPC/FPCCheckout/rtl/inc/systemh.inc"/> <CursorPos X="11" Y="513"/> <TopLine Value="496"/> - <EditorIndex Value="17"/> <UsageCount Value="11"/> - <Loaded Value="True"/> </Unit90> <Unit91> <Filename Value="../../../FPC/FPCCheckout/rtl/i386/fastmove.inc"/> <CursorPos X="44" Y="836"/> <TopLine Value="817"/> - <EditorIndex Value="18"/> <UsageCount Value="11"/> - <Loaded Value="True"/> </Unit91> </Units> - <JumpHistory Count="30" HistoryIndex="29"> + <JumpHistory Count="26" HistoryIndex="25"> <Position1> <Filename Value="../../Units/MMLAddon/mmlpsthread.pas"/> <Caret Line="132" Column="31" TopLine="106"/> @@ -728,117 +708,101 @@ <Caret Line="107" Column="21" TopLine="100"/> </Position2> <Position3> - <Filename Value="../../../lazarus/lcl/intfgraphics.pas"/> - <Caret Line="274" Column="64" TopLine="251"/> - </Position3> - <Position4> <Filename Value="../../Units/MMLCore/bitmaps.pas"/> <Caret Line="30" Column="43" TopLine="28"/> - </Position4> - <Position5> + </Position3> + <Position4> <Filename Value="../../Units/MMLCore/mufasatypes.pas"/> <Caret Line="20" Column="12" TopLine="1"/> + </Position4> + <Position5> + <Filename Value="../../Units/MMLCore/bitmaps.pas"/> + <Caret Line="37" Column="54" TopLine="19"/> </Position5> <Position6> <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="37" Column="54" TopLine="19"/> + <Caret Line="85" Column="5" TopLine="51"/> </Position6> <Position7> <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="85" Column="5" TopLine="51"/> + <Caret Line="80" Column="26" TopLine="63"/> </Position7> <Position8> - <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="80" Column="26" TopLine="63"/> - </Position8> - <Position9> <Filename Value="../../Units/MMLAddon/mmlpsthread.pas"/> <Caret Line="145" Column="17" TopLine="123"/> - </Position9> - <Position10> + </Position8> + <Position9> <Filename Value="../../Units/MMLAddon/PSInc/pscompile.inc"/> <Caret Line="8" Column="30" TopLine="1"/> + </Position9> + <Position10> + <Filename Value="../../Units/MMLCore/bitmaps.pas"/> + <Caret Line="36" Column="60" TopLine="22"/> </Position10> <Position11> <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="36" Column="60" TopLine="22"/> + <Caret Line="94" Column="67" TopLine="76"/> </Position11> <Position12> <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="94" Column="67" TopLine="76"/> + <Caret Line="230" Column="5" TopLine="196"/> </Position12> <Position13> <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="230" Column="5" TopLine="196"/> + <Caret Line="234" Column="22" TopLine="212"/> </Position13> <Position14> <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="234" Column="22" TopLine="212"/> + <Caret Line="234" Column="9" TopLine="209"/> </Position14> <Position15> - <Filename Value="../../../lazarus/lcl/intfgraphics.pas"/> - <Caret Line="3242" Column="48" TopLine="3238"/> + <Filename Value="../../Units/MMLCore/bitmaps.pas"/> + <Caret Line="229" Column="19" TopLine="212"/> </Position15> <Position16> <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="234" Column="9" TopLine="209"/> + <Caret Line="109" Column="39" TopLine="106"/> </Position16> <Position17> <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="229" Column="19" TopLine="212"/> + <Caret Line="247" Column="36" TopLine="230"/> </Position17> <Position18> - <Filename Value="../../../lazarus/lcl/intfgraphics.pas"/> - <Caret Line="274" Column="64" TopLine="245"/> + <Filename Value="../../Units/MMLCore/bitmaps.pas"/> + <Caret Line="223" Column="68" TopLine="201"/> </Position18> <Position19> <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="109" Column="39" TopLine="106"/> + <Caret Line="225" Column="21" TopLine="202"/> </Position19> <Position20> <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="247" Column="36" TopLine="230"/> + <Caret Line="219" Column="23" TopLine="196"/> </Position20> <Position21> <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="223" Column="68" TopLine="201"/> + <Caret Line="211" Column="60" TopLine="196"/> </Position21> <Position22> <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="225" Column="21" TopLine="202"/> + <Caret Line="230" Column="3" TopLine="206"/> </Position22> <Position23> - <Filename Value="../../../FPC/FPCCheckout/packages/fcl-image/src/fpimage.inc"/> - <Caret Line="194" Column="23" TopLine="168"/> + <Filename Value="../../Units/MMLCore/bitmaps.pas"/> + <Caret Line="233" Column="3" TopLine="206"/> </Position23> <Position24> <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="219" Column="23" TopLine="196"/> + <Caret Line="224" Column="60" TopLine="209"/> </Position24> <Position25> <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="211" Column="60" TopLine="196"/> + <Caret Line="86" Column="5" TopLine="31"/> </Position25> <Position26> - <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="230" Column="3" TopLine="206"/> - </Position26> - <Position27> - <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="233" Column="3" TopLine="206"/> - </Position27> - <Position28> - <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="224" Column="60" TopLine="209"/> - </Position28> - <Position29> - <Filename Value="../../Units/MMLCore/bitmaps.pas"/> - <Caret Line="86" Column="5" TopLine="31"/> - </Position29> - <Position30> <Filename Value="../../Units/MMLCore/client.pas"/> <Caret Line="1" Column="38" TopLine="1"/> - </Position30> + </Position26> </JumpHistory> </ProjectOptions> <CompilerOptions> diff --git a/Tests/PS/SimpleBMPLoader.txt b/Tests/PS/SimpleBMPLoader.txt index 1272140..2867c6b 100644 --- a/Tests/PS/SimpleBMPLoader.txt +++ b/Tests/PS/SimpleBMPLoader.txt @@ -134,9 +134,9 @@ begin GetBitmapSize(bmpz,w,h); Writeln(inttostr(w) + '-' + inttostr(h)); SetBitmapSize(Bmpz,w div 2, h div 2); - SaveBitmap(Bmpz,'c:\Test.bmp'); - FreeBitmap(Bmpz); - Bmpz := LoadBitmap('c:\Test.bmp'); + SaveBitmap(Bmpz,'/tmp/test.bmp'); + //FreeBitmap(Bmpz); + Bmpz := LoadBitmap('/tmp/test.bmp'); SetBitmapSize(bmpz,w,h); - SaveBitmap(Bmpz,'c:\Test2.bmp'); -end. \ No newline at end of file + SaveBitmap(Bmpz,'/tmp/test2.bmp'); +end. diff --git a/Units/MMLCore/bitmaps.pas b/Units/MMLCore/bitmaps.pas index 7f2c0e7..c285221 100644 --- a/Units/MMLCore/bitmaps.pas +++ b/Units/MMLCore/bitmaps.pas @@ -1,322 +1,322 @@ -unit bitmaps; - -{$mode objfpc}{$H+} - -interface -uses - Classes, SysUtils, FPImgCanv,FPImage,IntfGraphics,graphtype,MufasaTypes ,graphics; - -type - - { TMufasaBitmap } - - TMufasaBitmap = class(TObject) - private - w,h : integer; - public - FData : PRGB32; - procedure SetSize(AWidth,AHeight : integer); - property Width : Integer read w; - property Height : Integer read h; - function SaveToFile(const FileName : string) :boolean; - procedure LoadFromFile(const FileName : string); - constructor Create; - destructor Destroy;override; - - end; - TMufasaBmpArray = Array of TMufasaBitmap; - { TMBitmaps } - TMBitmaps = class(TObject) - protected - Client : TObject; - FreeSpots : Array of integer; - BmpArray : TMufasaBmpArray; - BmpsCurr,BmpsHigh,FreeSpotsHigh,FreeSpotsLen : integer; - public - function GetBMP(Index : integer) : TMufasaBitmap; - property Bmp[Index : integer]: TMufasaBitmap read GetBMP; - function CreateBMP(w, h: integer): Integer; - function CreateMirroredBitmap(bitmap: Integer): Integer; - function CreateBMPFromFile(const Path : string) : integer; - function CreateBMPFromString(width,height : integer; Data : string) : integer; - procedure FreeBMP( Number : integer); - constructor Create(Owner : TObject); - destructor Destroy;override; - end; - - -implementation - -uses - Windowutil,paszlib,DCPbase64; -{ TMBitmaps } - - -function TMBitmaps.GetBMP(Index: integer): TMufasaBitmap; -begin - if (Index >= 0) and (Index <= BmpsCurr) then - if BmpArray[Index] <> nil then - Result := BmpArray[Index]; -end; - -function TMBitmaps.CreateBMP(w,h : integer): Integer; -begin; - if BmpsCurr < BmpsHigh then - begin; - inc(BmpsCurr); - Result := BmpsCurr; - end else if (FreeSpotsHigh > -1) then - begin; - Result := FreeSpots[FreeSpotsHigh]; - dec(FreeSpotsHigh); - end else - begin; - SetLength(BmpArray, BmpsHigh + 6); - BmpsHigh := BmpsHigh + 5; - inc(BmpsCurr); - Result := BmpsCurr; - end; - BmpArray[Result] := TMufasaBitmap.Create; - BmpArray[Result].SetSize(w,h); -end; - -function TMBitmaps.CreateMirroredBitmap(bitmap: Integer): Integer; -var - w,h : integer; - y,x : integer; - Source,Dest : PRGB32; -begin; - Source := Bmp[Bitmap].FData; - w := BmpArray[Bitmap].Width; - h := BmpArray[Bitmap].Height; - Result := CreateBMP(w,h); - Dest := BmpArray[Result].FData; - for y := (h-1) downto 0 do - for x := (w-1) downto 0 do - Dest[y*w+x] := Source[y*w+w-1-x]; -//Can be optmized, this is just proof of concept -end; - -function TMBitmaps.CreateBMPFromFile(const Path: string): integer; -begin - Result := CreateBMP(0,0); - BmpArray[result].LoadFromFile(Path); -end; - -function HexToInt(HexNum: string): LongInt;inline; -begin - Result:=StrToInt('$' + HexNum); -end; - -function TMBitmaps.CreateBMPFromString(width, height: integer; Data: string): integer; -var - I,II,x,y: LongWord; - DestLen : LongWord; - Dest,Source : string; - DestPoint, Point : PByte; - LazIntf : TLazIntfImage; - -begin; - Result := CreateBMP(width,height); - if (Data <> '') and (Length(Data) <> 6) then - begin; - Point := Pointer(BmpArray[Result].FData); - if Data[1] = 'b' then - begin; - Source := Base64DecodeStr(Copy(Data,2,Length(Data) - 1)); - Destlen := Width * Height * 3; - Setlength(Dest,DestLen); - if uncompress(PChar(Dest),Destlen,pchar(Source), Length(Source)) = Z_OK then - begin; - DestPoint := @Dest[1]; - i := 0; - ii := 2; - Dec(DestLen); - if DestLen > 2 then - begin; - while (ii < DestLen) do - Begin; - Point[i]:= DestPoint[ii+2]; - Point[i+1]:= DestPoint[ii+1]; - Point[i+2]:= DestPoint[ii]; - ii := ii + 3; - i := i + 4; - end; - Point[i] := DestPoint[1]; - Point[i+1] := DestPoint[0]; - Point[i+2] := DestPoint[ii]; - end else if (Width = 1) and (Height =1 ) then - begin; - Point[0] := DestPoint[1]; - Point[1] := DestPoint[0]; - Point[2] := DestPoint[2]; - end; - end; - end else if Data[1] = 'z' then - begin; - Destlen := Width * Height * 3 *2; - Setlength(Dest,DestLen); - ii := (Length(Data) - 1) div 2; - SetLength(Source,ii); - for i := 1 to ii do - Source[i] := Chr(HexToInt(Data[i * 2] + Data[i * 2+1])); - if uncompress(PChar(Dest),Destlen,pchar(Source), ii) = Z_OK then - begin; - ii := 1; - i := 0; - while (II < DestLen) do - begin; - Point[i+2]:= HexToInt(Dest[ii] + Dest[ii + 1]); - Point[i+1]:= HexToInt(Dest[ii+2] + Dest[ii + 3]); - Point[i]:= HexToInt(Dest[ii+4] + Dest[ii + 5]); - ii := ii + 6; - i := i + 4; - end; - end; - end else if LongWord(Length(Data)) = (Width * Height * 3 * 2) then - begin; - ii := 1; - i := 0; - Destlen := Width * Height * 3 * 2; - while (II < DestLen) do - begin; - Point[i+2]:= HexToInt(Data[ii] + Data[ii + 1]); - Point[i+1]:= HexToInt(Data[ii+2] + Data[ii + 3]); - Point[i]:= HexToInt(Data[ii+4] + Data[ii + 5]); - ii := ii + 6; - i := i + 4; - end; - end; - end else - begin; -{ if Length(data) = 6 then - FastDrawClear(Result,HexToInt(Data)) - else - Bmps[Result].Canvas.Rectangle(0,0,Width-1,Height-1);} - end; -end; - -procedure TMBitmaps.FreeBMP(Number: integer); -begin; - if Number = BmpsCurr then - Dec(BmpsCurr) - else - begin; - inc(FreeSpotsHigh); - if FreeSpotsHigh = FreeSpotsLen then - begin; - inc(FreeSpotsLen); - SetLength(FreeSpots, FreeSpotsLen); - end; - FreeSpots[FreeSpotsHigh] := Number; - end; - BmpArray[Number].Free; -end; - -function TMufasaBitmap.SaveToFile(const FileName: string): boolean; -var - rawImage : TRawImage; - Bmp : TLazIntfImage; -begin - ArrDataToRawImage(FData,Point(w,h),RawImage); -// Bmp := Graphics.TBitmap.Create; - Bmp := TLazIntfImage.Create(RawImage,true); - Bmp.SaveToFile(FileName); - Bmp.Free; -end; - -procedure TMufasaBitmap.LoadFromFile(const FileName: string); -var - LazIntf : TLazIntfImage; - RawImageDesc : TRawImageDescription; -begin - if FileExists(FileName) then - begin; - LazIntf := TLazIntfImage.Create(0,0); - RawImageDesc.Init_BPP32_B8G8R8_BIO_TTB(LazIntf.Width,LazIntf.Height); - LazIntf.DataDescription := RawImageDesc; - LazIntf.LoadFromFile(FileName); - if Assigned(FData) then - Freemem(FData); - Self.W := LazIntf.Width; - Self.H := LazIntf.Height; - FData := GetMem(Self.W*Self.H*SizeOf(TRGB32)); - Move(LazIntf.PixelData[0],FData[0],w*h*sizeOf(TRGB32)); - LazIntf.Free; - end; -end; - -constructor TMBitmaps.Create(Owner: TObject); -begin - inherited Create; - SetLength(BmpArray,50); - SetLength(FreeSpots, 50); - FreeSpotsLen := 50; - BmpsHigh := 49; - BmpsCurr := -1; - FreeSpotsHigh := -1; - Self.Client := Owner; -end; - -destructor TMBitmaps.Destroy; -begin - - inherited Destroy; -end; - - -{ TMufasaBitmap } -function Min(a,b:integer) : integer; -begin; - if a < b then - result := a - else - result := b; -end; - -procedure TMufasaBitmap.SetSize(Awidth, Aheight: integer); -var - NewData : PRGB32; - i,minw,minh : integer; -begin - if (AWidth <> w) or (AHeight <> h) then - begin; - if AWidth*AHeight <> 0 then - begin; - NewData := GetMem(AWidth * AHeight * SizeOf(TRGB32)); - FillDWord(NewData[0],AWidth*AHeight,0); - end - else - NewData := nil; - if Assigned(FData) and Assigned(NewData) and (w*H <> 0) then - begin; - minw := Min(AWidth,w); - minh := Min(AHeight,h); - for i := 0 to minh - 1 do - Move(FData[i*w],Newdata[i*AWidth],minw * SizeOf(TRGB32)); - end; - if Assigned(FData) then - FreeMem(FData); - FData := NewData; - w := AWidth; - h := AHeight; - end; -end; - -constructor TMufasaBitmap.Create; -begin - inherited Create; - FData:= nil; - w := 0; - h := 0; -end; - -destructor TMufasaBitmap.Destroy; -begin - if Assigned(FData) then - Freemem(FData,w*h*SizeOf(TRGB32)); - inherited Destroy; -end; - -end. - +unit bitmaps; + +{$mode objfpc}{$H+} + +interface +uses + Classes, SysUtils, FPImgCanv,FPImage,IntfGraphics,graphtype,MufasaTypes ,graphics; + +type + + { TMufasaBitmap } + + TMufasaBitmap = class(TObject) + private + w,h : integer; + public + FData : PRGB32; + procedure SetSize(AWidth,AHeight : integer); + property Width : Integer read w; + property Height : Integer read h; + function SaveToFile(const FileName : string) :boolean; + procedure LoadFromFile(const FileName : string); + constructor Create; + destructor Destroy;override; + end; + + TMufasaBmpArray = Array of TMufasaBitmap; + { TMBitmaps } + TMBitmaps = class(TObject) + protected + Client : TObject; + FreeSpots : Array of integer; + BmpArray : TMufasaBmpArray; + BmpsCurr,BmpsHigh,FreeSpotsHigh,FreeSpotsLen : integer; + public + function GetBMP(Index : integer) : TMufasaBitmap; + property Bmp[Index : integer]: TMufasaBitmap read GetBMP; + function CreateBMP(w, h: integer): Integer; + function CreateMirroredBitmap(bitmap: Integer): Integer; + function CreateBMPFromFile(const Path : string) : integer; + function CreateBMPFromString(width,height : integer; Data : string) : integer; + procedure FreeBMP( Number : integer); + constructor Create(Owner : TObject); + destructor Destroy;override; + end; + + +implementation + +uses + Windowutil,paszlib,DCPbase64; +{ TMBitmaps } + + +function TMBitmaps.GetBMP(Index: integer): TMufasaBitmap; +begin + if (Index >= 0) and (Index <= BmpsCurr) then + if BmpArray[Index] <> nil then + Result := BmpArray[Index]; +end; + +function TMBitmaps.CreateBMP(w,h : integer): Integer; +begin + if BmpsCurr < BmpsHigh then + begin; + inc(BmpsCurr); + Result := BmpsCurr; + end else if (FreeSpotsHigh > -1) then + begin; + Result := FreeSpots[FreeSpotsHigh]; + dec(FreeSpotsHigh); + end else + begin; + SetLength(BmpArray, BmpsHigh + 6); + BmpsHigh := BmpsHigh + 5; + inc(BmpsCurr); + Result := BmpsCurr; + end; + BmpArray[Result] := TMufasaBitmap.Create; + BmpArray[Result].SetSize(w,h); +end; + +function TMBitmaps.CreateMirroredBitmap(bitmap: Integer): Integer; +var + w,h : integer; + y,x : integer; + Source,Dest : PRGB32; +begin + Source := Bmp[Bitmap].FData; + w := BmpArray[Bitmap].Width; + h := BmpArray[Bitmap].Height; + Result := CreateBMP(w,h); + Dest := BmpArray[Result].FData; + for y := (h-1) downto 0 do + for x := (w-1) downto 0 do + Dest[y*w+x] := Source[y*w+w-1-x]; +//Can be optmized, this is just proof of concept +end; + +function TMBitmaps.CreateBMPFromFile(const Path: string): integer; +begin + Result := CreateBMP(0,0); + BmpArray[result].LoadFromFile(Path); +end; + +function HexToInt(HexNum: string): LongInt;inline; +begin + Result:=StrToInt('$' + HexNum); +end; + +function TMBitmaps.CreateBMPFromString(width, height: integer; Data: string): integer; +var + I,II,x,y: LongWord; + DestLen : LongWord; + Dest,Source : string; + DestPoint, Point : PByte; + LazIntf : TLazIntfImage; + +begin + Result := CreateBMP(width,height); + if (Data <> '') and (Length(Data) <> 6) then + begin; + Point := Pointer(BmpArray[Result].FData); + if Data[1] = 'b' then + begin; + Source := Base64DecodeStr(Copy(Data,2,Length(Data) - 1)); + Destlen := Width * Height * 3; + Setlength(Dest,DestLen); + if uncompress(PChar(Dest),Destlen,pchar(Source), Length(Source)) = Z_OK then + begin; + DestPoint := @Dest[1]; + i := 0; + ii := 2; + Dec(DestLen); + if DestLen > 2 then + begin; + while (ii < DestLen) do + Begin; + Point[i]:= DestPoint[ii+2]; + Point[i+1]:= DestPoint[ii+1]; + Point[i+2]:= DestPoint[ii]; + ii := ii + 3; + i := i + 4; + end; + Point[i] := DestPoint[1]; + Point[i+1] := DestPoint[0]; + Point[i+2] := DestPoint[ii]; + end else if (Width = 1) and (Height =1 ) then + begin; + Point[0] := DestPoint[1]; + Point[1] := DestPoint[0]; + Point[2] := DestPoint[2]; + end; + end; + end else if Data[1] = 'z' then + begin; + Destlen := Width * Height * 3 *2; + Setlength(Dest,DestLen); + ii := (Length(Data) - 1) div 2; + SetLength(Source,ii); + for i := 1 to ii do + Source[i] := Chr(HexToInt(Data[i * 2] + Data[i * 2+1])); + if uncompress(PChar(Dest),Destlen,pchar(Source), ii) = Z_OK then + begin; + ii := 1; + i := 0; + while (II < DestLen) do + begin; + Point[i+2]:= HexToInt(Dest[ii] + Dest[ii + 1]); + Point[i+1]:= HexToInt(Dest[ii+2] + Dest[ii + 3]); + Point[i]:= HexToInt(Dest[ii+4] + Dest[ii + 5]); + ii := ii + 6; + i := i + 4; + end; + end; + end else if LongWord(Length(Data)) = (Width * Height * 3 * 2) then + begin; + ii := 1; + i := 0; + Destlen := Width * Height * 3 * 2; + while (II < DestLen) do + begin; + Point[i+2]:= HexToInt(Data[ii] + Data[ii + 1]); + Point[i+1]:= HexToInt(Data[ii+2] + Data[ii + 3]); + Point[i]:= HexToInt(Data[ii+4] + Data[ii + 5]); + ii := ii + 6; + i := i + 4; + end; + end; + end else + begin; +{ if Length(data) = 6 then + FastDrawClear(Result,HexToInt(Data)) + else + Bmps[Result].Canvas.Rectangle(0,0,Width-1,Height-1);} + end; +end; + +procedure TMBitmaps.FreeBMP(Number: integer); +begin + if Number = BmpsCurr then + Dec(BmpsCurr) + else + begin; + inc(FreeSpotsHigh); + if FreeSpotsHigh = FreeSpotsLen then + begin; + inc(FreeSpotsLen); + SetLength(FreeSpots, FreeSpotsLen); + end; + FreeSpots[FreeSpotsHigh] := Number; + end; + BmpArray[Number].Free; +end; + +function TMufasaBitmap.SaveToFile(const FileName: string): boolean; +var + rawImage : TRawImage; + Bmp : TLazIntfImage; +begin + ArrDataToRawImage(FData,Point(w,h),RawImage); +// Bmp := Graphics.TBitmap.Create; + Bmp := TLazIntfImage.Create(RawImage,true); + Bmp.SaveToFile(FileName); + Bmp.Free; +end; + +procedure TMufasaBitmap.LoadFromFile(const FileName: string); +var + LazIntf : TLazIntfImage; + RawImageDesc : TRawImageDescription; +begin + if FileExists(FileName) then + begin; + LazIntf := TLazIntfImage.Create(0,0); + RawImageDesc.Init_BPP32_B8G8R8_BIO_TTB(LazIntf.Width,LazIntf.Height); + LazIntf.DataDescription := RawImageDesc; + LazIntf.LoadFromFile(FileName); + if Assigned(FData) then + Freemem(FData); + Self.W := LazIntf.Width; + Self.H := LazIntf.Height; + FData := GetMem(Self.W*Self.H*SizeOf(TRGB32)); + Move(LazIntf.PixelData[0],FData[0],w*h*sizeOf(TRGB32)); + LazIntf.Free; + end; +end; + +constructor TMBitmaps.Create(Owner: TObject); +begin + inherited Create; + SetLength(BmpArray,50); + SetLength(FreeSpots, 50); + FreeSpotsLen := 50; + BmpsHigh := 49; + BmpsCurr := -1; + FreeSpotsHigh := -1; + Self.Client := Owner; +end; + +destructor TMBitmaps.Destroy; +begin + + inherited Destroy; +end; + + +{ TMufasaBitmap } +function Min(a,b:integer) : integer; +begin + if a < b then + result := a + else + result := b; +end; + +procedure TMufasaBitmap.SetSize(Awidth, Aheight: integer); +var + NewData : PRGB32; + i,minw,minh : integer; +begin + if (AWidth <> w) or (AHeight <> h) then + begin; + if AWidth*AHeight <> 0 then + begin; + NewData := GetMem(AWidth * AHeight * SizeOf(TRGB32)); + FillDWord(NewData[0],AWidth*AHeight,0); + end + else + NewData := nil; + if Assigned(FData) and Assigned(NewData) and (w*H <> 0) then + begin; + minw := Min(AWidth,w); + minh := Min(AHeight,h); + for i := 0 to minh - 1 do + Move(FData[i*w],Newdata[i*AWidth],minw * SizeOf(TRGB32)); + end; + if Assigned(FData) then + FreeMem(FData); + FData := NewData; + w := AWidth; + h := AHeight; + end; +end; + +constructor TMufasaBitmap.Create; +begin + inherited Create; + FData:= nil; + w := 0; + h := 0; +end; + +destructor TMufasaBitmap.Destroy; +begin + if Assigned(FData) then + Freemem(FData,w*h*SizeOf(TRGB32)); + inherited Destroy; +end; + +end. +