From 85dafe412072de2e953f0f9cf1109b74ca51a003 Mon Sep 17 00:00:00 2001 From: Justin Hawkins Date: Wed, 15 May 2024 18:45:29 +0930 Subject: [PATCH] Fix up some bugs and update to modern go --- go.mod | 7 +++ go.sum | 5 ++ main.go | 165 ++++++++++++++++++++++++++++---------------------------- 3 files changed, 95 insertions(+), 82 deletions(-) create mode 100644 go.mod create mode 100644 go.sum diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..0de7c15 --- /dev/null +++ b/go.mod @@ -0,0 +1,7 @@ +module github.com/tardisx/slicerdicer + +go 1.22.1 + +require github.com/disintegration/imaging v1.6.2 + +require golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..6e27fcd --- /dev/null +++ b/go.sum @@ -0,0 +1,5 @@ +github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= +github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= +golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U= +golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/main.go b/main.go index 064ef09..5404ac3 100644 --- a/main.go +++ b/main.go @@ -1,109 +1,110 @@ -package main; +package main -import "image" -import "image/png" -import "github.com/disintegration/imaging" -import "runtime" -import "flag" -import "fmt" -import "os" +import ( + "flag" + "fmt" + "image" + "image/png" + "os" + + "github.com/disintegration/imaging" +) const currentVersion = "0.01" func main() { - filenamePtr := flag.String("filename", "", "filename to open") - tileSizePtr := flag.Int ("tile-size", 256, "tile size, in pixels") - concurrencyPtr := flag.Int ("concurrency", 5, "how many tiles to generate concurrently (threads)") + filenamePtr := flag.String("filename", "", "filename to open") + tileSizePtr := flag.Int("tile-size", 256, "tile size, in pixels") + concurrencyPtr := flag.Int("concurrency", 5, "how many tiles to generate concurrently (threads)") + baseName := flag.String("basename", "tile", "base of the output files") - flag.Parse() + flag.Parse() - if (*filenamePtr == "") { - fmt.Println("Error: You must specify a filename with --filename"); - return; - } + if *filenamePtr == "" { + fmt.Println("Error: You must specify a filename with --filename") + return + } - fmt.Println("opening file:", *filenamePtr) - src, err := imaging.Open(*filenamePtr) - if err != nil { - fmt.Println("Error: Could not open file:", err) - return; - } + fmt.Println("opening file:", *filenamePtr) + src, err := imaging.Open(*filenamePtr) + if err != nil { + fmt.Println("Error: Could not open file:", err) + return + } - size := src.Bounds().Max + size := src.Bounds().Max - tile_size_x := *tileSizePtr - tile_size_y := *tileSizePtr + tile_size_x := *tileSizePtr + tile_size_y := *tileSizePtr - // work out maximum zoom - var max_zoom int - zoom_test_size_x := size.X - zoom_test_size_y := size.Y - for max_zoom = 0 ; ; max_zoom++ { - if zoom_test_size_x < tile_size_x && zoom_test_size_y < tile_size_y { - break - } - zoom_test_size_x = zoom_test_size_x >> 1 - zoom_test_size_y = zoom_test_size_y >> 1 - } + // work out maximum zoom + var max_zoom int + zoom_test_size_x := size.X + zoom_test_size_y := size.Y + for max_zoom = 0; ; max_zoom++ { + if zoom_test_size_x <= tile_size_x && zoom_test_size_y <= tile_size_y { + break + } + zoom_test_size_x = zoom_test_size_x >> 1 + zoom_test_size_y = zoom_test_size_y >> 1 + } - z := max_zoom - fmt.Println("maximum zoom level is", max_zoom) + z := max_zoom + fmt.Println("maximum zoom level is", max_zoom) - concurrency := *concurrencyPtr - sem := make(chan bool, concurrency) + concurrency := *concurrencyPtr + sem := make(chan bool, concurrency) - fmt.Println("starting tiling with concurrency of", concurrency) + fmt.Println("starting tiling with concurrency of", concurrency) - // outer loop for zoom - for { - if (z == max_zoom) { - // do nothing - } else { - // halve image size - src = imaging.Resize(src, size.X/2, 0, imaging.NearestNeighbor) - runtime.GC() - // recalculate size - size = src.Bounds().Max - } + // outer loop for zoom + for { + if z == max_zoom { + // do nothing + } else { + // halve image size + src = imaging.Resize(src, size.X/2, 0, imaging.NearestNeighbor) + // recalculate size + size = src.Bounds().Max + } - fmt.Print(fmt.Sprintf("zoom level: %d (%d x %d)\n", z, size.X, size.Y)) + fmt.Print(fmt.Sprintf("zoom level: %d (%d x %d)\n", z, size.X, size.Y)) - for y := 0 ; y <= (size.Y / tile_size_y) ; y++ { - for x := 0 ; x <= (size.X / tile_size_x) ; x++ { - sem <- true - go tile(src, z, x, y, tile_size_x, tile_size_y, sem) - } + for y := 0; y < (size.Y / tile_size_y); y++ { + for x := 0; x < (size.X / tile_size_x); x++ { + sem <- true + go tile(*baseName, src, z, x, y, tile_size_x, tile_size_y, sem) + } - } + } - z-- - if (z < 0) { - break - } - } + z-- + if z < 0 { + break + } + } - // drain at the end of each zoom level - // since we are about to modify the source image - for i := 0; i < cap(sem); i++ { - sem <- true - } + // drain at the end of each zoom level + // since we are about to modify the source image in memory + for i := 0; i < cap(sem); i++ { + sem <- true + } - fmt.Println("done") + fmt.Println("done") } -func tile (src image.Image, z, x, y int, tile_size_x, tile_size_y int, sem chan bool) { - defer func() { <-sem }() - output_filename := fmt.Sprintf("tile-%d-%d-%d.png", z, x, y) - cropped := imaging.Crop(src, image.Rect(tile_size_x*x, tile_size_y*y, tile_size_x*x+tile_size_x, tile_size_y*y+tile_size_y)); +func tile(basename string, src image.Image, z, x, y int, tile_size_x, tile_size_y int, sem chan bool) { + defer func() { <-sem }() + output_filename := fmt.Sprintf("%s-%d-%d-%d.png", basename, z, x, y) + cropped := imaging.Crop(src, image.Rect(tile_size_x*x, tile_size_y*y, tile_size_x*x+tile_size_x, tile_size_y*y+tile_size_y)) - writer, _ := os.Create(output_filename) - err := png.Encode(writer, cropped) - if err != nil { - fmt.Println(err) - } - writer.Close() + writer, _ := os.Create(output_filename) + err := png.Encode(writer, cropped) + if err != nil { + fmt.Println(err) + } + writer.Close() - runtime.GC() - return; + return }