Access violation at 0x00000000 Loading PNG File With SDL_image Library - c++

I am using the SDL2 2.0.3 library with the SDL_image library 2.0.0 in Visual C++ 2010 Express. I am utilizing the SDL_image library to load a variety of PNG and JPEG files from a resources folder. While the library initializes without any errors and loads BMP and JPEG files, it breaks when given a PNG file.
"Unhandled exception at 0x00000000 in appname.exe: 0xC0000005: Access violation."
Inside of my texture manager, (an object that stores and manages textures for the program), is a function to load a texture from a given file name string. Here is the code, including the commented line I used before implementing SDL_image to do the loading. It is within the line bitmapSurface = IMG_Load(... that the exception above is thrown.
/**
* Attempts to load a given image file and reports to the console any failures
*
* #param fileName The exact file name of the resource to be loaded
* #return The SDL_Texture loaded from the given fileName
*/
SDL_Texture* TextureManager::loadTexture(string fileName)
{
//Create our surface in RAM
SDL_Surface *bitmapSurface = NULL;
//bitmapSurface = SDL_LoadBMP(fileName.c_str()); //OLD METHOD; standard SDL, BMP only
bitmapSurface = IMG_Load(fileName.c_str()); //NEW METHOD; SDL_image lib, many formats
//Verify it exists
if (bitmapSurface == NULL)
cout << "Image resource not loaded: " << fileName << " Message: " << IMG_GetError() << endl;
//Create a texture in VRAM from the surface
SDL_Texture *bitmapTexture = NULL;
bitmapTexture = SDL_CreateTextureFromSurface(this->renderer, bitmapSurface);
//Verify it exists
if (bitmapTexture == NULL)
cout << "Failed to create texture: " << fileName << endl;
return bitmapTexture;
}
Call Stack:
00000000()
SDL2_image.dll!6a887a01()
[Frames below may be incorrect and/or missing, no symbols loaded for SDL2_image.dll]
SDL2.dll!6c77da4b()
SDL2_image.dll!6a88792e()
SDL2_image.dll!6a881693()
SDL2_image.dll!6a8817e9()
> appname.exe!TextureManager::loadTexture(std::basic_string<char,std::char_traits<char>,std::allocator<char> > fileName) Line 143 + 0xe bytes C++
00daf5e0()
Here is the constructor for my TextureManager:
/**
* Creates a new TextureManager with the current SDL_Renderer
*
* #param renderer The current renderer instance of the current graphic window
*/
TextureManager::TextureManager(SDL_Renderer* renderer)
{
//Assign our renderer link
this->renderer = renderer;
//Create the vector to hold textures
this->textures = new vector<Texture*>();
//SDL_image initialization
int flags = IMG_INIT_JPG|IMG_INIT_PNG;
int initted = IMG_Init(flags); //Use IMG_Quit(); at closing
if(initted&flags != flags)
{
//Handle error
printf("IMG_Init: Failed to init required jpg and png support!\n");
printf("IMG_Init: %s\n", IMG_GetError());
}
else
{
cout << "SDL_Image initialized for JPEG and PNG support" << endl;
}
}
For your information, I am using Windows 10 x64, which is up to date. Graphics drivers for dual NVidia GTX 550ti are up to date as well.
All DLL files (including the pnglib dll) are in the debug folder and do load. If I remove the DLL file from the program, the image fails to load and provides the message as coded above for NULL surfaces. No exceptions occur.
Question summary:
Why is this exception thrown, why is it only thrown for PNG files, and how can I trace it when the call stack's details end at my call that appears to work properly? Am I doing something wrong, or is there a configuration step I may have missed?
EDIT: Thanks to #Nandu I have recompiled the DLL SDL_image, and got a better call stack output here:
00000000()
> SDL2_image.dll!IMG_LoadPNG_RW(SDL_RWops * src) Line 375 + 0x11 bytes C
SDL2_image.dll!IMG_LoadTyped_RW(SDL_RWops * src, int freesrc, const char * type) Line 193 + 0x12 bytes C
SDL2_image.dll!IMG_Load(const char * file) Line 134 + 0xf bytes C
appname.exe!TextureManager::loadTexture(std::basic_string<char,std::char_traits<char>,std::allocator<char> > fileName) Line 143 + 0xe bytes C++
appname.exe!TextureManager::loadFromDirectory(std::basic_string<char,std::char_traits<char>,std::allocator<char> > relPath) Line 117 + 0x73 bytes C++
appname.exe!SDL_main(int argc, char * * argv) Line 31 C++
appname.exe!main(int argc, char * * argv) Line 140 + 0xd bytes C
appname.exe!__tmainCRTStartup() Line 555 + 0x19 bytes C
appname.exe!mainCRTStartup() Line 371 C
kernel32.dll!77963744()
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
ntdll.dll!77c3a064()
ntdll.dll!77c3a02f()
This suggests the problem is occurring on line 374 of IMG_png.c:
/* Create the PNG loading context structure */
png_ptr = lib.png_create_read_struct(PNG_LIBPNG_VER_STRING,
NULL,NULL,NULL);
VS reports that lib is NULL at this time, which would explain the error! The question becomes, why is it NULL? It seems this code should be doing a check for that, but nonetheless, nobody else seems to having this problem on the almighty internet.

Thank you all very much for you help, but the problem, as usual, was rather obvious!
As noted here by #Gigi: SDL_Image IMG_Load fails on png with: "Failed loading libpng16-16.dll:"
I suggest you try including all the rest - there may be a dependency that you and I are not aware of. In fact I just checked, and libpng requires zlib: libpng.org/pub/png/libpng.html
I'm not sure why my original search or suggestions didn't bring that post up.
I originally excluded the DLLs for other file formats I wasn't using (or initializing in my code), but once I included the zlib DLL, bingo. PNGs load exactly as expected.

Related

C++ Tesseract OCR: Getting ObjectCache(): WARNING! LEAK! object still has count 1

I installed libtesseract-dev (v4.1.1) on Ubuntu 20.04 & I am trying out a C++ code to OCR an image to searchable PDF.
My code is somewhat modified than the C++ API example code provided at official website:
/home/test/Desktop/Example2/testexample2.cpp:
#include <leptonica/allheaders.h>
#include <tesseract/baseapi.h>
#include <tesseract/renderer.h>
int main()
{
//const char* input_image = "/usr/src/tesseract-oc/testing/phototest.tif";
//const char* output_base = "my_first_tesseract_pdf";
//const char* datapath = "/Projects/OCR/tesseract/tessdata";
const char* input_image = "001.jpg";
const char* output_base = "001";
const char* datapath = ".";
int timeout_ms = 5000;
const char* retry_config = nullptr;
bool textonly = false;
int jpg_quality = 92;
tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
if (api->Init(datapath, "eng")) {
fprintf(stderr, "Could not initialize tesseract.\n");
exit(1);
}
/*
tesseract::TessPDFRenderer *renderer = new tesseract::TessPDFRenderer(
output_base, api->GetDatapath(), textonly, jpg_quality);
*/
tesseract::TessPDFRenderer *renderer = new tesseract::TessPDFRenderer(
output_base, api->GetDatapath(), textonly);
bool succeed = api->ProcessPages(input_image, retry_config, timeout_ms, renderer);
if (!succeed) {
fprintf(stderr, "Error during processing.\n");
return EXIT_FAILURE;
}
api->End();
return EXIT_SUCCESS;
}
I also followed https://stackoverflow.com/a/59382664 as follows:
cd /home/test/Desktop/Example2
wget https://github.com/tesseract-ocr/tessdata/raw/master/eng.traineddata
wget https://github.com/tesseract-ocr/tesseract/blob/master/tessdata/pdf.ttf
export TESSDATA_PREFIX=$(pwd)
gedit config
(In the config file, entered the contents:
tessedit_create_pdf 1 Write .pdf output file
tessedit_create txt 1 Write .txt output file
)
g++ testexample2.cpp -o testexample2 -ltesseract
./testexample2
But on execution, it displays the errors as follows:
Warning: Invalid resolution 0 dpi. Using 70 instead.
Error during processing.
ObjectCache(0x7f1b096669c0)::~ObjectCache(): WARNING! LEAK! object 0x55af5c5241a0 still has count 1 (id /home/test/Desktop/Example2/eng.traineddatapunc-dawg)
ObjectCache(0x7f1b096669c0)::~ObjectCache(): WARNING! LEAK! object 0x55af5c506770 still has count 1 (id /home/test/Desktop/Example2/eng.traineddataword-dawg)
ObjectCache(0x7f1b096669c0)::~ObjectCache(): WARNING! LEAK! object 0x55af5c9a4a70 still has count 1 (id /home/test/Desktop/Example2/eng.traineddatanumber-dawg)
ObjectCache(0x7f1b096669c0)::~ObjectCache(): WARNING! LEAK! object 0x55af5c9a4980 still has count 1 (id /home/test/Desktop/Example2/eng.traineddatabigram-dawg)
ObjectCache(0x7f1b096669c0)::~ObjectCache(): WARNING! LEAK! object 0x55af5d7d5170 still has count 1 (id /home/test/Desktop/Example2/eng.traineddatafreq-dawg)
My directory structure is:
Example2
|------->001.jpg
|------->config
|------->eng.traineddata
|------->pdf.ttf
|------->testexample2
|------->testexample2.cpp
I have searched about this on multiple sources, but could not find any fix for this.
Further, I would like to know if there is someway I can build a binary using C++ compilation from this code + libtesseract such that my binary becomes a standalone portable binary, running which on other Ubuntu systems would not require reinstalling tesseract libraries & their dependencies
tesseract API examples is show case for using tesseract features without covering all specifics of programming language of your choice (c++ in your case).
Just looking at your code even without trying it: you dynamically allocates memory 2x but you did not deallocate them. Try to fix these issues.
You must free use dynamic memory for your class "api"
Use:
... you code...
if (renderer) delete renderer;
if (api) delete api;

Runtime error on Windows when trying to load image with libpng

I am using pHash and that library uses libpng. I am having issues running my program because libpng fails loading a PNG file.
Version of libpng: 1.4.19
Platform: Windows 10
Environment: Visual Studio 2015
Trivial
Just if you came up with the following questions...
Is the path to image correct? Yes
Is the image a valid PNG file? Yes
Code details
Library pHash uses CImg, the version of CImg they are using is a bit old I think:
#define cimg_version 148 // In CImg.h
I have debugged the library and the problems occurs in CImg.h (contained in the pHash VC++ project):
CImg<T>& _load_png(std::FILE *const file, const char *const filename) {
if (!file && !filename)
throw CImgArgumentException(_cimg_instance
"load_png() : Specified filename is (null).",
cimg_instance);
// Open file and check for PNG validity
if (Buffer) strcat(Buffer, "Checking PNG availability\r\n");
const char *volatile nfilename = filename; // two 'volatile' here to remove a g++ warning due to 'setjmp'.
std::FILE *volatile nfile = file?file:cimg::fopen(nfilename,"rb");
unsigned char pngCheck[8] = { 0 };
cimg::fread(pngCheck,8,(std::FILE*)nfile);
if (png_sig_cmp(pngCheck,0,8)) {
if (!file) cimg::fclose(nfile);
throw CImgIOException(_cimg_instance
"load_png() : Invalid PNG file '%s'.",
cimg_instance,
nfilename?nfilename:"(FILE*)");
}
// Setup PNG structures for read
png_voidp user_error_ptr = 0;
png_error_ptr user_error_fn = 0, user_warning_fn = 0;
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,user_error_ptr,user_error_fn,user_warning_fn);
if (!png_ptr) { // <-- PROBLEM HERE
if (!file) cimg::fclose(nfile);
throw CImgIOException(_cimg_instance
"load_png() : Failed to initialize 'png_ptr' structure for file '%s'.",
cimg_instance,
nfilename?nfilename:"(FILE*)");
...
}
The snippet shows the first part of CImg<T>& _load_png(std::FILE *const file, const char *const filename) which is called by the CImg library used by pHash.
Runtime issue
The code compiles fine but I get this error at runtime which I can see in the debugger:
CImgIOException: Failed to initialize 'png_ptr'...
In the point indicated in the code. I don't know why, it fails loading the image. The failure occurs when calling png_create_read_struct in CImg.h. That code is a bit obscure as defined through preprocessor directives. It is not clear why it is failing.
Any ideas?
Either if you are including libpng yourself or if another library is including and using libpng there are a few things to be aware of.
Which ever version of Visual Studio you are using, the libpng (dll or lib) files must be built from the same version of Visual Studio that your solution is linking against.
The platform you are using 32bit or 64bit is of concern.
Project settings when building the png library must match the build types of your current project. (Code Generation -> Runtime Library) must match. Your character set should match as well.
It is a little to difficult to tell what exactly is causing the problem but these are a few things to have a look at.
One thing I would suggest is to go to the website that provides the newest version of libpng and download it. Set a folder on your computer and create "system environment variable through windows" to point to your library. Open the solution to this library in the current version of VS you are using, build it out for both a static lib and dynamic lib (two different solutions) and build them both out for 32 bit and 64 bit saving the generated files into separated folders. Then go into the other library that depends on this and try to switch the dlls or libs and link against the new ones if possible. Also the other 3rd party library you should try to open its solution in the same version of VS and try to do a clean build from there. Then make sure you link everything properly. You may have to also modify the props file.
EDIT
I am not familiar with pHash or CImg, but I am familiar with libpng.
Here is a function in one of my projects to load in a png into a texture structure. Now this is a part of a class object that relies on many other classes, but you should be able to see from this snippet that I am successfully using libpng.
// ----------------------------------------------------------------------------
// loadPng()
bool TextureFileReader::loadPng( Texture* pTexture ) {
struct PngFile {
FILE* fp;
png_struct* pStruct;
png_info* pInfo;
// --------------------------------------------------------------------
PngFile() :
fp( NULL ),
pStruct( NULL ),
pInfo( NULL )
{} // PngFile
// --------------------------------------------------------------------
~PngFile() {
if ( NULL != fp ) {
fclose( fp );
}
if ( NULL != pStruct ) {
if ( NULL != pInfo ) {
png_destroy_read_struct( &pStruct, &pInfo, NULL );
} else {
png_destroy_read_struct( &pStruct, NULL, NULL );
}
}
} // ~PngFile
} png;
// Error Message Handling
std::ostringstream strStream;
strStream << __FUNCTION__ << " ";
if ( fopen_s( &png.fp, m_strFilenameWithPath.c_str(), "rb" ) != 0 ) {
strStream << "can not open file for reading";
throwError( strStream );
}
// Test If File Is Actually A PNG Image
const int NUM_HEADER_BYTES = 8;
png_byte headerBytes[NUM_HEADER_BYTES];
// Read The File Header
if ( fread( headerBytes, 1, NUM_HEADER_BYTES, png.fp ) != NUM_HEADER_BYTES ) {
strStream << "error reading header";
return false;
}
// Test Header
if ( png_sig_cmp( headerBytes, 0, NUM_HEADER_BYTES ) != 0 ) {
return false; // Not A PNG FILE
}
// Init PNG Read Structure - Test PNG Version Compatibility
png.pStruct = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
if ( NULL == png.pStruct ) {
strStream << "can not create struct for PNG file";
throwError( strStream );
}
// Init PNG Info Structure - Allocate Memory For Image Info
png.pInfo = png_create_info_struct( png.pStruct );
if ( NULL == png.pInfo ) {
strStream << "can not create info for PNG file";
throwError( strStream );
}
// Prepare For Error Handling
if ( setjmp( png_jmpbuf( png.pStruct ) ) ) {
strStream << "can not init error handling for PNG file";
throwError( strStream );
}
// Tell libPng Where The File Data Is
png_init_io( png.pStruct, png.fp );
// Tell libPng That You Have Already Read The Header Bytes
png_set_sig_bytes( png.pStruct, NUM_HEADER_BYTES );
// Read Image Data From The File
png_read_png( png.pStruct, png.pInfo, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_GRAY_TO_RGB, NULL );
// Show Image Attributes
png_byte colorType = png_get_color_type( png.pStruct, png.pInfo );
switch( colorType ) {
case PNG_COLOR_TYPE_RGB:
case PNG_COLOR_TYPE_RGBA: {
break;
}
default: {
strStream << "PNG is saved in an unsupported color type (" << colorType << ")";
throwError( strStream );
}
}
unsigned uHeight = png_get_image_height( png.pStruct, png.pInfo );
unsigned uBytesPerRow = png_get_rowbytes( png.pStruct, png.pInfo );
if ( 0 == uHeight || 0 == uBytesPerRow ) {
strStream << "invalid image size. Height(" << uHeight << "), Bytes per row(" << uBytesPerRow << ")";
throwError( strStream );
}
// Make Room For All Pixel Data
unsigned uTotalNumBytes = uHeight * uBytesPerRow;
pTexture->vPixelData.resize( uTotalNumBytes );
// Get All Pixel Data From PNG Image
png_bytepp ppPixelRow = png_get_rows( png.pStruct, png.pInfo );
for ( unsigned int r = 0; r < uHeight; ++r ) {
memcpy( &pTexture->vPixelData[ uBytesPerRow * ( uHeight - 1 - r ) ], ppPixelRow[r], uBytesPerRow );
}
// Store Other Values In Texture
pTexture->uWidth = png_get_image_width( png.pStruct, png.pInfo );
pTexture->uHeight = uHeight;
pTexture->hasAlphaChannel = ( colorType == PNG_COLOR_TYPE_RGBA );
return true;
} // loadPng
Looking through the source code for png_create_read_struct_2(), there are only 2 failure modes: inability to allocate memory, which is unlikely to be the problem, and a library version conflict.
If you are using a precompiled build of the pHash library, you must ensure that the copy of the libpng DLL that gets linked dynamically at runtime is the same version of the library that pHash was compiled against. The latest Windows build on pHash.org ships with libpng12.dll in the "Release" subdirectory, which is probably incompatible the version that you mentioned in the question, namely 1.4.19.
If you are building pHash from source, make sure that the libpng include files that are being used in your build process match the version being loaded at runtime.
If you're unsure exactly which DLLs are being loaded at runtime, the surest way I know to determine it would be to use Process Monitor.

Tesseract OCR German Special Characters

iam using tesseract ocr for reading german png images in c++ and i got problems with some special characters like
ß ä ö ü and so on.
Do i need to train tesseract for reading this correct or what need to be done?
This is the part of the original image read by tesseract
tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
UPDATE
SetConsoleOutputCP(1252);//changed to german.
SetConsoleCP(1252);//changed to german
wcout << "ÄÖÜ?ß" << endl;
// Open input image with leptonica library
Pix *image = pixRead("D:\\Images\\Document.png");
api->Init("D:\\TesseractBeispiele\\Tessaractbeispiel\\Tessaractbeispiel\\tessdata", "deu");
api->SetImage(image);
api->SetVariable("save_blob_choices", "T");
api->SetRectangle(1000, 3000, 9000, 9000);
api->Recognize(NULL);
// Get OCR result
wcout << api->GetUTF8Text());
After changing the Code below the Update
the hard coded umlauts will be shown correctly, but the text from the image issnt correct, what do i need to change?
tesseract version is 3.0.2
leptonica version is 1.68
Tesseract can recognize Unicode characters. Your console may have not been configured to display them.
What encoding/code page is cmd.exe using?
Unicode characters in Windows command line - how?
i don't how to detect German the word from the image in windows environment. but i know how to detect German word to Linux environment. following code may get you some idea.
/*
* word_OCR.cpp
*
* Created on: Jun 23, 2016
* Author: root
*/
#include <tesseract/baseapi.h>
#include <leptonica/allheaders.h>
#include <iostream>
using namespace std;
int main(int argc ,char **argv)
{
Pix *image = pixRead(argv[1]);
if (image == 0) {
cout << "Cannot load input file!\n";
}
tesseract::TessBaseAPI tess;
// insted of the passing "eng" pass "deu".
if (tess.Init("/usr/share/tesseract/tessdata", "deu")) {
fprintf(stderr, "Could not initialize tesseract.\n");
exit(1);
}
tess.SetImage(image);
tess.Recognize(0);
tesseract::ResultIterator *ri = tess.GetIterator();
tesseract::PageIteratorLevel level = tesseract::RIL_WORD;
if(ri!=0)
{
do {
const char *word = ri->GetUTF8Text(level);
cout << word << endl;
delete []word;
} while (ri->Next(level));
delete []ri;
}
}
one thing you have to take care that pass good resolution image then and then it works fine.

