discoverpixy
pixy_frame.c
Go to the documentation of this file.
1 /**************************************************************************************************************************************
2 * Project: discoverpixy
3 * Website: https://github.com/t-moe/discoverpixy
4 * Authors: Aaron Schmocker, Timo Lang
5 * Institution: BFH Bern University of Applied Sciences
6 * File: common/app/pixy_frame.c
7 *
8 * Version History:
9 * Date Autor Email SHA Changes
10 * 2015-06-07 timolang@gmail.com c87220d Renamed pixy_helper to pixy_frame. Updated docu of appliaction. added doxygen comments to pixy_{frame,control}.h
11 *
12 **************************************************************************************************************************************/
13 
14 #include "pixy_frame.h"
15 #include "pixy.h"
16 #include "tft.h"
17 #include <stdlib.h>
18 
19 
20 
21 static int renderBA81(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t* frame);
22 static int saveBA81(FILE_HANDLE* handle, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t* frame);
23 
24 
25 int pixy_render_full_frame(uint16_t x, uint16_t y)
26 {
27  return pixy_render_cropped_frame(x, y, 0, 0, 320, 200);
28 }
29 
30 
31 int pixy_render_cropped_frame(uint16_t x, uint16_t y, uint16_t xoffset, uint16_t yoffset, uint16_t width, uint16_t height)
32 {
33  uint8_t* videodata;
34  int32_t response;
35  int32_t fourccc;
36  int8_t renderflags;
37  uint16_t xwidth;
38  uint16_t ywidth;
39  uint32_t size;
40 
41 
42  int return_value = pixy_command("cam_getFrame", // String id for remote procedure
43  INT8(0x21), // mode
44  INT16(xoffset), // xoffset
45  INT16(yoffset), // yoffset
46  INT16(width), // width
47  INT16(height), // height
48  END_OUT_ARGS, // separator
49  &response, // pointer to mem address for return value
50  &fourccc,
51  &renderflags,
52  &xwidth,
53  &ywidth,
54  &size,
55  &videodata, // pointer to mem address for returned frame
56  END_IN_ARGS);
57 
58  if (return_value == 0) {
59  return_value = renderBA81(x, y, xwidth, ywidth, size, videodata);
60  }
61 
62  return return_value;
63 }
64 
66 {
67  return pixy_save_cropped_frame(handle, 0, 0, 320, 200);
68 }
69 
70 int pixy_save_cropped_frame(FILE_HANDLE* handle, uint16_t xoffset, uint16_t yoffset, uint16_t width, uint16_t height)
71 {
72  uint8_t* videodata;
73  int32_t response;
74  int32_t fourccc;
75  int8_t renderflags;
76  uint16_t xwidth;
77  uint16_t ywidth;
78  uint32_t size;
79 
80 
81  int return_value = pixy_command("cam_getFrame", // String id for remote procedure
82  INT8(0x21), // mode
83  INT16(xoffset), // xoffset
84  INT16(yoffset), // yoffset
85  INT16(width), // width
86  INT16(height), // height
87  END_OUT_ARGS, // separator
88  &response, // pointer to mem address for return value
89  &fourccc,
90  &renderflags,
91  &xwidth,
92  &ywidth,
93  &size,
94  &videodata, // pointer to mem address for returned frame
95  END_IN_ARGS);
96 
97  if (return_value == 0) {
98  return_value = saveBA81(handle, xwidth, ywidth, size, videodata);
99  }
100 
101  return return_value;
102 }
103 
104 
105 
106 
107 
108 static void interpolateBayer(uint16_t width, uint16_t x, uint16_t y, uint8_t* pixel, uint8_t* r, uint8_t* g, uint8_t* b)
109 {
110  if (y & 1) {
111  if (x & 1) {
112  *r = *pixel;
113  *g = (*(pixel - 1) + * (pixel + 1) + * (pixel + width) + * (pixel - width)) >> 2;
114  *b = (*(pixel - width - 1) + * (pixel - width + 1) + * (pixel + width - 1) + * (pixel + width + 1)) >> 2;
115  } else {
116  *r = (*(pixel - 1) + * (pixel + 1)) >> 1;
117  *g = *pixel;
118  *b = (*(pixel - width) + * (pixel + width)) >> 1;
119  }
120  } else {
121  if (x & 1) {
122  *r = (*(pixel - width) + * (pixel + width)) >> 1;
123  *g = *pixel;
124  *b = (*(pixel - 1) + * (pixel + 1)) >> 1;
125  } else {
126  *r = (*(pixel - width - 1) + * (pixel - width + 1) + * (pixel + width - 1) + * (pixel + width + 1)) >> 2;
127  *g = (*(pixel - 1) + * (pixel + 1) + * (pixel + width) + * (pixel - width)) >> 2;
128  *b = *pixel;
129  }
130  }
131 
132 }
133 
134 
135 
136 
137 
138 
139 static int renderBA81(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t* frame)
140 {
141  uint16_t x, y;
142  uint8_t r, g, b;
143 
144 
145  // skip first line
146  frame += width;
147 
148  // don't render top and bottom rows, and left and rightmost columns because of color
149  // interpolation
150  //uint32_t decodedimage[(width-2)*(height-2)];
151  uint16_t* decodedimage = malloc(sizeof(uint16_t) * (width - 2) * (height - 2));
152 
153  if (decodedimage == NULL) { //not enough free space to decode image in memory
154  //decode & render image pixel by pixel
155  for (y = 1; y < height - 1; y++) {
156  frame++;
157 
158  for (x = 1; x < width - 1; x++, frame++) {
159  interpolateBayer(width, x, y, frame, &r, &g, &b);
160  tft_draw_pixel(xpos + x - 1, ypos + y - 1, RGB(r, g, b));
161  }
162 
163  frame++;
164  }
165  } else { //enough space
166  uint16_t* line = decodedimage;
167 
168  for (y = 1; y < height - 1; y++) {
169  //line = (unsigned int *)img.scanLine(y-1);
170  frame++;
171 
172  for (x = 1; x < width - 1; x++, frame++) {
173  interpolateBayer(width, x, y, frame, &r, &g, &b);
174  //*line++ = (0xff<<24) | (r<<16) | (g<<8) | (b<<0);
175  *line++ = RGB(r, g, b);
176  }
177 
178  frame++;
179  }
180 
181  tft_draw_bitmap_unscaled(xpos, ypos, width - 2, height - 2, decodedimage);
182 
183  free(decodedimage);
184  }
185 
186  return 0;
187 }
188 
189 static int saveBA81(FILE_HANDLE* handle, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t* frame)
190 {
191  uint16_t x, y;
192  uint8_t r, g, b;
193 
194  uint32_t fpos = handle->fpos;
195  uint32_t row_size_padded = ((width - 2) * 3 + 3) & (~3); //row size aligned to 4 bytes
196  uint32_t fpos_end = fpos + row_size_padded * (height - 2);
197 
198 
199  // skip first line
200  frame += width;
201 
202  // don't render top and bottom rows, and left and rightmost columns because of color
203  // interpolation
204 
205  for (y = 1; y < height - 1; y++) {
206  frame++;
207  uint8_t rowbuf[row_size_padded];
208 
209  //Bitmaps are saved "bottom-up". Seek to the right row.
210  if (filesystem_file_seek(handle, fpos_end - row_size_padded * y) != F_OK) {
211  return -1;
212  }
213 
214  for (x = 1; x < width - 1; x++, frame++) {
215  interpolateBayer(width, x, y, frame, &r, &g, &b);
216  //bitmaps are saved in 24bit b,g,r format
217  rowbuf[(x - 1) * 3] = b;
218  rowbuf[(x - 1) * 3 + 1] = g;
219  rowbuf[(x - 1) * 3 + 2] = r;
220  }
221 
222  if (filesystem_file_write(handle, rowbuf, row_size_padded) != F_OK) {
223  return -1;
224  }
225 
226  frame++;
227  }
228 
229  return 0;
230 }
231 
232 
233 int pixy_cc_set_region(uint8_t signum, uint16_t xoffset, uint16_t yoffset, uint16_t width, uint16_t height)
234 {
235  int32_t response;
236 
237  int return_value = pixy_command("cc_setSigRegion", // String id for remote procedure
238  INT32(0), // type = normal color code
239  INT8(signum),
240  INT16(xoffset), // xoffset
241  INT16(yoffset), // yoffset
242  INT16(width), // width
243  INT16(height), // height
244  END_OUT_ARGS, // separator
245  &response, // pointer to mem address for return value
246  END_IN_ARGS);
247  return return_value;
248 }
FILE_STATUS filesystem_file_seek(FILE_HANDLE *handle, uint32_t offset)
Definition: filesystem.c:43
static int renderBA81(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t *frame)
Definition: pixy_frame.c:139
static int saveBA81(FILE_HANDLE *handle, uint16_t width, uint16_t height, uint32_t frameLen, uint8_t *frame)
Definition: pixy_frame.c:189
#define RGB(r, g, b)
Definition: tft.h:48
#define INT16(v)
Definition: pixydefs.h:63
#define INT32(v)
Definition: pixydefs.h:65
int pixy_save_cropped_frame(FILE_HANDLE *handle, uint16_t xoffset, uint16_t yoffset, uint16_t width, uint16_t height)
Definition: pixy_frame.c:70
int pixy_save_full_frame(FILE_HANDLE *handle)
Definition: pixy_frame.c:65
int pixy_render_cropped_frame(uint16_t x, uint16_t y, uint16_t xoffset, uint16_t yoffset, uint16_t width, uint16_t height)
Definition: pixy_frame.c:31
void tft_draw_bitmap_unscaled(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t *dat)
Definition: tft.c:72
static void interpolateBayer(uint16_t width, uint16_t x, uint16_t y, uint8_t *pixel, uint8_t *r, uint8_t *g, uint8_t *b)
Definition: pixy_frame.c:108
void tft_draw_pixel(uint16_t x, uint16_t y, uint16_t color)
Definition: tft.c:56
int pixy_command(const char *name,...)
Send a command to Pixy.
FILE_STATUS filesystem_file_write(FILE_HANDLE *handle, uint8_t *buf, uint32_t size)
Definition: filesystem.c:53
uint32_t fpos
The current byte-position in the file.
Definition: filesystem.h:83
#define END_OUT_ARGS
Definition: pixydefs.h:89
Everything ok.
Definition: filesystem.h:91
int pixy_render_full_frame(uint16_t x, uint16_t y)
Definition: pixy_frame.c:25
int pixy_cc_set_region(uint8_t signum, uint16_t xoffset, uint16_t yoffset, uint16_t width, uint16_t height)
Definition: pixy_frame.c:233
#define END_IN_ARGS
Definition: pixydefs.h:90
#define INT8(v)
Definition: pixydefs.h:61