Skip to content

Commit

Permalink
Fix a bug when heic files doubled when browsing a folder
Browse files Browse the repository at this point in the history
  • Loading branch information
SergeiVorobyov committed Mar 25, 2023
1 parent f471de9 commit 895d580
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 70 deletions.
126 changes: 59 additions & 67 deletions src/JPEGView/FileList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "DirectoryWatcher.h"
#include "Shlwapi.h"
#include "LepLoader.h"
#include <sstream>

///////////////////////////////////////////////////////////////////////////////////
// Helpers
Expand Down Expand Up @@ -124,19 +125,12 @@ void CFileDesc::SetModificationDate(const FILETIME& lastModDate) {
// Public interface
///////////////////////////////////////////////////////////////////////////////////

// image file types supported internally (there are additional endings for RAW and WIC - these come from INI file)
// NOTE: when adding more supported filetypes, update installer to add another extension for "SupportedTypes"
static const int cnNumEndingsInternal = 14;
static const TCHAR* csFileEndingsInternal[cnNumEndingsInternal] = {_T("jpg"), _T("jpeg"), _T("bmp"), _T("png"),
_T("tif"), _T("tiff"), _T("gif"), _T("webp"), _T("jxl"), _T("avif"), _T("heif"), _T("heic"), _T("tga"), _T("qoi")};
// Image file types supported internally and come from INI file.
typedef std::set<std::wstring> file_endings_type;

// supported camera RAW formats
static const TCHAR* csFileEndingsRAW = _T("*.pef;*.dng;*.crw;*.nef;*.cr2;*.mrw;*.rw2;*.orf;*.x3f;*.arw;*.kdc;*.nrw;*.dcr;*.sr2;*.raf");


static const int MAX_ENDINGS = 48;
static int nNumEndings;
static LPCTSTR* sFileEndings;

__declspec(dllimport) bool __stdcall WICPresent(void);

// Check if Windows Image Codecs library is present
Expand All @@ -149,48 +143,41 @@ static bool WICPresentGuarded(void) {
}

// Parses a semicolon separated list of file endings of the form "*.nef;*.cr2;*.dng"
static void ParseAndAddFileEndings(LPCTSTR sEndings) {
if (_tcslen(sEndings) > 2) {
LPTSTR buffer = new TCHAR[_tcslen(sEndings) + 1]; // this buffer will not be freed deliberately!
_tcscpy(buffer, sEndings);
LPTSTR sStart = buffer, sCurrent = buffer;
while (*sCurrent != 0 && nNumEndings < MAX_ENDINGS) {
while (*sCurrent != 0 && *sCurrent != _T(';')) {
sCurrent++;
}
if (*sCurrent == _T(';')) {
*sCurrent = 0;
sCurrent++;
}
if (_tcslen(sStart) > 2) {
sFileEndings[nNumEndings++] = sStart + 2;
}
sStart = sCurrent;
}
template<typename OUT_ITER>
static void ParseAndAddFileEndings(const std::wstring& input, OUT_ITER output) {
if (input.size() > 2)
{
std::wstringstream ss(input);
std::wstring item;
while (std::getline(ss, item, L';'))
output = item.substr(2);
}
}

// Gets all supported file endings, including the ones from WIC.
// The length of the returned list is nNumEndings
static LPCTSTR* GetSupportedFileEndingList() {
if (sFileEndings == NULL) {
sFileEndings = new LPCTSTR[MAX_ENDINGS];
for (nNumEndings = 0; nNumEndings < cnNumEndingsInternal; nNumEndings++) {
sFileEndings[nNumEndings] = csFileEndingsInternal[nNumEndings];
}
static file_endings_type& GetSupportedFileEndingList()
{
static file_endings_type file_endings;
if (!file_endings.empty())
return file_endings;

LPCTSTR sFileEndingsWIC = CSettingsProvider::This().FilesProcessedByWIC();
if (_tcslen(sFileEndingsWIC) > 2 && WICPresentGuarded()) {
ParseAndAddFileEndings(sFileEndingsWIC);
}
// Gets all supported file endings, including the ones from WIC.
file_endings = { _T("jpg"), _T("jpeg"), _T("bmp"), _T("png"),
_T("tif"), _T("tiff"), _T("gif"), _T("webp"), _T("jxl"), _T("avif"), _T("heif"), _T("heic"), _T("tga"), _T("qoi") };

if (LepLoader::LeptonToolPresent()) {
ParseAndAddFileEndings(CSettingsProvider::This().FilesProcessedByLepton());
}
LPCTSTR sFileEndingsWIC = CSettingsProvider::This().FilesProcessedByWIC();
if (_tcslen(sFileEndingsWIC) > 2 && WICPresentGuarded()) {
ParseAndAddFileEndings(sFileEndingsWIC, std::inserter(file_endings, file_endings.end()));
}

ParseAndAddFileEndings(CSettingsProvider::This().FileEndingsRAW());
if (LepLoader::LeptonToolPresent()) {
ParseAndAddFileEndings(CSettingsProvider::This().FilesProcessedByLepton(), std::inserter(file_endings, file_endings.end()));
}
return sFileEndings;

ParseAndAddFileEndings(CSettingsProvider::This().FileEndingsRAW(), std::inserter(file_endings, file_endings.end()));

return file_endings;
}

CFileList::CFileList(const CString & sInitialFile, CDirectoryWatcher & directoryWatcher,
Expand All @@ -212,7 +199,7 @@ CFileList::CFileList(const CString & sInitialFile, CDirectoryWatcher & directory
bool bImageFile = !bIsDirectory && IsImageFile(sExtensionInitialFile);
if (!bIsDirectory && !bImageFile && !sExtensionInitialFile.IsEmpty() && _tcsstr(csFileEndingsRAW, _T("*.") + sExtensionInitialFile) != NULL) {
// initial file is a supported camera raw file but was excluded in INI file - add temporarily to file ending list
ParseAndAddFileEndings(_T("*.") + sExtensionInitialFile);
ParseAndAddFileEndings((LPCWSTR)(_T("*.") + sExtensionInitialFile), std::inserter(GetSupportedFileEndingList(), GetSupportedFileEndingList().end()));
CSettingsProvider::This().AddTemporaryRAWFileEnding(sExtensionInitialFile);
bImageFile = true;
}
Expand Down Expand Up @@ -248,15 +235,22 @@ CFileList::~CFileList() {
m_fileList.clear();
}

CString CFileList::GetSupportedFileEndings() {
LPCTSTR* allFileEndings = GetSupportedFileEndingList();
CString sList;
for (int i = 0; i < nNumEndings; i++) {
sList += _T("*.");
sList += allFileEndings[i];
if (i+1 < nNumEndings) sList += _T(";");
CString CFileList::GetSupportedFileEndings()
{
auto extensions = GetSupportedFileEndingList();
std::wostringstream str;
bool first = true;
for each (auto extension in extensions)
{
if (!first)
str << L";";
else
first = false;

str << L"*." << extension;
}
return sList;

return CString(str.str().c_str());
}

void CFileList::Reload(LPCTSTR sFileName, bool clearForwardHistory) {
Expand Down Expand Up @@ -822,12 +816,14 @@ void CFileList::FindFiles() {
m_fileList.clear();
if (!m_sDirectory.IsEmpty()) {
CFindFile fileFind;
LPCTSTR* allFileEndings = GetSupportedFileEndingList();
for (int i = 0; i < nNumEndings; i++) {
if (fileFind.FindFile(m_sDirectory + _T("\\*.") + allFileEndings[i])) {
AddToFileList(m_fileList, fileFind, allFileEndings[i]);
auto extensions = GetSupportedFileEndingList();
for each(auto extension in extensions)
{
const auto c_extension = extension.c_str();
if (fileFind.FindFile(m_sDirectory + _T("\\*.") + c_extension)) {
AddToFileList(m_fileList, fileFind, c_extension);
while (fileFind.FindNextFile()) {
AddToFileList(m_fileList, fileFind, allFileEndings[i]);
AddToFileList(m_fileList, fileFind, c_extension);
}
}
}
Expand All @@ -851,13 +847,8 @@ void CFileList::VerifyFiles() {
bool CFileList::IsImageFile(const CString & sEnding) {
CString sEndingLC = sEnding;
sEndingLC.MakeLower();
LPCTSTR* allFileEndings = GetSupportedFileEndingList();
for (int i = 0; i < nNumEndings; i++) {
if (allFileEndings[i] == sEndingLC) {
return true;
}
}
return false;
auto allFileEndings = GetSupportedFileEndingList();
return allFileEndings.find((LPCWSTR)sEndingLC) != allFileEndings.end();
}

bool CFileList::TryReadingSlideShowList(const CString & sSlideShowFile) {
Expand Down Expand Up @@ -972,9 +963,10 @@ bool CFileList::TryReadingSlideShowList(const CString & sSlideShowFile) {
pStart--;
} else {
// try to find file name with relative path
LPCTSTR* allFileEndings = GetSupportedFileEndingList();
for (int i = 0; i < nNumEndings; i++) {
pStart = Helpers::stristr(lineBuff, (LPCTSTR)(CString(_T(".")) + allFileEndings[i]));
auto extensions = GetSupportedFileEndingList();
for each (auto extension in extensions)
{
pStart = Helpers::stristr(lineBuff, (LPCTSTR)(CString(_T(".")) + extension.c_str()));
if (pStart != NULL) {
while (pStart >= lineBuff && *pStart != _T('"') && *pStart != _T('>')) pStart--;
pStart++;
Expand Down
4 changes: 2 additions & 2 deletions src/JPEGView/JPEGView.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<OpenMPSupport>false</OpenMPSupport>
<LanguageStandard>stdcpp17</LanguageStandard>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
Expand Down Expand Up @@ -285,7 +285,7 @@
<SubSystem>Windows</SubSystem>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<DelayLoadDLLs>WICLoader.dll;jxl_dec.dll;jxl_threads.dll;heif.dll;avif.dll;lcms2.dll</DelayLoadDLLs>
<LinkTimeCodeGeneration>UseFastLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<AdditionalOptions>/IGNORE:4099 %(AdditionalOptions)</AdditionalOptions>
</Link>
<Manifest>
Expand Down
3 changes: 2 additions & 1 deletion src/JPEGView/stdafx.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ extern CAppModule _Module;
#pragma warning(pop)

// STL stuff
#include <list>
#include <list>
#include <set>

#define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS

Expand Down

0 comments on commit 895d580

Please sign in to comment.