Mercurial > audlegacy-plugins
comparison src/ffmpeg/libavcodec/imgconvert.c @ 808:e8776388b02a trunk
[svn] - add ffmpeg
| author | nenolod |
|---|---|
| date | Mon, 12 Mar 2007 11:18:54 -0700 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 807:0f9c8d4d3ac4 | 808:e8776388b02a |
|---|---|
| 1 /* | |
| 2 * Misc image convertion routines | |
| 3 * Copyright (c) 2001, 2002, 2003 Fabrice Bellard. | |
| 4 * | |
| 5 * This file is part of FFmpeg. | |
| 6 * | |
| 7 * FFmpeg is free software; you can redistribute it and/or | |
| 8 * modify it under the terms of the GNU Lesser General Public | |
| 9 * License as published by the Free Software Foundation; either | |
| 10 * version 2.1 of the License, or (at your option) any later version. | |
| 11 * | |
| 12 * FFmpeg is distributed in the hope that it will be useful, | |
| 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 15 * Lesser General Public License for more details. | |
| 16 * | |
| 17 * You should have received a copy of the GNU Lesser General Public | |
| 18 * License along with FFmpeg; if not, write to the Free Software | |
| 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 20 */ | |
| 21 | |
| 22 /** | |
| 23 * @file imgconvert.c | |
| 24 * Misc image convertion routines. | |
| 25 */ | |
| 26 | |
| 27 /* TODO: | |
| 28 * - write 'ffimg' program to test all the image related stuff | |
| 29 * - move all api to slice based system | |
| 30 * - integrate deinterlacing, postprocessing and scaling in the conversion process | |
| 31 */ | |
| 32 | |
| 33 #include "avcodec.h" | |
| 34 #include "dsputil.h" | |
| 35 | |
| 36 #ifdef USE_FASTMEMCPY | |
| 37 #include "libvo/fastmemcpy.h" | |
| 38 #endif | |
| 39 | |
| 40 #ifdef HAVE_MMX | |
| 41 #include "i386/mmx.h" | |
| 42 #endif | |
| 43 | |
| 44 #define xglue(x, y) x ## y | |
| 45 #define glue(x, y) xglue(x, y) | |
| 46 | |
| 47 #define FF_COLOR_RGB 0 /* RGB color space */ | |
| 48 #define FF_COLOR_GRAY 1 /* gray color space */ | |
| 49 #define FF_COLOR_YUV 2 /* YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */ | |
| 50 #define FF_COLOR_YUV_JPEG 3 /* YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */ | |
| 51 | |
| 52 #define FF_PIXEL_PLANAR 0 /* each channel has one component in AVPicture */ | |
| 53 #define FF_PIXEL_PACKED 1 /* only one components containing all the channels */ | |
| 54 #define FF_PIXEL_PALETTE 2 /* one components containing indexes for a palette */ | |
| 55 | |
| 56 typedef struct PixFmtInfo { | |
| 57 const char *name; | |
| 58 uint8_t nb_channels; /* number of channels (including alpha) */ | |
| 59 uint8_t color_type; /* color type (see FF_COLOR_xxx constants) */ | |
| 60 uint8_t pixel_type; /* pixel storage type (see FF_PIXEL_xxx constants) */ | |
| 61 uint8_t is_alpha : 1; /* true if alpha can be specified */ | |
| 62 uint8_t x_chroma_shift; /* X chroma subsampling factor is 2 ^ shift */ | |
| 63 uint8_t y_chroma_shift; /* Y chroma subsampling factor is 2 ^ shift */ | |
| 64 uint8_t depth; /* bit depth of the color components */ | |
| 65 } PixFmtInfo; | |
| 66 | |
| 67 /* this table gives more information about formats */ | |
| 68 static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { | |
| 69 /* YUV formats */ | |
| 70 [PIX_FMT_YUV420P] = { | |
| 71 .name = "yuv420p", | |
| 72 .nb_channels = 3, | |
| 73 .color_type = FF_COLOR_YUV, | |
| 74 .pixel_type = FF_PIXEL_PLANAR, | |
| 75 .depth = 8, | |
| 76 .x_chroma_shift = 1, .y_chroma_shift = 1, | |
| 77 }, | |
| 78 [PIX_FMT_YUV422P] = { | |
| 79 .name = "yuv422p", | |
| 80 .nb_channels = 3, | |
| 81 .color_type = FF_COLOR_YUV, | |
| 82 .pixel_type = FF_PIXEL_PLANAR, | |
| 83 .depth = 8, | |
| 84 .x_chroma_shift = 1, .y_chroma_shift = 0, | |
| 85 }, | |
| 86 [PIX_FMT_YUV444P] = { | |
| 87 .name = "yuv444p", | |
| 88 .nb_channels = 3, | |
| 89 .color_type = FF_COLOR_YUV, | |
| 90 .pixel_type = FF_PIXEL_PLANAR, | |
| 91 .depth = 8, | |
| 92 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 93 }, | |
| 94 [PIX_FMT_YUV422] = { | |
| 95 .name = "yuv422", | |
| 96 .nb_channels = 1, | |
| 97 .color_type = FF_COLOR_YUV, | |
| 98 .pixel_type = FF_PIXEL_PACKED, | |
| 99 .depth = 8, | |
| 100 .x_chroma_shift = 1, .y_chroma_shift = 0, | |
| 101 }, | |
| 102 [PIX_FMT_UYVY422] = { | |
| 103 .name = "uyvy422", | |
| 104 .nb_channels = 1, | |
| 105 .color_type = FF_COLOR_YUV, | |
| 106 .pixel_type = FF_PIXEL_PACKED, | |
| 107 .depth = 8, | |
| 108 .x_chroma_shift = 1, .y_chroma_shift = 0, | |
| 109 }, | |
| 110 [PIX_FMT_YUV410P] = { | |
| 111 .name = "yuv410p", | |
| 112 .nb_channels = 3, | |
| 113 .color_type = FF_COLOR_YUV, | |
| 114 .pixel_type = FF_PIXEL_PLANAR, | |
| 115 .depth = 8, | |
| 116 .x_chroma_shift = 2, .y_chroma_shift = 2, | |
| 117 }, | |
| 118 [PIX_FMT_YUV411P] = { | |
| 119 .name = "yuv411p", | |
| 120 .nb_channels = 3, | |
| 121 .color_type = FF_COLOR_YUV, | |
| 122 .pixel_type = FF_PIXEL_PLANAR, | |
| 123 .depth = 8, | |
| 124 .x_chroma_shift = 2, .y_chroma_shift = 0, | |
| 125 }, | |
| 126 | |
| 127 /* JPEG YUV */ | |
| 128 [PIX_FMT_YUVJ420P] = { | |
| 129 .name = "yuvj420p", | |
| 130 .nb_channels = 3, | |
| 131 .color_type = FF_COLOR_YUV_JPEG, | |
| 132 .pixel_type = FF_PIXEL_PLANAR, | |
| 133 .depth = 8, | |
| 134 .x_chroma_shift = 1, .y_chroma_shift = 1, | |
| 135 }, | |
| 136 [PIX_FMT_YUVJ422P] = { | |
| 137 .name = "yuvj422p", | |
| 138 .nb_channels = 3, | |
| 139 .color_type = FF_COLOR_YUV_JPEG, | |
| 140 .pixel_type = FF_PIXEL_PLANAR, | |
| 141 .depth = 8, | |
| 142 .x_chroma_shift = 1, .y_chroma_shift = 0, | |
| 143 }, | |
| 144 [PIX_FMT_YUVJ444P] = { | |
| 145 .name = "yuvj444p", | |
| 146 .nb_channels = 3, | |
| 147 .color_type = FF_COLOR_YUV_JPEG, | |
| 148 .pixel_type = FF_PIXEL_PLANAR, | |
| 149 .depth = 8, | |
| 150 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 151 }, | |
| 152 | |
| 153 /* RGB formats */ | |
| 154 [PIX_FMT_RGB24] = { | |
| 155 .name = "rgb24", | |
| 156 .nb_channels = 3, | |
| 157 .color_type = FF_COLOR_RGB, | |
| 158 .pixel_type = FF_PIXEL_PACKED, | |
| 159 .depth = 8, | |
| 160 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 161 }, | |
| 162 [PIX_FMT_BGR24] = { | |
| 163 .name = "bgr24", | |
| 164 .nb_channels = 3, | |
| 165 .color_type = FF_COLOR_RGB, | |
| 166 .pixel_type = FF_PIXEL_PACKED, | |
| 167 .depth = 8, | |
| 168 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 169 }, | |
| 170 [PIX_FMT_RGBA32] = { | |
| 171 .name = "rgba32", | |
| 172 .nb_channels = 4, .is_alpha = 1, | |
| 173 .color_type = FF_COLOR_RGB, | |
| 174 .pixel_type = FF_PIXEL_PACKED, | |
| 175 .depth = 8, | |
| 176 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 177 }, | |
| 178 [PIX_FMT_RGB565] = { | |
| 179 .name = "rgb565", | |
| 180 .nb_channels = 3, | |
| 181 .color_type = FF_COLOR_RGB, | |
| 182 .pixel_type = FF_PIXEL_PACKED, | |
| 183 .depth = 5, | |
| 184 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 185 }, | |
| 186 [PIX_FMT_RGB555] = { | |
| 187 .name = "rgb555", | |
| 188 .nb_channels = 4, .is_alpha = 1, | |
| 189 .color_type = FF_COLOR_RGB, | |
| 190 .pixel_type = FF_PIXEL_PACKED, | |
| 191 .depth = 5, | |
| 192 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 193 }, | |
| 194 | |
| 195 /* gray / mono formats */ | |
| 196 [PIX_FMT_GRAY8] = { | |
| 197 .name = "gray", | |
| 198 .nb_channels = 1, | |
| 199 .color_type = FF_COLOR_GRAY, | |
| 200 .pixel_type = FF_PIXEL_PLANAR, | |
| 201 .depth = 8, | |
| 202 }, | |
| 203 [PIX_FMT_MONOWHITE] = { | |
| 204 .name = "monow", | |
| 205 .nb_channels = 1, | |
| 206 .color_type = FF_COLOR_GRAY, | |
| 207 .pixel_type = FF_PIXEL_PLANAR, | |
| 208 .depth = 1, | |
| 209 }, | |
| 210 [PIX_FMT_MONOBLACK] = { | |
| 211 .name = "monob", | |
| 212 .nb_channels = 1, | |
| 213 .color_type = FF_COLOR_GRAY, | |
| 214 .pixel_type = FF_PIXEL_PLANAR, | |
| 215 .depth = 1, | |
| 216 }, | |
| 217 | |
| 218 /* paletted formats */ | |
| 219 [PIX_FMT_PAL8] = { | |
| 220 .name = "pal8", | |
| 221 .nb_channels = 4, .is_alpha = 1, | |
| 222 .color_type = FF_COLOR_RGB, | |
| 223 .pixel_type = FF_PIXEL_PALETTE, | |
| 224 .depth = 8, | |
| 225 }, | |
| 226 [PIX_FMT_XVMC_MPEG2_MC] = { | |
| 227 .name = "xvmcmc", | |
| 228 }, | |
| 229 [PIX_FMT_XVMC_MPEG2_IDCT] = { | |
| 230 .name = "xvmcidct", | |
| 231 }, | |
| 232 [PIX_FMT_UYVY411] = { | |
| 233 .name = "uyvy411", | |
| 234 .nb_channels = 1, | |
| 235 .color_type = FF_COLOR_YUV, | |
| 236 .pixel_type = FF_PIXEL_PACKED, | |
| 237 .depth = 8, | |
| 238 .x_chroma_shift = 2, .y_chroma_shift = 0, | |
| 239 }, | |
| 240 [PIX_FMT_BGR32] = { | |
| 241 .name = "bgr32", | |
| 242 .nb_channels = 4, .is_alpha = 1, | |
| 243 .color_type = FF_COLOR_RGB, | |
| 244 .pixel_type = FF_PIXEL_PACKED, | |
| 245 .depth = 8, | |
| 246 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 247 }, | |
| 248 [PIX_FMT_BGR565] = { | |
| 249 .name = "bgr565", | |
| 250 .nb_channels = 3, | |
| 251 .color_type = FF_COLOR_RGB, | |
| 252 .pixel_type = FF_PIXEL_PACKED, | |
| 253 .depth = 5, | |
| 254 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 255 }, | |
| 256 [PIX_FMT_BGR555] = { | |
| 257 .name = "bgr555", | |
| 258 .nb_channels = 4, .is_alpha = 1, | |
| 259 .color_type = FF_COLOR_RGB, | |
| 260 .pixel_type = FF_PIXEL_PACKED, | |
| 261 .depth = 5, | |
| 262 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 263 }, | |
| 264 [PIX_FMT_RGB8] = { | |
| 265 .name = "rgb8", | |
| 266 .nb_channels = 1, | |
| 267 .color_type = FF_COLOR_RGB, | |
| 268 .pixel_type = FF_PIXEL_PACKED, | |
| 269 .depth = 8, | |
| 270 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 271 }, | |
| 272 [PIX_FMT_RGB4] = { | |
| 273 .name = "rgb4", | |
| 274 .nb_channels = 1, | |
| 275 .color_type = FF_COLOR_RGB, | |
| 276 .pixel_type = FF_PIXEL_PACKED, | |
| 277 .depth = 4, | |
| 278 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 279 }, | |
| 280 [PIX_FMT_RGB4_BYTE] = { | |
| 281 .name = "rgb4_byte", | |
| 282 .nb_channels = 1, | |
| 283 .color_type = FF_COLOR_RGB, | |
| 284 .pixel_type = FF_PIXEL_PACKED, | |
| 285 .depth = 8, | |
| 286 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 287 }, | |
| 288 [PIX_FMT_BGR8] = { | |
| 289 .name = "bgr8", | |
| 290 .nb_channels = 1, | |
| 291 .color_type = FF_COLOR_RGB, | |
| 292 .pixel_type = FF_PIXEL_PACKED, | |
| 293 .depth = 8, | |
| 294 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 295 }, | |
| 296 [PIX_FMT_BGR4] = { | |
| 297 .name = "bgr4", | |
| 298 .nb_channels = 1, | |
| 299 .color_type = FF_COLOR_RGB, | |
| 300 .pixel_type = FF_PIXEL_PACKED, | |
| 301 .depth = 4, | |
| 302 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 303 }, | |
| 304 [PIX_FMT_BGR4_BYTE] = { | |
| 305 .name = "bgr4_byte", | |
| 306 .nb_channels = 1, | |
| 307 .color_type = FF_COLOR_RGB, | |
| 308 .pixel_type = FF_PIXEL_PACKED, | |
| 309 .depth = 8, | |
| 310 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 311 }, | |
| 312 [PIX_FMT_NV12] = { | |
| 313 .name = "nv12", | |
| 314 .nb_channels = 2, | |
| 315 .color_type = FF_COLOR_YUV, | |
| 316 .pixel_type = FF_PIXEL_PLANAR, | |
| 317 .depth = 8, | |
| 318 .x_chroma_shift = 1, .y_chroma_shift = 1, | |
| 319 }, | |
| 320 [PIX_FMT_NV21] = { | |
| 321 .name = "nv12", | |
| 322 .nb_channels = 2, | |
| 323 .color_type = FF_COLOR_YUV, | |
| 324 .pixel_type = FF_PIXEL_PLANAR, | |
| 325 .depth = 8, | |
| 326 .x_chroma_shift = 1, .y_chroma_shift = 1, | |
| 327 }, | |
| 328 | |
| 329 [PIX_FMT_BGR32_1] = { | |
| 330 .name = "bgr32_1", | |
| 331 .nb_channels = 4, .is_alpha = 1, | |
| 332 .color_type = FF_COLOR_RGB, | |
| 333 .pixel_type = FF_PIXEL_PACKED, | |
| 334 .depth = 8, | |
| 335 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 336 }, | |
| 337 [PIX_FMT_RGB32_1] = { | |
| 338 .name = "rgb32_1", | |
| 339 .nb_channels = 4, .is_alpha = 1, | |
| 340 .color_type = FF_COLOR_RGB, | |
| 341 .pixel_type = FF_PIXEL_PACKED, | |
| 342 .depth = 8, | |
| 343 .x_chroma_shift = 0, .y_chroma_shift = 0, | |
| 344 }, | |
| 345 }; | |
| 346 | |
| 347 void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift) | |
| 348 { | |
| 349 *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift; | |
| 350 *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift; | |
| 351 } | |
| 352 | |
| 353 const char *avcodec_get_pix_fmt_name(int pix_fmt) | |
| 354 { | |
| 355 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB) | |
| 356 return "???"; | |
| 357 else | |
| 358 return pix_fmt_info[pix_fmt].name; | |
| 359 } | |
| 360 | |
| 361 enum PixelFormat avcodec_get_pix_fmt(const char* name) | |
| 362 { | |
| 363 int i; | |
| 364 | |
| 365 for (i=0; i < PIX_FMT_NB; i++) | |
| 366 if (!strcmp(pix_fmt_info[i].name, name)) | |
| 367 break; | |
| 368 return i; | |
| 369 } | |
| 370 | |
| 371 /* Picture field are filled with 'ptr' addresses. Also return size */ | |
| 372 int avpicture_fill(AVPicture *picture, uint8_t *ptr, | |
| 373 int pix_fmt, int width, int height) | |
| 374 { | |
| 375 int size, w2, h2, size2; | |
| 376 const PixFmtInfo *pinfo; | |
| 377 | |
| 378 if(avcodec_check_dimensions(NULL, width, height)) | |
| 379 goto fail; | |
| 380 | |
| 381 pinfo = &pix_fmt_info[pix_fmt]; | |
| 382 size = width * height; | |
| 383 switch(pix_fmt) { | |
| 384 case PIX_FMT_YUV420P: | |
| 385 case PIX_FMT_YUV422P: | |
| 386 case PIX_FMT_YUV444P: | |
| 387 case PIX_FMT_YUV410P: | |
| 388 case PIX_FMT_YUV411P: | |
| 389 case PIX_FMT_YUVJ420P: | |
| 390 case PIX_FMT_YUVJ422P: | |
| 391 case PIX_FMT_YUVJ444P: | |
| 392 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift; | |
| 393 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift; | |
| 394 size2 = w2 * h2; | |
| 395 picture->data[0] = ptr; | |
| 396 picture->data[1] = picture->data[0] + size; | |
| 397 picture->data[2] = picture->data[1] + size2; | |
| 398 picture->linesize[0] = width; | |
| 399 picture->linesize[1] = w2; | |
| 400 picture->linesize[2] = w2; | |
| 401 return size + 2 * size2; | |
| 402 case PIX_FMT_NV12: | |
| 403 case PIX_FMT_NV21: | |
| 404 w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift; | |
| 405 h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift; | |
| 406 size2 = w2 * h2 * 2; | |
| 407 picture->data[0] = ptr; | |
| 408 picture->data[1] = picture->data[0] + size; | |
| 409 picture->data[2] = NULL; | |
| 410 picture->linesize[0] = width; | |
| 411 picture->linesize[1] = w2; | |
| 412 picture->linesize[2] = 0; | |
| 413 return size + 2 * size2; | |
| 414 case PIX_FMT_RGB24: | |
| 415 case PIX_FMT_BGR24: | |
| 416 picture->data[0] = ptr; | |
| 417 picture->data[1] = NULL; | |
| 418 picture->data[2] = NULL; | |
| 419 picture->linesize[0] = width * 3; | |
| 420 return size * 3; | |
| 421 case PIX_FMT_RGBA32: | |
| 422 case PIX_FMT_BGR32: | |
| 423 case PIX_FMT_RGB32_1: | |
| 424 case PIX_FMT_BGR32_1: | |
| 425 picture->data[0] = ptr; | |
| 426 picture->data[1] = NULL; | |
| 427 picture->data[2] = NULL; | |
| 428 picture->linesize[0] = width * 4; | |
| 429 return size * 4; | |
| 430 case PIX_FMT_BGR555: | |
| 431 case PIX_FMT_BGR565: | |
| 432 case PIX_FMT_RGB555: | |
| 433 case PIX_FMT_RGB565: | |
| 434 case PIX_FMT_YUV422: | |
| 435 picture->data[0] = ptr; | |
| 436 picture->data[1] = NULL; | |
| 437 picture->data[2] = NULL; | |
| 438 picture->linesize[0] = width * 2; | |
| 439 return size * 2; | |
| 440 case PIX_FMT_UYVY422: | |
| 441 picture->data[0] = ptr; | |
| 442 picture->data[1] = NULL; | |
| 443 picture->data[2] = NULL; | |
| 444 picture->linesize[0] = width * 2; | |
| 445 return size * 2; | |
| 446 case PIX_FMT_UYVY411: | |
| 447 picture->data[0] = ptr; | |
| 448 picture->data[1] = NULL; | |
| 449 picture->data[2] = NULL; | |
| 450 picture->linesize[0] = width + width/2; | |
| 451 return size + size/2; | |
| 452 case PIX_FMT_RGB8: | |
| 453 case PIX_FMT_BGR8: | |
| 454 case PIX_FMT_RGB4_BYTE: | |
| 455 case PIX_FMT_BGR4_BYTE: | |
| 456 case PIX_FMT_GRAY8: | |
| 457 picture->data[0] = ptr; | |
| 458 picture->data[1] = NULL; | |
| 459 picture->data[2] = NULL; | |
| 460 picture->linesize[0] = width; | |
| 461 return size; | |
| 462 case PIX_FMT_RGB4: | |
| 463 case PIX_FMT_BGR4: | |
| 464 picture->data[0] = ptr; | |
| 465 picture->data[1] = NULL; | |
| 466 picture->data[2] = NULL; | |
| 467 picture->linesize[0] = width / 2; | |
| 468 return size / 2; | |
| 469 case PIX_FMT_MONOWHITE: | |
| 470 case PIX_FMT_MONOBLACK: | |
| 471 picture->data[0] = ptr; | |
| 472 picture->data[1] = NULL; | |
| 473 picture->data[2] = NULL; | |
| 474 picture->linesize[0] = (width + 7) >> 3; | |
| 475 return picture->linesize[0] * height; | |
| 476 case PIX_FMT_PAL8: | |
| 477 size2 = (size + 3) & ~3; | |
| 478 picture->data[0] = ptr; | |
| 479 picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */ | |
| 480 picture->data[2] = NULL; | |
| 481 picture->linesize[0] = width; | |
| 482 picture->linesize[1] = 4; | |
| 483 return size2 + 256 * 4; | |
| 484 default: | |
| 485 fail: | |
| 486 picture->data[0] = NULL; | |
| 487 picture->data[1] = NULL; | |
| 488 picture->data[2] = NULL; | |
| 489 picture->data[3] = NULL; | |
| 490 return -1; | |
| 491 } | |
| 492 } | |
| 493 | |
| 494 int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height, | |
| 495 unsigned char *dest, int dest_size) | |
| 496 { | |
| 497 const PixFmtInfo* pf = &pix_fmt_info[pix_fmt]; | |
| 498 int i, j, w, h, data_planes; | |
| 499 const unsigned char* s; | |
| 500 int size = avpicture_get_size(pix_fmt, width, height); | |
| 501 | |
| 502 if (size > dest_size || size < 0) | |
| 503 return -1; | |
| 504 | |
| 505 if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) { | |
| 506 if (pix_fmt == PIX_FMT_YUV422 || | |
| 507 pix_fmt == PIX_FMT_UYVY422 || | |
| 508 pix_fmt == PIX_FMT_BGR565 || | |
| 509 pix_fmt == PIX_FMT_BGR565 || | |
| 510 pix_fmt == PIX_FMT_RGB565 || | |
| 511 pix_fmt == PIX_FMT_RGB555) | |
| 512 w = width * 2; | |
| 513 else if (pix_fmt == PIX_FMT_UYVY411) | |
| 514 w = width + width/2; | |
| 515 else if (pix_fmt == PIX_FMT_PAL8) | |
| 516 w = width; | |
| 517 else | |
| 518 w = width * (pf->depth * pf->nb_channels / 8); | |
| 519 | |
| 520 data_planes = 1; | |
| 521 h = height; | |
| 522 } else { | |
| 523 data_planes = pf->nb_channels; | |
| 524 w = (width*pf->depth + 7)/8; | |
| 525 h = height; | |
| 526 } | |
| 527 | |
| 528 for (i=0; i<data_planes; i++) { | |
| 529 if (i == 1) { | |
| 530 w = width >> pf->x_chroma_shift; | |
| 531 h = height >> pf->y_chroma_shift; | |
| 532 } | |
| 533 s = src->data[i]; | |
| 534 for(j=0; j<h; j++) { | |
| 535 memcpy(dest, s, w); | |
| 536 dest += w; | |
| 537 s += src->linesize[i]; | |
| 538 } | |
| 539 } | |
| 540 | |
| 541 if (pf->pixel_type == FF_PIXEL_PALETTE) | |
| 542 memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4); | |
| 543 | |
| 544 return size; | |
| 545 } | |
| 546 | |
| 547 int avpicture_get_size(int pix_fmt, int width, int height) | |
| 548 { | |
| 549 AVPicture dummy_pict; | |
| 550 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height); | |
| 551 } | |
| 552 | |
| 553 /** | |
| 554 * compute the loss when converting from a pixel format to another | |
| 555 */ | |
| 556 int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt, | |
| 557 int has_alpha) | |
| 558 { | |
| 559 const PixFmtInfo *pf, *ps; | |
| 560 int loss; | |
| 561 | |
| 562 ps = &pix_fmt_info[src_pix_fmt]; | |
| 563 pf = &pix_fmt_info[dst_pix_fmt]; | |
| 564 | |
| 565 /* compute loss */ | |
| 566 loss = 0; | |
| 567 pf = &pix_fmt_info[dst_pix_fmt]; | |
| 568 if (pf->depth < ps->depth || | |
| 569 (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565)) | |
| 570 loss |= FF_LOSS_DEPTH; | |
| 571 if (pf->x_chroma_shift > ps->x_chroma_shift || | |
| 572 pf->y_chroma_shift > ps->y_chroma_shift) | |
| 573 loss |= FF_LOSS_RESOLUTION; | |
| 574 switch(pf->color_type) { | |
| 575 case FF_COLOR_RGB: | |
| 576 if (ps->color_type != FF_COLOR_RGB && | |
| 577 ps->color_type != FF_COLOR_GRAY) | |
| 578 loss |= FF_LOSS_COLORSPACE; | |
| 579 break; | |
| 580 case FF_COLOR_GRAY: | |
| 581 if (ps->color_type != FF_COLOR_GRAY) | |
| 582 loss |= FF_LOSS_COLORSPACE; | |
| 583 break; | |
| 584 case FF_COLOR_YUV: | |
| 585 if (ps->color_type != FF_COLOR_YUV) | |
| 586 loss |= FF_LOSS_COLORSPACE; | |
| 587 break; | |
| 588 case FF_COLOR_YUV_JPEG: | |
| 589 if (ps->color_type != FF_COLOR_YUV_JPEG && | |
| 590 ps->color_type != FF_COLOR_YUV && | |
| 591 ps->color_type != FF_COLOR_GRAY) | |
| 592 loss |= FF_LOSS_COLORSPACE; | |
| 593 break; | |
| 594 default: | |
| 595 /* fail safe test */ | |
| 596 if (ps->color_type != pf->color_type) | |
| 597 loss |= FF_LOSS_COLORSPACE; | |
| 598 break; | |
| 599 } | |
| 600 if (pf->color_type == FF_COLOR_GRAY && | |
| 601 ps->color_type != FF_COLOR_GRAY) | |
| 602 loss |= FF_LOSS_CHROMA; | |
| 603 if (!pf->is_alpha && (ps->is_alpha && has_alpha)) | |
| 604 loss |= FF_LOSS_ALPHA; | |
| 605 if (pf->pixel_type == FF_PIXEL_PALETTE && | |
| 606 (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY)) | |
| 607 loss |= FF_LOSS_COLORQUANT; | |
| 608 return loss; | |
| 609 } | |
| 610 | |
| 611 static int avg_bits_per_pixel(int pix_fmt) | |
| 612 { | |
| 613 int bits; | |
| 614 const PixFmtInfo *pf; | |
| 615 | |
| 616 pf = &pix_fmt_info[pix_fmt]; | |
| 617 switch(pf->pixel_type) { | |
| 618 case FF_PIXEL_PACKED: | |
| 619 switch(pix_fmt) { | |
| 620 case PIX_FMT_YUV422: | |
| 621 case PIX_FMT_UYVY422: | |
| 622 case PIX_FMT_RGB565: | |
| 623 case PIX_FMT_RGB555: | |
| 624 case PIX_FMT_BGR565: | |
| 625 case PIX_FMT_BGR555: | |
| 626 bits = 16; | |
| 627 break; | |
| 628 case PIX_FMT_UYVY411: | |
| 629 bits = 12; | |
| 630 break; | |
| 631 default: | |
| 632 bits = pf->depth * pf->nb_channels; | |
| 633 break; | |
| 634 } | |
| 635 break; | |
| 636 case FF_PIXEL_PLANAR: | |
| 637 if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) { | |
| 638 bits = pf->depth * pf->nb_channels; | |
| 639 } else { | |
| 640 bits = pf->depth + ((2 * pf->depth) >> | |
| 641 (pf->x_chroma_shift + pf->y_chroma_shift)); | |
| 642 } | |
| 643 break; | |
| 644 case FF_PIXEL_PALETTE: | |
| 645 bits = 8; | |
| 646 break; | |
| 647 default: | |
| 648 bits = -1; | |
| 649 break; | |
| 650 } | |
| 651 return bits; | |
| 652 } | |
| 653 | |
| 654 static int avcodec_find_best_pix_fmt1(int pix_fmt_mask, | |
| 655 int src_pix_fmt, | |
| 656 int has_alpha, | |
| 657 int loss_mask) | |
| 658 { | |
| 659 int dist, i, loss, min_dist, dst_pix_fmt; | |
| 660 | |
| 661 /* find exact color match with smallest size */ | |
| 662 dst_pix_fmt = -1; | |
| 663 min_dist = 0x7fffffff; | |
| 664 for(i = 0;i < PIX_FMT_NB; i++) { | |
| 665 if (pix_fmt_mask & (1 << i)) { | |
| 666 loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask; | |
| 667 if (loss == 0) { | |
| 668 dist = avg_bits_per_pixel(i); | |
| 669 if (dist < min_dist) { | |
| 670 min_dist = dist; | |
| 671 dst_pix_fmt = i; | |
| 672 } | |
| 673 } | |
| 674 } | |
| 675 } | |
| 676 return dst_pix_fmt; | |
| 677 } | |
| 678 | |
| 679 /** | |
| 680 * find best pixel format to convert to. Return -1 if none found | |
| 681 */ | |
| 682 int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt, | |
| 683 int has_alpha, int *loss_ptr) | |
| 684 { | |
| 685 int dst_pix_fmt, loss_mask, i; | |
| 686 static const int loss_mask_order[] = { | |
| 687 ~0, /* no loss first */ | |
| 688 ~FF_LOSS_ALPHA, | |
| 689 ~FF_LOSS_RESOLUTION, | |
| 690 ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION), | |
| 691 ~FF_LOSS_COLORQUANT, | |
| 692 ~FF_LOSS_DEPTH, | |
| 693 0, | |
| 694 }; | |
| 695 | |
| 696 /* try with successive loss */ | |
| 697 i = 0; | |
| 698 for(;;) { | |
| 699 loss_mask = loss_mask_order[i++]; | |
| 700 dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt, | |
| 701 has_alpha, loss_mask); | |
| 702 if (dst_pix_fmt >= 0) | |
| 703 goto found; | |
| 704 if (loss_mask == 0) | |
| 705 break; | |
| 706 } | |
| 707 return -1; | |
| 708 found: | |
| 709 if (loss_ptr) | |
| 710 *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha); | |
| 711 return dst_pix_fmt; | |
| 712 } | |
| 713 | |
| 714 void ff_img_copy_plane(uint8_t *dst, int dst_wrap, | |
| 715 const uint8_t *src, int src_wrap, | |
| 716 int width, int height) | |
| 717 { | |
| 718 if((!dst) || (!src)) | |
| 719 return; | |
| 720 for(;height > 0; height--) { | |
| 721 memcpy(dst, src, width); | |
| 722 dst += dst_wrap; | |
| 723 src += src_wrap; | |
| 724 } | |
| 725 } | |
| 726 | |
| 727 /** | |
| 728 * Copy image 'src' to 'dst'. | |
| 729 */ | |
| 730 void img_copy(AVPicture *dst, const AVPicture *src, | |
| 731 int pix_fmt, int width, int height) | |
| 732 { | |
| 733 int bwidth, bits, i; | |
| 734 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt]; | |
| 735 | |
| 736 pf = &pix_fmt_info[pix_fmt]; | |
| 737 switch(pf->pixel_type) { | |
| 738 case FF_PIXEL_PACKED: | |
| 739 switch(pix_fmt) { | |
| 740 case PIX_FMT_YUV422: | |
| 741 case PIX_FMT_UYVY422: | |
| 742 case PIX_FMT_RGB565: | |
| 743 case PIX_FMT_RGB555: | |
| 744 case PIX_FMT_BGR565: | |
| 745 case PIX_FMT_BGR555: | |
| 746 bits = 16; | |
| 747 break; | |
| 748 case PIX_FMT_UYVY411: | |
| 749 bits = 12; | |
| 750 break; | |
| 751 default: | |
| 752 bits = pf->depth * pf->nb_channels; | |
| 753 break; | |
| 754 } | |
| 755 bwidth = (width * bits + 7) >> 3; | |
| 756 ff_img_copy_plane(dst->data[0], dst->linesize[0], | |
| 757 src->data[0], src->linesize[0], | |
| 758 bwidth, height); | |
| 759 break; | |
| 760 case FF_PIXEL_PLANAR: | |
| 761 for(i = 0; i < pf->nb_channels; i++) { | |
| 762 int w, h; | |
| 763 w = width; | |
| 764 h = height; | |
| 765 if (i == 1 || i == 2) { | |
| 766 w >>= pf->x_chroma_shift; | |
| 767 h >>= pf->y_chroma_shift; | |
| 768 } | |
| 769 bwidth = (w * pf->depth + 7) >> 3; | |
| 770 ff_img_copy_plane(dst->data[i], dst->linesize[i], | |
| 771 src->data[i], src->linesize[i], | |
| 772 bwidth, h); | |
| 773 } | |
| 774 break; | |
| 775 case FF_PIXEL_PALETTE: | |
| 776 ff_img_copy_plane(dst->data[0], dst->linesize[0], | |
| 777 src->data[0], src->linesize[0], | |
| 778 width, height); | |
| 779 /* copy the palette */ | |
| 780 ff_img_copy_plane(dst->data[1], dst->linesize[1], | |
| 781 src->data[1], src->linesize[1], | |
| 782 4, 256); | |
| 783 break; | |
| 784 } | |
| 785 } | |
| 786 | |
| 787 /* XXX: totally non optimized */ | |
| 788 | |
| 789 static void yuv422_to_yuv420p(AVPicture *dst, const AVPicture *src, | |
| 790 int width, int height) | |
| 791 { | |
| 792 const uint8_t *p, *p1; | |
| 793 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; | |
| 794 int w; | |
| 795 | |
| 796 p1 = src->data[0]; | |
| 797 lum1 = dst->data[0]; | |
| 798 cb1 = dst->data[1]; | |
| 799 cr1 = dst->data[2]; | |
| 800 | |
| 801 for(;height >= 1; height -= 2) { | |
| 802 p = p1; | |
| 803 lum = lum1; | |
| 804 cb = cb1; | |
| 805 cr = cr1; | |
| 806 for(w = width; w >= 2; w -= 2) { | |
| 807 lum[0] = p[0]; | |
| 808 cb[0] = p[1]; | |
| 809 lum[1] = p[2]; | |
| 810 cr[0] = p[3]; | |
| 811 p += 4; | |
| 812 lum += 2; | |
| 813 cb++; | |
| 814 cr++; | |
| 815 } | |
| 816 if (w) { | |
| 817 lum[0] = p[0]; | |
| 818 cb[0] = p[1]; | |
| 819 cr[0] = p[3]; | |
| 820 cb++; | |
| 821 cr++; | |
| 822 } | |
| 823 p1 += src->linesize[0]; | |
| 824 lum1 += dst->linesize[0]; | |
| 825 if (height>1) { | |
| 826 p = p1; | |
| 827 lum = lum1; | |
| 828 for(w = width; w >= 2; w -= 2) { | |
| 829 lum[0] = p[0]; | |
| 830 lum[1] = p[2]; | |
| 831 p += 4; | |
| 832 lum += 2; | |
| 833 } | |
| 834 if (w) { | |
| 835 lum[0] = p[0]; | |
| 836 } | |
| 837 p1 += src->linesize[0]; | |
| 838 lum1 += dst->linesize[0]; | |
| 839 } | |
| 840 cb1 += dst->linesize[1]; | |
| 841 cr1 += dst->linesize[2]; | |
| 842 } | |
| 843 } | |
| 844 | |
| 845 static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src, | |
| 846 int width, int height) | |
| 847 { | |
| 848 const uint8_t *p, *p1; | |
| 849 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; | |
| 850 int w; | |
| 851 | |
| 852 p1 = src->data[0]; | |
| 853 | |
| 854 lum1 = dst->data[0]; | |
| 855 cb1 = dst->data[1]; | |
| 856 cr1 = dst->data[2]; | |
| 857 | |
| 858 for(;height >= 1; height -= 2) { | |
| 859 p = p1; | |
| 860 lum = lum1; | |
| 861 cb = cb1; | |
| 862 cr = cr1; | |
| 863 for(w = width; w >= 2; w -= 2) { | |
| 864 lum[0] = p[1]; | |
| 865 cb[0] = p[0]; | |
| 866 lum[1] = p[3]; | |
| 867 cr[0] = p[2]; | |
| 868 p += 4; | |
| 869 lum += 2; | |
| 870 cb++; | |
| 871 cr++; | |
| 872 } | |
| 873 if (w) { | |
| 874 lum[0] = p[1]; | |
| 875 cb[0] = p[0]; | |
| 876 cr[0] = p[2]; | |
| 877 cb++; | |
| 878 cr++; | |
| 879 } | |
| 880 p1 += src->linesize[0]; | |
| 881 lum1 += dst->linesize[0]; | |
| 882 if (height>1) { | |
| 883 p = p1; | |
| 884 lum = lum1; | |
| 885 for(w = width; w >= 2; w -= 2) { | |
| 886 lum[0] = p[1]; | |
| 887 lum[1] = p[3]; | |
| 888 p += 4; | |
| 889 lum += 2; | |
| 890 } | |
| 891 if (w) { | |
| 892 lum[0] = p[1]; | |
| 893 } | |
| 894 p1 += src->linesize[0]; | |
| 895 lum1 += dst->linesize[0]; | |
| 896 } | |
| 897 cb1 += dst->linesize[1]; | |
| 898 cr1 += dst->linesize[2]; | |
| 899 } | |
| 900 } | |
| 901 | |
| 902 | |
| 903 static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src, | |
| 904 int width, int height) | |
| 905 { | |
| 906 const uint8_t *p, *p1; | |
| 907 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; | |
| 908 int w; | |
| 909 | |
| 910 p1 = src->data[0]; | |
| 911 lum1 = dst->data[0]; | |
| 912 cb1 = dst->data[1]; | |
| 913 cr1 = dst->data[2]; | |
| 914 for(;height > 0; height--) { | |
| 915 p = p1; | |
| 916 lum = lum1; | |
| 917 cb = cb1; | |
| 918 cr = cr1; | |
| 919 for(w = width; w >= 2; w -= 2) { | |
| 920 lum[0] = p[1]; | |
| 921 cb[0] = p[0]; | |
| 922 lum[1] = p[3]; | |
| 923 cr[0] = p[2]; | |
| 924 p += 4; | |
| 925 lum += 2; | |
| 926 cb++; | |
| 927 cr++; | |
| 928 } | |
| 929 p1 += src->linesize[0]; | |
| 930 lum1 += dst->linesize[0]; | |
| 931 cb1 += dst->linesize[1]; | |
| 932 cr1 += dst->linesize[2]; | |
| 933 } | |
| 934 } | |
| 935 | |
| 936 | |
| 937 static void yuv422_to_yuv422p(AVPicture *dst, const AVPicture *src, | |
| 938 int width, int height) | |
| 939 { | |
| 940 const uint8_t *p, *p1; | |
| 941 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; | |
| 942 int w; | |
| 943 | |
| 944 p1 = src->data[0]; | |
| 945 lum1 = dst->data[0]; | |
| 946 cb1 = dst->data[1]; | |
| 947 cr1 = dst->data[2]; | |
| 948 for(;height > 0; height--) { | |
| 949 p = p1; | |
| 950 lum = lum1; | |
| 951 cb = cb1; | |
| 952 cr = cr1; | |
| 953 for(w = width; w >= 2; w -= 2) { | |
| 954 lum[0] = p[0]; | |
| 955 cb[0] = p[1]; | |
| 956 lum[1] = p[2]; | |
| 957 cr[0] = p[3]; | |
| 958 p += 4; | |
| 959 lum += 2; | |
| 960 cb++; | |
| 961 cr++; | |
| 962 } | |
| 963 p1 += src->linesize[0]; | |
| 964 lum1 += dst->linesize[0]; | |
| 965 cb1 += dst->linesize[1]; | |
| 966 cr1 += dst->linesize[2]; | |
| 967 } | |
| 968 } | |
| 969 | |
| 970 static void yuv422p_to_yuv422(AVPicture *dst, const AVPicture *src, | |
| 971 int width, int height) | |
| 972 { | |
| 973 uint8_t *p, *p1; | |
| 974 const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; | |
| 975 int w; | |
| 976 | |
| 977 p1 = dst->data[0]; | |
| 978 lum1 = src->data[0]; | |
| 979 cb1 = src->data[1]; | |
| 980 cr1 = src->data[2]; | |
| 981 for(;height > 0; height--) { | |
| 982 p = p1; | |
| 983 lum = lum1; | |
| 984 cb = cb1; | |
| 985 cr = cr1; | |
| 986 for(w = width; w >= 2; w -= 2) { | |
| 987 p[0] = lum[0]; | |
| 988 p[1] = cb[0]; | |
| 989 p[2] = lum[1]; | |
| 990 p[3] = cr[0]; | |
| 991 p += 4; | |
| 992 lum += 2; | |
| 993 cb++; | |
| 994 cr++; | |
| 995 } | |
| 996 p1 += dst->linesize[0]; | |
| 997 lum1 += src->linesize[0]; | |
| 998 cb1 += src->linesize[1]; | |
| 999 cr1 += src->linesize[2]; | |
| 1000 } | |
| 1001 } | |
| 1002 | |
| 1003 static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src, | |
| 1004 int width, int height) | |
| 1005 { | |
| 1006 uint8_t *p, *p1; | |
| 1007 const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; | |
| 1008 int w; | |
| 1009 | |
| 1010 p1 = dst->data[0]; | |
| 1011 lum1 = src->data[0]; | |
| 1012 cb1 = src->data[1]; | |
| 1013 cr1 = src->data[2]; | |
| 1014 for(;height > 0; height--) { | |
| 1015 p = p1; | |
| 1016 lum = lum1; | |
| 1017 cb = cb1; | |
| 1018 cr = cr1; | |
| 1019 for(w = width; w >= 2; w -= 2) { | |
| 1020 p[1] = lum[0]; | |
| 1021 p[0] = cb[0]; | |
| 1022 p[3] = lum[1]; | |
| 1023 p[2] = cr[0]; | |
| 1024 p += 4; | |
| 1025 lum += 2; | |
| 1026 cb++; | |
| 1027 cr++; | |
| 1028 } | |
| 1029 p1 += dst->linesize[0]; | |
| 1030 lum1 += src->linesize[0]; | |
| 1031 cb1 += src->linesize[1]; | |
| 1032 cr1 += src->linesize[2]; | |
| 1033 } | |
| 1034 } | |
| 1035 | |
| 1036 static void uyvy411_to_yuv411p(AVPicture *dst, const AVPicture *src, | |
| 1037 int width, int height) | |
| 1038 { | |
| 1039 const uint8_t *p, *p1; | |
| 1040 uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; | |
| 1041 int w; | |
| 1042 | |
| 1043 p1 = src->data[0]; | |
| 1044 lum1 = dst->data[0]; | |
| 1045 cb1 = dst->data[1]; | |
| 1046 cr1 = dst->data[2]; | |
| 1047 for(;height > 0; height--) { | |
| 1048 p = p1; | |
| 1049 lum = lum1; | |
| 1050 cb = cb1; | |
| 1051 cr = cr1; | |
| 1052 for(w = width; w >= 4; w -= 4) { | |
| 1053 cb[0] = p[0]; | |
| 1054 lum[0] = p[1]; | |
| 1055 lum[1] = p[2]; | |
| 1056 cr[0] = p[3]; | |
| 1057 lum[2] = p[4]; | |
| 1058 lum[3] = p[5]; | |
| 1059 p += 6; | |
| 1060 lum += 4; | |
| 1061 cb++; | |
| 1062 cr++; | |
| 1063 } | |
| 1064 p1 += src->linesize[0]; | |
| 1065 lum1 += dst->linesize[0]; | |
| 1066 cb1 += dst->linesize[1]; | |
| 1067 cr1 += dst->linesize[2]; | |
| 1068 } | |
| 1069 } | |
| 1070 | |
| 1071 | |
| 1072 static void yuv420p_to_yuv422(AVPicture *dst, const AVPicture *src, | |
| 1073 int width, int height) | |
| 1074 { | |
| 1075 int w, h; | |
| 1076 uint8_t *line1, *line2, *linesrc = dst->data[0]; | |
| 1077 uint8_t *lum1, *lum2, *lumsrc = src->data[0]; | |
| 1078 uint8_t *cb1, *cb2 = src->data[1]; | |
| 1079 uint8_t *cr1, *cr2 = src->data[2]; | |
| 1080 | |
| 1081 for(h = height / 2; h--;) { | |
| 1082 line1 = linesrc; | |
| 1083 line2 = linesrc + dst->linesize[0]; | |
| 1084 | |
| 1085 lum1 = lumsrc; | |
| 1086 lum2 = lumsrc + src->linesize[0]; | |
| 1087 | |
| 1088 cb1 = cb2; | |
| 1089 cr1 = cr2; | |
| 1090 | |
| 1091 for(w = width / 2; w--;) { | |
| 1092 *line1++ = *lum1++; *line2++ = *lum2++; | |
| 1093 *line1++ = *line2++ = *cb1++; | |
| 1094 *line1++ = *lum1++; *line2++ = *lum2++; | |
| 1095 *line1++ = *line2++ = *cr1++; | |
| 1096 } | |
| 1097 | |
| 1098 linesrc += dst->linesize[0] * 2; | |
| 1099 lumsrc += src->linesize[0] * 2; | |
| 1100 cb2 += src->linesize[1]; | |
| 1101 cr2 += src->linesize[2]; | |
| 1102 } | |
| 1103 } | |
| 1104 | |
| 1105 static void yuv420p_to_uyvy422(AVPicture *dst, const AVPicture *src, | |
| 1106 int width, int height) | |
| 1107 { | |
| 1108 int w, h; | |
| 1109 uint8_t *line1, *line2, *linesrc = dst->data[0]; | |
| 1110 uint8_t *lum1, *lum2, *lumsrc = src->data[0]; | |
| 1111 uint8_t *cb1, *cb2 = src->data[1]; | |
| 1112 uint8_t *cr1, *cr2 = src->data[2]; | |
| 1113 | |
| 1114 for(h = height / 2; h--;) { | |
| 1115 line1 = linesrc; | |
| 1116 line2 = linesrc + dst->linesize[0]; | |
| 1117 | |
| 1118 lum1 = lumsrc; | |
| 1119 lum2 = lumsrc + src->linesize[0]; | |
| 1120 | |
| 1121 cb1 = cb2; | |
| 1122 cr1 = cr2; | |
| 1123 | |
| 1124 for(w = width / 2; w--;) { | |
| 1125 *line1++ = *line2++ = *cb1++; | |
| 1126 *line1++ = *lum1++; *line2++ = *lum2++; | |
| 1127 *line1++ = *line2++ = *cr1++; | |
| 1128 *line1++ = *lum1++; *line2++ = *lum2++; | |
| 1129 } | |
| 1130 | |
| 1131 linesrc += dst->linesize[0] * 2; | |
| 1132 lumsrc += src->linesize[0] * 2; | |
| 1133 cb2 += src->linesize[1]; | |
| 1134 cr2 += src->linesize[2]; | |
| 1135 } | |
| 1136 } | |
| 1137 | |
| 1138 #define SCALEBITS 10 | |
| 1139 #define ONE_HALF (1 << (SCALEBITS - 1)) | |
| 1140 #define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5)) | |
| 1141 | |
| 1142 #define YUV_TO_RGB1_CCIR(cb1, cr1)\ | |
| 1143 {\ | |
| 1144 cb = (cb1) - 128;\ | |
| 1145 cr = (cr1) - 128;\ | |
| 1146 r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\ | |
| 1147 g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \ | |
| 1148 ONE_HALF;\ | |
| 1149 b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\ | |
| 1150 } | |
| 1151 | |
| 1152 #define YUV_TO_RGB2_CCIR(r, g, b, y1)\ | |
| 1153 {\ | |
| 1154 y = ((y1) - 16) * FIX(255.0/219.0);\ | |
| 1155 r = cm[(y + r_add) >> SCALEBITS];\ | |
| 1156 g = cm[(y + g_add) >> SCALEBITS];\ | |
| 1157 b = cm[(y + b_add) >> SCALEBITS];\ | |
| 1158 } | |
| 1159 | |
| 1160 #define YUV_TO_RGB1(cb1, cr1)\ | |
| 1161 {\ | |
| 1162 cb = (cb1) - 128;\ | |
| 1163 cr = (cr1) - 128;\ | |
| 1164 r_add = FIX(1.40200) * cr + ONE_HALF;\ | |
| 1165 g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\ | |
| 1166 b_add = FIX(1.77200) * cb + ONE_HALF;\ | |
| 1167 } | |
| 1168 | |
| 1169 #define YUV_TO_RGB2(r, g, b, y1)\ | |
| 1170 {\ | |
| 1171 y = (y1) << SCALEBITS;\ | |
| 1172 r = cm[(y + r_add) >> SCALEBITS];\ | |
| 1173 g = cm[(y + g_add) >> SCALEBITS];\ | |
| 1174 b = cm[(y + b_add) >> SCALEBITS];\ | |
| 1175 } | |
| 1176 | |
| 1177 #define Y_CCIR_TO_JPEG(y)\ | |
| 1178 cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS] | |
| 1179 | |
| 1180 #define Y_JPEG_TO_CCIR(y)\ | |
| 1181 (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) | |
| 1182 | |
| 1183 #define C_CCIR_TO_JPEG(y)\ | |
| 1184 cm[(((y) - 128) * FIX(127.0/112.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS] | |
| 1185 | |
| 1186 /* NOTE: the clamp is really necessary! */ | |
| 1187 static inline int C_JPEG_TO_CCIR(int y) { | |
| 1188 y = (((y - 128) * FIX(112.0/127.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS); | |
| 1189 if (y < 16) | |
| 1190 y = 16; | |
| 1191 return y; | |
| 1192 } | |
| 1193 | |
| 1194 | |
| 1195 #define RGB_TO_Y(r, g, b) \ | |
| 1196 ((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \ | |
| 1197 FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS) | |
| 1198 | |
| 1199 #define RGB_TO_U(r1, g1, b1, shift)\ | |
| 1200 (((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \ | |
| 1201 FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) | |
| 1202 | |
| 1203 #define RGB_TO_V(r1, g1, b1, shift)\ | |
| 1204 (((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \ | |
| 1205 FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) | |
| 1206 | |
| 1207 #define RGB_TO_Y_CCIR(r, g, b) \ | |
| 1208 ((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \ | |
| 1209 FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) | |
| 1210 | |
| 1211 #define RGB_TO_U_CCIR(r1, g1, b1, shift)\ | |
| 1212 (((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \ | |
| 1213 FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) | |
| 1214 | |
| 1215 #define RGB_TO_V_CCIR(r1, g1, b1, shift)\ | |
| 1216 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \ | |
| 1217 FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) | |
| 1218 | |
| 1219 static uint8_t y_ccir_to_jpeg[256]; | |
| 1220 static uint8_t y_jpeg_to_ccir[256]; | |
| 1221 static uint8_t c_ccir_to_jpeg[256]; | |
| 1222 static uint8_t c_jpeg_to_ccir[256]; | |
| 1223 | |
| 1224 /* init various conversion tables */ | |
| 1225 static void img_convert_init(void) | |
| 1226 { | |
| 1227 int i; | |
| 1228 uint8_t *cm = cropTbl + MAX_NEG_CROP; | |
| 1229 | |
| 1230 for(i = 0;i < 256; i++) { | |
| 1231 y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i); | |
| 1232 y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i); | |
| 1233 c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i); | |
| 1234 c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i); | |
| 1235 } | |
| 1236 } | |
| 1237 | |
| 1238 /* apply to each pixel the given table */ | |
| 1239 static void img_apply_table(uint8_t *dst, int dst_wrap, | |
| 1240 const uint8_t *src, int src_wrap, | |
| 1241 int width, int height, const uint8_t *table1) | |
| 1242 { | |
| 1243 int n; | |
| 1244 const uint8_t *s; | |
| 1245 uint8_t *d; | |
| 1246 const uint8_t *table; | |
| 1247 | |
| 1248 table = table1; | |
| 1249 for(;height > 0; height--) { | |
| 1250 s = src; | |
| 1251 d = dst; | |
| 1252 n = width; | |
| 1253 while (n >= 4) { | |
| 1254 d[0] = table[s[0]]; | |
| 1255 d[1] = table[s[1]]; | |
| 1256 d[2] = table[s[2]]; | |
| 1257 d[3] = table[s[3]]; | |
| 1258 d += 4; | |
| 1259 s += 4; | |
| 1260 n -= 4; | |
| 1261 } | |
| 1262 while (n > 0) { | |
| 1263 d[0] = table[s[0]]; | |
| 1264 d++; | |
| 1265 s++; | |
| 1266 n--; | |
| 1267 } | |
| 1268 dst += dst_wrap; | |
| 1269 src += src_wrap; | |
| 1270 } | |
| 1271 } | |
| 1272 | |
| 1273 /* XXX: use generic filter ? */ | |
| 1274 /* XXX: in most cases, the sampling position is incorrect */ | |
| 1275 | |
| 1276 /* 4x1 -> 1x1 */ | |
| 1277 static void shrink41(uint8_t *dst, int dst_wrap, | |
| 1278 const uint8_t *src, int src_wrap, | |
| 1279 int width, int height) | |
| 1280 { | |
| 1281 int w; | |
| 1282 const uint8_t *s; | |
| 1283 uint8_t *d; | |
| 1284 | |
| 1285 for(;height > 0; height--) { | |
| 1286 s = src; | |
| 1287 d = dst; | |
| 1288 for(w = width;w > 0; w--) { | |
| 1289 d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2; | |
| 1290 s += 4; | |
| 1291 d++; | |
| 1292 } | |
| 1293 src += src_wrap; | |
| 1294 dst += dst_wrap; | |
| 1295 } | |
| 1296 } | |
| 1297 | |
| 1298 /* 2x1 -> 1x1 */ | |
| 1299 static void shrink21(uint8_t *dst, int dst_wrap, | |
| 1300 const uint8_t *src, int src_wrap, | |
| 1301 int width, int height) | |
| 1302 { | |
| 1303 int w; | |
| 1304 const uint8_t *s; | |
| 1305 uint8_t *d; | |
| 1306 | |
| 1307 for(;height > 0; height--) { | |
| 1308 s = src; | |
| 1309 d = dst; | |
| 1310 for(w = width;w > 0; w--) { | |
| 1311 d[0] = (s[0] + s[1]) >> 1; | |
| 1312 s += 2; | |
| 1313 d++; | |
| 1314 } | |
| 1315 src += src_wrap; | |
| 1316 dst += dst_wrap; | |
| 1317 } | |
| 1318 } | |
| 1319 | |
| 1320 /* 1x2 -> 1x1 */ | |
| 1321 static void shrink12(uint8_t *dst, int dst_wrap, | |
| 1322 const uint8_t *src, int src_wrap, | |
| 1323 int width, int height) | |
| 1324 { | |
| 1325 int w; | |
| 1326 uint8_t *d; | |
| 1327 const uint8_t *s1, *s2; | |
| 1328 | |
| 1329 for(;height > 0; height--) { | |
| 1330 s1 = src; | |
| 1331 s2 = s1 + src_wrap; | |
| 1332 d = dst; | |
| 1333 for(w = width;w >= 4; w-=4) { | |
| 1334 d[0] = (s1[0] + s2[0]) >> 1; | |
| 1335 d[1] = (s1[1] + s2[1]) >> 1; | |
| 1336 d[2] = (s1[2] + s2[2]) >> 1; | |
| 1337 d[3] = (s1[3] + s2[3]) >> 1; | |
| 1338 s1 += 4; | |
| 1339 s2 += 4; | |
| 1340 d += 4; | |
| 1341 } | |
| 1342 for(;w > 0; w--) { | |
| 1343 d[0] = (s1[0] + s2[0]) >> 1; | |
| 1344 s1++; | |
| 1345 s2++; | |
| 1346 d++; | |
| 1347 } | |
| 1348 src += 2 * src_wrap; | |
| 1349 dst += dst_wrap; | |
| 1350 } | |
| 1351 } | |
| 1352 | |
| 1353 /* 2x2 -> 1x1 */ | |
| 1354 void ff_shrink22(uint8_t *dst, int dst_wrap, | |
| 1355 const uint8_t *src, int src_wrap, | |
| 1356 int width, int height) | |
| 1357 { | |
| 1358 int w; | |
| 1359 const uint8_t *s1, *s2; | |
| 1360 uint8_t *d; | |
| 1361 | |
| 1362 for(;height > 0; height--) { | |
| 1363 s1 = src; | |
| 1364 s2 = s1 + src_wrap; | |
| 1365 d = dst; | |
| 1366 for(w = width;w >= 4; w-=4) { | |
| 1367 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2; | |
| 1368 d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2; | |
| 1369 d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2; | |
| 1370 d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2; | |
| 1371 s1 += 8; | |
| 1372 s2 += 8; | |
| 1373 d += 4; | |
| 1374 } | |
| 1375 for(;w > 0; w--) { | |
| 1376 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2; | |
| 1377 s1 += 2; | |
| 1378 s2 += 2; | |
| 1379 d++; | |
| 1380 } | |
| 1381 src += 2 * src_wrap; | |
| 1382 dst += dst_wrap; | |
| 1383 } | |
| 1384 } | |
| 1385 | |
| 1386 /* 4x4 -> 1x1 */ | |
| 1387 void ff_shrink44(uint8_t *dst, int dst_wrap, | |
| 1388 const uint8_t *src, int src_wrap, | |
| 1389 int width, int height) | |
| 1390 { | |
| 1391 int w; | |
| 1392 const uint8_t *s1, *s2, *s3, *s4; | |
| 1393 uint8_t *d; | |
| 1394 | |
| 1395 for(;height > 0; height--) { | |
| 1396 s1 = src; | |
| 1397 s2 = s1 + src_wrap; | |
| 1398 s3 = s2 + src_wrap; | |
| 1399 s4 = s3 + src_wrap; | |
| 1400 d = dst; | |
| 1401 for(w = width;w > 0; w--) { | |
| 1402 d[0] = (s1[0] + s1[1] + s1[2] + s1[3] + | |
| 1403 s2[0] + s2[1] + s2[2] + s2[3] + | |
| 1404 s3[0] + s3[1] + s3[2] + s3[3] + | |
| 1405 s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4; | |
| 1406 s1 += 4; | |
| 1407 s2 += 4; | |
| 1408 s3 += 4; | |
| 1409 s4 += 4; | |
| 1410 d++; | |
| 1411 } | |
| 1412 src += 4 * src_wrap; | |
| 1413 dst += dst_wrap; | |
| 1414 } | |
| 1415 } | |
| 1416 | |
| 1417 /* 8x8 -> 1x1 */ | |
| 1418 void ff_shrink88(uint8_t *dst, int dst_wrap, | |
| 1419 const uint8_t *src, int src_wrap, | |
| 1420 int width, int height) | |
| 1421 { | |
| 1422 int w, i; | |
| 1423 | |
| 1424 for(;height > 0; height--) { | |
| 1425 for(w = width;w > 0; w--) { | |
| 1426 int tmp=0; | |
| 1427 for(i=0; i<8; i++){ | |
| 1428 tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7]; | |
| 1429 src += src_wrap; | |
| 1430 } | |
| 1431 *(dst++) = (tmp + 32)>>6; | |
| 1432 src += 8 - 8*src_wrap; | |
| 1433 } | |
| 1434 src += 8*src_wrap - 8*width; | |
| 1435 dst += dst_wrap - width; | |
| 1436 } | |
| 1437 } | |
| 1438 | |
| 1439 static void grow21_line(uint8_t *dst, const uint8_t *src, | |
| 1440 int width) | |
| 1441 { | |
| 1442 int w; | |
| 1443 const uint8_t *s1; | |
| 1444 uint8_t *d; | |
| 1445 | |
| 1446 s1 = src; | |
| 1447 d = dst; | |
| 1448 for(w = width;w >= 4; w-=4) { | |
| 1449 d[1] = d[0] = s1[0]; | |
| 1450 d[3] = d[2] = s1[1]; | |
| 1451 s1 += 2; | |
| 1452 d += 4; | |
| 1453 } | |
| 1454 for(;w >= 2; w -= 2) { | |
| 1455 d[1] = d[0] = s1[0]; | |
| 1456 s1 ++; | |
| 1457 d += 2; | |
| 1458 } | |
| 1459 /* only needed if width is not a multiple of two */ | |
| 1460 /* XXX: veryfy that */ | |
| 1461 if (w) { | |
| 1462 d[0] = s1[0]; | |
| 1463 } | |
| 1464 } | |
| 1465 | |
| 1466 static void grow41_line(uint8_t *dst, const uint8_t *src, | |
| 1467 int width) | |
| 1468 { | |
| 1469 int w, v; | |
| 1470 const uint8_t *s1; | |
| 1471 uint8_t *d; | |
| 1472 | |
| 1473 s1 = src; | |
| 1474 d = dst; | |
| 1475 for(w = width;w >= 4; w-=4) { | |
| 1476 v = s1[0]; | |
| 1477 d[0] = v; | |
| 1478 d[1] = v; | |
| 1479 d[2] = v; | |
| 1480 d[3] = v; | |
| 1481 s1 ++; | |
| 1482 d += 4; | |
| 1483 } | |
| 1484 } | |
| 1485 | |
| 1486 /* 1x1 -> 2x1 */ | |
| 1487 static void grow21(uint8_t *dst, int dst_wrap, | |
| 1488 const uint8_t *src, int src_wrap, | |
| 1489 int width, int height) | |
| 1490 { | |
| 1491 for(;height > 0; height--) { | |
| 1492 grow21_line(dst, src, width); | |
| 1493 src += src_wrap; | |
| 1494 dst += dst_wrap; | |
| 1495 } | |
| 1496 } | |
| 1497 | |
| 1498 /* 1x1 -> 2x2 */ | |
| 1499 static void grow22(uint8_t *dst, int dst_wrap, | |
| 1500 const uint8_t *src, int src_wrap, | |
| 1501 int width, int height) | |
| 1502 { | |
| 1503 for(;height > 0; height--) { | |
| 1504 grow21_line(dst, src, width); | |
| 1505 if (height%2) | |
| 1506 src += src_wrap; | |
| 1507 dst += dst_wrap; | |
| 1508 } | |
| 1509 } | |
| 1510 | |
| 1511 /* 1x1 -> 4x1 */ | |
| 1512 static void grow41(uint8_t *dst, int dst_wrap, | |
| 1513 const uint8_t *src, int src_wrap, | |
| 1514 int width, int height) | |
| 1515 { | |
| 1516 for(;height > 0; height--) { | |
| 1517 grow41_line(dst, src, width); | |
| 1518 src += src_wrap; | |
| 1519 dst += dst_wrap; | |
| 1520 } | |
| 1521 } | |
| 1522 | |
| 1523 /* 1x1 -> 4x4 */ | |
| 1524 static void grow44(uint8_t *dst, int dst_wrap, | |
| 1525 const uint8_t *src, int src_wrap, | |
| 1526 int width, int height) | |
| 1527 { | |
| 1528 for(;height > 0; height--) { | |
| 1529 grow41_line(dst, src, width); | |
| 1530 if ((height & 3) == 1) | |
| 1531 src += src_wrap; | |
| 1532 dst += dst_wrap; | |
| 1533 } | |
| 1534 } | |
| 1535 | |
| 1536 /* 1x2 -> 2x1 */ | |
| 1537 static void conv411(uint8_t *dst, int dst_wrap, | |
| 1538 const uint8_t *src, int src_wrap, | |
| 1539 int width, int height) | |
| 1540 { | |
| 1541 int w, c; | |
| 1542 const uint8_t *s1, *s2; | |
| 1543 uint8_t *d; | |
| 1544 | |
| 1545 width>>=1; | |
| 1546 | |
| 1547 for(;height > 0; height--) { | |
| 1548 s1 = src; | |
| 1549 s2 = src + src_wrap; | |
| 1550 d = dst; | |
| 1551 for(w = width;w > 0; w--) { | |
| 1552 c = (s1[0] + s2[0]) >> 1; | |
| 1553 d[0] = c; | |
| 1554 d[1] = c; | |
| 1555 s1++; | |
| 1556 s2++; | |
| 1557 d += 2; | |
| 1558 } | |
| 1559 src += src_wrap * 2; | |
| 1560 dst += dst_wrap; | |
| 1561 } | |
| 1562 } | |
| 1563 | |
| 1564 /* XXX: add jpeg quantize code */ | |
| 1565 | |
| 1566 #define TRANSP_INDEX (6*6*6) | |
| 1567 | |
| 1568 /* this is maybe slow, but allows for extensions */ | |
| 1569 static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b) | |
| 1570 { | |
| 1571 return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6)); | |
| 1572 } | |
| 1573 | |
| 1574 static void build_rgb_palette(uint8_t *palette, int has_alpha) | |
| 1575 { | |
| 1576 uint32_t *pal; | |
| 1577 static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff }; | |
| 1578 int i, r, g, b; | |
| 1579 | |
| 1580 pal = (uint32_t *)palette; | |
| 1581 i = 0; | |
| 1582 for(r = 0; r < 6; r++) { | |
| 1583 for(g = 0; g < 6; g++) { | |
| 1584 for(b = 0; b < 6; b++) { | |
| 1585 pal[i++] = (0xff << 24) | (pal_value[r] << 16) | | |
| 1586 (pal_value[g] << 8) | pal_value[b]; | |
| 1587 } | |
| 1588 } | |
| 1589 } | |
| 1590 if (has_alpha) | |
| 1591 pal[i++] = 0; | |
| 1592 while (i < 256) | |
| 1593 pal[i++] = 0xff000000; | |
| 1594 } | |
| 1595 | |
| 1596 /* copy bit n to bits 0 ... n - 1 */ | |
| 1597 static inline unsigned int bitcopy_n(unsigned int a, int n) | |
| 1598 { | |
| 1599 int mask; | |
| 1600 mask = (1 << n) - 1; | |
| 1601 return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask); | |
| 1602 } | |
| 1603 | |
| 1604 /* rgb555 handling */ | |
| 1605 | |
| 1606 #define RGB_NAME rgb555 | |
| 1607 | |
| 1608 #define RGB_IN(r, g, b, s)\ | |
| 1609 {\ | |
| 1610 unsigned int v = ((const uint16_t *)(s))[0];\ | |
| 1611 r = bitcopy_n(v >> (10 - 3), 3);\ | |
| 1612 g = bitcopy_n(v >> (5 - 3), 3);\ | |
| 1613 b = bitcopy_n(v << 3, 3);\ | |
| 1614 } | |
| 1615 | |
| 1616 #define RGBA_IN(r, g, b, a, s)\ | |
| 1617 {\ | |
| 1618 unsigned int v = ((const uint16_t *)(s))[0];\ | |
| 1619 r = bitcopy_n(v >> (10 - 3), 3);\ | |
| 1620 g = bitcopy_n(v >> (5 - 3), 3);\ | |
| 1621 b = bitcopy_n(v << 3, 3);\ | |
| 1622 a = (-(v >> 15)) & 0xff;\ | |
| 1623 } | |
| 1624 | |
| 1625 #define RGBA_OUT(d, r, g, b, a)\ | |
| 1626 {\ | |
| 1627 ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3) | \ | |
| 1628 ((a << 8) & 0x8000);\ | |
| 1629 } | |
| 1630 | |
| 1631 #define BPP 2 | |
| 1632 | |
| 1633 #include "imgconvert_template.h" | |
| 1634 | |
| 1635 /* rgb565 handling */ | |
| 1636 | |
| 1637 #define RGB_NAME rgb565 | |
| 1638 | |
| 1639 #define RGB_IN(r, g, b, s)\ | |
| 1640 {\ | |
| 1641 unsigned int v = ((const uint16_t *)(s))[0];\ | |
| 1642 r = bitcopy_n(v >> (11 - 3), 3);\ | |
| 1643 g = bitcopy_n(v >> (5 - 2), 2);\ | |
| 1644 b = bitcopy_n(v << 3, 3);\ | |
| 1645 } | |
| 1646 | |
| 1647 #define RGB_OUT(d, r, g, b)\ | |
| 1648 {\ | |
| 1649 ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\ | |
| 1650 } | |
| 1651 | |
| 1652 #define BPP 2 | |
| 1653 | |
| 1654 #include "imgconvert_template.h" | |
| 1655 | |
| 1656 /* bgr24 handling */ | |
| 1657 | |
| 1658 #define RGB_NAME bgr24 | |
| 1659 | |
| 1660 #define RGB_IN(r, g, b, s)\ | |
| 1661 {\ | |
| 1662 b = (s)[0];\ | |
| 1663 g = (s)[1];\ | |
| 1664 r = (s)[2];\ | |
| 1665 } | |
| 1666 | |
| 1667 #define RGB_OUT(d, r, g, b)\ | |
| 1668 {\ | |
| 1669 (d)[0] = b;\ | |
| 1670 (d)[1] = g;\ | |
| 1671 (d)[2] = r;\ | |
| 1672 } | |
| 1673 | |
| 1674 #define BPP 3 | |
| 1675 | |
| 1676 #include "imgconvert_template.h" | |
| 1677 | |
| 1678 #undef RGB_IN | |
| 1679 #undef RGB_OUT | |
| 1680 #undef BPP | |
| 1681 | |
| 1682 /* rgb24 handling */ | |
| 1683 | |
| 1684 #define RGB_NAME rgb24 | |
| 1685 #define FMT_RGB24 | |
| 1686 | |
| 1687 #define RGB_IN(r, g, b, s)\ | |
| 1688 {\ | |
| 1689 r = (s)[0];\ | |
| 1690 g = (s)[1];\ | |
| 1691 b = (s)[2];\ | |
| 1692 } | |
| 1693 | |
| 1694 #define RGB_OUT(d, r, g, b)\ | |
| 1695 {\ | |
| 1696 (d)[0] = r;\ | |
| 1697 (d)[1] = g;\ | |
| 1698 (d)[2] = b;\ | |
| 1699 } | |
| 1700 | |
| 1701 #define BPP 3 | |
| 1702 | |
| 1703 #include "imgconvert_template.h" | |
| 1704 | |
| 1705 /* rgba32 handling */ | |
| 1706 | |
| 1707 #define RGB_NAME rgba32 | |
| 1708 #define FMT_RGBA32 | |
| 1709 | |
| 1710 #define RGB_IN(r, g, b, s)\ | |
| 1711 {\ | |
| 1712 unsigned int v = ((const uint32_t *)(s))[0];\ | |
| 1713 r = (v >> 16) & 0xff;\ | |
| 1714 g = (v >> 8) & 0xff;\ | |
| 1715 b = v & 0xff;\ | |
| 1716 } | |
| 1717 | |
| 1718 #define RGBA_IN(r, g, b, a, s)\ | |
| 1719 {\ | |
| 1720 unsigned int v = ((const uint32_t *)(s))[0];\ | |
| 1721 a = (v >> 24) & 0xff;\ | |
| 1722 r = (v >> 16) & 0xff;\ | |
| 1723 g = (v >> 8) & 0xff;\ | |
| 1724 b = v & 0xff;\ | |
| 1725 } | |
| 1726 | |
| 1727 #define RGBA_OUT(d, r, g, b, a)\ | |
| 1728 {\ | |
| 1729 ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\ | |
| 1730 } | |
| 1731 | |
| 1732 #define BPP 4 | |
| 1733 | |
| 1734 #include "imgconvert_template.h" | |
| 1735 | |
| 1736 static void mono_to_gray(AVPicture *dst, const AVPicture *src, | |
| 1737 int width, int height, int xor_mask) | |
| 1738 { | |
| 1739 const unsigned char *p; | |
| 1740 unsigned char *q; | |
| 1741 int v, dst_wrap, src_wrap; | |
| 1742 int y, w; | |
| 1743 | |
| 1744 p = src->data[0]; | |
| 1745 src_wrap = src->linesize[0] - ((width + 7) >> 3); | |
| 1746 | |
| 1747 q = dst->data[0]; | |
| 1748 dst_wrap = dst->linesize[0] - width; | |
| 1749 for(y=0;y<height;y++) { | |
| 1750 w = width; | |
| 1751 while (w >= 8) { | |
| 1752 v = *p++ ^ xor_mask; | |
| 1753 q[0] = -(v >> 7); | |
| 1754 q[1] = -((v >> 6) & 1); | |
| 1755 q[2] = -((v >> 5) & 1); | |
| 1756 q[3] = -((v >> 4) & 1); | |
| 1757 q[4] = -((v >> 3) & 1); | |
| 1758 q[5] = -((v >> 2) & 1); | |
| 1759 q[6] = -((v >> 1) & 1); | |
| 1760 q[7] = -((v >> 0) & 1); | |
| 1761 w -= 8; | |
| 1762 q += 8; | |
| 1763 } | |
| 1764 if (w > 0) { | |
| 1765 v = *p++ ^ xor_mask; | |
| 1766 do { | |
| 1767 q[0] = -((v >> 7) & 1); | |
| 1768 q++; | |
| 1769 v <<= 1; | |
| 1770 } while (--w); | |
| 1771 } | |
| 1772 p += src_wrap; | |
| 1773 q += dst_wrap; | |
| 1774 } | |
| 1775 } | |
| 1776 | |
| 1777 static void monowhite_to_gray(AVPicture *dst, const AVPicture *src, | |
| 1778 int width, int height) | |
| 1779 { | |
| 1780 mono_to_gray(dst, src, width, height, 0xff); | |
| 1781 } | |
| 1782 | |
| 1783 static void monoblack_to_gray(AVPicture *dst, const AVPicture *src, | |
| 1784 int width, int height) | |
| 1785 { | |
| 1786 mono_to_gray(dst, src, width, height, 0x00); | |
| 1787 } | |
| 1788 | |
| 1789 static void gray_to_mono(AVPicture *dst, const AVPicture *src, | |
| 1790 int width, int height, int xor_mask) | |
| 1791 { | |
| 1792 int n; | |
| 1793 const uint8_t *s; | |
| 1794 uint8_t *d; | |
| 1795 int j, b, v, n1, src_wrap, dst_wrap, y; | |
| 1796 | |
| 1797 s = src->data[0]; | |
| 1798 src_wrap = src->linesize[0] - width; | |
| 1799 | |
| 1800 d = dst->data[0]; | |
| 1801 dst_wrap = dst->linesize[0] - ((width + 7) >> 3); | |
| 1802 | |
| 1803 for(y=0;y<height;y++) { | |
| 1804 n = width; | |
| 1805 while (n >= 8) { | |
| 1806 v = 0; | |
| 1807 for(j=0;j<8;j++) { | |
| 1808 b = s[0]; | |
| 1809 s++; | |
| 1810 v = (v << 1) | (b >> 7); | |
| 1811 } | |
| 1812 d[0] = v ^ xor_mask; | |
| 1813 d++; | |
| 1814 n -= 8; | |
| 1815 } | |
| 1816 if (n > 0) { | |
| 1817 n1 = n; | |
| 1818 v = 0; | |
| 1819 while (n > 0) { | |
| 1820 b = s[0]; | |
| 1821 s++; | |
| 1822 v = (v << 1) | (b >> 7); | |
| 1823 n--; | |
| 1824 } | |
| 1825 d[0] = (v << (8 - (n1 & 7))) ^ xor_mask; | |
| 1826 d++; | |
| 1827 } | |
| 1828 s += src_wrap; | |
| 1829 d += dst_wrap; | |
| 1830 } | |
| 1831 } | |
| 1832 | |
| 1833 static void gray_to_monowhite(AVPicture *dst, const AVPicture *src, | |
| 1834 int width, int height) | |
| 1835 { | |
| 1836 gray_to_mono(dst, src, width, height, 0xff); | |
| 1837 } | |
| 1838 | |
| 1839 static void gray_to_monoblack(AVPicture *dst, const AVPicture *src, | |
| 1840 int width, int height) | |
| 1841 { | |
| 1842 gray_to_mono(dst, src, width, height, 0x00); | |
| 1843 } | |
| 1844 | |
| 1845 typedef struct ConvertEntry { | |
| 1846 void (*convert)(AVPicture *dst, | |
| 1847 const AVPicture *src, int width, int height); | |
| 1848 } ConvertEntry; | |
| 1849 | |
| 1850 /* Add each new convertion function in this table. In order to be able | |
| 1851 to convert from any format to any format, the following constraints | |
| 1852 must be satisfied: | |
| 1853 | |
| 1854 - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24 | |
| 1855 | |
| 1856 - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8 | |
| 1857 | |
| 1858 - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGBA32 | |
| 1859 | |
| 1860 - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from | |
| 1861 PIX_FMT_RGB24. | |
| 1862 | |
| 1863 - PIX_FMT_422 must convert to and from PIX_FMT_422P. | |
| 1864 | |
| 1865 The other conversion functions are just optimisations for common cases. | |
| 1866 */ | |
| 1867 static const ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = { | |
| 1868 [PIX_FMT_YUV420P] = { | |
| 1869 [PIX_FMT_YUV422] = { | |
| 1870 .convert = yuv420p_to_yuv422, | |
| 1871 }, | |
| 1872 [PIX_FMT_RGB555] = { | |
| 1873 .convert = yuv420p_to_rgb555 | |
| 1874 }, | |
| 1875 [PIX_FMT_RGB565] = { | |
| 1876 .convert = yuv420p_to_rgb565 | |
| 1877 }, | |
| 1878 [PIX_FMT_BGR24] = { | |
| 1879 .convert = yuv420p_to_bgr24 | |
| 1880 }, | |
| 1881 [PIX_FMT_RGB24] = { | |
| 1882 .convert = yuv420p_to_rgb24 | |
| 1883 }, | |
| 1884 [PIX_FMT_RGBA32] = { | |
| 1885 .convert = yuv420p_to_rgba32 | |
| 1886 }, | |
| 1887 [PIX_FMT_UYVY422] = { | |
| 1888 .convert = yuv420p_to_uyvy422, | |
| 1889 }, | |
| 1890 }, | |
| 1891 [PIX_FMT_YUV422P] = { | |
| 1892 [PIX_FMT_YUV422] = { | |
| 1893 .convert = yuv422p_to_yuv422, | |
| 1894 }, | |
| 1895 [PIX_FMT_UYVY422] = { | |
| 1896 .convert = yuv422p_to_uyvy422, | |
| 1897 }, | |
| 1898 }, | |
| 1899 [PIX_FMT_YUV444P] = { | |
| 1900 [PIX_FMT_RGB24] = { | |
| 1901 .convert = yuv444p_to_rgb24 | |
| 1902 }, | |
| 1903 }, | |
| 1904 [PIX_FMT_YUVJ420P] = { | |
| 1905 [PIX_FMT_RGB555] = { | |
| 1906 .convert = yuvj420p_to_rgb555 | |
| 1907 }, | |
| 1908 [PIX_FMT_RGB565] = { | |
| 1909 .convert = yuvj420p_to_rgb565 | |
| 1910 }, | |
| 1911 [PIX_FMT_BGR24] = { | |
| 1912 .convert = yuvj420p_to_bgr24 | |
| 1913 }, | |
| 1914 [PIX_FMT_RGB24] = { | |
| 1915 .convert = yuvj420p_to_rgb24 | |
| 1916 }, | |
| 1917 [PIX_FMT_RGBA32] = { | |
| 1918 .convert = yuvj420p_to_rgba32 | |
| 1919 }, | |
| 1920 }, | |
| 1921 [PIX_FMT_YUVJ444P] = { | |
| 1922 [PIX_FMT_RGB24] = { | |
| 1923 .convert = yuvj444p_to_rgb24 | |
| 1924 }, | |
| 1925 }, | |
| 1926 [PIX_FMT_YUV422] = { | |
| 1927 [PIX_FMT_YUV420P] = { | |
| 1928 .convert = yuv422_to_yuv420p, | |
| 1929 }, | |
| 1930 [PIX_FMT_YUV422P] = { | |
| 1931 .convert = yuv422_to_yuv422p, | |
| 1932 }, | |
| 1933 }, | |
| 1934 [PIX_FMT_UYVY422] = { | |
| 1935 [PIX_FMT_YUV420P] = { | |
| 1936 .convert = uyvy422_to_yuv420p, | |
| 1937 }, | |
| 1938 [PIX_FMT_YUV422P] = { | |
| 1939 .convert = uyvy422_to_yuv422p, | |
| 1940 }, | |
| 1941 }, | |
| 1942 [PIX_FMT_RGB24] = { | |
| 1943 [PIX_FMT_YUV420P] = { | |
| 1944 .convert = rgb24_to_yuv420p | |
| 1945 }, | |
| 1946 [PIX_FMT_RGB565] = { | |
| 1947 .convert = rgb24_to_rgb565 | |
| 1948 }, | |
| 1949 [PIX_FMT_RGB555] = { | |
| 1950 .convert = rgb24_to_rgb555 | |
| 1951 }, | |
| 1952 [PIX_FMT_RGBA32] = { | |
| 1953 .convert = rgb24_to_rgba32 | |
| 1954 }, | |
| 1955 [PIX_FMT_BGR24] = { | |
| 1956 .convert = rgb24_to_bgr24 | |
| 1957 }, | |
| 1958 [PIX_FMT_GRAY8] = { | |
| 1959 .convert = rgb24_to_gray | |
| 1960 }, | |
| 1961 [PIX_FMT_PAL8] = { | |
| 1962 .convert = rgb24_to_pal8 | |
| 1963 }, | |
| 1964 [PIX_FMT_YUV444P] = { | |
| 1965 .convert = rgb24_to_yuv444p | |
| 1966 }, | |
| 1967 [PIX_FMT_YUVJ420P] = { | |
| 1968 .convert = rgb24_to_yuvj420p | |
| 1969 }, | |
| 1970 [PIX_FMT_YUVJ444P] = { | |
| 1971 .convert = rgb24_to_yuvj444p | |
| 1972 }, | |
| 1973 }, | |
| 1974 [PIX_FMT_RGBA32] = { | |
| 1975 [PIX_FMT_RGB24] = { | |
| 1976 .convert = rgba32_to_rgb24 | |
| 1977 }, | |
| 1978 [PIX_FMT_RGB555] = { | |
| 1979 .convert = rgba32_to_rgb555 | |
| 1980 }, | |
| 1981 [PIX_FMT_PAL8] = { | |
| 1982 .convert = rgba32_to_pal8 | |
| 1983 }, | |
| 1984 [PIX_FMT_YUV420P] = { | |
| 1985 .convert = rgba32_to_yuv420p | |
| 1986 }, | |
| 1987 [PIX_FMT_GRAY8] = { | |
| 1988 .convert = rgba32_to_gray | |
| 1989 }, | |
| 1990 }, | |
| 1991 [PIX_FMT_BGR24] = { | |
| 1992 [PIX_FMT_RGB24] = { | |
| 1993 .convert = bgr24_to_rgb24 | |
| 1994 }, | |
| 1995 [PIX_FMT_YUV420P] = { | |
| 1996 .convert = bgr24_to_yuv420p | |
| 1997 }, | |
| 1998 [PIX_FMT_GRAY8] = { | |
| 1999 .convert = bgr24_to_gray | |
| 2000 }, | |
| 2001 }, | |
| 2002 [PIX_FMT_RGB555] = { | |
| 2003 [PIX_FMT_RGB24] = { | |
| 2004 .convert = rgb555_to_rgb24 | |
| 2005 }, | |
| 2006 [PIX_FMT_RGBA32] = { | |
| 2007 .convert = rgb555_to_rgba32 | |
| 2008 }, | |
| 2009 [PIX_FMT_YUV420P] = { | |
| 2010 .convert = rgb555_to_yuv420p | |
| 2011 }, | |
| 2012 [PIX_FMT_GRAY8] = { | |
| 2013 .convert = rgb555_to_gray | |
| 2014 }, | |
| 2015 }, | |
| 2016 [PIX_FMT_RGB565] = { | |
| 2017 [PIX_FMT_RGB24] = { | |
| 2018 .convert = rgb565_to_rgb24 | |
| 2019 }, | |
| 2020 [PIX_FMT_YUV420P] = { | |
| 2021 .convert = rgb565_to_yuv420p | |
| 2022 }, | |
| 2023 [PIX_FMT_GRAY8] = { | |
| 2024 .convert = rgb565_to_gray | |
| 2025 }, | |
| 2026 }, | |
| 2027 [PIX_FMT_GRAY8] = { | |
| 2028 [PIX_FMT_RGB555] = { | |
| 2029 .convert = gray_to_rgb555 | |
| 2030 }, | |
| 2031 [PIX_FMT_RGB565] = { | |
| 2032 .convert = gray_to_rgb565 | |
| 2033 }, | |
| 2034 [PIX_FMT_RGB24] = { | |
| 2035 .convert = gray_to_rgb24 | |
| 2036 }, | |
| 2037 [PIX_FMT_BGR24] = { | |
| 2038 .convert = gray_to_bgr24 | |
| 2039 }, | |
| 2040 [PIX_FMT_RGBA32] = { | |
| 2041 .convert = gray_to_rgba32 | |
| 2042 }, | |
| 2043 [PIX_FMT_MONOWHITE] = { | |
| 2044 .convert = gray_to_monowhite | |
| 2045 }, | |
| 2046 [PIX_FMT_MONOBLACK] = { | |
| 2047 .convert = gray_to_monoblack | |
| 2048 }, | |
| 2049 }, | |
| 2050 [PIX_FMT_MONOWHITE] = { | |
| 2051 [PIX_FMT_GRAY8] = { | |
| 2052 .convert = monowhite_to_gray | |
| 2053 }, | |
| 2054 }, | |
| 2055 [PIX_FMT_MONOBLACK] = { | |
| 2056 [PIX_FMT_GRAY8] = { | |
| 2057 .convert = monoblack_to_gray | |
| 2058 }, | |
| 2059 }, | |
| 2060 [PIX_FMT_PAL8] = { | |
| 2061 [PIX_FMT_RGB555] = { | |
| 2062 .convert = pal8_to_rgb555 | |
| 2063 }, | |
| 2064 [PIX_FMT_RGB565] = { | |
| 2065 .convert = pal8_to_rgb565 | |
| 2066 }, | |
| 2067 [PIX_FMT_BGR24] = { | |
| 2068 .convert = pal8_to_bgr24 | |
| 2069 }, | |
| 2070 [PIX_FMT_RGB24] = { | |
| 2071 .convert = pal8_to_rgb24 | |
| 2072 }, | |
| 2073 [PIX_FMT_RGBA32] = { | |
| 2074 .convert = pal8_to_rgba32 | |
| 2075 }, | |
| 2076 }, | |
| 2077 [PIX_FMT_UYVY411] = { | |
| 2078 [PIX_FMT_YUV411P] = { | |
| 2079 .convert = uyvy411_to_yuv411p, | |
| 2080 }, | |
| 2081 }, | |
| 2082 | |
| 2083 }; | |
| 2084 | |
| 2085 int avpicture_alloc(AVPicture *picture, | |
| 2086 int pix_fmt, int width, int height) | |
| 2087 { | |
| 2088 int size; | |
| 2089 void *ptr; | |
| 2090 | |
| 2091 size = avpicture_get_size(pix_fmt, width, height); | |
| 2092 if(size<0) | |
| 2093 goto fail; | |
| 2094 ptr = av_malloc(size); | |
| 2095 if (!ptr) | |
| 2096 goto fail; | |
| 2097 avpicture_fill(picture, ptr, pix_fmt, width, height); | |
| 2098 return 0; | |
| 2099 fail: | |
| 2100 memset(picture, 0, sizeof(AVPicture)); | |
| 2101 return -1; | |
| 2102 } | |
| 2103 | |
| 2104 void avpicture_free(AVPicture *picture) | |
| 2105 { | |
| 2106 av_free(picture->data[0]); | |
| 2107 } | |
| 2108 | |
| 2109 /* return true if yuv planar */ | |
| 2110 static inline int is_yuv_planar(const PixFmtInfo *ps) | |
| 2111 { | |
| 2112 return (ps->color_type == FF_COLOR_YUV || | |
| 2113 ps->color_type == FF_COLOR_YUV_JPEG) && | |
| 2114 ps->pixel_type == FF_PIXEL_PLANAR; | |
| 2115 } | |
| 2116 | |
| 2117 /** | |
| 2118 * Crop image top and left side | |
| 2119 */ | |
| 2120 int img_crop(AVPicture *dst, const AVPicture *src, | |
| 2121 int pix_fmt, int top_band, int left_band) | |
| 2122 { | |
| 2123 int y_shift; | |
| 2124 int x_shift; | |
| 2125 | |
| 2126 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt])) | |
| 2127 return -1; | |
| 2128 | |
| 2129 y_shift = pix_fmt_info[pix_fmt].y_chroma_shift; | |
| 2130 x_shift = pix_fmt_info[pix_fmt].x_chroma_shift; | |
| 2131 | |
| 2132 dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band; | |
| 2133 dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift); | |
| 2134 dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift); | |
| 2135 | |
| 2136 dst->linesize[0] = src->linesize[0]; | |
| 2137 dst->linesize[1] = src->linesize[1]; | |
| 2138 dst->linesize[2] = src->linesize[2]; | |
| 2139 return 0; | |
| 2140 } | |
| 2141 | |
| 2142 /** | |
| 2143 * Pad image | |
| 2144 */ | |
| 2145 int img_pad(AVPicture *dst, const AVPicture *src, int height, int width, int pix_fmt, | |
| 2146 int padtop, int padbottom, int padleft, int padright, int *color) | |
| 2147 { | |
| 2148 uint8_t *optr, *iptr; | |
| 2149 int y_shift; | |
| 2150 int x_shift; | |
| 2151 int yheight; | |
| 2152 int i, y; | |
| 2153 | |
| 2154 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt])) | |
| 2155 return -1; | |
| 2156 | |
| 2157 for (i = 0; i < 3; i++) { | |
| 2158 x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0; | |
| 2159 y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0; | |
| 2160 | |
| 2161 if (padtop || padleft) { | |
| 2162 memset(dst->data[i], color[i], dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift)); | |
| 2163 } | |
| 2164 | |
| 2165 if (padleft || padright || src) { | |
| 2166 if (src) { /* first line */ | |
| 2167 iptr = src->data[i]; | |
| 2168 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift); | |
| 2169 memcpy(optr, iptr, src->linesize[i]); | |
| 2170 iptr += src->linesize[i]; | |
| 2171 } | |
| 2172 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) + (dst->linesize[i] - (padright >> x_shift)); | |
| 2173 yheight = (height - 1 - (padtop + padbottom)) >> y_shift; | |
| 2174 for (y = 0; y < yheight; y++) { | |
| 2175 memset(optr, color[i], (padleft + padright) >> x_shift); | |
| 2176 if (src) { | |
| 2177 memcpy(optr + ((padleft + padright) >> x_shift), iptr, src->linesize[i]); | |
| 2178 iptr += src->linesize[i]; | |
| 2179 } | |
| 2180 optr += dst->linesize[i]; | |
| 2181 } | |
| 2182 } | |
| 2183 | |
| 2184 if (padbottom || padright) { | |
| 2185 optr = dst->data[i] + dst->linesize[i] * ((height - padbottom) >> y_shift) - (padright >> x_shift); | |
| 2186 memset(optr, color[i], dst->linesize[i] * (padbottom >> y_shift) + (padright >> x_shift)); | |
| 2187 } | |
| 2188 } | |
| 2189 return 0; | |
| 2190 } | |
| 2191 | |
| 2192 #ifndef CONFIG_SWSCALER | |
| 2193 /* XXX: always use linesize. Return -1 if not supported */ | |
| 2194 int img_convert(AVPicture *dst, int dst_pix_fmt, | |
| 2195 const AVPicture *src, int src_pix_fmt, | |
| 2196 int src_width, int src_height) | |
| 2197 { | |
| 2198 static int inited; | |
| 2199 int i, ret, dst_width, dst_height, int_pix_fmt; | |
| 2200 const PixFmtInfo *src_pix, *dst_pix; | |
| 2201 const ConvertEntry *ce; | |
| 2202 AVPicture tmp1, *tmp = &tmp1; | |
| 2203 | |
| 2204 if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB || | |
| 2205 dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB) | |
| 2206 return -1; | |
| 2207 if (src_width <= 0 || src_height <= 0) | |
| 2208 return 0; | |
| 2209 | |
| 2210 if (!inited) { | |
| 2211 inited = 1; | |
| 2212 img_convert_init(); | |
| 2213 } | |
| 2214 | |
| 2215 dst_width = src_width; | |
| 2216 dst_height = src_height; | |
| 2217 | |
| 2218 dst_pix = &pix_fmt_info[dst_pix_fmt]; | |
| 2219 src_pix = &pix_fmt_info[src_pix_fmt]; | |
| 2220 if (src_pix_fmt == dst_pix_fmt) { | |
| 2221 /* no conversion needed: just copy */ | |
| 2222 img_copy(dst, src, dst_pix_fmt, dst_width, dst_height); | |
| 2223 return 0; | |
| 2224 } | |
| 2225 | |
| 2226 ce = &convert_table[src_pix_fmt][dst_pix_fmt]; | |
| 2227 if (ce->convert) { | |
| 2228 /* specific conversion routine */ | |
| 2229 ce->convert(dst, src, dst_width, dst_height); | |
| 2230 return 0; | |
| 2231 } | |
| 2232 | |
| 2233 /* gray to YUV */ | |
| 2234 if (is_yuv_planar(dst_pix) && | |
| 2235 src_pix_fmt == PIX_FMT_GRAY8) { | |
| 2236 int w, h, y; | |
| 2237 uint8_t *d; | |
| 2238 | |
| 2239 if (dst_pix->color_type == FF_COLOR_YUV_JPEG) { | |
| 2240 ff_img_copy_plane(dst->data[0], dst->linesize[0], | |
| 2241 src->data[0], src->linesize[0], | |
| 2242 dst_width, dst_height); | |
| 2243 } else { | |
| 2244 img_apply_table(dst->data[0], dst->linesize[0], | |
| 2245 src->data[0], src->linesize[0], | |
| 2246 dst_width, dst_height, | |
| 2247 y_jpeg_to_ccir); | |
| 2248 } | |
| 2249 /* fill U and V with 128 */ | |
| 2250 w = dst_width; | |
| 2251 h = dst_height; | |
| 2252 w >>= dst_pix->x_chroma_shift; | |
| 2253 h >>= dst_pix->y_chroma_shift; | |
| 2254 for(i = 1; i <= 2; i++) { | |
| 2255 d = dst->data[i]; | |
| 2256 for(y = 0; y< h; y++) { | |
| 2257 memset(d, 128, w); | |
| 2258 d += dst->linesize[i]; | |
| 2259 } | |
| 2260 } | |
| 2261 return 0; | |
| 2262 } | |
| 2263 | |
| 2264 /* YUV to gray */ | |
| 2265 if (is_yuv_planar(src_pix) && | |
| 2266 dst_pix_fmt == PIX_FMT_GRAY8) { | |
| 2267 if (src_pix->color_type == FF_COLOR_YUV_JPEG) { | |
| 2268 ff_img_copy_plane(dst->data[0], dst->linesize[0], | |
| 2269 src->data[0], src->linesize[0], | |
| 2270 dst_width, dst_height); | |
| 2271 } else { | |
| 2272 img_apply_table(dst->data[0], dst->linesize[0], | |
| 2273 src->data[0], src->linesize[0], | |
| 2274 dst_width, dst_height, | |
| 2275 y_ccir_to_jpeg); | |
| 2276 } | |
| 2277 return 0; | |
| 2278 } | |
| 2279 | |
| 2280 /* YUV to YUV planar */ | |
| 2281 if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) { | |
| 2282 int x_shift, y_shift, w, h, xy_shift; | |
| 2283 void (*resize_func)(uint8_t *dst, int dst_wrap, | |
| 2284 const uint8_t *src, int src_wrap, | |
| 2285 int width, int height); | |
| 2286 | |
| 2287 /* compute chroma size of the smallest dimensions */ | |
| 2288 w = dst_width; | |
| 2289 h = dst_height; | |
| 2290 if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift) | |
| 2291 w >>= dst_pix->x_chroma_shift; | |
| 2292 else | |
| 2293 w >>= src_pix->x_chroma_shift; | |
| 2294 if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift) | |
| 2295 h >>= dst_pix->y_chroma_shift; | |
| 2296 else | |
| 2297 h >>= src_pix->y_chroma_shift; | |
| 2298 | |
| 2299 x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift); | |
| 2300 y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift); | |
| 2301 xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf); | |
| 2302 /* there must be filters for conversion at least from and to | |
| 2303 YUV444 format */ | |
| 2304 switch(xy_shift) { | |
| 2305 case 0x00: | |
| 2306 resize_func = ff_img_copy_plane; | |
| 2307 break; | |
| 2308 case 0x10: | |
| 2309 resize_func = shrink21; | |
| 2310 break; | |
| 2311 case 0x20: | |
| 2312 resize_func = shrink41; | |
| 2313 break; | |
| 2314 case 0x01: | |
| 2315 resize_func = shrink12; | |
| 2316 break; | |
| 2317 case 0x11: | |
| 2318 resize_func = ff_shrink22; | |
| 2319 break; | |
| 2320 case 0x22: | |
| 2321 resize_func = ff_shrink44; | |
| 2322 break; | |
| 2323 case 0xf0: | |
| 2324 resize_func = grow21; | |
| 2325 break; | |
| 2326 case 0xe0: | |
| 2327 resize_func = grow41; | |
| 2328 break; | |
| 2329 case 0xff: | |
| 2330 resize_func = grow22; | |
| 2331 break; | |
| 2332 case 0xee: | |
| 2333 resize_func = grow44; | |
| 2334 break; | |
| 2335 case 0xf1: | |
| 2336 resize_func = conv411; | |
| 2337 break; | |
| 2338 default: | |
| 2339 /* currently not handled */ | |
| 2340 goto no_chroma_filter; | |
| 2341 } | |
| 2342 | |
| 2343 ff_img_copy_plane(dst->data[0], dst->linesize[0], | |
| 2344 src->data[0], src->linesize[0], | |
| 2345 dst_width, dst_height); | |
| 2346 | |
| 2347 for(i = 1;i <= 2; i++) | |
| 2348 resize_func(dst->data[i], dst->linesize[i], | |
| 2349 src->data[i], src->linesize[i], | |
| 2350 dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift); | |
| 2351 /* if yuv color space conversion is needed, we do it here on | |
| 2352 the destination image */ | |
| 2353 if (dst_pix->color_type != src_pix->color_type) { | |
| 2354 const uint8_t *y_table, *c_table; | |
| 2355 if (dst_pix->color_type == FF_COLOR_YUV) { | |
| 2356 y_table = y_jpeg_to_ccir; | |
| 2357 c_table = c_jpeg_to_ccir; | |
| 2358 } else { | |
| 2359 y_table = y_ccir_to_jpeg; | |
| 2360 c_table = c_ccir_to_jpeg; | |
| 2361 } | |
| 2362 img_apply_table(dst->data[0], dst->linesize[0], | |
| 2363 dst->data[0], dst->linesize[0], | |
| 2364 dst_width, dst_height, | |
| 2365 y_table); | |
| 2366 | |
| 2367 for(i = 1;i <= 2; i++) | |
| 2368 img_apply_table(dst->data[i], dst->linesize[i], | |
| 2369 dst->data[i], dst->linesize[i], | |
| 2370 dst_width>>dst_pix->x_chroma_shift, | |
| 2371 dst_height>>dst_pix->y_chroma_shift, | |
| 2372 c_table); | |
| 2373 } | |
| 2374 return 0; | |
| 2375 } | |
| 2376 no_chroma_filter: | |
| 2377 | |
| 2378 /* try to use an intermediate format */ | |
| 2379 if (src_pix_fmt == PIX_FMT_YUV422 || | |
| 2380 dst_pix_fmt == PIX_FMT_YUV422) { | |
| 2381 /* specific case: convert to YUV422P first */ | |
| 2382 int_pix_fmt = PIX_FMT_YUV422P; | |
| 2383 } else if (src_pix_fmt == PIX_FMT_UYVY422 || | |
| 2384 dst_pix_fmt == PIX_FMT_UYVY422) { | |
| 2385 /* specific case: convert to YUV422P first */ | |
| 2386 int_pix_fmt = PIX_FMT_YUV422P; | |
| 2387 } else if (src_pix_fmt == PIX_FMT_UYVY411 || | |
| 2388 dst_pix_fmt == PIX_FMT_UYVY411) { | |
| 2389 /* specific case: convert to YUV411P first */ | |
| 2390 int_pix_fmt = PIX_FMT_YUV411P; | |
| 2391 } else if ((src_pix->color_type == FF_COLOR_GRAY && | |
| 2392 src_pix_fmt != PIX_FMT_GRAY8) || | |
| 2393 (dst_pix->color_type == FF_COLOR_GRAY && | |
| 2394 dst_pix_fmt != PIX_FMT_GRAY8)) { | |
| 2395 /* gray8 is the normalized format */ | |
| 2396 int_pix_fmt = PIX_FMT_GRAY8; | |
| 2397 } else if ((is_yuv_planar(src_pix) && | |
| 2398 src_pix_fmt != PIX_FMT_YUV444P && | |
| 2399 src_pix_fmt != PIX_FMT_YUVJ444P)) { | |
| 2400 /* yuv444 is the normalized format */ | |
| 2401 if (src_pix->color_type == FF_COLOR_YUV_JPEG) | |
| 2402 int_pix_fmt = PIX_FMT_YUVJ444P; | |
| 2403 else | |
| 2404 int_pix_fmt = PIX_FMT_YUV444P; | |
| 2405 } else if ((is_yuv_planar(dst_pix) && | |
| 2406 dst_pix_fmt != PIX_FMT_YUV444P && | |
| 2407 dst_pix_fmt != PIX_FMT_YUVJ444P)) { | |
| 2408 /* yuv444 is the normalized format */ | |
| 2409 if (dst_pix->color_type == FF_COLOR_YUV_JPEG) | |
| 2410 int_pix_fmt = PIX_FMT_YUVJ444P; | |
| 2411 else | |
| 2412 int_pix_fmt = PIX_FMT_YUV444P; | |
| 2413 } else { | |
| 2414 /* the two formats are rgb or gray8 or yuv[j]444p */ | |
| 2415 if (src_pix->is_alpha && dst_pix->is_alpha) | |
| 2416 int_pix_fmt = PIX_FMT_RGBA32; | |
| 2417 else | |
| 2418 int_pix_fmt = PIX_FMT_RGB24; | |
| 2419 } | |
| 2420 if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0) | |
| 2421 return -1; | |
| 2422 ret = -1; | |
| 2423 if (img_convert(tmp, int_pix_fmt, | |
| 2424 src, src_pix_fmt, src_width, src_height) < 0) | |
| 2425 goto fail1; | |
| 2426 if (img_convert(dst, dst_pix_fmt, | |
| 2427 tmp, int_pix_fmt, dst_width, dst_height) < 0) | |
| 2428 goto fail1; | |
| 2429 ret = 0; | |
| 2430 fail1: | |
| 2431 avpicture_free(tmp); | |
| 2432 return ret; | |
| 2433 } | |
| 2434 #endif | |
| 2435 | |
| 2436 /* NOTE: we scan all the pixels to have an exact information */ | |
| 2437 static int get_alpha_info_pal8(const AVPicture *src, int width, int height) | |
| 2438 { | |
| 2439 const unsigned char *p; | |
| 2440 int src_wrap, ret, x, y; | |
| 2441 unsigned int a; | |
| 2442 uint32_t *palette = (uint32_t *)src->data[1]; | |
| 2443 | |
| 2444 p = src->data[0]; | |
| 2445 src_wrap = src->linesize[0] - width; | |
| 2446 ret = 0; | |
| 2447 for(y=0;y<height;y++) { | |
| 2448 for(x=0;x<width;x++) { | |
| 2449 a = palette[p[0]] >> 24; | |
| 2450 if (a == 0x00) { | |
| 2451 ret |= FF_ALPHA_TRANSP; | |
| 2452 } else if (a != 0xff) { | |
| 2453 ret |= FF_ALPHA_SEMI_TRANSP; | |
| 2454 } | |
| 2455 p++; | |
| 2456 } | |
| 2457 p += src_wrap; | |
| 2458 } | |
| 2459 return ret; | |
| 2460 } | |
| 2461 | |
| 2462 /** | |
| 2463 * Tell if an image really has transparent alpha values. | |
| 2464 * @return ored mask of FF_ALPHA_xxx constants | |
| 2465 */ | |
| 2466 int img_get_alpha_info(const AVPicture *src, | |
| 2467 int pix_fmt, int width, int height) | |
| 2468 { | |
| 2469 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt]; | |
| 2470 int ret; | |
| 2471 | |
| 2472 pf = &pix_fmt_info[pix_fmt]; | |
| 2473 /* no alpha can be represented in format */ | |
| 2474 if (!pf->is_alpha) | |
| 2475 return 0; | |
| 2476 switch(pix_fmt) { | |
| 2477 case PIX_FMT_RGBA32: | |
| 2478 ret = get_alpha_info_rgba32(src, width, height); | |
| 2479 break; | |
| 2480 case PIX_FMT_RGB555: | |
| 2481 ret = get_alpha_info_rgb555(src, width, height); | |
| 2482 break; | |
| 2483 case PIX_FMT_PAL8: | |
| 2484 ret = get_alpha_info_pal8(src, width, height); | |
| 2485 break; | |
| 2486 default: | |
| 2487 /* we do not know, so everything is indicated */ | |
| 2488 ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP; | |
| 2489 break; | |
| 2490 } | |
| 2491 return ret; | |
| 2492 } | |
| 2493 | |
| 2494 #ifdef HAVE_MMX | |
| 2495 #define DEINT_INPLACE_LINE_LUM \ | |
| 2496 movd_m2r(lum_m4[0],mm0);\ | |
| 2497 movd_m2r(lum_m3[0],mm1);\ | |
| 2498 movd_m2r(lum_m2[0],mm2);\ | |
| 2499 movd_m2r(lum_m1[0],mm3);\ | |
| 2500 movd_m2r(lum[0],mm4);\ | |
| 2501 punpcklbw_r2r(mm7,mm0);\ | |
| 2502 movd_r2m(mm2,lum_m4[0]);\ | |
| 2503 punpcklbw_r2r(mm7,mm1);\ | |
| 2504 punpcklbw_r2r(mm7,mm2);\ | |
| 2505 punpcklbw_r2r(mm7,mm3);\ | |
| 2506 punpcklbw_r2r(mm7,mm4);\ | |
| 2507 paddw_r2r(mm3,mm1);\ | |
| 2508 psllw_i2r(1,mm2);\ | |
| 2509 paddw_r2r(mm4,mm0);\ | |
| 2510 psllw_i2r(2,mm1);\ | |
| 2511 paddw_r2r(mm6,mm2);\ | |
| 2512 paddw_r2r(mm2,mm1);\ | |
| 2513 psubusw_r2r(mm0,mm1);\ | |
| 2514 psrlw_i2r(3,mm1);\ | |
| 2515 packuswb_r2r(mm7,mm1);\ | |
| 2516 movd_r2m(mm1,lum_m2[0]); | |
| 2517 | |
| 2518 #define DEINT_LINE_LUM \ | |
| 2519 movd_m2r(lum_m4[0],mm0);\ | |
| 2520 movd_m2r(lum_m3[0],mm1);\ | |
| 2521 movd_m2r(lum_m2[0],mm2);\ | |
| 2522 movd_m2r(lum_m1[0],mm3);\ | |
| 2523 movd_m2r(lum[0],mm4);\ | |
| 2524 punpcklbw_r2r(mm7,mm0);\ | |
| 2525 punpcklbw_r2r(mm7,mm1);\ | |
| 2526 punpcklbw_r2r(mm7,mm2);\ | |
| 2527 punpcklbw_r2r(mm7,mm3);\ | |
| 2528 punpcklbw_r2r(mm7,mm4);\ | |
| 2529 paddw_r2r(mm3,mm1);\ | |
| 2530 psllw_i2r(1,mm2);\ | |
| 2531 paddw_r2r(mm4,mm0);\ | |
| 2532 psllw_i2r(2,mm1);\ | |
| 2533 paddw_r2r(mm6,mm2);\ | |
| 2534 paddw_r2r(mm2,mm1);\ | |
| 2535 psubusw_r2r(mm0,mm1);\ | |
| 2536 psrlw_i2r(3,mm1);\ | |
| 2537 packuswb_r2r(mm7,mm1);\ | |
| 2538 movd_r2m(mm1,dst[0]); | |
| 2539 #endif | |
| 2540 | |
| 2541 /* filter parameters: [-1 4 2 4 -1] // 8 */ | |
| 2542 static void deinterlace_line(uint8_t *dst, | |
| 2543 const uint8_t *lum_m4, const uint8_t *lum_m3, | |
| 2544 const uint8_t *lum_m2, const uint8_t *lum_m1, | |
| 2545 const uint8_t *lum, | |
| 2546 int size) | |
| 2547 { | |
| 2548 #ifndef HAVE_MMX | |
| 2549 uint8_t *cm = cropTbl + MAX_NEG_CROP; | |
| 2550 int sum; | |
| 2551 | |
| 2552 for(;size > 0;size--) { | |
| 2553 sum = -lum_m4[0]; | |
| 2554 sum += lum_m3[0] << 2; | |
| 2555 sum += lum_m2[0] << 1; | |
| 2556 sum += lum_m1[0] << 2; | |
| 2557 sum += -lum[0]; | |
| 2558 dst[0] = cm[(sum + 4) >> 3]; | |
| 2559 lum_m4++; | |
| 2560 lum_m3++; | |
| 2561 lum_m2++; | |
| 2562 lum_m1++; | |
| 2563 lum++; | |
| 2564 dst++; | |
| 2565 } | |
| 2566 #else | |
| 2567 | |
| 2568 { | |
| 2569 mmx_t rounder; | |
| 2570 rounder.uw[0]=4; | |
| 2571 rounder.uw[1]=4; | |
| 2572 rounder.uw[2]=4; | |
| 2573 rounder.uw[3]=4; | |
| 2574 pxor_r2r(mm7,mm7); | |
| 2575 movq_m2r(rounder,mm6); | |
| 2576 } | |
| 2577 for (;size > 3; size-=4) { | |
| 2578 DEINT_LINE_LUM | |
| 2579 lum_m4+=4; | |
| 2580 lum_m3+=4; | |
| 2581 lum_m2+=4; | |
| 2582 lum_m1+=4; | |
| 2583 lum+=4; | |
| 2584 dst+=4; | |
| 2585 } | |
| 2586 #endif | |
| 2587 } | |
| 2588 static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum, | |
| 2589 int size) | |
| 2590 { | |
| 2591 #ifndef HAVE_MMX | |
| 2592 uint8_t *cm = cropTbl + MAX_NEG_CROP; | |
| 2593 int sum; | |
| 2594 | |
| 2595 for(;size > 0;size--) { | |
| 2596 sum = -lum_m4[0]; | |
| 2597 sum += lum_m3[0] << 2; | |
| 2598 sum += lum_m2[0] << 1; | |
| 2599 lum_m4[0]=lum_m2[0]; | |
| 2600 sum += lum_m1[0] << 2; | |
| 2601 sum += -lum[0]; | |
| 2602 lum_m2[0] = cm[(sum + 4) >> 3]; | |
| 2603 lum_m4++; | |
| 2604 lum_m3++; | |
| 2605 lum_m2++; | |
| 2606 lum_m1++; | |
| 2607 lum++; | |
| 2608 } | |
| 2609 #else | |
| 2610 | |
| 2611 { | |
| 2612 mmx_t rounder; | |
| 2613 rounder.uw[0]=4; | |
| 2614 rounder.uw[1]=4; | |
| 2615 rounder.uw[2]=4; | |
| 2616 rounder.uw[3]=4; | |
| 2617 pxor_r2r(mm7,mm7); | |
| 2618 movq_m2r(rounder,mm6); | |
| 2619 } | |
| 2620 for (;size > 3; size-=4) { | |
| 2621 DEINT_INPLACE_LINE_LUM | |
| 2622 lum_m4+=4; | |
| 2623 lum_m3+=4; | |
| 2624 lum_m2+=4; | |
| 2625 lum_m1+=4; | |
| 2626 lum+=4; | |
| 2627 } | |
| 2628 #endif | |
| 2629 } | |
| 2630 | |
| 2631 /* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The | |
| 2632 top field is copied as is, but the bottom field is deinterlaced | |
| 2633 against the top field. */ | |
| 2634 static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap, | |
| 2635 const uint8_t *src1, int src_wrap, | |
| 2636 int width, int height) | |
| 2637 { | |
| 2638 const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2; | |
| 2639 int y; | |
| 2640 | |
| 2641 src_m2 = src1; | |
| 2642 src_m1 = src1; | |
| 2643 src_0=&src_m1[src_wrap]; | |
| 2644 src_p1=&src_0[src_wrap]; | |
| 2645 src_p2=&src_p1[src_wrap]; | |
| 2646 for(y=0;y<(height-2);y+=2) { | |
| 2647 memcpy(dst,src_m1,width); | |
| 2648 dst += dst_wrap; | |
| 2649 deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width); | |
| 2650 src_m2 = src_0; | |
| 2651 src_m1 = src_p1; | |
| 2652 src_0 = src_p2; | |
| 2653 src_p1 += 2*src_wrap; | |
| 2654 src_p2 += 2*src_wrap; | |
| 2655 dst += dst_wrap; | |
| 2656 } | |
| 2657 memcpy(dst,src_m1,width); | |
| 2658 dst += dst_wrap; | |
| 2659 /* do last line */ | |
| 2660 deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width); | |
| 2661 } | |
| 2662 | |
| 2663 static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap, | |
| 2664 int width, int height) | |
| 2665 { | |
| 2666 uint8_t *src_m1, *src_0, *src_p1, *src_p2; | |
| 2667 int y; | |
| 2668 uint8_t *buf; | |
| 2669 buf = (uint8_t*)av_malloc(width); | |
| 2670 | |
| 2671 src_m1 = src1; | |
| 2672 memcpy(buf,src_m1,width); | |
| 2673 src_0=&src_m1[src_wrap]; | |
| 2674 src_p1=&src_0[src_wrap]; | |
| 2675 src_p2=&src_p1[src_wrap]; | |
| 2676 for(y=0;y<(height-2);y+=2) { | |
| 2677 deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width); | |
| 2678 src_m1 = src_p1; | |
| 2679 src_0 = src_p2; | |
| 2680 src_p1 += 2*src_wrap; | |
| 2681 src_p2 += 2*src_wrap; | |
| 2682 } | |
| 2683 /* do last line */ | |
| 2684 deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width); | |
| 2685 av_free(buf); | |
| 2686 } | |
| 2687 | |
| 2688 | |
| 2689 /* deinterlace - if not supported return -1 */ | |
| 2690 int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, | |
| 2691 int pix_fmt, int width, int height) | |
| 2692 { | |
| 2693 int i; | |
| 2694 | |
| 2695 if (pix_fmt != PIX_FMT_YUV420P && | |
| 2696 pix_fmt != PIX_FMT_YUV422P && | |
| 2697 pix_fmt != PIX_FMT_YUV444P && | |
| 2698 pix_fmt != PIX_FMT_YUV411P) | |
| 2699 return -1; | |
| 2700 if ((width & 3) != 0 || (height & 3) != 0) | |
| 2701 return -1; | |
| 2702 | |
| 2703 for(i=0;i<3;i++) { | |
| 2704 if (i == 1) { | |
| 2705 switch(pix_fmt) { | |
| 2706 case PIX_FMT_YUV420P: | |
| 2707 width >>= 1; | |
| 2708 height >>= 1; | |
| 2709 break; | |
| 2710 case PIX_FMT_YUV422P: | |
| 2711 width >>= 1; | |
| 2712 break; | |
| 2713 case PIX_FMT_YUV411P: | |
| 2714 width >>= 2; | |
| 2715 break; | |
| 2716 default: | |
| 2717 break; | |
| 2718 } | |
| 2719 } | |
| 2720 if (src == dst) { | |
| 2721 deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i], | |
| 2722 width, height); | |
| 2723 } else { | |
| 2724 deinterlace_bottom_field(dst->data[i],dst->linesize[i], | |
| 2725 src->data[i], src->linesize[i], | |
| 2726 width, height); | |
| 2727 } | |
| 2728 } | |
| 2729 #ifdef HAVE_MMX | |
| 2730 emms(); | |
| 2731 #endif | |
| 2732 return 0; | |
| 2733 } | |
| 2734 | |
| 2735 #undef FIX |
