Jpegfile.cpp
上传用户:cjw5120
上传日期:2022-05-11
资源大小:5032k
文件大小:44k
源码类别:

网络截获/分析

开发平台:

Visual C++

  1. ////////////////////////////////////////////////////////////
  2. // JpegFile - A C++ class to allow reading and writing of
  3. // RGB and Grayscale JPEG images.
  4. // It is based on the IJG V.6 code.
  5. //
  6. // This class Copyright 1997, Chris Losinger
  7. // This is free to use and modify provided my name is 
  8. // included.
  9. //
  10. // See jpegfile.h for usage.
  11. //
  12. ////////////////////////////////////////////////////////////
  13. #include "stdafx.h"
  14. #include "JpegFile.h"
  15. #define MAX_SIZE 1000000
  16. #include <stdio.h>
  17. #ifdef __cplusplus
  18. extern "C" {
  19. #endif // __cplusplus
  20. #include "jpeglib\jpeglib.h"
  21. #ifdef __cplusplus
  22. }
  23. #endif // __cplusplus
  24. //
  25. //
  26. //
  27. /*
  28.  * <setjmp.h> is used for the optional error recovery mechanism shown in
  29.  * the second part of the example.
  30.  */
  31. #include <setjmp.h>
  32. // error handler, to avoid those pesky exit(0)'s
  33. struct my_error_mgr {
  34.   struct jpeg_error_mgr pub; /* "public" fields */
  35.   jmp_buf setjmp_buffer; /* for return to caller */
  36. };
  37. typedef struct my_error_mgr * my_error_ptr;
  38. //
  39. //
  40. //
  41. METHODDEF(void) my_error_exit (j_common_ptr cinfo);
  42. //
  43. // to handle fatal errors.
  44. // the original JPEG code will just exit(0). can't really
  45. // do that in Windows....
  46. //
  47. METHODDEF(void) my_error_exit (j_common_ptr cinfo)
  48. {
  49. /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
  50. my_error_ptr myerr = (my_error_ptr) cinfo->err;
  51. char buffer[JMSG_LENGTH_MAX];
  52. /* Create the message */
  53. (*cinfo->err->format_message) (cinfo, buffer);
  54. /* Always display the message. */
  55. //MessageBox(NULL,buffer,"JPEG Fatal Error",MB_ICONSTOP);
  56. /* Return control to the setjmp point */
  57. longjmp(myerr->setjmp_buffer, 1);
  58. }
  59. // store a scanline to our data buffer
  60. void j_putRGBScanline(BYTE *jpegline, 
  61.  int widthPix,
  62.  BYTE *outBuf,
  63.  int row);
  64. void j_putGrayScanlineToRGB(BYTE *jpegline, 
  65.  int widthPix,
  66.  BYTE *outBuf,
  67.  int row);
  68. //
  69. // constructor doesn't do much - there's no real class here...
  70. //
  71. JpegFile::JpegFile()
  72. {
  73. m_dwPoint = 0;
  74. // m_lpBuffer = NULL;
  75. m_bOpening = false;
  76. m_dwOutMaxSize = 0;
  77.     m_lpOutBuffer = NULL;
  78. m_dwScreenMaxSize = 0;
  79.     m_lpScreenBuffer = NULL;
  80.     m_lpPreData = NULL;
  81. }
  82. //
  83. //
  84. //
  85. JpegFile::~JpegFile()
  86. {
  87.    if (m_lpPreData) GlobalFree (m_lpPreData);
  88.    if (m_lpOutBuffer) GlobalFree (m_lpOutBuffer);
  89.    if (m_lpScreenBuffer) GlobalFree (m_lpScreenBuffer);
  90. }
  91. //
  92. // read a JPEG file
  93. //
  94. BYTE * JpegFile::JpegFileToRGB(BYTE *inBuf,
  95.    unsigned long size,
  96.    UINT *width,
  97.    UINT *height)
  98. {
  99. // get our buffer set to hold data
  100. BYTE *dataBuf = NULL;
  101. // basic code from IJG Jpeg Code v6 example.c
  102. *width=0;
  103. *height=0;
  104. /* This struct contains the JPEG decompression parameters and pointers to
  105. * working space (which is allocated as needed by the JPEG library).
  106. */
  107. struct jpeg_decompress_struct cinfo;
  108. /* We use our private extension JPEG error handler.
  109. * Note that this struct must live as long as the main JPEG parameter
  110. * struct, to avoid dangling-pointer problems.
  111. */
  112. struct my_error_mgr jerr;
  113. /* More stuff */
  114. FILE * infile=NULL; /* source file */
  115. JSAMPARRAY buffer; /* Output row buffer */
  116. int row_stride; /* physical row width in output buffer */
  117. // char buf[250];
  118. /* In this example we want to open the input file before doing anything else,
  119. * so that the setjmp() error recovery below can assume the file is open.
  120. * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
  121. * requires it in order to read binary files.
  122. */
  123. /* if ((infile = fopen(fileName, "rb")) == NULL) {
  124. sprintf(buf, "JPEG :nCan't open %sn", fileName);
  125. AfxMessageBox(buf);
  126. return NULL;
  127. }
  128. */
  129. /* Step 1: allocate and initialize JPEG decompression object */
  130. /* We set up the normal JPEG error routines, then override error_exit. */
  131. cinfo.err = jpeg_std_error(&jerr.pub);
  132. jerr.pub.error_exit = my_error_exit;
  133. /* Establish the setjmp return context for my_error_exit to use. */
  134. if (setjmp(jerr.setjmp_buffer)) {
  135. /* If we get here, the JPEG code has signaled an error.
  136.  * We need to clean up the JPEG object, close the input file, and return.
  137.  */
  138. jpeg_destroy_decompress(&cinfo);
  139. /*
  140. if (infile!=NULL)
  141. fclose(infile);
  142.       if (dataBuf!=NULL)
  143.       {
  144.          delete [] dataBuf;
  145.       }
  146. */
  147. return NULL;
  148. }
  149. /* Now we can initialize the JPEG decompression object. */
  150. jpeg_create_decompress(&cinfo);
  151.     cinfo.l_size = size;
  152.   cinfo.l_point = 0;
  153.   cinfo.i_stream = 1;
  154.   cinfo.buffer = inBuf;
  155. /* Step 2: specify data source (eg, a file) */
  156. jpeg_stdio_src(&cinfo, infile);
  157. /* Step 3: read file parameters with jpeg_read_header() */
  158. (void) jpeg_read_header(&cinfo, TRUE);
  159. /* We can ignore the return value from jpeg_read_header since
  160. *   (a) suspension is not possible with the stdio data source, and
  161. *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
  162. * See libjpeg.doc for more info.
  163. */
  164. /* Step 4: set parameters for decompression */
  165. /* In this example, we don't need to change any of the defaults set by
  166. * jpeg_read_header(), so we do nothing here.
  167. */
  168. /* Step 5: Start decompressor */
  169. (void) jpeg_start_decompress(&cinfo);
  170. /* We can ignore the return value since suspension is not possible
  171. * with the stdio data source.
  172. */
  173. /* We may need to do some setup of our own at this point before reading
  174. * the data.  After jpeg_start_decompress() we have the correct scaled
  175. * output image dimensions available, as well as the output colormap
  176. * if we asked for color quantization.
  177. * In this example, we need to make an output work buffer of the right size.
  178. */ 
  179. ////////////////////////////////////////////////////////////
  180. // alloc and open our new buffer
  181. // dataBuf=(BYTE *)new BYTE[cinfo.output_width * 3 * cinfo.output_height];
  182. DWORD dwSize = cinfo.output_width * 3 * cinfo.output_height;
  183. if (m_lpOutBuffer==NULL || m_dwOutMaxSize < dwSize) 
  184. {
  185.      if (m_lpOutBuffer) GlobalFree (m_lpOutBuffer);
  186.    m_lpOutBuffer = (BYTE *)GlobalAlloc (GMEM_FIXED, dwSize);
  187.    m_dwOutMaxSize = dwSize;
  188.    if (m_lpOutBuffer == NULL)
  189.    {
  190.      AfxMessageBox("JpegFile :nOut of memory",MB_ICONSTOP);
  191.  jpeg_destroy_decompress(&cinfo);
  192. //DEL fclose(infile);
  193.       return NULL;
  194.    }
  195. }
  196.     dataBuf = m_lpOutBuffer;
  197. // how big is this thing gonna be?
  198. *width = cinfo.output_width;
  199. *height = cinfo.output_height;
  200. /* JSAMPLEs per row in output buffer */
  201. row_stride = cinfo.output_width * cinfo.output_components;
  202. /* Make a one-row-high sample array that will go away when done with image */
  203. buffer = (*cinfo.mem->alloc_sarray)
  204. ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
  205. /* Step 6: while (scan lines remain to be read) */
  206. /*           jpeg_read_scanlines(...); */
  207. /* Here we use the library's state variable cinfo.output_scanline as the
  208. * loop counter, so that we don't have to keep track ourselves.
  209. */
  210. while (cinfo.output_scanline < cinfo.output_height) {
  211. /* jpeg_read_scanlines expects an array of pointers to scanlines.
  212.  * Here the array is only one element long, but you could ask for
  213.  * more than one scanline at a time if that's more convenient.
  214.  */
  215. (void) jpeg_read_scanlines(&cinfo, buffer, 1);
  216. /* Assume put_scanline_someplace wants a pointer and sample count. */
  217. // asuumer all 3-components are RGBs
  218. if (cinfo.out_color_components==3) {
  219. j_putRGBScanline(buffer[0], 
  220. *width,
  221. dataBuf,
  222. cinfo.output_scanline-1);
  223. } else if (cinfo.out_color_components==1) {
  224. // assume all single component images are grayscale
  225. j_putGrayScanlineToRGB(buffer[0], 
  226. *width,
  227. dataBuf,
  228. cinfo.output_scanline-1);
  229. }
  230. }
  231. /* Step 7: Finish decompression */
  232. (void) jpeg_finish_decompress(&cinfo);
  233. /* We can ignore the return value since suspension is not possible
  234. * with the stdio data source.
  235. */
  236. /* Step 8: Release JPEG decompression object */
  237. /* This is an important step since it will release a good deal of memory. */
  238. jpeg_destroy_decompress(&cinfo);
  239. /* After finish_decompress, we can close the input file.
  240. * Here we postpone it until after no more JPEG errors are possible,
  241. * so as to simplify the setjmp error logic above.  (Actually, I don't
  242. * think that jpeg_destroy can do an error exit, but why assume anything...)
  243. */
  244. // fclose(infile);
  245. /* At this point you may want to check to see whether any corrupt-data
  246. * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
  247. */
  248. return dataBuf;
  249. }
  250. BOOL JpegFile::GetJPGDimensions(CString fileName,
  251. UINT *width,
  252. UINT *height)
  253. {
  254. // basic code from IJG Jpeg Code v6 example.c
  255. /* This struct contains the JPEG decompression parameters and pointers to
  256. * working space (which is allocated as needed by the JPEG library).
  257. */
  258. struct jpeg_decompress_struct cinfo;
  259. /* We use our private extension JPEG error handler.
  260. * Note that this struct must live as long as the main JPEG parameter
  261. * struct, to avoid dangling-pointer problems.
  262. */
  263. struct my_error_mgr jerr;
  264. /* More stuff */
  265. FILE * infile=NULL; /* source file */
  266. char buf[250];
  267. /* In this example we want to open the input file before doing anything else,
  268. * so that the setjmp() error recovery below can assume the file is open.
  269. * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
  270. * requires it in order to read binary files.
  271. */
  272. if ((infile = fopen(fileName, "rb")) == NULL) {
  273. sprintf(buf, "JPEG :nCan't open %sn", fileName);
  274. AfxMessageBox(buf);
  275. return FALSE;
  276. }
  277. /* Step 1: allocate and initialize JPEG decompression object */
  278. /* We set up the normal JPEG error routines, then override error_exit. */
  279. cinfo.err = jpeg_std_error(&jerr.pub);
  280. jerr.pub.error_exit = my_error_exit;
  281. /* Establish the setjmp return context for my_error_exit to use. */
  282. if (setjmp(jerr.setjmp_buffer)) {
  283. /* If we get here, the JPEG code has signaled an error.
  284.  * We need to clean up the JPEG object, close the input file, and return.
  285.  */
  286. jpeg_destroy_decompress(&cinfo);
  287. if (infile!=NULL)
  288. fclose(infile);
  289. return FALSE;
  290. }
  291. /* Now we can initialize the JPEG decompression object. */
  292. jpeg_create_decompress(&cinfo);
  293. /* Step 2: specify data source (eg, a file) */
  294. jpeg_stdio_src(&cinfo, infile);
  295. /* Step 3: read file parameters with jpeg_read_header() */
  296. (void) jpeg_read_header(&cinfo, TRUE);
  297. /* We can ignore the return value from jpeg_read_header since
  298. *   (a) suspension is not possible with the stdio data source, and
  299. *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
  300. * See libjpeg.doc for more info.
  301. */
  302. // how big is this thing ?
  303. *width = cinfo.image_width;
  304. *height = cinfo.image_height;
  305. /* Step 8: Release JPEG decompression object */
  306. /* This is an important step since it will release a good deal of memory. */
  307. jpeg_destroy_decompress(&cinfo);
  308. /* After finish_decompress, we can close the input file.
  309. * Here we postpone it until after no more JPEG errors are possible,
  310. * so as to simplify the setjmp error logic above.  (Actually, I don't
  311. * think that jpeg_destroy can do an error exit, but why assume anything...)
  312. */
  313. fclose(infile);
  314. /* At this point you may want to check to see whether any corrupt-data
  315. * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
  316. */
  317. return TRUE;
  318. }
  319. //
  320. //
  321. //
  322. BYTE *JpegFile::RGBFromDWORDAligned(BYTE *inBuf,
  323. UINT widthPix, 
  324. UINT widthBytes,
  325. UINT height)
  326. {
  327. if (inBuf==NULL)
  328. return NULL;
  329. BYTE *tmp;
  330. tmp=(BYTE *)new BYTE[height * widthPix * 3];
  331. if (tmp==NULL)
  332. return NULL;
  333. UINT row;
  334. for (row=0;row<height;row++) {
  335. memcpy((tmp+row * widthPix * 3), 
  336. (inBuf + row * widthBytes), 
  337. widthPix * 3);
  338. }
  339. return tmp;
  340. }
  341. //
  342. //
  343. //
  344. BOOL JpegFile::RGBToJpegFile(BYTE *dataBuf,
  345.   BYTE *outBuf,
  346. UINT widthPix,
  347. UINT height,
  348. BOOL color, 
  349. int quality,
  350. unsigned long *size)
  351. {
  352.   BOOL b_return = true;
  353.   FILE *outfile = NULL; /* target file */
  354. /*  FILE outtmp;
  355.   FILE *outfile = &outtmp;
  356.   memset(outfile, 0, sizeof(FILE));
  357. */ if (dataBuf==NULL) goto err01;
  358. if (outBuf == NULL) goto err01;
  359. if (widthPix==0)  goto err01;
  360. if (height==0) goto err01;
  361. // we vertical flip for display. undo that.
  362. // VertFlipBuf(dataBuf, widthPix * 3, height);
  363. // we swap red and blue for display, undo that.
  364. // BGRFromRGB(dataBuf, widthPix, height);
  365. LPBYTE tmp;
  366. if (!color) {
  367. tmp = (BYTE*)new BYTE[widthPix*height];
  368. if (tmp==NULL) goto err01;
  369. UINT row,col;
  370. for (row=0;row<height;row++) {
  371. for (col=0;col<widthPix;col++) {
  372. LPBYTE pRed, pGrn, pBlu;
  373. pRed = dataBuf + row * widthPix * 3 + col * 3;
  374. pGrn = dataBuf + row * widthPix * 3 + col * 3 + 1;
  375. pBlu = dataBuf + row * widthPix * 3 + col * 3 + 2;
  376. // luminance
  377. int lum = (int)(.299 * (double)(*pRed) + .587 * (double)(*pGrn) + .114 * (double)(*pBlu));
  378. LPBYTE pGray;
  379. pGray = tmp + row * widthPix + col;
  380. *pGray = (BYTE)lum;
  381. }
  382. }
  383. }
  384. struct jpeg_compress_struct cinfo;
  385. /* More stuff */
  386. int row_stride; /* physical row widthPix in image buffer */
  387. struct my_error_mgr jerr;
  388. /* Step 1: allocate and initialize JPEG compression object */
  389. cinfo.err = jpeg_std_error(&jerr.pub);
  390. jerr.pub.error_exit = my_error_exit;
  391. /* Establish the setjmp return context for my_error_exit to use. */
  392. if (setjmp(jerr.setjmp_buffer)) {
  393. /* If we get here, the JPEG code has signaled an error.
  394.  * We need to clean up the JPEG object, close the input file, and return.
  395.  */
  396. jpeg_destroy_compress(&cinfo);
  397. //DEL if (outfile!=NULL)
  398. //DEL fclose(outfile);
  399. if (!color) delete [] tmp;
  400. //DEL return FALSE;
  401. //DEL if (!color)
  402.   goto err01;
  403. }
  404. /* Now we can initialize the JPEG compression object. */
  405. jpeg_create_compress(&cinfo);
  406. cinfo.l_size = *size;
  407.   cinfo.l_point = 0;
  408.   cinfo.i_stream = 1;
  409.   cinfo.buffer = (unsigned char *)outBuf;
  410. /* Step 2: specify data destination (eg, a file) */
  411. /* Note: steps 2 and 3 can be done in either order. */
  412. /*
  413. if ((outfile = fopen("c:\111.jpg", "wb")) == NULL) 
  414. {
  415.       char buf[250];
  416. //sprintf(buf, "JpegFile :nCan't open %sn", fileName);
  417. AfxMessageBox(buf);
  418. return FALSE;
  419. }
  420. */
  421. jpeg_stdio_dest(&cinfo, outfile);
  422. /* Step 3: set parameters for compression */
  423.     
  424. /* First we supply a description of the input image.
  425. * Four fields of the cinfo struct must be filled in:
  426. */
  427. cinfo.image_width = widthPix;  /* image widthPix and height, in pixels */
  428. cinfo.image_height = height;
  429. if (color) {
  430. cinfo.input_components = 3; /* # of color components per pixel */
  431. cinfo.in_color_space = JCS_RGB;  /* colorspace of input image */
  432. } else {
  433. cinfo.input_components = 1; /* # of color components per pixel */
  434. cinfo.in_color_space = JCS_GRAYSCALE;  /* colorspace of input image */
  435. }
  436.  
  437. /* Now use the library's routine to set default compression parameters.
  438.    * (You must set at least cinfo.in_color_space before calling this,
  439.    * since the defaults depend on the source color space.)
  440.    */
  441.   jpeg_set_defaults(&cinfo);
  442.   /* Now you can set any non-default parameters you wish to.
  443.    * Here we just illustrate the use of quality (quantization table) scaling:
  444.    */
  445.   jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
  446.   /* Step 4: Start compressor */
  447.   /* TRUE ensures that we will write a complete interchange-JPEG file.
  448.    * Pass TRUE unless you are very sure of what you're doing.
  449.    */
  450.   jpeg_start_compress(&cinfo, TRUE);
  451.   /* Step 5: while (scan lines remain to be written) */
  452.   /*           jpeg_write_scanlines(...); */
  453.   /* Here we use the library's state variable cinfo.next_scanline as the
  454.    * loop counter, so that we don't have to keep track ourselves.
  455.    * To keep things simple, we pass one scanline per call; you can pass
  456.    * more if you wish, though.
  457.    */
  458.   row_stride = widthPix * 3; /* JSAMPLEs per row in image_buffer */
  459.   while (cinfo.next_scanline < cinfo.image_height) {
  460.     /* jpeg_write_scanlines expects an array of pointers to scanlines.
  461.      * Here the array is only one element long, but you could pass
  462.      * more than one scanline at a time if that's more convenient.
  463.      */
  464. LPBYTE outRow;
  465. if (color) {
  466. outRow = dataBuf + (cinfo.next_scanline * widthPix * 3);
  467. } else {
  468. outRow = tmp + (cinfo.next_scanline * widthPix);
  469. }
  470.     (void) jpeg_write_scanlines(&cinfo, &outRow, 1);
  471.   }
  472.   /* Step 6: Finish compression */
  473.   jpeg_finish_compress(&cinfo);
  474.   *size = cinfo.l_point;
  475.   /* After finish_compress, we can close the output file. */
  476.   //DEL fclose(outfile);
  477.   /* Step 7: release JPEG compression object */
  478.   /* This is an important step since it will release a good deal of memory. */
  479.   if (cinfo.l_point > cinfo.l_size)
  480.     b_return = false;
  481.   jpeg_destroy_compress(&cinfo);
  482. //  fclose(outfile);
  483.   if (!color)  delete [] tmp;
  484.   /* And we're done! */
  485.   return b_return;
  486. err01:
  487.    return false;
  488. //  return TRUE;
  489. }
  490. //
  491. // stash a scanline
  492. //
  493. void j_putRGBScanline(BYTE *jpegline, 
  494.  int widthPix,
  495.  BYTE *outBuf,
  496.  int row)
  497. {
  498. int offset = row * widthPix * 3;
  499. int count;
  500. for (count=0;count<widthPix;count++) 
  501. {
  502. *(outBuf + offset + count * 3 + 0) = *(jpegline + count * 3 + 0);
  503. *(outBuf + offset + count * 3 + 1) = *(jpegline + count * 3 + 1);
  504. *(outBuf + offset + count * 3 + 2) = *(jpegline + count * 3 + 2);
  505. }
  506. }
  507. //
  508. // stash a gray scanline
  509. //
  510. void j_putGrayScanlineToRGB(BYTE *jpegline, 
  511.  int widthPix,
  512.  BYTE *outBuf,
  513.  int row)
  514. {
  515. int offset = row * widthPix * 3;
  516. int count;
  517. for (count=0;count<widthPix;count++) {
  518. BYTE iGray;
  519. // get our grayscale value
  520. iGray = *(jpegline + count);
  521. *(outBuf + offset + count * 3 + 0) = iGray;
  522. *(outBuf + offset + count * 3 + 1) = iGray;
  523. *(outBuf + offset + count * 3 + 2) = iGray;
  524. }
  525. }
  526. //
  527. // copies BYTE buffer into DWORD-aligned BYTE buffer
  528. // return addr of new buffer
  529. //
  530. BYTE * JpegFile::MovetoBuf(BYTE *dataBuf,
  531.  CRect *prcRect, // pixels!!
  532.  UINT widthNew,
  533.  UINT heightNew) // bytes!!!
  534. {
  535. ////////////////////////////////////////////////////////////
  536. // what's going on here? this certainly means trouble 
  537. if (dataBuf==NULL)
  538. return NULL;
  539. ////////////////////////////////////////////////////////////
  540. // how big is the smallest DWORD-aligned buffer that we can use?
  541. UINT uiWidthBytes, uiWidthBytesNew;
  542. uiWidthBytes = WIDTHBYTES(prcRect->Width() * 24);
  543. uiWidthBytes = 3 * prcRect->Width();
  544. uiWidthBytesNew = 3 * widthNew;
  545. DWORD dwNewsize=(DWORD)((DWORD)uiWidthBytesNew * 
  546. (DWORD)heightNew);
  547. BYTE *pNew;
  548. ////////////////////////////////////////////////////////////
  549. // alloc and open our new buffer
  550. pNew=(BYTE *)new BYTE[dwNewsize];
  551. if (pNew==NULL) {
  552. return NULL;
  553. }
  554. UINT row,col;
  555. memset(pNew, 0,dwNewsize);
  556. for (row=0;(int)row<prcRect->Height();row++) {
  557. for (col=0;(int)col<prcRect->Width();col++) {
  558. BYTE pRed, pGrn, pBlu;
  559. pRed = dataBuf[row * prcRect->Width() * 3 + col * 3];
  560. pGrn = dataBuf[row * prcRect->Width() * 3 + col * 3+1];
  561. pBlu = dataBuf[row * prcRect->Width() * 3 + col * 3+2];
  562. pNew[(heightNew - prcRect->bottom + row) * widthNew * 3 + (col+prcRect->left) * 3] = (BYTE)pRed;
  563. pNew[(heightNew - prcRect->bottom + row) * widthNew * 3 + (col+prcRect->left) * 3+1] = (BYTE)pGrn;
  564. pNew[(heightNew - prcRect->bottom + row) * widthNew * 3 + (col+prcRect->left) * 3+2] = (BYTE)pBlu;
  565. }
  566. }
  567. return pNew;
  568. }
  569. //
  570. // copies BYTE buffer into DWORD-aligned BYTE buffer
  571. // return addr of new buffer
  572. //
  573. BYTE * JpegFile::MakeDwordAlignedBuf(BYTE *dataBuf,
  574.  UINT widthPix, // pixels!!
  575.  UINT height,
  576.  UINT *uiOutWidthBytes) // bytes!!!
  577. {
  578. ////////////////////////////////////////////////////////////
  579. // what's going on here? this certainly means trouble 
  580. if (dataBuf==NULL)
  581. return NULL;
  582. ////////////////////////////////////////////////////////////
  583. // how big is the smallest DWORD-aligned buffer that we can use?
  584. UINT uiWidthBytes;
  585. uiWidthBytes = WIDTHBYTES(widthPix * 24);
  586. DWORD dwNewsize=(DWORD)((DWORD)uiWidthBytes * 
  587. (DWORD)height);
  588. BYTE *pNew;
  589. ////////////////////////////////////////////////////////////
  590. // alloc and open our new buffer
  591. /* pNew=(BYTE *)new BYTE[dwNewsize];
  592. if (pNew==NULL) {
  593. return NULL;
  594. }
  595. */
  596. if (m_lpScreenBuffer==NULL || m_dwScreenMaxSize < dwNewsize) 
  597. {
  598.      if (m_lpScreenBuffer) GlobalFree (m_lpScreenBuffer);
  599.    m_lpScreenBuffer = (BYTE *)GlobalAlloc (GMEM_FIXED, dwNewsize);
  600.    m_dwScreenMaxSize = dwNewsize;
  601.    if (m_lpScreenBuffer == NULL) return NULL;
  602.     }
  603. pNew = m_lpScreenBuffer;
  604. ////////////////////////////////////////////////////////////
  605. // copy row-by-row
  606. UINT uiInWidthBytes = widthPix * 3;
  607. UINT uiCount;
  608. for (uiCount=0;uiCount < height;uiCount++) {
  609. BYTE * bpInAdd;
  610. BYTE * bpOutAdd;
  611. ULONG lInOff;
  612. ULONG lOutOff;
  613. lInOff=uiInWidthBytes * uiCount;
  614. lOutOff=uiWidthBytes * uiCount;
  615. bpInAdd= dataBuf + lInOff;
  616. bpOutAdd= pNew + lOutOff;
  617. memcpy(bpOutAdd,bpInAdd,uiInWidthBytes);
  618. }
  619. *uiOutWidthBytes=uiWidthBytes;
  620. return pNew;
  621. }
  622. //
  623. // vertically flip a buffer 
  624. // note, this operates on a buffer of widthBytes bytes, not pixels!!!
  625. //
  626. BOOL JpegFile::VertFlipBuf(BYTE  * inbuf, 
  627.    UINT widthBytes, 
  628.    UINT height)
  629. {   
  630. BYTE  *tb1;
  631. BYTE  *tb2;
  632. if (inbuf==NULL)
  633. return FALSE;
  634. UINT bufsize;
  635. bufsize=widthBytes;
  636. tb1= (BYTE *)new BYTE[bufsize];
  637. if (tb1==NULL) {
  638. return FALSE;
  639. }
  640. tb2= (BYTE *)new BYTE [bufsize];
  641. if (tb2==NULL) {
  642. delete [] tb1;
  643. return FALSE;
  644. }
  645. UINT row_cnt;     
  646. ULONG off1=0;
  647. ULONG off2=0;
  648. for (row_cnt=0;row_cnt<(height+1)/2;row_cnt++) {
  649. off1=row_cnt*bufsize;
  650. off2=((height-1)-row_cnt)*bufsize;   
  651. memcpy(tb1,inbuf+off1,bufsize);
  652. memcpy(tb2,inbuf+off2,bufsize);
  653. memcpy(inbuf+off1,tb2,bufsize);
  654. memcpy(inbuf+off2,tb1,bufsize);
  655. }
  656. delete [] tb1;
  657. delete [] tb2;
  658. return TRUE;
  659. }        
  660. //
  661. // swap Rs and Bs
  662. //
  663. // Note! this does its stuff on buffers with a whole number of pixels
  664. // per data row!!
  665. //
  666. BOOL JpegFile::BGRFromRGB(BYTE *buf, UINT widthPix, UINT height)
  667. {
  668. if (buf==NULL)
  669. return FALSE;
  670. UINT col, row;
  671. for (row=0;row<height;row++) {
  672. for (col=0;col<widthPix;col++) {
  673. LPBYTE pRed, pGrn, pBlu;
  674. pRed = buf + row * widthPix * 3 + col * 3;
  675. pGrn = buf + row * widthPix * 3 + col * 3 + 1;
  676. pBlu = buf + row * widthPix * 3 + col * 3 + 2;
  677. // swap red and blue
  678. BYTE tmp;
  679. tmp = *pRed;
  680. *pRed = *pBlu;
  681. *pBlu = tmp;
  682. }
  683. }
  684. return TRUE;
  685. }
  686. //
  687. // Note! this does its stuff on buffers with a whole number of pixels
  688. // per data row!!
  689. //
  690. BOOL JpegFile::MakeGrayScale(BYTE *buf, UINT widthPix, UINT height, BOOL trun)
  691. {
  692. if (buf==NULL)
  693. return FALSE;
  694. UINT row,col;
  695. for (row=0;row<height;row++) {
  696. for (col=0;col<widthPix;col++) {
  697. LPBYTE pRed, pGrn, pBlu;
  698. pRed = buf + row * widthPix * 3 + col * 3;
  699. pGrn = buf + row * widthPix * 3 + col * 3 + 1;
  700. pBlu = buf + row * widthPix * 3 + col * 3 + 2;
  701. // luminance
  702. int lum = (int)(.299 * (double)(*pRed) + .587 * (double)(*pGrn) + .114 * (double)(*pBlu));
  703. if (trun) lum = ~lum;
  704. *pRed = (BYTE)lum;
  705. *pGrn = (BYTE)lum;
  706. *pBlu = (BYTE)lum;
  707. }
  708. }
  709. return TRUE;
  710. }
  711. //DEL bool JpegFile::MYMOpen(CString sFile)
  712. //DEL {
  713. //DEL    CFileException e;
  714. //DEL     MYMClose();
  715. //DEL     m_lpBuffer = new BYTE[MAX_SIZE];
  716. //DEL  if (m_lpBuffer == NULL) return false;
  717. //DEL 
  718. //DEL     if(!m_rFile.Open(sFile,CFile::typeBinary|CFile::modeRead,&e)) return false;
  719. //DEL     if(!m_rFile.Read(&m_header, sizeof(MYMHEADER))) goto err01;
  720. //DEL     if (memcmp(m_header.szNote, "MYMEDIA", 7) || memcmp(m_header.szVersion,"VERSION1.0", 10 ))
  721. //DEL  return false;
  722. //DEL 
  723. //DEL     m_bOpening = true;
  724. //DEL  m_dwPoint = 0;
  725. //DEL  m_dwFrame = 0;
  726. //DEL  return true;
  727. //DEL 
  728. //DEL err01:
  729. //DEL  m_rFile.Close();
  730. //DEL  return false;
  731. //DEL }
  732. //DEL void JpegFile::MYMClose()
  733. //DEL {
  734. //DEL     if(m_bOpening)
  735. //DEL  m_rFile.Close();
  736. //DEL  m_bOpening = false;
  737. //DEL  if(m_lpBuffer) delete m_lpBuffer;
  738. //DEL  m_lpBuffer = NULL;
  739. //DEL  m_dwPoint = 0;
  740. //DEL  m_dwFrame = 0;
  741. //DEL 
  742. //DEL }
  743. //DEL bool JpegFile::IsOpen()
  744. //DEL {
  745. //DEL    return m_bOpening;
  746. //DEL }
  747. //DEL PMYMCELL JpegFile::GetCell()
  748. //DEL {
  749. //DEL   return &m_cell;
  750. //DEL }
  751. //DEL BYTE *JpegFile::NextFrame(UINT *nBack)
  752. //DEL {
  753. //DEL  struct jpeg_decompress_struct cinfo;
  754. //DEL  /* We use our private extension JPEG error handler.
  755. //DEL  * Note that this struct must live as long as the main JPEG parameter
  756. //DEL  * struct, to avoid dangling-pointer problems.
  757. //DEL  */
  758. //DEL 
  759. //DEL  struct my_error_mgr jerr;
  760. //DEL  /* More stuff */
  761. //DEL  FILE * infile=NULL; /* source file */
  762. //DEL  // get our buffer set to hold data
  763. //DEL  BYTE * dataBuf = NULL;
  764. //DEL 
  765. //DEL  JSAMPARRAY buffer; /* Output row buffer */
  766. //DEL  int row_stride; /* physical row width in output buffer */
  767. //DEL  char buf[250];
  768. //DEL 
  769. //DEL  if (!m_bOpening) {*nBack = -1; return NULL;}
  770. //DEL  if (m_dwFrame == m_header.dwFrameSize) {*nBack = 0; return NULL;} //已到结尾
  771. //DEL     if((m_rFile.Read(&m_cell, sizeof(MYMCELL))) != sizeof(MYMCELL))
  772. //DEL  goto err01;
  773. //DEL     if(m_rFile.Read(m_lpBuffer, m_cell.lCellSize) != m_cell.lCellSize)
  774. //DEL  goto err01;
  775. //DEL 
  776. //DEL     m_dwFrame = m_cell.dwFrameNo;
  777. //DEL 
  778. //DEL  // basic code from IJG Jpeg Code v6 example.c
  779. //DEL 
  780. //DEL //DEL *width=0;
  781. //DEL //DEL *height=0;
  782. //DEL     m_lWidth = 0;
  783. //DEL  m_lHeight = 0;
  784. //DEL  /* This struct contains the JPEG decompression parameters and pointers to
  785. //DEL  * working space (which is allocated as needed by the JPEG library).
  786. //DEL  */
  787. //DEL 
  788. //DEL  /* In this example we want to open the input file before doing anything else,
  789. //DEL  * so that the setjmp() error recovery below can assume the file is open.
  790. //DEL  * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
  791. //DEL  * requires it in order to read binary files.
  792. //DEL  */
  793. //DEL 
  794. //DEL /*****DEL
  795. //DEL  if ((infile = fopen(fileName, "rb")) == NULL) {
  796. //DEL  sprintf(buf, "JPEG :nCan't open %sn", fileName);
  797. //DEL  AfxMessageBox(buf);
  798. //DEL  return NULL;
  799. //DEL  }
  800. //DEL *******/
  801. //DEL 
  802. //DEL  /* Step 1: allocate and initialize JPEG decompression object */
  803. //DEL 
  804. //DEL  /* We set up the normal JPEG error routines, then override error_exit. */
  805. //DEL  cinfo.err = jpeg_std_error(&jerr.pub);
  806. //DEL  jerr.pub.error_exit = my_error_exit;
  807. //DEL 
  808. //DEL 
  809. //DEL  /* Establish the setjmp return context for my_error_exit to use. */
  810. //DEL  if (setjmp(jerr.setjmp_buffer)) {
  811. //DEL  /* If we get here, the JPEG code has signaled an error.
  812. //DEL   * We need to clean up the JPEG object, close the input file, and return.
  813. //DEL   */
  814. //DEL 
  815. //DEL  jpeg_destroy_decompress(&cinfo);
  816. //DEL 
  817. //DEL /*******DEL
  818. //DEL  if (infile!=NULL)
  819. //DEL  fclose(infile);
  820. //DEL *********/
  821. //DEL       if (dataBuf!=NULL)
  822. //DEL       {
  823. //DEL          delete [] dataBuf;
  824. //DEL       }
  825. //DEL         *nBack = -1;
  826. //DEL  return NULL;
  827. //DEL  }
  828. //DEL 
  829. //DEL  /* Now we can initialize the JPEG decompression object. */
  830. //DEL  jpeg_create_decompress(&cinfo);
  831. //DEL  cinfo.l_size = MAX_SIZE;
  832. //DEL  cinfo.l_point = 0;
  833. //DEL  cinfo.i_stream = 1;
  834. //DEL  cinfo.buffer = m_lpBuffer;
  835. //DEL 
  836. //DEL  /* Step 2: specify data source (eg, a file) */
  837. //DEL 
  838. //DEL  jpeg_stdio_src(&cinfo, infile);
  839. //DEL 
  840. //DEL  /* Step 3: read file parameters with jpeg_read_header() */
  841. //DEL 
  842. //DEL  (void) jpeg_read_header(&cinfo, TRUE);
  843. //DEL  /* We can ignore the return value from jpeg_read_header since
  844. //DEL  *   (a) suspension is not possible with the stdio data source, and
  845. //DEL  *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
  846. //DEL  * See libjpeg.doc for more info.
  847. //DEL  */
  848. //DEL 
  849. //DEL  /* Step 4: set parameters for decompression */
  850. //DEL 
  851. //DEL  /* In this example, we don't need to change any of the defaults set by
  852. //DEL  * jpeg_read_header(), so we do nothing here.
  853. //DEL  */
  854. //DEL 
  855. //DEL  /* Step 5: Start decompressor */
  856. //DEL 
  857. //DEL  (void) jpeg_start_decompress(&cinfo);
  858. //DEL  /* We can ignore the return value since suspension is not possible
  859. //DEL  * with the stdio data source.
  860. //DEL  */
  861. //DEL 
  862. //DEL  /* We may need to do some setup of our own at this point before reading
  863. //DEL  * the data.  After jpeg_start_decompress() we have the correct scaled
  864. //DEL  * output image dimensions available, as well as the output colormap
  865. //DEL  * if we asked for color quantization.
  866. //DEL  * In this example, we need to make an output work buffer of the right size.
  867. //DEL  */ 
  868. //DEL 
  869. //DEL  ////////////////////////////////////////////////////////////
  870. //DEL  // alloc and open our new buffer
  871. //DEL  dataBuf=(BYTE *)new BYTE[cinfo.output_width * 3 * cinfo.output_height];
  872. //DEL  if (dataBuf==NULL) {
  873. //DEL 
  874. //DEL  AfxMessageBox("JpegFile :nOut of memory",MB_ICONSTOP);
  875. //DEL 
  876. //DEL  jpeg_destroy_decompress(&cinfo);
  877. //DEL 
  878. //DEL  fclose(infile);
  879. //DEL         *nBack = -1;
  880. //DEL  return NULL;
  881. //DEL  }
  882. //DEL 
  883. //DEL  // how big is this thing gonna be?
  884. //DEL //DEL *width = cinfo.output_width;
  885. //DEL //DEL *height = cinfo.output_height;
  886. //DEL  m_lWidth = cinfo.output_width;
  887. //DEL  m_lHeight = cinfo.output_height;
  888. //DEL 
  889. //DEL  /* JSAMPLEs per row in output buffer */
  890. //DEL  row_stride = cinfo.output_width * cinfo.output_components;
  891. //DEL 
  892. //DEL  /* Make a one-row-high sample array that will go away when done with image */
  893. //DEL  buffer = (*cinfo.mem->alloc_sarray)
  894. //DEL  ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
  895. //DEL 
  896. //DEL  /* Step 6: while (scan lines remain to be read) */
  897. //DEL  /*           jpeg_read_scanlines(...); */
  898. //DEL 
  899. //DEL  /* Here we use the library's state variable cinfo.output_scanline as the
  900. //DEL  * loop counter, so that we don't have to keep track ourselves.
  901. //DEL  */
  902. //DEL  while (cinfo.output_scanline < cinfo.output_height) {
  903. //DEL  /* jpeg_read_scanlines expects an array of pointers to scanlines.
  904. //DEL   * Here the array is only one element long, but you could ask for
  905. //DEL   * more than one scanline at a time if that's more convenient.
  906. //DEL   */
  907. //DEL  (void) jpeg_read_scanlines(&cinfo, buffer, 1);
  908. //DEL  /* Assume put_scanline_someplace wants a pointer and sample count. */
  909. //DEL 
  910. //DEL  // asuumer all 3-components are RGBs
  911. //DEL  if (cinfo.out_color_components==3) {
  912. //DEL 
  913. //DEL  j_putRGBScanline(buffer[0], 
  914. //DEL  m_lWidth,
  915. //DEL  dataBuf,
  916. //DEL  cinfo.output_scanline-1);
  917. //DEL 
  918. //DEL  } else if (cinfo.out_color_components==1) {
  919. //DEL 
  920. //DEL  // assume all single component images are grayscale
  921. //DEL  j_putGrayScanlineToRGB(buffer[0], 
  922. //DEL  m_lWidth,
  923. //DEL  dataBuf,
  924. //DEL  cinfo.output_scanline-1);
  925. //DEL 
  926. //DEL  }
  927. //DEL 
  928. //DEL  }
  929. //DEL 
  930. //DEL  /* Step 7: Finish decompression */
  931. //DEL 
  932. //DEL  (void) jpeg_finish_decompress(&cinfo);
  933. //DEL  /* We can ignore the return value since suspension is not possible
  934. //DEL  * with the stdio data source.
  935. //DEL  */
  936. //DEL 
  937. //DEL  /* Step 8: Release JPEG decompression object */
  938. //DEL 
  939. //DEL  /* This is an important step since it will release a good deal of memory. */
  940. //DEL  jpeg_destroy_decompress(&cinfo);
  941. //DEL 
  942. //DEL  /* After finish_decompress, we can close the input file.
  943. //DEL  * Here we postpone it until after no more JPEG errors are possible,
  944. //DEL  * so as to simplify the setjmp error logic above.  (Actually, I don't
  945. //DEL  * think that jpeg_destroy can do an error exit, but why assume anything...)
  946. //DEL  */
  947. //DEL 
  948. //DEL //DEL fclose(infile);
  949. //DEL 
  950. //DEL  /* At this point you may want to check to see whether any corrupt-data
  951. //DEL  * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
  952. //DEL  */
  953. //DEL      *nBack = 1;
  954. //DEL  return dataBuf;
  955. //DEL // return 1;
  956. //DEL 
  957. //DEL err01:
  958. //DEL  MYMClose();
  959. //DEL  *nBack = -1;
  960. //DEL  return NULL;
  961. //DEL }
  962. //DEL void JpegFile::MYMReset()
  963. //DEL {
  964. //DEL    if(!IsOpen()) return;
  965. //DEL 
  966. //DEL // m_bOpening = false;
  967. //DEL // m_lpBuffer = NULL;
  968. //DEL  m_dwPoint = 0;
  969. //DEL  m_dwFrame = 0;
  970. //DEL  m_rFile.Seek(m_header.dwSize, CFile::begin );
  971. //DEL }
  972. //DEL void JpegFile::MYMMove(DWORD dwPos)
  973. //DEL {
  974. //DEL  UINT nBack;
  975. //DEL  MYMReset();
  976. //DEL  while(true)
  977. //DEL  {
  978. //DEL //   NextFrame(&nBack);
  979. //DEL     if((m_rFile.Read(&m_cell, sizeof(MYMCELL))) != sizeof(MYMCELL))
  980. //DEL  return; //Error
  981. //DEL  if (m_cell.dwFrameNo == m_header.dwFrameSize) 
  982. //DEL  break;  //End 
  983. //DEL     if(m_cell.dwFrameNo >= dwPos) 
  984. //DEL  break;  //Found
  985. //DEL     m_rFile.Seek(m_cell.lCellSize, CFile::current); //Next
  986. //DEL  }
  987. //DEL     m_rFile.Seek(-1*m_cell.dwSize, CFile::current);
  988. //DEL }
  989. BYTE * JpegFile::LoadBMP(LPSTR lpData, unsigned long *lWidth ,unsigned long *lHeight) 
  990. {
  991.     
  992. LPBITMAPINFOHEADER lpbi; //指向位图信息头结构
  993. BYTE *outBuf=NULL;
  994. long m_bytesRead=0;
  995.     long row=0;
  996. long rowOffset=0;
  997.     long pixoff;
  998.     lpbi = (LPBITMAPINFOHEADER)lpData;
  999.         lpData += sizeof(BITMAPINFOHEADER);
  1000. //导入调色板
  1001. RGBQUAD szColormap[256];
  1002. RGBQUAD *colormap = szColormap;
  1003. switch (lpbi->biBitCount) {
  1004. case 24:
  1005. break;
  1006. // read pallete 
  1007. case 1:
  1008. case 4:
  1009. case 8:
  1010. //colormap = new RGBQUAD[lpbi->biClrUsed];
  1011. //if (colormap==NULL) return NULL;
  1012. int i;
  1013. for (i=0; i < (int)lpbi->biClrUsed;i++) {
  1014. colormap[i].rgbBlue=*(lpData+m_bytesRead);
  1015. m_bytesRead++;
  1016. colormap[i].rgbGreen=*(lpData+m_bytesRead);
  1017. m_bytesRead++;
  1018. colormap[i].rgbRed=*(lpData+m_bytesRead);
  1019. m_bytesRead++;
  1020. m_bytesRead++; //去空格
  1021. }
  1022. break;
  1023. }
  1024. int w = lpbi->biWidth;
  1025. int h = lpbi->biHeight;
  1026. *lWidth = w;
  1027. *lHeight = h;
  1028. long row_size = w * 3;
  1029. long bufsize = (long)w * 3 * (long)h;
  1030. ////////////////////////////////////////////////////////////////////////////
  1031. // alloc our buffer
  1032. DWORD dwSize = bufsize;
  1033. if (m_lpOutBuffer==NULL || m_dwOutMaxSize < dwSize) 
  1034. {
  1035.      if (m_lpOutBuffer) GlobalFree (m_lpOutBuffer);
  1036.    m_lpOutBuffer = (BYTE *)GlobalAlloc (GMEM_FIXED, dwSize);
  1037.    m_dwOutMaxSize = dwSize;
  1038.    if (m_lpOutBuffer == NULL) goto err01;
  1039. }
  1040.         outBuf = m_lpOutBuffer;
  1041. ////////////////////////////////////////////////////////////////////////////
  1042. // read it
  1043. row=0;
  1044.     rowOffset=0;
  1045.         pixoff = m_bytesRead;
  1046. // read rows in reverse order
  1047. for (row=lpbi->biHeight-1;row>=0;row--) {
  1048. // which row are we working on?
  1049. rowOffset=(long unsigned)row*row_size;       
  1050. if (lpbi->biBitCount==24) {
  1051. for (int col=0;col<w;col++) {
  1052. long offset = col * 3;
  1053. //char pixel[3];
  1054. // we swap red and blue here
  1055. *(outBuf + rowOffset + offset + 2)=*(lpData + m_bytesRead); // b
  1056. m_bytesRead++;
  1057. *(outBuf + rowOffset + offset + 1)=*(lpData + m_bytesRead); // g
  1058. m_bytesRead++;
  1059. *(outBuf + rowOffset + offset + 0)=*(lpData + m_bytesRead); // r
  1060. m_bytesRead++;
  1061. }
  1062. // read DWORD padding
  1063. while ((m_bytesRead-pixoff)&3) {
  1064. m_bytesRead++;
  1065. }
  1066.  
  1067. } else { // 1, 4, or 8 bit image
  1068. ////////////////////////////////////////////////////////////////
  1069. // pixels are packed as 1 , 4 or 8 bit vals. need to unpack them
  1070. int bit_count = 0;
  1071. UINT mask = (1 << lpbi->biBitCount) - 1;
  1072. BYTE inbyte=0;
  1073. for (int col=0;col<w;col++) {
  1074. int pix=0;
  1075. // if we need another byte
  1076. if (bit_count <= 0) {
  1077. bit_count = 8;
  1078. inbyte = *(lpData+m_bytesRead);
  1079. m_bytesRead++;
  1080. }
  1081. // keep track of where we are in the bytes
  1082. bit_count -= lpbi->biBitCount;
  1083. pix = ( inbyte >> bit_count) & mask;
  1084. // lookup the color from the colormap - stuff it in our buffer
  1085. // swap red and blue
  1086. *(outBuf + rowOffset + col * 3 + 2) = colormap[pix].rgbBlue;
  1087. *(outBuf + rowOffset + col * 3 + 1) = colormap[pix].rgbGreen;
  1088. *(outBuf + rowOffset + col * 3 + 0) = colormap[pix].rgbRed;
  1089. }
  1090. // read DWORD padding
  1091. while ((m_bytesRead-pixoff)&3) {
  1092. m_bytesRead++;
  1093. }
  1094. }
  1095. }
  1096. // if (colormap) delete [] colormap;
  1097. //BGRFromRGB(outBuf, lpbi->biWidth, lpbi->biHeight);
  1098. // vertical flip for display
  1099. //VertFlipBuf(outBuf, lpbi->biWidth * 3, lpbi->biHeight);
  1100. return outBuf;
  1101. err01:
  1102. // if (colormap) delete [] colormap;
  1103. return NULL;
  1104. }
  1105. /*
  1106. void CJpegFile::LoadBMP(CString fileName)
  1107. {
  1108. if (m_buf!=NULL) {
  1109. delete [] m_buf;
  1110. }
  1111. BMPFile theBmpFile;
  1112. m_buf=theBmpFile.LoadBMP(fileName, &m_width, &m_height);
  1113. if ((m_buf==NULL) || (theBmpFile.m_errorText!="OK")) 
  1114. {
  1115. AfxMessageBox(theBmpFile.m_errorText);
  1116. m_buf=NULL;
  1117. return;
  1118. }
  1119. //////////////////////
  1120. // set up for display
  1121. // do this before DWORD-alignment!!!
  1122. // this works on packed (not DWORD-aligned) buffers
  1123. // swap red and blue for display
  1124. m_MYM.BGRFromRGB(m_buf, m_width, m_height);
  1125. // vertical flip for display
  1126. m_MYM.VertFlipBuf(m_buf, m_width * 3, m_height);
  1127. }
  1128. void CMfcAppView::SaveJPG(CString fileName, BOOL color)
  1129. {
  1130. // note, because i'm lazy, most image data in this app
  1131. // is handled as 24-bit images. this makes the DIB
  1132. // conversion easier. 1,4,8, 15/16 and 32 bit DIBs are
  1133. // significantly more difficult to handle.
  1134. if (m_buf==NULL) {
  1135. AfxMessageBox("No Image!");
  1136. return;
  1137. }
  1138. // we vertical flip for display. undo that.
  1139. m_MYM.VertFlipBuf(m_buf, m_width * 3, m_height);
  1140. // we swap red and blue for display, undo that.
  1141. m_MYM.BGRFromRGB(m_buf, m_width, m_height);
  1142. // save RGB packed buffer to JPG
  1143. BOOL ok=m_MYM.RGBToJpegFile(inBuf,
  1144.                         size,
  1145. lWidth,
  1146. lHeight,
  1147. color, 
  1148. ); // quality value 1-100.
  1149. if (!ok) {
  1150. AfxMessageBox("Write Error");
  1151. else
  1152. {
  1153. // load what we just saved
  1154. LoadJPG(fileName);
  1155. Invalidate(TRUE);
  1156. }
  1157. }
  1158. */
  1159. void JpegFile::DeletePreData()
  1160. {
  1161.   if (m_lpPreData) GlobalFree (m_lpPreData);
  1162.   m_lpPreData = NULL;
  1163. }
  1164. #define GETBIT(p, x) ((unsigned char)p[x/8] >> (x%8) & 1)
  1165. /*
  1166. BYTE * JpegFile::FixtoBMP(unsigned char * lpInData, 
  1167.   unsigned long lWidth ,
  1168.   unsigned long lHeight, 
  1169.   unsigned char * lpHeadData,
  1170.   unsigned long lHeadSize, 
  1171.   unsigned long w, 
  1172.   unsigned long h) 
  1173. {
  1174.     
  1175. BOOL bPre = true;               //前图有效
  1176. unsigned long  hSize = (long)w*(long)h/1024;
  1177. if ((long)w*(long)h%1024)
  1178. hSize++;
  1179. if (hSize != lHeadSize) return NULL;
  1180. DWORD lInRowSize = w * 3;
  1181. DWORD lBufSize = (long)w * 3 * (long)h;
  1182. ////////////////////////////////////////////////////////////////////////////
  1183. //图象缓存
  1184. if (m_lpOutBuffer==NULL || m_dwOutMaxSize < lBufSize) 
  1185. {
  1186.      if (m_lpOutBuffer) GlobalFree (m_lpOutBuffer);
  1187.    m_lpOutBuffer = (BYTE *)GlobalAlloc (GMEM_FIXED, lBufSize);
  1188.    m_dwOutMaxSize = lBufSize;
  1189.    if (m_lpOutBuffer == NULL) return NULL;
  1190.      if (m_lpPreData) GlobalFree (m_lpPreData);
  1191.    m_lpPreData = NULL;
  1192. }
  1193. if (m_lpPreData==NULL) 
  1194. {
  1195.    m_lpPreData = (BYTE *)GlobalAlloc (GMEM_FIXED, lBufSize);
  1196.    if (m_lpPreData == NULL) return NULL;
  1197.    memset(m_lpPreData,0, lBufSize);
  1198.    bPre = false;
  1199. }
  1200.    BYTE *lpOutData = m_lpOutBuffer;
  1201.    DWORD lFullRow, row ;
  1202.    DWORD lFullRowOffset = 0, lFullPoint = 0;
  1203.    DWORD lPreRowOffset = 0, lPrePoint;
  1204.    for (lFullRow = 0; lFullRow < (long)w*(long)h/128; lFullRow++)
  1205.    {
  1206.        lPrePoint = ((lFullRow%(w/16))*16 + (lFullRow/(w/16))*w*8) * 3;
  1207.    if (bPre == false || GETBIT(lpHeadData, lFullRow))//不相同
  1208.    {
  1209.     for (row = 0 ; row < 8 ; row ++)
  1210. {
  1211.       memcpy(m_lpPreData + lPrePoint, lpInData + lFullPoint, 48);
  1212.       lPrePoint  += w * 3;
  1213.       lFullPoint += 48; //16 * 3
  1214. }//end for
  1215.    }//end if
  1216.   }//end for
  1217.  return m_lpPreData;
  1218. }
  1219. */
  1220. BYTE * JpegFile::FixtoBMP(unsigned char * lpInData, 
  1221.   unsigned long lWidth ,
  1222.   unsigned long lHeight, 
  1223.   unsigned char * lpHeadData,
  1224.   unsigned long lHeadSize, 
  1225.   unsigned long w, 
  1226.   unsigned long h) 
  1227. {
  1228. if (w % 16) return NULL;  //必需能被16整除
  1229. int hCell = h / 16;
  1230. if (hCell % 16) hCell++;
  1231. int wCell = w / 16;
  1232. int hSize = (wCell*hCell)/8;  
  1233. if ((wCell*hCell)%8)
  1234. hSize++;
  1235. if (hSize != lHeadSize) return NULL;
  1236. DWORD lBufSize = (long)w * 3 * (long)h;
  1237. ////////////////////////////////////////////////////////////////////////////
  1238. //图象缓存
  1239. /* if (m_lpOutBuffer==NULL || m_dwOutMaxSize < lBufSize) 
  1240. {
  1241.      if (m_lpOutBuffer) GlobalFree (m_lpOutBuffer);
  1242.    m_lpOutBuffer = (BYTE *)GlobalAlloc (GMEM_FIXED, lBufSize);
  1243.    m_dwOutMaxSize = lBufSize;
  1244.    if (m_lpOutBuffer == NULL) return NULL;
  1245.  //    if (m_lpPreData) GlobalFree (m_lpPreData);
  1246.  //    m_lpPreData = NULL;
  1247. }
  1248. */
  1249. if (m_lpPreData==NULL) 
  1250. {
  1251.    m_lpPreData = (BYTE *)GlobalAlloc (GMEM_FIXED, lBufSize);
  1252.    if (m_lpPreData == NULL) return NULL;
  1253.    memset(m_lpPreData,0, lBufSize);
  1254. }
  1255.    DWORD lFullRow, row ;
  1256.    DWORD lFullRowOffset = 0, lFullPoint = 0;
  1257.    DWORD lPreRowOffset = 0, lPrePoint;
  1258.    for (lFullRow = 0; lFullRow < wCell*hCell; lFullRow++)
  1259.    {
  1260. //       lPrePoint = ((lFullRow%(w/16))*16 + (lFullRow/(w/16))*w*16) * 3;
  1261.        lPrePoint = ((lFullRow%wCell) + (lFullRow/wCell)*w)*48;
  1262.    if (GETBIT(lpHeadData, lFullRow))//不相同
  1263.    {
  1264.     for (row = 0 ; row < 16 ; row ++)
  1265. {
  1266.       if (lPrePoint+1 < lBufSize)
  1267.   {
  1268.      memcpy(m_lpPreData + lPrePoint, lpInData + lFullPoint, 48);
  1269.   }
  1270.       lPrePoint  += w * 3;
  1271.       lFullPoint += 48; //16 * 3
  1272. }//end for
  1273.    }//end if
  1274.   }//end for
  1275.  return m_lpPreData;
  1276. }
  1277. #define SETBIT(p, x) ((unsigned char)p[x/8] |= (1 << (x%8)))
  1278. BYTE *JpegFile::BMPtoFix(unsigned char * lpInData, unsigned long *lWidth ,unsigned long *lHeight, 
  1279.   unsigned long *lHeadSize, unsigned long *lSize) 
  1280. {
  1281.     
  1282. LPBITMAPINFOHEADER lpbi; //指向位图信息头结构
  1283. BOOL bPre = true;               //前图有效
  1284. lpbi = (LPBITMAPINFOHEADER)lpInData;
  1285.     lpInData += sizeof(BITMAPINFOHEADER);
  1286. if (lpbi->biBitCount != 24) return NULL; //只支持真彩
  1287. int w = lpbi->biWidth;
  1288. int h = lpbi->biHeight;
  1289. if (w % 16) return NULL;  //必需能被16整除
  1290. // if (h % 8 )return NULL;   //必需能被8整除
  1291. // unsigned long  hSize = (long)w*(long)h/1024;
  1292. int hCell = h / 16;
  1293. if (hCell % 16) hCell++;
  1294. int wCell = w / 16;
  1295. int hSize = (wCell*hCell)/8;  
  1296. if ((wCell*hCell)%8)
  1297. hSize++;
  1298. // DWORD lInRowSize = w * 3;
  1299. DWORD lBufSize = wCell*hCell*768 + hSize;
  1300. ////////////////////////////////////////////////////////////////////////////
  1301. //图象缓存
  1302. if (m_lpOutBuffer==NULL || m_dwOutMaxSize < lBufSize) 
  1303. {
  1304.      if (m_lpOutBuffer) GlobalFree (m_lpOutBuffer);
  1305.    m_lpOutBuffer = (BYTE *)GlobalAlloc (GMEM_FIXED, lBufSize);
  1306.    m_dwOutMaxSize = lBufSize;
  1307.    if (m_lpOutBuffer == NULL) return NULL;
  1308. }
  1309. if (m_lpPreData==NULL) 
  1310. {
  1311.    m_lpPreData = (BYTE *)GlobalAlloc (GMEM_FIXED, lBufSize-hSize);
  1312.    if (m_lpPreData == NULL) return NULL;
  1313.    memset(m_lpPreData,0, lBufSize-hSize);
  1314.    bPre = false;
  1315. }
  1316.    memset(m_lpOutBuffer, 0, hSize);
  1317.    BYTE *lpOutData = m_lpOutBuffer + hSize;
  1318.    DWORD  lPreRow, row ;
  1319.    DWORD lOutRowOffset = 0, lPreRowOffset = 0, lPrePoint;
  1320.    DWORD lInPoint ;
  1321.    int iFound, iHeightPoint = 0;
  1322.   for (lPreRow = 0; lPreRow < wCell*hCell; lPreRow++, lPreRowOffset += 768)
  1323.    {
  1324.    iFound = 0;
  1325.        lPrePoint = lPreRowOffset;
  1326. //       lInPoint = ((lPreRow%wCell)*16 + (lPreRow/wCell)*w*16)*3;
  1327.       lInPoint = ((lPreRow%wCell) + (lPreRow/wCell)*w)*48;
  1328.    for (row = 0 ; row < 16 ; row ++)
  1329.    {
  1330. //比较
  1331. if (lInPoint+1 > lBufSize)
  1332. {
  1333.            memset(m_lpPreData + lPrePoint, 0,48); 
  1334.         }
  1335. else
  1336. {
  1337.            if (iFound == 0 && bPre == true) 
  1338.    {
  1339. //    iFound = memcmp(m_lpPreData + lPrePoint, lpInData + lInPoint, 48);
  1340. for (int i = 0 ; i < 48; i++)
  1341. {  
  1342. if (*(m_lpPreData + lPrePoint + i) != *(lpInData + lInPoint+i))
  1343. {
  1344.                iHeightPoint++;
  1345.    iFound++;
  1346.    break;
  1347. }
  1348.       
  1349. }//end for
  1350.    }//end if
  1351.            memcpy(m_lpPreData + lPrePoint, lpInData + lInPoint, 48); //保存        
  1352. }
  1353. lPrePoint += 48; //16 * 3;
  1354. lInPoint += w * 3;
  1355.    }//end for
  1356.      if (iFound == 0 && bPre == true) continue;
  1357.    SETBIT(m_lpOutBuffer, lPreRow);
  1358. //输出
  1359.    memcpy(lpOutData + lOutRowOffset, 
  1360.           m_lpPreData + lPreRowOffset, 768); //16*16*3
  1361.    lOutRowOffset += 768;
  1362.   }//end for
  1363.  *lWidth = 16;
  1364.  *lHeight = lOutRowOffset/(16*3);
  1365.  //*lHeight = iHeightPoint;
  1366.  *lHeadSize = hSize;
  1367.  *lSize = lOutRowOffset;
  1368.  return m_lpOutBuffer;
  1369. }