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.

142 lines
5.0KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2022 - 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 7 End-User License
  8. Agreement and JUCE Privacy Policy.
  9. End User License Agreement: www.juce.com/juce-7-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. if (auto pathCFString = CFUniquePtr<CFStringRef> (CFStringCreateWithCString (kCFAllocatorDefault, applicationPath.toRawUTF8(), kCFStringEncodingUTF8)))
  80. {
  81. if (auto url = CFUniquePtr<CFURLRef> (CFURLCreateWithFileSystemPath (kCFAllocatorDefault, pathCFString.get(), kCFURLPOSIXPathStyle, 1)))
  82. {
  83. if (auto appBundle = CFUniquePtr<CFBundleRef> (CFBundleCreate (kCFAllocatorDefault, url.get())))
  84. {
  85. if (CFTypeRef infoValue = CFBundleGetValueForInfoDictionaryKey (appBundle.get(), CFSTR("CFBundleIconFile")))
  86. {
  87. if (CFGetTypeID (infoValue) == CFStringGetTypeID())
  88. {
  89. CFStringRef iconFilename = reinterpret_cast<CFStringRef> (infoValue);
  90. CFStringRef resourceURLSuffix = CFStringHasSuffix (iconFilename, CFSTR(".icns")) ? nullptr : CFSTR("icns");
  91. if (auto iconURL = CFUniquePtr<CFURLRef> (CFBundleCopyResourceURL (appBundle.get(), iconFilename, resourceURLSuffix, nullptr)))
  92. {
  93. if (auto iconPath = CFUniquePtr<CFStringRef> (CFURLCopyFileSystemPath (iconURL.get(), kCFURLPOSIXPathStyle)))
  94. {
  95. File icnsFile (CFStringGetCStringPtr (iconPath.get(), CFStringGetSystemEncoding()));
  96. return getIconFromIcnsFile (icnsFile, size);
  97. }
  98. }
  99. }
  100. }
  101. }
  102. }
  103. }
  104. return {};
  105. }
  106. } // namespace juce