예제 #1
0
 /// <summary>
 /// Decodes the toptext multi page.
 /// </summary>
 /// <param name="cache">The cache.</param>
 private void DecodeMultiPage(TeletextPageCache cache)
 {
     // multi page contains the number of subpages transmitted for each page (100-899);
     if (!cache.PageExists(TOP_MULTI_PAGE))
     {
         return;
     }
     byte[] multiPage = cache.GetPage(TOP_MULTI_PAGE, 0);
     for (int pageNr = 100; pageNr <= 899; pageNr++)
     {
         int  row  = ((pageNr - 100) / 40) + 1;
         int  col  = ((pageNr - 100) % 40) + 2;
         byte data = Hamming.Decode[multiPage[row * 42 + col]];
         if (data == NotPresent)
         {
             //page is offair
             _pageSubCount[pageNr] = 0;
         }
         else if (data == 0x0a)
         {
             //page has > 10 subpages
             _pageSubCount[pageNr] = 10; //( or more)
         }
         else
         {
             int numberOfSubPages = data - 1;
             _pageSubCount[pageNr] = numberOfSubPages;
         }
     }
 }
예제 #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TeletextDecoder"/> class.
 /// </summary>
 /// <param name="cache">The cache.</param>
 public TeletextDecoder(TeletextPageCache cache)
 {
     _prevMagazine = 0;
     _pageCache    = cache;
     for (int i = 0; i < MAX_MAGAZINE + 2; ++i)
     {
         _vbiLine[i] = "";
         byte[] page = new byte[2100];
         _workingPage.Add(page);
     }
     Clear();
 }
예제 #3
0
        /// <summary>
        /// Decodes the additional toptext pages.
        /// </summary>
        /// <param name="cache">The cache.</param>
        private void DecodeAdditionalPages(TeletextPageCache cache)
        {
            //addditional pages carry information to display on line 24
            //
            for (int pageNr = TOP_ADDITIONAL_PAGE; pageNr < 0x1fd; ++pageNr)
            {
                if (!cache.PageExists(pageNr))
                {
                    continue;
                }
                byte[] additionalPage = cache.GetPage(pageNr, 0);
                int    lineCounter    = 0;
                while (true)
                {
                    int  row       = 1 + (lineCounter / 2);
                    int  col       = (20 * (lineCounter % 2));
                    byte magazine  = Hamming.Decode[additionalPage[row * 42 + 2 + col]];
                    byte pageTens  = Hamming.Decode[additionalPage[row * 42 + 3 + col]];
                    byte pageUnits = Hamming.Decode[additionalPage[row * 42 + 4 + col]];
                    if (magazine >= 0 && magazine <= 7)
                    {
                        if (pageTens >= 0x0 && pageTens <= 9)
                        {
                            if (pageUnits >= 0x0 && pageUnits <= 9)
                            {
                                string description = String.Empty;
                                for (int i = 1; i < 12; ++i)
                                {
                                    row = 1 + (lineCounter / 2);
                                    col = 9 + i + (20 * (lineCounter % 2));

                                    description += (char)(additionalPage[row * 42 + col] & 0x7f);
                                }
                                if (magazine == 0)
                                {
                                    magazine = 8;
                                }
                                int pageNo = magazine * 100 + pageTens * 10 + pageUnits;
                                if (pageNo >= 100 && pageNo <= 899)
                                {
                                    _pageDescription[pageNo] = description;
                                }
                            }
                        }
                    }
                    lineCounter++;
                    if (lineCounter >= 43)
                    {
                        break;
                    }
                }
            }
        }
예제 #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TeletextDecoder"/> class.
 /// </summary>
 /// <param name="cache">The cache.</param>
 public TeletextDecoder(TeletextPageCache cache)
 {
   _prevMagazine = 0;
   _pageCache = cache;
   for (int i = 0; i < MAX_MAGAZINE + 2; ++i)
   {
     _vbiLine[i] = "";
     byte[] page = new byte[2100];
     _workingPage.Add(page);
   }
   Clear();
 }
