[Top][All Lists]
[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);
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [libcvd-members] libcvd cvd/image_io.h cvd/internal/load_and_sav...,
Edward Rosten <=