forked from mozilla/mozjpeg
-
Notifications
You must be signed in to change notification settings - Fork 2
/
jdcolext.c
141 lines (127 loc) · 4.29 KB
/
jdcolext.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
* jdcolext.c
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1997, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2009, 2011, 2015, 2023, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file contains output colorspace conversion routines.
*/
/* This file is included by jdcolor.c */
/*
* Convert some rows of samples to the output colorspace.
*
* Note that we change from noninterleaved, one-plane-per-component format
* to interleaved-pixel format. The output buffer is therefore three times
* as wide as the input buffer.
* A starting row offset is provided only for the input buffer. The caller
* can easily adjust the passed output_buf value to accommodate any row
* offset required on that side.
*/
INLINE
LOCAL(void)
ycc_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
JDIMENSION input_row, JSAMPARRAY output_buf,
int num_rows)
{
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
register int y, cb, cr;
register JSAMPROW outptr;
register JSAMPROW inptr0, inptr1, inptr2;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->output_width;
/* copy these pointers into registers if possible */
register JSAMPLE *range_limit = cinfo->sample_range_limit;
register int *Crrtab = cconvert->Cr_r_tab;
register int *Cbbtab = cconvert->Cb_b_tab;
register JLONG *Crgtab = cconvert->Cr_g_tab;
register JLONG *Cbgtab = cconvert->Cb_g_tab;
SHIFT_TEMPS
while (--num_rows >= 0) {
inptr0 = input_buf[0][input_row];
inptr1 = input_buf[1][input_row];
inptr2 = input_buf[2][input_row];
input_row++;
outptr = *output_buf++;
for (col = 0; col < num_cols; col++) {
y = inptr0[col];
cb = inptr1[col];
cr = inptr2[col];
/* Range-limiting is essential due to noise introduced by DCT losses. */
outptr[RGB_RED] = range_limit[y + Crrtab[cr]];
outptr[RGB_GREEN] = range_limit[y +
((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
SCALEBITS))];
outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]];
/* Set unused byte to MAXJSAMPLE so it can be interpreted as an opaque */
/* alpha channel value */
#ifdef RGB_ALPHA
outptr[RGB_ALPHA] = MAXJSAMPLE;
#endif
outptr += RGB_PIXELSIZE;
}
}
}
/*
* Convert grayscale to RGB: just duplicate the graylevel three times.
* This is provided to support applications that don't want to cope
* with grayscale as a separate case.
*/
INLINE
LOCAL(void)
gray_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
JDIMENSION input_row, JSAMPARRAY output_buf,
int num_rows)
{
register JSAMPROW inptr, outptr;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->output_width;
while (--num_rows >= 0) {
inptr = input_buf[0][input_row++];
outptr = *output_buf++;
for (col = 0; col < num_cols; col++) {
outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
/* Set unused byte to MAXJSAMPLE so it can be interpreted as an opaque */
/* alpha channel value */
#ifdef RGB_ALPHA
outptr[RGB_ALPHA] = MAXJSAMPLE;
#endif
outptr += RGB_PIXELSIZE;
}
}
}
/*
* Convert RGB to extended RGB: just swap the order of source pixels
*/
INLINE
LOCAL(void)
rgb_rgb_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
JDIMENSION input_row, JSAMPARRAY output_buf,
int num_rows)
{
register JSAMPROW inptr0, inptr1, inptr2;
register JSAMPROW outptr;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->output_width;
while (--num_rows >= 0) {
inptr0 = input_buf[0][input_row];
inptr1 = input_buf[1][input_row];
inptr2 = input_buf[2][input_row];
input_row++;
outptr = *output_buf++;
for (col = 0; col < num_cols; col++) {
outptr[RGB_RED] = inptr0[col];
outptr[RGB_GREEN] = inptr1[col];
outptr[RGB_BLUE] = inptr2[col];
/* Set unused byte to MAXJSAMPLE so it can be interpreted as an opaque */
/* alpha channel value */
#ifdef RGB_ALPHA
outptr[RGB_ALPHA] = MAXJSAMPLE;
#endif
outptr += RGB_PIXELSIZE;
}
}
}