Skip to content

Commit

Permalink
Merge pull request #32 from mike42/feature/test-coverage
Browse files Browse the repository at this point in the history
Improve test coverage, related bug fixes
  • Loading branch information
mike42 authored Jun 10, 2018
2 parents c5d0e95 + 1526729 commit 3ac1be9
Show file tree
Hide file tree
Showing 15 changed files with 1,782 additions and 70 deletions.
45 changes: 25 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![Build Status](https://travis-ci.org/mike42/gfx-php.svg?branch=master)](https://travis-ci.org/mike42/gfx-php) [![Latest Stable Version](https://poser.pugx.org/mike42/gfx-php/v/stable)](https://packagist.org/packages/mike42/gfx-php)
[![Total Downloads](https://poser.pugx.org/mike42/gfx-php/downloads)](https://packagist.org/packages/mike42/gfx-php)
[![License](https://poser.pugx.org/mike42/gfx-php/license)](https://packagist.org/packages/mike42/gfx-php)
[![License](https://poser.pugx.org/mike42/gfx-php/license)](https://packagist.org/packages/mike42/gfx-php) [![Coverage Status](https://coveralls.io/repos/github/mike42/gfx-php/badge.svg?branch=master)](https://coveralls.io/github/mike42/gfx-php?branch=master)

This library implements input, output and processing of raster images in pure PHP, so that image
processing extensions (Gd, Imagick) are not required.
Expand All @@ -11,46 +11,51 @@ This allows developers to eliminate some portability issues from their applicati

## Requirements

- PHP 7.0 or newer
- PHP 7.0 or newer.
- zlib extension, for reading PNG files.

## Examples
## Get started

- See the `examples/` sub-folder.
- Have a read of the documentation at [gfx-php.readthedocs.io](https://gfx-php.readthedocs.io/)
- See the `examples/` sub-folder for snippets.

## Status & Scope
## Status & scope

Currently, we are implementing basic raster operations on select file formats. If you're interested in image processing algorithms, then please consider contributing an implementation.
Currently, we are implementing basic raster operations on select file formats.

See related documentation for:

- [Available input file formats](https://gfx-php.readthedocs.io/en/latest/user/formats.html#input-formats).
- [Available output file formats](https://gfx-php.readthedocs.io/en/latest/user/formats.html#output-formats).
- [Available image operations](https://gfx-php.readthedocs.io/en/latest/user/operations.html).

If you're interested in image processing algorithms, then please consider contributing an implementation.

For algorithms, it appears feasable to implement:

- Color conversions
- Scale
- Crop
- Blur
- Composite
- Mask
- Rotate
- Layered operations
- Affine transformations
- Lines, arcs, circles, and rectangles.

And the roadmap for format support:
And sill on the roadmap for format support:

- The full suite of Netpbm binary and text formats (PNM, PBM, PGM, PPM).
- BMP, which involves RLE (de)compression
- PNG, which involves DEFLATE (de)compression
- GIF and TIFF, which involve LZW (de)compression
- BMP input, which involves RLE decompression (BMP output is already available).
- GIF input, which involves LZW decompression (GIF output is already available).
- TIFF input and output, which also involves LZW (de)compression.

In the interests of getting the basic features working first, I'm not currently planning to attempt lossy compression, or formats that are not common on either the web or for printing:
In the interests of getting the basic features working first, there is no current plan to attempt lossy compression, or formats that are not common on either the web or for printing, eg:

- JPEG
- MNG
- PAM format
- XPM
- More advanced transformations
- .. etc.

Also, as we don't have the luxury of pulling in dependencies, I'm considering anything that is not a raster operation out-of-scope:

- All vector image formats (PDF, SVG, EPS, etc).
- Anything involving fonts
- Anything involving vector fonts

### Test data sets

Expand Down
3 changes: 2 additions & 1 deletion src/Mike42/GfxPhp/Codec/Png/InterlaceDecoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ private function decodeAdam7Interlace(PngHeader $header, string $binData)
foreach ($passes as $passId => $pass) {
$passWidth = $pass['width'];
$passHeight = $pass['height'];
if ($passWidth == 0) {
if ($passWidth == 0 || $passHeight == 0) {
// No data in this scanline, proceed.
continue;
}
$passScanlineWidth = intdiv($passWidth * $bitDepth + 7, 8) * $channels;
Expand Down
32 changes: 24 additions & 8 deletions src/Mike42/GfxPhp/Codec/Png/PngHeader.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ class PngHeader
const COLOR_TYPE_INDEXED = 3;
const COLOR_TYPE_MONOCHROME_ALPHA = 4;
const COLOR_TYPE_RGBA = 6;

const COMPRESSION_DEFLATE = 0;

const INTERLACE_NONE = 0;
const INTERLACE_ADAM7 = 1;

private $width;
private $height;
private $bitDepth;
Expand All @@ -32,13 +32,29 @@ public function __construct(int $width, int $height, int $bitDepth, int $colorTy
$height < 1 || $height > 2147483647) {
throw new \Exception("Invalid image dimensions");
}
$this -> width = $width;
$this -> height = $height;
// Color type & bit depth
// - Only some combinations of bit depth and colorType are valid
$this -> width = $width;
$this -> height = $height;
// Color type & bit depth - Only some combinations of bit depth and colorType are valid.
// I'm sure you could abbreviate this code, but it's written for comparison with the PNG standard.
if ($colorType === 0 && ($bitDepth === 1 || $bitDepth === 2 || $bitDepth === 4 || $bitDepth === 8 || $bitDepth === 16)) {
$this -> bitDepth = $bitDepth;
$this -> colorType = $colorType;
} else if ($colorType === 2 && ($bitDepth === 8 || $bitDepth === 16)) {
$this -> bitDepth = $bitDepth;
$this -> colorType = $colorType;
// Compression
} else if ($colorType === 3 && ($bitDepth === 1 || $bitDepth === 2 || $bitDepth === 4 || $bitDepth === 8)) {
$this -> bitDepth = $bitDepth;
$this -> colorType = $colorType;
} else if ($colorType === 4 && ($bitDepth === 8 || $bitDepth === 16)) {
$this -> bitDepth = $bitDepth;
$this -> colorType = $colorType;
} else if ($colorType === 6 && ($bitDepth === 8 || $bitDepth === 16)) {
$this -> bitDepth = $bitDepth;
$this -> colorType = $colorType;
} else {
throw new \Exception("Invalid color type / bit depth combination.");
}
// Compression
if ($compression != PngHeader::COMPRESSION_DEFLATE) {
throw new \Exception("Compression type not supported");
}
Expand Down
6 changes: 3 additions & 3 deletions src/Mike42/GfxPhp/Image.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public static function fromFile(string $filename) : RasterImage
if ($blob === false) {
throw new \Exception("Could not retrieve image data from '$filename'. Check that the file exists and can be read.");
}
return self::fromBlob($blob);
return self::fromBlob($blob, $filename);
}

public static function fromBlob(string $blob, string $filename = null) : RasterImage
Expand All @@ -29,11 +29,11 @@ public static function fromBlob(string $blob, string $filename = null) : RasterI
self::$codecs = ImageCodec::getInstance();
}
$format = self::$codecs -> identify($blob);
if ($format == null) {
if ($format === null) {
throw new \Exception("Unknown format for image '$filename'.");
}
$decoder = self::$codecs ->getDecoderForFormat($format);
if ($decoder == null) {
if ($decoder === null) {
throw new \Exception("Format $format not supported, reading '$filename'.");
}
return $decoder -> decode($blob);
Expand Down
6 changes: 3 additions & 3 deletions src/Mike42/GfxPhp/IndexedRasterImage.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,11 @@ public function setMaxVal(int $maxVal)
$this -> maxVal = $maxVal;
$this -> setPalette(PaletteGenerator::colorPalette());
return;
} else if ($maxVal >= 2) {
} else if ($maxVal >= 1) {
$this -> maxVal = $maxVal;
$this -> setPalette(PaletteGenerator::blackAndWhitePalette());
return;
} else if ($maxVal >= 1) {
} else if ($maxVal >= 0) {
$this -> maxVal = $maxVal;
$this -> setPalette(PaletteGenerator::whitePalette());
return;
Expand All @@ -228,7 +228,7 @@ public function deallocateColor(array $color)
throw new \Exception("Not implemented");
}

public static function create(int $width, int $height, array $data = null, array $palette = null, int $maxVal = 255)
public static function create(int $width, int $height, array $data = null, array $palette = [], int $maxVal = 255)
{
$expectedSize = $width * $height;
if ($data == null) {
Expand Down
Loading

0 comments on commit 3ac1be9

Please sign in to comment.