[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

how to read .raw image file in C++

Posted on 2007-12-02
9
Medium Priority
?
14,643 Views
Last Modified: 2013-12-16
Hello,

I am trying to open a .raw image file stored on my hard drive in a C++ program to manipulate it.
After opening the file, want to save its pixel information in a 2-D array. The image is a 256 X 256 with 8 bits per pixel and no header bytes.

I would like the array to be dynamic so that i am not limited to only a 256 X 256 image, but the 8-bit representation will be unchanged.

I figured using fstream in binary mode would work, but it doesn't seem too or maybe i am using it wrong.  

Can someone please show me how I can open the .raw file and then load it into a dynamic array and the needed libraries.  

If it makes any difference, I am using a window xp machine running Visual Studio .Net 2005 as my c++ editor and compiler

Thank you so much
Kevin Harrilal
0
Comment
Question by:krazieintent
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
9 Comments
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 20392141
could you post the code you have so far?
0
 
LVL 3

Author Comment

by:krazieintent
ID: 20392446
sure here is what i have so far.

The code asks the user for the location of the file using the function openFile.

it checks to see if the file location is valid using checkFile, and then proceeds to open the file with the command

inputFile.open(filename.c_str(),ios_base::binary)

where inputFile is my connection to fstream, and filename is the string of the file path entered by the user.

i then create a 2d dynamic array and begin reading and storing the contents of the file with the readfile function.

My method for either opening or reading or both doesnt seem to work.

Thank you so much for your help in advance.
Kevin Harrilal
#include <iostream>
#include <fstream>
#include <string>
 
using namespace std;
 
void openFile(ifstream& inputFile);
//pre condition: user is ready to input filename.
//post condition: inputFile is connected to user input filename. This //opens file.
 
bool checkFile(string filename);
//pre condition: filename is corresponding to the name of a file on the //local machine
//post condition: return true if file does not exist, returns false if file does exist, does not open file
 
int ** readFile(ifstream& inputFile, int& size);
//pre condition: inputFile has been connected to a filename and size has //been initialized to 0.
//post condition: returns a pointer to a dynamic array of ints //containing the data in inputFile.
 
 
int main()
{
	ifstream inFile;
	openFile(inFile);
	int size(0);
	int **p;
	p=readFile(inFile,size);
 
//test to see data in p
	cout<<p[3];
}
 
void openFile(ifstream& inputFile)
{ 
	//local variable
	string filename;
 
	//user input
	cout<<"Please enter the file path for the .raw image : ";
	cin>>filename;
	cout<<endl<<endl;
 
	//continue to ask for file if file does not exist
	while (checkFile(filename))
	{
		cout<<"This File does not exist, please enter another filename: ";
		cin>>filename;
		cout<<endl<<endl;
	}
 
	inputFile.open(filename.c_str(),ios_base::binary);
}
 
bool checkFile(string filename)
{
	//open file, if it opens successfull it exists, if it fails it doesnt exist
	ifstream testFile;
	testFile.open(filename.c_str(),ios_base::binary );
 
	if(testFile)
	{
		return false;
	}
	else
	{
 
		return true;
	}
 
	testFile.close();
}
 
int **readFile(ifstream& inputFile, int& size)
{
	//local variables
	int temp;
	size=256;
 
	//dynamic 2d array of size rows x size columns
	int ** p = new int*[size];
	
	for(int i=0; i < size; i++)
		p[i] = new int[size];
 
 
	//read from file into temp student
	for(int j=0;j<size; j++)
	{
		for (int i=0;inputFile>>temp && i<size; i++)
			p[i][j]=temp;
	}	
 
	return p;
}

Open in new window

0
 
LVL 55

Accepted Solution

by:
Jaime Olivares earned 2000 total points
ID: 20392556
ok, as far you are reading 8 bit values, you should have an array of 'unsigned char' instead of 'int'.
also, an STL vector will give you more flexibility than a pure C array.

so you can have a function like:
       bool readFile(ifstream &inputFile, vector<vector<unsigned char>> &rawdata);

instead of this:
      int **p
you can declare as:
      vector<vector<unsigned char>> rawdata;

it is a nested vector collection, so you will be able to access it as rawdata[i][j];
now, your readFile function will require some changes to accomodate this arrangement:


#include "math.h"
 
bool readFile(ifstream &inputFile, vector<vector<unsigned char>> &rawdata);
{
   unsigned char temp;
 
 // get length of file:
  inputFile.seekg (0, ios::end);
  int length = inputFile.tellg();
  inputFile.seekg (0, ios::beg);
 
  // determine the number of rows and cols
  int size = (int)sqrt((double)length);
  // check if it is a perfect square
  if (size*size != length)
       return false;
 
  // resize the vector
  rawdata.resize(size);
  for (int i=0; i<size; i++)
       rawdata[i].resize(size);
 
   //read from file into vector
   for(int j=0;j<size; j++)
   {
      for (int i=0; i<size; i++)
      {
          inputFile.get(temp);
          p[j][i] = temp;
      }
   }	
   return true; 
}

Open in new window

0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 3

Author Comment

by:krazieintent
ID: 20392752
Thank you so much for your help.

I just have a couple of questions on your implementation. Can you explain to me why I should use char instead of int. Does it have to do with char being store as a 16-bit value in c++?

If this is true, using the get command, since it reads one character at a time, will it also read 16 bits at a time from the input file, which would be the equivalent of two pixels? Therefore every temp store would store two pixels and not one?

As far as my opening the file in binary mode, is that part correct?


Thank you so much for your help.


0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 20392764
you mentioned your image has  8 bits per pixel.
char has 8 bits (or unsigned char)
int has 32 bits.
 
0
 
LVL 3

Author Comment

by:krazieintent
ID: 20392832
my other question is, if using unsigned chars, the pixel values will be output as ascii characters correct?
How could I extract the pixel values (0 to 255) from the character? would i use the math atoi() function or similar?

or could i just do another int static cast on the output for example cout<< (int) rawdata[0][3] because i dont think the atoi function operates on unsigned chars.

Also when running your code, I get the error of trying to convert unsigned char to char& in the inputFile.get(temp) call.

so i tried static casting to inputFile((char)temp&);

but the compiler tells me there is a syntax error ')'

any ideas?
0
 
LVL 3

Author Comment

by:krazieintent
ID: 20392840
oh I though char was a 16-bit value not 8.

So to better understand, if i were using a 16-bit per pixel picture, i would make a vector of strings of length 2?

length 3 for 24 bit and so on?

Thank you so much
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 20392893
in C++ language, a char value is treated as integer for most situation:

char a, b, c;
a = 5;
b = 4;
c = a*b;  // result 20

but some displaying function can present them as ascii char, you can make a static cast with easy in those cases:

cout << (int)c;

>>Also when running your code, I get the error of trying to convert unsigned char to char& in
you can use char instead, but depending on compiler option it will be signed or unsigned. This will affect you if you want to make some math operations.

>>So to better understand, if i were using a 16-bit per pixel picture, i would make a vector of strings of length 2?
for 16 bit images, I suggest to use 'short int' instead
for 24 bit images, I suggest to keep in char, but with double capacity of course, because you can access RGB independent values with easy.
0
 
LVL 3

Author Comment

by:krazieintent
ID: 20393097
Thank you so much for your help!  
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
The greatest common divisor (gcd) of two positive integers is their largest common divisor. Let's consider two numbers 12 and 20. The divisors of 12 are 1, 2, 3, 4, 6, 12 The divisors of 20 are 1, 2, 4, 5, 10 20 The highest number among the c…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

650 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question