Example #1
0
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
}
Example #2
0
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
}
Example #3
0
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
}
Example #4
0
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
}