views:

96

answers:

2

Hi all,

I'm just wondering how I would go about splitting a pixel array (R,G,B,A,R,G,B,A,R,G,B,A,etc.) into 64x64 chunks. I've tried several methods myself but they all seem really over-complex and a bit too messy.

I have the following variables (obviously filled with information):

int nWidth, nHeight;
unsigned char *pImage;

And basically for each chunk I want to call:

void ProcessChunk(int x, int y, int width, int height)

You may be wondering why there is a width and height argument for the processing function, but if the image is not exactly divisible by 64, then there will be smaller chunks at the edge of the image (right-hand side and the bottom). See this image for a better understanding what I mean (red chunks are the chunks that will have <64 width or height arguments).

Chunk diagram

Thanks in advance.

+2  A: 

I will assume that the chunks are unsigned char *chunk[64*64*4], in a similar way to the image itself.

int chunkOffset = 0;
int bufferOffset = y*nWidth*4 + x*4;
memset(chunk, 0, 64*64*4*sizeof(unsigned char));
for (int line = 0; line < height; line++)
{
    memcpy(chunk+chunkOffset, buffer+bufferOffset, width*4*sizeof(unsigned char));
    chunkOffset += 64*4;
    bufferOffset += nWidth*4;
}

In a real code I would replace the "4"s with sizeof(PIXEL) and the "64"s with CHUNK_WIDTH & CHUNK_HEIGHT, but you get the idea. I would also check width & height for accuracy, and basically you don't really need them (you can easily calculate them inside the function).

Also note that while the "sizeof(unsigned char)" isn't really needed, I like putting it there for clarification. It doesn't effect the runtime since it's evaluated in compilation time.

Eldad Mor
It looks to me like this doesn't handle the fractional chunks, since you are copying a loop-invariant number of bytes on each row.
RBerteig
Why? I'm copying 4width bytes.
Eldad Mor
You've confounded the request to break the image up into chunks with the signature of the function to call. You show the copy of a single chunk's pixels, but don't calculate `width` or take into account the chunks at the end of the line or the bottom of the image.
RBerteig
+1  A: 

Just define a MIN() macro to determine the minimum of two expressions, and then it's easy:

void ProcessChunk(unsigned char *pImage, int x, int y, int width, int height);

#define MIN(a, b) ((a) < (b) ? (a) : (b))    
#define CHUNKSIZE 64

void ProcessImage(unsigned char *pImage, int nWidth, int nHeight)
{
    int x, y;

    for (x = 0; x < nWidth; x += CHUNKSIZE)
        for (y = 0; y < nHeight; y += CHUNKSIZE)
            ProcessChunk(pImage, x, y, MIN(nWidth - x, CHUNKSIZE), MIN(nHeight - y, CHUNKSIZE));
}
caf
Thanks that's exactly what I wanted, however how do I convert my x and y into pixel indices? Would this work: pPixel =
Saul Rennison
@Saul Rennison: Within `ProcessChunk`, the pixel would be addressed as `pImage[(y * width + x) * PIXEL_BYTES]`
caf