You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
digikam/digikam/libs/dimg/filters/dimgthreadedfilter.cpp

171 lines
4.5 KiB

/* ============================================================
*
* This file is a part of digiKam project
* http://www.digikam.org
*
* Date : 2005-05-25
* Description : threaded image filter class.
*
* Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
*
* 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, 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.
*
* ============================================================ */
// TQt includes.
#include <tqobject.h>
#include <tqevent.h>
#include <tqdeepcopy.h>
// Local includes.
#include "ddebug.h"
#include "dimgthreadedfilter.h"
namespace Digikam
{
DImgThreadedFilter::DImgThreadedFilter(DImg *orgImage, TQObject *parent,
const TQString& name)
: TQThread()
{
// remove meta data
m_orgImage = orgImage->copyImageData();
m_parent = parent;
m_cancel = false;
// See B.K.O #133026: make a deep copy of Qstring to prevent crash
// on Hyperthreading computer.
m_name = TQDeepCopy<TQString>(name);
m_master = 0;
m_slave = 0;
m_progressBegin = 0;
m_progressSpan = 100;
}
DImgThreadedFilter::DImgThreadedFilter(DImgThreadedFilter *master, const DImg &orgImage,
const DImg &destImage, int progressBegin, int progressEnd,
const TQString& name)
{
m_orgImage = orgImage;
m_destImage = destImage;
m_parent = 0;
m_cancel = false;
// See B.K.O #133026: make a deep copy of Qstring to prevent crash
// on Hyperthreading computer.
m_name = TQDeepCopy<TQString>(name);
m_master = master;
m_slave = 0;
m_progressBegin = progressBegin;
m_progressSpan = progressEnd - progressBegin;
m_master->setSlave(this);
}
DImgThreadedFilter::~DImgThreadedFilter()
{
stopComputation();
if (m_master)
m_master->setSlave(0);
}
void DImgThreadedFilter::initFilter(void)
{
m_destImage.reset();
m_destImage = DImg(m_orgImage.width(), m_orgImage.height(),
m_orgImage.sixteenBit(), m_orgImage.hasAlpha());
if (m_orgImage.width() && m_orgImage.height())
{
if (m_parent)
start(); // m_parent is valide, start thread ==> run()
else
startComputation(); // no parent : no using thread.
}
else // No image data
{
if (m_parent) // If parent then send event about a problem.
{
postProgress(0, false, false);
DDebug() << m_name << "::No valid image data !!! ..." << endl;
}
}
}
void DImgThreadedFilter::stopComputation(void)
{
m_cancel = true;
if (m_slave)
{
m_slave->m_cancel = true;
// do not wait on slave, it is not running in its own separate thread!
//m_slave->cleanupFilter();
}
wait();
cleanupFilter();
}
void DImgThreadedFilter::postProgress(int progress, bool starting, bool success)
{
if (m_master)
{
progress = modulateProgress(progress);
m_master->postProgress(progress, starting, success);
}
else if (m_parent)
{
EventData *eventData = new EventData();
eventData->progress = progress;
eventData->starting = starting;
eventData->success = success;
TQApplication::postEvent(m_parent, new TQCustomEvent(TQEvent::User, eventData));
}
}
void DImgThreadedFilter::startComputation()
{
// See B.K.O #133026: do not use kdDebug() statements in threaded implementation
// to prevent crash under Hyperthreaded CPU.
if (m_parent)
postProgress(0, true, false);
filterImage();
if (!m_cancel)
{
if (m_parent)
postProgress(0, false, true);
}
else
{
if (m_parent)
postProgress(0, false, false);
}
}
void DImgThreadedFilter::setSlave(DImgThreadedFilter *slave)
{
m_slave = slave;
}
int DImgThreadedFilter::modulateProgress(int progress)
{
return m_progressBegin + (int)((double)progress * (double)m_progressSpan / 100.0);
}
} // NameSpace Digikam