Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

PixelFormat.cxx 17KB

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