Exemple #1
0
        /// <summary>
        /// Default case that adds comment with keyword to directory
        /// </summary>
        /// <param name="directory">EpsDirectory to add extracted data to</param>
        /// <param name="name">String that holds name of current comment</param>
        /// <param name="value">String that holds value of current comment</param>
        private void AddToDirectory(EpsDirectory directory, string name, string value)
        {
            if (!EpsDirectory.TagIntegerMap.ContainsKey(name))
            {
                return;
            }

            var tag = EpsDirectory.TagIntegerMap[name];

            switch (tag)
            {
            case EpsDirectory.TagImageData:
                ExtractImageData(directory, value);
                break;

            case EpsDirectory.TagContinueLine:
                directory.Set(_previousTag, directory.GetString(_previousTag) + " " + value);
                break;

            default:
                if (EpsDirectory.TagNameMap.ContainsKey(tag) && !directory.ContainsTag(tag))
                {
                    directory.Set(tag, value);
                    _previousTag = tag;
                }
                else
                {
                    // Set previous tag to an Integer that doesn't exist in EpsDirectory
                    _previousTag = 0;
                }
                break;
            }
            _previousTag = tag;
        }
Exemple #2
0
        /// <summary>
        /// Main method that parses all comments and then distributes data extraction among other methods that parse the
        /// rest of file and store encountered data in metadata(if there exists an entry in EpsDirectory
        /// for the found data).  Reads until a begin data/binary comment is found or reader's estimated
        /// available data has run out (or AI09 End Private Data).  Will extract data from normal EPS comments, Photoshop, ICC, and XMP.
        /// </summary>
        /// <param name="directory"></param>
        /// <param name="directories">list to add directory to and extracted data</param>
        /// <param name="reader"></param>
        private void Extract(EpsDirectory directory, List <Directory> directories, SequentialReader reader)
        {
            var line = new StringBuilder();

            while (true)
            {
                line.Length = 0;

                // Read the next line, excluding any trailing newline character
                // Note that for Windows-style line endings ("\r\n") the outer loop will be run a second time with an empty
                // string, which is fine.
                while (true)
                {
                    char c = (char)reader.GetByte();
                    if (c == '\r' || c == '\n')
                    {
                        break;
                    }
                    line.Append(c);
                }

                // Stop when we hit a line that is not a comment
                if (line.Length != 0 && line[0] != '%')
                {
                    break;
                }

                string name;

                // ':' signifies there is an associated keyword (should be put in directory)
                // otherwise, the name could be a marker
                int colonIndex = line.IndexOf(':');
                if (colonIndex != -1)
                {
                    name = line.ToString(0, colonIndex).Trim();
                    var value = line.ToString(colonIndex + 1, line.Length - (colonIndex + 1)).Trim();
                    AddToDirectory(directory, name, value);
                }
                else
                {
                    name = line.ToString().Trim();
                }

                // Some comments will both have a value and signify a new block to follow
                if (name.Equals("%BeginPhotoshop"))
                {
                    ExtractPhotoshopData(directories, reader);
                }
                else if (name.Equals("%%BeginICCProfile"))
                {
                    ExtractIccData(directories, reader);
                }
                else if (name.Equals("%begin_xml_packet"))
                {
                    ExtractXmpData(directories, reader);
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// Parses '%ImageData' comment which holds several values including width in px,
        /// height in px and color type.
        /// </summary>
        private static void ExtractImageData(EpsDirectory directory, string imageData)
        {
            // %ImageData: 1000 1000 8 3 1 1000 7 "beginimage"
            directory.Set(EpsDirectory.TagImageData, imageData.Trim());

            var imageDataParts = imageData.Split(' ');

            int width     = int.Parse(imageDataParts[0]);
            int height    = int.Parse(imageDataParts[1]);
            int colorType = int.Parse(imageDataParts[3]);

            // Only add values that are not already present
            if (!directory.ContainsTag(EpsDirectory.TagImageWidth))
            {
                directory.Set(EpsDirectory.TagImageWidth, width);
            }
            if (!directory.ContainsTag(EpsDirectory.TagImageHeight))
            {
                directory.Set(EpsDirectory.TagImageHeight, height);
            }
            if (!directory.ContainsTag(EpsDirectory.TagColorType))
            {
                directory.Set(EpsDirectory.TagColorType, colorType);
            }

            if (!directory.ContainsTag(EpsDirectory.TagRamSize))
            {
                int bytesPerPixel = colorType switch
                {
                    1 => 1, // grayscale
                    2 => 3, // Lab
                    3 => 3, // RGB
                    4 => 3, // CMYK
                    _ => 0
                };

                if (bytesPerPixel != 0)
                {
                    directory.Set(EpsDirectory.TagRamSize, bytesPerPixel * width * height);
                }
            }
        }
Exemple #4
0
        public DirectoryList Extract(Stream inputStream)
        {
            IndexedReader reader         = new IndexedSeekingReader(inputStream);
            var           directory      = new EpsDirectory();
            var           epsDirectories = new List <Directory>()
            {
                directory
            };

            // 0xC5D0D3C6 signifies an EPS Header block which contains 32-bytes of basic information
            // 0x25215053 (%!PS) signifies an EPS File and leads straight into the PostScript

            int startingPosition = (int)inputStream.Position;

            switch (reader.GetInt32(0))
            {
            case unchecked ((int)0xC5D0D3C6):
                reader = reader.WithByteOrder(isMotorolaByteOrder: false);
                int postScriptOffset = reader.GetInt32(4);
                int postScriptLength = reader.GetInt32(8);
                int wmfOffset        = reader.GetInt32(12);
                int wmfSize          = reader.GetInt32(16);
                int tifOffset        = reader.GetInt32(20);
                int tifSize          = reader.GetInt32(24);
                //int checkSum = reader.getInt32(28);

                // Get Tiff/WMF preview data if applicable
                if (tifSize != 0)
                {
                    directory.Set(EpsDirectory.TagTiffPreviewSize, tifSize);
                    directory.Set(EpsDirectory.TagTiffPreviewOffset, tifOffset);
                    // Get Tiff metadata
                    try
                    {
                        ByteArrayReader byteArrayReader = new(reader.GetBytes(tifOffset, tifSize));
                        TiffReader.ProcessTiff(byteArrayReader, new PhotoshopTiffHandler(epsDirectories));
                    }
                    catch (TiffProcessingException ex)
                    {
                        directory.AddError("Unable to process TIFF data: " + ex.Message);
                    }
                }
                else if (wmfSize != 0)
                {
                    directory.Set(EpsDirectory.TagWmfPreviewSize, wmfSize);
                    directory.Set(EpsDirectory.TagWmfPreviewOffset, wmfOffset);
                }

                // TODO avoid allocating byte array here -- read directly from InputStream
                Extract(directory, epsDirectories, new SequentialByteArrayReader(reader.GetBytes(postScriptOffset, postScriptLength)));
                break;

            case 0x25215053:
                inputStream.Position = startingPosition;
                Extract(directory, epsDirectories, new SequentialStreamReader(inputStream));
                break;

            default:
                directory.AddError("File type not supported.");
                break;
            }

            return(epsDirectories);
        }