📄 jzimagejpg.cpp
字号:
/*
* File: ximajpg.cpp
* Purpose: Platform Independent JPEG Image Class Loader and Writer
* 07/Aug/2001 Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#include "JzImageJpg.h"
#include "../jpeg/jmorecfg.h"
#include "JzImageInfo.h"
//////////////////////////////////////////////
extern "C"
{
void *jmalloc(unsigned int size)
{
return CImageMemMgr::malloc(size);
}
void jfree(void * mem)
{
CImageMemMgr::free(mem);
}
}
//////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Here's the routine that will replace the standard error_exit method:
////////////////////////////////////////////////////////////////////////////////
static void
ima_jpeg_error_exit (j_common_ptr cinfo)
{
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
jpg_error_ptr myerr = (jpg_error_ptr) cinfo->err;
/* Create the message */
myerr->pub.format_message (cinfo, myerr->buffer);
/* Send it to stderr, adding a newline */
/* Return control to the setjmp point */
longjmp(myerr->setjmp_buffer, 1);
}
////////////////////////////////////////////////////////////////////////////////
CJzImageJPG::CJzImageJPG()
{
#if CXIMAGEJPG_SUPPORT_EXIF
m_exif = NULL;
memset(&m_exifinfo, 0, sizeof(EXIFINFO));
#endif
}
////////////////////////////////////////////////////////////////////////////////
CJzImageJPG::~CJzImageJPG()
{
#if CXIMAGEJPG_SUPPORT_EXIF
if (m_exif) delete m_exif;
#endif
}
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGEJPG_SUPPORT_EXIF
bool CJzImageJPG::DecodeExif(CxFile * hFile)
{
m_exif = new CxExifInfo(&m_exifinfo);
if (m_exif){
long pos=hFile->Tell();
m_exif->DecodeExif(hFile);
hFile->Seek(pos,SEEK_SET);
return m_exif->m_exifinfo->IsExif;
} else {
return false;
}
}
#endif //CXIMAGEJPG_SUPPORT_EXIF
////////////////////////////////////////////////////////////////////////////////
bool CJzImageJPG::Decode(CxFile * hFile)
{
printf(" ^^^^^^^^^^^^^ start decode jpg \n");
bool is_exif = false;
pRgb = 0;
#if CXIMAGEJPG_SUPPORT_EXIF
is_exif = DecodeExif(hFile);
#endif
/* This struct contains the JPEG decompression parameters and pointers to
* working space (which is allocated as needed by the JPEG library).
*/
/* We use our private extension JPEG error handler. <CSC> */
struct jpg_error_mgr jerr;
jerr.buffer=info.szLastError;
/* In this example we want to open the input file before doing anything else,
* so that the setjmp() error recovery below can assume the file is open.
* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
* requires it in order to read binary files.
*/
/* Step 1: allocate and initialize JPEG decompression object */
/* We set up the normal JPEG error routines, then override error_exit. */
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = ima_jpeg_error_exit;
/* Establish the setjmp return context for my_error_exit to use. */
if (setjmp(jerr.setjmp_buffer)) {
/* If we get here, the JPEG code has signaled an error.
* We need to clean up the JPEG object, close the input file, and return.
*/
printf(" ===========**======= setjmp(jerr.setjmp_buffer) ======\n");
jpeg_destroy_decompress(&cinfo);
return false;
}
/* Now we can initialize the JPEG decompression object. */
jpeg_create_decompress(&cinfo);
/* Step 2: specify data source (eg, a file) */
//jpeg_stdio_src(&cinfo, infile);
CxFileJpg src(hFile);
cinfo.src = &src;
/* Step 3: read file parameters with jpeg_read_header() */
(void) jpeg_read_header(&cinfo, TRUE);
jpeg_calc_output_dimensions(&cinfo);
//printf(" ===start=== get jpg info ============\n ");
// Borrowed the idea from GIF implementation <ignacio>
printf(" =33== Decode jpg ===w:%d=== h:%d====bpp:%d===\n ",cinfo.image_width, cinfo.image_height, 8*cinfo.output_components);
if (info.nEscape == -1) {
// Return output dimensions only
//jpeg_calc_output_dimensions(&cinfo);
info.dwWidth = cinfo.output_width;
info.dwHeight = cinfo.output_height;
info.wBpp = 8*cinfo.output_components;
jpeg_destroy_decompress(&cinfo);
return true;
}
{
int w = (cinfo.image_width/pScr->w+1);
int h = cinfo.image_height/pScr->h+1;
#if 0
int temp_scale =( w < h )?w:h;
printf("=======temp_scale: %d\n", temp_scale );
w = cinfo.image_width/pScr->h+1;
h = cinfo.image_height/pScr->w+1;
#endif
cinfo.scale_denom =( w < h )?w:h;
// cinfo.scale_denom = ( cinfo.scale_denom < temp_scale )?cinfo.scale_denom:temp_scale;
if( cinfo.scale_denom <= 2 ) cinfo.scale_denom = 1;
else if( cinfo.scale_denom <= 4 ) cinfo.scale_denom = 2;
else if( cinfo.scale_denom <= 8 ) cinfo.scale_denom = 4;
else cinfo.scale_denom = 8;
info.nJpegScale = cinfo.scale_denom;
printf("cpp ========= cinfo.scale_denom: %d\n", cinfo.scale_denom );
/*
if( cinfo.scale_denom < 2 ) cinfo.scale_denom = 1;
else if( cinfo.scale_denom < 4 ) cinfo.scale_denom = 2;
else if( cinfo.scale_denom < 8 ) cinfo.scale_denom = 4;
else cinfo.scale_denom = 8;
*/
// printf(" scale w :%d, scale h:%d ,denom:%d \n",w,h,cinfo.scale_denom);
}
//cinfo.scale_denom = 1;
/* Step 5: Start decompressor */
jpeg_start_decompress(&cinfo);
/* We may need to do some setup of our own at this point before reading
* the data. After jpeg_start_decompress() we have the correct scaled
* output image dimensions available, as well as the output colormap
* if we asked for color quantization.
*/
//Create the image using output dimensions <ignacio>
//Create(cinfo.image_width, cinfo.image_height, 8*cinfo.output_components, CXIMAGE_FORMAT_JPG);
//printf("width = %d,height = %d\n",cinfo.output_width,cinfo.output_height);
DWORD wBpp = 8*cinfo.output_components;
//printf(" === Decode jpg ===w:%d=== h:%d====bpp:%d===\n ",cinfo.image_width, cinfo.image_height, wBpp);
//if (!CreateImageInfo(cinfo.image_width, cinfo.image_height, wBpp, CXIMAGE_FORMAT_JPG))
if( wBpp <= 8 ) return FALSE;
{
IVSETIMAGEINFO ivSetImageInfo = ivGetImageInfoCallback();
if( ivSetImageInfo )
{
IVIMAGEINFO ImageInfo;
ImageInfo.w = cinfo.output_width;
ImageInfo.h = cinfo.output_height;//image_height;
ImageInfo.bpp = 8*cinfo.output_components;
ivSetImageInfo( &ImageInfo );
info.dwimaWidth = ImageInfo.w;
info.dwimaHeight = ImageInfo.h;
ivscale = ImageInfo.ivscale;
info.pImage = ImageInfo.pImage;
if( info.pImage == NULL ) return FALSE;
printf("********** 11info.dwimaWidth: %d\n", info.dwimaWidth);
printf("cpp ====== ImageInfo.pImage: %x\n", ImageInfo.pImage );
}
}
if(!CreateImageInfo(cinfo.output_width, cinfo.output_height, wBpp, CXIMAGE_FORMAT_JPG))
{
printf("Can't allocate memory!");
longjmp(jerr.setjmp_buffer, 1);
return false;
}
int biClrUsed = 0;
if (cinfo.out_color_space==JCS_GRAYSCALE){
if(CreateGrayPalette(8*cinfo.output_components) == 0)
{
printf("Can't allocate memory!");
longjmp(jerr.setjmp_buffer, 1);
return false;
}
} else {
if (cinfo.quantize_colors==TRUE){
if(biClrUsed > cinfo.actual_number_of_colors) biClrUsed = cinfo.actual_number_of_colors;
if(CreatePalette(biClrUsed, cinfo.colormap[0], cinfo.colormap[1], cinfo.colormap[2]) == 0)
{
printf("Can't allocate memory!");
longjmp(jerr.setjmp_buffer, 1);
return false;
}
}
}
/* JSAMPLEs per row in output buffer */
row_stride = cinfo.output_width * cinfo.output_components;
/* Make a one-row-high sample array that will go away when done with image */
buffer = (*cinfo.mem->alloc_sarray)
((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
/* Step 6: while (scan lines remain to be read) */
/* jpeg_read_scanlines(...); */
/* Here we use the library's state variable cinfo.output_scanline as the
* loop counter, so that we don't have to keep track ourselves.
*/
//printf("============== deflate =============\n");
extract();
//deflate();
#if 0
{
int i,line;
for( i = 0; i < cinfo.output_height; i++ )
{
line = jpeg_read_scanlines(&cinfo, buffer, 4);
//printf("cinfo.output_scanline1 = %d, %d \n", cinfo.output_scanline,line );
cinfo.output_scanline+=4;
if(cinfo.output_scanline >=cinfo.output_height)
break;
}
printf(" line, input_scan_number,output_scan_number = %d, %d, %d \n", line, cinfo.input_scan_number, cinfo.output_scan_number );
}
//cinfo.output_scanline = cinfo.output_height;
#endif
/* Step 7: Finish decompression */
(void) jpeg_finish_decompress(&cinfo);
/* We can ignore the return value since suspension is not possible
* with the stdio data source.
*/
//<DP> Step 7A: Swap red and blue components
// not necessary if swapped red and blue definition in jmorecfg.h;ln322 <W. Morrison>
#if 0
if ((cinfo.num_components==3)&&(cinfo.quantize_colors==FALSE)){
BYTE* r0=GetBits();
for(long y=0;y<head.biHeight;y++){
if (info.nEscape) longjmp(jerr.setjmp_buffer, 1); // <vho> - cancel decoding
RGBtoBGR(r0,3*head.biWidth);
r0+=info.dwEffWidth;
}
}
#endif
/* Step 8: Release JPEG decompression object */
/* This is an important step since it will release a good deal of memory. */
jpeg_destroy_decompress(&cinfo);
/* At this point you may want to check to see whether any corrupt-data
* warnings occurred (test whether jerr.pub.num_warnings is nonzero).
*/
if(pRgb)
delete[] pRgb;
/* And we're done! */
return true;
}
////////////////////////////////////////////////////////////////////////////////
void CJzImageJPG::extract()
{
DWORD i, j;
int dx, dy, direction = 0;
BYTE *src = NULL;
//info.dwEffWidth = pScr->w*4;
info.dwEffWidth = info.dwimaWidth*4;
//ivscale = (int)( ((float)info.dwimaWidth/cinfo.output_width)*128.0+1 );
//if( ivscale > 128 ) ivscale = 128;
//ivscale = ivscale*info.nJpegScale;
printf("******** cinfo.output_width: %d, cinfo.output_height: %d\n",cinfo.output_width,cinfo.output_height);
printf("******** info.dwimaWidth: %d, info.dwimaHeight: %d\n",info.dwimaWidth,info.dwimaHeight);
printf("******** info.dwEffWidth: %d, ivscale: %d\n", info.dwEffWidth, ivscale);
/*
if( info.dwimaWidth > cinfo.output_width || info.dwimaHeight > cinfo.output_height)
{
printf(" ============ extract error =============\n");
return ;
}
*/
BYTE *line = info.pImage;
printf("========== line: %x\n", line );
//BYTE ivCenter = (cinfo.output_height-info.dwimaHeight)/2*info.dwimaWidth
unsigned int *ptar = pScr->buffer;//for test
//printf("---------------- ptar: %x, info.pImage: %x \n", ptar, info.pImage );
BOOL type_32bpp = ( (cinfo.num_components==4)&&(cinfo.quantize_colors==FALSE));
printf(" --------- type_32bpp: %d\n", type_32bpp );
//unsigned int *fb = NULL;
//ivTest(&fb);
//printf("YYYYYYYYYYYYYYYYYYYYYY ivTest: %x YYYYYYYYYYYYYYYYYYY\n", ptar);
// memset( (void *)line, 0 , info.dwimaHeight*info.dwimaWidth*4 );
//memcpy( ( void *)fb, (void *)line, 480*272*4);
//static int test=0;
dy = 0;
for( j = 0; j < info.dwimaHeight; j++ )
{
while( ivscale*dy/128 <= j )
{
jpeg_read_scanlines(&cinfo, buffer, 1 );
dy++;
}
//////////// row
src = buffer[0];
dx = 0;
if( type_32bpp )
{
for( i = 0; i < info.dwimaWidth; i++ )
{
while( ivscale*dx/128 < i ) dx++;
line[i * 4 + 2] = src[dx * 4 +0];
line[i * 4 + 1] = src[dx * 4 +1];
line[i * 4 + 0] = src[dx * 4 +2];
}
}
else
{
for( i = 0; i < info.dwimaWidth; i++ )
{
while( ivscale*dx/128 < i ) dx++;
line[i * 4 + 2] = src[dx * 3 +0];
line[i * 4 + 1] = src[dx * 3 +1];
line[i * 4 + 0] = src[dx * 3 +2];
// test++;
// printf("=============i: %d\n", i);
}
}
///////////
//memcpy( (void *)fb, ptar, info.dwEffWidth );
//fb += 480;
//ptar += 480;
line = line + info.dwEffWidth;
}
//test
if(cinfo.output_scanline >=cinfo.output_height)
{
printf("=========== notice extract jpg ==============\n");
return;
}
while( cinfo.output_scanline < cinfo.output_height )
{
jpeg_read_scanlines(&cinfo, buffer, 1 );
}
printf(" ========jpgtest==== \n" );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -