- Add
LoadOptionsstruct withpassword,filter, andstrictfields for extensible loading configuration - Add
load_with_options,load_from_with_options, andload_mem_with_optionsmethods (sync + async)
- Deprecate
load_filtered,load_from_with_password,load_mem_with_passwordin favor of_with_optionsvariants
v0.38.0 (2025-08-26)
- Add enhanced PDF decryption support for encrypted documents with empty passwords
- Add automatic decryption during document loading for better pdftk compatibility
- Add raw object extraction before parsing to handle encrypted content
- Add support for decrypting PDFs with compressed object streams
- Add comprehensive test suite for PDF decryption functionality
- Add
assets/encrypted.pdftest file for decryption testing - Add examples demonstrating decryption capabilities (
test_decryption.rs,verify_decryption.rs)
- Enhance
Reader::read()to detect and handle encrypted PDFs automatically - Enhance document loading to attempt empty password authentication by default
- Enhance object processing to decrypt objects after parsing
- Enhance support for encrypted PDFs containing object streams
- Fix encrypted object parsing by extracting raw bytes before decryption
- Fix object stream handling in encrypted documents
- Fix decryption workflow to match pdftk's approach
- Modified
src/reader.rsto addload_encrypted_document()method - Added
extract_raw_object()method for raw byte extraction - Added
parse_raw_object()method for parsing extracted bytes - Store raw object bytes in
Reader::raw_objectsfield for deferred decryption - Process compressed objects from object streams after decryption
v0.37.0 (2025-08-08)
- Add complete PDF object streams write support enabling 11-61% file size reduction (#XXX)
- Add
save_modern()method for easy object streams and cross-reference streams usage - Add
SaveOptionsstruct with builder pattern for configuring compression settings - Add
ObjectStreamBuilderfor creating object streams programmatically - Add cross-reference stream support for PDF 1.5+ compliance
- Add
replace_partial_text()function for partial text replacement in PDFs - Add comprehensive test suite with 50+ tests for object streams functionality
- Add object streams write capability (previously read-only)
- Add implementation documentation in OBJECT_STREAMS_IMPLEMENTATION.md
- Fix pdfutil build error - missing
derivefeature for clap dependency - Fix async feature compilation - 25 examples/tests failing with
--all-features - Fix 31 clippy linting errors blocking CI with
#![deny(clippy::all)] - Fix object compression eligibility - structural objects (Catalog, Pages, Page) now properly compressed
- Fix trailer-referenced objects compression - only encryption dictionary excluded from compression
- Fix linearization detection for proper Catalog handling per PDF specification
- Fix compilation warnings
- Update to Rust 2024 edition with minimum Rust 1.85 requirement
- Maintain full backward compatibility - all existing APIs unchanged
v0.36.0 (2025-03-15)
- Add support for Revision 5 (#401)
- Add more checks to the encryption/decryption logic (#399)
- Add sanity checks for PDF encryption, add examples for decrypting/encrypting PDF files and various bug fixes (#397)
- Add encrypt function to crypt filters
- Add support for jiff and make both chrono and time optional features
- Avoid parsing encrypted object streams early and correctly parse object streams upon decryption (#385)
- Avoid decrypting cross-reference streams (#381)
- Check if the security handler is the standard one
- Clarify datetime parsing logic using the PDF specification
- Compute the file encryption key (revision 6)
- Declare and implement crypt filters
- Ensure the document is actually encrypted
- Fix unused imports
- Fix warning for rotate example
- Fix warnings about nom_parser
- Fix clippy warning about operator precedence
- Fix typo in comment
- Gracefully handle the is_aes check without throwing errors (#376)
- Handle cases where the stream objects override the crypt filter
- Implement Document::encrypt() (#396)
- Implement password authentication (revision 6)
- Implement decrypt with and without password sanitization
- Implement authentication functions
- Implement password sanitization from string
- Implement password algorithms 2-7
- Implement encrypt_object function
- Implement and use PKCS#5 padding instead
- Implement function to parse the available crypt filters
- Implement 256-bit AES-CBC crypt filter
- Implement TryFrom rather than TryInto
- Improve the AES decryption with some sanity checks (#383)
- Merge remaining algorithms functions into PasswordAlgorithm implementation
- Missing import to test
- Only encode EncryptMetadata when V >= 4 (#400)
- Provide revision-agnostic functions for the password algorithms
- Randomly generate file encryption key for V5 in encrypt example (#403)
- Recurse into arrays and dictionaries to fully decrypt all strings/streams (#378)
- Release 0.36
- Remove the old implementation
- Remove workflow that used to enable the nom_parser feature
- Remove nom_parser feature
- Reorganize encryption code
- Sanitize passwords (revision 6)
- Try decrypting with an empty password
- Unpack objects after decrypting object streams (#382)
- Update to nom 8.0 and nom_locate 5.0 (#402)
- update changelog
- Use a hasher instead of allocating a Vec
- Use the new implementation to compute the file encryption key
- Use the default stream and string crypt filter if present
- Use Unix epoch if time feature is not enabled
- Use get_deref for the Kids array to handle indirect references (#379)
- Validate encryption dictionary for revision 5 (#405)
- validate binary comment during parsing (#392)
0.35.0 (2025-01-19)
- Add test for supported color types in PDF image embedding
- Add function for text chunks extraction. (#342)
- added binary comment as attribute and for load and write. Binary Comment is gonna be important for pdf in A/2, A/3 format. (#370)
- Allow parsing off-spec PDF files with prefixes before the header (#362)
- Also accept ASCII85 streams without EOD marker (#354)
- Fix clippy warning
- Fix incorrect image data handling in PDF content stream
- Fix BitsPerComponent calculation and improper ColorSpace mapping
- Fix incorrect color type detection for JPEG images
- Fix mulitplication overflow in ascii85 decode (#348)
- Fix out of memory bug (#347)
- Fix addition overflow (#346)
- Fix lowercase s of Procset and no space target string(J-F-Liu#323) (#324)
- Ignore space after byte index of startxref (#371)
- Implement ToUnicode for variadic len encodings (#328)
- Improve JPEG processing efficiency by avoiding unnecessary decode (#345)
- Improve cmap parsing and internal error handling (#335)
- Inline images (#356)
- keep existing values when extending dictionary (#322)
- Properly support document prefixes (#365)
- Refactor and optimize image processing logic in xobject.rs
- Release 0.35
- remove misleading Object::as_string (#350)
- Rework errors (#358)
- Specify minimum Rust version in Cargo.toml (#320)
- Support UTF-16 encoding for bookmark titles with non-ASCII characters (#364)
- Support AES encryption and revision 4 (#343)
- Throw error if xref stream cannot be uncompressed (#339)
- update changelog
v0.34.0 (2024-08-31)
- Add ASCII85 decoding (#317)
- Add text extraction based on ToUnicode cmap (#314)
- Add error handling to object stream (#299)
- Add PDFDocEncoding (#296)
- Cleanup comments and cargo fmt (#290)
- Detect reference cycles when going through trailers (#308)
- Detect reference cycles when parsing streams (with nom_parser) (#300)
- Detect reference cycles when collecting page resources (#298)
- Fix unicode fonts extraction in extract text example. (#315)
- Fix clippy warings
- Implement encoding and decoding of text strings (PDF1.7 section 7.9.2.2) (#297)
- Improve error handling (#307)
- Refactor get_or_create_resources() (#291)
- Release 0.34
v0.33.0 (2024-08-31)
- Accept comments in content parsing (#261)
- Added a new feature to get images info from the pdf page. (#275)
- Async Examples (#266)
- AsyncReader (#265)
- Fix parse outline failed, the key ’D‘ might be an object id (#274)
- Fix parse outline failed(#270) (#271)
- indexmap use in TOC for sorted TOC (#267)
- Release 0.33
- Replace md5 with md-5 (#272)
v0.32.0 (2024-08-31)
- Add debug format for hexadecimal (#240)
- Added big generation value parsing (#257)
- Fix clippy warning and format code
- Fix clippy warnings
- Fix typo in README.md (#251)
- Fixed parsing of the PDFs with incorrect xrefs to indirect objects (#254)
- fixed clippy issues (#238)
- Handle references to arrays in get_page_contents() (#245)
- Object and related types implement PartialEq (#236)
- Release 0.32
v0.31.0 (2023-05-10)
- Annotate feature usage (#229)
- Fix typo in README.md (#233)
- PDF 2.0 is now a free specification
- Release 0.31
- Remove extraneous
Qoperation from insert_image (#227)
v0.30.0 (2023-04-09)
- Add support for extracting TOC, Outlines and NamedDestinations (#211)
- Add example extract_text (#212)
- Add get_encrypted and is_encrypted (#210)
- Add load_filtered method (#198)
- Add as_string method to Object (#196)
- Adding Comments to examples (#220)
- Fix clippy warning
- Fix cliippy warnings
- Fix datetime using time crate
- Fix Cargo.toml (#213)
- Fix ci build issue (#209)
- Fix extract_text to split text at word boundaries.
- Fix embed_image feature
- Make some more objects public. (#199)
- Readd accidently deleted pdf files in assets (#204)
- Release 0.30
- Remove obsolete lifetime
- Replace unmaitained encoding crate with encoding_rs (#222)
- Set default to nom_parser and rayon (#208)
- Update time dependency (#206)
- Update nom dependency
- Update time dependency
- Update edition and some dependencies.
v0.29.0 (2023-04-09)
- Add function get_page_annotations and include an example (#184)
- Added documentation and improved tests (#178)
- Allow mutable access to the document catalog (#189)
- Extend match layout change and Full bookmark example in merge. (#179)
- Fix nom parser
- Fix clippy warnings
- Fix add_barcode example
- Fix Incremental.pdf
- Fix documentation issues and make README testable (#171)
- Fix pdfutil build error
- Fix
extenddefinition confusion bug (#161)
- Guard example based on if the "parser" feature is enabled (#173)
- made XREF parser accept an optional space character after 'xref' (#167)
- Make add_xobject follow references (#187)
- Make xref public ,fix line endings and Fix Xref output so Adobe will open them again. (#181)
- Merge branch 'master' of https://github.com/J-F-Liu/lopdf
- Release 0.29
- Release 0.28
- Remove --no-default-features test
- remove unneccessary time 0.1 dependency (#163)
- Reorder Pages before Renumbering Objects. (#193)
- Support Incremental Updates (#176)
- switch to single-precision floating point (#190)
- Update itoa dependency to 1.0 (#162)
v0.27.0 (2021-12-16)
- Add GitHub Actions build matrix (#127)
- Add Change Log
- Avoid panic when encounters negative stream length
- Bookmarks (#135)
- Change indent_style to space
- Check stream length
- Do not limit Real precision to two digits (#155)
- Fix document save race in parser_aux::load_and_save and creator::create_document (#151)
- Fix clippy warnings & add clippy build job (#128)
- Preserve the eol characters in literal strings (#131)
- Reduce allocation by reusing the iterator (#129)
- Release 0.27
- Release pdfutil 0.4
- Replace lzw with weezl (#140)
- Return early on error in
Stream::filters(#130)
- Unwrap the text (#119)
- Update nom to 6.0 (#126)
v0.26.0 (2020-09-29)
- Add as_str, as_str_mut methods to Object (#107)
- dtoa may write real number in exponential format which is not allowed in PDF
- Genericize Content to allow AsRef<[Operation]> (#111)
- Merge document PDF logic with some fixes (#117)
- Various improvements, updated libraries and image features (#118)
v0.25.0 (2020-06-25)
- add indexing checks (#98)
- Bugfix for xref_start. (#105)
- check that the buffer is big enough for startxref (#93)
- Create rust.yml (#104)
- extend recursion limit to non-local references (#100)
- Fix compilation error&test error (#102)
- keep looking for the last pattern (#94)
- Limit allowed bracket depth. (#97)
- limit recursion to the number of objects (#92)
- Move bracket depth checking into parsers. (#101)
- Release 0.25
- Return Result from as_array_mut() (#106)
- Update itoa and linked-hash-map (#91)
v0.24.0 (2020-02-17)
- Compute an accurate iterator size when the page tree is sane.
- Fix datetime parser (#89)
- More permissive datetime parsing (#90)
- Release 0.24
- Validate expected id in pom parser.
- Validate the expected id when reading indirect objects.
v0.23.0 (2019-07-14)
- Adapt pom parser.
- Add error descriptions.
- Add a proper error type and remove some more panics.
- Allow loading a document from a memory slice.
- Avoid allocating an intermediate collection for iteration.
- Avoid unwraps when already returning an Option for failure.
- Error signaling around compression and image handling.
- Escape fix (#68)
- Export dereference function as it is useful for PDF consumers.
- Export filters module.
- get_font_encoding seems more at home with Dictionary.
- Handle stream filter chains (#66)
- Hex fix (#67)
- Implement LZW decompression.
- Improve hex parsing performance.
- Make a page iterator.
- Make Reader::read consume the Reader.
- Make content operations faillible.
- Protect against reference loops.
- Protect against a corrupted page tree.
- Refactor a bit to allow a utility function.
- Release 0.23.0
- Remove intermediate assignation.
- Remove unsafe code around FilterType.
- Remove unsafe code on get_object_mut.
- Remove some 'if let' for readability.
- Remove more panic paths in xref parsing.
- Replace unwraps in processor.rs.
- Return results when appropriate.
- Separate decompression into two functions.
- Take care of panic that I actually hit on the pom side.
- Take care of creator.rs.
- Unify buffer creation.
- Use lifetime ellision.
- Use TryInto.
- Use writeln where appropriate.
- Use error enum in reader.
- Use stable cloned.
v0.22.0 (2019-05-13)
- Add parsing benchmark.
- Add nom dependency.
- Also test with nom parsing feature enabled.
- Array and dictionary parsing.
- Avoid using format! when writing.
- Be explicit about trait objects.
- Boolean and null parsing.
- Content parsing.
- Duplicate pom parser for incremental replacement with nom 5.
- Ease off on rayon a bit.
- Escape sequence parsing.
- extern crate is not required anymore with 2018 edition.
- Fix last ugly parser.
- Fix octal parser.
- Fix pdfutil build
- Float parsing.
- Header parsing.
- Hex string parsing.
- Indirect object and stream parsing.
- Literal string syntax.
- Make sure Stream.start_position is relative to the whole file.
- Merge remote-tracking branch 'upstream/master' into nom5
- Merge remote-tracking branch 'upstream/master' into nom5
- More 2018 edition lints.
- More cleanup.
- More cleanup.
- More simplifications.
- Object id and reference parsing.
- Octal and hexadecimal parsing.
- Parallel object stream parsing.
- Rayon usage proof of concept.
- Release 0.22.0
- Remove pom dependency in tests.
- Replace name parser.
- Resolve name collisions.
- Simplify lifetime annotations.
- Slowly replace the cute pom parser with nom.
- Trailer and xref start.
- Turns out "contained" already exists in nom.
- Unify both variants of the parsing functions.
- Use a BufWriter when saving to path.
- Use parse_at(&self.buffer, offset) to read indirect_object
- Use nom digit testing functions.
- Use lifetime ellision.
- Use nom sequence operators.
- Useless move.
- Xref stream and trailer parsing.
- Xref parsing.
v0.21.0 (2019-04-26)
- Avoid allocating a String.
- Check offsets read from file to avoid panics
- Check and correct Size entry of trailer dictionary
- Clean up bytes_to_string, string_to_bytes iterators
- Fix clippy warnings
- Fix .editorconfig
- fixed finally
- Redundant imports with 2018 edition.
- Release 0.21.0
- Update example
- Update Cargo.toml
- Use env_logger in pdfutil
v0.20.0 (2019-03-07)
- Release 0.20.0
- Replace println with log macros
- Use Rust 2018
- Use pom 3.0
v0.19.0 (2018-10-24)
- Allow xref section has zero entries
- Dictionary key type changed to Vec
- Format code with rustfmt
- Improve codestyle (simplify loops, remove closures, use is_empty() etc.)
- Move image dependency to embed_image feature
- Release 0.19.0
- Skip corrupt deflate stream
v0.18.0 (2018-10-05)
- Able to read stream when it's length is in object stream
- Adress timezone formatting problem from #34
- insert image on page
v0.17.0 (2018-09-19)
- Make chrono crate optional
- Release 0.17.0
- Update add_barcode example
v0.16.0 (2018-09-18)
- Add form xobject to page
- Add extract_stream subcommand
- Compress created Form xobject
- compress page content after change
- Fix collect_fonts_from_resources for referenced resources
- Fix add xobject to page resources as direct object
v0.15.3 (2018-09-14)
- Decompress Form XObject
- Disable auto format markdown
- Fix bug in reading incremental updated document
- Fix build warning
- Fix string_to_bytes method
- Hexadecimal strings can contain white space.
- Remove println in extract_text
- Update example code
- Update example
v0.15.0 (2018-02-04)
- add
get_object_mut - add method as_array_mut
- Extract text from specified pages
- Replace text of specified page
v0.14.1 (2017-11-03)
- Add
impl From<_> for Objectfor more numeric types - Add an Object::string_literal constructor
- Add a
dictionary!macro that creates a Dictionary - Add
impl From<ObjectId> for Objectcreating Object::Reference
- Derive Clone for lopdf::Document
- Release 0.14.0
- Remove the Seek bound on Document::save_to
v0.13.0 (2017-10-02)
- Avoid decompress flate stream which has Subtype
- Debug with lldb
- Fix get_object for created document
- Ignore invalid objects when reading all object in xref table
- impl fmt::Debug for Object
- pdfutil add extract_pages command
- Read optional space at the end of xref subsection header line
- Release 0.13.0
- Release 0.12.0
- Store compressed stream objects and normal objects together
v0.11.0 (2017-08-21)
- Release 0.11.0
- Use itoa and dtoa to improve writing performance
v0.10.0 (2017-07-20)
- Added optional allows_compression for Stream object
- Release 0.10.0
v0.9.0 (2017-05-24)
- Add pdfutil readme
- Added unit test for load_from() and save_to()
- Added Document::with_version + refactored save() and load()
- Added Debug trait for lopdf::Document
- Apply multiple operations in one command
- Build with Rust stable
- Build with Rust beta
- Fix delete_zero_length_streams
- Fixed unit tests
- Fixed breaking API changes
- Release 0.9.0
v0.8.0 (2017-03-16)
- Change Name(String) to Name(Vec)
- delete_object and delete_unused_objects
- get_pages and delete_pages
- Handle zero length stream
- Release 0.8.0
- Traverse objects from trailer recursively
v0.7.0 (2017-03-07)
- Add Content::decode() function
- Build on Rust 1.17
- Create String object for DateTime
- Parse PDF datetime value
- Read xref stream in hybrid-reference file
- Update create_document example
- Update README
v0.6.0 (2017-02-16)
- Add Stream::decompressed_content() method
- Read previous Xrefs of linearized or incremental updated document
v0.5.0 (2017-02-10)
- Add size field to Xref
- Add Xref struct
- Decode PNG frame after FlateDecode
- Read compressed objects from object stream
- Read xref stream
- Update README
- Use pom 0.9.0
- XrefEntry as enum type
v0.4.0 (2017-01-29)
- Add Operation constructor
- Add modify_text test
- Add travis-ci build status
- Add FAQ in Readme
- Add print_xref_size() for debuging
- Decode content stream
- Encode content operations
- Fix load_document test
- Fix rust-lang/rust#39177
- Optimize parser code
- Solve mutual reference problem between Pages and Page objects
- Trigger new release to pass build on docs.rs
- Update create PDF example
v0.3.0 (2017-01-18)
- Add compress/decompress subcommands to pdfutil
- create PDF parser using pom instead of nom
- Dictionary preserve key insert order
- Update README
- Update parser to use pom 0.6.0
- Use reader to get stream length if it is a reference object
v0.2.0 (2017-01-05)
- Add pdfutil program
- Fix parsing PDF array error
- Improve documentation
- Editor config
- impl Document add_object method
- Improve Document::save functional type
- Initial commit
- PDF objects and document definition
- Parse and load PDF document
- Read objects from xref table instead of sequentially from file stream
- Save PDF document to file
- Store max_id as a field of document