Skip to content

Commit

Permalink
jpeg2000 encoder (#19)
Browse files Browse the repository at this point in the history
* jpeg2000 encoder

* allow image/x-jp2-codestream

* Refactor mime type detection

* Add BaseTestCase::assertMediaTypeJpeg2000()

* Add debug info

* Include alternative Jpeg 2000 magic byte signature

* Revert "Add debug info"

This reverts commit 5a656d3.

* Reduce sample size

* Refactor Jpeg200EncoderTest::class

---------

Co-authored-by: Oliver Vogel <[email protected]>
  • Loading branch information
deluxetom and olivervogel authored Dec 29, 2024
1 parent 28880b2 commit ceb985c
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 6 deletions.
29 changes: 29 additions & 0 deletions src/Encoders/Jpeg2000Encoder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Intervention\Image\Drivers\Vips\Encoders;

use Intervention\Image\EncodedImage;
use Intervention\Image\Encoders\Jpeg2000Encoder as GenericJpeg2000Encoder;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\SpecializedInterface;

class Jpeg2000Encoder extends GenericJpeg2000Encoder implements SpecializedInterface
{
/**
* {@inheritdoc}
*
* @see EncoderInterface::function()
*/
public function encode(ImageInterface $image): EncodedImage
{
$result = $image->core()->native()->writeToBuffer('.j2k', [
'Q' => $this->quality,
'strip' => true,
'lossless' => false,
]);

return new EncodedImage($result, 'image/jp2');
}
}
8 changes: 2 additions & 6 deletions tests/BaseTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Intervention\Image\Drivers\Vips\Tests;

use finfo;
use Intervention\Image\Colors\Rgb\Channels\Alpha;
use Intervention\Image\Colors\Rgb\Channels\Blue;
use Intervention\Image\Colors\Rgb\Channels\Green;
Expand Down Expand Up @@ -121,12 +122,7 @@ protected function assertColor(int $r, int $g, int $b, int $a, ColorInterface $c

protected function assertMediaType(string|array $allowed, string|EncodedImage $input): void
{
$pointer = fopen('php://temp', 'rw');
fputs($pointer, (string) $input);
rewind($pointer);
$detected = mime_content_type($pointer);
fclose($pointer);

$detected = (new finfo(FILEINFO_MIME_TYPE))->buffer((string) $input);
$allowed = is_string($allowed) ? [$allowed] : $allowed;
$this->assertTrue(
in_array($detected, $allowed),
Expand Down
33 changes: 33 additions & 0 deletions tests/Unit/Encoders/Jpeg200EncoderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Intervention\Image\Drivers\Vips\Tests\Unit\Encoders;

use Intervention\Image\Drivers\Vips\Driver;
use Intervention\Image\Drivers\Vips\Encoders\Jpeg2000Encoder;
use Intervention\Image\Drivers\Vips\Tests\BaseTestCase;
use Intervention\Image\EncodedImage;
use PHPUnit\Framework\Attributes\CoversClass;

#[CoversClass(Jpeg2000Encoder::class)]
final class Jpeg200EncoderTest extends BaseTestCase
{
public function testEncode(): void
{
$image = (new Driver())->createImage(3, 2);
$encoder = new Jpeg2000Encoder(75);
$encoder->setDriver(new Driver());
$result = $encoder->encode($image);
$this->assertEquals('image/jp2', $result->mimetype());
$this->assertTrue($this->isJpeg2000($result), 'Encoding result is not in Jpeg 2000 format.');
}

private function isJpeg2000(string|EncodedImage $input): bool
{
return 1 === preg_match(
"/^0000000C6A5020200D0A870A|FF4FFF51/",
strtoupper(substr(bin2hex((string) $input), 0, 24))
);
}
}

0 comments on commit ceb985c

Please sign in to comment.