1use image::{GenericImageView, Pixel};
7use std::{error::Error, path::Path};
8
9pub const MAX_IMAGE_WIDTH: u32 = 0x136;
12
13pub const MAX_IMAGE_HEIGHT: u32 = 0x191;
16
17pub fn convert_imgs_to_c2b<T, S>(image_paths: Vec<T>, destination: S) -> Result<(), Box<dyn Error>>
29where
30 T: AsRef<Path> + Clone,
31 S: AsRef<Path> + Clone,
32{
33 if image_paths.len() < 2 {
34 eprintln!("At least two images have to be supplied!");
35 return Ok(());
36 }
37
38 let image = image::ImageReader::open(&image_paths[0])
39 .expect("Failed to open image!")
40 .decode()
41 .expect("Failed to decode image!");
42 let (mut width, mut height): (u32, u32) = (image.width(), image.height());
43 (width, height) = fit_image_dimensions(width, height);
44 assert!(width > 0 && height > 0);
45
46 let mut images_data: Vec<u8> = Vec::new();
47 for path in &image_paths {
48 let image = image::ImageReader::open(path)
49 .expect("Failed to open image!")
50 .decode()
51 .expect("Failed to decode image!");
52 let (i_width, i_height): (u32, u32) = (image.width(), image.height());
53 assert!(i_width > 0 && i_height > 0);
54
55 let image = if i_width > MAX_IMAGE_WIDTH || i_height > MAX_IMAGE_HEIGHT {
56 eprintln!("Image too big! scaling down...");
57 image.resize(width, height, image::imageops::FilterType::Lanczos3)
58 } else {
59 image
60 };
61
62 let img_data = bitmap_to_rgb565(&image);
63 let compressed_img_data = compress(img_data);
64
65 let f = compressed_img_data.len();
67 let f4 = ((f >> 24) & 0xFF) as u8;
68 let f3 = ((f >> 16) & 0xFF) as u8;
69 let f2 = ((f >> 8) & 0xFF) as u8;
70 let f1 = (f & 0xFF) as u8;
71
72 images_data.extend_from_slice(&[f4, f3, f2, f1]);
73 images_data.extend_from_slice(&compressed_img_data);
74 }
75 let header = &get_c2b_header(
76 images_data.len(),
77 image_paths.len(),
78 width as usize,
79 height as usize,
80 );
81 let footer = &get_c2b_footer();
82 let mut new_file: Vec<u8> = Vec::new();
83
84 new_file.extend_from_slice(header);
85 new_file.extend_from_slice(&images_data);
86 new_file.extend_from_slice(footer);
87 std::fs::write(destination, new_file)?;
88
89 Ok(())
90}
91
92pub fn convert_img_to_c2p<T, S>(image_path: T, destination: S) -> Result<(), Box<dyn Error>>
103where
104 T: AsRef<Path> + Clone,
105 S: AsRef<Path> + Clone,
106{
107 let image = image::ImageReader::open(image_path)
108 .expect("Failed to open image!")
109 .decode()
110 .expect("Failed to decode image!");
111 let (width, height): (u32, u32) = fit_image_dimensions(image.width(), image.height());
112 assert!(width > 0 && height > 0);
113
114 let image = if width > MAX_IMAGE_WIDTH || height > MAX_IMAGE_HEIGHT {
115 eprintln!("Image too big! scaling down...");
116 let (new_width, new_height) = (
117 (width / (width / MAX_IMAGE_WIDTH)).clamp(1, MAX_IMAGE_WIDTH),
118 (height / (height / MAX_IMAGE_HEIGHT)).clamp(1, MAX_IMAGE_HEIGHT),
119 );
120 image.resize(new_width, new_height, image::imageops::FilterType::Lanczos3)
121 } else {
122 image
123 };
124
125 let img_data = bitmap_to_rgb565(&image);
126 let compressed_img_data = compress(img_data);
127
128 let header = &get_c2p_header(
129 compressed_img_data.len(),
130 image.width() as usize,
131 image.height() as usize,
132 );
133
134 let footer = &get_c2p_footer();
135
136 let mut new_file = Vec::new();
137 new_file.extend_from_slice(header);
138 new_file.extend_from_slice(&compressed_img_data);
139 new_file.extend_from_slice(footer);
140
141 std::fs::write(destination, new_file)?;
142
143 Ok(())
144}
145
146pub fn convert_c2p_to_img<T, S>(c2p_path: T, destination: S) -> Result<(), Box<dyn Error>>
157where
158 T: AsRef<Path> + Clone,
159 S: AsRef<Path> + Clone,
160{
161 let c2p_data: Vec<u8> = std::fs::read(c2p_path)?;
162 let (header, slice) = c2p_data.split_at(0xDC);
163 let (compressed_data, _footer) = slice.split_at(slice.len() - 0x17C);
164
165 let (width, height): (u32, u32) = (
166 ((header[0xC2] as u32) << 8) + header[0xC3] as u32,
167 ((header[0xC4] as u32) << 8) + header[0xC5] as u32,
168 );
169
170 let bytes = miniz_oxide::inflate::decompress_to_vec_zlib(compressed_data)
171 .expect("Failed to decompress compressed c2p image data!");
172
173 let mut img_buffer = image::RgbImage::new(width, height);
174
175 let (mut x, mut y) = (0, 0);
176 for i in (0..bytes.len()).step_by(2) {
177 let pixel = img_buffer.get_pixel_mut(x, y);
178
179 let rgb565: u32 = ((bytes[i] as u32) << 8) + bytes[i + 1] as u32;
180
181 let r5 = rgb565 >> 11;
182 let g6 = (rgb565 >> 5) & 0b111111;
183 let b5 = rgb565 & 0b11111;
184
185 let r = (r5 as f32 / 31.0 * 255.0) as u8;
186 let g = (g6 as f32 / 63.0 * 255.0) as u8;
187 let b = (b5 as f32 / 31.0 * 255.0) as u8;
188
189 *pixel = image::Rgb::from([r, g, b]);
190
191 x += 1;
192 if x == img_buffer.width() {
193 x = 0;
194 y += 1
195 }
196 }
197
198 img_buffer.save(destination)?;
199 Ok(())
200}
201
202pub fn convert_c2b_to_imgs<T, S>(c2b_path: T, destination: S) -> Result<(), Box<dyn Error>>
214where
215 T: AsRef<Path> + Clone,
216 S: AsRef<Path> + Clone,
217{
218 let c2b_data: Vec<u8> = std::fs::read(c2b_path)?;
219 let (header, data) = c2b_data.split_at(0xD8);
220
221 let (width, height): (u32, u32) = (
222 ((header[0xC2] as u32) << 8) + header[0xC3] as u32,
223 ((header[0xC4] as u32) << 8) + header[0xC5] as u32,
224 );
225
226 let mut image_block_len = (((data[0x00] as u32) << 24)
227 + ((data[0x01] as u32) << 16)
228 + ((data[0x02] as u32) << 8)
229 + (data[0x03] as u32)) as usize;
230 let mut offset: usize = 0x04;
231 let mut index: usize = 0;
232
233 while data[offset] == 0x78 && data[offset + 1] == 0x9C {
234 let (mut x, mut y) = (0, 0);
235 let mut img_buffer = image::RgbImage::new(width, height);
236 let data_buffer = &data[offset..offset + image_block_len];
237 let bytes = miniz_oxide::inflate::decompress_to_vec_zlib(data_buffer)
238 .expect("Failed to decompress compressed c2p image data!");
239
240 for i in (0..bytes.len()).step_by(2) {
241 let pixel = img_buffer.get_pixel_mut(x, y);
242
243 let rgb565: u32 = ((bytes[i] as u32) << 8) + bytes[i + 1] as u32;
244
245 let r5 = rgb565 >> 11;
246 let g6 = (rgb565 >> 5) & 0b111111;
247 let b5 = rgb565 & 0b11111;
248
249 let r = (r5 as f32 / 31.0 * 255.0) as u8;
250 let g = (g6 as f32 / 63.0 * 255.0) as u8;
251 let b = (b5 as f32 / 31.0 * 255.0) as u8;
252
253 *pixel = image::Rgb::from([r, g, b]);
254
255 x += 1;
256 if x == img_buffer.width() {
257 x = 0;
258 y += 1
259 }
260 }
261
262 let tmp = image_block_len;
263 image_block_len = (((data[offset + image_block_len] as u32) << 24)
264 + ((data[offset + image_block_len + 0x01] as u32) << 16)
265 + ((data[offset + image_block_len + 0x02] as u32) << 8)
266 + (data[offset + image_block_len + 0x03] as u32)) as usize;
267 offset += tmp + 4;
268
269 let path: &Path = destination.as_ref();
270 let file_dest: &str = path
271 .file_stem()
272 .unwrap_or_default()
273 .to_str()
274 .unwrap_or_default();
275 let extension: &str = path
276 .extension()
277 .unwrap_or_default()
278 .to_str()
279 .unwrap_or_default();
280 let destination = format!("{file_dest}{index}.{extension}");
281 index += 1;
282
283 img_buffer.save(&destination)?;
284 }
285
286 Ok(())
287}
288
289const fn fit_image_dimensions(width: u32, height: u32) -> (u32, u32) {
291 let (mut new_width, mut new_height) = (width, height);
292
293 if width > MAX_IMAGE_WIDTH || height > MAX_IMAGE_HEIGHT {
294 if width < height {
295 let aspect_ratio: f32 = width as f32 / height as f32;
296 new_height = MAX_IMAGE_HEIGHT;
297 new_width = (aspect_ratio * new_height as f32) as u32;
298 } else {
299 let aspect_ratio: f32 = height as f32 / width as f32;
300 new_width = MAX_IMAGE_WIDTH;
301 new_height = (aspect_ratio * new_width as f32) as u32;
302 }
303 }
304
305 (new_width, new_height)
306}
307
308fn bitmap_to_rgb565(image: &image::DynamicImage) -> Vec<u8> {
310 let w = image.width();
311 let h = image.height();
312 let mut image_data = Vec::with_capacity((w * h) as usize * 2);
313
314 for y in 0..h {
315 for x in 0..w {
316 let c = image.get_pixel(x, y).to_rgb().0;
317
318 let (r, g, b) = (
319 convert_range(0, 255, 0, 0x1F, c[0] as usize),
320 convert_range(0, 255, 0, 0x3F, c[1] as usize),
321 convert_range(0, 255, 0, 0x1F, c[2] as usize),
322 );
323
324 let rgb565: usize = (r << 11) + (g << 5) + b;
325 let rgb565_2: u8 = (rgb565 >> 8 & 0xFF) as u8;
326 let rgb565_1: u8 = (rgb565 & 0xFF) as u8;
327
328 image_data.push(rgb565_2);
329 image_data.push(rgb565_1);
330 }
331 }
332 image_data
333}
334
335const fn convert_range(
337 original_start: usize,
338 original_end: usize,
339 new_start: usize,
340 new_end: usize,
341 value: usize,
342) -> usize {
343 let scale: f64 = (new_end - new_start) as f64 / (original_end - original_start) as f64;
344 (new_start as f64 + ((value - original_start) as f64 * scale)) as usize
345}
346
347fn compress(input: Vec<u8>) -> Vec<u8> {
349 use miniz_oxide::deflate;
350 deflate::compress_to_vec_zlib(&input, deflate::CompressionLevel::DefaultLevel as u8)
351}
352
353fn get_c2p_header(image_data_size: usize, width: usize, height: usize) -> Vec<u8> {
355 let file_size: usize = image_data_size + 0xDC + 0x17C; let a = !(file_size & 0xFFFFFF) & 0xFFFFFF;
357 let a3 = (a >> 16 & 0xFF) as u8;
358 let a2 = (a >> 8 & 0xFF) as u8;
359 let a1 = (a & 0xFF) as u8;
360
361 let b1 = ((0x1D1 - (file_size & 0xFF)) & 0xFF) as u8;
362
363 let c = file_size - 0x20;
364 let c4 = (c >> 24 & 0xFF) as u8;
365 let c3 = (c >> 16 & 0xFF) as u8;
366 let c2 = (c >> 8 & 0xFF) as u8;
367 let c1 = (c & 0xFF) as u8;
368
369 let d = file_size - 0x234;
370 let d4 = (d >> 24 & 0xFF) as u8;
371 let d3 = (d >> 16 & 0xFF) as u8;
372 let d2 = (d >> 8 & 0xFF) as u8;
373 let d1 = (d & 0xFF) as u8;
374
375 let e = file_size - 0x254;
376 let e4 = (e >> 24 & 0xFF) as u8;
377 let e3 = (e >> 16 & 0xFF) as u8;
378 let e2 = (e >> 8 & 0xFF) as u8;
379 let e1 = (e & 0xFF) as u8;
380
381 let w = width & 0xFFFF;
382 let h = height & 0xFFFF;
383 let w2 = (w >> 8 & 0xFF) as u8;
384 let w1 = (w & 0xFF) as u8;
385 let h2 = (h >> 8 & 0xFF) as u8;
386 let h1 = (h & 0xFF) as u8;
387
388 let f = file_size - 0x258;
389 let f4 = (f >> 24 & 0xFF) as u8;
390 let f3 = (f >> 16 & 0xFF) as u8;
391 let f2 = (f >> 8 & 0xFF) as u8;
392 let f1 = (f & 0xFF) as u8;
393
394 vec![
395 0xBC, 0xBE, 0xAC, 0xB6, 0xB0, 0xFF, 0xFF, 0xFF, 0x9C, 0xCD, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF,
396 0xFF, 0xFF, 0xFE, 0xFF, 0xEF, 0xFF, 0xFE, 0xFF, a3, a2, a1, b1, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x43, 0x43, 0x30, 0x31, 0x30, 0x30, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x43, 0x50, 0x00,
398 0x00, 0x00, c4, c3, c2, c1, 0x00, 0x00, 0x00, 0x09, d4, d3, d2, d1, 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
403 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407 0x30, 0x31, 0x30, 0x30, e4, e3, e2, e1, 0x00, 0x00, w2, w1, h2, h1, 0x00, 0x10, 0x00, 0xFF,
408 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, f4, f3,
409 f2, f1,
410 ]
411}
412
413fn get_c2p_footer() -> Vec<u8> {
416 vec![
417 0x30, 0x31, 0x30, 0x30, 0x00, 0x00, 0x00, 0x8C, 0x07, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,
418 0x00, 0x00, 0x00, 0x60, 0x00, 0x07, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
419 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x05,
420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x98, 0x04, 0x60, 0x00, 0x00,
421 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
422 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
423 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x98, 0x00,
424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x31, 0x85,
425 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x06, 0x28, 0x32, 0x00, 0x00, 0x00, 0x00,
426 0x00, 0x00, 0x00, 0x09, 0x98, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x30, 0x31,
427 0x30, 0x30, 0xE0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
428 0x00, 0x60, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
429 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x50, 0x00,
430 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
431 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
432 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
433 0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x03, 0x00, 0x00,
434 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
435 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436 0x00, 0x10, 0x00, 0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01,
437 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x07, 0x00, 0x00,
438 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x03, 0x14, 0x15, 0x93, 0x00, 0x00,
439 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x03, 0x14, 0x15, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00,
440 0x00, 0x10, 0x00, 0x03, 0x14, 0x15, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
441 0x03, 0x14, 0x15, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x01, 0x01,
442 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
443 ]
444}
445
446fn get_c2b_header(
448 image_data_size: usize,
449 total_image_count: usize,
450 width: usize,
451 height: usize,
452) -> Vec<u8> {
453 let file_size: usize = image_data_size + 0xD8 + 0x1A8; let a = !(file_size & 0xFFFFFF) & 0xFFFFFF;
455 let a3 = (a >> 16 & 0xFF) as u8;
456 let a2 = (a >> 8 & 0xFF) as u8;
457 let a1 = (a & 0xFF) as u8;
458
459 let b1 = ((0x1D0 - (file_size & 0xFF)) & 0xFF) as u8;
460
461 let c = file_size - 0x20;
462 let c4 = (c >> 24 & 0xFF) as u8;
463 let c3 = (c >> 16 & 0xFF) as u8;
464 let c2 = (c >> 8 & 0xFF) as u8;
465 let c1 = (c & 0xFF) as u8;
466
467 let d = file_size - 0x260;
468 let d4 = (d >> 24 & 0xFF) as u8;
469 let d3 = (d >> 16 & 0xFF) as u8;
470 let d2 = (d >> 8 & 0xFF) as u8;
471 let d1 = (d & 0xFF) as u8;
472
473 let e = file_size - 0x280;
474 let e4 = (e >> 24 & 0xFF) as u8;
475 let e3 = (e >> 16 & 0xFF) as u8;
476 let e2 = (e >> 8 & 0xFF) as u8;
477 let e1 = (e & 0xFF) as u8;
478
479 let w = width & 0xFFFF;
480 let h = height & 0xFFFF;
481 let w2 = (w >> 8 & 0xFF) as u8;
482 let w1 = (w & 0xFF) as u8;
483 let h2 = (h >> 8 & 0xFF) as u8;
484 let h1 = (h & 0xFF) as u8;
485
486 let i = total_image_count as u8;
487
488 vec![
489 0xBC, 0xBE, 0xAC, 0xB6, 0xB0, 0xFF, 0xFF, 0xFF, 0x9C, 0xCD, 0x9D, 0xFF, 0xFF, 0xFF, 0xFF,
490 0xFF, 0xFF, 0xFE, 0xFF, 0xEF, 0xFF, 0xFE, 0xFF, a3, a2, a1, b1, 0x00, 0x00, 0x00, 0x00,
491 0x00, 0x43, 0x43, 0x30, 0x31, 0x30, 0x30, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x43, 0x50, 0x00,
492 0x00, 0x00, c4, c3, c2, c1, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, d4, d3, d2, d1,
493 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7C, 0x00, 0x00, 0x00,
494 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
495 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
496 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
497 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
498 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
499 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
500 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
501 0x30, 0x31, 0x30, 0x30, e4, e3, e2, e1, 0x00, 0x00, w2, w1, h2, h1, 0x00, 0x10, 0x00, 0xFF,
502 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x01, 0x00, i, 0xFF, 0xFF, 0xFF, 0xFF,
503 ]
504}
505
506fn get_c2b_footer() -> Vec<u8> {
509 vec![
510 0x30, 0x31, 0x30, 0x30, 0x00, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
511 0x00, 0x00, 0x00, 0x10, 0x01, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
512 0x10, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03,
513 0x24, 0x67, 0x53, 0x24, 0x67, 0x53, 0x25, 0x00, 0x00, 0x09, 0x97, 0x01, 0x02, 0x54, 0x71,
514 0x69, 0x81, 0x13, 0x21, 0x00, 0x00, 0x10, 0x01, 0x01, 0x07, 0x45, 0x28, 0x30, 0x18, 0x86,
515 0x79, 0x00, 0x00, 0x10, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
516 0x10, 0x00, 0x02, 0x35, 0x84, 0x90, 0x56, 0x60, 0x37, 0x74, 0x00, 0x00, 0x09, 0x97, 0x00,
517 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x31, 0x85,
518 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x06, 0x28, 0x32, 0x00, 0x00, 0x00, 0x00,
519 0x00, 0x00, 0x00, 0x09, 0x98, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x30, 0x31,
520 0x30, 0x30, 0xE0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
521 0x00, 0x60, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
522 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x50, 0x00,
523 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
524 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
525 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
526 0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x03, 0x00, 0x00,
527 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
528 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
529 0x00, 0x10, 0x00, 0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01,
530 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x07, 0x00, 0x00,
531 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x03, 0x14, 0x15, 0x93, 0x00, 0x00,
532 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x03, 0x14, 0x15, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00,
533 0x00, 0x10, 0x00, 0x03, 0x14, 0x15, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
534 0x03, 0x14, 0x15, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x01, 0x01,
535 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x30, 0x31, 0x30, 0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
536 0x50, 0x47, 0x54, 0x69, 0x6D, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
537 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538 0x00, 0x00, 0x09, 0x99,
539 ]
540}