File indexing completed on 2024-04-28 15:25:41

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 2013 Boudewijn Rempt <boud@valdyas.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 
0007     This code is based on Thacher Ulrich PSD loading code released
0008     on public domain. See: http://tulrich.com/geekstuff/
0009 */
0010 
0011 #include "kra.h"
0012 
0013 #include <kzip.h>
0014 
0015 #include <QFile>
0016 #include <QIODevice>
0017 #include <QImage>
0018 
0019 static constexpr char s_magic[] = "application/x-krita";
0020 static constexpr int s_magic_size = sizeof(s_magic) - 1; // -1 to remove the last \0
0021 
0022 KraHandler::KraHandler()
0023 {
0024 }
0025 
0026 bool KraHandler::canRead() const
0027 {
0028     if (canRead(device())) {
0029         setFormat("kra");
0030         return true;
0031     }
0032     return false;
0033 }
0034 
0035 bool KraHandler::read(QImage *image)
0036 {
0037     KZip zip(device());
0038     if (!zip.open(QIODevice::ReadOnly)) {
0039         return false;
0040     }
0041 
0042     const KArchiveEntry *entry = zip.directory()->entry(QStringLiteral("mergedimage.png"));
0043     if (!entry || !entry->isFile()) {
0044         return false;
0045     }
0046 
0047     const KZipFileEntry *fileZipEntry = static_cast<const KZipFileEntry *>(entry);
0048 
0049     image->loadFromData(fileZipEntry->data(), "PNG");
0050 
0051     return true;
0052 }
0053 
0054 bool KraHandler::canRead(QIODevice *device)
0055 {
0056     if (!device) {
0057         qWarning("KraHandler::canRead() called with no device");
0058         return false;
0059     }
0060     if (device->isSequential()) {
0061         return false;
0062     }
0063 
0064     char buff[57];
0065     if (device->peek(buff, sizeof(buff)) == sizeof(buff)) {
0066         return memcmp(buff + 0x26, s_magic, s_magic_size) == 0;
0067     }
0068 
0069     return false;
0070 }
0071 
0072 QImageIOPlugin::Capabilities KraPlugin::capabilities(QIODevice *device, const QByteArray &format) const
0073 {
0074     if (format == "kra" || format == "KRA") {
0075         return Capabilities(CanRead);
0076     }
0077     if (!format.isEmpty()) {
0078         return {};
0079     }
0080     if (!device->isOpen()) {
0081         return {};
0082     }
0083 
0084     Capabilities cap;
0085     if (device->isReadable() && KraHandler::canRead(device)) {
0086         cap |= CanRead;
0087     }
0088     return cap;
0089 }
0090 
0091 QImageIOHandler *KraPlugin::create(QIODevice *device, const QByteArray &format) const
0092 {
0093     QImageIOHandler *handler = new KraHandler;
0094     handler->setDevice(device);
0095     handler->setFormat(format);
0096     return handler;
0097 }
0098 
0099 #include "moc_kra.cpp"