imageinfo/formats/
try_cur_ico.rs1use crate::{ImageFormat, ImageInfo, ImageInfoError, ImageInfoResult, ImageSize, ReadInterface};
2use std::io::{BufRead, Seek};
3
4pub fn try_cur_ico<R>(ri: &mut ReadInterface<R>, length: usize) -> ImageInfoResult<ImageInfo>
5where
6 R: BufRead + Seek,
7{
8 if length < 6 {
9 return Err(ImageInfoError::UnrecognizedFormat);
10 }
11 let buffer = ri.read(0, 6)?;
12
13 let mut ret =
14 if buffer.cmp(0, 4, b"\x00\x00\x01\x00") {
16 ImageInfo {
17 format: ImageFormat::ICO,
18 ext: "ico",
19 full_ext: "ico",
20 mimetype: "image/ico",
21 size: ImageSize {
22 width: 0,
23 height: 0,
24 },
25 entry_sizes: vec![],
26 }
27 }
28 else if buffer.cmp(0, 4, b"\x00\x00\x02\x00") {
30 ImageInfo {
31 format: ImageFormat::CUR,
32 ext: "cur",
33 full_ext: "cur",
34 mimetype: "image/cur",
35 size: ImageSize {
36 width: 0,
37 height: 0,
38 },
39 entry_sizes: vec![],
40 }
41 }
42 else {
44 return Err(ImageInfoError::UnrecognizedFormat);
45 };
46
47 let entry_count = buffer.read_u16_le(4) as usize;
48 if entry_count == 0 {
49 return Err(ImageInfoError::UnrecognizedFormat);
50 }
51
52 let entry_size = 16;
53 let entry_total_size = entry_count * entry_size;
54
55 let mut offset = 6usize;
56 if length < offset + entry_total_size {
57 return Err(ImageInfoError::UnrecognizedFormat);
58 }
59
60 let buffer = ri.read(offset, entry_total_size)?;
61 offset += entry_total_size;
62
63 for i in 0..entry_count {
64 let width = buffer.read_u8(i * entry_size);
65 let height = buffer.read_u8(i * entry_size + 1);
66 let width = if width == 0 { 256i64 } else { width as i64 };
67 let height = if height == 0 { 256i64 } else { height as i64 };
68 ret.entry_sizes.push(ImageSize { width, height });
69
70 let bytes = buffer.read_i32_le(i * entry_size + 8) as usize;
71 offset += bytes;
72 }
73
74 if let Some(size) = ret.entry_sizes.first() {
75 ret.size.width = size.width;
76 ret.size.height = size.height;
77 } else {
78 return Err(ImageInfoError::UnrecognizedFormat);
79 }
80
81 Ok(ret)
82}