blob: a9ed9da01732d7b6fc7a54310c3ee8f8552bc8b8 [file] [log] [blame]
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// -----------------------------------------------------------------------------
//
// Internal constants.
//
// Authors: Vincent Rabaud (vrabaud@google.com)
#ifndef WP2_COMMON_CONSTANTS_H_
#define WP2_COMMON_CONSTANTS_H_
#include <algorithm>
#include <cassert>
#include <cstdint>
#include "src/dsp/math.h"
#include "src/utils/ans.h"
#include "src/utils/utils.h"
#include "src/wp2/base.h"
#include "src/wp2/format_constants.h"
//------------------------------------------------------------------------------
// Lossy and common constants.
namespace WP2 {
// Maximum number of bytes used by a variable-length integer.
static constexpr uint32_t kMaxVarIntLength = 4;
// Maximum value expressible with a variable-length integer (included).
static constexpr uint32_t kMaxVarInt =
0x7Fu + (0x80u << 7) + (0x80u << 14) + (0x100u << 21); // ~514 MB
static_assert(kMaxChunkSize - 1u <= kMaxVarInt,
"The maximum chunk size cannot be represented with var ints.");
// Maximum (inclusive) bytes per pixel.
static constexpr uint64_t kMaxNumBytesPerPixel =
#if defined(WP2_ENC_DEC_MATCH)
// Each channel is sizeof(uint16_t) and its ANS hash sizeof(uint16_t).
4 * 2 * sizeof(uint16_t);
#else
4 * sizeof(uint16_t);
#endif
static constexpr char kChannelStr[4][2] = {"Y", "U", "V", "A"};
const char* const kPartitionMethodString[] = {
"Multipass", "Block-enc", "Split-enc", "Tile-enc", "SplitRec-enc",
"Area-enc", "Sub-area-enc", "Exhaustive", "Fixed-4x4", "Fixed-8x8",
"Fixed-16x16", "Fixed-32x32", "Auto"};
STATIC_ASSERT_ARRAY_SIZE(kPartitionMethodString, WP2::NUM_PARTITION_METHODS);
// Number of sets of residual statistics. For now, there is one set per method.
// kMethod0 and kMethod1.
static constexpr uint32_t kNumResidualStats = 2;
// Maximum value used by StoreCoeffs to use the first dictionary.
// A value of kResidual1Max is an escape code to get to the second
// dictionary.
static constexpr uint32_t kResidual1Max = 12;
// Maximum value of consecutive 0s we store for residuals.
static constexpr uint32_t kResidualCons0Max = 6;
// Maximum quantized DC value that can be coded.
static constexpr uint32_t kMaxDcValue = (1u << 12) - 1u;
// Maximum quantized value that can be coded for AC coeffs.
static constexpr uint32_t kMaxCoeffValue =
((1u << kMaxCoeffBits) - 1u) + 3 + kResidual1Max;
static constexpr Argb38b kDefaultBackgroundColor{kAlphaMax, 0x0000u, 0x0000u,
0x0000u};
// Decoding progress proportion in [0:1] range.
static constexpr double kOnePercent = 0.01; // For each header, ICC, ANMF etc.
static constexpr double kProgressEnd = 0.02; // XMP+EXIF.
// Progress occupied by header + preview + ICC.
static constexpr double kProgressBeforeFrames = 3 * kOnePercent;
// Progress left after removing the header + preview + ICC + XMP+EXIF.
static constexpr double kProgressFrames =
1. - kProgressBeforeFrames - kProgressEnd;
// Progress for all tiles within a frame minus ANMF + GlobalParams.
static constexpr double kProgressTiles = 1. - 2 * kOnePercent;
// Returns the tile width/height in pixels for a given TileShape and frame
// dimensions.
static inline uint32_t TileWidth(TileShape tile_shape, uint32_t frame_width,
uint32_t frame_height) {
switch (tile_shape) {
case TILE_SHAPE_SQUARE_128:
return 128;
case TILE_SHAPE_SQUARE_256:
return 256;
case TILE_SHAPE_SQUARE_512:
return 512;
case TILE_SHAPE_WIDE:
(void)frame_height;
return std::min(Pad(frame_width, kMinBlockSizePix), kMaxTileSize);
case TILE_SHAPE_FULL:
return frame_width;
default:
assert(false);
return 0;
}
}
static inline uint32_t TileHeight(TileShape tile_shape, uint32_t frame_width,
uint32_t frame_height) {
const uint32_t tile_width = TileWidth(tile_shape, frame_width, frame_height);
switch (tile_shape) {
case TILE_SHAPE_SQUARE_128:
case TILE_SHAPE_SQUARE_256:
case TILE_SHAPE_SQUARE_512:
return tile_width;
case TILE_SHAPE_WIDE:
// Should this be smaller than width?
return std::min(Pad(kMaxTilePixels / tile_width, kMinBlockSizePix),
kMaxTileSize);
case TILE_SHAPE_FULL:
return frame_height;
default:
assert(false);
return 0;
}
}
} // namespace WP2
//------------------------------------------------------------------------------
// Lossless constants.
namespace WP2L {
// Modes used in Group4 compression: pass is just about skipping the definition
// of a segment, horizontal mode is about defining the next two segments,
// vertical is about defining a segment with respect to the line above.
enum class Group4Mode { kVertical, kHorizontal, kPass };
// TODO(mouradfelipe): change location of LZW capacity definition.
// For now, it is defined as a value taken from the gifsicle GIF optimizer.
static constexpr uint32_t kLZWCapacity = 3963;
// Gives the maximum possible palette size for a given image size.
static inline uint32_t MaxPaletteSize(uint32_t num_pixels) {
// We only allow palettes of at least 2 elements.
if (num_pixels < 2) return 2;
// The palette cannot be bigger than the number of pixels.
return std::min(kMaxPaletteSize, num_pixels);
}
// Make sure that the palette + predictors can be encoded in ANS: this is
// definitely not a perfect static_assert but it is better than nothing.
static_assert(2 * kMaxPaletteSize < WP2::kANSMaxRange,
"Max palette size is too big.");
// Prefix code size when writing the ARGB ranges.
constexpr uint32_t kARGBRangePrefixSize = 1;
} // namespace WP2L
//------------------------------------------------------------------------------
#endif /* WP2_COMMON_CONSTANTS_H_ */