Codecs.Mod 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. MODULE Codecs; (** AUTHOR "TF"; PURPOSE "CODEC repository"; *)
  2. IMPORT
  3. Streams, Commands, Files, SoundDevices, Raster, Modules, Strings, Configuration, Unzip, Texts, Archives;
  4. CONST
  5. ResFailed* = -1;
  6. ResOk* = 0;
  7. ResSeekInexact* = 1;
  8. ImgFmtBW* = 0;
  9. ImgFmtGrey* = 1;
  10. ImgFmtRGB* = 2;
  11. ImgFmtRGBA* = 3;
  12. STError* = -1; (* e.g. when requested stream does not exist *)
  13. STUnknown* = 0;
  14. STAudio* = 1;
  15. STVideo* = 2;
  16. STImage* = 3;
  17. SeekByte* = 0;
  18. SeekSample* = 1;
  19. SeekKeySample* = 2;
  20. SeekFrame* = 3;
  21. SeekKeyFrame* = 4;
  22. TYPE
  23. AVStreamInfo* = RECORD
  24. streamType* : LONGINT;
  25. seekability* : SET;
  26. contentType* : ARRAY 16 OF CHAR;
  27. length* : LONGINT;
  28. frames* : LONGINT;
  29. rate*: LONGINT;
  30. END;
  31. FileInputStream* = OBJECT(Streams.Reader)
  32. VAR
  33. r : Files.Rider;
  34. f* : Files.File;
  35. streamInfo*: AVStreamInfo;
  36. PROCEDURE Receive(VAR buf: ARRAY OF CHAR; ofs, size, min: LONGINT; VAR len, res: LONGINT);
  37. BEGIN
  38. f.ReadBytes(r, buf, ofs, size);
  39. len := size - r.res;
  40. IF len >= min THEN res := Streams.Ok ELSE res := Streams.EOF (* end of file *) END
  41. END Receive;
  42. PROCEDURE &InitFileReader*(f : Files.File; pos: LONGINT);
  43. BEGIN
  44. InitReader(SELF.Receive, 4096);
  45. SELF.f := f;
  46. f.Set(r, pos);
  47. streamInfo.seekability := {SeekByte};
  48. END InitFileReader;
  49. PROCEDURE CanSetPos*(): BOOLEAN;
  50. BEGIN
  51. RETURN TRUE;
  52. END CanSetPos;
  53. PROCEDURE SetPos*(pos : LONGINT);
  54. BEGIN
  55. f.Set(r, pos);
  56. Reset;
  57. received := pos;
  58. END SetPos;
  59. END FileInputStream;
  60. AVDemultiplexer* = OBJECT
  61. (** open the demultiplexer on an input stream *)
  62. PROCEDURE Open*(in : Streams.Reader; VAR res : WORD);
  63. END Open;
  64. PROCEDURE GetNumberOfStreams*() : LONGINT;
  65. BEGIN
  66. RETURN 0
  67. END GetNumberOfStreams;
  68. PROCEDURE GetStreamType*(streamNr : LONGINT): LONGINT;
  69. BEGIN
  70. RETURN -1;
  71. END GetStreamType;
  72. PROCEDURE GetStreamInfo*(streamNr : LONGINT): AVStreamInfo;
  73. END GetStreamInfo;
  74. (* get stream streamNr *)
  75. PROCEDURE GetStream*(streamNr: LONGINT): DemuxStream;
  76. END GetStream;
  77. (* 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 *)
  78. (* this procedure should not be directly called - it is called by the DemuxStream object! *)
  79. PROCEDURE GetData*(streamNr : LONGINT; VAR buf: ARRAY OF CHAR; ofs, size, min: LONGINT; VAR len, res: LONGINT);
  80. END GetData;
  81. (* seek the streamNr to position pos (defined bz seekType), res = 0 if Ok, otherwise an error number *)
  82. (* this procedure should not be directly called - it is called by the DemuxStream object! *)
  83. PROCEDURE SetStreamPos*(streamNr : LONGINT; seekType : LONGINT; pos : LONGINT; VAR itemSize : LONGINT; VAR res : WORD);
  84. END SetStreamPos;
  85. END AVDemultiplexer;
  86. DemuxStream* = OBJECT(Streams.Reader)
  87. VAR
  88. demultiplexer* : AVDemultiplexer;
  89. streamNr* : LONGINT;
  90. streamInfo* : AVStreamInfo;
  91. PROCEDURE& Open*(demultiplexer : AVDemultiplexer; streamNr : LONGINT);
  92. BEGIN
  93. SELF.demultiplexer := demultiplexer;
  94. SELF.streamNr := streamNr;
  95. InitReader(Receive, 4096)
  96. END Open;
  97. PROCEDURE Receive(VAR buf: ARRAY OF CHAR; ofs, size, min: LONGINT; VAR len, res: LONGINT);
  98. BEGIN
  99. demultiplexer.GetData(streamNr, buf, ofs, size, min, len, res)
  100. END Receive;
  101. PROCEDURE SetPos*(pos : LONGINT);
  102. VAR seekType, itemSize, res: LONGINT;
  103. BEGIN
  104. seekType := SeekByte;
  105. demultiplexer.SetStreamPos(streamNr, seekType, pos, itemSize, res);
  106. Reset
  107. END SetPos;
  108. (* 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 *)
  109. PROCEDURE SetPosX*(seekType : LONGINT; pos : LONGINT; VAR itemSize : LONGINT; VAR res : WORD);
  110. BEGIN
  111. demultiplexer.SetStreamPos(streamNr, seekType, pos, itemSize, res);
  112. Reset
  113. END SetPosX;
  114. END DemuxStream;
  115. AudioDecoder* = OBJECT
  116. (* open the decoder on a file *)
  117. PROCEDURE Open*(in : Streams.Reader; VAR res : WORD);
  118. END Open;
  119. PROCEDURE HasMoreData*():BOOLEAN;
  120. END HasMoreData;
  121. PROCEDURE GetAudioInfo*(VAR nofChannels, samplesPerSecond, bitsPerSample : LONGINT);
  122. END GetAudioInfo;
  123. PROCEDURE SetAudioInfo*(nofChannels, samplesPerSecond, bitsPerSample : LONGINT);
  124. END SetAudioInfo;
  125. PROCEDURE CanSeek*() : BOOLEAN;
  126. BEGIN RETURN FALSE
  127. END CanSeek;
  128. PROCEDURE GetCurrentSample*() : LONGINT;
  129. BEGIN HALT(301); RETURN 0
  130. END GetCurrentSample;
  131. PROCEDURE GetTotalSamples*() : LONGINT;
  132. BEGIN HALT(301); RETURN 0
  133. END GetTotalSamples;
  134. PROCEDURE GetCurrentTime*() : LONGINT;
  135. BEGIN HALT(301); RETURN 0
  136. END GetCurrentTime;
  137. PROCEDURE SetStreamLength*(length : LONGINT);
  138. END SetStreamLength;
  139. PROCEDURE SeekSample*(sample: LONGINT; goKeySample : BOOLEAN; VAR res : WORD);
  140. END SeekSample;
  141. PROCEDURE SeekMillisecond*(millisecond : LONGINT; goKeySample : BOOLEAN; VAR res : WORD);
  142. END SeekMillisecond;
  143. (** Prepare the next audio bytes not yet filled into a buffer *)
  144. PROCEDURE Next*;
  145. END Next;
  146. PROCEDURE FillBuffer*(buffer : SoundDevices.Buffer);
  147. END FillBuffer;
  148. END AudioDecoder;
  149. AudioEncoder* = OBJECT
  150. (* open the encoder *)
  151. PROCEDURE Open*(out : Streams.Writer; sRate, sRes, nofCh: LONGINT; VAR res : WORD);
  152. END Open;
  153. PROCEDURE Write*(buffer : SoundDevices.Buffer; VAR res : WORD);
  154. END Write;
  155. PROCEDURE Close*(VAR res : WORD);
  156. END Close;
  157. END AudioEncoder;
  158. VideoDecoder* = OBJECT
  159. (* open the decoder on a file *)
  160. PROCEDURE Open*(in : Streams.Reader; VAR res : WORD);
  161. END Open;
  162. PROCEDURE HasMoreData*():BOOLEAN;
  163. END HasMoreData;
  164. PROCEDURE GetVideoInfo*(VAR width, height, millisecondsPerFrame : LONGINT);
  165. END GetVideoInfo;
  166. PROCEDURE CanSeek*() : BOOLEAN;
  167. BEGIN RETURN FALSE
  168. END CanSeek;
  169. PROCEDURE GetCurrentFrame*() : LONGINT;
  170. END GetCurrentFrame;
  171. PROCEDURE GetCurrentTime*() : LONGINT;
  172. END GetCurrentTime;
  173. PROCEDURE SeekFrame*(frame : LONGINT; goKeyFrame : BOOLEAN; VAR res : WORD);
  174. END SeekFrame;
  175. PROCEDURE SeekMillisecond*(millisecond : LONGINT; goKeyFrame : BOOLEAN; VAR res : WORD);
  176. END SeekMillisecond;
  177. (** Prepare the next frame *)
  178. PROCEDURE Next*;
  179. END Next;
  180. PROCEDURE Render*(img : Raster.Image);
  181. END Render;
  182. END VideoDecoder;
  183. ImageDecoder* = OBJECT
  184. (* open the decoder on an InputStream *)
  185. PROCEDURE Open*(in : Streams.Reader; VAR res : WORD);
  186. END Open;
  187. PROCEDURE GetImageInfo*(VAR width, height, format, maxProgressionLevel : LONGINT);
  188. END GetImageInfo;
  189. (** Render will read and decode the image data up to progrssionLevel.
  190. If the progressionLevel is lower than a previously rendered progressionLevel,
  191. the new level can be ignored by the decoder. If no progressionLevel is set with
  192. SetProgressionLevel, the level is assumed to be maxProgressionLevel of the image,
  193. which corresponds to best image quality.
  194. *)
  195. PROCEDURE SetProgressionLevel*(progressionLevel: LONGINT);
  196. END SetProgressionLevel;
  197. (* return the image in Raster format that best matches the format *)
  198. PROCEDURE GetNativeImage*(VAR img : Raster.Image);
  199. END GetNativeImage;
  200. (* renders the image into the given Raster.Image at the given progressionLevel *)
  201. PROCEDURE Render*(img : Raster.Image);
  202. END Render;
  203. END ImageDecoder;
  204. ImageEncoder* = OBJECT
  205. (* open the encoder on a stream*)
  206. PROCEDURE Open*(out : Streams.Writer);
  207. END Open;
  208. PROCEDURE SetQuality*(quality : LONGINT);
  209. END SetQuality;
  210. PROCEDURE WriteImage*(img : Raster.Image; VAR res : WORD);
  211. END WriteImage;
  212. END ImageEncoder;
  213. TextDecoder* = OBJECT
  214. (* open the decoder on an InputStream *)
  215. PROCEDURE Open*(in : Streams.Reader; VAR res : WORD);
  216. END Open;
  217. PROCEDURE GetText*() : Texts.Text;
  218. BEGIN
  219. HALT(301); RETURN NIL
  220. END GetText;
  221. END TextDecoder;
  222. TextEncoder* = OBJECT
  223. (* open the encoder on a stream*)
  224. PROCEDURE Open*(out : Streams.Writer);
  225. END Open;
  226. PROCEDURE WriteText*(text : Texts.Text; VAR res : WORD);
  227. END WriteText;
  228. END TextEncoder;
  229. CryptoDecoder* = OBJECT
  230. PROCEDURE Open*(in: Streams.Reader; VAR res: WORD);
  231. END Open;
  232. PROCEDURE GetReader*(): Streams.Reader;
  233. END GetReader;
  234. END CryptoDecoder;
  235. CryptoEncoder* = OBJECT
  236. PROCEDURE Open*(out: Streams.Writer);
  237. END Open;
  238. PROCEDURE GetWriter*(): Streams.Writer;
  239. END GetWriter;
  240. END CryptoEncoder;
  241. (****** Animations *)
  242. CONST
  243. (** ImageDescriptor.disposeMode *)
  244. Unspecified* = 0;
  245. DoNotDispose* = 1;
  246. RestoreToBackground* = 2;
  247. RestoreToPrevious* = 3;
  248. (** ImageDescriptor.flags *)
  249. WaitForUserInput* = 0;
  250. TYPE
  251. ImageDescriptor* = OBJECT
  252. VAR
  253. left*, top*, width*, height* : LONGINT;
  254. image* : Raster.Image;
  255. delayTime* : LONGINT; (* in milliseconds *)
  256. disposeMode* : LONGINT;
  257. flags* : SET;
  258. previous*, next* : ImageDescriptor;
  259. PROCEDURE &Init*;
  260. BEGIN
  261. left := 0; top := 0; width := 0; height := 0;
  262. image := NIL;
  263. delayTime := 20; disposeMode := Unspecified;
  264. flags := {};
  265. previous := NIL; next := NIL;
  266. END Init;
  267. END ImageDescriptor;
  268. ImageSequence* = RECORD
  269. width*, height* : LONGINT;
  270. bgColor* : LONGINT;
  271. images* : ImageDescriptor;
  272. END;
  273. AnimationDecoder* = OBJECT
  274. (* open the decoder on an InputStream *)
  275. PROCEDURE Open*(in : Streams.Reader; VAR res : WORD);
  276. END Open;
  277. PROCEDURE GetImageSequence*(VAR sequence : ImageSequence; VAR res : WORD);
  278. END GetImageSequence;
  279. END AnimationDecoder;
  280. TYPE
  281. DemuxFactory = PROCEDURE () : AVDemultiplexer;
  282. AudioDecoderFactory = PROCEDURE () : AudioDecoder;
  283. AudioEncoderFactory = PROCEDURE () : AudioEncoder;
  284. VideoDecoderFactory = PROCEDURE () : VideoDecoder;
  285. ImageDecoderFactory = PROCEDURE () : ImageDecoder;
  286. ImageEncoderFactory = PROCEDURE () : ImageEncoder;
  287. TextDecoderFactory = PROCEDURE () : TextDecoder;
  288. TextEncoderFactory = PROCEDURE () : TextEncoder;
  289. CryptoDecoderFactory = PROCEDURE () : CryptoDecoder;
  290. CryptoEncoderFactory = PROCEDURE () : CryptoEncoder;
  291. AnimationDecoderFactory = PROCEDURE () : AnimationDecoder;
  292. PROCEDURE GetDemuxFactoryName(CONST name : ARRAY OF CHAR; VAR module , procedure : Modules.Name; VAR res : WORD);
  293. VAR config, factoryName, msg : ARRAY 128 OF CHAR;
  294. BEGIN
  295. res := ResFailed;
  296. config := "Codecs.Demultiplexer."; Strings.Append(config, name);
  297. Configuration.Get(config, factoryName, res);
  298. IF (res = Configuration.Ok) THEN
  299. Commands.Split(factoryName, module, procedure, res, msg);
  300. END
  301. END GetDemuxFactoryName;
  302. PROCEDURE GetDecoderFactoryName(CONST type, name : ARRAY OF CHAR; VAR module, procedure : Modules.Name; VAR res : WORD);
  303. VAR config, factoryName, msg : ARRAY 128 OF CHAR;
  304. BEGIN
  305. res := ResFailed;
  306. config := "Codecs.Decoder."; Strings.Append(config, type); Strings.Append(config, ".");
  307. Strings.Append(config, name);
  308. Configuration.Get(config, factoryName, res);
  309. IF (res = Configuration.Ok) THEN
  310. Commands.Split(factoryName, module, procedure, res, msg);
  311. END
  312. END GetDecoderFactoryName;
  313. PROCEDURE GetEncoderFactoryName(CONST type, name : ARRAY OF CHAR; VAR module, procedure : Modules.Name; VAR res : WORD);
  314. VAR config, factoryName, msg : ARRAY 128 OF CHAR;
  315. BEGIN
  316. res := ResFailed;
  317. config := "Codecs.Encoder."; Strings.Append(config, type); Strings.Append(config, ".");
  318. Strings.Append(config, name);
  319. Configuration.Get(config, factoryName, res);
  320. IF (res = Configuration.Ok) THEN
  321. Commands.Split(factoryName, module, procedure, res, msg);
  322. END
  323. END GetEncoderFactoryName;
  324. (** Return a registered demultiplexer e.g. "AVI" *)
  325. PROCEDURE GetDemultiplexer*(CONST name : ARRAY OF CHAR) : AVDemultiplexer;
  326. VAR
  327. demux : AVDemultiplexer; factory : DemuxFactory;
  328. moduleName, procedureName : Modules.Name; res : WORD;
  329. BEGIN
  330. demux := NIL;
  331. GetDemuxFactoryName(name, moduleName, procedureName, res);
  332. IF (res = ResOk) THEN
  333. GETPROCEDURE(moduleName, procedureName, factory);
  334. IF (factory # NIL) THEN
  335. demux := factory();
  336. END;
  337. END;
  338. RETURN demux;
  339. END GetDemultiplexer;
  340. (** Return a registered image decoder e.g. "JP2", "BMP", "PNG" *)
  341. PROCEDURE GetImageDecoder*(CONST name : ARRAY OF CHAR) : ImageDecoder;
  342. VAR
  343. decoder : ImageDecoder; factory : ImageDecoderFactory;
  344. moduleName, procedureName : Modules.Name; res : WORD;
  345. BEGIN
  346. decoder := NIL;
  347. GetDecoderFactoryName("Image", name, moduleName, procedureName, res);
  348. IF (res = ResOk) THEN
  349. GETPROCEDURE(moduleName, procedureName, factory);
  350. IF (factory # NIL) THEN
  351. decoder := factory();
  352. END;
  353. END;
  354. RETURN decoder;
  355. END GetImageDecoder;
  356. (** Return a registered image decoder e.g. "BMP" *)
  357. PROCEDURE GetImageEncoder*(CONST name : ARRAY OF CHAR) : ImageEncoder;
  358. VAR
  359. encoder : ImageEncoder; factory : ImageEncoderFactory;
  360. moduleName, procedureName : Modules.Name; res : WORD;
  361. BEGIN
  362. encoder := NIL;
  363. GetEncoderFactoryName("Image", name, moduleName, procedureName, res);
  364. IF (res = ResOk) THEN
  365. GETPROCEDURE(moduleName, procedureName, factory);
  366. IF (factory # NIL) THEN
  367. encoder := factory();
  368. END;
  369. END;
  370. RETURN encoder;
  371. END GetImageEncoder;
  372. (** Return a registered video decoder. The decoder name is typically a FourCC code e.g. "DivX" *)
  373. PROCEDURE GetVideoDecoder*(CONST name : ARRAY OF CHAR) : VideoDecoder;
  374. VAR
  375. decoder : VideoDecoder; factory : VideoDecoderFactory;
  376. moduleName, procedureName : Modules.Name; res : WORD;
  377. BEGIN
  378. decoder := NIL;
  379. GetDecoderFactoryName("Video", name, moduleName, procedureName, res);
  380. IF (res = ResOk) THEN
  381. GETPROCEDURE(moduleName, procedureName, factory);
  382. IF (factory # NIL) THEN
  383. decoder := factory();
  384. END;
  385. END;
  386. RETURN decoder;
  387. END GetVideoDecoder;
  388. (** Return a registered audio decoder e.g. "MP3" *)
  389. PROCEDURE GetAudioDecoder*(CONST name : ARRAY OF CHAR) : AudioDecoder;
  390. VAR
  391. decoder : AudioDecoder; factory : AudioDecoderFactory;
  392. moduleName, procedureName : Modules.Name; res : WORD;
  393. BEGIN
  394. decoder := NIL;
  395. GetDecoderFactoryName("Audio", name, moduleName, procedureName, res);
  396. IF (res = ResOk) THEN
  397. GETPROCEDURE(moduleName, procedureName, factory);
  398. IF (factory # NIL) THEN
  399. decoder := factory();
  400. END;
  401. END;
  402. RETURN decoder;
  403. END GetAudioDecoder;
  404. (** Return a registered audio encoder e.g. "WAV" *)
  405. PROCEDURE GetAudioEncoder*(CONST name : ARRAY OF CHAR) : AudioEncoder;
  406. VAR
  407. encoder : AudioEncoder; factory : AudioEncoderFactory;
  408. moduleName, procedureName : Modules.Name; res : WORD;
  409. BEGIN
  410. encoder := NIL;
  411. GetEncoderFactoryName("Audio", name, moduleName, procedureName, res);
  412. IF (res = ResOk) THEN
  413. GETPROCEDURE(moduleName, procedureName, factory);
  414. IF (factory # NIL) THEN
  415. encoder := factory();
  416. END;
  417. END;
  418. RETURN encoder;
  419. END GetAudioEncoder;
  420. PROCEDURE GetTextDecoder*(CONST name : ARRAY OF CHAR) : TextDecoder;
  421. VAR
  422. decoder : TextDecoder; factory : TextDecoderFactory;
  423. moduleName, procedureName : Modules.Name; res : WORD;
  424. BEGIN
  425. decoder := NIL;
  426. GetDecoderFactoryName("Text", name, moduleName, procedureName, res);
  427. IF (res = ResOk) THEN
  428. GETPROCEDURE(moduleName, procedureName, factory);
  429. IF (factory # NIL) THEN
  430. decoder := factory();
  431. END;
  432. END;
  433. RETURN decoder;
  434. END GetTextDecoder;
  435. (** Return a registered image decoder e.g. "BMP" *)
  436. PROCEDURE GetTextEncoder*(CONST name : ARRAY OF CHAR) : TextEncoder;
  437. VAR
  438. encoder : TextEncoder; factory : TextEncoderFactory;
  439. moduleName, procedureName : Modules.Name; res : WORD;
  440. BEGIN
  441. encoder := NIL;
  442. GetEncoderFactoryName("Text", name, moduleName, procedureName, res);
  443. IF (res = ResOk) THEN
  444. GETPROCEDURE(moduleName, procedureName, factory);
  445. IF (factory # NIL) THEN
  446. encoder := factory();
  447. END;
  448. END;
  449. RETURN encoder;
  450. END GetTextEncoder;
  451. (** Return a registered crypto decoder *)
  452. PROCEDURE GetCryptoDecoder*(CONST name : ARRAY OF CHAR) : CryptoDecoder;
  453. VAR
  454. decoder : CryptoDecoder; factory : CryptoDecoderFactory;
  455. moduleName, procedureName : Modules.Name; res : WORD;
  456. BEGIN
  457. decoder := NIL;
  458. GetDecoderFactoryName("Crypto", name, moduleName, procedureName, res);
  459. IF (res = ResOk) THEN
  460. GETPROCEDURE(moduleName, procedureName, factory);
  461. IF (factory # NIL) THEN
  462. decoder := factory();
  463. END;
  464. END;
  465. RETURN decoder;
  466. END GetCryptoDecoder;
  467. (** Return a registered crypto encoder *)
  468. PROCEDURE GetCryptoEncoder*(CONST name : ARRAY OF CHAR) : CryptoEncoder;
  469. VAR
  470. encoder : CryptoEncoder; factory : CryptoEncoderFactory;
  471. moduleName, procedureName : Modules.Name; res : WORD;
  472. BEGIN
  473. encoder := NIL;
  474. GetEncoderFactoryName("Crypto", name, moduleName, procedureName, res);
  475. IF (res = ResOk) THEN
  476. GETPROCEDURE(moduleName, procedureName, factory);
  477. IF (factory # NIL) THEN
  478. encoder := factory();
  479. END;
  480. END;
  481. RETURN encoder;
  482. END GetCryptoEncoder;
  483. (** Return a registered animation decoder e.g. "GIF", "ANI" *)
  484. PROCEDURE GetAnimationDecoder*(CONST name : ARRAY OF CHAR) : AnimationDecoder;
  485. VAR
  486. decoder : AnimationDecoder; factory : AnimationDecoderFactory;
  487. moduleName, procedureName : Modules.Name; res : WORD;
  488. BEGIN
  489. decoder := NIL;
  490. GetDecoderFactoryName("Animation", name, moduleName, procedureName, res);
  491. IF (res = ResOk) THEN
  492. GETPROCEDURE(moduleName, procedureName, factory);
  493. IF (factory # NIL) THEN
  494. decoder := factory();
  495. END;
  496. END;
  497. RETURN decoder;
  498. END GetAnimationDecoder;
  499. PROCEDURE SplitName*(CONST name : ARRAY OF CHAR; VAR protocol, filename : ARRAY OF CHAR);
  500. VAR pos, i : LONGINT;
  501. BEGIN
  502. pos := Strings.Pos("://", name);
  503. IF pos >= 0 THEN
  504. FOR i := 0 TO pos - 1 DO protocol[i] := name[i] END;
  505. protocol[pos] := 0X;
  506. INC(pos, 3); i := 0; WHILE name[pos] # 0X DO filename[i] := name[pos]; INC(pos); INC(i) END;
  507. filename[i] := 0X
  508. ELSE
  509. COPY("", protocol);
  510. COPY(name, filename)
  511. END
  512. END SplitName;
  513. PROCEDURE JoinName*(CONST protocol, filename : ARRAY OF CHAR; VAR name : ARRAY OF CHAR);
  514. BEGIN
  515. IF (protocol # "") THEN
  516. Strings.Concat(protocol, "://", name); Strings.Concat(name, filename, name);
  517. ELSE
  518. COPY(filename, name);
  519. END;
  520. END JoinName;
  521. PROCEDURE OpenInputStream*(CONST name : ARRAY OF CHAR) : Streams.Reader;
  522. VAR f : Files.File;
  523. is : FileInputStream;
  524. inpStream : Streams.Reader;
  525. r : Streams.Receiver;
  526. tp, protocol, filename : ARRAY 1024 OF CHAR;
  527. zf : Unzip.ZipFile;
  528. entry : Unzip.Entry;
  529. archive : Archives.Archive;
  530. res : WORD;
  531. BEGIN
  532. SplitName(name, protocol, filename);
  533. COPY(protocol, tp); Strings.LowerCase(tp);
  534. IF protocol = "" THEN
  535. f := Files.Old(filename);
  536. IF f = NIL THEN RETURN NIL END;
  537. NEW(is, f, 0);
  538. RETURN is
  539. ELSIF Strings.Match("*.zip", tp) THEN
  540. f := Files.Old(protocol);
  541. IF f = NIL THEN RETURN NIL END;
  542. NEW(zf, f, res);
  543. IF res = 0 THEN
  544. entry := zf.FindEntry(filename);
  545. IF entry # NIL THEN
  546. zf.OpenReceiver(r, entry, res);
  547. IF res = 0 THEN
  548. NEW(inpStream, r, 1024);
  549. RETURN inpStream
  550. ELSE RETURN NIL
  551. END
  552. ELSE RETURN NIL
  553. END
  554. ELSE RETURN NIL
  555. END
  556. ELSIF Strings.Match("*.skin", tp) THEN
  557. archive := Archives.Old(protocol, "skin");
  558. IF archive = NIL THEN
  559. RETURN NIL
  560. ELSE
  561. archive.Acquire; r := archive.OpenReceiver(filename); archive.Release;
  562. IF r = NIL THEN
  563. RETURN NIL
  564. ELSE
  565. NEW(inpStream, r, 1024);
  566. RETURN inpStream
  567. END
  568. END
  569. ELSIF Strings.Match("*.tar", tp) OR Strings.Match("*.rep", tp) THEN
  570. archive := Archives.Old(protocol, "tar");
  571. IF archive = NIL THEN
  572. RETURN NIL
  573. ELSE
  574. archive.Acquire; r := archive.OpenReceiver(filename); archive.Release;
  575. IF r = NIL THEN
  576. RETURN NIL
  577. ELSE
  578. NEW(inpStream, r, 1024);
  579. RETURN inpStream
  580. END
  581. END
  582. END;
  583. RETURN NIL
  584. END OpenInputStream;
  585. PROCEDURE OpenOutputStream*(CONST name : ARRAY OF CHAR) : Streams.Writer;
  586. VAR
  587. file : Files.File; w : Files.Writer;
  588. writer : Streams.Writer;
  589. sender : Streams.Sender;
  590. tp, protocol, filename : ARRAY 1024 OF CHAR;
  591. archive : Archives.Archive;
  592. BEGIN
  593. writer := NIL;
  594. SplitName(name, protocol, filename);
  595. COPY(protocol, tp); Strings.LowerCase(tp);
  596. IF protocol = "" THEN
  597. file := Files.New(filename);
  598. IF file # NIL THEN
  599. Files.Register(file);
  600. NEW(w, file, 0); writer := w;
  601. END
  602. ELSIF Strings.Match("*.skin", tp) THEN
  603. archive := Archives.Old(protocol, "skin");
  604. IF archive = NIL THEN archive := Archives.New(protocol, "skin"); END;
  605. IF archive # NIL THEN
  606. archive.Acquire; sender := archive.OpenSender(filename); archive.Release;
  607. IF sender # NIL THEN
  608. NEW(writer, sender, 1024);
  609. END
  610. END
  611. ELSIF Strings.Match("*.tar", tp) OR Strings.Match("*.rep", tp) THEN
  612. archive := Archives.Old(protocol, "tar");
  613. IF archive = NIL THEN archive := Archives.New(protocol, "tar"); END;
  614. IF archive # NIL THEN
  615. archive.Acquire; sender := archive.OpenSender(filename); archive.Release;
  616. IF sender # NIL THEN
  617. NEW(writer, sender, 1024);
  618. END
  619. END
  620. END;
  621. RETURN writer;
  622. END OpenOutputStream;
  623. END Codecs.
  624. --------------------------
  625. SystemTools.Free Codecs~