Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » getpixel() crashes program?

Credits go to Dustin Dettmer, Evert, LennyLen, miran, and Onewing for helping out!
This thread is locked; no one can reply to it. rss feed Print
getpixel() crashes program?
Crystylla
Member #7,921
October 2006

I'm trying to put together a Tetris clone called Bubbles using the Allegro library. It was all going swimmingly until I tried to display the bubbles (the blocks that make up the shapes).

See, I'm storing both the grid area and the current shape as small bitmaps a few pixels wide and tall, where one pixel corresponds to one block on screen. As such, I have to check what colour a given pixel is so that I can print the appropriate colour of block onto the screen. And that's where the problem lies.

I try to grab the pixel in question and compare it to my pre-defined colours in some way, to decide what to print to the screen. But every way I try to use to compare the two colours ends up crashing my program. I've tried defining RGB colours and comparing them to the colour grabbed with getpixel(), directly comparing the pixel grabbed to a pixel from a bitmap that exists for the sole purpose of being an example of all of the colours... everything crashes it.

Here's the relevant bit of code (actually, the real thing has more ifs, but they're mostly the same as the first anyway). The loops cycle through all the pixels in the shape bitmap, and the if statement SHOULD print a red bubble in the correct place if the pixel is red. The draw_sprite() by itself works like a charm, but trying any kind of colour comparison makes it crash.

         for(int y = 0; y < c_height; y++) {
              for(int x = 0; x < c_width; x++) {
                   if(_getpixel(cluster, x, y) == makecol(255, 0, 0)) {
                         draw_sprite(buffer, red, (left + ((c_x + x) * b_width)), (top + ((c_y + y) * b_height)));
                   }
              }
         }

I've been experimenting with trial and error for the past few hours, and searching these forums for likely topics, but nothing so far has worked. So a little wisdom from all you Allegro experts would be greatly appreciated.

P.S., try to keep explanations insultingly simple - I'm an Allegro newbie. ;)

Evert
Member #794
November 2000
avatar

Are your bitmaps 8 bit?
_getpixel() only works for 8 bit bitmaps. For higher colour depths, you need to use the proper version (be sure to check the manual for other caveats).

There are better waysto accomplish what you want than what you're doing now, but I'll leave it at the above for now.

Onewing
Member #6,152
August 2005
avatar

Quote:

P.S., try to keep explanations insultingly simple - I'm an Allegro newbie.

First off and foremost, have you stepped through it using a debugger of any kind? I think _getpixel() crashes if it tries to get a pixel outside the bitmap, but getpixel() will return a -1.

------------
Solo-Games.org | My Tech Blog: The Digital Helm

Crystylla
Member #7,921
October 2006

The bitmaps are all 24-bit (or they should be; that's what I saved them saved as). I tried the regular getpixel() as well (in fact, I only tried changing it to _getpixel() recently, in desperation), but that crashes just the same.

The point I'm checking is definitely inside the bitmap. I tried commenting out the loop and just giving it some test co-ordinates to make sure that the loop's x and y values weren't messing it up. And I'll know if it's returning the right thing, because the red bubbles should appear on screen (the Dev-C++ debugger doesn't seem to want to co-operate with me right now).

EDIT: Actually, the bubble and background bitmaps, which are loaded from bitmap files, are 24-bit... but the bitmaps I don't load from files, I don't know.

LennyLen
Member #5,313
December 2004
avatar

Quote:

but the bitmaps I don't load from files, I don't know.

Their bit depth will be whatever you set with set_color_depth. If you didn't set a color depth, they will be 8bit.

Evert
Member #794
November 2000
avatar

Quote:

