Sign in to follow this  

How to init SDL without a window?

This topic is 4050 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm just doing a quick image processing libary. I'm using certain functions from the main api and SDL_image. However i'm not wanting to initialise the screen since it's only ever going to be run from a console. If I don't include part or all of the following I get a 'Segmentation fault' when I call my load_image function.
   if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )

   {

      return 1;    

   }

    

   //Set up the screen

   screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
Any direction?

Share this post


Link to post
Share on other sites
Im not sure what are the exact dependancies of the SDL graphics functions and SDL_Init( SDL_INIT_VIDEO ) and SDL_SetVideoMode.

I would recommend leaving SDL_Init( SDL_INIT_VIDEO ) in, but omitting the call to SDL_SetVideoMode as that shouldnt be required.

Use a debugger to trace the SDL calls that cause segfaults.

Obvious examples are SDL_DisplayFormat*() or attempting to access the members of SDL_GetVideoSurface().

As long as you dont attempt to blit from or to the non-existant display surface you should be all right without SDL_SetVideoMode, that is after all the function you want to avoid calling to create a console application.

Show your load_image function code.

Share this post


Link to post
Share on other sites
Hidden
I'd like to find out about this myself. It seems that whenever I use SDL, console output is disabled. printf() doesn't do anything, no text appears.

Share this post


Link to post
Yeah, I just tried this and rip-off is correct. You need to initalize the video subsystem, but you don't need to set the video mode. I tried loading and saving images, direct pixel access, and blitting, and it all worked.

Also SDL_DisplayFormat will not crash, it just returns NULL.

About stdout, if you are using MSVC, and create a console project, you will be able to use stdout. If you create a windows project, it will be redirected to stdout.txt. I'm not sure about other compilers.

Share this post


Link to post
Share on other sites
Cheers all,

I've changed my load_image function to avoid using SDL_DisplayFormat. That now works fine, I wasn't sure if I wanted to optimise anyway.

The following is libsdl example of getting a pixel. The following line seems to the reason:

int bpp = surface->format->BytesPerPixel;

What other ways are there to avoid this call?




Uint32 getpixel(SDL_Surface *surface, int x, int y)
{
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to retrieve */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

switch(bpp) {
case 1:
return *p;
case 2:
return *(Uint16 *)p;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
return p[0] << 16 | p[1] << 8 | p[2];
else
return p[0] | p[1] << 8 | p[2] << 16;
case 4:
return *(Uint32 *)p;
default:
return 0; /* shouldn't happen, but avoids warnings */
}
}

Share this post


Link to post
Share on other sites
I really can't understand why this is giving me:

Fatal signal: Segmentation Fault (SDL Parachute Deployed)

It shouldn't depend on anything, surely?

Q. I'm using g++ 'n' gedit on Fed4, which debugger / trace program would you reccomend?

Share this post


Link to post
Share on other sites
The code I used included getpixel and putpixel and they worked fine for me. You should be able to inspect the format of any surface except the video surface (obviously).

Can you post your whole code? Or, if it's too long, an example that demostrates the problem?

Share this post


Link to post
Share on other sites
Yep, this will be too long! (p.s. very stripped down)

*** CODE ***


// compile:
// g++ -lSDL -lSDL_image main.cpp -o main
//
// usage:
// ./main -d imgs01/test2.pnm imgs01/test3.pnm imgs01/test.bmp 20
//

/*

PLACES WHERE IT HANGS!
====== ===== == ======

Uint32 getpixel(SDL_Surface *surface, int x, int y) // FUNCTION (where)
int bpp = surface->format->BytesPerPixel; // LINE (what)

SDL_Color get_rgb(int pix, SDL_PixelFormat *surffmt)
SDL_GetRGB ( pix , surffmt , &color.r , &color.g , &color.b );

void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
int bpp = surface->format->BytesPerPixel;

int save_image_bmp( const char *file, SDL_Surface * surf )
int iret = SDL_SaveBMP(surf, file);

*/


#include "SDL/SDL.h"
#include "SDL/SDL_image.h"

