in vireo/frame/yuv.cpp [122:207]
auto YUV::full_range(bool full_range) -> YUV {
THROW_IF(_this->full_range == full_range, InvalidArguments);
frame::YUV new_yuv(width(), height(), uv_ratio().first, uv_ratio().second, full_range);
uint8_t* const src[] = {
(uint8_t* const)plane(frame::Y).bytes().data(),
(uint8_t* const)plane(frame::U).bytes().data(),
(uint8_t* const)plane(frame::V).bytes().data()
};
uint8_t* const dst[] = {
(uint8_t* const)new_yuv.plane(frame::Y).bytes().data(),
(uint8_t* const)new_yuv.plane(frame::U).bytes().data(),
(uint8_t* const)new_yuv.plane(frame::V).bytes().data()
};
const int src_stride[] = {
plane(frame::Y).row(),
plane(frame::U).row(),
plane(frame::V).row()
};
const int dst_stride[] = {
new_yuv.plane(frame::Y).row(),
new_yuv.plane(frame::U).row(),
new_yuv.plane(frame::V).row()
};
const int width[] = {
plane(frame::Y).width(),
plane(frame::U).width(),
plane(frame::V).width()
};
const int height[] = {
plane(frame::Y).height(),
plane(frame::U).height(),
plane(frame::V).height()
};
#define CLIP3(x, low, high) ({\
__typeof__(x) _x = x;\
(((_x) < (low)) ? (low) : ((_x) > (high)) ? (high) : (_x));\
})
const int16_t _0 = 0;
const int16_t _16 = 16;
const int16_t _219 = 219;
const int16_t _224 = 224;
const int16_t _128 = 128;
const int16_t _235 = 235;
const int16_t _240 = 240;
const int16_t _255 = 255;
if (full_range) {
int p = frame::Y;
for (int y = 0; y < height[p]; ++y) {
uint8_t* sptr = src[p] + y * src_stride[p];
uint8_t* dptr = dst[p] + y * dst_stride[p];
for (int x = 0, w = width[p]; x < w; ++x) {
*dptr++ = (uint8_t)CLIP3((int16_t)_255 * ((int16_t)*sptr++ - _16) / _219, _0, _255);
}
}
for (auto p: enumeration::Enum<frame::PlaneIndex>(frame::U, frame::V)) {
for (int y = 0; y < height[p]; ++y) {
uint8_t* sptr = src[p] + y * src_stride[p];
uint8_t* dptr = dst[p] + y * dst_stride[p];
for (int x = 0, w = width[p]; x < w; ++x) {
*dptr++ = (uint8_t)CLIP3((int16_t)_255 * ((int16_t)*sptr++ - _128) / _224 + _128, _0, _255);
}
}
}
} else {
int p = frame::Y;
for (int y = 0; y < height[p]; ++y) {
uint8_t* sptr = src[p] + y * src_stride[p];
uint8_t* dptr = dst[p] + y * dst_stride[p];
for (int x = 0, w = width[p]; x < w; ++x) {
*dptr++ = (uint8_t)CLIP3((int16_t)_219 * *sptr++ / _255 + _16, _16, _235);
}
}
for (auto p: enumeration::Enum<frame::PlaneIndex>(frame::U, frame::V)) {
for (int y = 0; y < height[p]; ++y) {
uint8_t* sptr = src[p] + y * src_stride[p];
uint8_t* dptr = dst[p] + y * dst_stride[p];
for (int x = 0, w = width[p]; x < w; ++x) {
*dptr++ = (uint8_t)CLIP3((int16_t)_224 * ((int16_t)*sptr++ - _128) / _255 + _128, _16, _240);
}
}
}
}
return new_yuv;
}