Bug fixes:

--Better locks around creating image files in command line programs.
This commit is contained in:
Person 2017-08-22 20:13:25 -07:00
parent 50485f5d73
commit 4749a7aec4
2 changed files with 59 additions and 14 deletions

View File

@ -3,6 +3,7 @@
#include "EmberCommonPch.h"
#define PNG_COMMENT_MAX 8
static std::recursive_mutex fileCs;
/// <summary>
/// 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;
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;
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;
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_infop info_ptr;
@ -261,7 +286,7 @@ static bool SaveBmp(const char* filename, const byte* image, size_t width, size_
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER info;
DWORD bwritten;
HANDLE file;
HANDLE file = nullptr;
memset (&bmfh, 0, sizeof (BITMAPFILEHEADER));
memset (&info, 0, sizeof (BITMAPINFOHEADER));
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.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);
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 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)
{
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_nickname", StringAttribute(nick));
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));
}
file.setFrameBuffer(image, 1, iw);
file.writePixels(ih);
file->setFrameBuffer(image, 1, iw);
file->writePixels(ih);
return true;
}
catch (std::exception e)

View File

@ -28,7 +28,6 @@ bool EmberRender(EmberOptions& opt)
VerbosePrint("Using " << (sizeof(T) == sizeof(float) ? "single" : "double") << " precision.");
Timing t;
bool writeSuccess = false;
uint padding;
size_t i;
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);
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)
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);
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)
cout << "Error writing " << filename << "\n";
@ -337,7 +336,7 @@ bool EmberRender(EmberOptions& opt)
VerbosePrint("Writing " + filename);
vector<byte> rgba8Image(size * 4);
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)
cout << "Error writing " << filename << "\n";
@ -360,7 +359,7 @@ bool EmberRender(EmberOptions& opt)
VerbosePrint("Writing " + filename);
vector<glm::uint16> rgba16Image(size * 4);
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)
cout << "Error writing " << filename << "\n";
@ -376,7 +375,7 @@ bool EmberRender(EmberOptions& opt)
VerbosePrint("Writing " + filename);
vector<Rgba> rgba32Image(size);
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)
cout << "Error writing " << filename << "\n";