1/*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2013 Boudewijn Rempt <boud@valdyas.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6
7 This code is based on Thacher Ulrich PSD loading code released
8 on public domain. See: http://tulrich.com/geekstuff/
9*/
10
11#include "kra.h"
12
13#include <kzip.h>
14
15#include <QFile>
16#include <QIODevice>
17#include <QImage>
18
19static constexpr char s_magic[] = "application/x-krita";
20static constexpr int s_magic_size = sizeof(s_magic) - 1; // -1 to remove the last \0
21
22KraHandler::KraHandler()
23{
24}
25
26bool KraHandler::canRead() const
27{
28 if (canRead(device: device())) {
29 setFormat("kra");
30 return true;
31 }
32 return false;
33}
34
35bool KraHandler::read(QImage *image)
36{
37 KZip zip(device());
38 if (!zip.open(mode: QIODevice::ReadOnly)) {
39 return false;
40 }
41
42 const KArchiveEntry *entry = zip.directory()->entry(QStringLiteral("mergedimage.png"));
43 if (!entry || !entry->isFile()) {
44 return false;
45 }
46
47 const KZipFileEntry *fileZipEntry = static_cast<const KZipFileEntry *>(entry);
48
49 image->loadFromData(data: fileZipEntry->data(), format: "PNG");
50
51 return true;
52}
53
54bool KraHandler::canRead(QIODevice *device)
55{
56 if (!device) {
57 qWarning(msg: "KraHandler::canRead() called with no device");
58 return false;
59 }
60 if (device->isSequential()) {
61 return false;
62 }
63
64 char buff[57];
65 if (device->peek(data: buff, maxlen: sizeof(buff)) == sizeof(buff)) {
66 return memcmp(s1: buff + 0x26, s2: s_magic, n: s_magic_size) == 0;
67 }
68
69 return false;
70}
71
72QImageIOPlugin::Capabilities KraPlugin::capabilities(QIODevice *device, const QByteArray &format) const
73{
74 if (format == "kra" || format == "KRA") {
75 return Capabilities(CanRead);
76 }
77 if (!format.isEmpty()) {
78 return {};
79 }
80 if (!device->isOpen()) {
81 return {};
82 }
83
84 Capabilities cap;
85 if (device->isReadable() && KraHandler::canRead(device)) {
86 cap |= CanRead;
87 }
88 return cap;
89}
90
91QImageIOHandler *KraPlugin::create(QIODevice *device, const QByteArray &format) const
92{
93 QImageIOHandler *handler = new KraHandler;
94 handler->setDevice(device);
95 handler->setFormat(format);
96 return handler;
97}
98
99#include "moc_kra.cpp"
100

source code of kimageformats/src/imageformats/kra.cpp