Krita Source Code Documentation
Loading...
Searching...
No Matches
psd_resource_block.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2009 Boudewijn Rempt <boud@valdyas.org>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
7
8#include <QBuffer>
9#include <QDataStream>
10#include <QIODevice>
11
12#include <kis_debug.h>
13
14#include "psd.h"
16#include "psd_utils.h"
17
19 : KisAnnotation("PSD Resource Block", "", QByteArray())
20 , identifier(PSDImageResourceSection::UNKNOWN)
21 , dataSize(0)
22 , resource(0)
23{
24}
25
26bool PSDResourceBlock::read(QIODevice &io)
27{
28 dbgFile << "Reading resource block";
29 if (io.atEnd()) {
30 error = "Could not read resource block: no bytes left.";
31 return false;
32 }
33
34 QByteArray b;
35 b = io.read(4);
36 if (b.size() != 4 || QString(b) != "8BIM") {
37 error = QString("Could not read resource block signature. Got %1.").arg(QString(b));
38 return false;
39 }
40
41 if (!psdread(io, identifier)) {
42 error = "Could not read resource block identifier";
43 return false;
44 }
45
47
48 m_type = QString("PSD Resource Block: %1").arg(identifier);
49
50 if (!psdread_pascalstring(io, name, 2)) {
51 error = "Could not read name of resource block";
52 return false;
53 }
54
55 dbgFile << "\tresource block name" << name;
56
57 if (!psdread(io, dataSize)) {
58 error = QString("Could not read datasize for resource block with name %1 of type %2").arg(name).arg(identifier);
59 return false;
60 }
61
62 if ((dataSize & 0x01) != 0) {
63 dataSize++;
64 }
65
66 dbgFile << "\tresource block size" << dataSize;
67
69
70 data = io.read(dataSize);
71 if (data.size() != (int)dataSize) {
72 error = QString("Could not read data for resource block with name %1 of type %2").arg(name).arg(identifier);
73 return false;
74 }
75
77
78 switch (identifier) {
79 // case PSDImageResourceSection::MAC_PRINT_INFO:
80 // resource = new MAC_PRINT_INFO_1001;
81 // break;
84 break;
85 // case PSDImageResourceSection::ALPHA_NAMES:
86 // resource = new ALPHA_NAMES_1006;
87 // break;
88 // case PSDImageResourceSection::DISPLAY_INFO:
89 // resource = new DISPLAY_INFO_1007;
90 // break;
91 // case PSDImageResourceSection::CAPTION:
92 // resource = new CAPTION_1008;
93 // break;
94 // case PSDImageResourceSection::BORDER_INFO:
95 // resource = new BORDER_INFO_1009;
96 // break;
97 // case PSDImageResourceSection::BACKGROUND_COL:
98 // resource = new BACKGROUND_COL_1010;
99 // break;
100 // case PSDImageResourceSection::PRINT_FLAGS:
101 // resource = new PRINT_FLAGS_1011;
102 // break;
103 // case PSDImageResourceSection::GREY_HALFTONE:
104 // resource = new GREY_HALFTONE_1012;
105 // break;
106 // case PSDImageResourceSection::COLOR_HALFTONE:
107 // resource = new COLOR_HALFTONE_1013;
108 // break;
109 // case PSDImageResourceSection::DUOTONE_HALFTONE:
110 // resource = new DUOTONE_HALFTONE_1014;
111 // break;
112 // case PSDImageResourceSection::GREY_XFER:
113 // resource = new GREY_XFER_1015;
114 // break;
115 // case PSDImageResourceSection::COLOR_XFER:
116 // resource = new COLOR_XFER_1016;
117 // break;
118 // case PSDImageResourceSection::DUOTONE_XFER:
119 // resource = new DUOTONE_XFER_1017;
120 // break;
121 // case PSDImageResourceSection::DUOTONE_INFO:
122 // resource = new DUOTONE_INFO_1018;
123 // break;
124 // case PSDImageResourceSection::EFFECTIVE_BW:
125 // resource = new EFFECTIVE_BW_1019;
126 // break;
127 // case PSDImageResourceSection::EPS_OPT:
128 // resource = new EPS_OPT_1021;
129 // break;
130 // case PSDImageResourceSection::QUICK_MASK:
131 // resource = new QUICK_MASK_1022;
132 // break;
133 // case PSDImageResourceSection::LAYER_STATE:
134 // resource = new LAYER_STATE_1024;
135 // break;
136 // case PSDImageResourceSection::WORKING_PATH:
137 // resource = new WORKING_PATH_1025;
138 // break;
139 // case PSDImageResourceSection::LAYER_GROUP:
140 // resource = new LAYER_GROUP_1026;
141 // break;
142 // case PSDImageResourceSection::IPTC_NAA_DATA:
143 // resource = new IPTC_NAA_DATA_1028;
144 // break;
145 // case PSDImageResourceSection::IMAGE_MODE_RAW:
146 // resource = new IMAGE_MODE_RAW_1029;
147 // break;
148 // case PSDImageResourceSection::JPEG_QUAL:
149 // resource = new JPEG_QUAL_1030;
150 // break;
153 break;
154 // case PSDImageResourceSection::THUMB_RES:
155 // resource = new THUMB_RES_1033;
156 // break;
157 // case PSDImageResourceSection::COPYRIGHT_FLG:
158 // resource = new COPYRIGHT_FLG_1034;
159 // break;
160 // case PSDImageResourceSection::URL:
161 // resource = new URL_1035;
162 // break;
163 // case PSDImageResourceSection::THUMB_RES2:
164 // resource = new THUMB_RES2_1036;
165 // break;
168 break;
169 // case PSDImageResourceSection::COLOR_SAMPLER:
170 // resource = new COLOR_SAMPLER_1038;
171 // break;
174 break;
175 // case PSDImageResourceSection::WATERMARK:
176 // resource = new WATERMARK_1040;
177 // break;
178 // case PSDImageResourceSection::ICC_UNTAGGED:
179 // resource = new ICC_UNTAGGED_1041;
180 // break;
181 // case PSDImageResourceSection::EFFECTS_VISIBLE:
182 // resource = new EFFECTS_VISIBLE_1042;
183 // break;
184 // case PSDImageResourceSection::SPOT_HALFTONE:
185 // resource = new SPOT_HALFTONE_1043;
186 // break;
187 // case PSDImageResourceSection::DOC_IDS:
188 // resource = new DOC_IDS_1044;
189 // break;
190 // case PSDImageResourceSection::ALPHA_NAMES_UNI:
191 // resource = new ALPHA_NAMES_UNI_1045;
192 // break;
193 // case PSDImageResourceSection::IDX_COL_TAB_CNT:
194 // resource = new IDX_COL_TAB_CNT_1046;
195 // break;
196 // case PSDImageResourceSection::IDX_TRANSPARENT:
197 // resource = new IDX_TRANSPARENT_1047;
198 // break;
201 break;
202 // case PSDImageResourceSection::SLICES:
203 // resource = new SLICES_1050;
204 // break;
205 // case PSDImageResourceSection::WORKFLOW_URL_UNI:
206 // resource = new WORKFLOW_URL_UNI_1051;
207 // break;
208 // case PSDImageResourceSection::JUMP_TO_XPEP:
209 // resource = new JUMP_TO_XPEP_1052;
210 // break;
211 // case PSDImageResourceSection::ALPHA_ID:
212 // resource = new ALPHA_ID_1053;
213 // break;
214 // case PSDImageResourceSection::URL_LIST_UNI:
215 // resource = new URL_LIST_UNI_1054;
216 // break;
217 // case PSDImageResourceSection::VERSION_INFO:
218 // resource = new VERSION_INFO_1057;
219 // break;
220 // case PSDImageResourceSection::EXIF_DATA:
221 // resource = new EXIF_DATA_1058;
222 // break;
223 // case PSDImageResourceSection::XMP_DATA:
224 // resource = new XMP_DATA_1060;
225 // break;
226 // case PSDImageResourceSection::PATH_INFO_FIRST:
227 // resource = new PATH_INFO_FIRST_2000;
228 // break;
229 // case PSDImageResourceSection::PATH_INFO_LAST:
230 // resource = new PATH_INFO_LAST_2998;
231 // break;
232 // case PSDImageResourceSection::CLIPPING_PATH:
233 // resource = new CLIPPING_PATH_2999;
234 // break;
235 // case PSDImageResourceSection::PRINT_FLAGS_2:
236 // resource = new PRINT_FLAGS_2_10000;
237 // break;
238 default:;
239 }
240
241 if (resource) {
243 }
244
245 return valid();
246}
247
248bool PSDResourceBlock::write(QIODevice &io) const
249{
251
252 if (resource && !resource->valid()) {
253 error = QString("Cannot write an invalid Resource Block");
254 return false;
255 }
256
265 dbgFile << "Skip writing resource block" << identifier << displayText();
266 return true;
267 }
268
269 QByteArray ba;
270
271 // createBlock returns true by default but does not change the data.
272 if (resource && !resource->createBlock(ba)) {
274 return false;
275 } else if (!resource) {
276 // reconstruct from the data
277 QBuffer buf(&ba);
278 buf.open(QBuffer::WriteOnly);
279 psdwrite(buf, "8BIM");
280 psdwrite(buf, identifier);
282 psdwrite(buf, dataSize);
283 buf.write(data);
284 buf.close();
285 }
286 if (io.write(ba.constData(), ba.size()) != ba.size()) {
287 error = QString("Could not write complete resource");
288 return false;
289 }
290
291 return true;
292}
293
295{
297 error = QString("Unknown ID: %1").arg(identifier);
298 return false;
299 }
300 if (data.size() != (int)dataSize) {
301 error = QString("Needed %1 bytes, got %2 bytes of data").arg(dataSize).arg(data.length());
302 return false;
303 }
304 return true;
305}
306
308{
309 dbgFile << "Reading RESN_INFO_1005";
310
311 // the resolution we set on the image should be dpi; we can also set the unit on the KisDocument.
312 QDataStream ds(data);
313 ds.setByteOrder(QDataStream::BigEndian);
314
315 ds >> hRes >> hResUnit >> widthUnit >> vRes >> vResUnit >> heightUnit;
316
317 /* Resolution always recorded as pixels / inch in a fixed point implied
318 decimal int32 with 16 bits before point and 16 after (i.e. cast as
319 double and divide resolution by 2^16 */
320 dbgFile << "hres" << hRes << "vres" << vRes;
321
322 hRes = hRes / 65536.0;
323 vRes = vRes / 65536.0;
324
326
327 return ds.atEnd();
328}
329
330bool RESN_INFO_1005::createBlock(QByteArray &data)
331{
332 dbgFile << "Writing RESN_INFO_1005";
333 QBuffer buf(&data);
334
336
337 // Convert to 16.16 fixed point
338 Fixed h = hRes * 65536.0 + 0.5;
339 dbgFile << "h" << h << "hRes" << hRes;
340 psdwrite(buf, h);
341 psdwrite(buf, hResUnit);
342 psdwrite(buf, widthUnit);
343
344 // Convert to 16.16 fixed point
345 Fixed v = vRes * 65536.0 + 0.5;
346 dbgFile << "v" << v << "vRes" << vRes;
347 psdwrite(buf, v);
348 psdwrite(buf, vResUnit);
349 psdwrite(buf, heightUnit);
350
351 buf.close();
352
353 return true;
354}
355
357{
358 dbgFile << "Reading ICC_PROFILE_1039";
359
360 icc = data;
361
362 return true;
363}
364
365bool ICC_PROFILE_1039::createBlock(QByteArray &data)
366{
367 dbgFile << "Writing ICC_PROFILE_1039";
368 if (icc.size() == 0) {
369 error = "ICC_PROFILE_1039: Trying to save an empty profile";
370 return false;
371 }
372 QBuffer buf(&data);
374 buf.write(icc.constData(), icc.size());
375 buf.close();
376
377 return true;
378}
qreal v
A data extension mechanism for Krita.
QString m_description
QByteArray m_annotation
static QString idToString(PSDResourceID id)
virtual bool createBlock(QByteArray &)
virtual bool interpretBlock(QByteArray)
void startBlock(QBuffer &buf, PSDImageResourceSection::PSDResourceID id, quint32 size)
bool read(QIODevice &io)
PSDInterpretedResource * resource
bool write(QIODevice &io) const
QString displayText() const override
displayText: override this to return an interpreted version of the annotation
#define dbgFile
Definition kis_debug.h:53
qint32 Fixed
Definition psd.h:31
std::enable_if_t< std::is_arithmetic< T >::value, bool > psdread(QIODevice &io, T &v)
Definition psd_utils.h:397
bool psdwrite_pascalstring(QIODevice &io, const QString &s)
Definition psd_utils.h:188
bool psdread_pascalstring(QIODevice &io, QString &s, qint64 padding)
Definition psd_utils.h:417
std::enable_if_t< std::is_arithmetic< T >::value, bool > psdwrite(QIODevice &io, T v)
Definition psd_utils.h:170
bool createBlock(QByteArray &data) override
bool interpretBlock(QByteArray data) override
bool createBlock(QByteArray &data) override
bool interpretBlock(QByteArray data) override