#pragma once\r
\r
#include "FreeImagePlus.h"\r
-#include "WinIMergeLib.h"\r
#include <string>\r
#include <algorithm>\r
#include <cstdio>\r
+#include <cstring>\r
#include <cmath>\r
-#include <array>\r
#include <vector>\r
\r
template<class T> struct Point\r
Rect<int> rc;\r
};\r
\r
+struct DiffStat { int d1, d2, d3, detc; };\r
+\r
struct UndoRecord\r
{\r
UndoRecord(int pane, FIBITMAP *oldbitmap, FIBITMAP *newbitmap, const int modcountnew[3]) : \r
int m_modcountonsave[3];\r
};\r
\r
+#ifndef _WIN32\r
+class fipWinImage : public fipImage\r
+{\r
+public:\r
+ fipWinImage(FREE_IMAGE_TYPE image_type = FIT_BITMAP, unsigned width = 0, unsigned height = 0, unsigned bpp = 0) :\r
+ fipImage(image_type, width, height, bpp) {}\r
+ fipWinImage(const fipWinImage& Image) : fipImage(Image) {}\r
+ virtual ~fipWinImage() {}\r
+};\r
+#endif\r
+\r
class fipImageEx : public fipImage\r
{\r
public:\r
\r
BOOL openU(const wchar_t* lpszPathName, BOOL create_new, BOOL read_only, int flags = 0)\r
{\r
- wchar_t shortname[260];\r
char filename[260];\r
- GetShortPathName(lpszPathName, shortname, sizeof(shortname));\r
+#ifdef _WIN32\r
+ wchar_t shortname[260] = {0};\r
+ GetShortPathNameW(lpszPathName, shortname, sizeof(shortname)/sizeof(shortname[0]));\r
wsprintfA(filename, "%S", shortname);\r
+#else\r
+ snprintf(filename, sizeof(filename), "%ls", lpszPathName);\r
+ \r
+#endif\r
BOOL result = open(filename, create_new, read_only, flags);\r
return result;\r
}\r
bool saveU(const wchar_t* lpszPathName, int flag = 0) const\r
{\r
FILE *fp = NULL;\r
+#ifdef _WIN32\r
_wfopen_s(&fp, lpszPathName, L"r+b");\r
+#else\r
+ char filename[260];\r
+ snprintf(filename, sizeof(filename), "%ls", lpszPathName);\r
+ fp = fopen(filename, "r+b");\r
+#endif\r
if (!fp)\r
return false;\r
FreeImageIO io;\r
\r
class CImgMergeBuffer\r
{\r
+ typedef Array2D<int> DiffBlocks;\r
+\r
public:\r
+ enum OVERLAY_MODE {\r
+ OVERLAY_NONE = 0, OVERLAY_XOR, OVERLAY_ALPHABLEND\r
+ };\r
+\r
CImgMergeBuffer() : \r
m_nImages(0)\r
- , m_diffBlockSize(8)\r
- , m_overlayMode(IImgMergeWindow::OVERLAY_NONE)\r
- , m_overlayAlpha(0.3)\r
, m_showDifferences(true)\r
- , m_selDiffColor(RGB(0xff, 0x40, 0x40))\r
- , m_diffColor(RGB(0xff, 0xff, 0x40))\r
+ , m_overlayMode(OVERLAY_NONE)\r
+ , m_overlayAlpha(0.3)\r
+ , m_diffBlockSize(8)\r
+ , m_selDiffColor()\r
+ , m_diffColor()\r
, m_diffColorAlpha(0.7)\r
- , m_diffCount(0)\r
- , m_currentDiffIndex(-1)\r
, m_colorDistanceThreshold(0.0)\r
+ , m_currentDiffIndex(-1)\r
+ , m_diffCount(0)\r
{\r
+ m_selDiffColor.rgbRed = 0xff;\r
+ m_selDiffColor.rgbGreen = 0x40;\r
+ m_selDiffColor.rgbBlue = 0x40;\r
+ m_diffColor.rgbRed = 0xff;\r
+ m_diffColor.rgbGreen = 0xff;\r
+ m_diffColor.rgbBlue = 0x40;\r
for (int i = 0; i < 3; ++i)\r
{\r
m_currentPage[i] = 0;\r
\r
~CImgMergeBuffer()\r
{\r
+ CloseImages();\r
}\r
\r
const wchar_t *GetFileName(int pane)\r
m_bRO[pane] = readOnly;\r
}\r
\r
- COLORREF GetDiffColor() const\r
+ RGBQUAD GetDiffColor() const\r
{\r
return m_diffColor;\r
}\r
\r
- void SetDiffColor(COLORREF clrDiffColor)\r
+ void SetDiffColor(RGBQUAD clrDiffColor)\r
{\r
m_diffColor = clrDiffColor;\r
RefreshImages();\r
}\r
\r
- COLORREF GetSelDiffColor() const\r
+ RGBQUAD GetSelDiffColor() const\r
{\r
return m_selDiffColor;\r
}\r
\r
- void SetSelDiffColor(COLORREF clrSelDiffColor)\r
+ void SetSelDiffColor(RGBQUAD clrSelDiffColor)\r
{\r
m_selDiffColor = clrSelDiffColor;\r
RefreshImages();\r
CompareImages();\r
}\r
\r
- IImgMergeWindow::OVERLAY_MODE GetOverlayMode() const\r
+ OVERLAY_MODE GetOverlayMode() const\r
{\r
return m_overlayMode;\r
}\r
\r
- void SetOverlayMode(IImgMergeWindow::OVERLAY_MODE overlayMode)\r
+ void SetOverlayMode(OVERLAY_MODE overlayMode)\r
{\r
m_overlayMode = overlayMode;\r
RefreshImages();\r
\r
bool FirstConflict()\r
{\r
- for (int i = 0; i < m_diffInfos.size(); ++i)\r
+ for (size_t i = 0; i < m_diffInfos.size(); ++i)\r
if (m_diffInfos[i].op == DiffInfo::OP_DIFF)\r
- m_currentDiffIndex = i;\r
+ m_currentDiffIndex = static_cast<int>(i);\r
RefreshImages();\r
return true;\r
}\r
for (int i = 0; i < m_nImages; ++i)\r
CopyOriginalImageToDiffImage(i);\r
void (CImgMergeBuffer::*func)(int src, int dst) = NULL;\r
- if (m_overlayMode == IImgMergeWindow::OVERLAY_ALPHABLEND)\r
+ if (m_overlayMode == OVERLAY_ALPHABLEND)\r
func = &CImgMergeBuffer::AlphaBlendImages2;\r
- else if (m_overlayMode == IImgMergeWindow::OVERLAY_XOR)\r
+ else if (m_overlayMode == OVERLAY_XOR)\r
func = &CImgMergeBuffer::XorImages2;\r
if (func)\r
{\r
}\r
else\r
{\r
+#ifdef _WIN32\r
return !!m_imgOrig[pane].saveU(filename);\r
+#else\r
+ char filenameA[260];\r
+ snprintf(filenameA, sizeof(filenameA), "%ls", filename);\r
+ return !!m_imgOrig[pane].save(filenameA);\r
+#endif\r
}\r
}\r
\r
m_imgOrig32[i].clear();\r
m_undoRecords.clear();\r
}\r
+ m_nImages = 0;\r
return true;\r
}\r
\r
{\r
if (pane < 0 || pane >= m_nImages)\r
return false;\r
+#ifdef _WIN32\r
return !!m_imgDiff[pane].saveU(filename);\r
+#else\r
+ char filenameA[260];\r
+ snprintf(filenameA, sizeof(filenameA), "%ls", filename);\r
+ return !!m_imgDiff[pane].save(filenameA);\r
+#endif\r
}\r
\r
int GetImageWidth(int pane) const\r
}\r
if (!m_imgOrigMultiPage[i].isValid())\r
{\r
+#ifdef _WIN32\r
if (!m_imgOrig[i].loadU(m_filename[i].c_str()))\r
bSucceeded = false;\r
+#else\r
+ char filename[260];\r
+ snprintf(filename, sizeof(filename), "%ls", m_filename[i].c_str());\r
+ if (!m_imgOrig[i].load(filename))\r
+ bSucceeded = false;\r
+#endif\r
m_imgOrig32[i] = m_imgOrig[i];\r
}\r
\r
m_imgDiff[i].setSize(FIT_BITMAP, size.cx, size.cy, 32);\r
}\r
\r
- void CompareImages2(int pane1, int pane2, Array2D<unsigned>& diff)\r
+ void CompareImages2(int pane1, int pane2, DiffBlocks& diff)\r
{\r
unsigned w1 = m_imgOrig32[pane1].getWidth();\r
unsigned h1 = m_imgOrig32[pane1].getHeight();\r
}\r
}\r
\r
- void FloodFill8Directions(Array2D<unsigned>& data, int x, int y, unsigned val)\r
+ void FloodFill8Directions(DiffBlocks& data, int x, int y, unsigned val)\r
{\r
std::vector<Point<int> > stack;\r
stack.push_back(Point<int>(x, y));\r
}\r
}\r
\r
- int MarkDiffIndex(Array2D<unsigned>& diff)\r
+ int MarkDiffIndex(DiffBlocks& diff)\r
{\r
int diffCount = 0;\r
for (unsigned by = 0; by < diff.height(); ++by)\r
return diffCount;\r
}\r
\r
- int MarkDiffIndex3way(Array2D<unsigned>& diff01, Array2D<unsigned>& diff21, Array2D<unsigned>& diff02, Array2D<unsigned>& diff3)\r
+ int MarkDiffIndex3way(DiffBlocks& diff01, DiffBlocks& diff21, DiffBlocks& diff02, DiffBlocks& diff3)\r
{\r
int diffCount = MarkDiffIndex(diff3);\r
- std::vector<std::array<int, 4>> counter(m_diffInfos.size());\r
+ std::vector<DiffStat> counter(m_diffInfos.size());\r
for (unsigned by = 0; by < diff3.height(); ++by)\r
{\r
for (unsigned bx = 0; bx < diff3.width(); ++bx)\r
continue;\r
--diffIndex;\r
if (diff21(bx, by) == 0)\r
- ++counter[diffIndex][0];\r
+ ++counter[diffIndex].d1;\r
else if (diff02(bx, by) == 0)\r
- ++counter[diffIndex][1];\r
+ ++counter[diffIndex].d2;\r
else if (diff01(bx, by) == 0)\r
- ++counter[diffIndex][2];\r
+ ++counter[diffIndex].d3;\r
else\r
- ++counter[diffIndex][3];\r
+ ++counter[diffIndex].detc;\r
}\r
}\r
\r
for (size_t i = 0; i < m_diffInfos.size(); ++i)\r
{\r
int op;\r
- if (counter[i][0] != 0 && counter[i][1] == 0 && counter[i][2] == 0 && counter[i][3] == 0)\r
+ if (counter[i].d1 != 0 && counter[i].d2 == 0 && counter[i].d3 == 0 && counter[i].detc == 0)\r
op = DiffInfo::OP_1STONLY;\r
- else if (counter[i][0] == 0 && counter[i][1] != 0 && counter[i][2] == 0 && counter[i][3] == 0)\r
+ else if (counter[i].d1 == 0 && counter[i].d2 != 0 && counter[i].d3 == 0 && counter[i].detc == 0)\r
op = DiffInfo::OP_2NDONLY;\r
- else if (counter[i][0] == 0 && counter[i][1] == 0 && counter[i][2] != 0 && counter[i][3] == 0)\r
+ else if (counter[i].d1 == 0 && counter[i].d2 == 0 && counter[i].d3 != 0 && counter[i].detc == 0)\r
op = DiffInfo::OP_3RDONLY;\r
else\r
op = DiffInfo::OP_DIFF;\r
return diffCount;\r
}\r
\r
- void Make3WayDiff(const Array2D<unsigned>& diff01, const Array2D<unsigned>& diff21, Array2D<unsigned>& diff3)\r
+ void Make3WayDiff(const DiffBlocks& diff01, const DiffBlocks& diff21, DiffBlocks& diff3)\r
{\r
diff3 = diff01;\r
for (unsigned bx = 0; bx < diff3.width(); ++bx)\r
}\r
}\r
\r
- void MarkDiff(int pane, const Array2D<unsigned>& diff)\r
+ void MarkDiff(int pane, const DiffBlocks& diff)\r
{\r
const unsigned w = m_imgDiff[pane].getWidth();\r
const unsigned h = m_imgDiff[pane].getHeight();\r
{\r
for (unsigned bx = 0; bx < diff.width(); ++bx)\r
{\r
- unsigned diffIndex = diff(bx, by);\r
+ int diffIndex = diff(bx, by);\r
if (diffIndex != 0 && (\r
(pane == 0 && m_diffInfos[diffIndex - 1].op != DiffInfo::OP_3RDONLY) ||\r
(pane == 1) ||\r
(pane == 2 && m_diffInfos[diffIndex - 1].op != DiffInfo::OP_1STONLY)\r
))\r
{\r
- COLORREF color = (diffIndex - 1 == m_currentDiffIndex) ? m_selDiffColor : m_diffColor;\r
+ RGBQUAD color = (diffIndex - 1 == m_currentDiffIndex) ? m_selDiffColor : m_diffColor;\r
unsigned bsy = (h - by * m_diffBlockSize < m_diffBlockSize) ? (h - by * m_diffBlockSize) : m_diffBlockSize;\r
for (unsigned i = 0; i < bsy; ++i)\r
{\r
for (unsigned j = 0; j < bsx; ++j)\r
{\r
unsigned x = bx * m_diffBlockSize + j;\r
- scanline[x * 4 + 0] = static_cast<BYTE>(scanline[x * 4 + 0] * (1 - m_diffColorAlpha) + GetBValue(color) * m_diffColorAlpha);\r
- scanline[x * 4 + 1] = static_cast<BYTE>(scanline[x * 4 + 1] * (1 - m_diffColorAlpha) + GetGValue(color) * m_diffColorAlpha);\r
- scanline[x * 4 + 2] = static_cast<BYTE>(scanline[x * 4 + 2] * (1 - m_diffColorAlpha) + GetRValue(color) * m_diffColorAlpha);\r
+ scanline[x * 4 + 0] = static_cast<BYTE>(scanline[x * 4 + 0] * (1 - m_diffColorAlpha) + color.rgbBlue * m_diffColorAlpha);\r
+ scanline[x * 4 + 1] = static_cast<BYTE>(scanline[x * 4 + 1] * (1 - m_diffColorAlpha) + color.rgbGreen * m_diffColorAlpha);\r
+ scanline[x * 4 + 2] = static_cast<BYTE>(scanline[x * 4 + 2] * (1 - m_diffColorAlpha) + color.rgbRed * m_diffColorAlpha);\r
}\r
}\r
}\r
fipWinImage m_imgDiff[3];\r
std::wstring m_filename[3];\r
bool m_bRO[3];\r
- IImgMergeWindow::OVERLAY_MODE m_overlayMode;\r
bool m_showDifferences;\r
+ OVERLAY_MODE m_overlayMode;\r
double m_overlayAlpha;\r
unsigned m_diffBlockSize;\r
- COLORREF m_selDiffColor;\r
- COLORREF m_diffColor;\r
+ RGBQUAD m_selDiffColor;\r
+ RGBQUAD m_diffColor;\r
double m_diffColorAlpha;\r
double m_colorDistanceThreshold;\r
int m_currentPage[3];\r
int m_currentDiffIndex;\r
int m_diffCount;\r
- Array2D<unsigned> m_diff, m_diff01, m_diff21, m_diff02;\r
+ DiffBlocks m_diff, m_diff01, m_diff21, m_diff02;\r
std::vector<DiffInfo> m_diffInfos;\r
UndoRecords m_undoRecords;\r
};\r