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 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 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 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