KJpegLib.c
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:8k
源码类别:

模拟服务器

开发平台:

C/C++

  1. //---------------------------------------------------------------------------
  2. // Sword3 Engine (c) 1999-2000 by Kingsoft
  3. //
  4. // File: KJpegLib.cpp
  5. // Date: 2000.08.08
  6. // Code: Daniel Wang
  7. // Desc: Jpeg Decode Library
  8. // From: Cloud Wu's JPEG Decoder
  9. //---------------------------------------------------------------------------
  10. #include <windows.h>
  11. #include "KJpegLib.h"
  12. /****************************************************************************
  13. 附:JPEG 文件格式
  14. ~~~~~~~~~~~~~~~~
  15.   - 文件头 (2 bytes):  $ff, $d8 (SOI) (Start Of Image)
  16.   - 任意数量的段 , 见后面
  17.   - 文件结束 (2 bytes): $ff, $d9 (EOI) (End Of Image)
  18.   
  19. 段的格式:
  20. ~~~~~~~~~
  21.   - header (4 bytes):
  22.   $ff     段标识
  23.   n       段的类型 (1 byte)
  24.   sh, sl  该段长度, 包括这两个字节, 但是不包括前面的 $ff 和 n.
  25.   注意: 长度不是 intel 次序, 而是 Motorola 的, 高字节在前,
  26.   低字节在后!
  27.   - 该段的内容, 最多 65533 字节
  28. ****************************************************************************/
  29. PBYTE jpeg_stream = NULL;
  30. short jpeg_ybuf[256];
  31. short jpeg_cbbuf[64];
  32. short jpeg_crbuf[64];
  33. short jpeg_DC[3];
  34. short* jpeg_qtable[4];
  35. JPEG_HTABLE jpeg_htable[8];
  36. BYTE jpeg_bit;
  37. JPEG_SOF0 jpeg_head;
  38. void (*jpeg_IDCT)(short* buf) = NULL;
  39. void (*jpeg_Y2RGB)(WORD *bmppixel, int pitch) = NULL;
  40. void (*jpeg_YCbCr411)(WORD *bmppixel, int pitch) = NULL;
  41. void (*jpeg_YCbCr111)(WORD *bmppixel, int pitch) = NULL;
  42. //---------------------------------------------------------------------------
  43. // 函数: jpeg_decode_info
  44. // 功能:
  45. // 参数: pJpgBuf 输入指针
  46. // pInfo 格式信息
  47. // 返回: TRUE 成功
  48. // FALSE 失败
  49. //---------------------------------------------------------------------------
  50. BOOL jpeg_decode_info(PBYTE pJpgBuf, JPEG_INFO* pInfo)
  51. {
  52. WORD head;
  53. BYTE sign;
  54. int  HY, VY;
  55. int  HCb, VCb, HCr, VCr;
  56. jpeg_stream = (PBYTE)pJpgBuf;
  57. // is it a JPEG file ?
  58. READ_WORD(head, jpeg_stream);
  59. // SOI = start of image
  60. if (head != 0xffd8)
  61. return FALSE;
  62. // init huffman table
  63. jpeg_init_table();
  64. // read jpeg header data
  65. do
  66. {
  67. // find first 0xff
  68. while ((sign = READ_BYTE(jpeg_stream)) != 0xff);
  69. // skip other 0xff
  70. while ((sign = READ_BYTE(jpeg_stream)) == 0xff);
  71. switch (sign)
  72. {
  73. case 0x01: // TEM = 可以忽略
  74. break;
  75. case 0xc0: // SOF0 = Start Of Frame 0
  76. jpeg_stream = jpeg_read_SOF(jpeg_stream);
  77. if (jpeg_stream == NULL)
  78. return FALSE;
  79. break;
  80. case 0xc4: // DHT = Define Huffman Table
  81. jpeg_stream = jpeg_read_DHT(jpeg_stream);
  82. if (jpeg_stream == NULL)
  83. return FALSE;
  84. break;
  85. case 0xda: // SOS = Start Of Scan
  86. jpeg_stream = jpeg_read_SOS(jpeg_stream);
  87. if (jpeg_stream == NULL)
  88. return FALSE;
  89. break;
  90. case 0xdb: // DQT = Define Quantization Table
  91. jpeg_stream = jpeg_read_DQT(jpeg_stream);
  92. if (jpeg_stream == NULL)
  93. return FALSE;
  94. break;
  95. case 0xd9: // EOI = End of Image
  96. return FALSE;
  97. case 0xdd: // DRI = Define Reset interval
  98. // Not supported
  99. return FALSE;
  100. default: // 忽略其他的 Segment
  101. jpeg_stream = jpeg_skip_SEG(jpeg_stream);
  102. break;
  103. }
  104. } while (sign != 0xda); // SOS 扫描行开始
  105. // 初始化
  106. HY = jpeg_head.component[0].h;
  107. VY = jpeg_head.component[0].v;
  108. if (HY != VY || HY > 2)
  109. {
  110. // 不支持的 MCU (只支持 YDU, YDU*4 CbDU CrDU, YDU CbDU CrDU 三种模式)
  111. return FALSE;
  112. }
  113. // 确定JPEG文件的色彩模式
  114. if (jpeg_head.components == 1)
  115. {
  116. pInfo->mode = 0;
  117. }
  118. else
  119. {
  120. HCb = jpeg_head.component[1].h;
  121. VCb = jpeg_head.component[1].v;
  122. HCr = jpeg_head.component[2].h;
  123. VCr = jpeg_head.component[2].v;
  124. if ((HCb | VCb | HCr | VCr) != 1)
  125. {
  126. // 不支持的 MCU (只支持 YDU, YDU*4 CbDU CrDU, YDU CbDU CrDU 三种模式)
  127. return FALSE;
  128. }
  129. if (HY == 2)
  130. {
  131. pInfo->mode = 1;
  132. }
  133. else
  134. {
  135. pInfo->mode = 2;
  136. }
  137. }
  138. // HDU = horizion data unit (width)
  139. pInfo->width = (jpeg_head.width + HY * 8 - 1) & (-1 << (HY + 2));
  140. // VDU = vertical data unit (height)
  141. pInfo->height = (jpeg_head.height + VY * 8 - 1) & (-1 << (VY + 2));
  142. return TRUE;
  143. }
  144. //---------------------------------------------------------------------------
  145. // 函数: jpeg_decode_data
  146. // 功能:
  147. // 参数: pBitmap 输出指针
  148. // pInfo 格式信息
  149. // 返回: TRUE 成功
  150. // FALSE 失败
  151. //---------------------------------------------------------------------------
  152. BOOL jpeg_decode_data(PWORD pBitmap, JPEG_INFO* pInfo)
  153. {
  154. int   x, y;
  155. int   width = pInfo->width;
  156. int   height = pInfo->height;
  157. int   pitch = pInfo->width * 2;
  158. PWORD bitmap = pBitmap;
  159. if (jpeg_stream == NULL)
  160. return FALSE;
  161. jpeg_DC[0] = 0;
  162. jpeg_DC[1] = 0;
  163. jpeg_DC[2] = 0;
  164. jpeg_preprocess(jpeg_stream);
  165. jpeg_bit = 0;
  166. switch (pInfo->mode)
  167. {
  168. case 0: // Gray Jpeg
  169. for (y = 0; y < height; y += 8)
  170. {
  171. for (x = 0; x < width; x += 8)
  172. {
  173. jpeg_decode_DU(jpeg_ybuf, 0);
  174. jpeg_Y2RGB(bitmap + width * y + x, pitch);
  175. }
  176. }
  177. break;
  178. case 1: // Y4CbCr Jpeg
  179. for (y = 0; y < height; y += 16)
  180. {
  181. for (x = 0; x < width; x += 16)
  182. {
  183. jpeg_decode_DU(jpeg_ybuf, 0);
  184. jpeg_decode_DU(jpeg_ybuf + 64, 0);
  185. jpeg_decode_DU(jpeg_ybuf + 128, 0);
  186. jpeg_decode_DU(jpeg_ybuf + 192, 0);
  187. jpeg_decode_DU(jpeg_cbbuf, 1);
  188. jpeg_decode_DU(jpeg_crbuf, 2);
  189. jpeg_YCbCr411(bitmap + width * y + x, pitch);
  190. }
  191. }
  192. break;
  193. case 2: // YCbCr Jpeg
  194. for (y = 0; y < height; y += 8)
  195. {
  196. for (x = 0; x < width; x += 8)
  197. {
  198. jpeg_decode_DU(jpeg_ybuf, 0);
  199. jpeg_decode_DU(jpeg_cbbuf, 1);
  200. jpeg_decode_DU(jpeg_crbuf, 2);
  201. jpeg_YCbCr111(bitmap + width * y + x, pitch);
  202. }
  203. }
  204. break;
  205. }
  206. jpeg_free_table();
  207. jpeg_stream = NULL;
  208. return TRUE;
  209. }
  210. //---------------------------------------------------------------------------
  211. // 函数: jpeg_decode_data
  212. // 功能:
  213. // 参数: pBitmap 输出指针
  214. // pitch 数据行跨度
  215. // pInfo 格式信息
  216. // 返回: TRUE 成功
  217. // FALSE 失败
  218. //---------------------------------------------------------------------------
  219. BOOL jpeg_decode_dataEx(PWORD pBitmap, int nPitch, JPEG_INFO* pInfo)
  220. {
  221. int   x, y;
  222. int   width = pInfo->width;
  223. int   height = pInfo->height;
  224. int   pitch = nPitch;
  225. PWORD bitmap = pBitmap;
  226. if (jpeg_stream == NULL)
  227. return FALSE;
  228. jpeg_DC[0] = 0;
  229. jpeg_DC[1] = 0;
  230. jpeg_DC[2] = 0;
  231. jpeg_preprocess(jpeg_stream);
  232. jpeg_bit = 0;
  233. switch (pInfo->mode)
  234. {
  235. case 0: // Gray Jpeg
  236. for (y = 0; y < height; y += 8)
  237. {
  238. for (x = 0; x < width; x += 8)
  239. {
  240. jpeg_decode_DU(jpeg_ybuf, 0);
  241. jpeg_Y2RGB(bitmap + pitch * y / 2 + x, pitch);
  242. }
  243. }
  244. break;
  245. case 1: // Y4CbCr Jpeg
  246. for (y = 0; y < height; y += 16)
  247. {
  248. for (x = 0; x < width; x += 16)
  249. {
  250. jpeg_decode_DU(jpeg_ybuf, 0);
  251. jpeg_decode_DU(jpeg_ybuf + 64, 0);
  252. jpeg_decode_DU(jpeg_ybuf + 128, 0);
  253. jpeg_decode_DU(jpeg_ybuf + 192, 0);
  254. jpeg_decode_DU(jpeg_cbbuf, 1);
  255. jpeg_decode_DU(jpeg_crbuf, 2);
  256. jpeg_YCbCr411(bitmap + pitch * y / 2 + x, pitch);
  257. }
  258. }
  259. break;
  260. case 2: // YCbCr Jpeg
  261. for (y = 0; y < height; y += 8)
  262. {
  263. for (x = 0; x < width; x += 8)
  264. {
  265. jpeg_decode_DU(jpeg_ybuf, 0);
  266. jpeg_decode_DU(jpeg_cbbuf, 1);
  267. jpeg_decode_DU(jpeg_crbuf, 2);
  268. jpeg_YCbCr111(bitmap + pitch * y / 2 + x, pitch);
  269. }
  270. }
  271. break;
  272. }
  273. jpeg_free_table();
  274. jpeg_stream = NULL;
  275. return TRUE;
  276. }
  277. //---------------------------------------------------------------------------
  278. // 函数: jpeg_init_table
  279. // 功能: 初始化表格
  280. // 参数: void
  281. // 返回: void
  282. //---------------------------------------------------------------------------
  283. void jpeg_init_table()
  284. {
  285. memset(jpeg_htable, 0, 8 * sizeof(JPEG_HTABLE));
  286. memset(jpeg_qtable, 0, 4 * sizeof(short *));
  287. }
  288. //---------------------------------------------------------------------------
  289. // 函数: jpeg_free_table
  290. // 功能: 释放表格
  291. // 参数: void
  292. // 返回: void
  293. //---------------------------------------------------------------------------
  294. void jpeg_free_table()
  295. {
  296. int  i;
  297. for (i = 0; i < 8; i++)
  298. {
  299. if (jpeg_htable[i].htb)
  300. {
  301. free(jpeg_htable[i].htb);
  302. jpeg_htable[i].htb = NULL;
  303. }
  304. }
  305. for (i = 0 ; i < 4; i++)
  306. {
  307. if (jpeg_qtable[i])
  308. {
  309. free(jpeg_qtable[i]);
  310. jpeg_qtable[i] = NULL;
  311. }
  312. }
  313. }
  314. //---------------------------------------------------------------------------