Content-Aware-Image-Resizer / src / Matrix.cpp
Matrix.cpp
Raw

#include <cassert>
#include "Matrix.h"

// REQUIRES: mat points to a Matrix
//           0 < width && width <= MAX_MATRIX_WIDTH
//           0 < height && height <= MAX_MATRIX_HEIGHT
// MODIFIES: *mat
// EFFECTS:  Initializes *mat as a Matrix with the given width and height.
// NOTE:     Do NOT use new or delete here.
void Matrix_init(Matrix* mat, int width, int height) {
    assert(0 < width && width <= MAX_MATRIX_WIDTH);
    assert(0 < height && height <= MAX_MATRIX_HEIGHT);
    
    mat->width = width;
    mat->height = height;
    mat->data[width * height] = {};
}

// REQUIRES: mat points to a valid Matrix
// MODIFIES: os
// EFFECTS:  First, prints the width and height for the Matrix to os:
//             WIDTH [space] HEIGHT [newline]
//           Then prints the rows of the Matrix to os with one row per line.
//           Each element is followed by a space and each row is followed
//           by a newline. This means there will be an "extra" space at
//           the end of each line.
void Matrix_print(const Matrix* mat, std::ostream& os) {
    os << Matrix_width(mat) << " " << Matrix_height(mat) << std::endl;
    for (int r = 0; r < Matrix_height(mat); r++) {
        for (int c = 0; c < Matrix_width(mat); c++)    {
            os << *Matrix_at(mat, r, c) << " ";
        }
        os << std::endl;
    }
    
//    for (int i = 0; i < (mat->width * mat->height); ++i) {
//        os << mat->data[i] << " ";
//        if ((i + 1) % mat->width == 0)  {
//            os << std::endl;
//        }
//    }
}

// REQUIRES: mat points to an valid Matrix
// EFFECTS:  Returns the width of the Matrix.
int Matrix_width(const Matrix* mat) {
    return mat->width;
}

// REQUIRES: mat points to a valid Matrix
// EFFECTS:  Returns the height of the Matrix.
int Matrix_height(const Matrix* mat) {
    return mat->height;
}

// REQUIRES: mat points to a valid Matrix
//           ptr points to an element in the Matrix
// EFFECTS:  Returns the row of the element pointed to by ptr.
int Matrix_row(const Matrix* mat, const int* ptr) {
    for (int r = 0; r < Matrix_height(mat); r++)    {
        for (int c = 0; c < Matrix_width(mat); c++)  {
            if (ptr == Matrix_at(mat, r, c))    {
                return r;
            }
        }
    }
//    for (int i = 0; i < (mat->width * mat->height); ++i) {
//        if (&(mat->data[i]) == ptr)  {
//            return i / mat->width;
//        }
//    }
//    return 0;
    return 0;
}

// REQUIRES: mat points to a valid Matrix
//           ptr point to an element in the Matrix
// EFFECTS:  Returns the column of the element pointed to by ptr.
int Matrix_column(const Matrix* mat, const int* ptr) {
    for (int r = 0; r < Matrix_height(mat); r++)    {
        for (int c = 0; c < Matrix_width(mat); c++)  {
            if (ptr == Matrix_at(mat, r, c))    {
                return c;
            }
        }
    }
//    for (int i = 0; i < (mat->width * mat->height); ++i) {
//        if (&(mat->data[i]) == ptr)  {
//            return i % mat->width;
//        }
//    }
//    return 0;
    return 0;
}

// REQUIRES: mat points to a valid Matrix
//           0 <= row && row < Matrix_height(mat)
//           0 <= column && column < Matrix_width(mat)
//
// MODIFIES: (The returned pointer may be used to modify an
//            element in the Matrix.)
// EFFECTS:  Returns a pointer to the element in the Matrix
//           at the given row and column.
int* Matrix_at(Matrix* mat, int row, int column) {
    assert(0 <= row && row < Matrix_height(mat));
    assert(0 <= column && column < Matrix_width(mat));
    
    int index = row * mat->width + column;
    int* ptr = &(mat->data[index]);
    return ptr;
}

// REQUIRES: mat points to a valid Matrix
//           0 <= row && row < Matrix_height(mat)
//           0 <= column && column < Matrix_width(mat)
//
// EFFECTS:  Returns a pointer-to-const to the element in
//           the Matrix at the given row and column.
const int* Matrix_at(const Matrix* mat, int row, int column) {
    assert(0 <= row && row < Matrix_height(mat));
    assert(0 <= column && column < Matrix_width(mat));
    
    int index = row * mat->width + column;
    const int* ptr = &(mat->data[index]);
    return ptr;
}

