# Dividing a image into 4 blocks

This topic is 3758 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I want to divide an image into for blocks and each block will be height/2 and width/2. I can do this using for loop but it's taking two much time to process for large images. Please suggest me any best and efficient way to do this. Thanks, Soumyadipta De

##### Share on other sites
You have the image in main memory, right?

Then use 4 for-loops, one for each block. Iterate through the lines and copy one line at a time into the new buffer.

##### Share on other sites
////////////////////////////////// PREPARE IMAGE BLOCKS //////////////////////////////		int srcIndex1 =	0; 		int srcIndex2 = 0;		int srcIndex3 =	0; 		int srcIndex4 = 0;		int dstIndex =	0;		for(int i=0; i<POT_height; i++)		{			if( i < POT_height/2)			{				for(int j=0; j<POT_width; j++)				{					if( j < POT_width/2)					{						dib_POT_block1[srcIndex1 + 0]	= POT_data[dstIndex + 0];						dib_POT_block1[srcIndex1 + 1]	= POT_data[dstIndex + 1];						dib_POT_block1[srcIndex1 + 2]	= POT_data[dstIndex + 2];						dib_POT_block1[srcIndex1 + 3]	= POT_data[dstIndex + 3];							srcIndex1 += 4;					}					else					{						dib_POT_block2[srcIndex2 + 0]	= POT_data[dstIndex + 0];						dib_POT_block2[srcIndex2 + 1]	= POT_data[dstIndex + 1];						dib_POT_block2[srcIndex2 + 2]	= POT_data[dstIndex + 2];						dib_POT_block2[srcIndex2 + 3]	= POT_data[dstIndex + 3];						srcIndex2 += 4;					}										dstIndex += 4;				}			}			else			{								for(int j=0; j<POT_width; j++)				{					if( j < POT_width/2)					{						dib_POT_block3[srcIndex3 + 0]	= POT_data[dstIndex + 0];						dib_POT_block3[srcIndex3 + 1]	= POT_data[dstIndex + 1];						dib_POT_block3[srcIndex3 + 2]	= POT_data[dstIndex + 2];						dib_POT_block3[srcIndex3 + 3]	= POT_data[dstIndex + 3];						srcIndex3 += 4;					}					else					{						dib_POT_block4[srcIndex4 + 0]	= POT_data[dstIndex + 0];						dib_POT_block4[srcIndex4 + 1]	= POT_data[dstIndex + 1];						dib_POT_block4[srcIndex4 + 2]	= POT_data[dstIndex + 2];						dib_POT_block4[srcIndex4 + 3]	= POT_data[dstIndex + 3];						srcIndex4 += 4;					}					dstIndex += 4;				}			}		}

##### Share on other sites
Is it possible to enhance the above for loop?

##### Share on other sites
You could use the following approach:
for(int i = 0; i < height/2; i++){  memcpy(destimage0 + width/2 * sizeof(pixel) * i, srcimage + i * width, width/2 * sizeof(pixel));  memcpy(destimage1 + width/2 * sizeof(pixel) * i, srcimage + i * width + width/2, width/2 * sizeof(pixel));  memcpy(destimage2 + width/2 * sizeof(pixel) * i, srcimage + (i + height/2) * width, width/2 * sizeof(pixel));  memcpy(destimage3 + width/2 * sizeof(pixel) * i, srcimage + (i + height/2) * width + width/2, width/2 * sizeof(pixel));}

You could precompute width/2 and height/2 as well as width/2 * sizeof(pixel) in order to reduce calculations.

##### Share on other sites
Thanks for your help but the above loop is very confusing. It will be really helpful if you please explain the logic?

Can you please explain the loop? i not getting the point why you are incrementing the source and destination buffer pointer while doing memcpy.

destimage0 + width/2 * sizeof(pixel) * i

and

srcimage + i * width, width/2 * sizeof(pixel)

Regards,

