Jump to content
  • Advertisement
Sign in to follow this  
caldiar

[.net] Reading Two Bytes as One

This topic is 3561 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am at my wits end here and about to break something so I thought I'd tap gamedev once more. I've googled for hours. Searched the gamedev site. Visited lame sites that claim to have the answers but want you to register first. The works. Nothing. Maybe it's because I haven't slept in two days or maybe I'm just worse at programming than I thought but this is stupid hard for me. Here's the situation: I have a file. Its contents look like 00 00 FF 00 repeated over and over again. When read in to memory, 00 is treated as two individual bytes (a char each) I want 00 to be treated as a single byte so I can write the damn thing to address and get the ascii representation of the hex value. I found out that the images I was writing out as .tga was writing the hex values of what were supposed to be my hex values. I wasn't pleased. I was simply moving the source file's content to an output with an added header and a new extension. But for some reason, when looking at this in a hex editor, the values were nowhere near to the original's values. No code because I know it doesn't work and I know that the way I'm doing it assumes that I'm trying to convert a single char into a piece of an address. Here's an example though of what I'm doing:
unsigned int stride32;
unsigned char *buffer = new unsigned char[length];
file.read(buffer, length); //go on until end of file

int abyte = 0;
//we have the original file in a bigass buffer now. Sweet. We have the "hex" values saved and ready for use. 

unsigned char *whereisit = (unsigned char*)&stride32;
*(whereisit + abyte) = buffer[first two chars];
abyte += 1; //next byte in int
*(whereisit + abyte) = buffer[next two chars]; //yes, I skip whitespace
abyte += 1; //next byte in int
//Repeat that until all 4 bytes of int have been filled then....

cout << stride32;

Not the exact code but it sums up what I'm trying to do I guess. I would really appreciate ANY help I can get with this. Thanks again gamedev.net!

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by caldiar
I have a file. Its contents look like 00 00 FF 00 repeated over and over again.

When read in to memory, 00 is treated as two individual bytes (a char each)

I want 00 to be treated as a single byte so I can write the damn thing to address and get the ascii representation of the hex value.


Maybe this is way off, as I'm not sure if I understand what you're trying to do, but I think you should do something like this:


for each pair of characters (i.e., 00/FF)
int leftDigit = convert left char to a number
int rightDigit = convert right char to a number
char theByte = (char)(leftDigit * 16 + rightDigit);


Again, sorry if this is way off.

EDIT: Made some changes to the pseudo-code.

EDIT 2: Changed it again, thanks Nypyren for pointing out a stupid mistake.

[Edited by - Gage64 on January 14, 2009 2:33:26 AM]

Share this post


Link to post
Share on other sites
00 is two chars (0 and 0)

I want 00 to be one char so I can use it to modify my the 4 bytes that make up my int.

Basically I want 00 00 FF 00 to fit inside the 4 bytes of an int but when 00 00 FF 00 is read into the buffer each individual digit is treated as a byte when it should be pairs of digits.

EDITED: I sounded like a jerk. I need some sleep


Share this post


Link to post
Share on other sites
Quote:
Original post by Gage64
Quote:
Original post by caldiar
I have a file. Its contents look like 00 00 FF 00 repeated over and over again.

When read in to memory, 00 is treated as two individual bytes (a char each)

I want 00 to be treated as a single byte so I can write the damn thing to address and get the ascii representation of the hex value.


Maybe this is way off, as I'm not sure if I understand what you're trying to do, but I think you should do something like this:


for each pair of characters (i.e., 00/FF)
int leftDigit = leftChar - '0';
int rightDigit = rightChar - '0';
char theByte = (char)(leftDigit * 16 + rightDigit);


Again, sorry if this is way off.

EDIT: Made some changes to the pseudo-code.



Make sure that you do something different for the A-F characters, since they aren't next to the 0..9 characters in the ASCII table (after '9' there's junk like ':' and other punctuation marks)

such as:

int leftDigit = (leftchar <= '9') ? (leftChar - '0') : (toupper(leftChar) - 'A' + 0xA);

Share this post


Link to post
Share on other sites
Quote:
Original post by caldiar
00 is two chars (0 and 0)

I want 00 to be one char so I can use it to modify my the 4 bytes that make up my int.


Sorry, but I still don't understand why you can't use my method to convert every such "pair" into a byte, and then use bit manipulation to combine 4 bytes into an int.

Share this post


Link to post
Share on other sites
Quote:
Original post by Gage64
Quote:
Original post by caldiar
00 is two chars (0 and 0)

I want 00 to be one char so I can use it to modify my the 4 bytes that make up my int.


Sorry, but I still don't understand why you can't use my method to convert every such "pair" into a byte, and then use bit manipulation to combine 4 bytes into an int.

You should use that method - along with the changes suggested by Nypyren - to read in 2 chars and convert them to one byte.

Do that 4 times and build your integer from those 4 pairs. In your code you read each char as a byte, so your 4 pairs take up 8 bytes, not just 4.

Share this post


Link to post
Share on other sites
Thank you SO MUCH guys! I love you all <3

The reason I wanted to do this conversion is so I could turn a text file into a 32 bit RGBA tga file.

the text 00 00 FF 00 comes out as gibberish in ascii but the tga's hex value matches when opened with a hex editor.

I am curious though, why am I seeing green and blue in the green and blue channels even though I set the pixel to be only pure red?

Shouldn't green and blue be empty?

