Commit 1654a45d authored by Sehoon Yea's avatar Sehoon Yea Committed by David Flynn
Browse files

attr/m49601: add YCgCoR colour transform support

This commit adds the lossless YCgCoR colour transform.
The CTC configuration is updated to use YCgCoR for lossless
attribute coding instead of inter-component prediction on
GBR (colourMatrix=0) data.
parent 20d66c65
......@@ -21,7 +21,8 @@ categories:
# attribute coding (common options -- relies on option ordering)
# - skip attribute coding if dist2 parameters are not defined
# -- this may seem odd, but is required for lossy-geom data
# - avoid measuring loss of colourspace conversion
# - use YCgCoR colour space to avoid conversion losses
# NB: inter component prediction doesn't work well in non-RGB space
# - scale 16bit reflectance data to 8bit
# - use predicting transform for lossless conditions
# - automatically derive dist2 based on single initial value by the encoder:
......@@ -29,7 +30,7 @@ categories:
# - generates dist2 per lod
-
- !conditional 'defined ${seq_lod} && defined ${seq_dist2}'
- convertPlyColourspace: 0
- convertPlyColourspace: 1
-
- !conditional '${reflectance8b16b_scale_factor}'
- hack.reflectanceScale: ${reflectance8b16b_scale_factor}
......@@ -43,7 +44,7 @@ categories:
- positionQuantizationScaleAdjustsDist2: 1
- dist2: ${seq_dist2}
- intraLodPredictionEnabled: 1
- interComponentPredictionEnabled: 1
- interComponentPredictionEnabled: 0
##
# attribute coding -- reflectance
......@@ -62,12 +63,12 @@ categories:
- qp: 4
- qpChromaOffset: 0
- bitdepth: 8
- colourMatrix: 0
- colourMatrix: 8
- attribute: color
decflags:
- mode: 1
- convertPlyColourspace: 0
- convertPlyColourspace: 1
-
- !conditional '${reflectance8b16b_scale_factor}'
- hack.reflectanceScale: ${reflectance8b16b_scale_factor}
......
......@@ -302,11 +302,14 @@ decoder if supported.
| 5 | No | YCbCr ITU-R BT.601 |
| 6 | No | YCbCr SMPTE 170M |
| 7 | No | YCbCr SMPTE 240M |
| 8 | No | YCgCo / YCgCoR |
| 8 | Yes (YCgCoR) | YCgCo / YCgCoR |
| 9 | No | YCbCr ITU-R BT.2020 |
| 10 | No | YCbCr ITU-R BT.2020 (constant luminance) |
| 11 | No | YDzDx SMPTE ST 2085 |
NB: the use of YCgCoR and `bitdepth=N` implies that the bitdepth of the
chroma component bitdepth is N + 1.
### `--bitdepth=INT-VALUE`
The bitdepth of the attribute data. NB, this is not necessarily the
same as the bitdepth of the PLY property.
......
......@@ -561,7 +561,8 @@ ParseParameters(int argc, char* argv[], Parameters& params)
params_attr.desc.cicp_matrix_coefficients_idx, ColourMatrix::kBt709,
"Matrix used in colourspace conversion\n"
" 0: none (identity)\n"
" 1: ITU-T BT.709")
" 1: ITU-T BT.709\n"
" 8: YCgCo")
("transformType",
params_attr.aps.attr_encoding, AttributeEncoding::kPredictingTransform,
......@@ -775,6 +776,10 @@ ParseParameters(int argc, char* argv[], Parameters& params)
// -- but there are a few edge cases to handle
attr_sps.attr_bitdepth_secondary = attr_sps.attr_bitdepth;
// Assume that YCgCo is actually YCgCoR for now
if (attr_sps.cicp_matrix_coefficients_idx == ColourMatrix::kYCgCo)
attr_sps.attr_bitdepth_secondary++;
bool isLifting =
attr_aps.attr_encoding == AttributeEncoding::kPredictingTransform
|| attr_aps.attr_encoding == AttributeEncoding::kLiftingTransform;
......@@ -1219,6 +1224,11 @@ convertToGbr(const SequenceParameterSet& sps, PCCPointSet3& cloud)
switch (attrDesc->cicp_matrix_coefficients_idx) {
case ColourMatrix::kBt709: convertYCbCrBt709ToGbr(cloud); break;
case ColourMatrix::kYCgCo:
// todo(df): select YCgCoR vs YCgCo
convertYCgCoRToGbr(attrDesc->attr_bitdepth, cloud);
break;
default: break;
}
}
......@@ -1235,6 +1245,11 @@ convertFromGbr(const SequenceParameterSet& sps, PCCPointSet3& cloud)
switch (attrDesc->cicp_matrix_coefficients_idx) {
case ColourMatrix::kBt709: convertGbrToYCbCrBt709(cloud); break;
case ColourMatrix::kYCgCo:
// todo(df): select YCgCoR vs YCgCo
convertGbrToYCgCoR(attrDesc->attr_bitdepth, cloud);
break;
default: break;
}
}
......
......@@ -79,4 +79,50 @@ transformYCbCrBt709ToGbr(T<Tv>& ycbcr)
//============================================================================
template<template<typename> class T, typename Tv>
T<Tv>
transformGbrToYCgCoR(int bitDepth, T<Tv>& gbr)
{
int g = gbr[0];
int b = gbr[1];
int r = gbr[2];
int co = r - b;
int t = b + (co >> 1);
int cg = g - t;
int y = t + (cg >> 1);
int offset = 1 << bitDepth;
// NB: YCgCoR needs extra 1-bit for chroma
return {Tv(y), Tv(cg + offset), Tv(co + offset)};
}
//============================================================================
template<template<typename> class T, typename Tv>
T<Tv>
transformYCgCoRToGbr(int bitDepth, T<Tv>& ycgco)
{
int offset = 1 << bitDepth;
int y0 = ycgco[0];
int cg = ycgco[1] - offset;
int co = ycgco[2] - offset;
int t = y0 - (cg >> 1);
int g = cg + t;
int b = t - (co >> 1);
int r = co + b;
int maxVal = (1 << bitDepth) - 1;
g = PCCClip(g, 0, maxVal);
b = PCCClip(b, 0, maxVal);
r = PCCClip(r, 0, maxVal);
return {Tv(g), Tv(b), Tv(r)};
}
//============================================================================
} // namespace pcc
......@@ -912,6 +912,28 @@ recolour(
//============================================================================
void
convertGbrToYCgCoR(int bitDepth, PCCPointSet3& cloud)
{
for (int i = 0; i < cloud.getPointCount(); i++) {
auto& val = cloud.getColor(i);
val = transformGbrToYCgCoR(bitDepth, val);
}
}
//============================================================================
void
convertYCgCoRToGbr(int bitDepth, PCCPointSet3& cloud)
{
for (int i = 0; i < cloud.getPointCount(); i++) {
auto& val = cloud.getColor(i);
val = transformYCgCoRToGbr(bitDepth, val);
}
}
//============================================================================
void
convertGbrToYCbCrBt709(PCCPointSet3& cloud)
{
......
......@@ -180,6 +180,9 @@ int recolour(
void convertGbrToYCbCrBt709(PCCPointSet3&);
void convertYCbCrBt709ToGbr(PCCPointSet3&);
void convertGbrToYCgCoR(int bitDepth, PCCPointSet3&);
void convertYCgCoRToGbr(int bitDepth, PCCPointSet3&);
//============================================================================
} // namespace pcc
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