|
@@ -62,7 +62,7 @@ func prepareBmpCanvas(width, height, bands int) (*C.VipsImage, []byte, error) {
|
|
|
|
|
|
// decodeBmpPaletted reads an 8 bit-per-pixel BMP image from r.
|
|
// decodeBmpPaletted reads an 8 bit-per-pixel BMP image from r.
|
|
// If topDown is false, the image rows will be read bottom-up.
|
|
// If topDown is false, the image rows will be read bottom-up.
|
|
-func (img *Image) decodeBmpPaletted(r io.Reader, width, height int, palette []Color, topDown bool) error {
|
|
|
|
|
|
+func (img *Image) decodeBmpPaletted(r io.Reader, width, height, bpp int, palette []Color, topDown bool) error {
|
|
tmp, imgData, err := prepareBmpCanvas(width, height, 3)
|
|
tmp, imgData, err := prepareBmpCanvas(width, height, 3)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
@@ -76,7 +76,8 @@ func (img *Image) decodeBmpPaletted(r io.Reader, width, height int, palette []Co
|
|
}()
|
|
}()
|
|
|
|
|
|
// Each row is 4-byte aligned.
|
|
// Each row is 4-byte aligned.
|
|
- b := make([]byte, (width+3)&^3)
|
|
|
|
|
|
+ cap := 8 / bpp
|
|
|
|
+ b := make([]byte, ((width+cap-1)/cap+3)&^3)
|
|
|
|
|
|
y0, y1, yDelta := height-1, -1, -1
|
|
y0, y1, yDelta := height-1, -1, -1
|
|
if topDown {
|
|
if topDown {
|
|
@@ -93,8 +94,18 @@ func (img *Image) decodeBmpPaletted(r io.Reader, width, height int, palette []Co
|
|
|
|
|
|
p := imgData[y*stride : (y+1)*stride]
|
|
p := imgData[y*stride : (y+1)*stride]
|
|
|
|
|
|
- for i, j := 0, 0; i < len(p); i, j = i+3, j+1 {
|
|
|
|
- c := palette[b[j]]
|
|
|
|
|
|
+ j, bit := 0, 8-bpp
|
|
|
|
+ for i := 0; i < len(p); i += 3 {
|
|
|
|
+ pind := (b[j] >> bit) & (1<<bpp - 1)
|
|
|
|
+
|
|
|
|
+ if bit == 0 {
|
|
|
|
+ bit = 8 - bpp
|
|
|
|
+ j++
|
|
|
|
+ } else {
|
|
|
|
+ bit -= bpp
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ c := palette[pind]
|
|
|
|
|
|
p[i+0] = c.R
|
|
p[i+0] = c.R
|
|
p[i+1] = c.G
|
|
p[i+1] = c.G
|
|
@@ -245,7 +256,7 @@ func (img *Image) loadBmp(data []byte) error {
|
|
}
|
|
}
|
|
|
|
|
|
switch bpp {
|
|
switch bpp {
|
|
- case 8:
|
|
|
|
|
|
+ case 1, 2, 4, 8:
|
|
palColors := readUint32(b[46:50])
|
|
palColors := readUint32(b[46:50])
|
|
|
|
|
|
if offset != fileHeaderLen+infoLen+palColors*4 {
|
|
if offset != fileHeaderLen+infoLen+palColors*4 {
|
|
@@ -264,7 +275,7 @@ func (img *Image) loadBmp(data []byte) error {
|
|
palette[i] = Color{b[4*i+2], b[4*i+1], b[4*i+0]}
|
|
palette[i] = Color{b[4*i+2], b[4*i+1], b[4*i+0]}
|
|
}
|
|
}
|
|
|
|
|
|
- return img.decodeBmpPaletted(r, width, height, palette, topDown)
|
|
|
|
|
|
+ return img.decodeBmpPaletted(r, width, height, int(bpp), palette, topDown)
|
|
case 24:
|
|
case 24:
|
|
if offset != fileHeaderLen+infoLen {
|
|
if offset != fileHeaderLen+infoLen {
|
|
return errBmpUnsupported
|
|
return errBmpUnsupported
|