Skip to content

Commit 3a02e06

Browse files
committed
jfifcom: CLI to embed comment sections
This is a quick tool to exercise inserting new JFIF segments and that it works as expected.
1 parent 9dbc9cf commit 3a02e06

File tree

6 files changed

+134
-0
lines changed

6 files changed

+134
-0
lines changed

cmd/jfifcom/asdf.jpg

115 Bytes
Loading

cmd/jfifcom/jfifcom

2.38 MB
Binary file not shown.

cmd/jfifcom/main.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// jfifcom embeds a new comment segment with the data from stdin
2+
// before the start of stream (SOS) segment.
3+
package main
4+
5+
import (
6+
"flag"
7+
"fmt"
8+
"io"
9+
"io/ioutil"
10+
"os"
11+
12+
"neilpa.me/go-jfif"
13+
)
14+
15+
func main() {
16+
os.Exit(realMain(os.Args[1:], os.Stdin))
17+
}
18+
19+
func realMain(args []string, stdin io.Reader) int {
20+
flag.Usage = printUsage
21+
flag.CommandLine.Parse(args)
22+
23+
if flag.NArg() == 0 {
24+
return usageError("no files specified")
25+
}
26+
27+
buf, err := ioutil.ReadAll(stdin)
28+
if err != nil {
29+
return fatal(err.Error())
30+
}
31+
32+
for _, arg := range flag.Args() {
33+
//fmt.Println("embeddding", arg, "buf", buf)
34+
35+
err = jfif.Append(arg, jfif.Patch{jfif.COM, buf})
36+
if err != nil {
37+
return fatal(err.Error()) // todo: continue writing the other files?
38+
}
39+
}
40+
return 0
41+
}
42+
43+
func fatal(format string, args ...interface{}) int {
44+
format = os.Args[0] + ": " + format + "\n"
45+
fmt.Fprintf(os.Stderr, format, args...)
46+
return 1
47+
}
48+
49+
func usageError(msg string) int {
50+
fmt.Fprintln(os.Stderr, msg)
51+
printUsage()
52+
return 2
53+
}
54+
55+
func printUsage() {
56+
fmt.Fprintf(os.Stderr, `Usage: %s jpeg [jpeg...] < ...
57+
58+
jfifcomment embeds a new comment segment with the data from stdin
59+
before the start of stream (SOS) segment.
60+
`, os.Args[0])
61+
flag.PrintDefaults()
62+
fmt.Fprintln(os.Stderr)
63+
}

cmd/jfifcom/main_test.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"io"
6+
"io/ioutil"
7+
"os"
8+
"path/filepath"
9+
"strings"
10+
"testing"
11+
)
12+
13+
func TestMain(t *testing.T) {
14+
root := filepath.Join("..", "..", "testdata")
15+
16+
tests := []struct {
17+
in string
18+
golden string
19+
}{
20+
{
21+
"min.jpg",
22+
"min.jfifcom.jpg",
23+
},
24+
}
25+
26+
for _, tt := range tests {
27+
t.Run(tt.golden, func(t *testing.T) {
28+
temp, err := ioutil.TempFile(os.TempDir(), "jfifcom-test-main-"+tt.in)
29+
if err != nil {
30+
t.Fatal(err)
31+
}
32+
path := temp.Name()
33+
defer os.Remove(path)
34+
defer temp.Close()
35+
36+
src, err := os.Open(filepath.Join(root, tt.in))
37+
if err != nil {
38+
t.Fatal(err)
39+
}
40+
defer src.Close()
41+
42+
_, err = io.Copy(temp, src)
43+
if err != nil {
44+
t.Fatal(err)
45+
}
46+
temp.Close()
47+
src.Close()
48+
49+
exit := realMain([]string{path}, strings.NewReader("hello"))
50+
if exit != 0 {
51+
t.Fatalf("invalid exit %d", exit)
52+
}
53+
54+
compareFiles(t, path, filepath.Join(root, tt.golden))
55+
})
56+
}
57+
}
58+
59+
func compareFiles(t *testing.T, path, golden string) {
60+
want, err := ioutil.ReadFile(golden)
61+
if err != nil {
62+
t.Fatal(err)
63+
}
64+
got, err := ioutil.ReadFile(path)
65+
if err != nil {
66+
t.Fatal(err)
67+
}
68+
if !bytes.Equal(got, want) {
69+
t.Errorf("bytes don't match\ngot: % x\nwant: % x", got, want) // TODO Better diff
70+
}
71+
}

cmd/jfifcom/min.jpg

107 Bytes
Loading

testdata/min.jfifcom.jpg

116 Bytes
Loading

0 commit comments

Comments
 (0)