#ifndef BROTLI_ENC_QUALITY_H_\r
#define BROTLI_ENC_QUALITY_H_\r
\r
-#include "./encode.h"\r
+#include "../common/platform.h"\r
+#include <brotli/encode.h>\r
+#include "./params.h"\r
\r
#define FAST_ONE_PASS_COMPRESSION_QUALITY 0\r
#define FAST_TWO_PASS_COMPRESSION_QUALITY 1\r
#define ZOPFLIFICATION_QUALITY 10\r
#define HQ_ZOPFLIFICATION_QUALITY 11\r
\r
-#define MAX_QUALITY_FOR_STATIC_ENRTOPY_CODES 2\r
+#define MAX_QUALITY_FOR_STATIC_ENTROPY_CODES 2\r
#define MIN_QUALITY_FOR_BLOCK_SPLIT 4\r
+#define MIN_QUALITY_FOR_NONZERO_DISTANCE_PARAMS 4\r
#define MIN_QUALITY_FOR_OPTIMIZE_HISTOGRAMS 4\r
#define MIN_QUALITY_FOR_EXTENSIVE_REFERENCE_SEARCH 5\r
#define MIN_QUALITY_FOR_CONTEXT_MODELING 5\r
#define MIN_QUALITY_FOR_HQ_CONTEXT_MODELING 7\r
#define MIN_QUALITY_FOR_HQ_BLOCK_SPLITTING 10\r
-/* Only for "font" mode. */\r
-#define MIN_QUALITY_FOR_RECOMPUTE_DISTANCE_PREFIXES 10\r
\r
/* For quality below MIN_QUALITY_FOR_BLOCK_SPLIT there is no block splitting,\r
so we buffer at most this much literals and commands. */\r
-#define MAX_NUM_DELAYED_SYMBOLS 0x2fff\r
+#define MAX_NUM_DELAYED_SYMBOLS 0x2FFF\r
\r
-/* Encoding parameters */\r
-typedef struct BrotliEncoderParams {\r
- BrotliEncoderMode mode;\r
- int quality;\r
- int lgwin;\r
- int lgblock;\r
-} BrotliEncoderParams;\r
-\r
-/* Returns hashtable size for quality levels 0 and 1. */\r
+/* Returns hash-table size for quality levels 0 and 1. */\r
static BROTLI_INLINE size_t MaxHashTableSize(int quality) {\r
return quality == FAST_ONE_PASS_COMPRESSION_QUALITY ? 1 << 15 : 1 << 17;\r
}\r
#define MAX_ZOPFLI_LEN_QUALITY_10 150\r
#define MAX_ZOPFLI_LEN_QUALITY_11 325\r
\r
+/* Do not thoroughly search when a long copy is found. */\r
+#define BROTLI_LONG_COPY_QUICK_STEP 16384\r
+\r
static BROTLI_INLINE size_t MaxZopfliLen(const BrotliEncoderParams* params) {\r
return params->quality <= 10 ?\r
MAX_ZOPFLI_LEN_QUALITY_10 :\r
MAX_ZOPFLI_LEN_QUALITY_11;\r
}\r
\r
-/* Number of best candidates to evaluate to expand zopfli chain. */\r
+/* Number of best candidates to evaluate to expand Zopfli chain. */\r
static BROTLI_INLINE size_t MaxZopfliCandidates(\r
const BrotliEncoderParams* params) {\r
return params->quality <= 10 ? 1 : 5;\r
static BROTLI_INLINE void SanitizeParams(BrotliEncoderParams* params) {\r
params->quality = BROTLI_MIN(int, BROTLI_MAX_QUALITY,\r
BROTLI_MAX(int, BROTLI_MIN_QUALITY, params->quality));\r
- if (params->lgwin < kBrotliMinWindowBits) {\r
- params->lgwin = kBrotliMinWindowBits;\r
- } else if (params->lgwin > kBrotliMaxWindowBits) {\r
- params->lgwin = kBrotliMaxWindowBits;\r
+ if (params->quality <= MAX_QUALITY_FOR_STATIC_ENTROPY_CODES) {\r
+ params->large_window = BROTLI_FALSE;\r
+ }\r
+ if (params->lgwin < BROTLI_MIN_WINDOW_BITS) {\r
+ params->lgwin = BROTLI_MIN_WINDOW_BITS;\r
+ } else {\r
+ int max_lgwin = params->large_window ? BROTLI_LARGE_MAX_WINDOW_BITS :\r
+ BROTLI_MAX_WINDOW_BITS;\r
+ if (params->lgwin > max_lgwin) params->lgwin = max_lgwin;\r
}\r
}\r
\r
lgblock = BROTLI_MIN(int, 18, params->lgwin);\r
}\r
} else {\r
- lgblock = BROTLI_MIN(int, kBrotliMaxInputBlockBits,\r
- BROTLI_MAX(int, kBrotliMinInputBlockBits, lgblock));\r
+ lgblock = BROTLI_MIN(int, BROTLI_MAX_INPUT_BLOCK_BITS,\r
+ BROTLI_MAX(int, BROTLI_MIN_INPUT_BLOCK_BITS, lgblock));\r
}\r
return lgblock;\r
}\r
Allocate at least lgwin + 1 bits for the ring buffer so that the newly\r
added block fits there completely and we still get lgwin bits and at least\r
read_block_size_bits + 1 bits because the copy tail length needs to be\r
- smaller than ringbuffer size. */\r
+ smaller than ring-buffer size. */\r
static BROTLI_INLINE int ComputeRbBits(const BrotliEncoderParams* params) {\r
return 1 + BROTLI_MAX(int, params->lgwin, params->lgblock);\r
}\r
\r
static BROTLI_INLINE size_t MaxMetablockSize(\r
const BrotliEncoderParams* params) {\r
- int bits = BROTLI_MIN(int, ComputeRbBits(params), kBrotliMaxInputBlockBits);\r
+ int bits =\r
+ BROTLI_MIN(int, ComputeRbBits(params), BROTLI_MAX_INPUT_BLOCK_BITS);\r
return (size_t)1 << bits;\r
}\r
\r
return params->quality < 9 ? 64 : 512;\r
}\r
\r
-static BROTLI_INLINE int ChooseHasher(const BrotliEncoderParams* params) {\r
+static BROTLI_INLINE void ChooseHasher(const BrotliEncoderParams* params,\r
+ BrotliHasherParams* hparams) {\r
if (params->quality > 9) {\r
- return 10;\r
+ hparams->type = 10;\r
+ } else if (params->quality == 4 && params->size_hint >= (1 << 20)) {\r
+ hparams->type = 54;\r
} else if (params->quality < 5) {\r
- return params->quality;\r
+ hparams->type = params->quality;\r
} else if (params->lgwin <= 16) {\r
- return params->quality < 7 ? 40 : params->quality < 9 ? 41 : 42;\r
+ hparams->type = params->quality < 7 ? 40 : params->quality < 9 ? 41 : 42;\r
+ } else if (params->size_hint >= (1 << 20) && params->lgwin >= 19) {\r
+ hparams->type = 6;\r
+ hparams->block_bits = params->quality - 1;\r
+ hparams->bucket_bits = 15;\r
+ hparams->hash_len = 5;\r
+ hparams->num_last_distances_to_check =\r
+ params->quality < 7 ? 4 : params->quality < 9 ? 10 : 16;\r
+ } else {\r
+ hparams->type = 5;\r
+ hparams->block_bits = params->quality - 1;\r
+ hparams->bucket_bits = params->quality < 7 ? 14 : 15;\r
+ hparams->num_last_distances_to_check =\r
+ params->quality < 7 ? 4 : params->quality < 9 ? 10 : 16;\r
+ }\r
+\r
+ if (params->lgwin > 24) {\r
+ /* Different hashers for large window brotli: not for qualities <= 2,\r
+ these are too fast for large window. Not for qualities >= 10: their\r
+ hasher already works well with large window. So the changes are:\r
+ H3 --> H35: for quality 3.\r
+ H54 --> H55: for quality 4 with size hint > 1MB\r
+ H6 --> H65: for qualities 5, 6, 7, 8, 9. */\r
+ if (hparams->type == 3) {\r
+ hparams->type = 35;\r
+ }\r
+ if (hparams->type == 54) {\r
+ hparams->type = 55;\r
+ }\r
+ if (hparams->type == 6) {\r
+ hparams->type = 65;\r
+ }\r
}\r
- return params->quality;\r
}\r
\r
#endif /* BROTLI_ENC_QUALITY_H_ */\r