/* Image compression for buffer overflow demo */ /* Last edited on 2009-01-08 17:21:46 by stolfi */ #include #include #include #define MAXROWS 480 #define MAXCOLS 640 /* Error in image file: prints `msg' and halts the program. */ void file_error(char *msg); /* Output a pixel group consisting of `count' copies of character `c' */ void putgroup(unsigned char c, int count); int main(argc, argv) int argc; char **argv; { /* Read an uncompressed ascii-art image from stdin, writes the compressed version to stdout The first line of the file contains the number of columns and the number of rows per column, in decimal, surrounded by optional spaces, and separated by at least one space. Each line after the first one contains the pixels of one row of the image, starting from the top line. */ int c, cprev, count; int col; while((c = fgetc(stdin)) != EOF) { col = 0; cprev = -1; count = 0; while(c != '\n') { if ((c == cprev) && (count < 128) && (c >= 32) && (c - 32 < 128)) { /* Repeated pixel value */ count++; } else { /* New pixel value, or count saturation */ if (count > 0) { putgroup(cprev, count); cprev = -1; count = 0; } cprev = c; count = 1; } col++; c = fgetc(stdin); if (c == EOF) { file_error("missing end-of-line"); } } if (count > 0) { putgroup(cprev, count); } putchar('\n'); } return 0; } void putgroup(c, count) unsigned char c; int count; { if ((count == 1) && (c >= 32) && (c <= 32+127)) { /* Verbatim group: */ putchar((c - 32) | 128); } else if (count-1 > 127) { file_error("bad count"); } else { /* Replication group */ putchar(count-1); putchar(c); } } void file_error(msg) char *msg; { fprintf(stderr, "** %s\n", msg); exit(1); }