BOOL JpegFile::RGBToJpegFile(CString fileName, 
BYTE *dataBuf,
UINT widthPix,
UINT height,
BOOL color, 
int quality)
{
if (dataBuf==NULL)
return FALSE;
if (widthPix==0)
return FALSE;
if (height==0)
return FALSE; LPBYTE tmp;
if (!color) {
tmp = (BYTE*)new BYTE[widthPix*height];
if (tmp==NULL) {
AfxMessageBox("Memory error");
return FALSE;
} UINT row,col;
for (row=0;row<height;row++) {
for (col=0;col<widthPix;col++) {
LPBYTE pRed, pGrn, pBlu;
pRed = dataBuf + row * widthPix * 3 + col * 3;
pGrn = dataBuf + row * widthPix * 3 + col * 3 + 1;
pBlu = dataBuf + row * widthPix * 3 + col * 3 + 2; // luminance
int lum = (int)(.299 * (double)(*pRed) + .587 * (double)(*pGrn) + .114 * (double)(*pBlu));
LPBYTE pGray;
pGray = tmp + row * widthPix + col;
*pGray = (BYTE)lum;
}
}
} struct jpeg_compress_struct cinfo;
/* More stuff */
FILE * outfile=NULL; /* target file */
int row_stride; /* physical row widthPix in image buffer */ struct my_error_mgr jerr; /* Step 1: allocate and initialize JPEG compression object */
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit; /* Establish the setjmp return context for my_error_exit to use. */
if (setjmp(jerr.setjmp_buffer)) {
/* If we get here, the JPEG code has signaled an error.
 * We need to clean up the JPEG object, close the input file, and return.
 */ jpeg_destroy_compress(&cinfo); if (outfile!=NULL)
fclose(outfile); if (!color) {
delete [] tmp;
}
return FALSE;
} /* Now we can initialize the JPEG compression object. */
jpeg_create_compress(&cinfo); /* Step 2: specify data destination (eg, a file) */
/* Note: steps 2 and 3 can be done in either order. */ if ((outfile = fopen(fileName, "wb")) == NULL) {
char buf[250];
sprintf(buf, "JpegFile :\nCan't open %s\n", fileName);
AfxMessageBox(buf);
return FALSE;
} jpeg_stdio_dest(&cinfo, outfile); /* Step 3: set parameters for compression */
    
/* First we supply a description of the input image.
* Four fields of the cinfo struct must be filled in:
*/
cinfo.image_width = widthPix;  /* image widthPix and height, in pixels */
cinfo.image_height = height;
if (color) {
cinfo.input_components = 3; /* # of color components per pixel */
cinfo.in_color_space = JCS_RGB;  /* colorspace of input image */
} else {
cinfo.input_components = 1; /* # of color components per pixel */
cinfo.in_color_space = JCS_GRAYSCALE;  /* colorspace of input image */

/* Now use the library's routine to set default compression parameters.
   * (You must set at least cinfo.in_color_space before calling this,
   * since the defaults depend on the source color space.)
   */  jpeg_set_defaults(&cinfo);
  /* Now you can set any non-default parameters you wish to.
   * Here we just illustrate the use of quality (quantization table) scaling:
   */
  jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);  /* Step 4: Start compressor */  /* TRUE ensures that we will write a complete interchange-JPEG file.
   * Pass TRUE unless you are very sure of what you're doing.
   */
  jpeg_start_compress(&cinfo, TRUE);  /* Step 5: while (scan lines remain to be written) */
  /*           jpeg_write_scanlines(...); */  /* Here we use the library's state variable cinfo.next_scanline as the
   * loop counter, so that we don't have to keep track ourselves.
   * To keep things simple, we pass one scanline per call; you can pass
   * more if you wish, though.
   */
  row_stride = widthPix * 3; /* JSAMPLEs per row in image_buffer */  while (cinfo.next_scanline < cinfo.image_height) {
    /* jpeg_write_scanlines expects an array of pointers to scanlines.
     * Here the array is only one element long, but you could pass
     * more than one scanline at a time if that's more convenient.
     */
LPBYTE outRow;
if (color) {
outRow = dataBuf + (cinfo.next_scanline * widthPix * 3);
} else {
outRow = tmp + (cinfo.next_scanline * widthPix);
}    (void) jpeg_write_scanlines(&cinfo, &outRow, 1);
  }  /* Step 6: Finish compression */  jpeg_finish_compress(&cinfo);  /* After finish_compress, we can close the output file. */
  fclose(outfile);  /* Step 7: release JPEG compression object */  /* This is an important step since it will release a good deal of memory. */
  jpeg_destroy_compress(&cinfo);  if (!color)
  delete [] tmp;
  /* And we're done! */  return TRUE;
}