OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C)2009-2012, 2014 D. R. Commander. All Rights Reserved. | 2 * Copyright (C)2009-2016 D. R. Commander. All Rights Reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are met: | 5 * modification, are permitted provided that the following conditions are met: |
6 * | 6 * |
7 * - Redistributions of source code must retain the above copyright notice, | 7 * - Redistributions of source code must retain the above copyright notice, |
8 * this list of conditions and the following disclaimer. | 8 * this list of conditions and the following disclaimer. |
9 * - Redistributions in binary form must reproduce the above copyright notice, | 9 * - Redistributions in binary form must reproduce the above copyright notice, |
10 * this list of conditions and the following disclaimer in the documentation | 10 * this list of conditions and the following disclaimer in the documentation |
11 * and/or other materials provided with the distribution. | 11 * and/or other materials provided with the distribution. |
12 * - Neither the name of the libjpeg-turbo Project nor the names of its | 12 * - Neither the name of the libjpeg-turbo Project nor the names of its |
(...skipping 11 matching lines...) Expand all Loading... |
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 * POSSIBILITY OF SUCH DAMAGE. | 26 * POSSIBILITY OF SUCH DAMAGE. |
27 */ | 27 */ |
28 | 28 |
29 /* TurboJPEG/LJT: this implements the TurboJPEG API using libjpeg or | 29 /* TurboJPEG/LJT: this implements the TurboJPEG API using libjpeg or |
30 libjpeg-turbo */ | 30 libjpeg-turbo */ |
31 | 31 |
32 #include <stdio.h> | 32 #include <stdio.h> |
33 #include <stdlib.h> | 33 #include <stdlib.h> |
| 34 #include <ctype.h> |
34 #include <jinclude.h> | 35 #include <jinclude.h> |
35 #define JPEG_INTERNALS | 36 #define JPEG_INTERNALS |
36 #include <jpeglib.h> | 37 #include <jpeglib.h> |
37 #include <jerror.h> | 38 #include <jerror.h> |
38 #include <setjmp.h> | 39 #include <setjmp.h> |
39 #include "./turbojpeg.h" | 40 #include "./turbojpeg.h" |
40 #include "./tjutil.h" | 41 #include "./tjutil.h" |
41 #include "transupp.h" | 42 #include "transupp.h" |
| 43 #include "./jpegcomp.h" |
42 | 44 |
43 extern void jpeg_mem_dest_tj(j_compress_ptr, unsigned char **, | 45 extern void jpeg_mem_dest_tj(j_compress_ptr, unsigned char **, |
44 unsigned long *, boolean); | 46 unsigned long *, boolean); |
45 extern void jpeg_mem_src_tj(j_decompress_ptr, unsigned char *, unsigned long); | 47 extern void jpeg_mem_src_tj(j_decompress_ptr, const unsigned char *, |
| 48 » unsigned long); |
46 | 49 |
47 #define PAD(v, p) ((v+(p)-1)&(~((p)-1))) | 50 #define PAD(v, p) ((v+(p)-1)&(~((p)-1))) |
| 51 #define isPow2(x) (((x)&(x-1))==0) |
48 | 52 |
49 | 53 |
50 /* Error handling (based on example in example.c) */ | 54 /* Error handling (based on example in example.c) */ |
51 | 55 |
52 static char errStr[JMSG_LENGTH_MAX]="No error"; | 56 static char errStr[JMSG_LENGTH_MAX]="No error"; |
53 | 57 |
54 struct my_error_mgr | 58 struct my_error_mgr |
55 { | 59 { |
56 struct jpeg_error_mgr pub; | 60 struct jpeg_error_mgr pub; |
57 jmp_buf setjmp_buffer; | 61 jmp_buf setjmp_buffer; |
| 62 void (*emit_message)(j_common_ptr, int); |
| 63 boolean warning; |
58 }; | 64 }; |
59 typedef struct my_error_mgr *my_error_ptr; | 65 typedef struct my_error_mgr *my_error_ptr; |
60 | 66 |
61 static void my_error_exit(j_common_ptr cinfo) | 67 static void my_error_exit(j_common_ptr cinfo) |
62 { | 68 { |
63 my_error_ptr myerr=(my_error_ptr)cinfo->err; | 69 my_error_ptr myerr=(my_error_ptr)cinfo->err; |
64 (*cinfo->err->output_message)(cinfo); | 70 (*cinfo->err->output_message)(cinfo); |
65 longjmp(myerr->setjmp_buffer, 1); | 71 longjmp(myerr->setjmp_buffer, 1); |
66 } | 72 } |
67 | 73 |
68 /* Based on output_message() in jerror.c */ | 74 /* Based on output_message() in jerror.c */ |
69 | 75 |
70 static void my_output_message(j_common_ptr cinfo) | 76 static void my_output_message(j_common_ptr cinfo) |
71 { | 77 { |
72 (*cinfo->err->format_message)(cinfo, errStr); | 78 (*cinfo->err->format_message)(cinfo, errStr); |
73 } | 79 } |
74 | 80 |
| 81 static void my_emit_message(j_common_ptr cinfo, int msg_level) |
| 82 { |
| 83 my_error_ptr myerr=(my_error_ptr)cinfo->err; |
| 84 myerr->emit_message(cinfo, msg_level); |
| 85 if(msg_level<0) myerr->warning=TRUE; |
| 86 } |
| 87 |
75 | 88 |
76 /* Global structures, macros, etc. */ | 89 /* Global structures, macros, etc. */ |
77 | 90 |
78 enum {COMPRESS=1, DECOMPRESS=2}; | 91 enum {COMPRESS=1, DECOMPRESS=2}; |
79 | 92 |
80 typedef struct _tjinstance | 93 typedef struct _tjinstance |
81 { | 94 { |
82 struct jpeg_compress_struct cinfo; | 95 struct jpeg_compress_struct cinfo; |
83 struct jpeg_decompress_struct dinfo; | 96 struct jpeg_decompress_struct dinfo; |
84 struct my_error_mgr jerr; | 97 struct my_error_mgr jerr; |
85 » int init; | 98 » int init, headerRead; |
86 } tjinstance; | 99 } tjinstance; |
87 | 100 |
88 static const int pixelsize[TJ_NUMSAMP]={3, 3, 3, 1, 3}; | 101 static const int pixelsize[TJ_NUMSAMP]={3, 3, 3, 1, 3, 3}; |
89 | 102 |
90 static const JXFORM_CODE xformtypes[TJ_NUMXOP]= | 103 static const JXFORM_CODE xformtypes[TJ_NUMXOP]= |
91 { | 104 { |
92 JXFORM_NONE, JXFORM_FLIP_H, JXFORM_FLIP_V, JXFORM_TRANSPOSE, | 105 JXFORM_NONE, JXFORM_FLIP_H, JXFORM_FLIP_V, JXFORM_TRANSPOSE, |
93 JXFORM_TRANSVERSE, JXFORM_ROT_90, JXFORM_ROT_180, JXFORM_ROT_270 | 106 JXFORM_TRANSVERSE, JXFORM_ROT_90, JXFORM_ROT_180, JXFORM_ROT_270 |
94 }; | 107 }; |
95 | 108 |
96 #define NUMSF 16 | 109 #define NUMSF 16 |
97 static const tjscalingfactor sf[NUMSF]={ | 110 static const tjscalingfactor sf[NUMSF]={ |
98 {2, 1}, | 111 {2, 1}, |
(...skipping 13 matching lines...) Expand all Loading... |
112 {1, 4}, | 125 {1, 4}, |
113 {1, 8} | 126 {1, 8} |
114 }; | 127 }; |
115 | 128 |
116 #define _throw(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s", m); \ | 129 #define _throw(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s", m); \ |
117 retval=-1; goto bailout;} | 130 retval=-1; goto bailout;} |
118 #define getinstance(handle) tjinstance *this=(tjinstance *)handle; \ | 131 #define getinstance(handle) tjinstance *this=(tjinstance *)handle; \ |
119 j_compress_ptr cinfo=NULL; j_decompress_ptr dinfo=NULL; \ | 132 j_compress_ptr cinfo=NULL; j_decompress_ptr dinfo=NULL; \ |
120 if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ | 133 if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ |
121 return -1;} \ | 134 return -1;} \ |
122 » cinfo=&this->cinfo; dinfo=&this->dinfo; | 135 » cinfo=&this->cinfo; dinfo=&this->dinfo; \ |
| 136 » this->jerr.warning=FALSE; |
| 137 #define getcinstance(handle) tjinstance *this=(tjinstance *)handle; \ |
| 138 » j_compress_ptr cinfo=NULL; \ |
| 139 » if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ |
| 140 » » return -1;} \ |
| 141 » cinfo=&this->cinfo; \ |
| 142 » this->jerr.warning=FALSE; |
| 143 #define getdinstance(handle) tjinstance *this=(tjinstance *)handle; \ |
| 144 » j_decompress_ptr dinfo=NULL; \ |
| 145 » if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ |
| 146 » » return -1;} \ |
| 147 » dinfo=&this->dinfo; \ |
| 148 » this->jerr.warning=FALSE; |
123 | 149 |
124 static int getPixelFormat(int pixelSize, int flags) | 150 static int getPixelFormat(int pixelSize, int flags) |
125 { | 151 { |
126 if(pixelSize==1) return TJPF_GRAY; | 152 if(pixelSize==1) return TJPF_GRAY; |
127 if(pixelSize==3) | 153 if(pixelSize==3) |
128 { | 154 { |
129 if(flags&TJ_BGR) return TJPF_BGR; | 155 if(flags&TJ_BGR) return TJPF_BGR; |
130 else return TJPF_RGB; | 156 else return TJPF_RGB; |
131 } | 157 } |
132 if(pixelSize==4) | 158 if(pixelSize==4) |
133 { | 159 { |
134 if(flags&TJ_ALPHAFIRST) | 160 if(flags&TJ_ALPHAFIRST) |
135 { | 161 { |
136 if(flags&TJ_BGR) return TJPF_XBGR; | 162 if(flags&TJ_BGR) return TJPF_XBGR; |
137 else return TJPF_XRGB; | 163 else return TJPF_XRGB; |
138 } | 164 } |
139 else | 165 else |
140 { | 166 { |
141 if(flags&TJ_BGR) return TJPF_BGRX; | 167 if(flags&TJ_BGR) return TJPF_BGRX; |
142 else return TJPF_RGBX; | 168 else return TJPF_RGBX; |
143 } | 169 } |
144 } | 170 } |
145 return -1; | 171 return -1; |
146 } | 172 } |
147 | 173 |
148 static int setCompDefaults(struct jpeg_compress_struct *cinfo, | 174 static int setCompDefaults(struct jpeg_compress_struct *cinfo, |
149 int pixelFormat, int subsamp, int jpegQual, int flags) | 175 int pixelFormat, int subsamp, int jpegQual, int flags) |
150 { | 176 { |
151 int retval=0; | 177 int retval=0; |
| 178 char *env=NULL; |
152 | 179 |
153 switch(pixelFormat) | 180 switch(pixelFormat) |
154 { | 181 { |
155 case TJPF_GRAY: | 182 case TJPF_GRAY: |
156 cinfo->in_color_space=JCS_GRAYSCALE; break; | 183 cinfo->in_color_space=JCS_GRAYSCALE; break; |
157 #if JCS_EXTENSIONS==1 | 184 #if JCS_EXTENSIONS==1 |
158 case TJPF_RGB: | 185 case TJPF_RGB: |
159 cinfo->in_color_space=JCS_EXT_RGB; break; | 186 cinfo->in_color_space=JCS_EXT_RGB; break; |
160 case TJPF_BGR: | 187 case TJPF_BGR: |
161 cinfo->in_color_space=JCS_EXT_BGR; break; | 188 cinfo->in_color_space=JCS_EXT_BGR; break; |
(...skipping 16 matching lines...) Expand all Loading... |
178 case TJPF_BGRX: | 205 case TJPF_BGRX: |
179 case TJPF_XRGB: | 206 case TJPF_XRGB: |
180 case TJPF_XBGR: | 207 case TJPF_XBGR: |
181 case TJPF_RGBA: | 208 case TJPF_RGBA: |
182 case TJPF_BGRA: | 209 case TJPF_BGRA: |
183 case TJPF_ARGB: | 210 case TJPF_ARGB: |
184 case TJPF_ABGR: | 211 case TJPF_ABGR: |
185 cinfo->in_color_space=JCS_RGB; pixelFormat=TJPF_RGB; | 212 cinfo->in_color_space=JCS_RGB; pixelFormat=TJPF_RGB; |
186 break; | 213 break; |
187 #endif | 214 #endif |
| 215 case TJPF_CMYK: |
| 216 cinfo->in_color_space=JCS_CMYK; break; |
188 } | 217 } |
189 | 218 |
190 cinfo->input_components=tjPixelSize[pixelFormat]; | 219 cinfo->input_components=tjPixelSize[pixelFormat]; |
191 jpeg_set_defaults(cinfo); | 220 jpeg_set_defaults(cinfo); |
| 221 |
| 222 #ifndef NO_GETENV |
| 223 if((env=getenv("TJ_OPTIMIZE"))!=NULL && strlen(env)>0 && !strcmp(env, "1
")) |
| 224 cinfo->optimize_coding=TRUE; |
| 225 if((env=getenv("TJ_ARITHMETIC"))!=NULL && strlen(env)>0 && !strcmp(env,
"1")) |
| 226 cinfo->arith_code=TRUE; |
| 227 if((env=getenv("TJ_RESTART"))!=NULL && strlen(env)>0) |
| 228 { |
| 229 int temp=-1; char tempc=0; |
| 230 if(sscanf(env, "%d%c", &temp, &tempc)>=1 && temp>=0 && temp<=655
35) |
| 231 { |
| 232 if(toupper(tempc)=='B') |
| 233 { |
| 234 cinfo->restart_interval=temp; |
| 235 cinfo->restart_in_rows=0; |
| 236 } |
| 237 else |
| 238 cinfo->restart_in_rows=temp; |
| 239 } |
| 240 } |
| 241 #endif |
| 242 |
192 if(jpegQual>=0) | 243 if(jpegQual>=0) |
193 { | 244 { |
194 jpeg_set_quality(cinfo, jpegQual, TRUE); | 245 jpeg_set_quality(cinfo, jpegQual, TRUE); |
195 if(jpegQual>=96 || flags&TJFLAG_ACCURATEDCT) cinfo->dct_method=J
DCT_ISLOW; | 246 if(jpegQual>=96 || flags&TJFLAG_ACCURATEDCT) cinfo->dct_method=J
DCT_ISLOW; |
196 else cinfo->dct_method=JDCT_FASTEST; | 247 else cinfo->dct_method=JDCT_FASTEST; |
197 } | 248 } |
198 if(subsamp==TJSAMP_GRAY) | 249 if(subsamp==TJSAMP_GRAY) |
199 jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); | 250 jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); |
200 » else | 251 » else if(pixelFormat==TJPF_CMYK) |
201 » » jpeg_set_colorspace(cinfo, JCS_YCbCr); | 252 » » jpeg_set_colorspace(cinfo, JCS_YCCK); |
| 253 » else jpeg_set_colorspace(cinfo, JCS_YCbCr); |
| 254 |
| 255 #ifndef NO_GETENV |
| 256 » if((env=getenv("TJ_PROGRESSIVE"))!=NULL && strlen(env)>0 |
| 257 » » && !strcmp(env, "1")) |
| 258 » » jpeg_simple_progression(cinfo); |
| 259 #endif |
202 | 260 |
203 cinfo->comp_info[0].h_samp_factor=tjMCUWidth[subsamp]/8; | 261 cinfo->comp_info[0].h_samp_factor=tjMCUWidth[subsamp]/8; |
204 cinfo->comp_info[1].h_samp_factor=1; | 262 cinfo->comp_info[1].h_samp_factor=1; |
205 cinfo->comp_info[2].h_samp_factor=1; | 263 cinfo->comp_info[2].h_samp_factor=1; |
| 264 if(cinfo->num_components>3) |
| 265 cinfo->comp_info[3].h_samp_factor=tjMCUWidth[subsamp]/8; |
206 cinfo->comp_info[0].v_samp_factor=tjMCUHeight[subsamp]/8; | 266 cinfo->comp_info[0].v_samp_factor=tjMCUHeight[subsamp]/8; |
207 cinfo->comp_info[1].v_samp_factor=1; | 267 cinfo->comp_info[1].v_samp_factor=1; |
208 cinfo->comp_info[2].v_samp_factor=1; | 268 cinfo->comp_info[2].v_samp_factor=1; |
| 269 if(cinfo->num_components>3) |
| 270 cinfo->comp_info[3].v_samp_factor=tjMCUHeight[subsamp]/8; |
209 | 271 |
210 return retval; | 272 return retval; |
211 } | 273 } |
212 | 274 |
213 static int setDecompDefaults(struct jpeg_decompress_struct *dinfo, | 275 static int setDecompDefaults(struct jpeg_decompress_struct *dinfo, |
214 int pixelFormat, int flags) | 276 int pixelFormat, int flags) |
215 { | 277 { |
216 int retval=0; | 278 int retval=0; |
217 | 279 |
218 switch(pixelFormat) | 280 switch(pixelFormat) |
(...skipping 29 matching lines...) Expand all Loading... |
248 case TJPF_RGBX: | 310 case TJPF_RGBX: |
249 case TJPF_BGRX: | 311 case TJPF_BGRX: |
250 case TJPF_XRGB: | 312 case TJPF_XRGB: |
251 case TJPF_XBGR: | 313 case TJPF_XBGR: |
252 case TJPF_RGBA: | 314 case TJPF_RGBA: |
253 case TJPF_BGRA: | 315 case TJPF_BGRA: |
254 case TJPF_ARGB: | 316 case TJPF_ARGB: |
255 case TJPF_ABGR: | 317 case TJPF_ABGR: |
256 dinfo->out_color_space=JCS_RGB; break; | 318 dinfo->out_color_space=JCS_RGB; break; |
257 #endif | 319 #endif |
| 320 case TJPF_CMYK: |
| 321 dinfo->out_color_space=JCS_CMYK; break; |
258 default: | 322 default: |
259 _throw("Unsupported pixel format"); | 323 _throw("Unsupported pixel format"); |
260 } | 324 } |
261 | 325 |
262 if(flags&TJFLAG_FASTDCT) dinfo->dct_method=JDCT_FASTEST; | 326 if(flags&TJFLAG_FASTDCT) dinfo->dct_method=JDCT_FASTEST; |
263 | 327 |
264 bailout: | 328 bailout: |
265 return retval; | 329 return retval; |
266 } | 330 } |
267 | 331 |
268 | 332 |
269 static int getSubsamp(j_decompress_ptr dinfo) | 333 static int getSubsamp(j_decompress_ptr dinfo) |
270 { | 334 { |
271 int retval=-1, i, k; | 335 int retval=-1, i, k; |
| 336 |
| 337 /* The sampling factors actually have no meaning with grayscale JPEG fil
es, |
| 338 and in fact it's possible to generate grayscale JPEGs with sampling |
| 339 factors > 1 (even though those sampling factors are ignored by the |
| 340 decompressor.) Thus, we need to treat grayscale as a special case. *
/ |
| 341 if(dinfo->num_components==1 && dinfo->jpeg_color_space==JCS_GRAYSCALE) |
| 342 return TJSAMP_GRAY; |
| 343 |
272 for(i=0; i<NUMSUBOPT; i++) | 344 for(i=0; i<NUMSUBOPT; i++) |
273 { | 345 { |
274 » » if(dinfo->num_components==pixelsize[i]) | 346 » » if(dinfo->num_components==pixelsize[i] |
| 347 » » » || ((dinfo->jpeg_color_space==JCS_YCCK |
| 348 » » » » || dinfo->jpeg_color_space==JCS_CMYK) |
| 349 » » » » » && pixelsize[i]==3 && dinfo->num_compone
nts==4)) |
275 { | 350 { |
276 if(dinfo->comp_info[0].h_samp_factor==tjMCUWidth[i]/8 | 351 if(dinfo->comp_info[0].h_samp_factor==tjMCUWidth[i]/8 |
277 && dinfo->comp_info[0].v_samp_factor==tjMCUHeigh
t[i]/8) | 352 && dinfo->comp_info[0].v_samp_factor==tjMCUHeigh
t[i]/8) |
278 { | 353 { |
279 int match=0; | 354 int match=0; |
280 for(k=1; k<dinfo->num_components; k++) | 355 for(k=1; k<dinfo->num_components; k++) |
281 { | 356 { |
282 » » » » » if(dinfo->comp_info[k].h_samp_factor==1 | 357 » » » » » int href=1, vref=1; |
283 » » » » » » && dinfo->comp_info[k].v_samp_fa
ctor==1) | 358 » » » » » if(dinfo->jpeg_color_space==JCS_YCCK &&
k==3) |
| 359 » » » » » { |
| 360 » » » » » » href=tjMCUWidth[i]/8; vref=tjMC
UHeight[i]/8; |
| 361 » » » » » } |
| 362 » » » » » if(dinfo->comp_info[k].h_samp_factor==hr
ef |
| 363 » » » » » » && dinfo->comp_info[k].v_samp_fa
ctor==vref) |
284 match++; | 364 match++; |
285 } | 365 } |
286 if(match==dinfo->num_components-1) | 366 if(match==dinfo->num_components-1) |
287 { | 367 { |
288 retval=i; break; | 368 retval=i; break; |
289 } | 369 } |
290 } | 370 } |
291 } | 371 } |
292 } | 372 } |
293 return retval; | 373 return retval; |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 DLLEXPORT unsigned char *DLLCALL tjAlloc(int bytes) | 550 DLLEXPORT unsigned char *DLLCALL tjAlloc(int bytes) |
471 { | 551 { |
472 return (unsigned char *)malloc(bytes); | 552 return (unsigned char *)malloc(bytes); |
473 } | 553 } |
474 | 554 |
475 | 555 |
476 /* Compressor */ | 556 /* Compressor */ |
477 | 557 |
478 static tjhandle _tjInitCompress(tjinstance *this) | 558 static tjhandle _tjInitCompress(tjinstance *this) |
479 { | 559 { |
480 » unsigned char buffer[1], *buf=buffer; unsigned long size=1; | 560 » static unsigned char buffer[1]; |
| 561 » unsigned char *buf=buffer; unsigned long size=1; |
481 | 562 |
482 /* This is also straight out of example.c */ | 563 /* This is also straight out of example.c */ |
483 this->cinfo.err=jpeg_std_error(&this->jerr.pub); | 564 this->cinfo.err=jpeg_std_error(&this->jerr.pub); |
484 this->jerr.pub.error_exit=my_error_exit; | 565 this->jerr.pub.error_exit=my_error_exit; |
485 this->jerr.pub.output_message=my_output_message; | 566 this->jerr.pub.output_message=my_output_message; |
| 567 this->jerr.emit_message=this->jerr.pub.emit_message; |
| 568 this->jerr.pub.emit_message=my_emit_message; |
486 | 569 |
487 if(setjmp(this->jerr.setjmp_buffer)) | 570 if(setjmp(this->jerr.setjmp_buffer)) |
488 { | 571 { |
489 /* If we get here, the JPEG code has signaled an error. */ | 572 /* If we get here, the JPEG code has signaled an error. */ |
490 if(this) free(this); return NULL; | 573 if(this) free(this); return NULL; |
491 } | 574 } |
492 | 575 |
493 jpeg_create_compress(&this->cinfo); | 576 jpeg_create_compress(&this->cinfo); |
494 /* Make an initial call so it will create the destination manager */ | 577 /* Make an initial call so it will create the destination manager */ |
495 jpeg_mem_dest_tj(&this->cinfo, &buf, &size, 0); | 578 jpeg_mem_dest_tj(&this->cinfo, &buf, &size, 0); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 /* This allows for rare corner cases in which a JPEG image can actually
be | 623 /* This allows for rare corner cases in which a JPEG image can actually
be |
541 larger than the uncompressed input (we wouldn't mention it if it hadn
't | 624 larger than the uncompressed input (we wouldn't mention it if it hadn
't |
542 happened before.) */ | 625 happened before.) */ |
543 retval=PAD(width, 16) * PAD(height, 16) * 6 + 2048; | 626 retval=PAD(width, 16) * PAD(height, 16) * 6 + 2048; |
544 | 627 |
545 bailout: | 628 bailout: |
546 return retval; | 629 return retval; |
547 } | 630 } |
548 | 631 |
549 | 632 |
550 DLLEXPORT unsigned long DLLCALL tjBufSizeYUV(int width, int height, | 633 DLLEXPORT unsigned long DLLCALL tjBufSizeYUV2(int width, int pad, int height, |
551 int subsamp) | 634 int subsamp) |
552 { | 635 { |
553 » unsigned long retval=0; | 636 » int retval=0, nc, i; |
554 » int pw, ph, cw, ch; | 637 |
555 » if(width<1 || height<1 || subsamp<0 || subsamp>=NUMSUBOPT) | 638 » if(subsamp<0 || subsamp>=NUMSUBOPT) |
556 » » _throw("tjBufSizeYUV(): Invalid argument"); | 639 » » _throw("tjBufSizeYUV2(): Invalid argument"); |
557 » pw=PAD(width, tjMCUWidth[subsamp]/8); | 640 |
558 » ph=PAD(height, tjMCUHeight[subsamp]/8); | 641 » nc=(subsamp==TJSAMP_GRAY? 1:3); |
559 » cw=pw*8/tjMCUWidth[subsamp]; ch=ph*8/tjMCUHeight[subsamp]; | 642 » for(i=0; i<nc; i++) |
560 » retval=PAD(pw, 4)*ph + (subsamp==TJSAMP_GRAY? 0:PAD(cw, 4)*ch*2); | 643 » { |
| 644 » » int pw=tjPlaneWidth(i, width, subsamp); |
| 645 » » int stride=PAD(pw, pad); |
| 646 » » int ph=tjPlaneHeight(i, height, subsamp); |
| 647 » » if(pw<0 || ph<0) return -1; |
| 648 » » else retval+=stride*ph; |
| 649 » } |
561 | 650 |
562 bailout: | 651 bailout: |
563 return retval; | 652 return retval; |
564 } | 653 } |
565 | 654 |
| 655 DLLEXPORT unsigned long DLLCALL tjBufSizeYUV(int width, int height, |
| 656 int subsamp) |
| 657 { |
| 658 return tjBufSizeYUV2(width, 4, height, subsamp); |
| 659 } |
566 | 660 |
567 DLLEXPORT unsigned long DLLCALL TJBUFSIZEYUV(int width, int height, | 661 DLLEXPORT unsigned long DLLCALL TJBUFSIZEYUV(int width, int height, |
568 int subsamp) | 662 int subsamp) |
569 { | 663 { |
570 return tjBufSizeYUV(width, height, subsamp); | 664 return tjBufSizeYUV(width, height, subsamp); |
571 } | 665 } |
572 | 666 |
573 | 667 |
574 DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf, | 668 DLLEXPORT int tjPlaneWidth(int componentID, int width, int subsamp) |
| 669 { |
| 670 » int pw, nc, retval=0; |
| 671 |
| 672 » if(width<1 || subsamp<0 || subsamp>=TJ_NUMSAMP) |
| 673 » » _throw("tjPlaneWidth(): Invalid argument"); |
| 674 » nc=(subsamp==TJSAMP_GRAY? 1:3); |
| 675 » if(componentID<0 || componentID>=nc) |
| 676 » » _throw("tjPlaneWidth(): Invalid argument"); |
| 677 |
| 678 » pw=PAD(width, tjMCUWidth[subsamp]/8); |
| 679 » if(componentID==0) |
| 680 » » retval=pw; |
| 681 » else |
| 682 » » retval=pw*8/tjMCUWidth[subsamp]; |
| 683 |
| 684 » bailout: |
| 685 » return retval; |
| 686 } |
| 687 |
| 688 |
| 689 DLLEXPORT int tjPlaneHeight(int componentID, int height, int subsamp) |
| 690 { |
| 691 » int ph, nc, retval=0; |
| 692 |
| 693 » if(height<1 || subsamp<0 || subsamp>=TJ_NUMSAMP) |
| 694 » » _throw("tjPlaneHeight(): Invalid argument"); |
| 695 » nc=(subsamp==TJSAMP_GRAY? 1:3); |
| 696 » if(componentID<0 || componentID>=nc) |
| 697 » » _throw("tjPlaneHeight(): Invalid argument"); |
| 698 |
| 699 » ph=PAD(height, tjMCUHeight[subsamp]/8); |
| 700 » if(componentID==0) |
| 701 » » retval=ph; |
| 702 » else |
| 703 » » retval=ph*8/tjMCUHeight[subsamp]; |
| 704 |
| 705 » bailout: |
| 706 » return retval; |
| 707 } |
| 708 |
| 709 |
| 710 DLLEXPORT unsigned long DLLCALL tjPlaneSizeYUV(int componentID, int width, |
| 711 » int stride, int height, int subsamp) |
| 712 { |
| 713 » unsigned long retval=0; |
| 714 » int pw, ph; |
| 715 |
| 716 » if(width<1 || height<1 || subsamp<0 || subsamp>=NUMSUBOPT) |
| 717 » » _throw("tjPlaneSizeYUV(): Invalid argument"); |
| 718 |
| 719 » pw=tjPlaneWidth(componentID, width, subsamp); |
| 720 » ph=tjPlaneHeight(componentID, height, subsamp); |
| 721 » if(pw<0 || ph<0) return -1; |
| 722 |
| 723 » if(stride==0) stride=pw; |
| 724 » else stride=abs(stride); |
| 725 |
| 726 » retval=stride*(ph-1)+pw; |
| 727 |
| 728 » bailout: |
| 729 » return retval; |
| 730 } |
| 731 |
| 732 |
| 733 DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, const unsigned char *srcBuf, |
575 int width, int pitch, int height, int pixelFormat, unsigned char **jpegB
uf, | 734 int width, int pitch, int height, int pixelFormat, unsigned char **jpegB
uf, |
576 unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) | 735 unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) |
577 { | 736 { |
578 int i, retval=0, alloc=1; JSAMPROW *row_pointer=NULL; | 737 int i, retval=0, alloc=1; JSAMPROW *row_pointer=NULL; |
579 #ifndef JCS_EXTENSIONS | 738 #ifndef JCS_EXTENSIONS |
580 unsigned char *rgbBuf=NULL; | 739 unsigned char *rgbBuf=NULL; |
581 #endif | 740 #endif |
582 | 741 |
583 » getinstance(handle) | 742 » getcinstance(handle) |
584 if((this->init&COMPRESS)==0) | 743 if((this->init&COMPRESS)==0) |
585 _throw("tjCompress2(): Instance has not been initialized for com
pression"); | 744 _throw("tjCompress2(): Instance has not been initialized for com
pression"); |
586 | 745 |
587 if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 | 746 if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 |
588 || pixelFormat>=TJ_NUMPF || jpegBuf==NULL || jpegSize==NULL | 747 || pixelFormat>=TJ_NUMPF || jpegBuf==NULL || jpegSize==NULL |
589 || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT || jpegQual<0 || jpeg
Qual>100) | 748 || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT || jpegQual<0 || jpeg
Qual>100) |
590 _throw("tjCompress2(): Invalid argument"); | 749 _throw("tjCompress2(): Invalid argument"); |
591 | 750 |
592 if(setjmp(this->jerr.setjmp_buffer)) | 751 if(setjmp(this->jerr.setjmp_buffer)) |
593 { | 752 { |
594 /* If we get here, the JPEG code has signaled an error. */ | 753 /* If we get here, the JPEG code has signaled an error. */ |
595 retval=-1; | 754 retval=-1; |
596 goto bailout; | 755 goto bailout; |
597 } | 756 } |
598 | 757 |
599 if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; | 758 if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; |
600 | 759 |
601 #ifndef JCS_EXTENSIONS | 760 #ifndef JCS_EXTENSIONS |
602 » if(pixelFormat!=TJPF_GRAY) | 761 » if(pixelFormat!=TJPF_GRAY && pixelFormat!=TJPF_CMYK) |
603 { | 762 { |
604 rgbBuf=(unsigned char *)malloc(width*height*RGB_PIXELSIZE); | 763 rgbBuf=(unsigned char *)malloc(width*height*RGB_PIXELSIZE); |
605 if(!rgbBuf) _throw("tjCompress2(): Memory allocation failure"); | 764 if(!rgbBuf) _throw("tjCompress2(): Memory allocation failure"); |
606 srcBuf=toRGB(srcBuf, width, pitch, height, pixelFormat, rgbBuf); | 765 srcBuf=toRGB(srcBuf, width, pitch, height, pixelFormat, rgbBuf); |
607 pitch=width*RGB_PIXELSIZE; | 766 pitch=width*RGB_PIXELSIZE; |
608 } | 767 } |
609 #endif | 768 #endif |
610 | 769 |
611 cinfo->image_width=width; | 770 cinfo->image_width=width; |
612 cinfo->image_height=height; | 771 cinfo->image_height=height; |
613 | 772 |
614 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); | 773 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); |
615 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); | 774 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); |
616 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); | 775 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); |
617 | 776 |
618 if(flags&TJFLAG_NOREALLOC) | 777 if(flags&TJFLAG_NOREALLOC) |
619 { | 778 { |
620 alloc=0; *jpegSize=tjBufSize(width, height, jpegSubsamp); | 779 alloc=0; *jpegSize=tjBufSize(width, height, jpegSubsamp); |
621 } | 780 } |
622 jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); | 781 jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); |
623 if(setCompDefaults(cinfo, pixelFormat, jpegSubsamp, jpegQual, flags)==-1
) | 782 if(setCompDefaults(cinfo, pixelFormat, jpegSubsamp, jpegQual, flags)==-1
) |
624 return -1; | 783 return -1; |
625 | 784 |
626 jpeg_start_compress(cinfo, TRUE); | 785 jpeg_start_compress(cinfo, TRUE); |
627 if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*height))==NULL) | 786 if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*height))==NULL) |
628 _throw("tjCompress2(): Memory allocation failure"); | 787 _throw("tjCompress2(): Memory allocation failure"); |
629 for(i=0; i<height; i++) | 788 for(i=0; i<height; i++) |
630 { | 789 { |
631 » » if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&srcBuf[(height-i-1)*pi
tch]; | 790 » » if(flags&TJFLAG_BOTTOMUP) |
632 » » else row_pointer[i]=&srcBuf[i*pitch]; | 791 » » » row_pointer[i]=(JSAMPROW)&srcBuf[(height-i-1)*pitch]; |
| 792 » » else row_pointer[i]=(JSAMPROW)&srcBuf[i*pitch]; |
633 } | 793 } |
634 while(cinfo->next_scanline<cinfo->image_height) | 794 while(cinfo->next_scanline<cinfo->image_height) |
635 { | 795 { |
636 jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], | 796 jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], |
637 cinfo->image_height-cinfo->next_scanline); | 797 cinfo->image_height-cinfo->next_scanline); |
638 } | 798 } |
639 jpeg_finish_compress(cinfo); | 799 jpeg_finish_compress(cinfo); |
640 | 800 |
641 bailout: | 801 bailout: |
642 if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); | 802 if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); |
643 #ifndef JCS_EXTENSIONS | 803 #ifndef JCS_EXTENSIONS |
644 if(rgbBuf) free(rgbBuf); | 804 if(rgbBuf) free(rgbBuf); |
645 #endif | 805 #endif |
646 if(row_pointer) free(row_pointer); | 806 if(row_pointer) free(row_pointer); |
| 807 if(this->jerr.warning) retval=-1; |
647 return retval; | 808 return retval; |
648 } | 809 } |
649 | 810 |
650 DLLEXPORT int DLLCALL tjCompress(tjhandle handle, unsigned char *srcBuf, | 811 DLLEXPORT int DLLCALL tjCompress(tjhandle handle, unsigned char *srcBuf, |
651 int width, int pitch, int height, int pixelSize, unsigned char *jpegBuf, | 812 int width, int pitch, int height, int pixelSize, unsigned char *jpegBuf, |
652 unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) | 813 unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) |
653 { | 814 { |
654 int retval=0; unsigned long size; | 815 int retval=0; unsigned long size; |
655 if(flags&TJ_YUV) | 816 if(flags&TJ_YUV) |
656 { | 817 { |
657 size=tjBufSizeYUV(width, height, jpegSubsamp); | 818 size=tjBufSizeYUV(width, height, jpegSubsamp); |
658 retval=tjEncodeYUV2(handle, srcBuf, width, pitch, height, | 819 retval=tjEncodeYUV2(handle, srcBuf, width, pitch, height, |
659 getPixelFormat(pixelSize, flags), jpegBuf, jpegSubsamp,
flags); | 820 getPixelFormat(pixelSize, flags), jpegBuf, jpegSubsamp,
flags); |
660 } | 821 } |
661 else | 822 else |
662 { | 823 { |
663 retval=tjCompress2(handle, srcBuf, width, pitch, height, | 824 retval=tjCompress2(handle, srcBuf, width, pitch, height, |
664 getPixelFormat(pixelSize, flags), &jpegBuf, &size, jpegS
ubsamp, jpegQual, | 825 getPixelFormat(pixelSize, flags), &jpegBuf, &size, jpegS
ubsamp, jpegQual, |
665 flags|TJFLAG_NOREALLOC); | 826 flags|TJFLAG_NOREALLOC); |
666 } | 827 } |
667 *jpegSize=size; | 828 *jpegSize=size; |
668 return retval; | 829 return retval; |
669 } | 830 } |
670 | 831 |
671 | 832 |
672 DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf, | 833 DLLEXPORT int DLLCALL tjEncodeYUVPlanes(tjhandle handle, |
673 » int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf
, | 834 » const unsigned char *srcBuf, int width, int pitch, int height, |
674 » int subsamp, int flags) | 835 » int pixelFormat, unsigned char **dstPlanes, int *strides, int subsamp, |
| 836 » int flags) |
675 { | 837 { |
676 int i, retval=0; JSAMPROW *row_pointer=NULL; | 838 int i, retval=0; JSAMPROW *row_pointer=NULL; |
677 JSAMPLE *_tmpbuf[MAX_COMPONENTS], *_tmpbuf2[MAX_COMPONENTS]; | 839 JSAMPLE *_tmpbuf[MAX_COMPONENTS], *_tmpbuf2[MAX_COMPONENTS]; |
678 JSAMPROW *tmpbuf[MAX_COMPONENTS], *tmpbuf2[MAX_COMPONENTS]; | 840 JSAMPROW *tmpbuf[MAX_COMPONENTS], *tmpbuf2[MAX_COMPONENTS]; |
679 JSAMPROW *outbuf[MAX_COMPONENTS]; | 841 JSAMPROW *outbuf[MAX_COMPONENTS]; |
680 » int row, pw, ph, cw[MAX_COMPONENTS], ch[MAX_COMPONENTS]; | 842 » int row, pw0, ph0, pw[MAX_COMPONENTS], ph[MAX_COMPONENTS]; |
681 » JSAMPLE *ptr=dstBuf; | 843 » JSAMPLE *ptr; |
682 » unsigned long yuvsize=0; | |
683 jpeg_component_info *compptr; | 844 jpeg_component_info *compptr; |
684 #ifndef JCS_EXTENSIONS | 845 #ifndef JCS_EXTENSIONS |
685 unsigned char *rgbBuf=NULL; | 846 unsigned char *rgbBuf=NULL; |
686 #endif | 847 #endif |
687 | 848 |
688 » getinstance(handle); | 849 » getcinstance(handle); |
689 | 850 |
690 for(i=0; i<MAX_COMPONENTS; i++) | 851 for(i=0; i<MAX_COMPONENTS; i++) |
691 { | 852 { |
692 tmpbuf[i]=NULL; _tmpbuf[i]=NULL; | 853 tmpbuf[i]=NULL; _tmpbuf[i]=NULL; |
693 tmpbuf2[i]=NULL; _tmpbuf2[i]=NULL; outbuf[i]=NULL; | 854 tmpbuf2[i]=NULL; _tmpbuf2[i]=NULL; outbuf[i]=NULL; |
694 } | 855 } |
695 | 856 |
696 if((this->init&COMPRESS)==0) | 857 if((this->init&COMPRESS)==0) |
697 » » _throw("tjEncodeYUV2(): Instance has not been initialized for co
mpression"); | 858 » » _throw("tjEncodeYUVPlanes(): Instance has not been initialized f
or compression"); |
698 | 859 |
699 if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 | 860 if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 |
700 » » || pixelFormat>=TJ_NUMPF || dstBuf==NULL || subsamp<0 | 861 » » || pixelFormat>=TJ_NUMPF || !dstPlanes || !dstPlanes[0] || subsa
mp<0 |
701 || subsamp>=NUMSUBOPT) | 862 || subsamp>=NUMSUBOPT) |
702 » » _throw("tjEncodeYUV2(): Invalid argument"); | 863 » » _throw("tjEncodeYUVPlanes(): Invalid argument"); |
| 864 » if(subsamp!=TJSAMP_GRAY && (!dstPlanes[1] || !dstPlanes[2])) |
| 865 » » _throw("tjEncodeYUVPlanes(): Invalid argument"); |
703 | 866 |
704 if(setjmp(this->jerr.setjmp_buffer)) | 867 if(setjmp(this->jerr.setjmp_buffer)) |
705 { | 868 { |
706 /* If we get here, the JPEG code has signaled an error. */ | 869 /* If we get here, the JPEG code has signaled an error. */ |
707 retval=-1; | 870 retval=-1; |
708 goto bailout; | 871 goto bailout; |
709 } | 872 } |
710 | 873 |
| 874 if(pixelFormat==TJPF_CMYK) |
| 875 _throw("tjEncodeYUVPlanes(): Cannot generate YUV images from CMY
K pixels"); |
| 876 |
711 if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; | 877 if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; |
712 | 878 |
713 #ifndef JCS_EXTENSIONS | 879 #ifndef JCS_EXTENSIONS |
714 » if(pixelFormat!=TJPF_GRAY) | 880 » if(pixelFormat!=TJPF_GRAY && pixelFormat!=TJPF_CMYK) |
715 { | 881 { |
716 rgbBuf=(unsigned char *)malloc(width*height*RGB_PIXELSIZE); | 882 rgbBuf=(unsigned char *)malloc(width*height*RGB_PIXELSIZE); |
717 » » if(!rgbBuf) _throw("tjEncodeYUV2(): Memory allocation failure"); | 883 » » if(!rgbBuf) _throw("tjEncodeYUVPlanes(): Memory allocation failu
re"); |
718 srcBuf=toRGB(srcBuf, width, pitch, height, pixelFormat, rgbBuf); | 884 srcBuf=toRGB(srcBuf, width, pitch, height, pixelFormat, rgbBuf); |
719 pitch=width*RGB_PIXELSIZE; | 885 pitch=width*RGB_PIXELSIZE; |
720 } | 886 } |
721 #endif | 887 #endif |
722 | 888 |
723 cinfo->image_width=width; | 889 cinfo->image_width=width; |
724 cinfo->image_height=height; | 890 cinfo->image_height=height; |
725 | 891 |
726 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); | 892 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); |
727 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); | 893 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); |
728 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); | 894 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); |
729 | 895 |
730 yuvsize=tjBufSizeYUV(width, height, subsamp); | |
731 if(setCompDefaults(cinfo, pixelFormat, subsamp, -1, flags)==-1) return -
1; | 896 if(setCompDefaults(cinfo, pixelFormat, subsamp, -1, flags)==-1) return -
1; |
732 | 897 |
733 /* Execute only the parts of jpeg_start_compress() that we need. If we | 898 /* Execute only the parts of jpeg_start_compress() that we need. If we |
734 were to call the whole jpeg_start_compress() function, then it would
try | 899 were to call the whole jpeg_start_compress() function, then it would
try |
735 to write the file headers, which could overflow the output buffer if
the | 900 to write the file headers, which could overflow the output buffer if
the |
736 YUV image were very small. */ | 901 YUV image were very small. */ |
737 if(cinfo->global_state!=CSTATE_START) | 902 if(cinfo->global_state!=CSTATE_START) |
738 » » _throw("tjEncodeYUV3(): libjpeg API is in the wrong state"); | 903 » » _throw("tjEncodeYUVPlanes(): libjpeg API is in the wrong state")
; |
739 (*cinfo->err->reset_error_mgr)((j_common_ptr)cinfo); | 904 (*cinfo->err->reset_error_mgr)((j_common_ptr)cinfo); |
740 jinit_c_master_control(cinfo, FALSE); | 905 jinit_c_master_control(cinfo, FALSE); |
741 jinit_color_converter(cinfo); | 906 jinit_color_converter(cinfo); |
742 jinit_downsampler(cinfo); | 907 jinit_downsampler(cinfo); |
743 (*cinfo->cconvert->start_pass)(cinfo); | 908 (*cinfo->cconvert->start_pass)(cinfo); |
744 | 909 |
745 » pw=PAD(width, cinfo->max_h_samp_factor); | 910 » pw0=PAD(width, cinfo->max_h_samp_factor); |
746 » ph=PAD(height, cinfo->max_v_samp_factor); | 911 » ph0=PAD(height, cinfo->max_v_samp_factor); |
747 | 912 |
748 » if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph))==NULL) | 913 » if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph0))==NULL) |
749 » » _throw("tjEncodeYUV2(): Memory allocation failure"); | 914 » » _throw("tjEncodeYUVPlanes(): Memory allocation failure"); |
750 for(i=0; i<height; i++) | 915 for(i=0; i<height; i++) |
751 { | 916 { |
752 » » if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&srcBuf[(height-i-1)*pi
tch]; | 917 » » if(flags&TJFLAG_BOTTOMUP) |
753 » » else row_pointer[i]=&srcBuf[i*pitch]; | 918 » » » row_pointer[i]=(JSAMPROW)&srcBuf[(height-i-1)*pitch]; |
| 919 » » else row_pointer[i]=(JSAMPROW)&srcBuf[i*pitch]; |
754 } | 920 } |
755 » if(height<ph) | 921 » if(height<ph0) |
756 » » for(i=height; i<ph; i++) row_pointer[i]=row_pointer[height-1]; | 922 » » for(i=height; i<ph0; i++) row_pointer[i]=row_pointer[height-1]; |
757 | 923 |
758 for(i=0; i<cinfo->num_components; i++) | 924 for(i=0; i<cinfo->num_components; i++) |
759 { | 925 { |
760 compptr=&cinfo->comp_info[i]; | 926 compptr=&cinfo->comp_info[i]; |
761 _tmpbuf[i]=(JSAMPLE *)malloc( | 927 _tmpbuf[i]=(JSAMPLE *)malloc( |
762 PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*D
CTSIZE) | 928 PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*D
CTSIZE) |
763 /compptr->h_samp_factor, 16) * cinfo->max_v_samp
_factor + 16); | 929 /compptr->h_samp_factor, 16) * cinfo->max_v_samp
_factor + 16); |
764 » » if(!_tmpbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failur
e"); | 930 » » if(!_tmpbuf[i]) _throw("tjEncodeYUVPlanes(): Memory allocation f
ailure"); |
765 tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*cinfo->max_v_samp_
factor); | 931 tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*cinfo->max_v_samp_
factor); |
766 » » if(!tmpbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure
"); | 932 » » if(!tmpbuf[i]) _throw("tjEncodeYUVPlanes(): Memory allocation fa
ilure"); |
767 for(row=0; row<cinfo->max_v_samp_factor; row++) | 933 for(row=0; row<cinfo->max_v_samp_factor; row++) |
768 { | 934 { |
769 unsigned char *_tmpbuf_aligned= | 935 unsigned char *_tmpbuf_aligned= |
770 (unsigned char *)PAD((size_t)_tmpbuf[i], 16); | 936 (unsigned char *)PAD((size_t)_tmpbuf[i], 16); |
771 tmpbuf[i][row]=&_tmpbuf_aligned[ | 937 tmpbuf[i][row]=&_tmpbuf_aligned[ |
772 PAD((compptr->width_in_blocks*cinfo->max_h_samp_
factor*DCTSIZE) | 938 PAD((compptr->width_in_blocks*cinfo->max_h_samp_
factor*DCTSIZE) |
773 /compptr->h_samp_factor, 16) * row]; | 939 /compptr->h_samp_factor, 16) * row]; |
774 } | 940 } |
775 _tmpbuf2[i]=(JSAMPLE *)malloc(PAD(compptr->width_in_blocks*DCTSI
ZE, 16) | 941 _tmpbuf2[i]=(JSAMPLE *)malloc(PAD(compptr->width_in_blocks*DCTSI
ZE, 16) |
776 * compptr->v_samp_factor + 16); | 942 * compptr->v_samp_factor + 16); |
777 » » if(!_tmpbuf2[i]) _throw("tjEncodeYUV2(): Memory allocation failu
re"); | 943 » » if(!_tmpbuf2[i]) _throw("tjEncodeYUVPlanes(): Memory allocation
failure"); |
778 tmpbuf2[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*compptr->v_samp_f
actor); | 944 tmpbuf2[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*compptr->v_samp_f
actor); |
779 » » if(!tmpbuf2[i]) _throw("tjEncodeYUV2(): Memory allocation failur
e"); | 945 » » if(!tmpbuf2[i]) _throw("tjEncodeYUVPlanes(): Memory allocation f
ailure"); |
780 for(row=0; row<compptr->v_samp_factor; row++) | 946 for(row=0; row<compptr->v_samp_factor; row++) |
781 { | 947 { |
782 unsigned char *_tmpbuf2_aligned= | 948 unsigned char *_tmpbuf2_aligned= |
783 (unsigned char *)PAD((size_t)_tmpbuf2[i], 16); | 949 (unsigned char *)PAD((size_t)_tmpbuf2[i], 16); |
784 tmpbuf2[i][row]=&_tmpbuf2_aligned[ | 950 tmpbuf2[i][row]=&_tmpbuf2_aligned[ |
785 PAD(compptr->width_in_blocks*DCTSIZE, 16) * row]
; | 951 PAD(compptr->width_in_blocks*DCTSIZE, 16) * row]
; |
786 } | 952 } |
787 » » cw[i]=pw*compptr->h_samp_factor/cinfo->max_h_samp_factor; | 953 » » pw[i]=pw0*compptr->h_samp_factor/cinfo->max_h_samp_factor; |
788 » » ch[i]=ph*compptr->v_samp_factor/cinfo->max_v_samp_factor; | 954 » » ph[i]=ph0*compptr->v_samp_factor/cinfo->max_v_samp_factor; |
789 » » outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ch[i]); | 955 » » outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph[i]); |
790 » » if(!outbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure
"); | 956 » » if(!outbuf[i]) _throw("tjEncodeYUVPlanes(): Memory allocation fa
ilure"); |
791 » » for(row=0; row<ch[i]; row++) | 957 » » ptr=dstPlanes[i]; |
| 958 » » for(row=0; row<ph[i]; row++) |
792 { | 959 { |
793 outbuf[i][row]=ptr; | 960 outbuf[i][row]=ptr; |
794 » » » ptr+=PAD(cw[i], 4); | 961 » » » ptr+=(strides && strides[i]!=0)? strides[i]:pw[i]; |
795 } | 962 } |
796 } | 963 } |
797 if(yuvsize!=(unsigned long)(ptr-dstBuf)) | |
798 _throw("tjEncodeYUV2(): Generated image is not the correct size"
); | |
799 | 964 |
800 » for(row=0; row<ph; row+=cinfo->max_v_samp_factor) | 965 » for(row=0; row<ph0; row+=cinfo->max_v_samp_factor) |
801 { | 966 { |
802 (*cinfo->cconvert->color_convert)(cinfo, &row_pointer[row], tmpb
uf, 0, | 967 (*cinfo->cconvert->color_convert)(cinfo, &row_pointer[row], tmpb
uf, 0, |
803 cinfo->max_v_samp_factor); | 968 cinfo->max_v_samp_factor); |
804 (cinfo->downsample->downsample)(cinfo, tmpbuf, 0, tmpbuf2, 0); | 969 (cinfo->downsample->downsample)(cinfo, tmpbuf, 0, tmpbuf2, 0); |
805 for(i=0, compptr=cinfo->comp_info; i<cinfo->num_components; i++,
compptr++) | 970 for(i=0, compptr=cinfo->comp_info; i<cinfo->num_components; i++,
compptr++) |
806 jcopy_sample_rows(tmpbuf2[i], 0, outbuf[i], | 971 jcopy_sample_rows(tmpbuf2[i], 0, outbuf[i], |
807 row*compptr->v_samp_factor/cinfo->max_v_samp_fac
tor, | 972 row*compptr->v_samp_factor/cinfo->max_v_samp_fac
tor, |
808 » » » » compptr->v_samp_factor, cw[i]); | 973 » » » » compptr->v_samp_factor, pw[i]); |
809 } | 974 } |
810 cinfo->next_scanline+=height; | 975 cinfo->next_scanline+=height; |
811 jpeg_abort_compress(cinfo); | 976 jpeg_abort_compress(cinfo); |
812 | 977 |
813 bailout: | 978 bailout: |
814 if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); | 979 if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); |
815 #ifndef JCS_EXTENSIONS | 980 #ifndef JCS_EXTENSIONS |
816 if(rgbBuf) free(rgbBuf); | 981 if(rgbBuf) free(rgbBuf); |
817 #endif | 982 #endif |
818 if(row_pointer) free(row_pointer); | 983 if(row_pointer) free(row_pointer); |
819 for(i=0; i<MAX_COMPONENTS; i++) | 984 for(i=0; i<MAX_COMPONENTS; i++) |
820 { | 985 { |
821 if(tmpbuf[i]!=NULL) free(tmpbuf[i]); | 986 if(tmpbuf[i]!=NULL) free(tmpbuf[i]); |
822 if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]); | 987 if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]); |
823 if(tmpbuf2[i]!=NULL) free(tmpbuf2[i]); | 988 if(tmpbuf2[i]!=NULL) free(tmpbuf2[i]); |
824 if(_tmpbuf2[i]!=NULL) free(_tmpbuf2[i]); | 989 if(_tmpbuf2[i]!=NULL) free(_tmpbuf2[i]); |
825 if(outbuf[i]!=NULL) free(outbuf[i]); | 990 if(outbuf[i]!=NULL) free(outbuf[i]); |
826 } | 991 } |
| 992 if(this->jerr.warning) retval=-1; |
827 return retval; | 993 return retval; |
828 } | 994 } |
829 | 995 |
| 996 DLLEXPORT int DLLCALL tjEncodeYUV3(tjhandle handle, |
| 997 const unsigned char *srcBuf, int width, int pitch, int height, |
| 998 int pixelFormat, unsigned char *dstBuf, int pad, int subsamp, int flags) |
| 999 { |
| 1000 unsigned char *dstPlanes[3]; |
| 1001 int pw0, ph0, strides[3], retval=-1; |
| 1002 |
| 1003 if(width<=0 || height<=0 || dstBuf==NULL || pad<0 || !isPow2(pad) |
| 1004 || subsamp<0 || subsamp>=NUMSUBOPT) |
| 1005 _throw("tjEncodeYUV3(): Invalid argument"); |
| 1006 |
| 1007 pw0=tjPlaneWidth(0, width, subsamp); |
| 1008 ph0=tjPlaneHeight(0, height, subsamp); |
| 1009 dstPlanes[0]=dstBuf; |
| 1010 strides[0]=PAD(pw0, pad); |
| 1011 if(subsamp==TJSAMP_GRAY) |
| 1012 { |
| 1013 strides[1]=strides[2]=0; |
| 1014 dstPlanes[1]=dstPlanes[2]=NULL; |
| 1015 } |
| 1016 else |
| 1017 { |
| 1018 int pw1=tjPlaneWidth(1, width, subsamp); |
| 1019 int ph1=tjPlaneHeight(1, height, subsamp); |
| 1020 strides[1]=strides[2]=PAD(pw1, pad); |
| 1021 dstPlanes[1]=dstPlanes[0]+strides[0]*ph0; |
| 1022 dstPlanes[2]=dstPlanes[1]+strides[1]*ph1; |
| 1023 } |
| 1024 |
| 1025 return tjEncodeYUVPlanes(handle, srcBuf, width, pitch, height, pixelForm
at, |
| 1026 dstPlanes, strides, subsamp, flags); |
| 1027 |
| 1028 bailout: |
| 1029 return retval; |
| 1030 } |
| 1031 |
| 1032 DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf, |
| 1033 int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf
, |
| 1034 int subsamp, int flags) |
| 1035 { |
| 1036 return tjEncodeYUV3(handle, srcBuf, width, pitch, height, pixelFormat, |
| 1037 dstBuf, 4, subsamp, flags); |
| 1038 } |
| 1039 |
830 DLLEXPORT int DLLCALL tjEncodeYUV(tjhandle handle, unsigned char *srcBuf, | 1040 DLLEXPORT int DLLCALL tjEncodeYUV(tjhandle handle, unsigned char *srcBuf, |
831 int width, int pitch, int height, int pixelSize, unsigned char *dstBuf, | 1041 int width, int pitch, int height, int pixelSize, unsigned char *dstBuf, |
832 int subsamp, int flags) | 1042 int subsamp, int flags) |
833 { | 1043 { |
834 return tjEncodeYUV2(handle, srcBuf, width, pitch, height, | 1044 return tjEncodeYUV2(handle, srcBuf, width, pitch, height, |
835 getPixelFormat(pixelSize, flags), dstBuf, subsamp, flags); | 1045 getPixelFormat(pixelSize, flags), dstBuf, subsamp, flags); |
836 } | 1046 } |
837 | 1047 |
838 | 1048 |
| 1049 DLLEXPORT int DLLCALL tjCompressFromYUVPlanes(tjhandle handle, |
| 1050 const unsigned char **srcPlanes, int width, const int *strides, int heig
ht, |
| 1051 int subsamp, unsigned char **jpegBuf, unsigned long *jpegSize, int jpegQ
ual, |
| 1052 int flags) |
| 1053 { |
| 1054 int i, row, retval=0, alloc=1; JSAMPROW *inbuf[MAX_COMPONENTS]; |
| 1055 int pw[MAX_COMPONENTS], ph[MAX_COMPONENTS], iw[MAX_COMPONENTS], |
| 1056 tmpbufsize=0, usetmpbuf=0, th[MAX_COMPONENTS]; |
| 1057 JSAMPLE *_tmpbuf=NULL, *ptr; JSAMPROW *tmpbuf[MAX_COMPONENTS]; |
| 1058 |
| 1059 getcinstance(handle) |
| 1060 |
| 1061 for(i=0; i<MAX_COMPONENTS; i++) |
| 1062 { |
| 1063 tmpbuf[i]=NULL; inbuf[i]=NULL; |
| 1064 } |
| 1065 |
| 1066 if((this->init&COMPRESS)==0) |
| 1067 _throw("tjCompressFromYUVPlanes(): Instance has not been initial
ized for compression"); |
| 1068 |
| 1069 if(!srcPlanes || !srcPlanes[0] || width<=0 || height<=0 || subsamp<0 |
| 1070 || subsamp>=NUMSUBOPT || jpegBuf==NULL || jpegSize==NULL || jpeg
Qual<0 |
| 1071 || jpegQual>100) |
| 1072 _throw("tjCompressFromYUVPlanes(): Invalid argument"); |
| 1073 if(subsamp!=TJSAMP_GRAY && (!srcPlanes[1] || !srcPlanes[2])) |
| 1074 _throw("tjCompressFromYUVPlanes(): Invalid argument"); |
| 1075 |
| 1076 if(setjmp(this->jerr.setjmp_buffer)) |
| 1077 { |
| 1078 /* If we get here, the JPEG code has signaled an error. */ |
| 1079 retval=-1; |
| 1080 goto bailout; |
| 1081 } |
| 1082 |
| 1083 cinfo->image_width=width; |
| 1084 cinfo->image_height=height; |
| 1085 |
| 1086 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); |
| 1087 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); |
| 1088 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); |
| 1089 |
| 1090 if(flags&TJFLAG_NOREALLOC) |
| 1091 { |
| 1092 alloc=0; *jpegSize=tjBufSize(width, height, subsamp); |
| 1093 } |
| 1094 jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); |
| 1095 if(setCompDefaults(cinfo, TJPF_RGB, subsamp, jpegQual, flags)==-1) |
| 1096 return -1; |
| 1097 cinfo->raw_data_in=TRUE; |
| 1098 |
| 1099 jpeg_start_compress(cinfo, TRUE); |
| 1100 for(i=0; i<cinfo->num_components; i++) |
| 1101 { |
| 1102 jpeg_component_info *compptr=&cinfo->comp_info[i]; |
| 1103 int ih; |
| 1104 iw[i]=compptr->width_in_blocks*DCTSIZE; |
| 1105 ih=compptr->height_in_blocks*DCTSIZE; |
| 1106 pw[i]=PAD(cinfo->image_width, cinfo->max_h_samp_factor) |
| 1107 *compptr->h_samp_factor/cinfo->max_h_samp_factor; |
| 1108 ph[i]=PAD(cinfo->image_height, cinfo->max_v_samp_factor) |
| 1109 *compptr->v_samp_factor/cinfo->max_v_samp_factor; |
| 1110 if(iw[i]!=pw[i] || ih!=ph[i]) usetmpbuf=1; |
| 1111 th[i]=compptr->v_samp_factor*DCTSIZE; |
| 1112 tmpbufsize+=iw[i]*th[i]; |
| 1113 if((inbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph[i]))==NULL) |
| 1114 _throw("tjCompressFromYUVPlanes(): Memory allocation fai
lure"); |
| 1115 ptr=(JSAMPLE *)srcPlanes[i]; |
| 1116 for(row=0; row<ph[i]; row++) |
| 1117 { |
| 1118 inbuf[i][row]=ptr; |
| 1119 ptr+=(strides && strides[i]!=0)? strides[i]:pw[i]; |
| 1120 } |
| 1121 } |
| 1122 if(usetmpbuf) |
| 1123 { |
| 1124 if((_tmpbuf=(JSAMPLE *)malloc(sizeof(JSAMPLE)*tmpbufsize))==NULL
) |
| 1125 _throw("tjCompressFromYUVPlanes(): Memory allocation fai
lure"); |
| 1126 ptr=_tmpbuf; |
| 1127 for(i=0; i<cinfo->num_components; i++) |
| 1128 { |
| 1129 if((tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*th[i])
)==NULL) |
| 1130 _throw("tjCompressFromYUVPlanes(): Memory alloca
tion failure"); |
| 1131 for(row=0; row<th[i]; row++) |
| 1132 { |
| 1133 tmpbuf[i][row]=ptr; |
| 1134 ptr+=iw[i]; |
| 1135 } |
| 1136 } |
| 1137 } |
| 1138 |
| 1139 for(row=0; row<(int)cinfo->image_height; |
| 1140 row+=cinfo->max_v_samp_factor*DCTSIZE) |
| 1141 { |
| 1142 JSAMPARRAY yuvptr[MAX_COMPONENTS]; |
| 1143 int crow[MAX_COMPONENTS]; |
| 1144 for(i=0; i<cinfo->num_components; i++) |
| 1145 { |
| 1146 jpeg_component_info *compptr=&cinfo->comp_info[i]; |
| 1147 crow[i]=row*compptr->v_samp_factor/cinfo->max_v_samp_fac
tor; |
| 1148 if(usetmpbuf) |
| 1149 { |
| 1150 int j, k; |
| 1151 for(j=0; j<min(th[i], ph[i]-crow[i]); j++) |
| 1152 { |
| 1153 memcpy(tmpbuf[i][j], inbuf[i][crow[i]+j]
, pw[i]); |
| 1154 /* Duplicate last sample in row to fill
out MCU */ |
| 1155 for(k=pw[i]; k<iw[i]; k++) tmpbuf[i][j][
k]=tmpbuf[i][j][pw[i]-1]; |
| 1156 } |
| 1157 /* Duplicate last row to fill out MCU */ |
| 1158 for(j=ph[i]-crow[i]; j<th[i]; j++) |
| 1159 memcpy(tmpbuf[i][j], tmpbuf[i][ph[i]-cro
w[i]-1], iw[i]); |
| 1160 yuvptr[i]=tmpbuf[i]; |
| 1161 } |
| 1162 else |
| 1163 yuvptr[i]=&inbuf[i][crow[i]]; |
| 1164 } |
| 1165 jpeg_write_raw_data(cinfo, yuvptr, cinfo->max_v_samp_factor*DCTS
IZE); |
| 1166 } |
| 1167 jpeg_finish_compress(cinfo); |
| 1168 |
| 1169 bailout: |
| 1170 if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); |
| 1171 for(i=0; i<MAX_COMPONENTS; i++) |
| 1172 { |
| 1173 if(tmpbuf[i]) free(tmpbuf[i]); |
| 1174 if(inbuf[i]) free(inbuf[i]); |
| 1175 } |
| 1176 if(_tmpbuf) free(_tmpbuf); |
| 1177 if(this->jerr.warning) retval=-1; |
| 1178 return retval; |
| 1179 } |
| 1180 |
| 1181 DLLEXPORT int DLLCALL tjCompressFromYUV(tjhandle handle, |
| 1182 const unsigned char *srcBuf, int width, int pad, int height, int subsamp
, |
| 1183 unsigned char **jpegBuf, unsigned long *jpegSize, int jpegQual, int flag
s) |
| 1184 { |
| 1185 const unsigned char *srcPlanes[3]; |
| 1186 int pw0, ph0, strides[3], retval=-1; |
| 1187 |
| 1188 if(srcBuf==NULL || width<=0 || pad<1 || height<=0 || subsamp<0 |
| 1189 || subsamp>=NUMSUBOPT) |
| 1190 _throw("tjCompressFromYUV(): Invalid argument"); |
| 1191 |
| 1192 pw0=tjPlaneWidth(0, width, subsamp); |
| 1193 ph0=tjPlaneHeight(0, height, subsamp); |
| 1194 srcPlanes[0]=srcBuf; |
| 1195 strides[0]=PAD(pw0, pad); |
| 1196 if(subsamp==TJSAMP_GRAY) |
| 1197 { |
| 1198 strides[1]=strides[2]=0; |
| 1199 srcPlanes[1]=srcPlanes[2]=NULL; |
| 1200 } |
| 1201 else |
| 1202 { |
| 1203 int pw1=tjPlaneWidth(1, width, subsamp); |
| 1204 int ph1=tjPlaneHeight(1, height, subsamp); |
| 1205 strides[1]=strides[2]=PAD(pw1, pad); |
| 1206 srcPlanes[1]=srcPlanes[0]+strides[0]*ph0; |
| 1207 srcPlanes[2]=srcPlanes[1]+strides[1]*ph1; |
| 1208 } |
| 1209 |
| 1210 return tjCompressFromYUVPlanes(handle, srcPlanes, width, strides, height
, |
| 1211 subsamp, jpegBuf, jpegSize, jpegQual, flags); |
| 1212 |
| 1213 bailout: |
| 1214 return retval; |
| 1215 } |
| 1216 |
| 1217 |
839 /* Decompressor */ | 1218 /* Decompressor */ |
840 | 1219 |
841 static tjhandle _tjInitDecompress(tjinstance *this) | 1220 static tjhandle _tjInitDecompress(tjinstance *this) |
842 { | 1221 { |
843 » unsigned char buffer[1]; | 1222 » static unsigned char buffer[1]; |
844 | 1223 |
845 /* This is also straight out of example.c */ | 1224 /* This is also straight out of example.c */ |
846 this->dinfo.err=jpeg_std_error(&this->jerr.pub); | 1225 this->dinfo.err=jpeg_std_error(&this->jerr.pub); |
847 this->jerr.pub.error_exit=my_error_exit; | 1226 this->jerr.pub.error_exit=my_error_exit; |
848 this->jerr.pub.output_message=my_output_message; | 1227 this->jerr.pub.output_message=my_output_message; |
| 1228 this->jerr.emit_message=this->jerr.pub.emit_message; |
| 1229 this->jerr.pub.emit_message=my_emit_message; |
849 | 1230 |
850 if(setjmp(this->jerr.setjmp_buffer)) | 1231 if(setjmp(this->jerr.setjmp_buffer)) |
851 { | 1232 { |
852 /* If we get here, the JPEG code has signaled an error. */ | 1233 /* If we get here, the JPEG code has signaled an error. */ |
853 if(this) free(this); return NULL; | 1234 if(this) free(this); return NULL; |
854 } | 1235 } |
855 | 1236 |
856 jpeg_create_decompress(&this->dinfo); | 1237 jpeg_create_decompress(&this->dinfo); |
857 /* Make an initial call so it will create the source manager */ | 1238 /* Make an initial call so it will create the source manager */ |
858 jpeg_mem_src_tj(&this->dinfo, buffer, 1); | 1239 jpeg_mem_src_tj(&this->dinfo, buffer, 1); |
859 | 1240 |
860 this->init|=DECOMPRESS; | 1241 this->init|=DECOMPRESS; |
861 return (tjhandle)this; | 1242 return (tjhandle)this; |
862 } | 1243 } |
863 | 1244 |
864 DLLEXPORT tjhandle DLLCALL tjInitDecompress(void) | 1245 DLLEXPORT tjhandle DLLCALL tjInitDecompress(void) |
865 { | 1246 { |
866 tjinstance *this; | 1247 tjinstance *this; |
867 if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) | 1248 if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) |
868 { | 1249 { |
869 snprintf(errStr, JMSG_LENGTH_MAX, | 1250 snprintf(errStr, JMSG_LENGTH_MAX, |
870 "tjInitDecompress(): Memory allocation failure"); | 1251 "tjInitDecompress(): Memory allocation failure"); |
871 return NULL; | 1252 return NULL; |
872 } | 1253 } |
873 MEMZERO(this, sizeof(tjinstance)); | 1254 MEMZERO(this, sizeof(tjinstance)); |
874 return _tjInitDecompress(this); | 1255 return _tjInitDecompress(this); |
875 } | 1256 } |
876 | 1257 |
877 | 1258 |
878 DLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle, | 1259 DLLEXPORT int DLLCALL tjDecompressHeader3(tjhandle handle, |
879 » unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height, | 1260 » const unsigned char *jpegBuf, unsigned long jpegSize, int *width, |
880 » int *jpegSubsamp) | 1261 » int *height, int *jpegSubsamp, int *jpegColorspace) |
881 { | 1262 { |
882 int retval=0; | 1263 int retval=0; |
883 | 1264 |
884 » getinstance(handle); | 1265 » getdinstance(handle); |
885 if((this->init&DECOMPRESS)==0) | 1266 if((this->init&DECOMPRESS)==0) |
886 » » _throw("tjDecompressHeader2(): Instance has not been initialized
for decompression"); | 1267 » » _throw("tjDecompressHeader3(): Instance has not been initialized
for decompression"); |
887 | 1268 |
888 if(jpegBuf==NULL || jpegSize<=0 || width==NULL || height==NULL | 1269 if(jpegBuf==NULL || jpegSize<=0 || width==NULL || height==NULL |
889 » » || jpegSubsamp==NULL) | 1270 » » || jpegSubsamp==NULL || jpegColorspace==NULL) |
890 » » _throw("tjDecompressHeader2(): Invalid argument"); | 1271 » » _throw("tjDecompressHeader3(): Invalid argument"); |
891 | 1272 |
892 if(setjmp(this->jerr.setjmp_buffer)) | 1273 if(setjmp(this->jerr.setjmp_buffer)) |
893 { | 1274 { |
894 /* If we get here, the JPEG code has signaled an error. */ | 1275 /* If we get here, the JPEG code has signaled an error. */ |
895 return -1; | 1276 return -1; |
896 } | 1277 } |
897 | 1278 |
898 jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); | 1279 jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); |
899 jpeg_read_header(dinfo, TRUE); | 1280 jpeg_read_header(dinfo, TRUE); |
900 | 1281 |
901 *width=dinfo->image_width; | 1282 *width=dinfo->image_width; |
902 *height=dinfo->image_height; | 1283 *height=dinfo->image_height; |
903 *jpegSubsamp=getSubsamp(dinfo); | 1284 *jpegSubsamp=getSubsamp(dinfo); |
| 1285 switch(dinfo->jpeg_color_space) |
| 1286 { |
| 1287 case JCS_GRAYSCALE: *jpegColorspace=TJCS_GRAY; break; |
| 1288 case JCS_RGB: *jpegColorspace=TJCS_RGB; break; |
| 1289 case JCS_YCbCr: *jpegColorspace=TJCS_YCbCr; break; |
| 1290 case JCS_CMYK: *jpegColorspace=TJCS_CMYK; break; |
| 1291 case JCS_YCCK: *jpegColorspace=TJCS_YCCK; break; |
| 1292 default: *jpegColorspace=-1; break; |
| 1293 } |
904 | 1294 |
905 jpeg_abort_decompress(dinfo); | 1295 jpeg_abort_decompress(dinfo); |
906 | 1296 |
907 if(*jpegSubsamp<0) | 1297 if(*jpegSubsamp<0) |
908 » » _throw("tjDecompressHeader2(): Could not determine subsampling t
ype for JPEG image"); | 1298 » » _throw("tjDecompressHeader3(): Could not determine subsampling t
ype for JPEG image"); |
| 1299 » if(*jpegColorspace<0) |
| 1300 » » _throw("tjDecompressHeader3(): Could not determine colorspace of
JPEG image"); |
909 if(*width<1 || *height<1) | 1301 if(*width<1 || *height<1) |
910 » » _throw("tjDecompressHeader2(): Invalid data returned in header")
; | 1302 » » _throw("tjDecompressHeader3(): Invalid data returned in header")
; |
911 | 1303 |
912 bailout: | 1304 bailout: |
| 1305 if(this->jerr.warning) retval=-1; |
913 return retval; | 1306 return retval; |
914 } | 1307 } |
915 | 1308 |
| 1309 DLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle, |
| 1310 unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height, |
| 1311 int *jpegSubsamp) |
| 1312 { |
| 1313 int jpegColorspace; |
| 1314 return tjDecompressHeader3(handle, jpegBuf, jpegSize, width, height, |
| 1315 jpegSubsamp, &jpegColorspace); |
| 1316 } |
| 1317 |
916 DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle handle, | 1318 DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle handle, |
917 unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height) | 1319 unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height) |
918 { | 1320 { |
919 int jpegSubsamp; | 1321 int jpegSubsamp; |
920 return tjDecompressHeader2(handle, jpegBuf, jpegSize, width, height, | 1322 return tjDecompressHeader2(handle, jpegBuf, jpegSize, width, height, |
921 &jpegSubsamp); | 1323 &jpegSubsamp); |
922 } | 1324 } |
923 | 1325 |
924 | 1326 |
925 DLLEXPORT tjscalingfactor* DLLCALL tjGetScalingFactors(int *numscalingfactors) | 1327 DLLEXPORT tjscalingfactor* DLLCALL tjGetScalingFactors(int *numscalingfactors) |
926 { | 1328 { |
927 if(numscalingfactors==NULL) | 1329 if(numscalingfactors==NULL) |
928 { | 1330 { |
929 snprintf(errStr, JMSG_LENGTH_MAX, | 1331 snprintf(errStr, JMSG_LENGTH_MAX, |
930 "tjGetScalingFactors(): Invalid argument"); | 1332 "tjGetScalingFactors(): Invalid argument"); |
931 return NULL; | 1333 return NULL; |
932 } | 1334 } |
933 | 1335 |
934 *numscalingfactors=NUMSF; | 1336 *numscalingfactors=NUMSF; |
935 return (tjscalingfactor *)sf; | 1337 return (tjscalingfactor *)sf; |
936 } | 1338 } |
937 | 1339 |
938 | 1340 |
939 DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, unsigned char *jpegBuf, | 1341 DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, |
940 » unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, | 1342 » const unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dst
Buf, |
941 » int height, int pixelFormat, int flags) | 1343 » int width, int pitch, int height, int pixelFormat, int flags) |
942 { | 1344 { |
943 int i, retval=0; JSAMPROW *row_pointer=NULL; | 1345 int i, retval=0; JSAMPROW *row_pointer=NULL; |
944 int jpegwidth, jpegheight, scaledw, scaledh; | 1346 int jpegwidth, jpegheight, scaledw, scaledh; |
945 #ifndef JCS_EXTENSIONS | 1347 #ifndef JCS_EXTENSIONS |
946 unsigned char *rgbBuf=NULL; | 1348 unsigned char *rgbBuf=NULL; |
947 unsigned char *_dstBuf=NULL; int _pitch=0; | 1349 unsigned char *_dstBuf=NULL; int _pitch=0; |
948 #endif | 1350 #endif |
949 | 1351 |
950 » getinstance(handle); | 1352 » getdinstance(handle); |
951 if((this->init&DECOMPRESS)==0) | 1353 if((this->init&DECOMPRESS)==0) |
952 _throw("tjDecompress2(): Instance has not been initialized for d
ecompression"); | 1354 _throw("tjDecompress2(): Instance has not been initialized for d
ecompression"); |
953 | 1355 |
954 if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL || width<0 || pitch<0 | 1356 if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL || width<0 || pitch<0 |
955 || height<0 || pixelFormat<0 || pixelFormat>=TJ_NUMPF) | 1357 || height<0 || pixelFormat<0 || pixelFormat>=TJ_NUMPF) |
956 _throw("tjDecompress2(): Invalid argument"); | 1358 _throw("tjDecompress2(): Invalid argument"); |
957 | 1359 |
958 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); | 1360 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); |
959 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); | 1361 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); |
960 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); | 1362 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); |
(...skipping 17 matching lines...) Expand all Loading... |
978 jpegwidth=dinfo->image_width; jpegheight=dinfo->image_height; | 1380 jpegwidth=dinfo->image_width; jpegheight=dinfo->image_height; |
979 if(width==0) width=jpegwidth; | 1381 if(width==0) width=jpegwidth; |
980 if(height==0) height=jpegheight; | 1382 if(height==0) height=jpegheight; |
981 for(i=0; i<NUMSF; i++) | 1383 for(i=0; i<NUMSF; i++) |
982 { | 1384 { |
983 scaledw=TJSCALED(jpegwidth, sf[i]); | 1385 scaledw=TJSCALED(jpegwidth, sf[i]); |
984 scaledh=TJSCALED(jpegheight, sf[i]); | 1386 scaledh=TJSCALED(jpegheight, sf[i]); |
985 if(scaledw<=width && scaledh<=height) | 1387 if(scaledw<=width && scaledh<=height) |
986 break; | 1388 break; |
987 } | 1389 } |
988 » if(scaledw>width || scaledh>height) | 1390 » if(i>=NUMSF) |
989 _throw("tjDecompress2(): Could not scale down to desired image d
imensions"); | 1391 _throw("tjDecompress2(): Could not scale down to desired image d
imensions"); |
990 width=scaledw; height=scaledh; | 1392 width=scaledw; height=scaledh; |
991 dinfo->scale_num=sf[i].num; | 1393 dinfo->scale_num=sf[i].num; |
992 dinfo->scale_denom=sf[i].denom; | 1394 dinfo->scale_denom=sf[i].denom; |
993 | 1395 |
994 jpeg_start_decompress(dinfo); | 1396 jpeg_start_decompress(dinfo); |
995 if(pitch==0) pitch=dinfo->output_width*tjPixelSize[pixelFormat]; | 1397 if(pitch==0) pitch=dinfo->output_width*tjPixelSize[pixelFormat]; |
996 | 1398 |
997 #ifndef JCS_EXTENSIONS | 1399 #ifndef JCS_EXTENSIONS |
998 » if(pixelFormat!=TJPF_GRAY && | 1400 » if(pixelFormat!=TJPF_GRAY && pixelFormat!=TJPF_CMYK && |
999 (RGB_RED!=tjRedOffset[pixelFormat] || | 1401 (RGB_RED!=tjRedOffset[pixelFormat] || |
1000 RGB_GREEN!=tjGreenOffset[pixelFormat] || | 1402 RGB_GREEN!=tjGreenOffset[pixelFormat] || |
1001 RGB_BLUE!=tjBlueOffset[pixelFormat] || | 1403 RGB_BLUE!=tjBlueOffset[pixelFormat] || |
1002 RGB_PIXELSIZE!=tjPixelSize[pixelFormat])) | 1404 RGB_PIXELSIZE!=tjPixelSize[pixelFormat])) |
1003 { | 1405 { |
1004 rgbBuf=(unsigned char *)malloc(width*height*3); | 1406 rgbBuf=(unsigned char *)malloc(width*height*3); |
1005 if(!rgbBuf) _throw("tjDecompress2(): Memory allocation failure")
; | 1407 if(!rgbBuf) _throw("tjDecompress2(): Memory allocation failure")
; |
1006 _pitch=pitch; pitch=width*3; | 1408 _pitch=pitch; pitch=width*3; |
1007 _dstBuf=dstBuf; dstBuf=rgbBuf; | 1409 _dstBuf=dstBuf; dstBuf=rgbBuf; |
1008 } | 1410 } |
(...skipping 18 matching lines...) Expand all Loading... |
1027 #ifndef JCS_EXTENSIONS | 1429 #ifndef JCS_EXTENSIONS |
1028 fromRGB(rgbBuf, _dstBuf, width, _pitch, height, pixelFormat); | 1430 fromRGB(rgbBuf, _dstBuf, width, _pitch, height, pixelFormat); |
1029 #endif | 1431 #endif |
1030 | 1432 |
1031 bailout: | 1433 bailout: |
1032 if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); | 1434 if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); |
1033 #ifndef JCS_EXTENSIONS | 1435 #ifndef JCS_EXTENSIONS |
1034 if(rgbBuf) free(rgbBuf); | 1436 if(rgbBuf) free(rgbBuf); |
1035 #endif | 1437 #endif |
1036 if(row_pointer) free(row_pointer); | 1438 if(row_pointer) free(row_pointer); |
| 1439 if(this->jerr.warning) retval=-1; |
1037 return retval; | 1440 return retval; |
1038 } | 1441 } |
1039 | 1442 |
1040 DLLEXPORT int DLLCALL tjDecompress(tjhandle handle, unsigned char *jpegBuf, | 1443 DLLEXPORT int DLLCALL tjDecompress(tjhandle handle, unsigned char *jpegBuf, |
1041 unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, | 1444 unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, |
1042 int height, int pixelSize, int flags) | 1445 int height, int pixelSize, int flags) |
1043 { | 1446 { |
1044 if(flags&TJ_YUV) | 1447 if(flags&TJ_YUV) |
1045 return tjDecompressToYUV(handle, jpegBuf, jpegSize, dstBuf, flag
s); | 1448 return tjDecompressToYUV(handle, jpegBuf, jpegSize, dstBuf, flag
s); |
1046 else | 1449 else |
1047 return tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, width, p
itch, | 1450 return tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, width, p
itch, |
1048 height, getPixelFormat(pixelSize, flags), flags); | 1451 height, getPixelFormat(pixelSize, flags), flags); |
1049 } | 1452 } |
1050 | 1453 |
1051 | 1454 |
1052 DLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle, | 1455 static int setDecodeDefaults(struct jpeg_decompress_struct *dinfo, |
1053 » unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, | 1456 » int pixelFormat, int subsamp, int flags) |
| 1457 { |
| 1458 » int i; |
| 1459 |
| 1460 » dinfo->scale_num=dinfo->scale_denom=1; |
| 1461 |
| 1462 » if(subsamp==TJSAMP_GRAY) |
| 1463 » { |
| 1464 » » dinfo->num_components=dinfo->comps_in_scan=1; |
| 1465 » » dinfo->jpeg_color_space=JCS_GRAYSCALE; |
| 1466 » } |
| 1467 » else |
| 1468 » { |
| 1469 » » dinfo->num_components=dinfo->comps_in_scan=3; |
| 1470 » » dinfo->jpeg_color_space=JCS_YCbCr; |
| 1471 » } |
| 1472 |
| 1473 » dinfo->comp_info=(jpeg_component_info *) |
| 1474 » » (*dinfo->mem->alloc_small)((j_common_ptr)dinfo, JPOOL_IMAGE, |
| 1475 » » » dinfo->num_components*sizeof(jpeg_component_info)); |
| 1476 |
| 1477 » for(i=0; i<dinfo->num_components; i++) |
| 1478 » { |
| 1479 » » jpeg_component_info *compptr=&dinfo->comp_info[i]; |
| 1480 » » compptr->h_samp_factor=(i==0)? tjMCUWidth[subsamp]/8:1; |
| 1481 » » compptr->v_samp_factor=(i==0)? tjMCUHeight[subsamp]/8:1; |
| 1482 » » compptr->component_index=i; |
| 1483 » » compptr->component_id=i+1; |
| 1484 » » compptr->quant_tbl_no=compptr->dc_tbl_no=compptr->ac_tbl_no= |
| 1485 » » » (i==0)? 0:1; |
| 1486 » » dinfo->cur_comp_info[i]=compptr; |
| 1487 » } |
| 1488 » dinfo->data_precision=8; |
| 1489 » for(i=0; i<2; i++) |
| 1490 » { |
| 1491 » » if(dinfo->quant_tbl_ptrs[i]==NULL) |
| 1492 » » » dinfo->quant_tbl_ptrs[i]=jpeg_alloc_quant_table((j_commo
n_ptr)dinfo); |
| 1493 » } |
| 1494 |
| 1495 » return 0; |
| 1496 } |
| 1497 |
| 1498 |
| 1499 int my_read_markers(j_decompress_ptr dinfo) |
| 1500 { |
| 1501 » return JPEG_REACHED_SOS; |
| 1502 } |
| 1503 |
| 1504 void my_reset_marker_reader(j_decompress_ptr dinfo) |
| 1505 { |
| 1506 } |
| 1507 |
| 1508 DLLEXPORT int DLLCALL tjDecodeYUVPlanes(tjhandle handle, |
| 1509 » const unsigned char **srcPlanes, const int *strides, int subsamp, |
| 1510 » unsigned char *dstBuf, int width, int pitch, int height, int pixelFormat
, |
1054 int flags) | 1511 int flags) |
1055 { | 1512 { |
1056 » int i, row, retval=0; JSAMPROW *outbuf[MAX_COMPONENTS]; | 1513 » int i, retval=0; JSAMPROW *row_pointer=NULL; |
1057 » int cw[MAX_COMPONENTS], ch[MAX_COMPONENTS], iw[MAX_COMPONENTS], | 1514 » JSAMPLE *_tmpbuf[MAX_COMPONENTS]; |
| 1515 » JSAMPROW *tmpbuf[MAX_COMPONENTS], *inbuf[MAX_COMPONENTS]; |
| 1516 » int row, pw0, ph0, pw[MAX_COMPONENTS], ph[MAX_COMPONENTS]; |
| 1517 » JSAMPLE *ptr; |
| 1518 » jpeg_component_info *compptr; |
| 1519 » #ifndef JCS_EXTENSIONS |
| 1520 » unsigned char *rgbBuf=NULL; |
| 1521 » unsigned char *_dstBuf=NULL; int _pitch=0; |
| 1522 » #endif |
| 1523 » int (*old_read_markers)(j_decompress_ptr); |
| 1524 » void (*old_reset_marker_reader)(j_decompress_ptr); |
| 1525 |
| 1526 » getdinstance(handle); |
| 1527 |
| 1528 » for(i=0; i<MAX_COMPONENTS; i++) |
| 1529 » { |
| 1530 » » tmpbuf[i]=NULL; _tmpbuf[i]=NULL; inbuf[i]=NULL; |
| 1531 » } |
| 1532 |
| 1533 » if((this->init&DECOMPRESS)==0) |
| 1534 » » _throw("tjDecodeYUVPlanes(): Instance has not been initialized f
or decompression"); |
| 1535 |
| 1536 » if(!srcPlanes || !srcPlanes[0] || subsamp<0 || subsamp>=NUMSUBOPT |
| 1537 » » || dstBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelForm
at<0 |
| 1538 » » || pixelFormat>=TJ_NUMPF) |
| 1539 » » _throw("tjDecodeYUVPlanes(): Invalid argument"); |
| 1540 » if(subsamp!=TJSAMP_GRAY && (!srcPlanes[1] || !srcPlanes[2])) |
| 1541 » » _throw("tjDecodeYUVPlanes(): Invalid argument"); |
| 1542 |
| 1543 » if(setjmp(this->jerr.setjmp_buffer)) |
| 1544 » { |
| 1545 » » /* If we get here, the JPEG code has signaled an error. */ |
| 1546 » » retval=-1; |
| 1547 » » goto bailout; |
| 1548 » } |
| 1549 |
| 1550 » if(pixelFormat==TJPF_CMYK) |
| 1551 » » _throw("tjDecodeYUVPlanes(): Cannot decode YUV images into CMYK
pixels."); |
| 1552 |
| 1553 » if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; |
| 1554 » dinfo->image_width=width; |
| 1555 » dinfo->image_height=height; |
| 1556 |
| 1557 » if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); |
| 1558 » else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); |
| 1559 » else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); |
| 1560 |
| 1561 » if(setDecodeDefaults(dinfo, pixelFormat, subsamp, flags)==-1) |
| 1562 » { |
| 1563 » » retval=-1; goto bailout; |
| 1564 » } |
| 1565 » old_read_markers=dinfo->marker->read_markers; |
| 1566 » dinfo->marker->read_markers=my_read_markers; |
| 1567 » old_reset_marker_reader=dinfo->marker->reset_marker_reader; |
| 1568 » dinfo->marker->reset_marker_reader=my_reset_marker_reader; |
| 1569 » jpeg_read_header(dinfo, TRUE); |
| 1570 » dinfo->marker->read_markers=old_read_markers; |
| 1571 » dinfo->marker->reset_marker_reader=old_reset_marker_reader; |
| 1572 |
| 1573 » if(setDecompDefaults(dinfo, pixelFormat, flags)==-1) |
| 1574 » { |
| 1575 » » retval=-1; goto bailout; |
| 1576 » } |
| 1577 » dinfo->do_fancy_upsampling=FALSE; |
| 1578 » dinfo->Se=DCTSIZE2-1; |
| 1579 » jinit_master_decompress(dinfo); |
| 1580 » (*dinfo->upsample->start_pass)(dinfo); |
| 1581 |
| 1582 » pw0=PAD(width, dinfo->max_h_samp_factor); |
| 1583 » ph0=PAD(height, dinfo->max_v_samp_factor); |
| 1584 |
| 1585 » if(pitch==0) pitch=dinfo->output_width*tjPixelSize[pixelFormat]; |
| 1586 |
| 1587 » #ifndef JCS_EXTENSIONS |
| 1588 » if(pixelFormat!=TJPF_GRAY && pixelFormat!=TJPF_CMYK && |
| 1589 » » (RGB_RED!=tjRedOffset[pixelFormat] || |
| 1590 » » » RGB_GREEN!=tjGreenOffset[pixelFormat] || |
| 1591 » » » RGB_BLUE!=tjBlueOffset[pixelFormat] || |
| 1592 » » » RGB_PIXELSIZE!=tjPixelSize[pixelFormat])) |
| 1593 » { |
| 1594 » » rgbBuf=(unsigned char *)malloc(width*height*3); |
| 1595 » » if(!rgbBuf) _throw("tjDecodeYUVPlanes(): Memory allocation failu
re"); |
| 1596 » » _pitch=pitch; pitch=width*3; |
| 1597 » » _dstBuf=dstBuf; dstBuf=rgbBuf; |
| 1598 » } |
| 1599 » #endif |
| 1600 |
| 1601 » if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph0))==NULL) |
| 1602 » » _throw("tjDecodeYUVPlanes(): Memory allocation failure"); |
| 1603 » for(i=0; i<height; i++) |
| 1604 » { |
| 1605 » » if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&dstBuf[(height-i-1)*pi
tch]; |
| 1606 » » else row_pointer[i]=&dstBuf[i*pitch]; |
| 1607 » } |
| 1608 » if(height<ph0) |
| 1609 » » for(i=height; i<ph0; i++) row_pointer[i]=row_pointer[height-1]; |
| 1610 |
| 1611 » for(i=0; i<dinfo->num_components; i++) |
| 1612 » { |
| 1613 » » compptr=&dinfo->comp_info[i]; |
| 1614 » » _tmpbuf[i]=(JSAMPLE *)malloc(PAD(compptr->width_in_blocks*DCTSIZ
E, 16) |
| 1615 » » » * compptr->v_samp_factor + 16); |
| 1616 » » if(!_tmpbuf[i]) _throw("tjDecodeYUVPlanes(): Memory allocation f
ailure"); |
| 1617 » » tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*compptr->v_samp_fa
ctor); |
| 1618 » » if(!tmpbuf[i]) _throw("tjDecodeYUVPlanes(): Memory allocation fa
ilure"); |
| 1619 » » for(row=0; row<compptr->v_samp_factor; row++) |
| 1620 » » { |
| 1621 » » » unsigned char *_tmpbuf_aligned= |
| 1622 » » » » (unsigned char *)PAD((size_t)_tmpbuf[i], 16); |
| 1623 » » » tmpbuf[i][row]=&_tmpbuf_aligned[ |
| 1624 » » » » PAD(compptr->width_in_blocks*DCTSIZE, 16) * row]
; |
| 1625 » » } |
| 1626 » » pw[i]=pw0*compptr->h_samp_factor/dinfo->max_h_samp_factor; |
| 1627 » » ph[i]=ph0*compptr->v_samp_factor/dinfo->max_v_samp_factor; |
| 1628 » » inbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph[i]); |
| 1629 » » if(!inbuf[i]) _throw("tjDecodeYUVPlanes(): Memory allocation fai
lure"); |
| 1630 » » ptr=(JSAMPLE *)srcPlanes[i]; |
| 1631 » » for(row=0; row<ph[i]; row++) |
| 1632 » » { |
| 1633 » » » inbuf[i][row]=ptr; |
| 1634 » » » ptr+=(strides && strides[i]!=0)? strides[i]:pw[i]; |
| 1635 » » } |
| 1636 » } |
| 1637 |
| 1638 » for(row=0; row<ph0; row+=dinfo->max_v_samp_factor) |
| 1639 » { |
| 1640 » » JDIMENSION inrow=0, outrow=0; |
| 1641 » » for(i=0, compptr=dinfo->comp_info; i<dinfo->num_components; i++,
compptr++) |
| 1642 » » » jcopy_sample_rows(inbuf[i], |
| 1643 » » » » row*compptr->v_samp_factor/dinfo->max_v_samp_fac
tor, tmpbuf[i], 0, |
| 1644 » » » » compptr->v_samp_factor, pw[i]); |
| 1645 » » (dinfo->upsample->upsample)(dinfo, tmpbuf, &inrow, |
| 1646 » » » dinfo->max_v_samp_factor, &row_pointer[row], &outrow, |
| 1647 » » » dinfo->max_v_samp_factor); |
| 1648 » } |
| 1649 » jpeg_abort_decompress(dinfo); |
| 1650 |
| 1651 » #ifndef JCS_EXTENSIONS |
| 1652 » fromRGB(rgbBuf, _dstBuf, width, _pitch, height, pixelFormat); |
| 1653 » #endif |
| 1654 |
| 1655 » bailout: |
| 1656 » if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); |
| 1657 » #ifndef JCS_EXTENSIONS |
| 1658 » if(rgbBuf) free(rgbBuf); |
| 1659 » #endif |
| 1660 » if(row_pointer) free(row_pointer); |
| 1661 » for(i=0; i<MAX_COMPONENTS; i++) |
| 1662 » { |
| 1663 » » if(tmpbuf[i]!=NULL) free(tmpbuf[i]); |
| 1664 » » if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]); |
| 1665 » » if(inbuf[i]!=NULL) free(inbuf[i]); |
| 1666 » } |
| 1667 » if(this->jerr.warning) retval=-1; |
| 1668 » return retval; |
| 1669 } |
| 1670 |
| 1671 DLLEXPORT int DLLCALL tjDecodeYUV(tjhandle handle, const unsigned char *srcBuf, |
| 1672 » int pad, int subsamp, unsigned char *dstBuf, int width, int pitch, |
| 1673 » int height, int pixelFormat, int flags) |
| 1674 { |
| 1675 » const unsigned char *srcPlanes[3]; |
| 1676 » int pw0, ph0, strides[3], retval=-1; |
| 1677 |
| 1678 » if(srcBuf==NULL || pad<0 || !isPow2(pad) || subsamp<0 || subsamp>=NUMSUB
OPT |
| 1679 » » || width<=0 || height<=0) |
| 1680 » » _throw("tjDecodeYUV(): Invalid argument"); |
| 1681 |
| 1682 » pw0=tjPlaneWidth(0, width, subsamp); |
| 1683 » ph0=tjPlaneHeight(0, height, subsamp); |
| 1684 » srcPlanes[0]=srcBuf; |
| 1685 » strides[0]=PAD(pw0, pad); |
| 1686 » if(subsamp==TJSAMP_GRAY) |
| 1687 » { |
| 1688 » » strides[1]=strides[2]=0; |
| 1689 » » srcPlanes[1]=srcPlanes[2]=NULL; |
| 1690 » } |
| 1691 » else |
| 1692 » { |
| 1693 » » int pw1=tjPlaneWidth(1, width, subsamp); |
| 1694 » » int ph1=tjPlaneHeight(1, height, subsamp); |
| 1695 » » strides[1]=strides[2]=PAD(pw1, pad); |
| 1696 » » srcPlanes[1]=srcPlanes[0]+strides[0]*ph0; |
| 1697 » » srcPlanes[2]=srcPlanes[1]+strides[1]*ph1; |
| 1698 » } |
| 1699 |
| 1700 » return tjDecodeYUVPlanes(handle, srcPlanes, strides, subsamp, dstBuf, wi
dth, |
| 1701 » » pitch, height, pixelFormat, flags); |
| 1702 |
| 1703 » bailout: |
| 1704 » return retval; |
| 1705 } |
| 1706 |
| 1707 DLLEXPORT int DLLCALL tjDecompressToYUVPlanes(tjhandle handle, |
| 1708 » const unsigned char *jpegBuf, unsigned long jpegSize, |
| 1709 » unsigned char **dstPlanes, int width, int *strides, int height, int flag
s) |
| 1710 { |
| 1711 » int i, sfi, row, retval=0; JSAMPROW *outbuf[MAX_COMPONENTS]; |
| 1712 » int jpegwidth, jpegheight, jpegSubsamp, scaledw, scaledh; |
| 1713 » int pw[MAX_COMPONENTS], ph[MAX_COMPONENTS], iw[MAX_COMPONENTS], |
1058 tmpbufsize=0, usetmpbuf=0, th[MAX_COMPONENTS]; | 1714 tmpbufsize=0, usetmpbuf=0, th[MAX_COMPONENTS]; |
1059 » JSAMPLE *_tmpbuf=NULL, *ptr=dstBuf; JSAMPROW *tmpbuf[MAX_COMPONENTS]; | 1715 » JSAMPLE *_tmpbuf=NULL, *ptr; JSAMPROW *tmpbuf[MAX_COMPONENTS]; |
1060 | 1716 » int dctsize; |
1061 » getinstance(handle); | 1717 |
| 1718 » getdinstance(handle); |
1062 | 1719 |
1063 for(i=0; i<MAX_COMPONENTS; i++) | 1720 for(i=0; i<MAX_COMPONENTS; i++) |
1064 { | 1721 { |
1065 tmpbuf[i]=NULL; outbuf[i]=NULL; | 1722 tmpbuf[i]=NULL; outbuf[i]=NULL; |
1066 } | 1723 } |
1067 | 1724 |
1068 if((this->init&DECOMPRESS)==0) | 1725 if((this->init&DECOMPRESS)==0) |
1069 » » _throw("tjDecompressToYUV(): Instance has not been initialized f
or decompression"); | 1726 » » _throw("tjDecompressToYUVPlanes(): Instance has not been initial
ized for decompression"); |
1070 | 1727 |
1071 » if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL) | 1728 » if(jpegBuf==NULL || jpegSize<=0 || !dstPlanes || !dstPlanes[0] || width<
0 |
1072 » » _throw("tjDecompressToYUV(): Invalid argument"); | 1729 » » || height<0) |
| 1730 » » _throw("tjDecompressToYUVPlanes(): Invalid argument"); |
1073 | 1731 |
1074 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); | 1732 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); |
1075 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); | 1733 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); |
1076 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); | 1734 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); |
1077 | 1735 |
1078 if(setjmp(this->jerr.setjmp_buffer)) | 1736 if(setjmp(this->jerr.setjmp_buffer)) |
1079 { | 1737 { |
1080 /* If we get here, the JPEG code has signaled an error. */ | 1738 /* If we get here, the JPEG code has signaled an error. */ |
1081 retval=-1; | 1739 retval=-1; |
1082 goto bailout; | 1740 goto bailout; |
1083 } | 1741 } |
1084 | 1742 |
1085 » jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); | 1743 » if(!this->headerRead) |
1086 » jpeg_read_header(dinfo, TRUE); | 1744 » { |
| 1745 » » jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); |
| 1746 » » jpeg_read_header(dinfo, TRUE); |
| 1747 » } |
| 1748 » this->headerRead=0; |
| 1749 » jpegSubsamp=getSubsamp(dinfo); |
| 1750 » if(jpegSubsamp<0) |
| 1751 » » _throw("tjDecompressToYUVPlanes(): Could not determine subsampli
ng type for JPEG image"); |
| 1752 |
| 1753 » if(jpegSubsamp!=TJSAMP_GRAY && (!dstPlanes[1] || !dstPlanes[2])) |
| 1754 » » _throw("tjDecompressToYUVPlanes(): Invalid argument"); |
| 1755 |
| 1756 » jpegwidth=dinfo->image_width; jpegheight=dinfo->image_height; |
| 1757 » if(width==0) width=jpegwidth; |
| 1758 » if(height==0) height=jpegheight; |
| 1759 » for(i=0; i<NUMSF; i++) |
| 1760 » { |
| 1761 » » scaledw=TJSCALED(jpegwidth, sf[i]); |
| 1762 » » scaledh=TJSCALED(jpegheight, sf[i]); |
| 1763 » » if(scaledw<=width && scaledh<=height) |
| 1764 » » » break; |
| 1765 » } |
| 1766 » if(i>=NUMSF) |
| 1767 » » _throw("tjDecompressToYUVPlanes(): Could not scale down to desir
ed image dimensions"); |
| 1768 » if(dinfo->num_components>3) |
| 1769 » » _throw("tjDecompressToYUVPlanes(): JPEG image must have 3 or few
er components"); |
| 1770 |
| 1771 » width=scaledw; height=scaledh; |
| 1772 » dinfo->scale_num=sf[i].num; |
| 1773 » dinfo->scale_denom=sf[i].denom; |
| 1774 » sfi=i; |
| 1775 » jpeg_calc_output_dimensions(dinfo); |
| 1776 |
| 1777 » dctsize=DCTSIZE*sf[sfi].num/sf[sfi].denom; |
1087 | 1778 |
1088 for(i=0; i<dinfo->num_components; i++) | 1779 for(i=0; i<dinfo->num_components; i++) |
1089 { | 1780 { |
1090 jpeg_component_info *compptr=&dinfo->comp_info[i]; | 1781 jpeg_component_info *compptr=&dinfo->comp_info[i]; |
1091 int ih; | 1782 int ih; |
1092 » » iw[i]=compptr->width_in_blocks*DCTSIZE; | 1783 » » iw[i]=compptr->width_in_blocks*dctsize; |
1093 » » ih=compptr->height_in_blocks*DCTSIZE; | 1784 » » ih=compptr->height_in_blocks*dctsize; |
1094 » » cw[i]=PAD(dinfo->image_width, dinfo->max_h_samp_factor) | 1785 » » pw[i]=PAD(dinfo->output_width, dinfo->max_h_samp_factor) |
1095 *compptr->h_samp_factor/dinfo->max_h_samp_factor; | 1786 *compptr->h_samp_factor/dinfo->max_h_samp_factor; |
1096 » » ch[i]=PAD(dinfo->image_height, dinfo->max_v_samp_factor) | 1787 » » ph[i]=PAD(dinfo->output_height, dinfo->max_v_samp_factor) |
1097 *compptr->v_samp_factor/dinfo->max_v_samp_factor; | 1788 *compptr->v_samp_factor/dinfo->max_v_samp_factor; |
1098 » » if(iw[i]!=cw[i] || ih!=ch[i]) usetmpbuf=1; | 1789 » » if(iw[i]!=pw[i] || ih!=ph[i]) usetmpbuf=1; |
1099 » » th[i]=compptr->v_samp_factor*DCTSIZE; | 1790 » » th[i]=compptr->v_samp_factor*dctsize; |
1100 tmpbufsize+=iw[i]*th[i]; | 1791 tmpbufsize+=iw[i]*th[i]; |
1101 » » if((outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ch[i]))==NULL) | 1792 » » if((outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph[i]))==NULL) |
1102 » » » _throw("tjDecompressToYUV(): Memory allocation failure")
; | 1793 » » » _throw("tjDecompressToYUVPlanes(): Memory allocation fai
lure"); |
1103 » » for(row=0; row<ch[i]; row++) | 1794 » » ptr=dstPlanes[i]; |
| 1795 » » for(row=0; row<ph[i]; row++) |
1104 { | 1796 { |
1105 outbuf[i][row]=ptr; | 1797 outbuf[i][row]=ptr; |
1106 » » » ptr+=PAD(cw[i], 4); | 1798 » » » ptr+=(strides && strides[i]!=0)? strides[i]:pw[i]; |
1107 } | 1799 } |
1108 } | 1800 } |
1109 if(usetmpbuf) | 1801 if(usetmpbuf) |
1110 { | 1802 { |
1111 if((_tmpbuf=(JSAMPLE *)malloc(sizeof(JSAMPLE)*tmpbufsize))==NULL
) | 1803 if((_tmpbuf=(JSAMPLE *)malloc(sizeof(JSAMPLE)*tmpbufsize))==NULL
) |
1112 » » » _throw("tjDecompressToYUV(): Memory allocation failure")
; | 1804 » » » _throw("tjDecompressToYUVPlanes(): Memory allocation fai
lure"); |
1113 ptr=_tmpbuf; | 1805 ptr=_tmpbuf; |
1114 for(i=0; i<dinfo->num_components; i++) | 1806 for(i=0; i<dinfo->num_components; i++) |
1115 { | 1807 { |
1116 if((tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*th[i])
)==NULL) | 1808 if((tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*th[i])
)==NULL) |
1117 » » » » _throw("tjDecompressToYUV(): Memory allocation f
ailure"); | 1809 » » » » _throw("tjDecompressToYUVPlanes(): Memory alloca
tion failure"); |
1118 for(row=0; row<th[i]; row++) | 1810 for(row=0; row<th[i]; row++) |
1119 { | 1811 { |
1120 tmpbuf[i][row]=ptr; | 1812 tmpbuf[i][row]=ptr; |
1121 ptr+=iw[i]; | 1813 ptr+=iw[i]; |
1122 } | 1814 } |
1123 } | 1815 } |
1124 } | 1816 } |
1125 | 1817 |
1126 if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE; | 1818 if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE; |
1127 if(flags&TJFLAG_FASTDCT) dinfo->dct_method=JDCT_FASTEST; | 1819 if(flags&TJFLAG_FASTDCT) dinfo->dct_method=JDCT_FASTEST; |
1128 dinfo->raw_data_out=TRUE; | 1820 dinfo->raw_data_out=TRUE; |
1129 | 1821 |
1130 jpeg_start_decompress(dinfo); | 1822 jpeg_start_decompress(dinfo); |
1131 for(row=0; row<(int)dinfo->output_height; | 1823 for(row=0; row<(int)dinfo->output_height; |
1132 » » row+=dinfo->max_v_samp_factor*DCTSIZE) | 1824 » » row+=dinfo->max_v_samp_factor*dinfo->_min_DCT_scaled_size) |
1133 { | 1825 { |
1134 JSAMPARRAY yuvptr[MAX_COMPONENTS]; | 1826 JSAMPARRAY yuvptr[MAX_COMPONENTS]; |
1135 int crow[MAX_COMPONENTS]; | 1827 int crow[MAX_COMPONENTS]; |
1136 for(i=0; i<dinfo->num_components; i++) | 1828 for(i=0; i<dinfo->num_components; i++) |
1137 { | 1829 { |
1138 jpeg_component_info *compptr=&dinfo->comp_info[i]; | 1830 jpeg_component_info *compptr=&dinfo->comp_info[i]; |
| 1831 if(jpegSubsamp==TJ_420) |
| 1832 { |
| 1833 /* When 4:2:0 subsampling is used with IDCT scal
ing, libjpeg will try |
| 1834 to be clever and use the IDCT to perform upsa
mpling on the U and V |
| 1835 planes. For instance, if the output image is
to be scaled by 1/2 |
| 1836 relative to the JPEG image, then the scaling
factor and upsampling |
| 1837 effectively cancel each other, so a normal 8x
8 IDCT can be used. |
| 1838 However, this is not desirable when using the
decompress-to-YUV |
| 1839 functionality in TurboJPEG, since we want to
output the U and V |
| 1840 planes in their subsampled form. Thus, we ha
ve to override some |
| 1841 internal libjpeg parameters to force it to us
e the "scaled" IDCT |
| 1842 functions on the U and V planes. */ |
| 1843 compptr->_DCT_scaled_size=dctsize; |
| 1844 compptr->MCU_sample_width=tjMCUWidth[jpegSubsamp
]* |
| 1845 sf[sfi].num/sf[sfi].denom* |
| 1846 compptr->v_samp_factor/dinfo->max_v_samp
_factor; |
| 1847 dinfo->idct->inverse_DCT[i] = dinfo->idct->inver
se_DCT[0]; |
| 1848 } |
1139 crow[i]=row*compptr->v_samp_factor/dinfo->max_v_samp_fac
tor; | 1849 crow[i]=row*compptr->v_samp_factor/dinfo->max_v_samp_fac
tor; |
1140 if(usetmpbuf) yuvptr[i]=tmpbuf[i]; | 1850 if(usetmpbuf) yuvptr[i]=tmpbuf[i]; |
1141 else yuvptr[i]=&outbuf[i][crow[i]]; | 1851 else yuvptr[i]=&outbuf[i][crow[i]]; |
1142 } | 1852 } |
1143 » » jpeg_read_raw_data(dinfo, yuvptr, dinfo->max_v_samp_factor*DCTSI
ZE); | 1853 » » jpeg_read_raw_data(dinfo, yuvptr, |
| 1854 » » » dinfo->max_v_samp_factor*dinfo->_min_DCT_scaled_size); |
1144 if(usetmpbuf) | 1855 if(usetmpbuf) |
1145 { | 1856 { |
1146 int j; | 1857 int j; |
1147 for(i=0; i<dinfo->num_components; i++) | 1858 for(i=0; i<dinfo->num_components; i++) |
1148 { | 1859 { |
1149 » » » » for(j=0; j<min(th[i], ch[i]-crow[i]); j++) | 1860 » » » » for(j=0; j<min(th[i], ph[i]-crow[i]); j++) |
1150 { | 1861 { |
1151 » » » » » memcpy(outbuf[i][crow[i]+j], tmpbuf[i][j
], cw[i]); | 1862 » » » » » memcpy(outbuf[i][crow[i]+j], tmpbuf[i][j
], pw[i]); |
1152 } | 1863 } |
1153 } | 1864 } |
1154 } | 1865 } |
1155 } | 1866 } |
1156 jpeg_finish_decompress(dinfo); | 1867 jpeg_finish_decompress(dinfo); |
1157 | 1868 |
1158 bailout: | 1869 bailout: |
1159 if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); | 1870 if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); |
1160 for(i=0; i<MAX_COMPONENTS; i++) | 1871 for(i=0; i<MAX_COMPONENTS; i++) |
1161 { | 1872 { |
1162 if(tmpbuf[i]) free(tmpbuf[i]); | 1873 if(tmpbuf[i]) free(tmpbuf[i]); |
1163 if(outbuf[i]) free(outbuf[i]); | 1874 if(outbuf[i]) free(outbuf[i]); |
1164 } | 1875 } |
1165 if(_tmpbuf) free(_tmpbuf); | 1876 if(_tmpbuf) free(_tmpbuf); |
| 1877 if(this->jerr.warning) retval=-1; |
1166 return retval; | 1878 return retval; |
1167 } | 1879 } |
1168 | 1880 |
| 1881 DLLEXPORT int DLLCALL tjDecompressToYUV2(tjhandle handle, |
| 1882 const unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dst
Buf, |
| 1883 int width, int pad, int height, int flags) |
| 1884 { |
| 1885 unsigned char *dstPlanes[3]; |
| 1886 int pw0, ph0, strides[3], retval=-1, jpegSubsamp=-1; |
| 1887 int i, jpegwidth, jpegheight, scaledw, scaledh; |
1169 | 1888 |
| 1889 getdinstance(handle); |
| 1890 |
| 1891 if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL || width<0 || pad<1 |
| 1892 || !isPow2(pad) || height<0) |
| 1893 _throw("tjDecompressToYUV2(): Invalid argument"); |
| 1894 |
| 1895 jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); |
| 1896 jpeg_read_header(dinfo, TRUE); |
| 1897 jpegSubsamp=getSubsamp(dinfo); |
| 1898 if(jpegSubsamp<0) |
| 1899 _throw("tjDecompressToYUV2(): Could not determine subsampling ty
pe for JPEG image"); |
| 1900 |
| 1901 jpegwidth=dinfo->image_width; jpegheight=dinfo->image_height; |
| 1902 if(width==0) width=jpegwidth; |
| 1903 if(height==0) height=jpegheight; |
| 1904 |
| 1905 for(i=0; i<NUMSF; i++) |
| 1906 { |
| 1907 scaledw=TJSCALED(jpegwidth, sf[i]); |
| 1908 scaledh=TJSCALED(jpegheight, sf[i]); |
| 1909 if(scaledw<=width && scaledh<=height) |
| 1910 break; |
| 1911 } |
| 1912 if(i>=NUMSF) |
| 1913 _throw("tjDecompressToYUV2(): Could not scale down to desired im
age dimensions"); |
| 1914 |
| 1915 pw0=tjPlaneWidth(0, width, jpegSubsamp); |
| 1916 ph0=tjPlaneHeight(0, height, jpegSubsamp); |
| 1917 dstPlanes[0]=dstBuf; |
| 1918 strides[0]=PAD(pw0, pad); |
| 1919 if(jpegSubsamp==TJSAMP_GRAY) |
| 1920 { |
| 1921 strides[1]=strides[2]=0; |
| 1922 dstPlanes[1]=dstPlanes[2]=NULL; |
| 1923 } |
| 1924 else |
| 1925 { |
| 1926 int pw1=tjPlaneWidth(1, width, jpegSubsamp); |
| 1927 int ph1=tjPlaneHeight(1, height, jpegSubsamp); |
| 1928 strides[1]=strides[2]=PAD(pw1, pad); |
| 1929 dstPlanes[1]=dstPlanes[0]+strides[0]*ph0; |
| 1930 dstPlanes[2]=dstPlanes[1]+strides[1]*ph1; |
| 1931 } |
| 1932 |
| 1933 this->headerRead=1; |
| 1934 return tjDecompressToYUVPlanes(handle, jpegBuf, jpegSize, dstPlanes, wid
th, |
| 1935 strides, height, flags); |
| 1936 |
| 1937 bailout: |
| 1938 return retval; |
| 1939 |
| 1940 } |
| 1941 |
| 1942 DLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle, |
| 1943 unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, |
| 1944 int flags) |
| 1945 { |
| 1946 return tjDecompressToYUV2(handle, jpegBuf, jpegSize, dstBuf, 0, 4, 0, fl
ags); |
| 1947 } |
| 1948 |
| 1949 |
1170 /* Transformer */ | 1950 /* Transformer */ |
1171 | 1951 |
1172 DLLEXPORT tjhandle DLLCALL tjInitTransform(void) | 1952 DLLEXPORT tjhandle DLLCALL tjInitTransform(void) |
1173 { | 1953 { |
1174 tjinstance *this=NULL; tjhandle handle=NULL; | 1954 tjinstance *this=NULL; tjhandle handle=NULL; |
1175 if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) | 1955 if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) |
1176 { | 1956 { |
1177 snprintf(errStr, JMSG_LENGTH_MAX, | 1957 snprintf(errStr, JMSG_LENGTH_MAX, |
1178 "tjInitTransform(): Memory allocation failure"); | 1958 "tjInitTransform(): Memory allocation failure"); |
1179 return NULL; | 1959 return NULL; |
1180 } | 1960 } |
1181 MEMZERO(this, sizeof(tjinstance)); | 1961 MEMZERO(this, sizeof(tjinstance)); |
1182 handle=_tjInitCompress(this); | 1962 handle=_tjInitCompress(this); |
1183 if(!handle) return NULL; | 1963 if(!handle) return NULL; |
1184 handle=_tjInitDecompress(this); | 1964 handle=_tjInitDecompress(this); |
1185 return handle; | 1965 return handle; |
1186 } | 1966 } |
1187 | 1967 |
1188 | 1968 |
1189 DLLEXPORT int DLLCALL tjTransform(tjhandle handle, unsigned char *jpegBuf, | 1969 DLLEXPORT int DLLCALL tjTransform(tjhandle handle, |
1190 » unsigned long jpegSize, int n, unsigned char **dstBufs, | 1970 » const unsigned char *jpegBuf, unsigned long jpegSize, int n, |
1191 » unsigned long *dstSizes, tjtransform *t, int flags) | 1971 » unsigned char **dstBufs, unsigned long *dstSizes, tjtransform *t, int fl
ags) |
1192 { | 1972 { |
1193 jpeg_transform_info *xinfo=NULL; | 1973 jpeg_transform_info *xinfo=NULL; |
1194 jvirt_barray_ptr *srccoefs, *dstcoefs; | 1974 jvirt_barray_ptr *srccoefs, *dstcoefs; |
1195 int retval=0, i, jpegSubsamp; | 1975 int retval=0, i, jpegSubsamp; |
1196 | 1976 |
1197 getinstance(handle); | 1977 getinstance(handle); |
1198 if((this->init&COMPRESS)==0 || (this->init&DECOMPRESS)==0) | 1978 if((this->init&COMPRESS)==0 || (this->init&DECOMPRESS)==0) |
1199 _throw("tjTransform(): Instance has not been initialized for tra
nsformation"); | 1979 _throw("tjTransform(): Instance has not been initialized for tra
nsformation"); |
1200 | 1980 |
1201 if(jpegBuf==NULL || jpegSize<=0 || n<1 || dstBufs==NULL || dstSizes==NUL
L | 1981 if(jpegBuf==NULL || jpegSize<=0 || n<1 || dstBufs==NULL || dstSizes==NUL
L |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1329 } | 2109 } |
1330 if(!(t[i].options&TJXOPT_NOOUTPUT)) jpeg_finish_compress(cinfo); | 2110 if(!(t[i].options&TJXOPT_NOOUTPUT)) jpeg_finish_compress(cinfo); |
1331 } | 2111 } |
1332 | 2112 |
1333 jpeg_finish_decompress(dinfo); | 2113 jpeg_finish_decompress(dinfo); |
1334 | 2114 |
1335 bailout: | 2115 bailout: |
1336 if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); | 2116 if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); |
1337 if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); | 2117 if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); |
1338 if(xinfo) free(xinfo); | 2118 if(xinfo) free(xinfo); |
| 2119 if(this->jerr.warning) retval=-1; |
1339 return retval; | 2120 return retval; |
1340 } | 2121 } |
OLD | NEW |