BlinkenArea - GitList
Repositories
Blog
Wiki
BlinkenLib
Code
Commits
Branches
Tags
Search
Tree:
e08c7c5
Branches
Tags
master
v0.1
v0.2
v0.3
v0.3.1
v0.4
v0.4.1
v0.5
v0.5.1
v0.5.2
v0.5.3
v0.5.4
v0.5.5
v0.6.0
v0.6.1
v0.6.2
v0.6.3
v0.6.4
v0.6.5
v0.6.6
v0.6.7
v0.6.8
v0.6.9
v0.7.0
v0.7.1
v0.7.10
v0.7.2
v0.7.3
v0.7.4
v0.7.5
v0.7.6
v0.7.7
v0.7.8
v0.7.9
v0.8.0
v0.8.1
BlinkenLib
BlinkenLib
BlinkenFrame.c
implemented copying rectangular section
Stefan Schuermans
commited
e08c7c5
at 2011-10-16 14:44:35
BlinkenFrame.c
Blame
History
Raw
/* BlinkenLib Copyright 2004-2011 Stefan Schuermans <stefan@blinkenarea.org> Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html a blinkenarea.org project */ #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32 #include <winsock2.h> #include <windows.h> typedef WORD uint16_t; typedef DWORD uint32_t; #else #include <stdint.h> #include <netinet/in.h> #endif #include <BlinkenLib/BlinkenConstants.h> #include <BlinkenLib/BlinkenColorizer.h> #include <BlinkenLib/BlinkenFrame.h> #include <BlinkenLib/Tools.h> struct sBlinkenFrame { int height; int width; int channels; int maxval; int duration; unsigned char **ppData; }; // blinken protocol headers typedef struct sBlinkenProtoBlpHdr { uint32_t magic; uint32_t frameNo; uint16_t width; uint16_t height; } stBlinkenProtoBlpHdr; #define BlinkenProtoBlpMagic 0xDEADBEEF typedef struct sBlinkenProtoEblpHdr { uint32_t magic; uint32_t frameNo; uint16_t width; uint16_t height; } stBlinkenProtoEblpHdr; #define BlinkenProtoEblpMagic 0xFEEDBEEF typedef struct sBlinkenProtoMcufHdr { uint32_t magic; uint16_t height; uint16_t width; uint16_t channels; uint16_t maxval; } stBlinkenProtoMcufHdr; #define BlinkenProtoMcufMagic 0x23542666 stBlinkenFrame *BlinkenFrameNew(int height, int width, int channels, int maxval, int duration) { stBlinkenFrame *pFrame; if (height < BlinkenHeightMin) height = BlinkenHeightMin; if (height > BlinkenHeightMax) height = BlinkenHeightMax; if (width < BlinkenWidthMin) width = BlinkenWidthMin; if (width > BlinkenWidthMax) width = BlinkenWidthMax; if (channels < BlinkenChannelsMin) channels = BlinkenChannelsMin; if (channels > BlinkenChannelsMax) channels = BlinkenMaxvalMax; if (maxval < BlinkenMaxvalMin) maxval = BlinkenMaxvalMin; if (maxval > BlinkenMaxvalMax) maxval = BlinkenMaxvalMax; if (duration < BlinkenDurationMin) duration = BlinkenDurationMin; if (duration > BlinkenDurationMax) duration = BlinkenDurationMax; pFrame = (stBlinkenFrame *) malloc(sizeof(stBlinkenFrame)); if (pFrame == NULL) return NULL; pFrame->height = height; pFrame->width = width; pFrame->channels = channels; pFrame->maxval = maxval; pFrame->duration = duration; pFrame->ppData = (unsigned char **)malloc2D(height, width * channels, sizeof(unsigned char)); if (pFrame->ppData == NULL) { free(pFrame); return NULL; } return pFrame; } stBlinkenFrame *BlinkenFrameClone(stBlinkenFrame *pSrcFrame) { int y, x, c, i; stBlinkenFrame *pFrame; if (pSrcFrame == NULL) return NULL; pFrame = BlinkenFrameNew(pSrcFrame->height, pSrcFrame->width, pSrcFrame->channels, pSrcFrame->maxval, pSrcFrame->duration); if (pFrame == NULL) return NULL; for (y = 0; y < pFrame->height; y++) for (x = 0, i = 0; x < pFrame->width; x++) for (c = 0; c < pFrame->channels; c++, i++) pFrame->ppData[y][i] = pSrcFrame->ppData[y][i]; return pFrame; } void BlinkenFrameFree(stBlinkenFrame *pFrame) { if (pFrame == NULL) return; free(pFrame->ppData); free(pFrame); } void BlinkenFrameClear(stBlinkenFrame *pFrame) { int y, x, c, i; if (pFrame == NULL) return; for (y = 0; y < pFrame->height; y++) for (x = 0, i = 0; x < pFrame->width; x++) for (c = 0; c < pFrame->channels; c++, i++) pFrame->ppData[y][i] = 0; } int BlinkenFrameGetHeight(stBlinkenFrame *pFrame) { if (pFrame == NULL) return 0; return pFrame->height; } int BlinkenFrameGetWidth(stBlinkenFrame *pFrame) { if (pFrame == NULL) return 0; return pFrame->width; } int BlinkenFrameGetChannels(stBlinkenFrame *pFrame) { if (pFrame == NULL) return 0; return pFrame->channels; } int BlinkenFrameGetMaxval(stBlinkenFrame *pFrame) { if (pFrame == NULL) return 0; return pFrame->maxval; } int BlinkenFrameGetDuration(stBlinkenFrame *pFrame) { if (pFrame == NULL) return 0; return pFrame->duration; } void BlinkenFrameSetDuration(stBlinkenFrame *pFrame, int duration) { if (pFrame == NULL) return; if (duration < BlinkenDurationMin) duration = BlinkenDurationMin; if (duration > BlinkenDurationMax) duration = BlinkenDurationMax; pFrame->duration = duration; } unsigned char BlinkenFrameGetPixel(stBlinkenFrame *pFrame, int y, int x, int c) { if (pFrame == NULL || y < 0 || y >= pFrame->height || x < 0 || x >= pFrame->width || c < 0 || c >= pFrame->channels) return 0; return pFrame->ppData[y][x * pFrame->channels + c]; } void BlinkenFrameSetPixel(stBlinkenFrame *pFrame, int y, int x, int c, unsigned char val) { if (pFrame == NULL || y < 0 || y >= pFrame->height || x < 0 || x >= pFrame->width || c < 0 || c >= pFrame->channels) return; if (val > pFrame->maxval) val = pFrame->maxval; pFrame->ppData[y][x * pFrame->channels + c] = val; } unsigned long BlinkenFrameGetColor(stBlinkenFrame *pFrame, int y, int x) { int i; if (pFrame == NULL || y < 0 || y >= pFrame->height || x < 0 || x >= pFrame->width) return 0; i = x * pFrame->channels; if (pFrame->channels == 1) return (((unsigned long)pFrame->ppData[y][i + 0] * 255 + pFrame->maxval / 2) / pFrame-> maxval) << 16 | (((unsigned long)pFrame->ppData[y][i + 0] * 255 + pFrame->maxval / 2) / pFrame->maxval) << 8 | (((unsigned long) pFrame->ppData[y][i + 0] * 255 + pFrame->maxval / 2) / pFrame->maxval); if (pFrame->channels == 2) return (((unsigned long)pFrame->ppData[y][i + 0] * 255 + pFrame->maxval / 2) / pFrame-> maxval) << 16 | (((unsigned long)pFrame->ppData[y][i + 1] * 255 + pFrame->maxval / 2) / pFrame->maxval) << 8; return (((unsigned long)pFrame->ppData[y][i + 0] * 255 + pFrame->maxval / 2) / pFrame->maxval) << 16 | (((unsigned long)pFrame->ppData[y][i + 1] * 255 + pFrame->maxval / 2) / pFrame->maxval) << 8 | (((unsigned long) pFrame->ppData[y] [i + 2] * 255 + pFrame->maxval / 2) / pFrame->maxval); } void BlinkenFrameSetColor(stBlinkenFrame *pFrame, int y, int x, unsigned long color) { int i, alpha, alpha_, c; if (pFrame == NULL || y < 0 || y >= pFrame->height || x < 0 || x >= pFrame->width) return; i = x * pFrame->channels; alpha = (color >> 24) & 0xFF; alpha_ = 255 - alpha; if (pFrame->channels >= 1) pFrame->ppData[y][i + 0] = (unsigned char)((((((color >> 16) & 0xFF) * pFrame->maxval + 127) / 255) * alpha + (unsigned long)pFrame->ppData[y][i + 0] * alpha_) / 255); if (pFrame->channels >= 2) pFrame->ppData[y][i + 1] = (unsigned char)((((((color >> 8) & 0xFF) * pFrame->maxval + 127) / 255) * alpha + (unsigned long)pFrame->ppData[y][i + 1] * alpha_) / 255); if (pFrame->channels >= 3) pFrame->ppData[y][i + 2] = (unsigned char)(((((color & 0xFF) * pFrame->maxval + 127) / 255) * alpha + (unsigned long)pFrame->ppData[y][i + 2] * alpha_) / 255); for (c = 3; c < pFrame->channels; c++) pFrame->ppData[y][i + c] = (unsigned char)((0 + (unsigned long) pFrame->ppData[y][i + c] * alpha_) / 255); } int BlinkenFrameIsEmpty(stBlinkenFrame *pFrame) // returns 1 if frame is empty (i.e. black), returns 0 otherwise { int y, x, c, i; if (pFrame == NULL) return 0; for (y = 0; y < pFrame->height; y++) { for (x = 0, i = 0; x < pFrame->width; x++) { for (c = 0; c < pFrame->channels; c++, i++) { if (pFrame->ppData[y][i] != 0) break; // pixel is not black -> abort } if (c < pFrame->channels) break; } if (x < pFrame->width) break; } if (y < pFrame->height) return 0; // aborted somewhere -> at least ony pixel is not black else return 1; // not aborted -> all pixels are black } int BlinkenFrameCompare(stBlinkenFrame *pFrame1, stBlinkenFrame *pFrame2) // returns -1 for frame1 smaller, 0 for equal, 1 for frame2 smaller { int y, cmp; if (pFrame1->height < pFrame2->height) return -1; if (pFrame1->height > pFrame2->height) return 1; if (pFrame1->width < pFrame2->width) return -1; if (pFrame1->width > pFrame2->width) return 1; if (pFrame1->channels < pFrame2->channels) return -1; if (pFrame1->channels > pFrame2->channels) return 1; if (pFrame1->maxval < pFrame2->maxval) return -1; if (pFrame1->maxval > pFrame2->maxval) return 1; for (y = 0; y < pFrame1->height; y++) { cmp = memcmp(pFrame1->ppData[y], pFrame2->ppData[y], pFrame1->width * pFrame2->channels); if (cmp != 0) return cmp; } return 0; } void BlinkenFrameResize(stBlinkenFrame *pFrame, int height, int width, int channels, int maxval) { unsigned char **ppData; int y, x, c, i, j; int emptyY, emptyX, skipY, skipX, rangeY, rangeX; unsigned long val, div; if (pFrame == NULL) return; if (height < BlinkenHeightMin) height = BlinkenHeightMin; if (height > BlinkenHeightMax) height = BlinkenHeightMax; if (width < BlinkenWidthMin) width = BlinkenWidthMin; if (width > BlinkenWidthMax) width = BlinkenWidthMax; if (channels < BlinkenChannelsMin) channels = BlinkenChannelsMin; if (channels > BlinkenChannelsMax) channels = BlinkenMaxvalMax; if (maxval < BlinkenMaxvalMin) maxval = BlinkenMaxvalMin; if (maxval > BlinkenMaxvalMax) maxval = BlinkenMaxvalMax; if (height == pFrame->height && width == pFrame->width && channels == pFrame->channels && maxval == pFrame->maxval) return; // allocate new data array ppData = (unsigned char **)malloc2D(height, width * channels, sizeof(unsigned char)); if (ppData == NULL) return; for (y = 0; y < height; y++) for (x = 0, i = 0; x < width; x++) for (c = 0; c < channels; c++, i++) ppData[y][i] = 0; // get number of pixels to skip / to leave empty in X and Y direction if (height > pFrame->height) { emptyY = (height - pFrame->height) / 2; skipY = 0; rangeY = pFrame->height; } else { emptyY = 0; skipY = (pFrame->height - height) / 2; rangeY = height; } if (width > pFrame->width) { emptyX = (width - pFrame->width) / 2; skipX = 0; rangeX = pFrame->width; } else { emptyX = 0; skipX = (pFrame->width - width) / 2; rangeX = width; } // resize frame with help of calculated parameters for (y = 0; y < rangeY; y++) { for (x = 0; x < rangeX; x++) { i = (skipX + x) * pFrame->channels; j = (emptyX + x) * channels; if (channels >= pFrame->channels) // add channels: copy last channel // into new channels { for (c = 0; c < pFrame->channels; c++, i++, j++) ppData[emptyY + y][j] = (unsigned char)(((unsigned long)pFrame->ppData[skipY + y][i] * maxval + pFrame->maxval / 2) / pFrame->maxval); for (; c < channels; c++, j++) ppData[emptyY + y][j] = ppData[emptyY + y][j - 1]; } else // remove channels: merge leftover channels with last kept // channel { val = 0; for (c = 0; c < channels - 1; c++, i++, j++) ppData[emptyY + y][j] = (unsigned char)(((unsigned long)pFrame->ppData[skipY + y][i] * maxval + pFrame->maxval / 2) / pFrame->maxval); for (c = channels - 1; c < pFrame->channels; c++, i++) val += (unsigned long)pFrame->ppData[skipY + y][i]; div = pFrame->maxval * (pFrame->channels - channels + 1); ppData[emptyY + y][j++] = (unsigned char)((val * maxval + div / 2) / div); } } } pFrame->height = height; pFrame->width = width; pFrame->channels = channels; pFrame->maxval = maxval; free(pFrame->ppData); pFrame->ppData = ppData; } void BlinkenFrameScale(stBlinkenFrame *pFrame, int height, int width) { unsigned char **ppData; double scaleHor, scaleVer, ox, oy, ox1, oy1, val; int chans, c, nx, ny, x, y, oxi, oyi, ox1i, oy1i; if (pFrame == NULL) return; if (height < BlinkenHeightMin) height = BlinkenHeightMin; if (height > BlinkenHeightMax) height = BlinkenHeightMax; if (width < BlinkenWidthMin) width = BlinkenWidthMin; if (width > BlinkenWidthMax) width = BlinkenWidthMax; if (height == pFrame->height && width == pFrame->width) return; scaleHor = (double)width / (double)pFrame->width; scaleVer = (double)height / (double)pFrame->height; // allocate new data array ppData = (unsigned char **)malloc2D(height, width * pFrame->channels, sizeof(unsigned char)); if (ppData == NULL) return; // scale every channel chans = pFrame->channels; for (c = 0; c < chans; c++) { for (ny = 0; ny < height; ny++) { for (nx = 0; nx < width; nx++) { oy = (double)ny / scaleVer; // sub-pixel exact range in old // picture ox = (double)nx / scaleHor; oy1 = (double)(ny + 1) / scaleVer - 0.000001; ox1 = (double)(nx + 1) / scaleHor - 0.000001; if (oy < 0 || ox < 0 || oy1 >= pFrame->height || ox1 >= pFrame->width) // out // // // // // // of // old // picture ppData[ny][nx * chans + c] = 0; else { oyi = (int)oy; oxi = (int)ox; oy1i = (int)oy1; ox1i = (int)ox1; if (oyi == oy1i) { if (oxi == ox1i) // one source pixel { val = (double)pFrame->ppData[oyi][oxi * chans + c]; } else // one line of source pixels { val = (double)pFrame->ppData[oyi][oxi * chans + c] * (1 - ox + oxi) + (double)pFrame->ppData[oyi][ox1i * chans + c] * (ox1 - ox1i); for (x = oxi + 1; x < ox1i; x++) val += (double)pFrame->ppData[oyi][x * chans + c]; val /= ox1 - ox; } } else // one column of source pixels { if (oxi == ox1i) { val = (double)pFrame->ppData[oyi][oxi * chans + c] * (1 - oy + oyi) + (double)pFrame->ppData[oy1i][oxi * chans + c] * (oy1 - oy1i); for (y = oyi + 1; y < oy1i; y++) val += (double)pFrame->ppData[y][oxi * chans + c]; val /= oy1 - oy; } else // rectangle of source pixels { val = (double)pFrame->ppData[oyi][oxi * chans + c] * (1 - oy + oyi) * (1 - ox + oxi) + (double)pFrame->ppData[oyi][ox1i * chans + c] * (1 - oy + oyi) * (ox1 - ox1i) + (double)pFrame->ppData[oy1i][oxi * chans + c] * (oy1 - oy1i) * (1 - ox + oxi) + (double)pFrame->ppData[oy1i][ox1i * chans + c] * (oy1 - oy1i) * (ox1 - ox1i); for (y = oyi + 1; y < oy1i; y++) { val += (double)pFrame->ppData[y][oxi * chans + c] * (1 - ox + oxi) + (double)pFrame->ppData[y][ox1i * chans + c] * (ox1 - ox1i); } for (x = oxi + 1; x < ox1i; x++) { val += (double)pFrame->ppData[oyi][x * chans + c] * (1 - oy + oyi) + (double)pFrame->ppData[oy1i][x * chans + c] * (oy1 - oy1i); } for (y = oyi + 1; y < oy1i; y++) for (x = oxi + 1; x < ox1i; x++) val += (double)pFrame->ppData[y][x * chans + c]; val /= (oy1 - oy) * (ox1 - ox); } } ppData[ny][nx * chans + c] = (unsigned char)(val + 0.5); } } // for( nx ... } // for( ny ... } // for( c ... pFrame->height = height; pFrame->width = width; free(pFrame->ppData); pFrame->ppData = ppData; } void BlinkenFrameColorize(stBlinkenFrame *pFrame, int channels, int mode, int step) { unsigned char **ppData; int y, x, c, i, j; unsigned int val; if (pFrame == NULL) return; if (channels < BlinkenChannelsMin) channels = BlinkenChannelsMin; if (channels > BlinkenChannelsMax) channels = BlinkenMaxvalMax; // allocate new data array ppData = (unsigned char **)malloc2D(pFrame->height, pFrame->width * channels, sizeof(unsigned char)); if (ppData == NULL) return; for (y = 0; y < pFrame->height; y++) for (x = 0, i = 0; x < pFrame->width; x++) for (c = 0; c < channels; c++, i++) ppData[y][i] = 0; // colorize frame for (y = 0; y < pFrame->height; y++) { for (x = 0; x < pFrame->width; x++) { i = x * pFrame->channels; // merge channels val = 0; for (c = 0; c < pFrame->channels; c++, i++) val += pFrame->ppData[y][i]; val = (val + pFrame->channels / 2) / pFrame->channels; val = (val * BlinkenMaxvalMax + pFrame->maxval / 2) / pFrame->maxval; // colorize j = x * channels; for (c = 0; c < channels; c++, j++) { int color = BlinkenColorizerGetColor(channels, mode, step, y, x, c); ppData[y][j] = (unsigned char)((val * color + 127) / 255); } } } pFrame->channels = channels; pFrame->maxval = BlinkenMaxvalMax; free(pFrame->ppData); pFrame->ppData = ppData; } void BlinkenFrameCopyRect(stBlinkenFrame *pDest, int destY, int destX, stBlinkenFrame *pSrc, int srcY, int srcX, int height, int width) { int bFreeSrc = 0; int destI, srcI, y, x, c, dy, sy, di, si; if (pDest == NULL || pSrc == NULL) return; // make sure source frame matches dest frame in channels and maxval if (pSrc->channels != pDest->channels || pSrc->maxval != pDest->maxval) { pSrc = BlinkenFrameClone(pSrc); if (pSrc == NULL) return; BlinkenFrameResize(pSrc, pSrc->height, pSrc->width, pDest->channels, pDest->maxval); bFreeSrc = 1; // source is now a temporary copy that needs to be freed } // correct coordinates if (destY < 0) { height += destY; srcY -= destY; destY = 0; } if (destX < 0) { width += destX; srcX -= destX; destX = 0; } if (srcY < 0) { height += srcY; destY -= srcY; srcY = 0; } if (srcX < 0) { width += srcX; destX -= srcX; srcX = 0; } if (height > pDest->height - destY) height = pDest->height - destY; if (width > pDest->width - destX) width = pDest->width - destX; if (height > pSrc->height - srcY) height = pSrc->height - srcY; if (width > pSrc->width - srcX) width = pSrc->width - srcX; if (height < 0) height = 0; if (width < 0) width = 0; // copy rectangular area destI = destX * pDest->channels; srcI = srcX * pSrc->channels; for (y = 0, dy = destY, sy = srcY; y < height; y++, dy++, sy++) for (x = 0, di = destI, si = srcI; x < width; x++) for (c = 0; c < pDest->channels; c++, di++, si++) pDest->ppData[dy][di] = pSrc->ppData[sy][si]; // free source if it is a temporary copy if (bFreeSrc) BlinkenFrameFree(pSrc); } char *BlinkenFrameToString(stBlinkenFrame *pFrame) { int size, y, x, c, i; char *str, *ptr; unsigned long val; if (pFrame == NULL) return NULL; size = pFrame->height * (pFrame->width + 1) + 32; str = (char *)malloc(size); if (str == NULL) return NULL; ptr = str; for (y = 0; y < pFrame->height; y++) { for (x = 0, i = 0; x < pFrame->width; x++) { val = 0; for (val = 0, c = 0; c < pFrame->channels; c++, i++) val += pFrame->ppData[y][i]; val = val * 7 / pFrame->maxval / pFrame->channels; *ptr = " -+*%#&@"[val]; ptr++; } *ptr = '\n'; ptr++; } sprintf(ptr, "%u ms\n", pFrame->duration); return str; } int BlinkenFrameToNetwork(stBlinkenFrame *pFrame, etBlinkenProto proto, char *pData, int maxLength) // returns length or -1 on error { int y, x, c, i, j, val; if (pFrame == NULL) return -1; switch (proto) { case BlinkenProtoNone: return 0; case BlinkenProtoBlp: if (maxLength < (int)sizeof(stBlinkenProtoBlpHdr) + pFrame->height * pFrame->width) // buffer // // // // // // too // short return -1; ((stBlinkenProtoBlpHdr *) pData)->magic = htonl(BlinkenProtoBlpMagic); // build // // // // // // header ((stBlinkenProtoBlpHdr *) pData)->frameNo = htonl(0); ((stBlinkenProtoBlpHdr *) pData)->width = htons((uint16_t) pFrame->width); ((stBlinkenProtoBlpHdr *) pData)->height = htons((uint16_t) pFrame->height); i = sizeof(stBlinkenProtoBlpHdr); // put data into packet for (y = 0; y < pFrame->height; y++) { for (x = 0, j = 0; x < pFrame->width; x++, i++) { val = 0; for (c = 0; c < pFrame->channels; c++, j++) val += pFrame->ppData[y][j]; pData[i] = (val >= pFrame->channels * pFrame->maxval / 2 ? 0x01 : 0x00); } } return i; // return length case BlinkenProtoEblp: if (maxLength < (int)sizeof(stBlinkenProtoEblpHdr) + pFrame->height * pFrame->width) // buffer // // // // // // too // short return -1; ((stBlinkenProtoEblpHdr *) pData)->magic = htonl(BlinkenProtoEblpMagic); // build // // // // // // header ((stBlinkenProtoEblpHdr *) pData)->frameNo = htonl(0); ((stBlinkenProtoEblpHdr *) pData)->width = htons((uint16_t) pFrame->width); ((stBlinkenProtoEblpHdr *) pData)->height = htons((uint16_t) pFrame->height); i = sizeof(stBlinkenProtoEblpHdr); // put data into packet for (y = 0; y < pFrame->height; y++) { for (x = 0, j = 0; x < pFrame->width; x++, i++) { val = 0; for (c = 0; c < pFrame->channels; c++, j++) val += pFrame->ppData[y][j]; val /= pFrame->channels; pData[i] = (pFrame->maxval == 255 ? (unsigned char)val : (unsigned char)((val * 255 + pFrame->maxval / 2) / pFrame->maxval)); } } return i; // return length case BlinkenProtoMcuf: if (maxLength < (int)sizeof(stBlinkenProtoMcufHdr) + pFrame->height * pFrame->width * pFrame->channels) // buffer // // // // // // too // short return -1; ((stBlinkenProtoMcufHdr *) pData)->magic = htonl(BlinkenProtoMcufMagic); // build // // // // // // header ((stBlinkenProtoMcufHdr *) pData)->height = htons((uint16_t) pFrame->height); ((stBlinkenProtoMcufHdr *) pData)->width = htons((uint16_t) pFrame->width); ((stBlinkenProtoMcufHdr *) pData)->channels = htons((uint16_t) pFrame->channels); ((stBlinkenProtoMcufHdr *) pData)->maxval = htons((uint16_t) pFrame->maxval); i = sizeof(stBlinkenProtoMcufHdr); // put data into packet for (y = 0; y < pFrame->height; y++) for (x = 0, j = 0; x < pFrame->width; x++) for (c = 0; c < pFrame->channels; c++, i++, j++) pData[i] = pFrame->ppData[y][j]; return i; // return length default: return -1; } } stBlinkenFrame *BlinkenFrameFromNetwork(char *pData, int length, etBlinkenProto * pProto) // returns protocol in *pProto if pProto not NULL { stBlinkenFrame *pFrame; int height, width, channels, maxval, y, x, c, i, j; if (length >= (int)sizeof(stBlinkenProtoBlpHdr) && ((stBlinkenProtoBlpHdr *) pData)->magic == htonl(BlinkenProtoBlpMagic)) { if (pProto != NULL) // return protocol *pProto = BlinkenProtoBlp; height = ntohs(((stBlinkenProtoBlpHdr *) pData)->height); // get header // // // // // // data width = ntohs(((stBlinkenProtoBlpHdr *) pData)->width); if (length < (int)sizeof(stBlinkenProtoBlpHdr) + height * width) // check // // // // // // length // of // packet return NULL; if (height < BlinkenHeightMin || height > BlinkenHeightMax || // check // // // // // // header // data width < BlinkenWidthMin || width > BlinkenWidthMax) return NULL; pFrame = BlinkenFrameNew(height, width, 1, 1, 0); // create frame // according to // header data if (pFrame == NULL) return NULL; i = sizeof(stBlinkenProtoBlpHdr); // put data into frame for (y = 0; y < pFrame->height; y++) for (x = 0; x < pFrame->width; x++, i++) pFrame->ppData[y][x] = pData[i] ? 0x01 : 0x00; return pFrame; } if (length >= (int)sizeof(stBlinkenProtoEblpHdr) && ((stBlinkenProtoEblpHdr *) pData)->magic == htonl(BlinkenProtoEblpMagic)) { if (pProto != NULL) // return protocol *pProto = BlinkenProtoEblp; height = ntohs(((stBlinkenProtoEblpHdr *) pData)->height); // get header // // // // // // data width = ntohs(((stBlinkenProtoEblpHdr *) pData)->width); if (length < (int)sizeof(stBlinkenProtoEblpHdr) + width * height) // check // // // // // // length // of // packet return NULL; if (height < BlinkenHeightMin || height > BlinkenHeightMax || // check // // // // // // header // data width < BlinkenWidthMin || width > BlinkenWidthMax) return NULL; pFrame = BlinkenFrameNew(height, width, 1, 255, 0); // create frame // according to // header data if (pFrame == NULL) return NULL; i = sizeof(stBlinkenProtoEblpHdr); // put data into frame for (y = 0; y < pFrame->height; y++) for (x = 0; x < pFrame->width; x++, i++) pFrame->ppData[y][x] = pData[i]; return pFrame; } if (length >= (int)sizeof(stBlinkenProtoMcufHdr) && ((stBlinkenProtoMcufHdr *) pData)->magic == htonl(BlinkenProtoMcufMagic)) { if (pProto != NULL) // return protocol *pProto = BlinkenProtoMcuf; height = ntohs(((stBlinkenProtoMcufHdr *) pData)->height); // get header // // // // // // data width = ntohs(((stBlinkenProtoMcufHdr *) pData)->width); channels = ntohs(((stBlinkenProtoMcufHdr *) pData)->channels); maxval = ntohs(((stBlinkenProtoMcufHdr *) pData)->maxval); if (length < (int)sizeof(stBlinkenProtoMcufHdr) + height * width * channels) // check // // // // // // length // of // packet return NULL; if (height < BlinkenHeightMin || height > BlinkenHeightMax || // check // // // // // // header // data width < BlinkenWidthMin || width > BlinkenWidthMax || channels < BlinkenChannelsMin || channels > BlinkenChannelsMax || maxval < BlinkenMaxvalMin || maxval > BlinkenMaxvalMax) return NULL; pFrame = BlinkenFrameNew(height, width, channels, maxval, 0); // create // // // // // // frame // according // to // header // data if (pFrame == NULL) return NULL; i = sizeof(stBlinkenProtoMcufHdr); // put data into frame for (y = 0; y < pFrame->height; y++) for (x = 0, j = 0; x < pFrame->width; x++) for (c = 0; c < pFrame->channels; c++, i++, j++) pFrame->ppData[y][j] = pData[i]; return pFrame; } if (pProto != NULL) // return protocol *pProto = BlinkenProtoNone; return NULL; }