rle.c 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <stdint.h>
  4. #define LEN_THRESH (3)
  5. FILE *in, *out;
  6. uint8_t data, datalast;
  7. uint16_t len, first=1;
  8. size_t off;
  9. uint16_t getrunlength(uint8_t data) {
  10. uint16_t count=1;
  11. while(fgetc(in)==data && count<65535) {
  12. if(feof(in))break;
  13. count++;
  14. }
  15. return count;
  16. }
  17. void writerle(uint8_t data, uint16_t len) {
  18. if(len<256) {
  19. fputc(0x5b, out);
  20. fputc(data, out);
  21. fputc(len & 0xff, out);
  22. } else {
  23. fputc(0x77, out);
  24. fputc(data, out);
  25. fputc(len & 0xff, out);
  26. fputc(len >> 8, out);
  27. }
  28. }
  29. void writeliteral(uint8_t data) {
  30. if(data==0x5b || data==0x77 || data==0x9b) {
  31. fputc(0x9b, out);
  32. }
  33. fputc(data, out);
  34. }
  35. int main(int argc, char** argv) {
  36. if((in=fopen(argv[1], "rb"))==NULL) {
  37. perror("could not open input file");
  38. return 1;
  39. }
  40. if((out=fopen(argv[2], "wb"))==NULL) {
  41. perror("could not open output file");
  42. fclose(in);
  43. return 1;
  44. }
  45. len=0;
  46. while(!feof(in)) {
  47. data=fgetc(in);
  48. if(feof(in))break;
  49. off=ftell(in);
  50. if((len=getrunlength(data)) > LEN_THRESH) {
  51. writerle(data, len);
  52. fseek(in, -1, SEEK_CUR);
  53. } else {
  54. fseek(in, off, SEEK_SET);
  55. writeliteral(data);
  56. }
  57. }
  58. fclose(out);
  59. fclose(in);
  60. return 0;
  61. }