jdmrg565.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /*
  2. * jdmrg565.c
  3. *
  4. * This file was part of the Independent JPEG Group's software:
  5. * Copyright (C) 1994-1996, Thomas G. Lane.
  6. * libjpeg-turbo Modifications:
  7. * Copyright (C) 2013, Linaro Limited.
  8. * Copyright (C) 2014-2015, 2018, 2020, D. R. Commander.
  9. * For conditions of distribution and use, see the accompanying README.ijg
  10. * file.
  11. *
  12. * This file contains code for merged upsampling/color conversion.
  13. */
  14. INLINE
  15. LOCAL(void)
  16. h2v1_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
  17. JDIMENSION in_row_group_ctr,
  18. JSAMPARRAY output_buf)
  19. {
  20. my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
  21. register int y, cred, cgreen, cblue;
  22. int cb, cr;
  23. register JSAMPROW outptr;
  24. JSAMPROW inptr0, inptr1, inptr2;
  25. JDIMENSION col;
  26. /* copy these pointers into registers if possible */
  27. register JSAMPLE *range_limit = cinfo->sample_range_limit;
  28. int *Crrtab = upsample->Cr_r_tab;
  29. int *Cbbtab = upsample->Cb_b_tab;
  30. JLONG *Crgtab = upsample->Cr_g_tab;
  31. JLONG *Cbgtab = upsample->Cb_g_tab;
  32. unsigned int r, g, b;
  33. JLONG rgb;
  34. SHIFT_TEMPS
  35. inptr0 = input_buf[0][in_row_group_ctr];
  36. inptr1 = input_buf[1][in_row_group_ctr];
  37. inptr2 = input_buf[2][in_row_group_ctr];
  38. outptr = output_buf[0];
  39. /* Loop for each pair of output pixels */
  40. for (col = cinfo->output_width >> 1; col > 0; col--) {
  41. /* Do the chroma part of the calculation */
  42. cb = *inptr1++;
  43. cr = *inptr2++;
  44. cred = Crrtab[cr];
  45. cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  46. cblue = Cbbtab[cb];
  47. /* Fetch 2 Y values and emit 2 pixels */
  48. y = *inptr0++;
  49. r = range_limit[y + cred];
  50. g = range_limit[y + cgreen];
  51. b = range_limit[y + cblue];
  52. rgb = PACK_SHORT_565(r, g, b);
  53. y = *inptr0++;
  54. r = range_limit[y + cred];
  55. g = range_limit[y + cgreen];
  56. b = range_limit[y + cblue];
  57. rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
  58. WRITE_TWO_PIXELS(outptr, rgb);
  59. outptr += 4;
  60. }
  61. /* If image width is odd, do the last output column separately */
  62. if (cinfo->output_width & 1) {
  63. cb = *inptr1;
  64. cr = *inptr2;
  65. cred = Crrtab[cr];
  66. cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  67. cblue = Cbbtab[cb];
  68. y = *inptr0;
  69. r = range_limit[y + cred];
  70. g = range_limit[y + cgreen];
  71. b = range_limit[y + cblue];
  72. rgb = PACK_SHORT_565(r, g, b);
  73. *(INT16 *)outptr = (INT16)rgb;
  74. }
  75. }
  76. INLINE
  77. LOCAL(void)
  78. h2v1_merged_upsample_565D_internal(j_decompress_ptr cinfo,
  79. JSAMPIMAGE input_buf,
  80. JDIMENSION in_row_group_ctr,
  81. JSAMPARRAY output_buf)
  82. {
  83. my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
  84. register int y, cred, cgreen, cblue;
  85. int cb, cr;
  86. register JSAMPROW outptr;
  87. JSAMPROW inptr0, inptr1, inptr2;
  88. JDIMENSION col;
  89. /* copy these pointers into registers if possible */
  90. register JSAMPLE *range_limit = cinfo->sample_range_limit;
  91. int *Crrtab = upsample->Cr_r_tab;
  92. int *Cbbtab = upsample->Cb_b_tab;
  93. JLONG *Crgtab = upsample->Cr_g_tab;
  94. JLONG *Cbgtab = upsample->Cb_g_tab;
  95. JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
  96. unsigned int r, g, b;
  97. JLONG rgb;
  98. SHIFT_TEMPS
  99. inptr0 = input_buf[0][in_row_group_ctr];
  100. inptr1 = input_buf[1][in_row_group_ctr];
  101. inptr2 = input_buf[2][in_row_group_ctr];
  102. outptr = output_buf[0];
  103. /* Loop for each pair of output pixels */
  104. for (col = cinfo->output_width >> 1; col > 0; col--) {
  105. /* Do the chroma part of the calculation */
  106. cb = *inptr1++;
  107. cr = *inptr2++;
  108. cred = Crrtab[cr];
  109. cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  110. cblue = Cbbtab[cb];
  111. /* Fetch 2 Y values and emit 2 pixels */
  112. y = *inptr0++;
  113. r = range_limit[DITHER_565_R(y + cred, d0)];
  114. g = range_limit[DITHER_565_G(y + cgreen, d0)];
  115. b = range_limit[DITHER_565_B(y + cblue, d0)];
  116. d0 = DITHER_ROTATE(d0);
  117. rgb = PACK_SHORT_565(r, g, b);
  118. y = *inptr0++;
  119. r = range_limit[DITHER_565_R(y + cred, d0)];
  120. g = range_limit[DITHER_565_G(y + cgreen, d0)];
  121. b = range_limit[DITHER_565_B(y + cblue, d0)];
  122. d0 = DITHER_ROTATE(d0);
  123. rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
  124. WRITE_TWO_PIXELS(outptr, rgb);
  125. outptr += 4;
  126. }
  127. /* If image width is odd, do the last output column separately */
  128. if (cinfo->output_width & 1) {
  129. cb = *inptr1;
  130. cr = *inptr2;
  131. cred = Crrtab[cr];
  132. cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  133. cblue = Cbbtab[cb];
  134. y = *inptr0;
  135. r = range_limit[DITHER_565_R(y + cred, d0)];
  136. g = range_limit[DITHER_565_G(y + cgreen, d0)];
  137. b = range_limit[DITHER_565_B(y + cblue, d0)];
  138. rgb = PACK_SHORT_565(r, g, b);
  139. *(INT16 *)outptr = (INT16)rgb;
  140. }
  141. }
  142. INLINE
  143. LOCAL(void)
  144. h2v2_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
  145. JDIMENSION in_row_group_ctr,
  146. JSAMPARRAY output_buf)
  147. {
  148. my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
  149. register int y, cred, cgreen, cblue;
  150. int cb, cr;
  151. register JSAMPROW outptr0, outptr1;
  152. JSAMPROW inptr00, inptr01, inptr1, inptr2;
  153. JDIMENSION col;
  154. /* copy these pointers into registers if possible */
  155. register JSAMPLE *range_limit = cinfo->sample_range_limit;
  156. int *Crrtab = upsample->Cr_r_tab;
  157. int *Cbbtab = upsample->Cb_b_tab;
  158. JLONG *Crgtab = upsample->Cr_g_tab;
  159. JLONG *Cbgtab = upsample->Cb_g_tab;
  160. unsigned int r, g, b;
  161. JLONG rgb;
  162. SHIFT_TEMPS
  163. inptr00 = input_buf[0][in_row_group_ctr * 2];
  164. inptr01 = input_buf[0][in_row_group_ctr * 2 + 1];
  165. inptr1 = input_buf[1][in_row_group_ctr];
  166. inptr2 = input_buf[2][in_row_group_ctr];
  167. outptr0 = output_buf[0];
  168. outptr1 = output_buf[1];
  169. /* Loop for each group of output pixels */
  170. for (col = cinfo->output_width >> 1; col > 0; col--) {
  171. /* Do the chroma part of the calculation */
  172. cb = *inptr1++;
  173. cr = *inptr2++;
  174. cred = Crrtab[cr];
  175. cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  176. cblue = Cbbtab[cb];
  177. /* Fetch 4 Y values and emit 4 pixels */
  178. y = *inptr00++;
  179. r = range_limit[y + cred];
  180. g = range_limit[y + cgreen];
  181. b = range_limit[y + cblue];
  182. rgb = PACK_SHORT_565(r, g, b);
  183. y = *inptr00++;
  184. r = range_limit[y + cred];
  185. g = range_limit[y + cgreen];
  186. b = range_limit[y + cblue];
  187. rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
  188. WRITE_TWO_PIXELS(outptr0, rgb);
  189. outptr0 += 4;
  190. y = *inptr01++;
  191. r = range_limit[y + cred];
  192. g = range_limit[y + cgreen];
  193. b = range_limit[y + cblue];
  194. rgb = PACK_SHORT_565(r, g, b);
  195. y = *inptr01++;
  196. r = range_limit[y + cred];
  197. g = range_limit[y + cgreen];
  198. b = range_limit[y + cblue];
  199. rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
  200. WRITE_TWO_PIXELS(outptr1, rgb);
  201. outptr1 += 4;
  202. }
  203. /* If image width is odd, do the last output column separately */
  204. if (cinfo->output_width & 1) {
  205. cb = *inptr1;
  206. cr = *inptr2;
  207. cred = Crrtab[cr];
  208. cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  209. cblue = Cbbtab[cb];
  210. y = *inptr00;
  211. r = range_limit[y + cred];
  212. g = range_limit[y + cgreen];
  213. b = range_limit[y + cblue];
  214. rgb = PACK_SHORT_565(r, g, b);
  215. *(INT16 *)outptr0 = (INT16)rgb;
  216. y = *inptr01;
  217. r = range_limit[y + cred];
  218. g = range_limit[y + cgreen];
  219. b = range_limit[y + cblue];
  220. rgb = PACK_SHORT_565(r, g, b);
  221. *(INT16 *)outptr1 = (INT16)rgb;
  222. }
  223. }
  224. INLINE
  225. LOCAL(void)
  226. h2v2_merged_upsample_565D_internal(j_decompress_ptr cinfo,
  227. JSAMPIMAGE input_buf,
  228. JDIMENSION in_row_group_ctr,
  229. JSAMPARRAY output_buf)
  230. {
  231. my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
  232. register int y, cred, cgreen, cblue;
  233. int cb, cr;
  234. register JSAMPROW outptr0, outptr1;
  235. JSAMPROW inptr00, inptr01, inptr1, inptr2;
  236. JDIMENSION col;
  237. /* copy these pointers into registers if possible */
  238. register JSAMPLE *range_limit = cinfo->sample_range_limit;
  239. int *Crrtab = upsample->Cr_r_tab;
  240. int *Cbbtab = upsample->Cb_b_tab;
  241. JLONG *Crgtab = upsample->Cr_g_tab;
  242. JLONG *Cbgtab = upsample->Cb_g_tab;
  243. JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
  244. JLONG d1 = dither_matrix[(cinfo->output_scanline + 1) & DITHER_MASK];
  245. unsigned int r, g, b;
  246. JLONG rgb;
  247. SHIFT_TEMPS
  248. inptr00 = input_buf[0][in_row_group_ctr * 2];
  249. inptr01 = input_buf[0][in_row_group_ctr * 2 + 1];
  250. inptr1 = input_buf[1][in_row_group_ctr];
  251. inptr2 = input_buf[2][in_row_group_ctr];
  252. outptr0 = output_buf[0];
  253. outptr1 = output_buf[1];
  254. /* Loop for each group of output pixels */
  255. for (col = cinfo->output_width >> 1; col > 0; col--) {
  256. /* Do the chroma part of the calculation */
  257. cb = *inptr1++;
  258. cr = *inptr2++;
  259. cred = Crrtab[cr];
  260. cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  261. cblue = Cbbtab[cb];
  262. /* Fetch 4 Y values and emit 4 pixels */
  263. y = *inptr00++;
  264. r = range_limit[DITHER_565_R(y + cred, d0)];
  265. g = range_limit[DITHER_565_G(y + cgreen, d0)];
  266. b = range_limit[DITHER_565_B(y + cblue, d0)];
  267. d0 = DITHER_ROTATE(d0);
  268. rgb = PACK_SHORT_565(r, g, b);
  269. y = *inptr00++;
  270. r = range_limit[DITHER_565_R(y + cred, d0)];
  271. g = range_limit[DITHER_565_G(y + cgreen, d0)];
  272. b = range_limit[DITHER_565_B(y + cblue, d0)];
  273. d0 = DITHER_ROTATE(d0);
  274. rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
  275. WRITE_TWO_PIXELS(outptr0, rgb);
  276. outptr0 += 4;
  277. y = *inptr01++;
  278. r = range_limit[DITHER_565_R(y + cred, d1)];
  279. g = range_limit[DITHER_565_G(y + cgreen, d1)];
  280. b = range_limit[DITHER_565_B(y + cblue, d1)];
  281. d1 = DITHER_ROTATE(d1);
  282. rgb = PACK_SHORT_565(r, g, b);
  283. y = *inptr01++;
  284. r = range_limit[DITHER_565_R(y + cred, d1)];
  285. g = range_limit[DITHER_565_G(y + cgreen, d1)];
  286. b = range_limit[DITHER_565_B(y + cblue, d1)];
  287. d1 = DITHER_ROTATE(d1);
  288. rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
  289. WRITE_TWO_PIXELS(outptr1, rgb);
  290. outptr1 += 4;
  291. }
  292. /* If image width is odd, do the last output column separately */
  293. if (cinfo->output_width & 1) {
  294. cb = *inptr1;
  295. cr = *inptr2;
  296. cred = Crrtab[cr];
  297. cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  298. cblue = Cbbtab[cb];
  299. y = *inptr00;
  300. r = range_limit[DITHER_565_R(y + cred, d0)];
  301. g = range_limit[DITHER_565_G(y + cgreen, d0)];
  302. b = range_limit[DITHER_565_B(y + cblue, d0)];
  303. rgb = PACK_SHORT_565(r, g, b);
  304. *(INT16 *)outptr0 = (INT16)rgb;
  305. y = *inptr01;
  306. r = range_limit[DITHER_565_R(y + cred, d1)];
  307. g = range_limit[DITHER_565_G(y + cgreen, d1)];
  308. b = range_limit[DITHER_565_B(y + cblue, d1)];
  309. rgb = PACK_SHORT_565(r, g, b);
  310. *(INT16 *)outptr1 = (INT16)rgb;
  311. }
  312. }