// Copyright (c) the JPEG XL Project Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file.
// This constructor is not constexpr so it can't be used in any of the // constexpr cases above. explicit QuantEncodingInternal(Mode mode) : mode(mode) {}
Mode mode;
// Weights for DCT4+ tables.
DctQuantWeightParams dct_params;
union { // Weights for identity.
IdWeights idweights;
// Weights for DCT2.
DCT2Weights dct2weights;
// Extra multipliers for coefficients 01/10 and 11 for DCT4 and AFV.
DCT4Multipliers dct4multipliers;
// Weights for AFV. {0, 1} are used directly for coefficients (0, 1) and (1, // 0); {2, 3, 4} are used directly corner DC, (1,0) - (0,1) and (0, 1) + // (1, 0) - (0, 0) inside the AFV block. Values from 5 to 8 are interpolated // as in GetQuantWeights for DC and are used for other coefficients.
AFVWeights afv_weights = {};
// Extra multipliers for coefficients 01 or 10 for DCT4X8 and DCT8X4.
DCT4x8Multipliers dct4x8multipliers;
// Only used in kQuantModeRAW mode. struct { // explicit quantization table (like in JPEG)
std::vector<int>* qtable = nullptr; float qtable_den = 1.f / (8 * 255);
} qraw;
};
// Weights for 4x4 sub-block in AFV.
DctQuantWeightParams dct_params_afv_4x4;
union { // Which predefined table to use. Only used if mode is kQuantModeLibrary.
uint8_t predefined = 0;
// Which other quant table to copy; must copy from a table that comes before // the current one. Only used if mode is kQuantModeCopy.
uint8_t source;
};
};
class QuantEncoding final : public QuantEncodingInternal { public:
QuantEncoding(const QuantEncoding& other)
: QuantEncodingInternal( static_cast<const QuantEncodingInternal&>(other)) { if (mode == kQuantModeRAW && qraw.qtable) { // Need to make a copy of the passed *qtable.
qraw.qtable = new std::vector<int>(*other.qraw.qtable);
}
}
QuantEncoding(QuantEncoding&& other) noexcept
: QuantEncodingInternal( static_cast<const QuantEncodingInternal&>(other)) { // Steal the qtable from the other object if any. if (mode == kQuantModeRAW) {
other.qraw.qtable = nullptr;
}
}
QuantEncoding& operator=(const QuantEncoding& other) { if (mode == kQuantModeRAW && qraw.qtable) { delete qraw.qtable;
}
*static_cast<QuantEncodingInternal*>(this) =
QuantEncodingInternal(static_cast<const QuantEncodingInternal&>(other)); if (mode == kQuantModeRAW && qraw.qtable) { // Need to make a copy of the passed *qtable.
qraw.qtable = new std::vector<int>(*other.qraw.qtable);
} return *this;
}
// Wrappers of the QuantEncodingInternal:: static functions that return a // QuantEncoding instead. This is using the explicit and private cast from // QuantEncodingInternal to QuantEncoding, which would be inlined anyway. // In general, you should use this wrappers. The only reason to directly // create a QuantEncodingInternal instance is if you need a constexpr version // of this class. Note that RAW() is not supported in that case since it uses // a std::vector. template <size_t A> static QuantEncoding Library() { return QuantEncoding(QuantEncodingInternal::Library<A>());
} static QuantEncoding Identity(const IdWeights& xybweights) { return QuantEncoding(QuantEncodingInternal::Identity(xybweights));
} static QuantEncoding DCT2(const DCT2Weights& xybweights) { return QuantEncoding(QuantEncodingInternal::DCT2(xybweights));
} static QuantEncoding DCT4(const DctQuantWeightParams& params, const DCT4Multipliers& xybmul) { return QuantEncoding(QuantEncodingInternal::DCT4(params, xybmul));
} static QuantEncoding DCT4X8(const DctQuantWeightParams& params, const DCT4x8Multipliers& xybmul) { return QuantEncoding(QuantEncodingInternal::DCT4X8(params, xybmul));
} static QuantEncoding DCT(const DctQuantWeightParams& params) { return QuantEncoding(QuantEncodingInternal::DCT(params));
} static QuantEncoding AFV(const DctQuantWeightParams& params4x8, const DctQuantWeightParams& params4x4, const AFVWeights& weights) { return QuantEncoding(
QuantEncodingInternal::AFV(params4x8, params4x4, weights));
}
// RAW, note that this one is not a constexpr one. static QuantEncoding RAW(std::vector<int>&& qtable, int shift = 0) {
QuantEncoding encoding(kQuantModeRAW);
encoding.qraw.qtable = new std::vector<int>();
*encoding.qraw.qtable = qtable;
encoding.qraw.qtable_den = (1 << shift) * (1.f / (8 * 255)); return encoding;
}
// A constexpr QuantEncodingInternal instance is often downcasted to the // QuantEncoding subclass even if the instance wasn't an instance of the // subclass. This is safe because user will upcast to QuantEncodingInternal to // access any of its members.
static_assert(sizeof(QuantEncoding) == sizeof(QuantEncodingInternal), "Don't add any members to QuantEncoding");
// Let's try to keep these 2**N for possible future simplicity. constfloat kInvDCQuant[3] = {
4096.0f,
512.0f,
256.0f,
};
class DequantMatrices { public:
DequantMatrices();
staticconst QuantEncoding* Library();
typedef std::array<QuantEncodingInternal,
kNumPredefinedTables * kNumQuantTables>
DequantLibraryInternal; // Return the array of library kNumPredefinedTables QuantEncoding entries as // a constexpr array. Use Library() to obtain a pointer to the copy in the // .cc file. static DequantLibraryInternal LibraryInit();
// DC quants are used in modular mode for XYB multipliers.
JXL_INLINE float DCQuant(size_t c) const { return dc_quant_[c]; }
JXL_INLINE constfloat* DCQuants() const { return dc_quant_; }
JXL_INLINE float InvDCQuant(size_t c) const { return inv_dc_quant_[c]; }
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.