image.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. // Copyright 2009 The Go Authors. 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. // Package image implements a basic 2-D image library.
  5. //
  6. // The fundamental interface is called Image. An Image contains colors, which
  7. // are described in the image/color package.
  8. //
  9. // Values of the Image interface are created either by calling functions such
  10. // as NewRGBA and NewPaletted, or by calling Decode on an io.Reader containing
  11. // image data in a format such as GIF, JPEG or PNG. Decoding any particular
  12. // image format requires the prior registration of a decoder function.
  13. // Registration is typically automatic as a side effect of initializing that
  14. // format's package so that, to decode a PNG image, it suffices to have
  15. // import _ "image/png"
  16. // in a program's main package. The _ means to import a package purely for its
  17. // initialization side effects.
  18. //
  19. // See "The Go image package" for more details:
  20. // http://golang.org/doc/articles/image_package.html
  21. package image
  22. import (
  23. "image/color"
  24. )
  25. // Config holds an image's color model and dimensions.
  26. type Config struct {
  27. ColorModel color.Model
  28. Width, Height int
  29. }
  30. // Image is a finite rectangular grid of color.Color values taken from a color
  31. // model.
  32. type Image interface {
  33. // ColorModel returns the Image's color model.
  34. ColorModel() color.Model
  35. // Bounds returns the domain for which At can return non-zero color.
  36. // The bounds do not necessarily contain the point (0, 0).
  37. Bounds() Rectangle
  38. // At returns the color of the pixel at (x, y).
  39. // At(Bounds().Min.X, Bounds().Min.Y) returns the upper-left pixel of the grid.
  40. // At(Bounds().Max.X-1, Bounds().Max.Y-1) returns the lower-right one.
  41. At(x, y int) color.Color
  42. }
  43. // PalettedImage is an image whose colors may come from a limited palette.
  44. // If m is a PalettedImage and m.ColorModel() returns a PalettedColorModel p,
  45. // then m.At(x, y) should be equivalent to p[m.ColorIndexAt(x, y)]. If m's
  46. // color model is not a PalettedColorModel, then ColorIndexAt's behavior is
  47. // undefined.
  48. type PalettedImage interface {
  49. // ColorIndexAt returns the palette index of the pixel at (x, y).
  50. ColorIndexAt(x, y int) uint8
  51. Image
  52. }
  53. // RGBA is an in-memory image whose At method returns color.RGBA values.
  54. type RGBA struct {
  55. // Pix holds the image's pixels, in R, G, B, A order. The pixel at
  56. // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4].
  57. Pix []uint8
  58. // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
  59. Stride int
  60. // Rect is the image's bounds.
  61. Rect Rectangle
  62. }
  63. func (p *RGBA) ColorModel() color.Model { return color.RGBAModel }
  64. func (p *RGBA) Bounds() Rectangle { return p.Rect }
  65. func (p *RGBA) At(x, y int) color.Color {
  66. return p.RGBAAt(x, y)
  67. }
  68. func (p *RGBA) RGBAAt(x, y int) color.RGBA {
  69. if !(Point{x, y}.In(p.Rect)) {
  70. return color.RGBA{}
  71. }
  72. i := p.PixOffset(x, y)
  73. return color.RGBA{p.Pix[i+0], p.Pix[i+1], p.Pix[i+2], p.Pix[i+3]}
  74. }
  75. // PixOffset returns the index of the first element of Pix that corresponds to
  76. // the pixel at (x, y).
  77. func (p *RGBA) PixOffset(x, y int) int {
  78. return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*4
  79. }
  80. func (p *RGBA) Set(x, y int, c color.Color) {
  81. if !(Point{x, y}.In(p.Rect)) {
  82. return
  83. }
  84. i := p.PixOffset(x, y)
  85. c1 := color.RGBAModel.Convert(c).(color.RGBA)
  86. p.Pix[i+0] = c1.R
  87. p.Pix[i+1] = c1.G
  88. p.Pix[i+2] = c1.B
  89. p.Pix[i+3] = c1.A
  90. }
  91. func (p *RGBA) SetRGBA(x, y int, c color.RGBA) {
  92. if !(Point{x, y}.In(p.Rect)) {
  93. return
  94. }
  95. i := p.PixOffset(x, y)
  96. p.Pix[i+0] = c.R
  97. p.Pix[i+1] = c.G
  98. p.Pix[i+2] = c.B
  99. p.Pix[i+3] = c.A
  100. }
  101. // SubImage returns an image representing the portion of the image p visible
  102. // through r. The returned value shares pixels with the original image.
  103. func (p *RGBA) SubImage(r Rectangle) Image {
  104. r = r.Intersect(p.Rect)
  105. // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
  106. // either r1 or r2 if the intersection is empty. Without explicitly checking for
  107. // this, the Pix[i:] expression below can panic.
  108. if r.Empty() {
  109. return &RGBA{}
  110. }
  111. i := p.PixOffset(r.Min.X, r.Min.Y)
  112. return &RGBA{
  113. Pix: p.Pix[i:],
  114. Stride: p.Stride,
  115. Rect: r,
  116. }
  117. }
  118. // Opaque scans the entire image and reports whether it is fully opaque.
  119. func (p *RGBA) Opaque() bool {
  120. if p.Rect.Empty() {
  121. return true
  122. }
  123. i0, i1 := 3, p.Rect.Dx()*4
  124. for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
  125. for i := i0; i < i1; i += 4 {
  126. if p.Pix[i] != 0xff {
  127. return false
  128. }
  129. }
  130. i0 += p.Stride
  131. i1 += p.Stride
  132. }
  133. return true
  134. }
  135. // NewRGBA returns a new RGBA with the given bounds.
  136. func NewRGBA(r Rectangle) *RGBA {
  137. w, h := r.Dx(), r.Dy()
  138. buf := make([]uint8, 4*w*h)
  139. return &RGBA{buf, 4 * w, r}
  140. }
  141. // RGBA64 is an in-memory image whose At method returns color.RGBA64 values.
  142. type RGBA64 struct {
  143. // Pix holds the image's pixels, in R, G, B, A order and big-endian format. The pixel at
  144. // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*8].
  145. Pix []uint8
  146. // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
  147. Stride int
  148. // Rect is the image's bounds.
  149. Rect Rectangle
  150. }
  151. func (p *RGBA64) ColorModel() color.Model { return color.RGBA64Model }
  152. func (p *RGBA64) Bounds() Rectangle { return p.Rect }
  153. func (p *RGBA64) At(x, y int) color.Color {
  154. return p.RGBA64At(x, y)
  155. }
  156. func (p *RGBA64) RGBA64At(x, y int) color.RGBA64 {
  157. if !(Point{x, y}.In(p.Rect)) {
  158. return color.RGBA64{}
  159. }
  160. i := p.PixOffset(x, y)
  161. return color.RGBA64{
  162. uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1]),
  163. uint16(p.Pix[i+2])<<8 | uint16(p.Pix[i+3]),
  164. uint16(p.Pix[i+4])<<8 | uint16(p.Pix[i+5]),
  165. uint16(p.Pix[i+6])<<8 | uint16(p.Pix[i+7]),
  166. }
  167. }
  168. // PixOffset returns the index of the first element of Pix that corresponds to
  169. // the pixel at (x, y).
  170. func (p *RGBA64) PixOffset(x, y int) int {
  171. return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*8
  172. }
  173. func (p *RGBA64) Set(x, y int, c color.Color) {
  174. if !(Point{x, y}.In(p.Rect)) {
  175. return
  176. }
  177. i := p.PixOffset(x, y)
  178. c1 := color.RGBA64Model.Convert(c).(color.RGBA64)
  179. p.Pix[i+0] = uint8(c1.R >> 8)
  180. p.Pix[i+1] = uint8(c1.R)
  181. p.Pix[i+2] = uint8(c1.G >> 8)
  182. p.Pix[i+3] = uint8(c1.G)
  183. p.Pix[i+4] = uint8(c1.B >> 8)
  184. p.Pix[i+5] = uint8(c1.B)
  185. p.Pix[i+6] = uint8(c1.A >> 8)
  186. p.Pix[i+7] = uint8(c1.A)
  187. }
  188. func (p *RGBA64) SetRGBA64(x, y int, c color.RGBA64) {
  189. if !(Point{x, y}.In(p.Rect)) {
  190. return
  191. }
  192. i := p.PixOffset(x, y)
  193. p.Pix[i+0] = uint8(c.R >> 8)
  194. p.Pix[i+1] = uint8(c.R)
  195. p.Pix[i+2] = uint8(c.G >> 8)
  196. p.Pix[i+3] = uint8(c.G)
  197. p.Pix[i+4] = uint8(c.B >> 8)
  198. p.Pix[i+5] = uint8(c.B)
  199. p.Pix[i+6] = uint8(c.A >> 8)
  200. p.Pix[i+7] = uint8(c.A)
  201. }
  202. // SubImage returns an image representing the portion of the image p visible
  203. // through r. The returned value shares pixels with the original image.
  204. func (p *RGBA64) SubImage(r Rectangle) Image {
  205. r = r.Intersect(p.Rect)
  206. // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
  207. // either r1 or r2 if the intersection is empty. Without explicitly checking for
  208. // this, the Pix[i:] expression below can panic.
  209. if r.Empty() {
  210. return &RGBA64{}
  211. }
  212. i := p.PixOffset(r.Min.X, r.Min.Y)
  213. return &RGBA64{
  214. Pix: p.Pix[i:],
  215. Stride: p.Stride,
  216. Rect: r,
  217. }
  218. }
  219. // Opaque scans the entire image and reports whether it is fully opaque.
  220. func (p *RGBA64) Opaque() bool {
  221. if p.Rect.Empty() {
  222. return true
  223. }
  224. i0, i1 := 6, p.Rect.Dx()*8
  225. for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
  226. for i := i0; i < i1; i += 8 {
  227. if p.Pix[i+0] != 0xff || p.Pix[i+1] != 0xff {
  228. return false
  229. }
  230. }
  231. i0 += p.Stride
  232. i1 += p.Stride
  233. }
  234. return true
  235. }
  236. // NewRGBA64 returns a new RGBA64 with the given bounds.
  237. func NewRGBA64(r Rectangle) *RGBA64 {
  238. w, h := r.Dx(), r.Dy()
  239. pix := make([]uint8, 8*w*h)
  240. return &RGBA64{pix, 8 * w, r}
  241. }
  242. // NRGBA is an in-memory image whose At method returns color.NRGBA values.
  243. type NRGBA struct {
  244. // Pix holds the image's pixels, in R, G, B, A order. The pixel at
  245. // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4].
  246. Pix []uint8
  247. // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
  248. Stride int
  249. // Rect is the image's bounds.
  250. Rect Rectangle
  251. }
  252. func (p *NRGBA) ColorModel() color.Model { return color.NRGBAModel }
  253. func (p *NRGBA) Bounds() Rectangle { return p.Rect }
  254. func (p *NRGBA) At(x, y int) color.Color {
  255. return p.NRGBAAt(x, y)
  256. }
  257. func (p *NRGBA) NRGBAAt(x, y int) color.NRGBA {
  258. if !(Point{x, y}.In(p.Rect)) {
  259. return color.NRGBA{}
  260. }
  261. i := p.PixOffset(x, y)
  262. return color.NRGBA{p.Pix[i+0], p.Pix[i+1], p.Pix[i+2], p.Pix[i+3]}
  263. }
  264. // PixOffset returns the index of the first element of Pix that corresponds to
  265. // the pixel at (x, y).
  266. func (p *NRGBA) PixOffset(x, y int) int {
  267. return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*4
  268. }
  269. func (p *NRGBA) Set(x, y int, c color.Color) {
  270. if !(Point{x, y}.In(p.Rect)) {
  271. return
  272. }
  273. i := p.PixOffset(x, y)
  274. c1 := color.NRGBAModel.Convert(c).(color.NRGBA)
  275. p.Pix[i+0] = c1.R
  276. p.Pix[i+1] = c1.G
  277. p.Pix[i+2] = c1.B
  278. p.Pix[i+3] = c1.A
  279. }
  280. func (p *NRGBA) SetNRGBA(x, y int, c color.NRGBA) {
  281. if !(Point{x, y}.In(p.Rect)) {
  282. return
  283. }
  284. i := p.PixOffset(x, y)
  285. p.Pix[i+0] = c.R
  286. p.Pix[i+1] = c.G
  287. p.Pix[i+2] = c.B
  288. p.Pix[i+3] = c.A
  289. }
  290. // SubImage returns an image representing the portion of the image p visible
  291. // through r. The returned value shares pixels with the original image.
  292. func (p *NRGBA) SubImage(r Rectangle) Image {
  293. r = r.Intersect(p.Rect)
  294. // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
  295. // either r1 or r2 if the intersection is empty. Without explicitly checking for
  296. // this, the Pix[i:] expression below can panic.
  297. if r.Empty() {
  298. return &NRGBA{}
  299. }
  300. i := p.PixOffset(r.Min.X, r.Min.Y)
  301. return &NRGBA{
  302. Pix: p.Pix[i:],
  303. Stride: p.Stride,
  304. Rect: r,
  305. }
  306. }
  307. // Opaque scans the entire image and reports whether it is fully opaque.
  308. func (p *NRGBA) Opaque() bool {
  309. if p.Rect.Empty() {
  310. return true
  311. }
  312. i0, i1 := 3, p.Rect.Dx()*4
  313. for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
  314. for i := i0; i < i1; i += 4 {
  315. if p.Pix[i] != 0xff {
  316. return false
  317. }
  318. }
  319. i0 += p.Stride
  320. i1 += p.Stride
  321. }
  322. return true
  323. }
  324. // NewNRGBA returns a new NRGBA with the given bounds.
  325. func NewNRGBA(r Rectangle) *NRGBA {
  326. w, h := r.Dx(), r.Dy()
  327. pix := make([]uint8, 4*w*h)
  328. return &NRGBA{pix, 4 * w, r}
  329. }
  330. // NRGBA64 is an in-memory image whose At method returns color.NRGBA64 values.
  331. type NRGBA64 struct {
  332. // Pix holds the image's pixels, in R, G, B, A order and big-endian format. The pixel at
  333. // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*8].
  334. Pix []uint8
  335. // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
  336. Stride int
  337. // Rect is the image's bounds.
  338. Rect Rectangle
  339. }
  340. func (p *NRGBA64) ColorModel() color.Model { return color.NRGBA64Model }
  341. func (p *NRGBA64) Bounds() Rectangle { return p.Rect }
  342. func (p *NRGBA64) At(x, y int) color.Color {
  343. return p.NRGBA64At(x, y)
  344. }
  345. func (p *NRGBA64) NRGBA64At(x, y int) color.NRGBA64 {
  346. if !(Point{x, y}.In(p.Rect)) {
  347. return color.NRGBA64{}
  348. }
  349. i := p.PixOffset(x, y)
  350. return color.NRGBA64{
  351. uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1]),
  352. uint16(p.Pix[i+2])<<8 | uint16(p.Pix[i+3]),
  353. uint16(p.Pix[i+4])<<8 | uint16(p.Pix[i+5]),
  354. uint16(p.Pix[i+6])<<8 | uint16(p.Pix[i+7]),
  355. }
  356. }
  357. // PixOffset returns the index of the first element of Pix that corresponds to
  358. // the pixel at (x, y).
  359. func (p *NRGBA64) PixOffset(x, y int) int {
  360. return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*8
  361. }
  362. func (p *NRGBA64) Set(x, y int, c color.Color) {
  363. if !(Point{x, y}.In(p.Rect)) {
  364. return
  365. }
  366. i := p.PixOffset(x, y)
  367. c1 := color.NRGBA64Model.Convert(c).(color.NRGBA64)
  368. p.Pix[i+0] = uint8(c1.R >> 8)
  369. p.Pix[i+1] = uint8(c1.R)
  370. p.Pix[i+2] = uint8(c1.G >> 8)
  371. p.Pix[i+3] = uint8(c1.G)
  372. p.Pix[i+4] = uint8(c1.B >> 8)
  373. p.Pix[i+5] = uint8(c1.B)
  374. p.Pix[i+6] = uint8(c1.A >> 8)
  375. p.Pix[i+7] = uint8(c1.A)
  376. }
  377. func (p *NRGBA64) SetNRGBA64(x, y int, c color.NRGBA64) {
  378. if !(Point{x, y}.In(p.Rect)) {
  379. return
  380. }
  381. i := p.PixOffset(x, y)
  382. p.Pix[i+0] = uint8(c.R >> 8)
  383. p.Pix[i+1] = uint8(c.R)
  384. p.Pix[i+2] = uint8(c.G >> 8)
  385. p.Pix[i+3] = uint8(c.G)
  386. p.Pix[i+4] = uint8(c.B >> 8)
  387. p.Pix[i+5] = uint8(c.B)
  388. p.Pix[i+6] = uint8(c.A >> 8)
  389. p.Pix[i+7] = uint8(c.A)
  390. }
  391. // SubImage returns an image representing the portion of the image p visible
  392. // through r. The returned value shares pixels with the original image.
  393. func (p *NRGBA64) SubImage(r Rectangle) Image {
  394. r = r.Intersect(p.Rect)
  395. // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
  396. // either r1 or r2 if the intersection is empty. Without explicitly checking for
  397. // this, the Pix[i:] expression below can panic.
  398. if r.Empty() {
  399. return &NRGBA64{}
  400. }
  401. i := p.PixOffset(r.Min.X, r.Min.Y)
  402. return &NRGBA64{
  403. Pix: p.Pix[i:],
  404. Stride: p.Stride,
  405. Rect: r,
  406. }
  407. }
  408. // Opaque scans the entire image and reports whether it is fully opaque.
  409. func (p *NRGBA64) Opaque() bool {
  410. if p.Rect.Empty() {
  411. return true
  412. }
  413. i0, i1 := 6, p.Rect.Dx()*8
  414. for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
  415. for i := i0; i < i1; i += 8 {
  416. if p.Pix[i+0] != 0xff || p.Pix[i+1] != 0xff {
  417. return false
  418. }
  419. }
  420. i0 += p.Stride
  421. i1 += p.Stride
  422. }
  423. return true
  424. }
  425. // NewNRGBA64 returns a new NRGBA64 with the given bounds.
  426. func NewNRGBA64(r Rectangle) *NRGBA64 {
  427. w, h := r.Dx(), r.Dy()
  428. pix := make([]uint8, 8*w*h)
  429. return &NRGBA64{pix, 8 * w, r}
  430. }
  431. // Alpha is an in-memory image whose At method returns color.Alpha values.
  432. type Alpha struct {
  433. // Pix holds the image's pixels, as alpha values. The pixel at
  434. // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
  435. Pix []uint8
  436. // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
  437. Stride int
  438. // Rect is the image's bounds.
  439. Rect Rectangle
  440. }
  441. func (p *Alpha) ColorModel() color.Model { return color.AlphaModel }
  442. func (p *Alpha) Bounds() Rectangle { return p.Rect }
  443. func (p *Alpha) At(x, y int) color.Color {
  444. return p.AlphaAt(x, y)
  445. }
  446. func (p *Alpha) AlphaAt(x, y int) color.Alpha {
  447. if !(Point{x, y}.In(p.Rect)) {
  448. return color.Alpha{}
  449. }
  450. i := p.PixOffset(x, y)
  451. return color.Alpha{p.Pix[i]}
  452. }
  453. // PixOffset returns the index of the first element of Pix that corresponds to
  454. // the pixel at (x, y).
  455. func (p *Alpha) PixOffset(x, y int) int {
  456. return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
  457. }
  458. func (p *Alpha) Set(x, y int, c color.Color) {
  459. if !(Point{x, y}.In(p.Rect)) {
  460. return
  461. }
  462. i := p.PixOffset(x, y)
  463. p.Pix[i] = color.AlphaModel.Convert(c).(color.Alpha).A
  464. }
  465. func (p *Alpha) SetAlpha(x, y int, c color.Alpha) {
  466. if !(Point{x, y}.In(p.Rect)) {
  467. return
  468. }
  469. i := p.PixOffset(x, y)
  470. p.Pix[i] = c.A
  471. }
  472. // SubImage returns an image representing the portion of the image p visible
  473. // through r. The returned value shares pixels with the original image.
  474. func (p *Alpha) SubImage(r Rectangle) Image {
  475. r = r.Intersect(p.Rect)
  476. // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
  477. // either r1 or r2 if the intersection is empty. Without explicitly checking for
  478. // this, the Pix[i:] expression below can panic.
  479. if r.Empty() {
  480. return &Alpha{}
  481. }
  482. i := p.PixOffset(r.Min.X, r.Min.Y)
  483. return &Alpha{
  484. Pix: p.Pix[i:],
  485. Stride: p.Stride,
  486. Rect: r,
  487. }
  488. }
  489. // Opaque scans the entire image and reports whether it is fully opaque.
  490. func (p *Alpha) Opaque() bool {
  491. if p.Rect.Empty() {
  492. return true
  493. }
  494. i0, i1 := 0, p.Rect.Dx()
  495. for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
  496. for i := i0; i < i1; i++ {
  497. if p.Pix[i] != 0xff {
  498. return false
  499. }
  500. }
  501. i0 += p.Stride
  502. i1 += p.Stride
  503. }
  504. return true
  505. }
  506. // NewAlpha returns a new Alpha with the given bounds.
  507. func NewAlpha(r Rectangle) *Alpha {
  508. w, h := r.Dx(), r.Dy()
  509. pix := make([]uint8, 1*w*h)
  510. return &Alpha{pix, 1 * w, r}
  511. }
  512. // Alpha16 is an in-memory image whose At method returns color.Alpha64 values.
  513. type Alpha16 struct {
  514. // Pix holds the image's pixels, as alpha values in big-endian format. The pixel at
  515. // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*2].
  516. Pix []uint8
  517. // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
  518. Stride int
  519. // Rect is the image's bounds.
  520. Rect Rectangle
  521. }
  522. func (p *Alpha16) ColorModel() color.Model { return color.Alpha16Model }
  523. func (p *Alpha16) Bounds() Rectangle { return p.Rect }
  524. func (p *Alpha16) At(x, y int) color.Color {
  525. return p.Alpha16At(x, y)
  526. }
  527. func (p *Alpha16) Alpha16At(x, y int) color.Alpha16 {
  528. if !(Point{x, y}.In(p.Rect)) {
  529. return color.Alpha16{}
  530. }
  531. i := p.PixOffset(x, y)
  532. return color.Alpha16{uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1])}
  533. }
  534. // PixOffset returns the index of the first element of Pix that corresponds to
  535. // the pixel at (x, y).
  536. func (p *Alpha16) PixOffset(x, y int) int {
  537. return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*2
  538. }
  539. func (p *Alpha16) Set(x, y int, c color.Color) {
  540. if !(Point{x, y}.In(p.Rect)) {
  541. return
  542. }
  543. i := p.PixOffset(x, y)
  544. c1 := color.Alpha16Model.Convert(c).(color.Alpha16)
  545. p.Pix[i+0] = uint8(c1.A >> 8)
  546. p.Pix[i+1] = uint8(c1.A)
  547. }
  548. func (p *Alpha16) SetAlpha16(x, y int, c color.Alpha16) {
  549. if !(Point{x, y}.In(p.Rect)) {
  550. return
  551. }
  552. i := p.PixOffset(x, y)
  553. p.Pix[i+0] = uint8(c.A >> 8)
  554. p.Pix[i+1] = uint8(c.A)
  555. }
  556. // SubImage returns an image representing the portion of the image p visible
  557. // through r. The returned value shares pixels with the original image.
  558. func (p *Alpha16) SubImage(r Rectangle) Image {
  559. r = r.Intersect(p.Rect)
  560. // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
  561. // either r1 or r2 if the intersection is empty. Without explicitly checking for
  562. // this, the Pix[i:] expression below can panic.
  563. if r.Empty() {
  564. return &Alpha16{}
  565. }
  566. i := p.PixOffset(r.Min.X, r.Min.Y)
  567. return &Alpha16{
  568. Pix: p.Pix[i:],
  569. Stride: p.Stride,
  570. Rect: r,
  571. }
  572. }
  573. // Opaque scans the entire image and reports whether it is fully opaque.
  574. func (p *Alpha16) Opaque() bool {
  575. if p.Rect.Empty() {
  576. return true
  577. }
  578. i0, i1 := 0, p.Rect.Dx()*2
  579. for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
  580. for i := i0; i < i1; i += 2 {
  581. if p.Pix[i+0] != 0xff || p.Pix[i+1] != 0xff {
  582. return false
  583. }
  584. }
  585. i0 += p.Stride
  586. i1 += p.Stride
  587. }
  588. return true
  589. }
  590. // NewAlpha16 returns a new Alpha16 with the given bounds.
  591. func NewAlpha16(r Rectangle) *Alpha16 {
  592. w, h := r.Dx(), r.Dy()
  593. pix := make([]uint8, 2*w*h)
  594. return &Alpha16{pix, 2 * w, r}
  595. }
  596. // Gray is an in-memory image whose At method returns color.Gray values.
  597. type Gray struct {
  598. // Pix holds the image's pixels, as gray values. The pixel at
  599. // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
  600. Pix []uint8
  601. // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
  602. Stride int
  603. // Rect is the image's bounds.
  604. Rect Rectangle
  605. }
  606. func (p *Gray) ColorModel() color.Model { return color.GrayModel }
  607. func (p *Gray) Bounds() Rectangle { return p.Rect }
  608. func (p *Gray) At(x, y int) color.Color {
  609. return p.GrayAt(x, y)
  610. }
  611. func (p *Gray) GrayAt(x, y int) color.Gray {
  612. if !(Point{x, y}.In(p.Rect)) {
  613. return color.Gray{}
  614. }
  615. i := p.PixOffset(x, y)
  616. return color.Gray{p.Pix[i]}
  617. }
  618. // PixOffset returns the index of the first element of Pix that corresponds to
  619. // the pixel at (x, y).
  620. func (p *Gray) PixOffset(x, y int) int {
  621. return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
  622. }
  623. func (p *Gray) Set(x, y int, c color.Color) {
  624. if !(Point{x, y}.In(p.Rect)) {
  625. return
  626. }
  627. i := p.PixOffset(x, y)
  628. p.Pix[i] = color.GrayModel.Convert(c).(color.Gray).Y
  629. }
  630. func (p *Gray) SetGray(x, y int, c color.Gray) {
  631. if !(Point{x, y}.In(p.Rect)) {
  632. return
  633. }
  634. i := p.PixOffset(x, y)
  635. p.Pix[i] = c.Y
  636. }
  637. // SubImage returns an image representing the portion of the image p visible
  638. // through r. The returned value shares pixels with the original image.
  639. func (p *Gray) SubImage(r Rectangle) Image {
  640. r = r.Intersect(p.Rect)
  641. // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
  642. // either r1 or r2 if the intersection is empty. Without explicitly checking for
  643. // this, the Pix[i:] expression below can panic.
  644. if r.Empty() {
  645. return &Gray{}
  646. }
  647. i := p.PixOffset(r.Min.X, r.Min.Y)
  648. return &Gray{
  649. Pix: p.Pix[i:],
  650. Stride: p.Stride,
  651. Rect: r,
  652. }
  653. }
  654. // Opaque scans the entire image and reports whether it is fully opaque.
  655. func (p *Gray) Opaque() bool {
  656. return true
  657. }
  658. // NewGray returns a new Gray with the given bounds.
  659. func NewGray(r Rectangle) *Gray {
  660. w, h := r.Dx(), r.Dy()
  661. pix := make([]uint8, 1*w*h)
  662. return &Gray{pix, 1 * w, r}
  663. }
  664. // Gray16 is an in-memory image whose At method returns color.Gray16 values.
  665. type Gray16 struct {
  666. // Pix holds the image's pixels, as gray values in big-endian format. The pixel at
  667. // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*2].
  668. Pix []uint8
  669. // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
  670. Stride int
  671. // Rect is the image's bounds.
  672. Rect Rectangle
  673. }
  674. func (p *Gray16) ColorModel() color.Model { return color.Gray16Model }
  675. func (p *Gray16) Bounds() Rectangle { return p.Rect }
  676. func (p *Gray16) At(x, y int) color.Color {
  677. return p.Gray16At(x, y)
  678. }
  679. func (p *Gray16) Gray16At(x, y int) color.Gray16 {
  680. if !(Point{x, y}.In(p.Rect)) {
  681. return color.Gray16{}
  682. }
  683. i := p.PixOffset(x, y)
  684. return color.Gray16{uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1])}
  685. }
  686. // PixOffset returns the index of the first element of Pix that corresponds to
  687. // the pixel at (x, y).
  688. func (p *Gray16) PixOffset(x, y int) int {
  689. return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*2
  690. }
  691. func (p *Gray16) Set(x, y int, c color.Color) {
  692. if !(Point{x, y}.In(p.Rect)) {
  693. return
  694. }
  695. i := p.PixOffset(x, y)
  696. c1 := color.Gray16Model.Convert(c).(color.Gray16)
  697. p.Pix[i+0] = uint8(c1.Y >> 8)
  698. p.Pix[i+1] = uint8(c1.Y)
  699. }
  700. func (p *Gray16) SetGray16(x, y int, c color.Gray16) {
  701. if !(Point{x, y}.In(p.Rect)) {
  702. return
  703. }
  704. i := p.PixOffset(x, y)
  705. p.Pix[i+0] = uint8(c.Y >> 8)
  706. p.Pix[i+1] = uint8(c.Y)
  707. }
  708. // SubImage returns an image representing the portion of the image p visible
  709. // through r. The returned value shares pixels with the original image.
  710. func (p *Gray16) SubImage(r Rectangle) Image {
  711. r = r.Intersect(p.Rect)
  712. // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
  713. // either r1 or r2 if the intersection is empty. Without explicitly checking for
  714. // this, the Pix[i:] expression below can panic.
  715. if r.Empty() {
  716. return &Gray16{}
  717. }
  718. i := p.PixOffset(r.Min.X, r.Min.Y)
  719. return &Gray16{
  720. Pix: p.Pix[i:],
  721. Stride: p.Stride,
  722. Rect: r,
  723. }
  724. }
  725. // Opaque scans the entire image and reports whether it is fully opaque.
  726. func (p *Gray16) Opaque() bool {
  727. return true
  728. }
  729. // NewGray16 returns a new Gray16 with the given bounds.
  730. func NewGray16(r Rectangle) *Gray16 {
  731. w, h := r.Dx(), r.Dy()
  732. pix := make([]uint8, 2*w*h)
  733. return &Gray16{pix, 2 * w, r}
  734. }
  735. // Paletted is an in-memory image of uint8 indices into a given palette.
  736. type Paletted struct {
  737. // Pix holds the image's pixels, as palette indices. The pixel at
  738. // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
  739. Pix []uint8
  740. // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
  741. Stride int
  742. // Rect is the image's bounds.
  743. Rect Rectangle
  744. // Palette is the image's palette.
  745. Palette color.Palette
  746. }
  747. func (p *Paletted) ColorModel() color.Model { return p.Palette }
  748. func (p *Paletted) Bounds() Rectangle { return p.Rect }
  749. func (p *Paletted) At(x, y int) color.Color {
  750. if len(p.Palette) == 0 {
  751. return nil
  752. }
  753. if !(Point{x, y}.In(p.Rect)) {
  754. return p.Palette[0]
  755. }
  756. i := p.PixOffset(x, y)
  757. return p.Palette[p.Pix[i]]
  758. }
  759. // PixOffset returns the index of the first element of Pix that corresponds to
  760. // the pixel at (x, y).
  761. func (p *Paletted) PixOffset(x, y int) int {
  762. return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
  763. }
  764. func (p *Paletted) Set(x, y int, c color.Color) {
  765. if !(Point{x, y}.In(p.Rect)) {
  766. return
  767. }
  768. i := p.PixOffset(x, y)
  769. p.Pix[i] = uint8(p.Palette.Index(c))
  770. }
  771. func (p *Paletted) ColorIndexAt(x, y int) uint8 {
  772. if !(Point{x, y}.In(p.Rect)) {
  773. return 0
  774. }
  775. i := p.PixOffset(x, y)
  776. return p.Pix[i]
  777. }
  778. func (p *Paletted) SetColorIndex(x, y int, index uint8) {
  779. if !(Point{x, y}.In(p.Rect)) {
  780. return
  781. }
  782. i := p.PixOffset(x, y)
  783. p.Pix[i] = index
  784. }
  785. // SubImage returns an image representing the portion of the image p visible
  786. // through r. The returned value shares pixels with the original image.
  787. func (p *Paletted) SubImage(r Rectangle) Image {
  788. r = r.Intersect(p.Rect)
  789. // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
  790. // either r1 or r2 if the intersection is empty. Without explicitly checking for
  791. // this, the Pix[i:] expression below can panic.
  792. if r.Empty() {
  793. return &Paletted{
  794. Palette: p.Palette,
  795. }
  796. }
  797. i := p.PixOffset(r.Min.X, r.Min.Y)
  798. return &Paletted{
  799. Pix: p.Pix[i:],
  800. Stride: p.Stride,
  801. Rect: p.Rect.Intersect(r),
  802. Palette: p.Palette,
  803. }
  804. }
  805. // Opaque scans the entire image and reports whether it is fully opaque.
  806. func (p *Paletted) Opaque() bool {
  807. var present [256]bool
  808. i0, i1 := 0, p.Rect.Dx()
  809. for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
  810. for _, c := range p.Pix[i0:i1] {
  811. present[c] = true
  812. }
  813. i0 += p.Stride
  814. i1 += p.Stride
  815. }
  816. for i, c := range p.Palette {
  817. if !present[i] {
  818. continue
  819. }
  820. _, _, _, a := c.RGBA()
  821. if a != 0xffff {
  822. return false
  823. }
  824. }
  825. return true
  826. }
  827. // NewPaletted returns a new Paletted with the given width, height and palette.
  828. func NewPaletted(r Rectangle, p color.Palette) *Paletted {
  829. w, h := r.Dx(), r.Dy()
  830. pix := make([]uint8, 1*w*h)
  831. return &Paletted{pix, 1 * w, r, p}
  832. }