imgconvert.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:66k
源码类别:

Windows CE

开发平台:

C/C++

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