cmd/handsum: add -base64 flag
diff --git a/cmd/handsum/main.go b/cmd/handsum/main.go index 2449bc7..84842d8 100644 --- a/cmd/handsum/main.go +++ b/cmd/handsum/main.go
@@ -15,6 +15,7 @@ import ( "bytes" + "encoding/base64" "errors" "flag" "image" @@ -39,10 +40,11 @@ encodeFlag = flag.Bool("encode", false, "") roundtripFlag = flag.Bool("roundtrip", false, "") - bFlag = flag.String("b", "", "") - bgFlag = flag.String("bg", "", "") - cFlag = flag.String("c", "rgb", "") - qFlag = flag.Int("q", 4, "") + bFlag = flag.String("b", "", "") + base64Flag = flag.String("base64", "", "") + bgFlag = flag.String("bg", "", "") + cFlag = flag.String("c", "rgb", "") + qFlag = flag.Int("q", 4, "") ) func getBFlag() string { @@ -84,6 +86,7 @@ -b or -bg Encoding background color: e.g. red, white, 9c27b0 or #ff8. The default is ff9e9e9e (for -c=1 or -c=3) or 00000000 (for -c=4). + -base64=std or -base64=url Decode or encode base64, not raw bytes. -c Encoding color: gray (1), rgb (3, default) or rgba (4). -q Encoding quality: 1, 2, 3 or 4 (default). ` @@ -99,6 +102,16 @@ flag.Usage = func() { os.Stderr.WriteString(usageStr) } flag.Parse() + b64e := (*base64.Encoding)(nil) + if !*roundtripFlag { + switch *base64Flag { + case "STD", "Std", "std": + b64e = base64.StdEncoding + case "URL", "Url", "url": + b64e = base64.URLEncoding + } + } + color := handsum.ColorRGB switch *cFlag { case "1", "GRAY", "Gray", "gray": @@ -106,13 +119,16 @@ case "4", "RGBA", "Rgba", "rgba": color = handsum.ColorRGBA } - quality := handsum.Quality(max(1, min(4, *qFlag))) - if (color <= handsum.ColorRGB) && (getBFlag() == "") { *bFlag = "ff9e9e9e" } - inFile := os.Stdin + quality := handsum.Quality(max(1, min(4, *qFlag))) + + // ---- + + r := (io.Reader)(os.Stdin) + switch flag.NArg() { case 0: // No-op. @@ -122,33 +138,48 @@ return err } defer f.Close() - inFile = f + r = f default: return errors.New("too many filenames; the maximum is one") } + if *decodeFlag && (b64e != nil) { + buf := [1024]byte{} + n, err := io.ReadFull(r, buf[:]) + if (err != nil) && (err != io.ErrUnexpectedEOF) { + return err + } + dec, err := b64e.AppendDecode(nil, buf[:n]) + if err != nil { + return err + } + r = bytes.NewReader(dec) + } + + // ---- + if *decodeFlag && !*encodeFlag && !*roundtripFlag { - return decode(inFile) + return decode(r) } if !*decodeFlag && *encodeFlag && !*roundtripFlag { - return encode(os.Stdout, inFile, color, quality) + return encode(os.Stdout, b64e, r, color, quality) } if !*decodeFlag && !*encodeFlag && *roundtripFlag { - return roundtrip(inFile, color, quality) + return roundtrip(r, color, quality) } return errors.New("must specify exactly one of -decode, -encode, -roundtrip or -help") } -func decode(inFile *os.File) error { - src, err := handsum.Decode(inFile) +func decode(r io.Reader) error { + src, err := handsum.Decode(r) if err != nil { return err } return png.Encode(os.Stdout, src) } -func encode(w io.Writer, inFile *os.File, color handsum.Color, quality handsum.Quality) error { - src, _, err := image.Decode(inFile) +func encode(w io.Writer, b64e *base64.Encoding, r io.Reader, color handsum.Color, quality handsum.Quality) error { + src, _, err := image.Decode(r) if err != nil { return err } @@ -157,15 +188,32 @@ src = applyBackgroundColor(src) } - return handsum.Encode(w, src, &handsum.EncodeOptions{ + w1, buf := w, (*bytes.Buffer)(nil) + if b64e != nil { + buf = &bytes.Buffer{} + w1 = buf + } + + if err := handsum.Encode(w1, src, &handsum.EncodeOptions{ Color: color, Quality: quality, - }) + }); err != nil { + return err + } + + if b64e != nil { + enc := b64e.AppendEncode(nil, buf.Bytes()) + if _, err := w.Write(enc); err != nil { + return err + } + } + + return nil } -func roundtrip(inFile *os.File, color handsum.Color, quality handsum.Quality) error { +func roundtrip(r io.Reader, color handsum.Color, quality handsum.Quality) error { buf := &bytes.Buffer{} - err := encode(buf, inFile, color, quality) + err := encode(buf, nil, r, color, quality) if err != nil { return err }