123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741 |
- MODULE Codecs; (** AUTHOR "TF"; PURPOSE "CODEC repository"; *)
- IMPORT
- Streams, Commands, Files, SoundDevices, Raster, Modules, Strings, Configuration, Unzip, Texts, Archives;
- CONST
- ResFailed* = -1;
- ResOk* = 0;
- ResSeekInexact* = 1;
- ImgFmtBW* = 0;
- ImgFmtGrey* = 1;
- ImgFmtRGB* = 2;
- ImgFmtRGBA* = 3;
- STError* = -1; (* e.g. when requested stream does not exist *)
- STUnknown* = 0;
- STAudio* = 1;
- STVideo* = 2;
- STImage* = 3;
- SeekByte* = 0;
- SeekSample* = 1;
- SeekKeySample* = 2;
- SeekFrame* = 3;
- SeekKeyFrame* = 4;
- TYPE
- AVStreamInfo* = RECORD
- streamType* : LONGINT;
- seekability* : SET;
- contentType* : ARRAY 16 OF CHAR;
- length* : LONGINT;
- frames* : LONGINT;
- rate*: LONGINT;
- END;
- FileInputStream* = OBJECT(Streams.Reader)
- VAR
- r : Files.Rider;
- f* : Files.File;
- streamInfo*: AVStreamInfo;
- PROCEDURE Receive(VAR buf: ARRAY OF CHAR; ofs, size, min: LONGINT; VAR len, res: LONGINT);
- BEGIN
- f.ReadBytes(r, buf, ofs, size);
- len := size - r.res;
- IF len >= min THEN res := Streams.Ok ELSE res := Streams.EOF (* end of file *) END
- END Receive;
- PROCEDURE &InitFileReader*(f : Files.File; pos: LONGINT);
- BEGIN
- InitReader(SELF.Receive, 4096);
- SELF.f := f;
- f.Set(r, pos);
- streamInfo.seekability := {SeekByte};
- END InitFileReader;
- PROCEDURE CanSetPos*(): BOOLEAN;
- BEGIN
- RETURN TRUE;
- END CanSetPos;
- PROCEDURE SetPos*(pos : LONGINT);
- BEGIN
- f.Set(r, pos);
- Reset;
- received := pos;
- END SetPos;
- END FileInputStream;
- AVDemultiplexer* = OBJECT
- (** open the demultiplexer on an input stream *)
- PROCEDURE Open*(in : Streams.Reader; VAR res : WORD);
- END Open;
- PROCEDURE GetNumberOfStreams*() : LONGINT;
- BEGIN
- RETURN 0
- END GetNumberOfStreams;
- PROCEDURE GetStreamType*(streamNr : LONGINT): LONGINT;
- BEGIN
- RETURN -1;
- END GetStreamType;
- PROCEDURE GetStreamInfo*(streamNr : LONGINT): AVStreamInfo;
- END GetStreamInfo;
- (* get stream streamNr *)
- PROCEDURE GetStream*(streamNr: LONGINT): DemuxStream;
- END GetStream;
- (* read data from streamNr, store it into buffer buf starting at offset ofs, store size bytes if possible, block if not read min bytes at least. Return number of read bytes in len and return code res *)
- (* this procedure should not be directly called - it is called by the DemuxStream object! *)
- PROCEDURE GetData*(streamNr : LONGINT; VAR buf: ARRAY OF CHAR; ofs, size, min: LONGINT; VAR len, res: LONGINT);
- END GetData;
- (* seek the streamNr to position pos (defined bz seekType), res = 0 if Ok, otherwise an error number *)
- (* this procedure should not be directly called - it is called by the DemuxStream object! *)
- PROCEDURE SetStreamPos*(streamNr : LONGINT; seekType : LONGINT; pos : LONGINT; VAR itemSize : LONGINT; VAR res : WORD);
- END SetStreamPos;
- END AVDemultiplexer;
- DemuxStream* = OBJECT(Streams.Reader)
- VAR
- demultiplexer* : AVDemultiplexer;
- streamNr* : LONGINT;
- streamInfo* : AVStreamInfo;
- PROCEDURE& Open*(demultiplexer : AVDemultiplexer; streamNr : LONGINT);
- BEGIN
- SELF.demultiplexer := demultiplexer;
- SELF.streamNr := streamNr;
- InitReader(Receive, 4096)
- END Open;
- PROCEDURE Receive(VAR buf: ARRAY OF CHAR; ofs, size, min: LONGINT; VAR len, res: LONGINT);
- BEGIN
- demultiplexer.GetData(streamNr, buf, ofs, size, min, len, res)
- END Receive;
- PROCEDURE SetPos*(pos : LONGINT);
- VAR seekType, itemSize, res: LONGINT;
- BEGIN
- seekType := SeekByte;
- demultiplexer.SetStreamPos(streamNr, seekType, pos, itemSize, res);
- Reset
- END SetPos;
- (* seek the streamNr to position pos with seekType. itemSize contains the size of the element seeked to, if known and applicable; res = 0 if Ok, otherwise an error number *)
- PROCEDURE SetPosX*(seekType : LONGINT; pos : LONGINT; VAR itemSize : LONGINT; VAR res : WORD);
- BEGIN
- demultiplexer.SetStreamPos(streamNr, seekType, pos, itemSize, res);
- Reset
- END SetPosX;
- END DemuxStream;
- AudioDecoder* = OBJECT
- (* open the decoder on a file *)
- PROCEDURE Open*(in : Streams.Reader; VAR res : WORD);
- END Open;
- PROCEDURE HasMoreData*():BOOLEAN;
- END HasMoreData;
- PROCEDURE GetAudioInfo*(VAR nofChannels, samplesPerSecond, bitsPerSample : LONGINT);
- END GetAudioInfo;
- PROCEDURE SetAudioInfo*(nofChannels, samplesPerSecond, bitsPerSample : LONGINT);
- END SetAudioInfo;
- PROCEDURE CanSeek*() : BOOLEAN;
- BEGIN RETURN FALSE
- END CanSeek;
- PROCEDURE GetCurrentSample*() : LONGINT;
- BEGIN HALT(301); RETURN 0
- END GetCurrentSample;
- PROCEDURE GetTotalSamples*() : LONGINT;
- BEGIN HALT(301); RETURN 0
- END GetTotalSamples;
- PROCEDURE GetCurrentTime*() : LONGINT;
- BEGIN HALT(301); RETURN 0
- END GetCurrentTime;
- PROCEDURE SetStreamLength*(length : LONGINT);
- END SetStreamLength;
- PROCEDURE SeekSample*(sample: LONGINT; goKeySample : BOOLEAN; VAR res : WORD);
- END SeekSample;
- PROCEDURE SeekMillisecond*(millisecond : LONGINT; goKeySample : BOOLEAN; VAR res : WORD);
- END SeekMillisecond;
- (** Prepare the next audio bytes not yet filled into a buffer *)
- PROCEDURE Next*;
- END Next;
- PROCEDURE FillBuffer*(buffer : SoundDevices.Buffer);
- END FillBuffer;
- END AudioDecoder;
- AudioEncoder* = OBJECT
- (* open the encoder *)
- PROCEDURE Open*(out : Streams.Writer; sRate, sRes, nofCh: LONGINT; VAR res : WORD);
- END Open;
- PROCEDURE Write*(buffer : SoundDevices.Buffer; VAR res : WORD);
- END Write;
- PROCEDURE Close*(VAR res : WORD);
- END Close;
- END AudioEncoder;
- VideoDecoder* = OBJECT
- (* open the decoder on a file *)
- PROCEDURE Open*(in : Streams.Reader; VAR res : WORD);
- END Open;
- PROCEDURE HasMoreData*():BOOLEAN;
- END HasMoreData;
- PROCEDURE GetVideoInfo*(VAR width, height, millisecondsPerFrame : LONGINT);
- END GetVideoInfo;
- PROCEDURE CanSeek*() : BOOLEAN;
- BEGIN RETURN FALSE
- END CanSeek;
- PROCEDURE GetCurrentFrame*() : LONGINT;
- END GetCurrentFrame;
- PROCEDURE GetCurrentTime*() : LONGINT;
- END GetCurrentTime;
- PROCEDURE SeekFrame*(frame : LONGINT; goKeyFrame : BOOLEAN; VAR res : WORD);
- END SeekFrame;
- PROCEDURE SeekMillisecond*(millisecond : LONGINT; goKeyFrame : BOOLEAN; VAR res : WORD);
- END SeekMillisecond;
- (** Prepare the next frame *)
- PROCEDURE Next*;
- END Next;
- PROCEDURE Render*(img : Raster.Image);
- END Render;
- END VideoDecoder;
- ImageDecoder* = OBJECT
- (* open the decoder on an InputStream *)
- PROCEDURE Open*(in : Streams.Reader; VAR res : WORD);
- END Open;
- PROCEDURE GetImageInfo*(VAR width, height, format, maxProgressionLevel : LONGINT);
- END GetImageInfo;
- (** Render will read and decode the image data up to progrssionLevel.
- If the progressionLevel is lower than a previously rendered progressionLevel,
- the new level can be ignored by the decoder. If no progressionLevel is set with
- SetProgressionLevel, the level is assumed to be maxProgressionLevel of the image,
- which corresponds to best image quality.
- *)
- PROCEDURE SetProgressionLevel*(progressionLevel: LONGINT);
- END SetProgressionLevel;
- (* return the image in Raster format that best matches the format *)
- PROCEDURE GetNativeImage*(VAR img : Raster.Image);
- END GetNativeImage;
- (* renders the image into the given Raster.Image at the given progressionLevel *)
- PROCEDURE Render*(img : Raster.Image);
- END Render;
- END ImageDecoder;
- ImageEncoder* = OBJECT
- (* open the encoder on a stream*)
- PROCEDURE Open*(out : Streams.Writer);
- END Open;
- PROCEDURE SetQuality*(quality : LONGINT);
- END SetQuality;
- PROCEDURE WriteImage*(img : Raster.Image; VAR res : WORD);
- END WriteImage;
- END ImageEncoder;
- TextDecoder* = OBJECT
- (* open the decoder on an InputStream *)
- PROCEDURE Open*(in : Streams.Reader; VAR res : WORD);
- END Open;
- PROCEDURE GetText*() : Texts.Text;
- BEGIN
- HALT(301); RETURN NIL
- END GetText;
- END TextDecoder;
- TextEncoder* = OBJECT
- (* open the encoder on a stream*)
- PROCEDURE Open*(out : Streams.Writer);
- END Open;
- PROCEDURE WriteText*(text : Texts.Text; VAR res : WORD);
- END WriteText;
- END TextEncoder;
- CryptoDecoder* = OBJECT
- PROCEDURE Open*(in: Streams.Reader; VAR res: WORD);
- END Open;
- PROCEDURE GetReader*(): Streams.Reader;
- END GetReader;
- END CryptoDecoder;
- CryptoEncoder* = OBJECT
- PROCEDURE Open*(out: Streams.Writer);
- END Open;
- PROCEDURE GetWriter*(): Streams.Writer;
- END GetWriter;
- END CryptoEncoder;
- (****** Animations *)
- CONST
- (** ImageDescriptor.disposeMode *)
- Unspecified* = 0;
- DoNotDispose* = 1;
- RestoreToBackground* = 2;
- RestoreToPrevious* = 3;
- (** ImageDescriptor.flags *)
- WaitForUserInput* = 0;
- TYPE
- ImageDescriptor* = OBJECT
- VAR
- left*, top*, width*, height* : LONGINT;
- image* : Raster.Image;
- delayTime* : LONGINT; (* in milliseconds *)
- disposeMode* : LONGINT;
- flags* : SET;
- previous*, next* : ImageDescriptor;
- PROCEDURE &Init*;
- BEGIN
- left := 0; top := 0; width := 0; height := 0;
- image := NIL;
- delayTime := 20; disposeMode := Unspecified;
- flags := {};
- previous := NIL; next := NIL;
- END Init;
- END ImageDescriptor;
- ImageSequence* = RECORD
- width*, height* : LONGINT;
- bgColor* : LONGINT;
- images* : ImageDescriptor;
- END;
- AnimationDecoder* = OBJECT
- (* open the decoder on an InputStream *)
- PROCEDURE Open*(in : Streams.Reader; VAR res : WORD);
- END Open;
- PROCEDURE GetImageSequence*(VAR sequence : ImageSequence; VAR res : WORD);
- END GetImageSequence;
- END AnimationDecoder;
- TYPE
- DemuxFactory = PROCEDURE () : AVDemultiplexer;
- AudioDecoderFactory = PROCEDURE () : AudioDecoder;
- AudioEncoderFactory = PROCEDURE () : AudioEncoder;
- VideoDecoderFactory = PROCEDURE () : VideoDecoder;
- ImageDecoderFactory = PROCEDURE () : ImageDecoder;
- ImageEncoderFactory = PROCEDURE () : ImageEncoder;
- TextDecoderFactory = PROCEDURE () : TextDecoder;
- TextEncoderFactory = PROCEDURE () : TextEncoder;
- CryptoDecoderFactory = PROCEDURE () : CryptoDecoder;
- CryptoEncoderFactory = PROCEDURE () : CryptoEncoder;
- AnimationDecoderFactory = PROCEDURE () : AnimationDecoder;
- PROCEDURE GetDemuxFactoryName(CONST name : ARRAY OF CHAR; VAR module , procedure : Modules.Name; VAR res : WORD);
- VAR config, factoryName, msg : ARRAY 128 OF CHAR;
- BEGIN
- res := ResFailed;
- config := "Codecs.Demultiplexer."; Strings.Append(config, name);
- Configuration.Get(config, factoryName, res);
- IF (res = Configuration.Ok) THEN
- Commands.Split(factoryName, module, procedure, res, msg);
- END
- END GetDemuxFactoryName;
- PROCEDURE GetDecoderFactoryName(CONST type, name : ARRAY OF CHAR; VAR module, procedure : Modules.Name; VAR res : WORD);
- VAR config, factoryName, msg : ARRAY 128 OF CHAR;
- BEGIN
- res := ResFailed;
- config := "Codecs.Decoder."; Strings.Append(config, type); Strings.Append(config, ".");
- Strings.Append(config, name);
- Configuration.Get(config, factoryName, res);
- IF (res = Configuration.Ok) THEN
- Commands.Split(factoryName, module, procedure, res, msg);
- END
- END GetDecoderFactoryName;
- PROCEDURE GetEncoderFactoryName(CONST type, name : ARRAY OF CHAR; VAR module, procedure : Modules.Name; VAR res : WORD);
- VAR config, factoryName, msg : ARRAY 128 OF CHAR;
- BEGIN
- res := ResFailed;
- config := "Codecs.Encoder."; Strings.Append(config, type); Strings.Append(config, ".");
- Strings.Append(config, name);
- Configuration.Get(config, factoryName, res);
- IF (res = Configuration.Ok) THEN
- Commands.Split(factoryName, module, procedure, res, msg);
- END
- END GetEncoderFactoryName;
- (** Return a registered demultiplexer e.g. "AVI" *)
- PROCEDURE GetDemultiplexer*(CONST name : ARRAY OF CHAR) : AVDemultiplexer;
- VAR
- demux : AVDemultiplexer; factory : DemuxFactory;
- moduleName, procedureName : Modules.Name; res : WORD;
- BEGIN
- demux := NIL;
- GetDemuxFactoryName(name, moduleName, procedureName, res);
- IF (res = ResOk) THEN
- GETPROCEDURE(moduleName, procedureName, factory);
- IF (factory # NIL) THEN
- demux := factory();
- END;
- END;
- RETURN demux;
- END GetDemultiplexer;
- (** Return a registered image decoder e.g. "JP2", "BMP", "PNG" *)
- PROCEDURE GetImageDecoder*(CONST name : ARRAY OF CHAR) : ImageDecoder;
- VAR
- decoder : ImageDecoder; factory : ImageDecoderFactory;
- moduleName, procedureName : Modules.Name; res : WORD;
- BEGIN
- decoder := NIL;
- GetDecoderFactoryName("Image", name, moduleName, procedureName, res);
- IF (res = ResOk) THEN
- GETPROCEDURE(moduleName, procedureName, factory);
- IF (factory # NIL) THEN
- decoder := factory();
- END;
- END;
- RETURN decoder;
- END GetImageDecoder;
- (** Return a registered image decoder e.g. "BMP" *)
- PROCEDURE GetImageEncoder*(CONST name : ARRAY OF CHAR) : ImageEncoder;
- VAR
- encoder : ImageEncoder; factory : ImageEncoderFactory;
- moduleName, procedureName : Modules.Name; res : WORD;
- BEGIN
- encoder := NIL;
- GetEncoderFactoryName("Image", name, moduleName, procedureName, res);
- IF (res = ResOk) THEN
- GETPROCEDURE(moduleName, procedureName, factory);
- IF (factory # NIL) THEN
- encoder := factory();
- END;
- END;
- RETURN encoder;
- END GetImageEncoder;
- (** Return a registered video decoder. The decoder name is typically a FourCC code e.g. "DivX" *)
- PROCEDURE GetVideoDecoder*(CONST name : ARRAY OF CHAR) : VideoDecoder;
- VAR
- decoder : VideoDecoder; factory : VideoDecoderFactory;
- moduleName, procedureName : Modules.Name; res : WORD;
- BEGIN
- decoder := NIL;
- GetDecoderFactoryName("Video", name, moduleName, procedureName, res);
- IF (res = ResOk) THEN
- GETPROCEDURE(moduleName, procedureName, factory);
- IF (factory # NIL) THEN
- decoder := factory();
- END;
- END;
- RETURN decoder;
- END GetVideoDecoder;
- (** Return a registered audio decoder e.g. "MP3" *)
- PROCEDURE GetAudioDecoder*(CONST name : ARRAY OF CHAR) : AudioDecoder;
- VAR
- decoder : AudioDecoder; factory : AudioDecoderFactory;
- moduleName, procedureName : Modules.Name; res : WORD;
- BEGIN
- decoder := NIL;
- GetDecoderFactoryName("Audio", name, moduleName, procedureName, res);
- IF (res = ResOk) THEN
- GETPROCEDURE(moduleName, procedureName, factory);
- IF (factory # NIL) THEN
- decoder := factory();
- END;
- END;
- RETURN decoder;
- END GetAudioDecoder;
- (** Return a registered audio encoder e.g. "WAV" *)
- PROCEDURE GetAudioEncoder*(CONST name : ARRAY OF CHAR) : AudioEncoder;
- VAR
- encoder : AudioEncoder; factory : AudioEncoderFactory;
- moduleName, procedureName : Modules.Name; res : WORD;
- BEGIN
- encoder := NIL;
- GetEncoderFactoryName("Audio", name, moduleName, procedureName, res);
- IF (res = ResOk) THEN
- GETPROCEDURE(moduleName, procedureName, factory);
- IF (factory # NIL) THEN
- encoder := factory();
- END;
- END;
- RETURN encoder;
- END GetAudioEncoder;
- PROCEDURE GetTextDecoder*(CONST name : ARRAY OF CHAR) : TextDecoder;
- VAR
- decoder : TextDecoder; factory : TextDecoderFactory;
- moduleName, procedureName : Modules.Name; res : WORD;
- BEGIN
- decoder := NIL;
- GetDecoderFactoryName("Text", name, moduleName, procedureName, res);
- IF (res = ResOk) THEN
- GETPROCEDURE(moduleName, procedureName, factory);
- IF (factory # NIL) THEN
- decoder := factory();
- END;
- END;
- RETURN decoder;
- END GetTextDecoder;
- (** Return a registered image decoder e.g. "BMP" *)
- PROCEDURE GetTextEncoder*(CONST name : ARRAY OF CHAR) : TextEncoder;
- VAR
- encoder : TextEncoder; factory : TextEncoderFactory;
- moduleName, procedureName : Modules.Name; res : WORD;
- BEGIN
- encoder := NIL;
- GetEncoderFactoryName("Text", name, moduleName, procedureName, res);
- IF (res = ResOk) THEN
- GETPROCEDURE(moduleName, procedureName, factory);
- IF (factory # NIL) THEN
- encoder := factory();
- END;
- END;
- RETURN encoder;
- END GetTextEncoder;
- (** Return a registered crypto decoder *)
- PROCEDURE GetCryptoDecoder*(CONST name : ARRAY OF CHAR) : CryptoDecoder;
- VAR
- decoder : CryptoDecoder; factory : CryptoDecoderFactory;
- moduleName, procedureName : Modules.Name; res : WORD;
- BEGIN
- decoder := NIL;
- GetDecoderFactoryName("Crypto", name, moduleName, procedureName, res);
- IF (res = ResOk) THEN
- GETPROCEDURE(moduleName, procedureName, factory);
- IF (factory # NIL) THEN
- decoder := factory();
- END;
- END;
- RETURN decoder;
- END GetCryptoDecoder;
- (** Return a registered crypto encoder *)
- PROCEDURE GetCryptoEncoder*(CONST name : ARRAY OF CHAR) : CryptoEncoder;
- VAR
- encoder : CryptoEncoder; factory : CryptoEncoderFactory;
- moduleName, procedureName : Modules.Name; res : WORD;
- BEGIN
- encoder := NIL;
- GetEncoderFactoryName("Crypto", name, moduleName, procedureName, res);
- IF (res = ResOk) THEN
- GETPROCEDURE(moduleName, procedureName, factory);
- IF (factory # NIL) THEN
- encoder := factory();
- END;
- END;
- RETURN encoder;
- END GetCryptoEncoder;
- (** Return a registered animation decoder e.g. "GIF", "ANI" *)
- PROCEDURE GetAnimationDecoder*(CONST name : ARRAY OF CHAR) : AnimationDecoder;
- VAR
- decoder : AnimationDecoder; factory : AnimationDecoderFactory;
- moduleName, procedureName : Modules.Name; res : WORD;
- BEGIN
- decoder := NIL;
- GetDecoderFactoryName("Animation", name, moduleName, procedureName, res);
- IF (res = ResOk) THEN
- GETPROCEDURE(moduleName, procedureName, factory);
- IF (factory # NIL) THEN
- decoder := factory();
- END;
- END;
- RETURN decoder;
- END GetAnimationDecoder;
- PROCEDURE SplitName*(CONST name : ARRAY OF CHAR; VAR protocol, filename : ARRAY OF CHAR);
- VAR pos, i : LONGINT;
- BEGIN
- pos := Strings.Pos("://", name);
- IF pos >= 0 THEN
- FOR i := 0 TO pos - 1 DO protocol[i] := name[i] END;
- protocol[pos] := 0X;
- INC(pos, 3); i := 0; WHILE name[pos] # 0X DO filename[i] := name[pos]; INC(pos); INC(i) END;
- filename[i] := 0X
- ELSE
- COPY("", protocol);
- COPY(name, filename)
- END
- END SplitName;
- PROCEDURE JoinName*(CONST protocol, filename : ARRAY OF CHAR; VAR name : ARRAY OF CHAR);
- BEGIN
- IF (protocol # "") THEN
- Strings.Concat(protocol, "://", name); Strings.Concat(name, filename, name);
- ELSE
- COPY(filename, name);
- END;
- END JoinName;
- PROCEDURE OpenInputStream*(CONST name : ARRAY OF CHAR) : Streams.Reader;
- VAR f : Files.File;
- is : FileInputStream;
- inpStream : Streams.Reader;
- r : Streams.Receiver;
- tp, protocol, filename : ARRAY 1024 OF CHAR;
- zf : Unzip.ZipFile;
- entry : Unzip.Entry;
- archive : Archives.Archive;
- res : WORD;
- BEGIN
- SplitName(name, protocol, filename);
- COPY(protocol, tp); Strings.LowerCase(tp);
- IF protocol = "" THEN
- f := Files.Old(filename);
- IF f = NIL THEN RETURN NIL END;
- NEW(is, f, 0);
- RETURN is
- ELSIF Strings.Match("*.zip", tp) THEN
- f := Files.Old(protocol);
- IF f = NIL THEN RETURN NIL END;
- NEW(zf, f, res);
- IF res = 0 THEN
- entry := zf.FindEntry(filename);
- IF entry # NIL THEN
- zf.OpenReceiver(r, entry, res);
- IF res = 0 THEN
- NEW(inpStream, r, 1024);
- RETURN inpStream
- ELSE RETURN NIL
- END
- ELSE RETURN NIL
- END
- ELSE RETURN NIL
- END
- ELSIF Strings.Match("*.skin", tp) THEN
- archive := Archives.Old(protocol, "skin");
- IF archive = NIL THEN
- RETURN NIL
- ELSE
- archive.Acquire; r := archive.OpenReceiver(filename); archive.Release;
- IF r = NIL THEN
- RETURN NIL
- ELSE
- NEW(inpStream, r, 1024);
- RETURN inpStream
- END
- END
- ELSIF Strings.Match("*.tar", tp) OR Strings.Match("*.rep", tp) THEN
- archive := Archives.Old(protocol, "tar");
- IF archive = NIL THEN
- RETURN NIL
- ELSE
- archive.Acquire; r := archive.OpenReceiver(filename); archive.Release;
- IF r = NIL THEN
- RETURN NIL
- ELSE
- NEW(inpStream, r, 1024);
- RETURN inpStream
- END
- END
- END;
- RETURN NIL
- END OpenInputStream;
- PROCEDURE OpenOutputStream*(CONST name : ARRAY OF CHAR) : Streams.Writer;
- VAR
- file : Files.File; w : Files.Writer;
- writer : Streams.Writer;
- sender : Streams.Sender;
- tp, protocol, filename : ARRAY 1024 OF CHAR;
- archive : Archives.Archive;
- BEGIN
- writer := NIL;
- SplitName(name, protocol, filename);
- COPY(protocol, tp); Strings.LowerCase(tp);
- IF protocol = "" THEN
- file := Files.New(filename);
- IF file # NIL THEN
- Files.Register(file);
- NEW(w, file, 0); writer := w;
- END
- ELSIF Strings.Match("*.skin", tp) THEN
- archive := Archives.Old(protocol, "skin");
- IF archive = NIL THEN archive := Archives.New(protocol, "skin"); END;
- IF archive # NIL THEN
- archive.Acquire; sender := archive.OpenSender(filename); archive.Release;
- IF sender # NIL THEN
- NEW(writer, sender, 1024);
- END
- END
- ELSIF Strings.Match("*.tar", tp) OR Strings.Match("*.rep", tp) THEN
- archive := Archives.Old(protocol, "tar");
- IF archive = NIL THEN archive := Archives.New(protocol, "tar"); END;
- IF archive # NIL THEN
- archive.Acquire; sender := archive.OpenSender(filename); archive.Release;
- IF sender # NIL THEN
- NEW(writer, sender, 1024);
- END
- END
- END;
- RETURN writer;
- END OpenOutputStream;
- END Codecs.
- --------------------------
- SystemTools.Free Codecs~
|