#include <string>



int sdl_init()
{
printf("Initialising SDL\n");



if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )

{

return 1;

}



//Set up the screen



printf(" SDL initialised\n");
return 0;
}

int sdl_cleanup()
{

SDL_Quit();
}

int save_image_bmp( const char *file, SDL_Surface * surf )
{
printf(" Saving image\n");
int iret = SDL_SaveBMP(surf, file);
printf(" Saved image\n");
return iret;
}

SDL_Surface *load_image_pnm( std::string fname )

{
printf(" Loading pnm image\n");

SDL_Surface* sret = NULL; // return surface

// load sample.pnm into image
SDL_Surface *image;
SDL_RWops *rwop;
rwop=SDL_RWFromFile(fname.c_str(), "rb");
image=IMG_LoadPNM_RW(rwop);
if(!image) {
printf("IMG_LoadPNM_RW: %s\n", IMG_GetError());
// handle error
}

//If nothing went wrong in loading the image

if( image != NULL )

{

//Create an optimized image

//sret = SDL_DisplayFormat( image );
sret = image;



//Free the old image

SDL_FreeSurface( image );

}
printf(" Load success\n");
return sret;
}

int rgb_compare_range(SDL_Color c1, SDL_Color c2, int tol)
{
if ( ( (c1.r >= c2.r - tol) && (c1.r <= c2.r + tol) ) &&
( (c1.g >= c2.g - tol) && (c1.g <= c2.g + tol) ) &&
( (c1.b >= c2.b - tol) && (c1.b <= c2.b + tol) ) )
{
return 1;
}
return 0;
}

Uint32 getpixel(SDL_Surface *surface, int x, int y)
{
printf(" Getting pixel\n");
//int bpp = 4;
int bpp = surface->format->BytesPerPixel;
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

switch(bpp) {
case 1:
return *p;
case 2:
return *(Uint16 *)p;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
return p[0] << 16 | p[1] << 8 | p[2];
else
return p[0] | p[1] << 8 | p[2] << 16;
case 4:
return *(Uint32 *)p;
default:
return 0; /* shouldn't happen, but avoids warnings */
}
printf(" Got pixel succesfully\n");
}

void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
printf(" Putting pixel\n");
//int bpp = 4;
int bpp = surface->format->BytesPerPixel;
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

switch(bpp) {
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
} else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
printf(" Pixel put succesfully\n");
}

SDL_Color get_rgb(int pix, SDL_PixelFormat *surffmt)
{
SDL_Color c ;
printf(" Getting RGB\n");
SDL_GetRGB ( pix , surffmt , &c.r , &c.g , &c.b );
//c.r = 255; c.g = 100; c.b = 100;
printf(" Got RGB succesfully\n");
return c;
}

SDL_Surface * image_difference(SDL_Surface *surf1, SDL_Surface *surf2, int tol)
{
printf ( "Image find differences\n" );

SDL_Surface* sret = NULL; // our return surface

sret = surf1;

SDL_PixelFormat *surffmt1 = surf1->format;
SDL_PixelFormat *surffmt2 = surf2->format;

int num_diff = 0;
int w1 = surf1->w;
int h1 = surf1->h;
int w2 = surf2->w;
int h2 = surf2->h;
int w, h;

// SIMPLIFIED CHECKING !!!!
w = w1;
h = h1;

int ud = 65504; // diff colour
int us = 35100; // same colour

for (int i = 0; i < w-1; i++)
{
for (int j = 0; j < h-1; j++)
{
// GET COLOUR 1
Uint32 u1 = getpixel(surf1, i, j); // SDL_Surface *surface, int x, int y
SDL_Color c1 = get_rgb(u1, surffmt1); // int pix, SDL_PixelFormat *surffmt1

// GET COLOUR 2
Uint32 u2 = getpixel(surf2, i, j); // SDL_Surface *surface, int x, int y
SDL_Color c2 = get_rgb(u2, surffmt2); // int pix, SDL_PixelFormat *surffmt1

// CHECK THE COLOURS
int iret = rgb_compare_range(c1, c2, tol); // SDL_Color c1, SDL_Color c2, int tol
if ( iret == 1 )
{
num_diff++;
putpixel(sret, i, j, ud); // SDL_Surface *surface, int x, int y, Uint32 pixel
}
else
{
putpixel(sret, i, j, us); // SDL_Surface *surface, int x, int y, Uint32 pixel
}
}
}
printf(" Finished finding differences\n");
return sret;
}

