10 #define UINT16 IJPG_UINT16
11 #define INT16 IJPG_INT16
15 #include "libavutil/common.h"
18 #include "vd_internal.h"
20 static vd_info_t info
= {
21 "JPEG Images decoder",
25 "uses Independent JPEG Group's jpeglib"
33 // to set/get/query special features/parameters
34 static int control(sh_video_t
*sh
,int cmd
,void* arg
,...){
35 return CONTROL_UNKNOWN
;
39 static int init(sh_video_t
*sh
){
45 static void uninit(sh_video_t
*sh
){
48 //mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h);
52 struct jpeg_source_mgr pub
;
53 unsigned char * inbuf
;
57 typedef my_source_mgr
* my_src_ptr
;
59 METHODDEF(void) init_source (j_decompress_ptr cinfo
)
63 METHODDEF(boolean
) fill_input_buffer (j_decompress_ptr cinfo
)
65 my_src_ptr src
= (my_src_ptr
) cinfo
->src
;
66 src
->pub
.next_input_byte
= src
->inbuf
;
67 src
->pub
.bytes_in_buffer
= src
->bufsize
;
71 METHODDEF(void) skip_input_data (j_decompress_ptr cinfo
, long num_bytes
)
73 my_src_ptr src
= (my_src_ptr
) cinfo
->src
;
77 while (num_bytes
> (long) src
->pub
.bytes_in_buffer
)
79 num_bytes
-= (long) src
->pub
.bytes_in_buffer
;
80 (void) fill_input_buffer(cinfo
);
82 src
->pub
.next_input_byte
+= (size_t) num_bytes
;
83 src
->pub
.bytes_in_buffer
-= (size_t) num_bytes
;
87 METHODDEF(void) term_source (j_decompress_ptr cinfo
) { }
89 GLOBAL(void) jpeg_buf_src ( j_decompress_ptr cinfo
, char * inbuf
,int bufsize
)
92 if (cinfo
->src
== NULL
) cinfo
->src
=malloc( sizeof( my_source_mgr
) );
93 src
= (my_src_ptr
) cinfo
->src
;
94 src
->pub
.init_source
= init_source
;
95 src
->pub
.fill_input_buffer
= fill_input_buffer
;
96 src
->pub
.skip_input_data
= skip_input_data
;
97 src
->pub
.resync_to_restart
= jpeg_resync_to_restart
;
98 src
->pub
.term_source
= term_source
;
100 src
->bufsize
=bufsize
;
101 src
->pub
.bytes_in_buffer
= 0;
102 src
->pub
.next_input_byte
= NULL
;
107 struct jpeg_error_mgr pub
;
108 jmp_buf setjmp_buffer
;
111 typedef struct my_error_mgr
* my_error_ptr
;
113 METHODDEF(void) my_error_exit (j_common_ptr cinfo
)
115 my_error_ptr myerr
=(my_error_ptr
) cinfo
->err
;
116 (*cinfo
->err
->output_message
) (cinfo
);
117 longjmp(myerr
->setjmp_buffer
, 1);
120 static struct jpeg_decompress_struct cinfo
;
121 static struct my_error_mgr jerr
;
122 static int row_stride
;
123 static unsigned char *temp_row
=NULL
;
126 static mp_image_t
* decode(sh_video_t
*sh
,void* data
,int len
,int flags
){
127 mp_image_t
* mpi
= NULL
;
128 int width
,height
,depth
,i
;
130 if ( len
<= 0 ) return NULL
; // skipped frame
132 cinfo
.err
=jpeg_std_error( &jerr
.pub
);
133 jerr
.pub
.error_exit
=my_error_exit
;
134 if( setjmp( jerr
.setjmp_buffer
) )
136 mp_msg( MSGT_DECVIDEO
,MSGL_ERR
,"[ijpg] setjmp error ...\n" );
140 jpeg_create_decompress( &cinfo
);
141 jpeg_buf_src( &cinfo
,data
,len
);
142 jpeg_read_header( &cinfo
,TRUE
);
143 sh
->disp_w
=width
=cinfo
.image_width
;
144 sh
->disp_h
=height
=cinfo
.image_height
;
145 jpeg_start_decompress( &cinfo
);
146 depth
=cinfo
.output_components
* 8;
151 default: mp_msg( MSGT_DECVIDEO
,MSGL_ERR
,"Sorry, unsupported JPEG colorspace: %d.\n",depth
); return NULL
;
154 if ( last_w
!=width
|| last_h
!=height
)
156 if(!mpcodecs_config_vo( sh
,width
,height
, IMGFMT_RGB24
)) return NULL
;
157 if(temp_row
) free(temp_row
);
158 temp_row
=malloc(3*width
+16);
159 last_w
=width
; last_h
=height
;
162 mpi
=mpcodecs_get_image( sh
,MP_IMGTYPE_TEMP
,MP_IMGFLAG_ACCEPT_STRIDE
,width
,height
);
163 if ( !mpi
) return NULL
;
165 row_stride
=cinfo
.output_width
* cinfo
.output_components
;
167 for ( i
=0;i
< height
;i
++ )
169 unsigned char * drow
= mpi
->planes
[0] + mpi
->stride
[0] * i
;
170 unsigned char * row
= (mpi
->imgfmt
==IMGFMT_RGB24
&& depth
==24) ? drow
: temp_row
;
171 jpeg_read_scanlines( &cinfo
,(JSAMPLE
**)&row
,1 );
173 // grayscale -> rgb/bgr 24/32
176 for(x
=0;x
<width
;x
++) drow
[4*x
]=0x010101*row
[x
];
178 for(x
=0;x
<width
;x
++) drow
[3*x
+0]=drow
[3*x
+1]=drow
[3*x
+2]=row
[x
];
184 for(x
=0;x
<3*width
;x
+=3){
192 for(x
=0;x
<width
;x
++){
193 #ifdef WORDS_BIGENDIAN
194 drow
[4*x
+1]=row
[3*x
+0];
195 drow
[4*x
+2]=row
[3*x
+1];
196 drow
[4*x
+3]=row
[3*x
+2];
198 drow
[4*x
+0]=row
[3*x
+2];
199 drow
[4*x
+1]=row
[3*x
+1];
200 drow
[4*x
+2]=row
[3*x
+0];
208 jpeg_finish_decompress(&cinfo
);
209 jpeg_destroy_decompress(&cinfo
);