/*
* $Id$
*
* (C) 2006-2010 see AUTHORS
*
* This file is part of mplayerc.
*
* Mplayerc 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 3 of the License, or
* (at your option) any later version.
*
* Mplayerc 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, see .
*
*/
#include "stdafx.h"
#include "CompositionObject.h"
#include "../DSUtil/GolombBuffer.h"
CompositionObject::CompositionObject()
{
m_rtStart = 0;
m_rtStop = 0;
m_pRLEData = NULL;
m_nRLEDataSize = 0;
m_nRLEPos = 0;
m_nColorNumber = 0;
memsetd (m_Colors, 0xFF000000, sizeof(m_Colors));
}
CompositionObject::~CompositionObject()
{
delete[] m_pRLEData;
}
void CompositionObject::SetPalette (int nNbEntry, HDMV_PALETTE* pPalette, bool bIsHD)
{
m_nColorNumber = nNbEntry;
for (int i=0; i 0)
nPaletteIndex = 0;
}
else
{
nCount = (bSwitch&0x3F) <<8 | (SHORT)GBuffer.ReadByte();
nPaletteIndex = 0;
}
}
else
{
if (!(bSwitch & 0x40))
{
nCount = bSwitch & 0x3F;
nPaletteIndex = GBuffer.ReadByte();
}
else
{
nCount = (bSwitch&0x3F) <<8 | (SHORT)GBuffer.ReadByte();
nPaletteIndex = GBuffer.ReadByte();
}
}
}
if (nCount>0)
{
if (nPaletteIndex != 0xFF) // Fully transparent (§9.14.4.2.2.1.1)
FillSolidRect (spd, nX, nY, nCount, 1, m_Colors[nPaletteIndex]);
nX += nCount;
}
else
{
nY++;
nX = 0;
}
}
}
}
void CompositionObject::RenderDvb(SubPicDesc& spd, SHORT nX, SHORT nY)
{
if (m_pRLEData)
{
CGolombBuffer gb (m_pRLEData, m_nRLEDataSize);
SHORT sTopFieldLength;
SHORT sBottomFieldLength;
sTopFieldLength = gb.ReadShort();
sBottomFieldLength = gb.ReadShort();
DvbRenderField (spd, gb, nX, nY, sTopFieldLength);
DvbRenderField (spd, gb, nX, nY+1, sBottomFieldLength);
}
}
void CompositionObject::DvbRenderField(SubPicDesc& spd, CGolombBuffer& gb, SHORT nXStart, SHORT nYStart, SHORT nLength)
{
//FillSolidRect (spd, 0, 0, 300, 10, 0xFFFF0000); // Red opaque
//FillSolidRect (spd, 0, 10, 300, 10, 0xCC00FF00); // Green 80%
//FillSolidRect (spd, 0, 20, 300, 10, 0x100000FF); // Blue 60%
//return;
SHORT nX = nXStart;
SHORT nY = nYStart;
INT64 nEnd = gb.GetPos()+nLength;
while (gb.GetPos() < nEnd)
{
BYTE bType = gb.ReadByte();
switch (bType)
{
case 0x10 :
Dvb2PixelsCodeString(spd, gb, nX, nY);
break;
case 0x11 :
Dvb4PixelsCodeString(spd, gb, nX, nY);
break;
case 0x12 :
Dvb8PixelsCodeString(spd, gb, nX, nY);
break;
case 0x20 :
gb.SkipBytes (2);
break;
case 0x21 :
gb.SkipBytes (4);
break;
case 0x22 :
gb.SkipBytes (16);
break;
case 0xF0 :
nX = nXStart;
nY += 2;
break;
default :
ASSERT(FALSE);
break;
}
}
}
void CompositionObject::Dvb2PixelsCodeString(SubPicDesc& spd, CGolombBuffer& gb, SHORT& nX, SHORT& nY)
{
BYTE bTemp;
BYTE nPaletteIndex = 0;
SHORT nCount;
bool bQuit = false;
while (!bQuit && !gb.IsEOF())
{
nCount = 0;
nPaletteIndex = 0;
bTemp = (BYTE)gb.BitRead(2);
if (bTemp != 0)
{
nPaletteIndex = bTemp;
nCount = 1;
}
else
{
if (gb.BitRead(1) == 1) // switch_1
{
nCount = 3 + (SHORT)gb.BitRead(3); // run_length_3-9
nPaletteIndex = (BYTE)gb.BitRead(2);
}
else
{
if (gb.BitRead(1) == 0) // switch_2
{
switch (gb.BitRead(2)) // switch_3
{
case 0 :
bQuit = true;
break;
case 1 :
nCount = 2;
break;
case 2 : // if (switch_3 == '10')
nCount = 12 + (SHORT)gb.BitRead(4); // run_length_12-27
nPaletteIndex = (BYTE)gb.BitRead(2); // 4-bit_pixel-code
break;
case 3 :
nCount = 29 + gb.ReadByte(); // run_length_29-284
nPaletteIndex = (BYTE)gb.BitRead(2); // 4-bit_pixel-code
break;
}
}
else
nCount = 1;
}
}
if (nX+nCount > m_width)
{
ASSERT (FALSE);
break;
}
if (nCount>0)
{
FillSolidRect (spd, nX, nY, nCount, 1, m_Colors[nPaletteIndex]);
nX += nCount;
}
}
gb.BitByteAlign();
}
void CompositionObject::Dvb4PixelsCodeString(SubPicDesc& spd, CGolombBuffer& gb, SHORT& nX, SHORT& nY)
{
BYTE bTemp;
BYTE nPaletteIndex = 0;
SHORT nCount;
bool bQuit = false;
while (!bQuit && !gb.IsEOF())
{
nCount = 0;
nPaletteIndex = 0;
bTemp = (BYTE)gb.BitRead(4);
if (bTemp != 0)
{
nPaletteIndex = bTemp;
nCount = 1;
}
else
{
if (gb.BitRead(1) == 0) // switch_1
{
nCount = (SHORT)gb.BitRead(3); // run_length_3-9
if (nCount != 0)
nCount += 2;
else
bQuit = true;
}
else
{
if (gb.BitRead(1) == 0) // switch_2
{
nCount = 4 + (SHORT)gb.BitRead(2); // run_length_4-7
nPaletteIndex = (BYTE)gb.BitRead(4); // 4-bit_pixel-code
}
else
{
switch (gb.BitRead(2)) // switch_3
{
case 0 :
nCount = 1;
break;
case 1 :
nCount = 2;
break;
case 2 : // if (switch_3 == '10')
nCount = 9 + (SHORT)gb.BitRead(4); // run_length_9-24
nPaletteIndex = (BYTE)gb.BitRead(4); // 4-bit_pixel-code
break;
case 3 :
nCount = 25 + gb.ReadByte(); // run_length_25-280
nPaletteIndex = (BYTE)gb.BitRead(4); // 4-bit_pixel-code
break;
}
}
}
}
if (nX+nCount > m_width)
{
ASSERT (FALSE);
break;
}
if (nCount>0)
{
FillSolidRect (spd, nX, nY, nCount, 1, m_Colors[nPaletteIndex]);
nX += nCount;
}
}
gb.BitByteAlign();
}
void CompositionObject::Dvb8PixelsCodeString(SubPicDesc& spd, CGolombBuffer& gb, SHORT& nX, SHORT& nY)
{
BYTE bTemp;
BYTE nPaletteIndex = 0;
SHORT nCount;
bool bQuit = false;
while (!bQuit && !gb.IsEOF())
{
nCount = 0;
nPaletteIndex = 0;
bTemp = gb.ReadByte();
if (bTemp != 0)
{
nPaletteIndex = bTemp;
nCount = 1;
}
else
{
if (gb.BitRead(1) == 0) // switch_1
{
nCount = (SHORT)gb.BitRead(7); // run_length_1-127
if (nCount == 0)
bQuit = true;
}
else
{
nCount = (SHORT)gb.BitRead(7); // run_length_3-127
nPaletteIndex = gb.ReadByte();
}
}
if (nX+nCount > m_width)
{
ASSERT (FALSE);
break;
}
if (nCount>0)
{
FillSolidRect (spd, nX, nY, nCount, 1, m_Colors[nPaletteIndex]);
nX += nCount;
}
}
gb.BitByteAlign();
}