void img_diff(std::string fn1, std::string fn2, char * fout, int tol)
{

SDL_Surface* img1 = load_image_pnm( fn1 );
SDL_Surface* img2 = load_image_pnm( fn2 );
SDL_Surface* s = image_difference(img1, img2, tol); // SDL_Surface *surf1, SDL_Surface *surf2
int iret = save_image_bmp(fout, s); // const char *file, SDL_Surface * surf
//SDL_FreeSurface( img1 );
//SDL_FreeSurface( img2 );
//SDL_FreeSurface( s );
}


int main( int argc, char* args[] )

{
printf("Welcome to imgproc\n");

sdl_init();

int t1 = SDL_GetTicks(); // get num milliseconds since init

// SIMPLIFIED !!!
if (argc == 6)
{
printf("Comparing differences %s to %s\n", args[2], args[3]);
img_diff( args[2], args[3], args[4], atoi(args[5]) ); // std::string fn1, std::string fn2)
}
else { printf("Wrong number of arguments\n");
printf(" usage:\n ./main -d imgs01/test2.pnm imgs01/test3.pnm imgs01/test.bmp 20\n"); }

sdl_cleanup();


int t2 = SDL_GetTicks(); // get num milliseconds since init
int t3 = t2 - t1;
printf("Duration: %d milliseconds...\n", t3);


return 0;

}



*** CODE END ***

A solution would be muchos appreciated!

Share this post


Link to post
Share on other sites
I tested everything but your load_image_pnm function (I don't know what pnm's are). Everything ran without a problem, so I've concluded that your problem must be in this function.


SDL_Surface *load_image_pnm( std::string fname )
{
printf(" Loading pnm image\n");
SDL_Surface* sret = NULL; // return surface

// load sample.pnm into image
SDL_Surface *image;
SDL_RWops *rwop;

rwop=SDL_RWFromFile(fname.c_str(), "rb");
image=IMG_LoadPNM_RW(rwop);

if(!image)
{
printf("IMG_LoadPNM_RW: %s\n", IMG_GetError());
// handle error
}

//If nothing went wrong in loading the image
if( image != NULL )
{
//Create an optimized image
//sret = SDL_DisplayFormat( image );

sret = image; ///////////////////// A

//Free the old image
SDL_FreeSurface( image ); /////////////// B
}

printf(" Load success\n");
return sret;
}



The problem, I think, is on the lines marked A and B. On line A you set your sret to be the image. They now point at the same surface. On line be, you free the "old" image, but it is the same as the new image. This is probably a holdover from when you were calling SDL_DisplayFormat. Since you free the only image you had, the function fails.

Hope that was it.

Share this post


Link to post
Share on other sites
I'm in awe (and that's not a word I use). I can see why it affects everything down the line and even misled me. Cheers thats just what the doctor orderd!

I need to handle 'pnm' files because i'm using 'scanimage' to grab images from my webcams. Here's a little info on them.


Quote:

PBM, PGM, PPM or PNM images?

The PBMplus package is split into four distinct suites. PBM programs to handle bitmaps (1 bit per pixel), PGM programs to handle grayscale images, PPM programs to handle full colour images and lastly PNM programs which carry out content-independent manipulations on any of the three internal formats. PBM stands for Portable Bit Map, PGM stands for Portable Gay Map, PPM stands for Portable Pixel Map and PNM stands for Portable Any Map


EDIT: changed code tags to quote tags; the former were fscking up the page formatting

[Edited by - 23yrold3yrold on November 11, 2006 5:33:10 AM]

Share this post


Link to post
Share on other sites

This topic is 4050 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this