]> Cypherpunks repositories - gostls13.git/commitdiff
image/internal/imageutil: generate subsample-ratio-specific code.
authorNigel Tao <nigeltao@golang.org>
Tue, 24 Mar 2015 00:43:36 +0000 (11:43 +1100)
committerNigel Tao <nigeltao@golang.org>
Tue, 24 Mar 2015 01:01:20 +0000 (01:01 +0000)
This is in preparation for inlining the color.YCbCrToRGB calls in a
follow-up change.

Change-Id: I30750ace11a8ef6016b3c1e0b4bfdbcc8151f9a5
Reviewed-on: https://go-review.googlesource.com/7951
Reviewed-by: Rob Pike <r@golang.org>
src/image/internal/imageutil/gen.go [new file with mode: 0644]
src/image/internal/imageutil/imageutil.go
src/image/internal/imageutil/impl.go [new file with mode: 0644]

diff --git a/src/image/internal/imageutil/gen.go b/src/image/internal/imageutil/gen.go
new file mode 100644 (file)
index 0000000..59125da
--- /dev/null
@@ -0,0 +1,132 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+package main
+
+import (
+       "bytes"
+       "flag"
+       "fmt"
+       "go/format"
+       "io/ioutil"
+       "log"
+       "os"
+)
+
+var debug = flag.Bool("debug", false, "")
+
+func main() {
+       flag.Parse()
+
+       w := new(bytes.Buffer)
+       w.WriteString(pre)
+       for _, sratio := range subsampleRatios {
+               fmt.Fprintf(w, sratioCase, sratio, sratioLines[sratio])
+       }
+       w.WriteString(post)
+
+       if *debug {
+               os.Stdout.Write(w.Bytes())
+               return
+       }
+       out, err := format.Source(w.Bytes())
+       if err != nil {
+               log.Fatal(err)
+       }
+       if err := ioutil.WriteFile("impl.go", out, 0660); err != nil {
+               log.Fatal(err)
+       }
+}
+
+const pre = `// generated by "go run gen.go". DO NOT EDIT.
+
+package imageutil
+
+import (
+       "image"
+       "image/color"
+)
+
+// DrawYCbCr draws the YCbCr source image on the RGBA destination image with
+// r.Min in dst aligned with sp in src. It reports whether the draw was
+// successful. If it returns false, no dst pixels were changed.
+//
+// This function assumes that r is entirely within dst's bounds and the
+// translation of r from dst co-ordinate space to src co-ordinate space is
+// entirely within src's bounds.
+func DrawYCbCr(dst *image.RGBA, r image.Rectangle, src *image.YCbCr, sp image.Point) (ok bool) {
+       // This function exists in the image/internal/imageutil package because it
+       // is needed by both the image/draw and image/jpeg packages, but it doesn't
+       // seem right for one of those two to depend on the other.
+       //
+       // Another option is to have this code be exported in the image package,
+       // but we'd need to make sure we're totally happy with the API (for the
+       // rest of Go 1 compatibility), and decide if we want to have a more
+       // general purpose DrawToRGBA method for other image types. One possibility
+       // is:
+       //
+       // func (src *YCbCr) CopyToRGBA(dst *RGBA, dr, sr Rectangle) (effectiveDr, effectiveSr Rectangle)
+       //
+       // in the spirit of the built-in copy function for 1-dimensional slices,
+       // that also allowed a CopyFromRGBA method if needed.
+
+       x0 := (r.Min.X - dst.Rect.Min.X) * 4
+       x1 := (r.Max.X - dst.Rect.Min.X) * 4
+       y0 := r.Min.Y - dst.Rect.Min.Y
+       y1 := r.Max.Y - dst.Rect.Min.Y
+       switch src.SubsampleRatio {
+`
+
+const post = `
+       default:
+               return false
+       }
+       return true
+}
+`
+
+const sratioCase = `
+       case image.YCbCrSubsampleRatio%s:
+               for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
+                       dpix := dst.Pix[y*dst.Stride:]
+                       yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
+                       %s
+                               rr, gg, bb := color.YCbCrToRGB(src.Y[yi], src.Cb[ci], src.Cr[ci])
+                               dpix[x+0] = rr
+                               dpix[x+1] = gg
+                               dpix[x+2] = bb
+                               dpix[x+3] = 255
+                       }
+               }
+`
+
+var subsampleRatios = []string{
+       "444",
+       "422",
+       "420",
+       "440",
+}
+
+var sratioLines = map[string]string{
+       "444": `
+               ci := (sy-src.Rect.Min.Y)*src.CStride + (sp.X - src.Rect.Min.X)
+               for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 {
+       `,
+       "422": `
+               ciBase := (sy-src.Rect.Min.Y)*src.CStride - src.Rect.Min.X/2
+               for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 {
+                       ci := ciBase + sx/2
+       `,
+       "420": `
+               ciBase := (sy/2-src.Rect.Min.Y/2)*src.CStride - src.Rect.Min.X/2
+               for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 {
+                       ci := ciBase + sx/2
+       `,
+       "440": `
+               ci := (sy/2-src.Rect.Min.Y/2)*src.CStride + (sp.X - src.Rect.Min.X)
+               for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 {
+       `,
+}
index 4ef53f10d901fa0c88e30d0962995270662fe6bb..10cef0c665057c21520f62e8a1acc9623048dbef 100644 (file)
@@ -2,95 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:generate go run gen.go
+
 // Package imageutil contains code shared by image-related packages.
 package imageutil
