static void handle_transformations(QPDF& pdf, Options& o)
{
    QPDFPageDocumentHelper dh(pdf);
    if (o.externalize_inline_images)
    {
        std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
        for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
             iter != pages.end(); ++iter)
        {
            QPDFPageObjectHelper& ph(*iter);
            ph.externalizeInlineImages(o.ii_min_bytes);
        }
    }
    if (o.optimize_images)
    {
        int pageno = 0;
        std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
        for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
             iter != pages.end(); ++iter)
        {
            ++pageno;
            QPDFPageObjectHelper& ph(*iter);
            QPDFObjectHandle page = ph.getObjectHandle();
            std::map<std::string, QPDFObjectHandle> images =
                ph.getPageImages();
            for (std::map<std::string, QPDFObjectHandle>::iterator iter =
                     images.begin();
                 iter != images.end(); ++iter)
            {
                std::string name = (*iter).first;
                QPDFObjectHandle& image = (*iter).second;
                ImageOptimizer* io = new ImageOptimizer(o, image);
                PointerHolder<QPDFObjectHandle::StreamDataProvider> sdp(io);
                if (io->evaluate("image " + name + " on page " +
                                 QUtil::int_to_string(pageno)))
                {
                    QPDFObjectHandle new_image =
                        QPDFObjectHandle::newStream(&pdf);
                    new_image.replaceDict(image.getDict().shallowCopy());
                    new_image.replaceStreamData(
                        sdp,
                        QPDFObjectHandle::newName("/DCTDecode"),
                        QPDFObjectHandle::newNull());
                    ph.getAttribute("/Resources", true).
                        getKey("/XObject").replaceKey(
                            name, new_image);
                }
            }
        }
    }
    if (o.generate_appearances)
    {
        QPDFAcroFormDocumentHelper afdh(pdf);
        afdh.generateAppearancesIfNeeded();
    }
    if (o.flatten_annotations)
    {
        dh.flattenAnnotations(o.flatten_annotations_required,
                              o.flatten_annotations_forbidden);
    }
    if (o.coalesce_contents)
    {
        std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
        for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
             iter != pages.end(); ++iter)
        {
            (*iter).coalesceContentStreams();
        }
    }
    if (o.remove_page_labels)
    {
        pdf.getRoot().removeKey("/PageLabels");
    }
}
static void handle_transformations(QPDF& pdf, Options& o)
{
    QPDFPageDocumentHelper dh(pdf);
    if (o.externalize_inline_images)
    {
        std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
        for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
             iter != pages.end(); ++iter)
        {
            QPDFPageObjectHelper& ph(*iter);
            ph.externalizeInlineImages(o.ii_min_bytes);
        }
    }
    if (o.optimize_images)
    {
        int pageno = 0;
        std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
        for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
             iter != pages.end(); ++iter)
        {
            ++pageno;
            QPDFPageObjectHelper& ph(*iter);
            QPDFObjectHandle page = ph.getObjectHandle();
            std::map<std::string, QPDFObjectHandle> images =
                ph.getPageImages();
            for (std::map<std::string, QPDFObjectHandle>::iterator iter =
                     images.begin();
                 iter != images.end(); ++iter)
            {
                std::string name = (*iter).first;
                QPDFObjectHandle& image = (*iter).second;
                ImageOptimizer* io = new ImageOptimizer(o, image);
                PointerHolder<QPDFObjectHandle::StreamDataProvider> sdp(io);
                if (io->evaluate("image " + name + " on page " +
                                 QUtil::int_to_string(pageno)))
                {
                    QPDFObjectHandle new_image =
                        QPDFObjectHandle::newStream(&pdf);
                    new_image.replaceDict(image.getDict().shallowCopy());
                    new_image.replaceStreamData(
                        sdp,
                        QPDFObjectHandle::newName("/DCTDecode"),
                        QPDFObjectHandle::newNull());
                    ph.getAttribute("/Resources", true).
                        getKey("/XObject").replaceKey(
                            name, new_image);
                }
            }
        }
    }
    if (o.generate_appearances)
    {
        QPDFAcroFormDocumentHelper afdh(pdf);
        afdh.generateAppearancesIfNeeded();
    }
    if (o.flatten_annotations)
    {
        dh.flattenAnnotations(o.flatten_annotations_required,
                              o.flatten_annotations_forbidden);
    }
    if (o.coalesce_contents)
    {
        std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
        for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
             iter != pages.end(); ++iter)
        {
            (*iter).coalesceContentStreams();
        }
    }
    if (o.remove_page_labels)
    {
        pdf.getRoot().removeKey("/PageLabels");
    }
}