1use std::fs::File;
2use std::io::Write;
3use std::path::PathBuf;
4
5use byteorder::{BigEndian, ByteOrder};
6
7extern crate hex_slice;
8use hex_slice::AsHex;
9
10use crate::data::color::ColorType;
11use crate::data::layer::Layer;
12use crate::data::property::Property;
13use crate::data::property::PropertyPayload;
14use crate::data::xcf::XcfCompression;
15use crate::data::tiles::Tiles;
16use crate::LayerColorValue;
17use crate::PropertyIdentifier;
18use crate::RgbaPixel;
19
20pub struct XcfCreator {
21 pub version: u16,
22 pub data: Vec<u8>,
23 pub index: u64,
24 pub compression: XcfCompression,
25}
26
27impl XcfCreator {
29 fn extend_u32(&mut self, value: u32) {
30 let mut width_buf = vec![0; 4];
31 BigEndian::write_u32(&mut width_buf, value);
32 self.data.extend_from_slice(&width_buf);
33 self.index += 4;
34 }
35
36 fn extend_u64(&mut self, value: u64) {
37 let mut width_buf = vec![0; 8];
38 BigEndian::write_u64(&mut width_buf, value);
39 self.data.extend_from_slice(&width_buf);
40 self.index += 8;
41 }
42
43 fn buf_extend_u32(&mut self, data: &mut Vec<u8>, index: &mut u32, value: u32) {
44 let size = 4;
45 let mut width_buf = vec![0; size];
46 BigEndian::write_u32(&mut width_buf, value);
47 data.extend_from_slice(&width_buf);
48 *index += size as u32;
49 }
50
51 fn buf_extend_u64(&mut self, data: &mut Vec<u8>, index: &mut u32, value: u64) {
52 let size = 8;
53 let mut width_buf = vec![0; size];
54 BigEndian::write_u64(&mut width_buf, value);
55 data.extend_from_slice(&mut width_buf);
56 *index += size as u32;
57 }
58
59 fn create_signature(&mut self, gimp_version: u16) {
60 let mut signature = format!("gimp xcf v{:03}\0", gimp_version);
61 if gimp_version == 1 {
62 signature = "gimp xcf file\0".to_string();
63 }
64 self.data.extend_from_slice(signature.as_bytes());
65 self.index += 14;
66 }
67
68 fn v10_gimp_string(&mut self, data: &mut Vec<u8>, index: &mut u32, str: &[u8]) {
69 let str_count = str.len() as u32;
70 self.buf_extend_u32(data, index, str_count + 4);
71 data.extend_from_slice(str);
72 *index += str_count;
73 self.buf_extend_u32(data, index, 0);
74 }
75
76 fn gimp_string(&mut self, data: &mut Vec<u8>, index: &mut u32, str: &[u8]) {
77 let str_count = str.len() as u32 + 1;
78 self.buf_extend_u32(data, index, str_count);
79 data.extend_from_slice(str);
80 data.extend_from_slice(&[0]);
81 *index += str_count;
82 }
83
84 fn parasite_prop(&mut self, data: &mut Vec<u8>, index: &mut u32, parasite_title: &str, parasite_data: &str, flags: u32) {
85 let title_len = parasite_title.len() + 1;
86 self.buf_extend_u32(data, index, title_len as u32);
87 data.extend_from_slice(parasite_title.as_bytes());
88 data.extend_from_slice(&[0]);
89 *index += title_len as u32;
90 self.buf_extend_u32(data, index,flags);
91
92 let data_len = parasite_data.len() + 1;
93 self.buf_extend_u32(data, index,data_len as u32);
94 data.extend_from_slice(parasite_data.as_bytes());
95 data.extend_from_slice(&[0]);
96 *index += data_len as u32;
97 }
98
99 pub fn new(version: u16, width: u32, height: u32, color_type: ColorType) -> Self {
100 let data = vec![];
101 let index = 0;
102
103 let mut _self = XcfCreator {
104 version,
105 data,
106 index,
107 compression: XcfCompression::None,
108 };
109 _self.create_signature(version);
110 _self.extend_u32(width);
111 _self.extend_u32(height);
112 _self.extend_u32(color_type as u32);
113
114 if version >= 4 {
115 _self.extend_u32(150); }
117
118 _self
119 }
120
121 fn prop_end(&mut self, data: &mut Vec<u8>, index: &mut u32) {
122 self.buf_extend_u32(data, index, 0);
123 self.buf_extend_u32(data, index, 0);
124 }
126
127 pub fn add_properties(&mut self, properties: &Vec<Property>) {
128 let mut _has_compression = false;
129 for property in properties {
130 self.extend_u32(property.kind as u32);
131 match &property.payload {
132 PropertyPayload::Compression(_value) => {
133 self.extend_u32(property.length as u32); self.data.extend_from_slice(&[_value.to_u8()]);
136 self.index += 1;
137 self.compression = _value.clone();
138 _has_compression = true;
139 }
140 PropertyPayload::ResolutionProperty(_value) => {
141 self.extend_u32(property.length as u32); self.extend_u32(_value.xres.to_bits()); self.extend_u32(_value.yres.to_bits()); }
146 PropertyPayload::Tatoo(_value) | PropertyPayload::Unit(_value) => {
147 self.extend_u32(property.length as u32); self.extend_u32(*_value);
150 }
151 PropertyPayload::Parasites(_parasites) => {
152 let mut parasite_prop_buf = vec![];
153 let mut parasite_prop_len = 0;
154 for parasite in _parasites {
155 self.parasite_prop(
156 &mut parasite_prop_buf,
157 &mut parasite_prop_len,
158 ¶site.name,
159 ¶site.data,
160 parasite.flags
161 );
162 }
163 self.extend_u32(parasite_prop_len); self.data.extend_from_slice(¶site_prop_buf);
165 self.index += parasite_prop_len as u64;
166 }
167 _ => {
168 self.extend_u32(property.length as u32); }
170 }
171 }
172 if self.version > 10 && !_has_compression {
173 self.extend_u32(PropertyIdentifier::PropCompression as u32);
174 self.extend_u32(1); self.data.extend_from_slice(&[XcfCompression::Rle as u8]);
176 self.index += 1;
177 self.compression = XcfCompression::Rle;
178
179 self.extend_u32(PropertyIdentifier::PropResolution as u32);
181 self.extend_u32(8); let value: f32 = 300.0;
183 self.extend_u32(value.to_bits()); self.extend_u32(value.to_bits()); self.extend_u32(PropertyIdentifier::PropTattoo as u32);
188 self.extend_u32(4); self.extend_u32(2);
190
191 self.extend_u32(PropertyIdentifier::PropUnit as u32);
193 self.extend_u32(4); self.extend_u32(1);
195
196 let mut parasite_prop_buf = vec![];
198 let mut parasite_prop_len = 0;
199 self.parasite_prop(
200 &mut parasite_prop_buf,
201 &mut parasite_prop_len,
202 "gimp-comment",
203 "Test Comment",
205 1
206 );
207 self.parasite_prop(
208 &mut parasite_prop_buf,
209 &mut parasite_prop_len,
210 "gimp-image-grid",
211 "(style solid)\n(fgcolor (color-rgba 0 0 0 1))\n(bgcolor (color-rgba 1 1 1 1))\n(xspacing 10)\n(yspacing 10)\n(spacing-unit inches)\n(xoffset 0)\n(yoffset 0)\n(offset-unit inches)\n",
212 1
213 );
214 self.extend_u32(PropertyIdentifier::PropParasites as u32);
215 self.extend_u32(parasite_prop_len); self.data.extend_from_slice(¶site_prop_buf);
217 self.index += parasite_prop_len as u64;
218 }
219
220 self.extend_u32(0);
222 self.extend_u32(0);
223 }
224
225 fn _add_layers_properties(&mut self, data: &mut Vec<u8>, index: &mut u32, layers_properties: &Vec<Property>) {
226 for layer_property in layers_properties {
227 self.buf_extend_u32(data, index, layer_property.kind as u32);
228 self.buf_extend_u32(data, index, layer_property.length as u32); match &layer_property.payload {
230 PropertyPayload::Compression(_value) => {
231 data.extend_from_slice(&[_value.to_u8()]);
232 *index += 1;
233 }
234 PropertyPayload::OpacityLayer(_value) => {
235 data
236 .extend_from_slice(&[_value.r(), _value.g(), _value.b(), _value.a()]);
237 *index += 4;
238 }
239 PropertyPayload::FloatOpacityLayer() => {
240 let float_slice = [63, 128, 0, 0];
242 data.extend_from_slice(&float_slice); *index += 4;
244 }
245 PropertyPayload::VisibleLayer() => {
246 let float_slice = [0, 0, 0, 1];
247 data.extend_from_slice(&float_slice); *index += 4;
249 }
250 PropertyPayload::OffsetsLayer(_offset_x, _offset_y) => {
251 self.buf_extend_u32(data, index, *_offset_x);
252 self.buf_extend_u32(data, index, *_offset_y);
253 }
254 PropertyPayload::LinkedLayer(_value)
255 | PropertyPayload::ColorTagLayer(_value)
256 | PropertyPayload::LockContentLayer(_value)
257 | PropertyPayload::LockAlphaLayer(_value)
258 | PropertyPayload::LockPositionLayer(_value)
259 | PropertyPayload::ApplyMaskLayer(_value)
260 | PropertyPayload::EditMaskLayer(_value)
261 | PropertyPayload::ShowMaskLayer(_value)
262 | PropertyPayload::ModeLayer(_value)
263 | PropertyPayload::BlendSpaceLayer(_value)
264 | PropertyPayload::CompositeSpaceLayer(_value)
265 | PropertyPayload::CompositeModeLayer(_value)
266 | PropertyPayload::Tatoo(_value) => {
267 self.buf_extend_u32(data, index, *_value);
268 }
269 _ => {}
270 }
271 }
272 if self.version > 10 && layers_properties.iter().len() == 0 {
273 self.buf_extend_u32(data, index, PropertyIdentifier::PropActiveLayer as u32);
275 self.buf_extend_u32(data, index, 0);
276 self.buf_extend_u32(data, index, PropertyIdentifier::PropOpacity as u32);
278 self.buf_extend_u32(data, index, 4);
279 data.extend_from_slice(&[0, 0, 0, 255]);
280 *index += 4;
281 self.buf_extend_u32(data, index, PropertyIdentifier::PropFloatOpacity as u32);
283 self.buf_extend_u32(data, index, 4);
284 let float_slice = [63, 128, 0, 0];
285 data.extend_from_slice(&float_slice); *index += 4;
287 self.buf_extend_u32(data, index, PropertyIdentifier::PropVisible as u32);
289 self.buf_extend_u32(data, index, 4);
290 let float_slice = [0, 0, 0, 1];
291 data.extend_from_slice(&float_slice); *index += 4;
293
294 self.buf_extend_u32(data, index, PropertyIdentifier::PropLinked as u32);
296 self.buf_extend_u32(data, index, 4);
297 self.buf_extend_u32(data, index, 0);
298
299 self.buf_extend_u32(data, index, PropertyIdentifier::PropColorTag as u32);
301 self.buf_extend_u32(data, index, 4);
302 self.buf_extend_u32(data, index, 0);
303
304 self.buf_extend_u32(data, index, PropertyIdentifier::PropLockContent as u32);
306 self.buf_extend_u32(data, index, 4);
307 self.buf_extend_u32(data, index, 0);
308
309 self.buf_extend_u32(data, index, PropertyIdentifier::PropLockAlpha as u32);
311 self.buf_extend_u32(data, index, 4);
312 self.buf_extend_u32(data, index, 0);
313
314 self.buf_extend_u32(data, index, PropertyIdentifier::PropLockPosition as u32);
316 self.buf_extend_u32(data, index, 4);
317 self.buf_extend_u32(data, index, 0);
318
319 self.buf_extend_u32(data, index, PropertyIdentifier::PropApplyMask as u32);
321 self.buf_extend_u32(data, index, 4);
322 self.buf_extend_u32(data, index, 0);
323
324 self.buf_extend_u32(data, index, PropertyIdentifier::PropEditMask as u32);
326 self.buf_extend_u32(data, index, 4);
327 self.buf_extend_u32(data, index, 0);
328
329 self.buf_extend_u32(data, index, PropertyIdentifier::PropShowMask as u32);
331 self.buf_extend_u32(data, index, 4);
332 self.buf_extend_u32(data, index, 0);
333
334 self.buf_extend_u32(data, index, PropertyIdentifier::PropOffsets as u32);
336 self.buf_extend_u32(data, index, 8);
337 self.buf_extend_u32(data, index, 0);
338 self.buf_extend_u32(data, index, 0);
339
340 self.buf_extend_u32(data, index, PropertyIdentifier::PropMode as u32);
342 self.buf_extend_u32(data, index, 4); self.buf_extend_u32(data, index, 28); self.buf_extend_u32(data, index, PropertyIdentifier::PropBlendSpace as u32);
347 self.buf_extend_u32(data, index, 4);
348 self.buf_extend_u32(data, index, 0);
349
350 self.buf_extend_u32(data, index, PropertyIdentifier::PropCompositeSpace as u32);
352 self.buf_extend_u32(data, index, 4);
353 self.buf_extend_u32(data, index, u32::MAX);
354
355 self.buf_extend_u32(data, index, PropertyIdentifier::PropCompositeMode as u32);
357 self.buf_extend_u32(data, index, 4);
358 self.buf_extend_u32(data, index, u32::MAX);
359
360 self.buf_extend_u32(data, index, PropertyIdentifier::PropTattoo as u32);
362 self.buf_extend_u32(data, index, 4);
363 self.buf_extend_u32(data, index, 2);
364 }
365 self.prop_end(data, index);
366 }
367
368 fn _add_layers_v10(&mut self, _layers: &[Layer]) {
369 let mut intermediate_buf = vec![];
370 let mut layer_offset_zero_index = 0;
371
372 self.buf_extend_u32(&mut intermediate_buf, &mut layer_offset_zero_index, 0); self.buf_extend_u32(&mut intermediate_buf, &mut layer_offset_zero_index, 0); self.index += layer_offset_zero_index as u64;
376
377 let mut layer_offset_one_buf = vec![];
378 let mut layer_offset_one_index = 0;
379
380 self.buf_extend_u32(
381 &mut layer_offset_one_buf,
382 &mut layer_offset_one_index,
383 self.index as u32 + 4,
384 ); layer_offset_one_buf.extend_from_slice(&intermediate_buf);
387 self.data.extend_from_slice(&layer_offset_one_buf);
388 self.index += layer_offset_one_index as u64;
389
390 self.extend_u32(1); self.extend_u32(1); self.extend_u32(0); let mut layer_name_data = vec!();
396 let mut layer_name_len = 0;
397 self.v10_gimp_string(&mut layer_name_data, &mut layer_name_len, b"Background");
398 self.data.extend_from_slice(&layer_name_data);
399 self.index += layer_name_len as u64;
400
401 self.extend_u32(PropertyIdentifier::PropActiveLayer as u32); self.extend_u32(0);
403
404 self.extend_u32(PropertyIdentifier::PropOpacity as u32); self.extend_u32(4); self.extend_u32(RgbaPixel::new(0, 0, 0, 255).to_u32()); self.extend_u32(PropertyIdentifier::PropMode as u32); self.extend_u32(4); self.extend_u32(0); self.extend_u32(PropertyIdentifier::PropFloatOpacity as u32); self.extend_u32(4); let float_slice = [63, 128, 0, 0];
416 self.data.extend_from_slice(&float_slice); self.index += 4;
418
419 self.extend_u32(PropertyIdentifier::PropVisible as u32); self.extend_u32(4); let float_slice = [0, 0, 0, 1];
422 self.data.extend_from_slice(&float_slice); self.index += 4;
424
425 self.extend_u32(PropertyIdentifier::PropLinked as u32); self.extend_u32(4); self.extend_u32(0); self.extend_u32(0);
432 self.extend_u32(0);
433
434 self.extend_u32(self.index as u32 + 8);
436 self.extend_u32(0); self.extend_u32(1); self.extend_u32(1); self.extend_u32(3); self.extend_u32(self.index as u32 + 8); self.extend_u32(0); self.extend_u32(1); self.extend_u32(1); self.extend_u32(self.index as u32 + 8); self.extend_u32(0); let slice = [158, 36, 222]; self.data.extend_from_slice(&slice);
458 }
459
460 pub fn add_layers(&mut self, layers: &Vec<Layer>) {
461 if self.version < 11 {
462 self._add_layers_v10(layers);
463 return;
464 }
465 let nb_layers = layers.iter().len();
466
467 let mut layer_data = vec![];
468 let mut layer_index = 0;
469 for layer in layers {
470 layer_index += 1;
471 let mut layer_len = 0;
472
473 let tiles = Tiles::new(layer);
474
475 let layer_offset = self.index + (nb_layers - layer_index + 1) as u64 * 8 + layer_len as u64 + 16;
477 self.extend_u64(layer_offset); self.buf_extend_u32(&mut layer_data, &mut layer_len, layer.width);
492 self.buf_extend_u32(&mut layer_data, &mut layer_len, layer.height);
493 self.buf_extend_u32(&mut layer_data, &mut layer_len, layer.kind.kind.clone() as u32);
494
495 self.gimp_string(&mut layer_data, &mut layer_len, layer.name.as_bytes());
497
498 self._add_layers_properties(&mut layer_data, &mut layer_len, &layer.properties);
500
501 let mut hierarchy_data = vec![];
502 let mut hierarchy_len = 0;
503 self.buf_extend_u32(&mut hierarchy_data, &mut hierarchy_len,layer.pixels.width); self.buf_extend_u32(&mut hierarchy_data, &mut hierarchy_len,layer.pixels.height); let layer_has_alpha = LayerColorValue::has_alpha(layer.kind.kind.clone());
508 if layer_has_alpha {
509 self.buf_extend_u32(&mut hierarchy_data, &mut hierarchy_len, 4); } else {
511 self.buf_extend_u32(&mut hierarchy_data, &mut hierarchy_len, 3); }
513
514 let mut tiles_headers = vec![];
515 let mut tiles_body = vec![];
516 let mut tiles_pixels: Vec<Vec<RgbaPixel>> = vec![];
517 for _x in 0..tiles.nb {
518 tiles_pixels.push(vec![]);
519 }
520
521 let mut pixel_index = 0;
522 let mut x = 0;
523 let mut y = 1;
524 for pixel in &layer.pixels.pixels {
525 pixel_index += 1;
526 x += 1;
527
528 let tile_x = (x as f32 / 64.0).ceil();
529 let tile_y = (y as f32 / 64.0).ceil();
530
531 tiles_pixels[tiles.nb_width as usize * (tile_y as usize - 1) + tile_x as usize - 1].push(*pixel);
540
541 if pixel_index % layer.width == 0 {
542 y += 1;
543 x = 0;
544 }
545 }
546
547 if self.compression == XcfCompression::Rle {
559 let nb_of_pixels = layer.pixels.pixels.iter().len() as u32;
568 let nb_pixels_of_layers = layer.pixels.width * layer.pixels.height;
569 if nb_pixels_of_layers != nb_of_pixels {
570 panic!(
571 "Number of pixels on the layers {} and pixels {} aren't equals",
572 nb_pixels_of_layers, nb_of_pixels
573 );
574 }
575
576 let mut offset_data = vec![];
579 let mut offset_len = 0;
580 let hierarchy_ofs = layer_offset + layer_len as u64 + 16;
582 self.buf_extend_u32(&mut offset_data, &mut offset_len,layer.pixels.width); self.buf_extend_u32(&mut offset_data, &mut offset_len,layer.pixels.height); self.buf_extend_u32(&mut offset_data, &mut offset_len,0); let offset_index = hierarchy_ofs + offset_len as u64 + tiles.nb as u64 * 8 + 8;
593 for _tile in &tiles_pixels {
601 self.buf_extend_u64(&mut hierarchy_data, &mut hierarchy_len, offset_index); }
603 self.buf_extend_u64(&mut hierarchy_data, &mut hierarchy_len, 0); let mut tiles_headers_len = 0;
606 for tile in &tiles_pixels {
607 let tile_index = offset_index as u32 + 16 + tiles.nb * 8 + tiles_body.len() as u32;
608 self.buf_extend_u32(&mut tiles_headers, &mut tiles_headers_len, tile_index);
610 self.buf_extend_u32(&mut tiles_headers, &mut tiles_headers_len, 0);
611 tiles_headers_len = 0;
612
613 let mut buffer_r = vec![];
614 let mut buffer_g = vec![];
615 let mut buffer_b = vec![];
616 let mut buffer_a = vec![];
617 for pixel in tile {
618 buffer_r.push(pixel.r());
619 buffer_g.push(pixel.g());
620 buffer_b.push(pixel.b());
621 if layer_has_alpha {
622 buffer_a.push(pixel.a());
623 }
624 }
625
626 let rle_r = rle_compress(&buffer_r);
627 tiles_body.extend(rle_r);
630
631 let rle_g = rle_compress(&buffer_g);
632 tiles_body.extend(rle_g);
635
636 let rle_b = rle_compress(&buffer_b);
637 tiles_body.extend(rle_b);
640
641 if layer_has_alpha {
642 let rle_a = rle_compress(&buffer_a);
643 tiles_body.extend(rle_a);
646 }
647 }
648
649 hierarchy_data.extend_from_slice(&offset_data);
650 hierarchy_len += offset_len;
651
652 self.buf_extend_u64(&mut layer_data, &mut layer_len, hierarchy_ofs); self.buf_extend_u64(&mut layer_data, &mut layer_len,0); layer_data.extend_from_slice(&hierarchy_data);
657 layer_len += hierarchy_len;
658 tiles_headers.extend_from_slice(&[0, 0, 0, 0]);
659
660 layer_data.extend_from_slice(&tiles_headers);
661 layer_data.extend_from_slice(&tiles_body);
662 layer_len += tiles_headers.len() as u32 + tiles_body.len() as u32;
663 self.index += layer_len as u64;
664 } else {
665 panic!("not implemented");
666 }
667 }
668 self.extend_u64(0); self.extend_u64(0); self.data.extend_from_slice(&layer_data);
671 }
672
673 pub fn save(&mut self, path: &PathBuf) -> Result<File, crate::Error> {
674 let mut new_file = File::create(&path)?;
675 new_file.write_all(self.data.as_slice())?;
676 Ok(new_file)
677 }
678}
679
680pub fn short_run_identical(verbatim: &[u8]) -> Vec<u8> {
681 println!("short run identical");
682 if verbatim.len() < 1 {
683 panic!("Wrong verbatim lengh : {}", verbatim.len());
684 }
685 vec![(verbatim.len() - 1) as u8, verbatim[0]]
686}
687
688pub fn long_run_identical(verbatim: &[u8]) -> Vec<u8> {
689 println!("long run identical");
690 if verbatim.len() < 127 {
691 panic!("Wrong verbatim lengh : {}", verbatim.len());
692 }
693 let p = verbatim.len() / 256;
695 let q = verbatim.len() % 256;
696 vec![127, p as u8, q as u8, verbatim[0]]
697}
698
699pub fn run_identical(verbatim: &[u8]) -> Vec<u8> {
700 if verbatim.len() > 126 {
701 return long_run_identical(&verbatim);
702 }
703 short_run_identical(&verbatim)
704}
705
706pub fn short_run_diff(verbatim: &[u8]) -> Vec<u8> {
707 println!("short run diff");
708 if verbatim.len() < 1 {
709 panic!("Wrong verbatim lengh : {}", verbatim.len());
710 }
711 let mut r = vec![(256 - verbatim.len()) as u8];
712 r.extend_from_slice(verbatim);
713 r
714}
715
716pub fn long_run_diff(verbatim: &[u8]) -> Vec<u8> {
717 println!("long run diff");
718 if verbatim.len() < 127 {
719 panic!("Wrong verbatim lengh : {}", verbatim.len());
720 }
721 let p = verbatim.len() / 256;
723 let q = verbatim.len() % 256;
724 let mut r = vec![128, p as u8, q as u8];
725 r.extend_from_slice(verbatim);
726 r
727}
728
729pub fn run_diff(verbatim: &[u8]) -> Vec<u8> {
730 if verbatim.len() > 126 {
731 return long_run_diff(&verbatim);
732 }
733 short_run_diff(&verbatim)
734}
735
736pub fn is_identiqual(values: &[u8]) -> bool {
737 if values.len() < 2 {
738 panic!("Wrong values lengh : {}", values.len());
739 }
740 let value = values[0];
741 for v in &values[1..values.len()] {
742 if value != *v {
743 return false;
744 }
745 }
746 return true;
747}
748
749pub fn rle_compress(data: &Vec<u8>) -> Vec<u8> {
751 let mut compress_data = vec![];
752 let mut verbatim: Vec<u8> = vec![];
753 let mut i = 0;
754 for byte in data {
755 i += 1;
756 verbatim.push(*byte);
757
758 if i >= data.len() - 1 {
759 break;
760 }
761 let val = *byte;
762 let mut val_last_1 = val;
763 let mut val_last_2 = val;
764 if i > 1 {
765 val_last_1 = data[i - 2];
766 }
767 if i > 2 {
768 val_last_2 = data[i - 3];
769 }
770 let val_1 = data[i];
771 let val_2 = data[i + 1];
772 let mut val_3 = val_2;
773 if i < data.len() - 2 {
774 val_3 = data[i + 2];
775 }
776
777 if i == 2
789 && val_last_1 == val
790 && val != val_1 {
791 let buffer = short_run_identical(&verbatim);
792 compress_data.extend_from_slice(&buffer);
793 verbatim = vec![];
794 continue;
795 }
796 if i == 1
797 && val != val_1
798 && val_1 == val_2
799 && val_2 == val_3 {
800 let buffer = run_diff(&verbatim);
801 compress_data.extend_from_slice(&buffer);
802 verbatim = vec![];
803 continue;
804 }
805 if i > 2
806 && val_last_2 == val_last_1
807 && val_last_1 == val
808 && val != val_1 {
809 println!("f 2: {:?}", verbatim);
810 let buffer = run_identical(&verbatim);
811 compress_data.extend_from_slice(&buffer);
812 verbatim = vec![];
813 continue;
814 }
815
816 if i > 4 && i < data.len() - 2
817 && is_identiqual(&vec![data[i - 3], data[i - 4], data[i - 5]])
818 && val_last_1 == val
819 && val != val_1
820 {
821 println!("f 3: {:?}", verbatim);
822 let buffer = run_identical(&verbatim);
823 compress_data.extend_from_slice(&buffer);
824 verbatim = vec![];
825 continue;
826 }
827
828 if i < data.len() - 2
829 && val != val_1
830 && val_1 == val_2
831 && val_2 == val_3 {
832 println!("f 4");
833 let buffer = run_diff(&verbatim);
834 compress_data.extend_from_slice(&buffer);
835 verbatim = vec![];
836 continue;
837 }
838 }
839 verbatim.push(data[data.len() - 1]);
840 let val = verbatim[verbatim.len() - 1];
841 let mut val_last_1 = val;
842 let mut val_last_2 = val;
843 let mut val_last_3 = val;
844 if verbatim.len() > 1 {
845 val_last_1 = verbatim[verbatim.len() - 2];
846 }
847 if verbatim.len() > 2 {
848 val_last_2 = verbatim[verbatim.len() - 3];
849 }
850 if verbatim.len() > 3 {
851 val_last_3 = verbatim[verbatim.len() - 4];
852 }
853 let mut buffer;
854
855 if verbatim.len() >= 2 && val == val_last_1 && val_last_1 == val_last_2 {
856 println!("1.");
857 if data.len() == 1 {
858 buffer = vec![0, verbatim[0]];
859 } else {
860 buffer = run_identical(&verbatim);
861 }
862 } else if verbatim.len() >= 2 && val != val_last_1 && val_last_1 == val_last_2 && val_last_2 == val_last_3 {
863 println!("1.1");
864 buffer = run_identical(&verbatim[..verbatim.len() - 1]);
865 buffer.push(0);
866 buffer.push(val);
867 } else if verbatim.len() >= 2 && val == val_last_1 {
868 println!("2.");
869 buffer = run_diff(&verbatim[..verbatim.len() - 2]);
871 buffer.push(1);
872 buffer.push(verbatim[verbatim.len() - 1]);
873 } else {
874 println!("3.");
875 buffer = run_diff(&verbatim);
876 }
877
878 compress_data.extend_from_slice(&buffer);
879 compress_data
880}