SkSwizzler.cpp 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237
  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/private/SkColorData.h"
  8. #include "include/private/SkHalf.h"
  9. #include "include/private/SkTemplates.h"
  10. #include "src/codec/SkCodecPriv.h"
  11. #include "src/codec/SkSwizzler.h"
  12. #include "src/core/SkOpts.h"
  13. #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
  14. #include "include/android/SkAndroidFrameworkUtils.h"
  15. #endif
  16. static void copy(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  17. const SkPMColor ctable[]) {
  18. // This function must not be called if we are sampling. If we are not
  19. // sampling, deltaSrc should equal bpp.
  20. SkASSERT(deltaSrc == bpp);
  21. memcpy(dst, src + offset, width * bpp);
  22. }
  23. static void sample1(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  24. const SkPMColor ctable[]) {
  25. src += offset;
  26. uint8_t* dst8 = (uint8_t*) dst;
  27. for (int x = 0; x < width; x++) {
  28. dst8[x] = *src;
  29. src += deltaSrc;
  30. }
  31. }
  32. static void sample2(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  33. const SkPMColor ctable[]) {
  34. src += offset;
  35. uint16_t* dst16 = (uint16_t*) dst;
  36. for (int x = 0; x < width; x++) {
  37. dst16[x] = *((const uint16_t*) src);
  38. src += deltaSrc;
  39. }
  40. }
  41. static void sample4(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  42. const SkPMColor ctable[]) {
  43. src += offset;
  44. uint32_t* dst32 = (uint32_t*) dst;
  45. for (int x = 0; x < width; x++) {
  46. dst32[x] = *((const uint32_t*) src);
  47. src += deltaSrc;
  48. }
  49. }
  50. static void sample6(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  51. const SkPMColor ctable[]) {
  52. src += offset;
  53. uint8_t* dst8 = (uint8_t*) dst;
  54. for (int x = 0; x < width; x++) {
  55. memcpy(dst8, src, 6);
  56. dst8 += 6;
  57. src += deltaSrc;
  58. }
  59. }
  60. static void sample8(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  61. const SkPMColor ctable[]) {
  62. src += offset;
  63. uint64_t* dst64 = (uint64_t*) dst;
  64. for (int x = 0; x < width; x++) {
  65. dst64[x] = *((const uint64_t*) src);
  66. src += deltaSrc;
  67. }
  68. }
  69. // kBit
  70. // These routines exclusively choose between white and black
  71. #define GRAYSCALE_BLACK 0
  72. #define GRAYSCALE_WHITE 0xFF
  73. // same as swizzle_bit_to_index and swizzle_bit_to_n32 except for value assigned to dst[x]
  74. static void swizzle_bit_to_grayscale(
  75. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  76. int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
  77. uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
  78. // increment src by byte offset and bitIndex by bit offset
  79. src += offset / 8;
  80. int bitIndex = offset % 8;
  81. uint8_t currByte = *src;
  82. dst[0] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK;
  83. for (int x = 1; x < dstWidth; x++) {
  84. int bitOffset = bitIndex + deltaSrc;
  85. bitIndex = bitOffset % 8;
  86. currByte = *(src += bitOffset / 8);
  87. dst[x] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK;
  88. }
  89. }
  90. #undef GRAYSCALE_BLACK
  91. #undef GRAYSCALE_WHITE
  92. // same as swizzle_bit_to_grayscale and swizzle_bit_to_index except for value assigned to dst[x]
  93. static void swizzle_bit_to_n32(
  94. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  95. int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
  96. SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow;
  97. // increment src by byte offset and bitIndex by bit offset
  98. src += offset / 8;
  99. int bitIndex = offset % 8;
  100. uint8_t currByte = *src;
  101. dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? SK_ColorWHITE : SK_ColorBLACK;
  102. for (int x = 1; x < dstWidth; x++) {
  103. int bitOffset = bitIndex + deltaSrc;
  104. bitIndex = bitOffset % 8;
  105. currByte = *(src += bitOffset / 8);
  106. dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? SK_ColorWHITE : SK_ColorBLACK;
  107. }
  108. }
  109. #define RGB565_BLACK 0
  110. #define RGB565_WHITE 0xFFFF
  111. static void swizzle_bit_to_565(
  112. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  113. int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
  114. uint16_t* SK_RESTRICT dst = (uint16_t*) dstRow;
  115. // increment src by byte offset and bitIndex by bit offset
  116. src += offset / 8;
  117. int bitIndex = offset % 8;
  118. uint8_t currByte = *src;
  119. dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? RGB565_WHITE : RGB565_BLACK;
  120. for (int x = 1; x < dstWidth; x++) {
  121. int bitOffset = bitIndex + deltaSrc;
  122. bitIndex = bitOffset % 8;
  123. currByte = *(src += bitOffset / 8);
  124. dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? RGB565_WHITE : RGB565_BLACK;
  125. }
  126. }
  127. #undef RGB565_BLACK
  128. #undef RGB565_WHITE
  129. static void swizzle_bit_to_f16(
  130. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  131. int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
  132. constexpr uint64_t kWhite = (((uint64_t) SK_Half1) << 0) |
  133. (((uint64_t) SK_Half1) << 16) |
  134. (((uint64_t) SK_Half1) << 32) |
  135. (((uint64_t) SK_Half1) << 48);
  136. constexpr uint64_t kBlack = (((uint64_t) 0) << 0) |
  137. (((uint64_t) 0) << 16) |
  138. (((uint64_t) 0) << 32) |
  139. (((uint64_t) SK_Half1) << 48);
  140. uint64_t* SK_RESTRICT dst = (uint64_t*) dstRow;
  141. // increment src by byte offset and bitIndex by bit offset
  142. src += offset / 8;
  143. int bitIndex = offset % 8;
  144. uint8_t currByte = *src;
  145. dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? kWhite : kBlack;
  146. for (int x = 1; x < dstWidth; x++) {
  147. int bitOffset = bitIndex + deltaSrc;
  148. bitIndex = bitOffset % 8;
  149. currByte = *(src += bitOffset / 8);
  150. dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? kWhite : kBlack;
  151. }
  152. }
  153. // kIndex1, kIndex2, kIndex4
  154. static void swizzle_small_index_to_565(
  155. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  156. int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
  157. uint16_t* dst = (uint16_t*) dstRow;
  158. src += offset / 8;
  159. int bitIndex = offset % 8;
  160. uint8_t currByte = *src;
  161. const uint8_t mask = (1 << bpp) - 1;
  162. uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask;
  163. dst[0] = SkPixel32ToPixel16(ctable[index]);
  164. for (int x = 1; x < dstWidth; x++) {
  165. int bitOffset = bitIndex + deltaSrc;
  166. bitIndex = bitOffset % 8;
  167. currByte = *(src += bitOffset / 8);
  168. index = (currByte >> (8 - bpp - bitIndex)) & mask;
  169. dst[x] = SkPixel32ToPixel16(ctable[index]);
  170. }
  171. }
  172. static void swizzle_small_index_to_n32(
  173. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  174. int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
  175. SkPMColor* dst = (SkPMColor*) dstRow;
  176. src += offset / 8;
  177. int bitIndex = offset % 8;
  178. uint8_t currByte = *src;
  179. const uint8_t mask = (1 << bpp) - 1;
  180. uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask;
  181. dst[0] = ctable[index];
  182. for (int x = 1; x < dstWidth; x++) {
  183. int bitOffset = bitIndex + deltaSrc;
  184. bitIndex = bitOffset % 8;
  185. currByte = *(src += bitOffset / 8);
  186. index = (currByte >> (8 - bpp - bitIndex)) & mask;
  187. dst[x] = ctable[index];
  188. }
  189. }
  190. // kIndex
  191. static void swizzle_index_to_n32(
  192. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  193. int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
  194. src += offset;
  195. SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
  196. for (int x = 0; x < dstWidth; x++) {
  197. SkPMColor c = ctable[*src];
  198. dst[x] = c;
  199. src += deltaSrc;
  200. }
  201. }
  202. static void swizzle_index_to_n32_skipZ(
  203. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  204. int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
  205. src += offset;
  206. SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
  207. for (int x = 0; x < dstWidth; x++) {
  208. SkPMColor c = ctable[*src];
  209. if (c != 0) {
  210. dst[x] = c;
  211. }
  212. src += deltaSrc;
  213. }
  214. }
  215. static void swizzle_index_to_565(
  216. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  217. int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
  218. src += offset;
  219. uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
  220. for (int x = 0; x < dstWidth; x++) {
  221. dst[x] = SkPixel32ToPixel16(ctable[*src]);
  222. src += deltaSrc;
  223. }
  224. }
  225. // kGray
  226. static void swizzle_gray_to_n32(
  227. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  228. int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
  229. src += offset;
  230. SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
  231. for (int x = 0; x < dstWidth; x++) {
  232. dst[x] = SkPackARGB32NoCheck(0xFF, *src, *src, *src);
  233. src += deltaSrc;
  234. }
  235. }
  236. static void fast_swizzle_gray_to_n32(
  237. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  238. const SkPMColor ctable[]) {
  239. // This function must not be called if we are sampling. If we are not
  240. // sampling, deltaSrc should equal bpp.
  241. SkASSERT(deltaSrc == bpp);
  242. // Note that there is no need to distinguish between RGB and BGR.
  243. // Each color channel will get the same value.
  244. SkOpts::gray_to_RGB1((uint32_t*) dst, src + offset, width);
  245. }
  246. static void swizzle_gray_to_565(
  247. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  248. int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
  249. src += offset;
  250. uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
  251. for (int x = 0; x < dstWidth; x++) {
  252. dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]);
  253. src += deltaSrc;
  254. }
  255. }
  256. // kGrayAlpha
  257. static void swizzle_grayalpha_to_n32_unpremul(
  258. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  259. const SkPMColor ctable[]) {
  260. src += offset;
  261. SkPMColor* dst32 = (SkPMColor*) dst;
  262. for (int x = 0; x < width; x++) {
  263. dst32[x] = SkPackARGB32NoCheck(src[1], src[0], src[0], src[0]);
  264. src += deltaSrc;
  265. }
  266. }
  267. static void fast_swizzle_grayalpha_to_n32_unpremul(
  268. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  269. const SkPMColor ctable[]) {
  270. // This function must not be called if we are sampling. If we are not
  271. // sampling, deltaSrc should equal bpp.
  272. SkASSERT(deltaSrc == bpp);
  273. // Note that there is no need to distinguish between RGB and BGR.
  274. // Each color channel will get the same value.
  275. SkOpts::grayA_to_RGBA((uint32_t*) dst, src + offset, width);
  276. }
  277. static void swizzle_grayalpha_to_n32_premul(
  278. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  279. const SkPMColor ctable[]) {
  280. src += offset;
  281. SkPMColor* dst32 = (SkPMColor*) dst;
  282. for (int x = 0; x < width; x++) {
  283. uint8_t pmgray = SkMulDiv255Round(src[1], src[0]);
  284. dst32[x] = SkPackARGB32NoCheck(src[1], pmgray, pmgray, pmgray);
  285. src += deltaSrc;
  286. }
  287. }
  288. static void fast_swizzle_grayalpha_to_n32_premul(
  289. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  290. const SkPMColor ctable[]) {
  291. // This function must not be called if we are sampling. If we are not
  292. // sampling, deltaSrc should equal bpp.
  293. SkASSERT(deltaSrc == bpp);
  294. // Note that there is no need to distinguish between rgb and bgr.
  295. // Each color channel will get the same value.
  296. SkOpts::grayA_to_rgbA((uint32_t*) dst, src + offset, width);
  297. }
  298. static void swizzle_grayalpha_to_a8(void* dst, const uint8_t* src, int width, int bpp,
  299. int deltaSrc, int offset, const SkPMColor[]) {
  300. src += offset;
  301. uint8_t* dst8 = (uint8_t*)dst;
  302. for (int x = 0; x < width; ++x) {
  303. dst8[x] = src[1]; // src[0] is gray, ignored
  304. src += deltaSrc;
  305. }
  306. }
  307. // kBGR
  308. static void swizzle_bgr_to_565(
  309. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  310. int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
  311. src += offset;
  312. uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
  313. for (int x = 0; x < dstWidth; x++) {
  314. dst[x] = SkPack888ToRGB16(src[2], src[1], src[0]);
  315. src += deltaSrc;
  316. }
  317. }
  318. // kRGB
  319. static void swizzle_rgb_to_rgba(
  320. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  321. int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
  322. src += offset;
  323. SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
  324. for (int x = 0; x < dstWidth; x++) {
  325. dst[x] = SkPackARGB_as_RGBA(0xFF, src[0], src[1], src[2]);
  326. src += deltaSrc;
  327. }
  328. }
  329. static void swizzle_rgb_to_bgra(
  330. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  331. int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
  332. src += offset;
  333. SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
  334. for (int x = 0; x < dstWidth; x++) {
  335. dst[x] = SkPackARGB_as_BGRA(0xFF, src[0], src[1], src[2]);
  336. src += deltaSrc;
  337. }
  338. }
  339. static void fast_swizzle_rgb_to_rgba(
  340. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
  341. int offset, const SkPMColor ctable[]) {
  342. // This function must not be called if we are sampling. If we are not
  343. // sampling, deltaSrc should equal bpp.
  344. SkASSERT(deltaSrc == bpp);
  345. SkOpts::RGB_to_RGB1((uint32_t*) dst, src + offset, width);
  346. }
  347. static void fast_swizzle_rgb_to_bgra(
  348. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
  349. int offset, const SkPMColor ctable[]) {
  350. // This function must not be called if we are sampling. If we are not
  351. // sampling, deltaSrc should equal bpp.
  352. SkASSERT(deltaSrc == bpp);
  353. SkOpts::RGB_to_BGR1((uint32_t*) dst, src + offset, width);
  354. }
  355. static void swizzle_rgb_to_565(
  356. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  357. int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
  358. src += offset;
  359. uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
  360. for (int x = 0; x < dstWidth; x++) {
  361. dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]);
  362. src += deltaSrc;
  363. }
  364. }
  365. // kRGBA
  366. static void swizzle_rgba_to_rgba_premul(
  367. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  368. int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
  369. src += offset;
  370. SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
  371. for (int x = 0; x < dstWidth; x++) {
  372. dst[x] = premultiply_argb_as_rgba(src[3], src[0], src[1], src[2]);
  373. src += deltaSrc;
  374. }
  375. }
  376. static void swizzle_rgba_to_bgra_premul(
  377. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  378. int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
  379. src += offset;
  380. SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
  381. for (int x = 0; x < dstWidth; x++) {
  382. dst[x] = premultiply_argb_as_bgra(src[3], src[0], src[1], src[2]);
  383. src += deltaSrc;
  384. }
  385. }
  386. static void fast_swizzle_rgba_to_rgba_premul(
  387. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
  388. int offset, const SkPMColor ctable[]) {
  389. // This function must not be called if we are sampling. If we are not
  390. // sampling, deltaSrc should equal bpp.
  391. SkASSERT(deltaSrc == bpp);
  392. SkOpts::RGBA_to_rgbA((uint32_t*) dst, (const uint32_t*)(src + offset), width);
  393. }
  394. static void fast_swizzle_rgba_to_bgra_premul(
  395. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
  396. int offset, const SkPMColor ctable[]) {
  397. // This function must not be called if we are sampling. If we are not
  398. // sampling, deltaSrc should equal bpp.
  399. SkASSERT(deltaSrc == bpp);
  400. SkOpts::RGBA_to_bgrA((uint32_t*) dst, (const uint32_t*)(src + offset), width);
  401. }
  402. static void swizzle_rgba_to_bgra_unpremul(
  403. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  404. int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
  405. src += offset;
  406. uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
  407. for (int x = 0; x < dstWidth; x++) {
  408. unsigned alpha = src[3];
  409. dst[x] = SkPackARGB_as_BGRA(alpha, src[0], src[1], src[2]);
  410. src += deltaSrc;
  411. }
  412. }
  413. static void fast_swizzle_rgba_to_bgra_unpremul(
  414. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  415. const SkPMColor ctable[]) {
  416. // This function must not be called if we are sampling. If we are not
  417. // sampling, deltaSrc should equal bpp.
  418. SkASSERT(deltaSrc == bpp);
  419. SkOpts::RGBA_to_BGRA((uint32_t*) dst, (const uint32_t*)(src + offset), width);
  420. }
  421. // 16-bits per component kRGB and kRGBA
  422. static void swizzle_rgb16_to_rgba(
  423. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  424. const SkPMColor ctable[]) {
  425. auto strip16to8 = [](const uint8_t* ptr) {
  426. return 0xFF000000 | (ptr[4] << 16) | (ptr[2] << 8) | ptr[0];
  427. };
  428. src += offset;
  429. uint32_t* dst32 = (uint32_t*) dst;
  430. for (int x = 0; x < width; x++) {
  431. dst32[x] = strip16to8(src);
  432. src += deltaSrc;
  433. }
  434. }
  435. static void swizzle_rgb16_to_bgra(
  436. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  437. const SkPMColor ctable[]) {
  438. auto strip16to8 = [](const uint8_t* ptr) {
  439. return 0xFF000000 | (ptr[0] << 16) | (ptr[2] << 8) | ptr[4];
  440. };
  441. src += offset;
  442. uint32_t* dst32 = (uint32_t*) dst;
  443. for (int x = 0; x < width; x++) {
  444. dst32[x] = strip16to8(src);
  445. src += deltaSrc;
  446. }
  447. }
  448. static void swizzle_rgb16_to_565(
  449. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  450. const SkPMColor ctable[]) {
  451. auto strip16to565 = [](const uint8_t* ptr) {
  452. return SkPack888ToRGB16(ptr[0], ptr[2], ptr[4]);
  453. };
  454. src += offset;
  455. uint16_t* dst16 = (uint16_t*) dst;
  456. for (int x = 0; x < width; x++) {
  457. dst16[x] = strip16to565(src);
  458. src += deltaSrc;
  459. }
  460. }
  461. static void swizzle_rgba16_to_rgba_unpremul(
  462. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  463. const SkPMColor ctable[]) {
  464. auto strip16to8 = [](const uint8_t* ptr) {
  465. return (ptr[6] << 24) | (ptr[4] << 16) | (ptr[2] << 8) | ptr[0];
  466. };
  467. src += offset;
  468. uint32_t* dst32 = (uint32_t*) dst;
  469. for (int x = 0; x < width; x++) {
  470. dst32[x] = strip16to8(src);
  471. src += deltaSrc;
  472. }
  473. }
  474. static void swizzle_rgba16_to_rgba_premul(
  475. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  476. const SkPMColor ctable[]) {
  477. auto stripAndPremul16to8 = [](const uint8_t* ptr) {
  478. return premultiply_argb_as_rgba(ptr[6], ptr[0], ptr[2], ptr[4]);
  479. };
  480. src += offset;
  481. uint32_t* dst32 = (uint32_t*) dst;
  482. for (int x = 0; x < width; x++) {
  483. dst32[x] = stripAndPremul16to8(src);
  484. src += deltaSrc;
  485. }
  486. }
  487. static void swizzle_rgba16_to_bgra_unpremul(
  488. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  489. const SkPMColor ctable[]) {
  490. auto strip16to8 = [](const uint8_t* ptr) {
  491. return (ptr[6] << 24) | (ptr[0] << 16) | (ptr[2] << 8) | ptr[4];
  492. };
  493. src += offset;
  494. uint32_t* dst32 = (uint32_t*) dst;
  495. for (int x = 0; x < width; x++) {
  496. dst32[x] = strip16to8(src);
  497. src += deltaSrc;
  498. }
  499. }
  500. static void swizzle_rgba16_to_bgra_premul(
  501. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  502. const SkPMColor ctable[]) {
  503. auto stripAndPremul16to8 = [](const uint8_t* ptr) {
  504. return premultiply_argb_as_bgra(ptr[6], ptr[0], ptr[2], ptr[4]);
  505. };
  506. src += offset;
  507. uint32_t* dst32 = (uint32_t*) dst;
  508. for (int x = 0; x < width; x++) {
  509. dst32[x] = stripAndPremul16to8(src);
  510. src += deltaSrc;
  511. }
  512. }
  513. // kCMYK
  514. //
  515. // CMYK is stored as four bytes per pixel.
  516. //
  517. // We will implement a crude conversion from CMYK -> RGB using formulas
  518. // from easyrgb.com.
  519. //
  520. // CMYK -> CMY
  521. // C = C * (1 - K) + K
  522. // M = M * (1 - K) + K
  523. // Y = Y * (1 - K) + K
  524. //
  525. // libjpeg actually gives us inverted CMYK, so we must subtract the
  526. // original terms from 1.
  527. // CMYK -> CMY
  528. // C = (1 - C) * (1 - (1 - K)) + (1 - K)
  529. // M = (1 - M) * (1 - (1 - K)) + (1 - K)
  530. // Y = (1 - Y) * (1 - (1 - K)) + (1 - K)
  531. //
  532. // Simplifying the above expression.
  533. // CMYK -> CMY
  534. // C = 1 - CK
  535. // M = 1 - MK
  536. // Y = 1 - YK
  537. //
  538. // CMY -> RGB
  539. // R = (1 - C) * 255
  540. // G = (1 - M) * 255
  541. // B = (1 - Y) * 255
  542. //
  543. // Therefore the full conversion is below. This can be verified at
  544. // www.rapidtables.com (assuming inverted CMYK).
  545. // CMYK -> RGB
  546. // R = C * K * 255
  547. // G = M * K * 255
  548. // B = Y * K * 255
  549. //
  550. // As a final note, we have treated the CMYK values as if they were on
  551. // a scale from 0-1, when in fact they are 8-bit ints scaling from 0-255.
  552. // We must divide each CMYK component by 255 to obtain the true conversion
  553. // we should perform.
  554. // CMYK -> RGB
  555. // R = C * K / 255
  556. // G = M * K / 255
  557. // B = Y * K / 255
  558. static void swizzle_cmyk_to_rgba(
  559. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  560. int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
  561. src += offset;
  562. SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
  563. for (int x = 0; x < dstWidth; x++) {
  564. const uint8_t r = SkMulDiv255Round(src[0], src[3]);
  565. const uint8_t g = SkMulDiv255Round(src[1], src[3]);
  566. const uint8_t b = SkMulDiv255Round(src[2], src[3]);
  567. dst[x] = SkPackARGB_as_RGBA(0xFF, r, g, b);
  568. src += deltaSrc;
  569. }
  570. }
  571. static void swizzle_cmyk_to_bgra(
  572. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  573. int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
  574. src += offset;
  575. SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
  576. for (int x = 0; x < dstWidth; x++) {
  577. const uint8_t r = SkMulDiv255Round(src[0], src[3]);
  578. const uint8_t g = SkMulDiv255Round(src[1], src[3]);
  579. const uint8_t b = SkMulDiv255Round(src[2], src[3]);
  580. dst[x] = SkPackARGB_as_BGRA(0xFF, r, g, b);
  581. src += deltaSrc;
  582. }
  583. }
  584. static void fast_swizzle_cmyk_to_rgba(
  585. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  586. const SkPMColor ctable[]) {
  587. // This function must not be called if we are sampling. If we are not
  588. // sampling, deltaSrc should equal bpp.
  589. SkASSERT(deltaSrc == bpp);
  590. SkOpts::inverted_CMYK_to_RGB1((uint32_t*) dst, (const uint32_t*)(src + offset), width);
  591. }
  592. static void fast_swizzle_cmyk_to_bgra(
  593. void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
  594. const SkPMColor ctable[]) {
  595. // This function must not be called if we are sampling. If we are not
  596. // sampling, deltaSrc should equal bpp.
  597. SkASSERT(deltaSrc == bpp);
  598. SkOpts::inverted_CMYK_to_BGR1((uint32_t*) dst, (const uint32_t*)(src + offset), width);
  599. }
  600. static void swizzle_cmyk_to_565(
  601. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  602. int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
  603. src += offset;
  604. uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
  605. for (int x = 0; x < dstWidth; x++) {
  606. const uint8_t r = SkMulDiv255Round(src[0], src[3]);
  607. const uint8_t g = SkMulDiv255Round(src[1], src[3]);
  608. const uint8_t b = SkMulDiv255Round(src[2], src[3]);
  609. dst[x] = SkPack888ToRGB16(r, g, b);
  610. src += deltaSrc;
  611. }
  612. }
  613. template <SkSwizzler::RowProc proc>
  614. void SkSwizzler::SkipLeadingGrayAlphaZerosThen(
  615. void* dst, const uint8_t* src, int width,
  616. int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
  617. SkASSERT(!ctable);
  618. const uint16_t* src16 = (const uint16_t*) (src + offset);
  619. uint32_t* dst32 = (uint32_t*) dst;
  620. // This may miss opportunities to skip when the output is premultiplied,
  621. // e.g. for a src pixel 0x00FF which is not zero but becomes zero after premultiplication.
  622. while (width > 0 && *src16 == 0x0000) {
  623. width--;
  624. dst32++;
  625. src16 += deltaSrc / 2;
  626. }
  627. proc(dst32, (const uint8_t*)src16, width, bpp, deltaSrc, 0, ctable);
  628. }
  629. template <SkSwizzler::RowProc proc>
  630. void SkSwizzler::SkipLeading8888ZerosThen(
  631. void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
  632. int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
  633. SkASSERT(!ctable);
  634. auto src32 = (const uint32_t*)(src+offset);
  635. auto dst32 = (uint32_t*)dstRow;
  636. // This may miss opportunities to skip when the output is premultiplied,
  637. // e.g. for a src pixel 0x00FFFFFF which is not zero but becomes zero after premultiplication.
  638. while (dstWidth > 0 && *src32 == 0x00000000) {
  639. dstWidth--;
  640. dst32++;
  641. src32 += deltaSrc/4;
  642. }
  643. proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable);
  644. }
  645. std::unique_ptr<SkSwizzler> SkSwizzler::MakeSimple(int srcBPP, const SkImageInfo& dstInfo,
  646. const SkCodec::Options& options) {
  647. RowProc proc = nullptr;
  648. switch (srcBPP) {
  649. case 1: // kGray_8_SkColorType
  650. proc = &sample1;
  651. break;
  652. case 2: // kRGB_565_SkColorType
  653. proc = &sample2;
  654. break;
  655. case 4: // kRGBA_8888_SkColorType
  656. // kBGRA_8888_SkColorType
  657. proc = &sample4;
  658. break;
  659. case 6: // 16 bit PNG no alpha
  660. proc = &sample6;
  661. break;
  662. case 8: // 16 bit PNG with alpha
  663. proc = &sample8;
  664. break;
  665. default:
  666. return nullptr;
  667. }
  668. return Make(dstInfo, &copy, proc, nullptr /*ctable*/, srcBPP,
  669. dstInfo.bytesPerPixel(), options, nullptr /*frame*/);
  670. }
  671. std::unique_ptr<SkSwizzler> SkSwizzler::Make(const SkEncodedInfo& encodedInfo,
  672. const SkPMColor* ctable,
  673. const SkImageInfo& dstInfo,
  674. const SkCodec::Options& options,
  675. const SkIRect* frame) {
  676. if (SkEncodedInfo::kPalette_Color == encodedInfo.color() && nullptr == ctable) {
  677. return nullptr;
  678. }
  679. RowProc fastProc = nullptr;
  680. RowProc proc = nullptr;
  681. SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized;
  682. const bool premultiply = (SkEncodedInfo::kOpaque_Alpha != encodedInfo.alpha()) &&
  683. (kPremul_SkAlphaType == dstInfo.alphaType());
  684. switch (encodedInfo.color()) {
  685. case SkEncodedInfo::kGray_Color:
  686. switch (encodedInfo.bitsPerComponent()) {
  687. case 1:
  688. switch (dstInfo.colorType()) {
  689. case kRGBA_8888_SkColorType:
  690. case kBGRA_8888_SkColorType:
  691. proc = &swizzle_bit_to_n32;
  692. break;
  693. case kRGB_565_SkColorType:
  694. proc = &swizzle_bit_to_565;
  695. break;
  696. case kGray_8_SkColorType:
  697. proc = &swizzle_bit_to_grayscale;
  698. break;
  699. case kRGBA_F16_SkColorType:
  700. proc = &swizzle_bit_to_f16;
  701. break;
  702. default:
  703. return nullptr;
  704. }
  705. break;
  706. case 8:
  707. switch (dstInfo.colorType()) {
  708. case kRGBA_8888_SkColorType:
  709. case kBGRA_8888_SkColorType:
  710. proc = &swizzle_gray_to_n32;
  711. fastProc = &fast_swizzle_gray_to_n32;
  712. break;
  713. case kGray_8_SkColorType:
  714. proc = &sample1;
  715. fastProc = &copy;
  716. break;
  717. case kRGB_565_SkColorType:
  718. proc = &swizzle_gray_to_565;
  719. break;
  720. default:
  721. return nullptr;
  722. }
  723. break;
  724. default:
  725. return nullptr;
  726. }
  727. break;
  728. case SkEncodedInfo::kXAlpha_Color:
  729. case SkEncodedInfo::kGrayAlpha_Color:
  730. switch (dstInfo.colorType()) {
  731. case kRGBA_8888_SkColorType:
  732. case kBGRA_8888_SkColorType:
  733. if (premultiply) {
  734. if (SkCodec::kYes_ZeroInitialized == zeroInit) {
  735. proc = &SkipLeadingGrayAlphaZerosThen
  736. <swizzle_grayalpha_to_n32_premul>;
  737. fastProc = &SkipLeadingGrayAlphaZerosThen
  738. <fast_swizzle_grayalpha_to_n32_premul>;
  739. } else {
  740. proc = &swizzle_grayalpha_to_n32_premul;
  741. fastProc = &fast_swizzle_grayalpha_to_n32_premul;
  742. }
  743. } else {
  744. if (SkCodec::kYes_ZeroInitialized == zeroInit) {
  745. proc = &SkipLeadingGrayAlphaZerosThen
  746. <swizzle_grayalpha_to_n32_unpremul>;
  747. fastProc = &SkipLeadingGrayAlphaZerosThen
  748. <fast_swizzle_grayalpha_to_n32_unpremul>;
  749. } else {
  750. proc = &swizzle_grayalpha_to_n32_unpremul;
  751. fastProc = &fast_swizzle_grayalpha_to_n32_unpremul;
  752. }
  753. }
  754. break;
  755. case kAlpha_8_SkColorType:
  756. proc = &swizzle_grayalpha_to_a8;
  757. break;
  758. default:
  759. return nullptr;
  760. }
  761. break;
  762. case SkEncodedInfo::kPalette_Color:
  763. // We assume that the color table is premultiplied and swizzled
  764. // as desired.
  765. switch (encodedInfo.bitsPerComponent()) {
  766. case 1:
  767. case 2:
  768. case 4:
  769. switch (dstInfo.colorType()) {
  770. case kRGBA_8888_SkColorType:
  771. case kBGRA_8888_SkColorType:
  772. proc = &swizzle_small_index_to_n32;
  773. break;
  774. case kRGB_565_SkColorType:
  775. proc = &swizzle_small_index_to_565;
  776. break;
  777. default:
  778. return nullptr;
  779. }
  780. break;
  781. case 8:
  782. switch (dstInfo.colorType()) {
  783. case kRGBA_8888_SkColorType:
  784. case kBGRA_8888_SkColorType:
  785. if (SkCodec::kYes_ZeroInitialized == zeroInit) {
  786. proc = &swizzle_index_to_n32_skipZ;
  787. } else {
  788. proc = &swizzle_index_to_n32;
  789. }
  790. break;
  791. case kRGB_565_SkColorType:
  792. proc = &swizzle_index_to_565;
  793. break;
  794. default:
  795. return nullptr;
  796. }
  797. break;
  798. default:
  799. return nullptr;
  800. }
  801. break;
  802. case SkEncodedInfo::k565_Color:
  803. // Treat 565 exactly like RGB (since it's still encoded as 8 bits per component).
  804. // We just mark as 565 when we have a hint that there are only 5/6/5 "significant"
  805. // bits in each channel.
  806. case SkEncodedInfo::kRGB_Color:
  807. switch (dstInfo.colorType()) {
  808. case kRGBA_8888_SkColorType:
  809. if (16 == encodedInfo.bitsPerComponent()) {
  810. proc = &swizzle_rgb16_to_rgba;
  811. break;
  812. }
  813. SkASSERT(8 == encodedInfo.bitsPerComponent());
  814. proc = &swizzle_rgb_to_rgba;
  815. fastProc = &fast_swizzle_rgb_to_rgba;
  816. break;
  817. case kBGRA_8888_SkColorType:
  818. if (16 == encodedInfo.bitsPerComponent()) {
  819. proc = &swizzle_rgb16_to_bgra;
  820. break;
  821. }
  822. SkASSERT(8 == encodedInfo.bitsPerComponent());
  823. proc = &swizzle_rgb_to_bgra;
  824. fastProc = &fast_swizzle_rgb_to_bgra;
  825. break;
  826. case kRGB_565_SkColorType:
  827. if (16 == encodedInfo.bitsPerComponent()) {
  828. proc = &swizzle_rgb16_to_565;
  829. break;
  830. }
  831. proc = &swizzle_rgb_to_565;
  832. break;
  833. default:
  834. return nullptr;
  835. }
  836. break;
  837. case SkEncodedInfo::kRGBA_Color:
  838. switch (dstInfo.colorType()) {
  839. case kRGBA_8888_SkColorType:
  840. if (16 == encodedInfo.bitsPerComponent()) {
  841. proc = premultiply ? &swizzle_rgba16_to_rgba_premul :
  842. &swizzle_rgba16_to_rgba_unpremul;
  843. break;
  844. }
  845. SkASSERT(8 == encodedInfo.bitsPerComponent());
  846. if (premultiply) {
  847. if (SkCodec::kYes_ZeroInitialized == zeroInit) {
  848. proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
  849. fastProc = &SkipLeading8888ZerosThen
  850. <fast_swizzle_rgba_to_rgba_premul>;
  851. } else {
  852. proc = &swizzle_rgba_to_rgba_premul;
  853. fastProc = &fast_swizzle_rgba_to_rgba_premul;
  854. }
  855. } else {
  856. if (SkCodec::kYes_ZeroInitialized == zeroInit) {
  857. proc = &SkipLeading8888ZerosThen<sample4>;
  858. fastProc = &SkipLeading8888ZerosThen<copy>;
  859. } else {
  860. proc = &sample4;
  861. fastProc = &copy;
  862. }
  863. }
  864. break;
  865. case kBGRA_8888_SkColorType:
  866. if (16 == encodedInfo.bitsPerComponent()) {
  867. proc = premultiply ? &swizzle_rgba16_to_bgra_premul :
  868. &swizzle_rgba16_to_bgra_unpremul;
  869. break;
  870. }
  871. SkASSERT(8 == encodedInfo.bitsPerComponent());
  872. if (premultiply) {
  873. if (SkCodec::kYes_ZeroInitialized == zeroInit) {
  874. proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
  875. fastProc = &SkipLeading8888ZerosThen
  876. <fast_swizzle_rgba_to_bgra_premul>;
  877. } else {
  878. proc = &swizzle_rgba_to_bgra_premul;
  879. fastProc = &fast_swizzle_rgba_to_bgra_premul;
  880. }
  881. } else {
  882. if (SkCodec::kYes_ZeroInitialized == zeroInit) {
  883. proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
  884. fastProc = &SkipLeading8888ZerosThen
  885. <fast_swizzle_rgba_to_bgra_unpremul>;
  886. } else {
  887. proc = &swizzle_rgba_to_bgra_unpremul;
  888. fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
  889. }
  890. }
  891. break;
  892. default:
  893. return nullptr;
  894. }
  895. break;
  896. case SkEncodedInfo::kBGR_Color:
  897. switch (dstInfo.colorType()) {
  898. case kBGRA_8888_SkColorType:
  899. proc = &swizzle_rgb_to_rgba;
  900. fastProc = &fast_swizzle_rgb_to_rgba;
  901. break;
  902. case kRGBA_8888_SkColorType:
  903. proc = &swizzle_rgb_to_bgra;
  904. fastProc = &fast_swizzle_rgb_to_bgra;
  905. break;
  906. case kRGB_565_SkColorType:
  907. proc = &swizzle_bgr_to_565;
  908. break;
  909. default:
  910. return nullptr;
  911. }
  912. break;
  913. case SkEncodedInfo::kBGRX_Color:
  914. switch (dstInfo.colorType()) {
  915. case kBGRA_8888_SkColorType:
  916. proc = &swizzle_rgb_to_rgba;
  917. break;
  918. case kRGBA_8888_SkColorType:
  919. proc = &swizzle_rgb_to_bgra;
  920. break;
  921. case kRGB_565_SkColorType:
  922. proc = &swizzle_bgr_to_565;
  923. break;
  924. default:
  925. return nullptr;
  926. }
  927. break;
  928. case SkEncodedInfo::kBGRA_Color:
  929. switch (dstInfo.colorType()) {
  930. case kBGRA_8888_SkColorType:
  931. if (premultiply) {
  932. if (SkCodec::kYes_ZeroInitialized == zeroInit) {
  933. proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
  934. fastProc = &SkipLeading8888ZerosThen
  935. <fast_swizzle_rgba_to_rgba_premul>;
  936. } else {
  937. proc = &swizzle_rgba_to_rgba_premul;
  938. fastProc = &fast_swizzle_rgba_to_rgba_premul;
  939. }
  940. } else {
  941. if (SkCodec::kYes_ZeroInitialized == zeroInit) {
  942. proc = &SkipLeading8888ZerosThen<sample4>;
  943. fastProc = &SkipLeading8888ZerosThen<copy>;
  944. } else {
  945. proc = &sample4;
  946. fastProc = &copy;
  947. }
  948. }
  949. break;
  950. case kRGBA_8888_SkColorType:
  951. if (premultiply) {
  952. if (SkCodec::kYes_ZeroInitialized == zeroInit) {
  953. proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
  954. fastProc = &SkipLeading8888ZerosThen
  955. <fast_swizzle_rgba_to_bgra_premul>;
  956. } else {
  957. proc = &swizzle_rgba_to_bgra_premul;
  958. fastProc = &fast_swizzle_rgba_to_bgra_premul;
  959. }
  960. } else {
  961. if (SkCodec::kYes_ZeroInitialized == zeroInit) {
  962. proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
  963. fastProc = &SkipLeading8888ZerosThen
  964. <fast_swizzle_rgba_to_bgra_unpremul>;
  965. } else {
  966. proc = &swizzle_rgba_to_bgra_unpremul;
  967. fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
  968. }
  969. }
  970. break;
  971. default:
  972. return nullptr;
  973. }
  974. break;
  975. case SkEncodedInfo::kInvertedCMYK_Color:
  976. switch (dstInfo.colorType()) {
  977. case kRGBA_8888_SkColorType:
  978. proc = &swizzle_cmyk_to_rgba;
  979. fastProc = &fast_swizzle_cmyk_to_rgba;
  980. break;
  981. case kBGRA_8888_SkColorType:
  982. proc = &swizzle_cmyk_to_bgra;
  983. fastProc = &fast_swizzle_cmyk_to_bgra;
  984. break;
  985. case kRGB_565_SkColorType:
  986. proc = &swizzle_cmyk_to_565;
  987. break;
  988. default:
  989. return nullptr;
  990. }
  991. break;
  992. default:
  993. return nullptr;
  994. }
  995. // Store bpp in bytes if it is an even multiple, otherwise use bits
  996. uint8_t bitsPerPixel = encodedInfo.bitsPerPixel();
  997. int srcBPP = SkIsAlign8(bitsPerPixel) ? bitsPerPixel / 8 : bitsPerPixel;
  998. int dstBPP = dstInfo.bytesPerPixel();
  999. return Make(dstInfo, fastProc, proc, ctable, srcBPP, dstBPP, options, frame);
  1000. }
  1001. std::unique_ptr<SkSwizzler> SkSwizzler::Make(const SkImageInfo& dstInfo,
  1002. RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcBPP,
  1003. int dstBPP, const SkCodec::Options& options, const SkIRect* frame) {
  1004. int srcOffset = 0;
  1005. int srcWidth = dstInfo.width();
  1006. int dstOffset = 0;
  1007. int dstWidth = srcWidth;
  1008. if (options.fSubset) {
  1009. // We do not currently support subset decodes for image types that may have
  1010. // frames (gif).
  1011. SkASSERT(!frame);
  1012. srcOffset = options.fSubset->left();
  1013. srcWidth = options.fSubset->width();
  1014. dstWidth = srcWidth;
  1015. } else if (frame) {
  1016. dstOffset = frame->left();
  1017. srcWidth = frame->width();
  1018. }
  1019. return std::unique_ptr<SkSwizzler>(new SkSwizzler(fastProc, proc, ctable, srcOffset, srcWidth,
  1020. dstOffset, dstWidth, srcBPP, dstBPP));
  1021. }
  1022. SkSwizzler::SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset,
  1023. int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP)
  1024. : fFastProc(fastProc)
  1025. , fSlowProc(proc)
  1026. , fActualProc(fFastProc ? fFastProc : fSlowProc)
  1027. , fColorTable(ctable)
  1028. , fSrcOffset(srcOffset)
  1029. , fDstOffset(dstOffset)
  1030. , fSrcOffsetUnits(srcOffset * srcBPP)
  1031. , fDstOffsetBytes(dstOffset * dstBPP)
  1032. , fSrcWidth(srcWidth)
  1033. , fDstWidth(dstWidth)
  1034. , fSwizzleWidth(srcWidth)
  1035. , fAllocatedWidth(dstWidth)
  1036. , fSampleX(1)
  1037. , fSrcBPP(srcBPP)
  1038. , fDstBPP(dstBPP)
  1039. {}
  1040. int SkSwizzler::onSetSampleX(int sampleX) {
  1041. SkASSERT(sampleX > 0);
  1042. fSampleX = sampleX;
  1043. fDstOffsetBytes = (fDstOffset / sampleX) * fDstBPP;
  1044. fSwizzleWidth = get_scaled_dimension(fSrcWidth, sampleX);
  1045. fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX);
  1046. int frameSampleX = sampleX;
  1047. if (fSrcWidth < fDstWidth) {
  1048. // Although SkSampledCodec adjusted sampleX so that it will never be
  1049. // larger than the width of the image (or subset, if applicable), it
  1050. // doesn't account for the width of a subset frame (i.e. gif). As a
  1051. // result, get_start_coord(sampleX) could result in fSrcOffsetUnits
  1052. // being wider than fSrcWidth. Compute a sampling rate based on the
  1053. // frame width to ensure that fSrcOffsetUnits is sensible.
  1054. frameSampleX = fSrcWidth / fSwizzleWidth;
  1055. }
  1056. fSrcOffsetUnits = (get_start_coord(frameSampleX) + fSrcOffset) * fSrcBPP;
  1057. if (fDstOffsetBytes > 0) {
  1058. const size_t dstSwizzleBytes = fSwizzleWidth * fDstBPP;
  1059. const size_t dstAllocatedBytes = fAllocatedWidth * fDstBPP;
  1060. if (fDstOffsetBytes + dstSwizzleBytes > dstAllocatedBytes) {
  1061. #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
  1062. SkAndroidFrameworkUtils::SafetyNetLog("118143775");
  1063. #endif
  1064. SkASSERT(dstSwizzleBytes <= dstAllocatedBytes);
  1065. fDstOffsetBytes = dstAllocatedBytes - dstSwizzleBytes;
  1066. }
  1067. }
  1068. // The optimized swizzler functions do not support sampling. Sampled swizzles
  1069. // are already fast because they skip pixels. We haven't seen a situation
  1070. // where speeding up sampling has a significant impact on total decode time.
  1071. if (1 == fSampleX && fFastProc) {
  1072. fActualProc = fFastProc;
  1073. } else {
  1074. fActualProc = fSlowProc;
  1075. }
  1076. return fAllocatedWidth;
  1077. }
  1078. void SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
  1079. SkASSERT(nullptr != dst && nullptr != src);
  1080. fActualProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcBPP,
  1081. fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable);
  1082. }