]> git.lyx.org Git - features.git/commitdiff
Fix the loading of xpm files by the simple image loader when it encounters
authorAngus Leeming <leeming@lyx.org>
Wed, 17 Apr 2002 16:08:31 +0000 (16:08 +0000)
committerAngus Leeming <leeming@lyx.org>
Wed, 17 Apr 2002 16:08:31 +0000 (16:08 +0000)
colour strings like #rrrrggggbbbb.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@4017 a592a061-630c-0410-9148-cb99ea01b6c8

src/graphics/ChangeLog
src/graphics/GraphicsImageXPM.C

index c1c9564dce067dcb073d679e5b6471510fc9d3c4..bc4c5cfcb99b61b595c7301347c031710bf68aa8 100644 (file)
@@ -1,3 +1,9 @@
+2002-04-17  Angus Leeming  <a.leeming@ic.ac.uk>
+
+       * GraphicsImageXPM.C (Data::reset): Fix the loading of xpm files by
+       the simple image loader when it encounters colour strings like
+       #rrrrggggbbbb.
+
 2002-04-16  Angus Leeming  <a.leeming@ic.ac.uk>
 
        * GraphicsCacheItem.C (convertToDisplayFormat):
index 7289e37154e0b3b5bcfddf28367dfd7ccadd0fca..453bbb0b15301230507628e16242313be2eb490c 100644 (file)
@@ -388,6 +388,10 @@ bool contains_color_none(XpmImage const & image);
 
 string const unique_color_string(XpmImage const & image);
 
+// libXpm cannot cope with strings of the form #rrrrggggbbbb,
+// #rrrgggbbb or #rgb, so convert them to #rrggbb.
+string const convertTo7chars(string const &);
+
 // create a copy (using malloc and strcpy). If (!in) return 0;
 char * clone_c_string(char const * in);
 
@@ -470,21 +474,17 @@ void GImageXPM::Data::reset(XpmImage & image)
 
        // 2. Ensure that the color table has g_color and m_color entries
        XpmColor * table = colorTable_.get();
-       string buggy_color;
 
        for (size_t i = 0; i < ncolors_; ++i) {
                XpmColor & entry = table[i];
                if (!entry.c_color)
                        continue;
 
-               // A work-around for buggy XPM files that may be created by
-               // ImageMagick's convert.
+               // libXpm cannot cope with strings of the form #rrrrggggbbbb,
+               // #rrrgggbbb or #rgb, so convert them to #rrggbb.
                string c_color = entry.c_color;
-               if (c_color[0] == '#' && c_color.size() > 7) {
-                       if (buggy_color.empty())
-                               buggy_color = c_color;
-
-                       c_color = c_color.substr(0, 7);
+               if (c_color[0] == '#' && c_color.size() != 7) {
+                       c_color = convertTo7chars(c_color);
                        free(entry.c_color);
                        entry.c_color = clone_c_string(c_color.c_str());
                }
@@ -493,18 +493,6 @@ void GImageXPM::Data::reset(XpmImage & image)
                // grayscale or monochrome ones are not, then define them.
                mapcolor(entry.c_color, &entry.g_color, &entry.m_color);
        }
-
-       if (!buggy_color.empty()) {
-               lyxerr << "The XPM file contains silly colors, "
-                      << "an example being \""
-                      << buggy_color << "\".\n"
-                      << "This was cropped to \""
-                      << buggy_color.substr(0, 7)
-                      << "\" so you can see something!\n"
-                      << "If this file was created by ImageMagick's convert,\n"
-                      << "then upgrading may cure the problem."
-                      << std::endl;
-       }
 }
 
 
@@ -557,6 +545,68 @@ unsigned int GImageXPM::Data::color_none_id() const
 
 namespace {
 
+// libXpm cannot cope with strings of the form #rrrrggggbbbb,
+// #rrrgggbbb or #rgb, so convert them to #rrggbb.
+string const convertTo7chars(string const & input)
+{
+       string::size_type size = input.size();
+       if (size != 13 && size != 10 && size != 4)
+               // Can't deal with it.
+               return input;
+
+       if (input[0] != '#')
+               // Can't deal with it.
+               return input;
+
+       int nbytes;
+       double factor;
+       switch (size) {
+       case 13: // #rrrrggggbbbb
+           nbytes = 4;
+           factor = 1.0 / 256.0;
+           break;
+
+       case 10: // #rrrgggbbb
+           nbytes = 3;
+           factor = 1.0 / 16.0;
+           break;
+
+       case 4:  // #rgb
+           nbytes = 1;
+           factor = 16.0;
+           break;
+       }
+
+       int r, g, b;
+       int const pos1 = 1;
+       int const pos2 = pos1 + nbytes;
+       int const pos3 = pos2 + nbytes;
+       
+       stringstream ss;
+       ss << input.substr(pos1, nbytes) << ' '
+          << input.substr(pos2, nbytes) << ' '
+          << input.substr(pos3, nbytes);
+       ss >> std::hex >> r >> g >> b;
+       if (ss.fail())
+               // Oh, you're on your own.
+               return input;
+       
+       // The existing r,g,b values are multiplied by these factors
+       // to end up with values in the range 0 <= c <= 255
+       r = int(factor * double(r));
+       g = int(factor * double(g));
+       b = int(factor * double(b));
+
+       ostringstream oss;
+       oss << '#' << std::hex << std::setfill('0')
+           << std::setw(2) << r
+           << std::setw(2) << g
+           << std::setw(2) << b;
+
+       return oss.str().c_str();
+}
+
+
 // Given a string of the form #ff0571 create appropriate grayscale and
 // monochrome colors.
 void mapcolor(char const * c_color, char ** g_color_ptr, char ** m_color_ptr)