10 #define UINT16 IJPG_UINT16
11 #define INT16 IJPG_INT16
17 #include "vd_internal.h"
19 static vd_info_t info
= {
20 "JPEG Images decoder",
24 "uses Independent JPEG Group's jpeglib"
31 static int last_depth
=-1;
33 // to set/get/query special features/parameters
34 static int control(sh_video_t
*sh
,int cmd
,void* arg
,...){
35 if (cmd
== VDCTRL_QUERY_FORMAT
) {
36 int format
= *(int *)arg
;
37 if ((last_depth
== 24 && format
== IMGFMT_RGB24
) ||
38 (last_depth
== 8 && format
== IMGFMT_Y8
))
42 return CONTROL_UNKNOWN
;
46 static int init(sh_video_t
*sh
){
52 static void uninit(sh_video_t
*sh
){
55 //mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h);
59 struct jpeg_source_mgr pub
;
60 unsigned char * inbuf
;
64 typedef my_source_mgr
* my_src_ptr
;
66 METHODDEF(void) init_source (j_decompress_ptr cinfo
)
70 METHODDEF(boolean
) fill_input_buffer (j_decompress_ptr cinfo
)
72 my_src_ptr src
= (my_src_ptr
) cinfo
->src
;
73 src
->pub
.next_input_byte
= src
->inbuf
;
74 src
->pub
.bytes_in_buffer
= src
->bufsize
;
78 METHODDEF(void) skip_input_data (j_decompress_ptr cinfo
, long num_bytes
)
80 my_src_ptr src
= (my_src_ptr
) cinfo
->src
;
84 while (num_bytes
> (long) src
->pub
.bytes_in_buffer
)
86 num_bytes
-= (long) src
->pub
.bytes_in_buffer
;
87 (void) fill_input_buffer(cinfo
);
89 src
->pub
.next_input_byte
+= (size_t) num_bytes
;
90 src
->pub
.bytes_in_buffer
-= (size_t) num_bytes
;
94 METHODDEF(void) term_source (j_decompress_ptr cinfo
) { }
96 GLOBAL(void) jpeg_buf_src ( j_decompress_ptr cinfo
, char * inbuf
,int bufsize
)
99 if (cinfo
->src
== NULL
) cinfo
->src
=malloc( sizeof( my_source_mgr
) );
100 src
= (my_src_ptr
) cinfo
->src
;
101 src
->pub
.init_source
= init_source
;
102 src
->pub
.fill_input_buffer
= fill_input_buffer
;
103 src
->pub
.skip_input_data
= skip_input_data
;
104 src
->pub
.resync_to_restart
= jpeg_resync_to_restart
;
105 src
->pub
.term_source
= term_source
;
107 src
->bufsize
=bufsize
;
108 src
->pub
.bytes_in_buffer
= 0;
109 src
->pub
.next_input_byte
= NULL
;
114 struct jpeg_error_mgr pub
;
115 jmp_buf setjmp_buffer
;
118 typedef struct my_error_mgr
* my_error_ptr
;
120 METHODDEF(void) my_error_exit (j_common_ptr cinfo
)
122 my_error_ptr myerr
=(my_error_ptr
) cinfo
->err
;
123 (*cinfo
->err
->output_message
) (cinfo
);
124 longjmp(myerr
->setjmp_buffer
, 1);
128 static mp_image_t
* decode(sh_video_t
*sh
,void* data
,int len
,int flags
){
129 struct jpeg_decompress_struct cinfo
;
130 struct my_error_mgr jerr
;
131 mp_image_t
* mpi
= NULL
;
132 int width
,height
,depth
,i
;
134 if ( len
<= 0 ) return NULL
; // skipped frame
136 memset(&cinfo
, 0, sizeof(cinfo
));
137 memset(&jerr
, 0, sizeof(jerr
));
138 cinfo
.err
=jpeg_std_error( &jerr
.pub
);
139 jerr
.pub
.error_exit
=my_error_exit
;
140 if( setjmp( jerr
.setjmp_buffer
) )
142 mp_msg( MSGT_DECVIDEO
,MSGL_ERR
,"[ijpg] setjmp error ...\n" );
146 jpeg_create_decompress( &cinfo
);
147 jpeg_buf_src( &cinfo
,data
,len
);
148 jpeg_read_header( &cinfo
,TRUE
);
149 sh
->disp_w
=width
=cinfo
.image_width
;
150 sh
->disp_h
=height
=cinfo
.image_height
;
151 jpeg_start_decompress( &cinfo
);
152 depth
=cinfo
.output_components
* 8;
157 default: mp_msg( MSGT_DECVIDEO
,MSGL_ERR
,"Sorry, unsupported JPEG colorspace: %d.\n",depth
); return NULL
;
160 if ( last_w
!=width
|| last_h
!=height
|| last_depth
!= depth
)
163 if(!mpcodecs_config_vo( sh
,width
,height
, depth
== 8 ? IMGFMT_Y8
: IMGFMT_RGB24
)) return NULL
;
164 last_w
=width
; last_h
=height
;
167 mpi
=mpcodecs_get_image( sh
,MP_IMGTYPE_TEMP
,MP_IMGFLAG_ACCEPT_STRIDE
,width
,height
);
168 if ( !mpi
) return NULL
;
170 for ( i
=0;i
< height
;i
++ )
172 unsigned char * drow
= mpi
->planes
[0] + mpi
->stride
[0] * i
;
173 jpeg_read_scanlines( &cinfo
,(JSAMPLE
**)&drow
,1 );
176 jpeg_finish_decompress(&cinfo
);
177 jpeg_destroy_decompress(&cinfo
);