/* iterates through the elements in each block and calls apply. Used by * UArray2b_map */ void block_iter(UArray2b_T array2b, int i, int j, void apply(int i, int j, T array2b, void *elem, void *cl), void *cl) { void* elem; int client_x, client_y, col, row, bs = array2b->blocksize; for (row = 0; row < bs; row++) { for (col = 0; col < bs; col++) { client_x = i*bs + col; /* coordinates of client */ client_y = j*bs + row; elem = UArray2b_at(array2b, client_x, client_y); if(client_x < array2b->width && client_y < array2b->height){ apply(client_x, client_y, array2b, elem, cl); } } } }
/* * Should recognize and accomodate partially filled blocks without * segfaulting. * Blocki and Blockj are indices in the outer UArray2 */ extern void mapBlock(T array2b, int width, int height, void *element, void *cl, void apply(int i, int j, T array2b, void *element, void *cl), int blocki, int blockj) { /* Number of full blocks on the width */ int fullBlocksWid = width / (array2b->blocksize); /* Number of full blocks on the height */ int fullBlocksHgt = height / (array2b->blocksize); /* FULL BLOCK */ if(blocki < fullBlocksWid && blockj < fullBlocksHgt) { for(int i = 0; i < array2b->blocksize; i++) { for(int j = 0; j < array2b->blocksize; j++) { /* Coordinates in terms of cells */ int col = i + blocki * (array2b->blocksize); int row = j + blockj * (array2b->blocksize); element = UArray2b_at(array2b, col, row); apply(col, row, array2b, element, cl); } } } /* RIGHT BOTTOM CORNER BLOCK */ else if (blocki == fullBlocksWid && blockj == fullBlocksHgt) { for(int i = 0; i < width % array2b->blocksize; i++) { for(int j = 0; j < height % array2b->blocksize; j++) { int col = i + blocki * (array2b->blocksize); int row = j + blockj * (array2b->blocksize); element = UArray2b_at(array2b, col, row); apply(col, row, array2b, element, cl); } } } /* RIGHT EDGE PARTIALLY FILLED BLOCK */ else if(blocki == fullBlocksWid) { for(int i = 0; i < width % array2b->blocksize; i++) { for(int j = 0; j < array2b->blocksize; j++) { int col = i + blocki * (array2b->blocksize); int row = j + blockj * (array2b->blocksize); element = UArray2b_at(array2b, col, row); apply(col, row, array2b, element, cl); } } } // LEFT EDGE PARTIALLY FILLED BLOCK */ else if(blockj == fullBlocksHgt) { for(int i = 0; i < array2b->blocksize; i++) { for(int j = 0; j < height % array2b->blocksize; j++) { int col = i + blocki * (array2b->blocksize); int row = j + blockj * (array2b->blocksize); element = UArray2b_at(array2b, col, row); apply(col, row, array2b, element, cl); } } } }