Page 1 of 1

C#: Byte Array to Decimal to Int

Posted: Tue Mar 17, 2009 11:32 am
by HaLo2FrEeEk
Ok, I've tried everything I know (which, admittedly, isn't much yet), and I can't get a proper conversion from a byte array to decimal to int. The byte array is the hex representation of the number of bytes I'm reading from the starting offset. I get those 4 bytes starting at offset 0x40 in the file. I then need to convert them to Decimal so I can get the actual number of bytes which the hex values represent, then I guess I have to convert it to an int so I can use it in my next readbytes command that actually reads the bytes starting from the starting offset.

My problem is that I keep getting an error "InvalidCastException was unhandled" telling me I can't cast object of type 'System.IO.BinaryReader' to type 'System.IConvertible'. What can I do to make this work? Is there an easier way to get the proper number I need from the 4 bytes starting at 0x40? I'm working with .blf files, btw, and this is a project I'm doing just to learn the language, so please don't tell me that there are already tools to do it, just please help me getting started. I've tried googling how to do it and they all seem to use memorystream/memoryreader, so I tried using that and it doesn't want to work!

Please help!

Re: C#: Byte Array to Decimal to Int

Posted: Tue Mar 17, 2009 1:14 pm
by OwnZ joO
I think you are looking for:

Code: Select all

// assuming br is a BinaryReader
br.BaseStream.Position = 0x40;
int fourBytes = br.ReadInt32();

Re: C#: Byte Array to Decimal to Int

Posted: Tue Mar 17, 2009 1:33 pm
by HaLo2FrEeEk
Will that get the decimal value of the hex bytes? The hex values are 00 00 A3 E1, and the decimal equivalent is 41953, which is how far I need to read into the file until I hit the end of the image. I'll try it.

Edit: This gives me: -509411328, not 41953, am I missing something? Remember I've been using this language for all of about 3 days.

Re: C#: Byte Array to Decimal to Int

Posted: Tue Mar 17, 2009 5:45 pm
by LuxuriousMeat
HaLo2FrEeEk wrote:Will that get the decimal value of the hex bytes? The hex values are 00 00 A3 E1, and the decimal equivalent is 41953, which is how far I need to read into the file until I hit the end of the image. I'll try it.

Edit: This gives me: -509411328, not 41953, am I missing something? Remember I've been using this language for all of about 3 days.
Would this file happen to be a Xbox 360 file? If so, you need to read it in big endian.

Re: C#: Byte Array to Decimal to Int

Posted: Tue Mar 17, 2009 6:21 pm
by OwnZ joO
LuxuriousMeat wrote:You need to read it in big endian.
Like so:

Code: Select all

byte[] temp = br.ReadBytes(4); // read a 4 byte array
Array.Reverse(temp);
int offset = BitConverter.ToInt32(temp, 0);

Re: C#: Byte Array to Decimal to Int

Posted: Tue Mar 17, 2009 10:17 pm
by HaLo2FrEeEk
What's the main difference between Big and Little Endian? I've got my hex editor set to Big, but it doesn't seem to change anything, the bytes are still the same. I'll try that code you wrote though, ownzjoo, thanks.

Edit: I love you...

Edit 2: Ah son of a Bi...

Now I'm having trouble saving the png. I've put it into a memorystream and tried saving that stream, but all I get is a file with extension png that contains the text "System.IO.MemoryStream". I tried making a new bitmap using the memorystream, but I don't know the dimensions of the image, since .blf files can be different sizes (these are the blf images in the Halo 3 /maps/images folder.) I'm sorry, I know I'm being annoying, but I don't get it. I've tried I really did. My code:

Code: Select all

