r23519 by jghali - Search for potential ICC profile information also in Krita's mergedimage.png files

scribus-commit scribus-commit at lists.scribus.net
Thu Mar 19 21:40:44 UTC 2020


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




More information about the scribus-commit mailing list