diff options
45 files changed, 7532 insertions, 6785 deletions
@@ -1,11 +1,11 @@ /* -* dxr3.c: A plugin for the Video Disk Recorder -* -* See the README file for copyright information and how to reach the author. -* -* $Id: dxr3.c,v 1.1.2.9 2005/04/19 06:11:43 scop Exp $ -*/ - + * dxr3.c: A plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + * $Id: dxr3.c,v 1.1.2.10 2005/04/19 18:19:36 scop Exp $ + * + */ #include "dxr3vdrincludes.h" #include "dxr3device.h" @@ -23,180 +23,212 @@ static const char *MAINMENUENTRY = "DXR3"; // ================================== // 'message-handler' for the main screen -eOSState cDxr3OsdItem::ProcessKey(eKeys Key) +eOSState cDxr3OsdItem::ProcessKey(eKeys Key) { - if (Key == kOk) + if (Key == kOk) + { + switch (m_item) { - switch (m_item) - { - case DXR3_RESET_HARDWARE: - cDxr3Interface::Instance().ResetHardware(); - if (cDxr3Device::InstanceP()) - cDxr3Device::InstanceP()->Reset(); - break; - - case DXR3_FORCE_LETTER_BOX: - cDxr3ConfigData::Instance().SetForceLetterBox(!cDxr3ConfigData::Instance().GetForceLetterBox()); - break; - - case DXR3_ANALOG_OUT: - cLog::Instance() << "Changing audio to analog\n"; - cDxr3ConfigData::Instance().SetUseDigitalOut(0); - cDxr3ConfigData::Instance().SetAc3OutPut(0); - if (cDxr3Device::InstanceP()) - cDxr3Device::InstanceP()->Reset(); - break; - - case DXR3_DIGITAL_OUT: - cLog::Instance() << "Changing audio to digital\n"; - cDxr3ConfigData::Instance().SetUseDigitalOut(1); - cDxr3ConfigData::Instance().SetAc3OutPut(0); - if (cDxr3Device::InstanceP()) - cDxr3Device::InstanceP()->Reset(); - break; - - case DXR3_AC3_OUT: - cLog::Instance() << "Changing audio to ac3\n"; - cDxr3ConfigData::Instance().SetAc3OutPut(!cDxr3ConfigData::Instance().GetAc3OutPut()); - if (cDxr3Device::InstanceP()) - cDxr3Device::InstanceP()->Reset(); - break; - } + case DXR3_RESET_HARDWARE: + cDxr3Interface::Instance().ResetHardware(); + if (cDxr3Device::InstanceP()) + cDxr3Device::InstanceP()->Reset(); + break; + + case DXR3_FORCE_LETTER_BOX: + cDxr3ConfigData::Instance().SetForceLetterBox(!cDxr3ConfigData::Instance().GetForceLetterBox()); + break; + + case DXR3_ANALOG_OUT: + cLog::Instance() << "Changing audio to analog\n"; + cDxr3ConfigData::Instance().SetUseDigitalOut(0); + cDxr3ConfigData::Instance().SetAc3OutPut(0); + if (cDxr3Device::InstanceP()) + cDxr3Device::InstanceP()->Reset(); + break; + + case DXR3_DIGITAL_OUT: + cLog::Instance() << "Changing audio to digital\n"; + cDxr3ConfigData::Instance().SetUseDigitalOut(1); + cDxr3ConfigData::Instance().SetAc3OutPut(0); + if (cDxr3Device::InstanceP()) + cDxr3Device::InstanceP()->Reset(); + break; + + case DXR3_AC3_OUT: + cLog::Instance() << "Changing audio to ac3\n"; + cDxr3ConfigData::Instance().SetAc3OutPut(!cDxr3ConfigData::Instance().GetAc3OutPut()); + if (cDxr3Device::InstanceP()) + cDxr3Device::InstanceP()->Reset(); + break; } - - return Key == kOk ? osBack : cOsdItem::ProcessKey(Key); + } + + return Key == kOk ? osBack : cOsdItem::ProcessKey(Key); } // ================================== // setup menu cMenuSetupDxr3::cMenuSetupDxr3(void) { - newUseDigitalOut = cDxr3ConfigData::Instance().GetUseDigitalOut(); - Add(new cMenuEditBoolItem(tr("Digital audio output"), &newUseDigitalOut)); - newDxr3Card = cDxr3ConfigData::Instance().GetDxr3Card(); - Add(new cMenuEditIntItem(tr("Card number"), &newDxr3Card)); - newVideoMode = (int) cDxr3ConfigData::Instance().GetVideoMode(); - menuVideoModes[0] = tr("PAL"); - menuVideoModes[1] = tr("PAL60"); - menuVideoModes[2] = tr("NTSC"); - Add(new cMenuEditStraItem(tr("Video mode"), &newVideoMode, 3, menuVideoModes)); - newDebug = (int) cDxr3ConfigData::Instance().GetDebug(); - Add(new cMenuEditBoolItem(tr("Debug mode"), &newDebug)); - newDebugLevel = (int) cDxr3ConfigData::Instance().GetDebugLevel(); - menuDebugModes[0] = tr("low"); - menuDebugModes[1] = tr("everything"); - Add(new cMenuEditStraItem(tr("Debug level"), &newDebugLevel, 2, menuDebugModes)); + newUseDigitalOut = cDxr3ConfigData::Instance().GetUseDigitalOut(); + Add(new cMenuEditBoolItem(tr("Digital audio output"), &newUseDigitalOut)); + newDxr3Card = cDxr3ConfigData::Instance().GetDxr3Card(); + Add(new cMenuEditIntItem(tr("Card number"), &newDxr3Card)); + newVideoMode = (int) cDxr3ConfigData::Instance().GetVideoMode(); + menuVideoModes[0] = tr("PAL"); + menuVideoModes[1] = tr("PAL60"); + menuVideoModes[2] = tr("NTSC"); + Add(new cMenuEditStraItem(tr("Video mode"), + &newVideoMode, 3, menuVideoModes)); + newDebug = (int) cDxr3ConfigData::Instance().GetDebug(); + Add(new cMenuEditBoolItem(tr("Debug mode"), &newDebug)); + newDebugLevel = (int) cDxr3ConfigData::Instance().GetDebugLevel(); + menuDebugModes[0] = tr("low"); + menuDebugModes[1] = tr("everything"); + Add(new cMenuEditStraItem(tr("Debug level"), + &newDebugLevel, 2, menuDebugModes)); } // ================================== // save menu values void cMenuSetupDxr3::Store(void) -{ - SetupStore("UseDigitalOut", cDxr3ConfigData::Instance().SetUseDigitalOut(newUseDigitalOut)); - SetupStore("Dxr3Card", cDxr3ConfigData::Instance().SetDxr3Card(newDxr3Card)); - SetupStore("Dxr3VideoMode", cDxr3ConfigData::Instance().SetVideoMode((eVideoMode) newVideoMode)); - SetupStore("Dxr3Debug", cDxr3ConfigData::Instance().SetDebug(newDebug)); - SetupStore("Dxr3DebugLevel", cDxr3ConfigData::Instance().SetDebugLevel(newDebugLevel)); +{ + SetupStore("UseDigitalOut", + cDxr3ConfigData::Instance().SetUseDigitalOut(newUseDigitalOut)); + SetupStore("Dxr3Card", + cDxr3ConfigData::Instance().SetDxr3Card(newDxr3Card)); + SetupStore("Dxr3VideoMode", + cDxr3ConfigData::Instance().SetVideoMode((eVideoMode) newVideoMode)); + SetupStore("Dxr3Debug", + cDxr3ConfigData::Instance().SetDebug(newDebug)); + SetupStore("Dxr3DebugLevel", + cDxr3ConfigData::Instance().SetDebugLevel(newDebugLevel)); } // ================================== -class cPluginDxr3 : public cPlugin +class cPluginDxr3 : public cPlugin { private: - // Add any member variables or functions you may need here. + // Add any member variables or functions you may need here. public: - cPluginDxr3(); - ~cPluginDxr3(); - const char *Version() { return VERSION; } - const char *Description() { return tr(DESCRIPTION); } - const char *CommandLineHelp(); - bool ProcessArgs(int argc, char *argv[]); - bool Initialize(); - bool Start(); - void Housekeeping(); - cMenuSetupPage *SetupMenu(); - bool SetupParse(const char *Name, const char *Value); - const char* MainMenuEntry(); - cOsdObject* MainMenuAction(); + cPluginDxr3(); + ~cPluginDxr3(); + const char *Version() + { + return VERSION; + } + const char *Description() + { + return tr(DESCRIPTION); + } + const char *CommandLineHelp(); + bool ProcessArgs(int argc, char *argv[]); + bool Initialize(); + bool Start(); + void Housekeeping(); + cMenuSetupPage *SetupMenu(); + bool SetupParse(const char *Name, const char *Value); + const char* MainMenuEntry(); + cOsdObject* MainMenuAction(); }; // ================================== -cPluginDxr3::cPluginDxr3() +cPluginDxr3::cPluginDxr3() { - // Initialize any member varaiables here. - // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL - // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT! - cDxr3ConfigData::Instance(); + // Initialize any member varaiables here. + // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL + // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT! + cDxr3ConfigData::Instance(); } // ================================== -cPluginDxr3::~cPluginDxr3() +cPluginDxr3::~cPluginDxr3() { } // ================================== -const char *cPluginDxr3::CommandLineHelp() +const char *cPluginDxr3::CommandLineHelp() { - return NULL; + return NULL; } // ================================== -bool cPluginDxr3::ProcessArgs(int argc, char *argv[]) +bool cPluginDxr3::ProcessArgs(int argc, char *argv[]) { - return true; + return true; } // ================================== -bool cPluginDxr3::Start() +bool cPluginDxr3::Start() { return true; } // ================================== -bool cPluginDxr3::Initialize() +bool cPluginDxr3::Initialize() { - RegisterI18n(Phrases); + RegisterI18n(Phrases); - new cDxr3CPU(); - cDxr3Device::InstanceP(); + new cDxr3CPU(); + cDxr3Device::InstanceP(); return true; -} +} -// ================================== -void cPluginDxr3::Housekeeping() +// ================================== +void cPluginDxr3::Housekeeping() { } // ================================== -cMenuSetupPage* cPluginDxr3::SetupMenu() +cMenuSetupPage* cPluginDxr3::SetupMenu() { - return new cMenuSetupDxr3(); + return new cMenuSetupDxr3(); } // ================================== -bool cPluginDxr3::SetupParse(const char *Name, const char *Value) +bool cPluginDxr3::SetupParse(const char *Name, const char *Value) { - // Parse your own setup parameters and store their values. - if (!strcasecmp(Name, "UseDigitalOut")) { cDxr3ConfigData::Instance().SetUseDigitalOut(atoi(Value)); return true; } - if (!strcasecmp(Name, "Dxr3Card")) { cDxr3ConfigData::Instance().SetDxr3Card(atoi(Value)); return true; } - if (!strcasecmp(Name, "Dxr3Debug")) { cDxr3ConfigData::Instance().SetDebug(atoi(Value)); return true; } - if (!strcasecmp(Name, "Dxr3VideoMode")) { cDxr3ConfigData::Instance().SetVideoMode((eVideoMode) atoi(Value)); return true;} - if (!strcasecmp(Name, "Dxr3DebugLevel")) { cDxr3ConfigData::Instance().SetDebugLevel(atoi(Value)); return true;} - - return false; + if (!strcasecmp(Name, "UseDigitalOut")) + { + cDxr3ConfigData::Instance().SetUseDigitalOut(atoi(Value)); + return true; + } + if (!strcasecmp(Name, "Dxr3Card")) + { + cDxr3ConfigData::Instance().SetDxr3Card(atoi(Value)); + return true; + } + if (!strcasecmp(Name, "Dxr3Debug")) + { + cDxr3ConfigData::Instance().SetDebug(atoi(Value)); + return true; + } + if (!strcasecmp(Name, "Dxr3VideoMode")) + { + cDxr3ConfigData::Instance().SetVideoMode((eVideoMode) atoi(Value)); + return true; + } + if (!strcasecmp(Name, "Dxr3DebugLevel")) + { + cDxr3ConfigData::Instance().SetDebugLevel(atoi(Value)); + return true; + } + + return false; } // ================================== -const char* cPluginDxr3::MainMenuEntry() +const char* cPluginDxr3::MainMenuEntry() { - return tr(MAINMENUENTRY); + return tr(MAINMENUENTRY); } // ================================== -cOsdObject* cPluginDxr3::MainMenuAction() +cOsdObject* cPluginDxr3::MainMenuAction() { - return new cDxr3OsdMenu; + return new cDxr3OsdMenu; } VDRPLUGINCREATOR(cPluginDxr3); // Don't touch this! @@ -5,27 +5,27 @@ // ================================== // setup screen -class cMenuSetupDxr3 : public cMenuSetupPage +class cMenuSetupDxr3 : public cMenuSetupPage { public: - cMenuSetupDxr3(); - + cMenuSetupDxr3(); + protected: - virtual void Store(); - + virtual void Store(); + private: - int newUseDigitalOut; - int newDxr3Card; - int newVideoMode; - int newDebug; - int newDebugLevel; - const char *menuVideoModes[3]; - const char *menuDebugModes[2]; + int newUseDigitalOut; + int newDxr3Card; + int newVideoMode; + int newDebug; + int newDebugLevel; + const char *menuVideoModes[3]; + const char *menuDebugModes[2]; }; // ================================== -enum eDxr3OsdItem +enum eDxr3OsdItem { DXR3_RESET_HARDWARE, DXR3_FORCE_LETTER_BOX, @@ -36,60 +36,55 @@ enum eDxr3OsdItem // ================================== // osd item -class cDxr3OsdItem : public cOsdItem +class cDxr3OsdItem : public cOsdItem { -public: - cDxr3OsdItem(const char* text, eDxr3OsdItem item) : cOsdItem(text), m_item(item) {} - - // process fb input +public: + cDxr3OsdItem(const char* text, eDxr3OsdItem item) : + cOsdItem(text), m_item(item) {} + + // process fb input eOSState ProcessKey(eKeys Key); protected: - eDxr3OsdItem m_item; + eDxr3OsdItem m_item; }; // ================================== // main screen -class cDxr3OsdMenu : public cOsdMenu +class cDxr3OsdMenu : public cOsdMenu { public: cDxr3OsdMenu(): cOsdMenu(tr("DXR3 Adjustment")) - { - Clear(); - SetHasHotkeys(); - Add(new cDxr3OsdItem(hk(tr("Reset DXR3 hardware")), DXR3_RESET_HARDWARE)); - Add(new cDxr3OsdItem(hk(tr("Toggle force letterbox")), DXR3_FORCE_LETTER_BOX)); + { + Clear(); + SetHasHotkeys(); + Add(new cDxr3OsdItem(hk(tr("Reset DXR3 hardware")), + DXR3_RESET_HARDWARE)); + Add(new cDxr3OsdItem(hk(tr("Toggle force letterbox")), + DXR3_FORCE_LETTER_BOX)); - if (cDxr3ConfigData::Instance().GetUseDigitalOut()) - { - Add(new cDxr3OsdItem(hk(tr("Switch to analog audio output")), DXR3_ANALOG_OUT)); - } - else - { - Add(new cDxr3OsdItem(hk(tr("Switch to digital audio output")), DXR3_DIGITAL_OUT)); - } -/* - if (cDxr3ConfigData::Instance().GetUseDigitalOut()) - { - Add(new cDxr3OsdItem(hk("Analog output"), DXR3_ANALOG_OUT)); + if (cDxr3ConfigData::Instance().GetUseDigitalOut()) + Add(new cDxr3OsdItem(hk(tr("Switch to analog audio output")), + DXR3_ANALOG_OUT)); + else + Add(new cDxr3OsdItem(hk(tr("Switch to digital audio output")), + DXR3_DIGITAL_OUT)); + /* + if (cDxr3ConfigData::Instance().GetUseDigitalOut()) + { + Add(new cDxr3OsdItem(hk("Analog output"), DXR3_ANALOG_OUT)); - if (cDxr3ConfigData::Instance().GetAc3OutPut()) - { - Add(new cDxr3OsdItem(hk(tr("AC3 output off")), DXR3_AC3_OUT)); - } - else - { - if (cDxr3Interface::Instance().IsAc3Present()) - { - Add(new cDxr3OsdItem(hk(tr("AC3 output on")), DXR3_AC3_OUT)); - } - } - } - else - { - Add(new cDxr3OsdItem(hk(tr("Switch to digital audio output")), DXR3_DIGITAL_OUT)); - } - */ + if (cDxr3ConfigData::Instance().GetAc3OutPut()) + Add(new cDxr3OsdItem(hk(tr("AC3 output off")), DXR3_AC3_OUT)); + else if (cDxr3Interface::Instance().IsAc3Present()) + Add(new cDxr3OsdItem(hk(tr("AC3 output on")), DXR3_AC3_OUT)); + } + else + { + Add(new cDxr3OsdItem(hk(tr("Switch to digital audio output")), + DXR3_DIGITAL_OUT)); + } + */ } }; diff --git a/dxr3audiodecoder.c b/dxr3audiodecoder.c index 19371a2..17ea0fe 100644 --- a/dxr3audiodecoder.c +++ b/dxr3audiodecoder.c @@ -22,11 +22,10 @@ /* -ToDo: - - cDxr3AudioDecoder::Init: Why are we always reinit the codec? + ToDo: + - cDxr3AudioDecoder::Init: Why are we always reinit the codec? */ - #include <stdio.h> #include "dxr3audiodecoder.h" #include "dxr3pesframe.h" @@ -36,12 +35,12 @@ const int LPCM_HEADER_LENGTH = 7; // ================================== //! constructor -cDxr3AudioDecoder::cDxr3AudioDecoder() : rbuf(50000), ac3dtsDecoder(&rbuf) +cDxr3AudioDecoder::cDxr3AudioDecoder() : rbuf(50000), ac3dtsDecoder(&rbuf) { decoderOpened = false; audioSynched = false; volume = 255; - Codec.id = CODEC_ID_MP2; + Codec.id = CODEC_ID_MP2; Init(); @@ -51,245 +50,262 @@ cDxr3AudioDecoder::cDxr3AudioDecoder() : rbuf(50000), ac3dtsDecoder(&rbuf) // ================================== //! deconst. -cDxr3AudioDecoder::~cDxr3AudioDecoder() +cDxr3AudioDecoder::~cDxr3AudioDecoder() { - // close codec, if it is open - cDxr3Ffmepg::Instance().CloseCodec(Codec); + // close codec, if it is open + cDxr3Ffmepg::Instance().CloseCodec(Codec); }; // ================================== //! (re)init ffmpeg codec -void cDxr3AudioDecoder::Init() +void cDxr3AudioDecoder::Init() { - // (re)init codec - cDxr3Ffmepg::Instance().CloseCodec(Codec); - if (cDxr3Ffmepg::Instance().FindCodec(Codec)) - { - cDxr3Ffmepg::Instance().OpenCodec(Codec); - rate = channels = -1; - frameSize = Codec.codec_context.frame_size; - decoderOpened = true; - foundHeader = false; - decodeAudio = true; - - //lastHeader[0] = 0xFF; - //lastHeader[1] = lastHeader[2] = lastHeader[3] = 0; - } - else - { - decoderOpened = false; - } + // (re)init codec + cDxr3Ffmepg::Instance().CloseCodec(Codec); + if (cDxr3Ffmepg::Instance().FindCodec(Codec)) + { + cDxr3Ffmepg::Instance().OpenCodec(Codec); + rate = channels = -1; + frameSize = Codec.codec_context.frame_size; + decoderOpened = true; + foundHeader = false; + decodeAudio = true; + + //lastHeader[0] = 0xFF; + //lastHeader[1] = lastHeader[2] = lastHeader[3] = 0; + } + else + { + decoderOpened = false; + } } // ================================== //! decode given buffer -void cDxr3AudioDecoder::Decode(const uint8_t* buf, int length, uint32_t pts, cDxr3SyncBuffer &aBuf) +void cDxr3AudioDecoder::Decode(const uint8_t* buf, int length, uint32_t pts, + cDxr3SyncBuffer &aBuf) { - if (!decoderOpened) - { - // No decoder is open, so it - // is better to stop here. - return; - } + if (!decoderOpened) + { + // No decoder is open, so it + // is better to stop here. + return; + } int len; int out_size; - enum audioException - { - WRONG_LENGTH, - UNEXPECTED_PARAMETER_CHANGE + enum audioException + { + WRONG_LENGTH, + UNEXPECTED_PARAMETER_CHANGE }; int i = 0; - for (i = 0; i < length-4 && !foundHeader; i++) + for (i = 0; i < length-4 && !foundHeader; i++) + { + unsigned int tempHead = *((unsigned int*)(buf+i)); + if (HeadCheck(tempHead)) { - unsigned int tempHead = *((unsigned int*)(buf+i)); - if (HeadCheck(tempHead)) - { - if ((buf[i+2] & 0xFC) != (lastHeader[2] & 0xFC)) - { - cLog::Instance() << "cDxr3AudioDecoder::Decode Found different audio header -> init\n"; - cLog::Instance() << "cDxr3AudioDecoder::Decode Old header 0x" << std::hex << *((uint32_t*) lastHeader) << " new header 0x" << *((uint32_t*) (buf+i)) << std::dec << "\n"; - - Init(); - lastHeader[0] = buf[i]; - lastHeader[1] = buf[i+1]; - lastHeader[2] = buf[i+2]; - lastHeader[3] = buf[i+3]; - } - foundHeader = true; - } + if ((buf[i+2] & 0xFC) != (lastHeader[2] & 0xFC)) + { + cLog::Instance() << "cDxr3AudioDecoder::Decode Found different audio header -> init\n"; + cLog::Instance() << "cDxr3AudioDecoder::Decode Old header 0x" + << std::hex << *((uint32_t*) lastHeader) + << " new header 0x" << *((uint32_t*) (buf+i)) + << std::dec << "\n"; + + Init(); + lastHeader[0] = buf[i]; + lastHeader[1] = buf[i+1]; + lastHeader[2] = buf[i+2]; + lastHeader[3] = buf[i+3]; + } + foundHeader = true; + } } - if (audioSynched) - { - // no header found - decodeAudio = true; - } - else + if (audioSynched) + { + // no header found + decodeAudio = true; + } + else + { + if (foundHeader && pts) { - if (foundHeader && pts) - { - decodeAudio = true; - audioSynched = true; - } + decodeAudio = true; + audioSynched = true; + } } - try + try + { + while (length > 0 && decodeAudio) { - while (length > 0 && decodeAudio) - { - len = avcodec_decode_audio(&Codec.codec_context, (short *)(&pcmbuf), &out_size, - const_cast<uint8_t *>(buf), length); - if (len < 0 || out_size < 0) throw WRONG_LENGTH; - - if (Codec.codec_context.sample_rate != rate) - { - cLog::Instance() << "cDxr3AudioDecoder::Decode Sample rate = " << Codec.codec_context.sample_rate << "\n"; - if (rate != -1) throw UNEXPECTED_PARAMETER_CHANGE; - rate = Codec.codec_context.sample_rate; - } - if (Codec.codec_context.channels != channels+1 ) - { - if (channels != -1) throw UNEXPECTED_PARAMETER_CHANGE; - channels = (Codec.codec_context.channels == 2) ? 1 : 0; - cLog::Instance() << "cDxr3AudioDecoder::Decode channels = " << Codec.codec_context.channels << "\n"; - } - if (out_size) - { - cFixedLengthFrame* pTempFrame = aBuf.Push(pcmbuf, out_size, pts); - pTempFrame->SetChannelCount(channels); - pTempFrame->SetDataRate(rate); - } - length -= len; - buf += len; - } - } - catch (audioException ex) + len = avcodec_decode_audio(&Codec.codec_context, + (short *)(&pcmbuf), &out_size, + const_cast<uint8_t *>(buf), length); + if (len < 0 || out_size < 0) + throw WRONG_LENGTH; + + if (Codec.codec_context.sample_rate != rate) + { + cLog::Instance() << "cDxr3AudioDecoder::Decode Sample rate = " + << Codec.codec_context.sample_rate << "\n"; + if (rate != -1) throw UNEXPECTED_PARAMETER_CHANGE; + rate = Codec.codec_context.sample_rate; + } + if (Codec.codec_context.channels != channels + 1) + { + if (channels != -1) + throw UNEXPECTED_PARAMETER_CHANGE; + channels = (Codec.codec_context.channels == 2) ? 1 : 0; + cLog::Instance() << "cDxr3AudioDecoder::Decode channels = " + << Codec.codec_context.channels << "\n"; + } + if (out_size) + { + cFixedLengthFrame* pTempFrame = aBuf.Push(pcmbuf, + out_size, pts); + pTempFrame->SetChannelCount(channels); + pTempFrame->SetDataRate(rate); + } + length -= len; + buf += len; + } + } + catch (audioException ex) + { + switch (ex) { - switch (ex) - { - case WRONG_LENGTH: - cLog::Instance() << "cDxr3AudioDecoder::Decode wrong length\n"; - break; - - case UNEXPECTED_PARAMETER_CHANGE: - cLog::Instance() << "cDxr3AudioDecoder::Decode unexpected parameter change\n"; - break; - - default: - cLog::Instance() << "cDxr3AudioDecoder::Decode unexpeced exception\n"; - break; - } - dsyslog("cDxr3AudioDecoder::Decode skipping %d broken data bytes", length); - - Init(); + case WRONG_LENGTH: + cLog::Instance() << "cDxr3AudioDecoder::Decode wrong length\n"; + break; + + case UNEXPECTED_PARAMETER_CHANGE: + cLog::Instance() << "cDxr3AudioDecoder::Decode unexpected parameter change\n"; + break; + + default: + cLog::Instance() << "cDxr3AudioDecoder::Decode unexpeced exception\n"; + break; + } + dsyslog("cDxr3AudioDecoder::Decode skipping %d broken data bytes", + length); + + Init(); } } // ================================== //! decode lpcm -void cDxr3AudioDecoder::DecodeLpcm(const uint8_t* buf, int length, uint32_t pts, cDxr3SyncBuffer &aBuf) +void cDxr3AudioDecoder::DecodeLpcm(const uint8_t* buf, int length, + uint32_t pts, cDxr3SyncBuffer &aBuf) { - if (length > (LPCM_HEADER_LENGTH + 2)) + if (length > (LPCM_HEADER_LENGTH + 2)) + { + uint8_t* pFrame = new uint8_t[length - LPCM_HEADER_LENGTH]; + // only even number of bytes are allowed + assert(!((length - LPCM_HEADER_LENGTH) % 2)); + + for (int i = LPCM_HEADER_LENGTH; i < length; i += 2) { - uint8_t* pFrame = new uint8_t[length - LPCM_HEADER_LENGTH]; - assert(!((length - LPCM_HEADER_LENGTH) % 2)); // only even number of bytes are allowed - - for (int i = LPCM_HEADER_LENGTH; i < length; i += 2) - { - pFrame[i - LPCM_HEADER_LENGTH] = buf[i + 1]; - pFrame[i - LPCM_HEADER_LENGTH + 1] = buf[i]; - } - - int codedSpeed = (buf[5] >> 4) & 0x03; - int speed = 0; - - switch (codedSpeed) - { - case 1: - speed = 96000; - break; - - case 2: - speed = 44100; - break; - - case 3: - speed = 32000; - break; - - default: - speed = 48000; - break; - } - - cFixedLengthFrame* pTempFrame = aBuf.Push(pFrame, length - LPCM_HEADER_LENGTH, pts); - pTempFrame->SetChannelCount(1); - pTempFrame->SetDataRate(speed); - - delete[] pFrame; + pFrame[i - LPCM_HEADER_LENGTH] = buf[i + 1]; + pFrame[i - LPCM_HEADER_LENGTH + 1] = buf[i]; + } + + int codedSpeed = (buf[5] >> 4) & 0x03; + int speed = 0; + + switch (codedSpeed) + { + case 1: + speed = 96000; + break; + + case 2: + speed = 44100; + break; + + case 3: + speed = 32000; + break; + + default: + speed = 48000; + break; + } + + cFixedLengthFrame* pTempFrame = aBuf.Push(pFrame, + length - LPCM_HEADER_LENGTH, + pts); + pTempFrame->SetChannelCount(1); + pTempFrame->SetDataRate(speed); + + delete[] pFrame; } } // ================================== //! decode ac3 -void cDxr3AudioDecoder::DecodeAc3Dts(const uint8_t* pPes, const uint8_t* buf, int length, uint32_t pts, cDxr3SyncBuffer &aBuf) +void cDxr3AudioDecoder::DecodeAc3Dts(const uint8_t* pPes, const uint8_t* buf, + int length, uint32_t pts, + cDxr3SyncBuffer &aBuf) { int headerLength = (int) (buf - pPes); uint8_t* pBuf = (uint8_t*) pPes; ac3dtsDecoder.Check(pBuf + headerLength, length, pBuf); ac3dtsDecoder.Encapsulate(pBuf + headerLength, length); - + cFrame* pFrame = 0; - while ((pFrame = rbuf.Get())) + while ((pFrame = rbuf.Get())) + { + if (pFrame && pFrame->Count()) { - if (pFrame && pFrame->Count()) - { - cDxr3PesFrame tempPes; - tempPes.ExtractNextFrame(pFrame->Data(), pFrame->Count()); - int pesHeaderLength = (int) (tempPes.GetEsStart() - tempPes.GetPesStart()); - uint8_t* pData = pFrame->Data() + pesHeaderLength + LPCM_HEADER_LENGTH; - - for (int i = 0; i < pFrame->Count() - pesHeaderLength - LPCM_HEADER_LENGTH; i += 2) - { - std::swap(pData[i], pData[i + 1]); - } - - aBuf.Push(pFrame->Data() + pesHeaderLength + LPCM_HEADER_LENGTH, pFrame->Count() - pesHeaderLength - 7, tempPes.GetPts()); - if (pFrame) rbuf.Drop(pFrame); - } + cDxr3PesFrame tempPes; + tempPes.ExtractNextFrame(pFrame->Data(), pFrame->Count()); + int pesHeaderLength = (int) (tempPes.GetEsStart() - tempPes.GetPesStart()); + uint8_t* pData = pFrame->Data() + pesHeaderLength + LPCM_HEADER_LENGTH; + + for (int i = 0; i < pFrame->Count() - pesHeaderLength - LPCM_HEADER_LENGTH; i += 2) + { + std::swap(pData[i], pData[i + 1]); + } + + aBuf.Push(pFrame->Data() + pesHeaderLength + LPCM_HEADER_LENGTH, pFrame->Count() - pesHeaderLength - 7, tempPes.GetPts()); + if (pFrame) rbuf.Drop(pFrame); + } } -} +} // ================================== //! checking routine -bool cDxr3AudioDecoder::HeadCheck(unsigned long head) +bool cDxr3AudioDecoder::HeadCheck(unsigned long head) { bool retval = false; - + uint8_t* phead = (uint8_t*) (&head); - if (phead[0] != 0xFF) - { - retval = false; - } - else if (phead[1] != 0xFC && phead[1] != 0xFE) - { - retval = false; - } - else if ((phead[2] & 0xF0) == 0xF0) - { - retval = false; - } - else if ((phead[2] & 0xC) == 0xC) - { - retval = false; + if (phead[0] != 0xFF) + { + retval = false; } - else - { - retval = true; + else if (phead[1] != 0xFC && phead[1] != 0xFE) + { + retval = false; + } + else if ((phead[2] & 0xF0) == 0xF0) + { + retval = false; + } + else if ((phead[2] & 0xC) == 0xC) + { + retval = false; + } + else + { + retval = true; } return retval; diff --git a/dxr3audiodecoder.h b/dxr3audiodecoder.h index 7d575d3..33bde7b 100644 --- a/dxr3audiodecoder.h +++ b/dxr3audiodecoder.h @@ -33,31 +33,47 @@ // ================================== // decode audio to mp2 or use DD :) -class cDxr3AudioDecoder +class cDxr3AudioDecoder { public: cDxr3AudioDecoder(); ~cDxr3AudioDecoder(); - void Init(void); // init in const? + void Init(void); // init in const? - void Decode(const uint8_t* buf, int length, uint32_t pts, cDxr3SyncBuffer &aBuf); - void DecodeLpcm(const uint8_t* buf, int length, uint32_t pts, cDxr3SyncBuffer &aBuf); - void DecodeAc3Dts(const uint8_t* pPes, const uint8_t* buf, int length, uint32_t pts, cDxr3SyncBuffer &aBuf); + void Decode(const uint8_t* buf, int length, uint32_t pts, + cDxr3SyncBuffer &aBuf); + void DecodeLpcm(const uint8_t* buf, int length, uint32_t pts, + cDxr3SyncBuffer &aBuf); + void DecodeAc3Dts(const uint8_t* pPes, const uint8_t* buf, int length, + uint32_t pts, cDxr3SyncBuffer &aBuf); + + int GetRate(void) const + { + return rate; + } + int GetChannelCount(void) const + { + return channels; + } + int GetFrameSize(void) const + { + return frameSize; + } + void Reset(void) + { + ac3dtsDecoder.Clear(); + rbuf.Clear(); + } - int GetRate(void) const { return rate; } - int GetChannelCount(void) const { return channels; } - int GetFrameSize(void) const { return frameSize; } - void Reset(void) { ac3dtsDecoder.Clear(); rbuf.Clear(); } - private: bool HeadCheck(unsigned long head); - - struct Dxr3Codec Codec; + + struct Dxr3Codec Codec; cRingBufferFrame rbuf; cMultichannelAudio ac3dtsDecoder; - + bool audioSynched; bool decoderOpened; uint8_t lastHeader[4]; diff --git a/dxr3blackframe.c b/dxr3blackframe.c index 33344cf..639ba96 100644 --- a/dxr3blackframe.c +++ b/dxr3blackframe.c @@ -21,1267 +21,1268 @@ // ================================== //! used when channel gets switched -char blackframe[] = - -{ 0x0, 0x0, 0x1, 0xb3, 0x2d, 0x2, 0x40, 0x23, 0x24, 0x9f, 0x23, 0x82, 0x10, 0x20, 0x20, 0x26, -0x20, 0x26, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x34, 0x30, 0x34, 0x36, 0x36, 0x36, 0x34, -0x34, 0x34, 0x34, 0x36, 0x36, 0x36, 0x3a, 0x3a, 0x3a, 0x44, 0x44, 0x44, 0x3a, 0x3a, 0x3a, -0x36, 0x36, 0x3a, 0x3a, 0x40, 0x40, 0x44, 0x44, 0x4a, 0x4c, 0x4a, 0x46, 0x46, 0x44, 0x46, -0x4c, 0x4c, 0x50, 0x50, 0x50, 0x60, 0x60, 0x5c, 0x5c, 0x70, 0x70, 0x74, 0x8a, 0x8a, 0xa7, -0x10, 0x11, 0x11, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x14, -0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, -0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, 0x18, 0x19, 0x18, 0x18, 0x18, 0x19, 0x1a, -0x1a, 0x1a, 0x1a, 0x19, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c, 0x1c, 0x1c, 0x1e, 0x1e, -0x1e, 0x1f, 0x1f, 0x21, 0x0, 0x0, 0x1, 0xb5, 0x14, 0x82, 0x0, 0x1, 0x0, 0x0, 0x0, -0x0, 0x1, 0xb8, 0x5a, 0x9, 0xc4, 0x80, 0x0, 0x0, 0x1, 0x0, 0x0, 0x4b, 0x9, 0xb0, -0x0, 0x0, 0x1, 0xb5, 0x8f, 0xff, 0xf7, 0x98, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0xb, 0x7e, -0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, -0x30, 0xd4, 0x28, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, -0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, -0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, -0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, -0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, -0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, -0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, -0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, -0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, -0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, -0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, -0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, -0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, -0x68, 0xc3, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x13, 0x7e, 0x1f, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, -0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, -0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, -0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, -0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, -0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, -0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, -0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, -0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, -0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, -0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, -0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, -0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, -0x3, 0x13, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, -0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, -0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, -0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, -0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, -0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, -0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, -0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, -0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, -0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, -0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, -0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, -0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xa8, 0x31, 0xa3, 0x46, 0x8c, 0x30, 0xda, -0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, -0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x4, 0x13, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, -0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, -0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, -0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, -0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, -0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, -0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, -0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, -0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, -0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, -0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1a, 0x83, 0x1a, 0x34, -0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, -0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, -0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, -0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xc, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x1, 0x5, 0x13, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, -0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, -0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, -0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, -0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x35, 0x6, 0x34, 0x68, 0xd1, 0x86, -0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, -0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, -0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, -0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, -0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, -0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, -0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, -0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, -0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, -0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xc, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x6, 0x13, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, -0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, -0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, -0x34, 0x68, 0xc3, 0xd, 0x41, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, -0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, -0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, -0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, -0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, -0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, -0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, -0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, -0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, -0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x62, 0xb5, 0x4e, 0x81, -0x2a, 0x5, 0x46, 0x18, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x1, 0x7, 0xb, 0xfe, 0x1f, 0x3, 0x4d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, -0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, -0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, -0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, -0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, -0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, -0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, -0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, -0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, -0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, -0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, -0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, -0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x8, 0xb, -0x7e, 0x1f, 0x68, 0xd0, 0x94, 0x48, 0xf5, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, -0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, -0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, -0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, -0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, -0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, -0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, -0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, -0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, -0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, -0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, -0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, -0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, -0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, -0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, -0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, -0x86, 0xd1, 0xa3, 0x46, 0x21, 0xea, 0x31, 0x6, 0x97, 0x54, 0x85, 0x18, 0x61, 0x80, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x9, -0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, -0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, -0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, -0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, -0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, -0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, -0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, -0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, -0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, -0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, -0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, -0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, -0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, -0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, -0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, -0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, -0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xa, 0xb, 0xfe, 0x1f, 0x3, 0x4d, 0x1a, -0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, -0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, -0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, -0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, -0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, -0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, -0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, -0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, -0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, -0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, -0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, -0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, -0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, -0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x60, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xb, 0xb, 0x7e, -0x1f, 0x68, 0xd0, 0x94, 0x48, 0xf5, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, -0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, -0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, -0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, -0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, -0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, -0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, -0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, -0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, -0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, -0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, -0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, -0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xc, 0xb, -0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, -0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, -0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, -0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, -0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, -0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, -0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, -0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, -0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, -0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, -0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, -0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, -0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x1, 0xd, 0xb, 0xfe, 0x1f, 0x3, 0x4d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, -0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, -0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, -0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, -0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, -0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, -0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, -0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, -0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, -0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, -0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, -0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, -0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, -0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, -0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, -0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, -0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xe, 0xb, 0x7e, 0x1f, -0x68, 0xd0, 0x94, 0x48, 0xf5, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, -0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, -0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, -0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, -0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, -0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, -0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, -0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, -0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, -0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, -0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, -0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, -0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, -0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, -0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, -0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, -0xa3, 0x46, 0x8c, 0x30, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xf, 0xb, 0x7e, 0x1f, -0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, -0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, -0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, -0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, -0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, -0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, -0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, -0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, -0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, -0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, -0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, -0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, -0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, -0x10, 0xb, 0xfe, 0x1f, 0x3, 0x4d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, -0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, -0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, -0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, -0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, -0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, -0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, -0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, -0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, -0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, -0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, -0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, -0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x1, 0x11, 0xb, 0x7e, 0x1f, 0x68, 0xd0, 0x94, 0x48, 0xf5, 0x68, 0xc3, -0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, -0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, -0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, -0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, -0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, -0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, -0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, -0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, -0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, -0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, -0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, -0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, -0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, -0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xc0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x1, 0x12, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, -0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, -0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, -0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, -0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, -0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, -0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, -0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, -0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, -0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, -0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, -0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, -0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, -0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, -0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x13, 0xb, -0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, -0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, -0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, -0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, -0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, -0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, -0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, -0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, -0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, -0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, -0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, -0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, -0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x1, 0x14, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, -0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, -0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, -0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, -0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, -0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, -0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, -0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, -0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, -0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, -0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, -0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, -0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, -0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, -0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x1, 0x15, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, -0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, -0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, -0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, -0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, -0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, -0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, -0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, -0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, -0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, -0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, -0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, -0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, -0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, -0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x1, 0x16, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, -0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, -0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, -0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, -0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, -0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, -0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, -0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, -0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, -0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, -0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, -0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, -0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, -0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, -0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x17, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, -0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, -0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, -0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, -0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, -0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, -0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, -0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, -0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, -0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, -0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, -0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, -0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, -0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, -0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, -0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, -0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x1, 0x18, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, -0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, -0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, -0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, -0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, -0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, -0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, -0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, -0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, -0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, -0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, -0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, -0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, -0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, -0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x19, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, -0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, -0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, -0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, -0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, -0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, -0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, -0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, -0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, -0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, -0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, -0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, -0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, -0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, -0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, -0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, -0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x1, 0x1a, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, -0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, -0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, -0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, -0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, -0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, -0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, -0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, -0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, -0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, -0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, -0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, -0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, -0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, -0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1b, 0xb, 0x7e, 0x1f, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, -0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, -0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, -0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, -0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, -0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, -0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, -0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, -0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, -0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, -0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, -0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, -0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1c, 0xb, -0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, -0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, -0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, -0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, -0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, -0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, -0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, -0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, -0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, -0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, -0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, -0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, -0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x1, 0x1d, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, -0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, -0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, -0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, -0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, -0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, -0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, -0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, -0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, -0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, -0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, -0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, -0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, -0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, -0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x1, 0x1e, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, -0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, -0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, -0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, -0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, -0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, -0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, -0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, -0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, -0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, -0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, -0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, -0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, -0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, -0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, -0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, -0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x1, 0x1f, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, -0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, -0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, -0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, -0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, -0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, -0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, -0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, -0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, -0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, -0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, -0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, -0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, -0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, -0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0xb, 0xfe, 0x1f, 0x68, 0xd1, 0xa3, -0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, -0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, -0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, -0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, -0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, -0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, -0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, -0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, -0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, -0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, -0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, -0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, -0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, -0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, -0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, -0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x21, 0xb, 0x7e, 0x1f, -0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, -0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, -0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, -0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, -0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, -0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, -0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, -0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, -0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, -0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, -0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, -0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, -0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x22, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, -0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, -0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, -0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, -0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, -0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, -0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, -0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, -0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, -0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, -0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, -0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, -0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, -0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, -0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, -0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, -0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x1, 0x23, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, -0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, -0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, -0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, -0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, -0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, -0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, -0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, -0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, -0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, -0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, -0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, -0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, -0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, -0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x24, 0xb, 0x7e, 0x1f, 0x68, 0xd1, -0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, -0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, -0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, -0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, -0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, -0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, -0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, -0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, -0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, -0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, -0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, -0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, -0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, -0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, -0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, -0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, -0x0, 0x0, 0x0, 0x0, 0x0 }; +char blackframe[] = +{ +0x0, 0x0, 0x1, 0xb3, 0x2d, 0x2, 0x40, 0x23, 0x24, 0x9f, 0x23, 0x82, 0x10, 0x20, 0x20, 0x26, +0x20, 0x26, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x34, 0x30, 0x34, 0x36, 0x36, 0x36, 0x34, +0x34, 0x34, 0x34, 0x36, 0x36, 0x36, 0x3a, 0x3a, 0x3a, 0x44, 0x44, 0x44, 0x3a, 0x3a, 0x3a, +0x36, 0x36, 0x3a, 0x3a, 0x40, 0x40, 0x44, 0x44, 0x4a, 0x4c, 0x4a, 0x46, 0x46, 0x44, 0x46, +0x4c, 0x4c, 0x50, 0x50, 0x50, 0x60, 0x60, 0x5c, 0x5c, 0x70, 0x70, 0x74, 0x8a, 0x8a, 0xa7, +0x10, 0x11, 0x11, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x14, +0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, +0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, 0x18, 0x19, 0x18, 0x18, 0x18, 0x19, 0x1a, +0x1a, 0x1a, 0x1a, 0x19, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c, 0x1c, 0x1c, 0x1e, 0x1e, +0x1e, 0x1f, 0x1f, 0x21, 0x0, 0x0, 0x1, 0xb5, 0x14, 0x82, 0x0, 0x1, 0x0, 0x0, 0x0, +0x0, 0x1, 0xb8, 0x5a, 0x9, 0xc4, 0x80, 0x0, 0x0, 0x1, 0x0, 0x0, 0x4b, 0x9, 0xb0, +0x0, 0x0, 0x1, 0xb5, 0x8f, 0xff, 0xf7, 0x98, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0xb, 0x7e, +0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, +0x30, 0xd4, 0x28, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, +0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, +0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, +0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, +0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, +0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, +0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, +0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, +0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, +0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, +0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, +0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, +0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, +0x68, 0xc3, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x13, 0x7e, 0x1f, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, +0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, +0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, +0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, +0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, +0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, +0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, +0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, +0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, +0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, +0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, +0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, +0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, +0x3, 0x13, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, +0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, +0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, +0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, +0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, +0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, +0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, +0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, +0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, +0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, +0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, +0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, +0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xa8, 0x31, 0xa3, 0x46, 0x8c, 0x30, 0xda, +0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, +0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x4, 0x13, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, +0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, +0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, +0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, +0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, +0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, +0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, +0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, +0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, +0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, +0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1a, 0x83, 0x1a, 0x34, +0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, +0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, +0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, +0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xc, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x1, 0x5, 0x13, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, +0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, +0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, +0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, +0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x35, 0x6, 0x34, 0x68, 0xd1, 0x86, +0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, +0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, +0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, +0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, +0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, +0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, +0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, +0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, +0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, +0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xc, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x6, 0x13, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, +0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, +0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, +0x34, 0x68, 0xc3, 0xd, 0x41, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, +0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, +0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, +0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, +0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, +0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, +0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, +0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, +0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, +0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x62, 0xb5, 0x4e, 0x81, +0x2a, 0x5, 0x46, 0x18, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x1, 0x7, 0xb, 0xfe, 0x1f, 0x3, 0x4d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, +0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, +0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, +0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, +0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, +0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, +0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, +0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, +0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, +0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, +0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, +0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, +0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x8, 0xb, +0x7e, 0x1f, 0x68, 0xd0, 0x94, 0x48, 0xf5, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, +0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, +0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, +0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, +0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, +0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, +0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, +0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, +0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, +0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, +0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, +0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, +0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, +0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, +0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, +0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, +0x86, 0xd1, 0xa3, 0x46, 0x21, 0xea, 0x31, 0x6, 0x97, 0x54, 0x85, 0x18, 0x61, 0x80, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x9, +0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, +0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, +0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, +0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, +0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, +0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, +0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, +0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, +0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, +0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, +0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, +0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, +0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, +0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, +0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, +0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, +0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xa, 0xb, 0xfe, 0x1f, 0x3, 0x4d, 0x1a, +0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, +0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, +0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, +0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, +0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, +0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, +0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, +0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, +0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, +0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, +0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, +0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, +0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, +0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x60, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xb, 0xb, 0x7e, +0x1f, 0x68, 0xd0, 0x94, 0x48, 0xf5, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, +0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, +0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, +0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, +0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, +0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, +0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, +0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, +0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, +0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, +0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, +0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, +0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xc, 0xb, +0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, +0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, +0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, +0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, +0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, +0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, +0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, +0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, +0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, +0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, +0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, +0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, +0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x1, 0xd, 0xb, 0xfe, 0x1f, 0x3, 0x4d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, +0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, +0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, +0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, +0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, +0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, +0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, +0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, +0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, +0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, +0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, +0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, +0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, +0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, +0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, +0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, +0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xe, 0xb, 0x7e, 0x1f, +0x68, 0xd0, 0x94, 0x48, 0xf5, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, +0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, +0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, +0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, +0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, +0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, +0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, +0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, +0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, +0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, +0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, +0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, +0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, +0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, +0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, +0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, +0xa3, 0x46, 0x8c, 0x30, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xf, 0xb, 0x7e, 0x1f, +0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, +0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, +0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, +0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, +0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, +0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, +0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, +0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, +0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, +0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, +0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, +0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, +0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, +0x10, 0xb, 0xfe, 0x1f, 0x3, 0x4d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, +0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, +0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, +0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, +0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, +0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, +0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, +0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, +0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, +0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, +0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, +0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, +0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x1, 0x11, 0xb, 0x7e, 0x1f, 0x68, 0xd0, 0x94, 0x48, 0xf5, 0x68, 0xc3, +0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, +0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, +0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, +0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, +0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, +0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, +0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, +0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, +0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, +0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, +0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, +0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, +0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, +0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xc0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x1, 0x12, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, +0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, +0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, +0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, +0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, +0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, +0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, +0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, +0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, +0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, +0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, +0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, +0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, +0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, +0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x13, 0xb, +0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, +0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, +0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, +0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, +0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, +0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, +0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, +0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, +0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, +0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, +0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, +0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, +0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x1, 0x14, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, +0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, +0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, +0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, +0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, +0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, +0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, +0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, +0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, +0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, +0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, +0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, +0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, +0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, +0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x1, 0x15, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, +0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, +0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, +0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, +0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, +0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, +0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, +0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, +0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, +0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, +0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, +0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, +0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, +0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, +0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x1, 0x16, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, +0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, +0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, +0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, +0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, +0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, +0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, +0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, +0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, +0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, +0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, +0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, +0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, +0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, +0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x17, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, +0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, +0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, +0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, +0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, +0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, +0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, +0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, +0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, +0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, +0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, +0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, +0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, +0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, +0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, +0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, +0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x1, 0x18, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, +0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, +0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, +0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, +0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, +0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, +0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, +0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, +0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, +0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, +0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, +0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, +0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, +0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, +0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x19, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, +0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, +0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, +0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, +0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, +0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, +0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, +0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, +0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, +0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, +0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, +0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, +0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, +0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, +0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, +0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, +0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x1, 0x1a, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, +0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, +0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, +0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, +0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, +0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, +0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, +0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, +0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, +0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, +0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, +0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, +0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, +0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, +0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1b, 0xb, 0x7e, 0x1f, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, +0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, +0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, +0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, +0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, +0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, +0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, +0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, +0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, +0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, +0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, +0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, +0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1c, 0xb, +0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, +0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, +0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, +0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, +0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, +0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, +0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, +0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, +0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, +0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, +0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, +0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, +0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x1, 0x1d, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, +0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, +0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, +0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, +0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, +0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, +0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, +0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, +0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, +0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, +0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, +0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, +0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, +0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, +0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x1, 0x1e, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, +0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, +0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, +0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, +0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, +0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, +0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, +0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, +0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, +0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, +0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, +0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, +0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, +0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, +0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, +0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, +0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x1, 0x1f, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, +0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, +0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, +0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, +0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, +0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, +0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, +0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, +0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, +0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, +0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, +0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, +0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, +0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, +0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0xb, 0xfe, 0x1f, 0x68, 0xd1, 0xa3, +0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, +0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, +0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, +0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, +0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, +0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, +0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, +0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, +0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, +0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, +0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, +0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, +0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, +0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, +0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, +0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x21, 0xb, 0x7e, 0x1f, +0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, +0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, +0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, +0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, +0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, +0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, +0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, +0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, +0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, +0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, +0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, +0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, +0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x22, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, +0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, +0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, +0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, +0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, +0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, +0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, +0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, +0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, +0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, +0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, +0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, +0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, +0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, +0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, +0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, +0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x1, 0x23, 0xb, 0x7e, 0x1f, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, +0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, +0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, +0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, +0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, +0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, +0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, +0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, +0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, +0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, +0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, +0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, +0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, +0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, +0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x24, 0xb, 0x7e, 0x1f, 0x68, 0xd1, +0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, +0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, +0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, +0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, +0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, +0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, +0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, +0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, +0xd, 0xa3, 0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, +0x61, 0x86, 0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, +0x1a, 0x30, 0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, +0x46, 0x8d, 0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, +0xd1, 0xa3, 0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, +0xc3, 0x68, 0xd1, 0xa3, 0x46, 0x18, 0x6d, 0x1a, 0x34, 0x68, 0xc3, 0xd, 0xa3, 0x46, 0x8d, +0x18, 0x61, 0xb4, 0x68, 0xd1, 0xa3, 0xc, 0x36, 0x8d, 0x1a, 0x34, 0x61, 0x86, 0xd1, 0xa3, +0x46, 0x8c, 0x30, 0xda, 0x34, 0x68, 0xd1, 0x86, 0x1b, 0x46, 0x8d, 0x1a, 0x30, 0xc3, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0 +}; int blackframeLength = sizeof(blackframe); diff --git a/dxr3colormanager.c b/dxr3colormanager.c index 1ddca35..1e40711 100644 --- a/dxr3colormanager.c +++ b/dxr3colormanager.c @@ -60,166 +60,189 @@ //! constructor cColorManager::cColorManager() { - NrOfRegions = -1; - for(int i = 0; i < MAX_NO_OF_REGIONS; i++) - hlr[i] = NULL; + NrOfRegions = -1; + for(int i = 0; i < MAX_NO_OF_REGIONS; i++) + hlr[i] = NULL; } // ================================== cColorManager::~cColorManager() { - for (int i = 0; i < NrOfRegions; i++) + for (int i = 0; i < NrOfRegions; i++) + { + if (hlr[i]) { - if (hlr[i]) - { - delete(hlr[i]); - } + delete(hlr[i]); } + } } // ================================== // Opens a new highlight region void cColorManager::OpenRegion(int y) { - // Calling method (cColorManager::EncodeColors) - // already checks MAX_NO_OF_REGIONS - curRegion = new yRegion(); - curRegion->Y1 = y; - NrOfRegions++; - hlr[NrOfRegions] = curRegion; - NewSection(0); //there's always at least a section + // Calling method (cColorManager::EncodeColors) + // already checks MAX_NO_OF_REGIONS + curRegion = new yRegion(); + curRegion->Y1 = y; + NrOfRegions++; + hlr[NrOfRegions] = curRegion; + NewSection(0); //there's always at least a section } // ================================== // Closes the spu-highlight region void cColorManager::CloseRegion(int y) { - curRegion->Y2 = y; + curRegion->Y2 = y; } -// ================================== -void cColorManager::EncodeColors(int width, int height, unsigned char* map, unsigned char* dmap) +// ================================== +void cColorManager::EncodeColors(int width, int height, unsigned char* map, + unsigned char* dmap) { unsigned char color; - unsigned char oldcolor=0xFF; + unsigned char oldcolor = 0xFF; unsigned char ColorIndex; - int mapoffset=0; + int mapoffset = 0; OpenRegion(0); - for (int y = 0; y < height; ++y) { - oldcolor=0xFF; - FirstSection(); - for(int x = 0; x < width; ++x) { - if(x>curSection->X2) { - oldcolor=0xFF; - NextSection(); - } - color = map[mapoffset + x]; - if (color==oldcolor) dmap[mapoffset + x]=ColorIndex; else { - //try to map the color in the current region - if (AddColor(x,y,color, ColorIndex)) { - // store as the highlight region index - dmap[mapoffset + x]=ColorIndex; - } else { - CloseRegion(y-1); - if(NrOfRegions<=MAX_NO_OF_REGIONS-1) { - //retry with another region - OpenRegion(y); - x = -1; - oldcolor=0xFF; - } else - { - //give up - cLog::Instance() << "dxr3colormanager: too many regions!\n"; - return; - } - } - } - } - mapoffset+=width; + for (int y = 0; y < height; ++y) + { + oldcolor = 0xFF; + FirstSection(); + for(int x = 0; x < width; ++x) + { + if (x > curSection->X2) + { + oldcolor = 0xFF; + NextSection(); + } + color = map[mapoffset + x]; + if (color == oldcolor) + dmap[mapoffset + x] = ColorIndex; + else + { + // try to map the color in the current region + if (AddColor(x, y, color, ColorIndex)) + { + // store as the highlight region index + dmap[mapoffset + x] = ColorIndex; + } + else + { + CloseRegion(y - 1); + if (NrOfRegions <= MAX_NO_OF_REGIONS - 1) + { + // retry with another region + OpenRegion(y); + x = -1; + oldcolor = 0xFF; + } + else + { + // give up + cLog::Instance() << "dxr3colormanager: too many regions!\n"; + return; + } + } + } + } + mapoffset += width; } - //close the last highligt region + // close the last highlight region CloseRegion(height); -//#define colordebug -#ifdef colordebug - { - FILE *fp; - fp = fopen("OSD.dump","w+"); - u_char *pippo=dmap; - u_char *pippo2=map; - int curregion=0; - int cursection=0; - - - for (int dumpy=0; dumpy<height; dumpy++) - { - if(curregion<NrOfRegions) { - if(hlr[curregion]->Y1==dumpy) { - fprintf(fp,"%i",hlr[curregion]->N); - for(int sec=0; sec<hlr[curregion]->N; sec++) fprintf(fp,",%i",hlr[curregion]->Section[sec]->X1); - for(int dumpx=0; dumpx<width; dumpx++) fprintf(fp,"="); - fprintf(fp,"\n"); - curregion++; - } - } - - cursection=0; - for(int dumpx=0; dumpx<width; dumpx++) { - if(curregion<NrOfRegions) { - if(cursection<hlr[curregion]->N) { - if(hlr[curregion]->Section[cursection]->X1==dumpx) { - fprintf(fp,"|"); - cursection++; - } - } - } - fprintf(fp,"%01X",*pippo2 & 0xF); - pippo2++; - } - fprintf(fp,"\n"); - - - cursection=0; - for(int dumpx=0; dumpx<width; dumpx++) { - if(curregion<NrOfRegions) { - if(cursection<hlr[curregion]->N) { - if(hlr[curregion]->Section[cursection]->X1==dumpx) { - fprintf(fp,"|"); - cursection++; - } - } - } - fprintf(fp,"%01X",*pippo & 0xF); - pippo++; - } - fprintf(fp,"\n"); - } - fclose(fp); - printf("**** dumped\n"); +//#define colordebug +#ifdef colordebug + { + FILE *fp; + fp = fopen("OSD.dump","w+"); + u_char *pippo = dmap; + u_char *pippo2 = map; + int curregion = 0; + int cursection = 0; + + + for (int dumpy = 0; dumpy < height; dumpy++) + { + if(curregion < NrOfRegions) + { + if(hlr[curregion]->Y1 == dumpy) + { + fprintf(fp, "%i", hlr[curregion]->N); + for (int sec = 0; sec < hlr[curregion]->N; sec++) + fprintf(fp, ",%i", hlr[curregion]->Section[sec]->X1); + for (int dumpx = 0; dumpx < width; dumpx++) + fprintf(fp, "="); + fprintf(fp, "\n"); + curregion++; + } + } + + cursection = 0; + for (int dumpx = 0; dumpx < width; dumpx++) + { + if (curregion < NrOfRegions) + { + if (cursection < hlr[curregion]->N) + { + if (hlr[curregion]->Section[cursection]->X1 == dumpx) + { + fprintf(fp, "|"); + cursection++; + } + } + } + fprintf(fp, "%01X", *pippo2 & 0xF); + pippo2++; + } + fprintf(fp, "\n"); + + cursection = 0; + for (int dumpx = 0; dumpx < width; dumpx++) + { + if(curregion < NrOfRegions) + { + if (cursection < hlr[curregion]->N) + { + if (hlr[curregion]->Section[cursection]->X1 == dumpx) + { + fprintf(fp, "|"); + cursection++; + } + } + } + fprintf(fp, "%01X", *pippo & 0xF); + pippo++; + } + fprintf(fp, "\n"); + } + fclose(fp); + printf("**** dumped\n"); } #endif - } // ================================== -unsigned char cColorManager::AddColor(int x, int y, unsigned char color, unsigned char &ColorIndex) { - - if (!curSection->HasColor(color, ColorIndex)) - { - // this color is new for this section - if (curSection->AllColorsUsed()) - { - // no more free colors - if (y != curRegion->Y1) - { - // terminate region - return(0); - } - NewSection(x); - } - // and add new color - ColorIndex = curSection->AddColor(color); +unsigned char cColorManager::AddColor(int x, int y, unsigned char color, + unsigned char &ColorIndex) { + + if (!curSection->HasColor(color, ColorIndex)) + { + // this color is new for this section + if (curSection->AllColorsUsed()) + { + // no more free colors + if (y != curRegion->Y1) + { + // terminate region + return(0); + } + NewSection(x); + } + // and add new color + ColorIndex = curSection->AddColor(color); } return(1); } @@ -227,27 +250,28 @@ unsigned char cColorManager::AddColor(int x, int y, unsigned char color, unsigne // ================================== void cColorManager::FirstSection(void) { - curSectionIndex=0; - curSection=curRegion->Section[0]; + curSectionIndex = 0; + curSection = curRegion->Section[0]; } // ================================== void cColorManager::NextSection(void) { curSectionIndex++; - if(curSectionIndex<curRegion->N) curSection=curRegion->Section[curSectionIndex]; - //it shouldn't happen + if (curSectionIndex < curRegion->N) + curSection=curRegion->Section[curSectionIndex]; + // it shouldn't happen else cLog::Instance() << - "dxr3colormanager: no more sections in NextSection!\n"; + "dxr3colormanager: no more sections in NextSection!\n"; } // ================================== // convert into SPU - hope is correct description unsigned char* cColorManager::GetSpuData(int& len) { - if (NrOfRegions >= 0) + if (NrOfRegions >= 0) { - int ptr = 0; + int ptr = 0; spudata[ptr++] = 0x07; // CHG_COLCON command spudata[ptr++] = 0x00; // total size of parameter area spudata[ptr++] = 0x00; // will be filled later @@ -255,21 +279,21 @@ unsigned char* cColorManager::GetSpuData(int& len) for(int i = 0; i <= NrOfRegions;i++) { - spudata[ptr++] = (hlr[i]->Y1 >> 8) & 0x0f; - spudata[ptr++] = (hlr[i]->Y1 & 0xff); - spudata[ptr++] = ( ( (hlr[i]->N) & 0x0f) << 4) | ((hlr[i]->Y2 >> 8) & 0x0f); - spudata[ptr++] = (hlr[i]->Y2 & 0xff); - - for(int c = 0; c < hlr[i]->N; c++) - { - spudata[ptr++] = hlr[i]->Section[c]->X1 >> 8; - spudata[ptr++] = hlr[i]->Section[c]->X1 & 0xff; - spudata[ptr++] = (hlr[i]->Section[c]->Colors[3] << 4) | (hlr[i]->Section[c]->Colors[2] & 0x0F); - spudata[ptr++] = (hlr[i]->Section[c]->Colors[1] << 4) | (hlr[i]->Section[c]->Colors[0] & 0x0F); - - spudata[ptr++] = (hlr[i]->Section[c]->Opac[3] << 4) | hlr[i]->Section[c]->Opac[2]; - spudata[ptr++] = (hlr[i]->Section[c]->Opac[1] << 4) | hlr[i]->Section[c]->Opac[0]; - } + spudata[ptr++] = (hlr[i]->Y1 >> 8) & 0x0f; + spudata[ptr++] = (hlr[i]->Y1 & 0xff); + spudata[ptr++] = (((hlr[i]->N) & 0x0f) << 4) | ((hlr[i]->Y2 >> 8) & 0x0f); + spudata[ptr++] = (hlr[i]->Y2 & 0xff); + + for(int c = 0; c < hlr[i]->N; c++) + { + spudata[ptr++] = hlr[i]->Section[c]->X1 >> 8; + spudata[ptr++] = hlr[i]->Section[c]->X1 & 0xff; + spudata[ptr++] = (hlr[i]->Section[c]->Colors[3] << 4) | (hlr[i]->Section[c]->Colors[2] & 0x0F); + spudata[ptr++] = (hlr[i]->Section[c]->Colors[1] << 4) | (hlr[i]->Section[c]->Colors[0] & 0x0F); + + spudata[ptr++] = (hlr[i]->Section[c]->Opac[3] << 4) | hlr[i]->Section[c]->Opac[2]; + spudata[ptr++] = (hlr[i]->Section[c]->Opac[1] << 4) | hlr[i]->Section[c]->Opac[0]; + } } spudata[ptr++] = 0x0f; // termination of parameter block spudata[ptr++] = 0xff; @@ -282,34 +306,37 @@ unsigned char* cColorManager::GetSpuData(int& len) len = ptr; } else - len = 0; + { + len = 0; + } #if OSD_SPU_CM_DUMP - FILE *fp; - fp = fopen("CM.dump","a+"); - fprintf(fp,"len:%03d ",len); + FILE *fp; + fp = fopen("CM.dump", "a+"); + fprintf(fp, "len:%03d ", len); for (int i = 0; i < len; i++) - fprintf(fp,"%02X",*(spudata+i)); - fprintf(fp,"\n"); + fprintf(fp, "%02X", *(spudata + i)); + fprintf(fp, "\n"); fclose(fp); #endif - return(spudata); + return(spudata); } // ================================== void cColorManager::NewSection(int x) { int N = curRegion->N; - if (N>=MAX_NO_OF_SECTIONS-1) { - cLog::Instance() << "dxr3colormanager: bummer, too many sections\n"; - return; //reuse last section, not optimal but there's no other way out - } + if (N >= MAX_NO_OF_SECTIONS - 1) { + cLog::Instance() << "dxr3colormanager: bummer, too many sections\n"; + return; // reuse last section, not optimal but there's no other way out + } curSection = new xSection(x); curRegion->Section[N] = curSection; - if (N > 0) curRegion->Section[N-1]->X2 = x-1; + if (N > 0) + curRegion->Section[N-1]->X2 = x - 1; (curRegion->N)++; - curSectionIndex=N; + curSectionIndex = N; } // ================================== @@ -320,22 +347,22 @@ xSection::xSection(int x) NrOfColors = 0; for (int i = 0; i < 4; i++) { - Opac[i] = 0xFF; - Colors[i] = 0; + Opac[i] = 0xFF; + Colors[i] = 0; } } // ================================== unsigned char xSection::AddColor(unsigned int color) { - unsigned char ColorIndex = 0; + unsigned char ColorIndex = 0; - if (NrOfColors <= 3) + if (NrOfColors <= 3) { - Colors[NrOfColors] = color; - Opac[NrOfColors] = color >> 4; - ColorIndex = NrOfColors; - NrOfColors++; + Colors[NrOfColors] = color; + Opac[NrOfColors] = color >> 4; + ColorIndex = NrOfColors; + NrOfColors++; } return(ColorIndex); } @@ -343,13 +370,13 @@ unsigned char xSection::AddColor(unsigned int color) // ================================== bool xSection::HasColor(unsigned int color, unsigned char &ColorIndex) { - for(int i = 0; i < NrOfColors; i++) + for(int i = 0; i < NrOfColors; i++) { - if (Colors[i] == color) - { - ColorIndex = i; - return (true); - } + if (Colors[i] == color) + { + ColorIndex = i; + return (true); + } } return(false); } diff --git a/dxr3colormanager.h b/dxr3colormanager.h index ea05a0c..e21888e 100644 --- a/dxr3colormanager.h +++ b/dxr3colormanager.h @@ -21,97 +21,102 @@ // ================================== struct rectangular_area { - rectangular_area() : m_startrow(0), m_endrow(0), m_startcol(0), m_endcol(0) {} + rectangular_area() : + m_startrow(0), m_endrow(0), m_startcol(0), m_endcol(0) {} private: - size_t m_startrow; - size_t m_endrow; - size_t m_startcol; - size_t m_endcol; + size_t m_startrow; + size_t m_endrow; + size_t m_startcol; + size_t m_endcol; - unsigned int Colors[4]; - unsigned int Opac[4]; + unsigned int Colors[4]; + unsigned int Opac[4]; } - - - */ - - /**SPU-ColorManager - *@author Stefan Schluenss -*/ + *@author Stefan Schluenss + */ #include <stdio.h> #define OSD_SPU_CM_DUMP 0 -#define MAX_NO_OF_SECTIONS 15 -#define MAX_NO_OF_REGIONS 100 +#define MAX_NO_OF_SECTIONS 15 +#define MAX_NO_OF_REGIONS 100 // ================================== class xSection { public: - xSection(int x); + xSection(int x); bool HasColor(unsigned int color, unsigned char &ColorIndex); unsigned char AddColor(unsigned int color); - bool AllColorsUsed() {/*DIAG("AllColorsUsed: %d\n",NrOfColors)*/;if(NrOfColors >= 4) return(true); else return (false); }; - int X1; - int X2; + bool AllColorsUsed() { + //DIAG("AllColorsUsed: %d\n",NrOfColors); + if(NrOfColors >= 4) + return (true); + else + return (false); + }; + int X1; + int X2; int NrOfColors; - unsigned int Colors[4]; - unsigned int Opac[4]; + unsigned int Colors[4]; + unsigned int Opac[4]; }; // ================================== class yRegion { public: - yRegion(): Y1(0), Y2(0), N(0) {} + yRegion() : Y1(0), Y2(0), N(0) {} - /** No descriptions */ - void AddSection(int first, int last, unsigned int color, unsigned int opac); - int Y1; - int Y2; - int N; + /** No descriptions */ + void AddSection(int first, int last, unsigned int color, + unsigned int opac); + int Y1; + int Y2; + int N; - xSection* Section[MAX_NO_OF_SECTIONS]; + xSection* Section[MAX_NO_OF_SECTIONS]; }; // ================================== class cColorManager { public: - cColorManager(); - ~cColorManager(); - - void EncodeColors(int width, int height, unsigned char* smap, unsigned char* dmap); - - /** Sets a new color on the OSD */ - unsigned char AddColor(int x, int y, unsigned char color, unsigned char &ColorIndex); - - /** encodes the color information as highlight spu data*/ - unsigned char* GetSpuData(int &len); - -private: // Private attributes - yRegion *hlr[MAX_NO_OF_REGIONS]; - yRegion *curRegion; - int NrOfRegions; - unsigned char spudata[(4+6*MAX_NO_OF_SECTIONS)*MAX_NO_OF_REGIONS+7]; - xSection *curSection; - int curSectionIndex; - - /** Opens a new highlight region */ - void OpenRegion(int y); - /** Closes the spu-highlight region */ - void CloseRegion(int y); - - void NewSection(int x); - void FirstSection(void); - void NextSection(void); + cColorManager(); + ~cColorManager(); + + void EncodeColors(int width, int height, unsigned char* smap, + unsigned char* dmap); + + /** Sets a new color on the OSD */ + unsigned char AddColor(int x, int y, unsigned char color, + unsigned char &ColorIndex); + + /** Encodes the color information as highlight spu data */ + unsigned char* GetSpuData(int &len); + +private: + yRegion *hlr[MAX_NO_OF_REGIONS]; + yRegion *curRegion; + int NrOfRegions; + unsigned char spudata[(4+6*MAX_NO_OF_SECTIONS)*MAX_NO_OF_REGIONS+7]; + xSection *curSection; + int curSectionIndex; + + /** Opens a new highlight region */ + void OpenRegion(int y); + /** Closes the spu-highlight region */ + void CloseRegion(int y); + + void NewSection(int x); + void FirstSection(void); + void NextSection(void); }; #endif /*_DXR3COLORMANAGER_H_*/ diff --git a/dxr3configdata.c b/dxr3configdata.c index e3763db..1a77687 100644 --- a/dxr3configdata.c +++ b/dxr3configdata.c @@ -24,19 +24,19 @@ // ================================== //! constructor -cDxr3ConfigData::cDxr3ConfigData() +cDxr3ConfigData::cDxr3ConfigData() { - m_digitaloutput = 0; - m_ac3output = 0; - m_card = 0; - m_forceletterbox = 0; + m_digitaloutput = 0; + m_ac3output = 0; + m_card = 0; + m_forceletterbox = 0; m_videomode = PAL; - m_menumode = SUBPICTURE; - m_debug = 1; - m_debuglevel = 0; - m_brightness = 500; - m_contrast = 500; - m_saturation = 500; + m_menumode = SUBPICTURE; + m_debug = 1; + m_debuglevel = 0; + m_brightness = 500; + m_contrast = 500; + m_saturation = 500; } // Local variables: diff --git a/dxr3configdata.h b/dxr3configdata.h index 894c3fb..3ee4e37 100644 --- a/dxr3configdata.h +++ b/dxr3configdata.h @@ -27,84 +27,159 @@ // ================================== //! possible video modes -enum eVideoMode +enum eVideoMode { - PAL = 0, ///< use PAL as videomode - PAL60, ///< use PAL60 as videomode - NTSC ///< use NTSC as videomode -}; + PAL = 0, ///< use PAL as videomode + PAL60, ///< use PAL60 as videomode + NTSC ///< use NTSC as videomode +}; // ================================== // possible menu modes -enum eMenuMode +enum eMenuMode { - SUBPICTURE = 0, + SUBPICTURE = 0, MPEG -}; +}; // ================================== //! possible debug levels enum eDebugLevel { - LOW = 0, ///< only log basic warings and errors - EVERYTHING ///< log everything - note logfile can become very big + LOW = 0, ///< only log basic warings and errors + EVERYTHING ///< log everything - note logfile can become very big }; // ================================== //! global interface to access all config datas of this plugin /* - With this singleton you can access very easy all possible - config settings of the plugin. + With this singleton you can access very easy all possible + config settings of the plugin. */ class cDxr3ConfigData : public Singleton<cDxr3ConfigData> { public: cDxr3ConfigData(); - ~cDxr3ConfigData() {} + ~cDxr3ConfigData() {} - int GetUseDigitalOut() const { return m_digitaloutput; } - int SetUseDigitalOut(int value) { return m_digitaloutput = value; } - int GetDxr3Card() const { return m_card; } - int SetDxr3Card(int value) { return m_card = value; } - int GetForceLetterBox() const { return m_forceletterbox; } - int SetForceLetterBox(int value) { return m_forceletterbox = value; } - int GetAc3OutPut() const { return m_ac3output; } - int SetAc3OutPut(int value) { return m_ac3output = value;} + int GetUseDigitalOut() const + { + return m_digitaloutput; + } + int SetUseDigitalOut(int value) + { + return m_digitaloutput = value; + } + int GetDxr3Card() const + { + return m_card; + } + int SetDxr3Card(int value) + { + return m_card = value; + } + int GetForceLetterBox() const + { + return m_forceletterbox; + } + int SetForceLetterBox(int value) + { + return m_forceletterbox = value; + } + int GetAc3OutPut() const + { + return m_ac3output; + } + int SetAc3OutPut(int value) + { + return m_ac3output = value; + } - eVideoMode GetVideoMode() const { return m_videomode;} - eVideoMode SetVideoMode(eVideoMode videoMode) { return m_videomode = videoMode;} - eMenuMode GetMenuMode() const { return m_menumode; } - eMenuMode SetMenuMode(eMenuMode menuMode) { return m_menumode = menuMode; } + eVideoMode GetVideoMode() const + { + return m_videomode; + } + eVideoMode SetVideoMode(eVideoMode videoMode) + { + return m_videomode = videoMode; + } + eMenuMode GetMenuMode() const + { + return m_menumode; + } + eMenuMode SetMenuMode(eMenuMode menuMode) + { + return m_menumode = menuMode; + } - int GetDebug() const { return m_debug; } - int SetDebug(int value) { return m_debug = value; } - int GetDebugLevel() const { return m_debuglevel; } - int SetDebugLevel(int value) { return m_debuglevel = value; } + int GetDebug() const + { + return m_debug; + } + int SetDebug(int value) + { + return m_debug = value; + } + int GetDebugLevel() const + { + return m_debuglevel; + } + int SetDebugLevel(int value) + { + return m_debuglevel = value; + } - // some little helpers to save some writing - int GetDebugLow() const { return (m_debug && !m_debuglevel); } - int GetDebugEverything() const { if (m_debug && !m_debuglevel) { return 1; } else { return 0; } } + // some little helpers to save some writing + int GetDebugLow() const + { + return (m_debug && !m_debuglevel); + } + int GetDebugEverything() const + { + if (m_debug && !m_debuglevel) + return 1; + else + return 0; + } - int GetBrightness() const { return m_brightness; } - int SetBrightness(int value) { return m_brightness = value; } - int GetContrast() const { return m_contrast; } - int SetContrast(int value) { return m_contrast = value; } - int GetSaturation() const { return m_saturation; } - int SetSaturation(int value) { return m_saturation = value; } + int GetBrightness() const + { + return m_brightness; + } + int SetBrightness(int value) + { + return m_brightness = value; + } + int GetContrast() const + { + return m_contrast; + } + int SetContrast(int value) + { + return m_contrast = value; + } + int GetSaturation() const + { + return m_saturation; + } + int SetSaturation(int value) + { + return m_saturation = value; + } protected: - eVideoMode m_videomode; - eMenuMode m_menumode; + eVideoMode m_videomode; + eMenuMode m_menumode; - int m_digitaloutput; - int m_ac3output; - int m_card; - int m_forceletterbox; - int m_debug; - int m_debuglevel; - int m_brightness; - int m_contrast; - int m_saturation; + int m_digitaloutput; + int m_ac3output; + int m_card; + int m_forceletterbox; + int m_debug; + int m_debuglevel; + int m_brightness; + int m_contrast; + int m_saturation; }; #endif /*_DXR3_CONFIGDATA_H_*/ @@ -29,111 +29,113 @@ //! constructor cDxr3CPU::cDxr3CPU() { - unsigned long eax,ebx,edx,unused; - - // readout the vendor - Cpuid(0,eax,ebx,unused,edx); - - // set Vendor to "" - memset(m_Info.Vendor, 0, 16); - - // connect the single register values to the vendor string - // maybe there is an better solution - i will google :) - *(unsigned long *)(m_Info.Vendor) = ebx; - *(unsigned long *)(m_Info.Vendor + 4) = edx; - *(unsigned long *)(m_Info.Vendor + 8) = unused; - - // check the features - // could we get the needed infos? - if (Cpuid(1,eax,ebx,unused,edx)) + unsigned long eax, ebx, edx, unused; + + // readout the vendor + Cpuid(0, eax, ebx, unused, edx); + + // set Vendor to "" + memset(m_Info.Vendor, 0, 16); + + // connect the single register values to the vendor string + // maybe there is an better solution - i will google :) + *(unsigned long *)(m_Info.Vendor) = ebx; + *(unsigned long *)(m_Info.Vendor + 4) = edx; + *(unsigned long *)(m_Info.Vendor + 8) = unused; + + // check the features + // could we get the needed infos? + if (Cpuid(1, eax, ebx, unused, edx)) + { + m_Info.MMX = ((edx & 1<<23) != 0); + m_Info.SSE = ((edx & 1<<25) != 0); + m_Info.SSE2 = ((edx & 1<<26) != 0); + m_Info.RDTSC = ((edx & 1<<4) != 0); /*0x10*/ + m_Info.HT = ((edx & 1<<28) !=0 ); // need additional checks? + + // 3DNow is a litle bit harder to read out + // We read the ext. CPUID level 0x80000000 + if (Cpuid(0x80000000, eax, ebx, unused, edx)) { - m_Info.MMX = ((edx & 1<<23) != 0); - m_Info.SSE = ((edx & 1<<25) != 0); - m_Info.SSE2= ((edx & 1<<26) != 0); - m_Info.RDTSC=((edx & 1<<4) != 0); /*0x10*/ - m_Info.HT = ((edx & 1<<28) !=0); // should we do here addinonal checks? - - // 3DNow is a litle bit harder to read out - // We read the ext. CPUID level 0x80000000 - if (Cpuid(0x80000000,eax,ebx,unused,edx)) + // now in eax there is the max. supported extended CPUID level + // we check if theres an extended CPUID level support + if (eax >= 0x80000001) + { + // If we can access the extended CPUID level 0x80000001 we + // get the edx register + if (Cpuid(0x80000001, eax, ebx, unused, edx)) { - // now in eax there is the max. supported extended CPUID level - // we check if theres an extended CPUID level support - if (eax >= 0x80000001) - { - // If we can access the extended CPUID level 0x80000001 we get the - // edx register - if (Cpuid(0x80000001,eax,ebx,unused,edx)) - { - // Now we can mask some AMD specific cpu extensions - // 22 ... Extended MMX_MultimediaExtensions - m_Info.MMXEXT = ((edx & 1<<22) != 0); - m_Info.AMD64Bit = ((edx & 1<<29) != 0); - // 30 ... Extended 3DNOW_InstructionExtensions - m_Info.Now = ((edx & (1<<31)) != 0); - } - } + // Now we can mask some AMD specific cpu extensions + // 22 ... Extended MMX_MultimediaExtensions + m_Info.MMXEXT = ((edx & 1<<22) != 0); + m_Info.AMD64Bit = ((edx & 1<<29) != 0); + // 30 ... Extended 3DNOW_InstructionExtensions + m_Info.Now = ((edx & 1<<31) != 0); } + } } + } - // MPlayer, Xine-lib, Transcode: SSE implies MMXEXT - m_Info.MMXEXT = m_Info.MMXEXT || m_Info.SSE; + // MPlayer, Xine-lib, Transcode: SSE implies MMXEXT + m_Info.MMXEXT = m_Info.MMXEXT || m_Info.SSE; - // fill cabs - if (m_Info.MMX) - { - m_Info.caps |= CC_MMX; - } + // fill cabs + if (m_Info.MMX) + { + m_Info.caps |= CC_MMX; + } - if (m_Info.MMXEXT) - { - m_Info.caps |= CC_MMXEXT; - } + if (m_Info.MMXEXT) + { + m_Info.caps |= CC_MMXEXT; + } - if (m_Info.SSE) - { - m_Info.caps |= CC_SSE; - } + if (m_Info.SSE) + { + m_Info.caps |= CC_SSE; + } - if (m_Info.Now) - { - m_Info.caps |= CC_3DNOW; - } + if (m_Info.Now) + { + m_Info.caps |= CC_3DNOW; + } + + // print some infos about cpu + cLog::Instance() << "cpu vendor: " << m_Info.Vendor << "\n"; + cLog::Instance() << "cpu extensions:\n"; + cLog::Instance() << "mmx: " << m_Info.MMX << "\n"; + cLog::Instance() << "mmx-ext: " << m_Info.MMXEXT << "\n"; + cLog::Instance() << "sse: " << m_Info.SSE << "\n"; + cLog::Instance() << "sse2: " << m_Info.SSE2 << "\n"; + cLog::Instance() << "3dnow: " << m_Info.Now << "\n"; - // print some infos about cpu - cLog::Instance() << "cpu vendor: " << m_Info.Vendor << "\n"; - cLog::Instance() << "cpu extensions:\n"; - cLog::Instance() << "mmx: " << m_Info.MMX << "\n"; - cLog::Instance() << "mmx-ext: " << m_Info.MMXEXT << "\n"; - cLog::Instance() << "sse: " << m_Info.SSE << "\n"; - cLog::Instance() << "sse2: " << m_Info.SSE2 << "\n"; - cLog::Instance() << "3dnow: " << m_Info.Now << "\n"; - - // now we select the best memcpy mehtode - cDxr3MemcpyBench Benchmark(m_Info.caps); + // now we select the best memcpy mehtode + cDxr3MemcpyBench Benchmark(m_Info.caps); } // ================================== //! does the cpu support cpuid instructions bool cDxr3CPU::CheckCPUIDPresence() { - // todo - return true; + // todo + return true; } // ================================== //! cpuid function -bool cDxr3CPU::Cpuid(unsigned long function, unsigned long& out_eax, unsigned long& out_ebx, unsigned long& out_ecx, unsigned long& out_edx) +bool cDxr3CPU::Cpuid(unsigned long function, unsigned long& out_eax, + unsigned long& out_ebx, unsigned long& out_ecx, + unsigned long& out_edx) { - // This works with PIC/non-PIC, from ffmpeg (libavcodec/i386/cputest.c) - __asm __volatile \ - ("movl %%ebx, %%esi\n\t" \ - "cpuid\n\t" \ - "xchgl %%ebx, %%esi" \ - : "=a" (out_eax), "=S" (out_ebx), \ - "=c" (out_ecx), "=d" (out_edx) \ - : "0" (function)); - return true; + // This works with PIC/non-PIC, from ffmpeg (libavcodec/i386/cputest.c) + __asm __volatile \ + ("movl %%ebx, %%esi\n\t" \ + "cpuid\n\t" \ + "xchgl %%ebx, %%esi" \ + : "=a" (out_eax), "=S" (out_ebx), \ + "=c" (out_ecx), "=d" (out_edx) \ + : "0" (function)); + return true; } // Local variables: @@ -31,76 +31,99 @@ //! all possible cabs enum Cpu_cabs { - CC_MMX = 0x80000000, ///< Value for mmx - CC_3DNOW = 0x40000000, ///< Value for 3dnow - CC_MMXEXT = 0x20000000, ///< Value for mmx ext - CC_SSE = 0x10000000, ///< Value for sse - CC_SSE2 = 0x08000000 ///< Value for sse2 + CC_MMX = 0x80000000, ///< Value for mmx + CC_3DNOW = 0x40000000, ///< Value for 3dnow + CC_MMXEXT = 0x20000000, ///< Value for mmx ext + CC_SSE = 0x10000000, ///< Value for sse + CC_SSE2 = 0x08000000 ///< Value for sse2 }; // ================================== //! easy and fast access to all infos struct CPUInformation { - CPUInformation() - { - AMD = false; - INTEL = false; - MMX = false; - MMXEXT = false; - SSE = false; - SSE2 = false; - Now = false; - RDTSC = false; - HT = false; - AMD64Bit = false; - } - - char Vendor[16]; ///< vendorname - - bool AMD; ///< is it an AMD CPU? - bool INTEL; ///< is it an Intel CPU? - bool MMX; ///< is MMX-Technology supported? - bool MMXEXT; ///< are Extended MMX_MultimediaExtensions supported? - bool SSE; ///< is SSE-Technology supported? - bool SSE2; ///< is SSE2-Technology supported? - bool Now; ///< is 3DNow-Technology supported? - bool RDTSC; ///< is RDTSC-Technology supported? - bool HT; ///< is HyperThreading supported? - bool AMD64Bit; ///< is it a 64 bit machine? + CPUInformation() + { + AMD = false; + INTEL = false; + MMX = false; + MMXEXT = false; + SSE = false; + SSE2 = false; + Now = false; + RDTSC = false; + HT = false; + AMD64Bit = false; + } - uint32_t caps; ///< all features represanted as caps + char Vendor[16]; ///< vendorname + + bool AMD; ///< is it an AMD CPU? + bool INTEL; ///< is it an Intel CPU? + bool MMX; ///< is MMX-Technology supported? + bool MMXEXT; ///< is Extended MMX supported? + bool SSE; ///< is SSE-Technology supported? + bool SSE2; ///< is SSE2-Technology supported? + bool Now; ///< is 3DNow-Technology supported? + bool RDTSC; ///< is RDTSC-Technology supported? + bool HT; ///< is HyperThreading supported? + bool AMD64Bit; ///< is it a 64 bit machine? + + uint32_t caps; ///< all features represanted as caps }; // ================================== //! Grab some infos about the cpu(s) /*! - If you want to know what the cpu of the - target machine can do, this class is for you :) - It is used intern for the math and memcpy part. + If you want to know what the cpu of the + target machine can do, this class is for you :) + It is used intern for the math and memcpy part. */ class cDxr3CPU : public Singleton<cDxr3CPU> { public: - cDxr3CPU(); - ~cDxr3CPU() {} - - bool HasMMXSupport() const { return m_Info.MMX; } - bool HasSSESupport() const { return m_Info.SSE; } - bool HasSSE2Support() const { return m_Info.SSE2; } - bool Has3DNowSupport() const { return m_Info.Now; } - bool HasRDTSCSupport() const { return m_Info.RDTSC; } - bool HasHTSupport() const { return m_Info.HT; } - - inline CPUInformation GetInfos() const { return m_Info ;} - + cDxr3CPU(); + ~cDxr3CPU() {} + + bool HasMMXSupport() const + { + return m_Info.MMX; + } + bool HasSSESupport() const + { + return m_Info.SSE; + } + bool HasSSE2Support() const + { + return m_Info.SSE2; + } + bool Has3DNowSupport() const + { + return m_Info.Now; + } + bool HasRDTSCSupport() const + { + return m_Info.RDTSC; + } + bool HasHTSupport() const + { + return m_Info.HT; + } + + inline CPUInformation GetInfos() const + { + return m_Info; + } + private: - bool CheckCPUIDPresence(); + bool CheckCPUIDPresence(); + + // main function to get cpu(s) features + bool Cpuid(unsigned long function, unsigned long& out_eax, + unsigned long& out_ebx, unsigned long& out_ecx, + unsigned long& out_edx); - // main function to get cpu(s) features - bool Cpuid(unsigned long function, unsigned long& out_eax, unsigned long& out_ebx, unsigned long& out_ecx, unsigned long& out_edx); - - CPUInformation m_Info; + CPUInformation m_Info; }; #endif /*_DXR3_CPU_H_*/ diff --git a/dxr3demuxdevice.c b/dxr3demuxdevice.c index 72433ec..81eeea6 100644 --- a/dxr3demuxdevice.c +++ b/dxr3demuxdevice.c @@ -33,36 +33,36 @@ // ================================== //! constructor cDxr3DemuxDevice::cDxr3DemuxDevice(cDxr3Interface& dxr3Device) : -m_dxr3Device(dxr3Device), -m_aBuf(AUDIO_MAX_BUFFER_SIZE, AUIDO_MAX_FRAME_SIZE, m_dxr3Device), -m_vBuf(VIDEO_MAX_BUFFER_SIZE, VIDEO_MAX_FRAME_SIZE, m_dxr3Device) + m_dxr3Device(dxr3Device), + m_aBuf(AUDIO_MAX_BUFFER_SIZE, AUIDO_MAX_FRAME_SIZE, m_dxr3Device), + m_vBuf(VIDEO_MAX_BUFFER_SIZE, VIDEO_MAX_FRAME_SIZE, m_dxr3Device) { - m_ReUseFrame = 1; + m_ReUseFrame = 1; m_synchState = DXR3_DEMUX_UNSYNCHED; m_demuxMode = DXR3_DEMUX_OFF_MODE; m_pAudioThread = new cDxr3AudioOutThread(dxr3Device, m_aBuf); - if (!m_pAudioThread) - { - cLog::Instance() << "cDxr3DemuxDevice::cDxr3DemuxDevice: failed to allocate memory\n"; - exit(1); - } + if (!m_pAudioThread) + { + cLog::Instance() << "cDxr3DemuxDevice::cDxr3DemuxDevice: failed to allocate memory\n"; + exit(1); + } m_pAudioThread->Start(); m_pVideoThread = new cDxr3VideoOutThread(dxr3Device, m_vBuf); - if (!m_pVideoThread) - { - cLog::Instance() << "cDxr3DemuxDevice::cDxr3DemuxDevice: failed to allocate memory\n"; - exit(1); - } + if (!m_pVideoThread) + { + cLog::Instance() << "cDxr3DemuxDevice::cDxr3DemuxDevice: failed to allocate memory\n"; + exit(1); + } m_pVideoThread->Start(); m_aDecoder.Init(); } // ================================== cDxr3DemuxDevice::cDxr3DemuxDevice() : // dummy constructor -m_dxr3Device(cDxr3Interface::Instance()), -m_aBuf(AUDIO_MAX_BUFFER_SIZE, AUIDO_MAX_FRAME_SIZE, m_dxr3Device), -m_vBuf(VIDEO_MAX_BUFFER_SIZE, VIDEO_MAX_FRAME_SIZE, m_dxr3Device) + m_dxr3Device(cDxr3Interface::Instance()), + m_aBuf(AUDIO_MAX_BUFFER_SIZE, AUIDO_MAX_FRAME_SIZE, m_dxr3Device), + m_vBuf(VIDEO_MAX_BUFFER_SIZE, VIDEO_MAX_FRAME_SIZE, m_dxr3Device) { m_synchState = DXR3_DEMUX_UNSYNCHED; m_demuxMode = DXR3_DEMUX_OFF_MODE; @@ -70,22 +70,22 @@ m_vBuf(VIDEO_MAX_BUFFER_SIZE, VIDEO_MAX_FRAME_SIZE, m_dxr3Device) // ================================== // deconstr. -cDxr3DemuxDevice::~cDxr3DemuxDevice() +cDxr3DemuxDevice::~cDxr3DemuxDevice() { - if (m_pVideoThread) - { - delete m_pVideoThread; - } + if (m_pVideoThread) + { + delete m_pVideoThread; + } - if (m_pAudioThread) - { - delete m_pAudioThread; - } + if (m_pAudioThread) + { + delete m_pAudioThread; + } } // ================================== // stop demuxing process -void cDxr3DemuxDevice::Stop() +void cDxr3DemuxDevice::Stop() { m_dxr3Device.DisableVideo(); m_dxr3Device.DisableAudio(); @@ -100,11 +100,11 @@ void cDxr3DemuxDevice::Stop() m_demuxMode = DXR3_DEMUX_OFF_MODE; m_dxr3Device.PlayBlackFrame(); - m_dxr3Device.ReOpenAudio(); + m_dxr3Device.ReOpenAudio(); } // ================================== -void cDxr3DemuxDevice::Resync() +void cDxr3DemuxDevice::Resync() { m_dxr3Device.DisableVideo(); m_dxr3Device.DisableAudio(); @@ -120,7 +120,7 @@ void cDxr3DemuxDevice::Resync() } // ================================== -void cDxr3DemuxDevice::Clear() +void cDxr3DemuxDevice::Clear() { m_dxr3Device.DisableVideo(); m_dxr3Device.DisableAudio(); @@ -136,7 +136,7 @@ void cDxr3DemuxDevice::Clear() } // ================================== -void cDxr3DemuxDevice::Init() +void cDxr3DemuxDevice::Init() { m_vBuf.Clear(); m_aBuf.Clear(); @@ -146,7 +146,7 @@ void cDxr3DemuxDevice::Init() } // ================================== -void cDxr3DemuxDevice::SetTvMode() +void cDxr3DemuxDevice::SetTvMode() { m_synchState = DXR3_DEMUX_UNSYNCHED; m_demuxMode = DXR3_DEMUX_TV_MODE; @@ -157,7 +157,7 @@ void cDxr3DemuxDevice::SetTvMode() } // ================================== -void cDxr3DemuxDevice::SetAudioOnlyMode() +void cDxr3DemuxDevice::SetAudioOnlyMode() { m_synchState = DXR3_DEMUX_UNSYNCHED; m_demuxMode = DXR3_DEMUX_AUDIO_ONLY_MODE; @@ -165,89 +165,90 @@ void cDxr3DemuxDevice::SetAudioOnlyMode() m_vBuf.SetDemuxMode(DXR3_DEMUX_REPLAY_MODE); m_aBuf.Start(); m_vBuf.Start(); -} +} // ================================== -void cDxr3DemuxDevice::SetReplayMode() +void cDxr3DemuxDevice::SetReplayMode() { - if (m_demuxMode != DXR3_DEMUX_REPLAY_MODE) + if (m_demuxMode != DXR3_DEMUX_REPLAY_MODE) + { + if (m_demuxMode == DXR3_DEMUX_TRICK_MODE && + m_trickState == DXR3_FREEZE) { - if (m_demuxMode == DXR3_DEMUX_TRICK_MODE && m_trickState == DXR3_FREEZE) - { - m_dxr3Device.SetPlayMode(); - m_dxr3Device.SetSysClock(m_stopScr); - m_dxr3Device.EnableVideo(); - m_dxr3Device.EnableAudio(); - m_vBuf.Start(); - m_aBuf.Start(); - m_vBuf.WakeUp(); - m_aBuf.WakeUp(); - } - else - { - m_synchState = DXR3_DEMUX_UNSYNCHED; - m_aBuf.SetDemuxMode(DXR3_DEMUX_REPLAY_MODE); - m_vBuf.SetDemuxMode(DXR3_DEMUX_REPLAY_MODE); - } + m_dxr3Device.SetPlayMode(); + m_dxr3Device.SetSysClock(m_stopScr); + m_dxr3Device.EnableVideo(); + m_dxr3Device.EnableAudio(); + m_vBuf.Start(); + m_aBuf.Start(); + m_vBuf.WakeUp(); + m_aBuf.WakeUp(); + } + else + { + m_synchState = DXR3_DEMUX_UNSYNCHED; + m_aBuf.SetDemuxMode(DXR3_DEMUX_REPLAY_MODE); + m_vBuf.SetDemuxMode(DXR3_DEMUX_REPLAY_MODE); + } } m_demuxMode = DXR3_DEMUX_REPLAY_MODE; } // ================================== -void cDxr3DemuxDevice::SetTrickMode(eDxr3TrickState trickState, int Speed) +void cDxr3DemuxDevice::SetTrickMode(eDxr3TrickState trickState, int Speed) { m_demuxMode = DXR3_DEMUX_TRICK_MODE; m_trickState = trickState; m_dxr3Device.DisableAudio(); - if (m_demuxMode == DXR3_DEMUX_TRICK_MODE && m_trickState == DXR3_FREEZE) - { - m_stopScr = m_dxr3Device.GetSysClock(); - // m_dxr3Device.Pause(); - m_vBuf.Stop(); - m_aBuf.Stop(); + if (m_demuxMode == DXR3_DEMUX_TRICK_MODE && + m_trickState == DXR3_FREEZE) + { + m_stopScr = m_dxr3Device.GetSysClock(); + // m_dxr3Device.Pause(); + m_vBuf.Stop(); + m_aBuf.Stop(); } - else - { - m_vBuf.Clear(); - m_aBuf.Clear(); + else + { + m_vBuf.Clear(); + m_aBuf.Clear(); } - m_ReUseFrame = 1;//Speed; + m_ReUseFrame = 1;//Speed; } // ================================== -void cDxr3DemuxDevice::SetVideoOnlyMode() +void cDxr3DemuxDevice::SetVideoOnlyMode() { m_demuxMode = DXR3_DEMUX_VIDEO_ONLY_MODE; m_dxr3Device.DisableAudio(); - - if (m_demuxMode == DXR3_DEMUX_TRICK_MODE && m_trickState == DXR3_FREEZE) - { - m_stopScr = m_dxr3Device.GetSysClock(); - // m_dxr3Device.Pause(); - m_vBuf.Stop(); - m_aBuf.Stop(); - } - else - { - m_vBuf.Clear(); - m_aBuf.Clear(); + + if (m_demuxMode == DXR3_DEMUX_TRICK_MODE && m_trickState == DXR3_FREEZE) + { + m_stopScr = m_dxr3Device.GetSysClock(); + // m_dxr3Device.Pause(); + m_vBuf.Stop(); + m_aBuf.Stop(); + } + else + { + m_vBuf.Clear(); + m_aBuf.Clear(); } m_dxr3Device.SetPlayMode(); - } #if VDRVERSNUM < 10307 // ================================== -cOsdBase* cDxr3DemuxDevice::NewOsd(int x, int y) +cOsdBase* cDxr3DemuxDevice::NewOsd(int x, int y) { return m_dxr3Device.NewOsd(x, y); } -#endif +#endif // ================================== -void cDxr3DemuxDevice::StillPicture(const uint8_t* buf, int length) +void cDxr3DemuxDevice::StillPicture(const uint8_t* buf, int length) { m_vBuf.Clear(); m_aBuf.Clear(); @@ -255,7 +256,7 @@ void cDxr3DemuxDevice::StillPicture(const uint8_t* buf, int length) m_trickState = DXR3_FREEZE; m_dxr3Device.SingleStep(); - cLog::Instance() << "StillPicture: len = " << length << "\n"; + cLog::Instance() << "StillPicture: len = " << length << "\n"; DemuxPes(buf, length); DemuxPes(buf, length); @@ -263,7 +264,7 @@ void cDxr3DemuxDevice::StillPicture(const uint8_t* buf, int length) } // ================================== -int cDxr3DemuxDevice::DemuxPes(const uint8_t* buf, int length, bool bAc3Dts) +int cDxr3DemuxDevice::DemuxPes(const uint8_t* buf, int length, bool bAc3Dts) { uint32_t pts = 0; static uint32_t aPts = 0; @@ -272,357 +273,381 @@ int cDxr3DemuxDevice::DemuxPes(const uint8_t* buf, int length, bool bAc3Dts) static bool bPlaySuc = false; static bool bPlayedFrame = false; int origLength = length; - + int scr = 0; int pcr = 0; - + scr = m_dxr3Device.GetSysClock(); - - // printf("vBuf size = %d\n", m_vBuf.Available()); - // printf("aBuf size = %d\n", m_aBuf.Available()); - /* - if (cDxr3ConfigData::Instance().GetAc3OutPut()) { + + //printf("vBuf size = %d\n", m_vBuf.Available()); + //printf("aBuf size = %d\n", m_aBuf.Available()); + /* + if (cDxr3ConfigData::Instance().GetAc3OutPut()) cDxr3AbsDevice::Instance().SetAudioDigitalAC3(); // !!! FIXME - } - */ - - if (m_pAudioThread->NeedResync() || m_pVideoThread->NeedResync()) + */ + + if (m_pAudioThread->NeedResync() || m_pVideoThread->NeedResync()) + { + Resync(); + if (m_demuxMode == DXR3_DEMUX_REPLAY_MODE) { - Resync(); - if (m_demuxMode == DXR3_DEMUX_REPLAY_MODE) - { - SetReplayMode(); - } - m_aBuf.Clear(); - m_vBuf.Clear(); - m_pAudioThread->ClearResyncRequest(); - m_pVideoThread->ClearResyncRequest(); - m_aDecoder.Reset(); - lastPts = 0; - aPts = 0; - vPts = 0; - bPlaySuc = false; + SetReplayMode(); } - - if (m_demuxMode == DXR3_DEMUX_OFF_MODE) - { - m_demuxMode = DXR3_DEMUX_TV_MODE; - m_synchState = DXR3_DEMUX_UNSYNCHED; - - lastPts = 0; - aPts = 0; - vPts = 0; - bPlaySuc = false; - /* - if (cDxr3ConfigData::Instance().GetAc3OutPut()) { - cDxr3AbsDevice::Instance().SetAudioDigitalAC3(); // !!! FIXME - } - */ + m_aBuf.Clear(); + m_vBuf.Clear(); + m_pAudioThread->ClearResyncRequest(); + m_pVideoThread->ClearResyncRequest(); + m_aDecoder.Reset(); + lastPts = 0; + aPts = 0; + vPts = 0; + bPlaySuc = false; + } + + if (m_demuxMode == DXR3_DEMUX_OFF_MODE) + { + m_demuxMode = DXR3_DEMUX_TV_MODE; + m_synchState = DXR3_DEMUX_UNSYNCHED; + + lastPts = 0; + aPts = 0; + vPts = 0; + bPlaySuc = false; + /* + if (cDxr3ConfigData::Instance().GetAc3OutPut()) + cDxr3AbsDevice::Instance().SetAudioDigitalAC3(); // !!! FIXME + */ } // find start code - try + try + { + cDxr3PesFrame pesFrame; + + pesFrame.ExtractNextFrame(buf, length); + + while (pesFrame.IsValid()) { - cDxr3PesFrame pesFrame; - - pesFrame.ExtractNextFrame(buf, length); - - while (pesFrame.IsValid()) + if (pesFrame.GetEsLength() > (uint32_t) VIDEO_MAX_FRAME_SIZE) + { + throw (cDxr3PesFrame::PES_GENERAL_ERROR); + }; + if (pesFrame.GetPts() != lastPts) + { + pts = lastPts = pesFrame.GetPts(); + } + else + { + pts = 0; + } + + if (pesFrame.GetPesDataType() == cDxr3PesFrame::PES_VIDEO_DATA) + { + /* + m_dxr3Device.PlayVideoFrame(pesFrame.GetEsStart(), + (int) (pesFrame.GetEsLength())); + */ + + if (m_demuxMode == DXR3_DEMUX_TRICK_MODE) { - if (pesFrame.GetEsLength() > (uint32_t) VIDEO_MAX_FRAME_SIZE) { throw (cDxr3PesFrame::PES_GENERAL_ERROR);}; - if (pesFrame.GetPts() != lastPts) + switch (pesFrame.GetFrameType()) + { + case I_FRAME: + cLog::Instance() << "i - frame\n"; + m_dxr3Device.SingleStep(); + bPlaySuc = true; + //if (bPlayedFrame) return length; + bPlayedFrame = true; + //usleep(30000); // otherwise there is problem with audio (driver bug?) + m_dxr3Device.SetHorizontalSize(pesFrame.GetHorizontalSize()); + m_dxr3Device.SetVerticalSize(pesFrame.GetVerticalSize()); + m_dxr3Device.PlayVideoFrame(pesFrame.GetEsStart(), (int) (pesFrame.GetEsLength()), m_ReUseFrame); + break; + + case UNKNOWN_FRAME: + cLog::Instance() << "frame unknown\n"; + if (bPlaySuc) { - pts = lastPts = pesFrame.GetPts(); - } - else + m_dxr3Device.PlayVideoFrame(pesFrame.GetEsStart(), (int) (pesFrame.GetEsLength()), m_ReUseFrame); + } + break; + + default: + cLog::Instance() << "default frame\n"; + if (bPlaySuc) { - pts = 0; + m_dxr3Device.PlayVideoFrame(pesFrame.GetEsStart(), (int) (pesFrame.GetOffset()), m_ReUseFrame); } - - if (pesFrame.GetPesDataType() == cDxr3PesFrame::PES_VIDEO_DATA) + + bPlaySuc = false; + break; + } + + } + else if (m_demuxMode == DXR3_DEMUX_VIDEO_ONLY_MODE) + { + m_dxr3Device.PlayVideoFrame(pesFrame.GetEsStart(), + (int)(pesFrame.GetEsLength())); + } + else if (m_synchState == DXR3_DEMUX_VIDEO_SYNCHED || + m_synchState == DXR3_DEMUX_SYNCHED) + { + m_dxr3Device.SetHorizontalSize(pesFrame.GetHorizontalSize()); + m_dxr3Device.SetVerticalSize(pesFrame.GetVerticalSize()); + while (!Poll(100)); + cFixedLengthFrame* pTempFrame = m_vBuf.Push(pesFrame.GetEsStart(), (int) (pesFrame.GetEsLength()), pts, ftVideo); + pTempFrame->SetAspectRatio(pesFrame.GetAspectRatio()); + + m_aBuf.WakeUp(); + + if (m_vBuf.GetFillLevel() > 5 && + m_synchState != DXR3_DEMUX_SYNCHED) + { + m_synchState = DXR3_DEMUX_SYNCHED; + pcr = vPts - PRE_BUFFER_LENGTH; + m_dxr3Device.SetSysClock(pcr); + m_dxr3Device.SetPlayMode(); + m_dxr3Device.EnableVideo(); + m_dxr3Device.EnableAudio(); + m_vBuf.Start(); + m_aBuf.Start(); + } + } + else + { + if (pesFrame.GetFrameType() == I_FRAME) + { + vPts = pts; + + m_dxr3Device.SetHorizontalSize(pesFrame.GetHorizontalSize()); + m_dxr3Device.SetVerticalSize(pesFrame.GetVerticalSize()); + cFixedLengthFrame* pTempFrame = m_vBuf.Push(pesFrame.GetEsStart(), (int) (pesFrame.GetEsLength()), pts, ftVideo); + pTempFrame->SetAspectRatio(pesFrame.GetAspectRatio()); + + if (m_synchState == DXR3_DEMUX_AUDIO_SYNCHED) { - // m_dxr3Device.PlayVideoFrame(pesFrame.GetEsStart(), (int) (pesFrame.GetEsLength())); - - if (m_demuxMode == DXR3_DEMUX_TRICK_MODE) - { - switch (pesFrame.GetFrameType()) - { - case I_FRAME: - cLog::Instance() << "i - frame\n"; - m_dxr3Device.SingleStep(); - bPlaySuc = true; - // if (bPlayedFrame) return length; - bPlayedFrame = true; - // usleep(30000); // otherwise there is problem with audio (driver bug?) - m_dxr3Device.SetHorizontalSize(pesFrame.GetHorizontalSize()); - m_dxr3Device.SetVerticalSize(pesFrame.GetVerticalSize()); - m_dxr3Device.PlayVideoFrame(pesFrame.GetEsStart(), (int) (pesFrame.GetEsLength()), m_ReUseFrame); - break; - - case UNKNOWN_FRAME: - cLog::Instance() << "frame unknown\n"; - if (bPlaySuc) - { - m_dxr3Device.PlayVideoFrame(pesFrame.GetEsStart(), (int) (pesFrame.GetEsLength()), m_ReUseFrame); - } - break; - - default: - cLog::Instance() << "default frame\n"; - if (bPlaySuc) - { - m_dxr3Device.PlayVideoFrame(pesFrame.GetEsStart(), (int) (pesFrame.GetOffset()), m_ReUseFrame); - } - - bPlaySuc = false; - break; - } - - } - else if (m_demuxMode == DXR3_DEMUX_VIDEO_ONLY_MODE) - { - m_dxr3Device.PlayVideoFrame(pesFrame.GetEsStart(), (int) (pesFrame.GetEsLength())); - } - else if (m_synchState == DXR3_DEMUX_VIDEO_SYNCHED || m_synchState == DXR3_DEMUX_SYNCHED) - { - m_dxr3Device.SetHorizontalSize(pesFrame.GetHorizontalSize()); - m_dxr3Device.SetVerticalSize(pesFrame.GetVerticalSize()); - while(!Poll(100)); - cFixedLengthFrame* pTempFrame = m_vBuf.Push(pesFrame.GetEsStart(), (int) (pesFrame.GetEsLength()), pts, ftVideo); - pTempFrame->SetAspectRatio(pesFrame.GetAspectRatio()); - - m_aBuf.WakeUp(); - - if (m_vBuf.GetFillLevel() > 5 && m_synchState != DXR3_DEMUX_SYNCHED) - { - m_synchState = DXR3_DEMUX_SYNCHED; - pcr = vPts - PRE_BUFFER_LENGTH; - m_dxr3Device.SetSysClock(pcr); - m_dxr3Device.SetPlayMode(); - m_dxr3Device.EnableVideo(); - m_dxr3Device.EnableAudio(); - m_vBuf.Start(); - m_aBuf.Start(); - } - } - else - { - if (pesFrame.GetFrameType() == I_FRAME) - { - vPts = pts; - - m_dxr3Device.SetHorizontalSize(pesFrame.GetHorizontalSize()); - m_dxr3Device.SetVerticalSize(pesFrame.GetVerticalSize()); - cFixedLengthFrame* pTempFrame = m_vBuf.Push(pesFrame.GetEsStart(), (int) (pesFrame.GetEsLength()), pts, ftVideo); - pTempFrame->SetAspectRatio(pesFrame.GetAspectRatio()); - - if (m_synchState == DXR3_DEMUX_AUDIO_SYNCHED) - { - m_synchState = DXR3_DEMUX_SYNCHED; - } - else - { - m_synchState = DXR3_DEMUX_VIDEO_SYNCHED; - } - if (m_synchState == DXR3_DEMUX_SYNCHED) - { - if (!vPts) vPts = aPts; - if (aPts < vPts) - { - pcr = aPts - PRE_BUFFER_LENGTH; - } - else - { - pcr = vPts - PRE_BUFFER_LENGTH; - } - m_dxr3Device.SetSysClock(pcr); - m_dxr3Device.SetPlayMode(); - m_dxr3Device.EnableVideo(); - m_dxr3Device.EnableAudio(); - m_vBuf.Start(); - m_aBuf.Start(); - } - } - } - - } - else if (pesFrame.GetPesDataType() == cDxr3PesFrame::PES_AUDIO_DATA - && m_demuxMode != DXR3_DEMUX_VIDEO_ONLY_MODE - && !cDxr3ConfigData::Instance().GetAc3OutPut()) + m_synchState = DXR3_DEMUX_SYNCHED; + } + else { - if (m_synchState == DXR3_DEMUX_AUDIO_SYNCHED || m_synchState == DXR3_DEMUX_SYNCHED) - { - if (pts && m_synchState != DXR3_DEMUX_SYNCHED) - { - m_synchState = DXR3_DEMUX_SYNCHED; - pcr = aPts - PRE_BUFFER_LENGTH; - m_dxr3Device.SetSysClock(pcr); - m_dxr3Device.SetPlayMode(); - m_dxr3Device.EnableVideo(); - m_dxr3Device.EnableAudio(); - m_vBuf.Start(); - m_aBuf.Start(); - } - while(!Poll(100)); - m_aDecoder.Decode(pesFrame.GetEsStart(), (int) (pesFrame.GetEsLength()), pts, m_aBuf); - - } - else - { - if (pts) - { - aPts = pts; - - m_aDecoder.Decode(pesFrame.GetEsStart(), (int) (pesFrame.GetEsLength()), pts, m_aBuf); - - if (m_synchState == DXR3_DEMUX_VIDEO_SYNCHED) - { - m_synchState = DXR3_DEMUX_SYNCHED; - } - else - { - m_synchState = DXR3_DEMUX_AUDIO_SYNCHED; - } - if (m_synchState == DXR3_DEMUX_SYNCHED) - { - if (!vPts) vPts = aPts; - if (aPts < vPts) - { - pcr = aPts - PRE_BUFFER_LENGTH; - } - else - { - pcr = vPts - PRE_BUFFER_LENGTH; - } - m_dxr3Device.SetSysClock(pcr); - m_dxr3Device.SetPlayMode(); - m_dxr3Device.EnableVideo(); - m_dxr3Device.EnableAudio(); - m_vBuf.Start(); - m_aBuf.Start(); - } - } - } - } - else if (pesFrame.GetPesDataType() == cDxr3PesFrame::PES_PRIVATE_DATA - && m_demuxMode != DXR3_DEMUX_VIDEO_ONLY_MODE - && !cDxr3ConfigData::Instance().GetAc3OutPut() - && !bAc3Dts) + m_synchState = DXR3_DEMUX_VIDEO_SYNCHED; + } + if (m_synchState == DXR3_DEMUX_SYNCHED) { - if (m_synchState == DXR3_DEMUX_AUDIO_SYNCHED || m_synchState == DXR3_DEMUX_SYNCHED) - { - m_aDecoder.DecodeLpcm(pesFrame.GetEsStart(), pesFrame.GetEsLength(), pts, m_aBuf); - } - else - { - if (pts) - { - aPts = pts; - m_aDecoder.DecodeLpcm(pesFrame.GetEsStart(), pesFrame.GetEsLength(), pts, m_aBuf); - - if (m_synchState == DXR3_DEMUX_VIDEO_SYNCHED) - { - m_synchState = DXR3_DEMUX_SYNCHED; - } - else - { - m_synchState = DXR3_DEMUX_AUDIO_SYNCHED; - } - if (m_synchState == DXR3_DEMUX_SYNCHED) - { - if (!vPts) vPts = aPts; - if (aPts < vPts) - { - pcr = aPts - PRE_BUFFER_LENGTH; - } - else - { - pcr = vPts - PRE_BUFFER_LENGTH; - } - m_dxr3Device.SetSysClock(pcr); - m_dxr3Device.SetPlayMode(); - m_dxr3Device.EnableVideo(); - m_dxr3Device.EnableAudio(); - m_vBuf.Start(); - m_aBuf.Start(); - } - } - } - } - else if (pesFrame.GetPesDataType() == cDxr3PesFrame::PES_PRIVATE_DATA - && m_demuxMode != DXR3_DEMUX_VIDEO_ONLY_MODE - && cDxr3ConfigData::Instance().GetAc3OutPut() - && bAc3Dts) + if (!vPts) vPts = aPts; + if (aPts < vPts) + { + pcr = aPts - PRE_BUFFER_LENGTH; + } + else + { + pcr = vPts - PRE_BUFFER_LENGTH; + } + m_dxr3Device.SetSysClock(pcr); + m_dxr3Device.SetPlayMode(); + m_dxr3Device.EnableVideo(); + m_dxr3Device.EnableAudio(); + m_vBuf.Start(); + m_aBuf.Start(); + } + } + } + + } + else if (pesFrame.GetPesDataType() == cDxr3PesFrame::PES_AUDIO_DATA + && m_demuxMode != DXR3_DEMUX_VIDEO_ONLY_MODE + && !cDxr3ConfigData::Instance().GetAc3OutPut()) + { + if (m_synchState == DXR3_DEMUX_AUDIO_SYNCHED || + m_synchState == DXR3_DEMUX_SYNCHED) + { + if (pts && m_synchState != DXR3_DEMUX_SYNCHED) + { + m_synchState = DXR3_DEMUX_SYNCHED; + pcr = aPts - PRE_BUFFER_LENGTH; + m_dxr3Device.SetSysClock(pcr); + m_dxr3Device.SetPlayMode(); + m_dxr3Device.EnableVideo(); + m_dxr3Device.EnableAudio(); + m_vBuf.Start(); + m_aBuf.Start(); + } + while(!Poll(100)); + m_aDecoder.Decode(pesFrame.GetEsStart(), + (int) (pesFrame.GetEsLength()), + pts, m_aBuf); + + } + else + { + if (pts) + { + aPts = pts; + + m_aDecoder.Decode(pesFrame.GetEsStart(), + (int) (pesFrame.GetEsLength()), + pts, m_aBuf); + + if (m_synchState == DXR3_DEMUX_VIDEO_SYNCHED) { - if (m_synchState == DXR3_DEMUX_AUDIO_SYNCHED || m_synchState == DXR3_DEMUX_SYNCHED) - { - m_aDecoder.DecodeAc3Dts(pesFrame.GetPesStart(), pesFrame.GetEsStart(), pesFrame.GetEsLength(), pts, m_aBuf); - } - else - { - if (pts) - { - aPts = pts; - m_aDecoder.DecodeAc3Dts(pesFrame.GetPesStart(), pesFrame.GetEsStart(), pesFrame.GetEsLength(), pts, m_aBuf); - - if (m_synchState == DXR3_DEMUX_VIDEO_SYNCHED) - { - m_synchState = DXR3_DEMUX_SYNCHED; - } - else - { - m_synchState = DXR3_DEMUX_AUDIO_SYNCHED; - } - if (m_synchState == DXR3_DEMUX_SYNCHED) - { - if (!vPts) vPts = aPts; - if (aPts < vPts) - { - pcr = aPts - PRE_BUFFER_LENGTH; - } - else - { - pcr = vPts - PRE_BUFFER_LENGTH; - } - m_dxr3Device.SetSysClock(pcr); - m_dxr3Device.SetPlayMode(); - m_dxr3Device.EnableVideo(); - m_dxr3Device.EnableAudio(); - m_vBuf.Start(); - m_aBuf.Start(); - } - } - } - - } - - if (pesFrame.IsValid()) + m_synchState = DXR3_DEMUX_SYNCHED; + } + else { - pesFrame.ExtractNextFrame(pesFrame.GetNextStart(), pesFrame.GetRemainingLength()); + m_synchState = DXR3_DEMUX_AUDIO_SYNCHED; } - - } - - length -= pesFrame.GetRemainingLength(); - - // if (m_demuxMode == DXR3_DEMUX_TRICK_MODE) return origLength; - return length; - } - catch (cDxr3PesFrame::ePesFrameError err) - { - dsyslog("cDxr3DemuxDevice::DemuxPes() ePesFrameError skipping data and resync"); - Resync(); - return origLength; - } - catch (cDxr3SyncBuffer::eSyncBufferException err) - { - Stop(); - return origLength; + if (m_synchState == DXR3_DEMUX_SYNCHED) + { + if (!vPts) vPts = aPts; + if (aPts < vPts) + { + pcr = aPts - PRE_BUFFER_LENGTH; + } + else + { + pcr = vPts - PRE_BUFFER_LENGTH; + } + m_dxr3Device.SetSysClock(pcr); + m_dxr3Device.SetPlayMode(); + m_dxr3Device.EnableVideo(); + m_dxr3Device.EnableAudio(); + m_vBuf.Start(); + m_aBuf.Start(); + } + } + } + } + else if (pesFrame.GetPesDataType() == cDxr3PesFrame::PES_PRIVATE_DATA + && m_demuxMode != DXR3_DEMUX_VIDEO_ONLY_MODE + && !cDxr3ConfigData::Instance().GetAc3OutPut() + && !bAc3Dts) + { + if (m_synchState == DXR3_DEMUX_AUDIO_SYNCHED || + m_synchState == DXR3_DEMUX_SYNCHED) + { + m_aDecoder.DecodeLpcm(pesFrame.GetEsStart(), + pesFrame.GetEsLength(), pts, m_aBuf); + } + else + { + if (pts) + { + aPts = pts; + m_aDecoder.DecodeLpcm(pesFrame.GetEsStart(), + pesFrame.GetEsLength(), + pts, m_aBuf); + + if (m_synchState == DXR3_DEMUX_VIDEO_SYNCHED) + { + m_synchState = DXR3_DEMUX_SYNCHED; + } + else + { + m_synchState = DXR3_DEMUX_AUDIO_SYNCHED; + } + if (m_synchState == DXR3_DEMUX_SYNCHED) + { + if (!vPts) vPts = aPts; + if (aPts < vPts) + { + pcr = aPts - PRE_BUFFER_LENGTH; + } + else + { + pcr = vPts - PRE_BUFFER_LENGTH; + } + m_dxr3Device.SetSysClock(pcr); + m_dxr3Device.SetPlayMode(); + m_dxr3Device.EnableVideo(); + m_dxr3Device.EnableAudio(); + m_vBuf.Start(); + m_aBuf.Start(); + } + } + } + } + else if (pesFrame.GetPesDataType() == cDxr3PesFrame::PES_PRIVATE_DATA + && m_demuxMode != DXR3_DEMUX_VIDEO_ONLY_MODE + && cDxr3ConfigData::Instance().GetAc3OutPut() + && bAc3Dts) + { + if (m_synchState == DXR3_DEMUX_AUDIO_SYNCHED || + m_synchState == DXR3_DEMUX_SYNCHED) + { + m_aDecoder.DecodeAc3Dts(pesFrame.GetPesStart(), + pesFrame.GetEsStart(), + pesFrame.GetEsLength(), + pts, m_aBuf); + } + else + { + if (pts) + { + aPts = pts; + m_aDecoder.DecodeAc3Dts(pesFrame.GetPesStart(), + pesFrame.GetEsStart(), + pesFrame.GetEsLength(), + pts, m_aBuf); + + if (m_synchState == DXR3_DEMUX_VIDEO_SYNCHED) + { + m_synchState = DXR3_DEMUX_SYNCHED; + } + else + { + m_synchState = DXR3_DEMUX_AUDIO_SYNCHED; + } + if (m_synchState == DXR3_DEMUX_SYNCHED) + { + if (!vPts) vPts = aPts; + if (aPts < vPts) + { + pcr = aPts - PRE_BUFFER_LENGTH; + } + else + { + pcr = vPts - PRE_BUFFER_LENGTH; + } + m_dxr3Device.SetSysClock(pcr); + m_dxr3Device.SetPlayMode(); + m_dxr3Device.EnableVideo(); + m_dxr3Device.EnableAudio(); + m_vBuf.Start(); + m_aBuf.Start(); + } + } + } + + } + + if (pesFrame.IsValid()) + { + pesFrame.ExtractNextFrame(pesFrame.GetNextStart(), + pesFrame.GetRemainingLength()); + } + + } + + length -= pesFrame.GetRemainingLength(); + + //if (m_demuxMode == DXR3_DEMUX_TRICK_MODE) return origLength; + return length; + } + catch (cDxr3PesFrame::ePesFrameError err) + { + dsyslog("cDxr3DemuxDevice::DemuxPes() ePesFrameError skipping data and resync"); + Resync(); + return origLength; + } + catch (cDxr3SyncBuffer::eSyncBufferException err) + { + Stop(); + return origLength; } } // ================================== -int cDxr3DemuxDevice::DemuxAudioPes(const uint8_t* buf, int length) +int cDxr3DemuxDevice::DemuxAudioPes(const uint8_t* buf, int length) { static int syncCounter = 0; int origLength = length; @@ -631,50 +656,54 @@ int cDxr3DemuxDevice::DemuxAudioPes(const uint8_t* buf, int length) m_aBuf.SetDemuxMode(DXR3_DEMUX_REPLAY_MODE); m_vBuf.SetDemuxMode(DXR3_DEMUX_REPLAY_MODE); - try - { - cDxr3PesFrame pesFrame; + try + { + cDxr3PesFrame pesFrame; - pesFrame.ExtractNextFrame(buf, length); + pesFrame.ExtractNextFrame(buf, length); - while (pesFrame.IsValid()) + while (pesFrame.IsValid()) + { + if (pesFrame.GetPesDataType() == cDxr3PesFrame::PES_PRIVATE_DATA) + { + if (m_synchState != DXR3_DEMUX_AUDIO_SYNCHED && + syncCounter > 2) { - if (pesFrame.GetPesDataType() == cDxr3PesFrame::PES_PRIVATE_DATA) - { - if (m_synchState != DXR3_DEMUX_AUDIO_SYNCHED && syncCounter > 2) - { - m_synchState = DXR3_DEMUX_AUDIO_SYNCHED; - m_dxr3Device.SetPlayMode(); - m_dxr3Device.EnableVideo(); - m_dxr3Device.EnableAudio(); - m_vBuf.Start(); - m_aBuf.Start(); - } - if (m_synchState != DXR3_DEMUX_AUDIO_SYNCHED && syncCounter <= 2) - { - syncCounter++; - } - while (!m_aBuf.Poll(100)); - m_aDecoder.DecodeLpcm(pesFrame.GetEsStart(), pesFrame.GetEsLength(), 0, m_aBuf); - - } - - if (pesFrame.IsValid()) - { - pesFrame.ExtractNextFrame(pesFrame.GetNextStart(), pesFrame.GetRemainingLength()); - } - } + m_synchState = DXR3_DEMUX_AUDIO_SYNCHED; + m_dxr3Device.SetPlayMode(); + m_dxr3Device.EnableVideo(); + m_dxr3Device.EnableAudio(); + m_vBuf.Start(); + m_aBuf.Start(); + } + if (m_synchState != DXR3_DEMUX_AUDIO_SYNCHED && + syncCounter <= 2) + { + syncCounter++; + } + while (!m_aBuf.Poll(100)); + m_aDecoder.DecodeLpcm(pesFrame.GetEsStart(), + pesFrame.GetEsLength(), 0, m_aBuf); + + } + + if (pesFrame.IsValid()) + { + pesFrame.ExtractNextFrame(pesFrame.GetNextStart(), + pesFrame.GetRemainingLength()); + } + } - length -= pesFrame.GetRemainingLength(); + length -= pesFrame.GetRemainingLength(); - return length; - } - catch (cDxr3PesFrame::ePesFrameError err) - { - dsyslog("cDxr3DemuxDevice::DemuxAudioPes() ePesFrameError skipping data and resync"); - Stop(); - return origLength; - } + return length; + } + catch (cDxr3PesFrame::ePesFrameError err) + { + dsyslog("cDxr3DemuxDevice::DemuxAudioPes() ePesFrameError skipping data and resync"); + Stop(); + return origLength; + } } // Local variables: diff --git a/dxr3demuxdevice.h b/dxr3demuxdevice.h index fdd1942..ebccaae 100644 --- a/dxr3demuxdevice.h +++ b/dxr3demuxdevice.h @@ -37,10 +37,10 @@ const uint32_t PRE_BUFFER_LENGTH = 0; // ================================== // extract video and audio -class cDxr3DemuxDevice +class cDxr3DemuxDevice { public: - cDxr3DemuxDevice(); + cDxr3DemuxDevice(); cDxr3DemuxDevice(cDxr3Interface& dxr3Device); ~cDxr3DemuxDevice(); @@ -55,31 +55,43 @@ public: void SetReplayMode(void); void SetTrickMode(eDxr3TrickState trickState, int Speed = 1); - #if VDRVERSNUM < 10307 +#if VDRVERSNUM < 10307 cOsdBase* NewOsd(int x, int y); - #endif +#endif int DemuxPes(const uint8_t* buf, int length, bool bAc3Dts = false); int DemuxAudioPes(const uint8_t* buf, int length); void StillPicture(const uint8_t* buf, int length); - eDxr3DemuxMode GetDemuxMode(void) { return m_demuxMode;}; - eDxr3TrickState GetTrickState(void) { return m_trickState;}; - bool Poll(int TimeoutMs){ return m_aBuf.Poll(TimeoutMs) && m_vBuf.Poll(TimeoutMs); }; - // { return m_demuxMode == DXR3_DEMUX_AUDIO_ONLY_MODE ? m_aBuf.Poll(TimeoutMs) : m_aBuf.Poll(TimeoutMs); }; + eDxr3DemuxMode GetDemuxMode(void) + { + return m_demuxMode; + }; + eDxr3TrickState GetTrickState(void) + { + return m_trickState; + }; + bool Poll(int TimeoutMs) + { + return m_aBuf.Poll(TimeoutMs) && m_vBuf.Poll(TimeoutMs); + /* + return m_demuxMode == DXR3_DEMUX_AUDIO_ONLY_MODE ? + m_aBuf.Poll(TimeoutMs) : m_aBuf.Poll(TimeoutMs); + */ + }; protected: - cDxr3Interface& m_dxr3Device; - cDxr3SyncBuffer m_aBuf; - cDxr3SyncBuffer m_vBuf; - eDxr3DemuxSynchState m_synchState; - eDxr3DemuxMode m_demuxMode; - eDxr3TrickState m_trickState; - cDxr3AudioDecoder m_aDecoder; - cDxr3AudioOutThread* m_pAudioThread; - cDxr3VideoOutThread* m_pVideoThread; - uint32_t m_stopScr; - int m_ReUseFrame; // how often a frame should be used + cDxr3Interface& m_dxr3Device; + cDxr3SyncBuffer m_aBuf; + cDxr3SyncBuffer m_vBuf; + eDxr3DemuxSynchState m_synchState; + eDxr3DemuxMode m_demuxMode; + eDxr3TrickState m_trickState; + cDxr3AudioDecoder m_aDecoder; + cDxr3AudioOutThread* m_pAudioThread; + cDxr3VideoOutThread* m_pVideoThread; + uint32_t m_stopScr; + int m_ReUseFrame; // how often a frame should be used private: cDxr3DemuxDevice(cDxr3DemuxDevice&); // no copy constructor diff --git a/dxr3device.c b/dxr3device.c index 6632d69..42f48d2 100644 --- a/dxr3device.c +++ b/dxr3device.c @@ -27,9 +27,9 @@ #include "dxr3log.h" #include "dxr3osd.h" -extern "C" +extern "C" { - #include <jpeglib.h> +#include <jpeglib.h> } // ================================== @@ -46,10 +46,10 @@ cDxr3Device::cDxr3Device() : m_DemuxDevice(cDxr3Interface::Instance()) // ================================== cDxr3Device::~cDxr3Device() { - if (m_spuDecoder) - { - delete m_spuDecoder; - } + if (m_spuDecoder) + { + delete m_spuDecoder; + } } // ================================== @@ -65,107 +65,107 @@ void cDxr3Device::MakePrimaryDevice(bool On) //! does we have an mpeg2 devocer? bool cDxr3Device::HasDecoder() const { - // sure we have one ;) - return true; + // sure we have one ;) + return true; } // ================================== //! can we replay vdr recordings? bool cDxr3Device::CanReplay() const { - // also sure... - return true; + // also sure... + return true; } // ================================== bool cDxr3Device::SetPlayMode(ePlayMode PlayMode) { - if (cDxr3ConfigData::Instance().GetDebug()) + if (cDxr3ConfigData::Instance().GetDebug()) + { + switch (PlayMode) { - switch (PlayMode) - { - case pmNone: - cLog::Instance() << "cDxr3Device::SetPlayMode audio/video from decoder\n"; - break; - - case pmAudioVideo: - cLog::Instance() << "cDxr3Device::SetPlayMode audio/video from player\n"; - break; - - case pmAudioOnly: - cLog::Instance() << "cDxr3Device::SetPlayMode audio only from player, video from decoder\n"; - break; - - case pmAudioOnlyBlack: - cLog::Instance() << "cDxr3Device::SetPlayMode audio only from player, no video (black screen)\n"; - break; - - case pmExtern_THIS_SHOULD_BE_AVOIDED: - cLog::Instance() << "cDxr3Device::SetPlayMode this should be avoided\n"; - break; - - #if VDRVERSNUM >= 10307 - case pmVideoOnly: - cLog::Instance() << "cDxr3Device::SetPlayMode video only from player, audio from decoder\n"; - break; - #endif - } - } + case pmNone: + cLog::Instance() << "cDxr3Device::SetPlayMode audio/video from decoder\n"; + break; - if (PlayMode == pmExtern_THIS_SHOULD_BE_AVOIDED) - { - Tools::WriteInfoToOsd(tr("DXR3: releasing devices")); - cDxr3Interface::Instance().ExternalReleaseDevices(); - } - else - { - cDxr3Interface::Instance().ExternalReopenDevices(); - } - - // should this relay be here? - m_Offset = 0; - m_AC3Present = false; - m_strBuf.erase(m_strBuf.begin(), m_strBuf.end()); - - if (PlayMode == pmAudioOnlyBlack) - { - m_PlayMode = pmAudioOnly; - } - else - { - m_PlayMode = PlayMode; + case pmAudioVideo: + cLog::Instance() << "cDxr3Device::SetPlayMode audio/video from player\n"; + break; + + case pmAudioOnly: + cLog::Instance() << "cDxr3Device::SetPlayMode audio only from player, video from decoder\n"; + break; + + case pmAudioOnlyBlack: + cLog::Instance() << "cDxr3Device::SetPlayMode audio only from player, no video (black screen)\n"; + break; + + case pmExtern_THIS_SHOULD_BE_AVOIDED: + cLog::Instance() << "cDxr3Device::SetPlayMode this should be avoided\n"; + break; + +#if VDRVERSNUM >= 10307 + case pmVideoOnly: + cLog::Instance() << "cDxr3Device::SetPlayMode video only from player, audio from decoder\n"; + break; +#endif } - - if (m_PlayMode == pmAudioVideo) + } + + if (PlayMode == pmExtern_THIS_SHOULD_BE_AVOIDED) + { + Tools::WriteInfoToOsd(tr("DXR3: releasing devices")); + cDxr3Interface::Instance().ExternalReleaseDevices(); + } + else + { + cDxr3Interface::Instance().ExternalReopenDevices(); + } + + // should this relay be here? + m_Offset = 0; + m_AC3Present = false; + m_strBuf.erase(m_strBuf.begin(), m_strBuf.end()); + + if (PlayMode == pmAudioOnlyBlack) + { + m_PlayMode = pmAudioOnly; + } + else + { + m_PlayMode = PlayMode; + } + + if (m_PlayMode == pmAudioVideo) + { + m_DemuxDevice.SetReplayMode(); + } + + if (m_PlayMode == pmNone) + { + m_DemuxDevice.Stop(); + } + + cLog::Instance() << "Setting audio mode..."; + + if (cDxr3ConfigData::Instance().GetUseDigitalOut()) + { + if (cDxr3ConfigData::Instance().GetAc3OutPut() && m_CalledBySet) { - m_DemuxDevice.SetReplayMode(); + cDxr3Interface::Instance().SetAudioDigitalAC3(); // !!! FIXME + cLog::Instance() << "ac3\n"; } - - if (m_PlayMode == pmNone) + else { - m_DemuxDevice.Stop(); + cDxr3Interface::Instance().SetAudioDigitalPCM(); + cDxr3ConfigData::Instance().SetAc3OutPut(0); + cLog::Instance() << "digital pcm\n"; } - - cLog::Instance() << "Setting audio mode..."; - - if (cDxr3ConfigData::Instance().GetUseDigitalOut()) - { - if (cDxr3ConfigData::Instance().GetAc3OutPut() && m_CalledBySet) - { - cDxr3Interface::Instance().SetAudioDigitalAC3(); // !!! FIXME - cLog::Instance() << "ac3\n"; - } - else - { - cDxr3Interface::Instance().SetAudioDigitalPCM(); - cDxr3ConfigData::Instance().SetAc3OutPut(0); - cLog::Instance() << "digital pcm\n"; - } - } - else - { - cDxr3Interface::Instance().SetAudioAnalog(); - cLog::Instance() << "analog\n"; + } + else + { + cDxr3Interface::Instance().SetAudioAnalog(); + cLog::Instance() << "analog\n"; } return true; @@ -174,38 +174,38 @@ bool cDxr3Device::SetPlayMode(ePlayMode PlayMode) // ================================== int64_t cDxr3Device::GetSTC() { - return cDxr3Interface::Instance().GetPts(); + return cDxr3Interface::Instance().GetPts(); } // ================================== void cDxr3Device::TrickSpeed(int Speed) { - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "cDxr3Device::TrickSpeed(int Speed): " << Speed << "\n"; - } + if (cDxr3ConfigData::Instance().GetDebug()) + { + cLog::Instance() << "cDxr3Device::TrickSpeed(int Speed): " + << Speed << "\n"; + } + m_DemuxDevice.SetTrickMode(DXR3_FAST, Speed); - m_DemuxDevice.SetTrickMode(DXR3_FAST, Speed); + /* + switch (Speed) + { + case 6: + cLog::Instance() << "Trickspeed: 1x vorwärts\n"; + break; -/* - switch (Speed) - { - case 6: - cLog::Instance() << "Trickspeed: 1x vorwärts\n"; - break; - - case 3: - cLog::Instance() << "Trickspeed: 2x vorwärts\n"; - break; - - case 1: - cLog::Instance() << "Trickspeed: 3x vorwärts\n"; - break; - }; -*/ -/* + case 3: + cLog::Instance() << "Trickspeed: 2x vorwärts\n"; + break; + + case 1: + cLog::Instance() << "Trickspeed: 3x vorwärts\n"; + break; + }; + */ + /* 6 ... 1x vowärts 3 ... 2x vowärts 1 ... 2x vowärts @@ -215,23 +215,24 @@ void cDxr3Device::TrickSpeed(int Speed) 1 ... 3x rückwärts 8 ... 1x vorwörts, wenn Pause gedrückt -*/ + */ - /* + /* #define EM8300_PLAYMODE_PAUSED 1 #define EM8300_PLAYMODE_SLOWFORWARDS 2 #define EM8300_PLAYMODE_SLOWBACKWARDS 3 #define EM8300_PLAYMODE_SINGLESTEP 4 - */ - /* - if (Speed == 8) - { - cDxr3Interface::Instance().SingleStep(); - } - else - { - m_DemuxDevice.SetTrickMode(DXR3_FAST); - }*/ + */ + /* + if (Speed == 8) + { + cDxr3Interface::Instance().SingleStep(); + } + else + { + m_DemuxDevice.SetTrickMode(DXR3_FAST); + } + */ } // ================================== @@ -249,45 +250,45 @@ void cDxr3Device::Play() { m_DemuxDevice.SetReplayMode(); m_Offset = 0; - ///< free buffer - m_strBuf.erase(m_strBuf.begin(), m_strBuf.end()); + ///< free buffer + m_strBuf.erase(m_strBuf.begin(), m_strBuf.end()); } // ================================== //! puts the device into "freeze frame" mode void cDxr3Device::Freeze() { - m_DemuxDevice.SetTrickMode(DXR3_FREEZE); + m_DemuxDevice.SetTrickMode(DXR3_FREEZE); } // ================================== void cDxr3Device::Mute() { - m_DemuxDevice.SetTrickMode(DXR3_FAST); + m_DemuxDevice.SetTrickMode(DXR3_FAST); } // ================================== //! displays the given I-frame as a still picture. void cDxr3Device::StillPicture(const uchar *Data, int Length) { - m_DemuxDevice.StillPicture(Data, Length); + m_DemuxDevice.StillPicture(Data, Length); } // ================================== bool cDxr3Device::Poll(cPoller &Poller, int TimeoutMs) { - if ((m_DemuxDevice.GetDemuxMode() == DXR3_DEMUX_TRICK_MODE && - m_DemuxDevice.GetTrickState() == DXR3_FREEZE) || - cDxr3Interface::Instance().IsExternalReleased()) - { + if ((m_DemuxDevice.GetDemuxMode() == DXR3_DEMUX_TRICK_MODE && + m_DemuxDevice.GetTrickState() == DXR3_FREEZE) || + cDxr3Interface::Instance().IsExternalReleased()) + { #if VDRVERSNUM >= 10314 - cCondWait::SleepMs(TimeoutMs); + cCondWait::SleepMs(TimeoutMs); #else - usleep(TimeoutMs * 1000); + usleep(TimeoutMs * 1000); #endif - return false; - } - return m_DemuxDevice.Poll(TimeoutMs); // Poller.Poll(TimeoutMs); + return false; + } + return m_DemuxDevice.Poll(TimeoutMs); // Poller.Poll(TimeoutMs); } // ================================== @@ -296,52 +297,53 @@ int cDxr3Device::PlayVideo(const uchar *Data, int Length) { int retLength = 0; int origLength = Length; - + if ((m_DemuxDevice.GetDemuxMode() == DXR3_DEMUX_TRICK_MODE && - m_DemuxDevice.GetTrickState() == DXR3_FREEZE) || cDxr3Interface::Instance().IsExternalReleased()) - { - // Why is here so a huge time waster? - //usleep(1000000); - return -1; + m_DemuxDevice.GetTrickState() == DXR3_FREEZE) || + cDxr3Interface::Instance().IsExternalReleased()) + { + // Why is here so a huge time waster? + //usleep(1000000); + return -1; } - if (m_strBuf.length()) + if (m_strBuf.length()) + { + m_strBuf.append((const char*)Data, Length); + + if (m_PlayMode == pmAudioOnly) { - m_strBuf.append((const char*)Data, Length); - - if (m_PlayMode == pmAudioOnly) - { - retLength = m_DemuxDevice.DemuxAudioPes((const uint8_t*)m_strBuf.data(), m_strBuf.length()); - } - else - { - retLength = m_DemuxDevice.DemuxPes((const uint8_t*)m_strBuf.data(), m_strBuf.length()); - } - } - else + retLength = m_DemuxDevice.DemuxAudioPes((const uint8_t*)m_strBuf.data(), m_strBuf.length()); + } + else { - if (m_PlayMode == pmAudioOnly) - { - retLength = m_DemuxDevice.DemuxAudioPes((const uint8_t*)Data, Length); - } - else - { - retLength = m_DemuxDevice.DemuxPes((const uint8_t*)Data, Length); - } + retLength = m_DemuxDevice.DemuxPes((const uint8_t*)m_strBuf.data(), m_strBuf.length()); + } + } + else + { + if (m_PlayMode == pmAudioOnly) + { + retLength = m_DemuxDevice.DemuxAudioPes((const uint8_t*)Data, Length); + } + else + { + retLength = m_DemuxDevice.DemuxPes((const uint8_t*)Data, Length); + } } Length -= retLength; - - if (m_strBuf.length()) - { - m_strBuf.erase(m_strBuf.length() - retLength, retLength); - } - else + + if (m_strBuf.length()) + { + m_strBuf.erase(m_strBuf.length() - retLength, retLength); + } + else + { + if (Length) { - if (Length) - { - m_strBuf.append((const char*)(Data + retLength), Length); - } + m_strBuf.append((const char*)(Data + retLength), Length); + } } return origLength; @@ -350,172 +352,175 @@ int cDxr3Device::PlayVideo(const uchar *Data, int Length) // ================================== // plays additional audio streams, like Dolby Digital #if VDRVERSNUM >= 10318 - int cDxr3Device::PlayAudio(const uchar *Data, int Length) +int cDxr3Device::PlayAudio(const uchar *Data, int Length) #else - void cDxr3Device::PlayAudio(const uchar *Data, int Length) +void cDxr3Device::PlayAudio(const uchar *Data, int Length) #endif { int retLength = 0; #if VDRVERSNUM >= 10318 - int origLength = Length; -#endif + int origLength = Length; +#endif #if VDRVERSNUM < 10307 - if (!m_AC3Present) - { - Interface->Write(Interface->Width() / 2, 0, "AC3", clrRed); - } + if (!m_AC3Present) + { + Interface->Write(Interface->Width() / 2, 0, "AC3", clrRed); + } #endif m_AC3Present = true; - - if ((m_DemuxDevice.GetDemuxMode() == DXR3_DEMUX_TRICK_MODE && - m_DemuxDevice.GetTrickState() == DXR3_FREEZE) || cDxr3Interface::Instance().IsExternalReleased()) - { - //usleep(1000000); + if ((m_DemuxDevice.GetDemuxMode() == DXR3_DEMUX_TRICK_MODE && + m_DemuxDevice.GetTrickState() == DXR3_FREEZE) || + cDxr3Interface::Instance().IsExternalReleased()) + { + //usleep(1000000); #if VDRVERSNUM >= 10318 - return 0; + return 0; #else - return; + return; #endif } - if (m_strBuf.length()) + if (m_strBuf.length()) + { + m_strBuf.append((const char*)Data, Length); + if (m_PlayMode == pmAudioOnly) { - m_strBuf.append((const char*)Data, Length); - if (m_PlayMode == pmAudioOnly) { retLength = m_DemuxDevice.DemuxAudioPes((const uint8_t*)m_strBuf.data(), m_strBuf.length()); } else { retLength = m_DemuxDevice.DemuxPes((const uint8_t*)m_strBuf.data(), m_strBuf.length(), true); } - - } - else + } + else + { + if (m_PlayMode == pmAudioOnly) { - if (m_PlayMode == pmAudioOnly) { - retLength = m_DemuxDevice.DemuxAudioPes((const uint8_t*)Data, Length); - } else { - retLength = m_DemuxDevice.DemuxPes((const uint8_t*)Data, Length, true); - } + retLength = m_DemuxDevice.DemuxAudioPes((const uint8_t*) Data, Length); + } else { + retLength = m_DemuxDevice.DemuxPes((const uint8_t*)Data, Length, true); + } } - + Length -= retLength; - - if (m_strBuf.length()) - { - m_strBuf.erase(m_strBuf.length() - retLength, retLength); - } - else + + if (m_strBuf.length()) + { + m_strBuf.erase(m_strBuf.length() - retLength, retLength); + } + else + { + if (Length) { - if (Length) - { - m_strBuf.append((const char*)(Data + retLength), Length); - } + m_strBuf.append((const char*)(Data + retLength), Length); + } } #if VDRVERSNUM >= 10318 - return origLength; + return origLength; #endif } // addition functions // ================================== //! capture a single frame as an image -bool cDxr3Device::GrabImage(const char *FileName, bool Jpeg, int Quality, int SizeX, int SizeY) +bool cDxr3Device::GrabImage(const char *FileName, bool Jpeg, int Quality, + int SizeX, int SizeY) { - int w = SizeX; - int h = SizeY; - unsigned char *Data = new unsigned char[w*h*3]; - memset(Data, 0, w*h*3); - - // we could get a I-Frame and save it - //m_DemuxDevice.StillPicture(Data, 100*1024); - - isyslog("grabbing to %s (%s %d %d %d)", FileName, Jpeg ? "JPEG" : "PNM", Quality, w, h); - FILE *f = fopen(FileName, "wb"); - if (f) + int w = SizeX; + int h = SizeY; + unsigned char *Data = new unsigned char[w * h * 3]; + memset(Data, 0, w * h * 3); + + // we could get a I-Frame and save it + //m_DemuxDevice.StillPicture(Data, 100 * 1024); + + isyslog("grabbing to %s (%s %d %d %d)", + FileName, Jpeg ? "JPEG" : "PNM", Quality, w, h); + FILE *f = fopen(FileName, "wb"); + if (f) + { + if (Jpeg) { - if (Jpeg) - { - ///< write JPEG file: - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_compress(&cinfo); - jpeg_stdio_dest(&cinfo, f); - cinfo.image_width = w; - cinfo.image_height = h; - cinfo.input_components = 3; - cinfo.in_color_space = JCS_RGB; - - jpeg_set_defaults(&cinfo); - jpeg_set_quality(&cinfo, Quality, true); - jpeg_start_compress(&cinfo, true); - - int rs = w * 3; - JSAMPROW rp[h]; - for (int k = 0; k < h; k++) - { - rp[k] = &Data[rs * k]; - } - jpeg_write_scanlines(&cinfo, rp, h); - jpeg_finish_compress(&cinfo); - jpeg_destroy_compress(&cinfo); - - } - else - { - ///< write PNM file: - if (fprintf(f, "P6\n%d\n%d\n255\n", w, h) < 0 || - fwrite(Data, w * h * 3, 1, f) != 1) - { - LOG_ERROR_STR(FileName); - } - } - fclose(f); + ///< write JPEG file: + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + jpeg_stdio_dest(&cinfo, f); + cinfo.image_width = w; + cinfo.image_height = h; + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo, Quality, true); + jpeg_start_compress(&cinfo, true); + + int rs = w * 3; + JSAMPROW rp[h]; + for (int k = 0; k < h; k++) + { + rp[k] = &Data[rs * k]; + } + jpeg_write_scanlines(&cinfo, rp, h); + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + } else { - return false; + ///< write PNM file: + if (fprintf(f, "P6\n%d\n%d\n255\n", w, h) < 0 || + fwrite(Data, w * h * 3, 1, f) != 1) + { + LOG_ERROR_STR(FileName); + } } + fclose(f); + } + else + { + return false; + } - delete Data; - return true; + delete Data; + return true; } // ================================== void cDxr3Device::SetVideoFormat(bool VideoFormat16_9) { - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "cDxr3Device::SetPlayMode(ePlayMode PlayMode)() done\n"; - } - // Do we need this function? + if (cDxr3ConfigData::Instance().GetDebug()) + { + cLog::Instance() << "cDxr3Device::SetPlayMode(ePlayMode PlayMode)() done\n"; + } + // Do we need this function? } // ================================== //! sets volume for audio output void cDxr3Device::SetVolumeDevice(int Volume) { - cDxr3Interface::Instance().SetVolume(Volume); + cDxr3Interface::Instance().SetVolume(Volume); } // ================================== // get spudecoder cSpuDecoder *cDxr3Device::GetSpuDecoder(void) { - if (!m_spuDecoder && IsPrimaryDevice()) - { - m_spuDecoder = new cDxr3SpuDecoder(); - } - return m_spuDecoder; + if (!m_spuDecoder && IsPrimaryDevice()) + { + m_spuDecoder = new cDxr3SpuDecoder(); + } + return m_spuDecoder; } #if VDRVERSNUM < 10307 // ================================== // return osd -cOsdBase *cDxr3Device::NewOsd(int x, int y) +cOsdBase *cDxr3Device::NewOsd(int x, int y) { return m_DemuxDevice.NewOsd(x, y); } diff --git a/dxr3device.h b/dxr3device.h index 14c3191..ce79ceb 100644 --- a/dxr3device.h +++ b/dxr3device.h @@ -32,58 +32,64 @@ // ================================== // our device :) /*! - cDxr3Device is the interface for VDR devices. - Is is the part, which VDR "talks" with our plugin. + cDxr3Device is the interface for VDR devices. + Is is the part, which VDR "talks" with our plugin. */ class cDxr3Device : public cDevice, public Singleton<cDxr3Device> { public: cDxr3Device(); - cDxr3Device(cDxr3Interface& demuxDevice); + cDxr3Device(cDxr3Interface& demuxDevice); ~cDxr3Device(); - virtual void MakePrimaryDevice(bool On); + virtual void MakePrimaryDevice(bool On); - // replaying - virtual bool HasDecoder() const; - virtual bool CanReplay() const; - virtual bool SetPlayMode(ePlayMode PlayMode); - virtual int64_t GetSTC(); - virtual void TrickSpeed(int Speed); - virtual void Clear(); - virtual void Play(); - virtual void Freeze(); - virtual void Mute(); - virtual void StillPicture(const uchar *Data, int Length); - virtual bool Poll(cPoller &Poller, int TimeoutMs = 0); - virtual int PlayVideo(const uchar *Data, int Length); + // replaying + virtual bool HasDecoder() const; + virtual bool CanReplay() const; + virtual bool SetPlayMode(ePlayMode PlayMode); + virtual int64_t GetSTC(); + virtual void TrickSpeed(int Speed); + virtual void Clear(); + virtual void Play(); + virtual void Freeze(); + virtual void Mute(); + virtual void StillPicture(const uchar *Data, int Length); + virtual bool Poll(cPoller &Poller, int TimeoutMs = 0); + virtual int PlayVideo(const uchar *Data, int Length); #if VDRVERSNUM >= 10318 - virtual int PlayAudio(const uchar *Data, int Length); + virtual int PlayAudio(const uchar *Data, int Length); #else - virtual void PlayAudio(const uchar *Data, int Length); + virtual void PlayAudio(const uchar *Data, int Length); #endif - // addition functions - virtual bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1); - virtual void SetVideoFormat(bool VideoFormat16_9); - virtual void SetVolumeDevice(int Volume); + // addition functions + virtual bool GrabImage(const char *FileName, bool Jpeg = true, + int Quality = -1, int SizeX = -1, int SizeY = -1); + virtual void SetVideoFormat(bool VideoFormat16_9); + virtual void SetVolumeDevice(int Volume); - // osd - virtual cSpuDecoder *GetSpuDecoder(); - #if VDRVERSNUM < 10307 + // osd + virtual cSpuDecoder *GetSpuDecoder(); +#if VDRVERSNUM < 10307 virtual cOsdBase* NewOsd(int x, int y); - #endif +#endif - // helper function - void Reset() { m_CalledBySet = true; SetPlayMode(m_PlayMode); m_CalledBySet = false; } + // helper function + void Reset() + { + m_CalledBySet = true; + SetPlayMode(m_PlayMode); + m_CalledBySet = false; + } protected: - ePlayMode m_PlayMode; - cDxr3DemuxDevice m_DemuxDevice; - bool m_AC3Present; - bool m_CalledBySet; - std::string m_strBuf; - int m_Offset; + ePlayMode m_PlayMode; + cDxr3DemuxDevice m_DemuxDevice; + bool m_AC3Present; + bool m_CalledBySet; + std::string m_strBuf; + int m_Offset; //virtual bool SetPlayMode(ePlayMode PlayMode); //uint8_t m_pBuffer[MAX_VIDEO_BUFFER_SIZE]; diff --git a/dxr3ffmpeg.c b/dxr3ffmpeg.c index f524849..b7309e5 100644 --- a/dxr3ffmpeg.c +++ b/dxr3ffmpeg.c @@ -27,7 +27,7 @@ //! constructor cDxr3Ffmepg::cDxr3Ffmepg() { - avcodec_init(); + avcodec_init(); // Register only codec(s) we'll need. register_avcodec(&mp2_decoder); } @@ -36,57 +36,59 @@ cDxr3Ffmepg::cDxr3Ffmepg() //! look if Codec is supported by ffmpeg bool cDxr3Ffmepg::FindCodec(struct Dxr3Codec& Codec) { - // find codec + // find codec Codec.codec = avcodec_find_decoder(Codec.id); - if (!Codec.codec) + if (!Codec.codec) + { + // codec is't supported by ffmpeg + if (cDxr3ConfigData::Instance().GetDebug()) { - // codec is't supported by ffmpeg - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "cDxr3Ffmepg::OpenCodec(struct Dxr3Codec& Codec) codec not found (" << Codec.id << ")\n"; - } - return false; + cLog::Instance() << "cDxr3Ffmepg::FindCodec() codec not found (" + << Codec.id << ")\n"; } + return false; + } - // init codec_context + // init codec_context memset(&Codec.codec_context, 0, sizeof(Codec.codec_context)); - return true; + return true; } // ================================== //! try to open Codec bool cDxr3Ffmepg::OpenCodec(struct Dxr3Codec& Codec) { - // try to open codec - int result = avcodec_open(&Codec.codec_context, Codec.codec); + // try to open codec + int result = avcodec_open(&Codec.codec_context, Codec.codec); - if (result < 0) - { - // we could not open codec - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "cDxr3Ffmepg::OpenCodec(struct Dxr3Codec& Codec) coudnt open codec (" << Codec.id << ")\n"; - } - return false; - } - else + if (result < 0) + { + // we could not open codec + if (cDxr3ConfigData::Instance().GetDebug()) { - Codec.Open = true; + cLog::Instance() << "cDxr3Ffmepg::OpenCodec() coudnt open codec (" + << Codec.id << ")\n"; } + return false; + } + else + { + Codec.Open = true; + } - return true; + return true; } // ================================== //! close codec void cDxr3Ffmepg::CloseCodec(struct Dxr3Codec& Codec) { - if (Codec.Open) - { - avcodec_close(&Codec.codec_context); - Codec.Open = false; + if (Codec.Open) + { + avcodec_close(&Codec.codec_context); + Codec.Open = false; } } diff --git a/dxr3ffmpeg.h b/dxr3ffmpeg.h index 165f646..a833021 100644 --- a/dxr3ffmpeg.h +++ b/dxr3ffmpeg.h @@ -22,44 +22,44 @@ #ifndef _DXR3_FFMPEG_H_ #define _DXR3_FFMPEG_H_ -extern "C" +extern "C" { - #include <avcodec.h> +#include <avcodec.h> } -#include <string.h> +#include <string.h> #include "dxr3singleton.h" // ================================== //! a codec used by this plugin struct Dxr3Codec { - Dxr3Codec() : Open(false) {} + Dxr3Codec() : Open(false) {} - AVCodec* codec; ///< ffmpeg's AVCodec + AVCodec* codec; ///< ffmpeg's AVCodec AVCodecContext codec_context; ///< ffmpeg's AVCodecContext - enum CodecID id; ///< id's from ffmpeg - like CODEC_ID_MP2 - bool Open; ///< is codec open? + enum CodecID id; ///< id's from ffmpeg, eg. CODEC_ID_MP2 + bool Open; ///< is codec open? }; // ================================== // class to work with ffmpeg /*! - With cDxr3Ffmepg you can easily handle as many - codecs as you want. - At the moment we need this only for - the audiodecoder, but in future i want to use - it for ohter nice stuff :) + With cDxr3Ffmepg you can easily handle as many + codecs as you want. + At the moment we need this only for + the audiodecoder, but in future i want to use + it for ohter nice stuff :) */ -class cDxr3Ffmepg : public Singleton<cDxr3Ffmepg> +class cDxr3Ffmepg : public Singleton<cDxr3Ffmepg> { public: cDxr3Ffmepg(); - ~cDxr3Ffmepg() {} + ~cDxr3Ffmepg() {} - bool FindCodec(struct Dxr3Codec& Codec); - bool OpenCodec(struct Dxr3Codec& Codec); - void CloseCodec(struct Dxr3Codec& Codec); + bool FindCodec(struct Dxr3Codec& Codec); + bool OpenCodec(struct Dxr3Codec& Codec); + void CloseCodec(struct Dxr3Codec& Codec); private: cDxr3Ffmepg(cDxr3Ffmepg&); // no copy constructor @@ -24,727 +24,727 @@ const char *i18n_name = 0; const tI18nPhrase Phrases[] = { - { - "DXR3", - "DXR3", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "DXR3-toiminnot", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + { + "DXR3", + "DXR3", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "DXR3-toiminnot", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "Hardware MPEG decoder", - "", // Deutsch - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "MPEG-purkukortti", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "Hardware MPEG decoder", + "", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "MPEG-purkukortti", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "DXR3 Adjustment", - "DXR3 Einstellungen", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "DXR3-toiminnot", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "DXR3 Adjustment", + "DXR3 Einstellungen", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "DXR3-toiminnot", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "Digital audio output", - "Digitaler Audioausgang", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "Digitaalinen audioulostulo", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "Digital audio output", + "Digitaler Audioausgang", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Digitaalinen audioulostulo", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "Card number", - "Karte", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "Kortin järjestysnumero", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "Card number", + "Karte", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Kortin järjestysnumero", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "Video mode", - "Videomodus", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "Näyttötila", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "Video mode", + "Videomodus", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Näyttötila", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "PAL", - "PAL", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "PAL", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "PAL", + "PAL", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "PAL", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "PAL60", - "PAL60", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "PAL60", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "PAL60", + "PAL60", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "PAL60", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "NTSC", - "NTSC", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "NTSC", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "NTSC", + "NTSC", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "NTSC", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "Reset DXR3 hardware", - "Reset DXR3 Hardware", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "Palauta kortti alkutilaan", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "Reset DXR3 hardware", + "Reset DXR3 Hardware", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Palauta kortti alkutilaan", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "Toggle force letterbox", - "Letterbox erzwingen", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "Letterbox-näyttötilan pakotus päälle/pois", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "Toggle force letterbox", + "Letterbox erzwingen", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Letterbox-näyttötilan pakotus päälle/pois", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "Switch to analog audio output", - "Analoge Ausgabe", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "Kytke analoginen audioulostulo", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "Switch to analog audio output", + "Analoge Ausgabe", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Kytke analoginen audioulostulo", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "AC3 output on", - "AC3 Ausgabe Ein", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "AC3-ulostulo päälle", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "AC3 output on", + "AC3 Ausgabe Ein", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "AC3-ulostulo päälle", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "AC3 output off", - "AC3 Ausgabe Aus", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "AC3-ulostulo pois", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "AC3 output off", + "AC3 Ausgabe Aus", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "AC3-ulostulo pois", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "Switch to digital audio output", - "Digitaler Ausgang", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "Kytke digitaalinen audioulostulo", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "Switch to digital audio output", + "Digitaler Ausgang", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Kytke digitaalinen audioulostulo", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "DXR3: releasing devices", - "DXR3: Releasing Devices", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "DXR3: vapautetaan laitteet", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "DXR3: releasing devices", + "DXR3: Releasing Devices", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "DXR3: vapautetaan laitteet", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "Color settings", - "Farbeinstellungen", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "Väriasetukset", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "Color settings", + "Farbeinstellungen", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Väriasetukset", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "Brightness", - "Helligkeit", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "Kirkkaus", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "Brightness", + "Helligkeit", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Kirkkaus", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "Contrast", - "Kontrast", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "Kontrasti", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "Contrast", + "Kontrast", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Kontrasti", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "Saturation", - "Sättigung", - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "Värikylläisyys", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "Saturation", + "Sättigung", + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Värikylläisyys", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "Debug mode", - "", // Deutsch - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "Debug-tila", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "Debug mode", + "", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Debug-tila", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "Debug level", - "", // Deutsch - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "Debug-taso", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "Debug level", + "", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Debug-taso", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "low", - "", // Deutsch - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "alhainen", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "low", + "", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "alhainen", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { - "everything", - "", // Deutsch - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "kaikki", - "", // Polski - "", // Español - "", // ÅëëçíéêÜ (Greek) - "", // Svenska - "", // Românã - "", // Magyar - "", // Català + }, + { + "everything", + "", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "kaikki", + "", // Polski + "", // Español + "", // ÅëëçíéêÜ (Greek) + "", // Svenska + "", // Românã + "", // Magyar + "", // Català #if VDRVERSNUM > 10302 - "", // ÀãááÚØÙ (Russian) + "", // ÀãááÚØÙ (Russian) # if VDRVERSNUM > 10307 - "", // Hrvatski + "", // Hrvatski # if VDRVERSNUM > 10312 - "", // Eesti + "", // Eesti # if VDRVERSNUM > 10315 - "", // Dansk + "", // Dansk # endif # endif # endif #endif - }, - { NULL } + }, + { NULL } }; // Local variables: diff --git a/dxr3interface.c b/dxr3interface.c index 3eea756..c3f5150 100644 --- a/dxr3interface.c +++ b/dxr3interface.c @@ -38,91 +38,98 @@ const uint32_t UNKNOWN_AUDIO_MODE = 9; // default, unused value //! helper function to generate name static const char *Dxr3Name(const char *Name, int n) { - static char buffer[PATH_MAX]; - snprintf(buffer, sizeof(buffer), "/dev/em8300%s-%d", Name, n); - return buffer; + static char buffer[PATH_MAX]; + snprintf(buffer, sizeof(buffer), "/dev/em8300%s-%d", Name, n); + return buffer; } // ================================== //! helper function to open the card #n static int Dxr3Open(const char *Name, int n, int Mode) { - const char *FileName = Dxr3Name(Name, n); - int fd = open(FileName, Mode); - - if (fd < 0) - { - cLog::Instance() << "Unable to open " << FileName << "\n"; - } - return fd; + const char *FileName = Dxr3Name(Name, n); + int fd = open(FileName, Mode); + + if (fd < 0) + { + cLog::Instance() << "Unable to open " << FileName << "\n"; + } + return fd; } // ================================== //! constructor cDxr3Interface::cDxr3Interface() : -m_fdControl(-1), m_fdVideo(-1), m_fdAudio(-1), m_fdSpu(-1) + m_fdControl(-1), m_fdVideo(-1), m_fdAudio(-1), m_fdSpu(-1) { - // open control stream - m_fdControl = Dxr3Open("", cDxr3ConfigData::Instance().GetDxr3Card(), O_WRONLY | O_SYNC); - if (m_fdControl < 0) - { - cLog::Instance() << "Please check if the dxr3 modules are loaded!\n"; - exit(1); - } - - // upload microcode to dxr3 - UploadMicroCode(); + // open control stream + m_fdControl = Dxr3Open("", cDxr3ConfigData::Instance().GetDxr3Card(), + O_WRONLY | O_SYNC); + if (m_fdControl < 0) + { + cLog::Instance() << "Please check if the dxr3 modules are loaded!\n"; + exit(1); + } - ///< open 'multimedia' streams - m_fdVideo = Dxr3Open("_mv", cDxr3ConfigData::Instance().GetDxr3Card(), O_WRONLY | O_SYNC); - m_fdAudio = Dxr3Open("_ma", cDxr3ConfigData::Instance().GetDxr3Card(), O_WRONLY | O_SYNC); - m_fdSpu = Dxr3Open("_sp", cDxr3ConfigData::Instance().GetDxr3Card(), O_WRONLY | O_SYNC); + // upload microcode to dxr3 + UploadMicroCode(); - // everything ok? - if (m_fdVideo < 0 || m_fdAudio < 0 || m_fdSpu < 0) - { - cLog::Instance() << "Unable to open one of the 'multimedia' streams!\n"; - exit(1); - } + ///< open multimedia streams + m_fdVideo = Dxr3Open("_mv", cDxr3ConfigData::Instance().GetDxr3Card(), + O_WRONLY | O_SYNC); + m_fdAudio = Dxr3Open("_ma", cDxr3ConfigData::Instance().GetDxr3Card(), + O_WRONLY | O_SYNC); + m_fdSpu = Dxr3Open("_sp", cDxr3ConfigData::Instance().GetDxr3Card(), + O_WRONLY | O_SYNC); + + // everything ok? + if (m_fdVideo < 0 || m_fdAudio < 0 || m_fdSpu < 0) + { + cLog::Instance() << "Unable to open one of the 'multimedia' streams!\n"; + exit(1); + } - // create clock - m_pClock = new cDxr3SysClock(m_fdControl, m_fdVideo, m_fdSpu); + // create clock + m_pClock = new cDxr3SysClock(m_fdControl, m_fdVideo, m_fdSpu); - // everything ok? - if (!m_pClock) - { - cLog::Instance() << "Unable to allocate memory for m_pClock in cDxr3Interface\n"; - exit(1); - } + // everything ok? + if (!m_pClock) + { + cLog::Instance() << "Unable to allocate memory for m_pClock in cDxr3Interface\n"; + exit(1); + } - // set default values + // set default values m_AudioActive = false; - m_VideoActive = false; - m_OverlayActive = false; + m_VideoActive = false; + m_OverlayActive = false; m_ExternalReleased = false; m_volume = 255; - m_horizontal = 720; - m_vertical = 576; + m_horizontal = 720; + m_vertical = 576; m_audioChannelCount = UNKNOWN_CHANNEL_COUNT; m_audioDataRate = 0; m_audioSampleSize = 0; m_audioMode = UNKNOWN_AUDIO_MODE; - m_aspectRatio = UNKNOWN_ASPECT_RATIO; - m_spuMode = EM8300_SPUMODE_OFF; + m_aspectRatio = UNKNOWN_ASPECT_RATIO; + m_spuMode = EM8300_SPUMODE_OFF; - // configure device based on settings - ConfigureDevice(); - - // get bcs values from driver - ioctl(m_fdControl, EM8300_IOCTL_GETBCS, &m_bcs); + // configure device based on settings + ConfigureDevice(); - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "DXR3: brightness: " << m_bcs.brightness << "\n"; - cLog::Instance() << "DXR3: contrast: " << m_bcs.contrast << "\n"; - cLog::Instance() << "DXR3: saturation: " << m_bcs.saturation << "\n"; - } + // get bcs values from driver + ioctl(m_fdControl, EM8300_IOCTL_GETBCS, &m_bcs); + + if (cDxr3ConfigData::Instance().GetDebug()) + { + cLog::Instance() << "DXR3: brightness: " + << m_bcs.brightness << "\n"; + cLog::Instance() << "DXR3: contrast: " + << m_bcs.contrast << "\n"; + cLog::Instance() << "DXR3: saturation: " + << m_bcs.saturation << "\n"; + } PlayBlackFrame(); SetChannelCount(1); @@ -132,29 +139,29 @@ m_fdControl(-1), m_fdVideo(-1), m_fdAudio(-1), m_fdSpu(-1) //! destructor cDxr3Interface::~cDxr3Interface() { - // close filehandles - if (m_fdControl > -1) - { - close(m_fdControl); - } - if (m_fdVideo > -1) - { - close(m_fdVideo); - } - if (m_fdSpu > -1) - { - close(m_fdSpu); - } - if (m_fdAudio > -1) - { - close(m_fdAudio); - } + // close filehandles + if (m_fdControl > -1) + { + close(m_fdControl); + } + if (m_fdVideo > -1) + { + close(m_fdVideo); + } + if (m_fdSpu > -1) + { + close(m_fdSpu); + } + if (m_fdAudio > -1) + { + close(m_fdAudio); + } - // free some memory - if (m_pClock) - { - delete m_pClock; - } + // free some memory + if (m_pClock) + { + delete m_pClock; + } } // main @@ -176,18 +183,18 @@ void cDxr3Interface::SetAudioAnalog() int ioval = 0; Lock(); - if (!m_ExternalReleased && m_audioMode != EM8300_AUDIOMODE_ANALOG) + if (!m_ExternalReleased && m_audioMode != EM8300_AUDIOMODE_ANALOG) + { + int prevMode = m_audioMode; + m_audioMode = ioval = EM8300_AUDIOMODE_ANALOG; + if (ioctl(m_fdControl, EM8300_IOCTL_SET_AUDIOMODE, &ioval) < 0) { - int prevMode = m_audioMode; - m_audioMode = ioval = EM8300_AUDIOMODE_ANALOG; - if (ioctl(m_fdControl, EM8300_IOCTL_SET_AUDIOMODE, &ioval) < 0) - { - cLog::Instance() << "cDxr3AbsDevice::SetAudioAnalog Unable to set audiomode!\n"; - } - if (prevMode == EM8300_AUDIOMODE_DIGITALAC3) - { - ReOpenAudio(); - } + cLog::Instance() << "cDxr3AbsDevice::SetAudioAnalog Unable to set audiomode!\n"; + } + if (prevMode == EM8300_AUDIOMODE_DIGITALAC3) + { + ReOpenAudio(); + } } Unlock(); @@ -200,19 +207,19 @@ void cDxr3Interface::SetAudioDigitalPCM() int ioval = 0; Lock(); - if (!m_ExternalReleased && m_audioMode != EM8300_AUDIOMODE_DIGITALPCM) + if (!m_ExternalReleased && m_audioMode != EM8300_AUDIOMODE_DIGITALPCM) + { + int prevMode = m_audioMode; + m_audioMode = ioval = EM8300_AUDIOMODE_DIGITALPCM; + + if (ioctl(m_fdControl, EM8300_IOCTL_SET_AUDIOMODE, &ioval) < 0) { - int prevMode = m_audioMode; - m_audioMode = ioval = EM8300_AUDIOMODE_DIGITALPCM; - - if (ioctl(m_fdControl, EM8300_IOCTL_SET_AUDIOMODE, &ioval) < 0) - { - cLog::Instance() << "cDxr3AbsDevice::SetAudioAnalog Unable to set audiomode!\n"; - } - if (prevMode == EM8300_AUDIOMODE_DIGITALAC3) - { - ReOpenAudio(); - } + cLog::Instance() << "cDxr3AbsDevice::SetAudioAnalog Unable to set audiomode!\n"; + } + if (prevMode == EM8300_AUDIOMODE_DIGITALAC3) + { + ReOpenAudio(); + } } Unlock(); @@ -222,22 +229,22 @@ void cDxr3Interface::SetAudioDigitalPCM() //! set audio-output to digital ac3 void cDxr3Interface::SetAudioDigitalAC3() { - if (m_audioMode != EM8300_AUDIOMODE_DIGITALAC3) + if (m_audioMode != EM8300_AUDIOMODE_DIGITALAC3) + { + int ioval = 0; + Lock(); + + if (!m_ExternalReleased && m_audioMode != EM8300_AUDIOMODE_DIGITALAC3) { - int ioval = 0; - Lock(); + m_audioMode = ioval = EM8300_AUDIOMODE_DIGITALAC3; + if (ioctl(m_fdControl, EM8300_IOCTL_SET_AUDIOMODE, &ioval) < 0) + { + cLog::Instance() << "cDxr3AbsDevice::SetAudioAnalog Unable to set audiomode!\n"; + } + ReOpenAudio(); + } - if (!m_ExternalReleased && m_audioMode != EM8300_AUDIOMODE_DIGITALAC3) - { - m_audioMode = ioval = EM8300_AUDIOMODE_DIGITALAC3; - if (ioctl(m_fdControl, EM8300_IOCTL_SET_AUDIOMODE, &ioval) < 0) - { - cLog::Instance() << "cDxr3AbsDevice::SetAudioAnalog Unable to set audiomode!\n"; - } - ReOpenAudio(); - } - - Unlock(); + Unlock(); } } @@ -245,19 +252,19 @@ void cDxr3Interface::SetAudioDigitalAC3() //! set audiosepeed void cDxr3Interface::SetAudioSpeed(uint32_t speed) { - if (m_audioDataRate != speed && speed != UNKNOWN_DATA_RATE) + if (m_audioDataRate != speed && speed != UNKNOWN_DATA_RATE) + { + if (!m_ExternalReleased) { - if (!m_ExternalReleased) + if (m_audioMode != EM8300_AUDIOMODE_DIGITALAC3) + { + if (ioctl(m_fdAudio, SNDCTL_DSP_SPEED, &speed) < 0) { - if (m_audioMode != EM8300_AUDIOMODE_DIGITALAC3) - { - if (ioctl(m_fdAudio, SNDCTL_DSP_SPEED, &speed) < 0) - { - cLog::Instance() << "cDxr3AbsDevice::SetAudioSpeed Unable to set dsp speed\n"; - } - } - } - m_audioDataRate = speed; + cLog::Instance() << "cDxr3Interface::SetAudioSpeed Unable to set dsp speed\n"; + } + } + } + m_audioDataRate = speed; } } @@ -265,53 +272,53 @@ void cDxr3Interface::SetAudioSpeed(uint32_t speed) //! set nummber of channels void cDxr3Interface::SetChannelCount(uint32_t count) { - if (m_audioChannelCount != count && count != UNKNOWN_CHANNEL_COUNT) + if (m_audioChannelCount != count && count != UNKNOWN_CHANNEL_COUNT) + { + if (!m_ExternalReleased) { - if (!m_ExternalReleased) + if (m_audioMode != EM8300_AUDIOMODE_DIGITALAC3) + { + if (ioctl(m_fdAudio, SNDCTL_DSP_STEREO, &count) < 0) { - if (m_audioMode != EM8300_AUDIOMODE_DIGITALAC3) - { - if (ioctl(m_fdAudio, SNDCTL_DSP_STEREO, &count) < 0) - { - cLog::Instance() << "cDxr3AbsDevice::SetChannelCount Unable to set channel count\n"; - } - } - } - m_audioChannelCount = count; + cLog::Instance() << "cDxr3AbsDevice::SetChannelCount Unable to set channel count\n"; + } + } + } + m_audioChannelCount = count; } } // ================================== //! set audio sample size -void cDxr3Interface::SetAudioSampleSize(uint32_t sampleSize) +void cDxr3Interface::SetAudioSampleSize(uint32_t sampleSize) { - if (!m_ExternalReleased) + if (!m_ExternalReleased) + { + if (ioctl(m_fdAudio, SNDCTL_DSP_SAMPLESIZE, sampleSize)) { - if (ioctl(m_fdAudio, SNDCTL_DSP_SAMPLESIZE, sampleSize)) - { - cLog::Instance() <<"cDxr3AbsDevice::SetAudioSampleSize Unable to set audio sample size\n"; - } + cLog::Instance() <<"cDxr3AbsDevice::SetAudioSampleSize Unable to set audio sample size\n"; + } } - m_audioSampleSize = sampleSize; + m_audioSampleSize = sampleSize; } // clock // ================================== -void cDxr3Interface::SetSysClock(uint32_t scr) +void cDxr3Interface::SetSysClock(uint32_t scr) { - if (!m_ExternalReleased) - { - m_pClock->SetSysClock(scr); + if (!m_ExternalReleased) + { + m_pClock->SetSysClock(scr); } } // ================================== -uint32_t cDxr3Interface::GetSysClock() const +uint32_t cDxr3Interface::GetSysClock() const { uint32_t ret = 0; - if (!m_ExternalReleased) - { - ret = m_pClock->GetSysClock(); + if (!m_ExternalReleased) + { + ret = m_pClock->GetSysClock(); } return ret; } @@ -323,24 +330,25 @@ int64_t cDxr3Interface::GetPts() } // ================================== -void cDxr3Interface::SetPts(uint32_t pts) +void cDxr3Interface::SetPts(uint32_t pts) { - if (!m_ExternalReleased) - { - m_pClock->SetPts(pts); + if (!m_ExternalReleased) + { + m_pClock->SetPts(pts); } } // ================================== -void cDxr3Interface::SetSpuPts(uint32_t pts) +void cDxr3Interface::SetSpuPts(uint32_t pts) { - pts = pts >> 1; - if (!m_ExternalReleased) + pts = pts >> 1; + if (!m_ExternalReleased) + { + if (pts > m_pClock->GetSysClock() && + pts - m_pClock->GetSysClock() < 100000) { - if (pts > m_pClock->GetSysClock() && pts - m_pClock->GetSysClock() < 100000) - { - m_pClock->SetSpuPts(pts); - } + m_pClock->SetSpuPts(pts); + } } } @@ -352,13 +360,13 @@ void cDxr3Interface::EnableSPU() int ioval = 0; Lock(); - if (!m_ExternalReleased && m_spuMode != EM8300_SPUMODE_ON) - { - m_spuMode = ioval = EM8300_SPUMODE_ON; - if (ioctl(m_fdControl, EM8300_IOCTL_SET_SPUMODE, &ioval) < 0) - { - cLog::Instance() << "cDxr3AbsDevice::EnableSpu Unable to set subpicture mode!\n"; - } + if (!m_ExternalReleased && m_spuMode != EM8300_SPUMODE_ON) + { + m_spuMode = ioval = EM8300_SPUMODE_ON; + if (ioctl(m_fdControl, EM8300_IOCTL_SET_SPUMODE, &ioval) < 0) + { + cLog::Instance() << "cDxr3AbsDevice::EnableSpu Unable to set subpicture mode!\n"; + } } Unlock(); @@ -371,13 +379,13 @@ void cDxr3Interface::DisableSPU() int ioval = 0; Lock(); - if (!m_ExternalReleased && m_spuMode != EM8300_SPUMODE_OFF) - { - m_spuMode = ioval = EM8300_SPUMODE_OFF; - if (ioctl(m_fdControl, EM8300_IOCTL_SET_SPUMODE, &ioval) < 0) - { - cLog::Instance() << "cDxr3AbsDevice::EnableSpu Unable to set subpicture mode!\n"; - } + if (!m_ExternalReleased && m_spuMode != EM8300_SPUMODE_OFF) + { + m_spuMode = ioval = EM8300_SPUMODE_OFF; + if (ioctl(m_fdControl, EM8300_IOCTL_SET_SPUMODE, &ioval) < 0) + { + cLog::Instance() << "cDxr3AbsDevice::EnableSpu Unable to set subpicture mode!\n"; + } } Unlock(); @@ -386,16 +394,16 @@ void cDxr3Interface::DisableSPU() // ================================== //! disable audio output of dxr3 void cDxr3Interface::DisableAudio() -{ - m_AudioActive = false; - - // we write zero buffers to dxr3 - if (!m_ExternalReleased) - { - if (write(m_fdAudio, zerobuffer, ZEROBUFFER_SIZE) < 0) Resuscitation(); - if (write(m_fdAudio, zerobuffer, ZEROBUFFER_SIZE) < 0) Resuscitation(); - if (write(m_fdAudio, zerobuffer, ZEROBUFFER_SIZE) < 0) Resuscitation(); - if (write(m_fdAudio, zerobuffer, ZEROBUFFER_SIZE) < 0) Resuscitation(); +{ + m_AudioActive = false; + + // we write zero buffers to dxr3 + if (!m_ExternalReleased) + { + if (write(m_fdAudio, zerobuffer, ZEROBUFFER_SIZE) < 0) Resuscitation(); + if (write(m_fdAudio, zerobuffer, ZEROBUFFER_SIZE) < 0) Resuscitation(); + if (write(m_fdAudio, zerobuffer, ZEROBUFFER_SIZE) < 0) Resuscitation(); + if (write(m_fdAudio, zerobuffer, ZEROBUFFER_SIZE) < 0) Resuscitation(); } } @@ -403,65 +411,65 @@ void cDxr3Interface::DisableAudio() //! enable overlay mode of the dxr3 void cDxr3Interface::EnableOverlay() { - // first we check, if it is enabled yet - if (m_OverlayActive) - { - return; - } - - /* - #define EM8300_OVERLAY_SIGNAL_ONLY 1 - #define EM8300_OVERLAY_SIGNAL_WITH_VGA 2 - #define EM8300_OVERLAY_VGA_ONLY 3 - */ - - int ioval = EM8300_OVERLAY_SIGNAL_WITH_VGA; - // set overlay signal mode - if (ioctl(m_fdControl, EM8300_IOCTL_OVERLAY_SIGNALMODE, &ioval) < 0) - { - //###### - cLog::Instance() << "Singnalmode failed\n"; - return; - } + // first we check, if it is enabled yet + if (m_OverlayActive) + { + return; + } - // setup overlay screen - em8300_overlay_screen_t scr; - scr.xsize = 1024; - scr.ysize = 768; + /* +#define EM8300_OVERLAY_SIGNAL_ONLY 1 +#define EM8300_OVERLAY_SIGNAL_WITH_VGA 2 +#define EM8300_OVERLAY_VGA_ONLY 3 + */ + + int ioval = EM8300_OVERLAY_SIGNAL_WITH_VGA; + // set overlay signal mode + if (ioctl(m_fdControl, EM8300_IOCTL_OVERLAY_SIGNALMODE, &ioval) < 0) + { + //###### + cLog::Instance() << "Singnalmode failed\n"; + return; + } - if (ioctl(m_fdControl, EM8300_IOCTL_OVERLAY_SETSCREEN, &scr) < 0) - { - //###### - cLog::Instance() << "seting up screen failed\n"; - return; - } + // setup overlay screen + em8300_overlay_screen_t scr; + scr.xsize = 1024; + scr.ysize = 768; - // setup overlay window - em8300_overlay_window_t win; - win.xpos = 0; - win.ypos = 0; - win.width = 1024; - win.height = 768; + if (ioctl(m_fdControl, EM8300_IOCTL_OVERLAY_SETSCREEN, &scr) < 0) + { + //###### + cLog::Instance() << "seting up screen failed\n"; + return; + } - if (ioctl(m_fdControl, EM8300_IOCTL_OVERLAY_SETWINDOW, &win) < 0) - { - //###### - cLog::Instance() << "seting up window failed\n"; - return; - } + // setup overlay window + em8300_overlay_window_t win; + win.xpos = 0; + win.ypos = 0; + win.width = 1024; + win.height = 768; + + if (ioctl(m_fdControl, EM8300_IOCTL_OVERLAY_SETWINDOW, &win) < 0) + { + //###### + cLog::Instance() << "seting up window failed\n"; + return; + } - m_OverlayActive = true; + m_OverlayActive = true; } // ================================== //! disable overlay mode of the dxr3 void cDxr3Interface::DisanleOverlay() { - // is it allready disabled - if (!m_OverlayActive) - { - return; - } + // is it allready disabled + if (!m_OverlayActive) + { + return; + } } // set/get functions @@ -471,57 +479,59 @@ uint32_t cDxr3Interface::GetAspectRatio() const { int ioval = 0; Lock(); - - if (!m_ExternalReleased) + + if (!m_ExternalReleased) + { + if (ioctl(m_fdControl, EM8300_IOCTL_GET_ASPECTRATIO, &ioval) < 0) { - if (ioctl(m_fdControl, EM8300_IOCTL_GET_ASPECTRATIO, &ioval) < 0) - { - cLog::Instance() << "cDxr3AbsDevice::GetAspectRatio Unable to get aspect ratio\n"; - } + cLog::Instance() << "cDxr3AbsDevice::GetAspectRatio Unable to get aspect ratio\n"; + } } - + Unlock(); return ioval; } // ================================== //! set aspectratio -void cDxr3Interface::SetAspectRatio(uint32_t ratio) +void cDxr3Interface::SetAspectRatio(uint32_t ratio) { static int requestCounter = 0; - + Lock(); - if (cDxr3ConfigData::Instance().GetForceLetterBox()) ratio = EM8300_ASPECTRATIO_16_9; - if (Setup.VideoFormat) ratio = EM8300_ASPECTRATIO_4_3; + if (cDxr3ConfigData::Instance().GetForceLetterBox()) + ratio = EM8300_ASPECTRATIO_16_9; + if (Setup.VideoFormat) + ratio = EM8300_ASPECTRATIO_4_3; - if (!m_ExternalReleased && ratio != UNKNOWN_ASPECT_RATIO) - { - if (ratio != m_aspectRatio && requestCounter > 50) - { - requestCounter = 0; - if (ioctl(m_fdControl, EM8300_IOCTL_SET_ASPECTRATIO, &ratio) < 0) - { - cLog::Instance() << "cDxr3AbsDevice::SetAspectRatio Unable to set aspect ratio\n"; - } - else - { - m_aspectRatio = ratio; - } - } - else - { - if (ratio != m_aspectRatio) - { - ++requestCounter; - } - else - { - requestCounter = 0; - } - } + if (!m_ExternalReleased && ratio != UNKNOWN_ASPECT_RATIO) + { + if (ratio != m_aspectRatio && requestCounter > 50) + { + requestCounter = 0; + if (ioctl(m_fdControl, EM8300_IOCTL_SET_ASPECTRATIO, &ratio) < 0) + { + cLog::Instance() << "cDxr3AbsDevice::SetAspectRatio Unable to set aspect ratio\n"; + } + else + { + m_aspectRatio = ratio; + } + } + else + { + if (ratio != m_aspectRatio) + { + ++requestCounter; + } + else + { + requestCounter = 0; + } + } } - + Unlock(); } @@ -535,26 +545,26 @@ void cDxr3Interface::SetPlayMode() Lock(); - if (!m_ExternalReleased) - { - ioval = EM8300_SUBDEVICE_AUDIO; - ioctl(m_fdControl, EM8300_IOCTL_FLUSH, &ioval); - fsync(m_fdVideo); + if (!m_ExternalReleased) + { + ioval = EM8300_SUBDEVICE_AUDIO; + ioctl(m_fdControl, EM8300_IOCTL_FLUSH, &ioval); + fsync(m_fdVideo); - ioval = EM8300_PLAYMODE_PLAY; - if (ioctl(m_fdControl, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) - { - cLog::Instance() << "cDxr3Device::SetPlayMode Unable to set playmode!\n"; - } - reg.microcode_register = 1; - reg.reg = 0; - reg.val = MVCOMMAND_SYNC; + ioval = EM8300_PLAYMODE_PLAY; + if (ioctl(m_fdControl, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) + { + cLog::Instance() << "cDxr3Device::SetPlayMode Unable to set playmode!\n"; + } + reg.microcode_register = 1; + reg.reg = 0; + reg.val = MVCOMMAND_SYNC; - if (ioctl(m_fdControl, EM8300_IOCTL_WRITEREG, ®) < 0) - { - cLog::Instance() << "cDxr3Device::SetPlayMode Unable to start em8300 sync engine\n"; - } + if (ioctl(m_fdControl, EM8300_IOCTL_WRITEREG, ®) < 0) + { + cLog::Instance() << "cDxr3Device::SetPlayMode Unable to start em8300 sync engine\n"; + } } Unlock(); @@ -566,12 +576,12 @@ void cDxr3Interface::Pause() int ioval = EM8300_PLAYMODE_PAUSED; Lock(); - if (!m_ExternalReleased) - { - if (ioctl(m_fdControl, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) - { - cLog::Instance() << "cDxr3Device::Pause Unable to set playmode!\n"; - } + if (!m_ExternalReleased) + { + if (ioctl(m_fdControl, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) + { + cLog::Instance() << "cDxr3Device::Pause Unable to set playmode!\n"; + } } Unlock(); @@ -582,11 +592,12 @@ void cDxr3Interface::SingleStep() int ioval = EM8300_PLAYMODE_SINGLESTEP; Lock(); - if (!m_ExternalReleased) - { - if (ioctl(m_fdControl, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) { - cLog::Instance() << "cDxr3Device::Pause Unable to set playmode!\n"; - } + if (!m_ExternalReleased) + { + if (ioctl(m_fdControl, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) + { + cLog::Instance() << "cDxr3Device::Pause Unable to set playmode!\n"; + } } Unlock(); @@ -598,39 +609,39 @@ void cDxr3Interface::PlayVideoFrame(cFixedLengthFrame* pFrame, int times) int written = 0; int count = 0; - if (m_VideoActive) + if (m_VideoActive) + { + Lock(); + + if (!m_ExternalReleased) { - Lock(); + for (int i = 0; i < times; i++) + { + if (times > 1) + { + cLog::Instance() << "times: " << times << "\n"; + } - if (!m_ExternalReleased) + while (written < pFrame->GetCount() && count >= 0) { - for (int i = 0; i < times; i++) - { - if (times > 1) - { - cLog::Instance() << "times: " << times << "\n"; - } - - while (written < pFrame->GetCount() && count >= 0) - { - if ((count = write(m_fdVideo, pFrame->GetData() + written, pFrame->GetCount() - written)) < 0) - { - // an error occured - Resuscitation(); - } - written += count; - } - - // reset - written = 0; - } - } - - Unlock(); - - SetAspectRatio(pFrame->GetAspectRatio()); - uint32_t pts = pFrame->GetPts(); - if (pts > 0) m_lastSeenPts = pts; + if ((count = write(m_fdVideo, pFrame->GetData() + written, pFrame->GetCount() - written)) < 0) + { + // an error occured + Resuscitation(); + } + written += count; + } + + // reset + written = 0; + } + } + + Unlock(); + + SetAspectRatio(pFrame->GetAspectRatio()); + uint32_t pts = pFrame->GetPts(); + if (pts > 0) m_lastSeenPts = pts; } } @@ -638,15 +649,15 @@ void cDxr3Interface::PlayVideoFrame(cFixedLengthFrame* pFrame, int times) void cDxr3Interface::PlayVideoFrame(const uint8_t* pBuf, int length, int times) { Lock(); - - if (!m_ExternalReleased) + + if (!m_ExternalReleased) + { + for (int i = 0; i < times; i++) { - for (int i = 0; i < times; i++) - { - if (write(m_fdVideo, pBuf, length) < 0) Resuscitation(); - } + if (write(m_fdVideo, pBuf, length) < 0) Resuscitation(); + } } - + Unlock(); } @@ -654,22 +665,23 @@ void cDxr3Interface::PlayVideoFrame(const uint8_t* pBuf, int length, int times) void cDxr3Interface::PlayAudioFrame(cFixedLengthFrame* pFrame) { - // XXX: Call this only with we are not in external mode? + // XXX: Call this only with we are not in external mode? - if (m_AudioActive) - { - Lock(); + if (m_AudioActive) + { + Lock(); - SetAudioSpeed(pFrame->GetDataRate()); - SetChannelCount(pFrame->GetChannelCount()); + SetAudioSpeed(pFrame->GetDataRate()); + SetChannelCount(pFrame->GetChannelCount()); - if (!m_ExternalReleased) - { - if (!cDxr3ConfigData::Instance().GetAc3OutPut()) ResampleVolume((short*)pFrame->GetData(), pFrame->GetCount()); - write(m_fdAudio, pFrame->GetData(), pFrame->GetCount()); - } + if (!m_ExternalReleased) + { + if (!cDxr3ConfigData::Instance().GetAc3OutPut()) + ResampleVolume((short*)pFrame->GetData(), pFrame->GetCount()); + write(m_fdAudio, pFrame->GetData(), pFrame->GetCount()); + } - Unlock(); + Unlock(); } } @@ -679,15 +691,16 @@ void cDxr3Interface::PlayAudioFrame(uint8_t* pBuf, int length) int written = 0; Lock(); - if (!m_ExternalReleased) - { - if (!cDxr3ConfigData::Instance().GetAc3OutPut()) ResampleVolume((short*)pBuf, length); + if (!m_ExternalReleased) + { + if (!cDxr3ConfigData::Instance().GetAc3OutPut()) + ResampleVolume((short*)pBuf, length); - if ((written = write(m_fdAudio, pBuf, length) < 0)) Resuscitation(); - if (written != length) - { - cLog::Instance() << "cDxr3Interface::PlayAudioFrame(uint8_t* pBuf, int length): Not written = " << length - written << "\n"; - } + if ((written = write(m_fdAudio, pBuf, length) < 0)) Resuscitation(); + if (written != length) + { + cLog::Instance() << "cDxr3Interface::PlayAudioFrame(uint8_t* pBuf, int length): Not written = " << length - written << "\n"; + } } Unlock(); @@ -696,42 +709,43 @@ void cDxr3Interface::PlayAudioFrame(uint8_t* pBuf, int length) // ================================== void cDxr3Interface::PlayAudioLpcmFrame(uint8_t* pBuf, int length) { - if (length > (LPCM_HEADER_LENGTH + 2)) + if (length > (LPCM_HEADER_LENGTH + 2)) + { + uint8_t* pFrame = new uint8_t[length - LPCM_HEADER_LENGTH]; + // only even number of bytes are allowed + assert(!((length - LPCM_HEADER_LENGTH) % 2)); + + for (int i = LPCM_HEADER_LENGTH; i < length; i += 2) { - uint8_t* pFrame = new uint8_t[length - LPCM_HEADER_LENGTH]; - assert(!((length - LPCM_HEADER_LENGTH) % 2)); // only even number of bytes are allowed - - for (int i = LPCM_HEADER_LENGTH; i < length; i += 2) - { - pFrame[i - LPCM_HEADER_LENGTH] = pBuf[i + 1]; - pFrame[i - LPCM_HEADER_LENGTH + 1] = pBuf[i]; - } + pFrame[i - LPCM_HEADER_LENGTH] = pBuf[i + 1]; + pFrame[i - LPCM_HEADER_LENGTH + 1] = pBuf[i]; + } - int codedSpeed = (pBuf[5] >> 4) & 0x03; - int speed = 0; + int codedSpeed = (pBuf[5] >> 4) & 0x03; + int speed = 0; - switch (codedSpeed) - { - case 1: - speed = 96000; - break; - - case 2: - speed = 44100; - break; - - case 3: - speed = 32000; - break; - - default: - speed = 48000; - break; - } - - SetAudioSpeed(speed); - PlayAudioFrame(pFrame, length - LPCM_HEADER_LENGTH); - delete[] pFrame; + switch (codedSpeed) + { + case 1: + speed = 96000; + break; + + case 2: + speed = 44100; + break; + + case 3: + speed = 32000; + break; + + default: + speed = 48000; + break; + } + + SetAudioSpeed(speed); + PlayAudioFrame(pFrame, length - LPCM_HEADER_LENGTH); + delete[] pFrame; } } @@ -743,22 +757,22 @@ void cDxr3Interface::ExternalReleaseDevices() { Lock(); - if (!m_ExternalReleased) - { - if (m_fdControl > -1) close(m_fdControl); - if (m_fdVideo > -1) close(m_fdVideo); - if (m_fdSpu > -1) close(m_fdSpu); - if (m_fdAudio > -1) close(m_fdAudio); - m_fdControl = m_fdVideo = m_fdSpu = m_fdAudio = -1; - m_aspectRatio = UNKNOWN_ASPECT_RATIO; - m_audioMode = UNKNOWN_AUDIO_MODE; - - m_ExternalReleased = true; - - delete m_pClock; - m_pClock = 0; + if (!m_ExternalReleased) + { + if (m_fdControl > -1) close(m_fdControl); + if (m_fdVideo > -1) close(m_fdVideo); + if (m_fdSpu > -1) close(m_fdSpu); + if (m_fdAudio > -1) close(m_fdAudio); + m_fdControl = m_fdVideo = m_fdSpu = m_fdAudio = -1; + m_aspectRatio = UNKNOWN_ASPECT_RATIO; + m_audioMode = UNKNOWN_AUDIO_MODE; + + m_ExternalReleased = true; + + delete m_pClock; + m_pClock = 0; } - + Unlock(); } @@ -768,36 +782,40 @@ void cDxr3Interface::ExternalReopenDevices() { Lock(); - if (m_ExternalReleased) + if (m_ExternalReleased) + { + // open control stream + m_fdControl = Dxr3Open("", cDxr3ConfigData::Instance().GetDxr3Card(), + O_WRONLY | O_SYNC); + + // open 'multimedia' streams + m_fdVideo = Dxr3Open("_mv", cDxr3ConfigData::Instance().GetDxr3Card(), + O_WRONLY | O_SYNC); + m_fdAudio = Dxr3Open("_ma", cDxr3ConfigData::Instance().GetDxr3Card(), + O_WRONLY | O_SYNC); + m_fdSpu = Dxr3Open("_sp", cDxr3ConfigData::Instance().GetDxr3Card(), + O_WRONLY | O_SYNC); + + if (m_fdControl < 0 || m_fdVideo < 0 || m_fdAudio < 0 || m_fdSpu <0) { - // open control stream - m_fdControl = Dxr3Open("", cDxr3ConfigData::Instance().GetDxr3Card(), O_WRONLY | O_SYNC); + ExternalReleaseDevices(); + } + else + { + m_pClock = new cDxr3SysClock(m_fdControl, m_fdVideo, m_fdSpu); + if (!m_pClock) + { + cLog::Instance() << "Unable to allocate memory for m_pClock in cDxr3Interface\n"; + exit(1); + } - // open 'multimedia' streams - m_fdVideo = Dxr3Open("_mv", cDxr3ConfigData::Instance().GetDxr3Card(), O_WRONLY | O_SYNC); - m_fdAudio = Dxr3Open("_ma", cDxr3ConfigData::Instance().GetDxr3Card(), O_WRONLY | O_SYNC); - m_fdSpu = Dxr3Open("_sp", cDxr3ConfigData::Instance().GetDxr3Card(), O_WRONLY | O_SYNC); + SetChannelCount(1); + m_ExternalReleased = false; + } - if (m_fdControl < 0 || m_fdVideo < 0 || m_fdAudio < 0 || m_fdSpu <0) - { - ExternalReleaseDevices(); - } - else - { - m_pClock = new cDxr3SysClock(m_fdControl, m_fdVideo, m_fdSpu); - if (!m_pClock) - { - cLog::Instance() << "Unable to allocate memory for m_pClock in cDxr3Interface\n"; - exit(1); - } - - SetChannelCount(1); - m_ExternalReleased = false; - } - - Resuscitation(); + Resuscitation(); } - + Unlock(); } @@ -809,18 +827,21 @@ void cDxr3Interface::PlayBlackFrame() { extern char blackframe[]; extern int blackframeLength; - + Lock(); - - if (!m_ExternalReleased) - { - if (write(m_fdVideo, blackframe, blackframeLength) < 0) Resuscitation(); - if (write(m_fdVideo, blackframe, blackframeLength) < 0) Resuscitation(); - if (write(m_fdVideo, blackframe, blackframeLength) < 0) Resuscitation(); + + if (!m_ExternalReleased) + { + if (write(m_fdVideo, blackframe, blackframeLength) < 0) + Resuscitation(); + if (write(m_fdVideo, blackframe, blackframeLength) < 0) + Resuscitation(); + if (write(m_fdVideo, blackframe, blackframeLength) < 0) + Resuscitation(); } m_horizontal = 720; m_vertical = 576; - + Unlock(); } @@ -828,28 +849,30 @@ void cDxr3Interface::PlayBlackFrame() void cDxr3Interface::ReOpenAudio() { Lock(); - - if (!m_ExternalReleased) + + if (!m_ExternalReleased) + { + if (m_fdAudio > -1) { - if (m_fdAudio > -1) - { - int bufsize = 0; - ioctl(m_fdAudio, SNDCTL_DSP_GETODELAY, &bufsize); - usleep(bufsize / 192 * 1000); - - delete m_pClock; - close(m_fdAudio); - - m_fdAudio = Dxr3Open("_ma", cDxr3ConfigData::Instance().GetDxr3Card(), O_WRONLY | O_SYNC); - - uint32_t tmpAudioDataRate = m_audioDataRate; - uint32_t tmpAudioChannelCount = m_audioChannelCount; - m_audioDataRate = m_audioChannelCount = 0; - m_pClock = new cDxr3SysClock(m_fdControl, m_fdVideo, m_fdSpu); - SetAudioSpeed(tmpAudioDataRate); - SetChannelCount(tmpAudioChannelCount); - } + int bufsize = 0; + ioctl(m_fdAudio, SNDCTL_DSP_GETODELAY, &bufsize); + usleep(bufsize / 192 * 1000); + + delete m_pClock; + close(m_fdAudio); + + m_fdAudio = Dxr3Open("_ma", + cDxr3ConfigData::Instance().GetDxr3Card(), + O_WRONLY | O_SYNC); + + uint32_t tmpAudioDataRate = m_audioDataRate; + uint32_t tmpAudioChannelCount = m_audioChannelCount; + m_audioDataRate = m_audioChannelCount = 0; + m_pClock = new cDxr3SysClock(m_fdControl, m_fdVideo, m_fdSpu); + SetAudioSpeed(tmpAudioDataRate); + SetChannelCount(tmpAudioChannelCount); } + } Unlock(); } @@ -858,7 +881,7 @@ void cDxr3Interface::ReOpenAudio() // ================================== cOsdBase* cDxr3Interface::NewOsd(int x, int y) { - return new cDxr3Osd(x, y); + return new cDxr3Osd(x, y); } #endif @@ -866,140 +889,143 @@ cOsdBase* cDxr3Interface::NewOsd(int x, int y) //! uploadroutine for microcode void cDxr3Interface::UploadMicroCode() { - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "cDxr3Interface::UploadMicroCode: uploading from " << MICROCODE << "..."; - } + if (cDxr3ConfigData::Instance().GetDebug()) + { + cLog::Instance() << "cDxr3Interface::UploadMicroCode: uploading from " + << MICROCODE << "..."; + } - em8300_microcode_t em8300_microcode; + em8300_microcode_t em8300_microcode; struct stat s; - // try to open it - // MICROCODE comes from makefile + // try to open it + // MICROCODE comes from makefile int UCODE = open(MICROCODE, O_RDONLY); - - if (UCODE <0) - { - cLog::Instance() << "Unable to open microcode file " << MICROCODE << " for reading\n"; - exit(1); + + if (UCODE <0) + { + cLog::Instance() << "Unable to open microcode file " + << MICROCODE << " for reading\n"; + exit(1); } - if (fstat(UCODE, &s ) <0) - { - cLog::Instance() << "Unable to fstat ucode file\n"; - exit(1); + if (fstat(UCODE, &s ) <0) + { + cLog::Instance() << "Unable to fstat ucode file\n"; + exit(1); } - // read microcode + // read microcode em8300_microcode.ucode = new char[s.st_size]; - if (em8300_microcode.ucode == NULL) - { - cLog::Instance() << "Unable to malloc() space for ucode\n"; - exit(1); + if (em8300_microcode.ucode == NULL) + { + cLog::Instance() << "Unable to malloc() space for ucode\n"; + exit(1); } - - if (read(UCODE,em8300_microcode.ucode,s.st_size) < 1) - { - cLog::Instance() << "Unable to read data from microcode file\n"; - // free memory to avoid memory leak - delete [] (char*) em8300_microcode.ucode; - exit(1); + + if (read(UCODE,em8300_microcode.ucode,s.st_size) < 1) + { + cLog::Instance() << "Unable to read data from microcode file\n"; + // free memory to avoid memory leak + delete [] (char*) em8300_microcode.ucode; + exit(1); } close(UCODE); em8300_microcode.ucode_size = s.st_size; - // upload it - if( ioctl(m_fdControl, EM8300_IOCTL_INIT, &em8300_microcode) == -1) - { - cLog::Instance() << "Microcode upload to failed!! \n"; - // free memory to avoid memory leak - delete [] (char*) em8300_microcode.ucode; - exit(1); + // upload it + if( ioctl(m_fdControl, EM8300_IOCTL_INIT, &em8300_microcode) == -1) + { + cLog::Instance() << "Microcode upload to failed!! \n"; + // free memory to avoid memory leak + delete [] (char*) em8300_microcode.ucode; + exit(1); } - // free memory to avoid memory leak + // free memory to avoid memory leak delete [] (char*) em8300_microcode.ucode; - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "...done\n"; - } + if (cDxr3ConfigData::Instance().GetDebug()) + { + cLog::Instance() << "...done\n"; + } } // ================================== //! config and setup device via ioctl calls void cDxr3Interface::ConfigureDevice() { - uint32_t videomode = 0; + uint32_t videomode = 0; - // set video mode - if (cDxr3ConfigData::Instance().GetVideoMode() == PAL) + // set video mode + if (cDxr3ConfigData::Instance().GetVideoMode() == PAL) + { + videomode = EM8300_VIDEOMODE_PAL; + if (cDxr3ConfigData::Instance().GetDebug()) { - videomode = EM8300_VIDEOMODE_PAL; - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "cDxr3Interface::ConfigureDevice: Videomode = PAL\n"; - } + cLog::Instance() << "cDxr3Interface::ConfigureDevice: Videomode = PAL\n"; } - else if (cDxr3ConfigData::Instance().GetVideoMode() == PAL60) + } + else if (cDxr3ConfigData::Instance().GetVideoMode() == PAL60) + { + videomode = EM8300_VIDEOMODE_PAL60; + if (cDxr3ConfigData::Instance().GetDebug()) { - videomode = EM8300_VIDEOMODE_PAL60; - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "cDxr3Interface::ConfigureDevice: Videomode = PAL60\n"; - } + cLog::Instance() << "cDxr3Interface::ConfigureDevice: Videomode = PAL60\n"; } - else + } + else + { + videomode = EM8300_VIDEOMODE_NTSC; + if (cDxr3ConfigData::Instance().GetDebug()) { - videomode = EM8300_VIDEOMODE_NTSC; - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "cDxr3Interface::ConfigureDevice: Videomode = NTSC\n"; - } + cLog::Instance() << "cDxr3Interface::ConfigureDevice: Videomode = NTSC\n"; } + } - // make ioctl - if (ioctl(m_fdControl, EM8300_IOCTL_SET_VIDEOMODE, &videomode) == -1) - { - cLog::Instance() << "Unable to set videomode\n"; - exit(1); + // make ioctl + if (ioctl(m_fdControl, EM8300_IOCTL_SET_VIDEOMODE, &videomode) == -1) + { + cLog::Instance() << "Unable to set videomode\n"; + exit(1); } - // set audio mode - if (!cDxr3ConfigData::Instance().GetUseDigitalOut()) + // set audio mode + if (!cDxr3ConfigData::Instance().GetUseDigitalOut()) + { + SetAudioAnalog(); + if (cDxr3ConfigData::Instance().GetDebug()) { - SetAudioAnalog(); - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "cDxr3Interface::ConfigureDevice: Audiomode = Analog\n"; - } + cLog::Instance() << "cDxr3Interface::ConfigureDevice: Audiomode = Analog\n"; } + } } // ================================== //! reset whole hardware -void cDxr3Interface::Resuscitation() +void cDxr3Interface::Resuscitation() { time_t startt = time(&startt); time_t endt = 0; m_ExternalReleased = true; dsyslog("cDxr3Interface::Resuscitation Device failure detected"); - + UploadMicroCode(); dsyslog("cDxr3Interface::Resuscitation Micro code upload successfully"); - -// NonBlockingCloseOpen(); + + //NonBlockingCloseOpen(); m_ExternalReleased = false; - + endt = time(&endt); - - dsyslog("cDxr3Interface::Resuscitation Reopening devices took %d", (int)(endt - startt)); - - if (endt - startt > 4) - { - exit(1); + + dsyslog("cDxr3Interface::Resuscitation Reopening devices took %d", + (int)(endt - startt)); + + if (endt - startt > 4) + { + exit(1); } ConfigureDevice(); @@ -1009,18 +1035,18 @@ void cDxr3Interface::Resuscitation() //! pcm resampling funtcion void cDxr3Interface::ResampleVolume(short* pcmbuf, int size) { - if (m_volume == 0) - { - memset(pcmbuf, 0, size); + if (m_volume == 0) + { + memset(pcmbuf, 0, size); } - else if (m_volume != 255) + else if (m_volume != 255) + { + int factor = (int)pow (2.0, (double)m_volume/32 + 8.0) - 1; + //int factor = (int)pow (2.0, (double)m_volume/16) - 1; + for (int i = 0; i < size / (int)sizeof(short); i++) { - int factor = (int)pow (2.0, (double)m_volume/32 + 8.0) - 1; - //int factor = (int)pow (2.0, (double)m_volume/16) - 1; - for (int i = 0; i < size / (int)sizeof(short); i++) - { - pcmbuf[i] = (((int)pcmbuf[i]) * factor) / 65536; - } + pcmbuf[i] = (((int)pcmbuf[i]) * factor) / 65536; + } } } @@ -1032,10 +1058,10 @@ void cDxr3Interface::ClearOsd() int x1 = 0; int& i = ed.count = 0; - // display duration... + // display duration... ed.data[i++]= 0x00; ed.data[i++]= 0x00; //durration before turn on command occurs - //in 90000/1024 units + //in 90000/1024 units // x1 ed.data[i++]= x1 >> 8; //since this is the last command block, this ed.data[i++]= x1 & 0xff; //points back to itself @@ -1046,9 +1072,9 @@ void cDxr3Interface::ClearOsd() // 0xFF: end sequence ed.data[i++]= 0xFF; - if (!i&1) - { - ed.data[i++]= 0xff; + if (!i&1) + { + ed.data[i++]= 0xff; } // x0 @@ -1059,10 +1085,10 @@ void cDxr3Interface::ClearOsd() ed.data[0]= i >> 8; ed.data[1]= i & 0xff; - if (!m_ExternalReleased) - { - WriteSpu((const uint8_t*) &ed, (int) ed.count); - ClearButton(); + if (!m_ExternalReleased) + { + WriteSpu((const uint8_t*) &ed, (int) ed.count); + ClearButton(); } } @@ -1070,17 +1096,18 @@ void cDxr3Interface::ClearOsd() void cDxr3Interface::WriteSpu(const uint8_t* pBuf, int length) { Lock(); - - if (!m_ExternalReleased) - { - if (write(m_fdSpu, pBuf, length) < 0) Resuscitation(); + + if (!m_ExternalReleased) + { + if (write(m_fdSpu, pBuf, length) < 0) Resuscitation(); } - + Unlock(); } // ================================== -void cDxr3Interface::SetButton(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t palette) +void cDxr3Interface::SetButton(uint16_t sx, uint16_t sy, uint16_t ex, + uint16_t ey, uint32_t palette) { em8300_button_t button; @@ -1112,7 +1139,7 @@ void cDxr3Interface::ClearButton() // ================================== void cDxr3Interface::SetPalette(unsigned int *pal) { - ioctl(m_fdSpu, EM8300_IOCTL_SPU_SETPALETTE, (uint8_t*)pal); + ioctl(m_fdSpu, EM8300_IOCTL_SPU_SETPALETTE, (uint8_t*)pal); } // helper functions for dxr3 main osd screen @@ -1120,9 +1147,9 @@ void cDxr3Interface::SetPalette(unsigned int *pal) //! reset dxr3 card void cDxr3Interface::ResetHardware() { - Lock(); + Lock(); - cLog::Instance() << "cDxr3Interface: Resetting DXR3 hardware\n"; + cLog::Instance() << "cDxr3Interface: Resetting DXR3 hardware\n"; Resuscitation(); Unlock(); @@ -1133,36 +1160,36 @@ void cDxr3Interface::ResetHardware() //! set brightness void cDxr3Interface::SetBrightness(int value) { - m_bcs.brightness = value; + m_bcs.brightness = value; - if (ioctl(m_fdControl, EM8300_IOCTL_SETBCS, &m_bcs) < 0) - { - cLog::Instance() << "cDxr3Interface::SetBrightness: Unable to set brightness to " << value << "\n"; - } + if (ioctl(m_fdControl, EM8300_IOCTL_SETBCS, &m_bcs) < 0) + { + cLog::Instance() << "cDxr3Interface::SetBrightness: Unable to set brightness to " << value << "\n"; + } } // ================================== //! set contrast void cDxr3Interface::SetContrast(int value) { - m_bcs.contrast = value; + m_bcs.contrast = value; - if (ioctl(m_fdControl, EM8300_IOCTL_SETBCS, &m_bcs) < 0) - { - cLog::Instance() << "cDxr3Interface::SetContrast: Unable to set contrast to " << value << "\n"; - } + if (ioctl(m_fdControl, EM8300_IOCTL_SETBCS, &m_bcs) < 0) + { + cLog::Instance() << "cDxr3Interface::SetContrast: Unable to set contrast to " << value << "\n"; + } } // ================================== //! set saturation void cDxr3Interface::SetSaturation(int value) { - m_bcs.saturation = value; + m_bcs.saturation = value; - if (ioctl(m_fdControl, EM8300_IOCTL_SETBCS, &m_bcs) < 0) - { - cLog::Instance() << "cDxr3Interface::SetSaturation: Unable to set saturation to " << value << "\n"; - } + if (ioctl(m_fdControl, EM8300_IOCTL_SETBCS, &m_bcs) < 0) + { + cLog::Instance() << "cDxr3Interface::SetSaturation: Unable to set saturation to " << value << "\n"; + } } // ================================== diff --git a/dxr3interface.h b/dxr3interface.h index 771adac..0a6a5b6 100644 --- a/dxr3interface.h +++ b/dxr3interface.h @@ -40,136 +40,170 @@ class cFixedLengthFrame; // ================================== //! interafce to dxr3-card /*! - cDxr3Interface is the interface to the dxr3 - driver and so to the card, - so this is the layer between plugin and driver. + cDxr3Interface is the interface to the dxr3 + driver and so to the card, + so this is the layer between plugin and driver. */ class cDxr3Interface : public Singleton<cDxr3Interface> { public: - cDxr3Interface(); - ~cDxr3Interface(); + cDxr3Interface(); + ~cDxr3Interface(); - // main - void Start(); - void Stop(); + // main + void Start(); + void Stop(); - // audio + // audio void SetAudioAnalog(); void SetAudioDigitalPCM(); void SetAudioDigitalAC3(); - void SetVolume(int volume) { m_volume = volume;} + void SetVolume(int volume) + { + m_volume = volume; + } void SetAudioSpeed(uint32_t speed); void SetChannelCount(uint32_t count); - void SetAudioSampleSize(uint32_t sampleSize); + void SetAudioSampleSize(uint32_t sampleSize); - // clock + // clock void SetSysClock(uint32_t scr); uint32_t GetSysClock() const; void SetPts(uint32_t pts); void SetSpuPts(uint32_t pts); int64_t GetPts(); - // state changes - void EnableSPU(); - void DisableSPU(); - void EnableVideo() { m_VideoActive = true; } - void DisableVideo() { m_VideoActive = false; } - void EnableAudio() { m_AudioActive = true; } - void DisableAudio(); - void EnableOverlay(); - void DisanleOverlay(); - - // set/get functions - uint32_t GetAspectRatio() const; - void SetAspectRatio(uint32_t ratio); - uint32_t GetHorizontalSize() const { return m_horizontal; } - void SetHorizontalSize(uint32_t horizontal) { m_horizontal = horizontal;}; - uint32_t GetVerticalSize() const { return m_vertical; } - void SetVerticalSize(uint32_t vertical) { m_vertical = vertical;}; - - // play functions + // state changes + void EnableSPU(); + void DisableSPU(); + void EnableVideo() + { + m_VideoActive = true; + } + void DisableVideo() + { + m_VideoActive = false; + } + void EnableAudio() + { + m_AudioActive = true; + } + void DisableAudio(); + void EnableOverlay(); + void DisanleOverlay(); + + // set/get functions + uint32_t GetAspectRatio() const; + void SetAspectRatio(uint32_t ratio); + uint32_t GetHorizontalSize() const + { + return m_horizontal; + } + void SetHorizontalSize(uint32_t horizontal) + { + m_horizontal = horizontal; + }; + uint32_t GetVerticalSize() const + { + return m_vertical; + } + void SetVerticalSize(uint32_t vertical) + { + m_vertical = vertical; + }; + + // play functions void SetPlayMode(); void Pause(); void SingleStep(); - void PlayVideoFrame(cFixedLengthFrame* pFrame, int times = 1); + void PlayVideoFrame(cFixedLengthFrame* pFrame, int times = 1); void PlayVideoFrame(const uint8_t* pBuf, int length, int times = 1); void PlayAudioFrame(cFixedLengthFrame* pFrame); void PlayAudioFrame(uint8_t* pBuf, int length); void PlayAudioLpcmFrame(uint8_t* pBuf, int length); - // external device access + // external device access void ExternalReleaseDevices(); void ExternalReopenDevices(); - bool IsExternalReleased() const { return m_ExternalReleased; } + bool IsExternalReleased() const + { + return m_ExternalReleased; + } - // tools - void PlayBlackFrame(); - void ReOpenAudio(); + // tools + void PlayBlackFrame(); + void ReOpenAudio(); - // osd/spu - #if VDRVERSNUM < 10307 - cOsdBase* NewOsd(int x, int y); - #endif + // osd/spu +#if VDRVERSNUM < 10307 + cOsdBase* NewOsd(int x, int y); +#endif void ClearOsd(); void WriteSpu(const uint8_t* pBuf, int length); - void SetButton(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t palette); + void SetButton(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, + uint32_t palette); void ClearButton(); void SetPalette(unsigned int *pal = NULL); - // overlay functions + // overlay functions - // helper functions for dxr3 main osd screen - void ResetHardware(); + // helper functions for dxr3 main osd screen + void ResetHardware(); - // set brightness/contrast/saturation - void SetBrightness(int value); - void SetContrast(int value); - void SetSaturation(int value); + // set brightness/contrast/saturation + void SetBrightness(int value); + void SetContrast(int value); + void SetSaturation(int value); private: - // file handles - int m_fdControl; ///< filehandle for contol fifo of dxr3 card + // file handles + int m_fdControl; ///< filehandle for contol fifo of dxr3 card int m_fdVideo; ///< filehandle for video fifo of dxr3 card int m_fdAudio; ///< filehandle for audio fifo of dxr3 card int m_fdSpu; ///< filehandle for spu fifo of dxr3 card uint32_t m_lastSeenPts; - // dxr3 clock - cDxr3SysClock* m_pClock; ///< clock used for sync - - uint32_t m_audioChannelCount; ///< how many channles has the current audiostream - uint32_t m_audioDataRate; ///< which rate is used for the current audiostream - int m_aspectDelayCounter; - uint32_t m_aspectRatio; ///< current used aspect ratio - uint32_t m_horizontal; ///< horizontal size of current videostream - uint32_t m_vertical; ///< vertical size of current videostream - uint32_t m_audioSampleSize; ///< how big is the sample size for the current audiostream - uint32_t m_audioMode; - uint32_t m_spuMode; - bool m_ExternalReleased; // is dxr3 used by e.g. mplayer? - int m_volume; ///< volumevalue (0...255) - bool m_AudioActive; ///< is audio active? - bool m_VideoActive; ///< is video active? - bool m_OverlayActive; ///< is overlay active? - - // bcs - em8300_bcs_t m_bcs; ///< BrightnessContrastSaturation values - - // spu -// cDxr3InterfaceSpu m_SpuInterface; - - void UploadMicroCode(); - void ConfigureDevice(); - void ResampleVolume(short* pcmbuf, int size); - void Resuscitation(); + // dxr3 clock + cDxr3SysClock* m_pClock; ///< clock used for sync + + uint32_t m_audioChannelCount; ///< how many channles has the current audiostream + uint32_t m_audioDataRate; ///< which rate is used for the current audiostream + int m_aspectDelayCounter; + uint32_t m_aspectRatio; ///< current used aspect ratio + uint32_t m_horizontal; ///< horizontal size of current videostream + uint32_t m_vertical; ///< vertical size of current videostream + uint32_t m_audioSampleSize; ///< how big is the sample size for the current audiostream + uint32_t m_audioMode; + uint32_t m_spuMode; + bool m_ExternalReleased; // is dxr3 used by e.g. mplayer? + int m_volume; ///< volumevalue (0...255) + bool m_AudioActive; ///< is audio active? + bool m_VideoActive; ///< is video active? + bool m_OverlayActive; ///< is overlay active? + + // bcs + em8300_bcs_t m_bcs; ///< BrightnessContrastSaturation values + + // spu + //cDxr3InterfaceSpu m_SpuInterface; + + void UploadMicroCode(); + void ConfigureDevice(); + void ResampleVolume(short* pcmbuf, int size); + void Resuscitation(); protected: - static cMutex* m_pMutex; ///< mutex for dxr3interface - - static void Lock() { cDxr3Interface::m_pMutex->Lock(); } - static void Unlock() { cDxr3Interface::m_pMutex->Unlock(); } + static cMutex* m_pMutex; ///< mutex for dxr3interface + + static void Lock() + { + cDxr3Interface::m_pMutex->Lock(); + } + static void Unlock() + { + cDxr3Interface::m_pMutex->Unlock(); + } }; #endif /*_DXR3_INTERFACE_H_*/ diff --git a/dxr3interface_spu_encoder.c b/dxr3interface_spu_encoder.c index eb6daec..4db1f37 100644 --- a/dxr3interface_spu_encoder.c +++ b/dxr3interface_spu_encoder.c @@ -30,8 +30,8 @@ #include "dxr3tools.h" /* -ToDo: - - cSPUEncoder::encode_do_row: FIXME: watch this space for EOL + ToDo: + - cSPUEncoder::encode_do_row: FIXME: watch this space for EOL */ @@ -39,9 +39,9 @@ ToDo: /*======================================================================= * * Scaling functions taken from the xine plugin - * + * */ - + #include <math.h> #include <signal.h> #include <string> @@ -50,168 +50,156 @@ ToDo: namespace XineScaler { - template <const int yInc = 1, class T = int> + template <const int yInc = 1, class T = int> class cBresenham - { - const int m_dx; - const int m_dy; - - int m_eps; - T m_y; - - public: - cBresenham(const int dy, const int dx, const int eps, T const y0 = 0) - : m_dx(dx) - , m_dy(dy) - , m_eps(eps - m_dx) - , m_y(y0) - { - } - - int eps() const - { - return m_eps; - } - - T step() { - m_eps += m_dy; + const int m_dx; + const int m_dy; - while (m_eps >= 0) - { - m_eps -= m_dx; + int m_eps; + T m_y; - m_y += yInc; - } + public: + cBresenham(const int dy, const int dx, const int eps, T const y0 = 0) + : m_dx(dx), m_dy(dy), m_eps(eps - m_dx), m_y(y0) + { + } - return m_y; - } + int eps() const + { + return m_eps; + } - T step(int n) - { - if (n <= 0) - return m_y; - - while (--n > 0) - step(); + T step() + { + m_eps += m_dy; + while (m_eps >= 0) + { + m_eps -= m_dx; + m_y += yInc; + } + return m_y; + } - return step(); - } + T step(int n) + { + if (n <= 0) + return m_y; + while (--n > 0) + step(); + return step(); + } - T stepRelative(int n = 1) - { - T const y = m_y; - - return step(n) - y; - } - }; + T stepRelative(int n = 1) + { + T const y = m_y; + return step(n) - y; + } + }; - static uint8_t *ScaleBitmapLQ(const uint8_t *src, uint8_t *dest, int x0, int y0, int w, int h, int ws, int hs, int x1, int y1, int w1, int h1, const uint8_t transparentIndex) - { - uint8_t *const screen = new uint8_t[ OSDHEIGHT * OSDWIDTH ]; - { - int x1 = x0 + w; - int y1 = y0 + h; - int x2 = OSDWIDTH; - int y2 = OSDHEIGHT; - - if (x1 > x2) - x1 = x2; - - if (y1 > y2) - y1 = y2; - - uint8_t *dst = screen; - - for (int y = 0; y < y0; y++) - { - for (int x = 0; x < x2; x++) - *dst++ = transparentIndex; - } - - for (int y = y0; y < y1; y++) - { - for (int x = 0; x < x0; x++) - *dst++ = transparentIndex; - - for (int x = x0; x < x1; x++) - *dst++ = *src++; - - for (int x = x1; x < x2; x++) - *dst++ = transparentIndex; - } - - for (int y = y1; y < y2; y++) - { - for (int x = 0; x < x2; x++) - *dst++ = transparentIndex; - } - } - - uint8_t *scaled = dest; //new uint8_t[ hs * ws ]; + static uint8_t *ScaleBitmapLQ(const uint8_t *src, uint8_t *dest, int x0, + int y0, int w, int h, int ws, int hs, int x1, + int y1, int w1, int h1, + const uint8_t transparentIndex) { - int x2 = x1 + w1; - int y2 = y1 + h1; - - if (x2 > ws) - { - x2 = ws; - - w1 = x2 - x1; - if (w1 < 0) - w1 = 0; - } - - if (y2 > hs) - { - y2 = hs; - - h1 = y2 - y1; - if (h1 < 0) - h1 = 0; - } - - cBresenham<OSDWIDTH, uint8_t *> yyBh(2 * OSDHEIGHT, 2 * hs, hs, screen); - uint8_t *screen0 = yyBh.step(y1); //(((2 * y1 + 1) * OSDHEIGHT / hs) / 2); - - cBresenham<> xxBh0(2 * OSDWIDTH, 2 * ws, ws); - xxBh0.step(x1); //(((2 * x1 + 1) * OSDWIDTH / ws) / 2); - - uint8_t *scaled0 = scaled + y1 * OSDWIDTH; //ws; ****** - - for (int y = y1; y < y2; y++) - { - cBresenham<> xxBh(xxBh0); - int xxx = xxBh.step(0); //(((2 * x1 + 1) * OSDWIDTH / ws) / 2); - - uint8_t *screen00 = screen0 + xxx; - - uint8_t *scaled00 = scaled0 + x1; - - for (int x = x1; x < x2; x++) - { - *scaled00++ = *screen00; + uint8_t *const screen = new uint8_t[ OSDHEIGHT * OSDWIDTH ]; + { + int x1 = x0 + w; + int y1 = y0 + h; + int x2 = OSDWIDTH; + int y2 = OSDHEIGHT; + + if (x1 > x2) + x1 = x2; + + if (y1 > y2) + y1 = y2; + + uint8_t *dst = screen; + + for (int y = 0; y < y0; y++) + { + for (int x = 0; x < x2; x++) + *dst++ = transparentIndex; + } + + for (int y = y0; y < y1; y++) + { + for (int x = 0; x < x0; x++) + *dst++ = transparentIndex; + + for (int x = x0; x < x1; x++) + *dst++ = *src++; + + for (int x = x1; x < x2; x++) + *dst++ = transparentIndex; + } + + for (int y = y1; y < y2; y++) + { + for (int x = 0; x < x2; x++) + *dst++ = transparentIndex; + } + } - screen00 += xxBh.stepRelative(); - } + uint8_t *scaled = dest; //new uint8_t[ hs * ws ]; + { + int x2 = x1 + w1; + int y2 = y1 + h1; + + if (x2 > ws) + { + x2 = ws; + w1 = x2 - x1; + if (w1 < 0) + w1 = 0; + } + + if (y2 > hs) + { + y2 = hs; + h1 = y2 - y1; + if (h1 < 0) + h1 = 0; + } + + cBresenham<OSDWIDTH, uint8_t *> yyBh(2 * OSDHEIGHT, 2 * hs, hs, screen); + uint8_t *screen0 = yyBh.step(y1); //(((2 * y1 + 1) * OSDHEIGHT / hs) / 2); + + cBresenham<> xxBh0(2 * OSDWIDTH, 2 * ws, ws); + xxBh0.step(x1); //(((2 * x1 + 1) * OSDWIDTH / ws) / 2); + + uint8_t *scaled0 = scaled + y1 * OSDWIDTH; //ws; ****** + + for (int y = y1; y < y2; y++) + { + cBresenham<> xxBh(xxBh0); + int xxx = xxBh.step(0); //(((2 * x1 + 1) * OSDWIDTH / ws) / 2); + + uint8_t *screen00 = screen0 + xxx; + uint8_t *scaled00 = scaled0 + x1; + + for (int x = x1; x < x2; x++) + { + *scaled00++ = *screen00; + screen00 += xxBh.stepRelative(); + } - scaled0 += OSDWIDTH; //ws; ******* + scaled0 += OSDWIDTH; //ws; ******* + screen0 = yyBh.step(); + } + } - screen0 = yyBh.step(); - } + delete [] screen; + return scaled; } - delete [] screen; - - return scaled; - } - }; /*======================================================================= * * End of scaling functions taken from the xine plugin - * + * */ #endif /* USE_XINE_SCALER */ @@ -220,30 +208,29 @@ namespace XineScaler // dec. cSpuData::~cSpuData() { - Clear(); + Clear(); } // ================================== // free buffer and set it to 0 void cSpuData::Clear() { - if (data) - { - free(data); - count = malloc_size = 0; - } + if (data) + { + free(data); + count = malloc_size = 0; + } } // ================================== // wirte a byte to spu buffer void cSpuData::WriteByte(uint8_t byte) { - if (count >= malloc_size) - { - data = (u_char*)realloc(data, malloc_size += 2048); - } - - data[count++] = byte; + if (count >= malloc_size) + { + data = (u_char*) realloc(data, malloc_size += 2048); + } + data[count++] = byte; } // ================================== @@ -256,19 +243,16 @@ void cSpuData::WriteRle(int *higher_nibble, int length, int color) { } - - - // ================================== -cSPUEncoder::cSPUEncoder() +cSPUEncoder::cSPUEncoder() { - // clear osd - memset(OSD_Screen, 0x00 ,OSDWIDTH * OSDHEIGHT); - memset(OSD_Screen2, 0x00 ,OSDWIDTH * OSDHEIGHT); - memset(OSD_Screen3, 0x00 ,OSDWIDTH * OSDHEIGHT); + // clear osd + memset(OSD_Screen, 0x00, OSDWIDTH * OSDHEIGHT); + memset(OSD_Screen2, 0x00, OSDWIDTH * OSDHEIGHT); + memset(OSD_Screen3, 0x00, OSDWIDTH * OSDHEIGHT); - // set active area to 0 - //m_x0 = m_x1 = m_y0 = m_y1 = 0; + // set active area to 0 + //m_x0 = m_x1 = m_y0 = m_y1 = 0; } @@ -277,17 +261,20 @@ cSPUEncoder::cSPUEncoder() //window taking into account the global //palette (with colors needed by all windows) -void cSPUEncoder::SetPalette(int numWindow, cPalette* commonPalette, cPalette* windowPalette) +void cSPUEncoder::SetPalette(int numWindow, cPalette* commonPalette, + cPalette* windowPalette) { - int NumColors; - const tColor *Colors = windowPalette->Colors(NumColors); - if (Colors) { - for (int i=0; i<NumColors; i++) { - int idx=commonPalette->Index(Colors[i] & 0x00FFFFFF); - int opacity=((Colors[i] & 0xFF000000) >> 24) * 0xF / 0xFF; - bitmapcolor[numWindow][i]=(opacity<<4) | idx; - } - } + int NumColors; + const tColor *Colors = windowPalette->Colors(NumColors); + if (Colors) + { + for (int i = 0; i < NumColors; i++) + { + int idx = commonPalette->Index(Colors[i] & 0x00FFFFFF); + int opacity = ((Colors[i] & 0xFF000000) >> 24) * 0xF / 0xFF; + bitmapcolor[numWindow][i] = (opacity<<4) | idx; + } + } } //======================================== @@ -295,73 +282,89 @@ void cSPUEncoder::SetPalette(int numWindow, cPalette* commonPalette, cPalette* w void cSPUEncoder::Clear(void) { - memset(OSD_Screen, 0 , sizeof(OSD_Screen)); + memset(OSD_Screen, 0, sizeof(OSD_Screen)); } //============================================================= //Sets the spu palette and flushes the OSD content into the spu int cSPUEncoder::Flush(cPalette *Palette) { + int NumColors; + const tColor *Colors = Palette->Colors(NumColors); + if (Colors) + { + unsigned int palcolors[16]; + for (int i = 0; i < NumColors; i++) + { + // convert AARRGGBB to AABBGGRR (the driver expected the the + // colors the wrong way, so does Rgb2YCrCb and friends) + unsigned int color = ((Colors[i] & 0x0000FF) << 16) + | (Colors[i] & 0x00FF00) | ((Colors[i] & 0xFF0000) >> 16); + palcolors[i] = Tools::Rgb2YCrCb(color); + } + cDxr3Interface::Instance().SetPalette(palcolors); + } + + // calculate osd size (actually dead code) + CalculateActiveOsdArea(); + + /* + cLog::Instance() << "(" << m_x0 << ", " << m_x1 << ") - (" + << m_y0 << ", " << m_y1 << ")"; + */ - int NumColors; - const tColor *Colors = Palette->Colors(NumColors); - if (Colors) { - unsigned int palcolors[16]; - for (int i=0; i<NumColors; i++) { - // convert AARRGGBB to AABBGGRR (the driver expected the the colors the wrong way, so does Rgb2YCrCb and friends) - unsigned int color = ((Colors[i] & 0x0000FF) << 16) | (Colors[i] & 0x00FF00) | ((Colors[i] & 0xFF0000) >> 16); - palcolors[i]=Tools::Rgb2YCrCb(color); + m_encodeddata.count = 0; + EncodePixelbufRle(0, 0, OSDWIDTH, OSDHEIGHT-1, OSD_Screen, 0, + &m_encodeddata); + + if (cDxr3ConfigData::Instance().GetDebug()) + { + cLog::Instance() << "OSD Datasize: " << m_encodeddata.count << "\n"; + } + + if (m_encodeddata.count <= DATASIZE) + { + cDxr3Interface::Instance().WriteSpu((uint8_t*) &m_encodeddata, + m_encodeddata.count); + return 0; + } + else + { + cLog::Instance() << "Warning: SPU data (" << m_encodeddata.count + << ") size exceeds limit\n"; + return -1; } - cDxr3Interface::Instance().SetPalette(palcolors); - } - - // calculate osd size (actually dead code) - CalculateActiveOsdArea(); - - //cLog::Instance() << "(" << m_x0 << ", " << m_x1 << ") - (" << m_y0 << ", " << m_y1 << ")"; - - m_encodeddata.count = 0; - EncodePixelbufRle(0,0, OSDWIDTH, OSDHEIGHT-1, OSD_Screen, 0, &m_encodeddata); - - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "OSD Datasize: " << m_encodeddata.count << "\n"; - } - - if (m_encodeddata.count <= DATASIZE) - { - cDxr3Interface::Instance().WriteSpu((uint8_t*) &m_encodeddata, m_encodeddata.count); - return 0; - } else - { - cLog::Instance() << "Warning: SPU data (" << m_encodeddata.count << ") size exceeds limit\n"; - return -1; - } } // ================================== // stamps window content into full osd bitmap -void cSPUEncoder::CopyBlockIntoOSD(int numWindow, int linewidth, int x0, int y0, int x1, int y1, const tIndex *data) +void cSPUEncoder::CopyBlockIntoOSD(int numWindow, int linewidth, int x0, + int y0, int x1, int y1, const tIndex *data) { tIndex *cp; const tIndex *sp = data; - - if (x1>=OSDWIDTH) x1=OSDWIDTH-1; - if (y1>=OSDHEIGHT) y1=OSDHEIGHT-1; - cp = &OSD_Screen[y0*OSDWIDTH+x0]; - - for (int y = y0; y <= y1; y++) { - for (int x=x0; x <= x1; x++) { - *(cp++) = bitmapcolor[numWindow][*(sp++) & 0x0f]; - } - cp+=OSDWIDTH-(x1-x0+1); - sp+=linewidth-(x1-x0+1); + + if (x1 >= OSDWIDTH) + x1 = OSDWIDTH - 1; + if (y1 >= OSDHEIGHT) + y1 = OSDHEIGHT - 1; + cp = &OSD_Screen[y0 * OSDWIDTH + x0]; + + for (int y = y0; y <= y1; y++) + { + for (int x = x0; x <= x1; x++) + { + *(cp++) = bitmapcolor[numWindow][*(sp++) & 0x0f]; + } + cp += OSDWIDTH - (x1 - x0 + 1); + sp += linewidth - (x1 - x0 + 1); } } // ================================== // taken from mplayer (spuenc.c) -void cSPUEncoder::EncodePixelbufRle(int x, int y, int w, int h, u_char *inbuf, int stride, encodedata *ed) +void cSPUEncoder::EncodePixelbufRle(int x, int y, int w, int h, u_char *inbuf, + int stride, encodedata *ed) { pixbuf pb; int i, row; @@ -371,311 +374,317 @@ void cSPUEncoder::EncodePixelbufRle(int x, int y, int w, int h, u_char *inbuf, i #ifdef USE_XINE_SCALER int ws = cDxr3Interface::Instance().GetHorizontalSize(); int hs = cDxr3Interface::Instance().GetVerticalSize(); - if (ws < 720 || hs < 576 ) - inbuf = XineScaler::ScaleBitmapLQ(inbuf, OSD_Screen2, 0, 0, OSDWIDTH, OSDHEIGHT, ws, hs, 0, 0, ws, hs, 0 /* clrTransparent */); + if (ws < 720 || hs < 576) + inbuf = XineScaler::ScaleBitmapLQ(inbuf, OSD_Screen2, 0, 0, OSDWIDTH, + OSDHEIGHT, ws, hs, 0, 0, ws, hs, + 0 /* clrTransparent */); #else - if (cDxr3Interface::Instance().GetHorizontalSize() < 700) - { - double fac = (double)OSDWIDTH / (double)OSDWIDTH2; - ScaleOSD(fac, inbuf,10); - inbuf = OSD_Screen2; + if (cDxr3Interface::Instance().GetHorizontalSize() < 700) + { + double fac = (double)OSDWIDTH / (double)OSDWIDTH2; + ScaleOSD(fac, inbuf, 10); + inbuf = OSD_Screen2; } #endif /* USE_XINE_SCALER */ m_ColorManager = new cColorManager(); - // Encode colors into highlight regions + // Encode colors into highlight regions m_ColorManager->EncodeColors(w, h, inbuf, OSD_Screen3); inbuf = OSD_Screen3; pb.pixels = inbuf; - ed->count= 4; - ed->nibblewaiting= 0; + ed->count = 4; + ed->nibblewaiting = 0; - row= 0; - for (i= 0; i < pb.y; i++) + row = 0; + for (i = 0; i < pb.y; i++) + { + encode_do_row(ed, &pb, row); + row += 2; + if (row > pb.y) { - encode_do_row(ed, &pb, row); - row+= 2; - if (row > pb.y) - { - row= 1; - ed->oddstart= ed->count; - } + row = 1; + ed->oddstart = ed->count; + } } - encode_do_control(x,y, ed, &pb); + encode_do_control(x, y, ed, &pb); delete m_ColorManager; } #ifndef USE_XINE_SCALER // ================================== -void cSPUEncoder::ScaleOSD(double fac, unsigned char* buf, unsigned char NumColors) +void cSPUEncoder::ScaleOSD(double fac, unsigned char* buf, + unsigned char NumColors) { - int y,x,s,d; + int y, x, s, d; unsigned char dline[2 * OSDWIDTH + 10]; - memset(OSD_Screen2, 0x00 ,OSDWIDTH * OSDHEIGHT); + memset(OSD_Screen2, 0x00, OSDWIDTH * OSDHEIGHT); if (cDxr3Interface::Instance().GetHorizontalSize() < 470) { for (y = 0; y < OSDHEIGHT; y++) for (s = 0, d = 0; d < OSDWIDTH; s++, d += 2) OSD_Screen2[y * OSDWIDTH + s] = buf[y * OSDWIDTH + d]; - } else { - for (y = 0; y < OSDHEIGHT; y++) - { - memset(dline,0,2*OSDWIDTH+10); - - for (s=0,d=0; s < OSDWIDTH; s++,d+=2) - { - // stretch line to double width to 1440 - dline[d] = buf[y*OSDWIDTH + s]; - } - - for (d=1; d < (2*OSDWIDTH); d+=2) - { - #if VDRVERSNUM <= 10307 - // 'interpolate' values - if ((dline[d-1] == BLACK) || (dline[d+1] == BLACK)) - { - dline[d] = BLACK; - } - else if ((dline[d-1] == WHITE) || (dline[d+1] == WHITE)) - { - dline[d] = WHITE; - } - else if ((dline[d-1] == CYAN) || (dline[d+1] == CYAN)) - { - dline[d] = CYAN; - } - else - { - dline[d] = dline[d+1]; - } - #else /*VDRVERSNUM*/ - dline[d] = dline[d+1]; - #endif /*VDRVERSNUM*/ - } - - for (s=0, x = 0; x < OSDWIDTH2; x++,s+=3) - { - // now take every third pixel (1440/3=480) - OSD_Screen2[y * OSDWIDTH + x] = dline[s]; - } } + else + { + for (y = 0; y < OSDHEIGHT; y++) + { + memset(dline, 0, 2 * OSDWIDTH + 10); + + for (s = 0, d = 0; s < OSDWIDTH; s++, d += 2) + { + // stretch line to double width to 1440 + dline[d] = buf[y * OSDWIDTH + s]; + } + + for (d = 1; d < (2 * OSDWIDTH); d += 2) + { +#if VDRVERSNUM <= 10307 + // 'interpolate' values + if ((dline[d - 1] == BLACK) || (dline[d + 1] == BLACK)) + { + dline[d] = BLACK; + } + else if ((dline[d - 1] == WHITE) || (dline[d + 1] == WHITE)) + { + dline[d] = WHITE; + } + else if ((dline[d - 1] == CYAN) || (dline[d + 1] == CYAN)) + { + dline[d] = CYAN; + } + else + { + dline[d] = dline[d + 1]; + } +#else /*VDRVERSNUM*/ + dline[d] = dline[d + 1]; +#endif /*VDRVERSNUM*/ + } + + for (s = 0, x = 0; x < OSDWIDTH2; x++, s += 3) + { + // now take every third pixel (1440/3=480) + OSD_Screen2[y * OSDWIDTH + x] = dline[s]; + } + } } } #endif /* not USE_XINE_SCALER */ // ================================== // taken from mplayer (spuenc.c) -void cSPUEncoder::encode_put_nibble(encodedata* ed, u_char nibble) +void cSPUEncoder::encode_put_nibble(encodedata* ed, u_char nibble) { - if (ed->nibblewaiting) - { - ed->data[ed->count++]|= nibble; - ed->nibblewaiting= 0; - } - else - { - ed->data[ed->count]= nibble<<4; - ed->nibblewaiting= 1; + if (ed->nibblewaiting) + { + ed->data[ed->count++] |= nibble; + ed->nibblewaiting = 0; + } + else + { + ed->data[ed->count] = nibble << 4; + ed->nibblewaiting = 1; } } // ================================== // taken from mplayer (spuenc.c) -void cSPUEncoder::encode_pixels(encodedata* ed, int color, int number) +void cSPUEncoder::encode_pixels(encodedata* ed, int color, int number) { - if (number > 3) + if (number > 3) + { + if (number > 15) { - if (number > 15) - { - encode_put_nibble(ed, 0); - if (number > 63) - { - encode_put_nibble(ed, (number & 0xC0)>>6); - } - } - encode_put_nibble(ed, (number & 0x3C)>>2); + encode_put_nibble(ed, 0); + if (number > 63) + { + encode_put_nibble(ed, (number & 0xC0) >> 6); + } + } + encode_put_nibble(ed, (number & 0x3C) >> 2); } - encode_put_nibble(ed, ((number & 0xF)<<2) | color); + encode_put_nibble(ed, ((number & 0xF) << 2) | color); } // ================================== // taken from mplayer (spuenc.c) -void cSPUEncoder::encode_eol(encodedata* ed) +void cSPUEncoder::encode_eol(encodedata* ed) { - if (ed->nibblewaiting) - { - ed->count++; - ed->nibblewaiting= 0; + if (ed->nibblewaiting) + { + ed->count++; + ed->nibblewaiting = 0; } - ed->data[ed->count++]= 0x00; - ed->data[ed->count++]= 0x00; + ed->data[ed->count++] = 0x00; + ed->data[ed->count++] = 0x00; } // ================================== // taken from mplayer (spuenc.c) -void cSPUEncoder::encode_do_row(encodedata* ed, pixbuf* pb, int row) +void cSPUEncoder::encode_do_row(encodedata* ed, pixbuf* pb, int row) { - int i= 0; - u_char* pix= pb->pixels + row * pb->x; - int color= *pix & 0x03; - int n= 0; /* the number of pixels of this color */ + int i = 0; + u_char* pix = pb->pixels + row * pb->x; + int color = *pix & 0x03; + int n = 0; /* the number of pixels of this color */ while (i++ < pb->x) + { + /* FIXME: watch this space for EOL */ + if ((*pix & 0x03) != color || n == 255) { - /* FIXME: watch this space for EOL */ - if ((*pix & 0x03) != color || n == 255 ) - { - encode_pixels( ed, color, n ); - color= *pix & 0x03; - n= 1; - } - else - { - n++; - } - pix++; + encode_pixels(ed, color, n); + color = *pix & 0x03; + n = 1; + } + else + { + n++; + } + pix++; } /* this small optimization: (n>63) can save up to two bytes per line * I wonder if this is compatible with all the hardware... */ - if (color == 0 && n > 63) - { - encode_eol( ed ); - } - else - { - encode_pixels( ed, color, n ); + if (color == 0 && n > 63) + { + encode_eol(ed); + } + else + { + encode_pixels(ed, color, n); } - if (ed->nibblewaiting) - { - ed->count++; - ed->nibblewaiting= 0; + if (ed->nibblewaiting) + { + ed->count++; + ed->nibblewaiting = 0; } } // ================================== // taken from mplayer (spuenc.c) -void cSPUEncoder::encode_do_control(int x,int y, encodedata* ed, pixbuf* pb) +void cSPUEncoder::encode_do_control(int x, int y, encodedata* ed, pixbuf* pb) { - int controlstart= ed->count; + int controlstart = ed->count; int x1; int i; u_int top, left, bottom, right; - top= y; //this forces the first bit to be visible on a TV - left= x; //you could actually pass in x/y and do some nice + top = y; //this forces the first bit to be visible on a TV + left = x; //you could actually pass in x/y and do some nice - bottom= top + pb->y - 1; - right= left + pb->x - 1; + bottom = top + pb->y - 1; + right = left + pb->x - 1; /* start at x0+2*/ - i= controlstart; + i = controlstart; - x1= (i); //marker for last command block address + x1 = (i); //marker for last command block address /* display duration... */ - ed->data[i++]= 0x00; - ed->data[i++]= 0x00; //duration before turn on command occurs (will not be used) + ed->data[i++] = 0x00; + ed->data[i++] = 0x00; //duration before turn on command occurs (will not be used) /* x1 */ - ed->data[i++]= x1 >> 8; //since this is the last command block, this - ed->data[i++]= x1 & 0xff;//points back to itself + ed->data[i++] = x1 >> 8; //since this is the last command block, this + ed->data[i++] = x1 & 0xff; //points back to itself /* 0x00: force displaying */ - ed->data[i++]= 0x00; + ed->data[i++] = 0x00; /* 0x03: palette info */ - ed->data[i++]= 0x03; - ed->data[i++]= 0x01; - ed->data[i++]= 0x23; + ed->data[i++] = 0x03; + ed->data[i++] = 0x01; + ed->data[i++] = 0x23; /* 0x04: transparency info (reversed) */ - ed->data[i++]= 0x04; // SET_CONTR - ed->data[i++]= 0xFF; - ed->data[i++]= 0x70; + ed->data[i++] = 0x04; // SET_CONTR + ed->data[i++] = 0xFF; + ed->data[i++] = 0x70; /* 0x05: coordinates */ - ed->data[i++]= 0x05; // SET_DAREA - ed->data[i++]= left >> 4; - ed->data[i++]= ((left&0xf)<<4)+(right>>8); - ed->data[i++]= (right&0xff); - ed->data[i++]= top >> 4; - ed->data[i++]= ((top&0xf)<<4)+(bottom>>8); - ed->data[i++]= (bottom&0xff); + ed->data[i++] = 0x05; // SET_DAREA + ed->data[i++] = left >> 4; + ed->data[i++] = ((left & 0xf) << 4) + (right >> 8); + ed->data[i++] = (right & 0xff); + ed->data[i++] = top >> 4; + ed->data[i++] = ((top&0xf) << 4) + (bottom >> 8); + ed->data[i++] = (bottom&0xff); /* 0x06: both fields' offsets */ - ed->data[i++]= 0x06; // SET_DSPXA - ed->data[i++]= 0x00; - ed->data[i++]= 0x04; - ed->data[i++]= ed->oddstart >> 8; - ed->data[i++]= ed->oddstart & 0xff; + ed->data[i++] = 0x06; // SET_DSPXA + ed->data[i++] = 0x00; + ed->data[i++] = 0x04; + ed->data[i++] = ed->oddstart >> 8; + ed->data[i++] = ed->oddstart & 0xff; int len; unsigned char *spudata; spudata = m_ColorManager->GetSpuData(len); //check that the highlight regions data wont overflow the buffer - if(i+len+2>DATASIZE) { - ed->count=DATASIZE+1; - return; + if (i + len + 2 > DATASIZE) + { + ed->count = DATASIZE + 1; + return; } - for (int si= 0; si < len; si++) - { - ed->data[i++] = *(spudata + si); + for (int si = 0; si < len; si++) + { + ed->data[i++] = *(spudata + si); } /* 0xFF: end sequence */ ed->data[i++]= 0xFF; - if (! i&1 ) - { - ed->data[i++]= 0xff; + if (! i&1) + { + ed->data[i++]= 0xff; } /* x0 */ - ed->data[2]= (controlstart) >> 8; - ed->data[3]= (controlstart) & 0xff; + ed->data[2] = (controlstart) >> 8; + ed->data[3] = (controlstart) & 0xff; /* packet size */ - ed->data[0]= i >> 8; - ed->data[1]= i & 0xff; + ed->data[0] = i >> 8; + ed->data[1] = i & 0xff; - ed->count= i; + ed->count = i; } // ================================== // Stop spu display -void cSPUEncoder::StopSpu(void) +void cSPUEncoder::StopSpu(void) { uint8_t ed[10]; /* packet size */ - ed[0]= 0; - ed[1]= 10; - + ed[0] = 0; + ed[1] = 10; + /* pointer to the SP_DCSQT */ - ed[2]= 0; - ed[3]= 4; - + ed[2] = 0; + ed[3] = 4; + /* SP_DCSQT */ /* display duration... */ - ed[4]= 0x00; - ed[5]= 0x00; //duration before turn on command occurs (will not be used) + ed[4] = 0x00; + ed[5] = 0x00; //duration before turn on command occurs (will not be used) /* pointer to next command block */ - ed[6]= 0; //since this is the last command block, this - ed[7]= 4;//points back to itself + ed[6] = 0; //since this is the last command block, this + ed[7] = 4;//points back to itself /* 0x02: stop displaying */ - ed[8]= 0x02; + ed[8] = 0x02; /* 0xFF: end sequence */ - ed[9]= 0xFF; + ed[9] = 0xFF; cDxr3Interface::Instance().WriteSpu(ed, 10); } @@ -683,18 +692,19 @@ void cSPUEncoder::StopSpu(void) // we _only_ write usefull data void cSPUEncoder::CalculateActiveOsdArea() { - // reset - //m_x0 = m_x1 = m_y0 = m_y1 = 0; + // reset + //m_x0 = m_x1 = m_y0 = m_y1 = 0; - // calculate -/* for (int i = 1; i < 8; i++) - { - m_x0 = max(m_x0, m_windows[i].x0); - m_x1 = max(m_x1, m_windows[i].y0); - m_y0 = max(m_y0, m_windows[i].x1); - m_y1 = max(m_y1, m_windows[i].y1); - } -*/ + // calculate + /* + for (int i = 1; i < 8; i++) + { + m_x0 = max(m_x0, m_windows[i].x0); + m_x1 = max(m_x1, m_windows[i].y0); + m_y0 = max(m_y0, m_windows[i].x1); + m_y1 = max(m_y1, m_windows[i].y1); + } + */ } // Local variables: diff --git a/dxr3interface_spu_encoder.h b/dxr3interface_spu_encoder.h index 09fdc2a..2e7027e 100644 --- a/dxr3interface_spu_encoder.h +++ b/dxr3interface_spu_encoder.h @@ -48,12 +48,12 @@ // used to get active osd area struct sRectal { - sRectal() : x0(0), x1(0), y0(0), y1(0) {} + sRectal() : x0(0), x1(0), y0(0), y1(0) {} - size_t x0; - size_t x1; - size_t y0; - size_t y1; + size_t x0; + size_t x1; + size_t y0; + size_t y1; }; // ================================== @@ -61,80 +61,86 @@ struct sRectal class cSpuData { public: - cSpuData(): count(0), malloc_size(0) {} - ~cSpuData(); + cSpuData(): count(0), malloc_size(0) {} + ~cSpuData(); - void Clear(); - u_char* GetData() const { return data; } + void Clear(); + u_char* GetData() const + { + return data; + } - // write operations - void WriteByte(uint8_t byte); - void WriteNibble(int *higher_nibble, uint8_t nibble); - void WriteRle(int *higher_nibble, int length, int color); + // write operations + void WriteByte(uint8_t byte); + void WriteNibble(int *higher_nibble, uint8_t nibble); + void WriteRle(int *higher_nibble, int length, int color); private: - u_char *data; - size_t count; // the count of bytes written - size_t malloc_size; // size of data + u_char *data; + size_t count; // the count of bytes written + size_t malloc_size; // size of data }; // ================================== struct pixbuf { - int x, y; - u_int rgb[4]; - u_char* pixels; + int x, y; + u_int rgb[4]; + u_char* pixels; }; // ================================== struct encodedata { - u_char data[DATASIZE]; - int count; // the count of bytes written - int oddstart; - int nibblewaiting; + u_char data[DATASIZE]; + int count; // the count of bytes written + int oddstart; + int nibblewaiting; }; // ================================== class cSPUEncoder : public Singleton<cSPUEncoder> { public: - cSPUEncoder(); + cSPUEncoder(); ~cSPUEncoder() {} - int Flush(cPalette *Palette); - void CopyBlockIntoOSD(int numWindow, int linewidth, int x0,int y0, int x1, int y1, const tIndex *data); - void StopSpu(void); - void SetPalette(int numWindow, cPalette* commonPalette, cPalette* windowPalette); - void Clear(void); + int Flush(cPalette *Palette); + void CopyBlockIntoOSD(int numWindow, int linewidth, + int x0,int y0, int x1, int y1, const tIndex *data); + void StopSpu(void); + void SetPalette(int numWindow, cPalette* commonPalette, + cPalette* windowPalette); + void Clear(void); private: cSPUEncoder(cSPUEncoder&); // no copy constructor - // helper functions - void EncodePixelbufRle(int x, int y, int w, int h, u_char *inbuf, int stride, encodedata *ed); + // helper functions + void EncodePixelbufRle(int x, int y, int w, int h, + u_char *inbuf, int stride, encodedata *ed); #ifndef USE_XINE_SCALER - void ScaleOSD(double fac, unsigned char* buf, unsigned char NumColors=4); + void ScaleOSD(double fac, unsigned char* buf, unsigned char NumColors=4); #endif - void encode_put_nibble(encodedata* ed, u_char nibble); - void encode_pixels(encodedata* ed, int color, int number); - void encode_eol(encodedata* ed); - void encode_do_row(encodedata* ed, pixbuf* pb, int row); - void encode_do_control(int x,int y, encodedata* ed, pixbuf* pb); + void encode_put_nibble(encodedata* ed, u_char nibble); + void encode_pixels(encodedata* ed, int color, int number); + void encode_eol(encodedata* ed); + void encode_do_row(encodedata* ed, pixbuf* pb, int row); + void encode_do_control(int x,int y, encodedata* ed, pixbuf* pb); - void CalculateActiveOsdArea(); + void CalculateActiveOsdArea(); - int bitmapcolor[8][16]; - cColorManager* m_ColorManager; - encodedata m_encodeddata; + int bitmapcolor[8][16]; + cColorManager* m_ColorManager; + encodedata m_encodeddata; - // our osd :) - u_char OSD_Screen[OSDWIDTH * OSDHEIGHT]; - u_char OSD_Screen2[OSDWIDTH * OSDHEIGHT]; - u_char OSD_Screen3[OSDWIDTH * OSDHEIGHT]; + // our osd :) + u_char OSD_Screen[OSDWIDTH * OSDHEIGHT]; + u_char OSD_Screen2[OSDWIDTH * OSDHEIGHT]; + u_char OSD_Screen3[OSDWIDTH * OSDHEIGHT]; - // 'active' osd sizes - sRectal m_active_osd; + // 'active' osd sizes + sRectal m_active_osd; }; #endif /*_DXR3_INTERFACE_SPU_ENCODER_*/ @@ -25,46 +25,46 @@ //! constructor cLog::cLog() { - m_LogOpen = false; - m_ForeFlush = true; - - std::string Filename; - Filename = LOGPATH; - Filename += "dxr3plugin.log"; + m_LogOpen = false; + m_ForeFlush = true; + + std::string Filename; + Filename = LOGPATH; + Filename += "dxr3plugin.log"; - Open(Filename); + Open(Filename); } // ================================== //! constructor with filename cLog::cLog(std::string Filename) { - m_LogOpen = false; - m_ForeFlush = true; - - Open(Filename); + m_LogOpen = false; + m_ForeFlush = true; + + Open(Filename); } // ================================== //! open log file void cLog::Open(std::string Filename) { - m_LogStream.open(Filename.c_str()); - m_LogOpen = true; + m_LogStream.open(Filename.c_str()); + m_LogOpen = true; } - + // ================================== //! close log file void cLog::Close() { - if (m_LogOpen) - { - // close file now - m_LogStream.flush(); - m_LogStream.close(); - - m_LogOpen = false; - } + if (m_LogOpen) + { + // close file now + m_LogStream.flush(); + m_LogStream.close(); + + m_LogOpen = false; + } } // Local variables: @@ -27,67 +27,75 @@ #include "dxr3singleton.h" // ================================== -//! A log class. +//! A log class. /*! - With this nice util dxr3plugin generates and mange a log file. In this - file the developer/enduser can find informations and can find errors, - problems and ohter stuff. + With this nice util dxr3plugin generates and mange a log file. In this + file the developer/enduser can find informations and can find errors, + problems and ohter stuff. */ class cLog : public Singleton<cLog> { -public: - cLog(); // use default log file - cLog(std::string FileName); - - ~cLog() { Close(); } - - void SetForceFlush(const bool v) { m_ForeFlush = v; } - bool GetForceFlush() const { return m_ForeFlush; } - - // write type data to log file. - template <class Type> - inline cLog& operator << ( Type item ) +public: + cLog(); // use default log file + cLog(std::string FileName); + + ~cLog() + { + Close(); + } + + void SetForceFlush(const bool v) + { + m_ForeFlush = v; + } + bool GetForceFlush() const + { + return m_ForeFlush; + } + + // write type data to log file. + template <class Type> + inline cLog& operator << ( Type item ) + { + if (m_LogOpen) { - if (m_LogOpen) - { - m_LogStream << item; - if (m_ForeFlush) m_LogStream.flush(); - } - return *this; + m_LogStream << item; + if (m_ForeFlush) + m_LogStream.flush(); } - inline cLog& operator << ( size_t item ) + return *this; + } + inline cLog& operator << ( size_t item ) + { + if (m_LogOpen) { - if (m_LogOpen) - { - m_LogStream << (unsigned int)item; - if (m_ForeFlush) m_LogStream.flush(); - } - return *this; + m_LogStream << (unsigned int)item; + if (m_ForeFlush) + m_LogStream.flush(); } - inline cLog& operator << ( bool item ) + return *this; + } + inline cLog& operator << ( bool item ) + { + if (m_LogOpen) { - if (m_LogOpen) - { - if (item == true) - { - m_LogStream << "true"; - } - else - { - m_LogStream << "false"; - } - if (m_ForeFlush) m_LogStream.flush(); - } - return *this; + if (item == true) + m_LogStream << "true"; + else + m_LogStream << "false"; + if (m_ForeFlush) + m_LogStream.flush(); } + return *this; + } private: - std::ofstream m_LogStream; ///< Our logstream - bool m_LogOpen; ///< Is log open? - bool m_ForeFlush; ///< Do we want to flush log everytime? + std::ofstream m_LogStream; ///< Our logstream + bool m_LogOpen; ///< Is log open? + bool m_ForeFlush; ///< Do we want to flush log everytime? - void Open(std::string Filename); // with this function we open our logfile - void Close(); // with this function we close our logfile + void Open(std::string Filename); // with this function we open our logfile + void Close(); // with this function we close our logfile }; #endif /*_DXR3_LOG_H_*/ diff --git a/dxr3memcpy.c b/dxr3memcpy.c index fe65cc0..19f7fda 100644 --- a/dxr3memcpy.c +++ b/dxr3memcpy.c @@ -60,258 +60,260 @@ __asm__ __volatile__(\ */ // ================================== //! linux kernel __memcpy (from: /include/asm/string.h) -static __inline__ void * __memcpy ( - void * to, - const void * from, - size_t n) +static __inline__ void * __memcpy (void * to, const void * from, size_t n) { -int d0, d1, d2; - - if( n < 4 ) { - small_memcpy(to,from,n); - } - else - __asm__ __volatile__( - "rep ; movsl\n\t" - "testb $2,%b4\n\t" - "je 1f\n\t" - "movsw\n" - "1:\ttestb $1,%b4\n\t" - "je 2f\n\t" - "movsb\n" - "2:" - : "=&c" (d0), "=&D" (d1), "=&S" (d2) - :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) - : "memory"); - - return (to); + int d0, d1, d2; + + if (n < 4) + { + small_memcpy(to, from, n); + } + else + __asm__ __volatile__( + "rep ; movsl\n\t" + "testb $2,%b4\n\t" + "je 1f\n\t" + "movsw\n" + "1:\ttestb $1,%b4\n\t" + "je 2f\n\t" + "movsb\n" + "2:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) + : "memory"); + + return (to); } #define SSE_MMREG_SIZE 16 #define MMX_MMREG_SIZE 8 #define MMX1_MIN_LEN 0x800 /* 2K blocks */ -#define MIN_LEN 0x40 /* 64-byte blocks */ +#define MIN_LEN 0x40 /* 64-byte blocks */ // ================================== /* SSE note: i tried to move 128 bytes a time instead of 64 but it -didn't make any measureable difference. i'm using 64 for the sake of -simplicity. [MF] */ + didn't make any measureable difference. i'm using 64 for the sake of + simplicity. [MF] */ static void * sse_memcpy(void * to, const void * from, size_t len) { - void *retval; - size_t i; - retval = to; - - /* PREFETCH has effect even for MOVSB instruction ;) */ - __asm__ __volatile__ ( - " prefetchnta (%0)\n" - " prefetchnta 32(%0)\n" - " prefetchnta 64(%0)\n" - " prefetchnta 96(%0)\n" - " prefetchnta 128(%0)\n" - " prefetchnta 160(%0)\n" - " prefetchnta 192(%0)\n" - " prefetchnta 224(%0)\n" - " prefetchnta 256(%0)\n" - " prefetchnta 288(%0)\n" - : : "r" (from) ); - - if(len >= MIN_LEN) - { - register unsigned long int delta; - /* Align destinition to MMREG_SIZE -boundary */ - delta = ((unsigned long int)to)&(SSE_MMREG_SIZE-1); - if(delta) + void *retval; + size_t i; + retval = to; + + /* PREFETCH has effect even for MOVSB instruction ;) */ + __asm__ __volatile__ ( + " prefetchnta (%0)\n" + " prefetchnta 32(%0)\n" + " prefetchnta 64(%0)\n" + " prefetchnta 96(%0)\n" + " prefetchnta 128(%0)\n" + " prefetchnta 160(%0)\n" + " prefetchnta 192(%0)\n" + " prefetchnta 224(%0)\n" + " prefetchnta 256(%0)\n" + " prefetchnta 288(%0)\n" + : : "r" (from) ); + + if (len >= MIN_LEN) { - delta=SSE_MMREG_SIZE-delta; - len -= delta; - small_memcpy(to, from, delta); + register unsigned long int delta; + /* Align destinition to MMREG_SIZE -boundary */ + delta = ((unsigned long int)to) & (SSE_MMREG_SIZE - 1); + if (delta) + { + delta = SSE_MMREG_SIZE - delta; + len -= delta; + small_memcpy(to, from, delta); + } + i = len >> 6; /* len/64 */ + len&=63; + if (((unsigned long)from) & 15) /* if SRC is misaligned */ + { + for( ; i > 0; i--) + { + __asm__ __volatile__ ( + "prefetchnta 320(%0)\n" + "prefetchnta 352(%0)\n" + "movups (%0), %%xmm0\n" + "movups 16(%0), %%xmm1\n" + "movups 32(%0), %%xmm2\n" + "movups 48(%0), %%xmm3\n" + "movntps %%xmm0, (%1)\n" + "movntps %%xmm1, 16(%1)\n" + "movntps %%xmm2, 32(%1)\n" + "movntps %%xmm3, 48(%1)\n" + : : "r" (from), "r" (to) : "memory"); + from = ((const unsigned char *)from) + 64; + to = ((unsigned char *)to) + 64; + } + } + else + { + /* + Only if SRC is aligned on 16-byte boundary. + It allows to use movaps instead of movups, which required data + to be aligned or a general-protection exception (#GP) is generated. + */ + for( ; i > 0; i--) + { + __asm__ __volatile__ ( + "prefetchnta 320(%0)\n" + "prefetchnta 352(%0)\n" + "movaps (%0), %%xmm0\n" + "movaps 16(%0), %%xmm1\n" + "movaps 32(%0), %%xmm2\n" + "movaps 48(%0), %%xmm3\n" + "movntps %%xmm0, (%1)\n" + "movntps %%xmm1, 16(%1)\n" + "movntps %%xmm2, 32(%1)\n" + "movntps %%xmm3, 48(%1)\n" + : : "r" (from), "r" (to) : "memory"); + from = ((const unsigned char *)from) + 64; + to = ((unsigned char *)to) + 64; + } + } + /* since movntq is weakly-ordered, a "sfence" + * is needed to become ordered again. */ + __asm__ __volatile__ ("sfence": : :"memory"); + /* enables to use FPU */ + __asm__ __volatile__ ("emms": : :"memory"); } - i = len >> 6; /* len/64 */ - len&=63; - if(((unsigned long)from) & 15) - /* if SRC is misaligned */ - for(; i>0; i--) - { - __asm__ __volatile__ ( - "prefetchnta 320(%0)\n" - "prefetchnta 352(%0)\n" - "movups (%0), %%xmm0\n" - "movups 16(%0), %%xmm1\n" - "movups 32(%0), %%xmm2\n" - "movups 48(%0), %%xmm3\n" - "movntps %%xmm0, (%1)\n" - "movntps %%xmm1, 16(%1)\n" - "movntps %%xmm2, 32(%1)\n" - "movntps %%xmm3, 48(%1)\n" - : : "r" (from), "r" (to) : "memory"); - from = ((const unsigned char *)from) + 64; - to = ((unsigned char *)to) + 64; - } - else - /* - Only if SRC is aligned on 16-byte boundary. - It allows to use movaps instead of movups, which required data - to be aligned or a general-protection exception (#GP) is generated. - */ - for(; i>0; i--) - { - __asm__ __volatile__ ( - "prefetchnta 320(%0)\n" - "prefetchnta 352(%0)\n" - "movaps (%0), %%xmm0\n" - "movaps 16(%0), %%xmm1\n" - "movaps 32(%0), %%xmm2\n" - "movaps 48(%0), %%xmm3\n" - "movntps %%xmm0, (%1)\n" - "movntps %%xmm1, 16(%1)\n" - "movntps %%xmm2, 32(%1)\n" - "movntps %%xmm3, 48(%1)\n" - : : "r" (from), "r" (to) : "memory"); - from = ((const unsigned char *)from) + 64; - to = ((unsigned char *)to) + 64; - } - /* since movntq is weakly-ordered, a "sfence" - * is needed to become ordered again. */ - __asm__ __volatile__ ("sfence": : :"memory"); - /* enables to use FPU */ - __asm__ __volatile__ ("emms": : :"memory"); - } - /* - * Now do the tail of the block - */ - if(len) __memcpy(to, from, len); - return retval; + /* + * Now do the tail of the block + */ + if(len) __memcpy(to, from, len); + return retval; } // ================================== static void * mmx_memcpy(void * to, const void * from, size_t len) { - void *retval; - size_t i; - retval = to; - - if(len >= MMX1_MIN_LEN) - { - register unsigned long int delta; - /* Align destinition to MMREG_SIZE -boundary */ - delta = ((unsigned long int)to)&(MMX_MMREG_SIZE-1); - if(delta) - { - delta=MMX_MMREG_SIZE-delta; - len -= delta; - small_memcpy(to, from, delta); - } - i = len >> 6; /* len/64 */ - len&=63; - for(; i>0; i--) + void *retval; + size_t i; + retval = to; + + if(len >= MMX1_MIN_LEN) { - __asm__ __volatile__ ( - "movq (%0), %%mm0\n" - "movq 8(%0), %%mm1\n" - "movq 16(%0), %%mm2\n" - "movq 24(%0), %%mm3\n" - "movq 32(%0), %%mm4\n" - "movq 40(%0), %%mm5\n" - "movq 48(%0), %%mm6\n" - "movq 56(%0), %%mm7\n" - "movq %%mm0, (%1)\n" - "movq %%mm1, 8(%1)\n" - "movq %%mm2, 16(%1)\n" - "movq %%mm3, 24(%1)\n" - "movq %%mm4, 32(%1)\n" - "movq %%mm5, 40(%1)\n" - "movq %%mm6, 48(%1)\n" - "movq %%mm7, 56(%1)\n" - : : "r" (from), "r" (to) : "memory"); - from = ((const unsigned char *)from) + 64; - to = ((unsigned char *)to) + 64; + register unsigned long int delta; + /* Align destinition to MMREG_SIZE -boundary */ + delta = ((unsigned long int)to) & (MMX_MMREG_SIZE - 1); + if (delta) + { + delta = MMX_MMREG_SIZE - delta; + len -= delta; + small_memcpy(to, from, delta); + } + i = len >> 6; /* len/64 */ + len&=63; + for( ; i > 0; i--) + { + __asm__ __volatile__ ( + "movq (%0), %%mm0\n" + "movq 8(%0), %%mm1\n" + "movq 16(%0), %%mm2\n" + "movq 24(%0), %%mm3\n" + "movq 32(%0), %%mm4\n" + "movq 40(%0), %%mm5\n" + "movq 48(%0), %%mm6\n" + "movq 56(%0), %%mm7\n" + "movq %%mm0, (%1)\n" + "movq %%mm1, 8(%1)\n" + "movq %%mm2, 16(%1)\n" + "movq %%mm3, 24(%1)\n" + "movq %%mm4, 32(%1)\n" + "movq %%mm5, 40(%1)\n" + "movq %%mm6, 48(%1)\n" + "movq %%mm7, 56(%1)\n" + : : "r" (from), "r" (to) : "memory"); + from = ((const unsigned char *)from) + 64; + to = ((unsigned char *)to) + 64; + } + __asm__ __volatile__ ("emms": : :"memory"); } - __asm__ __volatile__ ("emms": : :"memory"); - } - /* - * Now do the tail of the block - */ - if(len) __memcpy(to, from, len); - return retval; + /* + * Now do the tail of the block + */ + if(len) __memcpy(to, from, len); + return retval; } // ================================== static void * mmx2_memcpy(void * to, const void * from, size_t len) { - void *retval; - size_t i; - retval = to; - - /* PREFETCH has effect even for MOVSB instruction ;) */ - __asm__ __volatile__ ( - " prefetchnta (%0)\n" - " prefetchnta 32(%0)\n" - " prefetchnta 64(%0)\n" - " prefetchnta 96(%0)\n" - " prefetchnta 128(%0)\n" - " prefetchnta 160(%0)\n" - " prefetchnta 192(%0)\n" - " prefetchnta 224(%0)\n" - " prefetchnta 256(%0)\n" - " prefetchnta 288(%0)\n" - : : "r" (from) ); - - if(len >= MIN_LEN) - { - register unsigned long int delta; - /* Align destinition to MMREG_SIZE -boundary */ - delta = ((unsigned long int)to)&(MMX_MMREG_SIZE-1); - if(delta) + void *retval; + size_t i; + retval = to; + + /* PREFETCH has effect even for MOVSB instruction ;) */ + __asm__ __volatile__ ( + " prefetchnta (%0)\n" + " prefetchnta 32(%0)\n" + " prefetchnta 64(%0)\n" + " prefetchnta 96(%0)\n" + " prefetchnta 128(%0)\n" + " prefetchnta 160(%0)\n" + " prefetchnta 192(%0)\n" + " prefetchnta 224(%0)\n" + " prefetchnta 256(%0)\n" + " prefetchnta 288(%0)\n" + : : "r" (from) ); + + if (len >= MIN_LEN) { - delta=MMX_MMREG_SIZE-delta; - len -= delta; - small_memcpy(to, from, delta); - } - i = len >> 6; /* len/64 */ - len&=63; - for(; i>0; i--) - { - __asm__ __volatile__ ( - "prefetchnta 320(%0)\n" - "prefetchnta 352(%0)\n" - "movq (%0), %%mm0\n" - "movq 8(%0), %%mm1\n" - "movq 16(%0), %%mm2\n" - "movq 24(%0), %%mm3\n" - "movq 32(%0), %%mm4\n" - "movq 40(%0), %%mm5\n" - "movq 48(%0), %%mm6\n" - "movq 56(%0), %%mm7\n" - "movntq %%mm0, (%1)\n" - "movntq %%mm1, 8(%1)\n" - "movntq %%mm2, 16(%1)\n" - "movntq %%mm3, 24(%1)\n" - "movntq %%mm4, 32(%1)\n" - "movntq %%mm5, 40(%1)\n" - "movntq %%mm6, 48(%1)\n" - "movntq %%mm7, 56(%1)\n" - : : "r" (from), "r" (to) : "memory"); - from = ((const unsigned char *)from) + 64; - to = ((unsigned char *)to) + 64; + register unsigned long int delta; + /* Align destinition to MMREG_SIZE -boundary */ + delta = ((unsigned long int)to) & (MMX_MMREG_SIZE - 1); + if (delta) + { + delta = MMX_MMREG_SIZE - delta; + len -= delta; + small_memcpy(to, from, delta); + } + i = len >> 6; /* len/64 */ + len&=63; + for( ; i > 0; i--) + { + __asm__ __volatile__ ( + "prefetchnta 320(%0)\n" + "prefetchnta 352(%0)\n" + "movq (%0), %%mm0\n" + "movq 8(%0), %%mm1\n" + "movq 16(%0), %%mm2\n" + "movq 24(%0), %%mm3\n" + "movq 32(%0), %%mm4\n" + "movq 40(%0), %%mm5\n" + "movq 48(%0), %%mm6\n" + "movq 56(%0), %%mm7\n" + "movntq %%mm0, (%1)\n" + "movntq %%mm1, 8(%1)\n" + "movntq %%mm2, 16(%1)\n" + "movntq %%mm3, 24(%1)\n" + "movntq %%mm4, 32(%1)\n" + "movntq %%mm5, 40(%1)\n" + "movntq %%mm6, 48(%1)\n" + "movntq %%mm7, 56(%1)\n" + : : "r" (from), "r" (to) : "memory"); + from = ((const unsigned char *)from) + 64; + to = ((unsigned char *)to) + 64; + } + /* since movntq is weakly-ordered, a "sfence" + * is needed to become ordered again. */ + __asm__ __volatile__ ("sfence": : :"memory"); + __asm__ __volatile__ ("emms": : :"memory"); } - /* since movntq is weakly-ordered, a "sfence" - * is needed to become ordered again. */ - __asm__ __volatile__ ("sfence": : :"memory"); - __asm__ __volatile__ ("emms": : :"memory"); - } - /* - * Now do the tail of the block - */ - if(len) __memcpy(to, from, len); - return retval; + /* + * Now do the tail of the block + */ + if(len) __memcpy(to, from, len); + return retval; } // ================================== -static void *linux_kernel_memcpy(void *to, const void *from, size_t len) { - return __memcpy(to,from,len); +static void *linux_kernel_memcpy(void *to, const void *from, size_t len) +{ + return __memcpy(to, from, len); } #endif /* __i386__ || __x86_64__ */ @@ -319,105 +321,108 @@ static void *linux_kernel_memcpy(void *to, const void *from, size_t len) { // ================================== //! constr. cDxr3MemcpyBench::cDxr3MemcpyBench(uint32_t config_flags) -{ - // - // add all aviable memcpy routines - // +{ + // + // add all available memcpy routines + // - memcpy_routine routine; + memcpy_routine routine; - // glibc memcpy - routine.name = "glibc memcpy()"; - routine.function = memcpy; - routine.time = 0; - routine.cpu_require = 0; - m_methods.push_back(routine); + // glibc memcpy + routine.name = "glibc memcpy()"; + routine.function = memcpy; + routine.time = 0; + routine.cpu_require = 0; + m_methods.push_back(routine); #if defined(__i386__) || defined(__x86_64__) - // linux_kernel_memcpy - routine.name = "linux_kernel_memcpy()"; - routine.function = linux_kernel_memcpy; - routine.cpu_require = 0; - m_methods.push_back(routine); + // linux_kernel_memcpy + routine.name = "linux_kernel_memcpy()"; + routine.function = linux_kernel_memcpy; + routine.cpu_require = 0; + m_methods.push_back(routine); - // MMX optimized memcpy() - routine.name = "MMX optimized memcpy()"; - routine.function = mmx_memcpy; - routine.cpu_require = CC_MMX; - m_methods.push_back(routine); + // MMX optimized memcpy() + routine.name = "MMX optimized memcpy()"; + routine.function = mmx_memcpy; + routine.cpu_require = CC_MMX; + m_methods.push_back(routine); - // MMXEXT optimized memcpy() - routine.name = "MMXEXT optimized memcpy()"; - routine.function = mmx2_memcpy; - routine.cpu_require = CC_MMXEXT; - m_methods.push_back(routine); + // MMXEXT optimized memcpy() + routine.name = "MMXEXT optimized memcpy()"; + routine.function = mmx2_memcpy; + routine.cpu_require = CC_MMXEXT; + m_methods.push_back(routine); #ifndef __FreeBSD__ - // SSE optimized memcpy() - routine.name = "SSE optimized memcpy()"; - routine.function = sse_memcpy; - routine.cpu_require = CC_MMXEXT|CC_SSE; - m_methods.push_back(routine); + // SSE optimized memcpy() + routine.name = "SSE optimized memcpy()"; + routine.function = sse_memcpy; + routine.cpu_require = CC_MMXEXT|CC_SSE; + m_methods.push_back(routine); #endif /* not __FreeBSD__ */ #endif /* __i386__ || __x86_64__ */ - // - // run benchmarking - // + // + // run benchmarking + // + + unsigned long long t = 0; + void *buf1, *buf2; + int j, best = -1; + + if ((buf1 = malloc(BUFSIZE)) == NULL) + return; - unsigned long long t = 0; - void *buf1, *buf2; - int j, best = -1; + if ((buf2 = malloc(BUFSIZE)) == NULL) + { + free(buf1); + return; + } - if ((buf1 = malloc(BUFSIZE)) == NULL) - return; - - if ((buf2 = malloc(BUFSIZE)) == NULL) + cLog::Instance() << + "\nBenchmarking memcpy() methods (smaller is better):\n"; + // make sure buffers are present on physical memory + memcpy(buf1, buf2, BUFSIZE); + + for (size_t i = 0; i < m_methods.size(); i++) + { + if ((config_flags & m_methods[i].cpu_require) != m_methods[i].cpu_require) + { + continue; + } + + // count 100 runs of the memcpy function + t = Rdtsc(config_flags); + for (j = 0; j < 50; j++) { - free(buf1); - return; + m_methods[i].function(buf2, buf1, BUFSIZE); + m_methods[i].function(buf1, buf2, BUFSIZE); } + t = Rdtsc(config_flags) - t; + + m_methods[i].time = t; - cLog::Instance() << "\nBenchmarking memcpy() methods (smaller is better):\n"; - // make sure buffers are present on physical memory - memcpy(buf1,buf2,BUFSIZE); + cLog::Instance() << m_methods[i].name.c_str() << ": " + << (unsigned long long)t << "\n"; - for (size_t i = 0; i < m_methods.size(); i++) + if (best == -1 || t < m_methods[best].time) { - if ((config_flags & m_methods[i].cpu_require) != m_methods[i].cpu_require) - { - continue; - } - - // count 100 runs of the memcpy function - t = Rdtsc(config_flags); - for (j = 0; j < 50; j++) - { - m_methods[i].function(buf2,buf1,BUFSIZE); - m_methods[i].function(buf1,buf2,BUFSIZE); - } - t = Rdtsc(config_flags) - t; - - m_methods[i].time = t; - - cLog::Instance() << m_methods[i].name.c_str() << ": " << (unsigned long long)t << "\n"; - - if (best == -1 || t < m_methods[best].time) - { - best = i; - } + best = i; } - cLog::Instance() << "\nBest one: " << m_methods[best].name.c_str() << "\n\n"; + } + cLog::Instance() << "\nBest one: " + << m_methods[best].name.c_str() << "\n\n"; - dxr3_memcpy = m_methods[best].function; + dxr3_memcpy = m_methods[best].function; - // clear unused memory - free(buf1); - free(buf2); + // clear unused memory + free(buf1); + free(buf2); } // ================================== @@ -425,20 +430,20 @@ cDxr3MemcpyBench::cDxr3MemcpyBench(uint32_t config_flags) unsigned long long int cDxr3MemcpyBench::Rdtsc(uint32_t config_flags) { #if defined(__i386__) || defined(__x86_64__) - // we need rdtsc support - if (config_flags && CC_MMX) - { - unsigned long long int x; - __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); - return x; - } - else - { - return times(NULL); - } + // we need rdtsc support + if (config_flags && CC_MMX) + { + unsigned long long int x; + __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); + return x; + } + else + { + return times(NULL); + } #else - struct tms tp; - return times(&tp); + struct tms tp; + return times(&tp); #endif /* __i386__ || __x86_64__ */ } diff --git a/dxr3memcpy.h b/dxr3memcpy.h index 0fb1442..c590d6c 100644 --- a/dxr3memcpy.h +++ b/dxr3memcpy.h @@ -29,7 +29,7 @@ * 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 @@ -41,11 +41,11 @@ ***************************************************************************** * * Original code: - * + * * Copyright (C) 2000-2001 the xine project - * + * * This file is part of xine, a unix video player. - * + * *****************************************************************************/ #ifndef _DXR3MEMCPY_H_ @@ -55,34 +55,34 @@ // ================================== /*! \def BUFSIZE - \brief size of buffers for benchmark :) + \brief size of buffers for benchmark :) */ #define BUFSIZE 1024*1024 // ================================== struct memcpy_routine { - std::string name; ///< name of memcpy methode - void *(* function)(void *to, const void *from, size_t len); ///< our memcopy methode - unsigned long long time; ///< needed time for banchmark - uint32_t cpu_require; ///< caps from dxr3cpu.h + std::string name; ///< name of memcpy methode + void *(* function)(void *to, const void *from, size_t len); ///< our memcopy methode + unsigned long long time; ///< needed time for banchmark + uint32_t cpu_require; ///< caps from dxr3cpu.h }; // ================================== //! Little class to do a nice benchmark /* - Whith this class we can get the fastest memcyp - methode for target computer. + Whith this class we can get the fastest memcyp + methode for target computer. */ class cDxr3MemcpyBench { public: - cDxr3MemcpyBench(uint32_t config_flags = 0); + cDxr3MemcpyBench(uint32_t config_flags = 0); private: - unsigned long long int Rdtsc(uint32_t config_flags); + unsigned long long int Rdtsc(uint32_t config_flags); - std::vector<memcpy_routine> m_methods; ///< a std::vector with all methodes + std::vector<memcpy_routine> m_methods; ///< a std::vector with all methods }; // ================================== diff --git a/dxr3multichannelaudio.c b/dxr3multichannelaudio.c index 9a12d70..1d1bc30 100644 --- a/dxr3multichannelaudio.c +++ b/dxr3multichannelaudio.c @@ -1,10 +1,10 @@ /* -* dxr3multichannelaudio.c: -* -* taken from the AC3overDVB Patch maintained by Stefan Huelswitt -* -* -*/ + * dxr3multichannelaudio.c: + * + * taken from the AC3overDVB Patch maintained by Stefan Huelswitt + * + * + */ #include <malloc.h> #include "dxr3multichannelaudio.h" @@ -22,625 +22,759 @@ #define aLPCM 0xA0 #define aMPEG 0xC0 -#define aVDR 0x0B // VDR specific audio substream -#define aSPU 0x20 // SPU stream +#define aVDR 0x0B // VDR specific audio substream +#define aSPU 0x20 // SPU stream #define PES_HDR_SIZE 6 // length of PES header #define PTS_SIZE 5 // length of PTS data #define MAX_FRAMECOUNT 1536 // max. LPCM payload size -#define SYNC_SIZE 7 // how many bytes we need to sync on a audio header +#define SYNC_SIZE 7 // how many bytes needed to sync on a audio header #define AC3_SIZE 6144 // size of AC3 IEC paket #define DTS_SIZE 2048 // size of DTS IEC paket #define IEC_HDR_SIZE 8 // size of IEC header -// --- cAudioEncapsulator ------------------------------------------------------ +// --- cAudioEncapsulator ----------------------------------------------------- -class cAudioEncapsulator { +class cAudioEncapsulator +{ private: - int totalSize, frameCount; - cFrame *frame; - uchar *frameData; - // - uchar syncBuff[SYNC_SIZE]; - int have, length, skipped; - // - uchar ptsFlags; - const uchar *ptsData; - int ptsDelay; - // - void NewFrame(uchar PTSflags, const uchar *PTSdata); - void SyncFound(const uchar *data); + int totalSize, frameCount; + cFrame *frame; + uchar *frameData; + // + uchar syncBuff[SYNC_SIZE]; + int have, length, skipped; + // + uchar ptsFlags; + const uchar *ptsData; + int ptsDelay; + // + void NewFrame(uchar PTSflags, const uchar *PTSdata); + void SyncFound(const uchar *data); protected: - int streamType; - cRingBufferFrame *ringBuffer; - int fillup, firstBurst; - bool mute, muteData; - // - void StartFrame(int size, uchar PTSflags, const uchar *PTSdata); - void FinishFrame(void); - void PutData(const uchar *data, int len); - void SendIECpause(int type, uchar PTSflags, const uchar *PTSdata); - // - virtual int SyncInfo(const uchar *data)=0; - virtual void StartIECFrame(const uchar *buf, int length, uchar PTSflags, const uchar *PTSdata)=0; - virtual void FinishIECFrame(void); + int streamType; + cRingBufferFrame *ringBuffer; + int fillup, firstBurst; + bool mute, muteData; + // + void StartFrame(int size, uchar PTSflags, const uchar *PTSdata); + void FinishFrame(void); + void PutData(const uchar *data, int len); + void SendIECpause(int type, uchar PTSflags, const uchar *PTSdata); + // + virtual int SyncInfo(const uchar *data)=0; + virtual void StartIECFrame(const uchar *buf, int length, uchar PTSflags, + const uchar *PTSdata) = 0; + virtual void FinishIECFrame(void); public: - cAudioEncapsulator(cRingBufferFrame *rb, int StreamType); - virtual ~cAudioEncapsulator(); - void Clear(void); - void Decode(const uchar *data, int len, uchar PTSflags, int PTSdelay, const uchar *PTSdata); - int StreamType() { return streamType; } - void Mute(bool Mute) { mute=Mute; } - }; + cAudioEncapsulator(cRingBufferFrame *rb, int StreamType); + virtual ~cAudioEncapsulator(); + void Clear(void); + void Decode(const uchar *data, int len, uchar PTSflags, int PTSdelay, + const uchar *PTSdata); + int StreamType() + { + return streamType; + } + void Mute(bool Mute) + { + mute = Mute; + } +}; cAudioEncapsulator::cAudioEncapsulator(cRingBufferFrame *rb, int StreamType) { - ringBuffer=rb; - streamType=StreamType; - frame=0; firstBurst=1; - Clear(); + ringBuffer = rb; + streamType = StreamType; + frame = 0; + firstBurst = 1; + Clear(); } cAudioEncapsulator::~cAudioEncapsulator() { - delete frame; + delete frame; } void cAudioEncapsulator::Clear(void) { - delete frame; - frame=0; frameCount=0; fillup=0; mute=muteData=false; - have=length=skipped=0; + delete frame; + frame = 0; + frameCount = 0; + fillup = 0; + mute = muteData = false; + have = length = skipped = 0; } -void cAudioEncapsulator::StartFrame(int size, uchar PTSflags, const uchar *PTSdata) +void cAudioEncapsulator::StartFrame(int size, uchar PTSflags, + const uchar *PTSdata) { - if(frame) { - DEBUG("StartFrame() with unfinished frame!\n"); - FinishFrame(); + if (frame) + { + DEBUG("StartFrame() with unfinished frame!\n"); + FinishFrame(); } - ED("StartFrame: size=%d ptsFlags=%d\n",size,PTSflags); - totalSize=size; - NewFrame(PTSflags,PTSdata); + ED("StartFrame: size=%d ptsFlags=%d\n", size, PTSflags); + totalSize = size; + NewFrame(PTSflags, PTSdata); } void cAudioEncapsulator::NewFrame(uchar PTSflags, const uchar *PTSdata) { - if(!totalSize) { - DEBUG("NewFrame: new frame requested, but totalSize=0\n"); - return; + if (!totalSize) + { + DEBUG("NewFrame: new frame requested, but totalSize=0\n"); + return; } - static const int ptslen[] = { 0,0,PTS_SIZE,PTS_SIZE*2 }; - const int plen = ptslen[PTSflags]; - int len = std::min(totalSize, MAX_FRAMECOUNT); - ED("NewFrame: totalSize=%d frameCount=%d PTSflags=%d",totalSize,len,PTSflags); - totalSize -= len; - ED(" new totalSize=%d\n",totalSize); - len += (plen + 3 + 7); - frameCount = len+PES_HDR_SIZE; - frameData = MALLOC(uchar,frameCount); - if (frameData) { - frame = new cFrame(frameData, -frameCount, ftUnknown); - if (frame) { - uchar buf[10]; - // build the PES header - buf[0] = 0x00; - buf[1] = 0x00; - buf[2] = 0x01; - buf[3] = 0xBD; // PRIVATE_STREAM1 - buf[4] = (len >> 8) & 0xFF; - buf[5] = len & 0xFF; - buf[6] = 0x84; - buf[7] = plen ? (PTSflags << 6) : 0; - buf[8] = plen; - PutData(buf,9); - - if (plen) PutData(PTSdata,plen); - - // build LPCM header - buf[0] = aLPCM; // substream ID - buf[1] = 0xFF; - buf[2] = 0x00; - buf[3] = 0x00; - buf[4] = 0x00; - buf[5] = 0x00; - buf[6] = 0x81; - PutData(buf,7); - return; - } - else { free(frameData); frameData=0; } + static const int ptslen[] = { 0, 0, PTS_SIZE, PTS_SIZE*2 }; + const int plen = ptslen[PTSflags]; + int len = std::min(totalSize, MAX_FRAMECOUNT); + ED("NewFrame: totalSize=%d frameCount=%d PTSflags=%d", totalSize, len, PTSflags); + totalSize -= len; + ED(" new totalSize=%d\n",totalSize); + len += (plen + 3 + 7); + frameCount = len + PES_HDR_SIZE; + frameData = MALLOC(uchar, frameCount); + if (frameData) + { + frame = new cFrame(frameData, -frameCount, ftUnknown); + if (frame) + { + uchar buf[10]; + // build the PES header + buf[0] = 0x00; + buf[1] = 0x00; + buf[2] = 0x01; + buf[3] = 0xBD; // PRIVATE_STREAM1 + buf[4] = (len >> 8) & 0xFF; + buf[5] = len & 0xFF; + buf[6] = 0x84; + buf[7] = plen ? (PTSflags << 6) : 0; + buf[8] = plen; + PutData(buf, 9); + + if (plen) + PutData(PTSdata, plen); + + // build LPCM header + buf[0] = aLPCM; // substream ID + buf[1] = 0xFF; + buf[2] = 0x00; + buf[3] = 0x00; + buf[4] = 0x00; + buf[5] = 0x00; + buf[6] = 0x81; + PutData(buf, 7); + return; + } + else + { + free(frameData); + frameData = 0; + } } - esyslog("Failed to build frame for audio encapsulation"); + esyslog("Failed to build frame for audio encapsulation"); } void cAudioEncapsulator::FinishFrame(void) { - if (frameCount) { - DEBUG("FinishFrame() with frameCount>0\n"); - PutData(0,frameCount); + if (frameCount) + { + DEBUG("FinishFrame() with frameCount>0\n"); + PutData(0, frameCount); } - if (frame && frameData) { - ED("FinishFrame: totalSize=%d\n",totalSize); - if (!ringBuffer->Put(frame)) { - esyslog("Ringbuffer overflow. Encapsulated audio frame lost"); - delete frame; - } + if (frame && frameData) + { + ED("FinishFrame: totalSize=%d\n", totalSize); + if (!ringBuffer->Put(frame)) { + esyslog("Ringbuffer overflow. Encapsulated audio frame lost"); + delete frame; + } } - frame=0; frameData=0; frameCount=0; + frame = 0; + frameData = 0; + frameCount = 0; } void cAudioEncapsulator::PutData(const uchar *data, int len) { - if(!muteData) { - if(!frameData) DEBUG("PutData() without frame\n"); - while (frameData && len > 0) { - int l = std::min(len,frameCount); - if(data) { - memcpy(frameData,data,l); - data += l; - } - else memset(frameData,0,l); - frameData += l; len -= l; frameCount -= l; - - ED("PutData: %s=%d len=%d frameCount=%d\n",data?"put":"zero",l,len,frameCount); - if (!frameCount) { - FinishFrame(); - if (totalSize > 0) NewFrame(0,0); - } - } + if (!muteData) + { + if (!frameData) + DEBUG("PutData() without frame\n"); + while (frameData && len > 0) + { + int l = std::min(len, frameCount); + if (data) + { + memcpy(frameData, data, l); + data += l; + } + else + memset(frameData, 0, l); + frameData += l; + len -= l; + frameCount -= l; + + ED("PutData: %s=%d len=%d frameCount=%d\n", + data ? "put" : "zero", l, len, frameCount); + if (!frameCount) + { + FinishFrame(); + if (totalSize > 0) + NewFrame(0, 0); + } + } } } -void cAudioEncapsulator::SendIECpause(int type, uchar PTSflags, const uchar *PTSdata) +void cAudioEncapsulator::SendIECpause(int type, uchar PTSflags, + const uchar *PTSdata) { - StartFrame(AC3_SIZE,PTSflags,PTSdata); - uchar burst[IEC_HDR_SIZE]; - // prepare IEC 60958 data frame - burst[0] = 0xF8; - burst[1] = 0x72; - burst[2] = 0x4E; - burst[3] = 0x1F; - - switch (type) { + StartFrame(AC3_SIZE, PTSflags, PTSdata); + uchar burst[IEC_HDR_SIZE]; + // prepare IEC 60958 data frame + burst[0] = 0xF8; + burst[1] = 0x72; + burst[2] = 0x4E; + burst[3] = 0x1F; + + switch (type) { default: case 0: - burst[4] = 7 << 5; // null frame, stream = 7 - burst[5] = 0x00; - burst[6] = 0x00; // No data therein - burst[7] = 0x00; - break; + burst[4] = 7 << 5; // null frame, stream = 7 + burst[5] = 0x00; + burst[6] = 0x00; // No data therein + burst[7] = 0x00; + break; case 1: - burst[4] = 0x00; // Audio ES Channel empty, wait - burst[5] = 0x03; // for DD Decoder or pause - burst[6] = 0x00; // Trailing frame size is 32 bits payload - burst[7] = 0x20; - break; + burst[4] = 0x00; // Audio ES Channel empty, wait + burst[5] = 0x03; // for DD Decoder or pause + burst[6] = 0x00; // Trailing frame size is 32 bits payload + burst[7] = 0x20; + break; case -1: - burst[4] = 0x01; // User stop, skip or error - burst[5] = 0x03; - burst[6] = 0x08; // Trailing frame size is zero - burst[7] = 0x00; - break; + burst[4] = 0x01; // User stop, skip or error + burst[5] = 0x03; + burst[6] = 0x08; // Trailing frame size is zero + burst[7] = 0x00; + break; } - PutData(burst,sizeof(burst)); - PutData(0,AC3_SIZE-sizeof(burst)); - FinishFrame(); - muteData = true; + PutData(burst, sizeof(burst)); + PutData(0, AC3_SIZE - sizeof(burst)); + FinishFrame(); + muteData = true; } void cAudioEncapsulator::FinishIECFrame(void) { - if(!muteData) { - ED("FinishIECFrame: fillup=%d\n",fillup); - if (fillup) PutData(0,fillup); - FinishFrame(); + if (!muteData) + { + ED("FinishIECFrame: fillup=%d\n", fillup); + if (fillup) + PutData(0, fillup); + FinishFrame(); } - muteData=false; fillup=0; + muteData = false; + fillup = 0; } void cAudioEncapsulator::SyncFound(const uchar *data) { - if(skipped) { - DEBUG("Decode: skipped %d bytes\n",skipped); - ED("skipped: "); for(int k=-skipped ; k<0 ; k++) ED("%02x ",data[k]); - ED("\ndata: "); for(int k=0 ; k<24 ; k++) ED("%02x ",data[k]); - ED("\n"); - skipped=0; + if (skipped) + { + DEBUG("Decode: skipped %d bytes\n", skipped); + ED("skipped: "); for(int k = -skipped; k < 0; k++) ED("%02x ",data[k]); + ED("\ndata: "); for(int k = 0; k<24; k++) ED("%02x ", data[k]); + ED("\n"); + skipped = 0; } - uchar pf=0; - ED("Decode: sync found ptsFlags=%d ptsDelay=%d\n",ptsFlags,ptsDelay); - if(ptsFlags && ptsDelay<=1) { - pf=ptsFlags; ptsFlags=0; + uchar pf = 0; + ED("Decode: sync found ptsFlags=%d ptsDelay=%d\n", ptsFlags, ptsDelay); + if (ptsFlags && ptsDelay <= 1) + { + pf = ptsFlags; + ptsFlags = 0; } - if(firstBurst || mute) { - SendIECpause(1,pf,ptsData); - if(firstBurst && ++firstBurst>10) firstBurst=0; + if (firstBurst || mute) + { + SendIECpause(1, pf, ptsData); + if (firstBurst && ++firstBurst>10) + firstBurst = 0; } - else StartIECFrame(data,length,pf,ptsData); - PutData(data,SYNC_SIZE); - have = SYNC_SIZE; + else + StartIECFrame(data, length, pf, ptsData); + PutData(data, SYNC_SIZE); + have = SYNC_SIZE; } -void cAudioEncapsulator::Decode(const uchar *data, int len, uchar PTSflags, int PTSdelay, const uchar *PTSdata) +void cAudioEncapsulator::Decode(const uchar *data, int len, uchar PTSflags, + int PTSdelay, const uchar *PTSdata) { - ED("Decode: enter length=%d have=%d len=%d PTSflags=%d PTSdelay=%d\n",length,have,len,PTSflags,PTSdelay); - if(PTSflags) { - // if we are close to the end of an audio frame, but are already receiving - // the start of the next frame, assume a corrupted stream and finish the - // incomplete frame. - if(length && length-have<20 && !PTSdelay && SyncInfo(data)) { - int miss=length-have; - DEBUG("Decode: incomplete frame (stream corrupt?). syncing to next. miss=%d\n",miss); - PutData(0,miss); - FinishIECFrame(); - length=have=0; - } -/* - // we only send PTS info if we're nearly at frame start, except - // if we're signaled to delay the PTS - if(length && have>40) { - if(PTSdelay) ED("Decode: PTS delayed\n"); - else { - DEBUG("Decode: PTS info dropped length=%d have=%d\n",length,have); - PTSflags=0; - } - } -*/ - ptsFlags=PTSflags; ptsData=PTSdata; ptsDelay=PTSdelay; -// ED("Decode: saved PTS flags=%d delay=%d\n",ptsFlags,ptsDelay); + ED("Decode: enter length=%d have=%d len=%d PTSflags=%d PTSdelay=%d\n", + length, have, len, PTSflags, PTSdelay); + if (PTSflags) + { + // if we are close to the end of an audio frame, but are already + // receiving the start of the next frame, assume a corrupted stream + // and finish the incomplete frame. + if (length && length-have < 20 && !PTSdelay && SyncInfo(data)) + { + int miss = length - have; + DEBUG("Decode: incomplete frame (stream corrupt?). syncing to next. miss=%d\n", miss); + PutData(0, miss); + FinishIECFrame(); + length = have = 0; + } + /* + // we only send PTS info if we're nearly at frame start, except + // if we're signaled to delay the PTS + if (length && have > 40) + { + if(PTSdelay) + ED("Decode: PTS delayed\n"); + else + { + DEBUG("Decode: PTS info dropped length=%d have=%d\n", + length, have); + PTSflags = 0; + } + } + */ + ptsFlags = PTSflags; + ptsData = PTSdata; + ptsDelay = PTSdelay; + //ED("Decode: saved PTS flags=%d delay=%d\n", ptsFlags, ptsDelay); } #if 0 - { - printf("Decode: len=%d\n",len); - for(int i=0 ; i<len ; ) { - printf("%04x:",i); - for(int j=0 ; j<16 && i<len ; j++) { - printf(" %02x",data[i++]); - } - printf("\n"); + { + printf("Decode: len=%d\n", len); + for (int i = 0; i < len; ) + { + printf("%04x:", i); + for (int j = 0; j < 16 && i < len; j++) + printf(" %02x", data[i++]); + printf("\n"); + } } - } #endif - int used=0; - while (used < len) { - if (!length) { // we are still searching for a header sync - if (!have) { // buffer is empty, work without buffering - if (used+SYNC_SIZE < len) { - length=SyncInfo(&data[used]); - if (length) { - ED("Decode: sync found at offset %d (len=%d)\n",used,length); - SyncFound(&data[used]); - used += SYNC_SIZE; ptsDelay -= SYNC_SIZE; - continue; - } - else { used++; skipped++; } - } - else { // not enough data to try a sync, buffer the rest - ED("Decode: buffering started\n"); - have = len-used; - memcpy(syncBuff,&data[used],have); - used += have; ptsDelay -= have; - } - } - else { // unfortunaly buffer is not empty, so continue with buffering until sync found - int need=std::min(SYNC_SIZE-have,len-used); - if (need) { - memcpy(&syncBuff[have],&data[used],need); - have += need; used += need; ptsDelay -= need; - } - if (have==SYNC_SIZE) { - length=SyncInfo(syncBuff); - if (length) { - ED("Decode: (buffered) sync found at offset %d (len=%d)\n",used-7,length); - SyncFound(syncBuff); - continue; - } - else { - memmove(syncBuff,syncBuff+1,SYNC_SIZE-1); - have--; skipped++; - } - } - } - } - else { // we have a header sync and are copying data - int need = std::min(length-have,len-used); - if(need) { - ED("Decode: writing %d\n",need); - PutData(&data[used],need); - have += need; used += need; ptsDelay -= need; - if (have == length) { - FinishIECFrame(); - length = have = 0; - continue; - } - } - } + int used = 0; + while (used < len) + { + if (!length) // we are still searching for a header sync + { + if (!have) // buffer is empty, work without buffering + { + if (used + SYNC_SIZE < len) + { + length = SyncInfo(&data[used]); + if (length) + { + ED("Decode: sync found at offset %d (len=%d)\n", + used, length); + SyncFound(&data[used]); + used += SYNC_SIZE; + ptsDelay -= SYNC_SIZE; + continue; + } + else + { + used++; + skipped++; + } + } + else // not enough data to try a sync, buffer the rest + { + ED("Decode: buffering started\n"); + have = len - used; + memcpy(syncBuff, &data[used], have); + used += have; + ptsDelay -= have; + } + } + else // unfortunately buffer is not empty, so continue with + // buffering until sync found + { + int need = std::min(SYNC_SIZE - have, len - used); + if (need) + { + memcpy(&syncBuff[have], &data[used], need); + have += need; + used += need; + ptsDelay -= need; + } + if (have == SYNC_SIZE) + { + length = SyncInfo(syncBuff); + if (length) + { + ED("Decode: (buffered) sync found at offset %d (len=%d)\n",used-7,length); + SyncFound(syncBuff); + continue; + } + else + { + memmove(syncBuff, syncBuff + 1, SYNC_SIZE - 1); + have--; + skipped++; + } + } + } + } + else // we have a header sync and are copying data + { + int need = std::min(length - have, len - used); + if (need) + { + ED("Decode: writing %d\n", need); + PutData(&data[used], need); + have += need; + used += need; + ptsDelay -= need; + if (have == length) + { + FinishIECFrame(); + length = have = 0; + continue; + } + } + } } - ED("Decode: leave length=%d have=%d len=%d used=%d\n",length,have,len,used); + ED("Decode: leave length=%d have=%d len=%d used=%d\n", + length, have, len, used); } -// --- cAudioEncapsulatorAC3 --------------------------------------------------- +// --- cAudioEncapsulatorAC3 -------------------------------------------------- class cAudioEncapsulatorAC3 : public cAudioEncapsulator { private: - virtual int SyncInfo(const uchar *buf); - virtual void StartIECFrame(const uchar *buf, int length, uchar PTSflags, const uchar *PTSdata); + virtual int SyncInfo(const uchar *buf); + virtual void StartIECFrame(const uchar *buf, int length, uchar PTSflags, + const uchar *PTSdata); public: - cAudioEncapsulatorAC3(cRingBufferFrame *rb, int StreamType); - }; + cAudioEncapsulatorAC3(cRingBufferFrame *rb, int StreamType); +}; -cAudioEncapsulatorAC3::cAudioEncapsulatorAC3(cRingBufferFrame *rb, int StreamType) -:cAudioEncapsulator(rb, StreamType) +cAudioEncapsulatorAC3::cAudioEncapsulatorAC3(cRingBufferFrame *rb, + int StreamType) + : cAudioEncapsulator(rb, StreamType) {} int cAudioEncapsulatorAC3::SyncInfo(const uchar *buf) { - static const int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112, - 128, 160, 192, 224, 256, 320, 384, 448, - 512, 576, 640}; - - if ((buf[0] != 0x0B) || (buf[1] != 0x77)) /* syncword */ - return 0; - if (buf[5] >= 0x60) /* bsid >= 12 */ - return 0; - - int frmsizecod = buf[4] & 63; - if (frmsizecod >= 38) - return 0; - int bitrate = rate[frmsizecod >> 1]; - - switch (buf[4] & 0xC0) { - case 0: - return 4 * bitrate; - case 0x40: - return 2 * (320 * bitrate / 147 + (frmsizecod & 1)); - case 0x80: - return 6 * bitrate; - default: - return 0; - } + static const int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112, + 128, 160, 192, 224, 256, 320, 384, 448, + 512, 576, 640 }; + + if ((buf[0] != 0x0B) || (buf[1] != 0x77)) /* syncword */ + return 0; + if (buf[5] >= 0x60) /* bsid >= 12 */ + return 0; + + int frmsizecod = buf[4] & 63; + if (frmsizecod >= 38) + return 0; + int bitrate = rate[frmsizecod >> 1]; + + switch (buf[4] & 0xC0) { + case 0: + return 4 * bitrate; + case 0x40: + return 2 * (320 * bitrate / 147 + (frmsizecod & 1)); + case 0x80: + return 6 * bitrate; + default: + return 0; + } } -void cAudioEncapsulatorAC3::StartIECFrame(const uchar *buf, int length, uchar PTSflags, const uchar *PTSdata) +void cAudioEncapsulatorAC3::StartIECFrame(const uchar *buf, int length, + uchar PTSflags, const uchar *PTSdata) { - StartFrame(AC3_SIZE,PTSflags,PTSdata); - fillup = AC3_SIZE-IEC_HDR_SIZE-length; - - // prepare IEC 60958 data frame - uchar burst[IEC_HDR_SIZE]; - burst[0] = 0xF8; - burst[1] = 0x72; - burst[2] = 0x4E; - burst[3] = 0x1F; - burst[4] = (buf[5] & 0x07); // Pc1 - burst[5] = 0x01; // Pc2 AC-3 - burst[6] = ((length * 8) >> 8 ) & 0xFF; // Pd1 - burst[7] = (length * 8) & 0xFF; // Pd2 - PutData(burst,sizeof(burst)); + StartFrame(AC3_SIZE, PTSflags, PTSdata); + fillup = AC3_SIZE - IEC_HDR_SIZE - length; + + // prepare IEC 60958 data frame + uchar burst[IEC_HDR_SIZE]; + burst[0] = 0xF8; + burst[1] = 0x72; + burst[2] = 0x4E; + burst[3] = 0x1F; + burst[4] = (buf[5] & 0x07); // Pc1 + burst[5] = 0x01; // Pc2 AC-3 + burst[6] = ((length * 8) >> 8 ) & 0xFF; // Pd1 + burst[7] = (length * 8) & 0xFF; // Pd2 + PutData(burst,sizeof(burst)); } -// --- cAudioEncapsulatorDTS --------------------------------------------------- +// --- cAudioEncapsulatorDTS -------------------------------------------------- -class cAudioEncapsulatorDTS : public cAudioEncapsulator { +class cAudioEncapsulatorDTS : public cAudioEncapsulator +{ private: - virtual int SyncInfo(const uchar *buf); - virtual void StartIECFrame(const uchar *buf, int length, uchar PTSflags, const uchar *PTSdata); + virtual int SyncInfo(const uchar *buf); + virtual void StartIECFrame(const uchar *buf, int length, uchar PTSflags, + const uchar *PTSdata); public: - cAudioEncapsulatorDTS(cRingBufferFrame *rb, int StreamType); - }; + cAudioEncapsulatorDTS(cRingBufferFrame *rb, int StreamType); +}; -cAudioEncapsulatorDTS::cAudioEncapsulatorDTS(cRingBufferFrame *rb, int StreamType) -: cAudioEncapsulator(rb, StreamType) +cAudioEncapsulatorDTS::cAudioEncapsulatorDTS(cRingBufferFrame *rb, + int StreamType) + : cAudioEncapsulator(rb, StreamType) {} int cAudioEncapsulatorDTS::SyncInfo(const uchar *buf) { - if ((buf[0] != 0x7F) || - (buf[1] != 0xfE) || - (buf[2] != 0x80) || - (buf[3] != 0x01)) return 0; + if ((buf[0] != 0x7F) || + (buf[1] != 0xfE) || + (buf[2] != 0x80) || + (buf[3] != 0x01)) + return 0; - int length = ((buf[5] & 0x03) << 12) | - ((buf[6] & 0xFF) << 4) | - ((buf[7] & 0xF0) >> 4); + int length = ((buf[5] & 0x03) << 12) | + ((buf[6] & 0xFF) << 4) | + ((buf[7] & 0xF0) >> 4); - return length + 1; + return length + 1; } -void cAudioEncapsulatorDTS::StartIECFrame(const uchar *buf, int length, uchar PTSflags, const uchar *PTSdata) +void cAudioEncapsulatorDTS::StartIECFrame(const uchar *buf, int length, + uchar PTSflags, const uchar *PTSdata) { - uchar ac5_type = ((buf[4] & 0x01) << 6) | ((buf[5] >>2) & 0x3F); - uchar ac5_spdif_type; - switch(ac5_type) { - case 0x0F: - ac5_spdif_type = 0x0B; /* DTS */ - break; - case 0x1F: - ac5_spdif_type = 0x0C; /* DTS */ - break; - case 0x3F: - ac5_spdif_type = 0x0D; /* DTS */ - break; - default: - ac5_spdif_type = 0x00; /* DTS */ - esyslog("DTS: SPDIF type not detected: ac5 type = %X!\n", ac5_type); - break; - } - - if (length > DTS_SIZE-IEC_HDR_SIZE) { - DEBUG("DTS: length too long %d\n",length); - return; - } - - StartFrame(DTS_SIZE,PTSflags,PTSdata); - fillup = DTS_SIZE-IEC_HDR_SIZE-length; - - // prepare IEC 60958 data frame - uchar burst[IEC_HDR_SIZE]; - burst[0] = 0xF8; - burst[1] = 0x72; - burst[2] = 0x4E; - burst[3] = 0x1F; - burst[4] = 0x00; - burst[5] = ac5_spdif_type; /* DTS data */ - burst[6] = ((length * 8) >> 8 ) & 0xFF; /* ac5_length * 8 */ - burst[7] = (length * 8) & 0xFF; - PutData(burst,sizeof(burst)); + uchar ac5_type = ((buf[4] & 0x01) << 6) | ((buf[5] >>2) & 0x3F); + uchar ac5_spdif_type; + switch(ac5_type) + { + case 0x0F: + ac5_spdif_type = 0x0B; // DTS + break; + case 0x1F: + ac5_spdif_type = 0x0C; // DTS + break; + case 0x3F: + ac5_spdif_type = 0x0D; // DTS + break; + default: + ac5_spdif_type = 0x00; // DTS + esyslog("DTS: SPDIF type not detected: ac5 type = %X!\n", ac5_type); + break; + } + + if (length > DTS_SIZE-IEC_HDR_SIZE) + { + DEBUG("DTS: length too long %d\n", length); + return; + } + + StartFrame(DTS_SIZE, PTSflags, PTSdata); + fillup = DTS_SIZE - IEC_HDR_SIZE - length; + + // prepare IEC 60958 data frame + uchar burst[IEC_HDR_SIZE]; + burst[0] = 0xF8; + burst[1] = 0x72; + burst[2] = 0x4E; + burst[3] = 0x1F; + burst[4] = 0x00; + burst[5] = ac5_spdif_type; // DTS data + burst[6] = ((length * 8) >> 8) & 0xFF; // ac5_length * 8 + burst[7] = (length * 8) & 0xFF; + PutData(burst,sizeof(burst)); } -// --- cMultichannelAudio ------------------------------------------------------ +// --- cMultichannelAudio ----------------------------------------------------- cMultichannelAudio::cMultichannelAudio(cRingBufferFrame *rb) { - encapsulator=0; ringBuffer=rb; - fixed=false; - if(!ringBuffer) DEBUG("multichannel: no ringbuffer!"); + encapsulator = 0; + ringBuffer = rb; + fixed = false; + if (!ringBuffer) + DEBUG("multichannel: no ringbuffer!"); } cMultichannelAudio::~cMultichannelAudio() { - delete encapsulator; + delete encapsulator; } void cMultichannelAudio::Clear() { - Lock(); - if(encapsulator) encapsulator->Clear(); - Unlock(); + Lock(); + if (encapsulator) + encapsulator->Clear(); + Unlock(); } void cMultichannelAudio::Reset() { - Lock(); - delete encapsulator; encapsulator=0; - fixed=false; - Unlock(); + Lock(); + delete encapsulator; + encapsulator = 0; + fixed = false; + Unlock(); } /* void cMultichannelAudio::Mute(bool Mute) { - Lock(); - if(encapsulator) encapsulator->Mute(Mute); - Unlock(); + Lock(); + if (encapsulator) + encapsulator->Mute(Mute); + Unlock(); } */ int cMultichannelAudio::Check(uchar *b, int length, uchar *header) { - Lock(); - int res=0; - ptsDelay=0; offset=0; ptsData=0; - - // get PTS information - ptsFlags=header[7]>>6; - if(ptsFlags) ptsData=&header[9]; - - // AC3 frames may span over multiple PES packets. Unfortunaly the continuation - // packets start with the aLPCM code sometimes. Some magic here to detect - // this case. - uchar subStreamType=b[0]; - if(subStreamType!=aVDR) subStreamType&=0xF8; - bool aligned=header[6]&4; - if(!aligned) { - uchar ost=encapsulator ? encapsulator->StreamType() : 0; - if(!ptsFlags) { - if((subStreamType!=aLPCM && subStreamType!=aSPU) || fixed) { - if(ost>0) { - ED("multichannel: crossing -> keep encapsulator\n"); - subStreamType=ost; - } - else { - ED("multichannel: crossing -> skip\n"); - res=1; goto out; // skip - } - } - } - else if(fixed && ost>0) { - ED("multichannel: fixed unaligned -> keep encapsulator\n"); - subStreamType=ost; - } + Lock(); + int res = 0; + ptsDelay = 0; + offset = 0; + ptsData = 0; + + // get PTS information + ptsFlags = header[7] >> 6; + if (ptsFlags) + ptsData = &header[9]; + + // AC3 frames may span over multiple PES packets. Unfortunately the + // continuation packets start with the aLPCM code sometimes. Some magic + // here to detect this case. + uchar subStreamType = b[0]; + if (subStreamType != aVDR) + subStreamType&=0xF8; + bool aligned = header[6] & 4; + if (!aligned) + { + uchar ost = encapsulator ? encapsulator->StreamType() : 0; + if (!ptsFlags) + { + if ((subStreamType != aLPCM && subStreamType != aSPU) || fixed) + { + if (ost > 0) + { + ED("multichannel: crossing -> keep encapsulator\n"); + subStreamType = ost; + } + else + { + ED("multichannel: crossing -> skip\n"); + res = 1; + goto out; // skip + } + } + } + else if (fixed && ost > 0) + { + ED("multichannel: fixed unaligned -> keep encapsulator\n"); + subStreamType = ost; + } } - fixed=false; + fixed = false; - switch(subStreamType) { + switch (subStreamType) + { case aDTS: case aAC3: - offset=4; // skip the DVD stream infos - break; + offset = 4; // skip the DVD stream infos + break; default: - if(aligned || !ptsFlags) { - if(encapsulator) { - Reset(); - DEBUG("multichannel: interrupted encapsulator stream (unknown)\n"); - } - DEBUG("multichannel: unknown substream type %x (skipped)\n",subStreamType); - res=1; goto out; // skip - } - subStreamType=aVDR; - ED("multichannel: assuming aVDR for unknown substream type\n"); - // fall through + if (aligned || !ptsFlags) + { + if (encapsulator) + { + Reset(); + DEBUG("multichannel: interrupted encapsulator stream (unknown)\n"); + } + DEBUG("multichannel: unknown substream type %x (skipped)\n", + subStreamType); + res = 1; + goto out; // skip + } + subStreamType = aVDR; + ED("multichannel: assuming aVDR for unknown substream type\n"); + // fall through case aVDR: - fixed=true; - break; + fixed = true; + break; case aLPCM: - if(encapsulator) { - Reset(); - DEBUG("multichannel: interrupted encapsulator stream (LPCM)\n"); - } - ED("multichannel: LPCM\n"); - res=2; goto out; // pass + if (encapsulator) + { + Reset(); + DEBUG("multichannel: interrupted encapsulator stream (LPCM)\n"); + } + ED("multichannel: LPCM\n"); + res = 2; + goto out; // pass case aSPU: - ED("multichannel: SPU stream (skipped)\n"); - res=1; goto out; // skip + ED("multichannel: SPU stream (skipped)\n"); + res = 1; + goto out; // skip } - // If the SubStreamType has changed then select the right encapsulator - if(!encapsulator || encapsulator->StreamType()!=subStreamType) { - DEBUG("multichannel: new encapsulator %x\n",subStreamType); - Reset(); - switch(subStreamType) { - case aAC3: - case aVDR: // AC3 - encapsulator=new cAudioEncapsulatorAC3(ringBuffer,subStreamType); - break; - case aDTS: // Dts - encapsulator=new cAudioEncapsulatorDTS(ringBuffer,subStreamType); - break; - } - if(!encapsulator) { - DEBUG("multichannel: no encapsulator\n"); - res=1; goto out; // skip - } + // If the SubStreamType has changed then select the right encapsulator + if (!encapsulator || encapsulator->StreamType() != subStreamType) + { + DEBUG("multichannel: new encapsulator %x\n", subStreamType); + Reset(); + switch (subStreamType) + { + case aAC3: + case aVDR: // AC3 + encapsulator = new cAudioEncapsulatorAC3(ringBuffer,subStreamType); + break; + case aDTS: // Dts + encapsulator = new cAudioEncapsulatorDTS(ringBuffer,subStreamType); + break; + } + if (!encapsulator) + { + DEBUG("multichannel: no encapsulator\n"); + res = 1; + goto out; // skip + } } out: - ED("HEADER type=%x sub=%x ptsflags=%d length=%d\n",header[3],subStreamType,ptsFlags,length); - ED("head: "); for(int k=0 ; k<24 ; k++) ED("%02x ",header[k]); - ED("\ndata: "); for(int k=0 ; k<24 ; k++) ED("%02x ",b[k]); - ED("\n"); + ED("HEADER type=%x sub=%x ptsflags=%d length=%d\n", + header[3], subStreamType, ptsFlags, length); + ED("head: "); for(int k = 0; k < 24; k++) ED("%02x ", header[k]); + ED("\ndata: "); for(int k = 0; k < 24; k++) ED("%02x ", b[k]); + ED("\n"); - Unlock(); return res; + Unlock(); + return res; } void cMultichannelAudio::Encapsulate(uchar *b, int length) { - Lock(); - if(offset && ptsFlags) { // get start of the packet to which the PTS belong (DVD only) - if(offset>=2 && length>offset-2) ptsDelay|=b[offset-2]*256; - if(offset>=1 && length>offset-1) ptsDelay|=b[offset-1]; + Lock(); + if(offset && ptsFlags) + { // get start of the packet to which the PTS belong (DVD only) + if (offset >= 2 && length > offset - 2) + ptsDelay |= b[offset - 2] * 256; + if (offset >= 1 && length > offset - 1) + ptsDelay |= b[offset - 1]; } - if(length>=offset) { - if(encapsulator) - encapsulator->Decode(b+offset,length-offset,ptsFlags,ptsDelay,ptsData); - ptsFlags=0; ptsDelay=0; offset=0; ptsData=0; + if (length >= offset) + { + if (encapsulator) + encapsulator->Decode(b+offset, length - offset, ptsFlags, + ptsDelay, ptsData); + ptsFlags = 0; + ptsDelay = 0; + offset = 0; + ptsData = 0; } - else offset-=length; - Unlock(); + else + offset -= length; + Unlock(); } // Local variables: diff --git a/dxr3multichannelaudio.h b/dxr3multichannelaudio.h index fcd0594..d2dd40c 100644 --- a/dxr3multichannelaudio.h +++ b/dxr3multichannelaudio.h @@ -12,22 +12,25 @@ class cRingBufferFrame; class cMultichannelAudio : public cMutex { private: - cAudioEncapsulator *encapsulator; - cRingBufferFrame *ringBuffer; - int ptsFlags, ptsDelay, offset; - uchar *ptsData; - bool fixed; + cAudioEncapsulator *encapsulator; + cRingBufferFrame *ringBuffer; + int ptsFlags, ptsDelay, offset; + uchar *ptsData; + bool fixed; public: - cMultichannelAudio(cRingBufferFrame *rb); - virtual ~cMultichannelAudio(); + cMultichannelAudio(cRingBufferFrame *rb); + virtual ~cMultichannelAudio(); - int Check(uchar *b, int length, uchar *header); - int Offset(void) { return offset; } - void Encapsulate(uchar *b, int length); - void Clear(); - void Reset(); - //void Mute(bool Mute); + int Check(uchar *b, int length, uchar *header); + int Offset(void) + { + return offset; + } + void Encapsulate(uchar *b, int length); + void Clear(); + void Reset(); + //void Mute(bool Mute); }; #endif /*_DXR3MULTICHANNELAUDIO_H_*/ diff --git a/dxr3nextpts.h b/dxr3nextpts.h index 4d66d0a..3b459d4 100644 --- a/dxr3nextpts.h +++ b/dxr3nextpts.h @@ -23,7 +23,7 @@ #define _DXR3NEXTPTS_H_ #include <unistd.h> -#include <stdint.h> +#include <stdint.h> #include "dxr3vdrincludes.h" #include "dxr3singleton.h" @@ -36,20 +36,43 @@ public: cDxr3NextPts() {} ~cDxr3NextPts() {} - void SetNextPts(uint32_t pts) { Lock(); if (pts) m_nextPts = pts; Unlock(); } - uint32_t GetNextPts() { Lock(); uint32_t tmpPts = m_nextPts; Unlock(); return tmpPts;} + void SetNextPts(uint32_t pts) + { + Lock(); + if (pts) + m_nextPts = pts; + Unlock(); + } + uint32_t GetNextPts() + { + Lock(); + uint32_t tmpPts = m_nextPts; + Unlock(); + return tmpPts; + } + + void Clear() + { + Lock(); + m_nextPts = 0; + Unlock(); + } - void Clear() { Lock(); m_nextPts = 0; Unlock();} - protected: static cMutex* m_pMutex; uint32_t m_nextPts; - static void Lock() {cDxr3NextPts::m_pMutex->Lock();} - static void Unlock() {cDxr3NextPts::m_pMutex->Unlock();} - + static void Lock() + { + cDxr3NextPts::m_pMutex->Lock(); + } + static void Unlock() + { + cDxr3NextPts::m_pMutex->Unlock(); + } + private: - cDxr3NextPts(cDxr3NextPts&); // no copy constructor + cDxr3NextPts(cDxr3NextPts&); // no copy constructor }; #endif /*_DXR3NEXTPTS_H_*/ @@ -40,123 +40,135 @@ // ! create osd at (Left, Top) cOsd *cDxr3OsdProvider::CreateOsd(int Left, int Top) { -// if (cDxr3ConfigData::Instance().GetMenuMode() == (eMenuMode)SUBPICTURE) -// { - // use subpicture - return new cDxr3SubpictureOsd(Left, Top); -/* } - else - { - // mpeg based menu system - return new cDxr3MpegOsd(Left, Top); - }*/ + /* + if (cDxr3ConfigData::Instance().GetMenuMode() == (eMenuMode) SUBPICTURE) + { + */ + // use subpicture + return new cDxr3SubpictureOsd(Left, Top); + /* + } + else + { + // mpeg based menu system + return new cDxr3MpegOsd(Left, Top); + } + */ } #else /*VDRVERSNUM*/ // ================================== -bool cDxr3Osd::SetWindow(cWindow *Window) +bool cDxr3Osd::SetWindow(cWindow *Window) { - if (Window) + if (Window) + { + // Window handles are counted 0...(MAXNUMWINDOWS - 1), but the actual + // window numbers in the driver are used from 1...MAXNUMWINDOWS. + int Handle = Window->Handle(); + if (0 <= Handle && Handle < MAXNUMWINDOWS) + { + Spu->Cmd(OSD_SetWindow, 0, Handle + 1); + return true; + } + esyslog("ERROR: illegal window handle: %d", Handle); + + if (cDxr3ConfigData::Instance().GetDebug()) { - // Window handles are counted 0...(MAXNUMWINDOWS - 1), but the actual window - // numbers in the driver are used from 1...MAXNUMWINDOWS. - int Handle = Window->Handle(); - if (0 <= Handle && Handle < MAXNUMWINDOWS) - { - Spu->Cmd(OSD_SetWindow, 0, Handle + 1); - return true; - } - esyslog("ERROR: illegal window handle: %d", Handle); - - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "cDxr3Osd::SetWindow: illegal window handle:" << Handle << "\n"; - } + cLog::Instance() << "cDxr3Osd::SetWindow: illegal window handle:" + << Handle << "\n"; } - return false; + } + return false; } // ================================== cDxr3Osd::cDxr3Osd(int x, int y) : cOsdBase(x, y) -{ +{ Spu = &cSPUEncoder::Instance(); } // ================================== cDxr3Osd::~cDxr3Osd() { - for (int i = 0; i < NumWindows(); i++) - { - CloseWindow(GetWindowNr(i)); - } + for (int i = 0; i < NumWindows(); i++) + { + CloseWindow(GetWindowNr(i)); + } } // ================================== bool cDxr3Osd::OpenWindow(cWindow *Window) { - if (SetWindow(Window)) - { - Spu->Cmd(OSD_Open, Window->Bpp(), X0() + Window->X0(), Y0() + Window->Y0(), X0() + Window->X0() + Window->Width() - 1, Y0() + Window->Y0() + Window->Height() - 1, (void *)1); // initially hidden! - return true; - } - return false; + if (SetWindow(Window)) + { + Spu->Cmd(OSD_Open, + Window->Bpp(), + X0() + Window->X0(), + Y0() + Window->Y0(), + X0() + Window->X0() + Window->Width() - 1, + Y0() + Window->Y0() + Window->Height() - 1, + (void *)1); // initially hidden! + return true; + } + return false; } // ================================== void cDxr3Osd::CommitWindow(cWindow *Window) { - if (SetWindow(Window)) + if (SetWindow(Window)) + { + int x1 = 0, y1 = 0, x2 = 0, y2 = 0; + + if (Window->Dirty(x1, y1, x2, y2)) { - int x1 = 0, y1 = 0, x2 = 0, y2 = 0; - - if (Window->Dirty(x1, y1, x2, y2)) - { - // commit colors: - int FirstColor = 0, LastColor = 0; - const eDvbColor *pal; - while ((pal = Window->NewColors(FirstColor, LastColor)) != NULL) - Spu->Cmd(OSD_SetPalette, FirstColor, LastColor, 0, 0, 0, pal); - // commit modified data: - Spu->Cmd(OSD_SetBlock, Window->Width(), x1, y1, x2, y2, Window->Data(x1, y1)); - } + // commit colors: + int FirstColor = 0, LastColor = 0; + const eDvbColor *pal; + while ((pal = Window->NewColors(FirstColor, LastColor)) != NULL) + Spu->Cmd(OSD_SetPalette, FirstColor, LastColor, 0, 0, 0, pal); + // commit modified data: + Spu->Cmd(OSD_SetBlock, Window->Width(), x1, y1, x2, y2, + Window->Data(x1, y1)); } + } } // ================================== void cDxr3Osd::ShowWindow(cWindow *Window) { - if (SetWindow(Window)) - { - Spu->Cmd(OSD_MoveWindow, 0, X0() + Window->X0(), Y0() + Window->Y0()); - } + if (SetWindow(Window)) + { + Spu->Cmd(OSD_MoveWindow, 0, X0() + Window->X0(), Y0() + Window->Y0()); + } } // ================================== void cDxr3Osd::HideWindow(cWindow *Window, bool Hide) { - if (SetWindow(Window)) - { - Spu->Cmd(Hide ? OSD_Hide : OSD_Show, 0); - } + if (SetWindow(Window)) + { + Spu->Cmd(Hide ? OSD_Hide : OSD_Show, 0); + } } // ================================== void cDxr3Osd::CloseWindow(cWindow *Window) { - if (SetWindow(Window)) - { - Spu->Cmd(OSD_Close); - } + if (SetWindow(Window)) + { + Spu->Cmd(OSD_Close); + } } // ================================== void cDxr3Osd::MoveWindow(cWindow *Window, int x, int y) { - if (SetWindow(Window)) - { - Spu->Cmd(OSD_MoveWindow, 0, X0() + x, Y0() + y); - } + if (SetWindow(Window)) + { + Spu->Cmd(OSD_MoveWindow, 0, X0() + x, Y0() + y); + } } #endif /*VDRVERSNUM*/ @@ -8,10 +8,10 @@ // ================================== // osd plugin provider -class cDxr3OsdProvider : public cOsdProvider +class cDxr3OsdProvider : public cOsdProvider { public: - cDxr3OsdProvider() {} + cDxr3OsdProvider() {} virtual cOsd *CreateOsd(int Left, int Top); }; @@ -19,12 +19,12 @@ public: // ================================== // osd interface for =< vdr1,3,7 -class cDxr3Osd : public cOsdBase +class cDxr3Osd : public cOsdBase { private: cSPUEncoder* Spu; ///< interface to cSPUEncoder - bool SetWindow(cWindow*); + bool SetWindow(cWindow*); public: cDxr3Osd(int x, int y); diff --git a/dxr3osd_subpicture.c b/dxr3osd_subpicture.c index 47d4712..b96b0c2 100644 --- a/dxr3osd_subpicture.c +++ b/dxr3osd_subpicture.c @@ -3,27 +3,30 @@ // Enables some time measure debugging code // (taken from the osdteletext plugin, thanks folks) #ifdef timingdebug - #include <sys/timeb.h> - - class cTime { - // Debugging: Simple class to measure time - timeb start; - public: - void Start() { - ftime(&start); - } - void Stop(char *txt) { - timeb t; - ftime(&t); - int s=t.time-start.time; - int ms=t.millitm-start.millitm; - if (ms<0) { - s--; - ms+=1000; - } - printf("%s: %i.%03i\n",txt,s,ms); - } - }; +#include <sys/timeb.h> +class cTime +{ + // Debugging: Simple class to measure time + timeb start; +public: + void Start() + { + ftime(&start); + } + void Stop(char *txt) + { + timeb t; + ftime(&t); + int s = t.time-start.time; + int ms = t.millitm - start.millitm; + if (ms<0) + { + s--; + ms += 1000; + } + printf("%s: %i.%03i\n", txt, s, ms); + } +}; #endif #if VDRVERSNUM >= 10307 @@ -34,28 +37,28 @@ //! constructor cDxr3SubpictureOsd::cDxr3SubpictureOsd(int Left, int Top) : cOsd(Left, Top) { - shown = false; - Palette = new cPalette(4); + shown = false; + Palette = new cPalette(4); #if VDRVERSNUM >= 10318 - last = new cTimeMs(); - last->Set(-FLUSHRATE); + last = new cTimeMs(); + last->Set(-FLUSHRATE); #else - last = time_ms() - FLUSHRATE; + last = time_ms() - FLUSHRATE; #endif - Spu = &cSPUEncoder::Instance(); - - //Clears the OSD screen image - Spu->Clear(); + Spu = &cSPUEncoder::Instance(); + + //Clears the OSD screen image + Spu->Clear(); } // ================================== cDxr3SubpictureOsd::~cDxr3SubpictureOsd() { - //Remove the OSD from the screen - Spu->StopSpu(); - delete Palette; + //Remove the OSD from the screen + Spu->StopSpu(); + delete Palette; #if VDRVERSNUM >= 10318 - delete last; + delete last; #endif } @@ -63,176 +66,198 @@ cDxr3SubpictureOsd::~cDxr3SubpictureOsd() eOsdError cDxr3SubpictureOsd::CanHandleAreas(const tArea *Areas, int NumAreas) { - eOsdError Result = cOsd::CanHandleAreas(Areas, NumAreas); - if (Result == oeOk) + eOsdError Result = cOsd::CanHandleAreas(Areas, NumAreas); + if (Result == oeOk) + { + if (NumAreas > MAXNUMWINDOWS) { - if (NumAreas > MAXNUMWINDOWS) - { - return oeTooManyAreas; - } - - for (int i = 0; i < NumAreas; i++) - { - if (Areas[i].bpp != 1 && Areas[i].bpp != 2 && Areas[i].bpp != 4 && Areas[i].bpp != 8) - { - return oeBppNotSupported; - } - - if ((Areas[i].Width() & (8 / Areas[i].bpp - 1)) != 0) - { - return oeWrongAlignment; - } - } + return oeTooManyAreas; + } + + for (int i = 0; i < NumAreas; i++) + { + if (Areas[i].bpp != 1 && + Areas[i].bpp != 2 && + Areas[i].bpp != 4 && + Areas[i].bpp != 8) + { + return oeBppNotSupported; + } + + if ((Areas[i].Width() & (8 / Areas[i].bpp - 1)) != 0) + { + return oeWrongAlignment; + } } - return Result; + } + return Result; } // ================================== void cDxr3SubpictureOsd::SaveRegion(int x1, int y1, int x2, int y2) { - // ToDo? + // ToDo? } // ================================== void cDxr3SubpictureOsd::RestoreRegion() { - // ToDo? + // ToDo? } // ================================== void cDxr3SubpictureOsd::Flush() { #if VDRVERSNUM >= 10318 - if (last->Elapsed()<FLUSHRATE) return; - last->Set(); + if (last->Elapsed()<FLUSHRATE) return; + last->Set(); #else - if (time_ms()-last<FLUSHRATE) return; - last = time_ms(); + if (time_ms()-last<FLUSHRATE) return; + last = time_ms(); +#endif + +#ifdef timingdebug + cTime t; + t.Start(); #endif - #ifdef timingdebug - cTime t; - t.Start(); - #endif - - cBitmap *Bitmap; - int oldi; - int newi; - int i; - int indexfree[16]; - int firstfree=-1; - int indexnoassigned[16]; - int firstnoassigned=-1; - bool colfree[16]; - int NumNewColors; - int NumOldColors; - - //determine the palette used by all bitmaps (without alpha channel) - - cPalette *newPalette=new cPalette(4); - for (i=0; i<16; i++) colfree[i]=true; - for (i=0; (Bitmap = GetBitmap(i)) != NULL; i++) { - int nc; - const tColor *col=Bitmap->Colors(nc); - if (col) for (int kk=0; kk<nc; kk++) newPalette->Index(col[kk] & 0x00FFFFFF); - } - const tColor *newColors=newPalette->Colors(NumNewColors); - const tColor *oldColors=Palette->Colors(NumOldColors); - //colors already assigned - for (newi=0;newi<NumNewColors;newi++) { - for(oldi=0;oldi<NumOldColors;oldi++) { - if (newColors[newi]==oldColors[oldi]) { - colfree[oldi]=false; - break; + cBitmap *Bitmap; + int oldi; + int newi; + int i; + int indexfree[16]; + int firstfree = -1; + int indexnoassigned[16]; + int firstnoassigned = -1; + bool colfree[16]; + int NumNewColors; + int NumOldColors; + + //determine the palette used by all bitmaps (without alpha channel) + + cPalette *newPalette = new cPalette(4); + for (i = 0; i < 16; i++) + colfree[i]=true; + for (i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) + { + int nc; + const tColor *col = Bitmap->Colors(nc); + if (col) + for (int kk = 0; kk < nc; kk++) + newPalette->Index(col[kk] & 0x00FFFFFF); + } + const tColor *newColors = newPalette->Colors(NumNewColors); + const tColor *oldColors = Palette->Colors(NumOldColors); + // colors already assigned + for (newi = 0; newi < NumNewColors; newi++) + { + for (oldi = 0; oldi < NumOldColors; oldi++) + { + if (newColors[newi] == oldColors[oldi]) + { + colfree[oldi] = false; + break; } - } - if (oldi>=NumOldColors) { - firstnoassigned++; - indexnoassigned[firstnoassigned]=newi; - } } - //unused colors - for (i=0; i<NumOldColors; i++) { - if(colfree[i]) { + if (oldi >= NumOldColors) + { + firstnoassigned++; + indexnoassigned[firstnoassigned] = newi; + } + } + // unused colors + for (i = 0; i < NumOldColors; i++) + { + if (colfree[i]) { firstfree++; - indexfree[firstfree]=i; - } + indexfree[firstfree] = i; } - //replace unused colors with unassigned ones - for (i=0; i<=firstnoassigned; i++) { - newi=indexnoassigned[i]; - if (firstfree>=0) { + } + // replace unused colors with unassigned ones + for (i = 0; i <= firstnoassigned; i++) + { + newi = indexnoassigned[i]; + if (firstfree >= 0) + { Palette->SetColor(indexfree[firstfree], newColors[newi]); firstfree--; - } else { + } else { Palette->Index(newColors[newi]); - } } - delete newPalette; - - //Shove the bitmaps to the OSD global bitmap - for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) + } + delete newPalette; + + // Shove the bitmaps to the OSD global bitmap + for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) + { + int x1 = 0, y1 = 0, x2 = 0, y2 = 0; + if (Bitmap->Dirty(x1, y1, x2, y2)) { - int x1 = 0, y1 = 0, x2 = 0, y2 = 0; - if (Bitmap->Dirty(x1, y1, x2, y2)) + /* TODO workaround: + apparently the bitmap sent to the driver always has to be a + multiple of 8 bits wide, and (dx * dy) also has to be a + multiple of 8. Fix driver (should be able to handle any size + bitmaps!) + This isn't actually necessary with this plugin, but since other + plugins rely on this behaviour to work correctly, I left it + here. It doesn't hurt too much. + */ + + while ((x1 > 0 || x2 < Bitmap->Width() - 1) && + ((x2 - x1) & 7) != 7) + { + if (x2 < Bitmap->Width() - 1) + { + x2++; + } + else if (x1 > 0) + { + x1--; + } + } + + //TODO "... / 2" <==> Bpp??? + while ((y1 > 0 || y2 < Bitmap->Height() - 1) && + (((x2 - x1 + 1) * (y2 - y1 + 1) / 2) & 7) != 0) + { + if (y2 < Bitmap->Height() - 1) + { + y2++; + } + else if (y1 > 0) { - //TODO Workaround: apparently the bitmap sent to the driver always has to be a multiple - //TODO of 8 bits wide, and (dx * dy) also has to be a multiple of 8. - //TODO Fix driver (should be able to handle any size bitmaps!) - // - // This isn't actually necessary with this plugin, but since other plugins rely - // on this behaviour to work correctly, I left it here. It doesn't hurt too much. - - while ((x1 > 0 || x2 < Bitmap->Width() - 1) && ((x2 - x1) & 7) != 7) - { - if (x2 < Bitmap->Width() - 1) - { - x2++; - } - else if (x1 > 0) - { - x1--; - } - } - - //TODO "... / 2" <==> Bpp??? - while ((y1 > 0 || y2 < Bitmap->Height() - 1) && (((x2 - x1 + 1) * (y2 - y1 + 1) / 2) & 7) != 0) - { - if (y2 < Bitmap->Height() - 1) - { - y2++; - } - else if (y1 > 0) - { - y1--; - } - } - - while ((x1 > 0 || x2 < Bitmap->Width() - 1) && (((x2 - x1 + 1) * (y2 - y1 + 1) / 2) & 7) != 0) - { - if (x2 < Bitmap->Width() - 1) - { - x2++; - } - else if (x1 > 0) - { - x1--; - } - } - - Spu->SetPalette(i+1,Palette,Bitmap); - int origx=Left()+Bitmap->X0(); - int origy=Top()+Bitmap->Y0(); - Spu->CopyBlockIntoOSD(i+1, Bitmap->Width(), origx+x1, origy+y1, origx+x2, origy+y2, Bitmap->Data(x1, y1)); - Bitmap->Clean(); + y1--; } + } + + while ((x1 > 0 || x2 < Bitmap->Width() - 1) && + (((x2 - x1 + 1) * (y2 - y1 + 1) / 2) & 7) != 0) + { + if (x2 < Bitmap->Width() - 1) + { + x2++; + } + else if (x1 > 0) + { + x1--; + } + } + + Spu->SetPalette(i + 1, Palette, Bitmap); + int origx = Left() + Bitmap->X0(); + int origy = Top() + Bitmap->Y0(); + Spu->CopyBlockIntoOSD(i + 1, Bitmap->Width(), origx + x1, + origy + y1, origx + x2, origy + y2, + Bitmap->Data(x1, y1)); + Bitmap->Clean(); } - - Spu->Flush(Palette); - shown = true; - #ifdef timingdebug - t.Stop("cDxr3SubpictureOsd::Flush"); - #endif + } + + Spu->Flush(Palette); + shown = true; +#ifdef timingdebug + t.Stop("cDxr3SubpictureOsd::Flush"); +#endif } #endif /*VDRVERSNUM*/ diff --git a/dxr3osd_subpicture.h b/dxr3osd_subpicture.h index c9db4ef..1500d60 100644 --- a/dxr3osd_subpicture.h +++ b/dxr3osd_subpicture.h @@ -11,22 +11,22 @@ class cDxr3SubpictureOsd : public cOsd { private: - cSPUEncoder* Spu; ///< interface to cSPUEncoder - bool shown; ///< is the osd shown? - cPalette* Palette; ///< global palette (needed by all bitmaps) + cSPUEncoder* Spu; ///< interface to cSPUEncoder + bool shown; ///< is the osd shown? + cPalette* Palette; ///< global palette (needed by all bitmaps) #if VDRVERSNUM >= 10318 - cTimeMs *last; + cTimeMs *last; #else - int last; + int last; #endif public: - cDxr3SubpictureOsd(int Left, int Top/*, int SpuDev*/); - ~cDxr3SubpictureOsd(); + cDxr3SubpictureOsd(int Left, int Top/*, int SpuDev*/); + ~cDxr3SubpictureOsd(); - eOsdError CanHandleAreas(const tArea *Areas, int NumAreas); - void SaveRegion(int x1, int y1, int x2, int y2); - void RestoreRegion(void); + eOsdError CanHandleAreas(const tArea *Areas, int NumAreas); + void SaveRegion(int x1, int y1, int x2, int y2); + void RestoreRegion(void); void Flush(); }; diff --git a/dxr3outputthread.c b/dxr3outputthread.c index ba7e7bb..34fc79c 100644 --- a/dxr3outputthread.c +++ b/dxr3outputthread.c @@ -26,21 +26,26 @@ #include "dxr3outputthread.h" #include "dxr3log.h" -// ================================== +// ================================== const int AUDIO_OFFSET = 4500; #define SCR m_dxr3Device.GetSysClock() -// ================================== +// ================================== -// ================================== +// ================================== //! constructor -cDxr3OutputThread::cDxr3OutputThread(cDxr3Interface& dxr3Device, cDxr3SyncBuffer& buffer) : -cThread(), m_dxr3Device(dxr3Device), m_buffer(buffer), m_bStopThread(false), m_bNeedResync(false) +cDxr3OutputThread::cDxr3OutputThread(cDxr3Interface& dxr3Device, + cDxr3SyncBuffer& buffer) : + cThread(), + m_dxr3Device(dxr3Device), + m_buffer(buffer), + m_bStopThread(false), + m_bNeedResync(false) { } -// ================================== +// ================================== //! send stop signal -void cDxr3OutputThread::SetStopSignal() +void cDxr3OutputThread::SetStopSignal() { Lock(); m_bStopThread = true; @@ -49,7 +54,7 @@ void cDxr3OutputThread::SetStopSignal() // ================================== //! was stop signal send? -bool cDxr3OutputThread::GetStopSignal() +bool cDxr3OutputThread::GetStopSignal() { bool ret = false; Lock(); @@ -61,8 +66,9 @@ bool cDxr3OutputThread::GetStopSignal() // ================================== //! constr. -cDxr3AudioOutThread::cDxr3AudioOutThread(cDxr3Interface& dxr3Device, cDxr3SyncBuffer& buffer) : -cDxr3OutputThread(dxr3Device, buffer) +cDxr3AudioOutThread::cDxr3AudioOutThread(cDxr3Interface& dxr3Device, + cDxr3SyncBuffer& buffer) : + cDxr3OutputThread(dxr3Device, buffer) { #if VDRVERSNUM >= 10300 SetDescription("DXR3 audio output"); @@ -79,83 +85,85 @@ cDxr3AudioOutThread::~cDxr3AudioOutThread() // ================================== //! thread action -void cDxr3AudioOutThread::Action() -{ +void cDxr3AudioOutThread::Action() +{ bool resync = false; uint32_t pts = 0; - + cLog::Instance() << "cDxr3AudioOutThread::Action Thread started\n"; sched_param temp; temp.sched_priority = 2; - if (!pthread_setschedparam(pthread_self(), SCHED_RR, &temp)) - { - cLog::Instance() << "cDxr3AudioOutThread::Action(): Error can't set priority\n"; - } + if (!pthread_setschedparam(pthread_self(), SCHED_RR, &temp)) + { + cLog::Instance() << "cDxr3AudioOutThread::Action(): Error can't set priority\n"; + } - while (!GetStopSignal()) + while (!GetStopSignal()) + { + pts = 0; + cFixedLengthFrame* pNext = m_buffer.Get(); + + if (pNext) pts = pNext->GetPts(); + + if (pts && abs((int)pts-(int)SCR) > 30000 || + m_dxr3Device.IsExternalReleased()) { - pts = 0; - cFixedLengthFrame* pNext = m_buffer.Get(); + m_buffer.Clear(); + m_bNeedResync = true; + } + else if (pNext) + { + if (!pts || pts < SCR) + { + if (!pts && resync) + { + continue; + } + else + { + resync = false; + } - if (pNext) pts = pNext->GetPts(); - - if (pts && abs((int)pts-(int)SCR) > 30000 || m_dxr3Device.IsExternalReleased()) + if (pts && (pts < SCR) && ((SCR - pts) > 5000)) { - m_buffer.Clear(); - m_bNeedResync = true; - } - else if (pNext) + m_dxr3Device.SetSysClock(pts + 1 * AUDIO_OFFSET); + m_dxr3Device.PlayAudioFrame(pNext); + if (m_buffer.IsPolled()) + { + m_buffer.Clear(); + m_bNeedResync = true; + } + } + else { - if (!pts || pts < SCR) - { - if (!pts && resync) - { - continue; - } - else - { - resync = false; - } - - if (pts && (pts < SCR) && ((SCR - pts) > 5000)) - { - m_dxr3Device.SetSysClock(pts+ 1 * AUDIO_OFFSET); - m_dxr3Device.PlayAudioFrame(pNext); - if (m_buffer.IsPolled()) - { - m_buffer.Clear(); - m_bNeedResync = true; - } - } - else - { - m_dxr3Device.PlayAudioFrame(pNext); - m_buffer.Pop(); - } - } - else - { - if (abs((int)pts - (int)SCR) < (AUDIO_OFFSET )) - { - m_dxr3Device.PlayAudioFrame(pNext); - m_buffer.Pop(); - } - } - } - - if ((pts > SCR && abs((int)pts - (int)SCR) > AUDIO_OFFSET)) + m_dxr3Device.PlayAudioFrame(pNext); + m_buffer.Pop(); + } + } + else + { + if (abs((int)pts - (int)SCR) < (AUDIO_OFFSET )) { - usleep(10000); - } + m_dxr3Device.PlayAudioFrame(pNext); + m_buffer.Pop(); + } + } + } + + if ((pts > SCR && abs((int)pts - (int)SCR) > AUDIO_OFFSET)) + { + usleep(10000); + } } } // ================================== //! constr. -cDxr3VideoOutThread::cDxr3VideoOutThread(cDxr3Interface& dxr3Device, cDxr3SyncBuffer& buffer) : -cDxr3OutputThread(dxr3Device, buffer) +cDxr3VideoOutThread::cDxr3VideoOutThread(cDxr3Interface& dxr3Device, + cDxr3SyncBuffer& buffer) : + cDxr3OutputThread(dxr3Device, buffer) { #if VDRVERSNUM >= 10300 SetDescription("DXR3 video output"); @@ -172,80 +180,81 @@ cDxr3VideoOutThread::~cDxr3VideoOutThread() // ================================== //! thread action -void cDxr3VideoOutThread::Action() +void cDxr3VideoOutThread::Action() { uint32_t pts = 0; static uint32_t lastPts = 0; - - cLog::Instance() << "cDxr3VideoOutThread::Action Thread started\n"; + + cLog::Instance() << "cDxr3VideoOutThread::Action Thread started\n"; sched_param temp; temp.sched_priority = 1; - if (!pthread_setschedparam(pthread_self(), SCHED_RR, &temp)) - { - cLog::Instance() << "cDxr3VideoOutThread::Action(): Error can't set priority\n"; - } + if (!pthread_setschedparam(pthread_self(), SCHED_RR, &temp)) + { + cLog::Instance() << "cDxr3VideoOutThread::Action(): Error can't set priority\n"; + } - while (!GetStopSignal()) + while (!GetStopSignal()) + { + cFixedLengthFrame* pNext = m_buffer.Get(); + if (pNext) { - cFixedLengthFrame* pNext = m_buffer.Get(); - if (pNext) + pts = pNext->GetPts(); + if (pts == lastPts) + pts = 0; + + if (pts > SCR && abs((int)pts - (int)SCR) < 7500) + { + m_dxr3Device.SetPts(pts); + } + + if (!pts || pts < SCR) + { + if (m_buffer.Available()) { - pts = pNext->GetPts(); - if (pts == lastPts) pts = 0; - - if (pts > SCR && abs((int)pts - (int)SCR) < 7500) - { - m_dxr3Device.SetPts(pts); - } - - if (!pts || pts < SCR) - { - if (m_buffer.Available()) - { - m_dxr3Device.PlayVideoFrame(pNext); - m_buffer.Pop(); - } - } - else - { - if ((pts > SCR) && abs((int)pts - (int)SCR) < 7500) - { - m_dxr3Device.SetPts(pts); - - if (m_buffer.Available() && pNext->GetData() && pNext->GetCount()) - { - m_dxr3Device.PlayVideoFrame(pNext); - m_buffer.Pop(); - } - } - else - { - if (pts < SCR) - { - m_dxr3Device.PlayVideoFrame(pNext); - m_buffer.Pop(); - } - } - } - - - if (m_dxr3Device.IsExternalReleased()) - { - m_bNeedResync = true; - m_buffer.Clear(); - } - - if ((pts > SCR && abs((int)pts - (int)SCR) > 7500 )) - { - usleep(10000); - } - } + m_dxr3Device.PlayVideoFrame(pNext); + m_buffer.Pop(); + } + } + else + { + if ((pts > SCR) && abs((int)pts - (int)SCR) < 7500) + { + m_dxr3Device.SetPts(pts); + + if (m_buffer.Available() && pNext->GetData() && + pNext->GetCount()) + { + m_dxr3Device.PlayVideoFrame(pNext); + m_buffer.Pop(); + } + } + else + { + if (pts < SCR) + { + m_dxr3Device.PlayVideoFrame(pNext); + m_buffer.Pop(); + } + } + } + + + if (m_dxr3Device.IsExternalReleased()) + { + m_bNeedResync = true; + m_buffer.Clear(); + } + + if ((pts > SCR && abs((int)pts - (int)SCR) > 7500 )) + { + usleep(10000); + } + } } } - #undef SCR // Local variables: diff --git a/dxr3outputthread.h b/dxr3outputthread.h index 38630ae..2c533a7 100644 --- a/dxr3outputthread.h +++ b/dxr3outputthread.h @@ -27,16 +27,29 @@ #include "dxr3audiodecoder.h" // ================================== -class cDxr3OutputThread : public cThread +class cDxr3OutputThread : public cThread { public: cDxr3OutputThread(cDxr3Interface& dxr3Device, cDxr3SyncBuffer& buffer); - virtual ~cDxr3OutputThread() {Cancel();}; - - // virtual void Start(void) {cThread::Start()}; + virtual ~cDxr3OutputThread() + { + Cancel(); + }; + /* + virtual void Start(void) + { + cThread::Start(); + }; + */ void SetStopSignal(); - bool NeedResync() { return m_bNeedResync;}; - void ClearResyncRequest() { m_bNeedResync = false;}; + bool NeedResync() + { + return m_bNeedResync; + }; + void ClearResyncRequest() + { + m_bNeedResync = false; + }; protected: virtual void Action() = 0; @@ -52,32 +65,32 @@ private: }; // ================================== -class cDxr3AudioOutThread : public cDxr3OutputThread +class cDxr3AudioOutThread : public cDxr3OutputThread { public: cDxr3AudioOutThread(cDxr3Interface& dxr3Device, cDxr3SyncBuffer& buffer); virtual ~cDxr3AudioOutThread(); - -protected: + +protected: void Action(); private: -// cDxr3AudioOutThread(); // no standard constructor - cDxr3AudioOutThread(cDxr3AudioOutThread&); // no copy constructor + //cDxr3AudioOutThread(); // no standard constructor + cDxr3AudioOutThread(cDxr3AudioOutThread&); // no copy constructor }; // ================================== -class cDxr3VideoOutThread : public cDxr3OutputThread +class cDxr3VideoOutThread : public cDxr3OutputThread { public: cDxr3VideoOutThread(cDxr3Interface& dxr3Device, cDxr3SyncBuffer& buffer); virtual ~cDxr3VideoOutThread(); -protected: +protected: void Action(); private: -// cDxr3VideoOutThread(); // no standard constructor + //cDxr3VideoOutThread(); // no standard constructor cDxr3VideoOutThread(cDxr3VideoOutThread&); // no copy constructor }; diff --git a/dxr3pesframe.c b/dxr3pesframe.c index bcf089e..cb953a4 100644 --- a/dxr3pesframe.c +++ b/dxr3pesframe.c @@ -19,7 +19,6 @@ * */ - #include "dxr3pesframe.h" #include "dxr3log.h" @@ -30,7 +29,8 @@ #include <fcntl.h> // ================================== -bool cDxr3PesFrame::ExtractNextFrame(const uint8_t* pBuf, uint32_t length) throw (ePesFrameError) +bool cDxr3PesFrame::ExtractNextFrame(const uint8_t* pBuf, uint32_t length) + throw (ePesFrameError) { cDxr3SafeArray<uint8_t> pesArray((uint8_t*)pBuf, length); uint32_t pos = 0; @@ -39,147 +39,156 @@ bool cDxr3PesFrame::ExtractNextFrame(const uint8_t* pBuf, uint32_t length) throw InitData(); - try + try + { + if (length > 9) { - if (length > 9) + for (; pos + 9 < length && !IsPesHeader(pesArray.SubArray(pos, 4)); pos++); + m_pPesStart = pBuf + pos; + + if ((pesArray[pos + 6] & 0xC0) == 0x80 + /*|| (pesArray[pos + 6] & 0xC0) == 0x00*/) + { + if (pos + 9 + pesArray[pos + 8] < length) { - for (; pos + 9 < length && !IsPesHeader(pesArray.SubArray(pos, 4)); pos++); - m_pPesStart = pBuf + pos; - - if ((pesArray[pos + 6] & 0xC0) == 0x80 /*|| (pesArray[pos + 6] & 0xC0) == 0x00*/) - { - if (pos + 9 + pesArray[pos + 8] < length) - { - m_pEsStart = pBuf + pos + 9 + pesArray[pos + 8]; - if ((((int)pesArray[pos + 4]) * (int)256 + (int)pesArray[pos + 5]) > 0) - { - m_esLength = ((int)pesArray[pos + 4]) * (int)256 + (int)pesArray[pos + 5] + (int)6 - (9 + (int)pesArray[pos + 8]); - if (pos + 9 + pesArray[pos + 8] + m_esLength <= length) - { - m_bValid = true; - m_pNextStart = m_pEsStart + m_esLength; - m_remainingLength = pBuf + length - (m_pEsStart + m_esLength); - if (pesArray[pos + 6] >> 6 == 2 && pesArray[pos + 7] >> 7 != 0) - { - ExtractPts(pesArray.SubArray(pos + 9, 5)); - } - if (m_pesDataType == PES_VIDEO_DATA) - { - int retval = ExtractVideoData(pesArray.SubArray(pos + 9 + pesArray[pos + 8], m_esLength)); - if (m_videoFrameType != UNKNOWN_FRAME && retval) m_offset = retval + pos + 9 + pesArray[pos + 8]; - } - } - } - } - } - else + m_pEsStart = pBuf + pos + 9 + pesArray[pos + 8]; + if ((((int)pesArray[pos + 4]) * (int)256 + (int)pesArray[pos + 5]) > 0) + { + m_esLength = ((int)pesArray[pos + 4]) * + (int)256 + (int)pesArray[pos + 5] + (int)6 - + (9 + (int)pesArray[pos + 8]); + if (pos + 9 + pesArray[pos + 8] + m_esLength <= length) { - uint32_t fpos = pos + 6; - m_esLength = ((int)pesArray[pos + 4]) * (int)256 + (int)pesArray[pos + 5]; - if (length >= pos + 6 + m_esLength) - { - while (pesArray[fpos] == 0xff) ++fpos; // skip stuffing bytes - if ((pesArray[fpos] & 0xC0) == 0x40) fpos += 2; // skip std buffer scale and size - if ((pesArray[fpos] & 0xF0) == 0x20) - { - // pts only - ExtractPts(pesArray.SubArray(fpos, 5)); - fpos += 5; - } - else if ((pesArray[fpos] & 0xF0) == 0x30) - { - // pts and dts - ExtractPts(pesArray.SubArray(fpos, 5)); - fpos += 10; - } - else - { - ++fpos; - } + m_bValid = true; + m_pNextStart = m_pEsStart + m_esLength; + m_remainingLength = pBuf + length - (m_pEsStart + m_esLength); + if (pesArray[pos + 6] >> 6 == 2 && + pesArray[pos + 7] >> 7 != 0) + { + ExtractPts(pesArray.SubArray(pos + 9, 5)); + } + if (m_pesDataType == PES_VIDEO_DATA) + { + int retval = ExtractVideoData(pesArray.SubArray(pos + 9 + pesArray[pos + 8], m_esLength)); + if (m_videoFrameType != UNKNOWN_FRAME && retval) + m_offset = retval + pos + 9 + pesArray[pos + 8]; + } + } + } + } + } + else + { + uint32_t fpos = pos + 6; + m_esLength = ((int)pesArray[pos + 4]) * (int)256 + (int)pesArray[pos + 5]; + if (length >= pos + 6 + m_esLength) + { + while (pesArray[fpos] == 0xff) + ++fpos; // skip stuffing bytes + if ((pesArray[fpos] & 0xC0) == 0x40) + fpos += 2; // skip std buffer scale and size + if ((pesArray[fpos] & 0xF0) == 0x20) + { + // pts only + ExtractPts(pesArray.SubArray(fpos, 5)); + fpos += 5; + } + else if ((pesArray[fpos] & 0xF0) == 0x30) + { + // pts and dts + ExtractPts(pesArray.SubArray(fpos, 5)); + fpos += 10; + } + else + { + ++fpos; + } - if (m_esLength) m_esLength = m_esLength - (fpos - pos - 6); - m_pEsStart = pBuf + fpos; - m_pNextStart = m_pEsStart + m_esLength; - m_remainingLength = pBuf + length - (m_pEsStart + m_esLength); - m_bValid = true; - if (m_pesDataType == PES_VIDEO_DATA) - { - int retval = ExtractVideoData(pesArray.SubArray(fpos, m_esLength)); - if (m_videoFrameType != UNKNOWN_FRAME && retval) m_offset = 0; - } - } - } - } - } - catch (cDxr3SafeArray<uint8_t>::eSafeArrayException ex) - { - m_bValid = false; - cLog::Instance() << "*** PES_GENERAL_ERROR ****\n"; - throw(PES_GENERAL_ERROR); + if (m_esLength) m_esLength = m_esLength - (fpos - pos - 6); + m_pEsStart = pBuf + fpos; + m_pNextStart = m_pEsStart + m_esLength; + m_remainingLength = pBuf + length - (m_pEsStart + m_esLength); + m_bValid = true; + if (m_pesDataType == PES_VIDEO_DATA) + { + int retval = ExtractVideoData(pesArray.SubArray(fpos, m_esLength)); + if (m_videoFrameType != UNKNOWN_FRAME && retval) + m_offset = 0; + } + } + } + } + } + catch (cDxr3SafeArray<uint8_t>::eSafeArrayException ex) + { + m_bValid = false; + cLog::Instance() << "*** PES_GENERAL_ERROR ****\n"; + throw(PES_GENERAL_ERROR); } return m_bValid; - } // ================================== -int cDxr3PesFrame::ExtractVideoData(cDxr3SafeArray<uint8_t> esFrame) throw (cDxr3SafeArray<uint8_t>::eSafeArrayException) { +int cDxr3PesFrame::ExtractVideoData(cDxr3SafeArray<uint8_t> esFrame) + throw (cDxr3SafeArray<uint8_t>::eSafeArrayException) +{ int retval = 0; - for (uint32_t i = 0; esFrame.GetLength() > (uint32_t) 8 && i < esFrame.GetLength() - 8; i++) + for (uint32_t i = 0; esFrame.GetLength() > (uint32_t) 8 && i < esFrame.GetLength() - 8; i++) + { + if (esFrame[i] == 0 && esFrame[i+1] == 0 && esFrame[i+2] == 1) { - if (esFrame[i] == 0 && esFrame[i+1] == 0 && esFrame[i+2] == 1) - { - // start code - if ((esFrame[i + 3] & 0xFF) == 0x00) - { - // extract frame type - if (m_offset == 0) retval = i - ; - switch ((esFrame[ i + 5] >> 3) & 0x7) - { - case 0x1: - m_videoFrameType = I_FRAME; - break; + // start code + if ((esFrame[i + 3] & 0xFF) == 0x00) + { + // extract frame type + if (m_offset == 0) retval = i; + switch ((esFrame[ i + 5] >> 3) & 0x7) + { + case 0x1: + m_videoFrameType = I_FRAME; + break; - case 0x2: - m_videoFrameType = P_FRAME; - break; + case 0x2: + m_videoFrameType = P_FRAME; + break; - case 0x3: - m_videoFrameType = B_FRAME; - break; + case 0x3: + m_videoFrameType = B_FRAME; + break; - default: - m_videoFrameType = UNKNOWN_FRAME; - break; - } - } - else if ((esFrame[i + 3] & 0xFF) == 0xB3) - { - // aspect ratio - switch ((esFrame[i + 7]) & 0xF0) - { - case 0x20: - m_staticAspectRatio = m_aspectRatio = ASPECTRATIO_4_3; - break; + default: + m_videoFrameType = UNKNOWN_FRAME; + break; + } + } + else if ((esFrame[i + 3] & 0xFF) == 0xB3) + { + // aspect ratio + switch ((esFrame[i + 7]) & 0xF0) + { + case 0x20: + m_staticAspectRatio = m_aspectRatio = ASPECTRATIO_4_3; + break; - case 0x30: - m_staticAspectRatio = m_aspectRatio = ASPECTRATIO_16_9; - break; + case 0x30: + m_staticAspectRatio = m_aspectRatio = ASPECTRATIO_16_9; + break; - default: - break; - } - m_staticHorizontalSize = m_horizontalSize = (esFrame[i + 5] & 0xF0) >> 4 | esFrame[i + 4] << 4; - m_staticVerticalSize = m_verticalSize = ((esFrame[i + 5] & 0x0F) << 8) | (esFrame[i + 6]); - } - } + default: + break; + } + m_staticHorizontalSize = m_horizontalSize = (esFrame[i + 5] & 0xF0) >> 4 | esFrame[i + 4] << 4; + m_staticVerticalSize = m_verticalSize = ((esFrame[i + 5] & 0x0F) << 8) | (esFrame[i + 6]); + } + } } return retval; } // ================================== -void cDxr3PesFrame::ExtractPts(cDxr3SafeArray<uint8_t> ptsData) throw (cDxr3SafeArray<uint8_t>::eSafeArrayException) +void cDxr3PesFrame::ExtractPts(cDxr3SafeArray<uint8_t> ptsData) + throw (cDxr3SafeArray<uint8_t>::eSafeArrayException) { m_pts = ((ptsData[0] >> 1) & 0x07) << 29; m_pts |= ptsData[1] << 21; @@ -189,55 +198,56 @@ void cDxr3PesFrame::ExtractPts(cDxr3SafeArray<uint8_t> ptsData) throw (cDxr3Safe } // ================================== -bool cDxr3PesFrame::IsPesHeader(cDxr3SafeArray<uint8_t> header) throw (cDxr3SafeArray<uint8_t>::eSafeArrayException) +bool cDxr3PesFrame::IsPesHeader(cDxr3SafeArray<uint8_t> header) + throw (cDxr3SafeArray<uint8_t>::eSafeArrayException) { bool ret = false; - if (!header[0] && !header[1] && header[2] == 0x01 ) + if (!header[0] && !header[1] && header[2] == 0x01 ) + { + ret = true; + switch (header[3]) { - ret = true; - switch (header[3]) - { - case 0xC0 ... 0xDF: // audio stream - m_pesDataType = PES_AUDIO_DATA; - break; + case 0xC0 ... 0xDF: // audio stream + m_pesDataType = PES_AUDIO_DATA; + break; - case 0xE0 ... 0xEF: // video stream - m_pesDataType = PES_VIDEO_DATA; - break; + case 0xE0 ... 0xEF: // video stream + m_pesDataType = PES_VIDEO_DATA; + break; - case 0xBD: // private stream 1 - m_pesDataType = PES_PRIVATE_DATA; - break; + case 0xBD: // private stream 1 + m_pesDataType = PES_PRIVATE_DATA; + break; - case 0xBA: - ret = false; - break; + case 0xBA: + ret = false; + break; - case 0xBE: // padding stream - ret = false; - break; + case 0xBE: // padding stream + ret = false; + break; - case 0xBC: // program stream map - case 0xBF: // private stream 2 - case 0xF0: // ECM stream - case 0xF1: // EMM stream - case 0xF2: // DSMCC stream - case 0xF3: // 13522 stream - case 0xF4: // H.22.1 type A - case 0xF5: // H.22.1 type B - case 0xF6: // H.22.1 type C - case 0xF7: // H.22.1 type D - case 0xF8: // H.22.1 type E - case 0xF9: // ancillary stream - case 0xFA ... 0xFE: // reserved data stream - case 0xFF: // program stream directory - break; - default: - ret = false; - break; - } - m_streamId = header[3]; + case 0xBC: // program stream map + case 0xBF: // private stream 2 + case 0xF0: // ECM stream + case 0xF1: // EMM stream + case 0xF2: // DSMCC stream + case 0xF3: // 13522 stream + case 0xF4: // H.22.1 type A + case 0xF5: // H.22.1 type B + case 0xF6: // H.22.1 type C + case 0xF7: // H.22.1 type D + case 0xF8: // H.22.1 type E + case 0xF9: // ancillary stream + case 0xFA ... 0xFE: // reserved data stream + case 0xFF: // program stream directory + break; + default: + ret = false; + break; + } + m_streamId = header[3]; } return ret; diff --git a/dxr3pesframe.h b/dxr3pesframe.h index 99c9b35..d4e6677 100644 --- a/dxr3pesframe.h +++ b/dxr3pesframe.h @@ -30,7 +30,7 @@ const int ASPECTRATIO_4_3 = 0; const int ASPECTRATIO_16_9 = 1; // ================================== -enum eVideoFrameType +enum eVideoFrameType { I_FRAME, P_FRAME, @@ -41,105 +41,194 @@ enum eVideoFrameType // ================================== // XXX: Should we use here std:vector? template <class T> -class cDxr3SafeArray +class cDxr3SafeArray { public: // ================================== - enum eSafeArrayException - { - SAFE_ARRAY_INDEX_OUT_OF_BOUND + enum eSafeArrayException + { + SAFE_ARRAY_INDEX_OUT_OF_BOUND }; - cDxr3SafeArray(T* pBuf, uint32_t length) : m_pBuf(pBuf), m_length(length) {}; - cDxr3SafeArray(const cDxr3SafeArray& from) : m_pBuf(from.m_pBuf), m_length(from.m_length) {}; + cDxr3SafeArray(T* pBuf, uint32_t length) : + m_pBuf(pBuf), m_length(length) {}; + cDxr3SafeArray(const cDxr3SafeArray& from) : + m_pBuf(from.m_pBuf), m_length(from.m_length) {}; virtual ~cDxr3SafeArray() {}; - - T& operator[](uint32_t index) throw (eSafeArrayException) { if (index >= m_length) throw(SAFE_ARRAY_INDEX_OUT_OF_BOUND); return m_pBuf[index];}; - cDxr3SafeArray SubArray(uint32_t offset, uint32_t length) { if (offset + length > m_length) throw(SAFE_ARRAY_INDEX_OUT_OF_BOUND); return cDxr3SafeArray(m_pBuf + offset, length);}; - uint32_t GetLength(void) { return m_length; }; + T& operator[](uint32_t index) throw (eSafeArrayException) + { + if (index >= m_length) + throw(SAFE_ARRAY_INDEX_OUT_OF_BOUND); + return m_pBuf[index]; + }; + cDxr3SafeArray SubArray(uint32_t offset, uint32_t length) + { + if (offset + length > m_length) + throw(SAFE_ARRAY_INDEX_OUT_OF_BOUND); + return cDxr3SafeArray(m_pBuf + offset, length); + }; + + uint32_t GetLength(void) + { + return m_length; + }; + protected: T* m_pBuf; uint32_t m_length; private: - cDxr3SafeArray(); // no standard constructor + cDxr3SafeArray(); // no standard constructor }; // ================================== // pes - packetized elementary stream -class cDxr3PesFrame +class cDxr3PesFrame { public: - // ================================== - enum ePesDataType - { - PES_AUDIO_DATA, - PES_VIDEO_DATA, - PES_PRIVATE_DATA, - PES_UNKNOWN_DATA - }; - - // ================================== - enum ePesFrameError - { - PES_GENERAL_ERROR - }; - -public: - cDxr3PesFrame() : m_pesDataType(PES_UNKNOWN_DATA), m_bValid(false), m_pPesStart(0), m_pEsStart(0) - , m_esLength(0), m_pts(0), m_videoFrameType(UNKNOWN_FRAME), m_aspectRatio(m_staticAspectRatio) - , m_horizontalSize(m_staticHorizontalSize), m_verticalSize(m_staticVerticalSize), m_streamId(0), m_pNextStart(0), m_remainingLength(0) - , m_offset(0) {}; - - virtual ~cDxr3PesFrame() {} - - bool ExtractNextFrame(const uint8_t* pBuf, uint32_t length) throw (ePesFrameError); - - ePesDataType GetPesDataType(void) const { assert(m_bValid); return m_pesDataType; }; - const uint8_t* GetPesStart(void) const { assert(m_bValid); return m_pPesStart; }; - const uint8_t* GetEsStart(void) const { assert(m_bValid); return m_pEsStart; }; - uint32_t GetEsLength(void) const { assert(m_bValid); return m_esLength; }; - - const uint8_t* GetNextStart(void) const { return m_pNextStart;}; - uint32_t GetRemainingLength(void) const { return m_remainingLength;}; - - uint32_t GetPts(void) const { assert(m_bValid); return m_pts; }; - - eVideoFrameType GetFrameType(void) const { assert(m_bValid); assert(m_pesDataType == PES_VIDEO_DATA); return m_videoFrameType;}; - uint32_t GetAspectRatio(void) const { assert(m_bValid); assert(m_pesDataType == PES_VIDEO_DATA); return m_aspectRatio;}; - uint32_t GetHorizontalSize(void) const { assert(m_bValid); assert(m_pesDataType == PES_VIDEO_DATA); return m_horizontalSize;}; - uint32_t GetVerticalSize(void) const { assert(m_bValid); assert(m_pesDataType == PES_VIDEO_DATA); return m_verticalSize;}; - uint8_t GetStreamId(void) const { assert(m_bValid); assert(m_pesDataType == PES_VIDEO_DATA); return m_streamId;}; - int GetOffset(void) const { assert(m_bValid); return m_offset;}; - - bool IsValid(void) { return m_bValid; }; - + // ================================== + enum ePesDataType + { + PES_AUDIO_DATA, + PES_VIDEO_DATA, + PES_PRIVATE_DATA, + PES_UNKNOWN_DATA + }; + + // ================================== + enum ePesFrameError + { + PES_GENERAL_ERROR + }; + +public: + cDxr3PesFrame() : + m_pesDataType(PES_UNKNOWN_DATA), + m_bValid(false), + m_pPesStart(0), + m_pEsStart(0), + m_esLength(0), + m_pts(0), + m_videoFrameType(UNKNOWN_FRAME), + m_aspectRatio(m_staticAspectRatio), + m_horizontalSize(m_staticHorizontalSize), + m_verticalSize(m_staticVerticalSize), + m_streamId(0), + m_pNextStart(0), + m_remainingLength(0), + m_offset(0) {}; + + virtual ~cDxr3PesFrame() {} + + bool ExtractNextFrame(const uint8_t* pBuf, uint32_t length) + throw (ePesFrameError); + + ePesDataType GetPesDataType(void) const + { + assert(m_bValid); + return m_pesDataType; + }; + const uint8_t* GetPesStart(void) const + { + assert(m_bValid); + return m_pPesStart; + }; + const uint8_t* GetEsStart(void) const + { + assert(m_bValid); + return m_pEsStart; + }; + uint32_t GetEsLength(void) const + { + assert(m_bValid); + return m_esLength; + }; + + const uint8_t* GetNextStart(void) const + { + return m_pNextStart; + }; + uint32_t GetRemainingLength(void) const + { + return m_remainingLength; + }; + + uint32_t GetPts(void) const + { + assert(m_bValid); + return m_pts; + }; + + eVideoFrameType GetFrameType(void) const + { + assert(m_bValid); + assert(m_pesDataType == PES_VIDEO_DATA); + return m_videoFrameType; + }; + uint32_t GetAspectRatio(void) const + { + assert(m_bValid); + assert(m_pesDataType == PES_VIDEO_DATA); + return m_aspectRatio; + }; + uint32_t GetHorizontalSize(void) const + { + assert(m_bValid); + assert(m_pesDataType == PES_VIDEO_DATA); + return m_horizontalSize; + }; + uint32_t GetVerticalSize(void) const + { + assert(m_bValid); + assert(m_pesDataType == PES_VIDEO_DATA); + return m_verticalSize; + }; + uint8_t GetStreamId(void) const + { + assert(m_bValid); + assert(m_pesDataType == PES_VIDEO_DATA); + return m_streamId; + }; + int GetOffset(void) const + { + assert(m_bValid); + return m_offset; + }; + + bool IsValid(void) + { + return m_bValid; + }; + protected: - bool IsPesHeader(cDxr3SafeArray<uint8_t> header) throw (cDxr3SafeArray<uint8_t>::eSafeArrayException); - void ExtractPts(cDxr3SafeArray<uint8_t> ptsData) throw (cDxr3SafeArray<uint8_t>::eSafeArrayException); - int ExtractVideoData(cDxr3SafeArray<uint8_t> esFrame) throw (cDxr3SafeArray<uint8_t>::eSafeArrayException); - - void InitData(void) - { - m_pesDataType = PES_UNKNOWN_DATA; - m_bValid = false; - m_pPesStart = 0; - m_pEsStart = 0; - m_esLength = 0; - m_pts = 0; - m_videoFrameType = UNKNOWN_FRAME; - m_aspectRatio = m_staticAspectRatio; - m_horizontalSize = m_staticHorizontalSize; - m_verticalSize = m_staticVerticalSize; - m_streamId = 0; - m_pNextStart = 0; - m_remainingLength = 0; - m_offset = 0; - } - + bool IsPesHeader(cDxr3SafeArray<uint8_t> header) + throw (cDxr3SafeArray<uint8_t>::eSafeArrayException); + void ExtractPts(cDxr3SafeArray<uint8_t> ptsData) + throw (cDxr3SafeArray<uint8_t>::eSafeArrayException); + int ExtractVideoData(cDxr3SafeArray<uint8_t> esFrame) + throw (cDxr3SafeArray<uint8_t>::eSafeArrayException); + + void InitData(void) + { + m_pesDataType = PES_UNKNOWN_DATA; + m_bValid = false; + m_pPesStart = 0; + m_pEsStart = 0; + m_esLength = 0; + m_pts = 0; + m_videoFrameType = UNKNOWN_FRAME; + m_aspectRatio = m_staticAspectRatio; + m_horizontalSize = m_staticHorizontalSize; + m_verticalSize = m_staticVerticalSize; + m_streamId = 0; + m_pNextStart = 0; + m_remainingLength = 0; + m_offset = 0; + } + ePesDataType m_pesDataType; bool m_bValid; const uint8_t* m_pPesStart; @@ -169,7 +258,6 @@ private: }; - #endif /*_DXR3PESFRAME_H_*/ // Local variables: diff --git a/dxr3singleton.h b/dxr3singleton.h index 8be1216..3639c93 100644 --- a/dxr3singleton.h +++ b/dxr3singleton.h @@ -21,32 +21,32 @@ #ifndef _DXR3_SINGLETON_H_ #define _DXR3_SINGLETON_H_ - + // ================================== -//! A singleton template. +//! A singleton template. /*! - Is a nice solution to use only - one instance of a class. + Is a nice solution to use only + one instance of a class. */ template<typename T> class Singleton { - protected: - Singleton() {} - virtual ~Singleton() {} +protected: + Singleton() {} + virtual ~Singleton() {} - public: - static T& Instance() - { - static T m_Instance; - return m_Instance; - } +public: + static T& Instance() + { + static T m_Instance; + return m_Instance; + } - static T* InstanceP() - { - static T* m_InstanceP = new T; - return m_InstanceP; - } + static T* InstanceP() + { + static T* m_InstanceP = new T; + return m_InstanceP; + } }; #endif /*_DXR3_SINGLETON_H_*/ diff --git a/dxr3spudecoder.c b/dxr3spudecoder.c index 239c97f..8b09524 100644 --- a/dxr3spudecoder.c +++ b/dxr3spudecoder.c @@ -22,11 +22,6 @@ * */ -/* -ToDo: - - Line 175 -*/ - #include <assert.h> #include <string.h> #include <inttypes.h> @@ -48,7 +43,7 @@ ToDo: #define CMD_SPU_CHG_COLCON 0x07 #define CMD_SPU_EOF 0xff -#define spuU32(i) ((spu[i] << 8) + spu[i+1]) +#define spuU32(i) ((spu[i] << 8) + spu[i+1]) /* @@ -60,36 +55,36 @@ ToDo: * Inputs: * - a SPU rle encoded image on creation, which will be decoded into * the full screen indexed bitmap - * + * * Output: * - a minimal sized cDxr3SpuBitmap a given palette, the indexed bitmap * will be scanned to get the smallest possible resulting bitmap considering * transparencies */ - // ================================== void cDxr3SpuPalette::setPalette(const uint32_t * pal) { for (int i = 0; i < 16; i++) - palette[i] = Tools::YUV2Rgb(pal[i]); + palette[i] = Tools::YUV2Rgb(pal[i]); } // ================================== #define setMin(a, b) if (a > b) a = b #define setMax(a, b) if (a < b) a = b -#define spuXres 720 -#define spuYres 576 +#define spuXres 720 +#define spuYres 576 #define revRect(r1, r2) { r1.x1 = r2.x2; r1.y1 = r2.y2; r1.x2 = r2.x1; r1.y2 = r2.y1; } // ================================== -cDxr3SpuBitmap::cDxr3SpuBitmap(sDxr3SpuRect size, uint8_t * fodd, uint8_t * eodd, uint8_t * feven, uint8_t * eeven) +cDxr3SpuBitmap::cDxr3SpuBitmap(sDxr3SpuRect size, uint8_t * fodd, + uint8_t * eodd, uint8_t * feven, + uint8_t * eeven) { - if (size.x1 < 0 || size.y1 < 0 || size.x2 >= spuXres - || size.y2 >= spuYres) - throw; + if (size.x1 < 0 || size.y1 < 0 || size.x2 >= spuXres || size.y2 >= spuYres) + throw; bmpsize = size; revRect(minsize[0], size); @@ -98,7 +93,7 @@ cDxr3SpuBitmap::cDxr3SpuBitmap(sDxr3SpuRect size, uint8_t * fodd, uint8_t * eodd revRect(minsize[3], size); if (!(bmp = new uint8_t[spuXres * spuYres * sizeof(uint8_t)])) - throw; + throw; memset(bmp, 0, spuXres * spuYres * sizeof(uint8_t)); putFieldData(0, fodd, eodd); @@ -112,75 +107,80 @@ cDxr3SpuBitmap::~cDxr3SpuBitmap() } // ================================== -cBitmap *cDxr3SpuBitmap::getBitmap(const aDxr3SpuPalDescr paldescr, const cDxr3SpuPalette & pal, sDxr3SpuRect & size) const +cBitmap *cDxr3SpuBitmap::getBitmap(const aDxr3SpuPalDescr paldescr, + const cDxr3SpuPalette & pal, + sDxr3SpuRect & size) const { int h = size.height(); int w = size.width(); if (size.y1 + h >= spuYres) - { - h = spuYres - size.y1 - 1; - } + { + h = spuYres - size.y1 - 1; + } if (size.x1 + w >= spuXres) - { - w = spuXres - size.x1 - 1; - } + { + w = spuXres - size.x1 - 1; + } if (w & 0x03) - { - w += 4 - (w & 0x03); - } + { + w += 4 - (w & 0x03); + } cBitmap *ret = new cBitmap(w, h, 2); // set the palette - for (int i = 0; i < 4; i++) - { - uint32_t color = pal.getColor(paldescr[i].index, paldescr[i].trans); - ret->SetColor(i, (tColor) color); + for (int i = 0; i < 4; i++) + { + uint32_t color = pal.getColor(paldescr[i].index, paldescr[i].trans); + ret->SetColor(i, (tColor) color); } // set the content - for (int yp = 0; yp < h; yp++) + for (int yp = 0; yp < h; yp++) + { + for (int xp = 0; xp < w; xp++) { - for (int xp = 0; xp < w; xp++) - { - uint8_t idx = bmp[(size.y1 + yp) * spuXres + size.x1 + xp]; - ret->SetIndex(xp, yp, idx); - } + uint8_t idx = bmp[(size.y1 + yp) * spuXres + size.x1 + xp]; + ret->SetIndex(xp, yp, idx); + } } return ret; } // ================================== // find the minimum non-transparent area -bool cDxr3SpuBitmap::getMinSize(const aDxr3SpuPalDescr paldescr, sDxr3SpuRect & size) const +bool cDxr3SpuBitmap::getMinSize(const aDxr3SpuPalDescr paldescr, + sDxr3SpuRect & size) const { bool ret = false; - for (int i = 0; i < 4; i++) - { - if (paldescr[i].trans != 0) - { - if (!ret) - { - size = minsize[i]; - } - else - { - setMin(size.x1, minsize[i].x1); - setMin(size.y1, minsize[i].y1); - setMax(size.x2, minsize[i].x2); - setMax(size.y2, minsize[i].y2); - } - ret = true; - } - } -/* - if (ret && cDxr3ConfigData::Instance().GetDebug()) + for (int i = 0; i < 4; i++) + { + if (paldescr[i].trans != 0) { - cLog::Instance() << "cDxr3SpuBitmap::getMinSize: (" << size.x1 ", " << size.y1 << ") x (" << size.x2 << ", " << size.y2 << ")\n"; + if (!ret) + { + size = minsize[i]; + } + else + { + setMin(size.x1, minsize[i].x1); + setMin(size.y1, minsize[i].y1); + setMax(size.x2, minsize[i].x2); + setMax(size.y2, minsize[i].y2); + } + ret = true; } -*/ + } + /* + if (ret && cDxr3ConfigData::Instance().GetDebug()) + { + cLog::Instance() << "cDxr3SpuBitmap::getMinSize: (" + << size.x1 ", " << size.y1 << ") x (" + << size.x2 << ", " << size.y2 << ")\n"; + } + */ return ret; } @@ -199,13 +199,13 @@ static uint8_t getBits(uint8_t * &data, uint8_t & bitf) { uint8_t ret = *data; if (bitf) - { - ret >>= 4; - } + { + ret >>= 4; + } else - { - data++; - } + { + data++; + } bitf ^= 1; @@ -219,41 +219,41 @@ void cDxr3SpuBitmap::putFieldData(int field, uint8_t * data, uint8_t * endp) int yp = bmpsize.y1 + field; uint8_t bitf = 1; - while (data < endp) + while (data < endp) + { + uint16_t vlc = getBits(data, bitf); + if (vlc < 0x0004) { - uint16_t vlc = getBits(data, bitf); - if (vlc < 0x0004) - { - vlc = (vlc << 4) | getBits(data, bitf); - if (vlc < 0x0010) - { - vlc = (vlc << 4) | getBits(data, bitf); - if (vlc < 0x0040) - { - vlc = (vlc << 4) | getBits(data, bitf); - } - } - } - - uint8_t color = vlc & 0x03; - int len = vlc >> 2; - - // if len == 0 -> end sequence - fill to end of line - len = len ? len : bmpsize.x2 - xp + 1; - putPixel(xp, yp, len, color); - xp += len; - - if (xp > bmpsize.x2) + vlc = (vlc << 4) | getBits(data, bitf); + if (vlc < 0x0010) + { + vlc = (vlc << 4) | getBits(data, bitf); + if (vlc < 0x0040) { - // nextLine - if (!bitf) - data++; - bitf = 1; - xp = bmpsize.x1; - yp += 2; - if (yp > bmpsize.y2) - return; - } + vlc = (vlc << 4) | getBits(data, bitf); + } + } + } + + uint8_t color = vlc & 0x03; + int len = vlc >> 2; + + // if len == 0 -> end sequence - fill to end of line + len = len ? len : bmpsize.x2 - xp + 1; + putPixel(xp, yp, len, color); + xp += len; + + if (xp > bmpsize.x2) + { + // nextLine + if (!bitf) + data++; + bitf = 1; + xp = bmpsize.x1; + yp += 2; + if (yp > bmpsize.y2) + return; + } } } @@ -286,10 +286,11 @@ void cDxr3SpuDecoder::processSPU(uint32_t pts, uint8_t * buf) { setTime(pts); - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "cDxr3SpuDecoder::processSPU: SPU pushData: pts: " << pts << "\n"; - } + if (cDxr3ConfigData::Instance().GetDebug()) + { + cLog::Instance() << "cDxr3SpuDecoder::processSPU: SPU pushData: pts: " + << pts << "\n"; + } delete spubmp; spubmp = NULL; @@ -329,31 +330,32 @@ void cDxr3SpuDecoder::setPalette(uint32_t * pal) void cDxr3SpuDecoder::setHighlight(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t palette) { aDxr3SpuPalDescr pld; - for (int i = 0; i < 4; i++) - { - pld[i].index = 0xf & (palette >> (16 + 4 * i)); - pld[i].trans = 0xf & (palette >> (4 * i)); + for (int i = 0; i < 4; i++) + { + pld[i].index = 0xf & (palette >> (16 + 4 * i)); + pld[i].trans = 0xf & (palette >> (4 * i)); } bool ne = hlpsize.x1 != sx || hlpsize.y1 != sy || - hlpsize.x2 != ex || hlpsize.y2 != ey || - pld[0] != hlpDescr[0] || pld[1] != hlpDescr[1] || - pld[2] != hlpDescr[2] || pld[3] != hlpDescr[3]; + hlpsize.x2 != ex || hlpsize.y2 != ey || + pld[0] != hlpDescr[0] || pld[1] != hlpDescr[1] || + pld[2] != hlpDescr[2] || pld[3] != hlpDescr[3]; - if (ne) + if (ne) + { + if (cDxr3ConfigData::Instance().GetDebug()) { - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "cDxr3SpuDecoder::setHighlight: " << sx << ", " << sy << ", " << ex << ", " << ey << "\n"; - } + cLog::Instance() << "cDxr3SpuDecoder::setHighlight: " << sx + << ", " << sy << ", " << ex << ", " << ey << "\n"; + } - hlpsize.x1 = sx; - hlpsize.y1 = sy; - hlpsize.x2 = ex; - hlpsize.y2 = ey; - memcpy(hlpDescr, pld, sizeof(aDxr3SpuPalDescr)); - highlight = true; - clean = false; + hlpsize.x1 = sx; + hlpsize.y1 = sy; + hlpsize.x2 = ex; + hlpsize.y2 = ey; + memcpy(hlpDescr, pld, sizeof(aDxr3SpuPalDescr)); + highlight = true; + clean = false; } } @@ -372,22 +374,23 @@ void cDxr3SpuDecoder::clearHighlight() // ================================== int cDxr3SpuDecoder::ScaleYcoord(int value) { - if (scaleMode == eSpuLetterBox) - { - int offset = cDevice::PrimaryDevice()->GetVideoSystem() == vsPAL ? 72 : 60; - return lround((value * 3.0) / 4.0) + offset; + if (scaleMode == eSpuLetterBox) + { + int offset = + cDevice::PrimaryDevice()->GetVideoSystem() == vsPAL ? 72 : 60; + return lround((value * 3.0) / 4.0) + offset; } - return value; + return value; } // ================================== int cDxr3SpuDecoder::ScaleYres(int value) { if (scaleMode == eSpuLetterBox) - { - return lround((value * 3.0) / 4.0); - } - return value; + { + return lround((value * 3.0) / 4.0); + } + return value; } // ================================== @@ -395,11 +398,11 @@ void cDxr3SpuDecoder::DrawBmp(sDxr3SpuRect & size, cBitmap * bmp) { int x2 = size.x2; while ((x2 - size.x1 + 1) & 0x03) - x2++; + x2++; tArea Area = { size.x1, size.y1, x2, size.y2, 2 }; osd->SetAreas(&Area, 1); if (x2 > size.x2) - osd->DrawRectangle(size.x2 + 1, size.y1, x2, size.y2, clrTransparent); + osd->DrawRectangle(size.x2 + 1, size.y1, x2, size.y2, clrTransparent); osd->DrawBitmap(size.x1, size.y1, *bmp); delete bmp; } @@ -411,9 +414,9 @@ void cDxr3SpuDecoder::Draw() Hide(); if (!spubmp) - { - return; - } + { + return; + } cBitmap *fg = NULL; cBitmap *bg = NULL; @@ -426,46 +429,46 @@ void cDxr3SpuDecoder::Draw() hlsize.y2 = ScaleYcoord(hlpsize.y2); if (highlight) - { - fg = spubmp->getBitmap(hlpDescr, palette, hlsize); - } + { + fg = spubmp->getBitmap(hlpDescr, palette, hlsize); + } - if (spubmp->getMinSize(palDescr, bgsize)) + if (spubmp->getMinSize(palDescr, bgsize)) + { + bg = spubmp->getBitmap(palDescr, palette, bgsize); + if (scaleMode == eSpuLetterBox) { - bg = spubmp->getBitmap(palDescr, palette, bgsize); - if (scaleMode == eSpuLetterBox) - { - // the coordinates have to be modified for letterbox - int y1 = ScaleYres(bgsize.y1) + bgsize.height(); - bgsize.y2 = y1 + bgsize.height(); - bgsize.y1 = y1; - } + // the coordinates have to be modified for letterbox + int y1 = ScaleYres(bgsize.y1) + bgsize.height(); + bgsize.y2 = y1 + bgsize.height(); + bgsize.y1 = y1; + } } - if (bg || fg) - { - if (osd == NULL) - if ((osd = cOsdProvider::NewOsd(0, 0)) == NULL) - { - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "cDxr3SpuDecoder::Draw: New OSD faild!\n"; - } - dsyslog("NewOsd failed\n"); - return; - } - - if (fg) + if (bg || fg) + { + if (osd == NULL) + if ((osd = cOsdProvider::NewOsd(0, 0)) == NULL) + { + if (cDxr3ConfigData::Instance().GetDebug()) { - DrawBmp(hlsize, fg); + cLog::Instance() << "cDxr3SpuDecoder::Draw: New OSD faild!\n"; } + dsyslog("NewOsd failed\n"); + return; + } - if (bg) - { - DrawBmp(bgsize, bg); - } + if (fg) + { + DrawBmp(hlsize, fg); + } + + if (bg) + { + DrawBmp(bgsize, bg); + } - osd->Flush(); + osd->Flush(); } clean = true; @@ -500,157 +503,164 @@ void cDxr3SpuDecoder::Empty() int cDxr3SpuDecoder::setTime(uint32_t pts) { if (!spu) - { - return 0; - } + { + return 0; + } if (spu && !clean) + { + Draw(); + } + + while (DCSQ_offset != prev_DCSQ_offset) + { + // Display Control Sequences + int i = DCSQ_offset; + state = spNONE; + + uint32_t exec_time = spupts + spuU32(i) * 1024; + if ((pts != 0) && (exec_time > pts)) { - Draw(); + return 0; } - while (DCSQ_offset != prev_DCSQ_offset) - { - // Display Control Sequences - int i = DCSQ_offset; - state = spNONE; + if (pts != 0) + { + uint16_t feven = 0; + uint16_t fodd = 0; + + i += 2; - uint32_t exec_time = spupts + spuU32(i) * 1024; - if ((pts != 0) && (exec_time > pts)) - { - return 0; - } + prev_DCSQ_offset = DCSQ_offset; + DCSQ_offset = spuU32(i); + i += 2; - if (pts != 0) + while (spu[i] != CMD_SPU_EOF) + { + // Command Sequence + switch (spu[i]) { - uint16_t feven = 0; - uint16_t fodd = 0; - - i += 2; - - prev_DCSQ_offset = DCSQ_offset; - DCSQ_offset = spuU32(i); - i += 2; - - while (spu[i] != CMD_SPU_EOF) - { - // Command Sequence - switch (spu[i]) - { - case CMD_SPU_SHOW: - // show subpicture - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "cDxr3SpuDecoder::setTime: show subpicture\n"; - } - state = spSHOW; - i++; - break; - - case CMD_SPU_HIDE: - // hide subpicture - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "cDxr3SpuDecoder::setTime: hide subpicture\n"; - } - state = spHIDE; - i++; - break; - - case CMD_SPU_SET_PALETTE: - // CLUT - palDescr[0].index = spu[i + 2] & 0xf; - palDescr[1].index = spu[i + 2] >> 4; - palDescr[2].index = spu[i + 1] & 0xf; - palDescr[3].index = spu[i + 1] >> 4; - i += 3; - break; - - case CMD_SPU_SET_ALPHA: - // transparency palette - palDescr[0].trans = spu[i + 2] & 0xf; - palDescr[1].trans = spu[i + 2] >> 4; - palDescr[2].trans = spu[i + 1] & 0xf; - palDescr[3].trans = spu[i + 1] >> 4; - i += 3; - break; - - case CMD_SPU_SET_SIZE: - // image coordinates - size.x1 = (spu[i + 1] << 4) | (spu[i + 2] >> 4); - size.x2 = ((spu[i + 2] & 0x0f) << 8) | spu[i + 3]; - - size.y1 = (spu[i + 4] << 4) | (spu[i + 5] >> 4); - size.y2 = ((spu[i + 5] & 0x0f) << 8) | spu[i + 6]; - - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "cDxr3SpuDecoder::setTime: (" << size.x1 << ", " << size.y1 <<") x (" << size.x2 << ", " << size.y2 <<")\n"; - } - i += 7; - break; - - case CMD_SPU_SET_PXD_OFFSET: - // image 1 / image 2 offsets - fodd = spuU32(i + 1); - feven = spuU32(i + 3); - - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "cDxr3SpuDecoder::setTime: odd = " << fodd << " even = " << feven << "\n"; - } - i += 5; - break; + case CMD_SPU_SHOW: + // show subpicture + if (cDxr3ConfigData::Instance().GetDebug()) + { + cLog::Instance() << "cDxr3SpuDecoder::setTime: show subpicture\n"; + } + state = spSHOW; + i++; + break; - case CMD_SPU_CHG_COLCON: + case CMD_SPU_HIDE: + // hide subpicture + if (cDxr3ConfigData::Instance().GetDebug()) { - int size = spuU32(i + 1); - i += 1 + size; + cLog::Instance() << "cDxr3SpuDecoder::setTime: hide subpicture\n"; } + state = spHIDE; + i++; break; - case CMD_SPU_MENU: - if (cDxr3ConfigData::Instance().GetDebug()) - { - cLog::Instance() << "cDxr3SpuDecoder::setTime: spu menu\n"; - } - state = spMENU; - - i++; - break; - - default: - esyslog("invalid sequence in control header (%.2x)\n", spu[i]); - assert(0); - i++; - break; - } - } - if (fodd != 0 && feven != 0) - { - delete spubmp; - spubmp = new cDxr3SpuBitmap(size, spu + fodd, spu + feven, spu + feven, spu + cmdOffs()); - } - } - else if (!clean) - { - state = spSHOW; - } + case CMD_SPU_SET_PALETTE: + // CLUT + palDescr[0].index = spu[i + 2] & 0xf; + palDescr[1].index = spu[i + 2] >> 4; + palDescr[2].index = spu[i + 1] & 0xf; + palDescr[3].index = spu[i + 1] >> 4; + i += 3; + break; - if (state == spSHOW || state == spMENU) - { - Draw(); - } + case CMD_SPU_SET_ALPHA: + // transparency palette + palDescr[0].trans = spu[i + 2] & 0xf; + palDescr[1].trans = spu[i + 2] >> 4; + palDescr[2].trans = spu[i + 1] & 0xf; + palDescr[3].trans = spu[i + 1] >> 4; + i += 3; + break; + + case CMD_SPU_SET_SIZE: + // image coordinates + size.x1 = (spu[i + 1] << 4) | (spu[i + 2] >> 4); + size.x2 = ((spu[i + 2] & 0x0f) << 8) | spu[i + 3]; + + size.y1 = (spu[i + 4] << 4) | (spu[i + 5] >> 4); + size.y2 = ((spu[i + 5] & 0x0f) << 8) | spu[i + 6]; - if (state == spHIDE) + if (cDxr3ConfigData::Instance().GetDebug()) + { + cLog::Instance() << "cDxr3SpuDecoder::setTime: (" + << size.x1 << ", " << size.y1 + << ") x (" << size.x2 << ", " + << size.y2 <<")\n"; + } + i += 7; + break; + + case CMD_SPU_SET_PXD_OFFSET: + // image 1 / image 2 offsets + fodd = spuU32(i + 1); + feven = spuU32(i + 3); + + if (cDxr3ConfigData::Instance().GetDebug()) + { + cLog::Instance() << "cDxr3SpuDecoder::setTime: odd = " + << fodd << " even = " << feven + << "\n"; + } + i += 5; + break; + + case CMD_SPU_CHG_COLCON: { - Hide(); + int size = spuU32(i + 1); + i += 1 + size; } + break; - if (pts == 0) - { - return 0; + case CMD_SPU_MENU: + if (cDxr3ConfigData::Instance().GetDebug()) + { + cLog::Instance() << "cDxr3SpuDecoder::setTime: spu menu\n"; + } + state = spMENU; + + i++; + break; + + default: + esyslog("invalid sequence in control header (%.2x)\n", + spu[i]); + assert(0); + i++; + break; } + } + if (fodd != 0 && feven != 0) + { + delete spubmp; + spubmp = new cDxr3SpuBitmap(size, spu + fodd, spu + feven, + spu + feven, spu + cmdOffs()); + } + } + else if (!clean) + { + state = spSHOW; + } + + if (state == spSHOW || state == spMENU) + { + Draw(); + } + + if (state == spHIDE) + { + Hide(); + } + + if (pts == 0) + { + return 0; + } } return 1; diff --git a/dxr3spudecoder.h b/dxr3spudecoder.h index 85eac98..d44040a 100644 --- a/dxr3spudecoder.h +++ b/dxr3spudecoder.h @@ -21,77 +21,81 @@ #ifndef _DXR3SPUDECODER_H_ #define _DXR3SPUDECODER_H_ - + #include "dxr3vdrincludes.h" #include <inttypes.h> // ================================== -typedef struct sDxr3SpuPalDescr +typedef struct sDxr3SpuPalDescr { uint8_t index; uint8_t trans; - bool operator != (const sDxr3SpuPalDescr pd) const { - return index != pd.index && trans != pd.trans; + bool operator != (const sDxr3SpuPalDescr pd) const + { + return index != pd.index && trans != pd.trans; }; } aDxr3SpuPalDescr[4]; // ================================== -struct sDxr3SpuRect +struct sDxr3SpuRect { int x1, y1; int x2, y2; - int width() - { - return x2 - x1 + 1; + int width() + { + return x2 - x1 + 1; }; - int height() - { - return y2 - y1 + 1; + int height() + { + return y2 - y1 + 1; }; - bool operator != (const sDxr3SpuRect r) const - { - return r.x1 != x1 || r.y1 != y1 || r.x2 != x2 || r.y2 != y2; + bool operator != (const sDxr3SpuRect r) const + { + return r.x1 != x1 || r.y1 != y1 || r.x2 != x2 || r.y2 != y2; }; }; // ================================== -class cDxr3SpuPalette +class cDxr3SpuPalette { private: uint32_t palette[16]; - + public: void setPalette(const uint32_t * pal); uint32_t getColor(uint8_t idx, uint8_t trans) const; }; // ================================== -class cDxr3SpuBitmap +class cDxr3SpuBitmap { private: sDxr3SpuRect bmpsize; sDxr3SpuRect minsize[4]; uint8_t *bmp; - + void putPixel(int xp, int yp, int len, uint8_t colorid); void putFieldData(int field, uint8_t * data, uint8_t * endp); - + public: - cDxr3SpuBitmap(sDxr3SpuRect size, uint8_t * fodd, uint8_t * eodd, uint8_t * feven, uint8_t * eeven); + cDxr3SpuBitmap(sDxr3SpuRect size, uint8_t * fodd, uint8_t * eodd, + uint8_t * feven, uint8_t * eeven); ~cDxr3SpuBitmap(); - - bool getMinSize(const aDxr3SpuPalDescr paldescr, sDxr3SpuRect & size) const; - cBitmap *getBitmap(const aDxr3SpuPalDescr paldescr, const cDxr3SpuPalette & pal, sDxr3SpuRect & size) const; + + bool getMinSize(const aDxr3SpuPalDescr paldescr, + sDxr3SpuRect & size) const; + cBitmap *getBitmap(const aDxr3SpuPalDescr paldescr, + const cDxr3SpuPalette & pal, sDxr3SpuRect & size) const; }; // ================================== -class cDxr3SpuDecoder : public cSpuDecoder +class cDxr3SpuDecoder : public cSpuDecoder { -public: +public: cDxr3SpuDecoder(); ~cDxr3SpuDecoder(); @@ -100,7 +104,8 @@ public: cSpuDecoder::eScaleMode getScaleMode(void); void setScaleMode(cSpuDecoder::eScaleMode ScaleMode); void setPalette(uint32_t * pal); - void setHighlight(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t palette); + void setHighlight(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, + uint32_t palette); void clearHighlight(); void Empty(); #if VDRVERSNUM >= 10318 @@ -109,11 +114,14 @@ public: void processSPU(uint32_t pts, uint8_t * buf); #endif - #if VDRVERSNUM >= 10311 +#if VDRVERSNUM >= 10311 void Hide(); void Draw(); - bool IsVisible() { return osd != NULL; } - #endif + bool IsVisible() + { + return osd != NULL; + } +#endif private: cOsd * osd; @@ -123,31 +131,43 @@ private: uint32_t spupts; bool clean; bool ready; - - enum spFlag { spNONE, spHIDE, spSHOW, spMENU }; + + enum spFlag + { + spNONE, + spHIDE, + spSHOW, + spMENU + }; spFlag state; - + cSpuDecoder::eScaleMode scaleMode; - + // highligh area bool highlight; sDxr3SpuRect hlpsize; aDxr3SpuPalDescr hlpDescr; - + // palette cDxr3SpuPalette palette; - + // spu info's sDxr3SpuRect size; aDxr3SpuPalDescr palDescr; - + uint16_t DCSQ_offset; uint16_t prev_DCSQ_offset; - + cDxr3SpuBitmap *spubmp; - int cmdOffs() { return ((spu[2] << 8) | spu[3]); } - int spuSize() { return ((spu[0] << 8) | spu[1]); } + int cmdOffs() + { + return ((spu[2] << 8) | spu[3]); + } + int spuSize() + { + return ((spu[0] << 8) | spu[1]); + } int ScaleYcoord(int value); int ScaleYres(int value); diff --git a/dxr3syncbuffer.c b/dxr3syncbuffer.c index d21f40c..d7fe170 100644 --- a/dxr3syncbuffer.c +++ b/dxr3syncbuffer.c @@ -20,8 +20,9 @@ */ /* - ToDo: - - cDxr3SyncBuffer::Push: XXX This is only a workaround until a sufficient control algorithm is implemented + ToDo: + - cDxr3SyncBuffer::Push: XXX This is only a workaround until a + sufficient control algorithm is implemented */ #include <unistd.h> @@ -33,8 +34,9 @@ const int DXR3_MAX_AUDIO_FRAME_LENGTH = 4096; // ================================== //! constructor -cFixedLengthFrame::cFixedLengthFrame() : -m_count(0), m_length(0), m_pts(0), m_type(ftUnknown) { +cFixedLengthFrame::cFixedLengthFrame() : + m_count(0), m_length(0), m_pts(0), m_type(ftUnknown) +{ m_audioChannelCount = UNKNOWN_CHANNEL_COUNT; m_audioDataRate = UNKNOWN_DATA_RATE; @@ -44,62 +46,63 @@ m_count(0), m_length(0), m_pts(0), m_type(ftUnknown) { // ================================== cFixedLengthFrame::~cFixedLengthFrame() { - if (m_pData) - { - delete[] m_pData; - } + if (m_pData) + { + delete[] m_pData; + } } // ================================== // ! setup our frame void cFixedLengthFrame::Init(uint32_t lenght) { - m_length = lenght; - m_pData = new uint8_t[lenght]; - - // allocation ok? - if (!m_pData) - { - cLog::Instance() << "Failed to allocate memory in cFixedLengthFrame (m_pData) - will stop now"; - exit(1); - } + m_length = lenght; + m_pData = new uint8_t[lenght]; + + // allocation ok? + if (!m_pData) + { + cLog::Instance() << "Failed to allocate memory in cFixedLengthFrame (m_pData) - will stop now"; + exit(1); + } } // ================================== -void cFixedLengthFrame::CopyFrame(const uint8_t* pStart, int length, uint32_t pts, eFrameType type) +void cFixedLengthFrame::CopyFrame(const uint8_t* pStart, int length, + uint32_t pts, eFrameType type) { - if (length > m_length) - { - delete[] m_pData; - m_pData = new uint8_t[length]; - m_length = length; + if (length > m_length) + { + delete[] m_pData; + m_pData = new uint8_t[length]; + m_length = length; } m_type = type; m_count = length; m_pts = pts; - dxr3_memcpy((void*) m_pData,(void*) pStart, length); + dxr3_memcpy((void*) m_pData, (void*) pStart, length); } // ================================== -uint8_t* cFixedLengthFrame::GetData(void) +uint8_t* cFixedLengthFrame::GetData(void) { return m_pData; } // ================================== -int cFixedLengthFrame::GetCount(void) +int cFixedLengthFrame::GetCount(void) { return m_count; } // ================================== -uint32_t cFixedLengthFrame::GetPts(void) +uint32_t cFixedLengthFrame::GetPts(void) { - return m_pts; + return m_pts; } // ================================== -void cFixedLengthFrame::SetPts(uint32_t pts) +void cFixedLengthFrame::SetPts(uint32_t pts) { m_pts = pts; } @@ -111,24 +114,26 @@ uint32_t cFixedLengthFrame::m_staticAudioDataRate = 0; // ================================== //! constructor -cDxr3SyncBuffer::cDxr3SyncBuffer(int frameCount, int frameLength, cDxr3Interface& dxr3Device) : cRingBuffer(frameCount, true), m_dxr3Device(dxr3Device) +cDxr3SyncBuffer::cDxr3SyncBuffer(int frameCount, int frameLength, + cDxr3Interface& dxr3Device) : + cRingBuffer(frameCount, true), m_dxr3Device(dxr3Device) { m_pBuffer = new cFixedLengthFrame[frameCount]; - // got we a valid m_pBuffer? - if (!m_pBuffer) - { - cLog::Instance() << "Failed to allocate memory in cDxr3SyncBuffer (m_pBuffer) - will stop now"; - exit(1); - } + // got we a valid m_pBuffer? + if (!m_pBuffer) + { + cLog::Instance() << "Failed to allocate memory in cDxr3SyncBuffer (m_pBuffer) - will stop now"; + exit(1); + } - // init our new m_pBuffer; - for (int i = 0; i < frameCount; i++) - { - m_pBuffer[i].Init(frameLength); - } + // init our new m_pBuffer; + for (int i = 0; i < frameCount; i++) + { + m_pBuffer[i].Init(frameLength); + } - // set some default values + // set some default values m_count = 0; m_nextFree = 0; m_next = 0; @@ -146,24 +151,24 @@ cDxr3SyncBuffer::cDxr3SyncBuffer(int frameCount, int frameLength, cDxr3Interface } // ================================== -cDxr3SyncBuffer::~cDxr3SyncBuffer() +cDxr3SyncBuffer::~cDxr3SyncBuffer() { - if (m_pBuffer) - { - delete[] m_pBuffer; - } + if (m_pBuffer) + { + delete[] m_pBuffer; + } } // ================================== -int cDxr3SyncBuffer::Available(void) +int cDxr3SyncBuffer::Available(void) { int ret = 0; #if VDRVERSNUM < 10313 - Lock(); + Lock(); #endif ret = m_count; #if VDRVERSNUM < 10313 - Unlock(); + Unlock(); #endif return ret; } @@ -173,182 +178,184 @@ const int BUFFER_LIMIT = 5; const int BUFFER_LIMIT_2 = 10; // ================================== -bool cDxr3SyncBuffer::Poll(int TimeoutMs) +bool cDxr3SyncBuffer::Poll(int TimeoutMs) { bool retVal = true; uint32_t currTime = m_dxr3Device.GetSysClock(); m_bPollSync = true; - if (m_demuxMode == DXR3_DEMUX_REPLAY_MODE) + if (m_demuxMode == DXR3_DEMUX_REPLAY_MODE) + { + if (Available() >= Size() - (Size()*BUFFER_LIMIT/100)) { - if (Available() >= Size() - (Size()*BUFFER_LIMIT/100)) - { - m_bPollSync = true; - while ((Available() >= Size() - (Size()*BUFFER_LIMIT_2)/100) && ((m_dxr3Device.GetSysClock() - currTime) < ((uint32_t)TimeoutMs * (uint32_t)45))) - { - m_bPutBlock = true; - EnableGet(); - m_bWaitPts = false; - WaitForPut(); - } - if (Available() >= Size() - (Size()*BUFFER_LIMIT_2)/100) - { - retVal = false; - } - } + m_bPollSync = true; + while ((Available() >= Size() - (Size()*BUFFER_LIMIT_2)/100) && + ((m_dxr3Device.GetSysClock() - currTime) < + ((uint32_t)TimeoutMs * (uint32_t)45))) + { + m_bPutBlock = true; + EnableGet(); + m_bWaitPts = false; + WaitForPut(); + } + if (Available() >= Size() - (Size()*BUFFER_LIMIT_2)/100) + { + retVal = false; + } + } } return retVal; } // ================================== -cFixedLengthFrame* cDxr3SyncBuffer::Push(const uint8_t* pStart, int length, uint32_t pts, eFrameType type) throw (eSyncBufferException) +cFixedLengthFrame* cDxr3SyncBuffer::Push(const uint8_t* pStart, int length, uint32_t pts, eFrameType type) throw (eSyncBufferException) { int lastIndex = 0; - switch (m_demuxMode) + switch (m_demuxMode) + { + case DXR3_DEMUX_TRICK_MODE: + break; + + case DXR3_DEMUX_TV_MODE: + case DXR3_DEMUX_REPLAY_MODE: + default: + + while ((Available() >= Size() - (Size()*10)/100)) { - case DXR3_DEMUX_TRICK_MODE: - break; - - case DXR3_DEMUX_TV_MODE: - case DXR3_DEMUX_REPLAY_MODE: - default: - - while ((Available() >= Size() - (Size()*10)/100)) - { - m_bPutBlock = true; - EnableGet(); - m_bWaitPts = false; - WaitForPut(); - } - - #if VDRVERSNUM < 10313 - Lock(); - #endif - if (pts == m_lastPts) - { - pts = 0; - } - else - { - m_lastPts = pts; - } - lastIndex = m_nextFree; - m_pBuffer[m_nextFree].CopyFrame(pStart, length, pts, type); - m_pBuffer[m_nextFree].SetChannelCount(UNKNOWN_CHANNEL_COUNT); - m_pBuffer[m_nextFree].SetDataRate(UNKNOWN_DATA_RATE); - m_pBuffer[m_nextFree].SetAspectRatio(UNKNOWN_ASPECT_RATIO); - m_nextFree++; - m_count++; - m_nextFree %= Size(); - - if (m_nextFree == m_next) - { - cLog::Instance() << "Buffer overrun\n"; -// cLog::Instance() << "cDxr3SyncBuffer::Push m_demuxMode: " << (int)m_demuxMode << endl; -// cLog::Instance() << "cDxr3SyncBuffer::Push Available(): " << Available() << endl; -// cLog::Instance() << "cDxr3SyncBuffer::Push Size(): " << Size() << endl; - - Clear(); // XXX This is only a workaround until a sufficient control algorithm is implemented - throw(SYNC_BUFFER_OVERRUN); - } - if (!m_bWaitPts) - { - if (m_bStartReceiver) - { - EnableGet(); - } - } - else - { - if (m_waitPts < m_dxr3Device.GetSysClock() || - m_waitPts - m_dxr3Device.GetSysClock() < m_waitDelta) - { - EnableGet(); - m_bWaitPts = false; - } - } - #if VDRVERSNUM < 10313 - Unlock(); - #endif - break; + m_bPutBlock = true; + EnableGet(); + m_bWaitPts = false; + WaitForPut(); + } + +#if VDRVERSNUM < 10313 + Lock(); +#endif + if (pts == m_lastPts) + { + pts = 0; + } + else + { + m_lastPts = pts; + } + lastIndex = m_nextFree; + m_pBuffer[m_nextFree].CopyFrame(pStart, length, pts, type); + m_pBuffer[m_nextFree].SetChannelCount(UNKNOWN_CHANNEL_COUNT); + m_pBuffer[m_nextFree].SetDataRate(UNKNOWN_DATA_RATE); + m_pBuffer[m_nextFree].SetAspectRatio(UNKNOWN_ASPECT_RATIO); + m_nextFree++; + m_count++; + m_nextFree %= Size(); + + if (m_nextFree == m_next) + { + cLog::Instance() << "Buffer overrun\n"; + //cLog::Instance() << "cDxr3SyncBuffer::Push m_demuxMode: " << (int)m_demuxMode << endl; + //cLog::Instance() << "cDxr3SyncBuffer::Push Available(): " << Available() << endl; + //cLog::Instance() << "cDxr3SyncBuffer::Push Size(): " << Size() << endl; + + Clear(); // XXX This is only a workaround until a sufficient control algorithm is implemented + throw(SYNC_BUFFER_OVERRUN); + } + if (!m_bWaitPts) + { + if (m_bStartReceiver) + { + EnableGet(); + } + } + else + { + if (m_waitPts < m_dxr3Device.GetSysClock() || + m_waitPts - m_dxr3Device.GetSysClock() < m_waitDelta) + { + EnableGet(); + m_bWaitPts = false; + } + } +#if VDRVERSNUM < 10313 + Unlock(); +#endif + break; } return &m_pBuffer[lastIndex]; } // ================================== -void cDxr3SyncBuffer::Pop(void) +void cDxr3SyncBuffer::Pop(void) { #if VDRVERSNUM < 10313 - Lock(); + Lock(); #endif - if (m_count) + if (m_count) + { + uint32_t nextPts = 0; + uint32_t tmpBuffer = m_next; + for (int i = 0; i < m_count && nextPts == 0; ++i) + { + if (tmpBuffer) tmpBuffer = --tmpBuffer ? tmpBuffer : (Size() - 1); + nextPts = m_pBuffer[tmpBuffer].GetPts(); + } + if (nextPts != 30) { - uint32_t nextPts = 0; - uint32_t tmpBuffer = m_next; - for (int i = 0; i < m_count && nextPts == 0; ++i) - { - if (tmpBuffer) tmpBuffer = --tmpBuffer ? tmpBuffer : (Size() - 1); - nextPts = m_pBuffer[tmpBuffer].GetPts(); - } - if (nextPts != 30) - { - cDxr3NextPts::Instance().SetNextPts(nextPts); - } - - m_next++; - m_count--; - m_next %= Size(); - if (m_next == m_nextFree) - { - m_next = m_nextFree = m_count = 0; - } + cDxr3NextPts::Instance().SetNextPts(nextPts); + } + + m_next++; + m_count--; + m_next %= Size(); + if (m_next == m_nextFree) + { + m_next = m_nextFree = m_count = 0; + } } EnablePut(); #if VDRVERSNUM < 10313 - Unlock(); + Unlock(); #endif } // ================================== -cFixedLengthFrame* cDxr3SyncBuffer::Get(void) +cFixedLengthFrame* cDxr3SyncBuffer::Get(void) { cFixedLengthFrame* pRet = 0; - - if (!m_bStopped) + + if (!m_bStopped) + { + while ((!Available() || !m_bStartReceiver) && !m_bStopped) { - while ((!Available() || !m_bStartReceiver) && !m_bStopped) - { - m_bGetBlock = true; - ReceiverStopped(); - WaitForGet(); - } - - #if VDRVERSNUM < 10313 - Lock(); - #endif - if (m_nextFree != m_next) - { - pRet = &m_pBuffer[m_next]; - } - #if VDRVERSNUM < 10313 - Unlock(); - #endif - } - else + m_bGetBlock = true; + ReceiverStopped(); + WaitForGet(); + } + +#if VDRVERSNUM < 10313 + Lock(); +#endif + if (m_nextFree != m_next) { - WaitForGet(); + pRet = &m_pBuffer[m_next]; + } +#if VDRVERSNUM < 10313 + Unlock(); +#endif + } + else + { + WaitForGet(); } return pRet; } // ================================== -void cDxr3SyncBuffer::Clear(void) +void cDxr3SyncBuffer::Clear(void) { #if VDRVERSNUM < 10313 - Lock(); + Lock(); #endif m_next = 0; m_nextFree = 0; @@ -357,108 +364,108 @@ void cDxr3SyncBuffer::Clear(void) m_bWaitPts = false; m_bStartReceiver = false; m_bPollSync = false; - if (m_bPutBlock) - { - EnablePut(); - m_bPutBlock = false; + if (m_bPutBlock) + { + EnablePut(); + m_bPutBlock = false; } cFixedLengthFrame::Clear(); cDxr3NextPts::Instance().Clear(); #if VDRVERSNUM < 10313 - Unlock(); + Unlock(); #endif } // ================================== -void cDxr3SyncBuffer::WaitForSysClock(uint32_t pts, uint32_t delta) +void cDxr3SyncBuffer::WaitForSysClock(uint32_t pts, uint32_t delta) { m_waitPts = pts; m_waitDelta = delta; - if (!m_bPutBlock) - { - #if VDRVERSNUM < 10313 - Lock(); - #endif - m_bWaitPts = true; - #if VDRVERSNUM < 10313 - Unlock(); - #endif - m_bGetBlock = true; - ReceiverStopped(); - WaitForGet(); + if (!m_bPutBlock) + { +#if VDRVERSNUM < 10313 + Lock(); +#endif + m_bWaitPts = true; +#if VDRVERSNUM < 10313 + Unlock(); +#endif + m_bGetBlock = true; + ReceiverStopped(); + WaitForGet(); } - else - { - usleep(1); //* (pts - pSysClock->GetSysClock())); + else + { + usleep(1); //* (pts - pSysClock->GetSysClock())); } } // ================================== -void cDxr3SyncBuffer::WaitForNextPut(void) +void cDxr3SyncBuffer::WaitForNextPut(void) { - if (!m_bPutBlock) - { - m_bGetBlock = true; - ReceiverStopped(); - WaitForGet(); + if (!m_bPutBlock) + { + m_bGetBlock = true; + ReceiverStopped(); + WaitForGet(); } - else - { - usleep(1); + else + { + usleep(1); } } // ================================== -void cDxr3SyncBuffer::Start(void) +void cDxr3SyncBuffer::Start(void) { m_bStartReceiver = true; m_bStopped = false; - if (Available()) - { - EnableGet(); + if (Available()) + { + EnableGet(); } } // ================================== -void cDxr3SyncBuffer::WakeUp(void) +void cDxr3SyncBuffer::WakeUp(void) { #if VDRVERSNUM < 10313 - Lock(); + Lock(); #endif - if (m_bStartReceiver == true) + if (m_bStartReceiver == true) + { + if (!m_bWaitPts) + { + EnableGet(); + } + else { - if (!m_bWaitPts) - { - EnableGet(); - } - else - { - if (m_waitPts < m_dxr3Device.GetSysClock() || - m_waitPts - m_dxr3Device.GetSysClock() < m_waitDelta) - { - EnableGet(); - m_bWaitPts = false; - } - } + if (m_waitPts < m_dxr3Device.GetSysClock() || + m_waitPts - m_dxr3Device.GetSysClock() < m_waitDelta) + { + EnableGet(); + m_bWaitPts = false; + } + } } #if VDRVERSNUM < 10313 - Unlock(); + Unlock(); #endif } // ================================== -void cDxr3SyncBuffer::WaitForReceiverStopped(void) +void cDxr3SyncBuffer::WaitForReceiverStopped(void) { - if (!m_bGetBlock) - { - receiverStoppedMutex.Lock(); - receiverStopped.Wait(receiverStoppedMutex); - receiverStoppedMutex.Unlock(); + if (!m_bGetBlock) + { + receiverStoppedMutex.Lock(); + receiverStopped.Wait(receiverStoppedMutex); + receiverStoppedMutex.Unlock(); } } // ================================== -void cDxr3SyncBuffer::ReceiverStopped(void) +void cDxr3SyncBuffer::ReceiverStopped(void) { receiverStopped.Broadcast(); } diff --git a/dxr3syncbuffer.h b/dxr3syncbuffer.h index bfef1ec..b1d2912 100644 --- a/dxr3syncbuffer.h +++ b/dxr3syncbuffer.h @@ -36,28 +36,64 @@ const uint32_t UNKNOWN_DATA_RATE = 0xFFFFFFFF; const uint32_t UNKNOWN_ASPECT_RATIO = 0xFFFFFFFF; // ================================== -class cFixedLengthFrame -{ -public: +class cFixedLengthFrame +{ +public: cFixedLengthFrame(); ~cFixedLengthFrame(); - + void Init(uint32_t lenght); - void CopyFrame(const uint8_t* pStart, int length, uint32_t pts, eFrameType type); + void CopyFrame(const uint8_t* pStart, int length, uint32_t pts, + eFrameType type); uint8_t* GetData(void); int GetCount(void); uint32_t GetPts(void); void SetPts(uint32_t pts); - void SetChannelCount(uint32_t channelCount) {if (channelCount != UNKNOWN_CHANNEL_COUNT) m_staticAudioChannelCount = m_audioChannelCount = channelCount; else m_audioChannelCount = m_staticAudioChannelCount; }; - void SetDataRate(uint32_t dataRate) {if (m_audioDataRate != UNKNOWN_DATA_RATE) m_staticAudioDataRate = m_audioDataRate = dataRate; else m_audioDataRate = m_staticAudioDataRate;}; - void SetAspectRatio(uint32_t aspectRatio) {m_videoAspectRatio = aspectRatio;}; - uint32_t GetChannelCount(void) {return ((m_audioChannelCount == m_staticAudioChannelCount || !m_staticAudioChannelCount)? m_audioChannelCount : m_staticAudioChannelCount) ;}; - uint32_t GetDataRate(void) {return ((m_audioDataRate == m_staticAudioDataRate || !m_staticAudioDataRate) ? m_audioDataRate : m_staticAudioDataRate);}; - uint32_t GetAspectRatio(void) {return m_videoAspectRatio;}; - eFrameType GetFrameType(void) {return m_type;} + void SetChannelCount(uint32_t channelCount) + { + if (channelCount != UNKNOWN_CHANNEL_COUNT) + m_staticAudioChannelCount = m_audioChannelCount = channelCount; + else + m_audioChannelCount = m_staticAudioChannelCount; + }; + void SetDataRate(uint32_t dataRate) + { + if (m_audioDataRate != UNKNOWN_DATA_RATE) + m_staticAudioDataRate = m_audioDataRate = dataRate; + else + m_audioDataRate = m_staticAudioDataRate; + }; + void SetAspectRatio(uint32_t aspectRatio) + { + m_videoAspectRatio = aspectRatio; + }; + uint32_t GetChannelCount(void) + { + return ((m_audioChannelCount == m_staticAudioChannelCount || + !m_staticAudioChannelCount)? + m_audioChannelCount : m_staticAudioChannelCount); + }; + uint32_t GetDataRate(void) + { + return ((m_audioDataRate == m_staticAudioDataRate || + !m_staticAudioDataRate) ? + m_audioDataRate : m_staticAudioDataRate); + }; + uint32_t GetAspectRatio(void) + { + return m_videoAspectRatio; + }; + eFrameType GetFrameType(void) + { + return m_type; + } - static void Clear(void) {m_staticAudioDataRate = 0; m_staticAudioChannelCount = 0;}; + static void Clear(void) + { + m_staticAudioDataRate = 0; + m_staticAudioChannelCount = 0; + }; protected: uint8_t* m_pData; @@ -65,52 +101,70 @@ protected: int m_length; uint32_t m_pts; eFrameType m_type; - + uint32_t m_audioChannelCount; uint32_t m_audioDataRate; uint32_t m_videoAspectRatio; static uint32_t m_staticAudioChannelCount; static uint32_t m_staticAudioDataRate; - + private: -// cFixedLengthFrame(); // you are not allowed to use this constructor + //cFixedLengthFrame(); // you are not allowed to use this constructor cFixedLengthFrame(cFixedLengthFrame&); // no copy constructor - + }; // ================================== -class cDxr3SyncBuffer : public cRingBuffer +class cDxr3SyncBuffer : public cRingBuffer { public: - enum eSyncBufferException - { - SYNC_BUFFER_OVERRUN - }; + enum eSyncBufferException + { + SYNC_BUFFER_OVERRUN + }; public: - cDxr3SyncBuffer(int frameCount, int frameLength, cDxr3Interface& dxr3Device); - ~cDxr3SyncBuffer(); + cDxr3SyncBuffer(int frameCount, int frameLength, + cDxr3Interface& dxr3Device); + ~cDxr3SyncBuffer(); virtual int Available(void); - cFixedLengthFrame* Push(const uint8_t* pStart, int length, uint32_t pts, eFrameType type = ftUnknown) throw (eSyncBufferException); + cFixedLengthFrame* Push(const uint8_t* pStart, int length, uint32_t pts, + eFrameType type = ftUnknown) + throw (eSyncBufferException); void Pop(void); - cFixedLengthFrame* Get(void); + cFixedLengthFrame* Get(void); void Clear(void); - void Stop(void) { m_bStopped = true;}; + void Stop(void) + { + m_bStopped = true; + }; void Start(void); void WaitForSysClock(uint32_t pts, uint32_t delta); void WaitForNextPut(void); void WakeUp(void); void WaitForReceiverStopped(void); - void SetDemuxMode(eDxr3DemuxMode demuxMode) {m_demuxMode = demuxMode;}; - eDxr3DemuxMode GetDemuxMode(void) {return m_demuxMode;}; + void SetDemuxMode(eDxr3DemuxMode demuxMode) + { + m_demuxMode = demuxMode; + }; + eDxr3DemuxMode GetDemuxMode(void) + { + return m_demuxMode; + }; bool Poll(int TimeoutMs); - bool IsPolled(void) { return m_bPollSync;}; - uint32_t GetFillLevel(void) { return Available() * 100 / Size();}; + bool IsPolled(void) + { + return m_bPollSync; + }; + uint32_t GetFillLevel(void) + { + return Available() * 100 / Size(); + }; protected: void ReceiverStopped(void); - + cFixedLengthFrame* m_pBuffer; int m_count; int m_nextFree; @@ -129,7 +183,7 @@ protected: cMutex receiverStoppedMutex; cDxr3Interface& m_dxr3Device; bool m_bPollSync; - + private: cDxr3SyncBuffer(); // you are not allowed to use this constructor cDxr3SyncBuffer(cDxr3SyncBuffer&); // no constructor diff --git a/dxr3sysclock.h b/dxr3sysclock.h index cc52e8e..d204c2e 100644 --- a/dxr3sysclock.h +++ b/dxr3sysclock.h @@ -27,27 +27,30 @@ // ================================== // work with dxr3's clock -class cDxr3SysClock +class cDxr3SysClock { public: - cDxr3SysClock(int fd_control, int fd_video, int fd_spu) : m_fdcontrol(fd_control), - m_fdvideo(fd_video), m_fdspu(fd_spu), m_offset(0) {}; - + cDxr3SysClock(int fd_control, int fd_video, int fd_spu): + m_fdcontrol(fd_control), + m_fdvideo(fd_video), + m_fdspu(fd_spu), + m_offset(0) {}; + virtual ~cDxr3SysClock() {}; - + public: void SetSysClock(uint32_t scr); uint32_t GetSysClock(void); void SetPts(uint32_t pts); void SetSpuPts(uint32_t pts); - + protected: int m_fdcontrol; int m_fdvideo; int m_fdspu; uint32_t m_offset; cMutex mutex; - + protected: cDxr3SysClock(); // you are not allowed to use this contructor cDxr3SysClock(cDxr3SysClock&); // no copy constructor diff --git a/dxr3tools.h b/dxr3tools.h index 2b84917..0a236b5 100644 --- a/dxr3tools.h +++ b/dxr3tools.h @@ -26,80 +26,80 @@ namespace Tools { - // ================================== - //! convert Rgb to CrCb - inline unsigned int Rgb2YCrCb(unsigned long rgb) - { - float Y,U,V; - float R,G,B; - unsigned int yuv = 0x0; - - B = ((rgb >> 16) & 0xFF); - G = ((rgb >> 8) & 0xFF); - R = (rgb & 0xFF); - - Y = (0.2578125 * R) + (0.50390625 * G) + (0.09765625 * B) + 16; - U = (0.4375 * R) - (0.3671875 * G) - (0.0703125 * B) + 128; - V =-(0.1484375 * R) - (0.2890625 * G) + (0.4375 * B) + 128; - - yuv = (int(Y) << 16) | (int(U) << 8) | int(V); - - return yuv; - } - - // ================================== - //! convert YUV to Rgb - inline unsigned int YUV2Rgb(unsigned int yuv_color) - { - int Y, Cb, Cr; - int Ey, Epb, Epr; - int Eg, Eb, Er; - - Y = (yuv_color >> 16) & 0xff; - Cb = (yuv_color) & 0xff; - Cr = (yuv_color >> 8) & 0xff; - - Ey = (Y - 16); - Epb = (Cb - 128); - Epr = (Cr - 128); - /* ITU-R 709 - Eg = (298*Ey - 55*Epb - 137*Epr)/256; - Eb = (298*Ey + 543*Epb)/256; - Er = (298*Ey + 460*Epr)/256; - */ - /* FCC ~= mediaLib */ - Eg = (298 * Ey - 100 * Epb - 208 * Epr) / 256; - Eb = (298 * Ey + 516 * Epb) / 256; - Er = (298 * Ey + 408 * Epr) / 256; - - if (Eg > 255) - Eg = 255; - if (Eg < 0) - Eg = 0; - - if (Eb > 255) - Eb = 255; - if (Eb < 0) - Eb = 0; - - if (Er > 255) - Er = 255; - if (Er < 0) - Er = 0; - - return Eb | (Eg << 8) | (Er << 16); - } - - // ================================== - //! write a string via vdr to OSD - inline void WriteInfoToOsd(std::string x) - { - #if VDRVERSNUM <= 10306 - Interface->Info(x.c_str()); - #else - Skins.Message(mtInfo, x.c_str()); - #endif - } + // ================================== + //! convert Rgb to CrCb + inline unsigned int Rgb2YCrCb(unsigned long rgb) + { + float Y,U,V; + float R,G,B; + unsigned int yuv = 0x0; + + B = ((rgb >> 16) & 0xFF); + G = ((rgb >> 8) & 0xFF); + R = (rgb & 0xFF); + + Y = (0.2578125 * R) + (0.50390625 * G) + (0.09765625 * B) + 16; + U = (0.4375 * R) - (0.3671875 * G) - (0.0703125 * B) + 128; + V =-(0.1484375 * R) - (0.2890625 * G) + (0.4375 * B) + 128; + + yuv = (int(Y) << 16) | (int(U) << 8) | int(V); + + return yuv; + } + + // ================================== + //! convert YUV to Rgb + inline unsigned int YUV2Rgb(unsigned int yuv_color) + { + int Y, Cb, Cr; + int Ey, Epb, Epr; + int Eg, Eb, Er; + + Y = (yuv_color >> 16) & 0xff; + Cb = (yuv_color) & 0xff; + Cr = (yuv_color >> 8) & 0xff; + + Ey = (Y - 16); + Epb = (Cb - 128); + Epr = (Cr - 128); + /* ITU-R 709 + Eg = (298*Ey - 55*Epb - 137*Epr)/256; + Eb = (298*Ey + 543*Epb)/256; + Er = (298*Ey + 460*Epr)/256; + */ + /* FCC ~= mediaLib */ + Eg = (298 * Ey - 100 * Epb - 208 * Epr) / 256; + Eb = (298 * Ey + 516 * Epb) / 256; + Er = (298 * Ey + 408 * Epr) / 256; + + if (Eg > 255) + Eg = 255; + if (Eg < 0) + Eg = 0; + + if (Eb > 255) + Eb = 255; + if (Eb < 0) + Eb = 0; + + if (Er > 255) + Er = 255; + if (Er < 0) + Er = 0; + + return Eb | (Eg << 8) | (Er << 16); + } + + // ================================== + //! write a string via vdr to OSD + inline void WriteInfoToOsd(std::string x) + { +#if VDRVERSNUM <= 10306 + Interface->Info(x.c_str()); +#else + Skins.Message(mtInfo, x.c_str()); +#endif + } } diff --git a/dxr3vdrincludes.h b/dxr3vdrincludes.h index 347e350..70508e6 100644 --- a/dxr3vdrincludes.h +++ b/dxr3vdrincludes.h @@ -34,9 +34,9 @@ // all includes from vdr #if VDRVERSNUM >= 10307 - #include <vdr/osd.h> +#include <vdr/osd.h> #else - #include <vdr/osdbase.h> +#include <vdr/osdbase.h> #endif #include <vdr/config.h> #include <vdr/thread.h> |