From 10962f2bc16d19d3a9fc7fe399af8d32f5bcda53 Mon Sep 17 00:00:00 2001 From: dcommander Date: Wed, 30 Oct 2013 23:02:57 +0000 Subject: Extend the TurboJPEG C API to support compressing JPEG images from YUV planar images git-svn-id: svn://svn.code.sf.net/p/libjpeg-turbo/code/trunk@1067 632fc199-4ca6-4c93-a231-07263d6284db --- turbojpeg.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-) (limited to 'turbojpeg.c') diff --git a/turbojpeg.c b/turbojpeg.c index bd37f57..d4ee84a 100644 --- a/turbojpeg.c +++ b/turbojpeg.c @@ -861,6 +861,133 @@ DLLEXPORT int DLLCALL tjEncodeYUV(tjhandle handle, unsigned char *srcBuf, } +DLLEXPORT int DLLCALL tjCompressFromYUV(tjhandle handle, unsigned char *srcBuf, + int width, int pad, int height, int subsamp, unsigned char **jpegBuf, + unsigned long *jpegSize, int jpegQual, int flags) +{ + int i, row, retval=0, alloc=1; JSAMPROW *inbuf[MAX_COMPONENTS]; + int cw[MAX_COMPONENTS], ch[MAX_COMPONENTS], iw[MAX_COMPONENTS], + tmpbufsize=0, usetmpbuf=0, th[MAX_COMPONENTS]; + JSAMPLE *_tmpbuf=NULL, *ptr=srcBuf; JSAMPROW *tmpbuf[MAX_COMPONENTS]; + + for(i=0; iinit&COMPRESS)==0) + _throw("tjCompressFromYUV(): Instance has not been initialized for compression"); + + if(srcBuf==NULL || width<=0 || pad<1 || height<=0 || subsamp<0 + || subsamp>=NUMSUBOPT || jpegBuf==NULL || jpegSize==NULL || jpegQual<0 + || jpegQual>100) + _throw("tjCompressFromYUV(): Invalid argument"); + + if(setjmp(this->jerr.setjmp_buffer)) + { + /* If we get here, the JPEG code has signaled an error. */ + retval=-1; + goto bailout; + } + + cinfo->image_width=width; + cinfo->image_height=height; + + if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); + else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); + else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); + + if(flags&TJFLAG_NOREALLOC) + { + alloc=0; *jpegSize=tjBufSize(width, height, subsamp); + } + jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); + if(setCompDefaults(cinfo, TJPF_RGB, subsamp, jpegQual, flags)==-1) + return -1; + cinfo->raw_data_in=TRUE; + + jpeg_start_compress(cinfo, TRUE); + for(i=0; inum_components; i++) + { + jpeg_component_info *compptr=&cinfo->comp_info[i]; + int ih; + iw[i]=compptr->width_in_blocks*DCTSIZE; + ih=compptr->height_in_blocks*DCTSIZE; + cw[i]=PAD(cinfo->image_width, cinfo->max_h_samp_factor) + *compptr->h_samp_factor/cinfo->max_h_samp_factor; + ch[i]=PAD(cinfo->image_height, cinfo->max_v_samp_factor) + *compptr->v_samp_factor/cinfo->max_v_samp_factor; + if(iw[i]!=cw[i] || ih!=ch[i]) usetmpbuf=1; + th[i]=compptr->v_samp_factor*DCTSIZE; + tmpbufsize+=iw[i]*th[i]; + if((inbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ch[i]))==NULL) + _throw("tjCompressFromYUV(): Memory allocation failure"); + for(row=0; rownum_components; i++) + { + if((tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*th[i]))==NULL) + _throw("tjCompressFromYUV(): Memory allocation failure"); + for(row=0; rowimage_height; + row+=cinfo->max_v_samp_factor*DCTSIZE) + { + JSAMPARRAY yuvptr[MAX_COMPONENTS]; + int crow[MAX_COMPONENTS]; + for(i=0; inum_components; i++) + { + jpeg_component_info *compptr=&cinfo->comp_info[i]; + crow[i]=row*compptr->v_samp_factor/cinfo->max_v_samp_factor; + if(usetmpbuf) + { + int j, k; + for(j=0; jmax_v_samp_factor*DCTSIZE); + } + jpeg_finish_compress(cinfo); + + bailout: + if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); + for(i=0; iimage_width; jpegheight=dinfo->image_height; if(width==0) width=jpegwidth; -- cgit v1.2.3