Пример #1
0
 public Type1FontHandler(IPdfTokenScanner pdfScanner, ILookupFilterProvider filterProvider,
                         IEncodingReader encodingReader)
 {
     this.pdfScanner     = pdfScanner;
     this.filterProvider = filterProvider;
     this.encodingReader = encodingReader;
 }
Пример #2
0
 public Type0FontHandler(CidFontFactory cidFontFactory, ILookupFilterProvider filterProvider,
                         IPdfTokenScanner scanner)
 {
     this.cidFontFactory = cidFontFactory;
     this.filterProvider = filterProvider;
     this.scanner        = scanner;
 }
Пример #3
0
 internal PdfDocument(ILog log,
                      IInputBytes inputBytes,
                      HeaderVersion version,
                      CrossReferenceTable crossReferenceTable,
                      ParsingCachingProviders cachingProviders,
                      IPageFactory pageFactory,
                      Catalog catalog,
                      DocumentInformation information,
                      EncryptionDictionary encryptionDictionary,
                      IPdfTokenScanner pdfScanner,
                      ILookupFilterProvider filterProvider,
                      AcroFormFactory acroFormFactory,
                      BookmarksProvider bookmarksProvider,
                      bool clipPaths)
 {
     this.log                  = log;
     this.inputBytes           = inputBytes;
     this.version              = version ?? throw new ArgumentNullException(nameof(version));
     this.cachingProviders     = cachingProviders ?? throw new ArgumentNullException(nameof(cachingProviders));
     this.encryptionDictionary = encryptionDictionary;
     this.pdfScanner           = pdfScanner ?? throw new ArgumentNullException(nameof(pdfScanner));
     this.filterProvider       = filterProvider ?? throw new ArgumentNullException(nameof(filterProvider));
     this.bookmarksProvider    = bookmarksProvider ?? throw new ArgumentNullException(nameof(bookmarksProvider));
     this.clipPaths            = clipPaths;
     Information               = information ?? throw new ArgumentNullException(nameof(information));
     pages        = new Pages(catalog, pageFactory, pdfScanner);
     Structure    = new Structure(catalog, crossReferenceTable, pdfScanner);
     Advanced     = new AdvancedPdfDocumentAccess(pdfScanner, filterProvider, catalog);
     documentForm = new Lazy <AcroForm>(() => acroFormFactory.GetAcroForm(catalog));
 }
Пример #4
0
 internal AdvancedPdfDocumentAccess(IPdfTokenScanner pdfScanner,
                                    ILookupFilterProvider filterProvider,
                                    Catalog catalog)
 {
     this.pdfScanner     = pdfScanner ?? throw new ArgumentNullException(nameof(pdfScanner));
     this.filterProvider = filterProvider ?? throw new ArgumentNullException(nameof(filterProvider));
     this.catalog        = catalog ?? throw new ArgumentNullException(nameof(catalog));
 }
Пример #5
0
 public PdfTokenScanner(IInputBytes inputBytes, IObjectLocationProvider objectLocationProvider, ILookupFilterProvider filterProvider,
                        IEncryptionHandler encryptionHandler)
 {
     this.inputBytes             = inputBytes;
     this.objectLocationProvider = objectLocationProvider;
     this.filterProvider         = filterProvider;
     this.encryptionHandler      = encryptionHandler;
     coreTokenScanner            = new CoreTokenScanner(inputBytes);
 }
Пример #6
0
 public PageFactory(IPdfTokenScanner pdfScanner, IResourceStore resourceStore, ILookupFilterProvider filterProvider,
                    IPageContentParser pageContentParser,
                    ILog log)
 {
     this.resourceStore     = resourceStore;
     this.filterProvider    = filterProvider;
     this.pageContentParser = pageContentParser;
     this.log        = log;
     this.pdfScanner = pdfScanner;
 }
Пример #7
0
 public void AddXObject(XObjectContentRecord xObject,
                        IPdfTokenScanner scanner,
                        ILookupFilterProvider filterProvider,
                        IResourceStore resourceStore)
 {
     if (top != null && xObject.Type == XObjectType.Image)
     {
         var image = XObjectFactory.ReadImage(xObject, scanner, filterProvider, resourceStore);
         top?.AddImage(image);
     }
 }
