Q
QuasiChameleon
Hi,
I'm trying to create a grayscale image class that reads and writes
grayscale Targa format. This works well with smaller images, but
corrupts larger images and creates a "Segmentation fault (core dumped)"
error. I am at a loss as to why this works only part of the time.
I hope it's proper etiquette to post the code below (3 files).
Can someone please show me what's wrong with the following code? I
adapted this from an old matrix class of mine.
Thanks in advance!
Kevin Crosby
Bare bones code below:
g++ -c -o image.o image.cpp
g++ -o targa.exe targa.cpp image.o -lm
//targa.cpp
int main(int argc, char **argv) {
int header[18];
image gpicval, gnew;
gpicval.readTarga(argv[1], header);
gnew = gpicval;
gnew.writeTarga(argv[2], header);
}
//image.cpp
#include <iostream.h>
#include <fstream.h>
#include "image.h"
image::image(int rows, int cols, int val) {
m = rows;
n = cols;
img = alloc(m, n);
for (int i=0; i < m; i++)
for (int j=0; j < n; j++)
img[j] = val;
}
void image::readTarga(char* filename, int* header) {
ifstream fpin(filename, ios::binary);
unsigned char gdata_char;
if (!fpin) {
cerr << "Cannot open input file!" << endl;
exit(0);
}
for (int j = 0; j < 18; j++) {
fpin >> gdata_char;
header[j] = gdata_char;
}
if (header[16] != 8) {
cerr << "This image file does not have 8 bits per pixel, execution
halted" << endl;
exit(2);
}
freem();
m = 256*header[15] + header[14]; /* number of lines in image */
n = 256*header[13] + header[12]; /* number of pixels per line */
img = alloc(m, n);
for (int k = 0; k < m; k++)
for (int j = 0; j < n; j++) {
fpin >> gdata_char;
img[j][k] = gdata_char;
}
fpin.close();
}
void image::writeTarga(char* filename, int* header) const {
ofstream fpout(filename, ios::binary);
unsigned char gdata_char;
if (!fpout) {
cerr << "Cannot open output file!" << endl;
exit(1);
}
for (int j = 0; j < 18; j++) {
gdata_char = header[j];
fpout << gdata_char;
}
for (int k = 0; k < m; k++)
for (int j = 0; j < n; j++) {
gdata_char = img[j][k];
fpout << gdata_char;
}
fpout.close();
}
image::~image() {
freem();
}
image::image(const image& val) {
m = val.m;
n = val.n;
img = alloc(m, n);
for (int i=0; i < m; i++)
for (int j=0; j < n; j++)
img[j] = val(i+1, j+1);
}
int **image::alloc(int rows, int cols) {
int **temp = new int*[rows];
for (int i=0; i < rows; i++)
temp = new int[cols];
return (temp);
}
void image::freem(void) {
for(int i=0; i < m; i++)
delete [] img;
delete [] img;
}
image& image:perator=(const image& val) {
freem();
m = val.m;
n = val.n;
img = alloc(m, n);
for (int i=0; i < m; i++)
for (int j=0; j < n; j++)
img[j] = val(i+1, j+1);
return (*this);
}
int &image:perator() (int row, int col) {
if ((row <= 0) || (row > m) || (col <= 0) || (col > n)) {
cerr << "Index out of range." << endl;
exit(1);
}
return img[row - 1][col - 1];
}
int image:perator() (int row, int col) const {
if ((row <= 0) || (row > m) || (col <= 0) || (col > n)) {
cerr << "Index out of range." << endl;
exit(1);
}
return img[row - 1][col - 1];
}
//image.h
#ifndef IMAGE
#define IMAGE
class image {
/* define the structure of a image */
private:
int m, n; /* quantity of rows and columns */
int **img; /* a 2D array for the elements */
/* define functions that all other functions can use */
public:
image(int row=1, int col=1, int val=0); /* default to 1x1
vacuous */
void image::readTarga(char*, int*); /* read Targa from file
*/
void image::writeTarga(char*, int*) const; /* write Targa to file
*/
~image();
image(const image &); /* copy an
existing image */
int **alloc(int, int); // allocate memory for image
void freem(void); // free memory for image
image& operator=(const image&); // equal
int &operator()(int, int); // element selection (write)
int operator()(int, int) const; // element selection (read)
};
#endif
I'm trying to create a grayscale image class that reads and writes
grayscale Targa format. This works well with smaller images, but
corrupts larger images and creates a "Segmentation fault (core dumped)"
error. I am at a loss as to why this works only part of the time.
I hope it's proper etiquette to post the code below (3 files).
Can someone please show me what's wrong with the following code? I
adapted this from an old matrix class of mine.
Thanks in advance!
Kevin Crosby
Bare bones code below:
g++ -c -o image.o image.cpp
g++ -o targa.exe targa.cpp image.o -lm
//targa.cpp
int main(int argc, char **argv) {
int header[18];
image gpicval, gnew;
gpicval.readTarga(argv[1], header);
gnew = gpicval;
gnew.writeTarga(argv[2], header);
}
//image.cpp
#include <iostream.h>
#include <fstream.h>
#include "image.h"
image::image(int rows, int cols, int val) {
m = rows;
n = cols;
img = alloc(m, n);
for (int i=0; i < m; i++)
for (int j=0; j < n; j++)
img[j] = val;
}
void image::readTarga(char* filename, int* header) {
ifstream fpin(filename, ios::binary);
unsigned char gdata_char;
if (!fpin) {
cerr << "Cannot open input file!" << endl;
exit(0);
}
for (int j = 0; j < 18; j++) {
fpin >> gdata_char;
header[j] = gdata_char;
}
if (header[16] != 8) {
cerr << "This image file does not have 8 bits per pixel, execution
halted" << endl;
exit(2);
}
freem();
m = 256*header[15] + header[14]; /* number of lines in image */
n = 256*header[13] + header[12]; /* number of pixels per line */
img = alloc(m, n);
for (int k = 0; k < m; k++)
for (int j = 0; j < n; j++) {
fpin >> gdata_char;
img[j][k] = gdata_char;
}
fpin.close();
}
void image::writeTarga(char* filename, int* header) const {
ofstream fpout(filename, ios::binary);
unsigned char gdata_char;
if (!fpout) {
cerr << "Cannot open output file!" << endl;
exit(1);
}
for (int j = 0; j < 18; j++) {
gdata_char = header[j];
fpout << gdata_char;
}
for (int k = 0; k < m; k++)
for (int j = 0; j < n; j++) {
gdata_char = img[j][k];
fpout << gdata_char;
}
fpout.close();
}
image::~image() {
freem();
}
image::image(const image& val) {
m = val.m;
n = val.n;
img = alloc(m, n);
for (int i=0; i < m; i++)
for (int j=0; j < n; j++)
img[j] = val(i+1, j+1);
}
int **image::alloc(int rows, int cols) {
int **temp = new int*[rows];
for (int i=0; i < rows; i++)
temp = new int[cols];
return (temp);
}
void image::freem(void) {
for(int i=0; i < m; i++)
delete [] img;
delete [] img;
}
image& image:perator=(const image& val) {
freem();
m = val.m;
n = val.n;
img = alloc(m, n);
for (int i=0; i < m; i++)
for (int j=0; j < n; j++)
img[j] = val(i+1, j+1);
return (*this);
}
int &image:perator() (int row, int col) {
if ((row <= 0) || (row > m) || (col <= 0) || (col > n)) {
cerr << "Index out of range." << endl;
exit(1);
}
return img[row - 1][col - 1];
}
int image:perator() (int row, int col) const {
if ((row <= 0) || (row > m) || (col <= 0) || (col > n)) {
cerr << "Index out of range." << endl;
exit(1);
}
return img[row - 1][col - 1];
}
//image.h
#ifndef IMAGE
#define IMAGE
class image {
/* define the structure of a image */
private:
int m, n; /* quantity of rows and columns */
int **img; /* a 2D array for the elements */
/* define functions that all other functions can use */
public:
image(int row=1, int col=1, int val=0); /* default to 1x1
vacuous */
void image::readTarga(char*, int*); /* read Targa from file
*/
void image::writeTarga(char*, int*) const; /* write Targa to file
*/
~image();
image(const image &); /* copy an
existing image */
int **alloc(int, int); // allocate memory for image
void freem(void); // free memory for image
image& operator=(const image&); // equal
int &operator()(int, int); // element selection (write)
int operator()(int, int) const; // element selection (read)
};
#endif