jdmrg565.c 11 KB

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