home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c070 / 4.ddi / TOOLS.4 / TCTSRC1.EXE / UTSQZSCN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-31  |  8.3 KB  |  283 lines

  1. /**
  2. *
  3. * Name        UTSQZSCN - Compress a screen image.
  4. *
  5. * Synopsis    length = utsqzscn(psource, pdestination,
  6. *                  source_length, destination_length);
  7. *
  8. *        int length        The number of bytes actually
  9. *                    used by the squeezed image.
  10. *        const char far *psource The address of the screen image
  11. *                    to be compressed.
  12. *        char *pdestination    The target address for the
  13. *                    compressed image to be placed.
  14. *        int source_length    The length in bytes of the
  15. *                    screen image to be compressed.
  16. *        int destination_length    The maximum length in bytes of
  17. *                    the compressed image. This is
  18. *                    the size of the destination
  19. *                    buffer.
  20. *
  21. * Description    This function compresses a screen image and returns the
  22. *        number of bytes required for the compressed image.
  23. *
  24. *        If destination_length is less than the number of bytes
  25. *        required for the compressed image, then only
  26. *        destination_length bytes of the squeezed image are moved
  27. *        into the target buffer, destination, but the number of
  28. *        bytes required for the entire compressed image is still
  29. *        returned. If either psource or pdestination is NIL, then
  30. *        zero is returned.
  31. *
  32. *        The compressed screen image has the format:
  33. *
  34. *        x(A)x(C)Length x(A)A1 charstr x(A)A2 ...
  35. *          charstr x(A)An ...
  36. *
  37. *        where x(A) is the attribute key;
  38. *              x(C) is the character key;
  39. *              Length is the length (in bytes) of the expanded
  40. *            screen image;
  41. *              A1,A2,...An are attribute bytes.
  42. *
  43. *        The format of charstr is as follows:
  44. *
  45. *        C1C2...Cn...x(C)RC'.....
  46. *
  47. *        where C1,C2,Cn,..,C' are characters;
  48. *              R is the replication count (word) for the
  49. *            character C'.
  50. *
  51. *        UTSQZSCN compresses a screen image into the format
  52. *        above. Some cases require special consideration:
  53. *        to store the single characters x(A) or x(C), the
  54. *        sequence
  55. *
  56. *              x(C)RX
  57. *
  58. *        is used where X is either x(A) or x(C) and R is 1.
  59. *        Thus, in the worst case (no two adjacent positions have
  60. *        the same attribute, and the characters are all either
  61. *        x(A) or x(C)), the compressed image will be three times
  62. *        larger than the standard image, plus 4 bytes for
  63. *        overhead.
  64. *
  65. * Returns    int length    The number of bytes actually used by
  66. *                the squeezed image.
  67. *
  68. * Version    6.00 (C)Copyright Blaise Computing Inc.  1989
  69. *
  70. **/
  71. #include <butil.h>
  72.  
  73. static void dump_characters(char *, int *, int, int, char,
  74.                 char *, int *);
  75.  
  76. int utsqzscn(psource, pdestination, source_length,
  77.          destination_length)
  78. const char far *psource;
  79. char     *pdestination;
  80. int      source_length;
  81. int      destination_length;
  82. {
  83.     int       overflow = 0;
  84.     int       source_index, destination_index;
  85.     int       character_count;
  86.     char      current_character = '\0';
  87.     char      previous_character;
  88.     unsigned char current_attribute = 0;
  89.     unsigned char previous_attribute;
  90.  
  91.     if ((psource == NIL) || (pdestination == NIL))
  92.        return(0);
  93.  
  94.     /* First set the control information in the compressed image.     */
  95.  
  96.     if (destination_length >= 4)
  97.     {
  98.     pdestination[0] = UT_ATTR_KEY;
  99.     pdestination[1] = UT_CHAR_KEY;
  100.     utpokew(&pdestination[2], source_length);
  101.     }
  102.     else
  103.     overflow = 1;
  104.  
  105.     destination_index  = 4;
  106.     character_count    = 0;
  107.     previous_character = psource[0];
  108.     previous_attribute = 0;
  109.     source_index       = 0;
  110.  
  111.     /* Now pass through the screen image.  If there is an attribute   */
  112.     /* change, output the attribute key and attribute after          */
  113.     /* outputting any character string built.  If there is a          */
  114.     /* character change, output the character string built.  If the   */
  115.     /* compressed image is greater than the target space, set          */
  116.     /* overflow to 1, but keep recording how big the compressed       */
  117.     /* image would be.                              */
  118.  
  119.     while (source_index < source_length)
  120.     {
  121.     current_character = psource[source_index];
  122.     current_attribute = psource[source_index + 1];
  123.  
  124.     if (current_attribute != previous_attribute)
  125.     {
  126.         dump_characters(pdestination, &destination_index,
  127.                 destination_length, character_count,
  128.                 current_character, &previous_character,
  129.                 &overflow);
  130.         character_count = 0;
  131.         if (overflow)
  132.         destination_index += 2;
  133.         else
  134.         if ((destination_index + 2) > destination_length)
  135.         {
  136.             overflow = 1;
  137.             destination_index += 2;
  138.         }
  139.         else
  140.         {
  141.             pdestination[destination_index++] =
  142.             UT_ATTR_KEY;
  143.             pdestination[destination_index++] =
  144.             current_attribute;
  145.         }
  146.         previous_attribute = current_attribute;
  147.     }
  148.     if ((current_character != previous_character) &&
  149.         (character_count != 0))
  150.     {
  151.         dump_characters(pdestination, &destination_index,
  152.                 destination_length, character_count,
  153.                 current_character, &previous_character,
  154.                 &overflow);
  155.         character_count = 1;
  156.     }
  157.     else
  158.        character_count++;
  159.  
  160.     source_index +=2;
  161.     }
  162.  
  163.         /* Output the last character or character string.     */
  164.  
  165.     dump_characters(pdestination, &destination_index,
  166.             destination_length, character_count,
  167.             current_character,
  168.             &previous_character, &overflow);
  169.  
  170.     return(destination_index);
  171. }
  172.  
  173.  
  174. /**
  175. *
  176. * Name        DUMP_CHARACTERS  -  Place waiting character/count pair
  177. *                    in compressed screen buffer.
  178. *
  179. * Synopsis    dump_characters(pdestination, pdestination_index,
  180. *                destination_length, pcharacter_count,
  181. *                current_character, pprevious_character,
  182. *                poverflow)
  183. *
  184. *        char *pdestination       Destination (output) buffer.
  185. *        int *pdestination_index    Current buffer index.
  186. *        int destination_length       Length of buffer.
  187. *        int character_count       Number of identical
  188. *                       characters accumulated.
  189. *        char current_character       The current source buffer
  190. *                       character.
  191. *        char *pprevious_character  The previous character in the
  192. *                       source buffer.
  193. *        int *poverflow           Whether target buffer has
  194. *                       overflowed.
  195. *
  196. * Description    This function will output a waiting character or a
  197. *        coded sequence indicating that a number of identical
  198. *        characters were encountered in the source buffer,
  199. *        placing the character or coded sequence in the
  200. *        destination buffer.  This is done whenever
  201. *        UTSQZSCN encounters a change of attribute or
  202. *        character in the source buffer.
  203. *
  204. *        If *poverflow is non-zero, no characters will actually
  205. *        be placed in the buffer, but *pdestination_index and
  206. *        *pprevious_character will contain the same values
  207. *        they would have if the buffer had not overflowed. This
  208. *        allows UTSQZSCN to compute the size the comressed image
  209. *        will require, even though it does not fit in the current
  210. *        buffer.
  211. *
  212. * Returns    *pdestination_index    New index into destination
  213. *                      buffer.
  214. *        *pprevious_character    New previous character.
  215. *        *poverflow        Non-zero if the destination
  216. *                      buffer has overflowed,
  217. *                      unchanged otherwise.
  218. *
  219. **/
  220.  
  221. static void dump_characters(pdestination, pdestination_index,
  222.                 destination_length, character_count,
  223.                 current_character, pprevious_character,
  224.                 poverflow)
  225. char *pdestination;
  226. int  *pdestination_index;
  227. int   destination_length;
  228. int   character_count;
  229. char  current_character;
  230. char *pprevious_character;
  231. int  *poverflow;
  232. {
  233.     if (character_count == 0)
  234.     {
  235.     (*pprevious_character) = current_character;
  236.     return;
  237.     }
  238.  
  239.     if (*poverflow)
  240.     {
  241.     if (((*pprevious_character) == (char) UT_ATTR_KEY) ||
  242.         ((*pprevious_character) == (char) UT_CHAR_KEY) ||
  243.         (character_count > 1))
  244.     {
  245.         (*pdestination_index) += 3;
  246.     }
  247.     else
  248.         (*pdestination_index)++;
  249.     }
  250.     else
  251.     if ((character_count == 1) &&
  252.         ((unsigned char) (*pprevious_character) != UT_ATTR_KEY) &&
  253.         ((unsigned char) (*pprevious_character) != UT_CHAR_KEY))
  254.     {
  255.         if ((*pdestination_index) >= destination_length)
  256.         (*poverflow) = 1;
  257.         else
  258.         pdestination[(*pdestination_index)] =
  259.             (*pprevious_character);
  260.     }
  261.     else
  262.     {
  263.         if (((*pdestination_index) + 4) > destination_length)
  264.         {
  265.         (*poverflow) = 1;
  266.         (*pdestination_index) += 3;
  267.         }
  268.         else
  269.         {
  270.         pdestination[(*pdestination_index)++] = UT_CHAR_KEY;
  271.         utpokew(&pdestination[(*pdestination_index)],
  272.             character_count);
  273.  
  274.         (*pdestination_index) += 2;
  275.         pdestination[(*pdestination_index)] =
  276.             (*pprevious_character);
  277.         }
  278.     }
  279.  
  280.     (*pprevious_character) = current_character;
  281.     (*pdestination_index)++;
  282. }
  283.