Beispiel #1
0
Datei: main.go Projekt: oov/psd
func main() {
	if len(os.Args) < 2 {
		fmt.Printf("USAGE: %s psdfile", os.Args[0])
		return
	}
	file, err := os.Open(os.Args[1])
	if err != nil {
		panic(err)
	}
	defer file.Close()

	img, _, err := psd.Decode(file, &psd.DecodeOptions{SkipMergedImage: true})
	if err != nil {
		panic(err)
	}
	for i, layer := range img.Layer {
		if err = processLayer(fmt.Sprintf("%03d", i), layer.Name, &layer); err != nil {
			panic(err)
		}
	}
}
Beispiel #2
0
func parse(rd readerAt, progress func(progress float64), makeCanvas func(seqID int, layer *psd.Layer)) (*root, error) {
	var r root
	s := time.Now().UnixNano()

	if rd.Size() < 4 {
		return nil, errors.New("unsupported file type")
	}
	var head [4]byte
	if _, err := rd.ReadAt(head[:], 0); err != nil {
		return nil, err
	}
	var psdReader *genericProgressReader
	switch string(head[:]) {
	case "PK\x03\x04": // zip archive
		zr, err := zip.NewReader(rd, rd.Size())
		if err != nil {
			return nil, err
		}
		var psdf, pfvf, txtf *zip.File
		for _, f := range zr.File {
			if psdf == nil && strings.ToLower(f.Name[len(f.Name)-4:]) == ".psd" {
				psdf = f
				continue
			}
			if psdf == nil && strings.ToLower(f.Name[len(f.Name)-4:]) == ".psb" {
				psdf = f
				continue
			}
			if pfvf == nil && strings.ToLower(f.Name[len(f.Name)-4:]) == ".pfv" {
				pfvf = f
				continue
			}
			if txtf == nil && strings.ToLower(f.Name[len(f.Name)-4:]) == ".txt" {
				txtf = f
				continue
			}
		}
		if psdf == nil {
			return nil, errors.New("psd file is not found from given zip archive")
		}

		if pfvf != nil {
			var pfvr io.ReadCloser
			pfvr, err = pfvf.Open()
			if err != nil {
				return nil, err
			}
			defer pfvr.Close()
			r.PFVModDate = pfvf.ModTime().Unix()
			r.PFV, err = readTextFile(pfvr)
			if err != nil {
				return nil, err
			}
		}

		if txtf != nil {
			var txtr io.ReadCloser
			txtr, err = txtf.Open()
			if err != nil {
				return nil, err
			}
			defer txtr.Close()
			r.Readme, err = readTextFile(txtr)
			if err != nil {
				return nil, err
			}
		}

		rc, err := zipFileOpenFast(rd, psdf, 1024*1024*100)
		if err != nil {
			return nil, err
		}
		defer rc.Close()
		psdReader = &genericProgressReader{
			R:        rc,
			Hash:     md5.New(),
			Progress: progress,
			size:     int(psdf.UncompressedSize64),
		}
	case "7z\xbc\xaf": // 7z archive
		return nil, errors.New("7z archive is not supported")
	case "8BPS": // psd file
		psdReader = &genericProgressReader{
			R:        bufio.NewReaderSize(rd, 1024*1024*2),
			Hash:     md5.New(),
			Progress: progress,
			size:     int(rd.Size()),
		}
		break
	default:
		return nil, errors.New("unsupported file type")
	}
	psdImg, _, err := psd.Decode(psdReader, &psd.DecodeOptions{
		LayerImageLoaded: func(layer *psd.Layer, index int, total int) {
			makeCanvas(index, layer)
			layer.Picker = nil
			layer.Channel = nil
		},
		SkipMergedImage: true,
	})
	if err != nil {
		return nil, err
	}
	e := time.Now().UnixNano()
	progress(1)
	log.Println("decode PSD structure:", (e-s)/1e6)

	if psdImg.Config.ColorMode != psd.ColorModeRGB {
		return nil, errors.New("Unsupported color mode")
	}

	s = time.Now().UnixNano()
	r.Hash = fmt.Sprintf("%x", psdReader.Sum())
	if err = r.Build(psdImg); err != nil {
		return nil, err
	}
	e = time.Now().UnixNano()
	log.Println("build layer tree:", (e-s)/1e6)
	return &r, nil
}