コード例 #1
0
/**
 * Returns the content type corresponding to the supplied file extension.
 * The mapping is determined using Uniform Type Identifiers (UTIs).  If
 * the file extension parameter is NULL, a CFString cannot be created
 * from the file extension parameter, there is no UTI corresponding to
 * the file extension, the UTI cannot supply a MIME type for the file
 * extension, or a Java string cannot be created, then NULL is returned;
 * otherwise the MIME type string is returned.
 */
JNIEXPORT jstring JNICALL
Java_sun_nio_fs_UTIFileTypeDetector_probe0(JNIEnv* env, jobject ftd,
                                           jstring ext)
{
    jstring result = NULL;

    CFStringRef extension = toCFString(env, ext);
    if (extension != NULL) {
        CFStringRef uti =
            UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,
                                                  extension, NULL);
        CFRelease(extension);

        if (uti != NULL) {
            CFStringRef mimeType =
                UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType);
            CFRelease(uti);

            if (mimeType != NULL) {
                result = toJavaString(env, mimeType);
                CFRelease(mimeType);
            }
        }
    }

    return result;
}
コード例 #2
0
ファイル: qmime_mac.cpp プロジェクト: FilipBE/qtextended
bool QMacPasteboardMimeQt3Any::canConvert(const QString &mime, QString flav)
{
    loadMimeRegistry();
    const int os_flav = UTGetOSTypeFromString(UTTypeCopyPreferredTagWithClass(QCFString(flav), kUTTagClassOSType));
    if(mime_registry.contains(mime) && mime_registry[mime] == os_flav)
        return true;
    return false;
}
コード例 #3
0
ファイル: qmime_mac.cpp プロジェクト: FilipBE/qtextended
QString QMacPasteboardMimeQt3Any::mimeFor(QString flav)
{
    loadMimeRegistry();
    const int os_flav = UTGetOSTypeFromString(UTTypeCopyPreferredTagWithClass(QCFString(flav), kUTTagClassOSType));
    for(QMap<QString, int>::const_iterator it = mime_registry.constBegin();
        it != mime_registry.constEnd(); ++it) {
        if(it.value() == os_flav)
            return QString::fromLatin1(it.key().toLatin1());
    }
    return QString();
}
コード例 #4
0
ファイル: mimetype.cpp プロジェクト: chromylei/third_party
// Look up the (locale) display name and icon file associated with a UTI
void wxMimeTypesManagerImpl::LoadDisplayDataForUti(const wxString& uti)
{
    // Keys in to Info.plist
    const static wxCFStringRef docTypesKey( "CFBundleDocumentTypes" );
    const static wxCFStringRef descKey( "CFBundleTypeName" );
    const static wxCFStringRef iconKey( "CFBundleTypeIconFile" );

    // The call for finding the preferred application for a UTI is LSCopyDefaultRoleHandlerForContentType
    // This returns an empty string on OS X 10.5
    // Instead it is necessary to get the primary extension and use LSGetApplicationForInfo
    wxCFStringRef ext = UTTypeCopyPreferredTagWithClass( wxCFStringRef( uti ), kUTTagClassFilenameExtension );

    // Look up the preferred application
    CFURLRef appUrl;
    OSStatus status = LSGetApplicationForInfo( kLSUnknownType, kLSUnknownCreator, ext, kLSRolesAll, NULL, &appUrl );

    if( status != noErr )
        return;

    // Create a bundle object for that application
    wxCFRef< CFBundleRef > bundle;
    bundle = wxCFRef< CFBundleRef >( CFBundleCreate( kCFAllocatorDefault, appUrl ) );

    if( !bundle )
        return;

    // Also get the open command while we have the bundle
    wxCFStringRef cfsAppPath(CFURLCopyFileSystemPath(appUrl, kCFURLPOSIXPathStyle));
    m_utiMap[ uti ].application = cfsAppPath.AsString();

    // Get all the document type data in this bundle
    CFTypeRef docTypeData;
    docTypeData = CFBundleGetValueForInfoDictionaryKey( bundle, docTypesKey );

    if( !docTypeData )
        return;

    // Find the document type entry that matches ext
    CFDictionaryRef docType;
    docType = GetDocTypeForExt( docTypeData, ext );

    if( !docType )
        return;

    // Get the display name for docType
    wxCFStringRef description = reinterpret_cast< CFStringRef >( CFDictionaryGetValue( docType, descKey ) );
    wxCFRetain( description.get() );
    m_utiMap[ uti ].description = description.AsString();

    // Get the icon path for docType
    CFStringRef iconFile = reinterpret_cast< CFStringRef > ( CFDictionaryGetValue( docType, iconKey ) );
    m_utiMap[ uti ].iconLoc.SetFileName( GetPathForIconFile( bundle, iconFile ) );
}
コード例 #5
0
ファイル: qclipboard_mac.cpp プロジェクト: Afreeca/qt
bool
QMacPasteboard::hasOSType(int c_flavor) const
{
    if (!paste)
        return false;

    sync();

    ItemCount cnt = 0;
    if(PasteboardGetItemCount(paste, &cnt) || !cnt)
        return false;

#ifdef DEBUG_PASTEBOARD
    qDebug("PasteBoard: hasOSType [%c%c%c%c]", (c_flavor>>24)&0xFF, (c_flavor>>16)&0xFF,
           (c_flavor>>8)&0xFF, (c_flavor>>0)&0xFF);
#endif
    for(uint index = 1; index <= cnt; ++index) {

        PasteboardItemID id;
        if(PasteboardGetItemIdentifier(paste, index, &id) != noErr)
            return false;

        QCFType<CFArrayRef> types;
        if(PasteboardCopyItemFlavors(paste, id, &types ) != noErr)
            return false;

        const int type_count = CFArrayGetCount(types);
        for(int i = 0; i < type_count; ++i) {
            CFStringRef flavor = (CFStringRef)CFArrayGetValueAtIndex(types, i);
            const int os_flavor = UTGetOSTypeFromString(UTTypeCopyPreferredTagWithClass(flavor, kUTTagClassOSType));
            if(os_flavor == c_flavor) {
#ifdef DEBUG_PASTEBOARD
                qDebug("  - Found!");
#endif
                return true;
            }
        }
    }
#ifdef DEBUG_PASTEBOARD
    qDebug("  - NotFound!");
#endif
    return false;
}
コード例 #6
0
ファイル: nglPath_Unix.cpp プロジェクト: JamesLinus/nui3
static nglString GetMimeType(const nglString& extension)
{
  CFStringRef mimeType = NULL;
  CFStringRef ext = extension.ToCFString();

  CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, ext, NULL);
  CFRelease(ext);
  if (!UTI)
    return nglString::Null;

  mimeType = UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType);
  if (!mimeType) // check for edge case
  {
    return nglString::Null;
  }

  CFRelease(UTI);
  nglString mime(mimeType);
  CFRelease(mimeType);
  return mime;
}
コード例 #7
0
bool FLACMetadata::WriteMetadata(CFErrorRef *error)
{
	UInt8 buf [PATH_MAX];
	if(!CFURLGetFileSystemRepresentation(mURL, false, buf, PATH_MAX))
		return false;

	auto stream = new TagLib::FileStream(reinterpret_cast<const char *>(buf));
	TagLib::FLAC::File file(stream, TagLib::ID3v2::FrameFactory::instance(), false);

	if(!file.isValid()) {
		if(error) {
			CFStringRef description = CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), "");
			CFStringRef failureReason = CFCopyLocalizedString(CFSTR("Not a FLAC file"), "");
			CFStringRef recoverySuggestion = CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), "");
			
			*error = CreateErrorForURL(AudioMetadataErrorDomain, AudioMetadataInputOutputError, description, mURL, failureReason, recoverySuggestion);
			
			CFRelease(description), description = nullptr;
			CFRelease(failureReason), failureReason = nullptr;
			CFRelease(recoverySuggestion), recoverySuggestion = nullptr;
		}

		return false;
	}

	SetXiphCommentFromMetadata(*this, file.xiphComment(), false);

	// Remove existing cover art
	file.removePictures();

	// Add album art
	for(auto attachedPicture : GetAttachedPictures()) {
	
		CGImageSourceRef imageSource = CGImageSourceCreateWithData(attachedPicture->GetData(), nullptr);
		if(nullptr == imageSource) {
			LOGGER_ERR("org.sbooth.AudioEngine.AudioMetadata.FLAC", "Skipping album art (unable to create image)");
			continue;
		}

		TagLib::FLAC::Picture *picture = new TagLib::FLAC::Picture;
		picture->setData(TagLib::ByteVector((const char *)CFDataGetBytePtr(attachedPicture->GetData()), (TagLib::uint)CFDataGetLength(attachedPicture->GetData())));
		picture->setType(static_cast<TagLib::FLAC::Picture::Type>(attachedPicture->GetType()));
		if(attachedPicture->GetDescription())
			picture->setDescription(TagLib::StringFromCFString(attachedPicture->GetDescription()));

		// Convert the image's UTI into a MIME type
		CFStringRef mimeType = UTTypeCopyPreferredTagWithClass(CGImageSourceGetType(imageSource), kUTTagClassMIMEType);
		if(mimeType) {
			picture->setMimeType(TagLib::StringFromCFString(mimeType));
			CFRelease(mimeType), mimeType = nullptr;
		}

		// Flesh out the height, width, and depth
		CFDictionaryRef imagePropertiesDictionary = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nullptr);
		if(imagePropertiesDictionary) {
			CFNumberRef imageWidth = (CFNumberRef)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyPixelWidth);
			CFNumberRef imageHeight = (CFNumberRef)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyPixelHeight);
			CFNumberRef imageDepth = (CFNumberRef)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyDepth);

			int height, width, depth;

			// Ignore numeric conversion errors
			CFNumberGetValue(imageWidth, kCFNumberIntType, &width);
			CFNumberGetValue(imageHeight, kCFNumberIntType, &height);
			CFNumberGetValue(imageDepth, kCFNumberIntType, &depth);

			picture->setHeight(height);
			picture->setWidth(width);
			picture->setColorDepth(depth);

			CFRelease(imagePropertiesDictionary), imagePropertiesDictionary = nullptr;
		}

		file.addPicture(picture);

		CFRelease(imageSource), imageSource = nullptr;
	}

	if(!file.save()) {
		if(error) {
			CFStringRef description = CFCopyLocalizedString(CFSTR("The file “%@” is not a valid FLAC file."), "");
			CFStringRef failureReason = CFCopyLocalizedString(CFSTR("Unable to write metadata"), "");
			CFStringRef recoverySuggestion = CFCopyLocalizedString(CFSTR("The file's extension may not match the file's type."), "");
			
			*error = CreateErrorForURL(AudioMetadataErrorDomain, AudioMetadataInputOutputError, description, mURL, failureReason, recoverySuggestion);
			
			CFRelease(description), description = nullptr;
			CFRelease(failureReason), failureReason = nullptr;
			CFRelease(recoverySuggestion), recoverySuggestion = nullptr;
		}

		return false;
	}

	MergeChangedMetadataIntoMetadata();

	return true;
}
コード例 #8
0
bool SFB::Audio::SetID3v2TagFromMetadata(const Metadata& metadata, TagLib::ID3v2::Tag *tag, bool setAlbumArt)
{
	if(nullptr == tag)
		return false;
	
	// Use UTF-8 as the default encoding
	(TagLib::ID3v2::FrameFactory::instance())->setDefaultTextEncoding(TagLib::String::UTF8);

	// Album title
	tag->setAlbum(TagLib::StringFromCFString(metadata.GetAlbumTitle()));

	// Artist
	tag->setArtist(TagLib::StringFromCFString(metadata.GetArtist()));
	
	// Composer
	tag->removeFrames("TCOM");
	if(metadata.GetComposer()) {
		auto frame = new TagLib::ID3v2::TextIdentificationFrame("TCOM", TagLib::String::Latin1);
		frame->setText(TagLib::StringFromCFString(metadata.GetComposer()));
		tag->addFrame(frame);
	}
	
	// Genre
	tag->setGenre(TagLib::StringFromCFString(metadata.GetGenre()));
	
	// Date
#if 1
	int year = 0;
	if(metadata.GetReleaseDate())
		year = CFStringGetIntValue(metadata.GetReleaseDate());
	tag->setYear((TagLib::uint)year);
#else
	// TODO: Parse the release date into components and set the frame appropriately
	tag->removeFrames("TDRC");
	if(metadata.GetReleaseDate()) {
		/*
		 The timestamp fields are based on a subset of ISO 8601. When being as
		 precise as possible the format of a time string is
		 yyyy-MM-ddTHH:mm:ss (year, "-", month, "-", day, "T", hour (out of
		 24), ":", minutes, ":", seconds), but the precision may be reduced by
		 removing as many time indicators as wanted. Hence valid timestamps
		 are
		 yyyy, yyyy-MM, yyyy-MM-dd, yyyy-MM-ddTHH, yyyy-MM-ddTHH:mm and
		 yyyy-MM-ddTHH:mm:ss. All time stamps are UTC. For durations, use
		 the slash character as described in 8601, and for multiple non-
		 contiguous dates, use multiple strings, if allowed by the frame
		 definition.
		*/
//		year = CFStringGetIntValue(metadata.GetReleaseDate());
		auto frame = new TagLib::ID3v2::TextIdentificationFrame("TDRC", TagLib::String::Latin1);
		frame->setText("");
		tag->addFrame(frame);
	}
#endif

	// Comment
	tag->setComment(TagLib::StringFromCFString(metadata.GetComment()));
	
	// Album artist
	tag->removeFrames("TPE2");
	if(metadata.GetAlbumArtist()) {
		auto frame = new TagLib::ID3v2::TextIdentificationFrame("TPE2", TagLib::String::Latin1);
		frame->setText(TagLib::StringFromCFString(metadata.GetAlbumArtist()));
		tag->addFrame(frame);
	}
	
	// Track title
	tag->setTitle(TagLib::StringFromCFString(metadata.GetTitle()));
	
	// BPM
	tag->removeFrames("TBPM");
	if(metadata.GetBPM()) {
		SFB::CFString str = CFStringCreateWithFormat(kCFAllocatorDefault, nullptr, CFSTR("%@"), metadata.GetBPM());

		auto frame = new TagLib::ID3v2::TextIdentificationFrame("TBPM", TagLib::String::Latin1);
		frame->setText(TagLib::StringFromCFString(str));
		tag->addFrame(frame);
	}

	// Rating
	tag->removeFrames("POPM");
	CFNumberRef rating = metadata.GetRating();
	if(rating) {
		TagLib::ID3v2::PopularimeterFrame *frame = new TagLib::ID3v2::PopularimeterFrame();

		int i;
		if(CFNumberGetValue(rating, kCFNumberIntType, &i)) {
			frame->setRating(i);
			tag->addFrame(frame);
		}
	}

	// Track number and total tracks
	tag->removeFrames("TRCK");
	CFNumberRef trackNumber	= metadata.GetTrackNumber();
	CFNumberRef trackTotal	= metadata.GetTrackTotal();
	if(trackNumber && trackTotal) {
		SFB::CFString str = CFStringCreateWithFormat(kCFAllocatorDefault, nullptr, CFSTR("%@/%@"), trackNumber, trackTotal);

		auto frame = new TagLib::ID3v2::TextIdentificationFrame("TRCK", TagLib::String::Latin1);
		frame->setText(TagLib::StringFromCFString(str));
		tag->addFrame(frame);
	}
	else if(trackNumber) {		
		SFB::CFString str = CFStringCreateWithFormat(kCFAllocatorDefault, nullptr, CFSTR("%@"), trackNumber);
		
		auto frame = new TagLib::ID3v2::TextIdentificationFrame("TRCK", TagLib::String::Latin1);
		frame->setText(TagLib::StringFromCFString(str));
		tag->addFrame(frame);
	}
	else if(trackTotal) {		
		SFB::CFString str = CFStringCreateWithFormat(kCFAllocatorDefault, nullptr, CFSTR("/%@"), trackTotal);
		
		auto frame = new TagLib::ID3v2::TextIdentificationFrame("TRCK", TagLib::String::Latin1);
		frame->setText(TagLib::StringFromCFString(str));
		tag->addFrame(frame);
	}
	
	// Compilation
	// iTunes uses the TCMP frame for this, which isn't in the standard, but we'll use it for compatibility
	tag->removeFrames("TCMP");
	if(metadata.GetCompilation()) {
		auto frame = new TagLib::ID3v2::TextIdentificationFrame("TCMP", TagLib::String::Latin1);
		frame->setText(CFBooleanGetValue(metadata.GetCompilation()) ? "1" : "0");
		tag->addFrame(frame);
	}
	
	// Disc number and total discs
	tag->removeFrames("TPOS");
	CFNumberRef discNumber	= metadata.GetDiscNumber();
	CFNumberRef discTotal	= metadata.GetDiscTotal();
	if(discNumber && discTotal) {
		SFB::CFString str = CFStringCreateWithFormat(kCFAllocatorDefault, nullptr, CFSTR("%@/%@"), discNumber, discTotal);
		
		auto frame = new TagLib::ID3v2::TextIdentificationFrame("TPOS", TagLib::String::Latin1);
		frame->setText(TagLib::StringFromCFString(str));
		tag->addFrame(frame);
	}
	else if(discNumber) {		
		SFB::CFString str = CFStringCreateWithFormat(kCFAllocatorDefault, nullptr, CFSTR("%@"), discNumber);
		
		auto frame = new TagLib::ID3v2::TextIdentificationFrame("TPOS", TagLib::String::Latin1);
		frame->setText(TagLib::StringFromCFString(str));
		tag->addFrame(frame);
	}
	else if(discTotal) {		
		SFB::CFString str = CFStringCreateWithFormat(kCFAllocatorDefault, nullptr, CFSTR("/%@"), discTotal);
		
		auto frame = new TagLib::ID3v2::TextIdentificationFrame("TPOS", TagLib::String::Latin1);
		frame->setText(TagLib::StringFromCFString(str));
		tag->addFrame(frame);
	}
	
	// Lyrics
	tag->removeFrames("USLT");
	if(metadata.GetLyrics()) {
		auto frame = new TagLib::ID3v2::UnsynchronizedLyricsFrame(TagLib::String::UTF8);
		frame->setText(TagLib::StringFromCFString(metadata.GetLyrics()));
		tag->addFrame(frame);
	}

	tag->removeFrames("TSRC");
	if(metadata.GetISRC()) {
		auto frame = new TagLib::ID3v2::TextIdentificationFrame("TSRC", TagLib::String::Latin1);
		frame->setText(TagLib::StringFromCFString(metadata.GetISRC()));
		tag->addFrame(frame);
	}

	// MusicBrainz
	auto musicBrainzReleaseIDFrame = TagLib::ID3v2::UserTextIdentificationFrame::find(tag, "MusicBrainz Album Id");
	if(nullptr != musicBrainzReleaseIDFrame)
		tag->removeFrame(musicBrainzReleaseIDFrame);

	CFStringRef musicBrainzReleaseID = metadata.GetMusicBrainzReleaseID();
	if(musicBrainzReleaseID) {
		auto frame = new TagLib::ID3v2::UserTextIdentificationFrame();
		frame->setDescription("MusicBrainz Album Id");
		frame->setText(TagLib::StringFromCFString(musicBrainzReleaseID));
		tag->addFrame(frame);
	}


	auto musicBrainzRecordingIDFrame = TagLib::ID3v2::UserTextIdentificationFrame::find(const_cast<TagLib::ID3v2::Tag *>(tag), "MusicBrainz Track Id");
	if(nullptr != musicBrainzRecordingIDFrame)
		tag->removeFrame(musicBrainzRecordingIDFrame);

	CFStringRef musicBrainzRecordingID = metadata.GetMusicBrainzRecordingID();
	if(musicBrainzRecordingID) {
		auto frame = new TagLib::ID3v2::UserTextIdentificationFrame();
		frame->setDescription("MusicBrainz Track Id");
		frame->setText(TagLib::StringFromCFString(musicBrainzRecordingID));
		tag->addFrame(frame);
	}

	// Sorting and grouping
	tag->removeFrames("TSOT");
	if(metadata.GetTitleSortOrder()) {
		auto frame = new TagLib::ID3v2::TextIdentificationFrame("TSOT", TagLib::String::UTF8);
		frame->setText(TagLib::StringFromCFString(metadata.GetTitleSortOrder()));
		tag->addFrame(frame);
	}
	
	tag->removeFrames("TSOA");
	if(metadata.GetAlbumTitleSortOrder()) {
		auto frame = new TagLib::ID3v2::TextIdentificationFrame("TSOA", TagLib::String::UTF8);
		frame->setText(TagLib::StringFromCFString(metadata.GetAlbumTitleSortOrder()));
		tag->addFrame(frame);
	}

	tag->removeFrames("TSOP");
	if(metadata.GetArtistSortOrder()) {
		auto frame = new TagLib::ID3v2::TextIdentificationFrame("TSOP", TagLib::String::UTF8);
		frame->setText(TagLib::StringFromCFString(metadata.GetArtistSortOrder()));
		tag->addFrame(frame);
	}

	tag->removeFrames("TSO2");
	if(metadata.GetAlbumArtistSortOrder()) {
		auto frame = new TagLib::ID3v2::TextIdentificationFrame("TSO2", TagLib::String::UTF8);
		frame->setText(TagLib::StringFromCFString(metadata.GetAlbumArtistSortOrder()));
		tag->addFrame(frame);
	}

	tag->removeFrames("TSOC");
	if(metadata.GetComposerSortOrder()) {
		auto frame = new TagLib::ID3v2::TextIdentificationFrame("TSOC", TagLib::String::UTF8);
		frame->setText(TagLib::StringFromCFString(metadata.GetComposerSortOrder()));
		tag->addFrame(frame);
	}

	tag->removeFrames("TIT1");
	if(metadata.GetGrouping()) {
		auto frame = new TagLib::ID3v2::TextIdentificationFrame("TIT1", TagLib::String::UTF8);
		frame->setText(TagLib::StringFromCFString(metadata.GetGrouping()));
		tag->addFrame(frame);
	}

	// ReplayGain
	CFNumberRef trackGain = metadata.GetReplayGainTrackGain();
	CFNumberRef trackPeak = metadata.GetReplayGainTrackPeak();
	CFNumberRef albumGain = metadata.GetReplayGainAlbumGain();
	CFNumberRef albumPeak = metadata.GetReplayGainAlbumPeak();
	
	// Write TXXX frames
	auto trackGainFrame = TagLib::ID3v2::UserTextIdentificationFrame::find(tag, "replaygain_track_gain");
	auto trackPeakFrame = TagLib::ID3v2::UserTextIdentificationFrame::find(tag, "replaygain_track_peak");
	auto albumGainFrame = TagLib::ID3v2::UserTextIdentificationFrame::find(tag, "replaygain_album_gain");
	auto albumPeakFrame = TagLib::ID3v2::UserTextIdentificationFrame::find(tag, "replaygain_album_peak");
	
	if(nullptr != trackGainFrame)
		tag->removeFrame(trackGainFrame);
	
	if(nullptr != trackPeakFrame)
		tag->removeFrame(trackPeakFrame);
	
	if(nullptr != albumGainFrame)
		tag->removeFrame(albumGainFrame);
	
	if(nullptr != albumPeakFrame)
		tag->removeFrame(albumPeakFrame);
	
	if(trackGain) {
		SFB::CFString str = CreateStringFromNumberWithFormat(trackGain, kCFNumberDoubleType, CFSTR("%+2.2f dB"));
		
		auto frame = new TagLib::ID3v2::UserTextIdentificationFrame();
		frame->setDescription("replaygain_track_gain");
		frame->setText(TagLib::StringFromCFString(str));		
		tag->addFrame(frame);
	}
	
	if(trackPeak) {		
		SFB::CFString str = CreateStringFromNumberWithFormat(trackPeak, kCFNumberDoubleType, CFSTR("%1.8f dB"));
		
		auto frame = new TagLib::ID3v2::UserTextIdentificationFrame();
		frame->setDescription("replaygain_track_peak");
		frame->setText(TagLib::StringFromCFString(str));		
		tag->addFrame(frame);
	}
	
	if(albumGain) {
		SFB::CFString str = CreateStringFromNumberWithFormat(albumGain, kCFNumberDoubleType, CFSTR("%+2.2f dB"));

		auto frame = new TagLib::ID3v2::UserTextIdentificationFrame();		
		frame->setDescription("replaygain_album_gain");
		frame->setText(TagLib::StringFromCFString(str));		
		tag->addFrame(frame);
	}
	
	if(albumPeak) {
		SFB::CFString str = CreateStringFromNumberWithFormat(albumPeak, kCFNumberDoubleType, CFSTR("%1.8f dB"));
		
		auto frame = new TagLib::ID3v2::UserTextIdentificationFrame();		
		frame->setDescription("replaygain_album_peak");
		frame->setText(TagLib::StringFromCFString(str));		
		tag->addFrame(frame);
	}
	
	// Also write the RVA2 frames
	tag->removeFrames("RVA2");
	if(trackGain) {
		auto relativeVolume = new TagLib::ID3v2::RelativeVolumeFrame();
		
		float f;
		CFNumberGetValue(trackGain, kCFNumberFloatType, &f);
		
		relativeVolume->setIdentification(TagLib::String("track", TagLib::String::Latin1));
		relativeVolume->setVolumeAdjustment(f, TagLib::ID3v2::RelativeVolumeFrame::MasterVolume);
		
		tag->addFrame(relativeVolume);
	}
	
	if(albumGain) {
		auto relativeVolume = new TagLib::ID3v2::RelativeVolumeFrame();

		float f;
		CFNumberGetValue(albumGain, kCFNumberFloatType, &f);

		relativeVolume->setIdentification(TagLib::String("album", TagLib::String::Latin1));
		relativeVolume->setVolumeAdjustment(f, TagLib::ID3v2::RelativeVolumeFrame::MasterVolume);
		
		tag->addFrame(relativeVolume);
	}

	// Album art
	if(setAlbumArt) {
		tag->removeFrames("APIC");

		for(auto attachedPicture : metadata.GetAttachedPictures()) {
			SFB::CGImageSource imageSource = CGImageSourceCreateWithData(attachedPicture->GetData(), nullptr);
			if(!imageSource)
				continue;

			TagLib::ID3v2::AttachedPictureFrame *frame = new TagLib::ID3v2::AttachedPictureFrame;

			// Convert the image's UTI into a MIME type
			SFB::CFString mimeType = UTTypeCopyPreferredTagWithClass(CGImageSourceGetType(imageSource), kUTTagClassMIMEType);
			if(mimeType)
				frame->setMimeType(TagLib::StringFromCFString(mimeType));

			frame->setPicture(TagLib::ByteVector((const char *)CFDataGetBytePtr(attachedPicture->GetData()), (TagLib::uint)CFDataGetLength(attachedPicture->GetData())));
			frame->setType((TagLib::ID3v2::AttachedPictureFrame::Type)attachedPicture->GetType());
			if(attachedPicture->GetDescription())
				frame->setDescription(TagLib::StringFromCFString(attachedPicture->GetDescription()));
			tag->addFrame(frame);
		}
	}

	return true;
}
コード例 #9
0
ファイル: mimedisp.c プロジェクト: nysan/alpine
/*
 * Given a mime-type, return the file extension if there is one
 *
 * Returns: 1 on success, 0 on failure
 */
