硬汉嵌入式论坛

 找回密码
 立即注册
查看: 5760|回复: 7
收起左侧

[LibJPEG] 研究了下,发现emWin的JPEG解码是用libjpeg

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106959
QQ
发表于 2015-4-4 14:14:08 | 显示全部楼层 |阅读模式
找了一下uCGUI3.98的源码,看了一下JPEG相关的文件,的确使用的是libjpeg,而PNG的解码用的libpng。
===============================================================
uCGUI3.98里面的JPEG部分:
JPEG.zip (383 KB, 下载次数: 104)

1.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106959
QQ
 楼主| 发表于 2015-4-4 14:18:16 | 显示全部楼层
UCGUI和libjpeg的接口文件:


  1. /*
  2. *********************************************************************************************************
  3. *                                                uC/GUI
  4. *                        Universal graphic software for embedded applications
  5. *
  6. *                       (c) Copyright 2002, Micrium Inc., Weston, FL
  7. *                       (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
  8. *
  9. *              礐/GUI is protected by international copyright laws. Knowledge of the
  10. *              source code may not be used to write a similar product. This file may
  11. *              only be used in accordance with a license and should not be redistributed
  12. *              in any way. We appreciate your understanding and fairness.
  13. *
  14. ----------------------------------------------------------------------
  15. File        : GUI_JPEG.c
  16. Purpose     : Implementation of GUI_JPEG... functions
  17. ---------------------------END-OF-HEADER------------------------------
  18. */
  19. #include <stdlib.h>
  20. #include "GUI_Private.h"
  21. #include "jpeglib.h"
  22. #include "jerror.h"
  23. #include "jmemsys.h"
  24. /*********************************************************************
  25. *
  26. *       Local defines & data types
  27. *
  28. **********************************************************************
  29. */
  30. #define INPUT_BUF_SIZE  4096    /* choose an efficiently fread'able size */
  31. /* Expanded data source object for stdio input */
  32. typedef struct {
  33.   struct jpeg_source_mgr pub;    /* public fields */
  34.   const U8* pFileData;
  35.   I32   FileSize;
  36.   I32   Off;
  37.   boolean start_of_file;    /* have we gotten any data yet? */
  38. } SOURCE_MANAGER;
  39. static const U8 _abEnd[2] = {
  40.     0xFF, JPEG_EOI
  41. };
  42. /*********************************************************************
  43. *
  44. *       Static code
  45. *
  46. **********************************************************************
  47. */
  48. /*
  49. * Initialize source --- called by jpeg_read_header
  50. * before any data is actually read.
  51. */
  52. static void _InitSource (j_decompress_ptr cinfo) {
  53.   SOURCE_MANAGER* pSrc = (SOURCE_MANAGER*) cinfo->src;
  54.   /* We reset the empty-input-file flag for each image,
  55.    * but we don't clear the input buffer.
  56.    * This is correct behavior for reading a series of images from one source.
  57.    */
  58.   pSrc->start_of_file = TRUE;
  59. }
  60. /*
  61. * Fill the input buffer --- called whenever buffer is emptied.
  62. *
  63. * In typical applications, this should read fresh data into the buffer
  64. * (ignoring the current state of next_input_byte & bytes_in_buffer),
  65. * reset the pointer & count to the start of the buffer, and return TRUE
  66. * indicating that the buffer has been reloaded.  It is not necessary to
  67. * fill the buffer entirely, only to obtain at least one more byte.
  68. *
  69. * There is no such thing as an EOF return.  If the end of the file has been
  70. * reached, the routine has a choice of ERREXIT() or inserting fake data into
  71. * the buffer.  In most cases, generating a warning message and inserting a
  72. * fake EOI marker is the best course of action --- this will allow the
  73. * decompressor to output however much of the image is there.  However,
  74. * the resulting error message is misleading if the real problem is an empty
  75. * input file, so we handle that case specially.
  76. *
  77. * In applications that need to be able to suspend compression due to input
  78. * not being available yet, a FALSE return indicates that no more data can be
  79. * obtained right now, but more may be forthcoming later.  In this situation,
  80. * the decompressor will return to its caller (with an indication of the
  81. * number of scanlines it has read, if any).  The application should resume
  82. * decompression after it has loaded more data into the input buffer.  Note
  83. * that there are substantial restrictions on the use of suspension --- see
  84. * the documentation.
  85. *
  86. * When suspending, the decompressor will back up to a convenient restart point
  87. * (typically the start of the current MCU). next_input_byte & bytes_in_buffer
  88. * indicate where the restart point will be if the current call returns FALSE.
  89. * Data beyond this point must be rescanned after resumption, so move it to
  90. * the front of the buffer rather than discarding it.
  91. */
  92. static boolean _FillInputBuffer(j_decompress_ptr cinfo) {
  93.   SOURCE_MANAGER* pSrc = (SOURCE_MANAGER*) cinfo->src;
  94.   size_t nbytes;
  95.   int RemBytes = pSrc->FileSize - pSrc->Off;
  96.   if (RemBytes > 0) {
  97.     nbytes = (RemBytes > INPUT_BUF_SIZE) ? INPUT_BUF_SIZE : RemBytes;
  98.     pSrc->pub.next_input_byte = pSrc->pFileData + pSrc->Off;
  99.     pSrc->Off += nbytes;
  100.   } else {
  101.     if (pSrc->start_of_file)    /* Treat empty input file as fatal error */
  102.       ERREXIT(cinfo, JERR_INPUT_EMPTY);
  103.     WARNMS(cinfo, JWRN_JPEG_EOF);
  104.     /* Insert a fake EOI marker */
  105.     nbytes = 2;
  106.     pSrc->pub.next_input_byte = _abEnd;
  107.   }
  108.   pSrc->pub.bytes_in_buffer = nbytes;
  109.   pSrc->start_of_file = FALSE;
  110.   return TRUE;
  111. }
  112. /*
  113. * Skip data --- used to skip over a potentially large amount of
  114. * uninteresting data (such as an APPn marker).
  115. *
  116. * Writers of suspendable-input applications must note that skip_input_data
  117. * is not granted the right to give a suspension return.  If the skip extends
  118. * beyond the data currently in the buffer, the buffer can be marked empty so
  119. * that the next read will cause a fill_input_buffer call that can suspend.
  120. * Arranging for additional bytes to be discarded before reloading the input
  121. * buffer is the application writer's problem.
  122. */
  123. static void _SkipInputData (j_decompress_ptr cinfo, long num_bytes) {
  124.   SOURCE_MANAGER* pSrc = (SOURCE_MANAGER*) cinfo->src;
  125.   /* Just a dumb implementation for now.  Could use fseek() except
  126.    * it doesn't work on pipes.  Not clear that being smart is worth
  127.    * any trouble anyway --- large skips are infrequent.
  128.    */
  129.   if (num_bytes > 0) {
  130.     while (num_bytes > (long) pSrc->pub.bytes_in_buffer) {
  131.       num_bytes -= (long) pSrc->pub.bytes_in_buffer;
  132.       (void) _FillInputBuffer(cinfo);
  133.       /* note we assume that fill_input_buffer will never return FALSE,
  134.        * so suspension need not be handled.
  135.        */
  136.     }
  137.     pSrc->pub.next_input_byte += (size_t) num_bytes;
  138.     pSrc->pub.bytes_in_buffer -= (size_t) num_bytes;
  139.   }
  140. }
  141. /*
  142. * An additional method that can be provided by data source modules is the
  143. * resync_to_restart method for error recovery in the presence of RST markers.
  144. * For the moment, this source module just uses the default resync method
  145. * provided by the JPEG library.  That method assumes that no backtracking
  146. * is possible.
  147. */
  148. /*
  149. * Terminate source --- called by jpeg_finish_decompress
  150. * after all data has been read.  Often a no-op.
  151. *
  152. * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
  153. * application must deal with any cleanup that should happen even
  154. * for error exit.
  155. */
  156. static void _TermSource(j_decompress_ptr cinfo) {
  157.   /* no work necessary here */
  158.   GUI_USE_PARA(cinfo);
  159. }
  160. static void _InitSrc(j_decompress_ptr cinfo, const U8* pFileData, I32 FileSize) {
  161.   SOURCE_MANAGER* pSrc;
  162.   /* The source object and input buffer are made permanent so that a series
  163.    * of JPEG images can be read from the same file by calling jpeg_stdio_src
  164.    * only before the first one.  (If we discarded the buffer at the end of
  165.    * one image, we'd likely lose the start of the next one.)
  166.    * This makes it unsafe to use this manager and a different source
  167.    * manager serially with the same JPEG object.  Caveat programmer.
  168.    */
  169.   if (cinfo->src == NULL) {    /* first time for this JPEG object? */
  170.     cinfo->src = (jpeg_source_mgr *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(SOURCE_MANAGER));
  171.   }
  172.   pSrc = (SOURCE_MANAGER*) cinfo->src;
  173.   pSrc->pub.init_source       = _InitSource;
  174.   pSrc->pub.fill_input_buffer = _FillInputBuffer;
  175.   pSrc->pub.skip_input_data   = _SkipInputData;
  176.   pSrc->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
  177.   pSrc->pub.term_source       = _TermSource;
  178.   pSrc->pub.bytes_in_buffer   = 0;    /* forces fill_input_buffer on first read */
  179.   pSrc->pub.next_input_byte   = NULL; /* until buffer loaded */
  180.   /*
  181.    *  Init private part of Source manager
  182.    */
  183.   pSrc->FileSize  = FileSize;
  184.   pSrc->pFileData = pFileData;
  185.   pSrc->Off       = 0;
  186. }
  187. /*********************************************************************
  188. *
  189. *       Memory allocation
  190. *
  191. **********************************************************************
  192. */
  193. int AllocCnt;   /* for debugging only */
  194. int TotalSize;
  195. /*
  196. * Memory allocation and freeing are controlled by the regular library
  197. * routines malloc() and free().
  198. */
  199. GLOBAL(void *) jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) {
  200.   GUI_USE_PARA(cinfo);
  201.   AllocCnt++;
  202.   TotalSize += sizeofobject;
  203.   return (void *) malloc(sizeofobject);
  204. }
  205. GLOBAL(void) jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) {
  206.   GUI_USE_PARA(cinfo);
  207.   GUI_USE_PARA(sizeofobject);
  208.   if (--AllocCnt) {
  209.     TotalSize = 0;
  210.   }
  211.   free(object);
  212. }
  213. /*
  214. * This routine computes the total memory space available for allocation.
  215. * Here we always say, "we got all you want bud!"
  216. */
  217. GLOBAL(long) jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, long max_bytes_needed, long already_allocated) {
  218.   GUI_USE_PARA(cinfo);
  219.   GUI_USE_PARA(min_bytes_needed);
  220.   GUI_USE_PARA(already_allocated);
  221.   return max_bytes_needed;
  222. }
  223. /*
  224. * These routines take care of any system-dependent initialization and
  225. * cleanup required.  Here, there isn't any.
  226. * just set max_memory_to_use to 0
  227. */
  228. GLOBAL(long) jpeg_mem_init (j_common_ptr cinfo) {
  229.   GUI_USE_PARA(cinfo);
  230.   return 0;
  231. }
  232. GLOBAL(void) jpeg_mem_term (j_common_ptr cinfo) {
  233.   GUI_USE_PARA(cinfo);
  234. }
  235. /*********************************************************************
  236. *
  237. *       _Init
  238. */
  239. static void _Init(struct jpeg_error_mgr* pjerr, struct jpeg_decompress_struct *pcinfo, const void * pFileData, int DataSize) {
  240.   /* 1. Allocate and initialize a JPEG decompression object. */
  241.   pcinfo->err = jpeg_std_error(pjerr);
  242.     jpeg_create_decompress(pcinfo);
  243.   /* 2. Init the source manager so the library can retrieve data via methods */
  244.   _InitSrc(pcinfo, (const U8*)pFileData, DataSize);
  245.   /* 3. Call jpeg_read_header() to obtain image info. */
  246.     jpeg_read_header(pcinfo, TRUE);
  247. }
  248. /*********************************************************************
  249. *
  250. *       _WritePixelsRGB
  251. */
  252. static void _WritePixelsRGB(const U8*p, int x0, int y0, int xSize) {
  253.   U8 r,g,b;
  254.   while (xSize) {
  255.     r = *p++;
  256.     g = *p++;
  257.     b = *p++;
  258.     LCD_SetColor(r | (g << 8) | (U32)((U32)b << 16));
  259.     LCD_DrawPixel(x0++, y0);
  260.     xSize--;
  261.   }
  262. }
  263. /*********************************************************************
  264. *
  265. *       _WritePixelsGray
  266. */
  267. static void _WritePixelsGray(const U8*p, int x0, int y0, int xSize) {
  268.   U8 u;
  269.   while (xSize) {
  270.     u = *p++;
  271.     LCD_SetColor(u * (U32)0x10101);
  272.     LCD_DrawPixel(x0++, y0);
  273.     xSize--;
  274.   }
  275. }
  276. /*********************************************************************
  277. *
  278. *       Public code
  279. *
  280. **********************************************************************
  281. */
  282. /*********************************************************************
  283. *
  284. *       GUI_JPEG_GetInfo
  285. */
  286. int GUI_JPEG_GetInfo(const void * pFileData, int DataSize, GUI_JPEG_INFO* pInfo) {
  287.     struct jpeg_decompress_struct cinfo;
  288.     struct jpeg_error_mgr jerr;
  289.   _Init(&jerr, &cinfo, pFileData, DataSize);
  290.   /*
  291.    * Release the JPEG decompression object.
  292.    */
  293.   jpeg_destroy_decompress(&cinfo);
  294.   if (pInfo) {
  295.     pInfo->XSize = cinfo.image_width;
  296.     pInfo->YSize = cinfo.image_height;
  297.   }
  298.   return 0;
  299. }
  300. /*********************************************************************
  301. *
  302. *       GUI_JPEG_Draw
  303. */
  304. int GUI_JPEG_Draw(const void * pFileData, int DataSize, int x0, int y0) {
  305.   #if (GUI_WINSUPPORT)
  306.     GUI_RECT r;
  307.   #endif
  308.   int Ret = 0;
  309.   GUI_HMEM hBuffer = 0;
  310.     struct jpeg_decompress_struct cinfo;
  311.     struct jpeg_error_mgr jerr;
  312.   GUI_LOCK();
  313.   _Init(&jerr, &cinfo, pFileData, DataSize);
  314.   #if (GUI_WINSUPPORT)
  315.     WM_ADDORG(x0,y0);
  316.     r.x1 = (r.x0 = x0) + cinfo.image_width - 1;
  317.     r.y1 = (r.y0 = y0) + cinfo.image_height - 1;
  318.     WM_ITERATE_START(&r) {
  319.   #endif
  320.     if (hBuffer) {
  321.       _Init(&jerr, &cinfo, pFileData, DataSize);
  322.     }
  323.     /* 4. Set up parameters for decompression (optional ...) */
  324.     /* 5. jpeg_start_decompress(...); Should normally return quickly */
  325.       jpeg_start_decompress(&cinfo);
  326.     /* 6. while (scan lines remain to be read) */
  327.       /*     jpeg_read_scanlines(...); */
  328.     if (!hBuffer) {
  329.       hBuffer = GUI_ALLOC_AllocNoInit(cinfo.image_width * 3);
  330.     }
  331.     while (cinfo.output_scanline < cinfo.output_height) {
  332.       U8* p;
  333.       p = (U8*)GUI_ALLOC_h2p(hBuffer);
  334.       jpeg_read_scanlines(&cinfo, &p, 1);
  335.       if (cinfo.jpeg_color_space == JCS_GRAYSCALE) {
  336.         _WritePixelsGray(p, x0, y0 + cinfo.output_scanline, cinfo.image_width);
  337.       } else {
  338.         _WritePixelsRGB(p, x0, y0 + cinfo.output_scanline, cinfo.image_width);
  339.       }
  340.     }
  341.     /* 7. jpeg_finish_decompress(...); */
  342.     /*    Complete the decompression cycle.  This causes working memory associated */
  343.     /*    with the JPEG object to be released. */
  344.       jpeg_finish_decompress(&cinfo);
  345.     /* 8. Release the JPEG decompression object. */
  346.     jpeg_destroy_decompress(&cinfo);
  347.   #if (GUI_WINSUPPORT)
  348.     } WM_ITERATE_END();
  349.   #endif
  350.   GUI_ALLOC_Free(hBuffer);
  351.   GUI_UNLOCK();
  352.   return Ret;
  353. }
  354. /*************************** End of file ****************************/
