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 "ora.h"
0012 
0013 #include <QImage>
0014 #include <QScopedPointer>
0015 
0016 #include <kzip.h>
0017 
0018 static constexpr char s_magic[] = "image/openraster";
0019 static constexpr int s_magic_size = sizeof(s_magic) - 1; // -1 to remove the last \0
0020 
0021 OraHandler::OraHandler()
0022 {
0023 }
0024 
0025 bool OraHandler::canRead() const
0026 {
0027     if (canRead(device())) {
0028         setFormat("ora");
0029         return true;
0030     }
0031     return false;
0032 }
0033 
0034 bool OraHandler::read(QImage *image)
0035 {
0036     KZip zip(device());
0037     if (!zip.open(QIODevice::ReadOnly)) {
0038         return false;
0039     }
0040 
0041     const KArchiveEntry *entry = zip.directory()->entry(QStringLiteral("mergedimage.png"));
0042     if (!entry || !entry->isFile()) {
0043         return false;
0044     }
0045 
0046     const KZipFileEntry *fileZipEntry = static_cast<const KZipFileEntry *>(entry);
0047 
0048     image->loadFromData(fileZipEntry->data(), "PNG");
0049 
0050     return true;
0051 }
0052 
0053 bool OraHandler::canRead(QIODevice *device)
0054 {
0055     if (!device) {
0056         qWarning("OraHandler::canRead() called with no device");
0057         return false;
0058     }
0059     if (device->isSequential()) {
0060         return false;
0061     }
0062 
0063     char buff[54];
0064     if (device->peek(buff, sizeof(buff)) == sizeof(buff)) {
0065         return memcmp(buff + 0x26, s_magic, s_magic_size) == 0;
0066     }
0067 
0068     return false;
0069 }
0070 
0071 QImageIOPlugin::Capabilities OraPlugin::capabilities(QIODevice *device, const QByteArray &format) const
0072 {
0073     if (format == "ora" || format == "ORA") {
0074         return Capabilities(CanRead);
0075     }
0076     if (!format.isEmpty()) {
0077         return {};
0078     }
0079     if (!device->isOpen()) {
0080         return {};
0081     }
0082 
0083     Capabilities cap;
0084     if (device->isReadable() && OraHandler::canRead(device)) {
0085         cap |= CanRead;
0086     }
0087     return cap;
0088 }
0089 
0090 QImageIOHandler *OraPlugin::create(QIODevice *device, const QByteArray &format) const
0091 {
0092     QImageIOHandler *handler = new OraHandler;
0093     handler->setDevice(device);
0094     handler->setFormat(format);
0095     return handler;
0096 }
0097 
0098 #include "moc_ora.cpp"