Returning ppointer

Hello gents. I need to return a pointer to base elements in an image and I am totally lost. Any suggesting would be great to get me going.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// image.cpp
#include "stdafx.h"
#include <iostream>
#include "image.h"

image::image() 
{
	pixels = NULL;
	width = 0;
	height = 0;
}

image::image(string filename) 
{
	pixels = NULL;
	width = 0;
	height = 0;
	loadImage(filename);
}

image::~image()
{
	if(pixels)
	{
		for(int i=0; i<height; i++)
			delete [] pixels[i];
		delete [] pixels;
		pixels = NULL;
		width = 0;
		height = 0;
	}
}

int image::getWidth()
{
	return width;
}

int image::getHeight()
{
	return height;
}

pixel** image::getPixels()
{
	return pixels;
}


bool image::loadImage(string filename)
{
	if(pixels)
	{
		for(int i=0; i<height; i++)
			delete [] pixels[i];
		delete [] pixels;
		pixels = NULL;
		width = 0;
		height = 0;
	}
	
	CImage myImage;
	CString cs(filename.c_str());
	myImage.Load(cs);
	
	if(myImage.IsNull())
	{
		cout << "The requested image could not be loaded." << endl;
		return false;
	}
	if(myImage.GetBPP() != 24) 
	{
		cout << "The input image must be stored in the 8 bit RGB (24 bpp) colorspace." << endl;
		return false;
	}

	width = myImage.GetWidth();
	height = myImage.GetHeight();

	pixels = new pixel*[height];
	uchar* imageBuf = (uchar*)myImage.GetBits();
	int scanline = myImage.GetPitch();

	for (int j = 0; j < height; j++) 
	{
		pixels[j] = new pixel[width];	
		for (int i = 0; i < width; i++) 
		{
			pixels[j][i].red = imageBuf[j*scanline+i*3+2];
			pixels[j][i].green = imageBuf[j*scanline+i*3+1];
			pixels[j][i].blue = imageBuf[j*scanline+i*3];
		}
	}
	return true;
}



void image::saveImage(string filename) 
{
	if(!pixels)
	{
		cout << "No image data has been created to save! (The pixel buffer is empty)" << endl;
		return;
	}

	CImage myImage;
	pixelsToCImage(&myImage);

	CString cs(filename.c_str());
	myImage.Save(cs);

	return;
}



//return a #include "stdafx.h"  //needed for the Windows display
#include <cstdlib>
#include <string>
#include <fstream> // allow file in and output

using namespace std;

#include "globals.h"  //some global variables are included here
#include "pixel.h"  //includes the pixel class for storing individual pixels
#include "image.h"	//includes the image class we will be using.pointer to your image object!

// in main I have
//load the image from a file and return the result
bool loadImageFromFile(string filename)
{
......
}

//save an image to a file
void saveImageToFile(string filename)
{
.....
}

// this () should return a pointer to the image object that is currently
// viewed on the screem 
image* displayImage()
{
	image* p = NULL;

	for (int j = 0; j < myImage.getHeight(); j++) 
	{
		if( j == 0)
		{
			p = j;
			return p;
		}

	}
	return NULL;	
}


I am pretty lost on the image* displayImage() here and could use some help.
I don't get your code. loadImageFromFile function. What does it do? Surely it calls someimage.loadImage(filename), but what is someimage? A global?
The same goes for saveImageToFile. And especially displayImage. What is it supposed to do at all? Blit image M onto the screen and return a pointer to M? Or a pointer to screen? And what is M?
Thanks for your help hamsterman, Let me clarify. I did not want the original post to have large amounts of code.

These are Globals
1
2
3
4
5
6
7
8
9
10
11
12
13
14

int counter = 0;

const int MAXRGB = 255;
int redValue;
int greenValue;
int blueValue;
int i = 0;

pixel** ptr = NULL;

image myImage;
pixel myPixels;


