jdmrgext.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * jdmrgext.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) 2011, 2015, 2020, D. R. Commander.
  8. * For conditions of distribution and use, see the accompanying README.ijg
  9. * file.
  10. *
  11. * This file contains code for merged upsampling/color conversion.
  12. */
  13. /* This file is included by jdmerge.c */
  14. /*
  15. * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
  16. */
  17. INLINE
  18. LOCAL(void)
  19. h2v1_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
  20. JDIMENSION in_row_group_ctr,
  21. JSAMPARRAY output_buf)
  22. {
  23. my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
  24. register int y, cred, cgreen, cblue;
  25. int cb, cr;
  26. register JSAMPROW outptr;
  27. JSAMPROW inptr0, inptr1, inptr2;
  28. JDIMENSION col;
  29. /* copy these pointers into registers if possible */
  30. register JSAMPLE *range_limit = cinfo->sample_range_limit;
  31. int *Crrtab = upsample->Cr_r_tab;
  32. int *Cbbtab = upsample->Cb_b_tab;
  33. JLONG *Crgtab = upsample->Cr_g_tab;
  34. JLONG *Cbgtab = upsample->Cb_g_tab;
  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 = *inptr1++;
  44. cr = *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 = *inptr0++;
  50. outptr[RGB_RED] = range_limit[y + cred];
  51. outptr[RGB_GREEN] = range_limit[y + cgreen];
  52. outptr[RGB_BLUE] = range_limit[y + cblue];
  53. #ifdef RGB_ALPHA
  54. outptr[RGB_ALPHA] = 0xFF;
  55. #endif
  56. outptr += RGB_PIXELSIZE;
  57. y = *inptr0++;
  58. outptr[RGB_RED] = range_limit[y + cred];
  59. outptr[RGB_GREEN] = range_limit[y + cgreen];
  60. outptr[RGB_BLUE] = range_limit[y + cblue];
  61. #ifdef RGB_ALPHA
  62. outptr[RGB_ALPHA] = 0xFF;
  63. #endif
  64. outptr += RGB_PIXELSIZE;
  65. }
  66. /* If image width is odd, do the last output column separately */
  67. if (cinfo->output_width & 1) {
  68. cb = *inptr1;
  69. cr = *inptr2;
  70. cred = Crrtab[cr];
  71. cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  72. cblue = Cbbtab[cb];
  73. y = *inptr0;
  74. outptr[RGB_RED] = range_limit[y + cred];
  75. outptr[RGB_GREEN] = range_limit[y + cgreen];
  76. outptr[RGB_BLUE] = range_limit[y + cblue];
  77. #ifdef RGB_ALPHA
  78. outptr[RGB_ALPHA] = 0xFF;
  79. #endif
  80. }
  81. }
  82. /*
  83. * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
  84. */
  85. INLINE
  86. LOCAL(void)
  87. h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
  88. JDIMENSION in_row_group_ctr,
  89. JSAMPARRAY output_buf)
  90. {
  91. my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
  92. register int y, cred, cgreen, cblue;
  93. int cb, cr;
  94. register JSAMPROW outptr0, outptr1;
  95. JSAMPROW inptr00, inptr01, inptr1, inptr2;
  96. JDIMENSION col;
  97. /* copy these pointers into registers if possible */
  98. register JSAMPLE *range_limit = cinfo->sample_range_limit;
  99. int *Crrtab = upsample->Cr_r_tab;
  100. int *Cbbtab = upsample->Cb_b_tab;
  101. JLONG *Crgtab = upsample->Cr_g_tab;
  102. JLONG *Cbgtab = upsample->Cb_g_tab;
  103. SHIFT_TEMPS
  104. inptr00 = input_buf[0][in_row_group_ctr * 2];
  105. inptr01 = input_buf[0][in_row_group_ctr * 2 + 1];
  106. inptr1 = input_buf[1][in_row_group_ctr];
  107. inptr2 = input_buf[2][in_row_group_ctr];
  108. outptr0 = output_buf[0];
  109. outptr1 = output_buf[1];
  110. /* Loop for each group of output pixels */
  111. for (col = cinfo->output_width >> 1; col > 0; col--) {
  112. /* Do the chroma part of the calculation */
  113. cb = *inptr1++;
  114. cr = *inptr2++;
  115. cred = Crrtab[cr];
  116. cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  117. cblue = Cbbtab[cb];
  118. /* Fetch 4 Y values and emit 4 pixels */
  119. y = *inptr00++;
  120. outptr0[RGB_RED] = range_limit[y + cred];
  121. outptr0[RGB_GREEN] = range_limit[y + cgreen];
  122. outptr0[RGB_BLUE] = range_limit[y + cblue];
  123. #ifdef RGB_ALPHA
  124. outptr0[RGB_ALPHA] = 0xFF;
  125. #endif
  126. outptr0 += RGB_PIXELSIZE;
  127. y = *inptr00++;
  128. outptr0[RGB_RED] = range_limit[y + cred];
  129. outptr0[RGB_GREEN] = range_limit[y + cgreen];
  130. outptr0[RGB_BLUE] = range_limit[y + cblue];
  131. #ifdef RGB_ALPHA
  132. outptr0[RGB_ALPHA] = 0xFF;
  133. #endif
  134. outptr0 += RGB_PIXELSIZE;
  135. y = *inptr01++;
  136. outptr1[RGB_RED] = range_limit[y + cred];
  137. outptr1[RGB_GREEN] = range_limit[y + cgreen];
  138. outptr1[RGB_BLUE] = range_limit[y + cblue];
  139. #ifdef RGB_ALPHA
  140. outptr1[RGB_ALPHA] = 0xFF;
  141. #endif
  142. outptr1 += RGB_PIXELSIZE;
  143. y = *inptr01++;
  144. outptr1[RGB_RED] = range_limit[y + cred];
  145. outptr1[RGB_GREEN] = range_limit[y + cgreen];
  146. outptr1[RGB_BLUE] = range_limit[y + cblue];
  147. #ifdef RGB_ALPHA
  148. outptr1[RGB_ALPHA] = 0xFF;
  149. #endif
  150. outptr1 += RGB_PIXELSIZE;
  151. }
  152. /* If image width is odd, do the last output column separately */
  153. if (cinfo->output_width & 1) {
  154. cb = *inptr1;
  155. cr = *inptr2;
  156. cred = Crrtab[cr];
  157. cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  158. cblue = Cbbtab[cb];
  159. y = *inptr00;
  160. outptr0[RGB_RED] = range_limit[y + cred];
  161. outptr0[RGB_GREEN] = range_limit[y + cgreen];
  162. outptr0[RGB_BLUE] = range_limit[y + cblue];
  163. #ifdef RGB_ALPHA
  164. outptr0[RGB_ALPHA] = 0xFF;
  165. #endif
  166. y = *inptr01;
  167. outptr1[RGB_RED] = range_limit[y + cred];
  168. outptr1[RGB_GREEN] = range_limit[y + cgreen];
  169. outptr1[RGB_BLUE] = range_limit[y + cblue];
  170. #ifdef RGB_ALPHA
  171. outptr1[RGB_ALPHA] = 0xFF;
  172. #endif
  173. }
  174. }