Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Program to decode "compressed" text that has been rendered down
- to a sequence of number pairs, as per the project specification.
- Written by Alistair Moffat, October 2012.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <string.h>
- #include <strings.h>
- #include <assert.h>
- /* constants and fixed strings */
- /* Maximum output size (1MB) */
- #define MAXBYTES 1000000
- /* Assumed radix for nibble encoding */
- #define RADIX 15
- /* Flag for single byte insertion */
- #define LITERAL 0
- /* function prototypes */
- void copybytes(unsigned char *S, int dest, int src, int len);
- int nibble_length(int d);
- /* where it all happens */
- int
- main(int argc, char **argv) {
- unsigned char S[MAXBYTES];
- int copyoffset, copylength;
- int current=0;
- int inputnibbles=0, inputphrases=0;
- /* main loop, slightly longer than ideal without breaking up into
- a series of functions, but it is the sole action of the program,
- so ok... */
- while (scanf("%d,%d", ©offset, ©length)==2) {
- if ((copyoffset<0) || (copyoffset>current) ||
- (copylength<0)) {
- fprintf(stderr, "Invalid input\n");
- exit(EXIT_FAILURE);
- }
- if (copyoffset == LITERAL) {
- /* in this case, the "copylength" is actually
- a single character */
- S[current++] = copylength;
- /* and this combination always takes
- three nibbles */
- inputnibbles += 3;
- } else {
- /* in this case, a sequence of prior bytes
- is copied, as indicated by the offset */
- copybytes(S, current,
- current-copyoffset, copylength);
- current += copylength;
- /* count nibbles in the radix-15 encoding */
- inputnibbles += nibble_length(copyoffset);
- inputnibbles += nibble_length(copylength);
- /* and allow for the two sentinel nibbles */
- inputnibbles += 2;
- }
- inputphrases += 1;
- }
- fwrite(S, sizeof(*S), current, stdout);
- fprintf(stderr, "# %d phrases extracted\n", inputphrases);
- fprintf(stderr, "# %d input nibbles, %d bytes\n",
- inputnibbles, (inputnibbles+1)/2);
- fprintf(stderr, "# %d bytes written to stdout\n", current);
- fprintf(stderr, "# %.2f bits per byte compression rate\n",
- inputnibbles*4.0/current);
- return 0;
- }
- /* copy a sequence of bytes from one part of the buffer to another */
- void
- copybytes(unsigned char *S, int dest, int src, int len) {
- int i=0;
- assert(len>0 && src<dest);
- for (i=0; i<len; i++) {
- S[dest+i] = S[src+i];
- }
- }
- /* count the number of base-RADIX digits in the integer d >= 0 */
- int
- nibble_length(int d) {
- int len=0;
- assert(d>=0);
- while (d>=1) {
- d /= RADIX;
- len++;
- }
- return len;
- }
Add Comment
Please, Sign In to add comment