diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 358217355dae4..eb139ea67a8f7 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -2154,6 +2154,7 @@ 'OC\\Preview\\Image' => $baseDir . '/lib/private/Preview/Image.php', 'OC\\Preview\\Imaginary' => $baseDir . '/lib/private/Preview/Imaginary.php', 'OC\\Preview\\ImaginaryPDF' => $baseDir . '/lib/private/Preview/ImaginaryPDF.php', + 'OC\\Preview\\JP2' => $baseDir . '/lib/private/Preview/JP2.php', 'OC\\Preview\\JPEG' => $baseDir . '/lib/private/Preview/JPEG.php', 'OC\\Preview\\Krita' => $baseDir . '/lib/private/Preview/Krita.php', 'OC\\Preview\\MP3' => $baseDir . '/lib/private/Preview/MP3.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 3764598341acf..6f4d27b27eee9 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -2195,6 +2195,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OC\\Preview\\Image' => __DIR__ . '/../../..' . '/lib/private/Preview/Image.php', 'OC\\Preview\\Imaginary' => __DIR__ . '/../../..' . '/lib/private/Preview/Imaginary.php', 'OC\\Preview\\ImaginaryPDF' => __DIR__ . '/../../..' . '/lib/private/Preview/ImaginaryPDF.php', + 'OC\\Preview\\JP2' => __DIR__ . '/../../..' . '/lib/private/Preview/JP2.php', 'OC\\Preview\\JPEG' => __DIR__ . '/../../..' . '/lib/private/Preview/JPEG.php', 'OC\\Preview\\Krita' => __DIR__ . '/../../..' . '/lib/private/Preview/Krita.php', 'OC\\Preview\\MP3' => __DIR__ . '/../../..' . '/lib/private/Preview/MP3.php', diff --git a/lib/private/Preview/JP2.php b/lib/private/Preview/JP2.php new file mode 100644 index 0000000000000..fa19a98d881df --- /dev/null +++ b/lib/private/Preview/JP2.php @@ -0,0 +1,38 @@ + ['mimetype' => '/image\/svg\+xml/', 'class' => SVG::class], 'TIFF' => ['mimetype' => '/image\/tiff/', 'class' => TIFF::class], + 'JP2' => ['mimetype' => '/image\/jp2/', 'class' => JP2::class], 'PDF' => ['mimetype' => '/application\/pdf/', 'class' => PDF::class], 'AI' => ['mimetype' => '/application\/illustrator/', 'class' => Illustrator::class], 'PSD' => ['mimetype' => '/application\/x-photoshop/', 'class' => Photoshop::class], diff --git a/tests/data/REUSE.toml b/tests/data/REUSE.toml index 34ea37845a0ef..255b35698189f 100644 --- a/tests/data/REUSE.toml +++ b/tests/data/REUSE.toml @@ -34,7 +34,7 @@ SPDX-FileCopyrightText = "2012 ownCloud, Inc." SPDX-License-Identifier = "AGPL-3.0-only" [[annotations]] -path = ["testavatar.png", "testimage.avif", "testimage.gif", "testimage.jpg", "testimage.png"] +path = ["testavatar.png", "testimage.avif", "testimage.gif", "testimage.jp2", "testimage.jpg", "testimage.png"] precedence = "aggregate" SPDX-FileCopyrightText = "2013 ownCloud, Inc." SPDX-License-Identifier = "AGPL-3.0-only" diff --git a/tests/data/testimage.jp2 b/tests/data/testimage.jp2 new file mode 100644 index 0000000000000..496069e81cb31 Binary files /dev/null and b/tests/data/testimage.jp2 differ diff --git a/tests/lib/Preview/AVIFImagickTest.php b/tests/lib/Preview/AVIFImagickTest.php index cc7e9b92624ef..258cd33dd229d 100644 --- a/tests/lib/Preview/AVIFImagickTest.php +++ b/tests/lib/Preview/AVIFImagickTest.php @@ -16,7 +16,7 @@ */ #[\PHPUnit\Framework\Attributes\Group('DB')] class AVIFImagickTest extends Provider { - use AvifPreviewTrait; + use PreviewPixelsTrait; #[\Override] protected function setUp(): void { diff --git a/tests/lib/Preview/AVIFTest.php b/tests/lib/Preview/AVIFTest.php index 5a32d7738406f..02a3a5455bff1 100644 --- a/tests/lib/Preview/AVIFTest.php +++ b/tests/lib/Preview/AVIFTest.php @@ -17,7 +17,7 @@ */ #[\PHPUnit\Framework\Attributes\Group('DB')] class AVIFTest extends Provider { - use AvifPreviewTrait; + use PreviewPixelsTrait; #[\Override] protected function setUp(): void { diff --git a/tests/lib/Preview/JP2Test.php b/tests/lib/Preview/JP2Test.php new file mode 100644 index 0000000000000..f8f1a54e905e5 --- /dev/null +++ b/tests/lib/Preview/JP2Test.php @@ -0,0 +1,54 @@ +markTestSkipped('ImageMagick is not installed. Skipping tests'); + } + if (!in_array('JP2', \Imagick::queryFormats('JP2'), true)) { + $this->markTestSkipped('ImageMagick was built without JPEG 2000. Skipping tests'); + } + + $fileName = 'testimage.jp2'; + $sourcePath = \OC::$SERVERROOT . '/tests/data/' . $fileName; + + // Reporting the coder is not the same as being able to use it: the + // OpenJPEG delegate may be missing, or policy.xml may have disabled + // it, in which case decoding throws and the tests would fail rather + // than skip. Decode once for real before committing to them. + try { + (new \Imagick())->readImage('jp2:' . $sourcePath . '[0]'); + } catch (\ImagickException $e) { + $this->markTestSkipped('ImageMagick cannot decode JPEG 2000 here: ' . $e->getMessage() . '. Skipping tests'); + } + + parent::setUp(); + + $this->imgPath = $this->prepareTestFile($fileName, $sourcePath); + $this->width = 1680; + $this->height = 1050; + $this->provider = new JP2(); + } + + public function testPreviewCarriesThePicture(): void { + $this->assertPreviewShowsThePicture(); + } +} diff --git a/tests/lib/Preview/AvifPreviewTrait.php b/tests/lib/Preview/PreviewPixelsTrait.php similarity index 91% rename from tests/lib/Preview/AvifPreviewTrait.php rename to tests/lib/Preview/PreviewPixelsTrait.php index 5a8fb4fbc2846..b208ff3fa65e7 100644 --- a/tests/lib/Preview/AvifPreviewTrait.php +++ b/tests/lib/Preview/PreviewPixelsTrait.php @@ -18,7 +18,7 @@ * came back, which a blank canvas of the right shape would satisfy just as * well as a decoded photo. These read the pixels. */ -trait AvifPreviewTrait { +trait PreviewPixelsTrait { /** How far the average may drift, over encoding and scaling */ private int $tolerance = 12; @@ -66,9 +66,9 @@ protected function assertPreviewShowsThePicture(): void { $this->assertLessThanOrEqual(256, $preview->width()); $this->assertLessThanOrEqual(256, $preview->height()); - // The fixture is a re-encode of testimage.jpg, so the two hold the - // same picture: a strong magenta whose average survives both the - // encoding and the scaling. A blank or black canvas misses by ~250. + // Every fixture using this is a re-encode of testimage.jpg, so they + // hold the same picture: a strong magenta whose average survives + // the encoding and the scaling. A blank canvas misses by ~250. $expected = $this->meanColour(file_get_contents(\OC::$SERVERROOT . '/tests/data/testimage.jpg')); $actual = $this->meanColour($preview->data());