// REQUIRES: mat points to a valid Matrix
// MODIFIES: *mat
// EFFECTS:  Sets each element of the Matrix to the given value.
void Matrix_fill(Matrix* mat, int value) {
    for (int r = 0; r < Matrix_height(mat); r++) {
        for (int c = 0; c < Matrix_width(mat); c++) {
            *Matrix_at(mat, r, c) = value;
        }
    }
//    for (int i = 0; i < (mat->width * mat->height); ++i) {
//        mat->data[i] = value;
//    }
}

// REQUIRES: mat points to a valid Matrix
// MODIFIES: *mat
// EFFECTS:  Sets each element on the border of the Matrix to
//           the given value. These are all elements in the first/last
//           row or the first/last column.
void Matrix_fill_border(Matrix* mat, int value) {
    for (int r = 0; r < Matrix_height(mat); r++) {
        for (int c = 0; c < Matrix_width(mat); c++) {
            if (r == 0 || r == (Matrix_height(mat) - 1) 
                || c == 0 || c == (Matrix_width(mat) - 1))   {
                *Matrix_at(mat, r, c) = value;
            }
        }
    }
//    for (int i = 0; i < (mat->width * mat->height); ++i) {
//        if (i < mat->width || i > ((mat->height - 1) * mat->width) - 1) {
//            mat->data[i] = value;
//        }
//        if (i % mat->width == 0 || (i + 1) % mat->width == 0)   {
//            mat->data[i] = value;
//        }
//    }
}

// REQUIRES: mat points to a valid Matrix
// EFFECTS:  Returns the value of the maximum element in the Matrix
int Matrix_max(const Matrix* mat) {
    
    int max = *Matrix_at(mat, 0, 0);
    
    for (int r = 0; r < Matrix_height(mat); r++) {
        for (int c = 0; c < Matrix_width(mat); c++)    {
            if (*Matrix_at(mat, r, c) > max) {
                max = *Matrix_at(mat, r, c);
            }
        }
    }
    return max;
//    int max = mat->data[0];
//    for (int i = 0; i < (mat->width * mat->height); ++i) {
//        if (mat->data[i] > max) {
//            max = mat->data[i];
//        }
//    }
//    return max;
}

// REQUIRES: mat points to a valid Matrix
//           0 <= row && row < Matrix_height(mat)
//           0 <= column_start && column_end <= Matrix_width(mat)
//           column_start < column_end
// EFFECTS:  Returns the column of the element with the minimal value
//           in a particular region. The region is defined as elements
//           in the given row and between column_start (inclusive) and
//           column_end (exclusive).
//           If multiple elements are minimal, returns the column of
//           the leftmost one.
int Matrix_column_of_min_value_in_row(const Matrix* mat, int row,
                                      int column_start, int column_end) {
    assert(0 <= row && row < Matrix_height(mat));
    assert(0 <= column_start && column_end <= Matrix_width(mat));
    assert(column_start < column_end);

    int min = *Matrix_at(mat, row, column_start);
    int min_index = column_start;
    for (int c = column_start; c < column_end; c++)    {
        if (*Matrix_at(mat, row, c) < min)  {
            min = *Matrix_at(mat, row, c);
            min_index = c;
        }
    }
    return min_index;
//    assert(0 <= row && row < mat->height);
//    assert(0 <= column_start && column_end <= mat->width);
//
//    int start = (mat->width * row) + column_start;
//    int end = (mat->width * row) + column_end;
//    int min = mat->data[start];
//    int min_index = start;
//
//    for (int i = start; i <= end; ++i)  {
//        if (mat->data[i] < min) {
//            min = mat->data[i];
//            min_index = i;
//        }
//    }
//    return min_index - (mat->width * row);
}

// REQUIRES: mat points to a valid Matrix
//           0 <= row && row < Matrix_height(mat)
//           0 <= column_start && column_end <= Matrix_width(mat)
//           column_start < column_end
// EFFECTS:  Returns the minimal value in a particular region. The region
//           is defined as elements in the given row and between
//           column_start (inclusive) and column_end (exclusive).
int Matrix_min_value_in_row(const Matrix* mat, int row,
                            int column_start, int column_end) {
    assert(0 <= row && row < Matrix_height(mat));
    assert(0 <= column_start && column_end <= Matrix_width(mat));
    assert(column_start < column_end);
    
    int min = *Matrix_at(mat, row, column_start);
    for (int c = column_start; c < column_end; c++)    {
        if (*Matrix_at(mat, row, c) < min)  {
            min = *Matrix_at(mat, row, c);
        }
    }
    return min;

//
//    int start = (mat->width * row) + column_start;
//    int end = (mat->width * row) + column_end;
//    int min = mat->data[start];
//
//    for (int i = start; i <= end; ++i)  {
//        if (mat->data[i] < min) {
//            min = mat->data[i];
//        }
//    }
//    return min;
}