glyf_decompress.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*********************
  2. * INCLUDES
  3. *********************/
  4. #include <os_common_api.h>
  5. /*********************
  6. * DEFINES
  7. *********************/
  8. /**********************
  9. * TYPEDEFS
  10. **********************/
  11. typedef enum {
  12. RLE_STATE_SINGLE = 0,
  13. RLE_STATE_REPEATE,
  14. RLE_STATE_COUNTER,
  15. } rle_state_t;
  16. /**********************
  17. * STATIC PROTOTYPES
  18. **********************/
  19. void decompress_glyf_bitmap(const uint8_t * in, uint8_t * out, int16_t w, int16_t h, uint8_t bpp, bool prefilter, uint8_t* linebuf1, uint8_t* linebuf2);
  20. static inline void decompress_line(uint8_t * out, int16_t w);
  21. static inline uint8_t get_bits(const uint8_t * in, uint32_t bit_pos, uint8_t len);
  22. static inline void bits_write(uint8_t * out, uint32_t bit_pos, uint8_t val, uint8_t len);
  23. static inline void rle_init(const uint8_t * in, uint8_t bpp);
  24. static inline uint8_t rle_next(void);
  25. /**********************
  26. * STATIC VARIABLES
  27. **********************/
  28. static uint32_t rle_rdp;
  29. static const uint8_t * rle_in;
  30. static uint8_t rle_bpp;
  31. static uint8_t rle_prev_v;
  32. static uint8_t rle_cnt;
  33. static rle_state_t rle_state;
  34. /**********************
  35. * GLOBAL FUNCTIONS
  36. **********************/
  37. /**
  38. * The compress a glyph's bitmap
  39. * @param in the compressed bitmap
  40. * @param out buffer to store the result
  41. * @param px_num number of pixels in the glyph (width * height)
  42. * @param bpp bit per pixel (bpp = 3 will be converted to bpp = 4)
  43. * @param prefilter true: the lines are XORed
  44. */
  45. void decompress_glyf_bitmap(const uint8_t * in, uint8_t * out, int16_t w, int16_t h, uint8_t bpp, bool prefilter, uint8_t* linebuf1, uint8_t* linebuf2)
  46. {
  47. uint32_t wrp = 0;
  48. uint8_t wr_size = bpp;
  49. if(bpp == 3) wr_size = 4;
  50. rle_init(in, bpp);
  51. //uint8_t * line_buf1 = bitmap_font_cache_malloc(w);
  52. uint8_t* line_buf1 = linebuf1;
  53. uint8_t * line_buf2 = NULL;
  54. if(prefilter) {
  55. //line_buf2 = bitmap_font_cache_malloc(w);
  56. line_buf2 = linebuf2;
  57. }
  58. decompress_line(line_buf1, w);
  59. int16_t y;
  60. int16_t x;
  61. for(x = 0; x < w; x++) {
  62. bits_write(out, wrp, line_buf1[x], bpp);
  63. wrp += wr_size;
  64. }
  65. for(y = 1; y < h; y++) {
  66. if(prefilter) {
  67. decompress_line(line_buf2, w);
  68. for(x = 0; x < w; x++) {
  69. line_buf1[x] = line_buf2[x] ^ line_buf1[x];
  70. bits_write(out, wrp, line_buf1[x], bpp);
  71. wrp += wr_size;
  72. }
  73. }
  74. else {
  75. decompress_line(line_buf1, w);
  76. for(x = 0; x < w; x++) {
  77. bits_write(out, wrp, line_buf1[x], bpp);
  78. wrp += wr_size;
  79. }
  80. }
  81. }
  82. //bitmap_font_cache_free(line_buf1);
  83. //bitmap_font_cache_free(line_buf2);
  84. }
  85. /**
  86. * Decompress one line. Store one pixel per byte
  87. * @param out output buffer
  88. * @param w width of the line in pixel count
  89. */
  90. static inline void decompress_line(uint8_t * out, int16_t w)
  91. {
  92. int16_t i;
  93. for(i = 0; i < w; i++) {
  94. out[i] = rle_next();
  95. }
  96. }
  97. /**
  98. * Read bits from an input buffer. The read can cross byte boundary.
  99. * @param in the input buffer to read from.
  100. * @param bit_pos index of the first bit to read.
  101. * @param len number of bits to read (must be <= 8).
  102. * @return the read bits
  103. */
  104. static inline uint8_t get_bits(const uint8_t * in, uint32_t bit_pos, uint8_t len)
  105. {
  106. uint8_t bit_mask;
  107. switch(len) {
  108. case 1:
  109. bit_mask = 0x1;
  110. break;
  111. case 2:
  112. bit_mask = 0x3;
  113. break;
  114. case 3:
  115. bit_mask = 0x7;
  116. break;
  117. case 4:
  118. bit_mask = 0xF;
  119. break;
  120. case 8:
  121. bit_mask = 0xFF;
  122. break;
  123. default:
  124. bit_mask = (uint16_t)((uint16_t) 1 << len) - 1;
  125. }
  126. uint32_t byte_pos = bit_pos >> 3;
  127. bit_pos = bit_pos & 0x7;
  128. if(bit_pos + len >= 8) {
  129. uint16_t in16 = (in[byte_pos] << 8) + in[byte_pos + 1];
  130. return (in16 >> (16 - bit_pos - len)) & bit_mask;
  131. }
  132. else {
  133. return (in[byte_pos] >> (8 - bit_pos - len)) & bit_mask;
  134. }
  135. }
  136. /**
  137. * Write `val` data to `bit_pos` position of `out`. The write can NOT cross byte boundary.
  138. * @param out buffer where to write
  139. * @param bit_pos bit index to write
  140. * @param val value to write
  141. * @param len length of bits to write from `val`. (Counted from the LSB).
  142. * @note `len == 3` will be converted to `len = 4` and `val` will be upscaled too
  143. */
  144. static inline void bits_write(uint8_t * out, uint32_t bit_pos, uint8_t val, uint8_t len)
  145. {
  146. if(len == 3) {
  147. len = 4;
  148. switch(val) {
  149. case 0:
  150. val = 0;
  151. break;
  152. case 1:
  153. val = 2;
  154. break;
  155. case 2:
  156. val = 4;
  157. break;
  158. case 3:
  159. val = 6;
  160. break;
  161. case 4:
  162. val = 9;
  163. break;
  164. case 5:
  165. val = 11;
  166. break;
  167. case 6:
  168. val = 13;
  169. break;
  170. case 7:
  171. val = 15;
  172. break;
  173. }
  174. }
  175. uint16_t byte_pos = bit_pos >> 3;
  176. bit_pos = bit_pos & 0x7;
  177. bit_pos = 8 - bit_pos - len;
  178. uint8_t bit_mask = (uint16_t)((uint16_t) 1 << len) - 1;
  179. out[byte_pos] &= ((~bit_mask) << bit_pos);
  180. out[byte_pos] |= (val << bit_pos);
  181. }
  182. static inline void rle_init(const uint8_t * in, uint8_t bpp)
  183. {
  184. rle_in = in;
  185. rle_bpp = bpp;
  186. rle_state = RLE_STATE_SINGLE;
  187. rle_rdp = 0;
  188. rle_prev_v = 0;
  189. rle_cnt = 0;
  190. }
  191. static inline uint8_t rle_next(void)
  192. {
  193. uint8_t v = 0;
  194. uint8_t ret = 0;
  195. if(rle_state == RLE_STATE_SINGLE) {
  196. ret = get_bits(rle_in, rle_rdp, rle_bpp);
  197. if(rle_rdp != 0 && rle_prev_v == ret) {
  198. rle_cnt = 0;
  199. rle_state = RLE_STATE_REPEATE;
  200. }
  201. rle_prev_v = ret;
  202. rle_rdp += rle_bpp;
  203. }
  204. else if(rle_state == RLE_STATE_REPEATE) {
  205. v = get_bits(rle_in, rle_rdp, 1);
  206. rle_cnt++;
  207. rle_rdp += 1;
  208. if(v == 1) {
  209. ret = rle_prev_v;
  210. if(rle_cnt == 11) {
  211. rle_cnt = get_bits(rle_in, rle_rdp, 6);
  212. rle_rdp += 6;
  213. if(rle_cnt != 0) {
  214. rle_state = RLE_STATE_COUNTER;
  215. }
  216. else {
  217. ret = get_bits(rle_in, rle_rdp, rle_bpp);
  218. rle_prev_v = ret;
  219. rle_rdp += rle_bpp;
  220. rle_state = RLE_STATE_SINGLE;
  221. }
  222. }
  223. }
  224. else {
  225. ret = get_bits(rle_in, rle_rdp, rle_bpp);
  226. rle_prev_v = ret;
  227. rle_rdp += rle_bpp;
  228. rle_state = RLE_STATE_SINGLE;
  229. }
  230. }
  231. else if(rle_state == RLE_STATE_COUNTER) {
  232. ret = rle_prev_v;
  233. rle_cnt--;
  234. if(rle_cnt == 0) {
  235. ret = get_bits(rle_in, rle_rdp, rle_bpp);
  236. rle_prev_v = ret;
  237. rle_rdp += rle_bpp;
  238. rle_state = RLE_STATE_SINGLE;
  239. }
  240. }
  241. return ret;
  242. }