...

Source file src/github.com/dsoprea/go-exif/v3/undefined/exif_927C_maker_note.go

Documentation: github.com/dsoprea/go-exif/v3/undefined

     1  package exifundefined
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"crypto/sha1"
     8  	"encoding/binary"
     9  
    10  	"github.com/dsoprea/go-logging"
    11  
    12  	"github.com/dsoprea/go-exif/v3/common"
    13  )
    14  
    15  type Tag927CMakerNote struct {
    16  	MakerNoteType  []byte
    17  	MakerNoteBytes []byte
    18  }
    19  
    20  func (Tag927CMakerNote) EncoderName() string {
    21  	return "Codec927CMakerNote"
    22  }
    23  
    24  func (mn Tag927CMakerNote) String() string {
    25  	parts := make([]string, len(mn.MakerNoteType))
    26  
    27  	for i, c := range mn.MakerNoteType {
    28  		parts[i] = fmt.Sprintf("%02x", c)
    29  	}
    30  
    31  	h := sha1.New()
    32  
    33  	_, err := h.Write(mn.MakerNoteBytes)
    34  	log.PanicIf(err)
    35  
    36  	digest := h.Sum(nil)
    37  
    38  	return fmt.Sprintf("MakerNote<TYPE-ID=[%s] LEN=(%d) SHA1=[%020x]>", strings.Join(parts, " "), len(mn.MakerNoteBytes), digest)
    39  }
    40  
    41  type Codec927CMakerNote struct {
    42  }
    43  
    44  func (Codec927CMakerNote) Encode(value interface{}, byteOrder binary.ByteOrder) (encoded []byte, unitCount uint32, err error) {
    45  	defer func() {
    46  		if state := recover(); state != nil {
    47  			err = log.Wrap(state.(error))
    48  		}
    49  	}()
    50  
    51  	mn, ok := value.(Tag927CMakerNote)
    52  	if ok == false {
    53  		log.Panicf("can only encode a Tag927CMakerNote")
    54  	}
    55  
    56  	// TODO(dustin): Confirm this size against the specification.
    57  
    58  	return mn.MakerNoteBytes, uint32(len(mn.MakerNoteBytes)), nil
    59  }
    60  
    61  func (Codec927CMakerNote) Decode(valueContext *exifcommon.ValueContext) (value EncodeableValue, err error) {
    62  	defer func() {
    63  		if state := recover(); state != nil {
    64  			err = log.Wrap(state.(error))
    65  		}
    66  	}()
    67  
    68  	// MakerNote
    69  	// TODO(dustin): !! This is the Wild Wild West. This very well might be a child IFD, but any and all OEM's define their own formats. If we're going to be writing changes and this is complete EXIF (which may not have the first eight bytes), it might be fine. However, if these are just IFDs they'll be relative to the main EXIF, this will invalidate the MakerNote data for IFDs and any other implementations that use offsets unless we can interpret them all. It be best to return to this later and just exclude this from being written for now, though means a loss of a wealth of image metadata.
    70  	//                  -> We can also just blindly try to interpret as an IFD and just validate that it's looks good (maybe it will even have a 'next ifd' pointer that we can validate is 0x0).
    71  
    72  	valueContext.SetUndefinedValueType(exifcommon.TypeByte)
    73  
    74  	valueBytes, err := valueContext.ReadBytes()
    75  	log.PanicIf(err)
    76  
    77  	// TODO(dustin): Doesn't work, but here as an example.
    78  	//             ie := NewIfdEnumerate(valueBytes, byteOrder)
    79  
    80  	// // TODO(dustin): !! Validate types (might have proprietary types, but it might be worth splitting the list between valid and not valid; maybe fail if a certain proportion are invalid, or maybe aren't less then a certain small integer)?
    81  	//             ii, err := ie.Collect(0x0)
    82  
    83  	//             for _, entry := range ii.RootIfd.Entries {
    84  	//                 fmt.Printf("ENTRY: 0x%02x %d\n", entry.TagId, entry.TagType)
    85  	//             }
    86  
    87  	var makerNoteType []byte
    88  	if len(valueBytes) >= 20 {
    89  		makerNoteType = valueBytes[:20]
    90  	} else {
    91  		makerNoteType = valueBytes
    92  	}
    93  
    94  	mn := Tag927CMakerNote{
    95  		MakerNoteType: makerNoteType,
    96  
    97  		// MakerNoteBytes has the whole length of bytes. There's always
    98  		// the chance that the first 20 bytes includes actual data.
    99  		MakerNoteBytes: valueBytes,
   100  	}
   101  
   102  	return mn, nil
   103  }
   104  
   105  func init() {
   106  	registerEncoder(
   107  		Tag927CMakerNote{},
   108  		Codec927CMakerNote{})
   109  
   110  	registerDecoder(
   111  		exifcommon.IfdExifStandardIfdIdentity.UnindexedString(),
   112  		0x927c,
   113  		Codec927CMakerNote{})
   114  }
   115  

View as plain text