00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #define CMAP_RGB2_SIZE 256
00026
00027
00028
00029
00030
00031
00032
00033 struct filter_sys_t
00034 {
00035 uint8_t *p_buffer;
00036 int *p_offset;
00037
00038 #ifdef MODULE_NAME_IS_i420_rgb
00039
00040 void *p_base;
00041 uint8_t *p_rgb8;
00042 uint16_t *p_rgb16;
00043 uint32_t *p_rgb32;
00044
00045
00046
00047
00048
00049 uint16_t p_rgb_r[CMAP_RGB2_SIZE];
00050 uint16_t p_rgb_g[CMAP_RGB2_SIZE];
00051 uint16_t p_rgb_b[CMAP_RGB2_SIZE];
00052 #endif
00053 };
00054
00055
00056
00057
00058 #ifdef MODULE_NAME_IS_i420_rgb
00059 void I420_RGB8 ( filter_t *, picture_t *, picture_t * );
00060 void I420_RGB16_dither ( filter_t *, picture_t *, picture_t * );
00061 void I420_RGB16 ( filter_t *, picture_t *, picture_t * );
00062 void I420_RGB32 ( filter_t *, picture_t *, picture_t * );
00063 static picture_t *I420_RGB8_Filter ( filter_t *, picture_t * );
00064 static picture_t *I420_RGB16_dither_Filter ( filter_t *, picture_t * );
00065 static picture_t *I420_RGB16_Filter ( filter_t *, picture_t * );
00066 static picture_t *I420_RGB32_Filter ( filter_t *, picture_t * );
00067 #else // if defined(MODULE_NAME_IS_i420_rgb_mmx)
00068 void I420_R5G5B5 ( filter_t *, picture_t *, picture_t * );
00069 void I420_R5G6B5 ( filter_t *, picture_t *, picture_t * );
00070 void I420_A8R8G8B8 ( filter_t *, picture_t *, picture_t * );
00071 void I420_R8G8B8A8 ( filter_t *, picture_t *, picture_t * );
00072 void I420_B8G8R8A8 ( filter_t *, picture_t *, picture_t * );
00073 void I420_A8B8G8R8 ( filter_t *, picture_t *, picture_t * );
00074 static picture_t *I420_R5G5B5_Filter ( filter_t *, picture_t * );
00075 static picture_t *I420_R5G6B5_Filter ( filter_t *, picture_t * );
00076 static picture_t *I420_A8R8G8B8_Filter ( filter_t *, picture_t * );
00077 static picture_t *I420_R8G8B8A8_Filter ( filter_t *, picture_t * );
00078 static picture_t *I420_B8G8R8A8_Filter ( filter_t *, picture_t * );
00079 static picture_t *I420_A8B8G8R8_Filter ( filter_t *, picture_t * );
00080 #endif
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 #define CONVERT_Y_PIXEL( BPP ) \
00091 \
00092 p_ybase = p_yuv + *p_y++; \
00093 *p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128)>>SHIFT) + i_red] | \
00094 p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) \
00095 + i_green ] | p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128)>>SHIFT) + i_blue];
00096
00097 #define CONVERT_YUV_PIXEL( BPP ) \
00098 \
00099 i_uval = *p_u++; \
00100 i_vval = *p_v++; \
00101 i_red = (V_RED_COEF * i_vval) >> SHIFT; \
00102 i_green = (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT; \
00103 i_blue = (U_BLUE_COEF * i_uval) >> SHIFT; \
00104 CONVERT_Y_PIXEL( BPP ) \
00105
00106 #define CONVERT_Y_PIXEL_DITHER( BPP ) \
00107 \
00108 p_ybase = p_yuv + *p_y++; \
00109 *p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128+p_dither[i_real_y])>>SHIFT) + i_red] | \
00110 p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128+p_dither[i_real_y])>>SHIFT) \
00111 + i_green ] | p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128+p_dither[i_real_y])>>SHIFT) + i_blue];
00112
00113 #define CONVERT_YUV_PIXEL_DITHER( BPP ) \
00114 \
00115 i_uval = *p_u++; \
00116 i_vval = *p_v++; \
00117 i_red = (V_RED_COEF * i_vval) >> SHIFT; \
00118 i_green = (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT; \
00119 i_blue = (U_BLUE_COEF * i_uval) >> SHIFT; \
00120 CONVERT_Y_PIXEL_DITHER( BPP ) \
00121
00122 #define CONVERT_4YUV_PIXEL( CHROMA ) \
00123 *p_pic++ = p_lookup[ \
00124 (((*p_y++ + dither10[i_real_y]) >> 4) << 7) \
00125 + ((*p_u + dither20[i_real_y]) >> 5) * 9 \
00126 + ((*p_v + dither20[i_real_y]) >> 5) ]; \
00127 *p_pic++ = p_lookup[ \
00128 (((*p_y++ + dither11[i_real_y]) >> 4) << 7) \
00129 + ((*p_u++ + dither21[i_real_y]) >> 5) * 9 \
00130 + ((*p_v++ + dither21[i_real_y]) >> 5) ]; \
00131 *p_pic++ = p_lookup[ \
00132 (((*p_y++ + dither12[i_real_y]) >> 4) << 7) \
00133 + ((*p_u + dither22[i_real_y]) >> 5) * 9 \
00134 + ((*p_v + dither22[i_real_y]) >> 5) ]; \
00135 *p_pic++ = p_lookup[ \
00136 (((*p_y++ + dither13[i_real_y]) >> 4) << 7) \
00137 + ((*p_u++ + dither23[i_real_y]) >> 5) * 9 \
00138 + ((*p_v++ + dither23[i_real_y]) >> 5) ]; \
00139
00140 #define CONVERT_4YUV_PIXEL_SCALE( CHROMA ) \
00141 *p_pic++ = p_lookup[ \
00142 ( ((*p_y + dither10[i_real_y]) >> 4) << 7) \
00143 + ((*p_u + dither20[i_real_y]) >> 5) * 9 \
00144 + ((*p_v + dither20[i_real_y]) >> 5) ]; \
00145 p_y += *p_offset++; \
00146 p_u += *p_offset; \
00147 p_v += *p_offset++; \
00148 *p_pic++ = p_lookup[ \
00149 ( ((*p_y + dither11[i_real_y]) >> 4) << 7) \
00150 + ((*p_u + dither21[i_real_y]) >> 5) * 9 \
00151 + ((*p_v + dither21[i_real_y]) >> 5) ]; \
00152 p_y += *p_offset++; \
00153 p_u += *p_offset; \
00154 p_v += *p_offset++; \
00155 *p_pic++ = p_lookup[ \
00156 ( ((*p_y + dither12[i_real_y]) >> 4) << 7) \
00157 + ((*p_u + dither22[i_real_y]) >> 5) * 9 \
00158 + ((*p_v + dither22[i_real_y]) >> 5) ]; \
00159 p_y += *p_offset++; \
00160 p_u += *p_offset; \
00161 p_v += *p_offset++; \
00162 *p_pic++ = p_lookup[ \
00163 ( ((*p_y + dither13[i_real_y]) >> 4) << 7) \
00164 + ((*p_u + dither23[i_real_y]) >> 5) * 9 \
00165 + ((*p_v + dither23[i_real_y]) >> 5) ]; \
00166 p_y += *p_offset++; \
00167 p_u += *p_offset; \
00168 p_v += *p_offset++; \
00169
00170
00171
00172
00173
00174
00175
00176 #define SCALE_WIDTH \
00177 if( b_hscale ) \
00178 { \
00179
00180 \
00181 p_buffer = p_buffer_start; \
00182 p_offset = p_offset_start; \
00183 for( i_x = p_filter->fmt_out.video.i_width / 16; i_x--; ) \
00184 { \
00185 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
00186 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
00187 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
00188 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
00189 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
00190 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
00191 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
00192 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
00193 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
00194 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
00195 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
00196 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
00197 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
00198 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
00199 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
00200 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
00201 } \
00202 for( i_x = p_filter->fmt_out.video.i_width & 15; i_x--; ) \
00203 { \
00204 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
00205 } \
00206 p_pic = (void*)((uint8_t*)p_pic + i_right_margin ); \
00207 } \
00208 else \
00209 { \
00210
00211 \
00212 p_pic = (void*)((uint8_t*)p_pic + p_dest->p->i_pitch ); \
00213 } \
00214
00215
00216
00217
00218
00219
00220 #define SCALE_WIDTH_DITHER( CHROMA ) \
00221 if( b_hscale ) \
00222 { \
00223 \
00224 p_offset = p_offset_start; \
00225 for( i_x = p_filter->fmt_out.video.i_width / 16; i_x--; ) \
00226 { \
00227 CONVERT_4YUV_PIXEL_SCALE( CHROMA ) \
00228 CONVERT_4YUV_PIXEL_SCALE( CHROMA ) \
00229 CONVERT_4YUV_PIXEL_SCALE( CHROMA ) \
00230 CONVERT_4YUV_PIXEL_SCALE( CHROMA ) \
00231 } \
00232 } \
00233 else \
00234 { \
00235 for( i_x = p_filter->fmt_in.video.i_width / 16; i_x--; ) \
00236 { \
00237 CONVERT_4YUV_PIXEL( CHROMA ) \
00238 CONVERT_4YUV_PIXEL( CHROMA ) \
00239 CONVERT_4YUV_PIXEL( CHROMA ) \
00240 CONVERT_4YUV_PIXEL( CHROMA ) \
00241 } \
00242 } \
00243 \
00244 p_pic = (void*)((uint8_t*)p_pic + i_right_margin ); \
00245 \
00246 \
00247 i_real_y = (i_real_y + 1) & 0x3; \
00248
00249
00250
00251
00252
00253
00254
00255
00256 #define SCALE_HEIGHT( CHROMA, BPP ) \
00257 \
00258 if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
00259 { \
00260 p_u -= i_chroma_width; \
00261 p_v -= i_chroma_width; \
00262 } \
00263 \
00264
00265
00266
00267 \
00268 switch( i_vscale ) \
00269 { \
00270 case -1: \
00271 while( (i_scale_count -= p_filter->fmt_out.video.i_height) > 0 ) \
00272 { \
00273 \
00274 p_y += p_filter->fmt_in.video.i_width; \
00275 i_y++; \
00276 if( (CHROMA == 420) || (CHROMA == 422) ) \
00277 { \
00278 if( i_y & 0x1 ) \
00279 { \
00280 p_u += i_chroma_width; \
00281 p_v += i_chroma_width; \
00282 } \
00283 } \
00284 else if( CHROMA == 444 ) \
00285 { \
00286 p_u += p_filter->fmt_in.video.i_width; \
00287 p_v += p_filter->fmt_in.video.i_width; \
00288 } \
00289 } \
00290 i_scale_count += p_filter->fmt_in.video.i_height; \
00291 break; \
00292 case 1: \
00293 while( (i_scale_count -= p_filter->fmt_in.video.i_height) > 0 ) \
00294 { \
00295 \
00296 vlc_memcpy( p_pic, p_pic_start, p_filter->fmt_out.video.i_width * BPP ); \
00297 p_pic = (void*)((uint8_t*)p_pic + p_dest->p->i_pitch ); \
00298 } \
00299 i_scale_count += p_filter->fmt_out.video.i_height; \
00300 break; \
00301 } \
00302
00303
00304
00305
00306
00307
00308
00309 #define SCALE_HEIGHT_DITHER( CHROMA ) \
00310 \
00311 \
00312 if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
00313 { \
00314 p_u -= i_chroma_width; \
00315 p_v -= i_chroma_width; \
00316 } \
00317 \
00318
00319
00320
00321 \
00322 \
00323 switch( i_vscale ) \
00324 { \
00325 case -1: \
00326 while( (i_scale_count -= p_filter->fmt_out.video.i_height) > 0 ) \
00327 { \
00328 \
00329 p_y += p_filter->fmt_in.video.i_width; \
00330 i_y++; \
00331 if( (CHROMA == 420) || (CHROMA == 422) ) \
00332 { \
00333 if( i_y & 0x1 ) \
00334 { \
00335 p_u += i_chroma_width; \
00336 p_v += i_chroma_width; \
00337 } \
00338 } \
00339 else if( CHROMA == 444 ) \
00340 { \
00341 p_u += p_filter->fmt_in.video.i_width; \
00342 p_v += p_filter->fmt_in.video.i_width; \
00343 } \
00344 } \
00345 i_scale_count += p_filter->fmt_in.video.i_height; \
00346 break; \
00347 case 1: \
00348 while( (i_scale_count -= p_filter->fmt_in.video.i_height) > 0 ) \
00349 { \
00350 p_y -= p_filter->fmt_in.video.i_width; \
00351 p_u -= i_chroma_width; \
00352 p_v -= i_chroma_width; \
00353 SCALE_WIDTH_DITHER( CHROMA ); \
00354 } \
00355 i_scale_count += p_filter->fmt_out.video.i_height; \
00356 break; \
00357 } \
00358