added TLazReaderBMP to cacheable image readers, added smallint, shortint reader/writer functions, accelerated LRS writer by writing big chunks in one call

git-svn-id: trunk@8825 -
This commit is contained in:
mattias 2006-02-25 22:48:47 +00:00
parent 7f9586348a
commit e8a5d48fbd
2 changed files with 51 additions and 35 deletions

View File

@ -519,7 +519,7 @@ procedure TBitmap.ReadStream(Stream: TStream; UseSize: boolean; Size: Longint);
end; end;
var var
CacheStream: TStream; WorkStream: TStream;
StreamType: TBitmapNativeType; StreamType: TBitmapNativeType;
ReaderClass: TFPCustomImageReaderClass; ReaderClass: TFPCustomImageReaderClass;
MemStream: TCustomMemoryStream; MemStream: TCustomMemoryStream;
@ -527,24 +527,24 @@ var
OldPosition: Int64; OldPosition: Int64;
begin begin
//debugln('TBitmap.ReadStream Stream=',DbgSName(Stream),' Stream.Size=',dbgs(Stream.Size),' Stream.Position=',dbgs(Stream.Position),' UseSize=',dbgs(UseSize),' Size=',dbgs(Size)); //debugln('TBitmap.ReadStream Stream=',DbgSName(Stream),' Stream.Size=',dbgs(Stream.Size),' Stream.Position=',dbgs(Stream.Position),' UseSize=',dbgs(UseSize),' Size=',dbgs(Size));
CacheStream:=nil; WorkStream:=nil;
try try
// create mem stream if not already done (to read the image type) // create mem stream if not already done (to read the image type)
if (Stream is TCustomMemoryStream) then begin if (Stream is TCustomMemoryStream) then begin
CacheStream:=Stream; WorkStream:=Stream;
end else if UseSize then begin end else if UseSize then begin
CacheStream:=TMemoryStream.Create; WorkStream:=TMemoryStream.Create;
TMemoryStream(CacheStream).SetSize(Size); TMemoryStream(WorkStream).SetSize(Size);
CacheStream.CopyFrom(Stream,Size); WorkStream.CopyFrom(Stream,Size);
CacheStream.Position:=0; WorkStream.Position:=0;
end else begin end else begin
// size is unknown and type is not TMemoryStream // size is unknown and type is not TMemoryStream
// ToDo: create cache stream from Stream // ToDo: create cache stream from Stream
CacheStream:=Stream; WorkStream:=Stream;
end; end;
// get image type // get image type
if CacheStream is TCustomMemoryStream then begin if WorkStream is TCustomMemoryStream then begin
MemStream:=TCustomMemoryStream(CacheStream); MemStream:=TCustomMemoryStream(WorkStream);
OldPosition:=MemStream.Position; OldPosition:=MemStream.Position;
GetSize:=MemStream.Size; GetSize:=MemStream.Size;
// workaround for TMemoryStream bug, reading Size sets Position to 0 // workaround for TMemoryStream bug, reading Size sets Position to 0
@ -563,10 +563,10 @@ begin
else else
RaiseInvalidBitmapHeader; RaiseInvalidBitmapHeader;
end; end;
ReadStreamWithFPImage(CacheStream,UseSize,Size,ReaderClass); ReadStreamWithFPImage(WorkStream,UseSize,Size,ReaderClass);
finally finally
if CacheStream<>Stream then if WorkStream<>Stream then
CacheStream.Free; WorkStream.Free;
end; end;
end; end;
@ -704,13 +704,14 @@ begin
finally finally
// set save stream // set save stream
FImage.SaveStream:=NewSaveStream; FImage.SaveStream:=NewSaveStream;
if ReaderClass=TFPReaderBMP then begin if (ReaderClass=TFPReaderBMP) or (ReaderClass=TLazReaderBMP) then begin
FImage.SaveStreamType:=bnWinBitmap; FImage.SaveStreamType:=bnWinBitmap;
FImage.SaveStreamClass:=TFPWriterBMP; FImage.SaveStreamClass:=TFPWriterBMP;
end else if ReaderClass=TLazReaderXPM then begin end else if ReaderClass=TLazReaderXPM then begin
FImage.SaveStreamType:=bnXPixmap; FImage.SaveStreamType:=bnXPixmap;
FImage.SaveStreamClass:=TLazWriterXPM; FImage.SaveStreamClass:=TLazWriterXPM;
end; end;
//DebugLn('TBitmap.ReadStreamWithFPImage ',DbgSName(FImage.SaveStreamClass),' ',DbgSName(ReaderClass));
// clean up // clean up
IntfImg.Free; IntfImg.Free;
ImgReader.Free; ImgReader.Free;

View File

