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

Reply via email to