0

I did the right portion of the decoding of the command, but when I get to decoding the image data to go the past as a byte array. I can't convert the data string to a byte array, since Zebra doesn't seem to be using base 64.

Here is my code:

The code works from there:

   private void ReadGF(string p_command)
   {

            // ^GFa,b,c,d,data

            // data
            string data = String.Empty;
            string command = String.Empty;

            int nbComma = 0;
            for (int i = 0; i < p_command.Length; i++)
            {
                if (p_command.ElementAt(i) == ',')
                {
                    nbComma++;
                }

                if (nbComma == 4) break;
                {
                    data = p_command.Substring(i + 2);

                    if (data.Trim().Length == 0)
                    {
                        return;
                    }

                    command = p_command.Remove(i + 1);
                }
            }

            string[] content = command.Split(',');

            // a = compression type
            // Values:
            // A = ASCII hexa
            // B = binary
            // C = compressed binary
            // Default: A
            string compressionType = "A";

            // b = binary byte count
            // Values: 1 to 99999
            // Default: command is ignored if a values is not specified
            int binaryByteCount = 0;

            // c = graphic field count
            // Values: 1 to 99999
            // Default: command is ignored if a values is not specified
            int graphicFieldCount = 0;

            // d = bytes per row
            // Values: 1 to 99999
            // Default: command is ignored if a values is not specified
            int bytesPerRow = 0;

            // Compression type
            if (content[0].Trim().Length == 3)
            {
                // A = ASCII hexa
                // B = binary
                // C = compressed binary
                compressionType = content[0].Trim().Substring(2, 1);

                if (!(compressionType.Equals("A") || compressionType.Equals("B") || compressionType.Equals("C")))
                {
                    throw new ArgumentOutOfRangeException("The compression type value must be A (ASCII Hexadecimal), B (Binary) or C (Compressed binary).");
                }
            }
            else
            {
                compressionType = "A";
            }

            // Binary byte count
            if (content[1].Trim().Length != 0)
            {
                binaryByteCount = TryParseInt(content[1].Trim());

                if (binaryByteCount == 0)
                {
                    return;
                }

                if (binaryByteCount > 99999 || binaryByteCount < 1)
                {
                    return;
                }
            }
            else
            {
                return;
            }

            // Graphic Field Count
            if (content[2].Trim().Length != 0)
            {
                graphicFieldCount = TryParseInt(content[2].Trim());

                if (binaryByteCount == 0)
                {
                    return;
                }

                if (binaryByteCount > 99999 || binaryByteCount < 1)
                {
                    return;
                }
            }
            else
            {
                return;
            }

            // Bytes Per Row
            if (content[3].Trim().Length != 0)
            {
                bytesPerRow = TryParseInt(content[3].Trim());

                if (bytesPerRow == 0)
                {
                    return;
                }

                if (bytesPerRow > 99999 || bytesPerRow < 1)
                {
                    return;
                }
            }
            else
            {
                return;
            }

            ID++;

I'm not sure if I am proceeding correctly from here, I will see on the internet everywhere that Zebra seems to use a compress form of hexadecimal, in Zb64 or B64 form, but it is not super clear. Would there be a better way to proceed, to know if I have the correct encryption, etc.


            byte[] imageByte = new byte[data.Length / 2];

            try
            {
                imageByte = Base64StringDecoder(data);
            }
            catch
            {
                try
                {
                    imageByte = ConvertZPLImageToByte(data);
                }
                catch
                {
                    imageByte = Enumerable.Range(0, data.Length)
                     .Where(x => x % 2 == 0)
                     .Select(x => Convert.ToByte(data.Substring(x, 2), 16))
                     .ToArray();
                }
            }

            // A = ASCII hexa
            // B = binary
            // C = compressed binary
            switch (compressionType)
            {
                case "A":
                DesignerForm.MagicToDesignerImage(ID, DateTime.Now.ToString("yyyy-MM-dd:h:mm:ss.tt)") + "_ID_" + ID, this.ActualFieldLocation.X, this.ActualFieldLocation.Y, GetSize(imageByte).Height, GetSize(imageByte).Width, imageByte);
                    break;

                case "B":
                    throw new NotImplementedException();
                case "C":
                    throw new NotImplementedException();
            }
     }

In the method called MagicToDesignerImage should draw the image. It is composed of an id, a name, an X and Y position, the width and height of the image and data in the form of a byte [].

Here is what I started with decompression in Zb64 and B64, so how do I try to recover the image size.

B64:

        private byte[] Base64StringDecoder(string p_encodedString)
        {
            return Convert.FromBase64String(p_encodedString);
        }

Zb64:


        /// <summary>
        /// I'm not sure how to do it here.
        /// </summary>
        private byte[] DecompressZb64(string compressedString)
        {
            Dictionary<char, int> valuePairs = new Dictionary<char, int>
            {
                { 'G', 1 },
                { 'H', 2 },
                { 'I', 3 },
                { 'J', 4 },
                { 'K', 5 },
                { 'L', 6 },
                { 'M', 7 },
                { 'N', 8 },
                { 'O', 9 },
                { 'P', 10 },
                { 'Q', 11 },
                { 'R', 12 },
                { 'S', 13 },
                { 'T', 14 },
                { 'U', 15 },
                { 'V', 16 },
                { 'W', 17 },
                { 'X', 18 },
                { 'Y', 19 },

                { 'g', 20 },
                { 'h', 40 },
                { 'i', 60 },
                { 'j', 80 },
                { 'k', 100 },
                { 'l', 120 },
                { 'm', 140 },
                { 'n', 160 },
                { 'o', 180 },
                { 'p', 200 },
                { 'q', 220 },
                { 'r', 240 },
                { 's', 260 },
                { 't', 280 },
                { 'u', 300 },
                { 'v', 320 },
                { 'w', 340 },
                { 'x', 360 },
                { 'y', 380 },
                { 'z', 400 }
            };

            throw new NotImplementedException();
        }

Image size:

        /// <summary>
        /// Get the size of an image from a byte array
        /// </summary>
        /// <param name="bytes">Image</param>
        /// <returns></returns>
        public Size GetSize(byte[] bytes)
        {
            using (var stream = new MemoryStream(bytes))
            {
                var image = System.Drawing.Image.FromStream(stream);
                return image.Size;
            }
        }
  • 1
    Your question isn't clear. What is the problem? Please edit the question and clarify what you are looking for; Don't add "edit" or "update" type tags, simply add the information as if it'd been there originally. Please see "[ask]", "[Stack Overflow question checklist](https://meta.stackoverflow.com/questions/260648)" and "[MCVE](https://stackoverflow.com/help/minimal-reproducible-example)" and all their linked pages. Is your code the _absolute minimum necessary to duplicate the problem_? Anything beyond that wastes our time when trying to help you. – the Tin Man May 19 '20 at 21:37
  • GF uses binary data. So when you get it into a *string* then it is already too late to recover the actual bytes, a string cannot store arbitrary byte values. The bug is in the caller of this method, it needs to generate a byte[] instead. – Hans Passant May 19 '20 at 22:19
  • look here: https://stackoverflow.com/questions/58417817/decoding-z64-zb64-string – user8759706 Jun 30 '20 at 10:18

0 Answers0