[vlc-commits] mux: add BIH creation in helper
Francois Cartegnie
git at videolan.org
Tue Aug 14 15:56:12 CEST 2018
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Aug 14 00:35:41 2018 +0200| [7794977d68953eb62c6ddb1edcbed9043f866ebe] | committer: Francois Cartegnie
mux: add BIH creation in helper
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=7794977d68953eb62c6ddb1edcbed9043f866ebe
---
modules/demux/avi/bitmapinfoheader.h | 168 +++++++++++++++++++++++++++++------
1 file changed, 141 insertions(+), 27 deletions(-)
diff --git a/modules/demux/avi/bitmapinfoheader.h b/modules/demux/avi/bitmapinfoheader.h
index 2c43fac043..f797c2e495 100644
--- a/modules/demux/avi/bitmapinfoheader.h
+++ b/modules/demux/avi/bitmapinfoheader.h
@@ -30,42 +30,60 @@
#define BI_RLE8 0x0001
#define BI_RLE4 0x0002
#define BI_BITFIELDS 0x0003
-#define BI_JPEG 0x0004
-#define BI_PNG 0x0005
#define BI_CMYK 0x000B
#define BI_CMYKRLE8 0x000C
#define BI_CMYKRLE4 0x000D
+static const struct
+{
+ vlc_fourcc_t codec;
+ uint32_t i_rmask, i_gmask, i_bmask;
+} bitmap_rgb_masks[] = {
+ { VLC_CODEC_RGB15, 0x7c00,
+ 0x03e0,
+ 0x001f, },
+ { VLC_CODEC_RGB16, 0xf800,
+ 0x07e0,
+ 0x001f, },
+ { VLC_CODEC_RGB24, 0x000000ff, /* BGR (see biBitCount) */
+ 0x0000ff00,
+ 0x00ff0000, },
+ { VLC_CODEC_RGB32, 0x0000ff00, /* This is in BGR0 format */
+ 0x00ff0000,
+ 0xff000000U, },
+ { VLC_CODEC_RGBA, 0x0000ff00, /* This is in BGRA format */
+ 0x00ff0000,
+ 0xff000000U, },
+};
+
static inline void SetBitmapRGBMasks( vlc_fourcc_t i_fourcc, es_format_t *fmt )
{
- switch( i_fourcc )
+ for( size_t i=0; i<ARRAY_SIZE(bitmap_rgb_masks); i++ )
{
- case VLC_CODEC_RGB15:
- fmt->video.i_rmask = 0x7c00;
- fmt->video.i_gmask = 0x03e0;
- fmt->video.i_bmask = 0x001f;
- break;
- case VLC_CODEC_RGB16:
- fmt->video.i_rmask = 0xf800;
- fmt->video.i_gmask = 0x07e0;
- fmt->video.i_bmask = 0x001f;
- break;
- case VLC_CODEC_RGB24: /* BGR (see biBitCount) */
- fmt->video.i_bmask = 0x00ff0000;
- fmt->video.i_gmask = 0x0000ff00;
- fmt->video.i_rmask = 0x000000ff;
- break;
- case VLC_CODEC_RGB32: /* This is in BGRx format */
- case VLC_CODEC_RGBA:
- fmt->video.i_bmask = 0xff000000;
- fmt->video.i_gmask = 0x00ff0000;
- fmt->video.i_rmask = 0x0000ff00;
+ if( bitmap_rgb_masks[i].codec == i_fourcc )
+ {
+ fmt->video.i_rmask = bitmap_rgb_masks[i].i_rmask;
+ fmt->video.i_gmask = bitmap_rgb_masks[i].i_gmask;
+ fmt->video.i_bmask = bitmap_rgb_masks[i].i_bmask;
+ fmt->video.i_chroma = i_fourcc;
+ video_format_FixRgb( &fmt->video );
break;
- default:
- return;
+ }
}
- fmt->video.i_chroma = i_fourcc;
- video_format_FixRgb( &fmt->video );
+}
+
+static inline bool MatchBitmapRGBMasks( const es_format_t *fmt )
+{
+ for( size_t i=0; i<ARRAY_SIZE(bitmap_rgb_masks); i++ )
+ {
+ if( bitmap_rgb_masks[i].codec == fmt->i_codec )
+ {
+ return fmt->video.i_rmask == bitmap_rgb_masks[i].i_rmask &&
+ fmt->video.i_gmask == bitmap_rgb_masks[i].i_gmask &&
+ fmt->video.i_bmask == bitmap_rgb_masks[i].i_bmask;
+ }
+ }
+ return false;
}
struct bitmapinfoheader_properties
@@ -189,3 +207,99 @@ static inline int ParseBitmapInfoHeader( VLC_BITMAPINFOHEADER *p_bih, size_t i_b
return VLC_SUCCESS;
}
+
+static inline VLC_BITMAPINFOHEADER * CreateBitmapInfoHeader( const es_format_t *fmt,
+ size_t *pi_total )
+{
+ uint16_t biBitCount = 0;
+ uint32_t biCompression = 0;
+ bool b_has_alpha = false;
+ switch( fmt->i_codec )
+ {
+ case VLC_CODEC_RGB32:
+ biBitCount = 32;
+ biCompression = MatchBitmapRGBMasks( fmt ) ? BI_RGB : BI_BITFIELDS;
+ break;
+ case VLC_CODEC_BGRA:
+ case VLC_CODEC_RGBA:
+ case VLC_CODEC_ARGB:
+ biBitCount = 32;
+ biCompression = MatchBitmapRGBMasks( fmt ) ? BI_RGB : BI_BITFIELDS;
+ b_has_alpha = true;
+ break;
+ case VLC_CODEC_RGB24:
+ biBitCount = 24;
+ biCompression = BI_RGB;
+ break;
+ case VLC_CODEC_RGB16:
+ case VLC_CODEC_RGB15:
+ biBitCount = 16;
+ biCompression = BI_BITFIELDS;
+ break;
+ case VLC_CODEC_RGBP:
+ case VLC_CODEC_GREY:
+ biBitCount = 8;
+ biCompression = BI_RGB;
+ break;
+ case VLC_CODEC_MP4V:
+ biCompression = VLC_FOURCC( 'X', 'V', 'I', 'D' );
+ break;
+ default:
+ biCompression = fmt->i_original_fourcc ?: fmt->i_codec;
+ break;
+ }
+
+ size_t i_bih_extra = 0;
+ size_t i_bmiColors = 0;
+ if( biCompression == BI_BITFIELDS )
+ i_bmiColors = (b_has_alpha) ? 16 : 12;
+ else if ( fmt->i_codec == VLC_CODEC_RGBP )
+ i_bmiColors = fmt->video.p_palette ? (fmt->video.p_palette->i_entries * 4) : 0;
+ else
+ i_bih_extra = fmt->i_extra;
+
+ VLC_BITMAPINFOHEADER *p_bih = malloc( sizeof(VLC_BITMAPINFOHEADER) +
+ i_bih_extra + i_bmiColors );
+ if( p_bih == NULL )
+ return NULL;
+
+ uint8_t *p_bih_extra = (uint8_t *) &p_bih[1];
+ uint8_t *p_bmiColors = p_bih_extra + i_bih_extra;
+ p_bih->biClrUsed = 0;
+ if( biCompression == BI_BITFIELDS )
+ {
+ SetDWBE( &p_bmiColors[0], fmt->video.i_rmask );
+ SetDWBE( &p_bmiColors[4], fmt->video.i_gmask );
+ SetDWBE( &p_bmiColors[8], fmt->video.i_bmask );
+ if( b_has_alpha )
+ {
+ SetDWBE( &p_bmiColors[12], ~(fmt->video.i_rmask |
+ fmt->video.i_gmask |
+ fmt->video.i_bmask) );
+ }
+ }
+ else if( fmt->i_codec == VLC_CODEC_RGBP )
+ {
+ for( int i = 0; i < fmt->video.p_palette->i_entries; i++ )
+ memcpy( &p_bmiColors[i * 4], fmt->video.p_palette->palette[i], 4 );
+ p_bih->biClrUsed = fmt->video.p_palette->i_entries;
+ }
+ else if( fmt->i_extra )
+ {
+ memcpy( p_bih_extra, fmt->p_extra, fmt->i_extra );
+ }
+
+ p_bih->biSize = sizeof(VLC_BITMAPINFOHEADER) + i_bih_extra;
+ p_bih->biCompression = biCompression;
+ p_bih->biBitCount = biBitCount;
+ p_bih->biWidth = fmt->video.i_visible_width;
+ p_bih->biHeight = fmt->video.i_visible_height;
+ p_bih->biPlanes = 1;
+ p_bih->biSizeImage = 0;
+ p_bih->biXPelsPerMeter = 0;
+ p_bih->biYPelsPerMeter = 0;
+ p_bih->biClrImportant = 0;
+
+ *pi_total = sizeof(VLC_BITMAPINFOHEADER) + i_bih_extra + i_bmiColors;
+ return p_bih;
+}
More information about the vlc-commits
mailing list