Slim Image

Discussion of challenges you have already solved
Post Reply
dloser
Posts: 2
Joined: Fri Aug 07, 2009 6:40 am

Slim Image

Post by dloser »

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. ;)
nighthalk
Posts: 41
Joined: Fri Jul 31, 2009 8:22 pm

Post by nighthalk »

and here i read it in byte by byte expanding/shifting/oring as needed and changed it to 8 bit *sighs* well it works so it counts =P (dont feel sorry i did it in ollydebug not by hand haha)
AMindForeverVoyaging
Forum Admin
Posts: 496
Joined: Sat May 28, 2011 9:14 am
Location: Germany

Post by AMindForeverVoyaging »

This was one of the better challenges in my opinion. I wrote some C code to transform the 7-bit to 8-bit and then wrote it to a .ppm file which I could open. The solution was also good for a smile :)
wodkahack0r
Posts: 9
Joined: Thu Mar 05, 2009 7:27 pm

Post by wodkahack0r »

Nice challenge! I wrote a PHP script (don't blame me for this :D ) 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");

?>
User avatar
yes-man
Posts: 32
Joined: Fri Jan 30, 2009 5:14 pm

Post by yes-man »

Agreed. This was one of the better challenges. Especially the fact, that most people (including me) ended up with the 'circle + garbage' images first :D
Post Reply