예제 #5
0
        /// <summary>
        /// Decodes the toptext for a specific page.
        /// </summary>
        /// <param name="cache">The cache.</param>
        /// <param name="pageNumber">The page number.</param>
        /// <returns>true when decoding succeeded</returns>
        public bool Decode(TeletextPageCache cache, int pageNumber)
        {
            int    red, green, yellow, blue;
            string nextGroup, nextBlock;

            if (!GetPageLinks(cache, pageNumber, out red, out green, out yellow, out blue, out nextGroup, out nextBlock))
            {
                return(false);
            }
            _pageRed    = ConvertToHex(red);
            _pageGreen  = ConvertToHex(green);
            _pageYellow = ConvertToHex(yellow);
            _pageBlue   = ConvertToHex(blue);
            if (nextGroup == String.Empty)
            {
                nextGroup = green.ToString();
            }
            if (nextBlock == String.Empty)
            {
                nextBlock = yellow.ToString();
            }

            Hamming.SetPacketNumber(0, ref _row24, pageNumber, 24);
            int spaces = 40 - (nextGroup.Length + nextBlock.Length + 3 + 3 + 4);

            spaces /= 3;
            string line = ((char)TeletextPageRenderer.Attributes.AlphaRed) + red.ToString();

            for (int x = 0; x < spaces; x++)
            {
                line += " ";
            }

            line += ((char)TeletextPageRenderer.Attributes.AlphaGreen) + nextGroup;
            for (int x = 0; x < spaces; x++)
            {
                line += " ";
            }

            line += ((char)TeletextPageRenderer.Attributes.AlphaYellow) + nextBlock;
            for (int x = 0; x < spaces; x++)
            {
                line += " ";
            }
            line += ((char)TeletextPageRenderer.Attributes.AlphaCyan) + blue.ToString();
            for (int i = 0; i < line.Length && i <= 40; ++i)
            {
                _row24[2 + i] = (byte)line[i];
            }
            return(true);
        }
예제 #6
0
 /// <summary>
 /// Decodes the basic toptext page.
 /// </summary>
 /// <param name="cache">The cache.</param>
 /// <returns></returns>
 private bool DecodeBasicPage(TeletextPageCache cache)
 {
     //basic toppage contains information which teletext pages are onair
     //and if onair if it has subpages or not
     //also contains the type for each page
     if (!cache.PageExists(TOP_BASIC_PAGE))
     {
         return(false);
     }
     byte[] basicPage = cache.GetPage(TOP_BASIC_PAGE, 0);
     for (int pageNr = 100; pageNr <= 899; pageNr++)
     {
         int  row  = ((pageNr - 100) / 40) + 1;
         int  col  = ((pageNr - 100) % 40) + 2;
         byte data = Hamming.Decode[basicPage[row * 42 + col]];
         if (data == ProgramInfoBlockPageMulti ||
             data == BlockPageMulti ||
             data == GroupPageMulti ||
             data == NormalPageMulti ||
             data == NormalPageMultiInfo
             )
         {
             //page is onair and has subpages
             _pageType[pageNr] = data;
         }
         if (data == ProgramInfoBlockPageSingle ||
             data == BlockPageSingle ||
             data == GroupPageSingle ||
             data == NormalPage ||
             data == NormalPageInfo)
         {
             //page is onair and has subpages
             _pageType[pageNr] = data;
         }
         if (data == NotPresent)
         {
             //page is not onair
             _pageType[pageNr]     = data;
             _pageSubCount[pageNr] = 0;
         }
     }
     return(true);
 }
