שחזור הפניות-צירוף חסום

HotPDF יכול לשחזר גרף אובייקטים אמיתי ועץ עמודים כאשר ל-PDF יש הצהרת startxref חסרה, בלתי-תקינה או מיושנת, או שורות xref בלתי-שמישות

רצף שחזור

  1. הטוען הרגיל תואם-המפרט רץ ראשון במצב xrrmOnFailure ברירת המחדל
  2. השחזור סורק את המקור בנתחים של 1 MiB עם carry קצר בין נתחים ורושם אובייקטים עקיפים מאומתים ועוגני xref
  3. סמנים המקוננים בתוך אובייקט עקיף מאומת נדחים, לרבות מחרוזות, הערות, מילונים ונתוני זרם בינאריים המכילים טקסט כגון 99 0 obj או xref
  4. טבלאות או זרמי xref תקפים מנוסים מהחדש ביותר אל הישן ביותר דרך הטוען האינקרמנטלי, ההיברידי ו-shל object-stream הקיים
  5. לכל היותר 4,096 עוגני סעיף xref נשמרים, ובכך נמנעת הכפלת ניסיונות פרסור על ידי חזרת סמנים עוינת
  6. אם אף סעיף xref אינו מייצר עץ עמודים אמיתי, היסטי אובייקט-ישיר נבנים מחדש ומספרי אובייקטים כפולים משתמשים בהגדרה הפיזית החדשה ביותר
  7. השחזור מצליח רק כאשר Catalog אמיתי, עץ Pages ולפחות עלה עמוד אחד נפתרים

הצהרות

type
  THPDFXRefRecoveryMode = (
    xrrmDisabled,
    xrrmOnFailure,
    xrrmForce
  );

  THPDFXRefRecoveryStatus = (
    xrrsNotNeeded,
    xrrsSucceeded,
    xrrsDisabled,
    xrrsScanLimitExceeded,
    xrrsObjectLimitExceeded,
    xrrsXRefLimitExceeded,
    xrrsFailed
  );

  THPDFXRefRecoveryMethod = (
    xrrmethodNone,
    xrrmethodRelocatedSection,
    xrrmethodRebuiltObjectOffsets
  );

  THPDFXRefMergeInfo = record
    HybridRevisionCount: Integer;
    HybridOverlapCount: Integer;
    OlderRevisionShadowedEntryCount: Integer;
    DuplicateEntryCount: Integer;
    NewestRevisionPrecedenceApplied: boolean;
    HybridStreamPrecedenceApplied: boolean;
  end;

property XRefRecoveryMode: THPDFXRefRecoveryMode;
property XRefRecoveryMaxScanBytes: Int64;
property XRefRecoveryMaxObjects: Integer;

function GetLoadedXRefRecoveryInfo(
  out Info: THPDFXRefRecoveryInfo
): boolean;

function GetLoadedXRefMergeInfo(
  out Info: THPDFXRefMergeInfo
): boolean;

הגדרה

חברברירת מחדלמטרה
XRefRecoveryModexrrmOnFailureמשבית את השחזור, מריץ אותו רק לאחר שהפרסור הרגיל נכשל, או מכריח אותו לפני הפרסור הרגיל
XRefRecoveryMaxScanBytes8 GiBגודל מקור מרבי קשיח שסריקת השחזור המנותחת מקבלת
XRefRecoveryMaxObjects2,000,000מרב מועמדי אובייקט-עקיף מאומתים קשיח שהשחזור מקבל
ParserRecoveryEventLimit1,024מקסימום אירועים מובנים שנשמרו עבור טעינה אחת, כאשר אפס מנטרל שימור אירועים

מידע שחזור

GetLoadedXRefRecoveryInfo מחזיר True כאשר נעשה ניסיון שחזור ומעתיק את רשומת THPDFXRefRecoveryInfo העדכנית ביותר

אירועי שחזור מובנים

GetLoadedParserRecoveryEvents מחזיר תמונת מצב בבעלות הקורא של זרם האירועים שנשמרו, בעוד GetLoadedParserRecoveryEvent קורא רשומה אחת בלי להקצות עותק מערך

מידע קדימות מיזוג

GetLoadedXRefMergeInfo מחזיר True כשטעינת xref-stream או הפניה-היברידית נתקלה במצב מיזוג ששווה לדווח עליו

מידע שלמות

GetLoadedXRefIntegrityInfo מדווח על שרשרת הרשימה-הפנויה הפעילה, קישורים לא תקינים, מחזורים, רשומות פנויות לא מקושרות, שגיאות מעבר generation, הגדרות חיות כפולות ורשומות ישנות שמוצלות על ידי המהדורה החדשה ביותר

פירוט ההצללה כולל סוגי רשומות פעילים ונדחים, offsets או שדות אחסון, generations ועומק מהדורה, עם תקרת פירוט קבועה של 256 רשומות

שמירת מסמכים משוחזרים

מסמך משוחזר תמיד משתמש בנתיב השכתוב-המלא ב-SaveLoadedDocument, אפילו כאשר אף אובייקט לא נערך, כך ש-HotPDF לעולם אינו מעתיק בתים פגומים של המקור כפלט שנראה כמתוקן

דוגמה

var
  Info: THPDFXRefRecoveryInfo;
  PDF: THotPDF;
begin
  PDF := THotPDF.Create(nil);
  try
    PDF.XRefRecoveryMode := xrrmOnFailure;
    PDF.XRefRecoveryMaxScanBytes := Int64(16) * 1024 * 1024 * 1024;
    PDF.XRefRecoveryMaxObjects := 3000000;
    if PDF.LoadFromFile('damaged.pdf') > 0 then
    begin
      if PDF.GetLoadedXRefRecoveryInfo(Info) then
        WriteLn(Info.Diagnostic);
      PDF.SaveLoadedDocument('recovered.pdf');
    end;
  finally
    PDF.Free;
  end;
end;

APIs קשורים