Commit 2cb7e016 authored by Gildas Bazin's avatar Gildas Bazin

* modules/codec/cvdsub.c: ported cvd subtitles decoder to the new subpicture architecture.

* modules/codec/svcdsub.c: ported svcd subtitles decoder to the new subpicture architecture.
parent 805a60e6
...@@ -2464,8 +2464,6 @@ AC_CHECK_HEADERS(png.h, [ ...@@ -2464,8 +2464,6 @@ AC_CHECK_HEADERS(png.h, [
AC_CHECK_LIB(png, png_set_rows, [ AC_CHECK_LIB(png, png_set_rows, [
VLC_ADD_LDFLAGS([png],[-lpng -lz]) VLC_ADD_LDFLAGS([png],[-lpng -lz])
VLC_ADD_PLUGINS([png]) VLC_ADD_PLUGINS([png])
VLC_ADD_LDFLAGS([svcdsub],[-lpng -lz])
VLC_ADD_LDFLAGS([cvdsub],[-lpng -lz -lm])
AC_DEFINE(HAVE_LIBPNG, [], [Define if you have the PNG library: libpng])], AC_DEFINE(HAVE_LIBPNG, [], [Define if you have the PNG library: libpng])],
[],[-lz]) [],[-lz])
LDFLAGS="${LDFLAGS_save}" LDFLAGS="${LDFLAGS_save}"
...@@ -4169,7 +4167,6 @@ AC_CONFIG_FILES([ ...@@ -4169,7 +4167,6 @@ AC_CONFIG_FILES([
modules/codec/cmml/Makefile modules/codec/cmml/Makefile
modules/codec/dmo/Makefile modules/codec/dmo/Makefile
modules/codec/ffmpeg/Makefile modules/codec/ffmpeg/Makefile
modules/codec/ogt/Makefile
modules/codec/spudec/Makefile modules/codec/spudec/Makefile
modules/control/Makefile modules/control/Makefile
modules/control/corba/Makefile modules/control/corba/Makefile
......
...@@ -23,3 +23,5 @@ SOURCES_x264 = x264.c ...@@ -23,3 +23,5 @@ SOURCES_x264 = x264.c
SOURCES_toolame = toolame.c SOURCES_toolame = toolame.c
SOURCES_dirac = dirac.c SOURCES_dirac = dirac.c
SOURCES_png = png.c SOURCES_png = png.c
SOURCES_svcdsub = svcdsub.c
SOURCES_cvdsub = cvdsub.c
This diff is collapsed.
SOURCES_svcdsub = \
common.c \
common.h \
subtitle.h \
ogt.c \
ogt.h \
ogt_parse.c \
pixmap.c \
pixmap.h \
render.c \
render.h \
write_png.c \
write_png.h \
$(NULL)
SOURCES_cvdsub = \
common.c \
common.h \
cvd.c \
cvd.h \
subtitle.h \
cvd_parse.c \
pixmap.c \
pixmap.h \
render.c \
render.h \
write_png.c \
write_png.h \
$(NULL)
This diff is collapsed.
/*****************************************************************************
* Header for Common SVCD and VCD subtitle routines.
*****************************************************************************
* Copyright (C) 2003, 2004 VideoLAN
* $Id: common.h,v 1.6 2004/01/16 13:32:37 rocky Exp $
*
* Author: Rocky Bernstein
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
void VCDSubClose ( vlc_object_t * );
void VCDSubInitSubtitleBlock( decoder_sys_t * p_sys );
void VCDSubInitSubtitleData(decoder_sys_t *p_sys);
void VCDSubAppendData( decoder_t *p_dec, uint8_t *buffer,
uint32_t buf_len );
vout_thread_t *VCDSubFindVout( decoder_t *p_dec );
void VCDSubHandleScaling( subpicture_t *p_spu, decoder_t *p_dec ) ;
void VCDSubScaleX( decoder_t *p_dec, subpicture_t *p_spu,
unsigned int i_scale_x, unsigned int i_scale_y );
void VCDSubDestroySPU( subpicture_t *p_spu );
int VCDSubCropCallback( vlc_object_t *p_object, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval,
void *p_data );
void VCDSubUpdateSPU( subpicture_t *p_spu, vlc_object_t *p_object );
void VCDSubDumpImage( uint8_t *p_image, uint32_t i_height,
uint32_t i_width );
unsigned int VCDSubGetAROverride(vlc_object_t * p_input,
vout_thread_t *p_vout);
#ifdef HAVE_LIBPNG
#include <png.h>
void VCDSubDumpPNG( uint8_t *p_image, decoder_t *p_dec,
uint32_t i_height, uint32_t i_width,
const char *filename, /*in*/ png_text *text_ptr,
int i_text_count );
#endif /*HAVE_LIBPNG*/
/*****************************************************************************
* cvd.c : CVD Subtitle decoder thread
*****************************************************************************
* Copyright (C) 2003, 2004 VideoLAN
* $Id$
*
* Authors: Rocky Bernstein
* based on code from:
* Julio Sanchez Fernandez (http://subhandler.sourceforge.net)
* Samuel Hocevar <sam@zoy.org>
* Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <vlc/decoder.h>
#include "subtitle.h"
#include "cvd.h"
#include "common.h"
/*****************************************************************************
* Module descriptor.
*****************************************************************************/
static int VCDSubOpen ( vlc_object_t * );
static int PacketizerOpen( vlc_object_t * );
vlc_module_begin();
set_description( _("CVD subtitle decoder") );
set_capability( "decoder", 50 );
set_callbacks( VCDSubOpen, VCDSubClose );
set_category( CAT_INPUT );
set_subcategory( SUBCAT_INPUT_SCODEC );
add_integer ( MODULE_STRING "-debug", 0, NULL,
DEBUG_TEXT, DEBUG_LONGTEXT, VLC_TRUE );
add_integer ( MODULE_STRING "-horizontal-correct", 0, NULL,
HORIZONTAL_CORRECT, HORIZONTAL_CORRECT_LONGTEXT, VLC_FALSE );
add_integer ( MODULE_STRING "-vertical-correct", 0, NULL,
VERTICAL_CORRECT, VERTICAL_CORRECT_LONGTEXT, VLC_FALSE );
add_string( MODULE_STRING "-aspect-ratio", "", NULL,
SUB_ASPECT_RATIO_TEXT, SUB_ASPECT_RATIO_LONGTEXT,
VLC_TRUE );
add_integer( MODULE_STRING "-duration-scaling", 3, NULL,
DURATION_SCALE_TEXT, DURATION_SCALE_LONGTEXT,
VLC_TRUE );
add_submodule();
set_description( _("Chaoji VCD subtitle packetizer") );
set_capability( "packetizer", 50 );
set_callbacks( PacketizerOpen, VCDSubClose );
vlc_module_end();
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static block_t *Reassemble( decoder_t *, block_t ** );
static subpicture_t *Decode( decoder_t *, block_t ** );
static block_t *Packetize( decoder_t *, block_t ** );
/*****************************************************************************
* VCDSubOpen
*****************************************************************************
* Tries to launch a decoder and return score so that the interface is able
* to chose.
*****************************************************************************/
static int
VCDSubOpen( vlc_object_t *p_this )
{
decoder_t *p_dec = (decoder_t*)p_this;
decoder_sys_t *p_sys;
if( p_dec->fmt_in.i_codec != VLC_FOURCC( 'c','v','d',' ' ) )
{
return VLC_EGENERIC;
}
p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) );
p_sys->i_debug = config_GetInt( p_this, MODULE_STRING "-debug" );
p_sys->b_packetizer = VLC_FALSE;
p_sys->p_vout = NULL;
p_sys->i_image = -1;
p_sys->subtitle_data = NULL;
VCDSubInitSubtitleBlock( p_sys );
es_format_Init( &p_dec->fmt_out, SPU_ES, VLC_FOURCC( 'c','v','d',' ' ) );
p_dec->pf_decode_sub = Decode;
p_dec->pf_packetize = Packetize;
dbg_print( (DECODE_DBG_CALL|DECODE_DBG_EXT) , "");
return VLC_SUCCESS;
}
/*****************************************************************************
* PacketizerOpen
*****************************************************************************
* Tries to launch a decoder and return score so that the interface is able
* to chose.
*****************************************************************************/
static int PacketizerOpen( vlc_object_t *p_this )
{
decoder_t *p_dec = (decoder_t*)p_this;
if( VCDSubOpen( p_this ) )
{
return VLC_EGENERIC;
}
p_dec->p_sys->b_packetizer = VLC_TRUE;
return VLC_SUCCESS;
}
/*****************************************************************************
* Decode:
*****************************************************************************/
static subpicture_t *
Decode ( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_spu = Reassemble( p_dec, pp_block );
vout_thread_t *p_last_vout = p_dec->p_sys->p_vout;
dbg_print( (DECODE_DBG_CALL) , "");
if( p_spu )
{
p_sys->i_spu = block_ChainExtract( p_spu, p_sys->buffer, 65536 );
p_sys->i_pts = p_spu->i_pts;
block_ChainRelease( p_spu );
if( ( p_sys->p_vout = VCDSubFindVout( p_dec ) ) )
{
if( p_last_vout != p_sys->p_vout )
{
spu_Control( p_sys->p_vout->p_spu, SPU_CHANNEL_REGISTER,
&p_sys->i_subpic_channel );
}
/* Parse and decode */
E_(ParsePacket)( p_dec );
vlc_object_release( p_sys->p_vout );
}
VCDSubInitSubtitleBlock ( p_sys );
}
return NULL;
}
/*****************************************************************************
* Packetize:
*****************************************************************************/
static block_t *
Packetize( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_spu = Reassemble( p_dec, pp_block );
if( p_spu )
{
p_spu->i_dts = p_spu->i_pts;
p_spu->i_length = 0;
VCDSubInitSubtitleBlock( p_sys );
return block_ChainGather( p_spu );
}
return NULL;
}
/* following functions are local */
#define SPU_HEADER_LEN 1
/*****************************************************************************
Reassemble:
Data for single screen subtitle may come in several non-contiguous
packets of a stream. This routine is called when the next packet in
the stream comes in. The job of this routine is to parse the header,
if this is the beginning, and combine the packets into one complete
subtitle unit.
If everything is complete, we will return a block. Otherwise return
NULL.
*****************************************************************************/
static block_t *
Reassemble( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_block;
uint8_t *p_buffer;
if( pp_block == NULL || *pp_block == NULL )
{
return NULL;
}
p_block = *pp_block;
*pp_block = NULL;
if( p_block->i_buffer < SPU_HEADER_LEN )
{
msg_Dbg( p_dec, "invalid packet header (size %d < %d)" ,
p_block->i_buffer, SPU_HEADER_LEN );
block_Release( p_block );
return NULL;
}
p_buffer = p_block->p_buffer;
dbg_print( (DECODE_DBG_CALL|DECODE_DBG_PACKET),
"header: 0x%02x 0x%02x 0x%02x 0x%02x, 0x%02x, 0x%02x, size: %i",
p_buffer[1], p_buffer[2], p_buffer[3], p_buffer[4],
p_buffer[5], p_buffer[6],
p_block->i_buffer);
/* Attach to our input thread and see if subtitle is selected. */
{
vlc_object_t * p_input;
vlc_value_t val;
p_input = vlc_object_find( p_dec, VLC_OBJECT_INPUT, FIND_PARENT );
if( !p_input ) return NULL;
if( var_Get( p_input, "spu-channel", &val ) )
{
vlc_object_release( p_input );
return NULL;
}
vlc_object_release( p_input );
/* Number could be 0bd, 1bd, 2bd, 3bd for 0..3. If so
reduce it to 0..3.
*/
if ( (val.i_int & 0xff) == 0xbd ) val.i_int >>= 8;
if( val.i_int == -1 || val.i_int != p_buffer[0] )
return NULL;
}
/* From the scant data on the format, there is only only way known
to detect the first packet in a subtitle. The first packet
seems to have a valid PTS while later packets for the same
image don't. */
if ( p_sys->state == SUBTITLE_BLOCK_EMPTY && p_block->i_pts == 0 ) {
msg_Warn( p_dec,
"first packet expected but no PTS present -- skipped\n");
return NULL;
}
if ( p_sys->subtitle_data_pos == 0 ) {
/* First packet in the subtitle block */
E_(ParseHeader)( p_dec, p_buffer, p_block );
VCDSubInitSubtitleData(p_sys);
}
/* FIXME - remove append_data and use chainappend */
VCDSubAppendData( p_dec, p_buffer + SPU_HEADER_LEN,
p_block->i_buffer - SPU_HEADER_LEN );
block_ChainAppend( &p_sys->p_block, p_block );
p_sys->i_spu += p_block->i_buffer - SPU_HEADER_LEN;
if ( p_sys->subtitle_data_pos == p_sys->i_spu_size ) {
E_(ParseMetaInfo)( p_dec );
return p_sys->p_block;
} else {
/* Not last block in subtitle, so wait for another. */
p_sys->state = SUBTITLE_BLOCK_PARTIAL;
}
return NULL;
}
/*****************************************************************************
* cvd.h : CVD subtitles decoder thread interface
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: cvd.h,v 1.2 2004/01/04 04:56:21 rocky Exp $
*
* Author: Rocky Bernstein
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Prototypes
*****************************************************************************/
void E_(ParseHeader)( decoder_t *, uint8_t *, block_t * );
void E_(ParsePacket)( decoder_t * );
void E_(ParseMetaInfo)( decoder_t *p_dec );
This diff is collapsed.
This diff is collapsed.
/*****************************************************************************
* ogt.h : Overlay Graphics Text (SVCD subtitles) decoder thread interface
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: ogt.h,v 1.6 2003/12/28 02:01:11 rocky Exp $
*
* Author: Rocky Bernstein
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Prototypes
*****************************************************************************/
void E_(ParseHeader)( decoder_t *, uint8_t *, block_t * );
void E_(ParsePacket)( decoder_t * );
This diff is collapsed.
/*****************************************************************************
* Common pixel/chroma manipulation routines.
*****************************************************************************
* Copyright (C) 2003, 2004 VideoLAN
* $Id: pixmap.c,v 1.3 2004/01/31 05:53:35 rocky Exp $
*
* Author: Rocky Bernstein
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include "pixmap.h"
/* FIXME: This is copied from modules/video_chroma/i420_rgb.h.
Include from a more common location.
*/
/*****************************************************************************
* chroma_sys_t: chroma method descriptor
*****************************************************************************
* This structure is part of the chroma transformation descriptor, it
* describes the yuv2rgb specific properties.
*****************************************************************************/
struct chroma_sys_t
{
uint8_t *p_buffer;
int *p_offset;
/* Pre-calculated conversion tables */
void *p_base; /* base for all conversion tables */
uint8_t *p_rgb8; /* RGB 8 bits table */
uint16_t *p_rgb16; /* RGB 16 bits table */
uint32_t *p_rgb32; /* RGB 32 bits table */
/* To get RGB value for palette entry i, use (p_rgb_r[i], p_rgb_g[i],
p_rgb_b[i])
*/
uint16_t p_rgb_r[CMAP_RGB2_SIZE]; /* Red values of palette */
uint16_t p_rgb_g[CMAP_RGB2_SIZE]; /* Green values of palette */
uint16_t p_rgb_b[CMAP_RGB2_SIZE]; /* Blue values of palette */
};
/*
From
http://www.inforamp.net/~poynton/notes/colour_and_gamma/ColorFAQ.html#RTFToC11
http://people.ee.ethz.ch/~buc/brechbuehler/mirror/color/ColorFAQ.html#RTFToC1
11. What is "luma"?
It is useful in a video system to convey a component representative of
luminance and two other components representative of colour. It is
important to convey the component representative of luminance in such
a way that noise (or quantization) introduced in transmission,
processing and storage has a perceptually similar effect across the
entire tone scale from black to white. The ideal way to accomplish
these goals would be to form a luminance signal by matrixing RGB, then
subjecting luminance to a nonlinear transfer function similar to the
L* function.
There are practical reasons in video to perform these operations
in the opposite order. First a nonlinear transfer function - gamma
correction - is applied to each of the linear R, G and B. Then a
weighted sum of the nonlinear components is computed to form a
signal representative of luminance. The resulting component is
related to brightness but is not CIE luminance. Many video
engineers call it luma and give it the symbol Y'. It is often
carelessly called luminance and given the symbol Y. You must be
careful to determine whether a particular author assigns a linear
or nonlinear interpretation to the term luminance and the symbol
Y.
The coefficients that correspond to the "NTSC" red, green and blue
CRT phosphors of 1953 are standardized in ITU-R Recommendation BT.
601-2 (formerly CCIR Rec. 601-2). I call it Rec. 601. To compute
nonlinear video luma from nonlinear red, green and blue:
Y'601 = 0.299R' 0.587G' + 0.114B'
We will use the integer scaled versions of these numbers below
as RED_COEF, GREEN_COEF and BLUE_COEF.
*/
/* 19 = round(0.299 * 64) */
#define RED_COEF ((int32_t) 19)
/* 38 = round(0.587 * 64) */
#define GREEN_COEF ((int32_t) 37)
/* 7 = round(0.114 * 64) */
#define BLUE_COEF ((int32_t) 7)
/**
Find the nearest colormap entry in p_vout (assumed to have RGB2
chroma, i.e. 256 RGB 8bpp entries) that is closest in color to p_rgb. Set
out_rgb to the color found and return the colormap index.
INVALID_CMAP_ENTRY is returned if there is some error.
The closest match is determined by the the Euclidean distance
using integer-scaled 601-2 coefficients described above.
Actually, we use the square of the Euclidean distance; but in
comparisons it amounts to the same thing.
*/
cmap_t
find_cmap_rgb8_nearest(const vout_thread_t *p_vout, const uint8_t *rgb,
uint8_t *out_rgb)
{
uint16_t *p_cmap_r;
uint16_t *p_cmap_g;
uint16_t *p_cmap_b;
int i;
cmap_t i_bestmatch = INVALID_CMAP_ENTRY;
uint32_t i_mindist = 0xFFFFFFFF; /* The largest number here. */
/* Check that we really have RGB2. */
if ( !p_vout && p_vout->output.i_chroma != VLC_FOURCC('R','G','B','2') )
return INVALID_CMAP_ENTRY;
p_cmap_r=p_vout->chroma.p_sys->p_rgb_r;
p_cmap_g=p_vout->chroma.p_sys->p_rgb_g;
p_cmap_b=p_vout->chroma.p_sys->p_rgb_b;
for (i = 0; i < CMAP_RGB2_SIZE; i++) {
/* Interval range calculations to show that we don't overflow the
word sizes below. pixels component values start out 8
bits. When we subtract two components we get 9 bits, then
square to 10 bits. Next we scale by 6 to give 16
bits. XXX_COEF all fit into 5 bits, so when we multiply we
should have 21 bits maximum. So computations can be done using
32-bit precision. However before storing back distance
components we scale back down by 12 bits making the precision 9
bits. (This checks out since it is basically the range of the
square of the initial 8-bit value.)
The squared distance is the sum of three of the 9-bit components
described above. This then uses 27-bits and also fits in a
32-bit word.
*/
/* We use in integer fixed-point fractions rather than floating
point for speed. We multiply by 64 (= 1 << 6) before computing
the product, and divide the result by 64*64 (= 1 >> (6*2)).
*/
#define SCALEBITS 6
#define int32_sqr(x) ( ((int32_t) (x)) * ((int32_t) x) )
/* colormap entires are scaled to 16 bits, so we need to shift
them back down to 8. */
#define CMAP8_RED(i) (p_cmap_r[i]>>8)
#define CMAP8_GREEN(i) (p_cmap_g[i]>>8)
#define CMAP8_BLUE(i) (p_cmap_b[i]>>8)
uint32_t dr = ( RED_COEF * ( int32_sqr(rgb[RED_PIXEL] - CMAP8_RED(i))
<< SCALEBITS ) ) >> (SCALEBITS*2);
uint32_t dg = ( GREEN_COEF * ( int32_sqr(rgb[GREEN_PIXEL] - CMAP8_GREEN(i))
<< SCALEBITS ) ) >> (SCALEBITS*2);
uint32_t db = ( BLUE_COEF * ( int32_sqr(rgb[BLUE_PIXEL] - CMAP8_BLUE(i))
<< SCALEBITS ) ) >> (SCALEBITS*2);
uint32_t i_dist = dr + dg + db;
if (i_dist < i_mindist) {
i_bestmatch = i;
i_mindist = i_dist;
#if 0
printf("+++Change dist to %d RGB cmap %d (%0x, %0x, %0x)\n",
i_dist, i, p_cmap_r[ i ], p_cmap_g[ i ], p_cmap_b[ i ]);
#endif
}
}
if (out_rgb)
{
out_rgb[RED_PIXEL] = CMAP8_RED(i_bestmatch);
out_rgb[GREEN_PIXEL] = CMAP8_GREEN(i_bestmatch);
out_rgb[BLUE_PIXEL] = CMAP8_BLUE(i_bestmatch);
}
return i_bestmatch;
}
/**
Get the the rgb value for a given colormap entry for p_vout (which is'
assumed to have RGB2 chroma).
VLC_FALSE is returned if there was some error.
*/
vlc_bool_t
query_color(const vout_thread_t *p_vout, cmap_t i_cmap,
/*out*/ uint8_t *out_rgb)
{
uint16_t *p_cmap_r;
uint16_t *p_cmap_g;
uint16_t *p_cmap_b;
/* Check that we really have RGB2. */
if ( !p_vout && p_vout->output.i_chroma != VLC_FOURCC('R','G','B','2') )
return VLC_FALSE;
if ( !out_rgb )
return VLC_FALSE;
p_cmap_r=p_vout->chroma.p_sys->p_rgb_r;
p_cmap_g=p_vout->chroma.p_sys->p_rgb_g;
p_cmap_b=p_vout->chroma.p_sys->p_rgb_b;
out_rgb[RED_PIXEL] = CMAP8_RED(i_cmap);
out_rgb[GREEN_PIXEL] = CMAP8_GREEN(i_cmap);
out_rgb[BLUE_PIXEL] = CMAP8_BLUE(i_cmap);
return VLC_TRUE;
}
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/
/*****************************************************************************
* Common pixel/chroma manipulation routines.
*****************************************************************************
* Copyright (C) 2003, 2004 VideoLAN
* $Id: pixmap.h,v 1.6 2004/01/31 23:33:02 rocky Exp $
*
* Author: Rocky Bernstein
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#ifndef PIXMAP_H
#define PIXMAP_H
/** Color and transparency of a pixel or a palette (CLUT) entry
*/
typedef union {
uint8_t plane[4];
struct {
uint8_t y;
uint8_t v;
uint8_t u;
uint8_t t;
} s;
} ogt_yuvt_t;
/** An undefined or invalid colormap index. */
#define INVALID_CMAP_ENTRY -1
/** Type of a palette/colormap index*/
typedef int16_t cmap_t;
/** Number of entries in RGB palette/colormap*/
#define CMAP_RGB2_SIZE 256
/**
Force v in the range 0..255. In video_chroma/i420_rgb.c, this
is macro is called CLIP. FIXME: Combine with that.
*/
#define clip_8_bit(v) \
((v < 0) ? 0 : (v > 255) ? 255 : v)
/**
Color conversion from
http://www.inforamp.net/~poynton/notes/colour_and_gamma/ColorFAQ.html#RTFToC30
http://people.ee.ethz.ch/~buc/brechbuehler/mirror/color/ColorFAQ.html
Thanks to Billy Biggs <vektor@dumbterm.net> for the pointer and
the following conversion.
R' = [ 1.1644 0 1.5960 ] ([ Y' ] [ 16 ])
G' = [ 1.1644 -0.3918 -0.8130 ] * ([ Cb ] - [ 128 ])
B' = [ 1.1644 2.0172 0 ] ([ Cr ] [ 128 ])
See also vlc/modules/video_chroma/i420_rgb.h and
vlc/modules/video_chroma/i420_rgb_c.h for a way to do this in a way
more optimized for integer arithmetic. Would be nice to merge the
two routines.
*/
/**
Convert a YUV pixel into an RGB pixel.
*/
static inline void
yuv2rgb(const ogt_yuvt_t *p_yuv, uint8_t *p_rgb_out )
{
int i_Y = p_yuv->s.y - 16;
int i_Cb = p_yuv->s.v - 128;
int i_Cr = p_yuv->s.u - 128;
int i_red = (1.1644 * i_Y) + (1.5960 * i_Cr);
int i_green = (1.1644 * i_Y) - (0.3918 * i_Cb) - (0.8130 * i_Cr);
int i_blue = (1.1644 * i_Y) + (2.0172 * i_Cb);
i_red = clip_8_bit( i_red );
i_green = clip_8_bit( i_green );
i_blue = clip_8_bit( i_blue );
#ifdef WORDS_BIGENDIAN
*p_rgb_out++ = i_red;
*p_rgb_out++ = i_green;
*p_rgb_out++ = i_blue;
#else
*p_rgb_out++ = i_blue;
*p_rgb_out++ = i_green;
*p_rgb_out++ = i_red;
#endif
}
/* The byte storage of an RGB pixel. */
#define RGB_SIZE 3
#define GREEN_PIXEL 1
#ifdef WORDS_BIGENDIAN
#define RED_PIXEL 0
#define BLUE_PIXEL 2
#else
#define RED_PIXEL 2
#define BLUE_PIXEL 0
#endif
/**
Store an RGB pixel into the location of p_pixel, taking into
account the "Endian"-ness of the underlying machine.
(N.B. Not sure if I've got this right or this is the right thing
to do.)
*/
static inline void
put_rgb24_pixel(const uint8_t *rgb, /*out*/ uint8_t *p_pixel)
{
#ifdef WORDS_BIGENDIAN
*p_pixel++;
#endif
*p_pixel++ = rgb[RED_PIXEL];
*p_pixel++ = rgb[GREEN_PIXEL];
*p_pixel++ = rgb[BLUE_PIXEL];
}
/**
Find the nearest colormap entry in p_vout (assumed to have RGB2
chroma, i.e. 256 RGB 8bpp entries) that is closest in color to p_rgb. Set
out_rgb to the color found and return the colormap index.
INVALID_CMAP_ENTRY is returned if there is some error.
*/
cmap_t
find_cmap_rgb8_nearest(const vout_thread_t *p_vout, const uint8_t *p_rgb,
/*out*/ uint8_t *out_rgb);
/**
Get the the rgb value for a given colormap entry for p_vout (which is'
assumed to have RGB2 chroma).
VLC_FALSE is returned if there was some error.
*/
vlc_bool_t
query_color(const vout_thread_t *p_vout, cmap_t i_cmap,
/*out*/ uint8_t *rgb);
#endif /* PIXMAP_H */
/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
* indent-tabs-mode: nil
* End:
*/
This diff is collapsed.
/*****************************************************************************
* render.h : Common SVCD and CVD rendering routine(s).
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: render.h,v 1.3 2004/01/21 04:45:47 rocky Exp $
*
* Author: Rocky Bernstein
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Prototypes
*****************************************************************************/
void VCDSubBlend ( vout_thread_t *, picture_t *, const subpicture_t * );
/*****************************************************************************
* subtitle.h : Common SVCD and CVD subtitles header
*****************************************************************************
* Copyright (C) 2003,2004 VideoLAN
* $Id$
*
* Author: Rocky Bernstein
* based on code from:
* Julio Sanchez Fernandez (http://subhandler.sourceforge.net)
* Sam Hocevar <sam@zoy.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include "pixmap.h"
#define DECODE_DBG_EXT 1 /* Calls from external routines */
#define DECODE_DBG_CALL 2 /* all calls */
#define DECODE_DBG_PACKET 4 /* packet assembly info */
#define DECODE_DBG_IMAGE 8 /* image bitmaps */
#define DECODE_DBG_TRANSFORM 16 /* bitmap transformations */
#define DECODE_DBG_RENDER 32 /* rendering information */
#define DECODE_DBG_PNG 64 /* Extract subtitles to PNG files. */
#define DECODE_DBG_INFO 128
#define DEBUG_TEXT N_( \
"If nonzero, this gives additional debug information." \
)
#define DEBUG_LONGTEXT N_( \
"This integer when viewed in binary is a debugging mask\n" \
"external call 1\n" \
"all calls 2\n" \
"packet assembly info 4\n" \
"image bitmaps 8\n" \
"image transformations 16\n" \
"rendering information 32\n" \
"extract subtitles 64\n" \
"misc info 128\n" )
#define SUB_ASPECT_RATIO_TEXT N_("Subtitle aspect-ratio correction")
#define SUB_ASPECT_RATIO_LONGTEXT N_( \
"Use this to force the subtitle aspect ratio. If you give a null string " \
"the right value will be determined automatically. Usually this is what " \
"you want. For OGT and CVD subtitles this undoes the effect " \
"of the underlying video scaling. And using a value of 1 will cause " \
"no correction; subtitles will be scaled with the same aspect " \
"ratio as as the underlying video (which not correct for OGT or " \
"CVD subtitles). You can also force another ratio by giving a pair of " \
"integers x:y where y should between x and twice x. For example 4:3, or " \
"16:9. Alternatively, you can give a float value expressing pixel " \
"squareness. For example 1.25 or 1.3333 which mean the same thing as " \
"4:3 and 16:9 respectively." \
)
#define DURATION_SCALE_TEXT N_("Factor to increase subtitle display interval")
#define DURATION_SCALE_LONGTEXT N_( \
"If you find you need extra time for reading subtitles, " \
"you can set this higher and it will multiply the display " \
"time by that amount. Use 0 to mean until the next " \
"subtitle.")
#define HORIZONTAL_CORRECT \
N_("Add this to starting horizontal position of subtitle.")
#define HORIZONTAL_CORRECT_LONGTEXT N_( \
"If you need to adjust the subtitle starting position horizontally, " \
"set this. Negative values shift left and positive values right. 0 would " \
"be no deviation from where the position specified in the subtitle." \
)
#define VERTICAL_CORRECT \
N_("Add this to starting vertical position of subtitle.")
#define VERTICAL_CORRECT_LONGTEXT N_( \
"If you need to adjust the subtitle starting position vertically, " \
"set this. Negative values shift up, positive values down. 0 would " \
"be no deviation from where the position specified in the subtitle." \
)
#define DECODE_DEBUG 1
#if DECODE_DEBUG
#define dbg_print(mask, s, args...) \
if (p_sys && p_sys->i_debug & mask) \
msg_Dbg(p_dec, "%s: "s, __func__ , ##args)
#else
#define dbg_print(mask, s, args...)
#endif
#define LOG_ERR(args...) msg_Err( p_input, args )
#define LOG_WARN(args...) msg_Warn( p_input, args )
#define GETINT16(p) ( (p[0] << 8) + p[1] ) ; p +=2;
#define GETINT32(p) ( (p[0] << 24) + (p[1] << 16) + \
(p[2] << 8) + (p[3]) ) ; p += 4;
/* The number of color palette entries allowed in a subtitle. */
#define NUM_SUBTITLE_COLORS 4
typedef enum {
SUBTITLE_BLOCK_EMPTY,
SUBTITLE_BLOCK_PARTIAL,
SUBTITLE_BLOCK_COMPLETE
} packet_state_t;
/* The byte storage used by one pixel */
#define PIXEL_SIZE 4
/* Size in bytes of YUV portion above. */
#define YUV_SIZE 3
/* Transparency plane. NOTE: see vlc_video.h for V_PLANE */
#define T_PLANE V_PLANE+1
struct decoder_sys_t
{
int i_debug; /* debugging mask */
mtime_t i_pts; /* Start PTS of subtitle block */
int i_spu;
packet_state_t state; /* data-gathering state for this subtitle */
uint16_t i_image; /* image number in the subtitle stream; 0 is the
first one. */
uint8_t i_packet;/* packet number for above image number; 0 is the
first one. */
block_t *p_block;/* Bytes of the packet. */
uint8_t buffer[65536 + 20 ]; /* we will never overflow more than 11
bytes if I'm right */
int b_packetizer;
int i_spu_size; /* goal for subtitle_data_pos while gathering,
size of used subtitle_data later */
vout_thread_t *p_vout;
int i_subpic_channel; /* Subpicture channel in which subtitles will
be written */
/* FIXME: Remove this? */
uint8_t *subtitle_data; /* buffer used to accumulate data from
successive packets in the same subtitle */
int subtitle_data_size; /* size of the allocated subtitle_data */
/* Move into subpicture_sys_t? */
uint16_t i_image_offset; /* offset from subtitle_data to compressed
image data */
int i_image_length; /* size of the compressed image data */
int first_field_offset; /* offset of even raster lines. Used
only for CVD. */
int second_field_offset; /* offset of odd raster lines */
int metadata_offset; /* offset to data describing the image */
int metadata_length; /* length of metadata */
int subtitle_data_pos; /* where to write next chunk */
mtime_t i_duration; /* how long to display the image, 0 stands
for "until next subtitle" */
uint16_t i_x_start, i_y_start; /* position of top leftmost pixel of
image when displayed */
uint16_t i_width, i_height; /* dimensions in pixels of image */
ogt_yuvt_t p_palette[NUM_SUBTITLE_COLORS]; /* Palette of colors used
in subtitle */
ogt_yuvt_t p_palette_highlight[NUM_SUBTITLE_COLORS]; /* Only used
for CVD */
uint8_t i_options;
uint8_t i_options2;
uint8_t i_cmd;
uint32_t i_cmd_arg;
};
struct subpicture_sys_t
{
int i_debug; /* debugging mask */
mtime_t i_pts; /* presentation timestamp */
uint8_t *p_data; /* Image data one byte T, Y, U, V */
/* Link to our input */
vlc_object_t * p_input;
/* Cropping properties */
vlc_mutex_t lock;
vlc_bool_t b_crop;
unsigned int i_x_start, i_y_start, i_x_end, i_y_end;
/* This is only used for color palette Chromas like RGB2. */
ogt_yuvt_t p_palette[NUM_SUBTITLE_COLORS]; /* Palette of colors used
in subtitle */
};
/*****************************************************************************
* Dump an Image to a Portable Network Graphics (PNG) file
****************************************************************************
Copyright (C) 2004 VideoLAN
Author: Rocky Bernstein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include "config.h"
#ifdef HAVE_LIBPNG
#include <stdio.h>
#include <stdlib.h>
#include "write_png.h"
#include <setjmp.h>
typedef void (*snapshot_messenger_t)(char *message);
#define _(x) x
/*
* Error functions for use as callbacks by the png libraries
*/
void error_msg(char *message)
{
printf("error: %s\n", message);
}
void warning_msg(char *message)
{
printf("warning: %s\n", message);
}
static snapshot_messenger_t error_msg_cb = error_msg;
static snapshot_messenger_t warning_msg_cb = warning_msg;
static void
user_error_fn(png_structp png_ptr, png_const_charp error_msg)
{
if(error_msg_cb) {
char uerror[4096];
memset(&uerror, 0, sizeof(uerror));
sprintf(uerror, _("Error: %s\n"), error_msg);
error_msg_cb(uerror);
}
}
static void
user_warning_fn(png_structp png_ptr, png_const_charp warning_msg)
{
if(error_msg_cb) {
char uerror[4096];
memset(&uerror, 0, sizeof(uerror));
sprintf(uerror, _("Error: %s\n"), warning_msg);
warning_msg_cb(uerror);
}
}
/*
Dump an image to a Portable Network Graphics (PNG) file. File_name
is where the file goes, i_height and i_width are the height and
width in pixels of the image. The data for the image is stored as a
linear array of one byte for each of red, green, and blue
components of an RGB pixel. Thus row[i] will begin at rgb_image +
i*(i_width*3) and the blue pixel at image[i][0] would be rgb_image +
i*(i_width*3) + 1.
*/
void
write_png(const char *file_name, png_uint_32 i_height, png_uint_32 i_width,
void *rgb_image, /*in*/ png_text *text_ptr, int i_text_count )
{
FILE *fp;
png_structp png_ptr;
png_infop info_ptr;
png_color_8 sig_bit;
png_bytep *row_pointers;
unsigned int i,j;
/* open the file */
fp = fopen(file_name, "wb");
if (fp == NULL)
return;
/* Create and initialize the png_struct with the desired error handler
* functions. If you want to use the default stderr and longjump method,
* you can supply NULL for the last three parameters. We also check that
* the library version is compatible with the one used at compile time,
* in case we are using dynamically linked libraries. REQUIRED.
*/
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp) NULL,
user_error_fn, user_warning_fn);
if (png_ptr == NULL)
{
fclose(fp);
return;
}
/* Allocate/initialize the image information data. REQUIRED */
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL)
{
fclose(fp);
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
return;
}
/* Set error handling. REQUIRED if you aren't supplying your own
* error handling functions in the png_create_write_struct() call.
*/
if (setjmp(png_ptr->jmpbuf))
{
/* If we get here, we had a problem writing the file */
fclose(fp);
png_destroy_write_struct(&png_ptr, (png_infopp) &info_ptr);
return;
}
/* Set up the output control using standard C streams. This
is required. */
png_init_io(png_ptr, fp);
/* Set the image information here. i_width and i_height are up to 2^31,
* bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
* the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
* PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
* or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or
* PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
* currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
*/
png_set_IHDR(png_ptr, info_ptr, i_width, i_height, 8, PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE);
/* For color images: */
sig_bit.red = 8;
sig_bit.green = 8;
sig_bit.blue = 8;
if (text_ptr)
png_set_text(png_ptr, info_ptr, text_ptr, i_text_count);
/* Write the file header information. REQUIRED */
png_write_info(png_ptr, info_ptr);
/* Once we write out the header, the compression type on the text
* chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or
* PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again
* at the end.
*/
/* Shift the pixels up to a legal bit depth and fill in
* as appropriate to correctly scale the image.
*/
png_set_shift(png_ptr, &sig_bit);
/* pack pixels into bytes */
png_set_packing(png_ptr);
row_pointers = png_malloc(png_ptr, i_height*sizeof(png_bytep *));
for (i=0, j=0; i<i_height; i++, j+=i_width*3) {
row_pointers[i] = rgb_image + j;
}
png_set_rows (png_ptr, info_ptr, row_pointers);
png_write_image(png_ptr, row_pointers);
/* You can write optional chunks like tEXt, zTXt, and tIME at the end
* as well.
*/
/* It is REQUIRED to call this to finish writing the rest of the file */
png_write_end(png_ptr, info_ptr);
/* if you allocated any text comments, free them here */
/* free image data if allocated. */
/* clean up after the write, and free any memory allocated */
png_destroy_info_struct(png_ptr, &info_ptr);
/* clean up after the write, and free any memory allocated */
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
fclose(fp);
return;
}
#ifdef STANDALONE
int
main(int argc, char **argv)
{
char image_data[3*16 * 3*16 * 3];
int i,j,k,l,m;
char r,g,b,t, or,og,ob;
or=0x00; og=0xFF; ob=0x0;
m=0;
for (i=0; i<3; i++) {
t=or; or=og; og=ob; ob=t;
for (j=0; j<16; j++) {
r=or; g=og; b=ob;
for (k=0; k<3; k++) {
for (l=0; l<16; l++) {
image_data[m++]=r;
image_data[m++]=g;
image_data[m++]=b;
}
t=r; r=g; g=b; b=t;
}
}
}
write_png("/tmp/pngtest.png", 3*16, 3*16, (void *) image_data) ;
return 0;
}
#endif /*STANDALONE*/
#endif /*HAVE_LIBPNG*/
/*****************************************************************************
* Dump an Image to a Portable Network Graphics (PNG) file
****************************************************************************
Copyright (C) 2004 VideoLAN
Author: Rocky Bernstein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include <png.h>
/*
Dump an image to a Portable Network Graphics (PNG) file. File_name
is where the file goes, i_height and i_width are the height and
width in pixels of the image. The data for the image is stored as a
linear array RGB pixel entries: one byte for each of red, green,
and blue component. Thus row[i] will begin at rgb_image +
i*(i_width*3) and the blue pixel at image[i][0] would be rgb_image
+ i*(i_width*3) + 1.
text_ptr contains comments that can be written to the image. It can
be null. i_text_count is the number of entries in text_ptr.
*/
void write_png(const char *file_name, png_uint_32 i_height,
png_uint_32 i_width, void *rgb_image,
/*in*/ png_text *text_ptr, int i_text_count );
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment