SkMasks.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * Copyright 2015 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "include/core/SkTypes.h"
  8. #include "src/codec/SkCodecPriv.h"
  9. #include "src/codec/SkMasks.h"
  10. /*
  11. *
  12. * Used to convert 1-7 bit color components into 8-bit color components
  13. *
  14. */
  15. static constexpr uint8_t n_bit_to_8_bit_lookup_table[] = {
  16. // 1 bit
  17. 0, 255,
  18. // 2 bits
  19. 0, 85, 170, 255,
  20. // 3 bits
  21. 0, 36, 73, 109, 146, 182, 219, 255,
  22. // 4 bits
  23. 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255,
  24. // 5 bits
  25. 0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99, 107, 115, 123, 132, 140,
  26. 148, 156, 165, 173, 181, 189, 197, 206, 214, 222, 230, 239, 247, 255,
  27. // 6 bits
  28. 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 53, 57, 61, 65, 69, 73,
  29. 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 130, 134, 138,
  30. 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, 194, 198,
  31. 202, 206, 210, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255,
  32. // 7 bits
  33. 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38,
  34. 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76,
  35. 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110,
  36. 112, 114, 116, 118, 120, 122, 124, 126, 129, 131, 133, 135, 137, 139, 141,
  37. 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171,
  38. 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201,
  39. 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231,
  40. 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255
  41. };
  42. /*
  43. *
  44. * Convert an n bit component to an 8-bit component
  45. *
  46. */
  47. static uint8_t convert_to_8(uint8_t component, uint32_t n) {
  48. if (0 == n) {
  49. return 0;
  50. } else if (8 > n) {
  51. return n_bit_to_8_bit_lookup_table[(1 << n) - 2 + component];
  52. } else {
  53. SkASSERT(8 == n);
  54. return component;
  55. }
  56. }
  57. static uint8_t get_comp(uint32_t pixel, uint32_t mask, uint32_t shift,
  58. uint32_t size) {
  59. return convert_to_8((pixel & mask) >> shift, size);
  60. }
  61. /*
  62. *
  63. * Get a color component
  64. *
  65. */
  66. uint8_t SkMasks::getRed(uint32_t pixel) const {
  67. return get_comp(pixel, fRed.mask, fRed.shift, fRed.size);
  68. }
  69. uint8_t SkMasks::getGreen(uint32_t pixel) const {
  70. return get_comp(pixel, fGreen.mask, fGreen.shift, fGreen.size);
  71. }
  72. uint8_t SkMasks::getBlue(uint32_t pixel) const {
  73. return get_comp(pixel, fBlue.mask, fBlue.shift, fBlue.size);
  74. }
  75. uint8_t SkMasks::getAlpha(uint32_t pixel) const {
  76. return get_comp(pixel, fAlpha.mask, fAlpha.shift, fAlpha.size);
  77. }
  78. /*
  79. *
  80. * Process an input mask to obtain the necessary information
  81. *
  82. */
  83. static const SkMasks::MaskInfo process_mask(uint32_t mask) {
  84. // Determine properties of the mask
  85. uint32_t tempMask = mask;
  86. uint32_t shift = 0;
  87. uint32_t size = 0;
  88. if (tempMask != 0) {
  89. // Count trailing zeros on masks
  90. for (; (tempMask & 1) == 0; tempMask >>= 1) {
  91. shift++;
  92. }
  93. // Count the size of the mask
  94. for (; tempMask & 1; tempMask >>= 1) {
  95. size++;
  96. }
  97. // Verify that the mask is continuous
  98. if (tempMask) {
  99. SkCodecPrintf("Warning: Bit mask is not continuous.\n");
  100. // Finish processing the mask
  101. for (; tempMask; tempMask >>= 1) {
  102. size++;
  103. }
  104. }
  105. // Truncate masks greater than 8 bits
  106. if (size > 8) {
  107. shift += size - 8;
  108. size = 8;
  109. mask &= 0xFF << shift;
  110. }
  111. }
  112. return { mask, shift, size };
  113. }
  114. /*
  115. *
  116. * Create the masks object
  117. *
  118. */
  119. SkMasks* SkMasks::CreateMasks(InputMasks masks, int bytesPerPixel) {
  120. SkASSERT(0 < bytesPerPixel && bytesPerPixel <= 4);
  121. // Trim the input masks to match bytesPerPixel.
  122. if (bytesPerPixel < 4) {
  123. int bitsPerPixel = 8*bytesPerPixel;
  124. masks.red &= (1 << bitsPerPixel) - 1;
  125. masks.green &= (1 << bitsPerPixel) - 1;
  126. masks.blue &= (1 << bitsPerPixel) - 1;
  127. masks.alpha &= (1 << bitsPerPixel) - 1;
  128. }
  129. // Check that masks do not overlap.
  130. if (((masks.red & masks.green) |
  131. (masks.red & masks.blue ) |
  132. (masks.red & masks.alpha) |
  133. (masks.green & masks.blue ) |
  134. (masks.green & masks.alpha) |
  135. (masks.blue & masks.alpha) ) != 0) {
  136. return nullptr;
  137. }
  138. return new SkMasks(process_mask(masks.red ),
  139. process_mask(masks.green),
  140. process_mask(masks.blue ),
  141. process_mask(masks.alpha));
  142. }
  143. SkMasks::SkMasks(const MaskInfo& red, const MaskInfo& green,
  144. const MaskInfo& blue, const MaskInfo& alpha)
  145. : fRed(red)
  146. , fGreen(green)
  147. , fBlue(blue)
  148. , fAlpha(alpha)
  149. {}