Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

PixelFormat.cxx 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
  2. * Copyright (C) 2011 D. R. Commander. All Rights Reserved.
  3. * Copyright 2009-2014 Pierre Ossman for Cendio AB
  4. *
  5. * This is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This software is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this software; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  18. * USA.
  19. */
  20. #include <assert.h>
  21. #include <stdio.h>
  22. #include <stdint.h>
  23. #include <string.h>
  24. #include <rdr/InStream.h>
  25. #include <rdr/OutStream.h>
  26. #include <rfb/Exception.h>
  27. #include <rfb/PixelFormat.h>
  28. #include <rfb/util.h>
  29. #ifdef _WIN32
  30. #define strcasecmp _stricmp
  31. #endif
  32. using namespace rfb;
  33. rdr::U8 PixelFormat::upconvTable[256*8];
  34. rdr::U8 PixelFormat::downconvTable[256*8];
  35. class PixelFormat::Init {
  36. public:
  37. Init();
  38. };
  39. PixelFormat::Init PixelFormat::_init;
  40. PixelFormat::Init::Init()
  41. {
  42. int bits;
  43. // Shifting bits is almost perfect, but not quite. And
  44. // a lookup table is still quicker when there is a large
  45. // difference between the source and destination depth.
  46. for (bits = 1;bits <= 8;bits++) {
  47. int i, maxVal;
  48. rdr::U8 *subUpTable;
  49. rdr::U8 *subDownTable;
  50. maxVal = (1 << bits) - 1;
  51. subUpTable = &upconvTable[(bits-1)*256];
  52. subDownTable = &downconvTable[(bits-1)*256];
  53. for (i = 0;i <= maxVal;i++)
  54. subUpTable[i] = i * 255 / maxVal;
  55. // Duplicate the up table so that we don't have to care about
  56. // the upper bits when doing a lookup
  57. for (;i < 256;i += maxVal+1)
  58. memcpy(&subUpTable[i], &subUpTable[0], maxVal+1);
  59. for (i = 0;i <= 255;i++)
  60. subDownTable[i] = (i * maxVal + 128) / 255;
  61. }
  62. }
  63. PixelFormat::PixelFormat(int b, int d, bool e, bool t,
  64. int rm, int gm, int bm, int rs, int gs, int bs)
  65. : bpp(b), depth(d), trueColour(t), bigEndian(e),
  66. redMax(rm), greenMax(gm), blueMax(bm),
  67. redShift(rs), greenShift(gs), blueShift(bs)
  68. {
  69. if (!isSane())
  70. throw Exception("invalid pixel format");
  71. updateState();
  72. }
  73. PixelFormat::PixelFormat()
  74. : bpp(8), depth(8), trueColour(true), bigEndian(false),
  75. redMax(7), greenMax(7), blueMax(3),
  76. redShift(0), greenShift(3), blueShift(6)
  77. {
  78. updateState();
  79. }
  80. bool PixelFormat::equal(const PixelFormat& other) const
  81. {
  82. if (bpp != other.bpp || depth != other.depth)
  83. return false;
  84. if (redMax != other.redMax)
  85. return false;
  86. if (greenMax != other.greenMax)
  87. return false;
  88. if (blueMax != other.blueMax)
  89. return false;
  90. // Endianness requires more care to determine compatibility
  91. if (bigEndian == other.bigEndian || bpp == 8) {
  92. if (redShift != other.redShift)
  93. return false;
  94. if (greenShift != other.greenShift)
  95. return false;
  96. if (blueShift != other.blueShift)
  97. return false;
  98. } else {
  99. // Has to be the same byte for each channel
  100. if (redShift/8 != (3 - other.redShift/8))
  101. return false;
  102. if (greenShift/8 != (3 - other.greenShift/8))
  103. return false;
  104. if (blueShift/8 != (3 - other.blueShift/8))
  105. return false;
  106. // And the same bit offset within the byte
  107. if (redShift%8 != other.redShift%8)
  108. return false;
  109. if (greenShift%8 != other.greenShift%8)
  110. return false;
  111. if (blueShift%8 != other.blueShift%8)
  112. return false;
  113. // And not cross a byte boundary
  114. if (redShift/8 != (redShift + redBits - 1)/8)
  115. return false;
  116. if (greenShift/8 != (greenShift + greenBits - 1)/8)
  117. return false;
  118. if (blueShift/8 != (blueShift + blueBits - 1)/8)
  119. return false;
  120. }
  121. return true;
  122. }
  123. void PixelFormat::read(rdr::InStream* is)
  124. {
  125. bpp = is->readU8();
  126. depth = is->readU8();
  127. bigEndian = is->readU8();
  128. trueColour = is->readU8();
  129. redMax = is->readU16();
  130. greenMax = is->readU16();
  131. blueMax = is->readU16();
  132. redShift = is->readU8();
  133. greenShift = is->readU8();
  134. blueShift = is->readU8();
  135. is->skip(3);
  136. // We have no real support for colour maps. If the client
  137. // wants one, then we force a 8-bit true colour format and
  138. // pretend it's a colour map.
  139. if (!trueColour) {
  140. redMax = 7;
  141. greenMax = 7;
  142. blueMax = 3;
  143. redShift = 0;
  144. greenShift = 3;
  145. blueShift = 6;
  146. }
  147. if (!isSane())
  148. throw Exception("invalid pixel format");
  149. updateState();
  150. }
  151. void PixelFormat::write(rdr::OutStream* os) const
  152. {
  153. os->writeU8(bpp);
  154. os->writeU8(depth);
  155. os->writeU8(bigEndian);
  156. os->writeU8(trueColour);
  157. os->writeU16(redMax);
  158. os->writeU16(greenMax);
  159. os->writeU16(blueMax);
  160. os->writeU8(redShift);
  161. os->writeU8(greenShift);
  162. os->writeU8(blueShift);
  163. os->pad(3);
  164. }
  165. bool PixelFormat::is888(void) const
  166. {
  167. if (!trueColour)
  168. return false;
  169. if (bpp != 32)
  170. return false;
  171. if (depth != 24)
  172. return false;
  173. if (redMax != 255)
  174. return false;
  175. if (greenMax != 255)
  176. return false;
  177. if (blueMax != 255)
  178. return false;
  179. if ((redShift & 0x7) != 0)
  180. return false;
  181. if ((greenShift & 0x7) != 0)
  182. return false;
  183. if ((blueShift & 0x7) != 0)
  184. return false;
  185. return true;
  186. }
  187. bool PixelFormat::isBigEndian(void) const
  188. {
  189. return bigEndian;
  190. }
  191. bool PixelFormat::isLittleEndian(void) const
  192. {
  193. return ! bigEndian;
  194. }
  195. void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int pixels) const
  196. {
  197. bufferFromRGB(dst, src, pixels, pixels, 1);
  198. }
  199. void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src,
  200. int w, int stride, int h) const
  201. {
  202. if (is888()) {
  203. // Optimised common case
  204. rdr::U8 *r, *g, *b, *x;
  205. if (bigEndian) {
  206. r = dst + (24 - redShift)/8;
  207. g = dst + (24 - greenShift)/8;
  208. b = dst + (24 - blueShift)/8;
  209. x = dst + (24 - (48 - redShift - greenShift - blueShift))/8;
  210. } else {
  211. r = dst + redShift/8;
  212. g = dst + greenShift/8;
  213. b = dst + blueShift/8;
  214. x = dst + (48 - redShift - greenShift - blueShift)/8;
  215. }
  216. int dstPad = (stride - w) * 4;
  217. while (h--) {
  218. int w_ = w;
  219. while (w_--) {
  220. *r = *(src++);
  221. *g = *(src++);
  222. *b = *(src++);
  223. *x = 0;
  224. r += 4;
  225. g += 4;
  226. b += 4;
  227. x += 4;
  228. }
  229. r += dstPad;
  230. g += dstPad;
  231. b += dstPad;
  232. x += dstPad;
  233. }
  234. } else {
  235. // Generic code
  236. int dstPad = (stride - w) * bpp/8;
  237. while (h--) {
  238. int w_ = w;
  239. while (w_--) {
  240. Pixel p;
  241. rdr::U8 r, g, b;
  242. r = *(src++);
  243. g = *(src++);
  244. b = *(src++);
  245. p = pixelFromRGB(r, g, b);
  246. bufferFromPixel(dst, p);
  247. dst += bpp/8;
  248. }
  249. dst += dstPad;
  250. }
  251. }
  252. }
  253. void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int pixels) const
  254. {
  255. rgbFromBuffer(dst, src, pixels, pixels, 1);
  256. }
  257. void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src,
  258. int w, int stride, int h) const
  259. {
  260. if (is888()) {
  261. // Optimised common case
  262. const rdr::U8 *r, *g, *b;
  263. if (bigEndian) {
  264. r = src + (24 - redShift)/8;
  265. g = src + (24 - greenShift)/8;
  266. b = src + (24 - blueShift)/8;
  267. } else {
  268. r = src + redShift/8;
  269. g = src + greenShift/8;
  270. b = src + blueShift/8;
  271. }
  272. int srcPad = (stride - w) * 4;
  273. while (h--) {
  274. int w_ = w;
  275. while (w_--) {
  276. *(dst++) = *r;
  277. *(dst++) = *g;
  278. *(dst++) = *b;
  279. r += 4;
  280. g += 4;
  281. b += 4;
  282. }
  283. r += srcPad;
  284. g += srcPad;
  285. b += srcPad;
  286. }
  287. } else {
  288. // Generic code
  289. int srcPad = (stride - w) * bpp/8;
  290. while (h--) {
  291. int w_ = w;
  292. while (w_--) {
  293. Pixel p;
  294. rdr::U8 r, g, b;
  295. p = pixelFromBuffer(src);
  296. rgbFromPixel(p, &r, &g, &b);
  297. *(dst++) = r;
  298. *(dst++) = g;
  299. *(dst++) = b;
  300. src += bpp/8;
  301. }
  302. src += srcPad;
  303. }
  304. }
  305. }
  306. Pixel PixelFormat::pixelFromPixel(const PixelFormat &srcPF, Pixel src) const
  307. {
  308. rdr::U16 r, g, b;
  309. srcPF.rgbFromPixel(src, &r, &g, &b);
  310. return pixelFromRGB(r, g, b);
  311. }
  312. void PixelFormat::bufferFromBuffer(rdr::U8* dst, const PixelFormat &srcPF,
  313. const rdr::U8* src, int pixels) const
  314. {
  315. bufferFromBuffer(dst, srcPF, src, pixels, 1, pixels, pixels);
  316. }
  317. #define IS_ALIGNED(v, a) (((intptr_t)v & (a-1)) == 0)
  318. void PixelFormat::bufferFromBuffer(rdr::U8* dst, const PixelFormat &srcPF,
  319. const rdr::U8* src, int w, int h,
  320. int dstStride, int srcStride) const
  321. {
  322. if (equal(srcPF)) {
  323. // Trivial case
  324. while (h--) {
  325. memcpy(dst, src, w * bpp/8);
  326. dst += dstStride * bpp/8;
  327. src += srcStride * srcPF.bpp/8;
  328. }
  329. } else if (is888() && srcPF.is888()) {
  330. // Optimised common case A: byte shuffling (e.g. endian conversion)
  331. rdr::U8 *d[4], *s[4];
  332. int dstPad, srcPad;
  333. if (bigEndian) {
  334. s[0] = dst + (24 - redShift)/8;
  335. s[1] = dst + (24 - greenShift)/8;
  336. s[2] = dst + (24 - blueShift)/8;
  337. s[3] = dst + (24 - (48 - redShift - greenShift - blueShift))/8;
  338. } else {
  339. s[0] = dst + redShift/8;
  340. s[1] = dst + greenShift/8;
  341. s[2] = dst + blueShift/8;
  342. s[3] = dst + (48 - redShift - greenShift - blueShift)/8;
  343. }
  344. if (srcPF.bigEndian) {
  345. d[(24 - srcPF.redShift)/8] = s[0];
  346. d[(24 - srcPF.greenShift)/8] = s[1];
  347. d[(24 - srcPF.blueShift)/8] = s[2];
  348. d[(24 - (48 - srcPF.redShift - srcPF.greenShift - srcPF.blueShift))/8] = s[3];
  349. } else {
  350. d[srcPF.redShift/8] = s[0];
  351. d[srcPF.greenShift/8] = s[1];
  352. d[srcPF.blueShift/8] = s[2];
  353. d[(48 - srcPF.redShift - srcPF.greenShift - srcPF.blueShift)/8] = s[3];
  354. }
  355. dstPad = (dstStride - w) * 4;
  356. srcPad = (srcStride - w) * 4;
  357. while (h--) {
  358. int w_ = w;
  359. while (w_--) {
  360. *d[0] = *(src++);
  361. *d[1] = *(src++);
  362. *d[2] = *(src++);
  363. *d[3] = *(src++);
  364. d[0] += 4;
  365. d[1] += 4;
  366. d[2] += 4;
  367. d[3] += 4;
  368. }
  369. d[0] += dstPad;
  370. d[1] += dstPad;
  371. d[2] += dstPad;
  372. d[3] += dstPad;
  373. src += srcPad;
  374. }
  375. } else if (IS_ALIGNED(dst, bpp/8) && srcPF.is888()) {
  376. // Optimised common case B: 888 source
  377. switch (bpp) {
  378. case 8:
  379. directBufferFromBufferFrom888((rdr::U8*)dst, srcPF, src,
  380. w, h, dstStride, srcStride);
  381. break;
  382. case 16:
  383. directBufferFromBufferFrom888((rdr::U16*)dst, srcPF, src,
  384. w, h, dstStride, srcStride);
  385. break;
  386. case 32:
  387. directBufferFromBufferFrom888((rdr::U32*)dst, srcPF, src,
  388. w, h, dstStride, srcStride);
  389. break;
  390. }
  391. } else if (IS_ALIGNED(src, srcPF.bpp/8) && is888()) {
  392. // Optimised common case C: 888 destination
  393. switch (srcPF.bpp) {
  394. case 8:
  395. directBufferFromBufferTo888(dst, srcPF, (rdr::U8*)src,
  396. w, h, dstStride, srcStride);
  397. break;
  398. case 16:
  399. directBufferFromBufferTo888(dst, srcPF, (rdr::U16*)src,
  400. w, h, dstStride, srcStride);
  401. break;
  402. case 32:
  403. directBufferFromBufferTo888(dst, srcPF, (rdr::U32*)src,
  404. w, h, dstStride, srcStride);
  405. break;
  406. }
  407. } else {
  408. // Generic code
  409. int dstPad = (dstStride - w) * bpp/8;
  410. int srcPad = (srcStride - w) * srcPF.bpp/8;
  411. while (h--) {
  412. int w_ = w;
  413. while (w_--) {
  414. Pixel p;
  415. rdr::U8 r, g, b;
  416. p = srcPF.pixelFromBuffer(src);
  417. srcPF.rgbFromPixel(p, &r, &g, &b);
  418. p = pixelFromRGB(r, g, b);
  419. bufferFromPixel(dst, p);
  420. dst += bpp/8;
  421. src += srcPF.bpp/8;
  422. }
  423. dst += dstPad;
  424. src += srcPad;
  425. }
  426. }
  427. }
  428. void PixelFormat::print(char* str, int len) const
  429. {
  430. // Unfortunately snprintf is not widely available so we build the string up
  431. // using strncat - not pretty, but should be safe against buffer overruns.
  432. char num[20];
  433. if (len < 1) return;
  434. str[0] = 0;
  435. strncat(str, "depth ", len-1-strlen(str));
  436. sprintf(num,"%d",depth);
  437. strncat(str, num, len-1-strlen(str));
  438. strncat(str, " (", len-1-strlen(str));
  439. sprintf(num,"%d",bpp);
  440. strncat(str, num, len-1-strlen(str));
  441. strncat(str, "bpp)", len-1-strlen(str));
  442. if (bpp != 8) {
  443. if (bigEndian)
  444. strncat(str, " big-endian", len-1-strlen(str));
  445. else
  446. strncat(str, " little-endian", len-1-strlen(str));
  447. }
  448. if (!trueColour) {
  449. strncat(str, " color-map", len-1-strlen(str));
  450. return;
  451. }
  452. if (blueShift == 0 && greenShift > blueShift && redShift > greenShift &&
  453. blueMax == (1 << greenShift) - 1 &&
  454. greenMax == (1 << (redShift-greenShift)) - 1 &&
  455. redMax == (1 << (depth-redShift)) - 1)
  456. {
  457. strncat(str, " rgb", len-1-strlen(str));
  458. sprintf(num,"%d",depth-redShift);
  459. strncat(str, num, len-1-strlen(str));
  460. sprintf(num,"%d",redShift-greenShift);
  461. strncat(str, num, len-1-strlen(str));
  462. sprintf(num,"%d",greenShift);
  463. strncat(str, num, len-1-strlen(str));
  464. return;
  465. }
  466. if (redShift == 0 && greenShift > redShift && blueShift > greenShift &&
  467. redMax == (1 << greenShift) - 1 &&
  468. greenMax == (1 << (blueShift-greenShift)) - 1 &&
  469. blueMax == (1 << (depth-blueShift)) - 1)
  470. {
  471. strncat(str, " bgr", len-1-strlen(str));
  472. sprintf(num,"%d",depth-blueShift);
  473. strncat(str, num, len-1-strlen(str));
  474. sprintf(num,"%d",blueShift-greenShift);
  475. strncat(str, num, len-1-strlen(str));
  476. sprintf(num,"%d",greenShift);
  477. strncat(str, num, len-1-strlen(str));
  478. return;
  479. }
  480. strncat(str, " rgb max ", len-1-strlen(str));
  481. sprintf(num,"%d,",redMax);
  482. strncat(str, num, len-1-strlen(str));
  483. sprintf(num,"%d,",greenMax);
  484. strncat(str, num, len-1-strlen(str));
  485. sprintf(num,"%d",blueMax);
  486. strncat(str, num, len-1-strlen(str));
  487. strncat(str, " shift ", len-1-strlen(str));
  488. sprintf(num,"%d,",redShift);
  489. strncat(str, num, len-1-strlen(str));
  490. sprintf(num,"%d,",greenShift);
  491. strncat(str, num, len-1-strlen(str));
  492. sprintf(num,"%d",blueShift);
  493. strncat(str, num, len-1-strlen(str));
  494. }
  495. bool PixelFormat::parse(const char* str)
  496. {
  497. char rgbbgr[4];
  498. int bits1, bits2, bits3;
  499. if (sscanf(str, "%3s%1d%1d%1d", rgbbgr, &bits1, &bits2, &bits3) < 4)
  500. return false;
  501. depth = bits1 + bits2 + bits3;
  502. bpp = depth <= 8 ? 8 : ((depth <= 16) ? 16 : 32);
  503. trueColour = true;
  504. rdr::U32 endianTest = 1;
  505. bigEndian = (*(rdr::U8*)&endianTest == 0);
  506. greenShift = bits3;
  507. greenMax = (1 << bits2) - 1;
  508. if (strcasecmp(rgbbgr, "bgr") == 0) {
  509. redShift = 0;
  510. redMax = (1 << bits3) - 1;
  511. blueShift = bits3 + bits2;
  512. blueMax = (1 << bits1) - 1;
  513. } else if (strcasecmp(rgbbgr, "rgb") == 0) {
  514. blueShift = 0;
  515. blueMax = (1 << bits3) - 1;
  516. redShift = bits3 + bits2;
  517. redMax = (1 << bits1) - 1;
  518. } else {
  519. return false;
  520. }
  521. assert(isSane());
  522. updateState();
  523. return true;
  524. }
  525. static int bits(rdr::U16 value)
  526. {
  527. int bits;
  528. bits = 16;
  529. if (!(value & 0xff00)) {
  530. bits -= 8;
  531. value <<= 8;
  532. }
  533. if (!(value & 0xf000)) {
  534. bits -= 4;
  535. value <<= 4;
  536. }
  537. if (!(value & 0xc000)) {
  538. bits -= 2;
  539. value <<= 2;
  540. }
  541. if (!(value & 0x8000)) {
  542. bits -= 1;
  543. value <<= 1;
  544. }
  545. return bits;
  546. }
  547. void PixelFormat::updateState(void)
  548. {
  549. int endianTest = 1;
  550. redBits = bits(redMax);
  551. greenBits = bits(greenMax);
  552. blueBits = bits(blueMax);
  553. maxBits = redBits;
  554. if (greenBits > maxBits)
  555. maxBits = greenBits;
  556. if (blueBits > maxBits)
  557. maxBits = blueBits;
  558. minBits = redBits;
  559. if (greenBits < minBits)
  560. minBits = greenBits;
  561. if (blueBits < minBits)
  562. minBits = blueBits;
  563. if (((*(char*)&endianTest) == 0) != bigEndian)
  564. endianMismatch = true;
  565. else
  566. endianMismatch = false;
  567. }
  568. bool PixelFormat::isSane(void)
  569. {
  570. int totalBits;
  571. if ((bpp != 8) && (bpp != 16) && (bpp != 32))
  572. return false;
  573. if (depth > bpp)
  574. return false;
  575. if (!trueColour && (depth != 8))
  576. return false;
  577. if ((redMax & (redMax + 1)) != 0)
  578. return false;
  579. if ((greenMax & (greenMax + 1)) != 0)
  580. return false;
  581. if ((blueMax & (blueMax + 1)) != 0)
  582. return false;
  583. /*
  584. * We don't allow individual channels > 8 bits in order to keep our
  585. * conversions simple.
  586. */
  587. if (redMax >= (1 << 8))
  588. return false;
  589. if (greenMax >= (1 << 8))
  590. return false;
  591. if (blueMax >= (1 << 8))
  592. return false;
  593. totalBits = bits(redMax) + bits(greenMax) + bits(blueMax);
  594. if (totalBits > depth)
  595. return false;
  596. if ((bits(redMax) + redShift) > bpp)
  597. return false;
  598. if ((bits(greenMax) + greenShift) > bpp)
  599. return false;
  600. if ((bits(blueMax) + blueShift) > bpp)
  601. return false;
  602. if (((redMax << redShift) & (greenMax << greenShift)) != 0)
  603. return false;
  604. if (((redMax << redShift) & (blueMax << blueShift)) != 0)
  605. return false;
  606. if (((greenMax << greenShift) & (blueMax << blueShift)) != 0)
  607. return false;
  608. return true;
  609. }
  610. // Preprocessor generated, optimised methods
  611. #define INBPP 8
  612. #define OUTBPP 8
  613. #include "PixelFormatBPP.cxx"
  614. #undef OUTBPP
  615. #define OUTBPP 16
  616. #include "PixelFormatBPP.cxx"
  617. #undef OUTBPP
  618. #define OUTBPP 32
  619. #include "PixelFormatBPP.cxx"
  620. #undef OUTBPP
  621. #undef INBPP
  622. #define INBPP 16
  623. #define OUTBPP 8
  624. #include "PixelFormatBPP.cxx"
  625. #undef OUTBPP
  626. #define OUTBPP 16
  627. #include "PixelFormatBPP.cxx"
  628. #undef OUTBPP
  629. #define OUTBPP 32
  630. #include "PixelFormatBPP.cxx"
  631. #undef OUTBPP
  632. #undef INBPP
  633. #define INBPP 32
  634. #define OUTBPP 8
  635. #include "PixelFormatBPP.cxx"
  636. #undef OUTBPP
  637. #define OUTBPP 16
  638. #include "PixelFormatBPP.cxx"
  639. #undef OUTBPP
  640. #define OUTBPP 32
  641. #include "PixelFormatBPP.cxx"
  642. #undef OUTBPP
  643. #undef INBPP