home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / vos2-121.zip / v / iconed / imageio.cpp < prev    next >
C/C++ Source or Header  |  1998-07-03  |  34KB  |  1,386 lines

  1. //===============================================================
  2. // imageio.cpp - IO library to read/write various image bitmap formats
  3. //
  4. // Copyright (C) 1996 Philip Eckenroth, Mike Tipping, Marilee Padilla,
  5. //                    John Fredric Jr. Masciantoni, and Bruce E. Wampler.
  6. //
  7. // This file is part of the V Icon Editor, and is covered
  8. // under the terms of the GNU General Public License,
  9. // Version 2. This program has NO WARRANTY. See the source file
  10. // viedapp.cpp for more complete information about license terms.
  11. //
  12. //===============================================================
  13.  
  14. #include "imageio.h"
  15. #include <string.h>
  16. #include <ctype.h>
  17.  
  18. #define FailMsgs        // If want to use V failure messages
  19.  
  20. #ifdef FailMsgs
  21. #include <v/vapp.h>
  22. #include <v/vnotice.h>
  23. #endif
  24.  
  25. //==================>>> imageIO::imageIO <<<====================
  26.   imageIO::imageIO(int maxW, int maxH)
  27.   {
  28.     _r = _g = _b = _pixels = 0;
  29.     _height = _width = _colors = _depth = 0;
  30.     _maxH = maxH; _maxW = maxW;
  31.   }
  32.  
  33. //==================>>> imageIO::imageIO <<<====================
  34.   imageIO::~imageIO()
  35.   {
  36.     // Destructor: free memory
  37.     ResetMemory();
  38.   }
  39.  
  40. //==================>>> imageIO::ResetMemory() <<<====================
  41.   void imageIO::ResetMemory()
  42.   {
  43.     // Free the memory that we've allocated
  44.  
  45.     if (_pixels != 0)
  46.         delete [] _pixels;
  47.     if (_b != 0)
  48.         delete [] _b;
  49.     if (_g != 0)
  50.         delete [] _g;
  51.     if (_r != 0)
  52.         delete [] _r;
  53.     _r = _g = _b = _pixels = 0;
  54.     _height = _width = _colors = _depth = 0;
  55.   }
  56.  
  57. //==================>>> imageIO::OptimizeColorMap() <<<====================
  58.   void imageIO::OptimizeColorMap()
  59.   {
  60.     // This method will optimize the color map. It also
  61.     // tries to put black first and white second
  62.  
  63.     int moved[256];
  64.     long used[256];
  65.     long lx;
  66.     int ix;
  67.  
  68.     if (_pixels == 0 || !_r || !_g || !_b)
  69.     return;
  70.  
  71.     long limit = _width * _height;
  72.  
  73.     // Find and zap duplicates
  74.     for (ix = 0 ; ix < 256 ; ++ix)      // assume all colors used
  75.         used[ix] = 1;
  76.  
  77.     for (ix = 0 ; ix < 255 ; ++ix)
  78.       {
  79.         if (used[ix])                   // might be dups
  80.           {
  81.             for (int idup = ix + 1 ; idup < 256 ; ++idup) // scan rest of list
  82.               {
  83.                 if (_r[ix] == _r[idup] && _g[ix] == _g[idup] && _b[ix] == _b[idup])
  84.                   {
  85.                     used[idup] = 0;             // fixing now, so don't scan again
  86.                     for (lx = 0 ; lx < limit ; ++lx)    // Scan pixel array
  87.                       {
  88.                         if (_pixels[lx] == idup)
  89.                             _pixels[lx] = ix;   // change to first color
  90.                       }
  91.                   }
  92.               }
  93.           }
  94.       }
  95.  
  96.     // Now count usage of colors
  97.     for (ix = 0 ; ix < 256 ; ++ix)      // not used yet
  98.       {
  99.         used[ix] = 0;
  100.         moved[ix] = 0;
  101.       }
  102.  
  103.     for (lx = 0 ; lx < limit ; ++lx)
  104.         ++used[_pixels[lx]];            // count and set usage
  105.  
  106.     for (ix = 0 ; ix < 255 ; ++ix)      // now squish
  107.       {
  108.         if (used[ix] == 0)              // this one not used
  109.           {
  110.             // Find the next one that IS used
  111.             for (int iy = ix + 1; iy < 256 ; ++iy)      // check rest
  112.               {
  113.                 if (used[iy])           // one that IS used
  114.                   {
  115.             // Swap colors
  116.             unsigned char tmp;
  117.             tmp = _r[iy]; _r[iy] = _r[ix]; _r[ix] = tmp;
  118.             tmp = _g[iy]; _g[iy] = _g[ix]; _g[ix] = tmp;
  119.             tmp = _b[iy]; _b[iy] = _b[ix]; _b[ix] = tmp;
  120.  
  121.                     used[ix] = used[iy];  // change
  122.                     used[iy] = 0;
  123.             for (lx = 0 ; lx < limit ; ++lx)   // fixup pixels
  124.                       {
  125.                         if (_pixels[lx] == iy)
  126.                             _pixels[lx] = ix;   // shift down
  127.                       }
  128.                     break;      // break to look for next unused color
  129.                   }
  130.               }
  131.           }
  132.       }
  133.  
  134.     // Reset how many colors are used
  135.     for (ix = 0 ; ix < 256 ; ++ix)
  136.       {
  137.         if (!used[ix])
  138.             break;
  139.       }
  140.     _colors = ix;
  141.  
  142.     if (_colors < 2)        // MUST have 2 colors!
  143.       {
  144.     _colors = 2;
  145.     if (_r[0] == 0)
  146.       {
  147.         _r[1] = 255; _g[1] = 255; _b[1] = 255;
  148.       }
  149.     else
  150.       {
  151.         _r[1] = 0; _g[1] = 0; _b[1] = 0;
  152.       }
  153.       }
  154.  
  155.     // Finally, put black as 0 and white as 1
  156.     for (ix = 0 ; ix < _colors ; ++ix) 
  157.       {
  158.         if (_r[ix] == 0 && _g[ix] == 0 && _b[ix] == 0)
  159.           {
  160.             // swap colors
  161.             unsigned char tmp;
  162.             tmp = _r[0]; _r[0] = _r[ix]; _r[ix] = tmp;
  163.             tmp = _g[0]; _g[0] = _g[ix]; _g[ix] = tmp;
  164.             tmp = _b[0]; _b[0] = _b[ix]; _b[ix] = tmp;
  165.             for (lx = 0 ; lx < limit ; ++lx)
  166.               {
  167.                 if (_pixels[lx] == 0)
  168.                     _pixels[lx] = ix;
  169.                 else if (_pixels[lx] == ix)
  170.                     _pixels[lx] = 0;
  171.               }
  172.             break;                      // all done
  173.           }
  174.       }
  175.  
  176.     for (ix = 0 ; ix < _colors ; ++ix)  // don't move if already 1
  177.       {
  178.         if (_r[ix] == 255 && _g[ix] == 255 && _b[ix] == 255)
  179.           {
  180.             // swap colors
  181.             unsigned char tmp;
  182.             tmp = _r[1]; _r[1] = _r[ix]; _r[ix] = tmp;
  183.             tmp = _g[1]; _g[1] = _g[ix]; _g[ix] = tmp;
  184.             tmp = _b[1]; _b[1] = _b[ix]; _b[ix] = tmp;
  185.             for (lx = 0 ; lx < limit ; ++lx)
  186.               {
  187.                 if (_pixels[lx] == 1)
  188.                     _pixels[lx] = ix;
  189.                 else if (_pixels[lx] == ix)
  190.                     _pixels[lx] = 1;
  191.               }
  192.             break;                      // all done
  193.           }
  194.       }
  195.   }
  196.  
  197. //==================>>> imageIO::CreatePixels <<<====================
  198.   unsigned char* imageIO::CreatePixels(long size)
  199.   {
  200.     if (_pixels != 0)
  201.         delete [] _pixels;
  202.     _pixels = new unsigned char[size];
  203.     return _pixels;
  204.   }
  205.  
  206. //==================>>> imageIO::CreateColorMap <<<====================
  207.   void imageIO::CreateColorMap(int size)
  208.   {
  209.     // Create color map entries of given size
  210.     if (_r != 0)
  211.         delete [] _r;
  212.     if (_g == 0)
  213.         delete [] _g;
  214.     if (_b == 0)
  215.         delete [] _b;
  216.  
  217.     _r = new unsigned char[size];
  218.     _g = new unsigned char[size];
  219.     _b = new unsigned char[size];
  220.  
  221.     for (int ix = 0 ; ix < size ; ++ix)
  222.       {
  223.         _r[ix] = _g[ix] = _b[ix] = 0;
  224.       }
  225.   }
  226.  
  227. // The following methods are used to read various elements
  228. // of files. They are encapsulated so that the can be
  229. // replaced if needed with more explicit reading.
  230.  
  231. //==================>>> imageIO::RdLine <<<====================
  232.   int imageIO::RdLine(char* buff, ifstream& ifs)
  233.   {
  234.     // Read rest of current input line
  235.     ifs.getline(buff, 255);
  236.     return 1;
  237.   }
  238.  
  239. //==================>>> imageIO::RdStr <<<====================
  240.   int imageIO::RdStr(char* buff, ifstream& ifs)
  241.   {
  242.     // Read a single char token
  243.     ifs >> buff;
  244.     return 1;
  245.   }
  246.  
  247. //==================>>> imageIO::RdToEOL <<<====================
  248.   int imageIO::RdToEOL(char* buff, ifstream& ifs)
  249.   {
  250.     // Read remainder of line
  251.     ifs.getline(buff, 255);
  252.     return 1;
  253.   }
  254.  
  255. //==================>>> imageIO::RdIntComma <<<====================
  256.   int imageIO::RdIntComma(ifstream& ifs)
  257.   {
  258.     // Read an int plus trailing comma
  259.     int val;
  260.     char comma;
  261.     ifs >> val >> comma;
  262.     return val;
  263.   }
  264.  
  265. //==================>>> imageIO::RdInt <<<====================
  266.   int imageIO::RdInt(ifstream& ifs)
  267.   {
  268.     // Read an int
  269.     int val;
  270.     ifs >> val;
  271.     return val;
  272.   }
  273.  
  274. //==================>>> imageIO::ReadVBM <<<====================
  275.   int imageIO::ReadVBM(char* name)
  276.   {
  277.     // reads in a VBM file and parses
  278.     //-------------------- VBM file format for vbm8
  279.     //  //vbm8
  280.     //  #define select_depth 8
  281.     //  #define select_height 36
  282.     //  #define select_width 45
  283.     //  unsigned char select_bits[] = {
  284.     //  7,
  285.     //  255,255,255,
  286.     //  192,192,192,
  287.     //  64,0,255,
  288.     //  0,0,0,
  289.     //  128,128,128,
  290.     //  0,0,128,
  291.     //  255,0,128,
  292.     //  81,81,251,// begin bitmap
  293.     //  1,2, ... (pixels follow) ... };
  294.  
  295.     char buff[256];
  296.  
  297.     ifstream inFile(name);              // open the file to read
  298.  
  299.     if (!inFile)
  300.         return 0;              // OK?
  301.  
  302.     RdLine(buff,inFile);        // Read header line
  303.     char bits = buff[5];        // fetch bits position
  304.     buff[5] = 0;                // zap for strcmp
  305.     if (strcmp(buff,"//vbm") != 0) // valid header?
  306.       {
  307. NOT_VBM:
  308. #ifdef FailMsgs
  309.     vNoticeDialog note(theApp);
  310.     note.Notice("Unable to read: Not a valid VBM file.");
  311. #endif
  312.         inFile.close();
  313.         return 0;
  314.       }
  315.  
  316.     if (bits == '1')            // check for valid depth
  317.         _depth = 1;
  318.     else if (bits == '2')
  319.         _depth = 24;
  320.     else if (bits == '8')
  321.         _depth = 8;
  322.     else
  323.       {
  324.     goto NOT_VBM;
  325.       }
  326.  
  327.     for (int wh = 0 ; wh < 2 ; ++wh)
  328.       {
  329. GetWH:
  330.     RdStr(buff,inFile);         // #define
  331.     if (strcmp(buff,"#define") != 0)
  332.         goto NOT_VBM;
  333.  
  334.     RdStr(buff,inFile);         // xxx_height or xxx_width
  335.     if (strstr(buff,"width") == 0)
  336.       {
  337.         if (strstr(buff,"height") == 0)
  338.           {
  339.         // An upward compatible way to get depth
  340.         if (strstr(buff,"depth") == 0)
  341.             goto NOT_VBM;
  342.         else
  343.           {
  344.             _depth = RdInt(inFile);    // And the height
  345.             RdToEOL(buff, inFile);
  346.             goto GetWH;
  347.           }
  348.           }
  349.         else
  350.           {
  351.         _height = RdInt(inFile);    // And the height
  352.           }
  353.       }
  354.     else
  355.       {
  356.         _width = RdInt(inFile);        // And the width
  357.       }
  358.     RdToEOL(buff,inFile);        // Finish line
  359.       }
  360.     
  361.     if (_width > _maxW || _height > _maxH)
  362.       {
  363. #ifdef FailMsgs
  364.     vNoticeDialog note(theApp);
  365.     note.Notice("Sorry, icon exceeds maxmimum sizes allowed.");
  366. #endif
  367.     inFile.close();
  368.     return 0;
  369.       }
  370.  
  371.     RdLine(buff,inFile);        // the static unsigned line
  372.  
  373.     if (_depth == 8)            // read 8 bit mapped colors
  374.       {
  375.         CreateColorMap(256);
  376.  
  377.         _colors = RdIntComma(inFile) + 1;  // The number of colors
  378.  
  379.         // read all but last color in color map
  380.     int cx;
  381.         for (cx = 0 ; cx < (_colors - 1) ; ++cx)
  382.           {
  383.             _r[cx] = RdIntComma(inFile);
  384.             _g[cx] = RdIntComma(inFile);
  385.             _b[cx] = RdIntComma(inFile);
  386.           }
  387.         _r[cx] = RdIntComma(inFile);    // finish color map
  388.         _g[cx] = RdIntComma(inFile);
  389.         _b[cx] = RdInt(inFile); // last color followed by comment
  390.         RdToEOL(buff,inFile);   // Finish line
  391.  
  392.         // now ready to read pixels
  393.         long cells = _width * _height;
  394.  
  395.         if (_pixels != 0)               // make sure not read already
  396.             delete [] _pixels;
  397.  
  398.         _pixels = new unsigned char [cells]; // allocate memory
  399.  
  400.     long ix;
  401.         for (ix = 0 ; ix < (cells - 1) ; ++ix)
  402.             _pixels[ix] = RdIntComma(inFile);
  403.         _pixels[ix] = RdInt(inFile);
  404.         inFile.close();                     // finished with file
  405.         return 1;
  406.       }
  407.     else if (_depth == 1)
  408.       {
  409.     int res = RdRestOfXBM(inFile);
  410.         inFile.close();
  411.         return res;
  412.       }
  413.     else if (_depth == 24)
  414.       {
  415. #ifdef FailMsgs
  416.     vNoticeDialog note(theApp);
  417.     note.Notice("Sorry, can't read 24-bit VBM files.");
  418. #endif
  419.         inFile.close();
  420.         return 0;
  421.       }
  422.     goto NOT_VBM;
  423.   }
  424.  
  425. //==================>>> imageIO::WriteVBM <<<====================
  426.   int imageIO::WriteVBM(char* fname, char* iname)
  427.   {
  428.     // Write out the image save in the data structure
  429.  
  430.     if (!fname || !*fname)
  431.         return 0;               // must supply name
  432.  
  433.     if (_pixels == 0 || !_r || !_g || !_b)
  434.         return 0;
  435.  
  436.     ofstream ofs(fname);        // open the file
  437.  
  438.     if (!ofs)
  439.         return 0;               // check that was opened
  440.  
  441.     if (_depth == 1 || 
  442.     (_colors == 2 && 
  443.        (((_r[0] == 0 && _g[0] == 0 && _b[0] == 0) &&
  444.          (_r[1] == 255 && _g[1] == 255 && _b[1] == 255)) ||
  445.         ((_r[1] == 0 && _g[1] == 0 && _b[1] == 0) &&
  446.          (_r[0] == 255 && _g[0] == 255 && _b[0] == 255)))))
  447.       {
  448.         ofs << "//vbm1\n";
  449.     ofs << "#define " << iname << "_depth 1\n";
  450.     int res = WriteRestOfXBM(ofs, iname, 1);
  451.     ofs.close();
  452.     return res;
  453.       }
  454.     else if (_depth == 8)
  455.       {
  456.         ofs << "//vbm8\n";
  457.     ofs << "#define " << iname << "_depth 8\n";
  458.         ofs << "#define " << iname << "_width " << _width << "\n";
  459.         ofs << "#define " << iname << "_height " << _height << "\n";
  460.         ofs << "static unsigned char " << iname << "_bits[] = {\n";
  461.         ofs << (_colors - 1) << ",\n";
  462.         for (int ic = 0 ; ic < _colors ; ++ic)
  463.           {
  464.             ofs << (unsigned int)_r[ic] << "," << (unsigned int) _g[ic] <<
  465.                  "," << (unsigned int) _b[ic] << ",\n";
  466.           }
  467.         if (_width < 32)                // neat format if narrow
  468.           {
  469.             long px = 0;
  470.             for (int ir = 0 ; ir < _height ; ++ir)
  471.               {
  472.                 for (int ic = 0 ; ic < _width ; ++ic)
  473.                   {
  474.                     if (ic < (_width - 1))
  475.                         ofs << (unsigned int)_pixels[px++] << ",";
  476.                     else
  477.                         ofs << (unsigned int)_pixels[px++];
  478.                   }
  479.                 if ( ir < (_height - 1))
  480.                     ofs << ",\n";
  481.                 else
  482.                     ofs << "\n};\n";
  483.               }
  484.           }
  485.         else
  486.           {
  487.             long limit = _width * _height;
  488.         long lx;
  489.             for (lx = 0 ; lx < (limit - 1) ; )
  490.               {
  491.                 ofs << (unsigned int)_pixels[lx++] << ",";
  492.                 if ((lx % 32) == 0)
  493.                     ofs << "\n";
  494.               }
  495.             ofs << (unsigned int)_pixels[lx] << "\n};\n";
  496.           }
  497.         ofs.close();
  498.         return 1;
  499.       }
  500.     else if (_depth == 24)
  501.       {
  502.       }
  503.     ofs.close();
  504.     return 0;
  505.   }
  506.  
  507. //==================>>> imageIO::ReadXBM <<<====================
  508.   int imageIO::ReadXBM(char* name)
  509.   {
  510.     char buff[256];
  511.  
  512.     ifstream inFile(name);              // open the file to read
  513.  
  514.     if (!inFile)
  515.         return 0;        // OK?
  516.  
  517.     for (int wh = 0 ; wh < 2 ; ++wh)
  518.       {
  519.     RdStr(buff,inFile);         // #define
  520.     if (strcmp(buff,"#define") != 0)
  521.       {
  522. NOT_XBM:
  523. #ifdef FailMsgs
  524.         vNoticeDialog note(theApp);
  525.         note.Notice("Not a valid XBM file.");
  526. #endif
  527.         inFile.close();
  528.         return 0;
  529.       }
  530.  
  531.     RdStr(buff,inFile);         // xxx_height or xxx_width
  532.     if (strstr(buff,"width") == 0)
  533.       {
  534.         if (strstr(buff,"height") == 0)
  535.         goto NOT_XBM;
  536.         else
  537.           {
  538.         _height = RdInt(inFile);    // And the height
  539.           }
  540.       }
  541.     else
  542.       {
  543.         _width = RdInt(inFile);        // And the width
  544.       }
  545.     RdToEOL(buff,inFile);        // Finish line
  546.       }
  547.  
  548.     if (_width > _maxW || _height > _maxH)
  549.       {
  550. #ifdef FailMsgs
  551.     vNoticeDialog note(theApp);
  552.     note.Notice("Sorry, icon exceeds maxmimum sizes allowed.");
  553. #endif
  554.     inFile.close();
  555.     return 0;
  556.       }
  557.  
  558.     int res = RdRestOfXBM(inFile);
  559.     inFile.close();
  560.     return res;
  561.   }
  562.  
  563. //==================>>> imageIO::RdRestOfXBM <<<====================
  564.   int imageIO::RdRestOfXBM(ifstream& ifs)
  565.   {
  566.     int i, j, k, bit;
  567.     char hex[4];
  568.  
  569.     long cells = _width * _height;
  570.  
  571.     _depth = 1;
  572.     _colors = 2;
  573.     CreateColorMap(2);
  574.     _r[0] = _g[0] = _b[0] = 0;        // a b/w colormap
  575.     _r[1] = _g[1] = _b[1] = 255;
  576.  
  577.     CreatePixels(cells);
  578.  
  579.     unsigned char c, c1;
  580.  
  581.     // scan forward until we see the first '0x'
  582.  
  583.     ifs.get(c); ifs.get(c1);
  584.     while (!ifs.eof() && !(c=='0' && c1=='x') )
  585.       { 
  586.     c = c1;  ifs.get(c1);
  587.       }
  588.  
  589.     if (ifs.eof())
  590.     return 0;
  591.  
  592.     // simple checks
  593.     if (_width < 1 || _height < 1 || _width > 10000 || _height > 10000) 
  594.     return 0;
  595.  
  596.     k = 0;
  597.  
  598.     // read/convert the image data
  599.  
  600.     long pix = 0;
  601.     for (i = 0 ; i < _height; i++)
  602.       {
  603.     for (j = 0, bit = 0 ; j < _width ; j++, bit = (++bit)&7)
  604.       {
  605.  
  606.         if (!bit)
  607.           {
  608.         // get next byte from file.  we're already positioned at it
  609.         ifs.get(c); ifs.get(c1);
  610.         if (ifs.eof())
  611.             return 0;
  612.  
  613.         hex[0] = c; hex[1] = c1 ; hex[2] = 0;
  614.         k = Hex_to_Bin_Convert(hex);
  615.  
  616.         // advance to next '0x'
  617.         if (c != '}')
  618.           {
  619.             if (!ifs.eof())
  620.             ifs.get(c);
  621.             if (!ifs.eof())
  622.             ifs.get(c1);
  623.             while (!ifs.eof() && !(c=='0' && c1=='x') && c != '}' )
  624.               { 
  625.             c = c1;  ifs.get(c1);
  626.               }
  627.           }
  628.           }
  629.  
  630.         _pixels[pix++] = (unsigned char)((k&1) ? 0 : 1);
  631.         k = k >> 1;
  632.       }
  633.       }
  634.     return 1;
  635.   }
  636.  
  637. //==================>>> imageIO::WriteXBM <<<====================
  638.   int imageIO::WriteXBM(char* fname, char* iname)
  639.   {
  640.     // Write out the image save in the data structure
  641.  
  642.     if (!fname || !*fname)
  643.         return 0;               // must supply name
  644.  
  645.     if (_pixels == 0 || !_r || !_g || !_b)
  646.         return 0;
  647.  
  648.     ofstream ofs(fname);        // open the file
  649.  
  650.     if (!ofs)
  651.         return 0;               // check that was opened
  652.  
  653.     int res = WriteRestOfXBM(ofs, iname);
  654.     ofs.close();
  655.     return res;
  656.   }
  657.  
  658. //==================>>> imageIO::WriteRestOfXBM <<<====================
  659.   int imageIO::WriteRestOfXBM(ofstream& ofs, char* iname, int isVBM)
  660.   {
  661.  
  662.     int  i,j,k,bit,len,nbytes,flipbw;
  663.     long pix;
  664.     char buff[20];
  665.  
  666.     ofs << "#define " << iname << "_width " << _width << endl;
  667.     ofs << "#define " << iname << "_height " << _height << endl;
  668.     if (isVBM)
  669.     ofs << "static unsigned char " << iname << "_bits[] = {" << endl;
  670.     else
  671.     ofs << "static char " << iname << "_bits[] = {" << endl;
  672.  
  673.     ofs << " ";
  674.  
  675.     // set flipbw if color#0 is black
  676.     flipbw = (_r[0] == 0);    // 0 is Black
  677.  
  678.     nbytes = _height * ((_width+7)/8);   // # of bytes to write
  679.  
  680.     for (i=0, len=1, pix = 0 ; i < _height ; i++)
  681.       {
  682.     for (j = bit = k = 0 ; j < _width ; j++)
  683.       {
  684.         k = (k>>1);
  685.         if (_pixels[pix++])
  686.         k |= 0x80;
  687.         bit++;
  688.         if (bit == 8)
  689.           {
  690.         if (flipbw)
  691.             k = ~k;
  692.         ByteToStr(k&0xff,buff);
  693.         ofs << "0x" << (char)tolower(buff[0]) << (char) tolower(buff[1]) ;
  694.         nbytes--;  len += 4;
  695.         if (nbytes)
  696.           {
  697.             ofs << ","; len++;
  698.           }
  699.         if (len > 72) 
  700.           { 
  701.             ofs << endl << " ";
  702.             len = 1;
  703.           }
  704.         bit = k = 0;
  705.           }
  706.       }
  707.  
  708.     if (bit)
  709.       {
  710.         k = k >> (8-bit);
  711.         if (flipbw) 
  712.         k = ~k;
  713.         ByteToStr(k&0xff,buff);
  714.         ofs << "0x" << (char)tolower(buff[0]) << (char) tolower(buff[1]) ;
  715.         nbytes--;  len += 4;
  716.         if (nbytes) 
  717.           {
  718.         ofs << ",";  len++;  
  719.           }
  720.         if (len>72)
  721.           {
  722.         ofs << endl << " "; len = 1;
  723.           }
  724.       }
  725.       }
  726.  
  727.     ofs << "};" << endl;
  728.     return 1;
  729.   }
  730.  
  731. //==================>>> imageIO::ReadXPM <<<====================
  732.   int imageIO::ReadXPM(char* name)
  733.   {
  734.     char buff[256];
  735.     char ch;
  736.  
  737.     ifstream inFile(name);              // open the file to read
  738.  
  739.     if (!inFile)
  740.         return 0;              // OK?
  741.  
  742.     RdLine(buff,inFile);        // Read header line
  743.  
  744.     if (strstr(buff,"XPM") == 0)    // Must be XPM in first line
  745.     return 0;
  746.  
  747.     for ( ; ; )
  748.       {
  749.     if (!inFile.get(ch))        // read a char
  750.         break;
  751.     if (ch == '"')
  752.         break;
  753.       }
  754.  
  755.     // now ready to read size and colors
  756.     int levels;
  757.     char insets[256];
  758.     char r[3], g[3], b[3];
  759.     char pix;
  760.     int x,y;
  761.  
  762.     inFile >> _width >> _height >> _colors >> levels;
  763.     if (levels != 1)
  764.       {
  765. NOT_XPM:
  766.     inFile.close();
  767.     return 0;        // can't read anything else
  768.       }
  769.  
  770.     if (_width > _maxW || _height > _maxH)
  771.       {
  772. #ifdef FailMsgs
  773.     vNoticeDialog note(theApp);
  774.     note.Notice("Sorry, icon exceeds maxmimum sizes allowed.");
  775. #endif
  776.     inFile.close();
  777.     return 0;
  778.       }
  779.  
  780.     levels = 8;
  781.  
  782.     inFile.getline(buff, 255);    // clear rest of line
  783.  
  784.     CreateColorMap(256);    // allocate space for rgb
  785.  
  786.     // read in the color lists and convert from quad hex (only 2 per quad
  787.     // are needed to get color, other two are repeats in 8 bit mode) to
  788.     // 0-255 value for color palette.  Place in front of palette.
  789.  
  790.  
  791.     for (x = 0; x < _colors ; x++)
  792.       {
  793. skipIt:
  794.     inFile.getline(buff, 255);
  795.     if (buff[0] != '"')        // skip possible embedded comments
  796.         goto skipIt;
  797.     pix = buff[1];
  798.     insets[x] = pix;
  799.     int cx;
  800.     for (cx = 2 ; cx < 256 ; ++cx)
  801.         if (buff[cx] == '#')
  802.         break;
  803.     ++cx;            // point to first char after #
  804.     if (cx >= 256)
  805.         continue;
  806.  
  807.     if (buff[cx+6] == '"')    // short form hex values
  808.       {
  809.         r[0] = buff[cx];  r[1] = buff[cx+1];  r[2] = 0;
  810.         g[0] = buff[cx+2];  g[1] = buff[cx+3];  g[2] = 0;
  811.         b[0] = buff[cx+4];  b[1] = buff[cx+5];  b[2] = 0;
  812.       }
  813.     else            // long form of hex colors
  814.       {
  815.         r[0] = buff[cx];  r[1] = buff[cx+1];  r[2] = 0;
  816.         g[0] = buff[cx+4];  g[1] = buff[cx+5];  g[2] = 0;
  817.         b[0] = buff[cx+8];  b[1] = buff[cx+9];  b[2] = 0;
  818.       }
  819.     _r[x] = Hex_to_Bin_Convert(r);
  820.     _g[x] = Hex_to_Bin_Convert(g);
  821.     _b[x] = Hex_to_Bin_Convert(b);
  822.       }                     
  823.  
  824.     insets[_colors] = 0;
  825.  
  826.     // now ready to read pixels
  827.     long cells = _width * _height;
  828.  
  829.     if (_pixels != 0)               // make sure not read already
  830.     delete [] _pixels;
  831.  
  832.     _pixels = new unsigned char [cells]; // allocate memory
  833.  
  834.     long nextPix = 0;
  835.  
  836.     for (y = 0 ; y < _height ; ++y)
  837.       {
  838. skip_line:
  839.     RdLine(buff,inFile);
  840.     if (inFile.eof())
  841.         break;
  842.     if (buff[0] != '"')    // check for correct line
  843.         goto skip_line;
  844.     // got a row, insert int the pixel array
  845.     for (x = 0 ; x < _width ; ++x)
  846.       {
  847.         int px = buff[x+1];
  848.         int ix;
  849.         for (ix = 0 ; ix < _colors ; ++ix)
  850.           {
  851.         if (px == insets[ix])    // found it!
  852.             break;
  853.           }
  854.         if (ix >= _colors)
  855.         ix = 0;
  856.         _pixels[nextPix++] = ix;    // fill in the index
  857.       }
  858.       }
  859.     inFile.close();
  860.     return 1;
  861.   }
  862.  
  863. //==================>>> imageIO::WriteXPM <<<====================
  864.   int imageIO::WriteXPM(char* fname, char* iname)
  865.   {
  866.     // Write out the image save in the data structure
  867.  
  868.     int x, y;
  869.     char insets[] = "# abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWZYZ!@$%&'()*+,-./0123456789:;<=>?@[]^_`{|}~";
  870.     char buff[10];
  871.  
  872.     if (!fname || !*fname)
  873.         return 0;               // must supply name
  874.  
  875.     if (_pixels == 0 || !_r || !_g || !_b)
  876.         return 0;
  877.  
  878.     ofstream ofs(fname);        // open the file
  879.  
  880.     if (!ofs)
  881.         return 0;               // check that was opened
  882.  
  883.     // begin with headers, 
  884.  
  885.     ofs << "/* XPM */" << endl;
  886.     ofs << "static char *" << iname << "_xpm[] = {" << endl;
  887.     ofs << "\"" << _width << " " << _height;
  888.     ofs << " " << _colors << " 1\"," << endl;
  889.  
  890.     // now the color map - we will write the 16 bit form
  891.  
  892.     for (x = 0; x < _colors; x++)
  893.     {
  894.       ofs << "\"" << insets[x] << " c #";
  895.       ByteToStr(_r[x],buff);
  896.       ofs << buff << buff;
  897.       ByteToStr(_g[x],buff);
  898.       ofs << buff << buff;
  899.       ByteToStr(_b[x],buff);
  900.       ofs << buff << buff << "\"," << endl;
  901.     }
  902.  
  903.     // and finally the pixels
  904.  
  905.     long pix = 0;
  906.     for (y = 0; y < _height; y++)
  907.       {
  908.     ofs << "\"";
  909.  
  910.     for (x = 0 ; x < _width ; x++)
  911.       {
  912.         ofs << insets[_pixels[pix++]];
  913.       }
  914.     if (y == (_height - 1))        // last line?
  915.         ofs << "\"};";
  916.     else
  917.         ofs << "\",";
  918.     ofs << endl;
  919.       }
  920.  
  921.     // close file now
  922.  
  923.     ofs.close();                    // done with file
  924.     return 1;
  925.   }
  926.  
  927. //=============================>>> ByteToStr   <<<============================
  928.   void imageIO::ByteToStr(unsigned char intg, char* str)
  929.   {  // convert byte intg to char string in str
  930.  
  931.     int i;
  932.     int d, intval, j;
  933.     char k;
  934.     static char digits[] = "0123456789ABCDEF";
  935.  
  936.     intval = intg;
  937.     str[0] = '\0';
  938.     i = 0;
  939.     do
  940.       {                // generate digits
  941.         i++;
  942.         d = intval % 16;    // mod 10
  943.         str[i] = digits[d];
  944.         intval = intval / 16;
  945.       }
  946.     while (intval != 0);
  947.  
  948.     for (j = 0 ; j < i ; j++ )
  949.       {                // then reverse
  950.         k = str[i];
  951.         str[i--] = str[j];
  952.         str[j] = k;
  953.       }
  954.     if (str[1] == 0)        // one char only
  955.       {
  956.     str[1] = str[0]; str[2] = 0; str[0] = '0';
  957.       }
  958.   }
  959.  
  960. //==================>>> myCanvasPane::Hex_to_Bin <<<===================
  961.   int imageIO::Hex_to_Bin(char digit)
  962.   {
  963.     // note - need to add the tolower function to ensure hex char is lowercase
  964.  
  965.     char *hex_code = "fedcba9876543210";
  966.  
  967.     digit = tolower((int)digit);
  968.     return strlen(strchr(hex_code, digit)) - 1;
  969.   }
  970.  
  971. //==================>>> myCanvasPane::Hex_to_Bin_Convert <<<===========
  972.   int imageIO::Hex_to_Bin_Convert(char * hexnumber)
  973.   {
  974.     // convert from hexadecimal to binary
  975.  
  976.     int return_val;
  977.  
  978.     return_val = Hex_to_Bin(hexnumber[0]);
  979.     return_val = return_val * 16;
  980.     return_val = return_val + Hex_to_Bin(hexnumber[1]);
  981.  
  982.     return return_val;
  983.   }
  984.  
  985. //***************************************************************
  986. // Defines for BMP files
  987.  
  988. #define BI_RGB  0
  989. #define BI_RLE8 1
  990. #define BI_RLE4 2
  991.  
  992. #define WIN 40
  993. #define OS2 64
  994. //==================>>> imageIO::ReadBMP <<<====================
  995.   int imageIO::ReadBMP(char* name)
  996.   {
  997.     ifstream inFile(name);              // open the file to read
  998.  
  999.     if (!inFile)
  1000.         return 0;              // OK?
  1001.  
  1002.     // Read MSDOS, OS/2 bmp files into internal format
  1003.  
  1004.     unsigned char c, c1;
  1005.     int          i, rv;
  1006.     unsigned int bfSize, bfOffBits, Size, Width, Height, Planes;
  1007.     unsigned int BitCount, Compression, SizeImage, XPelsPerMeter;
  1008.     unsigned int YPelsPerMeter, ClrUsed, ClrImportant;
  1009.     int bPad;
  1010.  
  1011.     // First two bytes must be "BM"
  1012.  
  1013.     inFile.get(c);  inFile.get(c1);
  1014.     if (c !='B' || c1 != 'M')        // anything not BM fails
  1015.       {
  1016. NOT_BMP:
  1017. #ifdef FailMsgs
  1018.     vNoticeDialog note(theApp);
  1019.     note.Notice("Sorry, can't read this BMP file.");
  1020. #endif
  1021.     inFile.close();
  1022.     return 0;
  1023.       }
  1024.  
  1025.     bfSize = rdInt32(inFile);
  1026.     rdInt16(inFile);                 // reserved: ignore
  1027.     rdInt16(inFile);
  1028.     bfOffBits = rdInt32(inFile);
  1029.  
  1030.     Size = rdInt32(inFile);
  1031.  
  1032.     if (Size == WIN || Size == OS2)  // read header info
  1033.       {
  1034.     Width         = rdInt32(inFile);
  1035.     Height        = rdInt32(inFile);
  1036.     Planes        = rdInt16(inFile);
  1037.     BitCount      = rdInt16(inFile);
  1038.     Compression   = rdInt32(inFile);
  1039.     SizeImage     = rdInt32(inFile);
  1040.     XPelsPerMeter = rdInt32(inFile);
  1041.     YPelsPerMeter = rdInt32(inFile);
  1042.     ClrUsed       = rdInt32(inFile);
  1043.     ClrImportant  = rdInt32(inFile);
  1044.       }
  1045.     else
  1046.     goto NOT_BMP;            // old format, we won't handle!
  1047.  
  1048.     if (Width > _maxW || Height > _maxH)
  1049.       {
  1050. #ifdef FailMsgs
  1051.     vNoticeDialog note(theApp);
  1052.     note.Notice("Sorry, icon exceeds maxmimum sizes allowed.");
  1053. #endif
  1054.     inFile.close();
  1055.     return 0;
  1056.       }
  1057.  
  1058.     // Check to see if things are as they should be
  1059.  
  1060.     if (inFile.eof())
  1061.     goto NOT_BMP;
  1062.  
  1063.     if ((BitCount!=1 && BitCount!=4 && BitCount!=8 && BitCount!=24) || 
  1064.       Planes!=1 || Compression > BI_RLE4)
  1065.     goto NOT_BMP;
  1066.  
  1067.     if (((BitCount==1 || BitCount==24) && Compression != BI_RGB) ||
  1068.     Compression != BI_RGB)    // only uncompressed for now
  1069.     goto NOT_BMP;
  1070.  
  1071.     // Skip to color map
  1072.     c = Size - 40;    // 40 bytes read from Size to ClrImportant
  1073.     for (i=0; i<c; i++)
  1074.     inFile.get(c);
  1075.     
  1076.     bPad = bfOffBits - (Size + 14);    // padding after color map
  1077.  
  1078.     // Now, set stuff
  1079.  
  1080.     if (BitCount != 24)        // colormap for 1 or 4 or 8
  1081.       {
  1082.     _colors = (ClrUsed) ? ClrUsed : 1 << BitCount;
  1083.     _height = Height;
  1084.     _width = Width;
  1085.     _depth = 8;
  1086.     CreateColorMap(_colors);  // allocate space for rgb
  1087.  
  1088.     // read the color map
  1089.     unsigned char r,g,b;
  1090.     for (i=0; i<_colors; i++)
  1091.       {
  1092.         inFile.get(b);
  1093.         inFile.get(g);
  1094.         inFile.get(r);
  1095.         inFile.get(c);
  1096.         bPad -= 4;            // we just read 4 bytes
  1097.         _r[i] = r; _g[i] = g; _b[i] = b;
  1098.       }
  1099.       }
  1100.     else                // 24 bit bmp
  1101.       {
  1102.     goto NOT_BMP;
  1103.       }
  1104.  
  1105.     if (inFile.eof())        // something is amiss
  1106.     goto NOT_BMP;
  1107.  
  1108.     // Now, skip over any unused bytes between the color map (if there
  1109.     // was one, and the start of the bitmap data.
  1110.     
  1111.     while (bPad > 0)
  1112.       {
  1113.     inFile.get(c);
  1114.     bPad--;
  1115.       }
  1116.  
  1117.     // Now, read rest of file and write out an 8 or 24 bit v icon def
  1118.  
  1119.     long limit = (BitCount == 24) ? Width*Height*3 : Width*Height;
  1120.  
  1121.     unsigned char* rev = new unsigned char[limit];
  1122.  
  1123.     if (BitCount == 1)
  1124.     rv = rdBMP1(inFile,rev,Width,Height);
  1125.     else if (BitCount == 4)
  1126.     rv = rdBMP4(inFile,rev,Width,Height,Compression);
  1127.     else if (BitCount == 8)
  1128.     rv = rdBMP8(inFile,rev,Width,Height, Compression);
  1129.     else
  1130.     goto NOT_BMP;
  1131. //    rv = rdBMP24(inFile,rev,Width,Height);
  1132.  
  1133.     if (rv == 0)
  1134.     goto NOT_BMP;
  1135.  
  1136.     // have to reverse the bitmap's row order
  1137.  
  1138.     long rowLen = (BitCount == 24) ? Width*3 : Width;
  1139.  
  1140.     long px = 0;
  1141.     CreatePixels(limit);
  1142.     
  1143.     for (long ix = limit - rowLen ; ix >= 0 ; ix -= rowLen)
  1144.       {
  1145.     // copy one row
  1146.     for (long ri = 0 ; ri < rowLen ; ++ri)
  1147.       {
  1148.         _pixels[px++] = rev[ix+ri];
  1149.       }
  1150.       }
  1151.  
  1152.     delete rev;
  1153.  
  1154.     return 1;
  1155.   }
  1156.  
  1157. //=========================>> rdBMP1 <<=============================
  1158.   int imageIO::rdBMP1(ifstream& fileIn, unsigned char* rev,
  1159.     unsigned int w, unsigned int h)
  1160.   {
  1161.     unsigned char c;
  1162.     int i,j,bitnum,padw;
  1163.  
  1164.     c = 0;
  1165.     padw = ((w + 31)/32) * 32;  /* 'w', padded to be a multiple of 32 */
  1166.  
  1167.     for (i=h-1; i>=0; i--)
  1168.       {
  1169.     for (j=bitnum=0; j<padw; j++,bitnum++)
  1170.       {
  1171.         if ((bitnum&7) == 0)
  1172.           { /* read the next byte */
  1173.         fileIn.get(c);
  1174.         bitnum = 0;
  1175.           }
  1176.       
  1177.         if (j<w)
  1178.           {
  1179.         *rev++ = (c & 0x80) ? 1 : 0;
  1180.         c <<= 1;
  1181.           }
  1182.       }
  1183.  
  1184.     if (fileIn.eof())    // something is amiss
  1185.         return 0;            // so fail
  1186.       }
  1187.  
  1188.     if (fileIn.eof())    // something is amiss
  1189.     return 0;            // so fail
  1190.     return 1;
  1191.   }  
  1192.  
  1193. //=========================>> rdBMP4 <<=============================
  1194.   int imageIO::rdBMP4(ifstream& fileIn, unsigned char*rev,
  1195.             unsigned int w, unsigned int h, unsigned int comp)
  1196.   {
  1197.     unsigned char c, c1;
  1198.     int   i,j,nybnum,padw,rv;
  1199.  
  1200.     rv = 1;
  1201.     c = c1 = 0;
  1202.  
  1203.     if (comp == BI_RGB)            // read uncompressed data
  1204.       {
  1205.     padw = ((w + 7)/8) * 8;     // 'w' padded to a multiple of 8pix (32 bits)
  1206.  
  1207.     for (i=h-1; i>=0; i--)
  1208.       {
  1209.         for (j=nybnum=0; j<padw; j++,nybnum++)
  1210.           {
  1211.         if ((nybnum & 1) == 0)    // read next byte
  1212.           { /* read next byte */
  1213.             fileIn.get(c);
  1214.             nybnum = 0;
  1215.           }
  1216.  
  1217.         if (j<w)
  1218.           {
  1219.             *rev++ = (c & 0xf0) >> 4;
  1220.             c <<= 4;
  1221.           }
  1222.         if (fileIn.eof())    // something is amiss
  1223.             return 0;            // so fail
  1224.           }
  1225.       }
  1226.       }
  1227.     else
  1228.     return 0;
  1229.  
  1230.     if (fileIn.eof())    // something is amiss
  1231.     return 0;            // so fail
  1232.     return rv;
  1233.   }
  1234.  
  1235. //=========================>> rdBMP8 <<=============================
  1236.   int imageIO::rdBMP8(ifstream& fileIn, unsigned char* rev,
  1237.             unsigned int w, unsigned int h, unsigned int comp)
  1238.   {
  1239.     unsigned char c;
  1240.     int   i,j,padw,rv;
  1241.  
  1242.     rv = 1;
  1243.  
  1244.     if (comp == BI_RGB)        // read uncompressed data
  1245.       {
  1246.     padw = ((w + 3)/4) * 4; /* 'w' padded to a multiple of 4pix (32 bits) */
  1247.  
  1248.     for (i=h-1; i>=0; i--) 
  1249.       {
  1250.         for (j=0; j<padw; j++) 
  1251.           {
  1252.         fileIn.get(c);
  1253.         if (fileIn.eof())
  1254.             rv = 1;
  1255.         if (j<w)
  1256.           {
  1257.             *rev++ = c;
  1258.           }
  1259.         if (fileIn.eof())
  1260.             return 0;            // so fail
  1261.           }
  1262.       }
  1263.       }
  1264.     else 
  1265.     return 0;
  1266.  
  1267.     if (fileIn.eof())
  1268.     return 0;            // so fail
  1269.     return rv;
  1270.   }
  1271.  
  1272. //========================>>> imageIO::putint <<<===========================
  1273.   void imageIO::putint(ofstream& fp, int i)
  1274.   {
  1275.     unsigned char c, c1, c2, c3;
  1276.  
  1277.     c  = ((unsigned int ) i)      & 0xff;  
  1278.     c1 = (((unsigned int) i)>>8)  & 0xff;
  1279.     c2 = (((unsigned int) i)>>16) & 0xff;
  1280.     c3 = (((unsigned int) i)>>24) & 0xff;
  1281.     fp.put(c); fp.put(c1); fp.put(c2); fp.put(c3);
  1282.   }
  1283.  
  1284. //========================>>> imageIO::putshort <<<===========================
  1285.   void imageIO::putshort(ofstream& fp, int i)
  1286.   {
  1287.     unsigned char c, c1;
  1288.  
  1289.     c  = ((unsigned int ) i)      & 0xff;  
  1290.     c1 = (((unsigned int) i)>>8)  & 0xff;
  1291.     fp.put(c); fp.put(c1);
  1292.   }
  1293.  
  1294. //========================>>> imageIO::WriteBMP <<<===========================
  1295.   int imageIO::WriteBMP(char* fname, char* iname)
  1296.   {
  1297.     int i, j, nbits, bperlin, padw;
  1298.     unsigned char *pp;
  1299.  
  1300.     if (!fname || !*fname)
  1301.         return 0;        // must supply name
  1302.  
  1303.     if (_pixels == 0 || !_r || !_g || !_b)
  1304.         return 0;
  1305.  
  1306.     ofstream fp(fname);    // open the file
  1307.  
  1308.     if (!fp)
  1309.         return 0;    // check that was opened 
  1310.  
  1311.     nbits = 8;
  1312.  
  1313.     bperlin = ((_width * nbits + 31) / 32) * 4;   /* # bytes written per line */
  1314.  
  1315.     fp << "BM";            // BMP file id
  1316.  
  1317.     /* compute filesize and write it */
  1318.     i = 14 +            /* size of bitmap file header */
  1319.     40 +            /* size of bitmap info header */
  1320.     (_colors * 4) +        /* size of colormap */
  1321.     bperlin * _height;    /* size of image data */
  1322.  
  1323.     putint(fp, i);
  1324.     putshort(fp, 0);        /* reserved1 */
  1325.     putshort(fp, 0);        /* reserved2 */
  1326.     putint(fp, 14 + 40 + (_colors * 4));  /* offset from BOfile to BObitmap */
  1327.  
  1328.     putint(fp, 40);        /* biSize: size of bitmap info header */
  1329.     putint(fp, _width);        /* biWidth */
  1330.     putint(fp, _height);    /* biHeight */
  1331.     putshort(fp, 1);        /* biPlanes:  must be '1' */
  1332.     putshort(fp, nbits);    /* biBitCount: 1,4,8, or 24 */
  1333.     putint(fp, BI_RGB);        /* biCompression:  BI_RGB, BI_RLE8 or BI_RLE4 */
  1334.     putint(fp, bperlin*_height); /* biSizeImage:  size of raw image data */
  1335.     putint(fp, 75 * 39);    /* biXPelsPerMeter: (75dpi * 39" per meter) */
  1336.     putint(fp, 75 * 39);    /* biYPelsPerMeter: (75dpi * 39" per meter) */
  1337.     putint(fp, _colors);    /* biClrUsed: # of colors used in cmap */
  1338.     putint(fp, _colors);    /* biClrImportant: same as above */
  1339.  
  1340.     /* write out the colormap */
  1341.     for (i=0; i<_colors; i++) 
  1342.       {
  1343.     fp.put(_b[i]);
  1344.     fp.put(_g[i]);
  1345.     fp.put(_r[i]);
  1346.     fp.put((unsigned char)0);
  1347.       }
  1348.  
  1349.     // now write out the image
  1350.  
  1351.     padw = ((_width + 3)/4) * 4; /* 'w' padded to a multiple of 4pix (32 bits) */
  1352.  
  1353.     for ( i = _height - 1 ; i >= 0 ; i--)
  1354.       {
  1355.     pp = _pixels + (i * _width);
  1356.  
  1357.     for (j = 0 ; j < _width ; j++)
  1358.         fp.put(*pp++);
  1359.     for ( ; j < padw ; j++) 
  1360.         fp.put((unsigned char)0);
  1361.       }
  1362.  
  1363.     fp.close();
  1364.     return 1;
  1365.   }
  1366.  
  1367. //=============================>>> rdInt16 <<<=============================
  1368.   unsigned int imageIO::rdInt16(ifstream& fileIn)
  1369.   {
  1370.     unsigned char c, c1;
  1371.     fileIn.get(c);  fileIn.get(c1);
  1372.     return ((unsigned int) c) + (((unsigned int) c1) << 8);
  1373.   }
  1374.  
  1375. //=============================>>> rdInt32 <<<=============================
  1376.   unsigned int imageIO::rdInt32(ifstream& fileIn)
  1377.   {
  1378.     unsigned char c, c1, c2, c3;
  1379.     fileIn.get(c);  fileIn.get(c1);
  1380.     fileIn.get(c2);  fileIn.get(c3);
  1381.     return ((unsigned int) c) +
  1382.          (((unsigned int) c1) << 8) + 
  1383.      (((unsigned int) c2) << 16) +
  1384.      (((unsigned int) c3) << 24);
  1385.   }
  1386.