Commit 289aade7 authored by Rocky Bernstein's avatar Rocky Bernstein

ogt.c cvd.c, subtitle.h: move common debug string help into subtitle.h

{cvd,ogt}_parse.c, common.c, subtitle.h: add ability to dump subtitles via
libpng.
parent 3a903d5f
/*****************************************************************************
* Common SVCD and VCD subtitle routines.
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: common.c,v 1.2 2003/12/30 04:43:52 rocky Exp $
* Copyright (C) 2003, 2004 VideoLAN
* $Id: common.c,v 1.3 2004/01/03 12:54:56 rocky Exp $
*
* Author: Rocky Bernstein
* based on code from:
......@@ -34,6 +34,9 @@
#include "subtitle.h"
#include "common.h"
#ifdef HAVE_LIBPNG
#include "write_png.h"
#endif
/*****************************************************************************
Free Resources associated with subtitle packet.
......@@ -123,6 +126,14 @@ VCDSubAppendData ( decoder_t *p_dec, uint8_t *buffer, uint32_t buf_len )
}
if ( chunk_length > 0 ) {
#if 0
int i;
int8_t *b=buffer;
for (i=0; i<chunk_length; i++)
printf ("%02x", b[i]);
printf("\n");
#endif
memcpy(p_sys->subtitle_data + p_sys->subtitle_data_pos,
buffer, chunk_length);
p_sys->subtitle_data_pos += chunk_length;
......@@ -175,7 +186,7 @@ VCDInlinePalette ( /*inout*/ uint8_t *p_dest, decoder_sys_t *p_sys,
ogt_yuvt_t *p_to = (ogt_yuvt_t *) p_dest;
for ( ; n >= 0 ; n-- ) {
p_to[n] = p_sys->pi_palette[p_from[n]];
p_to[n] = p_sys->p_palette[p_from[n]];
}
}
......@@ -302,3 +313,131 @@ void VCDSubUpdateSPU( subpicture_t *p_spu, vlc_object_t *p_object )
}
/*
Dump an a subtitle image to standard output - for debugging.
*/
void VCDSubDumpImage( uint8_t *p_image, uint32_t i_height, uint32_t i_width )
{
uint8_t *p = p_image;
unsigned int i_row; /* scanline row number */
unsigned int i_column; /* scanline column number */
printf("-------------------------------------\n++");
for ( i_row=0; i_row < i_height; i_row ++ ) {
for ( i_column=0; i_column<i_width; i_column++ ) {
printf("%1d", *p++ & 0x03);
}
printf("\n++");
}
printf("\n-------------------------------------\n");
}
/*
FIXME:
MOVE clip_8_bit and uuv2rgb TO A MORE GENERIC PLACE.
*/
/* Force v in the range 0.255 */
static inline uint8_t
clip_8_bit(int v)
{
if (v<0) return 0;
if (v>255) return 255;
return (uint8_t) 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.
***************************************************/
static inline void
yuv2rgb(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 );
*p_rgb_out++ = i_red;
*p_rgb_out++ = i_green;
*p_rgb_out++ = i_blue;
}
#ifdef HAVE_LIBPNG
#define BYTES_PER_RGB 3
#define PALETTE_SIZE 4
/* Note the below assumes the above is a power of 2 */
#define PALETTE_SIZE_MASK (PALETTE_SIZE-1)
/*
Dump an a subtitle image to a Portable Network Graphics (PNG) file.
All we do here is convert YUV palette entries to RGB, expand
the image into a linear RGB pixel array, and call the routine
that does the PNG writing.
*/
void
VCDSubDumpPNG( uint8_t *p_image, decoder_t *p_dec,
uint32_t i_height, uint32_t i_width, const char *filename,
png_text *text_ptr, int i_text_count )
{
decoder_sys_t *p_sys = p_dec->p_sys;
uint8_t *p = p_image;
uint8_t *image_data = malloc(BYTES_PER_RGB * i_height * i_width );
uint8_t *q = image_data;
unsigned int i_row; /* scanline row number */
unsigned int i_column; /* scanline column number */
uint8_t rgb_palette[PALETTE_SIZE * BYTES_PER_RGB];
int i;
dbg_print( (DECODE_DBG_CALL), "%s", filename);
if (NULL == image_data) return;
/* Convert palette YUV into RGB. */
for (i=0; i<PALETTE_SIZE; i++) {
ogt_yuvt_t *p_yuv = &(p_sys->p_palette[i]);
uint8_t *p_rgb_out = &(rgb_palette[i*BYTES_PER_RGB]);
yuv2rgb( p_yuv, p_rgb_out );
}
/* Convert palette entries into linear RGB array. */
for ( i_row=0; i_row < i_height; i_row ++ ) {
for ( i_column=0; i_column<i_width; i_column++ ) {
uint8_t *p_rgb = &rgb_palette[ ((*p)&PALETTE_SIZE_MASK)*BYTES_PER_RGB ];
*q++ = p_rgb[0];
*q++ = p_rgb[1];
*q++ = p_rgb[2];
p++;
}
}
write_png( filename, i_height, i_width, image_data, text_ptr, i_text_count );
free(image_data);
}
#endif /*HAVE_LIBPNG*/
/*****************************************************************************
* Header for Common SVCD and VCD subtitle routines.
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: common.h,v 1.2 2003/12/30 04:43:52 rocky Exp $
* Copyright (C) 2003, 2004 VideoLAN
* $Id: common.h,v 1.3 2004/01/03 12:54:56 rocky Exp $
*
* Author: Rocky Bernstein
*
......@@ -22,22 +22,37 @@
*****************************************************************************/
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 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 VCDInlinePalette ( /*inout*/ uint8_t *p_dest,
decoder_sys_t *p_sys, unsigned int i_height,
unsigned int i_width );
void VCDSubDumpImage( uint8_t *p_image, uint32_t i_height,
uint32_t i_width );
#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*/
......@@ -2,7 +2,7 @@
* cvd.c : CVD Subtitle decoder thread
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: cvd.c,v 1.5 2004/01/01 13:54:24 rocky Exp $
* $Id: cvd.c,v 1.6 2004/01/03 12:54:56 rocky Exp $
*
* Authors: Rocky Bernstein
* based on code from:
......@@ -36,15 +36,6 @@
#include "cvd.h"
#include "common.h"
#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" \
"misc info 32\n" )
/*****************************************************************************
* Module descriptor.
*****************************************************************************/
......@@ -324,9 +315,9 @@ Reassemble( decoder_t *p_dec, block_t **pp_block )
"primary palette %d (y,u,v): (0x%0x,0x%0x,0x%0x)",
v, p[1], p[2], p[3]);
p_sys->pi_palette[v].s.y = p[1];
p_sys->pi_palette[v].s.u = p[2];
p_sys->pi_palette[v].s.v = p[3];
p_sys->p_palette[v].s.y = p[1];
p_sys->p_palette[v].s.u = p[2];
p_sys->p_palette[v].s.v = p[3];
break;
}
......@@ -343,43 +334,43 @@ Reassemble( decoder_t *p_dec, block_t **pp_block )
v, p[1], p[2], p[3]);
/* Highlight Palette */
p_sys->pi_palette_highlight[v].s.y = p[1];
p_sys->pi_palette_highlight[v].s.u = p[2];
p_sys->pi_palette_highlight[v].s.v = p[3];
p_sys->p_palette_highlight[v].s.y = p[1];
p_sys->p_palette_highlight[v].s.u = p[2];
p_sys->p_palette_highlight[v].s.v = p[3];
break;
}
case 0x37:
/* transparency for primary palette */
p_sys->pi_palette[0].s.t = p[3] & 0x0f;
p_sys->pi_palette[1].s.t = p[3] >> 4;
p_sys->pi_palette[2].s.t = p[2] & 0x0f;
p_sys->pi_palette[3].s.t = p[2] >> 4;
p_sys->p_palette[0].s.t = p[3] & 0x0f;
p_sys->p_palette[1].s.t = p[3] >> 4;
p_sys->p_palette[2].s.t = p[2] & 0x0f;
p_sys->p_palette[3].s.t = p[2] >> 4;
dbg_print( DECODE_DBG_PACKET,
"transparancy for primary palette 0..3: "
"0x%0x 0x%0x 0x%0x 0x%0x",
p_sys->pi_palette[0].s.t,
p_sys->pi_palette[1].s.t,
p_sys->pi_palette[2].s.t,
p_sys->pi_palette[3].s.t );
p_sys->p_palette[0].s.t,
p_sys->p_palette[1].s.t,
p_sys->p_palette[2].s.t,
p_sys->p_palette[3].s.t );
break;
case 0x3f:
/* transparency for highlight palette */
p_sys->pi_palette_highlight[0].s.t = p[2] & 0x0f;
p_sys->pi_palette_highlight[1].s.t = p[2] >> 4;
p_sys->pi_palette_highlight[2].s.t = p[1] & 0x0f;
p_sys->pi_palette_highlight[3].s.t = p[1] >> 4;
p_sys->p_palette_highlight[0].s.t = p[2] & 0x0f;
p_sys->p_palette_highlight[1].s.t = p[2] >> 4;
p_sys->p_palette_highlight[2].s.t = p[1] & 0x0f;
p_sys->p_palette_highlight[3].s.t = p[1] >> 4;
dbg_print( DECODE_DBG_PACKET,
"transparancy for primary palette 0..3: "
"0x%0x 0x%0x 0x%0x 0x%0x",
p_sys->pi_palette_highlight[0].s.t,
p_sys->pi_palette_highlight[1].s.t,
p_sys->pi_palette_highlight[2].s.t,
p_sys->pi_palette_highlight[3].s.t );
p_sys->p_palette_highlight[0].s.t,
p_sys->p_palette_highlight[1].s.t,
p_sys->p_palette_highlight[2].s.t,
p_sys->p_palette_highlight[3].s.t );
break;
......
/*****************************************************************************
* parse.c: Philips OGT (SVCD subtitle) packet parser
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: cvd_parse.c,v 1.4 2003/12/30 04:43:52 rocky Exp $
* Copyright (C) 2003, 2004 VideoLAN
* $Id: cvd_parse.c,v 1.5 2004/01/03 12:54:56 rocky Exp $
*
* Authors: Rocky Bernstein
* based on code from:
......@@ -37,6 +37,10 @@
#include "cvd.h"
#include "common.h"
#ifdef HAVE_LIBPNG
#include <png.h>
#endif
/* An image color is a two-bit palette entry: 0..3 */
typedef uint8_t ogt_color_t;
......@@ -264,6 +268,14 @@ ParseImage( decoder_t *p_dec, subpicture_t * p_spu )
for ( i_field=0; i_field < 2; i_field++ ) {
i_nibble_field = 2; /* 4-bit pieces available in *p */
#if 0
unsigned int i;
int8_t *b=p;
for (i=0; i< i_width * i_height; i++)
printf ("%02x", b[i]);
printf("\n");
#endif
for ( i_row=i_field; i_row < i_height; i_row += 2 ) {
b_filling = VLC_FALSE;
for ( i_column=0; i_column<i_width; i_column++ ) {
......@@ -326,18 +338,31 @@ ParseImage( decoder_t *p_dec, subpicture_t * p_spu )
}
}
/* Dump out image not interlaced... */
if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE) {
uint8_t *p = p_dest;
printf("-------------------------------------\n++");
for ( i_row=0; i_row < i_height; i_row ++ ) {
for ( i_column=0; i_column<i_width; i_column++ ) {
printf("%1d", *p++ & 0x03);
}
printf("\n++");
}
printf("\n-------------------------------------\n");
if (p_sys && (p_sys->i_debug & DECODE_DBG_IMAGE)) {
/* Dump out image not interlaced... */
VCDSubDumpImage( p_dest, i_height, i_width );
}
#ifdef HAVE_LIBPNG
if (p_sys && (p_sys->i_debug & DECODE_DBG_PNG)) {
#define TEXT_COUNT 2
/* Dump image to a file in PNG format. */
char filename[300];
png_text text_ptr[TEXT_COUNT];
text_ptr[0].key = "Preparer";
text_ptr[0].text = "VLC";
text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
text_ptr[1].key = "Description";
text_ptr[1].text = "CVD Subtitle";
text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
snprintf(filename, 300, "%s%d.png", "/tmp/vlc-cvd-sub", p_sys->i_image);
VCDSubDumpPNG( p_dest, p_dec, i_height, i_width, filename,
text_ptr, TEXT_COUNT );
}
#endif /*HAVE_LIBPNG*/
VCDInlinePalette( p_dest, p_sys, i_height, i_width );
......
/*****************************************************************************
* ogt.c : Overlay Graphics Text (SVCD subtitles) decoder thread
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: ogt.c,v 1.7 2004/01/01 13:55:17 rocky Exp $
* Copyright (C) 2003, 2004 VideoLAN
* $Id: ogt.c,v 1.8 2004/01/03 12:54:56 rocky Exp $
*
* Authors: Rocky Bernstein
* Author: Rocky Bernstein
* based on code from:
* Julio Sanchez Fernandez (http://subhandler.sourceforge.net)
* Samuel Hocevar <sam@zoy.org>
......@@ -36,17 +36,6 @@
#include "ogt.h"
#include "common.h"
#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" \
"misc info 64\n" )
/*****************************************************************************
* Module descriptor.
*****************************************************************************/
......
/*****************************************************************************
* Philips OGT (SVCD subtitle) packet parser
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: ogt_parse.c,v 1.4 2003/12/30 04:43:52 rocky Exp $
* Copyright (C) 2003, 2004 VideoLAN
* $Id: ogt_parse.c,v 1.5 2004/01/03 12:54:56 rocky Exp $
*
* Author: Rocky Bernstein
* based on code from:
......@@ -37,6 +37,10 @@
#include "render.h"
#include "ogt.h"
#ifdef HAVE_LIBPNG
#include <png.h>
#endif
/* An image color is a two-bit palette entry: 0..3 */
typedef uint8_t ogt_color_t;
......@@ -104,14 +108,14 @@ void E_(ParseHeader)( decoder_t *p_dec, uint8_t *p_buffer, block_t *p_block )
p_sys->i_height = GETINT16(p);
for (i=0; i<4; i++) {
p_sys->pi_palette[i].s.y = *p++;
p_sys->pi_palette[i].s.u = *p++;
p_sys->pi_palette[i].s.v = *p++;
p_sys->p_palette[i].s.y = *p++;
p_sys->p_palette[i].s.u = *p++;
p_sys->p_palette[i].s.v = *p++;
/* OGT has 8-bit resolution for alpha, but DVD's and CVDS use 4-bits.
Since we want to use the same render routine, rather than scale up
CVD (and DVD) subtitles, we'll scale down ours.
*/
p_sys->pi_palette[i].s.t = (*p++) >> 4;
p_sys->p_palette[i].s.t = (*p++) >> 4;
}
p_sys->i_cmd = *p++;
/* We do not really know this, FIXME */
......@@ -136,8 +140,8 @@ void E_(ParseHeader)( decoder_t *p_dec, uint8_t *p_buffer, block_t *p_block )
for (i=0; i<4; i++) {
msg_Dbg( p_dec, "palette[%d]= T: %2x, Y: %2x, u: %2x, v: %2x", i,
p_sys->pi_palette[i].s.t, p_sys->pi_palette[i].s.y,
p_sys->pi_palette[i].s.u, p_sys->pi_palette[i].s.v );
p_sys->p_palette[i].s.t, p_sys->p_palette[i].s.y,
p_sys->p_palette[i].s.u, p_sys->p_palette[i].s.v );
}
}
}
......@@ -325,7 +329,7 @@ ParseImage( decoder_t *p_dec, subpicture_t * p_spu )
}
if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE)
if (p_sys && (p_sys->i_debug & DECODE_DBG_IMAGE))
printf("\n");
if ( i_2bit_field != 4 ) {
......@@ -337,20 +341,33 @@ ParseImage( decoder_t *p_dec, subpicture_t * p_spu )
+ p_sys->second_field_offset;
}
/* Dump out image not interlaced... */
if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE) {
uint8_t *p = p_dest;
printf("-------------------------------------\n++");
for ( i_row=0; i_row < i_height; i_row ++ ) {
for ( i_column=0; i_column<i_width; i_column++ ) {
printf("%1d", *p++ & 0x03);
}
printf("\n++");
}
printf("\n-------------------------------------\n");
if (p_sys && (p_sys->i_debug & DECODE_DBG_IMAGE)) {
/* Dump out image not interlaced... */
VCDSubDumpImage( p_dest, i_height, i_width );
}
#ifdef HAVE_LIBPNG
if (p_sys && (p_sys->i_debug & DECODE_DBG_PNG)) {
#define TEXT_COUNT 2
/* Dump image to a file in PNG format. */
char filename[300];
png_text text_ptr[TEXT_COUNT];
text_ptr[0].key = "Preparer";
text_ptr[0].text = "VLC";
text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
text_ptr[1].key = "Description";
text_ptr[1].text = "SVCD Subtitle";
text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
snprintf(filename, 300, "%s%d.png", "/tmp/vlc-svcd-sub", p_sys->i_image);
VCDSubDumpPNG( p_dest, p_dec, i_height, i_width, filename,
text_ptr, TEXT_COUNT );
}
#endif /*HAVE_LIBPNG*/
VCDInlinePalette( p_dest, p_sys, i_height, i_width );
/* The video is automatically scaled. However subtitle bitmaps
assume a 1:1 aspect ratio. So we need to scale to compensate for
......
/*****************************************************************************
* subtitle.h : Common SVCD and CVD subtitles header
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: subtitle.h,v 1.2 2003/12/28 11:26:52 rocky Exp $
* Copyright (C) 2003,2004 VideoLAN
* $Id: subtitle.h,v 1.3 2004/01/03 12:54:56 rocky Exp $
*
* Author: Rocky Bernstein
* based on code from:
......@@ -30,7 +30,19 @@
#define DECODE_DBG_IMAGE 8 /* image bitmaps */
#define DECODE_DBG_TRANSFORM 16 /* bitmap transformations */
#define DECODE_DBG_RENDER 32 /* rendering information */
#define DECODE_DBG_INFO 64
#define DECODE_DBG_PNG 64 /* Extract subtitles to PNG files. */
#define DECODE_DBG_INFO 128
#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 DECODE_DEBUG 1
#if DECODE_DEBUG
......@@ -124,11 +136,11 @@ struct decoder_sys_t
image when displayed */
uint16_t i_width, i_height; /* dimensions in pixels of image */
ogt_yuvt_t pi_palette[NUM_SUBTITLE_COLORS]; /* Palette of colors used
ogt_yuvt_t p_palette[NUM_SUBTITLE_COLORS]; /* Palette of colors used
in subtitle */
ogt_yuvt_t pi_palette_highlight[NUM_SUBTITLE_COLORS]; /* Only used
ogt_yuvt_t p_palette_highlight[NUM_SUBTITLE_COLORS]; /* Only used
for CVD */
uint8_t i_options;
......
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