imgconvert.c
上传用户:lctgjx
上传日期:2022-06-04
资源大小:8887k
文件大小:82k
源码类别:

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