mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-02-01 18:40:12 -05:00
Bug fixes:
--Better locks around creating image files in command line programs.
This commit is contained in:
parent
50485f5d73
commit
4749a7aec4
@ -3,6 +3,7 @@
|
|||||||
#include "EmberCommonPch.h"
|
#include "EmberCommonPch.h"
|
||||||
|
|
||||||
#define PNG_COMMENT_MAX 8
|
#define PNG_COMMENT_MAX 8
|
||||||
|
static std::recursive_mutex fileCs;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Write a JPEG file.
|
/// Write a JPEG file.
|
||||||
@ -22,8 +23,20 @@ static bool WriteJpeg(const char* filename, byte* image, size_t width, size_t he
|
|||||||
{
|
{
|
||||||
bool b = false;
|
bool b = false;
|
||||||
FILE* file;
|
FILE* file;
|
||||||
|
errno_t fileResult;
|
||||||
|
|
||||||
if (fopen_s(&file, filename, "wb") == 0)
|
//Just to be extra safe.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
rlg l(fileCs);
|
||||||
|
fileResult = fopen_s(&file, filename, "wb");
|
||||||
|
}
|
||||||
|
catch (std::exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileResult == 0)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
jpeg_error_mgr jerr;
|
jpeg_error_mgr jerr;
|
||||||
@ -126,8 +139,20 @@ static bool WritePng(const char* filename, byte* image, size_t width, size_t hei
|
|||||||
{
|
{
|
||||||
bool b = false;
|
bool b = false;
|
||||||
FILE* file;
|
FILE* file;
|
||||||
|
errno_t fileResult;
|
||||||
|
|
||||||
if (fopen_s(&file, filename, "wb") == 0)
|
//Just to be extra safe.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
rlg l(fileCs);
|
||||||
|
fileResult = fopen_s(&file, filename, "wb");
|
||||||
|
}
|
||||||
|
catch (std::exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileResult == 0)
|
||||||
{
|
{
|
||||||
png_structp png_ptr;
|
png_structp png_ptr;
|
||||||
png_infop info_ptr;
|
png_infop info_ptr;
|
||||||
@ -261,7 +286,7 @@ static bool SaveBmp(const char* filename, const byte* image, size_t width, size_
|
|||||||
BITMAPFILEHEADER bmfh;
|
BITMAPFILEHEADER bmfh;
|
||||||
BITMAPINFOHEADER info;
|
BITMAPINFOHEADER info;
|
||||||
DWORD bwritten;
|
DWORD bwritten;
|
||||||
HANDLE file;
|
HANDLE file = nullptr;
|
||||||
memset (&bmfh, 0, sizeof (BITMAPFILEHEADER));
|
memset (&bmfh, 0, sizeof (BITMAPFILEHEADER));
|
||||||
memset (&info, 0, sizeof (BITMAPINFOHEADER));
|
memset (&info, 0, sizeof (BITMAPINFOHEADER));
|
||||||
bmfh.bfType = 0x4d42; // 0x4d42 = 'BM'
|
bmfh.bfType = 0x4d42; // 0x4d42 = 'BM'
|
||||||
@ -281,7 +306,18 @@ static bool SaveBmp(const char* filename, const byte* image, size_t width, size_
|
|||||||
info.biClrUsed = 0;
|
info.biClrUsed = 0;
|
||||||
info.biClrImportant = 0;
|
info.biClrImportant = 0;
|
||||||
|
|
||||||
if ((file = CreateFileA(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == NULL)
|
//Just to be extra safe.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
rlg l(fileCs);
|
||||||
|
|
||||||
|
if ((file = CreateFileA(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == NULL)
|
||||||
|
{
|
||||||
|
CloseHandle(file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception)
|
||||||
{
|
{
|
||||||
CloseHandle(file);
|
CloseHandle(file);
|
||||||
return false;
|
return false;
|
||||||
@ -348,11 +384,21 @@ static bool WriteExr(const char* filename, Rgba* image, size_t width, size_t hei
|
|||||||
{
|
{
|
||||||
int iw = int(width);
|
int iw = int(width);
|
||||||
int ih = int(height);
|
int ih = int(height);
|
||||||
RgbaOutputFile file(filename, iw, ih, WRITE_RGBA);
|
std::unique_ptr<RgbaOutputFile> file;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
rlg l(fileCs);
|
||||||
|
file = std::make_unique<RgbaOutputFile>(filename, iw, ih, WRITE_RGBA);
|
||||||
|
}
|
||||||
|
catch (std::exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (enableComments)
|
if (enableComments)
|
||||||
{
|
{
|
||||||
auto& header = const_cast<Imf::Header&>(file.header());
|
auto& header = const_cast<Imf::Header&>(file->header());
|
||||||
header.insert("ember_version", StringAttribute(EmberVersion()));
|
header.insert("ember_version", StringAttribute(EmberVersion()));
|
||||||
header.insert("ember_nickname", StringAttribute(nick));
|
header.insert("ember_nickname", StringAttribute(nick));
|
||||||
header.insert("ember_url", StringAttribute(url));
|
header.insert("ember_url", StringAttribute(url));
|
||||||
@ -363,8 +409,8 @@ static bool WriteExr(const char* filename, Rgba* image, size_t width, size_t hei
|
|||||||
header.insert("ember_genome", StringAttribute(comments.m_Genome));
|
header.insert("ember_genome", StringAttribute(comments.m_Genome));
|
||||||
}
|
}
|
||||||
|
|
||||||
file.setFrameBuffer(image, 1, iw);
|
file->setFrameBuffer(image, 1, iw);
|
||||||
file.writePixels(ih);
|
file->writePixels(ih);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (std::exception e)
|
catch (std::exception e)
|
||||||
|
@ -28,7 +28,6 @@ bool EmberRender(EmberOptions& opt)
|
|||||||
|
|
||||||
VerbosePrint("Using " << (sizeof(T) == sizeof(float) ? "single" : "double") << " precision.");
|
VerbosePrint("Using " << (sizeof(T) == sizeof(float) ? "single" : "double") << " precision.");
|
||||||
Timing t;
|
Timing t;
|
||||||
bool writeSuccess = false;
|
|
||||||
uint padding;
|
uint padding;
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t strips;
|
size_t strips;
|
||||||
@ -304,7 +303,7 @@ bool EmberRender(EmberOptions& opt)
|
|||||||
{
|
{
|
||||||
auto filename = MakeSingleFilename(inputPath, opt.Out(), finalEmber.m_Name, opt.Prefix(), opt.Suffix(), "bmp", padding, i, useName);
|
auto filename = MakeSingleFilename(inputPath, opt.Out(), finalEmber.m_Name, opt.Prefix(), opt.Suffix(), "bmp", padding, i, useName);
|
||||||
VerbosePrint("Writing " + filename);
|
VerbosePrint("Writing " + filename);
|
||||||
writeSuccess = WriteBmp(filename.c_str(), rgb8Image.data(), finalEmber.m_FinalRasW, finalEmber.m_FinalRasH);
|
auto writeSuccess = WriteBmp(filename.c_str(), rgb8Image.data(), finalEmber.m_FinalRasW, finalEmber.m_FinalRasH);
|
||||||
|
|
||||||
if (!writeSuccess)
|
if (!writeSuccess)
|
||||||
cout << "Error writing " << filename << "\n";
|
cout << "Error writing " << filename << "\n";
|
||||||
@ -317,7 +316,7 @@ bool EmberRender(EmberOptions& opt)
|
|||||||
{
|
{
|
||||||
auto filename = MakeSingleFilename(inputPath, opt.Out(), finalEmber.m_Name, opt.Prefix(), opt.Suffix(), "jpg", padding, i, useName);
|
auto filename = MakeSingleFilename(inputPath, opt.Out(), finalEmber.m_Name, opt.Prefix(), opt.Suffix(), "jpg", padding, i, useName);
|
||||||
VerbosePrint("Writing " + filename);
|
VerbosePrint("Writing " + filename);
|
||||||
writeSuccess = WriteJpeg(filename.c_str(), rgb8Image.data(), finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, int(opt.JpegQuality()), opt.EnableComments(), comments, opt.Id(), opt.Url(), opt.Nick());
|
auto writeSuccess = WriteJpeg(filename.c_str(), rgb8Image.data(), finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, int(opt.JpegQuality()), opt.EnableComments(), comments, opt.Id(), opt.Url(), opt.Nick());
|
||||||
|
|
||||||
if (!writeSuccess)
|
if (!writeSuccess)
|
||||||
cout << "Error writing " << filename << "\n";
|
cout << "Error writing " << filename << "\n";
|
||||||
@ -337,7 +336,7 @@ bool EmberRender(EmberOptions& opt)
|
|||||||
VerbosePrint("Writing " + filename);
|
VerbosePrint("Writing " + filename);
|
||||||
vector<byte> rgba8Image(size * 4);
|
vector<byte> rgba8Image(size * 4);
|
||||||
Rgba32ToRgba8(finalImagep, rgba8Image.data(), finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, opt.Transparency());
|
Rgba32ToRgba8(finalImagep, rgba8Image.data(), finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, opt.Transparency());
|
||||||
writeSuccess = WritePng(filename.c_str(), rgba8Image.data(), finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, 1, opt.EnableComments(), comments, opt.Id(), opt.Url(), opt.Nick());
|
auto writeSuccess = WritePng(filename.c_str(), rgba8Image.data(), finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, 1, opt.EnableComments(), comments, opt.Id(), opt.Url(), opt.Nick());
|
||||||
|
|
||||||
if (!writeSuccess)
|
if (!writeSuccess)
|
||||||
cout << "Error writing " << filename << "\n";
|
cout << "Error writing " << filename << "\n";
|
||||||
@ -360,7 +359,7 @@ bool EmberRender(EmberOptions& opt)
|
|||||||
VerbosePrint("Writing " + filename);
|
VerbosePrint("Writing " + filename);
|
||||||
vector<glm::uint16> rgba16Image(size * 4);
|
vector<glm::uint16> rgba16Image(size * 4);
|
||||||
Rgba32ToRgba16(finalImagep, rgba16Image.data(), finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, opt.Transparency());
|
Rgba32ToRgba16(finalImagep, rgba16Image.data(), finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, opt.Transparency());
|
||||||
writeSuccess = WritePng(filename.c_str(), (byte*)rgba16Image.data(), finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, 2, opt.EnableComments(), comments, opt.Id(), opt.Url(), opt.Nick());
|
auto writeSuccess = WritePng(filename.c_str(), (byte*)rgba16Image.data(), finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, 2, opt.EnableComments(), comments, opt.Id(), opt.Url(), opt.Nick());
|
||||||
|
|
||||||
if (!writeSuccess)
|
if (!writeSuccess)
|
||||||
cout << "Error writing " << filename << "\n";
|
cout << "Error writing " << filename << "\n";
|
||||||
@ -376,7 +375,7 @@ bool EmberRender(EmberOptions& opt)
|
|||||||
VerbosePrint("Writing " + filename);
|
VerbosePrint("Writing " + filename);
|
||||||
vector<Rgba> rgba32Image(size);
|
vector<Rgba> rgba32Image(size);
|
||||||
Rgba32ToRgbaExr(finalImagep, rgba32Image.data(), finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, opt.Transparency());
|
Rgba32ToRgbaExr(finalImagep, rgba32Image.data(), finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, opt.Transparency());
|
||||||
writeSuccess = WriteExr(filename.c_str(), rgba32Image.data(), finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, opt.EnableComments(), comments, opt.Id(), opt.Url(), opt.Nick());
|
auto writeSuccess = WriteExr(filename.c_str(), rgba32Image.data(), finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, opt.EnableComments(), comments, opt.Id(), opt.Url(), opt.Nick());
|
||||||
|
|
||||||
if (!writeSuccess)
|
if (!writeSuccess)
|
||||||
cout << "Error writing " << filename << "\n";
|
cout << "Error writing " << filename << "\n";
|
||||||
|
Loading…
Reference in New Issue
Block a user