mattermost-community-enterp.../vendor/github.com/anthonynsimon/bild/clone/clone.go
Claude ec1f89217a Merge: Complete Mattermost Server with Community Enterprise
Full Mattermost server source with integrated Community Enterprise features.
Includes vendor directory for offline/air-gapped builds.

Structure:
- enterprise-impl/: Enterprise feature implementations
- enterprise-community/: Init files that register implementations
- enterprise/: Bridge imports (community_imports.go)
- vendor/: All dependencies for offline builds

Build (online):
  go build ./cmd/mattermost

Build (offline/air-gapped):
  go build -mod=vendor ./cmd/mattermost

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 23:59:07 +09:00

158 lines
3.9 KiB
Go

/*Package clone provides image cloning function.*/
package clone
import (
"image"
"image/draw"
"github.com/anthonynsimon/bild/parallel"
)
// PadMethod is the method used to fill padded pixels.
type PadMethod uint8
const (
// NoFill leaves the padded pixels empty.
NoFill = iota
// EdgeExtend extends the closest edge pixel.
EdgeExtend
// EdgeWrap wraps around the pixels of an image.
EdgeWrap
)
// AsRGBA returns an RGBA copy of the supplied image.
func AsRGBA(src image.Image) *image.RGBA {
bounds := src.Bounds()
img := image.NewRGBA(bounds)
draw.Draw(img, bounds, src, bounds.Min, draw.Src)
return img
}
// AsShallowRGBA tries to cast to image.RGBA to get reference. Otherwise makes a copy
func AsShallowRGBA(src image.Image) *image.RGBA {
if rgba, ok := src.(*image.RGBA); ok {
return rgba
}
return AsRGBA(src)
}
// Pad returns an RGBA copy of the src image parameter with its edges padded
// using the supplied PadMethod.
// Parameter padX and padY correspond to the amount of padding to be applied
// on each side.
// Parameter m is the PadMethod to fill the new pixels.
//
// Usage example:
//
// result := Pad(img, 5,5, EdgeExtend)
func Pad(src image.Image, padX, padY int, m PadMethod) *image.RGBA {
var result *image.RGBA
switch m {
case EdgeExtend:
result = extend(src, padX, padY)
case NoFill:
result = noFill(src, padX, padY)
case EdgeWrap:
result = wrap(src, padX, padY)
default:
result = extend(src, padX, padY)
}
return result
}
func noFill(img image.Image, padX, padY int) *image.RGBA {
srcBounds := img.Bounds()
paddedW, paddedH := srcBounds.Dx()+2*padX, srcBounds.Dy()+2*padY
newBounds := image.Rect(0, 0, paddedW, paddedH)
fillBounds := image.Rect(padX, padY, padX+srcBounds.Dx(), padY+srcBounds.Dy())
dst := image.NewRGBA(newBounds)
draw.Draw(dst, fillBounds, img, srcBounds.Min, draw.Src)
return dst
}
func extend(img image.Image, padX, padY int) *image.RGBA {
dst := noFill(img, padX, padY)
paddedW, paddedH := dst.Bounds().Dx(), dst.Bounds().Dy()
parallel.Line(paddedH, func(start, end int) {
for y := start; y < end; y++ {
iy := y
if iy < padY {
iy = padY
} else if iy >= paddedH-padY {
iy = paddedH - padY - 1
}
for x := 0; x < paddedW; x++ {
ix := x
if ix < padX {
ix = padX
} else if x >= paddedW-padX {
ix = paddedW - padX - 1
} else if iy == y {
// This only enters if we are not in a y-padded area or
// x-padded area, so nothing to extend here.
// So simply jump to the next padded-x index.
x = paddedW - padX - 1
continue
}
dstPos := y*dst.Stride + x*4
edgePos := iy*dst.Stride + ix*4
dst.Pix[dstPos+0] = dst.Pix[edgePos+0]
dst.Pix[dstPos+1] = dst.Pix[edgePos+1]
dst.Pix[dstPos+2] = dst.Pix[edgePos+2]
dst.Pix[dstPos+3] = dst.Pix[edgePos+3]
}
}
})
return dst
}
func wrap(img image.Image, padX, padY int) *image.RGBA {
dst := noFill(img, padX, padY)
paddedW, paddedH := dst.Bounds().Dx(), dst.Bounds().Dy()
parallel.Line(paddedH, func(start, end int) {
for y := start; y < end; y++ {
iy := y
if iy < padY {
iy = (paddedH - padY) - ((padY - y) % (paddedH - padY*2))
} else if iy >= paddedH-padY {
iy = padY - ((padY - y) % (paddedH - padY*2))
}
for x := 0; x < paddedW; x++ {
ix := x
if ix < padX {
ix = (paddedW - padX) - ((padX - x) % (paddedW - padX*2))
} else if ix >= paddedW-padX {
ix = padX - ((padX - x) % (paddedW - padX*2))
} else if iy == y {
// This only enters if we are not in a y-padded area or
// x-padded area, so nothing to extend here.
// So simply jump to the next padded-x index.
x = paddedW - padX - 1
continue
}
dstPos := y*dst.Stride + x*4
edgePos := iy*dst.Stride + ix*4
dst.Pix[dstPos+0] = dst.Pix[edgePos+0]
dst.Pix[dstPos+1] = dst.Pix[edgePos+1]
dst.Pix[dstPos+2] = dst.Pix[edgePos+2]
dst.Pix[dstPos+3] = dst.Pix[edgePos+3]
}
}
})
return dst
}