Author: jghali
Date: Thu Mar 19 21:40:44 2020
New Revision: 23519

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=23519
Log:
Search for potential ICC profile information also in Krita's mergedimage.png 
files

Modified:
    trunk/Scribus/scribus/imagedataloaders/scimgdataloader_kra.cpp
    trunk/Scribus/scribus/imagedataloaders/scimgdataloader_kra.h

Modified: trunk/Scribus/scribus/imagedataloaders/scimgdataloader_kra.cpp
URL: 
http://scribus.net/websvn/diff.php?repname=Scribus&rev=23519&path=/trunk/Scribus/scribus/imagedataloaders/scimgdataloader_kra.cpp
==============================================================================
--- trunk/Scribus/scribus/imagedataloaders/scimgdataloader_kra.cpp      
(original)
+++ trunk/Scribus/scribus/imagedataloaders/scimgdataloader_kra.cpp      Thu Mar 
19 21:40:44 2020
@@ -4,13 +4,20 @@
 a copyright and/or license notice that predates the release of Scribus 1.3.2
 for which a new license (GPL+exception) is in place.
 */
+#include <QBuffer>
+#include <QDomDocument>
+#include <QDomElement>
 #include <QFile>
 #include <QFileInfo>
 #include <QByteArray>
 #include <QList>
 #include <QScopedPointer>
 
+#include <png.h>
+
+#include "colormgmt/sccolormgmtengine.h"
 #include "scimgdataloader_kra.h"
+#include "scribuscore.h"
 #include "util_formats.h"
 
 ScImgDataLoader_KRA::ScImgDataLoader_KRA()
@@ -24,10 +31,123 @@
        m_supportedFormats.append("kra");
 }
 
+static void ScImgDataLoader_KRA_read_fn(png_structp pngPtr, png_bytep data, 
png_size_t length)
+{
+       QBuffer *buffer = (QBuffer*) png_get_io_ptr(pngPtr);
+
+       while (length)
+       {
+               int nr = buffer->read((char*) data, length);
+               if (nr <= 0)
+               {
+                       png_error(pngPtr, "Read Error");
+                       return;
+               }
+               length -= nr;
+       }
+}
+
+QByteArray ScImgDataLoader_KRA::getICCProfileFromPNGData(QByteArray& pngData)
+{
+       QByteArray profileData;
+       if (pngData.size() <= 0)
+               return QByteArray();
+
+       QBuffer pngBuffer(&pngData);
+       if (!pngBuffer.open(QFile::ReadOnly))
+               return QByteArray();
+
+       png_byte pngSignature[8];
+       pngBuffer.peek((char*) pngSignature, 8);
+       if (png_sig_cmp(pngSignature, 0, 8) != 0)
+       {
+               pngBuffer.close();
+               return QByteArray();
+       }
+
+       png_structp pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 
0, 0);
+       if (!pngPtr)
+       {
+               pngBuffer.close();
+               return QByteArray();
+       }
+
+       png_infop pngInfo = png_create_info_struct(pngPtr);
+       if (!pngInfo)
+       {
+               png_destroy_read_struct(&pngPtr, (png_infopp) NULL, 
(png_infopp) NULL);
+               pngBuffer.close();
+               return QByteArray();
+       }
+
+       // Catch errors (huh!!! we have to use setjump)
+       if (setjmp(png_jmpbuf(pngPtr)))
+       {
+               png_destroy_read_struct(&pngPtr, &pngInfo, (png_infopp) NULL);
+               pngBuffer.close();
+               return QByteArray();
+       }
+
+       png_set_read_fn(pngPtr, &pngBuffer, ScImgDataLoader_KRA_read_fn);
+       png_read_info(pngPtr, pngInfo);
+
+       // Read image profile
+    png_charp profileName;
+       png_bytep profileBuffer;
+       int compression_type;
+       png_uint_32 profileLen;
+
+       if (png_get_iCCP(pngPtr, pngInfo, &profileName, &compression_type, 
&profileBuffer, &profileLen))
+       {
+               QByteArray profArray = QByteArray((const char*) profileBuffer, 
profileLen);
+               if ((profArray.size() >= 40) && (profArray[36] == 'a') && 
(profArray[37] == 'c') && (profArray[38] == 's') && (profArray[39] == 'p'))
+                       profileData = profArray;
+       }
+       else if (png_get_valid(pngPtr, pngInfo, PNG_INFO_sRGB))
+       {
+               QByteArray profArray;
+               ScColorProfile prof = 
ScCore->defaultEngine.createProfile_sRGB();
+               if (prof.save(profArray))
+                       profileData = profArray;
+       }
+
+    pngBuffer.close();
+    png_destroy_read_struct(&pngPtr, &pngInfo, (png_infopp) NULL);
+
+       return profileData;
+}
+
 void ScImgDataLoader_KRA::loadEmbeddedProfile(const QString& fn, int /*page*/)
 {
        m_embeddedProfile.resize(0);
        m_profileComponents = 0;
+
+       QScopedPointer<ScZipHandler> uz(new ScZipHandler());
+       if (!uz->open(fn))
+               return;
+
+       if (!uz->contains("mergedimage.png"))
+               return;
+
+       QByteArray im;
+       if (!uz->read("mergedimage.png", im))
+               return;
+
+       QByteArray profileData = getICCProfileFromPNGData(im);
+       if (profileData.isEmpty())
+               return;
+
+       ScColorProfile prof = 
ScCore->defaultEngine.openProfileFromMem(profileData);
+       if (prof && prof.isSuitableForOutput())
+       {
+               if (prof.colorSpace() == ColorSpace_Rgb)
+                       m_profileComponents = 3;
+               if (prof.colorSpace() == ColorSpace_Cmyk)
+                       m_profileComponents = 4;
+               if (prof.colorSpace() == ColorSpace_Gray)
+                       m_profileComponents = 1;
+               m_embeddedProfile = profileData;
+       }
 }
 
 bool ScImgDataLoader_KRA::loadPicture(const QString& fn, int /*page*/, int 
/*res*/, bool thumbnail)
@@ -142,6 +262,22 @@
        m_imageInfoRecord.colorspace = ColorSpaceRGB;
        m_pixelFormat = Format_BGRA_8;
 
