Commit 5c866633537c603b96a4a070a1498dd1a4976e51
1 parent
807dbf42
Move QPDF inner class definitions to new QPDF_private.hh
Showing
11 changed files
with
595 additions
and
575 deletions
include/qpdf/QPDF.hh
| ... | ... | @@ -726,167 +726,14 @@ class QPDF |
| 726 | 726 | void removePage(QPDFObjectHandle page); |
| 727 | 727 | // End legacy page helpers |
| 728 | 728 | |
| 729 | - // Writer class is restricted to QPDFWriter so that only it can call certain methods. | |
| 730 | - class Writer | |
| 731 | - { | |
| 732 | - friend class QPDFWriter; | |
| 733 | - | |
| 734 | - private: | |
| 735 | - static void | |
| 736 | - optimize( | |
| 737 | - QPDF& qpdf, | |
| 738 | - QPDFWriter::ObjTable const& obj, | |
| 739 | - std::function<int(QPDFObjectHandle&)> skip_stream_parameters) | |
| 740 | - { | |
| 741 | - return qpdf.optimize(obj, skip_stream_parameters); | |
| 742 | - } | |
| 743 | - | |
| 744 | - static void | |
| 745 | - getLinearizedParts( | |
| 746 | - QPDF& qpdf, | |
| 747 | - QPDFWriter::ObjTable const& obj, | |
| 748 | - std::vector<QPDFObjectHandle>& part4, | |
| 749 | - std::vector<QPDFObjectHandle>& part6, | |
| 750 | - std::vector<QPDFObjectHandle>& part7, | |
| 751 | - std::vector<QPDFObjectHandle>& part8, | |
| 752 | - std::vector<QPDFObjectHandle>& part9) | |
| 753 | - { | |
| 754 | - qpdf.getLinearizedParts(obj, part4, part6, part7, part8, part9); | |
| 755 | - } | |
| 756 | - | |
| 757 | - static void | |
| 758 | - generateHintStream( | |
| 759 | - QPDF& qpdf, | |
| 760 | - QPDFWriter::NewObjTable const& new_obj, | |
| 761 | - QPDFWriter::ObjTable const& obj, | |
| 762 | - std::shared_ptr<Buffer>& hint_stream, | |
| 763 | - int& S, | |
| 764 | - int& O, | |
| 765 | - bool compressed) | |
| 766 | - { | |
| 767 | - return qpdf.generateHintStream(new_obj, obj, hint_stream, S, O, compressed); | |
| 768 | - } | |
| 769 | - | |
| 770 | - static std::vector<QPDFObjGen> | |
| 771 | - getCompressibleObjGens(QPDF& qpdf) | |
| 772 | - { | |
| 773 | - return qpdf.getCompressibleObjVector(); | |
| 774 | - } | |
| 775 | - | |
| 776 | - static std::vector<bool> | |
| 777 | - getCompressibleObjSet(QPDF& qpdf) | |
| 778 | - { | |
| 779 | - return qpdf.getCompressibleObjSet(); | |
| 780 | - } | |
| 781 | - | |
| 782 | - static std::map<QPDFObjGen, QPDFXRefEntry> const& | |
| 783 | - getXRefTable(QPDF& qpdf) | |
| 784 | - { | |
| 785 | - return qpdf.getXRefTableInternal(); | |
| 786 | - } | |
| 729 | + // End of the public API. The following classes and methods are for qpdf internal use only. | |
| 787 | 730 | |
| 788 | - static size_t | |
| 789 | - tableSize(QPDF& qpdf) | |
| 790 | - { | |
| 791 | - return qpdf.tableSize(); | |
| 792 | - } | |
| 793 | - }; | |
| 794 | - | |
| 795 | - // The Resolver class is restricted to QPDFObject so that only it can resolve indirect | |
| 796 | - // references. | |
| 797 | - class Resolver | |
| 798 | - { | |
| 799 | - friend class QPDFObject; | |
| 800 | - friend class QPDF_Unresolved; | |
| 801 | - friend class qpdf::BaseHandle; | |
| 802 | - | |
| 803 | - private: | |
| 804 | - static std::shared_ptr<QPDFObject> const& | |
| 805 | - resolved(QPDF* qpdf, QPDFObjGen og) | |
| 806 | - { | |
| 807 | - return qpdf->resolve(og); | |
| 808 | - } | |
| 809 | - }; | |
| 810 | - | |
| 811 | - // StreamCopier class is restricted to QPDFObjectHandle so it can copy stream data. | |
| 812 | - class StreamCopier | |
| 813 | - { | |
| 814 | - friend class QPDFObjectHandle; | |
| 815 | - | |
| 816 | - private: | |
| 817 | - static void | |
| 818 | - copyStreamData(QPDF* qpdf, QPDFObjectHandle const& dest, QPDFObjectHandle const& src) | |
| 819 | - { | |
| 820 | - qpdf->copyStreamData(dest, src); | |
| 821 | - } | |
| 822 | - }; | |
| 823 | - | |
| 824 | - // The ParseGuard class allows QPDFParser to detect re-entrant parsing. It also provides | |
| 825 | - // special access to allow the parser to create unresolved objects and dangling references. | |
| 826 | - class ParseGuard | |
| 827 | - { | |
| 828 | - friend class QPDFParser; | |
| 829 | - | |
| 830 | - private: | |
| 831 | - ParseGuard(QPDF* qpdf) : | |
| 832 | - qpdf(qpdf) | |
| 833 | - { | |
| 834 | - if (qpdf) { | |
| 835 | - qpdf->inParse(true); | |
| 836 | - } | |
| 837 | - } | |
| 838 | - | |
| 839 | - static std::shared_ptr<QPDFObject> | |
| 840 | - getObject(QPDF* qpdf, int id, int gen, bool parse_pdf) | |
| 841 | - { | |
| 842 | - return qpdf->getObjectForParser(id, gen, parse_pdf); | |
| 843 | - } | |
| 844 | - | |
| 845 | - ~ParseGuard() | |
| 846 | - { | |
| 847 | - if (qpdf) { | |
| 848 | - qpdf->inParse(false); | |
| 849 | - } | |
| 850 | - } | |
| 851 | - QPDF* qpdf; | |
| 852 | - }; | |
| 853 | - | |
| 854 | - // Pipe class is restricted to QPDF_Stream. | |
| 855 | - class Pipe | |
| 856 | - { | |
| 857 | - friend class QPDF_Stream; | |
| 858 | - friend class qpdf::Stream; | |
| 859 | - | |
| 860 | - private: | |
| 861 | - static bool | |
| 862 | - pipeStreamData( | |
| 863 | - QPDF* qpdf, | |
| 864 | - QPDFObjGen og, | |
| 865 | - qpdf_offset_t offset, | |
| 866 | - size_t length, | |
| 867 | - QPDFObjectHandle dict, | |
| 868 | - Pipeline* pipeline, | |
| 869 | - bool suppress_warnings, | |
| 870 | - bool will_retry) | |
| 871 | - { | |
| 872 | - return qpdf->pipeStreamData( | |
| 873 | - og, offset, length, dict, pipeline, suppress_warnings, will_retry); | |
| 874 | - } | |
| 875 | - }; | |
| 876 | - | |
| 877 | - // JobSetter class is restricted to QPDFJob. | |
| 878 | - class JobSetter | |
| 879 | - { | |
| 880 | - friend class QPDFJob; | |
| 881 | - | |
| 882 | - private: | |
| 883 | - // Enable enhanced warnings for pdf file checking. | |
| 884 | - static void | |
| 885 | - setCheckMode(QPDF& qpdf, bool val) | |
| 886 | - { | |
| 887 | - qpdf.m->check_mode = val; | |
| 888 | - } | |
| 889 | - }; | |
| 731 | + class Writer; | |
| 732 | + class Resolver; | |
| 733 | + class StreamCopier; | |
| 734 | + class ParseGuard; | |
| 735 | + class Pipe; | |
| 736 | + class JobSetter; | |
| 890 | 737 | |
| 891 | 738 | // For testing only -- do not add to DLL |
| 892 | 739 | static bool test_json_validators(); |
| ... | ... | @@ -901,136 +748,13 @@ class QPDF |
| 901 | 748 | |
| 902 | 749 | static std::string const qpdf_version; |
| 903 | 750 | |
| 904 | - class ObjCache | |
| 905 | - { | |
| 906 | - public: | |
| 907 | - ObjCache() : | |
| 908 | - end_before_space(0), | |
| 909 | - end_after_space(0) | |
| 910 | - { | |
| 911 | - } | |
| 912 | - ObjCache( | |
| 913 | - std::shared_ptr<QPDFObject> object, | |
| 914 | - qpdf_offset_t end_before_space = 0, | |
| 915 | - qpdf_offset_t end_after_space = 0) : | |
| 916 | - object(object), | |
| 917 | - end_before_space(end_before_space), | |
| 918 | - end_after_space(end_after_space) | |
| 919 | - { | |
| 920 | - } | |
| 921 | - | |
| 922 | - std::shared_ptr<QPDFObject> object; | |
| 923 | - qpdf_offset_t end_before_space; | |
| 924 | - qpdf_offset_t end_after_space; | |
| 925 | - }; | |
| 926 | - | |
| 927 | - class ObjCopier | |
| 928 | - { | |
| 929 | - public: | |
| 930 | - std::map<QPDFObjGen, QPDFObjectHandle> object_map; | |
| 931 | - std::vector<QPDFObjectHandle> to_copy; | |
| 932 | - QPDFObjGen::set visiting; | |
| 933 | - }; | |
| 934 | - | |
| 935 | - class EncryptionParameters | |
| 936 | - { | |
| 937 | - friend class QPDF; | |
| 938 | - | |
| 939 | - public: | |
| 940 | - EncryptionParameters(); | |
| 941 | - | |
| 942 | - private: | |
| 943 | - bool encrypted; | |
| 944 | - bool encryption_initialized; | |
| 945 | - int encryption_V; | |
| 946 | - int encryption_R; | |
| 947 | - bool encrypt_metadata; | |
| 948 | - std::map<std::string, encryption_method_e> crypt_filters; | |
| 949 | - encryption_method_e cf_stream; | |
| 950 | - encryption_method_e cf_string; | |
| 951 | - encryption_method_e cf_file; | |
| 952 | - std::string provided_password; | |
| 953 | - std::string user_password; | |
| 954 | - std::string encryption_key; | |
| 955 | - std::string cached_object_encryption_key; | |
| 956 | - QPDFObjGen cached_key_og; | |
| 957 | - bool user_password_matched; | |
| 958 | - bool owner_password_matched; | |
| 959 | - }; | |
| 960 | - | |
| 961 | - class ForeignStreamData | |
| 962 | - { | |
| 963 | - friend class QPDF; | |
| 964 | - | |
| 965 | - public: | |
| 966 | - ForeignStreamData( | |
| 967 | - std::shared_ptr<EncryptionParameters> encp, | |
| 968 | - std::shared_ptr<InputSource> file, | |
| 969 | - QPDFObjGen foreign_og, | |
| 970 | - qpdf_offset_t offset, | |
| 971 | - size_t length, | |
| 972 | - QPDFObjectHandle local_dict); | |
| 973 | - | |
| 974 | - private: | |
| 975 | - std::shared_ptr<EncryptionParameters> encp; | |
| 976 | - std::shared_ptr<InputSource> file; | |
| 977 | - QPDFObjGen foreign_og; | |
| 978 | - qpdf_offset_t offset; | |
| 979 | - size_t length; | |
| 980 | - QPDFObjectHandle local_dict; | |
| 981 | - }; | |
| 982 | - | |
| 983 | - class CopiedStreamDataProvider: public QPDFObjectHandle::StreamDataProvider | |
| 984 | - { | |
| 985 | - public: | |
| 986 | - CopiedStreamDataProvider(QPDF& destination_qpdf); | |
| 987 | - ~CopiedStreamDataProvider() override = default; | |
| 988 | - bool provideStreamData( | |
| 989 | - QPDFObjGen const& og, | |
| 990 | - Pipeline* pipeline, | |
| 991 | - bool suppress_warnings, | |
| 992 | - bool will_retry) override; | |
| 993 | - void registerForeignStream(QPDFObjGen const& local_og, QPDFObjectHandle foreign_stream); | |
| 994 | - void registerForeignStream(QPDFObjGen const& local_og, std::shared_ptr<ForeignStreamData>); | |
| 995 | - | |
| 996 | - private: | |
| 997 | - QPDF& destination_qpdf; | |
| 998 | - std::map<QPDFObjGen, QPDFObjectHandle> foreign_streams; | |
| 999 | - std::map<QPDFObjGen, std::shared_ptr<ForeignStreamData>> foreign_stream_data; | |
| 1000 | - }; | |
| 1001 | - | |
| 1002 | - class StringDecrypter: public QPDFObjectHandle::StringDecrypter | |
| 1003 | - { | |
| 1004 | - friend class QPDF; | |
| 1005 | - | |
| 1006 | - public: | |
| 1007 | - StringDecrypter(QPDF* qpdf, QPDFObjGen og); | |
| 1008 | - ~StringDecrypter() override = default; | |
| 1009 | - void decryptString(std::string& val) override; | |
| 1010 | - | |
| 1011 | - private: | |
| 1012 | - QPDF* qpdf; | |
| 1013 | - QPDFObjGen og; | |
| 1014 | - }; | |
| 1015 | - | |
| 1016 | - class ResolveRecorder | |
| 1017 | - { | |
| 1018 | - public: | |
| 1019 | - ResolveRecorder(QPDF* qpdf, QPDFObjGen og) : | |
| 1020 | - qpdf(qpdf), | |
| 1021 | - iter(qpdf->m->resolving.insert(og).first) | |
| 1022 | - { | |
| 1023 | - } | |
| 1024 | - virtual ~ResolveRecorder() | |
| 1025 | - { | |
| 1026 | - this->qpdf->m->resolving.erase(iter); | |
| 1027 | - } | |
| 1028 | - | |
| 1029 | - private: | |
| 1030 | - QPDF* qpdf; | |
| 1031 | - std::set<QPDFObjGen>::const_iterator iter; | |
| 1032 | - }; | |
| 1033 | - | |
| 751 | + class ObjCache; | |
| 752 | + class ObjCopier; | |
| 753 | + class EncryptionParameters; | |
| 754 | + class ForeignStreamData; | |
| 755 | + class CopiedStreamDataProvider; | |
| 756 | + class StringDecrypter; | |
| 757 | + class ResolveRecorder; | |
| 1034 | 758 | class JSONReactor; |
| 1035 | 759 | |
| 1036 | 760 | void parse(char const* password); |
| ... | ... | @@ -1200,200 +924,19 @@ class QPDF |
| 1200 | 924 | replaceForeignIndirectObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top); |
| 1201 | 925 | void copyStreamData(QPDFObjectHandle dest_stream, QPDFObjectHandle src_stream); |
| 1202 | 926 | |
| 1203 | - // Linearization Hint table structures. | |
| 1204 | - // Naming conventions: | |
| 1205 | - | |
| 1206 | - // HSomething is the Something Hint Table or table header | |
| 1207 | - // HSomethingEntry is an entry in the Something table | |
| 1208 | - | |
| 1209 | - // delta_something + min_something = something | |
| 1210 | - // nbits_something = number of bits required for something | |
| 1211 | - | |
| 1212 | - // something_offset is the pre-adjusted offset in the file. If >= | |
| 1213 | - // H0_offset, H0_length must be added to get an actual file | |
| 1214 | - // offset. | |
| 1215 | - | |
| 1216 | - // PDF 1.4: Table F.4 | |
| 1217 | - struct HPageOffsetEntry | |
| 1218 | - { | |
| 1219 | - int delta_nobjects{0}; // 1 | |
| 1220 | - qpdf_offset_t delta_page_length{0}; // 2 | |
| 1221 | - // vectors' sizes = nshared_objects | |
| 1222 | - int nshared_objects{0}; // 3 | |
| 1223 | - std::vector<int> shared_identifiers; // 4 | |
| 1224 | - std::vector<int> shared_numerators; // 5 | |
| 1225 | - qpdf_offset_t delta_content_offset{0}; // 6 | |
| 1226 | - qpdf_offset_t delta_content_length{0}; // 7 | |
| 1227 | - }; | |
| 1228 | - | |
| 1229 | - // PDF 1.4: Table F.3 | |
| 1230 | - struct HPageOffset | |
| 1231 | - { | |
| 1232 | - int min_nobjects{0}; // 1 | |
| 1233 | - qpdf_offset_t first_page_offset{0}; // 2 | |
| 1234 | - int nbits_delta_nobjects{0}; // 3 | |
| 1235 | - int min_page_length{0}; // 4 | |
| 1236 | - int nbits_delta_page_length{0}; // 5 | |
| 1237 | - int min_content_offset{0}; // 6 | |
| 1238 | - int nbits_delta_content_offset{0}; // 7 | |
| 1239 | - int min_content_length{0}; // 8 | |
| 1240 | - int nbits_delta_content_length{0}; // 9 | |
| 1241 | - int nbits_nshared_objects{0}; // 10 | |
| 1242 | - int nbits_shared_identifier{0}; // 11 | |
| 1243 | - int nbits_shared_numerator{0}; // 12 | |
| 1244 | - int shared_denominator{0}; // 13 | |
| 1245 | - // vector size is npages | |
| 1246 | - std::vector<HPageOffsetEntry> entries; | |
| 1247 | - }; | |
| 1248 | - | |
| 1249 | - // PDF 1.4: Table F.6 | |
| 1250 | - struct HSharedObjectEntry | |
| 1251 | - { | |
| 1252 | - // Item 3 is a 128-bit signature (unsupported by Acrobat) | |
| 1253 | - int delta_group_length{0}; // 1 | |
| 1254 | - int signature_present{0}; // 2 -- always 0 | |
| 1255 | - int nobjects_minus_one{0}; // 4 -- always 0 | |
| 1256 | - }; | |
| 1257 | - | |
| 1258 | - // PDF 1.4: Table F.5 | |
| 1259 | - struct HSharedObject | |
| 1260 | - { | |
| 1261 | - int first_shared_obj{0}; // 1 | |
| 1262 | - qpdf_offset_t first_shared_offset{0}; // 2 | |
| 1263 | - int nshared_first_page{0}; // 3 | |
| 1264 | - int nshared_total{0}; // 4 | |
| 1265 | - int nbits_nobjects{0}; // 5 | |
| 1266 | - int min_group_length{0}; // 6 | |
| 1267 | - int nbits_delta_group_length{0}; // 7 | |
| 1268 | - // vector size is nshared_total | |
| 1269 | - std::vector<HSharedObjectEntry> entries; | |
| 1270 | - }; | |
| 1271 | - | |
| 1272 | - // PDF 1.4: Table F.9 | |
| 1273 | - struct HGeneric | |
| 1274 | - { | |
| 1275 | - int first_object{0}; // 1 | |
| 1276 | - qpdf_offset_t first_object_offset{0}; // 2 | |
| 1277 | - int nobjects{0}; // 3 | |
| 1278 | - int group_length{0}; // 4 | |
| 1279 | - }; | |
| 1280 | - | |
| 1281 | - // Other linearization data structures | |
| 1282 | - | |
| 1283 | - // Initialized from Linearization Parameter dictionary | |
| 1284 | - struct LinParameters | |
| 1285 | - { | |
| 1286 | - qpdf_offset_t file_size{0}; // /L | |
| 1287 | - int first_page_object{0}; // /O | |
| 1288 | - qpdf_offset_t first_page_end{0}; // /E | |
| 1289 | - int npages{0}; // /N | |
| 1290 | - qpdf_offset_t xref_zero_offset{0}; // /T | |
| 1291 | - int first_page{0}; // /P | |
| 1292 | - qpdf_offset_t H_offset{0}; // offset of primary hint stream | |
| 1293 | - qpdf_offset_t H_length{0}; // length of primary hint stream | |
| 1294 | - }; | |
| 1295 | - | |
| 1296 | - // Computed hint table value data structures. These tables contain the computed values on which | |
| 1297 | - // the hint table values are based. They exclude things like number of bits and store actual | |
| 1298 | - // values instead of mins and deltas. File offsets are also absolute rather than being offset | |
| 1299 | - // by the size of the primary hint table. We populate the hint table structures from these | |
| 1300 | - // during writing and compare the hint table values with these during validation. We ignore | |
| 1301 | - // some values for various reasons described in the code. Those values are omitted from these | |
| 1302 | - // structures. Note also that object numbers are object numbers from the input file, not the | |
| 1303 | - // output file. | |
| 1304 | - | |
| 1305 | - // Naming convention: CHSomething is analogous to HSomething above. "CH" is computed hint. | |
| 1306 | - | |
| 1307 | - struct CHPageOffsetEntry | |
| 1308 | - { | |
| 1309 | - int nobjects{0}; | |
| 1310 | - int nshared_objects{0}; | |
| 1311 | - // vectors' sizes = nshared_objects | |
| 1312 | - std::vector<int> shared_identifiers; | |
| 1313 | - }; | |
| 1314 | - | |
| 1315 | - struct CHPageOffset | |
| 1316 | - { | |
| 1317 | - // vector size is npages | |
| 1318 | - std::vector<CHPageOffsetEntry> entries; | |
| 1319 | - }; | |
| 1320 | - | |
| 1321 | - struct CHSharedObjectEntry | |
| 1322 | - { | |
| 1323 | - CHSharedObjectEntry(int object) : | |
| 1324 | - object(object) | |
| 1325 | - { | |
| 1326 | - } | |
| 1327 | - | |
| 1328 | - int object; | |
| 1329 | - }; | |
| 1330 | - | |
| 1331 | - // PDF 1.4: Table F.5 | |
| 1332 | - struct CHSharedObject | |
| 1333 | - { | |
| 1334 | - int first_shared_obj{0}; | |
| 1335 | - int nshared_first_page{0}; | |
| 1336 | - int nshared_total{0}; | |
| 1337 | - // vector size is nshared_total | |
| 1338 | - std::vector<CHSharedObjectEntry> entries; | |
| 1339 | - }; | |
| 1340 | - | |
| 1341 | - // No need for CHGeneric -- HGeneric is fine as is. | |
| 1342 | - | |
| 1343 | - // Data structures to support optimization -- implemented in QPDF_optimization.cc | |
| 1344 | - | |
| 1345 | - class ObjUser | |
| 1346 | - { | |
| 1347 | - public: | |
| 1348 | - enum user_e { ou_bad, ou_page, ou_thumb, ou_trailer_key, ou_root_key, ou_root }; | |
| 1349 | - | |
| 1350 | - // type is set to ou_bad | |
| 1351 | - ObjUser(); | |
| 1352 | - | |
| 1353 | - // type must be ou_root | |
| 1354 | - ObjUser(user_e type); | |
| 1355 | - | |
| 1356 | - // type must be one of ou_page or ou_thumb | |
| 1357 | - ObjUser(user_e type, int pageno); | |
| 1358 | - | |
| 1359 | - // type must be one of ou_trailer_key or ou_root_key | |
| 1360 | - ObjUser(user_e type, std::string const& key); | |
| 1361 | - | |
| 1362 | - bool operator<(ObjUser const&) const; | |
| 1363 | - | |
| 1364 | - user_e ou_type; | |
| 1365 | - int pageno; // if ou_page; | |
| 1366 | - std::string key; // if ou_trailer_key or ou_root_key | |
| 1367 | - }; | |
| 1368 | - | |
| 1369 | - struct UpdateObjectMapsFrame | |
| 1370 | - { | |
| 1371 | - UpdateObjectMapsFrame(ObjUser const& ou, QPDFObjectHandle oh, bool top); | |
| 1372 | - | |
| 1373 | - ObjUser const& ou; | |
| 1374 | - QPDFObjectHandle oh; | |
| 1375 | - bool top; | |
| 1376 | - }; | |
| 1377 | - | |
| 1378 | - class PatternFinder: public InputSource::Finder | |
| 1379 | - { | |
| 1380 | - public: | |
| 1381 | - PatternFinder(QPDF& qpdf, bool (QPDF::*checker)()) : | |
| 1382 | - qpdf(qpdf), | |
| 1383 | - checker(checker) | |
| 1384 | - { | |
| 1385 | - } | |
| 1386 | - ~PatternFinder() override = default; | |
| 1387 | - bool | |
| 1388 | - check() override | |
| 1389 | - { | |
| 1390 | - return (this->qpdf.*checker)(); | |
| 1391 | - } | |
| 1392 | - | |
| 1393 | - private: | |
| 1394 | - QPDF& qpdf; | |
| 1395 | - bool (QPDF::*checker)(); | |
| 1396 | - }; | |
| 927 | + struct HPageOffsetEntry; | |
| 928 | + struct HPageOffset; | |
| 929 | + struct HSharedObjectEntry; | |
| 930 | + struct HSharedObject; | |
| 931 | + struct HGeneric; | |
| 932 | + struct LinParameters; | |
| 933 | + struct CHPageOffsetEntry; | |
| 934 | + struct CHPageOffset; | |
| 935 | + struct CHSharedObjectEntry; | |
| 936 | + struct CHSharedObject; | |
| 937 | + class ObjUser; | |
| 938 | + struct UpdateObjectMapsFrame; | |
| 939 | + class PatternFinder; | |
| 1397 | 940 | |
| 1398 | 941 | // Methods to support pattern finding |
| 1399 | 942 | static bool validatePDFVersion(char const*&, std::string& version); |
| ... | ... | @@ -1490,88 +1033,7 @@ class QPDF |
| 1490 | 1033 | return QIntC::to_ulonglong(i); |
| 1491 | 1034 | } |
| 1492 | 1035 | |
| 1493 | - class Members | |
| 1494 | - { | |
| 1495 | - friend class QPDF; | |
| 1496 | - friend class ResolveRecorder; | |
| 1497 | - | |
| 1498 | - public: | |
| 1499 | - Members(); | |
| 1500 | - Members(Members const&) = delete; | |
| 1501 | - ~Members() = default; | |
| 1502 | - | |
| 1503 | - private: | |
| 1504 | - std::shared_ptr<QPDFLogger> log; | |
| 1505 | - unsigned long long unique_id{0}; | |
| 1506 | - QPDFTokenizer tokenizer; | |
| 1507 | - std::shared_ptr<InputSource> file; | |
| 1508 | - std::string last_object_description; | |
| 1509 | - bool provided_password_is_hex_key{false}; | |
| 1510 | - bool ignore_xref_streams{false}; | |
| 1511 | - bool suppress_warnings{false}; | |
| 1512 | - size_t max_warnings{0}; | |
| 1513 | - bool attempt_recovery{true}; | |
| 1514 | - bool check_mode{false}; | |
| 1515 | - std::shared_ptr<EncryptionParameters> encp; | |
| 1516 | - std::string pdf_version; | |
| 1517 | - std::map<QPDFObjGen, QPDFXRefEntry> xref_table; | |
| 1518 | - // Various tables are indexed by object id, with potential size id + 1 | |
| 1519 | - int xref_table_max_id{std::numeric_limits<int>::max() - 1}; | |
| 1520 | - qpdf_offset_t xref_table_max_offset{0}; | |
| 1521 | - std::set<int> deleted_objects; | |
| 1522 | - std::map<QPDFObjGen, ObjCache> obj_cache; | |
| 1523 | - std::set<QPDFObjGen> resolving; | |
| 1524 | - QPDFObjectHandle trailer; | |
| 1525 | - std::vector<QPDFObjectHandle> all_pages; | |
| 1526 | - bool invalid_page_found{false}; | |
| 1527 | - std::map<QPDFObjGen, int> pageobj_to_pages_pos; | |
| 1528 | - bool pushed_inherited_attributes_to_pages{false}; | |
| 1529 | - bool ever_pushed_inherited_attributes_to_pages{false}; | |
| 1530 | - bool ever_called_get_all_pages{false}; | |
| 1531 | - std::vector<QPDFExc> warnings; | |
| 1532 | - std::map<unsigned long long, ObjCopier> object_copiers; | |
| 1533 | - std::shared_ptr<QPDFObjectHandle::StreamDataProvider> copied_streams; | |
| 1534 | - // copied_stream_data_provider is owned by copied_streams | |
| 1535 | - CopiedStreamDataProvider* copied_stream_data_provider{nullptr}; | |
| 1536 | - bool reconstructed_xref{false}; | |
| 1537 | - bool fixed_dangling_refs{false}; | |
| 1538 | - bool immediate_copy_from{false}; | |
| 1539 | - bool in_parse{false}; | |
| 1540 | - bool parsed{false}; | |
| 1541 | - std::set<int> resolved_object_streams; | |
| 1542 | - | |
| 1543 | - // Linearization data | |
| 1544 | - qpdf_offset_t first_xref_item_offset{0}; // actual value from file | |
| 1545 | - bool uncompressed_after_compressed{false}; | |
| 1546 | - bool linearization_warnings{false}; | |
| 1547 | - | |
| 1548 | - // Linearization parameter dictionary and hint table data: may be read from file or computed | |
| 1549 | - // prior to writing a linearized file | |
| 1550 | - QPDFObjectHandle lindict; | |
| 1551 | - LinParameters linp; | |
| 1552 | - HPageOffset page_offset_hints; | |
| 1553 | - HSharedObject shared_object_hints; | |
| 1554 | - HGeneric outline_hints; | |
| 1555 | - | |
| 1556 | - // Computed linearization data: used to populate above tables during writing and to compare | |
| 1557 | - // with them during validation. c_ means computed. | |
| 1558 | - LinParameters c_linp; | |
| 1559 | - CHPageOffset c_page_offset_data; | |
| 1560 | - CHSharedObject c_shared_object_data; | |
| 1561 | - HGeneric c_outline_data; | |
| 1562 | - | |
| 1563 | - // Object ordering data for linearized files: initialized by calculateLinearizationData(). | |
| 1564 | - // Part numbers refer to the PDF 1.4 specification. | |
| 1565 | - std::vector<QPDFObjectHandle> part4; | |
| 1566 | - std::vector<QPDFObjectHandle> part6; | |
| 1567 | - std::vector<QPDFObjectHandle> part7; | |
| 1568 | - std::vector<QPDFObjectHandle> part8; | |
| 1569 | - std::vector<QPDFObjectHandle> part9; | |
| 1570 | - | |
| 1571 | - // Optimization data | |
| 1572 | - std::map<ObjUser, std::set<QPDFObjGen>> obj_user_to_objects; | |
| 1573 | - std::map<QPDFObjGen, std::set<ObjUser>> object_to_obj_users; | |
| 1574 | - }; | |
| 1036 | + class Members; | |
| 1575 | 1037 | |
| 1576 | 1038 | // Keep all member variables inside the Members object, which we dynamically allocate. This |
| 1577 | 1039 | // makes it possible to add new private members without breaking binary compatibility. | ... | ... |
libqpdf/QPDF.cc
libqpdf/QPDFJob.cc
| ... | ... | @@ -13,7 +13,6 @@ |
| 13 | 13 | #include <qpdf/Pl_StdioFile.hh> |
| 14 | 14 | #include <qpdf/Pl_String.hh> |
| 15 | 15 | #include <qpdf/QIntC.hh> |
| 16 | -#include <qpdf/QPDF.hh> | |
| 17 | 16 | #include <qpdf/QPDFAcroFormDocumentHelper.hh> |
| 18 | 17 | #include <qpdf/QPDFCryptoProvider.hh> |
| 19 | 18 | #include <qpdf/QPDFEmbeddedFileDocumentHelper.hh> |
| ... | ... | @@ -27,6 +26,7 @@ |
| 27 | 26 | #include <qpdf/QPDFSystemError.hh> |
| 28 | 27 | #include <qpdf/QPDFUsage.hh> |
| 29 | 28 | #include <qpdf/QPDFWriter.hh> |
| 29 | +#include <qpdf/QPDF_private.hh> | |
| 30 | 30 | #include <qpdf/QTC.hh> |
| 31 | 31 | #include <qpdf/QUtil.hh> |
| 32 | 32 | #include <qpdf/Util.hh> | ... | ... |
libqpdf/QPDFWriter.cc
| ... | ... | @@ -14,9 +14,9 @@ |
| 14 | 14 | #include <qpdf/Pl_RC4.hh> |
| 15 | 15 | #include <qpdf/Pl_StdioFile.hh> |
| 16 | 16 | #include <qpdf/QIntC.hh> |
| 17 | -#include <qpdf/QPDF.hh> | |
| 18 | 17 | #include <qpdf/QPDFObjectHandle_private.hh> |
| 19 | 18 | #include <qpdf/QPDFObject_private.hh> |
| 19 | +#include <qpdf/QPDF_private.hh> | |
| 20 | 20 | #include <qpdf/QTC.hh> |
| 21 | 21 | #include <qpdf/QUtil.hh> |
| 22 | 22 | #include <qpdf/RC4.hh> | ... | ... |
libqpdf/QPDF_Stream.cc
| ... | ... | @@ -10,8 +10,8 @@ |
| 10 | 10 | #include <qpdf/Pl_Flate.hh> |
| 11 | 11 | #include <qpdf/Pl_QPDFTokenizer.hh> |
| 12 | 12 | #include <qpdf/QIntC.hh> |
| 13 | -#include <qpdf/QPDF.hh> | |
| 14 | 13 | #include <qpdf/QPDFExc.hh> |
| 14 | +#include <qpdf/QPDF_private.hh> | |
| 15 | 15 | #include <qpdf/QTC.hh> |
| 16 | 16 | #include <qpdf/QUtil.hh> |
| 17 | 17 | #include <qpdf/SF_ASCII85Decode.hh> | ... | ... |
libqpdf/QPDF_encryption.cc
libqpdf/QPDF_linearization.cc
libqpdf/QPDF_optimization.cc
libqpdf/QPDF_pages.cc
libqpdf/qpdf/QPDFObject_private.hh
libqpdf/qpdf/QPDF_private.hh
0 โ 100644
| 1 | +#ifndef QPDF_PRIVATE_HH | |
| 2 | +#define QPDF_PRIVATE_HH | |
| 3 | + | |
| 4 | +#include <qpdf/QPDF.hh> | |
| 5 | + | |
| 6 | +// Writer class is restricted to QPDFWriter so that only it can call certain methods. | |
| 7 | +class QPDF::Writer | |
| 8 | +{ | |
| 9 | + friend class QPDFWriter; | |
| 10 | + | |
| 11 | + private: | |
| 12 | + static void | |
| 13 | + optimize( | |
| 14 | + QPDF& qpdf, | |
| 15 | + QPDFWriter::ObjTable const& obj, | |
| 16 | + std::function<int(QPDFObjectHandle&)> skip_stream_parameters) | |
| 17 | + { | |
| 18 | + return qpdf.optimize(obj, skip_stream_parameters); | |
| 19 | + } | |
| 20 | + | |
| 21 | + static void | |
| 22 | + getLinearizedParts( | |
| 23 | + QPDF& qpdf, | |
| 24 | + QPDFWriter::ObjTable const& obj, | |
| 25 | + std::vector<QPDFObjectHandle>& part4, | |
| 26 | + std::vector<QPDFObjectHandle>& part6, | |
| 27 | + std::vector<QPDFObjectHandle>& part7, | |
| 28 | + std::vector<QPDFObjectHandle>& part8, | |
| 29 | + std::vector<QPDFObjectHandle>& part9) | |
| 30 | + { | |
| 31 | + qpdf.getLinearizedParts(obj, part4, part6, part7, part8, part9); | |
| 32 | + } | |
| 33 | + | |
| 34 | + static void | |
| 35 | + generateHintStream( | |
| 36 | + QPDF& qpdf, | |
| 37 | + QPDFWriter::NewObjTable const& new_obj, | |
| 38 | + QPDFWriter::ObjTable const& obj, | |
| 39 | + std::shared_ptr<Buffer>& hint_stream, | |
| 40 | + int& S, | |
| 41 | + int& O, | |
| 42 | + bool compressed) | |
| 43 | + { | |
| 44 | + return qpdf.generateHintStream(new_obj, obj, hint_stream, S, O, compressed); | |
| 45 | + } | |
| 46 | + | |
| 47 | + static std::vector<QPDFObjGen> | |
| 48 | + getCompressibleObjGens(QPDF& qpdf) | |
| 49 | + { | |
| 50 | + return qpdf.getCompressibleObjVector(); | |
| 51 | + } | |
| 52 | + | |
| 53 | + static std::vector<bool> | |
| 54 | + getCompressibleObjSet(QPDF& qpdf) | |
| 55 | + { | |
| 56 | + return qpdf.getCompressibleObjSet(); | |
| 57 | + } | |
| 58 | + | |
| 59 | + static std::map<QPDFObjGen, QPDFXRefEntry> const& | |
| 60 | + getXRefTable(QPDF& qpdf) | |
| 61 | + { | |
| 62 | + return qpdf.getXRefTableInternal(); | |
| 63 | + } | |
| 64 | + | |
| 65 | + static size_t | |
| 66 | + tableSize(QPDF& qpdf) | |
| 67 | + { | |
| 68 | + return qpdf.tableSize(); | |
| 69 | + } | |
| 70 | +}; | |
| 71 | + | |
| 72 | +// The Resolver class is restricted to QPDFObject so that only it can resolve indirect | |
| 73 | +// references. | |
| 74 | +class QPDF::Resolver | |
| 75 | +{ | |
| 76 | + friend class QPDFObject; | |
| 77 | + friend class qpdf::BaseHandle; | |
| 78 | + | |
| 79 | + private: | |
| 80 | + static std::shared_ptr<QPDFObject> const& | |
| 81 | + resolved(QPDF* qpdf, QPDFObjGen og) | |
| 82 | + { | |
| 83 | + return qpdf->resolve(og); | |
| 84 | + } | |
| 85 | +}; | |
| 86 | + | |
| 87 | +// StreamCopier class is restricted to QPDFObjectHandle so it can copy stream data. | |
| 88 | +class QPDF::StreamCopier | |
| 89 | +{ | |
| 90 | + friend class QPDFObjectHandle; | |
| 91 | + | |
| 92 | + private: | |
| 93 | + static void | |
| 94 | + copyStreamData(QPDF* qpdf, QPDFObjectHandle const& dest, QPDFObjectHandle const& src) | |
| 95 | + { | |
| 96 | + qpdf->copyStreamData(dest, src); | |
| 97 | + } | |
| 98 | +}; | |
| 99 | + | |
| 100 | +// The ParseGuard class allows QPDFParser to detect re-entrant parsing. It also provides | |
| 101 | +// special access to allow the parser to create unresolved objects and dangling references. | |
| 102 | +class QPDF::ParseGuard | |
| 103 | +{ | |
| 104 | + friend class QPDFParser; | |
| 105 | + | |
| 106 | + private: | |
| 107 | + ParseGuard(QPDF* qpdf) : | |
| 108 | + qpdf(qpdf) | |
| 109 | + { | |
| 110 | + if (qpdf) { | |
| 111 | + qpdf->inParse(true); | |
| 112 | + } | |
| 113 | + } | |
| 114 | + | |
| 115 | + static std::shared_ptr<QPDFObject> | |
| 116 | + getObject(QPDF* qpdf, int id, int gen, bool parse_pdf) | |
| 117 | + { | |
| 118 | + return qpdf->getObjectForParser(id, gen, parse_pdf); | |
| 119 | + } | |
| 120 | + | |
| 121 | + ~ParseGuard() | |
| 122 | + { | |
| 123 | + if (qpdf) { | |
| 124 | + qpdf->inParse(false); | |
| 125 | + } | |
| 126 | + } | |
| 127 | + QPDF* qpdf; | |
| 128 | +}; | |
| 129 | + | |
| 130 | +// Pipe class is restricted to QPDF_Stream. | |
| 131 | +class QPDF::Pipe | |
| 132 | +{ | |
| 133 | + friend class qpdf::Stream; | |
| 134 | + | |
| 135 | + private: | |
| 136 | + static bool | |
| 137 | + pipeStreamData( | |
| 138 | + QPDF* qpdf, | |
| 139 | + QPDFObjGen og, | |
| 140 | + qpdf_offset_t offset, | |
| 141 | + size_t length, | |
| 142 | + QPDFObjectHandle dict, | |
| 143 | + Pipeline* pipeline, | |
| 144 | + bool suppress_warnings, | |
| 145 | + bool will_retry) | |
| 146 | + { | |
| 147 | + return qpdf->pipeStreamData( | |
| 148 | + og, offset, length, dict, pipeline, suppress_warnings, will_retry); | |
| 149 | + } | |
| 150 | +}; | |
| 151 | + | |
| 152 | +class QPDF::ObjCache | |
| 153 | +{ | |
| 154 | + public: | |
| 155 | + ObjCache() : | |
| 156 | + end_before_space(0), | |
| 157 | + end_after_space(0) | |
| 158 | + { | |
| 159 | + } | |
| 160 | + ObjCache( | |
| 161 | + std::shared_ptr<QPDFObject> object, | |
| 162 | + qpdf_offset_t end_before_space = 0, | |
| 163 | + qpdf_offset_t end_after_space = 0) : | |
| 164 | + object(object), | |
| 165 | + end_before_space(end_before_space), | |
| 166 | + end_after_space(end_after_space) | |
| 167 | + { | |
| 168 | + } | |
| 169 | + | |
| 170 | + std::shared_ptr<QPDFObject> object; | |
| 171 | + qpdf_offset_t end_before_space; | |
| 172 | + qpdf_offset_t end_after_space; | |
| 173 | +}; | |
| 174 | + | |
| 175 | +class QPDF::ObjCopier | |
| 176 | +{ | |
| 177 | + public: | |
| 178 | + std::map<QPDFObjGen, QPDFObjectHandle> object_map; | |
| 179 | + std::vector<QPDFObjectHandle> to_copy; | |
| 180 | + QPDFObjGen::set visiting; | |
| 181 | +}; | |
| 182 | + | |
| 183 | +class QPDF::EncryptionParameters | |
| 184 | +{ | |
| 185 | + friend class QPDF; | |
| 186 | + | |
| 187 | + public: | |
| 188 | + EncryptionParameters(); | |
| 189 | + | |
| 190 | + private: | |
| 191 | + bool encrypted; | |
| 192 | + bool encryption_initialized; | |
| 193 | + int encryption_V; | |
| 194 | + int encryption_R; | |
| 195 | + bool encrypt_metadata; | |
| 196 | + std::map<std::string, encryption_method_e> crypt_filters; | |
| 197 | + encryption_method_e cf_stream; | |
| 198 | + encryption_method_e cf_string; | |
| 199 | + encryption_method_e cf_file; | |
| 200 | + std::string provided_password; | |
| 201 | + std::string user_password; | |
| 202 | + std::string encryption_key; | |
| 203 | + std::string cached_object_encryption_key; | |
| 204 | + QPDFObjGen cached_key_og; | |
| 205 | + bool user_password_matched; | |
| 206 | + bool owner_password_matched; | |
| 207 | +}; | |
| 208 | + | |
| 209 | +class QPDF::ForeignStreamData | |
| 210 | +{ | |
| 211 | + friend class QPDF; | |
| 212 | + | |
| 213 | + public: | |
| 214 | + ForeignStreamData( | |
| 215 | + std::shared_ptr<EncryptionParameters> encp, | |
| 216 | + std::shared_ptr<InputSource> file, | |
| 217 | + QPDFObjGen foreign_og, | |
| 218 | + qpdf_offset_t offset, | |
| 219 | + size_t length, | |
| 220 | + QPDFObjectHandle local_dict); | |
| 221 | + | |
| 222 | + private: | |
| 223 | + std::shared_ptr<EncryptionParameters> encp; | |
| 224 | + std::shared_ptr<InputSource> file; | |
| 225 | + QPDFObjGen foreign_og; | |
| 226 | + qpdf_offset_t offset; | |
| 227 | + size_t length; | |
| 228 | + QPDFObjectHandle local_dict; | |
| 229 | +}; | |
| 230 | + | |
| 231 | +class QPDF::CopiedStreamDataProvider: public QPDFObjectHandle::StreamDataProvider | |
| 232 | +{ | |
| 233 | + public: | |
| 234 | + CopiedStreamDataProvider(QPDF& destination_qpdf); | |
| 235 | + ~CopiedStreamDataProvider() override = default; | |
| 236 | + bool provideStreamData( | |
| 237 | + QPDFObjGen const& og, Pipeline* pipeline, bool suppress_warnings, bool will_retry) override; | |
| 238 | + void registerForeignStream(QPDFObjGen const& local_og, QPDFObjectHandle foreign_stream); | |
| 239 | + void registerForeignStream(QPDFObjGen const& local_og, std::shared_ptr<ForeignStreamData>); | |
| 240 | + | |
| 241 | + private: | |
| 242 | + QPDF& destination_qpdf; | |
| 243 | + std::map<QPDFObjGen, QPDFObjectHandle> foreign_streams; | |
| 244 | + std::map<QPDFObjGen, std::shared_ptr<ForeignStreamData>> foreign_stream_data; | |
| 245 | +}; | |
| 246 | + | |
| 247 | +class QPDF::StringDecrypter: public QPDFObjectHandle::StringDecrypter | |
| 248 | +{ | |
| 249 | + friend class QPDF; | |
| 250 | + | |
| 251 | + public: | |
| 252 | + StringDecrypter(QPDF* qpdf, QPDFObjGen og); | |
| 253 | + ~StringDecrypter() override = default; | |
| 254 | + void decryptString(std::string& val) override; | |
| 255 | + | |
| 256 | + private: | |
| 257 | + QPDF* qpdf; | |
| 258 | + QPDFObjGen og; | |
| 259 | +}; | |
| 260 | + | |
| 261 | +// PDF 1.4: Table F.4 | |
| 262 | +struct QPDF::HPageOffsetEntry | |
| 263 | +{ | |
| 264 | + int delta_nobjects{0}; // 1 | |
| 265 | + qpdf_offset_t delta_page_length{0}; // 2 | |
| 266 | + // vectors' sizes = nshared_objects | |
| 267 | + int nshared_objects{0}; // 3 | |
| 268 | + std::vector<int> shared_identifiers; // 4 | |
| 269 | + std::vector<int> shared_numerators; // 5 | |
| 270 | + qpdf_offset_t delta_content_offset{0}; // 6 | |
| 271 | + qpdf_offset_t delta_content_length{0}; // 7 | |
| 272 | +}; | |
| 273 | + | |
| 274 | +// PDF 1.4: Table F.3 | |
| 275 | +struct QPDF::HPageOffset | |
| 276 | +{ | |
| 277 | + int min_nobjects{0}; // 1 | |
| 278 | + qpdf_offset_t first_page_offset{0}; // 2 | |
| 279 | + int nbits_delta_nobjects{0}; // 3 | |
| 280 | + int min_page_length{0}; // 4 | |
| 281 | + int nbits_delta_page_length{0}; // 5 | |
| 282 | + int min_content_offset{0}; // 6 | |
| 283 | + int nbits_delta_content_offset{0}; // 7 | |
| 284 | + int min_content_length{0}; // 8 | |
| 285 | + int nbits_delta_content_length{0}; // 9 | |
| 286 | + int nbits_nshared_objects{0}; // 10 | |
| 287 | + int nbits_shared_identifier{0}; // 11 | |
| 288 | + int nbits_shared_numerator{0}; // 12 | |
| 289 | + int shared_denominator{0}; // 13 | |
| 290 | + // vector size is npages | |
| 291 | + std::vector<HPageOffsetEntry> entries; | |
| 292 | +}; | |
| 293 | + | |
| 294 | +// PDF 1.4: Table F.6 | |
| 295 | +struct QPDF::HSharedObjectEntry | |
| 296 | +{ | |
| 297 | + // Item 3 is a 128-bit signature (unsupported by Acrobat) | |
| 298 | + int delta_group_length{0}; // 1 | |
| 299 | + int signature_present{0}; // 2 -- always 0 | |
| 300 | + int nobjects_minus_one{0}; // 4 -- always 0 | |
| 301 | +}; | |
| 302 | + | |
| 303 | +// PDF 1.4: Table F.5 | |
| 304 | +struct QPDF::HSharedObject | |
| 305 | +{ | |
| 306 | + int first_shared_obj{0}; // 1 | |
| 307 | + qpdf_offset_t first_shared_offset{0}; // 2 | |
| 308 | + int nshared_first_page{0}; // 3 | |
| 309 | + int nshared_total{0}; // 4 | |
| 310 | + int nbits_nobjects{0}; // 5 | |
| 311 | + int min_group_length{0}; // 6 | |
| 312 | + int nbits_delta_group_length{0}; // 7 | |
| 313 | + // vector size is nshared_total | |
| 314 | + std::vector<HSharedObjectEntry> entries; | |
| 315 | +}; | |
| 316 | + | |
| 317 | +// PDF 1.4: Table F.9 | |
| 318 | +struct QPDF::HGeneric | |
| 319 | +{ | |
| 320 | + int first_object{0}; // 1 | |
| 321 | + qpdf_offset_t first_object_offset{0}; // 2 | |
| 322 | + int nobjects{0}; // 3 | |
| 323 | + int group_length{0}; // 4 | |
| 324 | +}; | |
| 325 | + | |
| 326 | +// Other linearization data structures | |
| 327 | + | |
| 328 | +// Initialized from Linearization Parameter dictionary | |
| 329 | +struct QPDF::LinParameters | |
| 330 | +{ | |
| 331 | + qpdf_offset_t file_size{0}; // /L | |
| 332 | + int first_page_object{0}; // /O | |
| 333 | + qpdf_offset_t first_page_end{0}; // /E | |
| 334 | + int npages{0}; // /N | |
| 335 | + qpdf_offset_t xref_zero_offset{0}; // /T | |
| 336 | + int first_page{0}; // /P | |
| 337 | + qpdf_offset_t H_offset{0}; // offset of primary hint stream | |
| 338 | + qpdf_offset_t H_length{0}; // length of primary hint stream | |
| 339 | +}; | |
| 340 | + | |
| 341 | +// Computed hint table value data structures. These tables contain the computed values on which | |
| 342 | +// the hint table values are based. They exclude things like number of bits and store actual | |
| 343 | +// values instead of mins and deltas. File offsets are also absolute rather than being offset | |
| 344 | +// by the size of the primary hint table. We populate the hint table structures from these | |
| 345 | +// during writing and compare the hint table values with these during validation. We ignore | |
| 346 | +// some values for various reasons described in the code. Those values are omitted from these | |
| 347 | +// structures. Note also that object numbers are object numbers from the input file, not the | |
| 348 | +// output file. | |
| 349 | + | |
| 350 | +// Naming convention: CHSomething is analogous to HSomething above. "CH" is computed hint. | |
| 351 | + | |
| 352 | +struct QPDF::CHPageOffsetEntry | |
| 353 | +{ | |
| 354 | + int nobjects{0}; | |
| 355 | + int nshared_objects{0}; | |
| 356 | + // vectors' sizes = nshared_objects | |
| 357 | + std::vector<int> shared_identifiers; | |
| 358 | +}; | |
| 359 | + | |
| 360 | +struct QPDF::CHPageOffset | |
| 361 | +{ | |
| 362 | + // vector size is npages | |
| 363 | + std::vector<CHPageOffsetEntry> entries; | |
| 364 | +}; | |
| 365 | + | |
| 366 | +struct QPDF::CHSharedObjectEntry | |
| 367 | +{ | |
| 368 | + CHSharedObjectEntry(int object) : | |
| 369 | + object(object) | |
| 370 | + { | |
| 371 | + } | |
| 372 | + | |
| 373 | + int object; | |
| 374 | +}; | |
| 375 | + | |
| 376 | +// PDF 1.4: Table F.5 | |
| 377 | +struct QPDF::CHSharedObject | |
| 378 | +{ | |
| 379 | + int first_shared_obj{0}; | |
| 380 | + int nshared_first_page{0}; | |
| 381 | + int nshared_total{0}; | |
| 382 | + // vector size is nshared_total | |
| 383 | + std::vector<CHSharedObjectEntry> entries; | |
| 384 | +}; | |
| 385 | + | |
| 386 | +// No need for CHGeneric -- HGeneric is fine as is. | |
| 387 | + | |
| 388 | +// Data structures to support optimization -- implemented in QPDF_optimization.cc | |
| 389 | + | |
| 390 | +class QPDF::ObjUser | |
| 391 | +{ | |
| 392 | + public: | |
| 393 | + enum user_e { ou_bad, ou_page, ou_thumb, ou_trailer_key, ou_root_key, ou_root }; | |
| 394 | + | |
| 395 | + // type is set to ou_bad | |
| 396 | + ObjUser(); | |
| 397 | + | |
| 398 | + // type must be ou_root | |
| 399 | + ObjUser(user_e type); | |
| 400 | + | |
| 401 | + // type must be one of ou_page or ou_thumb | |
| 402 | + ObjUser(user_e type, int pageno); | |
| 403 | + | |
| 404 | + // type must be one of ou_trailer_key or ou_root_key | |
| 405 | + ObjUser(user_e type, std::string const& key); | |
| 406 | + | |
| 407 | + bool operator<(ObjUser const&) const; | |
| 408 | + | |
| 409 | + user_e ou_type; | |
| 410 | + int pageno; // if ou_page; | |
| 411 | + std::string key; // if ou_trailer_key or ou_root_key | |
| 412 | +}; | |
| 413 | + | |
| 414 | +struct QPDF::UpdateObjectMapsFrame | |
| 415 | +{ | |
| 416 | + UpdateObjectMapsFrame(ObjUser const& ou, QPDFObjectHandle oh, bool top); | |
| 417 | + | |
| 418 | + ObjUser const& ou; | |
| 419 | + QPDFObjectHandle oh; | |
| 420 | + bool top; | |
| 421 | +}; | |
| 422 | + | |
| 423 | +class QPDF::PatternFinder: public InputSource::Finder | |
| 424 | +{ | |
| 425 | + public: | |
| 426 | + PatternFinder(QPDF& qpdf, bool (QPDF::*checker)()) : | |
| 427 | + qpdf(qpdf), | |
| 428 | + checker(checker) | |
| 429 | + { | |
| 430 | + } | |
| 431 | + ~PatternFinder() override = default; | |
| 432 | + bool | |
| 433 | + check() override | |
| 434 | + { | |
| 435 | + return (this->qpdf.*checker)(); | |
| 436 | + } | |
| 437 | + | |
| 438 | + private: | |
| 439 | + QPDF& qpdf; | |
| 440 | + bool (QPDF::*checker)(); | |
| 441 | +}; | |
| 442 | + | |
| 443 | +class QPDF::Members | |
| 444 | +{ | |
| 445 | + friend class QPDF; | |
| 446 | + friend class ResolveRecorder; | |
| 447 | + | |
| 448 | + public: | |
| 449 | + Members(); | |
| 450 | + Members(Members const&) = delete; | |
| 451 | + ~Members() = default; | |
| 452 | + | |
| 453 | + private: | |
| 454 | + std::shared_ptr<QPDFLogger> log; | |
| 455 | + unsigned long long unique_id{0}; | |
| 456 | + QPDFTokenizer tokenizer; | |
| 457 | + std::shared_ptr<InputSource> file; | |
| 458 | + std::string last_object_description; | |
| 459 | + bool provided_password_is_hex_key{false}; | |
| 460 | + bool ignore_xref_streams{false}; | |
| 461 | + bool suppress_warnings{false}; | |
| 462 | + size_t max_warnings{0}; | |
| 463 | + bool attempt_recovery{true}; | |
| 464 | + bool check_mode{false}; | |
| 465 | + std::shared_ptr<EncryptionParameters> encp; | |
| 466 | + std::string pdf_version; | |
| 467 | + std::map<QPDFObjGen, QPDFXRefEntry> xref_table; | |
| 468 | + // Various tables are indexed by object id, with potential size id + 1 | |
| 469 | + int xref_table_max_id{std::numeric_limits<int>::max() - 1}; | |
| 470 | + qpdf_offset_t xref_table_max_offset{0}; | |
| 471 | + std::set<int> deleted_objects; | |
| 472 | + std::map<QPDFObjGen, ObjCache> obj_cache; | |
| 473 | + std::set<QPDFObjGen> resolving; | |
| 474 | + QPDFObjectHandle trailer; | |
| 475 | + std::vector<QPDFObjectHandle> all_pages; | |
| 476 | + bool invalid_page_found{false}; | |
| 477 | + std::map<QPDFObjGen, int> pageobj_to_pages_pos; | |
| 478 | + bool pushed_inherited_attributes_to_pages{false}; | |
| 479 | + bool ever_pushed_inherited_attributes_to_pages{false}; | |
| 480 | + bool ever_called_get_all_pages{false}; | |
| 481 | + std::vector<QPDFExc> warnings; | |
| 482 | + std::map<unsigned long long, ObjCopier> object_copiers; | |
| 483 | + std::shared_ptr<QPDFObjectHandle::StreamDataProvider> copied_streams; | |
| 484 | + // copied_stream_data_provider is owned by copied_streams | |
| 485 | + CopiedStreamDataProvider* copied_stream_data_provider{nullptr}; | |
| 486 | + bool reconstructed_xref{false}; | |
| 487 | + bool fixed_dangling_refs{false}; | |
| 488 | + bool immediate_copy_from{false}; | |
| 489 | + bool in_parse{false}; | |
| 490 | + bool parsed{false}; | |
| 491 | + std::set<int> resolved_object_streams; | |
| 492 | + | |
| 493 | + // Linearization data | |
| 494 | + qpdf_offset_t first_xref_item_offset{0}; // actual value from file | |
| 495 | + bool uncompressed_after_compressed{false}; | |
| 496 | + bool linearization_warnings{false}; | |
| 497 | + | |
| 498 | + // Linearization parameter dictionary and hint table data: may be read from file or computed | |
| 499 | + // prior to writing a linearized file | |
| 500 | + QPDFObjectHandle lindict; | |
| 501 | + LinParameters linp; | |
| 502 | + HPageOffset page_offset_hints; | |
| 503 | + HSharedObject shared_object_hints; | |
| 504 | + HGeneric outline_hints; | |
| 505 | + | |
| 506 | + // Computed linearization data: used to populate above tables during writing and to compare | |
| 507 | + // with them during validation. c_ means computed. | |
| 508 | + LinParameters c_linp; | |
| 509 | + CHPageOffset c_page_offset_data; | |
| 510 | + CHSharedObject c_shared_object_data; | |
| 511 | + HGeneric c_outline_data; | |
| 512 | + | |
| 513 | + // Object ordering data for linearized files: initialized by calculateLinearizationData(). | |
| 514 | + // Part numbers refer to the PDF 1.4 specification. | |
| 515 | + std::vector<QPDFObjectHandle> part4; | |
| 516 | + std::vector<QPDFObjectHandle> part6; | |
| 517 | + std::vector<QPDFObjectHandle> part7; | |
| 518 | + std::vector<QPDFObjectHandle> part8; | |
| 519 | + std::vector<QPDFObjectHandle> part9; | |
| 520 | + | |
| 521 | + // Optimization data | |
| 522 | + std::map<ObjUser, std::set<QPDFObjGen>> obj_user_to_objects; | |
| 523 | + std::map<QPDFObjGen, std::set<ObjUser>> object_to_obj_users; | |
| 524 | +}; | |
| 525 | + | |
| 526 | +// JobSetter class is restricted to QPDFJob. | |
| 527 | +class QPDF::JobSetter | |
| 528 | +{ | |
| 529 | + friend class QPDFJob; | |
| 530 | + | |
| 531 | + private: | |
| 532 | + // Enable enhanced warnings for pdf file checking. | |
| 533 | + static void | |
| 534 | + setCheckMode(QPDF& qpdf, bool val) | |
| 535 | + { | |
| 536 | + qpdf.m->check_mode = val; | |
| 537 | + } | |
| 538 | +}; | |
| 539 | + | |
| 540 | +class QPDF::ResolveRecorder | |
| 541 | +{ | |
| 542 | + public: | |
| 543 | + ResolveRecorder(QPDF* qpdf, QPDFObjGen const& og) : | |
| 544 | + qpdf(qpdf), | |
| 545 | + iter(qpdf->m->resolving.insert(og).first) | |
| 546 | + { | |
| 547 | + } | |
| 548 | + virtual ~ResolveRecorder() | |
| 549 | + { | |
| 550 | + this->qpdf->m->resolving.erase(iter); | |
| 551 | + } | |
| 552 | + | |
| 553 | + private: | |
| 554 | + QPDF* qpdf; | |
| 555 | + std::set<QPDFObjGen>::const_iterator iter; | |
| 556 | +}; | |
| 557 | + | |
| 558 | +#endif // QPDF_PRIVATE_HH | ... | ... |