imgconvert.c
上传用户:chinavct
上传日期:2022-06-20
资源大小:330k
文件大小:80k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

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