Initial
This commit is contained in:
347
jpgimg/Jpgimg.cpp
Normal file
347
jpgimg/Jpgimg.cpp
Normal file
@@ -0,0 +1,347 @@
|
||||
#include <jpgimg/jpgimg.hpp>
|
||||
#include <jpgimg/rgb888.hpp>
|
||||
#include <common/purehdc.hpp>
|
||||
#include <common/file.hpp>
|
||||
#include <jpeg-6b/jpeg6b.hpp>
|
||||
#include <jpgimg/asmutil.hpp>
|
||||
|
||||
bool JPGImage::draw(PureDevice &pureDevice)
|
||||
{
|
||||
PureDevice compatibleDevice;
|
||||
if(!isOkay())return FALSE;
|
||||
compatibleDevice.compatibleDevice(pureDevice);
|
||||
compatibleDevice.select((GDIObj)mhBitmap,TRUE);
|
||||
pureDevice.bitBlt(Rect(0,0,width(),height()),compatibleDevice,Point(0,0));
|
||||
compatibleDevice.select((GDIObj)mhBitmap,FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool JPGImage::draw(PureDevice &pureDevice,int xSrc,int ySrc)
|
||||
{
|
||||
PureDevice compatibleDevice;
|
||||
if(!isOkay())return FALSE;
|
||||
compatibleDevice.compatibleDevice(pureDevice);
|
||||
compatibleDevice.select((GDIObj)mhBitmap,TRUE);
|
||||
pureDevice.bitBlt(Rect(xSrc,ySrc,width(),height()),compatibleDevice,Point(0,0));
|
||||
compatibleDevice.select((GDIObj)mhBitmap,FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool JPGImage::draw(PureDevice &pureDevice,const Rect &dstRect,const Point &srcPoint)
|
||||
{
|
||||
PureDevice compatibleDevice;
|
||||
if(!isOkay())return FALSE;
|
||||
compatibleDevice.compatibleDevice(pureDevice);
|
||||
compatibleDevice.select((GDIObj)mhBitmap,TRUE);
|
||||
pureDevice.bitBlt(dstRect,compatibleDevice,srcPoint);
|
||||
compatibleDevice.select((GDIObj)mhBitmap,FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool JPGImage::stretch(PureDevice &pureDevice,const Point &xyPoint,int strwidth,int strheight)
|
||||
{
|
||||
PureDevice compatibleDevice;
|
||||
if(!isOkay())return FALSE;
|
||||
compatibleDevice.compatibleDevice(pureDevice);
|
||||
compatibleDevice.select((GDIObj)mhBitmap,TRUE);
|
||||
pureDevice.stretchBlt(Rect(xyPoint.x(),xyPoint.y(),strwidth,strheight),compatibleDevice,Rect(0,0,width(),height()));
|
||||
compatibleDevice.select((GDIObj)mhBitmap,FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool JPGImage::decode(const String &strPathFileName,PureDevice &pureDevice)
|
||||
{
|
||||
JSAMPARRAY buffer;
|
||||
int row_stride;
|
||||
int row_elements;
|
||||
int row(0);
|
||||
jpeg_decompress_struct cinfo;
|
||||
FILE *fp;
|
||||
|
||||
destroy();
|
||||
if((fp=::fopen((char*)(String&)strPathFileName,"rb"))==NULL)return FALSE;
|
||||
::jpeg_create_decompress(&cinfo);
|
||||
::jpeg_stdio_src(&cinfo,fp);
|
||||
try{::jpeg_read_header(&cinfo,TRUE);}
|
||||
catch(JPGError){return FALSE;}
|
||||
try{::jpeg_start_decompress(&cinfo);}
|
||||
catch(JPGError){return FALSE;}
|
||||
row_stride=cinfo.output_width*cinfo.output_components;
|
||||
buffer=(*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo,JPOOL_IMAGE,row_stride,cinfo.output_height);
|
||||
while(cinfo.output_scanline<cinfo.output_height)::jpeg_read_scanlines(&cinfo,&buffer[row++],1);
|
||||
getBitmapInfo().rgbColors(0);
|
||||
getBitmapInfo().bitCount(BitmapInfo::Bit24);
|
||||
getBitmapInfo().width(cinfo.output_width);
|
||||
getBitmapInfo().height(-cinfo.output_height);
|
||||
getBitmapInfo().planes(1);
|
||||
getBitmapInfo().compression(BI_RGB);
|
||||
getBitmapInfo().sizeImage((cinfo.output_width*cinfo.output_height)*3);
|
||||
getBitmapInfo().colorUsed(0);
|
||||
getBitmapInfo().colorImportant(0);
|
||||
getBitmapInfo().verifyDimensions();
|
||||
getRGBArray().size(getBitmapInfo().width()*(-getBitmapInfo().height()));
|
||||
row_elements=row_stride/cinfo.output_components;
|
||||
for(int scanline=0;scanline<cinfo.output_height;scanline++)
|
||||
{
|
||||
copyBGRRGB(&getRGBArray()[scanline*getBitmapInfo().width()],(char*)buffer[scanline],row_elements,cinfo.output_components);
|
||||
}
|
||||
mhBitmap=::CreateDIBitmap((HDC)pureDevice,(BITMAPINFOHEADER*)getBitmapInfo(),CBM_INIT,&getRGBArray()[0],(BITMAPINFO*)getBitmapInfo(),DIB_RGB_COLORS);
|
||||
try{::jpeg_finish_decompress(&cinfo);}
|
||||
catch(JPGError){;}
|
||||
::jpeg_destroy_decompress(&cinfo);
|
||||
::fclose(fp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool JPGImage::decode(const String &strPathFileName)
|
||||
{
|
||||
JSAMPARRAY buffer;
|
||||
int row_stride;
|
||||
int row_elements;
|
||||
int row(0);
|
||||
jpeg_decompress_struct cinfo;
|
||||
FILE *fp;
|
||||
|
||||
destroy();
|
||||
if((fp=::fopen((char*)(String&)strPathFileName,"rb"))==NULL)return FALSE;
|
||||
::jpeg_create_decompress(&cinfo);
|
||||
::jpeg_stdio_src(&cinfo,fp);
|
||||
try{::jpeg_read_header(&cinfo,TRUE);}
|
||||
catch(JPGError){return FALSE;}
|
||||
try{::jpeg_start_decompress(&cinfo);}
|
||||
catch(JPGError){return FALSE;}
|
||||
row_stride=cinfo.output_width*cinfo.output_components;
|
||||
buffer=(*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo,JPOOL_IMAGE,row_stride,cinfo.output_height);
|
||||
while(cinfo.output_scanline<cinfo.output_height)::jpeg_read_scanlines(&cinfo,&buffer[row++],1);
|
||||
getBitmapInfo().rgbColors(0);
|
||||
getBitmapInfo().bitCount(BitmapInfo::Bit24);
|
||||
getBitmapInfo().width(cinfo.output_width);
|
||||
getBitmapInfo().height(-cinfo.output_height);
|
||||
getBitmapInfo().planes(1);
|
||||
getBitmapInfo().compression(BI_RGB);
|
||||
getBitmapInfo().sizeImage((cinfo.output_width*cinfo.output_height)*3);
|
||||
getBitmapInfo().colorUsed(0);
|
||||
getBitmapInfo().colorImportant(0);
|
||||
getBitmapInfo().verifyDimensions();
|
||||
getRGBArray().size(getBitmapInfo().width()*(-getBitmapInfo().height()));
|
||||
row_elements=row_stride/cinfo.output_components;
|
||||
for(int scanline=0;scanline<cinfo.output_height;scanline++)
|
||||
{
|
||||
copyBGRRGB(&getRGBArray()[scanline*getBitmapInfo().width()],(char*)buffer[scanline],row_elements,cinfo.output_components);
|
||||
}
|
||||
try{::jpeg_finish_decompress(&cinfo);}
|
||||
catch(JPGError){;}
|
||||
::jpeg_destroy_decompress(&cinfo);
|
||||
::fclose(fp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool JPGImage::saveBitmap(const String &strPathFileName)
|
||||
{
|
||||
BITMAPFILEHEADER bitmapFileHeader;
|
||||
OFSTRUCT ofStruct;
|
||||
File outFile;
|
||||
|
||||
BitmapInfo bmInfo=getBitmapInfo();
|
||||
if(!bmInfo.width()||!bmInfo.height()||!getRGBArray().size())return false;
|
||||
if(!outFile.open(strPathFileName,"wb"))return false;
|
||||
::memset(&bitmapFileHeader,0,sizeof(BITMAPFILEHEADER));
|
||||
bitmapFileHeader.bfType=0x4D42;
|
||||
bitmapFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)+getRGBArray().size();
|
||||
bitmapFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD);
|
||||
if(!outFile.write((char*)&bitmapFileHeader,sizeof(BITMAPFILEHEADER)))return false;
|
||||
if(bmInfo.height()<0)
|
||||
{
|
||||
Array<RGB888> &rgbArray=getRGBArray();
|
||||
Array<RGB888> tmpArray;
|
||||
|
||||
tmpArray.size(rgbArray.size());
|
||||
bmInfo.height(-bmInfo.height());
|
||||
for(int row=0;row<bmInfo.height();row++)
|
||||
copyRow(&tmpArray[row*bmInfo.width()],&rgbArray[(bmInfo.height()-row)*bmInfo.width()-bmInfo.width()],bmInfo.width());
|
||||
if(!outFile.write((char*)&(BITMAPINFO&)bmInfo,sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)))return false;
|
||||
if(!outFile.write((char*)&tmpArray[0],tmpArray.size()*sizeof(RGB888)))return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!outFile.write((char*)&(BITMAPINFO&)bmInfo,sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)))return false;
|
||||
if(!outFile.write((char*)&getRGBArray()[0],getRGBArray().size()*sizeof(RGB888)))return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void JPGImage::copyRow(RGB888 *pDstArray,RGB888 *pSrcArray,int length)
|
||||
{
|
||||
for(unsigned long count=0;count<length;count++)*pDstArray++=*pSrcArray++;
|
||||
}
|
||||
|
||||
bool JPGImage::resample(PureDevice &pureDevice,int newWidth)
|
||||
{
|
||||
Array<RGB888> rgbArray;
|
||||
Array<RGB888> tmpArray;
|
||||
BitmapInfo bitmapInfo;
|
||||
float heightFactor;
|
||||
float aspectRatio;
|
||||
int newHeight;
|
||||
|
||||
newWidth-=(newWidth%4); // align the width on DWORD boundary
|
||||
if(!isOkay())return false;
|
||||
aspectRatio=(float)width()/(float)height();
|
||||
newHeight=(float)newWidth/aspectRatio;
|
||||
heightFactor=(float)newHeight/height();
|
||||
bitmapInfo.rgbColors(0);
|
||||
bitmapInfo.bitCount(BitmapInfo::Bit24);
|
||||
bitmapInfo.width(newWidth);
|
||||
bitmapInfo.height(int((float)getBitmapInfo().height()*heightFactor));
|
||||
if(bitmapInfo.height()<0)bitmapInfo.height(-newHeight);
|
||||
else bitmapInfo.height(newHeight);
|
||||
bitmapInfo.planes(1);
|
||||
bitmapInfo.compression(BI_RGB);
|
||||
bitmapInfo.sizeImage(0);
|
||||
bitmapInfo.colorUsed(0);
|
||||
bitmapInfo.colorImportant(0);
|
||||
tmpArray.size(bitmapInfo.width()*height());
|
||||
for(int row=0;row<height();row++)::resampleClipRow(&getRGBArray()[(row*width())],&tmpArray[(row*newWidth)],width(),newWidth);
|
||||
rgbArray.size(bitmapInfo.width()*(bitmapInfo.height()<0?-bitmapInfo.height():bitmapInfo.height()));
|
||||
for(int col=0;col<bitmapInfo.width();col++)::resampleClipCol(&tmpArray[col],&rgbArray[col],height(),bitmapInfo.width(),bitmapInfo.height()<0?-bitmapInfo.height():bitmapInfo.height(),bitmapInfo.width());
|
||||
destroy();
|
||||
getBitmapInfo()=bitmapInfo;
|
||||
getRGBArray()=rgbArray;
|
||||
mhBitmap=::CreateDIBitmap((HDC)pureDevice,(BITMAPINFOHEADER*)getBitmapInfo(),CBM_INIT,&getRGBArray()[0],(BITMAPINFO*)getBitmapInfo(),DIB_RGB_COLORS);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JPGImage::resample(PureDevice &pureDevice,int newWidth,int newHeight)
|
||||
{
|
||||
Array<RGB888> rgbArray;
|
||||
Array<RGB888> tmpArray;
|
||||
BitmapInfo bitmapInfo;
|
||||
|
||||
if(!isOkay())return false;
|
||||
bitmapInfo.rgbColors(0);
|
||||
bitmapInfo.bitCount(BitmapInfo::Bit24);
|
||||
bitmapInfo.width(newWidth);
|
||||
bitmapInfo.height(-newHeight);
|
||||
bitmapInfo.planes(1);
|
||||
bitmapInfo.compression(BI_RGB);
|
||||
bitmapInfo.sizeImage(0);
|
||||
bitmapInfo.colorUsed(0);
|
||||
bitmapInfo.colorImportant(0);
|
||||
bitmapInfo.verifyDimensions();
|
||||
tmpArray.size(bitmapInfo.width()*(height()<0?-height():height()));
|
||||
for(int row=0;row<height();row++)::resampleClipRow(&getRGBArray()[(row*width())],&tmpArray[(row*newWidth)],width()+1,newWidth);
|
||||
rgbArray.size(bitmapInfo.width()*(bitmapInfo.height()<0?-bitmapInfo.height():bitmapInfo.height()));
|
||||
for(int col=0;col<bitmapInfo.width();col++)::resampleClipCol(&tmpArray[col],&rgbArray[col],height(),bitmapInfo.width(),bitmapInfo.height()<0?-bitmapInfo.height():bitmapInfo.height(),bitmapInfo.width());
|
||||
destroy();
|
||||
getBitmapInfo()=bitmapInfo;
|
||||
getRGBArray()=rgbArray;
|
||||
mhBitmap=::CreateDIBitmap((HDC)pureDevice,(BITMAPINFOHEADER*)getBitmapInfo(),CBM_INIT,&getRGBArray()[0],(BITMAPINFO*)getBitmapInfo(),DIB_RGB_COLORS);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JPGImage::resample(int newWidth,int newHeight)
|
||||
{
|
||||
Array<RGB888> rgbArray;
|
||||
Array<RGB888> tmpArray;
|
||||
BitmapInfo bitmapInfo;
|
||||
|
||||
if(!getRGBArray().size())return false;
|
||||
bitmapInfo.rgbColors(0);
|
||||
bitmapInfo.bitCount(BitmapInfo::Bit24);
|
||||
bitmapInfo.width(newWidth);
|
||||
bitmapInfo.height(-newHeight);
|
||||
bitmapInfo.planes(1);
|
||||
bitmapInfo.compression(BI_RGB);
|
||||
bitmapInfo.sizeImage(0);
|
||||
bitmapInfo.colorUsed(0);
|
||||
bitmapInfo.colorImportant(0);
|
||||
bitmapInfo.verifyDimensions();
|
||||
tmpArray.size(bitmapInfo.width()*(height()<0?-height():height()));
|
||||
for(int row=0;row<height();row++)::resampleClipRow(&getRGBArray()[(row*width())],&tmpArray[(row*newWidth)],width()+1,newWidth);
|
||||
rgbArray.size(bitmapInfo.width()*(bitmapInfo.height()<0?-bitmapInfo.height():bitmapInfo.height()));
|
||||
for(int col=0;col<bitmapInfo.width();col++)::resampleClipCol(&tmpArray[col],&rgbArray[col],height(),bitmapInfo.width(),bitmapInfo.height()<0?-bitmapInfo.height():bitmapInfo.height(),bitmapInfo.width());
|
||||
destroy();
|
||||
getBitmapInfo()=bitmapInfo;
|
||||
getRGBArray()=rgbArray;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JPGImage::getRawData(GlobalData<BYTE> &rawData)
|
||||
{
|
||||
return RawImage::getRawData(rawData);
|
||||
}
|
||||
|
||||
bool JPGImage::setRawData(GlobalData<BYTE> &rawData,PureDevice &pureDevice)
|
||||
{
|
||||
destroy();
|
||||
if(!RawImage::setRawData(rawData))return false;
|
||||
mhBitmap=::CreateDIBitmap((HDC)pureDevice,(BITMAPINFOHEADER*)getBitmapInfo(),CBM_INIT,&getRGBArray()[0],(BITMAPINFO*)getBitmapInfo(),DIB_RGB_COLORS);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JPGImage::rotateLeft(PureDevice &pureDevice)
|
||||
{
|
||||
Array<RGB888> rgbArray;
|
||||
RawImage rawImage;
|
||||
RGB888 rgb888;
|
||||
|
||||
if(!isOkay())return false;
|
||||
rawImage.getBitmapInfo().rgbColors(0);
|
||||
rawImage.getBitmapInfo().bitCount(BitmapInfo::Bit24);
|
||||
rawImage.getBitmapInfo().width(getBitmapInfo().height()<0?-getBitmapInfo().height():getBitmapInfo().height());
|
||||
rawImage.getBitmapInfo().height(getBitmapInfo().height()<0?-getBitmapInfo().width():getBitmapInfo().width());
|
||||
rawImage.getBitmapInfo().planes(1);
|
||||
rawImage.getBitmapInfo().compression(BI_RGB);
|
||||
rawImage.getBitmapInfo().sizeImage(0);
|
||||
rawImage.getBitmapInfo().colorUsed(0);
|
||||
rawImage.getBitmapInfo().colorImportant(0);
|
||||
rawImage.getBitmapInfo().verifyDimensions();
|
||||
rawImage.getRGBArray().size(rawImage.width()*rawImage.height());
|
||||
for(int rowIndex=0;rowIndex<(height()<0?-height():height());rowIndex++)
|
||||
{
|
||||
for(int colIndex=0;colIndex<width();colIndex++)
|
||||
{
|
||||
getAt(rowIndex,colIndex,rgb888);
|
||||
rawImage.setAt((width()-1)-colIndex,rowIndex,rgb888);
|
||||
}
|
||||
}
|
||||
destroy();
|
||||
getBitmapInfo()=rawImage.getBitmapInfo();
|
||||
getRGBArray()=rawImage.getRGBArray();
|
||||
mhBitmap=::CreateDIBitmap((HDC)pureDevice,(BITMAPINFOHEADER*)getBitmapInfo(),CBM_INIT,&getRGBArray()[0],(BITMAPINFO*)getBitmapInfo(),DIB_RGB_COLORS);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JPGImage::rotateRight(PureDevice &pureDevice)
|
||||
{
|
||||
Array<RGB888> rgbArray;
|
||||
RawImage rawImage;
|
||||
RGB888 rgb888;
|
||||
|
||||
if(!isOkay())return false;
|
||||
rawImage.getBitmapInfo().rgbColors(0);
|
||||
rawImage.getBitmapInfo().bitCount(BitmapInfo::Bit24);
|
||||
rawImage.getBitmapInfo().width(getBitmapInfo().height()<0?-getBitmapInfo().height():getBitmapInfo().height());
|
||||
rawImage.getBitmapInfo().height(getBitmapInfo().height()<0?-getBitmapInfo().width():getBitmapInfo().width());
|
||||
rawImage.getBitmapInfo().planes(1);
|
||||
rawImage.getBitmapInfo().compression(BI_RGB);
|
||||
rawImage.getBitmapInfo().sizeImage(0);
|
||||
rawImage.getBitmapInfo().colorUsed(0);
|
||||
rawImage.getBitmapInfo().colorImportant(0);
|
||||
rawImage.getBitmapInfo().verifyDimensions();
|
||||
rawImage.getRGBArray().size(rawImage.width()*rawImage.height());
|
||||
for(int rowIndex=0;rowIndex<(height()<0?-height():height());rowIndex++)
|
||||
{
|
||||
for(int colIndex=0;colIndex<width();colIndex++)
|
||||
{
|
||||
getAt(rowIndex,colIndex,rgb888);
|
||||
rawImage.setAt(colIndex,(height()-1)-rowIndex,rgb888);
|
||||
}
|
||||
}
|
||||
destroy();
|
||||
getBitmapInfo()=rawImage.getBitmapInfo();
|
||||
getRGBArray()=rawImage.getRGBArray();
|
||||
mhBitmap=::CreateDIBitmap((HDC)pureDevice,(BITMAPINFOHEADER*)getBitmapInfo(),CBM_INIT,&getRGBArray()[0],(BITMAPINFO*)getBitmapInfo(),DIB_RGB_COLORS);
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user