jchuff.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * jchuff.h
  3. *
  4. * This file was part of the Independent JPEG Group's software:
  5. * Copyright (C) 1991-1997, Thomas G. Lane.
  6. * libjpeg-turbo Modifications:
  7. * Copyright (C) 2009, 2018, 2021, D. R. Commander.
  8. * Copyright (C) 2018, Matthias Räncker.
  9. * Copyright (C) 2020-2021, Arm Limited.
  10. * For conditions of distribution and use, see the accompanying README.ijg
  11. * file.
  12. */
  13. /* Expanded entropy encoder object for Huffman encoding.
  14. *
  15. * The savable_state subrecord contains fields that change within an MCU,
  16. * but must not be updated permanently until we complete the MCU.
  17. */
  18. #if defined(__aarch64__) || defined(_M_ARM64)
  19. #define BIT_BUF_SIZE 64
  20. #else
  21. #define BIT_BUF_SIZE 32
  22. #endif
  23. typedef struct {
  24. size_t put_buffer; /* current bit accumulation buffer */
  25. int free_bits; /* # of bits available in it */
  26. int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
  27. } savable_state;
  28. typedef struct {
  29. JOCTET *next_output_byte; /* => next byte to write in buffer */
  30. size_t free_in_buffer; /* # of byte spaces remaining in buffer */
  31. savable_state cur; /* Current bit buffer & DC state */
  32. j_compress_ptr cinfo; /* dump_buffer needs access to this */
  33. int simd;
  34. } working_state;
  35. /* Outputting bits to the file */
  36. /* Output byte b and, speculatively, an additional 0 byte. 0xFF must be encoded
  37. * as 0xFF 0x00, so the output buffer pointer is advanced by 2 if the byte is
  38. * 0xFF. Otherwise, the output buffer pointer is advanced by 1, and the
  39. * speculative 0 byte will be overwritten by the next byte.
  40. */
  41. #define EMIT_BYTE(b) { \
  42. buffer[0] = (JOCTET)(b); \
  43. buffer[1] = 0; \
  44. buffer -= -2 + ((JOCTET)(b) < 0xFF); \
  45. }
  46. /* Output the entire bit buffer. If there are no 0xFF bytes in it, then write
  47. * directly to the output buffer. Otherwise, use the EMIT_BYTE() macro to
  48. * encode 0xFF as 0xFF 0x00.
  49. */
  50. #if defined(__aarch64__) || defined(_M_ARM64)
  51. #define FLUSH() { \
  52. if (put_buffer & 0x8080808080808080 & ~(put_buffer + 0x0101010101010101)) { \
  53. EMIT_BYTE(put_buffer >> 56) \
  54. EMIT_BYTE(put_buffer >> 48) \
  55. EMIT_BYTE(put_buffer >> 40) \
  56. EMIT_BYTE(put_buffer >> 32) \
  57. EMIT_BYTE(put_buffer >> 24) \
  58. EMIT_BYTE(put_buffer >> 16) \
  59. EMIT_BYTE(put_buffer >> 8) \
  60. EMIT_BYTE(put_buffer ) \
  61. } else { \
  62. *((uint64_t *)buffer) = BUILTIN_BSWAP64(put_buffer); \
  63. buffer += 8; \
  64. } \
  65. }
  66. #else
  67. #if defined(_MSC_VER) && !defined(__clang__)
  68. #define SPLAT() { \
  69. buffer[0] = (JOCTET)(put_buffer >> 24); \
  70. buffer[1] = (JOCTET)(put_buffer >> 16); \
  71. buffer[2] = (JOCTET)(put_buffer >> 8); \
  72. buffer[3] = (JOCTET)(put_buffer ); \
  73. buffer += 4; \
  74. }
  75. #else
  76. #define SPLAT() { \
  77. put_buffer = __builtin_bswap32(put_buffer); \
  78. __asm__("str %1, [%0], #4" : "+r" (buffer) : "r" (put_buffer)); \
  79. }
  80. #endif
  81. #define FLUSH() { \
  82. if (put_buffer & 0x80808080 & ~(put_buffer + 0x01010101)) { \
  83. EMIT_BYTE(put_buffer >> 24) \
  84. EMIT_BYTE(put_buffer >> 16) \
  85. EMIT_BYTE(put_buffer >> 8) \
  86. EMIT_BYTE(put_buffer ) \
  87. } else { \
  88. SPLAT(); \
  89. } \
  90. }
  91. #endif
  92. /* Fill the bit buffer to capacity with the leading bits from code, then output
  93. * the bit buffer and put the remaining bits from code into the bit buffer.
  94. */
  95. #define PUT_AND_FLUSH(code, size) { \
  96. put_buffer = (put_buffer << (size + free_bits)) | (code >> -free_bits); \
  97. FLUSH() \
  98. free_bits += BIT_BUF_SIZE; \
  99. put_buffer = code; \
  100. }
  101. /* Insert code into the bit buffer and output the bit buffer if needed.
  102. * NOTE: We can't flush with free_bits == 0, since the left shift in
  103. * PUT_AND_FLUSH() would have undefined behavior.
  104. */
  105. #define PUT_BITS(code, size) { \
  106. free_bits -= size; \
  107. if (free_bits < 0) \
  108. PUT_AND_FLUSH(code, size) \
  109. else \
  110. put_buffer = (put_buffer << size) | code; \
  111. }
  112. #define PUT_CODE(code, size, diff) { \
  113. diff |= code << nbits; \
  114. nbits += size; \
  115. PUT_BITS(diff, nbits) \
  116. }