Author: post
Date: 2011-03-19 20:23:21 +0100 (Sat, 19 Mar 2011)
New Revision: 347
Added:
RawSpeed/RawImageDataFloat.cpp
RawSpeed/RawImageDataU16.cpp
Modified:
RawSpeed/ArwDecoder.cpp
RawSpeed/Cr2Decoder.cpp
RawSpeed/DngDecoder.cpp
RawSpeed/LJpegPlain.cpp
RawSpeed/NefDecoder.cpp
RawSpeed/OrfDecoder.cpp
RawSpeed/PefDecoder.cpp
RawSpeed/RawDecoder.cpp
RawSpeed/RawImage.cpp
RawSpeed/RawImage.h
RawSpeed/RawSpeed.vcproj
RawSpeed/Rw2Decoder.cpp
Log:
Split RawImageData into separate classes, to prepare to have different data
type. Right now only Unsigned 16 bit is used. (Note: Makefiles must include the
new files)
Modified: RawSpeed/ArwDecoder.cpp
===================================================================
--- RawSpeed/ArwDecoder.cpp 2011-03-19 17:20:28 UTC (rev 346)
+++ RawSpeed/ArwDecoder.cpp 2011-03-19 19:23:21 UTC (rev 347)
@@ -70,7 +70,6 @@
height += 8;
mRaw->dim = iPoint2D(width, height);
- mRaw->bpp = 2;
mRaw->createData();
const ushort16* c = raw->getEntry(SONY_CURVE)->getShortArray();
Modified: RawSpeed/Cr2Decoder.cpp
===================================================================
--- RawSpeed/Cr2Decoder.cpp 2011-03-19 17:20:28 UTC (rev 346)
+++ RawSpeed/Cr2Decoder.cpp 2011-03-19 19:23:21 UTC (rev 347)
@@ -77,7 +77,6 @@
ThrowRDE("CR2 Decoder: No Slices found.");
}
- mRaw->bpp = 2;
mRaw->dim = iPoint2D(slices[0].w, completeH);
if (raw->hasEntry((TiffTag)0xc6c5)) {
Modified: RawSpeed/DngDecoder.cpp
===================================================================
--- RawSpeed/DngDecoder.cpp 2011-03-19 17:20:28 UTC (rev 346)
+++ RawSpeed/DngDecoder.cpp 2011-03-19 19:23:21 UTC (rev 347)
@@ -83,7 +83,6 @@
try {
mRaw->dim.x = raw->getEntry(IMAGEWIDTH)->getInt();
mRaw->dim.y = raw->getEntry(IMAGELENGTH)->getInt();
- mRaw->bpp = 2;
} catch (TiffParserException) {
ThrowRDE("DNG Decoder: Could not read basic image information.");
}
Modified: RawSpeed/LJpegPlain.cpp
===================================================================
--- RawSpeed/LJpegPlain.cpp 2011-03-19 17:20:28 UTC (rev 346)
+++ RawSpeed/LJpegPlain.cpp 2011-03-19 19:23:21 UTC (rev 347)
@@ -163,7 +163,7 @@
slice_width[i] = slicesW[i] / pixGroup / maxSuperH; // This is a guess,
but works for sRaw1+2.
for (slice = 0; slice < slices; slice++) {
- offset[slice] = ((t_x + offX) * mRaw->bpp + ((offY + t_y) * mRaw->pitch))
| (t_s << 28);
+ offset[slice] = ((t_x + offX) * mRaw->getBpp() + ((offY + t_y) *
mRaw->pitch)) | (t_s << 28);
_ASSERTE((offset[slice]&0x0fffffff) < mRaw->pitch*mRaw->dim.y);
t_y += maxSuperV;
if (t_y >= (frame.h - skipY)) {
@@ -300,7 +300,7 @@
slice_width[i] = slicesW[i] / COMPS;
for (slice = 0; slice < slices; slice++) {
- offset[slice] = ((t_x + offX) * mRaw->bpp + ((offY + t_y) * mRaw->pitch))
| (t_s << 28);
+ offset[slice] = ((t_x + offX) * mRaw->getBpp() + ((offY + t_y) *
mRaw->pitch)) | (t_s << 28);
_ASSERTE((offset[slice]&0x0fffffff) < mRaw->pitch*mRaw->dim.y);
t_y += 2;
if (t_y >= (frame.h - skipY)) {
@@ -426,7 +426,7 @@
slice_width[i] = slicesW[i] / 2;
for (slice = 0; slice < slices; slice++) {
- offset[slice] = ((t_x + offX) * mRaw->bpp + ((offY + t_y) * mRaw->pitch))
| (t_s << 28);
+ offset[slice] = ((t_x + offX) * mRaw->getBpp() + ((offY + t_y) *
mRaw->pitch)) | (t_s << 28);
_ASSERTE((offset[slice]&0x0fffffff) < mRaw->pitch*mRaw->dim.y);
t_y ++;
if (t_y >= (frame.h - skipY)) {
@@ -527,7 +527,7 @@
uint32 slice = 0;
uint32 cw = (frame.w - skipX);
for (slice = 0; slice < slices; slice++) {
- offset[slice] = ((t_x + offX) * mRaw->bpp + ((offY + t_y) * mRaw->pitch))
| (t_s << 28);
+ offset[slice] = ((t_x + offX) * mRaw->getBpp() + ((offY + t_y) *
mRaw->pitch)) | (t_s << 28);
_ASSERTE((offset[slice]&0x0fffffff) < mRaw->pitch*mRaw->dim.y);
t_y++;
if (t_y == (frame.h - skipY)) {
@@ -615,7 +615,7 @@
uint32 t_s = 0;
uint32 slice = 0;
for (slice = 0; slice < slices; slice++) {
- offset[slice] = ((t_x + offX) * mRaw->bpp + ((offY + t_y) * mRaw->pitch))
| (t_s << 28);
+ offset[slice] = ((t_x + offX) * mRaw->getBpp() + ((offY + t_y) *
mRaw->pitch)) | (t_s << 28);
_ASSERTE((offset[slice]&0x0fffffff) < mRaw->pitch*mRaw->dim.y);
t_y++;
if (t_y == (frame.h - skipY)) {
@@ -711,7 +711,7 @@
uint32 t_s = 0;
uint32 slice = 0;
for (slice = 0; slice < slices; slice++) {
- offset[slice] = ((t_x + offX) * mRaw->bpp + ((offY + t_y) * mRaw->pitch))
| (t_s << 28);
+ offset[slice] = ((t_x + offX) * mRaw->getBpp() + ((offY + t_y) *
mRaw->pitch)) | (t_s << 28);
_ASSERTE((offset[slice]&0x0fffffff) < mRaw->pitch*mRaw->dim.y);
t_y++;
if (t_y == (frame.h - skipY)) {
Modified: RawSpeed/NefDecoder.cpp
===================================================================
--- RawSpeed/NefDecoder.cpp 2011-03-19 17:20:28 UTC (rev 346)
+++ RawSpeed/NefDecoder.cpp 2011-03-19 19:23:21 UTC (rev 347)
@@ -83,7 +83,6 @@
uint32 bitPerPixel = raw->getEntry(BITSPERSAMPLE)->getInt();
mRaw->dim = iPoint2D(width, height);
- mRaw->bpp = 2;
mRaw->createData();
data = mRootIFD->getIFDsWithTag(MAKERNOTE);
@@ -177,7 +176,6 @@
ThrowRDE("NEF Decoder: No valid slices found. File probably truncated.");
mRaw->dim = iPoint2D(width, offY);
- mRaw->bpp = 2;
mRaw->createData();
if (bitPerPixel == 14 && width*slices[0].h*2 == slices[0].count)
bitPerPixel = 16; // D3
Modified: RawSpeed/OrfDecoder.cpp
===================================================================
--- RawSpeed/OrfDecoder.cpp 2011-03-19 17:20:28 UTC (rev 346)
+++ RawSpeed/OrfDecoder.cpp 2011-03-19 19:23:21 UTC (rev 347)
@@ -63,7 +63,6 @@
ThrowRDE("ORF Decoder: Truncated file");
mRaw->dim = iPoint2D(width, height);
- mRaw->bpp = 2;
mRaw->createData();
data = mRootIFD->getIFDsWithTag(MAKERNOTE);
Modified: RawSpeed/PefDecoder.cpp
===================================================================
--- RawSpeed/PefDecoder.cpp 2011-03-19 17:20:28 UTC (rev 346)
+++ RawSpeed/PefDecoder.cpp 2011-03-19 19:23:21 UTC (rev 347)
@@ -66,7 +66,6 @@
uint32 height = raw->getEntry(IMAGELENGTH)->getInt();
mRaw->dim = iPoint2D(width, height);
- mRaw->bpp = 2;
mRaw->createData();
try {
PentaxDecompressor l(mFile, mRaw);
Modified: RawSpeed/RawDecoder.cpp
===================================================================
--- RawSpeed/RawDecoder.cpp 2011-03-19 17:20:28 UTC (rev 346)
+++ RawSpeed/RawDecoder.cpp 2011-03-19 19:23:21 UTC (rev 347)
@@ -66,7 +66,6 @@
ThrowRDE("RAW Decoder: No valid slices found. File probably truncated.");
mRaw->dim = iPoint2D(width, offY);
- mRaw->bpp = 2;
mRaw->createData();
mRaw->whitePoint = (1<<bitPerPixel)-1;
@@ -136,7 +135,7 @@
if (bitPerPixel == 16 && getHostEndianness() == little) {
BitBlt(&data[offset.x*sizeof(ushort16)*cpp+y*outPitch], outPitch,
- input.getData(), inputPitch, w*mRaw->bpp, h - y);
+ input.getData(), inputPitch, w*mRaw->getBpp(), h - y);
return;
}
if (bitPerPixel == 12 && (int)w == inputPitch * 8 / 12 &&
getHostEndianness() == little) {
Modified: RawSpeed/RawImage.cpp
===================================================================
--- RawSpeed/RawImage.cpp 2011-03-19 17:20:28 UTC (rev 346)
+++ RawSpeed/RawImage.cpp 2011-03-19 19:23:21 UTC (rev 347)
@@ -148,254 +148,7 @@
dim = new_size;
}
-void RawImageData::calculateBlackAreas() {
- int* histogram = (int*)malloc(4*65536*sizeof(int));
- memset(histogram, 0, 4*65536*sizeof(int));
- int totalpixels = 0;
- for (uint32 i = 0; i < blackAreas.size(); i++) {
- BlackArea area = blackAreas[i];
-
- /* Make sure area sizes are multiple of two,
- so we have the same amount of pixels for each CFA group */
- area.size = area.size - (area.size&1);
-
- /* Process horizontal area */
- if (!area.isVertical) {
- if ((int)area.offset+(int)area.size > uncropped_dim.y)
- ThrowRDE("RawImageData::calculateBlackAreas: Offset + size is larger
than height of image");
- for (uint32 y = area.offset; y < area.offset+area.size; y++) {
- ushort16 *pixel = (ushort16*)getDataUncropped(mOffset.x, y);
- int* localhist = &histogram[(y&1)*(65536*2)];
- for (int x = mOffset.x; x < dim.x+mOffset.x; x++) {
- localhist[((x&1)<<16) + *pixel]++;
- }
- }
- totalpixels += area.size * dim.x;
- }
-
- /* Process vertical area */
- if (area.isVertical) {
- if ((int)area.offset+(int)area.size > uncropped_dim.x)
- ThrowRDE("RawImageData::calculateBlackAreas: Offset + size is larger
than width of image");
- for (int y = mOffset.y; y < dim.y+mOffset.y; y++) {
- ushort16 *pixel = (ushort16*)getDataUncropped(area.offset, y);
- int* localhist = &histogram[(y&1)*(65536*2)];
- for (uint32 x = area.offset; x < area.size+area.offset; x++) {
- localhist[((x&1)<<16) + *pixel]++;
- }
- }
- totalpixels += area.size * dim.y;
- }
- }
-
- if (!totalpixels) {
- for (int i = 0 ; i < 4; i++)
- blackLevelSeparate[i] = blackLevel;
- return;
- }
-
- /* Calculate median value of black areas for each component */
- /* Adjust the number of total pixels so it is the same as the median of each
histogram */
- totalpixels /= 4*2;
-
- for (int i = 0 ; i < 4; i++) {
- int* localhist = &histogram[i*65536];
- int acc_pixels = localhist[0];
- int pixel_value = 0;
- while (acc_pixels <= totalpixels && pixel_value < 65535) {
- pixel_value++;
- acc_pixels += localhist[pixel_value];
- }
- blackLevelSeparate[i] = pixel_value;
- }
- free(histogram);
-}
-
-void RawImageData::scaleBlackWhite() {
- const int skipBorder = 150;
- int gw = (dim.x - skipBorder) * cpp;
- if ((blackAreas.empty() && blackLevelSeparate[0] < 0 && blackLevel < 0) ||
whitePoint == 65536) { // Estimate
- int b = 65536;
- int m = 0;
- for (int row = skipBorder*cpp;row < (dim.y - skipBorder);row++) {
- ushort16 *pixel = (ushort16*)getData(skipBorder, row);
- for (int col = skipBorder ; col < gw ; col++) {
- b = MIN(*pixel, b);
- m = MAX(*pixel, m);
- pixel++;
- }
- }
- if (blackLevel < 0)
- blackLevel = b;
- if (whitePoint == 65536)
- whitePoint = m;
- printf("Estimated black:%d, Estimated white: %d\n", blackLevel,
whitePoint);
- }
-
- /* If filter has not set separate blacklevel, compute or fetch it */
- 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;
-
- 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 _MSC_VER > 1399 || defined(__SSE2__)
-
-void RawImageData::scaleValues(int start_y, int end_y) {
- bool use_sse2;
-#ifdef _MSC_VER
- int info[4];
- __cpuid(info, 1);
- use_sse2 = !!(info[3]&(1 << 26));
-#else
- use_sse2 = TRUE;
-#endif
-
- float app_scale = 65535.0f / (whitePoint - blackLevelSeparate[0]);
- // Check SSE2
- if (use_sse2 && app_scale < 63) {
-
- __m128i sseround;
- __m128i ssesub2;
- __m128i ssesign;
- uint32* sub_mul = (uint32*)_aligned_malloc(16*4*2, 16);
- uint32 gw = pitch / 16;
- // 10 bit fraction
- uint32 mul = (int)(1024.0f * 65535.0f / (float)(whitePoint -
blackLevelSeparate[mOffset.x&1]));
- mul |= ((int)(1024.0f * 65535.0f / (float)(whitePoint -
blackLevelSeparate[(mOffset.x+1)&1])))<<16;
- uint32 b = blackLevelSeparate[mOffset.x&1] |
(blackLevelSeparate[(mOffset.x+1)&1]<<16);
-
- for (int i = 0; i< 4; i++) {
- sub_mul[i] = b; // Subtract even lines
- sub_mul[4+i] = mul; // Multiply even lines
- }
-
- mul = (int)(1024.0f * 65535.0f / (float)(whitePoint -
blackLevelSeparate[2+(mOffset.x&1)]));
- mul |= ((int)(1024.0f * 65535.0f / (float)(whitePoint -
blackLevelSeparate[2+((mOffset.x+1)&1)])))<<16;
- b = blackLevelSeparate[2+(mOffset.x&1)] |
(blackLevelSeparate[2+((mOffset.x+1)&1)]<<16);
-
- for (int i = 0; i< 4; i++) {
- sub_mul[8+i] = b; // Subtract odd lines
- sub_mul[12+i] = mul; // Multiply odd lines
- }
-
- sseround = _mm_set_epi32(512, 512, 512, 512);
- ssesub2 = _mm_set_epi32(32768, 32768, 32768, 32768);
- ssesign = _mm_set_epi32(0x80008000, 0x80008000, 0x80008000, 0x80008000);
-
- for (int y = start_y; y < end_y; y++) {
- __m128i* pixel = (__m128i*) & data[(mOffset.y+y)*pitch];
- __m128i ssescale, ssesub;
- if (((y+mOffset.y)&1) == 0) {
- ssesub = _mm_load_si128((__m128i*)&sub_mul[0]);
- ssescale = _mm_load_si128((__m128i*)&sub_mul[4]);
- } else {
- ssesub = _mm_load_si128((__m128i*)&sub_mul[8]);
- ssescale = _mm_load_si128((__m128i*)&sub_mul[12]);
- }
-
- for (uint32 x = 0 ; x < gw; x++) {
- __m128i pix_high;
- __m128i temp;
- _mm_prefetch((char*)(pixel+1), _MM_HINT_T0);
- __m128i pix_low = _mm_load_si128(pixel);
- // Subtract black
- pix_low = _mm_subs_epu16(pix_low, ssesub);
- // Multiply the two unsigned shorts and combine it to 32 bit result
- pix_high = _mm_mulhi_epu16(pix_low, ssescale);
- temp = _mm_mullo_epi16(pix_low, ssescale);
- pix_low = _mm_unpacklo_epi16(temp, pix_high);
- pix_high = _mm_unpackhi_epi16(temp, pix_high);
- // Add rounder
- pix_low = _mm_add_epi32(pix_low, sseround);
- pix_high = _mm_add_epi32(pix_high, sseround);
- // Shift down
- pix_low = _mm_srai_epi32(pix_low, 10);
- pix_high = _mm_srai_epi32(pix_high, 10);
- // Subtract to avoid clipping
- pix_low = _mm_sub_epi32(pix_low, ssesub2);
- pix_high = _mm_sub_epi32(pix_high, ssesub2);
- // Pack
- pix_low = _mm_packs_epi32(pix_low, pix_high);
- // Shift sign off
- pix_low = _mm_xor_si128(pix_low, ssesign);
- _mm_store_si128(pixel, pix_low);
- pixel++;
- }
- }
- _aligned_free(sub_mul);
- } else {
- // Not SSE2
- int gw = dim.x * cpp;
- int mul[4];
- int sub[4];
- for (int i = 0; i < 4; i++) {
- int v = i;
- if ((mOffset.x&1) != 0)
- v ^= 1;
- if ((mOffset.y&1) != 0)
- v ^= 2;
- mul[i] = (int)(16384.0f * 65535.0f / (float)(whitePoint -
blackLevelSeparate[v]));
- sub[i] = blackLevelSeparate[v];
- }
- for (int y = start_y; y < end_y; y++) {
- ushort16 *pixel = (ushort16*)getData(0, y);
- int *mul_local = &mul[2*(y&1)];
- int *sub_local = &sub[2*(y&1)];
- for (int x = 0 ; x < gw; x++) {
- pixel[x] = clampbits(((pixel[x] - sub_local[x&1]) * mul_local[x&1] +
8192) >> 14, 16);
- }
- }
- }
-}
-
-#else
-
-void RawImageData::scaleValues(int start_y, int end_y) {
- int gw = dim.x * cpp;
- int mul[4];
- int sub[4];
- for (int i = 0; i < 4; i++) {
- int v = i;
- if ((mOffset.x&1) != 0)
- v ^= 1;
- if ((mOffset.y&1) != 0)
- v ^= 2;
- mul[i] = (int)(16384.0f * 65535.0f / (float)(whitePoint -
blackLevelSeparate[v]));
- sub[i] = blackLevelSeparate[v];
- }
- for (int y = start_y; y < end_y; y++) {
- ushort16 *pixel = (ushort16*)getData(0, y);
- int *mul_local = &mul[2*(y&1)];
- int *sub_local = &sub[2*(y&1)];
- for (int x = 0 ; x < gw; x++) {
- pixel[x] = clampbits(((pixel[x] - sub_local[x&1]) * mul_local[x&1] +
8192) >> 14, 16);
- }
- }
-}
-
-#endif
-
-
RawImage::RawImage(RawImageData* p) : p_(p) {
pthread_mutex_lock(&p_->mymutex);
++p_->dataRefCount;
Modified: RawSpeed/RawImage.h
===================================================================
--- RawSpeed/RawImage.h 2011-03-19 17:20:28 UTC (rev 346)
+++ RawSpeed/RawImage.h 2011-03-19 19:23:21 UTC (rev 347)
@@ -28,26 +28,29 @@
class RawImage;
class RawImageWorker;
+typedef enum {TYPE_USHORT16, TYPE_FLOAT32} RawImageType;
class RawImageData
{
friend class RawImageWorker;
public:
virtual ~RawImageData(void);
- iPoint2D dim;
- uint32 bpp; // Bytes per pixel.
uint32 getCpp() const { return cpp; }
+ uint32 getBpp() const { return bpp; }
void setCpp(uint32 val);
- uint32 pitch;
virtual void createData();
virtual void destroyData();
+ RawSpeed::RawImageType DataType() const { return dataType; }
uchar8* getData();
uchar8* getData(uint32 x, uint32 y); // Not super fast, but safe. Don't
use per pixel.
uchar8* getDataUncropped(uint32 x, uint32 y);
virtual void subFrame( iPoint2D offset, iPoint2D new_size );
iPoint2D getUncroppedDim();
iPoint2D getCropOffset();
- void scaleBlackWhite();
+ virtual void scaleBlackWhite() = 0;
+ bool isAllocated() {return !!data;}
+ iPoint2D dim;
+ uint32 pitch;
bool isCFA;
ColorFilterArray cfa;
int blackLevel;
@@ -55,21 +58,48 @@
int whitePoint;
vector<BlackArea> blackAreas;
iPoint2D subsampling;
- bool isAllocated() {return !!data;}
- void scaleValues(int start_y, int end_y);
protected:
+ RawImageType dataType;
RawImageData(void);
RawImageData(iPoint2D dim, uint32 bpp, uint32 cpp=1);
- void calculateBlackAreas();
+ virtual void calculateBlackAreas() = 0;
+ virtual void scaleValues(int start_y, int end_y) = 0;
uint32 dataRefCount;
uchar8* data;
uint32 cpp; // Components per pixel
+ uint32 bpp; // Bytes per pixel.
friend class RawImage;
pthread_mutex_t mymutex;
iPoint2D mOffset;
iPoint2D uncropped_dim;
};
+class RawImageDataU16 : public RawImageData
+{
+public:
+ virtual void scaleBlackWhite();
+
+protected:
+ virtual void calculateBlackAreas();
+ virtual void scaleValues(int start_y, int end_y);
+ RawImageDataU16(void);
+ RawImageDataU16(iPoint2D dim, uint32 cpp=1);
+ friend class RawImage;
+};
+
+class RawImageDataFloat : public RawImageData
+{
+public:
+ virtual void scaleBlackWhite();
+
+protected:
+ virtual void calculateBlackAreas();
+ virtual void scaleValues(int start_y, int end_y);
+ RawImageDataFloat(void);
+ RawImageDataFloat(iPoint2D dim, uint32 cpp=1);
+ friend class RawImage;
+};
+
class RawImageWorker {
public:
typedef enum {TASK_SCALE_VALUES} RawImageWorkerTask;
@@ -87,8 +117,8 @@
class RawImage {
public:
- static RawImage create();
- static RawImage create(iPoint2D dim, uint32 bytesPerComponent, uint32
componentsPerPixel = 1);
+ static RawImage create(RawImageType type = TYPE_USHORT16);
+ static RawImage create(iPoint2D dim, RawImageType type = TYPE_USHORT16,
uint32 componentsPerPixel = 1);
RawImageData* operator-> ();
RawImageData& operator* ();
RawImage(RawImageData* p); // p must not be NULL
@@ -100,8 +130,28 @@
RawImageData* p_; // p_ is never NULL
};
-inline RawImage RawImage::create() { return new RawImageData(); }
-inline RawImage RawImage::create(iPoint2D dim, uint32 bytesPerPixel, uint32
componentsPerPixel)
-{ return new RawImageData(dim, bytesPerPixel, componentsPerPixel); }
+inline RawImage RawImage::create(RawImageType type) {
+ switch (type)
+ {
+ case TYPE_USHORT16:
+ return new RawImageDataU16();
+ case TYPE_FLOAT32:
+ return new RawImageDataFloat();
+ default:
+ printf("RawImage::create: Unknown Image type!\n");
+ }
+ return NULL;
+}
+inline RawImage RawImage::create(iPoint2D dim, RawImageType type, uint32
componentsPerPixel)
+{
+ switch (type) {
+ case TYPE_USHORT16:
+ return new RawImageDataU16(dim, componentsPerPixel);
+ default:
+ printf("RawImage::create: Unknown Image type!\n");
+ }
+ return NULL;
+}
+
} // namespace RawSpeed
Added: RawSpeed/RawImageDataFloat.cpp
===================================================================
--- RawSpeed/RawImageDataFloat.cpp (rev 0)
+++ RawSpeed/RawImageDataFloat.cpp 2011-03-19 19:23:21 UTC (rev 347)
@@ -0,0 +1,288 @@
+#include "StdAfx.h"
+#include "RawImage.h"
+#include "RawDecoder.h" // For exceptions
+/*
+RawSpeed - RAW file decoder.
+
+Copyright (C) 2009 Klaus Post
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+http://www.klauspost.com
+*/
+#if defined(__SSE2__)
+#include <emmintrin.h>
+#endif
+
+namespace RawSpeed {
+
+ RawImageDataFloat::RawImageDataFloat(void) {
+ bpp = 4;
+ dataType = TYPE_FLOAT32;
+ }
+
+ RawImageDataFloat::RawImageDataFloat(iPoint2D _dim, uint32 _cpp) :
+ RawImageData(_dim, 4, _cpp)
+ {
+ dataType = TYPE_FLOAT32;
+ }
+
+
+ void RawImageDataFloat::calculateBlackAreas() {
+ float accPixels[4] = {0,0,0,0};
+ int totalpixels = 0;
+
+ for (uint32 i = 0; i < blackAreas.size(); i++) {
+ BlackArea area = blackAreas[i];
+
+ /* Make sure area sizes are multiple of two,
+ so we have the same amount of pixels for each CFA group */
+ area.size = area.size - (area.size&1);
+
+ /* Process horizontal area */
+ if (!area.isVertical) {
+ if ((int)area.offset+(int)area.size > uncropped_dim.y)
+ ThrowRDE("RawImageData::calculateBlackAreas: Offset + size is larger
than height of image");
+ for (uint32 y = area.offset; y < area.offset+area.size; y++) {
+ float *pixel = (float*)getDataUncropped(mOffset.x, y);
+ for (int x = mOffset.x; x < dim.x+mOffset.x; x++) {
+ accPixels[((y&1)<<1)|(x&1)] += *pixel++;
+ }
+ }
+ totalpixels += area.size * dim.x;
+ }
+
+ /* Process vertical area */
+ if (area.isVertical) {
+ if ((int)area.offset+(int)area.size > uncropped_dim.x)
+ ThrowRDE("RawImageData::calculateBlackAreas: Offset + size is larger
than width of image");
+ for (int y = mOffset.y; y < dim.y+mOffset.y; y++) {
+ float *pixel = (float*)getDataUncropped(area.offset, y);
+ for (uint32 x = area.offset; x < area.size+area.offset; x++) {
+ accPixels[((y&1)<<1)|(x&1)] += *pixel++;
+ }
+ }
+ totalpixels += area.size * dim.y;
+ }
+ }
+
+ if (!totalpixels) {
+ for (int i = 0 ; i < 4; i++)
+ blackLevelSeparate[i] = blackLevel;
+ return;
+ }
+
+ /* Calculate median value of black areas for each component */
+ /* Adjust the number of total pixels so it is the same as the median of
each histogram */
+ totalpixels /= 4;
+
+ for (int i = 0 ; i < 4; i++) {
+ blackLevelSeparate[i] = (int)(65535.0f * accPixels[i]/totalpixels);
+ }
+
+ /* If this is not a CFA image, we do not use separate blacklevels, use
average */
+ if (!isCFA) {
+ int total = 0;
+ for (int i = 0 ; i < 4; i++)
+ total+=blackLevelSeparate[i];
+ for (int i = 0 ; i < 4; i++)
+ blackLevelSeparate[i] = (total+2)>>2;
+ }
+ }
+
+ void RawImageDataFloat::scaleBlackWhite() {
+ const int skipBorder = 150;
+ int gw = (dim.x - skipBorder) * cpp;
+ if ((blackAreas.empty() && blackLevelSeparate[0] < 0 && blackLevel < 0) ||
whitePoint == 65536) { // Estimate
+ float b = 100000000;
+ float m = -10000000;
+ for (int row = skipBorder*cpp;row < (dim.y - skipBorder);row++) {
+ float *pixel = (float*)getData(skipBorder, row);
+ for (int col = skipBorder ; col < gw ; col++) {
+ b = MIN(*pixel, b);
+ m = MAX(*pixel, m);
+ pixel++;
+ }
+ }
+ if (blackLevel < 0)
+ blackLevel = (int)b;
+ if (whitePoint == 65536)
+ whitePoint = (int)m;
+ printf("Estimated black:%d, Estimated white: %d\n", blackLevel,
whitePoint);
+ }
+
+ /* If filter has not set separate blacklevel, compute or fetch it */
+ 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;
+
+ 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) {
+ bool use_sse2;
+#ifdef _MSC_VER
+ int info[4];
+ __cpuid(info, 1);
+ use_sse2 = !!(info[3]&(1 << 26));
+#else
+ use_sse2 = TRUE;
+#endif
+
+ float app_scale = 65535.0f / (whitePoint - blackLevelSeparate[0]);
+ // Check SSE2
+ if (use_sse2 && app_scale < 63) {
+
+ __m128i sseround;
+ __m128i ssesub2;
+ __m128i ssesign;
+ uint32* sub_mul = (uint32*)_aligned_malloc(16*4*2, 16);
+ uint32 gw = pitch / 16;
+ // 10 bit fraction
+ uint32 mul = (int)(1024.0f * 65535.0f / (float)(whitePoint -
blackLevelSeparate[mOffset.x&1]));
+ mul |= ((int)(1024.0f * 65535.0f / (float)(whitePoint -
blackLevelSeparate[(mOffset.x+1)&1])))<<16;
+ uint32 b = blackLevelSeparate[mOffset.x&1] |
(blackLevelSeparate[(mOffset.x+1)&1]<<16);
+
+ for (int i = 0; i< 4; i++) {
+ sub_mul[i] = b; // Subtract even lines
+ sub_mul[4+i] = mul; // Multiply even lines
+ }
+
+ mul = (int)(1024.0f * 65535.0f / (float)(whitePoint -
blackLevelSeparate[2+(mOffset.x&1)]));
+ mul |= ((int)(1024.0f * 65535.0f / (float)(whitePoint -
blackLevelSeparate[2+((mOffset.x+1)&1)])))<<16;
+ b = blackLevelSeparate[2+(mOffset.x&1)] |
(blackLevelSeparate[2+((mOffset.x+1)&1)]<<16);
+
+ for (int i = 0; i< 4; i++) {
+ sub_mul[8+i] = b; // Subtract odd lines
+ sub_mul[12+i] = mul; // Multiply odd lines
+ }
+
+ sseround = _mm_set_epi32(512, 512, 512, 512);
+ ssesub2 = _mm_set_epi32(32768, 32768, 32768, 32768);
+ ssesign = _mm_set_epi32(0x80008000, 0x80008000, 0x80008000, 0x80008000);
+
+ for (int y = start_y; y < end_y; y++) {
+ __m128i* pixel = (__m128i*) & data[(mOffset.y+y)*pitch];
+ __m128i ssescale, ssesub;
+ if (((y+mOffset.y)&1) == 0) {
+ ssesub = _mm_load_si128((__m128i*)&sub_mul[0]);
+ ssescale = _mm_load_si128((__m128i*)&sub_mul[4]);
+ } else {
+ ssesub = _mm_load_si128((__m128i*)&sub_mul[8]);
+ ssescale = _mm_load_si128((__m128i*)&sub_mul[12]);
+ }
+
+ for (uint32 x = 0 ; x < gw; x++) {
+ __m128i pix_high;
+ __m128i temp;
+ _mm_prefetch((char*)(pixel+1), _MM_HINT_T0);
+ __m128i pix_low = _mm_load_si128(pixel);
+ // Subtract black
+ pix_low = _mm_subs_epu16(pix_low, ssesub);
+ // Multiply the two unsigned shorts and combine it to 32 bit result
+ pix_high = _mm_mulhi_epu16(pix_low, ssescale);
+ temp = _mm_mullo_epi16(pix_low, ssescale);
+ pix_low = _mm_unpacklo_epi16(temp, pix_high);
+ pix_high = _mm_unpackhi_epi16(temp, pix_high);
+ // Add rounder
+ pix_low = _mm_add_epi32(pix_low, sseround);
+ pix_high = _mm_add_epi32(pix_high, sseround);
+ // Shift down
+ pix_low = _mm_srai_epi32(pix_low, 10);
+ pix_high = _mm_srai_epi32(pix_high, 10);
+ // Subtract to avoid clipping
+ pix_low = _mm_sub_epi32(pix_low, ssesub2);
+ pix_high = _mm_sub_epi32(pix_high, ssesub2);
+ // Pack
+ pix_low = _mm_packs_epi32(pix_low, pix_high);
+ // Shift sign off
+ pix_low = _mm_xor_si128(pix_low, ssesign);
+ _mm_store_si128(pixel, pix_low);
+ pixel++;
+ }
+ }
+ _aligned_free(sub_mul);
+ } else {
+ // Not SSE2
+ int gw = dim.x * cpp;
+ int mul[4];
+ int sub[4];
+ for (int i = 0; i < 4; i++) {
+ int v = i;
+ if ((mOffset.x&1) != 0)
+ v ^= 1;
+ if ((mOffset.y&1) != 0)
+ v ^= 2;
+ mul[i] = (int)(16384.0f * 65535.0f / (float)(whitePoint -
blackLevelSeparate[v]));
+ sub[i] = blackLevelSeparate[v];
+ }
+ for (int y = start_y; y < end_y; y++) {
+ ushort16 *pixel = (ushort16*)getData(0, y);
+ int *mul_local = &mul[2*(y&1)];
+ int *sub_local = &sub[2*(y&1)];
+ for (int x = 0 ; x < gw; x++) {
+ pixel[x] = clampbits(((pixel[x] - sub_local[x&1]) * mul_local[x&1] +
8192) >> 14, 16);
+ }
+ }
+ }
+ }
+
+#else
+
+ void RawImageDataFloat::scaleValues(int start_y, int end_y) {
+ int gw = dim.x * cpp;
+ float mul[4];
+ float sub[4];
+ for (int i = 0; i < 4; i++) {
+ int v = i;
+ if ((mOffset.x&1) != 0)
+ v ^= 1;
+ if ((mOffset.y&1) != 0)
+ v ^= 2;
+ mul[i] = 65535.0f / (float)(whitePoint - blackLevelSeparate[v]);
+ sub[i] = (float)blackLevelSeparate[v];
+ }
+ for (int y = start_y; y < end_y; y++) {
+ float *pixel = (float*)getData(0, y);
+ float *mul_local = &mul[2*(y&1)];
+ float *sub_local = &sub[2*(y&1)];
+ for (int x = 0 ; x < gw; x++) {
+ pixel[x] = (pixel[x] - sub_local[x&1]) * mul_local[x&1];
+ }
+ }
+ }
+
+#endif
+
+} // namespace RawSpeed
Added: RawSpeed/RawImageDataU16.cpp
===================================================================
--- RawSpeed/RawImageDataU16.cpp (rev 0)
+++ RawSpeed/RawImageDataU16.cpp 2011-03-19 19:23:21 UTC (rev 347)
@@ -0,0 +1,298 @@
+#include "StdAfx.h"
+#include "RawImage.h"
+#include "RawDecoder.h" // For exceptions
+/*
+ RawSpeed - RAW file decoder.
+
+ Copyright (C) 2009 Klaus Post
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
+
+ http://www.klauspost.com
+*/
+#if defined(__SSE2__)
+#include <emmintrin.h>
+#endif
+
+namespace RawSpeed {
+
+RawImageDataU16::RawImageDataU16(void)
+{
+ bpp = 2;
+}
+
+RawImageDataU16::RawImageDataU16(iPoint2D _dim, uint32 _cpp) :
+RawImageData(_dim, 2, _cpp)
+{
+}
+
+
+void RawImageDataU16::calculateBlackAreas() {
+ int* histogram = (int*)malloc(4*65536*sizeof(int));
+ memset(histogram, 0, 4*65536*sizeof(int));
+ int totalpixels = 0;
+
+ for (uint32 i = 0; i < blackAreas.size(); i++) {
+ BlackArea area = blackAreas[i];
+
+ /* Make sure area sizes are multiple of two,
+ so we have the same amount of pixels for each CFA group */
+ area.size = area.size - (area.size&1);
+
+ /* Process horizontal area */
+ if (!area.isVertical) {
+ if ((int)area.offset+(int)area.size > uncropped_dim.y)
+ ThrowRDE("RawImageData::calculateBlackAreas: Offset + size is larger
than height of image");
+ for (uint32 y = area.offset; y < area.offset+area.size; y++) {
+ ushort16 *pixel = (ushort16*)getDataUncropped(mOffset.x, y);
+ int* localhist = &histogram[(y&1)*(65536*2)];
+ for (int x = mOffset.x; x < dim.x+mOffset.x; x++) {
+ localhist[((x&1)<<16) + *pixel]++;
+ }
+ }
+ totalpixels += area.size * dim.x;
+ }
+
+ /* Process vertical area */
+ if (area.isVertical) {
+ if ((int)area.offset+(int)area.size > uncropped_dim.x)
+ ThrowRDE("RawImageData::calculateBlackAreas: Offset + size is larger
than width of image");
+ for (int y = mOffset.y; y < dim.y+mOffset.y; y++) {
+ ushort16 *pixel = (ushort16*)getDataUncropped(area.offset, y);
+ int* localhist = &histogram[(y&1)*(65536*2)];
+ for (uint32 x = area.offset; x < area.size+area.offset; x++) {
+ localhist[((x&1)<<16) + *pixel]++;
+ }
+ }
+ totalpixels += area.size * dim.y;
+ }
+ }
+
+ if (!totalpixels) {
+ for (int i = 0 ; i < 4; i++)
+ blackLevelSeparate[i] = blackLevel;
+ return;
+ }
+
+ /* Calculate median value of black areas for each component */
+ /* Adjust the number of total pixels so it is the same as the median of each
histogram */
+ totalpixels /= 4*2;
+
+ for (int i = 0 ; i < 4; i++) {
+ int* localhist = &histogram[i*65536];
+ int acc_pixels = localhist[0];
+ int pixel_value = 0;
+ while (acc_pixels <= totalpixels && pixel_value < 65535) {
+ pixel_value++;
+ acc_pixels += localhist[pixel_value];
+ }
+ blackLevelSeparate[i] = pixel_value;
+ }
+
+ /* If this is not a CFA image, we do not use separate blacklevels, use
average */
+ if (!isCFA) {
+ int total = 0;
+ for (int i = 0 ; i < 4; i++)
+ total+=blackLevelSeparate[i];
+ for (int i = 0 ; i < 4; i++)
+ blackLevelSeparate[i] = (total+2)>>2;
+ }
+ free(histogram);
+}
+
+void RawImageDataU16::scaleBlackWhite() {
+ const int skipBorder = 150;
+ int gw = (dim.x - skipBorder) * cpp;
+ if ((blackAreas.empty() && blackLevelSeparate[0] < 0 && blackLevel < 0) ||
whitePoint == 65536) { // Estimate
+ int b = 65536;
+ int m = 0;
+ for (int row = skipBorder*cpp;row < (dim.y - skipBorder);row++) {
+ ushort16 *pixel = (ushort16*)getData(skipBorder, row);
+ for (int col = skipBorder ; col < gw ; col++) {
+ b = MIN(*pixel, b);
+ m = MAX(*pixel, m);
+ pixel++;
+ }
+ }
+ if (blackLevel < 0)
+ blackLevel = b;
+ if (whitePoint == 65536)
+ whitePoint = m;
+ printf("Estimated black:%d, Estimated white: %d\n", blackLevel,
whitePoint);
+ }
+
+ /* If filter has not set separate blacklevel, compute or fetch it */
+ 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;
+
+ 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 _MSC_VER > 1399 || defined(__SSE2__)
+
+void RawImageDataU16::scaleValues(int start_y, int end_y) {
+ bool use_sse2;
+#ifdef _MSC_VER
+ int info[4];
+ __cpuid(info, 1);
+ use_sse2 = !!(info[3]&(1 << 26));
+#else
+ use_sse2 = TRUE;
+#endif
+
+ float app_scale = 65535.0f / (whitePoint - blackLevelSeparate[0]);
+ // Check SSE2
+ if (use_sse2 && app_scale < 63) {
+
+ __m128i sseround;
+ __m128i ssesub2;
+ __m128i ssesign;
+ uint32* sub_mul = (uint32*)_aligned_malloc(16*4*2, 16);
+ uint32 gw = pitch / 16;
+ // 10 bit fraction
+ uint32 mul = (int)(1024.0f * 65535.0f / (float)(whitePoint -
blackLevelSeparate[mOffset.x&1]));
+ mul |= ((int)(1024.0f * 65535.0f / (float)(whitePoint -
blackLevelSeparate[(mOffset.x+1)&1])))<<16;
+ uint32 b = blackLevelSeparate[mOffset.x&1] |
(blackLevelSeparate[(mOffset.x+1)&1]<<16);
+
+ for (int i = 0; i< 4; i++) {
+ sub_mul[i] = b; // Subtract even lines
+ sub_mul[4+i] = mul; // Multiply even lines
+ }
+
+ mul = (int)(1024.0f * 65535.0f / (float)(whitePoint -
blackLevelSeparate[2+(mOffset.x&1)]));
+ mul |= ((int)(1024.0f * 65535.0f / (float)(whitePoint -
blackLevelSeparate[2+((mOffset.x+1)&1)])))<<16;
+ b = blackLevelSeparate[2+(mOffset.x&1)] |
(blackLevelSeparate[2+((mOffset.x+1)&1)]<<16);
+
+ for (int i = 0; i< 4; i++) {
+ sub_mul[8+i] = b; // Subtract odd lines
+ sub_mul[12+i] = mul; // Multiply odd lines
+ }
+
+ sseround = _mm_set_epi32(512, 512, 512, 512);
+ ssesub2 = _mm_set_epi32(32768, 32768, 32768, 32768);
+ ssesign = _mm_set_epi32(0x80008000, 0x80008000, 0x80008000, 0x80008000);
+
+ for (int y = start_y; y < end_y; y++) {
+ __m128i* pixel = (__m128i*) & data[(mOffset.y+y)*pitch];
+ __m128i ssescale, ssesub;
+ if (((y+mOffset.y)&1) == 0) {
+ ssesub = _mm_load_si128((__m128i*)&sub_mul[0]);
+ ssescale = _mm_load_si128((__m128i*)&sub_mul[4]);
+ } else {
+ ssesub = _mm_load_si128((__m128i*)&sub_mul[8]);
+ ssescale = _mm_load_si128((__m128i*)&sub_mul[12]);
+ }
+
+ for (uint32 x = 0 ; x < gw; x++) {
+ __m128i pix_high;
+ __m128i temp;
+ _mm_prefetch((char*)(pixel+1), _MM_HINT_T0);
+ __m128i pix_low = _mm_load_si128(pixel);
+ // Subtract black
+ pix_low = _mm_subs_epu16(pix_low, ssesub);
+ // Multiply the two unsigned shorts and combine it to 32 bit result
+ pix_high = _mm_mulhi_epu16(pix_low, ssescale);
+ temp = _mm_mullo_epi16(pix_low, ssescale);
+ pix_low = _mm_unpacklo_epi16(temp, pix_high);
+ pix_high = _mm_unpackhi_epi16(temp, pix_high);
+ // Add rounder
+ pix_low = _mm_add_epi32(pix_low, sseround);
+ pix_high = _mm_add_epi32(pix_high, sseround);
+ // Shift down
+ pix_low = _mm_srai_epi32(pix_low, 10);
+ pix_high = _mm_srai_epi32(pix_high, 10);
+ // Subtract to avoid clipping
+ pix_low = _mm_sub_epi32(pix_low, ssesub2);
+ pix_high = _mm_sub_epi32(pix_high, ssesub2);
+ // Pack
+ pix_low = _mm_packs_epi32(pix_low, pix_high);
+ // Shift sign off
+ pix_low = _mm_xor_si128(pix_low, ssesign);
+ _mm_store_si128(pixel, pix_low);
+ pixel++;
+ }
+ }
+ _aligned_free(sub_mul);
+ } else {
+ // Not SSE2
+ int gw = dim.x * cpp;
+ int mul[4];
+ int sub[4];
+ for (int i = 0; i < 4; i++) {
+ int v = i;
+ if ((mOffset.x&1) != 0)
+ v ^= 1;
+ if ((mOffset.y&1) != 0)
+ v ^= 2;
+ mul[i] = (int)(16384.0f * 65535.0f / (float)(whitePoint -
blackLevelSeparate[v]));
+ sub[i] = blackLevelSeparate[v];
+ }
+ for (int y = start_y; y < end_y; y++) {
+ ushort16 *pixel = (ushort16*)getData(0, y);
+ int *mul_local = &mul[2*(y&1)];
+ int *sub_local = &sub[2*(y&1)];
+ for (int x = 0 ; x < gw; x++) {
+ pixel[x] = clampbits(((pixel[x] - sub_local[x&1]) * mul_local[x&1] +
8192) >> 14, 16);
+ }
+ }
+ }
+}
+
+#else
+
+void RawImageDataU16::scaleValues(int start_y, int end_y) {
+ int gw = dim.x * cpp;
+ int mul[4];
+ int sub[4];
+ for (int i = 0; i < 4; i++) {
+ int v = i;
+ if ((mOffset.x&1) != 0)
+ v ^= 1;
+ if ((mOffset.y&1) != 0)
+ v ^= 2;
+ mul[i] = (int)(16384.0f * 65535.0f / (float)(whitePoint -
blackLevelSeparate[v]));
+ sub[i] = blackLevelSeparate[v];
+ }
+ for (int y = start_y; y < end_y; y++) {
+ ushort16 *pixel = (ushort16*)getData(0, y);
+ int *mul_local = &mul[2*(y&1)];
+ int *sub_local = &sub[2*(y&1)];
+ for (int x = 0 ; x < gw; x++) {
+ pixel[x] = clampbits(((pixel[x] - sub_local[x&1]) * mul_local[x&1] +
8192) >> 14, 16);
+ }
+ }
+}
+
+#endif
+
+} // namespace RawSpeed
Modified: RawSpeed/RawSpeed.vcproj
===================================================================
--- RawSpeed/RawSpeed.vcproj 2011-03-19 17:20:28 UTC (rev 346)
+++ RawSpeed/RawSpeed.vcproj 2011-03-19 19:23:21 UTC (rev 347)
@@ -190,10 +190,6 @@
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
- RelativePath=".\RawImage.cpp"
- >
- </File>
- <File
RelativePath=".\RawSpeed.cpp"
>
</File>
@@ -389,6 +385,22 @@
>
</File>
</Filter>
+ <Filter
+ Name="RawImage"
+ >
+ <File
+ RelativePath=".\RawImage.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\RawImageDataFloat.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\RawImageDataU16.cpp"
+ >
+ </File>
+ </Filter>
</Filter>
<Filter
Name="Header Files"
Modified: RawSpeed/Rw2Decoder.cpp
===================================================================
--- RawSpeed/Rw2Decoder.cpp 2011-03-19 17:20:28 UTC (rev 346)
+++ RawSpeed/Rw2Decoder.cpp 2011-03-19 19:23:21 UTC (rev 347)
@@ -51,8 +51,6 @@
uint32 height = raw->getEntry((TiffTag)3)->getShort();
uint32 width = raw->getEntry((TiffTag)2)->getShort();
- mRaw->bpp = 2;
-
if (isOldPanasonic) {
ThrowRDE("Cannot decoder old-style Panasonic RAW files");
TiffEntry *offsets = raw->getEntry(STRIPOFFSETS);
_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit