Skip to content

Commit d26876c

Browse files
committed
It's working?
1 parent 707510d commit d26876c

File tree

7 files changed

+77
-31
lines changed

7 files changed

+77
-31
lines changed

src/jpeg.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
use crate::reader::ReadUtils;
12
use crate::reader::read_iptc_data;
2-
use crate::{ReadUtils, tags};
3+
use crate::tags;
4+
35
use std::collections::HashMap;
46
use std::error::Error;
57
use tags::IPTCTag;

src/lib.rs

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl IPTC {
7272
if format == ImageFormat::Jpeg {
7373
data = JPEGReader::read_iptc(&buffer)?;
7474
} else if format == ImageFormat::Tiff {
75-
println!("TIFF file detected");
75+
println!("TIFF file detected, not all tags are supported");
7676
data = TIFFReader::read_iptc(&buffer)?;
7777
} else {
7878
println!("Unsupported file, only JPEG & Tiff files are supported");
@@ -81,18 +81,3 @@ impl IPTC {
8181
Ok(IPTC { data })
8282
}
8383
}
84-
85-
trait ReadUtils {
86-
fn read_u16be(&self, offset: usize) -> u16;
87-
fn read_i16be(&self, offset: usize) -> i16;
88-
}
89-
90-
impl ReadUtils for Vec<u8> {
91-
fn read_u16be(&self, offset: usize) -> u16 {
92-
((self[offset] as u16) << 8) | (self[offset + 1] as u16)
93-
}
94-
95-
fn read_i16be(&self, offset: usize) -> i16 {
96-
((self[offset] as i16) << 8) | (self[offset + 1] as i16)
97-
}
98-
}

src/reader.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,26 @@
1-
use crate::{ReadUtils, tags};
1+
use crate::tags;
22
use std::collections::HashMap;
33
use std::error::Error;
44
use tags::IPTCTag;
55
use tags::{NULL_BLOCK, TagsMap};
66

77
const FIELD_DELIMITER: u8 = 0x1c;
88

9+
pub trait ReadUtils {
10+
fn read_u16be(&self, offset: usize) -> u16;
11+
fn read_i16be(&self, offset: usize) -> i16;
12+
}
13+
14+
impl ReadUtils for Vec<u8> {
15+
fn read_u16be(&self, offset: usize) -> u16 {
16+
((self[offset] as u16) << 8) | (self[offset + 1] as u16)
17+
}
18+
19+
fn read_i16be(&self, offset: usize) -> i16 {
20+
((self[offset] as i16) << 8) | (self[offset + 1] as i16)
21+
}
22+
}
23+
924
#[derive(Debug)]
1025
struct Block {
1126
resource_id: i16,

src/tiff.rs

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use crate::{ReadUtils, tags};
1+
use crate::tags;
22
use std::collections::HashMap;
33
use std::error::Error;
44
use std::io::Cursor;
55
use tags::IPTCTag;
66
use tiff::{
7-
decoder::{Decoder, DecodingResult, ifd::Value},
7+
decoder::{Decoder, ifd::Value},
88
tags::Tag,
99
};
1010
use xml::reader::{EventReader, XmlEvent};
@@ -18,6 +18,8 @@ impl TIFFReader {
1818

1919
let tag_value = decoder.get_tag(Tag::Unknown(700))?;
2020

21+
// println!("Tag value: {:?}", tag_value);
22+
2123
// Convert the tag value to bytes
2224
let bytes: Vec<u8> = match tag_value {
2325
Value::Byte(val) => vec![val],
@@ -32,34 +34,59 @@ impl TIFFReader {
3234
_ => vec![],
3335
};
3436

35-
println!("Bytes: {:?}", bytes);
37+
// println!("Bytes: {:?}", bytes);
3638

3739
// Parse the XMP data
3840
let data = read_xmp_data(&bytes)?;
39-
println!("Data: {:?}", data);
4041

41-
Ok(data) // Return the parsed data instead of empty HashMap
42+
Ok(data)
4243
}
4344
}
4445

4546
fn read_xmp_data(data: &[u8]) -> Result<HashMap<IPTCTag, String>, Box<dyn Error>> {
47+
// println!("Raw bytes: {:?}", data);
48+
// println!("As string: {}", String::from_utf8_lossy(data));
49+
4650
let parser = EventReader::new(Cursor::new(data));
4751
let mut iptc_data = HashMap::new();
4852
let mut current_tag: Option<IPTCTag> = None;
4953
let mut in_creator_seq = false;
5054

5155
for event in parser {
5256
match event? {
53-
XmlEvent::StartElement { name, .. } => match name.local_name.as_str() {
54-
"creator" => in_creator_seq = true,
55-
"li" if in_creator_seq => current_tag = Some(IPTCTag::ByLine),
56-
"Caption" => current_tag = Some(IPTCTag::Caption),
57-
"Description" => current_tag = Some(IPTCTag::Caption),
58-
_ => {}
59-
},
57+
XmlEvent::StartElement {
58+
name, attributes, ..
59+
} => {
60+
match name.local_name.as_str() {
61+
"creator" => in_creator_seq = true,
62+
"li" if in_creator_seq => current_tag = Some(IPTCTag::ByLine),
63+
"Description" => {
64+
// Look for photoshop:State and photoshop:Country in attributes
65+
for attr in attributes {
66+
if attr.name.prefix.as_deref() == Some("photoshop") {
67+
match attr.name.local_name.as_str() {
68+
"State" => {
69+
iptc_data.insert(IPTCTag::ProvinceOrState, attr.value);
70+
}
71+
"Country" => {
72+
iptc_data.insert(
73+
IPTCTag::CountryOrPrimaryLocationName,
74+
attr.value,
75+
);
76+
}
77+
_ => {}
78+
}
79+
}
80+
}
81+
}
82+
_ => {}
83+
}
84+
}
6085
XmlEvent::Characters(data) => {
6186
if let Some(tag) = &current_tag {
62-
iptc_data.insert(tag.clone(), data);
87+
if !data.trim().is_empty() {
88+
iptc_data.insert(tag.clone(), data);
89+
}
6390
}
6491
}
6592
XmlEvent::EndElement { name } => {

tests/DSC3003.jpg

1.6 MB
Loading

tests/DSC3003.tif

15.3 MB
Binary file not shown.

tests/tiff.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use std::error::Error;
2+
use std::path::Path;
3+
4+
use iptc::IPTC;
5+
use iptc::IPTCTag;
6+
7+
#[test]
8+
fn tiff_test() -> Result<(), Box<dyn Error>> {
9+
// Tiff files should work too
10+
let image_path = Path::new("tests/DSC3003.tif");
11+
let iptc = IPTC::read_from_path(&image_path)?;
12+
13+
let province_or_state = iptc.get(IPTCTag::ProvinceOrState);
14+
assert_eq!(province_or_state, "Ontario");
15+
16+
Ok(())
17+
}

0 commit comments

Comments
 (0)