summaryrefslogtreecommitdiff
path: root/libgo/go/image/tiff/reader.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/image/tiff/reader.go')
-rw-r--r--libgo/go/image/tiff/reader.go82
1 files changed, 45 insertions, 37 deletions
diff --git a/libgo/go/image/tiff/reader.go b/libgo/go/image/tiff/reader.go
index f5652667aa3..c452f5d54cc 100644
--- a/libgo/go/image/tiff/reader.go
+++ b/libgo/go/image/tiff/reader.go
@@ -12,6 +12,7 @@ import (
"compress/zlib"
"encoding/binary"
"image"
+ "image/color"
"io"
"io/ioutil"
"os"
@@ -45,7 +46,7 @@ type decoder struct {
config image.Config
mode imageMode
features map[int][]uint
- palette []image.Color
+ palette []color.Color
buf []byte
off int // Current offset in buf.
@@ -129,9 +130,9 @@ func (d *decoder) parseIFD(p []byte) os.Error {
if len(val)%3 != 0 || numcolors <= 0 || numcolors > 256 {
return FormatError("bad ColorMap length")
}
- d.palette = make([]image.Color, numcolors)
+ d.palette = make([]color.Color, numcolors)
for i := 0; i < numcolors; i++ {
- d.palette[i] = image.RGBA64Color{
+ d.palette[i] = color.RGBA64{
uint16(val[i]),
uint16(val[i+numcolors]),
uint16(val[i+2*numcolors]),
@@ -180,22 +181,21 @@ func (d *decoder) flushBits() {
// decode decodes the raw data of an image.
// It reads from d.buf and writes the strip with ymin <= y < ymax into dst.
func (d *decoder) decode(dst image.Image, ymin, ymax int) os.Error {
- spp := len(d.features[tBitsPerSample]) // samples per pixel
d.off = 0
- width := dst.Bounds().Dx()
// Apply horizontal predictor if necessary.
// In this case, p contains the color difference to the preceding pixel.
// See page 64-65 of the spec.
if d.firstVal(tPredictor) == prHorizontal && d.firstVal(tBitsPerSample) == 8 {
+ var off int
+ spp := len(d.features[tBitsPerSample]) // samples per pixel
for y := ymin; y < ymax; y++ {
- d.off += spp
- for x := 0; x < (width-1)*spp; x++ {
- d.buf[d.off] += d.buf[d.off-spp]
- d.off++
+ off += spp
+ for x := 0; x < (dst.Bounds().Dx()-1)*spp; x++ {
+ d.buf[off] += d.buf[off-spp]
+ off++
}
}
- d.off = 0
}
switch d.mode {
@@ -209,7 +209,7 @@ func (d *decoder) decode(dst image.Image, ymin, ymax int) os.Error {
if d.mode == mGrayInvert {
v = 0xff - v
}
- img.SetGray(x, y, image.GrayColor{v})
+ img.SetGray(x, y, color.Gray{v})
}
d.flushBits()
}
@@ -224,28 +224,32 @@ func (d *decoder) decode(dst image.Image, ymin, ymax int) os.Error {
}
case mRGB:
img := dst.(*image.RGBA)
- for y := ymin; y < ymax; y++ {
- for x := img.Rect.Min.X; x < img.Rect.Max.X; x++ {
- img.SetRGBA(x, y, image.RGBAColor{d.buf[d.off], d.buf[d.off+1], d.buf[d.off+2], 0xff})
- d.off += spp
- }
+ min := (ymin-img.Rect.Min.Y)*img.Stride - img.Rect.Min.X*4
+ max := (ymax-img.Rect.Min.Y)*img.Stride - img.Rect.Min.X*4
+ var off int
+ for i := min; i < max; i += 4 {
+ img.Pix[i+0] = d.buf[off+0]
+ img.Pix[i+1] = d.buf[off+1]
+ img.Pix[i+2] = d.buf[off+2]
+ img.Pix[i+3] = 0xff
+ off += 3
}
case mNRGBA:
img := dst.(*image.NRGBA)
- for y := ymin; y < ymax; y++ {
- for x := img.Rect.Min.X; x < img.Rect.Max.X; x++ {
- img.SetNRGBA(x, y, image.NRGBAColor{d.buf[d.off], d.buf[d.off+1], d.buf[d.off+2], d.buf[d.off+3]})
- d.off += spp
- }
+ min := (ymin-img.Rect.Min.Y)*img.Stride - img.Rect.Min.X*4
+ max := (ymax-img.Rect.Min.Y)*img.Stride - img.Rect.Min.X*4
+ if len(d.buf) != max-min {
+ return FormatError("short data strip")
}
+ copy(img.Pix[min:max], d.buf)
case mRGBA:
img := dst.(*image.RGBA)
- for y := ymin; y < ymax; y++ {
- for x := img.Rect.Min.X; x < img.Rect.Max.X; x++ {
- img.SetRGBA(x, y, image.RGBAColor{d.buf[d.off], d.buf[d.off+1], d.buf[d.off+2], d.buf[d.off+3]})
- d.off += spp
- }
+ min := (ymin-img.Rect.Min.Y)*img.Stride - img.Rect.Min.X*4
+ max := (ymax-img.Rect.Min.Y)*img.Stride - img.Rect.Min.X*4
+ if len(d.buf) != max-min {
+ return FormatError("short data strip")
}
+ copy(img.Pix[min:max], d.buf)
}
return nil
@@ -305,10 +309,13 @@ func newDecoder(r io.Reader) (*decoder, os.Error) {
return nil, UnsupportedError("non-8-bit RGB image")
}
}
- d.config.ColorModel = image.RGBAColorModel
+ d.config.ColorModel = color.RGBAModel
// RGB images normally have 3 samples per pixel.
// If there are more, ExtraSamples (p. 31-32 of the spec)
// gives their meaning (usually an alpha channel).
+ //
+ // This implementation does not support extra samples
+ // of an unspecified type.
switch len(d.features[tBitsPerSample]) {
case 3:
d.mode = mRGB
@@ -318,23 +325,22 @@ func newDecoder(r io.Reader) (*decoder, os.Error) {
d.mode = mRGBA
case 2:
d.mode = mNRGBA
- d.config.ColorModel = image.NRGBAColorModel
+ d.config.ColorModel = color.NRGBAModel
default:
- // The extra sample is discarded.
- d.mode = mRGB
+ return nil, FormatError("wrong number of samples for RGB")
}
default:
return nil, FormatError("wrong number of samples for RGB")
}
case pPaletted:
d.mode = mPaletted
- d.config.ColorModel = image.PalettedColorModel(d.palette)
+ d.config.ColorModel = color.Palette(d.palette)
case pWhiteIsZero:
d.mode = mGrayInvert
- d.config.ColorModel = image.GrayColorModel
+ d.config.ColorModel = color.GrayModel
case pBlackIsZero:
d.mode = mGray
- d.config.ColorModel = image.GrayColorModel
+ d.config.ColorModel = color.GrayModel
default:
return nil, UnsupportedError("color model")
}
@@ -373,13 +379,13 @@ func Decode(r io.Reader) (img image.Image, err os.Error) {
switch d.mode {
case mGray, mGrayInvert:
- img = image.NewGray(d.config.Width, d.config.Height)
+ img = image.NewGray(image.Rect(0, 0, d.config.Width, d.config.Height))
case mPaletted:
- img = image.NewPaletted(d.config.Width, d.config.Height, d.palette)
+ img = image.NewPaletted(image.Rect(0, 0, d.config.Width, d.config.Height), d.palette)
case mNRGBA:
- img = image.NewNRGBA(d.config.Width, d.config.Height)
+ img = image.NewNRGBA(image.Rect(0, 0, d.config.Width, d.config.Height))
case mRGB, mRGBA:
- img = image.NewRGBA(d.config.Width, d.config.Height)
+ img = image.NewRGBA(image.Rect(0, 0, d.config.Width, d.config.Height))
}
for i := 0; i < numStrips; i++ {
@@ -406,6 +412,8 @@ func Decode(r io.Reader) (img image.Image, err os.Error) {
}
d.buf, err = ioutil.ReadAll(r)
r.Close()
+ case cPackBits:
+ d.buf, err = unpackBits(io.NewSectionReader(d.r, offset, n))
default:
err = UnsupportedError("compression")
}