#include #include #include #include #include #include #include "Image.h" #include "processing.h" #include "Matrix_test_helpers.h" #include "Image_test_helpers.h" using namespace std; void test_all(string prefix, int sizes[], int num_sizes); void test_rotate(const Image *img, string prefix); void test_energy(const Matrix *energy_mat, string prefix); void test_cost(const Matrix *cost_mat, string prefix); void test_find_seam(const int seam[], int n, string prefix); void test_remove_seam(const Image* img, const int seam[], string prefix); void test_seam_carve(const Image *img, string prefix, int new_width, int new_height); static void load_matrix(Matrix* mat, string filename); static void write_matrix(const Matrix* mat, string filename); static void load_image(Image* img, string filename); static void write_image(const Image* img, string filename); static void load_seam(int seam[], string filename); static void write_seam(const int seam[], int len, string filename); const string OUT_PPM_EXT = ".out.ppm"; const string OUT_TXT_EXT = ".out.txt"; int main(int argc, char *argv[]){ if (argc > 2 || (argc == 2&& strcmp(argv[1], "dog") && strcmp(argv[1], "crabster") && strcmp(argv[1], "horses"))) { cout << "Usage: " << argv[0] << " [dog|crabster|horses]" << endl; return 1; } string which_test = argc == 2 ? argv[1] : "all"; if (which_test == "all" || which_test == "dog") { int dog_sizes[] = {4, 5}; test_all("dog", dog_sizes, 1); } if (which_test == "all" || which_test == "crabster") { int crabster_sizes[] = {50, 45, 70, 35}; test_all("crabster", crabster_sizes, 2); } if (which_test == "all" || which_test == "horses") { int horses_sizes[] = {300, 382, 400, 250}; test_all("horses", horses_sizes, 2); } } void test_all(string prefix, int sizes[], int num_sizes){ Image* img = new Image; load_image(img, prefix + ".ppm"); // Test rotate test_rotate(img, prefix); // Test energy Matrix* energy = new Matrix; compute_energy_matrix(img, energy); test_energy(energy, prefix); // Test cost Matrix* cost = new Matrix; compute_vertical_cost_matrix(energy, cost); test_cost(cost, prefix); // Test find seam int seam[MAX_MATRIX_HEIGHT]; find_minimal_vertical_seam(cost, seam); test_find_seam(seam, Matrix_height(cost), prefix); // Test remove seam test_remove_seam(img, seam, prefix); // Test full seam carving algorithm on various sizes for(int i = 0; i < num_sizes; ++i){ test_seam_carve(img, prefix, sizes[2*i], sizes[2*i + 1]); } cout << prefix << " tests PASS" << endl << endl; delete cost; delete energy; delete img; } void test_rotate(const Image *img, string prefix){ Image* rotated_img = new Image; Image* rotated_img_correct = new Image; // Test left rotation cout << "Testing " << prefix << " rotate left..." << flush; *rotated_img = *img; rotate_left(rotated_img); write_image(rotated_img, prefix + "_left" + OUT_PPM_EXT); load_image(rotated_img_correct, prefix + "_left.correct.ppm"); assert(Image_equal(rotated_img, rotated_img_correct)); cout << "PASS" << endl; // Test right rotation cout << "Testing " << prefix << " rotate right..."; *rotated_img = *img; rotate_right(rotated_img); write_image(rotated_img, prefix + "_right" + OUT_PPM_EXT); load_image(rotated_img_correct, prefix + "_right.correct.ppm"); assert(Image_equal(rotated_img, rotated_img_correct)); cout << "PASS" << endl; delete rotated_img_correct; delete rotated_img; } void test_energy(const Matrix *energy_mat, string prefix){ cout << "Testing " << prefix << " energy..." << flush; write_matrix(energy_mat, prefix + "_energy" + OUT_TXT_EXT); Matrix* energy_mat_correct = new Matrix; load_matrix(energy_mat_correct, prefix + "_energy_correct.txt"); assert(Matrix_equal(energy_mat, energy_mat_correct)); cout << "PASS" << endl; delete energy_mat_correct; } void test_cost(const Matrix *cost_mat, string prefix){ cout << "Testing " << prefix << " cost..." << flush; write_matrix(cost_mat, prefix + "_cost" + OUT_TXT_EXT); Matrix* cost_mat_correct = new Matrix; load_matrix(cost_mat_correct, prefix + "_cost_correct.txt"); assert(Matrix_equal(cost_mat, cost_mat_correct)); cout << "PASS" << endl; delete cost_mat_correct; } void test_find_seam(const int seam[], int n, string prefix){ cout << "Testing " << prefix << " find seam..." << flush; write_seam(seam, n, prefix + "_seam" + OUT_TXT_EXT); int seam_correct[MAX_MATRIX_HEIGHT]; load_seam(seam_correct, prefix + "_seam_correct.txt"); assert(array_equal(seam, seam_correct, n)); cout << "PASS" << endl; } void test_remove_seam(const Image* img, const int seam[], string prefix){ cout << "Testing " << prefix << " remove seam..." << flush; Image* removed_img = new Image(*img); remove_vertical_seam(removed_img, seam); write_image(removed_img, prefix + "_removed" + OUT_PPM_EXT); Image* removed_img_correct = new Image; load_image(removed_img_correct, prefix + "_removed.correct.ppm"); assert(Image_equal(removed_img, removed_img_correct)); cout << "PASS" << endl; delete removed_img_correct; delete removed_img; } void test_seam_carve(const Image *img, string prefix, int new_width, int new_height){ cout << "Testing " << prefix << " seam carve "; cout << new_width << "x" << new_height << "..." << flush; Image* carved_img = new Image(*img); seam_carve(carved_img, new_width, new_height); write_image(carved_img, prefix + "_" + to_string(new_width) + "x" + to_string(new_height) + OUT_PPM_EXT); Image* carved_img_correct = new Image; load_image(carved_img_correct, prefix + "_" + to_string(new_width) + "x" + to_string(new_height) + ".correct.ppm"); assert(Image_equal(carved_img, carved_img_correct)); cout << "PASS" << endl; delete carved_img_correct; delete carved_img; } static void load_matrix(Matrix* mat, string filename){ ifstream fin; fin.open(filename.c_str()); if (!fin.is_open()){ cout << "Unable to open " << filename << endl; exit(EXIT_FAILURE); } int width, height; fin >> width >> height; Matrix_init(mat, width, height); for (int r = 0; r < height; ++r) { for (int c = 0; c < width; ++c) { fin >> *Matrix_at(mat, r, c); } } } static void write_matrix(const Matrix* mat, string filename){ ofstream fout(filename.c_str()); Matrix_print(mat, fout); } static void load_image(Image* img, string filename){ ifstream fin; fin.open(filename.c_str()); if (!fin.is_open()){ cout << "Unable to open " << filename << endl; exit(EXIT_FAILURE); } Image_init(img, fin); } static void write_image(const Image* img, string filename){ ofstream fout(filename.c_str()); Image_print(img, fout); } static void load_seam(int seam[], string filename){ ifstream fin; fin.open(filename.c_str()); if (!fin.is_open()){ cout << "Unable to open " << filename << endl; exit(EXIT_FAILURE); } for(int i = 0, column; fin >> column; ++i){ seam[i] = column; } } static void write_seam(const int seam[], int len, string filename){ ofstream fout(filename.c_str()); for(int i = 0; i < len; ++i){ fout << seam[i] << endl; } }