github.com/boki/go-xmp@v1.0.1/models/xmp_base/types.go (about) 1 // Copyright (c) 2017-2018 Alexander Eichhorn 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 // not use this file except in compliance with the License. You may obtain 5 // a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations 13 // under the License. 14 15 // Package xmpbase implements the XMP namespace as defined by XMP Specification Part 2. 16 package xmpbase 17 18 import ( 19 "bytes" 20 "trimmer.io/go-xmp/xmp" 21 ) 22 23 type Rating float64 24 25 const ( 26 RatingRejected Rating = -1 27 RatingUnrated Rating = 0 28 Rating1 Rating = 1 29 Rating2 Rating = 2 30 Rating3 Rating = 3 31 Rating4 Rating = 4 32 Rating5 Rating = 5 33 ) 34 35 // 8.7 xmpidq namespace 36 // 37 // A qualifier providing the name of the formal identification scheme 38 // used for an item in the xmp:Identifier array. 39 // 40 // Form 1: <rdf:li>http://www.example.com/</rdf:li> 41 // Form 2: 42 // <rdf:li> 43 // <rdf:Description> 44 // <rdf:value>http://www.example.com/xmp_example/xmp/identifier3</rdf:value> 45 // <xmpidq:Scheme>myscheme</xmpidq:Scheme> 46 // </rdf:Description> 47 // </rdf:li> 48 // Form 3: 49 // <rdf:li xmpidq:Scheme="myscheme">http://www.example.com/</rdf:li> 50 51 type Identifier struct { 52 ID string `xmp:"rdf:value"` 53 Scheme string `xmp:"xmpidq:Scheme"` 54 } 55 56 func (x Identifier) MarshalXMP(e *xmp.Encoder, node *xmp.Node, m xmp.Model) error { 57 if x.Scheme == "" { 58 return e.EncodeElement(x.ID, node) 59 } else { 60 id := struct { 61 ID string `xmp:"rdf:value"` 62 Scheme string `xmp:"xmpidq:Scheme"` 63 }{ 64 ID: x.ID, 65 Scheme: x.Scheme, 66 } 67 return e.EncodeElement(id, node) 68 } 69 } 70 71 func (x *Identifier) UnmarshalXMP(d *xmp.Decoder, node *xmp.Node, m xmp.Model) error { 72 id := struct { 73 ID string `xmp:"rdf:value"` 74 Scheme string `xmp:"xmpidq:Scheme"` 75 }{ 76 ID: x.ID, 77 Scheme: x.Scheme, 78 } 79 var err error 80 if len(node.Nodes) == 0 && len(node.Attr) == 0 { 81 err = d.DecodeElement(&id.ID, node) // value-only from node.Value 82 } else if len(node.Nodes) == 0 { 83 err = d.DecodeElement(&id.ID, node) // value from node.Value 84 err = d.DecodeElement(&id, node) // scheme from attr 85 } else { 86 err = d.DecodeElement(&id, node.Nodes[0]) // both from child nodes 87 } 88 if err != nil { 89 return err 90 } 91 x.ID = id.ID 92 x.Scheme = id.Scheme 93 return nil 94 } 95 96 func (x Identifier) MarshalText() ([]byte, error) { 97 buf := bytes.Buffer{} 98 if x.Scheme != "" { 99 buf.WriteString(x.Scheme) 100 buf.WriteByte(':') 101 } 102 buf.WriteString(x.ID) 103 return buf.Bytes(), nil 104 } 105 106 func (x *Identifier) UnmarshalText(data []byte) error { 107 x.ID = string(data) 108 return nil 109 } 110 111 type IdentifierArray []Identifier 112 113 func NewIdentifierArray(items ...interface{}) IdentifierArray { 114 x := make(IdentifierArray, 0) 115 for _, v := range items { 116 if s := xmp.ToString(v); s != "" { 117 x = append(x, Identifier{ID: s}) 118 } 119 } 120 return x 121 } 122 123 func (x IdentifierArray) IsZero() bool { 124 return len(x) == 0 125 } 126 127 func (x *IdentifierArray) AddUnique(v string) error { 128 if !x.Contains(v) { 129 x.Add(v) 130 } 131 return nil 132 } 133 134 func (x *IdentifierArray) Add(value string) { 135 *x = append(*x, Identifier{ID: value}) 136 } 137 138 func (x *IdentifierArray) Contains(v string) bool { 139 return x.Index(v) > -1 140 } 141 142 func (x *IdentifierArray) Index(val string) int { 143 for i, v := range *x { 144 if v.ID == val { 145 return i 146 } 147 } 148 return -1 149 } 150 151 func (x *IdentifierArray) Remove(v string) { 152 if idx := x.Index(v); idx > -1 { 153 *x = append((*x)[:idx], (*x)[:idx+1]...) 154 } 155 } 156 157 func (x IdentifierArray) Typ() xmp.ArrayType { 158 return xmp.ArrayTypeUnordered 159 } 160 161 func (x IdentifierArray) MarshalXMP(e *xmp.Encoder, node *xmp.Node, m xmp.Model) error { 162 return xmp.MarshalArray(e, node, x.Typ(), x) 163 } 164 165 func (x *IdentifierArray) UnmarshalXMP(d *xmp.Decoder, node *xmp.Node, m xmp.Model) error { 166 return xmp.UnmarshalArray(d, node, x.Typ(), x) 167 } 168 169 // Part 2: 1.2.2.4 Thumbnail 170 type Thumbnail struct { 171 Format string `xmp:"xmpGImg:format"` 172 Width int64 `xmp:"xmpGImg:height"` 173 Height int64 `xmp:"xmpGImg:width"` 174 Image []byte `xmp:"xmpGImg:image"` 175 } 176 177 func (x Thumbnail) IsZero() bool { 178 return x.Format == "" && x.Width == 0 && x.Height == 0 && len(x.Image) == 0 179 } 180 181 func (x Thumbnail) MarshalXMP(e *xmp.Encoder, node *xmp.Node, m xmp.Model) error { 182 if x.IsZero() { 183 return nil 184 } 185 type _t Thumbnail 186 return e.EncodeElement(_t(x), node) 187 } 188 189 type ThumbnailArray []Thumbnail 190 191 func (x ThumbnailArray) Typ() xmp.ArrayType { 192 return xmp.ArrayTypeAlternative 193 } 194 195 func (x ThumbnailArray) MarshalXMP(e *xmp.Encoder, node *xmp.Node, m xmp.Model) error { 196 return xmp.MarshalArray(e, node, x.Typ(), x) 197 } 198 199 func (x *ThumbnailArray) UnmarshalXMP(d *xmp.Decoder, node *xmp.Node, m xmp.Model) error { 200 return xmp.UnmarshalArray(d, node, x.Typ(), x) 201 } 202 203 // Metadata Workinggroup Guidelines 2.0, 2010 204 // stArea 205 // http://ns.adobe.com/xmp/sType/Area# 206 type Area struct { 207 X float64 `xmp:"stArea:x,attr"` 208 Y float64 `xmp:"stArea:y,attr"` 209 W float64 `xmp:"stArea:w,attr"` 210 H float64 `xmp:"stArea:h,attr"` 211 D float64 `xmp:"stArea:d,attr"` 212 Unit AreaUnit `xmp:"stArea:unit,attr"` 213 } 214 215 type AreaUnit string 216 217 const ( 218 AreaUnitRatio AreaUnit = "normalized" 219 AreaUnitPixel AreaUnit = "pixel" 220 ) 221 222 func (x Area) IsZero() bool { 223 return x.X == 0 && x.Y == 0 && x.W == 0 && x.H == 0 && x.D == 0 && x.Unit == "" 224 } 225 226 func (x Area) MarshalXMP(e *xmp.Encoder, node *xmp.Node, m xmp.Model) error { 227 if x.IsZero() { 228 return nil 229 } 230 type _t Area 231 return e.EncodeElement(_t(x), node) 232 }