vfs: check userland buffers before reading them.
[haiku.git] / src / system / kernel / boot_splash.cpp
blob2ced62b1c0cb4ef61d05af0f5cfb2bf1f08fa4e4
1 /*
2 * Copyright 2008-2010, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Artur Wyszynski <harakash@gmail.com>
7 */
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <unistd.h>
15 #include <KernelExport.h>
17 #define __BOOTSPLASH_KERNEL__
18 #include <boot/images.h>
20 #include <boot_item.h>
21 #include <debug.h>
22 #include <frame_buffer_console.h>
24 #include <boot_splash.h>
27 //#define TRACE_BOOT_SPLASH 1
28 #ifdef TRACE_BOOT_SPLASH
29 # define TRACE(x...) dprintf(x);
30 #else
31 # define TRACE(x...) ;
32 #endif
35 static struct frame_buffer_boot_info *sInfo;
36 static uint8 *sUncompressedIcons;
39 static void
40 blit8_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop,
41 uint16 imageRight, uint16 imageBottom, uint16 imageWidth,
42 uint16 left, uint16 top)
44 data += (imageWidth * imageTop + imageLeft);
45 uint8* start = (uint8*)(sInfo->frame_buffer
46 + sInfo->bytes_per_row * (top + imageTop) + 1 * (left + imageLeft));
48 for (int32 y = imageTop; y < imageBottom; y++) {
49 const uint8* src = data;
50 uint8* dst = start;
51 for (int32 x = imageLeft; x < imageRight; x++) {
52 dst[0] = src[0];
53 dst++;
54 src++;
57 data += imageWidth;
58 start = (uint8*)((addr_t)start + sInfo->bytes_per_row);
63 static void
64 blit15_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop,
65 uint16 imageRight, uint16 imageBottom, uint16 imageWidth,
66 uint16 left, uint16 top)
68 data += (imageWidth * imageTop + imageLeft) * 3;
69 uint16* start = (uint16*)(sInfo->frame_buffer
70 + sInfo->bytes_per_row * (top + imageTop)
71 + 2 * (left + imageLeft));
73 for (int32 y = imageTop; y < imageBottom; y++) {
74 const uint8* src = data;
75 uint16* dst = start;
76 for (int32 x = imageLeft; x < imageRight; x++) {
77 dst[0] = ((src[2] >> 3) << 10)
78 | ((src[1] >> 3) << 5)
79 | ((src[0] >> 3));
81 dst++;
82 src += 3;
85 data += imageWidth * 3;
86 start = (uint16*)((addr_t)start + sInfo->bytes_per_row);
91 static void
92 blit16_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop,
93 uint16 imageRight, uint16 imageBottom, uint16 imageWidth,
94 uint16 left, uint16 top)
96 data += (imageWidth * imageTop + imageLeft) * 3;
97 uint16* start = (uint16*)(sInfo->frame_buffer
98 + sInfo->bytes_per_row * (top + imageTop) + 2 * (left + imageLeft));
100 for (int32 y = imageTop; y < imageBottom; y++) {
101 const uint8* src = data;
102 uint16* dst = start;
103 for (int32 x = imageLeft; x < imageRight; x++) {
104 dst[0] = ((src[2] >> 3) << 11)
105 | ((src[1] >> 2) << 5)
106 | ((src[0] >> 3));
108 dst++;
109 src += 3;
112 data += imageWidth * 3;
113 start = (uint16*)((addr_t)start + sInfo->bytes_per_row);
118 static void
119 blit24_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop,
120 uint16 imageRight, uint16 imageBottom, uint16 imageWidth,
121 uint16 left, uint16 top)
123 data += (imageWidth * imageTop + imageLeft) * 3;
124 uint8* start = (uint8*)(sInfo->frame_buffer
125 + sInfo->bytes_per_row * (top + imageTop) + 3 * (left + imageLeft));
127 for (int32 y = imageTop; y < imageBottom; y++) {
128 const uint8* src = data;
129 uint8* dst = start;
130 for (int32 x = imageLeft; x < imageRight; x++) {
131 dst[0] = src[0];
132 dst[1] = src[1];
133 dst[2] = src[2];
134 dst += 3;
135 src += 3;
138 data += imageWidth * 3;
139 start = (uint8*)((addr_t)start + sInfo->bytes_per_row);
144 static void
145 blit32_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop,
146 uint16 imageRight, uint16 imageBottom, uint16 imageWidth,
147 uint16 left, uint16 top)
149 data += (imageWidth * imageTop + imageLeft) * 3;
150 uint32* start = (uint32*)(sInfo->frame_buffer
151 + sInfo->bytes_per_row * (top + imageTop) + 4 * (left + imageLeft));
153 for (int32 y = imageTop; y < imageBottom; y++) {
154 const uint8* src = data;
155 uint32* dst = start;
156 for (int32 x = imageLeft; x < imageRight; x++) {
157 dst[0] = (src[2] << 16) | (src[1] << 8) | (src[0]);
158 dst++;
159 src += 3;
162 data += imageWidth * 3;
163 start = (uint32*)((addr_t)start + sInfo->bytes_per_row);
168 static void
169 blit_cropped(const uint8* data, uint16 imageLeft, uint16 imageTop,
170 uint16 imageRight, uint16 imageBottom, uint16 imageWidth,
171 uint16 left, uint16 top)
173 switch (sInfo->depth) {
174 case 8:
175 blit8_cropped(data, imageLeft, imageTop, imageRight, imageBottom,
176 imageWidth, left, top);
177 return;
178 case 15:
179 blit15_cropped(data, imageLeft, imageTop, imageRight, imageBottom,
180 imageWidth, left, top);
181 return;
182 case 16:
183 blit16_cropped(data, imageLeft, imageTop, imageRight, imageBottom,
184 imageWidth, left, top);
185 return;
186 case 24:
187 blit24_cropped(data, imageLeft, imageTop, imageRight, imageBottom,
188 imageWidth, left, top);
189 return;
190 case 32:
191 blit32_cropped(data, imageLeft, imageTop, imageRight, imageBottom,
192 imageWidth, left, top);
193 return;
198 // #pragma mark - exported functions
201 void
202 boot_splash_init(uint8 *bootSplash)
204 TRACE("boot_splash_init: enter\n");
206 if (debug_screen_output_enabled())
207 return;
209 sInfo = (frame_buffer_boot_info *)get_boot_item(FRAME_BUFFER_BOOT_INFO,
210 NULL);
212 sUncompressedIcons = bootSplash;
216 void
217 boot_splash_uninit(void)
219 sInfo = NULL;
223 void
224 boot_splash_set_stage(int stage)
226 TRACE("boot_splash_set_stage: stage=%d\n", stage);
228 if (sInfo == NULL || stage < 0 || stage >= BOOT_SPLASH_STAGE_MAX)
229 return;
231 int iconsHalfHeight = kSplashIconsHeight / 2;
232 int width = min_c(kSplashIconsWidth, sInfo->width);
233 int height = min_c(kSplashLogoHeight + iconsHalfHeight, sInfo->height);
234 int placementX = max_c(0, min_c(100, kSplashIconsPlacementX));
235 int placementY = max_c(0, min_c(100, kSplashIconsPlacementY));
237 int x = (sInfo->width - width) * placementX / 100;
238 int y = kSplashLogoHeight + (sInfo->height - height) * placementY / 100;
240 int stageLeftEdge = width * stage / BOOT_SPLASH_STAGE_MAX;
241 int stageRightEdge = width * (stage + 1) / BOOT_SPLASH_STAGE_MAX;
243 height = min_c(iconsHalfHeight, sInfo->height);
244 blit_cropped(sUncompressedIcons, stageLeftEdge, 0, stageRightEdge,
245 height, kSplashIconsWidth, x, y);