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;
110 _zoom_percentage_ = 100;
114 Image::~Image(void) {
117 void Image::release(){
119 if(!caches.empty()) {
120 std::vector<DrawableWithCache*> tmp;
121 for(CacheID::iterator i=caches.begin(); i!=caches.end(); i++) tmp.push_back(i->first);
122 for(int i=0; i<tmp.size(); i++) tmp[i]->uncacheImage(*this);
126 have_instance_ = false;
129 void Image::releasebitmap() {
133 if(bitmapub_ != NULL) delete [] bitmapub_;
136 if(bitmapf_ != NULL) delete [] bitmapf_;
142 bool Image::hasInstance() const {
143 return have_instance_;
146 Image& Image::cache(DrawableWithCache &target) {
147 target.cacheImage(*this);
150 Image& Image::uncache(DrawableWithCache &target) {
151 target.uncacheImage(*this);
155 Image Image::dup() const {
156 return Image(*this, true);
158 Image Image::duplicate() const {
159 return Image(*this, true);
161 Image& Image::convert(PixelComponentsCnt pixcompcntval) {
162 if(!have_instance_) throw Exception(typeid(*this), "Memory Error", "Image had not allocated.");
163 if(pixcomp_==pixcompcntval) {
166 Image *tmp = new Image;
169 set(tmp->width_, tmp->height_, pixcompcntval, tmp->pixprec_);
170 targetarea_ = tmp->targetarea_;
171 localarea_ = tmp->localarea_;
172 unsigned char *p = bitmapub_;
173 float *pf = bitmapf_;
176 for(int y=height_-1; y>=0; y--) {
177 for(int x=0; x<width_; x++) {
178 tmp->getPix(x,y).get(r, g, b, a);
179 *(p++) = (unsigned char)(r*255.0+.5);
180 if(pixcomp_==RGB||pixcomp_==RGBA) *(p++) = (unsigned char)(g*255.0+.5);
181 if(pixcomp_==RGB||pixcomp_==RGBA) *(p++) = (unsigned char)(b*255.0+.5);
182 if(pixcomp_==RGBA) { *(p++) = (unsigned char)(a*255.0+.5); }
186 for(int y=height_-1; y>=0; y--) {
187 for(int x=0; x<width_; x++) {
188 tmp->getPix(x,y).get(r, g, b, a);
190 if(pixcomp_==RGB||pixcomp_==RGBA) *(pf++) = g;
191 if(pixcomp_==RGB||pixcomp_==RGBA) *(pf++) = b;
192 if(pixcomp_==RGBA) { *(pf++) = a; }
196 //if(tmp->quickened_) quicken();
201 Image& Image::convertColorCalibration(bool on_off) {
204 if(!have_instance_) throw Exception(typeid(*this), "Memory Error", "Image had not allocated.");
205 Image *tmp = new Image;
208 set(tmp->width_, tmp->height_, tmp->pixcomp_, tmp->pixprec_);
209 targetarea_ = tmp->targetarea_;
210 localarea_ = tmp->localarea_;
212 for(int y=0; y<height_; y++) {
213 for(int x=0; x<width_; x++) {
220 tmp->pix_direct(x, y, col);
224 for(int y=0; y<height_; y++) {
225 for(int x=0; x<width_; x++) {
226 getPix(x, y).get(r,g,b,a);
231 tmp->pix_direct(x, y, col);
235 //if(tmp->quickened_) quicken();
242 //////// Drawing ////////
244 void Image::pix_ub_bits_mono_(int ix, int iy, double lum) {
246 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.");
247 int offset = y*lineValue_ + x*PixCompSize_[pixcomp_];
248 unsigned char *p = bitmapub_ + offset;
249 unsigned short wordlum = (unsigned short)(lum*65535);
250 *(p) = (unsigned char)(wordlum>>8);
251 *(++p) = (unsigned char)(wordlum&255);
252 *(++p) = (unsigned char)0;
255 Image& Image::_zoom_(const double percentage) {
\r
256 _zoom_percentage_ = percentage;
\r
257 targetarea_.resize(width_*(percentage/100.0), height_*(percentage/100.0));
\r
260 Image& Image::alpha(const double a)
262 for(int y=0; y<getHeight(); y++)
263 for(int x=0; x<getWidth(); x++)
267 Image& Image::alpha(const Matrix &a)
269 if(getWidth()!=a.getCols() || getHeight()!=a.getRows() || pixcomp_!=Image::RGBA)
270 throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent to Image");
271 for(int y=0; y<getHeight(); y++)
272 for(int x=0; x<getWidth(); x++)
273 alpha(x,y,a(y+1,x+1));
276 Image& Image::clear(const Color &col) {
278 //for(int y=0; y<height_; y++) {
279 // for(int x=0; x<width_; x++) {
280 // pix_direct_(*this,x,y,col);
286 pix_raw(0, getHeight()-1, col);
288 if(pixprec_ == Image::BYTE) {
289 if(pixcomp_ == Image::GRAY) {
291 for(x=0; x<width_; x++) {
292 (*pb++) = *(bitmapub_);
294 } else if(pixcomp_ == Image::RGB) {
296 for(x=0; x<width_; x++) {
297 (*pb++) = *(bitmapub_);
298 (*pb++) = *(bitmapub_+1);
299 (*pb++) = *(bitmapub_+2);
301 } else if(pixcomp_ == Image::RGBA) {
303 for(x=0; x<width_; x++) {
304 (*pb++) = *(bitmapub_);
305 (*pb++) = *(bitmapub_+1);
306 (*pb++) = *(bitmapub_+2);
307 (*pb++) = *(bitmapub_+3);
310 for(y=1; y<height_; y++) {
313 memcpy(pb, bitmapub_, lineValue_);
315 } else if(pixprec_ == Image::FLOAT) {
316 if(pixcomp_ == Image::GRAY) {
318 for(x=0; x<width_; x++) {
319 (*pf++) = *(bitmapf_);
321 } else if(pixcomp_ == Image::RGB) {
323 for(x=0; x<width_; x++) {
324 (*pf++) = *(bitmapf_);
325 (*pf++) = *(bitmapf_+1);
326 (*pf++) = *(bitmapf_+2);
328 } else if(pixcomp_ == Image::RGBA) {
330 for(x=0; x<width_; x++) {
331 (*pf++) = *(bitmapf_);
332 (*pf++) = *(bitmapf_+1);
333 (*pf++) = *(bitmapf_+2);
334 (*pf++) = *(bitmapf_+3);
337 for(y=1; y<height_; y++) {
340 memcpy(pf, bitmapf_, lineBytes_);
345 /* Image& Image::alpha(const int x, const int iy, const double a) {
350 Image& Image::pix(const double x, const double y, const Color &col) {
351 pix(Math::round(x), Math::round(y), col);
354 Image& Image::pix(const Point &po, const Color &col) {
355 pix(Math::round(po.x), Math::round(po.y), col);
359 void Image::rect(const Rectangle &rectangle, const Color &col) {
360 Rectangle filledrect(rectangle);
361 filledrect.cripped(area_);
362 int t = Math::round(filledrect.top);
363 int b = Math::round(filledrect.bottom);
364 int l = Math::round(filledrect.left);
365 int r = Math::round(filledrect.right);
366 for(int y=t; y<=b; y++) {
367 for(int x=l; x<=r; x++) {
372 void Image::line(const double x1, const double y1, const double x2, const double y2, const Color &col) {
373 int begin, end, tbegin, ax, ay;
376 double slope = (y1-y2)/(x1-x2);
377 if(slope<1 && slope>-1) {
379 tbegin = begin = Math::round(x1);
380 end = Math::round(x2);
383 tbegin = begin = Math::round(x2);
384 end = Math::round(x1);
387 begin = ( begin<0 ? 0 : begin );
388 end = ( end>width_-1 ? width_-1 : end );
389 for(int x=begin; x<=end; x++) {
390 ay = Math::round((x-tbegin)*slope + obegin);
391 if(-1<x && x<width_ && -1 <ay && ay<height_ ) pix(x, ay, col);
395 tbegin = begin = Math::round(y1);
396 end = Math::round(y2);
399 tbegin = begin = Math::round(y2);
400 end = Math::round(y1);
403 begin = ( begin<0 ? 0 : begin );
404 end = ( end>height_-1 ? height_-1 : end );
405 for(int y=begin; y<=end; y++) {
406 ax = Math::round((y-tbegin)/slope + obegin);
407 if(-1<ax && ax<width_ && -1<y && y<height_ ) pix(ax, y, col);
412 tbegin = begin = Math::round(y1);
413 end = Math::round(y2);
416 tbegin = begin = Math::round(y2);
417 end = Math::round(y1);
420 begin = ( begin<0 ? 0 : begin );
421 end = ( end>height_-1 ? height_-1 : end );
422 ax = Math::round(obegin);
423 for(int y=begin; y<=end; y++) {
424 if(-1<ax && ax<width_ && -1<y && y<height_ ) pix(ax, y, col);
428 void Image::line(const Point &po1, const Point &po2, const Color &col) {
429 line(po1.x, po1.y, po2.x, po2.y, col);
431 void Image::ellipse(const Rectangle &rect, const Color &col) {
432 double center_x = rect.getCenter().x;
433 double center_y = rect.getCenter().y;
434 double radius = rect.getHeight() / 2.0;
435 double aspect_ratio = rect.getWidth() / rect.getHeight();
438 t = ( rect.top < 0 ? 0 : Math::round(rect.top) );
439 b = ( rect.bottom > height_-1 ? height_-1 : Math::round(rect.bottom) );
440 for(int y=t; y<=b; y++) {
441 tmp = ( (y-center_y)/radius );
442 l = Math::round( center_x - aspect_ratio * ( radius * sqrt(1-(tmp*tmp)) ) );
443 r = Math::round( ( center_x - l ) + center_x );
444 l = ( l < 0 ? 0 : l );
445 r = ( r > width_-1 ? width_-1 : r );
446 for(int x=l; x<=r; x++) {
452 void Image::oval(const Rectangle &rect, const Color &col) {
455 void Image::fillRect(const Rectangle &rectangle, const Color &col) {
456 rect(rectangle, col);
458 /* void Image::msg(Letters &letters, int x, int y, const Color &col) {
459 api_->drawLetters(letters, x, y,col.Red,col.Blue,col.Green,col.Alpha,0,0);
463 Image& Image::draw(double left, double top, Drawable &target) {
464 target.image(*this, left, top);
467 Image& Image::draw(Drawable &target) {
471 Image& Image::draw(double alpha, Drawable &target) {
472 target.image(*this, alpha);
476 void Image::display(double x, double y) {
479 void Image::display() {
480 draw(targetarea_.left, targetarea_.top);
484 Image::PartialView::PartialView(Image *src, const Rectangle &d_source)
488 target.set(source.getWidth(), source.getHeight());
490 Image::PartialView& Image::PartialView::set(double width, double height)
492 target.set(width, height);
495 Image::PartialView::~PartialView()
498 const Point Image::PartialView::getDatum() const
500 return target.getDatum();
502 Image::PartialView& Image::PartialView::setDatum(const Point &p)
507 Image::PartialView& Image::PartialView::centering(const Point &p)
512 Image::PartialView& Image::PartialView::draw(Drawable &target_)
514 target_.image(*img, target, source);
517 Image::PartialView Image::operator ()(const Rectangle &view)
519 PartialView tmp(this, view);
526 // get bitmap properties
527 const void * Image::getBitmapPtr() const {
528 if(!have_instance_) Exception(typeid(*this), "Memory Error", "The Image does not have bitmap instance.");
531 return (void *)bitmapub_;
534 return (void *)bitmapf_;
544 const Point Image::getDatum() const {
545 return targetarea_.getDatum();
547 Image& Image::setDatum(const Point& p) {
548 targetarea_.setDatum(p);
551 Image& Image::centering(const Drawable& target) {
552 targetarea_.centering(target);
555 Image& Image::centering(const Figure& fig) {
556 targetarea_.centering(fig);
559 Image& Image::centering(const Point& p) {
560 targetarea_.centering(p);
563 Image& Image::centering(const double x, const double y, const double z) {
564 targetarea_.centering(x, y, z);
567 Image& Image::move_to(const double x, const double y, const double z) {
568 targetarea_.move_to(x, y, z);
571 Image& Image::shift(const double x, const double y, const double z) {
572 targetarea_.shift(x, y, z);
575 int Image::getWidth() const { return width_; }
576 int Image::getHeight() const { return height_; }
577 double Image::getHcenter() const { return width_/2 - 0.5; }
578 double Image::getVcenter() const { return height_/2 - 0.5; }
579 const Point Image::getCenter() const {
580 Point po(getHcenter(), getVcenter());
583 double Image::getTop() const { return targetarea_.top; }
584 double Image::getLeft() const { return targetarea_.left; }
585 double Image::getBottom() const { return targetarea_.bottom; }
586 double Image::getRight() const { return targetarea_.right; }
589 float* Image::getFloatPrt() { return bitmapf_; }
590 unsigned char* Image::getElementPtr() { return bitmapub_; }
591 int Image::getPixBytes() { return pixBytes_; }
592 int Image::getLineBytes() { return lineBytes_; }
593 int Image::getBitmapBytes() { return bitmapBytes_; }
594 int Image::getLineNumber() { return lineValue_; }
595 int Image::getElementNumber() { return bitmapValue_; }
596 const Image::PixelComponentsCnt Image::getComponentKind() const { return pixcomp_; }
\r
597 const Image::PixelComponentsPrecision Image::getPrecisionKind() const { return pixprec_; }
599 //// Special Utilities
601 void Image::to(const Rectangle &source__, Image &other, const Rectangle target__) const {
602 Rectangle source = source__, target = target__;
603 source.clipped_by(area_);
604 target.clipped_by(other.area_);
605 if(source.getWidth()!=target.getWidth() || source.getHeight()!=target.getHeight())
606 throw new Exception("Image.to: source area does not match target area.");
607 int sl = (int)source.getLeft(), st=(int)source.getTop(), tl=(int)target.getLeft(), tt=(int)target.getTop();
608 for(int y=0; y<source.getHeight(); y++)
609 for(int x=0; x<source.getWidth(); x++)
610 other.pix_direct(x+tl,y+tt, getPix(x+sl,y+st));
612 void Image::to(const Rectangle &source__, Image &other) const {
613 Rectangle source = source__;
614 source.clipped_by(area_);
616 other.set(source, pixcomp_, pixprec_);
617 for(int y=0; y<other.getHeight(); y++)
618 for(int x=0; x<other.getWidth(); x++)
619 other.pix_direct(x,y, getPix((int)(source.getLeft())+x, (int)(source.getTop())+y));
621 int vbase = getHeight() - source.getTop();
622 for(int i=0; i<other.getHeight(); i++) {
623 memcpy(other.bitmapub_+(other.getHeight()-i-1)*(lineBytes_),
624 bitmapub_+(vbase-i-1)*(lineBytes_)+(size_t)(source.getLeft()),
625 pixBytes_*other.getWidth());
631 void Image::load(std::string filename) {
632 IMAGE_FORMATS::IMAGE_FORMAT *loader;
636 std::string::size_type extention_index = filename.find_last_of('.');
637 if(extention_index==std::string::npos) throw Exception(typeid(*this), "File Type Error", "Specified image type is not supported.*..");
638 std::string file_extension = filename.substr(extention_index+1);
\r
639 IMAGE_FORMATS::FILE_EXT ext = IMAGE_FORMATS::getImageFileFormatFromExt(file_extension);
\r
640 if(ext==IMAGE_FORMATS::PNG) {
641 loader = new IMAGE_FORMATS::PNG_BRIDGE;
642 loader->load(File::decodePath(filename).c_str(), this);
644 } else if(ext==IMAGE_FORMATS::JPG) {
645 loader = new IMAGE_FORMATS::OPENCV_BRIDGE;
646 loader->load(File::decodePath(filename).c_str(), this);
648 } else if(ext==IMAGE_FORMATS::TIFF) {
649 loader = new IMAGE_FORMATS::OPENCV_BRIDGE;
650 loader->load(File::decodePath(filename).c_str(), this);
653 throw Exception(typeid(*this), "File Type Error", "Specified image type is not supported.");
655 switch(Color::getCalibrationMode()) {
656 case Color::SOFTWARE_GAMMA_VALUE:
657 case Color::SOFTWARE_TABLE:
658 convertColorCalibration(true);
664 void Image::load(const char * filename) {
665 load(std::string(filename));
667 void Image::save(std::string filename) {
668 IMAGE_FORMATS::IMAGE_FORMAT *loader;
669 if(!have_instance_) {
670 throw Exception(typeid(*this), "Memory Error", "Image does not have its instance.");
676 switch(Color::getCalibrationMode()) {
677 case Color::SOFTWARE_GAMMA_VALUE:
678 case Color::SOFTWARE_TABLE:
679 tmp = new Image(width_, height_, pixcomp_, pixprec_);
680 for(int y=0; y<height_; y++) {
681 for(int x=0; x<width_; x++) {
688 tmp->pix_direct(x, y, col);
697 std::string::size_type extention_index = filename.find_last_of('.');
698 if(extention_index==std::string::npos) throw Exception(typeid(*this), "File Type Error", "Specified image type is not supported.");
699 std::string file_extension = filename.substr(extention_index+1);
\r
700 IMAGE_FORMATS::FILE_EXT ext = IMAGE_FORMATS::getImageFileFormatFromExt(file_extension);
701 if(ext==IMAGE_FORMATS::PNG) {
702 loader = new IMAGE_FORMATS::PNG_BRIDGE;
703 loader->save(File::decodePath(filename).c_str(), tmp);
705 } else if(ext==IMAGE_FORMATS::JPG) {
706 loader = new IMAGE_FORMATS::OPENCV_BRIDGE;
707 loader->save(File::decodePath(filename).c_str(), tmp);
709 } else if(ext==IMAGE_FORMATS::TIFF) {
710 loader = new IMAGE_FORMATS::OPENCV_BRIDGE;
711 loader->save(File::decodePath(filename).c_str(), tmp);
714 throw Exception(typeid(*this), "File Type Error", "Specified image type is not supported.");
716 if(tmp != this) delete tmp;
718 void Image::save(const char * filename) {
719 save(std::string(filename));
722 void Image::from(const Matrix &mtx) {
724 if(getWidth()!=mtx.getCols() || getHeight()!=mtx.getRows() || pixcomp_!=Image::GRAY) {
725 //if (have_instance_==false) set(mtx.getCols(),mtx.getRows(), GRAY);
726 //else throw Exception(typeid(*this), "Memory Error", "Image has been allocated.");
728 set(mtx.getCols(),mtx.getRows(), GRAY);
730 int rowmax = mtx.getRows();
731 int colmax = mtx.getCols();
732 for(int row=1; row<=rowmax; row++) {
733 for(int col=1; col<=colmax; col++) {
734 //colour.set(mtx(row,col));
735 pix_direct(col-1,row-1,mtx(row,col));
739 void Image::from(const Matrix &r, const Matrix &g, const Matrix &b) {
741 if(r.getRows()!=g.getRows() || r.getRows()!=b.getRows()) throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent between each color.");
742 if(r.getCols()!=g.getCols() || r.getCols()!=b.getCols()) throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent between each color.");
743 if(getWidth()!=r.getCols() || getHeight()!=r.getRows() || pixcomp_!=Image::RGB) {
744 //if (have_instance_==false) set(r.getCols(),r.getRows(), RGB);
745 //else throw Exception(typeid(*this), "Memory Error", "Image has been allocated.");
747 set(r.getCols(),r.getRows(), RGB);
749 int rowmax = r.getRows();
750 int colmax = r.getCols();
751 for(int row=1; row<=rowmax; row++) {
752 for(int col=1; col<=colmax; col++) {
753 //colour.set(r(row,col), g(row,col), b(row,col));
754 pix_direct(col-1,row-1,r(row,col), g(row,col), b(row,col),1.0);
758 void Image::from(const Matrix &r, const Matrix &g, const Matrix &b, const Matrix &a) {
760 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.");
761 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.");
762 if(getWidth()!=r.getCols() || getHeight()!=r.getRows() || pixcomp_!=Image::RGBA) {
763 //if (have_instance_==false) set(r.getCols(),r.getRows(), RGBA);
764 //else throw Exception(typeid(*this), "Memory Error", "Image has been allocated.");
766 set(r.getCols(),r.getRows(), RGBA);
768 int rowmax = r.getRows();
769 int colmax = r.getCols();
770 for(int row=1; row<=rowmax; row++) {
771 for(int col=1; col<=colmax; col++) {
772 //colour.set(r(row,col), g(row,col), b(row,col), a(row,col));
773 pix_direct(col-1,row-1,r(row,col), g(row,col), b(row,col), a(row,col));
778 void Image::to(Matrix &mtx) const {
779 to(Point(0,0), getWidth(), getHeight(), mtx);
781 void Image::to(Point p, const Rectangle &rect, Matrix &gray) const {
782 to(Point(0,0), (int)rect.getWidth(), (int)rect.getHeight(), gray);
784 void Image::to(const Interval &horiz, const Interval &vert, Matrix &gray) const {
785 to(Point(horiz.int_floor(0), vert.int_floor(0)),
786 horiz.int_ceil(getWidth())-horiz.int_floor(0), vert.int_ceil(getHeight())-vert.int_floor(0),
789 void Image::to(Point p, int width_, int height_, Matrix &mtx) const {
792 double width = width_+p.x<getWidth() ? width_ : getWidth()-p.x;
793 double height = height_+p.y<getHeight() ? height_ : getHeight()-p.y;
794 if(pixcomp_!=GRAY) throw Exception(typeid(*this), "Argument Error", "Color types of Image(GRAY) and Matrix were not matched.");
795 if(!have_instance_) throw Exception(typeid(*this), "Memory Error", "Image had not allocated.");
796 if(width!=mtx.getCols() || height!=mtx.getRows()) { mtx.release(); mtx.set((int)height, (int)width); }
797 int rowmax = mtx.getRows(), colmax = mtx.getCols();
798 for(int row=1; row<=rowmax; row++) {
799 for(int col=1; col<=colmax; col++) {
800 colour = getPix((int)(p.x)+col-1, (int)(p.y)+row-1);
807 void Image::to(Matrix &r, Matrix &g, Matrix &b) const {
808 to(Point(0,0), getWidth(), getHeight(), r, g, b);
810 void Image::to(Point p, const Rectangle &rect, Matrix &r, Matrix &g, Matrix &b) const {
811 to(Point(0,0), (int)rect.getWidth(), (int)rect.getHeight(), r, g, b);
813 void Image::to(const Interval &horiz, const Interval &vert, Matrix &r, Matrix &g, Matrix &b) const {
814 to(Point(horiz.int_floor(0), vert.int_floor(0)),
815 horiz.int_ceil(getWidth())-horiz.int_floor(0), vert.int_ceil(getHeight())-vert.int_floor(0),
818 void Image::to(Point p, int width_, int height_, Matrix &r, Matrix &g, Matrix &b) const {
820 double rr, gg, bb, aa;
821 double width = width_+p.x<getWidth() ? width_ : getWidth()-p.x;
822 double height = height_+p.y<getHeight() ? height_ : getHeight()-p.y;
823 if(pixcomp_!=RGB) throw Exception(typeid(*this), "Argument Error", "Color types of Image(RGB) and Matrix were not matched.");
824 if(!have_instance_) throw Exception(typeid(*this), "Memory Error", "Image had not allocated.");
825 if(r.getRows()!=g.getRows() || r.getRows()!=b.getRows()) throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent between each color.");
826 if(r.getCols()!=g.getCols() || r.getCols()!=b.getCols()) throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent between each color.");
827 if(width!=r.getCols() || height!=r.getRows()) { r.release(); r.set((int)height, (int)width); }
828 if(width!=g.getCols() || height!=g.getRows()) { g.release(); g.set((int)height, (int)width); }
829 if(width!=b.getCols() || height!=b.getRows()) { b.release(); b.set((int)height, (int)width); }
830 int rowmax = r.getRows(), colmax = r.getCols();
831 for(int row=1; row<=rowmax; row++) {
832 for(int col=1; col<=colmax; col++) {
833 colour = getPix((int)(p.x)+col-1, (int)(p.y)+row-1);
834 colour.get(rr,gg,bb,aa);
842 void Image::to(Matrix &r, Matrix &g, Matrix &b, Matrix &a) const {
843 to(Point(0,0), getWidth(), getHeight(), r, g, b, a);
845 void Image::to(Point p, const Rectangle &rect, Matrix &r, Matrix &g, Matrix &b, Matrix &a) const {
846 to(Point(0,0), (int)rect.getWidth(), (int)rect.getHeight(), r, g, b, a);
848 void Image::to(const Interval &horiz, const Interval &vert, Matrix &r, Matrix &g, Matrix &b, Matrix &a) const {
849 to(Point(horiz.int_floor(0), vert.int_floor(0)),
850 horiz.int_ceil(getWidth())-horiz.int_floor(0), vert.int_ceil(getHeight())-vert.int_floor(0),
853 void Image::to(Point p, int width_, int height_, Matrix &r, Matrix &g, Matrix &b, Matrix &a) const {
855 double rr, gg, bb, aa;
856 double width = width_+p.x<getWidth() ? width_ : getWidth()-p.x;
857 double height = height_+p.y<getHeight() ? height_ : getHeight()-p.y;
858 if(pixcomp_!=RGBA) throw Exception(typeid(*this), "Argument Error", "Color types of Image(RGBA) and Matrix were not matched.");
859 if(!have_instance_) throw Exception(typeid(*this), "Memory Error", "Image had not allocated.");
860 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.");
861 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.");
862 if(width!=r.getCols() || height!=r.getRows()) { r.release(); r.set((int)height, (int)width); }
863 if(width!=g.getCols() || height!=g.getRows()) { g.release(); g.set((int)height, (int)width); }
864 if(width!=b.getCols() || height!=b.getRows()) { b.release(); b.set((int)height, (int)width); }
865 if(width!=a.getCols() || height!=a.getRows()) { a.release(); a.set((int)height, (int)width); }
866 int rowmax = r.getRows(), colmax = r.getCols();
867 for(int row=1; row<=rowmax; row++) {
868 for(int col=1; col<=colmax; col++) {
869 colour = getPix((int)(p.x)+col-1, (int)(p.y)+row-1);
870 colour.get(rr,gg,bb,aa);
880 Image & Image::operator -=(Image &rhs) {
881 if(pixcomp_!=rhs.pixcomp_) throw Exception(typeid(*this), "Format Error", "Difference must be resolved between same format Images.");
882 if(pixprec_!=rhs.pixprec_) throw Exception(typeid(*this), "Format Error", "Difference must be resolved between same format Images.");
883 if(width_!=rhs.width_) throw Exception(typeid(*this), "Format Error", "Difference must be resolved between same format Images.");
884 if(height_!=rhs.height_) throw Exception(typeid(*this), "Format Error", "Difference must be resolved between same format Images.");
886 unsigned char *pb=bitmapub_, *qb=rhs.bitmapub_;
887 float *pf=bitmapf_, *qf=bitmapf_;
891 for(int i=0; i<bitmapValue_; i++) {
893 if(pb[i]<0) pb[i] = -pb[i];
894 if(pb[i]>15) pb[i]=256; else pb[i]*=16;
898 for(int i=0; i<bitmapValue_; i++) {
900 if(pf[i]<0) pf[i] = -pf[i];
901 if(pf[i]>15) pf[i]=256; else pf[i]*=16;
908 namespace IMAGE_FORMATS {
\r
910 FILE_EXT getImageFileFormatFromExt(const std::string &s) {
\r
911 std::string ext = s;
\r
912 std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
\r
915 } else if(ext=="jpg") {
\r
917 } else if(ext=="jpeg") {
\r
919 } else if(ext=="jp2") {
\r
921 } else if(ext=="tiff") {
\r
923 } else if(ext=="cvmat") {
\r
925 } else if(ext=="mat") {
\r
933 IMAGE_FORMAT::~IMAGE_FORMAT() {
935 void IMAGE_FORMAT::readTargetMemoryAlignment(Image *target) {
936 target_bitmap_ub_ = target->bitmapub_;
937 target_bytes_per_line_ = target->lineBytes_;
938 pix_components_ = target->pixcomp_;
939 pix_precision_ = target->pixprec_;
943 } /* <- namespace Psycholops */