mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 15:52:25 -05:00 
			
		
		
		
	* start fixing up tests * fix up tests + automate with drone * fiddle with linting * messing about with drone.yml * some more fiddling * hmmm * add cache * add vendor directory * verbose * ci updates * update some little things * update sig
		
			
				
	
	
		
			106 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package pngstructure
 | |
| 
 | |
| import (
 | |
|     "bufio"
 | |
|     "bytes"
 | |
|     "io"
 | |
|     "os"
 | |
| 
 | |
|     "github.com/dsoprea/go-logging"
 | |
|     "github.com/dsoprea/go-utility/image"
 | |
| )
 | |
| 
 | |
| // PngMediaParser knows how to parse a PNG stream.
 | |
| type PngMediaParser struct {
 | |
| }
 | |
| 
 | |
| // NewPngMediaParser returns a new `PngMediaParser` struct.
 | |
| func NewPngMediaParser() *PngMediaParser {
 | |
| 
 | |
|     // TODO(dustin): Add test
 | |
| 
 | |
|     return new(PngMediaParser)
 | |
| }
 | |
| 
 | |
| // Parse parses a PNG stream given a `io.ReadSeeker`.
 | |
| func (pmp *PngMediaParser) Parse(rs io.ReadSeeker, size int) (mc riimage.MediaContext, err error) {
 | |
|     defer func() {
 | |
|         if state := recover(); state != nil {
 | |
|             err = log.Wrap(state.(error))
 | |
|         }
 | |
|     }()
 | |
| 
 | |
|     // TODO(dustin): Add test
 | |
| 
 | |
|     ps := NewPngSplitter()
 | |
| 
 | |
|     err = ps.readHeader(rs)
 | |
|     log.PanicIf(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() != false {
 | |
|     }
 | |
|     log.PanicIf(s.Err())
 | |
| 
 | |
|     return ps.Chunks(), nil
 | |
| }
 | |
| 
 | |
| // ParseFile parses a PNG stream given a file-path.
 | |
| func (pmp *PngMediaParser) ParseFile(filepath string) (mc riimage.MediaContext, err error) {
 | |
|     defer func() {
 | |
|         if state := recover(); state != nil {
 | |
|             err = log.Wrap(state.(error))
 | |
|         }
 | |
|     }()
 | |
| 
 | |
|     f, err := os.Open(filepath)
 | |
|     log.PanicIf(err)
 | |
| 
 | |
|     defer f.Close()
 | |
| 
 | |
|     stat, err := f.Stat()
 | |
|     log.PanicIf(err)
 | |
| 
 | |
|     size := stat.Size()
 | |
| 
 | |
|     chunks, err := pmp.Parse(f, int(size))
 | |
|     log.PanicIf(err)
 | |
| 
 | |
|     return chunks, nil
 | |
| }
 | |
| 
 | |
| // ParseBytes parses a PNG stream given a byte-slice.
 | |
| func (pmp *PngMediaParser) ParseBytes(data []byte) (mc riimage.MediaContext, err error) {
 | |
|     defer func() {
 | |
|         if state := recover(); state != nil {
 | |
|             err = log.Wrap(state.(error))
 | |
|         }
 | |
|     }()
 | |
| 
 | |
|     // TODO(dustin): Add test
 | |
| 
 | |
|     br := bytes.NewReader(data)
 | |
| 
 | |
|     chunks, err := pmp.Parse(br, len(data))
 | |
|     log.PanicIf(err)
 | |
| 
 | |
|     return chunks, nil
 | |
| }
 | |
| 
 | |
| // LooksLikeFormat returns a boolean indicating whether the stream looks like a
 | |
| // PNG image.
 | |
| func (pmp *PngMediaParser) LooksLikeFormat(data []byte) bool {
 | |
|     return bytes.Compare(data[:len(PngSignature)], PngSignature[:]) == 0
 | |
| }
 | |
| 
 | |
| var (
 | |
|     // Enforce interface conformance.
 | |
|     _ riimage.MediaParser = new(PngMediaParser)
 | |
| )
 |