6d5ec0e0f34bcd6d62865ccd02ec6a565d077c48
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

1) /*
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

2)  * EtherPix library
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

3)  *
Stefan Schuermans update copyright year

Stefan Schuermans authored 7 years ago

4)  * Copyright 2010-2017 Stefan Schuermans <stefan schuermans info>
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

5)  *
6)  * This program is free software: you can redistribute it and/or modify
7)  * it under the terms of the GNU General Public License as published by
8)  * the Free Software Foundation, version 3 of the License.
9)  *
10)  *
11)  * This program is distributed in the hope that it will be useful,
12)  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13)  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14)  * GNU General Public License for more details.
15)  *
16)  * You should have received a copy of the GNU Lesser General Public License
17)  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18)  */
19) 
20) #include <errno.h>
21) #include <stdlib.h>
22) #include <string.h>
23) 
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

24) #include <etherpix/display.h>
25) #include <etherpix/msg.h>
26) #include <etherpix/types.h>
Stefan Schuermans move internal includes

Stefan Schuermans authored 7 years ago

27) #include "config.h"
28) #include "constants.h"
29) #include "net.h"
30) #include "types.h"
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

31) 
32) /**
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

33)  * \brief create a new EtherPix display
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

34)  *
35)  * \param[in] sz_config_file name of config file to read
36)  * \param[in] p_msg_func message callback function or NULL
37)  * \param[in] p_msg_ctx user context for message callback
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

38)  * \return pointer to new EtherPix display on success
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

39)  *         or NULL on error
40)  */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

41) etp_display_t *etp_display_create(const char *sz_config_file,
42)                                   etp_msg_func_p_t p_msg_func,
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

43)                                   void *p_msg_ctx)
44) {
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

45)   etp_display_t *p_display;
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

46) 
47)   /* basic display setup */
48) 
49)   /* create display structure */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

50)   p_display = (etp_display_t *)calloc(1, sizeof (etp_display_t));
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

51)   if (!p_display) {
52)     if (p_msg_func)
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

53)       p_msg_func(p_msg_ctx, etp_msg_type_err,
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

54)                  "out of memory\n");
55)     return NULL;
56)   }
57) 
58)   /* set default bind address */
59)   p_display->bind_addr.sin_family = AF_INET;
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

60)   p_display->bind_addr.sin_port = htons(ETP_BIND_PORT);
61)   p_display->bind_addr.sin_addr.s_addr = htonl(ETP_BIND_IP);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

62) 
63)   /* no socket yet */
64)   p_display->sock = -1;
65) 
66)   /* config file */
67) 
68)   /* read config file */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

69)   if(etp_config_proc_file(p_display, sz_config_file,
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

70)                           p_msg_func, p_msg_ctx)) {
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

71)     etp_display_free(p_display); /* cleanup everything that config file
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

72)                                     processing might heave created already */
Stefan Schuermans fixed segfault if using wit...

Stefan Schuermans authored 12 years ago

73)     if (p_msg_func)
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

74)       p_msg_func(p_msg_ctx, etp_msg_type_err, "reading config file failed\n");
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

75)     return NULL;
76)   }
77) 
78)   /* set up UDP socket */
79) 
80)   /* create socket */
Stefan Schuermans update Windows support

Stefan Schuermans authored 7 years ago

81) #ifdef WINDOWS
82)   p_display->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
83)   if (p_display->sock != INVALID_SOCKET) {
84)     u_long arg = 1;
85)     if (ioctlsocket(p_display->sock, FIONBIO, &arg) != 0) {
86)       closesocket(p_display->sock);
87)       p_display->sock = INVALID_SOCKET;
88)     }
89)   }
90) #else
Stefan Schuermans make output socket non-bloc...

Stefan Schuermans authored 7 years ago

91)   p_display->sock = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
Stefan Schuermans update Windows support

Stefan Schuermans authored 7 years ago

92) #endif
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

93)   if (!etp_sock_is_valid(p_display->sock)) {
94)     etp_display_free(p_display);
Stefan Schuermans v1.0.2

Stefan Schuermans authored 13 years ago

95)     if (p_msg_func) {
96)       char errmsg[256];
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

97)       etp_sock_get_last_error(errmsg, sizeof(errmsg));
98)       p_msg_func(p_msg_ctx, etp_msg_type_err,
Stefan Schuermans v1.0.2

Stefan Schuermans authored 13 years ago

99)                  "could not create UDP socket: %s\n", errmsg);
100)     }
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

101)     return NULL;
102)   }
103) 
104)   /* bind socket */
105)   if (bind(p_display->sock, (struct sockaddr *)&p_display->bind_addr,
106)            sizeof (p_display->bind_addr))) {
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

107)     etp_display_free(p_display);
Stefan Schuermans v1.0.2

Stefan Schuermans authored 13 years ago

108)     if (p_msg_func) {
109)       char errmsg[256];
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

