Skip to content

Instantly share code, notes, and snippets.

@andrewrcollins
Created January 6, 2012 02:15
Show Gist options
  • Save andrewrcollins/1568592 to your computer and use it in GitHub Desktop.
Save andrewrcollins/1568592 to your computer and use it in GitHub Desktop.
#TJHSST ~ Run Length Encoding
/* Run Length Decoding
An example program that decompresses the data stored in
a disk file to video memory */
#include <stdio.h>
/* the screen's beginning memory address B800:0000 */
#define ScrnMem 0xb8000000
/* with CGAs the screen takes up 4000 bytes. */
#define ScrnSize 4000
/* the escape code is the symbol which we won't see in the data we are
run length encoding. this symbol does occur though, if there are more
than one of these symbols in a row then the run is encoded simply like
all other runs. if there is a single character that is the escape code
then the length is just 1, a special case. */
#define EscapeCode 0xe0
/* a maximum of 32 characters can be encoded using this technique and the
escape code above. */
#define MaxRun 0x1f
main(argc,argv)
int argc;
char *argv[];
{
FILE *infile;
char far *screen,oldchr;
int cnt;
/* these variables are used more often than any other, speedier executes. */
register int run;
/* right now it is a command line version, but later... */
if(argc<2) {
printf("enter a filename\n");
exit(1);
}
/* better safe than sorry. I hate that expression! */
if((infile=fopen(argv[1],"rb"))==NULL) {
printf("error opening the file\n");
exit(1);
}
/* the method for this compression is really just too simple.
read from the data and keep reading until there is a change in the
data element read previously, keep a count of the number of occurences.
Then instead of writing that number of data elements to the file,
simply write the number of times the symbol occurs and the actual symbol.
the decompressor will look for the escape code which means that the next
character was repeated the number of times that is encoded into the
escape code.
This specific version reads from a disk and does run length decoding,
first the characters of the screen are decoded and then attributes are
decoded so that a better compression ratio is achieved. */
for(cnt=0;cnt<2;cnt++) {
screen=(ScrnMem+cnt);
oldchr=fgetc(infile);
while(screen<=(ScrnMem+ScrnSize)) {
if((oldchr&EscapeCode)==EscapeCode) {
run=oldchr&MaxRun;
oldchr=fgetc(infile);
}
else run=1;
for(;run>0;run--) {
(*screen)=oldchr;
screen+=2;
}
oldchr=fgetc(infile);
}
}
fclose(infile);
}
/* Run Length Encoding
An example program that compresses the data stored in
video memory and writes it to disk */
#include <stdio.h>
/* the screen's beginning memory address B800:0000 */
#define ScrnMem 0xb8000000
/* with CGAs the screen takes up 4000 bytes. */
#define ScrnSize 4000
/* the escape code is the symbol which we won't see in the data we are
run length encoding. this symbol does occur though, if there are more
than one of these symbols in a row then the run is encoded simply like
all other runs. if there is a single character that is the escape code
then the length is just 1, a special case. */
#define EscapeCode 0xe0
/* a maximum of 32 characters can be encoded using this technique and the
escape code above. */
#define MaxRun 0x1f
main(argc,argv)
int argc;
char *argv[];
{
FILE *outfile;
char far *screen;
int cnt;
/* these variables are used more often than any other, speedier executes. */
register int run;
register char oldchr;
/* right now it is a command line version, but later... */
if(argc<2) {
printf("enter a filename\n");
exit(1);
}
/* better safe than sorry. I hate that expression! */
if((outfile=fopen(argv[1],"wb"))==NULL) {
printf("error opening the file\n");
exit(1);
}
/* the method for this compression is really just too simple.
read from the data and keep reading until there is a change in the
data element read previously, keep a count of the number of occurences.
Then instead of writing that number of data elements to the file,
simply write the number of times the symbol occurs and the actual symbol.
the decompressor will look for the escape code which means that the next
character was repeated the number of times that is encoded into the
escape code.
This specific version reads video memory and does this run length encoding,
but not as a continous piece of memory, first the characters of the
screen are encoded and then attributes are encoded so that a far
better compression ratio is achieved. */
for(cnt=0;cnt<2;cnt++) {
/* cnt ranges from 0..1, so screen will point to the character/attribute */
screen=(ScrnMem+cnt);
/* get the first character/attribute and save it. */
oldchr=*screen;
/* while we are not done reading and encoding do... */
while(screen<=(ScrnMem+ScrnSize)) {
/* no run-ons yet. */
run=0;
do {
run++;
/* go to the next character/attribute */
screen+=2;
} while(*screen==oldchr&&run<MaxRun);
/* if run of two or more, or the execption of the escape code. */
if(run>1||oldchr==(char)EscapeCode)
fputc(EscapeCode|run,outfile);
fputc(oldchr,outfile);
oldchr=*screen;
}
}
fclose(outfile);
}
@andrewrcollins
Copy link
Author

Run-length encoding code found on an old 5.25 floppy disk from when I was a nerd at Thomas Jefferson High School for Science and Technology between 1988 and 1992.

http://en.wikipedia.org/wiki/Run-length_encoding

Anyone can do whatever they'd like to with this program--if anything.

I remain a tight and compact nerd.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment