Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdbool.h>
- #include <stdlib.h>
- #include <string.h>
- #include "assert.h"
- #include "array.h"
- #include "uarray2b.h"
- #include "mem.h"
- #include "uarray2.h"
- #include "pnm.h"
- #define T Array2b_T
- struct T {
- int width;
- int height;
- int size;
- int blocksize;
- UArray2_T uarray2;
- };
- T UArray2b_new(int width, int height, int size, int blocksize)
- {
- T array2b;
- NEW(array2b);
- array2b->width = width;
- array2b->height = height;
- array2b->size = size;
- array2b->blocksize = blocksize;
- int width_overflow = (width % blocksize) ? 1 : 0;
- int height_overflow = (height % blocksize) ? 1 : 0;
- // printf("\nWidth overflow: %d Height overflow: %d\n", width_overflow, height_overflow);
- // Defining array2b to be a UArray2 with elements of size Array_T
- array2b->uarray2 = UArray2_new(width/blocksize + width_overflow, height/blocksize + height_overflow, sizeof(Array_T));
- // printf("\nShape of uarray2: (%d, %d)\n", width/blocksize + width_overflow, height/blocksize + height_overflow);
- // loop while i < the number of Array_Ts in uarray2
- for(int i = 0; i < UArray2_length(array2b->uarray2); i++)
- {
- //each inner array (block) is of size blocksize*blocksize
- Array_T inner_array = Array_new(blocksize*blocksize, size);
- //define each cell in the inner array to be a pointer to an int
- for(int j = 0; j < Array_length(inner_array); j++)
- {
- void *elemp = Array_get(inner_array, j);
- Pnm_rgb rgb = elemp;
- rgb->red = 0;
- rgb->blue = 0;
- rgb->green = 0;
- //initialize element to be index within blocked array
- // *elemp = j + (i*(blocksize*blocksize));
- }
- Array_T *innerp = UArray2_at_flat(array2b->uarray2, i);
- *innerp = inner_array;
- }
- return array2b;
- }
- T UArray2b_new_64K_block(int width, int height, int size)
- {
- T array2b;
- NEW(array2b);
- // array2b->width = 1368;
- array2b->width = width;
- // array2b->height = 936;
- array2b->height = height;
- array2b->size = size;
- printf("\nImage Height: %d width: %d size: %d", height, width, size);
- //Exactly 65,536 bits in 64KB. 65,536/sizeof(int) = 16384. sqrt(16384) = 128. blocksize = 128
- // Exactly 65,536 bits in 64KB. 65,536/3*sizeof(int) = 5461. sqrt(5461) = 72. blocksize = 72
- array2b->blocksize = 72;
- // array2b->blocksize = 128;
- int blocksize = array2b->blocksize;
- int width_overflow = (width % blocksize) ? 1 : 0;
- int height_overflow = (height % blocksize) ? 1 : 0;
- // printf("\nWidth overflow: %d Height overflow: %d\n", width_overflow, height_overflow);
- // Defining array2b to be a UArray2 with elements of size Array_T
- // array2b->uarray2 = UArray2_new(((height/blocksize) + height_overflow), ((width/blocksize) + width_overflow), sizeof(Array_T));
- array2b->uarray2 = UArray2_new(((width/blocksize) + width_overflow), ((height/blocksize) + height_overflow), sizeof(Array_T));
- printf("\n2D Blocks height: %d Width: %d length: %d\n", UArray2_rows(array2b->uarray2), UArray2_cols(array2b->uarray2), UArray2_length(array2b->uarray2));
- // loop while i < the number of Array_Ts in uarray2
- for(int i = 0; i < UArray2_length(array2b->uarray2); i++)
- {
- //each inner array (block) is of size blocksize*blocksize
- Array_T inner_array = Array_new(blocksize*blocksize, size);
- //define each cell in the inner array to be a pointer to an int
- for(int j = 0; j < Array_length(inner_array); j++)
- {
- void *elemp = Array_get(inner_array, j);
- Pnm_rgb rgb = elemp;
- rgb->red = 0;
- rgb->blue = 0;
- rgb->green = 0;
- // int *elemp = Array_get(inner_array, j);
- //initialize element to be index within blocked array
- // *elemp = 0;
- // *elemp = j + (i*(blocksize*blocksize));
- // printf("\ni: %d j: %d\n", i, j);
- }
- // printf("\ni: %d\n", i);
- Array_T *innerp = UArray2_at_flat(array2b->uarray2, i);
- *innerp = inner_array;
- }
- // UArray2b_print_block(array2b, 0,0);
- // UArray2b_print(array2b);
- printf("\nreached\n");
- return array2b;
- }
- void UArray2b_free(T *array2b)
- {
- FREE(*array2b);
- }
- void *UArray2b_at(T array2b, int i, int j)
- {
- //height = 1001
- //width = 1419
- // int height_overflow = UArray2b_height_overflow(array2b);
- // int width_overflow = UArray2b_width_overflow(array2b);
- //check to see if we are working with the final row of i, the overflow
- //if that is the case subtract the height overflow
- // printf("\nheight overflow: %d width overflow: %d", height_overflow, width_overflow);
- // int width_overflow = UArray2b_width_overflow(array2b);
- int block_index_i = (i / array2b->blocksize);
- int block_index_j = (j / array2b->blocksize);
- // if(block_index_i == UArray2_rows(array2b->uarray2))
- // {
- // // printf("Reached");
- // i -= height_overflow;
- // }
- // printf("\ni: %d j:%d", i, j);
- // printf("\nBlock found at: (%d, %d).\n", block_index_i, block_index_j);
- // printf("\ni: %d j:%d", i, j);
- int element_index = array2b->blocksize * (j % array2b->blocksize) + (i % array2b->blocksize);
- // printf("\nCell within block found at index: %d", element_index);
- // Array_T block = UArray2_get_block(array2b->uarray2, 0, 0);
- Array_T block = UArray2_get_block(array2b->uarray2, block_index_j, block_index_i);
- // Array_T block = UArray2_get_block(array2b->uarray2, block_index_i, block_index_j);
- // Array_T block = UArray2_get_block(array2b->uarray2, block_index_i, block_index_j);
- // printf("\ni: %d j:%d element_index %d", i, j, element_index);
- // void *elemp = Array_get(block, 0);
- void *elemp = Array_get(block, element_index);
- // Pnm_rgb rgb = Array_get(block, element_index);
- // printf("\n%d %d %d", rgb->red, rgb->green, rgb->blue);
- return elemp;
- }
- void UArray2b_print(T array2b)
- {
- printf("\n");
- for(int i = 0; i < array2b->height; i++)
- {
- //Print the column indices
- if(i == 0)
- {
- for(int k = 0; k < array2b->width; k++)
- {
- if(k == 0) printf(" ");
- if(k % array2b->blocksize == 0 && k != 0) printf(" %d ", k);
- else printf("%d ", k);
- }
- }
- //separate blocks by a new lines
- if (i % array2b->blocksize == 0)
- {
- printf("\n\n%d| ", i);
- }
- //print the current row index
- if (i != 0 && i % array2b->blocksize != 0)
- {
- printf("\n%d| ", i);
- }
- //print each of the blocks and their cells
- for(int j = 0 ; j < array2b->width; j++)
- {
- //get the current cell
- void *cell = UArray2b_at(array2b, i, j);
- //print whitespace to seperate blocks
- if(j % array2b->blocksize == 0 && j > 0)
- {
- printf(" %d ", *(int*)cell);
- }
- else
- {
- //account for single digit cell index spacing
- if(*(int*)cell < 10) printf(" %d ", *(int*)cell);
- else if(*(int*)cell < 100) printf(" %d ", *(int*)cell);
- else printf(" %d ", *(int*)cell);
- }
- }
- }
- printf("\n");
- }
- void UArray2b_print_block(T array2b, int i, int j)
- {
- // int initial_index;
- printf("\nDisplaying block found at (%d, %d):\n\n", i, j);
- Array_T block = UArray2_get_block(array2b->uarray2, i, j);
- for(int i = 0; i < Array_length(block); i++)
- {
- void *cell = Array_get(block, i);
- if(i % array2b->blocksize == 0 && i > 0)
- {
- printf("\n%d ", *(int*)cell);
- }
- else
- {
- printf("%d ", *(int*)cell);
- }
- }
- printf("\n");
- }
- void UArray2b_modify_block(T array2b, int i, int j, int val)
- {
- printf("\nChanging all values of the block found at (%d, %d) to %d:\n", i, j, val);
- Array_T block = UArray2_get_block(array2b->uarray2, i, j);
- for(int i = 0; i < Array_length(block); i++)
- {
- void *cell = Array_get(block, i);
- *(int*)cell = val;
- }
- }
- int UArray2b_width(T array2b)
- {
- return array2b->width;
- }
- int UArray2b_height(T array2b)
- {
- return array2b->height;
- }
- int UArray2b_size (T array2b)
- {
- return array2b->size;
- }
- int UArray2b_blocksize(T array2b)
- {
- return array2b->blocksize;
- }
- int UArray2b_length(T array2b)
- {
- int width_overflow = (array2b->width % array2b->blocksize) ? 1 : 0;
- int height_overflow = (array2b->height % array2b->blocksize) ? 1 : 0;
- return (array2b->width/array2b->blocksize + width_overflow) * (array2b->height/array2b->blocksize + height_overflow);
- }
- int UArray2b_width_overflow(T array2b)
- {
- return array2b->width % array2b->blocksize;
- }
- int UArray2b_height_overflow(T array2b)
- {
- return array2b->height % array2b->blocksize;
- }
- void UArray2b_map(T array2b, void (*apply)(int, int, T, void *, void *), void *cl)
- {
- // printf("\nReached mapping\n");
- //defining closure to be the Array2b_T being mapped over
- Array2b_T *original = cl;
- int height_overflow = UArray2b_height_overflow(array2b);
- int width_overflow = UArray2b_width_overflow(array2b);
- // printf("\nWidth overflow: %d Height overflow: %d\n", width_overflow, height_overflow);
- //initialization of variables used in mapping
- int row_num = 0;
- int blocksize = array2b->blocksize;
- int uarray2_rows = UArray2_rows(array2b->uarray2);
- int uarray2_cols = UArray2_cols(array2b->uarray2);
- //Loop through each of the blocks
- for(int k = 0; k < UArray2b_length(*original); k++)
- {
- // printf("\nk = %d\n", k);
- //variables storing intial row,col of block
- int initial_i, initial_j;
- //variables storing final row, col of block
- int final_i, final_j;
- //i is always 0 while we are mapping over the first row of blocks
- if(k < uarray2_rows) initial_i = 0;
- else
- {
- //if there is no remainder, we are in first column
- if(!(k % uarray2_rows)) row_num += 1;
- //initial row index of blocks is found at row_num*blocksize
- initial_i = row_num*blocksize;
- }
- //if there is no remainder we are mapping over first column of blocks
- if(k % uarray2_cols == 0) initial_j = 0;
- //if there is a remainder, intial col index found at remainder*blocksize
- else initial_j = (k % uarray2_cols)*blocksize;
- //if we are working within the last row of blocks, final_i = number of rows in final block = height_overflow
- if(height_overflow && (initial_i + height_overflow == array2b->height)) final_i = height_overflow;
- //if there is no height overflow, or there is but we are not yet in the final row of blocks, final_i = blocksize
- else final_i = blocksize;
- //if we are working within the last col of blocks, final_j = number of cols in final block = width_overflow
- if(width_overflow && ((k + 1) % uarray2_cols == 0)) final_j = width_overflow;
- //if there is no width overflow, or there is but we are not yet in the final column of blocks, final_j = blocksize
- else final_j = blocksize;
- //loop through each row of block
- for(int i = initial_i; i < initial_i+final_i; i++)
- {
- //loop through each col of block
- for(int j = initial_j; j < initial_j+final_j; j++)
- {
- //retrieve cell from Array2b_T we are modifying and call apply
- void *cell = UArray2b_at(*original, i, j);
- (*apply)(i, j, array2b, cell, cl);
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement