diff options
-rw-r--r-- | engines/gob/video_v6.cpp | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/engines/gob/video_v6.cpp b/engines/gob/video_v6.cpp index dd71e3ba51..23610aded1 100644 --- a/engines/gob/video_v6.cpp +++ b/engines/gob/video_v6.cpp @@ -126,11 +126,41 @@ void Video_v6::drawYUV(Surface &destDesc, int16 x, int16 y, for (int i = 0; i < height; i++) { Pixel dstRow = dst; + int nextChromaLine = (i < ((height - 1) & ~3) ) ? dataWidth : 0; + for (int j = 0; j < width; j++, dstRow++) { - // Get (7bit) YUV data - byte dY = dataY[j ] << 1; - byte dU = dataU[j >> 2] << 1; - byte dV = dataV[j >> 2] << 1; + + int nextChromaColumn = (j < ((width - 1) & ~3)) ? 1 : 0; + + // Get (7bit) Y data. It is at full res, does not need to be interpolated + byte dY = dataY[j] << 1; + + // do linear interpolation on chroma values (7bits) + // to avoid blockiness + byte dU0 = dataU[j >> 2]; + byte dV0 = dataV[j >> 2]; + + byte dU1 = dataU[(j >> 2) + nextChromaColumn]; + byte dV1 = dataV[(j >> 2) + nextChromaColumn]; + + byte dU2 = dataU[(j + nextChromaLine) >> 2]; + byte dV2 = dataV[(j + nextChromaLine) >> 2]; + + byte dU3 = dataU[((j + nextChromaLine) >> 2) + nextChromaColumn]; + byte dV3 = dataV[((j + nextChromaLine) >> 2) + nextChromaColumn]; + + byte tX = j & 3; + byte tY = i & 3; + byte invtX = 4 - tX; + byte invtY = 4 - tY; + + int16 dUX1 = dU0 * invtX + dU1 * tX; + int16 dUX2 = dU2 * invtX + dU3 * tX; + byte dU = (dUX1 * invtY + dUX2 * tY) >> 3; + + int16 dVY1 = dV0 * invtX + dV1 * tX; + int16 dVY2 = dV2 * invtX + dV3 * tX; + byte dV = (dVY1 * invtY + dVY2 * tY) >> 3; byte r, g, b; Graphics::YUV2RGB(dY, dU, dV, r, g, b); |