• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2011 The LibYuv project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "libyuv/general.h"
12 
13 #include <string.h>     // memcpy(), memset()
14 
15 #include "libyuv/planar_functions.h"
16 
17 namespace libyuv {
18 
19 int
I420Mirror(const uint8 * src_yplane,int src_ystride,const uint8 * src_uplane,int src_ustride,const uint8 * src_vplane,int src_vstride,uint8 * dst_yplane,int dst_ystride,uint8 * dst_uplane,int dst_ustride,uint8 * dst_vplane,int dst_vstride,int width,int height)20 I420Mirror(const uint8* src_yplane, int src_ystride,
21            const uint8* src_uplane, int src_ustride,
22            const uint8* src_vplane, int src_vstride,
23            uint8* dst_yplane, int dst_ystride,
24            uint8* dst_uplane, int dst_ustride,
25            uint8* dst_vplane, int dst_vstride,
26            int width, int height) {
27   if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL ||
28       dst_yplane == NULL || dst_uplane == NULL || dst_vplane == NULL) {
29     return -1;
30   }
31 
32   int indO = 0;
33   int indS  = 0;
34   int wind, hind;
35   uint8 tmpVal, tmpValU, tmpValV;
36   // Will swap two values per iteration
37   const int halfWidth = (width + 1) >> 1;
38 
39   // Y
40   for (wind = 0; wind < halfWidth; wind++) {
41    for (hind = 0; hind < height; hind++) {
42      indO = hind * src_ystride + wind;
43      indS = hind * dst_ystride + (width - wind - 1);
44      tmpVal = src_yplane[indO];
45      dst_yplane[indO] = src_yplane[indS];
46      dst_yplane[indS] = tmpVal;
47     }
48   }
49 
50   const int halfHeight = (height + 1) >> 1;
51   const int halfSrcuvStride = (height + 1) >> 1;
52   const int halfuvWidth = (width + 1) >> 2;
53 
54   for (wind = 0; wind < halfuvWidth; wind++) {
55    for (hind = 0; hind < halfHeight; hind++) {
56      indO = hind * halfSrcuvStride + wind;
57      indS = hind * halfSrcuvStride + (halfuvWidth - wind - 1);
58      // U
59      tmpValU = src_uplane[indO];
60      dst_uplane[indO] = src_uplane[indS];
61      dst_uplane[indS] = tmpValU;
62      // V
63      tmpValV = src_vplane[indO];
64      dst_vplane[indO] = src_vplane[indS];
65      dst_vplane[indS] = tmpValV;
66    }
67   }
68   return 0;
69 }
70 
71 // Make a center cut
72 int
I420Crop(uint8 * frame,int src_width,int src_height,int dst_width,int dst_height)73 I420Crop(uint8* frame,
74          int src_width, int src_height,
75          int dst_width, int dst_height)
76 {
77   if (frame == NULL)
78     return -1;
79 
80   if (src_width == dst_width && src_height == dst_height) {
81       // Nothing to do
82     return 3 * dst_height * dst_width / 2;
83   }
84   if (dst_width > src_width || dst_height > src_height) {
85       // error
86       return -1;
87   }
88   int i = 0;
89   int m = 0;
90   int loop = 0;
91   int half_dst_width = dst_width / 2;
92   int halfdst_height = dst_height / 2;
93   int halfsrc_width = src_width / 2;
94   int half_dst_height= src_height / 2;
95   int crop_height = ( src_height - dst_height ) / 2;
96   int crop_width = ( src_width - dst_width ) / 2;
97 
98   for (i = src_width * crop_height + crop_width; loop < dst_height ;
99       loop++, i += src_width) {
100     memcpy(&frame[m],&frame[i],dst_width);
101     m += dst_width;
102   }
103   i = src_width * src_height; // ilum
104   loop = 0;
105   for ( i += (halfsrc_width * crop_height / 2 + crop_width / 2);
106         loop < halfdst_height; loop++,i += halfsrc_width) {
107     memcpy(&frame[m],&frame[i],half_dst_width);
108     m += half_dst_width;
109   }
110   loop = 0;
111   i = src_width * src_height + half_dst_height * halfsrc_width; // ilum + Cr
112   for ( i += (halfsrc_width * crop_height / 2 + crop_width / 2);
113         loop < halfdst_height; loop++, i += halfsrc_width) {
114     memcpy(&frame[m],&frame[i],half_dst_width);
115     m += half_dst_width;
116   }
117   return 0;
118 }
119 
120 
121 int
I420CropPad(const uint8 * src_frame,int src_width,int src_height,uint8 * dst_frame,int dst_width,int dst_height)122 I420CropPad(const uint8* src_frame, int src_width,
123             int src_height, uint8* dst_frame,
124             int dst_width, int dst_height)
125 {
126   if (src_width < 1 || dst_width < 1 || src_height < 1 || dst_height < 1) {
127     return -1;
128   }
129   if (src_width == dst_width && src_height == dst_height) {
130     memcpy(dst_frame, src_frame, 3 * dst_width * (dst_height >> 1));
131   } else {
132     if (src_height < dst_height) {
133       // pad height
134       int pad_height = dst_height - src_height;
135       int i = 0;
136       int pad_width = 0;
137       int crop_width = 0;
138       int width = src_width;
139       if (src_width < dst_width) {
140         // pad width
141         pad_width = dst_width - src_width;
142       } else {
143         // cut width
144         crop_width = src_width - dst_width;
145         width = dst_width;
146       }
147       if (pad_height) {
148         memset(dst_frame, 0, dst_width * (pad_height >> 1));
149         dst_frame +=  dst_width * (pad_height >> 1);
150       }
151       for (i = 0; i < src_height;i++) {
152         if (pad_width) {
153             memset(dst_frame, 0, pad_width / 2);
154             dst_frame +=  pad_width / 2;
155         }
156         src_frame += crop_width >> 1; // in case we have a cut
157         memcpy(dst_frame,src_frame ,width);
158         src_frame += crop_width >> 1;
159         dst_frame += width;
160         src_frame += width;
161         if (pad_width) {
162           memset(dst_frame, 0, pad_width / 2);
163           dst_frame +=  pad_width / 2;
164         }
165       }
166       if (pad_height) {
167         memset(dst_frame, 0, dst_width * (pad_height >> 1));
168         dst_frame +=  dst_width * (pad_height >> 1);
169       }
170       if (pad_height) {
171         memset(dst_frame, 127, (dst_width >> 2) * (pad_height >> 1));
172         dst_frame +=  (dst_width >> 2) * (pad_height >> 1);
173       }
174       for (i = 0; i < (src_height >> 1); i++) {
175         if (pad_width) {
176           memset(dst_frame, 127, pad_width >> 2);
177           dst_frame +=  pad_width >> 2;
178         }
179         src_frame += crop_width >> 2; // in case we have a cut
180         memcpy(dst_frame, src_frame,width >> 1);
181         src_frame += crop_width >> 2;
182         dst_frame += width >> 1;
183         src_frame += width >> 1;
184         if (pad_width) {
185           memset(dst_frame, 127, pad_width >> 2);
186           dst_frame +=  pad_width >> 2;
187         }
188       }
189       if (pad_height) {
190         memset(dst_frame, 127, (dst_width >> 1) * (pad_height >> 1));
191         dst_frame +=  (dst_width >> 1) * (pad_height >> 1);
192       }
193       for (i = 0; i < (src_height >> 1); i++) {
194         if (pad_width) {
195           memset(dst_frame, 127, pad_width >> 2);
196           dst_frame +=  pad_width >> 2;
197         }
198         src_frame += crop_width >> 2; // in case we have a cut
199         memcpy(dst_frame, src_frame,width >> 1);
200         src_frame += crop_width >> 2;
201         dst_frame += width >> 1;
202         src_frame += width >> 1;
203         if (pad_width) {
204           memset(dst_frame, 127, pad_width >> 2);
205           dst_frame += pad_width >> 2;
206         }
207       }
208       if (pad_height) {
209         memset(dst_frame, 127, (dst_width >> 2) * (pad_height >> 1));
210         dst_frame +=  (dst_width >> 2) * (pad_height >> 1);
211       }
212     } else {
213       // cut height
214       int i = 0;
215       int pad_width = 0;
216       int crop_width = 0;
217       int width = src_width;
218 
219       if (src_width < dst_width) {
220         // pad width
221         pad_width = dst_width - src_width;
222       } else {
223         // cut width
224         crop_width = src_width - dst_width;
225         width = dst_width;
226       }
227       int diff_height = src_height - dst_height;
228       src_frame += src_width * (diff_height >> 1);  // skip top I
229 
230       for (i = 0; i < dst_height; i++) {
231         if (pad_width) {
232           memset(dst_frame, 0, pad_width / 2);
233           dst_frame +=  pad_width / 2;
234         }
235         src_frame += crop_width >> 1; // in case we have a cut
236         memcpy(dst_frame,src_frame ,width);
237         src_frame += crop_width >> 1;
238         dst_frame += width;
239         src_frame += width;
240         if (pad_width) {
241           memset(dst_frame, 0, pad_width / 2);
242           dst_frame +=  pad_width / 2;
243         }
244       }
245       src_frame += src_width * (diff_height >> 1);  // skip end I
246       src_frame += (src_width >> 2) * (diff_height >> 1); // skip top of Cr
247       for (i = 0; i < (dst_height >> 1); i++) {
248         if (pad_width) {
249           memset(dst_frame, 127, pad_width >> 2);
250           dst_frame +=  pad_width >> 2;
251         }
252         src_frame += crop_width >> 2; // in case we have a cut
253         memcpy(dst_frame, src_frame,width >> 1);
254         src_frame += crop_width >> 2;
255         dst_frame += width >> 1;
256         src_frame += width >> 1;
257         if (pad_width) {
258           memset(dst_frame, 127, pad_width >> 2);
259           dst_frame +=  pad_width >> 2;
260         }
261       }
262       src_frame += (src_width >> 2) * (diff_height >> 1); // skip end of Cr
263       src_frame += (src_width >> 2) * (diff_height >> 1); // skip top of Cb
264       for (i = 0; i < (dst_height >> 1); i++) {
265         if (pad_width) {
266           memset(dst_frame, 127, pad_width >> 2);
267           dst_frame +=  pad_width >> 2;
268         }
269         src_frame += crop_width >> 2; // in case we have a cut
270         memcpy(dst_frame, src_frame, width >> 1);
271         src_frame += crop_width >> 2;
272         dst_frame += width >> 1;
273         src_frame += width >> 1;
274         if (pad_width) {
275           memset(dst_frame, 127, pad_width >> 2);
276           dst_frame +=  pad_width >> 2;
277         }
278       }
279     }
280   }
281   return 0;
282 }
283 
284 } // namespace libyuv
285