bool loadImageFromFile(string filename)
INPUTS: a string containing a path to a file to open. This value is returned from the
user's selection in the open file dialog.
OUTPUTS: a Boolean indicating whether or not the image could be opened correctly.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//load the image from a file and return the result
bool loadImageFromFile(string filename)
{
	ifstream inFile; // declare in file stream variable
	inFile.open( filename.c_str() ); // open data file 

	// check to see if file will open, terminate the program if file failed to open
	if ( inFile.fail() )                                   
        {
		return false;
                exit( 1 );
        }
	else
	{
		myImage.loadImage( filename );
		return true;
	}

	inFile.close();
}


void saveImageToFile(string filename)
INPUTS: a string containing a path to save the current image out to.
OUTPUTS: NONE
1
2
3
4
5
6
7
8
9
10
11

//save an image to a file
void saveImageToFile(string filename)
{
	ofstream outFile; // declare out file stream variable
	outFile.open( filename.c_str() ); // open data out file
	
	myImage.saveImage( filename );	
	
	outFile.close();
}


image* displayImage()
INPUTS: NONE
OUTPUTS: This function should return a pointer to the image object that is currently being viewed on the screen.
If a user has loaded an image correctly, you should return a pointer to an image object containing the base image.
If a user has used the shrink button (aka averageRegions function) or performed any of the red/green/blue filters,
you should of course return a pointer to an image object that reflects these changes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

//return a pointer to your image object!
image* displayImage()
{
	// this is a mess because I am not sure what to do
        image* p = NULL;

	for (int j = 0; j < myImage.getHeight(); j++) 
	{
		if( j == 0)
		{
			p = j;
			return p;
		}

	}
	return NULL;	
}


I hope this answers your question and if you could help I would greatly appreciate it.
Thanks again
note: loadImageFromFile returns before the file is closed.

The implementation of displayImage depends on the implementation of your shrink and filter functions.
No image will load if I don't complete the image* displayImage(), so I cant get to my shrink function during debugging (VS) without the image* displayImage() being completed.

I have been playing with the image* displayImage() but I get an C2440 error, cannot convert pixel** to unsigned int.

1
2
3
4
5
6
7
8
9
10
11
12
//return a pointer to your image object!
image* displayImage()
{
	int j = 0;
	ptr = new image*[ myImage.getHeight() ];
	for ( j; j < myImage.getHeight(); j++ )
	{
		ptr[j] = new image[ myImage.getPixels() ];  // this gives me the error
	}

	return ptr[j];
}


Thanks again for your help.
Last edited on
So you want to return a pointer to a copy of myImage ?
Yes that is correct.
Then why not take the code of image::loadImage, delete half of it and add dynamic allocation.
1
2
3
4
5
6
7
8
9
10
11
12
Image* copy = new Image;
copy->width = myImage.GetWidth();
copy->height = myImage.GetHeight();

copy->pixels = new pixel*[height];

for (int j = 0; j < copy->height; j++) {
    copy->pixels[j] = new pixel[copy->width];	
    for (int i = 0; i < copy->width; i++)
        copy->pixels[i][j] = myImage.pixels[i][j];
}
return copy;

Also, http://www.cplusplus.com/forum/articles/17108/
That is code written by someone else and I can not change it.
I don't mean changing that code. I meant copying parts of it. My point was that these functions have a similar purpose (and thus similar code).
Sorry, pardon my ignorance. I get errors that say weight, height and pixels can not access private member declared in class 'image'.

here is the image and pixel header files:
1
2
3
4
5
6
7
8
9
10
11
12
13
14

#ifndef PIXEL_H
#define PIXEL_H

class pixel
{
public:
	unsigned char red;		//the red component
	unsigned char green;	//the green component
	unsigned char blue;		//the blue component
};

#endif


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

#ifndef IMAGE
#define IMAGE

#include <atlimage.h>
#include <string>
#include <cstdlib>
#include "globals.h"
#include "pixel.h"

