rle.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. * =====================================================================================
  3. *
  4. * ________ .__ __ ________ ____ ________
  5. * \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
  6. * / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
  7. * / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
  8. * \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
  9. * \__> \/ \/ \/ \/ \/
  10. * ___.
  11. * __ __ _____\_ |__
  12. * | | \/ ___/| __ \
  13. * | | /\___ \ | \_\ \
  14. * |____//____ >|___ /
  15. * \/ \/
  16. *
  17. * www.optixx.org
  18. *
  19. *
  20. * Version: 1.0
  21. * Created: 07/21/2009 03:32:16 PM
  22. * Author: david@optixx.org
  23. *
  24. * =====================================================================================
  25. */
  26. #include <avr/io.h>
  27. #include <stdlib.h>
  28. #include <stdio.h>
  29. #include <avr/pgmspace.h> /* required by usbdrv.h */
  30. #include <util/delay.h> /* for _delay_ms() */
  31. #include <avr/interrupt.h> /* for sei() */
  32. #include "sram.h"
  33. #include "debug.h"
  34. #define RUNCHAR 0x90
  35. uint8_t rle_decode(PGM_VOID_P in_addr, int32_t in_len, uint32_t out_addr)
  36. {
  37. uint8_t in_byte, in_repeat, last_byte;
  38. uint32_t out_len, out_len_left;
  39. printf("RLE decode len=%li addr=0x%08lx\n",in_len,out_addr);
  40. out_len_left = out_len;
  41. sram_bulk_write_start(out_addr);
  42. #define INBYTE(b) \
  43. do { \
  44. if ( --in_len < 0 ) { \
  45. return 1; \
  46. } \
  47. cli();\
  48. b = pgm_read_byte((PGM_VOID_P)in_addr++); \
  49. sei();\
  50. } while(0)
  51. #define OUTBYTE(b) \
  52. do { \
  53. sram_bulk_write(b);\
  54. sram_bulk_write_next();\
  55. out_addr++;\
  56. } while(0)
  57. /*
  58. ** Handle first byte separately (since we have to get angry
  59. ** in case of an orphaned RLE code).
  60. */
  61. INBYTE(in_byte);
  62. if (in_byte == RUNCHAR) {
  63. INBYTE(in_repeat);
  64. if (in_repeat != 0) {
  65. /* Note Error, not Incomplete (which is at the end
  66. ** of the string only). This is a programmer error.
  67. */
  68. printf("Orphaned RLE code at start\n");
  69. return 1;
  70. }
  71. OUTBYTE(RUNCHAR);
  72. } else {
  73. OUTBYTE(in_byte);
  74. }
  75. while( in_len > 0 ) {
  76. INBYTE(in_byte);
  77. if (in_len%1024==0)
  78. printf(".");
  79. if (in_byte == RUNCHAR) {
  80. INBYTE(in_repeat);
  81. if ( in_repeat == 0 ) {
  82. /* Just an escaped RUNCHAR value */
  83. OUTBYTE(RUNCHAR);
  84. } else {
  85. /* Pick up value and output a sequence of it */
  86. in_byte = last_byte; //;out_data[-1];
  87. while ( --in_repeat > 0 )
  88. OUTBYTE(in_byte);
  89. }
  90. } else {
  91. /* Normal byte */
  92. OUTBYTE(in_byte);
  93. }
  94. last_byte = in_byte;
  95. }
  96. sram_bulk_write_end();
  97. return 0;
  98. }