recreate project
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Mike42\GfxPhp\Codec\Bmp;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class BmpBitfieldDecoderTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* Decode various 16-bit pixels with the default 5-5-5 bit depths
|
||||
*/
|
||||
public function testReadDefaults()
|
||||
{
|
||||
// 5-5-5, little-endian encoded as 2 bytes.
|
||||
$decoder = new BmpBitfieldDecoder(BmpColorBitfield::from16bitDefaults());
|
||||
$this -> assertEquals([0, 0, 0], $decoder -> read16bit([0x00, 0x00])); // Black
|
||||
$this -> assertEquals([0, 0, 0], $decoder -> read16bit([0x00, 0x80])); // Also black (MSB ignored)
|
||||
$this -> assertEquals([255, 255, 255], $decoder -> read16bit([0xff, 0xff])); // White
|
||||
$this -> assertEquals([0, 0, 255], $decoder -> read16bit([0x1f, 0])); // Blue
|
||||
$this -> assertEquals([0, 255, 0], $decoder -> read16bit([0xe0, 0x03])); // Green
|
||||
$this -> assertEquals([255, 0, 0], $decoder -> read16bit([0x00, 0x7c])); // Red
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace Mike42\GfxPhp\Codec\Bmp;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class BmpColorMaskTest extends TestCase
|
||||
{
|
||||
public function testEmpty() {
|
||||
$mask = new BmpColorMask(0x00); // 00000000
|
||||
$this -> assertEquals(0, $mask -> getLen());
|
||||
$this -> assertEquals(0, $mask -> getOffset());
|
||||
$this -> assertEquals(0, $mask -> getMaxValue());
|
||||
$this -> assertEquals(0, $mask -> getValue(0xFF));
|
||||
$this -> assertEquals(0, $mask -> getNormalisedValue(0xFF));
|
||||
}
|
||||
|
||||
public function testOne() {
|
||||
$mask = new BmpColorMask(0x01); // 00000001
|
||||
$this -> assertEquals(1, $mask -> getLen());
|
||||
$this -> assertEquals(0, $mask -> getOffset());
|
||||
$this -> assertEquals(1, $mask -> getMaxValue());
|
||||
// Regular
|
||||
$this -> assertEquals(0, $mask -> getValue(0xFE)); // 11111110
|
||||
$this -> assertEquals(1, $mask -> getValue(0x01)); // 00000001
|
||||
// Normalised
|
||||
$this -> assertEquals(0, $mask -> getNormalisedValue(0xFE));
|
||||
$this -> assertEquals(255, $mask -> getNormalisedValue(0x01));
|
||||
}
|
||||
|
||||
public function testOffset() {
|
||||
$mask = new BmpColorMask(0x10); // 00010000
|
||||
$this -> assertEquals(1, $mask -> getLen());
|
||||
$this -> assertEquals(4, $mask -> getOffset());
|
||||
$this -> assertEquals(1, $mask -> getMaxValue());
|
||||
// Regular
|
||||
$this -> assertEquals(0, $mask -> getValue(0xEF)); // 11101111
|
||||
$this -> assertEquals(1, $mask -> getValue(0x10)); // 00010000
|
||||
// Normalised
|
||||
$this -> assertEquals(0, $mask -> getNormalisedValue(0xEF));
|
||||
$this -> assertEquals(255, $mask -> getNormalisedValue(0x10));
|
||||
}
|
||||
|
||||
public function testLength() {
|
||||
$mask = new BmpColorMask(0x30); // 00110000
|
||||
$this -> assertEquals(2, $mask -> getLen());
|
||||
$this -> assertEquals(4, $mask -> getOffset());
|
||||
$this -> assertEquals(3, $mask -> getMaxValue());
|
||||
// Regular
|
||||
$this -> assertEquals(0, $mask -> getValue(0xCF)); // 11001111
|
||||
$this -> assertEquals(2, $mask -> getValue(0x20)); // 00100000 -> 10
|
||||
$this -> assertEquals(3, $mask -> getValue(0x30)); // 00110000
|
||||
// Normalised
|
||||
$this -> assertEquals(0, $mask -> getNormalisedValue(0xCF));
|
||||
$this -> assertEquals(170, $mask -> getNormalisedValue(0x20)); // 10 in binary shifted then repeated to use full space.
|
||||
$this -> assertEquals(255, $mask -> getNormalisedValue(0x30));
|
||||
}
|
||||
|
||||
public function testLarge() {
|
||||
$mask = new BmpColorMask(0x03FF); // 00000011 11111111
|
||||
$this -> assertEquals(10, $mask -> getLen());
|
||||
$this -> assertEquals(0, $mask -> getOffset());
|
||||
$this -> assertEquals(1023, $mask -> getMaxValue());
|
||||
// Regular
|
||||
$this -> assertEquals(0, $mask -> getValue(0x0000));
|
||||
$this -> assertEquals(511, $mask -> getValue(0x01FF));
|
||||
$this -> assertEquals(1023, $mask -> getValue(0x03FF));
|
||||
// Normalised - note how raw value is scaled down this time
|
||||
$this -> assertEquals(0, $mask -> getNormalisedValue(0x0000));
|
||||
$this -> assertEquals(127, $mask -> getNormalisedValue(0x01FF));
|
||||
$this -> assertEquals(255, $mask -> getNormalisedValue(0x03FF));
|
||||
}
|
||||
|
||||
public function testNonContiguous() {
|
||||
$this -> expectException(\Exception::class);
|
||||
$mask = new BmpColorMask(0x50); // 01010000
|
||||
$this -> assertEquals(3, $mask -> getLen());
|
||||
$this -> assertEquals(4, $mask -> getOffset());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
use Mike42\GfxPhp\Codec\BmpCodec;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Mike42\GfxPhp\RgbRasterImage;
|
||||
|
||||
class BmpCodecTest extends TestCase
|
||||
{
|
||||
|
||||
const BMP_IMAGE = "BM:\x00\x00\x00\x00\x00\x00\x006\x00\x00\x00(\x00\x00" .
|
||||
"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x18\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01".
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff" .
|
||||
"\xff\x00";
|
||||
|
||||
public function testBmpEncode()
|
||||
{
|
||||
$encoder = new BmpCodec();
|
||||
$image = RgbRasterImage::create(1, 1);
|
||||
$imageStr = $encoder -> encode($image, 'bmp');
|
||||
$this -> assertEquals(self::BMP_IMAGE, $imageStr);
|
||||
}
|
||||
|
||||
public function testBmpDecode()
|
||||
{
|
||||
$decoder = new BmpCodec();
|
||||
$image = $decoder -> decode(self::BMP_IMAGE);
|
||||
$this -> assertEquals(1, $image -> getWidth());
|
||||
$this -> assertEquals(1, $image -> getHeight());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Mike42\GfxPhp\Codec\GifCodec;
|
||||
use Mike42\GfxPhp\IndexedRasterImage;
|
||||
|
||||
class GifCodecTest extends TestCase
|
||||
{
|
||||
/*
|
||||
* 1px by 1px white image, with a one white value and the remainder of the
|
||||
* 256-color palette filled with black.
|
||||
*/
|
||||
const GIF_IMAGE = "GIF89a\x01\x00\x01\x00\xf7\x00\x00\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!\xf9" .
|
||||
"\x04\x01\x00\x00\xff\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x08\x04\x00" .
|
||||
"\x01\x04\x04\x00;";
|
||||
|
||||
public function testGifEncode() {
|
||||
$encoder = new GifCodec();
|
||||
$image = IndexedRasterImage::create(1, 1);
|
||||
$image -> setTransparentColor(255);
|
||||
$imageStr = $encoder -> encode($image, 'gif');
|
||||
$this -> assertEquals(self::GIF_IMAGE, $imageStr);
|
||||
}
|
||||
|
||||
public function testGifDecode() {
|
||||
$decoder = new GifCodec();
|
||||
$image = $decoder -> decode(self::GIF_IMAGE, 'gif') -> toIndexed();
|
||||
$this -> assertEquals(1, $image -> getWidth());
|
||||
$this -> assertEquals(1, $image -> getHeight());
|
||||
$this -> assertEquals([255, 255, 255], $image -> indexToRgb($image -> getPixel(0, 0)));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
use Mike42\GfxPhp\Image;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Mike42\GfxPhp\RgbRasterImage;
|
||||
use Mike42\GfxPhp\Codec\PngCodec;
|
||||
|
||||
class PngCodecTest extends TestCase
|
||||
{
|
||||
// Example file that we compare encoder results against, and decode.
|
||||
const SMALL_FILE = "\x89PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90wS\xde\x00\x00\x00\x0cIDATx\x9cc\xf8\xff\xff?\x00\x05\xfe\x02\xfe\x0d\xefF\xb8\x00\x00\x00\x00IEND\xaeB`\x82";
|
||||
|
||||
public function testEncode() {
|
||||
// Simplest image I can come up with
|
||||
$img = RgbRasterImage::create(1, 1);
|
||||
$codec = new PngCodec();
|
||||
// Encode
|
||||
$pngStr = $codec -> encode($img, "png");
|
||||
// Compare to known-good PNG
|
||||
$this -> assertEquals(self::SMALL_FILE, $pngStr);
|
||||
}
|
||||
|
||||
public function testDecode() {
|
||||
$codec = new PngCodec();
|
||||
$img = $codec -> decode(self::SMALL_FILE);
|
||||
$this -> assertTrue($img instanceof RgbRasterImage);
|
||||
$this -> assertEquals(1, $img -> getWidth());
|
||||
$this -> assertEquals(1, $img -> getHeight());
|
||||
}
|
||||
|
||||
public function testBlackAndWhiteImageLoad() {
|
||||
// Simple test of a black-and-white, interlaced & non-interlaced image, since
|
||||
// we can do a text-based assertion on the actual image content.
|
||||
$expected = " ▄█\n" .
|
||||
" ▄███\n" .
|
||||
" ██ ██ ▄█████\n" .
|
||||
" ██ ▄▄ ██ ▄███████\n" .
|
||||
" ██ ██ ██ ▄█████████\n" .
|
||||
" ████████ ▄███████████\n" .
|
||||
" ██ ██ ▄█████████████\n" .
|
||||
" ▄███████████████\n" .
|
||||
" ▄█████████████████\n" .
|
||||
" ▄███████ █████\n" .
|
||||
" ▄█████████ ████ ████\n" .
|
||||
" ▄███████████ █████\n" .
|
||||
" ▄█████████████ ████ ████\n" .
|
||||
" ▄███████████████ █████\n" .
|
||||
" ▄█████████████████████████████\n" .
|
||||
"▄███████████████████████████████\n";
|
||||
// Load interlaced & non-interlaced
|
||||
$interlacedImage = Image::fromFile(__DIR__ . "/../../resources/pngsuite/basi0g01.png");
|
||||
$interlacedResult = $interlacedImage -> toString();
|
||||
$nonInterlacedImage = Image::fromFile(__DIR__ . "/../../resources/pngsuite/basn0g01.png");
|
||||
$nonInterlacedResult = $nonInterlacedImage -> toString();
|
||||
// These should both match the expected output
|
||||
$this -> assertEquals($expected, $interlacedResult);
|
||||
$this -> assertEquals($expected, $nonInterlacedResult);
|
||||
}
|
||||
|
||||
public function testIndexedImageLoad() {
|
||||
// Load an interlaced 8-bit image, which follows a very different code path to
|
||||
// lower bit depths.
|
||||
$img = Image::fromFile(__DIR__ . "/../../resources/pngsuite/basi3p08.png") -> toIndexed();
|
||||
$this -> assertEquals(255, $img -> getMaxVal());
|
||||
$this -> assertEquals(32, $img -> getWidth());
|
||||
$this -> assertEquals(32, $img -> getHeight());
|
||||
}
|
||||
|
||||
public function testFiltering() {
|
||||
// Expected value is sensitive to the grayscale -> B&W conversion
|
||||
$expected = "████████████████████████████████\n" .
|
||||
"███████████▀▀▀▀▀▀▀▀▀▀███████████\n" .
|
||||
"████████▀ ▀████████\n" .
|
||||
"██████▀ ▀██████\n" .
|
||||
"████▀ ▀████\n" .
|
||||
"███▀ ▀███\n" .
|
||||
"███ ███\n" .
|
||||
"███ ███\n" .
|
||||
"███ ███\n" .
|
||||
"███ ███\n" .
|
||||
"███▄ ▄███\n" .
|
||||
"████▄ ▄████\n" .
|
||||
"██████▄ ▄██████\n" .
|
||||
"████████▄ ▄████████\n" .
|
||||
"███████████▄▄▄▄▄▄▄▄▄▄███████████\n" .
|
||||
"████████████████████████████████\n";
|
||||
// Image with different filters on each scanline
|
||||
$img = Image::fromFile(__DIR__ . "/../../resources/pngsuite/f99n0g04.png") -> toBlackAndWhite();
|
||||
$result = $img -> toString();
|
||||
$this -> assertEquals($expected, $result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Mike42\GfxPhp\RgbRasterImage;
|
||||
use Mike42\GfxPhp\Codec\PngCodec;
|
||||
use Mike42\GfxPhp\Codec\PnmCodec;
|
||||
use Mike42\GfxPhp\BlackAndWhiteRasterImage;
|
||||
use Mike42\GfxPhp\GrayscaleRasterImage;
|
||||
|
||||
/*
|
||||
* Tiny example image used throughout this test looks like this:
|
||||
*╭────╮
|
||||
*│██░░│ ██ = 0x00
|
||||
*│░░██│ ░░ = 0xFF
|
||||
*╰────╯
|
||||
*/
|
||||
class PnmCodecTest extends TestCase
|
||||
{
|
||||
const IMAGE_TEXT = "▀▄\n";
|
||||
|
||||
const PBM_EXAMPLE = "P4\x0a2 2\x0a\x80@";
|
||||
const PGM_EXAMPLE = "P5\x0a2 2\x0a255\x0a\x00\xff\xff\x00";
|
||||
const PPM_EXAMPLE = "P6\x0a2 2\x0a255\x0a\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x00\x00";
|
||||
|
||||
protected function createRgbTestImage() {
|
||||
$image = RgbRasterImage::create(2, 2);
|
||||
$black = $image -> rgbToInt(0, 0, 0);
|
||||
$white = $image -> rgbToInt(255, 255, 255);
|
||||
$image -> setPixel(0, 0, $black);
|
||||
$image -> setPixel(1, 0, $white);
|
||||
$image -> setPixel(0, 1, $white);
|
||||
$image -> setPixel(1, 1, $black);
|
||||
return $image;
|
||||
}
|
||||
|
||||
public function testPnmEncodeRgb() {
|
||||
// Test image as RGB
|
||||
$encoder = new PnmCodec();
|
||||
$image = $this -> createRgbTestImage();
|
||||
// Encode
|
||||
$blob = $encoder -> encode($image, 'pnm');
|
||||
// Should have auto-selected PPM based on RgbTestImage input
|
||||
$this -> assertEquals(self::PPM_EXAMPLE, $blob);
|
||||
}
|
||||
|
||||
public function testPbmEncodeRgb() {
|
||||
// Test image as RGB
|
||||
$encoder = new PnmCodec();
|
||||
$image = $this -> createRgbTestImage();
|
||||
// Encode
|
||||
$blob = $encoder -> encode($image, 'pbm');
|
||||
// Check against known-good encoding of PBM
|
||||
$this -> assertEquals(self::PBM_EXAMPLE, $blob);
|
||||
}
|
||||
|
||||
public function testPbmDecode() {
|
||||
$decoder = new PnmCodec();
|
||||
$image = $decoder -> decode(self::PBM_EXAMPLE);
|
||||
$this -> assertTrue($image instanceof BlackAndWhiteRasterImage);
|
||||
$this -> assertEquals(self::IMAGE_TEXT, $image -> toString());
|
||||
|
||||
}
|
||||
|
||||
public function testPgmEncodeRgb() {
|
||||
// Test image as RGB
|
||||
$encoder = new PnmCodec();
|
||||
$image = $this -> createRgbTestImage();
|
||||
// Encode
|
||||
$blob = $encoder -> encode($image, 'pgm');
|
||||
// Check against known-good encoding of PGM
|
||||
$this -> assertEquals(self::PGM_EXAMPLE, $blob);
|
||||
}
|
||||
|
||||
public function testPgmDecode() {
|
||||
$decoder = new PnmCodec();
|
||||
$image = $decoder -> decode(self::PGM_EXAMPLE);
|
||||
$this -> assertTrue($image instanceof GrayscaleRasterImage);
|
||||
$this -> assertEquals(self::IMAGE_TEXT, $image -> toBlackAndWhite() -> toString());
|
||||
}
|
||||
|
||||
public function testPpmEncodeRgb() {
|
||||
// Test image as RGB
|
||||
$encoder = new PnmCodec();
|
||||
$image = $this -> createRgbTestImage();
|
||||
// Encode
|
||||
$blob = $encoder -> encode($image, 'ppm');
|
||||
// Check against known-good encoding of PPM
|
||||
$this -> assertEquals(self::PPM_EXAMPLE, $blob);
|
||||
}
|
||||
|
||||
public function testPpmDecode() {
|
||||
$decoder = new PnmCodec();
|
||||
$image = $decoder -> decode(self::PPM_EXAMPLE);
|
||||
$this -> assertTrue($image instanceof RgbRasterImage);
|
||||
$this -> assertEquals(self::IMAGE_TEXT, $image -> toBlackAndWhite() -> toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
namespace Mike42\GfxPhp\Codec\Bmp;
|
||||
|
||||
use Exception;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class Rle8DecoderTest extends TestCase
|
||||
{
|
||||
public function testDecodeEmpty()
|
||||
{
|
||||
$decoder = new Rle8Decoder();
|
||||
$result = $decoder -> decodeNumbers([], 0, 0);
|
||||
$this -> assertEquals([], $result);
|
||||
}
|
||||
|
||||
public function testDecodeEmpty2()
|
||||
{
|
||||
$decoder = new Rle8Decoder();
|
||||
$result = $decoder -> decodeNumbers([
|
||||
0, 1 // End of bitmap
|
||||
], 0, 0);
|
||||
$this -> assertEquals([], $result);
|
||||
}
|
||||
|
||||
public function testDecodeRun()
|
||||
{
|
||||
$decoder = new Rle8Decoder();
|
||||
$result = $decoder -> decodeNumbers([
|
||||
3, 1, // 3 1's
|
||||
0, 0, // Line break
|
||||
3, 3, // 3 3's
|
||||
0, 0, // Line break
|
||||
3, 5, // 3 5's
|
||||
0, 1 // End of bitmap
|
||||
], 3, 3);
|
||||
$expected = [
|
||||
[1, 1, 1],
|
||||
[3, 3, 3],
|
||||
[5, 5, 5]
|
||||
];
|
||||
$this -> assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testRunTooWide()
|
||||
{
|
||||
$this -> expectException(Exception::class);
|
||||
$decoder = new Rle8Decoder();
|
||||
$result = $decoder -> decodeNumbers([
|
||||
4, 1, // 4 1's (x-direction overflow)
|
||||
0, 0, // Line break
|
||||
3, 3, // 3 3's
|
||||
0, 0, // Line break
|
||||
3, 5, // 3 5's
|
||||
0, 1 // End of bitmap
|
||||
], 3, 3);
|
||||
$expected = [
|
||||
[1, 1, 1],
|
||||
[3, 3, 3],
|
||||
[5, 5, 5]
|
||||
];
|
||||
$this -> assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testRunTooTall()
|
||||
{
|
||||
$this -> expectException(Exception::class);
|
||||
$decoder = new Rle8Decoder();
|
||||
$result = $decoder -> decodeNumbers([
|
||||
3, 1, // 3 1's
|
||||
0, 0, // Line break
|
||||
3, 3, // 3 3's
|
||||
0, 0, // Line break
|
||||
3, 5, // 3 5's
|
||||
0, 0, // Line break
|
||||
3, 6, // 3 6's (y-direction overflow)
|
||||
0, 1 // End of bitmap
|
||||
], 3, 3);
|
||||
$expected = [
|
||||
[1, 1, 1],
|
||||
[3, 3, 3],
|
||||
[5, 5, 5]
|
||||
];
|
||||
$this -> assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
|
||||
public function testDeltaDiagonal()
|
||||
{
|
||||
$decoder = new Rle8Decoder();
|
||||
$result = $decoder -> decodeNumbers([
|
||||
0, 2, // Jump..
|
||||
2, 2, // .. diagonally
|
||||
1, 1, // Print 1
|
||||
0, 1 // End of bitmap
|
||||
], 3, 3);
|
||||
$expected = [
|
||||
[0, 0, 0],
|
||||
[0, 0, 0],
|
||||
[0, 0, 1]
|
||||
];
|
||||
$this -> assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testDeltaRight()
|
||||
{
|
||||
$decoder = new Rle8Decoder();
|
||||
$result = $decoder -> decodeNumbers([
|
||||
0, 2, // Jump..
|
||||
2, 0, // .. right
|
||||
1, 1, // Print 1
|
||||
0, 1 // End of bitmap
|
||||
], 3, 3);
|
||||
$expected = [
|
||||
[0, 0, 1],
|
||||
[0, 0, 0],
|
||||
[0, 0, 0]
|
||||
];
|
||||
$this -> assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testDeltaDown()
|
||||
{
|
||||
$decoder = new Rle8Decoder();
|
||||
$result = $decoder -> decodeNumbers([
|
||||
0, 2, // Jump..
|
||||
0, 2, // .. down
|
||||
1, 1, // Print 1
|
||||
0, 1 // End of bitmap
|
||||
], 3, 3);
|
||||
$expected = [
|
||||
[0, 0, 0],
|
||||
[0, 0, 0],
|
||||
[1, 0, 0]
|
||||
];
|
||||
$this -> assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testAbsolute()
|
||||
{
|
||||
$decoder = new Rle8Decoder();
|
||||
$result = $decoder -> decodeNumbers([
|
||||
0, 3, 1, 2, 3, 0, // Absolute run of 3 pixels + 1 pixel of padding
|
||||
0, 0, // Line break
|
||||
0, 3, 4, 5, 6, 0, // 3 pixels
|
||||
0, 0, // Line break
|
||||
0, 3, 7, 8, 9, 0, // 3 pixels
|
||||
0, 0, // Line break
|
||||
0, 1 // End of bitmap
|
||||
], 3, 3);
|
||||
$expected = [
|
||||
[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9]
|
||||
];
|
||||
$this -> assertEquals($expected, $result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
use Mike42\GfxPhp\BlackAndWhiteRasterImage;
|
||||
use Mike42\GfxPhp\Codec\Common\DataBlobInputStream;
|
||||
use Mike42\GfxPhp\Codec\WbmpCodec;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class WbmpCodecTest extends TestCase {
|
||||
const WBMP_IMAGE = "\x00\x00\x0c\x06\x24\x90\xff\xf0\x49\x20\xff\xf0\x92\x40\xff\xf0";
|
||||
|
||||
public function testIdentify() {
|
||||
$codec = new WbmpCodec();
|
||||
$this -> assertEquals("wbmp", $codec -> identify(self::WBMP_IMAGE));
|
||||
$this -> assertEquals("", $codec -> identify("HELLO"));
|
||||
}
|
||||
|
||||
public function testDecode() {
|
||||
$codec = new WbmpCodec();
|
||||
$image = $codec -> decode(self::WBMP_IMAGE) -> toBlackAndWhite();
|
||||
$this -> assertEquals(12, $image -> getWidth());
|
||||
$this -> assertEquals(6, $image -> getHeight());
|
||||
$content = "▀▀ ▀▀ ▀▀ ▀▀ \n" .
|
||||
"▀ ▀▀ ▀▀ ▀▀ ▀\n" .
|
||||
" ▀▀ ▀▀ ▀▀ ▀▀\n";
|
||||
$this -> assertEquals($content, $image -> toString());
|
||||
}
|
||||
|
||||
public function testEncode() {
|
||||
// Raster representation is inverse to WBMP format.
|
||||
$image = BlackAndWhiteRasterImage::create(12, 6, [0xdb, 0x6f, 0x00, 0x0f, 0xb6, 0xdf, 0x00, 0x0f, 0x6d, 0xbf, 0x00, 0x0f]);
|
||||
$codec = new WbmpCodec();
|
||||
$data = $codec -> encode($image, "wbmp");
|
||||
$this -> assertEquals(self::WBMP_IMAGE, $data);
|
||||
}
|
||||
|
||||
public function testReadOneByte() {
|
||||
$data = DataBlobInputStream::fromBlob("\x60");
|
||||
$codec = new WbmpCodec();
|
||||
$val = $codec -> readInt($data);
|
||||
$this -> assertEquals(0x60, $val);
|
||||
}
|
||||
|
||||
public function testReadMultibyte() {
|
||||
$data = DataBlobInputStream::fromBlob("\x81\x20");
|
||||
$codec = new WbmpCodec();
|
||||
$val = $codec -> readInt($data);
|
||||
$this -> assertEquals(0xA0, $val);
|
||||
}
|
||||
|
||||
public function testReadMax() {
|
||||
$data = DataBlobInputStream::fromBlob("\xFF\xFF\xFF\x7F\x00"); // Final byte not used
|
||||
$codec = new WbmpCodec();
|
||||
$val = $codec -> readInt($data);
|
||||
$this -> assertEquals(268435455, $val);
|
||||
}
|
||||
|
||||
public function testReadMultibyteOverflow() {
|
||||
// Appears to be no limit in WBMP to image dimensions, but we stop reading the multibyte-ints after 28 bits.
|
||||
$this -> expectException(Exception::class);
|
||||
$data = DataBlobInputStream::fromBlob("\xFF\xFF\xFF\x80\x00"); // (value in testMax()) + 1
|
||||
$codec = new WbmpCodec();
|
||||
$codec -> readInt($data);
|
||||
}
|
||||
|
||||
public function testWriteOneByte() {
|
||||
$codec = new WbmpCodec();
|
||||
$val = $codec -> writeInt(0x60);
|
||||
$this -> assertEquals("\x60", $val);
|
||||
}
|
||||
|
||||
public function testWriteMultibyte() {
|
||||
$codec = new WbmpCodec();
|
||||
$val = $codec -> writeInt(0xA0);
|
||||
$this -> assertEquals("\x81\x20", $val);
|
||||
}
|
||||
|
||||
public function testWriteMax() {
|
||||
$codec = new WbmpCodec();
|
||||
$val = $codec -> writeInt(268435455);
|
||||
$this -> assertEquals("\xFF\xFF\xFF\x7F", $val);
|
||||
|
||||
}
|
||||
|
||||
public function testWriteMultibyteOverflow() {
|
||||
$this -> expectException(Exception::class);
|
||||
$codec = new WbmpCodec();
|
||||
$val = $codec -> writeInt(268435456); // As testWriteMax(), +1
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user