1 use crate::{Document, Error, Result}; 2 use linked_hash_map::{self, Iter, IterMut, LinkedHashMap}; 3 use log::warn; 4 use std::fmt; 5 use std::str; 6 7 /// Object identifier consists of two parts: object number and generation number. 8 pub type ObjectId = (u32, u16); 9 10 /// Dictionary object. 11 #[derive(Clone, Default)] 12 pub struct Dictionary(LinkedHashMap<Vec<u8>, Object>); 13 14 /// Stream object 15 /// Warning - all streams must be indirect objects, while 16 /// the stream dictionary may be a direct object 17 #[derive(Debug, Clone)] 18 pub struct Stream { 19 /// Associated stream dictionary 20 pub dict: Dictionary, 21 /// Contents of the stream in bytes 22 pub content: Vec<u8>, 23 /// Can the stream be compressed by the `Document::compress()` function? 24 /// Font streams may not be compressed, for example 25 pub allows_compression: bool, 26 /// Stream data's position in PDF file. 27 pub start_position: Option<usize>, 28 } 29 30 /// Basic PDF object types defined in an enum. 31 #[derive(Clone)] 32 pub enum Object { 33 Null, 34 Boolean(bool), 35 Integer(i64), 36 Real(f64), 37 Name(Vec<u8>), 38 String(Vec<u8>, StringFormat), 39 Array(Vec<Object>), 40 Dictionary(Dictionary), 41 Stream(Stream), 42 Reference(ObjectId), 43 } 44 45 /// String objects can be written in two formats. 46 #[derive(Debug, Clone)] 47 pub enum StringFormat { 48 Literal, 49 Hexadecimal, 50 } 51 52 impl Default for StringFormat { default() -> StringFormat53 fn default() -> StringFormat { 54 StringFormat::Literal 55 } 56 } 57 58 impl From<bool> for Object { from(value: bool) -> Self59 fn from(value: bool) -> Self { 60 Object::Boolean(value) 61 } 62 } 63 64 impl From<i64> for Object { from(number: i64) -> Self65 fn from(number: i64) -> Self { 66 Object::Integer(number) 67 } 68 } 69 70 macro_rules! from_smaller_ints { 71 ($( $Int: ty )+) => { 72 $( 73 impl From<$Int> for Object { 74 fn from(number: $Int) -> Self { 75 Object::Integer(i64::from(number)) 76 } 77 } 78 )+ 79 } 80 } 81 82 from_smaller_ints! { 83 i8 i16 i32 84 u8 u16 u32 85 } 86 87 impl From<f64> for Object { from(number: f64) -> Self88 fn from(number: f64) -> Self { 89 Object::Real(number) 90 } 91 } 92 93 impl From<f32> for Object { from(number: f32) -> Self94 fn from(number: f32) -> Self { 95 Object::Real(f64::from(number)) 96 } 97 } 98 99 impl From<String> for Object { from(name: String) -> Self100 fn from(name: String) -> Self { 101 Object::Name(name.into_bytes()) 102 } 103 } 104 105 impl<'a> From<&'a str> for Object { from(name: &'a str) -> Self106 fn from(name: &'a str) -> Self { 107 Object::Name(name.as_bytes().to_vec()) 108 } 109 } 110 111 impl From<Vec<Object>> for Object { from(array: Vec<Object>) -> Self112 fn from(array: Vec<Object>) -> Self { 113 Object::Array(array) 114 } 115 } 116 117 impl From<Dictionary> for Object { from(dcit: Dictionary) -> Self118 fn from(dcit: Dictionary) -> Self { 119 Object::Dictionary(dcit) 120 } 121 } 122 123 impl From<Stream> for Object { from(stream: Stream) -> Self124 fn from(stream: Stream) -> Self { 125 Object::Stream(stream) 126 } 127 } 128 129 impl From<ObjectId> for Object { from(id: ObjectId) -> Self130 fn from(id: ObjectId) -> Self { 131 Object::Reference(id) 132 } 133 } 134 135 impl Object { string_literal<S: Into<Vec<u8>>>(s: S) -> Self136 pub fn string_literal<S: Into<Vec<u8>>>(s: S) -> Self { 137 Object::String(s.into(), StringFormat::Literal) 138 } 139 is_null(&self) -> bool140 pub fn is_null(&self) -> bool { 141 match *self { 142 Object::Null => true, 143 _ => false, 144 } 145 } 146 as_i64(&self) -> Result<i64>147 pub fn as_i64(&self) -> Result<i64> { 148 match *self { 149 Object::Integer(ref value) => Ok(*value), 150 _ => Err(Error::Type), 151 } 152 } 153 as_f64(&self) -> Result<f64>154 pub fn as_f64(&self) -> Result<f64> { 155 match *self { 156 Object::Real(ref value) => Ok(*value), 157 _ => Err(Error::Type), 158 } 159 } 160 as_name(&self) -> Result<&[u8]>161 pub fn as_name(&self) -> Result<&[u8]> { 162 match *self { 163 Object::Name(ref name) => Ok(name), 164 _ => Err(Error::Type), 165 } 166 } 167 as_name_str(&self) -> Result<&str>168 pub fn as_name_str(&self) -> Result<&str> { 169 Ok(str::from_utf8(self.as_name()?)?) 170 } 171 as_str(&self) -> Result<&[u8]>172 pub fn as_str(&self) -> Result<&[u8]> { 173 match self { 174 Object::String(string, _) => Ok(string), 175 _ => Err(Error::Type), 176 } 177 } 178 as_str_mut(&mut self) -> Result<&mut Vec<u8>>179 pub fn as_str_mut(&mut self) -> Result<&mut Vec<u8>> { 180 match self { 181 Object::String(string, _) => Ok(string), 182 _ => Err(Error::Type), 183 } 184 } 185 as_reference(&self) -> Result<ObjectId>186 pub fn as_reference(&self) -> Result<ObjectId> { 187 match *self { 188 Object::Reference(ref id) => Ok(*id), 189 _ => Err(Error::Type), 190 } 191 } 192 as_array(&self) -> Result<&Vec<Object>>193 pub fn as_array(&self) -> Result<&Vec<Object>> { 194 match *self { 195 Object::Array(ref arr) => Ok(arr), 196 _ => Err(Error::Type), 197 } 198 } 199 as_array_mut(&mut self) -> Result<&mut Vec<Object>>200 pub fn as_array_mut(&mut self) -> Result<&mut Vec<Object>> { 201 match *self { 202 Object::Array(ref mut arr) => Ok(arr), 203 _ => Err(Error::Type), 204 } 205 } 206 as_dict(&self) -> Result<&Dictionary>207 pub fn as_dict(&self) -> Result<&Dictionary> { 208 match *self { 209 Object::Dictionary(ref dict) => Ok(dict), 210 _ => Err(Error::Type), 211 } 212 } 213 as_dict_mut(&mut self) -> Result<&mut Dictionary>214 pub fn as_dict_mut(&mut self) -> Result<&mut Dictionary> { 215 match *self { 216 Object::Dictionary(ref mut dict) => Ok(dict), 217 _ => Err(Error::Type), 218 } 219 } 220 as_stream(&self) -> Result<&Stream>221 pub fn as_stream(&self) -> Result<&Stream> { 222 match *self { 223 Object::Stream(ref stream) => Ok(stream), 224 _ => Err(Error::Type), 225 } 226 } 227 as_stream_mut(&mut self) -> Result<&mut Stream>228 pub fn as_stream_mut(&mut self) -> Result<&mut Stream> { 229 match *self { 230 Object::Stream(ref mut stream) => Ok(stream), 231 _ => Err(Error::Type), 232 } 233 } 234 type_name(&self) -> Result<&str>235 pub fn type_name(&self) -> Result<&str> { 236 match *self { 237 Object::Dictionary(ref dict) => dict.type_name(), 238 Object::Stream(ref stream) => stream.dict.type_name(), 239 _ => Err(Error::Type), 240 } 241 } 242 } 243 244 impl fmt::Debug for Object { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result245 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 246 match *self { 247 Object::Null => f.write_str("null"), 248 Object::Boolean(ref value) => { 249 if *value { 250 f.write_str("true") 251 } else { 252 f.write_str("false") 253 } 254 } 255 Object::Integer(ref value) => write!(f, "{}", *value), 256 Object::Real(ref value) => write!(f, "{}", *value), 257 Object::Name(ref name) => write!(f, "/{}", String::from_utf8_lossy(name)), 258 Object::String(ref text, _) => write!(f, "({})", String::from_utf8_lossy(text)), 259 Object::Array(ref array) => { 260 let items = array.iter().map(|item| format!("{:?}", item)).collect::<Vec<String>>(); 261 write!(f, "[{}]", items.join(" ")) 262 } 263 Object::Dictionary(ref dict) => write!(f, "{:?}", dict), 264 Object::Stream(ref stream) => write!(f, "{:?}stream...endstream", stream.dict), 265 Object::Reference(ref id) => write!(f, "{} {} R", id.0, id.1), 266 } 267 } 268 } 269 270 impl Dictionary { new() -> Dictionary271 pub fn new() -> Dictionary { 272 Dictionary(LinkedHashMap::new()) 273 } 274 has(&self, key: &[u8]) -> bool275 pub fn has(&self, key: &[u8]) -> bool { 276 self.0.contains_key(key) 277 } 278 get(&self, key: &[u8]) -> Result<&Object>279 pub fn get(&self, key: &[u8]) -> Result<&Object> { 280 self.0.get(key).ok_or(Error::DictKey) 281 } 282 283 /// Extract object from dictionary, dereferencing the object if it 284 /// is a reference. get_deref<'a>(&'a self, key: &[u8], doc: &'a Document) -> Result<&'a Object>285 pub fn get_deref<'a>(&'a self, key: &[u8], doc: &'a Document) -> Result<&'a Object> { 286 doc.dereference(self.get(key)?).map(|(_, object)| object) 287 } 288 get_mut(&mut self, key: &[u8]) -> Result<&mut Object>289 pub fn get_mut(&mut self, key: &[u8]) -> Result<&mut Object> { 290 self.0.get_mut(key).ok_or(Error::DictKey) 291 } 292 set<K, V>(&mut self, key: K, value: V) where K: Into<Vec<u8>>, V: Into<Object>,293 pub fn set<K, V>(&mut self, key: K, value: V) 294 where 295 K: Into<Vec<u8>>, 296 V: Into<Object>, 297 { 298 self.0.insert(key.into(), value.into()); 299 } 300 len(&self) -> usize301 pub fn len(&self) -> usize { 302 self.0.len() 303 } 304 is_empty(&self) -> bool305 pub fn is_empty(&self) -> bool { 306 self.0.len() == 0 307 } 308 remove(&mut self, key: &[u8]) -> Option<Object>309 pub fn remove(&mut self, key: &[u8]) -> Option<Object> { 310 self.0.remove(key) 311 } 312 type_name(&self) -> Result<&str>313 pub fn type_name(&self) -> Result<&str> { 314 self.get(b"Type") 315 .and_then(Object::as_name_str) 316 .or_else(|_| self.get(b"Linearized").and(Ok("Linearized"))) 317 } 318 type_is(&self, type_name: &[u8]) -> bool319 pub fn type_is(&self, type_name: &[u8]) -> bool { 320 self.get(b"Type").and_then(Object::as_name).ok() == Some(type_name) 321 } 322 iter(&self) -> Iter<'_, Vec<u8>, Object>323 pub fn iter(&self) -> Iter<'_, Vec<u8>, Object> { 324 self.0.iter() 325 } 326 iter_mut(&mut self) -> IterMut<'_, Vec<u8>, Object>327 pub fn iter_mut(&mut self) -> IterMut<'_, Vec<u8>, Object> { 328 self.0.iter_mut() 329 } 330 get_font_encoding(&self) -> &str331 pub fn get_font_encoding(&self) -> &str { 332 self.get(b"Encoding") 333 .and_then(Object::as_name_str) 334 .unwrap_or("StandardEncoding") 335 } 336 extend(&mut self, other: &Dictionary)337 pub fn extend(&mut self, other: &Dictionary) { 338 let keep_both_objects = 339 |new_dict: &mut LinkedHashMap<Vec<u8>, Object>, key: &Vec<u8>, value: &Object, old_value: &Object| { 340 let mut final_array = Vec::new(); 341 match value { 342 Object::Array(array) => { 343 final_array.push(old_value.to_owned()); 344 final_array.extend(array.to_owned()); 345 } 346 _ => { 347 final_array.push(value.to_owned()); 348 final_array.push(old_value.to_owned()); 349 } 350 } 351 352 new_dict.insert(key.to_owned(), Object::Array(final_array)); 353 }; 354 355 let mut new_dict = LinkedHashMap::new(); 356 for (key, value) in other.0.iter() { 357 if let Some(old_value) = self.0.get(key) { 358 match old_value { 359 Object::Dictionary(old_dict) => match value { 360 Object::Dictionary(dict) => { 361 let mut replaced_dict = old_dict.to_owned(); 362 replaced_dict.extend(dict); 363 364 new_dict.insert(key.to_owned(), Object::Dictionary(replaced_dict)); 365 } 366 _ => keep_both_objects(&mut new_dict, key, value, old_value), 367 }, 368 Object::Array(old_array) => match value { 369 Object::Array(array) => { 370 let mut replaced_array = old_array.to_owned(); 371 replaced_array.extend(array.to_owned()); 372 373 new_dict.insert(key.to_owned(), Object::Array(replaced_array)); 374 } 375 _ => keep_both_objects(&mut new_dict, key, value, old_value), 376 }, 377 Object::Integer(old_id) => match value { 378 Object::Integer(id) => { 379 let mut array = Vec::new(); 380 array.push(Object::Integer(*old_id)); 381 array.push(Object::Integer(*id)); 382 383 new_dict.insert(key.to_owned(), Object::Array(array)); 384 } 385 _ => keep_both_objects(&mut new_dict, key, value, old_value), 386 }, 387 Object::Real(old_id) => match value { 388 Object::Real(id) => { 389 let mut array = Vec::new(); 390 array.push(Object::Real(*old_id)); 391 array.push(Object::Real(*id)); 392 393 new_dict.insert(key.to_owned(), Object::Array(array)); 394 } 395 _ => keep_both_objects(&mut new_dict, key, value, old_value), 396 }, 397 Object::String(old_ids, old_format) => match value { 398 Object::String(ids, format) => { 399 let mut array = Vec::new(); 400 array.push(Object::String(old_ids.to_owned(), old_format.to_owned())); 401 array.push(Object::String(ids.to_owned(), format.to_owned())); 402 403 new_dict.insert(key.to_owned(), Object::Array(array)); 404 } 405 _ => keep_both_objects(&mut new_dict, key, value, old_value), 406 }, 407 Object::Reference(old_object_id) => match value { 408 Object::Reference(object_id) => { 409 let mut array = Vec::new(); 410 array.push(Object::Reference(*old_object_id)); 411 array.push(Object::Reference(*object_id)); 412 413 new_dict.insert(key.to_owned(), Object::Array(array)); 414 } 415 _ => keep_both_objects(&mut new_dict, key, value, old_value), 416 }, 417 _ => { 418 new_dict.insert(key.to_owned(), old_value.to_owned()); 419 } 420 } 421 } else { 422 new_dict.insert(key.to_owned(), value.to_owned()); 423 } 424 } 425 426 self.0 = new_dict; 427 } 428 } 429 430 #[macro_export] 431 macro_rules! dictionary { 432 () => { 433 $crate::Dictionary::new() 434 }; 435 ($( $key: expr => $value: expr ),+ ,) => { 436 dictionary!( $($key => $value),+ ) 437 }; 438 ($( $key: expr => $value: expr ),*) => {{ 439 let mut dict = $crate::Dictionary::new(); 440 $( 441 dict.set($key, $value); 442 )* 443 dict 444 }} 445 } 446 447 impl fmt::Debug for Dictionary { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result448 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 449 let entries = self 450 .into_iter() 451 .map(|(key, value)| format!("/{} {:?}", String::from_utf8_lossy(key), value)) 452 .collect::<Vec<String>>(); 453 write!(f, "<<{}>>", entries.concat()) 454 } 455 } 456 457 impl<'a> IntoIterator for &'a Dictionary { 458 type Item = (&'a Vec<u8>, &'a Object); 459 type IntoIter = linked_hash_map::Iter<'a, Vec<u8>, Object>; 460 into_iter(self) -> Self::IntoIter461 fn into_iter(self) -> Self::IntoIter { 462 self.0.iter() 463 } 464 } 465 466 use std::iter::FromIterator; 467 impl<K: Into<Vec<u8>>> FromIterator<(K, Object)> for Dictionary { from_iter<I: IntoIterator<Item = (K, Object)>>(iter: I) -> Self468 fn from_iter<I: IntoIterator<Item = (K, Object)>>(iter: I) -> Self { 469 let mut dict = Dictionary::new(); 470 for (k, v) in iter { 471 dict.set(k, v); 472 } 473 dict 474 } 475 } 476 477 impl Stream { new(mut dict: Dictionary, content: Vec<u8>) -> Stream478 pub fn new(mut dict: Dictionary, content: Vec<u8>) -> Stream { 479 dict.set("Length", content.len() as i64); 480 Stream { 481 dict, 482 content, 483 allows_compression: true, 484 start_position: None, 485 } 486 } 487 with_position(dict: Dictionary, position: usize) -> Stream488 pub fn with_position(dict: Dictionary, position: usize) -> Stream { 489 Stream { 490 dict, 491 content: vec![], 492 allows_compression: true, 493 start_position: Some(position), 494 } 495 } 496 497 /// Default is that the stream may be compressed. On font streams, 498 /// set this to false, otherwise the font will be corrupt 499 #[inline] with_compression(mut self, allows_compression: bool) -> Stream500 pub fn with_compression(mut self, allows_compression: bool) -> Stream { 501 self.allows_compression = allows_compression; 502 self 503 } 504 505 // Return first filter filter(&self) -> Result<String>506 pub fn filter(&self) -> Result<String> { 507 self.filters() 508 .and_then(|f| f.into_iter().nth(0).ok_or(Error::ObjectNotFound)) 509 } 510 filters(&self) -> Result<Vec<String>>511 pub fn filters(&self) -> Result<Vec<String>> { 512 let filter = self.dict.get(b"Filter")?; 513 514 if let Ok(name) = filter.as_name_str() { 515 Ok(vec![name.into()]) 516 } else if let Ok(names) = filter.as_array() { 517 let out_names: Vec<_> = names 518 .iter() 519 .filter_map(|n| Object::as_name_str(n).ok()) 520 .map(Into::into) 521 .collect(); 522 523 // It is an error if a single conversion fails. 524 if out_names.len() == names.len() { 525 Ok(out_names) 526 } else { 527 Err(Error::Type) 528 } 529 } else { 530 Err(Error::Type) 531 } 532 } 533 set_content(&mut self, content: Vec<u8>)534 pub fn set_content(&mut self, content: Vec<u8>) { 535 self.content = content; 536 self.dict.set("Length", self.content.len() as i64); 537 } 538 set_plain_content(&mut self, content: Vec<u8>)539 pub fn set_plain_content(&mut self, content: Vec<u8>) { 540 self.dict.remove(b"DecodeParms"); 541 self.dict.remove(b"Filter"); 542 self.dict.set("Length", content.len() as i64); 543 self.content = content; 544 } 545 compress(&mut self) -> Result<()>546 pub fn compress(&mut self) -> Result<()> { 547 use flate2::write::ZlibEncoder; 548 use flate2::Compression; 549 use std::io::prelude::*; 550 551 if self.dict.get(b"Filter").is_err() { 552 let mut encoder = ZlibEncoder::new(Vec::new(), Compression::best()); 553 encoder.write_all(self.content.as_slice())?; 554 let compressed = encoder.finish()?; 555 if compressed.len() + 19 < self.content.len() { 556 self.dict.set("Filter", "FlateDecode"); 557 self.set_content(compressed); 558 } 559 } 560 Ok(()) 561 } 562 decompressed_content(&self) -> Result<Vec<u8>>563 pub fn decompressed_content(&self) -> Result<Vec<u8>> { 564 let params = self.dict.get(b"DecodeParms").and_then(Object::as_dict).ok(); 565 let filters = self.filters()?; 566 567 if self.dict.get(b"Subtype").and_then(Object::as_name_str).ok() == Some("Image") { 568 return Err(Error::Type); 569 } 570 571 let mut input = self.content.as_slice(); 572 let mut output = None; 573 574 // Filters are in decoding order. 575 for filter in filters { 576 output = Some(match filter.as_str() { 577 "FlateDecode" => Self::decompress_zlib(input, params)?, 578 "LZWDecode" => Self::decompress_lzw(input, params)?, 579 _ => { 580 return Err(Error::Type); 581 } 582 }); 583 input = output.as_ref().unwrap(); 584 } 585 586 output.ok_or(Error::Type) 587 } 588 decompress_lzw(input: &[u8], params: Option<&Dictionary>) -> Result<Vec<u8>>589 fn decompress_lzw(input: &[u8], params: Option<&Dictionary>) -> Result<Vec<u8>> { 590 use lzw::{Decoder, DecoderEarlyChange, MsbReader}; 591 const MIN_BITS: u8 = 9; 592 593 let early_change = params 594 .and_then(|p| p.get(b"EarlyChange").ok()) 595 .and_then(|p| Object::as_i64(p).ok()) 596 .map(|v| v != 0) 597 .unwrap_or(true); 598 599 let output = if early_change { 600 Self::decompress_lzw_loop( 601 input, 602 DecoderEarlyChange::new(MsbReader::new(), MIN_BITS - 1), 603 DecoderEarlyChange::decode_bytes, 604 ) 605 } else { 606 Self::decompress_lzw_loop( 607 input, 608 Decoder::new(MsbReader::new(), MIN_BITS - 1), 609 Decoder::decode_bytes, 610 ) 611 }; 612 613 Self::decompress_predictor(output, params) 614 } 615 decompress_lzw_loop<F, D>(mut input: &[u8], mut decoder: D, decode: F) -> Vec<u8> where F: for<'d> Fn(&'d mut D, &[u8]) -> std::io::Result<(usize, &'d [u8])>,616 fn decompress_lzw_loop<F, D>(mut input: &[u8], mut decoder: D, decode: F) -> Vec<u8> 617 where 618 F: for<'d> Fn(&'d mut D, &[u8]) -> std::io::Result<(usize, &'d [u8])>, 619 { 620 let mut output = Vec::with_capacity(input.len() * 2); 621 622 loop { 623 match decode(&mut decoder, input) { 624 Ok((consumed_bytes, out_bytes)) => { 625 output.extend(out_bytes); 626 input = &input[consumed_bytes..]; 627 if input.is_empty() || consumed_bytes == 0 { 628 break; 629 } 630 } 631 Err(err) => { 632 warn!("{}", err); 633 break; 634 } 635 } 636 } 637 638 output 639 } 640 decompress_zlib(input: &[u8], params: Option<&Dictionary>) -> Result<Vec<u8>>641 fn decompress_zlib(input: &[u8], params: Option<&Dictionary>) -> Result<Vec<u8>> { 642 use flate2::read::ZlibDecoder; 643 use std::io::prelude::*; 644 645 let mut output = Vec::with_capacity(input.len() * 2); 646 let mut decoder = ZlibDecoder::new(input); 647 648 if !input.is_empty() { 649 decoder.read_to_end(&mut output).unwrap_or_else(|err| { 650 warn!("{}", err); 651 0 652 }); 653 } 654 Self::decompress_predictor(output, params) 655 } 656 decompress_predictor(mut data: Vec<u8>, params: Option<&Dictionary>) -> Result<Vec<u8>>657 fn decompress_predictor(mut data: Vec<u8>, params: Option<&Dictionary>) -> Result<Vec<u8>> { 658 use crate::filters::png; 659 660 if let Some(params) = params { 661 let predictor = params.get(b"Predictor").and_then(Object::as_i64).unwrap_or(1); 662 if predictor >= 10 && predictor <= 15 { 663 let pixels_per_row = params.get(b"Columns").and_then(Object::as_i64).unwrap_or(1) as usize; 664 let colors = params.get(b"Colors").and_then(Object::as_i64).unwrap_or(1) as usize; 665 let bits = params.get(b"BitsPerComponent").and_then(Object::as_i64).unwrap_or(8) as usize; 666 let bytes_per_pixel = colors * bits / 8; 667 data = png::decode_frame(data.as_slice(), bytes_per_pixel, pixels_per_row)?; 668 } 669 Ok(data) 670 } else { 671 Ok(data) 672 } 673 } 674 decompress(&mut self)675 pub fn decompress(&mut self) { 676 if let Ok(data) = self.decompressed_content() { 677 self.dict.remove(b"DecodeParms"); 678 self.dict.remove(b"Filter"); 679 self.set_content(data); 680 } 681 } 682 } 683