Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(42)

Side by Side Diff: core/src/fxcodec/codec/fx_codec_jpx_opj.cpp

Issue 453133004: clang-format all code (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include "../../../include/fxcodec/fx_codec.h" 7 #include "../../../include/fxcodec/fx_codec.h"
8 #include "codec_int.h" 8 #include "codec_int.h"
9 #include "../fx_libopenjpeg/libopenjpeg20/openjpeg.h" 9 #include "../fx_libopenjpeg/libopenjpeg20/openjpeg.h"
10 #include "../lcms2/include/fx_lcms2.h" 10 #include "../lcms2/include/fx_lcms2.h"
11 static void fx_error_callback(const char *msg, void *client_data) 11 static void fx_error_callback(const char* msg, void* client_data) {
12 { 12 (void)client_data;
13 (void)client_data; 13 }
14 } 14 static void fx_warning_callback(const char* msg, void* client_data) {
15 static void fx_warning_callback(const char *msg, void *client_data) 15 (void)client_data;
16 { 16 }
17 (void)client_data; 17 static void fx_info_callback(const char* msg, void* client_data) {
18 } 18 (void)client_data;
19 static void fx_info_callback(const char *msg, void *client_data)
20 {
21 (void)client_data;
22 } 19 }
23 typedef struct { 20 typedef struct {
24 const unsigned char* src_data; 21 const unsigned char* src_data;
25 int»» » » » src_size; 22 int src_size;
26 int»» » » » offset; 23 int offset;
27 } decodeData; 24 } decodeData;
28 static OPJ_SIZE_T opj_read_from_memory (void * p_buffer, OPJ_SIZE_T p_nb_bytes, decodeData* srcData) 25 static OPJ_SIZE_T opj_read_from_memory(void* p_buffer,
29 { 26 OPJ_SIZE_T p_nb_bytes,
30 if(srcData == NULL || srcData->src_size == 0 || srcData->src_data == NULL || srcData->offset >= srcData->src_size) { 27 decodeData* srcData) {
31 return -1; 28 if (srcData == NULL || srcData->src_size == 0 || srcData->src_data == NULL ||
32 } 29 srcData->offset >= srcData->src_size) {
33 OPJ_SIZE_T readlength = p_nb_bytes; 30 return -1;
34 OPJ_SIZE_T bufferLength = (OPJ_SIZE_T)(srcData->src_size - srcData->offset); 31 }
35 if(bufferLength <= 0) { 32 OPJ_SIZE_T readlength = p_nb_bytes;
36 return 0; 33 OPJ_SIZE_T bufferLength = (OPJ_SIZE_T)(srcData->src_size - srcData->offset);
37 } 34 if (bufferLength <= 0) {
38 if(bufferLength <= p_nb_bytes) { 35 return 0;
39 readlength = bufferLength; 36 }
40 } 37 if (bufferLength <= p_nb_bytes) {
41 memcpy(p_buffer, &(srcData->src_data[srcData->offset]), readlength); 38 readlength = bufferLength;
42 srcData->offset += (int)readlength; 39 }
43 return readlength; 40 memcpy(p_buffer, &(srcData->src_data[srcData->offset]), readlength);
44 } 41 srcData->offset += (int)readlength;
45 static OPJ_SIZE_T opj_write_from_memory (void * p_buffer, OPJ_SIZE_T p_nb_bytes, decodeData* srcData) 42 return readlength;
46 { 43 }
47 if(srcData == NULL || srcData->src_size == 0 || srcData->src_data == NULL || srcData->offset >= srcData->src_size) { 44 static OPJ_SIZE_T opj_write_from_memory(void* p_buffer,
48 return -1; 45 OPJ_SIZE_T p_nb_bytes,
49 } 46 decodeData* srcData) {
50 OPJ_SIZE_T writeLength = p_nb_bytes; 47 if (srcData == NULL || srcData->src_size == 0 || srcData->src_data == NULL ||
51 OPJ_SIZE_T bufferLength = (OPJ_SIZE_T)(srcData->src_size - srcData->offset); 48 srcData->offset >= srcData->src_size) {
52 if(bufferLength <= p_nb_bytes) { 49 return -1;
53 writeLength = bufferLength; 50 }
54 } 51 OPJ_SIZE_T writeLength = p_nb_bytes;
55 memcpy((void*&)(srcData->src_data[srcData->offset]), p_buffer, writeLength); 52 OPJ_SIZE_T bufferLength = (OPJ_SIZE_T)(srcData->src_size - srcData->offset);
56 srcData->offset += (int)writeLength; 53 if (bufferLength <= p_nb_bytes) {
57 return writeLength; 54 writeLength = bufferLength;
58 } 55 }
59 static OPJ_OFF_T opj_skip_from_memory (OPJ_OFF_T p_nb_bytes, decodeData* srcData ) 56 memcpy((void*&)(srcData->src_data[srcData->offset]), p_buffer, writeLength);
60 { 57 srcData->offset += (int)writeLength;
61 if(srcData == NULL || srcData->src_size == 0 || srcData->src_data == NULL || srcData->offset >= srcData->src_size) { 58 return writeLength;
62 return -1; 59 }
63 } 60 static OPJ_OFF_T opj_skip_from_memory(OPJ_OFF_T p_nb_bytes,
64 OPJ_OFF_T postion = srcData->offset + p_nb_bytes; 61 decodeData* srcData) {
65 if(postion < 0 ) { 62 if (srcData == NULL || srcData->src_size == 0 || srcData->src_data == NULL ||
66 postion = 0; 63 srcData->offset >= srcData->src_size) {
67 } else if (postion > srcData->src_size) { 64 return -1;
68 } 65 }
69 srcData->offset = (int)postion; 66 OPJ_OFF_T postion = srcData->offset + p_nb_bytes;
70 return p_nb_bytes; 67 if (postion < 0) {
71 } 68 postion = 0;
72 static OPJ_BOOL opj_seek_from_memory (OPJ_OFF_T p_nb_bytes, decodeData * srcData ) 69 } else if (postion > srcData->src_size) {
73 { 70 }
74 if(srcData == NULL || srcData->src_size == 0 || srcData->src_data == NULL || srcData->offset >= srcData->src_size) { 71 srcData->offset = (int)postion;
75 return -1; 72 return p_nb_bytes;
76 } 73 }
77 srcData->offset = (int)p_nb_bytes; 74 static OPJ_BOOL opj_seek_from_memory(OPJ_OFF_T p_nb_bytes,
78 if(srcData->offset < 0) { 75 decodeData* srcData) {
79 srcData->offset = 0; 76 if (srcData == NULL || srcData->src_size == 0 || srcData->src_data == NULL ||
80 } else if(srcData->offset > srcData->src_size) { 77 srcData->offset >= srcData->src_size) {
81 srcData->offset = srcData->src_size; 78 return -1;
82 } 79 }
83 return OPJ_TRUE; 80 srcData->offset = (int)p_nb_bytes;
84 } 81 if (srcData->offset < 0) {
85 opj_stream_t* fx_opj_stream_create_memory_stream (decodeData* data, OPJ_SIZE _T p_size, OPJ_BOOL p_is_read_stream) 82 srcData->offset = 0;
86 { 83 } else if (srcData->offset > srcData->src_size) {
87 opj_stream_t* l_stream = 00; 84 srcData->offset = srcData->src_size;
88 if (!data || ! data->src_data || data->src_size <= 0 ) { 85 }
89 return NULL; 86 return OPJ_TRUE;
90 } 87 }
91 l_stream = opj_stream_create(p_size, p_is_read_stream); 88 opj_stream_t* fx_opj_stream_create_memory_stream(decodeData* data,
92 if (! l_stream) { 89 OPJ_SIZE_T p_size,
93 return NULL; 90 OPJ_BOOL p_is_read_stream) {
94 } 91 opj_stream_t* l_stream = 00;
95 opj_stream_set_user_data_v3(l_stream, data, NULL); 92 if (!data || !data->src_data || data->src_size <= 0) {
96 opj_stream_set_user_data_length(l_stream, data->src_size); 93 return NULL;
97 opj_stream_set_read_function(l_stream, (opj_stream_read_fn) opj_read_from_me mory); 94 }
98 opj_stream_set_write_function(l_stream, (opj_stream_write_fn) opj_write_from _memory); 95 l_stream = opj_stream_create(p_size, p_is_read_stream);
99 opj_stream_set_skip_function(l_stream, (opj_stream_skip_fn) opj_skip_from_me mory); 96 if (!l_stream) {
100 opj_stream_set_seek_function(l_stream, (opj_stream_seek_fn) opj_seek_from_me mory); 97 return NULL;
101 return l_stream; 98 }
102 } 99 opj_stream_set_user_data_v3(l_stream, data, NULL);
103 static void sycc_to_rgb(int offset, int upb, int y, int cb, int cr, 100 opj_stream_set_user_data_length(l_stream, data->src_size);
104 int *out_r, int *out_g, int *out_b) 101 opj_stream_set_read_function(l_stream,
105 { 102 (opj_stream_read_fn)opj_read_from_memory);
106 int r, g, b; 103 opj_stream_set_write_function(l_stream,
107 cb -= offset; 104 (opj_stream_write_fn)opj_write_from_memory);
108 cr -= offset; 105 opj_stream_set_skip_function(l_stream,
109 r = y + (int)(1.402 * (float)cr); 106 (opj_stream_skip_fn)opj_skip_from_memory);
110 if(r < 0) { 107 opj_stream_set_seek_function(l_stream,
111 r = 0; 108 (opj_stream_seek_fn)opj_seek_from_memory);
112 } else if(r > upb) { 109 return l_stream;
113 r = upb; 110 }
114 } *out_r = r; 111 static void sycc_to_rgb(int offset,
115 g = y - (int)(0.344 * (float)cb + 0.714 * (float)cr); 112 int upb,
116 if(g < 0) { 113 int y,
117 g = 0; 114 int cb,
118 } else if(g > upb) { 115 int cr,
119 g = upb; 116 int* out_r,
120 } *out_g = g; 117 int* out_g,
121 b = y + (int)(1.772 * (float)cb); 118 int* out_b) {
122 if(b < 0) { 119 int r, g, b;
123 b = 0; 120 cb -= offset;
124 } else if(b > upb) { 121 cr -= offset;
125 b = upb; 122 r = y + (int)(1.402 * (float)cr);
126 } *out_b = b; 123 if (r < 0) {
127 } 124 r = 0;
128 static void sycc444_to_rgb(opj_image_t *img) 125 } else if (r > upb) {
129 { 126 r = upb;
130 int *d0, *d1, *d2, *r, *g, *b; 127 }
131 const int *y, *cb, *cr; 128 *out_r = r;
132 int maxw, maxh, max, i, offset, upb; 129 g = y - (int)(0.344 * (float)cb + 0.714 * (float)cr);
133 i = (int)img->comps[0].prec; 130 if (g < 0) {
134 offset = 1 << (i - 1); 131 g = 0;
135 upb = (1 << i) - 1; 132 } else if (g > upb) {
136 maxw = (int)img->comps[0].w; 133 g = upb;
137 maxh = (int)img->comps[0].h; 134 }
138 max = maxw * maxh; 135 *out_g = g;
139 y = img->comps[0].data; 136 b = y + (int)(1.772 * (float)cb);
140 cb = img->comps[1].data; 137 if (b < 0) {
141 cr = img->comps[2].data; 138 b = 0;
142 d0 = r = FX_Alloc(int, (size_t)max); 139 } else if (b > upb) {
143 d1 = g = FX_Alloc(int, (size_t)max); 140 b = upb;
144 d2 = b = FX_Alloc(int, (size_t)max); 141 }
145 for(i = 0; i < max; ++i) { 142 *out_b = b;
146 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); 143 }
147 ++y; 144 static void sycc444_to_rgb(opj_image_t* img) {
148 ++cb; 145 int* d0, *d1, *d2, *r, *g, *b;
149 ++cr; 146 const int* y, *cb, *cr;
150 ++r; 147 int maxw, maxh, max, i, offset, upb;
151 ++g; 148 i = (int)img->comps[0].prec;
152 ++b; 149 offset = 1 << (i - 1);
153 } 150 upb = (1 << i) - 1;
154 FX_Free(img->comps[0].data); 151 maxw = (int)img->comps[0].w;
155 img->comps[0].data = d0; 152 maxh = (int)img->comps[0].h;
156 FX_Free(img->comps[1].data); 153 max = maxw * maxh;
157 img->comps[1].data = d1; 154 y = img->comps[0].data;
158 FX_Free(img->comps[2].data); 155 cb = img->comps[1].data;
159 img->comps[2].data = d2; 156 cr = img->comps[2].data;
160 } 157 d0 = r = FX_Alloc(int, (size_t)max);
161 static void sycc422_to_rgb(opj_image_t *img) 158 d1 = g = FX_Alloc(int, (size_t)max);
162 { 159 d2 = b = FX_Alloc(int, (size_t)max);
163 int *d0, *d1, *d2, *r, *g, *b; 160 for (i = 0; i < max; ++i) {
164 const int *y, *cb, *cr; 161 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
165 int maxw, maxh, max, offset, upb; 162 ++y;
166 int i, j; 163 ++cb;
167 i = (int)img->comps[0].prec; 164 ++cr;
168 offset = 1 << (i - 1); 165 ++r;
169 upb = (1 << i) - 1; 166 ++g;
170 maxw = (int)img->comps[0].w; 167 ++b;
171 maxh = (int)img->comps[0].h; 168 }
172 max = maxw * maxh; 169 FX_Free(img->comps[0].data);
173 y = img->comps[0].data; 170 img->comps[0].data = d0;
174 cb = img->comps[1].data; 171 FX_Free(img->comps[1].data);
175 cr = img->comps[2].data; 172 img->comps[1].data = d1;
176 d0 = r = FX_Alloc(int, (size_t)max); 173 FX_Free(img->comps[2].data);
177 d1 = g = FX_Alloc(int, (size_t)max); 174 img->comps[2].data = d2;
178 d2 = b = FX_Alloc(int, (size_t)max); 175 }
179 for(i = 0; i < maxh; ++i) { 176 static void sycc422_to_rgb(opj_image_t* img) {
180 for(j = 0; j < maxw; j += 2) { 177 int* d0, *d1, *d2, *r, *g, *b;
181 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); 178 const int* y, *cb, *cr;
182 ++y; 179 int maxw, maxh, max, offset, upb;
183 ++r; 180 int i, j;
184 ++g; 181 i = (int)img->comps[0].prec;
185 ++b; 182 offset = 1 << (i - 1);
186 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); 183 upb = (1 << i) - 1;
187 ++y; 184 maxw = (int)img->comps[0].w;
188 ++r; 185 maxh = (int)img->comps[0].h;
189 ++g; 186 max = maxw * maxh;
190 ++b; 187 y = img->comps[0].data;
191 ++cb; 188 cb = img->comps[1].data;
192 ++cr; 189 cr = img->comps[2].data;
190 d0 = r = FX_Alloc(int, (size_t)max);
191 d1 = g = FX_Alloc(int, (size_t)max);
192 d2 = b = FX_Alloc(int, (size_t)max);
193 for (i = 0; i < maxh; ++i) {
194 for (j = 0; j < maxw; j += 2) {
195 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
196 ++y;
197 ++r;
198 ++g;
199 ++b;
200 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
201 ++y;
202 ++r;
203 ++g;
204 ++b;
205 ++cb;
206 ++cr;
207 }
208 }
209 FX_Free(img->comps[0].data);
210 img->comps[0].data = d0;
211 FX_Free(img->comps[1].data);
212 img->comps[1].data = d1;
213 FX_Free(img->comps[2].data);
214 img->comps[2].data = d2;
215 img->comps[1].w = maxw;
216 img->comps[1].h = maxh;
217 img->comps[2].w = maxw;
218 img->comps[2].h = maxh;
219 img->comps[1].w = (OPJ_UINT32)maxw;
220 img->comps[1].h = (OPJ_UINT32)maxh;
221 img->comps[2].w = (OPJ_UINT32)maxw;
222 img->comps[2].h = (OPJ_UINT32)maxh;
223 img->comps[1].dx = img->comps[0].dx;
224 img->comps[2].dx = img->comps[0].dx;
225 img->comps[1].dy = img->comps[0].dy;
226 img->comps[2].dy = img->comps[0].dy;
227 }
228 static void sycc420_to_rgb(opj_image_t* img) {
229 int* d0, *d1, *d2, *r, *g, *b, *nr, *ng, *nb;
230 const int* y, *cb, *cr, *ny;
231 int maxw, maxh, max, offset, upb;
232 int i, j;
233 i = (int)img->comps[0].prec;
234 offset = 1 << (i - 1);
235 upb = (1 << i) - 1;
236 maxw = (int)img->comps[0].w;
237 maxh = (int)img->comps[0].h;
238 max = maxw * maxh;
239 y = img->comps[0].data;
240 cb = img->comps[1].data;
241 cr = img->comps[2].data;
242 d0 = r = FX_Alloc(int, (size_t)max);
243 d1 = g = FX_Alloc(int, (size_t)max);
244 d2 = b = FX_Alloc(int, (size_t)max);
245 for (i = 0; i < maxh; i += 2) {
246 ny = y + maxw;
247 nr = r + maxw;
248 ng = g + maxw;
249 nb = b + maxw;
250 for (j = 0; j < maxw; j += 2) {
251 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
252 ++y;
253 ++r;
254 ++g;
255 ++b;
256 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
257 ++y;
258 ++r;
259 ++g;
260 ++b;
261 sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
262 ++ny;
263 ++nr;
264 ++ng;
265 ++nb;
266 sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
267 ++ny;
268 ++nr;
269 ++ng;
270 ++nb;
271 ++cb;
272 ++cr;
273 }
274 y += maxw;
275 r += maxw;
276 g += maxw;
277 b += maxw;
278 }
279 FX_Free(img->comps[0].data);
280 img->comps[0].data = d0;
281 FX_Free(img->comps[1].data);
282 img->comps[1].data = d1;
283 FX_Free(img->comps[2].data);
284 img->comps[2].data = d2;
285 img->comps[1].w = maxw;
286 img->comps[1].h = maxh;
287 img->comps[2].w = maxw;
288 img->comps[2].h = maxh;
289 img->comps[1].w = (OPJ_UINT32)maxw;
290 img->comps[1].h = (OPJ_UINT32)maxh;
291 img->comps[2].w = (OPJ_UINT32)maxw;
292 img->comps[2].h = (OPJ_UINT32)maxh;
293 img->comps[1].dx = img->comps[0].dx;
294 img->comps[2].dx = img->comps[0].dx;
295 img->comps[1].dy = img->comps[0].dy;
296 img->comps[2].dy = img->comps[0].dy;
297 }
298 void color_sycc_to_rgb(opj_image_t* img) {
299 if (img->numcomps < 3) {
300 img->color_space = OPJ_CLRSPC_GRAY;
301 return;
302 }
303 if ((img->comps[0].dx == 1) && (img->comps[1].dx == 2) &&
304 (img->comps[2].dx == 2) && (img->comps[0].dy == 1) &&
305 (img->comps[1].dy == 2) && (img->comps[2].dy == 2)) {
306 sycc420_to_rgb(img);
307 } else if ((img->comps[0].dx == 1) && (img->comps[1].dx == 2) &&
308 (img->comps[2].dx == 2) && (img->comps[0].dy == 1) &&
309 (img->comps[1].dy == 1) && (img->comps[2].dy == 1)) {
310 sycc422_to_rgb(img);
311 } else if ((img->comps[0].dx == 1) && (img->comps[1].dx == 1) &&
312 (img->comps[2].dx == 1) && (img->comps[0].dy == 1) &&
313 (img->comps[1].dy == 1) && (img->comps[2].dy == 1)) {
314 sycc444_to_rgb(img);
315 } else {
316 return;
317 }
318 img->color_space = OPJ_CLRSPC_SRGB;
319 }
320 void color_apply_icc_profile(opj_image_t* image) {
321 cmsHPROFILE in_prof, out_prof;
322 cmsHTRANSFORM transform;
323 cmsColorSpaceSignature in_space, out_space;
324 cmsUInt32Number intent, in_type, out_type, nr_samples;
325 int* r, *g, *b;
326 int prec, i, max, max_w, max_h;
327 OPJ_COLOR_SPACE oldspace;
328 in_prof =
329 cmsOpenProfileFromMem(image->icc_profile_buf, image->icc_profile_len);
330 if (in_prof == NULL) {
331 return;
332 }
333 in_space = cmsGetPCS(in_prof);
334 out_space = cmsGetColorSpace(in_prof);
335 intent = cmsGetHeaderRenderingIntent(in_prof);
336 max_w = (int)image->comps[0].w;
337 max_h = (int)image->comps[0].h;
338 prec = (int)image->comps[0].prec;
339 oldspace = image->color_space;
340 if (out_space == cmsSigRgbData) {
341 if (prec <= 8) {
342 in_type = TYPE_RGB_8;
343 out_type = TYPE_RGB_8;
344 } else {
345 in_type = TYPE_RGB_16;
346 out_type = TYPE_RGB_16;
347 }
348 out_prof = cmsCreate_sRGBProfile();
349 image->color_space = OPJ_CLRSPC_SRGB;
350 } else if (out_space == cmsSigGrayData) {
351 if (prec <= 8) {
352 in_type = TYPE_GRAY_8;
353 out_type = TYPE_RGB_8;
354 } else {
355 in_type = TYPE_GRAY_16;
356 out_type = TYPE_RGB_16;
357 }
358 out_prof = cmsCreate_sRGBProfile();
359 image->color_space = OPJ_CLRSPC_SRGB;
360 } else if (out_space == cmsSigYCbCrData) {
361 in_type = TYPE_YCbCr_16;
362 out_type = TYPE_RGB_16;
363 out_prof = cmsCreate_sRGBProfile();
364 image->color_space = OPJ_CLRSPC_SRGB;
365 } else {
366 return;
367 }
368 transform =
369 cmsCreateTransform(in_prof, in_type, out_prof, out_type, intent, 0);
370 cmsCloseProfile(in_prof);
371 cmsCloseProfile(out_prof);
372 if (transform == NULL) {
373 image->color_space = oldspace;
374 return;
375 }
376 if (image->numcomps > 2) {
377 if (prec <= 8) {
378 unsigned char* inbuf, *outbuf, *in, *out;
379 max = max_w * max_h;
380 nr_samples =
381 (cmsUInt32Number)max * 3 * (cmsUInt32Number)sizeof(unsigned char);
382 in = inbuf = FX_Alloc(unsigned char, nr_samples);
383 out = outbuf = FX_Alloc(unsigned char, nr_samples);
384 r = image->comps[0].data;
385 g = image->comps[1].data;
386 b = image->comps[2].data;
387 for (i = 0; i < max; ++i) {
388 *in++ = (unsigned char)*r++;
389 *in++ = (unsigned char)*g++;
390 *in++ = (unsigned char)*b++;
391 }
392 cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
393 r = image->comps[0].data;
394 g = image->comps[1].data;
395 b = image->comps[2].data;
396 for (i = 0; i < max; ++i) {
397 *r++ = (int)*out++;
398 *g++ = (int)*out++;
399 *b++ = (int)*out++;
400 }
401 FX_Free(inbuf);
402 FX_Free(outbuf);
403 } else {
404 unsigned short* inbuf, *outbuf, *in, *out;
405 max = max_w * max_h;
406 nr_samples =
407 (cmsUInt32Number)max * 3 * (cmsUInt32Number)sizeof(unsigned short);
408 in = inbuf = FX_Alloc(unsigned short, nr_samples);
409 out = outbuf = FX_Alloc(unsigned short, nr_samples);
410 r = image->comps[0].data;
411 g = image->comps[1].data;
412 b = image->comps[2].data;
413 for (i = 0; i < max; ++i) {
414 *in++ = (unsigned short)*r++;
415 *in++ = (unsigned short)*g++;
416 *in++ = (unsigned short)*b++;
417 }
418 cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
419 r = image->comps[0].data;
420 g = image->comps[1].data;
421 b = image->comps[2].data;
422 for (i = 0; i < max; ++i) {
423 *r++ = (int)*out++;
424 *g++ = (int)*out++;
425 *b++ = (int)*out++;
426 }
427 FX_Free(inbuf);
428 FX_Free(outbuf);
429 }
430 } else {
431 unsigned char* in, *inbuf, *out, *outbuf;
432 max = max_w * max_h;
433 nr_samples = (cmsUInt32Number)max * 3 * sizeof(unsigned char);
434 in = inbuf = FX_Alloc(unsigned char, nr_samples);
435 out = outbuf = FX_Alloc(unsigned char, nr_samples);
436 image->comps = (opj_image_comp_t*)realloc(
437 image->comps, (image->numcomps + 2) * sizeof(opj_image_comp_t));
438 if (image->numcomps == 2) {
439 image->comps[3] = image->comps[1];
440 }
441 image->comps[1] = image->comps[0];
442 image->comps[2] = image->comps[0];
443 image->comps[1].data = FX_Alloc(int, (size_t)max);
444 FXSYS_memset8(image->comps[1].data, 0, sizeof(int) * (size_t)max);
445 image->comps[2].data = FX_Alloc(int, (size_t)max);
446 FXSYS_memset8(image->comps[2].data, 0, sizeof(int) * (size_t)max);
447 image->numcomps += 2;
448 r = image->comps[0].data;
449 for (i = 0; i < max; ++i) {
450 *in++ = (unsigned char)*r++;
451 }
452 cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
453 r = image->comps[0].data;
454 g = image->comps[1].data;
455 b = image->comps[2].data;
456 for (i = 0; i < max; ++i) {
457 *r++ = (int)*out++;
458 *g++ = (int)*out++;
459 *b++ = (int)*out++;
460 }
461 FX_Free(inbuf);
462 FX_Free(outbuf);
463 }
464 cmsDeleteTransform(transform);
465 }
466 void color_apply_conversion(opj_image_t* image) {
467 int* row;
468 int enumcs, numcomps;
469 numcomps = image->numcomps;
470 if (numcomps < 3) {
471 return;
472 }
473 row = (int*)image->icc_profile_buf;
474 enumcs = row[0];
475 if (enumcs == 14) {
476 int* L, *a, *b, *red, *green, *blue, *src0, *src1, *src2;
477 double rl, ol, ra, oa, rb, ob, prec0, prec1, prec2;
478 double minL, maxL, mina, maxa, minb, maxb;
479 unsigned int default_type, il;
480 unsigned int i, max, illu;
481 cmsHPROFILE in, out;
482 cmsHTRANSFORM transform;
483 cmsUInt16Number RGB[3];
484 cmsCIELab Lab;
485 illu = 0;
486 il = 0;
487 in = cmsCreateLab4Profile(NULL);
488 out = cmsCreate_sRGBProfile();
489 transform = cmsCreateTransform(
490 in, TYPE_Lab_DBL, out, TYPE_RGB_16, INTENT_PERCEPTUAL, 0);
491 cmsCloseProfile(in);
492 cmsCloseProfile(out);
493 if (transform == NULL) {
494 return;
495 }
496 prec0 = (double)image->comps[0].prec;
497 prec1 = (double)image->comps[1].prec;
498 prec2 = (double)image->comps[2].prec;
499 default_type = row[1];
500 if (default_type == 0x44454600) {
501 rl = 100;
502 ra = 170;
503 rb = 200;
504 ol = 0;
505 oa = pow(2, prec1 - 1);
506 ob = pow(2, prec2 - 2) + pow(2, prec2 - 3);
507 } else {
508 rl = row[2];
509 ra = row[4];
510 rb = row[6];
511 ol = row[3];
512 oa = row[5];
513 ob = row[7];
514 }
515 L = src0 = image->comps[0].data;
516 a = src1 = image->comps[1].data;
517 b = src2 = image->comps[2].data;
518 max = image->comps[0].w * image->comps[0].h;
519 red = FX_Alloc(int, max);
520 image->comps[0].data = red;
521 green = FX_Alloc(int, max);
522 image->comps[1].data = green;
523 blue = FX_Alloc(int, max);
524 image->comps[2].data = blue;
525 minL = -(rl * ol) / (pow(2, prec0) - 1);
526 maxL = minL + rl;
527 mina = -(ra * oa) / (pow(2, prec1) - 1);
528 maxa = mina + ra;
529 minb = -(rb * ob) / (pow(2, prec2) - 1);
530 maxb = minb + rb;
531 for (i = 0; i < max; ++i) {
532 Lab.L = minL + (double)(*L) * (maxL - minL) / (pow(2, prec0) - 1);
533 ++L;
534 Lab.a = mina + (double)(*a) * (maxa - mina) / (pow(2, prec1) - 1);
535 ++a;
536 Lab.b = minb + (double)(*b) * (maxb - minb) / (pow(2, prec2) - 1);
537 ++b;
538 cmsDoTransform(transform, &Lab, RGB, 1);
539 *red++ = RGB[0];
540 *green++ = RGB[1];
541 *blue++ = RGB[2];
542 }
543 cmsDeleteTransform(transform);
544 FX_Free(src0);
545 FX_Free(src1);
546 FX_Free(src2);
547 image->color_space = OPJ_CLRSPC_SRGB;
548 image->comps[0].prec = 16;
549 image->comps[1].prec = 16;
550 image->comps[2].prec = 16;
551 return;
552 }
553 }
554 class CJPX_Decoder : public CFX_Object {
555 public:
556 CJPX_Decoder();
557 ~CJPX_Decoder();
558 FX_BOOL Init(const unsigned char* src_data, int src_size);
559 void GetInfo(FX_DWORD& width,
560 FX_DWORD& height,
561 FX_DWORD& codestream_nComps,
562 FX_DWORD& output_nComps);
563 FX_BOOL Decode(FX_LPBYTE dest_buf,
564 int pitch,
565 FX_BOOL bTranslateColor,
566 FX_LPBYTE offsets);
567 FX_LPCBYTE m_SrcData;
568 int m_SrcSize;
569 opj_image_t* image;
570 opj_codec_t* l_codec;
571 opj_stream_t* l_stream;
572 FX_BOOL m_useColorSpace;
573 };
574 CJPX_Decoder::CJPX_Decoder()
575 : image(NULL), l_codec(NULL), l_stream(NULL), m_useColorSpace(FALSE) {
576 }
577 CJPX_Decoder::~CJPX_Decoder() {
578 if (l_codec) {
579 opj_destroy_codec(l_codec);
580 }
581 if (l_stream) {
582 opj_stream_destroy(l_stream);
583 }
584 if (image) {
585 opj_image_destroy(image);
586 }
587 }
588 FX_BOOL CJPX_Decoder::Init(const unsigned char* src_data, int src_size) {
589 opj_dparameters_t parameters;
590 try {
591 image = NULL;
592 m_SrcData = src_data;
593 m_SrcSize = src_size;
594 decodeData srcData;
595 srcData.offset = 0;
596 srcData.src_size = src_size;
597 srcData.src_data = src_data;
598 l_stream = fx_opj_stream_create_memory_stream(
599 &srcData, OPJ_J2K_STREAM_CHUNK_SIZE, 1);
600 if (l_stream == NULL) {
601 return FALSE;
602 }
603 opj_set_default_decoder_parameters(&parameters);
604 parameters.decod_format = 0;
605 parameters.cod_format = 3;
606 if (FXSYS_memcmp32(m_SrcData,
607 "\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a",
608 12) == 0) {
609 l_codec = opj_create_decompress(OPJ_CODEC_JP2);
610 parameters.decod_format = 1;
611 } else {
612 l_codec = opj_create_decompress(OPJ_CODEC_J2K);
613 }
614 if (!l_codec) {
615 return FALSE;
616 }
617 opj_set_info_handler(l_codec, fx_info_callback, 00);
618 opj_set_warning_handler(l_codec, fx_warning_callback, 00);
619 opj_set_error_handler(l_codec, fx_error_callback, 00);
620 if (!opj_setup_decoder(l_codec, &parameters)) {
621 return FALSE;
622 }
623 if (!opj_read_header(l_stream, l_codec, &image)) {
624 image = NULL;
625 return FALSE;
626 }
627 if (this->m_useColorSpace) {
628 image->useColorSpace = 1;
629 } else {
630 image->useColorSpace = 0;
631 }
632 if (!parameters.nb_tile_to_decode) {
633 if (!opj_set_decode_area(l_codec,
634 image,
635 parameters.DA_x0,
636 parameters.DA_y0,
637 parameters.DA_x1,
638 parameters.DA_y1)) {
639 opj_image_destroy(image);
640 image = NULL;
641 return FALSE;
642 }
643 if (!(opj_decode(l_codec, l_stream, image) &&
644 opj_end_decompress(l_codec, l_stream))) {
645 opj_image_destroy(image);
646 image = NULL;
647 return FALSE;
648 }
649 } else {
650 if (!opj_get_decoded_tile(
651 l_codec, l_stream, image, parameters.tile_index)) {
652 return FALSE;
653 }
654 }
655 opj_stream_destroy(l_stream);
656 l_stream = NULL;
657 if (image->color_space != OPJ_CLRSPC_SYCC && image->numcomps == 3 &&
658 image->comps[0].dx == image->comps[0].dy && image->comps[1].dx != 1) {
659 image->color_space = OPJ_CLRSPC_SYCC;
660 } else if (image->numcomps <= 2) {
661 image->color_space = OPJ_CLRSPC_GRAY;
662 }
663 if (image->color_space == OPJ_CLRSPC_SYCC) {
664 color_sycc_to_rgb(image);
665 }
666 if (image->icc_profile_buf && !image->useColorSpace) {
667 FX_Free(image->icc_profile_buf);
668 image->icc_profile_buf = NULL;
669 image->icc_profile_len = 0;
670 }
671 if (!image) {
672 return FALSE;
673 }
674 } catch (...) {
675 return FALSE;
676 }
677 return TRUE;
678 }
679 void CJPX_Decoder::GetInfo(FX_DWORD& width,
680 FX_DWORD& height,
681 FX_DWORD& codestream_nComps,
682 FX_DWORD& output_nComps) {
683 width = (FX_DWORD)image->x1;
684 height = (FX_DWORD)image->y1;
685 output_nComps = codestream_nComps = (FX_DWORD)image->numcomps;
686 }
687 FX_BOOL CJPX_Decoder::Decode(FX_LPBYTE dest_buf,
688 int pitch,
689 FX_BOOL bTranslateColor,
690 FX_LPBYTE offsets) {
691 FX_BYTE** channel_bufs;
692 int* adjust_comps;
693 int i, wid, hei, row, col, channel, src;
694 FX_BOOL flag;
695 FX_LPBYTE pChannel, pScanline, pPixel;
696 try {
697 if (image->comps[0].w != image->x1 || image->comps[0].h != image->y1) {
698 return FALSE;
699 }
700 if (pitch<(int)(image->comps[0].w * 8 * image->numcomps + 31)>> 5 << 2) {
701 return FALSE;
702 }
703 FXSYS_memset8(dest_buf, 0xff, image->y1 * pitch);
704 channel_bufs = FX_Alloc(FX_BYTE*, image->numcomps);
705 if (channel_bufs == NULL) {
706 return FALSE;
707 }
708 adjust_comps = FX_Alloc(int, image->numcomps);
709 if (adjust_comps == NULL) {
710 FX_Free(channel_bufs);
711 return FALSE;
712 }
713 flag = TRUE;
714 for (i = 0; i < (int)image->numcomps; i++) {
715 channel_bufs[i] = dest_buf + offsets[i];
716 adjust_comps[i] = image->comps[i].prec - 8;
717 if (i > 0) {
718 if (image->comps[i].dx != image->comps[i - 1].dx ||
719 image->comps[i].dy != image->comps[i - 1].dy ||
720 image->comps[i].prec != image->comps[i - 1].prec) {
721 flag = FALSE;
722 goto failed;
193 } 723 }
194 } 724 }
195 FX_Free(img->comps[0].data); 725 }
196 img->comps[0].data = d0; 726 wid = image->comps[0].w;
197 FX_Free(img->comps[1].data); 727 hei = image->comps[0].h;
198 img->comps[1].data = d1; 728 for (channel = 0; channel < (int)image->numcomps; channel++) {
199 FX_Free(img->comps[2].data); 729 pChannel = channel_bufs[channel];
200 img->comps[2].data = d2; 730 if (adjust_comps[channel] < 0) {
201 img->comps[1].w = maxw; 731 for (row = 0; row < hei; row++) {
202 img->comps[1].h = maxh; 732 pScanline = pChannel + row * pitch;
203 img->comps[2].w = maxw; 733 for (col = 0; col < wid; col++) {
204 img->comps[2].h = maxh; 734 pPixel = pScanline + col * image->numcomps;
205 img->comps[1].w = (OPJ_UINT32)maxw; 735 src = image->comps[channel].data[row * wid + col];
206 img->comps[1].h = (OPJ_UINT32)maxh; 736 src += image->comps[channel].sgnd
207 img->comps[2].w = (OPJ_UINT32)maxw; 737 ? 1 << (image->comps[channel].prec - 1)
208 img->comps[2].h = (OPJ_UINT32)maxh; 738 : 0;
209 img->comps[1].dx = img->comps[0].dx; 739 if (adjust_comps[channel] > 0) {
210 img->comps[2].dx = img->comps[0].dx; 740 *pPixel = 0;
211 img->comps[1].dy = img->comps[0].dy; 741 } else {
212 img->comps[2].dy = img->comps[0].dy; 742 *pPixel = (FX_BYTE)(src << -adjust_comps[channel]);
213 } 743 }
214 static void sycc420_to_rgb(opj_image_t *img) 744 }
215 {
216 int *d0, *d1, *d2, *r, *g, *b, *nr, *ng, *nb;
217 const int *y, *cb, *cr, *ny;
218 int maxw, maxh, max, offset, upb;
219 int i, j;
220 i = (int)img->comps[0].prec;
221 offset = 1 << (i - 1);
222 upb = (1 << i) - 1;
223 maxw = (int)img->comps[0].w;
224 maxh = (int)img->comps[0].h;
225 max = maxw * maxh;
226 y = img->comps[0].data;
227 cb = img->comps[1].data;
228 cr = img->comps[2].data;
229 d0 = r = FX_Alloc(int, (size_t)max);
230 d1 = g = FX_Alloc(int, (size_t)max);
231 d2 = b = FX_Alloc(int, (size_t)max);
232 for(i = 0; i < maxh; i += 2) {
233 ny = y + maxw;
234 nr = r + maxw;
235 ng = g + maxw;
236 nb = b + maxw;
237 for(j = 0; j < maxw; j += 2) {
238 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
239 ++y;
240 ++r;
241 ++g;
242 ++b;
243 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
244 ++y;
245 ++r;
246 ++g;
247 ++b;
248 sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
249 ++ny;
250 ++nr;
251 ++ng;
252 ++nb;
253 sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
254 ++ny;
255 ++nr;
256 ++ng;
257 ++nb;
258 ++cb;
259 ++cr;
260 } 745 }
261 y += maxw; 746 } else {
262 r += maxw; 747 for (row = 0; row < hei; row++) {
263 g += maxw; 748 pScanline = pChannel + row * pitch;
264 b += maxw; 749 for (col = 0; col < wid; col++) {
265 } 750 pPixel = pScanline + col * image->numcomps;
266 FX_Free(img->comps[0].data); 751 if (!image->comps[channel].data) {
267 img->comps[0].data = d0; 752 continue;
268 FX_Free(img->comps[1].data); 753 }
269 img->comps[1].data = d1; 754 src = image->comps[channel].data[row * wid + col];
270 FX_Free(img->comps[2].data); 755 src += image->comps[channel].sgnd
271 img->comps[2].data = d2; 756 ? 1 << (image->comps[channel].prec - 1)
272 img->comps[1].w = maxw; 757 : 0;
273 img->comps[1].h = maxh; 758 if (adjust_comps[channel] - 1 < 0) {
274 img->comps[2].w = maxw; 759 *pPixel = (FX_BYTE)((src >> adjust_comps[channel]));
275 img->comps[2].h = maxh; 760 } else {
276 img->comps[1].w = (OPJ_UINT32)maxw; 761 int tmpPixel = (src >> adjust_comps[channel]) +
277 img->comps[1].h = (OPJ_UINT32)maxh; 762 ((src >> (adjust_comps[channel] - 1)) % 2);
278 img->comps[2].w = (OPJ_UINT32)maxw; 763 if (tmpPixel > 255) {
279 img->comps[2].h = (OPJ_UINT32)maxh; 764 tmpPixel = 255;
280 img->comps[1].dx = img->comps[0].dx; 765 } else if (tmpPixel < 0) {
281 img->comps[2].dx = img->comps[0].dx; 766 tmpPixel = 0;
282 img->comps[1].dy = img->comps[0].dy; 767 }
283 img->comps[2].dy = img->comps[0].dy; 768 *pPixel = (FX_BYTE)tmpPixel;
284 } 769 }
285 void color_sycc_to_rgb(opj_image_t *img) 770 }
286 {
287 if(img->numcomps < 3) {
288 img->color_space = OPJ_CLRSPC_GRAY;
289 return;
290 }
291 if((img->comps[0].dx == 1)
292 && (img->comps[1].dx == 2)
293 && (img->comps[2].dx == 2)
294 && (img->comps[0].dy == 1)
295 && (img->comps[1].dy == 2)
296 && (img->comps[2].dy == 2)) {
297 sycc420_to_rgb(img);
298 } else if((img->comps[0].dx == 1)
299 && (img->comps[1].dx == 2)
300 && (img->comps[2].dx == 2)
301 && (img->comps[0].dy == 1)
302 && (img->comps[1].dy == 1)
303 && (img->comps[2].dy == 1)) {
304 sycc422_to_rgb(img);
305 } else if((img->comps[0].dx == 1)
306 && (img->comps[1].dx == 1)
307 && (img->comps[2].dx == 1)
308 && (img->comps[0].dy == 1)
309 && (img->comps[1].dy == 1)
310 && (img->comps[2].dy == 1)) {
311 sycc444_to_rgb(img);
312 } else {
313 return;
314 }
315 img->color_space = OPJ_CLRSPC_SRGB;
316 }
317 void color_apply_icc_profile(opj_image_t *image)
318 {
319 cmsHPROFILE in_prof, out_prof;
320 cmsHTRANSFORM transform;
321 cmsColorSpaceSignature in_space, out_space;
322 cmsUInt32Number intent, in_type, out_type, nr_samples;
323 int *r, *g, *b;
324 int prec, i, max, max_w, max_h;
325 OPJ_COLOR_SPACE oldspace;
326 in_prof =
327 cmsOpenProfileFromMem(image->icc_profile_buf, image->icc_profile_len);
328 if(in_prof == NULL) {
329 return;
330 }
331 in_space = cmsGetPCS(in_prof);
332 out_space = cmsGetColorSpace(in_prof);
333 intent = cmsGetHeaderRenderingIntent(in_prof);
334 max_w = (int)image->comps[0].w;
335 max_h = (int)image->comps[0].h;
336 prec = (int)image->comps[0].prec;
337 oldspace = image->color_space;
338 if(out_space == cmsSigRgbData) {
339 if( prec <= 8 ) {
340 in_type = TYPE_RGB_8;
341 out_type = TYPE_RGB_8;
342 } else {
343 in_type = TYPE_RGB_16;
344 out_type = TYPE_RGB_16;
345 } 771 }
346 out_prof = cmsCreate_sRGBProfile(); 772 }
347 image->color_space = OPJ_CLRSPC_SRGB; 773 }
348 } else if(out_space == cmsSigGrayData) { 774 } catch (...) {
349 if( prec <= 8 ) { 775 if (channel_bufs) {
350 in_type = TYPE_GRAY_8; 776 FX_Free(channel_bufs);
351 out_type = TYPE_RGB_8; 777 }
352 } else {
353 in_type = TYPE_GRAY_16;
354 out_type = TYPE_RGB_16;
355 }
356 out_prof = cmsCreate_sRGBProfile();
357 image->color_space = OPJ_CLRSPC_SRGB;
358 } else if(out_space == cmsSigYCbCrData) {
359 in_type = TYPE_YCbCr_16;
360 out_type = TYPE_RGB_16;
361 out_prof = cmsCreate_sRGBProfile();
362 image->color_space = OPJ_CLRSPC_SRGB;
363 } else {
364 return;
365 }
366 transform = cmsCreateTransform(in_prof, in_type,
367 out_prof, out_type, intent, 0);
368 cmsCloseProfile(in_prof);
369 cmsCloseProfile(out_prof);
370 if(transform == NULL) {
371 image->color_space = oldspace;
372 return;
373 }
374 if(image->numcomps > 2) {
375 if( prec <= 8 ) {
376 unsigned char *inbuf, *outbuf, *in, *out;
377 max = max_w * max_h;
378 nr_samples = (cmsUInt32Number)max * 3 * (cmsUInt32Number)sizeof(unsi gned char);
379 in = inbuf = FX_Alloc(unsigned char, nr_samples);
380 out = outbuf = FX_Alloc(unsigned char, nr_samples);
381 r = image->comps[0].data;
382 g = image->comps[1].data;
383 b = image->comps[2].data;
384 for(i = 0; i < max; ++i) {
385 *in++ = (unsigned char) * r++;
386 *in++ = (unsigned char) * g++;
387 *in++ = (unsigned char) * b++;
388 }
389 cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
390 r = image->comps[0].data;
391 g = image->comps[1].data;
392 b = image->comps[2].data;
393 for(i = 0; i < max; ++i) {
394 *r++ = (int) * out++;
395 *g++ = (int) * out++;
396 *b++ = (int) * out++;
397 }
398 FX_Free(inbuf);
399 FX_Free(outbuf);
400 } else {
401 unsigned short *inbuf, *outbuf, *in, *out;
402 max = max_w * max_h;
403 nr_samples = (cmsUInt32Number)max * 3 * (cmsUInt32Number)sizeof(unsi gned short);
404 in = inbuf = FX_Alloc(unsigned short, nr_samples);
405 out = outbuf = FX_Alloc(unsigned short, nr_samples);
406 r = image->comps[0].data;
407 g = image->comps[1].data;
408 b = image->comps[2].data;
409 for(i = 0; i < max; ++i) {
410 *in++ = (unsigned short) * r++;
411 *in++ = (unsigned short) * g++;
412 *in++ = (unsigned short) * b++;
413 }
414 cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
415 r = image->comps[0].data;
416 g = image->comps[1].data;
417 b = image->comps[2].data;
418 for(i = 0; i < max; ++i) {
419 *r++ = (int) * out++;
420 *g++ = (int) * out++;
421 *b++ = (int) * out++;
422 }
423 FX_Free(inbuf);
424 FX_Free(outbuf);
425 }
426 } else {
427 unsigned char *in, *inbuf, *out, *outbuf;
428 max = max_w * max_h;
429 nr_samples = (cmsUInt32Number)max * 3 * sizeof(unsigned char);
430 in = inbuf = FX_Alloc(unsigned char, nr_samples);
431 out = outbuf = FX_Alloc(unsigned char, nr_samples);
432 image->comps = (opj_image_comp_t*)
433 realloc(image->comps, (image->numcomps + 2) * sizeof(opj_ image_comp_t));
434 if(image->numcomps == 2) {
435 image->comps[3] = image->comps[1];
436 }
437 image->comps[1] = image->comps[0];
438 image->comps[2] = image->comps[0];
439 image->comps[1].data = FX_Alloc(int, (size_t)max);
440 FXSYS_memset8(image->comps[1].data, 0, sizeof(int) * (size_t)max);
441 image->comps[2].data = FX_Alloc(int, (size_t)max);
442 FXSYS_memset8(image->comps[2].data, 0, sizeof(int) * (size_t)max);
443 image->numcomps += 2;
444 r = image->comps[0].data;
445 for(i = 0; i < max; ++i) {
446 *in++ = (unsigned char) * r++;
447 }
448 cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
449 r = image->comps[0].data;
450 g = image->comps[1].data;
451 b = image->comps[2].data;
452 for(i = 0; i < max; ++i) {
453 *r++ = (int) * out++;
454 *g++ = (int) * out++;
455 *b++ = (int) * out++;
456 }
457 FX_Free(inbuf);
458 FX_Free(outbuf);
459 }
460 cmsDeleteTransform(transform);
461 }
462 void color_apply_conversion(opj_image_t *image)
463 {
464 int *row;
465 int enumcs, numcomps;
466 numcomps = image->numcomps;
467 if(numcomps < 3) {
468 return;
469 }
470 row = (int*)image->icc_profile_buf;
471 enumcs = row[0];
472 if(enumcs == 14) {
473 int *L, *a, *b, *red, *green, *blue, *src0, *src1, *src2;
474 double rl, ol, ra, oa, rb, ob, prec0, prec1, prec2;
475 double minL, maxL, mina, maxa, minb, maxb;
476 unsigned int default_type, il;
477 unsigned int i, max, illu;
478 cmsHPROFILE in, out;
479 cmsHTRANSFORM transform;
480 cmsUInt16Number RGB[3];
481 cmsCIELab Lab;
482 illu = 0;
483 il = 0;
484 in = cmsCreateLab4Profile(NULL);
485 out = cmsCreate_sRGBProfile();
486 transform =
487 cmsCreateTransform(in, TYPE_Lab_DBL, out, TYPE_RGB_16,
488 INTENT_PERCEPTUAL, 0);
489 cmsCloseProfile(in);
490 cmsCloseProfile(out);
491 if(transform == NULL) {
492 return;
493 }
494 prec0 = (double)image->comps[0].prec;
495 prec1 = (double)image->comps[1].prec;
496 prec2 = (double)image->comps[2].prec;
497 default_type = row[1];
498 if(default_type == 0x44454600) {
499 rl = 100;
500 ra = 170;
501 rb = 200;
502 ol = 0;
503 oa = pow(2, prec1 - 1);
504 ob = pow(2, prec2 - 2) + pow(2, prec2 - 3);
505 } else {
506 rl = row[2];
507 ra = row[4];
508 rb = row[6];
509 ol = row[3];
510 oa = row[5];
511 ob = row[7];
512 }
513 L = src0 = image->comps[0].data;
514 a = src1 = image->comps[1].data;
515 b = src2 = image->comps[2].data;
516 max = image->comps[0].w * image->comps[0].h;
517 red = FX_Alloc(int, max);
518 image->comps[0].data = red;
519 green = FX_Alloc(int, max);
520 image->comps[1].data = green;
521 blue = FX_Alloc(int, max);
522 image->comps[2].data = blue;
523 minL = -(rl * ol) / (pow(2, prec0) - 1);
524 maxL = minL + rl;
525 mina = -(ra * oa) / (pow(2, prec1) - 1);
526 maxa = mina + ra;
527 minb = -(rb * ob) / (pow(2, prec2) - 1);
528 maxb = minb + rb;
529 for(i = 0; i < max; ++i) {
530 Lab.L = minL + (double)(*L) * (maxL - minL) / (pow(2, prec0) - 1);
531 ++L;
532 Lab.a = mina + (double)(*a) * (maxa - mina) / (pow(2, prec1) - 1);
533 ++a;
534 Lab.b = minb + (double)(*b) * (maxb - minb) / (pow(2, prec2) - 1);
535 ++b;
536 cmsDoTransform(transform, &Lab, RGB, 1);
537 *red++ = RGB[0];
538 *green++ = RGB[1];
539 *blue++ = RGB[2];
540 }
541 cmsDeleteTransform(transform);
542 FX_Free(src0);
543 FX_Free(src1);
544 FX_Free(src2);
545 image->color_space = OPJ_CLRSPC_SRGB;
546 image->comps[0].prec = 16;
547 image->comps[1].prec = 16;
548 image->comps[2].prec = 16;
549 return;
550 }
551 }
552 class CJPX_Decoder : public CFX_Object
553 {
554 public:
555 CJPX_Decoder();
556 ~CJPX_Decoder();
557 FX_BOOL Init(const unsigned char* src_data, int src_size);
558 void GetInfo(FX_DWORD& width, FX_DWORD& height, FX_DWORD& codestream_ nComps, FX_DWORD& output_nComps);
559 FX_BOOL Decode(FX_LPBYTE dest_buf, int pitch, FX_BOOL bTranslateColor, F X_LPBYTE offsets);
560 FX_LPCBYTE m_SrcData;
561 int m_SrcSize;
562 opj_image_t *image;
563 opj_codec_t* l_codec;
564 opj_stream_t *l_stream;
565 FX_BOOL m_useColorSpace;
566 };
567 CJPX_Decoder::CJPX_Decoder(): image(NULL), l_codec(NULL), l_stream(NULL), m_useC olorSpace(FALSE)
568 {
569 }
570 CJPX_Decoder::~CJPX_Decoder()
571 {
572 if(l_codec) {
573 opj_destroy_codec(l_codec);
574 }
575 if(l_stream) {
576 opj_stream_destroy(l_stream);
577 }
578 if(image) {
579 opj_image_destroy(image);
580 }
581 }
582 FX_BOOL CJPX_Decoder::Init(const unsigned char* src_data, int src_size)
583 {
584 opj_dparameters_t parameters;
585 try {
586 image = NULL;
587 m_SrcData = src_data;
588 m_SrcSize = src_size;
589 decodeData srcData;
590 srcData.offset = 0;
591 srcData.src_size = src_size;
592 srcData.src_data = src_data;
593 l_stream = fx_opj_stream_create_memory_stream(&srcData, OPJ_J2K_STREAM_C HUNK_SIZE, 1);
594 if (l_stream == NULL) {
595 return FALSE;
596 }
597 opj_set_default_decoder_parameters(&parameters);
598 parameters.decod_format = 0;
599 parameters.cod_format = 3;
600 if(FXSYS_memcmp32(m_SrcData, "\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x 87\x0a", 12) == 0) {
601 l_codec = opj_create_decompress(OPJ_CODEC_JP2);
602 parameters.decod_format = 1;
603 } else {
604 l_codec = opj_create_decompress(OPJ_CODEC_J2K);
605 }
606 if(!l_codec) {
607 return FALSE;
608 }
609 opj_set_info_handler(l_codec, fx_info_callback, 00);
610 opj_set_warning_handler(l_codec, fx_warning_callback, 00);
611 opj_set_error_handler(l_codec, fx_error_callback, 00);
612 if ( !opj_setup_decoder(l_codec, &parameters) ) {
613 return FALSE;
614 }
615 if(! opj_read_header(l_stream, l_codec, &image)) {
616 image = NULL;
617 return FALSE;
618 }
619 if(this->m_useColorSpace) {
620 image->useColorSpace = 1;
621 } else {
622 image->useColorSpace = 0;
623 }
624 if (!parameters.nb_tile_to_decode) {
625 if (!opj_set_decode_area(l_codec, image, parameters.DA_x0,
626 parameters.DA_y0, parameters.DA_x1, paramet ers.DA_y1)) {
627 opj_image_destroy(image);
628 image = NULL;
629 return FALSE;
630 }
631 if (!(opj_decode(l_codec, l_stream, image) && opj_end_decompress(l_c odec, l_stream))) {
632 opj_image_destroy(image);
633 image = NULL;
634 return FALSE;
635 }
636 } else {
637 if (!opj_get_decoded_tile(l_codec, l_stream, image, parameters.tile_ index)) {
638 return FALSE;
639 }
640 }
641 opj_stream_destroy(l_stream);
642 l_stream = NULL;
643 if( image->color_space != OPJ_CLRSPC_SYCC
644 && image->numcomps == 3 && image->comps[0].dx == image->comps[0] .dy
645 && image->comps[1].dx != 1 ) {
646 image->color_space = OPJ_CLRSPC_SYCC;
647 } else if (image->numcomps <= 2) {
648 image->color_space = OPJ_CLRSPC_GRAY;
649 }
650 if(image->color_space == OPJ_CLRSPC_SYCC) {
651 color_sycc_to_rgb(image);
652 }
653 if(image->icc_profile_buf && !image->useColorSpace) {
654 FX_Free(image->icc_profile_buf);
655 image->icc_profile_buf = NULL;
656 image->icc_profile_len = 0;
657 }
658 if(!image) {
659 return FALSE;
660 }
661 } catch (...) {
662 return FALSE;
663 }
664 return TRUE;
665 }
666 void CJPX_Decoder::GetInfo(FX_DWORD& width, FX_DWORD& height, FX_DWORD& codestre am_nComps, FX_DWORD& output_nComps)
667 {
668 width = (FX_DWORD)image->x1;
669 height = (FX_DWORD)image->y1;
670 output_nComps = codestream_nComps = (FX_DWORD)image->numcomps;
671 }
672 FX_BOOL CJPX_Decoder::Decode(FX_LPBYTE dest_buf, int pitch, FX_BOOL bTranslateCo lor, FX_LPBYTE offsets)
673 {
674 FX_BYTE** channel_bufs;
675 int* adjust_comps;
676 int i, wid, hei, row, col, channel, src;
677 FX_BOOL flag;
678 FX_LPBYTE pChannel, pScanline, pPixel;
679 try {
680 if(image->comps[0].w != image->x1 || image->comps[0].h != image->y1) {
681 return FALSE;
682 }
683 if(pitch < (int)(image->comps[0].w * 8 * image->numcomps + 31) >> 5 << 2 ) {
684 return FALSE;
685 }
686 FXSYS_memset8(dest_buf, 0xff, image->y1 * pitch);
687 channel_bufs = FX_Alloc(FX_BYTE*, image->numcomps);
688 if (channel_bufs == NULL) {
689 return FALSE;
690 }
691 adjust_comps = FX_Alloc(int, image->numcomps);
692 if (adjust_comps == NULL) {
693 FX_Free(channel_bufs);
694 return FALSE;
695 }
696 flag = TRUE;
697 for (i = 0; i < (int)image->numcomps; i ++) {
698 channel_bufs[i] = dest_buf + offsets[i];
699 adjust_comps[i] = image->comps[i].prec - 8;
700 if(i > 0) {
701 if(image->comps[i].dx != image->comps[i - 1].dx
702 || image->comps[i].dy != image->comps[i - 1].dy
703 || image->comps[i].prec != image->comps[i - 1].prec) {
704 flag = FALSE;
705 goto failed;
706 }
707 }
708 }
709 wid = image->comps[0].w;
710 hei = image->comps[0].h;
711 for (channel = 0; channel < (int)image->numcomps; channel++) {
712 pChannel = channel_bufs[channel];
713 if(adjust_comps[channel] < 0) {
714 for(row = 0; row < hei; row++) {
715 pScanline = pChannel + row * pitch;
716 for (col = 0; col < wid; col++) {
717 pPixel = pScanline + col * image->numcomps;
718 src = image->comps[channel].data[row * wid + col];
719 src += image->comps[channel].sgnd ? 1 << (image->comps[c hannel].prec - 1) : 0;
720 if (adjust_comps[channel] > 0) {
721 *pPixel = 0;
722 } else {
723 *pPixel = (FX_BYTE)(src << -adjust_comps[channel]);
724 }
725 }
726 }
727 } else {
728 for(row = 0; row < hei; row++) {
729 pScanline = pChannel + row * pitch;
730 for (col = 0; col < wid; col++) {
731 pPixel = pScanline + col * image->numcomps;
732 if (!image->comps[channel].data) {
733 continue;
734 }
735 src = image->comps[channel].data[row * wid + col];
736 src += image->comps[channel].sgnd ? 1 << (image->comps[c hannel].prec - 1) : 0;
737 if (adjust_comps[channel] - 1 < 0) {
738 *pPixel = (FX_BYTE)((src >> adjust_comps[channel]));
739 } else {
740 int tmpPixel = (src >> adjust_comps[channel]) + ((sr c >> (adjust_comps[channel] - 1)) % 2);
741 if (tmpPixel > 255) {
742 tmpPixel = 255;
743 } else if (tmpPixel < 0) {
744 tmpPixel = 0;
745 }
746 *pPixel = (FX_BYTE)tmpPixel;
747 }
748 }
749 }
750 }
751 }
752 } catch (...) {
753 if (channel_bufs) {
754 FX_Free(channel_bufs);
755 }
756 FX_Free(adjust_comps);
757 return FALSE;
758 }
759 FX_Free(channel_bufs);
760 FX_Free(adjust_comps);
761 return TRUE;
762 failed:
763 FX_Free(channel_bufs);
764 FX_Free(adjust_comps); 778 FX_Free(adjust_comps);
765 return FALSE; 779 return FALSE;
780 }
781 FX_Free(channel_bufs);
782 FX_Free(adjust_comps);
783 return TRUE;
784 failed:
785 FX_Free(channel_bufs);
786 FX_Free(adjust_comps);
787 return FALSE;
766 } 788 }
767 void initialize_transition_table(); 789 void initialize_transition_table();
768 void initialize_significance_luts(); 790 void initialize_significance_luts();
769 void initialize_sign_lut(); 791 void initialize_sign_lut();
770 CCodec_JpxModule::CCodec_JpxModule() 792 CCodec_JpxModule::CCodec_JpxModule() {
771 { 793 }
772 } 794 void* CCodec_JpxModule::CreateDecoder(FX_LPCBYTE src_buf,
773 void* CCodec_JpxModule::CreateDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size , FX _BOOL useColorSpace) 795 FX_DWORD src_size,
774 { 796 FX_BOOL useColorSpace) {
775 CJPX_Decoder* pDecoder = FX_NEW CJPX_Decoder; 797 CJPX_Decoder* pDecoder = FX_NEW CJPX_Decoder;
776 if (pDecoder == NULL) { 798 if (pDecoder == NULL) {
777 return NULL; 799 return NULL;
778 } 800 }
779 pDecoder->m_useColorSpace = useColorSpace; 801 pDecoder->m_useColorSpace = useColorSpace;
780 if (!pDecoder->Init(src_buf, src_size)) { 802 if (!pDecoder->Init(src_buf, src_size)) {
781 delete pDecoder;
782 return NULL;
783 }
784 return pDecoder;
785 }
786 void CCodec_JpxModule::GetImageInfo(FX_LPVOID ctx, FX_DWORD& width, FX_DWORD& he ight,
787 FX_DWORD& codestream_nComps, FX_DWORD& outpu t_nComps)
788 {
789 CJPX_Decoder* pDecoder = (CJPX_Decoder*)ctx;
790 pDecoder->GetInfo(width, height, codestream_nComps, output_nComps);
791 }
792 FX_BOOL CCodec_JpxModule::Decode(void* ctx, FX_LPBYTE dest_data, int pitch, FX_B OOL bTranslateColor, FX_LPBYTE offsets)
793 {
794 CJPX_Decoder* pDecoder = (CJPX_Decoder*)ctx;
795 return pDecoder->Decode(dest_data, pitch, bTranslateColor, offsets);
796 }
797 void CCodec_JpxModule::DestroyDecoder(void* ctx)
798 {
799 CJPX_Decoder* pDecoder = (CJPX_Decoder*)ctx;
800 delete pDecoder; 803 delete pDecoder;
801 } 804 return NULL;
805 }
806 return pDecoder;
807 }
808 void CCodec_JpxModule::GetImageInfo(FX_LPVOID ctx,
809 FX_DWORD& width,
810 FX_DWORD& height,
811 FX_DWORD& codestream_nComps,
812 FX_DWORD& output_nComps) {
813 CJPX_Decoder* pDecoder = (CJPX_Decoder*)ctx;
814 pDecoder->GetInfo(width, height, codestream_nComps, output_nComps);
815 }
816 FX_BOOL CCodec_JpxModule::Decode(void* ctx,
817 FX_LPBYTE dest_data,
818 int pitch,
819 FX_BOOL bTranslateColor,
820 FX_LPBYTE offsets) {
821 CJPX_Decoder* pDecoder = (CJPX_Decoder*)ctx;
822 return pDecoder->Decode(dest_data, pitch, bTranslateColor, offsets);
823 }
824 void CCodec_JpxModule::DestroyDecoder(void* ctx) {
825 CJPX_Decoder* pDecoder = (CJPX_Decoder*)ctx;
826 delete pDecoder;
827 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698