Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use tiff tag types from tiff crate #11

Merged
merged 5 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 95 additions & 31 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ repository = "https://github.com/georust/geotiff"
byteorder = "*"
enum_primitive = "*"
num = "*"
tiff = "0.9"
14 changes: 5 additions & 9 deletions src/tiff.rs → src/geotiff.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::collections::HashSet;

use enum_primitive::FromPrimitive;
use tiff::tags::Type;

use crate::lowlevel::*;

Expand Down Expand Up @@ -35,11 +36,11 @@ pub struct IFD {
/// tag values.
#[derive(Debug)]
pub struct IFDEntry {
pub tag: TIFFTag,
pub tpe: TagType,
pub count: LONG,
pub tag: TIFFTag,
pub tpe: Type,
pub count: LONG,
pub value_offset: LONG,
pub value: Vec<TagValue>,
pub value: Vec<TagValue>,
}

/// Implementations for the IFD struct.
Expand All @@ -62,11 +63,6 @@ pub fn decode_tag(value: u16) -> Option<TIFFTag> {
TIFFTag::from_u16(value)
}

/// Decodes an u16 value into a TagType.
pub fn decode_tag_type(tpe: u16) -> Option<TagType> {
TagType::from_u16(tpe)
}

/// Validation functions to make sure all the required tags are existing for a certain GeoTiff
/// image type (e.g., grayscale or RGB image).
pub fn validate_required_tags_for(typ: &ImageType) -> Option<HashSet<TIFFTag>> {
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ extern crate num;
use std::fmt;
use std::io::Result;

pub mod geotiff;
mod lowlevel;
mod reader;
pub mod tiff;

pub use geotiff::TIFF;
use reader::*;
pub use tiff::TIFF;

/// The GeoTIFF library reads `.tiff` files.
///
Expand Down
52 changes: 19 additions & 33 deletions src/lowlevel.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![allow(dead_code)]
use tiff::tags::Type;

// Base types of the TIFF format.
pub type BYTE = u8;
Expand All @@ -23,40 +23,26 @@ enum_from_primitive! {
}
}

enum_from_primitive! {
#[repr(u16)]
#[derive(Debug,PartialEq)]
pub enum TagType {
ByteTag = 1,
ASCIITag = 2,
ShortTag = 3,
LongTag = 4,
RationalTag = 5,
SignedByteTag = 6,
UndefinedTag = 7,
SignedShortTag = 8,
SignedLongTag = 9,
SignedRationalTag = 10,
FloatTag = 11,
DoubleTag = 12,
}
}

/// Helper function that returns the size of a certain tag.
pub fn tag_size(t: &TagType) -> u32 {
pub fn tag_size(t: &Type) -> u32 {
match *t {
TagType::ByteTag => 1,
TagType::ASCIITag => 1,
TagType::ShortTag => 2,
TagType::LongTag => 4,
TagType::RationalTag => 8,
TagType::SignedByteTag => 1,
TagType::UndefinedTag => 1,
TagType::SignedShortTag => 2,
TagType::SignedLongTag => 2,
TagType::SignedRationalTag => 8,
TagType::FloatTag => 4,
TagType::DoubleTag => 8,
Type::BYTE => 1,
Type::ASCII => 1,
Type::SHORT => 2,
Type::LONG => 4,
Type::RATIONAL => 8,
Type::SBYTE => 1,
Type::UNDEFINED => 1,
Type::SSHORT => 2,
Type::SLONG => 2,
Type::SRATIONAL => 8,
Type::FLOAT => 4,
Type::DOUBLE => 8,
Type::IFD => 4,
Type::LONG8 => 8,
Type::SLONG8 => 8,
Type::IFD8 => 8,
_ => unimplemented!(),
}
}

Expand Down
46 changes: 28 additions & 18 deletions src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ use std::path::Path;

use byteorder::{BigEndian, ByteOrder, LittleEndian, ReadBytesExt};
use num::FromPrimitive;
use tiff::tags::Type;

use crate::lowlevel::{tag_size, TIFFByteOrder, TIFFTag, TagType, TagValue};
use crate::tiff::{decode_tag, decode_tag_type, IFDEntry, IFD, TIFF};
use crate::geotiff::{decode_tag, IFDEntry, IFD, TIFF};
use crate::lowlevel::{tag_size, TIFFByteOrder, TIFFTag, TagValue};

/// A helper trait to indicate that something needs to be seekable and readable.
pub trait SeekableReader: Seek + Read {}
Expand Down Expand Up @@ -119,23 +120,32 @@ impl TIFFReader {
/// Converts a Vec<u8> into a TagValue, depending on the type of the tag. In the TIFF file
/// format, each tag type indicates which value it stores (e.g., a byte, ascii, or long value).
/// This means that the tag values have to be read taking the tag type into consideration.
fn vec_to_tag_value<Endian: ByteOrder>(&self, vec: Vec<u8>, tpe: &TagType) -> TagValue {
fn vec_to_tag_value<Endian: ByteOrder>(&self, vec: Vec<u8>, tpe: &Type) -> TagValue {
let len = vec.len();
match tpe {
&TagType::ByteTag => TagValue::ByteValue(vec[0]),
&TagType::ASCIITag => TagValue::AsciiValue(String::from_utf8_lossy(&vec).to_string()),
&TagType::ShortTag => TagValue::ShortValue(Endian::read_u16(&vec[..])),
&TagType::LongTag => TagValue::LongValue(Endian::read_u32(&vec[..])),
&TagType::RationalTag => TagValue::RationalValue((Endian::read_u32(&vec[..(len / 2)]),
Endian::read_u32(&vec[(len / 2)..]))),
&TagType::SignedByteTag => TagValue::SignedByteValue(vec[0] as i8),
&TagType::SignedShortTag => TagValue::SignedShortValue(Endian::read_i16(&vec[..])),
&TagType::SignedLongTag => TagValue::SignedLongValue(Endian::read_i32(&vec[..])),
&TagType::SignedRationalTag => TagValue::SignedRationalValue((Endian::read_i32(&vec[..(len / 2)]),
Endian::read_i32(&vec[(len / 2)..]))),
&TagType::FloatTag => TagValue::FloatValue(Endian::read_f32(&vec[..])),
&TagType::DoubleTag => TagValue::DoubleValue(Endian::read_f64(&vec[..])),
&TagType::UndefinedTag => TagValue::ByteValue(0),
Type::BYTE => TagValue::ByteValue(vec[0]),
Type::ASCII => TagValue::AsciiValue(String::from_utf8_lossy(&vec).to_string()),
Type::SHORT => TagValue::ShortValue(Endian::read_u16(&vec[..])),
Type::LONG => TagValue::LongValue(Endian::read_u32(&vec[..])),
Type::RATIONAL => TagValue::RationalValue((
Endian::read_u32(&vec[..(len / 2)]),
Endian::read_u32(&vec[(len / 2)..]),
)),
Type::SBYTE => TagValue::SignedByteValue(vec[0] as i8),
Type::UNDEFINED => TagValue::ByteValue(0),
Type::SSHORT => TagValue::SignedShortValue(Endian::read_i16(&vec[..])),
Type::SLONG => TagValue::SignedLongValue(Endian::read_i32(&vec[..])),
Type::SRATIONAL => TagValue::SignedRationalValue((
Endian::read_i32(&vec[..(len / 2)]),
Endian::read_i32(&vec[(len / 2)..]),
)),
Type::FLOAT => TagValue::FloatValue(Endian::read_f32(&vec[..])),
Type::DOUBLE => TagValue::DoubleValue(Endian::read_f64(&vec[..])),
Type::IFD => unimplemented!(),
Type::LONG8 => unimplemented!(),
Type::SLONG8 => unimplemented!(),
Type::IFD8 => unimplemented!(),
Comment on lines +144 to +147
Copy link
Member Author

@weiji14 weiji14 May 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO implement TagValue enum variants for these, probably in a separate PR, as will likely need some upstream changes in the tiff crate.

_ => unimplemented!(),
}
}

Expand Down Expand Up @@ -185,7 +195,7 @@ impl TIFFReader {

// Decode the type.
let tpe_msg = format!("Invalid tag type {:04X}", tpe_value);
let tpe = decode_tag_type(tpe_value).expect(&tpe_msg);
let tpe = Type::from_u16(tpe_value).expect(&tpe_msg);
let value_size = tag_size(&tpe);

// Let's get the value(s) of this tag.
Expand Down