Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Load raw pixel data into Allegro Bitmap

This thread is locked; no one can reply to it. rss feed Print
Load raw pixel data into Allegro Bitmap
The Master
Member #4,498
April 2004
avatar

Hey guys,
I'm trying to load pixel data from a TileStudio map into a Bitmap. Basically my code locks a square on the tileset bitmap and then freads it into the locked area.

  bytesPerTile = 4 * m_iTileHeight * m_iTileWidth;
  // now load the tiles
  for ( byCount = 0; byCount < m_iTileCount; byCount++ ) {

    // calculate the location on the grid of the current tile
    x  = ( byCount % m_byTilesPerRow ) *  m_iTileWidth;
    y = ( byCount / m_byTilesPerRow ) * m_iTileHeight;

    // now load the tile into the bitmap
    tileRegion = al_lock_bitmap_region( m_pTileBitmap, x, y, m_iTileWidth, m_iTileHeight, ALLEGRO_PIXEL_FORMAT_ARGB_8888, ALLEGRO_LOCK_WRITEONLY );
    al_fread( pFile, tileRegion->data, bytesPerTile );
    al_unlock_bitmap( m_pTileBitmap );

  }

However its showing up blue and distorted. Any reason why?

We can only do what we feel is right each moment as we live it.

weapon_S
Member #7,859
October 2006
avatar

The pixel format has to be exactly the same between the file on disk and the ALLEGRO_BITMAP in (video)memory. Bitmaps usually have a header (data that is not pixels). ALLEGRO_BITMAPs can have 'padding' between lines IIRC[1]. I.e. you need skip some bytes when writing to it. There was an example, but I can't remember where...
If it's only for loading purposes al_put_pixel can also be used on locked bitmaps, and it takes care of the 'stride' issue.
BTW I think a nested loop would look cleaner.

Johan Halmén
Member #1,550
September 2001

Quick guess

Blue: You're only writing to the blue channel. Like loading single bytes from an 8 bit image and putting them into a 24 bit bitmap.

Distorted: A square (or any rectangular) area of a bitmap is not consecutive memory.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Years of thorough research have revealed that the red "x" that closes a window, really isn't red, but white on red background.

Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest.

The Master
Member #4,498
April 2004
avatar

ok, sounds good. I did use al_put_pixel at first, but I found it took up to a minute to load a 45-tile set with tile size 32x32. So I wanted something that ran faster.
I'll have a shot at using stride. Hopefully it'll work better.

-- EDIT --
Must say, not really digging the pitch approach. Just how much padding do the bitmaps have, anyway? Here's my new approach:

    // now load the tile into the bitmap
    tileRegion = al_lock_bitmap_region( m_pTileBitmap, x, y, m_iTileWidth, m_iTileHeight, ALLEGRO_PIXEL_FORMAT_ARGB_8888, ALLEGRO_LOCK_WRITEONLY );
    for( j=0; j < m_iTileHeight; j++ ) {
    
      p = (size_t*)tileRegion->data + j * tileRegion->pitch;
      al_fread( pFile, p, m_iTileWidth*4 );

    }
    al_unlock_bitmap( m_pTileBitmap );

We can only do what we feel is right each moment as we live it.

weapon_S
Member #7,859
October 2006
avatar

Must say, not really digging the pitch approach.

Do you have a choice? :P

Quote:

Just how much padding do the bitmaps have, anyway?

In any case the ones in memory will have more than the ones on disk >_> Unless, maybe if you use a non-video memory bitmap.

Matthew Leverton
Supreme Loser
January 1999
avatar

The pitch is in bytes, so I think you are advancing 4 or 8 times too far (depending if you are 32-bit or 64-bit). Try:

p = (char*)tileRegion->data + j * tileRegion->pitch;

The Master
Member #4,498
April 2004
avatar

weapon_S said:

Do you have a choice? :P

What I meant to say is, I've tried the pitch approach, and it segfaulted.
I'll have a shot using what Leverton suggested.

-EDIT-
Ok, that worked. However, the colour's all confused. The greens are greens, but the browns are blues, and the blues are yellow. I'm still iffie on how colour conversion works.

We can only do what we feel is right each moment as we live it.

weapon_S
Member #7,859
October 2006
avatar

Try other pixel formats[1]? There are differences in which order each color component is stored. (Apparently it is 32-bit and there is no header, when your image isn't distorted.)
You don't have any colour conversions; You're loading raw data.

The Master
Member #4,498
April 2004
avatar

I got it working. Just the endian-ness issue. Anyway, now comes to the drawing part.
What I've got now is a proper, non-colour-confused rendering of the map. However, when it renders tiles that have a portion transparent (like part of a pillar or something), it draws semi-transparent mask colour (as in [255,0,255]) where it should be drawing nothing. This didn't happen before when I just used put_pixel, and al_convert_mask_to_alpha doesn't seem to do anything. The bitmap format is ARGB 32bit.

-EDIT-
Got it working. But it's a bit of an ugly hack with TileStudio. I had to fix the export so that instead of outputting the proper alpha channel from the tile, TileStudio just outputs 255. This will make it hard if/when i want to do transparency in tiles rather than just masks.

We can only do what we feel is right each moment as we live it.

weapon_S
Member #7,859
October 2006
avatar

Go to: