1use super::objects::{PdfDictionary, PdfObject};
6use super::{ParseError, ParseOptions, ParseResult};
7
8#[cfg(feature = "compression")]
9use flate2::read::ZlibDecoder;
10use std::io::Read;
11
12use super::filter_impls::ccitt::decode_ccitt;
14use super::filter_impls::dct::decode_dct;
15use super::filter_impls::jbig2::decode_jbig2;
16pub use super::filter_impls::ccitt::decode_ccitt as decode_ccitt_public;
18pub use super::filter_impls::dct::{parse_jpeg_info, JpegColorSpace, JpegInfo};
19pub use super::filter_impls::jbig2::decode_jbig2 as decode_jbig2_public;
20
21#[derive(Debug, Clone, PartialEq)]
23pub enum Filter {
24 ASCIIHexDecode,
26
27 ASCII85Decode,
29
30 LZWDecode,
32
33 FlateDecode,
35
36 RunLengthDecode,
38
39 CCITTFaxDecode,
41
42 JBIG2Decode,
44
45 DCTDecode,
47
48 JPXDecode,
50
51 Crypt,
53}
54
55impl Filter {
56 pub fn from_name(name: &str) -> Option<Self> {
58 match name {
59 "ASCIIHexDecode" => Some(Filter::ASCIIHexDecode),
60 "ASCII85Decode" => Some(Filter::ASCII85Decode),
61 "LZWDecode" => Some(Filter::LZWDecode),
62 "FlateDecode" => Some(Filter::FlateDecode),
63 "RunLengthDecode" => Some(Filter::RunLengthDecode),
64 "CCITTFaxDecode" => Some(Filter::CCITTFaxDecode),
65 "JBIG2Decode" => Some(Filter::JBIG2Decode),
66 "DCTDecode" => Some(Filter::DCTDecode),
67 "JPXDecode" => Some(Filter::JPXDecode),
68 "Crypt" => Some(Filter::Crypt),
69 _ => None,
70 }
71 }
72}
73
74pub fn decode_stream(
76 data: &[u8],
77 dict: &PdfDictionary,
78 _options: &ParseOptions,
79) -> ParseResult<Vec<u8>> {
80 let filters = match dict.get("Filter") {
82 Some(PdfObject::Name(name)) => vec![name.as_str()],
83 Some(PdfObject::Array(array)) => {
84 let mut filter_names = Vec::new();
85 for obj in &array.0 {
86 if let PdfObject::Name(name) = obj {
87 filter_names.push(name.as_str());
88 } else {
89 return Err(ParseError::SyntaxError {
90 position: 0,
91 message: "Invalid filter in array".to_string(),
92 });
93 }
94 }
95 filter_names
96 }
97 None => {
98 return Ok(data.to_vec());
100 }
101 _ => {
102 return Err(ParseError::SyntaxError {
103 position: 0,
104 message: "Invalid Filter type".to_string(),
105 });
106 }
107 };
108
109 let decode_params = dict.get("DecodeParms");
111
112 let mut result = data.to_vec();
114 for (i, filter_name) in filters.iter().enumerate() {
115 let filter = Filter::from_name(filter_name).ok_or_else(|| ParseError::SyntaxError {
116 position: 0,
117 message: format!("Unknown filter: {filter_name}"),
118 })?;
119
120 let filter_params = get_filter_params(decode_params, i);
122
123 result = apply_filter_with_params(&result, filter, filter_params)?;
124 }
125
126 Ok(result)
127}
128
129#[allow(dead_code)]
131pub(crate) fn apply_filter(data: &[u8], filter: Filter) -> ParseResult<Vec<u8>> {
132 match filter {
133 Filter::FlateDecode => decode_flate(data),
134 Filter::ASCIIHexDecode => decode_ascii_hex(data),
135 Filter::ASCII85Decode => decode_ascii85(data),
136 Filter::LZWDecode => decode_lzw(data, None),
137 Filter::RunLengthDecode => decode_run_length(data),
138 Filter::CCITTFaxDecode => decode_ccitt(data, None),
139 Filter::JBIG2Decode => decode_jbig2(data, None),
140 Filter::DCTDecode => decode_dct(data),
141 _ => Err(ParseError::SyntaxError {
142 position: 0,
143 message: format!("Filter {filter:?} not yet implemented"),
144 }),
145 }
146}
147
148#[cfg(feature = "compression")]
150fn decode_flate(data: &[u8]) -> ParseResult<Vec<u8>> {
151 if let Ok(result) = try_standard_zlib_decode(data) {
153 return Ok(result);
154 }
155
156 if let Ok(result) = try_raw_deflate_decode(data) {
158 return Ok(result);
159 }
160
161 if data.len() > 10 {
163 for skip_bytes in 1..=5 {
164 if let Ok(result) = try_standard_zlib_decode(&data[skip_bytes..]) {
165 return Ok(result);
166 }
167 if let Ok(result) = try_raw_deflate_decode(&data[skip_bytes..]) {
168 return Ok(result);
169 }
170 }
171 }
172
173 if data.len() > 20 {
175 for truncate_bytes in 1..=10 {
176 let truncated = &data[..data.len() - truncate_bytes];
177 if let Ok(result) = try_standard_zlib_decode(truncated) {
178 return Ok(result);
179 }
180 if let Ok(result) = try_raw_deflate_decode(truncated) {
181 return Ok(result);
182 }
183 }
184 }
185
186 if let Ok(result) = try_gzip_decode(data) {
188 return Ok(result);
189 }
190
191 if let Ok(partial) = try_partial_flate_decode(data) {
193 tracing::debug!(
194 "Warning: Using partial FlateDecode recovery, {} bytes recovered",
195 partial.len()
196 );
197 return Ok(partial);
198 }
199
200 if data.len() > 20 {
202 for predictor in [10, 11, 12, 13, 14, 15] {
203 if let Ok(result) = try_flate_decode_with_predictor(data, predictor) {
204 tracing::debug!(
205 "Warning: FlateDecode succeeded with predictor {}",
206 predictor
207 );
208 return Ok(result);
209 }
210 }
211 }
212
213 tracing::debug!("Warning: All FlateDecode strategies failed, returning empty data");
215 Ok(Vec::new())
216}
217
218#[cfg(feature = "compression")]
219fn try_standard_zlib_decode(data: &[u8]) -> Result<Vec<u8>, std::io::Error> {
220 let mut decoder = ZlibDecoder::new(data);
221 let mut result = Vec::new();
222 decoder.read_to_end(&mut result)?;
223 Ok(result)
224}
225
226#[cfg(feature = "compression")]
227fn try_raw_deflate_decode(data: &[u8]) -> Result<Vec<u8>, std::io::Error> {
228 use flate2::read::DeflateDecoder;
229 let mut decoder = DeflateDecoder::new(data);
230 let mut result = Vec::new();
231 decoder.read_to_end(&mut result)?;
232 Ok(result)
233}
234
235#[cfg(feature = "compression")]
236fn try_gzip_decode(data: &[u8]) -> Result<Vec<u8>, std::io::Error> {
237 use flate2::read::GzDecoder;
238 let mut decoder = GzDecoder::new(data);
239 let mut result = Vec::new();
240 decoder.read_to_end(&mut result)?;
241 Ok(result)
242}
243
244#[cfg(feature = "compression")]
245fn try_partial_flate_decode(data: &[u8]) -> Result<Vec<u8>, std::io::Error> {
246 use flate2::read::ZlibDecoder;
247 use std::io::ErrorKind;
248
249 let mut decoder = ZlibDecoder::new(data);
251 let mut result = Vec::new();
252 let mut buffer = [0; 8192];
253
254 loop {
255 match decoder.read(&mut buffer) {
256 Ok(0) => break, Ok(n) => result.extend_from_slice(&buffer[..n]),
258 Err(e) if e.kind() == ErrorKind::UnexpectedEof => {
259 if !result.is_empty() {
261 return Ok(result);
262 }
263 return Err(e);
264 }
265 Err(e) => return Err(e),
266 }
267 }
268
269 if result.is_empty() {
270 Err(std::io::Error::new(
271 ErrorKind::InvalidData,
272 "No data decoded",
273 ))
274 } else {
275 Ok(result)
276 }
277}
278
279#[cfg(feature = "compression")]
280fn try_flate_decode_with_predictor(data: &[u8], predictor: u8) -> Result<Vec<u8>, std::io::Error> {
281 use flate2::read::ZlibDecoder;
282
283 let mut decoder = ZlibDecoder::new(data);
285 let mut raw_data = Vec::new();
286 decoder.read_to_end(&mut raw_data)?;
287
288 if predictor >= 10 && predictor <= 15 {
290 apply_png_predictor(&raw_data, predictor)
291 } else {
292 Ok(raw_data)
293 }
294}
295
296#[cfg(feature = "compression")]
297fn apply_png_predictor(data: &[u8], predictor: u8) -> Result<Vec<u8>, std::io::Error> {
298 if data.is_empty() {
299 return Ok(data.to_vec());
300 }
301
302 let common_widths = [1, 2, 3, 4, 8, 16, 24, 32, 48, 64, 96, 128];
305
306 for &width in &common_widths {
307 if let Ok(result) = apply_png_predictor_with_width(data, predictor, width) {
308 if result.len() > data.len() / 2 && result.len() < data.len() * 2 {
310 return Ok(result);
311 }
312 }
313 }
314
315 Ok(data.to_vec())
317}
318
319#[cfg(feature = "compression")]
320fn apply_png_predictor_with_width(
321 data: &[u8],
322 _predictor: u8,
323 width: usize,
324) -> Result<Vec<u8>, std::io::Error> {
325 use std::io::{Error, ErrorKind};
326
327 if width == 0 || data.len() % (width + 1) != 0 {
328 return Err(Error::new(ErrorKind::InvalidInput, "Invalid width"));
329 }
330
331 let mut result = Vec::new();
332 let row_len = width + 1; for row_data in data.chunks_exact(row_len) {
335 if row_data.is_empty() {
336 continue;
337 }
338
339 let predictor_byte = row_data[0];
340 let row = &row_data[1..];
341
342 match predictor_byte {
343 0 => {
344 result.extend_from_slice(row);
346 }
347 1 => {
348 result.push(row[0]);
350 for i in 1..row.len() {
351 let prev = if i >= width {
352 result[result.len() - width]
353 } else {
354 0
355 };
356 result.push(row[i].wrapping_add(prev));
357 }
358 }
359 2 => {
360 for i in 0..row.len() {
362 let up = if result.len() >= width {
363 result[result.len() - width + i]
364 } else {
365 0
366 };
367 result.push(row[i].wrapping_add(up));
368 }
369 }
370 _ => {
371 result.extend_from_slice(row);
373 }
374 }
375 }
376
377 Ok(result)
378}
379
380#[cfg(not(feature = "compression"))]
381fn decode_flate(_data: &[u8]) -> ParseResult<Vec<u8>> {
382 Err(ParseError::StreamDecodeError(
383 "FlateDecode requires 'compression' feature".to_string(),
384 ))
385}
386
387fn decode_ascii_hex(data: &[u8]) -> ParseResult<Vec<u8>> {
389 let mut result = Vec::new();
390 let mut chars = data.iter().filter(|&&b| !b.is_ascii_whitespace());
391
392 loop {
393 let high = match chars.next() {
394 Some(&b'>') => break, Some(&ch) => ch,
396 None => break,
397 };
398
399 let low = match chars.next() {
400 Some(&b'>') => {
401 b'0'
403 }
404 Some(&ch) => ch,
405 None => b'0', };
407
408 let high_val = hex_digit_value(high).ok_or_else(|| {
409 ParseError::StreamDecodeError(format!("Invalid hex digit: {}", high as char))
410 })?;
411 let low_val = hex_digit_value(low).ok_or_else(|| {
412 ParseError::StreamDecodeError(format!("Invalid hex digit: {}", low as char))
413 })?;
414
415 result.push((high_val << 4) | low_val);
416
417 if low == b'>' {
418 break;
419 }
420 }
421
422 Ok(result)
423}
424
425fn hex_digit_value(ch: u8) -> Option<u8> {
427 match ch {
428 b'0'..=b'9' => Some(ch - b'0'),
429 b'A'..=b'F' => Some(ch - b'A' + 10),
430 b'a'..=b'f' => Some(ch - b'a' + 10),
431 _ => None,
432 }
433}
434
435fn decode_ascii85(data: &[u8]) -> ParseResult<Vec<u8>> {
437 let mut result = Vec::new();
438 let mut chars = data.iter().filter(|&&b| !b.is_ascii_whitespace());
439 let mut group = Vec::with_capacity(5);
440
441 let mut ch = match chars.next() {
443 Some(&b'<') => {
444 if chars.next() == Some(&b'~') {
445 chars.next()
447 } else {
448 Some(&b'<')
450 }
451 }
452 other => other,
453 };
454
455 while let Some(&c) = ch {
456 match c {
457 b'~' => {
458 if chars.next() == Some(&b'>') {
460 break;
461 } else {
462 return Err(ParseError::StreamDecodeError(
463 "Invalid ASCII85 end marker".to_string(),
464 ));
465 }
466 }
467 b'z' if group.is_empty() => {
468 result.extend_from_slice(&[0, 0, 0, 0]);
470 }
471 b'!'..=b'u' => {
472 group.push(c);
473 if group.len() == 5 {
474 let value = group
476 .iter()
477 .enumerate()
478 .map(|(i, &ch)| (ch - b'!') as u32 * 85u32.pow(4 - i as u32))
479 .sum::<u32>();
480
481 result.push((value >> 24) as u8);
482 result.push((value >> 16) as u8);
483 result.push((value >> 8) as u8);
484 result.push(value as u8);
485
486 group.clear();
487 }
488 }
489 _ => {
490 return Err(ParseError::StreamDecodeError(format!(
491 "Invalid ASCII85 character: {}",
492 c as char
493 )));
494 }
495 }
496 ch = chars.next();
497 }
498
499 if !group.is_empty() {
501 let original_len = group.len();
503
504 while group.len() < 5 {
506 group.push(b'u');
507 }
508
509 let value = group
510 .iter()
511 .enumerate()
512 .map(|(i, &ch)| (ch - b'!') as u32 * 85u32.pow(4 - i as u32))
513 .sum::<u32>();
514
515 let output_bytes = original_len - 1;
517 for i in 0..output_bytes {
518 result.push((value >> (24 - 8 * i)) as u8);
519 }
520 }
521
522 Ok(result)
523}
524
525#[cfg(test)]
526mod tests {
527 use super::*;
528 use crate::parser::objects::{PdfArray, PdfDictionary, PdfName, PdfObject};
529
530 #[test]
531 fn test_ascii_hex_decode() {
532 let data = b"48656C6C6F>";
533 let result = decode_ascii_hex(data).unwrap();
534 assert_eq!(result, b"Hello");
535
536 let data = b"48 65 6C 6C 6F>"; let result = decode_ascii_hex(data).unwrap();
538 assert_eq!(result, b"Hello");
539
540 let data = b"48656C6C6>"; let result = decode_ascii_hex(data).unwrap();
542 assert_eq!(result, b"Hell`");
543 }
544
545 #[test]
546 fn test_ascii85_decode() {
547 let data = b"87cURD]j7BEbo80~>";
548 let result = decode_ascii85(data).unwrap();
549 assert_eq!(result, b"Hello world!");
550
551 let data = b"z~>"; let result = decode_ascii85(data).unwrap();
553 assert_eq!(result, &[0, 0, 0, 0]);
554 }
555
556 #[test]
557 fn test_filter_from_name() {
558 assert_eq!(
559 Filter::from_name("ASCIIHexDecode"),
560 Some(Filter::ASCIIHexDecode)
561 );
562 assert_eq!(
563 Filter::from_name("ASCII85Decode"),
564 Some(Filter::ASCII85Decode)
565 );
566 assert_eq!(Filter::from_name("LZWDecode"), Some(Filter::LZWDecode));
567 assert_eq!(Filter::from_name("FlateDecode"), Some(Filter::FlateDecode));
568 assert_eq!(
569 Filter::from_name("RunLengthDecode"),
570 Some(Filter::RunLengthDecode)
571 );
572 assert_eq!(
573 Filter::from_name("CCITTFaxDecode"),
574 Some(Filter::CCITTFaxDecode)
575 );
576 assert_eq!(Filter::from_name("JBIG2Decode"), Some(Filter::JBIG2Decode));
577 assert_eq!(Filter::from_name("DCTDecode"), Some(Filter::DCTDecode));
578 assert_eq!(Filter::from_name("JPXDecode"), Some(Filter::JPXDecode));
579 assert_eq!(Filter::from_name("Crypt"), Some(Filter::Crypt));
580 assert_eq!(Filter::from_name("UnknownFilter"), None);
581 }
582
583 #[test]
584 fn test_filter_equality() {
585 assert_eq!(Filter::ASCIIHexDecode, Filter::ASCIIHexDecode);
586 assert_ne!(Filter::ASCIIHexDecode, Filter::ASCII85Decode);
587 assert_ne!(Filter::FlateDecode, Filter::LZWDecode);
588 }
589
590 #[test]
591 fn test_filter_clone() {
592 let filter = Filter::FlateDecode;
593 let cloned = filter.clone();
594 assert_eq!(filter, cloned);
595 }
596
597 #[test]
598 fn test_decode_stream_no_filter() {
599 let data = b"Hello, world!";
600 let dict = PdfDictionary::new();
601
602 let result = decode_stream(data, &dict, &ParseOptions::default()).unwrap();
603 assert_eq!(result, data);
604 }
605
606 #[test]
607 fn test_decode_stream_single_filter() {
608 let data = b"48656C6C6F>";
609 let mut dict = PdfDictionary::new();
610 dict.insert(
611 "Filter".to_string(),
612 PdfObject::Name(PdfName("ASCIIHexDecode".to_string())),
613 );
614
615 let result = decode_stream(data, &dict, &ParseOptions::default()).unwrap();
616 assert_eq!(result, b"Hello");
617 }
618
619 #[test]
620 fn test_decode_stream_invalid_filter() {
621 let data = b"test data";
622 let mut dict = PdfDictionary::new();
623 dict.insert(
624 "Filter".to_string(),
625 PdfObject::Name(PdfName("UnknownFilter".to_string())),
626 );
627
628 let result = decode_stream(data, &dict, &ParseOptions::default());
629 assert!(result.is_err());
630 }
631
632 #[test]
633 fn test_decode_stream_filter_array() {
634 let data = b"48656C6C6F>";
635 let mut dict = PdfDictionary::new();
636 let filters = vec![PdfObject::Name(PdfName("ASCIIHexDecode".to_string()))];
637 dict.insert("Filter".to_string(), PdfObject::Array(PdfArray(filters)));
638
639 let result = decode_stream(data, &dict, &ParseOptions::default()).unwrap();
640 assert_eq!(result, b"Hello");
641 }
642
643 #[test]
644 fn test_decode_stream_invalid_filter_type() {
645 let data = b"test data";
646 let mut dict = PdfDictionary::new();
647 dict.insert("Filter".to_string(), PdfObject::Integer(42)); let result = decode_stream(data, &dict, &ParseOptions::default());
650 assert!(result.is_err());
651 }
652
653 #[test]
654 fn test_ascii_hex_decode_empty() {
655 let data = b">";
656 let result = decode_ascii_hex(data).unwrap();
657 assert!(result.is_empty());
658 }
659
660 #[test]
661 fn test_ascii_hex_decode_invalid() {
662 let data = b"GG>"; let result = decode_ascii_hex(data);
664 assert!(result.is_err());
665 }
666
667 #[test]
668 fn test_ascii_hex_decode_no_terminator() {
669 let data = b"48656C6C6F"; let result = decode_ascii_hex(data).unwrap();
671 assert_eq!(result, b"Hello"); }
673
674 #[test]
675 fn test_ascii85_decode_empty() {
676 let data = b"~>";
677 let result = decode_ascii85(data).unwrap();
678 assert!(result.is_empty());
679 }
680
681 #[test]
682 fn test_ascii85_decode_invalid() {
683 let data = b"invalid~>";
684 let result = decode_ascii85(data);
685 assert!(result.is_err());
686 }
687
688 #[cfg(feature = "compression")]
689 #[test]
690 fn test_flate_decode() {
691 use flate2::write::ZlibEncoder;
692 use flate2::Compression;
693 use std::io::Write;
694
695 let original = b"Hello, compressed world!";
696 let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
697 encoder.write_all(original).unwrap();
698 let compressed = encoder.finish().unwrap();
699
700 let result = decode_flate(&compressed).unwrap();
701 assert_eq!(result, original);
702 }
703
704 #[cfg(not(feature = "compression"))]
705 #[test]
706 fn test_flate_decode_not_supported() {
707 let data = b"compressed data";
708 let result = decode_flate(data);
709 assert!(result.is_err());
710 }
711
712 #[test]
713 fn test_apply_filter() {
714 let data = b"48656C6C6F>";
715 let result = apply_filter(data, Filter::ASCIIHexDecode).unwrap();
716 assert_eq!(result, b"Hello");
717 }
718
719 #[test]
720 fn test_apply_filter_unsupported() {
721 let data = b"test data";
722 let unsupported_filters = vec![Filter::JPXDecode, Filter::Crypt];
723
724 for filter in unsupported_filters {
725 let result = apply_filter(data, filter);
726 assert!(result.is_err());
727 }
728 }
729
730 #[test]
731 fn test_apply_filter_dct_decode() {
732 let invalid_data = b"not jpeg data";
734 let result = apply_filter(invalid_data, Filter::DCTDecode);
735 assert!(result.is_err()); let valid_jpeg = vec![
739 0xFF, 0xD8, 0xFF, 0xD9, ];
742 let result = apply_filter(&valid_jpeg, Filter::DCTDecode);
743 assert!(result.is_ok());
744 assert_eq!(result.unwrap(), valid_jpeg); }
746
747 #[test]
750 fn test_apply_filter_with_params_no_predictor() {
751 let data = b"48656C6C6F>";
752 let dict = PdfDictionary::new();
753
754 let result = apply_filter_with_params(data, Filter::ASCIIHexDecode, Some(&dict)).unwrap();
755 assert_eq!(result, b"Hello");
756 }
757
758 #[test]
759 fn test_apply_predictor_none() {
760 let data = vec![1, 2, 3, 4];
761 let dict = PdfDictionary::new();
762
763 let result = apply_predictor(&data, 1, &dict).unwrap();
764 assert_eq!(result, data);
765 }
766
767 #[test]
768 fn test_apply_predictor_unknown() {
769 let data = vec![1, 2, 3, 4];
770 let dict = PdfDictionary::new();
771
772 let result = apply_predictor(&data, 99, &dict).unwrap();
774 assert_eq!(result, data);
775 }
776
777 #[test]
778 fn test_png_predictor_sub_filter() {
779 let data = vec![1, 5, 10]; let result = apply_png_sub_filter(&data, 1);
782 assert_eq!(result, vec![1, 6, 16]); }
784
785 #[test]
786 fn test_png_predictor_up_filter() {
787 let data = vec![1, 2, 3];
789 let prev_row = vec![5, 10, 15];
790 let result = apply_png_up_filter(&data, Some(&prev_row));
791 assert_eq!(result, vec![6, 12, 18]); }
793
794 #[test]
795 fn test_png_predictor_up_filter_no_prev() {
796 let data = vec![1, 2, 3];
798 let result = apply_png_up_filter(&data, None);
799 assert_eq!(result, vec![1, 2, 3]); }
801
802 #[test]
803 fn test_png_predictor_average_filter() {
804 let data = vec![2, 4]; let prev_row = vec![6, 8];
807 let result = apply_png_average_filter(&data, Some(&prev_row), 1);
808 assert_eq!(result, vec![5, 10]);
811 }
812
813 #[test]
814 fn test_png_predictor_paeth_filter() {
815 let data = vec![1, 2]; let prev_row = vec![3, 4];
818 let result = apply_png_paeth_filter(&data, Some(&prev_row), 1);
819 assert_eq!(result.len(), 2);
821 }
822
823 #[test]
824 fn test_paeth_predictor_algorithm() {
825 assert_eq!(paeth_predictor(1, 2, 0), 2);
829
830 assert_eq!(paeth_predictor(5, 2, 3), 5);
833
834 assert_eq!(paeth_predictor(5, 8, 3), 8);
837 }
838
839 #[test]
840 fn test_apply_png_predictor_invalid_data() {
841 let mut params = PdfDictionary::new();
842 params.insert("Columns".to_string(), PdfObject::Integer(3));
843
844 let data = vec![0, 1, 2, 3, 4, 5]; let result = apply_png_predictor_with_width(&data, 10, 3);
847 assert!(result.is_err());
848 }
849
850 #[test]
851 fn test_apply_png_predictor_valid_simple() {
852 let mut params = PdfDictionary::new();
853 params.insert("Columns".to_string(), PdfObject::Integer(2));
854 params.insert("BitsPerComponent".to_string(), PdfObject::Integer(8));
855 params.insert("Colors".to_string(), PdfObject::Integer(1));
856
857 let data = vec![
859 0, 1, 2, 0, 3, 4, ];
862
863 let result = apply_png_predictor_with_width(&data, 10, 2).unwrap();
864 assert_eq!(result, vec![1, 2, 3, 4]);
865 }
866
867 #[test]
868 fn test_apply_png_predictor_with_sub_filter() {
869 let mut params = PdfDictionary::new();
870 params.insert("Columns".to_string(), PdfObject::Integer(3));
871 params.insert("BitsPerComponent".to_string(), PdfObject::Integer(8));
872 params.insert("Colors".to_string(), PdfObject::Integer(1));
873
874 let data = vec![
876 1, 1, 2, 3, ];
878
879 let result = apply_png_predictor_with_width(&data, 10, 3).unwrap();
880 assert_eq!(result, vec![1, 2, 3]); }
883
884 #[test]
885 fn test_apply_png_predictor_invalid_filter_type() {
886 let mut params = PdfDictionary::new();
887 params.insert("Columns".to_string(), PdfObject::Integer(2));
888
889 let data = vec![5, 1, 2];
891 let result = apply_png_predictor_with_width(&data, 10, 2);
892 if result.is_err() {
894 let error_msg = result.unwrap_err().to_string();
896 assert!(
897 error_msg.contains("filter")
898 || error_msg.contains("predictor")
899 || error_msg.contains("Invalid")
900 );
901 } else {
902 let _decoded_data = result.unwrap();
904 }
905 }
906
907 #[test]
908 fn test_get_filter_params_dict() {
909 let mut dict = PdfDictionary::new();
910 dict.insert("Predictor".to_string(), PdfObject::Integer(12));
911 let obj = PdfObject::Dictionary(dict);
912
913 let result = get_filter_params(Some(&obj), 0);
914 assert!(result.is_some());
915 assert_eq!(
916 result.unwrap().get("Predictor"),
917 Some(&PdfObject::Integer(12))
918 );
919 }
920
921 #[test]
922 fn test_get_filter_params_array() {
923 let mut inner_dict = PdfDictionary::new();
924 inner_dict.insert("Predictor".to_string(), PdfObject::Integer(15));
925
926 let array = vec![PdfObject::Dictionary(inner_dict)];
927 let obj = PdfObject::Array(crate::parser::objects::PdfArray(array));
928
929 let result = get_filter_params(Some(&obj), 0);
930 assert!(result.is_some());
931 assert_eq!(
932 result.unwrap().get("Predictor"),
933 Some(&PdfObject::Integer(15))
934 );
935 }
936
937 #[test]
938 fn test_get_filter_params_none() {
939 let result = get_filter_params(None, 0);
940 assert!(result.is_none());
941 }
942
943 #[test]
944 fn test_compressed_xref_integration() {
945 use flate2::write::ZlibEncoder;
947 use flate2::Compression;
948 use std::io::Write;
949
950 #[cfg(feature = "compression")]
951 {
952 let original_data = vec![
954 0, 1, 2, 0, 3, 4, ];
957
958 let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
960 encoder.write_all(&original_data).unwrap();
961 let compressed = encoder.finish().unwrap();
962
963 let mut decode_params = PdfDictionary::new();
965 decode_params.insert("Predictor".to_string(), PdfObject::Integer(12)); decode_params.insert("Columns".to_string(), PdfObject::Integer(2));
967 decode_params.insert("BitsPerComponent".to_string(), PdfObject::Integer(8));
968 decode_params.insert("Colors".to_string(), PdfObject::Integer(1));
969
970 let result =
972 apply_filter_with_params(&compressed, Filter::FlateDecode, Some(&decode_params))
973 .unwrap();
974 assert_eq!(result, vec![1, 2, 3, 4]);
975 }
976 }
977
978 fn encode_lzw_test_data(codes: &[u16]) -> Vec<u8> {
982 let mut result = Vec::new();
983 let mut bit_buffer = 0u32;
984 let mut bits_in_buffer = 0;
985 let mut code_size = 9;
986
987 for &code in codes {
988 bit_buffer = (bit_buffer << code_size) | (code as u32);
990 bits_in_buffer += code_size;
991
992 while bits_in_buffer >= 8 {
994 let byte = ((bit_buffer >> (bits_in_buffer - 8)) & 0xFF) as u8;
995 result.push(byte);
996 bits_in_buffer -= 8;
997 }
998
999 if code == 511 && code_size == 9 {
1001 code_size = 10;
1002 } else if code == 1023 && code_size == 10 {
1003 code_size = 11;
1004 } else if code == 2047 && code_size == 11 {
1005 code_size = 12;
1006 }
1007 }
1008
1009 if bits_in_buffer > 0 {
1011 let byte = ((bit_buffer << (8 - bits_in_buffer)) & 0xFF) as u8;
1012 result.push(byte);
1013 }
1014
1015 result
1016 }
1017
1018 #[test]
1019 fn test_lzw_decode_simple() {
1020 let codes = vec![65, 66, 67, 257];
1023 let data = encode_lzw_test_data(&codes);
1024 let result = decode_lzw(&data, None).unwrap();
1025 assert_eq!(result, b"ABC");
1026 }
1027
1028 #[test]
1029 fn test_lzw_decode_with_repetition() {
1030 let codes = vec![65, 65, 258, 257];
1033 let data = encode_lzw_test_data(&codes);
1034 let result = decode_lzw(&data, None).unwrap();
1035 assert_eq!(result, b"AAAA");
1036 }
1037
1038 #[test]
1039 fn test_lzw_decode_clear_code() {
1040 let codes = vec![65, 66, 256, 67, 68, 257];
1043 let data = encode_lzw_test_data(&codes);
1044 let result = decode_lzw(&data, None).unwrap();
1045 assert_eq!(result, b"ABCD");
1046 }
1047
1048 #[test]
1049 fn test_lzw_decode_growing_codes() {
1050 let mut params = PdfDictionary::new();
1054 params.insert("EarlyChange".to_string(), PdfObject::Integer(1));
1055
1056 let data = vec![0x08, 0x21, 0x08, 0x61, 0x08, 0x20, 0x80];
1058 let result = decode_lzw(&data, Some(¶ms));
1059 assert!(result.is_ok());
1060 }
1061
1062 #[test]
1063 fn test_lzw_decode_early_change_false() {
1064 let mut params = PdfDictionary::new();
1065 params.insert("EarlyChange".to_string(), PdfObject::Integer(0));
1066
1067 let codes = vec![65, 66, 67, 257];
1069 let data = encode_lzw_test_data(&codes);
1070 let result = decode_lzw(&data, Some(¶ms)).unwrap();
1071 assert_eq!(result, b"ABC");
1072 }
1073
1074 #[test]
1075 fn test_lzw_decode_invalid_code() {
1076 let data = vec![0x08, 0x21, 0xFF, 0xFF, 0x00];
1078 let result = decode_lzw(&data, None);
1079 assert!(result.is_err());
1080 }
1081
1082 #[test]
1083 fn test_lzw_decode_empty() {
1084 let codes = vec![257];
1086 let data = encode_lzw_test_data(&codes);
1087 let result = decode_lzw(&data, None).unwrap();
1088 assert!(result.is_empty());
1089 }
1090
1091 #[test]
1092 fn test_lzw_bit_reader() {
1093 let data = vec![0b10101010, 0b11001100, 0b11110000];
1094 let mut reader = LzwBitReader::new(&data);
1095
1096 assert_eq!(reader.read_bits(4), Some(0b1010));
1098
1099 assert_eq!(reader.read_bits(8), Some(0b10101100));
1101
1102 assert_eq!(reader.read_bits(6), Some(0b110011));
1104
1105 assert_eq!(reader.read_bits(6), Some(0b110000));
1107
1108 assert_eq!(reader.read_bits(8), None);
1110 }
1111
1112 #[test]
1113 fn test_lzw_bit_reader_edge_cases() {
1114 let data = vec![0xFF];
1115 let mut reader = LzwBitReader::new(&data);
1116
1117 assert_eq!(reader.read_bits(0), None);
1119
1120 assert_eq!(reader.read_bits(17), None);
1122
1123 assert_eq!(reader.read_bits(8), Some(0xFF));
1125
1126 assert_eq!(reader.read_bits(1), None);
1128 }
1129
1130 #[test]
1131 fn test_apply_filter_lzw() {
1132 let codes = vec![65, 66, 67, 257];
1134 let data = encode_lzw_test_data(&codes);
1135 let result = apply_filter(&data, Filter::LZWDecode).unwrap();
1136 assert_eq!(result, b"ABC");
1137 }
1138
1139 #[test]
1140 fn test_apply_filter_with_params_lzw() {
1141 let mut params = PdfDictionary::new();
1143 params.insert("EarlyChange".to_string(), PdfObject::Integer(0));
1144
1145 let codes = vec![65, 66, 67, 257];
1146 let data = encode_lzw_test_data(&codes);
1147 let result = apply_filter_with_params(&data, Filter::LZWDecode, Some(¶ms)).unwrap();
1148 assert_eq!(result, b"ABC");
1149 }
1150
1151 #[test]
1154 fn test_run_length_decode_literal() {
1155 let data = vec![2, b'A', b'B', b'C'];
1157 let result = decode_run_length(&data).unwrap();
1158 assert_eq!(result, b"ABC");
1159 }
1160
1161 #[test]
1162 fn test_run_length_decode_repeat() {
1163 let data = vec![253u8, b'X']; let result = decode_run_length(&data).unwrap();
1166 assert_eq!(result, b"XXXX");
1167 }
1168
1169 #[test]
1170 fn test_run_length_decode_mixed() {
1171 let data = vec![
1173 1, b'A', b'B', 254u8, b'C', 1, b'D', b'E', ];
1177 let result = decode_run_length(&data).unwrap();
1178 assert_eq!(result, b"ABCCCDE");
1179 }
1180
1181 #[test]
1182 fn test_run_length_decode_eod() {
1183 let data = vec![0, b'A', 128u8, 1, b'B', b'C']; let result = decode_run_length(&data).unwrap();
1186 assert_eq!(result, b"A"); }
1188
1189 #[test]
1190 fn test_run_length_decode_empty() {
1191 let data = vec![];
1193 let result = decode_run_length(&data).unwrap();
1194 assert!(result.is_empty());
1195 }
1196
1197 #[test]
1198 fn test_run_length_decode_single_literal() {
1199 let data = vec![0, b'Z'];
1201 let result = decode_run_length(&data).unwrap();
1202 assert_eq!(result, b"Z");
1203 }
1204
1205 #[test]
1206 fn test_run_length_decode_single_repeat() {
1207 let data = vec![255u8, b'Y']; let result = decode_run_length(&data).unwrap();
1210 assert_eq!(result, b"YY");
1211 }
1212
1213 #[test]
1214 fn test_run_length_decode_max_repeat() {
1215 let data = vec![129u8, b'M']; let result = decode_run_length(&data).unwrap();
1218 assert_eq!(result.len(), 128);
1219 assert!(result.iter().all(|&b| b == b'M'));
1220 }
1221
1222 #[test]
1223 fn test_run_length_decode_max_literal() {
1224 let mut data = vec![127];
1226 data.extend((0..128).map(|i| i as u8));
1227 let result = decode_run_length(&data).unwrap();
1228 assert_eq!(result.len(), 128);
1229 assert_eq!(result, (0..128).map(|i| i as u8).collect::<Vec<u8>>());
1230 }
1231
1232 #[test]
1233 fn test_run_length_decode_error_literal_overflow() {
1234 let data = vec![5, b'A', b'B']; let result = decode_run_length(&data);
1237 assert!(result.is_err());
1238 }
1239
1240 #[test]
1241 fn test_run_length_decode_error_missing_repeat_byte() {
1242 let data = vec![254u8]; let result = decode_run_length(&data);
1245 assert!(result.is_err());
1246 }
1247
1248 #[test]
1249 fn test_apply_filter_run_length() {
1250 let data = vec![2, b'X', b'Y', b'Z'];
1252 let result = apply_filter(&data, Filter::RunLengthDecode).unwrap();
1253 assert_eq!(result, b"XYZ");
1254 }
1255
1256 #[test]
1257 fn test_apply_filter_with_params_run_length() {
1258 let data = vec![254u8, b'A', 1, b'B', b'C']; let result = apply_filter_with_params(&data, Filter::RunLengthDecode, None).unwrap();
1261 assert_eq!(result, b"AAABC");
1262 }
1263}
1264
1265pub(crate) fn apply_filter_with_params(
1267 data: &[u8],
1268 filter: Filter,
1269 params: Option<&PdfDictionary>,
1270) -> ParseResult<Vec<u8>> {
1271 let result = match filter {
1272 Filter::FlateDecode => {
1273 if let Some(decode_params) = params {
1277 if decode_params
1278 .get("Predictor")
1279 .and_then(|p| p.as_integer())
1280 .is_some()
1281 {
1282 match try_standard_zlib_decode(data) {
1284 Ok(decoded) => decoded,
1285 Err(_) => {
1286 data.to_vec()
1289 }
1290 }
1291 } else {
1292 decode_flate(data)?
1293 }
1294 } else {
1295 decode_flate(data)?
1296 }
1297 }
1298 Filter::ASCIIHexDecode => decode_ascii_hex(data)?,
1299 Filter::ASCII85Decode => decode_ascii85(data)?,
1300 Filter::LZWDecode => decode_lzw(data, params)?,
1301 Filter::RunLengthDecode => decode_run_length(data)?,
1302 Filter::CCITTFaxDecode => decode_ccitt(data, params)?,
1303 Filter::JBIG2Decode => decode_jbig2(data, params)?,
1304 Filter::DCTDecode => decode_dct(data)?,
1305 _ => {
1306 return Err(ParseError::SyntaxError {
1307 position: 0,
1308 message: format!("Filter {filter:?} not yet implemented"),
1309 });
1310 }
1311 };
1312
1313 if let Some(params_dict) = params {
1315 if let Some(predictor_obj) = params_dict.get("Predictor") {
1316 if let Some(predictor) = predictor_obj.as_integer() {
1317 match apply_predictor(&result, predictor as u32, params_dict) {
1318 Ok(predictor_result) => return Ok(predictor_result),
1319 Err(_) => {
1320 return Ok(result);
1323 }
1324 }
1325 }
1326 }
1327 }
1328
1329 Ok(result)
1330}
1331
1332fn get_filter_params(decode_params: Option<&PdfObject>, _index: usize) -> Option<&PdfDictionary> {
1334 match decode_params {
1335 Some(PdfObject::Dictionary(dict)) => Some(dict),
1336 Some(PdfObject::Array(array)) => {
1337 array.0.first().and_then(|obj| obj.as_dict())
1340 }
1341 _ => None,
1342 }
1343}
1344
1345fn apply_predictor(data: &[u8], predictor: u32, params: &PdfDictionary) -> ParseResult<Vec<u8>> {
1347 match predictor {
1348 1 => {
1349 Ok(data.to_vec())
1351 }
1352 10..=15 => {
1353 apply_png_predictor_advanced(data, predictor, params)
1355 }
1356 _ => {
1357 #[cfg(debug_assertions)]
1359 tracing::debug!("Warning: Unknown predictor {predictor}, returning data as-is");
1360 Ok(data.to_vec())
1361 }
1362 }
1363}
1364
1365fn apply_png_predictor_advanced(
1367 data: &[u8],
1368 _predictor: u32,
1369 params: &PdfDictionary,
1370) -> ParseResult<Vec<u8>> {
1371 let columns = params
1373 .get("Columns")
1374 .and_then(|obj| obj.as_integer())
1375 .unwrap_or(1) as usize;
1376
1377 let bpc = params
1379 .get("BitsPerComponent")
1380 .and_then(|obj| obj.as_integer())
1381 .unwrap_or(8) as usize;
1382
1383 let colors = params
1385 .get("Colors")
1386 .and_then(|obj| obj.as_integer())
1387 .unwrap_or(1) as usize;
1388
1389 let bytes_per_pixel = (bpc * colors).div_ceil(8);
1391
1392 let row_size = columns + 1;
1394
1395 if data.len() % row_size != 0 {
1396 return Err(ParseError::StreamDecodeError(
1397 "PNG predictor: data length not multiple of row size".to_string(),
1398 ));
1399 }
1400
1401 let num_rows = data.len() / row_size;
1402 let mut result = Vec::with_capacity(columns * num_rows);
1403
1404 for row in 0..num_rows {
1405 let row_start = row * row_size;
1406 let predictor_byte = data[row_start];
1407 let row_data = &data[row_start + 1..row_start + row_size];
1408
1409 let filtered_row = match predictor_byte {
1411 0 => {
1412 row_data.to_vec()
1414 }
1415 1 => {
1416 apply_png_sub_filter(row_data, bytes_per_pixel)
1418 }
1419 2 => {
1420 let prev_row = if row > 0 {
1422 Some(&result[(row - 1) * columns..row * columns])
1423 } else {
1424 None
1425 };
1426 apply_png_up_filter(row_data, prev_row)
1427 }
1428 3 => {
1429 let prev_row = if row > 0 {
1431 Some(&result[(row - 1) * columns..row * columns])
1432 } else {
1433 None
1434 };
1435 apply_png_average_filter(row_data, prev_row, bytes_per_pixel)
1436 }
1437 4 => {
1438 let prev_row = if row > 0 {
1440 Some(&result[(row - 1) * columns..row * columns])
1441 } else {
1442 None
1443 };
1444 apply_png_paeth_filter(row_data, prev_row, bytes_per_pixel)
1445 }
1446 _ => {
1447 return Err(ParseError::StreamDecodeError(format!(
1448 "PNG predictor: unknown filter type {predictor_byte}"
1449 )));
1450 }
1451 };
1452
1453 result.extend_from_slice(&filtered_row);
1454 }
1455
1456 Ok(result)
1457}
1458
1459fn apply_png_sub_filter(data: &[u8], bytes_per_pixel: usize) -> Vec<u8> {
1461 let mut result = Vec::with_capacity(data.len());
1462
1463 for (i, &byte) in data.iter().enumerate() {
1464 if i < bytes_per_pixel {
1465 result.push(byte);
1466 } else {
1467 result.push(byte.wrapping_add(result[i - bytes_per_pixel]));
1468 }
1469 }
1470
1471 result
1472}
1473
1474fn apply_png_up_filter(data: &[u8], prev_row: Option<&[u8]>) -> Vec<u8> {
1476 let mut result = Vec::with_capacity(data.len());
1477
1478 for (i, &byte) in data.iter().enumerate() {
1479 let up_byte = prev_row.and_then(|row| row.get(i)).unwrap_or(&0);
1480 result.push(byte.wrapping_add(*up_byte));
1481 }
1482
1483 result
1484}
1485
1486fn apply_png_average_filter(
1488 data: &[u8],
1489 prev_row: Option<&[u8]>,
1490 bytes_per_pixel: usize,
1491) -> Vec<u8> {
1492 let mut result = Vec::with_capacity(data.len());
1493
1494 for (i, &byte) in data.iter().enumerate() {
1495 let left_byte = if i < bytes_per_pixel {
1496 0
1497 } else {
1498 result[i - bytes_per_pixel]
1499 };
1500 let up_byte = prev_row.and_then(|row| row.get(i)).unwrap_or(&0);
1501 let average = ((left_byte as u16 + *up_byte as u16) / 2) as u8;
1502 result.push(byte.wrapping_add(average));
1503 }
1504
1505 result
1506}
1507
1508fn apply_png_paeth_filter(data: &[u8], prev_row: Option<&[u8]>, bytes_per_pixel: usize) -> Vec<u8> {
1510 let mut result = Vec::with_capacity(data.len());
1511
1512 for (i, &byte) in data.iter().enumerate() {
1513 let left_byte = if i < bytes_per_pixel {
1514 0
1515 } else {
1516 result[i - bytes_per_pixel]
1517 };
1518 let up_byte = prev_row.and_then(|row| row.get(i)).unwrap_or(&0);
1519 let up_left_byte = if i < bytes_per_pixel {
1520 0
1521 } else {
1522 *prev_row
1523 .and_then(|row| row.get(i - bytes_per_pixel))
1524 .unwrap_or(&0)
1525 };
1526
1527 let paeth = paeth_predictor(left_byte, *up_byte, up_left_byte);
1528 result.push(byte.wrapping_add(paeth));
1529 }
1530
1531 result
1532}
1533
1534fn paeth_predictor(left: u8, up: u8, up_left: u8) -> u8 {
1536 let p = left as i16 + up as i16 - up_left as i16;
1537 let pa = (p - left as i16).abs();
1538 let pb = (p - up as i16).abs();
1539 let pc = (p - up_left as i16).abs();
1540
1541 if pa <= pb && pa <= pc {
1542 left
1543 } else if pb <= pc {
1544 up
1545 } else {
1546 up_left
1547 }
1548}
1549
1550fn decode_lzw(data: &[u8], params: Option<&PdfDictionary>) -> ParseResult<Vec<u8>> {
1556 let early_change = params
1558 .and_then(|p| p.get("EarlyChange"))
1559 .and_then(|v| v.as_integer())
1560 .map(|v| v != 0)
1561 .unwrap_or(true); const MIN_BITS: u32 = 9;
1565 const MAX_BITS: u32 = 12;
1566 const CLEAR_CODE: u16 = 256;
1567 const EOD_CODE: u16 = 257;
1568 #[allow(dead_code)]
1569 const FIRST_CODE: u16 = 258;
1570
1571 let mut dictionary: Vec<Vec<u8>> = Vec::with_capacity(4096);
1573 for i in 0..=255 {
1574 dictionary.push(vec![i]);
1575 }
1576 dictionary.push(vec![]); dictionary.push(vec![]); let mut result = Vec::new();
1581 let mut bit_reader = LzwBitReader::new(data);
1582 let mut code_size = MIN_BITS;
1583 let mut prev_code: Option<u16> = None;
1584
1585 while let Some(c) = bit_reader.read_bits(code_size) {
1586 let code = c as u16;
1587
1588 if code == EOD_CODE {
1589 break;
1590 }
1591
1592 if code == CLEAR_CODE {
1593 dictionary.truncate(258);
1595 code_size = MIN_BITS;
1596 prev_code = None;
1597 continue;
1598 }
1599
1600 if let Some(prev) = prev_code {
1602 let string = if (code as usize) < dictionary.len() {
1603 dictionary[code as usize].clone()
1605 } else if code as usize == dictionary.len() {
1606 let mut s = dictionary[prev as usize].clone();
1608 s.push(dictionary[prev as usize][0]);
1609 s
1610 } else {
1611 return Err(ParseError::StreamDecodeError(format!(
1612 "LZW decode error: invalid code {code}"
1613 )));
1614 };
1615
1616 result.extend_from_slice(&string);
1618
1619 if dictionary.len() < 4096 {
1621 let mut new_entry = dictionary[prev as usize].clone();
1622 new_entry.push(string[0]);
1623 dictionary.push(new_entry);
1624
1625 let dict_size = dictionary.len();
1627 let threshold = if early_change {
1628 1 << code_size
1629 } else {
1630 (1 << code_size) + 1
1631 };
1632
1633 if dict_size >= threshold as usize && code_size < MAX_BITS {
1634 code_size += 1;
1635 }
1636 }
1637 } else {
1638 if (code as usize) < dictionary.len() {
1640 result.extend_from_slice(&dictionary[code as usize]);
1641 } else {
1642 return Err(ParseError::StreamDecodeError(format!(
1643 "LZW decode error: invalid first code {code}"
1644 )));
1645 }
1646 }
1647
1648 prev_code = Some(code);
1649 }
1650
1651 Ok(result)
1652}
1653
1654struct LzwBitReader<'a> {
1656 data: &'a [u8],
1657 byte_pos: usize,
1658 bit_pos: u8,
1659}
1660
1661impl<'a> LzwBitReader<'a> {
1662 fn new(data: &'a [u8]) -> Self {
1663 Self {
1664 data,
1665 byte_pos: 0,
1666 bit_pos: 0,
1667 }
1668 }
1669
1670 fn read_bits(&mut self, n: u32) -> Option<u32> {
1672 if n == 0 || n > 16 {
1673 return None;
1674 }
1675
1676 let mut result = 0u32;
1677 let mut bits_read = 0;
1678
1679 while bits_read < n {
1680 if self.byte_pos >= self.data.len() {
1681 return None;
1682 }
1683
1684 let bits_available = 8 - self.bit_pos;
1685 let bits_to_read = (n - bits_read).min(bits_available as u32);
1686
1687 let mask = ((1u32 << bits_to_read) - 1) as u8;
1689 let shift = bits_available - bits_to_read as u8;
1690 let bits = (self.data[self.byte_pos] >> shift) & mask;
1691
1692 result = (result << bits_to_read) | (bits as u32);
1693 bits_read += bits_to_read;
1694 self.bit_pos += bits_to_read as u8;
1695
1696 if self.bit_pos >= 8 {
1697 self.bit_pos = 0;
1698 self.byte_pos += 1;
1699 }
1700 }
1701
1702 Some(result)
1703 }
1704}
1705
1706fn decode_run_length(data: &[u8]) -> ParseResult<Vec<u8>> {
1711 let mut result = Vec::new();
1712 let mut i = 0;
1713
1714 while i < data.len() {
1715 let length = data[i] as i8;
1716 i += 1;
1717
1718 if length == -128 {
1719 break;
1721 } else if length >= 0 {
1722 let count = (length as usize) + 1;
1724 if i + count > data.len() {
1725 return Err(ParseError::StreamDecodeError(
1726 "RunLength decode error: insufficient data for literal copy".to_string(),
1727 ));
1728 }
1729 result.extend_from_slice(&data[i..i + count]);
1730 i += count;
1731 } else {
1732 if i >= data.len() {
1734 return Err(ParseError::StreamDecodeError(
1735 "RunLength decode error: missing byte to repeat".to_string(),
1736 ));
1737 }
1738 let repeat_byte = data[i];
1739 let count = ((-length) as usize) + 1;
1740 for _ in 0..count {
1741 result.push(repeat_byte);
1742 }
1743 i += 1;
1744 }
1745 }
1746
1747 Ok(result)
1748}