diff options
author | dcommander <dcommander@3789f03b-4d11-0410-bbf8-ca57d06f2519> | 2010-11-24 04:02:37 +0000 |
---|---|---|
committer | dcommander <dcommander@3789f03b-4d11-0410-bbf8-ca57d06f2519> | 2010-11-24 04:02:37 +0000 |
commit | a86ba64e79349871add40dd32765897705b7d3ea (patch) | |
tree | ac979e38720343a0f2b46b8309d646933dbb186c /trunk/turbojpegl.c | |
parent | 06d4d124fa09f2368243a50bc6d5e4dcacecb81e (diff) |
Merge the TurboJPEG planar YUV encoding feature from VirtualGL 2.2
git-svn-id: https://libjpeg-turbo.svn.sourceforge.net/svnroot/libjpeg-turbo@305 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'trunk/turbojpegl.c')
-rw-r--r-- | trunk/turbojpegl.c | 146 |
1 files changed, 135 insertions, 11 deletions
diff --git a/trunk/turbojpegl.c b/trunk/turbojpegl.c index 03833c5..1d719cb 100644 --- a/trunk/turbojpegl.c +++ b/trunk/turbojpegl.c @@ -18,10 +18,35 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#define JPEG_INTERNALS #include <jpeglib.h> #include <jerror.h> #include <setjmp.h> #include "./turbojpeg.h" +#ifdef sun +#include <malloc.h> +#endif + +void *__memalign(size_t boundary, size_t size) +{ + #if defined(_WIN32) || defined(__APPLE__) + return malloc(size); + #else + #ifdef sun + return memalign(boundary, size); + #else + void *ptr=NULL; + posix_memalign(&ptr, boundary, size); + return ptr; + #endif + #endif +} + +#ifndef min + #define min(a,b) ((a)<(b)?(a):(b)) +#endif + +#define PAD(v, p) ((v+(p)-1)&(~((p)-1))) // Error handling @@ -117,9 +142,18 @@ DLLEXPORT int DLLCALL tjCompress(tjhandle h, int jpegsub, int qual, int flags) { int i; JSAMPROW *row_pointer=NULL; + JSAMPLE *_tmpbuf[MAX_COMPONENTS], *_tmpbuf2[MAX_COMPONENTS]; + JSAMPROW *tmpbuf[MAX_COMPONENTS], *tmpbuf2[MAX_COMPONENTS]; + JSAMPROW *outbuf[MAX_COMPONENTS]; checkhandle(h); + for(i=0; i<MAX_COMPONENTS; i++) + { + tmpbuf[i]=NULL; _tmpbuf[i]=NULL; + tmpbuf2[i]=NULL; _tmpbuf2[i]=NULL; outbuf[i]=NULL; + } + if(srcbuf==NULL || width<=0 || pitch<0 || height<=0 || dstbuf==NULL || size==NULL || jpegsub<0 || jpegsub>=NUMSUBOPT || qual<0 || qual>100) @@ -158,6 +192,14 @@ DLLEXPORT int DLLCALL tjCompress(tjhandle h, if(setjmp(j->jerr.jb)) { // this will execute if LIBJPEG has an error if(row_pointer) free(row_pointer); + for(i=0; i<MAX_COMPONENTS; i++) + { + if(tmpbuf[i]!=NULL) free(tmpbuf[i]); + if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]); + if(tmpbuf2[i]!=NULL) free(tmpbuf2[i]); + if(_tmpbuf2[i]!=NULL) free(_tmpbuf2[i]); + if(outbuf[i]!=NULL) free(outbuf[i]); + } return -1; } @@ -180,24 +222,105 @@ DLLEXPORT int DLLCALL tjCompress(tjhandle h, j->jdms.next_output_byte = dstbuf; j->jdms.free_in_buffer = TJBUFSIZE(j->cinfo.image_width, j->cinfo.image_height); - if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*height))==NULL) - _throw("Memory allocation failed in tjInitCompress()"); - for(i=0; i<height; i++) + jpeg_start_compress(&j->cinfo, TRUE); + if(flags&TJ_YUV) { - if(flags&TJ_BOTTOMUP) row_pointer[i]= &srcbuf[(height-i-1)*pitch]; - else row_pointer[i]= &srcbuf[i*pitch]; + j_compress_ptr cinfo=&j->cinfo; + int row; + int pw=PAD(width, cinfo->max_h_samp_factor); + int ph=PAD(height, cinfo->max_v_samp_factor); + int cw[MAX_COMPONENTS], ch[MAX_COMPONENTS]; + jpeg_component_info *compptr; + JSAMPLE *ptr=dstbuf; unsigned long yuvsize=0; + + if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph))==NULL) + _throw("Memory allocation failed in tjCompress()"); + for(i=0; i<height; i++) + { + if(flags&TJ_BOTTOMUP) row_pointer[i]= &srcbuf[(height-i-1)*pitch]; + else row_pointer[i]= &srcbuf[i*pitch]; + } + if(height<ph) + for(i=height; i<ph; i++) row_pointer[i]=row_pointer[height-1]; + + for(i=0; i<cinfo->num_components; i++) + { + compptr=&cinfo->comp_info[i]; + _tmpbuf[i]=(JSAMPLE *)__memalign(16, + PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE) + /compptr->h_samp_factor, 16) * cinfo->max_v_samp_factor); + if(!_tmpbuf[i]) _throw("Memory allocation failure"); + tmpbuf[i]=(JSAMPROW *)__memalign(16, + sizeof(JSAMPROW)*cinfo->max_v_samp_factor); + if(!tmpbuf[i]) _throw("Memory allocation failure"); + for(row=0; row<cinfo->max_v_samp_factor; row++) + tmpbuf[i][row]=&_tmpbuf[i][ + PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE) + /compptr->h_samp_factor, 16) * row]; + _tmpbuf2[i]=(JSAMPLE *)__memalign(16, + PAD(compptr->width_in_blocks*DCTSIZE, 16) * compptr->v_samp_factor); + if(!_tmpbuf2[i]) _throw("Memory allocation failure"); + tmpbuf2[i]=(JSAMPROW *)__memalign(16, + sizeof(JSAMPROW)*compptr->v_samp_factor); + if(!tmpbuf2[i]) _throw("Memory allocation failure"); + for(row=0; row<compptr->v_samp_factor; row++) + tmpbuf2[i][row]=&_tmpbuf2[i][ + PAD(compptr->width_in_blocks*DCTSIZE, 16) * row]; + cw[i]=pw*compptr->h_samp_factor/cinfo->max_h_samp_factor; + ch[i]=ph*compptr->v_samp_factor/cinfo->max_v_samp_factor; + outbuf[i]=(JSAMPROW *)__memalign(16, sizeof(JSAMPROW)*ch[i]); + if(!outbuf[i]) _throw("Memory allocation failure"); + for(row=0; row<ch[i]; row++) + { + outbuf[i][row]=ptr; + ptr+=PAD(cw[i], 4); + } + } + yuvsize=(unsigned long)(ptr-dstbuf); + + for(row=0; row<ph; row+=cinfo->max_v_samp_factor) + { + (*cinfo->cconvert->color_convert)(cinfo, &row_pointer[row], tmpbuf, + 0, cinfo->max_v_samp_factor); + (cinfo->downsample->downsample)(cinfo, tmpbuf, 0, tmpbuf2, 0); + for(i=0, compptr=cinfo->comp_info; i<cinfo->num_components; + i++, compptr++) + jcopy_sample_rows(tmpbuf2[i], 0, outbuf[i], + row*compptr->v_samp_factor/cinfo->max_v_samp_factor, + compptr->v_samp_factor, cw[i]); + } + *size=yuvsize; + cinfo->next_scanline+=height; } - jpeg_start_compress(&j->cinfo, TRUE); - while(j->cinfo.next_scanline<j->cinfo.image_height) + else { - jpeg_write_scanlines(&j->cinfo, &row_pointer[j->cinfo.next_scanline], - j->cinfo.image_height-j->cinfo.next_scanline); + if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*height))==NULL) + _throw("Memory allocation failed in tjCompress()"); + for(i=0; i<height; i++) + { + if(flags&TJ_BOTTOMUP) row_pointer[i]= &srcbuf[(height-i-1)*pitch]; + else row_pointer[i]= &srcbuf[i*pitch]; + } + while(j->cinfo.next_scanline<j->cinfo.image_height) + { + jpeg_write_scanlines(&j->cinfo, &row_pointer[j->cinfo.next_scanline], + j->cinfo.image_height-j->cinfo.next_scanline); + } } jpeg_finish_compress(&j->cinfo); - *size=TJBUFSIZE(j->cinfo.image_width, j->cinfo.image_height) - -(unsigned long)(j->jdms.free_in_buffer); + if(!(flags&TJ_YUV)) + *size=TJBUFSIZE(j->cinfo.image_width, j->cinfo.image_height) + -(unsigned long)(j->jdms.free_in_buffer); if(row_pointer) free(row_pointer); + for(i=0; i<MAX_COMPONENTS; i++) + { + if(tmpbuf[i]!=NULL) free(tmpbuf[i]); + if(_tmpbuf[i]!=NULL) free(_tmpbuf[i]); + if(tmpbuf2[i]!=NULL) free(tmpbuf2[i]); + if(_tmpbuf2[i]!=NULL) free(_tmpbuf2[i]); + if(outbuf[i]!=NULL) free(outbuf[i]); + } return 0; } @@ -334,6 +457,7 @@ DLLEXPORT int DLLCALL tjDecompress(tjhandle h, #else #error "TurboJPEG requires JPEG colorspace extensions" #endif + if(flags&TJ_FASTUPSAMPLE) j->dinfo.do_fancy_upsampling=FALSE; jpeg_start_decompress(&j->dinfo); |