00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
00048
00049 #define FF_PIXEL_PLANAR 0
00050 #define FF_PIXEL_PACKED 1
00051 #define FF_PIXEL_PALETTE 2
00052
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
00411 if (pix_fmt < 0)
00412 snprintf (buf, buf_size,
00413 "name " " nb_channels" " depth" " is_alpha"
00414 );
00415 else{
00416 PixFmtInfo info= pix_fmt_info[pix_fmt];
00417
00418 char is_alpha_char= info.is_alpha ? 'y' : 'n';
00419
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
00430 int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width)
00431 {
00432 int w2;
00433 const PixFmtInfo *pinfo;
00434
00435 memset(picture->linesize, 0, sizeof(picture->linesize));
00436
00437 pinfo = &pix_fmt_info[pix_fmt];
00438 switch(pix_fmt) {
00439 case PIX_FMT_YUV420P:
00440 case PIX_FMT_YUV422P:
00441 case PIX_FMT_YUV444P:
00442 case PIX_FMT_YUV410P:
00443 case PIX_FMT_YUV411P:
00444 case PIX_FMT_YUV440P:
00445 case PIX_FMT_YUVJ420P:
00446 case PIX_FMT_YUVJ422P:
00447 case PIX_FMT_YUVJ444P:
00448 case PIX_FMT_YUVJ440P:
00449 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
00450 picture->linesize[0] = width;
00451 picture->linesize[1] = w2;
00452 picture->linesize[2] = w2;
00453 break;
00454 case PIX_FMT_YUVA420P:
00455 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
00456 picture->linesize[0] = width;
00457 picture->linesize[1] = w2;
00458 picture->linesize[2] = w2;
00459 picture->linesize[3] = width;
00460 break;
00461 case PIX_FMT_NV12:
00462 case PIX_FMT_NV21:
00463 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
00464 picture->linesize[0] = width;
00465 picture->linesize[1] = w2;
00466 break;
00467 case PIX_FMT_RGB24:
00468 case PIX_FMT_BGR24:
00469 picture->linesize[0] = width * 3;
00470 break;
00471 case PIX_FMT_RGB32:
00472 case PIX_FMT_BGR32:
00473 case PIX_FMT_RGB32_1:
00474 case PIX_FMT_BGR32_1:
00475 picture->linesize[0] = width * 4;
00476 break;
00477 case PIX_FMT_GRAY16BE:
00478 case PIX_FMT_GRAY16LE:
00479 case PIX_FMT_BGR555:
00480 case PIX_FMT_BGR565:
00481 case PIX_FMT_RGB555:
00482 case PIX_FMT_RGB565:
00483 case PIX_FMT_YUYV422:
00484 picture->linesize[0] = width * 2;
00485 break;
00486 case PIX_FMT_UYVY422:
00487 picture->linesize[0] = width * 2;
00488 break;
00489 case PIX_FMT_UYYVYY411:
00490 picture->linesize[0] = width + width/2;
00491 break;
00492 case PIX_FMT_RGB8:
00493 case PIX_FMT_BGR8:
00494 case PIX_FMT_RGB4_BYTE:
00495 case PIX_FMT_BGR4_BYTE:
00496 case PIX_FMT_GRAY8:
00497 picture->linesize[0] = width;
00498 break;
00499 case PIX_FMT_RGB4:
00500 case PIX_FMT_BGR4:
00501 picture->linesize[0] = width / 2;
00502 break;
00503 case PIX_FMT_MONOWHITE:
00504 case PIX_FMT_MONOBLACK:
00505 picture->linesize[0] = (width + 7) >> 3;
00506 break;
00507 case PIX_FMT_PAL8:
00508 picture->linesize[0] = width;
00509 picture->linesize[1] = 4;
00510 break;
00511 default:
00512 return -1;
00513 }
00514 return 0;
00515 }
00516
00517 int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, int pix_fmt,
00518 int height)
00519 {
00520 int size, h2, size2;
00521 const PixFmtInfo *pinfo;
00522
00523 pinfo = &pix_fmt_info[pix_fmt];
00524 size = picture->linesize[0] * height;
00525 switch(pix_fmt) {
00526 case PIX_FMT_YUV420P:
00527 case PIX_FMT_YUV422P:
00528 case PIX_FMT_YUV444P:
00529 case PIX_FMT_YUV410P:
00530 case PIX_FMT_YUV411P:
00531 case PIX_FMT_YUV440P:
00532 case PIX_FMT_YUVJ420P:
00533 case PIX_FMT_YUVJ422P:
00534 case PIX_FMT_YUVJ444P:
00535 case PIX_FMT_YUVJ440P:
00536 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
00537 size2 = picture->linesize[1] * h2;
00538 picture->data[0] = ptr;
00539 picture->data[1] = picture->data[0] + size;
00540 picture->data[2] = picture->data[1] + size2;
00541 picture->data[3] = NULL;
00542 return size + 2 * size2;
00543 case PIX_FMT_YUVA420P:
00544 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
00545 size2 = picture->linesize[1] * h2;
00546 picture->data[0] = ptr;
00547 picture->data[1] = picture->data[0] + size;
00548 picture->data[2] = picture->data[1] + size2;
00549 picture->data[3] = picture->data[1] + size2 + size2;
00550 return 2 * size + 2 * size2;
00551 case PIX_FMT_NV12:
00552 case PIX_FMT_NV21:
00553 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
00554 size2 = picture->linesize[1] * h2 * 2;
00555 picture->data[0] = ptr;
00556 picture->data[1] = picture->data[0] + size;
00557 picture->data[2] = NULL;
00558 picture->data[3] = NULL;
00559 return size + 2 * size2;
00560 case PIX_FMT_RGB24:
00561 case PIX_FMT_BGR24:
00562 case PIX_FMT_RGB32:
00563 case PIX_FMT_BGR32:
00564 case PIX_FMT_RGB32_1:
00565 case PIX_FMT_BGR32_1:
00566 case PIX_FMT_GRAY16BE:
00567 case PIX_FMT_GRAY16LE:
00568 case PIX_FMT_BGR555:
00569 case PIX_FMT_BGR565:
00570 case PIX_FMT_RGB555:
00571 case PIX_FMT_RGB565:
00572 case PIX_FMT_YUYV422:
00573 case PIX_FMT_UYVY422:
00574 case PIX_FMT_UYYVYY411:
00575 case PIX_FMT_RGB8:
00576 case PIX_FMT_BGR8:
00577 case PIX_FMT_RGB4_BYTE:
00578 case PIX_FMT_BGR4_BYTE:
00579 case PIX_FMT_GRAY8:
00580 case PIX_FMT_RGB4:
00581 case PIX_FMT_BGR4:
00582 case PIX_FMT_MONOWHITE:
00583 case PIX_FMT_MONOBLACK:
00584 picture->data[0] = ptr;
00585 picture->data[1] = NULL;
00586 picture->data[2] = NULL;
00587 picture->data[3] = NULL;
00588 return size;
00589 case PIX_FMT_PAL8:
00590 size2 = (size + 3) & ~3;
00591 picture->data[0] = ptr;
00592 picture->data[1] = ptr + size2;
00593 picture->data[2] = NULL;
00594 picture->data[3] = NULL;
00595 return size2 + 256 * 4;
00596 default:
00597 picture->data[0] = NULL;
00598 picture->data[1] = NULL;
00599 picture->data[2] = NULL;
00600 picture->data[3] = NULL;
00601 return -1;
00602 }
00603 }
00604
00605 int avpicture_fill(AVPicture *picture, uint8_t *ptr,
00606 int pix_fmt, int width, int height)
00607 {
00608
00609 if(avcodec_check_dimensions(NULL, width, height))
00610 return -1;
00611
00612 if (ff_fill_linesize(picture, pix_fmt, width))
00613 return -1;
00614
00615 return ff_fill_pointer(picture, ptr, pix_fmt, height);
00616 }
00617
00618 int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
00619 unsigned char *dest, int dest_size)
00620 {
00621 const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
00622 int i, j, w, h, data_planes;
00623 const unsigned char* s;
00624 int size = avpicture_get_size(pix_fmt, width, height);
00625
00626 if (size > dest_size || size < 0)
00627 return -1;
00628
00629 if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
00630 if (pix_fmt == PIX_FMT_YUYV422 ||
00631 pix_fmt == PIX_FMT_UYVY422 ||
00632 pix_fmt == PIX_FMT_BGR565 ||
00633 pix_fmt == PIX_FMT_BGR555 ||
00634 pix_fmt == PIX_FMT_RGB565 ||
00635 pix_fmt == PIX_FMT_RGB555)
00636 w = width * 2;
00637 else if (pix_fmt == PIX_FMT_UYYVYY411)
00638 w = width + width/2;
00639 else if (pix_fmt == PIX_FMT_PAL8)
00640 w = width;
00641 else
00642 w = width * (pf->depth * pf->nb_channels / 8);
00643
00644 data_planes = 1;
00645 h = height;
00646 } else {
00647 data_planes = pf->nb_channels;
00648 w = (width*pf->depth + 7)/8;
00649 h = height;
00650 }
00651
00652 for (i=0; i<data_planes; i++) {
00653 if (i == 1) {
00654 w = width >> pf->x_chroma_shift;
00655 h = height >> pf->y_chroma_shift;
00656 }
00657 s = src->data[i];
00658 for(j=0; j<h; j++) {
00659 memcpy(dest, s, w);
00660 dest += w;
00661 s += src->linesize[i];
00662 }
00663 }
00664
00665 if (pf->pixel_type == FF_PIXEL_PALETTE)
00666 memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
00667
00668 return size;
00669 }
00670
00671 int avpicture_get_size(int pix_fmt, int width, int height)
00672 {
00673 AVPicture dummy_pict;
00674 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
00675 }
00676
00677 int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
00678 int has_alpha)
00679 {
00680 const PixFmtInfo *pf, *ps;
00681 int loss;
00682
00683 ps = &pix_fmt_info[src_pix_fmt];
00684 pf = &pix_fmt_info[dst_pix_fmt];
00685
00686
00687 loss = 0;
00688 pf = &pix_fmt_info[dst_pix_fmt];
00689 if (pf->depth < ps->depth ||
00690 (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
00691 loss |= FF_LOSS_DEPTH;
00692 if (pf->x_chroma_shift > ps->x_chroma_shift ||
00693 pf->y_chroma_shift > ps->y_chroma_shift)
00694 loss |= FF_LOSS_RESOLUTION;
00695 switch(pf->color_type) {
00696 case FF_COLOR_RGB:
00697 if (ps->color_type != FF_COLOR_RGB &&
00698 ps->color_type != FF_COLOR_GRAY)
00699 loss |= FF_LOSS_COLORSPACE;
00700 break;
00701 case FF_COLOR_GRAY:
00702 if (ps->color_type != FF_COLOR_GRAY)
00703 loss |= FF_LOSS_COLORSPACE;
00704 break;
00705 case FF_COLOR_YUV:
00706 if (ps->color_type != FF_COLOR_YUV)
00707 loss |= FF_LOSS_COLORSPACE;
00708 break;
00709 case FF_COLOR_YUV_JPEG:
00710 if (ps->color_type != FF_COLOR_YUV_JPEG &&
00711 ps->color_type != FF_COLOR_YUV &&
00712 ps->color_type != FF_COLOR_GRAY)
00713 loss |= FF_LOSS_COLORSPACE;
00714 break;
00715 default:
00716
00717 if (ps->color_type != pf->color_type)
00718 loss |= FF_LOSS_COLORSPACE;
00719 break;
00720 }
00721 if (pf->color_type == FF_COLOR_GRAY &&
00722 ps->color_type != FF_COLOR_GRAY)
00723 loss |= FF_LOSS_CHROMA;
00724 if (!pf->is_alpha && (ps->is_alpha && has_alpha))
00725 loss |= FF_LOSS_ALPHA;
00726 if (pf->pixel_type == FF_PIXEL_PALETTE &&
00727 (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
00728 loss |= FF_LOSS_COLORQUANT;
00729 return loss;
00730 }
00731
00732 static int avg_bits_per_pixel(int pix_fmt)
00733 {
00734 int bits;
00735 const PixFmtInfo *pf;
00736
00737 pf = &pix_fmt_info[pix_fmt];
00738 switch(pf->pixel_type) {
00739 case FF_PIXEL_PACKED:
00740 switch(pix_fmt) {
00741 case PIX_FMT_YUYV422:
00742 case PIX_FMT_UYVY422:
00743 case PIX_FMT_RGB565:
00744 case PIX_FMT_RGB555:
00745 case PIX_FMT_BGR565:
00746 case PIX_FMT_BGR555:
00747 bits = 16;
00748 break;
00749 case PIX_FMT_UYYVYY411:
00750 bits = 12;
00751 break;
00752 default:
00753 bits = pf->depth * pf->nb_channels;
00754 break;
00755 }
00756 break;
00757 case FF_PIXEL_PLANAR:
00758 if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
00759 bits = pf->depth * pf->nb_channels;
00760 } else {
00761 bits = pf->depth + ((2 * pf->depth) >>
00762 (pf->x_chroma_shift + pf->y_chroma_shift));
00763 }
00764 break;
00765 case FF_PIXEL_PALETTE:
00766 bits = 8;
00767 break;
00768 default:
00769 bits = -1;
00770 break;
00771 }
00772 return bits;
00773 }
00774
00775 static int avcodec_find_best_pix_fmt1(int pix_fmt_mask,
00776 int src_pix_fmt,
00777 int has_alpha,
00778 int loss_mask)
00779 {
00780 int dist, i, loss, min_dist, dst_pix_fmt;
00781
00782
00783 dst_pix_fmt = -1;
00784 min_dist = 0x7fffffff;
00785 for(i = 0;i < PIX_FMT_NB; i++) {
00786 if (pix_fmt_mask & (1 << i)) {
00787 loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
00788 if (loss == 0) {
00789 dist = avg_bits_per_pixel(i);
00790 if (dist < min_dist) {
00791 min_dist = dist;
00792 dst_pix_fmt = i;
00793 }
00794 }
00795 }
00796 }
00797 return dst_pix_fmt;
00798 }
00799
00800 int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt,
00801 int has_alpha, int *loss_ptr)
00802 {
00803 int dst_pix_fmt, loss_mask, i;
00804 static const int loss_mask_order[] = {
00805 ~0,
00806 ~FF_LOSS_ALPHA,
00807 ~FF_LOSS_RESOLUTION,
00808 ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
00809 ~FF_LOSS_COLORQUANT,
00810 ~FF_LOSS_DEPTH,
00811 0,
00812 };
00813
00814
00815 i = 0;
00816 for(;;) {
00817 loss_mask = loss_mask_order[i++];
00818 dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
00819 has_alpha, loss_mask);
00820 if (dst_pix_fmt >= 0)
00821 goto found;
00822 if (loss_mask == 0)
00823 break;
00824 }
00825 return -1;
00826 found:
00827 if (loss_ptr)
00828 *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
00829 return dst_pix_fmt;
00830 }
00831
00832 void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
00833 const uint8_t *src, int src_wrap,
00834 int width, int height)
00835 {
00836 if((!dst) || (!src))
00837 return;
00838 for(;height > 0; height--) {
00839 memcpy(dst, src, width);
00840 dst += dst_wrap;
00841 src += src_wrap;
00842 }
00843 }
00844
00845 int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
00846 {
00847 int bits;
00848 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
00849
00850 pf = &pix_fmt_info[pix_fmt];
00851 switch(pf->pixel_type) {
00852 case FF_PIXEL_PACKED:
00853 switch(pix_fmt) {
00854 case PIX_FMT_YUYV422:
00855 case PIX_FMT_UYVY422:
00856 case PIX_FMT_RGB565:
00857 case PIX_FMT_RGB555:
00858 case PIX_FMT_BGR565:
00859 case PIX_FMT_BGR555:
00860 bits = 16;
00861 break;
00862 case PIX_FMT_UYYVYY411:
00863 bits = 12;
00864 break;
00865 default:
00866 bits = pf->depth * pf->nb_channels;
00867 break;
00868 }
00869 return (width * bits + 7) >> 3;
00870 break;
00871 case FF_PIXEL_PLANAR:
00872 if (plane == 1 || plane == 2)
00873 width >>= pf->x_chroma_shift;
00874
00875 return (width * pf->depth + 7) >> 3;
00876 break;
00877 case FF_PIXEL_PALETTE:
00878 if (plane == 0)
00879 return width;
00880 break;
00881 }
00882
00883 return -1;
00884 }
00885
00886 void av_picture_copy(AVPicture *dst, const AVPicture *src,
00887 int pix_fmt, int width, int height)
00888 {
00889 int i;
00890 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
00891
00892 pf = &pix_fmt_info[pix_fmt];
00893 switch(pf->pixel_type) {
00894 case FF_PIXEL_PACKED:
00895 case FF_PIXEL_PLANAR:
00896 for(i = 0; i < pf->nb_channels; i++) {
00897 int w, h;
00898 int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
00899 if (bwidth < 0)
00900 continue;
00901 w = width;
00902 h = height;
00903 if (i == 1 || i == 2) {
00904 w >>= pf->x_chroma_shift;
00905 h >>= pf->y_chroma_shift;
00906 }
00907 ff_img_copy_plane(dst->data[i], dst->linesize[i],
00908 src->data[i], src->linesize[i],
00909 bwidth, h);
00910 }
00911 break;
00912 case FF_PIXEL_PALETTE:
00913 ff_img_copy_plane(dst->data[0], dst->linesize[0],
00914 src->data[0], src->linesize[0],
00915 width, height);
00916
00917 ff_img_copy_plane(dst->data[1], dst->linesize[1],
00918 src->data[1], src->linesize[1],
00919 4, 256);
00920 break;
00921 }
00922 }
00923
00924
00925
00926 static void yuyv422_to_yuv420p(AVPicture *dst, const AVPicture *src,
00927 int width, int height)
00928 {
00929 const uint8_t *p, *p1;
00930 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
00931 int w;
00932
00933 p1 = src->data[0];
00934 lum1 = dst->data[0];
00935 cb1 = dst->data[1];
00936 cr1 = dst->data[2];
00937
00938 for(;height >= 1; height -= 2) {
00939 p = p1;
00940 lum = lum1;
00941 cb = cb1;
00942 cr = cr1;
00943 for(w = width; w >= 2; w -= 2) {
00944 lum[0] = p[0];
00945 cb[0] = p[1];
00946 lum[1] = p[2];
00947 cr[0] = p[3];
00948 p += 4;
00949 lum += 2;
00950 cb++;
00951 cr++;
00952 }
00953 if (w) {
00954 lum[0] = p[0];
00955 cb[0] = p[1];
00956 cr[0] = p[3];
00957 cb++;
00958 cr++;
00959 }
00960 p1 += src->linesize[0];
00961 lum1 += dst->linesize[0];
00962 if (height>1) {
00963 p = p1;
00964 lum = lum1;
00965 for(w = width; w >= 2; w -= 2) {
00966 lum[0] = p[0];
00967 lum[1] = p[2];
00968 p += 4;
00969 lum += 2;
00970 }
00971 if (w) {
00972 lum[0] = p[0];
00973 }
00974 p1 += src->linesize[0];
00975 lum1 += dst->linesize[0];
00976 }
00977 cb1 += dst->linesize[1];
00978 cr1 += dst->linesize[2];
00979 }
00980 }
00981
00982 static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src,
00983 int width, int height)
00984 {
00985 const uint8_t *p, *p1;
00986 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
00987 int w;
00988
00989 p1 = src->data[0];
00990
00991 lum1 = dst->data[0];
00992 cb1 = dst->data[1];
00993 cr1 = dst->data[2];
00994
00995 for(;height >= 1; height -= 2) {
00996 p = p1;
00997 lum = lum1;
00998 cb = cb1;
00999 cr = cr1;
01000 for(w = width; w >= 2; w -= 2) {
01001 lum[0] = p[1];
01002 cb[0] = p[0];
01003 lum[1] = p[3];
01004 cr[0] = p[2];
01005 p += 4;
01006 lum += 2;
01007 cb++;
01008 cr++;
01009 }
01010 if (w) {
01011 lum[0] = p[1];
01012 cb[0] = p[0];
01013 cr[0] = p[2];
01014 cb++;
01015 cr++;
01016 }
01017 p1 += src->linesize[0];
01018 lum1 += dst->linesize[0];
01019 if (height>1) {
01020 p = p1;
01021 lum = lum1;
01022 for(w = width; w >= 2; w -= 2) {
01023 lum[0] = p[1];
01024 lum[1] = p[3];
01025 p += 4;
01026 lum += 2;
01027 }
01028 if (w) {
01029 lum[0] = p[1];
01030 }
01031 p1 += src->linesize[0];
01032 lum1 += dst->linesize[0];
01033 }
01034 cb1 += dst->linesize[1];
01035 cr1 += dst->linesize[2];
01036 }
01037 }
01038
01039
01040 static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src,
01041 int width, int height)
01042 {
01043 const uint8_t *p, *p1;
01044 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
01045 int w;
01046
01047 p1 = src->data[0];
01048 lum1 = dst->data[0];
01049 cb1 = dst->data[1];
01050 cr1 = dst->data[2];
01051 for(;height > 0; height--) {
01052 p = p1;
01053 lum = lum1;
01054 cb = cb1;
01055 cr = cr1;
01056 for(w = width; w >= 2; w -= 2) {
01057 lum[0] = p[1];
01058 cb[0] = p[0];
01059 lum[1] = p[3];
01060 cr[0] = p[2];
01061 p += 4;
01062 lum += 2;
01063 cb++;
01064