Skip to content

Commit

Permalink
jfifcom: CLI to embed comment sections
Browse files Browse the repository at this point in the history
This is a quick tool to exercise inserting new JFIF segments and that it
works as expected.
  • Loading branch information
neilpa committed May 8, 2020
1 parent 9dbc9cf commit a9a5051
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 0 deletions.
1 change: 1 addition & 0 deletions cmd/jfifcom/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
jfifcom
63 changes: 63 additions & 0 deletions cmd/jfifcom/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// jfifcom embeds a new comment segment with the data from stdin
// before the start of stream (SOS) segment.
package main

import (
"flag"
"fmt"
"io"
"io/ioutil"
"os"

"neilpa.me/go-jfif"
)

func main() {
os.Exit(realMain(os.Args[1:], os.Stdin))
}

func realMain(args []string, stdin io.Reader) int {
flag.Usage = printUsage
flag.CommandLine.Parse(args)

if flag.NArg() == 0 {
return usageError("no files specified")
}

buf, err := ioutil.ReadAll(stdin)
if err != nil {
return fatal(err.Error())
}

for _, arg := range flag.Args() {
//fmt.Println("embeddding", arg, "buf", buf)

err = jfif.Append(arg, jfif.Patch{jfif.COM, buf})
if err != nil {
return fatal(err.Error()) // todo: continue writing the other files?
}
}
return 0
}

func fatal(format string, args ...interface{}) int {
format = os.Args[0] + ": " + format + "\n"
fmt.Fprintf(os.Stderr, format, args...)
return 1
}

func usageError(msg string) int {
fmt.Fprintln(os.Stderr, msg)
printUsage()
return 2
}

func printUsage() {
fmt.Fprintf(os.Stderr, `Usage: %s jpeg [jpeg...] < ...
jfifcomment embeds a new comment segment with the data from stdin
before the start of stream (SOS) segment.
`, os.Args[0])
flag.PrintDefaults()
fmt.Fprintln(os.Stderr)
}
71 changes: 71 additions & 0 deletions cmd/jfifcom/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package main

import (
"bytes"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
)

func TestMain(t *testing.T) {
root := filepath.Join("..", "..", "testdata")

tests := []struct {
in string
golden string
}{
{
"min.jpg",
"min.jfifcom.jpg",
},
}

for _, tt := range tests {
t.Run(tt.golden, func(t *testing.T) {
temp, err := ioutil.TempFile(os.TempDir(), "jfifcom-test-main-"+tt.in)
if err != nil {
t.Fatal(err)
}
path := temp.Name()
defer os.Remove(path)
defer temp.Close()

src, err := os.Open(filepath.Join(root, tt.in))
if err != nil {
t.Fatal(err)
}
defer src.Close()

_, err = io.Copy(temp, src)
if err != nil {
t.Fatal(err)
}
temp.Close()
src.Close()

exit := realMain([]string{path}, strings.NewReader("hello"))
if exit != 0 {
t.Fatalf("invalid exit %d", exit)
}

compareFiles(t, path, filepath.Join(root, tt.golden))
})
}
}

func compareFiles(t *testing.T, path, golden string) {
want, err := ioutil.ReadFile(golden)
if err != nil {
t.Fatal(err)
}
got, err := ioutil.ReadFile(path)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(got, want) {
t.Errorf("bytes don't match\ngot: % x\nwant: % x", got, want) // TODO Better diff
}
}
Binary file added cmd/jfifcom/min.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added testdata/min.jfifcom.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a9a5051

Please sign in to comment.