annotate ffmpeg/libswscale/rgb2rgb_template.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents f445c3017523
children
rev   line source
yading@11 1 /*
yading@11 2 * software RGB to RGB converter
yading@11 3 * pluralize by software PAL8 to RGB converter
yading@11 4 * software YUV to YUV converter
yading@11 5 * software YUV to RGB converter
yading@11 6 * Written by Nick Kurshev.
yading@11 7 * palette & YUV & runtime CPU stuff by Michael (michaelni@gmx.at)
yading@11 8 * lot of big-endian byte order fixes by Alex Beregszaszi
yading@11 9 *
yading@11 10 * This file is part of FFmpeg.
yading@11 11 *
yading@11 12 * FFmpeg is free software; you can redistribute it and/or
yading@11 13 * modify it under the terms of the GNU Lesser General Public
yading@11 14 * License as published by the Free Software Foundation; either
yading@11 15 * version 2.1 of the License, or (at your option) any later version.
yading@11 16 *
yading@11 17 * FFmpeg is distributed in the hope that it will be useful,
yading@11 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@11 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@11 20 * Lesser General Public License for more details.
yading@11 21 *
yading@11 22 * You should have received a copy of the GNU Lesser General Public
yading@11 23 * License along with FFmpeg; if not, write to the Free Software
yading@11 24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@11 25 */
yading@11 26
yading@11 27 #include <stddef.h>
yading@11 28
yading@11 29 static inline void rgb24tobgr32_c(const uint8_t *src, uint8_t *dst,
yading@11 30 int src_size)
yading@11 31 {
yading@11 32 uint8_t *dest = dst;
yading@11 33 const uint8_t *s = src;
yading@11 34 const uint8_t *end = s + src_size;
yading@11 35
yading@11 36 while (s < end) {
yading@11 37 #if HAVE_BIGENDIAN
yading@11 38 /* RGB24 (= R, G, B) -> RGB32 (= A, B, G, R) */
yading@11 39 *dest++ = 255;
yading@11 40 *dest++ = s[2];
yading@11 41 *dest++ = s[1];
yading@11 42 *dest++ = s[0];
yading@11 43 s += 3;
yading@11 44 #else
yading@11 45 *dest++ = *s++;
yading@11 46 *dest++ = *s++;
yading@11 47 *dest++ = *s++;
yading@11 48 *dest++ = 255;
yading@11 49 #endif
yading@11 50 }
yading@11 51 }
yading@11 52
yading@11 53 static inline void rgb32tobgr24_c(const uint8_t *src, uint8_t *dst,
yading@11 54 int src_size)
yading@11 55 {
yading@11 56 uint8_t *dest = dst;
yading@11 57 const uint8_t *s = src;
yading@11 58 const uint8_t *end = s + src_size;
yading@11 59
yading@11 60 while (s < end) {
yading@11 61 #if HAVE_BIGENDIAN
yading@11 62 /* RGB32 (= A, B, G, R) -> RGB24 (= R, G, B) */
yading@11 63 s++;
yading@11 64 dest[2] = *s++;
yading@11 65 dest[1] = *s++;
yading@11 66 dest[0] = *s++;
yading@11 67 dest += 3;
yading@11 68 #else
yading@11 69 *dest++ = *s++;
yading@11 70 *dest++ = *s++;
yading@11 71 *dest++ = *s++;
yading@11 72 s++;
yading@11 73 #endif
yading@11 74 }
yading@11 75 }
yading@11 76
yading@11 77 /*
yading@11 78 * original by Strepto/Astral
yading@11 79 * ported to gcc & bugfixed: A'rpi
yading@11 80 * MMXEXT, 3DNOW optimization by Nick Kurshev
yading@11 81 * 32-bit C version, and and&add trick by Michael Niedermayer
yading@11 82 */
yading@11 83 static inline void rgb15to16_c(const uint8_t *src, uint8_t *dst, int src_size)
yading@11 84 {
yading@11 85 register uint8_t *d = dst;
yading@11 86 register const uint8_t *s = src;
yading@11 87 register const uint8_t *end = s + src_size;
yading@11 88 const uint8_t *mm_end = end - 3;
yading@11 89
yading@11 90 while (s < mm_end) {
yading@11 91 register unsigned x = *((const uint32_t *)s);
yading@11 92 *((uint32_t *)d) = (x & 0x7FFF7FFF) + (x & 0x7FE07FE0);
yading@11 93 d += 4;
yading@11 94 s += 4;
yading@11 95 }
yading@11 96 if (s < end) {
yading@11 97 register unsigned short x = *((const uint16_t *)s);
yading@11 98 *((uint16_t *)d) = (x & 0x7FFF) + (x & 0x7FE0);
yading@11 99 }
yading@11 100 }
yading@11 101
yading@11 102 static inline void rgb16to15_c(const uint8_t *src, uint8_t *dst, int src_size)
yading@11 103 {
yading@11 104 register uint8_t *d = dst;
yading@11 105 register const uint8_t *s = src;
yading@11 106 register const uint8_t *end = s + src_size;
yading@11 107 const uint8_t *mm_end = end - 3;
yading@11 108
yading@11 109 while (s < mm_end) {
yading@11 110 register uint32_t x = *((const uint32_t *)s);
yading@11 111 *((uint32_t *)d) = ((x >> 1) & 0x7FE07FE0) | (x & 0x001F001F);
yading@11 112 s += 4;
yading@11 113 d += 4;
yading@11 114 }
yading@11 115 if (s < end) {
yading@11 116 register uint16_t x = *((const uint16_t *)s);
yading@11 117 *((uint16_t *)d) = ((x >> 1) & 0x7FE0) | (x & 0x001F);
yading@11 118 }
yading@11 119 }
yading@11 120
yading@11 121 static inline void rgb32to16_c(const uint8_t *src, uint8_t *dst, int src_size)
yading@11 122 {
yading@11 123 uint16_t *d = (uint16_t *)dst;
yading@11 124 const uint8_t *s = src;
yading@11 125 const uint8_t *end = s + src_size;
yading@11 126
yading@11 127 while (s < end) {
yading@11 128 register int rgb = *(const uint32_t *)s;
yading@11 129 s += 4;
yading@11 130 *d++ = ((rgb & 0xFF) >> 3) +
yading@11 131 ((rgb & 0xFC00) >> 5) +
yading@11 132 ((rgb & 0xF80000) >> 8);
yading@11 133 }
yading@11 134 }
yading@11 135
yading@11 136 static inline void rgb32tobgr16_c(const uint8_t *src, uint8_t *dst,
yading@11 137 int src_size)
yading@11 138 {
yading@11 139 uint16_t *d = (uint16_t *)dst;
yading@11 140 const uint8_t *s = src;
yading@11 141 const uint8_t *end = s + src_size;
yading@11 142
yading@11 143 while (s < end) {
yading@11 144 register int rgb = *(const uint32_t *)s;
yading@11 145 s += 4;
yading@11 146 *d++ = ((rgb & 0xF8) << 8) +
yading@11 147 ((rgb & 0xFC00) >> 5) +
yading@11 148 ((rgb & 0xF80000) >> 19);
yading@11 149 }
yading@11 150 }
yading@11 151
yading@11 152 static inline void rgb32to15_c(const uint8_t *src, uint8_t *dst, int src_size)
yading@11 153 {
yading@11 154 uint16_t *d = (uint16_t *)dst;
yading@11 155 const uint8_t *s = src;
yading@11 156 const uint8_t *end = s + src_size;
yading@11 157
yading@11 158 while (s < end) {
yading@11 159 register int rgb = *(const uint32_t *)s;
yading@11 160 s += 4;
yading@11 161 *d++ = ((rgb & 0xFF) >> 3) +
yading@11 162 ((rgb & 0xF800) >> 6) +
yading@11 163 ((rgb & 0xF80000) >> 9);
yading@11 164 }
yading@11 165 }
yading@11 166
yading@11 167 static inline void rgb32tobgr15_c(const uint8_t *src, uint8_t *dst,
yading@11 168 int src_size)
yading@11 169 {
yading@11 170 uint16_t *d = (uint16_t *)dst;
yading@11 171 const uint8_t *s = src;
yading@11 172 const uint8_t *end = s + src_size;
yading@11 173
yading@11 174 while (s < end) {
yading@11 175 register int rgb = *(const uint32_t *)s;
yading@11 176 s += 4;
yading@11 177 *d++ = ((rgb & 0xF8) << 7) +
yading@11 178 ((rgb & 0xF800) >> 6) +
yading@11 179 ((rgb & 0xF80000) >> 19);
yading@11 180 }
yading@11 181 }
yading@11 182
yading@11 183 static inline void rgb24tobgr16_c(const uint8_t *src, uint8_t *dst,
yading@11 184 int src_size)
yading@11 185 {
yading@11 186 uint16_t *d = (uint16_t *)dst;
yading@11 187 const uint8_t *s = src;
yading@11 188 const uint8_t *end = s + src_size;
yading@11 189
yading@11 190 while (s < end) {
yading@11 191 const int b = *s++;
yading@11 192 const int g = *s++;
yading@11 193 const int r = *s++;
yading@11 194 *d++ = (b >> 3) | ((g & 0xFC) << 3) | ((r & 0xF8) << 8);
yading@11 195 }
yading@11 196 }
yading@11 197
yading@11 198 static inline void rgb24to16_c(const uint8_t *src, uint8_t *dst, int src_size)
yading@11 199 {
yading@11 200 uint16_t *d = (uint16_t *)dst;
yading@11 201 const uint8_t *s = src;
yading@11 202 const uint8_t *end = s + src_size;
yading@11 203
yading@11 204 while (s < end) {
yading@11 205 const int r = *s++;
yading@11 206 const int g = *s++;
yading@11 207 const int b = *s++;
yading@11 208 *d++ = (b >> 3) | ((g & 0xFC) << 3) | ((r & 0xF8) << 8);
yading@11 209 }
yading@11 210 }
yading@11 211
yading@11 212 static inline void rgb24tobgr15_c(const uint8_t *src, uint8_t *dst,
yading@11 213 int src_size)
yading@11 214 {
yading@11 215 uint16_t *d = (uint16_t *)dst;
yading@11 216 const uint8_t *s = src;
yading@11 217 const uint8_t *end = s + src_size;
yading@11 218
yading@11 219 while (s < end) {
yading@11 220 const int b = *s++;
yading@11 221 const int g = *s++;
yading@11 222 const int r = *s++;
yading@11 223 *d++ = (b >> 3) | ((g & 0xF8) << 2) | ((r & 0xF8) << 7);
yading@11 224 }
yading@11 225 }
yading@11 226
yading@11 227 static inline void rgb24to15_c(const uint8_t *src, uint8_t *dst, int src_size)
yading@11 228 {
yading@11 229 uint16_t *d = (uint16_t *)dst;
yading@11 230 const uint8_t *s = src;
yading@11 231 const uint8_t *end = s + src_size;
yading@11 232
yading@11 233 while (s < end) {
yading@11 234 const int r = *s++;
yading@11 235 const int g = *s++;
yading@11 236 const int b = *s++;
yading@11 237 *d++ = (b >> 3) | ((g & 0xF8) << 2) | ((r & 0xF8) << 7);
yading@11 238 }
yading@11 239 }
yading@11 240
yading@11 241 static inline void rgb15tobgr24_c(const uint8_t *src, uint8_t *dst,
yading@11 242 int src_size)
yading@11 243 {
yading@11 244 uint8_t *d = dst;
yading@11 245 const uint16_t *s = (const uint16_t *)src;
yading@11 246 const uint16_t *end = s + src_size / 2;
yading@11 247
yading@11 248 while (s < end) {
yading@11 249 register uint16_t bgr = *s++;
yading@11 250 *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
yading@11 251 *d++ = ((bgr&0x03E0)>>2) | ((bgr&0x03E0)>> 7);
yading@11 252 *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
yading@11 253 }
yading@11 254 }
yading@11 255
yading@11 256 static inline void rgb16tobgr24_c(const uint8_t *src, uint8_t *dst,
yading@11 257 int src_size)
yading@11 258 {
yading@11 259 uint8_t *d = (uint8_t *)dst;
yading@11 260 const uint16_t *s = (const uint16_t *)src;
yading@11 261 const uint16_t *end = s + src_size / 2;
yading@11 262
yading@11 263 while (s < end) {
yading@11 264 register uint16_t bgr = *s++;
yading@11 265 *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
yading@11 266 *d++ = ((bgr&0x07E0)>>3) | ((bgr&0x07E0)>> 9);
yading@11 267 *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
yading@11 268 }
yading@11 269 }
yading@11 270
yading@11 271 static inline void rgb15to32_c(const uint8_t *src, uint8_t *dst, int src_size)
yading@11 272 {
yading@11 273 uint8_t *d = dst;
yading@11 274 const uint16_t *s = (const uint16_t *)src;
yading@11 275 const uint16_t *end = s + src_size / 2;
yading@11 276
yading@11 277 while (s < end) {
yading@11 278 register uint16_t bgr = *s++;
yading@11 279 #if HAVE_BIGENDIAN
yading@11 280 *d++ = 255;
yading@11 281 *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
yading@11 282 *d++ = ((bgr&0x03E0)>>2) | ((bgr&0x03E0)>> 7);
yading@11 283 *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
yading@11 284 #else
yading@11 285 *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
yading@11 286 *d++ = ((bgr&0x03E0)>>2) | ((bgr&0x03E0)>> 7);
yading@11 287 *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
yading@11 288 *d++ = 255;
yading@11 289 #endif
yading@11 290 }
yading@11 291 }
yading@11 292
yading@11 293 static inline void rgb16to32_c(const uint8_t *src, uint8_t *dst, int src_size)
yading@11 294 {
yading@11 295 uint8_t *d = dst;
yading@11 296 const uint16_t *s = (const uint16_t *)src;
yading@11 297 const uint16_t *end = s + src_size / 2;
yading@11 298
yading@11 299 while (s < end) {
yading@11 300 register uint16_t bgr = *s++;
yading@11 301 #if HAVE_BIGENDIAN
yading@11 302 *d++ = 255;
yading@11 303 *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
yading@11 304 *d++ = ((bgr&0x07E0)>>3) | ((bgr&0x07E0)>> 9);
yading@11 305 *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
yading@11 306 #else
yading@11 307 *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
yading@11 308 *d++ = ((bgr&0x07E0)>>3) | ((bgr&0x07E0)>> 9);
yading@11 309 *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
yading@11 310 *d++ = 255;
yading@11 311 #endif
yading@11 312 }
yading@11 313 }
yading@11 314
yading@11 315 static inline void shuffle_bytes_2103_c(const uint8_t *src, uint8_t *dst,
yading@11 316 int src_size)
yading@11 317 {
yading@11 318 int idx = 15 - src_size;
yading@11 319 const uint8_t *s = src - idx;
yading@11 320 uint8_t *d = dst - idx;
yading@11 321
yading@11 322 for (; idx < 15; idx += 4) {
yading@11 323 register int v = *(const uint32_t *)&s[idx], g = v & 0xff00ff00;
yading@11 324 v &= 0xff00ff;
yading@11 325 *(uint32_t *)&d[idx] = (v >> 16) + g + (v << 16);
yading@11 326 }
yading@11 327 }
yading@11 328
yading@11 329 static inline void rgb24tobgr24_c(const uint8_t *src, uint8_t *dst, int src_size)
yading@11 330 {
yading@11 331 unsigned i;
yading@11 332
yading@11 333 for (i = 0; i < src_size; i += 3) {
yading@11 334 register uint8_t x = src[i + 2];
yading@11 335 dst[i + 1] = src[i + 1];
yading@11 336 dst[i + 2] = src[i + 0];
yading@11 337 dst[i + 0] = x;
yading@11 338 }
yading@11 339 }
yading@11 340
yading@11 341 static inline void yuvPlanartoyuy2_c(const uint8_t *ysrc, const uint8_t *usrc,
yading@11 342 const uint8_t *vsrc, uint8_t *dst,
yading@11 343 int width, int height,
yading@11 344 int lumStride, int chromStride,
yading@11 345 int dstStride, int vertLumPerChroma)
yading@11 346 {
yading@11 347 int y, i;
yading@11 348 const int chromWidth = width >> 1;
yading@11 349
yading@11 350 for (y = 0; y < height; y++) {
yading@11 351 #if HAVE_FAST_64BIT
yading@11 352 uint64_t *ldst = (uint64_t *)dst;
yading@11 353 const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;
yading@11 354 for (i = 0; i < chromWidth; i += 2) {
yading@11 355 uint64_t k = yc[0] + (uc[0] << 8) +
yading@11 356 (yc[1] << 16) + (unsigned)(vc[0] << 24);
yading@11 357 uint64_t l = yc[2] + (uc[1] << 8) +
yading@11 358 (yc[3] << 16) + (unsigned)(vc[1] << 24);
yading@11 359 *ldst++ = k + (l << 32);
yading@11 360 yc += 4;
yading@11 361 uc += 2;
yading@11 362 vc += 2;
yading@11 363 }
yading@11 364
yading@11 365 #else
yading@11 366 int *idst = (int32_t *)dst;
yading@11 367 const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;
yading@11 368
yading@11 369 for (i = 0; i < chromWidth; i++) {
yading@11 370 #if HAVE_BIGENDIAN
yading@11 371 *idst++ = (yc[0] << 24) + (uc[0] << 16) +
yading@11 372 (yc[1] << 8) + (vc[0] << 0);
yading@11 373 #else
yading@11 374 *idst++ = yc[0] + (uc[0] << 8) +
yading@11 375 (yc[1] << 16) + (vc[0] << 24);
yading@11 376 #endif
yading@11 377 yc += 2;
yading@11 378 uc++;
yading@11 379 vc++;
yading@11 380 }
yading@11 381 #endif
yading@11 382 if ((y & (vertLumPerChroma - 1)) == vertLumPerChroma - 1) {
yading@11 383 usrc += chromStride;
yading@11 384 vsrc += chromStride;
yading@11 385 }
yading@11 386 ysrc += lumStride;
yading@11 387 dst += dstStride;
yading@11 388 }
yading@11 389 }
yading@11 390
yading@11 391 /**
yading@11 392 * Height should be a multiple of 2 and width should be a multiple of 16.
yading@11 393 * (If this is a problem for anyone then tell me, and I will fix it.)
yading@11 394 */
yading@11 395 static inline void yv12toyuy2_c(const uint8_t *ysrc, const uint8_t *usrc,
yading@11 396 const uint8_t *vsrc, uint8_t *dst,
yading@11 397 int width, int height, int lumStride,
yading@11 398 int chromStride, int dstStride)
yading@11 399 {
yading@11 400 //FIXME interpolate chroma
yading@11 401 yuvPlanartoyuy2_c(ysrc, usrc, vsrc, dst, width, height, lumStride,
yading@11 402 chromStride, dstStride, 2);
yading@11 403 }
yading@11 404
yading@11 405 static inline void yuvPlanartouyvy_c(const uint8_t *ysrc, const uint8_t *usrc,
yading@11 406 const uint8_t *vsrc, uint8_t *dst,
yading@11 407 int width, int height,
yading@11 408 int lumStride, int chromStride,
yading@11 409 int dstStride, int vertLumPerChroma)
yading@11 410 {
yading@11 411 int y, i;
yading@11 412 const int chromWidth = width >> 1;
yading@11 413
yading@11 414 for (y = 0; y < height; y++) {
yading@11 415 #if HAVE_FAST_64BIT
yading@11 416 uint64_t *ldst = (uint64_t *)dst;
yading@11 417 const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;
yading@11 418 for (i = 0; i < chromWidth; i += 2) {
yading@11 419 uint64_t k = uc[0] + (yc[0] << 8) +
yading@11 420 (vc[0] << 16) + (unsigned)(yc[1] << 24);
yading@11 421 uint64_t l = uc[1] + (yc[2] << 8) +
yading@11 422 (vc[1] << 16) + (unsigned)(yc[3] << 24);
yading@11 423 *ldst++ = k + (l << 32);
yading@11 424 yc += 4;
yading@11 425 uc += 2;
yading@11 426 vc += 2;
yading@11 427 }
yading@11 428
yading@11 429 #else
yading@11 430 int *idst = (int32_t *)dst;
yading@11 431 const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;
yading@11 432
yading@11 433 for (i = 0; i < chromWidth; i++) {
yading@11 434 #if HAVE_BIGENDIAN
yading@11 435 *idst++ = (uc[0] << 24) + (yc[0] << 16) +
yading@11 436 (vc[0] << 8) + (yc[1] << 0);
yading@11 437 #else
yading@11 438 *idst++ = uc[0] + (yc[0] << 8) +
yading@11 439 (vc[0] << 16) + (yc[1] << 24);
yading@11 440 #endif
yading@11 441 yc += 2;
yading@11 442 uc++;
yading@11 443 vc++;
yading@11 444 }
yading@11 445 #endif
yading@11 446 if ((y & (vertLumPerChroma - 1)) == vertLumPerChroma - 1) {
yading@11 447 usrc += chromStride;
yading@11 448 vsrc += chromStride;
yading@11 449 }
yading@11 450 ysrc += lumStride;
yading@11 451 dst += dstStride;
yading@11 452 }
yading@11 453 }
yading@11 454
yading@11 455 /**
yading@11 456 * Height should be a multiple of 2 and width should be a multiple of 16
yading@11 457 * (If this is a problem for anyone then tell me, and I will fix it.)
yading@11 458 */
yading@11 459 static inline void yv12touyvy_c(const uint8_t *ysrc, const uint8_t *usrc,
yading@11 460 const uint8_t *vsrc, uint8_t *dst,
yading@11 461 int width, int height, int lumStride,
yading@11 462 int chromStride, int dstStride)
yading@11 463 {
yading@11 464 //FIXME interpolate chroma
yading@11 465 yuvPlanartouyvy_c(ysrc, usrc, vsrc, dst, width, height, lumStride,
yading@11 466 chromStride, dstStride, 2);
yading@11 467 }
yading@11 468
yading@11 469 /**
yading@11 470 * Width should be a multiple of 16.
yading@11 471 */
yading@11 472 static inline void yuv422ptouyvy_c(const uint8_t *ysrc, const uint8_t *usrc,
yading@11 473 const uint8_t *vsrc, uint8_t *dst,
yading@11 474 int width, int height, int lumStride,
yading@11 475 int chromStride, int dstStride)
yading@11 476 {
yading@11 477 yuvPlanartouyvy_c(ysrc, usrc, vsrc, dst, width, height, lumStride,
yading@11 478 chromStride, dstStride, 1);
yading@11 479 }
yading@11 480
yading@11 481 /**
yading@11 482 * Width should be a multiple of 16.
yading@11 483 */
yading@11 484 static inline void yuv422ptoyuy2_c(const uint8_t *ysrc, const uint8_t *usrc,
yading@11 485 const uint8_t *vsrc, uint8_t *dst,
yading@11 486 int width, int height, int lumStride,
yading@11 487 int chromStride, int dstStride)
yading@11 488 {
yading@11 489 yuvPlanartoyuy2_c(ysrc, usrc, vsrc, dst, width, height, lumStride,
yading@11 490 chromStride, dstStride, 1);
yading@11 491 }
yading@11 492
yading@11 493 /**
yading@11 494 * Height should be a multiple of 2 and width should be a multiple of 16.
yading@11 495 * (If this is a problem for anyone then tell me, and I will fix it.)
yading@11 496 */
yading@11 497 static inline void yuy2toyv12_c(const uint8_t *src, uint8_t *ydst,
yading@11 498 uint8_t *udst, uint8_t *vdst,
yading@11 499 int width, int height, int lumStride,
yading@11 500 int chromStride, int srcStride)
yading@11 501 {
yading@11 502 int y;
yading@11 503 const int chromWidth = width >> 1;
yading@11 504
yading@11 505 for (y = 0; y < height; y += 2) {
yading@11 506 int i;
yading@11 507 for (i = 0; i < chromWidth; i++) {
yading@11 508 ydst[2 * i + 0] = src[4 * i + 0];
yading@11 509 udst[i] = src[4 * i + 1];
yading@11 510 ydst[2 * i + 1] = src[4 * i + 2];
yading@11 511 vdst[i] = src[4 * i + 3];
yading@11 512 }
yading@11 513 ydst += lumStride;
yading@11 514 src += srcStride;
yading@11 515
yading@11 516 for (i = 0; i < chromWidth; i++) {
yading@11 517 ydst[2 * i + 0] = src[4 * i + 0];
yading@11 518 ydst[2 * i + 1] = src[4 * i + 2];
yading@11 519 }
yading@11 520 udst += chromStride;
yading@11 521 vdst += chromStride;
yading@11 522 ydst += lumStride;
yading@11 523 src += srcStride;
yading@11 524 }
yading@11 525 }
yading@11 526
yading@11 527 static inline void planar2x_c(const uint8_t *src, uint8_t *dst, int srcWidth,
yading@11 528 int srcHeight, int srcStride, int dstStride)
yading@11 529 {
yading@11 530 int x, y;
yading@11 531
yading@11 532 dst[0] = src[0];
yading@11 533
yading@11 534 // first line
yading@11 535 for (x = 0; x < srcWidth - 1; x++) {
yading@11 536 dst[2 * x + 1] = (3 * src[x] + src[x + 1]) >> 2;
yading@11 537 dst[2 * x + 2] = (src[x] + 3 * src[x + 1]) >> 2;
yading@11 538 }
yading@11 539 dst[2 * srcWidth - 1] = src[srcWidth - 1];
yading@11 540
yading@11 541 dst += dstStride;
yading@11 542
yading@11 543 for (y = 1; y < srcHeight; y++) {
yading@11 544 const int mmxSize = 1;
yading@11 545
yading@11 546 dst[0] = (src[0] * 3 + src[srcStride]) >> 2;
yading@11 547 dst[dstStride] = (src[0] + 3 * src[srcStride]) >> 2;
yading@11 548
yading@11 549 for (x = mmxSize - 1; x < srcWidth - 1; x++) {
yading@11 550 dst[2 * x + 1] = (src[x + 0] * 3 + src[x + srcStride + 1]) >> 2;
yading@11 551 dst[2 * x + dstStride + 2] = (src[x + 0] + 3 * src[x + srcStride + 1]) >> 2;
yading@11 552 dst[2 * x + dstStride + 1] = (src[x + 1] + 3 * src[x + srcStride]) >> 2;
yading@11 553 dst[2 * x + 2] = (src[x + 1] * 3 + src[x + srcStride]) >> 2;
yading@11 554 }
yading@11 555 dst[srcWidth * 2 - 1] = (src[srcWidth - 1] * 3 + src[srcWidth - 1 + srcStride]) >> 2;
yading@11 556 dst[srcWidth * 2 - 1 + dstStride] = (src[srcWidth - 1] + 3 * src[srcWidth - 1 + srcStride]) >> 2;
yading@11 557
yading@11 558 dst += dstStride * 2;
yading@11 559 src += srcStride;
yading@11 560 }
yading@11 561
yading@11 562 // last line
yading@11 563 dst[0] = src[0];
yading@11 564
yading@11 565 for (x = 0; x < srcWidth - 1; x++) {
yading@11 566 dst[2 * x + 1] = (src[x] * 3 + src[x + 1]) >> 2;
yading@11 567 dst[2 * x + 2] = (src[x] + 3 * src[x + 1]) >> 2;
yading@11 568 }
yading@11 569 dst[2 * srcWidth - 1] = src[srcWidth - 1];
yading@11 570 }
yading@11 571
yading@11 572 /**
yading@11 573 * Height should be a multiple of 2 and width should be a multiple of 16.
yading@11 574 * (If this is a problem for anyone then tell me, and I will fix it.)
yading@11 575 * Chrominance data is only taken from every second line, others are ignored.
yading@11 576 * FIXME: Write HQ version.
yading@11 577 */
yading@11 578 static inline void uyvytoyv12_c(const uint8_t *src, uint8_t *ydst,
yading@11 579 uint8_t *udst, uint8_t *vdst,
yading@11 580 int width, int height, int lumStride,
yading@11 581 int chromStride, int srcStride)
yading@11 582 {
yading@11 583 int y;
yading@11 584 const int chromWidth = width >> 1;
yading@11 585
yading@11 586 for (y = 0; y < height; y += 2) {
yading@11 587 int i;
yading@11 588 for (i = 0; i < chromWidth; i++) {
yading@11 589 udst[i] = src[4 * i + 0];
yading@11 590 ydst[2 * i + 0] = src[4 * i + 1];
yading@11 591 vdst[i] = src[4 * i + 2];
yading@11 592 ydst[2 * i + 1] = src[4 * i + 3];
yading@11 593 }
yading@11 594 ydst += lumStride;
yading@11 595 src += srcStride;
yading@11 596
yading@11 597 for (i = 0; i < chromWidth; i++) {
yading@11 598 ydst[2 * i + 0] = src[4 * i + 1];
yading@11 599 ydst[2 * i + 1] = src[4 * i + 3];
yading@11 600 }
yading@11 601 udst += chromStride;
yading@11 602 vdst += chromStride;
yading@11 603 ydst += lumStride;
yading@11 604 src += srcStride;
yading@11 605 }
yading@11 606 }
yading@11 607
yading@11 608 /**
yading@11 609 * Height should be a multiple of 2 and width should be a multiple of 2.
yading@11 610 * (If this is a problem for anyone then tell me, and I will fix it.)
yading@11 611 * Chrominance data is only taken from every second line,
yading@11 612 * others are ignored in the C version.
yading@11 613 * FIXME: Write HQ version.
yading@11 614 */
yading@11 615 void ff_rgb24toyv12_c(const uint8_t *src, uint8_t *ydst, uint8_t *udst,
yading@11 616 uint8_t *vdst, int width, int height, int lumStride,
yading@11 617 int chromStride, int srcStride, int32_t *rgb2yuv)
yading@11 618 {
yading@11 619 int32_t ry = rgb2yuv[RY_IDX], gy = rgb2yuv[GY_IDX], by = rgb2yuv[BY_IDX];
yading@11 620 int32_t ru = rgb2yuv[RU_IDX], gu = rgb2yuv[GU_IDX], bu = rgb2yuv[BU_IDX];
yading@11 621 int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX];
yading@11 622 int y;
yading@11 623 const int chromWidth = width >> 1;
yading@11 624
yading@11 625 for (y = 0; y < height; y += 2) {
yading@11 626 int i;
yading@11 627 for (i = 0; i < chromWidth; i++) {
yading@11 628 unsigned int b = src[6 * i + 0];
yading@11 629 unsigned int g = src[6 * i + 1];
yading@11 630 unsigned int r = src[6 * i + 2];
yading@11 631
yading@11 632 unsigned int Y = ((ry * r + gy * g + by * b) >> RGB2YUV_SHIFT) + 16;
yading@11 633 unsigned int V = ((rv * r + gv * g + bv * b) >> RGB2YUV_SHIFT) + 128;
yading@11 634 unsigned int U = ((ru * r + gu * g + bu * b) >> RGB2YUV_SHIFT) + 128;
yading@11 635
yading@11 636 udst[i] = U;
yading@11 637 vdst[i] = V;
yading@11 638 ydst[2 * i] = Y;
yading@11 639
yading@11 640 b = src[6 * i + 3];
yading@11 641 g = src[6 * i + 4];
yading@11 642 r = src[6 * i + 5];
yading@11 643
yading@11 644 Y = ((ry * r + gy * g + by * b) >> RGB2YUV_SHIFT) + 16;
yading@11 645 ydst[2 * i + 1] = Y;
yading@11 646 }
yading@11 647 ydst += lumStride;
yading@11 648 src += srcStride;
yading@11 649
yading@11 650 if (y+1 == height)
yading@11 651 break;
yading@11 652
yading@11 653 for (i = 0; i < chromWidth; i++) {
yading@11 654 unsigned int b = src[6 * i + 0];
yading@11 655 unsigned int g = src[6 * i + 1];
yading@11 656 unsigned int r = src[6 * i + 2];
yading@11 657
yading@11 658 unsigned int Y = ((ry * r + gy * g + by * b) >> RGB2YUV_SHIFT) + 16;
yading@11 659
yading@11 660 ydst[2 * i] = Y;
yading@11 661
yading@11 662 b = src[6 * i + 3];
yading@11 663 g = src[6 * i + 4];
yading@11 664 r = src[6 * i + 5];
yading@11 665
yading@11 666 Y = ((ry * r + gy * g + by * b) >> RGB2YUV_SHIFT) + 16;
yading@11 667 ydst[2 * i + 1] = Y;
yading@11 668 }
yading@11 669 udst += chromStride;
yading@11 670 vdst += chromStride;
yading@11 671 ydst += lumStride;
yading@11 672 src += srcStride;
yading@11 673 }
yading@11 674 }
yading@11 675
yading@11 676 static void interleaveBytes_c(const uint8_t *src1, const uint8_t *src2,
yading@11 677 uint8_t *dest, int width, int height,
yading@11 678 int src1Stride, int src2Stride, int dstStride)
yading@11 679 {
yading@11 680 int h;
yading@11 681
yading@11 682 for (h = 0; h < height; h++) {
yading@11 683 int w;
yading@11 684 for (w = 0; w < width; w++) {
yading@11 685 dest[2 * w + 0] = src1[w];
yading@11 686 dest[2 * w + 1] = src2[w];
yading@11 687 }
yading@11 688 dest += dstStride;
yading@11 689 src1 += src1Stride;
yading@11 690 src2 += src2Stride;
yading@11 691 }
yading@11 692 }
yading@11 693
yading@11 694 static inline void vu9_to_vu12_c(const uint8_t *src1, const uint8_t *src2,
yading@11 695 uint8_t *dst1, uint8_t *dst2,
yading@11 696 int width, int height,
yading@11 697 int srcStride1, int srcStride2,
yading@11 698 int dstStride1, int dstStride2)
yading@11 699 {
yading@11 700 int x, y;
yading@11 701 int w = width / 2;
yading@11 702 int h = height / 2;
yading@11 703
yading@11 704 for (y = 0; y < h; y++) {
yading@11 705 const uint8_t *s1 = src1 + srcStride1 * (y >> 1);
yading@11 706 uint8_t *d = dst1 + dstStride1 * y;
yading@11 707 for (x = 0; x < w; x++)
yading@11 708 d[2 * x] = d[2 * x + 1] = s1[x];
yading@11 709 }
yading@11 710 for (y = 0; y < h; y++) {
yading@11 711 const uint8_t *s2 = src2 + srcStride2 * (y >> 1);
yading@11 712 uint8_t *d = dst2 + dstStride2 * y;
yading@11 713 for (x = 0; x < w; x++)
yading@11 714 d[2 * x] = d[2 * x + 1] = s2[x];
yading@11 715 }
yading@11 716 }
yading@11 717
yading@11 718 static inline void yvu9_to_yuy2_c(const uint8_t *src1, const uint8_t *src2,
yading@11 719 const uint8_t *src3, uint8_t *dst,
yading@11 720 int width, int height,
yading@11 721 int srcStride1, int srcStride2,
yading@11 722 int srcStride3, int dstStride)
yading@11 723 {
yading@11 724 int x, y;
yading@11 725 int w = width / 2;
yading@11 726 int h = height;
yading@11 727
yading@11 728 for (y = 0; y < h; y++) {
yading@11 729 const uint8_t *yp = src1 + srcStride1 * y;
yading@11 730 const uint8_t *up = src2 + srcStride2 * (y >> 2);
yading@11 731 const uint8_t *vp = src3 + srcStride3 * (y >> 2);
yading@11 732 uint8_t *d = dst + dstStride * y;
yading@11 733 for (x = 0; x < w; x++) {
yading@11 734 const int x2 = x << 2;
yading@11 735 d[8 * x + 0] = yp[x2];
yading@11 736 d[8 * x + 1] = up[x];
yading@11 737 d[8 * x + 2] = yp[x2 + 1];
yading@11 738 d[8 * x + 3] = vp[x];
yading@11 739 d[8 * x + 4] = yp[x2 + 2];
yading@11 740 d[8 * x + 5] = up[x];
yading@11 741 d[8 * x + 6] = yp[x2 + 3];
yading@11 742 d[8 * x + 7] = vp[x];
yading@11 743 }
yading@11 744 }
yading@11 745 }
yading@11 746
yading@11 747 static void extract_even_c(const uint8_t *src, uint8_t *dst, int count)
yading@11 748 {
yading@11 749 dst += count;
yading@11 750 src += count * 2;
yading@11 751 count = -count;
yading@11 752 while (count < 0) {
yading@11 753 dst[count] = src[2 * count];
yading@11 754 count++;
yading@11 755 }
yading@11 756 }
yading@11 757
yading@11 758 static void extract_even2_c(const uint8_t *src, uint8_t *dst0, uint8_t *dst1,
yading@11 759 int count)
yading@11 760 {
yading@11 761 dst0 += count;
yading@11 762 dst1 += count;
yading@11 763 src += count * 4;
yading@11 764 count = -count;
yading@11 765 while (count < 0) {
yading@11 766 dst0[count] = src[4 * count + 0];
yading@11 767 dst1[count] = src[4 * count + 2];
yading@11 768 count++;
yading@11 769 }
yading@11 770 }
yading@11 771
yading@11 772 static void extract_even2avg_c(const uint8_t *src0, const uint8_t *src1,
yading@11 773 uint8_t *dst0, uint8_t *dst1, int count)
yading@11 774 {
yading@11 775 dst0 += count;
yading@11 776 dst1 += count;
yading@11 777 src0 += count * 4;
yading@11 778 src1 += count * 4;
yading@11 779 count = -count;
yading@11 780 while (count < 0) {
yading@11 781 dst0[count] = (src0[4 * count + 0] + src1[4 * count + 0]) >> 1;
yading@11 782 dst1[count] = (src0[4 * count + 2] + src1[4 * count + 2]) >> 1;
yading@11 783 count++;
yading@11 784 }
yading@11 785 }
yading@11 786
yading@11 787 static void extract_odd2_c(const uint8_t *src, uint8_t *dst0, uint8_t *dst1,
yading@11 788 int count)
yading@11 789 {
yading@11 790 dst0 += count;
yading@11 791 dst1 += count;
yading@11 792 src += count * 4;
yading@11 793 count = -count;
yading@11 794 src++;
yading@11 795 while (count < 0) {
yading@11 796 dst0[count] = src[4 * count + 0];
yading@11 797 dst1[count] = src[4 * count + 2];
yading@11 798 count++;
yading@11 799 }
yading@11 800 }
yading@11 801
yading@11 802 static void extract_odd2avg_c(const uint8_t *src0, const uint8_t *src1,
yading@11 803 uint8_t *dst0, uint8_t *dst1, int count)
yading@11 804 {
yading@11 805 dst0 += count;
yading@11 806 dst1 += count;
yading@11 807 src0 += count * 4;
yading@11 808 src1 += count * 4;
yading@11 809 count = -count;
yading@11 810 src0++;
yading@11 811 src1++;
yading@11 812 while (count < 0) {
yading@11 813 dst0[count] = (src0[4 * count + 0] + src1[4 * count + 0]) >> 1;
yading@11 814 dst1[count] = (src0[4 * count + 2] + src1[4 * count + 2]) >> 1;
yading@11 815 count++;
yading@11 816 }
yading@11 817 }
yading@11 818
yading@11 819 static void yuyvtoyuv420_c(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
yading@11 820 const uint8_t *src, int width, int height,
yading@11 821 int lumStride, int chromStride, int srcStride)
yading@11 822 {
yading@11 823 int y;
yading@11 824 const int chromWidth = -((-width) >> 1);
yading@11 825
yading@11 826 for (y = 0; y < height; y++) {
yading@11 827 extract_even_c(src, ydst, width);
yading@11 828 if (y & 1) {
yading@11 829 extract_odd2avg_c(src - srcStride, src, udst, vdst, chromWidth);
yading@11 830 udst += chromStride;
yading@11 831 vdst += chromStride;
yading@11 832 }
yading@11 833
yading@11 834 src += srcStride;
yading@11 835 ydst += lumStride;
yading@11 836 }
yading@11 837 }
yading@11 838
yading@11 839 static void yuyvtoyuv422_c(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
yading@11 840 const uint8_t *src, int width, int height,
yading@11 841 int lumStride, int chromStride, int srcStride)
yading@11 842 {
yading@11 843 int y;
yading@11 844 const int chromWidth = -((-width) >> 1);
yading@11 845
yading@11 846 for (y = 0; y < height; y++) {
yading@11 847 extract_even_c(src, ydst, width);
yading@11 848 extract_odd2_c(src, udst, vdst, chromWidth);
yading@11 849
yading@11 850 src += srcStride;
yading@11 851 ydst += lumStride;
yading@11 852 udst += chromStride;
yading@11 853 vdst += chromStride;
yading@11 854 }
yading@11 855 }
yading@11 856
yading@11 857 static void uyvytoyuv420_c(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
yading@11 858 const uint8_t *src, int width, int height,
yading@11 859 int lumStride, int chromStride, int srcStride)
yading@11 860 {
yading@11 861 int y;
yading@11 862 const int chromWidth = -((-width) >> 1);
yading@11 863
yading@11 864 for (y = 0; y < height; y++) {
yading@11 865 extract_even_c(src + 1, ydst, width);
yading@11 866 if (y & 1) {
yading@11 867 extract_even2avg_c(src - srcStride, src, udst, vdst, chromWidth);
yading@11 868 udst += chromStride;
yading@11 869 vdst += chromStride;
yading@11 870 }
yading@11 871
yading@11 872 src += srcStride;
yading@11 873 ydst += lumStride;
yading@11 874 }
yading@11 875 }
yading@11 876
yading@11 877 static void uyvytoyuv422_c(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
yading@11 878 const uint8_t *src, int width, int height,
yading@11 879 int lumStride, int chromStride, int srcStride)
yading@11 880 {
yading@11 881 int y;
yading@11 882 const int chromWidth = -((-width) >> 1);
yading@11 883
yading@11 884 for (y = 0; y < height; y++) {
yading@11 885 extract_even_c(src + 1, ydst, width);
yading@11 886 extract_even2_c(src, udst, vdst, chromWidth);
yading@11 887
yading@11 888 src += srcStride;
yading@11 889 ydst += lumStride;
yading@11 890 udst += chromStride;
yading@11 891 vdst += chromStride;
yading@11 892 }
yading@11 893 }
yading@11 894
yading@11 895 static inline void rgb2rgb_init_c(void)
yading@11 896 {
yading@11 897 rgb15to16 = rgb15to16_c;
yading@11 898 rgb15tobgr24 = rgb15tobgr24_c;
yading@11 899 rgb15to32 = rgb15to32_c;
yading@11 900 rgb16tobgr24 = rgb16tobgr24_c;
yading@11 901 rgb16to32 = rgb16to32_c;
yading@11 902 rgb16to15 = rgb16to15_c;
yading@11 903 rgb24tobgr16 = rgb24tobgr16_c;
yading@11 904 rgb24tobgr15 = rgb24tobgr15_c;
yading@11 905 rgb24tobgr32 = rgb24tobgr32_c;
yading@11 906 rgb32to16 = rgb32to16_c;
yading@11 907 rgb32to15 = rgb32to15_c;
yading@11 908 rgb32tobgr24 = rgb32tobgr24_c;
yading@11 909 rgb24to15 = rgb24to15_c;
yading@11 910 rgb24to16 = rgb24to16_c;
yading@11 911 rgb24tobgr24 = rgb24tobgr24_c;
yading@11 912 shuffle_bytes_2103 = shuffle_bytes_2103_c;
yading@11 913 rgb32tobgr16 = rgb32tobgr16_c;
yading@11 914 rgb32tobgr15 = rgb32tobgr15_c;
yading@11 915 yv12toyuy2 = yv12toyuy2_c;
yading@11 916 yv12touyvy = yv12touyvy_c;
yading@11 917 yuv422ptoyuy2 = yuv422ptoyuy2_c;
yading@11 918 yuv422ptouyvy = yuv422ptouyvy_c;
yading@11 919 yuy2toyv12 = yuy2toyv12_c;
yading@11 920 planar2x = planar2x_c;
yading@11 921 ff_rgb24toyv12 = ff_rgb24toyv12_c;
yading@11 922 interleaveBytes = interleaveBytes_c;
yading@11 923 vu9_to_vu12 = vu9_to_vu12_c;
yading@11 924 yvu9_to_yuy2 = yvu9_to_yuy2_c;
yading@11 925
yading@11 926 uyvytoyuv420 = uyvytoyuv420_c;
yading@11 927 uyvytoyuv422 = uyvytoyuv422_c;
yading@11 928 yuyvtoyuv420 = yuyvtoyuv420_c;
yading@11 929 yuyvtoyuv422 = yuyvtoyuv422_c;
yading@11 930 }