|
@@ -938,8 +938,7 @@ void predict_y_subblock(Span<i16> y_prediction, IntraBlockMode mode, int x, int
|
|
auto at = [&y_prediction, y, x](int px, int py) -> i16& { return y_prediction[(4 * y + py) * 16 + 4 * x + px]; };
|
|
auto at = [&y_prediction, y, x](int px, int py) -> i16& { return y_prediction[(4 * y + py) * 16 + 4 * x + px]; };
|
|
|
|
|
|
if (mode == B_DC_PRED) {
|
|
if (mode == B_DC_PRED) {
|
|
- // XXX spec text says this is like DC_PRED but predict_dc_nxn() in the sample impl looks like it doesn't do the "oob isn't read" part. what's right?
|
|
|
|
- // DC16NoTopLeft_C vs DC4_C in libwebp dec.c / common_dec.h suggests the spec text is incomplete :/
|
|
|
|
|
|
+ // The spec text says this is like DC_PRED, but predict_dc_nxn() in the sample implementation doesn't do the "oob isn't read" part.
|
|
int sum = 0, n = 8;
|
|
int sum = 0, n = 8;
|
|
for (int i = 0; i < 4; ++i)
|
|
for (int i = 0; i < 4; ++i)
|
|
sum += left[i] + above[i];
|
|
sum += left[i] + above[i];
|
|
@@ -952,12 +951,14 @@ void predict_y_subblock(Span<i16> y_prediction, IntraBlockMode mode, int x, int
|
|
for (int px = 0; px < 4; ++px)
|
|
for (int px = 0; px < 4; ++px)
|
|
y_prediction[(4 * y + py) * 16 + 4 * x + px] = clamp(left[py] + above[px] - corner, 0, 255);
|
|
y_prediction[(4 * y + py) * 16 + 4 * x + px] = clamp(left[py] + above[px] - corner, 0, 255);
|
|
} else if (mode == B_VE_PRED) {
|
|
} else if (mode == B_VE_PRED) {
|
|
|
|
+ // The spec text says this is like V_PRED, but the sample implementation shows it does weighted averages (unlike V_PRED).
|
|
for (int py = 0; py < 4; ++py)
|
|
for (int py = 0; py < 4; ++py)
|
|
for (int px = 0; px < 4; ++px) {
|
|
for (int px = 0; px < 4; ++px) {
|
|
auto top_left = (px > 0 ? above[px - 1] : corner);
|
|
auto top_left = (px > 0 ? above[px - 1] : corner);
|
|
y_prediction[(4 * y + py) * 16 + 4 * x + px] = weighted_average(top_left, above[px], above[px + 1]);
|
|
y_prediction[(4 * y + py) * 16 + 4 * x + px] = weighted_average(top_left, above[px], above[px + 1]);
|
|
}
|
|
}
|
|
} else if (mode == B_HE_PRED) {
|
|
} else if (mode == B_HE_PRED) {
|
|
|
|
+ // The spec text says this is like H_PRED, but the sample implementation shows it does weighted averages (unlike H_PRED).
|
|
for (int py = 0; py < 4; ++py)
|
|
for (int py = 0; py < 4; ++py)
|
|
for (int px = 0; px < 4; ++px) {
|
|
for (int px = 0; px < 4; ++px) {
|
|
if (py == 0) {
|
|
if (py == 0) {
|
|
@@ -1047,12 +1048,10 @@ void add_idct_to_prediction(Span<i16> prediction, Coefficients coefficients, int
|
|
short_idct4x4llm_c(coefficients, idct_output, 4 * sizeof(i16));
|
|
short_idct4x4llm_c(coefficients, idct_output, 4 * sizeof(i16));
|
|
|
|
|
|
// https://datatracker.ietf.org/doc/html/rfc6386#section-14.5 "Summation of Predictor and Residue"
|
|
// https://datatracker.ietf.org/doc/html/rfc6386#section-14.5 "Summation of Predictor and Residue"
|
|
- for (int py = 0; py < 4; ++py) { // Loop over 4x4 pixels in subblock
|
|
|
|
|
|
+ for (int py = 0; py < 4; ++py) {
|
|
for (int px = 0; px < 4; ++px) {
|
|
for (int px = 0; px < 4; ++px) {
|
|
- // sum with prediction
|
|
|
|
i16& p = prediction[(4 * y + py) * N + (4 * x + px)];
|
|
i16& p = prediction[(4 * y + py) * N + (4 * x + px)];
|
|
p += idct_output[py * 4 + px];
|
|
p += idct_output[py * 4 + px];
|
|
- // p = clamp(p, 0, 255);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|