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_wet_sticky_colorspace.cc 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. /*
  2. * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. */
  18. #include <limits.h>
  19. #include <stdlib.h>
  20. #include <config.h>
  21. #include LCMS_HEADER
  22. #include <tqimage.h>
  23. #include <tdelocale.h>
  24. #include <kdebug.h>
  25. #include "kis_color_conversions.h"
  26. #include "kis_abstract_colorspace.h"
  27. #include "kis_colorspace_registry.h"
  28. #include "kis_image.h"
  29. #include "kis_wet_sticky_colorspace.h"
  30. #include "kis_integer_maths.h"
  31. #include "kis_types.h"
  32. #include "kis_channelinfo.h"
  33. #define NOWSDEBUG
  34. using namespace WetAndSticky;
  35. enum WetStickyChannelIndex {
  36. BLUE_CHANNEL_INDEX,
  37. GREEN_CHANNEL_INDEX,
  38. RED_CHANNEL_INDEX,
  39. ALPHA_CHANNEL_INDEX,
  40. HUE_CHANNEL_INDEX,
  41. SATURATION_CHANNEL_INDEX,
  42. LIGHTNESS_CHANNEL_INDEX,
  43. LIQUID_CONTENT_CHANNEL_INDEX,
  44. DRYING_RATE_CHANNEL_INDEX,
  45. MISCIBILITY_CHANNEL_INDEX,
  46. GRAVITATIONAL_DIRECTION_INDEX,
  47. GRAVITATIONAL_STRENGTH_CHANNEL_INDEX,
  48. ABSORBANCY_CHANNEL_INDEX,
  49. PAINT_VOLUME_CHANNEL_INDEX
  50. };
  51. KisWetStickyColorSpace::KisWetStickyColorSpace() :
  52. KisAbstractColorSpace(KisID("W&S", i18n("Wet & Sticky")), 0, icMaxEnumData)
  53. {
  54. TQ_INT32 pos = 0;
  55. // Basic representational definition
  56. m_channels.push_back(new KisChannelInfo(i18n("Blue"), "B", pos, COLOR, 1));
  57. m_channels.push_back(new KisChannelInfo(i18n("Green"), "G", ++pos, COLOR, 1));
  58. m_channels.push_back(new KisChannelInfo(i18n("Red"), "R", ++pos, COLOR, 1));
  59. m_channels.push_back(new KisChannelInfo(i18n("Alpha"), "A", ++pos, ALPHA, 1));
  60. // Paint definition
  61. m_channels.push_back(new KisChannelInfo(i18n("Hue"), "H", ++pos, COLOR, sizeof(float)));
  62. m_channels.push_back(new KisChannelInfo(i18n("Saturation"), "S", pos+=sizeof(float) , COLOR, sizeof(float)));
  63. m_channels.push_back(new KisChannelInfo(i18n("Lightness"), "L", pos+=sizeof(float), COLOR, sizeof(float)));
  64. m_channels.push_back(new KisChannelInfo(i18n("Liquid Content"), "Q", pos+=sizeof(float), SUBSTANCE, 1));
  65. m_channels.push_back(new KisChannelInfo(i18n("Drying Rate"), "D", ++pos, SUBSTANCE, 1));
  66. m_channels.push_back(new KisChannelInfo(i18n("Miscibility"), "M", ++pos, SUBSTANCE, 1));
  67. // Substrate definition
  68. m_channels.push_back(new KisChannelInfo(i18n("Gravitational Direction"), "Gd", ++pos, SUBSTRATE, sizeof(enumDirection)));
  69. m_channels.push_back(new KisChannelInfo(i18n("Gravitational Strength"), "Gs", pos+=sizeof(enumDirection), SUBSTRATE, 1));
  70. m_channels.push_back(new KisChannelInfo(i18n("Absorbency"), "Ad", ++pos, SUBSTRATE, 1));
  71. m_channels.push_back(new KisChannelInfo(i18n("Paint Volume"), "V", ++pos, SUBSTANCE, 1));
  72. m_alphaPos = 3;
  73. m_alphaSize = 1;
  74. setDefaultProfile( 0 );
  75. #ifdef WSDEBUG
  76. TQValueVector<KisChannelInfo *>_it it;
  77. int i = 0;
  78. for (it = m_channels.begin(); it != m_channels.end(); ++it)
  79. {
  80. KisChannelInfo * ch = (*it);
  81. kdDebug(DBG_AREA_CMS) << "Channel: " << ch->name() << ", " << ch->pos() << ", " << i << "\n";
  82. ++i;
  83. }
  84. kdDebug(DBG_AREA_CMS) << "Size of cell: " << sizeof(CELL) << "\n";
  85. #endif
  86. }
  87. KisWetStickyColorSpace::~KisWetStickyColorSpace()
  88. {
  89. }
  90. void KisWetStickyColorSpace::fromTQColor(const TQColor& c, TQ_UINT8 *dst, KisProfile * profile)
  91. {
  92. CELL_PTR p = (CELL_PTR) dst;
  93. TQ_UINT8 r, g, b;
  94. r = c.red();
  95. g = c.green();
  96. b = c.blue();
  97. p -> red = r;
  98. p -> green = g;
  99. p -> blue = b;
  100. p -> alpha = OPACITY_OPAQUE;
  101. rgb_to_hls(r, g, b, &p->hue, &p->lightness, &p->saturation);
  102. p -> liquid_content = 0;
  103. p -> drying_rate = 0;
  104. p -> miscibility = 0;
  105. p -> direction = DOWN;
  106. p -> strength = 10;
  107. p -> absorbancy = 10;
  108. p -> volume = 0;
  109. #ifdef WSDEBUG
  110. kdDebug(DBG_AREA_CMS) << "qcolor: "
  111. << " r: " << c.red() << " b: " << c.blue() << " g: " << c.red()
  112. << " native color: (" << TQString().setNum(p->red) << ", "
  113. << TQString().setNum(p->green) << ", "
  114. << TQString().setNum(p->blue) << ", "
  115. << TQString().setNum(p->alpha) << ") "
  116. << ", hls: (" << p->hue << ", "
  117. << p->lightness << ", "
  118. << p->saturation << ")\n";
  119. #endif
  120. }
  121. void KisWetStickyColorSpace::fromTQColor(const TQColor& c, TQ_UINT8 opacity, TQ_UINT8 *dst, KisProfile * profile)
  122. {
  123. CELL_PTR p = (CELL_PTR) dst;
  124. TQ_UINT8 r, g, b;
  125. r = c.red();
  126. g = c.green();
  127. b = c.blue();
  128. p -> red = r;
  129. p -> green = g;
  130. p -> blue = b;
  131. p -> alpha = opacity;
  132. rgb_to_hls(r, g, b, &p -> hue, &p -> lightness, &p -> saturation);
  133. p ->liquid_content = 0;
  134. p ->drying_rate = 0;
  135. p ->miscibility = 0;
  136. p -> direction = DOWN;
  137. p -> strength = 10;
  138. p -> absorbancy = 10;
  139. p -> volume = 0;
  140. #ifdef WSDEBUG
  141. kdDebug(DBG_AREA_CMS) << "qcolor: "
  142. << " r: " << c.red() << " b: " << c.blue() << " g: " << c.red() << " opacity: " << opacity
  143. << " native color: (" << TQString().setNum(p->red) << ", "
  144. << TQString().setNum(p->green) << ", "
  145. << TQString().setNum(p->blue) << ", "
  146. << TQString().setNum(p->alpha) << ") "
  147. << ", hls: (" << p->hue << ", "
  148. << p->lightness << ", "
  149. << p->saturation << ")\n";
  150. #endif
  151. }
  152. void KisWetStickyColorSpace::toTQColor(const TQ_UINT8 *src, TQColor *c, KisProfile * profile)
  153. {
  154. CELL_PTR p = (CELL_PTR) src;
  155. c -> setRgb(p -> red,
  156. p -> green,
  157. p -> blue);
  158. #ifdef WSDEBUG
  159. kdDebug(DBG_AREA_CMS) << "Created qcolor from wet & sticky: " << " r: " << c->red() << " b: " << c->blue() << " g: " << c->red() << "\n";
  160. #endif
  161. }
  162. void KisWetStickyColorSpace::toTQColor(const TQ_UINT8 *src, TQColor *c, TQ_UINT8 *opacity, KisProfile * profile)
  163. {
  164. CELL_PTR p = (CELL_PTR) src;
  165. c -> setRgb(p -> red,
  166. p -> green,
  167. p -> blue);
  168. *opacity = p -> alpha;
  169. #ifdef WSDEBUG
  170. kdDebug(DBG_AREA_CMS) << "Created qcolor from wet & sticky: " << " r: " << c->red() << " b: " << c->blue() << " g: " << c->red() << "\n";
  171. #endif
  172. }
  173. KisPixelRO KisWetStickyColorSpace::toKisPixelRO(const TQ_UINT8 *src, KisProfile * profile)
  174. {
  175. return KisPixelRO (src, src, this, profile);
  176. }
  177. KisPixel KisWetStickyColorSpace::toKisPixel(TQ_UINT8 *src, KisProfile * profile)
  178. {
  179. return KisPixel (src, src, this, profile);
  180. }
  181. void KisWetStickyColorSpace::mixColors(const TQ_UINT8 **colors, const TQ_UINT8 *weights, TQ_UINT32 nColors, TQ_UINT8 *dst) const
  182. {
  183. }
  184. TQ_UINT8 KisWetStickyColorSpace::getAlpha(const TQ_UINT8 *pixel) const
  185. {
  186. return ((CELL_PTR)pixel)->alpha;
  187. }
  188. void KisWetStickyColorSpace::setAlpha(TQ_UINT8 * pixels, TQ_UINT8 alpha, TQ_INT32 nPixels) const
  189. {
  190. while (nPixels > 0) {
  191. ((CELL_PTR)pixels)->alpha = alpha;
  192. --nPixels;
  193. pixels+=pixelSize();
  194. }
  195. }
  196. void KisWetStickyColorSpace::applyAlphaU8Mask(TQ_UINT8 * pixels, TQ_UINT8 * alpha, TQ_INT32 nPixels)
  197. {
  198. }
  199. void KisWetStickyColorSpace::applyInverseAlphaU8Mask(TQ_UINT8 * pixels, TQ_UINT8 * alpha, TQ_INT32 nPixels)
  200. {
  201. }
  202. TQ_UINT8 KisWetStickyColorSpace::scaleToU8(const TQ_UINT8 * srcPixel, TQ_INT32 channelPos)
  203. {
  204. return 0;
  205. }
  206. TQ_UINT16 KisWetStickyColorSpace::scaleToU16(const TQ_UINT8 * srcPixel, TQ_INT32 channelPos)
  207. {
  208. return 0;
  209. }
  210. TQValueVector<KisChannelInfo *> KisWetStickyColorSpace::channels() const
  211. {
  212. return m_channels;
  213. }
  214. bool KisWetStickyColorSpace::hasAlpha() const
  215. {
  216. return true;
  217. }
  218. TQ_INT32 KisWetStickyColorSpace::nChannels() const
  219. {
  220. return 14;
  221. }
  222. TQ_INT32 KisWetStickyColorSpace::nColorChannels() const
  223. {
  224. return 3;
  225. }
  226. TQ_INT32 KisWetStickyColorSpace::nSubstanceChannels() const
  227. {
  228. return 4;
  229. }
  230. TQ_INT32 KisWetStickyColorSpace::pixelSize() const
  231. {
  232. return sizeof(CELL);
  233. }
  234. TQImage KisWetStickyColorSpace::convertToTQImage(const TQ_UINT8 *data, TQ_INT32 width, TQ_INT32 height,
  235. KisProfile * /*srcProfile*/, KisProfile * /*dstProfile*/,
  236. TQ_INT32 /*renderingIntent*/, float /*exposure*/)
  237. {
  238. TQImage img(width, height, 32, 0, TQImage::LittleEndian);
  239. TQ_INT32 i = 0;
  240. uchar *j = img.bits();
  241. CELL_PTR p = (CELL_PTR) data;
  242. while ( i < width * height) {
  243. const TQ_UINT8 PIXEL_BLUE = 0;
  244. const TQ_UINT8 PIXEL_GREEN = 1;
  245. const TQ_UINT8 PIXEL_RED = 2;
  246. const TQ_UINT8 PIXEL_ALPHA = 3;
  247. *( j + PIXEL_ALPHA ) = p -> alpha;
  248. *( j + PIXEL_RED ) = p -> red;
  249. *( j + PIXEL_GREEN ) = p -> green;
  250. *( j + PIXEL_BLUE ) = p -> blue;
  251. p++;
  252. i++;
  253. j += 4; // Because we're hard-coded 32 bits deep, 4 bytes
  254. }
  255. return img;
  256. }
  257. bool KisWetStickyColorSpace::convertPixelsTo(const TQ_UINT8 * src, KisProfile * /*srcProfile*/,
  258. TQ_UINT8 * dst, KisAbstractColorSpace * dstColorSpace, KisProfile * dstProfile,
  259. TQ_UINT32 numPixels,
  260. TQ_INT32 /*renderingIntent*/)
  261. {
  262. TQ_INT32 dSize = dstColorSpace -> pixelSize();
  263. TQ_INT32 sSize = pixelSize();
  264. TQ_UINT32 j = 0;
  265. TQ_UINT32 i = 0;
  266. TQColor c;
  267. CELL_PTR cp;
  268. while ( i < numPixels ) {
  269. cp = (CELL_PTR) (src + i);
  270. c.setRgb(cp -> red,
  271. cp -> green,
  272. cp -> blue);
  273. dstColorSpace -> fromTQColor(c, cp -> alpha, (dst + j), dstProfile);
  274. i += sSize;
  275. j += dSize;
  276. }
  277. return true;
  278. }
  279. void KisWetStickyColorSpace::bitBlt(TQ_UINT8 *dst,
  280. TQ_INT32 dstRowStride,
  281. const TQ_UINT8 *src,
  282. TQ_INT32 srcRowStride,
  283. const TQ_UINT8 *mask,
  284. TQ_INT32 maskRowStride,
  285. TQ_UINT8 opacity,
  286. TQ_INT32 rows,
  287. TQ_INT32 cols,
  288. const KisCompositeOp& op)
  289. {
  290. switch (op.op()) {
  291. case COMPOSITE_UNDEF:
  292. // Undefined == no composition
  293. break;
  294. case COMPOSITE_OVER:
  295. compositeOver(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
  296. break;
  297. case COMPOSITE_COPY:
  298. default:
  299. compositeCopy(dst, dstRowStride, src, srcRowStride, mask, maskRowStride, rows, cols, opacity);
  300. break;
  301. }
  302. }
  303. void KisWetStickyColorSpace::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_UINT8 opacity)
  304. {
  305. // XXX: This is basically the same as with rgb and used to composite layers for Composition for
  306. // painting works differently
  307. while (rows > 0) {
  308. const TQ_UINT8 *src = srcRowStart;
  309. TQ_UINT8 *dst = dstRowStart;
  310. const TQ_UINT8 *mask = maskRowStart;
  311. TQ_INT32 columns = numColumns;
  312. while (columns > 0) {
  313. CELL_PTR dstCell = (CELL_PTR) dst;
  314. CELL_PTR srcCell = (CELL_PTR) src;
  315. #ifdef WSDEBUG
  316. kdDebug(DBG_AREA_CMS) << "Source: " << rows << ", " << columns << " color: " <<
  317. srcCell->red << ", " << srcCell->blue << ", " << srcCell->green << ", " << srcCell->alpha << ", " << srcCell->volume << "\n";
  318. kdDebug(DBG_AREA_CMS) << "Destination: " << rows << ", " << columns << " color: " <<
  319. dstCell->red << ", " << dstCell->blue << ", " << dstCell->green << ", " << dstCell->alpha << ", " << dstCell->volume << "\n";
  320. #endif
  321. TQ_UINT8 srcAlpha = srcCell->alpha;
  322. // apply the alphamask
  323. if(mask != 0)
  324. {
  325. if(*mask != OPACITY_OPAQUE)
  326. srcAlpha = UINT8_MULT(srcAlpha, *mask);
  327. mask++;
  328. }
  329. if (srcAlpha != OPACITY_TRANSPARENT) {
  330. if (opacity != OPACITY_OPAQUE) {
  331. srcAlpha = UINT8_MULT(srcCell->alpha, opacity);
  332. }
  333. if (srcAlpha == OPACITY_OPAQUE) {
  334. memcpy(dst, src, 3); // XXX: First three bytes for rgb?
  335. } else {
  336. TQ_UINT8 dstAlpha = dstCell->alpha;
  337. TQ_UINT8 srcBlend;
  338. if (dstAlpha == OPACITY_OPAQUE) {
  339. srcBlend = srcAlpha;
  340. } else {
  341. TQ_UINT8 newAlpha = dstAlpha + UINT8_MULT(OPACITY_OPAQUE - dstAlpha, srcAlpha);
  342. dstCell->alpha = newAlpha;
  343. if (newAlpha != 0) {
  344. srcBlend = UINT8_DIVIDE(srcAlpha, newAlpha);
  345. } else {
  346. srcBlend = srcAlpha;
  347. }
  348. }
  349. if (srcBlend == OPACITY_OPAQUE) {
  350. memcpy(dst, src, 3); //XXX: First three bytes for rgb?
  351. } else {
  352. dstCell->red = UINT8_BLEND(srcCell->red, dstCell->red, srcBlend);
  353. dstCell->green = UINT8_BLEND(srcCell->green, dstCell->green, srcBlend);
  354. dstCell->blue = UINT8_BLEND(srcCell->blue, dstCell->blue, srcBlend);
  355. }
  356. }
  357. }
  358. columns--;
  359. src += sizeof(CELL);
  360. dst += sizeof(CELL);
  361. }
  362. rows--;
  363. srcRowStart += srcRowStride;
  364. dstRowStart += dstRowStride;
  365. if(maskRowStart)
  366. maskRowStart += maskRowStride;
  367. }
  368. }
  369. void KisWetStickyColorSpace::compositeCopy(TQ_UINT8 *dst, TQ_INT32 dstRowStride, const TQ_UINT8 *src, TQ_INT32 srcRowStride, const TQ_UINT8 *mask, TQ_INT32 maskRowStride, TQ_INT32 rows, TQ_INT32 columns, TQ_UINT8 opacity)
  370. {
  371. TQ_INT32 linesize = sizeof(CELL) * columns;
  372. TQ_UINT8 *d;
  373. const TQ_UINT8 *s;
  374. d = dst;
  375. s = src;
  376. while (rows-- > 0) {
  377. memcpy(d, s, linesize);
  378. d += dstRowStride;
  379. s += srcRowStride;
  380. }
  381. }
  382. KisCompositeOpList KisWetStickyColorSpace::userVisiblecompositeOps() const
  383. {
  384. KisCompositeOpList list;
  385. list.append(KisCompositeOp(COMPOSITE_OVER));
  386. return list;
  387. }
  388. TQString KisWetStickyColorSpace::channelValueText(const TQ_UINT8 *U8_pixel, TQ_UINT32 channelIndex) const
  389. {
  390. Q_ASSERT(channelIndex < nChannels());
  391. const CELL *pixel = reinterpret_cast<const CELL *>(U8_pixel);
  392. switch (channelIndex) {
  393. case BLUE_CHANNEL_INDEX:
  394. return TQString().setNum(pixel -> blue);
  395. case GREEN_CHANNEL_INDEX:
  396. return TQString().setNum(pixel -> green);
  397. case RED_CHANNEL_INDEX:
  398. return TQString().setNum(pixel -> red);
  399. case ALPHA_CHANNEL_INDEX:
  400. return TQString().setNum(pixel -> alpha);
  401. case HUE_CHANNEL_INDEX:
  402. return TQString().setNum(pixel -> hue);
  403. case SATURATION_CHANNEL_INDEX:
  404. return TQString().setNum(pixel -> saturation);
  405. case LIGHTNESS_CHANNEL_INDEX:
  406. return TQString().setNum(pixel -> lightness);
  407. case LIQUID_CONTENT_CHANNEL_INDEX:
  408. return TQString().setNum(pixel -> liquid_content);
  409. case DRYING_RATE_CHANNEL_INDEX:
  410. return TQString().setNum(pixel -> drying_rate);
  411. case MISCIBILITY_CHANNEL_INDEX:
  412. return TQString().setNum(pixel -> miscibility);
  413. case GRAVITATIONAL_DIRECTION_INDEX:
  414. {
  415. switch (pixel -> direction) {
  416. case UP:
  417. return i18n("Up");
  418. case DOWN:
  419. return i18n("Down");
  420. case LEFT:
  421. return i18n("Left");
  422. case RIGHT:
  423. return i18n("Right");
  424. default:
  425. Q_ASSERT(false);
  426. return TQString();
  427. }
  428. }
  429. case GRAVITATIONAL_STRENGTH_CHANNEL_INDEX:
  430. return TQString().setNum(pixel -> strength);
  431. case ABSORBANCY_CHANNEL_INDEX:
  432. return TQString().setNum(pixel -> absorbancy);
  433. case PAINT_VOLUME_CHANNEL_INDEX:
  434. return TQString().setNum(pixel -> volume);
  435. default:
  436. Q_ASSERT(false);
  437. return TQString();
  438. }
  439. }
  440. TQString KisWetStickyColorSpace::normalisedChannelValueText(const TQ_UINT8 *U8_pixel, TQ_UINT32 channelIndex) const
  441. {
  442. Q_ASSERT(channelIndex < nChannels());
  443. const CELL *pixel = reinterpret_cast<const CELL *>(U8_pixel);
  444. //XXX: Are these right?
  445. switch (channelIndex) {
  446. case BLUE_CHANNEL_INDEX:
  447. return TQString().setNum(static_cast<float>(pixel -> blue) / UINT8_MAX);
  448. case GREEN_CHANNEL_INDEX:
  449. return TQString().setNum(static_cast<float>(pixel -> green) / UINT8_MAX);
  450. case RED_CHANNEL_INDEX:
  451. return TQString().setNum(static_cast<float>(pixel -> red) / UINT8_MAX);
  452. case ALPHA_CHANNEL_INDEX:
  453. return TQString().setNum(static_cast<float>(pixel -> alpha) / UINT8_MAX);
  454. case HUE_CHANNEL_INDEX:
  455. return TQString().setNum(pixel -> hue);
  456. case SATURATION_CHANNEL_INDEX:
  457. return TQString().setNum(pixel -> saturation);
  458. case LIGHTNESS_CHANNEL_INDEX:
  459. return TQString().setNum(pixel -> lightness);
  460. case LIQUID_CONTENT_CHANNEL_INDEX:
  461. return TQString().setNum(static_cast<float>(pixel -> liquid_content) / UINT8_MAX);
  462. case DRYING_RATE_CHANNEL_INDEX:
  463. return TQString().setNum(static_cast<float>(pixel -> drying_rate) / UINT8_MAX);
  464. case MISCIBILITY_CHANNEL_INDEX:
  465. return TQString().setNum(static_cast<float>(pixel -> miscibility) / UINT8_MAX);
  466. case GRAVITATIONAL_DIRECTION_INDEX:
  467. {
  468. switch (pixel -> direction) {
  469. case UP:
  470. return i18n("Up");
  471. case DOWN:
  472. return i18n("Down");
  473. case LEFT:
  474. return i18n("Left");
  475. case RIGHT:
  476. return i18n("Right");
  477. default:
  478. Q_ASSERT(false);
  479. return TQString();
  480. }
  481. }
  482. case GRAVITATIONAL_STRENGTH_CHANNEL_INDEX:
  483. return TQString().setNum(static_cast<float>(pixel -> strength) / UINT8_MAX);
  484. case ABSORBANCY_CHANNEL_INDEX:
  485. return TQString().setNum(static_cast<float>(pixel -> absorbancy) / UINT8_MAX);
  486. case PAINT_VOLUME_CHANNEL_INDEX:
  487. return TQString().setNum(static_cast<float>(pixel -> volume) / UINT8_MAX);
  488. default:
  489. Q_ASSERT(false);
  490. return TQString();
  491. }
  492. }