Software Blitting Part 3

If we have a typical PNG of size, say, 100×100, then we can easily refer to a specific pixel as 44, 02, if we want the forty fourth pixel from the right, on the second line. Unfortunately it’s not quite that simple, since the raw pixel data is linear, so pixel 44,02, is actually just pixel #244. A visual representation might make this easier.

Imagine a very simple image consisting of four pixels:

fourPixels

Of course, I have added the black lines.

The way this image is stored in memory is like this:

greenPixel redPixel yellowPixel pinkPixel

So if we want to access the pink pixel, we can’t simply go for the pixel at 2, 2, we need to specify the #4 pixel. All this seems quite simple, but it makes blitting one image to another a bit harder.

Blitting is simply the act of putting the data from one image into another. Just think paper mache’ing one image over another, although we can’t simply take off the new image, since we’ve permanently changed the underlying one. Since a picture is worth a thousand words:

newImage +furtherTest = pixelBlit

Credit for the comic to poorlydrawnlines.com

Since the data is linear I needed to create an algorithm to allow me to blit while keeping my sanity, and it’s so simple once created:


///Boy I hate how WordPress destroys formatting

//blit one image onto another.
void ApplyImage(Image* pI1, Image* pI2, int startX, int startY){
int startLoc=pI1->wd*startY+startX;

int im1pxl, im2pxl;
for(int line=0; line<pI2->ht; line++){
for(int i=0; i<pI2->wd; i++){
im1pxl=pI1->wd*line+i+startLoc;
im2pxl=pI2->wd*line;

pI1->pImg[im1pxl]=pI2->pImg[im2pxl];
}
}
}

Experienced programmers will recognize this as a somewhat dangerous algorithm, since it doesn’t check for being out of bounds, but I just wanted to demonstrate it now.

Anyway, once we’ve blitted our images together, however many we would like, we have to write it to disk. stb_image_write, again written by Sean Barnett, makes this quite an easy task. I had to make this a touch uglier, since I needed to change the formatting back to raw data (from Pixels), but even still:


void WriteImage(Image img, std::string name){
int size=img.ht*img.wd*img.bpp;
unsigned char* pRaw=new unsigned char[size]();
for(int i=0; i<size; i+=img.bpp){
pRaw[i]=img.pImg[i/img.bpp].r;
pRaw[i+1]=img.pImg[i/img.bpp].g;
pRaw[i+2]=img.pImg[i/img.bpp].b;
}
stbi_write_png(name.c_str(), img.wd, img.ht, img.bpp, pRaw, 0);
delete pRaw;
}

…is incredibly clean compared to libPNG.

Anyway, the original point of all this was to use it in my chess board program. Continued in part 4…

This entry was posted in Programming, Uncategorized and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s