Do not #include libavutil/common.h. It is not used directly and mpbswap.h
[mplayer.git] / libmpcodecs / vd_ijpg.c
index 3f4fed1..a54b339 100644 (file)
@@ -1,6 +1,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "config.h"
 #include "mp_msg.h"
@@ -11,9 +12,7 @@
 
 #include <setjmp.h>
 
-#include "bswap.h"
-#include "postproc/rgb2rgb.h"
-#include "libvo/fastmemcpy.h"
+#include "mpbswap.h"
 
 #include "vd_internal.h"
 
@@ -29,9 +28,17 @@ LIBVD_EXTERN(ijpg)
 
 static int last_w=-1;
 static int last_h=-1;
+static int last_depth=-1;
 
 // to set/get/query special features/parameters
 static int control(sh_video_t *sh,int cmd,void* arg,...){
+    if (cmd == VDCTRL_QUERY_FORMAT) {
+        int format = *(int *)arg;
+        if ((last_depth == 24 && format == IMGFMT_RGB24) ||
+            (last_depth == 8  && format == IMGFMT_Y8   ))
+            return CONTROL_TRUE;
+        return CONTROL_FALSE;
+    }
     return CONTROL_UNKNOWN;
 }
 
@@ -62,15 +69,15 @@ METHODDEF(void) init_source (j_decompress_ptr cinfo)
 
 METHODDEF(boolean) fill_input_buffer (j_decompress_ptr cinfo)
 {
- my_src_ptr src = (my_src_ptr) cinfo->src;                                                         
+ my_src_ptr src = (my_src_ptr) cinfo->src;
  src->pub.next_input_byte = src->inbuf;
  src->pub.bytes_in_buffer = src->bufsize;
  return TRUE;
 }
-                                                                                                        
-METHODDEF(void) skip_input_data (j_decompress_ptr cinfo, long num_bytes)                           
-{                                                                                                  
- my_src_ptr src = (my_src_ptr) cinfo->src;                                                        
+
+METHODDEF(void) skip_input_data (j_decompress_ptr cinfo, long num_bytes)
+{
+ my_src_ptr src = (my_src_ptr) cinfo->src;
 
  if (num_bytes > 0)
   {
@@ -84,9 +91,9 @@ METHODDEF(void) skip_input_data (j_decompress_ptr cinfo, long num_bytes)
   }
 }
 
-METHODDEF(void) term_source (j_decompress_ptr cinfo) { }                                           
-                                                  
-GLOBAL(void) jpeg_buf_src ( j_decompress_ptr cinfo, char * inbuf,int bufsize )                     
+METHODDEF(void) term_source (j_decompress_ptr cinfo) { }
+
+GLOBAL(void) jpeg_buf_src ( j_decompress_ptr cinfo, char * inbuf,int bufsize )
 {
  my_src_ptr src;
  if (cinfo->src == NULL) cinfo->src=malloc( sizeof( my_source_mgr ) );
@@ -117,18 +124,17 @@ METHODDEF(void) my_error_exit (j_common_ptr cinfo)
  longjmp(myerr->setjmp_buffer, 1);
 }
 
-static struct     jpeg_decompress_struct cinfo;
-static struct     my_error_mgr jerr;
-static int        row_stride;
-static unsigned char *temp_row=NULL;
-
 // decode a frame
 static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
+ struct jpeg_decompress_struct cinfo;
+ struct my_error_mgr jerr;
  mp_image_t * mpi = NULL;
  int         width,height,depth,i;
 
  if ( len <= 0 ) return NULL; // skipped frame
 
+ memset(&cinfo, 0, sizeof(cinfo));
+ memset(&jerr, 0, sizeof(jerr));
  cinfo.err=jpeg_std_error( &jerr.pub );
  jerr.pub.error_exit=my_error_exit;
  if( setjmp( jerr.setjmp_buffer ) )
@@ -136,7 +142,7 @@ static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
    mp_msg( MSGT_DECVIDEO,MSGL_ERR,"[ijpg] setjmp error ...\n" );
    return NULL;
   }
-  
+
  jpeg_create_decompress( &cinfo );
  jpeg_buf_src( &cinfo,data,len );
  jpeg_read_header( &cinfo,TRUE );
@@ -151,62 +157,24 @@ static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
    default: mp_msg( MSGT_DECVIDEO,MSGL_ERR,"Sorry, unsupported JPEG colorspace: %d.\n",depth ); return NULL;
  }
 
- if ( last_w!=width || last_h!=height )
+ if ( last_w!=width || last_h!=height || last_depth != depth )
   {
-   if(!mpcodecs_config_vo( sh,width,height, IMGFMT_RGB24 )) return NULL;
-   if(temp_row) free(temp_row);
-   temp_row=malloc(3*width+16);
+   last_depth = depth;
+   if(!mpcodecs_config_vo( sh,width,height, depth == 8 ? IMGFMT_Y8 : IMGFMT_RGB24 )) return NULL;
    last_w=width; last_h=height;
   }
 
  mpi=mpcodecs_get_image( sh,MP_IMGTYPE_TEMP,MP_IMGFLAG_ACCEPT_STRIDE,width,height );
  if ( !mpi ) return NULL;
 
- row_stride=cinfo.output_width * cinfo.output_components;
-
  for ( i=0;i < height;i++ )
   {
    unsigned char * drow = mpi->planes[0] + mpi->stride[0] * i;
-   unsigned char * row = (mpi->imgfmt==IMGFMT_RGB24 && depth==24) ? drow : temp_row;
-   jpeg_read_scanlines( &cinfo,(JSAMPLE**)&row,1 );
-   if(depth==8){
-       // grayscale -> rgb/bgr 24/32
-       int x;
-       if(mpi->bpp==32)
-         for(x=0;x<width;x++) drow[4*x]=0x010101*row[x];
-       else
-         for(x=0;x<width;x++) drow[3*x+0]=drow[3*x+1]=drow[3*x+2]=row[x];
-   } else {
-       int x;
-       switch(mpi->imgfmt){
-       // rgb24 -> bgr24
-       case IMGFMT_BGR24:
-           for(x=0;x<3*width;x+=3){
-              drow[x+0]=row[x+2];
-              drow[x+1]=row[x+1];
-              drow[x+2]=row[x+0];
-          }
-          break;
-       // rgb24 -> bgr32
-       case IMGFMT_BGR32:
-           for(x=0;x<width;x++){
-#ifdef WORDS_BIGENDIAN
-              drow[4*x+1]=row[3*x+0];
-              drow[4*x+2]=row[3*x+1];
-              drow[4*x+3]=row[3*x+2];
-#else
-              drow[4*x+0]=row[3*x+2];
-              drow[4*x+1]=row[3*x+1];
-              drow[4*x+2]=row[3*x+0];
-#endif
-          }
-          break;
-       }
-   }
+   jpeg_read_scanlines( &cinfo,(JSAMPLE**)&drow,1 );
   }
-  
- jpeg_finish_decompress(&cinfo);                                                                   
- jpeg_destroy_decompress(&cinfo);                                                                  
-           
+
+ jpeg_finish_decompress(&cinfo);
+ jpeg_destroy_decompress(&cinfo);
+
  return mpi;
 }