1 /*
2     This file is part of darktable,
3     Copyright (C) 2020 darktable developers.
4     darktable is free software: you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation, either version 3 of the License, or
7     (at your option) any later version.
8 
9     darktable is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with darktable.  If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #include "dtwin.h"
19 
win_image_find_duplicates(const char * filename)20 GList* win_image_find_duplicates(const char* filename)
21 {
22   // find all duplicates of an image
23   gchar pattern[PATH_MAX] = { 0 };
24   GList* files = NULL;
25   gchar *imgpath = g_path_get_dirname(filename);
26   // Windows only accepts generic wildcards for filename
27   static const gchar *glob_patterns[] = { "", "_????", NULL };
28   const gchar *c3 = filename + strlen(filename);
29   while(*c3 != '\\' && c3 > filename) c3--;
30   if(*c3 == '\\') c3++;
31   const gchar **glob_pattern = glob_patterns;
32   files = NULL;
33   while(*glob_pattern)
34   {
35     g_strlcpy(pattern, filename, sizeof(pattern));
36     gchar *c1 = pattern + strlen(pattern);
37     while(*c1 != '.' && c1 > pattern) c1--;
38     g_strlcpy(c1, *glob_pattern, pattern + sizeof(pattern) - c1);
39     const gchar *c2 = filename + strlen(filename);
40     while(*c2 != '.' && c2 > filename) c2--;
41     snprintf(c1 + strlen(*glob_pattern), pattern + sizeof(pattern) - c1 - strlen(*glob_pattern), "%s.xmp", c2);
42     wchar_t *wpattern = g_utf8_to_utf16(pattern, -1, NULL, NULL, NULL);
43     WIN32_FIND_DATAW data;
44     HANDLE handle = FindFirstFileW(wpattern, &data);
45     g_free(wpattern);
46     gchar *imgfile_without_path=g_strndup(c3,c2-c3); /*Need to remove path from front of filename*/
47     if(handle != INVALID_HANDLE_VALUE)
48     {
49       do
50       {
51         gchar *file = g_utf16_to_utf8(data.cFileName, -1, NULL, NULL, NULL);
52         gchar *short_file_name = g_strndup(file, strlen(file) - 4 + c2 - filename - strlen(filename));
53         gboolean valid_xmp_name = FALSE;
54         if(!(valid_xmp_name = (strlen(short_file_name) == strlen(imgfile_without_path))))
55         {
56           // if not the same length, make sure the extra char are 2-4 digits preceded by '_'
57           gchar *c4 = short_file_name + strlen(short_file_name);
58           int i=0;
59           do
60           {
61             c4--;
62             i++;
63           }
64           while(g_ascii_isdigit(*c4) && c4 > short_file_name && i <= 4);
65           valid_xmp_name = (*c4 == '_' && strlen(short_file_name) == strlen(imgfile_without_path) + i);
66         }
67 
68         if(valid_xmp_name)
69             files = g_list_append(files, g_build_filename(imgpath, file, NULL));
70 
71         g_free(short_file_name);
72         g_free(file);
73       }
74       while(FindNextFileW(handle, &data));
75 
76     }
77 
78     g_free(imgfile_without_path);
79     FindClose(handle);
80     glob_pattern++;
81   }
82 
83   g_free(imgpath);
84   return files;
85 }
86 
87 // modelines: These editor modelines have been set for all relevant files by tools/update_modelines.sh
88 // vim: shiftwidth=2 expandtab tabstop=2 cindent
89 // kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
90