Sample code for 30+ languages & platforms
C Requires Chilkat v11.7.0+

Remove a PDF's Old Revisions

See more PDF Optimization Examples

Demonstrates dropOldRevisions. A PDF that has been edited and saved several times carries every earlier revision: the superseded objects are still in the file, reachable through the older cross-reference sections. The audit reports them as "oldRevisions", and dropping them is often the single largest saving in a real document. Dropping them requires a full rewrite, which is why it invalidates existing digital signatures.

Chilkat C Downloads

C
#include <C_CkPdf.h>
#include <C_CkJsonObject.h>
#include <C_CkFileAccess.h>

void ChilkatSample(void)
    {
    BOOL success;
    HCkPdf pdf;
    HCkJsonObject json;
    HCkJsonObject jsonOut;
    HCkFileAccess fac;

    success = FALSE;

    //  This example requires the Chilkat API to have been previously unlocked.
    //  See Global Unlock Sample for sample code.

    //  The PDF used in this example is available at grand_canyon_hiking_guide.pdf

    pdf = CkPdf_Create();
    success = CkPdf_LoadFile(pdf,"qa_data/pdf/grand_canyon_hiking_guide.pdf");
    if (success == FALSE) {
        printf("%s\n",CkPdf_lastErrorText(pdf));
        CkPdf_Dispose(pdf);
        return;
    }

    //  How much of this file is superseded revisions?
    json = CkJsonObject_Create();
    jsonOut = CkJsonObject_Create();
    success = CkPdf_Optimize(pdf,"audit",json,jsonOut);
    if (success == FALSE) {
        printf("%s\n",CkPdf_lastErrorText(pdf));
        CkPdf_Dispose(pdf);
        CkJsonObject_Dispose(json);
        CkJsonObject_Dispose(jsonOut);
        return;
    }

    printf("fileSize:     %d\n",CkJsonObject_IntOf(jsonOut,"fileSize"));
    printf("oldRevisions: %d\n",CkJsonObject_IntOf(jsonOut,"usage.oldRevisions.bytes"));

    //  Drop them, and nothing else, so that the saving is attributable.
    CkJsonObject_UpdateBool(json,"compressUncompressed",FALSE);
    CkJsonObject_UpdateBool(json,"recompressFlate",FALSE);
    CkJsonObject_UpdateBool(json,"replaceLegacyFilters",FALSE);
    CkJsonObject_UpdateBool(json,"imagePredictors",FALSE);
    CkJsonObject_UpdateBool(json,"dedupeStreams",FALSE);
    CkJsonObject_UpdateBool(json,"dedupeObjects",FALSE);
    CkJsonObject_UpdateBool(json,"removeUnreferenced",FALSE);
    CkJsonObject_UpdateBool(json,"removeUnusedResources",FALSE);
    CkJsonObject_UpdateBool(json,"removeUnusedLayers",FALSE);
    CkJsonObject_UpdateBool(json,"coalesceContent",FALSE);
    CkJsonObject_UpdateBool(json,"tidyContent",FALSE);
    CkJsonObject_UpdateBool(json,"subsetFonts",FALSE);
    CkJsonObject_UpdateBool(json,"dropOldRevisions",TRUE);

    success = CkPdf_Optimize(pdf,"optimize",json,jsonOut);
    if (success == FALSE) {
        printf("%s\n",CkPdf_lastErrorText(pdf));
        CkPdf_Dispose(pdf);
        CkJsonObject_Dispose(json);
        CkJsonObject_Dispose(jsonOut);
        return;
    }

    success = CkPdf_WriteFile(pdf,"qa_output/grand_canyon_one_revision.pdf");
    if (success == FALSE) {
        printf("%s\n",CkPdf_lastErrorText(pdf));
        CkPdf_Dispose(pdf);
        CkJsonObject_Dispose(json);
        CkJsonObject_Dispose(jsonOut);
        return;
    }

    //  The saving is an estimate: what the old revisions occupied is known exactly, but the writer
    //  decides the final layout.  Measure the written file for the real number.
    fac = CkFileAccess_Create();
    printf("bytesSaved (reported): %d\n",CkJsonObject_IntOf(jsonOut,"bytesSaved"));
    printf("written file:          %d\n",CkFileAccess_FileSize(fac,"qa_output/grand_canyon_one_revision.pdf"));


    CkPdf_Dispose(pdf);
    CkJsonObject_Dispose(json);
    CkJsonObject_Dispose(jsonOut);
    CkFileAccess_Dispose(fac);

    }