[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libcvd-members] libcvd cvd/image_io.h cvd/internal/io/png.h cvd...
From: |
Edward Rosten |
Subject: |
[libcvd-members] libcvd cvd/image_io.h cvd/internal/io/png.h cvd... |
Date: |
Tue, 05 Aug 2008 23:03:48 +0000 |
CVSROOT: /cvsroot/libcvd
Module name: libcvd
Changes by: Edward Rosten <edrosten> 08/08/05 23:03:47
Modified files:
cvd : image_io.h
cvd/internal/io: png.h tiff.h
pnm_src : png.cc
test : test_images.cxx
Log message:
Convert PNG writing to the new system.
Enable bools for TIFF writing.
Expand test image to larger size.
All write,read tests passed.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/libcvd/cvd/image_io.h?cvsroot=libcvd&r1=1.35&r2=1.36
http://cvs.savannah.gnu.org/viewcvs/libcvd/cvd/internal/io/png.h?cvsroot=libcvd&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/libcvd/cvd/internal/io/tiff.h?cvsroot=libcvd&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/libcvd/pnm_src/png.cc?cvsroot=libcvd&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/libcvd/test/test_images.cxx?cvsroot=libcvd&r1=1.12&r2=1.13
Patches:
Index: cvd/image_io.h
===================================================================
RCS file: /cvsroot/libcvd/libcvd/cvd/image_io.h,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -b -r1.35 -r1.36
--- cvd/image_io.h 5 Aug 2008 02:12:45 -0000 1.35
+++ cvd/image_io.h 5 Aug 2008 23:03:47 -0000 1.36
@@ -280,7 +280,7 @@
case ImageType::JPEG: JPEG::writeJPEG(im,o); break;
#endif
#ifdef CVD_HAVE_PNG
- case ImageType::PNG: PNG::writePNG(im,o); break;
+ case ImageType::PNG: Internal::writeImage<PixelType,
PNG::png_writer>(im,o); break;
#endif
#ifdef CVD_HAVE_TIFF
case ImageType::TIFF: Internal::writeImage<PixelType,
TIFF::tiff_writer>(im,o); break;
Index: cvd/internal/io/png.h
===================================================================
RCS file: /cvsroot/libcvd/libcvd/cvd/internal/io/png.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- cvd/internal/io/png.h 5 Aug 2008 22:14:22 -0000 1.7
+++ cvd/internal/io/png.h 5 Aug 2008 23:03:47 -0000 1.8
@@ -101,193 +101,85 @@
// How to convert Misc types in to PNG compatible types
//
+//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> struct IntMapper { typedef unsigned short type;};
+template<> struct IntMapper<1, 0> { typedef unsigned char type;
};
+template<> struct IntMapper<0, 0> { typedef bool type; };
-template<class C, class D> void make_row_pointers(const SubImage<C>& im,
std::vector<const D*>& rows)
-{
- rows.resize(im.size().y);
- for(int r=0; r < im.size().y; r++)
- rows[r] = (const D*)im[r];
-}
-struct png_out
+//Mapping for integral types
+template<class ComponentIn, int is_integral> struct ComponentMapper_
{
- typedef enum
- {
- Grey,
- GreyAlpha,
- Rgb,
- RgbAlpha
- }colour_type;
-
- png_out(int w, int h, colour_type t, int depth, std::ostream&);
- ~png_out();
-
- void pack();
- void rgbx();
-
- void write_raw_pixel_lines(const std::vector<const unsigned char*>&);
- void write_raw_pixel_lines(const std::vector<const unsigned short*>&);
-
- void read_end();
-
- std::string error_string;
-
- std::ostream& o;
-
- png_struct_def* png_ptr;
- png_info_struct* info_ptr, *end_info;
+ typedef typename IntMapper<
+
(Pixel::traits<ComponentIn>::bits_used > 1),
+
(Pixel::traits<ComponentIn>::bits_used > 8)
+ >::type type;
};
-template<int Components, bool use_16bit> struct PNGType;
-template<> struct PNGType<1,0>{ typedef byte type; static const
png_out::colour_type Colour = png_out::Grey; static const int Depth=8;};
-template<> struct PNGType<1,1>{ typedef unsigned short type; static const
png_out::colour_type Colour = png_out::Grey; static const int Depth=16;};
-template<> struct PNGType<3,0>{ typedef Rgb<byte> type; static const
png_out::colour_type Colour = png_out::Rgb; static const int Depth=8;};
-template<> struct PNGType<3,1>{ typedef Rgb<unsigned short> type; static const
png_out::colour_type Colour = png_out::Rgb; static const int Depth=16;};
-template<> struct PNGType<4,0>{ typedef Rgba<byte> type; static const
png_out::colour_type Colour = png_out::RgbAlpha; static const int Depth=8;};
-template<> struct PNGType<4,1>{ typedef Rgba<unsigned short> type; static
const png_out::colour_type Colour = png_out::RgbAlpha; static const int
Depth=16;};
+//Mapping for non integral types
+template<class ComponentIn> struct ComponentMapper_<ComponentIn, 0> { typedef
unsigned short type; };
-template<class T> struct PNGWriter
+template<class ComponentIn> struct ComponentMapper
{
- static void write(const SubImage<T>& i, std::ostream& o)
- {
- typedef PNGType<Pixel::Component<T>::count,
Internal::save_default<T>::use_16bit> PNGInfo;
-
- typedef typename PNGInfo::type Out;
- typedef typename Pixel::Component<Out>::type Comp;
-
- png_out po(i.size().x, i.size().y,
(png_out::colour_type)PNGInfo::Colour, PNGInfo::Depth, o);
- std::vector<Out> row_buf(i.size().x);
- std::vector<const Comp*> rows;
- rows.push_back(reinterpret_cast<const Comp*>(&row_buf[0]));
-
-
-
- for(int r=0; r < i.size().y ; r++)
- {
- Pixel::ConvertPixels<T,Out>::convert(i[r], &row_buf[0],
i.size().x);
- po.write_raw_pixel_lines(rows);
- }
- }
+ typedef typename ComponentMapper_<ComponentIn,
Pixel::traits<ComponentIn>::integral>::type type;
};
-template<class T> void writePNG(const SubImage<T>& i, std::ostream& o)
-{
- PNGWriter<T>::write(i, o);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Types which require no conversions
-//
-template<> struct PNGWriter<bool>
+//Mapping for Rgbish types
+template<class ComponentIn> struct ComponentMapper<Rgb<ComponentIn> >
{
- static void write(const SubImage<bool>& i, std::ostream& o)
- {
- png_out po(i.size().x, i.size().y, png_out::Grey, 1, o);
- po.pack();
- std::vector<const byte*> rows;
- make_row_pointers(i, rows);
- po.write_raw_pixel_lines(rows);
- }
+ typedef Rgb<typename ComponentMapper_<ComponentIn,
Pixel::traits<ComponentIn>::integral>::type> type;
};
-template<> struct PNGWriter<byte>
+template<class ComponentIn> struct ComponentMapper<Rgba<ComponentIn> >
{
- static void write(const SubImage<byte>& i, std::ostream& o)
- {
- png_out po(i.size().x, i.size().y, png_out::Grey, 8, o);
- std::vector<const byte*> rows;
- make_row_pointers(i, rows);
- po.write_raw_pixel_lines(rows);
- }
+ typedef Rgba<typename ComponentMapper_<ComponentIn,
Pixel::traits<ComponentIn>::integral>::type> type;
};
-template<> struct PNGWriter<unsigned short>
+template<> struct ComponentMapper<Rgb8>
{
- static void write(const SubImage<unsigned short>& i, std::ostream& o)
- {
- png_out po(i.size().x, i.size().y, png_out::Grey, 16, o);
- std::vector<const unsigned short*> rows;
- make_row_pointers(i, rows);
- po.write_raw_pixel_lines(rows);
- }
+ typedef Rgb8 type;
};
-template<> struct PNGWriter<Rgb8>
-{
- static void write(const SubImage<Rgb8>& i, std::ostream& o)
- {
- png_out po(i.size().x, i.size().y, png_out::RgbAlpha, 8, o);
- po.rgbx();
- std::vector<const byte*> rows;
- make_row_pointers(i, rows);
- po.write_raw_pixel_lines(rows);
- }
-};
-template<> struct PNGWriter<Rgb<byte> >
+class png_writer
{
- static void write(const SubImage<Rgb<byte> >& i, std::ostream& o)
- {
- png_out po(i.size().x, i.size().y, png_out::Rgb, 8, o);
- std::vector<const byte*> rows;
- make_row_pointers(i, rows);
- po.write_raw_pixel_lines(rows);
- }
-};
+ public:
+ png_writer(std::ostream&, ImageRef size, const std::string&
type);
+ ~png_writer();
-template<> struct PNGWriter<Rgb<unsigned short> >
-{
- static void write(const SubImage<Rgb<unsigned short> >& i,
std::ostream& o)
- {
- png_out po(i.size().x, i.size().y, png_out::Rgb, 16, o);
- std::vector<const byte*> rows;
- make_row_pointers(i, rows);
- po.write_raw_pixel_lines(rows);
- }
-};
-
-template<> struct PNGWriter<Rgba<byte> >
-{
- static void write(const SubImage<Rgba<byte> >& i, std::ostream& o)
- {
- png_out po(i.size().x, i.size().y, png_out::RgbAlpha, 8, o);
- std::vector<const byte*> rows;
- make_row_pointers(i, rows);
- po.write_raw_pixel_lines(rows);
- }
-};
+ void write_raw_pixel_line(const bool*);
+ void write_raw_pixel_line(const unsigned char*);
+ void write_raw_pixel_line(const unsigned short*);
+ void write_raw_pixel_line(const Rgb<unsigned char>*);
+ void write_raw_pixel_line(const Rgb8*);
+ void write_raw_pixel_line(const Rgb<unsigned short>*);
+ void write_raw_pixel_line(const Rgba<unsigned char>*);
+ void write_raw_pixel_line(const Rgba<unsigned short>*);
-template<> struct PNGWriter<Rgba<unsigned short> >
-{
- static void write(const SubImage<Rgba<unsigned short> >& i,
std::ostream& o)
+ template<class Incoming> struct Outgoing
{
- png_out po(i.size().x, i.size().y, png_out::RgbAlpha, 16, o);
- std::vector<const byte*> rows;
- make_row_pointers(i, rows);
- po.write_raw_pixel_lines(rows);
- }
-};
-
-
-
-
-
-
-
-
-
-
-
-
+ typedef typename ComponentMapper<Incoming>::type type;
+ };
+ private:
+ template<class P> void write_line(const P*);
+ long row;
+ std::ostream& o;
+ ImageRef size;
+ std::string type;
+ std::string error_string;
+ png_struct_def* png_ptr;
+ png_info_struct* info_ptr, *end_info;
+};
}}
Index: cvd/internal/io/tiff.h
===================================================================
RCS file: /cvsroot/libcvd/libcvd/cvd/internal/io/tiff.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- cvd/internal/io/tiff.h 5 Aug 2008 22:14:22 -0000 1.9
+++ cvd/internal/io/tiff.h 5 Aug 2008 23:03:47 -0000 1.10
@@ -112,7 +112,7 @@
//This allows us to choose a type with a reasonable number of bits.
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; };
+ template<> struct IntMapper<0, 0> { typedef bool type; };
//Mapping for integral types
Index: pnm_src/png.cc
===================================================================
RCS file: /cvsroot/libcvd/libcvd/pnm_src/png.cc,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- pnm_src/png.cc 5 Aug 2008 22:12:05 -0000 1.7
+++ pnm_src/png.cc 5 Aug 2008 23:03:47 -0000 1.8
@@ -213,8 +213,8 @@
// PNG writing functions.
//
-png_out::png_out(int w, int h, colour_type t, int depth, std::ostream& out)
-:o(out)
+png_writer::png_writer(ostream& out, ImageRef sz, const string& type_)
+:row(0),o(out),size(sz),type(type_)
{
//Create required structs
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, &error_string,
error_fn, warn_fn);
@@ -238,68 +238,110 @@
//Set up stream IO
png_set_write_fn(png_ptr, &o, write_fn, flush_fn);
- int c_type;
- switch(t)
+ int c_type=0;
+ int depth=0;
+
+ if(type == "bool")
+ {
+ c_type = PNG_COLOR_TYPE_GRAY;
+ depth=1;
+ }
+ else if(type == "unsigned char")
+ {
+ c_type = PNG_COLOR_TYPE_GRAY;
+ depth=8;
+ }
+ else if(type == "unsigned short")
+ {
+ c_type = PNG_COLOR_TYPE_GRAY;
+ depth=16;
+ }
+ else if(type == "CVD::Rgb<unsigned char>")
+ {
+ c_type = PNG_COLOR_TYPE_RGB;
+ depth=8;
+ }
+ else if(type == "CVD::Rgb8")
{
- case Grey: c_type = PNG_COLOR_TYPE_GRAY; break;
- case GreyAlpha: c_type = PNG_COLOR_TYPE_GRAY_ALPHA; break;
- case Rgb: c_type = PNG_COLOR_TYPE_RGB; break;
- case RgbAlpha: c_type = PNG_COLOR_TYPE_RGB_ALPHA; break;
- default:
- throw Exceptions::Image_IO::MalformedImage("unknown
pixel format");
+ c_type = PNG_COLOR_TYPE_RGB;
+ depth=8;
+ //Note the existence of meaningless filler.
+ png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
+ }
+ else if(type == "CVD::Rgb<unsigned short>")
+ {
+ c_type = PNG_COLOR_TYPE_RGB;
+ depth=16;
+ }
+ else if(type == "CVD::Rgba<unsigned char>")
+ {
+ c_type = PNG_COLOR_TYPE_RGB_ALPHA;
+ depth = 8;
}
+ else if(type == "CVD::Rgba<unsigned short>")
+ {
+ c_type = PNG_COLOR_TYPE_RGB_ALPHA;
+ depth = 16;
+ }
+ else
+ throw UnsupportedImageSubType("TIFF", type);
//Set up the image type
- png_set_IHDR(png_ptr, info_ptr, w, h, depth, c_type,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+ png_set_IHDR(png_ptr, info_ptr, size.x, size.y, depth, c_type,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
//Write the header
png_write_info(png_ptr, info_ptr);
//Write the transformations
#ifdef CVD_ARCH_LITTLE_ENDIAN
- if (depth > 8)
+ if (depth == 16)
png_set_swap(png_ptr);
#endif
-}
-
-void png_out::pack()
-{
+ //Pack from C++ bools to packed PNG bools
+ //This has to be done _after_ writing the info struct.
+ if(type == "bool")
png_set_packing(png_ptr);
-}
-void png_out::rgbx()
-{
- png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
}
-void png_out::write_raw_pixel_lines(const std::vector<const unsigned char*>& p)
-{
- //Set up error handling
- if(setjmp(png_jmpbuf(png_ptr)))
- {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- throw Exceptions::Image_IO::MalformedImage(error_string);
- }
+//Mechanically generate the pixel writing calls.
+#undef GEN1
+#undef GEN3
+#define GEN1(X) void png_writer::write_raw_pixel_line(const
X*d){write_line(d);}
+#define GEN3(X) GEN1(X) GEN1(Rgb<X>) GEN1(Rgba<X>)
+GEN1(bool)
+GEN1(Rgb8)
+GEN3(unsigned char)
+GEN3(unsigned short)
+
+
+template<class P> void png_writer::write_line(const P* data)
+{
+ unsigned char* chardata = const_cast<unsigned
char*>(reinterpret_cast<const unsigned char*>(data));
+
+ //Do some type checking
+ if(type != PNM::type_name<P>::name())
+ throw WriteTypeMismatch(type, PNM::type_name<P>::name());
- png_write_rows(png_ptr, const_cast<unsigned char**>(&p[0]), p.size());
-}
-void png_out::write_raw_pixel_lines(const std::vector<const unsigned short*>&
p)
-{
//Set up error handling
if(setjmp(png_jmpbuf(png_ptr)))
- {
- png_destroy_write_struct(&png_ptr, &info_ptr);
throw Exceptions::Image_IO::MalformedImage(error_string);
- }
- png_write_rows(png_ptr, reinterpret_cast<unsigned
char**>(const_cast<unsigned short**>(&p[0])), p.size());
+ //Do some sanity checking
+ if(row > size.y)
+ throw InternalLibraryError("CVD", "Write past end of image.");
+
+
+ unsigned char** row_ptr = & chardata;
+ png_write_rows(png_ptr, row_ptr, 1);
+ row++;
}
-png_out::~png_out()
+png_writer::~png_writer()
{
png_write_end(png_ptr, info_ptr);
png_destroy_write_struct(&png_ptr, &info_ptr);
Index: test/test_images.cxx
===================================================================
RCS file: /cvsroot/libcvd/libcvd/test/test_images.cxx,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- test/test_images.cxx 5 Aug 2008 19:35:49 -0000 1.12
+++ test/test_images.cxx 5 Aug 2008 23:03:47 -0000 1.13
@@ -164,7 +164,7 @@
{
try{
//Make a random image
- Image<Type> in(ImageRef(2,2)), out;
+ Image<Type> in(ImageRef(100,100)), out;
for(int y=0; y < in.size().y; y++)
for(int x=0; x < in.size().x; x++)
@@ -194,12 +194,12 @@
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);
+ double p =
Pixel::Component<Type>::get(in[y][x], c);
+ double p2 =
Pixel::Component<Type>::get(out[y][x], c);
+ t += abs(p - p2);
- maxval = max(maxval,
(double)p);
- minval = min(minval,
(double)p);
+ maxval = max(maxval, p);
+ minval = min(minval, p);
cerr << p << " " << p2
<< endl;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [libcvd-members] libcvd cvd/image_io.h cvd/internal/io/png.h cvd...,
Edward Rosten <=