]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/BrotliCompress/enc/quality.h
BaseTools: Copy Brotli algorithm 3rd party source code for tool
[mirror_edk2.git] / BaseTools / Source / C / BrotliCompress / enc / quality.h
CommitLineData
11b7501a
SB
1/* Copyright 2016 Google Inc. All Rights Reserved.\r
2\r
3 Distributed under MIT license.\r
4 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT\r
5*/\r
6\r
7/* Constants and formulas that affect speed-ratio trade-offs and thus define\r
8 quality levels. */\r
9\r
10#ifndef BROTLI_ENC_QUALITY_H_\r
11#define BROTLI_ENC_QUALITY_H_\r
12\r
13#include "./encode.h"\r
14\r
15#define FAST_ONE_PASS_COMPRESSION_QUALITY 0\r
16#define FAST_TWO_PASS_COMPRESSION_QUALITY 1\r
17#define ZOPFLIFICATION_QUALITY 10\r
18#define HQ_ZOPFLIFICATION_QUALITY 11\r
19\r
20#define MAX_QUALITY_FOR_STATIC_ENRTOPY_CODES 2\r
21#define MIN_QUALITY_FOR_BLOCK_SPLIT 4\r
22#define MIN_QUALITY_FOR_OPTIMIZE_HISTOGRAMS 4\r
23#define MIN_QUALITY_FOR_EXTENSIVE_REFERENCE_SEARCH 5\r
24#define MIN_QUALITY_FOR_CONTEXT_MODELING 5\r
25#define MIN_QUALITY_FOR_HQ_CONTEXT_MODELING 7\r
26#define MIN_QUALITY_FOR_HQ_BLOCK_SPLITTING 10\r
27/* Only for "font" mode. */\r
28#define MIN_QUALITY_FOR_RECOMPUTE_DISTANCE_PREFIXES 10\r
29\r
30/* For quality below MIN_QUALITY_FOR_BLOCK_SPLIT there is no block splitting,\r
31 so we buffer at most this much literals and commands. */\r
32#define MAX_NUM_DELAYED_SYMBOLS 0x2fff\r
33\r
34/* Encoding parameters */\r
35typedef struct BrotliEncoderParams {\r
36 BrotliEncoderMode mode;\r
37 int quality;\r
38 int lgwin;\r
39 int lgblock;\r
40} BrotliEncoderParams;\r
41\r
42/* Returns hashtable size for quality levels 0 and 1. */\r
43static BROTLI_INLINE size_t MaxHashTableSize(int quality) {\r
44 return quality == FAST_ONE_PASS_COMPRESSION_QUALITY ? 1 << 15 : 1 << 17;\r
45}\r
46\r
47/* The maximum length for which the zopflification uses distinct distances. */\r
48#define MAX_ZOPFLI_LEN_QUALITY_10 150\r
49#define MAX_ZOPFLI_LEN_QUALITY_11 325\r
50\r
51static BROTLI_INLINE size_t MaxZopfliLen(const BrotliEncoderParams* params) {\r
52 return params->quality <= 10 ?\r
53 MAX_ZOPFLI_LEN_QUALITY_10 :\r
54 MAX_ZOPFLI_LEN_QUALITY_11;\r
55}\r
56\r
57/* Number of best candidates to evaluate to expand zopfli chain. */\r
58static BROTLI_INLINE size_t MaxZopfliCandidates(\r
59 const BrotliEncoderParams* params) {\r
60 return params->quality <= 10 ? 1 : 5;\r
61}\r
62\r
63static BROTLI_INLINE void SanitizeParams(BrotliEncoderParams* params) {\r
64 params->quality = BROTLI_MIN(int, BROTLI_MAX_QUALITY,\r
65 BROTLI_MAX(int, BROTLI_MIN_QUALITY, params->quality));\r
66 if (params->lgwin < kBrotliMinWindowBits) {\r
67 params->lgwin = kBrotliMinWindowBits;\r
68 } else if (params->lgwin > kBrotliMaxWindowBits) {\r
69 params->lgwin = kBrotliMaxWindowBits;\r
70 }\r
71}\r
72\r
73/* Returns optimized lg_block value. */\r
74static BROTLI_INLINE int ComputeLgBlock(const BrotliEncoderParams* params) {\r
75 int lgblock = params->lgblock;\r
76 if (params->quality == FAST_ONE_PASS_COMPRESSION_QUALITY ||\r
77 params->quality == FAST_TWO_PASS_COMPRESSION_QUALITY) {\r
78 lgblock = params->lgwin;\r
79 } else if (params->quality < MIN_QUALITY_FOR_BLOCK_SPLIT) {\r
80 lgblock = 14;\r
81 } else if (lgblock == 0) {\r
82 lgblock = 16;\r
83 if (params->quality >= 9 && params->lgwin > lgblock) {\r
84 lgblock = BROTLI_MIN(int, 18, params->lgwin);\r
85 }\r
86 } else {\r
87 lgblock = BROTLI_MIN(int, kBrotliMaxInputBlockBits,\r
88 BROTLI_MAX(int, kBrotliMinInputBlockBits, lgblock));\r
89 }\r
90 return lgblock;\r
91}\r
92\r
93/* Returns log2 of the size of main ring buffer area.\r
94 Allocate at least lgwin + 1 bits for the ring buffer so that the newly\r
95 added block fits there completely and we still get lgwin bits and at least\r
96 read_block_size_bits + 1 bits because the copy tail length needs to be\r
97 smaller than ringbuffer size. */\r
98static BROTLI_INLINE int ComputeRbBits(const BrotliEncoderParams* params) {\r
99 return 1 + BROTLI_MAX(int, params->lgwin, params->lgblock);\r
100}\r
101\r
102static BROTLI_INLINE size_t MaxMetablockSize(\r
103 const BrotliEncoderParams* params) {\r
104 int bits = BROTLI_MIN(int, ComputeRbBits(params), kBrotliMaxInputBlockBits);\r
105 return (size_t)1 << bits;\r
106}\r
107\r
108/* When searching for backward references and have not seen matches for a long\r
109 time, we can skip some match lookups. Unsuccessful match lookups are very\r
110 expensive and this kind of a heuristic speeds up compression quite a lot.\r
111 At first 8 byte strides are taken and every second byte is put to hasher.\r
112 After 4x more literals stride by 16 bytes, every put 4-th byte to hasher.\r
113 Applied only to qualities 2 to 9. */\r
114static BROTLI_INLINE size_t LiteralSpreeLengthForSparseSearch(\r
115 const BrotliEncoderParams* params) {\r
116 return params->quality < 9 ? 64 : 512;\r
117}\r
118\r
119static BROTLI_INLINE int ChooseHasher(const BrotliEncoderParams* params) {\r
120 if (params->quality > 9) {\r
121 return 10;\r
122 } else if (params->quality < 5) {\r
123 return params->quality;\r
124 } else if (params->lgwin <= 16) {\r
125 return params->quality < 7 ? 40 : params->quality < 9 ? 41 : 42;\r
126 }\r
127 return params->quality;\r
128}\r
129\r
130#endif /* BROTLI_ENC_QUALITY_H_ */\r