예제 #7
0
        /// <summary>
        /// Gets the page links for a page.
        /// </summary>
        /// <param name="cache">The cache.</param>
        /// <param name="pageNumber">The page number.</param>
        /// <param name="redPage">The red page.</param>
        /// <param name="greenPage">The green page.</param>
        /// <param name="yellowPage">The yellow page.</param>
        /// <param name="bluePage">The blue page.</param>
        /// <param name="nextGroup">The next group.</param>
        /// <param name="nextBlock">The next block.</param>
        /// <returns></returns>
        public bool GetPageLinks(TeletextPageCache cache, int pageNumber, out int redPage, out int greenPage,
                                 out int yellowPage, out int bluePage, out string nextGroup, out string nextBlock)
        {
            //red   = previous page in current
            //green = first page of next group
            //yellow= first page of next block
            //blue  = next page
            int mag         = pageNumber / 0x100;
            int tens        = (pageNumber - mag * 0x100) / 0x10;
            int units       = (pageNumber - mag * 0x100) - tens * 0x10;
            int decimalPage = mag * 100 + tens * 10 + units;

            Clear();
            nextGroup = "";
            nextBlock = "";
            redPage   = greenPage = yellowPage = bluePage = -1;

            if (!DecodeBasicPage(cache))
            {
                return(false);
            }
            DecodeMultiPage(cache);
            DecodeAdditionalPages(cache);

            //red: prev page
            for (int page = decimalPage - 1; page > 100; page--)
            {
                if (_pageType[page] != NotPresent)
                {
                    redPage = page;
                    break;
                }
            }
            if (redPage == -1)
            {
                for (int page = 899; page > 100; page--)
                {
                    if (_pageType[page] != NotPresent)
                    {
                        redPage = page;
                        break;
                    }
                }
            }

            for (int page = decimalPage + 1; page <= 899; page++)
            {
                if (greenPage == -1)
                {
                    if (_pageType[page] == GroupPageSingle || _pageType[page] == GroupPageMulti)
                    {
                        greenPage = page;
                        nextGroup = _pageDescription[greenPage] ?? greenPage.ToString();
                    }
                }
                if (yellowPage == -1)
                {
                    if (_pageType[page] == BlockPageSingle || _pageType[page] == BlockPageMulti)
                    {
                        yellowPage = page;
                        nextBlock  = _pageDescription[yellowPage] ?? yellowPage.ToString();
                    }
                }
            }

            for (int page = 100; page <= decimalPage; page++)
            {
                if (greenPage == -1)
                {
                    if (_pageType[page] == GroupPageSingle || _pageType[page] == GroupPageMulti)
                    {
                        greenPage = page;
                        nextGroup = _pageDescription[greenPage] ?? greenPage.ToString();
                    }
                }
                if (yellowPage == -1)
                {
                    if (_pageType[page] == BlockPageSingle || _pageType[page] == BlockPageMulti)
                    {
                        yellowPage = page;
                        nextBlock  = _pageDescription[yellowPage] ?? yellowPage.ToString();
                    }
                }
            }


            //blue : next page
            for (int page = decimalPage + 1; page <= 899; page++)
            {
                if (_pageType[page] != NotPresent)
                {
                    bluePage = page;
                    break;
                }
            }
            if (bluePage == -1)
            {
                for (int page = 100; page <= 899; page++)
                {
                    if (_pageType[page] != NotPresent)
                    {
                        bluePage = page;
                        break;
                    }
                }
            }

            nextGroup = nextGroup.Trim();
            nextBlock = nextBlock.Trim();
            return(true);
        }
예제 #8
0
    /// <summary>
    /// Decodes the additional toptext pages.
    /// </summary>
    /// <param name="cache">The cache.</param>
    private void DecodeAdditionalPages(TeletextPageCache cache)
    {
      //addditional pages carry information to display on line 24
      //
      for (int pageNr = TOP_ADDITIONAL_PAGE; pageNr < 0x1fd; ++pageNr)
      {
        if (!cache.PageExists(pageNr))
          continue;
        byte[] additionalPage = cache.GetPage(pageNr, 0);
        int lineCounter = 0;
        while (true)
        {
          int row = 1 + (lineCounter / 2);
          int col = (20 * (lineCounter % 2));
          byte magazine = Hamming.Decode[additionalPage[row * 42 + 2 + col]];
          byte pageTens = Hamming.Decode[additionalPage[row * 42 + 3 + col]];
          byte pageUnits = Hamming.Decode[additionalPage[row * 42 + 4 + col]];
          if (magazine >= 0 && magazine <= 7)
          {
            if (pageTens >= 0x0 && pageTens <= 9)
            {
              if (pageUnits >= 0x0 && pageUnits <= 9)
              {
                string description = String.Empty;
                for (int i = 1; i < 12; ++i)
                {
                  row = 1 + (lineCounter / 2);
                  col = 9 + i + (20 * (lineCounter % 2));

                  description += (char)(additionalPage[row * 42 + col] & 0x7f);
                }
                if (magazine == 0)
                  magazine = 8;
                int pageNo = magazine * 100 + pageTens * 10 + pageUnits;
                if (pageNo >= 100 && pageNo <= 899)
                {
                  _pageDescription[pageNo] = description;
                }
              }
            }
          }
          lineCounter++;
          if (lineCounter >= 43)
            break;
        }
      }
    }
