[arch-commits] Commit in calligra/trunk (PKGBUILD krita_psd2.patch)

Antonio Rojas arojas at archlinux.org
Thu Apr 30 18:28:01 UTC 2015


    Date: Thursday, April 30, 2015 @ 20:28:01
  Author: arojas
Revision: 238297

Fix loading PSD files in Krita, for real this time

Added:
  calligra/trunk/krita_psd2.patch
Modified:
  calligra/trunk/PKGBUILD

------------------+
 PKGBUILD         |    9 
 krita_psd2.patch |  754 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 760 insertions(+), 3 deletions(-)

Modified: PKGBUILD
===================================================================
--- PKGBUILD	2015-04-30 15:16:31 UTC (rev 238296)
+++ PKGBUILD	2015-04-30 18:28:01 UTC (rev 238297)
@@ -21,7 +21,7 @@
          'calligra-stage'
          'calligra-words')
 pkgver=2.9.3
-pkgrel=2
+pkgrel=3
 arch=('i686' 'x86_64')
 url='http://www.calligra-suite.org/'
 license=('FDL1.2' 'GPL2' 'LGPL')
@@ -31,9 +31,11 @@
              'openjpeg' 'kdegraphics-okular' 'pstoedit' 'vc' 'libvisio'
              'libetonyek' 'libpqxx' 'libspnav' 'postgresql') # 'libqgit2'
 groups=('calligra')
