libpayload: cbgfx: Fix 'equals' counter for Lanczos resampling
The current initialization of the 'equals' counter is incorrect, so that when 'equals >= SSZ * SSZ', the pixels in the sample array might not be all the same, leading to a wrong pixel value being set in the framebuffer. The 'equals' counter stores the number of latest pixels that were exactly equal. Within the for loop of 'ox', the sample array is updated in a column-based order, and the 'equals' counter is updated accordingly. However, the 'equals' counter is initialized in a row-based order, which causes it to be set too large than it should be. Consider the example where sample[sx][sy] are initially: [X X X A A A] // sy = 0 [X X X B B B] [X X X B B B] [X X X B B B] [X X X B B B] [X X X B B B] // sy = SSZ Then, the correct implementation will initialize 'equals' to be 15, with last_equal being B. Suppose all of the remaining pixels are B. Then, at the end of the 'while (fpfloor(ixfp) > ix)' loop when ix = 4, or equivalently after 4 more columns of sample are updated, 'equals' will be 15 + 6 * 4 = 39, which is greater than SSZ * SSZ = 36, but we can see there are still 2 A's in the sample: [B B B B A A] [B B B B B B] [B B B B B B] [B B B B B B] [B B B B B B] [B B B B B B] Therefore, we must also initialize the 'equals' counter in a column-based order. BUG=b:167739127 TEST=emerge-puff libpayload TEST=Character 'k' is rendered correctly on puff BRANCH=zork Change-Id: Ibc91ad1af85adcf093eff40797cd54f32f57111d Signed-off-by: Yu-Ping Wu <yupingso@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/45235 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
parent
5d1a328e88
commit
541f2f74a3
|
@ -858,24 +858,25 @@ static int draw_bitmap_v3(const struct vector *top_left,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the sample array for this line. For pixels to the
|
* Initialize the sample array for this line, and also
|
||||||
* left of S0 there are no corresponding input pixels so just
|
* the equals counter, which counts how many of the latest
|
||||||
* copy the S0 values over.
|
* pixels were exactly equal.
|
||||||
*
|
|
||||||
* Also initialize the equals counter, which counts how many of
|
|
||||||
* the latest pixels were exactly equal. We know the columns
|
|
||||||
* left of S0 must be equal to S0, so start with that number.
|
|
||||||
*/
|
*/
|
||||||
int equals = S0 * SSZ;
|
int equals = 0;
|
||||||
uint8_t last_equal = ypix[0][0];
|
uint8_t last_equal = ypix[0][0];
|
||||||
|
for (sx = 0; sx < SSZ; sx++) {
|
||||||
for (sy = 0; sy < SSZ; sy++) {
|
for (sy = 0; sy < SSZ; sy++) {
|
||||||
for (sx = S0; sx < SSZ; sx++) {
|
if (sx - S0 >= dim_org->width) {
|
||||||
if (sx >= dim_org->width) {
|
|
||||||
sample[sx][sy] = sample[sx - 1][sy];
|
sample[sx][sy] = sample[sx - 1][sy];
|
||||||
equals++;
|
equals++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
uint8_t i = ypix[sy][sx - S0];
|
/*
|
||||||
|
* For pixels to the left of S0 there are no
|
||||||
|
* corresponding input pixels so just use
|
||||||
|
* ypix[sy][0].
|
||||||
|
*/
|
||||||
|
uint8_t i = ypix[sy][MAX(0, sx - S0)];
|
||||||
if (pal_to_rgb(i, pal, header->colors_used,
|
if (pal_to_rgb(i, pal, header->colors_used,
|
||||||
&sample[sx][sy]))
|
&sample[sx][sy]))
|
||||||
goto bitmap_error;
|
goto bitmap_error;
|
||||||
|
@ -886,8 +887,6 @@ static int draw_bitmap_v3(const struct vector *top_left,
|
||||||
equals = 1;
|
equals = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (sx = S0 - 1; sx >= 0; sx--)
|
|
||||||
sample[sx][sy] = sample[S0][sy];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ix = 0;
|
ix = 0;
|
||||||
|
|
Loading…
Reference in New Issue