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 for(i = 0;i < PIX_FMT_NB; i++) {
00894 if (pix_fmt_mask & (1ULL << i)) {
00895 loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
00896 if (loss == 0) {
00897 dist = avg_bits_per_pixel(i);
00898 if (dist < min_dist) {
00899 min_dist = dist;
00900 dst_pix_fmt = i;
00901 }
00902 }
00903 }
00904 }
00905 return dst_pix_fmt;
00906 }
00907
00908 int avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, int src_pix_fmt,
00909 int has_alpha, int *loss_ptr)
00910 {
00911 int dst_pix_fmt, loss_mask, i;
00912 static const int loss_mask_order[] = {
00913 ~0,
00914 ~FF_LOSS_ALPHA,
00915 ~FF_LOSS_RESOLUTION,
00916 ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
00917 ~FF_LOSS_COLORQUANT,
00918 ~FF_LOSS_DEPTH,
00919 0,
00920 };
00921
00922
00923 i = 0;
00924 for(;;) {
00925 loss_mask = loss_mask_order[i++];
00926 dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
00927 has_alpha, loss_mask);
00928 if (dst_pix_fmt >= 0)
00929 goto found;
00930 if (loss_mask == 0)
00931 break;
00932 }
00933 return -1;
00934 found:
00935 if (loss_ptr)
00936 *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
00937 return dst_pix_fmt;
00938 }
00939
00940 void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
00941 const uint8_t *src, int src_wrap,
00942 int width, int height)
00943 {
00944 if((!dst) || (!src))
00945 return;
00946 for(;height > 0; height--) {
00947 memcpy(dst, src, width);
00948 dst += dst_wrap;
00949 src += src_wrap;
00950 }
00951 }
00952
00953 int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
00954 {
00955 int bits;
00956 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
00957
00958 pf = &pix_fmt_info[pix_fmt];
00959 switch(pf->pixel_type) {
00960 case FF_PIXEL_PACKED:
00961 switch(pix_fmt) {
00962 case PIX_FMT_YUYV422:
00963 case PIX_FMT_UYVY422:
00964 case PIX_FMT_RGB565:
00965 case PIX_FMT_RGB555:
00966 case PIX_FMT_BGR565:
00967 case PIX_FMT_BGR555:
00968 bits = 16;
00969 break;
00970 case PIX_FMT_UYYVYY411:
00971 bits = 12;
00972 break;
00973 default:
00974 bits = pf->depth * pf->nb_channels;
00975 break;
00976 }
00977 return (width * bits + 7) >> 3;
00978 break;
00979 case FF_PIXEL_PLANAR:
00980 if (plane == 1 || plane == 2)
00981 width= -((-width)>>pf->x_chroma_shift);
00982
00983 return (width * pf->depth + 7) >> 3;
00984 break;
00985 case FF_PIXEL_PALETTE:
00986 if (plane == 0)
00987 return width;
00988 break;
00989 }
00990
00991 return -1;
00992 }
00993
00994 void av_picture_copy(AVPicture *dst, const AVPicture *src,
00995 int pix_fmt, int width, int height)
00996 {
00997 int i;
00998 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
00999
01000 pf = &pix_fmt_info[pix_fmt];
01001 switch(pf->pixel_type) {
01002 case FF_PIXEL_PACKED:
01003 case FF_PIXEL_PLANAR:
01004 for(i = 0; i < pf->nb_channels; i++) {
01005 int h;
01006 int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
01007 h = height;
01008 if (i == 1 || i == 2) {
01009 h= -((-height)>>pf->y_chroma_shift);
01010 }
01011 ff_img_copy_plane(dst->data[i], dst->linesize[i],
01012 src->data[i], src->linesize[i],
01013 bwidth, h);
01014 }
01015 break;
01016 case FF_PIXEL_PALETTE:
01017 ff_img_copy_plane(dst->data[0], dst->linesize[0],
01018 src->data[0], src->linesize[0],
01019 width, height);
01020
01021 ff_img_copy_plane(dst->data[1], dst->linesize[1],
01022 src->data[1], src->linesize[1],
01023 4, 256);
01024 break;
01025 }
01026 }
01027
01028
01029
01030 static void yuyv422_to_yuv420p(AVPicture *dst, const AVPicture *src,
01031 int width, int height)
01032 {
01033 const uint8_t *p, *p1;
01034 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
01035 int w;
01036
01037 p1 = src->data[0];
01038 lum1 = dst->data[0];
01039 cb1 = dst->data[1];
01040 cr1 = dst->data[2];
01041
01042 for(;height >= 1; height -= 2) {
01043 p = p1;
01044 lum = lum1;
01045 cb = cb1;
01046 cr = cr1;
01047 for(w = width; w >= 2; w -= 2) {
01048 lum[0] = p[0];
01049 cb[0] = p[1];
01050 lum[1] = p[2];
01051 cr[0] = p[3];
01052 p += 4;
01053 lum += 2;
01054 cb++;
01055 cr++;
01056 }
01057 if (w) {
01058 lum[0] = p[0];
01059 cb[0] = p[1];
01060 cr[0] = p[3];
01061 cb++;
01062 cr++;
01063 }
01064 p1 += src->linesize[0];
01065 lum1 += dst->linesize[0];
01066 if (height>1) {
01067 p = p1;
01068 lum = lum1;
01069 for(w = width; w >= 2; w -= 2) {
01070 lum[0] = p[0];
01071 lum[1] = p[2];
01072 p += 4;
01073 lum += 2;
01074 }
01075 if (w) {
01076 lum[0] = p[0];
01077 }
01078 p1 += src->linesize[0];
01079 lum1 += dst->linesize[0];
01080 }
01081 cb1 += dst->linesize[1];
01082 cr1 += dst->linesize[2];
01083 }
01084 }
01085
01086 static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src,
01087 int width, int height)
01088 {
01089 const uint8_t *p, *p1;
01090 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
01091 int w;
01092
01093 p1 = src->data[0];
01094
01095 lum1 = dst->data[0];
01096 cb1 = dst->data[1];
01097 cr1 = dst->data[2];
01098
01099 for(;height >= 1; height -= 2) {
01100 p = p1;
01101 lum = lum1;
01102 cb = cb1;
01103 cr = cr1;
01104 for(w = width; w >= 2; w -= 2) {
01105 lum[0] = p[1];
01106 cb[0] = p[0];
01107 lum[1] = p[3];
01108 cr[0] = p[2];
01109 p += 4;
01110 lum += 2;
01111 cb++;
01112 cr++;
01113 }
01114 if (w) {
01115 lum[0] = p[1];
01116 cb[0] = p[0];
01117 cr[0] = p[2];
01118 cb++;
01119 cr++;
01120 }
01121 p1 += src->linesize[0];
01122 lum1 += dst->linesize[0];
01123 if (height>1) {
01124 p = p1;
01125 lum = lum1;
01126 for(w = width; w >= 2; w -= 2) {
01127 lum[0] = p[1];
01128 lum[1] = p[3];
01129 p += 4;
01130 lum += 2;
01131 }
01132 if (w) {
01133 lum[0] = p[1];
01134 }
01135 p1 += src->linesize[0];
01136 lum1 += dst->linesize[0];
01137 }
01138 cb1 += dst->linesize[1];
01139 cr1 += dst->linesize[2];
01140 }
01141 }
01142
01143
01144 static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src,
01145 int width, int height)
01146 {
01147 const uint8_t *p, *p1;
01148 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
01149 int w;
01150
01151 p1 = src->data[0];
01152 lum1 = dst->data[0];
01153 cb1 = dst->data[1];
01154 cr1 = dst->data[2];
01155 for(;height > 0; height--) {
01156 p = p1;
01157 lum = lum1;
01158 cb = cb1;
01159 cr = cr1;
01160 for(w = width; w >= 2; w -= 2) {
01161 lum[0] = p[1];
01162 cb[0] = p[0];
01163 lum[1] = p[3];
01164 cr[0] = p[2];
01165 p += 4;
01166 lum += 2;
01167 cb++;
01168 cr++;
01169 }
01170 p1 += src->linesize[0];
01171 lum1 += dst->linesize[0];
01172 cb1 += dst->linesize[1];
01173 cr1 += dst->linesize[2];
01174 }
01175 }
01176
01177
01178 static void yuyv422_to_yuv422p(AVPicture *dst, const AVPicture *src,
01179 int width, int height)
01180 {
01181 const uint8_t *p, *p1;
01182 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
01183 int w;
01184
01185 p1 = src->data[0];
01186 lum1 = dst->data[0];
01187 cb1 = dst->data[1];
01188 cr1 = dst->data[2];
01189 for(;height > 0; height--) {
01190 p = p1;
01191 lum = lum1;
01192 cb = cb1;
01193 cr = cr1;
01194 for(w = width; w >= 2; w -= 2) {
01195 lum[0] = p[0];
01196 cb[0] = p[1];
01197 lum[1] = p[2];
01198 cr[0] = p[3];
01199 p += 4;
01200 lum += 2;
01201 cb++;
01202 cr++;
01203 }
01204 p1 += src->linesize[0];
01205 lum1 += dst->linesize[0];
01206 cb1 += dst->linesize[1];
01207 cr1 += dst->linesize[2];
01208 }
01209 }
01210
01211 static void yuv422p_to_yuyv422(AVPicture *dst, const AVPicture *src,
01212 int width, int height)
01213 {
01214 uint8_t *p, *p1;
01215 const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
01216 int w;
01217
01218 p1 = dst->data[0];
01219 lum1 = src->data[0];
01220 cb1 = src->data[1];
01221 cr1 = src->data[2];
01222 for(;height > 0; height--) {
01223 p = p1;
01224 lum = lum1;
01225 cb = cb1;
01226 cr = cr1;
01227 for(w = width; w >= 2; w -= 2) {
01228 p[0] = lum[0];
01229 p[1] = cb[0];
01230 p[2] = lum[1];
01231 p[3] = cr[0];
01232 p += 4;
01233 lum += 2;
01234 cb++;
01235 cr++;
01236 }
01237 p1 += dst->linesize[0];
01238 lum1 += src->linesize[0];
01239 cb1 += src->linesize[1];
01240 cr1 += src->linesize[2];
01241 }
01242 }
01243
01244 static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src,
01245 int width, int height)
01246 {
01247 uint8_t *p, *p1;
01248 const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
01249 int w;
01250
01251 p1 = dst->data[0];
01252 lum1 = src->data[0];
01253 cb1 = src->data[1];
01254 cr1 = src->data[2];
01255 for(;height > 0; height--) {
01256 p = p1;
01257 lum = lum1;
01258 cb = cb1;
01259 cr = cr1;
01260 for(w = width; w >= 2; w -= 2) {
01261 p[1] = lum[0];
01262 p[0] = cb[0];
01263 p[3] = lum[1];
01264 p[2] = cr[0];
01265 p += 4;
01266 lum += 2;
01267 cb++;
01268 cr++;
01269 }
01270 p1 += dst->linesize[0];
01271 lum1 += src->linesize[0];
01272 cb1 += src->linesize[1];
01273 cr1 += src->linesize[2];
01274 }
01275 }
01276
01277 static void uyyvyy411_to_yuv411p(AVPicture *dst, const AVPicture *src,
01278 int width, int height)
01279 {
01280 const uint8_t *p, *p1;
01281 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
01282 int w;
01283
01284 p1 = src->data[0];
01285 lum1 = dst->data[0];
01286 cb1 = dst->data[1];
01287 cr1 = dst->data[2];
01288 for(;height > 0; height--) {
01289 p = p1;
01290 lum = lum1;
01291 cb = cb1;
01292 cr = cr1;
01293 for(w = width; w >= 4; w -= 4) {
01294 cb[0] = p[0];
01295 lum[0] = p[1];
01296 lum[1] = p[2];
01297 cr[0] = p[3];
01298 lum[2] = p[4];
01299 lum[3] = p[5];
01300 p += 6;
01301 lum += 4;
01302 cb++;
01303 cr++;
01304 }
01305 p1 += src->linesize[0];
01306 lum1 += dst->linesize[0];
01307 cb1 += dst->linesize[1];
01308 cr1 += dst->linesize[2];
01309 }
01310 }
01311
01312
01313 static void yuv420p_to_yuyv422(AVPicture *dst, const AVPicture *src,
01314 int width, int height)
01315 {
01316 int w, h;
01317 uint8_t *line1, *line2, *linesrc = dst->data[0];
01318 uint8_t *lum1, *lum2, *lumsrc = src->data[0];
01319 uint8_t *cb1, *cb2 = src->data[1];
01320 uint8_t *cr1, *cr2 = src->data[2];
01321
01322 for(h = height / 2; h--;) {
01323 line1 = linesrc;
01324 line2 = linesrc + dst->linesize[0];
01325
01326 lum1 = lumsrc;
01327 lum2 = lumsrc + src->linesize[0];
01328
01329 cb1 = cb2;
01330 cr1 = cr2;
01331
01332 for(w = width / 2; w--;) {
01333 *line1++ = *lum1++; *line2++ = *lum2++;
01334 *line1++ = *line2++ = *cb1++;
01335 *line1++ = *lum1++; *line2++ = *lum2++;
01336 *line1++ = *line2++ = *cr1++;
01337 }
01338
01339 linesrc += dst->linesize[0] * 2;
01340 lumsrc += src->linesize[0] * 2;
01341 cb2 += src->linesize[1];
01342 cr2 += src->linesize[2];
01343 }
01344 }
01345
01346 static void yuv420p_to_uyvy422(AVPicture *dst, const AVPicture *src,
01347 int width, int height)
01348 {
01349 int w, h;
01350 uint8_t *line1, *line2, *linesrc = dst->data[0];
01351 uint8_t *lum1, *lum2, *lumsrc = src->data[0];
01352 uint8_t *cb1, *cb2 = src->data[1];
01353 uint8_t *cr1, *cr2 = src->data[2];
01354
01355 for(h = height / 2; h--;) {
01356 line1 = linesrc;
01357 line2 = linesrc + dst->linesize[0];
01358
01359 lum1 = lumsrc;
01360 lum2 = lumsrc + src->linesize[0];
01361
01362 cb1 = cb2;
01363 cr1 = cr2;
01364
01365 for(w = width / 2; w--;) {
01366 *line1++ = *line2++ = *cb1++;
01367 *line1++ = *lum1++; *line2++ = *lum2++;
01368 *line1++ = *line2++ = *cr1++;
01369 *line1++ = *lum1++; *line2++ = *lum2++;
01370 }
01371
01372 linesrc += dst->linesize[0] * 2;
01373 lumsrc += src->linesize[0] * 2;
01374 cb2 += src->linesize[1];
01375 cr2 += src->linesize[2];
01376 }
01377 }
01378
01379
01380 void ff_shrink22(uint8_t *dst, int dst_wrap,
01381 const uint8_t *src, int src_wrap,
01382 int width, int height)
01383 {
01384 int w;
01385 const uint8_t *s1, *s2;
01386 uint8_t *d;
01387
01388 for(;height > 0; height--) {
01389 s1 = src;
01390 s2 = s1 + src_wrap;
01391 d = dst;
01392 for(w = width;w >= 4; w-=4) {
01393 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
01394 d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
01395 d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
01396 d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
01397 s1 += 8;
01398 s2 += 8;
01399 d += 4;
01400 }
01401 for(;w > 0; w--) {
01402 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
01403 s1 += 2;
01404 s2 += 2;
01405 d++;
01406 }
01407 src += 2 * src_wrap;
01408 dst += dst_wrap;
01409 }
01410 }
01411
01412
01413 void ff_shrink44(uint8_t *dst, int dst_wrap,
01414 const uint8_t *src, int src_wrap,
01415 int width, int height)
01416 {
01417 int w;
01418 const uint8_t *s1, *s2, *s3, *s4;
01419 uint8_t *d;
01420
01421 for(;height > 0; height--) {
01422 s1 = src;
01423 s2 = s1 + src_wrap;
01424 s3 = s2 + src_wrap;
01425 s4 = s3 + src_wrap;
01426 d = dst;
01427 for(w = width;w > 0; w--) {
01428 d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
01429 s2[0] + s2[1] + s2[2] + s2[3] +
01430 s3[0] + s3[1] + s3[2] + s3[3] +
01431 s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
01432 s1 += 4;
01433 s2 += 4;
01434 s3 += 4;
01435 s4 += 4;
01436 d++;
01437 }
01438 src += 4 * src_wrap;
01439 dst += dst_wrap;
01440 }
01441 }
01442
01443
01444 void ff_shrink88(uint8_t *dst, int dst_wrap,
01445 const uint8_t *src, int src_wrap,
01446 int width, int height)
01447 {
01448 int w, i;
01449
01450 for(;height > 0; height--) {
01451 for(w = width;w > 0; w--) {
01452 int tmp=0;
01453 for(i=0; i<8; i++){
01454 tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
01455 src += src_wrap;
01456 }
01457 *(dst++) = (tmp + 32)>>6;
01458 src += 8 - 8*src_wrap;
01459 }
01460 src += 8*src_wrap - 8*width;
01461 dst += dst_wrap - width;
01462 }
01463 }
01464
01465
01466
01467 #define TRANSP_INDEX (6*6*6)
01468
01469
01470 static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
01471 {
01472 return (((r) / 47) % 6) * 6 * 6 + (((g) / 47) % 6) * 6 + (((b) / 47) % 6);
01473 }
01474
01475 static void build_rgb_palette(uint8_t *palette, int has_alpha)
01476 {
01477 uint32_t *pal;
01478 static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
01479 int i, r, g, b;
01480
01481 pal = (uint32_t *)palette;
01482 i = 0;
01483 for(r = 0; r < 6; r++) {
01484 for(g = 0; g < 6; g++) {
01485 for(b = 0; b < 6; b++) {
01486 pal[i++] = (0xff << 24) | (pal_value[r] << 16) |
01487 (pal_value[g] << 8) | pal_value[b];
01488 }
01489 }
01490 }
01491 if (has_alpha)
01492 pal[i++] = 0;
01493 while (i < 256)
01494 pal[i++] = 0xff000000;
01495 }
01496
01497
01498 static inline unsigned int bitcopy_n(unsigned int a, int n)
01499 {
01500 int mask;
01501 mask = (1 << n) - 1;
01502 return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
01503 }
01504
01505
01506
01507 #define RGB_NAME rgb555
01508
01509 #define RGB_IN(r, g, b, s)\
01510 {\
01511 unsigned int v = ((const uint16_t *)(s))[0];\
01512 r = bitcopy_n(v >> (10 - 3), 3);\
01513 g = bitcopy_n(v >> (5 - 3), 3);\
01514 b = bitcopy_n(v << 3, 3);\
01515 }
01516
01517
01518 #define RGB_OUT(d, r, g, b)\
01519 {\
01520 ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);\
01521 }
01522
01523 #define BPP 2
01524
01525 #include "imgconvert_template.c"
01526
01527
01528
01529 #define RGB_NAME rgb565
01530
01531 #define RGB_IN(r, g, b, s)\
01532 {\
01533 unsigned int v = ((const uint16_t *)(s))[0];\
01534 r = bitcopy_n(v >> (11 - 3), 3);\
01535 g = bitcopy_n(v >> (5 - 2), 2);\
01536 b = bitcopy_n(v << 3, 3);\
01537 }
01538
01539 #define RGB_OUT(d, r, g, b)\
01540 {\
01541 ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\
01542 }
01543
01544 #define BPP 2
01545
01546 #include "imgconvert_template.c"
01547
01548
01549
01550 #define RGB_NAME bgr24
01551
01552 #define RGB_IN(r, g, b, s)\
01553 {\
01554 b = (s)[0];\
01555 g = (s)[1];\
01556 r = (s)[2];\
01557 }
01558
01559 #define RGB_OUT(d, r, g, b)\
01560 {\
01561 (d)[0] = b;\
01562 (d)[1] = g;\
01563 (d)[2] = r;\
01564 }
01565
01566 #define BPP 3
01567
01568 #include "imgconvert_template.c"
01569
01570 #undef RGB_IN
01571 #undef RGB_OUT
01572 #undef BPP
01573
01574
01575
01576 #define RGB_NAME rgb24
01577 #define FMT_RGB24
01578
01579 #define RGB_IN(r, g, b, s)\
01580 {\
01581 r = (s)[0];\
01582 g = (s)[1];\
01583 b = (s)[2];\
01584 }
01585
01586 #define RGB_OUT(d, r, g, b)\
01587 {\
01588 (d)[0] = r;\
01589 (d)[1] = g;\
01590 (d)[2] = b;\
01591 }
01592
01593 #define BPP 3
01594
01595 #include "imgconvert_template.c"
01596
01597
01598
01599 #define RGB_NAME rgb32
01600 #define FMT_RGB32
01601
01602 #define RGB_IN(r, g, b, s)\
01603 {\
01604 unsigned int v = ((const uint32_t *)(s))[0];\
01605 r = (v >> 16) & 0xff;\
01606 g = (v >> 8) & 0xff;\
01607 b = v & 0xff;\
01608 }
01609
01610 #define RGBA_IN(r, g, b, a, s)\
01611 {\
01612 unsigned int v = ((const uint32_t *)(s))[0];\
01613 a = (v >> 24) & 0xff;\
01614 r = (v >> 16) & 0xff;\
01615 g = (v >> 8) & 0xff;\
01616 b = v & 0xff;\
01617 }
01618
01619 #define RGBA_OUT(d, r, g, b, a)\
01620 {\
01621 ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\
01622 }
01623
01624 #define BPP 4
01625
01626 #include "imgconvert_template.c"
01627
01628 static void mono_to_gray(AVPicture *dst, const AVPicture *src,
01629 int width, int height, int xor_mask)
01630 {
01631 const unsigned char *p;
01632 unsigned char *q;
01633 int v, dst_wrap, src_wrap;
01634 int y, w;
01635
01636 p = src->data[0];
01637 src_wrap = src->linesize[0] - ((width + 7) >> 3);
01638
01639 q = dst->data[0];
01640 dst_wrap = dst->linesize[0] - width;
01641 for(y=0;y<height;y++) {
01642 w = width;
01643 while (w >= 8) {
01644 v = *p++ ^ xor_mask;
01645 q[0] = -(v >> 7);
01646 q[1] = -((v >> 6) & 1);
01647 q[2] = -((v >> 5) & 1);
01648 q[3] = -((v >> 4) & 1);
01649 q[4] = -((v >> 3) & 1);
01650 q[5] = -((v >> 2) & 1);
01651 q[6] = -((v >> 1) & 1);
01652 q[7] = -((v >> 0) & 1);
01653 w -= 8;
01654 q += 8;
01655 }
01656 if (w > 0) {
01657 v = *p++ ^ xor_mask;
01658 do {
01659 q[0] = -((v >> 7) & 1);
01660 q++;
01661 v <<= 1;
01662 } while (--w);
01663 }
01664 p += src_wrap;
01665 q += dst_wrap;
01666 }
01667 }
01668
01669 static void monowhite_to_gray(AVPicture *dst, const AVPicture *src,
01670 int width, int height)
01671 {
01672 mono_to_gray(dst, src, width, height, 0xff);
01673 }
01674
01675 static void monoblack_to_gray(AVPicture *dst, const AVPicture *src,
01676 int width, int height)
01677 {
01678 mono_to_gray(dst, src, width, height, 0x00);
01679 }
01680
01681 static void gray_to_mono(AVPicture *dst, const AVPicture *src,
01682 int width, int height, int xor_mask)
01683 {
01684 int n;
01685 const uint8_t *s;
01686 uint8_t *d;
01687 int j, b, v, n1, src_wrap, dst_wrap, y;
01688
01689 s = src->data[0];
01690 src_wrap = src->linesize[0] - width;
01691
01692 d = dst->data[0];
01693 dst_wrap = dst->linesize[0] - ((width + 7) >> 3);
01694
01695 for(y=0;y<height;y++) {
01696 n = width;
01697 while (n >= 8) {
01698 v = 0;
01699 for(j=0;j<8;j++) {
01700 b = s[0];
01701 s++;
01702 v = (v << 1) | (b >> 7);
01703 }
01704 d[0] = v ^ xor_mask;
01705 d++;
01706 n -= 8;
01707 }
01708 if (n > 0) {
01709 n1 = n;
01710 v = 0;
01711 while (n > 0) {
01712 b = s[0];
01713 s++;
01714 v = (v << 1) | (b >> 7);
01715 n--;
01716 }
01717 d[0] = (v << (8 - (n1 & 7))) ^ xor_mask;
01718 d++;
01719 }
01720 s += src_wrap;
01721 d += dst_wrap;
01722 }
01723 }
01724
01725 static void gray_to_monowhite(AVPicture *dst, const AVPicture *src,
01726 int width, int height)
01727 {
01728 gray_to_mono(dst, src, width, height, 0xff);
01729 }
01730
01731 static void gray_to_monoblack(AVPicture *dst, const AVPicture *src,
01732 int width, int height)
01733 {
01734 gray_to_mono(dst, src, width, height, 0x00);
01735 }
01736
01737 static void gray_to_gray16(AVPicture *dst, const AVPicture *src,
01738 int width, int height)
01739 {
01740 int x, y, src_wrap, dst_wrap;
01741 uint8_t *s, *d;
01742 s = src->data[0];
01743 src_wrap = src->linesize[0] - width;
01744 d = dst->data[0];
01745 dst_wrap = dst->linesize[0] - width * 2;
01746 for(y=0; y<height; y++){
01747 for(x=0; x<width; x++){
01748 *d++ = *s;
01749 *d++ = *s++;
01750 }
01751 s += src_wrap;
01752 d += dst_wrap;
01753 }
01754 }
01755
01756 static void gray16_to_gray(AVPicture *dst, const AVPicture *src,
01757 int width, int height)
01758 {
01759 int x, y, src_wrap, dst_wrap;
01760 uint8_t *s, *d;
01761 s = src->data[0];
01762 src_wrap = src->linesize[0] - width * 2;
01763 d = dst->data[0];
01764 dst_wrap = dst->linesize[0] - width;
01765 for(y=0; y<height; y++){
01766 for(x=0; x<width; x++){
01767 *d++ = *s;
01768 s += 2;
01769 }
01770 s += src_wrap;
01771 d += dst_wrap;
01772 }
01773 }
01774
01775 static void gray16be_to_gray(AVPicture *dst, const AVPicture *src,
01776 int width, int height)
01777 {
01778 gray16_to_gray(dst, src, width, height);
01779 }
01780
01781 static void gray16le_to_gray(AVPicture *dst, const AVPicture *src,
01782 int width, int height)
01783 {
01784 AVPicture tmpsrc = *src;
01785 tmpsrc.data[0]++;
01786 gray16_to_gray(dst, &tmpsrc, width, height);
01787 }
01788
01789 static void gray16_to_gray16(AVPicture *dst, const AVPicture *src,
01790 int width, int height)
01791 {
01792 int x, y, src_wrap, dst_wrap;
01793 uint16_t *s, *d;
01794 s = (uint16_t*)src->data[0];
01795 src_wrap = (src->linesize[0] - width * 2)/2;
01796 d = (uint16_t*)dst->data[0];
01797 dst_wrap = (dst->linesize[0] - width * 2)/2;
01798 for(y=0; y<height; y++){
01799 for(x=0; x<width; x++){
01800 *d++ = bswap_16(*s++);
01801 }
01802 s += src_wrap;
01803 d += dst_wrap;
01804 }
01805 }
01806
01807
01808 typedef struct ConvertEntry {
01809 void (*convert)(AVPicture *dst,
01810 const AVPicture *src, int width, int height);
01811 } ConvertEntry;
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830 static const ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
01831 [PIX_FMT_YUV420P] = {
01832 [PIX_FMT_YUYV422] = {
01833 .convert = yuv420p_to_yuyv422,
01834 },
01835 [PIX_FMT_RGB555] = {
01836 .convert = yuv420p_to_rgb555
01837 },
01838 [PIX_FMT_RGB565] = {
01839 .convert = yuv420p_to_rgb565
01840 },
01841 [PIX_FMT_BGR24] = {
01842 .convert = yuv420p_to_bgr24
01843 },
01844 [PIX_FMT_RGB24] = {
01845 .convert = yuv420p_to_rgb24
01846 },
01847 [PIX_FMT_RGB32] = {
01848 .convert = yuv420p_to_rgb32
01849 },
01850 [PIX_FMT_UYVY422] = {
01851 .convert = yuv420p_to_uyvy422,
01852 },
01853 },
01854 [PIX_FMT_YUV422P] = {
01855 [PIX_FMT_YUYV422] = {
01856 .convert = yuv422p_to_yuyv422,
01857 },
01858 [PIX_FMT_UYVY422] = {
01859 .convert = yuv422p_to_uyvy422,
01860 },
01861 },
01862 [PIX_FMT_YUV444P] = {
01863 [PIX_FMT_RGB24] = {
01864 .convert = yuv444p_to_rgb24
01865 },
01866 },
01867 [PIX_FMT_YUVJ420P] = {
01868 [PIX_FMT_RGB555] = {
01869 .convert = yuvj420p_to_rgb555
01870 },
01871 [PIX_FMT_RGB565] = {
01872 .convert = yuvj420p_to_rgb565
01873 },
01874 [PIX_FMT_BGR24] = {
01875 .convert = yuvj420p_to_bgr24
01876 },
01877 [PIX_FMT_RGB24] = {
01878 .convert = yuvj420p_to_rgb24
01879 },
01880 [PIX_FMT_RGB32] = {
01881 .convert = yuvj420p_to_rgb32
01882 },
01883 },
01884 [PIX_FMT_YUVJ444P] = {
01885 [PIX_FMT_RGB24] = {
01886 .convert = yuvj444p_to_rgb24
01887 },
01888 },
01889 [PIX_FMT_YUYV422] = {
01890 [PIX_FMT_YUV420P] = {
01891 .convert = yuyv422_to_yuv420p,
01892 },
01893 [PIX_FMT_YUV422P] = {
01894 .convert = yuyv422_to_yuv422p,
01895 },
01896 },
01897 [PIX_FMT_UYVY422] = {
01898 [PIX_FMT_YUV420P] = {
01899 .convert = uyvy422_to_yuv420p,
01900 },
01901 [PIX_FMT_YUV422P] = {
01902 .convert = uyvy422_to_yuv422p,
01903 },
01904 },
01905 [PIX_FMT_RGB24] = {
01906 [PIX_FMT_YUV420P] = {
01907 .convert = rgb24_to_yuv420p
01908 },
01909 [PIX_FMT_RGB565] = {
01910 .convert = rgb24_to_rgb565
01911 },
01912 [PIX_FMT_RGB555] = {
01913 .convert = rgb24_to_rgb555
01914 },
01915 [PIX_FMT_RGB32] = {
01916 .convert = rgb24_to_rgb32
01917 },
01918 [PIX_FMT_BGR24] = {
01919 .convert = rgb24_to_bgr24
01920 },
01921 [PIX_FMT_GRAY8] = {
01922 .convert = rgb24_to_gray
01923 },
01924 [PIX_FMT_PAL8] = {
01925 .convert = rgb24_to_pal8
01926 },
01927 [PIX_FMT_YUV444P] = {
01928 .convert = rgb24_to_yuv444p
01929 },
01930 [PIX_FMT_YUVJ420P] = {
01931 .convert = rgb24_to_yuvj420p
01932 },
01933 [PIX_FMT_YUVJ444P] = {
01934 .convert = rgb24_to_yuvj444p
01935 },
01936 },
01937 [PIX_FMT_RGB32] = {
01938 [PIX_FMT_RGB24] = {
01939 .convert = rgb32_to_rgb24
01940 },
01941 [PIX_FMT_BGR24] = {
01942 .convert = rgb32_to_bgr24
01943 },
01944 [PIX_FMT_RGB565] = {
01945 .convert = rgb32_to_rgb565
01946 },
01947 [PIX_FMT_RGB555] = {
01948 .convert = rgb32_to_rgb555
01949 },
01950 [PIX_FMT_PAL8] = {
01951 .convert = rgb32_to_pal8
01952 },
01953 [PIX_FMT_YUV420P] = {
01954 .convert = rgb32_to_yuv420p
01955 },
01956 [PIX_FMT_GRAY8] = {
01957 .convert = rgb32_to_gray
01958 },
01959 },
01960 [PIX_FMT_BGR24] = {
01961 [PIX_FMT_RGB32] = {
01962 .convert = bgr24_to_rgb32
01963 },
01964 [PIX_FMT_RGB24] = {
01965 .convert = bgr24_to_rgb24
01966 },
01967 [PIX_FMT_YUV420P] = {
01968 .convert = bgr24_to_yuv420p
01969 },
01970 [PIX_FMT_GRAY8] = {
01971 .convert = bgr24_to_gray
01972 },
01973 },
01974 [PIX_FMT_RGB555] = {
01975 [PIX_FMT_RGB24] = {
01976 .convert = rgb555_to_rgb24
01977 },
01978 [PIX_FMT_RGB32] = {
01979 .convert = rgb555_to_rgb32
01980 },
01981 [PIX_FMT_YUV420P] = {
01982 .convert = rgb555_to_yuv420p
01983 },
01984 [PIX_FMT_GRAY8] = {
01985 .convert = rgb555_to_gray
01986 },
01987 },
01988 [PIX_FMT_RGB565] = {
01989 [PIX_FMT_RGB32] = {
01990 .convert = rgb565_to_rgb32
01991 },
01992 [PIX_FMT_RGB24] = {
01993 .convert = rgb565_to_rgb24
01994 },
01995 [PIX_FMT_YUV420P] = {
01996 .convert = rgb565_to_yuv420p
01997 },
01998 [PIX_FMT_GRAY8] = {
01999 .convert = rgb565_to_gray
02000 },
02001 },
02002 [PIX_FMT_GRAY16BE] = {
02003 [PIX_FMT_GRAY8] = {
02004 .convert = gray16be_to_gray
02005 },
02006 [PIX_FMT_GRAY16LE] = {
02007 .convert = gray16_to_gray16
02008 },
02009 },
02010 [PIX_FMT_GRAY16LE] = {
02011 [PIX_FMT_GRAY8] = {
02012 .convert = gray16le_to_gray
02013 },
02014 [PIX_FMT_GRAY16BE] = {
02015 .convert = gray16_to_gray16
02016 },
02017 },
02018 [PIX_FMT_GRAY8] = {
02019 [PIX_FMT_RGB555] = {
02020 .convert = gray_to_rgb555
02021 },
02022 [PIX_FMT_RGB565] = {
02023 .convert = gray_to_rgb565
02024 },
02025 [PIX_FMT_RGB24] = {
02026 .convert = gray_to_rgb24
02027 },
02028 [PIX_FMT_BGR24] = {
02029 .convert = gray_to_bgr24
02030 },
02031 [PIX_FMT_RGB32] = {
02032 .convert = gray_to_rgb32
02033 },
02034 [PIX_FMT_MONOWHITE] = {
02035 .convert = gray_to_monowhite
02036 },
02037 [PIX_FMT_MONOBLACK] = {
02038 .convert = gray_to_monoblack
02039 },
02040 [PIX_FMT_GRAY16LE] = {
02041 .convert = gray_to_gray16
02042 },
02043 [PIX_FMT_GRAY16BE] = {
02044 .convert = gray_to_gray16
02045 },
02046 },
02047 [PIX_FMT_MONOWHITE] = {
02048 [PIX_FMT_GRAY8] = {
02049 .convert = monowhite_to_gray
02050 },
02051 },
02052 [PIX_FMT_MONOBLACK] = {
02053 [PIX_FMT_GRAY8] = {
02054 .convert = monoblack_to_gray
02055 },
02056 },
02057 [PIX_FMT_PAL8] = {
02058 [PIX_FMT_RGB555] = {
02059 .convert = pal8_to_rgb555
02060 },
02061 [PIX_FMT_RGB565] = {
02062 .convert = pal8_to_rgb565
02063 },
02064 [PIX_FMT_BGR24] = {
02065 .convert = pal8_to_bgr24
02066 },
02067 [PIX_FMT_RGB24] = {
02068 .convert = pal8_to_rgb24
02069 },
02070 [PIX_FMT_RGB32] = {
02071 .convert = pal8_to_rgb32
02072 },
02073 },
02074 [PIX_FMT_UYYVYY411] = {
02075 [PIX_FMT_YUV411P] = {
02076 .convert = uyyvyy411_to_yuv411p,
02077 },
02078 },
02079
02080 };
02081
02082 int avpicture_alloc(AVPicture *picture,
02083 int pix_fmt, int width, int height)
02084 {
02085 int size;
02086 void *ptr;
02087
02088 size = avpicture_get_size(pix_fmt, width, height);
02089 if(size<0)
02090 goto fail;
02091 ptr = av_malloc(size);
02092 if (!ptr)
02093 goto fail;
02094 avpicture_fill(picture, ptr, pix_fmt, width, height);
02095 if(picture->data[1] && !picture->data[2])
02096 ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
02097
02098 return 0;
02099 fail:
02100 memset(picture, 0, sizeof(AVPicture));
02101 return -1;
02102 }
02103
02104 void avpicture_free(AVPicture *picture)
02105 {
02106 av_free(picture->data[0]);
02107 }
02108
02109
02110 static inline int is_yuv_planar(const PixFmtInfo *ps)
02111 {
02112 return (ps->color_type == FF_COLOR_YUV ||
02113 ps->color_type == FF_COLOR_YUV_JPEG) &&
02114 ps->pixel_type == FF_PIXEL_PLANAR;
02115 }
02116
02117 int av_picture_crop(AVPicture *dst, const AVPicture *src,
02118 int pix_fmt, int top_band, int left_band)
02119 {
02120 int y_shift;
02121 int x_shift;
02122
02123 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
02124 return -1;
02125
02126 y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
02127 x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
02128
02129 dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
02130 dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
02131 dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
02132
02133 dst->linesize[0] = src->linesize[0];
02134 dst->linesize[1] = src->linesize[1];
02135 dst->linesize[2] = src->linesize[2];
02136 return 0;
02137 }
02138
02139 int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
02140 int pix_fmt, int padtop, int padbottom, int padleft, int padright,
02141 int *color)
02142 {
02143 uint8_t *optr;
02144 int y_shift;
02145 int x_shift;
02146 int yheight;
02147 int i, y;
02148
02149 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
02150 !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
02151
02152 for (i = 0; i < 3; i++) {
02153 x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0;
02154 y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0;
02155
02156 if (padtop || padleft) {
02157 memset(dst->data[i], color[i],
02158 dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
02159 }
02160
02161 if (padleft || padright) {
02162 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
02163 (dst->linesize[i] - (padright >> x_shift));
02164 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
02165 for (y = 0; y < yheight; y++) {
02166 memset(optr, color[i], (padleft + padright) >> x_shift);
02167 optr += dst->linesize[i];
02168 }
02169 }
02170
02171 if (src) {
02172 uint8_t *iptr = src->data[i];
02173 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
02174 (padleft >> x_shift);
02175 memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
02176 iptr += src->linesize[i];
02177 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
02178 (dst->linesize[i] - (padright >> x_shift));
02179 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
02180 for (y = 0; y < yheight; y++) {
02181 memset(optr, color[i], (padleft + padright) >> x_shift);
02182 memcpy(optr + ((padleft + padright) >> x_shift), iptr,
02183 (width - padleft - padright) >> x_shift);
02184 iptr += src->linesize[i];
02185 optr += dst->linesize[i];
02186 }
02187 }
02188
02189 if (padbottom || padright) {
02190 optr = dst->data[i] + dst->linesize[i] *
02191 ((height - padbottom) >> y_shift) - (padright >> x_shift);
02192 memset(optr, color[i],dst->linesize[i] *
02193 (padbottom >> y_shift) + (padright >> x_shift));
02194 }
02195 }
02196 return 0;
02197 }
02198
02199 #if !CONFIG_SWSCALE
02200 static uint8_t y_ccir_to_jpeg[256];
02201 static uint8_t y_jpeg_to_ccir[256];
02202 static uint8_t c_ccir_to_jpeg[256];
02203 static uint8_t c_jpeg_to_ccir[256];
02204
02205
02206 static av_cold void img_convert_init(void)
02207 {
02208 int i;
02209 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
02210
02211 for(i = 0;i < 256; i++) {
02212 y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i);
02213 y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i);
02214 c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i);
02215 c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i);
02216 }
02217 }
02218
02219
02220 static void img_apply_table(uint8_t *dst, int dst_wrap,
02221 const uint8_t *src, int src_wrap,
02222 int width, int height, const uint8_t *table1)
02223 {
02224 int n;
02225 const uint8_t *s;
02226 uint8_t *d;
02227 const uint8_t *table;
02228
02229 table = table1;
02230 for(;height > 0; height--) {
02231 s = src;
02232 d = dst;
02233 n = width;
02234 while (n >= 4) {
02235 d[0] = table[s[0]];
02236 d[1] = table[s[1]];
02237 d[2] = table[s[2]];
02238 d[3] = table[s[3]];
02239 d += 4;
02240 s += 4;
02241 n -= 4;
02242 }
02243 while (n > 0) {
02244 d[0] = table[s[0]];
02245 d++;
02246 s++;
02247 n--;
02248 }
02249 dst += dst_wrap;
02250 src += src_wrap;
02251 }
02252 }
02253
02254
02255
02256
02257
02258 static void shrink41(uint8_t *dst, int dst_wrap,
02259 const uint8_t *src, int src_wrap,
02260 int width, int height)
02261 {
02262 int w;
02263 const uint8_t *s;
02264 uint8_t *d;
02265
02266 for(;height > 0; height--) {
02267 s = src;
02268 d = dst;
02269 for(w = width;w > 0; w--) {
02270 d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2;
02271 s += 4;
02272 d++;
02273 }
02274 src += src_wrap;
02275 dst += dst_wrap;
02276 }
02277 }
02278
02279
02280 static void shrink21(uint8_t *dst, int dst_wrap,
02281 const uint8_t *src, int src_wrap,
02282 int width, int height)
02283 {
02284 int w;
02285 const uint8_t *s;
02286 uint8_t *d;
02287
02288 for(;height > 0; height--) {
02289 s = src;
02290 d = dst;
02291 for(w = width;w > 0; w--) {
02292 d[0] = (s[0] + s[1]) >> 1;
02293 s += 2;
02294 d++;
02295 }
02296 src += src_wrap;
02297 dst += dst_wrap;
02298 }
02299 }
02300
02301
02302 static void shrink12(uint8_t *dst, int dst_wrap,
02303 const uint8_t *src, int src_wrap,
02304 int width, int height)
02305 {
02306 int w;
02307 uint8_t *d;
02308 const uint8_t *s1, *s2;
02309
02310 for(;height > 0; height--) {
02311 s1 = src;
02312 s2 = s1 + src_wrap;
02313 d = dst;
02314 for(w = width;w >= 4; w-=4) {
02315 d[0] = (s1[0] + s2[0]) >> 1;
02316 d[1] = (s1[1] + s2[1]) >> 1;
02317 d[2] = (s1[2] + s2[2]) >> 1;
02318 d[3] = (s1[3] + s2[3]) >> 1;
02319 s1 += 4;
02320 s2 += 4;
02321 d += 4;
02322 }
02323 for(;w > 0; w--) {
02324 d[0] = (s1[0] + s2[0]) >> 1;
02325 s1++;
02326 s2++;
02327 d++;
02328 }
02329 src += 2 * src_wrap;
02330 dst += dst_wrap;
02331 }
02332 }
02333
02334 static void grow21_line(uint8_t *dst, const uint8_t *src,
02335 int width)
02336 {
02337 int w;
02338 const uint8_t *s1;
02339 uint8_t *d;
02340
02341 s1 = src;
02342 d = dst;
02343 for(w = width;w >= 4; w-=4) {
02344 d[1] = d[0] = s1[0];
02345 d[3] = d[2] = s1[1];
02346 s1 += 2;
02347 d += 4;
02348 }
02349 for(;w >= 2; w -= 2) {
02350 d[1] = d[0] = s1[0];
02351 s1 ++;
02352 d += 2;
02353 }
02354
02355
02356 if (w) {
02357 d[0] = s1[0];
02358 }
02359 }
02360
02361 static void grow41_line(uint8_t *dst, const uint8_t *src,
02362 int width)
02363 {
02364 int w, v;
02365 const uint8_t *s1;
02366 uint8_t *d;
02367
02368 s1 = src;
02369 d = dst;
02370 for(w = width;w >= 4; w-=4) {
02371 v = s1[0];
02372 d[0] = v;
02373 d[1] = v;
02374 d[2] = v;
02375 d[3] = v;
02376 s1 ++;
02377 d += 4;
02378 }
02379 }
02380
02381
02382 static void grow21(uint8_t *dst, int dst_wrap,
02383 const uint8_t *src, int src_wrap,
02384 int width, int height)
02385 {
02386 for(;height > 0; height--) {
02387 grow21_line(dst, src, width);
02388 src += src_wrap;
02389 dst += dst_wrap;
02390 }
02391 }
02392
02393
02394 static void grow12(uint8_t *dst, int dst_wrap,
02395 const uint8_t *src, int src_wrap,
02396 int width, int height)
02397 {
02398 for(;height > 0; height-=2) {
02399 memcpy(dst, src, width);
02400 dst += dst_wrap;
02401 memcpy(dst, src, width);
02402 dst += dst_wrap;
02403 src += src_wrap;
02404 }
02405 }
02406
02407
02408 static void grow22(uint8_t *dst, int dst_wrap,
02409 const uint8_t *src, int src_wrap,
02410 int width, int height)
02411 {
02412 for(;height > 0; height--) {
02413 grow21_line(dst, src, width);
02414 if (height%2)
02415 src += src_wrap;
02416 dst += dst_wrap;
02417 }
02418 }
02419
02420
02421 static void grow41(uint8_t *dst, int dst_wrap,
02422 const uint8_t *src, int src_wrap,
02423 int width, int height)
02424 {
02425 for(;height > 0; height--) {
02426 grow41_line(dst, src, width);
02427 src += src_wrap;
02428 dst += dst_wrap;
02429 }
02430 }
02431
02432
02433 static void grow44(uint8_t *dst, int dst_wrap,
02434 const uint8_t *src, int src_wrap,
02435 int width, int height)
02436 {
02437 for(;height > 0; height--) {
02438 grow41_line(dst, src, width);
02439 if ((height & 3) == 1)
02440 src += src_wrap;
02441 dst += dst_wrap;
02442 }
02443 }
02444
02445
02446 static void conv411(uint8_t *dst, int dst_wrap,
02447 const uint8_t *src, int src_wrap,
02448 int width, int height)
02449 {
02450 int w, c;
02451 const uint8_t *s1, *s2;
02452 uint8_t *d;
02453
02454 width>>=1;
02455
02456 for(;height > 0; height--) {
02457 s1 = src;
02458 s2 = src + src_wrap;
02459 d = dst;
02460 for(w = width;w > 0; w--) {
02461 c = (s1[0] + s2[0]) >> 1;
02462 d[0] = c;
02463 d[1] = c;
02464 s1++;
02465 s2++;
02466 d += 2;
02467 }
02468 src += src_wrap * 2;
02469 dst += dst_wrap;
02470 }
02471 }
02472
02473
02474 int img_convert(AVPicture *dst, int dst_pix_fmt,
02475 const AVPicture *src, int src_pix_fmt,
02476 int src_width, int src_height)
02477 {
02478 static int initialized;
02479 int i, ret, dst_width, dst_height, int_pix_fmt;
02480 const PixFmtInfo *src_pix, *dst_pix;
02481 const ConvertEntry *ce;
02482 AVPicture tmp1, *tmp = &tmp1;
02483
02484 if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
02485 dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
02486 return -1;
02487 if (src_width <= 0 || src_height <= 0)
02488 return 0;
02489
02490 if (!initialized) {
02491 initialized = 1;
02492 img_convert_init();
02493 }
02494
02495 dst_width = src_width;
02496 dst_height = src_height;
02497
02498 dst_pix = &pix_fmt_info[dst_pix_fmt];
02499 src_pix = &pix_fmt_info[src_pix_fmt];
02500 if (src_pix_fmt == dst_pix_fmt) {
02501
02502 av_picture_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
02503 return 0;
02504 }
02505
02506 ce = &convert_table[src_pix_fmt][dst_pix_fmt];
02507 if (ce->convert) {
02508
02509 ce->convert(dst, src, dst_width, dst_height);
02510 return 0;
02511 }
02512
02513
02514 if (is_yuv_planar(dst_pix) &&
02515 src_pix_fmt == PIX_FMT_GRAY8) {
02516 int w, h, y;
02517 uint8_t *d;
02518
02519 if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
02520 ff_img_copy_plane(dst->data[0], dst->linesize[0],
02521 src->data[0], src->linesize[0],
02522 dst_width, dst_height);
02523 } else {
02524 img_apply_table(dst->data[0], dst->linesize[0],
02525 src->data[0], src->linesize[0],
02526 dst_width, dst_height,
02527 y_jpeg_to_ccir);
02528 }
02529
02530 w = dst_width;
02531 h = dst_height;
02532 w >>= dst_pix->x_chroma_shift;
02533 h >>= dst_pix->y_chroma_shift;
02534 for(i = 1; i <= 2; i++) {
02535 d = dst->data[i];
02536 for(y = 0; y< h; y++) {
02537 memset(d, 128, w);
02538 d += dst->linesize[i];
02539 }
02540 }
02541 return 0;
02542 }
02543
02544
02545 if (is_yuv_planar(src_pix) &&
02546 dst_pix_fmt == PIX_FMT_GRAY8) {
02547 if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
02548 ff_img_copy_plane(dst->data[0], dst->linesize[0],
02549 src->data[0], src->linesize[0],
02550 dst_width, dst_height);
02551 } else {
02552 img_apply_table(dst->data[0], dst->linesize[0],
02553 src->data[0], src->linesize[0],
02554 dst_width, dst_height,
02555 y_ccir_to_jpeg);
02556 }
02557 return 0;
02558 }
02559
02560
02561 if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {
02562 int x_shift, y_shift, w, h, xy_shift;
02563 void (*resize_func)(uint8_t *dst, int dst_wrap,
02564 const uint8_t *src, int src_wrap,
02565 int width, int height);
02566
02567
02568 w = dst_width;
02569 h = dst_height;
02570 if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)
02571 w >>= dst_pix->x_chroma_shift;
02572 else
02573 w >>= src_pix->x_chroma_shift;
02574 if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)
02575 h >>= dst_pix->y_chroma_shift;
02576 else
02577 h >>= src_pix->y_chroma_shift;
02578
02579 x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);
02580 y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);
02581 xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);
02582
02583
02584 switch(xy_shift) {
02585 case 0x00:
02586 resize_func = ff_img_copy_plane;
02587 break;
02588 case 0x10:
02589 resize_func = shrink21;
02590 break;
02591 case 0x20:
02592 resize_func = shrink41;
02593 break;
02594 case 0x01:
02595 resize_func = shrink12;
02596 break;
02597 case 0x11:
02598 resize_func = ff_shrink22;
02599 break;
02600 case 0x22:
02601 resize_func = ff_shrink44;
02602 break;
02603 case 0xf0:
02604 resize_func = grow21;
02605 break;
02606 case 0x0f:
02607 resize_func = grow12;
02608 break;
02609 case 0xe0:
02610 resize_func = grow41;
02611 break;
02612 case 0xff:
02613 resize_func = grow22;
02614 break;
02615 case 0xee:
02616 resize_func = grow44;
02617 break;
02618 case 0xf1:
02619 resize_func = conv411;
02620 break;
02621 default:
02622
02623 goto no_chroma_filter;
02624 }
02625
02626 ff_img_copy_plane(dst->data[0], dst->linesize[0],
02627 src->data[0], src->linesize[0],
02628 dst_width, dst_height);
02629
02630 for(i = 1;i <= 2; i++)
02631 resize_func(dst->data[i], dst->linesize[i],
02632 src->data[i], src->linesize[i],
02633 dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);
02634
02635
02636 if (dst_pix->color_type != src_pix->color_type) {
02637 const uint8_t *y_table, *c_table;
02638 if (dst_pix->color_type == FF_COLOR_YUV) {
02639 y_table = y_jpeg_to_ccir;
02640 c_table = c_jpeg_to_ccir;
02641 } else {
02642 y_table = y_ccir_to_jpeg;
02643 c_table = c_ccir_to_jpeg;
02644 }
02645 img_apply_table(dst->data[0], dst->linesize[0],
02646 dst->data[0], dst->linesize[0],
02647 dst_width, dst_height,
02648 y_table);
02649
02650 for(i = 1;i <= 2; i++)
02651 img_apply_table(dst->data[i], dst->linesize[i],
02652 dst->data[i], dst->linesize[i],
02653 dst_width>>dst_pix->x_chroma_shift,
02654 dst_height>>dst_pix->y_chroma_shift,
02655 c_table);
02656 }
02657 return 0;
02658 }
02659 no_chroma_filter:
02660
02661
02662 if (src_pix_fmt == PIX_FMT_YUYV422 ||
02663 dst_pix_fmt == PIX_FMT_YUYV422) {
02664
02665 int_pix_fmt = PIX_FMT_YUV422P;
02666 } else if (src_pix_fmt == PIX_FMT_UYVY422 ||
02667 dst_pix_fmt == PIX_FMT_UYVY422) {
02668
02669 int_pix_fmt = PIX_FMT_YUV422P;
02670 } else if (src_pix_fmt == PIX_FMT_UYYVYY411 ||
02671 dst_pix_fmt == PIX_FMT_UYYVYY411) {
02672
02673 int_pix_fmt = PIX_FMT_YUV411P;
02674 } else if ((src_pix->color_type == FF_COLOR_GRAY &&
02675 src_pix_fmt != PIX_FMT_GRAY8) ||
02676 (dst_pix->color_type == FF_COLOR_GRAY &&
02677 dst_pix_fmt != PIX_FMT_GRAY8)) {
02678
02679 int_pix_fmt = PIX_FMT_GRAY8;
02680 } else if ((is_yuv_planar(src_pix) &&
02681 src_pix_fmt != PIX_FMT_YUV444P &&
02682 src_pix_fmt != PIX_FMT_YUVJ444P)) {
02683
02684 if (src_pix->color_type == FF_COLOR_YUV_JPEG)
02685 int_pix_fmt = PIX_FMT_YUVJ444P;
02686 else
02687 int_pix_fmt = PIX_FMT_YUV444P;
02688 } else if ((is_yuv_planar(dst_pix) &&
02689 dst_pix_fmt != PIX_FMT_YUV444P &&
02690 dst_pix_fmt != PIX_FMT_YUVJ444P)) {
02691
02692 if (dst_pix->color_type == FF_COLOR_YUV_JPEG)
02693 int_pix_fmt = PIX_FMT_YUVJ444P;
02694 else
02695 int_pix_fmt = PIX_FMT_YUV444P;
02696 } else {
02697
02698 if (src_pix->is_alpha && dst_pix->is_alpha)
02699 int_pix_fmt = PIX_FMT_RGB32;
02700 else
02701 int_pix_fmt = PIX_FMT_RGB24;
02702 }
02703 if (src_pix_fmt == int_pix_fmt)
02704 return -1;
02705 if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)
02706 return -1;
02707 ret = -1;
02708 if (img_convert(tmp, int_pix_fmt,
02709 src, src_pix_fmt, src_width, src_height) < 0)
02710 goto fail1;
02711 if (img_convert(dst, dst_pix_fmt,
02712 tmp, int_pix_fmt, dst_width, dst_height) < 0)
02713 goto fail1;
02714 ret = 0;
02715 fail1:
02716 avpicture_free(tmp);
02717 return ret;
02718 }
02719 #endif
02720
02721
02722 static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
02723 {
02724 const unsigned char *p;
02725 int src_wrap, ret, x, y;
02726 unsigned int a;
02727 uint32_t *palette = (uint32_t *)src->data[1];
02728
02729 p = src->data[0];
02730 src_wrap = src->linesize[0] - width;
02731 ret = 0;
02732 for(y=0;y<height;y++) {
02733 for(x=0;x<width;x++) {
02734 a = palette[p[0]] >> 24;
02735 if (a == 0x00) {
02736 ret |= FF_ALPHA_TRANSP;
02737 } else if (a != 0xff) {
02738 ret |= FF_ALPHA_SEMI_TRANSP;
02739 }
02740 p++;
02741 }
02742 p += src_wrap;
02743 }
02744 return ret;
02745 }
02746
02747 int img_get_alpha_info(const AVPicture *src,
02748 int pix_fmt, int width, int height)
02749 {
02750 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
02751 int ret;
02752
02753 pf = &pix_fmt_info[pix_fmt];
02754
02755 if (!pf->is_alpha)
02756 return 0;
02757 switch(pix_fmt) {
02758 case PIX_FMT_RGB32:
02759 ret = get_alpha_info_rgb32(src, width, height);
02760 break;
02761 case PIX_FMT_PAL8:
02762 ret = get_alpha_info_pal8(src, width, height);
02763 break;
02764 default:
02765
02766 ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
02767 break;
02768 }
02769 return ret;
02770 }
02771
02772 #if HAVE_MMX
02773 #define DEINT_INPLACE_LINE_LUM \
02774 movd_m2r(lum_m4[0],mm0);\
02775 movd_m2r(lum_m3[0],mm1);\
02776 movd_m2r(lum_m2[0],mm2);\
02777 movd_m2r(lum_m1[0],mm3);\
02778 movd_m2r(lum[0],mm4);\
02779 punpcklbw_r2r(mm7,mm0);\
02780 movd_r2m(mm2,lum_m4[0]);\
02781 punpcklbw_r2r(mm7,mm1);\
02782 punpcklbw_r2r(mm7,mm2);\
02783 punpcklbw_r2r(mm7,mm3);\
02784 punpcklbw_r2r(mm7,mm4);\
02785 paddw_r2r(mm3,mm1);\
02786 psllw_i2r(1,mm2);\
02787 paddw_r2r(mm4,mm0);\
02788 psllw_i2r(2,mm1);\
02789 paddw_r2r(mm6,mm2);\
02790 paddw_r2r(mm2,mm1);\
02791 psubusw_r2r(mm0,mm1);\
02792 psrlw_i2r(3,mm1);\
02793 packuswb_r2r(mm7,mm1);\
02794 movd_r2m(mm1,lum_m2[0]);
02795
02796 #define DEINT_LINE_LUM \
02797 movd_m2r(lum_m4[0],mm0);\
02798 movd_m2r(lum_m3[0],mm1);\
02799 movd_m2r(lum_m2[0],mm2);\
02800 movd_m2r(lum_m1[0],mm3);\
02801 movd_m2r(lum[0],mm4);\
02802 punpcklbw_r2r(mm7,mm0);\
02803 punpcklbw_r2r(mm7,mm1);\
02804 punpcklbw_r2r(mm7,mm2);\
02805 punpcklbw_r2r(mm7,mm3);\
02806 punpcklbw_r2r(mm7,mm4);\
02807 paddw_r2r(mm3,mm1);\
02808 psllw_i2r(1,mm2);\
02809 paddw_r2r(mm4,mm0);\
02810 psllw_i2r(2,mm1);\
02811 paddw_r2r(mm6,mm2);\
02812 paddw_r2r(mm2,mm1);\
02813 psubusw_r2r(mm0,mm1);\
02814 psrlw_i2r(3,mm1);\
02815 packuswb_r2r(mm7,mm1);\
02816 movd_r2m(mm1,dst[0]);
02817 #endif
02818
02819
02820 static void deinterlace_line(uint8_t *dst,
02821 const uint8_t *lum_m4, const uint8_t *lum_m3,
02822 const uint8_t *lum_m2, const uint8_t *lum_m1,
02823 const uint8_t *lum,
02824 int size)
02825 {
02826 #if !HAVE_MMX
02827 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
02828 int sum;
02829
02830 for(;size > 0;size--) {
02831 sum = -lum_m4[0];
02832 sum += lum_m3[0] << 2;
02833 sum += lum_m2[0] << 1;
02834 sum += lum_m1[0] << 2;
02835 sum += -lum[0];
02836 dst[0] = cm[(sum + 4) >> 3];
02837 lum_m4++;
02838 lum_m3++;
02839 lum_m2++;
02840 lum_m1++;
02841 lum++;
02842 dst++;
02843 }
02844 #else
02845
02846 {
02847 pxor_r2r(mm7,mm7);
02848 movq_m2r(ff_pw_4,mm6);
02849 }
02850 for (;size > 3; size-=4) {
02851 DEINT_LINE_LUM
02852 lum_m4+=4;
02853 lum_m3+=4;
02854 lum_m2+=4;
02855 lum_m1+=4;
02856 lum+=4;
02857 dst+=4;
02858 }
02859 #endif
02860 }
02861 static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
02862 int size)
02863 {
02864 #if !HAVE_MMX
02865 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
02866 int sum;
02867
02868 for(;size > 0;size--) {
02869 sum = -lum_m4[0];
02870 sum += lum_m3[0] << 2;
02871 sum += lum_m2[0] << 1;
02872 lum_m4[0]=lum_m2[0];
02873 sum += lum_m1[0] << 2;
02874 sum += -lum[0];
02875 lum_m2[0] = cm[(sum + 4) >> 3];
02876 lum_m4++;
02877 lum_m3++;
02878 lum_m2++;
02879 lum_m1++;
02880 lum++;
02881 }
02882 #else
02883
02884 {
02885 pxor_r2r(mm7,mm7);
02886 movq_m2r(ff_pw_4,mm6);
02887 }
02888 for (;size > 3; size-=4) {
02889 DEINT_INPLACE_LINE_LUM
02890 lum_m4+=4;
02891 lum_m3+=4;
02892 lum_m2+=4;
02893 lum_m1+=4;
02894 lum+=4;
02895 }
02896 #endif
02897 }
02898
02899
02900
02901
02902 static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
02903 const uint8_t *src1, int src_wrap,
02904 int width, int height)
02905 {
02906 const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
02907 int y;
02908
02909 src_m2 = src1;
02910 src_m1 = src1;
02911 src_0=&src_m1[src_wrap];
02912 src_p1=&src_0[src_wrap];
02913 src_p2=&src_p1[src_wrap];
02914 for(y=0;y<(height-2);y+=2) {
02915 memcpy(dst,src_m1,width);
02916 dst += dst_wrap;
02917 deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
02918 src_m2 = src_0;
02919 src_m1 = src_p1;
02920 src_0 = src_p2;
02921 src_p1 += 2*src_wrap;
02922 src_p2 += 2*src_wrap;
02923 dst += dst_wrap;
02924 }
02925 memcpy(dst,src_m1,width);
02926 dst += dst_wrap;
02927
02928 deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
02929 }
02930
02931 static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
02932 int width, int height)
02933 {
02934 uint8_t *src_m1, *src_0, *src_p1, *src_p2;
02935 int y;
02936 uint8_t *buf;
02937 buf = (uint8_t*)av_malloc(width);
02938
02939 src_m1 = src1;
02940 memcpy(buf,src_m1,width);
02941 src_0=&src_m1[src_wrap];
02942 src_p1=&src_0[src_wrap];
02943 src_p2=&src_p1[src_wrap];
02944 for(y=0;y<(height-2);y+=2) {
02945 deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
02946 src_m1 = src_p1;
02947 src_0 = src_p2;
02948 src_p1 += 2*src_wrap;
02949 src_p2 += 2*src_wrap;
02950 }
02951
02952 deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
02953 av_free(buf);
02954 }
02955
02956 int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
02957 int pix_fmt, int width, int height)
02958 {
02959 int i;
02960
02961 if (pix_fmt != PIX_FMT_YUV420P &&
02962 pix_fmt != PIX_FMT_YUV422P &&
02963 pix_fmt != PIX_FMT_YUV444P &&
02964 pix_fmt != PIX_FMT_YUV411P &&
02965 pix_fmt != PIX_FMT_GRAY8)
02966 return -1;
02967 if ((width & 3) != 0 || (height & 3) != 0)
02968 return -1;
02969
02970 for(i=0;i<3;i++) {
02971 if (i == 1) {
02972 switch(pix_fmt) {
02973 case PIX_FMT_YUV420P:
02974 width >>= 1;
02975 height >>= 1;
02976 break;
02977 case PIX_FMT_YUV422P:
02978 width >>= 1;
02979 break;
02980 case PIX_FMT_YUV411P:
02981 width >>= 2;
02982 break;
02983 default:
02984 break;
02985 }
02986 if (pix_fmt == PIX_FMT_GRAY8) {
02987 break;
02988 }
02989 }
02990 if (src == dst) {
02991 deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
02992 width, height);
02993 } else {
02994 deinterlace_bottom_field(dst->data[i],dst->linesize[i],
02995 src->data[i], src->linesize[i],
02996 width, height);
02997 }
02998 }
02999 emms_c();
03000 return 0;
03001 }
03002