gif 图片解析绘图 RGB 转YUV 查表法 ,降低CPU占有率

举报
aiot_bigbear 发表于 2022/09/25 02:01:51 2022/09/25
【摘要】 /*----------------------------------------------------------------------File : GIFPICTURE.cPurpose : Implementation of picture widget-------------------------...

  
  1. /*
  2. ----------------------------------------------------------------------
  3. File : GIFPICTURE.c
  4. Purpose : Implementation of picture widget
  5. ---------------------------END-OF-HEADER------------------------------
  6. */
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "gif_lib.h"
  10. #include "pf_layer.h"
  11. #include "mod_date_time.h"
  12. #include "mod_time_list.h"
  13. #include "gxdemux.h"
  14. #include "gxvideo.h"
  15. #include "gxaudio.h"
  16. #include "sys_assert.h"
  17. #include "gxdisp.h"
  18. #include "stb_app.h"
  19. #include "media_type.h"
  20. #include "gxdenc.h"
  21. #include "gxvmix.h"
  22. #include "av.h"
  23. typedef struct GifColorPalette
  24. {
  25. ByteType Red, Green, Blue;
  26. } GifColorPalette;
  27. typedef struct {
  28. U16 time_id;
  29. GifFileType *GifFile;
  30. const U8* pGifData;
  31. //unsigned int palette[256];
  32. GifColorPalette palette[256];
  33. U32 nTransColor;
  34. U32 CurrentImage;
  35. } GifData_t;
  36. #include "GUIType.h"
  37. extern unsigned char ad_pic_osd_buffer[178*100];
  38. extern GUI_CONST_STORAGE GUI_BITMAP ad_pic_osd_struct ;
  39. static GifData_t GifData;
  40. //extern unsigned short g_SppBuffer[700 * 576 ];
  41. static int InterlacedOffset[] = { 0, 4, 2, 1 }, InterlacedJumps[] = { 8, 8, 4, 2 };
  42. //extern BOOL bAdShowFlag;
  43. //extern U32 nCapturePpNum;
  44. static unsigned short int gif_period_time=0;
  45. //unsigned short disposal_mothod=0;
  46. #if 0
  47. static unsigned char y_r[256];
  48. static unsigned char y_g[256];
  49. static unsigned char y_b[256];
  50. static unsigned char u_r[256];
  51. static unsigned char u_g[256];
  52. static unsigned char u_b[256];
  53. static unsigned char v_r[256];
  54. static unsigned char v_g[256];
  55. static unsigned char v_b[256];
  56. static void gif_init_Palette(void)
  57. {
  58. int i=0;
  59. for(i=0;i<256;i++)
  60. {
  61. #if 0
  62. y_r[i]=66 * i/ 256;
  63. u_r[i]=38* i/ 256;
  64. v_r[i]=112 * i/ 256;
  65. y_g[i]=129* i/ 256;
  66. u_g[i]=74 * i/ 256;
  67. v_g[i]=94 * i/ 256;
  68. y_b[i]=25* i/ 256;
  69. u_b[i]=112 * i/ 256;
  70. v_b[i]=18 * i/ 256;
  71. #else
  72. y_r[i]=(66 * i)>>8;
  73. u_r[i]=(38* i)>>8;
  74. v_r[i]=(112 * i)>>8;
  75. y_g[i]=(129* i)>>8;
  76. u_g[i]=(74 * i)>>8;
  77. v_g[i]=(94 * i)>>8;
  78. y_b[i]=(25* i)>>8;
  79. u_b[i]=(112 * i)>>8;
  80. v_b[i]=(18 * i)>>8;
  81. #endif
  82. }
  83. }
  84. #endif
  85. static int gif_time_callback_osd(void)
  86. {
  87. //*(volatile int*)0x40005028 |= (1<<1);
  88. GifFileType *GifFile=GifData.GifFile;
  89. int i, j,ExtCode=0,Len,Row, Col, Width, Height,Count, RealWidth;
  90. GifRecordType RecordType;
  91. ByteType *Extension;
  92. unsigned char r,g,b ;
  93. //unsigned short y2,u,v;//add for trans
  94. //unsigned int y = 0,cb0=0,cr0 = 0;
  95. //unsigned short cby = 0,cry = 0;
  96. //unsigned short *pPicUse = (unsigned short*)g_SppBuffer;
  97. PixelType *Line;
  98. #if 0
  99. int color;
  100. unsigned int CurrentImagePalette[256];
  101. #else
  102. GifColorPalette Current_GifColorPalette[256]={{0,},};
  103. GifColorPalette color={0,};
  104. #endif
  105. // unsigned char nDelayTime=0;
  106. //SYS_PRINTF("case gif_time_callback\n");
  107. if (DGifGetRecordType(GifFile, &RecordType) == ERROR) {
  108. return TERMINATE_RECORD_ERROR;
  109. }
  110. GifFile->SWidth= ((GifFile->SWidth % 2) ? (GifFile->SWidth - 1) : (GifFile->SWidth));
  111. switch (RecordType) {
  112. case IMAGE_DESC_RECORD_TYPE:
  113. //SYS_PRINTF("case IMAGE_DESC_RECORD_TYPE\n");
  114. if (DGifGetImageDesc(GifFile) == ERROR) {
  115. // SYS_PRINTF("DGifGetImageDesc(GifFile) == ERROR \n");
  116. return TERMINATE_RECORD_ERROR;
  117. }
  118. SYS_PRINTF("pic CurrentImage = %d ITop=%d ILeft=%d IWidth=%d IHeight=%d \n", GifData.CurrentImage, GifFile->ITop, GifFile->ILeft, GifFile->IWidth, GifFile->IHeight );
  119. if ( GifFile->IColorMap)
  120. {
  121. SYS_PRINTF("pic use IColorMap \n");
  122. Len = 1 << GifFile->SBitsPerPixel;
  123. for (i = 0; i < Len; i++)
  124. {
  125. Current_GifColorPalette[i].Blue=GifFile->IColorMap[i].Blue;
  126. Current_GifColorPalette[i].Green=GifFile->IColorMap[i].Green;
  127. Current_GifColorPalette[i].Red=GifFile->IColorMap[i].Red;
  128. }
  129. }
  130. else
  131. {
  132. SYS_PRINTF("pic use SColorMap \n");
  133. memcpy(Current_GifColorPalette, GifData.palette, 256*sizeof(GifColorPalette));
  134. }
  135. Line = (PixelType *) malloc(GifFile->IWidth *sizeof(PixelType));
  136. Row = GifFile->ITop; /* Image Position relative to Screen */
  137. Col = GifFile->ILeft;
  138. Width = GifFile->IWidth;
  139. Height = GifFile->IHeight;
  140. {
  141. RealWidth = (GifFile->IWidth % 2)?(GifFile->IWidth - 1):GifFile->IWidth;
  142. for (i=0; i< GifFile->IHeight; i++)
  143. {
  144. if (DGifGetLine(GifFile, Line, GifFile->IWidth) == ERROR)
  145. {
  146. //SYS_PRINTF("pic DGifGetLine ERROR\n");
  147. return TERMINATE_RECORD_ERROR;
  148. }
  149. //SYS_PRINTF("%d %d %d \n", GifData.palette[Line[10]], GifData.palette[Line[13]], GifData.palette[Line[45]]);
  150. for(j = 0; j < RealWidth; j++)
  151. {
  152. if(GifData.CurrentImage == 0)
  153. {
  154. //if(Line[j] != GifData.nTransColor)
  155. ad_pic_osd_buffer[(GifFile->ITop+i)*GifFile->SWidth + GifFile->ILeft + j ]=Line[j];
  156. //else
  157. //ad_pic_osd_buffer[(GifFile->ITop+i)*GifFile->SWidth + GifFile->ILeft + j ]=0;
  158. }
  159. else
  160. {
  161. //if(Line[j] != GifData.nTransColor)
  162. {
  163. ad_pic_osd_buffer[(GifFile->ITop+i)*GifFile->SWidth + GifFile->ILeft + j ]=Line[j];
  164. }
  165. }
  166. }
  167. }
  168. }
  169. free(Line);
  170. GifData.CurrentImage++;
  171. return IMAGE_DESC_RECORD_TYPE;
  172. break;
  173. case EXTENSION_RECORD_TYPE:
  174. /*图形控制扩展(Graphic Control Extension)
  175. 这一部分是可选的(需要89a版本),可以放在一个图象块(包括图象标识符、局部颜色列表和图象数据)或文本扩展块的前面,用来控制跟在它后面的第一个图象(或文本)的渲染(Render)形式,组成结构如下:
  176. BYTE 7 6 5 4 3 2 1 0 BIT
  177. 扩展块标识 Extension Introducer - 标识这是一个扩展块,固定值0x21
  178. 图形控制扩展标签 Graphic Control Label - 标识这是一个图形控制扩展块,固定值0xF9
  179. 块大小 Block Size - 不包括块终结器,固定值4
  180. 保留 处置方法 i
  181. t
  182. i - 用户输入标志;t - 透明色标志。
  183. 延迟时间 Delay Time - 单位1/100秒,如果值不为1,表示暂停规定的时间后再继续往下处理数据流
  184. 透明色索引 Transparent Color Index - 透明色索引值
  185. 块终结器 Block Terminator - 标识块终结,固定值0
  186. 处置方法(Disposal Method):指出处置图形的方法,当值为:
  187. 0 - 不使用处置方法
  188. 1 - 不处置图形,把图形从当前位置移去
  189. 2 - 回复到背景色
  190. 3 - 回复到先前状态
  191. 4-7 - 自定义
  192. 用户输入标志(Use Input Flag):指出是否期待用户有输入之后才继续进行下去,置位表示期待,值否表示不期待。用户输入可以是按回车键、鼠标点击等,可以和延迟时间一起使用,在设置的延迟时间内用户有输入则马上继续进行,或者没有输入直到延迟时间到达而继续
  193. 透明颜色标志(Transparent Color Flag):置位表示使用透明颜色
  194. */
  195. //SYS_PRINTF("case EXTENSION_RECORD_TYPE\n");
  196. if (DGifGetExtension(GifFile, &ExtCode, &Extension) == ERROR) {
  197. return TERMINATE_RECORD_ERROR;
  198. }
  199. if(ExtCode == 0xF9)
  200. {
  201. // SYS_PRINTF("Extension[1]=0x%x\n",Extension[1]);
  202. //disposal_mothod=(Extension[1]&0x1c)>>2;
  203. if((Extension[1] & 0x01) == 1)
  204. {
  205. GifData.nTransColor = Extension[4];//nClut;
  206. SYS_PRINTF("GifData.nTransColor=0x%x\n",GifData.nTransColor);
  207. }
  208. gif_period_time = (Extension[3]<<8)|Extension[2];
  209. }
  210. while (Extension != NULL) {
  211. if (DGifGetExtensionNext(GifFile, &Extension) == ERROR) {
  212. return TERMINATE_RECORD_ERROR;
  213. }
  214. }
  215. return EXTENSION_RECORD_TYPE;
  216. break;
  217. case TERMINATE_RECORD_TYPE:
  218. //SYS_PRINTF("case TERMINATE_RECORD_TYPE\n");
  219. GifData.CurrentImage = 0;
  220. GifData.nTransColor=0;
  221. DGifSetCurrentData(GifFile, GifData.pGifData);
  222. return TERMINATE_RECORD_TYPE;
  223. break;
  224. default: /* Should be traps by DGifGetRecordType */
  225. break;
  226. }
  227. return TERMINATE_RECORD_ERROR;
  228. }
  229. int gif_drow_one_frame_osd(void);
  230. int gif_drow_other_frame_osd(void);
  231. int gif_drow_one_frame_osd(void)
  232. {
  233. int err;
  234. err = gif_time_callback_osd();//第一次立刻画出一帧,免得出现绿色花屏
  235. while(err != TERMINATE_RECORD_ERROR && err != IMAGE_DESC_RECORD_TYPE)
  236. //while(err != IMAGE_DESC_RECORD_TYPE)
  237. {
  238. err = gif_time_callback_osd();//第一次立刻画出一帧,免得出现绿色花屏,直到调用画第一帧图像接口
  239. //if(err == TERMINATE_RECORD_ERROR )
  240. //return 0;
  241. }
  242. return 1;
  243. }
  244. int gif_drow_other_frame_osd(void)
  245. {
  246. int err;
  247. //*(volatile int*)0x40005028 |= (1<<1);
  248. #if 0
  249. if(GifData.time_id)
  250. {
  251. time_release(GifData.time_id);
  252. GifData.time_id = 0;
  253. }
  254. #endif
  255. err = gif_time_callback_osd();//第一次立刻画出一帧,免得出现绿色花屏
  256. while(err != TERMINATE_RECORD_ERROR && err != IMAGE_DESC_RECORD_TYPE)
  257. //while(err != IMAGE_DESC_RECORD_TYPE)
  258. {
  259. err = gif_time_callback_osd();//第一次立刻画出一帧,免得出现绿色花屏,直到调用画第一帧图像接口
  260. //if(err == TERMINATE_RECORD_ERROR )
  261. //return 0;
  262. }
  263. // SYS_PRINTF("gif_period_time= %d \n", gif_period_time);
  264. if(gif_period_time==0)
  265. {
  266. gif_drow_one_frame_osd();
  267. // err = time_register(gif_drow_one_frame_osd, 4000, 1, ONCE_TIME, TIME_RUN_MODE_ISR, &GifData.time_id);
  268. }
  269. else
  270. {
  271. //err = time_register(gif_drow_one_frame_osd, gif_period_time*10, 1, ONCE_TIME, TIME_RUN_MODE_ISR, &GifData.time_id);
  272. }
  273. //逻辑上要保证 GifData.time_id 肯定大于0,要有先于GifData.time_id申请定时器
  274. //time_start(GifData.time_id);
  275. //SYS_PRINTF("GifData.time_id = %d \n", GifData.time_id);
  276. return 1;
  277. }
  278. GifFileType *GifFile;
  279. inline int com_gif_draw_osd(unsigned char* pGifData,int x0,int y0)
  280. {
  281. int i, j,err,Len;
  282. Window_Para_t window;
  283. //U16 time_id = 0;
  284. GifData.nTransColor=0;
  285. GifData.CurrentImage = 0;
  286. GifFile=GifData.GifFile = DGifOpenFileName(pGifData);
  287. if(GifFile == NULL)
  288. {
  289. SYS_PRINTF("不是GIF格式图片\n");
  290. return 0;
  291. }
  292. GifData.pGifData = DGifGetCurrentData(GifFile);
  293. // window.PositionX=x0;
  294. // window.PositionY=y0;
  295. ad_pic_osd_struct.XSize=GifFile->SWidth;
  296. ad_pic_osd_struct.YSize=GifFile->SHeight;
  297. GifFile->SWidth=(GifFile->SWidth % 2) ? (GifFile->SWidth - 1) : (GifFile->SWidth);
  298. // window.Width=GifFile->SWidth;
  299. // window.Height=GifFile->SHeight;
  300. if ( GifFile->SColorMap)
  301. {
  302. Len = 1 << GifFile->SBitsPerPixel;
  303. for (i = 0; i < Len; i++)
  304. {
  305. GifData.palette[i].Blue=GifFile->SColorMap[i].Blue;
  306. GifData.palette[i].Green=GifFile->SColorMap[i].Green;
  307. GifData.palette[i].Red=GifFile->SColorMap[i].Red;
  308. }
  309. }
  310. //5000 old
  311. err = gif_time_callback_osd();//第一次立刻画出一帧,免得出现绿色花屏
  312. //while(err != TERMINATE_RECORD_ERROR && err != IMAGE_DESC_RECORD_TYPE)
  313. while(err != IMAGE_DESC_RECORD_TYPE)
  314. {
  315. err = gif_time_callback_osd();//第一次立刻画出一帧,免得出现绿色花屏,直到调用画第一帧图像接口
  316. }
  317. // SYS_PRINTF("gif_period_time= %d \n", gif_period_time);
  318. //if(gif_period_time==0)
  319. //{
  320. // gif_drow_one_frame_osd();
  321. //err = time_register(gif_drow_one_frame_osd, 4000, 1, ONCE_TIME, TIME_RUN_MODE_ISR, &GifData.time_id);
  322. //}
  323. return 1;
  324. }

文章来源: blog.csdn.net,作者:悟空胆好小,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/xushx_bigbear/article/details/122730997

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。