Skip to content

Commit 2b77e2b

Browse files
authored
Merge pull request #2678 from RunDevelopment/ico-entry-order-fix
Pick ICO entries in order
2 parents 5117fef + 50ecdc3 commit 2b77e2b

File tree

3 files changed

+16
-19
lines changed

3 files changed

+16
-19
lines changed

src/codecs/ico/decoder.rs

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -191,25 +191,22 @@ fn read_entry<R: Read>(r: &mut R) -> ImageResult<DirEntry> {
191191
}
192192

193193
/// Find the entry with the highest (color depth, size).
194-
fn best_entry(mut entries: Vec<DirEntry>) -> ImageResult<DirEntry> {
195-
let mut best = entries.pop().ok_or(DecoderError::NoEntries)?;
196-
197-
let mut best_score = (
198-
best.bits_per_pixel,
199-
u32::from(best.real_width()) * u32::from(best.real_height()),
200-
);
201-
202-
for entry in entries {
203-
let score = (
204-
entry.bits_per_pixel,
205-
u32::from(entry.real_width()) * u32::from(entry.real_height()),
206-
);
207-
if score > best_score {
208-
best = entry;
209-
best_score = score;
210-
}
211-
}
212-
Ok(best)
194+
///
195+
/// If two entries have the same color depth and size, pick the first one.
196+
/// While ICO files with multiple identical size and bpp entries are rare, they
197+
/// do exist. Since we can't make an educated guess which one is best, picking
198+
/// the first one is a reasonable default.
199+
fn best_entry(entries: Vec<DirEntry>) -> ImageResult<DirEntry> {
200+
entries
201+
.into_iter()
202+
.rev() // ties should pick the first entry, not the last
203+
.max_by_key(|entry| {
204+
(
205+
entry.bits_per_pixel,
206+
u32::from(entry.real_width()) * u32::from(entry.real_height()),
207+
)
208+
})
209+
.ok_or(DecoderError::NoEntries.into())
213210
}
214211

215212
impl DirEntry {
7.37 KB
Binary file not shown.
1.6 KB
Loading

0 commit comments

Comments
 (0)