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