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 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); /* If offset is negative (relative to right or bottom border) calculate the offset from the left or top border */ if(area.offset < 0) area.offset += area.isVertical ? uncropped_dim.x : uncropped_dim.y; /* 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; free(histogram); 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; }