Commit 05526a18 authored by Toshiyasu Sugio's avatar Toshiyasu Sugio Committed by David Flynn
Browse files

attr/m46108: implement coefficient zero run length coding

This commit introduces zero run length coding for attribute residual
value along with an eq1 flag which indicates if residual value is equal
to 1 based on the current residual coding specification. In zero run
length coding, the number of zeros prior to each residual value is
counted as zerorun, and then zerorun is encoded instead of encoding
sequence of 0s
parent cc990c49
...@@ -53,11 +53,14 @@ struct PCCResidualsDecoder { ...@@ -53,11 +53,14 @@ struct PCCResidualsDecoder {
AdaptiveBitModel binaryModelDiff[7]; AdaptiveBitModel binaryModelDiff[7];
AdaptiveBitModel binaryModelIsZero[7]; AdaptiveBitModel binaryModelIsZero[7];
AdaptiveBitModel ctxPredMode[2]; AdaptiveBitModel ctxPredMode[2];
AdaptiveBitModel ctxZeroCnt[3];
AdaptiveBitModel binaryModelIsOne[7];
DualLutCoder<false> symbolCoder[2]; DualLutCoder<false> symbolCoder[2];
void start(const char* buf, int buf_len); void start(const char* buf, int buf_len);
void stop(); void stop();
int decodePredMode(int max); int decodePredMode(int max);
int decodeZeroCnt(int max);
uint32_t decodeSymbol(int k1, int k2); uint32_t decodeSymbol(int k1, int k2);
void decode(uint32_t values[3]); void decode(uint32_t values[3]);
uint32_t decode(); uint32_t decode();
...@@ -103,21 +106,42 @@ PCCResidualsDecoder::decodePredMode(int maxMode) ...@@ -103,21 +106,42 @@ PCCResidualsDecoder::decodePredMode(int maxMode)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
int
PCCResidualsDecoder::decodeZeroCnt(int maxMode)
{
int mode = 0;
if (maxMode == 0)
return mode;
int ctxIdx = 0;
while (arithmeticDecoder.decode(ctxZeroCnt[ctxIdx])) {
ctxIdx = (ctxIdx == 0 ? 1 : 2);
mode++;
if (mode == maxMode)
break;
}
return mode;
}
//----------------------------------------------------------------------------
uint32_t uint32_t
PCCResidualsDecoder::decodeSymbol(int k1, int k2) PCCResidualsDecoder::decodeSymbol(int k1, int k2)
{ {
if (arithmeticDecoder.decode(binaryModelIsZero[k1])) { if (arithmeticDecoder.decode(binaryModelIsZero[k1]))
return 0u; return 0u;
}
if (arithmeticDecoder.decode(binaryModelIsOne[k1]))
return 1u;
uint32_t value = symbolCoder[k2].decode(&arithmeticDecoder); uint32_t value = symbolCoder[k2].decode(&arithmeticDecoder);
if (value == kAttributeResidualAlphabetSize) { if (value == kAttributeResidualAlphabetSize) {
value += value +=
arithmeticDecoder.decodeExpGolomb(0, binaryModel0, binaryModelDiff[k1]); arithmeticDecoder.decodeExpGolomb(0, binaryModel0, binaryModelDiff[k1]);
} }
++value;
return value; return value + 2;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
...@@ -130,6 +154,11 @@ PCCResidualsDecoder::decode(uint32_t value[3]) ...@@ -130,6 +154,11 @@ PCCResidualsDecoder::decode(uint32_t value[3])
value[1] = decodeSymbol(1 + b0, 1); value[1] = decodeSymbol(1 + b0, 1);
int b1 = value[1] == 0; int b1 = value[1] == 0;
value[2] = decodeSymbol(3 + (b0 << 1) + b1, 1); value[2] = decodeSymbol(3 + (b0 << 1) + b1, 1);
int d = (value[0] == value[1] && value[0] == value[2]);
for (int k = 0; k < 3; k++) {
value[k] += d;
}
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
...@@ -137,7 +166,7 @@ PCCResidualsDecoder::decode(uint32_t value[3]) ...@@ -137,7 +166,7 @@ PCCResidualsDecoder::decode(uint32_t value[3])
uint32_t uint32_t
PCCResidualsDecoder::decode() PCCResidualsDecoder::decode()
{ {
return decodeSymbol(0, 0); return decodeSymbol(0, 0) + 1;
} }
//============================================================================ //============================================================================
...@@ -260,6 +289,7 @@ AttributeDecoder::decodeReflectancesPred( ...@@ -260,6 +289,7 @@ AttributeDecoder::decodeReflectancesPred(
} }
const int64_t maxReflectance = (1ll << desc.attr_bitdepth) - 1; const int64_t maxReflectance = (1ll << desc.attr_bitdepth) - 1;
int zero_cnt = decoder.decodeZeroCnt(pointCount);
for (size_t predictorIndex = 0; predictorIndex < pointCount; for (size_t predictorIndex = 0; predictorIndex < pointCount;
++predictorIndex) { ++predictorIndex) {
auto& predictor = predictors[predictorIndex]; auto& predictor = predictors[predictorIndex];
...@@ -268,7 +298,13 @@ AttributeDecoder::decodeReflectancesPred( ...@@ -268,7 +298,13 @@ AttributeDecoder::decodeReflectancesPred(
aps, pointCloud, indexesLOD, predictor, decoder); aps, pointCloud, indexesLOD, predictor, decoder);
const uint32_t pointIndex = indexesLOD[predictorIndex]; const uint32_t pointIndex = indexesLOD[predictorIndex];
uint16_t& reflectance = pointCloud.getReflectance(pointIndex); uint16_t& reflectance = pointCloud.getReflectance(pointIndex);
const uint32_t attValue0 = decoder.decode(); uint32_t attValue0 = 0;
if (zero_cnt > 0) {
zero_cnt--;
} else {
attValue0 = decoder.decode();
zero_cnt = decoder.decodeZeroCnt(pointCount);
}
const int64_t quantPredAttValue = const int64_t quantPredAttValue =
predictor.predictReflectance(pointCloud, indexesLOD); predictor.predictReflectance(pointCloud, indexesLOD);
const int64_t delta = const int64_t delta =
...@@ -349,6 +385,7 @@ AttributeDecoder::decodeColorsPred( ...@@ -349,6 +385,7 @@ AttributeDecoder::decodeColorsPred(
} }
uint32_t values[3]; uint32_t values[3];
int zero_cnt = decoder.decodeZeroCnt(pointCount);
for (size_t predictorIndex = 0; predictorIndex < pointCount; for (size_t predictorIndex = 0; predictorIndex < pointCount;
++predictorIndex) { ++predictorIndex) {
auto& predictor = predictors[predictorIndex]; auto& predictor = predictors[predictorIndex];
...@@ -356,7 +393,13 @@ AttributeDecoder::decodeColorsPred( ...@@ -356,7 +393,13 @@ AttributeDecoder::decodeColorsPred(
const int64_t qs2 = qstep[1]; const int64_t qs2 = qstep[1];
computeColorPredictionWeights( computeColorPredictionWeights(
aps, pointCloud, indexesLOD, predictor, decoder); aps, pointCloud, indexesLOD, predictor, decoder);
decoder.decode(values); if (zero_cnt > 0) {
values[0] = values[1] = values[2] = 0;
zero_cnt--;
} else {
decoder.decode(values);
zero_cnt = decoder.decodeZeroCnt(pointCount);
}
const uint32_t pointIndex = indexesLOD[predictorIndex]; const uint32_t pointIndex = indexesLOD[predictorIndex];
Vec3<uint8_t>& color = pointCloud.getColor(pointIndex); Vec3<uint8_t>& color = pointCloud.getColor(pointIndex);
const Vec3<uint8_t> predictedColor = const Vec3<uint8_t> predictedColor =
...@@ -408,10 +451,16 @@ AttributeDecoder::decodeReflectancesRaht( ...@@ -408,10 +451,16 @@ AttributeDecoder::decodeReflectancesRaht(
// Entropy decode // Entropy decode
const int attribCount = 1; const int attribCount = 1;
uint32_t value;
int* integerizedAttributes = new int[attribCount * voxelCount]; int* integerizedAttributes = new int[attribCount * voxelCount];
int zero_cnt = decoder.decodeZeroCnt(voxelCount);
for (int n = 0; n < voxelCount; ++n) { for (int n = 0; n < voxelCount; ++n) {
value = decoder.decode(); uint32_t value = 0;
if (zero_cnt > 0) {
zero_cnt--;
} else {
value = decoder.decode();
zero_cnt = decoder.decodeZeroCnt(voxelCount);
}
integerizedAttributes[n] = UIntToInt(value); integerizedAttributes[n] = UIntToInt(value);
} }
...@@ -467,11 +516,18 @@ AttributeDecoder::decodeColorsRaht( ...@@ -467,11 +516,18 @@ AttributeDecoder::decodeColorsRaht(
// Entropy decode // Entropy decode
const int attribCount = 3; const int attribCount = 3;
uint32_t values[3]; int zero_cnt = decoder.decodeZeroCnt(voxelCount);
int* integerizedAttributes = new int[attribCount * voxelCount]; int* integerizedAttributes = new int[attribCount * voxelCount];
for (int n = 0; n < voxelCount; ++n) { for (int n = 0; n < voxelCount; ++n) {
decoder.decode(values); uint32_t values[3];
if (zero_cnt > 0) {
values[0] = values[1] = values[2] = 0;
zero_cnt--;
} else {
decoder.decode(values);
zero_cnt = decoder.decodeZeroCnt(voxelCount);
}
for (int d = 0; d < attribCount; ++d) { for (int d = 0; d < attribCount; ++d) {
integerizedAttributes[voxelCount * d + n] = UIntToInt(values[d]); integerizedAttributes[voxelCount * d + n] = UIntToInt(values[d]);
} }
...@@ -540,10 +596,17 @@ AttributeDecoder::decodeColorsLift( ...@@ -540,10 +596,17 @@ AttributeDecoder::decodeColorsLift(
std::vector<Vec3<int64_t>> colors; std::vector<Vec3<int64_t>> colors;
colors.resize(pointCount); colors.resize(pointCount);
// decompress // decompress
int zero_cnt = decoder.decodeZeroCnt(pointCount);
for (size_t predictorIndex = 0; predictorIndex < pointCount; for (size_t predictorIndex = 0; predictorIndex < pointCount;
++predictorIndex) { ++predictorIndex) {
uint32_t values[3]; uint32_t values[3];
decoder.decode(values); if (zero_cnt > 0) {
values[0] = values[1] = values[2] = 0;
zero_cnt--;
} else {
decoder.decode(values);
zero_cnt = decoder.decodeZeroCnt(pointCount);
}
const int64_t qs = qstep[0] << (kFixedPointWeightShift / 2); const int64_t qs = qstep[0] << (kFixedPointWeightShift / 2);
const int64_t qs2 = qstep[1] << (kFixedPointWeightShift / 2); const int64_t qs2 = qstep[1] << (kFixedPointWeightShift / 2);
// + kFixedPointAttributeShift ??? // + kFixedPointAttributeShift ???
...@@ -617,9 +680,16 @@ AttributeDecoder::decodeReflectancesLift( ...@@ -617,9 +680,16 @@ AttributeDecoder::decodeReflectancesLift(
reflectances.resize(pointCount); reflectances.resize(pointCount);
// decompress // decompress
int zero_cnt = decoder.decodeZeroCnt(pointCount);
for (size_t predictorIndex = 0; predictorIndex < pointCount; for (size_t predictorIndex = 0; predictorIndex < pointCount;
++predictorIndex) { ++predictorIndex) {
const int64_t detail = decoder.decode(); int64_t detail = 0;
if (zero_cnt > 0) {
zero_cnt--;
} else {
detail = decoder.decode();
zero_cnt = decoder.decodeZeroCnt(pointCount);
}
const int64_t qs = qstep[0] << (kFixedPointWeightShift / 2); const int64_t qs = qstep[0] << (kFixedPointWeightShift / 2);
const int64_t quantWeight = weights[predictorIndex]; const int64_t quantWeight = weights[predictorIndex];
auto& reflectance = reflectances[predictorIndex]; auto& reflectance = reflectances[predictorIndex];
......
...@@ -57,11 +57,14 @@ struct PCCResidualsEncoder { ...@@ -57,11 +57,14 @@ struct PCCResidualsEncoder {
AdaptiveBitModel binaryModelDiff[7]; AdaptiveBitModel binaryModelDiff[7];
AdaptiveBitModel binaryModelIsZero[7]; AdaptiveBitModel binaryModelIsZero[7];
AdaptiveBitModel ctxPredMode[2]; AdaptiveBitModel ctxPredMode[2];
AdaptiveBitModel ctxZeroCnt[3];
AdaptiveBitModel binaryModelIsOne[7];
DualLutCoder<false> symbolCoder[2]; DualLutCoder<false> symbolCoder[2];
void start(int numPoints); void start(int numPoints);
int stop(); int stop();
void encodePredMode(int value, int max); void encodePredMode(int value, int max);
void encodeZeroCnt(int value, int max);
void encodeSymbol(uint32_t value, int k1, int k2); void encodeSymbol(uint32_t value, int k1, int k2);
void encode(uint32_t value0, uint32_t value1, uint32_t value2); void encode(uint32_t value0, uint32_t value1, uint32_t value2);
void encode(uint32_t value); void encode(uint32_t value);
...@@ -108,6 +111,26 @@ PCCResidualsEncoder::encodePredMode(int mode, int maxMode) ...@@ -108,6 +111,26 @@ PCCResidualsEncoder::encodePredMode(int mode, int maxMode)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void
PCCResidualsEncoder::encodeZeroCnt(int mode, int maxMode)
{
// max = 0 => no direct predictors are used
if (maxMode == 0)
return;
int ctxIdx = 0;
for (int i = 0; i < mode; i++) {
arithmeticEncoder.encode(1, ctxZeroCnt[ctxIdx]);
ctxIdx = (ctxIdx == 0 ? 1 : 2);
}
// Truncated unary
if (mode != maxMode)
arithmeticEncoder.encode(0, ctxZeroCnt[ctxIdx]);
}
//----------------------------------------------------------------------------
void void
PCCResidualsEncoder::encodeSymbol(uint32_t value, int k1, int k2) PCCResidualsEncoder::encodeSymbol(uint32_t value, int k1, int k2)
{ {
...@@ -116,7 +139,14 @@ PCCResidualsEncoder::encodeSymbol(uint32_t value, int k1, int k2) ...@@ -116,7 +139,14 @@ PCCResidualsEncoder::encodeSymbol(uint32_t value, int k1, int k2)
if (isZero) { if (isZero) {
return; return;
} }
--value;
bool isOne = value == 1;
arithmeticEncoder.encode(isOne, binaryModelIsOne[k1]);
if (isOne) {
return;
}
value -= 2;
if (value < kAttributeResidualAlphabetSize) { if (value < kAttributeResidualAlphabetSize) {
symbolCoder[k2].encode(value, &arithmeticEncoder); symbolCoder[k2].encode(value, &arithmeticEncoder);
} else { } else {
...@@ -132,6 +162,12 @@ PCCResidualsEncoder::encodeSymbol(uint32_t value, int k1, int k2) ...@@ -132,6 +162,12 @@ PCCResidualsEncoder::encodeSymbol(uint32_t value, int k1, int k2)
void void
PCCResidualsEncoder::encode(uint32_t value0, uint32_t value1, uint32_t value2) PCCResidualsEncoder::encode(uint32_t value0, uint32_t value1, uint32_t value2)
{ {
if (value0 == value1 && value0 == value2) {
value0--;
value1--;
value2--;
}
int b0 = value0 == 0; int b0 = value0 == 0;
int b1 = value1 == 0; int b1 = value1 == 0;
encodeSymbol(value0, 0, 0); encodeSymbol(value0, 0, 0);
...@@ -144,7 +180,7 @@ PCCResidualsEncoder::encode(uint32_t value0, uint32_t value1, uint32_t value2) ...@@ -144,7 +180,7 @@ PCCResidualsEncoder::encode(uint32_t value0, uint32_t value1, uint32_t value2)
void void
PCCResidualsEncoder::encode(uint32_t value) PCCResidualsEncoder::encode(uint32_t value)
{ {
encodeSymbol(value, 0, 0); encodeSymbol(value - 1, 0, 0);
} }
//============================================================================ //============================================================================
...@@ -371,6 +407,7 @@ AttributeEncoder::computeReflectancePredictionWeights( ...@@ -371,6 +407,7 @@ AttributeEncoder::computeReflectancePredictionWeights(
const int64_t qs) const int64_t qs)
{ {
predictor.computeWeights(); predictor.computeWeights();
predictor.maxDiff = -1;
if (predictor.neighborCount > 1) { if (predictor.neighborCount > 1) {
int64_t minValue = 0; int64_t minValue = 0;
int64_t maxValue = 0; int64_t maxValue = 0;
...@@ -385,6 +422,7 @@ AttributeEncoder::computeReflectancePredictionWeights( ...@@ -385,6 +422,7 @@ AttributeEncoder::computeReflectancePredictionWeights(
} }
} }
const int64_t maxDiff = maxValue - minValue; const int64_t maxDiff = maxValue - minValue;
predictor.maxDiff = maxDiff;
if (maxDiff > aps.adaptive_prediction_threshold) { if (maxDiff > aps.adaptive_prediction_threshold) {
uint64_t attrValue = uint64_t attrValue =
pointCloud.getReflectance(indexesLOD[predictorIndex]); pointCloud.getReflectance(indexesLOD[predictorIndex]);
...@@ -418,9 +456,6 @@ AttributeEncoder::computeReflectancePredictionWeights( ...@@ -418,9 +456,6 @@ AttributeEncoder::computeReflectancePredictionWeights(
// with reconstruction. // with reconstruction.
} }
} }
encoder.encodePredMode(
predictor.predMode, aps.max_num_direct_predictors);
} }
} }
} }
...@@ -460,6 +495,12 @@ AttributeEncoder::encodeReflectancesPred( ...@@ -460,6 +495,12 @@ AttributeEncoder::encodeReflectancesPred(
const int64_t clipMax = (1ll << desc.attr_bitdepth) - 1; const int64_t clipMax = (1ll << desc.attr_bitdepth) - 1;
PCCResidualsEntropyEstimator context; PCCResidualsEntropyEstimator context;
int zero_cnt = 0;
std::vector<int> zerorun;
zerorun.reserve(pointCount);
std::vector<uint32_t> residual;
residual.resize(pointCount);
for (size_t predictorIndex = 0; predictorIndex < pointCount; for (size_t predictorIndex = 0; predictorIndex < pointCount;
++predictorIndex) { ++predictorIndex) {
auto& predictor = predictors[predictorIndex]; auto& predictor = predictors[predictorIndex];
...@@ -483,9 +524,37 @@ AttributeEncoder::encodeReflectancesPred( ...@@ -483,9 +524,37 @@ AttributeEncoder::encodeReflectancesPred(
const uint16_t reconstructedReflectance = const uint16_t reconstructedReflectance =
uint16_t(PCCClip(reconstructedQuantAttValue, int64_t(0), clipMax)); uint16_t(PCCClip(reconstructedQuantAttValue, int64_t(0), clipMax));
encoder.encode(attValue0); if (!attValue0)
++zero_cnt;
else {
zerorun.push_back(zero_cnt);
zero_cnt = 0;
}
residual[predictorIndex] = attValue0;
pointCloud.setReflectance(pointIndex, reconstructedReflectance); pointCloud.setReflectance(pointIndex, reconstructedReflectance);
} }
zerorun.push_back(zero_cnt);
int run_index = 0;
encoder.encodeZeroCnt(zerorun[run_index], pointCount);
zero_cnt = zerorun[run_index++];
for (size_t predictorIndex = 0; predictorIndex < pointCount;
++predictorIndex) {
auto& predictor = predictors[predictorIndex];
if (predictor.maxDiff > aps.adaptive_prediction_threshold) {
encoder.encodePredMode(
predictor.predMode, aps.max_num_direct_predictors);
}
if (zero_cnt > 0)
zero_cnt--;
else {
encoder.encode(residual[predictorIndex]);
if (predictorIndex != pointCount - 1)
encoder.encodeZeroCnt(zerorun[run_index], pointCount);
zero_cnt = zerorun[run_index++];
}
}
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
...@@ -528,6 +597,7 @@ AttributeEncoder::computeColorPredictionWeights( ...@@ -528,6 +597,7 @@ AttributeEncoder::computeColorPredictionWeights(
const int64_t qs2) const int64_t qs2)
{ {
predictor.computeWeights(); predictor.computeWeights();
predictor.maxDiff = -1;
if (predictor.neighborCount > 1) { if (predictor.neighborCount > 1) {
int64_t minValue[3] = {0, 0, 0}; int64_t minValue[3] = {0, 0, 0};
int64_t maxValue[3] = {0, 0, 0}; int64_t maxValue[3] = {0, 0, 0};
...@@ -546,6 +616,8 @@ AttributeEncoder::computeColorPredictionWeights( ...@@ -546,6 +616,8 @@ AttributeEncoder::computeColorPredictionWeights(
const int64_t maxDiff = (std::max)( const int64_t maxDiff = (std::max)(
maxValue[2] - minValue[2], maxValue[2] - minValue[2],
(std::max)(maxValue[0] - minValue[0], maxValue[1] - minValue[1])); (std::max)(maxValue[0] - minValue[0], maxValue[1] - minValue[1]));
predictor.maxDiff = maxDiff;
if (maxDiff > aps.adaptive_prediction_threshold) { if (maxDiff > aps.adaptive_prediction_threshold) {
Vec3<uint8_t> attrValue = Vec3<uint8_t> attrValue =
pointCloud.getColor(indexesLOD[predictorIndex]); pointCloud.getColor(indexesLOD[predictorIndex]);
...@@ -581,9 +653,6 @@ AttributeEncoder::computeColorPredictionWeights( ...@@ -581,9 +653,6 @@ AttributeEncoder::computeColorPredictionWeights(
// with reconstruction. // with reconstruction.
} }
} }
encoder.encodePredMode(
predictor.predMode, aps.max_num_direct_predictors);
} }
} }
} }
...@@ -624,6 +693,14 @@ AttributeEncoder::encodeColorsPred( ...@@ -624,6 +693,14 @@ AttributeEncoder::encodeColorsPred(
const int64_t clipMax = (1ll << desc.attr_bitdepth) - 1; const int64_t clipMax = (1ll << desc.attr_bitdepth) - 1;
uint32_t values[3]; uint32_t values[3];
PCCResidualsEntropyEstimator context; PCCResidualsEntropyEstimator context;
int zero_cnt = 0;
std::vector<int> zerorun;
std::vector<uint32_t> residual[3];
for (int i = 0; i < 3; i++) {
residual[i].resize(pointCount);
}
for (size_t predictorIndex = 0; predictorIndex < pointCount; for (size_t predictorIndex = 0; predictorIndex < pointCount;
++predictorIndex) { ++predictorIndex) {
auto& predictor = predictors[predictorIndex]; auto& predictor = predictors[predictorIndex];
...@@ -661,7 +738,41 @@ AttributeEncoder::encodeColorsPred( ...@@ -661,7 +738,41 @@ AttributeEncoder::encodeColorsPred(
uint8_t(PCCClip(reconstructedQuantAttValue, int64_t(0), clipMax)); uint8_t(PCCClip(reconstructedQuantAttValue, int64_t(0), clipMax));
} }
pointCloud.setColor(pointIndex, reconstructedColor); pointCloud.setColor(pointIndex, reconstructedColor);
encoder.encode(values[0], values[1], values[2]);
if (!values[0] && !values[1] && !values[2]) {
++zero_cnt;
} else {
zerorun.push_back(zero_cnt);
zero_cnt = 0;
}
for (int i = 0; i < 3; i++) {
residual[i][predictorIndex] = values[i];
}
}
zerorun.push_back(zero_cnt);
int run_index = 0;
encoder.encodeZeroCnt(zerorun[run_index], pointCount);
zero_cnt = zerorun[run_index++];
for (size_t predictorIndex = 0; predictorIndex < pointCount;
++predictorIndex) {
auto& predictor = predictors[predictorIndex];
if (predictor.maxDiff > aps.adaptive_prediction_threshold) {
encoder.encodePredMode(
predictor.predMode, aps.max_num_direct_predictors);
}
if (zero_cnt > 0)
zero_cnt--;
else {
for (size_t k = 0; k < 3; k++)
values[k] = residual[k][predictorIndex];
encoder.encode(values[0], values[1], values[2]);
if (predictorIndex != pointCount - 1)
encoder.encodeZeroCnt(zerorun[run_index], pointCount);
zero_cnt = zerorun[run_index++];
}
} }
} }
...@@ -705,13 +816,21 @@ AttributeEncoder::encodeReflectancesTransformRaht( ...@@ -705,13 +816,21 @@ AttributeEncoder::encodeReflectancesTransformRaht(
attribCount, voxelCount, integerizedAttributes); attribCount, voxelCount, integerizedAttributes);
// Entropy encode. // Entropy encode.
int zero_cnt = 0;
uint32_t value; uint32_t value;
for (int n = 0; n < voxelCount; ++n) { for (int n = 0; n < voxelCount; ++n) {
const int64_t detail = IntToUInt(integerizedAttributes[n]); const int64_t detail = IntToUInt(integerizedAttributes[n]);
assert(detail < std::numeric_limits<uint32_t>::max()); assert(detail < std::numeric_limits<uint32_t>::max());
value = uint32_t(detail); value = uint32_t(detail);