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"
31 #include "../../extension/FileFormat/JPEG/psychlops_g_JPEG_bridge.h"
37 ImageCache_::ImageCache_() : id(0), dirty(false) {}
38 ImageCache_::ImageCache_(APIImageCache* id__, bool dirty__) : id(id__), dirty(dirty__) {}
40 const int Image::PixCompSize_[3] = { 1, 3, 4 };
41 const int Image::PixPrecSize_[2] = { sizeof(unsigned char), sizeof(float) };
42 int Image::lineBytesAlingnment_ = AppState::ImageByteAlignment;
45 Image& Image::operator =(const Image &source) {
46 memcpy(this, &source, sizeof(*this));
49 Image::Image(const Image &readimage){}
50 Image::Image(const Image &readimage, bool dummt) {
57 //////// Construst and Destruct ////////
63 Image::Image(std::string filename) {
67 Image::Image(const char * filename) {
71 Image::Image(long x, long y, PixelComponentsCnt pixcomp, PixelComponentsPrecision pixprec) {
73 set(x, y, pixcomp, pixprec);
75 Image::Image(long x, long y, PixelComponentsPrecision pixprec) {
77 set(x, y, RGB, pixprec);
79 Image::Image(Rectangle rectangle, PixelComponentsCnt pixcomp, PixelComponentsPrecision pixprec) {
81 set(rectangle, pixcomp, pixprec);
83 Image::Image(Rectangle rectangle, PixelComponentsPrecision pixprec) {
85 set(rectangle, RGB, pixprec);
88 void Image::setWithoutClear(bool y)
92 bool Image::setWithoutClear_ = false; // OK?
94 void Image::set(long x, long y, PixelComponentsPrecision pixprec) {
95 set(x, y, RGB, pixprec);
97 void Image::set(Rectangle rectangle, PixelComponentsCnt pixcomp, PixelComponentsPrecision pixprec) {
98 set((long)rectangle.getWidth(), (long)rectangle.getHeight(), pixcomp, pixprec);
100 void Image::set(Rectangle rectangle, PixelComponentsPrecision pixprec) {
101 set(rectangle, RGB, pixprec);
103 void Image::initPointersNull() {
104 have_instance_ = false;
105 //quickened_ = false;
115 Image::~Image(void) {
118 void Image::release(){
120 if(!caches.empty()) {
121 std::vector<DrawableWithCache*> tmp;
122 for(CacheID::iterator i=caches.begin(); i!=caches.end(); i++) tmp.push_back(i->first);
123 for(int i=0; i<tmp.size(); i++) tmp[i]->uncacheImage(*this);
127 have_instance_ = false;
130 void Image::releasebitmap() {
134 if(bitmapub_ != NULL) delete [] bitmapub_;
137 if(bitmapf_ != NULL) delete [] bitmapf_;
143 bool Image::hasInstance() const {
144 return have_instance_;
147 Image& Image::cache(DrawableWithCache &target) {
148 target.cacheImage(*this);
151 Image& Image::uncache(DrawableWithCache &target) {
152 target.uncacheImage(*this);
156 Image Image::dup() const {
157 return Image(*this, true);
159 Image Image::duplicate() const {
160 return Image(*this, true);
162 Image& Image::convert(PixelComponentsCnt pixcompcntval) {
163 if(!have_instance_) throw Exception(typeid(*this), "Memory Error", "Image had not allocated.");
164 if(pixcomp_==pixcompcntval) {
167 Image *tmp = new Image;
170 set(tmp->width_, tmp->height_, pixcompcntval, tmp->pixprec_);
171 targetarea_ = tmp->targetarea_;
172 localarea_ = tmp->localarea_;
173 unsigned char *p = bitmapub_;
174 float *pf = bitmapf_;
177 for(int y=height_-1; y>=0; y--) {
178 for(int x=0; x<width_; x++) {
179 tmp->getPix(x,y).get(r, g, b, a);
180 *(p++) = (unsigned char)(r*255.0+.5);
181 if(pixcomp_==RGB||pixcomp_==RGBA) *(p++) = (unsigned char)(g*255.0+.5);
182 if(pixcomp_==RGB||pixcomp_==RGBA) *(p++) = (unsigned char)(b*255.0+.5);
183 if(pixcomp_==RGBA) { *(p++) = (unsigned char)(a*255.0+.5); }
187 for(int y=height_-1; y>=0; y--) {
188 for(int x=0; x<width_; x++) {
189 tmp->getPix(x,y).get(r, g, b, a);
191 if(pixcomp_==RGB||pixcomp_==RGBA) *(pf++) = g;
192 if(pixcomp_==RGB||pixcomp_==RGBA) *(pf++) = b;
193 if(pixcomp_==RGBA) { *(pf++) = a; }
197 //if(tmp->quickened_) quicken();
202 Image& Image::convertColorCalibration(bool on_off) {
205 if(!have_instance_) throw Exception(typeid(*this), "Memory Error", "Image had not allocated.");
206 Image *tmp = new Image;
209 set(tmp->width_, tmp->height_, tmp->pixcomp_, tmp->pixprec_);
210 targetarea_ = tmp->targetarea_;
211 localarea_ = tmp->localarea_;
213 for(int y=0; y<height_; y++) {
214 for(int x=0; x<width_; x++) {
221 tmp->pix_direct(x, y, col);
225 for(int y=0; y<height_; y++) {
226 for(int x=0; x<width_; x++) {
227 getPix(x, y).get(r,g,b,a);
232 tmp->pix_direct(x, y, col);
236 //if(tmp->quickened_) quicken();
243 //////// Drawing ////////
245 void Image::pix_ub_bits_mono_(int ix, int iy, double lum) {
247 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.");
248 int offset = y*lineValue_ + x*PixCompSize_[pixcomp_];
249 unsigned char *p = bitmapub_ + offset;
250 unsigned short wordlum = (unsigned short)(lum*65535);
251 *(p) = (unsigned char)(wordlum>>8);
252 *(++p) = (unsigned char)(wordlum&255);
253 *(++p) = (unsigned char)0;
256 Image& Image::alpha(const double a)
258 for(int y=0; y<getHeight(); y++)
259 for(int x=0; x<getWidth(); x++)
263 Image& Image::alpha(const Matrix &a)
265 if(getWidth()!=a.getCols() || getHeight()!=a.getRows() || pixcomp_!=Image::RGBA)
266 throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent to Image");
267 for(int y=0; y<getHeight(); y++)
268 for(int x=0; x<getWidth(); x++)
269 alpha(x,y,a(y+1,x+1));
272 Image& Image::clear(const Color &col) {
274 //for(int y=0; y<height_; y++) {
275 // for(int x=0; x<width_; x++) {
276 // pix_direct_(*this,x,y,col);
282 pix_raw(0, getHeight()-1, col);
284 if(pixprec_ == Image::BYTE) {
285 if(pixcomp_ == Image::GRAY) {
287 for(x=0; x<width_; x++) {
288 (*pb++) = *(bitmapub_);
290 } else if(pixcomp_ == Image::RGB) {
292 for(x=0; x<width_; x++) {
293 (*pb++) = *(bitmapub_);
294 (*pb++) = *(bitmapub_+1);
295 (*pb++) = *(bitmapub_+2);
297 } else if(pixcomp_ == Image::RGBA) {
299 for(x=0; x<width_; x++) {
300 (*pb++) = *(bitmapub_);
301 (*pb++) = *(bitmapub_+1);
302 (*pb++) = *(bitmapub_+2);
303 (*pb++) = *(bitmapub_+3);
306 for(y=1; y<height_; y++) {
309 memcpy(pb, bitmapub_, lineValue_);
311 } else if(pixprec_ == Image::FLOAT) {
312 if(pixcomp_ == Image::GRAY) {
314 for(x=0; x<width_; x++) {
315 (*pf++) = *(bitmapf_);
317 } else if(pixcomp_ == Image::RGB) {
319 for(x=0; x<width_; x++) {
320 (*pf++) = *(bitmapf_);
321 (*pf++) = *(bitmapf_+1);
322 (*pf++) = *(bitmapf_+2);
324 } else if(pixcomp_ == Image::RGBA) {
326 for(x=0; x<width_; x++) {
327 (*pf++) = *(bitmapf_);
328 (*pf++) = *(bitmapf_+1);
329 (*pf++) = *(bitmapf_+2);
330 (*pf++) = *(bitmapf_+3);
333 for(y=1; y<height_; y++) {
336 memcpy(pf, bitmapf_, lineBytes_);
341 /* Image& Image::alpha(const int x, const int iy, const double a) {
346 Image& Image::pix(const double x, const double y, const Color &col) {
347 pix(Math::round(x), Math::round(y), col);
350 Image& Image::pix(const Point &po, const Color &col) {
351 pix(Math::round(po.x), Math::round(po.y), col);
355 void Image::rect(const Rectangle &rectangle, const Color &col) {
356 Rectangle filledrect(rectangle);
357 filledrect.cripped(area_);
358 int t = Math::round(filledrect.top);
359 int b = Math::round(filledrect.bottom);
360 int l = Math::round(filledrect.left);
361 int r = Math::round(filledrect.right);
362 for(int y=t; y<=b; y++) {
363 for(int x=l; x<=r; x++) {
368 void Image::line(const double x1, const double y1, const double x2, const double y2, const Color &col) {
369 int begin, end, tbegin, ax, ay;
372 double slope = (y1-y2)/(x1-x2);
373 if(slope<1 && slope>-1) {
375 tbegin = begin = Math::round(x1);
376 end = Math::round(x2);
379 tbegin = begin = Math::round(x2);
380 end = Math::round(x1);
383 begin = ( begin<0 ? 0 : begin );
384 end = ( end>width_-1 ? width_-1 : end );
385 for(int x=begin; x<=end; x++) {
386 ay = Math::round((x-tbegin)*slope + obegin);
387 if(-1<x && x<width_ && -1 <ay && ay<height_ ) pix(x, ay, col);
391 tbegin = begin = Math::round(y1);
392 end = Math::round(y2);
395 tbegin = begin = Math::round(y2);
396 end = Math::round(y1);
399 begin = ( begin<0 ? 0 : begin );
400 end = ( end>height_-1 ? height_-1 : end );
401 for(int y=begin; y<=end; y++) {
402 ax = Math::round((y-tbegin)/slope + obegin);
403 if(-1<ax && ax<width_ && -1<y && y<height_ ) pix(ax, y, col);
408 tbegin = begin = Math::round(y1);
409 end = Math::round(y2);
412 tbegin = begin = Math::round(y2);
413 end = Math::round(y1);
416 begin = ( begin<0 ? 0 : begin );
417 end = ( end>height_-1 ? height_-1 : end );
418 ax = Math::round(obegin);
419 for(int y=begin; y<=end; y++) {
420 if(-1<ax && ax<width_ && -1<y && y<height_ ) pix(ax, y, col);
424 void Image::line(const Point &po1, const Point &po2, const Color &col) {
425 line(po1.x, po1.y, po2.x, po2.y, col);
427 void Image::ellipse(const Rectangle &rect, const Color &col) {
428 double center_x = rect.getCenter().x;
429 double center_y = rect.getCenter().y;
430 double radius = rect.getHeight() / 2.0;
431 double aspect_ratio = rect.getWidth() / rect.getHeight();
434 t = ( rect.top < 0 ? 0 : Math::round(rect.top) );
435 b = ( rect.bottom > height_-1 ? height_-1 : Math::round(rect.bottom) );
436 for(int y=t; y<=b; y++) {
437 tmp = ( (y-center_y)/radius );
438 l = Math::round( center_x - aspect_ratio * ( radius * sqrt(1-(tmp*tmp)) ) );
439 r = Math::round( ( center_x - l ) + center_x );
440 l = ( l < 0 ? 0 : l );
441 r = ( r > width_-1 ? width_-1 : r );
442 for(int x=l; x<=r; x++) {
448 void Image::oval(const Rectangle &rect, const Color &col) {
451 void Image::fillRect(const Rectangle &rectangle, const Color &col) {
452 rect(rectangle, col);
454 /* void Image::msg(Letters &letters, int x, int y, const Color &col) {
455 api_->drawLetters(letters, x, y,col.Red,col.Blue,col.Green,col.Alpha,0,0);
459 Image& Image::draw(double left, double top, Drawable &target) {
460 target.image(*this, left, top);
463 Image& Image::draw(Drawable &target) {
467 Image& Image::draw(double alpha, Drawable &target) {
468 target.image(*this, alpha);
472 void Image::display(double x, double y) {
475 void Image::display() {
476 draw(targetarea_.left, targetarea_.top);
480 Image::PartialView::PartialView(Image *src, const Rectangle &d_source)
484 target.set(source.getWidth(), source.getHeight());
486 Image::PartialView& Image::PartialView::set(double width, double height)
488 target.set(width, height);
491 Image::PartialView::~PartialView()
494 const Point Image::PartialView::getDatum() const
496 return target.getDatum();
498 Image::PartialView& Image::PartialView::setDatum(const Point &p)
503 Image::PartialView& Image::PartialView::centering(const Point &p)
508 Image::PartialView& Image::PartialView::draw(Drawable &target_)
510 target_.image(*img, target, source);
513 Image::PartialView Image::operator ()(const Rectangle &view)
515 PartialView tmp(this, view);
522 // get bitmap properties
523 const void * Image::getBitmapPtr() const {
524 if(!have_instance_) Exception(typeid(*this), "Memory Error", "The Image does not have bitmap instance.");
527 return (void *)bitmapub_;
530 return (void *)bitmapf_;
540 const Point Image::getDatum() const {
541 return targetarea_.getDatum();
543 Image& Image::setDatum(const Point& p) {
544 targetarea_.setDatum(p);
547 Image& Image::centering(const Drawable& target) {
548 targetarea_.centering(target);
551 Image& Image::centering(const Figure& fig) {
552 targetarea_.centering(fig);
555 Image& Image::centering(const Point& p) {
556 targetarea_.centering(p);
559 Image& Image::centering(const double x, const double y, const double z) {
560 targetarea_.centering(x, y, z);
563 Image& Image::move_to(const double x, const double y, const double z) {
564 targetarea_.move_to(x, y, z);
567 Image& Image::shift(const double x, const double y, const double z) {
568 targetarea_.shift(x, y, z);
571 int Image::getWidth() const { return width_; }
572 int Image::getHeight() const { return height_; }
573 double Image::getHcenter() const { return width_/2 - 0.5; }
574 double Image::getVcenter() const { return height_/2 - 0.5; }
575 const Point Image::getCenter() const {
576 Point po(getHcenter(), getVcenter());
579 double Image::getTop() const { return targetarea_.top; }
580 double Image::getLeft() const { return targetarea_.left; }
581 double Image::getBottom() const { return targetarea_.bottom; }
582 double Image::getRight() const { return targetarea_.right; }
585 float* Image::getFloatPrt() { return bitmapf_; }
586 unsigned char* Image::getElementPtr() { return bitmapub_; }
587 int Image::getPixBytes() { return pixBytes_; }
588 int Image::getLineBytes() { return lineBytes_; }
589 int Image::getBitmapBytes() { return bitmapBytes_; }
590 int Image::getLineNumber() { return lineValue_; }
591 int Image::getElementNumber() { return bitmapValue_; }
592 const Image::PixelComponentsCnt Image::getComponentKind() const { return pixcomp_; }
\r
593 const Image::PixelComponentsPrecision Image::getPrecisionKind() const { return pixprec_; }
595 //// Special Utilities
597 void Image::to(const Rectangle &source__, Image &other, const Rectangle target__) const {
598 Rectangle source = source__, target = target__;
599 source.clipped_by(area_);
600 target.clipped_by(other.area_);
601 if(source.getWidth()!=target.getWidth() || source.getHeight()!=target.getHeight())
602 throw new Exception("Image.to: source area does not match target area.");
603 int sl = (int)source.getLeft(), st=(int)source.getTop(), tl=(int)target.getLeft(), tt=(int)target.getTop();
604 for(int y=0; y<source.getHeight(); y++)
605 for(int x=0; x<source.getWidth(); x++)
606 other.pix_direct(x+tl,y+tt, getPix(x+sl,y+st));
608 void Image::to(const Rectangle &source__, Image &other) const {
609 Rectangle source = source__;
610 source.clipped_by(area_);
612 other.set(source, pixcomp_, pixprec_);
613 for(int y=0; y<other.getHeight(); y++)
614 for(int x=0; x<other.getWidth(); x++)
615 other.pix_direct(x,y, getPix((int)(source.getLeft())+x, (int)(source.getTop())+y));
617 int vbase = getHeight() - source.getTop();
618 for(int i=0; i<other.getHeight(); i++) {
619 memcpy(other.bitmapub_+(other.getHeight()-i-1)*(lineBytes_),
620 bitmapub_+(vbase-i-1)*(lineBytes_)+(size_t)(source.getLeft()),
621 pixBytes_*other.getWidth());
627 void Image::load(std::string filename) {
628 IMAGE_FORMATS::IMAGE_FORMAT *loader;
632 std::string::size_type extention_index = filename.find_last_of('.');
633 if(extention_index==std::string::npos) throw Exception(typeid(*this), "File Type Error", "Specified image type is not supported.*..");
634 std::string file_extension = filename.substr(extention_index+1);
635 if(file_extension=="png") {
636 loader = new IMAGE_FORMATS::PNG_BRIDGE;
637 loader->load(File::decodePath(filename).c_str(), this);
640 } else if(file_extension=="jpg") {
641 loader = new IMAGE_FORMATS::JPEG_BRIDGE;
642 loader->load(File::decodePath(filename).c_str(), this);
646 throw Exception(typeid(*this), "File Type Error", "Specified image type is not supported.");
648 switch(Color::getCalibrationMode()) {
649 case Color::SOFTWARE_GAMMA_VALUE:
650 case Color::SOFTWARE_TABLE:
651 convertColorCalibration(true);
657 void Image::load(const char * filename) {
658 load(std::string(filename));
660 void Image::save(std::string filename) {
661 IMAGE_FORMATS::IMAGE_FORMAT *loader;
662 if(!have_instance_) {
663 throw Exception(typeid(*this), "Memory Error", "Image does not have its instance.");
669 switch(Color::getCalibrationMode()) {
670 case Color::SOFTWARE_GAMMA_VALUE:
671 case Color::SOFTWARE_TABLE:
672 tmp = new Image(width_, height_, pixcomp_, pixprec_);
673 for(int y=0; y<height_; y++) {
674 for(int x=0; x<width_; x++) {
681 tmp->pix_direct(x, y, col);
690 std::string::size_type extention_index = filename.find_last_of('.');
691 if(extention_index==std::string::npos) throw Exception(typeid(*this), "File Type Error", "Specified image type is not supported.");
692 std::string file_extension = filename.substr(extention_index+1);
693 if(file_extension=="png") {
694 loader = new IMAGE_FORMATS::PNG_BRIDGE;
695 loader->save(File::decodePath(filename).c_str(), tmp);
698 throw Exception(typeid(*this), "File Type Error", "Specified image type is not supported.");
700 if(tmp != this) delete tmp;
702 void Image::save(const char * filename) {
703 save(std::string(filename));
706 void Image::from(const Matrix &mtx) {
708 if(getWidth()!=mtx.getCols() || getHeight()!=mtx.getRows() || pixcomp_!=Image::GRAY) {
709 //if (have_instance_==false) set(mtx.getCols(),mtx.getRows(), GRAY);
710 //else throw Exception(typeid(*this), "Memory Error", "Image has been allocated.");
712 set(mtx.getCols(),mtx.getRows(), GRAY);
714 int rowmax = mtx.getRows();
715 int colmax = mtx.getCols();
716 for(int row=1; row<=rowmax; row++) {
717 for(int col=1; col<=colmax; col++) {
718 //colour.set(mtx(row,col));
719 pix_direct(col-1,row-1,mtx(row,col));
723 void Image::from(const Matrix &r, const Matrix &g, const Matrix &b) {
725 if(r.getRows()!=g.getRows() || r.getRows()!=b.getRows()) throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent between each color.");
726 if(r.getCols()!=g.getCols() || r.getCols()!=b.getCols()) throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent between each color.");
727 if(getWidth()!=r.getCols() || getHeight()!=r.getRows() || pixcomp_!=Image::RGB) {
728 //if (have_instance_==false) set(r.getCols(),r.getRows(), RGB);
729 //else throw Exception(typeid(*this), "Memory Error", "Image has been allocated.");
731 set(r.getCols(),r.getRows(), RGB);
733 int rowmax = r.getRows();
734 int colmax = r.getCols();
735 for(int row=1; row<=rowmax; row++) {
736 for(int col=1; col<=colmax; col++) {
737 //colour.set(r(row,col), g(row,col), b(row,col));
738 pix_direct(col-1,row-1,r(row,col), g(row,col), b(row,col),1.0);
742 void Image::from(const Matrix &r, const Matrix &g, const Matrix &b, const Matrix &a) {
744 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.");
745 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.");
746 if(getWidth()!=r.getCols() || getHeight()!=r.getRows() || pixcomp_!=Image::RGBA) {
747 //if (have_instance_==false) set(r.getCols(),r.getRows(), RGBA);
748 //else throw Exception(typeid(*this), "Memory Error", "Image has been allocated.");
750 set(r.getCols(),r.getRows(), RGBA);
752 int rowmax = r.getRows();
753 int colmax = r.getCols();
754 for(int row=1; row<=rowmax; row++) {
755 for(int col=1; col<=colmax; col++) {
756 //colour.set(r(row,col), g(row,col), b(row,col), a(row,col));
757 pix_direct(col-1,row-1,r(row,col), g(row,col), b(row,col), a(row,col));
762 void Image::to(Matrix &mtx) const {
763 to(Point(0,0), getWidth(), getHeight(), mtx);
765 void Image::to(Point p, const Rectangle &rect, Matrix &gray) const {
766 to(Point(0,0), (int)rect.getWidth(), (int)rect.getHeight(), gray);
768 void Image::to(const Interval &horiz, const Interval &vert, Matrix &gray) const {
769 to(Point(horiz.int_floor(0), vert.int_floor(0)),
770 horiz.int_ceil(getWidth())-horiz.int_floor(0), vert.int_ceil(getHeight())-vert.int_floor(0),
773 void Image::to(Point p, int width_, int height_, Matrix &mtx) const {
776 double width = width_+p.x<getWidth() ? width_ : getWidth()-p.x;
777 double height = height_+p.y<getHeight() ? height_ : getHeight()-p.y;
778 if(pixcomp_!=GRAY) throw Exception(typeid(*this), "Argument Error", "Color types of Image(GRAY) and Matrix were not matched.");
779 if(!have_instance_) throw Exception(typeid(*this), "Memory Error", "Image had not allocated.");
780 if(width!=mtx.getCols() || height!=mtx.getRows()) { mtx.release(); mtx.set((int)height, (int)width); }
781 int rowmax = mtx.getRows(), colmax = mtx.getCols();
782 for(int row=1; row<=rowmax; row++) {
783 for(int col=1; col<=colmax; col++) {
784 colour = getPix((int)(p.x)+col-1, (int)(p.y)+row-1);
791 void Image::to(Matrix &r, Matrix &g, Matrix &b) const {
792 to(Point(0,0), getWidth(), getHeight(), r, g, b);
794 void Image::to(Point p, const Rectangle &rect, Matrix &r, Matrix &g, Matrix &b) const {
795 to(Point(0,0), (int)rect.getWidth(), (int)rect.getHeight(), r, g, b);
797 void Image::to(const Interval &horiz, const Interval &vert, Matrix &r, Matrix &g, Matrix &b) const {
798 to(Point(horiz.int_floor(0), vert.int_floor(0)),
799 horiz.int_ceil(getWidth())-horiz.int_floor(0), vert.int_ceil(getHeight())-vert.int_floor(0),
802 void Image::to(Point p, int width_, int height_, Matrix &r, Matrix &g, Matrix &b) const {
804 double rr, gg, bb, aa;
805 double width = width_+p.x<getWidth() ? width_ : getWidth()-p.x;
806 double height = height_+p.y<getHeight() ? height_ : getHeight()-p.y;
807 if(pixcomp_!=RGB) throw Exception(typeid(*this), "Argument Error", "Color types of Image(RGB) and Matrix were not matched.");
808 if(!have_instance_) throw Exception(typeid(*this), "Memory Error", "Image had not allocated.");
809 if(r.getRows()!=g.getRows() || r.getRows()!=b.getRows()) throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent between each color.");
810 if(r.getCols()!=g.getCols() || r.getCols()!=b.getCols()) throw Exception(typeid(*this), "Format Error", "Matrix sizes are defferent between each color.");
811 if(width!=r.getCols() || height!=r.getRows()) { r.release(); r.set((int)height, (int)width); }
812 if(width!=g.getCols() || height!=g.getRows()) { g.release(); g.set((int)height, (int)width); }
813 if(width!=b.getCols() || height!=b.getRows()) { b.release(); b.set((int)height, (int)width); }
814 int rowmax = r.getRows(), colmax = r.getCols();
815 for(int row=1; row<=rowmax; row++) {
816 for(int col=1; col<=colmax; col++) {
817 colour = getPix((int)(p.x)+col-1, (int)(p.y)+row-1);
818 colour.get(rr,gg,bb,aa);
826 void Image::to(Matrix &r, Matrix &g, Matrix &b, Matrix &a) const {
827 to(Point(0,0), getWidth(), getHeight(), r, g, b, a);
829 void Image::to(Point p, const Rectangle &rect, Matrix &r, Matrix &g, Matrix &b, Matrix &a) const {
830 to(Point(0,0), (int)rect.getWidth(), (int)rect.getHeight(), r, g, b, a);
832 void Image::to(const Interval &horiz, const Interval &vert, Matrix &r, Matrix &g, Matrix &b, Matrix &a) const {
833 to(Point(horiz.int_floor(0), vert.int_floor(0)),
834 horiz.int_ceil(getWidth())-horiz.int_floor(0), vert.int_ceil(getHeight())-vert.int_floor(0),
837 void Image::to(Point p, int width_, int height_, Matrix &r, Matrix &g, Matrix &b, Matrix &a) const {
839 double rr, gg, bb, aa;
840 double width = width_+p.x<getWidth() ? width_ : getWidth()-p.x;
841 double height = height_+p.y<getHeight() ? height_ : getHeight()-p.y;
842 if(pixcomp_!=RGBA) throw Exception(typeid(*this), "Argument Error", "Color types of Image(RGBA) and Matrix were not matched.");
843 if(!have_instance_) throw Exception(typeid(*this), "Memory Error", "Image had not allocated.");
844 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.");
845 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.");
846 if(width!=r.getCols() || height!=r.getRows()) { r.release(); r.set((int)height, (int)width); }
847 if(width!=g.getCols() || height!=g.getRows()) { g.release(); g.set((int)height, (int)width); }
848 if(width!=b.getCols() || height!=b.getRows()) { b.release(); b.set((int)height, (int)width); }
849 if(width!=a.getCols() || height!=a.getRows()) { a.release(); a.set((int)height, (int)width); }
850 int rowmax = r.getRows(), colmax = r.getCols();
851 for(int row=1; row<=rowmax; row++) {
852 for(int col=1; col<=colmax; col++) {
853 colour = getPix((int)(p.x)+col-1, (int)(p.y)+row-1);
854 colour.get(rr,gg,bb,aa);
864 Image & Image::operator -=(Image &rhs) {
865 if(pixcomp_!=rhs.pixcomp_) throw Exception(typeid(*this), "Format Error", "Difference must be resolved between same format Images.");
866 if(pixprec_!=rhs.pixprec_) throw Exception(typeid(*this), "Format Error", "Difference must be resolved between same format Images.");
867 if(width_!=rhs.width_) throw Exception(typeid(*this), "Format Error", "Difference must be resolved between same format Images.");
868 if(height_!=rhs.height_) throw Exception(typeid(*this), "Format Error", "Difference must be resolved between same format Images.");
870 unsigned char *pb=bitmapub_, *qb=rhs.bitmapub_;
871 float *pf=bitmapf_, *qf=bitmapf_;
875 for(int i=0; i<bitmapValue_; i++) {
877 if(pb[i]<0) pb[i] = -pb[i];
878 if(pb[i]>15) pb[i]=256; else pb[i]*=16;
882 for(int i=0; i<bitmapValue_; i++) {
884 if(pf[i]<0) pf[i] = -pf[i];
885 if(pf[i]>15) pf[i]=256; else pf[i]*=16;
894 namespace IMAGE_FORMATS {
895 IMAGE_FORMAT::~IMAGE_FORMAT() {
897 void IMAGE_FORMAT::readTargetMemoryAlignment(Image *target) {
898 target_bitmap_ub_ = target->bitmapub_;
899 target_bytes_per_line_ = target->lineBytes_;
900 pix_components_ = target->pixcomp_;
901 pix_precision_ = target->pixprec_;
905 } /* <- namespace Psycholops */