110)       etp_sock_get_last_error(errmsg, sizeof(errmsg));
111)       p_msg_func(p_msg_ctx, etp_msg_type_err,
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

112)                  "could not bind UDP socket to \"%s:%u\": %s\n",
113)                  inet_ntoa(p_display->bind_addr.sin_addr),
Stefan Schuermans v1.0.2

Stefan Schuermans authored 13 years ago

114)                  (unsigned int)ntohs(p_display->bind_addr.sin_port), errmsg);
115)     }
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

116)     return NULL;
117)   }
118) 
119)   /* clear display */
120) 
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

121)   etp_display_data_clear(p_display);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

122) 
123)   return p_display;
124) }
125) 
126) /**
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

127)  * \brief free a EtherPix display
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

128)  *
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

129)  * \param[in] p_display pointer to EtherPix display
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

130)  */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

131) void etp_display_free(etp_display_t *p_display)
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

132) {
133)   int i;
134) 
135)   if (p_display) {
136) 
137)     /* free distributors */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

138)     for (i = 0; i < ETP_DISTRI_MAX_CNT; i++) {
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

139)       if (p_display->distri_ptrs[i]) {
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

140)         etp_distri_t *p_distri = p_display->distri_ptrs[i];
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

141)         free(p_distri->p_pixels);
142)         free(p_distri->p_msg_buf);
143)         free(p_distri);
144)       }
145)     }
146) 
147)     /* close network connection */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

148)     if (etp_sock_is_valid(p_display->sock))
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

149)       closesocket(p_display->sock);
150) 
151)     /* free display structutre */
152)     free(p_display);
153) 
154)   } /* if (p_display) */
155) }
156) 
157) /**
158)  * \brief get size of display
159)  *
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

160)  * \param[in] p_display pointer to EtherPix display
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

161)  * \param[out] p_width width of display
162)  * \param[out] p_height height of display
163)  */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

164) void etp_display_get_size(etp_display_t *p_display,
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

165)                           unsigned int *p_width, unsigned int *p_height)
166) {
167)   *p_width = (unsigned int)p_display->size.x;
168)   *p_height = (unsigned int)p_display->size.y;
169) }
170) 
171) /**
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

172)  * \brief clear image data to output on EtherPix display
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

173)  *
174)  * clears the stored image data,
175)  * stored image data can later be sent to the distributors using
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

176)  * etp_display_send()
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

177)  *
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

178)  * \param[in] p_display pointer to EtherPix display
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

179)  */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

180) void etp_display_data_clear(etp_display_t *p_display)
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

181) {
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

182)   etp_u8_t black[3] = { 0, 0, 0 };
183)   etp_display_data_fmt(p_display, black, 0, 0,
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

184)                        0, 0, p_display->size.x, p_display->size.y,
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

185)                        etp_pixfmt_rgb24);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

186) }
187) 
188) /**
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

189)  * \brief set image data to output on EtherPix display
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

190)  *
191)  * updates (part of) the stored image data,
192)  * stored image data can later be sent to the distributors using
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

193)  * etp_display_send()
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

194)  *
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

195)  * \param[in] p_display pointer to EtherPix display
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

196)  * \param[in] p_data pointer to rectangular section of image data
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

197)  * \param[in] stride_x stride between two pixels in X direction
198)  * \param[in] stride_y stride between two pixels in Y direction
199)  * \param[in] x X coordinate of left side of rectangular area
200)  * \param[in] y Y coordinate of top side of rectangular area
201)  * \param[in] width with of rectangular area
202)  * \param[in] height height of rectangular area
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

203)  * \param[in] pixfmt format of pixel data
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

204)  */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

205) void etp_display_data_fmt(etp_display_t *p_display, etp_u8_t *p_data,
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

206)                           int stride_x, int stride_y,
207)                           unsigned int x, unsigned int y,
208)                           unsigned int width, unsigned int height,
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

209)                           etp_pixfmt_t pixfmt)
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

210) {
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

211)   unsigned int distri, out, pix, i;
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

212)   etp_distri_t *p_distri;
213)   etp_u8_t *dest, *src;
214)   etp_pixel_t *p_pixel;
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

215)   int rx, ry;
Stefan Schuermans add support for monochrome...

Stefan Schuermans authored 6 years ago

216)   etp_u8_t val;
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

217) 
218)   /* set data for all distributors */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

219)   for (distri = 0; distri < ETP_DISTRI_MAX_CNT; distri++) {
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

220)     p_distri = p_display->distri_ptrs[distri];
221)     if (p_distri) {
222) 
223)       /* set pointer to start of RGB data for pixels in message buffer
224)          (header is already set up and stays the same) */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

225)       dest = p_distri->p_msg_buf + ETP_MCUF_HDR_LEN;
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

