sequence.go
func NewFileSequencePad(sequence string, style PadStyle) (*FileSequence, error) {
	var dir, basename, pad, ext string
	var frameSet *FrameSet
	var err error

	// Determine which style of padding to use
	padder, ok := padders[style]
	if !ok {
		padder = defaultPadding
	}

	parts := splitPattern.FindStringSubmatch(sequence)

	if len(parts) == 0 {
		// If no match at this point, we are dealing with a possible
		// path that contains no range. Maybe a single frame or no frame.

		for _, pad := range defaultPadding.AllChars() {
			if strings.Contains(sequence, pad) {
				return nil, fmt.Errorf("Failed to parse sequence: %s", sequence)
			}
		}
		// We assume the sequence is just a single file path, containing
		// no frame patterns
		dir, basename = filepath.Split(sequence)
		idx := strings.LastIndex(basename, ".")
		if idx > -1 {
			basename, ext = basename[:idx], basename[idx:]
		}

		if dir == "" && basename == "" && ext != "" {
			// Just assume all we have is a file extension

		} else {
			// Try to see if we can at least find a specific frame
			// number, a la  .<frame>.ext
			parts = singleFrame.FindStringSubmatch(sequence)
			if len(parts) > 0 {
				frameStr := parts[2]
				frameSet, err = NewFrameSet(frameStr)
				if err != nil {
					frameSet = nil
				} else {
					// Reparse the dir/basename to not include the trailing frame
					dir, basename = filepath.Split(parts[1])

					// Calculate the padding chars
					pad = padder.PaddingChars(len(strings.TrimSpace(frameStr)))
				}
				ext = parts[3]
			}
		}

	} else {
		// We are dealing with a pattern containing a frame range

		frameSet, err = NewFrameSet(parts[2])
		if err != nil {
			frameSet = nil
		}

		dir, basename = filepath.Split(parts[1])
		pad = parts[3]
		ext = parts[4]
	}

	seq := &FileSequence{
		basename:  basename,
		dir:       dir,
		ext:       ext,
		padChar:   pad,
		zfill:     0, // Fill will be calculated after SetPadding()
		frameSet:  frameSet,
		padMapper: padder,
	}

	seq.SetPadding(pad)

	return seq, nil
}
func NewFileSequencePad(sequence string, style PadStyle) (*FileSequence, error) {
	var dir, basename, pad, ext string
	var frameSet *FrameSet
	var err error

	// Determine which style of padding to use
	padder, ok := padders[style]
	if !ok {
		padder = defaultPadding
	}

	parts := splitPattern.FindStringSubmatch(sequence)

	if len(parts) == 0 {
		// If no match at this point, we are dealing with a possible
		// path that contains no range. Maybe a single frame or no frame.

		for _, pad := range defaultPadding.AllChars() {
			if strings.Contains(sequence, pad) {
				return nil, fmt.Errorf("Failed to parse sequence: %s", sequence)
			}
		}
		// We assume the sequence is just a single file path, containing
		// no frame patterns
		dir, basename = filepath.Split(sequence)
		idx := strings.LastIndex(basename, ".")
		if idx > -1 {
			basename, ext = basename[:idx], basename[idx:]
		}

		if dir == "" && basename == "" && ext != "" {
			// Just assume all we have is a file extension

		} else {
			// Try to see if we can at least find a specific frame
			// number, a la  .<frame>.ext
			parts = singleFrame.FindStringSubmatch(sequence)
			if len(parts) > 0 {
				frameStr := parts[2]
				frameSet, err = NewFrameSet(frameStr)
				if err != nil {
					frameSet = nil
				} else {
					// Reparse the dir/basename to not include the trailing frame
					dir, basename = filepath.Split(parts[1])

					// Calculate the padding chars
					pad = padder.PaddingChars(len(strings.TrimSpace(frameStr)))
				}
				ext = parts[3]
			}
		}

	} else {
		// We are dealing with a pattern containing a frame range

		frameSet, err = NewFrameSet(parts[2])
		if err != nil {
			frameSet = nil
		}

		dir, basename = filepath.Split(parts[1])
		pad = parts[3]
		ext = parts[4]
	}

	seq := &FileSequence{
		basename:  basename,
		dir:       dir,
		ext:       ext,
		padChar:   pad,
		zfill:     0, // Fill will be calculated after SetPadding()
		frameSet:  frameSet,
		padMapper: padder,
	}

	seq.SetPadding(pad)

	return seq, nil
}
// NewFileSequencePad returns a FileSequence from a string
// sequence path. The path should be a valid sequence, expressing
// a frame range, or a single file path.
// If error is non-nil, then the given sequence string could not
// be successfully parsed.
//
// The sequence uses the style of padding given, in
// order to convert between padding characters and their numeric width.
//
// Example path w/ PadStyleHash1:
//     /path/to/image_foo.1-10x2#.jpg => /path/to/image_foo.1.jpg ...
//     /path/to/image_foo.1-10x2@.jpg => /path/to/image_foo.1.jpg ...
//     /path/to/image_foo.1-10x2##.jpg => /path/to/image_foo.01.jpg ...
//
// Example path w/ PadStyleHash4:
//     /path/to/image_foo.1-10x2#.jpg => /path/to/image_foo.0001.jpg ...
//     /path/to/image_foo.1-10x2@.jpg => /path/to/image_foo.1.jpg ...
//     /path/to/image_foo.1-10x2##.jpg => /path/to/image_foo.00000001.jpg ...
//