Skip to main content
added 3 characters in body
Source Link
AKHolland
  • 4.5k
  • 25
  • 36
#!/usr/bin/perl

use strict;
use warnings;

use Image::PNG::Libpng ':all';
use Image::PNG::Const ':all';

my $HEADER_SIZE = 2;
my $ROWS_SIZE = 16;
my $COLS_SIZE = 16;

my $png = create_read_struct();
open my $if, '<:raw', shift or die $!;
$png->init_io( $if );
$png->read_png;
$if->close;

my @bits;
for my $row ( $png->get_rows->@* ) {
    while ( $row ) {
        my ( $r, $g, $b ) = map { ord } unpack( 'aaa', $row );
        push @bits, $r & 1,
                    $g & 1,
                    $b & 1;
        $row = substr $row, 3;
    }
}

my $header = '';
$header .= shift @bits for 1 .. $HEADER_SIZE;
if ( $header ne '10' ) {
    print "invalid header";
    exit 1;
}

my $rows = 0;
for my $pos ( 1 .. $ROWS_SIZE ) {
    my $bit = shift @bits;
    my $value = $bit << $ROWS_SIZE - $pos;
    $rows += $value;
}
print "rows: $rows\n";

my $cols = 0;
for my $pos ( 1 .. $COLS_SIZE ) {
    my $bit = shift @bits;
    my $value = $bit << $COLS_SIZE - $pos;
    $cols += $value;
}
print "cols: $rows\n";
print "==========\n";

$png = create_write_struct();
open my $of, '>:raw', 'out.png';
$png->init_io( $of );
$png->set_IHDR( {
    'height'     => $rows,
    'width'      => $cols,
    'bit_depth'  => 1,
    'color_type' => PNG_COLOR_TYPE_GRAY,
} );
$png->write_info;

my @rows;
for my $x ( 0 .. $rows - 1 ) {
    my $row = '';
    for my $y ( 0 .. $cols - 1 ) {
        my $idx = $x * $rows + $y;
        my $value = $bits[ $idx ];
        $row .= $value;
    }
    push @rows, pack( 'B*', $row;$row );
}
$png->write_image( \@rows );
$png->write_end;

exit;
#!/usr/bin/perl

use strict;
use warnings;

use Image::PNG::Libpng ':all';
use Image::PNG::Const ':all';

my $HEADER_SIZE = 2;
my $ROWS_SIZE = 16;
my $COLS_SIZE = 16;

my $png = create_read_struct();
open my $if, '<:raw', shift or die $!;
$png->init_io( $if );
$png->read_png;
$if->close;

my @bits;
for my $row ( $png->get_rows->@* ) {
    while ( $row ) {
        my ( $r, $g, $b ) = map { ord } unpack( 'aaa', $row );
        push @bits, $r & 1,
                    $g & 1,
                    $b & 1;
        $row = substr $row, 3;
    }
}

my $header = '';
$header .= shift @bits for 1 .. $HEADER_SIZE;
if ( $header ne '10' ) {
    print "invalid header";
    exit 1;
}

my $rows = 0;
for my $pos ( 1 .. $ROWS_SIZE ) {
    my $bit = shift @bits;
    my $value = $bit << $ROWS_SIZE - $pos;
    $rows += $value;
}
print "rows: $rows\n";

my $cols = 0;
for my $pos ( 1 .. $COLS_SIZE ) {
    my $bit = shift @bits;
    my $value = $bit << $COLS_SIZE - $pos;
    $cols += $value;
}
print "cols: $rows\n";
print "==========\n";

$png = create_write_struct();
open my $of, '>:raw', 'out.png';
$png->init_io( $of );
$png->set_IHDR( {
    'height'     => $rows,
    'width'      => $cols,
    'bit_depth'  => 1,
    'color_type' => PNG_COLOR_TYPE_GRAY,
} );
$png->write_info;

my @rows;
for my $x ( 0 .. $rows - 1 ) {
    my $row = '';
    for my $y ( 0 .. $cols - 1 ) {
        my $idx = $x * $rows + $y;
        my $value = $bits[ $idx ];
        $row .= $value;
    }
    push @rows, pack 'B*', $row;
}
$png->write_image( \@rows );
$png->write_end;

exit;
#!/usr/bin/perl

use strict;
use warnings;

use Image::PNG::Libpng ':all';
use Image::PNG::Const ':all';

my $HEADER_SIZE = 2;
my $ROWS_SIZE = 16;
my $COLS_SIZE = 16;

my $png = create_read_struct();
open my $if, '<:raw', shift or die $!;
$png->init_io( $if );
$png->read_png;
$if->close;

my @bits;
for my $row ( $png->get_rows->@* ) {
    while ( $row ) {
        my ( $r, $g, $b ) = map { ord } unpack( 'aaa', $row );
        push @bits, $r & 1,
                    $g & 1,
                    $b & 1;
        $row = substr $row, 3;
    }
}

my $header = '';
$header .= shift @bits for 1 .. $HEADER_SIZE;
if ( $header ne '10' ) {
    print "invalid header";
    exit 1;
}

