aboutsummaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/image/bmp
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/image/bmp')
-rw-r--r--vendor/golang.org/x/image/bmp/reader.go30
-rw-r--r--vendor/golang.org/x/image/bmp/writer.go122
2 files changed, 131 insertions, 21 deletions
diff --git a/vendor/golang.org/x/image/bmp/reader.go b/vendor/golang.org/x/image/bmp/reader.go
index a0f2715..c10a022 100644
--- a/vendor/golang.org/x/image/bmp/reader.go
+++ b/vendor/golang.org/x/image/bmp/reader.go
@@ -137,20 +137,26 @@ func decodeConfig(r io.Reader) (config image.Config, bitsPerPixel int, topDown b
// We only support those BMP images that are a BITMAPFILEHEADER
// immediately followed by a BITMAPINFOHEADER.
const (
- fileHeaderLen = 14
- infoHeaderLen = 40
+ fileHeaderLen = 14
+ infoHeaderLen = 40
+ v4InfoHeaderLen = 108
+ v5InfoHeaderLen = 124
)
var b [1024]byte
- if _, err := io.ReadFull(r, b[:fileHeaderLen+infoHeaderLen]); err != nil {
+ if _, err := io.ReadFull(r, b[:fileHeaderLen+4]); err != nil {
return image.Config{}, 0, false, err
}
if string(b[:2]) != "BM" {
return image.Config{}, 0, false, errors.New("bmp: invalid format")
}
offset := readUint32(b[10:14])
- if readUint32(b[14:18]) != infoHeaderLen {
+ infoLen := readUint32(b[14:18])
+ if infoLen != infoHeaderLen && infoLen != v4InfoHeaderLen && infoLen != v5InfoHeaderLen {
return image.Config{}, 0, false, ErrUnsupported
}
+ if _, err := io.ReadFull(r, b[fileHeaderLen+4:fileHeaderLen+infoLen]); err != nil {
+ return image.Config{}, 0, false, err
+ }
width := int(int32(readUint32(b[18:22])))
height := int(int32(readUint32(b[22:26])))
if height < 0 {
@@ -159,14 +165,22 @@ func decodeConfig(r io.Reader) (config image.Config, bitsPerPixel int, topDown b
if width < 0 || height < 0 {
return image.Config{}, 0, false, ErrUnsupported
}
- // We only support 1 plane, 8 or 24 bits per pixel and no compression.
+ // We only support 1 plane and 8, 24 or 32 bits per pixel and no
+ // compression.
planes, bpp, compression := readUint16(b[26:28]), readUint16(b[28:30]), readUint32(b[30:34])
+ // if compression is set to BITFIELDS, but the bitmask is set to the default bitmask
+ // that would be used if compression was set to 0, we can continue as if compression was 0
+ if compression == 3 && infoLen > infoHeaderLen &&
+ readUint32(b[54:58]) == 0xff0000 && readUint32(b[58:62]) == 0xff00 &&
+ readUint32(b[62:66]) == 0xff && readUint32(b[66:70]) == 0xff000000 {
+ compression = 0
+ }
if planes != 1 || compression != 0 {
return image.Config{}, 0, false, ErrUnsupported
}
switch bpp {
case 8:
- if offset != fileHeaderLen+infoHeaderLen+256*4 {
+ if offset != fileHeaderLen+infoLen+256*4 {
return image.Config{}, 0, false, ErrUnsupported
}
_, err = io.ReadFull(r, b[:256*4])
@@ -181,12 +195,12 @@ func decodeConfig(r io.Reader) (config image.Config, bitsPerPixel int, topDown b
}
return image.Config{ColorModel: pcm, Width: width, Height: height}, 8, topDown, nil
case 24:
- if offset != fileHeaderLen+infoHeaderLen {
+ if offset != fileHeaderLen+infoLen {
return image.Config{}, 0, false, ErrUnsupported
}
return image.Config{ColorModel: color.RGBAModel, Width: width, Height: height}, 24, topDown, nil
case 32:
- if offset != fileHeaderLen+infoHeaderLen {
+ if offset != fileHeaderLen+infoLen {
return image.Config{}, 0, false, ErrUnsupported
}
return image.Config{ColorModel: color.RGBAModel, Width: width, Height: height}, 32, topDown, nil
diff --git a/vendor/golang.org/x/image/bmp/writer.go b/vendor/golang.org/x/image/bmp/writer.go
index 6947968..f07b39d 100644
--- a/vendor/golang.org/x/image/bmp/writer.go
+++ b/vendor/golang.org/x/image/bmp/writer.go
@@ -49,20 +49,91 @@ func encodePaletted(w io.Writer, pix []uint8, dx, dy, stride, step int) error {
return nil
}
-func encodeRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int) error {
+func encodeRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int, opaque bool) error {
buf := make([]byte, step)
- for y := dy - 1; y >= 0; y-- {
- min := y*stride + 0
- max := y*stride + dx*4
- off := 0
- for i := min; i < max; i += 4 {
- buf[off+2] = pix[i+0]
- buf[off+1] = pix[i+1]
- buf[off+0] = pix[i+2]
- off += 3
+ if opaque {
+ for y := dy - 1; y >= 0; y-- {
+ min := y*stride + 0
+ max := y*stride + dx*4
+ off := 0
+ for i := min; i < max; i += 4 {
+ buf[off+2] = pix[i+0]
+ buf[off+1] = pix[i+1]
+ buf[off+0] = pix[i+2]
+ off += 3
+ }
+ if _, err := w.Write(buf); err != nil {
+ return err
+ }
}
- if _, err := w.Write(buf); err != nil {
- return err
+ } else {
+ for y := dy - 1; y >= 0; y-- {
+ min := y*stride + 0
+ max := y*stride + dx*4
+ off := 0
+ for i := min; i < max; i += 4 {
+ a := uint32(pix[i+3])
+ if a == 0 {
+ buf[off+2] = 0
+ buf[off+1] = 0
+ buf[off+0] = 0
+ buf[off+3] = 0
+ off += 4
+ continue
+ } else if a == 0xff {
+ buf[off+2] = pix[i+0]
+ buf[off+1] = pix[i+1]
+ buf[off+0] = pix[i+2]
+ buf[off+3] = 0xff
+ off += 4
+ continue
+ }
+ buf[off+2] = uint8(((uint32(pix[i+0]) * 0xffff) / a) >> 8)
+ buf[off+1] = uint8(((uint32(pix[i+1]) * 0xffff) / a) >> 8)
+ buf[off+0] = uint8(((uint32(pix[i+2]) * 0xffff) / a) >> 8)
+ buf[off+3] = uint8(a)
+ off += 4
+ }
+ if _, err := w.Write(buf); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+func encodeNRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int, opaque bool) error {
+ buf := make([]byte, step)
+ if opaque {
+ for y := dy - 1; y >= 0; y-- {
+ min := y*stride + 0
+ max := y*stride + dx*4
+ off := 0
+ for i := min; i < max; i += 4 {
+ buf[off+2] = pix[i+0]
+ buf[off+1] = pix[i+1]
+ buf[off+0] = pix[i+2]
+ off += 3
+ }
+ if _, err := w.Write(buf); err != nil {
+ return err
+ }
+ }
+ } else {
+ for y := dy - 1; y >= 0; y-- {
+ min := y*stride + 0
+ max := y*stride + dx*4
+ off := 0
+ for i := min; i < max; i += 4 {
+ buf[off+2] = pix[i+0]
+ buf[off+1] = pix[i+1]
+ buf[off+0] = pix[i+2]
+ buf[off+3] = pix[i+3]
+ off += 4
+ }
+ if _, err := w.Write(buf); err != nil {
+ return err
+ }
}
}
return nil
@@ -105,6 +176,7 @@ func Encode(w io.Writer, m image.Image) error {
var step int
var palette []byte
+ var opaque bool
switch m := m.(type) {
case *image.Gray:
step = (d.X + 3) &^ 3
@@ -134,6 +206,28 @@ func Encode(w io.Writer, m image.Image) error {
h.fileSize += uint32(len(palette)) + h.imageSize
h.pixOffset += uint32(len(palette))
h.bpp = 8
+ case *image.RGBA:
+ opaque = m.Opaque()
+ if opaque {
+ step = (3*d.X + 3) &^ 3
+ h.bpp = 24
+ } else {
+ step = 4 * d.X
+ h.bpp = 32
+ }
+ h.imageSize = uint32(d.Y * step)
+ h.fileSize += h.imageSize
+ case *image.NRGBA:
+ opaque = m.Opaque()
+ if opaque {
+ step = (3*d.X + 3) &^ 3
+ h.bpp = 24
+ } else {
+ step = 4 * d.X
+ h.bpp = 32
+ }
+ h.imageSize = uint32(d.Y * step)
+ h.fileSize += h.imageSize
default:
step = (3*d.X + 3) &^ 3
h.imageSize = uint32(d.Y * step)
@@ -160,7 +254,9 @@ func Encode(w io.Writer, m image.Image) error {
case *image.Paletted:
return encodePaletted(w, m.Pix, d.X, d.Y, m.Stride, step)
case *image.RGBA:
- return encodeRGBA(w, m.Pix, d.X, d.Y, m.Stride, step)
+ return encodeRGBA(w, m.Pix, d.X, d.Y, m.Stride, step, opaque)
+ case *image.NRGBA:
+ return encodeNRGBA(w, m.Pix, d.X, d.Y, m.Stride, step, opaque)
}
return encode(w, m, step)
}