#include "control.h" pdisplay::pdisplay(QWidget *parent, const char *name, WFlags fl):picture_display(parent,name,fl) { w=0; h=0; connect( loadButton,SIGNAL(clicked()), this,SLOT( loadButtonSlot())); connect( saveButton,SIGNAL(clicked()), this,SLOT( saveButtonSlot())); connect( filterButton,SIGNAL(clicked()), this,SLOT(filterButtonSlot())); connect( &timer,SIGNAL(timeout()), this,SLOT( updateProgress())); connect(&filter_thread,SIGNAL(done()), this,SLOT( filterDoneSlot())); connect(colour_display->paint_area,SIGNAL(pressed(QMouseEvent*)),this,SLOT(colourPressedSlot(QMouseEvent*))); connect( red_display->paint_area,SIGNAL(pressed(QMouseEvent*)),this,SLOT( redPressedSlot(QMouseEvent*))); connect( green_display->paint_area,SIGNAL(pressed(QMouseEvent*)),this,SLOT( greenPressedSlot(QMouseEvent*))); connect( blue_display->paint_area,SIGNAL(pressed(QMouseEvent*)),this,SLOT( bluePressedSlot(QMouseEvent*))); connect(sr0,SIGNAL(valueChanged(int)), r0,SLOT( setValue(int))); connect( r0,SIGNAL(valueChanged(int)),this,SLOT( setRed0(int))); connect(sr1,SIGNAL(valueChanged(int)), r1,SLOT( setValue(int))); connect( r1,SIGNAL(valueChanged(int)),this,SLOT( setRed1(int))); connect(sb0,SIGNAL(valueChanged(int)), b0,SLOT( setValue(int))); connect( b0,SIGNAL(valueChanged(int)),this,SLOT( setBlue0(int))); connect(sb1,SIGNAL(valueChanged(int)), b1,SLOT( setValue(int))); connect( b1,SIGNAL(valueChanged(int)),this,SLOT( setBlue1(int))); connect(sg0,SIGNAL(valueChanged(int)), g0,SLOT( setValue(int))); connect( g0,SIGNAL(valueChanged(int)),this,SLOT(setGreen0(int))); connect(sg1,SIGNAL(valueChanged(int)), g1,SLOT( setValue(int))); connect( g1,SIGNAL(valueChanged(int)),this,SLOT(setGreen1(int))); connect(aSc ,SIGNAL(clicked()),this,SLOT(autoScR())); connect(aSc ,SIGNAL(clicked()),this,SLOT(autoScG())); connect(aSc ,SIGNAL(clicked()),this,SLOT(autoScB())); connect(aScR,SIGNAL(clicked()),this,SLOT(autoScR())); connect(aScG,SIGNAL(clicked()),this,SLOT(autoScG())); connect(aScB,SIGNAL(clicked()),this,SLOT(autoScB())); cmenu=NULL; rmenu=NULL; gmenu=NULL; bmenu=NULL; } void pdisplay::windowActivationChange(bool b) { if (!b && isActiveWindow()) emit(activated(this)); } void pdisplay::autoScR() { int min=0,max=1; layer[0].getMinMax(min,max); setRed0(min); setRed1(max); } void pdisplay::autoScG() { int min=0,max=1; layer[1].getMinMax(min,max); setGreen0(min); setGreen1(max); } void pdisplay::autoScB() { int min=0,max=1; layer[2].getMinMax(min,max); setBlue0(min); setBlue1(max); } void pdisplay::setRed0(int i) { sr0->setValue(i); if (isVisible()) convertFromFP(); } void pdisplay::setRed1(int i) { sr1->setValue(i); if (isVisible()) convertFromFP(); } void pdisplay::setGreen0(int i) { sg0->setValue(i); if (isVisible()) convertFromFP(); } void pdisplay::setGreen1(int i) { sg1->setValue(i); if (isVisible()) convertFromFP(); } void pdisplay::setBlue0(int i) { sb0->setValue(i); if (isVisible()) convertFromFP(); } void pdisplay::setBlue1(int i) { sb1->setValue(i); if (isVisible()) convertFromFP(); } int pdisplay::width() { return(w); } int pdisplay::height() { return(h); } void pdisplay::setKernel(int i, KERNEL2D &k) { kernel[i]=&k; } void pdisplay::setMenu(QPopupMenu *cp, QPopupMenu *rp, QPopupMenu *gp, QPopupMenu *bp) { cmenu=cp; rmenu=rp; gmenu=gp; bmenu=bp; } void pdisplay::colourPressedSlot(QMouseEvent *e) { emit(selectLayer(-1)); if ((e->button()==2) || (oneButton->isChecked())) cmenu->popup(colour_display->paint_area->mapToGlobal(QPoint(e->x(),e->y()))); } void pdisplay::redPressedSlot(QMouseEvent *e) { emit(selectLayer(0)); if ((e->button()==2) || (oneButton->isChecked())) rmenu->popup(red_display->paint_area->mapToGlobal(QPoint(e->x(),e->y()))); } void pdisplay::greenPressedSlot(QMouseEvent *e) { emit(selectLayer(1)); if ((e->button()==2) || (oneButton->isChecked())) gmenu->popup(green_display->paint_area->mapToGlobal(QPoint(e->x(),e->y()))); } void pdisplay::bluePressedSlot(QMouseEvent *e) { emit(selectLayer(2)); if ((e->button()==2) || (oneButton->isChecked())) bmenu->popup(blue_display->paint_area->mapToGlobal(QPoint(e->x(),e->y()))); } void pdisplay::closeEvent(QCloseEvent *e) { if (!filter_thread.running()) { emit(displayCloses(this)); e->accept(); } } void pdisplay::updateProgress() { qApp->lock(); progressBar->setProgress(filter_thread.pixel); qApp->unlock(); } void pdisplay::convertToFP() { QImage im=colour_display->paint_area->pm->convertToImage(); w=im.width(); h=im.height(); QImage im_src_r(w,h,8,256),im_src_g(w,h,8,256),im_src_b(w,h,8,256); double scale=1.0/255.0; for (int i=0;i<256;++i) { im_src_r.setColor(i,qRgb(i,i,i)); im_src_g.setColor(i,qRgb(i,i,i)); im_src_b.setColor(i,qRgb(i,i,i)); } for (int i=0;i<3;++i) { layer[i].resize(w,h); layer[i].resetPixelCounter(); } for (int j=0;jpaint_area->setImage(im_src_r); green_display->paint_area->setImage(im_src_g); blue_display ->paint_area->setImage(im_src_b); } void pdisplay::convertFromFP() { QImage im_out_r(w,h,8,256),im_out_g(w,h,8,256),im_out_b(w,h,8,256),im_out(w,h,32); long r_value,g_value,b_value; double r_offs=(double)r0->value(), g_offs=(double)g0->value(), b_offs=(double)b0->value(); double scale_r=255.0/(double)(r1->value()-r0->value()), scale_g=255.0/(double)(g1->value()-g0->value()), scale_b=255.0/(double)(b1->value()-b0->value()); for (int i=0;i<256;++i) { im_out_r.setColor(i,qRgb(i,i,i)); im_out_g.setColor(i,qRgb(i,i,i)); im_out_b.setColor(i,qRgb(i,i,i)); } for (int i=0;i<3;++i) layer[i].resetPixelCounter(); for (int j=0;j255) r_value=255; if (g_value<0) g_value=0; if (g_value>255) g_value=255; if (b_value<0) b_value=0; if (b_value>255) b_value=255; im_out_r.setPixel(i,j,r_value); im_out_g.setPixel(i,j,g_value); im_out_b.setPixel(i,j,b_value); im_out .setPixel(i,j,qRgb(r_value,g_value,b_value)); } } red_display ->paint_area->setImage(im_out_r); green_display ->paint_area->setImage(im_out_g); blue_display ->paint_area->setImage(im_out_b); colour_display->paint_area->setImage(im_out); } void pdisplay::filterDoneSlot() { filterButton->setText("Start Filter"); saveButton->setEnabled(true); loadButton->setEnabled(true); CTab ->setEnabled(true); timer.stop(); progressBar->reset(); if (openNew->isChecked()) { output_display->show(); output_display->convertFromFP(); output_display->filterButton->setEnabled(true); output_display->repaint(); } else { for (int i=0;i<3;++i) layer[i]=output_display->layer[i]; convertFromFP(); output_display->close(); output_display=NULL; } emit(filterDone(this)); } void pdisplay::saveButtonSlot() { QString s = QFileDialog::getSaveFileName("", "",this, "open file dialog","Choose a file" ); if (s!="") colour_display->paint_area->save(s,"PNG"); } void pdisplay::loadButtonSlot() { QString s = QFileDialog::getOpenFileName("", "",this, "open file dialog","Choose a file" ); if (colour_display->paint_area->load(s)) { convertToFP(); convertFromFP(); } } void pdisplay::startFilter(pdisplay* output) { output_display=output; output_display->filterButton->setEnabled(false); output_display->w=w; output_display->h=h; filter_thread.setImages(&layer[0],&layer[1],&layer[2],&output->layer[0],&output->layer[1],&output->layer[2]); filter_thread.setKernel(kernel[0],kernel[1],kernel[2]); timer.start(100); progressBar->setTotalSteps(w*h); filter_thread.start(); filterButton->setText("Stop"); saveButton->setEnabled(false); loadButton->setEnabled(false); CTab ->setEnabled(false); } void pdisplay::filterButtonSlot() { if (!filter_thread.running()) { if ((w>0) && (h>0)) emit(requestDisplay(this)); } else filter_thread.stop(); } void pdisplay::aboutToQuitSlot() { emit(displayCloses(this)); } control::control(QWidget *parent, const char *name, WFlags fl):QWidget(parent,name,fl) { // Constructor connect( qApp,SIGNAL(aboutToQuit() ),this,SLOT(aboutToQuitSlot( ))); connect(&cpopupmenu,SIGNAL(activated (int)),this,SLOT(activateCFilter(int))); connect(&rpopupmenu,SIGNAL(activated (int)),this,SLOT(activateRFilter(int))); connect(&gpopupmenu,SIGNAL(activated (int)),this,SLOT(activateGFilter(int))); connect(&bpopupmenu,SIGNAL(activated (int)),this,SLOT(activateBFilter(int))); scanDirectory(QDir::homeDirPath()+"/.KERNELS",&cpopupmenu,&rpopupmenu,&gpopupmenu,&bpopupmenu); copy_kernel =new KERNEL2D((const char*)"Copy" ,&manager); delete_kernel=new KERNEL2D((const char*)"Delete",&manager); mult2_kernel =new KERNEL2D((const char*)"*2.0", &manager); div2_kernel =new KERNEL2D((const char*)"/2.0", &manager); negate_kernel=new KERNEL2D((const char*)"*(-1)", &manager); copy_kernel ->insert(0,0); copy_kernel ->weight(1.0); delete_kernel->insert(0,0); delete_kernel->weight(0.0); mult2_kernel ->insert(0,0); mult2_kernel ->weight(2.0); div2_kernel ->insert(0,0); div2_kernel ->weight(0.5); negate_kernel->insert(0,0); negate_kernel->weight(-1.0); for (int i=0;i<3;++i) activeKernel[i]="Copy"; manager.resolveAll(); cpopupmenu.insertTearOffHandle(0,0); rpopupmenu.insertTearOffHandle(0,0); gpopupmenu.insertTearOffHandle(0,0); bpopupmenu.insertTearOffHandle(0,0); cpopupmenu.insertItem("Copy"); cpopupmenu.insertItem("Delete"); cpopupmenu.insertItem("/2.0"); cpopupmenu.insertItem("*2.0"); cpopupmenu.insertItem("*(-1)"); rpopupmenu.insertItem("Copy"); rpopupmenu.insertItem("Delete"); rpopupmenu.insertItem("/2.0"); rpopupmenu.insertItem("*2.0"); rpopupmenu.insertItem("*(-1)"); gpopupmenu.insertItem("Copy"); gpopupmenu.insertItem("Delete"); gpopupmenu.insertItem("/2.0"); gpopupmenu.insertItem("*2.0"); gpopupmenu.insertItem("*(-1)"); bpopupmenu.insertItem("Copy"); bpopupmenu.insertItem("Delete"); bpopupmenu.insertItem("/2.0"); bpopupmenu.insertItem("*2.0"); bpopupmenu.insertItem("*(-1)"); pdisplay* d=newDisplay(); #ifdef Q_OS_MACX d->oneButton->setChecked(true); #endif d->show(); } void control::aboutToQuitSlot() { manager.deleteAll(); // Delete all kernels } void control::checkoutDisplaySlot(pdisplay* source_display) { // Display closes children.erase(source_display); if (children.size()==0) qApp->exit(); if (activeDisplay==source_display) activeDisplay=NULL; } void control::checkinDisplaySlot(pdisplay* source_display) { // Display requests output display - open and start filtering for (int i=0;i<3;++i) source_display->setKernel(i,*manager.resolve(activeKernel[i])); working_display=newDisplay(); working_display->resize(source_display->width()+235,source_display->height()+130); working_display->r0->setValue(source_display->r0->value()); working_display->sr0->setValue(source_display->r0->value()); working_display->r1->setValue(source_display->r1->value()); working_display->sr1->setValue(source_display->r1->value()); working_display->g0->setValue(source_display->g0->value()); working_display->sg0->setValue(source_display->g0->value()); working_display->g1->setValue(source_display->g1->value()); working_display->sg1->setValue(source_display->g1->value()); working_display->b0->setValue(source_display->b0->value()); working_display->sb0->setValue(source_display->b0->value()); working_display->b1->setValue(source_display->b1->value()); working_display->sb1->setValue(source_display->b1->value()); working_display->openNew ->setChecked(source_display->openNew ->isChecked()); working_display->oneButton->setChecked(source_display->oneButton->isChecked()); source_display->startFilter(working_display); } pdisplay* control::newDisplay() { // Create and connect new pdisplay pdisplay *d =new pdisplay(); d->setMenu(&cpopupmenu, &rpopupmenu, &gpopupmenu, &bpopupmenu); children.insert(d); connect(d,SIGNAL(requestDisplay(pdisplay*)),this,SLOT( checkinDisplaySlot(pdisplay*))); connect(d,SIGNAL( displayCloses(pdisplay*)),this,SLOT(checkoutDisplaySlot(pdisplay*))); connect(d,SIGNAL( selectLayer(int)),this,SLOT( selectLayerSlot(int))); connect(d,SIGNAL( filterDone(pdisplay*)),this,SLOT( clearCachesSlot(pdisplay*))); connect(d,SIGNAL( activated(pdisplay*)),this,SLOT( activatedSlot(pdisplay*))); activeDisplay=d; return(d); } void control::clearCachesSlot(pdisplay* d){ // Clear all filter caches manager.clearCaches(); } void control::scanDirectory(QString rootpath, QPopupMenu *cmenu, QPopupMenu *rmenu, QPopupMenu *gmenu, QPopupMenu *bmenu) { // Scan a directory for filters, read them and extend the filter menu QDir d(rootpath); if (d.exists()) { d.setFilter( QDir::Dirs | QDir::Files | QDir::NoSymLinks ); d.setSorting( QDir::Name ); const QFileInfoList *list = d.entryInfoList(); QFileInfoListIterator it(*list), it2(*list); QFileInfo *fi; while ((fi=it.current())!=0) { if (fi->isDir()) { if ((fi->fileName()!="..") && (fi->fileName()!=".")) { QPopupMenu *cm=new QPopupMenu(); cm->insertTearOffHandle(); connect(cm,SIGNAL(activated(int)),this,SLOT(activateCFilter(int))); cmenu->insertItem(fi->fileName().latin1(),cm); QPopupMenu *rm=new QPopupMenu(); rm->insertTearOffHandle(); connect(rm,SIGNAL(activated(int)),this,SLOT(activateRFilter(int))); rmenu->insertItem(fi->fileName().latin1(),rm); QPopupMenu *gm=new QPopupMenu(); gm->insertTearOffHandle(); connect(gm,SIGNAL(activated(int)),this,SLOT(activateGFilter(int))); gmenu->insertItem(fi->fileName().latin1(),gm); QPopupMenu *bm=new QPopupMenu(); bm->insertTearOffHandle(); connect(bm,SIGNAL(activated(int)),this,SLOT(activateBFilter(int))); bmenu->insertItem(fi->fileName().latin1(),bm); scanDirectory(fi->filePath().latin1(),cm, rm, gm, bm); } } ++it; } while ((fi=it2.current())!=0) { if (!fi->isDir()) { KERNEL2D *k=new KERNEL2D(" ",&manager); k->load((char*)fi->filePath().ascii()); if (fi->extension().upper()!="HID") { cmenu->insertItem((QString)k->getName().c_str()); rmenu->insertItem((QString)k->getName().c_str()); gmenu->insertItem((QString)k->getName().c_str()); bmenu->insertItem((QString)k->getName().c_str()); } } ++it2; } } } void control::selectLayerSlot(int nr) { // Activated filter will be applied to this layer (r,g,b) activeLayer=nr; } void control::activatedSlot(pdisplay *p) { activeDisplay=p; } void control::activateCFilter(int nr) { // Activate a filter if (cpopupmenu.text(nr)!=NULL) for (int i=0;i<3;++i) activeKernel[i]=(const char*)cpopupmenu.text(nr); } void control::activateRFilter(int nr) { // Activate a filter if (rpopupmenu.text(nr)!=NULL) activeKernel[0]=(const char*)rpopupmenu.text(nr); } void control::activateGFilter(int nr) { // Activate a filter if (gpopupmenu.text(nr)!=NULL) activeKernel[1]=(const char*)gpopupmenu.text(nr); } void control::activateBFilter(int nr) { // Activate a filter if (bpopupmenu.text(nr)!=NULL) activeKernel[2]=(const char*)bpopupmenu.text(nr); }