func ParseIFD(br tiff.BReader, offset uint64, tsp tiff.TagSpace, ftsp tiff.FieldTypeSpace) (out tiff.IFD, err error) { if br == nil { return nil, errors.New("tiff: no BReader supplied") } if ftsp == nil { ftsp = tiff.DefaultFieldTypeSpace } if tsp == nil { tsp = tiff.DefaultTagSpace } ifd := &imageFileDirectory{ fieldMap: make(map[uint16]tiff.Field, 1), } br.Seek(int64(offset), 0) if err = br.BRead(&ifd.numEntries); err != nil { err = fmt.Errorf("bigtiff: unable to read the number of entries for the IFD at offset %#08x: %v", offset, err) return } for i := uint64(0); i < ifd.numEntries; i++ { var f tiff.Field if f, err = ParseField(br, tsp, ftsp); err != nil { return } ifd.fields = append(ifd.fields, f) ifd.fieldMap[f.Tag().ID()] = f } if err = br.BRead(&ifd.nextOffset); err != nil { err = fmt.Errorf("bigtiff: unable to read the offset for the next ifd: %v", err) return } return ifd, nil }
func ParseBigTIFF(ordr [2]byte, vers uint16, br tiff.BReader, tsp tiff.TagSpace, ftsp tiff.FieldTypeSpace) (out tiff.TIFF, err error) { if tsp == nil { tsp = tiff.DefaultTagSpace } if ftsp == nil { ftsp = tiff.DefaultFieldTypeSpace } var restOfHdr [12]byte if _, err = io.ReadFull(br, restOfHdr[:]); err != nil { return nil, fmt.Errorf("bigtiff: unable to read the rest of the header: %v", err) } offsetSize := br.ByteOrder().Uint16(restOfHdr[:2]) if offsetSize > 8 { return nil, fmt.Errorf("bigtiff: unsupported offset size %d", offsetSize) } // Skip restOfHdr[2:4] since it is a constant that is normally always 0x0000 and has no use yet. firstOffset := br.ByteOrder().Uint64(restOfHdr[4:]) // Check the offset to the first IFD (ensure it is past the end of the header) if firstOffset < 16 { return nil, fmt.Errorf("bigtiff: invalid offset to first IFD, %d < 16", firstOffset) } t := &BigTIFF{ordr: ordr, vers: vers, offsetSize: offsetSize, firstOff: firstOffset, r: br} // Locate and decode IFDs for nextOffset := firstOffset; nextOffset != 0; { var ifd tiff.IFD if ifd, err = ParseIFD(br, nextOffset, tsp, ftsp); err != nil { return nil, err } t.ifds = append(t.ifds, ifd) nextOffset = ifd.NextOffset() } return t, nil }
func ParseField(br tiff.BReader, tsp tiff.TagSpace, ftsp tiff.FieldTypeSpace) (out tiff.Field, err error) { if ftsp == nil { ftsp = tiff.DefaultFieldTypeSpace } if tsp == nil { tsp = tiff.DefaultTagSpace } f := &field{ftsp: ftsp, tsp: tsp} if f.entry, err = ParseEntry(br); err != nil { return } fv := &fieldValue{order: br.ByteOrder()} valSize := int64(f.Count()) * int64(f.Type().Size()) valOffBytes := f.entry.ValueOffset() if valSize > 8 { fv.value = make([]byte, valSize) offset := int64(br.ByteOrder().Uint64(valOffBytes[:])) // Hope this does not go negative if err = br.BReadSection(&fv.value, offset, valSize); err != nil { return } } else { fv.value = valOffBytes[:] } f.value = fv return f, nil }
func ParseEntry(br tiff.BReader) (out Entry, err error) { e := new(entry) if err = br.BRead(&e.tagID); err != nil { return } if err = br.BRead(&e.typeID); err != nil { return } if err = br.BRead(&e.count); err != nil { return } if err = br.BRead(&e.valueOffset); err != nil { return } return e, nil }