Share this post


Link to post
Share on other sites
Quote:
Original post by caldiar
The reason I wanted to do this conversion is so I could turn a text file into a 32 bit RGBA tga file.


std::ifstream input("input.txt");
std::ofstream output("output.txt", std::ios::out | std::ios::binary);

input >> std::hex;

std::copy(std::istream_iterator<unsigned>(input),
std::istream_iterator<unsigned>(),
std::ostream_iterator<unsigned char>(output));


Quote:
I am curious though, why am I seeing green and blue in the green and blue channels even though I set the pixel to be only pure red?
I don't think your eyes are able to see the actual bit patterns as green and blue colors, so I suspect you're using some kind of software to display the channels of your image. Could it be that your software displays a background greenish color to show that you're seeing the green channel?

Share this post


Link to post
Share on other sites
turns out the alpha channel was skewing the byte order creating a pattern of red/green/blue instead of just red.

Fixed by outputting as a .raw and loading it as an RGBA file in GIMP.

Wow that's some elegant code.

Here's mine (a ton of stuff is hard coded but it's for personal use so I didn't bother to make it do anything but function)


#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <sstream>

#include <string>
#include <vector>
#include <windows.h>

//#define NULL 0;

typedef unsigned char byte;
typedef unsigned int size_t;
int length;

using namespace std;

ifstream file;
ofstream o_file("output.tga", ios::binary);
int pos = 0;


char header[18];


char *buffer;
//unsigned char condensed[8]; //00 00 00 00 = 8 bytes / 2 (digit pairs)

void *safe_malloc( size_t size )
{
void *p;

p = malloc(size);
if(!p)
printf("SAFE_MALLOC HAS AN ERROR!");

return p;
}

void FlipBytes(){
//unsigned char* ARGH = (unsigned char*)&stride32;
unsigned int printme;
unsigned char *ptr = (unsigned char*)&printme;
int i = 0;
int left;
int right;
char *header;
header = (char*)safe_malloc(18);
memset(header, 0, 18);
//file.seekg(0);
header[2] = 2;
header[12] = 512 & 255;
header[13] = 512 >> 8;
header[14] = 512 & 255;
header[15] = 512 >> 8;
header[16] = 24;

o_file.write(header, 18);

//file.seekg(0, ios::beg);

while(pos < length){
//00 00 00 00
if(buffer[pos] <= '9'){
left = buffer[pos] - '0';
}else{
if(buffer[pos] == 'A'){left = toupper(buffer[pos]) - 'A' + 0xA; }
if(buffer[pos] == 'B'){left = toupper(buffer[pos]) - 'B' + 0xB; }
if(buffer[pos] == 'C'){left = toupper(buffer[pos]) - 'C' + 0xC; }
if(buffer[pos] == 'D'){left = toupper(buffer[pos]) - 'D' + 0xD; }
if(buffer[pos] == 'E'){left = toupper(buffer[pos]) - 'E' + 0xE; }
if(buffer[pos] == 'F'){left = toupper(buffer[pos]) - 'F' + 0xF; }
}
if(buffer[pos + 1] <= '9'){
right = buffer[pos + 1] - '0';
}else{
if(buffer[pos + 1] == 'A'){right = toupper(buffer[pos + 1]) - 'A' + 0xA; }
if(buffer[pos + 1] == 'B'){right = toupper(buffer[pos + 1]) - 'B' + 0xB; }
if(buffer[pos + 1] == 'C'){right = toupper(buffer[pos + 1]) - 'C' + 0xC; }
if(buffer[pos + 1] == 'D'){right = toupper(buffer[pos + 1]) - 'D' + 0xD; }
if(buffer[pos + 1] == 'E'){right = toupper(buffer[pos + 1]) - 'E' + 0xE; }
if(buffer[pos + 1] == 'F'){right = toupper(buffer[pos + 1]) - 'F' + 0xF; }
}

char newbyte = (char)(left * 16 + right);
o_file << newbyte;

//char newbyte = (char)(left + right);

*(ptr + i) = newbyte;
i++;
if(i >= sizeof(unsigned int)){
//o_file << *((unsigned int*)ptr);
i = 0;
}


pos += 3;



/*l1[0] = (char)&buffer[pos];
l1[1] = (char)&buffer[pos + 1];
//l1[2] = buffer[pos + 2];

l2[0] = buffer[pos + 3];
l2[1] = buffer[pos + 4];
//l2[2] = buffer[pos + 5];

l3[0] = buffer[pos + 6];
l3[1] = buffer[pos + 7];
//l3[2] = buffer[pos + 8];

l4[0] = buffer[pos + 9];
l4[1] = buffer[pos + 10];
//l4[2] = buffer[pos + 11];*/




//o_file.write(l4, 3);


//o_file.flush();


//cout << bytearray << endl;
//bytearray = NULL;
}
//if(file.eof()){
// file.close();
//}
}

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





char filename[512];
cout << "Enter the name of the file to convert:" << endl;
cin.getline(filename, 256);
cout << "Ok! Sit tight while this is processed..." << endl;
file.open(filename, ios::binary);
file.seekg(0, ios::end);
length = file.tellg();
file.seekg(0, ios::beg);

buffer = new char [length];
//pos = file.tellg();


file.read(buffer, length);
file.close();
if(file != NULL){
FlipBytes();
}
buffer = NULL;
delete[] buffer;
return 0;
}






Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!