📄 jpegfile3.cpp
字号:
//DEL (void) jpeg_start_decompress(&cinfo);
//DEL /* We can ignore the return value since suspension is not possible
//DEL * with the stdio data source.
//DEL */
//DEL
//DEL /* We may need to do some setup of our own at this point before reading
//DEL * the data. After jpeg_start_decompress() we have the correct scaled
//DEL * output image dimensions available, as well as the output colormap
//DEL * if we asked for color quantization.
//DEL * In this example, we need to make an output work buffer of the right size.
//DEL */
//DEL
//DEL ////////////////////////////////////////////////////////////
//DEL // alloc and open our new buffer
//DEL dataBuf=(BYTE *)new BYTE[cinfo.output_width * 3 * cinfo.output_height];
//DEL if (dataBuf==NULL) {
//DEL
//DEL AfxMessageBox("JpegFile :\nOut of memory",MB_ICONSTOP);
//DEL
//DEL jpeg_destroy_decompress(&cinfo);
//DEL
//DEL fclose(infile);
//DEL *nBack = -1;
//DEL return NULL;
//DEL }
//DEL
//DEL // how big is this thing gonna be?
//DEL //DEL *width = cinfo.output_width;
//DEL //DEL *height = cinfo.output_height;
//DEL m_lWidth = cinfo.output_width;
//DEL m_lHeight = cinfo.output_height;
//DEL
//DEL /* JSAMPLEs per row in output buffer */
//DEL row_stride = cinfo.output_width * cinfo.output_components;
//DEL
//DEL /* Make a one-row-high sample array that will go away when done with image */
//DEL buffer = (*cinfo.mem->alloc_sarray)
//DEL ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
//DEL
//DEL /* Step 6: while (scan lines remain to be read) */
//DEL /* jpeg_read_scanlines(...); */
//DEL
//DEL /* Here we use the library's state variable cinfo.output_scanline as the
//DEL * loop counter, so that we don't have to keep track ourselves.
//DEL */
//DEL while (cinfo.output_scanline < cinfo.output_height) {
//DEL /* jpeg_read_scanlines expects an array of pointers to scanlines.
//DEL * Here the array is only one element long, but you could ask for
//DEL * more than one scanline at a time if that's more convenient.
//DEL */
//DEL (void) jpeg_read_scanlines(&cinfo, buffer, 1);
//DEL /* Assume put_scanline_someplace wants a pointer and sample count. */
//DEL
//DEL // asuumer all 3-components are RGBs
//DEL if (cinfo.out_color_components==3) {
//DEL
//DEL j_putRGBScanline(buffer[0],
//DEL m_lWidth,
//DEL dataBuf,
//DEL cinfo.output_scanline-1);
//DEL
//DEL } else if (cinfo.out_color_components==1) {
//DEL
//DEL // assume all single component images are grayscale
//DEL j_putGrayScanlineToRGB(buffer[0],
//DEL m_lWidth,
//DEL dataBuf,
//DEL cinfo.output_scanline-1);
//DEL
//DEL }
//DEL
//DEL }
//DEL
//DEL /* Step 7: Finish decompression */
//DEL
//DEL (void) jpeg_finish_decompress(&cinfo);
//DEL /* We can ignore the return value since suspension is not possible
//DEL * with the stdio data source.
//DEL */
//DEL
//DEL /* Step 8: Release JPEG decompression object */
//DEL
//DEL /* This is an important step since it will release a good deal of memory. */
//DEL jpeg_destroy_decompress(&cinfo);
//DEL
//DEL /* After finish_decompress, we can close the input file.
//DEL * Here we postpone it until after no more JPEG errors are possible,
//DEL * so as to simplify the setjmp error logic above. (Actually, I don't
//DEL * think that jpeg_destroy can do an error exit, but why assume anything...)
//DEL */
//DEL
//DEL //DEL fclose(infile);
//DEL
//DEL /* At this point you may want to check to see whether any corrupt-data
//DEL * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
//DEL */
//DEL *nBack = 1;
//DEL return dataBuf;
//DEL // return 1;
//DEL
//DEL err01:
//DEL MYMClose();
//DEL *nBack = -1;
//DEL return NULL;
//DEL }
//DEL void JpegFile::MYMReset()
//DEL {
//DEL if(!IsOpen()) return;
//DEL
//DEL // m_bOpening = false;
//DEL // m_lpBuffer = NULL;
//DEL m_dwPoint = 0;
//DEL m_dwFrame = 0;
//DEL m_rFile.Seek(m_header.dwSize, CFile::begin );
//DEL }
//DEL void JpegFile::MYMMove(DWORD dwPos)
//DEL {
//DEL UINT nBack;
//DEL MYMReset();
//DEL while(true)
//DEL {
//DEL // NextFrame(&nBack);
//DEL if((m_rFile.Read(&m_cell, sizeof(MYMCELL))) != sizeof(MYMCELL))
//DEL return; //Error
//DEL if (m_cell.dwFrameNo == m_header.dwFrameSize)
//DEL break; //End
//DEL if(m_cell.dwFrameNo >= dwPos)
//DEL break; //Found
//DEL m_rFile.Seek(m_cell.lCellSize, CFile::current); //Next
//DEL }
//DEL m_rFile.Seek(-1*m_cell.dwSize, CFile::current);
//DEL }
BYTE * JpegFile::LoadBMP(LPSTR lpData, unsigned long *lWidth ,unsigned long *lHeight)
{
LPBITMAPINFOHEADER lpbi; //指向位图信息头结构
BYTE *outBuf=NULL;
long m_bytesRead=0;
long row=0;
long rowOffset=0;
long pixoff;
lpbi = (LPBITMAPINFOHEADER)lpData;
lpData += sizeof(BITMAPINFOHEADER);
//导入调色板
RGBQUAD szColormap[256];
RGBQUAD *colormap = szColormap;
switch (lpbi->biBitCount) {
case 24:
break;
// read pallete
case 1:
case 4:
case 8:
//colormap = new RGBQUAD[lpbi->biClrUsed];
//if (colormap==NULL) return NULL;
int i;
for (i=0; i < (int)lpbi->biClrUsed;i++) {
colormap[i].rgbBlue=*(lpData+m_bytesRead);
m_bytesRead++;
colormap[i].rgbGreen=*(lpData+m_bytesRead);
m_bytesRead++;
colormap[i].rgbRed=*(lpData+m_bytesRead);
m_bytesRead++;
m_bytesRead++; //去空格
}
break;
}
int w = lpbi->biWidth;
int h = lpbi->biHeight;
*lWidth = w;
*lHeight = h;
long row_size = w * 3;
long bufsize = (long)w * 3 * (long)h;
////////////////////////////////////////////////////////////////////////////
// alloc our buffer
DWORD dwSize = bufsize;
if (m_lpOutBuffer==NULL || m_dwOutMaxSize < dwSize)
{
if (m_lpOutBuffer) GlobalFree (m_lpOutBuffer);
m_lpOutBuffer = (BYTE *)GlobalAlloc (GMEM_FIXED, dwSize);
m_dwOutMaxSize = dwSize;
if (m_lpOutBuffer == NULL) goto err01;
}
outBuf = m_lpOutBuffer;
////////////////////////////////////////////////////////////////////////////
// read it
row=0;
rowOffset=0;
pixoff = m_bytesRead;
// read rows in reverse order
for (row=lpbi->biHeight-1;row>=0;row--) {
// which row are we working on?
rowOffset=(long unsigned)row*row_size;
if (lpbi->biBitCount==24) {
for (int col=0;col<w;col++) {
long offset = col * 3;
//char pixel[3];
// we swap red and blue here
*(outBuf + rowOffset + offset + 2)=*(lpData + m_bytesRead); // b
m_bytesRead++;
*(outBuf + rowOffset + offset + 1)=*(lpData + m_bytesRead); // g
m_bytesRead++;
*(outBuf + rowOffset + offset + 0)=*(lpData + m_bytesRead); // r
m_bytesRead++;
}
// read DWORD padding
while ((m_bytesRead-pixoff)&3) {
m_bytesRead++;
}
} else { // 1, 4, or 8 bit image
////////////////////////////////////////////////////////////////
// pixels are packed as 1 , 4 or 8 bit vals. need to unpack them
int bit_count = 0;
UINT mask = (1 << lpbi->biBitCount) - 1;
BYTE inbyte=0;
for (int col=0;col<w;col++) {
int pix=0;
// if we need another byte
if (bit_count <= 0) {
bit_count = 8;
inbyte = *(lpData+m_bytesRead);
m_bytesRead++;
}
// keep track of where we are in the bytes
bit_count -= lpbi->biBitCount;
pix = ( inbyte >> bit_count) & mask;
// lookup the color from the colormap - stuff it in our buffer
// swap red and blue
*(outBuf + rowOffset + col * 3 + 2) = colormap[pix].rgbBlue;
*(outBuf + rowOffset + col * 3 + 1) = colormap[pix].rgbGreen;
*(outBuf + rowOffset + col * 3 + 0) = colormap[pix].rgbRed;
}
// read DWORD padding
while ((m_bytesRead-pixoff)&3) {
m_bytesRead++;
}
}
}
// if (colormap) delete [] colormap;
//BGRFromRGB(outBuf, lpbi->biWidth, lpbi->biHeight);
// vertical flip for display
//VertFlipBuf(outBuf, lpbi->biWidth * 3, lpbi->biHeight);
return outBuf;
err01:
// if (colormap) delete [] colormap;
return NULL;
}
/*
void CJpegFile::LoadBMP(CString fileName)
{
if (m_buf!=NULL) {
delete [] m_buf;
}
BMPFile theBmpFile;
m_buf=theBmpFile.LoadBMP(fileName, &m_width, &m_height);
if ((m_buf==NULL) || (theBmpFile.m_errorText!="OK"))
{
AfxMessageBox(theBmpFile.m_errorText);
m_buf=NULL;
return;
}
//////////////////////
// set up for display
// do this before DWORD-alignment!!!
// this works on packed (not DWORD-aligned) buffers
// swap red and blue for display
m_MYM.BGRFromRGB(m_buf, m_width, m_height);
// vertical flip for display
m_MYM.VertFlipBuf(m_buf, m_width * 3, m_height);
}
void CMfcAppView::SaveJPG(CString fileName, BOOL color)
{
// note, because i'm lazy, most image data in this app
// is handled as 24-bit images. this makes the DIB
// conversion easier. 1,4,8, 15/16 and 32 bit DIBs are
// significantly more difficult to handle.
if (m_buf==NULL) {
AfxMessageBox("No Image!");
return;
}
// we vertical flip for display. undo that.
m_MYM.VertFlipBuf(m_buf, m_width * 3, m_height);
// we swap red and blue for display, undo that.
m_MYM.BGRFromRGB(m_buf, m_width, m_height);
// save RGB packed buffer to JPG
BOOL ok=m_MYM.RGBToJpegFile(inBuf,
size,
lWidth,
lHeight,
color,
); // quality value 1-100.
if (!ok) {
AfxMessageBox("Write Error");
}
else
{
// load what we just saved
LoadJPG(fileName);
Invalidate(TRUE);
}
}
*/
void JpegFile::DeletePreData()
{
if (m_lpPreData) GlobalFree (m_lpPreData);
m_lpPreData = NULL;
}
#define GETBIT(p, x) (p[x/8] &= (1 << (x%8)))
BYTE * JpegFile::FixtoBMP(unsigned char * lpInData,
unsigned long lWidth ,
unsigned long lHeight,
unsigned char * lpHeadData,
unsigned long lHeadSize,
unsigned long w,
unsigned long h)
{
// LPBITMAPINFOHEADER lpbi; //指向位图信息头结构
BOOL bPre = true; //前图有效
// lpbi = (LPBITMAPINFOHEADER)lpInData;
// lpInData += sizeof(BITMAPINFOHEADER);
// if (lpbi->biBitCount != 24) return NULL; //只支持真彩
// int w = lpbi->biWidth;
// int h = lpbi->biHeight;
int hSize = (long)w*(long)h/512+1;
if (hSize != lHeadSize) return NULL;
long lInRowSize = w * 3;
long lBufSize = (long)w * 3 * (long)h;
////////////////////////////////////////////////////////////////////////////
//图象缓存
if (m_lpOutBuffer==NULL || m_dwOutMaxSize < lBufSize)
{
if (m_lpOutBuffer) GlobalFree (m_lpOutBuffer);
m_lpOutBuffer = (BYTE *)GlobalAlloc (GMEM_FIXED, lBufSize);
m_dwOutMaxSize = lBufSize;
if (m_lpOutBuffer == NULL) return NULL;
if (m_lpPreData) GlobalFree (m_lpPreData);
m_lpPreData = NULL;
}
if (m_lpPreData==NULL)
{
m_lpPreData = (BYTE *)GlobalAlloc (GMEM_FIXED, lBufSize);
if (m_lpPreData == NULL) return NULL;
memset(m_lpPreData,0, lBufSize);
bPre = false;
}
BYTE *lpOutData = m_lpOutBuffer;
long lFullRow, row , col;
long /*lInRowOffset = 0,*/ lFullRowOffset = 0, lFullPoint;
long lPreRowOffset = 0, lPrePoint;
int iData1, iData2, iData3 ;
int i ;
for (lFullRow = 0; lFullRow < w * h / 64; lFullRow++)
{
// lFullRowOffset = lFullRow * 64 * 3;
// lPreRowOffset = ((lFullRow%(w/8))*8 + (lFullRow/(w/8))*w*8) * 3;
lFullPoint = lFullRow * 64 * 3;
lPrePoint = ((lFullRow%(w/8))*8 + (lFullRow/(w/8))*w*8) * 3;
i = GETBIT(lpHeadData, lFullRow);
if (bPre == false || i)//不相同
{
for (row = 0 ; row < 8 ; row ++)
{
/* lPrePoint = lPreRowOffset + row * 3 * w;
lFullPoint =lFullRowOffset + row * 8 * 3;
*/
for(col = 0 ; col < 8; col ++)
{
iData1 = *(lpInData + lFullPoint /*lFullRowOffset + row * 8 * 3 */+ 3 * col);
iData2 = *(lpInData + lFullPoint /*lFullRowOffset + row * 8 * 3 */+ 3 * col + 1);
iData3 = *(lpInData + lFullPoint /*lFullRowOffset + row * 8 * 3*/ + 3 * col+2);
*(m_lpPreData + lPrePoint + 3 * col) = iData1;
*(m_lpPreData + lPrePoint + 3 * col + 1) = iData2;
*(m_lpPreData + lPrePoint + 3 * col + 2) = iData3;
}//end for
lPrePoint += w * 3;
lFullPoint += 8 * 3;
}//end for
//lInRowOffset += 64 * 3;
}//end if
}//end for
return m_lpPreData;
}
#define SETBIT(p, x) (p[x/8] |= (1 << (x%8)))
BYTE *JpegFile::BMPtoFix(unsigned char * lpInData, unsigned long *lWidth ,unsigned long *lHeight,
unsigned long *lHeadSize, unsigned long *lSize)
{
LPBITMAPINFOHEADER lpbi; //指向位图信息头结构
BOOL bPre = true; //前图有效
lpbi = (LPBITMAPINFOHEADER)lpInData;
lpInData += sizeof(BITMAPINFOHEADER);
if (lpbi->biBitCount != 24) return NULL; //只支持真彩
int w = lpbi->biWidth;
int h = lpbi->biHeight;
int hSize = (long)w*(long)h/512+1;
long lInRowSize = w * 3;
long lBufSize = (long)w * 3 * (long)h + hSize;
////////////////////////////////////////////////////////////////////////////
//图象缓存
if (m_lpOutBuffer==NULL || m_dwOutMaxSize < lBufSize)
{
if (m_lpOutBuffer) GlobalFree (m_lpOutBuffer);
m_lpOutBuffer = (BYTE *)GlobalAlloc (GMEM_FIXED, lBufSize);
m_dwOutMaxSize = lBufSize;
if (m_lpOutBuffer == NULL) return NULL;
//if (m_lpPreData) GlobalFree (m_lpPreData);
//m_lpPreData = NULL;
}
if (m_lpPreData==NULL)
{
m_lpPreData = (BYTE *)GlobalAlloc (GMEM_FIXED, lBufSize-hSize);
if (m_lpPreData == NULL) return NULL;
memset(m_lpPreData,0, lBufSize-hSize);
bPre = false;
}
memset(m_lpOutBuffer, 0, hSize);
BYTE *lpOutData = m_lpOutBuffer + hSize;
long lOutRow, lPreRow, row , col;
long lOutRowOffset = 0, lPreRowOffset = 0, lPrePoint;
long /*lInRowOffset = 0,*/ lInPoint ;
int iData1, iData2, iData3 ;
BOOL bFound ;
for (lPreRow = 0; lPreRow < w * h / 64; lPreRow++, lPreRowOffset += 192)
{
bFound = FALSE;
// lPreRowOffset = lPreRow * 64 * 3;
// lInRowOffset = ((lPreRow%(w/8))*8 + (lPreRow/(w/8))*w*8)*3;
lPrePoint = lPreRowOffset;
lInPoint = ((lPreRow%(w/8))*8 + (lPreRow/(w/8))*w*8)*3;
for (row = 0 ; row < 8 ; row ++)
{
// lInPoint = lInRowOffset + row * w * 3;
for(col = 0 ; col < 8; col ++)
{
iData1 = *(lpInData + lInPoint + 3*col);
iData2 = *(lpInData + lInPoint + 3*col + 1);
iData3 = *(lpInData + lInPoint + 3*col + 2);
if(bPre == TRUE && bFound == FALSE )
{
if (iData1 != *(m_lpPreData + lPrePoint/*lPreRowOffset + row * 8 * 3*/ + 3*col))
{
SETBIT(m_lpOutBuffer, lPreRow);
bFound = TRUE;
}
else if(iData2 != *(m_lpPreData + lPrePoint/* lPreRowOffset + row * 8 * 3*/ + 3*col + 1))
{
SETBIT(m_lpOutBuffer, lPreRow);
bFound = TRUE;
}
else if(iData3 != *(m_lpPreData + lPrePoint/*lPreRowOffset + row * 8 * 3*/ + 3*col+2))
{
SETBIT(m_lpOutBuffer, lPreRow);
bFound = TRUE;
}
}//end if
//保存
*(m_lpPreData + lPrePoint/*lPreRowOffset + row * 8 * 3*/+ 3*col) = iData1;
*(m_lpPreData + lPrePoint/*lPreRowOffset + row * 8 * 3*/+ 3*col+1) = iData2;
*(m_lpPreData + lPrePoint/*lPreRowOffset + row * 8 * 3*/+ 3*col+2) = iData3;
}//end for
lPrePoint += 8 * 3;
lInPoint += w * 3;
}//end for
if (bFound == FALSE && bPre == true) continue;
//输出
memcpy(lpOutData + lOutRowOffset,
m_lpPreData + lPreRowOffset, 64*3);
lOutRowOffset += 64*3;
}//end for
*lWidth = 8;
*lHeight = lOutRowOffset/(8*3);
*lHeadSize = hSize;
*lSize = lOutRowOffset;
return m_lpOutBuffer;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -