1package psd 2 3import ( 4 "image" 5 "image/color" 6 7 psdColor "github.com/oov/psd/color" 8) 9 10type picker interface { 11 image.Image 12 setSource(rect image.Rectangle, src ...[]byte) 13} 14 15func findPicker(depth int, colorMode ColorMode, hasAlpha bool) picker { 16 switch colorMode { 17 case ColorModeBitmap, ColorModeGrayscale: 18 return findNGrayPicker(depth, hasAlpha) 19 case ColorModeRGB: 20 return findNRGBAPicker(depth, hasAlpha) 21 case ColorModeCMYK: 22 return findNCMYKAPicker(depth, hasAlpha) 23 } 24 return nil 25} 26 27func findGrayPicker(depth int) picker { 28 switch depth { 29 case 1: 30 return &pickerGray1{} 31 case 8: 32 return &pickerGray8{} 33 case 16: 34 return &pickerGray16{} 35 case 32: 36 return &pickerGray32{} 37 } 38 return nil 39} 40 41func findNGrayPicker(depth int, hasAlpha bool) picker { 42 switch depth { 43 case 8: 44 if hasAlpha { 45 return &pickerNGrayA8{} 46 } 47 return &pickerNGray8{} 48 case 16: 49 if hasAlpha { 50 return &pickerNGrayA16{} 51 } 52 return &pickerNGray16{} 53 case 32: 54 if hasAlpha { 55 return &pickerNGrayA32{} 56 } 57 return &pickerNGray32{} 58 } 59 return nil 60} 61 62func findNRGBAPicker(depth int, hasAlpha bool) picker { 63 switch depth { 64 case 8: 65 if hasAlpha { 66 return &pickerNRGBA8{} 67 } 68 return &pickerNRGB8{} 69 case 16: 70 if hasAlpha { 71 return &pickerNRGBA16{} 72 } 73 return &pickerNRGB16{} 74 case 32: 75 if hasAlpha { 76 return &pickerNRGBA32{} 77 } 78 return &pickerNRGB32{} 79 } 80 return nil 81} 82 83func findNCMYKAPicker(depth int, hasAlpha bool) picker { 84 switch depth { 85 case 8: 86 if hasAlpha { 87 return &pickerNCMYKA8{} 88 } 89 return &pickerNCMYK8{} 90 case 16: 91 if hasAlpha { 92 return &pickerNCMYKA16{} 93 } 94 return &pickerNCMYK16{} 95 } 96 return nil 97} 98 99type pickerPalette struct { 100 Rect image.Rectangle 101 Src []byte 102 Palette color.Palette 103} 104 105func (p *pickerPalette) setSource(rect image.Rectangle, src ...[]byte) { p.Rect, p.Src = rect, src[0] } 106func (p *pickerPalette) ColorModel() color.Model { return p.Palette } 107func (p *pickerPalette) Bounds() image.Rectangle { return p.Rect } 108func (p *pickerPalette) At(x, y int) color.Color { 109 pos := (y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X 110 return p.Palette[p.Src[pos]] 111} 112 113type pickerGray1 struct { 114 Rect image.Rectangle 115 Y []byte 116} 117 118func (p *pickerGray1) setSource(rect image.Rectangle, src ...[]byte) { p.Rect, p.Y = rect, src[0] } 119func (p *pickerGray1) ColorModel() color.Model { return psdColor.Gray1Model } 120func (p *pickerGray1) Bounds() image.Rectangle { return p.Rect } 121func (p *pickerGray1) At(x, y int) color.Color { 122 xx := x - p.Rect.Min.X 123 pos := (p.Rect.Dx()+7)>>3*(y-p.Rect.Min.Y) + xx>>3 124 return psdColor.Gray1{Y: p.Y[pos]&(1<<uint(^xx&7)) == 0} 125} 126 127type pickerGray8 struct { 128 Rect image.Rectangle 129 Y []byte 130} 131 132func (p *pickerGray8) setSource(rect image.Rectangle, src ...[]byte) { p.Rect, p.Y = rect, src[0] } 133func (p *pickerGray8) ColorModel() color.Model { return color.GrayModel } 134func (p *pickerGray8) Bounds() image.Rectangle { return p.Rect } 135func (p *pickerGray8) At(x, y int) color.Color { 136 pos := (y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X 137 return color.Gray{Y: p.Y[pos]} 138} 139 140type pickerNGray8 struct { 141 Rect image.Rectangle 142 Y []byte 143} 144 145func (p *pickerNGray8) setSource(rect image.Rectangle, src ...[]byte) { 146 p.Rect, p.Y = rect, src[0] 147} 148func (p *pickerNGray8) ColorModel() color.Model { return psdColor.NGrayAModel } 149func (p *pickerNGray8) Bounds() image.Rectangle { return p.Rect } 150func (p *pickerNGray8) At(x, y int) color.Color { 151 pos := (y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X 152 return psdColor.NGrayA{Y: p.Y[pos], A: 0xff} 153} 154 155type pickerNGrayA8 struct { 156 Rect image.Rectangle 157 Y, A []byte 158} 159 160func (p *pickerNGrayA8) setSource(rect image.Rectangle, src ...[]byte) { 161 p.Rect, p.Y, p.A = rect, src[0], src[1] 162} 163func (p *pickerNGrayA8) ColorModel() color.Model { return psdColor.NGrayAModel } 164func (p *pickerNGrayA8) Bounds() image.Rectangle { return p.Rect } 165func (p *pickerNGrayA8) At(x, y int) color.Color { 166 pos := (y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X 167 return psdColor.NGrayA{Y: p.Y[pos], A: p.A[pos]} 168} 169 170type pickerGray16 struct { 171 Rect image.Rectangle 172 Y []byte 173} 174 175func (p *pickerGray16) setSource(rect image.Rectangle, src ...[]byte) { p.Rect, p.Y = rect, src[0] } 176func (p *pickerGray16) ColorModel() color.Model { return color.Gray16Model } 177func (p *pickerGray16) Bounds() image.Rectangle { return p.Rect } 178func (p *pickerGray16) At(x, y int) color.Color { 179 pos := ((y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X) << 1 180 return color.Gray16{Y: readUint16(p.Y, pos)} 181} 182 183type pickerNGray16 struct { 184 Rect image.Rectangle 185 Y []byte 186} 187 188func (p *pickerNGray16) setSource(rect image.Rectangle, src ...[]byte) { 189 p.Rect, p.Y = rect, src[0] 190} 191func (p *pickerNGray16) ColorModel() color.Model { return psdColor.NGrayA32Model } 192func (p *pickerNGray16) Bounds() image.Rectangle { return p.Rect } 193func (p *pickerNGray16) At(x, y int) color.Color { 194 pos := ((y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X) << 1 195 return psdColor.NGrayA32{Y: readUint16(p.Y, pos), A: 0xffff} 196} 197 198type pickerNGrayA16 struct { 199 Rect image.Rectangle 200 Y, A []byte 201} 202 203func (p *pickerNGrayA16) setSource(rect image.Rectangle, src ...[]byte) { 204 p.Rect, p.Y, p.A = rect, src[0], src[1] 205} 206func (p *pickerNGrayA16) ColorModel() color.Model { return psdColor.NGrayA32Model } 207func (p *pickerNGrayA16) Bounds() image.Rectangle { return p.Rect } 208func (p *pickerNGrayA16) At(x, y int) color.Color { 209 pos := ((y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X) << 1 210 return psdColor.NGrayA32{Y: readUint16(p.Y, pos), A: readUint16(p.A, pos)} 211} 212 213type pickerGray32 struct { 214 Rect image.Rectangle 215 Y []byte 216} 217 218func (p *pickerGray32) setSource(rect image.Rectangle, src ...[]byte) { p.Rect, p.Y = rect, src[0] } 219func (p *pickerGray32) ColorModel() color.Model { return psdColor.Gray32Model } 220func (p *pickerGray32) Bounds() image.Rectangle { return p.Rect } 221func (p *pickerGray32) At(x, y int) color.Color { 222 pos := ((y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X) << 2 223 return psdColor.Gray32{Y: readFloat32(p.Y, pos)} 224} 225 226type pickerNGray32 struct { 227 Rect image.Rectangle 228 Y []byte 229} 230 231func (p *pickerNGray32) setSource(rect image.Rectangle, src ...[]byte) { 232 p.Rect, p.Y = rect, src[0] 233} 234func (p *pickerNGray32) ColorModel() color.Model { return psdColor.NGrayA64Model } 235func (p *pickerNGray32) Bounds() image.Rectangle { return p.Rect } 236func (p *pickerNGray32) At(x, y int) color.Color { 237 pos := ((y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X) << 2 238 return psdColor.NGrayA64{Y: readFloat32(p.Y, pos), A: 1} 239} 240 241type pickerNGrayA32 struct { 242 Rect image.Rectangle 243 Y, A []byte 244} 245 246func (p *pickerNGrayA32) setSource(rect image.Rectangle, src ...[]byte) { 247 p.Rect, p.Y, p.A = rect, src[0], src[1] 248} 249func (p *pickerNGrayA32) ColorModel() color.Model { return psdColor.NGrayA64Model } 250func (p *pickerNGrayA32) Bounds() image.Rectangle { return p.Rect } 251func (p *pickerNGrayA32) At(x, y int) color.Color { 252 pos := ((y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X) << 2 253 return psdColor.NGrayA64{ 254 Y: readFloat32(p.Y, pos), 255 A: readFloat32(p.A, pos), 256 } 257} 258 259type pickerNRGB8 struct { 260 Rect image.Rectangle 261 R, G, B []byte 262} 263 264func (p *pickerNRGB8) setSource(rect image.Rectangle, src ...[]byte) { 265 p.Rect, p.R, p.G, p.B = rect, src[0], src[1], src[2] 266} 267func (p *pickerNRGB8) ColorModel() color.Model { return color.NRGBAModel } 268func (p *pickerNRGB8) Bounds() image.Rectangle { return p.Rect } 269func (p *pickerNRGB8) At(x, y int) color.Color { 270 pos := (y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X 271 return color.NRGBA{ 272 R: p.R[pos], 273 G: p.G[pos], 274 B: p.B[pos], 275 A: 0xff, 276 } 277} 278 279type pickerNRGBA8 struct { 280 Rect image.Rectangle 281 R, G, B, A []byte 282} 283 284func (p *pickerNRGBA8) setSource(rect image.Rectangle, src ...[]byte) { 285 p.Rect, p.R, p.G, p.B, p.A = rect, src[0], src[1], src[2], src[3] 286} 287func (p *pickerNRGBA8) ColorModel() color.Model { return color.NRGBAModel } 288func (p *pickerNRGBA8) Bounds() image.Rectangle { return p.Rect } 289func (p *pickerNRGBA8) At(x, y int) color.Color { 290 pos := (y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X 291 return color.NRGBA{p.R[pos], p.G[pos], p.B[pos], p.A[pos]} 292} 293 294type pickerNRGB16 struct { 295 Rect image.Rectangle 296 R, G, B []byte 297} 298 299func (p *pickerNRGB16) setSource(rect image.Rectangle, src ...[]byte) { 300 p.Rect, p.R, p.G, p.B = rect, src[0], src[1], src[2] 301} 302func (p *pickerNRGB16) ColorModel() color.Model { return color.NRGBA64Model } 303func (p *pickerNRGB16) Bounds() image.Rectangle { return p.Rect } 304func (p *pickerNRGB16) At(x, y int) color.Color { 305 pos := ((y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X) << 1 306 return color.NRGBA64{ 307 R: readUint16(p.R, pos), 308 G: readUint16(p.G, pos), 309 B: readUint16(p.B, pos), 310 A: 0xffff, 311 } 312} 313 314type pickerNRGBA16 struct { 315 Rect image.Rectangle 316 R, G, B, A []byte 317} 318 319func (p *pickerNRGBA16) setSource(rect image.Rectangle, src ...[]byte) { 320 p.Rect, p.R, p.G, p.B, p.A = rect, src[0], src[1], src[2], src[3] 321} 322func (p *pickerNRGBA16) ColorModel() color.Model { return color.NRGBA64Model } 323func (p *pickerNRGBA16) Bounds() image.Rectangle { return p.Rect } 324func (p *pickerNRGBA16) At(x, y int) color.Color { 325 pos := ((y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X) << 1 326 return color.NRGBA64{ 327 R: readUint16(p.R, pos), 328 G: readUint16(p.G, pos), 329 B: readUint16(p.B, pos), 330 A: readUint16(p.A, pos), 331 } 332} 333 334type pickerNRGB32 struct { 335 Rect image.Rectangle 336 R, G, B []byte 337} 338 339func (p *pickerNRGB32) setSource(rect image.Rectangle, src ...[]byte) { 340 p.Rect, p.R, p.G, p.B = rect, src[0], src[1], src[2] 341} 342func (p *pickerNRGB32) ColorModel() color.Model { return psdColor.NRGBA128Model } 343func (p *pickerNRGB32) Bounds() image.Rectangle { return p.Rect } 344func (p *pickerNRGB32) At(x, y int) color.Color { 345 pos := ((y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X) << 2 346 return psdColor.NRGBA128{ 347 R: readFloat32(p.R, pos), 348 G: readFloat32(p.G, pos), 349 B: readFloat32(p.B, pos), 350 A: 1.0, 351 } 352} 353 354type pickerNRGBA32 struct { 355 Rect image.Rectangle 356 R, G, B, A []byte 357} 358 359func (p *pickerNRGBA32) setSource(rect image.Rectangle, src ...[]byte) { 360 p.Rect, p.R, p.G, p.B, p.A = rect, src[0], src[1], src[2], src[3] 361} 362func (p *pickerNRGBA32) ColorModel() color.Model { return psdColor.NRGBA128Model } 363func (p *pickerNRGBA32) Bounds() image.Rectangle { return p.Rect } 364func (p *pickerNRGBA32) At(x, y int) color.Color { 365 pos := ((y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X) << 2 366 return psdColor.NRGBA128{ 367 R: readFloat32(p.R, pos), 368 G: readFloat32(p.G, pos), 369 B: readFloat32(p.B, pos), 370 A: readFloat32(p.A, pos), 371 } 372} 373 374type pickerNCMYK8 struct { 375 Rect image.Rectangle 376 C, M, Y, K []byte 377} 378 379func (p *pickerNCMYK8) setSource(rect image.Rectangle, src ...[]byte) { 380 p.Rect, p.C, p.M, p.Y, p.K = rect, src[0], src[1], src[2], src[3] 381} 382func (p *pickerNCMYK8) ColorModel() color.Model { return psdColor.NCMYKAModel } 383func (p *pickerNCMYK8) Bounds() image.Rectangle { return p.Rect } 384func (p *pickerNCMYK8) At(x, y int) color.Color { 385 pos := (y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X 386 return psdColor.NCMYKA{ 387 C: p.C[pos], 388 M: p.M[pos], 389 Y: p.Y[pos], 390 K: p.K[pos], 391 A: 0xff, 392 } 393} 394 395type pickerNCMYKA8 struct { 396 Rect image.Rectangle 397 C, M, Y, K, A []byte 398} 399 400func (p *pickerNCMYKA8) setSource(rect image.Rectangle, src ...[]byte) { 401 p.Rect, p.C, p.M, p.Y, p.K, p.A = rect, src[0], src[1], src[2], src[3], src[4] 402} 403func (p *pickerNCMYKA8) ColorModel() color.Model { return psdColor.NCMYKAModel } 404func (p *pickerNCMYKA8) Bounds() image.Rectangle { return p.Rect } 405func (p *pickerNCMYKA8) At(x, y int) color.Color { 406 pos := (y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X 407 return psdColor.NCMYKA{ 408 C: p.C[pos], 409 M: p.M[pos], 410 Y: p.Y[pos], 411 K: p.K[pos], 412 A: p.A[pos], 413 } 414} 415 416type pickerNCMYK16 struct { 417 Rect image.Rectangle 418 C, M, Y, K []byte 419} 420 421func (p *pickerNCMYK16) setSource(rect image.Rectangle, src ...[]byte) { 422 p.Rect, p.C, p.M, p.Y, p.K = rect, src[0], src[1], src[2], src[3] 423} 424func (p *pickerNCMYK16) ColorModel() color.Model { return psdColor.NCMYKA80Model } 425func (p *pickerNCMYK16) Bounds() image.Rectangle { return p.Rect } 426func (p *pickerNCMYK16) At(x, y int) color.Color { 427 pos := ((y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X) << 1 428 return psdColor.NCMYKA80{ 429 C: readUint16(p.C, pos), 430 M: readUint16(p.M, pos), 431 Y: readUint16(p.Y, pos), 432 K: readUint16(p.K, pos), 433 A: 0xffff, 434 } 435} 436 437type pickerNCMYKA16 struct { 438 Rect image.Rectangle 439 C, M, Y, K, A []byte 440} 441 442func (p *pickerNCMYKA16) setSource(rect image.Rectangle, src ...[]byte) { 443 p.Rect, p.C, p.M, p.Y, p.K, p.A = rect, src[0], src[1], src[2], src[3], src[4] 444} 445func (p *pickerNCMYKA16) ColorModel() color.Model { return psdColor.NCMYKA80Model } 446func (p *pickerNCMYKA16) Bounds() image.Rectangle { return p.Rect } 447func (p *pickerNCMYKA16) At(x, y int) color.Color { 448 pos := ((y-p.Rect.Min.Y)*p.Rect.Dx() + x - p.Rect.Min.X) << 1 449 return psdColor.NCMYKA80{ 450 C: readUint16(p.C, pos), 451 M: readUint16(p.M, pos), 452 Y: readUint16(p.Y, pos), 453 K: readUint16(p.K, pos), 454 A: readUint16(p.A, pos), 455 } 456} 457