1 /*
2  * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3  *
4  * This source code is subject to the terms of the BSD 2 Clause License and
5  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6  * was not distributed with this source code in the LICENSE file, you can
7  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8  * Media Patent License 1.0 was not distributed with this source code in the
9  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10  */
11 
12 #include "config/aom_scale_rtcd.h"
13 
14 #include "aom_scale/aom_scale.h"
15 #include "aom_mem/aom_mem.h"
16 /****************************************************************************
17  *  Imports
18  ****************************************************************************/
19 
20 /****************************************************************************
21  *
22  *
23  *  INPUTS        : const unsigned char *source : Pointer to source data.
24  *                  unsigned int source_width   : Stride of source.
25  *                  unsigned char *dest         : Pointer to destination data.
26  *                  unsigned int dest_width     : Stride of destination
27  *                                                (NOT USED).
28  *
29  *  OUTPUTS       : None.
30  *
31  *  RETURNS       : void
32  *
33  *  FUNCTION      : Copies horizontal line of pixels from source to
34  *                  destination scaling up by 4 to 5.
35  *
36  *  SPECIAL NOTES : None.
37  *
38  ****************************************************************************/
aom_horizontal_line_5_4_scale_c(const unsigned char * source,unsigned int source_width,unsigned char * dest,unsigned int dest_width)39 void aom_horizontal_line_5_4_scale_c(const unsigned char *source,
40                                      unsigned int source_width,
41                                      unsigned char *dest,
42                                      unsigned int dest_width) {
43   const unsigned char *const source_end = source + source_width;
44   (void)dest_width;
45 
46   while (source < source_end) {
47     const unsigned int a = source[0];
48     const unsigned int b = source[1];
49     const unsigned int c = source[2];
50     const unsigned int d = source[3];
51     const unsigned int e = source[4];
52 
53     dest[0] = (unsigned char)a;
54     dest[1] = (unsigned char)((b * 192 + c * 64 + 128) >> 8);
55     dest[2] = (unsigned char)((c * 128 + d * 128 + 128) >> 8);
56     dest[3] = (unsigned char)((d * 64 + e * 192 + 128) >> 8);
57 
58     source += 5;
59     dest += 4;
60   }
61 }
62 
aom_vertical_band_5_4_scale_c(unsigned char * source,int src_pitch,unsigned char * dest,int dest_pitch,unsigned int dest_width)63 void aom_vertical_band_5_4_scale_c(unsigned char *source, int src_pitch,
64                                    unsigned char *dest, int dest_pitch,
65                                    unsigned int dest_width) {
66   const unsigned char *const dest_end = dest + dest_width;
67   while (dest < dest_end) {
68     const unsigned int a = source[0 * src_pitch];
69     const unsigned int b = source[1 * src_pitch];
70     const unsigned int c = source[2 * src_pitch];
71     const unsigned int d = source[3 * src_pitch];
72     const unsigned int e = source[4 * src_pitch];
73 
74     dest[0 * dest_pitch] = (unsigned char)a;
75     dest[1 * dest_pitch] = (unsigned char)((b * 192 + c * 64 + 128) >> 8);
76     dest[2 * dest_pitch] = (unsigned char)((c * 128 + d * 128 + 128) >> 8);
77     dest[3 * dest_pitch] = (unsigned char)((d * 64 + e * 192 + 128) >> 8);
78 
79     ++source;
80     ++dest;
81   }
82 }
83 
84 /*7***************************************************************************
85  *
86  *  ROUTINE       : aom_horizontal_line_3_5_scale_c
87  *
88  *  INPUTS        : const unsigned char *source : Pointer to source data.
89  *                  unsigned int source_width   : Stride of source.
90  *                  unsigned char *dest         : Pointer to destination data.
91  *                  unsigned int dest_width     : Stride of destination
92  *                                                (NOT USED).
93  *
94  *  OUTPUTS       : None.
95  *
96  *  RETURNS       : void
97  *
98  *  FUNCTION      : Copies horizontal line of pixels from source to
99  *                  destination scaling up by 3 to 5.
100  *
101  *  SPECIAL NOTES : None.
102  *
103  *
104  ****************************************************************************/
aom_horizontal_line_5_3_scale_c(const unsigned char * source,unsigned int source_width,unsigned char * dest,unsigned int dest_width)105 void aom_horizontal_line_5_3_scale_c(const unsigned char *source,
106                                      unsigned int source_width,
107                                      unsigned char *dest,
108                                      unsigned int dest_width) {
109   const unsigned char *const source_end = source + source_width;
110   (void)dest_width;
111   while (source < source_end) {
112     const unsigned int a = source[0];
113     const unsigned int b = source[1];
114     const unsigned int c = source[2];
115     const unsigned int d = source[3];
116     const unsigned int e = source[4];
117 
118     dest[0] = (unsigned char)a;
119     dest[1] = (unsigned char)((b * 85 + c * 171 + 128) >> 8);
120     dest[2] = (unsigned char)((d * 171 + e * 85 + 128) >> 8);
121 
122     source += 5;
123     dest += 3;
124   }
125 }
126 
aom_vertical_band_5_3_scale_c(unsigned char * source,int src_pitch,unsigned char * dest,int dest_pitch,unsigned int dest_width)127 void aom_vertical_band_5_3_scale_c(unsigned char *source, int src_pitch,
128                                    unsigned char *dest, int dest_pitch,
129                                    unsigned int dest_width) {
130   const unsigned char *const dest_end = dest + dest_width;
131   while (dest < dest_end) {
132     const unsigned int a = source[0 * src_pitch];
133     const unsigned int b = source[1 * src_pitch];
134     const unsigned int c = source[2 * src_pitch];
135     const unsigned int d = source[3 * src_pitch];
136     const unsigned int e = source[4 * src_pitch];
137 
138     dest[0 * dest_pitch] = (unsigned char)a;
139     dest[1 * dest_pitch] = (unsigned char)((b * 85 + c * 171 + 128) >> 8);
140     dest[2 * dest_pitch] = (unsigned char)((d * 171 + e * 85 + 128) >> 8);
141 
142     ++source;
143     ++dest;
144   }
145 }
146 
147 /****************************************************************************
148  *
149  *  ROUTINE       : aom_horizontal_line_1_2_scale_c
150  *
151  *  INPUTS        : const unsigned char *source : Pointer to source data.
152  *                  unsigned int source_width   : Stride of source.
153  *                  unsigned char *dest         : Pointer to destination data.
154  *                  unsigned int dest_width     : Stride of destination
155  *                                                (NOT USED).
156  *
157  *  OUTPUTS       : None.
158  *
159  *  RETURNS       : void
160  *
161  *  FUNCTION      : Copies horizontal line of pixels from source to
162  *                  destination scaling up by 1 to 2.
163  *
164  *  SPECIAL NOTES : None.
165  *
166  ****************************************************************************/
aom_horizontal_line_2_1_scale_c(const unsigned char * source,unsigned int source_width,unsigned char * dest,unsigned int dest_width)167 void aom_horizontal_line_2_1_scale_c(const unsigned char *source,
168                                      unsigned int source_width,
169                                      unsigned char *dest,
170                                      unsigned int dest_width) {
171   const unsigned char *const source_end = source + source_width;
172   (void)dest_width;
173   while (source < source_end) {
174     dest[0] = source[0];
175     source += 2;
176     ++dest;
177   }
178 }
179 
aom_vertical_band_2_1_scale_c(unsigned char * source,int src_pitch,unsigned char * dest,int dest_pitch,unsigned int dest_width)180 void aom_vertical_band_2_1_scale_c(unsigned char *source, int src_pitch,
181                                    unsigned char *dest, int dest_pitch,
182                                    unsigned int dest_width) {
183   (void)dest_pitch;
184   (void)src_pitch;
185   memcpy(dest, source, dest_width);
186 }
187 
aom_vertical_band_2_1_scale_i_c(unsigned char * source,int src_pitch,unsigned char * dest,int dest_pitch,unsigned int dest_width)188 void aom_vertical_band_2_1_scale_i_c(unsigned char *source, int src_pitch,
189                                      unsigned char *dest, int dest_pitch,
190                                      unsigned int dest_width) {
191   const unsigned char *const dest_end = dest + dest_width;
192   (void)dest_pitch;
193   while (dest < dest_end) {
194     const unsigned int a = source[-src_pitch] * 3;
195     const unsigned int b = source[0] * 10;
196     const unsigned int c = source[src_pitch] * 3;
197     dest[0] = (unsigned char)((8 + a + b + c) >> 4);
198     ++source;
199     ++dest;
200   }
201 }
202