adjust_test.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984
  1. package imaging
  2. import (
  3. "image"
  4. "image/color"
  5. "testing"
  6. )
  7. func TestGrayscale(t *testing.T) {
  8. testCases := []struct {
  9. name string
  10. src image.Image
  11. want *image.NRGBA
  12. }{
  13. {
  14. "Grayscale 3x3",
  15. &image.NRGBA{
  16. Rect: image.Rect(-1, -1, 2, 2),
  17. Stride: 3 * 4,
  18. Pix: []uint8{
  19. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  20. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  21. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  22. },
  23. },
  24. &image.NRGBA{
  25. Rect: image.Rect(0, 0, 3, 3),
  26. Stride: 3 * 4,
  27. Pix: []uint8{
  28. 0x3d, 0x3d, 0x3d, 0x01, 0x78, 0x78, 0x78, 0x02, 0x17, 0x17, 0x17, 0x03,
  29. 0x1f, 0x1f, 0x1f, 0xff, 0x25, 0x25, 0x25, 0xff, 0x66, 0x66, 0x66, 0xff,
  30. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  31. },
  32. },
  33. },
  34. }
  35. for _, tc := range testCases {
  36. t.Run(tc.name, func(t *testing.T) {
  37. got := Grayscale(tc.src)
  38. if !compareNRGBA(got, tc.want, 0) {
  39. t.Fatalf("got result %#v want %#v", got, tc.want)
  40. }
  41. })
  42. }
  43. }
  44. func BenchmarkGrayscale(b *testing.B) {
  45. b.ReportAllocs()
  46. for i := 0; i < b.N; i++ {
  47. Grayscale(testdataBranchesJPG)
  48. }
  49. }
  50. func TestInvert(t *testing.T) {
  51. testCases := []struct {
  52. name string
  53. src image.Image
  54. want *image.NRGBA
  55. }{
  56. {
  57. "Invert 3x3",
  58. &image.NRGBA{
  59. Rect: image.Rect(-1, -1, 2, 2),
  60. Stride: 3 * 4,
  61. Pix: []uint8{
  62. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  63. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  64. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  65. },
  66. },
  67. &image.NRGBA{
  68. Rect: image.Rect(0, 0, 3, 3),
  69. Stride: 3 * 4,
  70. Pix: []uint8{
  71. 0x33, 0xff, 0xff, 0x01, 0xff, 0x33, 0xff, 0x02, 0xff, 0xff, 0x33, 0x03,
  72. 0xee, 0xdd, 0xcc, 0xff, 0xcc, 0xdd, 0xee, 0xff, 0x55, 0xcc, 0x44, 0xff,
  73. 0xff, 0xff, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0x00, 0x00, 0x00, 0xff,
  74. },
  75. },
  76. },
  77. }
  78. for _, tc := range testCases {
  79. t.Run(tc.name, func(t *testing.T) {
  80. got := Invert(tc.src)
  81. if !compareNRGBA(got, tc.want, 0) {
  82. t.Fatalf("got result %#v want %#v", got, tc.want)
  83. }
  84. })
  85. }
  86. }
  87. func BenchmarkInvert(b *testing.B) {
  88. b.ReportAllocs()
  89. for i := 0; i < b.N; i++ {
  90. Invert(testdataBranchesJPG)
  91. }
  92. }
  93. func TestAdjustSaturation(t *testing.T) {
  94. testCases := []struct {
  95. name string
  96. src image.Image
  97. p float64
  98. want *image.NRGBA
  99. }{
  100. {
  101. "AdjustSaturation 3x3 10",
  102. &image.NRGBA{
  103. Rect: image.Rect(-1, -1, 2, 2),
  104. Stride: 3 * 4,
  105. Pix: []uint8{
  106. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  107. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  108. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  109. },
  110. },
  111. 10,
  112. &image.NRGBA{
  113. Rect: image.Rect(0, 0, 3, 3),
  114. Stride: 3 * 4,
  115. Pix: []uint8{
  116. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  117. 0x0f, 0x22, 0x35, 0xff, 0x35, 0x22, 0x0f, 0xff, 0xaf, 0x2c, 0xc2, 0xff,
  118. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  119. },
  120. },
  121. },
  122. {
  123. "AdjustSaturation 3x3 100",
  124. &image.NRGBA{
  125. Rect: image.Rect(-1, -1, 2, 2),
  126. Stride: 3 * 4,
  127. Pix: []uint8{
  128. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  129. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  130. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  131. },
  132. },
  133. 100,
  134. &image.NRGBA{
  135. Rect: image.Rect(0, 0, 3, 3),
  136. Stride: 3 * 4,
  137. Pix: []uint8{
  138. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  139. 0x00, 0x22, 0x44, 0xff, 0x44, 0x22, 0x00, 0xff, 0xd0, 0x00, 0xee, 0xff,
  140. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  141. },
  142. },
  143. },
  144. {
  145. "AdjustSaturation 3x3 -10",
  146. &image.NRGBA{
  147. Rect: image.Rect(-1, -1, 2, 2),
  148. Stride: 3 * 4,
  149. Pix: []uint8{
  150. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  151. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  152. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  153. },
  154. },
  155. -10,
  156. &image.NRGBA{
  157. Rect: image.Rect(0, 0, 3, 3),
  158. Stride: 3 * 4,
  159. Pix: []uint8{
  160. 0xc2, 0x0a, 0x0a, 0x01, 0x0a, 0xc2, 0x0a, 0x02, 0x0a, 0x0a, 0xc2, 0x03,
  161. 0x13, 0x22, 0x31, 0xff, 0x31, 0x22, 0x13, 0xff, 0xa5, 0x3a, 0xb4, 0xff,
  162. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  163. },
  164. },
  165. },
  166. {
  167. "AdjustSaturation 3x3 -100",
  168. &image.NRGBA{
  169. Rect: image.Rect(-1, -1, 2, 2),
  170. Stride: 3 * 4,
  171. Pix: []uint8{
  172. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  173. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  174. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  175. },
  176. },
  177. -100,
  178. &image.NRGBA{
  179. Rect: image.Rect(0, 0, 3, 3),
  180. Stride: 3 * 4,
  181. Pix: []uint8{
  182. 0x66, 0x66, 0x66, 0x01, 0x66, 0x66, 0x66, 0x02, 0x66, 0x66, 0x66, 0x03,
  183. 0x22, 0x22, 0x22, 0xff, 0x22, 0x22, 0x22, 0xff, 0x77, 0x77, 0x77, 0xff,
  184. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  185. },
  186. },
  187. },
  188. {
  189. "AdjustSaturation 3x3 0",
  190. &image.NRGBA{
  191. Rect: image.Rect(-1, -1, 2, 2),
  192. Stride: 3 * 4,
  193. Pix: []uint8{
  194. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  195. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  196. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  197. },
  198. },
  199. 0,
  200. &image.NRGBA{
  201. Rect: image.Rect(0, 0, 3, 3),
  202. Stride: 3 * 4,
  203. Pix: []uint8{
  204. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  205. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  206. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  207. },
  208. },
  209. },
  210. }
  211. for _, tc := range testCases {
  212. t.Run(tc.name, func(t *testing.T) {
  213. got := AdjustSaturation(tc.src, tc.p)
  214. if !compareNRGBA(got, tc.want, 0) {
  215. t.Fatalf("got result %#v want %#v", got, tc.want)
  216. }
  217. })
  218. }
  219. }
  220. func TestAdjustSaturationGolden(t *testing.T) {
  221. for name, p := range map[string]float64{
  222. "out_saturation_m30.png": -30,
  223. "out_saturation_p30.png": 30,
  224. } {
  225. got := AdjustSaturation(testdataFlowersSmallPNG, p)
  226. want, err := Open("testdata/" + name)
  227. if err != nil {
  228. t.Fatalf("failed to open image: %v", err)
  229. }
  230. if !compareNRGBAGolden(got, toNRGBA(want)) {
  231. t.Errorf("resulting image differs from golden: %s", name)
  232. }
  233. }
  234. }
  235. func BenchmarkAdjustSaturation(b *testing.B) {
  236. b.ReportAllocs()
  237. for i := 0; i < b.N; i++ {
  238. AdjustSaturation(testdataBranchesJPG, 10)
  239. }
  240. }
  241. func TestAdjustHue(t *testing.T) {
  242. testCases := []struct {
  243. name string
  244. src image.Image
  245. p float64
  246. want *image.NRGBA
  247. }{
  248. {
  249. "AdjustHue 3x3 10",
  250. &image.NRGBA{
  251. Rect: image.Rect(-1, -1, 2, 2),
  252. Stride: 3 * 4,
  253. Pix: []uint8{
  254. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  255. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  256. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  257. },
  258. },
  259. 10,
  260. &image.NRGBA{
  261. Rect: image.Rect(0, 0, 3, 3),
  262. Stride: 3 * 4,
  263. Pix: []uint8{
  264. 0xcc, 0x00, 0x22, 0x01, 0x22, 0xcc, 0x00, 0x02, 0x00, 0x22, 0xcc, 0x03,
  265. 0x11, 0x28, 0x33, 0xff, 0x33, 0x1c, 0x11, 0xff, 0x93, 0x33, 0xbb, 0xff,
  266. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  267. },
  268. },
  269. },
  270. {
  271. "AdjustHue 3x3 180",
  272. &image.NRGBA{
  273. Rect: image.Rect(-1, -1, 2, 2),
  274. Stride: 3 * 4,
  275. Pix: []uint8{
  276. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  277. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  278. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  279. },
  280. },
  281. 180,
  282. &image.NRGBA{
  283. Rect: image.Rect(0, 0, 3, 3),
  284. Stride: 3 * 4,
  285. Pix: []uint8{
  286. 0x00, 0xcc, 0xcc, 0x01, 0xcc, 0x00, 0xcc, 0x02, 0xcc, 0xcc, 0x00, 0x03,
  287. 0x33, 0x22, 0x11, 0xff, 0x11, 0x22, 0x33, 0xff, 0x44, 0xbb, 0x33, 0xff,
  288. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  289. },
  290. },
  291. },
  292. {
  293. "AdjustHue 3x3 -10",
  294. &image.NRGBA{
  295. Rect: image.Rect(-1, -1, 2, 2),
  296. Stride: 3 * 4,
  297. Pix: []uint8{
  298. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  299. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  300. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  301. },
  302. },
  303. -10,
  304. &image.NRGBA{
  305. Rect: image.Rect(0, 0, 3, 3),
  306. Stride: 3 * 4,
  307. Pix: []uint8{
  308. 0xcc, 0x22, 0x00, 0x01, 0x00, 0xcc, 0x22, 0x02, 0x22, 0x00, 0xcc, 0x03,
  309. 0x11, 0x1c, 0x33, 0xff, 0x33, 0x28, 0x11, 0xff, 0xbb, 0x33, 0xb5, 0xff,
  310. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  311. },
  312. },
  313. },
  314. {
  315. "AdjustHue 3x3 -180",
  316. &image.NRGBA{
  317. Rect: image.Rect(-1, -1, 2, 2),
  318. Stride: 3 * 4,
  319. Pix: []uint8{
  320. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  321. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  322. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  323. },
  324. },
  325. -180,
  326. &image.NRGBA{
  327. Rect: image.Rect(0, 0, 3, 3),
  328. Stride: 3 * 4,
  329. Pix: []uint8{
  330. 0x00, 0xcc, 0xcc, 0x01, 0xcc, 0x00, 0xcc, 0x02, 0xcc, 0xcc, 0x00, 0x03,
  331. 0x33, 0x22, 0x11, 0xff, 0x11, 0x22, 0x33, 0xff, 0x44, 0xbb, 0x33, 0xff,
  332. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  333. },
  334. },
  335. },
  336. {
  337. "AdjustHue 3x3 0",
  338. &image.NRGBA{
  339. Rect: image.Rect(-1, -1, 2, 2),
  340. Stride: 3 * 4,
  341. Pix: []uint8{
  342. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  343. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  344. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  345. },
  346. },
  347. 0,
  348. &image.NRGBA{
  349. Rect: image.Rect(0, 0, 3, 3),
  350. Stride: 3 * 4,
  351. Pix: []uint8{
  352. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  353. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  354. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  355. },
  356. },
  357. },
  358. }
  359. for _, tc := range testCases {
  360. t.Run(tc.name, func(t *testing.T) {
  361. got := AdjustHue(tc.src, tc.p)
  362. if !compareNRGBA(got, tc.want, 0) {
  363. t.Fatalf("got result %#v want %#v", got, tc.want)
  364. }
  365. })
  366. }
  367. }
  368. func TestAdjustHueGolden(t *testing.T) {
  369. for name, p := range map[string]float64{
  370. "out_hue_m120.png": -120,
  371. "out_hue_m60.png": -60,
  372. "out_hue_p60.png": 60,
  373. "out_hue_p120.png": 120,
  374. } {
  375. got := AdjustHue(testdataFlowersSmallPNG, p)
  376. want, err := Open("testdata/" + name)
  377. if err != nil {
  378. t.Fatalf("failed to open image: %v", err)
  379. }
  380. if !compareNRGBAGolden(got, toNRGBA(want)) {
  381. t.Errorf("resulting image differs from golden: %s", name)
  382. }
  383. }
  384. }
  385. func BenchmarkAdjustHue(b *testing.B) {
  386. b.ReportAllocs()
  387. for i := 0; i < b.N; i++ {
  388. AdjustHue(testdataBranchesJPG, 10)
  389. }
  390. }
  391. func TestAdjustContrast(t *testing.T) {
  392. testCases := []struct {
  393. name string
  394. src image.Image
  395. p float64
  396. want *image.NRGBA
  397. }{
  398. {
  399. "AdjustContrast 3x3 10",
  400. &image.NRGBA{
  401. Rect: image.Rect(-1, -1, 2, 2),
  402. Stride: 3 * 4,
  403. Pix: []uint8{
  404. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  405. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  406. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  407. },
  408. },
  409. 10,
  410. &image.NRGBA{
  411. Rect: image.Rect(0, 0, 3, 3),
  412. Stride: 3 * 4,
  413. Pix: []uint8{
  414. 0xd5, 0x00, 0x00, 0x01, 0x00, 0xd5, 0x00, 0x02, 0x00, 0x00, 0xd5, 0x03,
  415. 0x05, 0x18, 0x2b, 0xff, 0x2b, 0x18, 0x05, 0xff, 0xaf, 0x2b, 0xc2, 0xff,
  416. 0x00, 0x00, 0x00, 0xff, 0x2b, 0x2b, 0x2b, 0xff, 0xff, 0xff, 0xff, 0xff,
  417. },
  418. },
  419. },
  420. {
  421. "AdjustContrast 3x3 100",
  422. &image.NRGBA{
  423. Rect: image.Rect(-1, -1, 2, 2),
  424. Stride: 3 * 4,
  425. Pix: []uint8{
  426. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  427. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  428. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  429. },
  430. },
  431. 100,
  432. &image.NRGBA{
  433. Rect: image.Rect(0, 0, 3, 3),
  434. Stride: 3 * 4,
  435. Pix: []uint8{
  436. 0xff, 0x00, 0x00, 0x01, 0x00, 0xff, 0x00, 0x02, 0x00, 0x00, 0xff, 0x03,
  437. 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff,
  438. 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
  439. },
  440. },
  441. },
  442. {
  443. "AdjustContrast 3x3 -10",
  444. &image.NRGBA{
  445. Rect: image.Rect(-1, -1, 2, 2),
  446. Stride: 3 * 4,
  447. Pix: []uint8{
  448. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  449. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  450. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  451. },
  452. },
  453. -10,
  454. &image.NRGBA{
  455. Rect: image.Rect(0, 0, 3, 3),
  456. Stride: 3 * 4,
  457. Pix: []uint8{
  458. 0xc4, 0x0d, 0x0d, 0x01, 0x0d, 0xc4, 0x0d, 0x02, 0x0d, 0x0d, 0xc4, 0x03,
  459. 0x1c, 0x2b, 0x3b, 0xff, 0x3b, 0x2b, 0x1c, 0xff, 0xa6, 0x3b, 0xb5, 0xff,
  460. 0x0d, 0x0d, 0x0d, 0xff, 0x3b, 0x3b, 0x3b, 0xff, 0xf2, 0xf2, 0xf2, 0xff,
  461. },
  462. },
  463. },
  464. {
  465. "AdjustContrast 3x3 -100",
  466. &image.NRGBA{
  467. Rect: image.Rect(-1, -1, 2, 2),
  468. Stride: 3 * 4,
  469. Pix: []uint8{
  470. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  471. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  472. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  473. },
  474. },
  475. -100,
  476. &image.NRGBA{
  477. Rect: image.Rect(0, 0, 3, 3),
  478. Stride: 3 * 4,
  479. Pix: []uint8{
  480. 0x80, 0x80, 0x80, 0x01, 0x80, 0x80, 0x80, 0x02, 0x80, 0x80, 0x80, 0x03,
  481. 0x80, 0x80, 0x80, 0xff, 0x80, 0x80, 0x80, 0xff, 0x80, 0x80, 0x80, 0xff,
  482. 0x80, 0x80, 0x80, 0xff, 0x80, 0x80, 0x80, 0xff, 0x80, 0x80, 0x80, 0xff,
  483. },
  484. },
  485. },
  486. {
  487. "AdjustContrast 3x3 0",
  488. &image.NRGBA{
  489. Rect: image.Rect(-1, -1, 2, 2),
  490. Stride: 3 * 4,
  491. Pix: []uint8{
  492. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  493. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  494. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  495. },
  496. },
  497. 0,
  498. &image.NRGBA{
  499. Rect: image.Rect(0, 0, 3, 3),
  500. Stride: 3 * 4,
  501. Pix: []uint8{
  502. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  503. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  504. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  505. },
  506. },
  507. },
  508. }
  509. for _, tc := range testCases {
  510. t.Run(tc.name, func(t *testing.T) {
  511. got := AdjustContrast(tc.src, tc.p)
  512. if !compareNRGBA(got, tc.want, 0) {
  513. t.Fatalf("got result %#v want %#v", got, tc.want)
  514. }
  515. })
  516. }
  517. }
  518. func TestAdjustContrastGolden(t *testing.T) {
  519. for name, p := range map[string]float64{
  520. "out_contrast_m15.png": -15,
  521. "out_contrast_p15.png": 15,
  522. } {
  523. got := AdjustContrast(testdataFlowersSmallPNG, p)
  524. want, err := Open("testdata/" + name)
  525. if err != nil {
  526. t.Fatalf("failed to open image: %v", err)
  527. }
  528. if !compareNRGBAGolden(got, toNRGBA(want)) {
  529. t.Fatalf("resulting image differs from golden: %s", name)
  530. }
  531. }
  532. }
  533. func BenchmarkAdjustContrast(b *testing.B) {
  534. b.ReportAllocs()
  535. for i := 0; i < b.N; i++ {
  536. AdjustContrast(testdataBranchesJPG, 10)
  537. }
  538. }
  539. func TestAdjustBrightness(t *testing.T) {
  540. testCases := []struct {
  541. name string
  542. src image.Image
  543. p float64
  544. want *image.NRGBA
  545. }{
  546. {
  547. "AdjustBrightness 3x3 10",
  548. &image.NRGBA{
  549. Rect: image.Rect(-1, -1, 2, 2),
  550. Stride: 3 * 4,
  551. Pix: []uint8{
  552. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  553. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  554. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  555. },
  556. },
  557. 10,
  558. &image.NRGBA{
  559. Rect: image.Rect(0, 0, 3, 3),
  560. Stride: 3 * 4,
  561. Pix: []uint8{
  562. 0xe6, 0x1a, 0x1a, 0x01, 0x1a, 0xe6, 0x1a, 0x02, 0x1a, 0x1a, 0xe6, 0x03,
  563. 0x2b, 0x3c, 0x4d, 0xff, 0x4d, 0x3c, 0x2b, 0xff, 0xc4, 0x4d, 0xd5, 0xff,
  564. 0x1a, 0x1a, 0x1a, 0xff, 0x4d, 0x4d, 0x4d, 0xff, 0xff, 0xff, 0xff, 0xff,
  565. },
  566. },
  567. },
  568. {
  569. "AdjustBrightness 3x3 100",
  570. &image.NRGBA{
  571. Rect: image.Rect(-1, -1, 2, 2),
  572. Stride: 3 * 4,
  573. Pix: []uint8{
  574. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  575. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  576. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  577. },
  578. },
  579. 100,
  580. &image.NRGBA{
  581. Rect: image.Rect(0, 0, 3, 3),
  582. Stride: 3 * 4,
  583. Pix: []uint8{
  584. 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0x02, 0xff, 0xff, 0xff, 0x03,
  585. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  586. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  587. },
  588. },
  589. },
  590. {
  591. "AdjustBrightness 3x3 -10",
  592. &image.NRGBA{
  593. Rect: image.Rect(-1, -1, 2, 2),
  594. Stride: 3 * 4,
  595. Pix: []uint8{
  596. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  597. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  598. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  599. },
  600. },
  601. -10,
  602. &image.NRGBA{
  603. Rect: image.Rect(0, 0, 3, 3),
  604. Stride: 3 * 4,
  605. Pix: []uint8{
  606. 0xb3, 0x00, 0x00, 0x01, 0x00, 0xb3, 0x00, 0x02, 0x00, 0x00, 0xb3, 0x03,
  607. 0x00, 0x09, 0x1a, 0xff, 0x1a, 0x09, 0x00, 0xff, 0x91, 0x1a, 0xa2, 0xff,
  608. 0x00, 0x00, 0x00, 0xff, 0x1a, 0x1a, 0x1a, 0xff, 0xe6, 0xe6, 0xe6, 0xff,
  609. },
  610. },
  611. },
  612. {
  613. "AdjustBrightness 3x3 -100",
  614. &image.NRGBA{
  615. Rect: image.Rect(-1, -1, 2, 2),
  616. Stride: 3 * 4,
  617. Pix: []uint8{
  618. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  619. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  620. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  621. },
  622. },
  623. -100,
  624. &image.NRGBA{
  625. Rect: image.Rect(0, 0, 3, 3),
  626. Stride: 3 * 4,
  627. Pix: []uint8{
  628. 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03,
  629. 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
  630. 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
  631. },
  632. },
  633. },
  634. {
  635. "AdjustBrightness 3x3 0",
  636. &image.NRGBA{
  637. Rect: image.Rect(-1, -1, 2, 2),
  638. Stride: 3 * 4,
  639. Pix: []uint8{
  640. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  641. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  642. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  643. },
  644. },
  645. 0,
  646. &image.NRGBA{
  647. Rect: image.Rect(0, 0, 3, 3),
  648. Stride: 3 * 4,
  649. Pix: []uint8{
  650. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  651. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  652. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  653. },
  654. },
  655. },
  656. }
  657. for _, tc := range testCases {
  658. t.Run(tc.name, func(t *testing.T) {
  659. got := AdjustBrightness(tc.src, tc.p)
  660. if !compareNRGBA(got, tc.want, 0) {
  661. t.Fatalf("got result %#v want %#v", got, tc.want)
  662. }
  663. })
  664. }
  665. }
  666. func TestAdjustBrightnessGolden(t *testing.T) {
  667. for name, p := range map[string]float64{
  668. "out_brightness_m10.png": -10,
  669. "out_brightness_p10.png": 10,
  670. } {
  671. got := AdjustBrightness(testdataFlowersSmallPNG, p)
  672. want, err := Open("testdata/" + name)
  673. if err != nil {
  674. t.Fatalf("failed to open image: %v", err)
  675. }
  676. if !compareNRGBAGolden(got, toNRGBA(want)) {
  677. t.Fatalf("resulting image differs from golden: %s", name)
  678. }
  679. }
  680. }
  681. func BenchmarkAdjustBrightness(b *testing.B) {
  682. b.ReportAllocs()
  683. for i := 0; i < b.N; i++ {
  684. AdjustBrightness(testdataBranchesJPG, 10)
  685. }
  686. }
  687. func TestAdjustGamma(t *testing.T) {
  688. testCases := []struct {
  689. name string
  690. src image.Image
  691. p float64
  692. want *image.NRGBA
  693. }{
  694. {
  695. "AdjustGamma 3x3 0.75",
  696. &image.NRGBA{
  697. Rect: image.Rect(-1, -1, 2, 2),
  698. Stride: 3 * 4,
  699. Pix: []uint8{
  700. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  701. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  702. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  703. },
  704. },
  705. 0.75,
  706. &image.NRGBA{
  707. Rect: image.Rect(0, 0, 3, 3),
  708. Stride: 3 * 4,
  709. Pix: []uint8{
  710. 0xbd, 0x00, 0x00, 0x01, 0x00, 0xbd, 0x00, 0x02, 0x00, 0x00, 0xbd, 0x03,
  711. 0x07, 0x11, 0x1e, 0xff, 0x1e, 0x11, 0x07, 0xff, 0x95, 0x1e, 0xa9, 0xff,
  712. 0x00, 0x00, 0x00, 0xff, 0x1e, 0x1e, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff,
  713. },
  714. },
  715. },
  716. {
  717. "AdjustGamma 3x3 1.5",
  718. &image.NRGBA{
  719. Rect: image.Rect(-1, -1, 2, 2),
  720. Stride: 3 * 4,
  721. Pix: []uint8{
  722. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  723. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  724. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  725. },
  726. },
  727. 1.5,
  728. &image.NRGBA{
  729. Rect: image.Rect(0, 0, 3, 3),
  730. Stride: 3 * 4,
  731. Pix: []uint8{
  732. 0xdc, 0x00, 0x00, 0x01, 0x00, 0xdc, 0x00, 0x02, 0x00, 0x00, 0xdc, 0x03,
  733. 0x2a, 0x43, 0x57, 0xff, 0x57, 0x43, 0x2a, 0xff, 0xc3, 0x57, 0xcf, 0xff,
  734. 0x00, 0x00, 0x00, 0xff, 0x57, 0x57, 0x57, 0xff, 0xff, 0xff, 0xff, 0xff,
  735. },
  736. },
  737. },
  738. {
  739. "AdjustGamma 3x3 1.0",
  740. &image.NRGBA{
  741. Rect: image.Rect(-1, -1, 2, 2),
  742. Stride: 3 * 4,
  743. Pix: []uint8{
  744. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  745. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  746. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  747. },
  748. },
  749. 1.0,
  750. &image.NRGBA{
  751. Rect: image.Rect(0, 0, 3, 3),
  752. Stride: 3 * 4,
  753. Pix: []uint8{
  754. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  755. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  756. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  757. },
  758. },
  759. },
  760. }
  761. for _, tc := range testCases {
  762. t.Run(tc.name, func(t *testing.T) {
  763. got := AdjustGamma(tc.src, tc.p)
  764. if !compareNRGBA(got, tc.want, 0) {
  765. t.Fatalf("got result %#v want %#v", got, tc.want)
  766. }
  767. })
  768. }
  769. }
  770. func TestAdjustGammaGolden(t *testing.T) {
  771. for name, g := range map[string]float64{
  772. "out_gamma_0.75.png": 0.75,
  773. "out_gamma_1.25.png": 1.25,
  774. } {
  775. got := AdjustGamma(testdataFlowersSmallPNG, g)
  776. want, err := Open("testdata/" + name)
  777. if err != nil {
  778. t.Fatalf("failed to open image: %v", err)
  779. }
  780. if !compareNRGBAGolden(got, toNRGBA(want)) {
  781. t.Fatalf("resulting image differs from golden: %s", name)
  782. }
  783. }
  784. }
  785. func BenchmarkAdjustGamma(b *testing.B) {
  786. b.ReportAllocs()
  787. for i := 0; i < b.N; i++ {
  788. AdjustGamma(testdataBranchesJPG, 1.5)
  789. }
  790. }
  791. func TestAdjustSigmoid(t *testing.T) {
  792. testCases := []struct {
  793. name string
  794. src image.Image
  795. m float64
  796. p float64
  797. want *image.NRGBA
  798. }{
  799. {
  800. "AdjustSigmoid 3x3 0.5 3.0",
  801. &image.NRGBA{
  802. Rect: image.Rect(-1, -1, 2, 2),
  803. Stride: 3 * 4,
  804. Pix: []uint8{
  805. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  806. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  807. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  808. },
  809. },
  810. 0.5,
  811. 3.0,
  812. &image.NRGBA{
  813. Rect: image.Rect(0, 0, 3, 3),
  814. Stride: 3 * 4,
  815. Pix: []uint8{
  816. 0xd4, 0x00, 0x00, 0x01, 0x00, 0xd4, 0x00, 0x02, 0x00, 0x00, 0xd4, 0x03,
  817. 0x0d, 0x1b, 0x2b, 0xff, 0x2b, 0x1b, 0x0d, 0xff, 0xb1, 0x2b, 0xc3, 0xff,
  818. 0x00, 0x00, 0x00, 0xff, 0x2b, 0x2b, 0x2b, 0xff, 0xff, 0xff, 0xff, 0xff,
  819. },
  820. },
  821. },
  822. {
  823. "AdjustSigmoid 3x3 0.5 -3.0",
  824. &image.NRGBA{
  825. Rect: image.Rect(-1, -1, 2, 2),
  826. Stride: 3 * 4,
  827. Pix: []uint8{
  828. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  829. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  830. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  831. },
  832. },
  833. 0.5,
  834. -3.0,
  835. &image.NRGBA{
  836. Rect: image.Rect(0, 0, 3, 3),
  837. Stride: 3 * 4,
  838. Pix: []uint8{
  839. 0xc4, 0x00, 0x00, 0x01, 0x00, 0xc4, 0x00, 0x02, 0x00, 0x00, 0xc4, 0x03,
  840. 0x16, 0x2a, 0x3b, 0xff, 0x3b, 0x2a, 0x16, 0xff, 0xa4, 0x3b, 0xb3, 0xff,
  841. 0x00, 0x00, 0x00, 0xff, 0x3b, 0x3b, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xff,
  842. },
  843. },
  844. },
  845. {
  846. "AdjustSigmoid 3x3 0.5 0.0",
  847. &image.NRGBA{
  848. Rect: image.Rect(-1, -1, 2, 2),
  849. Stride: 3 * 4,
  850. Pix: []uint8{
  851. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  852. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  853. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  854. },
  855. },
  856. 0.5,
  857. 0.0,
  858. &image.NRGBA{
  859. Rect: image.Rect(0, 0, 3, 3),
  860. Stride: 3 * 4,
  861. Pix: []uint8{
  862. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  863. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  864. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  865. },
  866. },
  867. },
  868. }
  869. for _, tc := range testCases {
  870. t.Run(tc.name, func(t *testing.T) {
  871. got := AdjustSigmoid(tc.src, tc.m, tc.p)
  872. if !compareNRGBA(got, tc.want, 0) {
  873. t.Fatalf("got result %#v want %#v", got, tc.want)
  874. }
  875. })
  876. }
  877. }
  878. func BenchmarkAdjustSigmoid(b *testing.B) {
  879. b.ReportAllocs()
  880. for i := 0; i < b.N; i++ {
  881. AdjustSigmoid(testdataBranchesJPG, 0.5, 3.0)
  882. }
  883. }
  884. func TestAdjustFunc(t *testing.T) {
  885. testCases := []struct {
  886. name string
  887. src image.Image
  888. fn func(c color.NRGBA) color.NRGBA
  889. want *image.NRGBA
  890. }{
  891. {
  892. "invert",
  893. &image.NRGBA{
  894. Rect: image.Rect(-1, -1, 2, 2),
  895. Stride: 3 * 4,
  896. Pix: []uint8{
  897. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  898. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  899. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  900. },
  901. },
  902. func(c color.NRGBA) color.NRGBA {
  903. return color.NRGBA{255 - c.R, 255 - c.G, 255 - c.B, c.A}
  904. },
  905. &image.NRGBA{
  906. Rect: image.Rect(0, 0, 3, 3),
  907. Stride: 3 * 4,
  908. Pix: []uint8{
  909. 0x33, 0xff, 0xff, 0x01, 0xff, 0x33, 0xff, 0x02, 0xff, 0xff, 0x33, 0x03,
  910. 0xee, 0xdd, 0xcc, 0xff, 0xcc, 0xdd, 0xee, 0xff, 0x55, 0xcc, 0x44, 0xff,
  911. 0xff, 0xff, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0x00, 0x00, 0x00, 0xff,
  912. },
  913. },
  914. },
  915. {
  916. "threshold",
  917. &image.NRGBA{
  918. Rect: image.Rect(-1, -1, 2, 2),
  919. Stride: 3 * 4,
  920. Pix: []uint8{
  921. 0xcc, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x02, 0x00, 0x00, 0xcc, 0x03,
  922. 0x11, 0x22, 0x33, 0xff, 0x33, 0x22, 0x11, 0xff, 0xaa, 0x33, 0xbb, 0xff,
  923. 0x00, 0x00, 0x00, 0xff, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
  924. },
  925. },
  926. func(c color.NRGBA) color.NRGBA {
  927. y := 0.299*float64(c.R) + 0.587*float64(c.G) + 0.114*float64(c.B)
  928. if y > 0x55 {
  929. return color.NRGBA{0xff, 0xff, 0xff, c.A}
  930. }
  931. return color.NRGBA{0x00, 0x00, 0x00, c.A}
  932. },
  933. &image.NRGBA{
  934. Rect: image.Rect(0, 0, 3, 3),
  935. Stride: 3 * 4,
  936. Pix: []uint8{
  937. 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x03,
  938. 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
  939. 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
  940. },
  941. },
  942. },
  943. }
  944. for _, tc := range testCases {
  945. t.Run(tc.name, func(t *testing.T) {
  946. got := AdjustFunc(tc.src, tc.fn)
  947. if !compareNRGBA(got, tc.want, 0) {
  948. t.Fatalf("got result %#v want %#v", got, tc.want)
  949. }
  950. })
  951. }
  952. }
  953. func BenchmarkAdjustFunc(b *testing.B) {
  954. b.ReportAllocs()
  955. for i := 0; i < b.N; i++ {
  956. AdjustFunc(testdataBranchesJPG, func(c color.NRGBA) color.NRGBA {
  957. return color.NRGBA{c.B, c.G, c.R, c.A}
  958. })
  959. }
  960. }