Пример #8
0
 public TrueTypeFontHandler(ILog log, IPdfTokenScanner pdfScanner, ILookupFilterProvider filterProvider,
                            IEncodingReader encodingReader,
                            ISystemFontFinder systemFontFinder,
                            IFontHandler type1FontHandler)
 {
     this.log              = log;
     this.filterProvider   = filterProvider;
     this.encodingReader   = encodingReader;
     this.systemFontFinder = systemFontFinder;
     this.type1FontHandler = type1FontHandler;
     this.pdfScanner       = pdfScanner;
 }
Пример #9
0
        internal static IReadOnlyList <byte> Decode(this StreamToken stream, ILookupFilterProvider filterProvider, IPdfTokenScanner scanner)
        {
            var filters = filterProvider.GetFilters(stream.StreamDictionary, scanner);

            var transform = stream.Data;

            for (var i = 0; i < filters.Count; i++)
            {
                transform = filters[i].Decode(transform, stream.StreamDictionary, i);
            }

            return(transform);
        }
Пример #10
0
 internal PageContent(IReadOnlyList <IGraphicsStateOperation> graphicsStateOperations, IReadOnlyList <Letter> letters,
                      IReadOnlyList <PdfPath> paths,
                      IReadOnlyList <Union <XObjectContentRecord, InlineImage> > images,
                      IReadOnlyList <MarkedContentElement> markedContents,
                      IPdfTokenScanner pdfScanner,
                      ILookupFilterProvider filterProvider,
                      IResourceStore resourceStore)
 {
     GraphicsStateOperations = graphicsStateOperations;
     Letters             = letters;
     Paths               = paths;
     this.images         = images;
     this.markedContents = markedContents;
     this.pdfScanner     = pdfScanner ?? throw new ArgumentNullException(nameof(pdfScanner));
     this.filterProvider = filterProvider ?? throw new ArgumentNullException(nameof(filterProvider));
     this.resourceStore  = resourceStore ?? throw new ArgumentNullException(nameof(resourceStore));
 }
Пример #11
0
        public ContentStreamProcessor(PdfRectangle cropBox, IResourceStore resourceStore, UserSpaceUnit userSpaceUnit, PageRotationDegrees rotation,
                                      IPdfTokenScanner pdfScanner,
                                      IPageContentParser pageContentParser,
                                      ILookupFilterProvider filterProvider,
                                      ILog log,
                                      bool clipPaths,
                                      PdfVector pageSize)
        {
            this.resourceStore     = resourceStore;
            this.userSpaceUnit     = userSpaceUnit;
            this.rotation          = rotation;
            this.pdfScanner        = pdfScanner ?? throw new ArgumentNullException(nameof(pdfScanner));
            this.pageContentParser = pageContentParser ?? throw new ArgumentNullException(nameof(pageContentParser));
            this.filterProvider    = filterProvider ?? throw new ArgumentNullException(nameof(filterProvider));
            this.log       = log;
            this.clipPaths = clipPaths;
            this.pageSize  = pageSize;

            // initiate CurrentClippingPath to cropBox
            var clippingSubpath = new PdfSubpath();

            clippingSubpath.Rectangle(cropBox.BottomLeft.X, cropBox.BottomLeft.Y, cropBox.Width, cropBox.Height);
            var clippingPath = new PdfPath()
            {
                clippingSubpath
            };

            clippingPath.SetClipping(FillingRule.EvenOdd);

            graphicsStack.Push(new CurrentGraphicsState()
            {
                CurrentTransformationMatrix = GetInitialMatrix(),
                CurrentClippingPath         = clippingPath
            });

            ColorSpaceContext = new ColorSpaceContext(GetCurrentState, resourceStore);
        }
