1 #include "windows.h"
2 #include "stdio.h"
3 #include "stdlib.h"
4 #include "gx_validation_strings.h"
5 #include "gx_validation_verify.h"
6
7 /* Define the Windows Bitmap Structure */
8 typedef struct GUIX_BMP_INFO_STRUCT
9 {
10 BITMAPINFOHEADER bmiHeader;
11 DWORD bmiColors[256];
12 } GUIX_BMP_INFO;
13
14 GUIX_BMP_INFO bmp_info;
15 FILE *pFile = NULL;
16 FILE *goldenFile = NULL;
17 unsigned int*buffer = NULL;
18 unsigned int*golden_frame_buffer = NULL;
19 int total_frames = 0;
20 int height = 0;
21 int width = 0;
22 int data_width = 0;
23 HWND hwnd;
24 int index = 1;
25 int bits_per_pixel = 0;
26 int len;
27 int file_foramt = 0;
28
win32_16srgb_bitmap_header_create(int width,int height)29 static void win32_16srgb_bitmap_header_create(int width, int height)
30 {
31
32 DWORD *putmask;
33 HDC win_device;
34
35
36
37 bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
38 bmp_info.bmiHeader.biWidth = width;
39 bmp_info.bmiHeader.biHeight = height;
40
41 bmp_info.bmiHeader.biPlanes = 1;
42 bmp_info.bmiHeader.biBitCount = 16;
43 bmp_info.bmiHeader.biSizeImage = width * height * 2;
44 bmp_info.bmiHeader.biClrUsed = 65535;
45 bmp_info.bmiHeader.biClrImportant = 65535;
46 bmp_info.bmiHeader.biCompression = BI_BITFIELDS;
47
48
49 putmask = (DWORD *)&(bmp_info.bmiColors[0]);
50
51 *putmask++ = 0x0000f800;
52 *putmask++ = 0x000007e0;
53 *putmask = 0x0000001f;
54
55 }
56
win32_565bgr_bitmap_header_create(int width,int height)57 static void win32_565bgr_bitmap_header_create(int width, int height)
58 {
59
60 DWORD* putmask;
61 HDC win_device;
62
63
64
65 bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
66 bmp_info.bmiHeader.biWidth = width;
67 bmp_info.bmiHeader.biHeight = height;
68
69 bmp_info.bmiHeader.biPlanes = 1;
70 bmp_info.bmiHeader.biBitCount = 16;
71 bmp_info.bmiHeader.biSizeImage = width * height * 2;
72 bmp_info.bmiHeader.biClrUsed = 65535;
73 bmp_info.bmiHeader.biClrImportant = 65535;
74 bmp_info.bmiHeader.biCompression = BI_BITFIELDS;
75
76
77 putmask = (DWORD*)&(bmp_info.bmiColors[0]);
78
79 *putmask++ = 0x0000001f;
80 *putmask++ = 0x000007e0;
81 *putmask = 0x0000f800;
82
83 }
84
win32_1555xrgb_bitmap_header_create(int width,int height)85 static void win32_1555xrgb_bitmap_header_create(int width, int height)
86 {
87
88 DWORD *putmask;
89 HDC win_device;
90
91
92
93 bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
94 bmp_info.bmiHeader.biWidth = width;
95 bmp_info.bmiHeader.biHeight = height;
96
97 bmp_info.bmiHeader.biPlanes = 1;
98 bmp_info.bmiHeader.biBitCount = 16;
99 bmp_info.bmiHeader.biSizeImage = width * height * 2;
100 bmp_info.bmiHeader.biClrUsed = 65535;
101 bmp_info.bmiHeader.biClrImportant = 65535;
102 bmp_info.bmiHeader.biCompression = BI_BITFIELDS;
103
104
105 putmask = (DWORD *)&(bmp_info.bmiColors[0]);
106
107 *putmask++ = 0x00007c00;
108 *putmask++ = 0x000003e0;
109 *putmask = 0x0000001f;
110
111 }
112
win32_4444argb_bitmap_header_create(int width,int height)113 static void win32_4444argb_bitmap_header_create(int width, int height)
114 {
115
116 DWORD *putmask;
117 HDC win_device;
118
119
120
121 bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
122 bmp_info.bmiHeader.biWidth = width;
123 bmp_info.bmiHeader.biHeight = height;
124
125 bmp_info.bmiHeader.biPlanes = 1;
126 bmp_info.bmiHeader.biBitCount = 16;
127 bmp_info.bmiHeader.biSizeImage = width * height * 2;
128 bmp_info.bmiHeader.biClrUsed = 65535;
129 bmp_info.bmiHeader.biClrImportant = 65535;
130 bmp_info.bmiHeader.biCompression = BI_BITFIELDS;
131
132
133 putmask = (DWORD *)&(bmp_info.bmiColors[0]);
134
135 *putmask++ = 0x00000f00;
136 *putmask++ = 0x000000f0;
137 *putmask = 0x0000000f;
138
139 }
140
win32_24srgb_bitmap_header_create(int width,int height)141 static void win32_24srgb_bitmap_header_create(int width, int height)
142 {
143
144 DWORD *putmask;
145 HDC win_device;
146
147
148
149 bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
150 bmp_info.bmiHeader.biWidth = width;
151 bmp_info.bmiHeader.biHeight = height;
152
153 bmp_info.bmiHeader.biPlanes = 1;
154 bmp_info.bmiHeader.biBitCount = 32;
155 bmp_info.bmiHeader.biSizeImage = width * height * 4;
156 bmp_info.bmiHeader.biClrUsed = 16777215;
157 bmp_info.bmiHeader.biClrImportant = 16777215;
158 bmp_info.bmiHeader.biCompression = BI_BITFIELDS;
159
160
161 putmask = (DWORD *)&(bmp_info.bmiColors[0]);
162
163 *putmask++ = 0x00ff0000;
164 *putmask++ = 0x0000ff00;
165 *putmask = 0x000000ff;
166
167 }
168
win32_8bpp_bitmap_header_create(width,height)169 static void win32_8bpp_bitmap_header_create(width, height)
170 {
171 bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
172 bmp_info.bmiHeader.biWidth = width;
173 bmp_info.bmiHeader.biHeight = height;
174
175 bmp_info.bmiHeader.biPlanes = 1;
176 bmp_info.bmiHeader.biBitCount = 8;
177 bmp_info.bmiHeader.biSizeImage = width * height;
178 bmp_info.bmiHeader.biClrUsed = 255;
179 bmp_info.bmiHeader.biClrImportant = 255;
180 bmp_info.bmiHeader.biCompression = BI_RGB;
181 }
182
win32_332rgb_bitmap_header_create(width,height)183 static void win32_332rgb_bitmap_header_create(width, height)
184 {
185 ULONG color;
186 INT r = 0;
187 INT g = 0;
188 INT b = 0;
189 INT i = 0;
190 INT red;
191 INT green;
192 INT blue;
193
194 bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
195 bmp_info.bmiHeader.biWidth = width;
196 bmp_info.bmiHeader.biHeight = height;
197
198 bmp_info.bmiHeader.biPlanes = 1;
199 bmp_info.bmiHeader.biBitCount = 8;
200 bmp_info.bmiHeader.biSizeImage = width * height;
201 bmp_info.bmiHeader.biClrUsed = 0;
202 bmp_info.bmiHeader.biClrImportant = 0;
203 bmp_info.bmiHeader.biCompression = BI_RGB;
204
205 for (r = 0; r < 8; r++)
206 {
207 red = r << 21;
208 if (red & 0x200000) { red |= 0x1f0000; }
209 for (g = 0; g < 8; g++)
210 {
211 green = g << 13;
212 if (green & 0x2000) { green |= 0x1f00; }
213 for (b = 0; b < 4; b++)
214 {
215 blue = b << 6;
216 if (blue & 0x40) { blue |= 0x3f; }
217 color = red | green | blue;
218 bmp_info.bmiColors[i] = color;
219 i++;
220 }
221 }
222 }
223 }
224
win32_8bpp_palette_set()225 static void win32_8bpp_palette_set()
226 {
227 ULONG color = 0;
228 int loop;
229 int count = 0;
230 char line[256];
231
232 while(!count)
233 {
234 if(fgets(line, 100, pFile) != NULL);
235 {
236 if(strncmp(line, "PALETTE DATA SIZE: ", strlen("PALETTE DATA SIZE: ")) == 0)
237 count = atoi(&line[strlen("PALETTE DATA SIZE: ")]);
238 }
239 }
240 fgets(line, 100, pFile);
241
242 bmp_info.bmiHeader.biClrUsed = count;
243 bmp_info.bmiHeader.biClrImportant = count;
244
245 for (loop = 0; loop < count; loop++)
246 {
247 fscanf(pFile, "%ul", &color);
248 bmp_info.bmiColors[loop] = color;
249 }
250 }
251
252 static ULONG grayscale_table[] =
253 {
254 0xff000000,
255 0xff111111,
256 0xff222222,
257 0xff333333,
258 0xff444444,
259 0xff555555,
260 0xff666666,
261 0xff777777,
262 0xff888888,
263 0xff999999,
264 0xffaaaaaa,
265 0xffbbbbbb,
266 0xffcccccc,
267 0xffdddddd,
268 0xffeeeeee,
269 0xffffffff
270 };
271
win32_4bpp_bitmap_header_create(width,height)272 static void win32_4bpp_bitmap_header_create(width, height)
273 {
274 bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
275 bmp_info.bmiHeader.biWidth = width;
276 bmp_info.bmiHeader.biHeight = height;
277
278 bmp_info.bmiHeader.biPlanes = 1;
279 bmp_info.bmiHeader.biBitCount = 4;
280 bmp_info.bmiHeader.biSizeImage = width * height >> 1;
281 bmp_info.bmiHeader.biClrUsed = 16;
282 bmp_info.bmiHeader.biClrImportant = 16;
283 bmp_info.bmiHeader.biCompression = BI_RGB;
284
285 memcpy(bmp_info.bmiColors, grayscale_table, sizeof(grayscale_table));
286 }
287
288 static ULONG color_table[] =
289 {
290 0x00000000,
291 0x00ffffff
292 };
293
win32_1bpp_bitmap_header_create(width,height)294 static void win32_1bpp_bitmap_header_create(width, height)
295 {
296 bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
297 bmp_info.bmiHeader.biWidth = width;
298 bmp_info.bmiHeader.biHeight = height;
299
300 bmp_info.bmiHeader.biPlanes = 1;
301 bmp_info.bmiHeader.biBitCount = 1;
302 bmp_info.bmiHeader.biSizeImage = (width * height) >> 3;
303 bmp_info.bmiHeader.biClrUsed = 2;
304 bmp_info.bmiHeader.biClrImportant = 2;
305 bmp_info.bmiHeader.biCompression = BI_RGB;
306
307 memcpy(bmp_info.bmiColors, color_table, sizeof(color_table));
308 }
309
WndProc(HWND hwnd,unsigned int message,WPARAM wParam,LPARAM lParam)310 LRESULT CALLBACK WndProc(HWND hwnd, unsigned int message, WPARAM wParam, LPARAM lParam)
311 {
312 PAINTSTRUCT ps;
313
314 switch(message)
315 {
316 case WM_TIMER:
317 return 0;
318
319 case WM_PAINT:
320 BeginPaint(hwnd, &ps);
321 show_frame();
322 EndPaint(hwnd, &ps);
323
324 return 0;
325
326 case WM_KEYDOWN:
327 if(wParam == 0x26) /* Upper arrow key */
328 {
329 if(index > 1)
330 {
331 index--;
332 show_frame();
333 }
334 }
335 else if(wParam == 0x28) /* Down arrow key */
336 {
337 if(index < total_frames)
338 {
339 index++;
340 show_frame();
341 }
342 }
343
344 else if((wParam == 'q') || (wParam == 'Q'))
345 {
346 PostQuitMessage(0);
347 return 0;
348 }
349 break;
350
351
352
353 case WM_DESTROY:
354 PostQuitMessage(0);
355 return 0;
356 }
357
358 return DefWindowProc(hwnd, message, wParam, lParam);
359 }
360
win32_window_create(void)361 static HWND win32_window_create(void)
362 {
363 HINSTANCE Instance = GetModuleHandle(NULL);
364 RECT TargetSize;
365 DWORD WinStyle;
366 HWND win32_hwnd = 0;
367 WNDCLASS wndclass;
368
369 memset(&wndclass, 0, sizeof(wndclass));
370
371 wndclass.style = CS_HREDRAW | CS_VREDRAW;
372 wndclass.lpfnWndProc = WndProc;
373 wndclass.cbClsExtra = 0;
374 wndclass.cbWndExtra = 0;
375 wndclass.hInstance = Instance;
376
377 wndclass.hCursor = NULL;
378 wndclass.hbrBackground = (HBRUSH)(GetStockObject(WHITE_BRUSH));
379 wndclass.lpszMenuName = NULL;
380 wndclass.lpszClassName = TEXT("GUIX");
381
382 RegisterClass(&wndclass);
383
384 TargetSize.left = 0;
385 TargetSize.top = 0;
386 TargetSize.right = bmp_info.bmiHeader.biWidth;
387 TargetSize.bottom = bmp_info.bmiHeader.biHeight;
388
389 WinStyle = WS_CAPTION | WS_SIZEBOX | WS_VISIBLE | WS_MINIMIZEBOX |
390 WS_MAXIMIZEBOX | WS_SYSMENU;
391
392
393 /* This function adjusts the size of the Windows window so that the client
394 size is the size of the display, taking into account borders
395 and titles and such. We want our window client are to be exactly
396 the simulatedd display size.
397 */
398 AdjustWindowRect(&TargetSize, WinStyle, FALSE);
399 win32_hwnd = CreateWindow(TEXT("GUIX"), TEXT("GUIX"),
400 WinStyle, 20, 20,
401 TargetSize.right - TargetSize.left + 1,
402 TargetSize.bottom - TargetSize.top + 1, NULL, NULL,
403 Instance, NULL);
404 SetCursor(LoadCursor(NULL, IDC_ARROW));
405
406 return win32_hwnd;
407 }
408
409 int device_created = 0;
410
411 char comment_buffer[256];
412 char golden_frame_comment[256];
413
find_differences(unsigned int * buffer,unsigned int * golden_buffer,int buffer_size,int frame_ID)414 static find_differences(unsigned int *buffer, unsigned int *golden_buffer, int buffer_size, int frame_ID)
415 {
416
417 unsigned int *data = buffer;
418 unsigned int *gdata = golden_buffer;
419 int pos;
420 int print_frame_id = 0;
421
422 for (pos = 0; pos < buffer_size; pos++)
423 {
424 if (*data != *gdata)
425 {
426 if (print_frame_id == 0)
427 {
428 printf("Frame %d is different\n", frame_ID);
429 print_frame_id = 1;
430 }
431 *data = ~(*data);
432 }
433 data++;
434 gdata++;
435 }
436 }
437
438
show_frame(void)439 int show_frame(void)
440 {
441 HDC win_device;
442 int frame_number = -1;
443 int golden_frame_number = -1;
444 int file_format;
445 int ret = 0;
446 int i;
447 char *color_format;
448
449 fseek(pFile, 0, SEEK_SET);
450 if(goldenFile)
451 fseek(goldenFile, 0, SEEK_SET);
452
453
454 if(device_created == 0)
455 {
456 memset(&bmp_info, 0, sizeof(GUIX_BMP_INFO));
457
458 ret = read_file_header(pFile, &file_format, &total_frames, &color_format, &bits_per_pixel, &width, &height);
459
460 if(ret == -1)
461 {
462 cleanup(pFile, NULL);
463 if(goldenFile)
464 cleanup(goldenFile, NULL);
465 exit(0);
466 }
467
468 if(bits_per_pixel == 16 && ((width & 1) != 0))
469 {
470 data_width = width + 1;
471 }
472 else if(bits_per_pixel == 8 && (width % 4))
473 {
474 data_width = width + 4 - (width % 4);
475 }
476 else if ((bits_per_pixel == 4) && (width % 8))
477 {
478 data_width = width + 8 - (width % 8);
479 }
480 else
481 {
482 data_width = width;
483 }
484 buffer = (unsigned int*)malloc(data_width * height * bits_per_pixel >> 3);
485 if(goldenFile)
486 golden_frame_buffer = (unsigned int*)malloc(data_width * height * bits_per_pixel >> 3);
487
488 if (!strcmp(color_format, COLOR_FORMAT_24XRGB))
489 {
490 win32_24srgb_bitmap_header_create(width, height);
491 }
492 else if (!strcmp(color_format, COLOR_FORMAT_565RGB))
493 {
494 win32_16srgb_bitmap_header_create(width, height);
495 }
496 else if (!strcmp(color_format, COLOR_FORMAT_565BGR))
497 {
498 win32_565bgr_bitmap_header_create(width, height);
499 }
500 else if (!strcmp(color_format, COLOR_FORMAT_1555XRGB))
501 {
502 win32_1555xrgb_bitmap_header_create(width, height);
503 }
504 else if (!strcmp(color_format, COLOR_FORMAT_4444ARGB))
505 {
506 win32_4444argb_bitmap_header_create(width, height);
507 }
508 else if (!strcmp(color_format, COLOR_FORMAT_8BPP))
509 {
510 win32_8bpp_bitmap_header_create(width, height);
511 win32_8bpp_palette_set();
512 }
513 else if(!strcmp(color_format, COLOR_FORMAT_332RGB))
514 {
515 win32_332rgb_bitmap_header_create(width, height);
516 }
517 else if(!strcmp(color_format, COLOR_FORMAT_4BPP))
518 {
519 win32_4bpp_bitmap_header_create(width, height);
520 }
521 else if (!strcmp(color_format, COLOR_FORMAT_1BPP))
522 {
523 win32_1bpp_bitmap_header_create(width, height);
524 }
525
526 hwnd = win32_window_create();
527
528 device_created = 1;
529 }
530
531 for(i = 1; i < index; i++)
532 {
533 find_frame_data(pFile);
534 fseek(pFile, (bits_per_pixel * data_width * height >> 3), SEEK_CUR);
535 if(goldenFile)
536 {
537 find_frame_data(goldenFile);
538 fseek(goldenFile, (bits_per_pixel * data_width * height >> 3), SEEK_CUR);
539 }
540 }
541 get_frame_id(pFile, &frame_number);
542 get_frame_comment(pFile, comment_buffer, sizeof(comment_buffer));
543 fread(buffer, 1, (bits_per_pixel * data_width * height) >> 3, pFile);
544 if(goldenFile)
545 {
546 get_frame_id(goldenFile, &golden_frame_number);
547 get_frame_comment(goldenFile, golden_frame_comment, sizeof(golden_frame_comment));
548 fread(golden_frame_buffer, 1, (bits_per_pixel * data_width * height ) >> 3, goldenFile);
549
550 find_differences(buffer, golden_frame_buffer, (data_width * height * bits_per_pixel) >> 5, index);
551 }
552 if(strlen(comment_buffer))
553 {
554 printf("frame number %d %s\n", frame_number, comment_buffer);
555 }
556 else
557 printf("frame number %d\n", frame_number);
558
559 win_device = GetDC(hwnd);
560 SetMapMode(win_device, MM_TEXT);
561
562 StretchDIBits(win_device, 0, 0, width, height,
563 0, height, width, -height,
564 buffer,
565 (BITMAPINFO *)&bmp_info,
566 DIB_RGB_COLORS,
567 SRCCOPY);
568
569 ReleaseDC(hwnd, win_device);
570 }
571
main(int argc,char ** argv)572 int main(int argc, char **argv)
573 {
574
575 MSG Msg;
576 char *golden_file_name = NULL;
577
578 if(argc == 3)
579 {
580 if((argv[2][0] <= '9') && (argv[2][0] >= '0'))
581 index = atoi(argv[2]);
582 else
583 golden_file_name = argv[2];
584 }
585 if(argc == 4)
586 {
587 index = atoi(argv[2]);
588 golden_file_name = argv[3];
589 }
590
591 if(golden_file_name)
592 goldenFile = fopen(golden_file_name, "rb");
593
594 pFile = fopen(argv[1], "rb");
595
596 if(pFile != NULL)
597 {
598 show_frame(index);
599 }
600
601
602 while(GetMessage(&Msg, NULL, 0, 0) > 0)
603 {
604 TranslateMessage(&Msg);
605 DispatchMessage(&Msg);
606 }
607 cleanup(pFile, buffer);
608 if(goldenFile)
609 cleanup(goldenFile, golden_frame_buffer);
610
611 exit(0);
612 }
613
614
615
616
617