namespace dvd
 {
     // Maximum number of buttons in a menu.
-    const int menu_buttons_max = 36;
+    const unsigned menu_buttons_max = 36;
 
     // Number of colours allowed in each button.
     // Buttons can change colour when they are selected.
-    const int button_n_colours = 4;
+    const unsigned button_n_colours = 4;
 
     // DVD virtual machine register size.
-    const int reg_bits = 16;
+    const unsigned reg_bits = 16;
 
     // Number by which button numbers must be multiplied when stored in
     // system register 8.
-    const int reg_s8_button_mult = 0x400;
+    const unsigned reg_s8_button_mult = 0x400;
+
+    // Maximum number of PGCs in a domain that can be linked to.
+    // dvdauthor uses some menu numbers for special purposes,
+    // resulting in a practical limit of 119 per domain.
+    const unsigned domain_pgcs_max = 119;
+
+    // Maximum number of titles on a disc.  (Also the maximum number of
+    // titlesets per disc.)
+    const unsigned titles_max = 99;
 }
 
 #endif // !INC_DVD_HPP
 
            * double(params.rate_numer)
            / double(params.rate_denom);
     }
+
+    void throw_length_error(const char * limit_type, std::size_t limit)
+    {
+       std::ostringstream oss;
+       oss << "exceeded DVD limit: " << limit_type << " > " << limit;
+       throw std::length_error(oss.str());
+    }
 }
 
 dvd_generator::dvd_generator(const video::frame_params & frame_params,
 {
     pgc_ref next_menu(menu_pgc, menus_.size());
 
-    // Check against maximum number of menus.  It appears that no more
-    // than 128 menus are reachable through LinkPGCN instructions, and
-    // dvdauthor uses some menu numbers for special purposes, resulting
-    // in a practical limit of 119 per domain.  We can work around this
-    // later by spreading some menus across titlesets.
-    if (next_menu.index == 119)
-       throw std::runtime_error("No more than 119 menus can be used");
+    if (next_menu.index == dvd::domain_pgcs_max)
+       throw_length_error("number of menus", dvd::domain_pgcs_max);
 
     menus_.resize(next_menu.index + 1);
     return next_menu;
     assert(index < menus_.size());
     assert(target.type == menu_pgc && target.index < menus_.size()
           || target.type == title_pgc && target.index < titles_.size());
+
+    if (menus_[index].entries.size() == dvd::menu_buttons_max)
+       throw_length_error("number of buttons", dvd::menu_buttons_max);
+
     menu_entry new_entry = { area, target };
     menus_[index].entries.push_back(new_entry);
 }
     pgc_ref next_title(title_pgc, titles_.size());
 
     // Check against maximum number of titles.
-    if (next_title.index == 99)
-       throw std::runtime_error("No more than 99 titles can be used");
+    if (next_title.index == dvd::titles_max)
+       throw_length_error("number of titles", dvd::titles_max);
 
     titles_.resize(next_title.index + 1);
     titles_[next_title.index].swap(content);
 
                                  Gdk::COLORSPACE_RGB,
                                  true, 8, // has_alpha, bits_per_sample
                                  width, height)),
-                 link_num(0),
                  links_it(doc),
                  link_changing(false)
            {
        Glib::RefPtr<Gdk::Pixbuf> norm_pixbuf;
        Glib::RefPtr<Gdk::Pixbuf> diff_pixbuf;
 
-       unsigned link_num;
        link_iterator links_it, links_end;
 
        rectangle link_rect;
                    continue;
                }
 
-               ++state->link_num;
-
-               if (state->link_num >= unsigned(dvd::menu_buttons_max))
-               {
-                   if (state->link_num == unsigned(dvd::menu_buttons_max))
-                       std::cerr << "No more than " << dvd::menu_buttons_max
-                                 << " buttons can be placed on a menu\n";
-                   std::cerr << "Ignoring link to " << uri_and_fragment
-                             << "\n";
-                   continue;
-               }
-
                // Check whether this is a link to a video or a page then
                // add it to the known resources if not already seen; then
                // add it to the menu entries.