+       QByteArray profileData = getICCProfileFromPNGData(im);
+       if (profileData.size() > 0)
+       {
+               ScColorProfile prof = 
ScCore->defaultEngine.openProfileFromMem(profileData);
+               if (prof && prof.isSuitableForOutput())
+               {
+                       if (prof.colorSpace() == ColorSpace_Rgb)
+                               m_profileComponents = 3;
+                       if (prof.colorSpace() == ColorSpace_Cmyk)
+                               m_profileComponents = 4;
+                       if (prof.colorSpace() == ColorSpace_Gray)
+                               m_profileComponents = 1;
+                       m_embeddedProfile = profileData;
+               }
+       }
+
        uz->close();
        return true;
 }

Modified: trunk/Scribus/scribus/imagedataloaders/scimgdataloader_kra.h
URL: 
http://scribus.net/websvn/diff.php?repname=Scribus&rev=23519&path=/trunk/Scribus/scribus/imagedataloaders/scimgdataloader_kra.h
==============================================================================
--- trunk/Scribus/scribus/imagedataloaders/scimgdataloader_kra.h        
(original)
+++ trunk/Scribus/scribus/imagedataloaders/scimgdataloader_kra.h        Thu Mar 
19 21:40:44 2020
@@ -7,22 +7,24 @@
 #ifndef SCIMGDATALOADER_KRA_H
 #define SCIMGDATALOADER_KRA_H
 
+#include <QByteArray>
+
 #include "scimgdataloader.h"
 #include "scpainter.h"
 #include "third_party/zip/scribus_zip.h"
-#include <QDomDocument>
-#include <QDomElement>
 
 class ScImgDataLoader_KRA : public ScImgDataLoader
 {
 public:
-               ScImgDataLoader_KRA();
+       ScImgDataLoader_KRA();
 
        virtual bool preloadAlphaChannel(const QString& fn, int page, int res, 
bool& hasAlpha);
        virtual void loadEmbeddedProfile(const QString& fn, int page = 0);
        virtual bool loadPicture(const QString& fn, int page, int res, bool 
thumbnail);
+
 protected:
        void initSupportedFormatList();
+       QByteArray getICCProfileFromPNGData(QByteArray& pngData);
 };
 
 #endif


_______________________________________________
scribus-commit mailing list
[email protected]
http://lists.scribus.net/mailman/listinfo/scribus-commit

Reply via email to