SDL_LoadBMP only returning NULL

I've been following this tutorial, and I've got to the point where we are instructed how to load and use bitmaps. Here is the current code:
#include "SDL/SDL.h"
#include <stdlib.h>
int main (int arg, char *argc[]) {
SDL_Surface* screen = NULL;
SDL_Surface* hello = NULL;
SDL_Init(SDL_INIT_EVERYTHING);
screen = SDL_SetVideoMode (256, 256, 32, SDL_SWSURFACE);
hello = SDL_LoadBMP("hello world.png"); // Here
if (hello == NULL) exit(0);
SDL_BlitSurface(hello, NULL, screen, NULL);
SDL_Flip(screen);
SDL_Delay(2000);
SDL_FreeSurface(hello);
SDL_Quit();
return 0;
}
hello, however, never gets any value other than NULL. I'm using Code::Blocks, and even if I scatter hello world.png through all possible directories of the project (be it inside bin, obj, either of the Debug's, the directory with the .cbp) or specify the whole path to the image in-code (as in SDL_LoadBMP("C:\Dir\hello world.png")) hello will get NULL.
What am I doing wrong?
OS is Windows
EDIT: Alright, apparently SDL_LoadBMP can only load .bmp files! How silly of me.
Edit: I mixed SDL_LoadBMP with IMG_Load, here's my new answer:
You can use SDL Image (include SDL_Image.h, link SDL_image.lib and make sure that the correct DLL for you file type is with your binary, if you need one) to call IMG_Load. IMG_Load will take care to resolve your file type and use the appropriate loaded to create a new SDL Surface. Remember to Free your surface when you're done with it.
Yes, it only loads bitmaps. You can use SDL_Image to load other types such as a png.

