home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / utilities / utilsc / computils / !CompUtils / Resources / Compress / Docs next >
Encoding:
Text File  |  1996-04-13  |  30.1 KB  |  664 lines

  1. ############################################################################
  2. #                                                                          #
  3. #                              Compress utility                            #
  4. #                                                                          #
  5. #==========================================================================#
  6. #                                                                          #
  7. #                              by David Radford                            #
  8. #                                                                          #
  9. #==========================================================================#
  10. #                                                                          #
  11. #     These files are a part of !CompUtils and may not be distributed      #
  12. #         separately other than as laid down in the !ReadMe file.          #
  13. #                                                                          #
  14. ############################################################################
  15.  
  16. Overview
  17. ========
  18.  
  19. Compress is a piece of code that produces compressed samples from raw
  20. linear-signed ones. There is one piece of code for each group of sample
  21. types supported (eg. Type0-2, Type6-7, etc). Unlike Expand and ExpCode, there
  22. is no universal version - this would be utterly pointless in 99.9% of cases
  23. anyway. Each version has an almost-identical user interface, meaning that
  24. any program you write can quickly take advantage of new compression formats
  25. provided in future releases of !CompUtils with little or no changes needed
  26. to your code. However, certain compression algorithms require additional
  27. data to be passed to them, so a 16-byte block has been set aside for this.
  28. The format of this 16-byte block depends on the particular algorithm, and,
  29. with the possible exception of the flags, the default values are usually
  30. acceptable.
  31.  
  32.  
  33. Input/Output
  34. ============
  35.  
  36. The Compress utility passes data to and from it using a pair of buffers.
  37. These must be provided for it by your external program, from hereon referred
  38. to as the master. Data transfers are always controlled by Compress, not the
  39. master program; Compress *requests* new blocks of raw sample data from the
  40. master,rather than having them forced upon it. Similarly, Compress
  41. *requests* the master to dispose of the compressed data in the output
  42. (destination) buffer when it becomes full.
  43.  
  44. Compress simply treats the input and output buffers as blocks of data.
  45. Whether or not you reuse these areas is up to you (thus making them buffers
  46. in the true sense). If you prefer, you could load the source sample into one
  47. or more blocks of memory then pass these one at a time to Compress.
  48. Obviously these blocks could no longer be described as buffers. For
  49. consistency the term 'buffer' will be used throughout this document since
  50. most uses of Compress will require one or the other of these blocks to be a
  51. buffer.
  52.  
  53.  
  54. The Compress header
  55. ===================
  56.  
  57. The code has a standard header through which all parameters are passed:
  58.  
  59.     +0  branch instruction to machine code routine
  60.     +4  returned reason code
  61.     +8  pointer to the source buffer (user provided)
  62.    +12  length of source buffer (user provided)
  63.    +16  pointer to the destination buffer (user provided)
  64.    +20  length of destination buffer (user provided)
  65.    +24  pointer to global workspace block (user provided)
  66.    +28  required length of global workspace, or 0
  67.    +32  pointer to phase 1 workspace block (user provided)
  68.    +36  required length of phase 1 workspace, or 0
  69.    +40  pointer to phase 2 workspace block (user provided)
  70.    +44  required length of phase 2 workspace, or 0
  71.    +48  size of source sample (user provided)
  72.    +52  number of bytes written into destination buffer
  73.    +56  sample period for output (user provided)
  74.    +60  \
  75.    +64   \_    Special data - 16 bytes
  76.    +68   /           (see below)
  77.    +72  /
  78.    +76  Amount of source processed so far
  79.    +80  Filetype for compressed samples
  80.  
  81. Only those entries listed as 'user provided' may be modified; all others are
  82. read-only and provided for information.
  83.  
  84.  
  85. Workspace, phases and passes
  86. ============================
  87.  
  88. Compression is a two-phase process. First the entire sample is scanned from
  89. start to finish to determine important information about the sample, then
  90. Compress works its way through the sample a second time, performing the
  91. actual compression. In addition, the scanning phase (phase 1) may consist of
  92. zero or more passes. (A pass is one complete run through the sample.) There
  93. is usually only one pass in the scanning phase, and there is *always*
  94. one pass (no more or less) in the compression phase. Note that the scanning
  95. phase may not need to scan the sample at all (ie. just perform
  96. initialisation), in which case no source data is requested until sometime
  97. in the compression phase.
  98.  
  99. Compress provides one reason code to tell you that it needs to perform
  100. another pass of the sample (4), and another reason code to tell you it has
  101. completed the scanning phase (3). In either case you should arrange matters
  102. so that the next source block read is from the start of the file.
  103.  
  104. Compress requires a certain amount of addition workspace. Three blocks
  105. must be supplied: global, phase 1 and phase 2. The global workspace must be
  106. available from the start of the operation to its completion. The phase 1
  107. workspace must be available from the start of the operation to the end of
  108. the scanning phase (ie. reason code 3). The phase 2 workspace must be
  109. available from the start of the compression phase (ie. after reason code 3)
  110. to the completion of the operation (reason code 0).
  111.  
  112. The global workspace must be claimed before an operation begins. The phase 1
  113. workspace only needs to be claimed if Compress specifically requests it
  114. using reason code 7. The sizes needed are given in the header; if a block of
  115. workspace is not needed, its length is given as zero. When Compress returns a
  116. reason code of 3 (end of scanning phase) you should then claim the phase 2
  117. workspace. You are free to release the phase 1 workspace (if there is any)
  118. at this point if this will help. (You cannot claim the phase 2 workspace
  119. before this point because its length may not have been determined.)
  120.  
  121.  
  122. Using Compress
  123. ==============
  124.  
  125. The source file is compressed by setting the value at +4 to zero, then
  126. repeatedly calling the location +0 and examining the reason code returned
  127. at +4 to see what action needs to be taken. Typical actions are refilling
  128. the source buffer or outputting the contents of the destination buffer.
  129.  
  130. The master program (ie. the one calling the decompression routine) must
  131. respond to the reason code returned in the way outlined below. There is no
  132. need to call the machine code again immediately, and it may be used quite
  133. happily by repeated calls from the polling loop of a multitasking
  134. application. This is how !Compress works. If you want to do this, then make
  135. sure the buffers are fairly small ie. 16K or so to avoid soaking up too
  136. much processor time.
  137.  
  138. If your program decides to abort the operation for some reason, you MUST
  139. ensure that the reason code is at some stage reset to zero before calling
  140. the machine code routine again (otherwise it will attempt to carry on where
  141. it left off, with disastrous consequences).
  142.  
  143. Note that all source buffers passed, except the last one, must be completely
  144. full. Another way of looking at this is to say that the word at +12 gives
  145. the amount of data actually stored in the source buffer, or that +8 and +12
  146. describe a block of data to be decompressed. Destination buffers will always
  147. be completely full when returned to the master, with the exception of the
  148. very last buffer which may only be partially full (though never completely
  149. empty).
  150.  
  151. When starting a new operation, there is no need to provide a source buffer
  152. until Compress actually asks for one by means of reason code 1. Equally,
  153. there is no need to provide a destination buffer until phase 1 is complete
  154. (which you will be informed of via reason code 3).
  155.  
  156. Compress may seem a little complicated to use at first, but it is really
  157. quite straight-forward. The complexity arrises from its flexibility. It is
  158. recommended that you work your way through one of the example programs to
  159. get a better understanding of the way it works.
  160.  
  161.  
  162. The code - Technical details
  163. ============================
  164.  
  165. (Basic and C programmers can ignore all this information.)
  166.  
  167. On entry, R14 contains the return address and R13 must point to a full,
  168. descending stack with space for at least 32 registers. On exit, registers
  169. R0-R12 and R14 will have been corrupted, and the value at +32 will give a
  170. reason code as detailed below. The flags will be corrupted (except for mode
  171. and interrupt), but no SWIs are called so it will operate in any environment
  172. (including machines without a proper operating system). A copy of the reason
  173. code will be returned in R0 to make life easier for you.
  174.  
  175. If you intend to use Compress on an Arm6-based machine (or later) other than
  176. an Acorn computer then you should ensure you are using the 26-bit
  177. programmer's model rather than the 32-bit one, since Compress assumes the
  178. flags and PC are combined into register R15.
  179.  
  180. There is a potential problem when Compress is being used in IRQ mode (or FIQ
  181. mode for that matter) with interrupts enabled, since R14_irq can suddenly
  182. become corrupt. Since R14 is extensively used as a subroutine link register
  183. this can be fairly annoying. The solution is to change the ARM to either to
  184. SVC or USR mode before calling compress. Obviously this problem only applies
  185. when trying to use Compress from interrupt code, and will not affect
  186. programs written in Basic or C.
  187.  
  188.  
  189. Reason codes
  190. ============
  191.  
  192. Below is a description of the meanings of the various reason codes that may
  193. be returned from Compress, together with information on what action should
  194. be taken. In general, reason codes 0-4 are normal operations, 5-7 are 'soft'
  195. errors (from which a sufficiently capable master program can recover without
  196. having to abort the operation), and 8 upwards are 'hard' errors (which must
  197. always cause the operation to abort).
  198.  
  199.  
  200.   0  The operation has now finished.
  201.  
  202.      There is *no* data in the destination buffer, even though the value at
  203.      +52 (the amount of data in the buffer) may be non-zero. In fact, the
  204.      value at +52 is a copy of the value last returned with reason code 2
  205.      *unless* that buffer was completely full in which case +52 is zero.
  206.  
  207.      There is a very good reason for this, though it may not be clear. If
  208.      your program is designed so that it only saves the destination buffer
  209.      on reason code 2 *if* the buffer is completely full, then, on reason
  210.      code 0, the amount of data still to be written is given in +52, and
  211.      the data in the buffer is undamaged. A use for this may seem a little
  212.      obscure - the feature is present only because Compress shares some
  213.      code with Expand.
  214.      
  215.      After this reason code no more calls to Compress need to be made, and
  216.      any remaining workspace can be freed. Since +4 is now set to zero, any
  217.      future calls will start a *new* operation.
  218.  
  219.  
  220.   1  Source buffer request.
  221.  
  222.      Compress returns this reason code when it wants the master to provide
  223.      it with a new block of source data. You should transfer some data from
  224.      the source file to a convenient block of memory, set +8 to point to it
  225.      and +12 to give the length of it, then call Compress again. Compress
  226.      treats +8 and +12 as read-only fields from its point of view, so you
  227.      don't have to keep resetting these if you are reusing the same block of
  228.      memory. Note that the last buffer does not have to be completely full -
  229.      Compress knows automatically when the end has been reached from the
  230.      sample length given in the header and ignores any further source data.
  231.  
  232.      No copy is made of the data, but copies *are* taken of +8 and +12,
  233.      which makes it impossible to move the source buffer while it is in use.
  234.      Reason codes 1, 3 and 4 are the only time during an operation when the
  235.      position and size of this buffer can be changed, since it is never in
  236.      use at this point.
  237.  
  238.      No source buffer needs to be provided to Compress until the first time
  239.      reason code 1 is returned. (Before this, +8 and +12 are considered to
  240.      be undefined and can be changed as you see fit.) You can expect this
  241.      event sometime between starting the operation and receiving reason code
  242.      3, though it could easily occur after reason code 3 if the particular
  243.      version of Compress has no need of a scanning phase.
  244.  
  245.      By the way, this reason code is *only* for providing a new source
  246.      buffer. You should not attempt to access the destination buffer, and
  247.      the value at +52 will be meaningless. Reason code 2 is used for
  248.      dealing with the destination buffer.
  249.      
  250.      If you find it useful, +76 tells you how much data you have already
  251.      sent. If you want to calculate the percentage of compression done, use
  252.      the formula:
  253.  
  254.                             I
  255.         Percentage = 100 * ---
  256.                             S
  257.  
  258.      where I is the amount of source processed so far (ie. the contents of
  259.      +76) and S is the length of the source sample (ie. the contents of
  260.      +48).
  261.  
  262.  
  263.   2  The destination buffer has become full.
  264.  
  265.      Compress returns this reason code when it has a block of data for you
  266.      to output. This data is held in the destination buffer, which (with the
  267.      exception of the last block returned) will always be completely full.
  268.      The last buffer returned may be completely full or partially full but
  269.      never completely empty.
  270.  
  271.      Your program should dispose of the data in whatever manner seems fit
  272.      (eg. copy it to disc) then call the Compress routine again. If you
  273.      wish, before invoking the routine again your program may also change
  274.      the buffer pointer and length fields at offsets +16 and +20
  275.      respectively. This is one of the two occasions when you may safely do
  276.      this; the other is on reason code 3 (which is always returned before
  277.      any attempt is made by Compress to access the destination buffer).
  278.  
  279.      The value at +76 (the number of source bytes processed so far) *may*
  280.      have been updated (depending on the code in use), so you could use this
  281.      to calculate the percentage done so far (eg. for the hourglass).
  282.  
  283.      Note that the number of bytes in the destination buffer is given by
  284.      +52. This will usually (but not always) be equal to the value at +20
  285.      (the buffer size). Always use +52 instead.
  286.      
  287.  
  288.   3  End of scanning phase.
  289.  
  290.      The scanning phase has now been completed. It is possible that no
  291.      source buffer requests (reason code 1) have been made at this point, so
  292.      you should be careful about any assumptions you make.
  293.      
  294.      At this point you must claim the phase 2 workspace using the length
  295.      provided in +44 (unless the length is zero in which case no workspace
  296.      is needed). You cannot claim the workspace until this point - the
  297.      size may have to be calculated during the scanning phase. If you want
  298.      to save on memory you can of course release the phase 1 workspace,
  299.      since it will no longer be needed.
  300.      
  301.      No output will have been made yet, so there is no need to set up a
  302.      destination buffer until this reason code is received. The situation
  303.      will change shortly after returning control to Compress, so you *must*
  304.      now make sure the buffer is present.
  305.  
  306.      You should arrange matters so that the source block passed on the next
  307.      occurance of reason code 1 is from the start of the sample. For
  308.      example, if the source is a file on disc then you should set the file
  309.      position back to the start of the file. The address and length of the
  310.      source buffer can be changed at the same time if need be.
  311.      
  312.      After receiving this reason code (which you will always get, barring
  313.      errors) you may alter the destination buffer pointer and length at
  314.      offsets +16 and +20. The only other times you may alter these values
  315.      are after the utility has finished filling the destination buffer
  316.      (ie. on reason code 2). Note that copies are taken of +16 and +20 so
  317.      it is not possible to move or resize the destination buffer except on
  318.      reason code 2.
  319.  
  320.      The value at +56 is a single byte given the sample period of the sample
  321.      in microseconds. This information is stored in the file at the time of
  322.      compression, and is otherwise ignored by Expand and Compress, so
  323.      *could* be used to store other information if absolutely necessary.
  324.      (With type 0 samples it must be non-zero.) Many programs using Expand
  325.      expect it to be the sample period though, and you may get odd results
  326.      from such programs if you use it for anything else.
  327.  
  328.  
  329.   4  Next pass warning - another pass of the source sample is needed
  330.   
  331.      Only occurs during phase 1, and not all versions of Compress will need
  332.      to generate this reason code. The only action that needs to be taken is
  333.      to arrange that future reads made with reason code 1 are from the start
  334.      of the sample again. For example, if the source is a file on disc, then
  335.      this reason code should be used to reset the file pointer to the start
  336.      of the file.
  337.  
  338.  
  339.   5  Soft error - source buffer was invalid
  340.  
  341.      This reason code is only returned if there is a bug in your program,
  342.      and should not occur under normal circumstances. It occurs if an
  343.      invalid source buffer was passed after a request for a new source
  344.      buffer (reason code 1). The only check performed on the buffer is that
  345.      the length is not negative and is non-zero.
  346.  
  347.      You should either correct the problem and repeat the call, or abort
  348.      the operation.
  349.  
  350.  
  351.   6  Soft error - destination buffer was invalid
  352.  
  353.      This reason code is only returned if there is a bug in your program,
  354.      and should not occur under normal circumstances. It occurs if an
  355.      invalid destination buffer was passed after a request for a new
  356.      destination buffer (reason code 2). The only check performed on the
  357.      buffer is that the length is not negative and is non-zero.
  358.  
  359.      You should either correct the problem and repeat the call, or abort
  360.      the operation.
  361.  
  362.  
  363.   7  Instruction to set up the phase 1 workspace
  364.      
  365.      This reason code is returned sometime between starting the operation
  366.      and the end of the scanning phase. It instructs you to set up
  367.      suitable phase 1 workspace using the length given at +36. Until you
  368.      receive this reason code, the word at +36 is undefined, so no claim
  369.      could be made before starting the operation.
  370.      
  371.      Some compressors may not need phase 1 workspace, in which case they
  372.      will never return this value, and the value at +36 will always be
  373.      zero. If you do receive this reason code, the value at +36 will
  374.      definitely be non-zero, and will remain valid until the start of
  375.      the next operation.
  376.  
  377.  
  378.   8  Hard error - undefined
  379.   
  380.      This error is undefined at present. The operation should be aborted.
  381.      It should never occur in code from this particular release of
  382.      !CompUtils. Note that Expand *does* have a use for this reason code.
  383.  
  384.  
  385. Filetypes        
  386. =========
  387.  
  388. The filetype I use for compressed samples is:
  389.  
  390.    &350 - Compressed sample (Squished)
  391.  
  392. This filetyps is not Acorn allocated and may change in the future. To
  393. facilitate a smooth transition your program should read the filetype from
  394. the header on startup. This means that if future versions of Compress use
  395. a different filetype it is a simple matter of replacing the old code with
  396. the new code and everything will still work perfectly (barring renaming the
  397. icons in the !Sprites files).
  398.  
  399.  
  400. Special data
  401. ============
  402.  
  403. This 16-byte block in the header has a format that depends on the
  404. compression code being used:
  405.  
  406.  
  407. Type0-2
  408. -------
  409.  
  410.    +60  Flags:
  411.           bit 0 - Store in linear form, else store in VIDC form.
  412.           bit 1 - Allow compressed table. Distinguishes between Type 1 and
  413.                   Type 2 samples.
  414.    +64  Number of 16-byte sample blocks per block group (0-256).
  415.    +68  Number of bits in group header (0-2).
  416.  
  417. Storing the sample in VIDC format reduces the quality of the sample slightly
  418. but often produces greater compression.
  419.  
  420. Types 1 and 2 split the 16-byte blocks up into groups of blocks. Each group
  421. has a short header giving attributes to the group, the size of which is
  422. determined in +68. The smaller the header, the less the overheads, but the
  423. result is a restriction on the compression techniques used. Similarly, a
  424. large value for +64 reduces the number of headers needed, at the expense of
  425. slow reaction time to changes in the condition of the sample.
  426.  
  427. For type 0 samples, +64 and +68 should be zero. For types 1 and 2 +64 and
  428. +68 should both be non-zero, and bit 1 of +60 determines whether type 1 or
  429. type 2 is used (there is little difference between the two). The initial
  430. values in the header provide sensible defaults for producing type 2 samples.
  431.  
  432. Type4-5
  433. -------
  434.  
  435.    +60  Flags:
  436.           bit 0 - Enable entropy coding.
  437.           bit 1 - Entropy coding periodically resets.
  438.           bit 31 - Source is 16-bit linear else 8-bit linear.
  439.    +64  Number of samples (not bytes) in one entropy block.
  440.  
  441. Type 5 samples are essentially just Type 4 with entropy coding on the output.
  442. Thus bit 0 is the Type 5/Type 4 switch.
  443.  
  444. In addition, when entropy coding in use, you can opt to use a single table
  445. throughout the sample, or periodically recalculate the tree to adapt to
  446. subtle changes in code frequency. If you choose the adaptive output coder
  447. you should set bit 1 and specify the maximum number of samples that each
  448. table will be used for in +64.
  449.  
  450. Type 5 is not currently supported and should not be used. For this reason,
  451. the above information is subject to change in future versions. For now simply
  452. make sure that bit 0 of the flags are clear.
  453.  
  454. Type6-7
  455. -------
  456.  
  457.    +60  Flags:
  458.           bit 0 - Store in linear form, else store in VIDC form.
  459.           bit 1 - Use a 32-byte translation table, which improves compression
  460.                   slightly (only for 8-bit samples)
  461.           bit 2 - Use new sign coding (ie. output as Type 7)
  462.  
  463. Storing the sample in VIDC format reduces the quality of the sample slightly
  464. but *should* produce greater compression (this isn't always the case).
  465. Storing in linear format results in completely lossless compression.
  466.  
  467.  
  468.  
  469. Using Compress with your own programs
  470. =====================================
  471.  
  472. Basic
  473. -----
  474.  
  475. Choose an appropriate Compress file and copy it into your application's
  476. directory. You can load it using something like this:
  477.  
  478.     SYS "OS_File",5,"<App$Dir>.Compress" TO a%,,,,l%
  479.     IF a%<>1 THEN l%=16
  480.     DIM compress% l%
  481.     SYS "OS_File",255,"<App$Dir>.Compress",compress%,0
  482.  
  483. and the code can be called with:
  484.  
  485.     CALL compress%+0
  486.     
  487. Although Compress returns the reason code in R0, I would not advise using USR
  488. instead of CALL. It's better to use CALL and then read the reason code from
  489. the header. It's easier for debugging for a start.
  490.  
  491.  
  492. Assembler
  493. ---------
  494.  
  495. When including Compress in your own programs there is no reason why it has
  496. to be kept as a separate file in your application's directory. It is
  497. actually designed to be embedded somewhere in the middle of your own code.
  498. Refer to the Technical Details section for more information on calling
  499. Compress from machine code programs.
  500.  
  501.  
  502. ObjAsm
  503. ------
  504.  
  505. Users of Acorn's Desktop Assembler will find an AOF version of Compress in
  506. the 'asm' sub-directory. Header files are provided to import all the symbols
  507. you'll need. Note that unlike Expand and ExpCode, you can link more than one
  508. copy of Compress to your code. For this reason there is one header file
  509. (Universal) defining several constants used by all versions of Compress, plus
  510. one additional header for each group of sample types, giving version-specific
  511. data.
  512.  
  513. All you have to do is include the line:
  514.  
  515.         GET     CompUtils:Compress.asm.h.Universal
  516.         
  517. at the start of your source code, followed by something like:
  518.  
  519.     GET    CompUtils:Compress.asm.h.Type0-2
  520.  
  521. repeated as many times as necessary.
  522.  
  523. Then add the appropriate object file(s) to the list of objects and libraries
  524. to be linked. There is one object file for each group of sample types
  525. supported (eg. Type0-2, Type6-7, etc), but no Universal version even if there
  526. *is* a Universal header.
  527.  
  528. The version-specific header files import symbols for the start of the Compress
  529. header (eg. Compress_0) and the entry point (eg. Compress_0_Code). Note the
  530. number inserted after 'Compress'. This is the lowest numbered sample type
  531. supported by the object in question (this example is from Type0-2). Only
  532. version-specific symbols need this number, so that the linker can tell the
  533. various versions of Compress apart if you have more than 1 linked to your
  534. code.
  535.  
  536. The Universal header also defines symbols for offsets from the start of the
  537. Compress header to various entries within that header (eg.
  538. Compress_SrcBufferPtr, Compress_SamplePeriod, etc). So, to set the sample
  539. period you would use something like this:
  540.  
  541.         LDR     R0,=Compress                    ; finds the base address
  542.         STR     R1,[R0,#Compress_SamplePeriod]  ; writes the word
  543.  
  544. The first instruction transfers the address of Compress's header into R0, then
  545. the second instruction transfers the contents of R1 into the sample period
  546. entry. To call Compress use:
  547.  
  548.         BL      Compress_0_Code
  549.  
  550. which returns a copy of the reason code in R0 to make life easier for you.
  551.  
  552. Apart from these symbols, the header files also define a series of symbols
  553. for various bits in the output flags eg. OUTPUT_LINEAR_0, ALLOW_SMALL_TABLE,
  554. etc. These should be used in preference to actual values (eg. 1<<2 or 4+2+1)
  555. where possible to allow these to be changed in the future, should the need
  556. arrise. It can also be used to highlight trouble spots, if a bit's meaning
  557. changes.
  558.  
  559. Flag symbols are version-specific so are not held in the Universal file. In
  560. fact, there is no guarantee that +60 is going to be used for flags in future
  561. compression code - all the current ones simply define the first of their
  562. special words as containing flags. Other routines might use this word for
  563. something else.
  564.  
  565. The version-specific header may also contain symbols for entries in the
  566. special-data part of Compress's header (eg. Compress_0_BlocksPerGroup).
  567.  
  568. There are also some symbols in the Universal header giving textual equivalents
  569. for reason codes eg. SRC_EMPTY, DEST_FULL, etc which may make your source code
  570. easier to read (unless you're using jump tables of course). Have a look at the
  571. file for more details.
  572.  
  573.  
  574. C/APCS
  575. ------
  576.  
  577. For C users, a header file and a series of object files can be been found
  578. in the 'cc' sub-directory. One header file and one object are provided for
  579. each group of sample formats supported. You can link more than one of these
  580. to your own code without problems.
  581.  
  582. The object code is APCS-compliant (obviously) so can be used from any APCS
  583. language, such as Pascal, C++, etc. You would have to write your own header
  584. files though - the ones provided are for C, and should be included in your
  585. source with something similar to:
  586.  
  587. #include "CompUtils:Compress.cc.h.Type0-2"
  588.  
  589. They define the entries in Compress's header as global variables that can be
  590. accessed just like normal variables eg.
  591.  
  592.         int     filetype;
  593.         int     count;
  594.         char    *buffer;
  595.         char    bytes[16];
  596.         
  597.         filetype = Compress_6_SampleType;
  598.         buffer = Compress_6_DestBufferPtr;
  599.         for (count = 0; count < 16; count++)
  600.             bytes[count] = buffer[count];
  601.  
  602. Apart from these variables, the header files may also define symbols for
  603. various bits in the output flags, depending on what features the corresponding
  604. object file supports eg. OUTPUT_LINEAR, ALLOW_SMALL_TABLE, etc. These should
  605. be used in preference to actual values (eg. 1<<2 or 4+2+1) where possible to
  606. allow these to be changed in the future, should the need arise. It can also be
  607. used to highlight trouble spots: if a bit's meaning changes then so would the
  608. name attached to it, and the compiler would spot the fact that the required
  609. symbol no longer exists.
  610.  
  611. There are also some symbols giving textual equivalents for reason codes
  612. eg. SRC_EMPTY, DEST_FULL, etc which may make your source code easy to read,
  613. especially when using 'switch'. Have a look at the header file for more
  614. details.
  615.  
  616. To call Compress just make a call to function Compress_6(). This takes no
  617. arguments and returns the reason code (which is also held in global variable
  618. Compress_6_ReasonCode). Please look at the example file provided for further
  619. details.
  620.  
  621. Note that the above description assumes you are using object file 'Type6'. For
  622. 'Type20' you would use names of the form Compress_20_Reason code, and so on.
  623. Variables and constants that are not specific to any one version of Compress
  624. do not need the number in the name (eg. SRC_EMPTY, UNKNOWN_FORMAT), but these
  625. are not all that common.
  626.  
  627. Where an object file supports more than one type of compression eg. Type0-2,
  628. the numberic part of the name is a list of the types supported eg.
  629. Compress_0_1_2_ReasonCode. There are also variables Compress_0_ReasonCode,
  630. Compress_1_ReasonCode, and Compress_2_ReasonCode. All four are equivalent;
  631. they are just different names for the same variables. Generally you should
  632. choose one naming convention and stick to it.
  633.  
  634. Similarly, there would be four functions defined: Compress_0_1_2(),
  635. Compress_0(), Compress_1(), and Compress_2(). Unlike the variables and
  636. constants these are *not* all equivalent. Instead, the 0_1_2 form is the raw
  637. Compress code and the other 3 are charged with the responsibility of setting
  638. up the special data themselves to produce a typical output for the given
  639. sample type. For example, Compress_2() forces the ALLOW_SMALL_TABLE bit in the
  640. flags to be set, sets BlocksPerGroup to 6 and BitsPerHeader to 2, and only
  641. then calls Compress_0_1_2(). The output is then 100% backwards-compatible with
  642. old versions of the !Compress program (with Pack switched on). This short cut
  643. may be useful to you, or then again it may not.
  644.  
  645. If all this has left you a little befuddled (and who would blame you!) try
  646. modifying the example file and seeing what happens. Or, alternatively, send me
  647. an email or a letter at one of the addresses in the !ReadMe file and I'll see
  648. if I can help you out.
  649.  
  650.  
  651. Bugs
  652. ====
  653.  
  654. There may well be some bugs lurking around, particularly in the ObjAsm and C
  655. versions of Compress (I never use these myself). They have been tested with
  656. the example programs so they should work, but you never know. Please report
  657. any bugs, omissions or suggestions for improvement to one of the addresses
  658. in the main !ReadMe file.
  659.  
  660.  
  661.                            (c) David Radford
  662.  
  663.  
  664.