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