VirtualBox

source: vbox/trunk/src/VBox/Main/DisplayResampleImage.cpp@ 24865

Last change on this file since 24865 was 24373, checked in by vboxsync, 15 years ago

Updated screenshot API (xTracker 4364).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.7 KB
Line 
1/*
2 * Based on gdImageCopyResampled from libgd.
3 * Original copyright notice follow:
4
5 Portions copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
6 Pierre-Alain Joye ([email protected]).
7
8 Permission has been granted to copy, distribute and modify gd in
9 any context without fee, including a commercial application,
10 provided that this notice is present in user-accessible supporting
11 documentation.
12
13 This does not affect your ownership of the derived work itself, and
14 the intent is to assure proper credit for the authors of gd, not to
15 interfere with your productive use of gd. If you have questions,
16 ask. "Derived works" includes all programs that utilize the
17 library. Credit must be given in user-accessible documentation.
18
19 This software is provided "AS IS." The copyright holders disclaim
20 all warranties, either express or implied, including but not
21 limited to implied warranties of merchantability and fitness for a
22 particular purpose, with respect to this code and accompanying
23 documentation.
24 */
25
26/*
27 *
28 * @todo Simplify: Offsets of images are 0,0 => no dstX, dstY, srcX, srcY;
29 * Screenshot has no alpha channel => no processing of alpha byte.
30 */
31
32#include <iprt/types.h>
33
34/* 2.0.10: cast instead of floor() yields 35% performance improvement.
35 Thanks to John Buckman. */
36
37#define floor2(exp) ((long) exp)
38/*#define floor2(exp) floor(exp)*/
39
40typedef uint8_t *gdImagePtr;
41
42DECLINLINE(int) gdImageGetTrueColorPixel (gdImagePtr im, int x, int y, int w)
43{
44 return *(int32_t *)(im + y * w * 4 + x * 4);
45}
46
47DECLINLINE(void) gdImageSetPixel (gdImagePtr im, int x, int y, int color, int w)
48{
49 *(int32_t *)(im + y * w * 4 + x * 4) = color;
50}
51
52#define gdAlphaMax 127
53#define gdAlphaOpaque 0
54#define gdAlphaTransparent 127
55#define gdRedMax 255
56#define gdGreenMax 255
57#define gdBlueMax 255
58#define gdTrueColorGetAlpha(c) (((c) & 0x7F000000) >> 24)
59#define gdTrueColorGetRed(c) (((c) & 0xFF0000) >> 16)
60#define gdTrueColorGetGreen(c) (((c) & 0x00FF00) >> 8)
61#define gdTrueColorGetBlue(c) ((c) & 0x0000FF)
62#define gdTrueColorAlpha(r, g, b, a) (((a) << 24) + \
63 ((r) << 16) + \
64 ((g) << 8) + \
65 (b))
66
67void gdImageCopyResampled (uint8_t *dst,
68 uint8_t *src,
69 int dstX, int dstY,
70 int srcX, int srcY,
71 int dstW, int dstH, int srcW, int srcH)
72{
73 int x, y;
74 double sy1, sy2, sx1, sx2;
75 for (y = dstY; (y < dstY + dstH); y++)
76 {
77 sy1 = ((double) y - (double) dstY) * (double) srcH / (double) dstH;
78 sy2 = ((double) (y + 1) - (double) dstY) * (double) srcH /
79 (double) dstH;
80 for (x = dstX; (x < dstX + dstW); x++)
81 {
82 double sx, sy;
83 double spixels = 0;
84 double red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0;
85 sx1 = ((double) x - (double) dstX) * (double) srcW / dstW;
86 sx2 = ((double) (x + 1) - (double) dstX) * (double) srcW / dstW;
87 sy = sy1;
88 do
89 {
90 double yportion;
91 if (floor2 (sy) == floor2 (sy1))
92 {
93 yportion = 1.0 - (sy - floor2 (sy));
94 if (yportion > sy2 - sy1)
95 {
96 yportion = sy2 - sy1;
97 }
98 sy = floor2 (sy);
99 }
100 else if (sy == floor2 (sy2))
101 {
102 yportion = sy2 - floor2 (sy2);
103 }
104 else
105 {
106 yportion = 1.0;
107 }
108 sx = sx1;
109 do
110 {
111 double xportion;
112 double pcontribution;
113 int p;
114 if (floor2 (sx) == floor2 (sx1))
115 {
116 xportion = 1.0 - (sx - floor2 (sx));
117 if (xportion > sx2 - sx1)
118 {
119 xportion = sx2 - sx1;
120 }
121 sx = floor2 (sx);
122 }
123 else if (sx == floor2 (sx2))
124 {
125 xportion = sx2 - floor2 (sx2);
126 }
127 else
128 {
129 xportion = 1.0;
130 }
131 pcontribution = xportion * yportion;
132 /* 2.08: previously srcX and srcY were ignored.
133 Andrew Pattison */
134 p = gdImageGetTrueColorPixel (src,
135 (int) sx + srcX,
136 (int) sy + srcY, srcW);
137 red += gdTrueColorGetRed (p) * pcontribution;
138 green += gdTrueColorGetGreen (p) * pcontribution;
139 blue += gdTrueColorGetBlue (p) * pcontribution;
140 alpha += gdTrueColorGetAlpha (p) * pcontribution;
141 spixels += xportion * yportion;
142 sx += 1.0;
143 }
144 while (sx < sx2);
145 sy += 1.0;
146 }
147 while (sy < sy2);
148 if (spixels != 0.0)
149 {
150 red /= spixels;
151 green /= spixels;
152 blue /= spixels;
153 alpha /= spixels;
154 }
155 /* Clamping to allow for rounding errors above */
156 if (red > 255.0)
157 {
158 red = 255.0;
159 }
160 if (green > 255.0)
161 {
162 green = 255.0;
163 }
164 if (blue > 255.0)
165 {
166 blue = 255.0;
167 }
168 if (alpha > gdAlphaMax)
169 {
170 alpha = gdAlphaMax;
171 }
172 gdImageSetPixel (dst,
173 x, y,
174 gdTrueColorAlpha ((int) red,
175 (int) green,
176 (int) blue, (int) alpha), dstW);
177 }
178 }
179}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette