00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
00009
00010
00011 #include "vil1_mit.h"
00012
00013 #include <vcl_iostream.h>
00014 #include <vcl_cassert.h>
00015 #include <vcl_cstring.h>
00016
00017 #include <vil1/vil1_stream.h>
00018 #include <vil1/vil1_image_impl.h>
00019 #include <vil1/vil1_image.h>
00020 #include <vil1/vil1_16bit.h>
00021 #include <vil1/vil1_property.h>
00022
00023 static char const* vil1_mit_format_tag = "mit";
00024
00025 #define MIT_UNSIGNED 0x0001
00026 #define MIT_RGB 0x0002
00027 #define MIT_HSB 0x0003
00028 #define MIT_CAP 0x0004
00029 #define MIT_SIGNED 0x0005
00030 #define MIT_FLOAT 0x0006
00031 #define MIT_EDGE 0x0007
00032
00033 #define MIT_UCOMPLEX 0x0101
00034 #define MIT_SCOMPLEX 0x0105
00035 #define MIT_FCOMPLEX 0x0106
00036
00037 #define MIT_UNSIGNED_E 0x0201
00038 #define MIT_SIGNED_E 0x0205
00039 #define MIT_FLOAT_E 0x0206
00040
00041 #define MIT_UCOMPLEX_E 0x0301
00042 #define MIT_SCOMPLEX_E 0x0305
00043 #define MIT_FCOMPLEX_E 0x0306
00044
00045 #define EDGE_HOR 0200
00046 #define EDGE_VER 0100
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 vil1_image_impl* vil1_mit_file_format::make_input_image(vil1_stream* is)
00062 {
00063 is->seek(0L);
00064 int type = vil1_16bit_read_little_endian(is);
00065
00066 if (!(type == MIT_UNSIGNED ||
00067 type == MIT_RGB ||
00068 type == MIT_HSB ||
00069 type == MIT_CAP ||
00070 type == MIT_SIGNED ||
00071 type == MIT_FLOAT ||
00072 type == MIT_EDGE ))
00073 return 0;
00074
00075 int bits_per_pixel = vil1_16bit_read_little_endian(is);
00076 if (bits_per_pixel > 32) {
00077 vcl_cerr << "vil1_mit_file_format:: Thought it was MIT, but bpp = " << bits_per_pixel << vcl_endl;
00078 return 0;
00079 }
00080
00081 vil1_16bit_read_little_endian(is);
00082 vil1_16bit_read_little_endian(is);
00083 #if 0
00084 vcl_cerr << __FILE__ " : here we go:\n"
00085 << __FILE__ " : type_ = " << type << vcl_endl
00086 << __FILE__ " : bits_per_pixel_ = " << bits_per_pixel << vcl_endl
00087 << __FILE__ " : width_ = " << width << vcl_endl
00088 << __FILE__ " : height_ = " << height << vcl_endl;
00089 #endif
00090 return new vil1_mit_generic_image(is);
00091 }
00092
00093 vil1_image_impl* vil1_mit_file_format::make_output_image(vil1_stream* is, int planes,
00094 int width,
00095 int height,
00096 int components,
00097 int bits_per_component,
00098 vil1_component_format format)
00099 {
00100 return new vil1_mit_generic_image(is, planes, width, height, components, bits_per_component, format);
00101 }
00102
00103 char const* vil1_mit_file_format::tag() const
00104 {
00105 return vil1_mit_format_tag;
00106 }
00107
00108
00109
00110 vil1_mit_generic_image::vil1_mit_generic_image(vil1_stream* is):
00111 is_(is)
00112 {
00113 is_->ref();
00114 read_header();
00115 }
00116
00117 bool vil1_mit_generic_image::get_property(char const *tag, void *prop) const
00118 {
00119 if (0==vcl_strcmp(tag, vil1_property_top_row_first))
00120 return prop ? (*(bool*)prop) = true : true;
00121
00122 if (0==vcl_strcmp(tag, vil1_property_left_first))
00123 return prop ? (*(bool*)prop) = true : true;
00124
00125 return false;
00126 }
00127
00128 char const* vil1_mit_generic_image::file_format() const
00129 {
00130 return vil1_mit_format_tag;
00131 }
00132
00133 vil1_mit_generic_image::vil1_mit_generic_image(vil1_stream* is, int planes,
00134 int width,
00135 int height,
00136 int components,
00137 int bits_per_component,
00138 vil1_component_format ):
00139 is_(is)
00140 {
00141 is_->ref();
00142 assert(planes==1);
00143 width_ = width;
00144 height_ = height;
00145 components_ = components;
00146 bits_per_component_ = bits_per_component;
00147 bits_per_pixel_ = bits_per_component_ * components_;
00148
00149 if (bits_per_component_ == 8 || bits_per_component_ == 16)
00150 {
00151 if (components_ == 3) type_ = 2;
00152 else if (components_ == 1) type_ = 1;
00153 else vcl_cerr << __FILE__ " : Can only write RGB or grayscale\n";
00154 }
00155 else
00156 {
00157 if (components_ == 1) type_ = 6;
00158 else
00159 vcl_cerr << __FILE__ " : Ah can only write 8 or 16 bit images\n";
00160 }
00161
00162 write_header();
00163 }
00164
00165 vil1_mit_generic_image::~vil1_mit_generic_image()
00166 {
00167 is_->unref();
00168 }
00169
00170 bool vil1_mit_generic_image::read_header()
00171 {
00172 is_->seek(0L);
00173
00174 type_ = vil1_16bit_read_little_endian(is_);
00175 bits_per_pixel_ = vil1_16bit_read_little_endian(is_);
00176 width_ = vil1_16bit_read_little_endian(is_);
00177 height_ = vil1_16bit_read_little_endian(is_);
00178
00179 if (type_ > 7 || type_ < 1)
00180 return false;
00181
00182 if (type_ == 1) components_ = 1;
00183 else if (type_ == 2) components_ = 3;
00184 else if (type_ == 6) components_ = 1;
00185
00186 return true;
00187 }
00188
00189 bool vil1_mit_generic_image::write_header()
00190 {
00191 is_->seek(0L);
00192 vil1_16bit_write_little_endian(is_, type_);
00193 vil1_16bit_write_little_endian(is_, bits_per_pixel_);
00194 vil1_16bit_write_little_endian(is_, width_);
00195 vil1_16bit_write_little_endian(is_, height_);
00196 return true;
00197 }
00198
00199 bool vil1_mit_generic_image::get_section(void* buf, int x0, int y0, int xs, int ys) const
00200 {
00201 assert(buf != 0);
00202
00203 vil1_streampos offset = 8;
00204
00205 int skip = bytes_per_pixel() * (width_ - xs);
00206
00207 unsigned char *point = (unsigned char*)buf;
00208
00209 is_->seek(offset + (width_*y0*bytes_per_pixel()) + (x0*bytes_per_pixel()));
00210
00211
00212
00213 for (int tely = 0; tely < ys; tely++)
00214 {
00215 is_->read(point, xs * bytes_per_pixel());
00216 is_->seek(is_->tell() + skip);
00217 point += (xs * bytes_per_pixel());
00218 }
00219
00220 return true;
00221 }
00222
00223 bool vil1_mit_generic_image::put_section(void const* buf, int x0, int y0, int xs, int ys)
00224 {
00225 assert(buf != 0);
00226
00227 int skip = bytes_per_pixel() * (width_ - xs);
00228
00229 vil1_streampos offset = 8;
00230 is_->seek(offset + (width_*y0*bytes_per_pixel()) + (x0*bytes_per_pixel()));
00231
00232 const unsigned char* point = (const unsigned char*)buf;
00233
00234
00235 for (int tely = 0; tely < ys; tely++)
00236 {
00237 is_->write(point, xs * bytes_per_pixel());
00238 is_->seek(is_->tell() + skip);
00239 point += (xs * bytes_per_pixel());
00240 }
00241
00242 return true;
00243 }
00244
00245 vil1_image vil1_mit_generic_image::get_plane(unsigned int plane) const
00246 {
00247 assert(plane == 0);
00248 return const_cast<vil1_mit_generic_image*>(this);
00249 }