-source=("http://download.kde.org/stable/${pkgbase}-${pkgver}/${pkgbase}-${pkgver}.tar.xz" 'krita_psd.patch')
+source=("http://download.kde.org/stable/${pkgbase}-${pkgver}/${pkgbase}-${pkgver}.tar.xz" 'krita_psd.patch' 
+'krita_psd2.patch')
 md5sums=('9242b44eeeb7f13f72aeafb8e9365c07'
-         '7f90c54dc15bfeaf14c58e74f3f4aae7')
+         '7f90c54dc15bfeaf14c58e74f3f4aae7'
+         'ed427b5a854d554e4028422fa03082aa')
 
 prepare() {
   mkdir build
@@ -41,6 +43,7 @@
   cd $pkgbase-$pkgver
 # fix loading PSD files in Krita
   patch -p1 -i "$srcdir"/krita_psd.patch
+  patch -p1 -l -i "$srcdir"/krita_psd2.patch
 }
 
 build() {

Added: krita_psd2.patch
===================================================================
--- krita_psd2.patch	                        (rev 0)
+++ krita_psd2.patch	2015-04-30 18:28:01 UTC (rev 238297)
@@ -0,0 +1,754 @@
+From 039b58067e06eece1cc0c2788151b4a761847794 Mon Sep 17 00:00:00 2001
+From: Dmitry Kazakov <dimula73 at gmail.com>
+Date: Wed, 29 Apr 2015 18:20:23 +0300
+Subject: [PATCH] Properly fix PsdAdditionalLayerInfoBlock
+
+This patch ports PsdAdditionalLayerInfoBlock class into ASL framework
+so that all the offsets will be correct all the time.
+
+Also parse lfx2 section into XML as a bonus :)
+---
+ krita/libpsd/CMakeLists.txt                        |   1 +
+ krita/libpsd/asl/kis_asl_reader.cpp                | 138 ++++++-------------
+ krita/libpsd/asl/kis_asl_reader.h                  |   1 +
+ krita/libpsd/asl/kis_asl_reader_utils.cpp          |  73 ++++++++++
+ krita/libpsd/asl/kis_asl_reader_utils.h            | 122 +++++++++++++++++
+ krita/libpsd/asl/kis_asl_writer_utils.h            |   2 +-
+ .../psd/psd_additional_layer_info_block.cpp        | 147 ++++++++++-----------
+ .../formats/psd/psd_additional_layer_info_block.h  |   3 +
+ krita/plugins/formats/psd/tests/CMakeLists.txt     |   6 +-
+ .../formats/psd/tests/data/testing_psd_ls.psd      | Bin 0 -> 272169 bytes
+ krita/plugins/formats/psd/tests/kis_psd_test.cpp   |  17 +++
+ krita/plugins/formats/psd/tests/kis_psd_test.h     |   1 +
+ 12 files changed, 332 insertions(+), 179 deletions(-)
+ create mode 100644 krita/libpsd/asl/kis_asl_reader_utils.cpp
+ create mode 100644 krita/libpsd/asl/kis_asl_reader_utils.h
+ create mode 100644 krita/plugins/formats/psd/tests/data/testing_psd_ls.psd
+
+diff --git a/krita/libpsd/CMakeLists.txt b/krita/libpsd/CMakeLists.txt
+index c0beca3..ca3c48b 100644
+--- a/krita/libpsd/CMakeLists.txt
++++ b/krita/libpsd/CMakeLists.txt
+@@ -7,6 +7,7 @@ set(libkispsd_LIB_SRCS
+     psd_pattern.cpp
+ 
+     asl/kis_asl_reader.cpp
++    asl/kis_asl_reader_utils.cpp
+     asl/kis_asl_xml_parser.cpp
+     asl/kis_asl_object_catcher.cpp
+     asl/kis_asl_callback_object_catcher.cpp
+diff --git a/krita/libpsd/asl/kis_asl_reader.cpp b/krita/libpsd/asl/kis_asl_reader.cpp
+index 93afef4..4ae7a68 100644
+--- a/krita/libpsd/asl/kis_asl_reader.cpp
++++ b/krita/libpsd/asl/kis_asl_reader.cpp
+@@ -33,103 +33,11 @@
+ #include "kis_offset_on_exit_verifier.h"
+ 
+ #include "kis_asl_writer_utils.h"
+-
+-namespace Private {
+-
+-/**
+- * Default value for variabled read from a file
+- */
+-#define GARBAGE_VALUE_MARK 999
++#include "kis_asl_reader_utils.h"
+ 
+ 
+-/**
+- * Exception that is emitted when any parse error appear.
+- * Thanks to KisOffsetOnExitVerifier parsing can be continued
+- * most of the time, based on the offset values written in PSD.
+- */
+-
+-struct ASLParseException : public std::runtime_error
+-{
+-    ASLParseException(const QString &msg)
+-        : std::runtime_error(msg.toAscii().data())
+-    {
+-    }
+-};
+-
+-#define SAFE_READ_EX(device, varname)                                   \
+-    if (!psdread(device, &varname)) {                                   \
+-        QString msg = QString("Failed to read \'%1\' tag!").arg(#varname); \
+-        throw ASLParseException(msg);                                   \
+-    }
+-
+-#define SAFE_READ_SIGNATURE_EX(device, varname, expected)               \
+-    if (!psdread(device, &varname) || varname != expected) {            \
+-        QString msg = QString("Failed to check signature \'%1\' tag!\n" \
+-                              "Value: \'%2\' Expected: \'%3\'")         \
+-            .arg(#varname).arg(varname).arg(expected);                  \
+-        throw ASLParseException(msg);                                   \
+-    }
+-
+-/**
+- * String fetch functions
+- *
+- * ASL has 4 types of strings:
+- *
+- * - fixed length (4 bytes)
+- * - variable length (length (4 bytes) + string (var))
+- * - pascal (length (1 byte) + string (var))
+- * - unicode string (length (4 bytes) + null-terminated unicode string (var)
+- */
+-
+-QString readStringCommon(QIODevice *device, int length)
+-{
+-    QByteArray data;
+-    data.resize(length);
+-    qint64 dataRead = device->read(data.data(), length);
+-
+-    if (dataRead != length) {
+-        QString msg =
+-            QString("Failed to read a string! "
+-                    "Bytes read: %1 Expected: %2")
+-            .arg(dataRead).arg(length);
+-        throw ASLParseException(msg);
+-    }
+-
+-    return QString(data);
+-}
+-
+-QString readFixedString(QIODevice *device) {
+-    return readStringCommon(device, 4);
+-}
+-
+-QString readVarString(QIODevice *device) {
+-    quint32 length = 0;
+-    SAFE_READ_EX(device, length);
+-
+-    if (!length) {
+-        length = 4;
+-    }
+-
+-    return readStringCommon(device, length);
+-}
+ 
+-QString readPascalString(QIODevice *device) {
+-    quint8 length = 0;
+-    SAFE_READ_EX(device, length);
+-
+-    return readStringCommon(device, length);
+-}
+-
+-QString readUnicodeString(QIODevice *device) {
+-    QString string;
+-
+-    if (!psdread_unicodestring(device, string)) {
+-        QString msg = QString("Failed to read a unicode string!");
+-        throw ASLParseException(msg);
+-    }
+-
+-    return string;
+-}
++namespace Private {
+ 
+ /**
+  * Numerical fetch functions
+@@ -229,6 +137,8 @@ void readChildObject(QIODevice *device,
+                      QDomDocument *doc,
+                      bool skipKey = false)
+ {
++    using namespace KisAslReaderUtils;
++
+     QString key;
+ 
+     if (!skipKey) {
+@@ -298,6 +208,8 @@ void readDescriptor(QIODevice *device,
+                     QDomElement *parent,
+                     QDomDocument *doc)
+ {
++    using namespace KisAslReaderUtils;
++
+     QString name = readUnicodeString(device);
+     QString classId = readVarString(device);
+ 
+@@ -318,6 +230,8 @@ void readDescriptor(QIODevice *device,
+ QImage readVirtualArrayList(QIODevice *device,
+                             int numPlanes)
+ {
++    using namespace KisAslReaderUtils;
++
+     quint32 arrayVersion = GARBAGE_VALUE_MARK;
+     SAFE_READ_EX(device, arrayVersion);
+ 
+@@ -479,6 +393,8 @@ qint64 readPattern(QIODevice *device,
+                    QDomElement *parent,
+                    QDomDocument *doc)
+ {
++    using namespace KisAslReaderUtils;
++
+     quint32 patternSize = GARBAGE_VALUE_MARK;
+     SAFE_READ_EX(device, patternSize);
+ 
+@@ -577,6 +493,8 @@ qint64 readPattern(QIODevice *device,
+ 
+ QDomDocument readFileImpl(QIODevice *device)
+ {
++    using namespace KisAslReaderUtils;
++
+     QDomDocument doc;
+     QDomElement root = doc.createElement("asl");
+     doc.appendChild(root);
+@@ -663,9 +581,39 @@ QDomDocument KisAslReader::readFile(QIODevice *device)
+ 
+     try {
+         doc = Private::readFileImpl(device);
+-    } catch (Private::ASLParseException &e) {
++    } catch (KisAslReaderUtils::ASLParseException &e) {
+         qWarning() << "WARNING: ASL:" << e.what();
+     }
+ 
+     return doc;
+ }
++
++QDomDocument KisAslReader::readLfx2PsdSection(QIODevice *device)
++{
++    QDomDocument doc;
++
++    try {
++        {
++            quint32 objectEffectsVersion = GARBAGE_VALUE_MARK;
++            const quint32 ref = 0x00;
++            SAFE_READ_SIGNATURE_EX(device, objectEffectsVersion, ref);
++        }
++
++        {
++            quint32 descriptorVersion = GARBAGE_VALUE_MARK;
++            const quint32 ref = 0x10;
++            SAFE_READ_SIGNATURE_EX(device, descriptorVersion, ref);
++        }
++
++
++        QDomElement root = doc.createElement("asl");
++        doc.appendChild(root);
++
++        Private::readDescriptor(device, "", &root, &doc);
++
++    } catch (KisAslReaderUtils::ASLParseException &e) {
++        qWarning() << "WARNING: PSD: lfx2 section:" << e.what();
++    }
++
++    return doc;
++}
+diff --git a/krita/libpsd/asl/kis_asl_reader.h b/krita/libpsd/asl/kis_asl_reader.h
+index b28db5e..efe8e67 100644
+--- a/krita/libpsd/asl/kis_asl_reader.h
++++ b/krita/libpsd/asl/kis_asl_reader.h
+@@ -29,6 +29,7 @@ class LIBKISPSD_EXPORT KisAslReader
+ {
+ public:
+     QDomDocument readFile(QIODevice *device);
++    QDomDocument readLfx2PsdSection(QIODevice *device);
+ };
+ 
+ #endif /* __KIS_ASL_READER_H */
+diff --git a/krita/libpsd/asl/kis_asl_reader_utils.cpp b/krita/libpsd/asl/kis_asl_reader_utils.cpp
+new file mode 100644
+index 0000000..3c34aae
+--- /dev/null
++++ b/krita/libpsd/asl/kis_asl_reader_utils.cpp
+@@ -0,0 +1,73 @@
++/*
++ *  Copyright (c) 2015 Dmitry Kazakov <dimula73 at gmail.com>
++ *
++ *  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 "kis_asl_reader_utils.h"
++
++namespace KisAslReaderUtils {
++
++QString readStringCommon(QIODevice *device, int length)
++{
++    QByteArray data;
++    data.resize(length);
++    qint64 dataRead = device->read(data.data(), length);
++
++    if (dataRead != length) {
++        QString msg =
++            QString("Failed to read a string! "
++                    "Bytes read: %1 Expected: %2")
++            .arg(dataRead).arg(length);
++        throw ASLParseException(msg);
++    }
++
++    return QString(data);
++}
++
++QString readFixedString(QIODevice *device) {
++    return readStringCommon(device, 4);
++}
++
++QString readVarString(QIODevice *device) {
++    quint32 length = 0;
++    SAFE_READ_EX(device, length);
++
++    if (!length) {
++        length = 4;
++    }
++
++    return readStringCommon(device, length);
++}
++
++QString readPascalString(QIODevice *device) {
++    quint8 length = 0;
++    SAFE_READ_EX(device, length);
++
++    return readStringCommon(device, length);
++}
++
++QString readUnicodeString(QIODevice *device) {
++    QString string;
++
++    if (!psdread_unicodestring(device, string)) {
++        QString msg = QString("Failed to read a unicode string!");
++        throw ASLParseException(msg);
++    }
++
++    return string;
++}
++
++}
+diff --git a/krita/libpsd/asl/kis_asl_reader_utils.h b/krita/libpsd/asl/kis_asl_reader_utils.h
+new file mode 100644
+index 0000000..0f2f2b6
+--- /dev/null
++++ b/krita/libpsd/asl/kis_asl_reader_utils.h
+@@ -0,0 +1,122 @@
++/*
++ *  Copyright (c) 2015 Dmitry Kazakov <dimula73 at gmail.com>
++ *
++ *  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.
++ */
++
++#ifndef __KIS_ASL_READER_UTILS_H
++#define __KIS_ASL_READER_UTILS_H
++
++#include "psd_utils.h"
++
++#include <stdexcept>
++#include <string>
++
++#include <QtEndian>
++
++/**
++ * Default value for variable read from a file
++ */
++
++#define GARBAGE_VALUE_MARK 999
++
++namespace KisAslReaderUtils {
++
++/**
++ * Exception that is emitted when any parse error appear.
++ * Thanks to KisOffsetOnExitVerifier parsing can be continued
++ * most of the time, based on the offset values written in PSD.
++ */
++
++struct LIBKISPSD_EXPORT ASLParseException : public std::runtime_error
++{
++    ASLParseException(const QString &msg)
++        : std::runtime_error(msg.toAscii().data())
++    {
++    }
++};
++
++}
++
++#define SAFE_READ_EX(device, varname)                                   \
++    if (!psdread(device, &varname)) {                                   \
++        QString msg = QString("Failed to read \'%1\' tag!").arg(#varname); \
++        throw KisAslReaderUtils::ASLParseException(msg);                \
++    }
++
++#define SAFE_READ_SIGNATURE_EX(device, varname, expected)               \
++    if (!psdread(device, &varname) || varname != expected) {            \
++        QString msg = QString("Failed to check signature \'%1\' tag!\n" \
++                              "Value: \'%2\' Expected: \'%3\'")         \
++            .arg(#varname).arg(varname).arg(expected);                  \
++        throw KisAslReaderUtils::ASLParseException(msg);                \
++    }
++
++#define SAFE_READ_SIGNATURE_2OPS_EX(device, varname, expected1, expected2) \
++    if (!psdread(device, &varname) || (varname != expected1 && varname != expected2)) { \
++        QString msg = QString("Failed to check signature \'%1\' tag!\n" \
++                              "Value: \'%2\' Expected1: \'%3\' Expected2: \'%4\'") \
++            .arg(#varname).arg(varname).arg(expected1).arg(expected2);  \
++        throw KisAslReaderUtils::ASLParseException(msg);                \
++    }
++
++template <typename T>
++inline bool TRY_READ_SIGNATURE_2OPS_EX(QIODevice *device, T expected1, T expected2)
++{
++    T var;
++
++    qint64 bytesRead = device->peek((char*)&var, sizeof(T));
++    if (bytesRead != sizeof(T)) {
++        return false;
++    }
++
++    var = qFromBigEndian<T>(var);
++
++    bool result = var == expected1 || var == expected2;
++
++    // If read successfully, adjust current position of the io device
++
++    if (result) {
++        // read, not seek, to support sequential devices
++        bytesRead = device->read((char*)&var, sizeof(T));
++        if (bytesRead != sizeof(T)) {
++            return false;
++        }
++    }
++
++    return result;
++}
++
++namespace KisAslReaderUtils {
++
++/**
++ * String fetch functions
++ *
++ * ASL has 4 types of strings:
++ *
++ * - fixed length (4 bytes)
++ * - variable length (length (4 bytes) + string (var))
++ * - pascal (length (1 byte) + string (var))
++ * - unicode string (length (4 bytes) + null-terminated unicode string (var)
++ */
++
++LIBKISPSD_EXPORT QString readFixedString(QIODevice *device);
++LIBKISPSD_EXPORT QString readVarString(QIODevice *device);
++LIBKISPSD_EXPORT QString readPascalString(QIODevice *device);
++LIBKISPSD_EXPORT QString readUnicodeString(QIODevice *device);
++
++}
++
++#endif /* __KIS_ASL_READER_UTILS_H */
+diff --git a/krita/libpsd/asl/kis_asl_writer_utils.h b/krita/libpsd/asl/kis_asl_writer_utils.h
+index 58419e5..00b480a 100644
+--- a/krita/libpsd/asl/kis_asl_writer_utils.h
++++ b/krita/libpsd/asl/kis_asl_writer_utils.h
+@@ -34,7 +34,7 @@ namespace KisAslWriterUtils {
+ /**
+  * Exception that is emitted when any write error appear.
+  */
+-struct ASLWriteException : public std::runtime_error
++struct LIBKISPSD_EXPORT ASLWriteException : public std::runtime_error
+ {
+     ASLWriteException(const QString &msg)
+         : std::runtime_error(msg.toAscii().data())
+diff --git a/krita/plugins/formats/psd/psd_additional_layer_info_block.cpp b/krita/plugins/formats/psd/psd_additional_layer_info_block.cpp
+index b3eaa52..3c7c11d 100644
+--- a/krita/plugins/formats/psd/psd_additional_layer_info_block.cpp
++++ b/krita/plugins/formats/psd/psd_additional_layer_info_block.cpp
+@@ -18,9 +18,12 @@
+ 
+ #include "psd_additional_layer_info_block.h"
+ 
+-#include <QBuffer>
++#include <QDomDocument>
+ 
+-#include "psd_utils.h"
++#include <asl/kis_offset_on_exit_verifier.h>
++
++#include <asl/kis_asl_reader_utils.h>
++#include <asl/kis_asl_reader.h>
+ 
+ 
+ PsdAdditionalLayerInfoBlock::PsdAdditionalLayerInfoBlock()
+@@ -29,6 +32,22 @@ PsdAdditionalLayerInfoBlock::PsdAdditionalLayerInfoBlock()
+ 
+ bool PsdAdditionalLayerInfoBlock::read(QIODevice *io)
+ {
++    bool result = true;
++
++    try {
++        readImpl(io);
++    } catch (KisAslReaderUtils::ASLParseException &e) {
++        error = e.what();
++        result = false;
++    }
++
++    return result;
++}
++
++void PsdAdditionalLayerInfoBlock::readImpl(QIODevice* io)
++{
++    using namespace KisAslReaderUtils;
++
+     QStringList longBlocks;
+     if (m_header.version > 1) {
+         longBlocks << "LMsk" << "Lr16" << "Layr" << "Mt16" << "Mtrn" << "Alph";
+@@ -36,48 +55,36 @@ bool PsdAdditionalLayerInfoBlock::read(QIODevice *io)
+ 
+     while (!io->atEnd()) {
+ 
+-        // read all the additional layer info 8BIM blocks
+-        QByteArray b;
+-        b = io->peek(4);
+-        if (b.size() != 4 || QString(b) != "8BIM") {
+-            error = "No 8BIM marker for additional layer info block";
+-            return true;
+-        }
+-        else {
+-            io->seek(io->pos() + 4); // skip the 8BIM header we peeked ahead for
++        {
++            const quint32 refSignature1 = 0x3842494D; // '8BIM' in little-endian
++            const quint32 refSignature2 = 0x38423634; // '8B64' in little-endian
++            if (!TRY_READ_SIGNATURE_2OPS_EX(io, refSignature1, refSignature2)) {
++                break;
++            }
+         }
+ 
+-        QString key(io->read(4));
+-        if (key.size() != 4) {
+-            error = "Could not read key for additional layer info block";
+-            return false;
+-        }
++        QString key = readFixedString(io);
+         dbgFile << "found info block with key" << key;
+-        if (keys.contains(key)) {
+-            error = "Found duplicate entry for key ";
+-            continue;
+-        }
+-        keys << key;
+ 
+-        quint64 size;
++        quint64 blockSize = GARBAGE_VALUE_MARK;
+         if (longBlocks.contains(key)) {
+-            psdread(io, &size);
+-        }
+-        else {
+-            quint32 _size;
+-            psdread(io, &_size);
+-            size = _size;
++            SAFE_READ_EX(io, blockSize);
++        } else {
++            quint32 size32;
++            SAFE_READ_EX(io, size32);
++            blockSize = size32;
+         }
+ 
+-        QByteArray data = io->read(size);
+-        if (data.size() != (qint64)size) {
+-            error = QString("Could not read full info block for key %1.").arg(key);
+-            return false;
+-        }
++        // offset verifier will correct the position on the exit from
++        // current namespace, including 'continue', 'return' and
++        // exceptions.
++        SETUP_OFFSET_VERIFIER(infoBlockEndVerifier, io, blockSize, 0);
+ 
+-        dbgFile << "\tRead layer info block" << key << "for size" << data.size();
+-        QBuffer buf(&data);
+-        buf.open(QBuffer::ReadOnly);
++        if (keys.contains(key)) {
++            error = "Found duplicate entry for key ";
++            continue;
++        }
++        keys << key;
+ 
+         if (key == "SoCo") {
+ 
+@@ -140,47 +147,23 @@ bool PsdAdditionalLayerInfoBlock::read(QIODevice *io)
+ 
+         }
+         else if (key == "lrFX") {
+-//            if (!psdread(&buf, &layerEffects.version) || layerEffects.version != 0) {
+-//                dbgFile << "Layer Effect version is not zero" << layerEffects.version;
+-//                continue;
+-//            }
+-//            if (!psdread(&buf, &layerEffects.effects_count)
+-//                    || layerEffects.effects_count < 6
+-//                    || layerEffects.effects_count > 7) {
+-//                dbgFile << "Wrong number of Layer Effects " << layerEffects.effects_count;
+-//                continue;
+-//            }
+-//            for (int i = 0; i < layerEffects.effects_count; ++i) {
+-//                QByteArray b;
+-//                b = buf.peek(4);
+-//                if (b.size() != 4 || QString(b) != "8BIM") {
+-//                    error = "No 8BIM marker for lrFX block";
+-//                    return false;
+-//                }
+-//                else {
+-//                    buf.seek(buf.pos() + 4); // skip the 8BIM header we peeked ahead for
+-//                }
+-//                QString tag = QString(io->read(4));
+-//                if (tag.size() != 4) {
+-//                    error = "Could not read layer effect type tag";
+-//                    return false;
+-//                }
+-
+-//            }
+-
++            // deprecated! use lfx2 instead!
+         }
+         else if (key == "tySh") {
+         }
+         else if (key == "luni") {
+             // get the unicode layer name
+-            psdread_unicodestring(&buf, unicodeLayerName);
++            unicodeLayerName = readUnicodeString(io);
+             dbgFile << "unicodeLayerName" << unicodeLayerName;
+         }
+         else if (key == "lyid") {
+ 
+         }
+         else if (key == "lfx2") {
++            KisAslReader reader;
++            QDomDocument doc = reader.readLfx2PsdSection(io);
+ 
++            //qDebug() << ppVar(doc.toString());
+         }
+         else if (key == "Patt" || key == "Pat2" || key == "Pat3") {
+ 
+@@ -210,20 +193,27 @@ bool PsdAdditionalLayerInfoBlock::read(QIODevice *io)
+ 
+         }
+         else if (key == "lsct") {
+-            quint32 type;
+-            if (!psdread(&buf, &type)) {
+-                error = "Could not read group type";
+-                return false;
+-            }
+-            if (size >= 12) {
+-                if (!psd_read_blendmode(io, sectionDividerBlendMode)) {
+-                    error = QString("Could not read blend mode key. Got: %1").arg(sectionDividerBlendMode);
+-                    return false;
+-                }
++            quint32 dividerType = GARBAGE_VALUE_MARK;
++            SAFE_READ_EX(io, dividerType);
++            this->sectionDividerType = (psd_section_type)dividerType;
++
++
++            if (blockSize >= 12) {
++                quint32 lsctSignature = GARBAGE_VALUE_MARK;
++                const quint32 refSignature1 = 0x3842494D; // '8BIM' in little-endian
++                SAFE_READ_SIGNATURE_EX(io, lsctSignature, refSignature1);
++
++                this->sectionDividerBlendMode = readFixedString(io);
+             }
+-            if (size >= 16) {
+-                // Don't care: animation scene group
++
++            // Animation
++            if (blockSize >= 14) {
++                /**
++                 * "I don't care
++                 *  I don't care, no... !" (c)
++                 */
+             }
++
+         }
+         else if (key == "brst") {
+ 
+@@ -329,9 +319,6 @@ bool PsdAdditionalLayerInfoBlock::read(QIODevice *io)
+         }
+ 
+     }
+-    return true;
+-
+-
+ }
+ 
+ bool PsdAdditionalLayerInfoBlock::write(QIODevice */*io*/, KisNodeSP /*node*/)
+diff --git a/krita/plugins/formats/psd/psd_additional_layer_info_block.h b/krita/plugins/formats/psd/psd_additional_layer_info_block.h
+index 3028514..ff5a72e 100644
+--- a/krita/plugins/formats/psd/psd_additional_layer_info_block.h
++++ b/krita/plugins/formats/psd/psd_additional_layer_info_block.h
+@@ -267,6 +267,9 @@ public:
+     psd_section_type sectionDividerType;
+     QString sectionDividerBlendMode;
+ 
++private:
++    void readImpl(QIODevice* io);
++
+ };
+ 
+ #endif // PSD_ADDITIONAL_LAYER_INFO_BLOCK_H
+diff --git a/krita/plugins/formats/psd/tests/CMakeLists.txt b/krita/plugins/formats/psd/tests/CMakeLists.txt
+index c9f32b2..8d9573b 100644
+--- a/krita/plugins/formats/psd/tests/CMakeLists.txt
++++ b/krita/plugins/formats/psd/tests/CMakeLists.txt
+@@ -28,6 +28,6 @@ kde4_add_unit_test(compression_test TESTNAME krita-psd-compression_test  ${compr
+ target_link_libraries(compression_test ${KDE4_KDEUI_LIBS} ${QT_QTTEST_LIBRARY})
+ 
+ ########### next target ###############
+-#set(kis_psd_test_SRCS kis_psd_test.cpp )
+-#kde4_add_unit_test(kis_psd_test TESTNAME krita-plugins-formats-psd_test ${kis_psd_test_SRCS})
+-#target_link_libraries(kis_psd_test  ${KDE4_KDEUI_LIBS} kritaui ${QT_QTTEST_LIBRARY})
++set(kis_psd_test_SRCS kis_psd_test.cpp )
++kde4_add_unit_test(kis_psd_test TESTNAME krita-plugins-formats-psd_test ${kis_psd_test_SRCS})
++target_link_libraries(kis_psd_test  ${KDE4_KDEUI_LIBS} kritaui ${QT_QTTEST_LIBRARY})
+diff --git a/krita/plugins/formats/psd/tests/kis_psd_test.cpp b/krita/plugins/formats/psd/tests/kis_psd_test.cpp
+index c2a2900..181a6f1 100644
+--- a/krita/plugins/formats/psd/tests/kis_psd_test.cpp
++++ b/krita/plugins/formats/psd/tests/kis_psd_test.cpp
+@@ -36,6 +36,23 @@ void KisPSDTest::testFiles()
+     TestUtil::testFiles(QString(FILES_DATA_DIR) + "/sources", QStringList());
+ }
+ 
++void KisPSDTest::testOpening()
++{
++    QFileInfo sourceFileInfo(QString(FILES_DATA_DIR) + QDir::separator() + "testing_psd_ls.psd");
++
++    QScopedPointer<KisDocument> doc(qobject_cast<KisDocument*>(KisPart::instance()->createDocument()));
++
++    KisImportExportManager manager(doc.data());
++    manager.setBatchMode(true);
++
++    KisImportExportFilter::ConversionStatus status;
++    QString s = manager.importDocument(sourceFileInfo.absoluteFilePath(), QString(),
++                                       status);
++    qDebug() << s;
++
++    Q_ASSERT(doc->image());
++}
++
+ QTEST_KDEMAIN(KisPSDTest, GUI)
+ 
+ #include "kis_psd_test.moc"
+diff --git a/krita/plugins/formats/psd/tests/kis_psd_test.h b/krita/plugins/formats/psd/tests/kis_psd_test.h
+index 4773b6a..bc45a0c 100644
+--- a/krita/plugins/formats/psd/tests/kis_psd_test.h
++++ b/krita/plugins/formats/psd/tests/kis_psd_test.h
+@@ -26,6 +26,7 @@ class KisPSDTest : public QObject
+     Q_OBJECT
+ private Q_SLOTS:
+     void testFiles();
++    void testOpening();
+ };
+ 
+ #endif
+-- 
+2.3.7
+



More information about the arch-commits mailing list