Archived

This topic is now archived and is closed to further replies.

machiavelli

weirdest thing i've ever seen.... ever

Recommended Posts

so im movin along in my program, and i have a function that reads in a text file with RGB information. and it works. and i can reproduce the image i make from this RGB information on the screen. so then i try and duplicate that function into a function that loads a set of 16 .txt files and reads RGB information in. here is the code, where ReadFromFile is the function that works and i can use the data retrieved to produce an image, and loadBG function, which should load 16 images (cells) and put all the pixel information into one array. some information about the code: BMP[x][y] is an array of COLORREFS that is to represent the image to be displayed. the .txt files are arranged such that there is one integer per line representing a color intensity so the file is huge and looks like 24 160 32 54 etc etc
void ReadFromFile(char *filename)
{
	std::ifstream infile;
	infile.open(filename,std::ios::in);
	int tr,tg,tb;
	for(int x=0;x> tr;   //read red intensity
			infile >> tg;   //read green intensity
			infile >> tb;   //read blue intensity
			tempcell.BMP[x][y]=RGB(tr,tg,tb);

		}
	}
	infile.close();
}
//SETBG DEBUG MODE ONLY
void setBG()
{
 std::ifstream infile;
 std::ofstream debugfile("debug.txt");
 //for all 16 cells...
 for(int y=0;y<4;y++)
 {
  for(int x=0;x<4;x++)
  {
   char temp[12]
   sprintf(temp,"cell%d.txt",(80+y*4+x));
   debugfile << temp << "\n";
   infile.open(temp,std::ios::in);
   int tr,tg,tb;
   if(infile.is_open()) debugfile << "FILE OPENED SUCCESSFULLY\n";
   for(int xx=0;xx> tr;
         debugfile << "R:" << tr;
         infile >> tg;
         debugfile << "G:" << tg;
         infile >> tb;
         debugfile << "B:" << tb;
         long offset=y*70*280+x*70+yy*280+xx;
         BG[offset]=RGB(tr,tg,tb);
      }
      debugfile << "\n";
   }
   infile.close();
   if(!infile.is_open()) debugfile << "FILE CLOSED SUCCESSFULLY\n";
  }
 }
debugfile.close();
}
    
i know this is a long post.. i just dont understand how i can copy the code almost EXACTLY the same and offe will read the integers from the file correctly, and the other offe will read the integers as -8384783972 or some weird friggin number. someone please help me this is pretty much the last problem i face before i can complete my program [edited by - machiavelli on March 20, 2004 8:14:47 AM] [edited by - machiavelli on March 20, 2004 8:15:45 AM] added question: why cant i declare char *filename; sprintf(filename,"fu"); without getting a runtime error that says filename was declared but not defined. i thought sprintf defined the string "fu" in filename? also should mention that my second function works if i use infile.load("cell88.txt",std::ios::in); and also mention that my debug file reads that the correct .txt files are being opened successfully and closed successfully. [edited by - machiavelli on March 20, 2004 8:20:23 AM]

Share this post


Link to post
Share on other sites
Shouldn''t tr,tb and tg be BYTE (unsinged char) instead of int?!



"C lets you shoot yourself in the foot rather easily. C++ allows you to reuse the bullet!"

Share this post


Link to post
Share on other sites
the string of explitives thats about to fly outta my mouth is unheard of. ive tried every data type known to man to read into and all of them give some @#$@#$@%$#@^@^%^$@^^% up. yes, to be technical, R G and B should be DWORDS but it doesnt matter because neither fopen nor fstream open will read the #@^$# DFSGDSFJKLJFDSALBVJFDSLKFDLKFDSgb file the way i want it to. getline doesnt work because i cant convert string to integer because i get all sorts of exception errors when i try. and the rod in the butt of it all is that the reading of the file in the second function is a fuc#@$in EXACT COPY of the first function and one works and the other doesnt. CAN SOMEONE EXPLAIN THAT TO ME?!

Share this post


Link to post
Share on other sites
furthermore... let me mention again that
if i replace this line:

infile.open(temp,std::ios::out)

with

infile.open("cell81.txt",std::ios::out)

it works but i have only grabbed one cell. what changes between using a string variable to represent a filename and an actual filename in quotations that would make my >> operator read correctly?????? does this not make sense to anyone else besides me? mind you, BOTH of the aforementioned statements return TRUE on infile.is_open(), meaning my string variable isnt screwed up. are there any moderators/experts/anyone that can explain this phenomenom to me?

