+ok($ooim->read(file=>"testimg/simple.pbm"), "read simple pbm, via OO");
+
+check_gray(Imager::i_get_pixel($ooim->{IMG}, 0, 0), 0);
+check_gray(Imager::i_get_pixel($ooim->{IMG}, 0, 1), 255);
+check_gray(Imager::i_get_pixel($ooim->{IMG}, 1, 0), 255);
+check_gray(Imager::i_get_pixel($ooim->{IMG}, 1, 1), 0);
+is($ooim->type, 'paletted', "check pbm read as paletted");
+is($ooim->tags(name=>'pnm_type'), 1, "check pnm_type tag");
+
+{
+ # https://rt.cpan.org/Ticket/Display.html?id=7465
+ # the pnm reader ignores the maxval that it reads from the pnm file
+ my $maxval = Imager->new;
+ ok($maxval->read(file=>"testimg/maxval.ppm"),
+ "read testimg/maxval.ppm");
+
+ # this image contains three pixels, with each sample from 0 to 63
+ # the pixels are (63, 63, 63), (32, 32, 32) and (31, 31, 0)
+
+ # check basic parameters
+ is($maxval->getchannels, 3, "channel count");
+ is($maxval->getwidth, 3, "width");
+ is($maxval->getheight, 1, "height");
+
+ # check the pixels
+ ok(my ($white, $grey, $green) = $maxval->getpixel('x'=>[0,1,2], 'y'=>[0,0,0]), "fetch pixels");
+ is_color3($white, 255, 255, 255, "white pixel");
+ is_color3($grey, 130, 130, 130, "grey pixel");
+ is_color3($green, 125, 125, 0, "green pixel");
+ is($maxval->tags(name=>'pnm_type'), 6, "check pnm_type tag on maxval");
+
+ # and do the same for ASCII images
+ my $maxval_asc = Imager->new;
+ ok($maxval_asc->read(file=>"testimg/maxval_asc.ppm"),
+ "read testimg/maxval_asc.ppm");
+
+ # this image contains three pixels, with each sample from 0 to 63
+ # the pixels are (63, 63, 63), (32, 32, 32) and (31, 31, 0)
+
+ # check basic parameters
+ is($maxval_asc->getchannels, 3, "channel count");
+ is($maxval_asc->getwidth, 3, "width");
+ is($maxval_asc->getheight, 1, "height");
+
+ is($maxval->tags(name=>'pnm_type'), 6, "check pnm_type tag on maxval");
+
+ # check the pixels
+ ok(my ($white_asc, $grey_asc, $green_asc) = $maxval_asc->getpixel('x'=>[0,1,2], 'y'=>[0,0,0]), "fetch pixels");
+ is_color3($white_asc, 255, 255, 255, "white asc pixel");
+ is_color3($grey_asc, 130, 130, 130, "grey asc pixel");
+ is_color3($green_asc, 125, 125, 0, "green asc pixel");
+}
+
+{ # previously we didn't validate maxval at all, make sure it's
+ # validated now
+ my $maxval0 = Imager->new;
+ ok(!$maxval0->read(file=>'testimg/maxval_0.ppm'),
+ "should fail to read maxval 0 image");
+ print "# ", $maxval0->errstr, "\n";
+ like($maxval0->errstr, qr/maxval is zero - invalid pnm file/,
+ "error expected from reading maxval_0.ppm");
+
+ my $maxval65536 = Imager->new;
+ ok(!$maxval65536->read(file=>'testimg/maxval_65536.ppm'),
+ "should fail reading maxval 65536 image");
+ print "# ",$maxval65536->errstr, "\n";
+ like($maxval65536->errstr, qr/maxval of 65536 is over 65535 - invalid pnm file/,
+ "error expected from reading maxval_65536.ppm");
+
+ # maxval of 256 is valid, and handled as of 0.56
+ my $maxval256 = Imager->new;
+ ok($maxval256->read(file=>'testimg/maxval_256.ppm'),
+ "should succeed reading maxval 256 image");
+ is_color3($maxval256->getpixel(x => 0, 'y' => 0),
+ 0, 0, 0, "check black in maxval_256");
+ is_color3($maxval256->getpixel(x => 0, 'y' => 1),
+ 255, 255, 255, "check white in maxval_256");
+ is($maxval256->bits, 16, "check bits/sample on maxval 256");
+
+ # make sure we handle maxval > 255 for ascii
+ my $maxval4095asc = Imager->new;
+ ok($maxval4095asc->read(file=>'testimg/maxval_4095_asc.ppm'),
+ "read maxval_4095_asc.ppm");
+ is($maxval4095asc->getchannels, 3, "channels");
+ is($maxval4095asc->getwidth, 3, "width");
+ is($maxval4095asc->getheight, 1, "height");
+ is($maxval4095asc->bits, 16, "check bits/sample on maxval 4095");
+
+ ok(my ($white, $grey, $green) = $maxval4095asc->getpixel('x'=>[0,1,2], 'y'=>[0,0,0]), "fetch pixels");
+ is_color3($white, 255, 255, 255, "white 4095 pixel");
+ is_color3($grey, 128, 128, 128, "grey 4095 pixel");
+ is_color3($green, 127, 127, 0, "green 4095 pixel");
+}
+
+{ # check i_format is set when reading a pnm file
+ # doesn't really matter which file.
+ my $maxval = Imager->new;
+ ok($maxval->read(file=>"testimg/maxval.ppm"),
+ "read test file");
+ my ($type) = $maxval->tags(name=>'i_format');
+ is($type, 'pnm', "check i_format");
+}
+
+{ # check file limits are checked
+ my $limit_file = "testout/t104.ppm";
+ ok(Imager->set_file_limits(reset=>1, width=>149), "set width limit 149");
+ my $im = Imager->new;
+ ok(!$im->read(file=>$limit_file),
+ "should fail read due to size limits");
+ print "# ",$im->errstr,"\n";
+ like($im->errstr, qr/image width/, "check message");
+
+ ok(Imager->set_file_limits(reset=>1, height=>149), "set height limit 149");
+ ok(!$im->read(file=>$limit_file),
+ "should fail read due to size limits");
+ print "# ",$im->errstr,"\n";
+ like($im->errstr, qr/image height/, "check message");
+
+ ok(Imager->set_file_limits(reset=>1, width=>150), "set width limit 150");
+ ok($im->read(file=>$limit_file),
+ "should succeed - just inside width limit");
+ ok(Imager->set_file_limits(reset=>1, height=>150), "set height limit 150");
+ ok($im->read(file=>$limit_file),
+ "should succeed - just inside height limit");
+
+ # 150 x 150 x 3 channel image uses 67500 bytes
+ ok(Imager->set_file_limits(reset=>1, bytes=>67499),
+ "set bytes limit 67499");
+ ok(!$im->read(file=>$limit_file),
+ "should fail - too many bytes");
+ print "# ",$im->errstr,"\n";
+ like($im->errstr, qr/storage size/, "check error message");
+ ok(Imager->set_file_limits(reset=>1, bytes=>67500),
+ "set bytes limit 67500");
+ ok($im->read(file=>$limit_file),
+ "should succeed - just inside bytes limit");
+ Imager->set_file_limits(reset=>1);
+}
+
+{
+ # check we correctly sync with the data stream
+ my $im = Imager->new;
+ ok($im->read(file => 'testimg/pgm.pgm', type => 'pnm'),
+ "read pgm.pgm")
+ or print "# cannot read pgm.pgm: ", $im->errstr, "\n";
+ print "# ", $im->getsamples('y' => 0), "\n";
+ is_color1($im->getpixel(x=>0, 'y' => 0), 254, "check top left");
+}
+
+{ # check error messages set correctly
+ my $im = Imager->new(xsize=>100, ysize=>100, channels=>4);
+ ok(!$im->write(file=>"testout/t104_fail.ppm", type=>'pnm'),
+ "should fail to write 4 channel image");
+ is($im->errstr, 'can only save 1 or 3 channel images to pnm',
+ "check error message");
+ ok(!$im->read(file=>'t/t104ppm.t', type=>'pnm'),
+ 'should fail to read script as an image file');
+ is($im->errstr, 'unable to read pnm image: bad header magic, not a PNM file',
+ "check error message");
+}
+
+# various bad input files
+print "# check error handling\n";
+{
+ my $im = Imager->new;
+ ok(!$im->read(file => 'testimg/short_bin.ppm', type=>'pnm'),
+ "fail to read short bin ppm");
+ cmp_ok($im->errstr, '=~', 'short read - file truncated',
+ "check error message");
+}
+
+{
+ my $im = Imager->new;
+ ok(!$im->read(file => 'testimg/short_bin16.ppm', type=>'pnm'),
+ "fail to read short bin ppm (maxval 65535)");
+ cmp_ok($im->errstr, '=~', 'short read - file truncated',
+ "check error message");
+}
+
+{
+ my $im = Imager->new;
+ ok(!$im->read(file => 'testimg/short_bin.pgm', type=>'pnm'),
+ "fail to read short bin pgm");
+ cmp_ok($im->errstr, '=~', 'short read - file truncated',
+ "check error message");
+}
+
+{
+ my $im = Imager->new;
+ ok(!$im->read(file => 'testimg/short_bin16.pgm', type=>'pnm'),
+ "fail to read short bin pgm (maxval 65535)");
+ cmp_ok($im->errstr, '=~', 'short read - file truncated',
+ "check error message");
+}
+
+{
+ my $im = Imager->new;
+ ok(!$im->read(file => 'testimg/short_bin.pbm', type => 'pnm'),
+ "fail to read a short bin pbm");
+ cmp_ok($im->errstr, '=~', 'short read - file truncated',
+ "check error message");
+}
+
+{
+ my $im = Imager->new;
+ ok(!$im->read(file => 'testimg/short_asc.ppm', type => 'pnm'),
+ "fail to read a short asc ppm");
+ cmp_ok($im->errstr, '=~', 'short read - file truncated',
+ "check error message");
+}