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.

TransImageGetter.cxx 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
  2. *
  3. * This is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This software is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this software; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  16. * USA.
  17. */
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <rfb/PixelFormat.h>
  21. #include <rfb/Exception.h>
  22. #include <rfb/ConnParams.h>
  23. #include <rfb/SMsgWriter.h>
  24. #include <rfb/ColourMap.h>
  25. #include <rfb/TrueColourMap.h>
  26. #include <rfb/PixelBuffer.h>
  27. #include <rfb/ColourCube.h>
  28. #include <rfb/TransImageGetter.h>
  29. using namespace rfb;
  30. const PixelFormat bgr233PF(8, 8, false, true, 7, 7, 3, 0, 3, 6);
  31. static void noTransFn(void* table_,
  32. const PixelFormat& inPF, void* inPtr, int inStride,
  33. const PixelFormat& outPF, void* outPtr, int outStride,
  34. int width, int height)
  35. {
  36. rdr::U8* ip = (rdr::U8*)inPtr;
  37. rdr::U8* op = (rdr::U8*)outPtr;
  38. int inStrideBytes = inStride * (inPF.bpp/8);
  39. int outStrideBytes = outStride * (outPF.bpp/8);
  40. int widthBytes = width * (outPF.bpp/8);
  41. while (height > 0) {
  42. memcpy(op, ip, widthBytes);
  43. ip += inStrideBytes;
  44. op += outStrideBytes;
  45. height--;
  46. }
  47. }
  48. #define BPPOUT 8
  49. #include "transInitTempl.h"
  50. #define BPPIN 8
  51. #include "transTempl.h"
  52. #undef BPPIN
  53. #define BPPIN 16
  54. #include "transTempl.h"
  55. #undef BPPIN
  56. #define BPPIN 32
  57. #include "transTempl.h"
  58. #undef BPPIN
  59. #undef BPPOUT
  60. #define BPPOUT 16
  61. #include "transInitTempl.h"
  62. #define BPPIN 8
  63. #include "transTempl.h"
  64. #undef BPPIN
  65. #define BPPIN 16
  66. #include "transTempl.h"
  67. #undef BPPIN
  68. #define BPPIN 32
  69. #include "transTempl.h"
  70. #undef BPPIN
  71. #undef BPPOUT
  72. #define BPPOUT 32
  73. #include "transInitTempl.h"
  74. #define BPPIN 8
  75. #include "transTempl.h"
  76. #undef BPPIN
  77. #define BPPIN 16
  78. #include "transTempl.h"
  79. #undef BPPIN
  80. #define BPPIN 32
  81. #include "transTempl.h"
  82. #undef BPPIN
  83. #undef BPPOUT
  84. // Translation functions. Note that transSimple* is only used for 8/16bpp and
  85. // transRGB* is used for 16/32bpp
  86. static transFnType transSimpleFns[][3] = {
  87. { transSimple8to8, transSimple8to16, transSimple8to32 },
  88. { transSimple16to8, transSimple16to16, transSimple16to32 },
  89. };
  90. static transFnType transRGBFns[][3] = {
  91. { transRGB16to8, transRGB16to16, transRGB16to32 },
  92. { transRGB32to8, transRGB32to16, transRGB32to32 }
  93. };
  94. static transFnType transRGBCubeFns[][3] = {
  95. { transRGBCube16to8, transRGBCube16to16, transRGBCube16to32 },
  96. { transRGBCube32to8, transRGBCube32to16, transRGBCube32to32 }
  97. };
  98. // Table initialisation functions.
  99. typedef void (*initCMtoTCFnType)(rdr::U8** tablep, const PixelFormat& inPF,
  100. ColourMap* cm, const PixelFormat& outPF);
  101. typedef void (*initTCtoTCFnType)(rdr::U8** tablep, const PixelFormat& inPF,
  102. const PixelFormat& outPF);
  103. typedef void (*initCMtoCubeFnType)(rdr::U8** tablep, const PixelFormat& inPF,
  104. ColourMap* cm, ColourCube* cube);
  105. typedef void (*initTCtoCubeFnType)(rdr::U8** tablep, const PixelFormat& inPF,
  106. ColourCube* cube);
  107. static initCMtoTCFnType initSimpleCMtoTCFns[] = {
  108. initSimpleCMtoTC8, initSimpleCMtoTC16, initSimpleCMtoTC32
  109. };
  110. static initTCtoTCFnType initSimpleTCtoTCFns[] = {
  111. initSimpleTCtoTC8, initSimpleTCtoTC16, initSimpleTCtoTC32
  112. };
  113. static initCMtoCubeFnType initSimpleCMtoCubeFns[] = {
  114. initSimpleCMtoCube8, initSimpleCMtoCube16, initSimpleCMtoCube32
  115. };
  116. static initTCtoCubeFnType initSimpleTCtoCubeFns[] = {
  117. initSimpleTCtoCube8, initSimpleTCtoCube16, initSimpleTCtoCube32
  118. };
  119. static initTCtoTCFnType initRGBTCtoTCFns[] = {
  120. initRGBTCtoTC8, initRGBTCtoTC16, initRGBTCtoTC32
  121. };
  122. static initTCtoCubeFnType initRGBTCtoCubeFns[] = {
  123. initRGBTCtoCube8, initRGBTCtoCube16, initRGBTCtoCube32
  124. };
  125. TransImageGetter::TransImageGetter(bool econ)
  126. : economic(econ), pb(0), table(0), transFn(0), cube(0)
  127. {
  128. }
  129. TransImageGetter::~TransImageGetter()
  130. {
  131. delete [] table;
  132. }
  133. void TransImageGetter::init(PixelBuffer* pb_, const PixelFormat& out,
  134. SMsgWriter* writer, ColourCube* cube_)
  135. {
  136. pb = pb_;
  137. outPF = out;
  138. transFn = 0;
  139. cube = cube_;
  140. const PixelFormat& inPF = pb->getPF();
  141. if ((inPF.bpp != 8) && (inPF.bpp != 16) && (inPF.bpp != 32))
  142. throw Exception("TransImageGetter: bpp in not 8, 16 or 32");
  143. if ((outPF.bpp != 8) && (outPF.bpp != 16) && (outPF.bpp != 32))
  144. throw Exception("TransImageGetter: bpp out not 8, 16 or 32");
  145. if (!outPF.trueColour) {
  146. if (outPF.bpp != 8)
  147. throw Exception("TransImageGetter: outPF has color map but not 8bpp");
  148. if (!inPF.trueColour) {
  149. if (inPF.bpp != 8)
  150. throw Exception("TransImageGetter: inPF has colorMap but not 8bpp");
  151. // CM to CM/Cube
  152. if (cube) {
  153. transFn = transSimpleFns[inPF.bpp/16][outPF.bpp/16];
  154. (*initSimpleCMtoCubeFns[outPF.bpp/16]) (&table, inPF,
  155. pb->getColourMap(), cube);
  156. } else {
  157. transFn = noTransFn;
  158. setColourMapEntries(0, 256, writer);
  159. }
  160. return;
  161. }
  162. // TC to CM/Cube
  163. ColourCube defaultCube(6,6,6);
  164. if (!cube) cube = &defaultCube;
  165. if ((inPF.bpp > 16) || (economic && (inPF.bpp == 16))) {
  166. transFn = transRGBCubeFns[inPF.bpp/32][outPF.bpp/16];
  167. (*initRGBTCtoCubeFns[outPF.bpp/16]) (&table, inPF, cube);
  168. } else {
  169. transFn = transSimpleFns[inPF.bpp/16][outPF.bpp/16];
  170. (*initSimpleTCtoCubeFns[outPF.bpp/16]) (&table, inPF, cube);
  171. }
  172. if (cube != &defaultCube)
  173. return;
  174. if (writer) writer->writeSetColourMapEntries(0, 216, cube);
  175. cube = 0;
  176. return;
  177. }
  178. if (inPF.equal(outPF)) {
  179. transFn = noTransFn;
  180. return;
  181. }
  182. if (!inPF.trueColour) {
  183. // CM to TC
  184. if (inPF.bpp != 8)
  185. throw Exception("TransImageGetter: inPF has colorMap but not 8bpp");
  186. transFn = transSimpleFns[inPF.bpp/16][outPF.bpp/16];
  187. (*initSimpleCMtoTCFns[outPF.bpp/16]) (&table, inPF, pb->getColourMap(),
  188. outPF);
  189. return;
  190. }
  191. // TC to TC
  192. if ((inPF.bpp > 16) || (economic && (inPF.bpp == 16))) {
  193. transFn = transRGBFns[inPF.bpp/32][outPF.bpp/16];
  194. (*initRGBTCtoTCFns[outPF.bpp/16]) (&table, inPF, outPF);
  195. } else {
  196. transFn = transSimpleFns[inPF.bpp/16][outPF.bpp/16];
  197. (*initSimpleTCtoTCFns[outPF.bpp/16]) (&table, inPF, outPF);
  198. }
  199. }
  200. void TransImageGetter::setColourMapEntries(int firstCol, int nCols,
  201. SMsgWriter* writer)
  202. {
  203. if (nCols == 0)
  204. nCols = (1 << pb->getPF().depth) - firstCol;
  205. if (pb->getPF().trueColour) return; // shouldn't be called in this case
  206. if (outPF.trueColour) {
  207. (*initSimpleCMtoTCFns[outPF.bpp/16]) (&table, pb->getPF(),
  208. pb->getColourMap(), outPF);
  209. } else if (cube) {
  210. (*initSimpleCMtoCubeFns[outPF.bpp/16]) (&table, pb->getPF(),
  211. pb->getColourMap(), cube);
  212. } else if (writer && pb->getColourMap()) {
  213. writer->writeSetColourMapEntries(firstCol, nCols, pb->getColourMap());
  214. }
  215. }
  216. void TransImageGetter::getImage(void* outPtr, const Rect& r, int outStride)
  217. {
  218. if (!transFn)
  219. throw Exception("TransImageGetter: not initialised yet");
  220. int inStride;
  221. const rdr::U8* inPtr = pb->getPixelsR(r.translate(offset.negate()), &inStride);
  222. if (!outStride) outStride = r.width();
  223. (*transFn)(table, pb->getPF(), (void*)inPtr, inStride,
  224. outPF, outPtr, outStride, r.width(), r.height());
  225. }
  226. void TransImageGetter::translatePixels(void* inPtr, void* outPtr,
  227. int nPixels) const
  228. {
  229. (*transFn)(table, pb->getPF(), inPtr, nPixels,
  230. outPF, outPtr, nPixels, nPixels, 1);
  231. }