// Parse decodes all Nikon makernote data found in x and adds it to x. func (_ *nikonV3) Parse(x *exif.Exif) error { m, err := x.Get(exif.MakerNote) if err != nil { return nil } else if bytes.Compare(m.Val[:6], []byte("Nikon\000")) != 0 { return nil } // Nikon v3 maker note is a self-contained IFD (offsets are relative // to the start of the maker note) mkNotes, err := tiff.Decode(bytes.NewReader(m.Val[10:])) if err != nil { return err } x.LoadTags(mkNotes.Dirs[0], makerNoteNikon3Fields, false) return nil }
// Decode parses EXIF-encoded data from r and returns a queryable Exif object. func Decode(r io.Reader) (*Exif, error) { // Locate the EXIF (0xE1 = APP1) application section. sec, err := newAppSec(0xE1, r) if err != nil { return nil, err } er, err := sec.exifReader() if err != nil { return nil, err } tif, err := tiff.Decode(er) if err != nil { return nil, errors.New("exif: decode failed: " + err.Error()) } // build an exif structure from the tiff x := &Exif{ main: map[FieldName]*tiff.Tag{}, tif: tif, } ifd0 := tif.Dirs[0] for _, tag := range ifd0.Tags { name := exifFields[tag.Id] if name == "" { name = FieldName(fmt.Sprintf("%v%x", unknownPrefix, tag.Id)) } x.main[name] = tag } // recurse into exif, gps, and interop sub-IFDs if err = x.loadSubDir(er, ExifIFDPointer, exifFields); err != nil { return x, err } if err = x.loadSubDir(er, GPSInfoIFDPointer, gpsFields); err != nil { return x, err } if err = x.loadSubDir(er, InteroperabilityIFDPointer, interopFields); err != nil { return x, err } return x, nil }
// Decode parses EXIF-encoded data from r and returns a queryable Exif object. func Decode(r io.Reader) (*Exif, error) { sec, err := newAppSec(0xE1, r) if err != nil { return nil, err } er, err := sec.exifReader() if err != nil { return nil, err } tif, err := tiff.Decode(er) if err != nil { return nil, errors.New("exif: decode failed: " + err.Error()) } // build an exif structure from the tiff x := &Exif{ main: map[FieldName]*tiff.Tag{}, tif: tif, } ifd0 := tif.Dirs[0] for _, tag := range ifd0.Tags { name := exifFields[tag.Id] x.main[name] = tag } // recurse into exif, gps, and interop sub-IFDs if err = x.loadSubDir(er, exifIFDPointer, exifFields); err != nil { return x, err } if err = x.loadSubDir(er, gpsInfoIFDPointer, gpsFields); err != nil { return x, err } if err = x.loadSubDir(er, interoperabilityIFDPointer, interopFields); err != nil { return x, err } return x, nil }
// Decode parses EXIF-encoded data from r and returns a queryable Exif // object. After the exif data section is called and the tiff structure // decoded, each registered parser is called (in order of registration). If // one parser returns an error, decoding terminates and the remaining // parsers are not called. func Decode(r io.Reader) (*Exif, error) { // EXIF data in JPEG is stored in the APP1 marker. EXIF data uses the TIFF // format to store data. // If we're parsing a TIFF image, we don't need to strip away any data. // If we're parsing a JPEG image, we need to strip away the JPEG APP1 // marker and also the EXIF header. header := make([]byte, 4) n, err := r.Read(header) if err != nil { return nil, err } if n < len(header) { return nil, errors.New("exif: short read on header") } var isTiff bool switch string(header) { case "II*\x00": // TIFF - Little endian (Intel) isTiff = true case "MM\x00*": // TIFF - Big endian (Motorola) isTiff = true default: // Not TIFF, assume JPEG } // Put the header bytes back into the reader. r = io.MultiReader(bytes.NewReader(header), r) var ( er *bytes.Reader tif *tiff.Tiff ) if isTiff { // Functions below need the IFDs from the TIFF data to be stored in a // *bytes.Reader. We use TeeReader to get a copy of the bytes as a // side-effect of tiff.Decode() doing its work. b := &bytes.Buffer{} tr := io.TeeReader(r, b) tif, err = tiff.Decode(tr) er = bytes.NewReader(b.Bytes()) } else { // Locate the JPEG APP1 header. var sec *appSec sec, err = newAppSec(jpeg_APP1, r) if err != nil { return nil, err } // Strip away EXIF header. er, err = sec.exifReader() if err != nil { return nil, err } tif, err = tiff.Decode(er) } if err != nil { return nil, fmt.Errorf("exif: decode failed (%v) ", err) } er.Seek(0, 0) raw, err := ioutil.ReadAll(er) if err != nil { return nil, fmt.Errorf("exif: decode failed (%v) ", err) } // build an exif structure from the tiff x := &Exif{ main: map[FieldName]*tiff.Tag{}, Tiff: tif, Raw: raw, } for i, p := range parsers { if err := p.Parse(x); err != nil { return x, fmt.Errorf("exif: parser %v failed (%v)", i, err) } } return x, nil }