-
-import (
-       "image"
-       "image/color"
-)
-
-// DrawYCbCr draws the YCbCr source image on the RGBA destination image with
-// r.Min in dst aligned with sp in src. It returns whether the draw was
-// successful. If it returns false, no dst pixels were changed.
-func DrawYCbCr(dst *image.RGBA, r image.Rectangle, src *image.YCbCr, sp image.Point) (ok bool) {
-       // This function exists in the image/internal/imageutil package because it
-       // is needed by both the image/draw and image/jpeg packages, but it doesn't
-       // seem right for one of those two to depend on the other.
-       //
-       // Another option is to have this code be exported in the image package,
-       // but we'd need to make sure we're totally happy with the API (for the
-       // rest of Go 1 compatibility), and decide if we want to have a more
-       // general purpose DrawToRGBA method for other image types. One possibility
-       // is:
-       //
-       // func (src *YCbCr) CopyToRGBA(dst *RGBA, dr, sr Rectangle) (effectiveDr, effectiveSr Rectangle)
-       //
-       // in the spirit of the built-in copy function for 1-dimensional slices,
-       // that also allowed a CopyFromRGBA method if needed.
-
-       x0 := (r.Min.X - dst.Rect.Min.X) * 4
-       x1 := (r.Max.X - dst.Rect.Min.X) * 4
-       y0 := r.Min.Y - dst.Rect.Min.Y
-       y1 := r.Max.Y - dst.Rect.Min.Y
-       switch src.SubsampleRatio {
-       case image.YCbCrSubsampleRatio444:
-               for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
-                       dpix := dst.Pix[y*dst.Stride:]
-                       yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
-                       ci := (sy-src.Rect.Min.Y)*src.CStride + (sp.X - src.Rect.Min.X)
-                       for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 {
-                               rr, gg, bb := color.YCbCrToRGB(src.Y[yi], src.Cb[ci], src.Cr[ci])
-                               dpix[x+0] = rr
-                               dpix[x+1] = gg
-                               dpix[x+2] = bb
-                               dpix[x+3] = 255
-                       }
-               }
-       case image.YCbCrSubsampleRatio422:
-               for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
-                       dpix := dst.Pix[y*dst.Stride:]
-                       yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
-                       ciBase := (sy-src.Rect.Min.Y)*src.CStride - src.Rect.Min.X/2
-                       for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 {
-                               ci := ciBase + sx/2
-                               rr, gg, bb := color.YCbCrToRGB(src.Y[yi], src.Cb[ci], src.Cr[ci])
-                               dpix[x+0] = rr
-                               dpix[x+1] = gg
-                               dpix[x+2] = bb
-                               dpix[x+3] = 255
-                       }
-               }
-       case image.YCbCrSubsampleRatio420:
-               for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
-                       dpix := dst.Pix[y*dst.Stride:]
-                       yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
-                       ciBase := (sy/2-src.Rect.Min.Y/2)*src.CStride - src.Rect.Min.X/2
-                       for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 {
-                               ci := ciBase + sx/2
-                               rr, gg, bb := color.YCbCrToRGB(src.Y[yi], src.Cb[ci], src.Cr[ci])
-                               dpix[x+0] = rr
-                               dpix[x+1] = gg
-                               dpix[x+2] = bb
-                               dpix[x+3] = 255
-                       }
-               }
-
-       case image.YCbCrSubsampleRatio440:
-               for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
-                       dpix := dst.Pix[y*dst.Stride:]
-                       yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
-                       ci := (sy/2-src.Rect.Min.Y/2)*src.CStride + (sp.X - src.Rect.Min.X)
-                       for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 {
-                               rr, gg, bb := color.YCbCrToRGB(src.Y[yi], src.Cb[ci], src.Cr[ci])
-                               dpix[x+0] = rr
-                               dpix[x+1] = gg
-                               dpix[x+2] = bb
-                               dpix[x+3] = 255
-                       }
-               }
-       default:
-               return false
-       }
-       return true
-}
diff --git a/src/image/internal/imageutil/impl.go b/src/image/internal/imageutil/impl.go
new file mode 100644 (file)
index 0000000..5a156e4
--- /dev/null
@@ -0,0 +1,109 @@
+// generated by "go run gen.go". DO NOT EDIT.
+
+package imageutil
+
+import (
+       "image"
+       "image/color"
+)
+
+// DrawYCbCr draws the YCbCr source image on the RGBA destination image with
+// r.Min in dst aligned with sp in src. It reports whether the draw was
+// successful. If it returns false, no dst pixels were changed.
+//
+// This function assumes that r is entirely within dst's bounds and the
+// translation of r from dst co-ordinate space to src co-ordinate space is
+// entirely within src's bounds.
+func DrawYCbCr(dst *image.RGBA, r image.Rectangle, src *image.YCbCr, sp image.Point) (ok bool) {
+       // This function exists in the image/internal/imageutil package because it
+       // is needed by both the image/draw and image/jpeg packages, but it doesn't
+       // seem right for one of those two to depend on the other.
+       //
+       // Another option is to have this code be exported in the image package,
+       // but we'd need to make sure we're totally happy with the API (for the
+       // rest of Go 1 compatibility), and decide if we want to have a more
+       // general purpose DrawToRGBA method for other image types. One possibility
+       // is:
+       //
+       // func (src *YCbCr) CopyToRGBA(dst *RGBA, dr, sr Rectangle) (effectiveDr, effectiveSr Rectangle)
+       //
+       // in the spirit of the built-in copy function for 1-dimensional slices,
+       // that also allowed a CopyFromRGBA method if needed.
+
+       x0 := (r.Min.X - dst.Rect.Min.X) * 4
+       x1 := (r.Max.X - dst.Rect.Min.X) * 4
+       y0 := r.Min.Y - dst.Rect.Min.Y
+       y1 := r.Max.Y - dst.Rect.Min.Y
+       switch src.SubsampleRatio {
+
+       case image.YCbCrSubsampleRatio444:
+               for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
+                       dpix := dst.Pix[y*dst.Stride:]
+                       yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
+
+                       ci := (sy-src.Rect.Min.Y)*src.CStride + (sp.X - src.Rect.Min.X)
+                       for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 {
+
+                               rr, gg, bb := color.YCbCrToRGB(src.Y[yi], src.Cb[ci], src.Cr[ci])
+                               dpix[x+0] = rr
+                               dpix[x+1] = gg
+                               dpix[x+2] = bb
+                               dpix[x+3] = 255
+                       }
+               }
+
+       case image.YCbCrSubsampleRatio422:
+               for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
+                       dpix := dst.Pix[y*dst.Stride:]
+                       yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
+
+                       ciBase := (sy-src.Rect.Min.Y)*src.CStride - src.Rect.Min.X/2
+                       for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 {
+                               ci := ciBase + sx/2
+
+                               rr, gg, bb := color.YCbCrToRGB(src.Y[yi], src.Cb[ci], src.Cr[ci])
+                               dpix[x+0] = rr
+                               dpix[x+1] = gg
+                               dpix[x+2] = bb
+                               dpix[x+3] = 255
+                       }
+               }
+
+       case image.YCbCrSubsampleRatio420:
+               for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
+                       dpix := dst.Pix[y*dst.Stride:]
+                       yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
+
+                       ciBase := (sy/2-src.Rect.Min.Y/2)*src.CStride - src.Rect.Min.X/2
+                       for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 {
+                               ci := ciBase + sx/2
+
+                               rr, gg, bb := color.YCbCrToRGB(src.Y[yi], src.Cb[ci], src.Cr[ci])
+                               dpix[x+0] = rr
+                               dpix[x+1] = gg
+                               dpix[x+2] = bb
+                               dpix[x+3] = 255
+                       }
+               }
+
+       case image.YCbCrSubsampleRatio440:
+               for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
+                       dpix := dst.Pix[y*dst.Stride:]
+                       yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
+
+                       ci := (sy/2-src.Rect.Min.Y/2)*src.CStride + (sp.X - src.Rect.Min.X)
+                       for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 {
+
+                               rr, gg, bb := color.YCbCrToRGB(src.Y[yi], src.Cb[ci], src.Cr[ci])
+                               dpix[x+0] = rr
+                               dpix[x+1] = gg
+                               dpix[x+2] = bb
+                               dpix[x+3] = 255
+                       }
+               }
+
+       default:
+               return false
+       }
+       return true
+}