KOffice – TDE office suite
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.

kis_rgb_u16_colorspace.cc 31KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. /*
  2. * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
  3. * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
  4. * Copyright (c) 2005 Adrian Page <adrian@pagenet.plus.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. #include <config.h>
  21. #include <limits.h>
  22. #include <stdlib.h>
  23. #include LCMS_HEADER
  24. #include <tqimage.h>
  25. #include <tqcolor.h>
  26. #include <kdebug.h>
  27. #include <tdelocale.h>
  28. #include <tdeglobal.h>
  29. #include "kis_rgb_u16_colorspace.h"
  30. #include "kis_u16_base_colorspace.h"
  31. #include "kis_color_conversions.h"
  32. #include "kis_integer_maths.h"
  33. namespace {
  34. const TQ_INT32 MAX_CHANNEL_RGB = 3;
  35. const TQ_INT32 MAX_CHANNEL_RGBA = 4;
  36. }
  37. // XXX: already defined is superclass?
  38. //const TQ_UINT16 KisRgbU16ColorSpace::U16_OPACITY_OPAQUE;
  39. //const TQ_UINT16 KisRgbU16ColorSpace::U16_OPACITY_TRANSPARENT;
  40. KisRgbU16ColorSpace::KisRgbU16ColorSpace(KisColorSpaceFactoryRegistry * parent, KisProfile *p) :
  41. KisU16BaseColorSpace(KisID("RGBA16", i18n("RGB (16-bit integer/channel)")), TYPE_BGRA_16, icSigRgbData, parent, p)
  42. {
  43. m_channels.push_back(new KisChannelInfo(i18n("Red"), i18n("R"), PIXEL_RED * sizeof(TQ_UINT16), KisChannelInfo::COLOR, KisChannelInfo::UINT16, sizeof(TQ_UINT16), TQColor(255,0,0)));
  44. m_channels.push_back(new KisChannelInfo(i18n("Green"), i18n("G"), PIXEL_GREEN * sizeof(TQ_UINT16), KisChannelInfo::COLOR, KisChannelInfo::UINT16, sizeof(TQ_UINT16), TQColor(0,255,0)));
  45. m_channels.push_back(new KisChannelInfo(i18n("Blue"), i18n("B"), PIXEL_BLUE * sizeof(TQ_UINT16), KisChannelInfo::COLOR, KisChannelInfo::UINT16, sizeof(TQ_UINT16), TQColor(0,0,255)));
  46. m_channels.push_back(new KisChannelInfo(i18n("Alpha"), i18n("A"), PIXEL_ALPHA * sizeof(TQ_UINT16), KisChannelInfo::ALPHA, KisChannelInfo::UINT16, sizeof(TQ_UINT16)));
  47. m_alphaPos = PIXEL_ALPHA * sizeof(TQ_UINT16);
  48. init();
  49. }
  50. KisRgbU16ColorSpace::~KisRgbU16ColorSpace()
  51. {
  52. }
  53. void KisRgbU16ColorSpace::setPixel(TQ_UINT8 *dst, TQ_UINT16 red, TQ_UINT16 green, TQ_UINT16 blue, TQ_UINT16 alpha) const
  54. {
  55. Pixel *dstPixel = reinterpret_cast<Pixel *>(dst);
  56. dstPixel->red = red;
  57. dstPixel->green = green;
  58. dstPixel->blue = blue;
  59. dstPixel->alpha = alpha;
  60. }
  61. void KisRgbU16ColorSpace::getPixel(const TQ_UINT8 *src, TQ_UINT16 *red, TQ_UINT16 *green, TQ_UINT16 *blue, TQ_UINT16 *alpha) const
  62. {
  63. const Pixel *srcPixel = reinterpret_cast<const Pixel *>(src);
  64. *red = srcPixel->red;
  65. *green = srcPixel->green;
  66. *blue = srcPixel->blue;
  67. *alpha = srcPixel->alpha;
  68. }
  69. void KisRgbU16ColorSpace::mixColors(const TQ_UINT8 **colors, const TQ_UINT8 *weights, TQ_UINT32 nColors, TQ_UINT8 *dst) const
  70. {
  71. TQ_UINT32 totalRed = 0, totalGreen = 0, totalBlue = 0, newAlpha = 0;
  72. while (nColors--)
  73. {
  74. const Pixel *pixel = reinterpret_cast<const Pixel *>(*colors);
  75. TQ_UINT32 alpha = pixel->alpha;
  76. TQ_UINT32 alphaTimesWeight = UINT16_MULT(alpha, UINT8_TO_UINT16(*weights));
  77. totalRed += UINT16_MULT(pixel->red, alphaTimesWeight);
  78. totalGreen += UINT16_MULT(pixel->green, alphaTimesWeight);
  79. totalBlue += UINT16_MULT(pixel->blue, alphaTimesWeight);
  80. newAlpha += alphaTimesWeight;
  81. weights++;
  82. colors++;
  83. }
  84. Q_ASSERT(newAlpha <= U16_OPACITY_OPAQUE);
  85. Pixel *dstPixel = reinterpret_cast<Pixel *>(dst);
  86. dstPixel->alpha = newAlpha;
  87. if (newAlpha > 0) {
  88. totalRed = UINT16_DIVIDE(totalRed, newAlpha);
  89. totalGreen = UINT16_DIVIDE(totalGreen, newAlpha);
  90. totalBlue = UINT16_DIVIDE(totalBlue, newAlpha);
  91. }
  92. dstPixel->red = totalRed;
  93. dstPixel->green = totalGreen;
  94. dstPixel->blue = totalBlue;
  95. }
  96. void KisRgbU16ColorSpace::convolveColors(TQ_UINT8** colors, TQ_INT32* kernelValues, KisChannelInfo::enumChannelFlags channelFlags, TQ_UINT8 *dst,
  97. TQ_INT32 factor, TQ_INT32 offset, TQ_INT32 nColors) const
  98. {
  99. TQ_INT32 totalRed = 0, totalGreen = 0, totalBlue = 0, totalAlpha = 0;
  100. while (nColors--)
  101. {
  102. const Pixel * pixel = reinterpret_cast<const Pixel *>( *colors );
  103. TQ_INT32 weight = *kernelValues;
  104. if (weight != 0) {
  105. totalRed += pixel->red * weight;
  106. totalGreen += pixel->green * weight;
  107. totalBlue += pixel->blue * weight;
  108. totalAlpha +=pixel->alpha * weight;
  109. }
  110. colors++;
  111. kernelValues++;
  112. }
  113. Pixel * p = reinterpret_cast< Pixel *>( dst );
  114. if (channelFlags & KisChannelInfo::FLAG_COLOR) {
  115. p->red = CLAMP( ( totalRed / factor) + offset, 0, TQ_UINT16_MAX);
  116. p->green = CLAMP( ( totalGreen / factor) + offset, 0, TQ_UINT16_MAX);
  117. p->blue = CLAMP( ( totalBlue / factor) + offset, 0, TQ_UINT16_MAX);
  118. }
  119. if (channelFlags & KisChannelInfo::FLAG_ALPHA) {
  120. p->alpha = CLAMP((totalAlpha/ factor) + offset, 0, TQ_UINT16_MAX);
  121. }
  122. }
  123. void KisRgbU16ColorSpace::invertColor(TQ_UINT8 * src, TQ_INT32 nPixels)
  124. {
  125. TQ_UINT32 psize = pixelSize();
  126. while (nPixels--)
  127. {
  128. Pixel * p = reinterpret_cast< Pixel *>( src );
  129. p->red = TQ_UINT16_MAX - p->red;
  130. p->green = TQ_UINT16_MAX - p->green;
  131. p->blue = TQ_UINT16_MAX - p->blue;
  132. src += psize;
  133. }
  134. }
  135. TQ_UINT8 KisRgbU16ColorSpace::intensity8(const TQ_UINT8 * src) const
  136. {
  137. const Pixel * p = reinterpret_cast<const Pixel *>( src );
  138. return UINT16_TO_UINT8(static_cast<TQ_UINT16>((p->red * 0.30 + p->green * 0.59 + p->blue * 0.11) + 0.5));
  139. }
  140. TQValueVector<KisChannelInfo *> KisRgbU16ColorSpace::channels() const
  141. {
  142. return m_channels;
  143. }
  144. TQ_UINT32 KisRgbU16ColorSpace::nChannels() const
  145. {
  146. return MAX_CHANNEL_RGBA;
  147. }
  148. TQ_UINT32 KisRgbU16ColorSpace::nColorChannels() const
  149. {
  150. return MAX_CHANNEL_RGB;
  151. }
  152. TQ_UINT32 KisRgbU16ColorSpace::pixelSize() const
  153. {
  154. return MAX_CHANNEL_RGBA * sizeof(TQ_UINT16);
  155. }
  156. void KisRgbU16ColorSpace::compositeOver(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *maskRowStart, TQ_INT32 maskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT16 opacity)
  157. {
  158. while (rows > 0) {
  159. const TQ_UINT16 *src = reinterpret_cast<const TQ_UINT16 *>(srcRowStart);
  160. TQ_UINT16 *dst = reinterpret_cast<TQ_UINT16 *>(dstRowStart);
  161. const TQ_UINT8 *mask = maskRowStart;
  162. TQ_INT32 columns = numColumns;
  163. while (columns > 0) {
  164. TQ_UINT16 srcAlpha = src[PIXEL_ALPHA];
  165. // apply the alphamask
  166. if (mask != 0) {
  167. TQ_UINT8 U8_mask = *mask;
  168. if (U8_mask != OPACITY_OPAQUE) {
  169. srcAlpha = UINT16_MULT(srcAlpha, UINT8_TO_UINT16(U8_mask));
  170. }
  171. mask++;
  172. }
  173. if (srcAlpha != U16_OPACITY_TRANSPARENT) {
  174. if (opacity != U16_OPACITY_OPAQUE) {
  175. srcAlpha = UINT16_MULT(srcAlpha, opacity);
  176. }
  177. if (srcAlpha == U16_OPACITY_OPAQUE) {
  178. memcpy(dst, src, MAX_CHANNEL_RGBA * sizeof(TQ_UINT16));
  179. } else {
  180. TQ_UINT16 dstAlpha = dst[PIXEL_ALPHA];
  181. TQ_UINT16 srcBlend;
  182. if (dstAlpha == U16_OPACITY_OPAQUE) {
  183. srcBlend = srcAlpha;
  184. } else {
  185. TQ_UINT16 newAlpha = dstAlpha + UINT16_MULT(U16_OPACITY_OPAQUE - dstAlpha, srcAlpha);
  186. dst[PIXEL_ALPHA] = newAlpha;
  187. if (newAlpha != 0) {
  188. srcBlend = UINT16_DIVIDE(srcAlpha, newAlpha);
  189. } else {
  190. srcBlend = srcAlpha;
  191. }
  192. }
  193. if (srcBlend == U16_OPACITY_OPAQUE) {
  194. memcpy(dst, src, MAX_CHANNEL_RGB * sizeof(TQ_UINT16));
  195. } else {
  196. dst[PIXEL_RED] = UINT16_BLEND(src[PIXEL_RED], dst[PIXEL_RED], srcBlend);
  197. dst[PIXEL_GREEN] = UINT16_BLEND(src[PIXEL_GREEN], dst[PIXEL_GREEN], srcBlend);
  198. dst[PIXEL_BLUE] = UINT16_BLEND(src[PIXEL_BLUE], dst[PIXEL_BLUE], srcBlend);
  199. }
  200. }
  201. }
  202. columns--;
  203. src += MAX_CHANNEL_RGBA;
  204. dst += MAX_CHANNEL_RGBA;
  205. }
  206. rows--;
  207. srcRowStart += srcRowStride;
  208. dstRowStart += dstRowStride;
  209. if(maskRowStart) {
  210. maskRowStart += maskRowStride;
  211. }
  212. }
  213. }
  214. #define COMMON_COMPOSITE_OP_PROLOG() \
  215. while (rows > 0) { \
  216. \
  217. const TQ_UINT16 *src = reinterpret_cast<const TQ_UINT16 *>(srcRowStart); \
  218. TQ_UINT16 *dst = reinterpret_cast<TQ_UINT16 *>(dstRowStart); \
  219. TQ_INT32 columns = numColumns; \
  220. const TQ_UINT8 *mask = maskRowStart; \
  221. \
  222. while (columns > 0) { \
  223. \
  224. TQ_UINT16 srcAlpha = src[PIXEL_ALPHA]; \
  225. TQ_UINT16 dstAlpha = dst[PIXEL_ALPHA]; \
  226. \
  227. srcAlpha = TQMIN(srcAlpha, dstAlpha); \
  228. \
  229. if (mask != 0) { \
  230. TQ_UINT8 U8_mask = *mask; \
  231. \
  232. if (U8_mask != OPACITY_OPAQUE) { \
  233. srcAlpha = UINT16_MULT(srcAlpha, UINT8_TO_UINT16(U8_mask)); \
  234. } \
  235. mask++; \
  236. } \
  237. \
  238. if (srcAlpha != U16_OPACITY_TRANSPARENT) { \
  239. \
  240. if (opacity != U16_OPACITY_OPAQUE) { \
  241. srcAlpha = UINT16_MULT(srcAlpha, opacity); \
  242. } \
  243. \
  244. TQ_UINT16 srcBlend; \
  245. \
  246. if (dstAlpha == U16_OPACITY_OPAQUE) { \
  247. srcBlend = srcAlpha; \
  248. } else { \
  249. TQ_UINT16 newAlpha = dstAlpha + UINT16_MULT(U16_OPACITY_OPAQUE - dstAlpha, srcAlpha); \
  250. dst[PIXEL_ALPHA] = newAlpha; \
  251. \
  252. if (newAlpha != 0) { \
  253. srcBlend = UINT16_DIVIDE(srcAlpha, newAlpha); \
  254. } else { \
  255. srcBlend = srcAlpha; \
  256. } \
  257. }
  258. #define COMMON_COMPOSITE_OP_EPILOG() \
  259. } \
  260. \
  261. columns--; \
  262. src += MAX_CHANNEL_RGBA; \
  263. dst += MAX_CHANNEL_RGBA; \
  264. } \
  265. \
  266. rows--; \
  267. srcRowStart += srcRowStride; \
  268. dstRowStart += dstRowStride; \
  269. if(maskRowStart) { \
  270. maskRowStart += maskRowStride; \
  271. } \
  272. }
  273. void KisRgbU16ColorSpace::compositeMultiply(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *maskRowStart, TQ_INT32 maskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT16 opacity)
  274. {
  275. COMMON_COMPOSITE_OP_PROLOG();
  276. {
  277. for (int channel = 0; channel < MAX_CHANNEL_RGB; channel++) {
  278. TQ_UINT16 srcColor = src[channel];
  279. TQ_UINT16 dstColor = dst[channel];
  280. srcColor = UINT16_MULT(srcColor, dstColor);
  281. dst[channel] = UINT16_BLEND(srcColor, dstColor, srcBlend);
  282. }
  283. }
  284. COMMON_COMPOSITE_OP_EPILOG();
  285. }
  286. void KisRgbU16ColorSpace::compositeDivide(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *maskRowStart, TQ_INT32 maskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT16 opacity)
  287. {
  288. COMMON_COMPOSITE_OP_PROLOG();
  289. {
  290. for (int channel = 0; channel < MAX_CHANNEL_RGB; channel++) {
  291. TQ_UINT16 srcColor = src[channel];
  292. TQ_UINT16 dstColor = dst[channel];
  293. srcColor = TQMIN((dstColor * (UINT16_MAX + 1u) + (srcColor / 2u)) / (1u + srcColor), UINT16_MAX);
  294. TQ_UINT16 newColor = UINT16_BLEND(srcColor, dstColor, srcBlend);
  295. dst[channel] = newColor;
  296. }
  297. }
  298. COMMON_COMPOSITE_OP_EPILOG();
  299. }
  300. void KisRgbU16ColorSpace::compositeScreen(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *maskRowStart, TQ_INT32 maskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT16 opacity)
  301. {
  302. COMMON_COMPOSITE_OP_PROLOG();
  303. {
  304. for (int channel = 0; channel < MAX_CHANNEL_RGB; channel++) {
  305. TQ_UINT16 srcColor = src[channel];
  306. TQ_UINT16 dstColor = dst[channel];
  307. srcColor = UINT16_MAX - UINT16_MULT(UINT16_MAX - dstColor, UINT16_MAX - srcColor);
  308. TQ_UINT16 newColor = UINT16_BLEND(srcColor, dstColor, srcBlend);
  309. dst[channel] = newColor;
  310. }
  311. }
  312. COMMON_COMPOSITE_OP_EPILOG();
  313. }
  314. void KisRgbU16ColorSpace::compositeOverlay(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *maskRowStart, TQ_INT32 maskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT16 opacity)
  315. {
  316. COMMON_COMPOSITE_OP_PROLOG();
  317. {
  318. for (int channel = 0; channel < MAX_CHANNEL_RGB; channel++) {
  319. TQ_UINT16 srcColor = src[channel];
  320. TQ_UINT16 dstColor = dst[channel];
  321. srcColor = UINT16_MULT(dstColor, dstColor + 2u * UINT16_MULT(srcColor, UINT16_MAX - dstColor));
  322. TQ_UINT16 newColor = UINT16_BLEND(srcColor, dstColor, srcBlend);
  323. dst[channel] = newColor;
  324. }
  325. }
  326. COMMON_COMPOSITE_OP_EPILOG();
  327. }
  328. void KisRgbU16ColorSpace::compositeDodge(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *maskRowStart, TQ_INT32 maskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT16 opacity)
  329. {
  330. COMMON_COMPOSITE_OP_PROLOG();
  331. {
  332. for (int channel = 0; channel < MAX_CHANNEL_RGB; channel++) {
  333. TQ_UINT16 srcColor = src[channel];
  334. TQ_UINT16 dstColor = dst[channel];
  335. srcColor = TQMIN((dstColor * (UINT16_MAX + 1u)) / (UINT16_MAX + 1u - srcColor), UINT16_MAX);
  336. TQ_UINT16 newColor = UINT16_BLEND(srcColor, dstColor, srcBlend);
  337. dst[channel] = newColor;
  338. }
  339. }
  340. COMMON_COMPOSITE_OP_EPILOG();
  341. }
  342. void KisRgbU16ColorSpace::compositeBurn(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *maskRowStart, TQ_INT32 maskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT16 opacity)
  343. {
  344. COMMON_COMPOSITE_OP_PROLOG();
  345. {
  346. for (int channel = 0; channel < MAX_CHANNEL_RGB; channel++) {
  347. TQ_UINT16 srcColor = src[channel];
  348. TQ_UINT16 dstColor = dst[channel];
  349. srcColor = kMin(((UINT16_MAX - dstColor) * (UINT16_MAX + 1u)) / (srcColor + 1u), UINT16_MAX);
  350. srcColor = kClamp(UINT16_MAX - srcColor, 0u, UINT16_MAX);
  351. TQ_UINT16 newColor = UINT16_BLEND(srcColor, dstColor, srcBlend);
  352. dst[channel] = newColor;
  353. }
  354. }
  355. COMMON_COMPOSITE_OP_EPILOG();
  356. }
  357. void KisRgbU16ColorSpace::compositeDarken(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *maskRowStart, TQ_INT32 maskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT16 opacity)
  358. {
  359. COMMON_COMPOSITE_OP_PROLOG();
  360. {
  361. for (int channel = 0; channel < MAX_CHANNEL_RGB; channel++) {
  362. TQ_UINT16 srcColor = src[channel];
  363. TQ_UINT16 dstColor = dst[channel];
  364. srcColor = TQMIN(srcColor, dstColor);
  365. TQ_UINT16 newColor = UINT16_BLEND(srcColor, dstColor, srcBlend);
  366. dst[channel] = newColor;
  367. }
  368. }
  369. COMMON_COMPOSITE_OP_EPILOG();
  370. }
  371. void KisRgbU16ColorSpace::compositeLighten(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *maskRowStart, TQ_INT32 maskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT16 opacity)
  372. {
  373. COMMON_COMPOSITE_OP_PROLOG();
  374. {
  375. for (int channel = 0; channel < MAX_CHANNEL_RGB; channel++) {
  376. TQ_UINT16 srcColor = src[channel];
  377. TQ_UINT16 dstColor = dst[channel];
  378. srcColor = TQMAX(srcColor, dstColor);
  379. TQ_UINT16 newColor = UINT16_BLEND(srcColor, dstColor, srcBlend);
  380. dst[channel] = newColor;
  381. }
  382. }
  383. COMMON_COMPOSITE_OP_EPILOG();
  384. }
  385. void KisRgbU16ColorSpace::compositeHue(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *maskRowStart, TQ_INT32 maskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT16 opacity)
  386. {
  387. COMMON_COMPOSITE_OP_PROLOG();
  388. {
  389. float FSrcRed = static_cast<float>(src[PIXEL_RED]) / UINT16_MAX;
  390. float FSrcGreen = static_cast<float>(src[PIXEL_GREEN]) / UINT16_MAX;
  391. float FSrcBlue = static_cast<float>(src[PIXEL_BLUE]) / UINT16_MAX;
  392. TQ_UINT16 dstRed = dst[PIXEL_RED];
  393. TQ_UINT16 dstGreen = dst[PIXEL_GREEN];
  394. TQ_UINT16 dstBlue = dst[PIXEL_BLUE];
  395. float FDstRed = static_cast<float>(dstRed) / UINT16_MAX;
  396. float FDstGreen = static_cast<float>(dstGreen) / UINT16_MAX;
  397. float FDstBlue = static_cast<float>(dstBlue) / UINT16_MAX;
  398. float srcHue;
  399. float srcSaturation;
  400. float srcValue;
  401. float dstHue;
  402. float dstSaturation;
  403. float dstValue;
  404. RGBToHSV(FSrcRed, FSrcGreen, FSrcBlue, &srcHue, &srcSaturation, &srcValue);
  405. RGBToHSV(FDstRed, FDstGreen, FDstBlue, &dstHue, &dstSaturation, &dstValue);
  406. HSVToRGB(srcHue, dstSaturation, dstValue, &FSrcRed, &FSrcGreen, &FSrcBlue);
  407. TQ_UINT16 srcRed = static_cast<TQ_UINT16>(FSrcRed * UINT16_MAX + 0.5);
  408. TQ_UINT16 srcGreen = static_cast<TQ_UINT16>(FSrcGreen * UINT16_MAX + 0.5);
  409. TQ_UINT16 srcBlue = static_cast<TQ_UINT16>(FSrcBlue * UINT16_MAX + 0.5);
  410. dst[PIXEL_RED] = UINT16_BLEND(srcRed, dstRed, srcBlend);
  411. dst[PIXEL_GREEN] = UINT16_BLEND(srcGreen, dstGreen, srcBlend);
  412. dst[PIXEL_BLUE] = UINT16_BLEND(srcBlue, dstBlue, srcBlend);
  413. }
  414. COMMON_COMPOSITE_OP_EPILOG();
  415. }
  416. void KisRgbU16ColorSpace::compositeSaturation(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *maskRowStart, TQ_INT32 maskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT16 opacity)
  417. {
  418. COMMON_COMPOSITE_OP_PROLOG();
  419. {
  420. float FSrcRed = static_cast<float>(src[PIXEL_RED]) / UINT16_MAX;
  421. float FSrcGreen = static_cast<float>(src[PIXEL_GREEN]) / UINT16_MAX;
  422. float FSrcBlue = static_cast<float>(src[PIXEL_BLUE]) / UINT16_MAX;
  423. TQ_UINT16 dstRed = dst[PIXEL_RED];
  424. TQ_UINT16 dstGreen = dst[PIXEL_GREEN];
  425. TQ_UINT16 dstBlue = dst[PIXEL_BLUE];
  426. float FDstRed = static_cast<float>(dstRed) / UINT16_MAX;
  427. float FDstGreen = static_cast<float>(dstGreen) / UINT16_MAX;
  428. float FDstBlue = static_cast<float>(dstBlue) / UINT16_MAX;
  429. float srcHue;
  430. float srcSaturation;
  431. float srcValue;
  432. float dstHue;
  433. float dstSaturation;
  434. float dstValue;
  435. RGBToHSV(FSrcRed, FSrcGreen, FSrcBlue, &srcHue, &srcSaturation, &srcValue);
  436. RGBToHSV(FDstRed, FDstGreen, FDstBlue, &dstHue, &dstSaturation, &dstValue);
  437. HSVToRGB(dstHue, srcSaturation, dstValue, &FSrcRed, &FSrcGreen, &FSrcBlue);
  438. TQ_UINT16 srcRed = static_cast<TQ_UINT16>(FSrcRed * UINT16_MAX + 0.5);
  439. TQ_UINT16 srcGreen = static_cast<TQ_UINT16>(FSrcGreen * UINT16_MAX + 0.5);
  440. TQ_UINT16 srcBlue = static_cast<TQ_UINT16>(FSrcBlue * UINT16_MAX + 0.5);
  441. dst[PIXEL_RED] = UINT16_BLEND(srcRed, dstRed, srcBlend);
  442. dst[PIXEL_GREEN] = UINT16_BLEND(srcGreen, dstGreen, srcBlend);
  443. dst[PIXEL_BLUE] = UINT16_BLEND(srcBlue, dstBlue, srcBlend);
  444. }
  445. COMMON_COMPOSITE_OP_EPILOG();
  446. }
  447. void KisRgbU16ColorSpace::compositeValue(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *maskRowStart, TQ_INT32 maskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT16 opacity)
  448. {
  449. COMMON_COMPOSITE_OP_PROLOG();
  450. {
  451. float FSrcRed = static_cast<float>(src[PIXEL_RED]) / UINT16_MAX;
  452. float FSrcGreen = static_cast<float>(src[PIXEL_GREEN]) / UINT16_MAX;
  453. float FSrcBlue = static_cast<float>(src[PIXEL_BLUE]) / UINT16_MAX;
  454. TQ_UINT16 dstRed = dst[PIXEL_RED];
  455. TQ_UINT16 dstGreen = dst[PIXEL_GREEN];
  456. TQ_UINT16 dstBlue = dst[PIXEL_BLUE];
  457. float FDstRed = static_cast<float>(dstRed) / UINT16_MAX;
  458. float FDstGreen = static_cast<float>(dstGreen) / UINT16_MAX;
  459. float FDstBlue = static_cast<float>(dstBlue) / UINT16_MAX;
  460. float srcHue;
  461. float srcSaturation;
  462. float srcValue;
  463. float dstHue;
  464. float dstSaturation;
  465. float dstValue;
  466. RGBToHSV(FSrcRed, FSrcGreen, FSrcBlue, &srcHue, &srcSaturation, &srcValue);
  467. RGBToHSV(FDstRed, FDstGreen, FDstBlue, &dstHue, &dstSaturation, &dstValue);
  468. HSVToRGB(dstHue, dstSaturation, srcValue, &FSrcRed, &FSrcGreen, &FSrcBlue);
  469. TQ_UINT16 srcRed = static_cast<TQ_UINT16>(FSrcRed * UINT16_MAX + 0.5);
  470. TQ_UINT16 srcGreen = static_cast<TQ_UINT16>(FSrcGreen * UINT16_MAX + 0.5);
  471. TQ_UINT16 srcBlue = static_cast<TQ_UINT16>(FSrcBlue * UINT16_MAX + 0.5);
  472. dst[PIXEL_RED] = UINT16_BLEND(srcRed, dstRed, srcBlend);
  473. dst[PIXEL_GREEN] = UINT16_BLEND(srcGreen, dstGreen, srcBlend);
  474. dst[PIXEL_BLUE] = UINT16_BLEND(srcBlue, dstBlue, srcBlend);
  475. }
  476. COMMON_COMPOSITE_OP_EPILOG();
  477. }
  478. void KisRgbU16ColorSpace::compositeColor(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *maskRowStart, TQ_INT32 maskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT16 opacity)
  479. {
  480. COMMON_COMPOSITE_OP_PROLOG();
  481. {
  482. float FSrcRed = static_cast<float>(src[PIXEL_RED]) / UINT16_MAX;
  483. float FSrcGreen = static_cast<float>(src[PIXEL_GREEN]) / UINT16_MAX;
  484. float FSrcBlue = static_cast<float>(src[PIXEL_BLUE]) / UINT16_MAX;
  485. TQ_UINT16 dstRed = dst[PIXEL_RED];
  486. TQ_UINT16 dstGreen = dst[PIXEL_GREEN];
  487. TQ_UINT16 dstBlue = dst[PIXEL_BLUE];
  488. float FDstRed = static_cast<float>(dstRed) / UINT16_MAX;
  489. float FDstGreen = static_cast<float>(dstGreen) / UINT16_MAX;
  490. float FDstBlue = static_cast<float>(dstBlue) / UINT16_MAX;
  491. float srcHue;
  492. float srcSaturation;
  493. float srcLightness;
  494. float dstHue;
  495. float dstSaturation;
  496. float dstLightness;
  497. RGBToHSL(FSrcRed, FSrcGreen, FSrcBlue, &srcHue, &srcSaturation, &srcLightness);
  498. RGBToHSL(FDstRed, FDstGreen, FDstBlue, &dstHue, &dstSaturation, &dstLightness);
  499. HSLToRGB(srcHue, srcSaturation, dstLightness, &FSrcRed, &FSrcGreen, &FSrcBlue);
  500. TQ_UINT16 srcRed = static_cast<TQ_UINT16>(FSrcRed * UINT16_MAX + 0.5);
  501. TQ_UINT16 srcGreen = static_cast<TQ_UINT16>(FSrcGreen * UINT16_MAX + 0.5);
  502. TQ_UINT16 srcBlue = static_cast<TQ_UINT16>(FSrcBlue * UINT16_MAX + 0.5);
  503. dst[PIXEL_RED] = UINT16_BLEND(srcRed, dstRed, srcBlend);
  504. dst[PIXEL_GREEN] = UINT16_BLEND(srcGreen, dstGreen, srcBlend);
  505. dst[PIXEL_BLUE] = UINT16_BLEND(srcBlue, dstBlue, srcBlend);
  506. }
  507. COMMON_COMPOSITE_OP_EPILOG();
  508. }
  509. void KisRgbU16ColorSpace::compositeErase(TQ_UINT8 *dst,
  510. TQ_INT32 dstRowSize,
  511. const TQ_UINT8 *src,
  512. TQ_INT32 srcRowSize,
  513. const TQ_UINT8 *srcAlphaMask,
  514. TQ_INT32 maskRowStride,
  515. TQ_INT32 rows,
  516. TQ_INT32 cols,
  517. TQ_UINT16 /*opacity*/)
  518. {
  519. while (rows-- > 0)
  520. {
  521. const Pixel *s = reinterpret_cast<const Pixel *>(src);
  522. Pixel *d = reinterpret_cast<Pixel *>(dst);
  523. const TQ_UINT8 *mask = srcAlphaMask;
  524. for (TQ_INT32 i = cols; i > 0; i--, s++, d++)
  525. {
  526. TQ_UINT16 srcAlpha = s->alpha;
  527. // apply the alphamask
  528. if (mask != 0) {
  529. TQ_UINT8 U8_mask = *mask;
  530. if (U8_mask != OPACITY_OPAQUE) {
  531. srcAlpha = UINT16_BLEND(srcAlpha, U16_OPACITY_OPAQUE, UINT8_TO_UINT16(U8_mask));
  532. }
  533. mask++;
  534. }
  535. d->alpha = UINT16_MULT(srcAlpha, d->alpha);
  536. }
  537. dst += dstRowSize;
  538. src += srcRowSize;
  539. if(srcAlphaMask) {
  540. srcAlphaMask += maskRowStride;
  541. }
  542. }
  543. }
  544. void KisRgbU16ColorSpace::bitBlt(TQ_UINT8 *dst,
  545. TQ_INT32 dstRowStride,
  546. const TQ_UINT8 *src,
  547. TQ_INT32 srcRowStride,
  548. const TQ_UINT8 *mask,
  549. TQ_INT32 maskRowStride,
  550. TQ_UINT8 U8_opacity,
  551. TQ_INT32 rows,
  552. TQ_INT32 cols,
  553. const KisCompositeOp& op)
  554. {
  555. TQ_UINT16 opacity = UINT8_TO_UINT16(U8_opacity);
  556. switch (op.op()) {
  557. case COMPOSITE_UNDEF:
  558. // Undefined == no composition
  559. break;
  560. case COMPOSITE_OVER:
  561. compositeOver(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
  562. break;
  563. case COMPOSITE_IN:
  564. //compositeIn(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  565. case COMPOSITE_OUT:
  566. //compositeOut(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  567. break;
  568. case COMPOSITE_ATOP:
  569. //compositeAtop(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  570. break;
  571. case COMPOSITE_XOR:
  572. //compositeXor(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  573. break;
  574. case COMPOSITE_PLUS:
  575. //compositePlus(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  576. break;
  577. case COMPOSITE_MINUS:
  578. //compositeMinus(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  579. break;
  580. case COMPOSITE_ADD:
  581. //compositeAdd(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  582. break;
  583. case COMPOSITE_SUBTRACT:
  584. //compositeSubtract(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  585. break;
  586. case COMPOSITE_DIFF:
  587. //compositeDiff(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  588. break;
  589. case COMPOSITE_MULT:
  590. compositeMultiply(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
  591. break;
  592. case COMPOSITE_DIVIDE:
  593. compositeDivide(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
  594. break;
  595. case COMPOSITE_BUMPMAP:
  596. //compositeBumpmap(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  597. break;
  598. case COMPOSITE_COPY:
  599. compositeCopy(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, U8_opacity);
  600. break;
  601. case COMPOSITE_COPY_RED:
  602. //compositeCopyRed(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  603. break;
  604. case COMPOSITE_COPY_GREEN:
  605. //compositeCopyGreen(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  606. break;
  607. case COMPOSITE_COPY_BLUE:
  608. //compositeCopyBlue(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  609. break;
  610. case COMPOSITE_COPY_OPACITY:
  611. //compositeCopyOpacity(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  612. break;
  613. case COMPOSITE_CLEAR:
  614. //compositeClear(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  615. break;
  616. case COMPOSITE_DISSOLVE:
  617. //compositeDissolve(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  618. break;
  619. case COMPOSITE_DISPLACE:
  620. //compositeDisplace(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  621. break;
  622. #if 0
  623. case COMPOSITE_MODULATE:
  624. compositeModulate(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  625. break;
  626. case COMPOSITE_THRESHOLD:
  627. compositeThreshold(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  628. break;
  629. #endif
  630. case COMPOSITE_NO:
  631. // No composition.
  632. break;
  633. case COMPOSITE_DARKEN:
  634. compositeDarken(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
  635. break;
  636. case COMPOSITE_LIGHTEN:
  637. compositeLighten(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
  638. break;
  639. case COMPOSITE_HUE:
  640. compositeHue(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
  641. break;
  642. case COMPOSITE_SATURATION:
  643. compositeSaturation(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
  644. break;
  645. case COMPOSITE_VALUE:
  646. compositeValue(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
  647. break;
  648. case COMPOSITE_COLOR:
  649. compositeColor(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
  650. break;
  651. case COMPOSITE_COLORIZE:
  652. //compositeColorize(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  653. break;
  654. case COMPOSITE_LUMINIZE:
  655. //compositeLuminize(pixelSize(), dst, dstRowStride, src, srcRowStride, rows, cols, opacity);
  656. break;
  657. case COMPOSITE_SCREEN:
  658. compositeScreen(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
  659. break;
  660. case COMPOSITE_OVERLAY:
  661. compositeOverlay(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
  662. break;
  663. case COMPOSITE_ERASE:
  664. compositeErase(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
  665. break;
  666. case COMPOSITE_DODGE:
  667. compositeDodge(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
  668. break;
  669. case COMPOSITE_BURN:
  670. compositeBurn(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
  671. break;
  672. case COMPOSITE_ALPHA_DARKEN:
  673. abstractCompositeAlphaDarken<TQ_UINT16, U16Mult, Uint8ToU16, U16OpacityTest,
  674. PIXEL_ALPHA, MAX_CHANNEL_RGB, MAX_CHANNEL_RGBA>(
  675. dst, dstRowStride, src, srcRowStride, mask, maskRowStride,
  676. rows, cols, opacity, U16Mult(), Uint8ToU16(), U16OpacityTest());
  677. break;
  678. default:
  679. break;
  680. }
  681. }
  682. KisCompositeOpList KisRgbU16ColorSpace::userVisiblecompositeOps() const
  683. {
  684. KisCompositeOpList list;
  685. list.append(KisCompositeOp(COMPOSITE_OVER));
  686. list.append(KisCompositeOp(COMPOSITE_ALPHA_DARKEN));
  687. list.append(KisCompositeOp(COMPOSITE_MULT));
  688. list.append(KisCompositeOp(COMPOSITE_BURN));
  689. list.append(KisCompositeOp(COMPOSITE_DODGE));
  690. list.append(KisCompositeOp(COMPOSITE_DIVIDE));
  691. list.append(KisCompositeOp(COMPOSITE_SCREEN));
  692. list.append(KisCompositeOp(COMPOSITE_OVERLAY));
  693. list.append(KisCompositeOp(COMPOSITE_DARKEN));
  694. list.append(KisCompositeOp(COMPOSITE_LIGHTEN));
  695. list.append(KisCompositeOp(COMPOSITE_HUE));
  696. list.append(KisCompositeOp(COMPOSITE_SATURATION));
  697. list.append(KisCompositeOp(COMPOSITE_VALUE));
  698. list.append(KisCompositeOp(COMPOSITE_COLOR));
  699. return list;
  700. }