Share this post


Link to post
Share on other sites
I''m not sure why you would want to store pixels in a text file for especially how awkward it is to read the data back again. What I would suggest is to read and write as a binary file. If your creating your own format first thing you would want to do is to make a specification of the file format, defining a header for the file that describes everything about the contents of the file/image, its size, its width and height, bits per pixel etc. I’ve made a tutorial program that demonstrates (at a basic level) what’s involved in creating a new file format, defining a header structure, making a reading and writing functions and displaying it in OpenGL using some random colours. I call the file format KFile lol here it is, you need glut libs to run the example program:

KHeader.h:

/*
Title: C++ Binaray file input/output demo

Binary file reading and writing example with a simple file format i invented
for demenstration i call the "K" img file lol
format is:

-------------------
| HEADER |
-------------------
| |
| DATA |
| |
| |
-------------------

using : ifstream.read and ostream.write


ifstream.read (char* s, streamsize n );

Read a block of data. Reads a block of data of the length specified by n.
Data is read sequentially, so if the End-Of-File is reached before the
whole block could be read the buffer will contain the elements read
until End-Of-File.

ostream& ofstream.write ( const char* str , streamsize n );

Write a sequence of characters. Inserts into the output
stream a sequence of characters starting by character pointed
by str and following by successive characters in the array
until the number of characters specified by n has been
successfully written or until an error occurs in the output sequence.
No check for ending null characters is done.
*/

#ifndef _KHEADER_ // <-- ignore that not relevant, prevents multiple inclusions

#define _KHEADER_ // <-- ignore that not relevant


class KHeader {
public:
unsigned long size_of_img; // size of the img excluding header size

unsigned int width; // <-- pretty obvious

unsigned int height; // <-- same here

};

//Reads in a K file into the buffer given the file name

void read_k_file(const char* filename, unsigned char* img_buffer);

//Wright out a K file given a new file name, header spec, and the data

void write_k_file(const char* filename, const KHeader& header, const unsigned char img_buffer[]);

#endif // <-- ignore that not relevant



KHeader.cpp

/*
Title: C++ Binaray file input/output demo

Binary file reading and writing example with a simple file format i invented
for demenstration i call the "K" img file lol
format is:

-------------------
| HEADER |
-------------------
| |
| DATA |
| |
| |
-------------------

using : ifstream.read and ostream.write


ifstream.read (char* s, streamsize n );

Read a block of data. Reads a block of data of the length specified by n.
Data is read sequentially, so if the End-Of-File is reached before the
whole block could be read the buffer will contain the elements read
until End-Of-File.

ostream& ofstream.write ( const char* str , streamsize n );

Write a sequence of characters. Inserts into the output
stream a sequence of characters starting by character pointed
by str and following by successive characters in the array
until the number of characters specified by n has been
successfully written or until an error occurs in the output sequence.
No check for ending null characters is done.
*/

#include <iostream>

using std::ios; //input/output constants stuff


#include <fstream>

using std::ofstream; //input file stream

using std::ifstream; //output file stream


#include "KHeader.h"

void read_k_file(const char* filename, unsigned char* img_buffer) {

KHeader header; //Need a header to find out about the file


ifstream in(filename, ios::in | ios::binary); //create a input stream in binary mode


if(in.is_open() && in.good()) { //make sure everything went ok


// Read in all the header info where the file pointer starts at the begin

// of the file. The reinterpret_cast< some_type >() is a C++ operator

// which says to cast the address of the header object from type KHeader* to

// char * . the sizeof operator returns the size of the structure/class not the

// object but you can get the size of the object for other situtions

// sizeof(object) != sizeof(class) in some cases (always the case if the object is a pointer!)

in.read(reinterpret_cast< char * >(&header), sizeof(KHeader));

// Now the header info has been read in we can craete the correct sized buffer

// for the img to be stored in system memory;

img_buffer = new unsigned char[header.size_of_img];

// Some times the format of a file may not put the raw data automatic after the

// header part thats when at this stage you would use the method seekg.


// seekg moves the file pointer from its current location to what value you

// pass in its arguements, in a example case if the format did specifi the

// raw data to be straight after the header part, we move to some offset

// which is where the begining of the raw data is stored

// you call like this if we had to:


// in.seekg(header.offset); <--- just an example of moving the file pointer


// Now we have moved to the correct location, (which is wright after the header

// part) in the file of the pixel data we can

// just read it in telling the method that we want to read how ever big the

// image is that which just got from the header and thats it!

in.read(reinterpret_cast< char * >(img_buffer), header.size_of_img);

} else {
// Something went wrong, set img to null so others know if things went

// ok or not

img_buffer = 0;
}

// Always realease your resources!

in.close();

}

