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  }