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