backward_references.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // Copyright 2012 Google Inc. All Rights Reserved.
  2. //
  3. // Use of this source code is governed by a BSD-style license
  4. // that can be found in the COPYING file in the root of the source
  5. // tree. An additional intellectual property rights grant can be found
  6. // in the file PATENTS. All contributing project authors may
  7. // be found in the AUTHORS file in the root of the source tree.
  8. // -----------------------------------------------------------------------------
  9. //
  10. // Author: Jyrki Alakuijala (jyrki@google.com)
  11. //
  12. #ifndef WEBP_ENC_BACKWARD_REFERENCES_H_
  13. #define WEBP_ENC_BACKWARD_REFERENCES_H_
  14. #include <assert.h>
  15. #include <stdlib.h>
  16. #include "../webp/types.h"
  17. #include "../webp/format_constants.h"
  18. #ifdef __cplusplus
  19. extern "C" {
  20. #endif
  21. // The spec allows 11, we use 9 bits to reduce memory consumption in encoding.
  22. // Having 9 instead of 11 only removes about 0.25 % of compression density.
  23. #define MAX_COLOR_CACHE_BITS 9
  24. // Max ever number of codes we'll use:
  25. #define PIX_OR_COPY_CODES_MAX \
  26. (NUM_LITERAL_CODES + NUM_LENGTH_CODES + (1 << MAX_COLOR_CACHE_BITS))
  27. // -----------------------------------------------------------------------------
  28. // PixOrCopy
  29. enum Mode {
  30. kLiteral,
  31. kCacheIdx,
  32. kCopy,
  33. kNone
  34. };
  35. typedef struct {
  36. // mode as uint8_t to make the memory layout to be exactly 8 bytes.
  37. uint8_t mode;
  38. uint16_t len;
  39. uint32_t argb_or_distance;
  40. } PixOrCopy;
  41. static WEBP_INLINE PixOrCopy PixOrCopyCreateCopy(uint32_t distance,
  42. uint16_t len) {
  43. PixOrCopy retval;
  44. retval.mode = kCopy;
  45. retval.argb_or_distance = distance;
  46. retval.len = len;
  47. return retval;
  48. }
  49. static WEBP_INLINE PixOrCopy PixOrCopyCreateCacheIdx(int idx) {
  50. PixOrCopy retval;
  51. assert(idx >= 0);
  52. assert(idx < (1 << MAX_COLOR_CACHE_BITS));
  53. retval.mode = kCacheIdx;
  54. retval.argb_or_distance = idx;
  55. retval.len = 1;
  56. return retval;
  57. }
  58. static WEBP_INLINE PixOrCopy PixOrCopyCreateLiteral(uint32_t argb) {
  59. PixOrCopy retval;
  60. retval.mode = kLiteral;
  61. retval.argb_or_distance = argb;
  62. retval.len = 1;
  63. return retval;
  64. }
  65. static WEBP_INLINE int PixOrCopyIsLiteral(const PixOrCopy* const p) {
  66. return (p->mode == kLiteral);
  67. }
  68. static WEBP_INLINE int PixOrCopyIsCacheIdx(const PixOrCopy* const p) {
  69. return (p->mode == kCacheIdx);
  70. }
  71. static WEBP_INLINE int PixOrCopyIsCopy(const PixOrCopy* const p) {
  72. return (p->mode == kCopy);
  73. }
  74. static WEBP_INLINE uint32_t PixOrCopyLiteral(const PixOrCopy* const p,
  75. int component) {
  76. assert(p->mode == kLiteral);
  77. return (p->argb_or_distance >> (component * 8)) & 0xff;
  78. }
  79. static WEBP_INLINE uint32_t PixOrCopyLength(const PixOrCopy* const p) {
  80. return p->len;
  81. }
  82. static WEBP_INLINE uint32_t PixOrCopyArgb(const PixOrCopy* const p) {
  83. assert(p->mode == kLiteral);
  84. return p->argb_or_distance;
  85. }
  86. static WEBP_INLINE uint32_t PixOrCopyCacheIdx(const PixOrCopy* const p) {
  87. assert(p->mode == kCacheIdx);
  88. assert(p->argb_or_distance < (1U << MAX_COLOR_CACHE_BITS));
  89. return p->argb_or_distance;
  90. }
  91. static WEBP_INLINE uint32_t PixOrCopyDistance(const PixOrCopy* const p) {
  92. assert(p->mode == kCopy);
  93. return p->argb_or_distance;
  94. }
  95. // -----------------------------------------------------------------------------
  96. // VP8LHashChain
  97. #define HASH_BITS 18
  98. #define HASH_SIZE (1 << HASH_BITS)
  99. typedef struct VP8LHashChain VP8LHashChain;
  100. struct VP8LHashChain {
  101. // Stores the most recently added position with the given hash value.
  102. int32_t hash_to_first_index_[HASH_SIZE];
  103. // chain_[pos] stores the previous position with the same hash value
  104. // for every pixel in the image.
  105. int32_t* chain_;
  106. // This is the maximum size of the hash_chain that can be constructed.
  107. // Typically this is the pixel count (width x height) for a given image.
  108. int size_;
  109. };
  110. // Must be called first, to set size.
  111. int VP8LHashChainInit(VP8LHashChain* const p, int size);
  112. void VP8LHashChainClear(VP8LHashChain* const p); // release memory
  113. // -----------------------------------------------------------------------------
  114. // VP8LBackwardRefs (block-based backward-references storage)
  115. // maximum number of reference blocks the image will be segmented into
  116. #define MAX_REFS_BLOCK_PER_IMAGE 16
  117. typedef struct PixOrCopyBlock PixOrCopyBlock; // forward declaration
  118. typedef struct VP8LBackwardRefs VP8LBackwardRefs;
  119. // Container for blocks chain
  120. struct VP8LBackwardRefs {
  121. int block_size_; // common block-size
  122. int error_; // set to true if some memory error occurred
  123. PixOrCopyBlock* refs_; // list of currently used blocks
  124. PixOrCopyBlock** tail_; // for list recycling
  125. PixOrCopyBlock* free_blocks_; // free-list
  126. PixOrCopyBlock* last_block_; // used for adding new refs (internal)
  127. };
  128. // Initialize the object. 'block_size' is the common block size to store
  129. // references (typically, width * height / MAX_REFS_BLOCK_PER_IMAGE).
  130. void VP8LBackwardRefsInit(VP8LBackwardRefs* const refs, int block_size);
  131. // Release memory for backward references.
  132. void VP8LBackwardRefsClear(VP8LBackwardRefs* const refs);
  133. // Copies the 'src' backward refs to the 'dst'. Returns 0 in case of error.
  134. int VP8LBackwardRefsCopy(const VP8LBackwardRefs* const src,
  135. VP8LBackwardRefs* const dst);
  136. // Cursor for iterating on references content
  137. typedef struct {
  138. // public:
  139. PixOrCopy* cur_pos; // current position
  140. // private:
  141. PixOrCopyBlock* cur_block_; // current block in the refs list
  142. const PixOrCopy* last_pos_; // sentinel for switching to next block
  143. } VP8LRefsCursor;
  144. // Returns a cursor positioned at the beginning of the references list.
  145. VP8LRefsCursor VP8LRefsCursorInit(const VP8LBackwardRefs* const refs);
  146. // Returns true if cursor is pointing at a valid position.
  147. static WEBP_INLINE int VP8LRefsCursorOk(const VP8LRefsCursor* const c) {
  148. return (c->cur_pos != NULL);
  149. }
  150. // Move to next block of references. Internal, not to be called directly.
  151. void VP8LRefsCursorNextBlock(VP8LRefsCursor* const c);
  152. // Move to next position, or NULL. Should not be called if !VP8LRefsCursorOk().
  153. static WEBP_INLINE void VP8LRefsCursorNext(VP8LRefsCursor* const c) {
  154. assert(c != NULL);
  155. assert(VP8LRefsCursorOk(c));
  156. if (++c->cur_pos == c->last_pos_) VP8LRefsCursorNextBlock(c);
  157. }
  158. // -----------------------------------------------------------------------------
  159. // Main entry points
  160. // Evaluates best possible backward references for specified quality.
  161. // Further optimize for 2D locality if use_2d_locality flag is set.
  162. // The return value is the pointer to the best of the two backward refs viz,
  163. // refs[0] or refs[1].
  164. VP8LBackwardRefs* VP8LGetBackwardReferences(
  165. int width, int height, const uint32_t* const argb, int quality,
  166. int cache_bits, int use_2d_locality, VP8LHashChain* const hash_chain,
  167. VP8LBackwardRefs refs[2]);
  168. // Produce an estimate for a good color cache size for the image.
  169. int VP8LCalculateEstimateForCacheSize(const uint32_t* const argb,
  170. int xsize, int ysize, int quality,
  171. VP8LHashChain* const hash_chain,
  172. VP8LBackwardRefs* const ref,
  173. int* const best_cache_bits);
  174. #ifdef __cplusplus
  175. }
  176. #endif
  177. #endif // WEBP_ENC_BACKWARD_REFERENCES_H_