diff --git a/krita/libpsd/psd_pattern.cpp b/krita/libpsd/psd_pattern.cpp index ba1bccb9e2a..be3557fac67 100644 --- a/krita/libpsd/psd_pattern.cpp +++ b/krita/libpsd/psd_pattern.cpp @@ -1,217 +1,218 @@ /* * Copyright (c) 2014 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "psd_pattern.h" #include "psd_utils.h" #include "compression.h" #include #include struct PsdPattern::Private { KoPattern *patternResource; }; PsdPattern::PsdPattern() : d(new Private()) { d->patternResource = 0; } PsdPattern::~PsdPattern() { delete d; } void PsdPattern::setPattern(KoPattern *pattern) { d->patternResource = pattern; } KoPattern *PsdPattern::pattern() const { return d->patternResource; } bool psd_write_pattern(QIODevice *io) { Q_UNUSED(io); return false; } bool psd_read_pattern(QIODevice *io) { quint32 pattern_length; psd_pattern pattern; memset(&pattern, 0, sizeof(psd_pattern)); psdread(io, &pattern_length); pattern_length = (pattern_length + 3) & ~3; psdread(io, &pattern.version); if (pattern.version != 1) return false; psdread(io, (quint32*)&pattern.color_mode); psdread(io, &pattern.height); psdread(io, &pattern.width); psdread_unicodestring(io, pattern.name); psdread_pascalstring(io, pattern.uuid, 2); if (pattern.color_mode == Indexed) { pattern.color_table.reserve(256); quint8 r; quint8 g; quint8 b; for (int i = 0; i < 256; ++i) { psdread(io, &r); psdread(io, &g); psdread(io, &b); pattern.color_table.append(qRgb(r, g, b)); } } // Now load the virtual memory array psdread(io, &pattern.version); if (pattern.version != 3) return false; quint32 vm_array_length; psdread(io, &vm_array_length); psdread(io, &pattern.top); psdread(io, &pattern.left); psdread(io, &pattern.bottom); psdread(io, &pattern.right); QImage img; if (pattern.color_mode == Indexed) { img = QImage(pattern.width, pattern.height, QImage::Format_Indexed8); img.setColorTable(pattern.color_table); } else { img = QImage(pattern.width, pattern.height, QImage::Format_ARGB32); } qint32 max_channels; psdread(io, &max_channels); QVector channelData; for (int i = 0; i < max_channels; ++i) { quint32 written; qint32 len; quint32 pixel_depth1; quint32 top; quint32 left; quint32 bottom; quint32 right; quint16 pixel_depth2; quint8 compression_mode; psdread(io, &written); psdread(io, &len); len -= 4 + 4 * 4 + 2 + 1; if (len < 0) { continue; } if (written > 0) { + // Note: channel_number is not read from the file, so always equals 0. + // Other behavior may be implemented later. if (pattern.channel_number == 0) { psdread(io, &pixel_depth1); } else { quint32 d; psdread(io, &d); - Q_ASSERT(d == pixel_depth1); } } else { quint32 d; psdread(io, &d); } psdread(io, &top); psdread(io, &left); psdread(io, &bottom); psdread(io, &right); psdread(io, &pixel_depth2); psdread(io, &compression_mode); quint32 per_channel_length = 0; if (written > 0) { if (pattern.channel_number == 0) { qint32 pixels; qint32 length; pixels = length = pattern.width * pattern.height; switch(pixel_depth1) { case 1: length = (pattern.width + 7) / 8 * pattern.height; break; case 8: break; case 16: length *= 2; pixels *= 2; default: dbgKrita << "Wrong depth for pattern"; return false; } per_channel_length = length; Q_UNUSED(per_channel_length); // wtf!? switch(pattern.color_mode) { case Bitmap: case Indexed: break; case Grayscale: case DuoTone: length *= 2; break; case RGB: length *= 4; break; case CMYK: length *= 5; break; case Lab: length *= 4; break; case MultiChannel: length *= 4; default: dbgKrita << "Impossible color mode" << pattern.color_mode; return false; } QByteArray ba = io->read(len); channelData << Compression::uncompress(length, ba, (Compression::CompressionType)compression_mode); } } } return true; }