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>
101 lines
2.5 KiB
Go
101 lines
2.5 KiB
Go
package psd
|
|
|
|
import (
|
|
"compress/zlib"
|
|
"errors"
|
|
"image"
|
|
"io"
|
|
)
|
|
|
|
// CompressionMethod represents compression method that is used in psd file.
|
|
type CompressionMethod int16
|
|
|
|
// These compression methods are defined in this document.
|
|
//
|
|
// http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577409_pgfId-1054855
|
|
const (
|
|
CompressionMethodRaw = CompressionMethod(0)
|
|
CompressionMethodRLE = CompressionMethod(1)
|
|
CompressionMethodZIPWithoutPrediction = CompressionMethod(2)
|
|
CompressionMethodZIPWithPrediction = CompressionMethod(3)
|
|
)
|
|
|
|
var (
|
|
errBrokenPackBits = errors.New("psd: compressed image data seems broken")
|
|
)
|
|
|
|
// Decode decodes the compressed image data from r.
|
|
//
|
|
// You can pass 0 to sizeHint if unknown, but in this case may read more data than necessary from r.
|
|
func (cm CompressionMethod) Decode(dest []byte, r io.Reader, sizeHint int64, rect image.Rectangle, depth int, channels int, large bool) (read int, err error) {
|
|
switch cm {
|
|
case CompressionMethodRaw:
|
|
return io.ReadFull(r, dest)
|
|
case CompressionMethodRLE:
|
|
var width int
|
|
if depth == 1 {
|
|
width = (rect.Dx() + 7) >> 3
|
|
} else {
|
|
width = rect.Dx()
|
|
}
|
|
return decodePackBits(dest, r, width, rect.Dy()*channels, large)
|
|
case CompressionMethodZIPWithoutPrediction:
|
|
return decodeZLIB(dest, r, sizeHint)
|
|
case CompressionMethodZIPWithPrediction:
|
|
if read, err = decodeZLIB(dest, r, sizeHint); err != nil {
|
|
return read, err
|
|
}
|
|
decodeDelta(dest, rect.Dx(), depth)
|
|
return read, err
|
|
}
|
|
return 0, errors.New("psd: compression method " + itoa(int(cm)) + " is not implemented")
|
|
}
|
|
|
|
// decodeZLIB decodes compressed data by zlib.
|
|
// You can pass 0 to length if unknown,
|
|
// but in that case may read more data than necessary from r.
|
|
func decodeZLIB(dest []byte, r io.Reader, length int64) (read int, err error) {
|
|
N := length
|
|
if N == 0 {
|
|
N = 0x7fffffffffffffff
|
|
}
|
|
lr := &io.LimitedReader{R: r, N: N}
|
|
zr, err := zlib.NewReader(lr)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if _, err = io.ReadFull(zr, dest); err != nil {
|
|
zr.Close()
|
|
return int(N - lr.N), err
|
|
}
|
|
if err = zr.Close(); err != nil {
|
|
return int(N - lr.N), err
|
|
}
|
|
return int(N - lr.N), nil
|
|
}
|
|
|
|
func decodeDelta(buf []byte, width int, depth int) {
|
|
switch depth {
|
|
case 16:
|
|
var d uint16
|
|
for i := 0; i < len(buf); {
|
|
d = 0
|
|
for j := 0; j < width; j++ {
|
|
d += readUint16(buf, i)
|
|
writeUint16(buf, d, i)
|
|
i += 2
|
|
}
|
|
}
|
|
case 32:
|
|
var d uint32
|
|
for i := 0; i < len(buf); {
|
|
d = 0
|
|
for j := 0; j < width; j++ {
|
|
d += readUint32(buf, i)
|
|
writeUint32(buf, d, i)
|
|
i += 4
|
|
}
|
|
}
|
|
}
|
|
}
|