From 49c25e4dc4f3f63e21f0030d01d7f6b93dae94e8 Mon Sep 17 00:00:00 2001 From: Dmitriy Pankratov <7snack7@gmail.com> Date: Mon, 27 Jul 2026 15:57:58 +0700 Subject: [PATCH] feat(preview): add embedded preview support for CorelDRAW files Signed-off-by: Dmitriy Pankratov <7snack7@gmail.com> --- lib/composer/composer/autoload_classmap.php | 1 + lib/composer/composer/autoload_static.php | 1 + lib/private/Preview/CDR.php | 89 +++++++++++++++++++++ lib/private/PreviewManager.php | 3 + 4 files changed, 94 insertions(+) create mode 100644 lib/private/Preview/CDR.php diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index beafb4700c69d..6b1fbb7cc55f3 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -2072,6 +2072,7 @@ 'OC\\Preview\\BackgroundCleanupJob' => $baseDir . '/lib/private/Preview/BackgroundCleanupJob.php', 'OC\\Preview\\Bitmap' => $baseDir . '/lib/private/Preview/Bitmap.php', 'OC\\Preview\\Bundled' => $baseDir . '/lib/private/Preview/Bundled.php', + 'OC\\Preview\\CDR' => $baseDir . '/lib/private/Preview/CDR.php', 'OC\\Preview\\Db\\Preview' => $baseDir . '/lib/private/Preview/Db/Preview.php', 'OC\\Preview\\Db\\PreviewMapper' => $baseDir . '/lib/private/Preview/Db/PreviewMapper.php', 'OC\\Preview\\EMF' => $baseDir . '/lib/private/Preview/EMF.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index e024c1fb44b9f..6eececdd44728 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -2113,6 +2113,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OC\\Preview\\BackgroundCleanupJob' => __DIR__ . '/../../..' . '/lib/private/Preview/BackgroundCleanupJob.php', 'OC\\Preview\\Bitmap' => __DIR__ . '/../../..' . '/lib/private/Preview/Bitmap.php', 'OC\\Preview\\Bundled' => __DIR__ . '/../../..' . '/lib/private/Preview/Bundled.php', + 'OC\\Preview\\CDR' => __DIR__ . '/../../..' . '/lib/private/Preview/CDR.php', 'OC\\Preview\\Db\\Preview' => __DIR__ . '/../../..' . '/lib/private/Preview/Db/Preview.php', 'OC\\Preview\\Db\\PreviewMapper' => __DIR__ . '/../../..' . '/lib/private/Preview/Db/PreviewMapper.php', 'OC\\Preview\\EMF' => __DIR__ . '/../../..' . '/lib/private/Preview/EMF.php', diff --git a/lib/private/Preview/CDR.php b/lib/private/Preview/CDR.php new file mode 100644 index 0000000000000..19aa04da4cb49 --- /dev/null +++ b/lib/private/Preview/CDR.php @@ -0,0 +1,89 @@ +getSize() > 0; + } + #[\Override] + public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage { + if (!$this->isAvailable($file)) { + return null; + } + + $localFile = $this->getLocalFile($file); + + if ($localFile === false) { + return null; + } + + $data = $this->extractThumbnail($localFile); + if ($data === null) { + return null; + } + + $image = new Image(); + $image->loadFromData($data); + + if (!$image->valid()) { + return null; + } + + $image->scaleDownToFit($maxX, $maxY); + + return $image; + } + /** * Extract ONLY thumbnail (no pages) */ + private function extractThumbnail(string $file): ?string { + $zip = new \ZipArchive(); + + if ($zip->open($file) !== true) { + return null; + } + + /** + * Newer CorelDRAW files store the embedded preview in previews/thumbnail.png. + * + * Older CorelDRAW files store the embedded BMP thumbnail in + * metadata/thumbnails/thumbnail.bmp. + */ + foreach ([ + 'previews/thumbnail.png', + 'metadata/thumbnails/thumbnail.bmp', + ] as $thumbnail) { + $idx = $zip->locateName($thumbnail); + + if ($idx === false) { + continue; + } + + $data = $zip->getFromIndex($idx); + $zip->close(); + + return $data === false ? null : $data; + } + + $zip->close(); + + return null; + } +} diff --git a/lib/private/PreviewManager.php b/lib/private/PreviewManager.php index f1621d7973887..0dbdb79e5299d 100644 --- a/lib/private/PreviewManager.php +++ b/lib/private/PreviewManager.php @@ -11,6 +11,7 @@ use Closure; use OC\AppFramework\Bootstrap\Coordinator; use OC\Preview\BMP; +use OC\Preview\CDR; use OC\Preview\Db\PreviewMapper; use OC\Preview\EMF; use OC\Preview\Font; @@ -271,6 +272,7 @@ protected function getEnabledDefaultProvider(): array { XBitmap::class, Krita::class, WebP::class, + CDR::class, ]; $this->defaultProviders = $this->config->getSystemValue('enabledPreviewProviders', array_merge([ @@ -317,6 +319,7 @@ protected function registerCoreProviders(): void { $this->registerCoreProvider(BMP::class, '/image\/bmp/'); $this->registerCoreProvider(XBitmap::class, '/image\/x-xbitmap/'); $this->registerCoreProvider(WebP::class, '/image\/webp/'); + $this->registerCoreProvider(CDR::class, '/application\/coreldraw/'); $this->registerCoreProvider(Krita::class, '/application\/x-krita/'); $this->registerCoreProvider(MP3::class, '/audio\/mpeg$/'); $this->registerCoreProvider(OpenDocument::class, '/application\/vnd.oasis.opendocument.*/');