libcvd-members
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libcvd-members] libcvd cvd/image_io.h cvd/internal/load_and_sav...


From: Edward Rosten
Subject: [libcvd-members] libcvd cvd/image_io.h cvd/internal/load_and_sav...
Date: Tue, 05 Aug 2008 02:12:46 +0000

CVSROOT:        /cvsroot/libcvd
Module name:    libcvd
Changes by:     Edward Rosten <edrosten>        08/08/05 02:12:46

Modified files:
        cvd            : image_io.h 
        cvd/internal   : load_and_save.h 
        cvd/internal/io: tiff.h 
        cvd_src        : image_io.cc 
        pnm_src        : tiffwrite.cc 
        test           : test_images.cxx 

Log message:
        TIFF I/O almost works. It compiles cleanly, but there is an error with 
the 
        TIFF data writing module. Substituting tiffstream works, so the rest of
        the system works correctly.
        
        -Ed

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/libcvd/cvd/image_io.h?cvsroot=libcvd&r1=1.34&r2=1.35
http://cvs.savannah.gnu.org/viewcvs/libcvd/cvd/internal/load_and_save.h?cvsroot=libcvd&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/libcvd/cvd/internal/io/tiff.h?cvsroot=libcvd&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/libcvd/cvd_src/image_io.cc?cvsroot=libcvd&r1=1.27&r2=1.28
http://cvs.savannah.gnu.org/viewcvs/libcvd/pnm_src/tiffwrite.cc?cvsroot=libcvd&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/libcvd/test/test_images.cxx?cvsroot=libcvd&r1=1.10&r2=1.11

Patches:
Index: cvd/image_io.h
===================================================================
RCS file: /cvsroot/libcvd/libcvd/cvd/image_io.h,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -b -r1.34 -r1.35
--- cvd/image_io.h      28 Feb 2008 00:27:21 -0000      1.34
+++ cvd/image_io.h      5 Aug 2008 02:12:45 -0000       1.35
@@ -78,6 +78,9 @@
                        #ifdef CVD_HAVE_PNG
                                PNG=5,
                        #endif
+                       #ifdef CVD_HAVE_TIFF
+                               TIFF=6,
+                       #endif
                };
        }
 
@@ -132,9 +135,13 @@
                        JPEG,
                        /// Windows BMP (or DIB) format. Uncompressed 8 bit 
grey scale and 24 bit RGB are supported.
                        BMP,
-                       /// PNG imager format. 1, 8 and 16 bit, Greyscale, RGB 
and RGBA images are supported.
+                       /// PNG image format. 1, 8 and 16 bit, Greyscale, RGB 
and RGBA images are supported.
                        /// This image type is only present if libpng is 
available.
                        PNG,
+                       /// TIFF image format. 1, 8, 16, 32 (float) and 64 
(double) suported. Greyscale, RGB and RGBA supported.
+                       /// This image type is only present if libtiff is 
available. G4 FAX encoding is used for bools, otherwise
+                       /// "Deflate" compression is used.
+                       TIFF,
                        /// Postscript  format. This outputs a bare PostScript 
image with the coordinate system set up 
                        /// to that (x,y) corresponds to pixel (x,y), with 
(0,0) being at the top left of the pixel (0,0).
                        /// The Y axis is therefore inverted compared to normal 
