jpeg_idct.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // (C) 2020 Ultraembedded
  2. // SPDX-License-Identifier: Apache-2.0
  3. // https://github.com/ultraembedded/core_jpeg
  4. #ifndef JPEG_IDCT_H
  5. #define JPEG_IDCT_H
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <stdint.h>
  9. #include <string.h>
  10. #include <assert.h>
  11. //-----------------------------------------------------------------------------
  12. // jpeg_idct:
  13. //-----------------------------------------------------------------------------
  14. class jpeg_idct
  15. {
  16. public:
  17. jpeg_idct() { reset(); }
  18. void reset(void) { }
  19. //-----------------------------------------------------------------------------
  20. // process: Perform inverse DCT on already dequantized data.
  21. // [Not quite sure who to attribute this implementation to...]
  22. //-----------------------------------------------------------------------------
  23. void process(int *data_in, int *data_out)
  24. {
  25. int s0,s1,s2,s3,s4,s5,s6,s7;
  26. int t0,t1,t2,t3,t4,t5,t6,t7;
  27. int working_buf[64];
  28. int *temp_buf = working_buf;
  29. // X - Rows
  30. for(int i=0;i<8;i++)
  31. {
  32. s0 = (data_in[0] + data_in[4]) * C4;
  33. s1 = (data_in[0] - data_in[4]) * C4;
  34. s3 = (data_in[2] * C2) + (data_in[6] * C6);
  35. s2 = (data_in[2] * C6) - (data_in[6] * C2);
  36. s7 = (data_in[1] * C1) + (data_in[7] * C7);
  37. s4 = (data_in[1] * C7) - (data_in[7] * C1);
  38. s6 = (data_in[5] * C5) + (data_in[3] * C3);
  39. s5 = (data_in[5] * C3) - (data_in[3] * C5);
  40. // Next row
  41. data_in += 8;
  42. t0 = s0 + s3;
  43. t3 = s0 - s3;
  44. t1 = s1 + s2;
  45. t2 = s1 - s2;
  46. t4 = s4 + s5;
  47. t5 = s4 - s5;
  48. t7 = s7 + s6;
  49. t6 = s7 - s6;
  50. s6 = (t5 + t6) * 181 / 256; // 1/sqrt(2)
  51. s5 = (t6 - t5) * 181 / 256; // 1/sqrt(2)
  52. *temp_buf++ = (t0 + t7) >> 11;
  53. *temp_buf++ = (t1 + s6) >> 11;
  54. *temp_buf++ = (t2 + s5) >> 11;
  55. *temp_buf++ = (t3 + t4) >> 11;
  56. *temp_buf++ = (t3 - t4) >> 11;
  57. *temp_buf++ = (t2 - s5) >> 11;
  58. *temp_buf++ = (t1 - s6) >> 11;
  59. *temp_buf++ = (t0 - t7) >> 11;
  60. }
  61. // Y - Columns
  62. temp_buf = working_buf;
  63. for(int i=0;i<8;i++)
  64. {
  65. s0 = (temp_buf[0] + temp_buf[32]) * C4;
  66. s1 = (temp_buf[0] - temp_buf[32]) * C4;
  67. s3 = temp_buf[16] * C2 + temp_buf[48] * C6;
  68. s2 = temp_buf[16] * C6 - temp_buf[48] * C2;
  69. s7 = temp_buf[8] * C1 + temp_buf[56] * C7;
  70. s4 = temp_buf[8] * C7 - temp_buf[56] * C1;
  71. s6 = temp_buf[40] * C5 + temp_buf[24] * C3;
  72. s5 = temp_buf[40] * C3 - temp_buf[24] * C5;
  73. t0 = s0 + s3;
  74. t1 = s1 + s2;
  75. t2 = s1 - s2;
  76. t3 = s0 - s3;
  77. t4 = s4 + s5;
  78. t5 = s4 - s5;
  79. t6 = s7 - s6;
  80. t7 = s6 + s7;
  81. s5 = (t6 - t5) * 181 / 256; // 1/sqrt(2)
  82. s6 = (t5 + t6) * 181 / 256; // 1/sqrt(2)
  83. data_out[0] = ((t0 + t7) >> 15);
  84. data_out[56] = ((t0 - t7) >> 15);
  85. data_out[8] = ((t1 + s6) >> 15);
  86. data_out[48] = ((t1 - s6) >> 15);
  87. data_out[16] = ((t2 + s5) >> 15);
  88. data_out[40] = ((t2 - s5) >> 15);
  89. data_out[24] = ((t3 + t4) >> 15);
  90. data_out[32] = ((t3 - t4) >> 15);
  91. temp_buf++;
  92. data_out++;
  93. }
  94. data_out -= 8;
  95. }
  96. static const int C1 = 4017; // cos( pi/16) x4096
  97. static const int C2 = 3784; // cos(2pi/16) x4096
  98. static const int C3 = 3406; // cos(3pi/16) x4096
  99. static const int C4 = 2896; // cos(4pi/16) x4096
  100. static const int C5 = 2276; // cos(5pi/16) x4096
  101. static const int C6 = 1567; // cos(6pi/16) x4096
  102. static const int C7 = 799; // cos(7pi/16) x4096
  103. };
  104. #endif