SDL Video Init causes Exception on Mac OS X 10.8

I have just ported my C++ game to OS X and the first time it ran I get the following exception when trying to call SDL_SetVideoMode.
2012-09-28 15:01:05.437 SCRAsteroids[28595:707] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error (1000) creating CGSWindow on line 259'
* First throw call stack:
(
0 CoreFoundation 0x00007fff8b53b716 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff90e30470 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8b53b4ec +[NSException raise:format:] + 204
3 AppKit 0x00007fff8a26a579 _NSCreateWindowWithOpaqueShape2 + 655
4 AppKit 0x00007fff8a268d70 -[NSWindow _commonAwake] + 2002
5 AppKit 0x00007fff8a2277e2 -[NSWindow _commonInitFrame:styleMask:backing:defer:] + 1763
6 AppKit 0x00007fff8a22692f -[NSWindow _initContent:styleMask:backing:defer:contentView:] + 1568
7 AppKit 0x00007fff8a2262ff -[NSWindow initWithContentRect:styleMask:backing:defer:] + 45
8 libSDL-1.2.0.dylib 0x0000000107c228f6 -[SDL_QuartzWindow initWithContentRect:styleMask:backing:defer:] + 294
9 libSDL-1.2.0.dylib 0x0000000107c20505 QZ_SetVideoMode + 2837
10 libSDL-1.2.0.dylib 0x0000000107c17af5 SDL_SetVideoMode + 917
11 SCRAsteroids 0x0000000107be60fb _ZN11SDLGraphics4initEP6IWorldii + 291
)
libc++abi.dylib: terminate called throwing an exception
Abort trap: 6
My init code looks like this:
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
return false;
const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo();
if (!videoInfo) {
fprintf(stderr, "Video query failed: %s\n",
SDL_GetError());
return false;
}
/* the flags to pass to SDL_SetVideoMode */
videoFlags = SDL_OPENGL; /* Enable OpenGL in SDL */
videoFlags |= SDL_GL_DOUBLEBUFFER; /* Enable double buffering */
videoFlags |= SDL_HWPALETTE; /* Store the palette in hardware */
/* This checks to see if surfaces can be stored in memory */
if (videoInfo->hw_available)
videoFlags |= SDL_HWSURFACE;
else
videoFlags |= SDL_SWSURFACE;
if (w == 0) {
widthViewport = videoInfo->current_w;
heightViewport = videoInfo->current_h;
cout << "Will use full screen resolution of ";
videoFlags |= SDL_FULLSCREEN;
} else {
cout << "Will use full user supplied resolution of ";
widthViewport = w;
heightViewport = h;
videoFlags |= SDL_RESIZABLE; /* Enable window resizing */
}
cout << widthViewport << "x" << heightViewport << "\n";
/* This checks if hardware blits can be done */
if (videoInfo->blit_hw)
videoFlags |= SDL_HWACCEL;
/* Sets up OpenGL double buffering */
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
/* get a SDL surface */
surface = SDL_SetVideoMode(widthViewport, heightViewport,
SCREEN_BPP, videoFlags);
It gets into that last SDL call and throws the exception above. I have tried it in both full screen and resizable window mode, same thing.
I build my app old school, on the command line, as opposed to using Xcode.
SDL_main was yet again the culprit. My C++ main routine was in a file that does not include SDL.h, so it was not being redefined to SDL_main. The code that includes SDL is instead in a reusable static library, no main routine you see. I manually changed the name of my function to SDL_main and this means that SDL provides the essential main routine. I don't like doing this, but for the moment, on SDL 1.2.15 for Mac, it is necessary.
On Windows, the same new code causes linker conflicts. That's a new problem.
There are problems with calling the videocard in cocoa. So you need to initalize it before calling SDL_Setvideomode
Add the following method, and call it first in your main method
#include <dlfcn.h> //To make it work on mac
//This must be called before playing with SDL, else it won't work on osx.
void pre_init()
{
void* cocoa_lib;
cocoa_lib = dlopen( "/System/Library/Frameworks/Cocoa.framework/Cocoa", RTLD_LAZY );
void (*nsappload)(void);
nsappload = (void(*)()) dlsym( cocoa_lib, "NSApplicationLoad");
nsappload();
}
`
Same issue, but solved by linking libSDLmain (as well as libSDL). This in turn requires two frameworks: Foundation and Cocoa.
I didn't rename the main function.