diff --git a/image/decoders/nsBMPDecoder.cpp b/image/decoders/nsBMPDecoder.cpp index 1f0449e4e672..015f90562c3c 100644 --- a/image/decoders/nsBMPDecoder.cpp +++ b/image/decoders/nsBMPDecoder.cpp @@ -994,33 +994,36 @@ nsBMPDecoder::ReadRLEDelta(const char* aData) MOZ_ASSERT(mMayHaveTransparency); mDoesHaveTransparency = true; - if (mDownscaler) { - // Clear the skipped pixels. (This clears to the end of the row, - // which is perfect if there's a Y delta and harmless if not). - mDownscaler->ClearRestOfRow(/* aStartingAtCol = */ mCurrentPos); - } - - // Handle the XDelta. - mCurrentPos += uint8_t(aData[0]); - if (mCurrentPos > mH.mWidth) { - mCurrentPos = mH.mWidth; + // Handle the XDelta. This clears to the end of the row, which + // which is perfect if there's a Y delta and harmless if not. + uint8_t xDelta = uint8_t(aData[0]); + int32_t finalPos = std::min(mH.mWidth, mCurrentPos + xDelta); + uint32_t* dst = RowBuffer(); + while (mCurrentPos < mH.mWidth) { + SetPixel(dst, 0, 0, 0, 0); + ++mCurrentPos; } // Handle the Y Delta. int32_t yDelta = std::min(uint8_t(aData[1]), mCurrentRow); - mCurrentRow -= yDelta; - - if (mDownscaler && yDelta > 0) { + if (yDelta > 0) { // Commit the current row (the first of the skipped rows). - mDownscaler->CommitRow(); + mCurrentPos = 0; + FinishRow(); // Clear and commit the remaining skipped rows. for (int32_t line = 1; line < yDelta; line++) { - mDownscaler->ClearRow(); - mDownscaler->CommitRow(); + dst = RowBuffer(); + while (mCurrentPos < mH.mWidth) { + SetPixel(dst, 0, 0, 0, 0); + ++mCurrentPos; + } + mCurrentPos = 0; + FinishRow(); } } + mCurrentPos = finalPos; return mCurrentRow == 0 ? Transition::TerminateSuccess() : Transition::To(State::RLE_SEGMENT, RLE::SEGMENT_LENGTH);