MEMCOMPR.LST 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. Listing:
  2. 1 IMPLEMENTATION MODULE MemCompress;
  3. 2 (*
  4. 3 * REPERTOIRE
  5. 4 * Release 1.6
  6. 5 * By Charles Bradford and Cole Brecheen
  7. 6 * (c) Copyright 1985-1992 PMI
  8. 7 * Green Bay, Wisconsin
  9. 8 * All rights reserved
  10. 9 * (414) 468-6040
  11. 10 *
  12. 11 * $Header: D:/logfiles/mods/memcompr.mov 1.5 10 Mar 1991 15:29:32 coleb $
  13. 12 *
  14. 13 *
  15. 14 * Written and contributed by Doug Whitfield of Hornby Island,
  16. 15 * British Columbia.
  17. 16 *
  18. 17 *)
  19. 18
  20. 19
  21. 20 IMPORT SYSTEM;
  22. 21 IMPORT LowLevel;
  23. 22 IMPORT VStorage;
  24. 23
  25. 24 VAR
  26. 25 Initialized : BOOLEAN;
  27. 26
  28. 27 PROCEDURE Init();
  29. 28 BEGIN
  30. 29 IF Initialized THEN
  31. 30 RETURN;
  32. 31 ELSE
  33. 32 Initialized := TRUE;
  34. 33 END;
  35. 34 LowLevel.Init();
  36. ***** ^ not supported yet
  37. ***** ^ not supported yet
  38. ***** ^ not supported yet
  39. 35 VStorage.Init();
  40. ***** ^ not supported yet
  41. ***** ^ not supported yet
  42. ***** ^ not supported yet
  43. 36 END Init;
  44. ***** ^ not supported yet
  45. 37
  46. 38
  47. 39 (* These procedures perform run-length coding compression and
  48. 40 decompression of memory blocks. InAddress and InSize are input
  49. 41 parameters specifing the starting address and length (in bytes)
  50. 42 of the memory block to be compressed or decompressed. If
  51. 43 OutAlloc is TRUE, OutAddress and OutSize are taken as input
  52. 44 parameters by Compress and the compressed block is put at the
  53. 45 specified location. If OutAlloc is FALSE, Compress attempts to
  54. 46 allocate memory for the compressed block. If the allocation
  55. 47 fails, the compression is abandoned and Compress returns the
  56. 48 value FALSE with ErrorFlag set to AllocationFailed. If the
  57. 49 allocation is successful, Compress returns the allocated area's
  58. 50 address and size. The maximum size of memory block it will
  59. 51 allocate is InSize bytes. If, during compression, the compressed
  60. 52 block exceeds the specified OutSize (when OutAlloc is TRUE) or
  61. 53 InSize (when OutAlloc is FALSE), the compression is abandoned and
  62. 54 Compress returns the value FALSE, with ErrorFlag set to
  63. 55 CompressedTooLarge. (A compressed block can exceed the size of
  64. 56 the uncompressed block from which it is derived if the latter
  65. 57 contains characters with ordinal value 254, as this value is used
  66. 58 as a designator for the start of a run, and isolated occurences
  67. 59 of this character must be translated into two successive
  68. 60 characters to avoid ambiguity.) If compression is successfully
  69. 61 completed, Compress returns the value TRUE with ErrorFlag set to
  70. 62 NoCompressError.
  71. 63
  72. 64 Decompress performs no error testing, and thus assumes that the
  73. 65 size of memory specified to receive the decompressed block is
  74. 66 sufficiently large. If Decompress is called with OutSize equal
  75. 67 to the value of InSize used during compression, this will be
  76. 68 true.
  77. 69
  78. 70 Compress will yield a useful degree of compression if the input
  79. 71 memory block contains runs of successive bytes containing the
  80. 72 same value. Such may be the case, for example, in CGA and EGA
  81. 73 graphics mode screen images. *)
  82. 74
  83. 75
  84. 76 TYPE
  85. 77 Address8086 =
  86. 78 RECORD
  87. 79 CASE : CARDINAL OF
  88. ***** ^ not supported yet
  89. ***** ^ 'POINTER' expected
  90. 80 1 :
  91. 81 a : SYSTEM.ADDRESS;
  92. 82 |2 :
  93. 83 b : POINTER TO CHAR;
  94. 84 END;
  95. 85 END;
  96. 86
  97. 87 VAR
  98. 88 NewCharOrd, OldCharOrd, TempOutSize: CARDINAL;
  99. 89 InCount, OutCount, RunCount, MaxRunCount, CharOrd, Index:
  100. 90 CARDINAL;
  101. 91 InAddress, OutAddress: SYSTEM.ADDRESS;
  102. 92 InCharPointer, OutCharPointer: Address8086;
  103. 93 Char: CHAR;
  104. 94
  105. 95 PROCEDURE GetChar():CARDINAL;
  106. 96 BEGIN
  107. 97 Char := InCharPointer.b^;
  108. 98 LowLevel.IncAddr( InCharPointer.a, 1 );
  109. 99 INC (InCount);
  110. 100 RETURN ORD(Char);
  111. 101 END GetChar;
  112. 102
  113. 103 PROCEDURE PutChar (CharOrd:CARDINAL);
  114. 104 BEGIN
  115. 105 Char := CHR (CharOrd);
  116. 106 OutCharPointer.b^ := Char;
  117. 107 LowLevel.IncAddr( OutCharPointer.a, 1 );
  118. 108 INC(OutCount);
  119. 109 END PutChar;
  120. 110
  121. 111 PROCEDURE CompOut (CharOrd:CARDINAL;RunCount:CARDINAL);
  122. 112 BEGIN
  123. 113 IF CharOrd = 254 THEN
  124. 114 IF RunCount > 1 THEN
  125. 115 PutChar(254); PutChar(RunCount); PutChar(254)
  126. 116 ELSE
  127. 117 PutChar(254); PutChar(254)
  128. 118 END (*IF*);
  129. 119 ELSE
  130. 120 IF RunCount = 1 THEN
  131. 121 PutChar(CharOrd)
  132. 122 ELSIF RunCount = 2 THEN
  133. 123 PutChar(CharOrd); PutChar(CharOrd)
  134. 124 ELSE
  135. 125 PutChar(254); PutChar(RunCount);PutChar(CharOrd)
  136. 126 END (*IF*);
  137. 127 END (*IF*);
  138. 128 END CompOut;
  139. 129
  140. 130 PROCEDURE Compress (InAddress: SYSTEM.ADDRESS; InSize:CARDINAL;
  141. 131 VAR OutAddress: SYSTEM.ADDRESS; VAR OutSize:CARDINAL;
  142. 132 OutAlloc:BOOLEAN):BOOLEAN;
  143. 133 BEGIN
  144. 134 ErrorFlag := Corruption;
  145. 135 IF NOT OutAlloc THEN
  146. 136 IF VStorage.DosAvail (InSize + 5) THEN
  147. 137 VStorage.DosAlloc(OutAddress, InSize + 5);
  148. 138 TempOutSize := InSize
  149. 139 ELSE
  150. 140 ErrorFlag := AllocationFailed;
  151. 141 RETURN FALSE;
  152. 142 END;
  153. 143 ELSE
  154. 144 TempOutSize := OutSize
  155. 145 END;
  156. 146 InCharPointer.a := InAddress; OutCharPointer.a := OutAddress;
  157. 147 InCount := 0; OutCount :=0;
  158. 148 OldCharOrd := GetChar();
  159. 149 LOOP
  160. 150 RunCount := 1;
  161. 151 MaxRunCount := InSize - InCount + 1;
  162. 152 IF MaxRunCount > 253 THEN MaxRunCount := 253 END;
  163. 153 LOOP
  164. 154 NewCharOrd :=GetChar();
  165. 155 IF NewCharOrd = OldCharOrd THEN
  166. 156 INC (RunCount);
  167. 157 IF RunCount = MaxRunCount THEN EXIT END
  168. 158 ELSE
  169. 159 EXIT
  170. 160 END (*IF*)
  171. 161 END (*LOOP*);
  172. 162 CompOut (OldCharOrd,RunCount);
  173. 163 IF OutCount >= TempOutSize THEN;
  174. 164 IF NOT OutAlloc THEN
  175. 165 VStorage.DosDealloc(OutAddress,InSize + 5);
  176. 166 END;
  177. 167 ErrorFlag := CompressedTooLarge;
  178. 168 RETURN FALSE
  179. 169 END;
  180. 170 OldCharOrd := NewCharOrd;
  181. 171 IF InCount = InSize THEN
  182. 172 IF RunCount # MaxRunCount THEN CompOut (OldCharOrd,1) END;
  183. 173 EXIT
  184. 174 END (*IF*)
  185. 175 END (*LOOP*);
  186. 176 IF NOT OutAlloc THEN
  187. 177 OutSize := OutCount;
  188. 178 VStorage.DosDealloc(OutCharPointer.a,InSize + 5 - OutSize);
  189. 179 END;
  190. 180 ErrorFlag := NoCompressError;
  191. 181 RETURN TRUE;
  192. 182
  193. 183 END Compress;
  194. 184
  195. 185 PROCEDURE Decompress (InAddress: SYSTEM.ADDRESS; InSize:CARDINAL;
  196. 186 OutAddress: SYSTEM.ADDRESS; OutSize:CARDINAL);
  197. 187 BEGIN
  198. 188 InCharPointer.a := InAddress; OutCharPointer.a := OutAddress;
  199. 189 InCount := 0; OutCount := 0;
  200. 190 WHILE InCount < InSize DO
  201. 191 CharOrd := GetChar();
  202. 192 IF CharOrd = 254 THEN
  203. 193 RunCount := GetChar();
  204. 194 IF RunCount = 254 THEN
  205. 195 PutChar (254)
  206. 196 ELSE
  207. 197 CharOrd := GetChar();
  208. 198 FOR Index := 1 TO RunCount DO
  209. 199 PutChar (CharOrd);
  210. 200 END (*FOR*)
  211. 201 END (*IF*);
  212. 202 ELSE
  213. 203 PutChar (CharOrd)
  214. 204 END (*IF*)
  215. 205 END (*WHILE*);
  216. 206 OutSize := OutCount;
  217. 207 END Decompress;
  218. 208
  219. 209 BEGIN
  220. 210 Initialized := FALSE;
  221. 211 Init();
  222. 212 END MemCompress.
  223. 9 errors