OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [image/] [gif/] [reader.go] - Blame information for rev 801

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// 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 gif implements a GIF image decoder.
6
//
7
// The GIF specification is at http://www.w3.org/Graphics/GIF/spec-gif89a.txt.
8
package gif
9
 
10
import (
11
        "bufio"
12
        "compress/lzw"
13
        "errors"
14
        "fmt"
15
        "image"
16
        "image/color"
17
        "io"
18
)
19
 
20
// If the io.Reader does not also have ReadByte, then decode will introduce its own buffering.
21
type reader interface {
22
        io.Reader
23
        io.ByteReader
24
}
25
 
26
// Masks etc.
27
const (
28
        // Fields.
29
        fColorMapFollows = 1 << 7
30
 
31
        // Image fields.
32
        ifLocalColorTable = 1 << 7
33
        ifInterlace       = 1 << 6
34
        ifPixelSizeMask   = 7
35
 
36
        // Graphic control flags.
37
        gcTransparentColorSet = 1 << 0
38
)
39
 
40
// Section indicators.
41
const (
42
        sExtension       = 0x21
43
        sImageDescriptor = 0x2C
44
        sTrailer         = 0x3B
45
)
46
 
47
// Extensions.
48
const (
49
        eText           = 0x01 // Plain Text
50
        eGraphicControl = 0xF9 // Graphic Control
51
        eComment        = 0xFE // Comment
52
        eApplication    = 0xFF // Application
53
)
54
 
55
// decoder is the type used to decode a GIF file.
56
type decoder struct {
57
        r reader
58
 
59
        // From header.
60
        vers            string
61
        width           int
62
        height          int
63
        flags           byte
64
        headerFields    byte
65
        backgroundIndex byte
66
        loopCount       int
67
        delayTime       int
68
 
69
        // Unused from header.
70
        aspect byte
71
 
72
        // From image descriptor.
73
        imageFields byte
74
 
75
        // From graphics control.
76
        transparentIndex byte
77
 
78
        // Computed.
79
        pixelSize      uint
80
        globalColorMap color.Palette
81
 
82
        // Used when decoding.
83
        delay []int
84
        image []*image.Paletted
85
        tmp   [1024]byte // must be at least 768 so we can read color map
86
}
87
 
88
// blockReader parses the block structure of GIF image data, which
89
// comprises (n, (n bytes)) blocks, with 1 <= n <= 255.  It is the
90
// reader given to the LZW decoder, which is thus immune to the
91
// blocking.  After the LZW decoder completes, there will be a 0-byte
92
// block remaining (0, ()), but under normal execution blockReader
93
// doesn't consume it, so it is handled in decode.
94
type blockReader struct {
95
        r     reader
96
        slice []byte
97
        tmp   [256]byte
98
}
99
 
100
func (b *blockReader) Read(p []byte) (int, error) {
101
        if len(p) == 0 {
102
                return 0, nil
103
        }
104
        if len(b.slice) == 0 {
105
                blockLen, err := b.r.ReadByte()
106
                if err != nil {
107
                        return 0, err
108
                }
109
                if blockLen == 0 {
110
                        return 0, io.EOF
111
                }
112
                b.slice = b.tmp[0:blockLen]
113
                if _, err = io.ReadFull(b.r, b.slice); err != nil {
114
                        return 0, err
115
                }
116
        }
117
        n := copy(p, b.slice)
118
        b.slice = b.slice[n:]
119
        return n, nil
120
}
121
 
