Browse Source

Transpose, Transverse

disintegration 10 years ago
parent
commit
4685da8f7d
2 changed files with 128 additions and 0 deletions
  1. 56 0
      transform.go
  2. 72 0
      transform_test.go

+ 56 - 0
transform.go

@@ -143,3 +143,59 @@ func FlipV(img image.Image) *image.NRGBA {
 
 	return dst
 }
+
+// Transpose flips the image horizontally and rotates 90 degrees counter-clockwise.
+func Transpose(img image.Image) *image.NRGBA {
+	src := toNRGBA(img)
+	srcW := src.Bounds().Max.X
+	srcH := src.Bounds().Max.Y
+	dstW := srcH
+	dstH := srcW
+	dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
+
+	parallel(dstH, func(partStart, partEnd int) {
+
+		for dstY := partStart; dstY < partEnd; dstY++ {
+			for dstX := 0; dstX < dstW; dstX++ {
+				srcX := dstY
+				srcY := dstX
+
+				srcOff := srcY*src.Stride + srcX*4
+				dstOff := dstY*dst.Stride + dstX*4
+
+				copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
+			}
+		}
+
+	})
+
+	return dst
+}
+
+// Transverse flips the image vertically and rotates 90 degrees counter-clockwise.
+func Transverse(img image.Image) *image.NRGBA {
+	src := toNRGBA(img)
+	srcW := src.Bounds().Max.X
+	srcH := src.Bounds().Max.Y
+	dstW := srcH
+	dstH := srcW
+	dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
+
+	parallel(dstH, func(partStart, partEnd int) {
+
+		for dstY := partStart; dstY < partEnd; dstY++ {
+			for dstX := 0; dstX < dstW; dstX++ {
+				srcX := dstH - dstY - 1
+				srcY := dstW - dstX - 1
+
+				srcOff := srcY*src.Stride + srcX*4
+				dstOff := dstY*dst.Stride + dstX*4
+
+				copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
+			}
+		}
+
+	})
+
+	return dst
+}

+ 72 - 0
transform_test.go

@@ -187,3 +187,75 @@ func TestFlipH(t *testing.T) {
 		}
 	}
 }
+
+func TestTranspose(t *testing.T) {
+	td := []struct {
+		desc string
+		src  image.Image
+		want *image.NRGBA
+	}{
+		{
+			"Transpose 2x3",
+			&image.NRGBA{
+				Rect:   image.Rect(-1, -1, 1, 2),
+				Stride: 2 * 4,
+				Pix: []uint8{
+					0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff,
+					0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
+					0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
+				},
+			},
+			&image.NRGBA{
+				Rect:   image.Rect(0, 0, 3, 2),
+				Stride: 3 * 4,
+				Pix: []uint8{
+					0x00, 0x11, 0x22, 0x33, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
+					0xcc, 0xdd, 0xee, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+				},
+			},
+		},
+	}
+	for _, d := range td {
+		got := Transpose(d.src)
+		want := d.want
+		if !compareNRGBA(got, want, 0) {
+			t.Errorf("test [%s] failed: %#v", d.desc, got)
+		}
+	}
+}
+
+func TestTransverse(t *testing.T) {
+	td := []struct {
+		desc string
+		src  image.Image
+		want *image.NRGBA
+	}{
+		{
+			"Transverse 2x3",
+			&image.NRGBA{
+				Rect:   image.Rect(-1, -1, 1, 2),
+				Stride: 2 * 4,
+				Pix: []uint8{
+					0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff,
+					0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
+					0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
+				},
+			},
+			&image.NRGBA{
+				Rect:   image.Rect(0, 0, 3, 2),
+				Stride: 3 * 4,
+				Pix: []uint8{
+					0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xcc, 0xdd, 0xee, 0xff,
+					0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x11, 0x22, 0x33,
+				},
+			},
+		},
+	}
+	for _, d := range td {
+		got := Transverse(d.src)
+		want := d.want
+		if !compareNRGBA(got, want, 0) {
+			t.Errorf("test [%s] failed: %#v", d.desc, got)
+		}
+	}
+}