226) 
227)       /* get RGB data of pixels for every output */
228)       for (out = 0, i = 0; out < p_distri->output_cnt; out++) {
229)         for (pix = 0; pix < p_distri->pixel_cnt; pix++, i++) {
230)           p_pixel = &p_distri->p_pixels[i];
231) 
232)           /* get pixel coordinates relative to rectangular area of image */
233)           rx = p_pixel->x - (int)x;
234)           ry = p_pixel->y - (int)y;
235)           /* check if pixel is within rectangular area of image */
236)           if (rx >= 0 && (unsigned int)rx < width
237)               && ry >= 0 && (unsigned int)ry < height) {
238)             /* get pixel data and map it */
239)             src = (p_data + rx * stride_x + ry * stride_y);
Stefan Schuermans add support for monochrome...

Stefan Schuermans authored 6 years ago

240)             switch (p_distri->channels) {
241)               case 1:
242)                 switch (pixfmt) {
243)                   case etp_pixfmt_rgb24:
244)                   case etp_pixfmt_bgr24:
245)                     /* RGB/BGR -> monochrome, emphasize green */
246)                     val = (etp_u8_t)(((unsigned int)src[0] +
247)                                       ((unsigned int)src[1] << 1) +
248)                                       (unsigned int)src[2] + 2) >> 2);
249)                     dest[0] = p_distri->mapping[0].table[val];
250)                     break;
251)                   case etp_pixfmt_mono8:
252)                     dest[0] = p_distri->mapping[0].table[src[0]];
253)                     break;
254)                   default:
255)                     dest[0] = 0;
256)                 }
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

257)                 break;
Stefan Schuermans add support for monochrome...

Stefan Schuermans authored 6 years ago

258)               case 3:
259)                 switch (pixfmt) {
260)                   case etp_pixfmt_rgb24:
261)                     dest[0] = p_distri->mapping[0].table[src[0]];
262)                     dest[1] = p_distri->mapping[1].table[src[1]];
263)                     dest[2] = p_distri->mapping[2].table[src[2]];
264)                     break;
265)                   case etp_pixfmt_bgr24:
266)                     dest[0] = p_distri->mapping[0].table[src[2]];
267)                     dest[1] = p_distri->mapping[1].table[src[1]];
268)                     dest[2] = p_distri->mapping[2].table[src[0]];
269)                     break;
270)                   case etp_pixfmt_mono8:
271)                     val = p_distri->mapping[0].table[src[0]];
272)                     dest[0] = val;
273)                     dest[1] = val;
274)                     dest[2] = val;
275)                     break;
276)                   default:
277)                     dest[0] = 0;
278)                     dest[1] = 0;
279)                     dest[2] = 0;
280)                 }
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

281)                 break;
Stefan Schuermans add support for monochrome...

Stefan Schuermans authored 6 years ago

282)             } /* switch channels */
283)           } /* if */
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

284) 
Stefan Schuermans add support for monochrome...

Stefan Schuermans authored 6 years ago

285)           dest += p_distri->channels;
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

286)         } /* for (pix ...) */
287)       } /* for (out ...) */
288) 
289)     } /* if (p_distri) */
290)   } /* for (distri ...) */
291) }
292) 
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

293) /**
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

294)  * \brief set image data to output on EtherPix display
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

295)  *
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

296)  * see etp_display_data_fmt for documentation
297)  * pixfmt is fixed to etp_pixfmt_rgb24
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

298)  */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

299) void etp_display_data(etp_display_t *p_display, etp_u8_t *p_data,
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

300)                       int stride_x, int stride_y,
301)                       unsigned int x, unsigned int y,
302)                       unsigned int width, unsigned int height)
303) {
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

304)   etp_display_data_fmt(p_display, p_data, stride_x, stride_y,
305)                        x, y, width, height, etp_pixfmt_rgb24);
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

306) }
307) 
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

308) /**
309)  * \brief send image data to distributors
310)  *
311)  * sends the currently stored image data to all configured distributors
312)  *
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

313)  * \param[in] p_display pointer to EtherPix display
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

314)  */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

315) void etp_display_send(etp_display_t *p_display)
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

316) {
Stefan Schuermans support multiple addresses...

Stefan Schuermans authored 7 years ago

317)   unsigned int distri, addr_i;
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

318)   etp_distri_t *p_distri;
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

319) 
320)   /* send data to all distributors */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

321)   for (distri = 0; distri < ETP_DISTRI_MAX_CNT; distri++) {
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

322)     p_distri = p_display->distri_ptrs[distri];
323)     if (p_distri) {
324) 
Stefan Schuermans support multiple addresses...

Stefan Schuermans authored 7 years ago

325)       /* send message as UDP packet to each address */
326)       for (addr_i = 0; addr_i < p_distri->addr_cnt; ++addr_i) {
327)         sendto(p_display->sock,
328)                (char *)p_distri->p_msg_buf, p_distri->msg_len, 0,
329)                (struct sockaddr *)&p_distri->addrs[addr_i],
330)                sizeof (p_distri->addrs[addr_i]));
331)       } /* for (addr_i ...) */