Fixed access to invalid bitmap bug.
Refactored code a little bit. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5746 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
5aa7212658
commit
491eb383e0
@ -55,7 +55,7 @@ FilterThread::FilterThread(Filter* filter, int32 i, int32 n, bool runInCurrentTh
|
||||
|
||||
FilterThread::~FilterThread()
|
||||
{
|
||||
fFilter->Done();
|
||||
fFilter->FilterThreadDone();
|
||||
}
|
||||
|
||||
status_t
|
||||
@ -69,8 +69,13 @@ status_t
|
||||
FilterThread::Run()
|
||||
{
|
||||
if (fI == 0) {
|
||||
BBitmap* bm;
|
||||
// create destination image in first thread
|
||||
fFilter->GetBitmap();
|
||||
bm = fFilter->GetBitmap();
|
||||
if (bm == NULL) {
|
||||
fFilter->FilterThreadInitFailed();
|
||||
return B_ERROR;
|
||||
}
|
||||
// and start other filter threads
|
||||
for (int32 i = fI + 1; i < fN; i ++) {
|
||||
new FilterThread(fFilter, i, fN);
|
||||
@ -92,22 +97,10 @@ Filter::Filter(BBitmap* image, BMessenger listener, uint32 what)
|
||||
, fNumberOfThreads(0)
|
||||
, fIsRunning(false)
|
||||
, fSrcImage(image)
|
||||
, fDestImageInitialized(false)
|
||||
, fDestImage(NULL)
|
||||
{
|
||||
// get the number of active CPUs
|
||||
int count;
|
||||
system_info info;
|
||||
get_system_info(&info);
|
||||
count = info.cpu_count;
|
||||
fCPUCount = 0;
|
||||
for (int i = 0; i < count; i ++) {
|
||||
if (_kget_cpu_state_(i)) {
|
||||
fCPUCount ++;
|
||||
}
|
||||
}
|
||||
if (fCPUCount == 0) {
|
||||
fCPUCount = 1;
|
||||
}
|
||||
fCPUCount = NumberOfActiveCPUs();
|
||||
|
||||
fWaitForThreads = create_sem(0, "wait_for_threads");
|
||||
|
||||
@ -125,7 +118,8 @@ Filter::~Filter()
|
||||
BBitmap*
|
||||
Filter::GetBitmap()
|
||||
{
|
||||
if (fDestImage == NULL) {
|
||||
if (!fDestImageInitialized) {
|
||||
fDestImageInitialized = true;
|
||||
fDestImage = CreateDestImage(fSrcImage);
|
||||
}
|
||||
return fDestImage;
|
||||
@ -180,8 +174,19 @@ Filter::Stop()
|
||||
Wait();
|
||||
}
|
||||
|
||||
bool
|
||||
Filter::IsRunning() const
|
||||
{
|
||||
return fIsRunning;
|
||||
}
|
||||
|
||||
void
|
||||
Filter::Done()
|
||||
Filter::Completed()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Filter::FilterThreadDone()
|
||||
{
|
||||
if (atomic_add(&fNumberOfThreads, -1) == 1) {
|
||||
#if TIME_FILTER
|
||||
@ -196,15 +201,20 @@ Filter::Done()
|
||||
release_sem(fWaitForThreads);
|
||||
}
|
||||
|
||||
bool
|
||||
Filter::IsRunning() const
|
||||
void
|
||||
Filter::FilterThreadInitFailed()
|
||||
{
|
||||
return fIsRunning;
|
||||
ASSERT(fNumberOfThreads == fN);
|
||||
fNumberOfThreads = 0;
|
||||
Completed();
|
||||
fIsRunning = false;
|
||||
release_sem_etc(fWaitForThreads, fN, 0);
|
||||
}
|
||||
|
||||
void
|
||||
Filter::Completed()
|
||||
bool
|
||||
Filter::IsBitmapValid(BBitmap* bitmap) const
|
||||
{
|
||||
return bitmap != NULL && bitmap->InitCheck() == B_OK && bitmap->IsValid();
|
||||
}
|
||||
|
||||
int32
|
||||
@ -233,6 +243,25 @@ Filter::GetDestImage()
|
||||
return fDestImage;
|
||||
}
|
||||
|
||||
int32
|
||||
Filter::NumberOfActiveCPUs() const
|
||||
{
|
||||
int count;
|
||||
system_info info;
|
||||
get_system_info(&info);
|
||||
count = info.cpu_count;
|
||||
int32 CPUCount = 0;
|
||||
for (int i = 0; i < count; i ++) {
|
||||
if (_kget_cpu_state_(i)) {
|
||||
CPUCount ++;
|
||||
}
|
||||
}
|
||||
if (CPUCount == 0) {
|
||||
CPUCount = 1;
|
||||
}
|
||||
return CPUCount;
|
||||
}
|
||||
|
||||
// Implementation of (bilinear) Scaler
|
||||
Scaler::Scaler(BBitmap* image, BRect rect, BMessenger listener, uint32 what, bool dither)
|
||||
: Filter(image, listener, what)
|
||||
@ -253,14 +282,28 @@ BBitmap*
|
||||
Scaler::CreateDestImage(BBitmap* srcImage)
|
||||
{
|
||||
if (srcImage == NULL || srcImage->ColorSpace() != B_RGB32 && srcImage->ColorSpace() !=B_RGBA32) return NULL;
|
||||
|
||||
BRect dest(0, 0, fRect.IntegerWidth(), fRect.IntegerHeight());
|
||||
BBitmap* destImage = new BBitmap(dest, fDither ? B_CMAP8 : srcImage->ColorSpace());
|
||||
|
||||
if (!IsBitmapValid(destImage)) {
|
||||
delete destImage;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fDither) {
|
||||
BRect dest(0, 0, fRect.IntegerWidth(), fRect.IntegerHeight());
|
||||
fScaledImage = new BBitmap(dest, srcImage->ColorSpace());
|
||||
if (!IsBitmapValid(fScaledImage)) {
|
||||
delete destImage;
|
||||
delete fScaledImage;
|
||||
fScaledImage = NULL;
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
fScaledImage = destImage;
|
||||
}
|
||||
|
||||
return destImage;
|
||||
}
|
||||
|
||||
@ -906,7 +949,10 @@ ImageProcessor::CreateDestImage(BBitmap* srcImage)
|
||||
}
|
||||
|
||||
bm = new BBitmap(rect, cs);
|
||||
if (bm == NULL) return NULL;
|
||||
if (!IsBitmapValid(bm)) {
|
||||
delete bm;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fSrcBPR = GetSrcImage()->BytesPerRow();
|
||||
fDestBPR = bm->BytesPerRow();
|
||||
|
@ -69,9 +69,10 @@ public:
|
||||
private:
|
||||
status_t Run();
|
||||
static status_t worker_thread(void* data);
|
||||
|
||||
Filter* fFilter;
|
||||
int32 fI;
|
||||
int32 fN;
|
||||
int32 fI;
|
||||
int32 fN;
|
||||
};
|
||||
|
||||
class Filter {
|
||||
@ -125,7 +126,10 @@ public:
|
||||
virtual void Completed();
|
||||
|
||||
// Used by FilterThread only!
|
||||
void Done();
|
||||
void FilterThreadDone();
|
||||
void FilterThreadInitFailed();
|
||||
|
||||
bool IsBitmapValid(BBitmap* bitmap) const;
|
||||
|
||||
protected:
|
||||
// Number of threads to be used to perform the operation
|
||||
@ -134,21 +138,23 @@ protected:
|
||||
BBitmap* GetDestImage();
|
||||
|
||||
private:
|
||||
int32 NumberOfActiveCPUs() const;
|
||||
// Returns the number of active CPUs
|
||||
int32 CPUCount() const { return fCPUCount; }
|
||||
|
||||
BMessenger fListener;
|
||||
uint32 fWhat;
|
||||
int32 fCPUCount; // the number of active CPUs
|
||||
bool fStarted; // has Start() been called?
|
||||
sem_id fWaitForThreads; // to exit
|
||||
int32 fN; // the number of used filter threads
|
||||
BMessenger fListener;
|
||||
uint32 fWhat;
|
||||
int32 fCPUCount; // the number of active CPUs
|
||||
bool fStarted; // has Start() been called?
|
||||
sem_id fWaitForThreads; // to exit
|
||||
int32 fN; // the number of used filter threads
|
||||
volatile int32 fNumberOfThreads; // the current number of FilterThreads
|
||||
volatile bool fIsRunning; // FilterThreads should process data as long as it is true
|
||||
BBitmap* fSrcImage;
|
||||
BBitmap* fDestImage;
|
||||
volatile bool fIsRunning; // FilterThreads should process data as long as it is true
|
||||
BBitmap* fSrcImage;
|
||||
bool fDestImageInitialized;
|
||||
BBitmap* fDestImage;
|
||||
#if TIME_FILTER
|
||||
BStopWatch* fStopWatch;
|
||||
BStopWatch* fStopWatch;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -201,8 +207,10 @@ private:
|
||||
|
||||
enum operation fOp;
|
||||
int32 fBPP;
|
||||
int32 fWidth, fHeight;
|
||||
int32 fSrcBPR, fDestBPR;
|
||||
int32 fWidth;
|
||||
int32 fHeight;
|
||||
int32 fSrcBPR;
|
||||
int32 fDestBPR;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1945,6 +1945,10 @@ ShowImageView::DoImageOperation(ImageProcessor::operation op, bool quiet)
|
||||
ImageProcessor imageProcessor(op, fBitmap, msgr, 0);
|
||||
imageProcessor.Start(false);
|
||||
BBitmap* bm = imageProcessor.DetachBitmap();
|
||||
if (bm == NULL) {
|
||||
// operation failed
|
||||
return;
|
||||
}
|
||||
|
||||
// update orientation state
|
||||
if (op != ImageProcessor::kInvert) {
|
||||
|
Loading…
Reference in New Issue
Block a user