Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
L
libvncserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
rasky
libvncserver
Commits
88f1aa70
Commit
88f1aa70
authored
Jun 27, 2004
by
runge
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
x11vnc: speed up scaling a bit, add no blending option to -scale
parent
b512ce1b
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
199 additions
and
94 deletions
+199
-94
ChangeLog
x11vnc/ChangeLog
+4
-0
x11vnc.c
x11vnc/x11vnc.c
+195
-94
No files found.
x11vnc/ChangeLog
View file @
88f1aa70
2004-06-27 Karl Runge <runge@karlrunge.com>
* speed up scaling a bit for slow machines (still all floating point)
* add no blending option (-scale fraction:nb)
2004-06-26 Karl Runge <runge@karlrunge.com>
2004-06-26 Karl Runge <runge@karlrunge.com>
* add -scale fract for global (not per-client) server-side scaling
* add -scale fract for global (not per-client) server-side scaling
working more or less OK, needs to be optimized at some point.
working more or less OK, needs to be optimized at some point.
...
...
x11vnc/x11vnc.c
View file @
88f1aa70
...
@@ -193,6 +193,7 @@ int rfb_bytes_per_line;
...
@@ -193,6 +193,7 @@ int rfb_bytes_per_line;
/* scaling info */
/* scaling info */
int
scaling
=
0
;
int
scaling
=
0
;
int
scaling_noblend
=
0
;
double
scale_fac
=
1
.
0
;
double
scale_fac
=
1
.
0
;
int
scaled_x
=
0
,
scaled_y
=
0
;
int
scaled_x
=
0
,
scaled_y
=
0
;
...
@@ -3736,11 +3737,14 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
...
@@ -3736,11 +3737,14 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
main_blue_mask
=
fb
->
blue_mask
;
main_blue_mask
=
fb
->
blue_mask
;
if
(
scaling
)
{
if
(
scaling
)
{
width
=
(
int
)
(
width
*
scale_fac
);
double
eps
=
0
.
000001
;
height
=
(
int
)
(
height
*
scale_fac
);
width
=
(
int
)
(
width
*
scale_fac
+
eps
);
height
=
(
int
)
(
height
*
scale_fac
+
eps
);
scaled_x
=
width
;
scaled_x
=
width
;
scaled_y
=
height
;
scaled_y
=
height
;
rfb_bytes_per_line
=
(
main_bytes_per_line
/
fb
->
width
)
*
width
;
rfb_bytes_per_line
=
(
main_bytes_per_line
/
fb
->
width
)
*
width
;
rfbLog
(
"scaling screen: %dx%d -> %dx%d scale_fac=%.5f
\n
"
,
fb
->
width
,
fb
->
height
,
scaled_x
,
scaled_y
,
scale_fac
);
}
else
{
}
else
{
rfb_bytes_per_line
=
main_bytes_per_line
;
rfb_bytes_per_line
=
main_bytes_per_line
;
}
}
...
@@ -4643,18 +4647,17 @@ static void hint_updates(void) {
...
@@ -4643,18 +4647,17 @@ static void hint_updates(void) {
#define FLOOR(x) ( (double) ((int) (x)) )
#define FLOOR(x) ( (double) ((int) (x)) )
/*
/*
* Scaling
.
* Scaling
:
*
*
* For shrinking, a destination (scaled) pixel will correspond to more
* For shrinking, a destination (scaled) pixel will correspond to more
* than one source (i.e. main fb) pixel. Think of an x-y plane made
* than one source (i.e. main fb) pixel. Think of an x-y plane made with
* with graph paper. Each square in the graph paper (i.e. collection
* graph paper. Each unit square in the graph paper (i.e. collection of
* of points (x,y) such that N < x < N+1 and M < y < M+1, N and M
* points (x,y) such that N < x < N+1 and M < y < M+1, N and M integers)
* integers) corresponds to one pixel in the unscaled fb. There is a
* corresponds to one pixel in the unscaled fb. There is a solid
* solid color filling the inside such a square. A scaled pixel has
* color filling the inside of such a square. A scaled pixel has width
* width 1/scale_fac, e.g. for "-scale 3/4" the width of the scaled
* 1/scale_fac, e.g. for "-scale 3/4" the width of the scaled pixel
* pixel is 1.333. The area of this scaled pixel is 1.333 * 1.333
* is 1.333. The area of this scaled pixel is 1.333 * 1.333 (so it
* (so it obviously overlaps more than one source pixel, each which
* obviously overlaps more than one source pixel, each which have area 1).
* have area 1).
*
*
* We take the weight an unscaled pixel (source) contributes to a
* We take the weight an unscaled pixel (source) contributes to a
* scaled pixel (destination) as simply proportional to the overlap area
* scaled pixel (destination) as simply proportional to the overlap area
...
@@ -4662,65 +4665,103 @@ static void hint_updates(void) {
...
@@ -4662,65 +4665,103 @@ static void hint_updates(void) {
* pixel as an integral over the portion of the graph paper it covers.
* pixel as an integral over the portion of the graph paper it covers.
* The thing being integrated is the color value of the unscaled source.
* The thing being integrated is the color value of the unscaled source.
* That color value is constant over a graph paper square (source pixel),
* That color value is constant over a graph paper square (source pixel),
* and changes discontinuously from one square to the next.
* and changes discontinuously from one unit square to the next.
*
Here is an example for -scale 3/4, the solid lines are the source pixels
(graph paper unit squares), while the dotted lines denote the scaled
pixels (destination pixels):
0 1 4/3 2 8/3 3 4=12/3
|---------|--.------|------.--|---------|.
| | . | . | |.
| A | . B | . | |.
| | . | . | |.
| | . | . | |.
1 |---------|--.------|------.--|---------|.
4/3|.........|.........|.........|.........|.
| | . | . | |.
| C | . D | . | |.
| | . | . | |.
2 |---------|--.------|------.--|---------|.
| | . | . | |.
| | . | . | |.
8/3|.........|.........|.........|.........|.
| | . | . | |.
3 |---------|--.------|------.--|---------|.
So we see the first scaled pixel (0 < x < 4/3 and 0 < y < 4/3) mostly
overlaps with unscaled source pixel "A". The integration (averaging)
weights for this scaled pixel are:
A 1
B 1/3
C 1/3
D 1/9
*
*
* The Red, Green, and Blue color values must be averaged over separately
* The Red, Green, and Blue color values must be averaged over separately
* otherwise you can get a complete mess (except in solid regions).
* otherwise you can get a complete mess (except in solid regions),
* because high order bits are averaged differently from the low order bits.
*
*
* So the algorithm is roughly:
* So the algorithm is roughly:
*
*
* - Given as input a rectangle in the unscaled source fb with changes,
* - Given as input a rectangle in the unscaled source fb with changes,
* find the rectangle of pixels this affects in the scaled destination
* find the rectangle of pixels this affects in the scaled destination fb.
* fb.
*
*
* - For each of the affected scaled pixels, determine all of the
* - For each of the affected scaled
(dest)
pixels, determine all of the
* unscaled pixels it overlaps with.
* unscaled
(source)
pixels it overlaps with.
*
*
* - Average those unscaled values together, weighted by the area
* - Average those unscaled
source
values together, weighted by the area
* overlap with the destination pixel. Average R, G, B separately.
* overlap with the destination pixel. Average R, G, B separately.
*
*
* - Take this average value and convert to a valid pixel value if
* - Take this average value and convert to a valid pixel value if
* necessary (e.g. rounding, shifting), and then insert it into the
* necessary (e.g. rounding, shifting), and then insert it into the
* destination framebuffer as the pixel value.
* destination framebuffer as the pixel value.
*
*
* - On to the next destination pixel...
*
* ========================================================================
* ========================================================================
*
*
* For expanding
(which we don't think people will do very often... or
* For expanding
, e.g. -scale 1.1 (which we don't think people will do
*
at least so we hope, the framebuffer can become huge) the situation
*
very often... or at least so we hope, the framebuffer can become huge)
*
is reversed and the destination pixel is smaller than a "graph paper"
*
the situation is reversed and the destination pixel is smaller than a
*
square (source pixel). Some destination pixels will be completely
*
"graph paper" unit square (source pixel). Some destination pixels
* within a single unscaled source pixel.
* wi
ll be completely wi
thin a single unscaled source pixel.
*
*
* What we do here is a simple 4 point interpolation scheme:
* What we do here is a simple 4 point interpolation scheme:
*
*
* Let P00 be the source pixel closest to the destination pixel but with
* Let P00 be the source pixel closest to the destination pixel but with
* x and y values less than or equal to those of the destination pixel.
* x and y values less than or equal to those of the destination pixel.
* It is the source pixel immediately to the upper left of the destination
* (for simplicity, think of the upper left corner of a pixel defining the
* x,y location of the pixel, the center would work just as well). So it
* is the source pixel immediately to the upper left of the destination
* pixel. Let P10 be the source pixel one to the right of P00. Let P01
* pixel. Let P10 be the source pixel one to the right of P00. Let P01
* be one down from P00. And let P11 be one down and one to the right
* be one down from P00. And let P11 be one down and one to the right
* of P00. They form a 2x2 square we will interpolate inside of.
* of P00. They form a 2x2 square we will interpolate inside of.
*
*
* Let V00, V10, V01, and V11 be the color values of those 4 source
* Let V00, V10, V01, and V11 be the color values of those 4 source
* pixels. Let dx be the distance along x the destination pixel is from
* pixels. Let dx be the displacement along x the destination pixel is
* P00. Note: 0 <= dx < 1. Similarly let dy be the distance along y.
* from P00. Note: 0 <= dx < 1 by definition of P00. Similarly let
* The weighted average is:
* dy be the displacement along y. The weighted average for the
* interpolation is:
*
*
* Vave = V00 * (1 - dx) * (1 - dy)
* V
_
ave = V00 * (1 - dx) * (1 - dy)
* + V10 * dx * (1 - dy)
*
+ V10 * dx * (1 - dy)
* + V01 * (1 - dx) * dy
*
+ V01 * (1 - dx) * dy
* + V11 * dx * dy
*
+ V11 * dx * dy
*
*
* Note that the weights (1-dx)*(1-dy) + dx(1-dy) + (1-dx)*dy + dx*dy
* Note that the weights (1-dx)*(1-dy) + dx
*
(1-dy) + (1-dx)*dy + dx*dy
* automatically add up to 1. It is also nice that all the weights
* automatically add up to 1. It is also nice that all the weights
are
*
are positive. The above formula can be motivated by doing two 1D
*
positive (unsigned char stays unsigned char). The above formula can
* interpolations along x:
*
be motivated by doing two 1D
interpolations along x:
*
*
* VA = V00 * (1 - dx) + V10 * dx
* VA = V00 * (1 - dx) + V10 * dx
* VB = V01 * (1 - dx) + V11 * dx
* VB = V01 * (1 - dx) + V11 * dx
*
*
* and then interpolating VA and VB along y:
* and then interpolating VA and VB along y:
*
*
* Vave = VA * (1 - dy) + VB * dy
* V
_
ave = VA * (1 - dy) + VB * dy
*
*
* VA
* VA
* v |<-dx->|
* v |<-dx->|
...
@@ -4729,15 +4770,20 @@ static void hint_updates(void) {
...
@@ -4729,15 +4770,20 @@ static void hint_updates(void) {
* -- | o...|... "o" denotes the position of the desired
* -- | o...|... "o" denotes the position of the desired
* ^ | . | . destination pixel relative to the P00
* ^ | . | . destination pixel relative to the P00
* | . | . source pixel.
* | . | . source pixel.
* V10 ----
-
- V11 .
* V10 ----
.
- V11 .
* ........
* ........
* |
* VB
* VB
*
*
*
*
* Of course R, G, B averages are done separately. This gives reasonable
* Of course R, G, B averages are done separately as in the shrinking
* results. I believe this is called bilinear scaling.
* case. This gives reasonable results, and the implementation for
* shrinking can simply be used with different choices for weights for
* the loop over the 4 pixels.
*/
*/
#define FPTYPE double
static
void
scale_and_mark_rect
(
int
X1
,
int
Y1
,
int
X2
,
int
Y2
)
{
static
void
scale_and_mark_rect
(
int
X1
,
int
Y1
,
int
X2
,
int
Y2
)
{
/*
/*
* Notation:
* Notation:
...
@@ -4753,23 +4799,22 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
...
@@ -4753,23 +4799,22 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
int
i
,
j
,
i1
,
i2
,
j1
,
j2
;
/* indices for scaled fb (dest) */
int
i
,
j
,
i1
,
i2
,
j1
,
j2
;
/* indices for scaled fb (dest) */
int
I
,
J
,
I1
,
I2
,
J1
,
J2
;
/* indices for main fb (source) */
int
I
,
J
,
I1
,
I2
,
J1
,
J2
;
/* indices for main fb (source) */
double
w
,
wx
,
wy
,
wtot
;
/* pixel weights */
FPTYPE
w
,
wx
,
wy
,
wtot
;
/* pixel weights */
double
x1
,
y1
,
x2
,
y2
;
/* x-y coords for destination pixels edges */
FPTYPE
x1
,
y1
,
x2
,
y2
;
/* x-y coords for destination pixels edges */
double
dx
,
dy
;
/* size of destination pixel */
FPTYPE
dx
,
dy
;
/* size of destination pixel */
double
ddx
,
ddy
;
/* for interpolation expansion */
FPTYPE
ddx
,
ddy
;
/* for interpolation expansion */
char
*
src
,
*
dest
;
/* pointers to the two framebuffers */
char
*
src
,
*
dest
;
/* pointers to the two framebuffers */
double
pixave
[
4
];
/* for averaging pixel values */
FPTYPE
pixave
[
4
];
/* for averaging pixel values */
unsigned
char
uc
;
/* tmp pixel data holders */
unsigned
short
us
;
unsigned
short
us
;
int
shrink
;
/* whether shrinking or expanding */
int
shrink
;
/* whether shrinking or expanding */
static
int
constant_weights
=
-
1
;
int
pseudocolor
=
0
;
/* true if PseudoColor... */
if
(
scale_fac
<=
1
.
0
)
{
if
(
scale_fac
<=
1
.
0
)
{
shrink
=
1
;
shrink
=
1
;
}
else
{
}
else
{
...
@@ -4777,7 +4822,10 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
...
@@ -4777,7 +4822,10 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
}
}
if
(
!
screen
->
rfbServerFormat
.
trueColour
)
{
if
(
!
screen
->
rfbServerFormat
.
trueColour
)
{
pseudocolor
=
1
;
/*
* PseudoColor colormap... blending leads to random colors.
*/
scaling_noblend
=
1
;
}
}
Bpp
=
bpp
/
8
;
/* Bytes per pixel */
Bpp
=
bpp
/
8
;
/* Bytes per pixel */
...
@@ -4793,8 +4841,8 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
...
@@ -4793,8 +4841,8 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
* both are > 1 (e.g. 1.333 for -scale 3/4)
* both are > 1 (e.g. 1.333 for -scale 3/4)
* they should also be equal but we don't assume it.
* they should also be equal but we don't assume it.
*/
*/
dx
=
(
double
)
Nx
/
nx
;
dx
=
(
FPTYPE
)
Nx
/
nx
;
dy
=
(
double
)
Ny
/
ny
;
dy
=
(
FPTYPE
)
Ny
/
ny
;
/*
/*
* find the extent of the change the input rectangle induces in
* find the extent of the change the input rectangle induces in
...
@@ -4807,11 +4855,11 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
...
@@ -4807,11 +4855,11 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
/* Right edges: find smallest i such that (i+1) * dx >= X2+1 */
/* Right edges: find smallest i such that (i+1) * dx >= X2+1 */
i2
=
CEIL
(
(
X2
+
1
)
/
dx
)
-
1
;
i2
=
CEIL
(
(
X2
+
1
)
/
dx
)
-
1
;
/*
t
o be safe, correct any overflows: */
/*
T
o be safe, correct any overflows: */
i1
=
nfix
(
i1
,
nx
);
i1
=
nfix
(
i1
,
nx
);
i2
=
nfix
(
i2
,
nx
)
+
1
;
/* add 1 to make a rectangle upper boundary */
i2
=
nfix
(
i2
,
nx
)
+
1
;
/* add 1 to make a rectangle upper boundary */
/*
r
epeat above for y direction: */
/*
R
epeat above for y direction: */
j1
=
FLOOR
(
Y1
/
dy
);
j1
=
FLOOR
(
Y1
/
dy
);
j2
=
CEIL
(
(
Y2
+
1
)
/
dy
)
-
1
;
j2
=
CEIL
(
(
Y2
+
1
)
/
dy
)
-
1
;
...
@@ -4819,21 +4867,55 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
...
@@ -4819,21 +4867,55 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
j2
=
nfix
(
j2
,
ny
)
+
1
;
j2
=
nfix
(
j2
,
ny
)
+
1
;
/*
/*
* loop over destination pixels in scaled fb:
* There is some speedup if the pixel weights are constant, so
* let's special case these.
*
* If scale = 1/n and n divides Nx and Ny, the pixel weights
* are constant.
*/
if
(
constant_weights
<
0
)
{
int
n
=
0
;
constant_weights
=
0
;
for
(
i
=
2
;
i
<=
128
;
i
++
)
{
double
test
=
((
double
)
1
)
/
i
;
double
diff
,
eps
=
1.0e-9
;
diff
=
scale_fac
-
test
;
if
(
-
eps
<
diff
&&
diff
<
eps
)
{
n
=
i
;
break
;
}
}
if
(
n
!=
0
)
{
if
(
!
scaling_noblend
&&
Nx
%
n
==
0
&&
Ny
%
n
==
0
)
{
rfbLog
(
"scale_and_mark_rect: using constant "
"pixel weight speedup for 1/%d
\n
"
,
n
);
constant_weights
=
1
;
}
}
}
/* set these all to 1.0 to begin with */
wx
=
1
.
0
;
wy
=
1
.
0
;
w
=
1
.
0
;
/*
* Loop over destination pixels in scaled fb:
*/
*/
for
(
j
=
j1
;
j
<
j2
;
j
++
)
{
for
(
j
=
j1
;
j
<
j2
;
j
++
)
{
y1
=
j
*
dy
;
/* top edge */
y1
=
j
*
dy
;
/* top edge */
y2
=
y1
+
dy
;
/* bottom edge */
y2
=
y1
+
dy
;
/* bottom edge */
/*
f
ind main fb indices covered by this dest pixel: */
/*
F
ind main fb indices covered by this dest pixel: */
J1
=
(
int
)
FLOOR
(
y1
);
J1
=
(
int
)
FLOOR
(
y1
);
J2
=
(
int
)
CEIL
(
y2
)
-
1
;
J1
=
nfix
(
J1
,
Ny
);
J1
=
nfix
(
J1
,
Ny
);
J2
=
nfix
(
J2
,
Ny
);
if
(
!
shrink
)
{
if
(
shrink
)
{
J2
=
(
int
)
CEIL
(
y2
)
-
1
;
J2
=
nfix
(
J2
,
Ny
);
}
else
{
J2
=
J1
+
1
;
/* simple interpolation */
J2
=
J1
+
1
;
/* simple interpolation */
ddy
=
y1
-
J1
;
}
}
/* destination char* pointer: */
/* destination char* pointer: */
...
@@ -4843,41 +4925,45 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
...
@@ -4843,41 +4925,45 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
x1
=
i
*
dx
;
/* left edge */
x1
=
i
*
dx
;
/* left edge */
x2
=
x1
+
dx
;
/* right edge */
x2
=
x1
+
dx
;
/* right edge */
/*
f
ind main fb indices covered by this dest pixel: */
/*
F
ind main fb indices covered by this dest pixel: */
I1
=
(
int
)
FLOOR
(
x1
);
I1
=
(
int
)
FLOOR
(
x1
);
I2
=
(
int
)
CEIL
(
x2
)
-
1
;
if
(
I1
>=
Nx
)
I1
=
Nx
-
1
;
I1
=
nfix
(
I1
,
Nx
);
I2
=
nfix
(
I2
,
Nx
);
if
(
!
shrink
)
{
if
(
shrink
)
{
I2
=
(
int
)
CEIL
(
x2
)
-
1
;
if
(
I2
>=
Nx
)
I2
=
Nx
-
1
;
}
else
{
I2
=
I1
+
1
;
/* simple interpolation */
I2
=
I1
+
1
;
/* simple interpolation */
ddx
=
x1
-
I1
;
}
}
/*
z
ero out accumulators for next pixel average: */
/*
Z
ero out accumulators for next pixel average: */
for
(
b
=
0
;
b
<
4
;
b
++
)
{
for
(
b
=
0
;
b
<
4
;
b
++
)
{
pixave
[
b
]
=
0
.
0
;
/* for RGB weighted sums */
pixave
[
b
]
=
0
.
0
;
/* for RGB weighted sums */
}
}
/*
/*
* wtot is for accumulating the total weight.
* wtot is for accumulating the total weight.
* It should always be 1/(scale_fac * scale_fac),
* It should always sum to 1/(scale_fac * scale_fac).
* but we don't assume that.
*/
*/
wtot
=
0
.
0
;
wtot
=
0
.
0
;
if
(
!
shrink
)
{
/* interpolation distances, see diagram above */
ddx
=
x1
-
I1
;
ddy
=
y1
-
J1
;
}
/*
/*
* loop over source pixels covered by this dest pixel:
* Loop over source pixels covered by this dest pixel.
*
* These "extra" loops over "J" and "I" make
* the cache/cacheline performance unclear.
* For example, will the data brought in from
* src for j, i, and J=0 still be in the cache
* after the J > 0 data have been accessed and
* we are at j, i+1, J=0? The stride in J is
* main_bytes_per_line, and so ~4 KB.
*/
*/
for
(
J
=
J1
;
J
<=
J2
;
J
++
)
{
for
(
J
=
J1
;
J
<=
J2
;
J
++
)
{
/* see comments for I, x1, x2, etc. below */
/* see comments for I, x1, x2, etc. below */
if
(
pseudocolor
)
{
if
(
constant_weights
)
{
;
}
else
if
(
scaling_noblend
)
{
if
(
J
!=
J1
)
{
if
(
J
!=
J1
)
{
continue
;
continue
;
}
}
...
@@ -4886,7 +4972,7 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
...
@@ -4886,7 +4972,7 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
/* interpolation scheme: */
/* interpolation scheme: */
}
else
if
(
!
shrink
)
{
}
else
if
(
!
shrink
)
{
if
(
J
>=
Ny
)
{
if
(
J
>=
Ny
)
{
continue
;
/* off edge */
continue
;
}
else
if
(
J
==
J1
)
{
}
else
if
(
J
==
J1
)
{
wy
=
1
.
0
-
ddy
;
wy
=
1
.
0
-
ddy
;
}
else
if
(
J
!=
J1
)
{
}
else
if
(
J
!=
J1
)
{
...
@@ -4908,11 +4994,15 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
...
@@ -4908,11 +4994,15 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
/* Work out the weight: */
/* Work out the weight: */
if
(
pseudocolor
)
{
if
(
constant_weights
)
{
;
}
else
if
(
scaling_noblend
)
{
/*
/*
* ugh, colormap is bad news, to
* Ugh, PseudoColor colormap is
* avoid random colors just take
* bad news, to avoid random
* the first pixel.
* colors just take the first
* pixel. Or user may have
* specified :nb to fraction.
*/
*/
if
(
I
!=
I1
)
{
if
(
I
!=
I1
)
{
continue
;
continue
;
...
@@ -4958,22 +5048,22 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
...
@@ -4958,22 +5048,22 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
/*
/*
*
w
e average the unsigned char value
*
W
e average the unsigned char value
* instead of char value: otherwise
* instead of char value: otherwise
* the minimum (char 0) is right next
* the minimum (char 0) is right next
* to the maximum (char -1)! This way
* to the maximum (char -1)! This way
* they are spread between 0 and 255.
* they are spread between 0 and 255.
*/
*/
if
(
Bpp
==
4
||
Bpp
==
1
)
{
if
(
Bpp
!=
2
)
{
for
(
b
=
0
;
b
<
Bpp
;
b
++
)
{
for
(
b
=
0
;
b
<
Bpp
;
b
++
)
{
uc
=
(
unsigned
char
)
*
(
src
+
b
);
pixave
[
b
]
+=
w
*
pixave
[
b
]
+=
w
*
uc
;
((
unsigned
char
)
*
(
src
+
b
))
;
}
}
}
else
if
(
Bpp
==
2
)
{
}
else
{
/*
/*
* trickier with green split over
* 16bpp: trickier with green
* two bytes, so we use the masks:
* split over two bytes, so we
* use the masks:
*/
*/
us
=
*
(
(
unsigned
short
*
)
src
);
us
=
*
(
(
unsigned
short
*
)
src
);
pixave
[
0
]
+=
w
*
(
us
&
main_red_mask
);
pixave
[
0
]
+=
w
*
(
us
&
main_red_mask
);
...
@@ -4987,12 +5077,12 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
...
@@ -4987,12 +5077,12 @@ static void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
wtot
=
1
.
0
/
wtot
;
/* normalization factor */
wtot
=
1
.
0
/
wtot
;
/* normalization factor */
/* place weighted average pixel in the scaled fb: */
/* place weighted average pixel in the scaled fb: */
if
(
Bpp
==
4
||
Bpp
==
1
)
{
if
(
Bpp
!=
2
)
{
for
(
b
=
0
;
b
<
Bpp
;
b
++
)
{
for
(
b
=
0
;
b
<
Bpp
;
b
++
)
{
*
(
dest
+
b
)
=
(
char
)
(
wtot
*
pixave
[
b
]);
*
(
dest
+
b
)
=
(
char
)
(
wtot
*
pixave
[
b
]);
}
}
}
else
if
(
Bpp
==
2
)
{
}
else
{
/* 16bpp
/565
*/
/* 16bpp
/ 565 case:
*/
pixave
[
0
]
*=
wtot
;
pixave
[
0
]
*=
wtot
;
pixave
[
1
]
*=
wtot
;
pixave
[
1
]
*=
wtot
;
pixave
[
2
]
*=
wtot
;
pixave
[
2
]
*=
wtot
;
...
@@ -6523,7 +6613,9 @@ static void print_help(void) {
...
@@ -6523,7 +6613,9 @@ static void print_help(void) {
" and response may be slower. If
\"
fraction
\"
contains
\n
"
" and response may be slower. If
\"
fraction
\"
contains
\n
"
" a decimal point
\"
.
\"
it is taken as a floating point
\n
"
" a decimal point
\"
.
\"
it is taken as a floating point
\n
"
" number, alternatively the notation
\"
m/n
\"
may be used
\n
"
" number, alternatively the notation
\"
m/n
\"
may be used
\n
"
" to denote fractions, e.g. -scale 2/3
\n
"
" to denote fractions, e.g. -scale 2/3. If you just want
\n
"
" a quick, rough scaling without blending, append
\"
:nb
\"\n
"
" to
\"
fraction
\"
(e.g. -scale 1/3:nb)
\n
"
"-visual n Experimental option: probably does not do what you
\n
"
"-visual n Experimental option: probably does not do what you
\n
"
" think. It simply *forces* the visual used for the
\n
"
" think. It simply *forces* the visual used for the
\n
"
" framebuffer; this may be a bad thing... It is useful for
\n
"
" framebuffer; this may be a bad thing... It is useful for
\n
"
...
@@ -7010,8 +7102,17 @@ int main(int argc, char* argv[]) {
...
@@ -7010,8 +7102,17 @@ int main(int argc, char* argv[]) {
}
}
}
else
if
(
!
strcmp
(
arg
,
"-scale"
))
{
}
else
if
(
!
strcmp
(
arg
,
"-scale"
))
{
int
m
,
n
;
int
m
,
n
;
char
*
p
;
float
f
;
float
f
;
if
(
strchr
(
argv
[
++
i
],
'.'
)
!=
NULL
)
{
i
++
;
if
(
(
p
=
strchr
(
argv
[
i
],
':'
))
!=
NULL
)
{
/* options */
if
(
strstr
(
p
+
1
,
"nb"
)
!=
NULL
)
{
scaling_noblend
=
1
;
}
*
p
=
'\0'
;
}
if
(
strchr
(
argv
[
i
],
'.'
)
!=
NULL
)
{
if
(
sscanf
(
argv
[
i
],
"%f"
,
&
f
)
!=
1
)
{
if
(
sscanf
(
argv
[
i
],
"%f"
,
&
f
)
!=
1
)
{
fprintf
(
stderr
,
"bad -scale arg: %s
\n
"
,
fprintf
(
stderr
,
"bad -scale arg: %s
\n
"
,
argv
[
i
]);
argv
[
i
]);
...
@@ -7024,7 +7125,7 @@ int main(int argc, char* argv[]) {
...
@@ -7024,7 +7125,7 @@ int main(int argc, char* argv[]) {
argv
[
i
]);
argv
[
i
]);
exit
(
1
);
exit
(
1
);
}
}
scale_fac
=
(
double
)
m
/
n
;
scale_fac
=
(
(
double
)
m
)
/
n
;
}
}
if
(
scale_fac
==
1
.
0
)
{
if
(
scale_fac
==
1
.
0
)
{
fprintf
(
stderr
,
"scaling disabled for factor "
fprintf
(
stderr
,
"scaling disabled for factor "
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment