github.com/boki/go-xmp@v1.0.1/models/ps/model.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  // see also Photoshop Specification at
    16  // http://www.adobe.com/devnet-apps/photoshop/fileformatashtml
    17  
    18  // Package ps implements Adobe Photoshop metadata as defined by XMP Specification Part 2 Chapter 3.2.
    19  package ps
    20  
    21  import (
    22  	"fmt"
    23  	"trimmer.io/go-xmp/xmp"
    24  )
    25  
    26  var (
    27  	NsPhotoshop = xmp.NewNamespace("photoshop", "http://ns.adobe.com/photoshop/1.0/", NewModel)
    28  )
    29  
    30  func init() {
    31  	xmp.Register(NsPhotoshop, xmp.ImageMetadata)
    32  }
    33  
    34  func NewModel(name string) xmp.Model {
    35  	return &PhotoshopInfo{}
    36  }
    37  
    38  func MakeModel(d *xmp.Document) (*PhotoshopInfo, error) {
    39  	m, err := d.MakeModel(NsPhotoshop)
    40  	if err != nil {
    41  		return nil, err
    42  	}
    43  	x, _ := m.(*PhotoshopInfo)
    44  	return x, nil
    45  }
    46  
    47  func FindModel(d *xmp.Document) *PhotoshopInfo {
    48  	if m := d.FindModel(NsPhotoshop); m != nil {
    49  		return m.(*PhotoshopInfo)
    50  	}
    51  	return nil
    52  }
    53  
    54  type PhotoshopInfo struct {
    55  	AuthorsPosition        string          `xmp:"photoshop:AuthorsPosition"`
    56  	CaptionWriter          string          `xmp:"photoshop:CaptionWriter"`
    57  	Category               string          `xmp:"photoshop:Category"`
    58  	City                   string          `xmp:"photoshop:City"`
    59  	ColorMode              ColorMode       `xmp:"photoshop:ColorMode"`
    60  	Country                string          `xmp:"photoshop:Country"`
    61  	Credit                 string          `xmp:"photoshop:Credit"`
    62  	DateCreated            xmp.Date        `xmp:"photoshop:DateCreated"`
    63  	DocumentAncestors      AnchestorArray  `xmp:"photoshop:DocumentAncestors"`
    64  	Headline               string          `xmp:"photoshop:Headline"`
    65  	History                string          `xmp:"photoshop:History"`
    66  	ICCProfile             string          `xmp:"photoshop:ICCProfile"`
    67  	Instructions           string          `xmp:"photoshop:Instructions"`
    68  	Layer                  *Layer          `xmp:"photoshop:Layer"`
    69  	SidecarForExtension    string          `xmp:"photoshop:SidecarForExtension"` // "NEF"
    70  	Source                 string          `xmp:"photoshop:Source"`
    71  	State                  string          `xmp:"photoshop:State"`
    72  	SupplementalCategories xmp.StringArray `xmp:"photoshop:SupplementalCategories"`
    73  	TextLayers             LayerList       `xmp:"photoshop:TextLayers"`
    74  	TransmissionReference  string          `xmp:"photoshop:TransmissionReference"`
    75  	Urgency                int             `xmp:"photoshop:Urgency"` // 1 - 8
    76  
    77  	EmbeddedXMPDigest string `xmp:"photoshop:EmbeddedXMPDigest,omit"` // "00000000000000000000000000000000"
    78  	LegacyIPTCDigest  string `xmp:"photoshop:LegacyIPTCDigest,omit"`  // "AA5133A9479EA0F732E6A7414060A81F"
    79  }
    80  
    81  func (x PhotoshopInfo) Can(nsName string) bool {
    82  	return NsPhotoshop.GetName() == nsName
    83  }
    84  
    85  func (x PhotoshopInfo) Namespaces() xmp.NamespaceList {
    86  	return xmp.NamespaceList{NsPhotoshop}
    87  }
    88  
    89  func (x *PhotoshopInfo) SyncModel(d *xmp.Document) error {
    90  	return nil
    91  }
    92  
    93  func (x *PhotoshopInfo) SyncFromXMP(d *xmp.Document) error {
    94  	return nil
    95  }
    96  
    97  func (x PhotoshopInfo) SyncToXMP(d *xmp.Document) error {
    98  	return nil
    99  }
   100  
   101  func (x *PhotoshopInfo) CanTag(tag string) bool {
   102  	_, err := xmp.GetNativeField(x, tag)
   103  	return err == nil
   104  }
   105  
   106  func (x *PhotoshopInfo) GetTag(tag string) (string, error) {
   107  	if v, err := xmp.GetNativeField(x, tag); err != nil {
   108  		return "", fmt.Errorf("%s: %v", NsPhotoshop.GetName(), err)
   109  	} else {
   110  		return v, nil
   111  	}
   112  }
   113  
   114  func (x *PhotoshopInfo) SetTag(tag, value string) error {
   115  	if err := xmp.SetNativeField(x, tag, value); err != nil {
   116  		return fmt.Errorf("%s: %v", NsPhotoshop.GetName(), err)
   117  	}
   118  	return nil
   119  }
   120  
   121  // 3.2.1.1 Ancestor
   122  type Anchestor struct {
   123  	AncestorID xmp.Uri `xmp:"photoshop:AncestorID"`
   124  }
   125  
   126  type AnchestorArray []Anchestor
   127  
   128  func (x AnchestorArray) Typ() xmp.ArrayType {
   129  	return xmp.ArrayTypeUnordered
   130  }
   131  
   132  func (x AnchestorArray) MarshalXMP(e *xmp.Encoder, node *xmp.Node, m xmp.Model) error {
   133  	return xmp.MarshalArray(e, node, x.Typ(), x)
   134  }
   135  
   136  func (x *AnchestorArray) UnmarshalXMP(d *xmp.Decoder, node *xmp.Node, m xmp.Model) error {
   137  	return xmp.UnmarshalArray(d, node, x.Typ(), x)
   138  }
   139  
   140  // 3.2.1.2 Layer
   141  type Layer struct {
   142  	LayerName string `xmp:"photoshop:LayerName"`
   143  	LayerText string `xmp:"photoshop:LayerText"`
   144  }
   145  
   146  func (x Layer) IsZero() bool {
   147  	return x.LayerName == "" && x.LayerText == ""
   148  }
   149  
   150  type LayerList []Layer
   151  
   152  func (x LayerList) Typ() xmp.ArrayType {
   153  	return xmp.ArrayTypeOrdered
   154  }
   155  
   156  func (x LayerList) MarshalXMP(e *xmp.Encoder, node *xmp.Node, m xmp.Model) error {
   157  	return xmp.MarshalArray(e, node, x.Typ(), x)
   158  }
   159  
   160  func (x *LayerList) UnmarshalXMP(d *xmp.Decoder, node *xmp.Node, m xmp.Model) error {
   161  	return xmp.UnmarshalArray(d, node, x.Typ(), x)
   162  }
   163  
   164  type ColorMode int
   165  
   166  const (
   167  	ColorModeBitmap       = 0 // 0 = Bitmap
   168  	ColorModeGrayscale    = 1 // 1 = Gray scale
   169  	ColorModeIndexed      = 2 // 2 = Indexed colour
   170  	ColorModeRGB          = 3 // 3 = RGB colour
   171  	ColorModeCMYK         = 4 // 4 = CMYK colour
   172  	ColorModeMultiChannel = 7 // 7 = Multi-channel
   173  	ColorModeDuotone      = 8 // 8 = Duotone
   174  	ColorModeLAB          = 9 // 9 = LAB colour
   175  )