Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_asl_reader_utils.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2015 Dmitry Kazakov <dimula73@gmail.com>
3 * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8#ifndef __KIS_ASL_READER_UTILS_H
9#define __KIS_ASL_READER_UTILS_H
10
11#include "psd.h"
12#include "psd_utils.h"
13
14#include <algorithm>
15#include <stdexcept>
16#include <string>
17
18#include <QtEndian>
19
20#include <kis_debug.h>
21
26#define GARBAGE_VALUE_MARK 999
27
29{
36struct KRITAPSDUTILS_EXPORT ASLParseException : public std::runtime_error {
37 ASLParseException(const QString &msg)
38 : std::runtime_error(msg.toLatin1().data())
39 {
40 }
41};
42
43}
44
45#define SAFE_READ_EX(byteOrder, device, varname) \
46 if (!psdread<byteOrder>(device, varname)) { \
47 QString msg = QString("Failed to read \'%1\' tag!").arg(#varname); \
48 throw KisAslReaderUtils::ASLParseException(msg); \
49 }
50
51#define SAFE_READ_SIGNATURE_EX(byteOrder, device, varname, expected) \
52 if (!psdread<byteOrder>(device, varname) || varname != expected) { \
53 QString msg = QString( \
54 "Failed to check signature \'%1\' tag!\n" \
55 "Value: \'%2\' Expected: \'%3\'") \
56 .arg(#varname) \
57 .arg(varname) \
58 .arg(expected); \
59 throw KisAslReaderUtils::ASLParseException(msg); \
60 }
61
62template<psd_byte_order byteOrder, typename T, size_t S>
63inline bool TRY_READ_SIGNATURE_2OPS_EX(QIODevice &device, const std::array<T, S> &expected1, const std::array<T, S> &expected2)
64{
65 QByteArray bytes = device.peek(S);
66
67 if (byteOrder == psd_byte_order::psdLittleEndian) {
68 std::reverse(bytes.begin(), bytes.end());
69 }
70
71 if (bytes.size() != S) {
72 return false;
73 }
74
75 // If read successfully, adjust current position of the io device
76
77 if (std::equal(bytes.constBegin(), bytes.constEnd(), expected1.begin())
78 || std::equal(bytes.constBegin(), bytes.constEnd(), expected2.begin())) {
79 // read, not seek, to support sequential devices
80 auto bytesRead = psdreadBytes(device, S);
81 if (bytesRead.size() == S) {
82 return true;
83 }
84 }
85
86 dbgFile << "Photoshop signature verification failed! Got: " << bytes.toHex() << "(" << QString(bytes) << ")";
87 return false;
88}
89
90template<typename T, size_t S>
91inline bool TRY_READ_SIGNATURE_2OPS_EX(psd_byte_order byteOrder, QIODevice &device, const std::array<T, S> &expected1, const std::array<T, S> &expected2)
92{
93 switch (byteOrder) {
95 return TRY_READ_SIGNATURE_2OPS_EX<psd_byte_order::psdLittleEndian>(device, expected1, expected2);
96 default:
97 return TRY_READ_SIGNATURE_2OPS_EX<psd_byte_order::psdBigEndian>(device, expected1, expected2);
98 }
99}
100
101namespace KisAslReaderUtils
102{
114template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
115inline QString readStringCommon(QIODevice &device, int length)
116{
117 QByteArray data = psdreadBytes<byteOrder>(device, length);
118
119 if (data.size() != length) {
120 QString msg = QString(
121 "Failed to read a string! "
122 "Bytes read: %1 Expected: %2")
123 .arg(data.size())
124 .arg(length);
125 throw ASLParseException(msg);
126 }
127
128 return QString(data);
129}
130
131template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
132inline QString readFixedString(QIODevice &device)
133{
134 return readStringCommon<byteOrder>(device, 4);
135}
136
137template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
138inline QString readVarString(QIODevice &device)
139{
140 quint32 length = 0;
141 SAFE_READ_EX(byteOrder, device, length);
142
143 if (!length) {
144 length = 4;
145 }
146
147 return readStringCommon<byteOrder>(device, length);
148}
149
150template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
151inline QString readPascalString(QIODevice &device)
152{
153 quint8 length = 0;
154 SAFE_READ_EX(byteOrder, device, length);
155
156 return readStringCommon(device, length);
157}
158
159template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
160inline QString readUnicodeString(QIODevice &device)
161{
162 QString string;
163
164 if (!psdread_unicodestring<byteOrder>(device, string)) {
165 QString msg = QString("Failed to read a unicode string!");
166 throw ASLParseException(msg);
167 }
168
169 return string;
170}
171}
172
173#endif /* __KIS_ASL_READER_UTILS_H */
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
Eigen::Matrix< double, 4, 2 > S
bool TRY_READ_SIGNATURE_2OPS_EX(QIODevice &device, const std::array< T, S > &expected1, const std::array< T, S > &expected2)
#define SAFE_READ_EX(byteOrder, device, varname)
#define dbgFile
Definition kis_debug.h:53
QString readVarString(QIODevice &device)
QString readFixedString(QIODevice &device)
QString readPascalString(QIODevice &device)
QString readUnicodeString(QIODevice &device)
QString readStringCommon(QIODevice &device, int length)
psd_byte_order
Definition psd.h:33
QByteArray psdreadBytes(QIODevice &io, qint64 v)
Definition psd_utils.h:407