⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pdfxref.cs

📁 PDF文件格式解析库源代码
💻 CS
字号:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace AnotherPDFLib
{
    /// <summary>
    /// Cross-Reference Table
    /// </summary>
    public class PdfXref
    {
        public UInt32 Offset;
        public List<PdfXrefSection> Sections;
        PdfXrefSection OriginalSection;
        public bool InStream;

        public PdfXref()
        {
            Sections = new List<PdfXrefSection>();
            OriginalSection = new PdfXrefSection(0);
            Sections.Add(OriginalSection);
        }
        internal void AddXrefEntry(UInt32 offset)
        {
            PdfXrefEntry entry = new PdfXrefEntryNoraml(offset, 0);
            OriginalSection.Entries.Add(entry);
        }

        internal void AddXrefFreeEntry(UInt32 offset)
        {
            PdfXrefEntry entry = new PdfXrefEntryFree(offset, 0);
            OriginalSection.Entries.Add(entry);
        }

        internal void AddXrefFreeEntry(UInt32 nextObjNum, UInt16 generation)
        {
            PdfXrefEntry entry = new PdfXrefEntryFree(nextObjNum, generation);
            OriginalSection.Entries.Add(entry);
        }

        public void Initialize()
        {
            foreach (PdfXrefSection section in Sections)
            {
                section.Entries.Clear();
            }
            Sections.Clear();
            OriginalSection.Entries.Add(PdfXrefEntryFree.FirstEntry);
            Sections.Add(OriginalSection);
        }

        public IEnumerable<PdfXrefEntry> Entries
        {
            get
            {
                foreach (PdfXrefSection section in Sections)
                {
                    foreach (PdfXrefEntry entry in section.Entries)
                    {
                        yield return entry;
                    }
                }
            }
        }

        /// <summary>
        /// The total number of entries in cross-reference table
        /// </summary>
        public int EntryCount
        {
            get
            {
                int count = 0;
                foreach (PdfXrefSection section in Sections)
                {
                    count += section.Entries.Count;
                }
                return count;
            }
        }

        public void Output(PdfWriter writer)
        {
            writer.WriteLine("xref");
            foreach (PdfXrefSection section in Sections)
            {
                section.Output(writer);
            }
        }

        public void ReadEntriesFromStream(PdfXRefStream xrefstream)
        {
            PdfArray sectionIndex = xrefstream.Index;
            if (sectionIndex == null)
            {
                sectionIndex = new PdfArray();
                sectionIndex.Add(new PdfInteger(0));
                sectionIndex.Add(new PdfInteger(xrefstream.Size));
            }

            int bytesFirst = ((PdfInteger)xrefstream.FieldWidths[0]).Value;
            int bytesSecond = ((PdfInteger)xrefstream.FieldWidths[1]).Value;
            int bytesThird = ((PdfInteger)xrefstream.FieldWidths[2]).Value;
            int bytesTotal = bytesFirst + bytesSecond + bytesThird;

            xrefstream.Content.Position = 0;
            BinaryReader reader = new BinaryReader(xrefstream.Content);
            for (int i = 0; i < sectionIndex.Length / 2; i++)
            {
                int startObjectNumber = ((PdfInteger)sectionIndex[i * 2]).Value;
                int numberOfEntries = ((PdfInteger)sectionIndex[i * 2 + 1]).Value;
                PdfXrefSection section = new PdfXrefSection((UInt32)startObjectNumber);
                for (int j = 0; j < numberOfEntries; j++)
                {
                    byte[] bytes = reader.ReadBytes(bytesTotal);
                    int entryType = 1;
                    if (bytesFirst > 0)
                    {
                        entryType = (int)ReadBigEndianInterger(bytes, 0, bytesFirst);
                    }
                    PdfXrefEntry entry;
                    switch (entryType)
                    {
                        case 0: //free object
                            entry = ReadFreeEntry(bytesFirst, bytesSecond, bytesThird, bytes);
                            break;
                        case 1: //normal object
                            entry = ReadNormalEntry(bytesFirst, bytesSecond, bytesThird, bytes);
                            break;
                        case 2: //compressed object
                            entry = ReadCompressedEntry(bytesFirst, bytesSecond, bytesThird, bytes);
                            break;
                        default:
                            entry = new PdfXrefEntryFree();
                            break;
                    }
                    section.Entries.Add(entry);
                }
                Sections.Add(section);
            }
        }

        private PdfXrefEntryCompressed ReadCompressedEntry(int bytesFirst, int bytesSecond, int bytesThird, byte[] bytes)
        {
            PdfXrefEntryCompressed entry = new PdfXrefEntryCompressed();
            entry.ContainerObjectNumber = ReadBigEndianInterger(bytes, bytesFirst, bytesSecond);
            entry.Index = (UInt16)ReadBigEndianInterger(bytes, bytesFirst + bytesSecond, bytesThird);
            return entry;
        }

        private PdfXrefEntryNoraml ReadNormalEntry(int bytesFirst, int bytesSecond, int bytesThird, byte[] bytes)
        {
            PdfXrefEntryNoraml entry = new PdfXrefEntryNoraml(0, 0);
            entry.Offset = ReadBigEndianInterger(bytes, bytesFirst, bytesSecond);
            if (bytesThird > 0)
            {
                entry.Generation = (UInt16)ReadBigEndianInterger(bytes, bytesFirst + bytesSecond, bytesThird);
            }
            return entry;
        }

        private PdfXrefEntryFree ReadFreeEntry(int bytesFirst, int bytesSecond, int bytesThird, byte[] bytes)
        {
            PdfXrefEntryFree entry = new PdfXrefEntryFree();
            entry.NextObjectNumber = ReadBigEndianInterger(bytes, bytesFirst, bytesSecond);
            entry.Generation = (UInt16)ReadBigEndianInterger(bytes, bytesFirst + bytesSecond, bytesThird);
            return entry;
        }

        private uint ReadBigEndianInterger(byte[] bytes, int startIndex, int numBytes)
        {
            uint value = 0;
            for (int i = 0; i < numBytes; i++)
            {
                value = (value << 8) + bytes[startIndex + i];
            }
            return value;
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -