Search code examples
c#filezxing

Unusual Character addition after writing back decoded file


I am using ZXing.Net library to encode and decode my video file using RS Encoder. It works well by adding and and removing parity after encoding and decoding respectively. But When writing decoded file back it is adding "?" characters in file on different locations which was not part of original file. I am not getting why this problem is occurring when writing file back. Here is my code

using ZXing.Common.ReedSolomon;

namespace zxingtest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            string inputFileName = @"D:\JM\bin\baseline_30.264";
            string outputFileName = @"D:\JM\bin\baseline_encoded.264";
            string Content = File.ReadAllText(inputFileName, ASCIIEncoding.Default);
            //File.WriteAllText(outputFileName, Content, ASCIIEncoding.Default);
            ReedSolomonEncoder enc = new ReedSolomonEncoder(GenericGF.AZTEC_DATA_12);
            ReedSolomonDecoder dec = new ReedSolomonDecoder(GenericGF.AZTEC_DATA_12);
            //string s = "1,2,4,6,1,7,4,0,0";
            //int[] array = s.Split(',').Select(str => int.Parse(str)).ToArray();
            int parity = 10;
            List<byte> toBytes = ASCIIEncoding.Default.GetBytes(Content.Substring(0, 500)).ToList();

            for (int index = 0; index < parity; index++)
            {
                toBytes.Add(0);
            }
            int[] bytesAsInts = Array.ConvertAll(toBytes.ToArray(), c => (int)c);

            enc.encode(bytesAsInts, parity);
            bytesAsInts[1] = 3;
            dec.decode(bytesAsInts, parity);
            string st = new string(Array.ConvertAll(bytesAsInts.ToArray(), z => (char)z));
            File.WriteAllText(outputFileName, st, ASCIIEncoding.Default);
        }
    }
}   

And here is the Hex file view of H.264 bit stream enter image description here


Solution

  • The problem is that you're handling a binary format as if it is a Text file with an encoding. But based on what you are doing you only seem to be interested in reading some bytes, process them (encode, decode) and then write the bytes back to a file.

    If that is what you need then use the proper reader and writer for your files, in this case the BinaryReader and BinaryWriter. Using your code as a starting point this is my version using the earlier mentioned readers/writers. My inputfile and outputfile are similar for the bytes read and written.

    string inputFileName = @"input.264";
    string outputFileName = @"output.264";
    
    ReedSolomonEncoder enc = new ReedSolomonEncoder(GenericGF.AZTEC_DATA_12);
    ReedSolomonDecoder dec = new ReedSolomonDecoder(GenericGF.AZTEC_DATA_12);
    
    const int parity = 10;
    
    // open a file as stream for reading
    using (var input = File.OpenRead(inputFileName))
    {
        const int max_ints = 256;
        int[] bytesAsInts = new int[max_ints];
        // use a binary reader
        using (var binary = new BinaryReader(input))
        {
            for (int i = 0; i < max_ints - parity; i++)
            {
                //read a single byte, store them in the array of ints
                bytesAsInts[i] = binary.ReadByte();
            }
            // parity
            for (int i = max_ints - parity; i < max_ints; i++)
            {
                bytesAsInts[i] = 0;
            }
    
            enc.encode(bytesAsInts, parity);
    
            bytesAsInts[1] = 3;
    
            dec.decode(bytesAsInts, parity);
    
            // create a stream for writing
            using(var output = File.Create(outputFileName))
            {
                // write bytes back
                using(var writer = new BinaryWriter(output))
                {
                    foreach(var value in bytesAsInts)
                    {
                        // we need to write back a byte
                        // not an int so cast it
                        writer.Write((byte)value);
                    }
                }
            }
        }
    }