helpers_test.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. package imaging
  2. import (
  3. "bytes"
  4. "errors"
  5. "image"
  6. "image/color"
  7. "io"
  8. "io/ioutil"
  9. "os"
  10. "path/filepath"
  11. "testing"
  12. )
  13. var (
  14. errCreate = errors.New("failed to create file")
  15. errClose = errors.New("failed to close file")
  16. errOpen = errors.New("failed to open file")
  17. )
  18. type badFS struct{}
  19. func (badFS) Create(name string) (io.WriteCloser, error) {
  20. if name == "badFile.jpg" {
  21. return badFile{ioutil.Discard}, nil
  22. }
  23. return nil, errCreate
  24. }
  25. func (badFS) Open(name string) (io.ReadCloser, error) {
  26. return nil, errOpen
  27. }
  28. type badFile struct {
  29. io.Writer
  30. }
  31. func (badFile) Close() error {
  32. return errClose
  33. }
  34. func TestOpenSave(t *testing.T) {
  35. imgWithoutAlpha := image.NewNRGBA(image.Rect(0, 0, 4, 6))
  36. imgWithoutAlpha.Pix = []uint8{
  37. 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  38. 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  39. 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
  40. 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
  41. 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x88, 0x88, 0x88, 0xff, 0x88, 0x88, 0x88, 0xff,
  42. 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x88, 0x88, 0x88, 0xff, 0x88, 0x88, 0x88, 0xff,
  43. }
  44. imgWithAlpha := image.NewNRGBA(image.Rect(0, 0, 4, 6))
  45. imgWithAlpha.Pix = []uint8{
  46. 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  47. 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  48. 0xff, 0x00, 0x00, 0x80, 0xff, 0x00, 0x00, 0x80, 0x00, 0xff, 0x00, 0x80, 0x00, 0xff, 0x00, 0x80,
  49. 0xff, 0x00, 0x00, 0x80, 0xff, 0x00, 0x00, 0x80, 0x00, 0xff, 0x00, 0x80, 0x00, 0xff, 0x00, 0x80,
  50. 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x88, 0x88, 0x88, 0x00, 0x88, 0x88, 0x88, 0x00,
  51. 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x88, 0x88, 0x88, 0x00, 0x88, 0x88, 0x88, 0x00,
  52. }
  53. options := []EncodeOption{
  54. JPEGQuality(100),
  55. }
  56. dir, err := ioutil.TempDir("", "imaging")
  57. if err != nil {
  58. t.Fatalf("failed to create temporary directory: %v", err)
  59. }
  60. defer os.RemoveAll(dir)
  61. for _, ext := range []string{"jpg", "jpeg", "png", "gif", "bmp", "tif", "tiff"} {
  62. filename := filepath.Join(dir, "test."+ext)
  63. img := imgWithoutAlpha
  64. if ext == "png" {
  65. img = imgWithAlpha
  66. }
  67. err := Save(img, filename, options...)
  68. if err != nil {
  69. t.Fatalf("failed to save image (%q): %v", filename, err)
  70. }
  71. img2, err := Open(filename)
  72. if err != nil {
  73. t.Fatalf("failed to open image (%q): %v", filename, err)
  74. }
  75. got := Clone(img2)
  76. delta := 0
  77. if ext == "jpg" || ext == "jpeg" || ext == "gif" {
  78. delta = 3
  79. }
  80. if !compareNRGBA(got, img, delta) {
  81. t.Fatalf("bad encode-decode result (ext=%q): got %#v want %#v", ext, got, img)
  82. }
  83. }
  84. buf := &bytes.Buffer{}
  85. err = Encode(buf, imgWithAlpha, JPEG)
  86. if err != nil {
  87. t.Fatalf("failed to encode alpha to JPEG: %v", err)
  88. }
  89. buf = &bytes.Buffer{}
  90. err = Encode(buf, imgWithAlpha, Format(100))
  91. if err != ErrUnsupportedFormat {
  92. t.Fatalf("got %v want ErrUnsupportedFormat", err)
  93. }
  94. buf = bytes.NewBuffer([]byte("bad data"))
  95. _, err = Decode(buf)
  96. if err == nil {
  97. t.Fatalf("decoding bad data: expected error got nil")
  98. }
  99. err = Save(imgWithAlpha, filepath.Join(dir, "test.unknown"))
  100. if err != ErrUnsupportedFormat {
  101. t.Fatalf("got %v want ErrUnsupportedFormat", err)
  102. }
  103. prevFS := fs
  104. fs = badFS{}
  105. defer func() { fs = prevFS }()
  106. err = Save(imgWithAlpha, "test.jpg")
  107. if err != errCreate {
  108. t.Fatalf("got error %v want errCreate", err)
  109. }
  110. err = Save(imgWithAlpha, "badFile.jpg")
  111. if err != errClose {
  112. t.Fatalf("got error %v want errClose", err)
  113. }
  114. _, err = Open("test.jpg")
  115. if err != errOpen {
  116. t.Fatalf("got error %v want errOpen", err)
  117. }
  118. }
  119. func TestNew(t *testing.T) {
  120. testCases := []struct {
  121. name string
  122. w, h int
  123. c color.Color
  124. dstBounds image.Rectangle
  125. dstPix []uint8
  126. }{
  127. {
  128. "New 1x1 black",
  129. 1, 1,
  130. color.NRGBA{0, 0, 0, 0},
  131. image.Rect(0, 0, 1, 1),
  132. []uint8{0x00, 0x00, 0x00, 0x00},
  133. },
  134. {
  135. "New 1x2 red",
  136. 1, 2,
  137. color.NRGBA{255, 0, 0, 255},
  138. image.Rect(0, 0, 1, 2),
  139. []uint8{0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff},
  140. },
  141. {
  142. "New 2x1 white",
  143. 2, 1,
  144. color.NRGBA{255, 255, 255, 255},
  145. image.Rect(0, 0, 2, 1),
  146. []uint8{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
  147. },
  148. {
  149. "New 3x3 with alpha",
  150. 3, 3,
  151. color.NRGBA{0x01, 0x23, 0x45, 0x67},
  152. image.Rect(0, 0, 3, 3),
  153. []uint8{
  154. 0x01, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67,
  155. 0x01, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67,
  156. 0x01, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67,
  157. },
  158. },
  159. {
  160. "New 0x0 white",
  161. 0, 0,
  162. color.NRGBA{255, 255, 255, 255},
  163. image.Rect(0, 0, 0, 0),
  164. nil,
  165. },
  166. }
  167. for _, tc := range testCases {
  168. t.Run(tc.name, func(t *testing.T) {
  169. got := New(tc.w, tc.h, tc.c)
  170. want := image.NewNRGBA(tc.dstBounds)
  171. want.Pix = tc.dstPix
  172. if !compareNRGBA(got, want, 0) {
  173. t.Fatalf("got result %#v want %#v", got, want)
  174. }
  175. })
  176. }
  177. }
  178. func BenchmarkNew(b *testing.B) {
  179. b.ReportAllocs()
  180. for i := 0; i < b.N; i++ {
  181. New(1024, 1024, color.White)
  182. }
  183. }
  184. func TestFormats(t *testing.T) {
  185. formatNames := map[Format]string{
  186. JPEG: "JPEG",
  187. PNG: "PNG",
  188. GIF: "GIF",
  189. BMP: "BMP",
  190. TIFF: "TIFF",
  191. Format(-1): "Unsupported",
  192. }
  193. for format, name := range formatNames {
  194. got := format.String()
  195. if got != name {
  196. t.Fatalf("got format name %q want %q", got, name)
  197. }
  198. }
  199. }
  200. func TestClone(t *testing.T) {
  201. testCases := []struct {
  202. name string
  203. src image.Image
  204. want *image.NRGBA
  205. }{
  206. {
  207. "Clone NRGBA",
  208. &image.NRGBA{
  209. Rect: image.Rect(-1, -1, 0, 1),
  210. Stride: 1 * 4,
  211. Pix: []uint8{0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff},
  212. },
  213. &image.NRGBA{
  214. Rect: image.Rect(0, 0, 1, 2),
  215. Stride: 1 * 4,
  216. Pix: []uint8{0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff},
  217. },
  218. },
  219. {
  220. "Clone NRGBA64",
  221. &image.NRGBA64{
  222. Rect: image.Rect(-1, -1, 0, 1),
  223. Stride: 1 * 8,
  224. Pix: []uint8{
  225. 0x00, 0x00, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33,
  226. 0xcc, 0xcc, 0xdd, 0xdd, 0xee, 0xee, 0xff, 0xff,
  227. },
  228. },
  229. &image.NRGBA{
  230. Rect: image.Rect(0, 0, 1, 2),
  231. Stride: 1 * 4,
  232. Pix: []uint8{0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff},
  233. },
  234. },
  235. {
  236. "Clone RGBA",
  237. &image.RGBA{
  238. Rect: image.Rect(-1, -1, 0, 2),
  239. Stride: 1 * 4,
  240. Pix: []uint8{0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff},
  241. },
  242. &image.NRGBA{
  243. Rect: image.Rect(0, 0, 1, 3),
  244. Stride: 1 * 4,
  245. Pix: []uint8{0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa, 0x33, 0xcc, 0xdd, 0xee, 0xff},
  246. },
  247. },
  248. {
  249. "Clone RGBA64",
  250. &image.RGBA64{
  251. Rect: image.Rect(-1, -1, 0, 2),
  252. Stride: 1 * 8,
  253. Pix: []uint8{
  254. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  255. 0x00, 0x00, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33,
  256. 0xcc, 0xcc, 0xdd, 0xdd, 0xee, 0xee, 0xff, 0xff,
  257. },
  258. },
  259. &image.NRGBA{
  260. Rect: image.Rect(0, 0, 1, 3),
  261. Stride: 1 * 4,
  262. Pix: []uint8{0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa, 0x33, 0xcc, 0xdd, 0xee, 0xff},
  263. },
  264. },
  265. {
  266. "Clone Gray",
  267. &image.Gray{
  268. Rect: image.Rect(-1, -1, 0, 1),
  269. Stride: 1 * 1,
  270. Pix: []uint8{0x11, 0xee},
  271. },
  272. &image.NRGBA{
  273. Rect: image.Rect(0, 0, 1, 2),
  274. Stride: 1 * 4,
  275. Pix: []uint8{0x11, 0x11, 0x11, 0xff, 0xee, 0xee, 0xee, 0xff},
  276. },
  277. },
  278. {
  279. "Clone Gray16",
  280. &image.Gray16{
  281. Rect: image.Rect(-1, -1, 0, 1),
  282. Stride: 1 * 2,
  283. Pix: []uint8{0x11, 0x11, 0xee, 0xee},
  284. },
  285. &image.NRGBA{
  286. Rect: image.Rect(0, 0, 1, 2),
  287. Stride: 1 * 4,
  288. Pix: []uint8{0x11, 0x11, 0x11, 0xff, 0xee, 0xee, 0xee, 0xff},
  289. },
  290. },
  291. {
  292. "Clone Alpha",
  293. &image.Alpha{
  294. Rect: image.Rect(-1, -1, 0, 1),
  295. Stride: 1 * 1,
  296. Pix: []uint8{0x11, 0xee},
  297. },
  298. &image.NRGBA{
  299. Rect: image.Rect(0, 0, 1, 2),
  300. Stride: 1 * 4,
  301. Pix: []uint8{0xff, 0xff, 0xff, 0x11, 0xff, 0xff, 0xff, 0xee},
  302. },
  303. },
  304. {
  305. "Clone YCbCr",
  306. &image.YCbCr{
  307. Rect: image.Rect(-1, -1, 5, 0),
  308. SubsampleRatio: image.YCbCrSubsampleRatio444,
  309. YStride: 6,
  310. CStride: 6,
  311. Y: []uint8{0x00, 0xff, 0x7f, 0x26, 0x4b, 0x0e},
  312. Cb: []uint8{0x80, 0x80, 0x80, 0x6b, 0x56, 0xc0},
  313. Cr: []uint8{0x80, 0x80, 0x80, 0xc0, 0x4b, 0x76},
  314. },
  315. &image.NRGBA{
  316. Rect: image.Rect(0, 0, 6, 1),
  317. Stride: 6 * 4,
  318. Pix: []uint8{
  319. 0x00, 0x00, 0x00, 0xff,
  320. 0xff, 0xff, 0xff, 0xff,
  321. 0x7f, 0x7f, 0x7f, 0xff,
  322. 0x7f, 0x00, 0x00, 0xff,
  323. 0x00, 0x7f, 0x00, 0xff,
  324. 0x00, 0x00, 0x7f, 0xff,
  325. },
  326. },
  327. },
  328. {
  329. "Clone YCbCr 444",
  330. &image.YCbCr{
  331. Y: []uint8{0x4c, 0x69, 0x1d, 0xb1, 0x96, 0xe2, 0x26, 0x34, 0xe, 0x59, 0x4b, 0x71, 0x0, 0x4c, 0x99, 0xff},
  332. Cb: []uint8{0x55, 0xd4, 0xff, 0x8e, 0x2c, 0x01, 0x6b, 0xaa, 0xc0, 0x95, 0x56, 0x40, 0x80, 0x80, 0x80, 0x80},
  333. Cr: []uint8{0xff, 0xeb, 0x6b, 0x36, 0x15, 0x95, 0xc0, 0xb5, 0x76, 0x41, 0x4b, 0x8c, 0x80, 0x80, 0x80, 0x80},
  334. YStride: 4,
  335. CStride: 4,
  336. SubsampleRatio: image.YCbCrSubsampleRatio444,
  337. Rect: image.Rectangle{Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 4, Y: 4}},
  338. },
  339. &image.NRGBA{
  340. Pix: []uint8{0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x49, 0xe1, 0xca, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0xff, 0x0, 0xff, 0x7f, 0x0, 0x0, 0xff, 0x7f, 0x0, 0x7f, 0xff, 0x0, 0x0, 0x7f, 0xff, 0x0, 0x7f, 0x7f, 0xff, 0x0, 0x7f, 0x0, 0xff, 0x82, 0x7f, 0x0, 0xff, 0x0, 0x0, 0x0, 0xff, 0x4c, 0x4c, 0x4c, 0xff, 0x99, 0x99, 0x99, 0xff, 0xff, 0xff, 0xff, 0xff},
  341. Stride: 16,
  342. Rect: image.Rectangle{Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 4, Y: 4}},
  343. },
  344. },
  345. {
  346. "Clone YCbCr 440",
  347. &image.YCbCr{
  348. Y: []uint8{0x4c, 0x69, 0x1d, 0xb1, 0x96, 0xe2, 0x26, 0x34, 0xe, 0x59, 0x4b, 0x71, 0x0, 0x4c, 0x99, 0xff},
  349. Cb: []uint8{0x2c, 0x01, 0x6b, 0xaa, 0x80, 0x80, 0x80, 0x80},
  350. Cr: []uint8{0x15, 0x95, 0xc0, 0xb5, 0x80, 0x80, 0x80, 0x80},
  351. YStride: 4,
  352. CStride: 4,
  353. SubsampleRatio: image.YCbCrSubsampleRatio440,
  354. Rect: image.Rectangle{Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 4, Y: 4}},
  355. },
  356. &image.NRGBA{
  357. Pix: []uint8{0x0, 0xb5, 0x0, 0xff, 0x86, 0x86, 0x0, 0xff, 0x77, 0x0, 0x0, 0xff, 0xfb, 0x7d, 0xfb, 0xff, 0x0, 0xff, 0x1, 0xff, 0xff, 0xff, 0x1, 0xff, 0x80, 0x0, 0x1, 0xff, 0x7e, 0x0, 0x7e, 0xff, 0xe, 0xe, 0xe, 0xff, 0x59, 0x59, 0x59, 0xff, 0x4b, 0x4b, 0x4b, 0xff, 0x71, 0x71, 0x71, 0xff, 0x0, 0x0, 0x0, 0xff, 0x4c, 0x4c, 0x4c, 0xff, 0x99, 0x99, 0x99, 0xff, 0xff, 0xff, 0xff, 0xff},
  358. Stride: 16,
  359. Rect: image.Rectangle{Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 4, Y: 4}},
  360. },
  361. },
  362. {
  363. "Clone YCbCr 422",
  364. &image.YCbCr{
  365. Y: []uint8{0x4c, 0x69, 0x1d, 0xb1, 0x96, 0xe2, 0x26, 0x34, 0xe, 0x59, 0x4b, 0x71, 0x0, 0x4c, 0x99, 0xff},
  366. Cb: []uint8{0xd4, 0x8e, 0x01, 0xaa, 0x95, 0x40, 0x80, 0x80},
  367. Cr: []uint8{0xeb, 0x36, 0x95, 0xb5, 0x41, 0x8c, 0x80, 0x80},
  368. YStride: 4,
  369. CStride: 2,
  370. SubsampleRatio: image.YCbCrSubsampleRatio422,
  371. Rect: image.Rectangle{Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 4, Y: 4}},
  372. },
  373. &image.NRGBA{
  374. Pix: []uint8{0xe2, 0x0, 0xe1, 0xff, 0xff, 0x0, 0xfe, 0xff, 0x0, 0x4d, 0x36, 0xff, 0x49, 0xe1, 0xca, 0xff, 0xb3, 0xb3, 0x0, 0xff, 0xff, 0xff, 0x1, 0xff, 0x70, 0x0, 0x70, 0xff, 0x7e, 0x0, 0x7e, 0xff, 0x0, 0x34, 0x33, 0xff, 0x1, 0x7f, 0x7e, 0xff, 0x5c, 0x58, 0x0, 0xff, 0x82, 0x7e, 0x0, 0xff, 0x0, 0x0, 0x0, 0xff, 0x4c, 0x4c, 0x4c, 0xff, 0x99, 0x99, 0x99, 0xff, 0xff, 0xff, 0xff, 0xff},
  375. Stride: 16,
  376. Rect: image.Rectangle{Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 4, Y: 4}},
  377. },
  378. },
  379. {
  380. "Clone YCbCr 420",
  381. &image.YCbCr{
  382. Y: []uint8{0x4c, 0x69, 0x1d, 0xb1, 0x96, 0xe2, 0x26, 0x34, 0xe, 0x59, 0x4b, 0x71, 0x0, 0x4c, 0x99, 0xff},
  383. Cb: []uint8{0x01, 0xaa, 0x80, 0x80},
  384. Cr: []uint8{0x95, 0xb5, 0x80, 0x80},
  385. YStride: 4, CStride: 2,
  386. SubsampleRatio: image.YCbCrSubsampleRatio420,
  387. Rect: image.Rectangle{Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 4, Y: 4}},
  388. },
  389. &image.NRGBA{
  390. Pix: []uint8{0x69, 0x69, 0x0, 0xff, 0x86, 0x86, 0x0, 0xff, 0x67, 0x0, 0x67, 0xff, 0xfb, 0x7d, 0xfb, 0xff, 0xb3, 0xb3, 0x0, 0xff, 0xff, 0xff, 0x1, 0xff, 0x70, 0x0, 0x70, 0xff, 0x7e, 0x0, 0x7e, 0xff, 0xe, 0xe, 0xe, 0xff, 0x59, 0x59, 0x59, 0xff, 0x4b, 0x4b, 0x4b, 0xff, 0x71, 0x71, 0x71, 0xff, 0x0, 0x0, 0x0, 0xff, 0x4c, 0x4c, 0x4c, 0xff, 0x99, 0x99, 0x99, 0xff, 0xff, 0xff, 0xff, 0xff},
  391. Stride: 16,
  392. Rect: image.Rectangle{Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 4, Y: 4}},
  393. },
  394. },
  395. {
  396. "Clone Paletted",
  397. &image.Paletted{
  398. Rect: image.Rect(-1, -1, 5, 0),
  399. Stride: 6 * 1,
  400. Palette: color.Palette{
  401. color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0xff},
  402. color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff},
  403. color.NRGBA{R: 0x7f, G: 0x7f, B: 0x7f, A: 0xff},
  404. color.NRGBA{R: 0x7f, G: 0x00, B: 0x00, A: 0xff},
  405. color.NRGBA{R: 0x00, G: 0x7f, B: 0x00, A: 0xff},
  406. color.NRGBA{R: 0x00, G: 0x00, B: 0x7f, A: 0xff},
  407. },
  408. Pix: []uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5},
  409. },
  410. &image.NRGBA{
  411. Rect: image.Rect(0, 0, 6, 1),
  412. Stride: 6 * 4,
  413. Pix: []uint8{
  414. 0x00, 0x00, 0x00, 0xff,
  415. 0xff, 0xff, 0xff, 0xff,
  416. 0x7f, 0x7f, 0x7f, 0xff,
  417. 0x7f, 0x00, 0x00, 0xff,
  418. 0x00, 0x7f, 0x00, 0xff,
  419. 0x00, 0x00, 0x7f, 0xff,
  420. },
  421. },
  422. },
  423. }
  424. for _, tc := range testCases {
  425. t.Run(tc.name, func(t *testing.T) {
  426. got := Clone(tc.src)
  427. delta := 0
  428. if _, ok := tc.src.(*image.YCbCr); ok {
  429. delta = 1
  430. }
  431. if !compareNRGBA(got, tc.want, delta) {
  432. t.Fatalf("got result %#v want %#v", got, tc.want)
  433. }
  434. })
  435. }
  436. }