mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 21:59:14 +02:00
added basic TIcon reading from Colin
git-svn-id: trunk@5390 -
This commit is contained in:
parent
26b4223134
commit
ffe9052073
@ -903,7 +903,8 @@ type
|
|||||||
TBitmapNativeType = (
|
TBitmapNativeType = (
|
||||||
bnNone,
|
bnNone,
|
||||||
bnWinBitmap,
|
bnWinBitmap,
|
||||||
bnXPixmap
|
bnXPixmap,
|
||||||
|
bnIcon
|
||||||
);
|
);
|
||||||
TBitmapNativeTypes = set of TBitmapNativeType;
|
TBitmapNativeTypes = set of TBitmapNativeType;
|
||||||
|
|
||||||
@ -1109,9 +1110,11 @@ type
|
|||||||
{ TIcon }
|
{ TIcon }
|
||||||
{
|
{
|
||||||
TIcon reads and writes .ICO file format.
|
TIcon reads and writes .ICO file format.
|
||||||
! Currently it is only a TBitmap !
|
! Currently it is almost a TBitmap !
|
||||||
}
|
}
|
||||||
TIcon = class(TBitmap)
|
TIcon = class(TBitmap)
|
||||||
|
protected
|
||||||
|
procedure ReadData(Stream: TStream); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1175,6 +1178,7 @@ var
|
|||||||
function TestStreamBitmapNativeType(const AStream: TStream): TBitmapNativeType;
|
function TestStreamBitmapNativeType(const AStream: TStream): TBitmapNativeType;
|
||||||
function TestStreamIsBMP(const AStream: TStream): boolean;
|
function TestStreamIsBMP(const AStream: TStream): boolean;
|
||||||
function TestStreamIsXPM(const AStream: TStream): boolean;
|
function TestStreamIsXPM(const AStream: TStream): boolean;
|
||||||
|
function TestStreamIsIcon(const AStream: TStream): boolean;
|
||||||
|
|
||||||
function XPMToPPChar(const XPM: string): PPChar;
|
function XPMToPPChar(const XPM: string): PPChar;
|
||||||
function LazResourceXPMToPPChar(const ResourceName: string): PPChar;
|
function LazResourceXPMToPPChar(const ResourceName: string): PPChar;
|
||||||
@ -1213,7 +1217,6 @@ const
|
|||||||
***************************************************************************)
|
***************************************************************************)
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
|
||||||
function SendIntfMessage(LM_Message : integer; Sender : TObject;
|
function SendIntfMessage(LM_Message : integer; Sender : TObject;
|
||||||
Data : pointer) : integer;
|
Data : pointer) : integer;
|
||||||
begin
|
begin
|
||||||
@ -1583,6 +1586,35 @@ begin
|
|||||||
Result:='image/'+DefaultFileExt;
|
Result:='image/'+DefaultFileExt;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TIcon }
|
||||||
|
|
||||||
|
function TestStreamIsIcon(const AStream: TStream): boolean;
|
||||||
|
var
|
||||||
|
Signature: array[0..3] of char;
|
||||||
|
ReadSize: Integer;
|
||||||
|
OldPosition: TStreamSeekType;
|
||||||
|
begin
|
||||||
|
OldPosition:=AStream.Position;
|
||||||
|
ReadSize:=AStream.Read(Signature, SizeOf(Signature));
|
||||||
|
Result:=(ReadSize=SizeOf(Signature)) and (Signature=#0#0#1#0);
|
||||||
|
AStream.Position:=OldPosition;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TIcon.ReadData(Stream: TStream);
|
||||||
|
var
|
||||||
|
Size: longint;
|
||||||
|
Position: TStreamSeekType;
|
||||||
|
begin
|
||||||
|
Position := Stream.Position;
|
||||||
|
Stream.Read(Size, SizeOf(Size));
|
||||||
|
if Size = $10000 then begin // Icon starts 00 00 01 00
|
||||||
|
// Assume Icon - stream without explicit size
|
||||||
|
Stream.Position := Position;
|
||||||
|
ReadStream(Stream, false, Size);
|
||||||
|
end else
|
||||||
|
ReadStream(Stream, true, Size);
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
PicClipboardFormats:=nil;
|
PicClipboardFormats:=nil;
|
||||||
PicFileFormats:=nil;
|
PicFileFormats:=nil;
|
||||||
@ -1604,6 +1636,9 @@ end.
|
|||||||
{ =============================================================================
|
{ =============================================================================
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.132 2004/04/10 00:11:16 mattias
|
||||||
|
added basic TIcon reading from Colin
|
||||||
|
|
||||||
Revision 1.131 2004/04/03 16:47:46 mattias
|
Revision 1.131 2004/04/03 16:47:46 mattias
|
||||||
implemented converting gdkbitmap to RawImage mask
|
implemented converting gdkbitmap to RawImage mask
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@ begin
|
|||||||
Result:=bnWinBitmap
|
Result:=bnWinBitmap
|
||||||
else if TestStreamIsXPM(AStream) then
|
else if TestStreamIsXPM(AStream) then
|
||||||
Result:=bnXPixmap
|
Result:=bnXPixmap
|
||||||
|
else if TestStreamIsIcon(AStream) then
|
||||||
|
Result := bnIcon
|
||||||
else
|
else
|
||||||
Result:=bnNone;
|
Result:=bnNone;
|
||||||
end;
|
end;
|
||||||
@ -497,6 +499,7 @@ begin
|
|||||||
case StreamType of
|
case StreamType of
|
||||||
bnWinBitmap: ReaderClass:=TLazReaderBMP;
|
bnWinBitmap: ReaderClass:=TLazReaderBMP;
|
||||||
bnXPixmap: ReaderClass:=TLazReaderXPM;
|
bnXPixmap: ReaderClass:=TLazReaderXPM;
|
||||||
|
bnIcon: ReaderClass:=TLazReaderIcon;
|
||||||
else
|
else
|
||||||
RaiseInvalidBitmapHeader;
|
RaiseInvalidBitmapHeader;
|
||||||
end;
|
end;
|
||||||
@ -1193,6 +1196,9 @@ end;
|
|||||||
{ =============================================================================
|
{ =============================================================================
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.84 2004/04/10 00:11:16 mattias
|
||||||
|
added basic TIcon reading from Colin
|
||||||
|
|
||||||
Revision 1.83 2004/04/05 11:41:05 mattias
|
Revision 1.83 2004/04/05 11:41:05 mattias
|
||||||
fixed retrieving gdkbitmaps LineEnding=rileDWordBoundary
|
fixed retrieving gdkbitmaps LineEnding=rileDWordBoundary
|
||||||
|
|
||||||
|
@ -330,17 +330,30 @@ type
|
|||||||
LineBuf: PByte; // Buffer for 1 scanline. Can be Byte, Word, TColorRGB or TColorRGBA
|
LineBuf: PByte; // Buffer for 1 scanline. Can be Byte, Word, TColorRGB or TColorRGBA
|
||||||
|
|
||||||
// SetupRead will allocate the needed buffers, and read the colormap if needed.
|
// SetupRead will allocate the needed buffers, and read the colormap if needed.
|
||||||
procedure SetupRead(nPalette, nRowBits: Integer; Stream: TStream); virtual;
|
procedure SetupRead(nPalette, nRowBits: Integer; Stream: TStream;
|
||||||
|
ReadPalette: Boolean); virtual;
|
||||||
procedure ReadScanLine(Row: Integer; Stream: TStream); virtual;
|
procedure ReadScanLine(Row: Integer; Stream: TStream); virtual;
|
||||||
procedure WriteScanLine(Row: Integer; Img: TFPCustomImage); virtual;
|
procedure WriteScanLine(Row: Integer; Img: TFPCustomImage); virtual;
|
||||||
// required by TFPCustomImageReader
|
// required by TFPCustomImageReader
|
||||||
procedure InternalRead(Stream: TStream; Img: TFPCustomImage); override;
|
procedure InternalRead(Stream: TStream; Img: TFPCustomImage); override;
|
||||||
|
procedure InternalReadBody(Stream: TStream; Img: TFPCustomImage);
|
||||||
function InternalCheck(Stream: TStream) : boolean; override;
|
function InternalCheck(Stream: TStream) : boolean; override;
|
||||||
public
|
public
|
||||||
constructor Create; override;
|
constructor Create; override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TLazReaderIcon }
|
||||||
|
{ This is a FPImage writer for icon images. }
|
||||||
|
TLazReaderIcon = class (TLazReaderBMP)
|
||||||
|
private
|
||||||
|
FnIcons: Integer;
|
||||||
|
FnStartPos: TStreamSeekType;
|
||||||
|
protected
|
||||||
|
// required by TFPCustomImageReader
|
||||||
|
procedure InternalRead(Stream: TStream; Img: TFPCustomImage); override;
|
||||||
|
function InternalCheck(Stream: TStream) : boolean; override;
|
||||||
|
end;
|
||||||
|
|
||||||
function ReadCompleteStreamToString(Str: TStream; StartSize: integer): string;
|
function ReadCompleteStreamToString(Str: TStream; StartSize: integer): string;
|
||||||
procedure ReadCompleteStreamToStream(SrcStream, DestStream: TStream;
|
procedure ReadCompleteStreamToStream(SrcStream, DestStream: TStream;
|
||||||
@ -2924,7 +2937,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLazReaderBMP.SetupRead(nPalette, nRowBits: Integer; Stream: TStream);
|
procedure TLazReaderBMP.SetupRead(nPalette, nRowBits: Integer; Stream: TStream;
|
||||||
|
ReadPalette: Boolean);
|
||||||
{$ifdef VER1_0}
|
{$ifdef VER1_0}
|
||||||
type
|
type
|
||||||
tcolinfo = ARRAY [0..0] OF TColorBmpRGBA;
|
tcolinfo = ARRAY [0..0] OF TColorBmpRGBA;
|
||||||
@ -2942,20 +2956,24 @@ begin
|
|||||||
GetMem(FPalette, nPalette*SizeOf(TFPColor));
|
GetMem(FPalette, nPalette*SizeOf(TFPColor));
|
||||||
{$ifdef VER1_0}
|
{$ifdef VER1_0}
|
||||||
GetMem(ColInfo, nPalette*Sizeof(TColorBmpRGBA));
|
GetMem(ColInfo, nPalette*Sizeof(TColorBmpRGBA));
|
||||||
if BFI.biClrUsed>0 then
|
if ReadPalette then begin
|
||||||
Stream.Read(ColInfo^[0],BFI.biClrUsed*SizeOf(TColorBmpRGBA))
|
if BFI.biClrUsed>0 then
|
||||||
else // Seems to me that this is dangerous.
|
Stream.Read(ColInfo^[0],BFI.biClrUsed*SizeOf(TColorBmpRGBA))
|
||||||
Stream.Read(ColInfo^[0],nPalette*SizeOf(TColorBmpRGBA));
|
else // Seems to me that this is dangerous.
|
||||||
for i := 0 to nPalette-1 do
|
Stream.Read(ColInfo^[0],nPalette*SizeOf(TColorBmpRGBA));
|
||||||
FPalette[i] := BmpRGBAToFPColor(ColInfo^[i]);
|
for i := 0 to nPalette-1 do
|
||||||
|
FPalette[i] := BmpRGBAToFPColor(ColInfo^[i]);
|
||||||
|
end;
|
||||||
{$else}
|
{$else}
|
||||||
SetLength(ColInfo, nPalette);
|
SetLength(ColInfo, nPalette);
|
||||||
if BFI.biClrUsed>0 then
|
if ReadPalette then begin
|
||||||
Stream.Read(ColInfo[0],BFI.biClrUsed*SizeOf(TColorBmpRGBA))
|
if BFI.biClrUsed>0 then
|
||||||
else // Seems to me that this is dangerous.
|
Stream.Read(ColInfo[0],BFI.biClrUsed*SizeOf(TColorBmpRGBA))
|
||||||
Stream.Read(ColInfo[0],nPalette*SizeOf(TColorBmpRGBA));
|
else // Seems to me that this is dangerous.
|
||||||
for i := 0 to High(ColInfo) do
|
Stream.Read(ColInfo[0],nPalette*SizeOf(TColorBmpRGBA));
|
||||||
FPalette[i] := BmpRGBAToFPColor(ColInfo[i]);
|
for i := 0 to High(ColInfo) do
|
||||||
|
FPalette[i] := BmpRGBAToFPColor(ColInfo[i]);
|
||||||
|
end;
|
||||||
{$endif}
|
{$endif}
|
||||||
end
|
end
|
||||||
else if BFI.biClrUsed>0 then { Skip palette }
|
else if BFI.biClrUsed>0 then { Skip palette }
|
||||||
@ -3006,10 +3024,15 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLazReaderBMP.InternalRead(Stream: TStream; Img: TFPCustomImage);
|
procedure TLazReaderBMP.InternalRead(Stream: TStream; Img: TFPCustomImage);
|
||||||
|
begin
|
||||||
|
Stream.Read(BFI,SizeOf(BFI));
|
||||||
|
InternalReadBody(Stream, Img);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLazReaderBMP.InternalReadBody(Stream: TStream; Img: TFPCustomImage);
|
||||||
Var
|
Var
|
||||||
Row : Integer;
|
Row : Integer;
|
||||||
begin
|
begin
|
||||||
Stream.Read(BFI,SizeOf(BFI));
|
|
||||||
{ This will move past any junk after the BFI header }
|
{ This will move past any junk after the BFI header }
|
||||||
Stream.Position:=Stream.Position-TStreamSeekType(SizeOf(BFI)-BFI.biSize);
|
Stream.Position:=Stream.Position-TStreamSeekType(SizeOf(BFI)-BFI.biSize);
|
||||||
with BFI do
|
with BFI do
|
||||||
@ -3021,17 +3044,17 @@ begin
|
|||||||
end;
|
end;
|
||||||
Case BFI.biBitCount of
|
Case BFI.biBitCount of
|
||||||
1 : { Monochrome }
|
1 : { Monochrome }
|
||||||
SetupRead(2,Img.Width,Stream);
|
SetupRead(2,Img.Width,Stream,true);
|
||||||
4 :
|
4 :
|
||||||
SetupRead(16,Img.Width*4,Stream);
|
SetupRead(16,Img.Width*4,Stream,true);
|
||||||
8 :
|
8 :
|
||||||
SetupRead(256,Img.Width*8,Stream);
|
SetupRead(256,Img.Width*8,Stream,true);
|
||||||
16 :
|
16 :
|
||||||
SetupRead(0,Img.Width*8*2,Stream);
|
SetupRead(0,Img.Width*8*2,Stream,true);
|
||||||
24:
|
24:
|
||||||
SetupRead(0,Img.Width*8*3,Stream);
|
SetupRead(0,Img.Width*8*3,Stream,true);
|
||||||
32:
|
32:
|
||||||
SetupRead(0,Img.Width*8*4,Stream);
|
SetupRead(0,Img.Width*8*4,Stream,true);
|
||||||
end;
|
end;
|
||||||
Try
|
Try
|
||||||
for Row:=Img.Height-1 downto 0 do
|
for Row:=Img.Height-1 downto 0 do
|
||||||
@ -3115,6 +3138,78 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TLazReaderIcon }
|
||||||
|
|
||||||
|
type
|
||||||
|
TIconHeader = packed record
|
||||||
|
idReserved: Word; {0}
|
||||||
|
idType: Word; {1}
|
||||||
|
idCount: Word; {number of icons in file}
|
||||||
|
end;
|
||||||
|
|
||||||
|
TIconDirEntry = packed record
|
||||||
|
bWidth: Byte; {ie: 16 or 32}
|
||||||
|
bHeight: Byte; {ie: 16 or 32}
|
||||||
|
bColorCount: Byte; {number of entires in pallette table below}
|
||||||
|
bReserved: Byte; { not used = 0}
|
||||||
|
wPlanes: Word; { not used = 0}
|
||||||
|
wBitCount: Word; { not used = 0}
|
||||||
|
dwBytesInRes: Longint; {total number bytes in images including pallette data
|
||||||
|
XOR, AND and bitmap info header}
|
||||||
|
dwImageOffset: Longint; {pos of image as offset from the beginning of file}
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLazReaderIcon.InternalRead(Stream: TStream; Img: TFPCustomImage);
|
||||||
|
var
|
||||||
|
CurrentDirEntry, BestDirEntry: TIconDirEntry;
|
||||||
|
Row, Column, i: Integer;
|
||||||
|
begin
|
||||||
|
{ For the time being, read the largest and/or most colourful icon }
|
||||||
|
Stream.Read(BestDirEntry, Sizeof(BestDirEntry));
|
||||||
|
CurrentDirEntry := BestDirEntry;
|
||||||
|
for i := 2 to FnIcons do begin
|
||||||
|
Stream.Read(CurrentDirEntry, Sizeof(CurrentDirEntry));
|
||||||
|
if ((CurrentDirEntry.bWidth > BestDirEntry.bWidth)
|
||||||
|
and (CurrentDirEntry.bHeight > BestDirEntry.bHeight))
|
||||||
|
or ((CurrentDirEntry.bWidth = BestDirEntry.bWidth)
|
||||||
|
and (CurrentDirEntry.bHeight = BestDirEntry.bHeight)
|
||||||
|
and (CurrentDirEntry.dwBytesInRes > BestDirEntry.dwBytesInRes)) then
|
||||||
|
BestDirEntry := CurrentDirEntry;
|
||||||
|
end;
|
||||||
|
Stream.Position := FnStartPos + BestDirEntry.dwImageOffset;
|
||||||
|
Stream.Read(BFI,SizeOf(BFI));
|
||||||
|
BFI.biHeight := BFI.biHeight div 2; { Height field is doubled, to (sort of) accomodate mask }
|
||||||
|
InternalReadBody(Stream, Img); { Now read standard bitmap }
|
||||||
|
{ Mask immediately follows unless bitmap was 32 bit - monchrome bitmap with no header }
|
||||||
|
if BFI.biBitCount < 32 then begin
|
||||||
|
ReadSize:=((Img.Width + 31) div 32) shl 2;
|
||||||
|
SetupRead(2,Img.Width,Stream,False);
|
||||||
|
try
|
||||||
|
for Row:=Img.Height-1 downto 0 do begin
|
||||||
|
ReadScanLine(Row,Stream); // Scanline in LineBuf with Size ReadSize.
|
||||||
|
for Column:=0 to Img.Width-1 do
|
||||||
|
if ((LineBuf[Column div 8] shr (7-(Column and 7)) ) and 1) <> 0 then
|
||||||
|
img.colors[Column,Row]:=colTransparent
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FreeBufs;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{ Finally skip remaining icons }
|
||||||
|
Stream.Position := FnStartPos + BestDirEntry.dwImageOffset + BestDirEntry.dwBytesInRes;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLazReaderIcon.InternalCheck(Stream: TStream): boolean;
|
||||||
|
var
|
||||||
|
IconHeader: TIconHeader;
|
||||||
|
begin
|
||||||
|
FnStartPos := Stream.Position;
|
||||||
|
Stream.Read(IconHeader,SizeOf(IconHeader));
|
||||||
|
With IconHeader do
|
||||||
|
Result := (idReserved=0) and (idType=1);
|
||||||
|
FnIcons := IconHeader.idCount;
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
InternalInit;
|
InternalInit;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user