github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/raw/all_test.go (about)

     1  // Copyright 2014 <chaishushan{AT}gmail.com>. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package raw
     6  
     7  import (
     8  	"fmt"
     9  	"image"
    10  	"image/color"
    11  	"image/draw"
    12  	"reflect"
    13  	"testing"
    14  
    15  	image_ext "github.com/chai2010/gopkg/image"
    16  	color_ext "github.com/chai2010/gopkg/image/color"
    17  )
    18  
    19  type tTester struct {
    20  	Image    draw.Image
    21  	Model    color.Model
    22  	DataType reflect.Kind
    23  	Channels int
    24  }
    25  
    26  var tTesterList = []tTester{
    27  	// Gray/Gray16/Gray32f
    28  	tTester{
    29  		Image:    image.NewGray(image.Rect(0, 0, 10, 10)),
    30  		Model:    color.GrayModel,
    31  		DataType: reflect.Uint8,
    32  		Channels: 1,
    33  	},
    34  	tTester{
    35  		Image:    image.NewGray16(image.Rect(0, 0, 10, 10)),
    36  		Model:    color.Gray16Model,
    37  		DataType: reflect.Uint16,
    38  		Channels: 1,
    39  	},
    40  	tTester{
    41  		Image:    image_ext.NewGray32f(image.Rect(0, 0, 10, 10)),
    42  		Model:    color_ext.Gray32fModel,
    43  		DataType: reflect.Float32,
    44  		Channels: 1,
    45  	},
    46  	// RGB/RGB48/RGB96f
    47  	tTester{
    48  		Image:    image_ext.NewRGB(image.Rect(0, 0, 10, 10)),
    49  		Model:    color_ext.RGBModel,
    50  		DataType: reflect.Uint8,
    51  		Channels: 3,
    52  	},
    53  	tTester{
    54  		Image:    image_ext.NewRGB48(image.Rect(0, 0, 10, 10)),
    55  		Model:    color_ext.RGB48Model,
    56  		DataType: reflect.Uint16,
    57  		Channels: 3,
    58  	},
    59  	tTester{
    60  		Image:    image_ext.NewRGB96f(image.Rect(0, 0, 10, 10)),
    61  		Model:    color_ext.RGB96fModel,
    62  		DataType: reflect.Float32,
    63  		Channels: 3,
    64  	},
    65  	// RGBA/RGBA48/RGBA128f
    66  	tTester{
    67  		Image:    image.NewRGBA(image.Rect(0, 0, 10, 10)),
    68  		Model:    color.RGBAModel,
    69  		DataType: reflect.Uint8,
    70  		Channels: 4,
    71  	},
    72  	tTester{
    73  		Image:    image.NewRGBA64(image.Rect(0, 0, 10, 10)),
    74  		Model:    color.RGBA64Model,
    75  		DataType: reflect.Uint16,
    76  		Channels: 4,
    77  	},
    78  	tTester{
    79  		Image:    image_ext.NewRGBA128f(image.Rect(0, 0, 10, 10)),
    80  		Model:    color_ext.RGBA128fModel,
    81  		DataType: reflect.Float32,
    82  		Channels: 4,
    83  	},
    84  }
    85  
    86  func TestEncodeAndDecode(t *testing.T) {
    87  	for _, v := range tTesterList {
    88  		v.Image.Set(6, 3, color.RGBA{0xAA, 0xBB, 0xCC, 0xDD})
    89  	}
    90  	for i, v := range tTesterList {
    91  		encoder := Encoder{v.Channels, v.DataType}
    92  		decoder := Decoder{v.Channels, v.DataType, v.Image.Bounds().Dx(), v.Image.Bounds().Dy()}
    93  
    94  		data, err := encoder.Encode(v.Image, nil)
    95  		if err != nil {
    96  			t.Fatalf("%d: %v", i, err)
    97  		}
    98  
    99  		m, err := decoder.Decode(data, nil)
   100  		if err != nil {
   101  			t.Fatalf("%d: %v", i, err)
   102  		}
   103  
   104  		err = tCompareImage(v.Image, v.Channels, v.Model, m)
   105  		if err != nil {
   106  			t.Fatalf("%d: %v", i, err)
   107  		}
   108  	}
   109  }
   110  
   111  func TestEncodeAndDecode_YCbCr2Gray(t *testing.T) {
   112  	yuv := tNewYCbCr(image.Rect(0, 0, 10, 10), image.YCbCrSubsampleRatio420)
   113  	tSetYCbCr(yuv, 6, 3, color.Gray{0xAB})
   114  
   115  	encoder := Encoder{1, reflect.Uint8}
   116  	decoder := Decoder{1, reflect.Uint8, yuv.Bounds().Dx(), yuv.Bounds().Dy()}
   117  
   118  	data, err := encoder.Encode(yuv, nil)
   119  	if err != nil {
   120  		t.Fatalf("%v", err)
   121  	}
   122  	m0, err := decoder.Decode(data, nil)
   123  	if err != nil {
   124  		t.Fatalf("%v", err)
   125  	}
   126  
   127  	m1, err := decoder.DecodeImage(yuv, nil)
   128  	if err != nil {
   129  		t.Fatalf("%v", err)
   130  	}
   131  
   132  	// check color
   133  	if m0.ColorModel() != color.GrayModel {
   134  		t.Fatalf("want %v, got %v", color.GrayModel, m0.ColorModel())
   135  	}
   136  	if m1.ColorModel() != color.GrayModel {
   137  		t.Fatalf("want %v, got %v", color.GrayModel, m1.ColorModel())
   138  	}
   139  
   140  	// check size
   141  	if m0.Bounds() != yuv.Bounds() {
   142  		t.Fatalf("want %v, got %v", yuv.Bounds(), m0.Bounds())
   143  	}
   144  	if m1.Bounds() != yuv.Bounds() {
   145  		t.Fatalf("want %v, got %v", yuv.Bounds(), m1.Bounds())
   146  	}
   147  
   148  	// check data
   149  	b := yuv.Bounds()
   150  	for y := b.Min.Y; y < b.Max.Y; y++ {
   151  		for x := b.Min.X; x < b.Max.X; x++ {
   152  			gray := color.GrayModel.Convert(yuv.At(x, y)).(color.Gray)
   153  			c0 := m0.At(x, y).(color.Gray)
   154  			c1 := m1.At(x, y).(color.Gray)
   155  			if c0 != gray {
   156  				t.Fatalf("pixel at (%d, %d) has wrong color: want %v, got %v", x, y, gray, c0)
   157  			}
   158  			if c1 != gray {
   159  				t.Fatalf("pixel at (%d, %d) has wrong color: want %v, got %v", x, y, gray, c1)
   160  			}
   161  		}
   162  	}
   163  }
   164  
   165  func TestEncodeAndDecode_YCbCr2RGB(t *testing.T) {
   166  	yuv := tNewYCbCr(image.Rect(0, 0, 10, 10), image.YCbCrSubsampleRatio420)
   167  	tSetYCbCr(yuv, 6, 3, color.RGBA{0xAA, 0xBB, 0xCC, 0xDD})
   168  
   169  	encoder := Encoder{3, reflect.Uint8}
   170  	decoder := Decoder{3, reflect.Uint8, yuv.Bounds().Dx(), yuv.Bounds().Dy()}
   171  
   172  	data, err := encoder.Encode(yuv, nil)
   173  	if err != nil {
   174  		t.Fatalf("%v", err)
   175  	}
   176  	m0, err := decoder.Decode(data, nil)
   177  	if err != nil {
   178  		t.Fatalf("%v", err)
   179  	}
   180  
   181  	m1, err := decoder.DecodeImage(yuv, nil)
   182  	if err != nil {
   183  		t.Fatalf("%v", err)
   184  	}
   185  
   186  	// check color
   187  	if m0.ColorModel() != color_ext.RGBModel {
   188  		t.Fatalf("want %v, got %v", color_ext.RGBModel, m0.ColorModel())
   189  	}
   190  	if m1.ColorModel() != color_ext.RGBModel {
   191  		t.Fatalf("want %v, got %v", color_ext.RGBModel, m1.ColorModel())
   192  	}
   193  
   194  	// check size
   195  	if m0.Bounds() != yuv.Bounds() {
   196  		t.Fatalf("want %v, got %v", yuv.Bounds(), m0.Bounds())
   197  	}
   198  	if m1.Bounds() != yuv.Bounds() {
   199  		t.Fatalf("want %v, got %v", yuv.Bounds(), m1.Bounds())
   200  	}
   201  
   202  	// check data
   203  	b := yuv.Bounds()
   204  	for y := b.Min.Y; y < b.Max.Y; y++ {
   205  		for x := b.Min.X; x < b.Max.X; x++ {
   206  			rgb := color_ext.RGBModel.Convert(yuv.At(x, y)).(color_ext.RGB)
   207  			c0 := m0.At(x, y).(color_ext.RGB)
   208  			c1 := m1.At(x, y).(color_ext.RGB)
   209  			if c0 != rgb {
   210  				t.Fatalf("pixel at (%d, %d) has wrong color: want %v, got %v", x, y, rgb, c0)
   211  			}
   212  			if c1 != rgb {
   213  				t.Fatalf("pixel at (%d, %d) has wrong color: want %v, got %v", x, y, rgb, c1)
   214  			}
   215  		}
   216  	}
   217  }
   218  
   219  func TestEncodeAndDecode_YCbCr2RGBA(t *testing.T) {
   220  	yuv := tNewYCbCr(image.Rect(0, 0, 10, 10), image.YCbCrSubsampleRatio420)
   221  	tSetYCbCr(yuv, 6, 3, color.RGBA{0xAA, 0xBB, 0xCC, 0xDD})
   222  
   223  	encoder := Encoder{4, reflect.Uint8}
   224  	decoder := Decoder{4, reflect.Uint8, yuv.Bounds().Dx(), yuv.Bounds().Dy()}
   225  
   226  	data, err := encoder.Encode(yuv, nil)
   227  	if err != nil {
   228  		t.Fatalf("%v", err)
   229  	}
   230  	m0, err := decoder.Decode(data, nil)
   231  	if err != nil {
   232  		t.Fatalf("%v", err)
   233  	}
   234  
   235  	m1, err := decoder.DecodeImage(yuv, nil)
   236  	if err != nil {
   237  		t.Fatalf("%v", err)
   238  	}
   239  
   240  	// check color
   241  	if m0.ColorModel() != color.RGBAModel {
   242  		t.Fatalf("want %v, got %v", color.RGBAModel, m0.ColorModel())
   243  	}
   244  	if m1.ColorModel() != color.RGBAModel {
   245  		t.Fatalf("want %v, got %v", color.RGBAModel, m1.ColorModel())
   246  	}
   247  
   248  	// check size
   249  	if m0.Bounds() != yuv.Bounds() {
   250  		t.Fatalf("want %v, got %v", yuv.Bounds(), m0.Bounds())
   251  	}
   252  	if m1.Bounds() != yuv.Bounds() {
   253  		t.Fatalf("want %v, got %v", yuv.Bounds(), m1.Bounds())
   254  	}
   255  
   256  	// check data
   257  	b := yuv.Bounds()
   258  	for y := b.Min.Y; y < b.Max.Y; y++ {
   259  		for x := b.Min.X; x < b.Max.X; x++ {
   260  			rgba := color.RGBAModel.Convert(yuv.At(x, y)).(color.RGBA)
   261  			c0 := m0.At(x, y).(color.RGBA)
   262  			c1 := m1.At(x, y).(color.RGBA)
   263  			if c0 != rgba {
   264  				t.Fatalf("pixel at (%d, %d) has wrong color: want %v, got %v", x, y, rgba, c0)
   265  			}
   266  			if c1 != rgba {
   267  				t.Fatalf("pixel at (%d, %d) has wrong color: want %v, got %v", x, y, rgba, c1)
   268  			}
   269  		}
   270  	}
   271  }
   272  
   273  func tCompareImage(img0 image.Image, channels int, model color.Model, img1 image.Image) error {
   274  	if img1.ColorModel() != model {
   275  		return fmt.Errorf("img1 wrong image model: want %v, got %v", model, img1.ColorModel())
   276  	}
   277  	if !img1.Bounds().Eq(img0.Bounds()) {
   278  		return fmt.Errorf("wrong image size: want %v, got %v", img0.Bounds(), img1.Bounds())
   279  	}
   280  
   281  	switch img0.ColorModel() {
   282  	case color_ext.Gray32fModel:
   283  		b := img1.Bounds()
   284  		img0 := img0.(*image_ext.Gray32f)
   285  		img1 := img1.(*image_ext.Gray32f)
   286  		for y := b.Min.Y; y < b.Max.Y; y++ {
   287  			for x := b.Min.X; x < b.Max.X; x++ {
   288  				c0 := img0.Gray32fAt(x, y)
   289  				c1 := img1.Gray32fAt(x, y)
   290  				if c0 != c1 {
   291  					return fmt.Errorf("pixel at (%d, %d) has wrong color: want %v, got %v", x, y, c0, c1)
   292  				}
   293  			}
   294  		}
   295  	case color_ext.RGB96fModel:
   296  		b := img1.Bounds()
   297  		img0 := img0.(*image_ext.RGB96f)
   298  		img1 := img1.(*image_ext.RGB96f)
   299  		for y := b.Min.Y; y < b.Max.Y; y++ {
   300  			for x := b.Min.X; x < b.Max.X; x++ {
   301  				c0 := img0.RGB96fAt(x, y)
   302  				c1 := img1.RGB96fAt(x, y)
   303  				if c0 != c1 {
   304  					return fmt.Errorf("pixel at (%d, %d) has wrong color: want %v, got %v", x, y, c0, c1)
   305  				}
   306  			}
   307  		}
   308  	case color_ext.RGBA128fModel:
   309  		b := img1.Bounds()
   310  		img0 := img0.(*image_ext.RGBA128f)
   311  		img1 := img1.(*image_ext.RGBA128f)
   312  		for y := b.Min.Y; y < b.Max.Y; y++ {
   313  			for x := b.Min.X; x < b.Max.X; x++ {
   314  				c0 := img0.RGBA128fAt(x, y)
   315  				c1 := img1.RGBA128fAt(x, y)
   316  				if channels == 3 {
   317  					c0.A, c1.A = 0, 0
   318  				}
   319  				if c0 != c1 {
   320  					return fmt.Errorf("pixel at (%d, %d) has wrong color: want %v, got %v", x, y, c0, c1)
   321  				}
   322  			}
   323  		}
   324  	default:
   325  		b := img1.Bounds()
   326  		for y := b.Min.Y; y < b.Max.Y; y++ {
   327  			for x := b.Min.X; x < b.Max.X; x++ {
   328  				switch channels {
   329  				case 4:
   330  					c0 := img0.At(x, y)
   331  					c1 := img1.At(x, y)
   332  					r0, g0, b0, a0 := c0.RGBA()
   333  					r1, g1, b1, a1 := c1.RGBA()
   334  					if r0 != r1 || g0 != g1 || b0 != b1 || a0 != a1 {
   335  						return fmt.Errorf("pixel at (%d, %d) has wrong color: want %v, got %v", x, y, c0, c1)
   336  					}
   337  				case 3:
   338  					c0 := img0.At(x, y)
   339  					c1 := img1.At(x, y)
   340  					r0, g0, b0, _ := c0.RGBA()
   341  					r1, g1, b1, _ := c1.RGBA()
   342  					if r0 != r1 || g0 != g1 || b0 != b1 {
   343  						return fmt.Errorf("pixel at (%d, %d) has wrong color: want %v, got %v", x, y, c0, c1)
   344  					}
   345  				case 1:
   346  					c0 := color.GrayModel.Convert(img0.At(x, y)).(color.Gray)
   347  					c1 := color.GrayModel.Convert(img1.At(x, y)).(color.Gray)
   348  					if c0 != c1 {
   349  						return fmt.Errorf("pixel at (%d, %d) has wrong color: want %v, got %v", x, y, c0, c1)
   350  					}
   351  				}
   352  			}
   353  		}
   354  	}
   355  	return nil
   356  }
   357  
   358  // new a zero YCbCr
   359  func tNewYCbCr(r image.Rectangle, subsampleRatio image.YCbCrSubsampleRatio) *image.YCbCr {
   360  	m := image.NewYCbCr(r, subsampleRatio)
   361  	for i := 0; i < len(m.Cb); i++ {
   362  		m.Cb[i] = tZeroYCbCr.Cb
   363  	}
   364  	for i := 0; i < len(m.Cr); i++ {
   365  		m.Cr[i] = tZeroYCbCr.Cr
   366  	}
   367  	return m
   368  }
   369  
   370  // YCbCr.Set
   371  func tSetYCbCr(p *image.YCbCr, x, y int, c color.Color) {
   372  	if !(image.Point{x, y}.In(p.Rect)) {
   373  		return
   374  	}
   375  	yi := p.YOffset(x, y)
   376  	ci := p.COffset(x, y)
   377  	c1 := color.YCbCrModel.Convert(c).(color.YCbCr)
   378  	p.Y[yi] = c1.Y
   379  	p.Cb[ci] = c1.Cb
   380  	p.Cr[ci] = c1.Cr
   381  }
   382  
   383  var tZeroYCbCr = func() (c color.YCbCr) {
   384  	c.Y, c.Cb, c.Cr = color.RGBToYCbCr(0, 0, 0)
   385  	return
   386  }()