Logo Search packages:      
Sourcecode: libjpeg-turbo version File versions  Download package

DLLEXPORT int DLLCALL tjEncodeYUV2 ( tjhandle  handle,
unsigned char *  srcBuf,
int  width,
int  pitch,
int  height,
int  pixelFormat,
unsigned char *  dstBuf,
int  subsamp,
int  flags 
)

Encode an RGB or grayscale image into a YUV planar image. This function uses the accelerated color conversion routines in TurboJPEG's underlying codec to produce a planar YUV image that is suitable for X Video. Specifically, if the chrominance components are subsampled along the horizontal dimension, then the width of the luminance plane is padded to 2 in the output image (same goes for the height of the luminance plane, if the chrominance components are subsampled along the vertical dimension.) Also, each line of each plane in the output image is padded to 4 bytes. Although this will work with any subsampling option, it is really only useful in combination with TJ_420, which produces an image compatible with the I420 (AKA "YUV420P") format.

Parameters:
handlea handle to a TurboJPEG compressor or transformer instance
srcBufpointer to an image buffer containing RGB or grayscale pixels to be encoded
widthwidth (in pixels) of the source image
pitchbytes per line of the source image. Normally, this should be width * tjPixelSize[pixelFormat] if the image is unpadded, or TJPAD(width * tjPixelSize[pixelFormat]) if each line of the image is padded to the nearest 32-bit boundary, as is the case for Windows bitmaps. You can also be clever and use this parameter to skip lines, etc. Setting this parameter to 0 is the equivalent of setting it to width * tjPixelSize[pixelFormat].
heightheight (in pixels) of the source image
pixelFormatpixel format of the source image (see Pixel formats.)
dstBufpointer to an image buffer which will receive the YUV image. Use tjBufSizeYUV() to determine the appropriate size for this buffer based on the image width, height, and level of chrominance subsampling.
subsampthe level of chrominance subsampling to be used when generating the YUV image (see Chrominance subsampling options.)
flagsthe bitwise OR of one or more of the flags.
Returns:
0 if successful, or -1 if an error occurred (see tjGetErrorStr().)

Definition at line 479 of file turbojpeg.c.

References TJ_NUMPF, tjBufSizeYUV(), TJFLAG_BOTTOMUP, TJFLAG_FORCEMMX, TJFLAG_FORCESSE, TJFLAG_FORCESSE2, and tjPixelSize.

{
      int i, retval=0;  JSAMPROW *row_pointer=NULL;
      JSAMPLE *_tmpbuf[MAX_COMPONENTS], *_tmpbuf2[MAX_COMPONENTS];
      JSAMPROW *tmpbuf[MAX_COMPONENTS], *tmpbuf2[MAX_COMPONENTS];
      JSAMPROW *outbuf[MAX_COMPONENTS];
      int row, pw, ph, cw[MAX_COMPONENTS], ch[MAX_COMPONENTS];
      JSAMPLE *ptr=dstBuf;
  unsigned long yuvsize=0;
      jpeg_component_info *compptr;

      getinstance(handle);
      if((this->init&COMPRESS)==0)
            _throw("tjEncodeYUV2(): Instance has not been initialized for compression");

      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 || pixelFormat<0
            || pixelFormat>=TJ_NUMPF || dstBuf==NULL || subsamp<0
            || subsamp>=NUMSUBOPT)
            _throw("tjEncodeYUV2(): Invalid argument");

      if(setjmp(this->jerr.setjmp_buffer))
      {
            /* If we get here, the JPEG code has signaled an error. */
            retval=-1;
            goto bailout;
      }

      if(pitch==0) pitch=width*tjPixelSize[pixelFormat];

      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");

      yuvsize=tjBufSizeYUV(width, height, subsamp);
      jpeg_mem_dest_tj(cinfo, &dstBuf, &yuvsize, 0);
      if(setCompDefaults(cinfo, pixelFormat, subsamp, -1)==-1) return -1;

      jpeg_start_compress(cinfo, TRUE);
      pw=PAD(width, cinfo->max_h_samp_factor);
      ph=PAD(height, cinfo->max_v_samp_factor);

      if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*ph))==NULL)
            _throw("tjEncodeYUV2(): Memory allocation failure");
      for(i=0; i<height; i++)
      {
            if(flags&TJFLAG_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 *)malloc(
                  PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE)
                        /compptr->h_samp_factor, 16) * cinfo->max_v_samp_factor + 16);
            if(!_tmpbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure");
            tmpbuf[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*cinfo->max_v_samp_factor);
            if(!tmpbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure");
            for(row=0; row<cinfo->max_v_samp_factor; row++)
            {
                  unsigned char *_tmpbuf_aligned=
                        (unsigned char *)PAD((size_t)_tmpbuf[i], 16);
                  tmpbuf[i][row]=&_tmpbuf_aligned[
                        PAD((compptr->width_in_blocks*cinfo->max_h_samp_factor*DCTSIZE)
                              /compptr->h_samp_factor, 16) * row];
            }
            _tmpbuf2[i]=(JSAMPLE *)malloc(PAD(compptr->width_in_blocks*DCTSIZE, 16)
                  * compptr->v_samp_factor + 16);
            if(!_tmpbuf2[i]) _throw("tjEncodeYUV2(): Memory allocation failure");
            tmpbuf2[i]=(JSAMPROW *)malloc(sizeof(JSAMPROW)*compptr->v_samp_factor);
            if(!tmpbuf2[i]) _throw("tjEncodeYUV2(): Memory allocation failure");
            for(row=0; row<compptr->v_samp_factor; row++)
            {
                  unsigned char *_tmpbuf2_aligned=
                        (unsigned char *)PAD((size_t)_tmpbuf2[i], 16);
                  tmpbuf2[i][row]=&_tmpbuf2_aligned[
                        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 *)malloc(sizeof(JSAMPROW)*ch[i]);
            if(!outbuf[i]) _throw("tjEncodeYUV2(): Memory allocation failure");
            for(row=0; row<ch[i]; row++)
            {
                  outbuf[i][row]=ptr;
                  ptr+=PAD(cw[i], 4);
            }
      }
      if(yuvsize!=(unsigned long)(ptr-dstBuf))
            _throw("tjEncodeYUV2(): Generated image is not the correct size");

      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]);
      }
      cinfo->next_scanline+=height;
      jpeg_abort_compress(cinfo);

      bailout:
      if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo);
      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 retval;
}

Here is the call graph for this function:


Generated by  Doxygen 1.6.0   Back to index