| OLD | NEW |
| (Empty) |
| 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 | |
| 13 #ifndef WEBP_ENC_BACKWARD_REFERENCES_H_ | |
| 14 #define WEBP_ENC_BACKWARD_REFERENCES_H_ | |
| 15 | |
| 16 #include <assert.h> | |
| 17 #include <stdlib.h> | |
| 18 #include "../webp/types.h" | |
| 19 #include "../webp/format_constants.h" | |
| 20 | |
| 21 #ifdef __cplusplus | |
| 22 extern "C" { | |
| 23 #endif | |
| 24 | |
| 25 // The maximum allowed limit is 11. | |
| 26 #define MAX_COLOR_CACHE_BITS 10 | |
| 27 | |
| 28 // ----------------------------------------------------------------------------- | |
| 29 // PixOrCopy | |
| 30 | |
| 31 enum Mode { | |
| 32 kLiteral, | |
| 33 kCacheIdx, | |
| 34 kCopy, | |
| 35 kNone | |
| 36 }; | |
| 37 | |
| 38 typedef struct { | |
| 39 // mode as uint8_t to make the memory layout to be exactly 8 bytes. | |
| 40 uint8_t mode; | |
| 41 uint16_t len; | |
| 42 uint32_t argb_or_distance; | |
| 43 } PixOrCopy; | |
| 44 | |
| 45 static WEBP_INLINE PixOrCopy PixOrCopyCreateCopy(uint32_t distance, | |
| 46 uint16_t len) { | |
| 47 PixOrCopy retval; | |
| 48 retval.mode = kCopy; | |
| 49 retval.argb_or_distance = distance; | |
| 50 retval.len = len; | |
| 51 return retval; | |
| 52 } | |
| 53 | |
| 54 static WEBP_INLINE PixOrCopy PixOrCopyCreateCacheIdx(int idx) { | |
| 55 PixOrCopy retval; | |
| 56 assert(idx >= 0); | |
| 57 assert(idx < (1 << MAX_COLOR_CACHE_BITS)); | |
| 58 retval.mode = kCacheIdx; | |
| 59 retval.argb_or_distance = idx; | |
| 60 retval.len = 1; | |
| 61 return retval; | |
| 62 } | |
| 63 | |
| 64 static WEBP_INLINE PixOrCopy PixOrCopyCreateLiteral(uint32_t argb) { | |
| 65 PixOrCopy retval; | |
| 66 retval.mode = kLiteral; | |
| 67 retval.argb_or_distance = argb; | |
| 68 retval.len = 1; | |
| 69 return retval; | |
| 70 } | |
| 71 | |
| 72 static WEBP_INLINE int PixOrCopyIsLiteral(const PixOrCopy* const p) { | |
| 73 return (p->mode == kLiteral); | |
| 74 } | |
| 75 | |
| 76 static WEBP_INLINE int PixOrCopyIsCacheIdx(const PixOrCopy* const p) { | |
| 77 return (p->mode == kCacheIdx); | |
| 78 } | |
| 79 | |
| 80 static WEBP_INLINE int PixOrCopyIsCopy(const PixOrCopy* const p) { | |
| 81 return (p->mode == kCopy); | |
| 82 } | |
| 83 | |
| 84 static WEBP_INLINE uint32_t PixOrCopyLiteral(const PixOrCopy* const p, | |
| 85 int component) { | |
| 86 assert(p->mode == kLiteral); | |
| 87 return (p->argb_or_distance >> (component * 8)) & 0xff; | |
| 88 } | |
| 89 | |
| 90 static WEBP_INLINE uint32_t PixOrCopyLength(const PixOrCopy* const p) { | |
| 91 return p->len; | |
| 92 } | |
| 93 | |
| 94 static WEBP_INLINE uint32_t PixOrCopyArgb(const PixOrCopy* const p) { | |
| 95 assert(p->mode == kLiteral); | |
| 96 return p->argb_or_distance; | |
| 97 } | |
| 98 | |
| 99 static WEBP_INLINE uint32_t PixOrCopyCacheIdx(const PixOrCopy* const p) { | |
| 100 assert(p->mode == kCacheIdx); | |
| 101 assert(p->argb_or_distance < (1U << MAX_COLOR_CACHE_BITS)); | |
| 102 return p->argb_or_distance; | |
| 103 } | |
| 104 | |
| 105 static WEBP_INLINE uint32_t PixOrCopyDistance(const PixOrCopy* const p) { | |
| 106 assert(p->mode == kCopy); | |
| 107 return p->argb_or_distance; | |
| 108 } | |
| 109 | |
| 110 // ----------------------------------------------------------------------------- | |
| 111 // VP8LHashChain | |
| 112 | |
| 113 #define HASH_BITS 18 | |
| 114 #define HASH_SIZE (1 << HASH_BITS) | |
| 115 | |
| 116 typedef struct VP8LHashChain VP8LHashChain; | |
| 117 struct VP8LHashChain { | |
| 118 // The 20 most significant bits contain the offset at which the best match | |
| 119 // is found. These 20 bits are the limit defined by GetWindowSizeForHashChain | |
| 120 // (through WINDOW_SIZE = 1<<20). | |
| 121 // The lower 12 bits contain the length of the match. The 12 bit limit is | |
| 122 // defined in MaxFindCopyLength with MAX_LENGTH=4096. | |
| 123 uint32_t* offset_length_; | |
| 124 // This is the maximum size of the hash_chain that can be constructed. | |
| 125 // Typically this is the pixel count (width x height) for a given image. | |
| 126 int size_; | |
| 127 }; | |
| 128 | |
| 129 // Must be called first, to set size. | |
| 130 int VP8LHashChainInit(VP8LHashChain* const p, int size); | |
| 131 // Pre-compute the best matches for argb. | |
| 132 int VP8LHashChainFill(VP8LHashChain* const p, int quality, | |
| 133 const uint32_t* const argb, int xsize, int ysize); | |
| 134 void VP8LHashChainClear(VP8LHashChain* const p); // release memory | |
| 135 | |
| 136 // ----------------------------------------------------------------------------- | |
| 137 // VP8LBackwardRefs (block-based backward-references storage) | |
| 138 | |
| 139 // maximum number of reference blocks the image will be segmented into | |
| 140 #define MAX_REFS_BLOCK_PER_IMAGE 16 | |
| 141 | |
| 142 typedef struct PixOrCopyBlock PixOrCopyBlock; // forward declaration | |
| 143 typedef struct VP8LBackwardRefs VP8LBackwardRefs; | |
| 144 | |
| 145 // Container for blocks chain | |
| 146 struct VP8LBackwardRefs { | |
| 147 int block_size_; // common block-size | |
| 148 int error_; // set to true if some memory error occurred | |
| 149 PixOrCopyBlock* refs_; // list of currently used blocks | |
| 150 PixOrCopyBlock** tail_; // for list recycling | |
| 151 PixOrCopyBlock* free_blocks_; // free-list | |
| 152 PixOrCopyBlock* last_block_; // used for adding new refs (internal) | |
| 153 }; | |
| 154 | |
| 155 // Initialize the object. 'block_size' is the common block size to store | |
| 156 // references (typically, width * height / MAX_REFS_BLOCK_PER_IMAGE). | |
| 157 void VP8LBackwardRefsInit(VP8LBackwardRefs* const refs, int block_size); | |
| 158 // Release memory for backward references. | |
| 159 void VP8LBackwardRefsClear(VP8LBackwardRefs* const refs); | |
| 160 // Copies the 'src' backward refs to the 'dst'. Returns 0 in case of error. | |
| 161 int VP8LBackwardRefsCopy(const VP8LBackwardRefs* const src, | |
| 162 VP8LBackwardRefs* const dst); | |
| 163 | |
| 164 // Cursor for iterating on references content | |
| 165 typedef struct { | |
| 166 // public: | |
| 167 PixOrCopy* cur_pos; // current position | |
| 168 // private: | |
| 169 PixOrCopyBlock* cur_block_; // current block in the refs list | |
| 170 const PixOrCopy* last_pos_; // sentinel for switching to next block | |
| 171 } VP8LRefsCursor; | |
| 172 | |
| 173 // Returns a cursor positioned at the beginning of the references list. | |
| 174 VP8LRefsCursor VP8LRefsCursorInit(const VP8LBackwardRefs* const refs); | |
| 175 // Returns true if cursor is pointing at a valid position. | |
| 176 static WEBP_INLINE int VP8LRefsCursorOk(const VP8LRefsCursor* const c) { | |
| 177 return (c->cur_pos != NULL); | |
| 178 } | |
| 179 // Move to next block of references. Internal, not to be called directly. | |
| 180 void VP8LRefsCursorNextBlock(VP8LRefsCursor* const c); | |
| 181 // Move to next position, or NULL. Should not be called if !VP8LRefsCursorOk(). | |
| 182 static WEBP_INLINE void VP8LRefsCursorNext(VP8LRefsCursor* const c) { | |
| 183 assert(c != NULL); | |
| 184 assert(VP8LRefsCursorOk(c)); | |
| 185 if (++c->cur_pos == c->last_pos_) VP8LRefsCursorNextBlock(c); | |
| 186 } | |
| 187 | |
| 188 // ----------------------------------------------------------------------------- | |
| 189 // Main entry points | |
| 190 | |
| 191 // Evaluates best possible backward references for specified quality. | |
| 192 // The input cache_bits to 'VP8LGetBackwardReferences' sets the maximum cache | |
| 193 // bits to use (passing 0 implies disabling the local color cache). | |
| 194 // The optimal cache bits is evaluated and set for the *cache_bits parameter. | |
| 195 // The return value is the pointer to the best of the two backward refs viz, | |
| 196 // refs[0] or refs[1]. | |
| 197 VP8LBackwardRefs* VP8LGetBackwardReferences( | |
| 198 int width, int height, const uint32_t* const argb, int quality, | |
| 199 int low_effort, int* const cache_bits, | |
| 200 const VP8LHashChain* const hash_chain, VP8LBackwardRefs refs[2]); | |
| 201 | |
| 202 #ifdef __cplusplus | |
| 203 } | |
| 204 #endif | |
| 205 | |
| 206 #endif // WEBP_ENC_BACKWARD_REFERENCES_H_ | |
| OLD | NEW |