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.

TightEncoderBPP.cxx 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /* Copyright (C) 2000-2003 Constantin Kaplinsky. All Rights Reserved.
  2. * Copyright (C) 2011 D. R. Commander. All Rights Reserved.
  3. * Copyright 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. #define CONCAT2(a,b) a##b
  21. #define CONCAT2E(a,b) CONCAT2(a,b)
  22. #define UBPP CONCAT2E(U,BPP)
  23. void TightEncoder::writeMonoRect(int width, int height,
  24. const rdr::UBPP* buffer, int stride,
  25. const PixelFormat& pf,
  26. const Palette& palette)
  27. {
  28. rdr::OutStream* os;
  29. const int streamId = 1;
  30. rdr::UBPP pal[2];
  31. int length;
  32. rdr::OutStream* zos;
  33. assert(palette.size() == 2);
  34. os = conn->getOutStream();
  35. os->writeU8((streamId | tightExplicitFilter) << 4);
  36. os->writeU8(tightFilterPalette);
  37. // Write the palette
  38. pal[0] = (rdr::UBPP)palette.getColour(0);
  39. pal[1] = (rdr::UBPP)palette.getColour(1);
  40. os->writeU8(1);
  41. writePixels((rdr::U8*)pal, pf, 2, os);
  42. // Set up compression
  43. length = (width + 7)/8 * height;
  44. zos = getZlibOutStream(streamId, monoZlibLevel, length);
  45. // Encode the data
  46. rdr::UBPP bg;
  47. unsigned int value, mask;
  48. int pad, aligned_width;
  49. int x, y, bg_bits;
  50. bg = pal[0];
  51. aligned_width = width - width % 8;
  52. pad = stride - width;
  53. for (y = 0; y < height; y++) {
  54. for (x = 0; x < aligned_width; x += 8) {
  55. for (bg_bits = 0; bg_bits < 8; bg_bits++) {
  56. if (*buffer++ != bg)
  57. break;
  58. }
  59. if (bg_bits == 8) {
  60. zos->writeU8(0);
  61. continue;
  62. }
  63. mask = 0x80 >> bg_bits;
  64. value = mask;
  65. for (bg_bits++; bg_bits < 8; bg_bits++) {
  66. mask >>= 1;
  67. if (*buffer++ != bg) {
  68. value |= mask;
  69. }
  70. }
  71. zos->writeU8(value);
  72. }
  73. if (x < width) {
  74. mask = 0x80;
  75. value = 0;
  76. for (; x < width; x++) {
  77. if (*buffer++ != bg) {
  78. value |= mask;
  79. }
  80. mask >>= 1;
  81. }
  82. zos->writeU8(value);
  83. }
  84. buffer += pad;
  85. }
  86. // Finish the zlib stream
  87. flushZlibOutStream(zos);
  88. }
  89. #if (BPP != 8)
  90. void TightEncoder::writeIndexedRect(int width, int height,
  91. const rdr::UBPP* buffer, int stride,
  92. const PixelFormat& pf,
  93. const Palette& palette)
  94. {
  95. rdr::OutStream* os;
  96. const int streamId = 2;
  97. rdr::UBPP pal[256];
  98. rdr::OutStream* zos;
  99. int pad;
  100. rdr::UBPP prevColour;
  101. unsigned char idx;
  102. assert(palette.size() > 0);
  103. assert(palette.size() <= 256);
  104. os = conn->getOutStream();
  105. os->writeU8((streamId | tightExplicitFilter) << 4);
  106. os->writeU8(tightFilterPalette);
  107. // Write the palette
  108. for (int i = 0; i < palette.size(); i++)
  109. pal[i] = (rdr::UBPP)palette.getColour(i);
  110. os->writeU8(palette.size() - 1);
  111. writePixels((rdr::U8*)pal, pf, palette.size(), os);
  112. // Set up compression
  113. zos = getZlibOutStream(streamId, idxZlibLevel, width * height);
  114. // Encode the data
  115. pad = stride - width;
  116. prevColour = *buffer;
  117. idx = palette.lookup(*buffer);
  118. while (height--) {
  119. int w = width;
  120. while (w--) {
  121. if (*buffer != prevColour) {
  122. prevColour = *buffer;
  123. idx = palette.lookup(*buffer);
  124. }
  125. zos->writeU8(idx);
  126. buffer++;
  127. }
  128. buffer += pad;
  129. }
  130. // Finish the zlib stream
  131. flushZlibOutStream(zos);
  132. }
  133. #endif // #if (BPP != 8)