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