00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027
00028
00029
00030
00031
00032
00033 #include "avcodec.h"
00034 #include "dsputil.h"
00035 #include "colorspace.h"
00036
00037 #if HAVE_MMX
00038 #include "x86/mmx.h"
00039 #include "x86/dsputil_mmx.h"
00040 #endif
00041
00042 #define xglue(x, y) x ## y
00043 #define glue(x, y) xglue(x, y)
00044
00045 #define FF_COLOR_RGB 0
00046 #define FF_COLOR_GRAY 1
00047 #define FF_COLOR_YUV 2
00048 #define FF_COLOR_YUV_JPEG 3
00050 #define FF_PIXEL_PLANAR 0
00051 #define FF_PIXEL_PACKED 1
00052 #define FF_PIXEL_PALETTE 2
00054 typedef struct PixFmtInfo {
00055 const char *name;
00056 uint8_t nb_channels;
00057 uint8_t color_type;
00058 uint8_t pixel_type;
00059 uint8_t is_alpha : 1;
00060 uint8_t is_hwaccel : 1;
00061 uint8_t x_chroma_shift;
00062 uint8_t y_chroma_shift;
00063 uint8_t depth;
00064 } PixFmtInfo;
00065
00066
00067 static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
00068
00069 [PIX_FMT_YUV420P] = {
00070 .name = "yuv420p",
00071 .nb_channels = 3,
00072 .color_type = FF_COLOR_YUV,
00073 .pixel_type = FF_PIXEL_PLANAR,
00074 .depth = 8,
00075 .x_chroma_shift = 1, .y_chroma_shift = 1,
00076 },
00077 [PIX_FMT_YUV422P] = {
00078 .name = "yuv422p",
00079 .nb_channels = 3,
00080 .color_type = FF_COLOR_YUV,
00081 .pixel_type = FF_PIXEL_PLANAR,
00082 .depth = 8,
00083 .x_chroma_shift = 1, .y_chroma_shift = 0,
00084 },
00085 [PIX_FMT_YUV444P] = {
00086 .name = "yuv444p",
00087 .nb_channels = 3,
00088 .color_type = FF_COLOR_YUV,
00089 .pixel_type = FF_PIXEL_PLANAR,
00090 .depth = 8,
00091 .x_chroma_shift = 0, .y_chroma_shift = 0,
00092 },
00093 [PIX_FMT_YUYV422] = {
00094 .name = "yuyv422",
00095 .nb_channels = 1,
00096 .color_type = FF_COLOR_YUV,
00097 .pixel_type = FF_PIXEL_PACKED,
00098 .depth = 8,
00099 .x_chroma_shift = 1, .y_chroma_shift = 0,
00100 },
00101 [PIX_FMT_UYVY422] = {
00102 .name = "uyvy422",
00103 .nb_channels = 1,
00104 .color_type = FF_COLOR_YUV,
00105 .pixel_type = FF_PIXEL_PACKED,
00106 .depth = 8,
00107 .x_chroma_shift = 1, .y_chroma_shift = 0,
00108 },
00109 [PIX_FMT_YUV410P] = {
00110 .name = "yuv410p",
00111 .nb_channels = 3,
00112 .color_type = FF_COLOR_YUV,
00113 .pixel_type = FF_PIXEL_PLANAR,
00114 .depth = 8,
00115 .x_chroma_shift = 2, .y_chroma_shift = 2,
00116 },
00117 [PIX_FMT_YUV411P] = {
00118 .name = "yuv411p",
00119 .nb_channels = 3,
00120 .color_type = FF_COLOR_YUV,
00121 .pixel_type = FF_PIXEL_PLANAR,
00122 .depth = 8,
00123 .x_chroma_shift = 2, .y_chroma_shift = 0,
00124 },
00125 [PIX_FMT_YUV440P] = {
00126 .name = "yuv440p",
00127 .nb_channels = 3,
00128 .color_type = FF_COLOR_YUV,
00129 .pixel_type = FF_PIXEL_PLANAR,
00130 .depth = 8,
00131 .x_chroma_shift = 0, .y_chroma_shift = 1,
00132 },
00133
00134
00135 [PIX_FMT_YUVA420P] = {
00136 .name = "yuva420p",
00137 .nb_channels = 4,
00138 .color_type = FF_COLOR_YUV,
00139 .pixel_type = FF_PIXEL_PLANAR,
00140 .depth = 8,
00141 .x_chroma_shift = 1, .y_chroma_shift = 1,
00142 },
00143
00144
00145 [PIX_FMT_YUVJ420P] = {
00146 .name = "yuvj420p",
00147 .nb_channels = 3,
00148 .color_type = FF_COLOR_YUV_JPEG,
00149 .pixel_type = FF_PIXEL_PLANAR,
00150 .depth = 8,
00151 .x_chroma_shift = 1, .y_chroma_shift = 1,
00152 },
00153 [PIX_FMT_YUVJ422P] = {
00154 .name = "yuvj422p",
00155 .nb_channels = 3,
00156 .color_type = FF_COLOR_YUV_JPEG,
00157 .pixel_type = FF_PIXEL_PLANAR,
00158 .depth = 8,
00159 .x_chroma_shift = 1, .y_chroma_shift = 0,
00160 },
00161 [PIX_FMT_YUVJ444P] = {
00162 .name = "yuvj444p",
00163 .nb_channels = 3,
00164 .color_type = FF_COLOR_YUV_JPEG,
00165 .pixel_type = FF_PIXEL_PLANAR,
00166 .depth = 8,
00167 .x_chroma_shift = 0, .y_chroma_shift = 0,
00168 },
00169 [PIX_FMT_YUVJ440P] = {
00170 .name = "yuvj440p",
00171 .nb_channels = 3,
00172 .color_type = FF_COLOR_YUV_JPEG,
00173 .pixel_type = FF_PIXEL_PLANAR,
00174 .depth = 8,
00175 .x_chroma_shift = 0, .y_chroma_shift = 1,
00176 },
00177
00178
00179 [PIX_FMT_RGB24] = {
00180 .name = "rgb24",
00181 .nb_channels = 3,
00182 .color_type = FF_COLOR_RGB,
00183 .pixel_type = FF_PIXEL_PACKED,
00184 .depth = 8,
00185 .x_chroma_shift = 0, .y_chroma_shift = 0,
00186 },
00187 [PIX_FMT_BGR24] = {
00188 .name = "bgr24",
00189 .nb_channels = 3,
00190 .color_type = FF_COLOR_RGB,
00191 .pixel_type = FF_PIXEL_PACKED,
00192 .depth = 8,
00193 .x_chroma_shift = 0, .y_chroma_shift = 0,
00194 },
00195 [PIX_FMT_RGB32] = {
00196 .name = "rgb32",
00197 .nb_channels = 4, .is_alpha = 1,
00198 .color_type = FF_COLOR_RGB,
00199 .pixel_type = FF_PIXEL_PACKED,
00200 .depth = 8,
00201 .x_chroma_shift = 0, .y_chroma_shift = 0,
00202 },
00203 [PIX_FMT_RGB48BE] = {
00204 .name = "rgb48be",
00205 .nb_channels = 3,
00206 .color_type = FF_COLOR_RGB,
00207 .pixel_type = FF_PIXEL_PACKED,
00208 .depth = 16,
00209 .x_chroma_shift = 0, .y_chroma_shift = 0,
00210 },
00211 [PIX_FMT_RGB48LE] = {
00212 .name = "rgb48le",
00213 .nb_channels = 3,
00214 .color_type = FF_COLOR_RGB,
00215 .pixel_type = FF_PIXEL_PACKED,
00216 .depth = 16,
00217 .x_chroma_shift = 0, .y_chroma_shift = 0,
00218 },
00219 [PIX_FMT_RGB565] = {
00220 .name = "rgb565",
00221 .nb_channels = 3,
00222 .color_type = FF_COLOR_RGB,
00223 .pixel_type = FF_PIXEL_PACKED,
00224 .depth = 5,
00225 .x_chroma_shift = 0, .y_chroma_shift = 0,
00226 },
00227 [PIX_FMT_RGB555] = {
00228 .name = "rgb555",
00229 .nb_channels = 3,
00230 .color_type = FF_COLOR_RGB,
00231 .pixel_type = FF_PIXEL_PACKED,
00232 .depth = 5,
00233 .x_chroma_shift = 0, .y_chroma_shift = 0,
00234 },
00235
00236
00237 [PIX_FMT_GRAY16BE] = {
00238 .name = "gray16be",
00239 .nb_channels = 1,
00240 .color_type = FF_COLOR_GRAY,
00241 .pixel_type = FF_PIXEL_PLANAR,
00242 .depth = 16,
00243 },
00244 [PIX_FMT_GRAY16LE] = {
00245 .name = "gray16le",
00246 .nb_channels = 1,
00247 .color_type = FF_COLOR_GRAY,
00248 .pixel_type = FF_PIXEL_PLANAR,
00249 .depth = 16,
00250 },
00251 [PIX_FMT_GRAY8] = {
00252 .name = "gray",
00253 .nb_channels = 1,
00254 .color_type = FF_COLOR_GRAY,
00255 .pixel_type = FF_PIXEL_PLANAR,
00256 .depth = 8,
00257 },
00258 [PIX_FMT_MONOWHITE] = {
00259 .name = "monow",
00260 .nb_channels = 1,
00261 .color_type = FF_COLOR_GRAY,
00262 .pixel_type = FF_PIXEL_PLANAR,
00263 .depth = 1,
00264 },
00265 [PIX_FMT_MONOBLACK] = {
00266 .name = "monob",
00267 .nb_channels = 1,
00268 .color_type = FF_COLOR_GRAY,
00269 .pixel_type = FF_PIXEL_PLANAR,
00270 .depth = 1,
00271 },
00272
00273
00274 [PIX_FMT_PAL8] = {
00275 .name = "pal8",
00276 .nb_channels = 4, .is_alpha = 1,
00277 .color_type = FF_COLOR_RGB,
00278 .pixel_type = FF_PIXEL_PALETTE,
00279 .depth = 8,
00280 },
00281 [PIX_FMT_XVMC_MPEG2_MC] = {
00282 .name = "xvmcmc",
00283 .is_hwaccel = 1,
00284 },
00285 [PIX_FMT_XVMC_MPEG2_IDCT] = {
00286 .name = "xvmcidct",
00287 .is_hwaccel = 1,
00288 },
00289 [PIX_FMT_VDPAU_MPEG1] = {
00290 .name = "vdpau_mpeg1",
00291 .is_hwaccel = 1,
00292 },
00293 [PIX_FMT_VDPAU_MPEG2] = {
00294 .name = "vdpau_mpeg2",
00295 .is_hwaccel = 1,
00296 },
00297 [PIX_FMT_VDPAU_H264] = {
00298 .name = "vdpau_h264",
00299 .is_hwaccel = 1,
00300 },
00301 [PIX_FMT_VDPAU_WMV3] = {
00302 .name = "vdpau_wmv3",
00303 .is_hwaccel = 1,
00304 },
00305 [PIX_FMT_VDPAU_VC1] = {
00306 .name = "vdpau_vc1",
00307 .is_hwaccel = 1,
00308 },
00309 [PIX_FMT_UYYVYY411] = {
00310 .name = "uyyvyy411",
00311 .nb_channels = 1,
00312 .color_type = FF_COLOR_YUV,
00313 .pixel_type = FF_PIXEL_PACKED,
00314 .depth = 8,
00315 .x_chroma_shift = 2, .y_chroma_shift = 0,
00316 },
00317 [PIX_FMT_BGR32] = {
00318 .name = "bgr32",
00319 .nb_channels = 4, .is_alpha = 1,
00320 .color_type = FF_COLOR_RGB,
00321 .pixel_type = FF_PIXEL_PACKED,
00322 .depth = 8,
00323 .x_chroma_shift = 0, .y_chroma_shift = 0,
00324 },
00325 [PIX_FMT_BGR565] = {
00326 .name = "bgr565",
00327 .nb_channels = 3,
00328 .color_type = FF_COLOR_RGB,
00329 .pixel_type = FF_PIXEL_PACKED,
00330 .depth = 5,
00331 .x_chroma_shift = 0, .y_chroma_shift = 0,
00332 },
00333 [PIX_FMT_BGR555] = {
00334 .name = "bgr555",
00335 .nb_channels = 3,
00336 .color_type = FF_COLOR_RGB,
00337 .pixel_type = FF_PIXEL_PACKED,
00338 .depth = 5,
00339 .x_chroma_shift = 0, .y_chroma_shift = 0,
00340 },
00341 [PIX_FMT_RGB8] = {
00342 .name = "rgb8",
00343 .nb_channels = 1,
00344 .color_type = FF_COLOR_RGB,
00345 .pixel_type = FF_PIXEL_PACKED,
00346 .depth = 8,
00347 .x_chroma_shift = 0, .y_chroma_shift = 0,
00348 },
00349 [PIX_FMT_RGB4] = {
00350 .name = "rgb4",
00351 .nb_channels = 1,
00352 .color_type = FF_COLOR_RGB,
00353 .pixel_type = FF_PIXEL_PACKED,
00354 .depth = 4,
00355 .x_chroma_shift = 0, .y_chroma_shift = 0,
00356 },
00357 [PIX_FMT_RGB4_BYTE] = {
00358 .name = "rgb4_byte",
00359 .nb_channels = 1,
00360 .color_type = FF_COLOR_RGB,
00361 .pixel_type = FF_PIXEL_PACKED,
00362 .depth = 8,
00363 .x_chroma_shift = 0, .y_chroma_shift = 0,
00364 },
00365 [PIX_FMT_BGR8] = {
00366 .name = "bgr8",
00367 .nb_channels = 1,
00368 .color_type = FF_COLOR_RGB,
00369 .pixel_type = FF_PIXEL_PACKED,
00370 .depth = 8,
00371 .x_chroma_shift = 0, .y_chroma_shift = 0,
00372 },
00373 [PIX_FMT_BGR4] = {
00374 .name = "bgr4",
00375 .nb_channels = 1,
00376 .color_type = FF_COLOR_RGB,
00377 .pixel_type = FF_PIXEL_PACKED,
00378 .depth = 4,
00379 .x_chroma_shift = 0, .y_chroma_shift = 0,
00380 },
00381 [PIX_FMT_BGR4_BYTE] = {
00382 .name = "bgr4_byte",
00383 .nb_channels = 1,
00384 .color_type = FF_COLOR_RGB,
00385 .pixel_type = FF_PIXEL_PACKED,
00386 .depth = 8,
00387 .x_chroma_shift = 0, .y_chroma_shift = 0,
00388 },
00389 [PIX_FMT_NV12] = {
00390 .name = "nv12",
00391 .nb_channels = 2,
00392 .color_type = FF_COLOR_YUV,
00393 .pixel_type = FF_PIXEL_PLANAR,
00394 .depth = 8,
00395 .x_chroma_shift = 1, .y_chroma_shift = 1,
00396 },
00397 [PIX_FMT_NV21] = {
00398 .name = "nv12",
00399 .nb_channels = 2,
00400 .color_type = FF_COLOR_YUV,
00401 .pixel_type = FF_PIXEL_PLANAR,
00402 .depth = 8,
00403 .x_chroma_shift = 1, .y_chroma_shift = 1,
00404 },
00405
00406 [PIX_FMT_BGR32_1] = {
00407 .name = "bgr32_1",
00408 .nb_channels = 4, .is_alpha = 1,
00409 .color_type = FF_COLOR_RGB,
00410 .pixel_type = FF_PIXEL_PACKED,
00411 .depth = 8,
00412 .x_chroma_shift = 0, .y_chroma_shift = 0,
00413 },
00414 [PIX_FMT_RGB32_1] = {
00415 .name = "rgb32_1",
00416 .nb_channels = 4, .is_alpha = 1,
00417 .color_type = FF_COLOR_RGB,
00418 .pixel_type = FF_PIXEL_PACKED,
00419 .depth = 8,
00420 .x_chroma_shift = 0, .y_chroma_shift = 0,
00421 },
00422
00423
00424 [PIX_FMT_VAAPI_MOCO] = {
00425 .name = "vaapi_moco",
00426 .is_hwaccel = 1,
00427 },
00428 [PIX_FMT_VAAPI_IDCT] = {
00429 .name = "vaapi_idct",
00430 .is_hwaccel = 1,
00431 },
00432 [PIX_FMT_VAAPI_VLD] = {
00433 .name = "vaapi_vld",
00434 .is_hwaccel = 1,
00435 },
00436 };
00437
00438 void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift)
00439 {
00440 *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
00441 *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
00442 }
00443
00444 const char *avcodec_get_pix_fmt_name(int pix_fmt)
00445 {
00446 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
00447 return NULL;
00448 else
00449 return pix_fmt_info[pix_fmt].name;
00450 }
00451
00452 enum PixelFormat avcodec_get_pix_fmt(const char* name)
00453 {
00454 int i;
00455
00456 for (i=0; i < PIX_FMT_NB; i++)
00457 if (!strcmp(pix_fmt_info[i].name, name))
00458 return i;
00459 return PIX_FMT_NONE;
00460 }
00461
00462 void avcodec_pix_fmt_string (char *buf, int buf_size, int pix_fmt)
00463 {
00464
00465 if (pix_fmt < 0)
00466 snprintf (buf, buf_size,
00467 "name " " nb_channels" " depth" " is_alpha"
00468 );
00469 else{
00470 PixFmtInfo info= pix_fmt_info[pix_fmt];
00471
00472 char is_alpha_char= info.is_alpha ? 'y' : 'n';
00473
00474 snprintf (buf, buf_size,
00475 "%-10s" " %1d " " %2d " " %c ",
00476 info.name,
00477 info.nb_channels,
00478 info.depth,
00479 is_alpha_char
00480 );
00481 }
00482 }
00483
00484 int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
00485 {
00486 return pix_fmt_info[pix_fmt].is_hwaccel;
00487 }
00488
00489 int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){
00490 int i;
00491
00492 for(i=0; i<256; i++){
00493 int r,g,b;
00494
00495 switch(pix_fmt) {
00496 case PIX_FMT_RGB8:
00497 r= (i>>5 )*36;
00498 g= ((i>>2)&7)*36;
00499 b= (i&3 )*85;
00500 break;
00501 case PIX_FMT_BGR8:
00502 b= (i>>6 )*85;
00503 g= ((i>>3)&7)*36;
00504 r= (i&7 )*36;
00505 break;
00506 case PIX_FMT_RGB4_BYTE:
00507 r= (i>>3 )*255;
00508 g= ((i>>1)&3)*85;
00509 b= (i&1 )*255;
00510 break;
00511 case PIX_FMT_BGR4_BYTE:
00512 b= (i>>3 )*255;
00513 g= ((i>>1)&3)*85;
00514 r= (i&1 )*255;
00515 break;
00516 case PIX_FMT_GRAY8:
00517 r=b=g= i;
00518 break;
00519 default:
00520 return -1;
00521 }
00522 pal[i] = b + (g<<8) + (r<<16);
00523 }
00524
00525 return 0;
00526 }
00527
00528 int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width)
00529 {
00530 int w2;
00531 const PixFmtInfo *pinfo;
00532
00533 memset(picture->linesize, 0, sizeof(picture->linesize));
00534
00535 pinfo = &pix_fmt_info[pix_fmt];
00536 switch(pix_fmt) {
00537 case PIX_FMT_YUV420P:
00538 case PIX_FMT_YUV422P:
00539 case PIX_FMT_YUV444P:
00540 case PIX_FMT_YUV410P:
00541 case PIX_FMT_YUV411P:
00542 case PIX_FMT_YUV440P:
00543 case PIX_FMT_YUVJ420P:
00544 case PIX_FMT_YUVJ422P:
00545 case PIX_FMT_YUVJ444P:
00546 case PIX_FMT_YUVJ440P:
00547 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
00548 picture->linesize[0] = width;
00549 picture->linesize[1] = w2;
00550 picture->linesize[2] = w2;
00551 break;
00552 case PIX_FMT_YUVA420P:
00553 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
00554 picture->linesize[0] = width;
00555 picture->linesize[1] = w2;
00556 picture->linesize[2] = w2;
00557 picture->linesize[3] = width;
00558 break;
00559 case PIX_FMT_NV12:
00560 case PIX_FMT_NV21:
00561 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
00562 picture->linesize[0] = width;
00563 picture->linesize[1] = w2;
00564 break;
00565 case PIX_FMT_RGB24:
00566 case PIX_FMT_BGR24:
00567 picture->linesize[0] = width * 3;
00568 break;
00569 case PIX_FMT_RGB32:
00570 case PIX_FMT_BGR32:
00571 case PIX_FMT_RGB32_1:
00572 case PIX_FMT_BGR32_1:
00573 picture->linesize[0] = width * 4;
00574 break;
00575 case PIX_FMT_RGB48BE:
00576 case PIX_FMT_RGB48LE:
00577 picture->linesize[0] = width * 6;
00578 break;
00579 case PIX_FMT_GRAY16BE:
00580 case PIX_FMT_GRAY16LE:
00581 case PIX_FMT_BGR555:
00582 case PIX_FMT_BGR565:
00583 case PIX_FMT_RGB555:
00584 case PIX_FMT_RGB565:
00585 case PIX_FMT_YUYV422:
00586 picture->linesize[0] = width * 2;
00587 break;
00588 case PIX_FMT_UYVY422:
00589 picture->linesize[0] = width * 2;
00590 break;
00591 case PIX_FMT_UYYVYY411:
00592 picture->linesize[0] = width + width/2;
00593 break;
00594 case PIX_FMT_RGB4:
00595 case PIX_FMT_BGR4:
00596 picture->linesize[0] = width / 2;
00597 break;
00598 case PIX_FMT_MONOWHITE:
00599 case PIX_FMT_MONOBLACK:
00600 picture->linesize[0] = (width + 7) >> 3;
00601 break;
00602 case PIX_FMT_PAL8:
00603 case PIX_FMT_RGB8:
00604 case PIX_FMT_BGR8:
00605 case PIX_FMT_RGB4_BYTE:
00606 case PIX_FMT_BGR4_BYTE:
00607 case PIX_FMT_GRAY8:
00608 picture->linesize[0] = width;
00609 picture->linesize[1] = 4;
00610 break;
00611 default:
00612 return -1;
00613 }
00614 return 0;
00615 }
00616
00617 int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, int pix_fmt,
00618 int height)
00619 {
00620 int size, h2, size2;
00621 const PixFmtInfo *pinfo;
00622
00623 pinfo = &pix_fmt_info[pix_fmt];
00624 size = picture->linesize[0] * height;
00625 switch(pix_fmt) {
00626 case PIX_FMT_YUV420P:
00627 case PIX_FMT_YUV422P:
00628 case PIX_FMT_YUV444P:
00629 case PIX_FMT_YUV410P:
00630 case PIX_FMT_YUV411P:
00631 case PIX_FMT_YUV440P:
00632 case PIX_FMT_YUVJ420P:
00633 case PIX_FMT_YUVJ422P:
00634 case PIX_FMT_YUVJ444P:
00635 case PIX_FMT_YUVJ440P:
00636 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
00637 size2 = picture->linesize[1] * h2;
00638 picture->data[0] = ptr;
00639 picture->data[1] = picture->data[0] + size;
00640 picture->data[2] = picture->data[1] + size2;
00641 picture->data[3] = NULL;
00642 return size + 2 * size2;
00643 case PIX_FMT_YUVA420P:
00644 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
00645 size2 = picture->linesize[1] * h2;
00646 picture->data[0] = ptr;
00647 picture->data[1] = picture->data[0] + size;
00648 picture->data[2] = picture->data[1] + size2;
00649 picture->data[3] = picture->data[1] + size2 + size2;
00650 return 2 * size + 2 * size2;
00651 case PIX_FMT_NV12:
00652 case PIX_FMT_NV21:
00653 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
00654 size2 = picture->linesize[1] * h2 * 2;
00655 picture->data[0] = ptr;
00656 picture->data[1] = picture->data[0] + size;
00657 picture->data[2] = NULL;
00658 picture->data[3] = NULL;
00659 return size + 2 * size2;
00660 case PIX_FMT_RGB24:
00661 case PIX_FMT_BGR24:
00662 case PIX_FMT_RGB32:
00663 case PIX_FMT_BGR32:
00664 case PIX_FMT_RGB32_1:
00665 case PIX_FMT_BGR32_1:
00666 case PIX_FMT_RGB48BE:
00667 case PIX_FMT_RGB48LE:
00668 case PIX_FMT_GRAY16BE:
00669 case PIX_FMT_GRAY16LE:
00670 case PIX_FMT_BGR555:
00671 case PIX_FMT_BGR565:
00672 case PIX_FMT_RGB555:
00673 case PIX_FMT_RGB565:
00674 case PIX_FMT_YUYV422:
00675 case PIX_FMT_UYVY422:
00676 case PIX_FMT_UYYVYY411:
00677 case PIX_FMT_RGB4:
00678 case PIX_FMT_BGR4:
00679 case PIX_FMT_MONOWHITE:
00680 case PIX_FMT_MONOBLACK:
00681 picture->data[0] = ptr;
00682 picture->data[1] = NULL;
00683 picture->data[2] = NULL;
00684 picture->data[3] = NULL;
00685 return size;
00686 case PIX_FMT_PAL8:
00687 case PIX_FMT_RGB8:
00688 case PIX_FMT_BGR8:
00689 case PIX_FMT_RGB4_BYTE:
00690 case PIX_FMT_BGR4_BYTE:
00691 case PIX_FMT_GRAY8:
00692 size2 = (size + 3) & ~3;
00693 picture->data[0] = ptr;
00694 picture->data[1] = ptr + size2;
00695 picture->data[2] = NULL;
00696 picture->data[3] = NULL;
00697 return size2 + 256 * 4;
00698 default:
00699 picture->data[0] = NULL;
00700 picture->data[1] = NULL;
00701 picture->data[2] = NULL;
00702 picture->data[3] = NULL;
00703 return -1;
00704 }
00705 }
00706
00707 int avpicture_fill(AVPicture *picture, uint8_t *ptr,
00708 int pix_fmt, int width, int height)
00709 {
00710
00711 if(avcodec_check_dimensions(NULL, width, height))
00712 return -1;
00713
00714 if (ff_fill_linesize(picture, pix_fmt, width))
00715 return -1;
00716
00717 return ff_fill_pointer(picture, ptr, pix_fmt, height);
00718 }
00719
00720 int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
00721 unsigned char *dest, int dest_size)
00722 {
00723 const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
00724 int i, j, w, ow, h, oh, data_planes;
00725 const unsigned char* s;
00726 int size = avpicture_get_size(pix_fmt, width, height);
00727
00728 if (size > dest_size || size < 0)
00729 return -1;
00730
00731 if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
00732 if (pix_fmt == PIX_FMT_YUYV422 ||
00733 pix_fmt == PIX_FMT_UYVY422 ||
00734 pix_fmt == PIX_FMT_BGR565 ||
00735 pix_fmt == PIX_FMT_BGR555 ||
00736 pix_fmt == PIX_FMT_RGB565 ||
00737 pix_fmt == PIX_FMT_RGB555)
00738 w = width * 2;
00739 else if (pix_fmt == PIX_FMT_UYYVYY411)
00740 w = width + width/2;
00741 else if (pix_fmt == PIX_FMT_PAL8)
00742 w = width;
00743 else
00744 w = width * (pf->depth * pf->nb_channels / 8);
00745
00746 data_planes = 1;
00747 h = height;
00748 } else {
00749 data_planes = pf->nb_channels;
00750 w = (width*pf->depth + 7)/8;
00751 h = height;
00752 }
00753
00754 ow = w;
00755 oh = h;
00756
00757 for (i=0; i<data_planes; i++) {
00758 if (i == 1) {
00759 w = width >> pf->x_chroma_shift;
00760 h = height >> pf->y_chroma_shift;
00761 } else if (i == 3) {
00762 w = ow;
00763 h = oh;
00764 }
00765 s = src->data[i];
00766 for(j=0; j<h; j++) {
00767 memcpy(dest, s, w);
00768 dest += w;
00769 s += src->linesize[i];
00770 }
00771 }
00772
00773 if (pf->pixel_type == FF_PIXEL_PALETTE)
00774 memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
00775
00776 return size;
00777 }
00778
00779 int avpicture_get_size(int pix_fmt, int width, int height)
00780 {
00781 AVPicture dummy_pict;
00782 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
00783 }
00784
00785 int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
00786 int has_alpha)
00787 {
00788 const PixFmtInfo *pf, *ps;
00789 int loss;
00790
00791 ps = &pix_fmt_info[src_pix_fmt];
00792 pf = &pix_fmt_info[dst_pix_fmt];
00793
00794
00795 loss = 0;
00796 pf = &pix_fmt_info[dst_pix_fmt];
00797 if (pf->depth < ps->depth ||
00798 (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
00799 loss |= FF_LOSS_DEPTH;
00800 if (pf->x_chroma_shift > ps->x_chroma_shift ||
00801 pf->y_chroma_shift > ps->y_chroma_shift)
00802 loss |= FF_LOSS_RESOLUTION;
00803 switch(pf->color_type) {
00804 case FF_COLOR_RGB:
00805 if (ps->color_type != FF_COLOR_RGB &&
00806 ps->color_type != FF_COLOR_GRAY)
00807 loss |= FF_LOSS_COLORSPACE;
00808 break;
00809 case FF_COLOR_GRAY:
00810 if (ps->color_type != FF_COLOR_GRAY)
00811 loss |= FF_LOSS_COLORSPACE;
00812 break;
00813 case FF_COLOR_YUV:
00814 if (ps->color_type != FF_COLOR_YUV)
00815 loss |= FF_LOSS_COLORSPACE;
00816 break;
00817 case FF_COLOR_YUV_JPEG:
00818 if (ps->color_type != FF_COLOR_YUV_JPEG &&
00819 ps->color_type != FF_COLOR_YUV &&
00820 ps->color_type != FF_COLOR_GRAY)
00821 loss |= FF_LOSS_COLORSPACE;
00822 break;
00823 default:
00824
00825 if (ps->color_type != pf->color_type)
00826 loss |= FF_LOSS_COLORSPACE;
00827 break;
00828 }
00829 if (pf->color_type == FF_COLOR_GRAY &&
00830 ps->color_type != FF_COLOR_GRAY)
00831 loss |= FF_LOSS_CHROMA;
00832 if (!pf->is_alpha && (ps->is_alpha && has_alpha))
00833 loss |= FF_LOSS_ALPHA;
00834 if (pf->pixel_type == FF_PIXEL_PALETTE &&
00835 (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
00836 loss |= FF_LOSS_COLORQUANT;
00837 return loss;
00838 }
00839
00840 static int avg_bits_per_pixel(int pix_fmt)
00841 {
00842 int bits;
00843 const PixFmtInfo *pf;
00844
00845 pf = &pix_fmt_info[pix_fmt];
00846 switch(pf->pixel_type) {
00847 case FF_PIXEL_PACKED:
00848 switch(pix_fmt) {
00849 case PIX_FMT_YUYV422:
00850 case PIX_FMT_UYVY422:
00851 case PIX_FMT_RGB565:
00852 case PIX_FMT_RGB555:
00853 case PIX_FMT_BGR565:
00854 case PIX_FMT_BGR555:
00855 bits = 16;
00856 break;
00857 case PIX_FMT_UYYVYY411:
00858 bits = 12;
00859 break;
00860 default:
00861 bits = pf->depth * pf->nb_channels;
00862 break;
00863 }
00864 break;
00865 case FF_PIXEL_PLANAR:
00866 if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
00867 bits = pf->depth * pf->nb_channels;
00868 } else {
00869 bits = pf->depth + ((2 * pf->depth) >>
00870 (pf->x_chroma_shift + pf->y_chroma_shift));
00871 }
00872 break;
00873 case FF_PIXEL_PALETTE:
00874 bits = 8;
00875 break;
00876 default:
00877 bits = -1;
00878 break;
00879 }
00880 return bits;
00881 }
00882
00883 static int avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
00884 int src_pix_fmt,
00885 int has_alpha,
00886 int loss_mask)
00887 {
00888 int dist, i, loss, min_dist, dst_pix_fmt;
00889
00890
00891 dst_pix_fmt = -1;
00892 min_dist = 0x7fffffff;
00893
00894 for (i = 0; i < 64; i++) {
00895 if (pix_fmt_mask & (1ULL << i)) {
00896 loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
00897 if (loss == 0) {
00898 dist = avg_bits_per_pixel(i);
00899 if (dist < min_dist) {
00900 min_dist = dist;
00901 dst_pix_fmt = i;
00902 }
00903 }
00904 }
00905 }
00906 return dst_pix_fmt;
00907 }
00908
00909 int avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, int src_pix_fmt,
00910 int has_alpha, int *loss_ptr)
00911 {
00912 int dst_pix_fmt, loss_mask, i;
00913 static const int loss_mask_order[] = {
00914 ~0,
00915 ~FF_LOSS_ALPHA,
00916 ~FF_LOSS_RESOLUTION,
00917 ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
00918 ~FF_LOSS_COLORQUANT,
00919 ~FF_LOSS_DEPTH,
00920 0,
00921 };
00922
00923
00924 i = 0;
00925 for(;;) {
00926 loss_mask = loss_mask_order[i++];
00927 dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
00928 has_alpha, loss_mask);
00929 if (dst_pix_fmt >= 0)
00930 goto found;
00931 if (loss_mask == 0)
00932 break;
00933 }
00934 return -1;
00935 found:
00936 if (loss_ptr)
00937 *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
00938 return dst_pix_fmt;
00939 }
00940
00941 void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
00942 const uint8_t *src, int src_wrap,
00943 int width, int height)
00944 {
00945 if((!dst) || (!src))
00946 return;
00947 for(;height > 0; height--) {
00948 memcpy(dst, src, width);
00949 dst += dst_wrap;
00950 src += src_wrap;
00951 }
00952 }
00953
00954 int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
00955 {
00956 int bits;
00957 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
00958
00959 pf = &pix_fmt_info[pix_fmt];
00960 switch(pf->pixel_type) {
00961 case FF_PIXEL_PACKED:
00962 switch(pix_fmt) {
00963 case PIX_FMT_YUYV422:
00964 case PIX_FMT_UYVY422:
00965 case PIX_FMT_RGB565:
00966 case PIX_FMT_RGB555:
00967 case PIX_FMT_BGR565:
00968 case PIX_FMT_BGR555:
00969 bits = 16;
00970 break;
00971 case PIX_FMT_UYYVYY411:
00972 bits = 12;
00973 break;
00974 default:
00975 bits = pf->depth * pf->nb_channels;
00976 break;
00977 }
00978 return (width * bits + 7) >> 3;
00979 break;
00980 case FF_PIXEL_PLANAR:
00981 if (plane == 1 || plane == 2)
00982 width= -((-width)>>pf->x_chroma_shift);
00983
00984 return (width * pf->depth + 7) >> 3;
00985 break;
00986 case FF_PIXEL_PALETTE:
00987 if (plane == 0)
00988 return width;
00989 break;
00990 }
00991
00992 return -1;
00993 }
00994
00995 void av_picture_copy(AVPicture *dst, const AVPicture *src,
00996 int pix_fmt, int width, int height)
00997 {
00998 int i;
00999 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
01000
01001 pf = &pix_fmt_info[pix_fmt];
01002 switch(pf->pixel_type) {
01003 case FF_PIXEL_PACKED:
01004 case FF_PIXEL_PLANAR:
01005 for(i = 0; i < pf->nb_channels; i++) {
01006 int h;
01007 int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
01008 h = height;
01009 if (i == 1 || i == 2) {
01010 h= -((-height)>>pf->y_chroma_shift);
01011 }
01012 ff_img_copy_plane(dst->data[i], dst->linesize[i],
01013 src->data[i], src->linesize[i],
01014 bwidth, h);
01015 }
01016 break;
01017 case FF_PIXEL_PALETTE:
01018 ff_img_copy_plane(dst->data[0], dst->linesize[0],
01019 src->data[0], src->linesize[0],
01020 width, height);
01021
01022 ff_img_copy_plane(dst->data[1], dst->linesize[1],
01023 src->data[1], src->linesize[1],
01024 4, 256);
01025 break;
01026 }
01027 }
01028
01029
01030
01031 static void yuyv422_to_yuv420p(AVPicture *dst, const AVPicture *src,
01032 int width, int height)
01033 {
01034 const uint8_t *p, *p1;
01035 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
01036 int w;
01037
01038 p1 = src->data[0];
01039 lum1 = dst->data[0];
01040 cb1 = dst->data[1];
01041 cr1 = dst->data[2];
01042
01043 for(;height >= 1; height -= 2) {
01044 p = p1;
01045 lum = lum1;
01046 cb = cb1;
01047 cr = cr1;
01048 for(w = width; w >= 2; w -= 2) {
01049 lum[0] = p[0];
01050 cb[0] = p[1];
01051 lum[1] = p[2];
01052 cr[0] = p[3];
01053 p += 4;
01054 lum += 2;
01055 cb++;
01056 cr++;
01057 }
01058 if (w) {
01059 lum[0] = p[0];
01060 cb[0] = p[1];
01061 cr[0] = p[3];
01062 cb++;
01063 cr++;
01064 }
01065 p1 += src->linesize[0];
01066 lum1 += dst->linesize[0];
01067 if (height>1) {
01068 p = p1;
01069 lum = lum1;
01070 for(w = width; w >= 2; w -= 2) {
01071 lum[0] = p[0];
01072 lum[1] = p[2];
01073 p += 4;
01074 lum += 2;
01075 }
01076 if (w) {
01077 lum[0] = p[0];
01078 }
01079 p1 += src->linesize[0];
01080 lum1 += dst->linesize[0];
01081 }
01082 cb1 += dst->linesize[1];
01083 cr1 += dst->linesize[2];
01084 }
01085 }
01086
01087 static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src,
01088 int width, int height)
01089 {
01090 const uint8_t *p, *p1;
01091 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
01092 int w;
01093
01094 p1 = src->data[0];
01095
01096 lum1 = dst->data[0];
01097 cb1 = dst->data[1];
01098 cr1 = dst->data[2];
01099
01100 for(;height >= 1; height -= 2) {
01101 p = p1;
01102 lum = lum1;
01103 cb = cb1;
01104 cr = cr1;
01105 for(w = width; w >= 2; w -= 2) {
01106 lum[0] = p[1];
01107 cb[0] = p[0];
01108 lum[1] = p[3];
01109 cr[0] = p[2];
01110 p += 4;
01111 lum += 2;
01112 cb++;
01113 cr++;
01114 }
01115 if (w) {
01116 lum[0] = p[1];
01117 cb[0] = p[0];
01118 cr[0] = p[2];
01119 cb++;
01120 cr++;
01121 }
01122 p1 += src->linesize[0];
01123 lum1 += dst->linesize[0];
01124 if (height>1) {
01125 p = p1;
01126 lum = lum1;
01127 for(w = width; w >= 2; w -= 2) {
01128 lum[0] = p[1];
01129 lum[1] = p[3];
01130 p += 4;
01131 lum += 2;
01132 }
01133 if (w) {
01134 lum[0] = p[1];
01135 }
01136 p1 += src->linesize[0];
01137 lum1 += dst->linesize[0];
01138 }
01139 cb1 += dst->linesize[1];
01140 cr1 += dst->linesize[2];
01141 }
01142 }
01143
01144
01145 static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src,
01146 int width, int height)
01147 {
01148 const uint8_t *p, *p1;
01149 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
01150 int w;
01151
01152 p1 = src->data[0];
01153 lum1 = dst->data[0];
01154 cb1 = dst->data[1];
01155 cr1 = dst->data[2];
01156 for(;height > 0; height--) {
01157 p = p1;
01158 lum = lum1;
01159 cb = cb1;
01160 cr = cr1;
01161 for(w = width; w >= 2; w -= 2) {
01162 lum[0] = p[1];
01163 cb[0] = p[0];
01164 lum[1] = p[3];
01165 cr[0] = p[2];
01166 p += 4;
01167 lum += 2;
01168 cb++;
01169 cr++;
01170 }
01171 p1 += src->linesize[0];
01172 lum1 += dst->linesize[0];
01173 cb1 += dst->linesize[1];
01174 cr1 += dst->linesize[2];
01175 }
01176 }
01177
01178
01179 static void yuyv422_to_yuv422p(AVPicture *dst, const AVPicture *src,
01180 int width, int height)
01181 {
01182 const uint8_t *p, *p1;
01183 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
01184 int w;
01185
01186 p1 = src->data[0];
01187 lum1 = dst->data[0];
01188 cb1 = dst->data[1];
01189 cr1 = dst->data[2];
01190 for(;height > 0; height--) {
01191 p = p1;
01192 lum = lum1;
01193 cb = cb1;
01194 cr = cr1;
01195 for(w = width; w >= 2; w -= 2) {
01196 lum[0] = p[0];
01197 cb[0] = p[1];
01198 lum[1] = p[2];
01199 cr[0] = p[3];
01200 p += 4;
01201 lum += 2;
01202 cb++;
01203 cr++;
01204 }
01205 p1 += src->linesize[0];
01206 lum1 += dst->linesize[0];
01207 cb1 += dst->linesize[1];
01208 cr1 += dst->linesize[2];
01209 }
01210 }
01211
01212 static void yuv422p_to_yuyv422(AVPicture *dst, const AVPicture *src,
01213 int width, int height)
01214 {
01215 uint8_t *p, *p1;
01216 const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
01217 int w;
01218
01219 p1 = dst->data[0];
01220 lum1 = src->data[0];
01221 cb1 = src->data[1];
01222 cr1 = src->data[2];
01223 for(;height > 0; height--) {
01224 p = p1;
01225 lum = lum1;
01226 cb = cb1;
01227 cr = cr1;
01228 for(w = width; w >= 2; w -= 2) {
01229 p[0] = lum[0];
01230 p[1] = cb[0];
01231 p[2] = lum[1];
01232 p[3] = cr[0];
01233 p += 4;
01234 lum += 2;
01235 cb++;
01236 cr++;
01237 }
01238 p1 += dst->linesize[0];
01239 lum1 += src->linesize[0];
01240 cb1 += src->linesize[1];
01241 cr1 += src->linesize[2];
01242 }
01243 }
01244
01245 static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src,
01246 int width, int height)
01247 {
01248 uint8_t *p, *p1;
01249 const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
01250 int w;
01251
01252 p1 = dst->data[0];
01253 lum1 = src->data[0];
01254 cb1 = src->data[1];
01255 cr1 = src->data[2];
01256 for(;height > 0; height--) {
01257 p = p1;
01258 lum = lum1;
01259 cb = cb1;
01260 cr = cr1;
01261 for(w = width; w >= 2; w -= 2) {
01262 p[1] = lum[0];
01263 p[0] = cb[0];
01264 p[3] = lum[1];
01265 p[2] = cr[0];
01266 p += 4;
01267 lum += 2;
01268 cb++;
01269 cr++;
01270 }
01271 p1 += dst->linesize[0];
01272 lum1 += src->linesize[0];
01273 cb1 += src->linesize[1];
01274 cr1 += src->linesize[2];
01275 }
01276 }
01277
01278 static void uyyvyy411_to_yuv411p(AVPicture *dst, const AVPicture *src,
01279 int width, int height)
01280 {
01281 const uint8_t *p, *p1;
01282 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
01283 int w;
01284
01285 p1 = src->data[0];
01286 lum1 = dst->data[0];
01287 cb1 = dst->data[1];
01288 cr1 = dst->data[2];
01289 for(;height > 0; height--) {
01290 p = p1;
01291 lum = lum1;
01292 cb = cb1;
01293 cr = cr1;
01294 for(w = width; w >= 4; w -= 4) {
01295 cb[0] = p[0];
01296 lum[0] = p[1];
01297 lum[1] = p[2];
01298 cr[0] = p[3];
01299 lum[2] = p[4];
01300 lum[3] = p[5];
01301 p += 6;
01302 lum += 4;
01303 cb++;
01304 cr++;
01305 }
01306 p1 += src->linesize[0];
01307 lum1 += dst->linesize[0];
01308 cb1 += dst->linesize[1];
01309 cr1 += dst->linesize[2];
01310 }
01311 }
01312
01313
01314 static void yuv420p_to_yuyv422(AVPicture *dst, const AVPicture *src,
01315 int width, int height)
01316 {
01317 int w, h;
01318 uint8_t *line1, *line2, *linesrc = dst->data[0];
01319 uint8_t *lum1, *lum2, *lumsrc = src->data[0];
01320 uint8_t *cb1, *cb2 = src->data[1];
01321 uint8_t *cr1, *cr2 = src->data[2];
01322
01323 for(h = height / 2; h--;) {
01324 line1 = linesrc;
01325 line2 = linesrc + dst->linesize[0];
01326
01327 lum1 = lumsrc;
01328 lum2 = lumsrc + src->linesize[0];
01329
01330 cb1 = cb2;
01331 cr1 = cr2;
01332
01333 for(w = width / 2; w--;) {
01334 *line1++ = *lum1++; *line2++ = *lum2++;
01335 *line1++ = *line2++ = *cb1++;
01336 *line1++ = *lum1++; *line2++ = *lum2++;
01337 *line1++ = *line2++ = *cr1++;
01338 }
01339
01340 linesrc += dst->linesize[0] * 2;
01341 lumsrc += src->linesize[0] * 2;
01342 cb2 += src->linesize[1];
01343 cr2 += src->linesize[2];
01344 }
01345 }
01346
01347 static void yuv420p_to_uyvy422(AVPicture *dst, const AVPicture *src,
01348 int width, int height)
01349 {
01350 int w, h;
01351 uint8_t *line1, *line2, *linesrc = dst->data[0];
01352 uint8_t *lum1, *lum2, *lumsrc = src->data[0];
01353 uint8_t *cb1, *cb2 = src->data[1];
01354 uint8_t *cr1, *cr2 = src->data[2];
01355
01356 for(h = height / 2; h--;) {
01357 line1 = linesrc;
01358 line2 = linesrc + dst->linesize[0];
01359
01360 lum1 = lumsrc;
01361 lum2 = lumsrc + src->linesize[0];
01362
01363 cb1 = cb2;
01364 cr1 = cr2;
01365
01366 for(w = width / 2; w--;) {
01367 *line1++ = *line2++ = *cb1++;
01368 *line1++ = *lum1++; *line2++ = *lum2++;
01369 *line1++ = *line2++ = *cr1++;
01370 *line1++ = *lum1++; *line2++ = *lum2++;
01371 }
01372
01373 linesrc += dst->linesize[0] * 2;
01374 lumsrc += src->linesize[0] * 2;
01375 cb2 += src->linesize[1];
01376 cr2 += src->linesize[2];
01377 }
01378 }
01379
01380
01381 void ff_shrink22(uint8_t *dst, int dst_wrap,
01382 const uint8_t *src, int src_wrap,
01383 int width, int height)
01384 {
01385 int w;
01386 const uint8_t *s1, *s2;
01387 uint8_t *d;
01388
01389 for(;height > 0; height--) {
01390 s1 = src;
01391 s2 = s1 + src_wrap;
01392 d = dst;
01393 for(w = width;w >= 4; w-=4) {
01394 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
01395 d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
01396 d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
01397 d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
01398 s1 += 8;
01399 s2 += 8;
01400 d += 4;
01401 }
01402 for(;w > 0; w--) {
01403 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
01404 s1 += 2;
01405 s2 += 2;
01406 d++;
01407 }
01408 src += 2 * src_wrap;
01409 dst += dst_wrap;
01410 }
01411 }
01412
01413
01414 void ff_shrink44(uint8_t *dst, int dst_wrap,
01415 const uint8_t *src, int src_wrap,
01416 int width, int height)
01417 {
01418 int w;
01419 const uint8_t *s1, *s2, *s3, *s4;
01420 uint8_t *d;
01421
01422 for(;height > 0; height--) {
01423 s1 = src;
01424 s2 = s1 + src_wrap;
01425 s3 = s2 + src_wrap;
01426 s4 = s3 + src_wrap;
01427 d = dst;
01428 for(w = width;w > 0; w--) {
01429 d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
01430 s2[0] + s2[1] + s2[2] + s2[3] +
01431 s3[0] + s3[1] + s3[2] + s3[3] +
01432 s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
01433 s1 += 4;
01434 s2 += 4;
01435 s3 += 4;
01436 s4 += 4;
01437 d++;
01438 }
01439 src += 4 * src_wrap;
01440 dst += dst_wrap;
01441 }
01442 }
01443
01444
01445 void ff_shrink88(uint8_t *dst, int dst_wrap,
01446 const uint8_t *src, int src_wrap,
01447 int width, int height)
01448 {
01449 int w, i;
01450
01451 for(;height > 0; height--) {
01452 for(w = width;w > 0; w--) {
01453 int tmp=0;
01454 for(i=0; i<8; i++){
01455 tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
01456 src += src_wrap;
01457 }
01458 *(dst++) = (tmp + 32)>>6;
01459 src += 8 - 8*src_wrap;
01460 }
01461 src += 8*src_wrap - 8*width;
01462 dst += dst_wrap - width;
01463 }
01464 }
01465
01466
01467
01468 #define TRANSP_INDEX (6*6*6)
01469
01470
01471 static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
01472 {
01473 return (((r) / 47) % 6) * 6 * 6 + (((g) / 47) % 6) * 6 + (((b) / 47) % 6);
01474 }
01475
01476 static void build_rgb_palette(uint8_t *palette, int has_alpha)
01477 {
01478 uint32_t *pal;
01479 static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
01480 int i, r, g, b;
01481
01482 pal = (uint32_t *)palette;
01483 i = 0;
01484 for(r = 0; r < 6; r++) {
01485 for(g = 0; g < 6; g++) {
01486 for(b = 0; b < 6; b++) {
01487 pal[i++] = (0xff << 24) | (pal_value[r] << 16) |
01488 (pal_value[g] << 8) | pal_value[b];
01489 }
01490 }
01491 }
01492 if (has_alpha)
01493 pal[i++] = 0;
01494 while (i < 256)
01495 pal[i++] = 0xff000000;
01496 }
01497
01498
01499 static inline unsigned int bitcopy_n(unsigned int a, int n)
01500 {
01501 int mask;
01502 mask = (1 << n) - 1;
01503 return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
01504 }
01505
01506
01507
01508 #define RGB_NAME rgb555
01509
01510 #define RGB_IN(r, g, b, s)\
01511 {\
01512 unsigned int v = ((const uint16_t *)(s))[0];\
01513 r = bitcopy_n(v >> (10 - 3), 3);\
01514 g = bitcopy_n(v >> (5 - 3), 3);\
01515 b = bitcopy_n(v << 3, 3);\
01516 }
01517
01518
01519 #define RGB_OUT(d, r, g, b)\
01520 {\
01521 ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);\
01522 }
01523
01524 #define BPP 2
01525
01526 #include "imgconvert_template.c"
01527
01528
01529
01530 #define RGB_NAME rgb565
01531
01532 #define RGB_IN(r, g, b, s)\
01533 {\
01534 unsigned int v = ((const uint16_t *)(s))[0];\
01535 r = bitcopy_n(v >> (11 - 3), 3);\
01536 g = bitcopy_n(v >> (5 - 2), 2);\
01537 b = bitcopy_n(v << 3, 3);\
01538 }
01539
01540 #define RGB_OUT(d, r, g, b)\
01541 {\
01542 ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
01543 }
01544
01545 #define BPP 2
01546
01547 #include "imgconvert_template.c"
01548
01549
01550
01551 #define RGB_NAME bgr24
01552
01553 #define RGB_IN(r, g, b, s)\
01554 {\
01555 b = (s)[0];\
01556 g = (s)[1];\
01557 r = (s)[2];\
01558 }
01559
01560 #define RGB_OUT(d, r, g, b)\
01561 {\
01562 (d)[0] = b;\
01563 (d)[1] = g;\
01564 (d)[2] = r;\
01565 }
01566
01567 #define BPP 3
01568
01569 #include "imgconvert_template.c"
01570
01571 #undef RGB_IN
01572 #undef RGB_OUT
01573 #undef BPP
01574
01575
01576
01577 #define RGB_NAME rgb24
01578 #define FMT_RGB24
01579
01580 #define RGB_IN(r, g, b, s)\
01581 {\
01582 r = (s)[0];\
01583 g = (s)[1];\
01584 b = (s)[2];\
01585 }
01586
01587 #define RGB_OUT(d, r, g, b)\
01588 {\
01589 (d)[0] = r;\
01590 (d)[1] = g;\
01591 (d)[2] = b;\
01592 }
01593
01594 #define BPP 3
01595
01596 #include "imgconvert_template.c"
01597
01598
01599
01600 #define RGB_NAME rgb32
01601 #define FMT_RGB32
01602
01603 #define RGB_IN(r, g, b, s)\
01604 {\
01605 unsigned int v = ((const uint32_t *)(s))[0];\
01606 r = (v >> 16) & 0xff;\
01607 g = (v >> 8) & 0xff;\
01608 b = v & 0xff;\
01609 }
01610
01611 #define RGBA_IN(r, g, b, a, s)\
01612 {\
01613 unsigned int v = ((const uint32_t *)(s))[0];\
01614 a = (v >> 24) & 0xff;\
01615 r = (v >> 16) & 0xff;\
01616 g = (v >> 8) & 0xff;\
01617 b = v & 0xff;\
01618 }
01619
01620 #define RGBA_OUT(d, r, g, b, a)\
01621 {\
01622 ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
01623 }
01624
01625 #define BPP 4
01626
01627 #include "imgconvert_template.c"
01628
01629 static void mono_to_gray(AVPicture *dst, const AVPicture *src,
01630 int width, int height, int xor_mask)
01631 {
01632 const unsigned char *p;
01633 unsigned char *q;
01634 int v, dst_wrap, src_wrap;
01635 int y, w;
01636
01637 p = src->data[0];
01638 src_wrap = src->linesize[0] - ((width + 7) >> 3);
01639
01640 q = dst->data[0];
01641 dst_wrap = dst->linesize[0] - width;
01642 for(y=0;y<height;y++) {
01643 w = width;
01644 while (w >= 8) {
01645 v = *p++ ^ xor_mask;
01646 q[0] = -(v >> 7);
01647 q[1] = -((v >> 6) & 1);
01648 q[2] = -((v >> 5) & 1);
01649 q[3] = -((v >> 4) & 1);
01650 q[4] = -((v >> 3) & 1);
01651 q[5] = -((v >> 2) & 1);
01652 q[6] = -((v >> 1) & 1);
01653 q[7] = -((v >> 0) & 1);
01654 w -= 8;
01655 q += 8;
01656 }
01657 if (w > 0) {
01658 v = *p++ ^ xor_mask;
01659 do {
01660 q[0] = -((v >> 7) & 1);
01661 q++;
01662 v <<= 1;
01663 } while (--w);
01664 }
01665 p += src_wrap;
01666 q += dst_wrap;
01667 }
01668 }
01669
01670 static void monowhite_to_gray(AVPicture *dst, const AVPicture *src,
01671 int width, int height)
01672 {
01673 mono_to_gray(dst, src, width, height, 0xff);
01674 }
01675
01676 static void monoblack_to_gray(AVPicture *dst, const AVPicture *src,
01677 int width, int height)
01678 {
01679 mono_to_gray(dst, src, width, height, 0x00);
01680 }
01681
01682 static void gray_to_mono(AVPicture *dst, const AVPicture *src,
01683 int width, int height, int xor_mask)
01684 {
01685 int n;
01686 const uint8_t *s;
01687 uint8_t *d;
01688 int j, b, v, n1, src_wrap, dst_wrap, y;
01689
01690 s = src->data[0];
01691 src_wrap = src->linesize[0] - width;
01692
01693 d = dst->data[0];
01694 dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
01695
01696 for(y=0;y<height;y++) {
01697 n = width;
01698 while (n >= 8) {
01699 v = 0;
01700 for(j=0;j<8;j++) {
01701 b = s[0];
01702 s++;
01703 v = (v << 1) | (b >> 7);
01704 }
01705 d[0] = v ^ xor_mask;
01706 d++;
01707 n -= 8;
01708 }
01709 if (n > 0) {
01710 n1 = n;
01711 v = 0;
01712 while (n > 0) {
01713 b = s[0];
01714 s++;
01715 v = (v << 1) | (b >> 7);
01716 n--;
01717 }
01718 d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
01719 d++;
01720 }
01721 s += src_wrap;
01722 d += dst_wrap;
01723 }
01724 }
01725
01726 static void gray_to_monowhite(AVPicture *dst, const AVPicture *src,
01727 int width, int height)
01728 {
01729 gray_to_mono(dst, src, width, height, 0xff);
01730 }
01731
01732 static void gray_to_monoblack(AVPicture *dst, const AVPicture *src,
01733 int width, int height)
01734 {
01735 gray_to_mono(dst, src, width, height, 0x00);
01736 }
01737
01738 static void gray_to_gray16(AVPicture *dst, const AVPicture *src,
01739 int width, int height)
01740 {
01741 int x, y, src_wrap, dst_wrap;
01742 uint8_t *s, *d;
01743 s = src->data[0];
01744 src_wrap = src->linesize[0] - width;
01745 d = dst->data[0];
01746 dst_wrap = dst->linesize[0] - width * 2;
01747 for(y=0; y<height; y++){
01748 for(x=0; x<width; x++){
01749 *d++ = *s;
01750 *d++ = *s++;
01751 }
01752 s += src_wrap;
01753 d += dst_wrap;
01754 }
01755 }
01756
01757 static void gray16_to_gray(AVPicture *dst, const AVPicture *src,
01758 int width, int height)
01759 {
01760 int x, y, src_wrap, dst_wrap;
01761 uint8_t *s, *d;
01762 s = src->data[0];
01763 src_wrap = src->linesize[0] - width * 2;
01764 d = dst->data[0];
01765 dst_wrap = dst->linesize[0] - width;
01766 for(y=0; y<height; y++){
01767 for(x=0; x<width; x++){
01768 *d++ = *s;
01769 s += 2;
01770 }
01771 s += src_wrap;
01772 d += dst_wrap;
01773 }
01774 }
01775
01776 static void gray16be_to_gray(AVPicture *dst, const AVPicture *src,
01777 int width, int height)
01778 {
01779 gray16_to_gray(dst, src, width, height);
01780 }
01781
01782 static void gray16le_to_gray(AVPicture *dst, const AVPicture *src,
01783 int width, int height)
01784 {
01785 AVPicture tmpsrc = *src;
01786 tmpsrc.data[0]++;
01787 gray16_to_gray(dst, &tmpsrc, width, height);
01788 }
01789
01790 static void gray16_to_gray16(AVPicture *dst, const AVPicture *src,
01791 int width, int height)
01792 {
01793 int x, y, src_wrap, dst_wrap;
01794 uint16_t *s, *d;
01795 s = (uint16_t*)src->data[0];
01796 src_wrap = (src->linesize[0] - width * 2)/2;
01797 d = (uint16_t*)dst->data[0];
01798 dst_wrap = (dst->linesize[0] - width * 2)/2;
01799 for(y=0; y<height; y++){
01800 for(x=0; x<width; x++){
01801 *d++ = bswap_16(*s++);
01802 }
01803 s += src_wrap;
01804 d += dst_wrap;
01805 }
01806 }
01807
01808
01809 typedef struct ConvertEntry {
01810 void (*convert)(AVPicture *dst,
01811 const AVPicture *src, int width, int height);
01812 } ConvertEntry;
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831 static const ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
01832 [PIX_FMT_YUV420P] = {
01833 [PIX_FMT_YUYV422] = {
01834 .convert = yuv420p_to_yuyv422,
01835 },
01836 [PIX_FMT_RGB555] = {
01837 .convert = yuv420p_to_rgb555
01838 },
01839 [PIX_FMT_RGB565] = {
01840 .convert = yuv420p_to_rgb565
01841 },
01842 [PIX_FMT_BGR24] = {
01843 .convert = yuv420p_to_bgr24
01844 },
01845 [PIX_FMT_RGB24] = {
01846 .convert = yuv420p_to_rgb24
01847 },
01848 [PIX_FMT_RGB32] = {
01849 .convert = yuv420p_to_rgb32
01850 },
01851 [PIX_FMT_UYVY422] = {
01852 .convert = yuv420p_to_uyvy422,
01853 },
01854 },
01855 [PIX_FMT_YUV422P] = {
01856 [PIX_FMT_YUYV422] = {
01857 .convert = yuv422p_to_yuyv422,
01858 },
01859 [PIX_FMT_UYVY422] = {
01860 .convert = yuv422p_to_uyvy422,
01861 },
01862 },
01863 [PIX_FMT_YUV444P] = {
01864 [PIX_FMT_RGB24] = {
01865 .convert = yuv444p_to_rgb24
01866 },
01867 },
01868 [PIX_FMT_YUVJ420P] = {
01869 [PIX_FMT_RGB555] = {
01870 .convert = yuvj420p_to_rgb555
01871 },
01872 [PIX_FMT_RGB565] = {
01873 .convert = yuvj420p_to_rgb565
01874 },
01875 [PIX_FMT_BGR24] = {
01876 .convert = yuvj420p_to_bgr24
01877 },
01878 [PIX_FMT_RGB24] = {
01879 .convert = yuvj420p_to_rgb24
01880 },
01881 [PIX_FMT_RGB32] = {
01882 .convert = yuvj420p_to_rgb32
01883 },
01884 },
01885 [PIX_FMT_YUVJ444P] = {
01886 [PIX_FMT_RGB24] = {
01887 .convert = yuvj444p_to_rgb24
01888 },
01889 },
01890 [PIX_FMT_YUYV422] = {
01891 [PIX_FMT_YUV420P] = {
01892 .convert = yuyv422_to_yuv420p,
01893 },
01894 [PIX_FMT_YUV422P] = {
01895 .convert = yuyv422_to_yuv422p,
01896 },
01897 },
01898 [PIX_FMT_UYVY422] = {
01899 [PIX_FMT_YUV420P] = {
01900 .convert = uyvy422_to_yuv420p,
01901 },
01902 [PIX_FMT_YUV422P] = {
01903 .convert = uyvy422_to_yuv422p,
01904 },
01905 },
01906 [PIX_FMT_RGB24] = {
01907 [PIX_FMT_YUV420P] = {
01908 .convert = rgb24_to_yuv420p
01909 },
01910 [PIX_FMT_RGB565] = {
01911 .convert = rgb24_to_rgb565
01912 },
01913 [PIX_FMT_RGB555] = {
01914 .convert = rgb24_to_rgb555
01915 },
01916 [PIX_FMT_RGB32] = {
01917 .convert = rgb24_to_rgb32
01918 },
01919 [PIX_FMT_BGR24] = {
01920 .convert = rgb24_to_bgr24
01921 },
01922 [PIX_FMT_GRAY8] = {
01923 .convert = rgb24_to_gray
01924 },
01925 [PIX_FMT_PAL8] = {
01926 .convert = rgb24_to_pal8
01927 },
01928 [PIX_FMT_YUV444P] = {
01929 .convert = rgb24_to_yuv444p
01930 },
01931 [PIX_FMT_YUVJ420P] = {
01932 .convert = rgb24_to_yuvj420p
01933 },
01934 [PIX_FMT_YUVJ444P] = {
01935 .convert = rgb24_to_yuvj444p
01936 },
01937 },
01938 [PIX_FMT_RGB32] = {
01939 [PIX_FMT_RGB24] = {
01940 .convert = rgb32_to_rgb24
01941 },
01942 [PIX_FMT_BGR24] = {
01943 .convert = rgb32_to_bgr24
01944 },
01945 [PIX_FMT_RGB565] = {
01946 .convert = rgb32_to_rgb565
01947 },
01948 [PIX_FMT_RGB555] = {
01949 .convert = rgb32_to_rgb555
01950 },
01951 [PIX_FMT_PAL8] = {
01952 .convert = rgb32_to_pal8
01953 },
01954 [PIX_FMT_YUV420P] = {
01955 .convert = rgb32_to_yuv420p
01956 },
01957 [PIX_FMT_GRAY8] = {
01958 .convert = rgb32_to_gray
01959 },
01960 },
01961 [PIX_FMT_BGR24] = {
01962 [PIX_FMT_RGB32] = {
01963 .convert = bgr24_to_rgb32
01964 },
01965 [PIX_FMT_RGB24] = {
01966 .convert = bgr24_to_rgb24
01967 },
01968 [PIX_FMT_YUV420P] = {
01969 .convert = bgr24_to_yuv420p
01970 },
01971 [PIX_FMT_GRAY8] = {
01972 .convert = bgr24_to_gray
01973 },
01974 },
01975 [PIX_FMT_RGB555] = {
01976 [PIX_FMT_RGB24] = {
01977 .convert = rgb555_to_rgb24
01978 },
01979 [PIX_FMT_RGB32] = {
01980 .convert = rgb555_to_rgb32
01981 },
01982 [PIX_FMT_YUV420P] = {
01983 .convert = rgb555_to_yuv420p
01984 },
01985 [PIX_FMT_GRAY8] = {
01986 .convert = rgb555_to_gray
01987 },
01988 },
01989 [PIX_FMT_RGB565] = {
01990 [PIX_FMT_RGB32] = {
01991 .convert = rgb565_to_rgb32
01992 },
01993 [PIX_FMT_RGB24] = {
01994 .convert = rgb565_to_rgb24
01995 },
01996 [PIX_FMT_YUV420P] = {
01997 .convert = rgb565_to_yuv420p
01998 },
01999 [PIX_FMT_GRAY8] = {
02000 .convert = rgb565_to_gray
02001 },
02002 },
02003 [PIX_FMT_GRAY16BE] = {
02004 [PIX_FMT_GRAY8] = {
02005 .convert = gray16be_to_gray
02006 },
02007 [PIX_FMT_GRAY16LE] = {
02008 .convert = gray16_to_gray16
02009 },
02010 },
02011 [PIX_FMT_GRAY16LE] = {
02012 [PIX_FMT_GRAY8] = {
02013 .convert = gray16le_to_gray
02014 },
02015 [PIX_FMT_GRAY16BE] = {
02016 .convert = gray16_to_gray16
02017 },
02018 },
02019 [PIX_FMT_GRAY8] = {
02020 [PIX_FMT_RGB555] = {
02021 .convert = gray_to_rgb555
02022 },
02023 [PIX_FMT_RGB565] = {
02024 .convert = gray_to_rgb565
02025 },
02026 [PIX_FMT_RGB24] = {
02027 .convert = gray_to_rgb24
02028 },
02029 [PIX_FMT_BGR24] = {
02030 .convert = gray_to_bgr24
02031 },
02032 [PIX_FMT_RGB32] = {
02033 .convert = gray_to_rgb32
02034 },
02035 [PIX_FMT_MONOWHITE] = {
02036 .convert = gray_to_monowhite
02037 },
02038 [PIX_FMT_MONOBLACK] = {
02039 .convert = gray_to_monoblack
02040 },
02041 [PIX_FMT_GRAY16LE] = {
02042 .convert = gray_to_gray16
02043 },
02044 [PIX_FMT_GRAY16BE] = {
02045 .convert = gray_to_gray16
02046 },
02047 },
02048 [PIX_FMT_MONOWHITE] = {
02049 [PIX_FMT_GRAY8] = {
02050 .convert = monowhite_to_gray
02051 },
02052 },
02053 [PIX_FMT_MONOBLACK] = {
02054 [PIX_FMT_GRAY8] = {
02055 .convert = monoblack_to_gray
02056 },
02057 },
02058 [PIX_FMT_PAL8] = {
02059 [PIX_FMT_RGB555] = {
02060 .convert = pal8_to_rgb555
02061 },
02062 [PIX_FMT_RGB565] = {
02063 .convert = pal8_to_rgb565
02064 },
02065 [PIX_FMT_BGR24] = {
02066 .convert = pal8_to_bgr24
02067 },
02068 [PIX_FMT_RGB24] = {
02069 .convert = pal8_to_rgb24
02070 },
02071 [PIX_FMT_RGB32] = {
02072 .convert = pal8_to_rgb32
02073 },
02074 },
02075 [PIX_FMT_UYYVYY411] = {
02076 [PIX_FMT_YUV411P] = {
02077 .convert = uyyvyy411_to_yuv411p,
02078 },
02079 },
02080
02081 };
02082
02083 int avpicture_alloc(AVPicture *picture,
02084 int pix_fmt, int width, int height)
02085 {
02086 int size;
02087 void *ptr;
02088
02089 size = avpicture_get_size(pix_fmt, width, height);
02090 if(size<0)
02091 goto fail;
02092 ptr = av_malloc(size);
02093 if (!ptr)
02094 goto fail;
02095 avpicture_fill(picture, ptr, pix_fmt, width, height);
02096 if(picture->data[1] && !picture->data[2])
02097 ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
02098
02099 return 0;
02100 fail:
02101 memset(picture, 0, sizeof(AVPicture));
02102 return -1;
02103 }
02104
02105 void avpicture_free(AVPicture *picture)
02106 {
02107 av_free(picture->data[0]);
02108 }
02109
02110
02111 static inline int is_yuv_planar(const PixFmtInfo *ps)
02112 {
02113 return (ps->color_type == FF_COLOR_YUV ||
02114 ps->color_type == FF_COLOR_YUV_JPEG) &&
02115 ps->pixel_type == FF_PIXEL_PLANAR;
02116 }
02117
02118 int av_picture_crop(AVPicture *dst, const AVPicture *src,
02119 int pix_fmt, int top_band, int left_band)
02120 {
02121 int y_shift;
02122 int x_shift;
02123
02124 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
02125 return -1;
02126
02127 y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
02128 x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
02129
02130 dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
02131 dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
02132 dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
02133
02134 dst->linesize[0] = src->linesize[0];
02135 dst->linesize[1] = src->linesize[1];
02136 dst->linesize[2] = src->linesize[2];
02137 return 0;
02138 }
02139
02140 int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
02141 int pix_fmt, int padtop, int padbottom, int padleft, int padright,
02142 int *color)
02143 {
02144 uint8_t *optr;
02145 int y_shift;
02146 int x_shift;
02147 int yheight;
02148 int i, y;
02149
02150 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
02151 !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
02152
02153 for (i = 0; i < 3; i++) {
02154 x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0;
02155 y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0;
02156
02157 if (padtop || padleft) {
02158 memset(dst->data[i], color[i],
02159 dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
02160 }
02161
02162 if (padleft || padright) {
02163 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
02164 (dst->linesize[i] - (padright >> x_shift));
02165 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
02166 for (y = 0; y < yheight; y++) {
02167 memset(optr, color[i], (padleft + padright) >> x_shift);
02168 optr += dst->linesize[i];
02169 }
02170 }
02171
02172 if (src) {
02173 uint8_t *iptr = src->data[i];
02174 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
02175 (padleft >> x_shift);
02176 memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
02177 iptr += src->linesize[i];
02178 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
02179 (dst->linesize[i] - (padright >> x_shift));
02180 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
02181 for (y = 0; y < yheight; y++) {
02182 memset(optr, color[i], (padleft + padright) >> x_shift);
02183 memcpy(optr + ((padleft + padright) >> x_shift), iptr,
02184 (width - padleft - padright) >> x_shift);
02185 iptr += src->linesize[i];
02186 optr += dst->linesize[i];
02187 }
02188 }
02189
02190 if (padbottom || padright) {
02191 optr = dst->data[i] + dst->linesize[i] *
02192 ((height - padbottom) >> y_shift) - (padright >> x_shift);
02193 memset(optr, color[i],dst->linesize[i] *
02194 (padbottom >> y_shift) + (padright >> x_shift));
02195 }
02196 }
02197 return 0;
02198 }
02199
02200 #if !CONFIG_SWSCALE
02201 static uint8_t y_ccir_to_jpeg[256];
02202 static uint8_t y_jpeg_to_ccir[256];
02203 static uint8_t c_ccir_to_jpeg[256];
02204 static uint8_t c_jpeg_to_ccir[256];
02205
02206
02207 static av_cold void img_convert_init(void)
02208 {
02209 int i;
02210 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
02211
02212 for(i = 0;i < 256; i++) {
02213 y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
02214 y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
02215 c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
02216 c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
02217 }
02218 }
02219
02220
02221 static void img_apply_table(uint8_t *dst, int dst_wrap,
02222 const uint8_t *src, int src_wrap,
02223 int width, int height, const uint8_t *table1)
02224 {
02225 int n;
02226 const uint8_t *s;
02227 uint8_t *d;
02228 const uint8_t *table;
02229
02230 table = table1;
02231 for(;height > 0; height--) {
02232 s = src;
02233 d = dst;
02234 n = width;
02235 while (n >= 4) {
02236 d[0] = table[s[0]];
02237 d[1] = table[s[1]];
02238 d[2] = table[s[2]];
02239 d[3] = table[s[3]];
02240 d += 4;
02241 s += 4;
02242 n -= 4;
02243 }
02244 while (n > 0) {
02245 d[0] = table[s[0]];
02246 d++;
02247 s++;
02248 n--;
02249 }
02250 dst += dst_wrap;
02251 src += src_wrap;
02252 }
02253 }
02254
02255
02256
02257
02258
02259 static void shrink41(uint8_t *dst, int dst_wrap,
02260 const uint8_t *src, int src_wrap,
02261 int width, int height)
02262 {
02263 int w;
02264 const uint8_t *s;
02265 uint8_t *d;
02266
02267 for(;height > 0; height--) {
02268 s = src;
02269 d = dst;
02270 for(w = width;w > 0; w--) {
02271 d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
02272 s += 4;
02273 d++;
02274 }
02275 src += src_wrap;
02276 dst += dst_wrap;
02277 }
02278 }
02279
02280
02281 static void shrink21(uint8_t *dst, int dst_wrap,
02282 const uint8_t *src, int src_wrap,
02283 int width, int height)
02284 {
02285 int w;
02286 const uint8_t *s;
02287 uint8_t *d;
02288
02289 for(;height > 0; height--) {
02290 s = src;
02291 d = dst;
02292 for(w = width;w > 0; w--) {
02293 d[0] = (s[0] + s[1]) >> 1;
02294 s += 2;
02295 d++;
02296 }
02297 src += src_wrap;
02298 dst += dst_wrap;
02299 }
02300 }
02301
02302
02303 static void shrink12(uint8_t *dst, int dst_wrap,
02304 const uint8_t *src, int src_wrap,
02305 int width, int height)
02306 {
02307 int w;
02308 uint8_t *d;
02309 const uint8_t *s1, *s2;
02310
02311 for(;height > 0; height--) {
02312 s1 = src;
02313 s2 = s1 + src_wrap;
02314 d = dst;
02315 for(w = width;w >= 4; w-=4) {
02316 d[0] = (s1[0] + s2[0]) >> 1;
02317 d[1] = (s1[1] + s2[1]) >> 1;
02318 d[2] = (s1[2] + s2[2]) >> 1;
02319 d[3] = (s1[3] + s2[3]) >> 1;
02320 s1 += 4;
02321 s2 += 4;
02322 d += 4;
02323 }
02324 for(;w > 0; w--) {
02325 d[0] = (s1[0] + s2[0]) >> 1;
02326 s1++;
02327 s2++;
02328 d++;
02329 }
02330 src += 2 * src_wrap;
02331 dst += dst_wrap;
02332 }
02333 }
02334
02335 static void grow21_line(uint8_t *dst, const uint8_t *src,
02336 int width)
02337 {
02338 int w;
02339 const uint8_t *s1;
02340 uint8_t *d;
02341
02342 s1 = src;
02343 d = dst;
02344 for(w = width;w >= 4; w-=4) {
02345 d[1] = d[0] = s1[0];
02346 d[3] = d[2] = s1[1];
02347 s1 += 2;
02348 d += 4;
02349 }
02350 for(;w >= 2; w -= 2) {
02351 d[1] = d[0] = s1[0];
02352 s1 ++;
02353 d += 2;
02354 }
02355
02356
02357 if (w) {
02358 d[0] = s1[0];
02359 }
02360 }
02361
02362 static void grow41_line(uint8_t *dst, const uint8_t *src,
02363 int width)
02364 {
02365 int w, v;
02366 const uint8_t *s1;
02367 uint8_t *d;
02368
02369 s1 = src;
02370 d = dst;
02371 for(w = width;w >= 4; w-=4) {
02372 v = s1[0];
02373 d[0] = v;
02374 d[1] = v;
02375 d[2] = v;
02376 d[3] = v;
02377 s1 ++;
02378 d += 4;
02379 }
02380 }
02381
02382
02383 static void grow21(uint8_t *dst, int dst_wrap,
02384 const uint8_t *src, int src_wrap,
02385 int width, int height)
02386 {
02387 for(;height > 0; height--) {
02388 grow21_line(dst, src, width);
02389 src += src_wrap;
02390 dst += dst_wrap;
02391 }
02392 }
02393
02394
02395 static void grow12(uint8_t *dst, int dst_wrap,
02396 const uint8_t *src, int src_wrap,
02397 int width, int height)
02398 {
02399 for(;height > 0; height-=2) {
02400 memcpy(dst, src, width);
02401 dst += dst_wrap;
02402 memcpy(dst, src, width);
02403 dst += dst_wrap;
02404 src += src_wrap;
02405 }
02406 }
02407
02408
02409 static void grow22(uint8_t *dst, int dst_wrap,
02410 const uint8_t *src, int src_wrap,
02411 int width, int height)
02412 {
02413 for(;height > 0; height--) {
02414 grow21_line(dst, src, width);
02415 if (height%2)
02416 src += src_wrap;
02417 dst += dst_wrap;
02418 }
02419 }
02420
02421
02422 static void grow41(uint8_t *dst, int dst_wrap,
02423 const uint8_t *src, int src_wrap,
02424 int width, int height)
02425 {
02426 for(;height > 0; height--) {
02427 grow41_line(dst, src, width);
02428 src += src_wrap;
02429 dst += dst_wrap;
02430 }
02431 }
02432
02433
02434 static void grow44(uint8_t *dst, int dst_wrap,
02435 const uint8_t *src, int src_wrap,
02436 int width, int height)
02437 {
02438 for(;height > 0; height--) {
02439 grow41_line(dst, src, width);
02440 if ((height & 3) == 1)
02441 src += src_wrap;
02442 dst += dst_wrap;
02443 }
02444 }
02445
02446
02447 static void conv411(uint8_t *dst, int dst_wrap,
02448 const uint8_t *src, int src_wrap,
02449 int width, int height)
02450 {
02451 int w, c;
02452 const uint8_t *s1, *s2;
02453 uint8_t *d;
02454
02455 width>>=1;
02456
02457 for(;height > 0; height--) {
02458 s1 = src;
02459 s2 = src + src_wrap;
02460 d = dst;
02461 for(w = width;w > 0; w--) {
02462 c = (s1[0] + s2[0]) >> 1;
02463 d[0] = c;
02464 d[1] = c;
02465 s1++;
02466 s2++;
02467 d += 2;
02468 }
02469 src += src_wrap * 2;
02470 dst += dst_wrap;
02471 }
02472 }
02473
02474
02475 int img_convert(AVPicture *dst, int dst_pix_fmt,
02476 const AVPicture *src, int src_pix_fmt,
02477 int src_width, int src_height)
02478 {
02479 static int initialized;
02480 int i, ret, dst_width, dst_height, int_pix_fmt;
02481 const PixFmtInfo *src_pix, *dst_pix;
02482 const ConvertEntry *ce;
02483 AVPicture tmp1, *tmp = &tmp1;
02484
02485 if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
02486 dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
02487 return -1;
02488 if (src_width <= 0 || src_height <= 0)
02489 return 0;
02490
02491 if (!initialized) {
02492 initialized = 1;
02493 img_convert_init();
02494 }
02495
02496 dst_width = src_width;
02497 dst_height = src_height;
02498
02499 dst_pix = &pix_fmt_info[dst_pix_fmt];
02500 src_pix = &pix_fmt_info[src_pix_fmt];
02501 if (src_pix_fmt == dst_pix_fmt) {
02502
02503 av_picture_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
02504 return 0;
02505 }
02506
02507 ce = &convert_table[src_pix_fmt][dst_pix_fmt];
02508 if (ce->convert) {
02509
02510 ce->convert(dst, src, dst_width, dst_height);
02511 return 0;
02512 }
02513
02514
02515 if (is_yuv_planar(dst_pix) &&
02516 src_pix_fmt == PIX_FMT_GRAY8) {
02517 int w, h, y;
02518 uint8_t *d;
02519
02520 if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
02521 ff_img_copy_plane(dst->data[0], dst->linesize[0],
02522 src->data[0], src->linesize[0],
02523 dst_width, dst_height);
02524 } else {
02525 img_apply_table(dst->data[0], dst->linesize[0],
02526 src->data[0], src->linesize[0],
02527 dst_width, dst_height,
02528 y_jpeg_to_ccir);
02529 }
02530
02531 w = dst_width;
02532 h = dst_height;
02533 w >>= dst_pix->x_chroma_shift;
02534 h >>= dst_pix->y_chroma_shift;
02535 for(i = 1; i <= 2; i++) {
02536 d = dst->data[i];
02537 for(y = 0; y< h; y++) {
02538 memset(d, 128, w);
02539 d += dst->linesize[i];
02540 }
02541 }
02542 return 0;
02543 }
02544
02545
02546 if (is_yuv_planar(src_pix) &&
02547 dst_pix_fmt == PIX_FMT_GRAY8) {
02548 if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
02549 ff_img_copy_plane(dst->data[0], dst->linesize[0],
02550 src->data[0], src->linesize[0],
02551 dst_width, dst_height);
02552 } else {
02553 img_apply_table(dst->data[0], dst->linesize[0],
02554 src->data[0], src->linesize[0],
02555 dst_width, dst_height,
02556 y_ccir_to_jpeg);
02557 }
02558 return 0;
02559 }
02560
02561
02562 if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
02563 int x_shift, y_shift, w, h, xy_shift;
02564 void (*resize_func)(uint8_t *dst, int dst_wrap,
02565 const uint8_t *src, int src_wrap,
02566 int width, int height);
02567
02568
02569 w = dst_width;
02570 h = dst_height;
02571 if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
02572 w >>= dst_pix->x_chroma_shift;
02573 else
02574 w >>= src_pix->x_chroma_shift;
02575 if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
02576 h >>= dst_pix->y_chroma_shift;
02577 else
02578 h >>= src_pix->y_chroma_shift;
02579
02580 x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
02581 y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
02582 xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);
02583
02584
02585 switch(xy_shift) {
02586 case 0x00:
02587 resize_func = ff_img_copy_plane;
02588 break;
02589 case 0x10:
02590 resize_func = shrink21;
02591 break;
02592 case 0x20:
02593 resize_func = shrink41;
02594 break;
02595 case 0x01:
02596 resize_func = shrink12;
02597 break;
02598 case 0x11:
02599 resize_func = ff_shrink22;
02600 break;
02601 case 0x22:
02602 resize_func = ff_shrink44;
02603 break;
02604 case 0xf0:
02605 resize_func = grow21;
02606 break;
02607 case 0x0f:
02608 resize_func = grow12;
02609 break;
02610 case 0xe0:
02611 resize_func = grow41;
02612 break;
02613 case 0xff:
02614 resize_func = grow22;
02615 break;
02616 case 0xee:
02617 resize_func = grow44;
02618 break;
02619 case 0xf1:
02620 resize_func = conv411;
02621 break;
02622 default:
02623
02624 goto no_chroma_filter;
02625 }
02626
02627 ff_img_copy_plane(dst->data[0], dst->linesize[0],
02628 src->data[0], src->linesize[0],
02629 dst_width, dst_height);
02630
02631 for(i = 1;i <= 2; i++)
02632 resize_func(dst->data[i], dst->linesize[i],
02633 src->data[i], src->linesize[i],
02634 dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
02635
02636
02637 if (dst_pix->color_type != src_pix->color_type) {
02638 const uint8_t *y_table, *c_table;
02639 if (dst_pix->color_type == FF_COLOR_YUV) {
02640 y_table = y_jpeg_to_ccir;
02641 c_table = c_jpeg_to_ccir;
02642 } else {
02643 y_table = y_ccir_to_jpeg;
02644 c_table = c_ccir_to_jpeg;
02645 }
02646 img_apply_table(dst->data[0], dst->linesize[0],
02647 dst->data[0], dst->linesize[0],
02648 dst_width, dst_height,
02649 y_table);
02650
02651 for(i = 1;i <= 2; i++)
02652 img_apply_table(dst->data[i], dst->linesize[i],
02653 dst->data[i], dst->linesize[i],
02654 dst_width>>dst_pix->x_chroma_shift,
02655 dst_height>>dst_pix->y_chroma_shift,
02656 c_table);
02657 }
02658 return 0;
02659 }
02660 no_chroma_filter:
02661
02662
02663 if (src_pix_fmt == PIX_FMT_YUYV422 ||
02664 dst_pix_fmt == PIX_FMT_YUYV422) {
02665
02666 int_pix_fmt = PIX_FMT_YUV422P;
02667 } else if (src_pix_fmt == PIX_FMT_UYVY422 ||
02668 dst_pix_fmt == PIX_FMT_UYVY422) {
02669
02670 int_pix_fmt = PIX_FMT_YUV422P;
02671 } else if (src_pix_fmt == PIX_FMT_UYYVYY411 ||
02672 dst_pix_fmt == PIX_FMT_UYYVYY411) {
02673
02674 int_pix_fmt = PIX_FMT_YUV411P;
02675 } else if ((src_pix->color_type == FF_COLOR_GRAY &&
02676 src_pix_fmt != PIX_FMT_GRAY8) ||
02677 (dst_pix->color_type == FF_COLOR_GRAY &&
02678 dst_pix_fmt != PIX_FMT_GRAY8)) {
02679
02680 int_pix_fmt = PIX_FMT_GRAY8;
02681 } else if ((is_yuv_planar(src_pix) &&
02682 src_pix_fmt != PIX_FMT_YUV444P &&
02683 src_pix_fmt != PIX_FMT_YUVJ444P)) {
02684
02685 if (src_pix->color_type == FF_COLOR_YUV_JPEG)
02686 int_pix_fmt = PIX_FMT_YUVJ444P;
02687 else
02688 int_pix_fmt = PIX_FMT_YUV444P;
02689 } else if ((is_yuv_planar(dst_pix) &&
02690 dst_pix_fmt != PIX_FMT_YUV444P &&
02691 dst_pix_fmt != PIX_FMT_YUVJ444P)) {
02692
02693 if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
02694 int_pix_fmt = PIX_FMT_YUVJ444P;
02695 else
02696 int_pix_fmt = PIX_FMT_YUV444P;
02697 } else {
02698
02699 if (src_pix->is_alpha && dst_pix->is_alpha)
02700 int_pix_fmt = PIX_FMT_RGB32;
02701 else
02702 int_pix_fmt = PIX_FMT_RGB24;
02703 }
02704 if (src_pix_fmt == int_pix_fmt)
02705 return -1;
02706 if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
02707 return -1;
02708 ret = -1;
02709 if (img_convert(tmp, int_pix_fmt,
02710 src, src_pix_fmt, src_width, src_height) < 0)
02711 goto fail1;
02712 if (img_convert(dst, dst_pix_fmt,
02713 tmp, int_pix_fmt, dst_width, dst_height) < 0)
02714 goto fail1;
02715 ret = 0;
02716 fail1:
02717 avpicture_free(tmp);
02718 return ret;
02719 }
02720 #endif
02721
02722
02723 static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
02724 {
02725 const unsigned char *p;
02726 int src_wrap, ret, x, y;
02727 unsigned int a;
02728 uint32_t *palette = (uint32_t *)src->data[1];
02729
02730 p = src->data[0];
02731 src_wrap = src->linesize[0] - width;
02732 ret = 0;
02733 for(y=0;y<height;y++) {
02734 for(x=0;x<width;x++) {
02735 a = palette[p[0]] >> 24;
02736 if (a == 0x00) {
02737 ret |= FF_ALPHA_TRANSP;
02738 } else if (a != 0xff) {
02739 ret |= FF_ALPHA_SEMI_TRANSP;
02740 }
02741 p++;
02742 }
02743 p += src_wrap;
02744 }
02745 return ret;
02746 }
02747
02748 int img_get_alpha_info(const AVPicture *src,
02749 int pix_fmt, int width, int height)
02750 {
02751 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
02752 int ret;
02753
02754 pf = &pix_fmt_info[pix_fmt];
02755
02756 if (!pf->is_alpha)
02757 return 0;
02758 switch(pix_fmt) {
02759 case PIX_FMT_RGB32:
02760 ret = get_alpha_info_rgb32(src, width, height);
02761 break;
02762 case PIX_FMT_PAL8:
02763 ret = get_alpha_info_pal8(src, width, height);
02764 break;
02765 default:
02766
02767 ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
02768 break;
02769 }
02770 return ret;
02771 }
02772
02773 #if HAVE_MMX
02774 #define DEINT_INPLACE_LINE_LUM \
02775 movd_m2r(lum_m4[0],mm0);\
02776 movd_m2r(lum_m3[0],mm1);\
02777 movd_m2r(lum_m2[0],mm2);\
02778 movd_m2r(lum_m1[0],mm3);\
02779 movd_m2r(lum[0],mm4);\
02780 punpcklbw_r2r(mm7,mm0);\
02781 movd_r2m(mm2,lum_m4[0]);\
02782 punpcklbw_r2r(mm7,mm1);\
02783 punpcklbw_r2r(mm7,mm2);\
02784 punpcklbw_r2r(mm7,mm3);\
02785 punpcklbw_r2r(mm7,mm4);\
02786 paddw_r2r(mm3,mm1);\
02787 psllw_i2r(1,mm2);\
02788 paddw_r2r(mm4,mm0);\
02789 psllw_i2r(2,mm1);\
02790 paddw_r2r(mm6,mm2);\
02791 paddw_r2r(mm2,mm1);\
02792 psubusw_r2r(mm0,mm1);\
02793 psrlw_i2r(3,mm1);\
02794 packuswb_r2r(mm7,mm1);\
02795 movd_r2m(mm1,lum_m2[0]);
02796
02797 #define DEINT_LINE_LUM \
02798 movd_m2r(lum_m4[0],mm0);\
02799 movd_m2r(lum_m3[0],mm1);\
02800 movd_m2r(lum_m2[0],mm2);\
02801 movd_m2r(lum_m1[0],mm3);\
02802 movd_m2r(lum[0],mm4);\
02803 punpcklbw_r2r(mm7,mm0);\
02804 punpcklbw_r2r(mm7,mm1);\
02805 punpcklbw_r2r(mm7,mm2);\
02806 punpcklbw_r2r(mm7,mm3);\
02807 punpcklbw_r2r(mm7,mm4);\
02808 paddw_r2r(mm3,mm1);\
02809 psllw_i2r(1,mm2);\
02810 paddw_r2r(mm4,mm0);\
02811 psllw_i2r(2,mm1);\
02812 paddw_r2r(mm6,mm2);\
02813 paddw_r2r(mm2,mm1);\
02814 psubusw_r2r(mm0,mm1);\
02815 psrlw_i2r(3,mm1);\
02816 packuswb_r2r(mm7,mm1);\
02817 movd_r2m(mm1,dst[0]);
02818 #endif
02819
02820
02821 static void deinterlace_line(uint8_t *dst,
02822 const uint8_t *lum_m4, const uint8_t *lum_m3,
02823 const uint8_t *lum_m2, const uint8_t *lum_m1,
02824 const uint8_t *lum,
02825 int size)
02826 {
02827 #if !HAVE_MMX
02828 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
02829 int sum;
02830
02831 for(;size > 0;size--) {
02832 sum = -lum_m4[0];
02833 sum += lum_m3[0] << 2;
02834 sum += lum_m2[0] << 1;
02835 sum += lum_m1[0] << 2;
02836 sum += -lum[0];
02837 dst[0] = cm[(sum + 4) >> 3];
02838 lum_m4++;
02839 lum_m3++;
02840 lum_m2++;
02841 lum_m1++;
02842 lum++;
02843 dst++;
02844 }
02845 #else
02846
02847 {
02848 pxor_r2r(mm7,mm7);
02849 movq_m2r(ff_pw_4,mm6);
02850 }
02851 for (;size > 3; size-=4) {
02852 DEINT_LINE_LUM
02853 lum_m4+=4;
02854 lum_m3+=4;
02855 lum_m2+=4;
02856 lum_m1+=4;
02857 lum+=4;
02858 dst+=4;
02859 }
02860 #endif
02861 }
02862 static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
02863 int size)
02864 {
02865 #if !HAVE_MMX
02866 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
02867 int sum;
02868
02869 for(;size > 0;size--) {
02870 sum = -lum_m4[0];
02871 sum += lum_m3[0] << 2;
02872 sum += lum_m2[0] << 1;
02873 lum_m4[0]=lum_m2[0];
02874 sum += lum_m1[0] << 2;
02875 sum += -lum[0];
02876 lum_m2[0] = cm[(sum + 4) >> 3];
02877 lum_m4++;
02878 lum_m3++;
02879 lum_m2++;
02880 lum_m1++;
02881 lum++;
02882 }
02883 #else
02884
02885 {
02886 pxor_r2r(mm7,mm7);
02887 movq_m2r(ff_pw_4,mm6);
02888 }
02889 for (;size > 3; size-=4) {
02890 DEINT_INPLACE_LINE_LUM
02891 lum_m4+=4;
02892 lum_m3+=4;
02893 lum_m2+=4;
02894 lum_m1+=4;
02895 lum+=4;
02896 }
02897 #endif
02898 }
02899
02900
02901
02902
02903 static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
02904 const uint8_t *src1, int src_wrap,
02905 int width, int height)
02906 {
02907 const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
02908 int y;
02909
02910 src_m2 = src1;
02911 src_m1 = src1;
02912 src_0=&src_m1[src_wrap];
02913 src_p1=&src_0[src_wrap];
02914 src_p2=&src_p1[src_wrap];
02915 for(y=0;y<(height-2);y+=2) {
02916 memcpy(dst,src_m1,width);
02917 dst += dst_wrap;
02918 deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
02919 src_m2 = src_0;
02920 src_m1 = src_p1;
02921 src_0 = src_p2;
02922 src_p1 += 2*src_wrap;
02923 src_p2 += 2*src_wrap;
02924 dst += dst_wrap;
02925 }
02926 memcpy(dst,src_m1,width);
02927 dst += dst_wrap;
02928
02929 deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
02930 }
02931
02932 static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
02933 int width, int height)
02934 {
02935 uint8_t *src_m1, *src_0, *src_p1, *src_p2;
02936 int y;
02937 uint8_t *buf;
02938 buf = (uint8_t*)av_malloc(width);
02939
02940 src_m1 = src1;
02941 memcpy(buf,src_m1,width);
02942 src_0=&src_m1[src_wrap];
02943 src_p1=&src_0[src_wrap];
02944 src_p2=&src_p1[src_wrap];
02945 for(y=0;y<(height-2);y+=2) {
02946 deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
02947 src_m1 = src_p1;
02948 src_0 = src_p2;
02949 src_p1 += 2*src_wrap;
02950 src_p2 += 2*src_wrap;
02951 }
02952
02953 deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
02954 av_free(buf);
02955 }
02956
02957 int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
02958 int pix_fmt, int width, int height)
02959 {
02960 int i;
02961
02962 if (pix_fmt != PIX_FMT_YUV420P &&
02963 pix_fmt != PIX_FMT_YUV422P &&
02964 pix_fmt != PIX_FMT_YUV444P &&
02965 pix_fmt != PIX_FMT_YUV411P &&
02966 pix_fmt != PIX_FMT_GRAY8)
02967 return -1;
02968 if ((width & 3) != 0 || (height & 3) != 0)
02969 return -1;
02970
02971 for(i=0;i<3;i++) {
02972 if (i == 1) {
02973 switch(pix_fmt) {
02974 case PIX_FMT_YUV420P:
02975 width >>= 1;
02976 height >>= 1;
02977 break;
02978 case PIX_FMT_YUV422P:
02979 width >>= 1;
02980 break;
02981 case PIX_FMT_YUV411P:
02982 width >>= 2;
02983 break;
02984 default:
02985 break;
02986 }
02987 if (pix_fmt == PIX_FMT_GRAY8) {
02988 break;
02989 }
02990 }
02991 if (src == dst) {
02992 deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
02993 width, height);
02994 } else {
02995 deinterlace_bottom_field(dst->data[i],dst->linesize[i],
02996 src->data[i], src->linesize[i],
02997 width, height);
02998 }
02999 }
03000 emms_c();
03001 return 0;
03002 }
03003