So I guess the challenge is based on the premise that no image program can handle the 7-bit pixels. This seems plausible and my default viewers indeed failed. I probably did what most did and made a little program to read the 7-bit pixels and dump them in some "normal" format (I chose RAW).
After finishing the challenge I figured I could have easily made a PNM file instead of RAW (it's just a small header in front of RAW). Not knowing the header format by heart I figured a quick way to get it is to use one of the xxxtopnm tools on some arbitrary image. So I ran 'bmptopnm picnic.bmp'. Surprise: it didn't complain one bit. In fact, it has no problem with the 7-bit pixels and directly generates a nice and "normal" PNM, viewable without a problem.
Just thought I'd share.
Slim Image
-
- Forum Admin
- Posts: 496
- Joined: Sat May 28, 2011 9:14 am
- Location: Germany
-
- Posts: 9
- Joined: Thu Mar 05, 2009 7:27 pm
Nice challenge! I wrote a PHP script (don't blame me for this ) to read the BMG file and output an PNG.
Code: Select all
<?php
$file = "picnic.bmp";
$im = fopen($file, "rb");
$img = fread($im, filesize($file));
$headersize = 108;
$temp = unpack("H*",$img);
$hex = $temp[1];
$header = substr($hex,0,$headersize);
print "Image size: ".(strlen($hex)/2)."\n";
if (substr($header,0,4)=="424d")
{
$header_parts = str_split($header,2);
$width = hexdec($header_parts[19].$header_parts[18]);
$height = hexdec($header_parts[23].$header_parts[22]);
$start_image_data = hexdec($header_parts[11].$header_parts[10]);
$color_count = hexdec($header_parts[47].$header_parts[46]);
}
print "Width: $width\nHeight: $height\n";
print "Image data start: $start_image_data\n";
print "Colors used: $color_count\n";
print "Headersize: $headersize\n";
// Farbtabelle
$color_table = substr($hex, $headersize, 8*$color_count);
#print "Color table: ".$color_table."\n";
$color = array();
for ($i=0;$i<strlen($color_table);$i+=8)
{
$color[$i/8]['b'] = hexdec($color_table[$i].$color_table[$i+1]);
$color[$i/8]['g'] = hexdec($color_table[$i+2].$color_table[$i+3]);
$color[$i/8]['r'] = hexdec($color_table[$i+4].$color_table[$i+5]);
if ($i/8 == 255) break;
}
$x = 0;
$y = 1;
$image = imagecreatetruecolor($width,$height);
$body = substr($hex,$start_image_data*2);
$body_size = (strlen($body)/2);
print("Image data size: $body_size Byte\n");
print("Total Pixels (width x height): ".($width*$height)."\n");
print(($width*$height)." x 7 Bit per Pixel: ".($width*$height*7/8)." Byte\n");
$body_b = "";
for ($i=0;$i<strlen($body);$i+=56) {
for ($x=0;$x<56;$x+=4) {
$hex_1 = substr($body, $i+$x, 2);
$hex_2 = substr($body, $i+$x+2, 2);
$bin_1 = base_convert($hex_1, 16, 2);
$bin_1 = str_pad($bin_1, 8, '0', STR_PAD_LEFT);
$bin_2 = base_convert($hex_2, 16, 2);
$bin_2 = str_pad($bin_2, 8, '0', STR_PAD_LEFT);
$body_b .= $bin_1 . $bin_2;
}
}
$y = $x = 0;
// 7 bit per pixel
for ($i=0;$i<strlen($body_b);$i+=7)
{
if ($x >= $width) {
$x = 0;
$y++;
}
$bits = substr($body_b, $i, 7);
$color_index = bindec($bits);
$r = $color[$color_index]['r'];
$g = $color[$color_index]['g'];
$b = $color[$color_index]['b'];
$color_img = imagecolorallocate($image,$r,$g,$b);
imagesetpixel($image,$x,$height-$y,$color_img);
$x++;
}
imagepng($image, "out.png");
?>