mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	Add Image Diff for SVG files (#14867)
* Added type sniffer. * Switched content detection from base to typesniffer. * Added GuessContentType to Blob. * Moved image info logic to client. Added support for SVG images in diff. * Restore old blocked svg behaviour. * Added missing image formats. * Execute image diff only when container is visible. * add margin to spinner * improve BIN tag on image diffs * Default to render view. * Show image diff on incomplete diff. Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: Lauris BH <lauris@nix.lv>
This commit is contained in:
		@@ -11,13 +11,7 @@ import (
 | 
			
		||||
	"container/list"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"image"
 | 
			
		||||
	"image/color"
 | 
			
		||||
	_ "image/gif"  // for processing gif images
 | 
			
		||||
	_ "image/jpeg" // for processing jpeg images
 | 
			
		||||
	_ "image/png"  // for processing png images
 | 
			
		||||
	"io"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
@@ -81,70 +75,6 @@ func (c *Commit) ParentCount() int {
 | 
			
		||||
	return len(c.Parents)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isImageFile(data []byte) (string, bool) {
 | 
			
		||||
	contentType := http.DetectContentType(data)
 | 
			
		||||
	if strings.Contains(contentType, "image/") {
 | 
			
		||||
		return contentType, true
 | 
			
		||||
	}
 | 
			
		||||
	return contentType, false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsImageFile is a file image type
 | 
			
		||||
func (c *Commit) IsImageFile(name string) bool {
 | 
			
		||||
	blob, err := c.GetBlobByPath(name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dataRc, err := blob.DataAsync()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	defer dataRc.Close()
 | 
			
		||||
	buf := make([]byte, 1024)
 | 
			
		||||
	n, _ := dataRc.Read(buf)
 | 
			
		||||
	buf = buf[:n]
 | 
			
		||||
	_, isImage := isImageFile(buf)
 | 
			
		||||
	return isImage
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ImageMetaData represents metadata of an image file
 | 
			
		||||
type ImageMetaData struct {
 | 
			
		||||
	ColorModel color.Model
 | 
			
		||||
	Width      int
 | 
			
		||||
	Height     int
 | 
			
		||||
	ByteSize   int64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ImageInfo returns information about the dimensions of an image
 | 
			
		||||
func (c *Commit) ImageInfo(name string) (*ImageMetaData, error) {
 | 
			
		||||
	if !c.IsImageFile(name) {
 | 
			
		||||
		return nil, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	blob, err := c.GetBlobByPath(name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	reader, err := blob.DataAsync()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	defer reader.Close()
 | 
			
		||||
	config, _, err := image.DecodeConfig(reader)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	metadata := ImageMetaData{
 | 
			
		||||
		ColorModel: config.ColorModel,
 | 
			
		||||
		Width:      config.Width,
 | 
			
		||||
		Height:     config.Height,
 | 
			
		||||
		ByteSize:   blob.Size(),
 | 
			
		||||
	}
 | 
			
		||||
	return &metadata, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetCommitByPath return the commit of relative path object.
 | 
			
		||||
func (c *Commit) GetCommitByPath(relpath string) (*Commit, error) {
 | 
			
		||||
	return c.repo.getCommitByPathWithID(c.ID, relpath)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user