blob: 9bf4f1a307f372b25318a79a056220297401650a [file] [log] [blame]
hbono@chromium.orgc6beb742011-11-29 05:16:26 +00001/*
2 * jdmrgext.c
3 *
noel@chromium.org3395bcc2014-04-14 06:56:00 +00004 * This file was part of the Independent JPEG Group's software:
hbono@chromium.orgc6beb742011-11-29 05:16:26 +00005 * Copyright (C) 1994-1996, Thomas G. Lane.
noel@chromium.org3395bcc2014-04-14 06:56:00 +00006 * libjpeg-turbo Modifications:
Jonathan Wrightbbb82822020-11-25 13:36:43 +00007 * Copyright (C) 2011, 2015, 2020, D. R. Commander.
Tom Hudson0d47d2d2016-05-04 13:22:56 -04008 * For conditions of distribution and use, see the accompanying README.ijg
9 * file.
hbono@chromium.orgc6beb742011-11-29 05:16:26 +000010 *
11 * This file contains code for merged upsampling/color conversion.
12 */
13
14
15/* This file is included by jdmerge.c */
16
17
18/*
19 * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
20 */
21
22INLINE
23LOCAL(void)
Chris Blumecca8c4d2019-03-01 01:09:50 -080024h2v1_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
25 JDIMENSION in_row_group_ctr,
26 JSAMPARRAY output_buf)
hbono@chromium.orgc6beb742011-11-29 05:16:26 +000027{
Jonathan Wrightbbb82822020-11-25 13:36:43 +000028 my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
hbono@chromium.orgc6beb742011-11-29 05:16:26 +000029 register int y, cred, cgreen, cblue;
30 int cb, cr;
31 register JSAMPROW outptr;
32 JSAMPROW inptr0, inptr1, inptr2;
33 JDIMENSION col;
34 /* copy these pointers into registers if possible */
Chris Blumecca8c4d2019-03-01 01:09:50 -080035 register JSAMPLE *range_limit = cinfo->sample_range_limit;
36 int *Crrtab = upsample->Cr_r_tab;
37 int *Cbbtab = upsample->Cb_b_tab;
38 JLONG *Crgtab = upsample->Cr_g_tab;
39 JLONG *Cbgtab = upsample->Cb_g_tab;
hbono@chromium.orgc6beb742011-11-29 05:16:26 +000040 SHIFT_TEMPS
41
42 inptr0 = input_buf[0][in_row_group_ctr];
43 inptr1 = input_buf[1][in_row_group_ctr];
44 inptr2 = input_buf[2][in_row_group_ctr];
45 outptr = output_buf[0];
46 /* Loop for each pair of output pixels */
47 for (col = cinfo->output_width >> 1; col > 0; col--) {
48 /* Do the chroma part of the calculation */
Jonathan Wrightbbb82822020-11-25 13:36:43 +000049 cb = *inptr1++;
50 cr = *inptr2++;
hbono@chromium.orgc6beb742011-11-29 05:16:26 +000051 cred = Crrtab[cr];
Chris Blumecca8c4d2019-03-01 01:09:50 -080052 cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
hbono@chromium.orgc6beb742011-11-29 05:16:26 +000053 cblue = Cbbtab[cb];
54 /* Fetch 2 Y values and emit 2 pixels */
Jonathan Wrightbbb82822020-11-25 13:36:43 +000055 y = *inptr0++;
hbono@chromium.orgc6beb742011-11-29 05:16:26 +000056 outptr[RGB_RED] = range_limit[y + cred];
57 outptr[RGB_GREEN] = range_limit[y + cgreen];
58 outptr[RGB_BLUE] = range_limit[y + cblue];
hbono@chromium.orgdf5ffdd2012-05-11 07:46:03 +000059#ifdef RGB_ALPHA
60 outptr[RGB_ALPHA] = 0xFF;
61#endif
hbono@chromium.orgc6beb742011-11-29 05:16:26 +000062 outptr += RGB_PIXELSIZE;
Jonathan Wrightbbb82822020-11-25 13:36:43 +000063 y = *inptr0++;
hbono@chromium.orgc6beb742011-11-29 05:16:26 +000064 outptr[RGB_RED] = range_limit[y + cred];
65 outptr[RGB_GREEN] = range_limit[y + cgreen];
66 outptr[RGB_BLUE] = range_limit[y + cblue];
hbono@chromium.orgdf5ffdd2012-05-11 07:46:03 +000067#ifdef RGB_ALPHA
68 outptr[RGB_ALPHA] = 0xFF;
69#endif
hbono@chromium.orgc6beb742011-11-29 05:16:26 +000070 outptr += RGB_PIXELSIZE;
71 }
72 /* If image width is odd, do the last output column separately */
73 if (cinfo->output_width & 1) {
Jonathan Wrightbbb82822020-11-25 13:36:43 +000074 cb = *inptr1;
75 cr = *inptr2;
hbono@chromium.orgc6beb742011-11-29 05:16:26 +000076 cred = Crrtab[cr];
Chris Blumecca8c4d2019-03-01 01:09:50 -080077 cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
hbono@chromium.orgc6beb742011-11-29 05:16:26 +000078 cblue = Cbbtab[cb];
Jonathan Wrightbbb82822020-11-25 13:36:43 +000079 y = *inptr0;
hbono@chromium.orgc6beb742011-11-29 05:16:26 +000080 outptr[RGB_RED] = range_limit[y + cred];
81 outptr[RGB_GREEN] = range_limit[y + cgreen];
82 outptr[RGB_BLUE] = range_limit[y + cblue];
hbono@chromium.orgdf5ffdd2012-05-11 07:46:03 +000083#ifdef RGB_ALPHA
84 outptr[RGB_ALPHA] = 0xFF;
85#endif
hbono@chromium.orgc6beb742011-11-29 05:16:26 +000086 }
87}
88
89
90/*
91 * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
92 */
93
94INLINE
95LOCAL(void)
Chris Blumecca8c4d2019-03-01 01:09:50 -080096h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
97 JDIMENSION in_row_group_ctr,
98 JSAMPARRAY output_buf)
hbono@chromium.orgc6beb742011-11-29 05:16:26 +000099{
Jonathan Wrightbbb82822020-11-25 13:36:43 +0000100 my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
hbono@chromium.orgc6beb742011-11-29 05:16:26 +0000101 register int y, cred, cgreen, cblue;
102 int cb, cr;
103 register JSAMPROW outptr0, outptr1;
104 JSAMPROW inptr00, inptr01, inptr1, inptr2;
105 JDIMENSION col;
106 /* copy these pointers into registers if possible */
Chris Blumecca8c4d2019-03-01 01:09:50 -0800107 register JSAMPLE *range_limit = cinfo->sample_range_limit;
108 int *Crrtab = upsample->Cr_r_tab;
109 int *Cbbtab = upsample->Cb_b_tab;
110 JLONG *Crgtab = upsample->Cr_g_tab;
111 JLONG *Cbgtab = upsample->Cb_g_tab;
hbono@chromium.orgc6beb742011-11-29 05:16:26 +0000112 SHIFT_TEMPS
113
Chris Blumecca8c4d2019-03-01 01:09:50 -0800114 inptr00 = input_buf[0][in_row_group_ctr * 2];
115 inptr01 = input_buf[0][in_row_group_ctr * 2 + 1];
hbono@chromium.orgc6beb742011-11-29 05:16:26 +0000116 inptr1 = input_buf[1][in_row_group_ctr];
117 inptr2 = input_buf[2][in_row_group_ctr];
118 outptr0 = output_buf[0];
119 outptr1 = output_buf[1];
120 /* Loop for each group of output pixels */
121 for (col = cinfo->output_width >> 1; col > 0; col--) {
122 /* Do the chroma part of the calculation */
Jonathan Wrightbbb82822020-11-25 13:36:43 +0000123 cb = *inptr1++;
124 cr = *inptr2++;
hbono@chromium.orgc6beb742011-11-29 05:16:26 +0000125 cred = Crrtab[cr];
Chris Blumecca8c4d2019-03-01 01:09:50 -0800126 cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
hbono@chromium.orgc6beb742011-11-29 05:16:26 +0000127 cblue = Cbbtab[cb];
128 /* Fetch 4 Y values and emit 4 pixels */
Jonathan Wrightbbb82822020-11-25 13:36:43 +0000129 y = *inptr00++;
hbono@chromium.orgc6beb742011-11-29 05:16:26 +0000130 outptr0[RGB_RED] = range_limit[y + cred];
131 outptr0[RGB_GREEN] = range_limit[y + cgreen];
132 outptr0[RGB_BLUE] = range_limit[y + cblue];
hbono@chromium.orgdf5ffdd2012-05-11 07:46:03 +0000133#ifdef RGB_ALPHA
134 outptr0[RGB_ALPHA] = 0xFF;
135#endif
hbono@chromium.orgc6beb742011-11-29 05:16:26 +0000136 outptr0 += RGB_PIXELSIZE;
Jonathan Wrightbbb82822020-11-25 13:36:43 +0000137 y = *inptr00++;
hbono@chromium.orgc6beb742011-11-29 05:16:26 +0000138 outptr0[RGB_RED] = range_limit[y + cred];
139 outptr0[RGB_GREEN] = range_limit[y + cgreen];
140 outptr0[RGB_BLUE] = range_limit[y + cblue];
hbono@chromium.orgdf5ffdd2012-05-11 07:46:03 +0000141#ifdef RGB_ALPHA
142 outptr0[RGB_ALPHA] = 0xFF;
143#endif
hbono@chromium.orgc6beb742011-11-29 05:16:26 +0000144 outptr0 += RGB_PIXELSIZE;
Jonathan Wrightbbb82822020-11-25 13:36:43 +0000145 y = *inptr01++;
hbono@chromium.orgc6beb742011-11-29 05:16:26 +0000146 outptr1[RGB_RED] = range_limit[y + cred];
147 outptr1[RGB_GREEN] = range_limit[y + cgreen];
148 outptr1[RGB_BLUE] = range_limit[y + cblue];
hbono@chromium.orgdf5ffdd2012-05-11 07:46:03 +0000149#ifdef RGB_ALPHA
150 outptr1[RGB_ALPHA] = 0xFF;
151#endif
hbono@chromium.orgc6beb742011-11-29 05:16:26 +0000152 outptr1 += RGB_PIXELSIZE;
Jonathan Wrightbbb82822020-11-25 13:36:43 +0000153 y = *inptr01++;
hbono@chromium.orgc6beb742011-11-29 05:16:26 +0000154 outptr1[RGB_RED] = range_limit[y + cred];
155 outptr1[RGB_GREEN] = range_limit[y + cgreen];
156 outptr1[RGB_BLUE] = range_limit[y + cblue];
hbono@chromium.orgdf5ffdd2012-05-11 07:46:03 +0000157#ifdef RGB_ALPHA
158 outptr1[RGB_ALPHA] = 0xFF;
159#endif
hbono@chromium.orgc6beb742011-11-29 05:16:26 +0000160 outptr1 += RGB_PIXELSIZE;
161 }
162 /* If image width is odd, do the last output column separately */
163 if (cinfo->output_width & 1) {
Jonathan Wrightbbb82822020-11-25 13:36:43 +0000164 cb = *inptr1;
165 cr = *inptr2;
hbono@chromium.orgc6beb742011-11-29 05:16:26 +0000166 cred = Crrtab[cr];
Chris Blumecca8c4d2019-03-01 01:09:50 -0800167 cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
hbono@chromium.orgc6beb742011-11-29 05:16:26 +0000168 cblue = Cbbtab[cb];
Jonathan Wrightbbb82822020-11-25 13:36:43 +0000169 y = *inptr00;
hbono@chromium.orgc6beb742011-11-29 05:16:26 +0000170 outptr0[RGB_RED] = range_limit[y + cred];
171 outptr0[RGB_GREEN] = range_limit[y + cgreen];
172 outptr0[RGB_BLUE] = range_limit[y + cblue];
hbono@chromium.orgdf5ffdd2012-05-11 07:46:03 +0000173#ifdef RGB_ALPHA
174 outptr0[RGB_ALPHA] = 0xFF;
175#endif
Jonathan Wrightbbb82822020-11-25 13:36:43 +0000176 y = *inptr01;
hbono@chromium.orgc6beb742011-11-29 05:16:26 +0000177 outptr1[RGB_RED] = range_limit[y + cred];
178 outptr1[RGB_GREEN] = range_limit[y + cgreen];
179 outptr1[RGB_BLUE] = range_limit[y + cblue];
hbono@chromium.orgdf5ffdd2012-05-11 07:46:03 +0000180#ifdef RGB_ALPHA
181 outptr1[RGB_ALPHA] = 0xFF;
182#endif
hbono@chromium.orgc6beb742011-11-29 05:16:26 +0000183 }
184}