29
29
namespace RawSpeed {
31
31
RawImageData::RawImageData(void):
32
dim(0, 0), bpp(0), isCFA(true),
32
dim(0, 0), isCFA(true),
33
33
blackLevel(-1), whitePoint(65536),
34
dataRefCount(0), data(0), cpp(1) {
34
dataRefCount(0), data(0), cpp(1), bpp(0),
36
blackLevelSeparate[0] = blackLevelSeparate[1] = blackLevelSeparate[2] = blackLevelSeparate[3] = -1;
35
37
pthread_mutex_init(&mymutex, NULL);
36
38
subsampling.x = subsampling.y = 1;
39
41
RawImageData::RawImageData(iPoint2D _dim, uint32 _bpc, uint32 _cpp) :
41
43
blackLevel(-1), whitePoint(65536),
42
dataRefCount(0), data(0), cpp(cpp) {
44
dataRefCount(0), data(0), cpp(cpp), bpp(_bpc),
46
blackLevelSeparate[0] = blackLevelSeparate[1] = blackLevelSeparate[2] = blackLevelSeparate[3] = -1;
43
47
subsampling.x = subsampling.y = 1;
45
49
pthread_mutex_init(&mymutex, NULL);
136
void RawImageData::calculateBlackAreas() {
137
int* histogram = (int*)malloc(4*65536*sizeof(int));
138
memset(histogram, 0, 4*65536*sizeof(int));
141
for (uint32 i = 0; i < blackAreas.size(); i++) {
142
BlackArea area = blackAreas[i];
143
/* Process horizontal area */
144
if (!area.isVertical) {
145
for (uint32 y = area.offset; y < area.offset+area.size; y++) {
146
ushort16 *pixel = (ushort16*)getDataUncropped(mOffset.x, y);
147
int* localhist = &histogram[(y&1)*(65536*2)];
148
for (int x = mOffset.x; x < dim.x; x++) {
149
localhist[((x&1)<<16) + *pixel]++;
152
totalpixels += area.size * dim.x;
155
/* Process vertical area */
156
if (area.isVertical) {
157
for (int y = mOffset.y; y < dim.y; y++) {
158
ushort16 *pixel = (ushort16*)getDataUncropped(area.offset, y);
159
int* localhist = &histogram[(y&1)*(65536*2)];
160
for (uint32 x = area.offset; x < area.size; x++) {
161
localhist[((x&1)<<16) + *pixel]++;
165
totalpixels += area.size * dim.y;
169
for (int i = 0 ; i < 4; i++)
170
blackLevelSeparate[i] = blackLevel;
174
/* Calculate median value of black areas for each component */
175
/* Adjust the number of total pixels so it is the same as the median of each histogram */
178
for (int i = 0 ; i < 4; i++) {
179
int* localhist = &histogram[i*65536];
180
int acc_pixels = localhist[0];
182
while (acc_pixels <= totalpixels && pixel_value < 65535) {
184
acc_pixels += localhist[pixel_value];
186
blackLevelSeparate[i] = pixel_value;
191
void RawImageData::scaleBlackWhite() {
192
const int skipBorder = 150;
193
int gw = (dim.x - skipBorder) * cpp;
194
if (blackLevel < 0 || whitePoint == 65536) { // Estimate
197
for (int row = skipBorder*cpp;row < (dim.y - skipBorder);row++) {
198
ushort16 *pixel = (ushort16*)getData(skipBorder, row);
199
for (int col = skipBorder ; col < gw ; col++) {
207
if (whitePoint == 65536)
209
printf("Estimated black:%d, Estimated white: %d\n", blackLevel, whitePoint);
212
calculateBlackAreas();
216
#if _MSC_VER > 1399 || defined(__SSE2__)
218
void RawImageData::scaleValues() {
223
use_sse2 = !!(info[3]&(1 << 26));
234
uint32* sub_mul = (uint32*)_aligned_malloc(16*4*2, 16);
235
uint32 gw = pitch / 16;
237
uint32 mul = (int)(1024.0f * 65535.0f / (float)(whitePoint - blackLevelSeparate[mOffset.x&1]));
238
mul |= ((int)(1024.0f * 65535.0f / (float)(whitePoint - blackLevelSeparate[(mOffset.x+1)&1])))<<16;
239
uint32 b = blackLevelSeparate[mOffset.x&1] | (blackLevelSeparate[(mOffset.x+1)&1]<<16);
241
for (int i = 0; i< 4; i++) {
242
sub_mul[i] = b; // Subtract even lines
243
sub_mul[4+i] = mul; // Multiply even lines
246
mul = (int)(1024.0f * 65535.0f / (float)(whitePoint - blackLevelSeparate[2+(mOffset.x&1)]));
247
mul |= ((int)(1024.0f * 65535.0f / (float)(whitePoint - blackLevelSeparate[2+((mOffset.x+1)&1)])))<<16;
248
b = blackLevelSeparate[2+(mOffset.x&1)] | (blackLevelSeparate[2+((mOffset.x+1)&1)]<<16);
250
for (int i = 0; i< 4; i++) {
251
sub_mul[8+i] = b; // Subtract odd lines
252
sub_mul[12+i] = mul; // Multiply odd lines
255
sseround = _mm_set_epi32(512, 512, 512, 512);
256
ssesub2 = _mm_set_epi32(32768, 32768, 32768, 32768);
257
ssesign = _mm_set_epi32(0x80008000, 0x80008000, 0x80008000, 0x80008000);
259
for (int y = 0; y < dim.y; y++) {
260
__m128i* pixel = (__m128i*) & data[(mOffset.y+y)*pitch];
261
__m128i ssescale, ssesub;
262
if (((y+mOffset.y)&1) == 0) {
263
ssesub = _mm_load_si128((__m128i*)&sub_mul[0]);
264
ssescale = _mm_load_si128((__m128i*)&sub_mul[4]);
266
ssesub = _mm_load_si128((__m128i*)&sub_mul[8]);
267
ssescale = _mm_load_si128((__m128i*)&sub_mul[12]);
270
for (uint32 x = 0 ; x < gw; x++) {
273
__m128i pix_low = _mm_load_si128(pixel);
275
pix_low = _mm_subs_epu16(pix_low, ssesub);
276
// Multiply the two unsigned shorts and combine it to 32 bit result
277
pix_high = _mm_mulhi_epu16(pix_low, ssescale);
278
temp = _mm_mullo_epi16(pix_low, ssescale);
279
pix_low = _mm_unpacklo_epi16(temp, pix_high);
280
pix_high = _mm_unpackhi_epi16(temp, pix_high);
282
pix_low = _mm_add_epi32(pix_low, sseround);
283
pix_high = _mm_add_epi32(pix_high, sseround);
285
pix_low = _mm_srai_epi32(pix_low, 10);
286
pix_high = _mm_srai_epi32(pix_high, 10);
287
// Subtract to avoid clipping
288
pix_low = _mm_sub_epi32(pix_low, ssesub2);
289
pix_high = _mm_sub_epi32(pix_high, ssesub2);
291
pix_low = _mm_packs_epi32(pix_low, pix_high);
293
pix_low = _mm_xor_si128(pix_low, ssesign);
294
_mm_store_si128(pixel, pix_low);
298
_aligned_free(sub_mul);
301
int gw = dim.x * cpp;
304
for (int i = 0; i < 4; i++) {
306
if ((mOffset.x&1) != 0)
308
if ((mOffset.y&1) != 0)
310
mul[i] = (int)(16384.0f * 65535.0f / (float)(whitePoint - blackLevelSeparate[v]));
311
sub[i] = blackLevelSeparate[v];
313
for (int y = 0; y < dim.y; y++) {
314
ushort16 *pixel = (ushort16*)getData(0, y);
315
int *mul_local = &mul[2*(y&1)];
316
int *sub_local = &sub[2*(y&1)];
317
for (int x = 0 ; x < gw; x++) {
318
pixel[x] = clampbits(((pixel[x] - sub_local[x&1]) * mul_local[x&1] + 8192) >> 14, 16);
326
void RawImageData::scaleValues() {
327
int gw = dim.x * cpp;
330
for (int i = 0; i < 4; i++) {
332
if ((mOffset.x&1) != 0)
334
if ((mOffset.y&1) != 0)
336
mul[i] = (int)(16384.0f * 65535.0f / (float)(whitePoint - blackLevelSeparate[v]));
337
sub[i] = blackLevelSeparate[v];
339
for (int y = 0; y < dim.y; y++) {
340
ushort16 *pixel = (ushort16*)getData(0, y);
341
int *mul_local = &mul[2*(y&1)];
342
int *sub_local = &sub[2*(y&1)];
343
for (int x = 0 ; x < gw; x++) {
344
pixel[x] = clampbits(((pixel[x] - sub_local[x&1]) * mul_local[x&1] + 8192) >> 14, 16);
352
152
RawImage::RawImage(RawImageData* p) : p_(p) {
353
153
pthread_mutex_lock(&p_->mymutex);