Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

560 lines
12 KiB

  1. /***********************************************************************
  2. *
  3. * JPEG decompression utility functions
  4. *
  5. * Implement (1) JPEG memory data source
  6. * (2) JPEG error manager using setjmp/longjmp
  7. *
  8. * Author : Indy Zhu [indyz]
  9. * Date : 5/20/98
  10. *
  11. ***********************************************************************/
  12. #include "pch.h"
  13. #include <setjmp.h>
  14. //
  15. // Workaround for redefinition of INT32
  16. //
  17. #define XMD_H 1
  18. //
  19. // Header file for JPEG library
  20. //
  21. extern "C"
  22. {
  23. #include "jpeglib.h"
  24. }
  25. #include "utils.h"
  26. //
  27. // Buf source manager definition
  28. //
  29. typedef struct _buf_source_mgr
  30. {
  31. struct jpeg_source_mgr pub;
  32. //
  33. // Fields specific to buf_source_mgr
  34. //
  35. LPBYTE pJPEGBlob;
  36. DWORD dwSize;
  37. } buf_source_mgr;
  38. //
  39. // Jump error manager definition
  40. //
  41. typedef struct _jmp_error_mgr
  42. {
  43. struct jpeg_error_mgr pub;
  44. //
  45. // Private fields for jump error manager
  46. //
  47. jmp_buf stackContext;
  48. } jmp_error_mgr;
  49. /******************************************************************************\
  50. *
  51. * init_source()
  52. *
  53. * Arguments:
  54. *
  55. * Return Value:
  56. *
  57. * Status
  58. *
  59. * History:
  60. *
  61. * 11/4/1998 Original Version
  62. *
  63. \******************************************************************************/
  64. static void __cdecl
  65. init_source(
  66. j_decompress_ptr pDecompInfo)
  67. {
  68. //
  69. // No working necessary here
  70. //
  71. }
  72. /******************************************************************************\
  73. *
  74. * fill_input_buffer()
  75. *
  76. * Arguments:
  77. *
  78. * Return Value:
  79. *
  80. * Status
  81. *
  82. * History:
  83. *
  84. * 11/4/1998 Original Version
  85. *
  86. \******************************************************************************/
  87. static boolean __cdecl
  88. fill_input_buffer(
  89. j_decompress_ptr pDecompInfo)
  90. {
  91. buf_source_mgr *pBufSrcMgr;
  92. //
  93. // Recover buf source manager itself
  94. //
  95. pBufSrcMgr = (buf_source_mgr *)pDecompInfo->src;
  96. //
  97. // buf_source_mgr can only fire one shot
  98. //
  99. pBufSrcMgr->pub.next_input_byte = pBufSrcMgr->pJPEGBlob;
  100. pBufSrcMgr->pub.bytes_in_buffer = pBufSrcMgr->dwSize;
  101. return(TRUE);
  102. }
  103. /******************************************************************************\
  104. *
  105. * skip_input_data()
  106. *
  107. * Arguments:
  108. *
  109. * Return Value:
  110. *
  111. * Status
  112. *
  113. * History:
  114. *
  115. * 11/4/1998 Original Version
  116. *
  117. \******************************************************************************/
  118. static void __cdecl
  119. skip_input_data(
  120. j_decompress_ptr pDecompInfo,
  121. long lBytes)
  122. {
  123. buf_source_mgr *pBufSrcMgr;
  124. //
  125. // For buf source manager, it is very easy to implement
  126. //
  127. if (lBytes > 0)
  128. {
  129. pBufSrcMgr = (buf_source_mgr *)pDecompInfo->src;
  130. pBufSrcMgr->pub.next_input_byte += lBytes;
  131. pBufSrcMgr->pub.bytes_in_buffer -= lBytes;
  132. }
  133. }
  134. /******************************************************************************\
  135. *
  136. * term_source()
  137. *
  138. * Arguments:
  139. *
  140. * Return Value:
  141. *
  142. * Status
  143. *
  144. * History:
  145. *
  146. * 11/4/1998 Original Version
  147. *
  148. \******************************************************************************/
  149. static void __cdecl
  150. term_source(
  151. j_decompress_ptr pDecompInfo)
  152. {
  153. }
  154. /******************************************************************************\
  155. *
  156. * jpeg_buf_src()
  157. *
  158. * Arguments:
  159. *
  160. * Return Value:
  161. *
  162. * Status
  163. *
  164. * History:
  165. *
  166. * 11/4/1998 Original Version
  167. *
  168. \******************************************************************************/
  169. static void __cdecl
  170. jpeg_buf_src(
  171. j_decompress_ptr pDecompInfo,
  172. LPBYTE pJPEGBlob,
  173. DWORD dwSize)
  174. {
  175. buf_source_mgr *pBufSrcMgr;
  176. //
  177. // Allocate memory for the buf source manager
  178. //
  179. pBufSrcMgr = (buf_source_mgr *)
  180. (pDecompInfo->mem->alloc_small)((j_common_ptr)pDecompInfo,
  181. JPOOL_PERMANENT,
  182. sizeof(buf_source_mgr));
  183. //
  184. // Record the pJPEGBlob
  185. //
  186. pBufSrcMgr->pJPEGBlob = pJPEGBlob;
  187. pBufSrcMgr->dwSize = dwSize;
  188. //
  189. // Fill in the function pointers
  190. //
  191. pBufSrcMgr->pub.init_source = init_source;
  192. pBufSrcMgr->pub.fill_input_buffer = fill_input_buffer;
  193. pBufSrcMgr->pub.skip_input_data = skip_input_data;
  194. pBufSrcMgr->pub.resync_to_restart = jpeg_resync_to_restart;
  195. pBufSrcMgr->pub.term_source = term_source;
  196. //
  197. // Initialize the pointer into the buffer
  198. //
  199. pBufSrcMgr->pub.bytes_in_buffer = 0;
  200. pBufSrcMgr->pub.next_input_byte = NULL;
  201. //
  202. // Ask the decompression context to remember it
  203. //
  204. pDecompInfo->src = (struct jpeg_source_mgr *)pBufSrcMgr;
  205. }
  206. /******************************************************************************\
  207. *
  208. * jmp_error_exit()
  209. *
  210. * Arguments:
  211. *
  212. * Return Value:
  213. *
  214. * Status
  215. *
  216. * History:
  217. *
  218. * 11/4/1998 Original Version
  219. *
  220. \******************************************************************************/
  221. static void __cdecl
  222. jmp_error_exit(
  223. j_common_ptr pDecompInfo)
  224. {
  225. jmp_error_mgr *pJmpErrorMgr;
  226. //
  227. // Get the jump error manager back
  228. //
  229. pJmpErrorMgr = (jmp_error_mgr *)pDecompInfo->err;
  230. //
  231. // Display the error message
  232. //
  233. #ifdef _DEBUG
  234. (pDecompInfo->err->output_message)(pDecompInfo);
  235. #endif
  236. //
  237. // Recover the original stack
  238. //
  239. longjmp(pJmpErrorMgr->stackContext, 1);
  240. }
  241. /******************************************************************************\
  242. *
  243. * jpeg_jmp_error()
  244. *
  245. * Arguments:
  246. *
  247. * Return Value:
  248. *
  249. * Status
  250. *
  251. * History:
  252. *
  253. * 11/4/1998 Original Version
  254. *
  255. \******************************************************************************/
  256. struct jpeg_error_mgr *
  257. jpeg_jmp_error(
  258. jmp_error_mgr *pJmpErrorMgr)
  259. {
  260. //
  261. // Initialize the public part
  262. //
  263. jpeg_std_error(&pJmpErrorMgr->pub);
  264. //
  265. // Set up jump error manager exit method
  266. //
  267. pJmpErrorMgr->pub.error_exit = jmp_error_exit;
  268. return((jpeg_error_mgr *)pJmpErrorMgr);
  269. }
  270. /******************************************************************************\
  271. *
  272. * GetJpegDimensions
  273. *
  274. * Arguments:
  275. * pJpeg -- jpeg file in memory. It could be in JFIF and EXIF
  276. * format
  277. * JpegSize -- the jpeg file size
  278. * pWidth -- to return the image width in pixels
  279. * pHeight -- to return the image height in pixels
  280. * pBitDepth -- to return the image bit depth.
  281. *
  282. * Return Value:
  283. *
  284. * HRESULT
  285. *
  286. * History:
  287. *
  288. * 11/4/1998 Original Version
  289. *
  290. \******************************************************************************/
  291. HRESULT
  292. WINAPI
  293. GetJpegDimensions(
  294. BYTE *pJpeg,
  295. UINT JpegSize,
  296. UINT *pWidth,
  297. UINT *pHeight,
  298. UINT *pBitDepth
  299. )
  300. {
  301. struct jpeg_decompress_struct decompInfo;
  302. jmp_error_mgr jpegErrMgr;
  303. int ret;
  304. //
  305. // Step 1 : Initialize JPEG session data-structure
  306. //
  307. decompInfo.err = jpeg_jmp_error(&jpegErrMgr);
  308. jpeg_create_decompress(&decompInfo);
  309. //
  310. // Reserve the state of the current stack
  311. //
  312. if (setjmp(jpegErrMgr.stackContext))
  313. {
  314. //
  315. // JPEG lib will longjump here when there is an error
  316. //
  317. jpeg_destroy_decompress(&decompInfo);
  318. return(E_FAIL);
  319. }
  320. //
  321. // Step 2 : Specify the source of the compressed data
  322. //
  323. jpeg_buf_src(&decompInfo, pJpeg, JpegSize);
  324. //
  325. // Step 3 : Read JPEG file header information
  326. //
  327. ret = jpeg_read_header(&decompInfo, TRUE);
  328. //
  329. // Release the decompression context
  330. //
  331. jpeg_destroy_decompress(&decompInfo);
  332. //
  333. // Fill in the dimension info for the caller
  334. //
  335. *pWidth = decompInfo.image_width;
  336. *pHeight = decompInfo.image_height;
  337. *pBitDepth = 24;
  338. if (ret != JPEG_HEADER_OK)
  339. {
  340. return(E_FAIL);
  341. }
  342. return S_OK;
  343. }
  344. //
  345. // This function converts a jpeg file in memory to DIB bitmap
  346. //
  347. // Input:
  348. // pJpeg -- jpeg file in memory. JFIF or EXIF are supported
  349. // JpegSize -- the jpeg file size
  350. // DIBBmpSize -- DIB bitmap buffer size
  351. // pDIBBmp -- DIB bitmap buffer
  352. // LineSize -- desitnation scanline size in bytes
  353. // MaxLines -- maximum scanlines per transfer
  354. //
  355. HRESULT
  356. WINAPI
  357. Jpeg2DIBBitmap(
  358. BYTE *pJpeg,
  359. UINT JpegSize,
  360. BYTE *pDIBBmp,
  361. UINT DIBBmpSize,
  362. UINT LineSize,
  363. UINT MaxLines
  364. )
  365. {
  366. struct jpeg_decompress_struct decompInfo;
  367. jmp_error_mgr jpegErrMgr;
  368. //
  369. // Parameter checking
  370. //
  371. if (!pJpeg || !JpegSize || !DIBBmpSize || !pDIBBmp || !LineSize)
  372. return E_INVALIDARG;
  373. //
  374. // Step 1 : Initialize JPEG session data-structure
  375. //
  376. decompInfo.err = jpeg_jmp_error(&jpegErrMgr);
  377. jpeg_create_decompress(&decompInfo);
  378. //
  379. // Reserve the state of the current stack
  380. //
  381. if (setjmp(jpegErrMgr.stackContext))
  382. {
  383. //
  384. // JPEG lib will longjump here when there is an error
  385. //
  386. jpeg_destroy_decompress(&decompInfo);
  387. return(E_FAIL);
  388. }
  389. //
  390. // Step 2 : Specify the source of the compressed data
  391. //
  392. jpeg_buf_src(&decompInfo, pJpeg, JpegSize);
  393. //
  394. // Step 3 : Read JPEG file header information
  395. //
  396. if (jpeg_read_header(&decompInfo, TRUE) != JPEG_HEADER_OK)
  397. {
  398. jpeg_destroy_decompress(&decompInfo);
  399. return(E_FAIL);
  400. }
  401. //
  402. // Step 4 : Set parameter for decompression
  403. // Defaults are OK for this occasssion
  404. // Specify the JCS_BGR output colorspace so that the returned
  405. // decompressed image has the same format as DIB. Also, it forces
  406. // the decompressor to return a 24-bits RGB colors image
  407. //
  408. decompInfo.out_color_space = JCS_BGR;
  409. //
  410. // Calculate DIB scan line size, assuming 24bits color.
  411. //
  412. HRESULT hr;
  413. hr = S_OK;
  414. //
  415. // Step 5 : Start the real action
  416. //
  417. jpeg_start_decompress(&decompInfo);
  418. //
  419. // Step 6 : Acquire the scan line
  420. //
  421. while (S_OK == hr &&
  422. decompInfo.output_scanline < decompInfo.output_height)
  423. {
  424. if (DIBBmpSize >= LineSize)
  425. {
  426. //
  427. // Decompress line by line. Ignore the MaxLines since
  428. // we do not do more than one line at a time.
  429. //
  430. jpeg_read_scanlines(&decompInfo, &pDIBBmp, 1);
  431. pDIBBmp -= LineSize;
  432. DIBBmpSize -= LineSize;
  433. }
  434. else
  435. {
  436. //
  437. // The provided buffer is too small.
  438. //
  439. hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
  440. }
  441. }
  442. //
  443. // Step 7 : Finish the job
  444. //
  445. if (SUCCEEDED(hr))
  446. {
  447. jpeg_finish_decompress(&decompInfo);
  448. }
  449. else
  450. {
  451. jpeg_abort_decompress(&decompInfo);
  452. }
  453. //
  454. // Step 8 : Garbage collection
  455. //
  456. jpeg_destroy_decompress(&decompInfo);
  457. return hr;
  458. }