1 /*
2 Copyright (c) 2005-2021 Intel Corporation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 #ifndef TBB_examples_video_H
18 #define TBB_examples_video_H
19
20 #include <cassert>
21 #include <cstddef>
22 #if _MSC_VER
23 #include <stddef.h> // for uintptr_t
24 #else
25 #include <stdint.h> // for uintptr_t
26 #endif
27 #if _WIN32 || _WIN64
28 #include <windows.h>
29 #else
30 #include <unistd.h>
31 #endif
32
33 typedef unsigned int color_t;
34 typedef unsigned char colorcomp_t;
35 typedef signed char depth_t;
36
37 //! Class for getting access to drawing memory
38 class drawing_memory {
39 uintptr_t my_address;
40
41 public:
42 depth_t pixel_depth;
43 int sizex, sizey;
44 //! Get drawing memory
get_address() const45 inline char *get_address() const {
46 return reinterpret_cast<char *>(my_address);
47 }
48 //! Get drawing memory size
get_size() const49 inline int get_size() const {
50 return ((pixel_depth > 16) ? 4 : 2) * sizex * sizey;
51 }
52 //! Set drawing memory
set_address(char * mem)53 inline void set_address(char *mem) {
54 my_address = reinterpret_cast<uintptr_t>(mem);
55 }
56
57 friend class drawing_area;
58 friend class video;
59 };
60
61 //! Simple proxy class for managing of different video systems
62 class video {
63 //! colorspace information
64 depth_t depth, red_shift, green_shift, blue_shift;
65 color_t red_mask, green_mask, blue_mask;
66 friend class drawing_area;
67
68 public:
69 //! Constructor
70 video();
71 //! Destructor
72 ~video();
73 //! member to set window name
74 const char *title;
75 //! true is enable to show fps
76 bool calc_fps;
77 //! if true: on windows fork processing thread for on_process(), on non-windows note that next_frame() is called concurrently.
78 bool threaded;
79 //! true while running within main_loop()
80 bool running;
81 //! if true, do gui updating
82 bool updating;
83 //! initialize graphical video system
84 bool init_window(int sizex, int sizey);
85 //! initialize console. returns true if console is available
86 bool init_console();
87 //! terminate video system
88 void terminate();
89 //! Do standard event & processing loop. Use threaded = true to separate event/updating loop from frame processing
90 void main_loop();
91 //! Process next frame
92 bool next_frame();
93 //! Change window title
94 void show_title();
95 //! translate RGB components into packed type
96 inline color_t get_color(colorcomp_t red, colorcomp_t green, colorcomp_t blue) const;
97 //! Get drawing memory descriptor
98 inline drawing_memory get_drawing_memory() const;
99
100 //! code of the ESCape key
101 static const int esc_key = 27;
102 //! Mouse events handler.
on_mouse(int x,int y,int key)103 virtual void on_mouse(int x, int y, int key) {}
104 //! Mouse events handler.
on_key(int key)105 virtual void on_key(int key) {}
106 //! Main processing loop. Redefine with your own
on_process()107 virtual void on_process() {
108 while (next_frame())
109 ;
110 }
111
112 #ifdef _WINDOWS
113 //! Windows specific members
114 //! if VIDEO_WINMAIN isn't defined then set this just before init() by arguments of WinMain
115 static HINSTANCE win_hInstance;
116 static int win_iCmdShow;
117 //! optionally call it just before init() to set own. Use ascii strings convention
118 void win_set_class(WNDCLASSEX &);
119 //! load and set accelerator table from resources
120 void win_load_accelerators(int idc);
121 #endif
122 };
123
124 //! Drawing class
125 class drawing_area {
126 const std::size_t base_index, max_index, index_stride;
127 const depth_t pixel_depth;
128 unsigned int *const ptr32;
129 std::size_t index;
130
131 public:
132 const int start_x, start_y, size_x, size_y;
133 //! constructors
134 drawing_area(int x, int y, int sizex, int sizey);
135 inline drawing_area(int x, int y, int sizex, int sizey, const drawing_memory &dmem);
136 //! destructor
137 inline ~drawing_area();
138 //! update the image
139 void update();
140 //! set current position. local_x could be bigger then size_x
141 inline void set_pos(int local_x, int local_y);
142 //! put pixel in current position with incremental address calculating to next right pixel
143 inline void put_pixel(color_t color);
144 //! draw pixel at position by packed color
set_pixel(int localx,int localy,color_t color)145 void set_pixel(int localx, int localy, color_t color) {
146 set_pos(localx, localy);
147 put_pixel(color);
148 }
149 };
150
151 extern int g_sizex;
152 extern int g_sizey;
153 extern unsigned int *g_pImg;
154
get_drawing_memory() const155 inline drawing_memory video::get_drawing_memory() const {
156 drawing_memory dmem;
157 dmem.pixel_depth = depth;
158 dmem.my_address = reinterpret_cast<uintptr_t>(g_pImg);
159 dmem.sizex = g_sizex;
160 dmem.sizey = g_sizey;
161 return dmem;
162 }
163
get_color(colorcomp_t red,colorcomp_t green,colorcomp_t blue) const164 inline color_t video::get_color(colorcomp_t red, colorcomp_t green, colorcomp_t blue) const {
165 if (red_shift == 16) // only for depth == 24 && red_shift > blue_shift
166 return (red << 16) | (green << 8) | blue;
167 else if (depth >= 24)
168 return
169 #if __ANDROID__
170 // Setting Alpha to 0xFF
171 0xFF000000 |
172 #endif
173 (red << red_shift) | (green << green_shift) | (blue << blue_shift);
174 else if (depth > 0) {
175 depth_t bs = blue_shift, rs = red_shift;
176 if (blue_shift < 0)
177 blue >>= -bs, bs = 0;
178 else /*red_shift < 0*/
179 red >>= -rs, rs = 0;
180 return ((red << rs) & red_mask) | ((green << green_shift) & green_mask) |
181 ((blue << bs) & blue_mask);
182 }
183 else { // UYVY colorspace
184 unsigned y, u, v;
185 y = red * 77 + green * 150 + blue * 29; // sum(77+150+29=256) * max(=255): limit->2^16
186 u = (2048 + (blue << 3) - (y >> 5)) >> 4; // (limit->2^12)>>4
187 v = (2048 + (red << 3) - (y >> 5)) >> 4;
188 y = y >> 8;
189 return u | (y << 8) | (v << 16) | (y << 24);
190 }
191 }
192
drawing_area(int x,int y,int sizex,int sizey,const drawing_memory & dmem)193 inline drawing_area::drawing_area(int x, int y, int sizex, int sizey, const drawing_memory &dmem)
194 : base_index(y * dmem.sizex + x),
195 max_index(dmem.sizex * dmem.sizey),
196 index_stride(dmem.sizex),
197 pixel_depth(dmem.pixel_depth),
198 ptr32(reinterpret_cast<unsigned int *>(dmem.my_address)),
199 start_x(x),
200 start_y(y),
201 size_x(sizex),
202 size_y(sizey) {
203 assert(x < dmem.sizex);
204 assert(y < dmem.sizey);
205 assert(x + sizex <= dmem.sizex);
206 assert(y + sizey <= dmem.sizey);
207
208 index = base_index; // current index
209 }
210
set_pos(int local_x,int local_y)211 inline void drawing_area::set_pos(int local_x, int local_y) {
212 index = base_index + local_x + local_y * index_stride;
213 }
214
put_pixel(color_t color)215 inline void drawing_area::put_pixel(color_t color) {
216 assert(index < max_index);
217 if (pixel_depth > 16)
218 ptr32[index++] = color;
219 else if (pixel_depth > 0)
220 ((unsigned short *)ptr32)[index++] = (unsigned short)color;
221 else { // UYVY colorspace
222 if (index & 1)
223 color >>= 16;
224 ((unsigned short *)ptr32)[index++] = (unsigned short)color;
225 }
226 }
227
~drawing_area()228 inline drawing_area::~drawing_area() {}
229
230 #if defined(_WINDOWS) && (defined(VIDEO_WINMAIN) || defined(VIDEO_WINMAIN_ARGS))
231 #include <cstdlib>
232 //! define WinMain for subsystem:windows.
233 #ifdef VIDEO_WINMAIN_ARGS
234 int main(int, char *[]);
235 #else
236 int main();
237 #endif
WinMain(HINSTANCE hInstance,HINSTANCE,PSTR szCmdLine,int iCmdShow)238 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR szCmdLine, int iCmdShow) {
239 video::win_hInstance = hInstance;
240 video::win_iCmdShow = iCmdShow;
241 #ifdef VIDEO_WINMAIN_ARGS
242 return main(__argc, __argv);
243 #else
244 return main();
245 #endif
246 }
247 #endif
248
249 #endif /* TBB_examples_video_H */
250