my $rows = 0;
for my $pos ( 1 .. $ROWS_SIZE ) {
    my $bit = shift @bits;
    my $value = $bit << $ROWS_SIZE - $pos;
    $rows += $value;
}
print "rows: $rows\n";

my $cols = 0;
for my $pos ( 1 .. $COLS_SIZE ) {
    my $bit = shift @bits;
    my $value = $bit << $COLS_SIZE - $pos;
    $cols += $value;
}
print "cols: $rows\n";
print "==========\n";

$png = create_write_struct();
open my $of, '>:raw', 'out.png';
$png->init_io( $of );
$png->set_IHDR( {
    'height'     => $rows,
    'width'      => $cols,
    'bit_depth'  => 1,
    'color_type' => PNG_COLOR_TYPE_GRAY,
} );
$png->write_info;

my @rows;
for my $x ( 0 .. $rows - 1 ) {
    my $row = '';
    for my $y ( 0 .. $cols - 1 ) {
        my $idx = $x * $rows + $y;
        my $value = $bits[ $idx ];
        $row .= $value;
    }
    push @rows, pack( 'B*', $row );
}
$png->write_image( \@rows );
$png->write_end;

exit;
Source Link
AKHolland
  • 4.5k
  • 25
  • 36

Script 1: Text Decoder

#!/usr/bin/perl

use strict;
use warnings;

use Image::PNG::Libpng ':all';

my $HEADER_SIZE = 2;
my $LENGTH_SIZE = 16;

my $png = create_read_struct();
open my $if, '<:raw', shift or die $!;
$png->init_io( $if );
$png->read_png;
$if->close;

my @bits;
for my $row ( $png->get_rows->@* ) {
    while ( $row ) {
        my ( $r, $g, $b ) = map { ord } unpack( 'aaa', $row );
        push @bits, $r & 1,
                    $g & 1,
                    $b & 1;
        $row = substr $row, 3;
    }
}

my $header;
$header += shift @bits for 1 .. $HEADER_SIZE;
if ( $header != 0 ) {
    die "invalid header";
}

my $length = 0;
for my $pos ( 1 .. $LENGTH_SIZE ) {
    my $bit = shift @bits;
    my $value = $bit << $LENGTH_SIZE - $pos;
    $length += $value;
}
print "length: $length\n";
print "==========\n";

for ( 1 .. $length / 8 ) {
    my $byte = 0;
    my $pos = 1;
    for my $bit ( splice @bits, 0, 8 ) {
        my $value = $bit << 8 - $pos;
        $byte += $value;
        $pos ++;
    }
    print chr( $byte );
}
print "\n";
print "==========\n";

exit;

Script 2: Image Decoder

#!/usr/bin/perl

use strict;
use warnings;

use Image::PNG::Libpng ':all';
use Image::PNG::Const ':all';

my $HEADER_SIZE = 2;
my $ROWS_SIZE = 16;
my $COLS_SIZE = 16;

my $png = create_read_struct();
open my $if, '<:raw', shift or die $!;
$png->init_io( $if );
$png->read_png;
$if->close;

my @bits;
for my $row ( $png->get_rows->@* ) {
    while ( $row ) {
        my ( $r, $g, $b ) = map { ord } unpack( 'aaa', $row );
        push @bits, $r & 1,
                    $g & 1,
                    $b & 1;
        $row = substr $row, 3;
    }
}

my $header = '';
$header .= shift @bits for 1 .. $HEADER_SIZE;
if ( $header ne '10' ) {
    print "invalid header";
    exit 1;
}

my $rows = 0;
for my $pos ( 1 .. $ROWS_SIZE ) {
    my $bit = shift @bits;
    my $value = $bit << $ROWS_SIZE - $pos;
    $rows += $value;
}
print "rows: $rows\n";

my $cols = 0;
for my $pos ( 1 .. $COLS_SIZE ) {
    my $bit = shift @bits;
    my $value = $bit << $COLS_SIZE - $pos;
    $cols += $value;
}
print "cols: $rows\n";
print "==========\n";

$png = create_write_struct();
open my $of, '>:raw', 'out.png';
$png->init_io( $of );
$png->set_IHDR( {
    'height'     => $rows,
    'width'      => $cols,
    'bit_depth'  => 1,
    'color_type' => PNG_COLOR_TYPE_GRAY,
} );
$png->write_info;

my @rows;
for my $x ( 0 .. $rows - 1 ) {
    my $row = '';
    for my $y ( 0 .. $cols - 1 ) {
        my $idx = $x * $rows + $y;
        my $value = $bits[ $idx ];
        $row .= $value;
    }
    push @rows, pack 'B*', $row;
}
$png->write_image( \@rows );
$png->write_end;

exit;

Answer 1: "Three may keep a secret, if two of them are dead." Benjamin Franklin
Answer 2: A key (and a kite).

At first I tried to do the image decoder by having something like if ( $bit ) print "X" else print " ", opening it in a text editor, and zooming out to create hi-res ASCII art. And this almost worked, I could tell what the image was but couldn't read the text. Otherwise libpng made this pretty simple. Took a couple tries to get the binary row format down.