mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-11-04 08:42:24 -06:00 
			
		
		
		
	
		
			
	
	
		
			86 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			86 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package pngstructure
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"bufio"
							 | 
						||
| 
								 | 
							
									"bytes"
							 | 
						||
| 
								 | 
							
									"image"
							 | 
						||
| 
								 | 
							
									"io"
							 | 
						||
| 
								 | 
							
									"os"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									"image/png"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									riimage "github.com/dsoprea/go-utility/v2/image"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// PngMediaParser knows how to parse a PNG stream.
							 | 
						||
| 
								 | 
							
								type PngMediaParser struct {
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// NewPngMediaParser returns a new `PngMediaParser`.
							 | 
						||
| 
								 | 
							
								func NewPngMediaParser() riimage.MediaParser {
							 | 
						||
| 
								 | 
							
									return new(PngMediaParser)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Parse parses a PNG stream given a `io.ReadSeeker`.
							 | 
						||
| 
								 | 
							
								func (pmp *PngMediaParser) Parse(
							 | 
						||
| 
								 | 
							
									rs io.ReadSeeker,
							 | 
						||
| 
								 | 
							
									size int,
							 | 
						||
| 
								 | 
							
								) (riimage.MediaContext, error) {
							 | 
						||
| 
								 | 
							
									ps := NewPngSplitter()
							 | 
						||
| 
								 | 
							
									if err := ps.readHeader(rs); err != nil {
							 | 
						||
| 
								 | 
							
										return nil, err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									s := bufio.NewScanner(rs)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Since each segment can be any
							 | 
						||
| 
								 | 
							
									// size, our buffer must be allowed
							 | 
						||
| 
								 | 
							
									// to grow as large as the file.
							 | 
						||
| 
								 | 
							
									buffer := []byte{}
							 | 
						||
| 
								 | 
							
									s.Buffer(buffer, size)
							 | 
						||
| 
								 | 
							
									s.Split(ps.Split)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for s.Scan() {
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if err := s.Err(); err != nil {
							 | 
						||
| 
								 | 
							
										return nil, err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return ps.Chunks()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// ParseFile parses a PNG stream given a file-path.
							 | 
						||
| 
								 | 
							
								func (pmp *PngMediaParser) ParseFile(filepath string) (riimage.MediaContext, error) {
							 | 
						||
| 
								 | 
							
									f, err := os.Open(filepath)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return nil, err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									defer f.Close()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									stat, err := f.Stat()
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return nil, err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									size := stat.Size()
							 | 
						||
| 
								 | 
							
									return pmp.Parse(f, int(size))
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// ParseBytes parses a PNG stream given a byte-slice.
							 | 
						||
| 
								 | 
							
								func (pmp *PngMediaParser) ParseBytes(data []byte) (riimage.MediaContext, error) {
							 | 
						||
| 
								 | 
							
									br := bytes.NewReader(data)
							 | 
						||
| 
								 | 
							
									return pmp.Parse(br, len(data))
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// LooksLikeFormat returns a boolean indicating
							 | 
						||
| 
								 | 
							
								// whether the stream looks like a PNG image.
							 | 
						||
| 
								 | 
							
								func (pmp *PngMediaParser) LooksLikeFormat(data []byte) bool {
							 | 
						||
| 
								 | 
							
									return bytes.Equal(data[:len(PngSignature)], PngSignature[:])
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// GetImage returns an image.Image-compatible struct.
							 | 
						||
| 
								 | 
							
								func (pmp *PngMediaParser) GetImage(r io.Reader) (img image.Image, err error) {
							 | 
						||
| 
								 | 
							
									return png.Decode(r)
							 | 
						||
| 
								 | 
							
								}
							 |