VirtualBox

source: vbox/trunk/src/VBox/Main/src-all/DisplayResampleImage.cpp

Last change on this file was 106061, checked in by vboxsync, 3 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.2 KB
Line 
1/* $Id: DisplayResampleImage.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * Image resampling code, used for snapshot thumbnails.
4 */
5
6/*
7 * Copyright (C) 2009-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#include <iprt/types.h>
29
30DECLINLINE(void) imageSetPixel (uint8_t *im, int x, int y, int color, int w)
31{
32 *(int32_t *)(im + y * w * 4 + x * 4) = color;
33}
34
35#define trueColorGetAlpha(c) (((c) & 0x7F000000) >> 24)
36#define trueColorGetRed(c) (((c) & 0xFF0000) >> 16)
37#define trueColorGetGreen(c) (((c) & 0x00FF00) >> 8)
38#define trueColorGetBlue(c) ((c) & 0x0000FF)
39
40/* Fast integer implementation for 32 bpp bitmap scaling.
41 * Using fixed point values * 16.
42 */
43typedef int32_t FIXEDPOINT;
44#define INT_TO_FIXEDPOINT(i) (FIXEDPOINT)((i) << 4)
45#define FIXEDPOINT_TO_INT(v) (int)((v) >> 4)
46#define FIXEDPOINT_FLOOR(v) ((v) & ~0xF)
47#define FIXEDPOINT_FRACTION(v) ((v) & 0xF)
48
49/* For 32 bit source only. */
50void BitmapScale32 (uint8_t *dst,
51 int dstW, int dstH,
52 const uint8_t *src,
53 int iDeltaLine,
54 int srcW, int srcH)
55{
56 int x, y;
57
58 for (y = 0; y < dstH; y++)
59 {
60 FIXEDPOINT sy1 = INT_TO_FIXEDPOINT(y * srcH) / dstH;
61 FIXEDPOINT sy2 = INT_TO_FIXEDPOINT((y + 1) * srcH) / dstH;
62
63 for (x = 0; x < dstW; x++)
64 {
65 FIXEDPOINT red = 0, green = 0, blue = 0;
66
67 FIXEDPOINT sx1 = INT_TO_FIXEDPOINT(x * srcW) / dstW;
68 FIXEDPOINT sx2 = INT_TO_FIXEDPOINT((x + 1) * srcW) / dstW;
69
70 FIXEDPOINT spixels = (sx2 - sx1) * (sy2 - sy1);
71
72 FIXEDPOINT sy = sy1;
73
74 do
75 {
76 FIXEDPOINT yportion;
77 if (FIXEDPOINT_FLOOR (sy) == FIXEDPOINT_FLOOR (sy1))
78 {
79 yportion = INT_TO_FIXEDPOINT(1) - FIXEDPOINT_FRACTION(sy);
80 if (yportion > sy2 - sy1)
81 {
82 yportion = sy2 - sy1;
83 }
84 sy = FIXEDPOINT_FLOOR (sy);
85 }
86 else if (sy == FIXEDPOINT_FLOOR (sy2))
87 {
88 yportion = FIXEDPOINT_FRACTION(sy2);
89 }
90 else
91 {
92 yportion = INT_TO_FIXEDPOINT(1);
93 }
94
95 const uint8_t *pu8SrcLine = src + iDeltaLine * FIXEDPOINT_TO_INT(sy);
96 FIXEDPOINT sx = sx1;
97 do
98 {
99 FIXEDPOINT xportion;
100 FIXEDPOINT pcontribution;
101 if (FIXEDPOINT_FLOOR (sx) == FIXEDPOINT_FLOOR (sx1))
102 {
103 xportion = INT_TO_FIXEDPOINT(1) - FIXEDPOINT_FRACTION(sx);
104 if (xportion > sx2 - sx1)
105 {
106 xportion = sx2 - sx1;
107 }
108 pcontribution = xportion * yportion;
109 sx = FIXEDPOINT_FLOOR (sx);
110 }
111 else if (sx == FIXEDPOINT_FLOOR (sx2))
112 {
113 xportion = FIXEDPOINT_FRACTION(sx2);
114 pcontribution = xportion * yportion;
115 }
116 else
117 {
118 xportion = INT_TO_FIXEDPOINT(1);
119 pcontribution = xportion * yportion;
120 }
121 /* Color depth specific code begin */
122 int32_t p = *(int32_t *)(pu8SrcLine + FIXEDPOINT_TO_INT(sx) * 4);
123 /* Color depth specific code end */
124 red += trueColorGetRed (p) * pcontribution;
125 green += trueColorGetGreen (p) * pcontribution;
126 blue += trueColorGetBlue (p) * pcontribution;
127
128 sx += INT_TO_FIXEDPOINT(1);
129 } while (sx < sx2);
130
131 sy += INT_TO_FIXEDPOINT(1);
132 } while (sy < sy2);
133
134 if (spixels != 0)
135 {
136 red /= spixels;
137 green /= spixels;
138 blue /= spixels;
139 }
140 /* Clamping to allow for rounding errors above */
141 if (red > 255)
142 {
143 red = 255;
144 }
145 if (green > 255)
146 {
147 green = 255;
148 }
149 if (blue > 255)
150 {
151 blue = 255;
152 }
153 imageSetPixel (dst,
154 x, y,
155 ( ((int) red) << 16) + (((int) green) << 8) + ((int) blue),
156 dstW);
157 }
158 }
159}
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