jpegapi.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 8k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. /* jpegapi.cpp -- interface layer for painless JPEG compression of NIFty images.
  2.  * Written by Ajai Sehgal 3/10/96
  3.  * (c) Copyright Microsoft Corporation
  4.  *
  5.  * 08-27-1997 (kurtgeis) Pushed exception handling into library.  Changed
  6.  * all entry points to return HRESULTs.  Added width and heigth to parameters.
  7.  */
  8. #pragma warning(disable:4005)
  9. #include "stdafx.h"
  10. #include "jpegapi.h"
  11. #include "jmemsys.h"
  12. /********************************************************************************/
  13. /* JPEGCompressHeader()
  14.  *
  15.  * Arguments:
  16.  * tuQuality "Quality" of the resulting JPEG (0..100, 100=best)
  17.  *
  18.  * Returns:
  19.  * HRESULT
  20.  */
  21. HRESULT JPEGCompressHeader(BYTE *prgbJPEGHeaderBuf, UINT tuQuality, ULONG *pcbOut, HANDLE *phJpegC, J_COLOR_SPACE ColorSpace)
  22. {
  23. HRESULT hr = S_OK;
  24. try
  25. {
  26. jpeg_compress_struct *spjcs = new jpeg_compress_struct;
  27. struct jpeg_error_mgr *jem = new jpeg_error_mgr;
  28. spjcs->err = jpeg_std_error(jem); // Init the error handler
  29. jpeg_create_compress(spjcs); // Init the compression object
  30. if (ColorSpace == JCS_GRAYSCALE)
  31. {
  32. spjcs->in_color_space = JCS_GRAYSCALE;
  33. spjcs->input_components = 1;
  34. }
  35. else
  36. {
  37. spjcs->in_color_space = JCS_RGBA;
  38. spjcs->input_components = 4;
  39. }
  40. jpeg_set_defaults(spjcs); // Init the compression engine with the defaults
  41. jpeg_set_quality(spjcs, tuQuality, TRUE);
  42. jpeg_set_colorspace(spjcs,ColorSpace);
  43. jpeg_mem_dest(spjcs, prgbJPEGHeaderBuf); // Init the "destination manager"
  44. spjcs->comps_in_scan = 0;
  45. spjcs->write_JFIF_header = FALSE;
  46. jpeg_write_tables(spjcs);
  47. jpeg_suppress_tables(spjcs, TRUE);
  48. *pcbOut = spjcs->bytes_in_buffer;
  49. *phJpegC = (HANDLE) spjcs;
  50. }
  51. catch( THROWN thrownHR )
  52. {
  53. hr = thrownHR.Hr();
  54. }
  55. return hr;
  56. }
  57. /* JPEGDecompressHeader()
  58.  *
  59.  * Arguments:
  60.  * *prgbJPEGBuf : pointer to the JPEG header data as read from file
  61.  * *phJpegD: pointer to Handle of the JPEG decompression object returned
  62.  *
  63.  * Returns:
  64.  * HRESULT
  65.  */
  66. HRESULT JPEGDecompressHeader(BYTE *prgbJPEGHeaderBuf, HANDLE *phJpegD, ULONG ulBufferSize)
  67. {
  68. HRESULT hr = S_OK;
  69. try
  70. {
  71. jpeg_decompress_struct * spjds = new jpeg_decompress_struct;
  72. struct jpeg_error_mgr *jem = new jpeg_error_mgr;
  73. spjds->err = jpeg_std_error(jem); // Init the error handler
  74. jpeg_create_decompress(spjds); // Init the decompression object
  75. // Now we need to "read" it into the decompression object...
  76. jpeg_mem_src(spjds, prgbJPEGHeaderBuf, ulBufferSize);
  77. jpeg_read_header(spjds, FALSE);
  78. spjds->out_color_space = JCS_RGBA;
  79. *phJpegD = (HANDLE) spjds;
  80. }
  81. catch( THROWN thrownHR )
  82. {
  83. hr = thrownHR.Hr();
  84. }
  85. return hr;
  86. }
  87. // DestroyJPEGCompress
  88. //
  89. // Release all the JPEG stuff from the handle we gave to the user
  90. //
  91. HRESULT DestroyJPEGCompressHeader(HANDLE hJpegC)
  92. {
  93. HRESULT hr = S_OK;
  94. try
  95. {
  96. struct jpeg_compress_struct *pjcs = (struct jpeg_compress_struct *)hJpegC;
  97. jpeg_destroy_compress(pjcs);
  98. delete pjcs->err;
  99. delete pjcs;
  100. }
  101. catch( THROWN thrownHR )
  102. {
  103. hr = thrownHR.Hr();
  104. }
  105. return hr;
  106. }
  107. // DestroyJPEGDecompressHeader
  108. //
  109. // Release all the JPEG stuff from the handle we gave to the user
  110. //
  111. HRESULT DestroyJPEGDecompressHeader(HANDLE hJpegD)
  112. {
  113. HRESULT hr = S_OK;
  114. try
  115. {
  116. struct jpeg_decompress_struct *pjds = (struct jpeg_decompress_struct *)hJpegD;
  117. jpeg_destroy_decompress(pjds);
  118. delete pjds->err;
  119. delete pjds;
  120. }
  121. catch( THROWN thrownHR )
  122. {
  123. hr = thrownHR.Hr();
  124. }
  125. return hr;
  126. }
  127. /* JPEGFromRGBA()
  128.  *
  129.  * Arguments:
  130.  * prgbImage A raw image buffer (4 bytes/pixel, RGBA order)
  131.  * cpxlAcross Width of the image, in pixels
  132.  * cpxlDown Height of the image, in pixels
  133.  * tuQuality "Quality" of the resulting JPEG (0..100, 100=best)
  134.  * A memory buffer containing the complete JPEG compressed version of the
  135.  * given image. NULL on error.
  136.  *
  137.  * Returns:
  138.  * HRESULT
  139.  */
  140. HRESULT JPEGFromRGBA(BYTE *prgbImage, BYTE *prgbJPEGBuf, UINT tuQuality, ULONG *pcbOut, HANDLE hJpegC, J_COLOR_SPACE ColorSpace, UINT nWidth, UINT nHeight )
  141. {
  142. HRESULT hr = S_OK;
  143. try
  144. {
  145. struct jpeg_compress_struct *pjcs = (jpeg_compress_struct *)hJpegC;
  146. JSAMPROW rgrow[1];
  147. //
  148. // On non X86 architectures use only C code
  149. //
  150. #if defined (_X86_)
  151. pjcs->dct_method = JDCT_ISLOW;
  152. #else
  153. pjcs->dct_method = JDCT_FLOAT;
  154. #endif
  155.                 pjcs->image_width = nWidth;
  156. pjcs->image_height = nHeight;
  157. pjcs->data_precision = 8; /* 8 bits / sample */
  158. pjcs->bytes_in_buffer = 0;
  159. pjcs->write_JFIF_header = FALSE;
  160. if (ColorSpace == JCS_GRAYSCALE)
  161. {
  162. pjcs->input_components = 1;
  163. }
  164. else
  165. {
  166. pjcs->input_components = 4;
  167. }
  168. jpeg_set_colorspace(pjcs,ColorSpace);
  169.  
  170. jpeg_set_quality(pjcs, tuQuality, TRUE);
  171. jpeg_suppress_tables(pjcs, TRUE);
  172. jpeg_mem_dest(pjcs, prgbJPEGBuf); // Init the "destination manager"
  173. jpeg_start_compress(pjcs, FALSE);
  174. rgrow[0] = (JSAMPROW)prgbImage;
  175. while (pjcs->next_scanline < nHeight )
  176. {
  177. jpeg_write_scanlines(pjcs, rgrow, 1);
  178. rgrow[0] += nWidth * pjcs->input_components; //input_components is the equivalent of # of bytes
  179. }
  180. jpeg_finish_compress(pjcs); // Finish up compressing
  181. *pcbOut = pjcs->bytes_in_buffer;
  182. }
  183. catch( THROWN thrownHR )
  184. {
  185. hr = thrownHR.Hr();
  186. }
  187. return hr;
  188. }
  189. /* RGBAFromJPEG()
  190.  *
  191.  * Arguments:
  192.  * prgbJPEG: A JPEG data stream, as returned by JPEGFromRGBA()
  193.  * A memory buffer containing the reconstructed image in RGBA format.
  194.  * NULL on error.
  195.  *
  196.  * Returns:
  197.  * HRESULT
  198. */
  199. HRESULT RGBAFromJPEG(BYTE *prgbJPEG, BYTE *prgbImage, HANDLE hJpegD, ULONG ulBufferSize, BYTE bJPEGConversionType, ULONG *pulReturnedNumChannels, UINT nWidth, UINT nHeight )
  200. {
  201. HRESULT hr = S_OK;
  202. try
  203. {
  204. struct jpeg_decompress_struct *pjds;
  205. jpeg_decompress_struct * spjds = new jpeg_decompress_struct;
  206. struct jpeg_error_mgr *jem;
  207. jpeg_error_mgr * spjem = new jpeg_error_mgr;
  208. if ( hJpegD == NULL )
  209. {
  210. spjds->err = jpeg_std_error(spjem); // Init the error handler
  211. jpeg_create_decompress(spjds); // Init the decompression object in the case
  212. pjds = spjds; // that the headers are with the tiles.
  213. jem = spjem;
  214. }
  215. else if ( hJpegD == NULL )
  216. {
  217. // This should never happen.  The decompression header was not set up return an
  218. // error indication by setting the return value to kpvNil.
  219. return E_FAIL;
  220. }
  221. else
  222. {
  223. pjds = (struct jpeg_decompress_struct *)hJpegD;
  224. }
  225. JSAMPROW rgrow[1];
  226. // Set the various image parameters.
  227. pjds->data_precision = 8;
  228. pjds->image_width = nWidth;
  229. pjds->image_height = nHeight;
  230. jpeg_mem_src(pjds, prgbJPEG, ulBufferSize); // Init the "source manager"
  231. jpeg_read_header(pjds, TRUE);
  232. switch (bJPEGConversionType)
  233. {
  234. case 1:
  235. pjds->out_color_space = JCS_RGBA;
  236. if (pjds->jpeg_color_space != JCS_RGBA)
  237. {
  238. if ( 4 == pjds->num_components) 
  239. pjds->jpeg_color_space = JCS_YCbCrALegacy;
  240. else
  241. pjds->jpeg_color_space = JCS_YCbCr;
  242. }
  243. *pulReturnedNumChannels = 4;
  244. break;
  245. case 2:
  246. pjds->out_color_space = JCS_RGBA;
  247. if ( 4 == pjds->num_components) 
  248. pjds->jpeg_color_space = JCS_YCbCrA;
  249. else
  250. pjds->jpeg_color_space = JCS_YCbCr;
  251. pjds->jpeg_color_space = JCS_YCbCrA;
  252. *pulReturnedNumChannels = 4;
  253. break;
  254. default:
  255. pjds->out_color_space = JCS_UNKNOWN; 
  256. pjds->jpeg_color_space = JCS_UNKNOWN;
  257. *pulReturnedNumChannels = pjds->num_components;
  258. }
  259. //
  260. // On non X86 architectures use only C code
  261. //
  262. #if defined (_X86_)
  263. pjds->dct_method = JDCT_ISLOW;
  264. #else
  265.      pjds->dct_method = JDCT_FLOAT;
  266. #endif
  267. jpeg_start_decompress(pjds);
  268. rgrow[0] = (JSAMPROW)prgbImage;
  269. while (pjds->output_scanline < pjds->output_height)
  270. {
  271. jpeg_read_scanlines(pjds, rgrow, 1);
  272. rgrow[0] += pjds->output_width * *pulReturnedNumChannels;
  273. }
  274. jpeg_finish_decompress(pjds); // Finish up decompressing
  275. if (hJpegD == NULL)
  276. jpeg_destroy_decompress(pjds);  //Destroy the decompression object if it
  277. //was locally allocated as in when the header
  278. //is part of the tile.
  279. delete spjem;
  280.                 delete spjds;
  281. }
  282. catch( THROWN thrownHR )
  283. {
  284. hr = thrownHR.Hr();
  285. }
  286. return hr;
  287. }