00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <fvutils/color/yuv.h>
00026 #include <fvutils/color/colorspaces.h>
00027 #include <cstring>
00028
00029 void
00030 iyu1_to_yuy2(const unsigned char *src, unsigned char *dest, unsigned int width, unsigned int height)
00031 {
00032 unsigned int i=0, j=0;
00033 register int y0, y1, y2, y3, u, v;
00034 while (i < width * height * 3 / 2) {
00035 u = src[i++];
00036 y0 = src[i++];
00037 y1 = src[i++];
00038 v = src[i++];
00039 y2 = src[i++];
00040 y3 = src[i++];
00041
00042 dest[j++] = y0;
00043 dest[j++] = u;
00044 dest[j++] = y1;
00045 dest[j++] = v;
00046
00047 dest[j++] = y2;
00048 dest[j++] = u;
00049 dest[j++] = y3;
00050 dest[j++] = v;
00051 }
00052 }
00053
00054
00055
00056
00057
00058 void
00059 gray8_to_yuy2(const unsigned char *src, unsigned char *dest, unsigned int width, unsigned int height)
00060 {
00061 register unsigned int i=0, j=0;
00062 while (i < width * height) {
00063 dest[j++] = src[i++];
00064 dest[j++] = 128;
00065 dest[j++] = src[i++];
00066 dest[j++] = 128;
00067 }
00068 }
00069
00070
00071
00072
00073 void
00074 gray8_to_yuv422planar_plainc(const unsigned char *src, unsigned char *dst,
00075 unsigned int width, unsigned int height)
00076 {
00077
00078 memcpy(dst, src, width * height);
00079
00080 memset(YUV422_PLANAR_U_PLANE(dst, width, height), 128, width * height);
00081 }
00082
00083
00084
00085
00086
00087 void
00088 yuv422planar_copy_uv(const unsigned char *src, unsigned char *dst,
00089 unsigned int width, unsigned int height,
00090 unsigned int x, unsigned int y,
00091 unsigned int copy_width, unsigned int copy_height)
00092 {
00093
00094 register const unsigned char *sup = YUV422_PLANAR_U_PLANE(src, width, height) + (x / 2);
00095 register const unsigned char *svp = YUV422_PLANAR_V_PLANE(src, width, height) + (x / 2);
00096
00097 register unsigned char *dup = YUV422_PLANAR_U_PLANE(dst, width, height) + (x / 2);
00098 register unsigned char *dvp = YUV422_PLANAR_V_PLANE(dst, width, height) + (x / 2);
00099
00100 register unsigned int w;
00101 register unsigned int h;
00102
00103 unsigned const char *lsup = sup, *lsvp = svp, *ldup = dup, *ldvp = dvp;
00104
00105 for (h = 0; h < copy_height; ++h) {
00106 for ( w = 0; w < copy_width; w += 2 ) {
00107 *dup++ = *sup++;
00108 *dvp++ = *svp++;
00109 }
00110 lsup += width / 2;
00111 lsvp += width / 2;
00112 ldup += width / 2;
00113 ldvp += width / 2;
00114 }
00115 }
00116
00117
00118 void
00119 yuv422planar_to_yuv422packed(const unsigned char *planar, unsigned char *packed,
00120 unsigned int width, unsigned int height)
00121 {
00122 register const unsigned char *y, *u, *v;
00123 register unsigned int i;
00124
00125 y = planar;
00126 u = planar + (width * height);
00127 v = u + (width * height / 2);
00128
00129 for (i = 0; i < (width * height / 2); ++i) {
00130 *packed++ = *u++;
00131 *packed++ = *y++;
00132 *packed++ = *v++;
00133 *packed++ = *y++;
00134 }
00135 }
00136
00137 void
00138 yuv422planar_quarter_to_yuv422packed(const unsigned char *planar, unsigned char *packed,
00139 const unsigned int width,
00140 const unsigned int height)
00141 {
00142 volatile const unsigned char *y, *u, *v;
00143 register unsigned int w, h;
00144
00145 const unsigned int w_h_4 = (width * height) / 4;
00146 const unsigned int w_h_8 = (width * height) / 8;
00147 const unsigned int w_t_2 = width * 2;
00148 const unsigned int w_b_2 = width / 2;
00149 const unsigned int w_b_4 = width / 4;
00150
00151
00152 for (h = 0; h < height / 2; ++h) {
00153 y = planar + (h * w_b_2);
00154 u = planar + w_h_4 + (h * w_b_4);
00155 v = planar + w_h_4 + w_h_8 + (h * w_b_4);
00156
00157 for (w = 0; w < w_b_4; ++w) {
00158 packed[h * w_t_2 + w * 4 ] = *u++;
00159 packed[h * w_t_2 + w * 4 + 1] = *y++;
00160 packed[h * w_t_2 + w * 4 + 2] = *v++;
00161 packed[h * w_t_2 + w * 4 + 3] = *y++;
00162 }
00163 }
00164 }
00165
00166 void
00167 yuv422packed_to_yuv422planar(const unsigned char *packed, unsigned char *planar,
00168 unsigned int width, unsigned int height)
00169 {
00170 register volatile unsigned char *y, *u, *v;
00171 register int i, iy, iiy;
00172
00173 unsigned int wh = (width * height);
00174 int wh2 = wh >> 1;
00175 y = planar;
00176 u = planar + wh;
00177 v = u + wh2;
00178
00179 #ifdef _OPENMP
00180 #pragma omp parallel for firstprivate(wh2) private(i, iy, iiy) shared(y, u, v, packed) schedule(static)
00181 #endif
00182 for (i = 0; i < wh2; ++i) {
00183 iy = i << 1;
00184 iiy = iy << 1;
00185 u[i] = packed[iiy];
00186 y[iy] = packed[iiy + 1];
00187 v[i] = packed[iiy + 2];
00188 y[iy+1] = packed[iiy + 3];
00189 }
00190 }
00191
00192
00193 void
00194 yuy2_to_yuv422planar(const unsigned char *packed, unsigned char *planar,
00195 unsigned int width, unsigned int height)
00196 {
00197 register volatile unsigned char *y, *u, *v;
00198 register int i, iy, iiy;
00199
00200 unsigned int wh = (width * height);
00201 int wh2 = wh >> 1;
00202 y = planar;
00203 u = planar + wh;
00204 v = u + wh2;
00205
00206 #ifdef _OPENMP
00207 #pragma omp parallel for firstprivate(wh2) private(i, iy, iiy) shared(y, u, v, packed) schedule(static)
00208 #endif
00209 for (i = 0; i < wh2; ++i) {
00210 iy = i << 1;
00211 iiy = iy << 1;
00212 y[iy] = packed[iiy];
00213 u[i] = packed[iiy + 1];
00214 y[iy+1] = packed[iiy + 2];
00215 v[i] = packed[iiy + 3];
00216 }
00217 }
00218
00219
00220 void
00221 yvy2_to_yuv422planar(const unsigned char *packed, unsigned char *planar,
00222 unsigned int width, unsigned int height)
00223 {
00224 register volatile unsigned char *y, *u, *v;
00225 register int i, iy, iiy;
00226
00227 unsigned int wh = (width * height);
00228 int wh2 = wh >> 1;
00229 y = planar;
00230 u = planar + wh;
00231 v = u + wh2;
00232
00233 #ifdef _OPENMP
00234 #pragma omp parallel for firstprivate(wh2) private(i, iy, iiy) shared(y, u, v, packed) schedule(static)
00235 #endif
00236 for (i = 0; i < wh2; ++i) {
00237 iy = i << 1;
00238 iiy = iy << 1;
00239 y[iy] = packed[iiy];
00240 v[i] = packed[iiy + 1];
00241 y[iy+1] = packed[iiy + 2];
00242 u[i] = packed[iiy + 3];
00243 }
00244 }
00245
00246
00247 void
00248 yuy2_to_yuv422planar_quarter(const unsigned char *packed, unsigned char *planar,
00249 const unsigned int width, const unsigned int height)
00250 {
00251 register volatile unsigned char *y, *u, *v;
00252 register unsigned int h, w;
00253
00254 unsigned int wh = (width * height);
00255 y = planar;
00256 u = planar + (wh / 4);
00257 v = u + (wh / 8);
00258
00259 const unsigned int w_b_2 = width / 2;
00260 const unsigned int w_b_4 = width / 4;
00261 const unsigned int w_t_2 = width * 2;
00262 unsigned int packpix;
00263
00264 for (h = 0; h < height / 2; ++h) {
00265 for (w = 0; w < width; w += 4) {
00266 packpix = (h * w_t_2 + w) * 2;
00267 y[h * w_b_2 + w / 2 ] = (packed[packpix + 0] + packed[packpix + 2]) / 2;
00268 u[h * w_b_4 + w / 4 ] = (packed[packpix + 1] + packed[packpix + 5]) / 2;
00269 y[h * w_b_2 + w / 2 + 1] = (packed[packpix + 4] + packed[packpix + 6]) / 2;
00270 v[h * w_b_4 + w / 4 ] = (packed[packpix + 3] + packed[packpix + 7]) / 2;
00271 }
00272 }
00273 }
00274
00275
00276 void
00277 yuv444packed_to_yuv422planar(const unsigned char *yuv444, unsigned char *yuv422,
00278 unsigned int width, unsigned int height)
00279 {
00280 register volatile unsigned char *y, *u, *v;
00281 register int i, iy, iiy;
00282
00283 unsigned int wh = (width * height);
00284 int wh2 = wh >> 1;
00285 y = yuv422;
00286 u = yuv422 + wh;
00287 v = u + wh2;
00288
00289 #ifdef ___OPENMP
00290 #pragma omp parallel for firstprivate(wh2) private(i, iy, iiy) shared(y, u, v, yuv444) schedule(static)
00291 #endif
00292 for (i = 0; i < wh2; ++i) {
00293 iy = i << 1;
00294 iiy = i * 6;
00295 y[iy] = yuv444[iiy];
00296 y[iy+1] = yuv444[iiy + 3];
00297 u[i] = (yuv444[iiy + 1] + yuv444[iiy + 4]) >> 1;
00298 v[i] = (yuv444[iiy + 2] + yuv444[iiy + 5]) >> 1;
00299 }
00300 }
00301
00302
00303 void
00304 yuv444packed_to_yuv422packed(const unsigned char *yvu444, unsigned char *yuv422,
00305 unsigned int width, unsigned int height)
00306 {
00307 register int i, iiy;
00308
00309 unsigned int wh = (width * height);
00310 int wh2 = wh >> 1;
00311
00312 #ifdef ___OPENMP
00313 # pragma omp parallel for firstprivate(wh2) private(i, iiy) shared(yuv422, yvu444) schedule(static)
00314 #endif
00315 for (i = 0; i < wh2; i += 4) {
00316 iiy = i * 6;
00317 yuv422[i] = (yvu444[iiy + 1] + yvu444[iiy + 4]) >> 1;
00318 yuv422[i+1] = yvu444[iiy];
00319 yuv422[i+2] = (yvu444[iiy + 2] + yvu444[iiy + 5]) >> 1;
00320 yuv422[i+3] = yvu444[iiy + 3];
00321 }
00322 }
00323
00324
00325 void
00326 yvu444packed_to_yuv422planar(const unsigned char *yvu444, unsigned char *yuv422,
00327 unsigned int width, unsigned int height)
00328 {
00329 register volatile unsigned char *y, *u, *v;
00330 register int i, iy, iiy;
00331
00332 unsigned int wh = (width * height);
00333 int wh2 = wh >> 1;
00334 y = yuv422;
00335 u = yuv422 + wh;
00336 v = u + wh2;
00337
00338 #ifdef ___OPENMP
00339 # pragma omp parallel for firstprivate(wh2) private(i, iy, iiy) shared(y, u, v, yvu444) schedule(static)
00340 #endif
00341 for (i = 0; i < wh2; ++i) {
00342 iy = i << 1;
00343 iiy = i * 6;
00344 y[iy] = yvu444[iiy];
00345 y[iy+1] = yvu444[iiy + 3];
00346 u[i] = (yvu444[iiy + 2] + yvu444[iiy + 5]) >> 1;
00347 v[i] = (yvu444[iiy + 1] + yvu444[iiy + 4]) >> 1;
00348 }
00349 }
00350
00351
00352 void
00353 yvu444packed_to_yuv422packed(const unsigned char *yvu444, unsigned char *yuv422,
00354 unsigned int width, unsigned int height)
00355 {
00356 register int i, iiy;
00357
00358 unsigned int wh = (width * height);
00359 int wh2 = wh >> 1;
00360
00361 #ifdef ___OPENMP
00362 # pragma omp parallel for firstprivate(wh2) private(i, iiy) shared(yuv422, yvu444) schedule(static)
00363 #endif
00364 for (i = 0; i < wh2; i += 4) {
00365 iiy = i * 6;
00366 yuv422[i] = (yvu444[iiy + 2] + yvu444[iiy + 5]) >> 1;
00367 yuv422[i+1] = yvu444[iiy];
00368 yuv422[i+2] = (yvu444[iiy + 1] + yvu444[iiy + 4]) >> 1;
00369 yuv422[i+3] = yvu444[iiy + 3];
00370 }
00371 }
00372
00373
00374 void
00375 yuv422planar_erase_y_plane(unsigned char *yuv, unsigned int width, unsigned int height)
00376 {
00377 memset(yuv, 128, (width * height));
00378 }
00379
00380
00381 void
00382 yuv422planar_erase_u_plane(unsigned char *yuv, unsigned int width, unsigned int height)
00383 {
00384 memset(yuv + (width * height), 128, (width * height / 2));
00385 }
00386
00387
00388 void
00389 yuv422planar_erase_v_plane(unsigned char *yuv, unsigned int width, unsigned int height)
00390 {
00391 memset(yuv + (width * height * 3/2), 128, (width * height / 2));
00392 }
00393
00394
00395 void
00396 grayscale_yuv422packed(const unsigned char *src, unsigned char *dst,
00397 unsigned int width, unsigned int height)
00398 {
00399 unsigned int p = 0;
00400 unsigned int d = 0;
00401 while (p < colorspace_buffer_size(YUV422_PACKED, width, height)) {
00402 if ( (p % 2) == 0 ) {
00403
00404 } else {
00405 dst[d++] = src[p];
00406 }
00407 p += 1;
00408 }
00409 }
00410
00411
00412 void
00413 grayscale_yuv422planar(const unsigned char *src, unsigned char *dst,
00414 unsigned int width, unsigned int height)
00415 {
00416 memcpy(dst, src, width * height);
00417 memset(dst + width * height, 128, width * height);
00418 }
00419