Пример #12
0
        public static ColorSpaceDetails GetColorSpaceDetails(ColorSpace?colorSpace,
                                                             DictionaryToken imageDictionary,
                                                             IPdfTokenScanner scanner,
                                                             IResourceStore resourceStore,
                                                             ILookupFilterProvider filterProvider,
                                                             bool cannotRecurse = false)
        {
            if (imageDictionary.GetObjectOrDefault(NameToken.ImageMask, NameToken.Im) != null ||
                filterProvider.GetFilters(imageDictionary, scanner).OfType <CcittFaxDecodeFilter>().Any())
            {
                if (cannotRecurse)
                {
                    return(UnsupportedColorSpaceDetails.Instance);
                }

                var colorSpaceDetails = GetColorSpaceDetails(colorSpace, imageDictionary.Without(NameToken.Filter).Without(NameToken.F), scanner, resourceStore, filterProvider, true);

                var decodeRaw = imageDictionary.GetObjectOrDefault(NameToken.Decode, NameToken.D) as ArrayToken
                                ?? new ArrayToken(EmptyArray <IToken> .Instance);
                var decode = decodeRaw.Data.OfType <NumericToken>().Select(x => x.Data).ToArray();

                return(IndexedColorSpaceDetails.Stencil(colorSpaceDetails, decode));
            }

            if (!colorSpace.HasValue)
            {
                return(UnsupportedColorSpaceDetails.Instance);
            }

            switch (colorSpace.Value)
            {
            case ColorSpace.DeviceGray:
                return(DeviceGrayColorSpaceDetails.Instance);

            case ColorSpace.DeviceRGB:
                return(DeviceRgbColorSpaceDetails.Instance);

            case ColorSpace.DeviceCMYK:
                return(DeviceCmykColorSpaceDetails.Instance);

            case ColorSpace.CalGray:
            {
                if (!TryGetColorSpaceArray(imageDictionary, resourceStore, scanner, out var colorSpaceArray) ||
                    colorSpaceArray.Length != 2)
                {
                    return(UnsupportedColorSpaceDetails.Instance);
                }

                var first = colorSpaceArray[0] as NameToken;

                if (first == null || !ColorSpaceMapper.TryMap(first, resourceStore, out var innerColorSpace) ||
                    innerColorSpace != ColorSpace.CalGray)
                {
                    return(UnsupportedColorSpaceDetails.Instance);
                }

                var second = colorSpaceArray[1];

                // WhitePoint is required
                if (!DirectObjectFinder.TryGet(second, scanner, out DictionaryToken dictionaryToken) ||
                    !dictionaryToken.TryGet(NameToken.WhitePoint, scanner, out ArrayToken whitePointToken))
                {
                    return(UnsupportedColorSpaceDetails.Instance);
                }

                var whitePoint = whitePointToken.Data.OfType <NumericToken>().Select(x => x.Data).ToList();

                // BlackPoint is optional
                IReadOnlyList <decimal> blackPoint = null;
                if (dictionaryToken.TryGet(NameToken.BlackPoint, scanner, out ArrayToken blackPointToken))
                {
                    blackPoint = blackPointToken.Data.OfType <NumericToken>().Select(x => x.Data).ToList();
                }

                // Gamma is optional
                decimal?gamma = null;
                if (dictionaryToken.TryGet(NameToken.Gamma, scanner, out NumericToken gammaToken))
                {
                    gamma = gammaToken.Data;
                }

                return(new CalGrayColorSpaceDetails(whitePoint, blackPoint, gamma));
            }

            case ColorSpace.CalRGB:
            {
                if (!TryGetColorSpaceArray(imageDictionary, resourceStore, scanner, out var colorSpaceArray) ||
                    colorSpaceArray.Length != 2)
                {
                    return(UnsupportedColorSpaceDetails.Instance);
                }

                var first = colorSpaceArray[0] as NameToken;

                if (first == null || !ColorSpaceMapper.TryMap(first, resourceStore, out var innerColorSpace) ||
                    innerColorSpace != ColorSpace.CalRGB)
                {
                    return(UnsupportedColorSpaceDetails.Instance);
                }

                var second = colorSpaceArray[1];

                // WhitePoint is required
                if (!DirectObjectFinder.TryGet(second, scanner, out DictionaryToken dictionaryToken) ||
                    !dictionaryToken.TryGet(NameToken.WhitePoint, scanner, out ArrayToken whitePointToken))
                {
                    return(UnsupportedColorSpaceDetails.Instance);
                }

                var whitePoint = whitePointToken.Data.OfType <NumericToken>().Select(x => x.Data).ToList();

                // BlackPoint is optional
                IReadOnlyList <decimal> blackPoint = null;
                if (dictionaryToken.TryGet(NameToken.BlackPoint, scanner, out ArrayToken blackPointToken))
                {
                    blackPoint = blackPointToken.Data.OfType <NumericToken>().Select(x => x.Data).ToList();
                }

                // Gamma is optional
                IReadOnlyList <decimal> gamma = null;
                if (dictionaryToken.TryGet(NameToken.Gamma, scanner, out ArrayToken gammaToken))
                {
                    gamma = gammaToken.Data.OfType <NumericToken>().Select(x => x.Data).ToList();
                }

                // Matrix is optional
                IReadOnlyList <decimal> matrix = null;
                if (dictionaryToken.TryGet(NameToken.Matrix, scanner, out ArrayToken matrixToken))
                {
                    matrix = matrixToken.Data.OfType <NumericToken>().Select(x => x.Data).ToList();
                }

                return(new CalRGBColorSpaceDetails(whitePoint, blackPoint, gamma, matrix));
            }

            case ColorSpace.Lab:
                return(UnsupportedColorSpaceDetails.Instance);

            case ColorSpace.ICCBased:
            {
                if (!TryGetColorSpaceArray(imageDictionary, resourceStore, scanner, out var colorSpaceArray) ||
                    colorSpaceArray.Length != 2)
                {
                    return(UnsupportedColorSpaceDetails.Instance);
                }

                var first = colorSpaceArray[0] as NameToken;

                if (first == null || !ColorSpaceMapper.TryMap(first, resourceStore, out var innerColorSpace) ||
                    innerColorSpace != ColorSpace.ICCBased)
                {
                    return(UnsupportedColorSpaceDetails.Instance);
                }

                var second = colorSpaceArray[1];

                // N is required
                if (!DirectObjectFinder.TryGet(second, scanner, out StreamToken streamToken) ||
                    !streamToken.StreamDictionary.TryGet(NameToken.N, scanner, out NumericToken numeric))
                {
                    return(UnsupportedColorSpaceDetails.Instance);
                }

                // Alternate is optional
                ColorSpaceDetails alternateColorSpaceDetails = null;
                if (streamToken.StreamDictionary.TryGet(NameToken.Alternate, out NameToken alternateColorSpaceNameToken) &&
                    ColorSpaceMapper.TryMap(alternateColorSpaceNameToken, resourceStore, out var alternateColorSpace))
                {
                    alternateColorSpaceDetails =
                        GetColorSpaceDetails(alternateColorSpace, imageDictionary, scanner, resourceStore, filterProvider, true);
                }

                // Range is optional
                IReadOnlyList <decimal> range = null;
                if (streamToken.StreamDictionary.TryGet(NameToken.Range, scanner, out ArrayToken arrayToken))
                {
                    range = arrayToken.Data.OfType <NumericToken>().Select(x => x.Data).ToList();
                }

                // Metadata is optional
                XmpMetadata metadata = null;
                if (streamToken.StreamDictionary.TryGet(NameToken.Metadata, scanner, out StreamToken metadataStream))
                {
                    metadata = new XmpMetadata(metadataStream, filterProvider, scanner);
                }

                return(new ICCBasedColorSpaceDetails(numeric.Int, alternateColorSpaceDetails, range, metadata));
            }

            case ColorSpace.Indexed:
            {
                if (cannotRecurse)
                {
                    return(UnsupportedColorSpaceDetails.Instance);
                }

                if (!TryGetColorSpaceArray(imageDictionary, resourceStore, scanner, out var colorSpaceArray) ||
                    colorSpaceArray.Length != 4)
                {
                    // Error instead?
                    return(UnsupportedColorSpaceDetails.Instance);
                }

                var first = colorSpaceArray[0] as NameToken;

                if (first == null || !ColorSpaceMapper.TryMap(first, resourceStore, out var innerColorSpace) ||
                    innerColorSpace != ColorSpace.Indexed)
                {
                    return(UnsupportedColorSpaceDetails.Instance);
                }

                var second = colorSpaceArray[1];

                ColorSpaceDetails baseDetails;

                if (DirectObjectFinder.TryGet(second, scanner, out NameToken baseColorSpaceNameToken) &&
                    ColorSpaceMapper.TryMap(baseColorSpaceNameToken, resourceStore, out var baseColorSpaceName))
                {
                    baseDetails = GetColorSpaceDetails(
                        baseColorSpaceName,
                        imageDictionary,
                        scanner,
                        resourceStore,
                        filterProvider,
                        true);
                }
                else if (DirectObjectFinder.TryGet(second, scanner, out ArrayToken baseColorSpaceArrayToken) &&
                         baseColorSpaceArrayToken.Length > 0 && baseColorSpaceArrayToken[0] is NameToken baseColorSpaceArrayNameToken &&
                         ColorSpaceMapper.TryMap(baseColorSpaceArrayNameToken, resourceStore, out var baseColorSpaceArrayColorSpace))
                {
                    var pseudoImageDictionary = new DictionaryToken(
                        new Dictionary <NameToken, IToken>
                        {
                            { NameToken.ColorSpace, baseColorSpaceArrayToken }
                        });

                    baseDetails = GetColorSpaceDetails(
                        baseColorSpaceArrayColorSpace,
                        pseudoImageDictionary,
                        scanner,
                        resourceStore,
                        filterProvider,
                        true);
                }
Пример #13
0
 public CidFontFactory(IPdfTokenScanner pdfScanner, ILookupFilterProvider filterProvider)
 {
     this.pdfScanner     = pdfScanner;
     this.filterProvider = filterProvider;
 }
Пример #14
0
        public static ColorSpaceDetails GetColorSpaceDetails(ColorSpace?colorSpace,
                                                             DictionaryToken imageDictionary,
                                                             IPdfTokenScanner scanner,
                                                             IResourceStore resourceStore,
                                                             ILookupFilterProvider filterProvider,
                                                             bool cannotRecurse = false)
        {
            if (!colorSpace.HasValue)
            {
                return(UnsupportedColorSpaceDetails.Instance);
            }

            switch (colorSpace.Value)
            {
            case ColorSpace.DeviceGray:
                return(DeviceGrayColorSpaceDetails.Instance);

            case ColorSpace.DeviceRGB:
                return(DeviceRgbColorSpaceDetails.Instance);

            case ColorSpace.DeviceCMYK:
                return(DeviceCmykColorSpaceDetails.Instance);

            case ColorSpace.CalGray:
                return(UnsupportedColorSpaceDetails.Instance);

            case ColorSpace.CalRGB:
                return(UnsupportedColorSpaceDetails.Instance);

            case ColorSpace.Lab:
                return(UnsupportedColorSpaceDetails.Instance);

            case ColorSpace.ICCBased:
                return(UnsupportedColorSpaceDetails.Instance);

            case ColorSpace.Indexed:
            {
                if (cannotRecurse)
                {
                    return(UnsupportedColorSpaceDetails.Instance);
                }

                if (!imageDictionary.TryGet(NameToken.ColorSpace, scanner, out ArrayToken colorSpaceArray) ||
                    colorSpaceArray.Length != 4)
                {
                    // Error instead?
                    return(UnsupportedColorSpaceDetails.Instance);
                }

                var first = colorSpaceArray[0] as NameToken;

                if (first == null || !ColorSpaceMapper.TryMap(first, resourceStore, out var innerColorSpace) ||
                    innerColorSpace != ColorSpace.Indexed)
                {
                    return(UnsupportedColorSpaceDetails.Instance);
                }

                var second = colorSpaceArray[1];

                ColorSpaceDetails baseDetails;

                if (DirectObjectFinder.TryGet(second, scanner, out NameToken baseColorSpaceNameToken) &&
                    ColorSpaceMapper.TryMap(baseColorSpaceNameToken, resourceStore, out var baseColorSpaceName))
                {
                    baseDetails = GetColorSpaceDetails(
                        baseColorSpaceName,
                        imageDictionary,
                        scanner,
                        resourceStore,
                        filterProvider,
                        true);
                }
                else if (DirectObjectFinder.TryGet(second, scanner, out ArrayToken baseColorSpaceArrayToken) &&
                         baseColorSpaceArrayToken.Length > 0 && baseColorSpaceArrayToken[0] is NameToken baseColorSpaceArrayNameToken &&
                         ColorSpaceMapper.TryMap(baseColorSpaceArrayNameToken, resourceStore, out var baseColorSpaceArrayColorSpace))
                {
                    var pseudoImageDictionary = new DictionaryToken(
                        new Dictionary <NameToken, IToken>
                        {
                            { NameToken.ColorSpace, baseColorSpaceArrayToken }
                        });

                    baseDetails = GetColorSpaceDetails(
                        baseColorSpaceArrayColorSpace,
                        pseudoImageDictionary,
                        scanner,
                        resourceStore,
                        filterProvider,
                        true);
                }
Пример #15
0
 public AcroFormFactory(IPdfTokenScanner tokenScanner, ILookupFilterProvider filterProvider, CrossReferenceTable crossReferenceTable)
 {
     this.tokenScanner        = tokenScanner ?? throw new ArgumentNullException(nameof(tokenScanner));
     this.filterProvider      = filterProvider ?? throw new ArgumentNullException(nameof(filterProvider));
     this.crossReferenceTable = crossReferenceTable ?? throw new ArgumentNullException(nameof(crossReferenceTable));
 }
Пример #16
0
 internal XmpMetadata(StreamToken stream, ILookupFilterProvider filterProvider, IPdfTokenScanner pdfTokenScanner)
 {
     this.filterProvider  = filterProvider ?? throw new ArgumentNullException(nameof(filterProvider));
     this.pdfTokenScanner = pdfTokenScanner;
     MetadataStreamToken  = stream ?? throw new ArgumentNullException(nameof(stream));
 }
Пример #17
0
        public InlineImage CreateInlineImage(TransformationMatrix transformationMatrix, ILookupFilterProvider filterProvider,
                                             IPdfTokenScanner tokenScanner,
                                             RenderingIntent defaultRenderingIntent,
                                             IResourceStore resourceStore)
        {
            if (Properties == null || Bytes == null)
            {
                throw new InvalidOperationException($"Inline image builder not completely defined before calling {nameof(CreateInlineImage)}.");
            }

            var bounds = transformationMatrix.Transform(new PdfRectangle(new PdfPoint(1, 1),
                                                                         new PdfPoint(0, 0)));

            var width = GetByKeys <NumericToken>(NameToken.Width, NameToken.W, true).Int;

            var height = GetByKeys <NumericToken>(NameToken.Height, NameToken.H, true).Int;

            var maskToken = GetByKeys <BooleanToken>(NameToken.ImageMask, NameToken.Im, false);

            var isMask = maskToken?.Data == true;

            var bitsPerComponent = GetByKeys <NumericToken>(NameToken.BitsPerComponent, NameToken.Bpc, !isMask)?.Int ?? 1;

            var colorSpace = default(ColorSpace?);

            if (!isMask)
            {
                var colorSpaceName = GetByKeys <NameToken>(NameToken.ColorSpace, NameToken.Cs, false);

                if (colorSpaceName == null)
                {
                    var colorSpaceArray = GetByKeys <ArrayToken>(NameToken.ColorSpace, NameToken.Cs, true);

                    if (colorSpaceArray.Length == 0)
                    {
                        throw new PdfDocumentFormatException("Empty ColorSpace array defined for inline image.");
                    }

                    if (!(colorSpaceArray.Data[0] is NameToken firstColorSpaceName))
                    {
                        throw new PdfDocumentFormatException($"Invalid ColorSpace array defined for inline image: {colorSpaceArray}.");
                    }

                    if (!ColorSpaceMapper.TryMap(firstColorSpaceName, resourceStore, out var colorSpaceMapped))
                    {
                        throw new PdfDocumentFormatException($"Invalid ColorSpace defined for inline image: {firstColorSpaceName}.");
                    }

                    colorSpace = colorSpaceMapped;
                }
                else
                {
                    if (!ColorSpaceMapper.TryMap(colorSpaceName, resourceStore, out var colorSpaceMapped))
                    {
                        throw new PdfDocumentFormatException($"Invalid ColorSpace defined for inline image: {colorSpaceName}.");
                    }

                    colorSpace = colorSpaceMapped;
                }
            }

            var imgDic = new DictionaryToken(Properties ?? new Dictionary <NameToken, IToken>());

            var details = ColorSpaceDetailsParser.GetColorSpaceDetails(
                colorSpace,
                imgDic,
                tokenScanner,
                resourceStore,
                filterProvider);

            var renderingIntent = GetByKeys <NameToken>(NameToken.Intent, null, false)?.Data?.ToRenderingIntent() ?? defaultRenderingIntent;

            var filterNames = new List <NameToken>();

            var filterName = GetByKeys <NameToken>(NameToken.Filter, NameToken.F, false);

            if (filterName == null)
            {
                var filterArray = GetByKeys <ArrayToken>(NameToken.Filter, NameToken.F, false);

                if (filterArray != null)
                {
                    filterNames.AddRange(filterArray.Data.OfType <NameToken>());
                }
            }
            else
            {
                filterNames.Add(filterName);
            }

            var filters = filterProvider.GetNamedFilters(filterNames);

            var decodeRaw = GetByKeys <ArrayToken>(NameToken.Decode, NameToken.D, false) ?? new ArrayToken(EmptyArray <IToken> .Instance);

            var decode = decodeRaw.Data.OfType <NumericToken>().Select(x => x.Data).ToArray();

            var filterDictionaryEntries = new Dictionary <NameToken, IToken>();
            var decodeParamsDict        = GetByKeys <DictionaryToken>(NameToken.DecodeParms, NameToken.Dp, false);

            if (decodeParamsDict == null)
            {
                var decodeParamsArray = GetByKeys <ArrayToken>(NameToken.DecodeParms, NameToken.Dp, false);

                if (decodeParamsArray != null)
                {
                    filterDictionaryEntries[NameToken.DecodeParms] = decodeParamsArray;
                }
            }
            else
            {
                filterDictionaryEntries[NameToken.DecodeParms] = decodeParamsDict;
            }

            var streamDictionary = new DictionaryToken(filterDictionaryEntries);

            var interpolate = GetByKeys <BooleanToken>(NameToken.Interpolate, NameToken.I, false)?.Data ?? false;

            return(new InlineImage(bounds, width, height, bitsPerComponent, isMask, renderingIntent, interpolate, colorSpace, decode, Bytes,
                                   filters,
                                   streamDictionary,
                                   details));
        }
Пример #18
0
        public static XObjectImage ReadImage(XObjectContentRecord xObject, IPdfTokenScanner pdfScanner,
                                             ILookupFilterProvider filterProvider,
                                             IResourceStore resourceStore)
        {
            if (xObject == null)
            {
                throw new ArgumentNullException(nameof(xObject));
            }

            if (xObject.Type != XObjectType.Image)
            {
                throw new InvalidOperationException($"Cannot create an image from an XObject with type: {xObject.Type}.");
            }

            var dictionary = xObject.Stream.StreamDictionary;

            var bounds = xObject.AppliedTransformation.Transform(new PdfRectangle(new PdfPoint(0, 0), new PdfPoint(1, 1)));

            var width  = dictionary.Get <NumericToken>(NameToken.Width, pdfScanner).Int;
            var height = dictionary.Get <NumericToken>(NameToken.Height, pdfScanner).Int;

            var isImageMask = dictionary.TryGet(NameToken.ImageMask, pdfScanner, out BooleanToken isMaskToken) &&
                              isMaskToken.Data;

            var isJpxDecode = dictionary.TryGet(NameToken.Filter, out var token) &&
                              token is NameToken filterName &&
                              filterName.Equals(NameToken.JpxDecode);

            int bitsPerComponent = 0;

            if (!isImageMask && !isJpxDecode)
            {
                if (!dictionary.TryGet(NameToken.BitsPerComponent, pdfScanner, out NumericToken bitsPerComponentToken))
                {
                    throw new PdfDocumentFormatException($"No bits per component defined for image: {dictionary}.");
                }

                bitsPerComponent = bitsPerComponentToken.Int;
            }
            else if (isImageMask)
            {
                bitsPerComponent = 1;
            }

            var intent = xObject.DefaultRenderingIntent;

            if (dictionary.TryGet(NameToken.Intent, out NameToken renderingIntentToken))
            {
                intent = renderingIntentToken.Data.ToRenderingIntent();
            }

            var interpolate = dictionary.TryGet(NameToken.Interpolate, pdfScanner, out BooleanToken interpolateToken) &&
                              interpolateToken.Data;

            DictionaryToken filterDictionary = xObject.Stream.StreamDictionary;

            if (xObject.Stream.StreamDictionary.TryGet(NameToken.Filter, out var filterToken) &&
                filterToken is IndirectReferenceToken)
            {
                if (filterDictionary.TryGet(NameToken.Filter, pdfScanner, out ArrayToken filterArray))
                {
                    filterDictionary = filterDictionary.With(NameToken.Filter, filterArray);
                }
                else if (filterDictionary.TryGet(NameToken.Filter, pdfScanner, out NameToken filterNameToken))
                {
                    filterDictionary = filterDictionary.With(NameToken.Filter, filterNameToken);
                }
                else
                {
                    filterDictionary = null;
                }
            }

            var supportsFilters = filterDictionary != null;

            if (filterDictionary != null)
            {
                var filters = filterProvider.GetFilters(filterDictionary, pdfScanner);
                foreach (var filter in filters)
                {
                    if (!filter.IsSupported)
                    {
                        supportsFilters = false;
                        break;
                    }
                }
            }

            var decodeParams = dictionary.GetObjectOrDefault(NameToken.DecodeParms, NameToken.Dp);

            if (decodeParams is IndirectReferenceToken refToken)
            {
                dictionary = dictionary.With(NameToken.DecodeParms, pdfScanner.Get(refToken.Data).Data);
            }

            var streamToken = new StreamToken(dictionary, xObject.Stream.Data);

            var decodedBytes = supportsFilters ? new Lazy <IReadOnlyList <byte> >(() => streamToken.Decode(filterProvider, pdfScanner))
                : null;

            var decode = EmptyArray <decimal> .Instance;

            if (dictionary.TryGet(NameToken.Decode, pdfScanner, out ArrayToken decodeArrayToken))
            {
                decode = decodeArrayToken.Data.OfType <NumericToken>()
                         .Select(x => x.Data)
                         .ToArray();
            }

            var colorSpace = default(ColorSpace?);

            if (!isImageMask)
            {
                if (dictionary.TryGet(NameToken.ColorSpace, pdfScanner, out NameToken colorSpaceNameToken) &&
                    TryMapColorSpace(colorSpaceNameToken, resourceStore, out var colorSpaceResult))
                {
                    colorSpace = colorSpaceResult;
                }
                else if (dictionary.TryGet(NameToken.ColorSpace, pdfScanner, out ArrayToken colorSpaceArrayToken) &&
                         colorSpaceArrayToken.Length > 0)
                {
                    var first = colorSpaceArrayToken.Data[0];

                    if ((first is NameToken firstColorSpaceName) && TryMapColorSpace(firstColorSpaceName, resourceStore, out colorSpaceResult))
                    {
                        colorSpace = colorSpaceResult;
                    }
                }
                else if (!isJpxDecode)
                {
                    colorSpace = xObject.DefaultColorSpace;
                }
            }

            var details = ColorSpaceDetailsParser.GetColorSpaceDetails(colorSpace, dictionary, pdfScanner, resourceStore, filterProvider);

            return(new XObjectImage(
                       bounds,
                       width,
                       height,
                       bitsPerComponent,
                       colorSpace,
                       isJpxDecode,
                       isImageMask,
                       intent,
                       interpolate,
                       decode,
                       dictionary,
                       xObject.Stream.Data,
                       decodedBytes,
                       details));
        }