Well, I'm always trying to make it harder than it needs to be. A few more
hours of research yielded this solution:
$out = preg_replace("/\%([0-9][0-9])/e", "chr(hexdec(\"0x$1\"))", $buf);
Header("Content-type: image/png");
echo $out;
... Worked like a charm.
If anyone can see any problems with this solution, I would be interested to
hear them!
Thanks,
Clay
> From: Clay Loveless <[EMAIL PROTECTED]>
> Date: Fri, 10 Jan 2003 22:09:03 -0800
> To: PHP-General <[EMAIL PROTECTED]>
> Subject: [PHP] Binary data confusion
>
> Hi,
>
> I've got a problem to solve regarding binary data strings, which is an area
> I don't have a lot of experience in. If anyone can help, I would be
> grateful.
>
> Here's the problem in a nutshell:
>
> I am getting a binary string from a third-party server that I need to encode
> into a PNG image. The string arrives double-quoted, so double quotes which
> may occur in the binary string have been escaped. I need to parse through
> the string and extract only the PNG data, and convert whatever has been
> escaped into usable data.
>
> I cannot control the output from the third-party -- I've got to deal with
> what they're sending. (I would much rather have them send a base64 encoded
> PNG, but unfortunately I'm not able to influence their methods.)
>
>
> Here's the problem as described by the API I'm working with:
>
> ____________________________________________________________________________
> The rule for encoding the PNG image in the returned buffer was designed to
> eliminate certain illegal characters (byte values) by replacing them with an
> escape sequence. Those values that are not allowed include:
>
> * NULL (0x00 hex)
> * Double Quote (0x22 hex)
>
> The percent character '%' (0x25 hex) is used as the escape character, and
> therefore it must be replaced where it occurs naturally. Whenever a
> disallowed character or the escape character '%' is encountered, it is
> replaced by the escape character '%' (0x25 hex) followed by two characters
> comprising the hexadecimal numeral representing the value of the character.
> For example, the NULL character (0x00 hex) is replaced by three characters:
>
> * '%' (0x25)
> * '0' (0x30)
> * '0' (0x30)
>
> The percent character 0x25 is replaced by three characters:
>
> * '%' (0x25)
> * '2' (0x32)
> * '5' (0x35)
>
> The algorithm for decoding the PNG image in the returned buffer is as
> follows. Read bytes from the buffer one at a time. When a byte read is not
> equal to the '%' character (0x25 hex), pass it through unchanged. When a
> byte is read that is equal to the '%' character (0x25 hex), read an
> additional two bytes, which will each take a value from zero (0x30 hex)
> through nine (0x39 hex) or 'A' (0x41 hex) through 'F' (0x46 hex). These two
> bytes are interpreted as a character representation of a two-digit
> hexadecimal numeral ranging from 0x00 through 0xFF. The single byte having
> the integral value represented by that numeral is appended to your output.
>
> For example, when the 3-byte string '%22' is encountered, '"' (0x22) - the
> double quote character - is passed out. When the 3 bytes '%00' are read, the
> null character is written.
>
> In essence, the developer will need to take the data received and store it
> in a buffer, which has sufficient memory to hold the entire data stream.
> Once the data has been received, the program must call a function similar to
> the one described below in order to parse the data in the buffer and extract
> only the PNG image data.
> ____________________________________________________________________________
>
> The API then presents an example in C, which I've tried to translate into
> PHP as best as I can. It's pretty close, I think -- but I'm still not
> getting a PNG out when I'm done.
>
> Here's what I've written, based on the C example:
> ____________________________________________________________________________
> $buf = [binary data received];
> $len = strlen($buf);
> $out = '';
>
> for ($c = 1; $c < $len; $c++) {
> $data = $buf{$c};
>
> if ($data != '%')
> $out .= $data;
>
> if ($data == '%') {
> for ($e = 0; $e < 2; $e++) {
> $c++;
> $data = $buf{$c};
>
> if ((($data >= 0x30) && ($data <= 0x39))
> || (($data >= 0x41) && ($data <= 0x46))) {
> if ($e == 1) {
> $d = $data;
> $d = $d & 0x0f;
> if (($data >= 0x41) && ($data <= 0x46)) {
> $d += 9;
> }
> $store = $store | $d;
> } else {
> $d = $data;
> $d = $d & 0x0f;
> if (($data >= 0x41) && ($data <= 0x46)) {
> $d += 9;
> }
> $store = $d << 4;
> }
> }
>
> }
>
> $out .= $store;
> }
> }
>
> Header("Content-type: image/png");
> echo $out;
> ____________________________________________________________________________
>
>
> I'm just getting a blank screen at the end here -- not a PNG image.
>
> Can anyone with more experience dealing with binary data offer any
> suggestions? I'm at a loss and would appreciate the help! I would be happy
> to send the example C code from the API if that would be helpful.
>
> Thank you!
>
> -Clay
>
>
>
>
> --
> PHP General Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php