implement getting/setting pixel data
Stefan Schuermans

Stefan Schuermans commited on 2019-05-30 18:29:21
Showing 3 changed files, with 115 additions and 1 deletions.

... ...
@@ -40,6 +40,36 @@ unsigned long BlinkenFrameGetColor(stBlinkenFrame *pFrame, int y, int x);
40 40
 void BlinkenFrameSetColor(stBlinkenFrame *pFrame, int y, int x,
41 41
                           unsigned long color);
42 42
 
43
+/**
44
+ * get data of an rectangular area of pixels
45
+ * \param[in] pFrame BlinkenFrame to read
46
+ * \param[in] y first y coordinate of area
47
+ * \param[in] dy size of area in y direction
48
+ * \param[in] x first x coordinate of area
49
+ * \param[in] dx size of area in x direction
50
+ * \param[in] c first channel of area
51
+ * \param[in] dc number of channels in area
52
+ * \param[in] pData pointer to buffer for pixel data, size must be dy * dx * dc
53
+ */
54
+void BlinkenFrameGetPixelData(stBlinkenFrame const *pFrame,
55
+                              int y, int dy, int x, int dx, int c, int dc,
56
+                              unsigned char *pData);
57
+
58
+/**
59
+ * set data of an rectangular area of pixels
60
+ * \param[in] pFrame BlinkenFrame to modify
61
+ * \param[in] y first y coordinate of area
62
+ * \param[in] dy size of area in y direction
63
+ * \param[in] x first x coordinate of area
64
+ * \param[in] dx size of area in x direction
65
+ * \param[in] c first channel of area
66
+ * \param[in] dc number of channels in area
67
+ * \param[in] pData pointer to new pixel data, size must be dy * dx * dc
68
+ */
69
+void BlinkenFrameSetPixelData(stBlinkenFrame *pFrame,
70
+                              int y, int dy, int x, int dx, int c, int dc,
71
+                              unsigned char const *pData);
72
+
43 73
 int BlinkenFrameIsEmpty(stBlinkenFrame *pFrame);
44 74
 // returns 1 if frame is empty (i.e. black), returns 0 otherwise
45 75
 
... ...
@@ -280,6 +280,90 @@ void BlinkenFrameSetColor(stBlinkenFrame *pFrame, int y, int x,
280 280
                                                 alpha_) / 255);
281 281
 }
282 282
 
283
+void BlinkenFrameGetPixelData(stBlinkenFrame const *pFrame,
284
+                              int y, int dy, int x, int dx, int c, int dc,
285
+                              unsigned char *pData)
286
+{
287
+  int height, width, channels;
288
+  unsigned char const **ppFrameData;
289
+  int sy, ey, iy, sx, ex, ix, sc, ec, ic; // start/end/index x/y/channel
290
+  int fy, fix, fic; // indexes into frame data
291
+  int biy, bix, bic; // index into caller's data buffer
292
+
293
+  // no frame -> leave
294
+  if (pFrame == NULL) {
295
+    return;
296
+  }
297
+
298
+  height = pFrame->height;
299
+  width = pFrame->width;
300
+  channels = pFrame->channels;
301
+  ppFrameData = (unsigned char const **)pFrame->ppData;
302
+
303
+  // compute start and end for each coordinate
304
+  sy = y < 0 ? -y : 0;
305
+  ey = y + dy > height ? height - y : dy;
306
+  sx = x < 0 ? -x : 0;
307
+  ex = x + dx > width ? width - x : dx;
308
+  sc = c < 0 ? -c : 0;
309
+  ec = c + dc > channels ? channels - c : dc;
310
+
311
+  // get pixel data
312
+  for (iy = sy, fy = y, biy = (sy * dx + sx) * dc + sc;
313
+       iy < ey; ++iy, ++fy, biy += dx * dc) {
314
+    for (ix = sx, fix = x * channels + c, bix = biy;
315
+         ix < ex; ++ix, fix += channels, bix += dc) {
316
+      for (ic = sc, fic = fix, bic = bix; ic < ec; ++ic, ++fic, ++bic) {
317
+        pData[bic] = ppFrameData[fy][fic];
318
+      }
319
+    }
320
+  }
321
+}
322
+
323
+void BlinkenFrameSetPixelData(stBlinkenFrame *pFrame,
324
+                              int y, int dy, int x, int dx, int c, int dc,
325
+                              unsigned char const *pData)
326
+{
327
+  int height, width, channels;
328
+  unsigned char maxval;
329
+  unsigned char **ppFrameData;
330
+  int sy, ey, iy, sx, ex, ix, sc, ec, ic; // start/end/index x/y/channel
331
+  int fy, fix, fic; // indexes into frame data
332
+  int biy, bix, bic; // index into caller's data buffer
333
+  unsigned char value;
334
+
335
+  // no frame -> leave
336
+  if (pFrame == NULL) {
337
+    return;
338
+  }
339
+
340
+  height = pFrame->height;
341
+  width = pFrame->width;
342
+  channels = pFrame->channels;
343
+  maxval = pFrame->maxval;
344
+  ppFrameData = pFrame->ppData;
345
+
346
+  // compute start and end for each coordinate
347
+  sy = y < 0 ? -y : 0;
348
+  ey = y + dy > height ? height - y : dy;
349
+  sx = x < 0 ? -x : 0;
350
+  ex = x + dx > width ? width - x : dx;
351
+  sc = c < 0 ? -c : 0;
352
+  ec = c + dc > channels ? channels - c : dc;
353
+
354
+  // set pixel data
355
+  for (iy = sy, fy = y, biy = (sy * dx + sx) * dc + sc;
356
+       iy < ey; ++iy, ++fy, biy += dx * dc) {
357
+    for (ix = sx, fix = x * channels + c, bix = biy;
358
+         ix < ex; ++ix, fix += channels, bix += dc) {
359
+      for (ic = sc, fic = fix, bic = bix; ic < ec; ++ic, ++fic, ++bic) {
360
+        value = pData[bic];
361
+        ppFrameData[fy][fic] = value > maxval ? maxval : value;
362
+      }
363
+    }
364
+  }
365
+}
366
+
283 367
 int BlinkenFrameIsEmpty(stBlinkenFrame *pFrame)
284 368
 // returns 1 if frame is empty (i.e. black), returns 0 otherwise
285 369
 {
... ...
@@ -1,4 +1,4 @@
1 1
 VERSION_MAJOR := 0
2 2
 VERSION_MINOR := 8
3
-VERSION_REVISION := 0
3
+VERSION_REVISION := 1
4 4
 VERSION := $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_REVISION)
5 5