#!/usr/bin/perl

# wstaw( $wiadomosc, \&piksel_wej, \&piksel_wyj )
#    Wstawia poszczegolne bity wiadomosci do strumienia pikseli.
#    Jesli nie podano wartosci piksel_wej i piksel_wyj, to program
#    ustawia je domyslnie na stdin (odczyt) i stdout (zapis).  Piksel
#    to 3 skalarne wartosci o precyzji 16-bitowej dla kolorow czerwonego,
#    zielonego i niebieskiego.
sub wstaw {
    my $wiadomosc = shift;
    my $piksel_wej = shift || \&stdinpixel;
    my $piksel_wyj = shift || \&stdoutpixel;

    my $liczba_bitow = 8 * length( $wiadomosc );
    my $aktualny_bit = 0;
    my ( @piksel );

    while ( @piksel = \&piksel_wej ) {
        if ( $aktualny_bit < $liczba_bitow ) {
            for $j (0..2) {
                if ( vec( $wiadomosc, $aktualny_bit++, 1 ) ) {
                    $piksel[$j] |= 1;
                } else {
                    $piksel[$j] &= 65534;
                }
            }
        }
        &$piksel_wyj( @piksel );
    }
}

# $wiadomosc = odczytaj( \&piksel_wej )
#    Odczytuje wiadomosc ze strumienia pikseli.
#    Jesli nie podano wartosci getpixel, to do odczytu domyslnie uzywany jest stdin.
sub odczytaj {
    my $piksel_wej = shift || \&stdinpixel;
    my $wiadomosc;
    my $aktualny_bit = 0;
    my @piksel;

    while ( @piksel = &$piksel_wej ) {
        for $j (0..2) {
            if ( $piksel[$j] & 1 ) {
                vec( $wiadomosc, $aktualny_bit, 1 ) = 1;
            }
            ++$aktualny_bit;
        }
    }
}

sub stdinpixel {
    my $wejscie;
    read STDIN, $wejscie, 6 or return ();

    unpack "n3", $wejscie;
}

sub stdoutpixel {
    my $wyjscie = pack "n3", @_;
    print STDOUT $wyjscie;
}

