func (Bilevel) CanHandle(ifd tiff.IFD) bool { requiredTags := []uint16{256, 257, 259, 262, 273} for _, tagID := range requiredTags { if !ifd.HasField(tagID) { return false } } return true }
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 (FullColorRGB) CanHandle(ifd tiff.IFD) bool { return new(Grayscale).CanHandle(ifd) && ifd.HasField(277) }
func (PaletteColor) CanHandle(ifd tiff.IFD) bool { return new(Grayscale).CanHandle(ifd) && ifd.HasField(320) }
func UnmarshalSubIFDs(ifd tiff.IFD, br tiff.BReader, tsp tiff.TagSpace, out interface{}) error { if br == nil { return fmt.Errorf("bigtiff: UnmarshalSubIFDs: no BReader available") } if len(ifd.Fields()) == 0 { return fmt.Errorf("bigtiff: UnmarshalSubIFDs: ifd has no fields") } v := reflect.ValueOf(out).Elem() structType := v.Type() for i := 0; i < v.NumField(); i++ { stField := structType.Field(i) sTag := tiff.ParseTiffStructTag(stField.Tag.Get("tiff")) if sTag == nil || sTag.Type != "subifd" { continue } vf := v.Field(i) vft := vf.Type() vftk := vft.Kind() if vftk != reflect.Ptr && vftk != reflect.Struct { log.Printf("bigtiff: UnmarshalSubIFDs: using a tiff SubIFD struct tag is only supported for structs (not a %v)\n", vftk) continue } siTag := tiff.ParseTiffSubIFDStructTag(sTag.Data) if siTag == nil { log.Printf("bigtiff: UnmarshalSubIFDs: skipping struct field %q due to malformed tiff subifd struct tag (%q).\n", stField.Name, sTag.Data) continue } if siTag.Tag == nil { log.Printf("bigtiff: UnmarshalSubIFDs: skipping struct field %q due to missing \"tag\" key in tiff subifd struct tag.\n", stField.Name) continue } if !ifd.HasField(*siTag.Tag) { // Default values do not work here. We have to simply skip it. continue } ifdField := ifd.GetField(*siTag.Tag) ifdFT := ifdField.Type() fvBytes := ifdField.Value().Bytes() fvBo := ifdField.Value().Order() if ifdField.Count() == 0 { continue } var offsets []uint64 switch ifdFT.ReflectType().Kind() { case reflect.Uint32: offsets = make([]uint64, ifdField.Count()) for i := range offsets { offsets[i] = uint64(fvBo.Uint32(fvBytes)) fvBytes = fvBytes[4:] } case reflect.Uint64: offsets = make([]uint64, ifdField.Count()) for i := range offsets { offsets[i] = fvBo.Uint64(fvBytes) fvBytes = fvBytes[8:] } default: continue } off := offsets[0] if siTag.Index != nil { if *siTag.Index >= len(offsets) || *siTag.Index < 0 { // log a warning continue } off = offsets[*siTag.Index] } if tsp == nil { if siTag.TagSpace != nil { newSpace := tiff.GetTagSpace(*siTag.TagSpace) if newSpace != nil { tsp = newSpace } } if tsp == nil { tsp = tiff.DefaultTagSpace } } subIFD, err := ParseIFD(br, uint64(off), tsp, nil) if err != nil { return err } switch vftk { case reflect.Ptr: // We do not support recursive unmarshaling when // the field points back to the enclosing struct. if vf.Elem() != v && vft.Elem().Kind() == reflect.Struct { newStruct := reflect.New(vft.Elem()) if err := tiff.UnmarshalIFD(subIFD, newStruct.Interface()); err != nil { return err } vf.Set(newStruct) } case reflect.Struct: embStructPtr := v.Field(i).Addr().Interface() if err := tiff.UnmarshalIFD(subIFD, embStructPtr); err != nil { return err } } } return nil }
func (Grayscale) CanHandle(ifd tiff.IFD) bool { return new(Bilevel).CanHandle(ifd) && ifd.HasField(258) }