1use std::io;
2
3use io::BufWriter;
4use io::Write;
5
6use exif::Context;
7use exif::Tag;
8
9#[derive(serde::Serialize)]
10pub struct TagDTO {
11 pub context: &'static str,
12 pub tag_num: u16,
13 pub name: String,
14}
15
16pub fn str2tag(s: &str, num: u16) -> Option<Tag> {
17 match s {
18 "tiff" => Some(Tag(Context::Tiff, num)),
19 "exif" => Some(Tag(Context::Exif, num)),
20 "gps" => Some(Tag(Context::Gps, num)),
21 "interop" => Some(Tag(Context::Interop, num)),
22 _ => None,
23 }
24}
25
26impl From<Tag> for TagDTO {
27 fn from(t: Tag) -> Self {
28 let ctx: Context = t.0;
29 let tag_num: u16 = t.1;
30 let context: &str = match ctx {
31 Context::Tiff => "tiff",
32 Context::Exif => "exif",
33 Context::Gps => "gps",
34 Context::Interop => "interop",
35 _ => "unspecified",
36 };
37 let name: String = format!("{t}");
38 Self {
39 context,
40 tag_num,
41 name,
42 }
43 }
44}
45
46pub fn tag2string(tag: Tag) -> String {
47 format!("{tag}")
48}
49
50pub const TAGS: &[Tag] = &[
51 Tag::Acceleration,
52 Tag::ApertureValue,
53 Tag::Artist,
54 Tag::BitsPerSample,
55 Tag::BodySerialNumber,
56 Tag::BrightnessValue,
57 Tag::CFAPattern,
58 Tag::CameraElevationAngle,
59 Tag::CameraOwnerName,
60 Tag::ColorSpace,
61 Tag::ComponentsConfiguration,
62 Tag::CompositeImage,
63 Tag::CompressedBitsPerPixel,
64 Tag::Compression,
65 Tag::Contrast,
66 Tag::Copyright,
67 Tag::CustomRendered,
68 Tag::DateTime,
69 Tag::DateTimeDigitized,
70 Tag::DateTimeOriginal,
71 Tag::DeviceSettingDescription,
72 Tag::DigitalZoomRatio,
73 Tag::ExifVersion,
74 Tag::ExposureBiasValue,
75 Tag::ExposureIndex,
76 Tag::ExposureMode,
77 Tag::ExposureProgram,
78 Tag::ExposureTime,
79 Tag::FNumber,
80 Tag::FileSource,
81 Tag::Flash,
82 Tag::FlashEnergy,
83 Tag::FlashpixVersion,
84 Tag::FocalLength,
85 Tag::FocalLengthIn35mmFilm,
86 Tag::FocalPlaneResolutionUnit,
87 Tag::FocalPlaneXResolution,
88 Tag::FocalPlaneYResolution,
89 Tag::GPSAltitude,
90 Tag::GPSAltitudeRef,
91 Tag::GPSAreaInformation,
92 Tag::GPSDOP,
93 Tag::GPSDateStamp,
94 Tag::GPSDestBearing,
95 Tag::GPSDestBearingRef,
96 Tag::GPSDestDistance,
97 Tag::GPSDestDistanceRef,
98 Tag::GPSDestLatitude,
99 Tag::GPSDestLatitudeRef,
100 Tag::GPSDestLongitude,
101 Tag::GPSDestLongitudeRef,
102 Tag::GPSDifferential,
103 Tag::GPSHPositioningError,
104 Tag::GPSImgDirection,
105 Tag::GPSImgDirectionRef,
106 Tag::GPSLatitude,
107 Tag::GPSLatitudeRef,
108 Tag::GPSLongitude,
109 Tag::GPSLongitudeRef,
110 Tag::GPSMapDatum,
111 Tag::GPSMeasureMode,
112 Tag::GPSProcessingMethod,
113 Tag::GPSSatellites,
114 Tag::GPSSpeed,
115 Tag::GPSSpeedRef,
116 Tag::GPSStatus,
117 Tag::GPSTimeStamp,
118 Tag::GPSTrack,
119 Tag::GPSTrackRef,
120 Tag::GPSVersionID,
121 Tag::GainControl,
122 Tag::Gamma,
123 Tag::Humidity,
124 Tag::ISOSpeed,
125 Tag::ISOSpeedLatitudeyyy,
126 Tag::ISOSpeedLatitudezzz,
127 Tag::ImageDescription,
128 Tag::ImageLength,
129 Tag::ImageUniqueID,
130 Tag::ImageWidth,
131 Tag::InteroperabilityIndex,
132 Tag::InteroperabilityVersion,
133 Tag::JPEGInterchangeFormat,
134 Tag::JPEGInterchangeFormatLength,
135 Tag::LensMake,
136 Tag::LensModel,
137 Tag::LensSerialNumber,
138 Tag::LensSpecification,
139 Tag::LightSource,
140 Tag::Make,
141 Tag::MakerNote,
142 Tag::MaxApertureValue,
143 Tag::MeteringMode,
144 Tag::Model,
145 Tag::OECF,
146 Tag::OffsetTime,
147 Tag::OffsetTimeDigitized,
148 Tag::OffsetTimeOriginal,
149 Tag::Orientation,
150 Tag::PhotographicSensitivity,
151 Tag::PhotometricInterpretation,
152 Tag::PixelXDimension,
153 Tag::PixelYDimension,
154 Tag::PlanarConfiguration,
155 Tag::Pressure,
156 Tag::PrimaryChromaticities,
157 Tag::RecommendedExposureIndex,
158 Tag::ReferenceBlackWhite,
159 Tag::RelatedImageFileFormat,
160 Tag::RelatedImageLength,
161 Tag::RelatedImageWidth,
162 Tag::RelatedSoundFile,
163 Tag::ResolutionUnit,
164 Tag::RowsPerStrip,
165 Tag::SamplesPerPixel,
166 Tag::Saturation,
167 Tag::SceneCaptureType,
168 Tag::SceneType,
169 Tag::SensingMethod,
170 Tag::SensitivityType,
171 Tag::Sharpness,
172 Tag::ShutterSpeedValue,
173 Tag::Software,
174 Tag::SourceExposureTimesOfCompositeImage,
175 Tag::SourceImageNumberOfCompositeImage,
176 Tag::SpatialFrequencyResponse,
177 Tag::SpectralSensitivity,
178 Tag::StandardOutputSensitivity,
179 Tag::StripByteCounts,
180 Tag::StripOffsets,
181 Tag::SubSecTime,
182 Tag::SubSecTimeDigitized,
183 Tag::SubSecTimeOriginal,
184 Tag::SubjectArea,
185 Tag::SubjectDistance,
186 Tag::SubjectDistanceRange,
187 Tag::SubjectLocation,
188 Tag::Temperature,
189 Tag::TileByteCounts,
190 Tag::TileOffsets,
191 Tag::TransferFunction,
192 Tag::UserComment,
193 Tag::WaterDepth,
194 Tag::WhiteBalance,
195 Tag::WhitePoint,
196 Tag::XResolution,
197 Tag::YCbCrCoefficients,
198 Tag::YCbCrPositioning,
199 Tag::YCbCrSubSampling,
200 Tag::YResolution,
201];
202
203pub fn print_tags() -> Result<(), io::Error> {
204 for tag in TAGS {
205 println!("{tag}");
206 }
207
208 Ok(())
209}
210
211pub fn tag2json<W>(tag: Tag, wtr: W) -> Result<(), io::Error>
212where
213 W: Write,
214{
215 let dto: TagDTO = tag.into();
216 serde_json::to_writer(wtr, &dto)?;
217 Ok(())
218}
219
220pub fn tags2json<W>(mut wtr: W) -> Result<(), io::Error>
221where
222 W: Write,
223{
224 for tag in TAGS {
225 tag2json(*tag, &mut wtr)?;
226 writeln!(&mut wtr)?;
227 }
228
229 wtr.flush()
230}
231
232pub fn tags2json2stdout() -> Result<(), io::Error> {
233 let o = io::stdout();
234 let mut ol = o.lock();
235 tags2json(BufWriter::new(&mut ol))?;
236 ol.flush()
237}