#include #include #include #include #include #include #include #include #include #include #include #include struct _qpdf_error { PointerHolder exc; }; struct _qpdf_data { _qpdf_data(); ~_qpdf_data(); PointerHolder qpdf; PointerHolder qpdf_writer; PointerHolder error; _qpdf_error tmp_error; std::list warnings; std::string tmp_string; // Parameters for functions we call char const* filename; // or description char const* buffer; unsigned long long size; char const* password; bool write_memory; PointerHolder output_buffer; // QPDFObjectHandle support std::map> oh_cache; qpdf_oh next_oh; std::set cur_iter_dict_keys; std::set::const_iterator dict_iter; std::string cur_dict_key; }; _qpdf_data::_qpdf_data() : write_memory(false), next_oh(0) { } _qpdf_data::~_qpdf_data() { } class ProgressReporter: public QPDFWriter::ProgressReporter { public: ProgressReporter(void (*handler)(int, void*), void* data); virtual ~ProgressReporter() = default; virtual void reportProgress(int); private: void (*handler)(int, void*); void* data; }; ProgressReporter::ProgressReporter(void (*handler)(int, void*), void* data) : handler(handler), data(data) { } void ProgressReporter::reportProgress(int progress) { this->handler(progress, this->data); } // must set qpdf->filename and qpdf->password static void call_read(qpdf_data qpdf) { qpdf->qpdf->processFile(qpdf->filename, qpdf->password); } // must set qpdf->filename, qpdf->buffer, qpdf->size, and qpdf->password static void call_read_memory(qpdf_data qpdf) { qpdf->qpdf->processMemoryFile(qpdf->filename, qpdf->buffer, QIntC::to_size(qpdf->size), qpdf->password); } // must set qpdf->filename static void call_init_write(qpdf_data qpdf) { qpdf->qpdf_writer = new QPDFWriter(*(qpdf->qpdf), qpdf->filename); } static void call_init_write_memory(qpdf_data qpdf) { qpdf->qpdf_writer = new QPDFWriter(*(qpdf->qpdf)); qpdf->qpdf_writer->setOutputMemory(); } static void call_write(qpdf_data qpdf) { qpdf->qpdf_writer->write(); } static void call_check(qpdf_data qpdf) { QPDFWriter w(*qpdf->qpdf); Pl_Discard discard; w.setOutputPipeline(&discard); w.setDecodeLevel(qpdf_dl_all); w.write(); } static QPDF_ERROR_CODE trap_errors(qpdf_data qpdf, void (*fn)(qpdf_data)) { QPDF_ERROR_CODE status = QPDF_SUCCESS; try { fn(qpdf); } catch (QPDFExc& e) { qpdf->error = new QPDFExc(e); status |= QPDF_ERRORS; } catch (std::runtime_error& e) { qpdf->error = new QPDFExc(qpdf_e_system, "", "", 0, e.what()); status |= QPDF_ERRORS; } catch (std::exception& e) { qpdf->error = new QPDFExc(qpdf_e_internal, "", "", 0, e.what()); status |= QPDF_ERRORS; } if (qpdf_more_warnings(qpdf)) { status |= QPDF_WARNINGS; } return status; } char const* qpdf_get_qpdf_version() { QTC::TC("qpdf", "qpdf-c called qpdf_get_qpdf_version"); return QPDF::QPDFVersion().c_str(); } qpdf_data qpdf_init() { QTC::TC("qpdf", "qpdf-c called qpdf_init"); qpdf_data qpdf = new _qpdf_data(); qpdf->qpdf = new QPDF(); return qpdf; } void qpdf_cleanup(qpdf_data* qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_cleanup"); qpdf_oh_release_all(*qpdf); delete *qpdf; *qpdf = 0; } QPDF_BOOL qpdf_more_warnings(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_more_warnings"); if (qpdf->warnings.empty()) { std::vector w = qpdf->qpdf->getWarnings(); if (! w.empty()) { qpdf->warnings.assign(w.begin(), w.end()); } } if (qpdf->warnings.empty()) { return QPDF_FALSE; } else { return QPDF_TRUE; } } QPDF_BOOL qpdf_has_error(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_has_error"); return (qpdf->error.getPointer() ? QPDF_TRUE : QPDF_FALSE); } qpdf_error qpdf_get_error(qpdf_data qpdf) { if (qpdf->error.getPointer()) { qpdf->tmp_error.exc = qpdf->error; qpdf->error = 0; QTC::TC("qpdf", "qpdf-c qpdf_get_error returned error"); return &qpdf->tmp_error; } else { return 0; } } qpdf_error qpdf_next_warning(qpdf_data qpdf) { if (qpdf_more_warnings(qpdf)) { qpdf->tmp_error.exc = new QPDFExc(qpdf->warnings.front()); qpdf->warnings.pop_front(); QTC::TC("qpdf", "qpdf-c qpdf_next_warning returned warning"); return &qpdf->tmp_error; } else { return 0; } } char const* qpdf_get_error_full_text(qpdf_data qpdf, qpdf_error e) { if (e == 0) { return ""; } return e->exc->what(); } enum qpdf_error_code_e qpdf_get_error_code(qpdf_data qpdf, qpdf_error e) { if (e == 0) { return qpdf_e_success; } return e->exc->getErrorCode(); } char const* qpdf_get_error_filename(qpdf_data qpdf, qpdf_error e) { if (e == 0) { return ""; } return e->exc->getFilename().c_str(); } unsigned long long qpdf_get_error_file_position(qpdf_data qpdf, qpdf_error e) { if (e == 0) { return 0; } return QIntC::to_ulonglong(e->exc->getFilePosition()); } char const* qpdf_get_error_message_detail(qpdf_data qpdf, qpdf_error e) { if (e == 0) { return ""; } return e->exc->getMessageDetail().c_str(); } QPDF_ERROR_CODE qpdf_check_pdf(qpdf_data qpdf) { QPDF_ERROR_CODE status = trap_errors(qpdf, &call_check); QTC::TC("qpdf", "qpdf-c called qpdf_check_pdf"); return status; } void qpdf_set_suppress_warnings(qpdf_data qpdf, QPDF_BOOL value) { QTC::TC("qpdf", "qpdf-c called qpdf_set_suppress_warnings"); qpdf->qpdf->setSuppressWarnings(value != QPDF_FALSE); } void qpdf_set_ignore_xref_streams(qpdf_data qpdf, QPDF_BOOL value) { QTC::TC("qpdf", "qpdf-c called qpdf_set_ignore_xref_streams"); qpdf->qpdf->setIgnoreXRefStreams(value != QPDF_FALSE); } void qpdf_set_attempt_recovery(qpdf_data qpdf, QPDF_BOOL value) { QTC::TC("qpdf", "qpdf-c called qpdf_set_attempt_recovery"); qpdf->qpdf->setAttemptRecovery(value != QPDF_FALSE); } QPDF_ERROR_CODE qpdf_read(qpdf_data qpdf, char const* filename, char const* password) { QPDF_ERROR_CODE status = QPDF_SUCCESS; qpdf->filename = filename; qpdf->password = password; status = trap_errors(qpdf, &call_read); // We no longer have a good way to exercise a file with both // warnings and errors because qpdf is getting much better at // recovering. QTC::TC("qpdf", "qpdf-c called qpdf_read", (status == 0) ? 0 : (status & QPDF_WARNINGS) ? 1 : (status & QPDF_ERRORS) ? 2 : -1 ); return status; } QPDF_ERROR_CODE qpdf_read_memory(qpdf_data qpdf, char const* description, char const* buffer, unsigned long long size, char const* password) { QPDF_ERROR_CODE status = QPDF_SUCCESS; qpdf->filename = description; qpdf->buffer = buffer; qpdf->size = size; qpdf->password = password; status = trap_errors(qpdf, &call_read_memory); QTC::TC("qpdf", "qpdf-c called qpdf_read_memory", status); return status; } char const* qpdf_get_pdf_version(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_get_pdf_version"); qpdf->tmp_string = qpdf->qpdf->getPDFVersion(); return qpdf->tmp_string.c_str(); } int qpdf_get_pdf_extension_level(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_get_pdf_extension_level"); return qpdf->qpdf->getExtensionLevel(); } char const* qpdf_get_user_password(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_get_user_password"); qpdf->tmp_string = qpdf->qpdf->getTrimmedUserPassword(); return qpdf->tmp_string.c_str(); } char const* qpdf_get_info_key(qpdf_data qpdf, char const* key) { char const* result = 0; QPDFObjectHandle trailer = qpdf->qpdf->getTrailer(); if (trailer.hasKey("/Info")) { QPDFObjectHandle info = trailer.getKey("/Info"); if (info.hasKey(key)) { QPDFObjectHandle value = info.getKey(key); if (value.isString()) { qpdf->tmp_string = value.getStringValue(); result = qpdf->tmp_string.c_str(); } } } QTC::TC("qpdf", "qpdf-c get_info_key", (result == 0 ? 0 : 1)); return result; } void qpdf_set_info_key(qpdf_data qpdf, char const* key, char const* value) { if ((key == 0) || (std::strlen(key) == 0) || (key[0] != '/')) { return; } QPDFObjectHandle value_object; if (value) { QTC::TC("qpdf", "qpdf-c set_info_key to value"); value_object = QPDFObjectHandle::newString(value); } else { QTC::TC("qpdf", "qpdf-c set_info_key to null"); value_object = QPDFObjectHandle::newNull(); } QPDFObjectHandle trailer = qpdf->qpdf->getTrailer(); if (! trailer.hasKey("/Info")) { QTC::TC("qpdf", "qpdf-c add info to trailer"); trailer.replaceKey( "/Info", qpdf->qpdf->makeIndirectObject(QPDFObjectHandle::newDictionary())); } else { QTC::TC("qpdf", "qpdf-c set-info-key use existing info"); } QPDFObjectHandle info = trailer.getKey("/Info"); info.replaceOrRemoveKey(key, value_object); } QPDF_BOOL qpdf_is_linearized(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_is_linearized"); return (qpdf->qpdf->isLinearized() ? QPDF_TRUE : QPDF_FALSE); } QPDF_BOOL qpdf_is_encrypted(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_is_encrypted"); return (qpdf->qpdf->isEncrypted() ? QPDF_TRUE : QPDF_FALSE); } QPDF_BOOL qpdf_allow_accessibility(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_allow_accessibility"); return (qpdf->qpdf->allowAccessibility() ? QPDF_TRUE : QPDF_FALSE); } QPDF_BOOL qpdf_allow_extract_all(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_allow_extract_all"); return (qpdf->qpdf->allowExtractAll() ? QPDF_TRUE : QPDF_FALSE); } QPDF_BOOL qpdf_allow_print_low_res(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_allow_print_low_res"); return (qpdf->qpdf->allowPrintLowRes() ? QPDF_TRUE : QPDF_FALSE); } QPDF_BOOL qpdf_allow_print_high_res(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_allow_print_high_res"); return (qpdf->qpdf->allowPrintHighRes() ? QPDF_TRUE : QPDF_FALSE); } QPDF_BOOL qpdf_allow_modify_assembly(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_allow_modify_assembly"); return (qpdf->qpdf->allowModifyAssembly() ? QPDF_TRUE : QPDF_FALSE); } QPDF_BOOL qpdf_allow_modify_form(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_allow_modify_form"); return (qpdf->qpdf->allowModifyForm() ? QPDF_TRUE : QPDF_FALSE); } QPDF_BOOL qpdf_allow_modify_annotation(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_allow_modify_annotation"); return (qpdf->qpdf->allowModifyAnnotation() ? QPDF_TRUE : QPDF_FALSE); } QPDF_BOOL qpdf_allow_modify_other(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_allow_modify_other"); return (qpdf->qpdf->allowModifyOther() ? QPDF_TRUE : QPDF_FALSE); } QPDF_BOOL qpdf_allow_modify_all(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_allow_modify_all"); return (qpdf->qpdf->allowModifyAll() ? QPDF_TRUE : QPDF_FALSE); } static void qpdf_init_write_internal(qpdf_data qpdf) { if (qpdf->qpdf_writer.getPointer()) { QTC::TC("qpdf", "qpdf-c called qpdf_init_write multiple times"); qpdf->qpdf_writer = 0; if (qpdf->output_buffer.getPointer()) { qpdf->output_buffer = 0; qpdf->write_memory = false; qpdf->filename = 0; } } } QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename) { qpdf_init_write_internal(qpdf); qpdf->filename = filename; QPDF_ERROR_CODE status = trap_errors(qpdf, &call_init_write); QTC::TC("qpdf", "qpdf-c called qpdf_init_write", status); return status; } QPDF_ERROR_CODE qpdf_init_write_memory(qpdf_data qpdf) { qpdf_init_write_internal(qpdf); QPDF_ERROR_CODE status = trap_errors(qpdf, &call_init_write_memory); QTC::TC("qpdf", "qpdf-c called qpdf_init_write_memory"); qpdf->write_memory = true; return status; } static void qpdf_get_buffer_internal(qpdf_data qpdf) { if (qpdf->write_memory && (qpdf->output_buffer == 0)) { qpdf->output_buffer = qpdf->qpdf_writer->getBuffer(); } } size_t qpdf_get_buffer_length(qpdf_data qpdf) { qpdf_get_buffer_internal(qpdf); size_t result = 0; if (qpdf->output_buffer.getPointer()) { result = qpdf->output_buffer->getSize(); } return result; } unsigned char const* qpdf_get_buffer(qpdf_data qpdf) { unsigned char const* result = 0; qpdf_get_buffer_internal(qpdf); if (qpdf->output_buffer.getPointer()) { result = qpdf->output_buffer->getBuffer(); } return result; } void qpdf_set_object_stream_mode(qpdf_data qpdf, qpdf_object_stream_e mode) { QTC::TC("qpdf", "qpdf-c called qpdf_set_object_stream_mode"); qpdf->qpdf_writer->setObjectStreamMode(mode); } void qpdf_set_compress_streams(qpdf_data qpdf, QPDF_BOOL value) { QTC::TC("qpdf", "qpdf-c called qpdf_set_compress_streams"); qpdf->qpdf_writer->setCompressStreams(value != QPDF_FALSE); } void qpdf_set_decode_level(qpdf_data qpdf, qpdf_stream_decode_level_e level) { QTC::TC("qpdf", "qpdf-c called qpdf_set_decode_level"); qpdf->qpdf_writer->setDecodeLevel(level); } void qpdf_set_preserve_unreferenced_objects(qpdf_data qpdf, QPDF_BOOL value) { QTC::TC("qpdf", "qpdf-c called qpdf_set_preserve_unreferenced_objects"); qpdf->qpdf_writer->setPreserveUnreferencedObjects(value != QPDF_FALSE); } void qpdf_set_newline_before_endstream(qpdf_data qpdf, QPDF_BOOL value) { QTC::TC("qpdf", "qpdf-c called qpdf_set_newline_before_endstream"); qpdf->qpdf_writer->setNewlineBeforeEndstream(value != QPDF_FALSE); } void qpdf_set_stream_data_mode(qpdf_data qpdf, qpdf_stream_data_e mode) { QTC::TC("qpdf", "qpdf-c called qpdf_set_stream_data_mode"); qpdf->qpdf_writer->setStreamDataMode(mode); } void qpdf_set_content_normalization(qpdf_data qpdf, QPDF_BOOL value) { QTC::TC("qpdf", "qpdf-c called qpdf_set_content_normalization"); qpdf->qpdf_writer->setContentNormalization(value != QPDF_FALSE); } void qpdf_set_qdf_mode(qpdf_data qpdf, QPDF_BOOL value) { QTC::TC("qpdf", "qpdf-c called qpdf_set_qdf_mode"); qpdf->qpdf_writer->setQDFMode(value != QPDF_FALSE); } void qpdf_set_deterministic_ID(qpdf_data qpdf, QPDF_BOOL value) { QTC::TC("qpdf", "qpdf-c called qpdf_set_deterministic_ID"); qpdf->qpdf_writer->setDeterministicID(value != QPDF_FALSE); } void qpdf_set_static_ID(qpdf_data qpdf, QPDF_BOOL value) { QTC::TC("qpdf", "qpdf-c called qpdf_set_static_ID"); qpdf->qpdf_writer->setStaticID(value != QPDF_FALSE); } void qpdf_set_static_aes_IV(qpdf_data qpdf, QPDF_BOOL value) { QTC::TC("qpdf", "qpdf-c called qpdf_set_static_aes_IV"); qpdf->qpdf_writer->setStaticAesIV(value != QPDF_FALSE); } void qpdf_set_suppress_original_object_IDs( qpdf_data qpdf, QPDF_BOOL value) { QTC::TC("qpdf", "qpdf-c called qpdf_set_suppress_original_object_IDs"); qpdf->qpdf_writer->setSuppressOriginalObjectIDs(value != QPDF_FALSE); } void qpdf_set_preserve_encryption(qpdf_data qpdf, QPDF_BOOL value) { QTC::TC("qpdf", "qpdf-c called qpdf_set_preserve_encryption"); qpdf->qpdf_writer->setPreserveEncryption(value != QPDF_FALSE); } void qpdf_set_r2_encryption_parameters( qpdf_data qpdf, char const* user_password, char const* owner_password, QPDF_BOOL allow_print, QPDF_BOOL allow_modify, QPDF_BOOL allow_extract, QPDF_BOOL allow_annotate) { QTC::TC("qpdf", "qpdf-c called qpdf_set_r2_encryption_parameters"); qpdf->qpdf_writer->setR2EncryptionParameters( user_password, owner_password, allow_print != QPDF_FALSE, allow_modify != QPDF_FALSE, allow_extract != QPDF_FALSE, allow_annotate != QPDF_FALSE); } void qpdf_set_r3_encryption_parameters2( qpdf_data qpdf, char const* user_password, char const* owner_password, QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract, QPDF_BOOL allow_assemble, QPDF_BOOL allow_annotate_and_form, QPDF_BOOL allow_form_filling, QPDF_BOOL allow_modify_other, enum qpdf_r3_print_e print) { QTC::TC("qpdf", "qpdf-c called qpdf_set_r3_encryption_parameters"); qpdf->qpdf_writer->setR3EncryptionParameters( user_password, owner_password, allow_accessibility != QPDF_FALSE, allow_extract != QPDF_FALSE, allow_assemble != QPDF_FALSE, allow_annotate_and_form != QPDF_FALSE, allow_form_filling != QPDF_FALSE, allow_modify_other != QPDF_FALSE, print); } void qpdf_set_r4_encryption_parameters2( qpdf_data qpdf, char const* user_password, char const* owner_password, QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract, QPDF_BOOL allow_assemble, QPDF_BOOL allow_annotate_and_form, QPDF_BOOL allow_form_filling, QPDF_BOOL allow_modify_other, enum qpdf_r3_print_e print, QPDF_BOOL encrypt_metadata, QPDF_BOOL use_aes) { QTC::TC("qpdf", "qpdf-c called qpdf_set_r4_encryption_parameters"); qpdf->qpdf_writer->setR4EncryptionParameters( user_password, owner_password, allow_accessibility != QPDF_FALSE, allow_extract != QPDF_FALSE, allow_assemble != QPDF_FALSE, allow_annotate_and_form != QPDF_FALSE, allow_form_filling != QPDF_FALSE, allow_modify_other != QPDF_FALSE, print, encrypt_metadata != QPDF_FALSE, use_aes != QPDF_FALSE); } void qpdf_set_r5_encryption_parameters2( qpdf_data qpdf, char const* user_password, char const* owner_password, QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract, QPDF_BOOL allow_assemble, QPDF_BOOL allow_annotate_and_form, QPDF_BOOL allow_form_filling, QPDF_BOOL allow_modify_other, enum qpdf_r3_print_e print, QPDF_BOOL encrypt_metadata) { QTC::TC("qpdf", "qpdf-c called qpdf_set_r5_encryption_parameters"); qpdf->qpdf_writer->setR5EncryptionParameters( user_password, owner_password, allow_accessibility != QPDF_FALSE, allow_extract != QPDF_FALSE, allow_assemble != QPDF_FALSE, allow_annotate_and_form != QPDF_FALSE, allow_form_filling != QPDF_FALSE, allow_modify_other != QPDF_FALSE, print, encrypt_metadata != QPDF_FALSE); } void qpdf_set_r6_encryption_parameters2( qpdf_data qpdf, char const* user_password, char const* owner_password, QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract, QPDF_BOOL allow_assemble, QPDF_BOOL allow_annotate_and_form, QPDF_BOOL allow_form_filling, QPDF_BOOL allow_modify_other, enum qpdf_r3_print_e print, QPDF_BOOL encrypt_metadata) { QTC::TC("qpdf", "qpdf-c called qpdf_set_r6_encryption_parameters"); qpdf->qpdf_writer->setR6EncryptionParameters( user_password, owner_password, allow_accessibility != QPDF_FALSE, allow_extract != QPDF_FALSE, allow_assemble != QPDF_FALSE, allow_annotate_and_form != QPDF_FALSE, allow_form_filling != QPDF_FALSE, allow_modify_other != QPDF_FALSE, print, encrypt_metadata != QPDF_FALSE); } void qpdf_set_r3_encryption_parameters( qpdf_data qpdf, char const* user_password, char const* owner_password, QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract, qpdf_r3_print_e print, qpdf_r3_modify_e modify) { #ifdef _MSC_VER # pragma warning (disable: 4996) #endif #if (defined(__GNUC__) || defined(__clang__)) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif qpdf->qpdf_writer->setR3EncryptionParameters( user_password, owner_password, allow_accessibility != QPDF_FALSE, allow_extract != QPDF_FALSE, print, modify); #if (defined(__GNUC__) || defined(__clang__)) # pragma GCC diagnostic pop #endif } void qpdf_set_r4_encryption_parameters( qpdf_data qpdf, char const* user_password, char const* owner_password, QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract, qpdf_r3_print_e print, qpdf_r3_modify_e modify, QPDF_BOOL encrypt_metadata, QPDF_BOOL use_aes) { #ifdef _MSC_VER # pragma warning (disable: 4996) #endif #if (defined(__GNUC__) || defined(__clang__)) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif qpdf->qpdf_writer->setR4EncryptionParameters( user_password, owner_password, allow_accessibility != QPDF_FALSE, allow_extract != QPDF_FALSE, print, modify, encrypt_metadata != QPDF_FALSE, use_aes != QPDF_FALSE); #if (defined(__GNUC__) || defined(__clang__)) # pragma GCC diagnostic pop #endif } void qpdf_set_r5_encryption_parameters( qpdf_data qpdf, char const* user_password, char const* owner_password, QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract, qpdf_r3_print_e print, qpdf_r3_modify_e modify, QPDF_BOOL encrypt_metadata) { #ifdef _MSC_VER # pragma warning (disable: 4996) #endif #if (defined(__GNUC__) || defined(__clang__)) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif qpdf->qpdf_writer->setR5EncryptionParameters( user_password, owner_password, allow_accessibility != QPDF_FALSE, allow_extract != QPDF_FALSE, print, modify, encrypt_metadata != QPDF_FALSE); #if (defined(__GNUC__) || defined(__clang__)) # pragma GCC diagnostic pop #endif } void qpdf_set_r6_encryption_parameters( qpdf_data qpdf, char const* user_password, char const* owner_password, QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract, qpdf_r3_print_e print, qpdf_r3_modify_e modify, QPDF_BOOL encrypt_metadata) { #ifdef _MSC_VER # pragma warning (disable: 4996) #endif #if (defined(__GNUC__) || defined(__clang__)) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif qpdf->qpdf_writer->setR6EncryptionParameters( user_password, owner_password, allow_accessibility != QPDF_FALSE, allow_extract != QPDF_FALSE, print, modify, encrypt_metadata != QPDF_FALSE); #if (defined(__GNUC__) || defined(__clang__)) # pragma GCC diagnostic pop #endif } void qpdf_set_linearization(qpdf_data qpdf, QPDF_BOOL value) { QTC::TC("qpdf", "qpdf-c called qpdf_set_linearization"); qpdf->qpdf_writer->setLinearization(value != QPDF_FALSE); } void qpdf_set_minimum_pdf_version(qpdf_data qpdf, char const* version) { qpdf_set_minimum_pdf_version_and_extension(qpdf, version, 0); } void qpdf_set_minimum_pdf_version_and_extension( qpdf_data qpdf, char const* version, int extension_level) { QTC::TC("qpdf", "qpdf-c called qpdf_set_minimum_pdf_version"); qpdf->qpdf_writer->setMinimumPDFVersion(version, extension_level); } void qpdf_force_pdf_version(qpdf_data qpdf, char const* version) { qpdf_force_pdf_version_and_extension(qpdf, version, 0); } void qpdf_force_pdf_version_and_extension( qpdf_data qpdf, char const* version, int extension_level) { QTC::TC("qpdf", "qpdf-c called qpdf_force_pdf_version"); qpdf->qpdf_writer->forcePDFVersion(version, extension_level); } void qpdf_register_progress_reporter( qpdf_data qpdf, void (*report_progress)(int percent, void* data), void* data) { qpdf->qpdf_writer->registerProgressReporter( new ProgressReporter(report_progress, data)); } QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf) { QPDF_ERROR_CODE status = QPDF_SUCCESS; status = trap_errors(qpdf, &call_write); QTC::TC("qpdf", "qpdf-c called qpdf_write", (status == 0) ? 0 : 1); return status; } static qpdf_oh new_object(qpdf_data qpdf, QPDFObjectHandle const& qoh) { qpdf_oh oh = ++qpdf->next_oh; // never return 0 qpdf->oh_cache[oh] = new QPDFObjectHandle(qoh); return oh; } void qpdf_oh_release(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_release"); qpdf->oh_cache.erase(oh); } void qpdf_oh_release_all(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_release_all"); qpdf->oh_cache.clear(); } qpdf_oh qpdf_get_trailer(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_get_trailer"); return new_object(qpdf, qpdf->qpdf->getTrailer()); } qpdf_oh qpdf_get_root(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_get_root"); return new_object(qpdf, qpdf->qpdf->getRoot()); } static bool qpdf_oh_valid_internal(qpdf_data qpdf, qpdf_oh oh) { auto i = qpdf->oh_cache.find(oh); bool result = ((i != qpdf->oh_cache.end()) && (i->second).getPointer() && (i->second)->isInitialized()); if (! result) { QTC::TC("qpdf", "qpdf-c invalid object handle"); qpdf->warnings.push_back( QPDFExc( qpdf_e_damaged_pdf, qpdf->qpdf->getFilename(), std::string("C API object handle ") + QUtil::uint_to_string(oh), 0, "attempted access to unknown/uninitialized object handle")); } return result; } QPDF_BOOL qpdf_oh_is_bool(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_bool"); return (qpdf_oh_valid_internal(qpdf, oh) && qpdf->oh_cache[oh]->isBool()); } QPDF_BOOL qpdf_oh_is_null(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_null"); return (qpdf_oh_valid_internal(qpdf, oh) && qpdf->oh_cache[oh]->isNull()); } QPDF_BOOL qpdf_oh_is_integer(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_integer"); return (qpdf_oh_valid_internal(qpdf, oh) && qpdf->oh_cache[oh]->isInteger()); } QPDF_BOOL qpdf_oh_is_real(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_real"); return (qpdf_oh_valid_internal(qpdf, oh) && qpdf->oh_cache[oh]->isReal()); } QPDF_BOOL qpdf_oh_is_name(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_name"); return (qpdf_oh_valid_internal(qpdf, oh) && qpdf->oh_cache[oh]->isName()); } QPDF_BOOL qpdf_oh_is_string(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_string"); return (qpdf_oh_valid_internal(qpdf, oh) && qpdf->oh_cache[oh]->isString()); } QPDF_BOOL qpdf_oh_is_operator(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_operator"); return (qpdf_oh_valid_internal(qpdf, oh) && qpdf->oh_cache[oh]->isOperator()); } QPDF_BOOL qpdf_oh_is_inline_image(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_inline_image"); return (qpdf_oh_valid_internal(qpdf, oh) && qpdf->oh_cache[oh]->isInlineImage()); } QPDF_BOOL qpdf_oh_is_array(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_array"); return (qpdf_oh_valid_internal(qpdf, oh) && qpdf->oh_cache[oh]->isArray()); } QPDF_BOOL qpdf_oh_is_dictionary(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_dictionary"); return (qpdf_oh_valid_internal(qpdf, oh) && qpdf->oh_cache[oh]->isDictionary()); } QPDF_BOOL qpdf_oh_is_stream(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_stream"); return (qpdf_oh_valid_internal(qpdf, oh) && qpdf->oh_cache[oh]->isStream()); } QPDF_BOOL qpdf_oh_is_indirect(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_indirect"); return (qpdf_oh_valid_internal(qpdf, oh) && qpdf->oh_cache[oh]->isIndirect()); } QPDF_BOOL qpdf_oh_is_scalar(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_scalar"); return (qpdf_oh_valid_internal(qpdf, oh) && qpdf->oh_cache[oh]->isScalar()); } qpdf_oh qpdf_oh_wrap_in_array(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return qpdf_oh_new_array(qpdf); } auto qoh = qpdf->oh_cache[oh]; if (qoh->isArray()) { QTC::TC("qpdf", "qpdf-c array to wrap_in_array"); return oh; } else { QTC::TC("qpdf", "qpdf-c non-array to wrap_in_array"); return new_object(qpdf, QPDFObjectHandle::newArray( std::vector{ *qpdf->oh_cache[oh]})); } } qpdf_oh qpdf_oh_parse(qpdf_data qpdf, char const* object_str) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_parse"); return new_object(qpdf, QPDFObjectHandle::parse(object_str)); } QPDF_BOOL qpdf_oh_get_bool_value(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return QPDF_FALSE; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_bool_value"); return qpdf->oh_cache[oh]->getBoolValue(); } long long qpdf_oh_get_int_value(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return 0LL; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_int_value"); return qpdf->oh_cache[oh]->getIntValue(); } int qpdf_oh_get_int_value_as_int(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return 0; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_int_value_as_int"); return qpdf->oh_cache[oh]->getIntValueAsInt(); } unsigned long long qpdf_oh_get_uint_value(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return 0ULL; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_uint_value"); return qpdf->oh_cache[oh]->getUIntValue(); } unsigned int qpdf_oh_get_uint_value_as_uint(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return 0U; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_uint_value_as_uint"); return qpdf->oh_cache[oh]->getUIntValueAsUInt(); } char const* qpdf_oh_get_real_value(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return ""; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_real_value"); qpdf->tmp_string = qpdf->oh_cache[oh]->getRealValue(); return qpdf->tmp_string.c_str(); } QPDF_BOOL qpdf_oh_is_number(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return QPDF_FALSE; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_number"); return qpdf->oh_cache[oh]->isNumber(); } double qpdf_oh_get_numeric_value(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return 0.0; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_numeric_value"); return qpdf->oh_cache[oh]->getNumericValue(); } char const* qpdf_oh_get_name(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return ""; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_name"); qpdf->tmp_string = qpdf->oh_cache[oh]->getName(); return qpdf->tmp_string.c_str(); } char const* qpdf_oh_get_string_value(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return ""; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_string_value"); qpdf->tmp_string = qpdf->oh_cache[oh]->getStringValue(); return qpdf->tmp_string.c_str(); } char const* qpdf_oh_get_utf8_value(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return ""; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_utf8_value"); qpdf->tmp_string = qpdf->oh_cache[oh]->getUTF8Value(); return qpdf->tmp_string.c_str(); } int qpdf_oh_get_array_n_items(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return 0; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_array_n_items"); return qpdf->oh_cache[oh]->getArrayNItems(); } qpdf_oh qpdf_oh_get_array_item(qpdf_data qpdf, qpdf_oh oh, int n) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return qpdf_oh_new_null(qpdf); } QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_array_item"); return new_object(qpdf, qpdf->oh_cache[oh]->getArrayItem(n)); } void qpdf_oh_begin_dict_key_iter(qpdf_data qpdf, qpdf_oh oh) { if (qpdf_oh_valid_internal(qpdf, oh) && qpdf_oh_is_dictionary(qpdf, oh)) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_begin_dict_key_iter"); qpdf->cur_iter_dict_keys = qpdf->oh_cache[oh]->getKeys(); } else { qpdf->cur_iter_dict_keys = {}; } qpdf->dict_iter = qpdf->cur_iter_dict_keys.begin(); } QPDF_BOOL qpdf_oh_dict_more_keys(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_dict_more_keys"); return qpdf->dict_iter != qpdf->cur_iter_dict_keys.end(); } char const* qpdf_oh_dict_next_key(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_dict_next_key"); if (qpdf_oh_dict_more_keys(qpdf)) { qpdf->cur_dict_key = *qpdf->dict_iter; ++qpdf->dict_iter; return qpdf->cur_dict_key.c_str(); } else { return nullptr; } } QPDF_BOOL qpdf_oh_has_key(qpdf_data qpdf, qpdf_oh oh, char const* key) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return QPDF_FALSE; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_has_key"); return qpdf->oh_cache[oh]->hasKey(key); } qpdf_oh qpdf_oh_get_key(qpdf_data qpdf, qpdf_oh oh, char const* key) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return qpdf_oh_new_null(qpdf); } QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_key"); return new_object(qpdf, qpdf->oh_cache[oh]->getKey(key)); } QPDF_BOOL qpdf_oh_is_or_has_name(qpdf_data qpdf, qpdf_oh oh, char const* key) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return QPDF_FALSE; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_or_has_name"); return qpdf->oh_cache[oh]->isOrHasName(key); } qpdf_oh qpdf_oh_new_null(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_null"); return new_object(qpdf, QPDFObjectHandle::newNull()); } qpdf_oh qpdf_oh_new_bool(qpdf_data qpdf, QPDF_BOOL value) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_bool"); return new_object(qpdf, QPDFObjectHandle::newBool(value)); } qpdf_oh qpdf_oh_new_integer(qpdf_data qpdf, long long value) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_integer"); return new_object(qpdf, QPDFObjectHandle::newInteger(value)); } qpdf_oh qpdf_oh_new_real_from_string(qpdf_data qpdf, char const* value) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_real_from_string"); return new_object(qpdf, QPDFObjectHandle::newReal(value)); } qpdf_oh qpdf_oh_new_real_from_double(qpdf_data qpdf, double value, int decimal_places) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_real_from_double"); return new_object(qpdf, QPDFObjectHandle::newReal(value, decimal_places)); } qpdf_oh qpdf_oh_new_name(qpdf_data qpdf, char const* name) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_name"); return new_object(qpdf, QPDFObjectHandle::newName(name)); } qpdf_oh qpdf_oh_new_string(qpdf_data qpdf, char const* str) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_string"); return new_object(qpdf, QPDFObjectHandle::newString(str)); } qpdf_oh qpdf_oh_new_unicode_string(qpdf_data qpdf, char const* utf8_str) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_unicode_string"); return new_object(qpdf, QPDFObjectHandle::newUnicodeString(utf8_str)); } qpdf_oh qpdf_oh_new_array(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_array"); return new_object(qpdf, QPDFObjectHandle::newArray()); } qpdf_oh qpdf_oh_new_dictionary(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_dictionary"); return new_object(qpdf, QPDFObjectHandle::newDictionary()); } void qpdf_oh_make_direct(qpdf_data qpdf, qpdf_oh oh) { if (qpdf_oh_valid_internal(qpdf, oh)) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_make_direct"); qpdf->oh_cache[oh]->makeDirect(); } } static QPDFObjectHandle qpdf_oh_item_internal(qpdf_data qpdf, qpdf_oh item) { if (qpdf_oh_valid_internal(qpdf, item)) { return *(qpdf->oh_cache[item]); } else { return QPDFObjectHandle::newNull(); } } void qpdf_oh_set_array_item(qpdf_data qpdf, qpdf_oh oh, int at, qpdf_oh item) { if (qpdf_oh_is_array(qpdf, oh)) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_set_array_item"); qpdf->oh_cache[oh]->setArrayItem( at, qpdf_oh_item_internal(qpdf, item)); } } void qpdf_oh_insert_item(qpdf_data qpdf, qpdf_oh oh, int at, qpdf_oh item) { if (qpdf_oh_is_array(qpdf, oh)) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_insert_item"); qpdf->oh_cache[oh]->insertItem( at, qpdf_oh_item_internal(qpdf, item)); } } void qpdf_oh_append_item(qpdf_data qpdf, qpdf_oh oh, qpdf_oh item) { if (qpdf_oh_is_array(qpdf, oh)) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_append_item"); qpdf->oh_cache[oh]->appendItem( qpdf_oh_item_internal(qpdf, item)); } } void qpdf_oh_erase_item(qpdf_data qpdf, qpdf_oh oh, int at) { if (qpdf_oh_is_array(qpdf, oh)) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_erase_item"); qpdf->oh_cache[oh]->eraseItem(at); } } void qpdf_oh_replace_key(qpdf_data qpdf, qpdf_oh oh, char const* key, qpdf_oh item) { if (qpdf_oh_is_dictionary(qpdf, oh)) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_replace_key"); qpdf->oh_cache[oh]->replaceKey( key, qpdf_oh_item_internal(qpdf, item)); } } void qpdf_oh_remove_key(qpdf_data qpdf, qpdf_oh oh, char const* key) { if (qpdf_oh_is_dictionary(qpdf, oh)) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_remove_key"); qpdf->oh_cache[oh]->removeKey(key); } } void qpdf_oh_replace_or_remove_key(qpdf_data qpdf, qpdf_oh oh, char const* key, qpdf_oh item) { if (qpdf_oh_is_dictionary(qpdf, oh)) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_replace_or_remove_key"); qpdf->oh_cache[oh]->replaceOrRemoveKey( key, qpdf_oh_item_internal(qpdf, item)); } } qpdf_oh qpdf_oh_get_dict(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return qpdf_oh_new_null(qpdf); } QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_dict"); return new_object(qpdf, qpdf->oh_cache[oh]->getDict()); } int qpdf_oh_get_object_id(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return 0; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_object_id"); return qpdf->oh_cache[oh]->getObjectID(); } int qpdf_oh_get_generation(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return 0; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_generation"); return qpdf->oh_cache[oh]->getGeneration(); } char const* qpdf_oh_unparse(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return ""; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_unparse"); qpdf->tmp_string = qpdf->oh_cache[oh]->unparse(); return qpdf->tmp_string.c_str(); } char const* qpdf_oh_unparse_resolved(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return ""; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_unparse_resolved"); qpdf->tmp_string = qpdf->oh_cache[oh]->unparseResolved(); return qpdf->tmp_string.c_str(); } char const* qpdf_oh_unparse_binary(qpdf_data qpdf, qpdf_oh oh) { if (! qpdf_oh_valid_internal(qpdf, oh)) { return ""; } QTC::TC("qpdf", "qpdf-c called qpdf_oh_unparse_binary"); qpdf->tmp_string = qpdf->oh_cache[oh]->unparseBinary(); return qpdf->tmp_string.c_str(); }