| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753 |
- {
- Vampyre Imaging Library
- by Marek Mauder
- https://github.com/galfar/imaginglib
- https://imaginglib.sourceforge.io
- - - - - -
- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at https://mozilla.org/MPL/2.0.
- }
- { This unit contains default IO functions for reading from/writing to
- files, streams and memory.}
- unit ImagingIO;
- {$I ImagingOptions.inc}
- interface
- uses
- SysUtils, Classes, ImagingTypes, Imaging, ImagingUtility;
- type
- TMemoryIORec = record
- Data: ImagingUtility.PByteArray;
- Position: LongInt;
- Size: Int64;
- end;
- PMemoryIORec = ^TMemoryIORec;
- var
- OriginalFileIO: TIOFunctions;
- FileIO: TIOFunctions;
- StreamIO: TIOFunctions;
- MemoryIO: TIOFunctions;
- { Helper function that returns size of input (from current position to the end)
- represented by Handle (and opened and operated on by members of IOFunctions).}
- function GetInputSize(const IOFunctions: TIOFunctions; Handle: TImagingHandle): Int64;
- { Helper function that initializes TMemoryIORec with given params.}
- function PrepareMemIO(Data: Pointer; const Size: Int64): TMemoryIORec;
- { Reads one text line from input (CR+LF, CR, or LF as line delimiter).}
- function ReadLine(const IOFunctions: TIOFunctions; Handle: TImagingHandle;
- out Line: AnsiString; FailOnControlChars: Boolean = False): Boolean;
- { Writes one text line to input with optional line delimiter.}
- procedure WriteLine(const IOFunctions: TIOFunctions; Handle: TImagingHandle;
- const Line: AnsiString; const LineEnding: AnsiString = sLineBreak);
- type
- TReadMemoryStream = class(TCustomMemoryStream)
- public
- constructor Create(Data: Pointer; Size: Integer);
- class function CreateFromIOHandle(const IOFunctions: TIOFunctions; Handle: TImagingHandle): TReadMemoryStream;
- end;
- { A TStream descendant that wraps an existing TIOFunctions record and TImagingHandle.
- It translates TStream methods (Read, Write, Seek) into calls to the
- corresponding functions in the TIOFunctions record.
- Note: This stream does not own or manage the lifetime of the TImagingHandle.
- Closing the handle must be done externally using the appropriate TCloseProc.
- Note: Resizing the stream is not supported. }
- TImagingIOStream = class(TStream)
- private
- FIO: TIOFunctions;
- FHandle: TImagingHandle;
- FSize: Int64;
- protected
- function GetSize: Int64; override;
- procedure SetSize(const NewSize: Int64); override;
- public
- { Creates a stream wrapper around existing IO functions and handle.
- The handle must already be opened. The stream does NOT close the handle
- when destroyed. }
- constructor Create(const AIOFunctions: TIOFunctions; AHandle: TImagingHandle);
- function Read(var Buffer; Count: TIOReadWriteCount): TIOReadWriteCount; override;
- function Write(const Buffer; Count: TIOReadWriteCount): TIOReadWriteCount; override;
- function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
- {$IFNDEF FPC}
- function ReadByte: Byte; {$IFDEF USE_INLINE}inline;{$ENDIF}
- procedure WriteByte(Value: Byte); {$IFDEF USE_INLINE}inline;{$ENDIF}
- {$ENDIF}
- property Handle: TImagingHandle read FHandle;
- property IOFunctions: TIOFunctions read FIO;
- end;
- implementation
- const
- DefaultBufferSize = 32 * 1024;
- type
- { Based on TaaBufferedStream
- Copyright (c) Julian M Bucknall 1997, 1999 }
- TBufferedStream = class
- private
- FBuffer: PByteArray;
- FBufSize: Integer;
- FBufStart: Int64;
- FBufPos: Integer;
- FBytesInBuf: Integer;
- FSize: Int64;
- FDirty: Boolean;
- FStream: TStream;
- function GetPosition: Int64;
- function GetSize: Int64;
- procedure ReadBuffer;
- procedure WriteBuffer;
- procedure SetPosition(const Value: Int64);
- public
- constructor Create(AStream: TStream);
- destructor Destroy; override;
- function Read(var Buffer; Count: NativeInt): NativeInt;
- function Write(const Buffer; Count: NativeInt): NativeInt;
- function Seek(Offset: Int64; Origin: Word): Int64;
- procedure Commit;
- property Stream: TStream read FStream;
- property Position: Int64 read GetPosition write SetPosition;
- property Size: Int64 read GetSize;
- end;
- constructor TBufferedStream.Create(AStream: TStream);
- begin
- inherited Create;
- FStream := AStream;
- FBufSize := DefaultBufferSize;
- GetMem(FBuffer, FBufSize);
- FBufPos := 0;
- FBytesInBuf := 0;
- FBufStart := 0;
- FDirty := False;
- FSize := AStream.Size;
- end;
- destructor TBufferedStream.Destroy;
- begin
- if FBuffer <> nil then
- begin
- Commit;
- FreeMem(FBuffer);
- end;
- FStream.Position := Position; // Make sure source stream has right position
- inherited Destroy;
- end;
- function TBufferedStream.GetPosition: Int64;
- begin
- Result := FBufStart + FBufPos;
- end;
- procedure TBufferedStream.SetPosition(const Value: Int64);
- begin
- Seek(Value, soFromCurrent);
- end;
- function TBufferedStream.GetSize: Int64;
- begin
- Result := FSize;
- end;
- procedure TBufferedStream.ReadBuffer;
- var
- SeekResult: Integer;
- begin
- SeekResult := FStream.Seek(FBufStart, soBeginning);
- if SeekResult = -1 then
- raise Exception.Create('TBufferedStream.ReadBuffer: seek failed');
- FBytesInBuf := FStream.Read(FBuffer^, FBufSize);
- if FBytesInBuf <= 0 then
- raise Exception.Create('TBufferedStream.ReadBuffer: read failed');
- end;
- procedure TBufferedStream.WriteBuffer;
- var
- SeekResult: Integer;
- BytesWritten: Integer;
- begin
- SeekResult := FStream.Seek(FBufStart, soBeginning);
- if SeekResult = -1 then
- raise Exception.Create('TBufferedStream.WriteBuffer: seek failed');
- BytesWritten := FStream.Write(FBuffer^, FBytesInBuf);
- if BytesWritten <> FBytesInBuf then
- raise Exception.Create('TBufferedStream.WriteBuffer: write failed');
- end;
- procedure TBufferedStream.Commit;
- begin
- if FDirty then
- begin
- WriteBuffer;
- FDirty := False;
- end;
- end;
- function TBufferedStream.Read(var Buffer; Count: NativeInt): NativeInt;
- var
- BufAsBytes: TByteArray absolute Buffer;
- BufIdx, BytesToGo, BytesToRead: NativeInt;
- begin
- // Calculate the actual number of bytes we can read - this depends on
- // the current position and size of the stream as well as the number
- // of bytes requested.
- BytesToGo := Count;
- if FSize < (FBufStart + FBufPos + Count) then
- BytesToGo := FSize - (FBufStart + FBufPos);
- if BytesToGo <= 0 then
- begin
- Result := 0;
- Exit;
- end;
- // Remember to return the result of our calculation
- Result := BytesToGo;
- BufIdx := 0;
- if FBytesInBuf = 0 then
- ReadBuffer;
- // Calculate the number of bytes we can read prior to the loop
- BytesToRead := FBytesInBuf - FBufPos;
- if BytesToRead > BytesToGo then
- BytesToRead := BytesToGo;
- // Copy from the stream buffer to the caller's buffer
- Move(FBuffer^[FBufPos], BufAsBytes[BufIdx], BytesToRead);
- // Calculate the number of bytes still to read}
- Dec(BytesToGo, BytesToRead);
- // while we have bytes to read, read them
- while BytesToGo > 0 do
- begin
- Inc(BufIdx, BytesToRead);
- // As we've exhausted this buffer-full, advance to the next, check
- // to see whether we need to write the buffer out first
- if FDirty then
- begin
- WriteBuffer;
- FDirty := false;
- end;
- Inc(FBufStart, FBufSize);
- FBufPos := 0;
- ReadBuffer;
- // Calculate the number of bytes we can read in this cycle
- BytesToRead := FBytesInBuf;
- if BytesToRead > BytesToGo then
- BytesToRead := BytesToGo;
- // Copy from the stream buffer to the caller's buffer
- Move(FBuffer^, BufAsBytes[BufIdx], BytesToRead);
- // Calculate the number of bytes still to read
- Dec(BytesToGo, BytesToRead);
- end;
- // Remember our new position
- Inc(FBufPos, BytesToRead);
- if FBufPos = FBufSize then
- begin
- Inc(FBufStart, FBufSize);
- FBufPos := 0;
- FBytesInBuf := 0;
- end;
- end;
- function TBufferedStream.Seek(Offset: Int64; Origin: Word): Int64;
- var
- NewBufStart, NewPos: Int64;
- begin
- // Calculate the new position
- case Origin of
- soFromBeginning : NewPos := Offset;
- soFromCurrent : NewPos := FBufStart + FBufPos + Offset;
- soFromEnd : NewPos := FSize + Offset;
- else
- raise Exception.Create('TBufferedStream.Seek: invalid origin');
- end;
- if (NewPos < 0) or (NewPos > FSize) then
- begin
- //NewPos := ClampInt(NewPos, 0, FSize); don't do this - for writing
- end;
- // Calculate which page of the file we need to be at
- NewBufStart := NewPos and not Pred(FBufSize);
- // If the new page is different than the old, mark the buffer as being
- // ready to be replenished, and if need be write out any dirty data
- if NewBufStart <> FBufStart then
- begin
- if FDirty then
- begin
- WriteBuffer;
- FDirty := False;
- end;
- FBufStart := NewBufStart;
- FBytesInBuf := 0;
- end;
- // Save the new position
- FBufPos := NewPos - NewBufStart;
- Result := NewPos;
- end;
- function TBufferedStream.Write(const Buffer; Count: NativeInt): NativeInt;
- var
- BufAsBytes: TByteArray absolute Buffer;
- BufIdx, BytesToGo, BytesToWrite: NativeInt;
- begin
- // When we write to this stream we always assume that we can write the
- // requested number of bytes: if we can't (eg, the disk is full) we'll
- // get an exception somewhere eventually.
- BytesToGo := Count;
- // Remember to return the result of our calculation
- Result := BytesToGo;
- BufIdx := 0;
- if (FBytesInBuf = 0) and (FSize > FBufStart) then
- ReadBuffer;
- // Calculate the number of bytes we can write prior to the loop
- BytesToWrite := FBufSize - FBufPos;
- if BytesToWrite > BytesToGo then
- BytesToWrite := BytesToGo;
- // Copy from the caller's buffer to the stream buffer
- Move(BufAsBytes[BufIdx], FBuffer^[FBufPos], BytesToWrite);
- // Mark our stream buffer as requiring a save to the actual stream,
- // note that this will suffice for the rest of the routine as well: no
- // inner routine will turn off the dirty flag.
- FDirty := True;
- // Calculate the number of bytes still to write
- Dec(BytesToGo, BytesToWrite);
- // While we have bytes to write, write them
- while BytesToGo > 0 do
- begin
- Inc(BufIdx, BytesToWrite);
- // As we've filled this buffer, write it out to the actual stream
- // and advance to the next buffer, reading it if required
- FBytesInBuf := FBufSize;
- WriteBuffer;
- Inc(FBufStart, FBufSize);
- FBufPos := 0;
- FBytesInBuf := 0;
- if FSize > FBufStart then
- ReadBuffer;
- // Calculate the number of bytes we can write in this cycle
- BytesToWrite := FBufSize;
- if BytesToWrite > BytesToGo then
- BytesToWrite := BytesToGo;
- // Copy from the caller's buffer to our buffer
- Move(BufAsBytes[BufIdx], FBuffer^, BytesToWrite);
- // Calculate the number of bytes still to write
- Dec(BytesToGo, BytesToWrite);
- end;
- // Remember our new position
- Inc(FBufPos, BytesToWrite);
- // Make sure the count of valid bytes is correct
- if FBytesInBuf < FBufPos then
- FBytesInBuf := FBufPos;
- // Make sure the stream size is correct
- if FSize < (FBufStart + FBytesInBuf) then
- FSize := FBufStart + FBytesInBuf;
- // If we're at the end of the buffer, write it out and advance to the
- // start of the next page
- if FBufPos = FBufSize then
- begin
- WriteBuffer;
- FDirty := False;
- Inc(FBufStart, FBufSize);
- FBufPos := 0;
- FBytesInBuf := 0;
- end;
- end;
- { TImagingIOStream }
- constructor TImagingIOStream.Create(const AIOFunctions: TIOFunctions; AHandle: TImagingHandle);
- begin
- inherited Create;
- if (AHandle = nil) or
- not Assigned(AIOFunctions.Read) or
- not Assigned(AIOFunctions.Write) or
- not Assigned(AIOFunctions.Seek) or
- not Assigned(AIOFunctions.Tell) then
- begin
- raise EStreamError.Create('Invalid TIOFunctions or TImagingHandle provided');
- end;
- FIO := AIOFunctions;
- FHandle := AHandle;
- FSize := GetInputSize(FIO, FHandle);
- end;
- function TImagingIOStream.GetSize: Int64;
- begin
- Result := FSize;
- end;
- procedure TImagingIOStream.SetSize(const NewSize: Int64);
- begin
- raise EStreamError.CreateFmt('%s does not support SetSize', [ClassName]);
- end;
- function TImagingIOStream.Read(var Buffer; Count: TIOReadWriteCount): TIOReadWriteCount;
- begin
- Result := 0;
- if Count < 0 then raise EStreamError.Create('Read count cannot be negative');
- if Count = 0 then Exit;
- Result := FIO.Read(FHandle, @Buffer, Count);
- end;
- function TImagingIOStream.Write(const Buffer; Count: TIOReadWriteCount): TIOReadWriteCount;
- begin
- Result := 0;
- if Count < 0 then raise EStreamError.Create('Write count cannot be negative');
- if Count = 0 then Exit;
- Result := FIO.Write(FHandle, @Buffer, Count);
- end;
- function TImagingIOStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
- begin
- Result := FIO.Seek(FHandle, Offset, TSeekMode(Origin));
- end;
- {$IFNDEF FPC}
- function TImagingIOStream.ReadByte: Byte;
- begin
- ReadBuffer(Result, 1);
- end;
- procedure TImagingIOStream.WriteByte(Value: Byte);
- begin
- WriteBuffer(Value, 1);
- end;
- {$ENDIF}
- { File IO functions }
- function FileOpen(FileName: PChar; Mode: TOpenMode): TImagingHandle; cdecl;
- var
- Stream: TStream;
- begin
- Stream := nil;
- case Mode of
- omReadOnly: Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
- omCreate: Stream := TFileStream.Create(FileName, fmCreate);
- omReadWrite:
- begin
- if FileExists(FileName) then
- Stream := TFileStream.Create(FileName, fmOpenReadWrite or fmShareExclusive)
- else
- Stream := TFileStream.Create(FileName, fmCreate);
- end;
- end;
- Assert(Stream <> nil);
- Result := TBufferedStream.Create(Stream);
- end;
- procedure FileClose(Handle: TImagingHandle); cdecl;
- var
- Stream: TStream;
- begin
- Stream := TBufferedStream(Handle).Stream;
- TBufferedStream(Handle).Free;
- Stream.Free;
- end;
- function FileEof(Handle: TImagingHandle): Boolean; cdecl;
- begin
- Result := TBufferedStream(Handle).Position = TBufferedStream(Handle).Size;
- end;
- function FileSeek(Handle: TImagingHandle; Offset: Int64; Mode: TSeekMode): Int64; cdecl;
- begin
- Result := TBufferedStream(Handle).Seek(Offset, LongInt(Mode));
- end;
- function FileTell(Handle: TImagingHandle): Int64; cdecl;
- begin
- Result := TBufferedStream(Handle).Position;
- end;
- function FileRead(Handle: TImagingHandle; Buffer: Pointer; Count: TIOReadWriteCount): TIOReadWriteCount; cdecl;
- begin
- Result := TBufferedStream(Handle).Read(Buffer^, Count);
- end;
- function FileWrite(Handle: TImagingHandle; Buffer: Pointer; Count: TIOReadWriteCount): TIOReadWriteCount; cdecl;
- begin
- Result := TBufferedStream(Handle).Write(Buffer^, Count);
- end;
- { Stream IO functions }
- function StreamOpen(FileName: PChar; Mode: TOpenMode): TImagingHandle; cdecl;
- begin
- Result := FileName;
- end;
- procedure StreamClose(Handle: TImagingHandle); cdecl;
- begin
- end;
- function StreamEof(Handle: TImagingHandle): Boolean; cdecl;
- begin
- Result := TStream(Handle).Position = TStream(Handle).Size;
- end;
- function StreamSeek(Handle: TImagingHandle; Offset: Int64; Mode: TSeekMode): Int64; cdecl;
- begin
- Result := TStream(Handle).Seek(Offset, Word(Mode));
- end;
- function StreamTell(Handle: TImagingHandle): Int64; cdecl;
- begin
- Result := TStream(Handle).Position;
- end;
- function StreamRead(Handle: TImagingHandle; Buffer: Pointer; Count: TIOReadWriteCount):
- TIOReadWriteCount; cdecl;
- begin
- Result := TStream(Handle).Read(Buffer^, Count);
- end;
- function StreamWrite(Handle: TImagingHandle; Buffer: Pointer; Count: TIOReadWriteCount):
- TIOReadWriteCount; cdecl;
- begin
- Result := TStream(Handle).Write(Buffer^, Count);
- end;
- { Memory IO functions }
- function MemoryOpen(FileName: PChar; Mode: TOpenMode): TImagingHandle; cdecl;
- begin
- Result := FileName;
- end;
- procedure MemoryClose(Handle: TImagingHandle); cdecl;
- begin
- end;
- function MemoryEof(Handle: TImagingHandle): Boolean; cdecl;
- begin
- Result := PMemoryIORec(Handle).Position = PMemoryIORec(Handle).Size;
- end;
- function MemorySeek(Handle: TImagingHandle; Offset: Int64; Mode: TSeekMode): Int64; cdecl;
- begin
- Result := PMemoryIORec(Handle).Position;
- case Mode of
- smFromBeginning: Result := Offset;
- smFromCurrent: Result := PMemoryIORec(Handle).Position + Offset;
- smFromEnd: Result := PMemoryIORec(Handle).Size + Offset;
- end;
- //Result := ClampInt(Result, 0, PMemoryIORec(Handle).Size); don't do this - some file formats use it
- PMemoryIORec(Handle).Position := Result;
- end;
- function MemoryTell(Handle: TImagingHandle): Int64; cdecl;
- begin
- Result := PMemoryIORec(Handle).Position;
- end;
- function MemoryRead(Handle: TImagingHandle; Buffer: Pointer; Count: TIOReadWriteCount):
- TIOReadWriteCount; cdecl;
- var
- Rec: PMemoryIORec;
- begin
- Rec := PMemoryIORec(Handle);
- Result := Count;
- if Rec.Position + Count > Rec.Size then
- Result := Rec.Size - Rec.Position;
- Move(Rec.Data[Rec.Position], Buffer^, Result);
- Rec.Position := Rec.Position + Result;
- end;
- function MemoryWrite(Handle: TImagingHandle; Buffer: Pointer; Count: TIOReadWriteCount):
- TIOReadWriteCount; cdecl;
- var
- Rec: PMemoryIORec;
- begin
- Rec := PMemoryIORec(Handle);
- Result := Count;
- if Rec.Position + Count > Rec.Size then
- Result := Rec.Size - Rec.Position;
- Move(Buffer^, Rec.Data[Rec.Position], Result);
- Rec.Position := Rec.Position + Result;
- end;
- { Helper IO functions }
- function GetInputSize(const IOFunctions: TIOFunctions; Handle: TImagingHandle): Int64;
- var
- OldPos: Int64;
- begin
- OldPos := IOFunctions.Tell(Handle);
- IOFunctions.Seek(Handle, 0, smFromEnd);
- Result := IOFunctions.Tell(Handle);
- IOFunctions.Seek(Handle, OldPos, smFromBeginning);
- end;
- function PrepareMemIO(Data: Pointer; const Size: Int64): TMemoryIORec;
- begin
- Result.Data := Data;
- Result.Position := 0;
- Result.Size := Size;
- end;
- function ReadLine(const IOFunctions: TIOFunctions; Handle: TImagingHandle;
- out Line: AnsiString; FailOnControlChars: Boolean): Boolean;
- const
- MaxLine = 1024;
- var
- EolPos, Pos: Integer;
- C: AnsiChar;
- EolReached: Boolean;
- Endings: set of AnsiChar;
- begin
- Line := '';
- Pos := 0;
- EolPos := 0;
- EolReached := False;
- Endings := [#10, #13];
- Result := True;
- while not IOFunctions.Eof(Handle) do
- begin
- IOFunctions.Read(Handle, @C, SizeOf(C));
- if FailOnControlChars and (Byte(C) < $20) then
- begin
- Break;
- end;
- if not (C in Endings) then
- begin
- if EolReached then
- begin
- IOFunctions.Seek(Handle, EolPos, smFromBeginning);
- Exit;
- end
- else
- begin
- SetLength(Line, Length(Line) + 1);
- Line[Length(Line)] := C;
- end;
- end
- else if not EolReached then
- begin
- EolReached := True;
- EolPos := IOFunctions.Tell(Handle);
- end;
- Inc(Pos);
- if Pos >= MaxLine then
- begin
- Break;
- end;
- end;
- Result := False;
- IOFunctions.Seek(Handle, -Pos, smFromCurrent);
- end;
- procedure WriteLine(const IOFunctions: TIOFunctions; Handle: TImagingHandle;
- const Line: AnsiString; const LineEnding: AnsiString);
- var
- ToWrite: AnsiString;
- begin
- ToWrite := Line + LineEnding;
- IOFunctions.Write(Handle, @ToWrite[1], Length(ToWrite));
- end;
- { TReadMemoryStream }
- constructor TReadMemoryStream.Create(Data: Pointer; Size: Integer);
- begin
- SetPointer(Data, Size);
- end;
- class function TReadMemoryStream.CreateFromIOHandle(const IOFunctions: TIOFunctions; Handle: TImagingHandle): TReadMemoryStream;
- var
- Data: Pointer;
- Size: Integer;
- begin
- Size := GetInputSize(IOFunctions, Handle);
- GetMem(Data, Size);
- IOFunctions.Read(Handle, Data, Size);
- Result := TReadMemoryStream.Create(Data, Size);
- end;
- initialization
- OriginalFileIO.Open := FileOpen;
- OriginalFileIO.Close := FileClose;
- OriginalFileIO.Eof := FileEof;
- OriginalFileIO.Seek := FileSeek;
- OriginalFileIO.Tell := FileTell;
- OriginalFileIO.Read := FileRead;
- OriginalFileIO.Write := FileWrite;
- StreamIO.Open := StreamOpen;
- StreamIO.Close := StreamClose;
- StreamIO.Eof := StreamEof;
- StreamIO.Seek := StreamSeek;
- StreamIO.Tell := StreamTell;
- StreamIO.Read := StreamRead;
- StreamIO.Write := StreamWrite;
- MemoryIO.Open := MemoryOpen;
- MemoryIO.Close := MemoryClose;
- MemoryIO.Eof := MemoryEof;
- MemoryIO.Seek := MemorySeek;
- MemoryIO.Tell := MemoryTell;
- MemoryIO.Read := MemoryRead;
- MemoryIO.Write := MemoryWrite;
- ResetFileIO;
- {
- File Notes:
- -- TODOS ----------------------------------------------------
- - nothing now
- -- 0.77.3 ---------------------------------------------------
- - IO functions now have 64bit sizes and offsets.
- - Added helper classes TReadMemoryStream and TImagingIOStream.
- -- 0.77.1 ---------------------------------------------------
- - Updated IO Open functions according to changes in ImagingTypes.
- - Added ReadLine and WriteLine functions.
- -- 0.23 Changes/Bug Fixes -----------------------------------
- - Added merge between buffered read-only and write-only file
- stream adapters - TIFF saving needed both reading and writing.
- - Fixed bug causing wrong value of TBufferedWriteFile.Size
- (needed to add buffer pos to size).
- -- 0.21 Changes/Bug Fixes -----------------------------------
- - Removed TMemoryIORec.Written, use Position to get proper memory
- position (Written didn't take Seeks into account).
- - Added TBufferedReadFile and TBufferedWriteFile classes for
- buffered file reading/writing. File IO functions now use these
- classes resulting in performance increase mainly in file formats
- that read/write many small chunks.
- - Added fmShareDenyWrite to FileOpenRead. You can now read
- files opened for reading by Imaging from other apps.
- - Added GetInputSize and PrepareMemIO helper functions.
- -- 0.19 Changes/Bug Fixes -----------------------------------
- - changed behaviour of MemorySeek to act as TStream
- based Seeks
- }
- end.
|