21#ifdef HAVE_SYS_TYPES_H
22 #include <sys/types.h>
26#include <netinet/in.h>
31#include <tqradiobutton.h>
32#include <tqgroupbox.h>
33#include <tqbuttongroup.h>
34#include <tqpushbutton.h>
36#include <tqcheckbox.h>
37#include <tqapplication.h>
39#include <tqeventloop.h>
40#include <tqprogressdialog.h>
46#include <kgenericfactory.h>
47#include <kdialogbase.h>
49#include <tdemessagebox.h>
53#include <KoDocument.h>
54#include <KoFilterChain.h>
56#include "imageviewer.h"
57#include "kis_config.h"
58#include "kis_cmb_idlist.h"
60#include "kis_raw_import.h"
63#include "kis_meta_registry.h"
65#include "kis_annotation.h"
66#include "kis_profile.h"
67#include "kis_colorspace_factory_registry.h"
68#include "kis_iterators_pixel.h"
69#include "kis_abstract_colorspace.h"
70#include "kis_paint_device.h"
71#include "kis_paint_layer.h"
72#include "wdgrawimport.h"
74typedef KGenericFactory<KisRawImport, KoFilter> KisRawImportFactory;
75K_EXPORT_COMPONENT_FACTORY(libchalk_raw_import, KisRawImportFactory(
"kofficefilters"))
77KisRawImport::KisRawImport(KoFilter *, const
char *, const TQStringList&)
84 m_dialog =
new KDialogBase();
85 m_dialog->enableButtonApply(
false);
86 m_page =
new WdgRawImport(m_dialog);
87 m_dialog -> setMainWidget(m_page);
89 connect(m_page->bnPreview, TQ_SIGNAL(clicked()),
this, TQ_SLOT(slotUpdatePreview()));
90 connect(m_page->grpColorSpace, TQ_SIGNAL(clicked(
int )),
this, TQ_SLOT(slotFillCmbProfiles()));
91 connect(m_page->grpChannelDepth, TQ_SIGNAL(clicked(
int )),
this, TQ_SLOT(slotFillCmbProfiles()));
94 TQString monitorProfileName = cfg.monitorProfile();
95 m_monitorProfile = KisMetaRegistry::instance()->csRegistry()->getProfileByName(monitorProfileName);
97 slotFillCmbProfiles();
100KisRawImport::~KisRawImport()
106KoFilter::ConversionStatus KisRawImport::convert(
const TQCString& from,
const TQCString& to)
108 if (from !=
"image/x-raw" || to !=
"application/x-chalk") {
109 return KoFilter::NotImplemented;
113 return KoFilter::CreationError;
116 kdDebug(41008) <<
"Chalk importing from Raw\n";
118 KisDoc * doc =
dynamic_cast<KisDoc*
>(m_chain -> outputDocument());
120 return KoFilter::CreationError;
123 doc -> prepareForImport();
125 TQString filename = m_chain -> inputFile();
127 if (filename.isEmpty()) {
128 return KoFilter::FileNotFound;
134 m_dialog->setCursor(TQt::ArrowCursor);
135 TQApplication::setOverrideCursor(TQt::ArrowCursor);
137 TDEConfig * cfg = TDEGlobal::config();
138 cfg->setGroup(
"rawimport");
140 m_page->radioGray->setChecked(cfg->readBoolEntry(
"gray",
false));
141 m_page->radioRGB->setChecked(cfg->readBoolEntry(
"rgb",
true));
142 m_page->radio8->setChecked(cfg->readBoolEntry(
"8bit",
false));
143 m_page->radio16->setChecked(cfg->readBoolEntry(
"16bit",
true));
144 m_page->chkFourColorRGB->setChecked( cfg->readBoolEntry(
"four_color_rgb",
false));
145 m_page->chkCameraColors->setChecked( cfg->readBoolEntry(
"camera_colors",
false));
146 m_page->chkBrightness->setChecked( cfg->readBoolEntry(
"do_brightness",
false));
147 m_page->chkBlackpoint->setChecked( cfg->readBoolEntry(
"do_blackpoint",
false));
148 m_page->chkRed->setChecked( cfg->readBoolEntry(
"do_red",
false));
149 m_page->chkBlue->setChecked( cfg->readBoolEntry(
"do_blue",
false));
150 m_page->radioFixed->setChecked( cfg->readBoolEntry(
"fixed_wb",
true));
151 m_page->radioAutomatic->setChecked( cfg->readBoolEntry(
"automatic_wb",
false));
152 m_page->radioCamera->setChecked( cfg->readBoolEntry(
"camera_wb",
false));
153 m_page->chkClip->setChecked( cfg->readBoolEntry(
"clip",
true));
154 m_page->chkProfile->setChecked(cfg->readBoolEntry(
"useprofile",
false));
155 m_page->dblBrightness->setValue(cfg->readDoubleNumEntry(
"brightness", 1.0));
156 m_page->dblBlackpoint->setValue(cfg->readDoubleNumEntry(
"blackpoint", 0));
157 m_page->dblRed->setValue(cfg->readDoubleNumEntry(
"red", 1.0));
158 m_page->dblBlue->setValue(cfg->readDoubleNumEntry(
"blue", 1.0));
160 if (m_dialog->exec() == TQDialog::Accepted) {
162 cfg->writeEntry(
"gray", m_page->radioGray->isChecked());
163 cfg->writeEntry(
"rgb", m_page->radioRGB->isChecked());
164 cfg->writeEntry(
"8bit", m_page->radio8->isChecked());
165 cfg->writeEntry(
"16bit", m_page->radio16->isChecked());
166 cfg->writeEntry(
"four_color_rgb", m_page->chkFourColorRGB -> isChecked());
167 cfg->writeEntry(
"camera_colors", m_page->chkCameraColors -> isChecked());
168 cfg->writeEntry(
"do_brightness", m_page->chkBrightness -> isChecked());
169 cfg->writeEntry(
"do_blackpoint", m_page->chkBlackpoint -> isChecked());
170 cfg->writeEntry(
"do_red", m_page->chkRed -> isChecked());
171 cfg->writeEntry(
"do_blue", m_page->chkBlue -> isChecked());
172 cfg->writeEntry(
"fixed_wb", m_page->radioFixed -> isChecked());
173 cfg->writeEntry(
"automatic_wb", m_page->radioAutomatic -> isChecked());
174 cfg->writeEntry(
"camera_wb", m_page->radioCamera -> isChecked());
175 cfg->writeEntry(
"clip", m_page->chkClip->isChecked());
176 cfg->writeEntry(
"useprofile", m_page->chkProfile->isChecked());
177 cfg->writeEntry(
"brightness", m_page->dblBrightness->value());
178 cfg->writeEntry(
"blackpoint", m_page->dblBlackpoint->value());
179 cfg->writeEntry(
"red", m_page->dblRed->value());
180 cfg->writeEntry(
"blue", m_page->dblBlue->value());
182 TQApplication::setOverrideCursor(TQt::waitCursor);
184 m_progress =
new TQProgressDialog();
185 m_progress -> setTotalSteps(0);
186 m_progress -> setCancelButton(0);
188 connect(&timer, TQ_SIGNAL(timeout()),
this, TQ_SLOT(incrementProgress()));
191 doc -> undoAdapter() -> setUndo(
false);
193 getImageData(createArgumentList(
false));
195 KisImageSP image = 0;
196 KisPaintLayerSP layer = 0;
197 KisPaintDeviceSP device = 0;
199 TQApplication::restoreOverrideCursor();
204 if (m_page->radio8->isChecked()) {
208 img.loadFromData(*m_data);
210 KisColorSpace * cs = 0;
211 if (m_page->radioGray->isChecked()) {
212 cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace( KisID(
"GRAYA"), profile() );
215 cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace( KisID(
"RGBA"), profile() );
217 if (cs == 0) { kdDebug() <<
"No CS\n";
return KoFilter::InternalError; }
219 image =
new KisImage(doc->undoAdapter(), img.width(), img.height(), cs, filename);
220 if (image == 0)
return KoFilter::CreationError;
221 image->blockSignals(
true);
223 layer =
dynamic_cast<KisPaintLayer*
>( image->newLayer(image -> nextLayerName(), OPACITY_OPAQUE).data() );
224 if (layer == 0)
return KoFilter::CreationError;
226 device = layer->paintDevice();
227 if (device == 0)
return KoFilter::CreationError;
229 device->convertFromTQImage(img,
"");
234 TQ_UINT32 startOfImagedata = 0;
235 TQSize sz = determineSize(startOfImagedata);
237 kdDebug(41008) <<
"Total bytes: " << m_data->size()
238 <<
"\n start of image data: " << startOfImagedata
239 <<
"\n bytes for pixels left: " << m_data->size() - startOfImagedata
240 <<
"\n total pixels: " << sz.width() * sz.height()
241 <<
"\n total pixel bytes: " << sz.width() * sz.height() * 6
242 <<
"\n total necessary bytes: " << (sz.width() * sz.height() * 6) + startOfImagedata
246 char * data = m_data->data() + startOfImagedata;
248 KisColorSpace * cs = 0;
249 if (m_page->radioGray->isChecked()) {
250 cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace( KisID(
"GRAYA16"), profile() );
253 cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace( KisID(
"RGBA16"), profile() );
255 if (cs == 0)
return KoFilter::InternalError;
257 image =
new KisImage( doc->undoAdapter(), sz.width(), sz.height(), cs, filename);
258 if (image == 0)
return KoFilter::CreationError;
260 layer =
dynamic_cast<KisPaintLayer*
> (image->newLayer(image -> nextLayerName(), OPACITY_OPAQUE).data());
261 if (layer == 0)
return KoFilter::CreationError;
263 device = layer->paintDevice();
264 if (device == 0)
return KoFilter::CreationError;
269 for (
int line = 0; line < sz.height(); ++line) {
270 KisHLineIterator it = device->createHLineIterator(0, line, sz.width(),
true);
272 while (!it.isDone()) {
273 if (m_page->radioGray->isChecked()) {
274 TQ_UINT16 d = (TQ_INT16)*(data + pos);
276 memcpy(it.rawData(), &d, 2);
281 TQ_UINT16 d = (TQ_INT16)*(data + pos);
283 memcpy(it.rawData() + 4, &d, 2);
287 d = (TQ_INT16)*(data + pos );
289 memcpy(it.rawData() + 2, &d, 2);
293 d = (TQ_INT16)*(data + pos );
295 memcpy(it.rawData(), &d, 2);
299 cs->setAlpha(it.rawData(), OPACITY_OPAQUE, 1);
305 kdDebug() <<
"going to set image\n";
306 doc -> setCurrentImage(image);
307 doc -> undoAdapter() -> setUndo(
true);
308 doc -> setModified(
false);
309 kdDebug() <<
"everything ok\n";
311 TQApplication::restoreOverrideCursor();
315 TQApplication::restoreOverrideCursor();
316 return KoFilter::UserCancelled;
319void KisRawImport::incrementProgress()
321 m_progress -> setProgress(m_progress -> progress() + 10);
325void KisRawImport::slotUpdatePreview()
327 TQApplication::setOverrideCursor(TQt::waitCursor);
328 getImageData(createArgumentList(
true));
330 kdDebug(41008) <<
"Retrieved " << m_data->size() <<
" bytes of image data\n";
332 if (m_data->isNull())
return;
336 if (m_page->radio8->isChecked()) {
338 img.loadFromData(*m_data);
343 TQ_UINT32 startOfImagedata = 0;
344 TQSize sz = determineSize(startOfImagedata);
346 kdDebug(41008) <<
"Total bytes: " << m_data->size()
347 <<
"\n start of image data: " << startOfImagedata
348 <<
"\n bytes for pixels left: " << m_data->size() - startOfImagedata
349 <<
"\n total pixels: " << sz.width() * sz.height()
350 <<
"\n total pixel bytes: " << sz.width() * sz.height() * 6
351 <<
"\n total necessary bytes: " << (sz.width() * sz.height() * 6) + startOfImagedata
354 char * data = m_data->data() + startOfImagedata;
356 KisColorSpace * cs = 0;
357 if (m_page->radioGray->isChecked()) {
358 cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace( KisID(
"GRAYA16"), profile() );
361 cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace( KisID(
"RGBA16"), profile() );
363 KisPaintDevice * dev =
new KisPaintDevice(cs,
"preview");
367 for (
int line = 0; line < sz.height(); ++line) {
368 KisHLineIterator it = dev->createHLineIterator(0, line, sz.width(),
true);
370 while (!it.isDone()) {
371 if (m_page->radioGray->isChecked()) {
372 TQ_UINT16 d = (TQ_INT16)*(data + pos);
374 memcpy(it.rawData(), &d, 2);
379 TQ_UINT16 d = (TQ_INT16)*(data + pos);
381 memcpy(it.rawData() + 4, &d, 2);
385 d = (TQ_INT16)*(data + pos );
387 memcpy(it.rawData() + 2, &d, 2);
391 d = (TQ_INT16)*(data + pos );
393 memcpy(it.rawData(), &d, 2);
397 cs->setAlpha(it.rawData(), OPACITY_OPAQUE, 1);
402 img = dev->convertToTQImage(m_monitorProfile);
405 m_page->lblPreview->setImage(img);
406 TQApplication::restoreOverrideCursor();
410void KisRawImport::getImageData( TQStringList arguments )
415 kdDebug(41008) <<
"getImageData " << arguments.join(
" ") <<
"\n";
416 TDEProcess process (
this);
417 m_data =
new TQByteArray(0);
419 for (TQStringList::iterator it = arguments.begin(); it != arguments.end(); ++it) {
423 process.setUseShell(
true);
424 connect(&process, TQ_SIGNAL(receivedStdout(TDEProcess *,
char *,
int)),
this, TQ_SLOT(slotReceivedStdout(TDEProcess *,
char *,
int)));
425 connect(&process, TQ_SIGNAL(receivedStderr(TDEProcess *,
char *,
int)),
this, TQ_SLOT(slotReceivedStderr(TDEProcess *,
char *,
int)));
426 connect(&process, TQ_SIGNAL(processExited(TDEProcess *)),
this, TQ_SLOT(slotProcessDone()));
429 kdDebug(41008) <<
"Starting process\n";
431 if (!process.start(TDEProcess::NotifyOnExit, TDEProcess::AllOutput)) {
432 KMessageBox::error( 0, i18n(
"Cannot convert RAW files because the dcraw executable could not be started."));
434 while (process.isRunning()) {
436 tqApp->eventLoop()->processEvents(TQEventLoop::ExcludeUserInput);
440 if (process.normalExit()) {
441 kdDebug(41008) <<
"Return value of process: " << process.exitStatus() <<
"\n";
444 kdDebug(41008) <<
"Process did not exit normally. Exit signal: " << process.exitSignal() <<
"\n";
451void KisRawImport::slotProcessDone()
453 kdDebug(41008) <<
"process done!\n";
456void KisRawImport::slotReceivedStdout(TDEProcess *,
char *buffer,
int buflen)
460 int oldSize = m_data->size();
461 m_data->resize(oldSize + buflen, TQGArray::SpeedOptim);
462 memcpy(m_data->data() + oldSize, buffer, buflen);
465void KisRawImport::slotReceivedStderr(TDEProcess *,
char *buffer,
int buflen)
467 TQByteArray b(buflen);
468 memcpy(b.data(), buffer, buflen);
469 kdDebug(41008) << TQString(b) <<
"\n";
470 KMessageBox::error(0, i18n(
"Error: Dcraw cannot load this image. Message: ") + TQString(b));
475TQStringList KisRawImport::createArgumentList(
bool forPreview)
479 args.append(
"dcraw");
489 if (m_page->radio8->isChecked()) {
496 if (m_page->radioGray->isChecked()) {
500 if (m_page->chkCameraColors->isChecked()) {
504 if (m_page->radioAutomatic->isChecked()) {
508 if (m_page->radioCamera->isChecked()) {
512 if (m_page->chkFourColorRGB->isChecked()) {
516 if (!m_page->chkClip->isChecked()) {
520 if (m_page->chkBrightness->isChecked()) {
521 args.append(
"-b " + TQString::number(m_page->dblBrightness->value()));
524 if (m_page->chkBlackpoint->isChecked()) {
525 args.append(
"-k " + TQString::number(m_page->dblBlackpoint->value()));
528 if (m_page->chkRed->isChecked()) {
529 args.append(
"-r " + TQString::number(m_page->dblRed->value()));
532 if (m_page->chkBlue->isChecked()) {
533 args.append(
"-l " + TQString::number(m_page->dblBlue->value()));
537 KisProfile * pf = profile();
538 if (m_page->chkProfile->isChecked()) {
539 if (!pf->filename().isNull()) {
543 args.append(
"-p \"" + pf->filename() +
"\"");
548 args.append(
"\"" + m_chain -> inputFile() +
"\"");
553TQSize KisRawImport::determineSize(TQ_UINT32& startOfImageData)
555 if (m_data->isNull() || m_data->size() < 2048) {
556 startOfImageData = 0;
560 TQString magick = TQString::fromAscii(m_data->data(), 2);
561 if (magick !=
"P6") {
562 kdDebug(41008) <<
" Bad magick! " << magick <<
"\n";
563 startOfImageData = 0;
569 TQ_UINT32 counter = 0;
572 if (counter == 3)
break;
573 if (m_data->data()[i] ==
'\n') {
579 TQString size = TQStringList::split(
"\n", TQString::fromAscii(m_data->data(), i))[1];
580 kdDebug(41008) <<
"Header: " << TQString(TQString::fromAscii(m_data->data(), i)) <<
"\n";
581 TQStringList sizelist = TQStringList::split(
" ", size);
582 TQ_INT32 w = sizelist[0].toInt();
583 TQ_INT32 h = sizelist[1].toInt();
585 startOfImageData = i;
590KisProfile * KisRawImport::profile()
592 if (m_page->chkProfile->isChecked()) {
593 return KisMetaRegistry::instance()->csRegistry()->getProfileByName(m_page->cmbProfile->currentText());
599void KisRawImport::slotFillCmbProfiles()
601 KisID s = getColorSpace();
603 KisColorSpaceFactory * csf = KisMetaRegistry::instance()->csRegistry() -> get(s);
604 m_page -> cmbProfile -> clear();
605 TQValueVector<KisProfile *> profileList = KisMetaRegistry::instance()->csRegistry()->profilesFor( csf );
606 TQValueVector<KisProfile *> ::iterator it;
607 for ( it = profileList.begin(); it != profileList.end(); ++it ) {
608 m_page -> cmbProfile -> insertItem((*it) -> productName());
612KisID KisRawImport::getColorSpace()
614 if (m_page->radioRGB->isChecked()) {
615 if (m_page->radio16->isChecked()) {
616 return KisID(
"RGBA16" );
620 if (m_page->radio16->isChecked()) {
621 return KisID(
"GRAYA16" );
624 return KisID(
"GRAYA" );
627 return KisID(
"RGBA");
630#include "kis_raw_import.moc"