void write_k_file(const char* filename, const KHeader& header, const unsigned char img_buffer[]) {

ofstream out(filename, ios::out | ios::binary);

if(out.is_open() && out.good()) {

// This is pretty much straight foward, simillar to above but the

// other way round, and is much more simpler, just wright out the

// header then the data and thats it in are case

out.write(reinterpret_cast< const char * >(&header), sizeof(KHeader));
out.write(reinterpret_cast< const char * >(img_buffer), header.size_of_img);

}

// Always realease your resources!

out.close();
}


KHeaderTest.cpp

/*
Title: C++ Binaray file input/output demo

Binary file reading and writing example with a simple file format i invented
for demenstration i call the "K" img file lol
format is:

-------------------
| HEADER |
-------------------
| |
| DATA |
| |
| |
-------------------

using : ifstream.read and ostream.write


ifstream.read (char* s, streamsize n );

Read a block of data. Reads a block of data of the length specified by n.
Data is read sequentially, so if the End-Of-File is reached before the
whole block could be read the buffer will contain the elements read
until End-Of-File.

ostream& ofstream.write ( const char* str , streamsize n );

Write a sequence of characters. Inserts into the output
stream a sequence of characters starting by character pointed
by str and following by successive characters in the array
until the number of characters specified by n has been
successfully written or until an error occurs in the output sequence.
No check for ending null characters is done.
*/

#include <iostream>

using std::cout;
using std::endl;

#include <cstdlib>

using std::rand;
using std::srand;

#include <ctime>

using std::time;

#include <gl/glut.h>

#include "KHeader.h"

void init();

void reshape(GLsizei, GLsizei);

void display();

static GLsizei wh = 480;
static GLsizei ww = 640;

//To create are new K file we need to fill out the header

static KHeader header;

//are img buffer to store only pixel data

unsigned char* img = 0;


int main(int argc, char **argv) {

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(ww, wh);
glutInitWindowPosition(10, 50);
glutCreateWindow("Img reading/writing");

init(); //<-- this is where we intialize structures, not in the loop!


glutDisplayFunc(display);
glutReshapeFunc(reshape);

glutMainLoop();

delete img;
}

void init() {

// First lets create a new file with some random pixel data, lets

// make an image of 300 by 300 with random colors and in RGB format

// which is 3 values, the size of the image is thus:

// width * hieght * 3(RGB!)


const int width = 300;
const int height = 300;
const int size = width * height * 3;

// name for the new file to write and read

const char* filename = "kImage.k";

// so know we know how big this file is, lets allocate some

// dynamic memory to hold the pixel data

img = new unsigned char[size];

srand((unsigned)time(0)); // seed the random generator with the systems time for a unique number each time


for(int i = 0; i < size; i++) { //makes some random colors

img[i] = 1 + (rand() % 255);
}

// fill out are header structure

header.size_of_img = size;
header.width = width;
header.height = height;

//write the new data to file in binary

write_k_file(filename, header, img);


//Now for testing purposes lets read the file back again lol"

//read in the file we just created!

read_k_file(filename, img);

//rest of init is opengl stuff

glClearColor(0.0, 0.0, 0.0, 0.0); //black


glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, static_cast< GLdouble >(ww), 0.0, static_cast< GLdouble >(wh));
glMatrixMode(GL_MODELVIEW);

} // end of function init


void display() {

glClear(GL_COLOR_BUFFER_BIT);

// glRasterPos sets the current raster position in the frame buffer

// to its arguements, in are case we want it at the begining

glRasterPos2i(0, 0);

// glDrawPixels takes the pixel data stored in img variable from

// system memormy to the graphic card''s frame buffer, specifiing

// the height and width of the image and its format

glDrawPixels(header.width, header.height, GL_RGB, GL_UNSIGNED_BYTE, img);
glFlush();
glutSwapBuffers();
}

void reshape(GLsizei w, GLsizei h) {

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, static_cast< GLdouble >(ww), 0.0, static_cast< GLdouble >(wh));

glMatrixMode(GL_MODELVIEW);
glViewport(0, 0, ww, wh);
glutPostRedisplay();
}

Share this post


Link to post
Share on other sites