r17758 by jghali - #11029 : Add support for 1bit monochrome images
scribus-commit
scribus-commit at lists.scribus.net
Sat Aug 18 22:29:24 UTC 2012
Author: jghali
Date: Sat Aug 18 22:29:24 2012
New Revision: 17758
URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=17758
Log:
#11029 : Add support for 1bit monochrome images
Modified:
trunk/Scribus/scribus/commonstrings.cpp
trunk/Scribus/scribus/commonstrings.h
trunk/Scribus/scribus/pdflib_core.cpp
trunk/Scribus/scribus/pdflib_core.h
trunk/Scribus/scribus/scimage.cpp
trunk/Scribus/scribus/scimage.h
trunk/Scribus/scribus/scimagestructs.h
trunk/Scribus/scribus/scimgdataloader_qt.cpp
trunk/Scribus/scribus/scimgdataloader_tiff.cpp
trunk/Scribus/scribus/util_color.cpp
Modified: trunk/Scribus/scribus/commonstrings.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17758&path=/trunk/Scribus/scribus/commonstrings.cpp
==============================================================================
--- trunk/Scribus/scribus/commonstrings.cpp (original)
+++ trunk/Scribus/scribus/commonstrings.cpp Sat Aug 18 22:29:24 2012
@@ -129,6 +129,7 @@
QString CommonStrings::trCMYK = "";
QString CommonStrings::trGrayscale = "";
QString CommonStrings::trDuotone = "";
+QString CommonStrings::trMonochrome = "";
QString CommonStrings::trUnknownCS = "";
QString CommonStrings::trVisionNormal = "";
@@ -380,6 +381,7 @@
CommonStrings::trCMYK = tr("CMYK", "Colorspace");
CommonStrings::trGrayscale = tr("Grayscale", "Colorspace");
CommonStrings::trDuotone = tr("Duotone", "Colorspace");
+ CommonStrings::trMonochrome= tr("Monochrome", "Colorspace");
CommonStrings::trUnknownCS = tr("Unknown", "Colorspace (Unknown)");
CommonStrings::trVisionNormal = tr("Normal Vision", "Color Blindness - Normal Vision");
Modified: trunk/Scribus/scribus/commonstrings.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17758&path=/trunk/Scribus/scribus/commonstrings.h
==============================================================================
--- trunk/Scribus/scribus/commonstrings.h (original)
+++ trunk/Scribus/scribus/commonstrings.h Sat Aug 18 22:29:24 2012
@@ -211,6 +211,7 @@
static QString trCMYK;
static QString trGrayscale;
static QString trDuotone;
+ static QString trMonochrome;
static QString trUnknownCS;
//Color Blindness
Modified: trunk/Scribus/scribus/pdflib_core.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17758&path=/trunk/Scribus/scribus/pdflib_core.cpp
==============================================================================
--- trunk/Scribus/scribus/pdflib_core.cpp (original)
+++ trunk/Scribus/scribus/pdflib_core.cpp Sat Aug 18 22:29:24 2012
@@ -186,7 +186,7 @@
usedFonts.clear();
doc.getUsedFonts(usedFonts);
ucs2Codec = QTextCodec::codecForName("ISO-10646-UCS-2");
- if(!ucs2Codec)
+ if (!ucs2Codec)
ucs2Codec = QTextCodec::codecForName("UTF-16");
if (!ucs2Codec)
{
@@ -470,9 +470,9 @@
return (outStream.status() == QDataStream::Ok);
}
-int PDFLibCore::WriteImageToStream(ScImage& image, int ObjNum, bool cmyk, bool gray, bool precal)
+int PDFLibCore::WriteImageToStream(ScImage& image, int ObjNum, ColorSpaceEnum format, bool precal)
{
- bool succeed = false;
+ bool fromCmyk, succeed = false;
int bytesWritten = 0;
if (Options.Encrypt)
{
@@ -480,12 +480,18 @@
ScRC4EncodeFilter rc4Encode(&outStream, step1.data(), qMin(KeyLen+5, 16));
if (rc4Encode.openFilter())
{
- if (gray)
- succeed = image.writeGrayDataToFilter(&rc4Encode, precal);
- else if (cmyk)
- succeed = image.writeCMYKDataToFilter(&rc4Encode);
- else
- succeed = image.writeRGBDataToFilter(&rc4Encode);
+ switch (format)
+ {
+ case ColorSpaceMonochrome :
+ fromCmyk = !Options.UseRGB && !Options.isGrayscale && !(doc.HasCMS && Options.UseProfiles2);
+ succeed = image.writeMonochromeDataToFilter(&rc4Encode, fromCmyk); break;
+ case ColorSpaceGray :
+ succeed = image.writeGrayDataToFilter(&rc4Encode, precal); break;
+ case ColorSpaceCMYK :
+ succeed = image.writeCMYKDataToFilter(&rc4Encode); break;
+ default :
+ succeed = image.writeRGBDataToFilter(&rc4Encode); break;
+ }
succeed &= rc4Encode.closeFilter();
bytesWritten = rc4Encode.writtenToStream();
}
@@ -495,12 +501,18 @@
ScNullEncodeFilter nullEncode(&outStream);
if (nullEncode.openFilter())
{
- if (gray)
- succeed = image.writeGrayDataToFilter(&nullEncode, precal);
- else if (cmyk)
- succeed = image.writeCMYKDataToFilter(&nullEncode);
- else
- succeed = image.writeRGBDataToFilter(&nullEncode);
+ switch (format)
+ {
+ case ColorSpaceMonochrome :
+ fromCmyk = !Options.UseRGB && !Options.isGrayscale && !(doc.HasCMS && Options.UseProfiles2);
+ succeed = image.writeMonochromeDataToFilter(&nullEncode, fromCmyk); break;
+ case ColorSpaceGray :
+ succeed = image.writeGrayDataToFilter(&nullEncode, precal); break;
+ case ColorSpaceCMYK :
+ succeed = image.writeCMYKDataToFilter(&nullEncode); break;
+ default :
+ succeed = image.writeRGBDataToFilter(&nullEncode); break;
+ }
succeed &= nullEncode.closeFilter();
bytesWritten = nullEncode.writtenToStream();
}
@@ -508,8 +520,8 @@
return (succeed ? bytesWritten : 0);
}
-int PDFLibCore::WriteJPEGImageToStream(ScImage& image, const QString& fn, int ObjNum, int quality, bool cmyk,
- bool gray, bool sameFile, bool precal)
+int PDFLibCore::WriteJPEGImageToStream(ScImage& image, const QString& fn, int ObjNum, int quality, ColorSpaceEnum format,
+ bool sameFile, bool precal)
{
bool succeed = true;
int bytesWritten = 0;
@@ -521,9 +533,9 @@
else
{
tmpFile = QDir::toNativeSeparators(ScPaths::getTempFileDir() + "sc.jpg");
- if ((gray) && (!precal))
+ if (format == ColorSpaceGray && (!precal))
image.convertToGray();
- if (image.convert2JPG(tmpFile, quality, cmyk, gray))
+ if (image.convert2JPG(tmpFile, quality, format == ColorSpaceCMYK, format == ColorSpaceGray))
jpgFileName = tmpFile;
}
if (jpgFileName.isEmpty())
@@ -551,9 +563,9 @@
return (succeed ? bytesWritten : 0);
}
-int PDFLibCore::WriteFlateImageToStream(ScImage& image, int ObjNum, bool cmyk, bool gray, bool precal)
+int PDFLibCore::WriteFlateImageToStream(ScImage& image, int ObjNum, ColorSpaceEnum format, bool precal)
{
- bool succeed = false;
+ bool fromCmyk, succeed = false;
int bytesWritten = 0;
if (Options.Encrypt)
{
@@ -562,12 +574,18 @@
ScFlateEncodeFilter flateEncode(&rc4Encode);
if (flateEncode.openFilter())
{
- if (gray)
- succeed = image.writeGrayDataToFilter(&flateEncode, precal);
- else if (cmyk)
- succeed = image.writeCMYKDataToFilter(&flateEncode);
- else
- succeed = image.writeRGBDataToFilter(&flateEncode);
+ switch (format)
+ {
+ case ColorSpaceMonochrome :
+ fromCmyk = !Options.UseRGB && !Options.isGrayscale && !(doc.HasCMS && Options.UseProfiles2);
+ succeed = image.writeMonochromeDataToFilter(&flateEncode, fromCmyk); break;
+ case ColorSpaceGray :
+ succeed = image.writeGrayDataToFilter(&flateEncode, precal); break;
+ case ColorSpaceCMYK :
+ succeed = image.writeCMYKDataToFilter(&flateEncode); break;
+ default :
+ succeed = image.writeRGBDataToFilter(&flateEncode); break;
+ }
succeed &= flateEncode.closeFilter();
bytesWritten = flateEncode.writtenToStream();
}
@@ -577,12 +595,18 @@
ScFlateEncodeFilter flateEncode(&outStream);
if (flateEncode.openFilter())
{
- if (gray)
- succeed = image.writeGrayDataToFilter(&flateEncode, precal);
- else if (cmyk)
- succeed = image.writeCMYKDataToFilter(&flateEncode);
- else
- succeed = image.writeRGBDataToFilter(&flateEncode);
+ switch (format)
+ {
+ case ColorSpaceMonochrome :
+ fromCmyk = !Options.UseRGB && !Options.isGrayscale && !(doc.HasCMS && Options.UseProfiles2);
+ succeed = image.writeMonochromeDataToFilter(&flateEncode, fromCmyk); break;
+ case ColorSpaceGray :
+ succeed = image.writeGrayDataToFilter(&flateEncode, precal); break;
+ case ColorSpaceCMYK :
+ succeed = image.writeCMYKDataToFilter(&flateEncode); break;
+ default :
+ succeed = image.writeRGBDataToFilter(&flateEncode); break;
+ }
succeed &= flateEncode.closeFilter();
bytesWritten = flateEncode.writtenToStream();
}
@@ -9290,6 +9314,18 @@
}
#endif
+/*
+ * Helper function to transition for booleans to ColorSpaceEnum. This
+ * should be removed once output format is specified directly.
+ */
+static ColorSpaceEnum getOutputType(const bool gray, const bool cmyk)
+{
+ if (gray)
+ return ColorSpaceGray;
+ if (cmyk)
+ return ColorSpaceCMYK;
+ return ColorSpaceRGB;
+}
bool PDFLibCore::PDF_Image(PageItem* c, const QString& fn, double sx, double sy, double x, double y, bool fromAN, const QString& Profil, bool Embedded, eRenderIntent Intent, QString* output)
{
@@ -9367,7 +9403,7 @@
isEmbeddedPDF = true;
ImInfo.Page = c->pixm.imgInfo.actualPageNumber;
}
- if(!imageLoaded && extensionIndicatesPDF(ext) && c->effectsInUse.count() == 0 && Options.embedPDF)
+ if (!imageLoaded && extensionIndicatesPDF(ext) && c->effectsInUse.count() == 0 && Options.embedPDF)
qDebug() << "Failed to embed the PDF file";
// no embedded PDF:
if (!imageLoaded)
@@ -9734,28 +9770,6 @@
PutDoc("<<\n/Type /XObject\n/Subtype /Image\n");
PutDoc("/Width "+QString::number(img.width())+"\n");
PutDoc("/Height "+QString::number(img.height())+"\n");
- if ((doc.HasCMS) && (Options.UseProfiles2))
- {
- PutDoc("/ColorSpace "+ICCProfiles[profInUse].ICCArray+"\n");
- PutDoc("/Intent /");
- int inte2 = Intent;
- if (Options.EmbeddedI)
- inte2 = Options.Intent2;
- static const QString cmsmode[] = {"Perceptual", "RelativeColorimetric", "Saturation", "AbsoluteColorimetric"};
- PutDoc(cmsmode[inte2] + "\n");
- }
- else
- {
- if (Options.UseRGB)
- PutDoc("/ColorSpace /DeviceRGB\n");
- else
- {
- if (Options.isGrayscale)
- PutDoc("/ColorSpace /DeviceGray\n");
- else
- PutDoc("/ColorSpace /DeviceCMYK\n");
- }
- }
enum PDFOptions::PDFCompression compress_method = Options.CompressMethod;
enum PDFOptions::PDFCompression cm = Options.CompressMethod;
bool exportToCMYK = false, exportToGrayscale = false, jpegUseOriginal = false;
@@ -9769,6 +9783,11 @@
}
if (c->OverrideCompressionMethod)
compress_method = cm = (enum PDFOptions::PDFCompression) c->CompressionMethodIndex;
+ if (img.imgInfo.colorspace == ColorSpaceMonochrome && (c->effectsInUse.count() == 0))
+ {
+ compress_method = (compress_method != PDFOptions::Compression_None) ? PDFOptions::Compression_ZIP : compress_method;
+ cm = compress_method;
+ }
if (extensionIndicatesJPEG(ext) && (cm != PDFOptions::Compression_None))
{
if (((Options.UseRGB || Options.UseProfiles2) && (cm == PDFOptions::Compression_Auto) && (c->effectsInUse.count() == 0) && (img.imgInfo.colorspace == ColorSpaceRGB)) && (!img.imgInfo.progressive) && (!((Options.RecalcPic) && (Options.PicRes < (qMax(72.0 / c->imageXScale(), 72.0 / c->imageYScale()))))))
@@ -9831,8 +9850,39 @@
}*/
}
}
+ if ((hasGrayProfile) && (doc.HasCMS) && (Options.UseProfiles2) && (!hasColorEffect))
+ exportToGrayscale = true;
int bytesWritten = 0;
- PutDoc("/BitsPerComponent 8\n");
+ // Fixme: outType variable should be set directly in the if/else maze above.
+ ColorSpaceEnum outType;
+ if (img.imgInfo.colorspace == ColorSpaceMonochrome && c->effectsInUse.count() == 0)
+ outType = ColorSpaceMonochrome;
+ else
+ outType = getOutputType(exportToGrayscale, exportToCMYK);
+ if ((outType != ColorSpaceMonochrome) && (doc.HasCMS) && (Options.UseProfiles2))
+ {
+ PutDoc("/ColorSpace "+ICCProfiles[profInUse].ICCArray+"\n");
+ PutDoc("/Intent /");
+ int inte2 = Intent;
+ if (Options.EmbeddedI)
+ inte2 = Options.Intent2;
+ static const QString cmsmode[] = {"Perceptual", "RelativeColorimetric", "Saturation", "AbsoluteColorimetric"};
+ PutDoc(cmsmode[inte2] + "\n");
+ }
+ else
+ {
+ switch (outType)
+ {
+ case ColorSpaceMonochrome :
+ case ColorSpaceGray : PutDoc("/ColorSpace /DeviceGray\n"); break;
+ case ColorSpaceCMYK : PutDoc("/ColorSpace /DeviceCMYK\n"); break;
+ default : PutDoc("/ColorSpace /DeviceRGB\n"); break;
+ }
+ }
+ if (outType == ColorSpaceMonochrome)
+ PutDoc("/BitsPerComponent 1\n");
+ else
+ PutDoc("/BitsPerComponent 8\n");
uint lengthObj = newObject();
PutDoc("/Length "+QString::number(lengthObj)+" 0 R\n");
if (cm == PDFOptions::Compression_JPEG)
@@ -9849,19 +9899,17 @@
PutDoc("/Mask "+QString::number(maskObj)+" 0 R\n");
}
PutDoc(">>\nstream\n");
- if ((hasGrayProfile) && (doc.HasCMS) && (Options.UseProfiles2) && (!hasColorEffect))
- exportToGrayscale = true;
- if (cm == PDFOptions::Compression_JPEG)
+ if (cm == PDFOptions::Compression_JPEG) // Fixme: should not do this with monochrome images?
{
int quality = c->OverrideCompressionQuality ? c->CompressionQualityIndex : Options.Quality;
if (c->OverrideCompressionQuality)
jpegUseOriginal = false;
- bytesWritten = WriteJPEGImageToStream(img, fn, imageObj, quality, exportToCMYK, exportToGrayscale, jpegUseOriginal, (!hasColorEffect && hasGrayProfile));
+ bytesWritten = WriteJPEGImageToStream(img, fn, imageObj, quality, outType, jpegUseOriginal, (!hasColorEffect && hasGrayProfile));
}
else if (cm == PDFOptions::Compression_ZIP)
- bytesWritten = WriteFlateImageToStream(img, imageObj, exportToCMYK, exportToGrayscale, (!hasColorEffect && hasGrayProfile));
+ bytesWritten = WriteFlateImageToStream(img, imageObj, outType, (!hasColorEffect && hasGrayProfile));
else
- bytesWritten = WriteImageToStream(img, imageObj, exportToCMYK, exportToGrayscale, (!hasColorEffect && hasGrayProfile));
+ bytesWritten = WriteImageToStream(img, imageObj, outType, (!hasColorEffect && hasGrayProfile));
PutDoc("\nendstream\nendobj\n");
if (bytesWritten <= 0)
{
Modified: trunk/Scribus/scribus/pdflib_core.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17758&path=/trunk/Scribus/scribus/pdflib_core.h
==============================================================================
--- trunk/Scribus/scribus/pdflib_core.h (original)
+++ trunk/Scribus/scribus/pdflib_core.h Sat Aug 18 22:29:24 2012
@@ -106,9 +106,9 @@
bool EncodeArrayToStream(const QByteArray& in, int ObjNum);
- int WriteImageToStream(ScImage& image, int ObjNum, bool cmyk, bool gray, bool precal);
- int WriteJPEGImageToStream(ScImage& image, const QString& fn, int ObjNum, int quality, bool cmyk, bool gray, bool sameFile, bool precal);
- int WriteFlateImageToStream(ScImage& image, int ObjNum, bool cmyk, bool gray, bool precal);
+ int WriteImageToStream(ScImage& image, int ObjNum, ColorSpaceEnum format, bool precal);
+ int WriteJPEGImageToStream(ScImage& image, const QString& fn, int ObjNum, int quality, ColorSpaceEnum format, bool sameFile, bool precal);
+ int WriteFlateImageToStream(ScImage& image, int ObjNum, ColorSpaceEnum format, bool precal);
void CalcOwnerKey(const QString & Owner, const QString & User);
void CalcUserKey(const QString & User, int Permission);
Modified: trunk/Scribus/scribus/scimage.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17758&path=/trunk/Scribus/scribus/scimage.cpp
==============================================================================
--- trunk/Scribus/scribus/scimage.cpp (original)
+++ trunk/Scribus/scribus/scimage.cpp Sat Aug 18 22:29:24 2012
@@ -1347,6 +1347,51 @@
return success;
}
+bool ScImage::writeMonochromeDataToFilter(ScStreamFilter* filter, bool fromCmyk)
+{
+ QRgb *s;
+ QByteArray buffer;
+ bool success = true;
+ int h = height();
+ int w = width();
+ int byteCount = 0;
+ int bufferSize = (w + 7) / 8 * h;
+ int value;
+ const unsigned char threshold = 127;
+ buffer.resize(bufferSize);
+ if (buffer.isNull()) // Memory allocation failure
+ return false;
+ for (int yi = 0; yi < h; ++yi)
+ {
+ char curByte = 0;
+ int bitCount = 0;
+ s = (QRgb*)(scanLine( yi ));
+ for (int xi = 0; xi < w; ++xi)
+ {
+ curByte <<= 1;
+ value = fromCmyk ? (255 - qAlpha(*s)) : qRed(*s);
+ if (value > threshold) // In monochrome images all elements have the same value.
+ curByte |= 1;
+ ++bitCount;
+ if (bitCount == 8)
+ {
+ buffer[byteCount++] = curByte;
+ curByte = 0;
+ bitCount = 0;
+ }
+ ++s;
+ }
+ // End of line is aligned to byte.
+ if (bitCount > 0) {
+ curByte <<= 8-bitCount;
+ buffer[byteCount++] = curByte;
+ }
+ }
+ assert(byteCount == bufferSize);
+ success = filter->writeData(buffer.constData(), byteCount);
+ return success;
+}
+
bool ScImage::writeCMYKDataToFilter(ScStreamFilter* filter)
{
QRgb r, *s;
Modified: trunk/Scribus/scribus/scimage.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17758&path=/trunk/Scribus/scribus/scimage.h
==============================================================================
--- trunk/Scribus/scribus/scimage.h (original)
+++ trunk/Scribus/scribus/scimage.h Sat Aug 18 22:29:24 2012
@@ -85,6 +85,7 @@
bool writeRGBDataToFilter(ScStreamFilter* filter);
bool writeGrayDataToFilter(ScStreamFilter* filter, bool precal);
+ bool writeMonochromeDataToFilter(ScStreamFilter* filter, bool fromCmyk);
bool writeCMYKDataToFilter(ScStreamFilter* filter);
bool writePSImageToFilter(ScStreamFilter* filter, int pl);
Modified: trunk/Scribus/scribus/scimagestructs.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17758&path=/trunk/Scribus/scribus/scimagestructs.h
==============================================================================
--- trunk/Scribus/scribus/scimagestructs.h (original)
+++ trunk/Scribus/scribus/scimagestructs.h Sat Aug 18 22:29:24 2012
@@ -118,7 +118,8 @@
ColorSpaceRGB = 0,
ColorSpaceCMYK = 1,
ColorSpaceGray = 2,
- ColorSpaceDuotone = 3
+ ColorSpaceDuotone = 3,
+ ColorSpaceMonochrome = 4
} ColorSpaceEnum;
class ImageInfoRecord
Modified: trunk/Scribus/scribus/scimgdataloader_qt.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17758&path=/trunk/Scribus/scribus/scimgdataloader_qt.cpp
==============================================================================
--- trunk/Scribus/scribus/scimgdataloader_qt.cpp (original)
+++ trunk/Scribus/scribus/scimgdataloader_qt.cpp Sat Aug 18 22:29:24 2012
@@ -47,7 +47,9 @@
yres = 72.0;
int resInf = m_imageInfoRecord.lowResType;
m_imageInfoRecord.colorspace = ColorSpaceRGB;
- if (m_image.isGrayscale() || m_image.depth() == 1)
+ if (m_image.depth() == 1)
+ m_imageInfoRecord.colorspace = ColorSpaceMonochrome;
+ else if (m_image.isGrayscale())
m_imageInfoRecord.colorspace = ColorSpaceGray;
m_image = m_image.convertToFormat(QImage::Format_ARGB32);
m_image.setDotsPerMeterX ((int) (xres / 0.0254));
Modified: trunk/Scribus/scribus/scimgdataloader_tiff.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17758&path=/trunk/Scribus/scribus/scimgdataloader_tiff.cpp
==============================================================================
--- trunk/Scribus/scribus/scimgdataloader_tiff.cpp (original)
+++ trunk/Scribus/scribus/scimgdataloader_tiff.cpp Sat Aug 18 22:29:24 2012
@@ -1080,7 +1080,14 @@
else if (samplesperpixel == 1)
{
// Do not set m_pixelFormat here as the real pixel format is most probably different than gray
- m_imageInfoRecord.colorspace = ColorSpaceGray;
+ if (bitspersample == 1)
+ {
+ m_imageInfoRecord.colorspace = ColorSpaceMonochrome;
+ }
+ else
+ {
+ m_imageInfoRecord.colorspace = ColorSpaceGray;
+ }
}
else
{
Modified: trunk/Scribus/scribus/util_color.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17758&path=/trunk/Scribus/scribus/util_color.cpp
==============================================================================
--- trunk/Scribus/scribus/util_color.cpp (original)
+++ trunk/Scribus/scribus/util_color.cpp Sat Aug 18 22:29:24 2012
@@ -592,6 +592,8 @@
return CommonStrings::trGrayscale;
if (cs==3)
return CommonStrings::trDuotone;
+ if (cs==4)
+ return CommonStrings::trMonochrome;
return CommonStrings::trUnknownCS;
}
More information about the scribus-commit
mailing list