@ -272,9 +272,10 @@ function ConvertLRSExtendedToDouble(p: Pointer): Double;
procedure ConvertEndianBigDoubleToLRSExtended(BigEndianDouble, procedure ConvertEndianBigDoubleToLRSExtended(BigEndianDouble,
LRSExtended: Pointer); LRSExtended: Pointer);
function ReadLRSByte(s: TStream): byte;
function ReadLRSWord(s: TStream): word;
function ReadLRSShortInt(s: TStream): shortint; function ReadLRSShortInt(s: TStream): shortint;
function ReadLRSByte(s: TStream): byte;
function ReadLRSSmallInt(s: TStream): smallint;
function ReadLRSWord(s: TStream): word;
function ReadLRSInteger(s: TStream): integer; function ReadLRSInteger(s: TStream): integer;
function ReadLRSCardinal(s: TStream): cardinal; function ReadLRSCardinal(s: TStream): cardinal;
function ReadLRSInt64(s: TStream): int64; function ReadLRSInt64(s: TStream): int64;
@ -287,7 +288,7 @@ function ReadLRSEndianLittleExtendedAsDouble(s: TStream): Double;
function ReadLRSValueType(s: TStream): TValueType; function ReadLRSValueType(s: TStream): TValueType;
function ReadLRSInt64MB(s: TStream): int64;// multibyte function ReadLRSInt64MB(s: TStream): int64;// multibyte
procedure WriteLRSShortInt(s: TStream; const i: shortint); procedure WriteLRSSmallInt(s: TStream; const i: smallint);
procedure WriteLRSWord(s: TStream; const w: word); procedure WriteLRSWord(s: TStream; const w: word);
procedure WriteLRSInteger(s: TStream; const i: integer); procedure WriteLRSInteger(s: TStream; const i: integer);
procedure WriteLRSCardinal(s: TStream; const c: cardinal); procedure WriteLRSCardinal(s: TStream; const c: cardinal);
@ -2455,6 +2456,12 @@ begin
end; end;
end; end;
function ReadLRSShortInt(s: TStream): shortint;
begin
Result:=0;
s.Read(Result,1);
end;
function ReadLRSByte(s: TStream): byte; function ReadLRSByte(s: TStream): byte;
begin begin
Result:=0; Result:=0;
@ -2470,11 +2477,11 @@ begin
{$ENDIF} {$ENDIF}
end; end;
function ReadLRSShortInt(s: TStream): shortint; function ReadLRSSmallInt(s: TStream): smallint;
begin begin
Result:=0; Result:=0;
{$IFDEF FPC_BIG_ENDIAN} {$IFDEF FPC_BIG_ENDIAN}
Result:=shortint(ReadLRSWord(s)); Result:=smallint(ReadLRSWord(s));
{$ELSE} {$ELSE}
s.Read(Result,2); s.Read(Result,2);
{$ENDIF} {$ENDIF}
@ -2587,8 +2594,8 @@ var
begin begin
v:=ReadLRSValueType(s); v:=ReadLRSValueType(s);
case v of case v of
vaInt8: Result:=ReadLRSByte(s); vaInt8: Result:=ReadLRSShortInt(s);
vaInt16: Result:=ReadLRSWord(s); vaInt16: Result:=ReadLRSSmallInt(s);
vaInt32: Result:=ReadLRSInteger(s); vaInt32: Result:=ReadLRSInteger(s);
vaInt64: Result:=ReadLRSInt64(s); vaInt64: Result:=ReadLRSInt64(s);
else else
@ -2693,12 +2700,12 @@ begin
s.Write(e[0],10); s.Write(e[0],10);
end; end;
procedure WriteLRSShortInt(s: TStream; const i: shortint); procedure WriteLRSSmallInt(s: TStream; const i: SmallInt);
begin begin
{$IFDEF FPC_LITTLE_ENDIAN} {$IFDEF FPC_LITTLE_ENDIAN}
s.Write(i,2); s.Write(i,2);
{$ELSE} {$ELSE}
WriteLRSReversedShortInt(s,Word(i)); WriteLRSReversedWord(s,Word(i));
{$ENDIF} {$ENDIF}
end; end;
@ -2806,7 +2813,7 @@ begin
begin begin
b:=byte(vaInt8); b:=byte(vaInt8);
s.Write(b, 1); s.Write(b, 1);
b:=Byte(Value); b:=byte(Value);
s.Write(b, 1); s.Write(b, 1);
end else if (Value >= -32768) and (Value <= 32767) then end else if (Value >= -32768) and (Value <= 32767) then
begin begin
@ -3243,18 +3250,26 @@ var
CopyNow: LongInt; CopyNow: LongInt;
SourceBuf: PChar; SourceBuf: PChar;
begin begin
SourceBuf:=@Buffer; if Count<2*FBufSize then begin
while Count > 0 do // write a small amount of data
begin SourceBuf:=@Buffer;
CopyNow := Count; while Count > 0 do
if CopyNow > FBufSize - FBufPos then begin
CopyNow := FBufSize - FBufPos; CopyNow := Count;
Move(SourceBuf^, PChar(FBuffer)[FBufPos], CopyNow); if CopyNow > FBufSize - FBufPos then
Dec(Count, CopyNow); CopyNow := FBufSize - FBufPos;
Inc(FBufPos, CopyNow); Move(SourceBuf^, PChar(FBuffer)[FBufPos], CopyNow);
SourceBuf:=SourceBuf+CopyNow; Dec(Count, CopyNow);
if FBufPos = FBufSize then Inc(FBufPos, CopyNow);
SourceBuf:=SourceBuf+CopyNow;
if FBufPos = FBufSize then
FlushBuffer;
end;
end else begin
// write a big amount of data
if FBufPos>0 then
FlushBuffer; FlushBuffer;
FStream.WriteBuffer(Buffer, Count);
end; end;
end; end;