| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Image::TextMode::Reader::IDF; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 2 |  |  | 2 |  | 1320 | use Moo; | 
|  | 2 |  |  |  |  | 4 |  | 
|  | 2 |  |  |  |  | 16 |  | 
| 4 |  |  |  |  |  |  |  | 
| 5 |  |  |  |  |  |  | extends 'Image::TextMode::Reader'; | 
| 6 |  |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  | my $header_template = 'A4 v v v v'; | 
| 8 |  |  |  |  |  |  | my @header_fields   = qw( id x0 y0 x1 y1 ); | 
| 9 |  |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  | sub _read { | 
| 11 | 3 |  |  | 3 |  | 8 | my ( $self, $image, $fh, $options ) = @_; | 
| 12 |  |  |  |  |  |  |  | 
| 13 | 3 |  |  |  |  | 4 | my $buffer; | 
| 14 | 3 |  |  |  |  | 33 | read( $fh, $buffer, 12 ); | 
| 15 |  |  |  |  |  |  |  | 
| 16 | 3 |  |  |  |  | 5 | my %header; | 
| 17 | 3 |  |  |  |  | 38 | @header{ @header_fields } = unpack( $header_template, $buffer ); | 
| 18 |  |  |  |  |  |  |  | 
| 19 | 3 |  |  |  |  | 31 | $image->header( \%header ); | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | # font and palette data are stored at the bottom of the file | 
| 22 | 3 |  |  |  |  | 1633 | seek( $fh, -48 - 4096, 2 ); | 
| 23 | 3 | 50 |  |  |  | 91 | if ( $image->has_sauce ) { | 
| 24 | 0 |  |  |  |  | 0 | my $s = $image->sauce; | 
| 25 | 0 | 0 |  |  |  | 0 | seek( $fh, -129 - ( $s->comment_count ? 5 + 64 * $s->comment_count : 0 ), 1 ); | 
| 26 |  |  |  |  |  |  | } | 
| 27 |  |  |  |  |  |  |  | 
| 28 | 3 |  |  |  |  | 181 | my $max = tell( $fh ); | 
| 29 |  |  |  |  |  |  |  | 
| 30 | 3 |  |  |  |  | 38 | read( $fh, $buffer, 4096 ); | 
| 31 | 3 |  |  |  |  | 14 | _parse_font( $image, $buffer ); | 
| 32 |  |  |  |  |  |  |  | 
| 33 | 3 |  |  |  |  | 8477 | read( $fh, $buffer, 48 ); | 
| 34 | 3 |  |  |  |  | 21 | _parse_palette( $image, $buffer ); | 
| 35 |  |  |  |  |  |  |  | 
| 36 | 3 |  |  |  |  | 5906 | seek( $fh, 12, 0 ); | 
| 37 | 3 |  |  |  |  | 12 | my ( $x, $y ) = ( 0, 0 ); | 
| 38 | 3 |  |  |  |  | 91 | my $width = $image->header->{ x1 }; | 
| 39 | 3 |  |  |  |  | 41 | while ( tell $fh < $max ) { | 
| 40 | 92 |  |  |  |  | 193 | read( $fh, $buffer, 2 ); | 
| 41 | 92 |  |  |  |  | 174 | my $info = unpack( 'v', $buffer ); | 
| 42 |  |  |  |  |  |  |  | 
| 43 | 92 |  |  |  |  | 82 | my $len = 1; | 
| 44 | 92 | 100 |  |  |  | 162 | if ( $info == 1 ) { | 
| 45 | 2 |  |  |  |  | 8 | read( $fh, $info, 2 ); | 
| 46 | 2 |  |  |  |  | 8 | $len = unpack( 'v', $info ) & 255; | 
| 47 | 2 |  |  |  |  | 6 | read( $fh, $buffer, 2 ); | 
| 48 |  |  |  |  |  |  | } | 
| 49 |  |  |  |  |  |  |  | 
| 50 | 92 |  |  |  |  | 221 | my @data = unpack( 'aC', $buffer ); | 
| 51 | 92 |  |  |  |  | 136 | for ( 1 .. $len ) { | 
| 52 | 240 |  |  |  |  | 1017 | $image->putpixel( { char => $data[ 0 ], attr => $data[ 1 ] }, | 
| 53 |  |  |  |  |  |  | $x, $y ); | 
| 54 | 240 |  |  |  |  | 10987 | $x++; | 
| 55 | 240 | 100 |  |  |  | 777 | if ( $x > $width ) { | 
| 56 | 3 |  |  |  |  | 7 | $x = 0; | 
| 57 | 3 |  |  |  |  | 18 | $y++; | 
| 58 |  |  |  |  |  |  | } | 
| 59 |  |  |  |  |  |  | } | 
| 60 |  |  |  |  |  |  | } | 
| 61 |  |  |  |  |  |  |  | 
| 62 | 3 |  |  |  |  | 116 | return $image; | 
| 63 |  |  |  |  |  |  | } | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | sub _parse_palette { | 
| 66 | 3 |  |  | 3 |  | 13 | my ( $image, $data ) = @_; | 
| 67 |  |  |  |  |  |  |  | 
| 68 | 3 |  |  |  |  | 39 | my @pal = unpack( 'C*', $data ); | 
| 69 | 3 |  |  |  |  | 8 | my @colors; | 
| 70 | 3 |  |  |  |  | 13 | for ( 0 .. 15 ) { | 
| 71 | 48 |  |  |  |  | 50 | my $offset = $_ * 3; | 
| 72 | 48 |  |  |  |  | 74 | push @colors, [ map { $_ << 2 | $_ >> 4 } @pal[ $offset .. $offset + 2 ] ],; | 
|  | 144 |  |  |  |  | 255 |  | 
| 73 |  |  |  |  |  |  | } | 
| 74 |  |  |  |  |  |  |  | 
| 75 |  |  |  |  |  |  | $image->palette( | 
| 76 | 3 |  |  |  |  | 102 | Image::TextMode::Palette->new( { colors => \@colors } ) ); | 
| 77 |  |  |  |  |  |  | } | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | sub _parse_font { | 
| 80 | 3 |  |  | 3 |  | 8 | my ( $image, $data ) = @_; | 
| 81 | 3 |  |  |  |  | 7 | my $height = 16; | 
| 82 | 3 |  |  |  |  | 4 | my @chars; | 
| 83 |  |  |  |  |  |  |  | 
| 84 | 3 |  |  |  |  | 21 | for ( 0 .. ( length( $data ) / $height ) - 1 ) { | 
| 85 | 768 |  |  |  |  | 2770 | push @chars, | 
| 86 |  |  |  |  |  |  | [ unpack( 'C*', substr( $data, $_ * $height, $height ) ) ]; | 
| 87 |  |  |  |  |  |  | } | 
| 88 |  |  |  |  |  |  |  | 
| 89 |  |  |  |  |  |  | $image->font( | 
| 90 | 3 |  |  |  |  | 91 | Image::TextMode::Font->new( | 
| 91 |  |  |  |  |  |  | {   width  => 8, | 
| 92 |  |  |  |  |  |  | height => $height, | 
| 93 |  |  |  |  |  |  | chars  => \@chars, | 
| 94 |  |  |  |  |  |  | } | 
| 95 |  |  |  |  |  |  | ) | 
| 96 |  |  |  |  |  |  | ); | 
| 97 |  |  |  |  |  |  | } | 
| 98 |  |  |  |  |  |  |  | 
| 99 |  |  |  |  |  |  | =head1 NAME | 
| 100 |  |  |  |  |  |  |  | 
| 101 |  |  |  |  |  |  | Image::TextMode::Reader::IDF - Reads IDF files | 
| 102 |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 104 |  |  |  |  |  |  |  | 
| 105 |  |  |  |  |  |  | Provides reading capabilities for the IDF format. | 
| 106 |  |  |  |  |  |  |  | 
| 107 |  |  |  |  |  |  | =head1 AUTHOR | 
| 108 |  |  |  |  |  |  |  | 
| 109 |  |  |  |  |  |  | Brian Cassidy Ebricas@cpan.orgE | 
| 110 |  |  |  |  |  |  |  | 
| 111 |  |  |  |  |  |  | =head1 COPYRIGHT AND LICENSE | 
| 112 |  |  |  |  |  |  |  | 
| 113 |  |  |  |  |  |  | Copyright 2008-2015 by Brian Cassidy | 
| 114 |  |  |  |  |  |  |  | 
| 115 |  |  |  |  |  |  | This library is free software; you can redistribute it and/or modify | 
| 116 |  |  |  |  |  |  | it under the same terms as Perl itself. | 
| 117 |  |  |  |  |  |  |  | 
| 118 |  |  |  |  |  |  | =cut | 
| 119 |  |  |  |  |  |  |  | 
| 120 |  |  |  |  |  |  | 1; |