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