Error when decoding a gif using giflib - c++

I'm attempting to decode .gif files using giflib. The following code leads to a segfault on the final line (the output width/height is correct).
GifFileType* gif = DGifOpenFileName(filename.c_str(), &errCode);
if (gif == NULL) {
std::cout << "Failed to open .gif, return error with type " << errCode << std::endl;
return false;
}
int slurpReturn = DGifSlurp(gif);
if (slurpReturn != GIF_OK) {
std::cout << "Failed to read .gif file" << std::endl;
return false;
}
std::cout << "Opened .gif with width/height = " << gif->SWidth << " " << gif->SHeight << std::endl;
std::cout << gif->SavedImages[0].RasterBits[0] << std::endl;
Output:
Opened .gif with width/height = 921 922
zsh: segmentation fault (core dumped) ./bin/testgiflib
As I understand, giflib should populate gif->SavedImages. But it is NULL after calling DGifSlurp().
Any ideas would be appreciated.
EDIT
I've added the following lines of code following a suggestion in comments:
if (gif->SavedImages == NULL) {
std::cout <<"SavedImages is NULL" << std::endl;
}
The line is printed, indicating that SavedImages is NULL.
EDIT2
Some gifs on which this issue occurs (note that I can't get it to work on any gifs):
https://upload.wikimedia.org/wikipedia/en/3/39/Specialist_Science_Logo.gif
GIF image data, version 89a, 921 x 922
https://upload.wikimedia.org/wikipedia/commons/2/25/Nasa-logo.gif
GIF image data, version 87a, 1008 x 863

Preface: Looks like in my version of giflib, 4.1.6, the DGifOpenFileName() function takes only the filename parameter, and does not return an error code, which is an irrelevant detail.
After adjusting for the API change, and adding the necessary includes, I compiled and executed the following complete, standalone test program:
#include <gif_lib.h>
#include <iostream>
int main()
{
GifFileType* gif = DGifOpenFileName("Specialist_Science_Logo.gif");
if (gif == NULL) {
std::cout << "Failed to open .gif, return error with type " << std::endl;
return false;
}
int slurpReturn = DGifSlurp(gif);
if (slurpReturn != GIF_OK) {
std::cout << "Failed to read .gif file" << std::endl;
return false;
}
std::cout << "Opened .gif with width/height = " << gif->SWidth << " " << gif->SHeight << std::endl;
std::cout << (int)gif->SavedImages[0].RasterBits[0] << std::endl;
}
Except for the presence of the header files, the slightly different DGifOpenFilename() signature, and my tweak to cast the second output line's value to an explicit (int), this is identical to your code. Also, the code was changed to explicitly open the Specialist_Science_Logo.gif file, one of the GIF image files you were having an issue with.
This code executed successfully on Fedora x86-64, giflib 4.1.6, gcc 5.5.1, without any issues.
Instrumenting the sample code with valgrind did not reveal any memory access violations.
From this, I conclude that there is nothing wrong with the shown code. The shown code is obviously an excerpt from a larger application. The bug lies elsewhere in this application, or perhaps giflib itself, and only manifests here.

Related

Creating logical device in Vulkan returns -8, but only sometimes

While using a class to hold my window class and Vulkan class, this error VK_ERROR_FEATURE_NOT_PRESENT is returned when I use vkCreateDevice however, when I put the same code the class is running into the main class, it works completely fine. I also had a similar problem with getting the instance extensions via SDL_Vulkan_GetInstanceExtensions.
working main.cpp
window.createWindow();
engine.window = window.window;
try {
engine.initialize();
}
catch (XiError error) {
std::cout << "Error " << error.code << ": " << error.definition << std::endl;
}
window.instance = engine.getVkInstance();
VkPhysicalDeviceProperties deviceProperties;
vkGetPhysicalDeviceProperties(engine.physicalDevice, &deviceProperties);
std::cout << deviceProperties.deviceName << ", Driver Version " << deviceProperties.driverVersion << std::endl;
try {
window.createSurface();
}
catch (XiError error) {
std::cout << "Error " << error.code << ": " << error.definition << std::endl;
}
window.mainLoop();
vkDestroyDevice(engine.logicalDevice, nullptr);
vkDestroySurfaceKHR(engine.instance, window.surface, nullptr);
vkDestroyInstance(engine.instance, nullptr);
SDL_DestroyWindow(window.window);
SDL_Quit();
not working main.cpp
try {
app.run();
}
catch (XiError error) {
std::cout << "Error " << error.code << ": " << error.definition << std::endl;
}
VkPhysicalDeviceProperties deviceProperties;
vkGetPhysicalDeviceProperties(app.engine.physicalDevice, &deviceProperties);
std::cout << deviceProperties.deviceName << ", Driver Version " << deviceProperties.driverVersion << std::endl;
app.window.mainLoop();
app.shutDown();
app.run()
window.createWindow();
engine.window = window.window;
engine.createVulkanInstance();
window.instance = engine.getVkInstance();
window.createSurface();
engine.getPhysicalDevices();
engine.selectPhysicalDevice();
engine.createLogicalDevice();
window.mainLoop();
app.shutDown()
vkDestroyDevice(engine.logicalDevice, nullptr);
vkDestroySurfaceKHR(engine.instance, window.surface, nullptr);
vkDestroyInstance(engine.instance, nullptr);
SDL_DestroyWindow(window.window);
SDL_Quit();
window engine and app are pre-defined by my own classes
I've tried manually adding the different required and supported extensions, and it works, but it feels hacky and is quite a large bulk of code. If this is a weird out of scope error, I've really no idea. if any other code is needed I'll be happy to provide it and the GitHub can also be found here: https://github.com/XiniaDev/Xinia-Engine
I think your problem is that requiredFeatures in XiEngine is not initialised. You set a few values to true, but I think you need a memset(&requiredFeatures, 0, sizeof(requiredFeatures)); or similar at the start of XiEngine::XiEngine to fix it.

Reading large schemas with GenericData from Avro in C++

This question is in reference to: How to read data from AVRO file using C++ interface?
int main(int argc, char**argv)
{
std::cout << "AVRO Test\n" << std::endl;
if (argc < 2)
{
std::cerr << BOLD << RED << "ERROR: " << ENDC << "please provide an "
<< "input file\n" << std::endl;
return -1;
}
avro::DataFileReader<avro::GenericDatum> reader(argv[1]);
auto dataSchema = reader.dataSchema();
// Write out data schema in JSON for grins
std::ofstream output("data_schema.json");
dataSchema.toJson(output);
output.close();
avro::GenericDatum datum(dataSchema);
while (reader.read(datum))
{
std::cout << "Type: " << datum.type() << std::endl;
if (datum.type() == avro::AVRO_RECORD)
{
const avro::GenericRecord& r = datum.value<avro::GenericRecord>();
std::cout << "Field-count: " << r.fieldCount() << std::endl;
// TODO: pull out each field
}
}
return 0;
}
I used this code, but keep getting a seg fault at the while loop. I have a very large schema and a large amount of data. Decoding the data piece by piece as the Avro examples gives in its "cpx" example is not practical, I need a generic way of reading. I get the seg fault the 3rd time through (consistently) with no error code returned from the read(). Open to any and all suggestions and ideas about reading large schemas in Avro.
As it turns out there is an open ticket/issue on the Avro page for this exact issue. https://issues.apache.org/jira/browse/AVRO-3194

GetPrivateProfileStringA is returning "The system cannot find the file specified." eventhough the file exists

in CPP Visual studio 2010. I need to read some configurations from ini file. the below code is not working. can someone help me fix it.
char * path = "C:\\NotBackedUp\\Workspaces\\LDAP-DLL\\LDAPTestApp\\bin\\Debug\\conf\\ldap.ini";
std::wcout << "path: " << path << std::endl;
if(!ATLPath::FileExists(path))
{
HRESULT hr = ATL::AtlHresultFromLastError();
ATLTRACE("%x\n",hr);//system could not find the file specified!
std::cout << "File not found " << std::endl;
return 0;
}
else
{
std::cout << "File found " << std::endl;
}
char valueRead[320];
int a = GetPrivateProfileStringA("ldap", "url", "error", valueRead, 320, path);
std::cout << "Value Read " << valueRead << std::endl;
std::cout << "Error String " << GetLastErrorAsString();
the above code is generating below log, you can see ATLPath::FileExists is returning true, but still getLastError is stating the System cannot find the file specified
path: C:\NotBackedUp\Workspaces\LDAP-DLL\LDAPTestApp\bin\Debug\conf\ldap.ini
File found
Value Read error
Error String The system cannot find the file specified.
My ldap.ini file has following lines and is available in the above path
[ldap]
url=ldap://testserver
any help is highly appreciated
thanks
The ERROR_FILE_NOT_FOUND error code you’re getting is also set when GetPrivateProfileString is unable to find a section or value.
Your code works fine on my Win10 with your ini file.
Use a hex viewer/editor to verify your ldap.ini is actually ASCII, and that it doesn't contain BOM.

std::ofstream : Writing to a file using append and out flags

Below is a simple class which attempts to write an integer to a file. The mode of writing the file is to append characters at the end of the file (In this mode, file should be created if it doesn't exist)
#include <iostream>
#include <fstream>
class TestFileStream
{
private:
std::ofstream* _myFileStream;
bool isFileOpen;
public:
TestFileStream():isFileOpen(false)
{
_myFileStream = new std::ofstream("TestFile.txt", std::ios_base::out | std::ios_base::app );
isFileOpen = _myFileStream->is_open();
if( !isFileOpen )
{
std::cout << "Unable to open log file" << std::endl;
std::cout << "Good State: " << _myFileStream->good() <<std::endl;
std::cout << "Eof State: " << _myFileStream->eof() <<std::endl;
std::cout << "Fail State: " << _myFileStream->fail() <<std::endl;
std::cout << "Bad State: " << _myFileStream->bad() <<std::endl;
}
else
{
std::cout << "Opened log file" << std::endl;
}
}
~TestFileStream()
{
_myFileStream->close();
delete _myFileStream;
_myFileStream = nullptr;
}
void WriteFile( unsigned number )
{
if ( isFileOpen )
{
(*_myFileStream) << "Number: " << number << std::endl;
}
}
};
int main()
{
// Number of iterations can be multiple.
// For testing purpose, only 1 loop iteration executes
for( unsigned iter = 1; iter != 2; ++iter )
{
TestFileStream fileWriteObj;
fileWriteObj.WriteFile( 100+iter );
}
return 0;
}
When I execute the above code, I get following log output:
Unable to open log file
Good State: 0
Eof State: 0
Fail State: 1
Bad State: 0
This seems like trivial task, but I am not able to find out whats causing the failure. Note that this question is most likely related to the following question
Just to summarize the comments, there is nothing wrong about the code you posted (apart from the rather unconventional new ostream ;) )
Note however that opening files may fail for a number of reasons (Permissions, file in use, disk unavailable, the file does not exist, the file exists...). That is why you must always test it.
If you tried to run the above code in an online emulator, then chances are file IO is disabled. Which would explain why you get that the streams fail-bit is set.

FreeType error: FT_Load_Char returns 36

I've been trying to get FreeType working in my game, but it doesn't seem to work whenever I try to load the characters from a font. I've looked at a bunch of tutorials on the web and as far as I can see there doesn't seem to be anything wrong with the code.
I've tried with different fonts but they produce the same error.
This is the code that fails:
int errorCode = FT_New_Face(freetype, filename.c_str(), 0, &face);
if (errorCode != 0)
{
std::cerr << "Failed to load font: " << filename << ". Error code: " << errorCode << std::endl;
}
for (char i = 0; i < 256; i++)
{
errorCode = FT_Load_Char(face, i, FT_LOAD_RENDER); // This returns 36 when i is 0
if (errorCode != 0)
{
std::cerr << filename << ": Failed to load character '" << i << "'. Error code: " << errorCode << std::endl;
}
}
This prints out:
FreeSans.ttf: Failed to load character ' '. Error code: 36
I looked up error code 36 in the FreeType headers and it appears to be "Invalid_Size_Handle". This confounds me since no size handles where passed in the function. The only size handle I can think of the the face->size property, but there shouldn't be anything wrong with it since the face struct was initialized in the FT_New_Face function.
And yes, I do initialize FreeType earlier on in the code.
So, does anybody know what I am doing wrong and what I can do to fix this?
I got that same error code once. I guess the "Invalid_Size_Handle" means that the font size instead of memory size setting is invalid.
I fixed the problem by adding a call to FT_Set_Char_Size right after FT_New_Face. Hope that can be of help.
try to set font size after loading the face:
int errorCode = FT_New_Face(freetype, filename.c_str(), 0, &face);
if (!errorCode)
std::cerr << "Failed to load font: " << filename << ". Error code: " << errorCode << std::endl;
int pensize = 64;
FT_Set_Pixel_Sizes(face, pensize, 0);
// you can now load the glyphs
hope it helps!