jpeg_dht.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // (C) 2020 Ultraembedded
  2. // SPDX-License-Identifier: Apache-2.0
  3. // https://github.com/ultraembedded/core_jpeg
  4. #ifndef JPEG_DHT_H
  5. #define JPEG_DHT_H
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <stdint.h>
  9. #include <string.h>
  10. #include <assert.h>
  11. #define DHT_TABLE_Y_DC 0x00
  12. #define DHT_TABLE_Y_DC_IDX 0
  13. #define DHT_TABLE_Y_AC 0x10
  14. #define DHT_TABLE_Y_AC_IDX 1
  15. #define DHT_TABLE_CX_DC 0x01
  16. #define DHT_TABLE_CX_DC_IDX 2
  17. #define DHT_TABLE_CX_AC 0x11
  18. #define DHT_TABLE_CX_AC_IDX 3
  19. #ifndef dprintf
  20. #define dprintf(...)
  21. #endif
  22. //-----------------------------------------------------------------------------
  23. // jpeg_dqt:
  24. //-----------------------------------------------------------------------------
  25. class jpeg_dht
  26. {
  27. public:
  28. jpeg_dht() { reset(); }
  29. void reset(void)
  30. {
  31. for (int i=0;i<4;i++)
  32. memset(&m_dht_table[i], 0, sizeof(t_huffman_table));
  33. }
  34. int process(uint8_t *data, int len)
  35. {
  36. uint8_t *buf = data;
  37. int consumed = 0;
  38. // DHT tables can be combined into one section (it seems)
  39. while (consumed <= (len-17))
  40. {
  41. // Huffman table info, first four MSBs represent table type (0 for DC, 1 for AC), last four LSBs represent table #
  42. uint8_t table_info = *buf++;
  43. int table_idx = 0;
  44. switch (table_info)
  45. {
  46. case DHT_TABLE_Y_DC:
  47. table_idx = DHT_TABLE_Y_DC_IDX;
  48. break;
  49. case DHT_TABLE_Y_AC:
  50. table_idx = DHT_TABLE_Y_AC_IDX;
  51. break;
  52. case DHT_TABLE_CX_DC:
  53. table_idx = DHT_TABLE_CX_DC_IDX;
  54. break;
  55. case DHT_TABLE_CX_AC:
  56. table_idx = DHT_TABLE_CX_AC_IDX;
  57. break;
  58. default:
  59. assert(!"ERROR: Bad JPEG");
  60. break;
  61. }
  62. dprintf("DHT (Table idx %d)\n", table_idx);
  63. // Reset table
  64. memset(&m_dht_table[table_idx], 0, sizeof(m_dht_table[0]));
  65. // Extract symbol count
  66. uint8_t symb_count[16];
  67. for (int x=0;x<16;x++)
  68. {
  69. symb_count[x] = *buf++;
  70. dprintf(" bit length: %d, symbols: %d\n", x, symb_count[x]);
  71. }
  72. // Extract table values
  73. // Build the Huffman map of (length, code) -> value
  74. uint16_t code = 0;
  75. int entry = 0;
  76. for (int x=0;x<16;x++)
  77. {
  78. for (int j=0;j<symb_count[x];j++)
  79. {
  80. uint8_t dht_val = *buf++;
  81. m_dht_table[table_idx].code[entry] = code;
  82. m_dht_table[table_idx].code_len[entry] = x+1;
  83. m_dht_table[table_idx].value[entry++] = dht_val;
  84. dprintf(" %d: %x -> %x\n", entry, code, dht_val);
  85. code++;
  86. }
  87. code <<= 1;
  88. }
  89. m_dht_table[table_idx].entries = entry;
  90. consumed = buf - data;
  91. }
  92. return buf - data;
  93. }
  94. // lookup: Perform huffman lookup (starting from bit 15 of w)
  95. int lookup(int table_idx, uint16_t w, uint8_t &value)
  96. {
  97. for (int i=0;i<m_dht_table[table_idx].entries;i++)
  98. {
  99. int width = m_dht_table[table_idx].code_len[i];
  100. uint16_t bitmap = m_dht_table[table_idx].code[i];
  101. uint16_t shift_val = w >> (16-width);
  102. //printf("- %d: check against %04x ", width, shift_val);
  103. //print_bin(shift_val, width);
  104. //printf(" == %04x -> %02x\n", bitmap, value);
  105. if (shift_val == bitmap)
  106. {
  107. value = m_dht_table[table_idx].value[i];
  108. return width;
  109. }
  110. }
  111. return 0;
  112. }
  113. private:
  114. typedef struct
  115. {
  116. // 16-bit (max) code
  117. uint16_t code[255];
  118. // Code length
  119. uint8_t code_len[255];
  120. // Value to translate to
  121. uint8_t value[255];
  122. int entries;
  123. } t_huffman_table;
  124. t_huffman_table m_dht_table[4];
  125. };
  126. #endif