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.

734 lines
25KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE 7 technical preview.
  4. Copyright (c) 2022 - Raw Material Software Limited
  5. You may use this code under the terms of the GPL v3
  6. (see www.gnu.org/licenses).
  7. For the technical preview this file cannot be licensed commercially.
  8. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  9. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  10. DISCLAIMED.
  11. ==============================================================================
  12. */
  13. namespace juce
  14. {
  15. //==============================================================================
  16. #if JUCE_MSVC
  17. #pragma pack (push, 1)
  18. #endif
  19. class PixelRGB;
  20. class PixelAlpha;
  21. inline uint32 maskPixelComponents (uint32 x) noexcept
  22. {
  23. return (x >> 8) & 0x00ff00ff;
  24. }
  25. inline uint32 clampPixelComponents (uint32 x) noexcept
  26. {
  27. return (x | (0x01000100 - maskPixelComponents (x))) & 0x00ff00ff;
  28. }
  29. //==============================================================================
  30. /**
  31. Represents a 32-bit INTERNAL pixel with premultiplied alpha, and can perform compositing
  32. operations with it.
  33. This is used internally by the imaging classes.
  34. @see PixelRGB
  35. @tags{Graphics}
  36. */
  37. class JUCE_API PixelARGB
  38. {
  39. public:
  40. /** Creates a pixel without defining its colour. */
  41. PixelARGB() noexcept = default;
  42. PixelARGB (uint8 a, uint8 r, uint8 g, uint8 b) noexcept
  43. {
  44. components.b = b;
  45. components.g = g;
  46. components.r = r;
  47. components.a = a;
  48. }
  49. //==============================================================================
  50. /** Returns a uint32 which represents the pixel in a platform dependent format. */
  51. forcedinline uint32 getNativeARGB() const noexcept { return internal; }
  52. /** Returns a uint32 which will be in argb order as if constructed with the following mask operation
  53. ((alpha << 24) | (red << 16) | (green << 8) | blue). */
  54. forcedinline uint32 getInARGBMaskOrder() const noexcept
  55. {
  56. #if JUCE_ANDROID
  57. return (uint32) ((components.a << 24) | (components.r << 16) | (components.g << 8) | (components.b << 0));
  58. #else
  59. return getNativeARGB();
  60. #endif
  61. }
  62. /** Returns a uint32 which when written to memory, will be in the order a, r, g, b. In other words,
  63. if the return-value is read as a uint8 array then the elements will be in the order of a, r, g, b*/
  64. inline uint32 getInARGBMemoryOrder() const noexcept
  65. {
  66. #if JUCE_BIG_ENDIAN
  67. return getInARGBMaskOrder();
  68. #else
  69. return (uint32) ((components.b << 24) | (components.g << 16) | (components.r << 8) | components.a);
  70. #endif
  71. }
  72. /** Return channels with an even index and insert zero bytes between them. This is useful for blending
  73. operations. The exact channels which are returned is platform dependent. */
  74. forcedinline uint32 getEvenBytes() const noexcept { return 0x00ff00ff & internal; }
  75. /** Return channels with an odd index and insert zero bytes between them. This is useful for blending
  76. operations. The exact channels which are returned is platform dependent. */
  77. forcedinline uint32 getOddBytes() const noexcept { return 0x00ff00ff & (internal >> 8); }
  78. //==============================================================================
  79. forcedinline uint8 getAlpha() const noexcept { return components.a; }
  80. forcedinline uint8 getRed() const noexcept { return components.r; }
  81. forcedinline uint8 getGreen() const noexcept { return components.g; }
  82. forcedinline uint8 getBlue() const noexcept { return components.b; }
  83. //==============================================================================
  84. /** Copies another pixel colour over this one.
  85. This doesn't blend it - this colour is simply replaced by the other one.
  86. */
  87. template <class Pixel>
  88. forcedinline void set (const Pixel& src) noexcept
  89. {
  90. internal = src.getNativeARGB();
  91. }
  92. //==============================================================================
  93. /** Sets the pixel's colour from individual components. */
  94. void setARGB (uint8 a, uint8 r, uint8 g, uint8 b) noexcept
  95. {
  96. components.b = b;
  97. components.g = g;
  98. components.r = r;
  99. components.a = a;
  100. }
  101. //==============================================================================
  102. /** Blends another pixel onto this one.
  103. This takes into account the opacity of the pixel being overlaid, and blends
  104. it accordingly.
  105. */
  106. template <class Pixel>
  107. forcedinline void blend (const Pixel& src) noexcept
  108. {
  109. auto rb = src.getEvenBytes();
  110. auto ag = src.getOddBytes();
  111. const auto alpha = 0x100 - (ag >> 16);
  112. rb += maskPixelComponents (getEvenBytes() * alpha);
  113. ag += maskPixelComponents (getOddBytes() * alpha);
  114. internal = clampPixelComponents (rb) | (clampPixelComponents (ag) << 8);
  115. }
  116. /** Blends another pixel onto this one.
  117. This takes into account the opacity of the pixel being overlaid, and blends
  118. it accordingly.
  119. */
  120. forcedinline void blend (PixelRGB src) noexcept;
  121. /** Blends another pixel onto this one, applying an extra multiplier to its opacity.
  122. The opacity of the pixel being overlaid is scaled by the extraAlpha factor before
  123. being used, so this can blend semi-transparently from a PixelRGB argument.
  124. */
  125. template <class Pixel>
  126. forcedinline void blend (const Pixel& src, uint32 extraAlpha) noexcept
  127. {
  128. auto rb = maskPixelComponents (extraAlpha * src.getEvenBytes());
  129. auto ag = maskPixelComponents (extraAlpha * src.getOddBytes());
  130. const auto alpha = 0x100 - (ag >> 16);
  131. rb += maskPixelComponents (getEvenBytes() * alpha);
  132. ag += maskPixelComponents (getOddBytes() * alpha);
  133. internal = clampPixelComponents (rb) | (clampPixelComponents (ag) << 8);
  134. }
  135. /** Blends another pixel with this one, creating a colour that is somewhere
  136. between the two, as specified by the amount.
  137. */
  138. template <class Pixel>
  139. forcedinline void tween (const Pixel& src, uint32 amount) noexcept
  140. {
  141. auto dEvenBytes = getEvenBytes();
  142. dEvenBytes += (((src.getEvenBytes() - dEvenBytes) * amount) >> 8);
  143. dEvenBytes &= 0x00ff00ff;
  144. auto dOddBytes = getOddBytes();
  145. dOddBytes += (((src.getOddBytes() - dOddBytes) * amount) >> 8);
  146. dOddBytes &= 0x00ff00ff;
  147. dOddBytes <<= 8;
  148. dOddBytes |= dEvenBytes;
  149. internal = dOddBytes;
  150. }
  151. //==============================================================================
  152. /** Replaces the colour's alpha value with another one. */
  153. forcedinline void setAlpha (uint8 newAlpha) noexcept
  154. {
  155. components.a = newAlpha;
  156. }
  157. /** Multiplies the colour's alpha value with another one. */
  158. forcedinline void multiplyAlpha (int multiplier) noexcept
  159. {
  160. // increment alpha by 1, so that if multiplier == 255 (full alpha),
  161. // this function will not change the values.
  162. ++multiplier;
  163. internal = ((((uint32) multiplier) * getOddBytes()) & 0xff00ff00)
  164. | (((((uint32) multiplier) * getEvenBytes()) >> 8) & 0x00ff00ff);
  165. }
  166. forcedinline void multiplyAlpha (float multiplier) noexcept
  167. {
  168. multiplyAlpha ((int) (multiplier * 255.0f));
  169. }
  170. inline PixelARGB getUnpremultiplied() const noexcept
  171. {
  172. PixelARGB p (internal);
  173. p.unpremultiply();
  174. return p;
  175. }
  176. /** Premultiplies the pixel's RGB values by its alpha. */
  177. forcedinline void premultiply() noexcept
  178. {
  179. const auto alpha = components.a;
  180. if (alpha < 0xff)
  181. {
  182. if (alpha == 0)
  183. {
  184. components.b = 0;
  185. components.g = 0;
  186. components.r = 0;
  187. }
  188. else
  189. {
  190. components.b = (uint8) ((components.b * alpha + 0x7f) >> 8);
  191. components.g = (uint8) ((components.g * alpha + 0x7f) >> 8);
  192. components.r = (uint8) ((components.r * alpha + 0x7f) >> 8);
  193. }
  194. }
  195. }
  196. /** Unpremultiplies the pixel's RGB values. */
  197. forcedinline void unpremultiply() noexcept
  198. {
  199. const auto alpha = components.a;
  200. if (alpha < 0xff)
  201. {
  202. if (alpha == 0)
  203. {
  204. components.b = 0;
  205. components.g = 0;
  206. components.r = 0;
  207. }
  208. else
  209. {
  210. components.b = (uint8) jmin ((uint32) 0xffu, (components.b * 0xffu) / alpha);
  211. components.g = (uint8) jmin ((uint32) 0xffu, (components.g * 0xffu) / alpha);
  212. components.r = (uint8) jmin ((uint32) 0xffu, (components.r * 0xffu) / alpha);
  213. }
  214. }
  215. }
  216. forcedinline void desaturate() noexcept
  217. {
  218. if (components.a < 0xff && components.a > 0)
  219. {
  220. const auto newUnpremultipliedLevel = (0xff * ((int) components.r + (int) components.g + (int) components.b) / (3 * components.a));
  221. components.r = components.g = components.b
  222. = (uint8) ((newUnpremultipliedLevel * components.a + 0x7f) >> 8);
  223. }
  224. else
  225. {
  226. components.r = components.g = components.b
  227. = (uint8) (((int) components.r + (int) components.g + (int) components.b) / 3);
  228. }
  229. }
  230. //==============================================================================
  231. /** The indexes of the different components in the byte layout of this type of colour. */
  232. #if JUCE_ANDROID
  233. #if JUCE_BIG_ENDIAN
  234. enum { indexA = 0, indexR = 3, indexG = 2, indexB = 1 };
  235. #else
  236. enum { indexA = 3, indexR = 0, indexG = 1, indexB = 2 };
  237. #endif
  238. #else
  239. #if JUCE_BIG_ENDIAN
  240. enum { indexA = 0, indexR = 1, indexG = 2, indexB = 3 };
  241. #else
  242. enum { indexA = 3, indexR = 2, indexG = 1, indexB = 0 };
  243. #endif
  244. #endif
  245. private:
  246. //==============================================================================
  247. PixelARGB (uint32 internalValue) noexcept
  248. : internal (internalValue)
  249. {
  250. }
  251. //==============================================================================
  252. struct Components
  253. {
  254. #if JUCE_ANDROID
  255. #if JUCE_BIG_ENDIAN
  256. uint8 a, b, g, r;
  257. #else
  258. uint8 r, g, b, a;
  259. #endif
  260. #else
  261. #if JUCE_BIG_ENDIAN
  262. uint8 a, r, g, b;
  263. #else
  264. uint8 b, g, r, a;
  265. #endif
  266. #endif
  267. } JUCE_PACKED;
  268. union
  269. {
  270. uint32 internal;
  271. Components components;
  272. };
  273. }
  274. #ifndef DOXYGEN
  275. JUCE_PACKED
  276. #endif
  277. ;
  278. //==============================================================================
  279. /**
  280. Represents a 24-bit RGB pixel, and can perform compositing operations on it.
  281. This is used internally by the imaging classes.
  282. @see PixelARGB
  283. @tags{Graphics}
  284. */
  285. class JUCE_API PixelRGB
  286. {
  287. public:
  288. /** Creates a pixel without defining its colour. */
  289. PixelRGB() noexcept = default;
  290. //==============================================================================
  291. /** Returns a uint32 which represents the pixel in a platform dependent format which is compatible
  292. with the native format of a PixelARGB.
  293. @see PixelARGB::getNativeARGB */
  294. forcedinline uint32 getNativeARGB() const noexcept
  295. {
  296. #if JUCE_ANDROID
  297. return (uint32) ((0xffu << 24) | r | ((uint32) g << 8) | ((uint32) b << 16));
  298. #else
  299. return (uint32) ((0xffu << 24) | b | ((uint32) g << 8) | ((uint32) r << 16));
  300. #endif
  301. }
  302. /** Returns a uint32 which will be in argb order as if constructed with the following mask operation
  303. ((alpha << 24) | (red << 16) | (green << 8) | blue). */
  304. forcedinline uint32 getInARGBMaskOrder() const noexcept
  305. {
  306. #if JUCE_ANDROID
  307. return (uint32) ((0xffu << 24) | b | ((uint32) g << 8) | ((uint32) r << 16));
  308. #else
  309. return getNativeARGB();
  310. #endif
  311. }
  312. /** Returns a uint32 which when written to memory, will be in the order a, r, g, b. In other words,
  313. if the return-value is read as a uint8 array then the elements will be in the order of a, r, g, b*/
  314. inline uint32 getInARGBMemoryOrder() const noexcept
  315. {
  316. #if JUCE_BIG_ENDIAN
  317. return getInARGBMaskOrder();
  318. #else
  319. return (uint32) ((b << 24) | (g << 16) | (r << 8) | 0xff);
  320. #endif
  321. }
  322. /** Return channels with an even index and insert zero bytes between them. This is useful for blending
  323. operations. The exact channels which are returned is platform dependent but compatible with the
  324. return value of getEvenBytes of the PixelARGB class.
  325. @see PixelARGB::getEvenBytes */
  326. forcedinline uint32 getEvenBytes() const noexcept
  327. {
  328. #if JUCE_ANDROID
  329. return (uint32) (r | (b << 16));
  330. #else
  331. return (uint32) (b | (r << 16));
  332. #endif
  333. }
  334. /** Return channels with an odd index and insert zero bytes between them. This is useful for blending
  335. operations. The exact channels which are returned is platform dependent but compatible with the
  336. return value of getOddBytes of the PixelARGB class.
  337. @see PixelARGB::getOddBytes */
  338. forcedinline uint32 getOddBytes() const noexcept { return (uint32) 0xff0000 | g; }
  339. //==============================================================================
  340. forcedinline uint8 getAlpha() const noexcept { return 0xff; }
  341. forcedinline uint8 getRed() const noexcept { return r; }
  342. forcedinline uint8 getGreen() const noexcept { return g; }
  343. forcedinline uint8 getBlue() const noexcept { return b; }
  344. //==============================================================================
  345. /** Copies another pixel colour over this one.
  346. This doesn't blend it - this colour is simply replaced by the other one.
  347. Because PixelRGB has no alpha channel, any alpha value in the source pixel
  348. is thrown away.
  349. */
  350. template <class Pixel>
  351. forcedinline void set (const Pixel& src) noexcept
  352. {
  353. b = src.getBlue();
  354. g = src.getGreen();
  355. r = src.getRed();
  356. }
  357. /** Sets the pixel's colour from individual components. */
  358. void setARGB (uint8, uint8 red, uint8 green, uint8 blue) noexcept
  359. {
  360. r = red;
  361. g = green;
  362. b = blue;
  363. }
  364. //==============================================================================
  365. /** Blends another pixel onto this one.
  366. This takes into account the opacity of the pixel being overlaid, and blends
  367. it accordingly.
  368. */
  369. template <class Pixel>
  370. forcedinline void blend (const Pixel& src) noexcept
  371. {
  372. const auto alpha = (uint32) (0x100 - src.getAlpha());
  373. // getEvenBytes returns 0x00rr00bb on non-android
  374. const auto rb = clampPixelComponents (src.getEvenBytes() + maskPixelComponents (getEvenBytes() * alpha));
  375. // getOddBytes returns 0x00aa00gg on non-android
  376. const auto ag = clampPixelComponents (src.getOddBytes() + ((g * alpha) >> 8));
  377. g = (uint8) (ag & 0xff);
  378. #if JUCE_ANDROID
  379. b = (uint8) (rb >> 16);
  380. r = (uint8) (rb & 0xff);
  381. #else
  382. r = (uint8) (rb >> 16);
  383. b = (uint8) (rb & 0xff);
  384. #endif
  385. }
  386. forcedinline void blend (PixelRGB src) noexcept
  387. {
  388. set (src);
  389. }
  390. /** Blends another pixel onto this one, applying an extra multiplier to its opacity.
  391. The opacity of the pixel being overlaid is scaled by the extraAlpha factor before
  392. being used, so this can blend semi-transparently from a PixelRGB argument.
  393. */
  394. template <class Pixel>
  395. forcedinline void blend (const Pixel& src, uint32 extraAlpha) noexcept
  396. {
  397. auto ag = maskPixelComponents (extraAlpha * src.getOddBytes());
  398. auto rb = maskPixelComponents (extraAlpha * src.getEvenBytes());
  399. const auto alpha = 0x100 - (ag >> 16);
  400. ag = clampPixelComponents (ag + (g * alpha >> 8));
  401. rb = clampPixelComponents (rb + maskPixelComponents (getEvenBytes() * alpha));
  402. g = (uint8) (ag & 0xff);
  403. #if JUCE_ANDROID
  404. b = (uint8) (rb >> 16);
  405. r = (uint8) (rb & 0xff);
  406. #else
  407. r = (uint8) (rb >> 16);
  408. b = (uint8) (rb & 0xff);
  409. #endif
  410. }
  411. /** Blends another pixel with this one, creating a colour that is somewhere
  412. between the two, as specified by the amount.
  413. */
  414. template <class Pixel>
  415. forcedinline void tween (const Pixel& src, uint32 amount) noexcept
  416. {
  417. auto dEvenBytes = getEvenBytes();
  418. dEvenBytes += (((src.getEvenBytes() - dEvenBytes) * amount) >> 8);
  419. auto dOddBytes = getOddBytes();
  420. dOddBytes += (((src.getOddBytes() - dOddBytes) * amount) >> 8);
  421. g = (uint8) (dOddBytes & 0xff); // dOddBytes = 0x00aa00gg
  422. #if JUCE_ANDROID
  423. r = (uint8) (dEvenBytes & 0xff); // dEvenBytes = 0x00bb00rr
  424. b = (uint8) (dEvenBytes >> 16);
  425. #else
  426. b = (uint8) (dEvenBytes & 0xff); // dEvenBytes = 0x00rr00bb
  427. r = (uint8) (dEvenBytes >> 16);
  428. #endif
  429. }
  430. //==============================================================================
  431. /** This method is included for compatibility with the PixelARGB class. */
  432. forcedinline void setAlpha (uint8) noexcept {}
  433. /** Multiplies the colour's alpha value with another one. */
  434. forcedinline void multiplyAlpha (int) noexcept {}
  435. /** Multiplies the colour's alpha value with another one. */
  436. forcedinline void multiplyAlpha (float) noexcept {}
  437. /** Premultiplies the pixel's RGB values by its alpha. */
  438. forcedinline void premultiply() noexcept {}
  439. /** Unpremultiplies the pixel's RGB values. */
  440. forcedinline void unpremultiply() noexcept {}
  441. forcedinline void desaturate() noexcept
  442. {
  443. r = g = b = (uint8) (((int) r + (int) g + (int) b) / 3);
  444. }
  445. //==============================================================================
  446. /** The indexes of the different components in the byte layout of this type of colour. */
  447. #if JUCE_MAC
  448. enum { indexR = 0, indexG = 1, indexB = 2 };
  449. #else
  450. enum { indexR = 2, indexG = 1, indexB = 0 };
  451. #endif
  452. private:
  453. //==============================================================================
  454. PixelRGB (uint32 internal) noexcept
  455. {
  456. #if JUCE_ANDROID
  457. b = (uint8) (internal >> 16);
  458. g = (uint8) (internal >> 8);
  459. r = (uint8) (internal);
  460. #else
  461. r = (uint8) (internal >> 16);
  462. g = (uint8) (internal >> 8);
  463. b = (uint8) (internal);
  464. #endif
  465. }
  466. //==============================================================================
  467. #if JUCE_MAC
  468. uint8 r, g, b;
  469. #else
  470. uint8 b, g, r;
  471. #endif
  472. }
  473. #ifndef DOXYGEN
  474. JUCE_PACKED
  475. #endif
  476. ;
  477. forcedinline void PixelARGB::blend (PixelRGB src) noexcept
  478. {
  479. set (src);
  480. }
  481. //==============================================================================
  482. /**
  483. Represents an 8-bit single-channel pixel, and can perform compositing operations on it.
  484. This is used internally by the imaging classes.
  485. @see PixelARGB, PixelRGB
  486. @tags{Graphics}
  487. */
  488. class JUCE_API PixelAlpha
  489. {
  490. public:
  491. /** Creates a pixel without defining its colour. */
  492. PixelAlpha() noexcept = default;
  493. //==============================================================================
  494. /** Returns a uint32 which represents the pixel in a platform dependent format which is compatible
  495. with the native format of a PixelARGB.
  496. @see PixelARGB::getNativeARGB */
  497. forcedinline uint32 getNativeARGB() const noexcept { return (uint32) ((a << 24) | (a << 16) | (a << 8) | a); }
  498. /** Returns a uint32 which will be in argb order as if constructed with the following mask operation
  499. ((alpha << 24) | (red << 16) | (green << 8) | blue). */
  500. forcedinline uint32 getInARGBMaskOrder() const noexcept { return getNativeARGB(); }
  501. /** Returns a uint32 which when written to memory, will be in the order a, r, g, b. In other words,
  502. if the return-value is read as a uint8 array then the elements will be in the order of a, r, g, b*/
  503. inline uint32 getInARGBMemoryOrder() const noexcept { return getNativeARGB(); }
  504. /** Return channels with an even index and insert zero bytes between them. This is useful for blending
  505. operations. The exact channels which are returned is platform dependent but compatible with the
  506. return value of getEvenBytes of the PixelARGB class.
  507. @see PixelARGB::getEvenBytes */
  508. forcedinline uint32 getEvenBytes() const noexcept { return (uint32) ((a << 16) | a); }
  509. /** Return channels with an odd index and insert zero bytes between them. This is useful for blending
  510. operations. The exact channels which are returned is platform dependent but compatible with the
  511. return value of getOddBytes of the PixelARGB class.
  512. @see PixelARGB::getOddBytes */
  513. forcedinline uint32 getOddBytes() const noexcept { return (uint32) ((a << 16) | a); }
  514. //==============================================================================
  515. forcedinline uint8 getAlpha() const noexcept { return a; }
  516. forcedinline uint8 getRed() const noexcept { return 0; }
  517. forcedinline uint8 getGreen() const noexcept { return 0; }
  518. forcedinline uint8 getBlue() const noexcept { return 0; }
  519. //==============================================================================
  520. /** Copies another pixel colour over this one.
  521. This doesn't blend it - this colour is simply replaced by the other one.
  522. */
  523. template <class Pixel>
  524. forcedinline void set (const Pixel& src) noexcept
  525. {
  526. a = src.getAlpha();
  527. }
  528. /** Sets the pixel's colour from individual components. */
  529. forcedinline void setARGB (uint8 a_, uint8, uint8, uint8) noexcept
  530. {
  531. a = a_;
  532. }
  533. //==============================================================================
  534. /** Blends another pixel onto this one.
  535. This takes into account the opacity of the pixel being overlaid, and blends
  536. it accordingly.
  537. */
  538. template <class Pixel>
  539. forcedinline void blend (const Pixel& src) noexcept
  540. {
  541. const auto srcA = src.getAlpha();
  542. a = (uint8) ((a * (0x100 - srcA) >> 8) + srcA);
  543. }
  544. /** Blends another pixel onto this one, applying an extra multiplier to its opacity.
  545. The opacity of the pixel being overlaid is scaled by the extraAlpha factor before
  546. being used, so this can blend semi-transparently from a PixelRGB argument.
  547. */
  548. template <class Pixel>
  549. forcedinline void blend (const Pixel& src, uint32 extraAlpha) noexcept
  550. {
  551. ++extraAlpha;
  552. const auto srcAlpha = (int) ((extraAlpha * src.getAlpha()) >> 8);
  553. a = (uint8) ((a * (0x100 - srcAlpha) >> 8) + srcAlpha);
  554. }
  555. /** Blends another pixel with this one, creating a colour that is somewhere
  556. between the two, as specified by the amount.
  557. */
  558. template <class Pixel>
  559. forcedinline void tween (const Pixel& src, uint32 amount) noexcept
  560. {
  561. a += ((src.getAlpha() - a) * amount) >> 8;
  562. }
  563. //==============================================================================
  564. /** Replaces the colour's alpha value with another one. */
  565. forcedinline void setAlpha (uint8 newAlpha) noexcept
  566. {
  567. a = newAlpha;
  568. }
  569. /** Multiplies the colour's alpha value with another one. */
  570. forcedinline void multiplyAlpha (int multiplier) noexcept
  571. {
  572. ++multiplier;
  573. a = (uint8) ((a * multiplier) >> 8);
  574. }
  575. forcedinline void multiplyAlpha (float multiplier) noexcept
  576. {
  577. a = (uint8) (a * multiplier);
  578. }
  579. /** Premultiplies the pixel's RGB values by its alpha. */
  580. forcedinline void premultiply() noexcept {}
  581. /** Unpremultiplies the pixel's RGB values. */
  582. forcedinline void unpremultiply() noexcept {}
  583. forcedinline void desaturate() noexcept {}
  584. //==============================================================================
  585. /** The indexes of the different components in the byte layout of this type of colour. */
  586. enum { indexA = 0 };
  587. private:
  588. //==============================================================================
  589. PixelAlpha (uint32 internal) noexcept
  590. : a ((uint8) (internal >> 24)) { }
  591. //==============================================================================
  592. uint8 a;
  593. }
  594. #ifndef DOXYGEN
  595. JUCE_PACKED
  596. #endif
  597. ;
  598. #if JUCE_MSVC
  599. #pragma pack (pop)
  600. #endif
  601. } // namespace juce