##### Share on other sites
The code takes the top and middle horizontal lines and, since each line contains the data for two of the subimages, breaks each line into two groups. It copies each of the four groups into their respective subimage. The next iteration of the loop then does the same thing, but for the second-from-the-bottom and second-from-the-middle lines. This continues until the bottom line approaches the middle point of the image (and thus the middle line approaches the top of the image). If the pointers were not incremented, then the same partial image data would be copied into the same locations for height/2 times and you'd be left with four subimages that only contain one line of image data.

It looks like this code will throw away one line of the original image's data if the image's height is odd. You can solve it, but how does one go about doing that? Is throwing the data away perfectly OK? How do you decide which images get to be larger and which get to be smaller? These are implementation details that you will have to decide. Also keep in mind that you can take Lord_Evil's code and break it up into two for loops (one for the top subimages and one for the bottom). Although you'll face some slight additional overhead for managing two loops, you'll cut down on the complexity of the problem (possibly making it easier to read) and also get rid of some arithmetic overhead.

Using memcpy is much faster for copying large blocks of data at once rather than assigning the data one variable at a time.

##### Share on other sites
Thank you for your explanation, CrimsonSun. ;)

Just to make it easier to understand, a short and very simple example:

Your source image could look like this:12 13 14 15 8  9 10 11 4  5  6  7 0  1  2  3And you want those 4 subimages: 4  5   6  7   12 13   14 15 0  1 , 2  3 ,  8  9 , 10 11Now we have width/2 = 2 and height/2 = 2. sizeof(pixel) will be 1 byte in this case so width/2 * sizeof(pixel) = 1.Now the first iteration (i = 0) evolves to:memcpy(destimage0 + 0, srcimage + 0, 2); //copies the pixels 0 and 1 to destimage0memcpy(destimage1 + 0, srcimage + 2, 2); //copies the pixels 2 and 3 to destimage1memcpy(destimage2 + 0, srcimage + 8, 2); //copies the pixels 8 and 9 to destimage2memcpy(destimage3 + 0, srcimage + 10, 2); //copies the pixels 10 and 11 to destimage3Then the pointers are advanced by 2 bytes in the destination images as well as 4 bytes (one line) in the source image.The next iteration (i = 1) evolves to:memcpy(destimage0 + 2, srcimage + 4, 2); //copies the pixels 4 and 5 to destimage0memcpy(destimage1 + 2, srcimage + 6, 2); //copies the pixels 6 and 7 to destimage1memcpy(destimage2 + 2, srcimage + 12, 2); //copies the pixels 12 and 13 to destimage2memcpy(destimage3 + 2, srcimage + 14, 2); //copies the pixels 14 and 15 to destimage3After that, your destination images are laid out in memory like this:destimage0 = 0, 1, 4, 5destimage1 = 2, 3, 6, 7destimage3 = 8, 9, 12, 13destimage4 = 10, 11, 14, 15

Hope that makes it a bit clearer.

##### Share on other sites
Thanks a lot for your help. Now the loop is completely clear to me.

Many many thanks to all.

##### Share on other sites
We have not considered the BPP (3 or 4) in the above for loop and so the generated index are wrong and you will not get proper image.

//////////////////// BELOW IS THE CORRECT FOR LOOP ////////////////////////////

for(int i=0; i<POT_height/2; i++){        int srcIndex = POT_width/2 * bpp *i;	int size = POT_width/2 * bpp;	int size2 = POT_width * bpp;						//Bottom Left	memcpy(dib_POT_block1 + srcIndex, POT_data + i * size2, size);	//Bottom Right	memcpy(dib_POT_block2 + srcIndex, POT_data + i * size2 + size, size);	//Top Left	memcpy(dib_POT_block3 + srcIndex, POT_data + (i + POT_height/2) * size2, size);	//Top Right	memcpy(dib_POT_block4 + srcIndex, POT_data + (i + POT_height/2) * size2 + size, size);}

1. 1
2. 2
3. 3
4. 4
Rutin
13
5. 5

• 12
• 16
• 9
• 14
• 10
• ### Forum Statistics

• Total Topics
632657
• Total Posts
3007680
• ### Who's Online (See full list)

There are no registered users currently online

×