📄 jpegfile.cpp
字号:
//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) ((unsigned char)p[x/8] >> (x%8) & 1)
/*
BYTE * JpegFile::FixtoBMP(unsigned char * lpInData,
unsigned long lWidth ,
unsigned long lHeight,
unsigned char * lpHeadData,
unsigned long lHeadSize,
unsigned long w,
unsigned long h)
{
BOOL bPre = true; //前图有效
unsigned long hSize = (long)w*(long)h/1024;
if ((long)w*(long)h%1024)
hSize++;
if (hSize != lHeadSize) return NULL;
DWORD lInRowSize = w * 3;
DWORD 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;
DWORD lFullRow, row ;
DWORD lFullRowOffset = 0, lFullPoint = 0;
DWORD lPreRowOffset = 0, lPrePoint;
for (lFullRow = 0; lFullRow < (long)w*(long)h/128; lFullRow++)
{
lPrePoint = ((lFullRow%(w/16))*16 + (lFullRow/(w/16))*w*8) * 3;
if (bPre == false || GETBIT(lpHeadData, lFullRow))//不相同
{
for (row = 0 ; row < 8 ; row ++)
{
memcpy(m_lpPreData + lPrePoint, lpInData + lFullPoint, 48);
lPrePoint += w * 3;
lFullPoint += 48; //16 * 3
}//end for
}//end if
}//end for
return m_lpPreData;
}
*/
BYTE * JpegFile::FixtoBMP(unsigned char * lpInData,
unsigned long lWidth ,
unsigned long lHeight,
unsigned char * lpHeadData,
unsigned long lHeadSize,
unsigned long w,
unsigned long h)
{
if (w % 16) return NULL; //必需能被16整除
int hCell = h / 16;
if (hCell % 16) hCell++;
int wCell = w / 16;
int hSize = (wCell*hCell)/8;
if ((wCell*hCell)%8)
hSize++;
if (hSize != lHeadSize) return NULL;
DWORD 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);
}
DWORD lFullRow, row ;
DWORD lFullRowOffset = 0, lFullPoint = 0;
DWORD lPreRowOffset = 0, lPrePoint;
for (lFullRow = 0; lFullRow < wCell*hCell; lFullRow++)
{
// lPrePoint = ((lFullRow%(w/16))*16 + (lFullRow/(w/16))*w*16) * 3;
lPrePoint = ((lFullRow%wCell) + (lFullRow/wCell)*w)*48;
if (GETBIT(lpHeadData, lFullRow))//不相同
{
for (row = 0 ; row < 16 ; row ++)
{
if (lPrePoint+1 < lBufSize)
{
memcpy(m_lpPreData + lPrePoint, lpInData + lFullPoint, 48);
}
lPrePoint += w * 3;
lFullPoint += 48; //16 * 3
}//end for
}//end if
}//end for
return m_lpPreData;
}
#define SETBIT(p, x) ((unsigned char)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;
if (w % 16) return NULL; //必需能被16整除
// if (h % 8 )return NULL; //必需能被8整除
// unsigned long hSize = (long)w*(long)h/1024;
int hCell = h / 16;
if (hCell % 16) hCell++;
int wCell = w / 16;
int hSize = (wCell*hCell)/8;
if ((wCell*hCell)%8)
hSize++;
// DWORD lInRowSize = w * 3;
DWORD lBufSize = wCell*hCell*768 + 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==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;
DWORD lPreRow, row ;
DWORD lOutRowOffset = 0, lPreRowOffset = 0, lPrePoint;
DWORD lInPoint ;
int iFound, iHeightPoint = 0;
for (lPreRow = 0; lPreRow < wCell*hCell; lPreRow++, lPreRowOffset += 768)
{
iFound = 0;
lPrePoint = lPreRowOffset;
// lInPoint = ((lPreRow%wCell)*16 + (lPreRow/wCell)*w*16)*3;
lInPoint = ((lPreRow%wCell) + (lPreRow/wCell)*w)*48;
for (row = 0 ; row < 16 ; row ++)
{
//比较
if (lInPoint+1 > lBufSize)
{
memset(m_lpPreData + lPrePoint, 0,48);
}
else
{
if (iFound == 0 && bPre == true)
{
// iFound = memcmp(m_lpPreData + lPrePoint, lpInData + lInPoint, 48);
for (int i = 0 ; i < 48; i++)
{
if (*(m_lpPreData + lPrePoint + i) != *(lpInData + lInPoint+i))
{
iHeightPoint++;
iFound++;
break;
}
}//end for
}//end if
memcpy(m_lpPreData + lPrePoint, lpInData + lInPoint, 48); //保存
}
lPrePoint += 48; //16 * 3;
lInPoint += w * 3;
}//end for
if (iFound == 0 && bPre == true) continue;
SETBIT(m_lpOutBuffer, lPreRow);
//输出
memcpy(lpOutData + lOutRowOffset,
m_lpPreData + lPreRowOffset, 768); //16*16*3
lOutRowOffset += 768;
}//end for
*lWidth = 16;
*lHeight = lOutRowOffset/(16*3);
//*lHeight = iHeightPoint;
*lHeadSize = hSize;
*lSize = lOutRowOffset;
return m_lpOutBuffer;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -