aboutsummaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/image/tiff/reader.go
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2018-09-27 20:03:23 +0200
committerDimitri Sokolyuk <demon@dim13.org>2018-09-27 20:03:23 +0200
commit14bb08c1df8db9ec6c8a05520d4eee67971235d9 (patch)
treefc820e59c26ed4c5e87e65737909b47959f0faa5 /vendor/golang.org/x/image/tiff/reader.go
parent54eb169e8fc9bc0357139e7c259e977b184f8fbb (diff)
mod tidy
Diffstat (limited to 'vendor/golang.org/x/image/tiff/reader.go')
-rw-r--r--vendor/golang.org/x/image/tiff/reader.go684
1 files changed, 0 insertions, 684 deletions
diff --git a/vendor/golang.org/x/image/tiff/reader.go b/vendor/golang.org/x/image/tiff/reader.go
deleted file mode 100644
index 8a941c1..0000000
--- a/vendor/golang.org/x/image/tiff/reader.go
+++ /dev/null
@@ -1,684 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package tiff implements a TIFF image decoder and encoder.
-//
-// The TIFF specification is at http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf
-package tiff // import "golang.org/x/image/tiff"
-
-import (
- "compress/zlib"
- "encoding/binary"
- "fmt"
- "image"
- "image/color"
- "io"
- "io/ioutil"
- "math"
-
- "golang.org/x/image/tiff/lzw"
-)
-
-// A FormatError reports that the input is not a valid TIFF image.
-type FormatError string
-
-func (e FormatError) Error() string {
- return "tiff: invalid format: " + string(e)
-}
-
-// An UnsupportedError reports that the input uses a valid but
-// unimplemented feature.
-type UnsupportedError string
-
-func (e UnsupportedError) Error() string {
- return "tiff: unsupported feature: " + string(e)
-}
-
-var errNoPixels = FormatError("not enough pixel data")
-
-type decoder struct {
- r io.ReaderAt
- byteOrder binary.ByteOrder
- config image.Config
- mode imageMode
- bpp uint
- features map[int][]uint
- palette []color.Color
-
- buf []byte
- off int // Current offset in buf.
- v uint32 // Buffer value for reading with arbitrary bit depths.
- nbits uint // Remaining number of bits in v.
-}
-
-// firstVal returns the first uint of the features entry with the given tag,
-// or 0 if the tag does not exist.
-func (d *decoder) firstVal(tag int) uint {
- f := d.features[tag]
- if len(f) == 0 {
- return 0
- }
- return f[0]
-}
-
-// ifdUint decodes the IFD entry in p, which must be of the Byte, Short
-// or Long type, and returns the decoded uint values.
-func (d *decoder) ifdUint(p []byte) (u []uint, err error) {
- var raw []byte
- if len(p) < ifdLen {
- return nil, FormatError("bad IFD entry")
- }
-
- datatype := d.byteOrder.Uint16(p[2:4])
- if dt := int(datatype); dt <= 0 || dt >= len(lengths) {
- return nil, UnsupportedError("IFD entry datatype")
- }
-
- count := d.byteOrder.Uint32(p[4:8])
- if count > math.MaxInt32/lengths[datatype] {
- return nil, FormatError("IFD data too large")
- }
- if datalen := lengths[datatype] * count; datalen > 4 {
- // The IFD contains a pointer to the real value.
- raw = make([]byte, datalen)
- _, err = d.r.ReadAt(raw, int64(d.byteOrder.Uint32(p[8:12])))
- } else {
- raw = p[8 : 8+datalen]
- }
- if err != nil {
- return nil, err
- }
-
- u = make([]uint, count)
- switch datatype {
- case dtByte:
- for i := uint32(0); i < count; i++ {
- u[i] = uint(raw[i])
- }
- case dtShort:
- for i := uint32(0); i < count; i++ {
- u[i] = uint(d.byteOrder.Uint16(raw[2*i : 2*(i+1)]))
- }
- case dtLong:
- for i := uint32(0); i < count; i++ {
- u[i] = uint(d.byteOrder.Uint32(raw[4*i : 4*(i+1)]))
- }
- default:
- return nil, UnsupportedError("data type")
- }
- return u, nil
-}
-
-// parseIFD decides whether the the IFD entry in p is "interesting" and
-// stows away the data in the decoder. It returns the tag number of the
-// entry and an error, if any.
-func (d *decoder) parseIFD(p []byte) (int, error) {
- tag := d.byteOrder.Uint16(p[0:2])
- switch tag {
- case tBitsPerSample,
- tExtraSamples,
- tPhotometricInterpretation,
- tCompression,
- tPredictor,
- tStripOffsets,
- tStripByteCounts,
- tRowsPerStrip,
- tTileWidth,
- tTileLength,
- tTileOffsets,
- tTileByteCounts,
- tImageLength,
- tImageWidth:
- val, err := d.ifdUint(p)
- if err != nil {
- return 0, err
- }
- d.features[int(tag)] = val
- case tColorMap:
- val, err := d.ifdUint(p)
- if err != nil {
- return 0, err
- }
- numcolors := len(val) / 3
- if len(val)%3 != 0 || numcolors <= 0 || numcolors > 256 {
- return 0, FormatError("bad ColorMap length")
- }
- d.palette = make([]color.Color, numcolors)
- for i := 0; i < numcolors; i++ {
- d.palette[i] = color.RGBA64{
- uint16(val[i]),
- uint16(val[i+numcolors]),
- uint16(val[i+2*numcolors]),
- 0xffff,
- }
- }
- case tSampleFormat:
- // Page 27 of the spec: If the SampleFormat is present and
- // the value is not 1 [= unsigned integer data], a Baseline
- // TIFF reader that cannot handle the SampleFormat value
- // must terminate the import process gracefully.
- val, err := d.ifdUint(p)
- if err != nil {
- return 0, err
- }
- for _, v := range val {
- if v != 1 {
- return 0, UnsupportedError("sample format")
- }
- }
- }
- return int(tag), nil
-}
-
-// readBits reads n bits from the internal buffer starting at the current offset.
-func (d *decoder) readBits(n uint) (v uint32, ok bool) {
- for d.nbits < n {
- d.v <<= 8
- if d.off >= len(d.buf) {
- return 0, false
- }
- d.v |= uint32(d.buf[d.off])
- d.off++
- d.nbits += 8
- }
- d.nbits -= n
- rv := d.v >> d.nbits
- d.v &^= rv << d.nbits
- return rv, true
-}
-
-// flushBits discards the unread bits in the buffer used by readBits.
-// It is used at the end of a line.
-func (d *decoder) flushBits() {
- d.v = 0
- d.nbits = 0
-}
-
-// minInt returns the smaller of x or y.
-func minInt(a, b int) int {
- if a <= b {
- return a
- }
- return b
-}
-
-// decode decodes the raw data of an image.
-// It reads from d.buf and writes the strip or tile into dst.
-func (d *decoder) decode(dst image.Image, xmin, ymin, xmax, ymax int) error {
- d.off = 0
-
- // 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 {
- switch d.bpp {
- case 16:
- var off int
- n := 2 * len(d.features[tBitsPerSample]) // bytes per sample times samples per pixel
- for y := ymin; y < ymax; y++ {
- off += n
- for x := 0; x < (xmax-xmin-1)*n; x += 2 {
- if off+2 > len(d.buf) {
- return errNoPixels
- }
- v0 := d.byteOrder.Uint16(d.buf[off-n : off-n+2])
- v1 := d.byteOrder.Uint16(d.buf[off : off+2])
- d.byteOrder.PutUint16(d.buf[off:off+2], v1+v0)
- off += 2
- }
- }
- case 8:
- var off int
- n := 1 * len(d.features[tBitsPerSample]) // bytes per sample times samples per pixel
- for y := ymin; y < ymax; y++ {
- off += n
- for x := 0; x < (xmax-xmin-1)*n; x++ {
- if off >= len(d.buf) {
- return errNoPixels
- }
- d.buf[off] += d.buf[off-n]
- off++
- }
- }
- case 1:
- return UnsupportedError("horizontal predictor with 1 BitsPerSample")
- }
- }
-
- rMaxX := minInt(xmax, dst.Bounds().Max.X)
- rMaxY := minInt(ymax, dst.Bounds().Max.Y)
- switch d.mode {
- case mGray, mGrayInvert:
- if d.bpp == 16 {
- img := dst.(*image.Gray16)
- for y := ymin; y < rMaxY; y++ {
- for x := xmin; x < rMaxX; x++ {
- if d.off+2 > len(d.buf) {
- return errNoPixels
- }
- v := d.byteOrder.Uint16(d.buf[d.off : d.off+2])
- d.off += 2
- if d.mode == mGrayInvert {
- v = 0xffff - v
- }
- img.SetGray16(x, y, color.Gray16{v})
- }
- if rMaxX == img.Bounds().Max.X {
- d.off += 2 * (xmax - img.Bounds().Max.X)
- }
- }
- } else {
- img := dst.(*image.Gray)
- max := uint32((1 << d.bpp) - 1)
- for y := ymin; y < rMaxY; y++ {
- for x := xmin; x < rMaxX; x++ {
- v, ok := d.readBits(d.bpp)
- if !ok {
- return errNoPixels
- }
- v = v * 0xff / max
- if d.mode == mGrayInvert {
- v = 0xff - v
- }
- img.SetGray(x, y, color.Gray{uint8(v)})
- }
- d.flushBits()
- }
- }
- case mPaletted:
- img := dst.(*image.Paletted)
- for y := ymin; y < rMaxY; y++ {
- for x := xmin; x < rMaxX; x++ {
- v, ok := d.readBits(d.bpp)
- if !ok {
- return errNoPixels
- }
- img.SetColorIndex(x, y, uint8(v))
- }
- d.flushBits()
- }
- case mRGB:
- if d.bpp == 16 {
- img := dst.(*image.RGBA64)
- for y := ymin; y < rMaxY; y++ {
- for x := xmin; x < rMaxX; x++ {
- if d.off+6 > len(d.buf) {
- return errNoPixels
- }
- r := d.byteOrder.Uint16(d.buf[d.off+0 : d.off+2])
- g := d.byteOrder.Uint16(d.buf[d.off+2 : d.off+4])
- b := d.byteOrder.Uint16(d.buf[d.off+4 : d.off+6])
- d.off += 6
- img.SetRGBA64(x, y, color.RGBA64{r, g, b, 0xffff})
- }
- }
- } else {
- img := dst.(*image.RGBA)
- for y := ymin; y < rMaxY; y++ {
- min := img.PixOffset(xmin, y)
- max := img.PixOffset(rMaxX, y)
- off := (y - ymin) * (xmax - xmin) * 3
- for i := min; i < max; i += 4 {
- if off+3 > len(d.buf) {
- return errNoPixels
- }
- 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:
- if d.bpp == 16 {
- img := dst.(*image.NRGBA64)
- for y := ymin; y < rMaxY; y++ {
- for x := xmin; x < rMaxX; x++ {
- if d.off+8 > len(d.buf) {
- return errNoPixels
- }
- r := d.byteOrder.Uint16(d.buf[d.off+0 : d.off+2])
- g := d.byteOrder.Uint16(d.buf[d.off+2 : d.off+4])
- b := d.byteOrder.Uint16(d.buf[d.off+4 : d.off+6])
- a := d.byteOrder.Uint16(d.buf[d.off+6 : d.off+8])
- d.off += 8
- img.SetNRGBA64(x, y, color.NRGBA64{r, g, b, a})
- }
- }
- } else {
- img := dst.(*image.NRGBA)
- for y := ymin; y < rMaxY; y++ {
- min := img.PixOffset(xmin, y)
- max := img.PixOffset(rMaxX, y)
- i0, i1 := (y-ymin)*(xmax-xmin)*4, (y-ymin+1)*(xmax-xmin)*4
- if i1 > len(d.buf) {
- return errNoPixels
- }
- copy(img.Pix[min:max], d.buf[i0:i1])
- }
- }
- case mRGBA:
- if d.bpp == 16 {
- img := dst.(*image.RGBA64)
- for y := ymin; y < rMaxY; y++ {
- for x := xmin; x < rMaxX; x++ {
- if d.off+8 > len(d.buf) {
- return errNoPixels
- }
- r := d.byteOrder.Uint16(d.buf[d.off+0 : d.off+2])
- g := d.byteOrder.Uint16(d.buf[d.off+2 : d.off+4])
- b := d.byteOrder.Uint16(d.buf[d.off+4 : d.off+6])
- a := d.byteOrder.Uint16(d.buf[d.off+6 : d.off+8])
- d.off += 8
- img.SetRGBA64(x, y, color.RGBA64{r, g, b, a})
- }
- }
- } else {
- img := dst.(*image.RGBA)
- for y := ymin; y < rMaxY; y++ {
- min := img.PixOffset(xmin, y)
- max := img.PixOffset(rMaxX, y)
- i0, i1 := (y-ymin)*(xmax-xmin)*4, (y-ymin+1)*(xmax-xmin)*4
- if i1 > len(d.buf) {
- return errNoPixels
- }
- copy(img.Pix[min:max], d.buf[i0:i1])
- }
- }
- }
-
- return nil
-}
-
-func newDecoder(r io.Reader) (*decoder, error) {
- d := &decoder{
- r: newReaderAt(r),
- features: make(map[int][]uint),
- }
-
- p := make([]byte, 8)
- if _, err := d.r.ReadAt(p, 0); err != nil {
- return nil, err
- }
- switch string(p[0:4]) {
- case leHeader:
- d.byteOrder = binary.LittleEndian
- case beHeader:
- d.byteOrder = binary.BigEndian
- default:
- return nil, FormatError("malformed header")
- }
-
- ifdOffset := int64(d.byteOrder.Uint32(p[4:8]))
-
- // The first two bytes contain the number of entries (12 bytes each).
- if _, err := d.r.ReadAt(p[0:2], ifdOffset); err != nil {
- return nil, err
- }
- numItems := int(d.byteOrder.Uint16(p[0:2]))
-
- // All IFD entries are read in one chunk.
- p = make([]byte, ifdLen*numItems)
- if _, err := d.r.ReadAt(p, ifdOffset+2); err != nil {
- return nil, err
- }
-
- prevTag := -1
- for i := 0; i < len(p); i += ifdLen {
- tag, err := d.parseIFD(p[i : i+ifdLen])
- if err != nil {
- return nil, err
- }
- if tag <= prevTag {
- return nil, FormatError("tags are not sorted in ascending order")
- }
- prevTag = tag
- }
-
- d.config.Width = int(d.firstVal(tImageWidth))
- d.config.Height = int(d.firstVal(tImageLength))
-
- if _, ok := d.features[tBitsPerSample]; !ok {
- return nil, FormatError("BitsPerSample tag missing")
- }
- d.bpp = d.firstVal(tBitsPerSample)
- switch d.bpp {
- case 0:
- return nil, FormatError("BitsPerSample must not be 0")
- case 1, 8, 16:
- // Nothing to do, these are accepted by this implementation.
- default:
- return nil, UnsupportedError(fmt.Sprintf("BitsPerSample of %v", d.bpp))
- }
-
- // Determine the image mode.
- switch d.firstVal(tPhotometricInterpretation) {
- case pRGB:
- if d.bpp == 16 {
- for _, b := range d.features[tBitsPerSample] {
- if b != 16 {
- return nil, FormatError("wrong number of samples for 16bit RGB")
- }
- }
- } else {
- for _, b := range d.features[tBitsPerSample] {
- if b != 8 {
- return nil, FormatError("wrong number of samples for 8bit RGB")
- }
- }
- }
- // 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
- if d.bpp == 16 {
- d.config.ColorModel = color.RGBA64Model
- } else {
- d.config.ColorModel = color.RGBAModel
- }
- case 4:
- switch d.firstVal(tExtraSamples) {
- case 1:
- d.mode = mRGBA
- if d.bpp == 16 {
- d.config.ColorModel = color.RGBA64Model
- } else {
- d.config.ColorModel = color.RGBAModel
- }
- case 2:
- d.mode = mNRGBA
- if d.bpp == 16 {
- d.config.ColorModel = color.NRGBA64Model
- } else {
- d.config.ColorModel = color.NRGBAModel
- }
- default:
- 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 = color.Palette(d.palette)
- case pWhiteIsZero:
- d.mode = mGrayInvert
- if d.bpp == 16 {
- d.config.ColorModel = color.Gray16Model
- } else {
- d.config.ColorModel = color.GrayModel
- }
- case pBlackIsZero:
- d.mode = mGray
- if d.bpp == 16 {
- d.config.ColorModel = color.Gray16Model
- } else {
- d.config.ColorModel = color.GrayModel
- }
- default:
- return nil, UnsupportedError("color model")
- }
-
- return d, nil
-}
-
-// DecodeConfig returns the color model and dimensions of a TIFF image without
-// decoding the entire image.
-func DecodeConfig(r io.Reader) (image.Config, error) {
- d, err := newDecoder(r)
- if err != nil {
- return image.Config{}, err
- }
- return d.config, nil
-}
-
-// Decode reads a TIFF image from r and returns it as an image.Image.
-// The type of Image returned depends on the contents of the TIFF.
-func Decode(r io.Reader) (img image.Image, err error) {
- d, err := newDecoder(r)
- if err != nil {
- return
- }
-
- blockPadding := false
- blockWidth := d.config.Width
- blockHeight := d.config.Height
- blocksAcross := 1
- blocksDown := 1
-
- if d.config.Width == 0 {
- blocksAcross = 0
- }
- if d.config.Height == 0 {
- blocksDown = 0
- }
-
- var blockOffsets, blockCounts []uint
-
- if int(d.firstVal(tTileWidth)) != 0 {
- blockPadding = true
-
- blockWidth = int(d.firstVal(tTileWidth))
- blockHeight = int(d.firstVal(tTileLength))
-
- if blockWidth != 0 {
- blocksAcross = (d.config.Width + blockWidth - 1) / blockWidth
- }
- if blockHeight != 0 {
- blocksDown = (d.config.Height + blockHeight - 1) / blockHeight
- }
-
- blockCounts = d.features[tTileByteCounts]
- blockOffsets = d.features[tTileOffsets]
-
- } else {
- if int(d.firstVal(tRowsPerStrip)) != 0 {
- blockHeight = int(d.firstVal(tRowsPerStrip))
- }
-
- if blockHeight != 0 {
- blocksDown = (d.config.Height + blockHeight - 1) / blockHeight
- }
-
- blockOffsets = d.features[tStripOffsets]
- blockCounts = d.features[tStripByteCounts]
- }
-
- // Check if we have the right number of strips/tiles, offsets and counts.
- if n := blocksAcross * blocksDown; len(blockOffsets) < n || len(blockCounts) < n {
- return nil, FormatError("inconsistent header")
- }
-
- imgRect := image.Rect(0, 0, d.config.Width, d.config.Height)
- switch d.mode {
- case mGray, mGrayInvert:
- if d.bpp == 16 {
- img = image.NewGray16(imgRect)
- } else {
- img = image.NewGray(imgRect)
- }
- case mPaletted:
- img = image.NewPaletted(imgRect, d.palette)
- case mNRGBA:
- if d.bpp == 16 {
- img = image.NewNRGBA64(imgRect)
- } else {
- img = image.NewNRGBA(imgRect)
- }
- case mRGB, mRGBA:
- if d.bpp == 16 {
- img = image.NewRGBA64(imgRect)
- } else {
- img = image.NewRGBA(imgRect)
- }
- }
-
- for i := 0; i < blocksAcross; i++ {
- blkW := blockWidth
- if !blockPadding && i == blocksAcross-1 && d.config.Width%blockWidth != 0 {
- blkW = d.config.Width % blockWidth
- }
- for j := 0; j < blocksDown; j++ {
- blkH := blockHeight
- if !blockPadding && j == blocksDown-1 && d.config.Height%blockHeight != 0 {
- blkH = d.config.Height % blockHeight
- }
- offset := int64(blockOffsets[j*blocksAcross+i])
- n := int64(blockCounts[j*blocksAcross+i])
- switch d.firstVal(tCompression) {
-
- // According to the spec, Compression does not have a default value,
- // but some tools interpret a missing Compression value as none so we do
- // the same.
- case cNone, 0:
- if b, ok := d.r.(*buffer); ok {
- d.buf, err = b.Slice(int(offset), int(n))
- } else {
- d.buf = make([]byte, n)
- _, err = d.r.ReadAt(d.buf, offset)
- }
- case cLZW:
- r := lzw.NewReader(io.NewSectionReader(d.r, offset, n), lzw.MSB, 8)
- d.buf, err = ioutil.ReadAll(r)
- r.Close()
- case cDeflate, cDeflateOld:
- var r io.ReadCloser
- r, err = zlib.NewReader(io.NewSectionReader(d.r, offset, n))
- if err != nil {
- return nil, err
- }
- d.buf, err = ioutil.ReadAll(r)
- r.Close()
- case cPackBits:
- d.buf, err = unpackBits(io.NewSectionReader(d.r, offset, n))
- default:
- err = UnsupportedError(fmt.Sprintf("compression value %d", d.firstVal(tCompression)))
- }
- if err != nil {
- return nil, err
- }
-
- xmin := i * blockWidth
- ymin := j * blockHeight
- xmax := xmin + blkW
- ymax := ymin + blkH
- err = d.decode(img, xmin, ymin, xmax, ymax)
- if err != nil {
- return nil, err
- }
- }
- }
- return
-}
-
-func init() {
- image.RegisterFormat("tiff", leHeader, Decode, DecodeConfig)
- image.RegisterFormat("tiff", beHeader, Decode, DecodeConfig)
-}