Skip to content

Commit

Permalink
:octocat: QRGdImage: remove custom error handler
Browse files Browse the repository at this point in the history
  • Loading branch information
codemasher committed Jul 23, 2024
1 parent e51e367 commit 7e7552b
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 47 deletions.
71 changes: 31 additions & 40 deletions src/Output/QRGdImage.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
use chillerlan\QRCode\QROptions;
use chillerlan\QRCode\Data\QRMatrix;
use chillerlan\Settings\SettingsContainerInterface;
use ErrorException, GdImage, Throwable;
use GdImage;
use function extension_loaded, imagecolorallocate, imagecolortransparent,
imagecreatetruecolor, imagedestroy, imagefilledellipse, imagefilledrectangle,
imagescale, imagetypes, intdiv, intval, max, min, ob_end_clean, ob_get_contents, ob_start,
restore_error_handler, set_error_handler, sprintf;
sprintf;
use const IMG_AVIF, IMG_BMP, IMG_GIF, IMG_JPG, IMG_PNG, IMG_WEBP;

/**
Expand Down Expand Up @@ -140,17 +140,14 @@ protected function getDefaultModuleValue(bool $isDark):int{
* @throws \ErrorException|\chillerlan\QRCode\Output\QRCodeOutputException
*/
public function dump(string|null $file = null):string|GdImage{

set_error_handler(function(int $errno, string $errstr):bool{
throw new ErrorException($errstr, $errno);
});

$this->image = $this->createImage();
// set module values after image creation because we need the GdImage instance
$this->setModuleValues();
$this->setBgColor();

imagefilledrectangle($this->image, 0, 0, $this->length, $this->length, $this->background);
if(imagefilledrectangle($this->image, 0, 0, $this->length, $this->length, $this->background) === false){
throw new QRCodeOutputException('imagefilledrectangle() error');
}

$this->drawImage();

Expand All @@ -173,8 +170,6 @@ public function dump(string|null $file = null):string|GdImage{
$this->setTransparencyColor();

if($this->options->returnResource){
restore_error_handler();

return $this->image;
}

Expand All @@ -186,8 +181,6 @@ public function dump(string|null $file = null):string|GdImage{
$imageData = $this->toBase64DataURI($imageData);
}

restore_error_handler();

return $imageData;
}

Expand All @@ -197,6 +190,8 @@ public function dump(string|null $file = null):string|GdImage{
* we're scaling the image up in order to draw crisp round circles, otherwise they appear square-y on small scales
*
* @see https://github.com/chillerlan/php-qrcode/issues/23
*
* @throws \chillerlan\QRCode\Output\QRCodeOutputException
*/
protected function createImage():GdImage{

Expand All @@ -207,7 +202,13 @@ protected function createImage():GdImage{
$this->upscaled = true;
}

return imagecreatetruecolor($this->length, $this->length);
$im = imagecreatetruecolor($this->length, $this->length);

if($im === false){
throw new QRCodeOutputException('imagecreatetruecolor() error');
}

return $im;
}

/**
Expand All @@ -229,12 +230,12 @@ protected function setBgColor():void{
}

/**
* Sets the transparency color
* Sets the transparency color, returns the identifier of the new transparent color
*/
protected function setTransparencyColor():void{
protected function setTransparencyColor():int{

if(!$this->options->imageTransparent){
return;
return -1;
}

$transparencyColor = $this->background;
Expand All @@ -243,7 +244,14 @@ protected function setTransparencyColor():void{
$transparencyColor = $this->prepareModuleValue($this->options->transparencyColor);
}

imagecolortransparent($this->image, $transparencyColor);
return imagecolortransparent($this->image, $transparencyColor);
}

/**
* Returns the image quality value for the current GdImage output child class (defaults to -1 ... 100)
*/
protected function getQuality():int{
return max(-1, min(100, $this->options->quality));
}

/**
Expand Down Expand Up @@ -304,37 +312,20 @@ abstract protected function renderImage():void;
* @throws \chillerlan\QRCode\Output\QRCodeOutputException
*/
protected function dumpImage():string{
$exception = null;
$imageData = null;

ob_start();

try{
$this->renderImage();
$this->renderImage();

$imageData = ob_get_contents();
$imageData = ob_get_contents();

if($imageData === false){
throw new QRCodeOutputException('ob_get_contents() error');
}

imagedestroy($this->image);
}
// not going to cover edge cases
// @codeCoverageIgnoreStart
catch(Throwable $e){
$exception = $e;
if($imageData === false){
throw new QRCodeOutputException('ob_get_contents() error');
}
// @codeCoverageIgnoreEnd

ob_end_clean();
imagedestroy($this->image);

// throw here in case an exception happened within the output buffer
if($exception instanceof Throwable){
throw new QRCodeOutputException($exception->getMessage());
}
ob_end_clean();

/** @var string $imageData */
return $imageData;
}

Expand Down
7 changes: 6 additions & 1 deletion src/Output/QRGdImageAVIF.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ class QRGdImageAVIF extends QRGdImage{

final public const MIME_TYPE = 'image/avif';

/**
* @throws \chillerlan\QRCode\Output\QRCodeOutputException
*/
protected function renderImage():void{
imageavif($this->image, null, max(-1, min(100, $this->options->quality)));
if(imageavif(image: $this->image, quality: $this->getQuality()) === false){
throw new QRCodeOutputException('imageavif() error');
}
}

}
8 changes: 7 additions & 1 deletion src/Output/QRGdImageBMP.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,14 @@ class QRGdImageBMP extends QRGdImage{

final public const MIME_TYPE = 'image/bmp';

/**
* @throws \chillerlan\QRCode\Output\QRCodeOutputException
*/
protected function renderImage():void{
imagebmp($this->image, null, ($this->options->quality > 0));
// the $compressed parameter is boolean here
if(imagebmp(image: $this->image, compressed: ($this->options->quality > 0)) === false){
throw new QRCodeOutputException('imagebmp() error');
}
}

}
7 changes: 6 additions & 1 deletion src/Output/QRGdImageGIF.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ class QRGdImageGIF extends QRGdImage{

final public const MIME_TYPE = 'image/gif';

/**
* @throws \chillerlan\QRCode\Output\QRCodeOutputException
*/
protected function renderImage():void{
imagegif($this->image);
if(imagegif(image: $this->image) === false){
throw new QRCodeOutputException('imagegif() error');
}
}

}
10 changes: 8 additions & 2 deletions src/Output/QRGdImageJPEG.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,18 @@ class QRGdImageJPEG extends QRGdImage{

final public const MIME_TYPE = 'image/jpg';

protected function setTransparencyColor():void{
protected function setTransparencyColor():int{
// noop - transparency is not supported
return -1;
}

/**
* @throws \chillerlan\QRCode\Output\QRCodeOutputException
*/
protected function renderImage():void{
imagejpeg($this->image, null, max(-1, min(100, $this->options->quality)));
if(imagejpeg(image: $this->image, quality: $this->getQuality()) === false){
throw new QRCodeOutputException('imagejpeg() error');
}
}

}
11 changes: 10 additions & 1 deletion src/Output/QRGdImagePNG.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,17 @@ class QRGdImagePNG extends QRGdImage{

final public const MIME_TYPE = 'image/png';

protected function getQuality():int{
return max(-1, min(9, $this->options->quality));
}

/**
* @throws \chillerlan\QRCode\Output\QRCodeOutputException
*/
protected function renderImage():void{
imagepng($this->image, null, max(-1, min(9, $this->options->quality)));
if(imagepng(image: $this->image, quality: $this->getQuality()) === false){
throw new QRCodeOutputException('imagepng() error');
}
}

}
7 changes: 6 additions & 1 deletion src/Output/QRGdImageWEBP.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ class QRGdImageWEBP extends QRGdImage{

final public const MIME_TYPE = 'image/webp';

/**
* @throws \chillerlan\QRCode\Output\QRCodeOutputException
*/
protected function renderImage():void{
imagewebp($this->image, null, max(-1, min(100, $this->options->quality)));
if(imagewebp(image: $this->image, quality: $this->getQuality()) === false){
throw new QRCodeOutputException('imagewebp() error');
}
}

}

0 comments on commit 7e7552b

Please sign in to comment.