Commit 20d66c65 authored by David Flynn's avatar David Flynn
Browse files

attr/m49601: add support to signal chroma (secondary) bitdepth

Some imput formats and colour spaces have a different bitdepth
for their chroma (non-primary) component.  This commit adds
support to signal their bitdepth as described by the codec
independent code points.
parent a8f27566
......@@ -377,6 +377,10 @@ AttributeDecoder::decodeColorsPred(
buildPredictorsFast(
aps, pointCloud, 0, predictors, numberOfPointsPerLOD, indexesLOD);
Vec3<int64_t> clipMax{(1 << desc.attr_bitdepth) - 1,
(1 << desc.attr_bitdepth_secondary) - 1,
(1 << desc.attr_bitdepth_secondary) - 1};
uint32_t values[3];
int zero_cnt = decoder.decodeZeroCnt(pointCount);
int quantLayer = 0;
......@@ -402,14 +406,13 @@ AttributeDecoder::decodeColorsPred(
const Vec3<attr_t> predictedColor =
predictor.predictColor(pointCloud, indexesLOD);
int64_t clipMax = (1 << desc.attr_bitdepth) - 1;
int64_t residual0 = 0;
for (int k = 0; k < 3; ++k) {
const auto& q = quant[std::min(k, 1)];
const int64_t residual = divExp2RoundHalfUp(
q.scale(UIntToInt(values[k])), kFixedPointAttributeShift);
const int64_t recon = predictedColor[k] + residual + residual0;
color[k] = attr_t(PCCClip(recon, int64_t(0), clipMax));
color[k] = attr_t(PCCClip(recon, int64_t(0), clipMax[k]));
if (!k && aps.inter_component_prediction_enabled_flag)
residual0 = residual;
......@@ -526,15 +529,18 @@ AttributeDecoder::decodeColorsRaht(
aps.raht_prediction_enabled_flag, quantLayers, mortonCode, attributes,
attribCount, voxelCount, coefficients);
const int clipMax = (1 << desc.attr_bitdepth) - 1;
Vec3<int> clipMax{(1 << desc.attr_bitdepth) - 1,
(1 << desc.attr_bitdepth_secondary) - 1,
(1 << desc.attr_bitdepth_secondary) - 1};
for (int n = 0; n < voxelCount; n++) {
const int r = attributes[attribCount * n];
const int g = attributes[attribCount * n + 1];
const int b = attributes[attribCount * n + 2];
Vec3<attr_t> color;
color[0] = attr_t(PCCClip(r, 0, clipMax));
color[1] = attr_t(PCCClip(g, 0, clipMax));
color[2] = attr_t(PCCClip(b, 0, clipMax));
color[0] = attr_t(PCCClip(r, 0, clipMax[0]));
color[1] = attr_t(PCCClip(g, 0, clipMax[1]));
color[2] = attr_t(PCCClip(b, 0, clipMax[2]));
pointCloud.setColor(packedVoxel[n].index, color);
}
......@@ -631,13 +637,16 @@ AttributeDecoder::decodeColorsLift(
PCCLiftPredict(predictors, startIndex, endIndex, false, colors);
}
const int64_t clipMax = (1 << desc.attr_bitdepth) - 1;
Vec3<int64_t> clipMax{(1 << desc.attr_bitdepth) - 1,
(1 << desc.attr_bitdepth_secondary) - 1,
(1 << desc.attr_bitdepth_secondary) - 1};
for (size_t f = 0; f < pointCount; ++f) {
const auto color0 =
divExp2RoundHalfInf(colors[f], kFixedPointAttributeShift);
Vec3<attr_t> color;
for (size_t d = 0; d < 3; ++d) {
color[d] = attr_t(PCCClip(color0[d], int64_t(0), clipMax));
color[d] = attr_t(PCCClip(color0[d], int64_t(0), clipMax[d]));
}
pointCloud.setColor(indexesLOD[f], color);
}
......
......@@ -670,7 +670,10 @@ AttributeEncoder::encodeColorsPred(
buildPredictorsFast(
aps, pointCloud, 0, predictors, numberOfPointsPerLOD, indexesLOD);
const int64_t clipMax = (1ll << desc.attr_bitdepth) - 1;
Vec3<int64_t> clipMax{(1 << desc.attr_bitdepth) - 1,
(1 << desc.attr_bitdepth_secondary) - 1,
(1 << desc.attr_bitdepth_secondary) - 1};
uint32_t values[3];
PCCResidualsEntropyEstimator context;
int zero_cnt = 0;
......@@ -720,7 +723,7 @@ AttributeEncoder::encodeColorsPred(
values[k] = uint32_t(IntToUInt(long(residualQ)));
int64_t recon = predictedColor[k] + residualR;
reconstructedColor[k] = attr_t(PCCClip(recon, int64_t(0), clipMax));
reconstructedColor[k] = attr_t(PCCClip(recon, int64_t(0), clipMax[k]));
}
pointCloud.setColor(pointIndex, reconstructedColor);
......@@ -886,15 +889,18 @@ AttributeEncoder::encodeColorsTransformRaht(
}
encoder.encodeZeroCnt(zero_cnt, voxelCount);
const int clipMax = (1 << desc.attr_bitdepth) - 1;
Vec3<int> clipMax{(1 << desc.attr_bitdepth) - 1,
(1 << desc.attr_bitdepth_secondary) - 1,
(1 << desc.attr_bitdepth_secondary) - 1};
for (int n = 0; n < voxelCount; n++) {
const int r = attributes[attribCount * n];
const int g = attributes[attribCount * n + 1];
const int b = attributes[attribCount * n + 2];
Vec3<attr_t> color;
color[0] = attr_t(PCCClip(r, 0, clipMax));
color[1] = attr_t(PCCClip(g, 0, clipMax));
color[2] = attr_t(PCCClip(b, 0, clipMax));
color[0] = attr_t(PCCClip(r, 0, clipMax[0]));
color[1] = attr_t(PCCClip(g, 0, clipMax[1]));
color[2] = attr_t(PCCClip(b, 0, clipMax[2]));
pointCloud.setColor(packedVoxel[n].index, color);
}
......@@ -996,13 +1002,16 @@ AttributeEncoder::encodeColorsLift(
PCCLiftPredict(predictors, startIndex, endIndex, false, colors);
}
const int64_t clipMax = (1 << desc.attr_bitdepth) - 1;
Vec3<int64_t> clipMax{(1 << desc.attr_bitdepth) - 1,
(1 << desc.attr_bitdepth_secondary) - 1,
(1 << desc.attr_bitdepth_secondary) - 1};
for (size_t f = 0; f < pointCount; ++f) {
const auto color0 =
divExp2RoundHalfInf(colors[f], kFixedPointAttributeShift);
Vec3<attr_t> color;
for (size_t d = 0; d < 3; ++d) {
color[d] = attr_t(PCCClip(color0[d], 0, clipMax));
color[d] = attr_t(PCCClip(color0[d], 0, clipMax[d]));
}
pointCloud.setColor(indexesLOD[f], color);
}
......
......@@ -770,6 +770,11 @@ ParseParameters(int argc, char* argv[], Parameters& params)
attr_sps.attributeLabel = KnownAttributeLabel::kColour;
}
// Derive the secondary bitdepth
// todo(df): this needs to be a command line argument
// -- but there are a few edge cases to handle
attr_sps.attr_bitdepth_secondary = attr_sps.attr_bitdepth;
bool isLifting =
attr_aps.attr_encoding == AttributeEncoding::kPredictingTransform
|| attr_aps.attr_encoding == AttributeEncoding::kLiftingTransform;
......@@ -855,10 +860,8 @@ ParseParameters(int argc, char* argv[], Parameters& params)
if (attr_sps.attr_bitdepth > 16)
err.error() << it.first << ".bitdepth must be less than 17\n";
if (it.first == "reflectance") {
if (attr_sps.attr_bitdepth > 16)
err.error() << it.first << ".bitdepth must be less than 17\n";
}
if (attr_sps.attr_bitdepth_secondary > 16)
err.error() << it.first << ".bitdepth_secondary must be less than 17\n";
if (isLifting) {
int lod = attr_aps.num_detail_levels;
......
......@@ -166,6 +166,7 @@ struct AttributeDescription {
int attr_num_dimensions;
int attr_instance_id;
int attr_bitdepth;
int attr_bitdepth_secondary;
int cicp_colour_primaries_idx;
int cicp_transfer_characteristics_idx;
ColourMatrix cicp_matrix_coefficients_idx;
......
......@@ -95,6 +95,7 @@ write(const SequenceParameterSet& sps)
bs.writeUe(attr.attr_num_dimensions);
bs.writeUe(attr.attr_instance_id);
bs.writeUe(attr.attr_bitdepth);
bs.writeUe(attr.attr_bitdepth_secondary);
bs.writeUe(attr.cicp_colour_primaries_idx);
bs.writeUe(attr.cicp_transfer_characteristics_idx);
bs.writeUe(attr.cicp_matrix_coefficients_idx);
......@@ -156,6 +157,7 @@ parseSps(const PayloadBuffer& buf)
bs.readUe(&attr.attr_num_dimensions);
bs.readUe(&attr.attr_instance_id);
bs.readUe(&attr.attr_bitdepth);
bs.readUe(&attr.attr_bitdepth_secondary);
bs.readUe(&attr.cicp_colour_primaries_idx);
bs.readUe(&attr.cicp_transfer_characteristics_idx);
bs.readUe(&attr.cicp_matrix_coefficients_idx);
......
......@@ -222,7 +222,9 @@ recolourColour(
std::vector<Vec3<attr_t>> refinedColors1;
refinedColors1.resize(pointCountTarget);
double clipMax = (1 << attrDesc.attr_bitdepth) - 1;
Vec3<double> clipMax{double((1 << attrDesc.attr_bitdepth) - 1),
double((1 << attrDesc.attr_bitdepth_secondary) - 1),
double((1 << attrDesc.attr_bitdepth_secondary) - 1)};
double maxGeometryDist2Fwd = params.maxGeometryDist2Fwd < 512
? params.maxGeometryDist2Fwd
......@@ -322,7 +324,7 @@ recolourColour(
}
for (int k = 0; k < 3; ++k) {
refinedColors1[index][k] =
attr_t(PCCClip(round(refinedColor[k]), 0.0, clipMax));
attr_t(PCCClip(round(refinedColor[k]), 0.0, clipMax[k]));
}
isDone = true;
}
......@@ -488,7 +490,7 @@ recolourColour(
Vec3<double> color0;
for (size_t k = 0; k < 3; ++k) {
color0[k] = PCCClip(
round(w * centroid1[k] + oneMinusW * centroid2[k]), 0.0, clipMax);
round(w * centroid1[k] + oneMinusW * centroid2[k]), 0.0, clipMax[k]);
}
const double rSource = 1.0 / double(pointCountSource);
const double rTarget = 1.0 / double(pointCountTarget);
......@@ -496,13 +498,13 @@ recolourColour(
Vec3<double> bestColor(color0);
Vec3<double> color;
for (int32_t s1 = -params.searchRange; s1 <= params.searchRange; ++s1) {
color[0] = PCCClip(color0[0] + s1, 0.0, clipMax);
color[0] = PCCClip(color0[0] + s1, 0.0, clipMax[0]);
for (int32_t s2 = -params.searchRange; s2 <= params.searchRange;
++s2) {
color[1] = PCCClip(color0[1] + s2, 0.0, clipMax);
color[1] = PCCClip(color0[1] + s2, 0.0, clipMax[1]);
for (int32_t s3 = -params.searchRange; s3 <= params.searchRange;
++s3) {
color[2] = PCCClip(color0[2] + s3, 0.0, clipMax);
color[2] = PCCClip(color0[2] + s3, 0.0, clipMax[2]);
double e1 = 0.0;
for (size_t k = 0; k < 3; ++k) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment