//go:build !test package photos /* #cgo CFLAGS: -I${SRCDIR}/../../bridge #cgo LDFLAGS: -L${SRCDIR}/../../bridge -lphotokit_bridge -framework Photos -framework Foundation -framework AppKit -framework UniformTypeIdentifiers -framework CoreLocation -framework MapKit #include "photokit_bridge.h" #include */ import "C" import "unsafe" type CgoBridge struct{} var DefaultBridge Bridge = &CgoBridge{} func (*CgoBridge) RequestAccess() error { rc := C.photos_request_access() if rc != 0 { return errAccessDenied } return nil } func (*CgoBridge) ListAlbums() ([]Album, error) { cs := C.photos_list_albums_json() if cs == nil { return nil, errBridgeNil } defer C.photos_free_string(cs) return ParseAlbumsJSON(C.GoString(cs)) } func (*CgoBridge) ListAssets(albumID string) ([]Asset, int, error) { cid := C.CString(albumID) defer C.free(unsafe.Pointer(cid)) cs := C.photos_list_assets_json(cid) if cs == nil { return nil, 0, errBridgeNil } defer C.photos_free_string(cs) return ParseAssetsJSON(C.GoString(cs)) } func (*CgoBridge) ReverseGeocode(latitude, longitude float64) (Placemark, error) { cs := C.photos_reverse_geocode_json(C.double(latitude), C.double(longitude)) if cs == nil { return Placemark{}, errBridgeNil } defer C.photos_free_string(cs) return ParsePlacemarkJSON(C.GoString(cs)) } func (*CgoBridge) ListTree() ([]CollectionNode, error) { cs := C.photos_list_tree_json() if cs == nil { return nil, errBridgeNil } defer C.photos_free_string(cs) return ParseTreeJSON(C.GoString(cs)) } func (*CgoBridge) Cancel() { C.photos_request_cancel() } func (*CgoBridge) IsCancelled() bool { return C.photos_request_is_cancelled() != 0 } func (*CgoBridge) ExportPreview(assetID, outputDir string, targetSize, quality, index int) (ExportResult, error) { return exportPreviewWithSlot(assetID, outputDir, targetSize, quality, index, -1) } func (*CgoBridge) ExportOriginal(assetID, outputDir string, index int) (ExportResult, error) { return exportOriginalWithSlot(assetID, outputDir, index, -1) } func (*CgoBridge) ExportPreviewWithSlot(assetID, outputDir string, targetSize, quality, index, slotIndex int) (ExportResult, error) { return exportPreviewWithSlot(assetID, outputDir, targetSize, quality, index, slotIndex) } func (*CgoBridge) ExportOriginalWithSlot(assetID, outputDir string, index, slotIndex int) (ExportResult, error) { return exportOriginalWithSlot(assetID, outputDir, index, slotIndex) } func exportPreviewWithSlot(assetID, outputDir string, targetSize, quality, index, slotIndex int) (ExportResult, error) { cid := C.CString(assetID) defer C.free(unsafe.Pointer(cid)) cdir := C.CString(outputDir) defer C.free(unsafe.Pointer(cdir)) cs := C.photos_export_preview_json(cid, cdir, C.int(targetSize), C.int(quality), C.int(index), C.int(slotIndex)) if cs == nil { return ExportResult{}, errBridgeNil } defer C.photos_free_string(cs) return ParseExportResultJSON(C.GoString(cs)) } func exportOriginalWithSlot(assetID, outputDir string, index, slotIndex int) (ExportResult, error) { cid := C.CString(assetID) defer C.free(unsafe.Pointer(cid)) cdir := C.CString(outputDir) defer C.free(unsafe.Pointer(cdir)) cs := C.photos_export_original_json(cid, cdir, C.int(index), C.int(slotIndex)) if cs == nil { return ExportResult{}, errBridgeNil } defer C.photos_free_string(cs) return ParseExportResultJSON(C.GoString(cs)) } func GetProgressSlots() []ExportProgressSlot { count := int(C.photos_get_progress_slot_count()) slots := C.photos_get_progress_slots() if slots == nil || count == 0 { return nil } result := make([]ExportProgressSlot, count) for i := 0; i < count; i++ { ptr := (*C.export_progress_t)(unsafe.Pointer(uintptr(unsafe.Pointer(slots)) + uintptr(i)*unsafe.Sizeof(C.export_progress_t{}))) result[i] = ExportProgressSlot{ Active: ptr.active != 0, Progress: float64(ptr.progress), BytesDone: int64(ptr.bytes_done), BytesTotal: int64(ptr.bytes_total), } } return result } func ResetProgressSlots() { C.photos_reset_progress_slots() } func GetProgressSlotCount() int { return int(C.photos_get_progress_slot_count()) } type ExportProgressSlot struct { Active bool Progress float64 BytesDone int64 BytesTotal int64 }