jdmrg565.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  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, D. R. Commander.
  9. * For conditions of distribution and use, see the accompanying README file.
  10. *
  11. * This file contains code for merged upsampling/color conversion.
  12. */
  13. INLINE
  14. LOCAL(void)
  15. h2v1_merged_upsample_565_internal (j_decompress_ptr cinfo,
  16. JSAMPIMAGE input_buf,
  17. JDIMENSION in_row_group_ctr,
  18. JSAMPARRAY output_buf)
  19. {
  20. my_upsample_ptr upsample = (my_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. INT32 * Crgtab = upsample->Cr_g_tab;
  31. INT32 * Cbgtab = upsample->Cb_g_tab;
  32. unsigned int r, g, b;
  33. INT32 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 = GETJSAMPLE(*inptr1++);
  43. cr = GETJSAMPLE(*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 = GETJSAMPLE(*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 = GETJSAMPLE(*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 = GETJSAMPLE(*inptr1);
  64. cr = GETJSAMPLE(*inptr2);
  65. cred = Crrtab[cr];
  66. cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  67. cblue = Cbbtab[cb];
  68. y = GETJSAMPLE(*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 = 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_upsample_ptr upsample = (my_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. INT32 * Crgtab = upsample->Cr_g_tab;
  94. INT32 * Cbgtab = upsample->Cb_g_tab;
  95. INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
  96. unsigned int r, g, b;
  97. INT32 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 = GETJSAMPLE(*inptr1++);
  107. cr = GETJSAMPLE(*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 = GETJSAMPLE(*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 = GETJSAMPLE(*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 = GETJSAMPLE(*inptr1);
  130. cr = GETJSAMPLE(*inptr2);
  131. cred = Crrtab[cr];
  132. cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  133. cblue = Cbbtab[cb];
  134. y = GETJSAMPLE(*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 = rgb;
  140. }
  141. }
  142. INLINE
  143. LOCAL(void)
  144. h2v2_merged_upsample_565_internal (j_decompress_ptr cinfo,
  145. JSAMPIMAGE input_buf,
  146. JDIMENSION in_row_group_ctr,
  147. JSAMPARRAY output_buf)
  148. {
  149. my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  150. register int y, cred, cgreen, cblue;
  151. int cb, cr;
  152. register JSAMPROW outptr0, outptr1;
  153. JSAMPROW inptr00, inptr01, inptr1, inptr2;
  154. JDIMENSION col;
  155. /* copy these pointers into registers if possible */
  156. register JSAMPLE * range_limit = cinfo->sample_range_limit;
  157. int * Crrtab = upsample->Cr_r_tab;
  158. int * Cbbtab = upsample->Cb_b_tab;
  159. INT32 * Crgtab = upsample->Cr_g_tab;
  160. INT32 * Cbgtab = upsample->Cb_g_tab;
  161. unsigned int r, g, b;
  162. INT32 rgb;
  163. SHIFT_TEMPS
  164. inptr00 = input_buf[0][in_row_group_ctr * 2];
  165. inptr01 = input_buf[0][in_row_group_ctr * 2 + 1];
  166. inptr1 = input_buf[1][in_row_group_ctr];
  167. inptr2 = input_buf[2][in_row_group_ctr];
  168. outptr0 = output_buf[0];
  169. outptr1 = output_buf[1];
  170. /* Loop for each group of output pixels */
  171. for (col = cinfo->output_width >> 1; col > 0; col--) {
  172. /* Do the chroma part of the calculation */
  173. cb = GETJSAMPLE(*inptr1++);
  174. cr = GETJSAMPLE(*inptr2++);
  175. cred = Crrtab[cr];
  176. cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  177. cblue = Cbbtab[cb];
  178. /* Fetch 4 Y values and emit 4 pixels */
  179. y = GETJSAMPLE(*inptr00++);
  180. r = range_limit[y + cred];
  181. g = range_limit[y + cgreen];
  182. b = range_limit[y + cblue];
  183. rgb = PACK_SHORT_565(r, g, b);
  184. y = GETJSAMPLE(*inptr00++);
  185. r = range_limit[y + cred];
  186. g = range_limit[y + cgreen];
  187. b = range_limit[y + cblue];
  188. rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
  189. WRITE_TWO_PIXELS(outptr0, rgb);
  190. outptr0 += 4;
  191. y = GETJSAMPLE(*inptr01++);
  192. r = range_limit[y + cred];
  193. g = range_limit[y + cgreen];
  194. b = range_limit[y + cblue];
  195. rgb = PACK_SHORT_565(r, g, b);
  196. y = GETJSAMPLE(*inptr01++);
  197. r = range_limit[y + cred];
  198. g = range_limit[y + cgreen];
  199. b = range_limit[y + cblue];
  200. rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
  201. WRITE_TWO_PIXELS(outptr1, rgb);
  202. outptr1 += 4;
  203. }
  204. /* If image width is odd, do the last output column separately */
  205. if (cinfo->output_width & 1) {
  206. cb = GETJSAMPLE(*inptr1);
  207. cr = GETJSAMPLE(*inptr2);
  208. cred = Crrtab[cr];
  209. cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  210. cblue = Cbbtab[cb];
  211. y = GETJSAMPLE(*inptr00);
  212. r = range_limit[y + cred];
  213. g = range_limit[y + cgreen];
  214. b = range_limit[y + cblue];
  215. rgb = PACK_SHORT_565(r, g, b);
  216. *(INT16*)outptr0 = rgb;
  217. y = GETJSAMPLE(*inptr01);
  218. r = range_limit[y + cred];
  219. g = range_limit[y + cgreen];
  220. b = range_limit[y + cblue];
  221. rgb = PACK_SHORT_565(r, g, b);
  222. *(INT16*)outptr1 = rgb;
  223. }
  224. }
  225. INLINE
  226. LOCAL(void)
  227. h2v2_merged_upsample_565D_internal (j_decompress_ptr cinfo,
  228. JSAMPIMAGE input_buf,
  229. JDIMENSION in_row_group_ctr,
  230. JSAMPARRAY output_buf)
  231. {
  232. my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  233. register int y, cred, cgreen, cblue;
  234. int cb, cr;
  235. register JSAMPROW outptr0, outptr1;
  236. JSAMPROW inptr00, inptr01, inptr1, inptr2;
  237. JDIMENSION col;
  238. /* copy these pointers into registers if possible */
  239. register JSAMPLE * range_limit = cinfo->sample_range_limit;
  240. int * Crrtab = upsample->Cr_r_tab;
  241. int * Cbbtab = upsample->Cb_b_tab;
  242. INT32 * Crgtab = upsample->Cr_g_tab;
  243. INT32 * Cbgtab = upsample->Cb_g_tab;
  244. INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
  245. INT32 d1 = dither_matrix[(cinfo->output_scanline+1) & DITHER_MASK];
  246. unsigned int r, g, b;
  247. INT32 rgb;
  248. SHIFT_TEMPS
  249. inptr00 = input_buf[0][in_row_group_ctr*2];
  250. inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
  251. inptr1 = input_buf[1][in_row_group_ctr];
  252. inptr2 = input_buf[2][in_row_group_ctr];
  253. outptr0 = output_buf[0];
  254. outptr1 = output_buf[1];
  255. /* Loop for each group of output pixels */
  256. for (col = cinfo->output_width >> 1; col > 0; col--) {
  257. /* Do the chroma part of the calculation */
  258. cb = GETJSAMPLE(*inptr1++);
  259. cr = GETJSAMPLE(*inptr2++);
  260. cred = Crrtab[cr];
  261. cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  262. cblue = Cbbtab[cb];
  263. /* Fetch 4 Y values and emit 4 pixels */
  264. y = GETJSAMPLE(*inptr00++);
  265. r = range_limit[DITHER_565_R(y + cred, d0)];
  266. g = range_limit[DITHER_565_G(y + cgreen, d0)];
  267. b = range_limit[DITHER_565_B(y + cblue, d0)];
  268. d0 = DITHER_ROTATE(d0);
  269. rgb = PACK_SHORT_565(r, g, b);
  270. y = GETJSAMPLE(*inptr00++);
  271. r = range_limit[DITHER_565_R(y + cred, d1)];
  272. g = range_limit[DITHER_565_G(y + cgreen, d1)];
  273. b = range_limit[DITHER_565_B(y + cblue, d1)];
  274. d1 = DITHER_ROTATE(d1);
  275. rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
  276. WRITE_TWO_PIXELS(outptr0, rgb);
  277. outptr0 += 4;
  278. y = GETJSAMPLE(*inptr01++);
  279. r = range_limit[DITHER_565_R(y + cred, d0)];
  280. g = range_limit[DITHER_565_G(y + cgreen, d0)];
  281. b = range_limit[DITHER_565_B(y + cblue, d0)];
  282. d0 = DITHER_ROTATE(d0);
  283. rgb = PACK_SHORT_565(r, g, b);
  284. y = GETJSAMPLE(*inptr01++);
  285. r = range_limit[DITHER_565_R(y + cred, d1)];
  286. g = range_limit[DITHER_565_G(y + cgreen, d1)];
  287. b = range_limit[DITHER_565_B(y + cblue, d1)];
  288. d1 = DITHER_ROTATE(d1);
  289. rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
  290. WRITE_TWO_PIXELS(outptr1, rgb);
  291. outptr1 += 4;
  292. }
  293. /* If image width is odd, do the last output column separately */
  294. if (cinfo->output_width & 1) {
  295. cb = GETJSAMPLE(*inptr1);
  296. cr = GETJSAMPLE(*inptr2);
  297. cred = Crrtab[cr];
  298. cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  299. cblue = Cbbtab[cb];
  300. y = GETJSAMPLE(*inptr00);
  301. r = range_limit[DITHER_565_R(y + cred, d0)];
  302. g = range_limit[DITHER_565_G(y + cgreen, d0)];
  303. b = range_limit[DITHER_565_B(y + cblue, d0)];
  304. rgb = PACK_SHORT_565(r, g, b);
  305. *(INT16*)outptr0 = rgb;
  306. y = GETJSAMPLE(*inptr01);
  307. r = range_limit[DITHER_565_R(y + cred, d1)];
  308. g = range_limit[DITHER_565_G(y + cgreen, d1)];
  309. b = range_limit[DITHER_565_B(y + cblue, d1)];
  310. rgb = PACK_SHORT_565(r, g, b);
  311. *(INT16*)outptr1 = rgb;
  312. }
  313. }