22 #include <QtGui/QImage>
23 #include <QtCore/QDataStream>
55 static QDataStream &
operator>> ( QDataStream & s, PSDHeader & header )
57 s >> header.signature;
59 for(
int i = 0; i < 6; i++ ) {
60 s >> header.reserved[i];
62 s >> header.channel_count;
66 s >> header.color_mode;
69 static bool seekBy(QDataStream& s,
unsigned int bytes)
73 unsigned int num= qMin(bytes,(
unsigned int )
sizeof(buf));
75 s.readRawData(buf, l);
84 static bool IsValid(
const PSDHeader & header )
86 if( header.signature != 0x38425053 ) {
95 if( header.version != 1 ) {
98 if( header.channel_count > 16 ) {
101 if( header.depth != 8 ) {
104 if( header.color_mode != CM_RGB ) {
111 static bool LoadPSD( QDataStream & s,
const PSDHeader & header, QImage & img )
114 img = QImage( header.width, header.height, QImage::Format_RGB32 );
120 s.device()->seek( s.device()->pos() + tmp );
124 s.device()->seek( s.device()->pos() + tmp );
128 s.device()->seek( s.device()->pos() + tmp );
137 if( compression > 1 ) {
142 uint channel_num = header.channel_count;
145 if( channel_num < 4 ) {
146 img.fill(
qRgba(0, 0, 0, 0xFF));
150 img = img.convertToFormat(QImage::Format_ARGB32);
156 const uint pixel_count = header.height * header.width;
158 static const uint components[4] = {2, 1, 0, 3};
163 if(!seekBy(s, header.height*header.channel_count*
sizeof(
ushort)))
167 for(
uint channel = 0; channel < channel_num; channel++) {
169 uchar * ptr = img.bits() + components[channel];
172 while( count < pixel_count ) {
183 if ( count > pixel_count )
192 else if( len > 128 ) {
198 if(s.atEnd() || count > pixel_count)
208 else if( len == 128 ) {
219 for(
uint channel = 0; channel < channel_num; channel++) {
221 uchar * ptr = img.bits() + components[channel];
224 uint count = pixel_count;
225 while( count != 0 ) {
254 QDataStream s( device() );
255 s.setByteOrder( QDataStream::BigEndian );
261 if( s.atEnd() || !
IsValid( header ) ) {
262 kDebug(399) <<
"This PSD file is not valid.";
268 kDebug(399) <<
"This PSD file is not supported.";
273 if( !LoadPSD(s, header, img) ) {
274 kDebug(399) <<
"Error loading PSD file.";
296 qWarning(
"PSDHandler::canRead() called with no device");
300 qint64 oldPos = device->pos();
303 qint64 readBytes = device->read(head,
sizeof(head));
304 if (readBytes !=
sizeof(head)) {
305 if (device->isSequential()) {
306 while (readBytes > 0)
307 device->ungetChar(head[readBytes-- - 1]);
309 device->seek(oldPos);
314 if (device->isSequential()) {
315 while (readBytes > 0)
316 device->ungetChar(head[readBytes-- - 1]);
318 device->seek(oldPos);
321 return qstrncmp(head,
"8BPS", 4) == 0;
325 class PSDPlugin :
public QImageIOPlugin
328 QStringList keys()
const;
329 Capabilities capabilities(QIODevice *device,
const QByteArray &format)
const;
330 QImageIOHandler *create(QIODevice *device,
const QByteArray &format = QByteArray())
const;
333 QStringList PSDPlugin::keys()
const
335 return QStringList() <<
"psd" <<
"PSD";
338 QImageIOPlugin::Capabilities PSDPlugin::capabilities(QIODevice *device,
const QByteArray &format)
const
340 if (format ==
"psd" || format ==
"PSD")
341 return Capabilities(CanRead);
342 if (!format.isEmpty())
344 if (!device->isOpen())
353 QImageIOHandler *PSDPlugin::create(QIODevice *device,
const QByteArray &format)
const
356 handler->setDevice(device);
357 handler->setFormat(format);
361 Q_EXPORT_STATIC_PLUGIN(PSDPlugin)
362 Q_EXPORT_PLUGIN2(psd, PSDPlugin)
bool write(const QImage &image)
static QDataStream & operator>>(QDataStream &s, DDSPixelFormat &pf)
static bool IsSupported(const DDSHeader &header)
static bool IsValid(const DDSHeader &header)
QRgb qRgba(const QRgb &rgb, int a)
Change a QRgb value's alpha only.