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