pkg://epscan-0.5.tar.gz:507824/
epscan/EPScan.cc
downloads
/**********************************************************************
* EPSCAN, an EPSON ES-1200 scanner driver
* Adam P. Jenkins <ajenkins@cs.umass.edu>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream.h>
#include <qapp.h>
#include <qcombo.h>
#include <qscrbar.h>
#include <qlabel.h>
#include <qpushbt.h>
#include <qrect.h>
#include <qlayout.h>
#include <qfiledlg.h>
#include <qpopmenu.h>
#include <qmenubar.h>
#include "EPScan.h"
#include "Separator.h"
#include "ProgressReport.h"
#include "ValSlider.h"
#include "EPGetRegion.h"
#include "HelpWindow.h"
#include "QLabeledBoxLayout.h"
EPScan::EPScan(QWidget *parent, const char *name) : QWidget(parent, name)
{
Separator *separator;
initScanner();
initMenus();
// enable tiff routines so QPixmap can load tif files.
void initTiffHandler();
initTiffHandler();
QBoxLayout *layout = new QBoxLayout(this, QBoxLayout::LeftToRight, 15);
CHECK_PTR(layout);
helpWin = new HelpWindow(EPSCAN_HELP_FILE);
CHECK_PTR(helpWin);
QPopupMenu *file = new QPopupMenu;
CHECK_PTR( file );
file->insertItem("&Exit", qApp, SLOT(quit()));
QPopupMenu *help = new QPopupMenu;
CHECK_PTR(help);
help->insertItem("&Description", helpWin, SLOT(showHelp()));
QMenuBar *menub = new QMenuBar(this);
CHECK_PTR(menub);
menub->insertItem("&File", file);
menub->insertItem("&Help", help);
layout->setMenuBar(menub);
QLabeledBoxLayout *controls = new QLabeledBoxLayout(QBoxLayout::TopToBottom,
10);
CHECK_PTR(controls);
layout->addLayout(controls);
// Image Type Menu
imageTypeMenu = new QComboBox(false, this, "Image Type");
CHECK_PTR(imageTypeMenu);
makeMenu(imageTypeMenu, &imageTypeData);
connect(imageTypeMenu, SIGNAL(activated(int)), SLOT(setImageType(int)) );
controls->addLabeledWidget(imageTypeMenu);
// Destination Menu
destinationMenu = new QComboBox(false, this, "Destination");
CHECK_PTR(destinationMenu);
makeMenu(destinationMenu, &destinationData);
connect(destinationMenu, SIGNAL(activated(int)), SLOT(setDestination(int)) );
controls->addLabeledWidget(destinationMenu);
// Resolution menu
resolutionMenu = new QComboBox(false, this, "Resolution");
CHECK_PTR(resolutionMenu);
makeMenu(resolutionMenu, &resolutionData);
connect(resolutionMenu, SIGNAL(activated(int)), SLOT(setResolution(int)) );
controls->addLabeledWidget(resolutionMenu);
// brightness slider
brightnessCtrl = new ValSlider(-3, 3, 1, 1, 0, this, "Brightness");
CHECK_PTR(brightnessCtrl);
connect(brightnessCtrl, SIGNAL(valueChanged(int)), SLOT(setBrightness(int)) );
controls->addLabeledWidget(brightnessCtrl);
separator = new Separator(this, Separator::Horizontal);
CHECK_PTR(separator);
controls->addWidget(separator);
// width and height display
QLabeledBoxLayout *dimensions = new QLabeledBoxLayout(QBoxLayout::LeftToRight);
CHECK_PTR(dimensions);
controls->addLayout(dimensions);
// width
widthLabel = new QLabel("00.00", this, "Width");
CHECK_PTR(widthLabel);
widthLabel->adjustSize();
widthLabel->setMinimumSize(widthLabel->size());
widthLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);
dimensions->addLabeledWidget(widthLabel);
// height
heightLabel = new QLabel("00.00", this, "Height");
CHECK_PTR(heightLabel);
heightLabel->adjustSize();
heightLabel->setMinimumSize(heightLabel->size());
heightLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);
dimensions->addLabeledWidget(heightLabel);
// units menu
unitsMenu = new QComboBox(this, "Units");
CHECK_PTR(unitsMenu);
makeMenu(unitsMenu, &unitsData);
connect(unitsMenu, SIGNAL(activated(int)), SLOT(displayDim(int)) );
dimensions->addLabeledWidget(unitsMenu);
separator = new Separator(this, Separator::Horizontal);
CHECK_PTR(separator);
controls->addWidget(separator);
// zoom control
zoomCtrl = new ValSlider(50, 200, 1, 10, 100, this, "Zoom");
CHECK_PTR(zoomCtrl);
connect(zoomCtrl, SIGNAL(valueChanged(int)), SLOT(setZoom(int)) );
controls->addLabeledWidget(zoomCtrl);
separator = new Separator(this, Separator::Horizontal);
CHECK_PTR(separator);
controls->addWidget(separator);
// scan and preview buttons
QBoxLayout *btns = new QBoxLayout(QBoxLayout::LeftToRight);
CHECK_PTR(btns);
controls->addLayout(btns);
QPushButton *b;
b = new QPushButton("Scan", this);
CHECK_PTR(b);
b->adjustSize();
b->setMinimumSize(b->size());
connect(b, SIGNAL(clicked()), SLOT(doScan()) );
btns->addWidget(b);
b = new QPushButton("Preview", this);
CHECK_PTR(b);
b->adjustSize();
b->setMinimumSize(b->size());
connect(b, SIGNAL(clicked()), SLOT(doPreview()) );
btns->addWidget(b);
controls->addStretch(10);
// Now add the preview widget
previewWin = new EPGetRegion(this);
CHECK_PTR(previewWin);
previewWin->setMinimumSize(370, 520); // kind of random!
previewWin->setFrameStyle(QFrame::Panel | QFrame::Sunken);
connect(previewWin, SIGNAL(regionChanged(const QRect&)),
SLOT(setArea(const QRect&)) );
layout->addWidget(previewWin, 10);
setDefaultValues();
layout->activate();
}
EPScan::~EPScan()
{
delete scanner;
delete helpWin;
}
void
EPScan::makeMenu(QComboBox *menu, MenuItemList *data)
{
for (MenuItem *i = data->first(); i; i=data->next())
menu->insertItem(i->item);
menu->adjustSize();
menu->setMinimumSize(menu->size());
}
void
EPScan::initScanner(const char *device)
{
scanner = new Scanner;
CHECK_PTR(scanner);
int res;
if (device)
res = scanner->open(device);
else
res = scanner->open();
if (res < 0) {
cerr << "Failed to initialize scanner: " << scanner->strError() << endl;
exit(1);
}
scanner->getSettings(Settings);
scanner->getIdentity(Identity);
Settings.scanmode = SCN_MODE_NORMAL;
Settings.color_mode = SCN_CLR_COLOR_LINE;
Settings.linecounter = 32 * 1024;
}
void
EPScan::initMenus()
{
// image type menu
MenuItemList& I = imageTypeData;
I.append(new MenuItem("Color", (int)Type::COLOR) );
I.append(new MenuItem("Grayscale", (int)Type::GRAY) );
I.append(new MenuItem("Halftone", (int)Type::HALFTONE) );
I.append(new MenuItem("Line/Text", (int)Type::LINEART) );
MenuItemList& D = destinationData;
D.append(new MenuItem("Color Laser Printer", (int)Dest::COLORLASER) );
D.append(new MenuItem("Laser Printer", (int)Dest::LASER) );
D.append(new MenuItem("Color Screen", (int)Dest::COLORSCREEN) );
D.append(new MenuItem("Black & White Screen", (int)Dest::BWSCREEN) );
MenuItemList& U = unitsData;
U.append(new MenuItem("inch", Units::INCH) );
U.append(new MenuItem("cm", Units::CM) );
QString num;
for (int i = 0; Identity.resolutions[i]; i++) {
num.setNum(Identity.resolutions[i]);
resolutionData.append(new MenuItem(num, Identity.resolutions[i]) );
}
}
int
EPScan::setMenu(QComboBox *menu, MenuItemList *data, int item)
{
int nth = 0;
for (MenuItem *i = data->first(); i; i = data->next(), nth++) {
if (item == (int)i->data) {
menu->setCurrentItem(nth);
return nth;
}
}
return -1;
}
void
EPScan::setDefaultValues()
{
QRect range(0, 0,
(int)(Identity.max_horiz_area * 100),
(int)(Identity.max_vert_area * 100));
previewWin->setRange(range);
previewWin->setRegion(range);
setArea(range);
setImageType( setMenu(imageTypeMenu, &imageTypeData, (int)Type::COLOR) );
setDestination( setMenu(destinationMenu, &destinationData,
(int)Dest::COLORSCREEN) );
setResolution( setMenu(resolutionMenu, &resolutionData, 75) );
displayDim( setMenu(unitsMenu, &unitsData, Units::INCH) );
setZoom(100);
setBrightness(0);
}
/// SLOTS
void
EPScan::setImageType(int id)
{
MenuItem *item = imageTypeData.at(id);
if (!item) {
warning("setImageType called with invalid id");
return;
}
switch (item->data) {
case Type::COLOR:
Settings.color_mode = SCN_CLR_COLOR_LINE;
Settings.bits_per_pixel = 8;
break;
case Type::GRAY:
Settings.color_mode = SCN_CLR_MONO;
Settings.bits_per_pixel = 8;
break;
case Type::HALFTONE:
Settings.color_mode = SCN_CLR_MONO;
Settings.bits_per_pixel = 1;
Settings.halftone = SCN_HTONE_HARD;
break;
case Type::LINEART:
Settings.color_mode = SCN_CLR_MONO;
Settings.bits_per_pixel = 1;
Settings.halftone = SCN_HTONE_DISABLE;
break;
default:
warning("Unrecognized image type");
}
}
void
EPScan::setDestination(int id)
{
MenuItem *item = destinationData.at(id);
if (!item) {
warning("setDestination called with invalid id");
return;
}
switch (item->data) {
case Dest::COLORLASER:
case Dest::LASER:
Settings.gamma = SCN_GAMMA_PRINTA;
Settings.color_correction = SCN_CLR_CORRECT_LASER;
break;
case Dest::DOTMAT:
Settings.gamma = SCN_GAMMA_PRINTB;
Settings.color_correction = SCN_CLR_CORRECT_DOTMAT;
break;
case Dest::COLORSCREEN:
Settings.gamma = SCN_GAMMA_CRTB;
Settings.color_correction = SCN_CLR_CORRECT_CRT;
break;
case Dest::BWSCREEN:
Settings.gamma = SCN_GAMMA_CRTA;
Settings.color_correction = SCN_CLR_CORRECT_CRT;
break;
default:
warning("Unrecognized data in setDestination");
}
}
void
EPScan::setResolution(int id)
{
MenuItem *item = resolutionData.at(id);
if (!item) {
warning("setResolution called with invalid id");
return;
}
Settings.main_scan_res = Settings.sub_scan_res = item->data;
}
void
EPScan::setBrightness(int val)
{
Settings.brightness = val;
}
void
EPScan::setZoom(int val)
{
Settings.main_scan_zoom = Settings.sub_scan_zoom = val;
}
void
EPScan::setArea(const QRect& r)
{
Settings.main_scan_offset = (float)r.x() / 100.0;
Settings.sub_scan_offset = (float)r.y() / 100.0;
Settings.main_scan_area = (float)r.width() / 100.0;
Settings.sub_scan_area = (float)r.height() / 100.0;
displayDim(unitsMenu->currentItem());
}
void
EPScan::displayDim(int id)
{
MenuItem *item = unitsData.at(id);
if (!item) {
warning("displayDim called with invalid id");
return;
}
QString w, h;
if (item->data == Units::INCH) {
w.setNum(Settings.main_scan_area, 'f', 2);
h.setNum(Settings.sub_scan_area, 'f', 2);
} else {
w.setNum(Settings.main_scan_area * 2.54, 'f', 2);
h.setNum(Settings.sub_scan_area * 2.54, 'f', 2);
}
widthLabel->setText(w);
heightLabel->setText(h);
}
void
EPScan::doScan()
{
QString fname = QFileDialog::getSaveFileName(0, "*.tif", this);
if (fname.isEmpty())
return;
if (scanner->applySettings(Settings)) {
warning("Error in settings: %s", scanner->strError());
return;
}
if (scanner->initScan(fname)) {
warning("Error initializing scan: %s", scanner->strError());
unlink(fname);
return;
}
ProgressReport *prg = new ProgressReport(scanner, this);
int res = prg->exec();
delete prg;
if (res < 0) {
warning("Picture was not successfuly scanned.");
unlink(fname);
return;
}
}
void
EPScan::doPreview()
{
ScanNewSettings set = Settings;
set.main_scan_res = set.sub_scan_res = 75;
set.main_scan_zoom = set.sub_scan_zoom = 50;
set.main_scan_offset = set.sub_scan_offset = 0.0;
set.main_scan_area = Identity.max_horiz_area;
set.sub_scan_area = Identity.max_vert_area;
set.scanmode = SCN_MODE_FAST;
char *p = tempnam(0, 0);
CHECK_PTR(p);
QString fname = (const char *)p;
free(p);
if (scanner->applySettings(set)) {
warning("Error in settings: %s", scanner->strError());
return;
}
if (scanner->initScan(fname)) {
warning("Error initializing scan: %s", scanner->strError());
unlink(fname);
return;
}
ProgressReport *prg = new ProgressReport(scanner, this);
int res = prg->exec();
delete prg;
if (res < 0) {
warning("Picture was not successfuly scanned.");
unlink(fname);
return;
}
QPixmap pix;
if (pix.load(fname))
previewWin->setPixmap(pix);
else
warning("failed to display pixmap");
unlink(fname);
}