diff --git a/docs/bilinear_interpolation.md b/docs/bilinear_interpolation.md new file mode 100644 index 0000000..1717b92 --- /dev/null +++ b/docs/bilinear_interpolation.md @@ -0,0 +1,59 @@ +## Coding Bilinear Interpolation ## + +Source: [The Supercomputing Blog](http://supercomputingblog.com/graphics/coding-bilinear-interpolation/) + +When performing image transformation and manipulation techniques, it is often +necessary to employ some sort of interpolation or filtering in order to obtain +a good image quality. For example, if you scale an image, you can determine +the final color of each pixel by either some basic nearest neighbor method, or +a more advanced interpolation method. However, an interpolation method will +invariably offer better final image quality. In this tutorial, we’ll be +writing a function to rotate an image, using bilinear interpolation. This +tutorial also demonstrates how to perform a high quality image rotate +transformation, however, that is not the focus of this tutorial, but rather +the example transform being performed. + + +### Why interpolation is used after image transforms ### + +Image transforms like scaling, rotating, twisting or otherwise warping, +effectively move pixels around in the image. The result is that the pixels in +the final image do not directly map to a single original pixel in the original +image. Suppose after rotation, a pixel should have the same color as pixel +(3.4, 5.6) in the original image. The only problem is that there is no such +thing as fractional pixels! Instead of simply choosing the color of the +nearest available pixel, (3,6), we can get better results by intelligently +averaging the colors of the four closest pixels. In this case, the values of +pixels (3,5) (3,6) (4,5) and (4,6) would be intelligently averaged together to +estimate the color of an imaginary pixel at (3.4, 5.6). This is called +interpolation, and it is used after image transforms to provide a smooth, +accurate and visually appealing images. + + +### Understanding bilinear interpolation ### + +We can best understand bilinear interpolation by looking at the graphic here. +The green P dot represents the point where we want to estimate the color. The +four red Q dots represent the nearest pixels from the original image. The +color of these four Q pixels is known. In this example, P lies closest to Q12, +so it is only appropriate that the color of Q12 contributes more to the final +color of P than the 3 other Q pixels. + + +### Calculating bilinear interpolation ### + +There are several ways equivalent ways to calculate the value of P. An easy +way to calculate the value of P would be to first calculate the value of the +two blue dots, R2, and R1. R2 is effectively a weighted average of Q12 and +Q22, while R1 is a weighted average of Q11 and Q21. + +``` R1 = ((x2 – x)/(x2 – x1))*Q11 + ((x – x1)/(x2 – x1))*Q21 R2 = ((x2 – +x)/(x2 – x1))*Q12 + ((x – x1)/(x2 – x1))*Q22 ``` + +After the two R values are calculated, the value of P can finally be +calculated by a weighted average of R1 and R2. + +``` P = ((y2 – y)/(y2 – y1))*R1 + ((y – y1)/(y2 – y1))*R2 ``` + +The calculation will have to be repeated for the red, green, blue, and +optionally the alpha component of. diff --git a/docs/padding.txt b/docs/padding.txt new file mode 100644 index 0000000..361bc59 --- /dev/null +++ b/docs/padding.txt @@ -0,0 +1,16 @@ +https://stackoverflow.com/questions/11642210/computing-padding-required-for-n-byte-alignment + +There is a faster way to compute the padding, if the alignment is a power of two +(2,4,8,...). The following runs because binary & is similar to % for powers of +two: %(2^x) and &(2^x-1) do the same for positive numbers. Attention: & will +delete the sign bit and therefore always returns the positive modulo result. + +So (4 - (string_length & 3)) & 3 will do the same as +(4 - (string_length % 4)) % 4. Using the positive modulo property this can be +simplified to (-string_length) & 3! + + +If you wanna add that result to the size you can even do more optimizations: + +padded_length = (string_length + 3) & ~3 Semantically this 'rounds up' the +number to the padding size of 4. diff --git a/docs/srgb_linear.md b/docs/srgb_linear.md new file mode 100644 index 0000000..a190d89 --- /dev/null +++ b/docs/srgb_linear.md @@ -0,0 +1,72 @@ +## A close look at the sRGB formula ## + +[Source](https://blog.demofox.org/2018/03/10/dont-convert-srgb-u8-to-linear-u8/) +[Specific page](http://entropymine.com/imageworsener/srgbformula/) + +The formulas for converting sRGB colors to linear, and the reverse, are usually +given as follows: + +``` +sRGB to Linear + +Condition Value +0 ≤ S ≤ 0.04045 L = S/12.92 +0.04045 < S ≤ 1 L = ((S+0.055)/1.055)^2.4 +``` + +``` +Linear to sRGB + +Condition Value +0 ≤ L ≤ 0.0031308 S = L×12.92 +0.0031308 < L ≤ 1 S = 1.055×L^(1/2.4) − 0.055 +``` + +The definition uses two different functions – a straight line and an +exponential curve – glued together at a certain “cutoff point”. The implication +is that these functions (the ones in the sRGB to Linear definition) intersect +at the point: + +**(0.0404500000000000, 0.00313080000000000)** + +If we take a close look at the function, though, we can see this intersection +point is not exact, so the formula has a slight discontinuity: + +* sRGB: 0.0404500000000000 +* sRGB: 0.0404500000000001 +* Linear: 0.00313080495356037 +* Linera: 0.00313080728306769 + +If we extend the functions, we see that they actually intersect at two points: + +1. (0.0381547987133173, 0.00295315779514840) +2. (0.0404482362771082, 0.00313066844250063) + +If we use either of these two points as the cutoff point, there will be no +discontinuity at all. It’s apparent that the sRGB inventors selected the second +of these points, and rounded its value to 4 significant digits to get 0.04045. +They then used that rounded sRGB value to recalculate the Linear value, and got +0.00313080. I don’t know why their Linear value has more significant digits (5 +or 6) than their sRGB value (4). + +I guess that if you’re a perfectionist, and want no discontinuity at all, you +can tweak the formulas like this: + +``` +sRGB to Linear + +Condition Value +0 ≤ S ≤ 0.0404482362771082 L = S/12.92 +0.0404482362771082 < S ≤ 1 L = ((S+0.055)/1.055)^2.4 +``` + +``` +Linear to sRGB + +Condition Value +0 ≤ L ≤ 0.00313066844250063 S = L×12.92 +0.00313066844250063 < L ≤ 1 S = 1.055×L^(1/2.4) − 0.055 +``` + +It doesn’t make any practical difference. The two functions are extremely close +together in this region, so the precise cutoff point is almost irrelevant.