The bitmaps are all 24-bit (or they should be; that's what I saved them saved as).

Doesn't work with _getpixel then.

Quote:

I tried the regular getpixel() as well (in fact, I only tried changing it to _getpixel() recently, in desperation), but that crashes just the same.

Odd. Check that cluster, buffer and red are valid bitmaps. Try making a small example program that reproduces the error.

Crystylla
Member #7,921
October 2006

Okay, I just tried setting it to 24-bit, and I still get a crash.

(In other news: On closer inspection, I noticed that yeah, setting to x and y to zero at the start of the loops wasn't going to get me far in terms of bitmap co-ordinates, so I've changed that. Also, make x < c_width into x <= c_width to accomodate for that. Same with y.)

for(int y = 1; y <= c_height; y++) {
              for(int x = 1; x <= c_width; x++) {
                   if(getpixel(cluster, x, y) == makecol(255, 0, 0)) {
                         draw_sprite(buffer, blue, (left + ((c_x + x) * b_width)), (top + ((c_y + y) * b_height)));
                   }

You know, I've tried this project before, and then I used char arrays instead of bitmaps to do this (and switch statements instead of if statements). That worked, but I thought this seemed neater somehow. What do you reckon?

EDIT: Trying your advice now, Evert...

LennyLen
Member #5,313
December 2004
avatar

Quote:

On closer inspection, I noticed that yeah, setting to x and y to zero at the start of the loops wasn't going to get me far in terms of bitmap co-ordinates, so I've changed that.

You had it right the first time. The top-left pixel in a bitmap is co-ordinate 0,0.

Crystylla
Member #7,921
October 2006

I did? Hmm, thanks. I'll change it back...

As far as I can see, cluster, buffer and red are valid. I tried throwing together a small test program, but this crashes, too...

1#include <allegro.h>
2 
3void init();
4void deinit();
5 
6int main() {
7 init();
8
9 while (!key[KEY_ESC]) {
10 BITMAP *red;
11 BITMAP *background;
12 BITMAP *grid;
13 BITMAP *buffer;
14
15 background = load_bitmap("images/background.bmp", NULL);
16 red = load_bitmap("images/bubble_red.bmp", NULL);
17 clear_to_color(grid, 0);
18 clear_to_color(buffer, 0);
19
20 draw_sprite(buffer, background, 0, 0);
21
22 if(getpixel(grid, 0, 0)) {
23 draw_sprite(buffer, red, 5, 5);
24 }
25
26 blit(buffer, screen, 0, 0, 0, 0, 320, 400);
27 clear_bitmap(buffer);
28 }
29
30 deinit();
31 return 0;
32}
33END_OF_MAIN()
34 
35void init() {
36 int depth, res;
37 allegro_init();
38 //depth = desktop_color_depth();
39 //if (depth == 0) depth = 32;
40 set_color_depth(24);
41 res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
42 if (res != 0) {
43 allegro_message(allegro_error);
44 exit(-1);
45 }
46
47 install_timer();
48 install_keyboard();
49 install_mouse();
50 /* add other initializations here */
51}
52 
53void deinit() {
54 clear_keybuf();
55 /* add other deinitializations here */
56}

miran
Member #2,407
June 2002

The only way you can make getpixel crash is if you give it an invalid bitmap pointer. Are you sure cluster is an actual valid pointer to a BITMAP? If cluster is a bitmap that you load from disk, then maybe this is the right moment to start checking if load_bitmap() was actually successful or not.

EDIT: In the example above grid is uninitialized.

--
sig used to be here

LennyLen
Member #5,313
December 2004
avatar

Also remove:

  if (res != 0) {
    allegro_message(allegro_error);
    exit(-1);
  }

Since you haven't defined res.

edit: Never mind that. I just missed where you did.

miran
Member #2,407
June 2002

Also you made a huge enourmous gigantic memory leak.

--
sig used to be here

Crystylla
Member #7,921
October 2006

Quote:

The only way you can make getpixel crash is if you give it an invalid bitmap pointer. Are you sure cluster is an actual valid pointer to a BITMAP? If cluster is a bitmap that you load from disk, then maybe this is the right moment to start checking if load_bitmap() was actually successful or not.

Ah... now that I look at it, I think it is the cluster that's causing it to crash. I'll see if I can't fiddle with the cluster to make it work. Huge thanks!

Quote:

Also you made a huge enourmous gigantic memory leak.

By putting everything into the loop? Oops. Sorry about that, I was being rushed to get off the PC for a while.

LennyLen
Member #5,313
December 2004
avatar

Quote:

I was being rushed to get off the PC for a while.

So you decided to put everything in a while {} then? ;)

Dustin Dettmer
Member #3,935
October 2003
avatar

1#include <allegro.h>
2 
3void init();
4void deinit();
5 
6int main() {
7 init();
8 
9 BITMAP *red;
10 BITMAP *background;
11 BITMAP *grid;
12 BITMAP *buffer;
13
14 background = load_bitmap("images/background.bmp", NULL);
15 red = load_bitmap("images/bubble_red.bmp", NULL);
16 grid = create_bitmap(320, 400);
17 buffer = create_bitmap(640, 480);
18 clear_to_color(grid, 0);
19 clear_to_color(buffer, 0);
20 
21 if(!background) {
22 allegro_message("Unable to load \"images/background.bmp\".\n");
23 exit(1);
24 }
25 
26 if(!red) {
27 allegro_message("Unable to load \"images/bubble_red.bmp\".\n");
28 exit(1);
29 }
30
31 while (!key[KEY_ESC]) {
32
33 draw_sprite(buffer, background, 0, 0);
34
35 if(getpixel(grid, 0, 0)) {
36 draw_sprite(buffer, red, 5, 5);
37 }
38
39 blit(buffer, screen, 0, 0, 0, 0, 320, 400);
40 clear_bitmap(buffer);
41 }
42
43 deinit();
44 return 0;
45}
46END_OF_MAIN()
47 
48void init() {
49 int depth, res;
50 allegro_init();
51 //depth = desktop_color_depth();
52 //if (depth == 0) depth = 32;
53 set_color_depth(24);
54 res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
55 if (res != 0) {
56 allegro_message(allegro_error);
57 exit(-1);
58 }
59
60 install_timer();
61 install_keyboard();
62 install_mouse();
63 /* add other initializations here */
64}
65 
66void deinit() {
67 clear_keybuf();
68 /* add other deinitializations here */
69}

Crystylla
Member #7,921
October 2006

Thanks guys, it works beautifully now! ;D

(Yeah, it was the cluster that was breaking it... heh.)

Go to: