Mercurial > mplayer.hg
annotate libmpcodecs/vd_ijpg.c @ 27975:806c541d03dd
Do not draw in window if our image has not yet been adjusted to the new window size.
Fixes some cases of borders not being black in fullscreen when fullscreen image
is scaled down.
author | reimar |
---|---|
date | Sun, 23 Nov 2008 20:39:15 +0000 |
parents | b21e1506e50b |
children | bbb6ebec87a0 |
rev | line source |
---|---|
5029 | 1 |
2 #include <stdio.h> | |
3 #include <stdlib.h> | |
23305
22d3d12c6dfb
Include string.h for memcpy, fastmemcpy.h alone is not enough.
reimar
parents:
21507
diff
changeset
|
4 #include <string.h> |
5029 | 5 |
6 #include "config.h" | |
7 #include "mp_msg.h" | |
8 | |
9 #include <jpeglib.h> | |
5048 | 10 #define UINT16 IJPG_UINT16 |
11 #define INT16 IJPG_INT16 | |
5029 | 12 |
13 #include <setjmp.h> | |
14 | |
21507
fa99b3d31d13
Hack around libavutil/bswap.h compilation problems due to always_inline undefined.
reimar
parents:
21372
diff
changeset
|
15 #include "mpbswap.h" |
5029 | 16 |
17 #include "vd_internal.h" | |
18 | |
19 static vd_info_t info = { | |
20 "JPEG Images decoder", | |
21 "ijpg", | |
22 "Pontscho", | |
23 "based on vd_mpng.c", | |
18604 | 24 "uses Independent JPEG Group's jpeglib" |
5029 | 25 }; |
26 | |
27 LIBVD_EXTERN(ijpg) | |
28 | |
29 static int last_w=-1; | |
30 static int last_h=-1; | |
25667
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
31 static int last_depth=-1; |
5029 | 32 |
33 // to set/get/query special features/parameters | |
34 static int control(sh_video_t *sh,int cmd,void* arg,...){ | |
25667
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
35 if (cmd == VDCTRL_QUERY_FORMAT) { |
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
36 int format = *(int *)arg; |
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
37 if ((last_depth == 24 && format == IMGFMT_RGB24) || |
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
38 (last_depth == 8 && format == IMGFMT_Y8 )) |
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
39 return CONTROL_TRUE; |
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
40 return CONTROL_FALSE; |
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
41 } |
5029 | 42 return CONTROL_UNKNOWN; |
43 } | |
44 | |
45 // init driver | |
46 static int init(sh_video_t *sh){ | |
47 last_w=-1; | |
48 return 1; | |
49 } | |
50 | |
51 // uninit driver | |
52 static void uninit(sh_video_t *sh){ | |
53 } | |
54 | |
55 //mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h); | |
56 | |
57 typedef struct | |
58 { | |
59 struct jpeg_source_mgr pub; | |
60 unsigned char * inbuf; | |
61 int bufsize; | |
62 } my_source_mgr; | |
63 | |
64 typedef my_source_mgr * my_src_ptr; | |
65 | |
66 METHODDEF(void) init_source (j_decompress_ptr cinfo) | |
67 { | |
68 } | |
69 | |
70 METHODDEF(boolean) fill_input_buffer (j_decompress_ptr cinfo) | |
71 { | |
25666
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
72 my_src_ptr src = (my_src_ptr) cinfo->src; |
5029 | 73 src->pub.next_input_byte = src->inbuf; |
74 src->pub.bytes_in_buffer = src->bufsize; | |
75 return TRUE; | |
76 } | |
25666
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
77 |
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
78 METHODDEF(void) skip_input_data (j_decompress_ptr cinfo, long num_bytes) |
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
79 { |
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
80 my_src_ptr src = (my_src_ptr) cinfo->src; |
5029 | 81 |
82 if (num_bytes > 0) | |
83 { | |
84 while (num_bytes > (long) src->pub.bytes_in_buffer) | |
85 { | |
86 num_bytes -= (long) src->pub.bytes_in_buffer; | |
87 (void) fill_input_buffer(cinfo); | |
88 } | |
89 src->pub.next_input_byte += (size_t) num_bytes; | |
90 src->pub.bytes_in_buffer -= (size_t) num_bytes; | |
91 } | |
92 } | |
93 | |
25666
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
94 METHODDEF(void) term_source (j_decompress_ptr cinfo) { } |
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
95 |
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
96 GLOBAL(void) jpeg_buf_src ( j_decompress_ptr cinfo, char * inbuf,int bufsize ) |
5029 | 97 { |
98 my_src_ptr src; | |
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; | |
106 src->inbuf = inbuf; | |
107 src->bufsize=bufsize; | |
108 src->pub.bytes_in_buffer = 0; | |
109 src->pub.next_input_byte = NULL; | |
110 } | |
111 | |
112 struct my_error_mgr | |
113 { | |
114 struct jpeg_error_mgr pub; | |
115 jmp_buf setjmp_buffer; | |
116 }; | |
117 | |
118 typedef struct my_error_mgr * my_error_ptr; | |
119 | |
120 METHODDEF(void) my_error_exit (j_common_ptr cinfo) | |
121 { | |
122 my_error_ptr myerr=(my_error_ptr) cinfo->err; | |
123 (*cinfo->err->output_message) (cinfo); | |
124 longjmp(myerr->setjmp_buffer, 1); | |
125 } | |
126 | |
127 // decode a frame | |
128 static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){ | |
25664 | 129 struct jpeg_decompress_struct cinfo; |
130 struct my_error_mgr jerr; | |
5029 | 131 mp_image_t * mpi = NULL; |
6097 | 132 int width,height,depth,i; |
5029 | 133 |
134 if ( len <= 0 ) return NULL; // skipped frame | |
135 | |
25664 | 136 memset(&cinfo, 0, sizeof(cinfo)); |
137 memset(&jerr, 0, sizeof(jerr)); | |
5366 | 138 cinfo.err=jpeg_std_error( &jerr.pub ); |
139 jerr.pub.error_exit=my_error_exit; | |
5029 | 140 if( setjmp( jerr.setjmp_buffer ) ) |
141 { | |
142 mp_msg( MSGT_DECVIDEO,MSGL_ERR,"[ijpg] setjmp error ...\n" ); | |
143 return NULL; | |
144 } | |
25666
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
145 |
5029 | 146 jpeg_create_decompress( &cinfo ); |
147 jpeg_buf_src( &cinfo,data,len ); | |
148 jpeg_read_header( &cinfo,TRUE ); | |
5365
b87743434e1f
Issue a warning in VDec if disp_w and disp_h weren't set by codec and try workaround.
atmos4
parents:
5124
diff
changeset
|
149 sh->disp_w=width=cinfo.image_width; |
b87743434e1f
Issue a warning in VDec if disp_w and disp_h weren't set by codec and try workaround.
atmos4
parents:
5124
diff
changeset
|
150 sh->disp_h=height=cinfo.image_height; |
5029 | 151 jpeg_start_decompress( &cinfo ); |
152 depth=cinfo.output_components * 8; | |
153 | |
154 switch( depth ) { | |
6097 | 155 case 8: |
156 case 24: break; | |
5029 | 157 default: mp_msg( MSGT_DECVIDEO,MSGL_ERR,"Sorry, unsupported JPEG colorspace: %d.\n",depth ); return NULL; |
158 } | |
159 | |
25667
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
160 if ( last_w!=width || last_h!=height || last_depth != depth ) |
5029 | 161 { |
25667
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
162 last_depth = depth; |
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
163 if(!mpcodecs_config_vo( sh,width,height, depth == 8 ? IMGFMT_Y8 : IMGFMT_RGB24 )) return NULL; |
6097 | 164 last_w=width; last_h=height; |
5029 | 165 } |
166 | |
167 mpi=mpcodecs_get_image( sh,MP_IMGTYPE_TEMP,MP_IMGFLAG_ACCEPT_STRIDE,width,height ); | |
168 if ( !mpi ) return NULL; | |
169 | |
170 for ( i=0;i < height;i++ ) | |
171 { | |
6097 | 172 unsigned char * drow = mpi->planes[0] + mpi->stride[0] * i; |
25667
a9fd64f3d166
Colourspace conversions do _not_ belong into a decoder!
reimar
parents:
25666
diff
changeset
|
173 jpeg_read_scanlines( &cinfo,(JSAMPLE**)&drow,1 ); |
5029 | 174 } |
25666
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
175 |
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
176 jpeg_finish_decompress(&cinfo); |
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
177 jpeg_destroy_decompress(&cinfo); |
79fee31fb216
Cosmetics: get rid of huge amounts of trailing whitespace
reimar
parents:
25665
diff
changeset
|
178 |
5029 | 179 return mpi; |
180 } |