Coding style changes, no functional change.
Hope all's OK, Filter.h is still mostly untouched as it's quite messy with many exessive commenting.
This commit is contained in:
+180
-129
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2006, Haiku.
|
* Copyright 2003-2006, Haiku, Inc. All rights reserved.
|
||||||
* Copyright 2004-2005 yellowTAB GmbH. All Rights Reserverd.
|
* Copyright 2004-2005 yellowTAB GmbH. All Rights Reserved.
|
||||||
* Copyright 2006 Bernd Korz. All Rights Reserved
|
* Copyright 2006 Bernd Korz. All Rights Reserved
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
@@ -21,29 +21,32 @@
|
|||||||
|
|
||||||
|
|
||||||
// Implementation of FilterThread
|
// Implementation of FilterThread
|
||||||
FilterThread::FilterThread(Filter* filter, int32 i, int32 n, bool runInCurrentThread)
|
FilterThread::FilterThread(Filter* filter, int32 i, int32 n,
|
||||||
: fFilter(filter)
|
bool runInCurrentThread)
|
||||||
, fI(i)
|
: fFilter(filter),
|
||||||
, fN(n)
|
fI(i),
|
||||||
|
fN(n)
|
||||||
{
|
{
|
||||||
if (runInCurrentThread) {
|
if (runInCurrentThread)
|
||||||
Run();
|
Run();
|
||||||
} else {
|
else {
|
||||||
thread_id tid;
|
thread_id tid;
|
||||||
tid = spawn_thread(worker_thread, "filter", suggest_thread_priority(B_STATUS_RENDERING), this);
|
tid = spawn_thread(worker_thread, "filter",
|
||||||
if (tid >= 0) {
|
suggest_thread_priority(B_STATUS_RENDERING), this);
|
||||||
|
if (tid >= 0)
|
||||||
resume_thread(tid);
|
resume_thread(tid);
|
||||||
} else {
|
else
|
||||||
delete this;
|
delete this;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FilterThread::~FilterThread()
|
FilterThread::~FilterThread()
|
||||||
{
|
{
|
||||||
fFilter->FilterThreadDone();
|
fFilter->FilterThreadDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
FilterThread::worker_thread(void* data)
|
FilterThread::worker_thread(void* data)
|
||||||
{
|
{
|
||||||
@@ -51,6 +54,7 @@ FilterThread::worker_thread(void* data)
|
|||||||
return thread->Run();
|
return thread->Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
FilterThread::Run()
|
FilterThread::Run()
|
||||||
{
|
{
|
||||||
@@ -67,24 +71,25 @@ FilterThread::Run()
|
|||||||
new FilterThread(fFilter, i, fN);
|
new FilterThread(fFilter, i, fN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fFilter->GetBitmap()) {
|
if (fFilter->GetBitmap())
|
||||||
fFilter->Run(fI, fN);
|
fFilter->Run(fI, fN);
|
||||||
}
|
|
||||||
delete this;
|
delete this;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implementation of Filter
|
// Implementation of Filter
|
||||||
Filter::Filter(BBitmap* image, BMessenger listener, uint32 what)
|
Filter::Filter(BBitmap* image, BMessenger listener, uint32 what)
|
||||||
: fListener(listener)
|
:
|
||||||
, fWhat(what)
|
fListener(listener),
|
||||||
, fStarted(false)
|
fWhat(what),
|
||||||
, fN(0)
|
fStarted(false),
|
||||||
, fNumberOfThreads(0)
|
fN(0),
|
||||||
, fIsRunning(false)
|
fNumberOfThreads(0),
|
||||||
, fSrcImage(image)
|
fIsRunning(false),
|
||||||
, fDestImageInitialized(false)
|
fSrcImage(image),
|
||||||
, fDestImage(NULL)
|
fDestImageInitialized(false),
|
||||||
|
fDestImage(NULL)
|
||||||
{
|
{
|
||||||
fCPUCount = NumberOfActiveCPUs();
|
fCPUCount = NumberOfActiveCPUs();
|
||||||
|
|
||||||
@@ -95,12 +100,14 @@ Filter::Filter(BBitmap* image, BMessenger listener, uint32 what)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Filter::~Filter()
|
Filter::~Filter()
|
||||||
{
|
{
|
||||||
delete fDestImage;
|
delete fDestImage;
|
||||||
delete_sem(fWaitForThreads);
|
delete_sem(fWaitForThreads);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BBitmap*
|
BBitmap*
|
||||||
Filter::GetBitmap()
|
Filter::GetBitmap()
|
||||||
{
|
{
|
||||||
@@ -111,6 +118,7 @@ Filter::GetBitmap()
|
|||||||
return fDestImage;
|
return fDestImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BBitmap*
|
BBitmap*
|
||||||
Filter::DetachBitmap()
|
Filter::DetachBitmap()
|
||||||
{
|
{
|
||||||
@@ -119,6 +127,7 @@ Filter::DetachBitmap()
|
|||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Filter::Start(bool async)
|
Filter::Start(bool async)
|
||||||
{
|
{
|
||||||
@@ -136,11 +145,11 @@ Filter::Start(bool async)
|
|||||||
// start first filter thread
|
// start first filter thread
|
||||||
new FilterThread(this, 0, fN, !async);
|
new FilterThread(this, 0, fN, !async);
|
||||||
|
|
||||||
if (!async) {
|
if (!async)
|
||||||
Wait();
|
Wait();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Filter::Wait()
|
Filter::Wait()
|
||||||
{
|
{
|
||||||
@@ -152,6 +161,7 @@ Filter::Wait()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Filter::Stop()
|
Filter::Stop()
|
||||||
{
|
{
|
||||||
@@ -160,17 +170,20 @@ Filter::Stop()
|
|||||||
Wait();
|
Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Filter::IsRunning() const
|
Filter::IsRunning() const
|
||||||
{
|
{
|
||||||
return fIsRunning;
|
return fIsRunning;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Filter::Completed()
|
Filter::Completed()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Filter::FilterThreadDone()
|
Filter::FilterThreadDone()
|
||||||
{
|
{
|
||||||
@@ -179,14 +192,15 @@ Filter::FilterThreadDone()
|
|||||||
delete fStopWatch; fStopWatch = NULL;
|
delete fStopWatch; fStopWatch = NULL;
|
||||||
#endif
|
#endif
|
||||||
Completed();
|
Completed();
|
||||||
if (fIsRunning) {
|
if (fIsRunning)
|
||||||
fListener.SendMessage(fWhat);
|
fListener.SendMessage(fWhat);
|
||||||
}
|
|
||||||
fIsRunning = false;
|
fIsRunning = false;
|
||||||
}
|
}
|
||||||
release_sem(fWaitForThreads);
|
release_sem(fWaitForThreads);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Filter::FilterThreadInitFailed()
|
Filter::FilterThreadInitFailed()
|
||||||
{
|
{
|
||||||
@@ -197,38 +211,43 @@ Filter::FilterThreadInitFailed()
|
|||||||
release_sem_etc(fWaitForThreads, fN, 0);
|
release_sem_etc(fWaitForThreads, fN, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Filter::IsBitmapValid(BBitmap* bitmap) const
|
Filter::IsBitmapValid(BBitmap* bitmap) const
|
||||||
{
|
{
|
||||||
return bitmap != NULL && bitmap->InitCheck() == B_OK && bitmap->IsValid();
|
return bitmap != NULL && bitmap->InitCheck() == B_OK && bitmap->IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
Filter::NumberOfThreads()
|
Filter::NumberOfThreads()
|
||||||
{
|
{
|
||||||
const int32 units = GetNumberOfUnits();
|
const int32 units = GetNumberOfUnits();
|
||||||
int32 n;
|
int32 n;
|
||||||
n = units / 32; // at least 32 units per CPU
|
n = units / 32; // at least 32 units per CPU
|
||||||
if (n > CPUCount()) {
|
if (n > CPUCount())
|
||||||
n = CPUCount();
|
n = CPUCount();
|
||||||
} else if (n <= 0) {
|
else if (n <= 0)
|
||||||
n = 1; // at least one thread!
|
n = 1; // at least one thread!
|
||||||
}
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BBitmap*
|
BBitmap*
|
||||||
Filter::GetSrcImage()
|
Filter::GetSrcImage()
|
||||||
{
|
{
|
||||||
return fSrcImage;
|
return fSrcImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BBitmap*
|
BBitmap*
|
||||||
Filter::GetDestImage()
|
Filter::GetDestImage()
|
||||||
{
|
{
|
||||||
return fDestImage;
|
return fDestImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
Filter::NumberOfActiveCPUs() const
|
Filter::NumberOfActiveCPUs() const
|
||||||
{
|
{
|
||||||
@@ -247,15 +266,19 @@ Filter::NumberOfActiveCPUs() const
|
|||||||
return cpuCount;
|
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,
|
||||||
: Filter(image, listener, what)
|
bool dither)
|
||||||
, fScaledImage(NULL)
|
:
|
||||||
, fRect(rect)
|
Filter(image, listener, what),
|
||||||
, fDither(dither)
|
fScaledImage(NULL),
|
||||||
|
fRect(rect),
|
||||||
|
fDither(dither)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Scaler::~Scaler()
|
Scaler::~Scaler()
|
||||||
{
|
{
|
||||||
if (GetDestImage() != fScaledImage) {
|
if (GetDestImage() != fScaledImage) {
|
||||||
@@ -264,13 +287,17 @@ Scaler::~Scaler()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BBitmap*
|
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)) {
|
if (!IsBitmapValid(destImage)) {
|
||||||
delete destImage;
|
delete destImage;
|
||||||
@@ -287,19 +314,19 @@ Scaler::CreateDestImage(BBitmap* srcImage)
|
|||||||
fScaledImage = NULL;
|
fScaledImage = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else
|
||||||
fScaledImage = destImage;
|
fScaledImage = destImage;
|
||||||
}
|
|
||||||
|
|
||||||
return destImage;
|
return destImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Scaler::Matches(BRect rect, bool dither) const
|
Scaler::Matches(BRect rect, bool dither) const
|
||||||
{
|
{
|
||||||
return fRect.IntegerWidth() == rect.IntegerWidth() &&
|
return fRect.IntegerWidth() == rect.IntegerWidth()
|
||||||
fRect.IntegerHeight() == rect.IntegerHeight() &&
|
&& fRect.IntegerHeight() == rect.IntegerHeight()
|
||||||
fDither == dither;
|
&& fDither == dither;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -310,6 +337,7 @@ typedef struct {
|
|||||||
float alpha1;
|
float alpha1;
|
||||||
} ColumnData;
|
} ColumnData;
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Scaler::ScaleBilinear(intType fromRow, int32 toRow)
|
Scaler::ScaleBilinear(intType fromRow, int32 toRow)
|
||||||
{
|
{
|
||||||
@@ -343,7 +371,7 @@ Scaler::ScaleBilinear(intType fromRow, int32 toRow)
|
|||||||
|
|
||||||
columnData = new ColumnData[destW];
|
columnData = new ColumnData[destW];
|
||||||
cd = columnData;
|
cd = columnData;
|
||||||
for (i = 0; i < destW; i ++, cd++) {
|
for (i = 0; i < destW; i++, cd++) {
|
||||||
float column = (float)i * (float)srcW / (float)destW;
|
float column = (float)i * (float)srcW / (float)destW;
|
||||||
cd->srcColumn = (intType)column;
|
cd->srcColumn = (intType)column;
|
||||||
cd->alpha1 = column - cd->srcColumn;
|
cd->alpha1 = column - cd->srcColumn;
|
||||||
@@ -352,16 +380,16 @@ Scaler::ScaleBilinear(intType fromRow, int32 toRow)
|
|||||||
|
|
||||||
destDataRow = destBits + fromRow * destBPR;
|
destDataRow = destBits + fromRow * destBPR;
|
||||||
|
|
||||||
for (y = fromRow; IsRunning() && y <= toRow; y ++, destDataRow += destBPR) {
|
for (y = fromRow; IsRunning() && y <= toRow; y++, destDataRow += destBPR) {
|
||||||
float row;
|
float row;
|
||||||
intType srcRow;
|
intType srcRow;
|
||||||
float alpha0, alpha1;
|
float alpha0, alpha1;
|
||||||
|
|
||||||
if (destH == 0) {
|
if (destH == 0)
|
||||||
row = 0;
|
row = 0;
|
||||||
} else {
|
else
|
||||||
row = (float)y * (float)srcH / (float)destH;
|
row = (float)y * (float)srcH / (float)destH;
|
||||||
}
|
|
||||||
srcRow = (intType)row;
|
srcRow = (intType)row;
|
||||||
alpha1 = row - srcRow;
|
alpha1 = row - srcRow;
|
||||||
alpha0 = 1.0 - alpha1;
|
alpha0 = 1.0 - alpha1;
|
||||||
@@ -434,6 +462,7 @@ Scaler::ScaleBilinear(intType fromRow, int32 toRow)
|
|||||||
delete[] columnData;
|
delete[] columnData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Scale bilinear using fixed point calculations
|
// Scale bilinear using fixed point calculations
|
||||||
// Is already more than two times faster than floating point version
|
// Is already more than two times faster than floating point version
|
||||||
// on AMD Athlon 1 GHz and Dual Intel Pentium III 866 MHz.
|
// on AMD Athlon 1 GHz and Dual Intel Pentium III 866 MHz.
|
||||||
@@ -444,6 +473,7 @@ typedef struct {
|
|||||||
fixed_point alpha1;
|
fixed_point alpha1;
|
||||||
} ColumnDataFP;
|
} ColumnDataFP;
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Scaler::ScaleBilinearFP(intType fromRow, int32 toRow)
|
Scaler::ScaleBilinearFP(intType fromRow, int32 toRow)
|
||||||
{
|
{
|
||||||
@@ -482,8 +512,9 @@ Scaler::ScaleBilinearFP(intType fromRow, int32 toRow)
|
|||||||
|
|
||||||
columnData = new ColumnDataFP[destW];
|
columnData = new ColumnDataFP[destW];
|
||||||
cd = columnData;
|
cd = columnData;
|
||||||
for (i = 0; i < destW; i ++, cd++) {
|
for (i = 0; i < destW; i++, cd++) {
|
||||||
fixed_point column = to_fixed_point(i) * (long_fixed_point)fpSrcW / fpDestW;
|
fixed_point column = to_fixed_point(i) * (long_fixed_point)fpSrcW
|
||||||
|
/ fpDestW;
|
||||||
cd->srcColumn = from_fixed_point(column);
|
cd->srcColumn = from_fixed_point(column);
|
||||||
cd->alpha1 = tail_value(column); // weigth for left pixel value
|
cd->alpha1 = tail_value(column); // weigth for left pixel value
|
||||||
cd->alpha0 = kFPOne - cd->alpha1; // weigth for right pixel value
|
cd->alpha0 = kFPOne - cd->alpha1; // weigth for right pixel value
|
||||||
@@ -491,18 +522,18 @@ Scaler::ScaleBilinearFP(intType fromRow, int32 toRow)
|
|||||||
|
|
||||||
destDataRow = destBits + fromRow * destBPR;
|
destDataRow = destBits + fromRow * destBPR;
|
||||||
|
|
||||||
for (y = fromRow; IsRunning() && y <= toRow; y ++, destDataRow += destBPR) {
|
for (y = fromRow; IsRunning() && y <= toRow; y++, destDataRow += destBPR) {
|
||||||
fixed_point row;
|
fixed_point row;
|
||||||
intType srcRow;
|
intType srcRow;
|
||||||
fixed_point alpha0, alpha1;
|
fixed_point alpha0, alpha1;
|
||||||
|
|
||||||
if (fpDestH == 0) {
|
if (fpDestH == 0)
|
||||||
row = 0;
|
row = 0;
|
||||||
} else {
|
else
|
||||||
row = to_fixed_point(y) * (long_fixed_point)fpSrcH / fpDestH;
|
row = to_fixed_point(y) * (long_fixed_point)fpSrcH / fpDestH;
|
||||||
}
|
|
||||||
srcRow = from_fixed_point(row);
|
srcRow = from_fixed_point(row);
|
||||||
alpha1 = tail_value(row); // weight for row y+1
|
alpha1 = tail_value(row); // weight for row y + 1
|
||||||
alpha0 = kFPOne - alpha1; // weight for row y
|
alpha0 = kFPOne - alpha1; // weight for row y
|
||||||
|
|
||||||
srcData = srcBits + srcRow * srcBPR;
|
srcData = srcBits + srcRow * srcBPR;
|
||||||
@@ -566,14 +597,15 @@ Scaler::ScaleBilinearFP(intType fromRow, int32 toRow)
|
|||||||
destData[2] = a[2];
|
destData[2] = a[2];
|
||||||
destData[3] = a[3];
|
destData[3] = a[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] columnData;
|
delete[] columnData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Scaler::RowValues(float* sum, const uchar* src, intType srcW, intType fromX, intType toX, const float a0X, const float a1X, const int32 kBPP)
|
Scaler::RowValues(float* sum, const uchar* src, intType srcW, intType fromX,
|
||||||
|
intType toX, const float a0X, const float a1X, const int32 kBPP)
|
||||||
{
|
{
|
||||||
sum[0] = a0X * src[0];
|
sum[0] = a0X * src[0];
|
||||||
sum[1] = a0X * src[1];
|
sum[1] = a0X * src[1];
|
||||||
@@ -581,7 +613,7 @@ Scaler::RowValues(float* sum, const uchar* src, intType srcW, intType fromX, int
|
|||||||
|
|
||||||
src += kBPP;
|
src += kBPP;
|
||||||
|
|
||||||
for (int32 x = fromX+1; x < toX; x ++, src += kBPP) {
|
for (int32 x = fromX + 1; x < toX; x++, src += kBPP) {
|
||||||
sum[0] += src[0];
|
sum[0] += src[0];
|
||||||
sum[1] += src[1];
|
sum[1] += src[1];
|
||||||
sum[2] += src[2];
|
sum[2] += src[2];
|
||||||
@@ -594,6 +626,7 @@ Scaler::RowValues(float* sum, const uchar* src, intType srcW, intType fromX, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32 from;
|
int32 from;
|
||||||
int32 to;
|
int32 to;
|
||||||
@@ -601,6 +634,7 @@ typedef struct {
|
|||||||
float alpha1;
|
float alpha1;
|
||||||
} DownScaleColumnData;
|
} DownScaleColumnData;
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Scaler::DownScaleBilinear(intType fromRow, int32 toRow)
|
Scaler::DownScaleBilinear(intType fromRow, int32 toRow)
|
||||||
{
|
{
|
||||||
@@ -637,9 +671,9 @@ Scaler::DownScaleBilinear(intType fromRow, int32 toRow)
|
|||||||
const float deltaY = (srcH + 1.0) / (destH + 1.0);
|
const float deltaY = (srcH + 1.0) / (destH + 1.0);
|
||||||
const float deltaXY = deltaX * deltaY;
|
const float deltaXY = deltaX * deltaY;
|
||||||
|
|
||||||
columnData = new DownScaleColumnData[destW+1];
|
columnData = new DownScaleColumnData[destW + 1];
|
||||||
DownScaleColumnData* cd = columnData;
|
DownScaleColumnData* cd = columnData;
|
||||||
for (x = 0; x <= destW; x ++, cd ++) {
|
for (x = 0; x <= destW; x++, cd++) {
|
||||||
const float fFromX = x * deltaX;
|
const float fFromX = x * deltaX;
|
||||||
const float fToX = fFromX + deltaX;
|
const float fToX = fFromX + deltaX;
|
||||||
|
|
||||||
@@ -664,7 +698,7 @@ Scaler::DownScaleBilinear(intType fromRow, int32 toRow)
|
|||||||
destData = destDataRow;
|
destData = destDataRow;
|
||||||
|
|
||||||
cd = columnData;
|
cd = columnData;
|
||||||
for (x = 0; x <= destW; x ++, destData += kBPP, cd ++) {
|
for (x = 0; x <= destW; x++, destData += kBPP, cd++) {
|
||||||
const intType fromX = cd->from;
|
const intType fromX = cd->from;
|
||||||
const intType toX = cd->to;
|
const intType toX = cd->to;
|
||||||
|
|
||||||
@@ -683,7 +717,7 @@ Scaler::DownScaleBilinear(intType fromRow, int32 toRow)
|
|||||||
|
|
||||||
srcData += srcBPR;
|
srcData += srcBPR;
|
||||||
|
|
||||||
for (int32 r = fromY+1; r < toY; r ++, srcData += srcBPR) {
|
for (int32 r = fromY + 1; r < toY; r++, srcData += srcBPR) {
|
||||||
RowValues(sum, srcData, srcW, fromX, toX, a0X, a1X, kBPP);
|
RowValues(sum, srcData, srcW, fromX, toX, a0X, a1X, kBPP);
|
||||||
totalSum[0] += sum[0];
|
totalSum[0] += sum[0];
|
||||||
totalSum[1] += sum[1];
|
totalSum[1] += sum[1];
|
||||||
@@ -706,6 +740,7 @@ Scaler::DownScaleBilinear(intType fromRow, int32 toRow)
|
|||||||
delete[] columnData;
|
delete[] columnData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Flyod-Steinberg Dithering
|
// Flyod-Steinberg Dithering
|
||||||
// Filter (distribution of error to adjacent pixels, X is current pixel):
|
// Filter (distribution of error to adjacent pixels, X is current pixel):
|
||||||
// 0 X 7
|
// 0 X 7
|
||||||
@@ -715,6 +750,7 @@ typedef struct {
|
|||||||
intType error[3];
|
intType error[3];
|
||||||
} DitheringColumnData;
|
} DitheringColumnData;
|
||||||
|
|
||||||
|
|
||||||
uchar
|
uchar
|
||||||
Scaler::Limit(intType value)
|
Scaler::Limit(intType value)
|
||||||
{
|
{
|
||||||
@@ -726,6 +762,7 @@ Scaler::Limit(intType value)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Scaler::Dither(int32 fromRow, int32 toRow)
|
Scaler::Dither(int32 fromRow, int32 toRow)
|
||||||
{
|
{
|
||||||
@@ -766,19 +803,20 @@ Scaler::Dither(int32 fromRow, int32 toRow)
|
|||||||
destBPR = dest->BytesPerRow();
|
destBPR = dest->BytesPerRow();
|
||||||
|
|
||||||
// Allocate space for sentinel at left and right bounds,
|
// Allocate space for sentinel at left and right bounds,
|
||||||
// so that columnData[-1] and columnData[destW+1] can be safely accessed
|
// so that columnData[-1] and columnData[destW + 1] can be safely accessed
|
||||||
columnData0 = new DitheringColumnData[destW+3];
|
columnData0 = new DitheringColumnData[destW + 3];
|
||||||
columnData = columnData0 + 1;
|
columnData = columnData0 + 1;
|
||||||
|
|
||||||
// clear error
|
// clear error
|
||||||
cd = columnData;
|
cd = columnData;
|
||||||
for (x = destW; x >= 0; x --, cd ++) {
|
for (x = destW; x >= 0; x --, cd++) {
|
||||||
cd->error[0] = cd->error[1] = cd->error[2] =0;
|
cd->error[0] = cd->error[1] = cd->error[2] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
srcDataRow = srcBits + fromRow * srcBPR;
|
srcDataRow = srcBits + fromRow * srcBPR;
|
||||||
destDataRow = destBits + fromRow * destBPR;
|
destDataRow = destBits + fromRow * destBPR;
|
||||||
for (y = fromRow; IsRunning() && y <= toRow; y ++, srcDataRow += srcBPR, destDataRow += destBPR) {
|
for (y = fromRow; IsRunning() && y <= toRow; y++, srcDataRow += srcBPR,
|
||||||
|
destDataRow += destBPR) {
|
||||||
// left to right
|
// left to right
|
||||||
error[0] = error[1] = error[2] = 0;
|
error[0] = error[1] = error[2] = 0;
|
||||||
srcData = srcDataRow;
|
srcData = srcDataRow;
|
||||||
@@ -797,12 +835,12 @@ Scaler::Dither(int32 fromRow, int32 toRow)
|
|||||||
*destData = index;
|
*destData = index;
|
||||||
|
|
||||||
err[0] = color.red - actualColor.red;
|
err[0] = color.red - actualColor.red;
|
||||||
err[1] = color.green -actualColor.green;
|
err[1] = color.green - actualColor.green;
|
||||||
err[2] = color.blue -actualColor.blue;
|
err[2] = color.blue - actualColor.blue;
|
||||||
|
|
||||||
// distribute error
|
// distribute error
|
||||||
// get error for next pixel
|
// get error for next pixel
|
||||||
cd = &columnData[x+1];
|
cd = &columnData[x + 1];
|
||||||
error[0] = cd->error[0] + 7 * err[0];
|
error[0] = cd->error[0] + 7 * err[0];
|
||||||
error[1] = cd->error[1] + 7 * err[1];
|
error[1] = cd->error[1] + 7 * err[1];
|
||||||
error[2] = cd->error[2] + 7 * err[2];
|
error[2] = cd->error[2] + 7 * err[2];
|
||||||
@@ -813,27 +851,27 @@ Scaler::Dither(int32 fromRow, int32 toRow)
|
|||||||
cd->error[2] = err[2];
|
cd->error[2] = err[2];
|
||||||
|
|
||||||
// add error for pixel below current pixel
|
// add error for pixel below current pixel
|
||||||
cd --;
|
cd--;
|
||||||
cd->error[0] += 5 * err[0];
|
cd->error[0] += 5 * err[0];
|
||||||
cd->error[1] += 5 * err[1];
|
cd->error[1] += 5 * err[1];
|
||||||
cd->error[2] += 5 * err[2];
|
cd->error[2] += 5 * err[2];
|
||||||
|
|
||||||
// add error for left pixel below current pixel
|
// add error for left pixel below current pixel
|
||||||
cd --;
|
cd--;
|
||||||
cd->error[0] += 3 * err[0];
|
cd->error[0] += 3 * err[0];
|
||||||
cd->error[1] += 3 * err[1];
|
cd->error[1] += 3 * err[1];
|
||||||
cd->error[2] += 3 * err[2];
|
cd->error[2] += 3 * err[2];
|
||||||
}
|
}
|
||||||
// Note: Alogrithm has good results with "left to right" already
|
// Note: Alogrithm has good results with "left to right" already
|
||||||
// Optionally remove code to end of block:
|
// Optionally remove code to end of block:
|
||||||
y ++;
|
y++;
|
||||||
srcDataRow += srcBPR; destDataRow += destBPR;
|
srcDataRow += srcBPR; destDataRow += destBPR;
|
||||||
if (y > toRow) break;
|
if (y > toRow) break;
|
||||||
// right to left
|
// right to left
|
||||||
error[0] = error[1] = error[2] = 0;
|
error[0] = error[1] = error[2] = 0;
|
||||||
srcData = srcDataRow + destW * kBPP;
|
srcData = srcDataRow + destW * kBPP;
|
||||||
destData = destDataRow + destW;
|
destData = destDataRow + destW;
|
||||||
for (x = 0; x <= destW; x ++, srcData -= kBPP, destData -= 1) {
|
for (x = 0; x <= destW; x++, srcData -= kBPP, destData -= 1) {
|
||||||
rgb_color color, actualColor;
|
rgb_color color, actualColor;
|
||||||
uint8 index;
|
uint8 index;
|
||||||
|
|
||||||
@@ -847,12 +885,12 @@ Scaler::Dither(int32 fromRow, int32 toRow)
|
|||||||
*destData = index;
|
*destData = index;
|
||||||
|
|
||||||
err[0] = color.red - actualColor.red;
|
err[0] = color.red - actualColor.red;
|
||||||
err[1] = color.green -actualColor.green;
|
err[1] = color.green - actualColor.green;
|
||||||
err[2] = color.blue -actualColor.blue;
|
err[2] = color.blue - actualColor.blue;
|
||||||
|
|
||||||
// distribute error
|
// distribute error
|
||||||
// get error for next pixel
|
// get error for next pixel
|
||||||
cd = &columnData[x-1];
|
cd = &columnData[x - 1];
|
||||||
error[0] = cd->error[0] + 7 * err[0];
|
error[0] = cd->error[0] + 7 * err[0];
|
||||||
error[1] = cd->error[1] + 7 * err[1];
|
error[1] = cd->error[1] + 7 * err[1];
|
||||||
error[2] = cd->error[2] + 7 * err[2];
|
error[2] = cd->error[2] + 7 * err[2];
|
||||||
@@ -863,13 +901,13 @@ Scaler::Dither(int32 fromRow, int32 toRow)
|
|||||||
cd->error[2] = err[2];
|
cd->error[2] = err[2];
|
||||||
|
|
||||||
// add error for pixel below current pixel
|
// add error for pixel below current pixel
|
||||||
cd ++;
|
cd++;
|
||||||
cd->error[0] += 5 * err[0];
|
cd->error[0] += 5 * err[0];
|
||||||
cd->error[1] += 5 * err[1];
|
cd->error[1] += 5 * err[1];
|
||||||
cd->error[2] += 5 * err[2];
|
cd->error[2] += 5 * err[2];
|
||||||
|
|
||||||
// add error for right pixel below current pixel
|
// add error for right pixel below current pixel
|
||||||
cd ++;
|
cd++;
|
||||||
cd->error[0] += 3 * err[0];
|
cd->error[0] += 3 * err[0];
|
||||||
cd->error[1] += 3 * err[1];
|
cd->error[1] += 3 * err[1];
|
||||||
cd->error[2] += 3 * err[2];
|
cd->error[2] += 3 * err[2];
|
||||||
@@ -879,12 +917,14 @@ Scaler::Dither(int32 fromRow, int32 toRow)
|
|||||||
delete[] columnData0;
|
delete[] columnData0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
Scaler::GetNumberOfUnits()
|
Scaler::GetNumberOfUnits()
|
||||||
{
|
{
|
||||||
return fRect.IntegerHeight() + 1;
|
return fRect.IntegerHeight() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Scaler::Run(int32 i, int32 n)
|
Scaler::Run(int32 i, int32 n)
|
||||||
{
|
{
|
||||||
@@ -892,43 +932,47 @@ Scaler::Run(int32 i, int32 n)
|
|||||||
imageHeight = GetDestImage()->Bounds().IntegerHeight() + 1;
|
imageHeight = GetDestImage()->Bounds().IntegerHeight() + 1;
|
||||||
height = imageHeight / n;
|
height = imageHeight / n;
|
||||||
from = i * height;
|
from = i * height;
|
||||||
if (i+1 == n) {
|
if (i + 1 == n)
|
||||||
to = imageHeight - 1;
|
to = imageHeight - 1;
|
||||||
} else {
|
else
|
||||||
to = from + height - 1;
|
to = from + height - 1;
|
||||||
}
|
|
||||||
if (GetDestImage()->Bounds().Width() >= GetSrcImage()->Bounds().Width()) {
|
if (GetDestImage()->Bounds().Width() >= GetSrcImage()->Bounds().Width())
|
||||||
ScaleBilinearFP(from, to);
|
ScaleBilinearFP(from, to);
|
||||||
} else {
|
else
|
||||||
DownScaleBilinear(from, to);
|
DownScaleBilinear(from, to);
|
||||||
}
|
|
||||||
if (fDither) {
|
if (fDither)
|
||||||
Dither(from, to);
|
Dither(from, to);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Scaler::Completed()
|
Scaler::Completed()
|
||||||
{
|
{
|
||||||
if (GetDestImage() != fScaledImage) {
|
if (GetDestImage() != fScaledImage)
|
||||||
delete fScaledImage;
|
delete fScaledImage;
|
||||||
}
|
|
||||||
fScaledImage = NULL;
|
fScaledImage = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implementation of ImageProcessor
|
|
||||||
ImageProcessor::ImageProcessor(enum operation op, BBitmap* image, BMessenger listener, uint32 what)
|
|
||||||
: Filter(image, listener, what)
|
|
||||||
, fOp(op)
|
|
||||||
, fBPP(0)
|
|
||||||
, fWidth(0)
|
|
||||||
, fHeight(0)
|
|
||||||
, fSrcBPR(0)
|
|
||||||
, fDestBPR(0)
|
|
||||||
|
|
||||||
|
// Implementation of ImageProcessor
|
||||||
|
ImageProcessor::ImageProcessor(enum operation op, BBitmap* image,
|
||||||
|
BMessenger listener, uint32 what)
|
||||||
|
:
|
||||||
|
Filter(image, listener, what),
|
||||||
|
fOp(op),
|
||||||
|
fBPP(0),
|
||||||
|
fWidth(0),
|
||||||
|
fHeight(0),
|
||||||
|
fSrcBPR(0),
|
||||||
|
fDestBPR(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BBitmap*
|
BBitmap*
|
||||||
ImageProcessor::CreateDestImage(BBitmap* /* srcImage */)
|
ImageProcessor::CreateDestImage(BBitmap* /* srcImage */)
|
||||||
{
|
{
|
||||||
@@ -936,20 +980,21 @@ ImageProcessor::CreateDestImage(BBitmap* /* srcImage */)
|
|||||||
BBitmap* bm;
|
BBitmap* bm;
|
||||||
BRect rect;
|
BRect rect;
|
||||||
|
|
||||||
if (GetSrcImage() == NULL) return NULL;
|
if (GetSrcImage() == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
cs = GetSrcImage()->ColorSpace();
|
cs = GetSrcImage()->ColorSpace();
|
||||||
fBPP = BytesPerPixel(cs);
|
fBPP = BytesPerPixel(cs);
|
||||||
if (fBPP < 1) return NULL;
|
if (fBPP < 1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
fWidth = GetSrcImage()->Bounds().IntegerWidth();
|
fWidth = GetSrcImage()->Bounds().IntegerWidth();
|
||||||
fHeight = GetSrcImage()->Bounds().IntegerHeight();
|
fHeight = GetSrcImage()->Bounds().IntegerHeight();
|
||||||
|
|
||||||
if (fOp == kRotateClockwise || fOp == kRotateCounterClockwise) {
|
if (fOp == kRotateClockwise || fOp == kRotateCounterClockwise)
|
||||||
rect.Set(0, 0, fHeight, fWidth);
|
rect.Set(0, 0, fHeight, fWidth);
|
||||||
} else {
|
else
|
||||||
rect.Set(0, 0, fWidth, fHeight);
|
rect.Set(0, 0, fWidth, fHeight);
|
||||||
}
|
|
||||||
|
|
||||||
bm = new BBitmap(rect, cs);
|
bm = new BBitmap(rect, cs);
|
||||||
if (!IsBitmapValid(bm)) {
|
if (!IsBitmapValid(bm)) {
|
||||||
@@ -963,45 +1008,50 @@ ImageProcessor::CreateDestImage(BBitmap* /* srcImage */)
|
|||||||
return bm;
|
return bm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
ImageProcessor::GetNumberOfUnits()
|
ImageProcessor::GetNumberOfUnits()
|
||||||
{
|
{
|
||||||
return GetSrcImage()->Bounds().IntegerHeight() + 1;
|
return GetSrcImage()->Bounds().IntegerHeight() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
ImageProcessor::BytesPerPixel(color_space cs) const
|
ImageProcessor::BytesPerPixel(color_space cs) const
|
||||||
{
|
{
|
||||||
switch (cs) {
|
switch (cs) {
|
||||||
case B_RGB32: // fall through
|
case B_RGB32: // fall through
|
||||||
case B_RGB32_BIG: // fall through
|
case B_RGB32_BIG: // fall through
|
||||||
case B_RGBA32: // fall through
|
case B_RGBA32: // fall through
|
||||||
case B_RGBA32_BIG: return 4;
|
case B_RGBA32_BIG: return 4;
|
||||||
|
|
||||||
case B_RGB24_BIG: // fall through
|
case B_RGB24_BIG: // fall through
|
||||||
case B_RGB24: return 3;
|
case B_RGB24: return 3;
|
||||||
|
|
||||||
case B_RGB16: // fall through
|
case B_RGB16: // fall through
|
||||||
case B_RGB16_BIG: // fall through
|
case B_RGB16_BIG: // fall through
|
||||||
case B_RGB15: // fall through
|
case B_RGB15: // fall through
|
||||||
case B_RGB15_BIG: // fall through
|
case B_RGB15_BIG: // fall through
|
||||||
case B_RGBA15: // fall through
|
case B_RGBA15: // fall through
|
||||||
case B_RGBA15_BIG: return 2;
|
case B_RGBA15_BIG: return 2;
|
||||||
|
|
||||||
case B_GRAY8: // fall through
|
case B_GRAY8: // fall through
|
||||||
case B_CMAP8: return 1;
|
case B_CMAP8: return 1;
|
||||||
case B_GRAY1: return 0;
|
case B_GRAY1: return 0;
|
||||||
default: return -1;
|
default: return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ImageProcessor::CopyPixel(uchar* dest, int32 destX, int32 destY, const uchar* src, int32 x, int32 y)
|
ImageProcessor::CopyPixel(uchar* dest, int32 destX, int32 destY,
|
||||||
|
const uchar* src, int32 x, int32 y)
|
||||||
{
|
{
|
||||||
// Note: On my systems (Dual Intel P3 866MHz and AMD Athlon 1GHz), replacing
|
// Note: On my systems (Dual Intel P3 866MHz and AMD Athlon 1GHz),
|
||||||
// the multiplications below with pointer arithmethics showed no speedup at all!
|
// replacing the multiplications below with pointer arithmethics showed
|
||||||
|
// no speedup at all!
|
||||||
dest += fDestBPR * destY + destX * fBPP;
|
dest += fDestBPR * destY + destX * fBPP;
|
||||||
src += fSrcBPR * y + x *fBPP;
|
src += fSrcBPR * y + x * fBPP;
|
||||||
// Replacing memcpy with this switch statement is slightly faster
|
// Replacing memcpy with this switch statement is slightly faster
|
||||||
switch (fBPP) {
|
switch (fBPP) {
|
||||||
case 4:
|
case 4:
|
||||||
@@ -1016,6 +1066,7 @@ ImageProcessor::CopyPixel(uchar* dest, int32 destX, int32 destY, const uchar* sr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Note: For B_CMAP8 InvertPixel inverts the color index not the color value!
|
// Note: For B_CMAP8 InvertPixel inverts the color index not the color value!
|
||||||
void
|
void
|
||||||
ImageProcessor::InvertPixel(int32 x, int32 y, uchar* dest, const uchar* src)
|
ImageProcessor::InvertPixel(int32 x, int32 y, uchar* dest, const uchar* src)
|
||||||
@@ -1035,18 +1086,19 @@ ImageProcessor::InvertPixel(int32 x, int32 y, uchar* dest, const uchar* src)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: On my systems, the operation kInvert shows a speedup on multiple CPUs only!
|
|
||||||
|
// Note: On my systems, the operation kInvert shows a speedup on
|
||||||
|
// multiple CPUs only!
|
||||||
void
|
void
|
||||||
ImageProcessor::Run(int32 i, int32 n)
|
ImageProcessor::Run(int32 i, int32 n)
|
||||||
{
|
{
|
||||||
int32 from, to;
|
int32 from, to;
|
||||||
int32 height = (fHeight+1) / n;
|
int32 height = (fHeight + 1) / n;
|
||||||
from = i * height;
|
from = i * height;
|
||||||
if (i+1 == n) {
|
if (i + 1 == n)
|
||||||
to = fHeight;
|
to = fHeight;
|
||||||
} else {
|
else
|
||||||
to = from + height - 1;
|
to = from + height - 1;
|
||||||
}
|
|
||||||
|
|
||||||
int32 x, y, destX, destY;
|
int32 x, y, destX, destY;
|
||||||
const uchar* src = (uchar*)GetSrcImage()->Bits();
|
const uchar* src = (uchar*)GetSrcImage()->Bits();
|
||||||
@@ -1054,8 +1106,8 @@ ImageProcessor::Run(int32 i, int32 n)
|
|||||||
|
|
||||||
switch (fOp) {
|
switch (fOp) {
|
||||||
case kRotateClockwise:
|
case kRotateClockwise:
|
||||||
for (y = from; y <= to; y ++) {
|
for (y = from; y <= to; y++) {
|
||||||
for (x = 0; x <= fWidth; x ++) {
|
for (x = 0; x <= fWidth; x++) {
|
||||||
destX = fHeight - y;
|
destX = fHeight - y;
|
||||||
destY = x;
|
destY = x;
|
||||||
CopyPixel(dest, destX, destY, src, x, y);
|
CopyPixel(dest, destX, destY, src, x, y);
|
||||||
@@ -1097,5 +1149,4 @@ ImageProcessor::Run(int32 i, int32 n)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-20
@@ -63,16 +63,17 @@ const int32 kFPOne = to_fixed_point(1);
|
|||||||
// Used by class Filter
|
// Used by class Filter
|
||||||
class FilterThread {
|
class FilterThread {
|
||||||
public:
|
public:
|
||||||
FilterThread(Filter* filter, int32 i, int32 n, bool runInCurrentThread = false);
|
FilterThread(Filter* filter, int32 i, int32 n,
|
||||||
|
bool runInCurrentThread = false);
|
||||||
~FilterThread();
|
~FilterThread();
|
||||||
|
|
||||||
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 {
|
||||||
@@ -142,26 +143,27 @@ private:
|
|||||||
// 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;
|
||||||
bool fDestImageInitialized;
|
bool fDestImageInitialized;
|
||||||
BBitmap* fDestImage;
|
BBitmap* fDestImage;
|
||||||
#if TIME_FILTER
|
#if TIME_FILTER
|
||||||
BStopWatch* fStopWatch;
|
BStopWatch* fStopWatch;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// Scales and optionally dithers an image
|
// Scales and optionally dithers an image
|
||||||
class Scaler : public Filter {
|
class Scaler : public Filter {
|
||||||
public:
|
public:
|
||||||
Scaler(BBitmap* image, BRect rect, BMessenger listener, uint32 what, bool dither);
|
Scaler(BBitmap* image, BRect rect, BMessenger listener, uint32 what,
|
||||||
|
bool dither);
|
||||||
~Scaler();
|
~Scaler();
|
||||||
|
|
||||||
BBitmap* CreateDestImage(BBitmap* srcImage);
|
BBitmap* CreateDestImage(BBitmap* srcImage);
|
||||||
@@ -173,7 +175,9 @@ public:
|
|||||||
private:
|
private:
|
||||||
void ScaleBilinear(int32 fromRow, int32 toRow);
|
void ScaleBilinear(int32 fromRow, int32 toRow);
|
||||||
void ScaleBilinearFP(int32 fromRow, int32 toRow);
|
void ScaleBilinearFP(int32 fromRow, int32 toRow);
|
||||||
inline void RowValues(float* sum, const uchar* srcData, intType srcW, intType fromX, intType toX, const float a0X, const float a1X, const int32 kBPP);
|
inline void RowValues(float* sum, const uchar* srcData, intType srcW,
|
||||||
|
intType fromX, intType toX, const float a0X,
|
||||||
|
const float a1X, const int32 kBPP);
|
||||||
void DownScaleBilinear(int32 fromRow, int32 toRow);
|
void DownScaleBilinear(int32 fromRow, int32 toRow);
|
||||||
static inline uchar Limit(intType value);
|
static inline uchar Limit(intType value);
|
||||||
void Dither(int32 fromRow, int32 toRow);
|
void Dither(int32 fromRow, int32 toRow);
|
||||||
@@ -195,14 +199,16 @@ public:
|
|||||||
kNumberOfAffineTransformations = 4
|
kNumberOfAffineTransformations = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
ImageProcessor(enum operation op, BBitmap* image, BMessenger listener, uint32 what);
|
ImageProcessor(enum operation op, BBitmap* image, BMessenger listener,
|
||||||
|
uint32 what);
|
||||||
BBitmap* CreateDestImage(BBitmap* srcImage);
|
BBitmap* CreateDestImage(BBitmap* srcImage);
|
||||||
int32 GetNumberOfUnits();
|
int32 GetNumberOfUnits();
|
||||||
void Run(int32 i, int32 n);
|
void Run(int32 i, int32 n);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int32 BytesPerPixel(color_space cs) const;
|
int32 BytesPerPixel(color_space cs) const;
|
||||||
inline void CopyPixel(uchar* dest, int32 destX, int32 destY, const uchar* src, int32 x, int32 y);
|
inline void CopyPixel(uchar* dest, int32 destX, int32 destY,
|
||||||
|
const uchar* src, int32 x, int32 y);
|
||||||
inline void InvertPixel(int32 x, int32 y, uchar* dest, const uchar* src);
|
inline void InvertPixel(int32 x, int32 y, uchar* dest, const uchar* src);
|
||||||
|
|
||||||
enum operation fOp;
|
enum operation fOp;
|
||||||
|
|||||||
@@ -374,14 +374,16 @@ AutoAdjustingNavigator::~AutoAdjustingNavigator()
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
AutoAdjustingNavigator::FindNextImage(const entry_ref& currentRef, entry_ref& nextRef,
|
AutoAdjustingNavigator::FindNextImage(const entry_ref& currentRef,
|
||||||
bool next, bool rewind)
|
entry_ref& nextRef, bool next, bool rewind)
|
||||||
{
|
{
|
||||||
if (_CheckForTracker(currentRef))
|
if (_CheckForTracker(currentRef))
|
||||||
return fTrackerNavigator->FindNextImage(currentRef, nextRef, next, rewind);
|
return fTrackerNavigator->FindNextImage(currentRef, nextRef, next,
|
||||||
|
rewind);
|
||||||
|
|
||||||
if (fFolderNavigator != NULL)
|
if (fFolderNavigator != NULL)
|
||||||
return fFolderNavigator->FindNextImage(currentRef, nextRef, next, rewind);
|
return fFolderNavigator->FindNextImage(currentRef, nextRef, next,
|
||||||
|
rewind);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,10 @@
|
|||||||
#include <Button.h>
|
#include <Button.h>
|
||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
#include <ControlLook.h>
|
#include <ControlLook.h>
|
||||||
#include <GroupLayoutBuilder.h>
|
|
||||||
#include <GridLayoutBuilder.h>
|
#include <GridLayoutBuilder.h>
|
||||||
#include <Locale.h>
|
#include <GroupLayoutBuilder.h>
|
||||||
#include <LayoutBuilder.h>
|
#include <LayoutBuilder.h>
|
||||||
|
#include <Locale.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
#include "ShowImageConstants.h"
|
#include "ShowImageConstants.h"
|
||||||
@@ -73,7 +73,7 @@ PrintOptions::SetWidth(float w)
|
|||||||
void
|
void
|
||||||
PrintOptions::SetHeight(float h)
|
PrintOptions::SetHeight(float h)
|
||||||
{
|
{
|
||||||
fWidth = (fBounds.Width()+1) * h / (fBounds.Height()+1);
|
fWidth = (fBounds.Width() + 1) * h / (fBounds.Height() + 1);
|
||||||
fHeight = h;
|
fHeight = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ ProgressWindow::ProgressWindow()
|
|||||||
{
|
{
|
||||||
BRect rect = Bounds();
|
BRect rect = Bounds();
|
||||||
|
|
||||||
BView *view = new BView(rect, NULL, B_FOLLOW_ALL, B_WILL_DRAW);
|
BView* view = new BView(rect, NULL, B_FOLLOW_ALL, B_WILL_DRAW);
|
||||||
view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
AddChild(view);
|
AddChild(view);
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ ProgressWindow::Stop()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ProgressWindow::MessageReceived(BMessage *message)
|
ProgressWindow::MessageReceived(BMessage* message)
|
||||||
{
|
{
|
||||||
switch (message->what) {
|
switch (message->what) {
|
||||||
case kMsgShow:
|
case kMsgShow:
|
||||||
@@ -123,7 +123,7 @@ ProgressWindow::MessageReceived(BMessage *message)
|
|||||||
if (message->FindFloat("percent", &percent) == B_OK)
|
if (message->FindFloat("percent", &percent) == B_OK)
|
||||||
fStatusBar->Update(percent - fStatusBar->CurrentValue());
|
fStatusBar->Update(percent - fStatusBar->CurrentValue());
|
||||||
|
|
||||||
const char *text;
|
const char* text;
|
||||||
if (message->FindString("message", &text) == B_OK)
|
if (message->FindString("message", &text) == B_OK)
|
||||||
fStatusBar->SetText(text);
|
fStatusBar->SetText(text);
|
||||||
|
|
||||||
|
|||||||
@@ -109,13 +109,13 @@ SelectionBox::Animate()
|
|||||||
{
|
{
|
||||||
// rotate up
|
// rotate up
|
||||||
uchar p = fPatternUp.data[0];
|
uchar p = fPatternUp.data[0];
|
||||||
for (int i = 0; i <= 6; i ++)
|
for (int i = 0; i <= 6; i++)
|
||||||
fPatternUp.data[i] = fPatternUp.data[i + 1];
|
fPatternUp.data[i] = fPatternUp.data[i + 1];
|
||||||
fPatternUp.data[7] = p;
|
fPatternUp.data[7] = p;
|
||||||
|
|
||||||
// rotate down
|
// rotate down
|
||||||
p = fPatternDown.data[7];
|
p = fPatternDown.data[7];
|
||||||
for (int i = 7; i >= 1; i --)
|
for (int i = 7; i >= 1; i--)
|
||||||
fPatternDown.data[i] = fPatternDown.data[i - 1];
|
fPatternDown.data[i] = fPatternDown.data[i - 1];
|
||||||
fPatternDown.data[0] = p;
|
fPatternDown.data[0] = p;
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ SelectionBox::_InitPatterns()
|
|||||||
uchar p;
|
uchar p;
|
||||||
uchar p1 = 0x33;
|
uchar p1 = 0x33;
|
||||||
uchar p2 = 0xCC;
|
uchar p2 = 0xCC;
|
||||||
for (int i = 0; i <= 7; i ++) {
|
for (int i = 0; i <= 7; i++) {
|
||||||
fPatternLeft.data[i] = p1;
|
fPatternLeft.data[i] = p1;
|
||||||
fPatternRight.data[i] = p2;
|
fPatternRight.data[i] = p2;
|
||||||
if ((i / 2) % 2 == 0)
|
if ((i / 2) % 2 == 0)
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ void
|
|||||||
ShowImageApp::_BroadcastToWindows(BMessage* message)
|
ShowImageApp::_BroadcastToWindows(BMessage* message)
|
||||||
{
|
{
|
||||||
const int32 count = CountWindows();
|
const int32 count = CountWindows();
|
||||||
for (int32 i = 0; i < count; i ++) {
|
for (int32 i = 0; i < count; i++) {
|
||||||
// BMessenger checks for us if BWindow is still a valid object
|
// BMessenger checks for us if BWindow is still a valid object
|
||||||
BMessenger messenger(WindowAt(i));
|
BMessenger messenger(WindowAt(i));
|
||||||
messenger.SendMessage(message);
|
messenger.SendMessage(message);
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ ShowImageUndo::SendUndoStateMessage(bool bCanUndo)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ShowImageUndo::SetTo(BRect rect, BBitmap *restore, BBitmap *selection)
|
ShowImageUndo::SetTo(BRect rect, BBitmap* restore, BBitmap* selection)
|
||||||
{
|
{
|
||||||
// NOTE: THIS FUNCTION DOES NOT MAKE COPIES OF THE BITMAPS PASSED TO IT
|
// NOTE: THIS FUNCTION DOES NOT MAKE COPIES OF THE BITMAPS PASSED TO IT
|
||||||
InternalClear();
|
InternalClear();
|
||||||
@@ -79,7 +79,7 @@ ShowImageUndo::SetTo(BRect rect, BBitmap *restore, BBitmap *selection)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ShowImageUndo::Undo(BRect rect, BBitmap *restore, BBitmap *selection)
|
ShowImageUndo::Undo(BRect rect, BBitmap* restore, BBitmap* selection)
|
||||||
{
|
{
|
||||||
// NOTE: THIS FUNCTION DOES NOT MAKE COPIES OF THE BITMAPS PASSED TO IT
|
// NOTE: THIS FUNCTION DOES NOT MAKE COPIES OF THE BITMAPS PASSED TO IT
|
||||||
fUndoType = UNDO_REDO;
|
fUndoType = UNDO_REDO;
|
||||||
|
|||||||
@@ -90,8 +90,8 @@ ShowImageView::fTransformation[ImageProcessor::kNumberOfAffineTransformations]
|
|||||||
{k0V, k90V, k0H, k270V, k0, k90, k180, k270}
|
{k0V, k90V, k0H, k270V, k0, k90, k180, k270}
|
||||||
};
|
};
|
||||||
|
|
||||||
const rgb_color kAlphaLow = (rgb_color){ 0xbb, 0xbb, 0xbb, 0xff };
|
const rgb_color kAlphaLow = (rgb_color) { 0xbb, 0xbb, 0xbb, 0xff };
|
||||||
const rgb_color kAlphaHigh = (rgb_color){ 0xe0, 0xe0, 0xe0, 0xff };
|
const rgb_color kAlphaHigh = (rgb_color) { 0xe0, 0xe0, 0xe0, 0xff };
|
||||||
|
|
||||||
const uint32 kMsgPopUpMenuClosed = 'pmcl';
|
const uint32 kMsgPopUpMenuClosed = 'pmcl';
|
||||||
|
|
||||||
@@ -129,17 +129,16 @@ compose_checker_background(const BBitmap* bitmap)
|
|||||||
p[3] = 255;
|
p[3] = 255;
|
||||||
alpha = 255 - alpha;
|
alpha = 255 - alpha;
|
||||||
if (x % 10 >= 5) {
|
if (x % 10 >= 5) {
|
||||||
if (i % 10 >= 5) {
|
if (i % 10 >= 5)
|
||||||
blend_colors(p, kAlphaLow.red, kAlphaLow.green, kAlphaLow.blue, alpha);
|
blend_colors(p, kAlphaLow.red, kAlphaLow.green, kAlphaLow.blue, alpha);
|
||||||
} else {
|
else
|
||||||
blend_colors(p, kAlphaHigh.red, kAlphaHigh.green, kAlphaHigh.blue, alpha);
|
blend_colors(p, kAlphaHigh.red, kAlphaHigh.green, kAlphaHigh.blue, alpha);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (i % 10 >= 5) {
|
if (i % 10 >= 5)
|
||||||
blend_colors(p, kAlphaHigh.red, kAlphaHigh.green, kAlphaHigh.blue, alpha);
|
blend_colors(p, kAlphaHigh.red, kAlphaHigh.green, kAlphaHigh.blue, alpha);
|
||||||
} else {
|
else
|
||||||
blend_colors(p, kAlphaLow.red, kAlphaLow.green, kAlphaLow.blue, alpha);
|
blend_colors(p, kAlphaLow.red, kAlphaLow.green, kAlphaLow.blue, alpha);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p += 4;
|
p += 4;
|
||||||
@@ -171,7 +170,7 @@ PopUpMenu::~PopUpMenu()
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
ShowImageView::ShowImageView(BRect rect, const char *name, uint32 resizingMode,
|
ShowImageView::ShowImageView(BRect rect, const char* name, uint32 resizingMode,
|
||||||
uint32 flags)
|
uint32 flags)
|
||||||
:
|
:
|
||||||
BView(rect, name, resizingMode, flags),
|
BView(rect, name, resizingMode, flags),
|
||||||
@@ -249,9 +248,8 @@ ShowImageView::Pulse()
|
|||||||
BPoint mousePos;
|
BPoint mousePos;
|
||||||
uint32 buttons;
|
uint32 buttons;
|
||||||
GetMouse(&mousePos, &buttons, false);
|
GetMouse(&mousePos, &buttons, false);
|
||||||
if (Bounds().Contains(mousePos)) {
|
if (Bounds().Contains(mousePos))
|
||||||
be_app->ObscureCursor();
|
be_app->ObscureCursor();
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
fHideCursorCountDown--;
|
fHideCursorCountDown--;
|
||||||
}
|
}
|
||||||
@@ -263,7 +261,7 @@ ShowImageView::Pulse()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ShowImageView::_SendMessageToWindow(BMessage *message)
|
ShowImageView::_SendMessageToWindow(BMessage* message)
|
||||||
{
|
{
|
||||||
BMessenger target(Window());
|
BMessenger target(Window());
|
||||||
target.SendMessage(message);
|
target.SendMessage(message);
|
||||||
@@ -605,18 +603,18 @@ ShowImageView::_DrawBackground(BRect border)
|
|||||||
{
|
{
|
||||||
BRect bounds(Bounds());
|
BRect bounds(Bounds());
|
||||||
// top
|
// top
|
||||||
FillRect(BRect(0, 0, bounds.right, border.top-1), B_SOLID_LOW);
|
FillRect(BRect(0, 0, bounds.right, border.top - 1), B_SOLID_LOW);
|
||||||
// left
|
// left
|
||||||
FillRect(BRect(0, border.top, border.left-1, border.bottom), B_SOLID_LOW);
|
FillRect(BRect(0, border.top, border.left - 1, border.bottom), B_SOLID_LOW);
|
||||||
// right
|
// right
|
||||||
FillRect(BRect(border.right+1, border.top, bounds.right, border.bottom), B_SOLID_LOW);
|
FillRect(BRect(border.right + 1, border.top, bounds.right, border.bottom), B_SOLID_LOW);
|
||||||
// bottom
|
// bottom
|
||||||
FillRect(BRect(0, border.bottom+1, bounds.right, bounds.bottom), B_SOLID_LOW);
|
FillRect(BRect(0, border.bottom + 1, bounds.right, bounds.bottom), B_SOLID_LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ShowImageView::_LayoutCaption(BFont &font, BPoint &pos, BRect &rect)
|
ShowImageView::_LayoutCaption(BFont& font, BPoint& pos, BRect& rect)
|
||||||
{
|
{
|
||||||
font_height fontHeight;
|
font_height fontHeight;
|
||||||
float width, height;
|
float width, height;
|
||||||
@@ -790,7 +788,7 @@ ShowImageView::_CopySelection(uchar alpha, bool imageSize)
|
|||||||
bool
|
bool
|
||||||
ShowImageView::_AddSupportedTypes(BMessage* msg, BBitmap* bitmap)
|
ShowImageView::_AddSupportedTypes(BMessage* msg, BBitmap* bitmap)
|
||||||
{
|
{
|
||||||
BTranslatorRoster *roster = BTranslatorRoster::Default();
|
BTranslatorRoster* roster = BTranslatorRoster::Default();
|
||||||
if (roster == NULL)
|
if (roster == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -812,9 +810,9 @@ ShowImageView::_AddSupportedTypes(BMessage* msg, BBitmap* bitmap)
|
|||||||
int32 count;
|
int32 count;
|
||||||
roster->GetOutputFormats(info[i].translator, &formats, &count);
|
roster->GetOutputFormats(info[i].translator, &formats, &count);
|
||||||
for (int32 j = 0; j < count; j++) {
|
for (int32 j = 0; j < count; j++) {
|
||||||
if (fMimeType == formats[j].MIME) {
|
if (fMimeType == formats[j].MIME)
|
||||||
foundCurrent = true;
|
foundCurrent = true;
|
||||||
} else if (strcmp(formats[j].MIME, "image/x-be-bitmap") != 0) {
|
else if (strcmp(formats[j].MIME, "image/x-be-bitmap") != 0) {
|
||||||
foundOther = true;
|
foundOther = true;
|
||||||
// needed to send data in message
|
// needed to send data in message
|
||||||
msg->AddString("be:types", formats[j].MIME);
|
msg->AddString("be:types", formats[j].MIME);
|
||||||
@@ -932,7 +930,7 @@ ShowImageView::SaveToFile(BDirectory* dir, const char* name, BBitmap* bitmap,
|
|||||||
|
|
||||||
bool loop = true;
|
bool loop = true;
|
||||||
while (loop) {
|
while (loop) {
|
||||||
BTranslatorRoster *roster = BTranslatorRoster::Default();
|
BTranslatorRoster* roster = BTranslatorRoster::Default();
|
||||||
if (!roster)
|
if (!roster)
|
||||||
break;
|
break;
|
||||||
// write data
|
// write data
|
||||||
@@ -954,7 +952,7 @@ ShowImageView::SaveToFile(BDirectory* dir, const char* name, BBitmap* bitmap,
|
|||||||
char buffer[512];
|
char buffer[512];
|
||||||
snprintf(buffer, sizeof(buffer), B_TRANSLATE("The file '%s' could not "
|
snprintf(buffer, sizeof(buffer), B_TRANSLATE("The file '%s' could not "
|
||||||
"be written."), name);
|
"be written."), name);
|
||||||
BAlert *palert = new BAlert("", buffer, B_TRANSLATE("OK"));
|
BAlert* palert = new BAlert("", buffer, B_TRANSLATE("OK"));
|
||||||
palert->Go();
|
palert->Go();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -965,14 +963,16 @@ ShowImageView::SaveToFile(BDirectory* dir, const char* name, BBitmap* bitmap,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ShowImageView::_SendInMessage(BMessage* msg, BBitmap* bitmap, translation_format* format)
|
ShowImageView::_SendInMessage(BMessage* msg, BBitmap* bitmap,
|
||||||
|
translation_format* format)
|
||||||
{
|
{
|
||||||
BMessage reply(B_MIME_DATA);
|
BMessage reply(B_MIME_DATA);
|
||||||
BBitmapStream stream(bitmap); // destructor deletes bitmap
|
BBitmapStream stream(bitmap); // destructor deletes bitmap
|
||||||
BTranslatorRoster *roster = BTranslatorRoster::Default();
|
BTranslatorRoster* roster = BTranslatorRoster::Default();
|
||||||
BMallocIO memStream;
|
BMallocIO memStream;
|
||||||
if (roster->Translate(&stream, NULL, NULL, &memStream, format->type) == B_OK) {
|
if (roster->Translate(&stream, NULL, NULL, &memStream, format->type) == B_OK) {
|
||||||
reply.AddData(format->MIME, B_MIME_TYPE, memStream.Buffer(), memStream.BufferLength());
|
reply.AddData(format->MIME, B_MIME_TYPE, memStream.Buffer(),
|
||||||
|
memStream.BufferLength());
|
||||||
msg->SendReply(&reply);
|
msg->SendReply(&reply);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1335,7 +1335,7 @@ ShowImageView::KeyDown(const char* bytes, int32 numBytes)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ShowImageView::_MouseWheelChanged(BMessage *msg)
|
ShowImageView::_MouseWheelChanged(BMessage* msg)
|
||||||
{
|
{
|
||||||
// The BeOS driver does not currently support
|
// The BeOS driver does not currently support
|
||||||
// X wheel scrolling, therefore, dx is zero.
|
// X wheel scrolling, therefore, dx is zero.
|
||||||
@@ -1379,14 +1379,14 @@ void
|
|||||||
ShowImageView::_ShowPopUpMenu(BPoint screen)
|
ShowImageView::_ShowPopUpMenu(BPoint screen)
|
||||||
{
|
{
|
||||||
if (!fShowingPopUpMenu) {
|
if (!fShowingPopUpMenu) {
|
||||||
PopUpMenu* menu = new PopUpMenu("PopUpMenu", this);
|
PopUpMenu* menu = new PopUpMenu("PopUpMenu", this);
|
||||||
|
|
||||||
ShowImageWindow* window = dynamic_cast<ShowImageWindow*>(Window());
|
ShowImageWindow* window = dynamic_cast<ShowImageWindow*>(Window());
|
||||||
if (window != NULL)
|
if (window != NULL)
|
||||||
window->BuildContextMenu(menu);
|
window->BuildContextMenu(menu);
|
||||||
|
|
||||||
menu->Go(screen, true, true, true);
|
menu->Go(screen, true, true, true);
|
||||||
fShowingPopUpMenu = true;
|
fShowingPopUpMenu = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1430,18 +1430,18 @@ ShowImageView::FixupScrollBar(orientation o, float bitmapLength,
|
|||||||
float viewLength)
|
float viewLength)
|
||||||
{
|
{
|
||||||
float prop, range;
|
float prop, range;
|
||||||
BScrollBar *psb;
|
BScrollBar* psb;
|
||||||
|
|
||||||
psb = ScrollBar(o);
|
psb = ScrollBar(o);
|
||||||
if (psb) {
|
if (psb) {
|
||||||
range = bitmapLength - viewLength;
|
range = bitmapLength - viewLength;
|
||||||
if (range < 0.0) {
|
if (range < 0.0)
|
||||||
range = 0.0;
|
range = 0.0;
|
||||||
}
|
|
||||||
prop = viewLength / bitmapLength;
|
prop = viewLength / bitmapLength;
|
||||||
if (prop > 1.0) {
|
if (prop > 1.0)
|
||||||
prop = 1.0;
|
prop = 1.0;
|
||||||
}
|
|
||||||
psb->SetRange(0, range);
|
psb->SetRange(0, range);
|
||||||
psb->SetProportion(prop);
|
psb->SetProportion(prop);
|
||||||
psb->SetSteps(10, 100);
|
psb->SetSteps(10, 100);
|
||||||
@@ -1481,22 +1481,23 @@ ShowImageView::Undo()
|
|||||||
|
|
||||||
// backup current selection
|
// backup current selection
|
||||||
BRect undoneSelRect;
|
BRect undoneSelRect;
|
||||||
BBitmap *undoneSelection;
|
BBitmap* undoneSelection;
|
||||||
undoneSelRect = fSelectionBox.Bounds();
|
undoneSelRect = fSelectionBox.Bounds();
|
||||||
undoneSelection = _CopySelection();
|
undoneSelection = _CopySelection();
|
||||||
|
|
||||||
if (undoType == UNDO_UNDO) {
|
if (undoType == UNDO_UNDO) {
|
||||||
BBitmap *undoRestore;
|
BBitmap* undoRestore;
|
||||||
undoRestore = fUndo.GetRestoreBitmap();
|
undoRestore = fUndo.GetRestoreBitmap();
|
||||||
if (undoRestore)
|
if (undoRestore)
|
||||||
_MergeWithBitmap(undoRestore, fUndo.GetRect());
|
_MergeWithBitmap(undoRestore, fUndo.GetRect());
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore previous image/selection
|
// restore previous image/selection
|
||||||
BBitmap *undoSelection;
|
BBitmap* undoSelection;
|
||||||
undoSelection = fUndo.GetSelectionBitmap();
|
undoSelection = fUndo.GetSelectionBitmap();
|
||||||
// NOTE: ShowImageView is responsible for deleting this bitmap
|
// NOTE: ShowImageView is responsible for deleting this bitmap
|
||||||
// (Which it will, as it would with a fSelectionBitmap that it allocated itself)
|
// (Which it will, as it would with a fSelectionBitmap that it
|
||||||
|
// allocated itself)
|
||||||
if (!undoSelection)
|
if (!undoSelection)
|
||||||
_SetHasSelection(false);
|
_SetHasSelection(false);
|
||||||
else {
|
else {
|
||||||
@@ -1683,10 +1684,14 @@ ShowImageView::_DoImageOperation(ImageProcessor::operation op, bool quiet)
|
|||||||
// update orientation state
|
// update orientation state
|
||||||
if (op != ImageProcessor::kInvert) {
|
if (op != ImageProcessor::kInvert) {
|
||||||
// Note: If one of these fails, check its definition in class ImageProcessor.
|
// Note: If one of these fails, check its definition in class ImageProcessor.
|
||||||
// ASSERT(ImageProcessor::kRotateClockwise < ImageProcessor::kNumberOfAffineTransformations);
|
// ASSERT(ImageProcessor::kRotateClockwise <
|
||||||
// ASSERT(ImageProcessor::kRotateCounterClockwise < ImageProcessor::kNumberOfAffineTransformations);
|
// ImageProcessor::kNumberOfAffineTransformations);
|
||||||
// ASSERT(ImageProcessor::kFlipLeftToRight < ImageProcessor::kNumberOfAffineTransformations);
|
// ASSERT(ImageProcessor::kRotateCounterClockwise <
|
||||||
// ASSERT(ImageProcessor::kFlipTopToBottom < ImageProcessor::kNumberOfAffineTransformations);
|
// ImageProcessor::kNumberOfAffineTransformations);
|
||||||
|
// ASSERT(ImageProcessor::kFlipLeftToRight <
|
||||||
|
// ImageProcessor::kNumberOfAffineTransformations);
|
||||||
|
// ASSERT(ImageProcessor::kFlipTopToBottom <
|
||||||
|
// ImageProcessor::kNumberOfAffineTransformations);
|
||||||
fImageOrientation = fTransformation[op][fImageOrientation];
|
fImageOrientation = fTransformation[op][fImageOrientation];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1697,9 +1702,8 @@ ShowImageView::_DoImageOperation(ImageProcessor::operation op, bool quiet)
|
|||||||
if (orientation != k0) {
|
if (orientation != k0) {
|
||||||
node.WriteAttr(SHOW_IMAGE_ORIENTATION_ATTRIBUTE, B_INT32_TYPE, 0,
|
node.WriteAttr(SHOW_IMAGE_ORIENTATION_ATTRIBUTE, B_INT32_TYPE, 0,
|
||||||
&orientation, sizeof(orientation));
|
&orientation, sizeof(orientation));
|
||||||
} else {
|
} else
|
||||||
node.RemoveAttr(SHOW_IMAGE_ORIENTATION_ATTRIBUTE);
|
node.RemoveAttr(SHOW_IMAGE_ORIENTATION_ATTRIBUTE);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set new bitmap
|
// set new bitmap
|
||||||
@@ -1749,7 +1753,7 @@ ShowImageView::ResizeImage(int w, int h)
|
|||||||
if (fBitmap == NULL || w < 1 || h < 1)
|
if (fBitmap == NULL || w < 1 || h < 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Scaler scaler(fBitmap, BRect(0, 0, w-1, h-1), BMessenger(), 0, false);
|
Scaler scaler(fBitmap, BRect(0, 0, w - 1, h - 1), BMessenger(), 0, false);
|
||||||
scaler.Start(false);
|
scaler.Start(false);
|
||||||
BBitmap* scaled = scaler.DetachBitmap();
|
BBitmap* scaled = scaler.DetachBitmap();
|
||||||
if (scaled == NULL) {
|
if (scaled == NULL) {
|
||||||
@@ -1784,17 +1788,17 @@ ShowImageView::_SetIcon(bool clear, icon_size which)
|
|||||||
|
|
||||||
BRect rect(fBitmap->Bounds());
|
BRect rect(fBitmap->Bounds());
|
||||||
float s;
|
float s;
|
||||||
s = size / (rect.Width()+1.0);
|
s = size / (rect.Width() + 1.0);
|
||||||
|
|
||||||
if (s * (rect.Height()+1.0) <= size) {
|
if (s * (rect.Height() + 1.0) <= size) {
|
||||||
rect.right = size-1;
|
rect.right = size - 1;
|
||||||
rect.bottom = static_cast<int>(s * (rect.Height()+1.0))-1;
|
rect.bottom = static_cast<int>(s * (rect.Height() + 1.0)) - 1;
|
||||||
// center vertically
|
// center vertically
|
||||||
rect.OffsetBy(0, (size - rect.IntegerHeight()) / 2);
|
rect.OffsetBy(0, (size - rect.IntegerHeight()) / 2);
|
||||||
} else {
|
} else {
|
||||||
s = size / (rect.Height()+1.0);
|
s = size / (rect.Height() + 1.0);
|
||||||
rect.right = static_cast<int>(s * (rect.Width()+1.0))-1;
|
rect.right = static_cast<int>(s * (rect.Width() + 1.0)) - 1;
|
||||||
rect.bottom = size-1;
|
rect.bottom = size - 1;
|
||||||
// center horizontally
|
// center horizontally
|
||||||
rect.OffsetBy((size - rect.IntegerWidth()) / 2, 0);
|
rect.OffsetBy((size - rect.IntegerWidth()) / 2, 0);
|
||||||
}
|
}
|
||||||
@@ -1806,7 +1810,7 @@ ShowImageView::_SetIcon(bool clear, icon_size which)
|
|||||||
scaler.Start(false);
|
scaler.Start(false);
|
||||||
ASSERT(thumbnail->ColorSpace() == B_CMAP8);
|
ASSERT(thumbnail->ColorSpace() == B_CMAP8);
|
||||||
// create icon from thumbnail
|
// create icon from thumbnail
|
||||||
BBitmap icon(BRect(0, 0, size-1, size-1), B_CMAP8);
|
BBitmap icon(BRect(0, 0, size - 1, size - 1), B_CMAP8);
|
||||||
memset(icon.Bits(), B_TRANSPARENT_MAGIC_CMAP8, icon.BitsLength());
|
memset(icon.Bits(), B_TRANSPARENT_MAGIC_CMAP8, icon.BitsLength());
|
||||||
BScreen screen;
|
BScreen screen;
|
||||||
const uchar* src = (uchar*)thumbnail->Bits();
|
const uchar* src = (uchar*)thumbnail->Bits();
|
||||||
@@ -1816,10 +1820,10 @@ ShowImageView::_SetIcon(bool clear, icon_size which)
|
|||||||
const int32 dx = (int32)rect.left;
|
const int32 dx = (int32)rect.left;
|
||||||
const int32 dy = (int32)rect.top;
|
const int32 dy = (int32)rect.top;
|
||||||
|
|
||||||
for (int32 y = 0; y <= rect.IntegerHeight(); y ++) {
|
for (int32 y = 0; y <= rect.IntegerHeight(); y++) {
|
||||||
for (int32 x = 0; x <= rect.IntegerWidth(); x ++) {
|
for (int32 x = 0; x <= rect.IntegerWidth(); x++) {
|
||||||
const uchar* s = src + y * srcBPR + x;
|
const uchar* s = src + y * srcBPR + x;
|
||||||
uchar* d = dest + (y+dy) * destBPR + (x+dx);
|
uchar* d = dest + (y + dy) * destBPR + (x + dx);
|
||||||
*d = *s;
|
*d = *s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,20 +104,20 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
enum image_orientation {
|
enum image_orientation {
|
||||||
k0, // 0
|
k0, // 0
|
||||||
k90, // 1
|
k90, // 1
|
||||||
k180, // 2
|
k180, // 2
|
||||||
k270, // 3
|
k270, // 3
|
||||||
k0V, // 4
|
k0V, // 4
|
||||||
k90V, // 5
|
k90V, // 5
|
||||||
k0H, // 6
|
k0H, // 6
|
||||||
k270V, // 7
|
k270V, // 7
|
||||||
kNumberOfOrientations,
|
kNumberOfOrientations,
|
||||||
};
|
};
|
||||||
|
|
||||||
void _SetHasSelection(bool bHasSelection);
|
void _SetHasSelection(bool bHasSelection);
|
||||||
void _AnimateSelection(bool a);
|
void _AnimateSelection(bool a);
|
||||||
void _SendMessageToWindow(BMessage *message);
|
void _SendMessageToWindow(BMessage* message);
|
||||||
void _SendMessageToWindow(uint32 code);
|
void _SendMessageToWindow(uint32 code);
|
||||||
void _Notify();
|
void _Notify();
|
||||||
void _UpdateStatusText();
|
void _UpdateStatusText();
|
||||||
|
|||||||
@@ -990,7 +990,8 @@ ShowImageWindow::MessageReceived(BMessage* message)
|
|||||||
backgroundsMessage.AddRef("refs", fImageView->Image());
|
backgroundsMessage.AddRef("refs", fImageView->Image());
|
||||||
// This is used in the Backgrounds code for scaled placement
|
// This is used in the Backgrounds code for scaled placement
|
||||||
backgroundsMessage.AddInt32("placement", 'scpl');
|
backgroundsMessage.AddInt32("placement", 'scpl');
|
||||||
be_roster->Launch("application/x-vnd.haiku-backgrounds", &backgroundsMessage);
|
be_roster->Launch("application/x-vnd.haiku-backgrounds",
|
||||||
|
&backgroundsMessage);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1050,9 +1051,9 @@ ShowImageWindow::MessageReceived(BMessage* message)
|
|||||||
if (message->FindFloat("offset", &offset) == B_OK
|
if (message->FindFloat("offset", &offset) == B_OK
|
||||||
&& message->FindBool("show", &show) == B_OK) {
|
&& message->FindBool("show", &show) == B_OK) {
|
||||||
// Compensate rounding errors with the final placement
|
// Compensate rounding errors with the final placement
|
||||||
if (show) {
|
if (show)
|
||||||
fToolBarView->MoveTo(fToolBarView->Frame().left, 0);
|
fToolBarView->MoveTo(fToolBarView->Frame().left, 0);
|
||||||
} else {
|
else {
|
||||||
fToolBarView->MoveTo(fToolBarView->Frame().left, offset);
|
fToolBarView->MoveTo(fToolBarView->Frame().left, offset);
|
||||||
fToolBarView->Hide();
|
fToolBarView->Hide();
|
||||||
}
|
}
|
||||||
@@ -1174,7 +1175,8 @@ ShowImageWindow::_SaveToFile(BMessage* message)
|
|||||||
|
|
||||||
int32 i;
|
int32 i;
|
||||||
for (i = 0; i < outCount; i++) {
|
for (i = 0; i < outCount; i++) {
|
||||||
if (outFormat[i].group == B_TRANSLATOR_BITMAP && outFormat[i].type == outType)
|
if (outFormat[i].group == B_TRANSLATOR_BITMAP && outFormat[i].type
|
||||||
|
== outType)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == outCount)
|
if (i == outCount)
|
||||||
@@ -1271,8 +1273,8 @@ ShowImageWindow::_ToggleFullScreen()
|
|||||||
BScreen screen;
|
BScreen screen;
|
||||||
fWindowFrame = Frame();
|
fWindowFrame = Frame();
|
||||||
frame = screen.Frame();
|
frame = screen.Frame();
|
||||||
frame.top -= fBar->Bounds().Height()+1;
|
frame.top -= fBar->Bounds().Height() + 1;
|
||||||
frame.right += B_V_SCROLL_BAR_WIDTH-1;
|
frame.right += B_V_SCROLL_BAR_WIDTH - 1;
|
||||||
frame.bottom += B_H_SCROLL_BAR_HEIGHT;
|
frame.bottom += B_H_SCROLL_BAR_HEIGHT;
|
||||||
frame.InsetBy(-1, -1); // PEN_SIZE in ShowImageView
|
frame.InsetBy(-1, -1); // PEN_SIZE in ShowImageView
|
||||||
|
|
||||||
@@ -1414,7 +1416,7 @@ ShowImageWindow::_Print(BMessage* msg)
|
|||||||
float width;
|
float width;
|
||||||
switch (fPrintOptions.Option()) {
|
switch (fPrintOptions.Option()) {
|
||||||
case PrintOptions::kFitToPage: {
|
case PrintOptions::kFitToPage: {
|
||||||
float w1 = printableRect.Width()+1;
|
float w1 = printableRect.Width() + 1;
|
||||||
float w2 = imageWidth * (printableRect.Height() + 1)
|
float w2 = imageWidth * (printableRect.Height() + 1)
|
||||||
/ imageHeight;
|
/ imageHeight;
|
||||||
if (w2 < w1)
|
if (w2 < w1)
|
||||||
|
|||||||
@@ -51,8 +51,8 @@ ToolBarView::AddAction(uint32 command, BHandler* target, const BBitmap* icon,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ToolBarView::AddAction(BMessage* message, BHandler* target, const BBitmap* icon,
|
ToolBarView::AddAction(BMessage* message, BHandler* target,
|
||||||
const char* toolTipText)
|
const BBitmap* icon, const char* toolTipText)
|
||||||
{
|
{
|
||||||
BIconButton* button = new BIconButton(NULL, NULL, message, target);
|
BIconButton* button = new BIconButton(NULL, NULL, message, target);
|
||||||
button->SetIcon(icon);
|
button->SetIcon(icon);
|
||||||
|
|||||||
Reference in New Issue
Block a user