Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(247)

Side by Side Diff: tiff/reader.go

Issue 5593053: code review 5593053: go.image: initial code. (Closed)
Patch Set: diff -r b50a7fb49394 https://code.google.com/p/go.image Created 13 years, 2 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tiff/consts.go ('k') | tiff/reader_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Package tiff implements a TIFF image decoder.
6 //
7 // The TIFF specification is at http://partners.adobe.com/public/developer/en/ti ff/TIFF6.pdf
8 package tiff
9
10 import (
11 "compress/lzw"
12 "compress/zlib"
13 "encoding/binary"
14 "image"
15 "image/color"
16 "io"
17 "io/ioutil"
18 )
19
20 // A FormatError reports that the input is not a valid TIFF image.
21 type FormatError string
22
23 func (e FormatError) Error() string {
24 return "tiff: invalid format: " + string(e)
25 }
26
27 // An UnsupportedError reports that the input uses a valid but
28 // unimplemented feature.
29 type UnsupportedError string
30
31 func (e UnsupportedError) Error() string {
32 return "tiff: unsupported feature: " + string(e)
33 }
34
35 // An InternalError reports that an internal error was encountered.
36 type InternalError string
37
38 func (e InternalError) Error() string {
39 return "tiff: internal error: " + string(e)
40 }
41
42 type decoder struct {
43 r io.ReaderAt
44 byteOrder binary.ByteOrder
45 config image.Config
46 mode imageMode
47 features map[int][]uint
48 palette []color.Color
49
50 buf []byte
51 off int // Current offset in buf.
52 v uint32 // Buffer value for reading with arbitrary bit depths.
53 nbits uint // Remaining number of bits in v.
54 }
55
56 // firstVal returns the first uint of the features entry with the given tag,
57 // or 0 if the tag does not exist.
58 func (d *decoder) firstVal(tag int) uint {
59 f := d.features[tag]
60 if len(f) == 0 {
61 return 0
62 }
63 return f[0]
64 }
65
66 // ifdUint decodes the IFD entry in p, which must be of the Byte, Short
67 // or Long type, and returns the decoded uint values.
68 func (d *decoder) ifdUint(p []byte) (u []uint, err error) {
69 var raw []byte
70 datatype := d.byteOrder.Uint16(p[2:4])
71 count := d.byteOrder.Uint32(p[4:8])
72 if datalen := lengths[datatype] * count; datalen > 4 {
73 // The IFD contains a pointer to the real value.
74 raw = make([]byte, datalen)
75 _, err = d.r.ReadAt(raw, int64(d.byteOrder.Uint32(p[8:12])))
76 } else {
77 raw = p[8 : 8+datalen]
78 }
79 if err != nil {
80 return nil, err
81 }
82
83 u = make([]uint, count)
84 switch datatype {
85 case dtByte:
86 for i := uint32(0); i < count; i++ {
87 u[i] = uint(raw[i])
88 }
89 case dtShort:
90 for i := uint32(0); i < count; i++ {
91 u[i] = uint(d.byteOrder.Uint16(raw[2*i : 2*(i+1)]))
92 }
93 case dtLong:
94 for i := uint32(0); i < count; i++ {
95 u[i] = uint(d.byteOrder.Uint32(raw[4*i : 4*(i+1)]))
96 }
97 default:
98 return nil, UnsupportedError("data type")
99 }
100 return u, nil
101 }
102
103 // parseIFD decides whether the the IFD entry in p is "interesting" and
104 // stows away the data in the decoder.
105 func (d *decoder) parseIFD(p []byte) error {
106 tag := d.byteOrder.Uint16(p[0:2])
107 switch tag {
108 case tBitsPerSample,
109 tExtraSamples,
110 tPhotometricInterpretation,
111 tCompression,
112 tPredictor,
113 tStripOffsets,
114 tStripByteCounts,
115 tRowsPerStrip,
116 tImageLength,
117 tImageWidth:
118 val, err := d.ifdUint(p)
119 if err != nil {
120 return err
121 }
122 d.features[int(tag)] = val
123 case tColorMap:
124 val, err := d.ifdUint(p)
125 if err != nil {
126 return err
127 }
128 numcolors := len(val) / 3
129 if len(val)%3 != 0 || numcolors <= 0 || numcolors > 256 {
130 return FormatError("bad ColorMap length")
131 }
132 d.palette = make([]color.Color, numcolors)
133 for i := 0; i < numcolors; i++ {
134 d.palette[i] = color.RGBA64{
135 uint16(val[i]),
136 uint16(val[i+numcolors]),
137 uint16(val[i+2*numcolors]),
138 0xffff,
139 }
140 }
141 case tSampleFormat:
142 // Page 27 of the spec: If the SampleFormat is present and
143 // the value is not 1 [= unsigned integer data], a Baseline
144 // TIFF reader that cannot handle the SampleFormat value
145 // must terminate the import process gracefully.
146 val, err := d.ifdUint(p)
147 if err != nil {
148 return err
149 }
150 for _, v := range val {
151 if v != 1 {
152 return UnsupportedError("sample format")
153 }
154 }
155 }
156 return nil
157 }
158
159 // readBits reads n bits from the internal buffer starting at the current offset .
160 func (d *decoder) readBits(n uint) uint32 {
161 for d.nbits < n {
162 d.v <<= 8
163 d.v |= uint32(d.buf[d.off])
164 d.off++
165 d.nbits += 8
166 }
167 d.nbits -= n
168 rv := d.v >> d.nbits
169 d.v &^= rv << d.nbits
170 return rv
171 }
172
173 // flushBits discards the unread bits in the buffer used by readBits.
174 // It is used at the end of a line.
175 func (d *decoder) flushBits() {
176 d.v = 0
177 d.nbits = 0
178 }
179
180 // decode decodes the raw data of an image.
181 // It reads from d.buf and writes the strip with ymin <= y < ymax into dst.
182 func (d *decoder) decode(dst image.Image, ymin, ymax int) error {
183 d.off = 0
184
185 // Apply horizontal predictor if necessary.
186 // In this case, p contains the color difference to the preceding pixel.
187 // See page 64-65 of the spec.
188 if d.firstVal(tPredictor) == prHorizontal && d.firstVal(tBitsPerSample) == 8 {
189 var off int
190 spp := len(d.features[tBitsPerSample]) // samples per pixel
191 for y := ymin; y < ymax; y++ {
192 off += spp
193 for x := 0; x < (dst.Bounds().Dx()-1)*spp; x++ {
194 d.buf[off] += d.buf[off-spp]
195 off++
196 }
197 }
198 }
199
200 switch d.mode {
201 case mGray, mGrayInvert:
202 img := dst.(*image.Gray)
203 bpp := d.firstVal(tBitsPerSample)
204 max := uint32((1 << bpp) - 1)
205 for y := ymin; y < ymax; y++ {
206 for x := img.Rect.Min.X; x < img.Rect.Max.X; x++ {
207 v := uint8(d.readBits(bpp) * 0xff / max)
208 if d.mode == mGrayInvert {
209 v = 0xff - v
210 }
211 img.SetGray(x, y, color.Gray{v})
212 }
213 d.flushBits()
214 }
215 case mPaletted:
216 img := dst.(*image.Paletted)
217 bpp := d.firstVal(tBitsPerSample)
218 for y := ymin; y < ymax; y++ {
219 for x := img.Rect.Min.X; x < img.Rect.Max.X; x++ {
220 img.SetColorIndex(x, y, uint8(d.readBits(bpp)))
221 }
222 d.flushBits()
223 }
224 case mRGB:
225 img := dst.(*image.RGBA)
226 min := img.PixOffset(0, ymin)
227 max := img.PixOffset(0, ymax)
228 var off int
229 for i := min; i < max; i += 4 {
230 img.Pix[i+0] = d.buf[off+0]
231 img.Pix[i+1] = d.buf[off+1]
232 img.Pix[i+2] = d.buf[off+2]
233 img.Pix[i+3] = 0xff
234 off += 3
235 }
236 case mNRGBA:
237 img := dst.(*image.NRGBA)
238 min := img.PixOffset(0, ymin)
239 max := img.PixOffset(0, ymax)
240 if len(d.buf) != max-min {
241 return FormatError("short data strip")
242 }
243 copy(img.Pix[min:max], d.buf)
244 case mRGBA:
245 img := dst.(*image.RGBA)
246 min := img.PixOffset(0, ymin)
247 max := img.PixOffset(0, ymax)
248 if len(d.buf) != max-min {
249 return FormatError("short data strip")
250 }
251 copy(img.Pix[min:max], d.buf)
252 }
253
254 return nil
255 }
256
257 func newDecoder(r io.Reader) (*decoder, error) {
258 d := &decoder{
259 r: newReaderAt(r),
260 features: make(map[int][]uint),
261 }
262
263 p := make([]byte, 8)
264 if _, err := d.r.ReadAt(p, 0); err != nil {
265 return nil, err
266 }
267 switch string(p[0:4]) {
268 case leHeader:
269 d.byteOrder = binary.LittleEndian
270 case beHeader:
271 d.byteOrder = binary.BigEndian
272 default:
273 return nil, FormatError("malformed header")
274 }
275
276 ifdOffset := int64(d.byteOrder.Uint32(p[4:8]))
277
278 // The first two bytes contain the number of entries (12 bytes each).
279 if _, err := d.r.ReadAt(p[0:2], ifdOffset); err != nil {
280 return nil, err
281 }
282 numItems := int(d.byteOrder.Uint16(p[0:2]))
283
284 // All IFD entries are read in one chunk.
285 p = make([]byte, ifdLen*numItems)
286 if _, err := d.r.ReadAt(p, ifdOffset+2); err != nil {
287 return nil, err
288 }
289
290 for i := 0; i < len(p); i += ifdLen {
291 if err := d.parseIFD(p[i : i+ifdLen]); err != nil {
292 return nil, err
293 }
294 }
295
296 d.config.Width = int(d.firstVal(tImageWidth))
297 d.config.Height = int(d.firstVal(tImageLength))
298
299 if _, ok := d.features[tBitsPerSample]; !ok {
300 return nil, FormatError("BitsPerSample tag missing")
301 }
302
303 // Determine the image mode.
304 switch d.firstVal(tPhotometricInterpretation) {
305 case pRGB:
306 for _, b := range d.features[tBitsPerSample] {
307 if b != 8 {
308 return nil, UnsupportedError("non-8-bit RGB imag e")
309 }
310 }
311 d.config.ColorModel = color.RGBAModel
312 // RGB images normally have 3 samples per pixel.
313 // If there are more, ExtraSamples (p. 31-32 of the spec)
314 // gives their meaning (usually an alpha channel).
315 //
316 // This implementation does not support extra samples
317 // of an unspecified type.
318 switch len(d.features[tBitsPerSample]) {
319 case 3:
320 d.mode = mRGB
321 case 4:
322 switch d.firstVal(tExtraSamples) {
323 case 1:
324 d.mode = mRGBA
325 case 2:
326 d.mode = mNRGBA
327 d.config.ColorModel = color.NRGBAModel
328 default:
329 return nil, FormatError("wrong number of samples for RGB")
330 }
331 default:
332 return nil, FormatError("wrong number of samples for RGB ")
333 }
334 case pPaletted:
335 d.mode = mPaletted
336 d.config.ColorModel = color.Palette(d.palette)
337 case pWhiteIsZero:
338 d.mode = mGrayInvert
339 d.config.ColorModel = color.GrayModel
340 case pBlackIsZero:
341 d.mode = mGray
342 d.config.ColorModel = color.GrayModel
343 default:
344 return nil, UnsupportedError("color model")
345 }
346
347 return d, nil
348 }
349
350 // DecodeConfig returns the color model and dimensions of a TIFF image without
351 // decoding the entire image.
352 func DecodeConfig(r io.Reader) (image.Config, error) {
353 d, err := newDecoder(r)
354 if err != nil {
355 return image.Config{}, err
356 }
357 return d.config, nil
358 }
359
360 // Decode reads a TIFF image from r and returns it as an image.Image.
361 // The type of Image returned depends on the contents of the TIFF.
362 func Decode(r io.Reader) (img image.Image, err error) {
363 d, err := newDecoder(r)
364 if err != nil {
365 return
366 }
367
368 // Check if we have the right number of strips, offsets and counts.
369 rps := int(d.firstVal(tRowsPerStrip))
370 if rps == 0 {
371 // Assume only one strip.
372 rps = d.config.Height
373 }
374 numStrips := (d.config.Height + rps - 1) / rps
375 if rps == 0 || len(d.features[tStripOffsets]) < numStrips || len(d.featu res[tStripByteCounts]) < numStrips {
376 return nil, FormatError("inconsistent header")
377 }
378
379 switch d.mode {
380 case mGray, mGrayInvert:
381 img = image.NewGray(image.Rect(0, 0, d.config.Width, d.config.He ight))
382 case mPaletted:
383 img = image.NewPaletted(image.Rect(0, 0, d.config.Width, d.confi g.Height), d.palette)
384 case mNRGBA:
385 img = image.NewNRGBA(image.Rect(0, 0, d.config.Width, d.config.H eight))
386 case mRGB, mRGBA:
387 img = image.NewRGBA(image.Rect(0, 0, d.config.Width, d.config.He ight))
388 }
389
390 for i := 0; i < numStrips; i++ {
391 ymin := i * rps
392 // The last strip may be shorter.
393 if i == numStrips-1 && d.config.Height%rps != 0 {
394 rps = d.config.Height % rps
395 }
396 offset := int64(d.features[tStripOffsets][i])
397 n := int64(d.features[tStripByteCounts][i])
398 switch d.firstVal(tCompression) {
399 case cNone:
400 // TODO(bsiegert): Avoid copy if r is a tiff.buffer.
401 d.buf = make([]byte, n)
402 _, err = d.r.ReadAt(d.buf, offset)
403 case cLZW:
404 r := lzw.NewReader(io.NewSectionReader(d.r, offset, n), lzw.MSB, 8)
405 d.buf, err = ioutil.ReadAll(r)
406 r.Close()
407 case cDeflate, cDeflateOld:
408 r, err := zlib.NewReader(io.NewSectionReader(d.r, offset , n))
409 if err != nil {
410 return nil, err
411 }
412 d.buf, err = ioutil.ReadAll(r)
413 r.Close()
414 case cPackBits:
415 d.buf, err = unpackBits(io.NewSectionReader(d.r, offset, n))
416 default:
417 err = UnsupportedError("compression")
418 }
419 if err != nil {
420 return
421 }
422 err = d.decode(img, ymin, ymin+rps)
423 }
424 return
425 }
426
427 func init() {
428 image.RegisterFormat("tiff", leHeader, Decode, DecodeConfig)
429 image.RegisterFormat("tiff", beHeader, Decode, DecodeConfig)
430 }
OLDNEW
« no previous file with comments | « tiff/consts.go ('k') | tiff/reader_test.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b