1

The program is supposed take pixel data from a uni dimensional array and display it. The pixel data is supposed to be 1 byte per pixel, which is supposed to result in a gray scale image.

The result is supposed to look like this:

GRADIENT PATTERN

Th problem i run into is that the "SDL_SetPaletteColors" command crashes the program.

What am I doing wrong here?

Here is the code:

#include <SDL.h>
#include <stdio.h>

//Screen dimension constants
const int SCREEN_WIDTH = 100;
const int SCREEN_HEIGHT = 100;

char* pixels;
int icnt,icnt2;



//Starts up SDL and creates window
bool init();

//Frees media and shuts down SDL
void close();

//The window we'll be rendering to
SDL_Window* gWindow = NULL;

//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;

//The image we will load and show on the screen
//SDL_Surface* gHelloWorld = NULL;
SDL_Surface* gHelloWorld = NULL;




bool init()
{
    //Initialization flag
    bool success = true;

    //Initialize SDL
    if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
        printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
        success = false;
    }
    else
    {
        //Create window
        gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
        if( gWindow == NULL )
        {
            printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
            success = false;
        }
        else
        {
            //Get window surface
            gScreenSurface = SDL_GetWindowSurface( gWindow );
        }
    }

    return success;
}



void close()
{
    //Deallocate surface
    SDL_FreeSurface( gHelloWorld );
    gHelloWorld = NULL;

    //Destroy window
    SDL_DestroyWindow( gWindow );
    gWindow = NULL;

    //Quit SDL subsystems
    SDL_Quit();
}

int main( int argc, char* args[] )
{
    pixels = new char[10000];      //pixel array
    icnt2=0;
    SDL_Color colors[256];

    for(icnt=0;icnt<10000;icnt++)  //gradient test image generator
    {
      pixels[icnt]=(char)icnt2;
      icnt2++;
      if(icnt2 == 99){icnt2 =0;}
    }



    //Start up SDL and create window
    if( !init() )
    {
        printf( "Failed to initialize!\n" );
    }
    else
    {

            gHelloWorld = SDL_CreateRGBSurfaceFrom((void*)pixels,
            100,
            100,
            8,
            100,
            0x000000FF,
            0x0000FF00,
            0x00FF0000,
            0);

            for(icnt = 0; icnt < 255; icnt++)
            {
                colors[icnt].r = colors[icnt].g = colors[icnt].b = icnt;
            }

            //program crashes here   ------------------
            SDL_SetPaletteColors(gHelloWorld->format->palette, colors, 0, 255);   //program crashes here
            //-----------------------------------------

            //Apply the image
            SDL_BlitSurface( gHelloWorld, NULL, gScreenSurface, NULL );

            //Update the surface
            SDL_UpdateWindowSurface( gWindow );

            //Wait two seconds
            SDL_Delay( 2000 );
        //}
    }

    //Free resources and close SDL
    close();

    return 0;
}
genpfault
  • 51,148
  • 11
  • 85
  • 139
nutron
  • 39
  • 3
  • 2
    Your program is crashing because gHelloWorld is NULL – aram Apr 04 '18 at 18:28
  • And don't name your functions after system functions like `close()`. [Gonna have a bad time.](https://stackoverflow.com/questions/48566070/sdl-error-while-creating-window) – genpfault Apr 04 '18 at 20:00
  • 1
    I changed `close()` to `close_prg()` . Are you sure gHelloWorld is still NULL ? it is at the top of the code , but in the main function it gets a value. `gHelloWorld = SDL_CreateRGBSurfaceFrom((void*)pixels, 100, 100, 8, 100, 0x000000FF, 0x0000FF00, 0x00FF0000, 0);` – nutron Apr 04 '18 at 20:28
  • 2
    @nutron I fail to imagine why Aram (supposedly) decided to just run your program in debugger and quickly figure out where problem is, but you didn't even after that being pointed out. Seriously, use debugger, it helps. On other note - your pixel format makes no sense so SDL_CreateRGBSurfaceFrom fails to create a surface (and `SDL_GetError()` call will say "Unknown pixel format", which explains the problem quite well). You say it is 8 bits per pixel (SDL implies it is paletted) but specify RGB masks way outside of 8 bit range. Setting masks to 0 creates paletted surface here. – keltar Apr 05 '18 at 11:41
  • So i use codeblocks and use the GDB32.exe in compiler settings > toolchain executables > resource compiler. The debugger passes SDL_CreateRGBSurfaceFrom without a problem , but once it reaches SDL_SetPaletteColors , the crash occurs with these errors... – nutron Apr 05 '18 at 14:10
  • #0 0x40158e SDL_main(argc=argc@entry=1, args=args@entry=0x30008) (C:\Users\nutron\Desktop\codeblock_projects\pixel\01_hello_SDL.cpp:117) #1 0x401f4e main_utf8(argv=0x30008, argc=) (../src/main/windows/SDL_windows_main.c:126) #2 ?? main_getcmdline () (../src/main/windows/SDL_windows_main.c:159) #3 0x4021f5 WinMain@16(hInst=0x400000, hPrev=0x0, szCmdLine=0x2743e97 "", sw=10) (../src/main/windows/SDL_windows_main.c:202) #4 0x418e0b main () (??:??) – nutron Apr 05 '18 at 14:14
  • @nutron exactly, and you can use the same debugger to inspect values of your variables (and registers), and it will show your surface to be NULL, as that is what `SDL_CreateRGBSurfaceFrom` returned (it by no means supposed to crash - it couldn't figure out what you want it to do so it raised an error message and returned NULL). Crash happens later when you trying to read from NULL structure and do `gHelloWorld->format->palette`, which have nothing to do with function call. Also using e.g. `-g3` option and reducing compiler optimisation level usually helps with debugging. – keltar Apr 05 '18 at 14:16
  • As you guys said , the return value of `SDL_CreateRGBSurfaceFrom` was NULL. I changed the parameters to fit the provided data format and i get almost the right image i want to. `gHelloWorld = SDL_CreateRGBSurfaceFrom((void*)pixels, 100, 100, 8, 100, 0x00000000, 0x00000000, 0x00000000, 0);` did the trick – nutron Apr 06 '18 at 14:47
  • now i have to figure out two things , why the gradient pattern crops to the right end and why the debugger did not show the return value of `SDL_CreateRGBSurfaceFrom` to be NULL , unless NULL variables are not displayed at all. Thanks guys for the hints. the documentation of SDL is a little sparse when it comes to examples for displaying surfaces generated within code the rather than surfaces loaded from image files. – nutron Apr 06 '18 at 15:00
  • @nutron I suppose crop happens because you do `if(icnt2 == 99){icnt2 =0;}`, but at that point icnt2 already incremented, so it gets reset on each 99th pixel, while row have 100 (and 1 pixel offset accumulated on each line, moving it further and further). As for NULL - it is just a normal value, debugger is not supposed to trap on each NULL. Basically it is just a value that conventionally considered 'special' to indicate empty value. If function can't do what it is requested, it often returns NULL to indicate it failed (but anyway - check documentation of function, there is no guarantee) – keltar Apr 09 '18 at 18:05

0 Answers0