void scale_brightness( uint8_t array[],
unsigned int cols,
unsigned int rows,
double scale_factor )
{
for (int x = 0; x < rows; x++)
{
for (int y = 0; y < cols; y++)
{
array[x] = ceil(scale_factor * array[x]);
array[y] = ceil(scale_factor * array[y]);
if (array[x] >= 255 && array[y] >= 255)
{
array[x] = 255;
array[y] = 255;
}
}
}
}
So this function is supposed to multiply each pixel in an image by a scale factor. But for some reason, it's not working. I can't find whats wrong with it. Would anybody be able to help me out with it?
Just unroll the loops on paper and you'll see what's happening...
1st iteration (x = 0, y = 0)
array[0] = ceil(scale_factor * array[0]);
array[0] = ceil(scale_factor * array[0]);
if (array[0] >= 255 && array[0] >= 255)
{
array[0] = 255;
array[0] = 255;
}
Already this is nonsensical, you're doing the same operation twice on the same element and then your if statement checks for the same condition twice on the same element, to then assign 255 twice to that same value.
2nd iteration (x = 0, y = 1)
array[0] = ceil(scale_factor * array[0]);
array[1] = ceil(scale_factor * array[1]);
if (array[0] >= 255 && array[1] >= 255)
{
array[0] = 255;
array[1] = 255;
}
So now you're setting element 0 again even though you just did it in the last iteration, but at least we're considering element 1 now.
By extrapolating we can see that the calculation will be applied for pixels 0 to max(cols, rows). Obviously your array of pixels has many more pixels than that, probably (cols * rows) pixels, so your algorithm ignores most pixels but is applied many times for some pixels, and that's basically why it doesn't work.
Consider array[x] = ceil(scale_factor * array[x]);. If array[x] is 255 and scale_factor is 1.1, then that would be like array[x] = 281;. This is an overflow (281 is too large to fit in an unsigned 8-bit integer). C will discard the highest bits that don't fit, so it would be like array[x] = 25;.
Now consider if(array[x] >= 255) array[x] = 255;. Because it's working with unsigned 8-bit integers (that can only store values in the range from 0 to 255); it's only possible for (array[x] >= 255) to be true when array[x] contains the value 255. It would be equivalent to if(array[x] == 255) array[x] = 255;, which actually does nothing at all. Your if (array[x] >= 255 && array[y] >= 255) { code has the same problem - it does nothing.
Now read Asik's answer - he's right too. You're doing the same broken calculation multiple times on each pixel; and it's going to end up being a bit like a pseudo-random number generator.
Related
Suppose I have an array of size 100.
Initially, let's assume that all the elements have a value of 0.
Now, let's say I want to insert 60 elements such that the elements get filled evenly.
I don't want all the elements to be filled from arr[0] to arr[59]. Rather, I want the whole array to be filled in such a way that the array looks filled. What algorithm can I use to achieve this?
For eg-
I have 5 elements to be filled (let's say with 1) in an array of size 10. Then the array should look like this:
[1,0,1,0,1,0,1,0,1,0]
In the case of 3 elements,
[1,0,0,0,1,0,0,0,1,0]
Is there any smart way to do this dynamically?
You would need to find the right gap length to evenly fill it. For this, we binary search the correct gap which most evenly fills the gap such that the no. of 1's to be supposedly filled doesn't go out of the array bounds.
In the case where no. of ones to be filled is greater than half of the array size, we fill it with as even gaps of length 2 as much as possible and fill the remaining ones adjacent to each other.
function solve(arraySize, oneCount) {
let newArray = Array(arraySize).fill(0);
let low = 0,
high = arraySize;
let gap = 0;
while (low <= high) {
let mid = (low + high) >> 1;
if (mid * (oneCount - 1) < arraySize) {
gap = mid;
low = mid + 1;
} else {
high = mid - 1;
}
}
let needsEvenDivision = oneCount > (arraySize >> 1) && gap === 1;
gap = needsEvenDivision ? 2 : gap;
let idx = 0;
while (idx < arraySize && oneCount > 0) {
newArray[idx] = 1;
oneCount--;
if (needsEvenDivision && arraySize - idx - 2 < oneCount) gap = 1;
idx += gap;
}
return newArray;
}
console.log(solve(4, 2));
console.log(solve(10, 4));
console.log(solve(10, 7));
The problem is like:
There is a 60mm long rubber with a scale every 1mm.
Where is the position of each scale when this rubber is stretched to a length of 100 mm?
int main(void)
{
constexpr int M= 10;
constexpr int n = 5;
//initially all 0
int Array[M] = { 0 };
//Calclate where the ith element of the n elements should go in the result array
for( int i=0; i<n; ++i )
{
int idx = (int)std::round( (double)i * M / n);
Array[idx] = 1;
}
//Show Result
for( auto a : Array ){ std::cout << a << " "; }
std::cout << std::endl;
return 0;
}
Here is something you can do
function populateArray(arraySize, arrayElements) {
const newArray = [];
if (arraySize >= arrayElements) {
const parts = Math.ceil(arraySize / arrayElements);
for (let i = 0; i < arraySize; i++) {
if (i % parts == 0) {
newArray.push(1);
} else {
newArray.push(0);
}
}
return newArray;
}
return "Invalid array Size";
}
console.log(populateArray(10, 3));
Suppose I have an array of bytes from a secure PRNG, and I need to generate a number between 1 and 10 using that data, how would I do that correctly?
Think of the array as one big unsigned integer. Then the answer is simple:
(Big_Number % 10) + 1
So all that is needed is a method to find the modulus 10 of big integers. Using modular exponentiation:
#include <limits.h>
#include <stdlib.h>
int ArrayMod10(const unsigned char *a, size_t n) {
int mod10 = 0;
int base = (UCHAR_MAX + 1) % 10;
for (size_t i = n; i-- > 0; ) {
mod10 = (base*mod10 + a[i]) % 10;
base = (base * base) % 10;
}
return mod10;
}
void test10(size_t n) {
unsigned char a[n];
// fill array with your secure PRNG
for (size_t i = 0; i<n; i++) a[i] = rand();
return ArrayMod10(a, n) + 1;
}
There will be a slight bias as 256^n is not a power of 10. With large n, this will rapidly decrease in significance.
Untested code: Detect if a biased result occurred. Calling code could repeatedly call this function with new a array values to get an unbiased result on the rare occasions when bias occurs.
int ArrayMod10BiasDetect(const unsigned char *a, size_t n, bool *biasptr) {
bool bias = true;
int mod10 = 0;
int base = (UCHAR_MAX + 1) % 10; // Note base is usually 6: 256%10, 65536%10, etc.
for (size_t i = n; i-- > 0; ) {
mod10 = (base*mod10 + a[i]) % 10;
if (n > 0) {
if (a[i] < UCHAR_MAX) bias = false;
} else {
if (a[i] < UCHAR_MAX + 1 - base) bias = false;
}
base = (base * base) % 10;
}
*biaseptr = bias;
return mod10;
}
As per the comments follow-up, it seems what you need is modulus operator [%].
You may also need to check the related wiki.
Note: Every time we use the modulo operator on a random number, there is a probability that we'll be running into modulo bias, which ends up in disbalancing the fair distribution of random numbers. You've to take care of that.
For a detailed discussion on this, please see this question and related answers.
It depends on a bunch of things. Secure PRNG sometimes makes long byte arrays instead of integers, let's say it is 16 bytes long array, then extract 32 bit integer like so: buf[0]*0x1000000+buf[1]*0x10000+buf[2]*0x100+buf[3] or use shift operator. This is random so big-endian/little-endian doesn't matter.
char randbytes[16];
//...
const char *p = randbytes;
//assumes size of int is 4
unsigned int rand1 = p[0] << 24 + p[1] << 16 + p[2] << 8 + p[3]; p += 4;
unsigned int rand2 = p[0] << 24 + p[1] << 16 + p[2] << 8 + p[3]; p += 4;
unsigned int rand3 = p[0] << 24 + p[1] << 16 + p[2] << 8 + p[3]; p += 4;
unsigned int rand4 = p[0] << 24 + p[1] << 16 + p[2] << 8 + p[3];
Then use % on the integer
ps, I think that's a long answer. If you want number between 1 and 10 then just use % on first byte.
OK, so this answer is in Java until I get to my Eclipse C/C++ IDE:
public final static int simpleBound(Random rbg, int n) {
final int BYTE_VALUES = 256;
// sanity check, only return positive numbers
if (n <= 0) {
throw new IllegalArgumentException("Oops");
}
// sanity check: choice of value 0 or 0...
if (n == 1) {
return 0;
}
// sanity check: does not fit in byte
if (n > BYTE_VALUES) {
throw new IllegalArgumentException("Oops");
}
// optimization for n = 2^y
if (Integer.bitCount(n) == 1) {
final int mask = n - 1;
return retrieveRandomByte(rbg) & mask;
}
// you can skip to this if you are sure n = 10
// z is upper bound, and contains floor(z / n) blocks of n values
final int z = (BYTE_VALUES / n) * n;
int x;
do {
x = retrieveRandomByte(rbg);
} while (x >= z);
return x % n;
}
So n is the maximum value in a range [0..n), i.e. n is exclusive. For a range [1..10] simply increase the result with 1.
void invert( uint8_t array[],
unsigned int cols,
unsigned int rows )
{
int y;
uint8_t darkest = 255;
uint8_t lightest = 0;
uint8_t anygray = y;
for (int x = 0; x < (cols*rows); x++)
{
for (y = 0; y < (cols*rows); y++)
{
if (array[x] == darkest && array[x] == anygray && array[x] == lightest)
{
array[x] = 255-y;
}
}
}
}
I have a function here that inverts the image intensities, so that black becomes white, and vice versa as well as all the light grays become dark grays. But my code here doesn't seem to work and I don't know where i went wrong. Would anybody be able to help me out?
I haven't prototyped anything to check but I see at least two things that look suspicious.
1) I expected the && in the IF to be ||.
2) I expected array[x] = 255 - y to be something like array[x] = 255 - array[x].
So we're reading a matrix and saving it in an array sequentially. We read the matrix from a starting [x,y] point which is provided. Here's an example of some code I wrote to get the values of [x-1,y] [x+1,y] [x,y-1] [x,y+1], which is a cross.
for(i = 0, n = -1, m = 0, array_pos = 0; i < 4; i++, n++, array_pos++) {
if(x+n < filter_matrix.src.columns && x+n >= 0 )
if(y+m < filter_matrix.src.lines && y+m >= 0){
for(k = 0; k < numpixels; k++) {
arrayToProcess[array_pos].rgb[h] = filter_matrix.src.points[x+n][y+m].rgb[h];
}
}
m = n;
m++;
}
(The if's are meant to avoid reading null positions, since it's an image we're reading the origin pixel can be located in a corner. Not relevant to the issue here.)
Now is there a similar generic algorithm which can read ALL the elements around as a square (not just a cross) based on a single parameter, which is the size of the square's side squared?
If it helps, the only values we're dealing with are 9, 25 and 49 (a 3x3 5x5 and 7x7 square).
Here is a generalized code for reading the square centered at (x,y) of size n
int startx = x-n/2;
int starty = y-n/2;
for(int u=0;u<n;u++) {
for(int v=0;v<n;v++) {
int i = startx + u;
int j = starty + v;
if(i>=0 && j>=0 && i<N && j<M) {
printf(Matrix[i][j]);
}
}
}
Explanation: Start from top left value which is (x - n/2, y-n/2) now consider that you are read a normal square matrix from where i and j are indices of Matrix[i][j]. So we just added startx & starty to shift the matrix at (0,0) to (x-n/2,y-n/2).
Given:
static inline int min(int x, int y) { return (x < y) ? x : y; }
static inline int max(int x, int y) { return (x > y) ? x : y; }
or equivalent macros, and given that:
the x-coordinates range from 0 to x_max (inclusive),
the y-coordinates range from 0 to y_max (inclusive),
the centre of the square (x,y) is within the bounds,
the square you are creating has sides of (2 * size + 1) (so size is 1, 2, or 3 for the 3x3, 5x5, and 7x7 cases; or if you prefer to have sq_side = one of 3, 5, 7, then size = sq_side / 2),
the integer types are all signed (so x - size can produce a negative value; if they're unsigned, you will get the wrong result using the expressions shown),
then you can ensure that you are within bounds by setting:
x_lo = max(x - size, 0);
x_hi = min(x + size, x_max);
y_lo = max(y - size, 0);
y_hi = min(y + size, y_max);
for (x_pos = x_lo; x_pos <= x_hi; x_pos++)
{
for (y_pos = y_lo; y_pos <= y_hi; y_pos++)
{
// Process the data at array[x_pos][y_pos]
}
}
Basically, the initial assignments determine the bounds of the the array from [x-size][y-size] to [x+size][y+size], but bounded by 0 on the low side and the maximum sizes on the high end. Then scan over the relevant rectangular (usually square) sub-section of the matrix. Note that this determines the valid ranges once, outside the loops, rather than repeatedly within the loops.
If the integer types are signed, you have ensure you never try to create a negative number during subtraction. The expressions could be rewritten as:
x_lo = x - min(x, size);
x_hi = min(x + size, x_max);
y_lo = y - min(y, size);
y_hi = min(y + size, y_max);
which isn't as symmetric but only uses the min function.
Given the coordinates (x,y), you first need to find the surrounding elements. You can do that with a double for loop, like this:
for (int i = x-1; i <= x+1; i++) {
for (int j = y-1; j <= y+1; j++) {
int elem = square[i][j];
}
}
Now you just need to do a bit of work to make sure that 0 <= i,j < n, where n is the length of a side;
I don't know whether the (X,Y) in your code is the center of the square. I assume it is.
If the side of the square is odd. generate the coordinates of the points on the square. I assume the center is (0,0). Then the points on the squares are
(-side/2, [-side/2,side/2 - 1]); ([-side/2 + 1,side/2], -side/2); (side/2,[side/2 - 1,-side/2]);([side/2 - 1, side/2],-side/2);
side is the length of the square
make use of this:
while(int i<=0 && int j<=0)
for (i = x-1; i <= x+1; i++) {
for (j = y-1; j <= y+1; j++) {
int elem = square[i][j];
}
}
}
Because I'm masochistic I'm trying to write something in C to decode an 8-bit PNG file (it's a learning thing, I'm not trying to reinvent libpng...)
I've got to the point when the stuff in my deflated, unfiltered data buffer unmistakably resembles the source image (see below), but it's still quite, erm, wrong, and I'm pretty sure there's something askew with my implementation of the filtering algorithms. Most of them are quite simple, but there's one major thing I don't understand in the docs, not being good at maths or ever having taken a comp-sci course:
Unsigned arithmetic modulo 256 is used, so that both the inputs and outputs fit into bytes.
What does that mean?
If someone can tell me that I'd be very grateful!
For reference, (and I apologise for the crappy C) my noddy implementation of the filtering algorithms described in the docs look like:
unsigned char paeth_predictor (unsigned char a, unsigned char b, unsigned char c) {
// a = left, b = above, c = upper left
char p = a + b - c; // initial estimate
char pa = abs(p - a); // distances to a, b, c
char pb = abs(p - b);
char pc = abs(p - c);
// return nearest of a,b,c,
// breaking ties in order a,b,c.
if (pa <= pb && pa <= pc) return a;
else if (pb <= pc) return b;
else return c;
}
void unfilter_sub(char* out, char* in, int bpp, int row, int rowlen) {
for (int i = 0; i < rowlen; i++)
out[i] = in[i] + (i < bpp ? 0 : out[i-bpp]);
}
void unfilter_up(char* out, char* in, int bpp, int row, int rowlen) {
for (int i = 0; i < rowlen; i++)
out[i] = in[i] + (row == 0 ? 0 : out[i-rowlen]);
}
void unfilter_paeth(char* out, char* in, int bpp, int row, int rowlen) {
char a, b, c;
for (int i = 0; i < rowlen; i++) {
a = i < bpp ? 0 : out[i - bpp];
b = row < 1 ? 0 : out[i - rowlen];
c = i < bpp ? 0 : (row == 0 ? 0 : out[i - rowlen - bpp]);
out[i] = in[i] + paeth_predictor(a, b, c);
}
}
And the images I'm seeing:
Source
Source http://img220.imageshack.us/img220/8111/testdn.png
Output
Output http://img862.imageshack.us/img862/2963/helloworld.png
It means that, in the algorithm, whenever an arithmetic operation is performed, it is performed modulo 256, i.e. if the result is greater than 256 then it "wraps" around. The result is that all values will always fit into 8 bits and not overflow.
Unsigned types already behave this way by mandate, and if you use unsigned char (and a byte on your system is 8 bits, which it probably is), then your calculation results will naturally just never overflow beyond 8 bits.
It means only the last 8 bits of the result is used. 2^8=256, the last 8 bits of unsigned value v is the same as (v%256).
For example, 2+255=257, or 100000001, last 8 bits of 257 is 1, and 257%256 is also 1.
In 'simple language' it means that you never go "out" of your byte size.
For example in C# if you try this it will fail:
byte test = 255 + 255;
(1,13): error CS0031: Constant value '510' cannot be converted to a
'byte'
byte test = (byte)(255 + 255);
(1,13): error CS0221: Constant value '510' cannot be converted to a
'byte' (use 'unchecked' syntax to override)
For every calculation you have to do modulo 256 (C#: % 256).
Instead of writing % 256 you can also do AND 255:
(175 + 205) mod 256 = (175 + 205) AND 255
Some C# samples:
byte test = ((255 + 255) % 256);
// test: 254
byte test = ((255 + 255) & 255);
// test: 254
byte test = ((1 + 379) % 256);
// test: 124
byte test = ((1 + 379) & 0xFF);
// test: 124
Note that you sometimes can simplify a byte-series:
(byteVal1 + byteVal2 + byteVal3) % 256
= (((byteVal1 % 256) + (byteVal2 % 256)) % 256 + (byteVal3 % 256)) % 256