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.

PixelFormat.cxx 17KB

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