// Lab_3_Goldhill_ImageProc.h
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
#ifndef _IMAGE_
#define _IMAGE_
class Image {
unsigned char **p2matr2D; // start address of image on HEAP
int num_rows; // the number of rows
int num_columns; // the number of columns
void get_image_dimensions(char *fname); // Private : determines num_rows, num_columns from file
public:
Image(); // CTOR, does NOT allocate anything
Image(Image &Img_ref); // CCTOR
~Image(); // DTOR
Image& operator=(Image&im); // assignment operator
Image extract_sub_image(int xu, int yu, int xo, int yo); // extracts an image with edges [xu, yu] [xo,yo]
void insert_image(Image &Img_ref, int xu, int yu); // inserts an image at position [xu,yu]
void show_image(int=0,int=0,int=10,int=10); // displays an image, default sizes as specified
void operator++(int); // interpolate an image
void operator--(int); // decimate an image
void operator<<(int N); // rotate LEFT N times
void operator>>(int N); // rotate RIGHT N times
void read_image_from_disk(char *fname); // reads image and uses get_image_dimensions() to determine rows and columns
void write_image_to_disk(char *fname);
};
#endif
Image::Image(){
p2matr2D = NULL;
num_rows = 0;
num_columns = 0;
}
Image::~Image(){
cout << "DTOR called " << endl;
int i;
for (i=0;i<num_rows;i++)
delete [ ] p2matr2D[i]; // delete each allocated array separately !!
delete [ ] p2matr2D; // delete array of pointers */
}
Image::Image(Image &Img_ref){
cout << "CCTOR Image" << endl;
num_rows = Img_ref.num_rows;
num_columns = Img_ref.num_columns;
int i,j;
p2matr2D = new unsigned char* [num_rows];
for (i=0; i<num_rows; i++)
p2matr2D[i] = new unsigned char [num_columns];
for (i=0;i<num_rows;i++){
for (j=0;j<num_columns;j++){
p2matr2D[i][j] = Img_ref.p2matr2D[i][j];
}
}
}
Image& Image::operator= (Image & im)
{
if (this == &im) return *this; // Handle the self assignment
cout << "Assign-OP Image" << endl;
int i,j;
for (i=0;i<num_rows;i++)
delete [ ] p2matr2D[i]; // delete each allocated array separately !!
delete [ ] p2matr2D; // delete array of pointers */
num_rows = im.num_rows;
num_columns = im.num_columns;
p2matr2D = new unsigned char* [num_rows];
for (i=0; i<num_rows; i++)
p2matr2D[i] = new unsigned char [num_columns];
for (i=0;i<num_rows;i++){
for (j=0;j<num_columns;j++){
p2matr2D[i][j] = im.p2matr2D[i][j];
}
}
return *this;
}
void Image::show_image(int xu,int yu,int xo,int yo){
int show_columns;
int show_rows;
int i,j;
if (xu < xo){show_columns = xo - xu;}
else {show_columns = xu - xo;}
if (yu < yo){show_rows = yo - yu;}
else {show_rows = yu - yo;}
// Printing the values
for (i=0;i<show_rows;i++){
for (j=0;j<show_columns;j++){
cout << setw(3) << (unsigned int) p2matr2D[yu+i][xu+j] << " ";
}
cout << endl;
}
}
Image Image::extract_sub_image(int xu, int yu, int xo, int yo){ // 100 100 200 200
//y = row, x = col
int i,j;
Image Ext_img;
if (xu < xo){Ext_img.num_columns = xo - xu;}
else {Ext_img.num_columns = xu - xo;}
if (yu < yo){Ext_img.num_rows = yo - yu;}
else {Ext_img.num_rows = yu - yo;}
Ext_img.p2matr2D = new unsigned char* [Ext_img.num_rows];
for (i=0; i<Ext_img.num_rows; i++)
Ext_img.p2matr2D[i] = new unsigned char [Ext_img.num_columns];
for (i=0;i<Ext_img.num_rows;i++){
for (j=0;j<Ext_img.num_columns;j++){
Ext_img.p2matr2D[i][j] = p2matr2D[yu+i][xu+j];
}
}
return Ext_img;
}
void Image::insert_image(Image &Img_ref, int xu, int yu){ // ext_img, 300 50
//y = row, x = col
int i,j;
for (i=0;i<Img_ref.num_rows;i++){
for (j=0;j<Img_ref.num_columns;j++){
p2matr2D[yu+i][xu+j] = Img_ref.p2matr2D[i][j];
}
}
}
// writes data to a file, filename as parameter
void Image::write_image_to_disk(char *fname){
int i, j;
ofstream fout(fname);
for (i=0;i<num_rows;i++){
for (j=0;j<num_columns;j++)
fout << setw(4) << (int) p2matr2D[j][i];
fout << endl;
}
cout << "done writing to file " << fname << endl;
}
// reads data from a file, filename as parameter, e.g. goldhill.txt
void Image::read_image_from_disk(char *fname){
int row_indx=0, col_indx=0, i;
unsigned char letter;
unsigned int data;
get_image_dimensions(fname);
ifstream fin(fname);
cout << "... reading from file " << fname << endl;
fin >> num_rows ;
fin >> num_columns ;
p2matr2D = new unsigned char* [num_rows];
for (i=0; i<num_rows; i++)
p2matr2D[i] = new unsigned char [num_columns];
while (1) {
fin >> data ;
letter = (unsigned char) data;
p2matr2D[row_indx][col_indx]=letter;
col_indx++;
if (col_indx==num_rows)
{
row_indx++;
col_indx=0;
if (row_indx == num_rows) break;
}
}
cout << "...done reading from file " << fname<< endl;
fin.close();
}
void Image::get_image_dimensions(char *fname){
// determine the number of entries in image
ifstream fin(fname);
fin >> num_rows ;
fin >> num_columns ;
cout << " File has " << num_columns << " rows and "<< num_columns << " columns" << endl;
fin.close();
}
void main(){
Image image, extracted_image;
image.read_image_from_disk("goldhill.txt");
image.show_image(0,0,4,4);
extracted_image = image.extract_sub_image(0,0,100,100);
extracted_image.write_image_to_disk("extracted_image.txt");
image.insert_image(extracted_image, 150, 50);
image.write_image_to_disk("extracted_image_inserted.txt");
/*
for (int i=0;i<2;i++)
image--;
image.write_image_to_disk("decimated_image.txt");
for (int i=0;i<2;i++)
image++;
image.write_image_to_disk("interpolated_image.txt");
// image.read_image_from_disk("gh1.txt");
image.read_image_from_disk("goldhill.txt");
cout << "After LEFT rotation " << endl;
image<<1;
image.show_image(0,0,4,4);
image.write_image_to_disk("left_rotated_image.txt");
cout << "After right rotation " << endl;
image>>1;
image>>1;
image.show_image(0,0,4,4);
image.write_image_to_disk("right_rotated_image.txt");*/
}