1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2016 Alex Char.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QICNSHANDLER_P_H
6#define QICNSHANDLER_P_H
7
8#include <QtGui/qimageiohandler.h>
9#include <QtCore/qlist.h>
10
11#ifndef QT_NO_DATASTREAM
12
13#define MAKEOSTYPE(c0,c1,c2,c3) (((quint8)c0 << 24) | ((quint8)c1 << 16) | ((quint8)c2 << 8) | (quint8)c3)
14
15QT_BEGIN_NAMESPACE
16
17struct ICNSBlockHeader
18{
19 enum OS {
20 TypeIcns = MAKEOSTYPE('i', 'c', 'n', 's'), // Icns container magic
21 TypeToc = MAKEOSTYPE('T', 'O', 'C', ' '), // Table of contents
22 TypeIcnv = MAKEOSTYPE('i', 'c', 'n', 'V'), // Icon Composer version
23 // Legacy:
24 TypeClut = MAKEOSTYPE('c', 'l', 'u', 't'), // Color look-up table (pre-OS X resources)
25 TypeTile = MAKEOSTYPE('t', 'i', 'l', 'e'), // Container (icon variants)
26 TypeOver = MAKEOSTYPE('o', 'v', 'e', 'r'), // Container (icon variants)
27 TypeOpen = MAKEOSTYPE('o', 'p', 'e', 'n'), // Container (icon variants)
28 TypeDrop = MAKEOSTYPE('d', 'r', 'o', 'p'), // Container (icon variants)
29 TypeOdrp = MAKEOSTYPE('o', 'd', 'r', 'p'), // Container (icon variants)
30 };
31
32 quint32 ostype;
33 quint32 length;
34};
35
36struct ICNSEntry
37{
38 enum Group {
39 GroupUnknown = 0, // Default for invalid ones
40 GroupMini = 'm', // "mini" (16x12)
41 GroupSmall = 's', // "small" (16x16)
42 GroupLarge = 'l', // "large" (32x32)
43 GroupHuge = 'h', // "huge" (48x48)
44 GroupThumbnail = 't', // "thumbnail" (128x128)
45 GroupPortable = 'p', // "portable"? (Speculation, used for png/jp2)
46 GroupCompressed = 'c', // "compressed"? (Speculation, used for png/jp2)
47 // Legacy icons:
48 GroupICON = 'N', // "ICON" (32x32)
49 };
50 enum Depth {
51 DepthUnknown = 0, // Default for invalid or compressed ones
52 DepthMono = 1,
53 Depth4bit = 4,
54 Depth8bit = 8,
55 Depth32bit = 32
56 };
57 enum Flags {
58 Unknown = 0x0, // Default for invalid ones
59 IsIcon = 0x1, // Contains a raw icon without alpha or compressed icon
60 IsMask = 0x2, // Contains alpha mask
61 IconPlusMask = IsIcon | IsMask // Contains raw icon and mask combined in one entry (double size)
62 };
63 enum Format {
64 FormatUnknown = 0, // Default for invalid or undetermined ones
65 RawIcon, // Raw legacy icon, uncompressed
66 RLE24, // Raw 32bit icon, data is compressed
67 PNG, // Compressed icon in PNG format
68 JP2 // Compressed icon in JPEG2000 format
69 };
70
71 quint32 ostype; // Real OSType
72 quint32 variant; // Virtual OSType: a parent container, zero if parent is icns root
73 Group group; // ASCII character number
74 quint32 width; // For uncompressed icons only, zero for compressed ones for now
75 quint32 height; // For uncompressed icons only, zero for compressed ones fow now
76 Depth depth; // Color depth
77 Flags flags; // Flags to determine the type of entry
78 Format dataFormat; // Format of the image data
79 quint32 dataLength; // Length of the image data in bytes
80 qint64 dataOffset; // Offset from the initial position of the file/device
81
82 ICNSEntry() :
83 ostype(0), variant(0), group(GroupUnknown), width(0), height(0), depth(DepthUnknown),
84 flags(Unknown), dataFormat(FormatUnknown), dataLength(0), dataOffset(0)
85 {
86 }
87};
88Q_DECLARE_TYPEINFO(ICNSEntry, Q_RELOCATABLE_TYPE);
89
90class QICNSHandler : public QImageIOHandler
91{
92public:
93 QICNSHandler();
94
95 bool canRead() const override;
96 bool read(QImage *image) override;
97 bool write(const QImage &image) override;
98
99 bool supportsOption(ImageOption option) const override;
100 QVariant option(ImageOption option) const override;
101
102 int imageCount() const override;
103 bool jumpToImage(int imageNumber) override;
104 bool jumpToNextImage() override;
105
106 static bool canRead(QIODevice *device);
107
108private:
109 bool ensureScanned() const;
110 bool scanDevice();
111 bool addEntry(const ICNSBlockHeader &header, qint64 imgDataOffset, quint32 variant = 0);
112 const ICNSEntry &getIconMask(const ICNSEntry &icon) const;
113
114private:
115 enum ScanState {
116 ScanError = -1,
117 ScanNotScanned = 0,
118 ScanSuccess = 1,
119 };
120
121 int m_currentIconIndex;
122 QList<ICNSEntry> m_icons;
123 QList<ICNSEntry> m_masks;
124 ScanState m_state;
125};
126
127QT_END_NAMESPACE
128
129#endif // QT_NO_DATASTREAM
130
131#endif /* QICNSHANDLER_P_H */
132

source code of qtimageformats/src/plugins/imageformats/icns/qicnshandler_p.h