func (editor *Mp3TagEditor) getUnsupportedID3v2Tags(existingTagData []byte) []byte { result := make([]byte, len(existingTagData)) size := 0 for len(existingTagData) > id3v2FrameHeaderSize { frameId := string(existingTagData[0:4]) frameSize := utils.ReadInt32Be(existingTagData[4:8]) stop := false switch frameId { case "\x00\x00\x00\x00": stop = true case "APIC", "COMM", "TALB", "TCON", "TIT2", "TPE1", "TRCK", "TYER", "TDRC": break default: copy(result[size:size+id3v2FrameHeaderSize+frameSize], existingTagData[:id3v2FrameHeaderSize+frameSize]) size += id3v2FrameHeaderSize + frameSize } if stop { break } existingTagData = existingTagData[id3v2FrameHeaderSize+frameSize:] } return result[:size] }
func (editor *Mp3TagEditor) findIDv2Data(version byte, data []byte) []byte { if len(data) < id3v2HeaderSize { return nil } if string(data[0:3]) != id3v2TagMagic { return nil } size := editor.readSyncInt32Be(data[6:10]) if len(data) < id3v2HeaderSize+size || size == 0 { return nil } // wrong version, continue search if data[3] != version || data[4] != 0 { return editor.findIDv2Data(version, data[(id3v2HeaderSize+size):]) } // exclude extended header if any extendedHeaderSize := 0 if data[5]&0x40 != 0 { switch version { case 3: extendedHeaderSize = utils.ReadInt32Be(data[11:15]) + 4 case 4: extendedHeaderSize = editor.readSyncInt32Be(data[11:15]) } } return data[(id3v2HeaderSize + extendedHeaderSize):(id3v2HeaderSize + extendedHeaderSize + size)] }
func (editor *Mp3TagEditor) parseID3v2Tag(data []byte, version int) Tag { if len(data) == 0 { return Tag{} } var tag Tag for len(data) > id3v2FrameHeaderSize { frameId := string(data[0:4]) if frameId == "\x00\x00\x00\x00" { break } frameSize := 0 switch version { case 3: frameSize = utils.ReadInt32Be(data[4:8]) case 4: frameSize = editor.readSyncInt32Be(data[4:8]) } editor.parseID3v2Frame(&tag, frameId, data[id3v2FrameHeaderSize:(id3v2FrameHeaderSize+frameSize)]) data = data[id3v2FrameHeaderSize+frameSize:] } return tag }
func parseVorbisTagPictureField(data []byte, cover *Cover) error { if len(data) < 4 { return errors.New("vorbis picture data is too short to contain a picture") } cover.Type = imageType[byte(utils.ReadInt32Be(data[0:4]))] mimeTypeSize := utils.ReadInt32Be(data[4:8]) if len(data) < 8+mimeTypeSize+4 { return errors.New("vorbis picture data is incomplete") } cover.Mime = string(data[8 : 8+mimeTypeSize]) descriptionSize := utils.ReadInt32Be(data[8+mimeTypeSize : 8+mimeTypeSize+4]) if len(data) < 8+mimeTypeSize+4+descriptionSize+20 { return errors.New("vorbis picture data is incomplete") } cover.Description = string(data[8+mimeTypeSize+4 : 8+mimeTypeSize+4+descriptionSize]) cover.Data = make([]byte, len(data)-(8+mimeTypeSize+4+descriptionSize+20)) copy(cover.Data, data[8+mimeTypeSize+4+descriptionSize+20:]) return nil }