Skip to content

Commit 6fc73df

Browse files
committed
First take
1 parent db9f74e commit 6fc73df

File tree

10 files changed

+872
-20
lines changed

10 files changed

+872
-20
lines changed

‎README.md‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
[![Tests on Linux, MacOS and Windows](https://github.com/bep/goexif/workflows/Test/badge.svg)](https://github.com/bep/goexif/actions?query=workflow:Test)
22
[![Go Report Card](https://goreportcard.com/badge/github.com/bep/goexif)](https://goreportcard.com/report/github.com/bep/goexif)
3-
[![GoDoc](https://godoc.org/github.com/bep/goexif?status.svg)](https://godoc.org/github.com/bep/goexif)
3+
[![GoDoc](https://godoc.org/github.com/bep/goexif?status.svg)](https://godoc.org/github.com/bep/goexif)
4+
5+
# Work in progress
6+
7+
This is not ready, yet, but the goal is to use this as the library to read image metadata in Hugo. The existing Go libraries I have found is not maintained anymore and too complex to build on top of. The goal of this library is to be relatively small and simple, but I may prove myself wrong.

‎fieldsexif.go‎

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package goexif
2+
3+
import "fmt"
4+
5+
const (
6+
OrientationUnspecified Orientation = iota
7+
OrientationNormal
8+
OrientationFlipH
9+
OrientationRotate180
10+
OrientationFlipV
11+
OrientationTranspose
12+
OrientationRotate270
13+
OrientationTransverse
14+
OrientationRotate90
15+
)
16+
17+
const (
18+
// TODO1 check usage.
19+
markerSOI = 0xffd8
20+
markerAPP1 = 0xffe1
21+
markerApp13 = 0xffed
22+
exifPointer = 0x8769
23+
gpsPointer = 0x8825
24+
interopPointer = 0xa005
25+
exifHeader = 0x45786966
26+
byteOrderBigEndian = 0x4d4d
27+
byteOrderLittleEndian = 0x4949
28+
tagOrientation = 0x0112
29+
tagDate = 0x0132
30+
)
31+
32+
var errStop = fmt.Errorf("stop")
33+
34+
const (
35+
typeUnsignedByte exifType = 1
36+
typeUnsignedAscii exifType = 2
37+
typeUnsignedShort exifType = 3
38+
typeUnsignedLong exifType = 4
39+
typeUnsignedRat exifType = 5
40+
typeSignedByte exifType = 6
41+
typeUndef exifType = 7
42+
typeSignedShort exifType = 8
43+
typeSignedLong exifType = 9
44+
typeSignedRat exifType = 10
45+
typeSignedFloat exifType = 11
46+
typeSignedDouble exifType = 12
47+
)
48+
49+
// Size in bytes of each type.
50+
var typeSize = map[exifType]uint32{
51+
typeUnsignedByte: 1,
52+
typeUnsignedAscii: 1,
53+
typeUnsignedShort: 2,
54+
typeUnsignedLong: 4,
55+
typeUnsignedRat: 8,
56+
typeSignedByte: 1,
57+
typeUndef: 1,
58+
typeSignedShort: 2,
59+
typeSignedLong: 4,
60+
typeSignedRat: 8,
61+
typeSignedFloat: 4,
62+
typeSignedDouble: 8,
63+
}
64+
65+
// UnknownPrefix is used as prefix for unknown tags.
66+
const UnknownPrefix = "UnknownTag_"
67+
68+
var (
69+
fieldsExif = map[uint16]string{0x100: "ImageWidth", 0x101: "ImageLength", 0x102: "BitsPerSample", 0x103: "Compression", 0x106: "PhotometricInterpretation", 0x10e: "ImageDescription", 0x10f: "Make", 0x110: "Model", 0x112: "Orientation", 0x115: "SamplesPerPixel", 0x11a: "XResolution", 0x11b: "YResolution", 0x11c: "PlanarConfiguration", 0x128: "ResolutionUnit", 0x131: "Software", 0x132: "DateTime", 0x13b: "Artist", 0x212: "YCbCrSubSampling", 0x213: "YCbCrPositioning", 0x8298: "Copyright", 0x829a: "ExposureTime", 0x829d: "FNumber", 0x8769: "ExifIFDPointer", 0x8822: "ExposureProgram", 0x8824: "SpectralSensitivity", 0x8825: "GPSInfoIFDPointer", 0x8827: "ISOSpeedRatings", 0x8828: "OECF", 0x9000: "ExifVersion", 0x9003: "DateTimeOriginal", 0x9004: "DateTimeDigitized", 0x9101: "ComponentsConfiguration", 0x9102: "CompressedBitsPerPixel", 0x9201: "ShutterSpeedValue", 0x9202: "ApertureValue", 0x9203: "BrightnessValue", 0x9204: "ExposureBiasValue", 0x9205: "MaxApertureValue", 0x9206: "SubjectDistance", 0x9207: "MeteringMode", 0x9208: "LightSource", 0x9209: "Flash", 0x920a: "FocalLength", 0x9214: "SubjectArea", 0x927c: "MakerNote", 0x9286: "UserComment", 0x9290: "SubSecTime", 0x9291: "SubSecTimeOriginal", 0x9292: "SubSecTimeDigitized", 0x9c9b: "XPTitle", 0x9c9c: "XPComment", 0x9c9d: "XPAuthor", 0x9c9e: "XPKeywords", 0x9c9f: "XPSubject", 0xa000: "FlashpixVersion", 0xa001: "ColorSpace", 0xa002: "PixelXDimension", 0xa003: "PixelYDimension", 0xa004: "RelatedSoundFile", 0xa005: "InteroperabilityIFDPointer", 0xa20b: "FlashEnergy", 0xa20c: "SpatialFrequencyResponse", 0xa20e: "FocalPlaneXResolution", 0xa20f: "FocalPlaneYResolution", 0xa210: "FocalPlaneResolutionUnit", 0xa214: "SubjectLocation", 0xa215: "ExposureIndex", 0xa217: "SensingMethod", 0xa300: "FileSource", 0xa301: "SceneType", 0xa302: "CFAPattern", 0xa401: "CustomRendered", 0xa402: "ExposureMode", 0xa403: "WhiteBalance", 0xa404: "DigitalZoomRatio", 0xa405: "FocalLengthIn35mmFilm", 0xa406: "SceneCaptureType", 0xa407: "GainControl", 0xa408: "Contrast", 0xa409: "Saturation", 0xa40a: "Sharpness", 0xa40b: "DeviceSettingDescription", 0xa40c: "SubjectDistanceRange", 0xa420: "ImageUniqueID", 0xa433: "LensMake", 0xa434: "LensModel"}
70+
fieldsGps = map[uint16]string{0x0: "GPSVersionID", 0x1: "GPSLatitudeRef", 0x2: "GPSLatitude", 0x3: "GPSLongitudeRef", 0x4: "GPSLongitude", 0x5: "GPSAltitudeRef", 0x6: "GPSAltitude", 0x7: "GPSTimeStamp", 0x8: "GPSSatelites", 0x9: "GPSStatus", 0xa: "GPSMeasureMode", 0xb: "GPSDOP", 0xc: "GPSSpeedRef", 0xd: "GPSSpeed", 0xe: "GPSTrackRef", 0xf: "GPSTrack", 0x10: "GPSImgDirectionRef", 0x11: "GPSImgDirection", 0x12: "GPSMapDatum", 0x13: "GPSDestLatitudeRef", 0x14: "GPSDestLatitude", 0x15: "GPSDestLongitudeRef", 0x16: "GPSDestLongitude", 0x17: "GPSDestBearingRef", 0x18: "GPSDestBearing", 0x19: "GPSDestDistanceRef", 0x1a: "GPSDestDistance", 0x1b: "GPSProcessingMethod", 0x1c: "GPSAreaInformation", 0x1d: "GPSDateStamp", 0x1e: "GPSDifferential"}
71+
fieldsInterop = map[uint16]string{0x1: "InteroperabilityIndex"}
72+
fieldsThumbnail = map[uint16]string{0x201: "ThumbJPEGInterchangeFormat", 0x202: "ThumbJPEGInterchangeFormatLength"}
73+
74+
fieldsAll = map[uint16]string{}
75+
)
76+
77+
func init() {
78+
for k, v := range fieldsExif {
79+
fieldsAll[k] = v
80+
}
81+
for k, v := range fieldsGps {
82+
fieldsAll[k] = v
83+
}
84+
for k, v := range fieldsInterop {
85+
fieldsAll[k] = v
86+
}
87+
for k, v := range fieldsThumbnail {
88+
fieldsAll[k] = v
89+
}
90+
}

‎fieldsiptc.go‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package goexif
2+
3+
var iptcFieldMap = map[uint8]iptcField{
4+
0: {"RecordVersion", false, "B"},
5+
5: {"ObjectName", false, "string"},
6+
7: {"EditStatus", false, "string"},
7+
10: {"Urgency", false, "B"},
8+
15: {"Category", true, "string"},
9+
20: {"SupplementalCategory", true, "string"},
10+
22: {"FixtureIdentifier", false, "string"},
11+
25: {"Keywords", true, "string"},
12+
26: {"ContentLocationCode", false, "string"},
13+
27: {"ContentLocationName", false, "string"},
14+
30: {"ReleaseDate", false, "string"},
15+
35: {"ReleaseTime", false, "string"},
16+
37: {"ExpirationDate", false, "string"},
17+
38: {"ExpirationTime", false, "string"},
18+
40: {"SpecialInstructions", false, "string"},
19+
42: {"ActionAdvised", false, "B"},
20+
45: {"ReferenceService", false, "string"},
21+
47: {"ReferenceDate", false, "string"},
22+
50: {"ReferenceNumber", false, "string"},
23+
55: {"DateCreated", false, "string"},
24+
60: {"TimeCreated", false, "string"},
25+
62: {"DigitalCreationDate", false, "string"},
26+
63: {"DigitalCreationTime", false, "string"},
27+
65: {"OriginatingProgram", false, "string"},
28+
70: {"ProgramVersion", false, "string"},
29+
75: {"ObjectCycle", false, "string"},
30+
80: {"Byline", false, "string"},
31+
85: {"BylineTitle", false, "string"},
32+
90: {"City", false, "string"},
33+
92: {"SubLocation", false, "string"},
34+
95: {"ProvinceState", false, "string"},
35+
100: {"CountryCode", false, "string"},
36+
101: {"CountryName", false, "string"},
37+
103: {"OriginalTransmissionReference", false, "string"},
38+
105: {"Headline", false, "string"},
39+
110: {"Credit", false, "string"},
40+
115: {"Source", false, "string"},
41+
116: {"Copyright", false, "string"},
42+
118: {"Contact", false, "string"},
43+
}
44+
45+
type iptcField struct {
46+
name string
47+
repeatable bool
48+
format string
49+
}

‎go.mod‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ module github.com/bep/goexif
22

33
go 1.18
44

5-
require github.com/frankban/quicktest v1.14.5
5+
require (
6+
github.com/frankban/quicktest v1.14.5
7+
github.com/google/go-cmp v0.5.9
8+
golang.org/x/text v0.12.0
9+
)
610

711
require (
8-
github.com/google/go-cmp v0.5.9 // indirect
912
github.com/kr/pretty v0.3.1 // indirect
1013
github.com/kr/text v0.2.0 // indirect
1114
github.com/rogpeppe/go-internal v1.10.0 // indirect

‎go.sum‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsK
1111
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
1212
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
1313
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
14+
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
15+
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=

‎goexif.go‎

Lines changed: 0 additions & 5 deletions
This file was deleted.

‎goexif_test.go‎

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)