コード例 #1
0
ファイル: XObjectFactory.cs プロジェクト: rbanks54/PdfPig
        public XObjectImage CreateImage(XObjectContentRecord xObject, IPdfTokenScanner pdfScanner, bool isLenientParsing)
        {
            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 width  = xObject.Stream.StreamDictionary.Get <NumericToken>(NameToken.Width, pdfScanner).Int;
            var height = xObject.Stream.StreamDictionary.Get <NumericToken>(NameToken.Height, pdfScanner).Int;

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

            var isImageMask = xObject.Stream.StreamDictionary.TryGet(NameToken.ImageMask, out var maskToken) &&
                              maskToken is BooleanToken maskBoolean &&
                              maskBoolean.Data;

            return(new XObjectImage(width, height, isJpxDecode, isImageMask, xObject.Stream.StreamDictionary,
                                    xObject.Stream.Data));
        }
コード例 #2
0
ファイル: XObjectFactory.cs プロジェクト: gitforbit/PdfPig
        public static XObjectImage ReadImage(XObjectContentRecord xObject, IPdfTokenScanner pdfScanner,
                                             IFilterProvider filterProvider,
                                             IResourceStore resourceStore,
                                             bool isLenientParsing)
        {
            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;

            var decodedBytes = new Lazy <IReadOnlyList <byte> >(() => xObject.Stream.Decode(filterProvider));

            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))
                {
                    if (colorSpaceArrayToken.Length == 0)
                    {
                        throw new PdfDocumentFormatException($"Empty ColorSpace array defined for image XObject: {dictionary}.");
                    }

                    var first = colorSpaceArrayToken.Data[0];

                    if (!(first is NameToken firstColorSpaceName) || !TryMapColorSpace(firstColorSpaceName, resourceStore, out colorSpaceResult))
                    {
                        throw new PdfDocumentFormatException($"Invalid ColorSpace array defined for image XObject: {colorSpaceArrayToken}.");
                    }

                    colorSpace = colorSpaceResult;
                }
                else if (!isJpxDecode)
                {
                    throw new PdfDocumentFormatException($"No ColorSpace defined for image XObject: {dictionary}.");
                }
            }

            return(new XObjectImage(bounds, width, height, bitsPerComponent, colorSpace, isJpxDecode, isImageMask, intent, interpolate, decode,
                                    dictionary, xObject.Stream.Data, decodedBytes));
        }
コード例 #3
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));
        }