예제 #9
0
 /// <summary>
 /// Decodes the toptext multi page.
 /// </summary>
 /// <param name="cache">The cache.</param>
 private void DecodeMultiPage(TeletextPageCache cache)
 {
   // multi page contains the number of subpages transmitted for each page (100-899);
   if (!cache.PageExists(TOP_MULTI_PAGE))
     return;
   byte[] multiPage = cache.GetPage(TOP_MULTI_PAGE, 0);
   for (int pageNr = 100; pageNr <= 899; pageNr++)
   {
     int row = ((pageNr - 100) / 40) + 1;
     int col = ((pageNr - 100) % 40) + 2;
     byte data = Hamming.Decode[multiPage[row * 42 + col]];
     if (data == NotPresent)
     {
       //page is offair
       _pageSubCount[pageNr] = 0;
     }
     else if (data == 0x0a)
     {
       //page has > 10 subpages
       _pageSubCount[pageNr] = 10; //( or more)
     }
     else
     {
       int numberOfSubPages = data - 1;
       _pageSubCount[pageNr] = numberOfSubPages;
     }
   }
 }
예제 #10
0
 /// <summary>
 /// Decodes the basic toptext page.
 /// </summary>
 /// <param name="cache">The cache.</param>
 /// <returns></returns>
 private bool DecodeBasicPage(TeletextPageCache cache)
 {
   //basic toppage contains information which teletext pages are onair
   //and if onair if it has subpages or not
   //also contains the type for each page
   if (!cache.PageExists(TOP_BASIC_PAGE))
     return false;
   byte[] basicPage = cache.GetPage(TOP_BASIC_PAGE, 0);
   for (int pageNr = 100; pageNr <= 899; pageNr++)
   {
     int row = ((pageNr - 100) / 40) + 1;
     int col = ((pageNr - 100) % 40) + 2;
     byte data = Hamming.Decode[basicPage[row * 42 + col]];
     if (data == ProgramInfoBlockPageMulti ||
         data == BlockPageMulti ||
         data == GroupPageMulti ||
         data == NormalPageMulti ||
         data == NormalPageMultiInfo
       )
     {
       //page is onair and has subpages
       _pageType[pageNr] = data;
     }
     if (data == ProgramInfoBlockPageSingle ||
         data == BlockPageSingle ||
         data == GroupPageSingle ||
         data == NormalPage ||
         data == NormalPageInfo)
     {
       //page is onair and has subpages
       _pageType[pageNr] = data;
     }
     if (data == NotPresent)
     {
       //page is not onair
       _pageType[pageNr] = data;
       _pageSubCount[pageNr] = 0;
     }
   }
   return true;
 }