int
mime_get_os_ext_from_mimetype(char *mime_type, char *file_ext, int file_ext_len)
{
#ifdef	_WINDOWS
    int ret;
    LPTSTR x, mime_type_lpt, file_ext_lpt;

    mime_type_lpt = utf8_to_lptstr(mime_type);

    if(mime_type_lpt){
	if(file_ext){
	    file_ext_lpt = (LPTSTR) fs_get(file_ext_len * sizeof(TCHAR));
	    file_ext_lpt[0] = '\0';
	}
	else
	  file_ext_lpt = NULL;
    }

    ret = mswin_reg_mime_ext(mime_type_lpt, file_ext_lpt, (size_t) file_ext_len);

    /* convert answer back to UTF-8 */
    if(ret && file_ext_lpt && file_ext){
	char *u;

	u = lptstr_to_utf8(file_ext_lpt);
	if(u){
	    strncpy(file_ext, u, file_ext_len);
	    file_ext[file_ext_len-1] = '\0';
	    fs_give((void **) &u);
	}
    }

    if(mime_type_lpt)
      fs_give((void **) &mime_type_lpt);

    if(file_ext_lpt)
      fs_give((void **) &file_ext_lpt);

    return ret;

#elif	OSX_TARGET

    if(!mime_os_specific_access())
      return(0);
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER
    CFStringRef mime_ref = NULL, type_id_ref = NULL, ext_ref = NULL;

    if(!mime_type || !*mime_type)
      return 0;
    /* This for if we built on OS X >= 10.3 but run on < 10.3 */
    if(&UTTypeCreatePreferredIdentifierForTag == NULL)
      return 0;
    if((mime_ref = CFStringCreateWithCString(NULL, mime_type,
				    kCFStringEncodingASCII)) == NULL)
      return 0;
    if((type_id_ref 
	= UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType,
						mime_ref, NULL)) == NULL)
      return 0;

    if((ext_ref = UTTypeCopyPreferredTagWithClass(type_id_ref,
				   kUTTagClassFilenameExtension)) == NULL)
      return 0;
    if((CFStringGetCString(ext_ref, file_ext, (CFIndex)file_ext_len - 1,
			   kCFStringEncodingASCII)) == false)
      return 0;

    file_ext[file_ext_len - 1] = '\0';

    return 1;
