1
0
mirror of https://github.com/azure-rtos/guix.git synced 2025-02-04 07:13:17 +08:00
guix/guix_studio/jpg_reader.cpp

161 lines
3.4 KiB
C++

#include "studiox_includes.h"
#include "image_reader.h"
extern "C" {
#include "jpeglib.h"
//#include "jerror.h"
//#include "jmorecfg.h"
}
struct my_error_mgr
{
struct jpeg_error_mgr pub; /* "public" fields */
jmp_buf setjmp_buffer; /* for return to caller */
};
typedef struct my_error_mgr * my_error_ptr;
METHODDEF(void) my_error_exit (j_common_ptr cinfo)
{
my_error_ptr myerr = (my_error_ptr) cinfo->err;
(*cinfo->err->output_message) (cinfo);
longjmp(myerr->setjmp_buffer, 1);
}
jpg_reader::jpg_reader() : image_reader()
{
mpRawData = NULL;
memset(&mJpgInfo, 0, sizeof(jpeg_decompress_struct));
}
jpg_reader::~jpg_reader()
{
if (mpRawData)
{
delete [] mpRawData;
}
}
BOOL jpg_reader::ReadImage(CString &path, int frame_id)
{
struct my_error_mgr jerr;
FILE *file = _tfopen(path.GetBuffer(), _T("rb"));
if (!file)
{
return FALSE;
}
mJpgInfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
jpeg_create_decompress(&mJpgInfo);
if (setjmp(jerr.setjmp_buffer))
{
jpeg_destroy_decompress(&mJpgInfo);
fclose(file);
return FALSE;
}
jpeg_stdio_src(&mJpgInfo, file);
if (jpeg_read_header(&mJpgInfo, TRUE) != JPEG_HEADER_OK)
{
fclose(file);
jpeg_destroy_decompress(&mJpgInfo);
return FALSE;
}
mJpgInfo.out_color_space = JCS_RGB;
mJpgInfo.do_fancy_upsampling = FALSE;
jpeg_calc_output_dimensions(&mJpgInfo);
if (!jpeg_start_decompress(&mJpgInfo))
{
fclose(file);
jpeg_destroy_decompress(&mJpgInfo);
return FALSE;
}
// for now assume all JPG files are 24-bit rgb, and fail if it is not:
if (mJpgInfo.output_components != 3)
{
jpeg_finish_decompress(&mJpgInfo);
jpeg_destroy_decompress(&mJpgInfo);
fclose(file);
return FALSE;
}
SetDefaultPixelReader(24);
// test for 32-bit overflow before we attempt to allocate memory for
// jpg input file:
long long testval;
mRawRowStride = mJpgInfo.output_width * mJpgInfo.output_components;
testval = (long long) mRawRowStride * (long long) mJpgInfo.output_height;
if (testval & 0xffffffff00000000)
{
jpeg_destroy_decompress(&mJpgInfo);
fclose(file);
return FALSE;
}
// no size overflow, continue
mpRawData = new UCHAR[mRawRowStride * mJpgInfo.output_height];
if (!mpRawData)
{
jpeg_destroy_decompress(&mJpgInfo);
fclose(file);
return FALSE;
}
memset(mpRawData, 0, mRawRowStride * mJpgInfo.output_height);
while (mJpgInfo.output_scanline < mJpgInfo.output_height)
{
UCHAR *pPut = mpRawData;
pPut += mJpgInfo.output_scanline * mRawRowStride;
jpeg_read_scanlines(&mJpgInfo, &pPut, 1);
}
jpeg_finish_decompress(&mJpgInfo);
jpeg_destroy_decompress(&mJpgInfo);
DoCompress(FALSE);
if (FinalizeImage(mJpgInfo.output_width, mJpgInfo.output_height))
{
fclose(file);
return TRUE;
}
else
{
fclose(file);
return FALSE;
}
}
BOOL jpg_reader::ReadImage(unsigned char* data, int data_size)
{
// This route is not needed at present, return FALSE directly.
return FALSE;
}
UCHAR *jpg_reader::GetInputDataPtr(int row)
{
if (mpRawData)
{
UCHAR *pPut = mpRawData;
pPut += row * mRawRowStride;
return pPut;
}
return NULL;
}