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

Side by Side Diff: third_party/libjpeg_turbo/turbojpeg.c

Issue 7554002: Updates libjpeg-turbo to 1.1.90 (r677) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/
Patch Set: '' Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/libjpeg_turbo/turbojpeg.h ('k') | third_party/libjpeg_turbo/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')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 /*
2 * Copyright (C)2009-2011 D. R. Commander. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * - Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * - Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12 * - Neither the name of the libjpeg-turbo Project nor the names of its
13 * contributors may be used to endorse or promote products derived from this
14 * software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
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
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /* TurboJPEG/OSS: this implements the TurboJPEG API using libjpeg-turbo */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <jinclude.h>
34 #define JPEG_INTERNALS
35 #include <jpeglib.h>
36 #include <jerror.h>
37 #include <setjmp.h>
38 #include "./turbojpeg.h"
39 #include "./tjutil.h"
40 #include "transupp.h"
41
42 extern void jpeg_mem_dest_tj(j_compress_ptr, unsigned char **,
43 unsigned long *, boolean);
44 extern void jpeg_mem_src_tj(j_decompress_ptr, unsigned char *, unsigned long);
45
46 #define PAD(v, p) ((v+(p)-1)&(~((p)-1)))
47
48
49 /* Error handling (based on example in example.c) */
50
51 static char errStr[JMSG_LENGTH_MAX]="No error";
52
53 struct my_error_mgr
54 {
55 struct jpeg_error_mgr pub;
56 jmp_buf setjmp_buffer;
57 };
58 typedef struct my_error_mgr *my_error_ptr;
59
60 static void my_error_exit(j_common_ptr cinfo)
61 {
62 my_error_ptr myerr=(my_error_ptr)cinfo->err;
63 (*cinfo->err->output_message)(cinfo);
64 longjmp(myerr->setjmp_buffer, 1);
65 }
66
67 /* Based on output_message() in jerror.c */
68
69 static void my_output_message(j_common_ptr cinfo)
70 {
71 (*cinfo->err->format_message)(cinfo, errStr);
72 }
73
74
75 /* Global structures, macros, etc. */
76
77 enum {COMPRESS=1, DECOMPRESS=2};
78
79 typedef struct _tjinstance
80 {
81 struct jpeg_compress_struct cinfo;
82 struct jpeg_decompress_struct dinfo;
83 struct my_error_mgr jerr;
84 int init;
85 } tjinstance;
86
87 static const int pixelsize[TJ_NUMSAMP]={3, 3, 3, 1, 3};
88
89 static const JXFORM_CODE xformtypes[TJ_NUMXOP]=
90 {
91 JXFORM_NONE, JXFORM_FLIP_H, JXFORM_FLIP_V, JXFORM_TRANSPOSE,
92 JXFORM_TRANSVERSE, JXFORM_ROT_90, JXFORM_ROT_180, JXFORM_ROT_270
93 };
94
95 #define NUMSF 4
96 static const tjscalingfactor sf[NUMSF]={
97 {1, 1},
98 {1, 2},
99 {1, 4},
100 {1, 8}
101 };
102
103 #define _throw(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s", m); \
104 retval=-1; goto bailout;}
105 #define getinstance(handle) tjinstance *this=(tjinstance *)handle; \
106 j_compress_ptr cinfo=NULL; j_decompress_ptr dinfo=NULL; \
107 if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \
108 return -1;} \
109 cinfo=&this->cinfo; dinfo=&this->dinfo;
110
111 static int getPixelFormat(int pixelSize, int flags)
112 {
113 if(pixelSize==1) return TJPF_GRAY;
114 if(pixelSize==3)
115 {
116 if(flags&TJ_BGR) return TJPF_BGR;
117 else return TJPF_RGB;
118 }
119 if(pixelSize==4)
120 {
121 if(flags&TJ_ALPHAFIRST)
122 {
123 if(flags&TJ_BGR) return TJPF_XBGR;
124 else return TJPF_XRGB;
125 }
126 else
127 {
128 if(flags&TJ_BGR) return TJPF_BGRX;
129 else return TJPF_RGBX;
130 }
131 }
132 return -1;
133 }
134
135 static void setCompDefaults(struct jpeg_compress_struct *cinfo,
136 int pixelFormat, int subsamp, int jpegQual)
137 {
138 switch(pixelFormat)
139 {
140 case TJPF_GRAY:
141 cinfo->in_color_space=JCS_GRAYSCALE; break;
142 #if JCS_EXTENSIONS==1
143 case TJPF_RGB:
144 cinfo->in_color_space=JCS_EXT_RGB; break;
145 case TJPF_BGR:
146 cinfo->in_color_space=JCS_EXT_BGR; break;
147 case TJPF_RGBX:
148 cinfo->in_color_space=JCS_EXT_RGBX; break;
149 case TJPF_BGRX:
150 cinfo->in_color_space=JCS_EXT_BGRX; break;
151 case TJPF_XRGB:
152 cinfo->in_color_space=JCS_EXT_XRGB; break;
153 case TJPF_XBGR:
154 cinfo->in_color_space=JCS_EXT_XBGR; break;
155 #else
156 case TJPF_RGB:
157 if(RGB_RED==0 && RGB_GREEN==1 && RGB_BLUE==2 && RGB_PIXE LSIZE==3)
158 {
159 cinfo->in_color_space=JCS_RGB; break;
160 }
161 default:
162 _throw("Unsupported pixel format");
163 #endif
164 }
165
166 cinfo->input_components=tjPixelSize[pixelFormat];
167 jpeg_set_defaults(cinfo);
168 if(jpegQual>=0)
169 {
170 jpeg_set_quality(cinfo, jpegQual, TRUE);
171 if(jpegQual>=96) cinfo->dct_method=JDCT_ISLOW;
172 else cinfo->dct_method=JDCT_FASTEST;
173 }
174 if(subsamp==TJSAMP_GRAY)
175 jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
176 else
177 jpeg_set_colorspace(cinfo, JCS_YCbCr);
178
179 cinfo->comp_info[0].h_samp_factor=tjMCUWidth[subsamp]/8;
180 cinfo->comp_info[1].h_samp_factor=1;
181 cinfo->comp_info[2].h_samp_factor=1;
182 cinfo->comp_info[0].v_samp_factor=tjMCUHeight[subsamp]/8;
183 cinfo->comp_info[1].v_samp_factor=1;
184 cinfo->comp_info[2].v_samp_factor=1;
185 }
186
187 static void setDecompDefaults(struct jpeg_decompress_struct *dinfo,
188 int pixelFormat)
189 {
190 switch(pixelFormat)
191 {
192 case TJPF_GRAY:
193 dinfo->out_color_space=JCS_GRAYSCALE; break;
194 #if JCS_EXTENSIONS==1
195 case TJPF_RGB:
196 dinfo->out_color_space=JCS_EXT_RGB; break;
197 case TJPF_BGR:
198 dinfo->out_color_space=JCS_EXT_BGR; break;
199 case TJPF_RGBX:
200 dinfo->out_color_space=JCS_EXT_RGBX; break;
201 case TJPF_BGRX:
202 dinfo->out_color_space=JCS_EXT_BGRX; break;
203 case TJPF_XRGB:
204 dinfo->out_color_space=JCS_EXT_XRGB; break;
205 case TJPF_XBGR:
206 dinfo->out_color_space=JCS_EXT_XBGR; break;
207 #else
208 case TJPF_RGB:
209 if(RGB_RED==0 && RGB_GREEN==1 && RGB_BLUE==2 && RGB_PIXE LSIZE==3)
210 {
211 dinfo->out_color_space=JCS_RGB; break;
212 }
213 default:
214 _throw("Unsupported pixel format");
215 #endif
216 }
217 }
218
219
220 static int getSubsamp(j_decompress_ptr dinfo)
221 {
222 int retval=-1, i, k;
223 for(i=0; i<NUMSUBOPT; i++)
224 {
225 if(dinfo->num_components==pixelsize[i])
226 {
227 if(dinfo->comp_info[0].h_samp_factor==tjMCUWidth[i]/8
228 && dinfo->comp_info[0].v_samp_factor==tjMCUHeigh t[i]/8)
229 {
230 int match=0;
231 for(k=1; k<dinfo->num_components; k++)
232 {
233 if(dinfo->comp_info[k].h_samp_factor==1
234 && dinfo->comp_info[k].v_samp_fa ctor==1)
235 match++;
236 }
237 if(match==dinfo->num_components-1)
238 {
239 retval=i; break;
240 }
241 }
242 }
243 }
244 return retval;
245 }
246
247
248 /* General API functions */
249
250 DLLEXPORT char* DLLCALL tjGetErrorStr(void)
251 {
252 return errStr;
253 }
254
255
256 DLLEXPORT int DLLCALL tjDestroy(tjhandle handle)
257 {
258 getinstance(handle);
259 if(setjmp(this->jerr.setjmp_buffer)) return -1;
260 if(this->init&COMPRESS) jpeg_destroy_compress(cinfo);
261 if(this->init&DECOMPRESS) jpeg_destroy_decompress(dinfo);
262 free(this);
263 return 0;
264 }
265
266
267 /* These are exposed mainly because Windows can't malloc() and free() across
268 DLL boundaries except when the CRT DLL is used, and we don't use the CRT DLL
269 with turbojpeg.dll for compatibility reasons. However, these functions
270 can potentially be used for other purposes by different implementations. */
271
272 DLLEXPORT void DLLCALL tjFree(unsigned char *buf)
273 {
274 if(buf) free(buf);
275 }
276
277
278 DLLEXPORT unsigned char *DLLCALL tjAlloc(int bytes)
279 {
280 return (unsigned char *)malloc(bytes);
281 }
282
283
284 /* Compressor */
285
286 static tjhandle _tjInitCompress(tjinstance *this)
287 {
288 unsigned char buffer[1], *buf=buffer; unsigned long size=1;
289
290 /* This is also straight out of example.c */
291 this->cinfo.err=jpeg_std_error(&this->jerr.pub);
292 this->jerr.pub.error_exit=my_error_exit;
293 this->jerr.pub.output_message=my_output_message;
294
295 if(setjmp(this->jerr.setjmp_buffer))
296 {
297 /* If we get here, the JPEG code has signaled an error. */
298 if(this) free(this); return NULL;
299 }
300
301 jpeg_create_compress(&this->cinfo);
302 /* Make an initial call so it will create the destination manager */
303 jpeg_mem_dest_tj(&this->cinfo, &buf, &size, 0);
304
305 this->init|=COMPRESS;
306 return (tjhandle)this;
307 }
308
309 DLLEXPORT tjhandle DLLCALL tjInitCompress(void)
310 {
311 tjinstance *this=NULL;
312 if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL)
313 {
314 snprintf(errStr, JMSG_LENGTH_MAX,
315 "tjInitCompress(): Memory allocation failure");
316 return NULL;
317 }
318 MEMZERO(this, sizeof(tjinstance));
319 return _tjInitCompress(this);
320 }
321
322
323 DLLEXPORT unsigned long DLLCALL tjBufSize(int width, int height,
324 int jpegSubsamp)
325 {
326 unsigned long retval=0; int mcuw, mcuh, chromasf;
327 if(width<1 || height<1 || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT)
328 _throw("tjBufSize(): Invalid argument");
329
330 // This allows for rare corner cases in which a JPEG image can actually be
331 // larger than the uncompressed input (we wouldn't mention it if it hadn 't
332 // happened before.)
333 mcuw=tjMCUWidth[jpegSubsamp];
334 mcuh=tjMCUHeight[jpegSubsamp];
335 chromasf=jpegSubsamp==TJSAMP_GRAY? 0: 4*64/(mcuw*mcuh);
336 retval=PAD(width, mcuw) * PAD(height, mcuh) * (2 + chromasf) + 2048;
337
338 bailout:
339 return retval;
340 }
341
342
343 DLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height)
344 {
345 unsigned long retval=0;
346 if(width<1 || height<1)
347 _throw("TJBUFSIZE(): Invalid argument");
348
349 // This allows for rare corner cases in which a JPEG image can actually be
350 // larger than the uncompressed input (we wouldn't mention it if it hadn 't
351 // happened before.)
352 retval=PAD(width, 16) * PAD(height, 16) * 6 + 2048;
353
354 bailout:
355 return retval;
356 }
357
358
359 DLLEXPORT unsigned long DLLCALL tjBufSizeYUV(int width, int height,
360 int subsamp)
361 {
362 unsigned long retval=0;
363 int pw, ph, cw, ch;
364 if(width<1 || height<1 || subsamp<0 || subsamp>=NUMSUBOPT)
365 _throw("tjBufSizeYUV(): Invalid argument");
366 pw=PAD(width, tjMCUWidth[subsamp]/8);
367 ph=PAD(height, tjMCUHeight[subsamp]/8);
368 cw=pw*8/tjMCUWidth[subsamp]; ch=ph*8/tjMCUHeight[subsamp];
369 retval=PAD(pw, 4)*ph + (subsamp==TJSAMP_GRAY? 0:PAD(cw, 4)*ch*2);
370
371 bailout:
372 return retval;
373 }
374
375
376 DLLEXPORT unsigned long DLLCALL TJBUFSIZEYUV(int width, int height,
377 int subsamp)
378 {
379 return tjBufSizeYUV(width, height, subsamp);
380 }
381
382
383 DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf,
384 int width, int pitch, int height, int pixelFormat, unsigned char **jpegB uf,
385 unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags)
386 {
387 int i, retval=0, alloc=1; JSAMPROW *row_pointer=NULL;
388
389 getinstance(handle)
390 if((this->init&COMPRESS)==0)
391 _throw("tjCompress2(): Instance has not been initialized for com pression");
392
393 if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0
394 || pixelFormat>=TJ_NUMPF || jpegBuf==NULL || jpegSize==NULL
395 || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT || jpegQual<0 || jpeg Qual>100)
396 _throw("tjCompress2(): Invalid argument");
397
398 if(setjmp(this->jerr.setjmp_buffer))
399 {
400 /* If we get here, the JPEG code has signaled an error. */
401 retval=-1;
402 goto bailout;
403 }
404
405 if(pitch==0) pitch=width*tjPixelSize[pixelFormat];
406
407 cinfo->image_width=width;
408 cinfo->image_height=height;
409
410 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
411 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1");
412 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
413
414 if(flags&TJFLAG_NOREALLOC)
415 {
416 alloc=0; *jpegSize=tjBufSize(width, height, jpegSubsamp);
417 }
418 jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc);
419 setCompDefaults(cinfo, pixelFormat, jpegSubsamp, jpegQual);
420
421 jpeg_start_compress(cinfo, TRUE);
422 if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*height))==NULL)
423 _throw("tjCompress2(): Memory allocation failure");
424 for(i=0; i<height; i++)
425 {
426 if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&srcBuf[(height-i-1)*pi tch];
427 else row_pointer[i]=&srcBuf[i*pitch];
428 }
429 while(cinfo->next_scanline<cinfo->image_height)
430 {
431 jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline],
432 cinfo->image_height-cinfo->next_scanline);
433 }
434 jpeg_finish_compress(cinfo);
435
436 bailout:
437 if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo);
438 if(row_pointer) free(row_pointer);
439 return retval;
440 }
441
442 DLLEXPORT int DLLCALL tjCompress(tjhandle handle, unsigned char *srcBuf,
443 int width, int pitch, int height, int pixelSize, unsigned char *jpegBuf,
444 unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags)
445 {
446 int retval=0; unsigned long size;
447 if(flags&TJ_YUV)
448 {
449 size=tjBufSizeYUV(width, height, jpegSubsamp);
450 retval=tjEncodeYUV2(handle, srcBuf, width, pitch, height,
451 getPixelFormat(pixelSize, flags), jpegBuf, jpegSubsamp, flags);
452 }
453 else
454 {
455 retval=tjCompress2(handle, srcBuf, width, pitch, height,
456 getPixelFormat(pixelSize, flags), &jpegBuf, &size, jpegS ubsamp, jpegQual,
457 flags|TJFLAG_NOREALLOC);
458 }
459 *jpegSize=size;
460 return retval;
461 }
462
463
464 DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf,
465 int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf ,
466 int subsamp, int flags)
467 {
468 int i, retval=0; JSAMPROW *row_pointer=NULL;
469 JSAMPLE *_tmpbuf[MAX_COMPONENTS], *_tmpbuf2[MAX_COMPONENTS];
470 JSAMPROW *tmpbuf[MAX_COMPONENTS], *tmpbuf2[MAX_COMPONENTS];
471 JSAMPROW *outbuf[MAX_COMPONENTS];
472 int row, pw, ph, cw[MAX_COMPONENTS], ch[MAX_COMPONENTS];
473 JSAMPLE *ptr=dstBuf;
474 unsigned long yuvsize=0;
475 jpeg_component_info *compptr;
476
477 getinstance(handle);
478 if((this->init&COMPRESS)==0)
479 _throw("tjEncodeYUV2(): Instance has not been initialized for co mpression");
480
481 for(i=0; i<MAX_COMPONENTS; i++)
482 {
483 tmpbuf[i]=NULL; _tmpbuf[i]=NULL;
484 tmpbuf2[i]=NULL; _tmpbuf2[i]=NULL; outbuf[i]=NULL;
485 }
486
487 if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0
488 || pixelFormat>=TJ_NUMPF || dstBuf==NULL || subsamp<0
489 || subsamp>=NUMSUBOPT)
490 _throw("tjEncodeYUV2(): Invalid argument");
491
492 if(setjmp(this->jerr.setjmp_buffer))
493 {
494 /* If we get here, the JPEG code has signaled an error. */
495 retval=-1;
496 goto bailout;
497 }
498
499 if(pitch==0) pitch=width*tjPixelSize[pixelFormat];
500
501 cinfo->image_width=width;
502 cinfo->image_height=height;
503
504 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
505 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1");
506 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
507
508 yuvsize=tjBufSizeYUV(width, height, subsamp);
509 jpeg_mem_dest_tj(cinfo, &dstBuf, &yuvsize, 0);
510 setCompDefaults(cinfo, pixelFormat, subsamp, -1);
511
512 jpeg_start_compress(cinfo, TRUE);
513 pw=PAD(width, cinfo->max_h_samp_factor);
514 ph=PAD(height, cinfo->max_v_samp_factor);
515
516 if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph))==NULL)
517 _throw("tjEncodeYUV2(): Memory allocation failure");
518 for(i=0; i<height; i++)
519 {
520 if(flags&TJFLAG_BOTTOMUP) row_pointer[i]=&srcBuf[(height-i-1)*pi tch];
521 else row_pointer[i]=&srcBuf[i*pitch];
522 }
523 if(height<ph)
524 for(i=height; i<ph; i++) row_pointer[i]=row_pointer[height-1];
525
526 for(i=0; i<cinfo->num_components; i++)
527 {
528 compptr=&cinfo->comp_info[i];
529 _tmpbuf[i]=(JSAMPLE *)malloc(
530 PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*D CTSIZE)
531 /compptr->h_samp_factor, 16) * cinfo->max_v_samp _factor + 16);
532 if(!_tmpbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failur e");
533 tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*cinfo->max_v_samp_ factor);
534 if(!tmpbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure ");
535 for(row=0; row<cinfo->max_v_samp_factor; row++)
536 {
537 unsigned char *_tmpbuf_aligned=
538 (unsigned char *)PAD((size_t)_tmpbuf[i], 16);
539 tmpbuf[i][row]=&_tmpbuf_aligned[
540 PAD((compptr->width_in_blocks*cinfo->max_h_samp_ factor*DCTSIZE)
541 /compptr->h_samp_factor, 16) * row];
542 }
543 _tmpbuf2[i]=(JSAMPLE *)malloc(PAD(compptr->width_in_blocks*DCTSI ZE, 16)
544 * compptr->v_samp_factor + 16);
545 if(!_tmpbuf2[i]) _throw("tjEncodeYUV2(): Memory allocation failu re");
546 tmpbuf2[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*compptr->v_samp_f actor);
547 if(!tmpbuf2[i]) _throw("tjEncodeYUV2(): Memory allocation failur e");
548 for(row=0; row<compptr->v_samp_factor; row++)
549 {
550 unsigned char *_tmpbuf2_aligned=
551 (unsigned char *)PAD((size_t)_tmpbuf2[i], 16);
552 tmpbuf2[i][row]=&_tmpbuf2_aligned[
553 PAD(compptr->width_in_blocks*DCTSIZE, 16) * row] ;
554 }
555 cw[i]=pw*compptr->h_samp_factor/cinfo->max_h_samp_factor;
556 ch[i]=ph*compptr->v_samp_factor/cinfo->max_v_samp_factor;
557 outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ch[i]);
558 if(!outbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure ");
559 for(row=0; row<ch[i]; row++)
560 {
561 outbuf[i][row]=ptr;
562 ptr+=PAD(cw[i], 4);
563 }
564 }
565 if(yuvsize!=(unsigned long)(ptr-dstBuf))
566 _throw("tjEncodeYUV2(): Generated image is not the correct size" );
567
568 for(row=0; row<ph; row+=cinfo->max_v_samp_factor)
569 {
570 (*cinfo->cconvert->color_convert)(cinfo, &row_pointer[row], tmpb uf, 0,
571 cinfo->max_v_samp_factor);
572 (cinfo->downsample->downsample)(cinfo, tmpbuf, 0, tmpbuf2, 0);
573 for(i=0, compptr=cinfo->comp_info; i<cinfo->num_components; i++, compptr++)
574 jcopy_sample_rows(tmpbuf2[i], 0, outbuf[i],
575 row*compptr->v_samp_factor/cinfo->max_v_samp_fac tor,
576 compptr->v_samp_factor, cw[i]);
577 }
578 cinfo->next_scanline+=height;
579 jpeg_abort_compress(cinfo);
580
581 bailout:
582 if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo);
583 if(row_pointer) free(row_pointer);
584 for(i=0; i<MAX_COMPONENTS; i++)
585 {
586 if(tmpbuf[i]!=NULL) free(tmpbuf[i]);
587 if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]);
588 if(tmpbuf2[i]!=NULL) free(tmpbuf2[i]);
589 if(_tmpbuf2[i]!=NULL) free(_tmpbuf2[i]);
590 if(outbuf[i]!=NULL) free(outbuf[i]);
591 }
592 return retval;
593 }
594
595 DLLEXPORT int DLLCALL tjEncodeYUV(tjhandle handle, unsigned char *srcBuf,
596 int width, int pitch, int height, int pixelSize, unsigned char *dstBuf,
597 int subsamp, int flags)
598 {
599 return tjEncodeYUV2(handle, srcBuf, width, pitch, height,
600 getPixelFormat(pixelSize, flags), dstBuf, subsamp, flags);
601 }
602
603
604 /* Decompressor */
605
606 static tjhandle _tjInitDecompress(tjinstance *this)
607 {
608 unsigned char buffer[1];
609
610 /* This is also straight out of example.c */
611 this->dinfo.err=jpeg_std_error(&this->jerr.pub);
612 this->jerr.pub.error_exit=my_error_exit;
613 this->jerr.pub.output_message=my_output_message;
614
615 if(setjmp(this->jerr.setjmp_buffer))
616 {
617 /* If we get here, the JPEG code has signaled an error. */
618 if(this) free(this); return NULL;
619 }
620
621 jpeg_create_decompress(&this->dinfo);
622 /* Make an initial call so it will create the source manager */
623 jpeg_mem_src_tj(&this->dinfo, buffer, 1);
624
625 this->init|=DECOMPRESS;
626 return (tjhandle)this;
627 }
628
629 DLLEXPORT tjhandle DLLCALL tjInitDecompress(void)
630 {
631 tjinstance *this;
632 if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL)
633 {
634 snprintf(errStr, JMSG_LENGTH_MAX,
635 "tjInitDecompress(): Memory allocation failure");
636 return NULL;
637 }
638 MEMZERO(this, sizeof(tjinstance));
639 return _tjInitDecompress(this);
640 }
641
642
643 DLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle,
644 unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height,
645 int *jpegSubsamp)
646 {
647 int retval=0;
648
649 getinstance(handle);
650 if((this->init&DECOMPRESS)==0)
651 _throw("tjDecompressHeader2(): Instance has not been initialized for decompression");
652
653 if(jpegBuf==NULL || jpegSize<=0 || width==NULL || height==NULL
654 || jpegSubsamp==NULL)
655 _throw("tjDecompressHeader2(): Invalid argument");
656
657 if(setjmp(this->jerr.setjmp_buffer))
658 {
659 /* If we get here, the JPEG code has signaled an error. */
660 return -1;
661 }
662
663 jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize);
664 jpeg_read_header(dinfo, TRUE);
665
666 *width=dinfo->image_width;
667 *height=dinfo->image_height;
668 *jpegSubsamp=getSubsamp(dinfo);
669
670 jpeg_abort_decompress(dinfo);
671
672 if(*jpegSubsamp<0)
673 _throw("tjDecompressHeader2(): Could not determine subsampling t ype for JPEG image");
674 if(*width<1 || *height<1)
675 _throw("tjDecompressHeader2(): Invalid data returned in header") ;
676
677 bailout:
678 return retval;
679 }
680
681 DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle handle,
682 unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height)
683 {
684 int jpegSubsamp;
685 return tjDecompressHeader2(handle, jpegBuf, jpegSize, width, height,
686 &jpegSubsamp);
687 }
688
689
690 DLLEXPORT tjscalingfactor* DLLCALL tjGetScalingFactors(int *numscalingfactors)
691 {
692 if(numscalingfactors==NULL)
693 {
694 snprintf(errStr, JMSG_LENGTH_MAX,
695 "tjGetScalingFactors(): Invalid argument");
696 return NULL;
697 }
698
699 *numscalingfactors=NUMSF;
700 return (tjscalingfactor *)sf;
701 }
702
703
704 DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, unsigned char *jpegBuf,
705 unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch,
706 int height, int pixelFormat, int flags)
707 {
708 int i, retval=0; JSAMPROW *row_pointer=NULL;
709 int jpegwidth, jpegheight, scaledw, scaledh;
710
711 getinstance(handle);
712 if((this->init&DECOMPRESS)==0)
713 _throw("tjDecompress2(): Instance has not been initialized for d ecompression");
714
715 if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL || width<0 || pitch<0
716 || height<0 || pixelFormat<0 || pixelFormat>=TJ_NUMPF)
717 _throw("tjDecompress2(): Invalid argument");
718
719 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
720 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1");
721 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
722
723 if(setjmp(this->jerr.setjmp_buffer))
724 {
725 /* If we get here, the JPEG code has signaled an error. */
726 retval=-1;
727 goto bailout;
728 }
729
730 jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize);
731 jpeg_read_header(dinfo, TRUE);
732 setDecompDefaults(dinfo, pixelFormat);
733
734 if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE;
735
736 jpegwidth=dinfo->image_width; jpegheight=dinfo->image_height;
737 if(width==0) width=jpegwidth;
738 if(height==0) height=jpegheight;
739 for(i=0; i<NUMSF; i++)
740 {
741 scaledw=TJSCALED(jpegwidth, sf[i]);
742 scaledh=TJSCALED(jpegheight, sf[i]);
743 if(scaledw<=width && scaledh<=height)
744 break;
745 }
746 if(scaledw>width || scaledh>height)
747 _throw("tjDecompress2(): Could not scale down to desired image d imensions");
748 width=scaledw; height=scaledh;
749 dinfo->scale_num=sf[i].num;
750 dinfo->scale_denom=sf[i].denom;
751
752 jpeg_start_decompress(dinfo);
753 if(pitch==0) pitch=dinfo->output_width*tjPixelSize[pixelFormat];
754 if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)
755 *dinfo->output_height))==NULL)
756 _throw("tjDecompress2(): Memory allocation failure");
757 for(i=0; i<(int)dinfo->output_height; i++)
758 {
759 if(flags&TJFLAG_BOTTOMUP)
760 row_pointer[i]=&dstBuf[(dinfo->output_height-i-1)*pitch] ;
761 else row_pointer[i]=&dstBuf[i*pitch];
762 }
763 while(dinfo->output_scanline<dinfo->output_height)
764 {
765 jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline],
766 dinfo->output_height-dinfo->output_scanline);
767 }
768 jpeg_finish_decompress(dinfo);
769
770 bailout:
771 if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo);
772 if(row_pointer) free(row_pointer);
773 return retval;
774 }
775
776 DLLEXPORT int DLLCALL tjDecompress(tjhandle handle, unsigned char *jpegBuf,
777 unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch,
778 int height, int pixelSize, int flags)
779 {
780 if(flags&TJ_YUV)
781 return tjDecompressToYUV(handle, jpegBuf, jpegSize, dstBuf, flag s);
782 else
783 return tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, width, p itch,
784 height, getPixelFormat(pixelSize, flags), flags);
785 }
786
787
788 DLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle handle,
789 unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf,
790 int flags)
791 {
792 int i, row, retval=0; JSAMPROW *outbuf[MAX_COMPONENTS];
793 int cw[MAX_COMPONENTS], ch[MAX_COMPONENTS], iw[MAX_COMPONENTS],
794 tmpbufsize=0, usetmpbuf=0, th[MAX_COMPONENTS];
795 JSAMPLE *_tmpbuf=NULL, *ptr=dstBuf; JSAMPROW *tmpbuf[MAX_COMPONENTS];
796
797 getinstance(handle);
798 if((this->init&DECOMPRESS)==0)
799 _throw("tjDecompressToYUV(): Instance has not been initialized f or decompression");
800
801 for(i=0; i<MAX_COMPONENTS; i++)
802 {
803 tmpbuf[i]=NULL; outbuf[i]=NULL;
804 }
805
806 if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL)
807 _throw("tjDecompressToYUV(): Invalid argument");
808
809 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
810 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1");
811 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
812
813 if(setjmp(this->jerr.setjmp_buffer))
814 {
815 /* If we get here, the JPEG code has signaled an error. */
816 retval=-1;
817 goto bailout;
818 }
819
820 jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize);
821 jpeg_read_header(dinfo, TRUE);
822
823 for(i=0; i<dinfo->num_components; i++)
824 {
825 jpeg_component_info *compptr=&dinfo->comp_info[i];
826 int ih;
827 iw[i]=compptr->width_in_blocks*DCTSIZE;
828 ih=compptr->height_in_blocks*DCTSIZE;
829 cw[i]=PAD(dinfo->image_width, dinfo->max_h_samp_factor)
830 *compptr->h_samp_factor/dinfo->max_h_samp_factor;
831 ch[i]=PAD(dinfo->image_height, dinfo->max_v_samp_factor)
832 *compptr->v_samp_factor/dinfo->max_v_samp_factor;
833 if(iw[i]!=cw[i] || ih!=ch[i]) usetmpbuf=1;
834 th[i]=compptr->v_samp_factor*DCTSIZE;
835 tmpbufsize+=iw[i]*th[i];
836 if((outbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ch[i]))==NULL)
837 _throw("tjDecompressToYUV(): Memory allocation failure") ;
838 for(row=0; row<ch[i]; row++)
839 {
840 outbuf[i][row]=ptr;
841 ptr+=PAD(cw[i], 4);
842 }
843 }
844 if(usetmpbuf)
845 {
846 if((_tmpbuf=(JSAMPLE *)malloc(sizeof(JSAMPLE)*tmpbufsize))==NULL )
847 _throw("tjDecompressToYUV(): Memory allocation failure") ;
848 ptr=_tmpbuf;
849 for(i=0; i<dinfo->num_components; i++)
850 {
851 if((tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*th[i]) )==NULL)
852 _throw("tjDecompressToYUV(): Memory allocation f ailure");
853 for(row=0; row<th[i]; row++)
854 {
855 tmpbuf[i][row]=ptr;
856 ptr+=iw[i];
857 }
858 }
859 }
860
861 if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE;
862 dinfo->raw_data_out=TRUE;
863
864 jpeg_start_decompress(dinfo);
865 for(row=0; row<(int)dinfo->output_height;
866 row+=dinfo->max_v_samp_factor*DCTSIZE)
867 {
868 JSAMPARRAY yuvptr[MAX_COMPONENTS];
869 int crow[MAX_COMPONENTS];
870 for(i=0; i<dinfo->num_components; i++)
871 {
872 jpeg_component_info *compptr=&dinfo->comp_info[i];
873 crow[i]=row*compptr->v_samp_factor/dinfo->max_v_samp_fac tor;
874 if(usetmpbuf) yuvptr[i]=tmpbuf[i];
875 else yuvptr[i]=&outbuf[i][crow[i]];
876 }
877 jpeg_read_raw_data(dinfo, yuvptr, dinfo->max_v_samp_factor*DCTSI ZE);
878 if(usetmpbuf)
879 {
880 int j;
881 for(i=0; i<dinfo->num_components; i++)
882 {
883 for(j=0; j<min(th[i], ch[i]-crow[i]); j++)
884 {
885 memcpy(outbuf[i][crow[i]+j], tmpbuf[i][j ], cw[i]);
886 }
887 }
888 }
889 }
890 jpeg_finish_decompress(dinfo);
891
892 bailout:
893 if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo);
894 for(i=0; i<MAX_COMPONENTS; i++)
895 {
896 if(tmpbuf[i]) free(tmpbuf[i]);
897 if(outbuf[i]) free(outbuf[i]);
898 }
899 if(_tmpbuf) free(_tmpbuf);
900 return retval;
901 }
902
903
904 /* Transformer */
905
906 DLLEXPORT tjhandle DLLCALL tjInitTransform(void)
907 {
908 tjinstance *this=NULL; tjhandle handle=NULL;
909 if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL)
910 {
911 snprintf(errStr, JMSG_LENGTH_MAX,
912 "tjInitTransform(): Memory allocation failure");
913 return NULL;
914 }
915 MEMZERO(this, sizeof(tjinstance));
916 handle=_tjInitCompress(this);
917 if(!handle) return NULL;
918 handle=_tjInitDecompress(this);
919 return handle;
920 }
921
922
923 DLLEXPORT int DLLCALL tjTransform(tjhandle handle, unsigned char *jpegBuf,
924 unsigned long jpegSize, int n, unsigned char **dstBufs,
925 unsigned long *dstSizes, tjtransform *t, int flags)
926 {
927 jpeg_transform_info *xinfo=NULL;
928 jvirt_barray_ptr *srccoefs, *dstcoefs;
929 int retval=0, i, jpegSubsamp;
930
931 getinstance(handle);
932 if((this->init&COMPRESS)==0 || (this->init&DECOMPRESS)==0)
933 _throw("tjTransform(): Instance has not been initialized for tra nsformation");
934
935 if(jpegBuf==NULL || jpegSize<=0 || n<1 || dstBufs==NULL || dstSizes==NUL L
936 || t==NULL || flags<0)
937 _throw("tjTransform(): Invalid argument");
938
939 if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
940 else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1");
941 else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
942
943 if(setjmp(this->jerr.setjmp_buffer))
944 {
945 /* If we get here, the JPEG code has signaled an error. */
946 retval=-1;
947 goto bailout;
948 }
949
950 jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize);
951
952 if((xinfo=(jpeg_transform_info *)malloc(sizeof(jpeg_transform_info)*n))
953 ==NULL)
954 _throw("tjTransform(): Memory allocation failure");
955 MEMZERO(xinfo, sizeof(jpeg_transform_info)*n);
956
957 for(i=0; i<n; i++)
958 {
959 xinfo[i].transform=xformtypes[t[i].op];
960 xinfo[i].perfect=(t[i].options&TJXOPT_PERFECT)? 1:0;
961 xinfo[i].trim=(t[i].options&TJXOPT_TRIM)? 1:0;
962 xinfo[i].force_grayscale=(t[i].options&TJXOPT_GRAY)? 1:0;
963 xinfo[i].crop=(t[i].options&TJXOPT_CROP)? 1:0;
964 if(n!=1 && t[i].op==TJXOP_HFLIP) xinfo[i].slow_hflip=1;
965 else xinfo[i].slow_hflip=0;
966
967 if(xinfo[i].crop)
968 {
969 xinfo[i].crop_xoffset=t[i].r.x; xinfo[i].crop_xoffset_s et=JCROP_POS;
970 xinfo[i].crop_yoffset=t[i].r.y; xinfo[i].crop_yoffset_s et=JCROP_POS;
971 if(t[i].r.w!=0)
972 {
973 xinfo[i].crop_width=t[i].r.w; xinfo[i].crop_wid th_set=JCROP_POS;
974 }
975 else xinfo[i].crop_width=JCROP_UNSET;
976 if(t[i].r.h!=0)
977 {
978 xinfo[i].crop_height=t[i].r.h; xinfo[i].crop_he ight_set=JCROP_POS;
979 }
980 else xinfo[i].crop_height=JCROP_UNSET;
981 }
982 }
983
984 jcopy_markers_setup(dinfo, JCOPYOPT_ALL);
985 jpeg_read_header(dinfo, TRUE);
986 jpegSubsamp=getSubsamp(dinfo);
987 if(jpegSubsamp<0)
988 _throw("tjTransform(): Could not determine subsampling type for JPEG image");
989
990 for(i=0; i<n; i++)
991 {
992 if(!jtransform_request_workspace(dinfo, &xinfo[i]))
993 _throw("tjTransform(): Transform is not perfect");
994
995 if(xinfo[i].crop)
996 {
997 if((t[i].r.x%xinfo[i].iMCU_sample_width)!=0
998 || (t[i].r.y%xinfo[i].iMCU_sample_height)!=0)
999 {
1000 snprintf(errStr, JMSG_LENGTH_MAX,
1001 "To crop this JPEG image, x must be a mu ltiple of %d\n"
1002 "and y must be a multiple of %d.\n",
1003 xinfo[i].iMCU_sample_width, xinfo[i].iMC U_sample_height);
1004 retval=-1; goto bailout;
1005 }
1006 }
1007 }
1008
1009 srccoefs=jpeg_read_coefficients(dinfo);
1010
1011 for(i=0; i<n; i++)
1012 {
1013 int w, h, alloc=1;
1014 if(!xinfo[i].crop)
1015 {
1016 w=dinfo->image_width; h=dinfo->image_height;
1017 }
1018 else
1019 {
1020 w=xinfo[i].crop_width; h=xinfo[i].crop_height;
1021 }
1022 if(flags&TJFLAG_NOREALLOC)
1023 {
1024 alloc=0; dstSizes[i]=tjBufSize(w, h, jpegSubsamp);
1025 }
1026 jpeg_mem_dest_tj(cinfo, &dstBufs[i], &dstSizes[i], alloc);
1027 jpeg_copy_critical_parameters(dinfo, cinfo);
1028 dstcoefs=jtransform_adjust_parameters(dinfo, cinfo, srccoefs,
1029 &xinfo[i]);
1030 jpeg_write_coefficients(cinfo, dstcoefs);
1031 jcopy_markers_execute(dinfo, cinfo, JCOPYOPT_ALL);
1032 jtransform_execute_transformation(dinfo, cinfo, srccoefs,
1033 &xinfo[i]);
1034 jpeg_finish_compress(cinfo);
1035 }
1036
1037 jpeg_finish_decompress(dinfo);
1038
1039 bailout:
1040 if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo);
1041 if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo);
1042 if(xinfo) free(xinfo);
1043 return retval;
1044 }
OLDNEW
« no previous file with comments | « third_party/libjpeg_turbo/turbojpeg.h ('k') | third_party/libjpeg_turbo/turbojpeg-jni.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698