]>
Commit | Line | Data |
---|---|---|
50361660 VS |
1 | /* |
2 | * GRUB -- GRand Unified Bootloader | |
3 | * Copyright (C) 2013 Free Software Foundation, Inc. | |
4 | * | |
5 | * GRUB is free software: you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License as published by | |
7 | * the Free Software Foundation, either version 3 of the License, or | |
8 | * (at your option) any later version. | |
9 | * | |
10 | * GRUB is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with GRUB. If not, see <http://www.gnu.org/licenses/>. | |
17 | */ | |
18 | ||
19 | /* All tests need to include test.h for GRUB testing framework. */ | |
25ac643a VS |
20 | |
21 | #include <config.h> | |
22 | ||
50361660 VS |
23 | #include <grub/test.h> |
24 | #include <grub/dl.h> | |
25 | #include <grub/video.h> | |
26 | #include <grub/lib/crc.h> | |
27 | #include <grub/mm.h> | |
0e7b2e32 | 28 | #include <grub/term.h> |
25ac643a VS |
29 | #ifdef GRUB_MACHINE_EMU |
30 | #include <grub/emu/hostdisk.h> | |
31 | #include <grub/emu/misc.h> | |
32 | #endif | |
50361660 VS |
33 | |
34 | GRUB_MOD_LICENSE ("GPLv3+"); | |
35 | ||
36 | static int ctr; | |
37 | static int nchk; | |
38 | static char *basename; | |
39 | static const grub_uint32_t *checksums; | |
40 | static struct grub_video_mode_info capt_mode_info; | |
41 | ||
79054c1d | 42 | struct grub_video_mode_info grub_test_video_modes[GRUB_TEST_VIDEO_ALL_N_MODES] = { |
c104b6f9 VS |
43 | { |
44 | .width = 640, | |
45 | .height = 480, | |
46 | .pitch = 640, | |
47 | .mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, | |
48 | .bpp = 8, | |
49 | .bytes_per_pixel = 1, | |
50 | .number_of_colors = GRUB_VIDEO_FBSTD_NUMCOLORS | |
51 | }, | |
52 | { | |
53 | .width = 800, | |
54 | .height = 600, | |
55 | .pitch = 800, | |
56 | .mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, | |
57 | .bpp = 8, | |
58 | .bytes_per_pixel = 1, | |
59 | .number_of_colors = GRUB_VIDEO_FBSTD_NUMCOLORS | |
60 | }, | |
61 | { | |
62 | .width = 1024, | |
63 | .height = 768, | |
64 | .pitch = 1024, | |
65 | .mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, | |
66 | .bpp = 8, | |
67 | .bytes_per_pixel = 1, | |
68 | .number_of_colors = GRUB_VIDEO_FBSTD_NUMCOLORS | |
69 | }, | |
b7c036bc VS |
70 | { |
71 | .width = 640, | |
72 | .height = 480, | |
73 | .pitch = 640 * 4, | |
74 | GRUB_VIDEO_MI_RGBA8888() | |
75 | }, | |
76 | { | |
77 | .width = 800, | |
78 | .height = 600, | |
79 | .pitch = 800 * 4, | |
80 | GRUB_VIDEO_MI_RGBA8888() | |
81 | }, | |
82 | { | |
83 | .width = 1024, | |
84 | .height = 768, | |
85 | .pitch = 1024 * 4, | |
86 | GRUB_VIDEO_MI_RGBA8888() | |
87 | }, | |
79054c1d VS |
88 | { |
89 | .width = 2560, | |
90 | .height = 1440, | |
91 | .pitch = 2560 * 4, | |
92 | GRUB_VIDEO_MI_RGBA8888() | |
93 | }, | |
c104b6f9 VS |
94 | { |
95 | .width = 640, | |
96 | .height = 480, | |
97 | .pitch = 640, | |
98 | .mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, | |
99 | .bpp = 8, | |
100 | .bytes_per_pixel = 1, | |
101 | .number_of_colors = GRUB_VIDEO_FBSTD_EXT_NUMCOLORS | |
102 | }, | |
103 | { | |
104 | .width = 800, | |
105 | .height = 600, | |
106 | .pitch = 800, | |
107 | .mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, | |
108 | .bpp = 8, | |
109 | .bytes_per_pixel = 1, | |
110 | .number_of_colors = GRUB_VIDEO_FBSTD_EXT_NUMCOLORS | |
111 | }, | |
112 | { | |
113 | .width = 1024, | |
114 | .height = 768, | |
115 | .pitch = 1024, | |
116 | .mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, | |
117 | .bpp = 8, | |
118 | .bytes_per_pixel = 1, | |
119 | .number_of_colors = GRUB_VIDEO_FBSTD_EXT_NUMCOLORS | |
120 | }, | |
b7c036bc VS |
121 | |
122 | ||
123 | ||
124 | ||
c104b6f9 VS |
125 | { |
126 | .width = 640, | |
127 | .height = 480, | |
128 | .pitch = 1280, | |
129 | GRUB_VIDEO_MI_RGB555 () | |
130 | }, | |
131 | { | |
132 | .width = 800, | |
133 | .height = 600, | |
134 | .pitch = 1600, | |
135 | GRUB_VIDEO_MI_RGB555 () | |
136 | }, | |
137 | { | |
138 | .width = 1024, | |
139 | .height = 768, | |
140 | .pitch = 2048, | |
141 | GRUB_VIDEO_MI_RGB555 () | |
142 | }, | |
143 | { | |
144 | .width = 640, | |
145 | .height = 480, | |
146 | .pitch = 1280, | |
147 | GRUB_VIDEO_MI_RGB565 () | |
148 | }, | |
149 | { | |
150 | .width = 800, | |
151 | .height = 600, | |
152 | .pitch = 1600, | |
153 | GRUB_VIDEO_MI_RGB565 () | |
154 | }, | |
155 | { | |
156 | .width = 1024, | |
157 | .height = 768, | |
158 | .pitch = 2048, | |
159 | GRUB_VIDEO_MI_RGB565 () | |
160 | }, | |
161 | { | |
162 | .width = 640, | |
163 | .height = 480, | |
164 | .pitch = 640 * 3, | |
165 | GRUB_VIDEO_MI_RGB888 () | |
166 | }, | |
167 | { | |
168 | .width = 800, | |
169 | .height = 600, | |
170 | .pitch = 800 * 3, | |
171 | GRUB_VIDEO_MI_RGB888 () | |
172 | }, | |
173 | { | |
174 | .width = 1024, | |
175 | .height = 768, | |
176 | .pitch = 1024 * 3, | |
177 | GRUB_VIDEO_MI_RGB888 () | |
178 | }, | |
c104b6f9 VS |
179 | { |
180 | .width = 640, | |
181 | .height = 480, | |
182 | .pitch = 1280, | |
183 | GRUB_VIDEO_MI_BGR555 () | |
184 | }, | |
185 | { | |
186 | .width = 800, | |
187 | .height = 600, | |
188 | .pitch = 1600, | |
189 | GRUB_VIDEO_MI_BGR555 () | |
190 | }, | |
191 | { | |
192 | .width = 1024, | |
193 | .height = 768, | |
194 | .pitch = 2048, | |
195 | GRUB_VIDEO_MI_BGR555 () | |
196 | }, | |
197 | { | |
198 | .width = 640, | |
199 | .height = 480, | |
200 | .pitch = 1280, | |
201 | GRUB_VIDEO_MI_BGR565 () | |
202 | }, | |
203 | { | |
204 | .width = 800, | |
205 | .height = 600, | |
206 | .pitch = 1600, | |
207 | GRUB_VIDEO_MI_BGR565 () | |
208 | }, | |
209 | { | |
210 | .width = 1024, | |
211 | .height = 768, | |
212 | .pitch = 2048, | |
213 | GRUB_VIDEO_MI_BGR565 () | |
214 | }, | |
215 | { | |
216 | .width = 640, | |
217 | .height = 480, | |
218 | .pitch = 640 * 3, | |
219 | GRUB_VIDEO_MI_BGR888 () | |
220 | }, | |
221 | { | |
222 | .width = 800, | |
223 | .height = 600, | |
224 | .pitch = 800 * 3, | |
225 | GRUB_VIDEO_MI_BGR888 () | |
226 | }, | |
227 | { | |
228 | .width = 1024, | |
229 | .height = 768, | |
230 | .pitch = 1024 * 3, | |
231 | GRUB_VIDEO_MI_BGR888 () | |
232 | }, | |
233 | { | |
234 | .width = 640, | |
235 | .height = 480, | |
236 | .pitch = 640 * 4, | |
237 | GRUB_VIDEO_MI_BGRA8888() | |
238 | }, | |
239 | { | |
240 | .width = 800, | |
241 | .height = 600, | |
242 | .pitch = 800 * 4, | |
243 | GRUB_VIDEO_MI_BGRA8888() | |
244 | }, | |
245 | { | |
246 | .width = 1024, | |
247 | .height = 768, | |
248 | .pitch = 1024 * 4, | |
249 | GRUB_VIDEO_MI_BGRA8888() | |
250 | }, | |
251 | }; | |
252 | ||
50361660 | 253 | #ifdef GRUB_MACHINE_EMU |
f4e0adc0 | 254 | #include <grub/emu/hostfile.h> |
50361660 VS |
255 | |
256 | struct bmp_header | |
257 | { | |
258 | grub_uint8_t magic[2]; | |
259 | grub_uint32_t filesize; | |
260 | grub_uint32_t reserved; | |
261 | grub_uint32_t bmp_off; | |
262 | grub_uint32_t head_size; | |
263 | grub_uint16_t width; | |
264 | grub_uint16_t height; | |
265 | grub_uint16_t planes; | |
266 | grub_uint16_t bpp; | |
7e47e27b | 267 | } GRUB_PACKED; |
50361660 VS |
268 | |
269 | static void | |
270 | grub_video_capture_write_bmp (const char *fname, | |
271 | void *ptr, | |
272 | const struct grub_video_mode_info *mode_info) | |
273 | { | |
99519c15 | 274 | grub_util_fd_t fd = grub_util_fd_open (fname, GRUB_UTIL_FD_O_WRONLY | GRUB_UTIL_FD_O_CREATTRUNC); |
50361660 VS |
275 | struct bmp_header head; |
276 | ||
25ac643a | 277 | if (!GRUB_UTIL_FD_IS_VALID (fd)) |
50361660 VS |
278 | { |
279 | grub_printf (_("cannot open `%s': %s"), | |
25ac643a | 280 | fname, grub_util_fd_strerror ()); |
50361660 VS |
281 | } |
282 | ||
283 | grub_memset (&head, 0, sizeof (head)); | |
284 | ||
285 | head.magic[0] = 'B'; | |
286 | head.magic[1] = 'M'; | |
287 | ||
288 | if (mode_info->mode_type & GRUB_VIDEO_MODE_TYPE_RGB) | |
289 | { | |
290 | head.filesize = grub_cpu_to_le32 (sizeof (head) + mode_info->width * mode_info->height * 3); | |
291 | head.bmp_off = grub_cpu_to_le32 (sizeof (head)); | |
292 | head.bpp = grub_cpu_to_le16_compile_time (24); | |
293 | } | |
294 | else | |
295 | { | |
296 | head.filesize = grub_cpu_to_le32 (sizeof (head) + 3 * 256 + mode_info->width * mode_info->height); | |
297 | head.bmp_off = grub_cpu_to_le32 (sizeof (head) + 3 * 256); | |
298 | head.bpp = grub_cpu_to_le16_compile_time (8); | |
299 | } | |
300 | head.head_size = grub_cpu_to_le32 (sizeof (head) - 14); | |
301 | head.width = grub_cpu_to_le16 (mode_info->width); | |
302 | head.height = grub_cpu_to_le16 (mode_info->height); | |
303 | head.planes = grub_cpu_to_le16_compile_time (1); | |
304 | ||
305 | head.width = grub_cpu_to_le16 (mode_info->width); | |
306 | head.height = grub_cpu_to_le16 (mode_info->height); | |
307 | ||
25ac643a | 308 | grub_util_fd_write (fd, (char *) &head, sizeof (head)); |
50361660 VS |
309 | |
310 | if (!(mode_info->mode_type & GRUB_VIDEO_MODE_TYPE_RGB)) | |
311 | { | |
312 | struct grub_video_palette_data palette_data[256]; | |
313 | int i; | |
314 | int palette_len = mode_info->number_of_colors; | |
315 | grub_memset (palette_data, 0, sizeof (palette_data)); | |
316 | if (palette_len > 256) | |
317 | palette_len = 256; | |
318 | grub_video_get_palette (0, palette_len, palette_data); | |
319 | for (i = 0; i < 256; i++) | |
320 | { | |
321 | grub_uint8_t r, g, b; | |
322 | r = palette_data[i].r; | |
323 | g = palette_data[i].g; | |
324 | b = palette_data[i].b; | |
325 | ||
25ac643a VS |
326 | grub_util_fd_write (fd, (char *) &b, 1); |
327 | grub_util_fd_write (fd, (char *) &g, 1); | |
328 | grub_util_fd_write (fd, (char *) &r, 1); | |
50361660 VS |
329 | } |
330 | } | |
331 | ||
332 | /* This does essentialy the same as some fbblit functions yet using | |
333 | them would mean testing them against themselves so keep this | |
334 | implemetation separate. */ | |
335 | switch (mode_info->bytes_per_pixel) | |
336 | { | |
337 | case 4: | |
338 | { | |
339 | grub_uint8_t *buffer = xmalloc (mode_info->width * 3); | |
340 | grub_uint32_t rmask = ((1 << mode_info->red_mask_size) - 1); | |
341 | grub_uint32_t gmask = ((1 << mode_info->green_mask_size) - 1); | |
342 | grub_uint32_t bmask = ((1 << mode_info->blue_mask_size) - 1); | |
343 | int rshift = mode_info->red_field_pos; | |
344 | int gshift = mode_info->green_field_pos; | |
345 | int bshift = mode_info->blue_field_pos; | |
346 | int mulrshift = (8 - mode_info->red_mask_size); | |
347 | int mulgshift = (8 - mode_info->green_mask_size); | |
348 | int mulbshift = (8 - mode_info->blue_mask_size); | |
349 | int y; | |
350 | ||
351 | for (y = mode_info->height - 1; y >= 0; y--) | |
352 | { | |
c311ced5 | 353 | grub_uint32_t *iptr = (grub_uint32_t *) ptr + (mode_info->pitch / 4) * y; |
50361660 VS |
354 | int x; |
355 | grub_uint8_t *optr = buffer; | |
356 | for (x = 0; x < (int) mode_info->width; x++) | |
357 | { | |
358 | grub_uint32_t val = *iptr++; | |
359 | *optr++ = ((val >> bshift) & bmask) << mulbshift; | |
360 | *optr++ = ((val >> gshift) & gmask) << mulgshift; | |
361 | *optr++ = ((val >> rshift) & rmask) << mulrshift; | |
362 | } | |
25ac643a | 363 | grub_util_fd_write (fd, (char *) buffer, mode_info->width * 3); |
50361660 VS |
364 | } |
365 | grub_free (buffer); | |
366 | break; | |
367 | } | |
368 | case 3: | |
369 | { | |
370 | grub_uint8_t *buffer = xmalloc (mode_info->width * 3); | |
371 | grub_uint32_t rmask = ((1 << mode_info->red_mask_size) - 1); | |
372 | grub_uint32_t gmask = ((1 << mode_info->green_mask_size) - 1); | |
373 | grub_uint32_t bmask = ((1 << mode_info->blue_mask_size) - 1); | |
374 | int rshift = mode_info->red_field_pos; | |
375 | int gshift = mode_info->green_field_pos; | |
376 | int bshift = mode_info->blue_field_pos; | |
377 | int mulrshift = (8 - mode_info->red_mask_size); | |
378 | int mulgshift = (8 - mode_info->green_mask_size); | |
379 | int mulbshift = (8 - mode_info->blue_mask_size); | |
380 | int y; | |
381 | ||
382 | for (y = mode_info->height - 1; y >= 0; y--) | |
383 | { | |
384 | grub_uint8_t *iptr = ((grub_uint8_t *) ptr + mode_info->pitch * y); | |
385 | int x; | |
386 | grub_uint8_t *optr = buffer; | |
387 | for (x = 0; x < (int) mode_info->width; x++) | |
388 | { | |
389 | grub_uint32_t val = 0; | |
390 | #ifdef GRUB_CPU_WORDS_BIGENDIAN | |
391 | val |= *iptr++ << 16; | |
392 | val |= *iptr++ << 8; | |
393 | val |= *iptr++; | |
394 | #else | |
395 | val |= *iptr++; | |
396 | val |= *iptr++ << 8; | |
397 | val |= *iptr++ << 16; | |
398 | #endif | |
399 | *optr++ = ((val >> bshift) & bmask) << mulbshift; | |
400 | *optr++ = ((val >> gshift) & gmask) << mulgshift; | |
401 | *optr++ = ((val >> rshift) & rmask) << mulrshift; | |
402 | } | |
25ac643a | 403 | grub_util_fd_write (fd, (char *) buffer, mode_info->width * 3); |
50361660 VS |
404 | } |
405 | grub_free (buffer); | |
406 | break; | |
407 | } | |
408 | case 2: | |
409 | { | |
410 | grub_uint8_t *buffer = xmalloc (mode_info->width * 3); | |
411 | grub_uint16_t rmask = ((1 << mode_info->red_mask_size) - 1); | |
412 | grub_uint16_t gmask = ((1 << mode_info->green_mask_size) - 1); | |
413 | grub_uint16_t bmask = ((1 << mode_info->blue_mask_size) - 1); | |
414 | int rshift = mode_info->red_field_pos; | |
415 | int gshift = mode_info->green_field_pos; | |
416 | int bshift = mode_info->blue_field_pos; | |
417 | int mulrshift = (8 - mode_info->red_mask_size); | |
418 | int mulgshift = (8 - mode_info->green_mask_size); | |
419 | int mulbshift = (8 - mode_info->blue_mask_size); | |
420 | int y; | |
421 | ||
422 | for (y = mode_info->height - 1; y >= 0; y--) | |
423 | { | |
c311ced5 | 424 | grub_uint16_t *iptr = (grub_uint16_t *) ptr + (mode_info->pitch / 2) * y; |
50361660 VS |
425 | int x; |
426 | grub_uint8_t *optr = buffer; | |
427 | for (x = 0; x < (int) mode_info->width; x++) | |
428 | { | |
429 | grub_uint16_t val = *iptr++; | |
430 | *optr++ = ((val >> bshift) & bmask) << mulbshift; | |
431 | *optr++ = ((val >> gshift) & gmask) << mulgshift; | |
432 | *optr++ = ((val >> rshift) & rmask) << mulrshift; | |
433 | } | |
25ac643a | 434 | grub_util_fd_write (fd, (char *) buffer, mode_info->width * 3); |
50361660 VS |
435 | } |
436 | grub_free (buffer); | |
437 | break; | |
438 | } | |
439 | case 1: | |
440 | { | |
441 | int y; | |
442 | ||
443 | for (y = mode_info->height - 1; y >= 0; y--) | |
25ac643a VS |
444 | grub_util_fd_write (fd, ((char *) ptr + mode_info->pitch * y), |
445 | mode_info->width); | |
50361660 VS |
446 | break; |
447 | } | |
448 | } | |
25ac643a | 449 | grub_util_fd_close (fd); |
50361660 VS |
450 | } |
451 | ||
452 | #endif | |
453 | ||
b7c036bc VS |
454 | const char * |
455 | grub_video_checksum_get_modename (void) | |
50361660 VS |
456 | { |
457 | static char buf[40]; | |
458 | if (capt_mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) | |
459 | { | |
460 | grub_snprintf (buf, sizeof (buf), "i%d", capt_mode_info.number_of_colors); | |
461 | return buf; | |
462 | } | |
463 | if (capt_mode_info.red_field_pos == 0) | |
464 | { | |
a8905e8a | 465 | grub_snprintf (buf, sizeof (buf), "bgra%d%d%d%d", capt_mode_info.blue_mask_size, |
50361660 | 466 | capt_mode_info.green_mask_size, |
a8905e8a VS |
467 | capt_mode_info.red_mask_size, |
468 | capt_mode_info.reserved_mask_size); | |
50361660 VS |
469 | return buf; |
470 | } | |
a8905e8a | 471 | grub_snprintf (buf, sizeof (buf), "rgba%d%d%d%d", capt_mode_info.red_mask_size, |
50361660 | 472 | capt_mode_info.green_mask_size, |
a8905e8a VS |
473 | capt_mode_info.blue_mask_size, |
474 | capt_mode_info.reserved_mask_size); | |
50361660 VS |
475 | return buf; |
476 | } | |
477 | ||
cdce14fa | 478 | #define GENERATE_MODE 1 |
b7c036bc VS |
479 | //#define SAVE_ALL_IMAGES |
480 | //#define COLLECT_TIME_STATISTICS 1 | |
50361660 VS |
481 | |
482 | #if defined (GENERATE_MODE) && defined (GRUB_MACHINE_EMU) | |
25ac643a | 483 | grub_util_fd_t genfd = GRUB_UTIL_FD_INVALID; |
50361660 VS |
484 | #endif |
485 | ||
b7c036bc VS |
486 | #include <grub/time.h> |
487 | ||
488 | static void | |
489 | write_time (void) | |
490 | { | |
491 | #if defined (GRUB_MACHINE_EMU) && defined (COLLECT_TIME_STATISTICS) | |
492 | char buf[60]; | |
493 | static grub_uint64_t prev; | |
494 | grub_uint64_t cur; | |
25ac643a | 495 | static grub_util_fd_t tmrfd = GRUB_UTIL_FD_INVALID; |
25ac643a VS |
496 | if (!GRUB_UTIL_FD_IS_VALID (tmrfd)) |
497 | tmrfd = grub_util_fd_open ("time.txt", GRUB_UTIL_FD_O_WRONLY | |
498 | | GRUB_UTIL_FD_O_CREATTRUNC); | |
85002bf3 | 499 | |
7e45abce | 500 | cur = grub_util_get_cpu_time_ms (); |
b7c036bc VS |
501 | grub_snprintf (buf, sizeof (buf), "%s_%dx%dx%s:%d: %" PRIuGRUB_UINT64_T " ms\n", |
502 | basename, | |
503 | capt_mode_info.width, | |
504 | capt_mode_info.height, | |
505 | grub_video_checksum_get_modename (), ctr, | |
506 | cur - prev); | |
507 | prev = cur; | |
25ac643a VS |
508 | if (GRUB_UTIL_FD_IS_VALID (tmrfd)) |
509 | grub_util_fd_write (tmrfd, buf, grub_strlen (buf)); | |
b7c036bc VS |
510 | #endif |
511 | } | |
512 | ||
513 | ||
50361660 VS |
514 | static void |
515 | checksum (void) | |
516 | { | |
517 | void *ptr; | |
a8905e8a | 518 | grub_uint32_t crc = 0; |
50361660 VS |
519 | |
520 | ptr = grub_video_capture_get_framebuffer (); | |
521 | ||
b7c036bc VS |
522 | write_time (); |
523 | ||
a8905e8a VS |
524 | #ifdef GRUB_CPU_WORDS_BIGENDIAN |
525 | switch (capt_mode_info.bytes_per_pixel) | |
526 | { | |
527 | case 1: | |
528 | crc = grub_getcrc32c (0, ptr, capt_mode_info.pitch | |
529 | * capt_mode_info.height); | |
530 | break; | |
531 | case 2: | |
532 | { | |
533 | unsigned x, y, rowskip; | |
534 | grub_uint8_t *iptr = ptr; | |
535 | crc = 0; | |
536 | rowskip = capt_mode_info.pitch - capt_mode_info.width * 2; | |
537 | for (y = 0; y < capt_mode_info.height; y++) | |
538 | { | |
539 | for (x = 0; x < capt_mode_info.width; x++) | |
540 | { | |
541 | crc = grub_getcrc32c (crc, iptr + 1, 1); | |
542 | crc = grub_getcrc32c (crc, iptr, 1); | |
543 | iptr += 2; | |
544 | } | |
545 | crc = grub_getcrc32c (crc, iptr, rowskip); | |
546 | iptr += rowskip; | |
547 | } | |
548 | break; | |
549 | } | |
550 | case 3: | |
551 | { | |
552 | unsigned x, y, rowskip; | |
553 | grub_uint8_t *iptr = ptr; | |
554 | crc = 0; | |
555 | rowskip = capt_mode_info.pitch - capt_mode_info.width * 3; | |
556 | for (y = 0; y < capt_mode_info.height; y++) | |
557 | { | |
558 | for (x = 0; x < capt_mode_info.width; x++) | |
559 | { | |
560 | crc = grub_getcrc32c (crc, iptr + 2, 1); | |
561 | crc = grub_getcrc32c (crc, iptr + 1, 1); | |
562 | crc = grub_getcrc32c (crc, iptr, 1); | |
563 | iptr += 3; | |
564 | } | |
565 | crc = grub_getcrc32c (crc, iptr, rowskip); | |
566 | iptr += rowskip; | |
567 | } | |
568 | break; | |
569 | } | |
570 | case 4: | |
571 | { | |
572 | unsigned x, y, rowskip; | |
573 | grub_uint8_t *iptr = ptr; | |
574 | crc = 0; | |
575 | rowskip = capt_mode_info.pitch - capt_mode_info.width * 4; | |
576 | for (y = 0; y < capt_mode_info.height; y++) | |
577 | { | |
578 | for (x = 0; x < capt_mode_info.width; x++) | |
579 | { | |
580 | crc = grub_getcrc32c (crc, iptr + 3, 1); | |
581 | crc = grub_getcrc32c (crc, iptr + 2, 1); | |
582 | crc = grub_getcrc32c (crc, iptr + 1, 1); | |
583 | crc = grub_getcrc32c (crc, iptr, 1); | |
584 | iptr += 4; | |
585 | } | |
586 | crc = grub_getcrc32c (crc, iptr, rowskip); | |
587 | iptr += rowskip; | |
588 | } | |
589 | break; | |
590 | } | |
591 | } | |
592 | #else | |
50361660 | 593 | crc = grub_getcrc32c (0, ptr, capt_mode_info.pitch * capt_mode_info.height); |
a8905e8a | 594 | #endif |
b7c036bc VS |
595 | |
596 | #if defined (GENERATE_MODE) && defined (GRUB_MACHINE_EMU) | |
25ac643a | 597 | if (GRUB_UTIL_FD_IS_VALID (genfd)) |
b7c036bc VS |
598 | { |
599 | char buf[20]; | |
600 | grub_snprintf (buf, sizeof (buf), "0x%x, ", crc); | |
25ac643a | 601 | grub_util_fd_write (genfd, buf, grub_strlen (buf)); |
b7c036bc VS |
602 | } |
603 | #endif | |
604 | ||
50361660 VS |
605 | if (!checksums || ctr >= nchk) |
606 | { | |
607 | grub_test_assert (0, "Unexpected checksum %s_%dx%dx%s:%d: 0x%x", | |
608 | basename, | |
609 | capt_mode_info.width, | |
b7c036bc VS |
610 | capt_mode_info.height, |
611 | grub_video_checksum_get_modename (), ctr, crc); | |
50361660 VS |
612 | } |
613 | else if (crc != checksums[ctr]) | |
614 | { | |
615 | grub_test_assert (0, "Checksum %s_%dx%dx%s:%d failed: 0x%x vs 0x%x", | |
616 | basename, | |
617 | capt_mode_info.width, | |
b7c036bc VS |
618 | capt_mode_info.height, |
619 | grub_video_checksum_get_modename (), | |
50361660 VS |
620 | ctr, crc, checksums[ctr]); |
621 | } | |
b7c036bc | 622 | #if !(defined (SAVE_ALL_IMAGES) && defined (GRUB_MACHINE_EMU)) |
50361660 VS |
623 | else |
624 | { | |
b7c036bc | 625 | write_time (); |
50361660 VS |
626 | ctr++; |
627 | return; | |
50361660 | 628 | } |
b7c036bc | 629 | #endif |
50361660 VS |
630 | #ifdef GRUB_MACHINE_EMU |
631 | char *name = grub_xasprintf ("%s_%dx%dx%s_%d.bmp", basename, | |
632 | capt_mode_info.width, | |
b7c036bc VS |
633 | capt_mode_info.height, |
634 | grub_video_checksum_get_modename (), | |
50361660 VS |
635 | ctr); |
636 | grub_video_capture_write_bmp (name, ptr, &capt_mode_info); | |
b7c036bc | 637 | grub_free (name); |
50361660 VS |
638 | #endif |
639 | ||
b7c036bc | 640 | write_time (); |
50361660 VS |
641 | |
642 | ctr++; | |
643 | } | |
644 | ||
645 | struct checksum_desc | |
646 | { | |
647 | const char *name; | |
648 | unsigned width; | |
649 | unsigned height; | |
650 | unsigned mode_type; | |
651 | unsigned number_of_colors; | |
652 | unsigned bpp; | |
653 | unsigned bytes_per_pixel; | |
654 | unsigned red_field_pos; | |
655 | unsigned red_mask_size; | |
656 | unsigned green_field_pos; | |
657 | unsigned green_mask_size; | |
658 | unsigned blue_field_pos; | |
659 | unsigned blue_mask_size; | |
660 | unsigned reserved_field_pos; | |
661 | unsigned reserved_mask_size; | |
662 | const grub_uint32_t *checksums; | |
663 | int nchk; | |
664 | }; | |
665 | ||
666 | const struct checksum_desc checksum_table[] = { | |
8cec7bd4 | 667 | #include "checksums.h" |
50361660 VS |
668 | }; |
669 | ||
670 | void | |
671 | grub_video_checksum (const char *basename_in) | |
672 | { | |
673 | unsigned i; | |
674 | ||
675 | grub_video_get_info (&capt_mode_info); | |
676 | ||
677 | #if defined (GENERATE_MODE) && defined (GRUB_MACHINE_EMU) | |
25ac643a VS |
678 | if (!GRUB_UTIL_FD_IS_VALID (genfd)) |
679 | genfd = grub_util_fd_open ("checksums.h", GRUB_UTIL_FD_O_WRONLY | |
680 | | GRUB_UTIL_FD_O_CREATTRUNC); | |
681 | if (GRUB_UTIL_FD_IS_VALID (genfd)) | |
50361660 VS |
682 | { |
683 | char buf[400]; | |
684 | ||
685 | grub_snprintf (buf, sizeof (buf), "\", %d, %d, 0x%x, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d /* %dx%dx%s */, (grub_uint32_t []) { ", | |
686 | capt_mode_info.width, | |
687 | capt_mode_info.height, | |
688 | capt_mode_info.mode_type, | |
689 | capt_mode_info.number_of_colors, | |
690 | capt_mode_info.bpp, | |
691 | capt_mode_info.bytes_per_pixel, | |
692 | capt_mode_info.red_field_pos, | |
693 | capt_mode_info.red_mask_size, | |
694 | capt_mode_info.green_field_pos, | |
695 | capt_mode_info.green_mask_size, | |
696 | capt_mode_info.blue_field_pos, | |
697 | capt_mode_info.blue_mask_size, | |
698 | capt_mode_info.reserved_field_pos, | |
699 | capt_mode_info.reserved_mask_size, | |
700 | capt_mode_info.width, | |
c5dbc13d VS |
701 | capt_mode_info.height, |
702 | grub_video_checksum_get_modename ()); | |
50361660 | 703 | |
25ac643a VS |
704 | grub_util_fd_write (genfd, " { \"", 5); |
705 | grub_util_fd_write (genfd, basename_in, grub_strlen (basename_in)); | |
706 | grub_util_fd_write (genfd, buf, grub_strlen (buf)); | |
50361660 VS |
707 | } |
708 | #endif | |
709 | ||
710 | basename = grub_strdup (basename_in); | |
711 | nchk = 0; | |
712 | checksums = 0; | |
713 | /* FIXME: optimize this. */ | |
714 | for (i = 0; i < ARRAY_SIZE (checksum_table); i++) | |
715 | if (grub_strcmp (checksum_table[i].name, basename_in) == 0 | |
716 | && capt_mode_info.width == checksum_table[i].width | |
717 | && capt_mode_info.height == checksum_table[i].height | |
718 | && capt_mode_info.mode_type == checksum_table[i].mode_type | |
719 | && capt_mode_info.number_of_colors == checksum_table[i].number_of_colors | |
720 | && capt_mode_info.bpp == checksum_table[i].bpp | |
721 | && capt_mode_info.bytes_per_pixel == checksum_table[i].bytes_per_pixel | |
722 | && capt_mode_info.red_field_pos == checksum_table[i].red_field_pos | |
723 | && capt_mode_info.red_mask_size == checksum_table[i].red_mask_size | |
724 | && capt_mode_info.green_field_pos == checksum_table[i].green_field_pos | |
725 | && capt_mode_info.green_mask_size == checksum_table[i].green_mask_size | |
726 | && capt_mode_info.blue_field_pos == checksum_table[i].blue_field_pos | |
727 | && capt_mode_info.blue_mask_size == checksum_table[i].blue_mask_size | |
728 | && capt_mode_info.reserved_field_pos == checksum_table[i].reserved_field_pos | |
729 | && capt_mode_info.reserved_mask_size == checksum_table[i].reserved_mask_size) | |
730 | { | |
731 | nchk = checksum_table[i].nchk; | |
732 | checksums = checksum_table[i].checksums; | |
733 | break; | |
734 | } | |
735 | ||
736 | ctr = 0; | |
737 | grub_video_capture_refresh_cb = checksum; | |
738 | } | |
739 | ||
740 | void | |
741 | grub_video_checksum_end (void) | |
742 | { | |
743 | #if defined (GENERATE_MODE) && defined (GRUB_MACHINE_EMU) | |
25ac643a | 744 | if (GRUB_UTIL_FD_IS_VALID (genfd)) |
50361660 VS |
745 | { |
746 | char buf[40]; | |
b7c036bc | 747 | grub_snprintf (buf, sizeof (buf), "}, %d },\n", ctr); |
25ac643a | 748 | grub_util_fd_write (genfd, buf, grub_strlen (buf)); |
50361660 VS |
749 | } |
750 | #endif | |
751 | grub_test_assert (ctr == nchk, "Not enough checksums %s_%dx%dx%s: %d vs %d", | |
752 | basename, | |
753 | capt_mode_info.width, | |
b7c036bc VS |
754 | capt_mode_info.height, |
755 | grub_video_checksum_get_modename (), | |
50361660 VS |
756 | ctr, nchk); |
757 | grub_free (basename); | |
758 | basename = 0; | |
759 | nchk = 0; | |
760 | checksums = 0; | |
761 | ctr = 0; | |
762 | grub_video_capture_refresh_cb = 0; | |
763 | } | |
0e7b2e32 VS |
764 | |
765 | static struct grub_term_output *saved_outputs; | |
766 | static struct grub_term_output *saved_gfxnext; | |
767 | static struct grub_term_output *gfxterm; | |
d71b45ae | 768 | static int use_gfxterm = 0; |
0e7b2e32 VS |
769 | |
770 | int | |
771 | grub_test_use_gfxterm (void) | |
772 | { | |
0e7b2e32 VS |
773 | FOR_ACTIVE_TERM_OUTPUTS (gfxterm) |
774 | if (grub_strcmp (gfxterm->name, "gfxterm") == 0) | |
775 | break; | |
776 | if (!gfxterm) | |
777 | FOR_DISABLED_TERM_OUTPUTS (gfxterm) | |
778 | if (grub_strcmp (gfxterm->name, "gfxterm") == 0) | |
779 | break; | |
780 | ||
781 | if (!gfxterm) | |
782 | { | |
783 | grub_test_assert (0, "terminal `%s' isn't found", "gfxterm"); | |
784 | return 1; | |
785 | } | |
786 | ||
d71b45ae VS |
787 | if (gfxterm->init (gfxterm)) |
788 | { | |
789 | grub_test_assert (0, "terminal `%s' failed: %s", "gfxterm", grub_errmsg); | |
790 | return 1; | |
791 | } | |
792 | ||
793 | saved_outputs = grub_term_outputs; | |
0e7b2e32 VS |
794 | saved_gfxnext = gfxterm->next; |
795 | grub_term_outputs = gfxterm; | |
796 | gfxterm->next = 0; | |
d71b45ae | 797 | use_gfxterm = 1; |
0e7b2e32 VS |
798 | |
799 | return 0; | |
800 | } | |
801 | ||
802 | void | |
803 | grub_test_use_gfxterm_end (void) | |
804 | { | |
d71b45ae VS |
805 | if (!use_gfxterm) |
806 | return; | |
807 | use_gfxterm = 0; | |
0e7b2e32 VS |
808 | gfxterm->fini (gfxterm); |
809 | gfxterm->next = saved_gfxnext; | |
810 | grub_term_outputs = saved_outputs; | |
d71b45ae VS |
811 | saved_outputs = 0; |
812 | saved_gfxnext = 0; | |
0e7b2e32 | 813 | } |