# dcf ## Description `dcf` is a WTFPL-licensed Go library by [@sneak](https://sneak.berlin) that reads DCF memory cards from digital cameras. DCF is the "Design rule for Camera File system". It is also JEITA specification number CP-3461. JEITA is the Japan Electronics and Information Technology Industries Association. Wikipedia describes it at [Design rule for Camera File system](https://en.wikipedia.org/wiki/Design_rule_for_Camera_File_system). The DCF specification is why your digital camera puts images and videos in `DCIM` and `PRIVATE/M4ROOT` directories on the memory card. `dcf` is incomplete and under development. It does not work yet. ## Getting Started Add the library to your Go module: ```sh go get sneak.berlin/go/dcf ``` Then list the DCF stores on the mounted filesystems: ```go package main import ( "fmt" "log" "sneak.berlin/go/dcf/pkg/dcf" ) func main() { stores, err := dcf.GetDCFStores(0) if err != nil { log.Fatal(err) } for _, store := range *stores { fmt.Println(store.String()) } } ``` To work on the library itself, you need docker and git: ```sh git clone git@git.eeqj.de:sneak/dcf.git cd dcf script/setup make check ``` ## Entrypoints This repo adheres to the [Scripts to Rule Them All](https://github.com/github/scripts-to-rule-them-all) standard. Each entrypoint is a POSIX sh script in `script/`. Use these instead of running the underlying tools directly. - `script/bootstrap` (`make bootstrap`) installs the tools the host needs. It does not install docker or the linter. It installs: - `make` and git - Go into `~/.local/go`, at the version in the `Dockerfile`, unless the `go` on the `PATH` is already that version - the Go modules - node and yarn - `prettier` - `script/setup` (`make setup`) runs `script/bootstrap` and then installs the git pre-commit hook. - `script/test` (`make test`) runs the tests by building the `test` stage of the `Dockerfile`. - `script/lint` (`make lint`) checks the Go code by building the `lint` stage of the `Dockerfile`. - `script/fmt` (`make fmt`) rewrites the Go code with `go fmt` and the Markdown files with `prettier`. - `script/fmt-check` (`make fmt-check`) checks the same formatting and changes nothing. - `script/check` (`make check`) runs the tests, then the linter, then the formatting check. - `script/build` (`make build`) compiles every package. It needs the Go that `script/bootstrap` installs. - `script/docker` (`make docker`) builds the development image, tagged `dcf`. - `script/cibuild` runs the whole CI build. The Gitea workflow runs it on every push. - `script/precommit` is what the git pre-commit hook runs. It runs `script/check`. - `script/install-precommit` (`make hooks`) installs the git pre-commit hook. - `script/projectname` prints the project name for the other scripts. The development image cannot be built unless the `lint` and `test` stages pass. Run `docker run --rm -it dcf` for a shell inside it, with Go and `make`. ## Rationale I wanted to copy images off my memory cards for processing. I also like overengineering and reusable code. ## Design All the code is in the `pkg/dcf` package. The repo has no commands. - `dcf.go` holds the public API. `GetDCFStores` finds the DCF stores and lists the files on them. - `helpers.go` finds the mount points that hold a DCF store. The main types are: - `Store` is one DCF store on one mounted filesystem. - `Object` is one file in a store. - `Image` and `Video` embed `Object`. The file extension decides which one a file becomes. A mounted filesystem is a DCF store when its root holds a `DCIM` or `PRIVATE/M4ROOT` directory. `dcf` never mounts a filesystem. ## TODO - Handle DCF file groups, where multiple objects share the same index number. `dcf` does not handle these yet. If you need this, send me a link to a zip or tar of a memory card that uses them, and I'll see what I can do. - Parse the DCF directory and file names, rather than listing every media file on the filesystem. - Read stores through `fs.FS`, with a `context.Context` to cancel a walk. - Return a plain slice from `GetDCFStores`, not a pointer to one. - Test the walk of a store. It only runs against real mounted media today. - Copy files off a card, and verify each copy against its SHA256 hash. ## License WTFPL. See [LICENSE](LICENSE). ## Author [@sneak](https://sneak.berlin) <[sneak@sneak.berlin](mailto:sneak@sneak.berlin)>