2 * psychlops_g_image.cpp
3 * Psychlops Standard Library (Universal)
5 * Last Modified 2006/01/04 by Kenchi HOSOKAWA
6 * (C) 2006 Kenchi HOSOKAWA, Kazushi MARUYA and Takao SATO
16 #define PSYCHLOPS_WINDOW_API_PLATFORM
17 #include "../../platform/psychlops_platform_selector.h"
18 #include "../ApplicationInterfaces/psychlops_app_info.h"
19 #include "../devices/psychlops_io_file.h"
20 #include "../math/psychlops_math.h"
22 #include "psychlops_g_fundamental.h"
23 #include "psychlops_g_color.h"
24 #include "psychlops_g_module.h"
25 #include "psychlops_g_shape.h"
26 #include "psychlops_g_canvas.h"
27 #include "psychlops_g_image.h"
29 #include "../../extension/FileFormat/PNG/psychlops_g_PNG_bridge.h"
30 #include "../../extension/FileFormat/OpenCV/psychlops_g_OPENCV_bridge.h"
35 ImageCache_::ImageCache_() : id(0), dirty(false) {}
36 ImageCache_::ImageCache_(APIImageCache* id__, bool dirty__) : id(id__), dirty(dirty__) {}
38 const int Image::PixCompSize_[3] = { 1, 3, 4 };
39 const int Image::PixPrecSize_[2] = { sizeof(unsigned char), sizeof(float) };
40 int Image::lineBytesAlingnment_ = AppState::ImageByteAlignment;
43 Image& Image::operator =(const Image &source) {
44 memcpy(this, &source, sizeof(*this));
47 Image::Image(const Image &readimage){}
48 Image::Image(const Image &readimage, bool dummt) {
55 //////// Construst and Destruct ////////
61 Image::Image(std::string filename) {
65 Image::Image(const char * filename) {
69 Image::Image(long x, long y, PixelComponentsCnt pixcomp, PixelComponentsPrecision pixprec) {
71 set(x, y, pixcomp, pixprec);
73 Image::Image(long x, long y, PixelComponentsPrecision pixprec) {
75 set(x, y, RGB, pixprec);
77 Image::Image(Rectangle rectangle, PixelComponentsCnt pixcomp, PixelComponentsPrecision pixprec) {
79 set(rectangle, pixcomp, pixprec);
81 Image::Image(Rectangle rectangle, PixelComponentsPrecision pixprec) {
83 set(rectangle, RGB, pixprec);
86 void Image::setWithoutClear(bool y)
90 bool Image::setWithoutClear_ = false; // OK?
92 void Image::set(long x, long y, PixelComponentsPrecision pixprec) {
93 set(x, y, RGB, pixprec);
95 void Image::set(Rectangle rectangle, PixelComponentsCnt pixcomp, PixelComponentsPrecision pixprec) {
96 set((long)rectangle.getWidth(), (long)rectangle.getHeight(), pixcomp, pixprec);
98 void Image::set(Rectangle rectangle, PixelComponentsPrecision pixprec) {
99 set(rectangle, RGB, pixprec);
101 void Image::initPointersNull() {
102 have_instance_ = false;
103 //quickened_ = false;
113 Image::~Image(void) {
116 void Image::release(){
118 if(!caches.empty()) {
119 std::vector<DrawableWithCache*> tmp;
120 for(CacheID::iterator i=caches.begin(); i!=caches.end(); i++) tmp.push_back(i->first);
121 for(int i=0; i<tmp.size(); i++) tmp[i]->uncacheImage(*this);
125 have_instance_ = false;
128 void Image::releasebitmap() {
132 if(bitmapub_ != NULL) delete [] bitmapub_;
135 if(bitmapf_ != NULL) delete [] bitmapf_;
141 bool Image::hasInstance() const {
142 return have_instance_;
145 Image& Image::cache(DrawableWithCache &target) {
146 target.cacheImage(*this);
149 Image& Image::uncache(DrawableWithCache &target) {
150 target.uncacheImage(*this);
154 Image Image::dup() const {
155 return Image(*this, true);
157 Image Image::duplicate() const {
158 return Image(*this, true);
160 Image& Image::convert(PixelComponentsCnt pixcompcntval) {
161 if(!have_instance_) throw Exception(typeid(*this), "Memory Error", "Image had not allocated.");
162 if(pixcomp_==pixcompcntval) {
165 Image *tmp = new Image;
168 set(tmp->width_, tmp->height_, pixcompcntval, tmp->pixprec_);
169 targetarea_ = tmp->targetarea_;
170 localarea_ = tmp->localarea_;
171 unsigned char *p = bitmapub_;
172 float *pf = bitmapf_;
175 for(int y=height_-1; y>=0; y--) {
176 for(int x=0; x<width_; x++) {
177 tmp->getPix(x,y).get(r, g, b, a);
178 *(p++) = (unsigned char)(r*255.0+.5);
179 if(pixcomp_==RGB||pixcomp_==RGBA) *(p++) = (unsigned char)(g*255.0+.5);
180 if(pixcomp_==RGB||pixcomp_==RGBA) *(p++) = (unsigned char)(b*255.0+.5);
181 if(pixcomp_==RGBA) { *(p++) = (unsigned char)(a*255.0+.5); }
185 for(int y=height_-1; y>=0; y--) {
186 for(int x=0; x<width_; x++) {
187 tmp->getPix(x,y).get(r, g, b, a);
189 if(pixcomp_==RGB||pixcomp_==RGBA) *(pf++) = g;
190 if(pixcomp_==RGB||pixcomp_==RGBA) *(pf++) = b;
191 if(pixcomp_==RGBA) { *(pf++) = a; }
195 //if(tmp->quickened_) quicken();
200 Image& Image::convertColorCalibration(bool on_off) {
203 if(!have_instance_) throw Exception(typeid(*this), "Memory Error", "Image had not allocated.");
204 Image *tmp = new Image;
207 set(tmp->width_, tmp->height_, tmp->pixcomp_, tmp->pixprec_);
208 targetarea_ = tmp->targetarea_;
209 localarea_ = tmp->localarea_;
211 for(int y=0; y<height_; y++) {
212 for(int x=0; x<width_; x++) {
219 tmp->pix_direct(x, y, col);
223 for(int y=0; y<height_; y++) {
224 for(int x=0; x<width_; x++) {
225 getPix(x, y).get(r,g,b,a);
230 tmp->pix_direct(x, y, col);
234 //if(tmp->quickened_) quicken();
241 //////// Drawing ////////
243 void Image::pix_ub_bits_mono_(int ix, int iy, double lum) {
245 if(0>x || x>width_-1 || y<0 || y>height_-1) throw Exception(typeid(Image), "Out Of Bound Exception", "Specified coordinate is out of bound.");
246 int offset = y*lineValue_ + x*PixCompSize_[pixcomp_];
247 unsigned char *p = bitmapub_ + offset;
248 unsigned short wordlum = (unsigned short)(lum*65535);
249 *(p) = (unsigned char)(wordlum>>8);
250 *(++p) = (unsigned char)(wordlum&255);
251 *(++p) = (unsigned char)0;
254 Image& Image::alpha(const double a)
256 for(int y=0; y<getHeight(); y++)
257 for(int x=0; x<getWidth(); x++)
261 Image& Image::alpha(const Matrix &a)
263 if(getWidth()!=a.getCols() || getHeight()!=a.getRows() || pixcomp_!=Image::RGBA)
264 throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent to Image");
265 for(int y=0; y<getHeight(); y++)
266 for(int x=0; x<getWidth(); x++)
267 alpha(x,y,a(y+1,x+1));
270 Image& Image::clear(const Color &col) {
272 //for(int y=0; y<height_; y++) {
273 // for(int x=0; x<width_; x++) {
274 // pix_direct_(*this,x,y,col);
280 pix_raw(0, getHeight()-1, col);
282 if(pixprec_ == Image::BYTE) {
283 if(pixcomp_ == Image::GRAY) {
285 for(x=0; x<width_; x++) {
286 (*pb++) = *(bitmapub_);
288 } else if(pixcomp_ == Image::RGB) {
290 for(x=0; x<width_; x++) {
291 (*pb++) = *(bitmapub_);
292 (*pb++) = *(bitmapub_+1);
293 (*pb++) = *(bitmapub_+2);
295 } else if(pixcomp_ == Image::RGBA) {
297 for(x=0; x<width_; x++) {
298 (*pb++) = *(bitmapub_);
299 (*pb++) = *(bitmapub_+1);
300 (*pb++) = *(bitmapub_+2);
301 (*pb++) = *(bitmapub_+3);
304 for(y=1; y<height_; y++) {
307 memcpy(pb, bitmapub_, lineValue_);
309 } else if(pixprec_ == Image::FLOAT) {
310 if(pixcomp_ == Image::GRAY) {
312 for(x=0; x<width_; x++) {
313 (*pf++) = *(bitmapf_);
315 } else if(pixcomp_ == Image::RGB) {
317 for(x=0; x<width_; x++) {
318 (*pf++) = *(bitmapf_);
319 (*pf++) = *(bitmapf_+1);
320 (*pf++) = *(bitmapf_+2);
322 } else if(pixcomp_ == Image::RGBA) {
324 for(x=0; x<width_; x++) {
325 (*pf++) = *(bitmapf_);
326 (*pf++) = *(bitmapf_+1);
327 (*pf++) = *(bitmapf_+2);
328 (*pf++) = *(bitmapf_+3);
331 for(y=1; y<height_; y++) {
334 memcpy(pf, bitmapf_, lineBytes_);
339 /* Image& Image::alpha(const int x, const int iy, const double a) {
344 Image& Image::pix(const double x, const double y, const Color &col) {
345 pix(Math::round(x), Math::round(y), col);
348 Image& Image::pix(const Point &po, const Color &col) {
349 pix(Math::round(po.x), Math::round(po.y), col);
353 void Image::rect(const Rectangle &rectangle, const Color &col) {
354 Rectangle filledrect(rectangle);
355 filledrect.cripped(area_);
356 int t = Math::round(filledrect.top);
357 int b = Math::round(filledrect.bottom);
358 int l = Math::round(filledrect.left);
359 int r = Math::round(filledrect.right);
360 for(int y=t; y<=b; y++) {
361 for(int x=l; x<=r; x++) {
366 void Image::line(const double x1, const double y1, const double x2, const double y2, const Color &col) {
367 int begin, end, tbegin, ax, ay;
370 double slope = (y1-y2)/(x1-x2);
371 if(slope<1 && slope>-1) {
373 tbegin = begin = Math::round(x1);
374 end = Math::round(x2);
377 tbegin = begin = Math::round(x2);
378 end = Math::round(x1);
381 begin = ( begin<0 ? 0 : begin );
382 end = ( end>width_-1 ? width_-1 : end );
383 for(int x=begin; x<=end; x++) {
384 ay = Math::round((x-tbegin)*slope + obegin);
385 if(-1<x && x<width_ && -1 <ay && ay<height_ ) pix(x, ay, col);
389 tbegin = begin = Math::round(y1);
390 end = Math::round(y2);
393 tbegin = begin = Math::round(y2);
394 end = Math::round(y1);
397 begin = ( begin<0 ? 0 : begin );
398 end = ( end>height_-1 ? height_-1 : end );
399 for(int y=begin; y<=end; y++) {
400 ax = Math::round((y-tbegin)/slope + obegin);
401 if(-1<ax && ax<width_ && -1<y && y<height_ ) pix(ax, y, col);
406 tbegin = begin = Math::round(y1);
407 end = Math::round(y2);
410 tbegin = begin = Math::round(y2);
411 end = Math::round(y1);
414 begin = ( begin<0 ? 0 : begin );
415 end = ( end>height_-1 ? height_-1 : end );
416 ax = Math::round(obegin);
417 for(int y=begin; y<=end; y++) {
418 if(-1<ax && ax<width_ && -1<y && y<height_ ) pix(ax, y, col);
422 void Image::line(const Point &po1, const Point &po2, const Color &col) {
423 line(po1.x, po1.y, po2.x, po2.y, col);
425 void Image::ellipse(const Rectangle &rect, const Color &col) {
426 double center_x = rect.getCenter().x;
427 double center_y = rect.getCenter().y;
428 double radius = rect.getHeight() / 2.0;
429 double aspect_ratio = rect.getWidth() / rect.getHeight();
432 t = ( rect.top < 0 ? 0 : Math::round(rect.top) );
433 b = ( rect.bottom > height_-1 ? height_-1 : Math::round(rect.bottom) );
434 for(int y=t; y<=b; y++) {
435 tmp = ( (y-center_y)/radius );
436 l = Math::round( center_x - aspect_ratio * ( radius * sqrt(1-(tmp*tmp)) ) );
437 r = Math::round( ( center_x - l ) + center_x );
438 l = ( l < 0 ? 0 : l );
439 r = ( r > width_-1 ? width_-1 : r );
440 for(int x=l; x<=r; x++) {
446 void Image::oval(const Rectangle &rect, const Color &col) {
449 void Image::fillRect(const Rectangle &rectangle, const Color &col) {
450 rect(rectangle, col);
452 /* void Image::msg(Letters &letters, int x, int y, const Color &col) {
453 api_->drawLetters(letters, x, y,col.Red,col.Blue,col.Green,col.Alpha,0,0);
457 Image& Image::draw(double left, double top, Drawable &target) {
458 target.image(*this, left, top);
461 Image& Image::draw(Drawable &target) {
465 Image& Image::draw(double alpha, Drawable &target) {
466 target.image(*this, alpha);
470 void Image::display(double x, double y) {
473 void Image::display() {
474 draw(targetarea_.left, targetarea_.top);
478 Image::PartialView::PartialView(Image *src, const Rectangle &d_source)
482 target.set(source.getWidth(), source.getHeight());
484 Image::PartialView& Image::PartialView::set(double width, double height)
486 target.set(width, height);
489 Image::PartialView::~PartialView()
492 const Point Image::PartialView::getDatum() const
494 return target.getDatum();
496 Image::PartialView& Image::PartialView::setDatum(const Point &p)
501 Image::PartialView& Image::PartialView::centering(const Point &p)
506 Image::PartialView& Image::PartialView::draw(Drawable &target_)
508 target_.image(*img, target, source);
511 Image::PartialView Image::operator ()(const Rectangle &view)
513 PartialView tmp(this, view);
520 // get bitmap properties
521 const void * Image::getBitmapPtr() const {
522 if(!have_instance_) Exception(typeid(*this), "Memory Error", "The Image does not have bitmap instance.");
525 return (void *)bitmapub_;
528 return (void *)bitmapf_;
538 const Point Image::getDatum() const {
539 return targetarea_.getDatum();
541 Image& Image::setDatum(const Point& p) {
542 targetarea_.setDatum(p);
545 Image& Image::centering(const Drawable& target) {
546 targetarea_.centering(target);
549 Image& Image::centering(const Figure& fig) {
550 targetarea_.centering(fig);
553 Image& Image::centering(const Point& p) {
554 targetarea_.centering(p);
557 Image& Image::centering(const double x, const double y, const double z) {
558 targetarea_.centering(x, y, z);
561 Image& Image::move_to(const double x, const double y, const double z) {
562 targetarea_.move_to(x, y, z);
565 Image& Image::shift(const double x, const double y, const double z) {
566 targetarea_.shift(x, y, z);
569 int Image::getWidth() const { return width_; }
570 int Image::getHeight() const { return height_; }
571 double Image::getHcenter() const { return width_/2 - 0.5; }
572 double Image::getVcenter() const { return height_/2 - 0.5; }
573 const Point Image::getCenter() const {
574 Point po(getHcenter(), getVcenter());
577 double Image::getTop() const { return targetarea_.top; }
578 double Image::getLeft() const { return targetarea_.left; }
579 double Image::getBottom() const { return targetarea_.bottom; }
580 double Image::getRight() const { return targetarea_.right; }
583 float* Image::getFloatPrt() { return bitmapf_; }
584 unsigned char* Image::getElementPtr() { return bitmapub_; }
585 int Image::getPixBytes() { return pixBytes_; }
586 int Image::getLineBytes() { return lineBytes_; }
587 int Image::getBitmapBytes() { return bitmapBytes_; }
588 int Image::getLineNumber() { return lineValue_; }
589 int Image::getElementNumber() { return bitmapValue_; }
590 const Image::PixelComponentsCnt Image::getComponentKind() const { return pixcomp_; }
\r
591 const Image::PixelComponentsPrecision Image::getPrecisionKind() const { return pixprec_; }
593 //// Special Utilities
595 void Image::to(const Rectangle &source__, Image &other, const Rectangle target__) const {
596 Rectangle source = source__, target = target__;
597 source.clipped_by(area_);
598 target.clipped_by(other.area_);
599 if(source.getWidth()!=target.getWidth() || source.getHeight()!=target.getHeight())
600 throw new Exception("Image.to: source area does not match target area.");
601 int sl = (int)source.getLeft(), st=(int)source.getTop(), tl=(int)target.getLeft(), tt=(int)target.getTop();
602 for(int y=0; y<source.getHeight(); y++)
603 for(int x=0; x<source.getWidth(); x++)
604 other.pix_direct(x+tl,y+tt, getPix(x+sl,y+st));
606 void Image::to(const Rectangle &source__, Image &other) const {
607 Rectangle source = source__;
608 source.clipped_by(area_);
610 other.set(source, pixcomp_, pixprec_);
611 for(int y=0; y<other.getHeight(); y++)
612 for(int x=0; x<other.getWidth(); x++)
613 other.pix_direct(x,y, getPix((int)(source.getLeft())+x, (int)(source.getTop())+y));
615 int vbase = getHeight() - source.getTop();
616 for(int i=0; i<other.getHeight(); i++) {
617 memcpy(other.bitmapub_+(other.getHeight()-i-1)*(lineBytes_),
618 bitmapub_+(vbase-i-1)*(lineBytes_)+(size_t)(source.getLeft()),
619 pixBytes_*other.getWidth());
625 void Image::load(std::string filename) {
626 IMAGE_FORMATS::IMAGE_FORMAT *loader;
630 std::string::size_type extention_index = filename.find_last_of('.');
631 if(extention_index==std::string::npos) throw Exception(typeid(*this), "File Type Error", "Specified image type is not supported.*..");
632 std::string file_extension = filename.substr(extention_index+1);
\r
633 IMAGE_FORMATS::FILE_EXT ext = IMAGE_FORMATS::getImageFileFormatFromExt(file_extension);
\r
634 if(ext==IMAGE_FORMATS::PNG) {
635 loader = new IMAGE_FORMATS::PNG_BRIDGE;
636 loader->load(File::decodePath(filename).c_str(), this);
638 } else if(ext==IMAGE_FORMATS::JPG) {
639 loader = new IMAGE_FORMATS::OPENCV_BRIDGE;
640 loader->load(File::decodePath(filename).c_str(), this);
642 } else if(ext==IMAGE_FORMATS::TIFF) {
643 loader = new IMAGE_FORMATS::OPENCV_BRIDGE;
644 loader->load(File::decodePath(filename).c_str(), this);
647 throw Exception(typeid(*this), "File Type Error", "Specified image type is not supported.");
649 switch(Color::getCalibrationMode()) {
650 case Color::SOFTWARE_GAMMA_VALUE:
651 case Color::SOFTWARE_TABLE:
652 convertColorCalibration(true);
658 void Image::load(const char * filename) {
659 load(std::string(filename));
661 void Image::save(std::string filename) {
662 IMAGE_FORMATS::IMAGE_FORMAT *loader;
663 if(!have_instance_) {
664 throw Exception(typeid(*this), "Memory Error", "Image does not have its instance.");
670 switch(Color::getCalibrationMode()) {
671 case Color::SOFTWARE_GAMMA_VALUE:
672 case Color::SOFTWARE_TABLE:
673 tmp = new Image(width_, height_, pixcomp_, pixprec_);
674 for(int y=0; y<height_; y++) {
675 for(int x=0; x<width_; x++) {
682 tmp->pix_direct(x, y, col);
691 std::string::size_type extention_index = filename.find_last_of('.');
692 if(extention_index==std::string::npos) throw Exception(typeid(*this), "File Type Error", "Specified image type is not supported.");
693 std::string file_extension = filename.substr(extention_index+1);
\r
694 IMAGE_FORMATS::FILE_EXT ext = IMAGE_FORMATS::getImageFileFormatFromExt(file_extension);
695 if(ext==IMAGE_FORMATS::PNG) {
696 loader = new IMAGE_FORMATS::PNG_BRIDGE;
697 loader->save(File::decodePath(filename).c_str(), tmp);
699 } else if(ext==IMAGE_FORMATS::JPG) {
700 loader = new IMAGE_FORMATS::OPENCV_BRIDGE;
701 loader->save(File::decodePath(filename).c_str(), tmp);
703 } else if(ext==IMAGE_FORMATS::TIFF) {
704 loader = new IMAGE_FORMATS::OPENCV_BRIDGE;
705 loader->save(File::decodePath(filename).c_str(), tmp);
708 throw Exception(typeid(*this), "File Type Error", "Specified image type is not supported.");
710 if(tmp != this) delete tmp;
712 void Image::save(const char * filename) {
713 save(std::string(filename));
716 void Image::from(const Matrix &mtx) {
718 if(getWidth()!=mtx.getCols() || getHeight()!=mtx.getRows() || pixcomp_!=Image::GRAY) {
719 //if (have_instance_==false) set(mtx.getCols(),mtx.getRows(), GRAY);
720 //else throw Exception(typeid(*this), "Memory Error", "Image has been allocated.");
722 set(mtx.getCols(),mtx.getRows(), GRAY);
724 int rowmax = mtx.getRows();
725 int colmax = mtx.getCols();
726 for(int row=1; row<=rowmax; row++) {
727 for(int col=1; col<=colmax; col++) {
728 //colour.set(mtx(row,col));
729 pix_direct(col-1,row-1,mtx(row,col));
733 void Image::from(const Matrix &r, const Matrix &g, const Matrix &b) {
735 if(r.getRows()!=g.getRows() || r.getRows()!=b.getRows()) throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent between each color.");
736 if(r.getCols()!=g.getCols() || r.getCols()!=b.getCols()) throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent between each color.");
737 if(getWidth()!=r.getCols() || getHeight()!=r.getRows() || pixcomp_!=Image::RGB) {
738 //if (have_instance_==false) set(r.getCols(),r.getRows(), RGB);
739 //else throw Exception(typeid(*this), "Memory Error", "Image has been allocated.");
741 set(r.getCols(),r.getRows(), RGB);
743 int rowmax = r.getRows();
744 int colmax = r.getCols();
745 for(int row=1; row<=rowmax; row++) {
746 for(int col=1; col<=colmax; col++) {
747 //colour.set(r(row,col), g(row,col), b(row,col));
748 pix_direct(col-1,row-1,r(row,col), g(row,col), b(row,col),1.0);
752 void Image::from(const Matrix &r, const Matrix &g, const Matrix &b, const Matrix &a) {
754 if(r.getRows()!=g.getRows() || r.getRows()!=b.getRows() || r.getRows()!=a.getRows()) throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent between each color.");
755 if(r.getCols()!=g.getCols() || r.getCols()!=b.getCols() || r.getCols()!=a.getCols()) throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent between each color.");
756 if(getWidth()!=r.getCols() || getHeight()!=r.getRows() || pixcomp_!=Image::RGBA) {
757 //if (have_instance_==false) set(r.getCols(),r.getRows(), RGBA);
758 //else throw Exception(typeid(*this), "Memory Error", "Image has been allocated.");
760 set(r.getCols(),r.getRows(), RGBA);
762 int rowmax = r.getRows();
763 int colmax = r.getCols();
764 for(int row=1; row<=rowmax; row++) {
765 for(int col=1; col<=colmax; col++) {
766 //colour.set(r(row,col), g(row,col), b(row,col), a(row,col));
767 pix_direct(col-1,row-1,r(row,col), g(row,col), b(row,col), a(row,col));
772 void Image::to(Matrix &mtx) const {
773 to(Point(0,0), getWidth(), getHeight(), mtx);
775 void Image::to(Point p, const Rectangle &rect, Matrix &gray) const {
776 to(Point(0,0), (int)rect.getWidth(), (int)rect.getHeight(), gray);
778 void Image::to(const Interval &horiz, const Interval &vert, Matrix &gray) const {
779 to(Point(horiz.int_floor(0), vert.int_floor(0)),
780 horiz.int_ceil(getWidth())-horiz.int_floor(0), vert.int_ceil(getHeight())-vert.int_floor(0),
783 void Image::to(Point p, int width_, int height_, Matrix &mtx) const {
786 double width = width_+p.x<getWidth() ? width_ : getWidth()-p.x;
787 double height = height_+p.y<getHeight() ? height_ : getHeight()-p.y;
788 if(pixcomp_!=GRAY) throw Exception(typeid(*this), "Argument Error", "Color types of Image(GRAY) and Matrix were not matched.");
789 if(!have_instance_) throw Exception(typeid(*this), "Memory Error", "Image had not allocated.");
790 if(width!=mtx.getCols() || height!=mtx.getRows()) { mtx.release(); mtx.set((int)height, (int)width); }
791 int rowmax = mtx.getRows(), colmax = mtx.getCols();
792 for(int row=1; row<=rowmax; row++) {
793 for(int col=1; col<=colmax; col++) {
794 colour = getPix((int)(p.x)+col-1, (int)(p.y)+row-1);
801 void Image::to(Matrix &r, Matrix &g, Matrix &b) const {
802 to(Point(0,0), getWidth(), getHeight(), r, g, b);
804 void Image::to(Point p, const Rectangle &rect, Matrix &r, Matrix &g, Matrix &b) const {
805 to(Point(0,0), (int)rect.getWidth(), (int)rect.getHeight(), r, g, b);
807 void Image::to(const Interval &horiz, const Interval &vert, Matrix &r, Matrix &g, Matrix &b) const {
808 to(Point(horiz.int_floor(0), vert.int_floor(0)),
809 horiz.int_ceil(getWidth())-horiz.int_floor(0), vert.int_ceil(getHeight())-vert.int_floor(0),
812 void Image::to(Point p, int width_, int height_, Matrix &r, Matrix &g, Matrix &b) const {
814 double rr, gg, bb, aa;
815 double width = width_+p.x<getWidth() ? width_ : getWidth()-p.x;
816 double height = height_+p.y<getHeight() ? height_ : getHeight()-p.y;
817 if(pixcomp_!=RGB) throw Exception(typeid(*this), "Argument Error", "Color types of Image(RGB) and Matrix were not matched.");
818 if(!have_instance_) throw Exception(typeid(*this), "Memory Error", "Image had not allocated.");
819 if(r.getRows()!=g.getRows() || r.getRows()!=b.getRows()) throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent between each color.");
820 if(r.getCols()!=g.getCols() || r.getCols()!=b.getCols()) throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent between each color.");
821 if(width!=r.getCols() || height!=r.getRows()) { r.release(); r.set((int)height, (int)width); }
822 if(width!=g.getCols() || height!=g.getRows()) { g.release(); g.set((int)height, (int)width); }
823 if(width!=b.getCols() || height!=b.getRows()) { b.release(); b.set((int)height, (int)width); }
824 int rowmax = r.getRows(), colmax = r.getCols();
825 for(int row=1; row<=rowmax; row++) {
826 for(int col=1; col<=colmax; col++) {
827 colour = getPix((int)(p.x)+col-1, (int)(p.y)+row-1);
828 colour.get(rr,gg,bb,aa);
836 void Image::to(Matrix &r, Matrix &g, Matrix &b, Matrix &a) const {
837 to(Point(0,0), getWidth(), getHeight(), r, g, b, a);
839 void Image::to(Point p, const Rectangle &rect, Matrix &r, Matrix &g, Matrix &b, Matrix &a) const {
840 to(Point(0,0), (int)rect.getWidth(), (int)rect.getHeight(), r, g, b, a);
842 void Image::to(const Interval &horiz, const Interval &vert, Matrix &r, Matrix &g, Matrix &b, Matrix &a) const {
843 to(Point(horiz.int_floor(0), vert.int_floor(0)),
844 horiz.int_ceil(getWidth())-horiz.int_floor(0), vert.int_ceil(getHeight())-vert.int_floor(0),
847 void Image::to(Point p, int width_, int height_, Matrix &r, Matrix &g, Matrix &b, Matrix &a) const {
849 double rr, gg, bb, aa;
850 double width = width_+p.x<getWidth() ? width_ : getWidth()-p.x;
851 double height = height_+p.y<getHeight() ? height_ : getHeight()-p.y;
852 if(pixcomp_!=RGBA) throw Exception(typeid(*this), "Argument Error", "Color types of Image(RGBA) and Matrix were not matched.");
853 if(!have_instance_) throw Exception(typeid(*this), "Memory Error", "Image had not allocated.");
854 if(r.getRows()!=g.getRows() || r.getRows()!=b.getRows() || r.getRows()!=a.getRows()) throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent between each color.");
855 if(r.getCols()!=g.getCols() || r.getCols()!=b.getCols() || r.getCols()!=a.getCols()) throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent between each color.");
856 if(width!=r.getCols() || height!=r.getRows()) { r.release(); r.set((int)height, (int)width); }
857 if(width!=g.getCols() || height!=g.getRows()) { g.release(); g.set((int)height, (int)width); }
858 if(width!=b.getCols() || height!=b.getRows()) { b.release(); b.set((int)height, (int)width); }
859 if(width!=a.getCols() || height!=a.getRows()) { a.release(); a.set((int)height, (int)width); }
860 int rowmax = r.getRows(), colmax = r.getCols();
861 for(int row=1; row<=rowmax; row++) {
862 for(int col=1; col<=colmax; col++) {
863 colour = getPix((int)(p.x)+col-1, (int)(p.y)+row-1);
864 colour.get(rr,gg,bb,aa);
874 Image & Image::operator -=(Image &rhs) {
875 if(pixcomp_!=rhs.pixcomp_) throw Exception(typeid(*this), "Format Error", "Difference must be resolved between same format Images.");
876 if(pixprec_!=rhs.pixprec_) throw Exception(typeid(*this), "Format Error", "Difference must be resolved between same format Images.");
877 if(width_!=rhs.width_) throw Exception(typeid(*this), "Format Error", "Difference must be resolved between same format Images.");
878 if(height_!=rhs.height_) throw Exception(typeid(*this), "Format Error", "Difference must be resolved between same format Images.");
880 unsigned char *pb=bitmapub_, *qb=rhs.bitmapub_;
881 float *pf=bitmapf_, *qf=bitmapf_;
885 for(int i=0; i<bitmapValue_; i++) {
887 if(pb[i]<0) pb[i] = -pb[i];
888 if(pb[i]>15) pb[i]=256; else pb[i]*=16;
892 for(int i=0; i<bitmapValue_; i++) {
894 if(pf[i]<0) pf[i] = -pf[i];
895 if(pf[i]>15) pf[i]=256; else pf[i]*=16;
902 namespace IMAGE_FORMATS {
\r
904 FILE_EXT getImageFileFormatFromExt(const std::string &s) {
\r
905 std::string ext = s;
\r
906 std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
\r
909 } else if(ext=="jpg") {
\r
911 } else if(ext=="jpeg") {
\r
913 } else if(ext=="jp2") {
\r
915 } else if(ext=="tiff") {
\r
917 } else if(ext=="cvmat") {
\r
919 } else if(ext=="mat") {
\r
927 IMAGE_FORMAT::~IMAGE_FORMAT() {
929 void IMAGE_FORMAT::readTargetMemoryAlignment(Image *target) {
930 target_bitmap_ub_ = target->bitmapub_;
931 target_bytes_per_line_ = target->lineBytes_;
932 pix_components_ = target->pixcomp_;
933 pix_precision_ = target->pixprec_;
937 } /* <- namespace Psycholops */