122
// decode reads a GIF image from r and stores the result in d.
123
func (d *decoder) decode(r io.Reader, configOnly bool) error {
124
        // Add buffering if r does not provide ReadByte.
125
        if rr, ok := r.(reader); ok {
126
                d.r = rr
127
        } else {
128
                d.r = bufio.NewReader(r)
129
        }
130
 
131
        err := d.readHeaderAndScreenDescriptor()
132
        if err != nil {
133
                return err
134
        }
135
        if configOnly {
136
                return nil
137
        }
138
 
139
        if d.headerFields&fColorMapFollows != 0 {
140
                if d.globalColorMap, err = d.readColorMap(); err != nil {
141
                        return err
142
                }
143
        }
144
 
145
Loop:
146
        for err == nil {
147
                var c byte
148
                c, err = d.r.ReadByte()
149
                if err == io.EOF {
150
                        break
151
                }
152
                switch c {
153
                case sExtension:
154
                        err = d.readExtension()
155
 
156
                case sImageDescriptor:
157
                        var m *image.Paletted
158
                        m, err = d.newImageFromDescriptor()
159
                        if err != nil {
160
                                break
161
                        }
162
                        if d.imageFields&fColorMapFollows != 0 {
163
                                m.Palette, err = d.readColorMap()
164
                                if err != nil {
165
                                        break
166
                                }
167
                                // TODO: do we set transparency in this map too? That would be
168
                                // d.setTransparency(m.Palette)
169
                        } else {
170
                                m.Palette = d.globalColorMap
171
                        }
172
                        var litWidth uint8
173
                        litWidth, err = d.r.ReadByte()
174
                        if err != nil {
175
                                return err
176
                        }
177
                        if litWidth < 2 || litWidth > 8 {
178
                                return fmt.Errorf("gif: pixel size in decode out of range: %d", litWidth)
179
                        }
180
                        // A wonderfully Go-like piece of magic.
181
                        lzwr := lzw.NewReader(&blockReader{r: d.r}, lzw.LSB, int(litWidth))
182
                        if _, err = io.ReadFull(lzwr, m.Pix); err != nil {
183
                                break
184
                        }
185
 
186
                        // There should be a "0" block remaining; drain that.
187
                        c, err = d.r.ReadByte()
188
                        if err != nil {
189
                                return err
190
                        }
191
                        if c != 0 {
192
                                return errors.New("gif: extra data after image")
193
                        }
194
 
195
                        // Undo the interlacing if necessary.
196
                        if d.imageFields&ifInterlace != 0 {
197
                                uninterlace(m)
198
                        }
199
 
200
                        d.image = append(d.image, m)
201
                        d.delay = append(d.delay, d.delayTime)
202
                        d.delayTime = 0 // TODO: is this correct, or should we hold on to the value?
203
 
204
                case sTrailer:
205
                        break Loop
206
 
207
                default:
208
                        err = fmt.Errorf("gif: unknown block type: 0x%.2x", c)
209
                }
210
        }
211
        if err != nil {
212
                return err
213
        }
214
        if len(d.image) == 0 {
215
                return io.ErrUnexpectedEOF
216
        }
217
        return nil
218
}
219
 
220
func (d *decoder) readHeaderAndScreenDescriptor() error {
221
        _, err := io.ReadFull(d.r, d.tmp[0:13])
222
        if err != nil {
223
                return err
224
        }
225
        d.vers = string(d.tmp[0:6])
226
        if d.vers != "GIF87a" && d.vers != "GIF89a" {
227
                return fmt.Errorf("gif: can't recognize format %s", d.vers)
228
        }
229
        d.width = int(d.tmp[6]) + int(d.tmp[7])<<8
230
        d.height = int(d.tmp[8]) + int(d.tmp[9])<<8
231
        d.headerFields = d.tmp[10]
232
        d.backgroundIndex = d.tmp[11]
233
        d.aspect = d.tmp[12]
234
        d.loopCount = -1
235
        d.pixelSize = uint(d.headerFields&7) + 1
236
        return nil
237
}
238
 
239
func (d *decoder) readColorMap() (color.Palette, error) {
240
        if d.pixelSize > 8 {
241
                return nil, fmt.Errorf("gif: can't handle %d bits per pixel", d.pixelSize)
242
        }
243
        numColors := 1 << d.pixelSize
244
        if d.imageFields&ifLocalColorTable != 0 {
245
                numColors = 1 << ((d.imageFields & ifPixelSizeMask) + 1)
246
        }
247
        numValues := 3 * numColors
248
        _, err := io.ReadFull(d.r, d.tmp[0:numValues])
249
        if err != nil {
250
                return nil, fmt.Errorf("gif: short read on color map: %s", err)
251
        }
252
        colorMap := make(color.Palette, numColors)
253
        j := 0
254
        for i := range colorMap {
255
                colorMap[i] = color.RGBA{d.tmp[j+0], d.tmp[j+1], d.tmp[j+2], 0xFF}
256
                j += 3
257
        }
258
        return colorMap, nil
259
}
260
 
261
func (d *decoder) readExtension() error {
262
        extension, err := d.r.ReadByte()
263
        if err != nil {
264
                return err
265
        }
266
        size := 0
267
        switch extension {
268
        case eText:
269
                size = 13
270
        case eGraphicControl:
271
                return d.readGraphicControl()
272
        case eComment:
273
                // nothing to do but read the data.
274
        case eApplication:
275
                b, err := d.r.ReadByte()
276
                if err != nil {
277
                        return err
278
                }
279
                // The spec requires size be 11, but Adobe sometimes uses 10.
280
                size = int(b)
281
        default:
282
                return fmt.Errorf("gif: unknown extension 0x%.2x", extension)
283
        }
284
        if size > 0 {
285
                if _, err := io.ReadFull(d.r, d.tmp[0:size]); err != nil {
286
                        return err
287
                }
288
        }
289
 
290
        // Application Extension with "NETSCAPE2.0" as string and 1 in data means
291
        // this extension defines a loop count.
292
        if extension == eApplication && string(d.tmp[:size]) == "NETSCAPE2.0" {
293
                n, err := d.readBlock()
294
                if n == 0 || err != nil {
295
                        return err
296
                }
297
                if n == 3 && d.tmp[0] == 1 {
298
                        d.loopCount = int(d.tmp[1]) | int(d.tmp[2])<<8
299
                }
300
        }
301
        for {
302
                n, err := d.readBlock()
303
                if n == 0 || err != nil {
304
                        return err
305
                }
306
        }
307
        panic("unreachable")
308
}
309
 
