From 5c25eefe2690412e61e07627b62cf0546a51cd59 Mon Sep 17 00:00:00 2001 From: Edi61 <84682915+Edi61@users.noreply.github.com> Date: Tue, 9 Apr 2024 22:20:11 +0200 Subject: [PATCH 1/2] Speedup Wipeffect - WipeEffect only if position changed - Difference based wipeeffect (Only part between old and new position is updated) --- src/WinIMergeLib/ImgDiffBuffer.hpp | 118 ++++++++++++++++++++++------- 1 file changed, 90 insertions(+), 28 deletions(-) diff --git a/src/WinIMergeLib/ImgDiffBuffer.hpp b/src/WinIMergeLib/ImgDiffBuffer.hpp index 0f04b9e..3f4c582 100644 --- a/src/WinIMergeLib/ImgDiffBuffer.hpp +++ b/src/WinIMergeLib/ImgDiffBuffer.hpp @@ -502,6 +502,7 @@ class CImgDiffBuffer , m_overlayAlpha(0.3) , m_wipeMode(WIPE_NONE) , m_wipePosition(0) + , m_wipePosition_old(INT_MAX) , m_diffBlockSize(8) , m_selDiffColor(Image::Rgb(0xff, 0x40, 0x40)) , m_selDiffDeletedColor(Image::Rgb(0xf0, 0xc0, 0xc0)) @@ -777,7 +778,7 @@ class CImgDiffBuffer if (m_wipePosition == pos) return; m_wipePosition = pos; - RefreshImages(); + WipeEffect(); } void SetWipeModePosition(WIPE_MODE wipeMode, int pos) @@ -1134,10 +1135,6 @@ class CImgDiffBuffer (this->*func)(1, 2); } } - if (m_wipeMode != WIPE_NONE) - { - WipeEffect(); - } if (m_showDifferences) { bool showDiff = true; @@ -1157,6 +1154,7 @@ class CImgDiffBuffer MarkDiff(i, m_diff); } } + m_wipePosition_old = INT_MAX; } bool OpenImages(int nImages, const wchar_t * const filename[3]) @@ -1878,49 +1876,112 @@ class CImgDiffBuffer const unsigned w = m_imgDiff[0].width(); const unsigned h = m_imgDiff[0].height(); + if (m_wipePosition <= 0) + m_wipePosition = 0; + if (m_wipeMode == WIPE_VERTICAL) { + if (m_wipePosition >= h) + m_wipePosition = h; + if (m_wipePosition_old == INT_MAX) + m_wipePosition_old = h; auto tmp = new unsigned char[w * 4]; - for (unsigned y = m_wipePosition; y < h; ++y) + if (m_wipePosition <= m_wipePosition_old) { - for (int pane = 0; pane < m_nImages - 1; ++pane) + for (unsigned y = m_wipePosition; y < m_wipePosition_old; ++y) + { + for (int pane = 0; pane < m_nImages - 1; ++pane) + { + unsigned char* scanline = m_imgDiff[pane].scanLine(y); + unsigned char* scanline2 = m_imgDiff[pane + 1].scanLine(y); + memcpy(tmp, scanline, w * 4); + memcpy(scanline, scanline2, w * 4); + memcpy(scanline2, tmp, w * 4); + } + } + } + else + { + for (unsigned y = m_wipePosition_old; y < m_wipePosition; ++y) { - unsigned char *scanline = m_imgDiff[pane].scanLine(y); - unsigned char *scanline2 = m_imgDiff[pane + 1].scanLine(y); - memcpy(tmp, scanline, w * 4); - memcpy(scanline, scanline2, w * 4); - memcpy(scanline2, tmp, w * 4); + for (int pane = m_nImages - 1; pane > 0; --pane) + { + unsigned char* scanline = m_imgDiff[pane].scanLine(y); + unsigned char* scanline2 = m_imgDiff[pane - 1].scanLine(y); + memcpy(tmp, scanline, w * 4); + memcpy(scanline, scanline2, w * 4); + memcpy(scanline2, tmp, w * 4); + } } } + delete[] tmp; } else if (m_wipeMode = WIPE_HORIZONTAL) { + if (m_wipePosition >= w) + m_wipePosition = w; + if (m_wipePosition_old == INT_MAX) + m_wipePosition_old = w; for (unsigned y = 0; y < h; ++y) { for (int pane = 0; pane < m_nImages - 1; ++pane) { - unsigned char *scanline = m_imgDiff[pane].scanLine(y); - unsigned char *scanline2 = m_imgDiff[pane + 1].scanLine(y); - for (unsigned x = m_wipePosition; x < w; ++x) + unsigned char* scanline; + unsigned char* scanline2; + if (m_wipePosition <= m_wipePosition_old) + { + scanline = m_imgDiff[pane].scanLine(y); + scanline2 = m_imgDiff[pane + 1].scanLine(y); + } + else + { + scanline = m_imgDiff[m_nImages - 2 - pane].scanLine(y); + scanline2 = m_imgDiff[m_nImages - 1 - pane].scanLine(y); + } + + if (m_wipePosition <= m_wipePosition_old) { - unsigned char tmp[4]; - tmp[0] = scanline[x * 4 + 0]; - tmp[1] = scanline[x * 4 + 1]; - tmp[2] = scanline[x * 4 + 2]; - tmp[3] = scanline[x * 4 + 3]; - scanline[x * 4 + 0] = scanline2[x * 4 + 0]; - scanline[x * 4 + 1] = scanline2[x * 4 + 1]; - scanline[x * 4 + 2] = scanline2[x * 4 + 2]; - scanline[x * 4 + 3] = scanline2[x * 4 + 3]; - scanline2[x * 4 + 0] = tmp[0]; - scanline2[x * 4 + 1] = tmp[1]; - scanline2[x * 4 + 2] = tmp[2]; - scanline2[x * 4 + 3] = tmp[3]; + for (unsigned x = m_wipePosition; x < m_wipePosition_old; ++x) + { + unsigned char tmp[4]; + tmp[0] = scanline[x * 4 + 0]; + tmp[1] = scanline[x * 4 + 1]; + tmp[2] = scanline[x * 4 + 2]; + tmp[3] = scanline[x * 4 + 3]; + scanline[x * 4 + 0] = scanline2[x * 4 + 0]; + scanline[x * 4 + 1] = scanline2[x * 4 + 1]; + scanline[x * 4 + 2] = scanline2[x * 4 + 2]; + scanline[x * 4 + 3] = scanline2[x * 4 + 3]; + scanline2[x * 4 + 0] = tmp[0]; + scanline2[x * 4 + 1] = tmp[1]; + scanline2[x * 4 + 2] = tmp[2]; + scanline2[x * 4 + 3] = tmp[3]; + } + } + else + { + for (unsigned x = m_wipePosition_old; x < m_wipePosition; ++x) + { + unsigned char tmp[4]; + tmp[0] = scanline[x * 4 + 0]; + tmp[1] = scanline[x * 4 + 1]; + tmp[2] = scanline[x * 4 + 2]; + tmp[3] = scanline[x * 4 + 3]; + scanline[x * 4 + 0] = scanline2[x * 4 + 0]; + scanline[x * 4 + 1] = scanline2[x * 4 + 1]; + scanline[x * 4 + 2] = scanline2[x * 4 + 2]; + scanline[x * 4 + 3] = scanline2[x * 4 + 3]; + scanline2[x * 4 + 0] = tmp[0]; + scanline2[x * 4 + 1] = tmp[1]; + scanline2[x * 4 + 2] = tmp[2]; + scanline2[x * 4 + 3] = tmp[3]; + } } } } } + m_wipePosition_old = m_wipePosition; } void CopyPreprocessedImageToDiffImage(int dst) @@ -2257,6 +2318,7 @@ class CImgDiffBuffer double m_overlayAlpha; WIPE_MODE m_wipeMode; int m_wipePosition; + int m_wipePosition_old; unsigned m_diffBlockSize; Image::Color m_selDiffColor; Image::Color m_selDiffDeletedColor; From b06068e178ae928f90ddea5eaa7411c67da8d17d Mon Sep 17 00:00:00 2001 From: Edi61 <84682915+Edi61@users.noreply.github.com> Date: Sat, 20 Apr 2024 23:43:39 +0200 Subject: [PATCH 2/2] Transparency detection + redraw Transparency detection and triggering of a redraw in case of image wiping --- src/WinIMergeLib/ImgDiffBuffer.hpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/WinIMergeLib/ImgDiffBuffer.hpp b/src/WinIMergeLib/ImgDiffBuffer.hpp index 3f4c582..004eac6 100644 --- a/src/WinIMergeLib/ImgDiffBuffer.hpp +++ b/src/WinIMergeLib/ImgDiffBuffer.hpp @@ -520,6 +520,10 @@ class CImgDiffBuffer { for (int i = 0; i < 3; ++i) m_currentPage[i] = 0; + for (int i = 0; i < m_nImages; ++i) + { + m_imgDiffIsTransparent[i] = false; + } } virtual ~CImgDiffBuffer() @@ -766,6 +770,11 @@ class CImgDiffBuffer return; m_wipeMode = wipeMode; RefreshImages(); + for (int i = 0; i < m_nImages; ++i) + { + if (m_imgDiff[i].getFipImage()->isTransparent()) + m_imgDiffIsTransparent[i] = true; + } } int GetWipePosition() const @@ -778,9 +787,21 @@ class CImgDiffBuffer if (m_wipePosition == pos) return; m_wipePosition = pos; + for (int i = 0; i < m_nImages; ++i) + { + if (m_imgDiffIsTransparent[i] == true) + { + // Dummy operation with less performance to retrigger redrawing + // setPixelColor leads to _bHasChanged = TRUE which will enable redrawing + RGBQUAD color; + m_imgDiff[i].getFipImage()->getPixelColor(0, 0, &color); + m_imgDiff[i].getFipImage()->setPixelColor(0, 0, &color); + } + } WipeEffect(); } + void SetWipeModePosition(WIPE_MODE wipeMode, int pos) { if (m_wipeMode == wipeMode && m_wipePosition == pos) @@ -788,6 +809,13 @@ class CImgDiffBuffer m_wipeMode = wipeMode; m_wipePosition = pos; RefreshImages(); + for (int i = 0; i < m_nImages; ++i) + { + if (m_imgDiff[i].getFipImage()->isTransparent()) + m_imgDiffIsTransparent[i] = true; + } + if (m_wipeMode != WIPE_NONE) + WipeEffect(); } bool GetShowDifferences() const @@ -2337,4 +2365,5 @@ class CImgDiffBuffer std::vector m_lineDiffInfos; bool m_temporarilyTransformed; DIFF_ALGORITHM m_diffAlgorithm; + bool m_imgDiffIsTransparent[3]; };