예제 #11
0
    /// <summary>
    /// Gets the page links for a page.
    /// </summary>
    /// <param name="cache">The cache.</param>
    /// <param name="pageNumber">The page number.</param>
    /// <param name="redPage">The red page.</param>
    /// <param name="greenPage">The green page.</param>
    /// <param name="yellowPage">The yellow page.</param>
    /// <param name="bluePage">The blue page.</param>
    /// <param name="nextGroup">The next group.</param>
    /// <param name="nextBlock">The next block.</param>
    /// <returns></returns>
    public bool GetPageLinks(TeletextPageCache cache, int pageNumber, out int redPage, out int greenPage,
                             out int yellowPage, out int bluePage, out string nextGroup, out string nextBlock)
    {
      //red   = previous page in current
      //green = first page of next group
      //yellow= first page of next block
      //blue  = next page
      int mag = pageNumber / 0x100;
      int tens = (pageNumber - mag * 0x100) / 0x10;
      int units = (pageNumber - mag * 0x100) - tens * 0x10;
      int decimalPage = mag * 100 + tens * 10 + units;

      Clear();
      nextGroup = "";
      nextBlock = "";
      redPage = greenPage = yellowPage = bluePage = -1;

      if (!DecodeBasicPage(cache))
        return false;
      DecodeMultiPage(cache);
      DecodeAdditionalPages(cache);

      //red: prev page
      for (int page = decimalPage - 1; page > 100; page--)
      {
        if (_pageType[page] != NotPresent)
        {
          redPage = page;
          break;
        }
      }
      if (redPage == -1)
      {
        for (int page = 899; page > 100; page--)
        {
          if (_pageType[page] != NotPresent)
          {
            redPage = page;
            break;
          }
        }
      }

      for (int page = decimalPage + 1; page <= 899; page++)
      {
        if (greenPage == -1)
        {
          if (_pageType[page] == GroupPageSingle || _pageType[page] == GroupPageMulti)
          {
            greenPage = page;
            nextGroup = _pageDescription[greenPage] ?? greenPage.ToString();
          }
        }
        if (yellowPage == -1)
        {
          if (_pageType[page] == BlockPageSingle || _pageType[page] == BlockPageMulti)
          {
            yellowPage = page;
            nextBlock = _pageDescription[yellowPage] ?? yellowPage.ToString();
          }
        }
      }

      for (int page = 100; page <= decimalPage; page++)
      {
        if (greenPage == -1)
        {
          if (_pageType[page] == GroupPageSingle || _pageType[page] == GroupPageMulti)
          {
            greenPage = page;
            nextGroup = _pageDescription[greenPage] ?? greenPage.ToString();
          }
        }
        if (yellowPage == -1)
        {
          if (_pageType[page] == BlockPageSingle || _pageType[page] == BlockPageMulti)
          {
            yellowPage = page;
            nextBlock = _pageDescription[yellowPage] ?? yellowPage.ToString();
          }
        }
      }


      //blue : next page
      for (int page = decimalPage + 1; page <= 899; page++)
      {
        if (_pageType[page] != NotPresent)
        {
          bluePage = page;
          break;
        }
      }
      if (bluePage == -1)
      {
        for (int page = 100; page <= 899; page++)
        {
          if (_pageType[page] != NotPresent)
          {
            bluePage = page;
            break;
          }
        }
      }

      nextGroup = nextGroup.Trim();
      nextBlock = nextBlock.Trim();
      return true;
    }
예제 #12
0
    /// <summary>
    /// Decodes the toptext for a specific page.
    /// </summary>
    /// <param name="cache">The cache.</param>
    /// <param name="pageNumber">The page number.</param>
    /// <returns>true when decoding succeeded</returns>
    public bool Decode(TeletextPageCache cache, int pageNumber)
    {
      int red, green, yellow, blue;
      string nextGroup, nextBlock;
      if (!GetPageLinks(cache, pageNumber, out red, out green, out yellow, out blue, out nextGroup, out nextBlock))
        return false;
      _pageRed = ConvertToHex(red);
      _pageGreen = ConvertToHex(green);
      _pageYellow = ConvertToHex(yellow);
      _pageBlue = ConvertToHex(blue);
      if (nextGroup == String.Empty)
        nextGroup = green.ToString();
      if (nextBlock == String.Empty)
        nextBlock = yellow.ToString();

      Hamming.SetPacketNumber(0, ref _row24, pageNumber, 24);
      int spaces = 40 - (nextGroup.Length + nextBlock.Length + 3 + 3 + 4);
      spaces /= 3;
      string line = ((char)TeletextPageRenderer.Attributes.AlphaRed) + red.ToString();
      for (int x = 0; x < spaces; x++)
        line += " ";

      line += ((char)TeletextPageRenderer.Attributes.AlphaGreen) + nextGroup;
      for (int x = 0; x < spaces; x++)
        line += " ";

      line += ((char)TeletextPageRenderer.Attributes.AlphaYellow) + nextBlock;
      for (int x = 0; x < spaces; x++)
        line += " ";
      line += ((char)TeletextPageRenderer.Attributes.AlphaCyan) + blue.ToString();
      for (int i = 0; i < line.Length && i <= 40; ++i)
      {
        _row24[2 + i] = (byte)line[i];
      }
      return true;
    }