diff --git a/exif.go b/exif.go index ae48757..cb37422 100644 --- a/exif.go +++ b/exif.go @@ -22,6 +22,8 @@ const ( var ( exifLogger = log.NewLogger("exif.exif") + + ExifHeaderPrefixBytes = []byte("Exif\000\000") ) var ( @@ -31,7 +33,7 @@ var ( func IsExif(data []byte) (ok bool) { - if bytes.Compare(data[:6], []byte("Exif\000\000")) == 0 { + if bytes.Compare(data[:6], ExifHeaderPrefixBytes) == 0 { return true } @@ -39,6 +41,9 @@ func IsExif(data []byte) (ok bool) { } +// TODO(dustin): Isolated this to its own packge breakout the methods as independent function. There's no use for a dedicated struct. + + type Exif struct { } @@ -170,3 +175,32 @@ func (e *Exif) Collect(exifData []byte) (eh ExifHeader, index IfdIndex, err erro return eh, index, nil } + +func BuildExifHeader(byteOrder binary.ByteOrder, firstIfdOffset uint32) (headerBytes []byte, err error) { + defer func() { + if state := recover(); state != nil { + err = log.Wrap(state.(error)) + } + }() + + b := new(bytes.Buffer) + + _, err = b.Write(ExifHeaderPrefixBytes) + log.PanicIf(err) + + if byteOrder == binary.BigEndian { + _, err := b.WriteString("MM") + log.PanicIf(err) + } else { + _, err := b.WriteString("II") + log.PanicIf(err) + } + + _, err = b.Write([]byte { 0x2a, 0x00 }) + log.PanicIf(err) + + err = binary.Write(b, byteOrder, firstIfdOffset) + log.PanicIf(err) + + return b.Bytes(), nil +} diff --git a/exif_test.go b/exif_test.go index c37cd8d..58076b9 100644 --- a/exif_test.go +++ b/exif_test.go @@ -319,6 +319,22 @@ func TestCollect(t *testing.T) { } } +func TestBuildAndParseExifHeader(t *testing.T) { + headerBytes, err := BuildExifHeader(TestDefaultByteOrder, 0x11223344) + log.PanicIf(err) + + e := NewExif() + + eh, err := e.ParseExifHeader(headerBytes) + log.PanicIf(err) + + if eh.ByteOrder != TestDefaultByteOrder { + t.Fatalf("Byte-order of EXIF header not correct.") + } else if eh.FirstIfdOffset != 0x11223344 { + t.Fatalf("First IFD offset not correct.") + } +} + func init() { goPath := os.Getenv("GOPATH") if goPath == "" {