Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
5.1KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2020 - Raw Material Software Limited
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 6 End-User License
  8. Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
  9. End User License Agreement: www.juce.com/juce-6-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce
  19. {
  20. extern Image JUCE_API getIconFromApplication (const String&, int);
  21. static Image getIconFromIcnsFile (const File& icnsFile, const int size)
  22. {
  23. FileInputStream stream (icnsFile);
  24. if (! stream.openedOk())
  25. return {};
  26. const int numHeaderSectionBytes = 4;
  27. char headerSection [numHeaderSectionBytes];
  28. if (stream.read (headerSection, numHeaderSectionBytes) != numHeaderSectionBytes
  29. || headerSection[0] != 'i'
  30. || headerSection[1] != 'c'
  31. || headerSection[2] != 'n'
  32. || headerSection[3] != 's')
  33. return {};
  34. if (stream.read (headerSection, numHeaderSectionBytes) != numHeaderSectionBytes)
  35. return {};
  36. const auto dataSize = juce::ByteOrder::bigEndianInt (headerSection);
  37. if (dataSize <= 0)
  38. return {};
  39. OwnedArray<juce::ImageFileFormat> internalFormats;
  40. internalFormats.add (new PNGImageFormat());
  41. internalFormats.add (new JPEGImageFormat());
  42. Array<Image> images;
  43. auto maxWidth = 0;
  44. auto maxWidthIndex = -1;
  45. while (stream.getPosition() < dataSize)
  46. {
  47. const auto sectionStart = stream.getPosition();
  48. if (! stream.setPosition (sectionStart + 4))
  49. break;
  50. if (stream.read (headerSection, numHeaderSectionBytes) != numHeaderSectionBytes)
  51. break;
  52. const auto sectionSize = ByteOrder::bigEndianInt (headerSection);
  53. if (sectionSize <= 0)
  54. break;
  55. const auto sectionDataStart = stream.getPosition();
  56. for (auto* fmt : internalFormats)
  57. {
  58. if (fmt->canUnderstand (stream))
  59. {
  60. stream.setPosition (sectionDataStart);
  61. images.add (fmt->decodeImage (stream));
  62. const auto lastImageIndex = images.size() - 1;
  63. const auto lastWidth = images.getReference (lastImageIndex).getWidth();
  64. if (lastWidth > maxWidth)
  65. {
  66. maxWidthIndex = lastImageIndex;
  67. maxWidth = lastWidth;
  68. }
  69. }
  70. stream.setPosition (sectionDataStart);
  71. }
  72. stream.setPosition (sectionStart + sectionSize);
  73. }
  74. return maxWidthIndex == -1 ? juce::Image()
  75. : images.getReference (maxWidthIndex).rescaled (size, size, Graphics::ResamplingQuality::highResamplingQuality);
  76. }
  77. Image JUCE_API getIconFromApplication (const String& applicationPath, const int size)
  78. {
  79. Image hostIcon;
  80. if (CFStringRef pathCFString = CFStringCreateWithCString (kCFAllocatorDefault, applicationPath.toRawUTF8(), kCFStringEncodingUTF8))
  81. {
  82. if (CFURLRef url = CFURLCreateWithFileSystemPath (kCFAllocatorDefault, pathCFString, kCFURLPOSIXPathStyle, 1))
  83. {
  84. if (CFBundleRef appBundle = CFBundleCreate (kCFAllocatorDefault, url))
  85. {
  86. if (CFTypeRef infoValue = CFBundleGetValueForInfoDictionaryKey (appBundle, CFSTR("CFBundleIconFile")))
  87. {
  88. if (CFGetTypeID (infoValue) == CFStringGetTypeID())
  89. {
  90. CFStringRef iconFilename = reinterpret_cast<CFStringRef> (infoValue);
  91. CFStringRef resourceURLSuffix = CFStringHasSuffix (iconFilename, CFSTR(".icns")) ? nullptr : CFSTR("icns");
  92. if (CFURLRef iconURL = CFBundleCopyResourceURL (appBundle, iconFilename, resourceURLSuffix, nullptr))
  93. {
  94. if (CFStringRef iconPath = CFURLCopyFileSystemPath (iconURL, kCFURLPOSIXPathStyle))
  95. {
  96. File icnsFile (CFStringGetCStringPtr (iconPath, CFStringGetSystemEncoding()));
  97. hostIcon = getIconFromIcnsFile (icnsFile, size);
  98. CFRelease (iconPath);
  99. }
  100. CFRelease (iconURL);
  101. }
  102. }
  103. }
  104. CFRelease (appBundle);
  105. }
  106. CFRelease (url);
  107. }
  108. CFRelease (pathCFString);
  109. }
  110. return hostIcon;
  111. }
  112. } // namespace juce