1 
2 #include "studiox_includes.h"
3 #include "image_reader.h"
4 
5 extern "C" {
6 #include "jpeglib.h"
7 //#include "jerror.h"
8 //#include "jmorecfg.h"
9 }
10 
11 struct my_error_mgr
12 {
13 	struct jpeg_error_mgr pub;	/* "public" fields */
14 	jmp_buf setjmp_buffer;	/* for return to caller */
15 };
16 typedef struct my_error_mgr * my_error_ptr;
17 
my_error_exit(j_common_ptr cinfo)18 METHODDEF(void) my_error_exit (j_common_ptr cinfo)
19 {
20 	my_error_ptr myerr = (my_error_ptr) cinfo->err;
21 	(*cinfo->err->output_message) (cinfo);
22 	longjmp(myerr->setjmp_buffer, 1);
23 }
24 
jpg_reader()25 jpg_reader::jpg_reader() : image_reader()
26 {
27     mpRawData = NULL;
28     memset(&mJpgInfo, 0, sizeof(jpeg_decompress_struct));
29 }
30 
~jpg_reader()31 jpg_reader::~jpg_reader()
32 {
33     if (mpRawData)
34     {
35         delete [] mpRawData;
36     }
37 }
38 
ReadImage(CString & path,int frame_id)39 BOOL jpg_reader::ReadImage(CString &path, int frame_id)
40 {
41 	struct my_error_mgr jerr;
42 
43     FILE *file = _tfopen(path.GetBuffer(), _T("rb"));
44 
45     if (!file)
46     {
47         return FALSE;
48     }
49 
50 	mJpgInfo.err = jpeg_std_error(&jerr.pub);
51 	jerr.pub.error_exit = my_error_exit;
52 
53     jpeg_create_decompress(&mJpgInfo);
54 
55     if (setjmp(jerr.setjmp_buffer))
56     {
57         jpeg_destroy_decompress(&mJpgInfo);
58         fclose(file);
59         return FALSE;
60     }
61 
62     jpeg_stdio_src(&mJpgInfo, file);
63 
64     if (jpeg_read_header(&mJpgInfo, TRUE) != JPEG_HEADER_OK)
65     {
66         fclose(file);
67         jpeg_destroy_decompress(&mJpgInfo);
68         return FALSE;
69     }
70 
71     mJpgInfo.out_color_space = JCS_RGB;
72     mJpgInfo.do_fancy_upsampling = FALSE;
73     jpeg_calc_output_dimensions(&mJpgInfo);
74 
75     if (!jpeg_start_decompress(&mJpgInfo))
76     {
77         fclose(file);
78         jpeg_destroy_decompress(&mJpgInfo);
79         return FALSE;
80     }
81 
82     // for now assume all JPG files are 24-bit rgb, and fail if it is not:
83 
84     if (mJpgInfo.output_components != 3)
85     {
86         jpeg_finish_decompress(&mJpgInfo);
87         jpeg_destroy_decompress(&mJpgInfo);
88         fclose(file);
89         return FALSE;
90     }
91     SetDefaultPixelReader(24);
92 
93     // test for 32-bit overflow before we attempt to allocate memory for
94     // jpg input file:
95 
96     long long testval;
97 
98     mRawRowStride = mJpgInfo.output_width * mJpgInfo.output_components;
99 
100     testval = (long long) mRawRowStride * (long long) mJpgInfo.output_height;
101     if (testval & 0xffffffff00000000)
102     {
103         jpeg_destroy_decompress(&mJpgInfo);
104         fclose(file);
105         return FALSE;
106     }
107 
108     // no size overflow, continue
109 
110     mpRawData = new UCHAR[mRawRowStride * mJpgInfo.output_height];
111 
112     if (!mpRawData)
113     {
114         jpeg_destroy_decompress(&mJpgInfo);
115         fclose(file);
116         return FALSE;
117     }
118     memset(mpRawData, 0,  mRawRowStride * mJpgInfo.output_height);
119 
120     while (mJpgInfo.output_scanline < mJpgInfo.output_height)
121     {
122         UCHAR *pPut = mpRawData;
123         pPut += mJpgInfo.output_scanline * mRawRowStride;
124         jpeg_read_scanlines(&mJpgInfo, &pPut, 1);
125     }
126 
127     jpeg_finish_decompress(&mJpgInfo);
128     jpeg_destroy_decompress(&mJpgInfo);
129 
130     DoCompress(FALSE);
131     if (FinalizeImage(mJpgInfo.output_width, mJpgInfo.output_height))
132     {
133         fclose(file);
134         return TRUE;
135     }
136     else
137     {
138         fclose(file);
139         return FALSE;
140     }
141 }
142 
ReadImage(unsigned char * data,int data_size)143 BOOL jpg_reader::ReadImage(unsigned char* data, int data_size)
144 {
145     // This route is not needed at present, return FALSE directly.
146     return FALSE;
147 }
148 
GetInputDataPtr(int row)149 UCHAR *jpg_reader::GetInputDataPtr(int row)
150 {
151     if (mpRawData)
152     {
153         UCHAR *pPut = mpRawData;
154         pPut += row * mRawRowStride;
155         return pPut;
156     }
157     return NULL;
158 }
159 
160 
161