mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-27 03:18:12 +08:00
Add basic thumbnail extraction to Rawkit (#2659)
* Add `CompressionValue` * Rename `Transform` to `OrientationValue` * Add basic thumbnail extraction * Add `ThumbnailFormat` * fmt + clippy fixes
This commit is contained in:
@@ -26,8 +26,8 @@ pub enum TagId {
|
||||
RowsPerStrip = 0x116,
|
||||
StripByteCounts = 0x117,
|
||||
SubIfd = 0x14a,
|
||||
JpegOffset = 0x201,
|
||||
JpegLength = 0x202,
|
||||
ThumbnailOffset = 0x201,
|
||||
ThumbnailLength = 0x202,
|
||||
SonyToneCurve = 0x7010,
|
||||
BlackLevel = 0x7310,
|
||||
WhiteBalanceRggbLevels = 0x7313,
|
||||
@@ -88,10 +88,10 @@ impl Ifd {
|
||||
}
|
||||
|
||||
file.seek_from_start(offset)?;
|
||||
let num = file.read_u16()?;
|
||||
let num_entries = file.read_u16()?;
|
||||
|
||||
let mut ifd_entries = Vec::with_capacity(num.into());
|
||||
for _ in 0..num {
|
||||
let mut ifd_entries = Vec::with_capacity(num_entries.into());
|
||||
for _ in 0..num_entries {
|
||||
let tag = file.read_u16()?.into();
|
||||
let the_type = file.read_u16()?.into();
|
||||
let count = file.read_u32()?;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::types::{Array, ConstArray, TagType, TypeByte, TypeIfd, TypeLong, TypeNumber, TypeOrientation, TypeSRational, TypeSShort, TypeShort, TypeSonyToneCurve, TypeString};
|
||||
use super::types::{Array, ConstArray, TagType, TypeByte, TypeCompression, TypeIfd, TypeLong, TypeNumber, TypeOrientation, TypeSRational, TypeSShort, TypeShort, TypeSonyToneCurve, TypeString};
|
||||
use super::{Ifd, TagId, TiffError, TiffRead};
|
||||
use std::io::{Read, Seek};
|
||||
|
||||
@@ -22,8 +22,8 @@ pub struct SamplesPerPixel;
|
||||
pub struct RowsPerStrip;
|
||||
pub struct StripByteCounts;
|
||||
pub struct SubIfd;
|
||||
pub struct JpegOffset;
|
||||
pub struct JpegLength;
|
||||
pub struct ThumbnailOffset;
|
||||
pub struct ThumbnailLength;
|
||||
pub struct SonyDataOffset;
|
||||
pub struct SonyToneCurve;
|
||||
pub struct BlackLevel;
|
||||
@@ -55,7 +55,7 @@ impl SimpleTag for BitsPerSample {
|
||||
}
|
||||
|
||||
impl SimpleTag for Compression {
|
||||
type Type = TypeShort;
|
||||
type Type = TypeCompression;
|
||||
|
||||
const ID: TagId = TagId::Compression;
|
||||
const NAME: &'static str = "Compression";
|
||||
@@ -124,17 +124,17 @@ impl SimpleTag for SubIfd {
|
||||
const NAME: &'static str = "SubIFD";
|
||||
}
|
||||
|
||||
impl SimpleTag for JpegOffset {
|
||||
impl SimpleTag for ThumbnailOffset {
|
||||
type Type = TypeLong;
|
||||
|
||||
const ID: TagId = TagId::JpegOffset;
|
||||
const ID: TagId = TagId::ThumbnailOffset;
|
||||
const NAME: &'static str = "Jpeg Offset";
|
||||
}
|
||||
|
||||
impl SimpleTag for JpegLength {
|
||||
impl SimpleTag for ThumbnailLength {
|
||||
type Type = TypeLong;
|
||||
|
||||
const ID: TagId = TagId::JpegLength;
|
||||
const ID: TagId = TagId::ThumbnailLength;
|
||||
const NAME: &'static str = "Jpeg Length";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::file::TiffRead;
|
||||
use super::values::{CurveLookupTable, Rational, Transform};
|
||||
use super::values::{CompressionValue, CurveLookupTable, OrientationValue, Rational};
|
||||
use super::{Ifd, IfdTagType, TiffError};
|
||||
use std::io::{Read, Seek};
|
||||
|
||||
@@ -350,6 +350,7 @@ impl<T: PrimitiveType, const N: usize> TagType for ConstArray<T, N> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TypeCompression;
|
||||
pub struct TypeString;
|
||||
pub struct TypeSonyToneCurve;
|
||||
pub struct TypeOrientation;
|
||||
@@ -376,19 +377,17 @@ impl TagType for TypeSonyToneCurve {
|
||||
}
|
||||
|
||||
impl TagType for TypeOrientation {
|
||||
type Output = Transform;
|
||||
type Output = OrientationValue;
|
||||
|
||||
fn read<R: Read + Seek>(file: &mut TiffRead<R>) -> Result<Self::Output, TiffError> {
|
||||
Ok(match TypeShort::read(file)? {
|
||||
1 => Transform::Horizontal,
|
||||
2 => Transform::MirrorHorizontal,
|
||||
3 => Transform::Rotate180,
|
||||
4 => Transform::MirrorVertical,
|
||||
5 => Transform::MirrorHorizontalRotate270,
|
||||
6 => Transform::Rotate90,
|
||||
7 => Transform::MirrorHorizontalRotate90,
|
||||
8 => Transform::Rotate270,
|
||||
_ => return Err(TiffError::InvalidValue),
|
||||
})
|
||||
OrientationValue::try_from(TypeShort::read(file)?).map_err(|_| TiffError::InvalidValue)
|
||||
}
|
||||
}
|
||||
|
||||
impl TagType for TypeCompression {
|
||||
type Output = CompressionValue;
|
||||
|
||||
fn read<R: Read + Seek>(file: &mut TiffRead<R>) -> Result<Self::Output, TiffError> {
|
||||
CompressionValue::try_from(TypeShort::read(file)?).map_err(|_| TiffError::InvalidValue)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
|
||||
pub trait ToFloat {
|
||||
fn to_float(&self) -> f64;
|
||||
}
|
||||
@@ -51,29 +53,80 @@ impl CurveLookupTable {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
pub enum Transform {
|
||||
Horizontal,
|
||||
MirrorHorizontal,
|
||||
Rotate180,
|
||||
MirrorVertical,
|
||||
MirrorHorizontalRotate270,
|
||||
Rotate90,
|
||||
MirrorHorizontalRotate90,
|
||||
Rotate270,
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug, IntoPrimitive, TryFromPrimitive)]
|
||||
#[repr(u16)]
|
||||
pub enum OrientationValue {
|
||||
Horizontal = 1,
|
||||
MirrorHorizontal = 2,
|
||||
Rotate180 = 3,
|
||||
MirrorVertical = 4,
|
||||
MirrorHorizontalRotate270 = 5,
|
||||
Rotate90 = 6,
|
||||
MirrorHorizontalRotate90 = 7,
|
||||
Rotate270 = 8,
|
||||
}
|
||||
|
||||
impl Transform {
|
||||
impl OrientationValue {
|
||||
pub fn is_identity(&self) -> bool {
|
||||
*self == Transform::Horizontal
|
||||
*self == Self::Horizontal
|
||||
}
|
||||
|
||||
pub fn will_swap_coordinates(&self) -> bool {
|
||||
use Transform as Tr;
|
||||
|
||||
match *self {
|
||||
Tr::Horizontal | Tr::MirrorHorizontal | Tr::Rotate180 | Tr::MirrorVertical => false,
|
||||
Tr::MirrorHorizontalRotate270 | Tr::Rotate90 | Tr::MirrorHorizontalRotate90 | Tr::Rotate270 => true,
|
||||
Self::Horizontal | Self::MirrorHorizontal | Self::Rotate180 | Self::MirrorVertical => false,
|
||||
Self::MirrorHorizontalRotate270 | Self::Rotate90 | Self::MirrorHorizontalRotate90 | Self::Rotate270 => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
|
||||
#[repr(u16)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum CompressionValue {
|
||||
Uncompressed = 1,
|
||||
CCITT_1D = 2,
|
||||
T4 = 3,
|
||||
T6 = 4,
|
||||
LZW = 5,
|
||||
JPEG_Old = 6,
|
||||
JPEG = 7,
|
||||
AdobeDeflate = 8,
|
||||
JBIG_BW = 9,
|
||||
JBIG_Color = 10,
|
||||
KODAK_626 = 262,
|
||||
Next = 32766,
|
||||
Sony_ARW_Compressed = 32767,
|
||||
Packed_Raw = 32769,
|
||||
Samsung_SRW_Compressed = 32770,
|
||||
CCIRLEW = 32771,
|
||||
Samsung_SRW_Compressed_2 = 32772,
|
||||
PackedBits = 32773,
|
||||
Thunderscan = 32809,
|
||||
Kodak_KDC_Compressed = 32867,
|
||||
IT8CTPAD = 32895,
|
||||
IT8LW = 32896,
|
||||
IT8MP = 32897,
|
||||
IT8BL = 32898,
|
||||
PixarFilm = 32908,
|
||||
PixarLog = 32909,
|
||||
Deflate = 32946,
|
||||
DCS = 32947,
|
||||
AperioJPEG2K_YCbCr = 33003,
|
||||
AperioJPEG2K_RGB = 33005,
|
||||
JBIG = 34661,
|
||||
SGILog = 34676,
|
||||
SGILog24 = 34677,
|
||||
JPEG2K = 34712,
|
||||
NikonNEFCompressed = 34713,
|
||||
JBIG2_TIFF_FX = 34715,
|
||||
ESRI_Lerc = 34887,
|
||||
LossyJPEG = 34892,
|
||||
LZMA2 = 34925,
|
||||
PNG = 34933,
|
||||
JPEG_XR = 34934,
|
||||
Zstd = 50000,
|
||||
WebP = 50001,
|
||||
JPEG_XL = 52546,
|
||||
Kodak_DCR_Compressed = 65000,
|
||||
Pentax_PEF_Compressed = 65535,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user