Move the two low-level file I/O helper to their respective single place of usage.
This commit is contained in:
parent
e853629854
commit
0eab0ebd94
@ -47,9 +47,37 @@ using namespace std;
|
||||
using namespace rtengine;
|
||||
using namespace rtengine::procparams;
|
||||
|
||||
Glib::ustring safe_locale_to_utf8 (const std::string& src);
|
||||
Glib::ustring ImageIO::errorMsg[6] = {"Success", "Cannot read file.", "Invalid header.", "Error while reading header.", "File reading error", "Image format not supported."};
|
||||
namespace
|
||||
{
|
||||
|
||||
// Opens a file for binary writing and request exclusive lock (cases were you need "wb" mode plus locking)
|
||||
FILE* g_fopen_withBinaryAndLock(const Glib::ustring& fname)
|
||||
{
|
||||
FILE* f = NULL;
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
// Use native function to disallow sharing, i.e. lock the file for exclusive access.
|
||||
// This is important to e.g. prevent Windows Explorer from crashing RT due to concurrently scanning an image file.
|
||||
std::unique_ptr<wchar_t, GFreeFunc> wfname (reinterpret_cast<wchar_t*>(g_utf8_to_utf16 (fname.c_str (), -1, NULL, NULL, NULL)), g_free);
|
||||
|
||||
HANDLE hFile = CreateFileW ( wfname.get (), GENERIC_READ | GENERIC_WRITE, 0 /* no sharing allowed */, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFile != INVALID_HANDLE_VALUE) {
|
||||
f = _fdopen (_open_osfhandle ((intptr_t)hFile, 0), "wb");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
f = ::g_fopen (fname.c_str (), "wb");
|
||||
|
||||
#endif
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Glib::ustring ImageIO::errorMsg[6] = {"Success", "Cannot read file.", "Invalid header.", "Error while reading header.", "File reading error", "Image format not supported."};
|
||||
|
||||
// For only copying the raw input data
|
||||
void ImageIO::setMetadata (const rtexif::TagDirectory* eroot)
|
||||
@ -888,7 +916,7 @@ int ImageIO::loadPPMFromMemory(const char* buffer, int width, int height, bool s
|
||||
int ImageIO::savePNG (Glib::ustring fname, int compression, volatile int bps)
|
||||
{
|
||||
|
||||
FILE *file = safe_g_fopen_WriteBinLock (fname);
|
||||
FILE *file = g_fopen_withBinaryAndLock (fname);
|
||||
|
||||
if (!file) {
|
||||
return IMIO_CANNOTWRITEFILE;
|
||||
@ -982,7 +1010,7 @@ int ImageIO::savePNG (Glib::ustring fname, int compression, volatile int bps)
|
||||
int ImageIO::saveJPEG (Glib::ustring fname, int quality, int subSamp)
|
||||
{
|
||||
|
||||
FILE *file = safe_g_fopen_WriteBinLock (fname);
|
||||
FILE *file = g_fopen_withBinaryAndLock (fname);
|
||||
|
||||
if (!file) {
|
||||
return IMIO_CANNOTWRITEFILE;
|
||||
@ -1183,7 +1211,7 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed)
|
||||
|
||||
// TODO the following needs to be looked into - do we really need two ways to write a Tiff file ?
|
||||
if (exifRoot && uncompressed) {
|
||||
FILE *file = safe_g_fopen_WriteBinLock (fname);
|
||||
FILE *file = g_fopen_withBinaryAndLock (fname);
|
||||
|
||||
if (!file) {
|
||||
delete [] linebuffer;
|
||||
|
@ -68,7 +68,25 @@ int munmap(void *start, size_t length)
|
||||
|
||||
IMFILE* fopen (const char* fname)
|
||||
{
|
||||
int fd = safe_open_ReadOnly(fname);
|
||||
int fd = -1;
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
{
|
||||
// First convert UTF8 to UTF16, then use Windows function to open the file and convert back to file descriptor.
|
||||
std::unique_ptr<wchar_t, GFreeFunc> wfname (reinterpret_cast<wchar_t*>(g_utf8_to_utf16 (fname, -1, NULL, NULL, NULL)), g_free);
|
||||
|
||||
HANDLE hFile = CreateFileW (wfname.get (), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFile != INVALID_HANDLE_VALUE) {
|
||||
fd = _open_osfhandle((intptr_t)hFile, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
fd = ::g_open (fname, O_RDONLY);
|
||||
|
||||
#endif
|
||||
|
||||
if ( fd < 0 ) {
|
||||
return 0;
|
||||
|
@ -80,56 +80,6 @@ std::string safe_locale_from_utf8 (const Glib::ustring& utf8_str)
|
||||
return str;
|
||||
}
|
||||
|
||||
// Opens a file for binary writing and request exclusive lock (cases were you need "wb" mode plus locking)
|
||||
// (Important on Windows to prevent Explorer to crash RT when parallel scanning e.g. a currently written image file)
|
||||
FILE * safe_g_fopen_WriteBinLock(const Glib::ustring& fname)
|
||||
{
|
||||
FILE* f = NULL;
|
||||
|
||||
#ifdef WIN32
|
||||
// g_fopen just uses _wfopen internally on Windows, does not lock access and has no options to set this
|
||||
// so use a native function to work around this problem
|
||||
wchar_t *wFname = (wchar_t*)g_utf8_to_utf16 (fname.c_str(), -1, NULL, NULL, NULL);
|
||||
HANDLE hFile = CreateFileW(wFname, GENERIC_READ | GENERIC_WRITE, 0 /* no sharing allowed */, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
g_free(wFname);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
f = NULL;
|
||||
} else {
|
||||
f = _fdopen( _open_osfhandle((intptr_t)hFile, 0) , "wb");
|
||||
}
|
||||
|
||||
#else
|
||||
f = safe_g_fopen(fname, "wb");
|
||||
#endif
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
// Covers old UNIX ::open, which expects ANSI instead of UTF8 on Windows
|
||||
int safe_open_ReadOnly(const char *fname)
|
||||
{
|
||||
int fd = -1;
|
||||
|
||||
#ifdef WIN32
|
||||
// First convert UTF8 to UTF16, then use Windows function to open
|
||||
wchar_t *wFname = (wchar_t*)g_utf8_to_utf16 (fname, -1, NULL, NULL, NULL);
|
||||
HANDLE hFile = CreateFileW(wFname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
g_free(wFname);
|
||||
|
||||
// convert back to old file descriptor format
|
||||
if (hFile != INVALID_HANDLE_VALUE) {
|
||||
fd = _open_osfhandle((intptr_t)hFile, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
fd = ::open(fname, O_RDONLY);
|
||||
#endif
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
FILE * safe_g_fopen(const Glib::ustring& src, const gchar *mode)
|
||||
{
|
||||
return g_fopen(src.c_str(), mode);
|
||||
|
@ -6,12 +6,8 @@
|
||||
#include <giomm.h>
|
||||
|
||||
Glib::ustring safe_filename_to_utf8 (const std::string& src);
|
||||
Glib::ustring safe_locale_to_utf8 (const std::string& src); // from rtengine
|
||||
Glib::ustring safe_locale_to_utf8 (const std::string& src);
|
||||
std::string safe_locale_from_utf8 (const Glib::ustring& utf8_str);
|
||||
std::string safe_filename_from_utf8 (const Glib::ustring& utf8_str);
|
||||
|
||||
FILE * safe_g_fopen_WriteBinLock(const Glib::ustring& fname);
|
||||
int safe_open_ReadOnly(const char *fname);
|
||||
|
||||
FILE * safe_g_fopen(const Glib::ustring& src, const gchar *mode);
|
||||
bool safe_file_test (const Glib::ustring& filename, Glib::FileTest test);
|
||||
|
Loading…
x
Reference in New Issue
Block a user