📄 jpegfile3.cpp
字号:
cinfo.l_size = *size;
cinfo.l_point = 0;
cinfo.i_stream = 1;
cinfo.buffer = (unsigned char *)outBuf;
/* Step 2: specify data destination (eg, a file) */
/* Note: steps 2 and 3 can be done in either order. */
/*
if ((outfile = fopen("c:\\111.jpg", "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);
*size = cinfo.l_point;
/* After finish_compress, we can close the output file. */
//DEL fclose(outfile);
/* Step 7: release JPEG compression object */
/* This is an important step since it will release a good deal of memory. */
if (cinfo.l_point > cinfo.l_size)
b_return = false;
jpeg_destroy_compress(&cinfo);
// fclose(outfile);
if (!color) delete [] tmp;
/* And we're done! */
return b_return;
err01:
return false;
// return TRUE;
}
//
// stash a scanline
//
void j_putRGBScanline(BYTE *jpegline,
int widthPix,
BYTE *outBuf,
int row)
{
int offset = row * widthPix * 3;
int count;
for (count=0;count<widthPix;count++)
{
*(outBuf + offset + count * 3 + 0) = *(jpegline + count * 3 + 0);
*(outBuf + offset + count * 3 + 1) = *(jpegline + count * 3 + 1);
*(outBuf + offset + count * 3 + 2) = *(jpegline + count * 3 + 2);
}
}
//
// stash a gray scanline
//
void j_putGrayScanlineToRGB(BYTE *jpegline,
int widthPix,
BYTE *outBuf,
int row)
{
int offset = row * widthPix * 3;
int count;
for (count=0;count<widthPix;count++) {
BYTE iGray;
// get our grayscale value
iGray = *(jpegline + count);
*(outBuf + offset + count * 3 + 0) = iGray;
*(outBuf + offset + count * 3 + 1) = iGray;
*(outBuf + offset + count * 3 + 2) = iGray;
}
}
//
// copies BYTE buffer into DWORD-aligned BYTE buffer
// return addr of new buffer
//
BYTE * JpegFile::MovetoBuf(BYTE *dataBuf,
CRect *prcRect, // pixels!!
UINT widthNew,
UINT heightNew) // bytes!!!
{
////////////////////////////////////////////////////////////
// what's going on here? this certainly means trouble
if (dataBuf==NULL)
return NULL;
////////////////////////////////////////////////////////////
// how big is the smallest DWORD-aligned buffer that we can use?
UINT uiWidthBytes, uiWidthBytesNew;
uiWidthBytes = WIDTHBYTES(prcRect->Width() * 24);
uiWidthBytes = 3 * prcRect->Width();
uiWidthBytesNew = 3 * widthNew;
DWORD dwNewsize=(DWORD)((DWORD)uiWidthBytesNew *
(DWORD)heightNew);
BYTE *pNew;
////////////////////////////////////////////////////////////
// alloc and open our new buffer
pNew=(BYTE *)new BYTE[dwNewsize];
if (pNew==NULL) {
return NULL;
}
UINT row,col;
memset(pNew, 0,dwNewsize);
for (row=0;(int)row<prcRect->Height();row++) {
for (col=0;(int)col<prcRect->Width();col++) {
BYTE pRed, pGrn, pBlu;
pRed = dataBuf[row * prcRect->Width() * 3 + col * 3];
pGrn = dataBuf[row * prcRect->Width() * 3 + col * 3+1];
pBlu = dataBuf[row * prcRect->Width() * 3 + col * 3+2];
pNew[(heightNew - prcRect->bottom + row) * widthNew * 3 + (col+prcRect->left) * 3] = (BYTE)pRed;
pNew[(heightNew - prcRect->bottom + row) * widthNew * 3 + (col+prcRect->left) * 3+1] = (BYTE)pGrn;
pNew[(heightNew - prcRect->bottom + row) * widthNew * 3 + (col+prcRect->left) * 3+2] = (BYTE)pBlu;
}
}
return pNew;
}
//
// copies BYTE buffer into DWORD-aligned BYTE buffer
// return addr of new buffer
//
BYTE * JpegFile::MakeDwordAlignedBuf(BYTE *dataBuf,
UINT widthPix, // pixels!!
UINT height,
UINT *uiOutWidthBytes) // bytes!!!
{
////////////////////////////////////////////////////////////
// what's going on here? this certainly means trouble
if (dataBuf==NULL)
return NULL;
////////////////////////////////////////////////////////////
// how big is the smallest DWORD-aligned buffer that we can use?
UINT uiWidthBytes;
uiWidthBytes = WIDTHBYTES(widthPix * 24);
DWORD dwNewsize=(DWORD)((DWORD)uiWidthBytes *
(DWORD)height);
BYTE *pNew;
////////////////////////////////////////////////////////////
// alloc and open our new buffer
/* pNew=(BYTE *)new BYTE[dwNewsize];
if (pNew==NULL) {
return NULL;
}
*/
if (m_lpScreenBuffer==NULL || m_dwScreenMaxSize < dwNewsize)
{
if (m_lpScreenBuffer) GlobalFree (m_lpScreenBuffer);
m_lpScreenBuffer = (BYTE *)GlobalAlloc (GMEM_FIXED, dwNewsize);
m_dwScreenMaxSize = dwNewsize;
if (m_lpScreenBuffer == NULL) return NULL;
}
pNew = m_lpScreenBuffer;
////////////////////////////////////////////////////////////
// copy row-by-row
UINT uiInWidthBytes = widthPix * 3;
UINT uiCount;
for (uiCount=0;uiCount < height;uiCount++) {
BYTE * bpInAdd;
BYTE * bpOutAdd;
ULONG lInOff;
ULONG lOutOff;
lInOff=uiInWidthBytes * uiCount;
lOutOff=uiWidthBytes * uiCount;
bpInAdd= dataBuf + lInOff;
bpOutAdd= pNew + lOutOff;
memcpy(bpOutAdd,bpInAdd,uiInWidthBytes);
}
*uiOutWidthBytes=uiWidthBytes;
return pNew;
}
//
// vertically flip a buffer
// note, this operates on a buffer of widthBytes bytes, not pixels!!!
//
BOOL JpegFile::VertFlipBuf(BYTE * inbuf,
UINT widthBytes,
UINT height)
{
BYTE *tb1;
BYTE *tb2;
if (inbuf==NULL)
return FALSE;
UINT bufsize;
bufsize=widthBytes;
tb1= (BYTE *)new BYTE[bufsize];
if (tb1==NULL) {
return FALSE;
}
tb2= (BYTE *)new BYTE [bufsize];
if (tb2==NULL) {
delete [] tb1;
return FALSE;
}
UINT row_cnt;
ULONG off1=0;
ULONG off2=0;
for (row_cnt=0;row_cnt<(height+1)/2;row_cnt++) {
off1=row_cnt*bufsize;
off2=((height-1)-row_cnt)*bufsize;
memcpy(tb1,inbuf+off1,bufsize);
memcpy(tb2,inbuf+off2,bufsize);
memcpy(inbuf+off1,tb2,bufsize);
memcpy(inbuf+off2,tb1,bufsize);
}
delete [] tb1;
delete [] tb2;
return TRUE;
}
//
// swap Rs and Bs
//
// Note! this does its stuff on buffers with a whole number of pixels
// per data row!!
//
BOOL JpegFile::BGRFromRGB(BYTE *buf, UINT widthPix, UINT height)
{
if (buf==NULL)
return FALSE;
UINT col, row;
for (row=0;row<height;row++) {
for (col=0;col<widthPix;col++) {
LPBYTE pRed, pGrn, pBlu;
pRed = buf + row * widthPix * 3 + col * 3;
pGrn = buf + row * widthPix * 3 + col * 3 + 1;
pBlu = buf + row * widthPix * 3 + col * 3 + 2;
// swap red and blue
BYTE tmp;
tmp = *pRed;
*pRed = *pBlu;
*pBlu = tmp;
}
}
return TRUE;
}
//
// Note! this does its stuff on buffers with a whole number of pixels
// per data row!!
//
BOOL JpegFile::MakeGrayScale(BYTE *buf, UINT widthPix, UINT height, BOOL trun)
{
if (buf==NULL)
return FALSE;
UINT row,col;
for (row=0;row<height;row++) {
for (col=0;col<widthPix;col++) {
LPBYTE pRed, pGrn, pBlu;
pRed = buf + row * widthPix * 3 + col * 3;
pGrn = buf + row * widthPix * 3 + col * 3 + 1;
pBlu = buf + row * widthPix * 3 + col * 3 + 2;
// luminance
int lum = (int)(.299 * (double)(*pRed) + .587 * (double)(*pGrn) + .114 * (double)(*pBlu));
if (trun) lum = ~lum;
*pRed = (BYTE)lum;
*pGrn = (BYTE)lum;
*pBlu = (BYTE)lum;
}
}
return TRUE;
}
//DEL bool JpegFile::MYMOpen(CString sFile)
//DEL {
//DEL CFileException e;
//DEL MYMClose();
//DEL m_lpBuffer = new BYTE[MAX_SIZE];
//DEL if (m_lpBuffer == NULL) return false;
//DEL
//DEL if(!m_rFile.Open(sFile,CFile::typeBinary|CFile::modeRead,&e)) return false;
//DEL if(!m_rFile.Read(&m_header, sizeof(MYMHEADER))) goto err01;
//DEL if (memcmp(m_header.szNote, "MYMEDIA", 7) || memcmp(m_header.szVersion,"VERSION1.0", 10 ))
//DEL return false;
//DEL
//DEL m_bOpening = true;
//DEL m_dwPoint = 0;
//DEL m_dwFrame = 0;
//DEL return true;
//DEL
//DEL err01:
//DEL m_rFile.Close();
//DEL return false;
//DEL }
//DEL void JpegFile::MYMClose()
//DEL {
//DEL if(m_bOpening)
//DEL m_rFile.Close();
//DEL m_bOpening = false;
//DEL if(m_lpBuffer) delete m_lpBuffer;
//DEL m_lpBuffer = NULL;
//DEL m_dwPoint = 0;
//DEL m_dwFrame = 0;
//DEL
//DEL }
//DEL bool JpegFile::IsOpen()
//DEL {
//DEL return m_bOpening;
//DEL }
//DEL PMYMCELL JpegFile::GetCell()
//DEL {
//DEL return &m_cell;
//DEL }
//DEL BYTE *JpegFile::NextFrame(UINT *nBack)
//DEL {
//DEL struct jpeg_decompress_struct cinfo;
//DEL /* We use our private extension JPEG error handler.
//DEL * Note that this struct must live as long as the main JPEG parameter
//DEL * struct, to avoid dangling-pointer problems.
//DEL */
//DEL
//DEL struct my_error_mgr jerr;
//DEL /* More stuff */
//DEL FILE * infile=NULL; /* source file */
//DEL // get our buffer set to hold data
//DEL BYTE * dataBuf = NULL;
//DEL
//DEL JSAMPARRAY buffer; /* Output row buffer */
//DEL int row_stride; /* physical row width in output buffer */
//DEL char buf[250];
//DEL
//DEL if (!m_bOpening) {*nBack = -1; return NULL;}
//DEL if (m_dwFrame == m_header.dwFrameSize) {*nBack = 0; return NULL;} //已到结尾
//DEL if((m_rFile.Read(&m_cell, sizeof(MYMCELL))) != sizeof(MYMCELL))
//DEL goto err01;
//DEL if(m_rFile.Read(m_lpBuffer, m_cell.lCellSize) != m_cell.lCellSize)
//DEL goto err01;
//DEL
//DEL m_dwFrame = m_cell.dwFrameNo;
//DEL
//DEL // basic code from IJG Jpeg Code v6 example.c
//DEL
//DEL //DEL *width=0;
//DEL //DEL *height=0;
//DEL m_lWidth = 0;
//DEL m_lHeight = 0;
//DEL /* This struct contains the JPEG decompression parameters and pointers to
//DEL * working space (which is allocated as needed by the JPEG library).
//DEL */
//DEL
//DEL /* In this example we want to open the input file before doing anything else,
//DEL * so that the setjmp() error recovery below can assume the file is open.
//DEL * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
//DEL * requires it in order to read binary files.
//DEL */
//DEL
//DEL /*****DEL
//DEL if ((infile = fopen(fileName, "rb")) == NULL) {
//DEL sprintf(buf, "JPEG :\nCan't open %s\n", fileName);
//DEL AfxMessageBox(buf);
//DEL return NULL;
//DEL }
//DEL *******/
//DEL
//DEL /* Step 1: allocate and initialize JPEG decompression object */
//DEL
//DEL /* We set up the normal JPEG error routines, then override error_exit. */
//DEL cinfo.err = jpeg_std_error(&jerr.pub);
//DEL jerr.pub.error_exit = my_error_exit;
//DEL
//DEL
//DEL /* Establish the setjmp return context for my_error_exit to use. */
//DEL if (setjmp(jerr.setjmp_buffer)) {
//DEL /* If we get here, the JPEG code has signaled an error.
//DEL * We need to clean up the JPEG object, close the input file, and return.
//DEL */
//DEL
//DEL jpeg_destroy_decompress(&cinfo);
//DEL
//DEL /*******DEL
//DEL if (infile!=NULL)
//DEL fclose(infile);
//DEL *********/
//DEL if (dataBuf!=NULL)
//DEL {
//DEL delete [] dataBuf;
//DEL }
//DEL *nBack = -1;
//DEL return NULL;
//DEL }
//DEL
//DEL /* Now we can initialize the JPEG decompression object. */
//DEL jpeg_create_decompress(&cinfo);
//DEL cinfo.l_size = MAX_SIZE;
//DEL cinfo.l_point = 0;
//DEL cinfo.i_stream = 1;
//DEL cinfo.buffer = m_lpBuffer;
//DEL
//DEL /* Step 2: specify data source (eg, a file) */
//DEL
//DEL jpeg_stdio_src(&cinfo, infile);
//DEL
//DEL /* Step 3: read file parameters with jpeg_read_header() */
//DEL
//DEL (void) jpeg_read_header(&cinfo, TRUE);
//DEL /* We can ignore the return value from jpeg_read_header since
//DEL * (a) suspension is not possible with the stdio data source, and
//DEL * (b) we passed TRUE to reject a tables-only JPEG file as an error.
//DEL * See libjpeg.doc for more info.
//DEL */
//DEL
//DEL /* Step 4: set parameters for decompression */
//DEL
//DEL /* In this example, we don't need to change any of the defaults set by
//DEL * jpeg_read_header(), so we do nothing here.
//DEL */
//DEL
//DEL /* Step 5: Start decompressor */
//DEL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -