Author: post
Date: 2013-03-25 16:39:12 +0100 (Mon, 25 Mar 2013)
New Revision: 528
Modified:
RawSpeed/RawDecoder.cpp
RawSpeed/RawDecoder.h
RawSpeed/RawImage.cpp
RawSpeed/RawImage.h
RawSpeed/RawImageDataFloat.cpp
RawSpeed/RawImageDataU16.cpp
RawSpeed/Rw2Decoder.cpp
RawSpeed/Rw2Decoder.h
Log:
Move bad pixel interpolation in to a generic setting, and make it possible to
have bad pixels that doesn't depend on the value of the pixel.
Make a 4-way interpolation where bad pixels bordering the current bad pixel is
skipped, and the distance to the found pixel is used.
Bad pixel interpolation can be disabled by setting
RawDecoder.interpolateBadPixels = false;
Modified: RawSpeed/RawDecoder.cpp
===================================================================
--- RawSpeed/RawDecoder.cpp 2013-03-20 19:37:34 UTC (rev 527)
+++ RawSpeed/RawDecoder.cpp 2013-03-25 15:39:12 UTC (rev 528)
@@ -27,6 +27,7 @@
RawDecoder::RawDecoder(FileMap* file) : mRaw(RawImage::create()),
mFile(file) {
decoderVersion = 0;
failOnUnknown = FALSE;
+ interpolateBadPixels = TRUE;
}
RawDecoder::~RawDecoder(void) {
@@ -261,7 +262,7 @@
void *RawDecoderDecodeThread(void *_this) {
RawDecoderThread* me = (RawDecoderThread*)_this;
try {
- me->parent->decodeThreaded(me);
+ me->parent->decodeThreaded(me);
} catch (RawDecoderException &ex) {
me->parent->mRaw->setError(ex.what());
} catch (IOException &ex) {
@@ -310,7 +311,10 @@
RawSpeed::RawImage RawDecoder::decodeRaw()
{
try {
- return decodeRawInternal();
+ RawImage raw = decodeRawInternal();
+ if (interpolateBadPixels)
+ raw->fixBadPixels();
+ return raw;
} catch (TiffParserException &e) {
ThrowRDE("%s", e.what());
} catch (FileIOException &e) {
Modified: RawSpeed/RawDecoder.h
===================================================================
--- RawSpeed/RawDecoder.h 2013-03-20 19:37:34 UTC (rev 527)
+++ RawSpeed/RawDecoder.h 2013-03-25 15:39:12 UTC (rev 528)
@@ -93,6 +93,10 @@
/* DNGs are always attempted to be decoded, so this variable has no effect
on DNGs */
bool failOnUnknown;
+ /* Set how to handle bad pixels. */
+ /* If you disable this parameter, no bad pixel interpolation will be done */
+ bool interpolateBadPixels;
+
protected:
/* Attempt to decode the image */
/* A RawDecoderException will be thrown if the image cannot be decoded, */
Modified: RawSpeed/RawImage.cpp
===================================================================
--- RawSpeed/RawImage.cpp 2013-03-20 19:37:34 UTC (rev 527)
+++ RawSpeed/RawImage.cpp 2013-03-25 15:39:12 UTC (rev 528)
@@ -37,7 +37,9 @@
pthread_mutex_init(&mymutex, NULL);
subsampling.x = subsampling.y = 1;
isoSpeed = 0;
+ mBadPixelMap = NULL;
pthread_mutex_init(&errMutex, NULL);
+ pthread_mutex_init(&mBadPixelMutex, NULL);
}
RawImageData::RawImageData(iPoint2D _dim, uint32 _bpc, uint32 _cpp) :
@@ -48,23 +50,24 @@
blackLevelSeparate[0] = blackLevelSeparate[1] = blackLevelSeparate[2] =
blackLevelSeparate[3] = -1;
subsampling.x = subsampling.y = 1;
isoSpeed = 0;
+ mBadPixelMap = NULL;
createData();
pthread_mutex_init(&mymutex, NULL);
pthread_mutex_init(&errMutex, NULL);
+ pthread_mutex_init(&mBadPixelMutex, NULL);
}
RawImageData::~RawImageData(void) {
_ASSERTE(dataRefCount == 0);
- if (data)
- _aligned_free(data);
- data = 0;
mOffset = iPoint2D(0, 0);
pthread_mutex_destroy(&mymutex);
pthread_mutex_destroy(&errMutex);
+ pthread_mutex_destroy(&mBadPixelMutex);
for (uint32 i = 0 ; i < errors.size(); i++) {
free((void*)errors[i]);
}
errors.clear();
+ destroyData();
}
@@ -85,7 +88,10 @@
void RawImageData::destroyData() {
if (data)
_aligned_free(data);
+ if (mBadPixelMap)
+ _aligned_free(mBadPixelMap);
data = 0;
+ mBadPixelMap = 0;
}
void RawImageData::setCpp(uint32 val) {
@@ -164,6 +170,17 @@
pthread_mutex_unlock(&errMutex);
}
+void RawImageData::createBadPixelMap()
+{
+ if (!isAllocated())
+ ThrowRDE("RawImageData::createBadPixelMap: (internal) Bad pixel map cannot
be allocated before image.");
+ mBadPixelMapPitch = (((uncropped_dim.x / 8) + 15) / 16) * 16;
+ mBadPixelMap = (uchar8*)_aligned_malloc(mBadPixelMapPitch * uncropped_dim.y,
16);
+ memset(mBadPixelMap, 0, mBadPixelMapPitch * uncropped_dim.y);
+ if (!mBadPixelMap)
+ ThrowRDE("RawImageData::createData: Memory Allocation failed.");
+}
+
RawImage::RawImage(RawImageData* p) : p_(p) {
pthread_mutex_lock(&p_->mymutex);
++p_->dataRefCount;
@@ -186,6 +203,123 @@
pthread_mutex_unlock(&p_->mymutex);
}
+
+void RawImageData::transferBadPixelsToMap()
+{
+ if (mBadPixelPositions.empty())
+ return;
+
+ if (!mBadPixelMap)
+ createBadPixelMap();
+
+ for (vector<uint32>::iterator i=mBadPixelPositions.begin(); i !=
mBadPixelPositions.end(); i++) {
+ uint32 pos = *i;
+ uint32 pos_x = pos&0xffff;
+ uint32 pos_y = pos>>16;
+ mBadPixelMap[mBadPixelMapPitch * pos_y + (pos_x >> 3)] |= 1 << (pos_x&7);
+ }
+ mBadPixelPositions.clear();
+}
+
+void RawImageData::fixBadPixels()
+{
+#if !defined (EMULATE_DCRAW_BAD_PIXELS)
+
+ /* Transfer if not already done */
+ transferBadPixelsToMap();
+
+#if 0 // For testing purposes
+ if (!mBadPixelMap)
+ createBadPixelMap();
+ for (int y = 400; y < 700; y++){
+ for (int x = 1200; x < 1700; x++) {
+ mBadPixelMap[mBadPixelMapPitch * y + (x >> 3)] |= 1 << (x&7);
+ }
+ }
+#endif
+
+ /* Process bad pixels, if any */
+ if (mBadPixelMap)
+ startWorker(RawImageWorker::FIX_BAD_PIXELS, false);
+
+ return;
+
+#else // EMULATE_DCRAW_BAD_PIXELS - not recommended, testing purposes only
+
+ for (vector<uint32>::iterator i=mBadPixelPositions.begin(); i !=
mBadPixelPositions.end(); i++) {
+ uint32 pos = *i;
+ uint32 pos_x = pos&0xffff;
+ uint32 pos_y = pos>>16;
+ uint32 total = 0;
+ uint32 div = 0;
+ // 0 side covered by unsignedness.
+ for (uint32 r=pos_x-2; r<=pos_x+2 && r<(uint32)uncropped_dim.x; r+=2) {
+ for (uint32 c=pos_y-2; c<=pos_y+2 && c<(uint32)uncropped_dim.y; c+=2) {
+ ushort16* pix = (ushort16*)getDataUncropped(r,c);
+ if (*pix) {
+ total += *pix;
+ div++;
+ }
+ }
+ }
+ ushort16* pix = (ushort16*)getDataUncropped(pos_x,pos_y);
+ if (div) {
+ pix[0] = total / div;
+ }
+ }
+#endif
+
+}
+
+void RawImageData::startWorker(RawImageWorker::RawImageWorkerTask task, bool
cropped )
+{
+ int height = cropped ? dim.y : uncropped_dim.y;
+
+ int threads = getThreadCount();
+ if (threads <= 1) {
+ RawImageWorker worker(this, task, 0, height);
+ worker.performTask();
+ return;
+ }
+
+ RawImageWorker **workers = new RawImageWorker*[threads];
+ int y_offset = 0;
+ int y_per_thread = (height + threads - 1) / threads;
+
+ for (int i = 0; i < threads; i++) {
+ int y_end = MIN(y_offset + y_per_thread, height);
+ workers[i] = new RawImageWorker(this, task, y_offset, y_end);
+ workers[i]->startThread();
+ y_offset = y_end;
+ }
+ for (int i = 0; i < threads; i++) {
+ workers[i]->waitForThread();
+ delete workers[i];
+ }
+ delete[] workers;
+}
+
+void RawImageData::fixBadPixelsThread( int start_y, int end_y )
+{
+ int gw = (uncropped_dim.x + 15) / 32;
+ for (int y = start_y; y < end_y; y++) {
+ uint32* bad_map = (uint32*)&mBadPixelMap[y*mBadPixelMapPitch];
+ for (int x = 0 ; x < gw; x++) {
+ // Test if there is a bad pixel within these 32 pixels
+ if (bad_map[x] != 0) {
+ uchar8 *bad = (uchar8*)&bad_map[x];
+ // Go through each pixel
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 8; j++) {
+ if (1 == ((bad[i]>>j) & 1))
+ fixBadPixel(x*32+i*8+j, y, 0);
+ }
+ }
+ }
+ }
+ }
+}
+
RawImageData* RawImage::operator->() {
return p_;
}
@@ -204,7 +338,7 @@
void *RawImageWorkerThread(void *_this) {
RawImageWorker* me = (RawImageWorker*)_this;
- me->_performTask();
+ me->performTask();
pthread_exit(NULL);
return 0;
}
@@ -215,7 +349,6 @@
start_y = _start_y;
end_y = _end_y;
task = _task;
- startThread();
}
void RawImageWorker::startThread()
@@ -233,14 +366,17 @@
pthread_join(threadid, &status);
}
-void RawImageWorker::_performTask()
+void RawImageWorker::performTask()
{
try {
switch(task)
{
- case TASK_SCALE_VALUES:
+ case SCALE_VALUES:
data->scaleValues(start_y, end_y);
break;
+ case FIX_BAD_PIXELS:
+ data->fixBadPixelsThread(start_y, end_y);
+ break;
default:
_ASSERTE(false);
}
@@ -254,4 +390,5 @@
}
+
} // namespace RawSpeed
Modified: RawSpeed/RawImage.h
===================================================================
--- RawSpeed/RawImage.h 2013-03-20 19:37:34 UTC (rev 527)
+++ RawSpeed/RawImage.h 2013-03-25 15:39:12 UTC (rev 528)
@@ -29,9 +29,24 @@
namespace RawSpeed {
class RawImage;
-class RawImageWorker;
+class RawImageData;
typedef enum {TYPE_USHORT16, TYPE_FLOAT32} RawImageType;
+class RawImageWorker {
+public:
+ typedef enum {SCALE_VALUES, FIX_BAD_PIXELS} RawImageWorkerTask;
+ RawImageWorker(RawImageData *img, RawImageWorkerTask task, int start_y, int
end_y);
+ void startThread();
+ void waitForThread();
+ void performTask();
+protected:
+ pthread_t threadid;
+ RawImageData* data;
+ RawImageWorkerTask task;
+ int start_y;
+ int end_y;
+};
+
class RawImageData
{
friend class RawImageWorker;
@@ -51,7 +66,11 @@
iPoint2D getCropOffset();
virtual void scaleBlackWhite() = 0;
virtual void calculateBlackAreas() = 0;
+ virtual void transferBadPixelsToMap();
+ virtual void fixBadPixels();
+
bool isAllocated() {return !!data;}
+ void createBadPixelMap();
iPoint2D dim;
uint32 pitch;
bool isCFA;
@@ -68,12 +87,21 @@
vector<const char*> errors;
pthread_mutex_t errMutex; // Mutex for above
void setError(const char* err);
+ /* Vector containing the positions of bad pixels */
+ /* Format is x | (y << 16), so maximum pixel position is 65535 */
+ vector<uint32> mBadPixelPositions; // Positions of zeroes that must be
interpolated
+ pthread_mutex_t mBadPixelMutex; // Mutex for above, must be used if more
than 1 thread is accessing vector
+ uchar8 *mBadPixelMap;
+ uint32 mBadPixelMapPitch;
protected:
RawImageType dataType;
RawImageData(void);
RawImageData(iPoint2D dim, uint32 bpp, uint32 cpp=1);
virtual void scaleValues(int start_y, int end_y) = 0;
+ virtual void fixBadPixel( uint32 x, uint32 y, int component = 0) = 0;
+ void fixBadPixelsThread(int start_y, int end_y);
+ void startWorker(RawImageWorker::RawImageWorkerTask task, bool cropped );
uint32 dataRefCount;
uchar8* data;
uint32 cpp; // Components per pixel
@@ -92,6 +120,8 @@
protected:
virtual void scaleValues(int start_y, int end_y);
+ virtual void fixBadPixel( uint32 x, uint32 y, int component = 0);
+
RawImageDataU16(void);
RawImageDataU16(iPoint2D dim, uint32 cpp=1);
friend class RawImage;
@@ -105,26 +135,12 @@
protected:
virtual void scaleValues(int start_y, int end_y);
+ virtual void fixBadPixel( uint32 x, uint32 y, int component = 0);
RawImageDataFloat(void);
RawImageDataFloat(iPoint2D dim, uint32 cpp=1);
friend class RawImage;
};
-class RawImageWorker {
-public:
- typedef enum {TASK_SCALE_VALUES} RawImageWorkerTask;
- RawImageWorker(RawImageData *img, RawImageWorkerTask task, int start_y, int
end_y);
- void waitForThread();
- void _performTask();
-protected:
- void startThread();
- pthread_t threadid;
- RawImageData* data;
- RawImageWorkerTask task;
- int start_y;
- int end_y;
-};
-
class RawImage {
public:
static RawImage create(RawImageType type = TYPE_USHORT16);
Modified: RawSpeed/RawImageDataFloat.cpp
===================================================================
--- RawSpeed/RawImageDataFloat.cpp 2013-03-20 19:37:34 UTC (rev 527)
+++ RawSpeed/RawImageDataFloat.cpp 2013-03-25 15:39:12 UTC (rev 528)
@@ -127,27 +127,9 @@
if (blackLevelSeparate[0] < 0)
calculateBlackAreas();
- int threads = getThreadCount();
- if (threads <= 1)
- scaleValues(0, dim.y);
- else {
- RawImageWorker **workers = new RawImageWorker*[threads];
- int y_offset = 0;
- int y_per_thread = (dim.y + threads - 1) / threads;
+ startWorker(RawImageWorker::SCALE_VALUES, true);
+}
- for (int i = 0; i < threads; i++) {
- int y_end = MIN(y_offset + y_per_thread, dim.y);
- workers[i] = new RawImageWorker(this,
RawImageWorker::TASK_SCALE_VALUES, y_offset, y_end);
- y_offset = y_end;
- }
- for (int i = 0; i < threads; i++) {
- workers[i]->waitForThread();
- delete workers[i];
- }
- delete[] workers;
- }
- }
-
#if 0 // _MSC_VER > 1399 || defined(__SSE2__)
void RawImageDataFloat::scaleValues(int start_y, int end_y) {
@@ -288,4 +270,96 @@
#endif
+ /* This performs a 4 way interpolated pixel */
+ /* The value is interpolated from the 4 closest valid pixels in */
+ /* the horizontal and vertical direction. Pixels found further away */
+ /* are weighed less */
+
+void RawImageDataFloat::fixBadPixel( uint32 x, uint32 y, int component )
+{
+ float values[4];
+ float dist[4];
+ float weight[4];
+
+ values[0] = values[1] = values[2] = values[3] = -1;
+ dist[0] = dist[1] = dist[2] = dist[3] = 0;
+ uchar8* bad_line = &mBadPixelMap[y*mBadPixelMapPitch];
+
+ // Find pixel to the left
+ int x_find = (int)x - 2;
+ int curr = 0;
+ while (x_find >= 0 && values[curr] < 0) {
+ if (0 == ((bad_line[x_find>>3] >> (x_find&7)) & 1)) {
+ values[curr] = ((float*)getData(x_find, y))[component];
+ dist[curr] = float((int)x-x_find);
+ }
+ x_find-=2;
+ }
+ // Find pixel to the right
+ x_find = (int)x + 2;
+ curr = 1;
+ while (x_find < uncropped_dim.x && values[curr] < 0) {
+ if (0 == ((bad_line[x_find>>3] >> (x_find&7)) & 1)) {
+ values[curr] = ((float*)getData(x_find, y))[component];
+ dist[curr] = float(x_find-(int)x);
+ }
+ x_find+=2;
+ }
+
+ bad_line = &mBadPixelMap[x>>3];
+ // Find pixel upwards
+ int y_find = (int)y - 2;
+ curr = 2;
+ while (y_find >= 0 && values[curr] < 0) {
+ if (0 == ((bad_line[y_find*mBadPixelMapPitch] >> (x&7)) & 1)) {
+ values[curr] = ((float*)getData(x, y_find))[component];
+ dist[curr] = float((int)y-y_find);
+ }
+ y_find-=2;
+ }
+ // Find pixel downwards
+ y_find = (int)y + 2;
+ curr = 3;
+ while (y_find < uncropped_dim.y && values[curr] < 0) {
+ if (0 == ((bad_line[y_find*mBadPixelMapPitch] >> (x&7)) & 1)) {
+ values[curr] = ((float*)getData(x, y_find))[component];
+ dist[curr] = float(y_find-(int)y);
+ }
+ y_find+=2;
+ }
+ // Find x weights
+ float total_dist_x = dist[0] + dist[1];
+
+ float total_div = 0.000001f;
+ if (total_dist_x) {
+ weight[0] = dist[0] > 0.0f ? (total_dist_x - dist[0]) / total_dist_x : 0;
+ weight[1] = 1.0f - weight[0];
+ total_div += 1;
+ }
+
+ // Find y weights
+ float total_dist_y = dist[2] + dist[3];
+ if (total_dist_y) {
+ weight[2] = dist[2] > 0.0f ? (total_dist_x - dist[2]) / total_dist_y : 0;
+ weight[3] = 1.0f - weight[2];
+ total_div += 1;
+ }
+
+
+ float total_pixel = 0;
+ for (int i = 0; i < 4; i++)
+ if (values[i] >= 0)
+ total_pixel += values[i] * dist[i];
+
+ total_pixel /= total_div;
+ float* pix = (float*)getDataUncropped(x, y);
+ pix[component] = total_pixel;
+
+ /* Process other pixels - could be done inline, since we have the weights */
+ if (cpp > 1 && component == 0)
+ for (int i = 1; i < (int)cpp; i++)
+ fixBadPixel(x,y,i);
+
+}
+
} // namespace RawSpeed
Modified: RawSpeed/RawImageDataU16.cpp
===================================================================
--- RawSpeed/RawImageDataU16.cpp 2013-03-20 19:37:34 UTC (rev 527)
+++ RawSpeed/RawImageDataU16.cpp 2013-03-25 15:39:12 UTC (rev 528)
@@ -133,7 +133,7 @@
blackLevel = b;
if (whitePoint >= 65536)
whitePoint = m;
- printf("ISO:%d, Estimated black:%d, Estimated white: %d\n", isoSpeed,
blackLevel, whitePoint);
+ printf("Rawspeed, ISO:%d, Estimated black:%d, Estimated white: %d\n",
isoSpeed, blackLevel, whitePoint);
}
/* Skip, if not needed */
@@ -146,26 +146,7 @@
// printf("ISO:%d, black[0]:%d, white: %d\n", isoSpeed,
blackLevelSeparate[0], whitePoint);
// printf("black[1]:%d, black[2]:%d, black[3]:%d\n", blackLevelSeparate[1],
blackLevelSeparate[2], blackLevelSeparate[3]);
-
- int threads = getThreadCount();
- if (threads <= 1)
- scaleValues(0, dim.y);
- else {
- RawImageWorker **workers = new RawImageWorker*[threads];
- int y_offset = 0;
- int y_per_thread = (dim.y + threads - 1) / threads;
-
- for (int i = 0; i < threads; i++) {
- int y_end = MIN(y_offset + y_per_thread, dim.y);
- workers[i] = new RawImageWorker(this, RawImageWorker::TASK_SCALE_VALUES,
y_offset, y_end);
- y_offset = y_end;
- }
- for (int i = 0; i < threads; i++) {
- workers[i]->waitForThread();
- delete workers[i];
- }
- delete[] workers;
- }
+ startWorker(RawImageWorker::SCALE_VALUES, true);
}
#if _MSC_VER > 1399 || defined(__SSE2__)
@@ -351,4 +332,96 @@
#endif
+/* This performs a 4 way interpolated pixel */
+/* The value is interpolated from the 4 closest valid pixels in */
+/* the horizontal and vertical direction. Pixels found further away */
+/* are weighed less */
+
+void RawImageDataU16::fixBadPixel( uint32 x, uint32 y, int component )
+{
+ int values[4];
+ int dist[4];
+ int weight[4];
+
+ values[0] = values[1] = values[2] = values[3] = -1;
+ dist[0] = dist[1] = dist[2] = dist[3] = 0;
+ uchar8* bad_line = &mBadPixelMap[y*mBadPixelMapPitch];
+ int step = isCFA ? 2 : 1;
+
+ // Find pixel to the left
+ int x_find = (int)x - step;
+ int curr = 0;
+ while (x_find >= 0 && values[curr] < 0) {
+ if (0 == ((bad_line[x_find>>3] >> (x_find&7)) & 1)) {
+ values[curr] = ((ushort16*)getData(x_find, y))[component];
+ dist[curr] = (int)x-x_find;
+ }
+ x_find -= step;
+ }
+ // Find pixel to the right
+ x_find = (int)x + step;
+ curr = 1;
+ while (x_find < uncropped_dim.x && values[curr] < 0) {
+ if (0 == ((bad_line[x_find>>3] >> (x_find&7)) & 1)) {
+ values[curr] = ((ushort16*)getData(x_find, y))[component];
+ dist[curr] = x_find-(int)x;
+ }
+ x_find += step;
+ }
+
+ bad_line = &mBadPixelMap[x>>3];
+ // Find pixel upwards
+ int y_find = (int)y - step;
+ curr = 2;
+ while (y_find >= 0 && values[curr] < 0) {
+ if (0 == ((bad_line[y_find*mBadPixelMapPitch] >> (x&7)) & 1)) {
+ values[curr] = ((ushort16*)getData(x, y_find))[component];
+ dist[curr] = (int)y-y_find;
+ }
+ y_find -= step;
+ }
+ // Find pixel downwards
+ y_find = (int)y + step;
+ curr = 3;
+ while (y_find < uncropped_dim.y && values[curr] < 0) {
+ if (0 == ((bad_line[y_find*mBadPixelMapPitch] >> (x&7)) & 1)) {
+ values[curr] = ((ushort16*)getData(x, y_find))[component];
+ dist[curr] = y_find-(int)y;
+ }
+ y_find += step;
+ }
+
+ // Find x weights
+ int total_dist_x = dist[0] + dist[1];
+
+ int total_shifts = 7;
+ if (total_dist_x) {
+ weight[0] = dist[0] ? (total_dist_x - dist[0]) * 256 / total_dist_x : 0;
+ weight[1] = 256 - weight[0];
+ total_shifts++;
+ }
+
+ // Find y weights
+ int total_dist_y = dist[2] + dist[3];
+ if (total_dist_y) {
+ weight[2] = dist[2] ? (total_dist_x - dist[2]) * 256 / total_dist_y : 0;
+ weight[3] = 256-weight[2];
+ total_shifts++;
+ }
+
+ int total_pixel = 0;
+ for (int i = 0; i < 4; i++)
+ if (values[i] >= 0)
+ total_pixel += values[i] * weight[i];
+
+ total_pixel >>= total_shifts;
+ ushort16* pix = (ushort16*)getDataUncropped(x, y);
+ pix[component] = clampbits(total_pixel, 16);
+
+ /* Process other pixels - could be done inline, since we have the weights */
+ if (cpp > 1 && component == 0)
+ for (int i = 1; i < (int)cpp; i++)
+ fixBadPixel(x,y,i);
+}
+
} // namespace RawSpeed
Modified: RawSpeed/Rw2Decoder.cpp
===================================================================
--- RawSpeed/Rw2Decoder.cpp 2013-03-20 19:37:34 UTC (rev 527)
+++ RawSpeed/Rw2Decoder.cpp 2013-03-25 15:39:12 UTC (rev 528)
@@ -102,38 +102,7 @@
}
void Rw2Decoder::DecodeRw2() {
- pthread_mutex_init(&zeroMutex, NULL);
startThreads();
- pthread_mutex_destroy(&zeroMutex);
- // Interpolate over zeroes.
- int pitch = (int)mRaw->pitch;
-
- for (vector<uint32>::iterator i=zero_pos.begin(); i != zero_pos.end(); i++) {
- uint32 pos = *i;
- uint32 pos_x = pos&0xffff;
- uint32 pos_y = pos>>16;
- ushort16* pix = (ushort16*)mRaw->getData(pos_x, pos_y);
- uint32 total = 0;
- uint32 div = 0;
- if (pos_x > 1 && 0 != pix[-2]) {
- total += pix[-2];
- div++;
- }
- if (pos_x < (uint32)mRaw->dim.x-2 && 0 != pix[2]) {
- total += pix[2];
- div++;
- }
- if (pos_y > 1 && 0 != pix[-pitch]) {
- total += pix[-pitch]; // Note: 2 lines above, since pitch is in bytes
and pix in shorts this cancels out.
- div++;
- }
- if (pos_y < (uint32)mRaw->dim.y-2 && 0 != pix[mRaw->pitch]) {
- total += pix[mRaw->pitch]; // Note: 2 lines below, since pitch is in
bytes and pix in shorts this cancels out.
- div++;
- }
- if (div)
- pix[0] = total / div;
- }
}
void Rw2Decoder::decodeThreaded(RawDecoderThread * t) {
@@ -204,10 +173,9 @@
}
}
if (zero_is_bad && !zero_pos.empty()) {
- Rw2Decoder* rw2_dec = (Rw2Decoder*)t->parent;
- pthread_mutex_lock(&zeroMutex);
- rw2_dec->zero_pos.insert(rw2_dec->zero_pos.end(), zero_pos.begin(),
zero_pos.end());
- pthread_mutex_unlock(&zeroMutex);
+ pthread_mutex_lock(&mRaw->mBadPixelMutex);
+ mRaw->mBadPixelPositions.insert(mRaw->mBadPixelPositions.end(),
zero_pos.begin(), zero_pos.end());
+ pthread_mutex_unlock(&mRaw->mBadPixelMutex);
}
}
Modified: RawSpeed/Rw2Decoder.h
===================================================================
--- RawSpeed/Rw2Decoder.h 2013-03-20 19:37:34 UTC (rev 527)
+++ RawSpeed/Rw2Decoder.h 2013-03-25 15:39:12 UTC (rev 528)
@@ -58,8 +58,6 @@
std::string guessMode();
ByteStream* input_start;
uint32 load_flags;
- vector<uint32> zero_pos; // Positions of zeroes that must be interpolated
- pthread_mutex_t zeroMutex; // Mutex for above
};
} // namespace RawSpeed
_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit