Acme-Steganography-Image-Png
view release on metacpan or search on metacpan
package Acme::Steganography::Image::Png::RGB;
use vars '@ISA';
@ISA = 'Acme::Steganography::Image::Png';
# Raw data in the low bits of a colour image
sub write_images {
my $self = shift;
my $victim = shift;
my $img;
if (ref($victim) && $victim->isa('Imager')) {
$img = $victim;
} else {
$img = new Imager;
$img->open(file=>$victim, type=>'jpeg') or croak($img->errstr);
}
$self->x($img->getwidth());
$self->y($img->getheight());
my $raw;
$img->write(data=> \$raw, type => 'raw')
or croak($img->errstr);
$self->raw($raw);
$self->SUPER::write_images;
}
package Acme::Steganography::Image::Png;
sub generate_next_image {
my ($self) = shift;
my $datum = $self->generate_header;
my $offset = $self->offset;
my $datum_length = $self->datum_length;
# Fill our blob of data to the correct length
my $grab = $datum_length - length $datum;
$datum .= substr ${$self->data()}, $offset, $grab;
$self->offset($offset + $grab);
if (length $datum < $datum_length) {
# Need to pad it. NUL is so uninspiring.
$datum .= "N" x ($datum_length - length $datum);
$self->done(1);
} elsif (length ${$self->data()} == $self->offset) {
warn length $datum;
}
$self->section($self->section + 1);
$self->make_image($datum);
}
sub new {
my $class = shift;
croak "Use a classname, not a reference for " . __PACKAGE__ . "::new"
if ref $class;
my $self = bless {}, $class;
my %args = @_;
my $acceptable = $self->_keys();
foreach (keys %args) {
croak "Unknown parameter $_" unless exists $acceptable->{$_};
$self->set($_, $args{$_});
}
$self->x(352) unless $args{x};
$self->y(288) unless $args{y};
# Kowtow to the metadata bodging into filenames world
$self->suffix('.png');
$self;
}
sub type {
'png';
}
sub write_images {
my $self = shift;
$self->section(0);
$self->offset(0);
$self->datum_length($self->calculate_datum_length());
my $type = $self->type;
my $filename_generator
= $self->filename_generator || \&default_filename_generator;
my @filenames;
my ($filename, $state);
while (!$self->done()) {
my $image = $self->generate_next_image;
($filename, $state) = &$filename_generator($state);
$filename .= $self->suffix;
$image->write(file => $filename, type=> $type);
push @filenames, $filename;
}
@filenames;
}
# package method
sub read_files {
my $class = shift;
# This is intentionally a "sparse" array to avoid some "interesting" DOS
# possibilities.
my $length;
my %got;
foreach my $file (@_) {
my $img = new Imager;
$img->open(file => $file) or carp "Can't read '$file': " . $img->errstr;
my $payload = $class->extract_payload($img);
my $datum;
my $section;
($section, $datum) = unpack "wa*", $payload;
if ($section == 0) {
# Oops. Strip off the length.
($length, $datum) = unpack "wa*", $datum;
}
$got{$section} = $datum;
( run in 1.365 second using v1.01-cache-2.11-cpan-524268b4103 )