postscript drawing, but is image aligned.
@@ -264,6 +271,7 @@
        void img_save(const BasicImage<PixelType>& im, std::ostream& o, 
ImageType::ImageType t)
        {
          switch (t) {
+         default:
          case ImageType::PNM:  
          case ImageType::Automatic:
          case ImageType::Unknown:
@@ -274,6 +282,9 @@
          #ifdef CVD_HAVE_PNG
                  case ImageType::PNG: PNG::writePNG(im,o); break;
          #endif
+         #ifdef CVD_HAVE_TIFF
+                 case ImageType::TIFF: Internal::writeImage<PixelType, 
TIFF::tiff_writer>(im,o); break;
+         #endif
          case ImageType::PS:   PS::writePS(im, o);  break;
          case ImageType::EPS:  PS::writeEPS(im,o);  break;
          case ImageType::BMP:  BMP::writeBMP(im,o);  break;

Index: cvd/internal/load_and_save.h
===================================================================
RCS file: /cvsroot/libcvd/libcvd/cvd/internal/load_and_save.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- cvd/internal/load_and_save.h        4 Aug 2008 23:50:06 -0000       1.12
+++ cvd/internal/load_and_save.h        5 Aug 2008 02:12:45 -0000       1.13
@@ -273,7 +273,7 @@
                //
                // Select an outgoing type, convert if necessary and then save.
                //
-               template<class Pixel, class ImageWriter, class OutgoingPixel> 
class maybe_process_and_write
+               template<class Pixel, class ImageWriter, class OutgoingPixel> 
struct maybe_process_and_write
                {       
                        static void write(std::ostream& os, const 
SubImage<Pixel>& im)
                        {
@@ -288,7 +288,7 @@
                        }
                };
 
-               template<class Pixel, class ImageWriter> class 
maybe_process_and_write<Pixel, ImageWriter, Pixel>
+               template<class Pixel, class ImageWriter> struct 
maybe_process_and_write<Pixel, ImageWriter, Pixel>
                {       
                        static void write(std::ostream& os, const 
SubImage<Pixel>& im)
                        {
@@ -300,7 +300,7 @@
 
                template<class Pixel, class Writer> void writeImage(const 
SubImage<Pixel>& im, std::ostream& o)
                {
-                       maybe_process_and_write<Pixel, Writer, typename 
Writer::template Outgoing<Pixel>::type>(im, o);
+                       maybe_process_and_write<Pixel, Writer, typename 
Writer::template Outgoing<Pixel>::type>::write(o, im);
                }
 
        

Index: cvd/internal/io/tiff.h
===================================================================
RCS file: /cvsroot/libcvd/libcvd/cvd/internal/io/tiff.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- cvd/internal/io/tiff.h      4 Aug 2008 23:50:06 -0000       1.6
+++ cvd/internal/io/tiff.h      5 Aug 2008 02:12:45 -0000       1.7
@@ -110,9 +110,9 @@
        //The range is encoded un unary notation. The range is on some integer, 
x.
        //g1 is set if x > 1. g8 is set if x > 8 and so on.
        //This allows us to choose a type with a reasonable number of bits.
-       template<int g1, int g8> class IntMapper    { typedef unsigned short 
type;};
-       template<>               class IntMapper<1, 0> { typedef unsigned char 
type; };
-       template<>               class IntMapper<0, 0> { typedef unsigned char 
type; };
+       template<int g1, int g8> struct IntMapper    { typedef unsigned short 
type;};
+       template<>               struct IntMapper<1, 0> { typedef unsigned char 
type; };
+       template<>               struct IntMapper<0, 0> { typedef unsigned char 
type; };
 
 
        //Mapping for integral types
@@ -130,18 +130,23 @@
        
        template<class ComponentIn> struct ComponentMapper
        {
-               typedef typename ComponentMapper_<ComponentIn, 
Pixel::traits<ComponentIn>::is_integral>::type type;
+               typedef typename ComponentMapper_<ComponentIn, 
Pixel::traits<ComponentIn>::integral>::type type;
        };
        
        //Mapping for Rgbish types
        template<class ComponentIn> struct ComponentMapper<Rgb<ComponentIn> >
        {
-               typedef Rgb<typename ComponentMapper_<ComponentIn, 
Pixel::traits<ComponentIn>::is_integral>::type> type;
+               typedef Rgb<typename ComponentMapper_<ComponentIn, 
Pixel::traits<ComponentIn>::integral>::type> type;
        };
 
        template<class ComponentIn> struct ComponentMapper<Rgba<ComponentIn> >
        {
-               typedef Rgba<typename ComponentMapper_<ComponentIn, 
Pixel::traits<ComponentIn>::is_integral>::type> type;
+               typedef Rgba<typename ComponentMapper_<ComponentIn, 
Pixel::traits<ComponentIn>::integral>::type> type;
+       };
+
+       template<> struct ComponentMapper<Rgb8>
+       {
+               typedef Rgb<byte> type;
        };
 
 

Index: cvd_src/image_io.cc
===================================================================
RCS file: /cvsroot/libcvd/libcvd/cvd_src/image_io.cc,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -b -r1.27 -r1.28
--- cvd_src/image_io.cc 4 Aug 2008 23:50:07 -0000       1.27
+++ cvd_src/image_io.cc 5 Aug 2008 02:12:46 -0000       1.28
@@ -121,6 +121,10 @@
        else if (suffix == "png") 
                 return  ImageType::PNG;
 #endif
+#ifdef CVD_HAVE_TIFF
+       else if (suffix == "tif" || suffix == "tiff")
+                return  ImageType::TIFF;
+#endif
        else if (suffix == "eps")
                return  ImageType::EPS;
        else if (suffix == "bmp") 

Index: pnm_src/tiffwrite.cc
===================================================================
RCS file: /cvsroot/libcvd/libcvd/pnm_src/tiffwrite.cc,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- pnm_src/tiffwrite.cc        4 Aug 2008 23:50:26 -0000       1.1
+++ pnm_src/tiffwrite.cc        5 Aug 2008 02:12:46 -0000       1.2
@@ -70,8 +70,9 @@
 tsize_t TIFFWritePimpl::write(thandle_t vis, tdata_t data, tsize_t count)
 {
        TIFFWritePimpl* o = (TIFFWritePimpl*)vis;
-       o->o.write((char*)data, count);
-       return o->o.tellp();
+       streamoff p = o->o.tellp();
+       o->o.write((const char*)data, count);
+       return o->o.tellp() - p;
 }
 
 tsize_t TIFFWritePimpl::read(thandle_t, tdata_t, tsize_t)
@@ -99,8 +100,10 @@
        return ii->length;
 }
 
-int TIFFWritePimpl::close(thandle_t)
+int TIFFWritePimpl::close(thandle_t vis)
 {
+       TIFFWritePimpl* o = (TIFFWritePimpl*)vis;
+       o->o << flush;
        return 0;
 }
 
@@ -198,6 +201,7 @@
        TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
        TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
 
+       uint16 alpha[] = {EXTRASAMPLE_UNASSALPHA};
        if(t == "bool")
        {
                TIFFSetField(tif, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
@@ -273,7 +277,7 @@
                TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
                TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 4);
                TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
-               TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, EXTRASAMPLE_UNASSALPHA);
+               TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, 1, alpha);
        }
        else if(t == "CVD::Rgba<unsigned short>")
        {
@@ -281,7 +285,7 @@
                TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
                TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 4);
                TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
-               TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, EXTRASAMPLE_UNASSALPHA);
+               TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, 1, alpha);
        }
        else if(t == "CVD::Rgba<float>")
        {
@@ -290,7 +294,7 @@
                TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 4);
                TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32);
                TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
