home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name UTSQZSCN - Compress a screen image.
- *
- * Synopsis length = utsqzscn(psource, pdestination,
- * source_length, destination_length);
- *
- * int length The number of bytes actually
- * used by the squeezed image.
- * const char far *psource The address of the screen image
- * to be compressed.
- * char *pdestination The target address for the
- * compressed image to be placed.
- * int source_length The length in bytes of the
- * screen image to be compressed.
- * int destination_length The maximum length in bytes of
- * the compressed image. This is
- * the size of the destination
- * buffer.
- *
- * Description This function compresses a screen image and returns the
- * number of bytes required for the compressed image.
- *
- * If destination_length is less than the number of bytes
- * required for the compressed image, then only
- * destination_length bytes of the squeezed image are moved
- * into the target buffer, destination, but the number of
- * bytes required for the entire compressed image is still
- * returned. If either psource or pdestination is NIL, then
- * zero is returned.
- *
- * The compressed screen image has the format:
- *
- * x(A)x(C)Length x(A)A1 charstr x(A)A2 ...
- * charstr x(A)An ...
- *
- * where x(A) is the attribute key;
- * x(C) is the character key;
- * Length is the length (in bytes) of the expanded
- * screen image;
- * A1,A2,...An are attribute bytes.
- *
- * The format of charstr is as follows:
- *
- * C1C2...Cn...x(C)RC'.....
- *
- * where C1,C2,Cn,..,C' are characters;
- * R is the replication count (word) for the
- * character C'.
- *
- * UTSQZSCN compresses a screen image into the format
- * above. Some cases require special consideration:
- * to store the single characters x(A) or x(C), the
- * sequence
- *
- * x(C)RX
- *
- * is used where X is either x(A) or x(C) and R is 1.
- * Thus, in the worst case (no two adjacent positions have
- * the same attribute, and the characters are all either
- * x(A) or x(C)), the compressed image will be three times
- * larger than the standard image, plus 4 bytes for
- * overhead.
- *
- * Returns int length The number of bytes actually used by
- * the squeezed image.
- *
- * Version 6.00 (C)Copyright Blaise Computing Inc. 1989
- *
- **/
- #include <butil.h>
-
- static void dump_characters(char *, int *, int, int, char,
- char *, int *);
-
- int utsqzscn(psource, pdestination, source_length,
- destination_length)
- const char far *psource;
- char *pdestination;
- int source_length;
- int destination_length;
- {
- int overflow = 0;
- int source_index, destination_index;
- int character_count;
- char current_character = '\0';
- char previous_character;
- unsigned char current_attribute = 0;
- unsigned char previous_attribute;
-
- if ((psource == NIL) || (pdestination == NIL))
- return(0);
-
- /* First set the control information in the compressed image. */
-
- if (destination_length >= 4)
- {
- pdestination[0] = UT_ATTR_KEY;
- pdestination[1] = UT_CHAR_KEY;
- utpokew(&pdestination[2], source_length);
- }
- else
- overflow = 1;
-
- destination_index = 4;
- character_count = 0;
- previous_character = psource[0];
- previous_attribute = 0;
- source_index = 0;
-
- /* Now pass through the screen image. If there is an attribute */
- /* change, output the attribute key and attribute after */
- /* outputting any character string built. If there is a */
- /* character change, output the character string built. If the */
- /* compressed image is greater than the target space, set */
- /* overflow to 1, but keep recording how big the compressed */
- /* image would be. */
-
- while (source_index < source_length)
- {
- current_character = psource[source_index];
- current_attribute = psource[source_index + 1];
-
- if (current_attribute != previous_attribute)
- {
- dump_characters(pdestination, &destination_index,
- destination_length, character_count,
- current_character, &previous_character,
- &overflow);
- character_count = 0;
- if (overflow)
- destination_index += 2;
- else
- if ((destination_index + 2) > destination_length)
- {
- overflow = 1;
- destination_index += 2;
- }
- else
- {
- pdestination[destination_index++] =
- UT_ATTR_KEY;
- pdestination[destination_index++] =
- current_attribute;
- }
- previous_attribute = current_attribute;
- }
- if ((current_character != previous_character) &&
- (character_count != 0))
- {
- dump_characters(pdestination, &destination_index,
- destination_length, character_count,
- current_character, &previous_character,
- &overflow);
- character_count = 1;
- }
- else
- character_count++;
-
- source_index +=2;
- }
-
- /* Output the last character or character string. */
-
- dump_characters(pdestination, &destination_index,
- destination_length, character_count,
- current_character,
- &previous_character, &overflow);
-
- return(destination_index);
- }
-
-
- /**
- *
- * Name DUMP_CHARACTERS - Place waiting character/count pair
- * in compressed screen buffer.
- *
- * Synopsis dump_characters(pdestination, pdestination_index,
- * destination_length, pcharacter_count,
- * current_character, pprevious_character,
- * poverflow)
- *
- * char *pdestination Destination (output) buffer.
- * int *pdestination_index Current buffer index.
- * int destination_length Length of buffer.
- * int character_count Number of identical
- * characters accumulated.
- * char current_character The current source buffer
- * character.
- * char *pprevious_character The previous character in the
- * source buffer.
- * int *poverflow Whether target buffer has
- * overflowed.
- *
- * Description This function will output a waiting character or a
- * coded sequence indicating that a number of identical
- * characters were encountered in the source buffer,
- * placing the character or coded sequence in the
- * destination buffer. This is done whenever
- * UTSQZSCN encounters a change of attribute or
- * character in the source buffer.
- *
- * If *poverflow is non-zero, no characters will actually
- * be placed in the buffer, but *pdestination_index and
- * *pprevious_character will contain the same values
- * they would have if the buffer had not overflowed. This
- * allows UTSQZSCN to compute the size the comressed image
- * will require, even though it does not fit in the current
- * buffer.
- *
- * Returns *pdestination_index New index into destination
- * buffer.
- * *pprevious_character New previous character.
- * *poverflow Non-zero if the destination
- * buffer has overflowed,
- * unchanged otherwise.
- *
- **/
-
- static void dump_characters(pdestination, pdestination_index,
- destination_length, character_count,
- current_character, pprevious_character,
- poverflow)
- char *pdestination;
- int *pdestination_index;
- int destination_length;
- int character_count;
- char current_character;
- char *pprevious_character;
- int *poverflow;
- {
- if (character_count == 0)
- {
- (*pprevious_character) = current_character;
- return;
- }
-
- if (*poverflow)
- {
- if (((*pprevious_character) == (char) UT_ATTR_KEY) ||
- ((*pprevious_character) == (char) UT_CHAR_KEY) ||
- (character_count > 1))
- {
- (*pdestination_index) += 3;
- }
- else
- (*pdestination_index)++;
- }
- else
- if ((character_count == 1) &&
- ((unsigned char) (*pprevious_character) != UT_ATTR_KEY) &&
- ((unsigned char) (*pprevious_character) != UT_CHAR_KEY))
- {
- if ((*pdestination_index) >= destination_length)
- (*poverflow) = 1;
- else
- pdestination[(*pdestination_index)] =
- (*pprevious_character);
- }
- else
- {
- if (((*pdestination_index) + 4) > destination_length)
- {
- (*poverflow) = 1;
- (*pdestination_index) += 3;
- }
- else
- {
- pdestination[(*pdestination_index)++] = UT_CHAR_KEY;
- utpokew(&pdestination[(*pdestination_index)],
- character_count);
-
- (*pdestination_index) += 2;
- pdestination[(*pdestination_index)] =
- (*pprevious_character);
- }
- }
-
- (*pprevious_character) = current_character;
- (*pdestination_index)++;
- }