Source file
src/image/gif/reader.go
1
2
3
4
5
6
7
8
9
10
11
12 package gif
13
14 import (
15 "bufio"
16 "compress/lzw"
17 "errors"
18 "fmt"
19 "image"
20 "image/color"
21 "io"
22 )
23
24 var (
25 errNotEnough = errors.New("gif: not enough image data")
26 errTooMuch = errors.New("gif: too much image data")
27 errBadPixel = errors.New("gif: invalid pixel value")
28 )
29
30
31 type reader interface {
32 io.Reader
33 io.ByteReader
34 }
35
36
37 const (
38
39 fColorTable = 1 << 7
40 fInterlace = 1 << 6
41 fColorTableBitsMask = 7
42
43
44 gcTransparentColorSet = 1 << 0
45 gcDisposalMethodMask = 7 << 2
46 )
47
48
49 const (
50 DisposalNone = 0x01
51 DisposalBackground = 0x02
52 DisposalPrevious = 0x03
53 )
54
55
56 const (
57 sExtension = 0x21
58 sImageDescriptor = 0x2C
59 sTrailer = 0x3B
60 )
61
62
63 const (
64 eText = 0x01
65 eGraphicControl = 0xF9
66 eComment = 0xFE
67 eApplication = 0xFF
68 )
69
70 func readFull(r io.Reader, b []byte) error {
71 _, err := io.ReadFull(r, b)
72 if err == io.EOF {
73 err = io.ErrUnexpectedEOF
74 }
75 return err
76 }
77
78 func readByte(r io.ByteReader) (byte, error) {
79 b, err := r.ReadByte()
80 if err == io.EOF {
81 err = io.ErrUnexpectedEOF
82 }
83 return b, err
84 }
85
86
87 type decoder struct {
88 r reader
89
90
91 vers string
92 width int
93 height int
94 loopCount int
95 delayTime int
96 backgroundIndex byte
97 disposalMethod byte
98
99
100 imageFields byte
101
102
103 transparentIndex byte
104 hasTransparentIndex bool
105
106
107 globalColorTable color.Palette
108
109
110 delay []int
111 disposal []byte
112 image []*image.Paletted
113 tmp [1024]byte
114 }
115
116
117
118
119
120
121
122
123
124 type blockReader struct {
125 d *decoder
126 i, j uint8
127 err error
128 }
129
130 func (b *blockReader) fill() {
131 if b.err != nil {
132 return
133 }
134 b.j, b.err = readByte(b.d.r)
135 if b.j == 0 && b.err == nil {
136 b.err = io.EOF
137 }
138 if b.err != nil {
139 return
140 }
141
142 b.i = 0
143 b.err = readFull(b.d.r, b.d.tmp[:b.j])
144 if b.err != nil {
145 b.j = 0
146 }
147 }
148
149 func (b *blockReader) ReadByte() (byte, error) {
150 if b.i == b.j {
151 b.fill()
152 if b.err != nil {
153 return 0, b.err
154 }
155 }
156
157 c := b.d.tmp[b.i]
158 b.i++
159 return c, nil
160 }
161
162
163
164 func (b *blockReader) Read(p []byte) (int, error) {
165 if len(p) == 0 || b.err != nil {
166 return 0, b.err
167 }
168 if b.i == b.j {
169 b.fill()
170 if b.err != nil {
171 return 0, b.err
172 }
173 }
174
175 n := copy(p, b.d.tmp[b.i:b.j])
176 b.i += uint8(n)
177 return n, nil
178 }
179
180
181
182
183
184
185
186
187
188 func (b *blockReader) close() error {
189 if b.err == io.EOF {
190
191 return nil
192 } else if b.err != nil {
193
194 return b.err
195 }
196
197 if b.i == b.j {
198
199
200 b.fill()
201 if b.err == io.EOF {
202 return nil
203 } else if b.err != nil {
204 return b.err
205 } else if b.j > 1 {
206 return errTooMuch
207 }
208 }
209
210
211
212 b.fill()
213 if b.err == io.EOF {
214 return nil
215 } else if b.err != nil {
216 return b.err
217 }
218
219 return errTooMuch
220 }
221
222
223 func (d *decoder) decode(r io.Reader, configOnly, keepAllFrames bool) error {
224
225 if rr, ok := r.(reader); ok {
226 d.r = rr
227 } else {
228 d.r = bufio.NewReader(r)
229 }
230
231 d.loopCount = -1
232
233 err := d.readHeaderAndScreenDescriptor()
234 if err != nil {
235 return err
236 }
237 if configOnly {
238 return nil
239 }
240
241 for {
242 c, err := readByte(d.r)
243 if err != nil {
244 return fmt.Errorf("gif: reading frames: %v", err)
245 }
246 switch c {
247 case sExtension:
248 if err = d.readExtension(); err != nil {
249 return err
250 }
251
252 case sImageDescriptor:
253 if err = d.readImageDescriptor(keepAllFrames); err != nil {
254 return err
255 }
256
257 if !keepAllFrames && len(d.image) == 1 {
258 return nil
259 }
260
261 case sTrailer:
262 if len(d.image) == 0 {
263 return fmt.Errorf("gif: missing image data")
264 }
265 return nil
266
267 default:
268 return fmt.Errorf("gif: unknown block type: 0x%.2x", c)
269 }
270 }
271 }
272
273 func (d *decoder) readHeaderAndScreenDescriptor() error {
274 err := readFull(d.r, d.tmp[:13])
275 if err != nil {
276 return fmt.Errorf("gif: reading header: %v", err)
277 }
278 d.vers = string(d.tmp[:6])
279 if d.vers != "GIF87a" && d.vers != "GIF89a" {
280 return fmt.Errorf("gif: can't recognize format %q", d.vers)
281 }
282 d.width = int(d.tmp[6]) + int(d.tmp[7])<<8
283 d.height = int(d.tmp[8]) + int(d.tmp[9])<<8
284 if fields := d.tmp[10]; fields&fColorTable != 0 {
285 d.backgroundIndex = d.tmp[11]
286
287 if d.globalColorTable, err = d.readColorTable(fields); err != nil {
288 return err
289 }
290 }
291
292 return nil
293 }
294
295 func (d *decoder) readColorTable(fields byte) (color.Palette, error) {
296 n := 1 << (1 + uint(fields&fColorTableBitsMask))
297 err := readFull(d.r, d.tmp[:3*n])
298 if err != nil {
299 return nil, fmt.Errorf("gif: reading color table: %s", err)
300 }
301 j, p := 0, make(color.Palette, n)
302 for i := range p {
303 p[i] = color.RGBA{d.tmp[j+0], d.tmp[j+1], d.tmp[j+2], 0xFF}
304 j += 3
305 }
306 return p, nil
307 }
308
309 func (d *decoder) readExtension() error {
310 extension, err := readByte(d.r)
311 if err != nil {
312 return fmt.Errorf("gif: reading extension: %v", err)
313 }
314 size := 0
315 switch extension {
316 case eText:
317 size = 13
318 case eGraphicControl:
319 return d.readGraphicControl()
320 case eComment:
321
322 case eApplication:
323 b, err := readByte(d.r)
324 if err != nil {
325 return fmt.Errorf("gif: reading extension: %v", err)
326 }
327
328 size = int(b)
329 default:
330 return fmt.Errorf("gif: unknown extension 0x%.2x", extension)
331 }
332 if size > 0 {
333 if err := readFull(d.r, d.tmp[:size]); err != nil {
334 return fmt.Errorf("gif: reading extension: %v", err)
335 }
336 }
337
338
339
340 if extension == eApplication && string(d.tmp[:size]) == "NETSCAPE2.0" {
341 n, err := d.readBlock()
342 if err != nil {
343 return fmt.Errorf("gif: reading extension: %v", err)
344 }
345 if n == 0 {
346 return nil
347 }
348 if n == 3 && d.tmp[0] == 1 {
349 d.loopCount = int(d.tmp[1]) | int(d.tmp[2])<<8
350 }
351 }
352 for {
353 n, err := d.readBlock()
354 if err != nil {
355 return fmt.Errorf("gif: reading extension: %v", err)
356 }
357 if n == 0 {
358 return nil
359 }
360 }
361 }
362
363 func (d *decoder) readGraphicControl() error {
364 if err := readFull(d.r, d.tmp[:6]); err != nil {
365 return fmt.Errorf("gif: can't read graphic control: %s", err)
366 }
367 if d.tmp[0] != 4 {
368 return fmt.Errorf("gif: invalid graphic control extension block size: %d", d.tmp[0])
369 }
370 flags := d.tmp[1]
371 d.disposalMethod = (flags & gcDisposalMethodMask) >> 2
372 d.delayTime = int(d.tmp[2]) | int(d.tmp[3])<<8
373 if flags&gcTransparentColorSet != 0 {
374 d.transparentIndex = d.tmp[4]
375 d.hasTransparentIndex = true
376 }
377 if d.tmp[5] != 0 {
378 return fmt.Errorf("gif: invalid graphic control extension block terminator: %d", d.tmp[5])
379 }
380 return nil
381 }
382
383 func (d *decoder) readImageDescriptor(keepAllFrames bool) error {
384 m, err := d.newImageFromDescriptor()
385 if err != nil {
386 return err
387 }
388 useLocalColorTable := d.imageFields&fColorTable != 0
389 if useLocalColorTable {
390 m.Palette, err = d.readColorTable(d.imageFields)
391 if err != nil {
392 return err
393 }
394 } else {
395 if d.globalColorTable == nil {
396 return errors.New("gif: no color table")
397 }
398 m.Palette = d.globalColorTable
399 }
400 if d.hasTransparentIndex {
401 if !useLocalColorTable {
402
403 m.Palette = append(color.Palette(nil), d.globalColorTable...)
404 }
405 if ti := int(d.transparentIndex); ti < len(m.Palette) {
406 m.Palette[ti] = color.RGBA{}
407 } else {
408
409
410
411
412 p := make(color.Palette, ti+1)
413 copy(p, m.Palette)
414 for i := len(m.Palette); i < len(p); i++ {
415 p[i] = color.RGBA{}
416 }
417 m.Palette = p
418 }
419 }
420 litWidth, err := readByte(d.r)
421 if err != nil {
422 return fmt.Errorf("gif: reading image data: %v", err)
423 }
424 if litWidth < 2 || litWidth > 8 {
425 return fmt.Errorf("gif: pixel size in decode out of range: %d", litWidth)
426 }
427
428 br := &blockReader{d: d}
429 lzwr := lzw.NewReader(br, lzw.LSB, int(litWidth))
430 defer lzwr.Close()
431 if err = readFull(lzwr, m.Pix); err != nil {
432 if err != io.ErrUnexpectedEOF {
433 return fmt.Errorf("gif: reading image data: %v", err)
434 }
435 return errNotEnough
436 }
437
438
439
440
441
442
443
444
445
446
447
448 if n, err := lzwr.Read(d.tmp[256:257]); n != 0 || (err != io.EOF && err != io.ErrUnexpectedEOF) {
449 if err != nil {
450 return fmt.Errorf("gif: reading image data: %v", err)
451 }
452 return errTooMuch
453 }
454
455
456
457 if err := br.close(); err == errTooMuch {
458 return errTooMuch
459 } else if err != nil {
460 return fmt.Errorf("gif: reading image data: %v", err)
461 }
462
463
464 if len(m.Palette) < 256 {
465 for _, pixel := range m.Pix {
466 if int(pixel) >= len(m.Palette) {
467 return errBadPixel
468 }
469 }
470 }
471
472
473 if d.imageFields&fInterlace != 0 {
474 uninterlace(m)
475 }
476
477 if keepAllFrames || len(d.image) == 0 {
478 d.image = append(d.image, m)
479 d.delay = append(d.delay, d.delayTime)
480 d.disposal = append(d.disposal, d.disposalMethod)
481 }
482
483
484
485 d.delayTime = 0
486 d.hasTransparentIndex = false
487 return nil
488 }
489
490 func (d *decoder) newImageFromDescriptor() (*image.Paletted, error) {
491 if err := readFull(d.r, d.tmp[:9]); err != nil {
492 return nil, fmt.Errorf("gif: can't read image descriptor: %s", err)
493 }
494 left := int(d.tmp[0]) + int(d.tmp[1])<<8
495 top := int(d.tmp[2]) + int(d.tmp[3])<<8
496 width := int(d.tmp[4]) + int(d.tmp[5])<<8
497 height := int(d.tmp[6]) + int(d.tmp[7])<<8
498 d.imageFields = d.tmp[8]
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516 if left+width > d.width || top+height > d.height {
517 return nil, errors.New("gif: frame bounds larger than image bounds")
518 }
519 return image.NewPaletted(image.Rectangle{
520 Min: image.Point{left, top},
521 Max: image.Point{left + width, top + height},
522 }, nil), nil
523 }
524
525 func (d *decoder) readBlock() (int, error) {
526 n, err := readByte(d.r)
527 if n == 0 || err != nil {
528 return 0, err
529 }
530 if err := readFull(d.r, d.tmp[:n]); err != nil {
531 return 0, err
532 }
533 return int(n), nil
534 }
535
536
537 type interlaceScan struct {
538 skip, start int
539 }
540
541
542 var interlacing = []interlaceScan{
543 {8, 0},
544 {8, 4},
545 {4, 2},
546 {2, 1},
547 }
548
549
550 func uninterlace(m *image.Paletted) {
551 var nPix []uint8
552 dx := m.Bounds().Dx()
553 dy := m.Bounds().Dy()
554 nPix = make([]uint8, dx*dy)
555 offset := 0
556 for _, pass := range interlacing {
557 nOffset := pass.start * dx
558 for y := pass.start; y < dy; y += pass.skip {
559 copy(nPix[nOffset:nOffset+dx], m.Pix[offset:offset+dx])
560 offset += dx
561 nOffset += dx * pass.skip
562 }
563 }
564 m.Pix = nPix
565 }
566
567
568
569
570
571
572
573
574 func Decode(r io.Reader) (image.Image, error) {
575 var d decoder
576 if err := d.decode(r, false, false); err != nil {
577 return nil, err
578 }
579 return d.image[0], nil
580 }
581
582
583 type GIF struct {
584 Image []*image.Paletted
585 Delay []int
586
587
588
589
590
591 LoopCount int
592
593
594
595
596 Disposal []byte
597
598
599
600
601
602
603
604
605
606 Config image.Config
607
608
609 BackgroundIndex byte
610 }
611
612
613
614
615
616
617
618
619 func DecodeAll(r io.Reader) (*GIF, error) {
620 var d decoder
621 if err := d.decode(r, false, true); err != nil {
622 return nil, err
623 }
624 gif := &GIF{
625 Image: d.image,
626 LoopCount: d.loopCount,
627 Delay: d.delay,
628 Disposal: d.disposal,
629 Config: image.Config{
630 ColorModel: d.globalColorTable,
631 Width: d.width,
632 Height: d.height,
633 },
634 BackgroundIndex: d.backgroundIndex,
635 }
636 return gif, nil
637 }
638
639
640
641
642
643
644
645 func DecodeConfig(r io.Reader) (image.Config, error) {
646 var d decoder
647 if err := d.decode(r, true, false); err != nil {
648 return image.Config{}, err
649 }
650 return image.Config{
651 ColorModel: d.globalColorTable,
652 Width: d.width,
653 Height: d.height,
654 }, nil
655 }
656
657 func init() {
658 image.RegisterFormat("gif", "GIF8?a", Decode, DecodeConfig)
659 }
660
View as plain text