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