Files
Work/browse/jpgimg.cpp
2024-08-07 09:12:07 -04:00

187 lines
7.0 KiB
C++

#include <browse/jpgimg.hpp>
#include <browse/rgb888.hpp>
#include <common/purehdc.hpp>
#include <jpeg-6b/jpeg6b.hpp>
#include <browse/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(0);
int imageCol;
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(0);
getBitmapInfo().colorUsed(0);
getBitmapInfo().colorImportant(0);
verifyDimensions(getBitmapInfo());
getRGBArray().size(getBitmapInfo().width()*(-getBitmapInfo().height()));
for(int scanline=0;scanline<cinfo.output_height;scanline++)
{
imageCol=0;
char *pScanLine=(char*)buffer[scanline];
for(int index=0;index<row_stride;index+=cinfo.output_components,pScanLine+=cinfo.output_components)
{
getRGBArray()[scanline*(getBitmapInfo().width())+imageCol]=RGB888(*pScanLine,*(pScanLine+1),*(pScanLine+2));
imageCol++;
}
}
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;
}
void JPGImage::verifyDimensions(BitmapInfo &someBitmapInfo)
{
DWORD desiredHeight(someBitmapInfo.height()<0?-someBitmapInfo.height():someBitmapInfo.height());
DWORD desiredWidth(someBitmapInfo.width());
DWORD imageExtent;
imageExtent=(((((LONG)desiredWidth*8)+31)&~31)>>3)*(LONG)desiredHeight;
if(imageExtent==(LONG)desiredWidth*(LONG)desiredHeight)return;
else desiredWidth=(WORD)(imageExtent/(LONG)desiredHeight);
someBitmapInfo.width(desiredWidth);
}
bool JPGImage::resample(PureDevice &pureDevice,int newWidth)
{
Array<RGB888> rgbArray;
Array<RGB888> tmpArray;
BitmapInfo bitmapInfo;
float heightFactor;
float aspectRatio;
int newHeight;
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));
bitmapInfo.planes(1);
bitmapInfo.compression(BI_RGB);
bitmapInfo.sizeImage(0);
bitmapInfo.colorUsed(0);
bitmapInfo.colorImportant(0);
verifyDimensions(bitmapInfo);
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,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(),bitmapInfo.height()<0?-bitmapInfo.height():bitmapInfo.height());
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);
verifyDimensions(bitmapInfo);
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,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(),bitmapInfo.height()<0?-bitmapInfo.height():bitmapInfo.height());
destroy();
getBitmapInfo()=bitmapInfo;
getRGBArray()=rgbArray;
mhBitmap=::CreateDIBitmap((HDC)pureDevice,(BITMAPINFOHEADER*)getBitmapInfo(),CBM_INIT,&getRGBArray()[0],(BITMAPINFO*)getBitmapInfo(),DIB_RGB_COLORS);
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;
}