Adding Int32 to List<byte> using AddRange throwing exception despite being successful

4

I'm creating an application that will take an image in a certain format from one of a video game's files and convert it to a DDS. This requires me to build the DDS in a buffer and then write it out to a DDS file. This buffer is of type List<byte>.

I first write the magic number, which is just the text "DDS ", with this code:

ddsFile.AddRange(Encoding.ASCII.GetBytes("DDS "));

I then need to write the header size, which is always 0x7C000000 (124), and this is where I've hit a wall. I used this code to write it to the buffer:

ddsFile.AddRange(BitConverter.GetBytes(0x0000007C));

This made sense to me because Encoding.ASCII.GetBytes()says itself that it returns a byte[], and it does accept an int as a parameter, no problem. And additionally, this was what I saw recommended when looking for a method for adding multi-byte values to a byte list. But for whatever reason, when the program tries to execute that line, this exception is thrown:

Unable to cast object of type 'System.Byte[]' to type 'System.IConvertible'.

But what's even more strange to the point of being ridiculous is that, upon seeing what did make it into the buffer, I see that the int actually was being written to the buffer, but the exception was still occurring for who knows what reason.

Bizarrely, even writing a single byte to the list after writing the magic number e.g. ddsFile.Add((byte)0x00)); results in the same thing.

Any help in figuring out why this exception occurs and/or a solution would be greatly appreciated.

c#
.net
asked on Stack Overflow Jun 4, 2018 by Display Name

1 Answer

2

This is not an answer to the question but a suggestion to do it differently.

Instead of using a List<byte> and manually doing all the conversions (while certainly possible, it's cumbersome), use a stream and a BinaryWriter - the stream can be a memory stream if you want to buffer the image in memory or a file stream if you want to write it to disk right away.

Using a BinaryWriter against the stream makes the conversions a lot simpler (and you can still manually convert parts of the data easily, if you need to do so).

Here's a short example:

var ms = new MemoryStream();
var bw = new BinaryWriter(ms, Encoding.ASCII);

bw.Write("DDS ");
bw.Write(124); // writes 4 bytes
bw.Write((byte) 124); // writes 1 byte
...

Use whichever overload of Write() you need to output the right bytes. (This short example omits cleaning up things but if you use a file stream, you'll need to make sure that you properly close it.)

answered on Stack Overflow Jun 4, 2018 by xxbbcc

User contributions licensed under CC BY-SA 3.0