public void OpenButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                FileStream fs = new FileStream(ofd.FileName, FileMode.Open);
                BinaryReader br = new BinaryReader(fs);
                textBox1.Text = "Opening file " + ofd.FileName + "..." + Environment.NewLine;
                br.BaseStream.Position = 0x40;
                textBox1.Text += "Calculating image length...";
                byte[] pnglen = br.ReadBytes(4);
                Array.Reverse(pnglen);
                int offset = BitConverter.ToInt32(pnglen, 0);
                textBox1.Text += offset + Environment.NewLine;
                br.BaseStream.Position = 0x44;
                byte[] pngbytes = br.ReadBytes(offset);
                textBox1.Text += "Reading Image File...";
                Stream pngStream = new MemoryStream(pngbytes);
                textBox1.Text += "Done!" + Environment.NewLine;
                SaveFileDialog sfd = new SaveFileDialog();
                sfd.DefaultExt = "png";
                sfd.Filter = "PNG Image|*.png";
                sfd.Title = "Save Image";
                sfd.AddExtension = true;
                sfd.RestoreDirectory = true;
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    textBox1.Text += "Writing File...";
                    StreamWriter wpng = new StreamWriter(sfd.FileName);
                    wpng.Write(pngStream);
                    wpng.Close();
                    textBox1.Text += "Done!" + Environment.NewLine;            
                }
                else
                {
                    textBox1.Text += "File Writing Canceled.";
                }
            }
        }
I know it's sloppy, but I like to get things working, then clean them up.

Re: C#: Byte Array to Decimal to Int

Posted: Wed Mar 18, 2009 1:46 pm
by LuxuriousMeat
Use this:

Code: Select all

wpng.Write(pngStream.ToArray());

Re: C#: Byte Array to Decimal to Int

Posted: Wed Mar 18, 2009 2:21 pm
by HaLo2FrEeEk
'System.IO.Stream' does not contain a definition for 'ToArray' and no extension method 'ToArray' accepting a first argument of type 'System.IO.Stream' could be found (are you missing a using directive or an assembly reference?)

Error. Do I really need to put pngbytes (a byte array) into a memorystream, then read it out again, then convert it back to an array? Can I just write pngbytes to the file?

edit: apparently not, I just can't figure this out.

Re: C#: Byte Array to Decimal to Int

Posted: Wed Mar 18, 2009 8:02 pm
by LuxuriousMeat
HaLo2FrEeEk wrote:'System.IO.Stream' does not contain a definition for 'ToArray' and no extension method 'ToArray' accepting a first argument of type 'System.IO.Stream' could be found (are you missing a using directive or an assembly reference?)

Error. Do I really need to put pngbytes (a byte array) into a memorystream, then read it out again, then convert it back to an array? Can I just write pngbytes to the file?

edit: apparently not, I just can't figure this out.
My bad I just saw you instantiate it as a 'MemoryStream'. Just do:

Code: Select all

wpng.Write(pngbytes);
Take out that MemoryStream stuff.

Re: C#: Byte Array to Decimal to Int

Posted: Thu Mar 19, 2009 8:54 am
by HaLo2FrEeEk
I feel bad for putting you through this, but I tried that:

wpng.Write(pngbytes);

it writes this to the file:

System.Byte[]

I've tried:

Encoding.Default.GetBytes(pngbytes)

And that doesn't work, and it I do BitConverter.ToString(pngbytes) it prints out the hex for the file...

Re: C#: Byte Array to Decimal to Int

Posted: Thu Mar 19, 2009 8:25 pm
by JacksonCougAr
Because StreamWriter uses ASII encoding or some such. You need to use a BinaryWriter to write the byte[] to a file. StreamWriter.Writer(byte[]) will literally write the byte[].ToString() method return value, whereas BinaryWriter.Write(byte[]) will write the bytes.

Re: C#: Byte Array to Decimal to Int

Posted: Fri Mar 20, 2009 6:27 am
by OwnZ joO
Ha I didn't realize that when I looked at his code. I didn't examine it too hard, but I didn't catch that. It's funny how when you get more advanced in stuff you miss the little things. Like when you get into the more advanced maths and 4 + 3 is 12 sometimes lol. Losing the edge :oops:

Re: C#: Byte Array to Decimal to Int

Posted: Fri Mar 20, 2009 8:30 am
by HaLo2FrEeEk
I got some help on another forum, he told me this:

Code: Select all

FileStream f = new FileStream(sfd.FileName, FileMode.Create, FileAccess.Create);
BinaryWriter wpng = new BinaryWriter(f);
wpng.Write(pngbytes);
wpng.Close();
And that works great. Thanks for all your help, guys.

Re: C#: Byte Array to Decimal to Int

Posted: Fri Mar 20, 2009 9:37 am
by OwnZ joO
That's what Jackson suggested you do, he just didn't provide you a code snippet.