-               TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, EXTRASAMPLE_UNASSALPHA);
+               TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, 1, alpha);
        }
        else if(t == "CVD::Rgba<double>")
        {
@@ -299,7 +303,7 @@
                TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 4);
                TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 64);
                TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
-               TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, EXTRASAMPLE_UNASSALPHA);
+               TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, 1,  alpha);
        }
        else
                throw UnsupportedImageSubType("TIFF", t);

Index: test/test_images.cxx
===================================================================
RCS file: /cvsroot/libcvd/libcvd/test/test_images.cxx,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- test/test_images.cxx        2 Aug 2008 01:32:39 -0000       1.10
+++ test/test_images.cxx        5 Aug 2008 02:12:46 -0000       1.11
@@ -20,7 +20,11 @@
 */
 #include <iostream>
 #include <fstream>
+#include <sstream>
 #include <string>
+#include <cstdlib>
+#include <limits>
+#include <algorithm>
 
 
 #include <cvd/image_io.h>
@@ -28,6 +32,48 @@
 using namespace std;
 using namespace CVD;
 
+using CVD::Internal::TypeList;
+using CVD::Internal::Head;
+
+template<class C> struct randpix
+{
+       static C r()
+       {
+               return rand() % (1+numeric_limits<C>::max());
+       }
+};
+
+template<> struct randpix<double>
+{
+       static double r()
+       {
+               return rand() * 1./RAND_MAX;
+       }
+};
+
+template<> struct randpix<float>
+{
+       static float r()
+       {
+               return rand() * 1./RAND_MAX;
+       }
+};
+
+template<class C> struct randpix<Rgb<C> >
+{
+       static Rgb<C> r()
+       {
+               return Rgb<C>(randpix<C>::r(), randpix<C>::r(),randpix<C>::r());
+       }
+};
+
+template<class C> struct randpix<Rgba<C> >
+{
+       static Rgba<C> r()
+       {
+               return Rgba<C>(randpix<C>::r(), 
randpix<C>::r(),randpix<C>::r(), randpix<C>::r());
+       }
+};
 
 template<class T> string make_output_file_name(string fin, string type)
 {
@@ -82,6 +128,20 @@
                img_save(im, o, ImageType::JPEG);
                o.close();
        #endif
+       #ifdef CVD_IMAGE_HAVE_PNG
+               fout=make_output_file_name<T>(fin, "png");
+               cout << "Writing: " << fout << endl << endl;
+               o.open(fout.c_str());
+               img_save(im, o, ImageType::PNG);
+               o.close();
+       #endif
+       #ifdef CVD_IMAGE_HAVE_TIFF
+               fout=make_output_file_name<T>(fin, "tiff");
+               cout << "Writing: " << fout << endl << endl;
+               o.open(fout.c_str());
+               img_save(im, o, ImageType::TIFF);
+               o.close();
+       #endif
 }
 
 template<class T> void loadsave_safe(const char*n)
@@ -96,17 +156,81 @@
        }
 }
 
