2 * (C) 2006-2012 see Authors.txt
4 * This file is part of MPC-HC.
6 * MPC-HC is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * MPC-HC is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "CompositionObject.h"
23 #include "../DSUtil/GolombBuffer.h"
24 #include "../subpic/color_conv_table.h"
27 CompositionObject::CompositionObject()
33 memsetd(m_Colors
, 0xFF000000, sizeof(m_Colors
));
36 CompositionObject::~CompositionObject()
41 void CompositionObject::SetPalette(int nNbEntry
, HDMV_PALETTE
* pPalette
, bool bIsHD
)
43 m_OriginalColorType
= bIsHD
? YUV_Rec709
: YUV_Rec601
;
47 m_Palette
.SetCount(nNbEntry
>0?nNbEntry
:0);
50 memcpy(m_Palette
.GetData(), pPalette
, nNbEntry
*sizeof(pPalette
[0]));
54 void CompositionObject::InitColor(const SubPicDesc
& spd
)
56 #define COMBINE_AYUV(a, y, u, v) ((((((((int)(a))<<8)|y)<<8)|u)<<8)|v)
57 //fix me: move all color conv function into color_conv_table or dsutil
59 int paletteNumber
= m_Palette
.GetCount();
60 if (m_colorType
!=spd
.type
)
63 if(m_OriginalColorType
!=NONE
)
65 m_colorType
= spd
.type
;
70 if ((m_OriginalColorType
==YUV_Rec709
&& ColorConvTable::GetDefaultYUVType()==ColorConvTable::BT709
) ||
71 (m_OriginalColorType
==YUV_Rec601
&& ColorConvTable::GetDefaultYUVType()==ColorConvTable::BT601
))
73 for (int i
=0;i
<paletteNumber
;i
++)
75 m_Colors
[m_Palette
[i
].entry_id
] = COMBINE_AYUV(m_Palette
[i
].T
, m_Palette
[i
].Y
, m_Palette
[i
].Cr
, m_Palette
[i
].Cb
);
78 else if (m_OriginalColorType
==YUV_Rec709
)
80 for (int i
=0;i
<paletteNumber
;i
++)
82 DWORD argb
= ColorConvTable::A8Y8U8V8_To_ARGB_TV_BT709(m_Palette
[i
].T
, m_Palette
[i
].Y
, m_Palette
[i
].Cr
, m_Palette
[i
].Cb
);
83 m_Colors
[m_Palette
[i
].entry_id
] = ColorConvTable::Argb2Ayuv(argb
);
86 else if (m_OriginalColorType
==YUV_Rec601
)
88 for (int i
=0;i
<paletteNumber
;i
++)
90 DWORD argb
= ColorConvTable::A8Y8U8V8_To_ARGB_TV_BT601(m_Palette
[i
].T
, m_Palette
[i
].Y
, m_Palette
[i
].Cr
, m_Palette
[i
].Cb
);
91 m_Colors
[m_Palette
[i
].entry_id
] = ColorConvTable::Argb2Ayuv(argb
);
100 if ((m_OriginalColorType
==YUV_Rec709
&& ColorConvTable::GetDefaultYUVType()==ColorConvTable::BT709
) ||
101 (m_OriginalColorType
==YUV_Rec601
&& ColorConvTable::GetDefaultYUVType()==ColorConvTable::BT601
))
103 for (int i
=0;i
<paletteNumber
;i
++)
105 m_Colors
[m_Palette
[i
].entry_id
] = COMBINE_AYUV(m_Palette
[i
].T
, m_Palette
[i
].Cr
, m_Palette
[i
].Y
, m_Palette
[i
].Cb
);
108 else if (m_OriginalColorType
==YUV_Rec709
)
110 for (int i
=0;i
<paletteNumber
;i
++)
112 DWORD argb
= YCrCbToRGB_Rec709(m_Palette
[i
].T
, m_Palette
[i
].Y
, m_Palette
[i
].Cr
, m_Palette
[i
].Cb
);
113 m_Colors
[m_Palette
[i
].entry_id
] = ColorConvTable::Argb2Auyv(argb
);
116 else if (m_OriginalColorType
==YUV_Rec601
)
118 for (int i
=0;i
<paletteNumber
;i
++)
120 DWORD argb
= YCrCbToRGB_Rec601(m_Palette
[i
].T
, m_Palette
[i
].Y
, m_Palette
[i
].Cr
, m_Palette
[i
].Cb
);
121 m_Colors
[m_Palette
[i
].entry_id
] = ColorConvTable::Argb2Auyv(argb
);
130 if (m_OriginalColorType
==YUV_Rec709
)
132 for (int i
=0;i
<paletteNumber
;i
++)
134 DWORD argb
= YCrCbToRGB_Rec709(m_Palette
[i
].T
, m_Palette
[i
].Y
, m_Palette
[i
].Cr
, m_Palette
[i
].Cb
);
135 m_Colors
[m_Palette
[i
].entry_id
] = argb
;
138 else if (m_OriginalColorType
==YUV_Rec601
)
140 for (int i
=0;i
<paletteNumber
;i
++)
142 DWORD argb
= YCrCbToRGB_Rec601(m_Palette
[i
].T
, m_Palette
[i
].Y
, m_Palette
[i
].Cr
, m_Palette
[i
].Cb
);
143 m_Colors
[m_Palette
[i
].entry_id
] = argb
;
156 if (m_colorType
== -1)
158 //todo fixme: log error
163 void CompositionObject::SetRLEData(const BYTE
* pBuffer
, int nSize
, int nTotalSize
)
165 delete [] m_pRLEData
;
166 m_pRLEData
= DNew BYTE
[nTotalSize
];
167 m_nRLEDataSize
= nTotalSize
;
170 memcpy(m_pRLEData
, pBuffer
, nSize
);
173 void CompositionObject::AppendRLEData(const BYTE
* pBuffer
, int nSize
)
175 ASSERT(m_nRLEPos
+ nSize
<= m_nRLEDataSize
);
176 if (m_nRLEPos
+ nSize
<= m_nRLEDataSize
) {
177 memcpy(m_pRLEData
+ m_nRLEPos
, pBuffer
, nSize
);
183 void CompositionObject::RenderHdmv(SubPicDesc
& spd
)
185 if (!m_pRLEData
|| !HavePalette()) {
189 CGolombBuffer
GBuffer(m_pRLEData
, m_nRLEDataSize
);
192 BYTE nPaletteIndex
= 0;
194 short nX
= m_horizontal_position
;
195 short nY
= m_vertical_position
;
197 while ((nY
< (m_vertical_position
+ m_height
)) && !GBuffer
.IsEOF()) {
198 bTemp
= GBuffer
.ReadByte();
200 nPaletteIndex
= bTemp
;
203 bSwitch
= GBuffer
.ReadByte();
204 if (!(bSwitch
& 0x80)) {
205 if (!(bSwitch
& 0x40)) {
206 nCount
= bSwitch
& 0x3F;
211 nCount
= (bSwitch
& 0x3F) << 8 | (short)GBuffer
.ReadByte();
215 if (!(bSwitch
& 0x40)) {
216 nCount
= bSwitch
& 0x3F;
217 nPaletteIndex
= GBuffer
.ReadByte();
219 nCount
= (bSwitch
& 0x3F) << 8 | (short)GBuffer
.ReadByte();
220 nPaletteIndex
= GBuffer
.ReadByte();
226 if (nPaletteIndex
!= 0xFF) { // Fully transparent (§9.14.4.2.2.1.1)
227 FillSolidRect(spd
, nX
, nY
, nCount
, 1, m_Colors
[nPaletteIndex
]);
232 nX
= m_horizontal_position
;
238 void CompositionObject::RenderDvb(SubPicDesc
& spd
, short nX
, short nY
)
244 CGolombBuffer
gb(m_pRLEData
, m_nRLEDataSize
);
245 short sTopFieldLength
;
246 short sBottomFieldLength
;
248 sTopFieldLength
= gb
.ReadShort();
249 sBottomFieldLength
= gb
.ReadShort();
251 DvbRenderField(spd
, gb
, nX
, nY
, sTopFieldLength
);
252 DvbRenderField(spd
, gb
, nX
, nY
+ 1, sBottomFieldLength
);
256 void CompositionObject::DvbRenderField(SubPicDesc
& spd
, CGolombBuffer
& gb
, short nXStart
, short nYStart
, short nLength
)
258 //FillSolidRect(spd, nXStart, nYStart, m_width, m_height, 0xFFFF0000); // Red opaque
259 //FillSolidRect(spd, nXStart, nYStart, m_width, m_height, 0xCC00FF00); // Green 80%
260 //FillSolidRect(spd, nXStart, nYStart, m_width, m_height, 0x100000FF); // Blue 60%
264 int nEnd
= gb
.GetPos() + nLength
;
265 while (gb
.GetPos() < nEnd
) {
266 BYTE bType
= gb
.ReadByte();
269 Dvb2PixelsCodeString(spd
, gb
, nX
, nY
);
272 Dvb4PixelsCodeString(spd
, gb
, nX
, nY
);
275 Dvb8PixelsCodeString(spd
, gb
, nX
, nY
);
298 void CompositionObject::Dvb2PixelsCodeString(SubPicDesc
& spd
, CGolombBuffer
& gb
, short& nX
, short& nY
)
301 BYTE nPaletteIndex
= 0;
305 while (!bQuit
&& !gb
.IsEOF()) {
308 bTemp
= (BYTE
)gb
.BitRead(2);
310 nPaletteIndex
= bTemp
;
313 if (gb
.BitRead(1) == 1) { // switch_1
314 nCount
= 3 + (short)gb
.BitRead(3); // run_length_3-9
315 nPaletteIndex
= (BYTE
)gb
.BitRead(2);
317 if (gb
.BitRead(1) == 0) { // switch_2
318 switch (gb
.BitRead(2)) { // switch_3
325 case 2: // if (switch_3 == '10')
326 nCount
= 12 + (short)gb
.BitRead(4); // run_length_12-27
327 nPaletteIndex
= (BYTE
)gb
.BitRead(2); // 4-bit_pixel-code
330 nCount
= 29 + gb
.ReadByte(); // run_length_29-284
331 nPaletteIndex
= (BYTE
)gb
.BitRead(2); // 4-bit_pixel-code
340 if (nX
+ nCount
> m_width
) {
346 FillSolidRect(spd
, nX
, nY
, nCount
, 1, m_Colors
[nPaletteIndex
]);
354 void CompositionObject::Dvb4PixelsCodeString(SubPicDesc
& spd
, CGolombBuffer
& gb
, short& nX
, short& nY
)
357 BYTE nPaletteIndex
= 0;
361 while (!bQuit
&& !gb
.IsEOF()) {
364 bTemp
= (BYTE
)gb
.BitRead(4);
366 nPaletteIndex
= bTemp
;
369 if (gb
.BitRead(1) == 0) { // switch_1
370 nCount
= (short)gb
.BitRead(3); // run_length_3-9
377 if (gb
.BitRead(1) == 0) { // switch_2
378 nCount
= 4 + (short)gb
.BitRead(2); // run_length_4-7
379 nPaletteIndex
= (BYTE
)gb
.BitRead(4); // 4-bit_pixel-code
381 switch (gb
.BitRead(2)) { // switch_3
388 case 2: // if (switch_3 == '10')
389 nCount
= 9 + (short)gb
.BitRead(4); // run_length_9-24
390 nPaletteIndex
= (BYTE
)gb
.BitRead(4); // 4-bit_pixel-code
393 nCount
= 25 + gb
.ReadByte(); // run_length_25-280
394 nPaletteIndex
= (BYTE
)gb
.BitRead(4); // 4-bit_pixel-code
402 if (nX
+ nCount
> m_width
) {
409 FillSolidRect(spd
, nX
, nY
, nCount
, 1, m_Colors
[nPaletteIndex
]);
417 void CompositionObject::Dvb8PixelsCodeString(SubPicDesc
& spd
, CGolombBuffer
& gb
, short& nX
, short& nY
)
420 BYTE nPaletteIndex
= 0;
424 while (!bQuit
&& !gb
.IsEOF()) {
427 bTemp
= gb
.ReadByte();
429 nPaletteIndex
= bTemp
;
432 if (gb
.BitRead(1) == 0) { // switch_1
433 nCount
= (short)gb
.BitRead(7); // run_length_1-127
438 nCount
= (short)gb
.BitRead(7); // run_length_3-127
439 nPaletteIndex
= gb
.ReadByte();
443 if (nX
+ nCount
> m_width
) {
449 FillSolidRect(spd
, nX
, nY
, nCount
, 1, m_Colors
[nPaletteIndex
]);