复制代码
回复

使用道具 举报

4

主题

531

回帖

543

积分

金牌会员

积分
543
发表于 2018-1-21 10:18:13 | 显示全部楼层
硬汉  问下怎么覆盖 emwin的GUI_JPEG_Draw,我新建一个会报错.  Symbol GUI_JPEG_Draw multiply defined (by gui_jpeg.o and gui_jpeg.o).
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106959
QQ
 楼主| 发表于 2018-1-21 11:52:19 | 显示全部楼层
qiousanxi 发表于 2018-1-21 10:18
硬汉  问下怎么覆盖 emwin的GUI_JPEG_Draw,我新建一个会报错.  Symbol GUI_JPEG_Draw multiply defined ( ...

下载我们的这个V6综合Demo,里面有覆盖:
http://www.armbbs.cn/forum.php?m ... &extra=page%3D1
回复

使用道具 举报

4

主题

531

回帖

543

积分

金牌会员

积分
543
发表于 2018-1-21 12:14:34 | 显示全部楼层
我看了,用的是外部的lib我想问问,怎么覆盖的emwin的函数
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106959
QQ
 楼主| 发表于 2018-1-21 12:19:28 | 显示全部楼层
qiousanxi 发表于 2018-1-21 12:14
我看了,用的是外部的lib我想问问,怎么覆盖的emwin的函数

直接添加新文件就好了,注意你的程序里面不要调用GUI_JPEG_DrawEx之类的其它函数,别的没有要注意的了。
回复

使用道具 举报

4

主题

531

回帖

543

积分

金牌会员

积分
543
发表于 2018-1-21 12:24:07 | 显示全部楼层
就是,我模仿你创建了个函数GUI_JPEG_Draw一直报错
回复

使用道具 举报

4

主题

531

回帖

543

积分

金牌会员

积分
543
发表于 2018-1-21 12:25:38 | 显示全部楼层
哦哦,如果需要用,也要去重新实现其他的jpeg函数对吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-11 19:28 , Processed in 0.210421 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表