From ac644c16a4d6ff2f9dca12bc6d10cae6e76c270b Mon Sep 17 00:00:00 2001 From: Jakub Melka Date: Sat, 19 Oct 2019 11:08:37 +0200 Subject: [PATCH] Mask image --- PdfForQtLib/sources/pdfcolorspaces.cpp | 2 +- PdfForQtLib/sources/pdfcolorspaces.h | 4 +++- PdfForQtLib/sources/pdfimage.cpp | 26 ++++++++++++++++++++++---- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/PdfForQtLib/sources/pdfcolorspaces.cpp b/PdfForQtLib/sources/pdfcolorspaces.cpp index 7cae05c..0f12f86 100644 --- a/PdfForQtLib/sources/pdfcolorspaces.cpp +++ b/PdfForQtLib/sources/pdfcolorspaces.cpp @@ -1088,7 +1088,7 @@ PDFColorSpacePointer PDFIndexedColorSpace::createIndexedColorSpace(const PDFDict const int colorCount = maxValue - MIN_VALUE + 1; const int componentCount = static_cast(baseColorSpace->getColorComponentCount()); const int byteCount = colorCount * componentCount; - if (byteCount != colors.size()) + if (byteCount > colors.size()) { throw PDFException(PDFTranslationContext::tr("Invalid colors for indexed color space. Color space has %1 colors, %2 color components and must have %3 size. Provided size is %4.").arg(colorCount).arg(componentCount).arg(byteCount).arg(colors.size())); } diff --git a/PdfForQtLib/sources/pdfcolorspaces.h b/PdfForQtLib/sources/pdfcolorspaces.h index 1dec59a..67b36d4 100644 --- a/PdfForQtLib/sources/pdfcolorspaces.h +++ b/PdfForQtLib/sources/pdfcolorspaces.h @@ -85,7 +85,6 @@ public: { None, ColorKeyMasking, ///< Masking by color key - Image, ///< Masking by image with alpha mask ImageMask, ///< Masking by 1-bit image (see "ImageMask" entry in image's dictionary), current color from the graphic state is used to paint an image SoftMask, ///< Image is masked by soft mask }; @@ -136,6 +135,9 @@ public: const std::vector& getDecode() const { return m_decode; } const std::vector& getMatte() const { return m_matte; } + void setMaskingType(MaskingType maskingType) { m_maskingType = maskingType; } + void setDecode(std::vector decode) { m_decode = qMove(decode); } + /// Returns number of color channels unsigned int getColorChannels() const { return m_components; } diff --git a/PdfForQtLib/sources/pdfimage.cpp b/PdfForQtLib/sources/pdfimage.cpp index 81f577f..638cd0c 100644 --- a/PdfForQtLib/sources/pdfimage.cpp +++ b/PdfForQtLib/sources/pdfimage.cpp @@ -125,10 +125,28 @@ PDFImage PDFImage::createImage(const PDFDocument* document, } else if (object.isStream()) { - // TODO: Implement Mask Image - PDFImage maskImage = createImage(document, object.getStream(), colorSpace, false, renderingIntent, errorReporter); - maskingType = PDFImageData::MaskingType::Image; - throw PDFRendererException(RenderErrorType::NotImplemented, PDFTranslationContext::tr("Mask image is not implemented.")); + PDFImage softMaskImage = createImage(document, object.getStream(), colorSpace, false, renderingIntent, errorReporter); + + if (softMaskImage.m_imageData.getMaskingType() != PDFImageData::MaskingType::ImageMask || + softMaskImage.m_imageData.getColorChannels() != 1 || + softMaskImage.m_imageData.getBitsPerComponent() != 1) + { + throw PDFRendererException(RenderErrorType::NotImplemented, PDFTranslationContext::tr("Invalid mask image.")); + } + + // We must alter decode, because it has opposite meaning (it is transparency) + std::vector decode = softMaskImage.m_imageData.getDecode(); + if (decode.size() < 2) + { + decode = { 0.0, 1.0}; + } + std::swap(decode[0], decode[1]); + + // Create soft mask from image + maskingType = PDFImageData::MaskingType::SoftMask; + image.m_softMask = qMove(softMaskImage.m_imageData); + image.m_softMask.setMaskingType(PDFImageData::MaskingType::None); + image.m_softMask.setDecode(qMove(decode)); } } else if (dictionary->hasKey("SMask"))