#else
    return 0;
#endif /* AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER */

#else
    return 0;
#endif /* OSX_TARGET */
}
コード例 #10
0
bool
SetAPETagFromMetadata(const AudioMetadata& metadata, TagLib::APE::Tag *tag, bool setAlbumArt)
{
	if(nullptr == tag)
		return false;

	// Standard tags
	SetAPETag(tag, "ALBUM", metadata.GetAlbumTitle());
	SetAPETag(tag, "ARTIST", metadata.GetArtist());
	SetAPETag(tag, "ALBUMARTIST", metadata.GetAlbumArtist());
	SetAPETag(tag, "COMPOSER", metadata.GetComposer());
	SetAPETag(tag, "GENRE", metadata.GetGenre());
	SetAPETag(tag, "DATE", metadata.GetReleaseDate());
	SetAPETag(tag, "DESCRIPTION", metadata.GetComment());
	SetAPETag(tag, "TITLE", metadata.GetTitle());
	SetAPETagNumber(tag, "TRACKNUMBER", metadata.GetTrackNumber());
	SetAPETagNumber(tag, "TRACKTOTAL", metadata.GetTrackTotal());
	SetAPETagBoolean(tag, "COMPILATION", metadata.GetCompilation());
	SetAPETagNumber(tag, "DISCNUMBER", metadata.GetDiscNumber());
	SetAPETagNumber(tag, "DISCTOTAL", metadata.GetDiscTotal());
	SetAPETagNumber(tag, "BPM", metadata.GetBPM());
	SetAPETagNumber(tag, "RATING", metadata.GetRating());
	SetAPETag(tag, "ISRC", metadata.GetISRC());
	SetAPETag(tag, "MCN", metadata.GetMCN());
	SetAPETag(tag, "TITLESORT", metadata.GetTitleSortOrder());
	SetAPETag(tag, "ALBUMTITLESORT", metadata.GetAlbumTitleSortOrder());
	SetAPETag(tag, "ARTISTSORT", metadata.GetArtistSortOrder());
	SetAPETag(tag, "ALBUMARTISTSORT", metadata.GetAlbumArtistSortOrder());
	SetAPETag(tag, "COMPOSERSORT", metadata.GetComposerSortOrder());
	SetAPETag(tag, "GROUPING", metadata.GetGrouping());

	// Additional metadata
	CFDictionaryRef additionalMetadata = metadata.GetAdditionalMetadata();
	if(nullptr != additionalMetadata) {
		CFIndex count = CFDictionaryGetCount(additionalMetadata);
		
		const void * keys [count];
		const void * values [count];
		
		CFDictionaryGetKeysAndValues(additionalMetadata, reinterpret_cast<const void **>(keys), reinterpret_cast<const void **>(values));
		
		for(CFIndex i = 0; i < count; ++i) {
			CFIndex keySize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(reinterpret_cast<CFStringRef>(keys[i])), kCFStringEncodingASCII);
			char key [keySize + 1];
			
			if(!CFStringGetCString(reinterpret_cast<CFStringRef>(keys[i]), key, keySize + 1, kCFStringEncodingASCII)) {
				LOGGER_ERR("org.sbooth.AudioEngine", "CFStringGetCString failed");
				continue;
			}
			
			SetAPETag(tag, key, reinterpret_cast<CFStringRef>(values[i]));
		}
	}
	
	// ReplayGain info
	SetAPETagDouble(tag, "REPLAYGAIN_REFERENCE_LOUDNESS", metadata.GetReplayGainReferenceLoudness(), CFSTR("%2.1f dB"));
	SetAPETagDouble(tag, "REPLAYGAIN_TRACK_GAIN", metadata.GetReplayGainTrackGain(), CFSTR("%+2.2f dB"));
	SetAPETagDouble(tag, "REPLAYGAIN_TRACK_PEAK", metadata.GetReplayGainTrackPeak(), CFSTR("%1.8f"));
	SetAPETagDouble(tag, "REPLAYGAIN_ALBUM_GAIN", metadata.GetReplayGainAlbumGain(), CFSTR("%+2.2f dB"));
	SetAPETagDouble(tag, "REPLAYGAIN_ALBUM_PEAK", metadata.GetReplayGainAlbumPeak(), CFSTR("%1.8f"));

	// Album art
	if(setAlbumArt) {
		tag->removeItem("Cover Art (Front)");
		tag->removeItem("Cover Art (Back)");
#if 0
		tag->removeItem("METADATA_BLOCK_PICTURE");
#endif

		for(auto attachedPicture : metadata.GetAttachedPictures()) {
			// APE can handle front and back covers natively
			if(AttachedPicture::Type::FrontCover == attachedPicture->GetType() || AttachedPicture::Type::FrontCover == attachedPicture->GetType()) {
				TagLib::ByteVector data;
				
				if(attachedPicture->GetDescription())
					data.append(TagLib::StringFromCFString(attachedPicture->GetDescription()).data(TagLib::String::UTF8));
				data.append('\0');
				data.append(TagLib::ByteVector((const char *)CFDataGetBytePtr(attachedPicture->GetData()), (TagLib::uint)CFDataGetLength(attachedPicture->GetData())));

				if(AttachedPicture::Type::FrontCover == attachedPicture->GetType())
					tag->setData("Cover Art (Front)", data);
				else if(AttachedPicture::Type::BackCover == attachedPicture->GetType())
					tag->setData("Cover Art (Back)", data);
			}
#if 0
			else {
				CGImageSourceRef imageSource = CGImageSourceCreateWithData(attachedPicture->GetData(), nullptr);
				if(nullptr == imageSource)
					return false;

				TagLib::FLAC::Picture picture;
				picture.setData(TagLib::ByteVector((const char *)CFDataGetBytePtr(attachedPicture->GetData()), (TagLib::uint)CFDataGetLength(attachedPicture->GetData())));
				picture.setType(static_cast<TagLib::FLAC::Picture::Type>(attachedPicture->GetType()));
				if(attachedPicture->GetDescription())
					picture.setDescription(TagLib::StringFromCFString(attachedPicture->GetDescription()));

				// Convert the image's UTI into a MIME type
				CFStringRef mimeType = UTTypeCopyPreferredTagWithClass(CGImageSourceGetType(imageSource), kUTTagClassMIMEType);
				if(mimeType) {
					picture.setMimeType(TagLib::StringFromCFString(mimeType));
					CFRelease(mimeType), mimeType = nullptr;
				}

				// Flesh out the height, width, and depth
				CFDictionaryRef imagePropertiesDictionary = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nullptr);
				if(imagePropertiesDictionary) {
					CFNumberRef imageWidth = (CFNumberRef)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyPixelWidth);
					CFNumberRef imageHeight = (CFNumberRef)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyPixelHeight);
					CFNumberRef imageDepth = (CFNumberRef)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyDepth);
					
					int height, width, depth;
					
					// Ignore numeric conversion errors
					CFNumberGetValue(imageWidth, kCFNumberIntType, &width);
					CFNumberGetValue(imageHeight, kCFNumberIntType, &height);
					CFNumberGetValue(imageDepth, kCFNumberIntType, &depth);
					
					picture.setHeight(height);
					picture.setWidth(width);
					picture.setColorDepth(depth);
					
					CFRelease(imagePropertiesDictionary), imagePropertiesDictionary = nullptr;
				}

				TagLib::ByteVector encodedBlock = TagLib::EncodeBase64(picture.render());
				tag->addValue("METADATA_BLOCK_PICTURE", TagLib::String(encodedBlock, TagLib::String::UTF8), false);

				CFRelease(imageSource), imageSource = nullptr;
			}
#endif
		}
	}

	return true;
}