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

Side by Side Diff: turbojpeg.c

Issue 1953443002: Update to libjpeg_turbo 1.4.90 (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/libjpeg_turbo.git@master
Patch Set: Created 4 years, 7 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
« no previous file with comments | « turbojpeg.h ('k') | turbojpeg-jni.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « turbojpeg.h ('k') | turbojpeg-jni.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698