/*-----------------------------------------------------------------------------* | Bit2_get | Purpose: Finds the element stored at the given location of the | specified Bit2 | Arguments: a pointer to the 2D bit array, the matrix location as a pair | of ints | Returns: the value stored at the given matrix location of the 2D bit | array as an int | Fail cases: | - the pointer to the 2D bit array is null | - the given matrix location lies outside the bounds of the 2D | bit array *-----------------------------------------------------------------------------*/ int Bit2_get(Bit2_T bit2, int i, int j) { assert(bit2 != NULL); assert((i >= 0 && i < Bit2_width(bit2)) && (j >= 0 && j < Bit2_height(bit2))); int index = get_index(i, j, Bit2_height(bit2)); return Bit_get(bit2->bitmap, index); }
/*-----------------------------------------------------------------------------* | Bit2_put | Purpose: Inserts the given value into the given Bit2 at the specified | matrix location | Arguments: a pointer to the 2D array, the matrix location as a pair of | ints, the value to be inserted as an int | Returns: returns the value previously stored at the given location as | an int | Fail cases: | - the pointer to the 2D bit array is null | - the given matrix location lies outside the bounds of the 2D | bit array | - the value to be inserted is not 0 or 1 *-----------------------------------------------------------------------------*/ int Bit2_put(Bit2_T bit2, int i, int j, int value) { assert(bit2 != NULL); assert((i >= 0 && i < Bit2_width(bit2)) && (j >= 0 && j < Bit2_height(bit2))); assert(value == 0 || value == 1); int index = get_index(i, j, Bit2_height(bit2)); return (Bit_put(bit2->bitmap, index, value)); }
/*-----------------------------------------------------------------------------* | Bit2_map_row_major | Purpose: maps the given function onto every element of the given Bit2 | in row major order | Arguments: a pointer to the 2D bit array, a pointer to a void apply | function, the closure as a void * | Returns: - | Fail cases: | - the pointer to the 2D bit array is null | - the pointer to the apply function is null *-----------------------------------------------------------------------------*/ void Bit2_map_row_major(Bit2_T bit2, void apply(int i, int j, Bit2_T bit2, int value, void *cl), void *cl){ assert(bit2 != NULL); assert(apply != NULL); int i; int j; for (j = 0; j < Bit2_height(bit2); j++) { for (i = 0; i < Bit2_width(bit2); i++) { apply(i, j, bit2, Bit2_get(bit2, i, j), cl); }; }; }
void unblack (Bit2_T bitmap, int cur_x, int cur_y) { int w_pixels = Bit2_width (bitmap); int h_pixels = Bit2_height (bitmap); Seq_T point_queue = Seq_new(w_pixels*h_pixels); assert(point_queue); assert(0 <= cur_x && cur_x < w_pixels); assert(0 <= cur_y && cur_y < h_pixels); if (Bit2_get(bitmap, cur_x, cur_y) != 1) { // if pixel is white assert(point_queue); Seq_free(&point_queue); return; } else { Seq_addhi(point_queue, (void*)makePoint(cur_x,cur_y)); while (Seq_length(point_queue) > 0) { PointPair temp = (PointPair)Seq_remlo(point_queue); assert(temp); int i = temp->i; int j = temp->j; freePoint(temp); if (Bit2_get(bitmap, i, j) == 1) { // if current is black pixel Bit2_put(bitmap, i, j, 0); // set current to white assert(0 <= i && i < w_pixels); assert(0 <= j && j < h_pixels); if (j != 0 && j != h_pixels-1) { // if not a top/bottom pixel if (i+1 < w_pixels && Bit2_get(bitmap, i+1, j) == 1) { // if Seq_addhi(point_queue, (void*)makePoint(i+1,j)); } if (i > 0 && Bit2_get(bitmap, i-1, j) == 1) { Seq_addhi(point_queue, (void*)makePoint(i-1,j)); } } if (i != 0 && i != w_pixels-1) { if (j+1 < h_pixels && Bit2_get(bitmap, i, j+1) == 1) { Seq_addhi(point_queue, (void*)makePoint(i,j+1)); } if (j > 0 && Bit2_get(bitmap, i, j-1) == 1) { Seq_addhi(point_queue, (void*)makePoint(i,j-1)); } } } } assert(point_queue); Seq_free(&point_queue); return; } }
void pbmwrite (Bit2_T bitmap) { int w_pixels = Bit2_width(bitmap); int h_pixels = Bit2_height(bitmap); printf("P1\n" "#\n" "%d %d", w_pixels, h_pixels); for (int j = 0; j < h_pixels; j++) { for (int i = 0; i < w_pixels; i++) { if ((i % 70) == 0) { printf("\n"); printf("%d", Bit2_get(bitmap, i, j)); } else { printf("%d", Bit2_get(bitmap, i, j)); } } } printf("\n"); return; }
int main (int argc, char *argv[] ) { assert(argc<=2); FILE *input; if (argc == 2) { input = fopen( argv[1], "rb"); if (!input) { perror(argv[1]); exit(1); } } else { input = stdin; } Bit2_T bitmap = pbmread(input); assert(bitmap); if (input != stdin) { fclose(input); } int w_pixels = Bit2_width(bitmap); int h_pixels = Bit2_height(bitmap); // call unblack on every edge pixel for (int i = 0; i < w_pixels; i++) { // top + bottom edge, +4 corners unblack(bitmap, i, 0); unblack(bitmap, i, h_pixels-1); } for (int j = 0; j < h_pixels; j++) { // left + right edge, no corners unblack(bitmap, 0, j); unblack(bitmap, w_pixels-1, j); } pbmwrite(bitmap); assert(bitmap); Bit2_free(&bitmap); return 0; }
int main(int argc, char *argv[]) { (void)argc; (void)argv; Bit2_T test_array; bool OK = true; int x; test_array = Bit2_new(DIM1, DIM2); OK &= (Bit2_width(test_array) == DIM1); OK &= (Bit2_height(test_array) == DIM2); // Bit2_put(test_array, 0, 0, 1); // printf("(0, 0) = %d\n", Bit2_get(test_array, 0, 0)); // printf("(0, 1) = %d\n", Bit2_get(test_array, 1, 0)); /* Note: we are only setting a value on the corner of the array */ Bit2_put(test_array, DIM1-1, DIM2-1, MARKER); OK &= (Bit2_get(test_array, DIM1-1, DIM2-1) == MARKER); x = Bit2_put(test_array, DIM1-1, DIM2-1, 0); OK &= (x == MARKER); /* hint: put returns previous value */ Bit2_put(test_array, DIM1-1, DIM2-1, MARKER); /* for map test */ printf("Trying column major\n"); Bit2_map_col_major(test_array, check_and_print, &OK); printf("Trying row major\n"); Bit2_map_row_major(test_array, check_and_print, &OK); Bit2_free(&test_array); printf("The array is %sOK!\n", (OK ? "" : "NOT ")); }