310
func (d *decoder) readGraphicControl() error {
311
        if _, err := io.ReadFull(d.r, d.tmp[0:6]); err != nil {
312
                return fmt.Errorf("gif: can't read graphic control: %s", err)
313
        }
314
        d.flags = d.tmp[1]
315
        d.delayTime = int(d.tmp[2]) | int(d.tmp[3])<<8
316
        if d.flags&gcTransparentColorSet != 0 {
317
                d.transparentIndex = d.tmp[4]
318
                d.setTransparency(d.globalColorMap)
319
        }
320
        return nil
321
}
322
 
323
func (d *decoder) setTransparency(colorMap color.Palette) {
324
        if int(d.transparentIndex) < len(colorMap) {
325
                colorMap[d.transparentIndex] = color.RGBA{}
326
        }
327
}
328
 
329
func (d *decoder) newImageFromDescriptor() (*image.Paletted, error) {
330
        if _, err := io.ReadFull(d.r, d.tmp[0:9]); err != nil {
331
                return nil, fmt.Errorf("gif: can't read image descriptor: %s", err)
332
        }
333
        left := int(d.tmp[0]) + int(d.tmp[1])<<8
334
        top := int(d.tmp[2]) + int(d.tmp[3])<<8
335
        width := int(d.tmp[4]) + int(d.tmp[5])<<8
336
        height := int(d.tmp[6]) + int(d.tmp[7])<<8
337
        d.imageFields = d.tmp[8]
338
        return image.NewPaletted(image.Rect(left, top, left+width, top+height), nil), nil
339
}
340
 
341
func (d *decoder) readBlock() (int, error) {
342
        n, err := d.r.ReadByte()
343
        if n == 0 || err != nil {
344
                return 0, err
345
        }
346
        return io.ReadFull(d.r, d.tmp[0:n])
347
}
348
 
349
// interlaceScan defines the ordering for a pass of the interlace algorithm.
350
type interlaceScan struct {
351
        skip, start int
352
}
353
 
354
// interlacing represents the set of scans in an interlaced GIF image.
355
var interlacing = []interlaceScan{
356
        {8, 0}, // Group 1 : Every 8th. row, starting with row 0.
357
        {8, 4}, // Group 2 : Every 8th. row, starting with row 4.
358
        {4, 2}, // Group 3 : Every 4th. row, starting with row 2.
359
        {2, 1}, // Group 4 : Every 2nd. row, starting with row 1.
360
}
361
 
362
// uninterlace rearranges the pixels in m to account for interlaced input.
363
func uninterlace(m *image.Paletted) {
364
        var nPix []uint8
365
        dx := m.Bounds().Dx()
366
        dy := m.Bounds().Dy()
367
        nPix = make([]uint8, dx*dy)
368
        offset := 0 // steps through the input by sequential scan lines.
369
        for _, pass := range interlacing {
370
                nOffset := pass.start * dx // steps through the output as defined by pass.
371
                for y := pass.start; y < dy; y += pass.skip {
372
                        copy(nPix[nOffset:nOffset+dx], m.Pix[offset:offset+dx])
373
                        offset += dx
374
                        nOffset += dx * pass.skip
375
                }
376
        }
377
        m.Pix = nPix
378
}
379
 
380
// Decode reads a GIF image from r and returns the first embedded
381
// image as an image.Image.
382
func Decode(r io.Reader) (image.Image, error) {
383
        var d decoder
384
        if err := d.decode(r, false); err != nil {
385
                return nil, err
386
        }
387
        return d.image[0], nil
388
}
389
 
390
// GIF represents the possibly multiple images stored in a GIF file.
391
type GIF struct {
392
        Image     []*image.Paletted // The successive images.
393
        Delay     []int             // The successive delay times, one per frame, in 100ths of a second.
394
        LoopCount int               // The loop count.
395
}
396
 
397
// DecodeAll reads a GIF image from r and returns the sequential frames
398
// and timing information.
399
func DecodeAll(r io.Reader) (*GIF, error) {
400
        var d decoder
401
        if err := d.decode(r, false); err != nil {
402
                return nil, err
403
        }
404
        gif := &GIF{
405
                Image:     d.image,
406
                LoopCount: d.loopCount,
407
                Delay:     d.delay,
408
        }
409
        return gif, nil
410
}
411
 
412
// DecodeConfig returns the global color model and dimensions of a GIF image
413
// without decoding the entire image.
414
func DecodeConfig(r io.Reader) (image.Config, error) {
415
        var d decoder
416
        if err := d.decode(r, true); err != nil {
417
                return image.Config{}, err
418
        }
419
        return image.Config{
420
                ColorModel: d.globalColorMap,
421
                Width:      d.width,
422
                Height:     d.height,
423
        }, nil
424
}
425
 
426
func init() {
427
        image.RegisterFormat("gif", "GIF8?a", Decode, DecodeConfig)
428
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.