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?
How to init SDL without a window?
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.
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.
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.
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.
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.
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?
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 */ }}
I really can't understand why this is giving me:
It shouldn't depend on anything, surely?
Q. I'm using g++ 'n' gedit on Fed4, which debugger / trace program would you reccomend?
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?
Also with a bit of hard coding, it seems this is also included:
SDL_GetRGB ( pix , surffmt , &color.r , &color.g , &color.b );
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?
Can you post your whole code? Or, if it's too long, an example that demostrates the problem?
Yep, this will be too long! (p.s. very stripped down)
*** CODE ***
*** CODE END ***
A solution would be muchos appreciated!
*** 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!
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.
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.
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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement