Created
January 6, 2012 02:15
-
-
Save andrewrcollins/1568592 to your computer and use it in GitHub Desktop.
#TJHSST ~ Run Length Encoding
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* 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); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* 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); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.