use crate::tiff::ifd::{IFD, IFDEntry};
use crate::tiff::constants::field_types;
use log::trace;
use std::collections::HashMap;
pub fn get_field_type_size(field_type: u16) -> usize {
match field_type {
field_types::BYTE | field_types::ASCII | field_types::SBYTE | field_types::UNDEFINED => 1,
field_types::SHORT | field_types::SSHORT => 2,
field_types::LONG | field_types::SLONG | field_types::FLOAT => 4,
field_types::RATIONAL | field_types::SRATIONAL | field_types::DOUBLE => 8,
field_types::LONG8 | field_types::SLONG8 | field_types::IFD8 => 8,
_ => 1, }
}
pub fn update_ifd_tag(ifd: &mut IFD, tag: u16, entry: IFDEntry) {
ifd.entries.retain(|e| e.tag != tag);
ifd.add_entry(entry);
}
pub fn create_external_tag(
ifd: &mut IFD,
external_data: &mut HashMap<(usize, u16), Vec<u8>>,
ifd_index: usize,
tag: u16,
field_type: u16,
count: u64,
data: Vec<u8>
) {
update_ifd_tag(ifd, tag, IFDEntry::new(tag, field_type, count, 0));
external_data.insert((ifd_index, tag), data);
}
pub fn copy_tags(
dest_ifd: &mut IFD,
source_ifd: &IFD,
tags: &[u16]
) {
for &tag in tags {
if let Some(entry) = source_ifd.get_entry(tag) {
trace!("Copying tag {} from source IFD to destination", tag);
let existing_idx = dest_ifd.entries.iter().position(|e| e.tag == tag);
if let Some(idx) = existing_idx {
dest_ifd.entries.remove(idx);
}
dest_ifd.add_entry(entry.clone());
}
}
}
pub fn copy_tags_except(
dest_ifd: &mut IFD,
source_ifd: &IFD,
exclude_tags: &[u16]
) {
for entry in &source_ifd.entries {
if !exclude_tags.contains(&entry.tag) {
trace!("Copying tag {} from source IFD to destination", entry.tag);
let existing_idx = dest_ifd.entries.iter().position(|e| e.tag == entry.tag);
if let Some(idx) = existing_idx {
dest_ifd.entries.remove(idx);
}
dest_ifd.add_entry(entry.clone());
}
}
}