using namespace std;

class image 
{
	public:
		image();			//the image constructor (initializes everything)
		image(string filename);  //a image constructor that directly loads an image from disk
		~image();			//the image destructor  (deletes the dynamically created pixel array)
		void createNewImage(int width, int height);
 //this function deletes any current image data and creates a new blank image
//with the specified width/height and allocates the needed number of pixels
//dynamically.
		
                 bool loadImage(string filename);	
//load an image from the specified file path.  Return true if it works, false if it is not a valid image.
		
                void saveImage(string filename);	   //Save an image to the specified path
		pixel** getPixels();				//return the 2-dimensional pixels array
		int getWidth();					//return the width of the image
		int getHeight();				//return the height of the image
		void viewImage(CImage* myImage);  //This function is called by the windows GUI. 
	private:
		void pixelsToCImage(CImage* myImage);
		pixel** pixels;	// pixel data array for image 
		int width, height; // stores the image dimensions 
};

#endif


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

image* copy = new image;
	copy->width = myImage.getWidth(); // error
	copy->height = myImage.getHeight(); // error

	copy->pixels = new pixel*[copy->height]; // error

	for (int j = 0; j < copy->height; j++)  // error
	{
		copy->pixels[j] = new pixel[copy->width];  // error
			for (int i = 0; i < copy->width; i++) // error
				copy->pixels[i][j] = myImage.pixels[i][j]; // error
	}
	return copy;




Thanks for your help and patience with me.
Well, then change all ->height\width to ->getHeight\Width. But still you won't be able to assign (lines 2, 3). The right way would be to make setHeight\Width functions (of make members public) but if you can't modify the header, that won't work.
One thing you could try to overcome this is to remove lines 1,2 and write *copy = myImage;
Thanks for hanging in hamsterman. This is what I have with your suggestions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
        int i, j = 0;
	image *copy = new image; 
	*copy = myImage;  // if I remove line 2 I get an error with this line

	copy->getPixels() = new pixel*[ copy->getHeight() ]; // error left operand must be l-value

	for (j; j < copy->getHeight(); j++)  
		copy->getPixels() = new pixel*[ copy->getWidth() ];  // error left operand must be l-value
	for (i; i < copy->getWidth(); i++) 
		copy->pixels[ i ][ j ] = myImage.pixels[ i ][ j ]; // error cammot access private member
                                                                    //  in  class image and subscript requires
                                                                    // array or pointer type
	
	return copy;


Thanks again . If you're getting tired of this I understand
If you delete line 2 in its entirety, you've no longer declared copy. Just remove the equals sign and the bit after it.
I didn't think about copy->pixels access. If you can't modify the header, I really can't think of a way to go around this. Are you sure you need to make a copy?
btw, in previous post I meant lines 2,3
I tried it Zhuge's way and I could not get it to work.
hamsterman, I figured you meant 2, 3.
I just need to return a pointer to to the image object that is loaded from a file.
When the program starts a window appears with various buttons. There is an open image button that needs to be pressed first. Upon clicking this button a separate window opens with various pictures. So I click on a picture and the picture becomes the image object that I need to return a pointer to.

I hope that makes sense.

Thanks for your help.
When the program starts a window appears with various buttons. There is an open image button that needs to be pressed first. Upon clicking this button a separate window opens with various pictures. So I click on a picture and the picture becomes the image object that I need to return a pointer to.
And what is myImage in this situation?

I'm starting to have a feeling that all you need is retrurn &myImage;
I have tried what you mentioned hamsterman, "return &myImage", and it works.
LOL
Something so easy yet I have made so difficult.

I want to thank you hamsterman for all your help, patience and understanding. You didn't talk down to me or belittle me because I don't know something so "basic". It is guys like you that makes guys like me want to keep programming.

Thanks again!
Last edited on
Topic archived. No new replies allowed.