+template<class T> struct randtest
+{
+       typedef typename T::Type Type;
+
+       static void exec(ImageType::ImageType fmt)
+       {       
+               try{
+                       //Make a random image
+                       Image<Type> in(ImageRef(2,2)), out;
 
+                       for(int y=0; y < in.size().y; y++)
+                               for(int x=0; x < in.size().x; x++)
+                                       in[y][x] = randpix<Type>::r();
 
+                       stringstream s;
 
-int main(int ac, char** av)
-{
-       if(ac < 2)
+                       //Save the image
+                       img_save(in, s, fmt);
+
+                       s.seekg(0, ios_base::beg);
+                       s.seekp(0, ios_base::beg);
+                       
+                       //Load the image
+                       out = img_load(s);
+
+                       //Compare the results
+                       if(out.size() != in.size())
+                               cerr << "Image R/W test for type " << fmt << " 
" << CVD::PNM::type_name<Type>::name() << " size mismatch.\n";
+                       else if(!equal(in.begin(), in.end(), out.begin()))
+                       {
+                               cerr << "Image R/W test for type " << fmt << " 
" << CVD::PNM::type_name<Type>::name() << " data mismatch.\n";
+
+                               typedef typename Pixel::Component<Type>::type  
Ct;
+                               double t=0, minval = HUGE_VAL, maxval=-HUGE_VAL;
+                               for(int y=0; y < in.size().y; y++)
+                                       for(int x=0; x < in.size().x; x++)
+                                               for(unsigned int c=0; c < 
Pixel::Component<Type>::count; c++)
+                                               {
+                                                       Ct p = 
Pixel::Component<Type>::get(in[y][x], c);
+                                                       Ct p2 = 
Pixel::Component<Type>::get(out[y][x], c);
+                                                       t += abs((double)p -  
(double)p2);
+
+                                                       maxval = max(maxval, 
(double)p);
+                                                       minval = min(minval, 
(double)p);
+
+                                                       cerr << p << " " << p2 
<< endl;
+
+                                               }
+
+                               cerr << "Mismatch is " << 100* t * 1.0 / 
in.totalsize()/(maxval - minval) << "% per pixel\n";
+
+                               cerr << "Min is: " << minval << endl;
+                               cerr << "Max is: " << maxval << endl;
+
+                       }
+                       else
+                               cerr << "Image R/W test for type " << fmt << " 
" << CVD::PNM::type_name<Type>::name() << " OK.\n";
+               }
+               catch(Exceptions::All w)
        {
-               cerr << "Error: give a filename\n";
-               exit(1);
+                       cerr << w.what << endl;
+               }
+
+               randtest<typename T::Next>::exec(fmt);
        }
+};
+
        
+template<> struct randtest<Head>
+{
+       static void exec(ImageType::ImageType){}
+};
+
+int main(int ac, char** av)
+{
        for(int i=1; i <ac; i++)
        {
                loadsave_safe<bool>(av[i]);
@@ -144,6 +268,47 @@
                loadsave_safe<CVD::Rgba<unsigned int> >(av[i]);
        }
        
+       cerr << "Testing PNM (type " << ImageType::PNM << ")\n";
+       randtest<
+                         TypeList<byte,
+                         TypeList<unsigned short,
+                         TypeList<Rgb<byte>,
+                         TypeList<Rgb<unsigned short>,
+                                      Head> > > > >::exec(ImageType::PNM);
+
+       #ifdef CVD_IMAGE_HAVE_PNG
+       cerr << "Testing PNG (type " << ImageType::PNG << ")\n";
+       randtest<
+                         TypeList<bool,
+                         TypeList<byte,
+                         TypeList<unsigned short,
+                         TypeList<Rgb<byte>,
+                         TypeList<Rgb<unsigned short>,
+                         TypeList<Rgba<byte>,
+                         TypeList<Rgba<unsigned short>,
+                                      Head> > > > > > > 
>::exec(ImageType::PNG);
+       #endif
+       #ifdef CVD_HAVE_TIFF
+       cerr << "Testing TIFF (type " << ImageType::TIFF << ")\n";
+       randtest<
+                         TypeList<bool,
+                         TypeList<byte,
+                         TypeList<unsigned short,
+                         TypeList<float,
+                         TypeList<double,
+
+                         TypeList<Rgb<byte>,
+                         TypeList<Rgb<unsigned short>,
+                         TypeList<Rgb<float>,
+                         TypeList<Rgb<double>,
+
+                         TypeList<Rgba<byte>,
+                         TypeList<Rgba<unsigned short>,
+                         TypeList<Rgba<float>,
+                         TypeList<Rgba<double>,
+
+                                      Head> > > > > > > > > > > > > 
>::exec(ImageType::TIFF);
+       #endif
        
        exit(0);
 }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]