BlinkenArea - GitList
Repositories
Blog
Wiki
BlinkenLib
Code
Commits
Branches
Tags
Search
Tree:
a6637d3
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
Makefile fixed for MAC OS X, removed version information from soure files
Stefan Schuermans
commited
a6637d3
at 2011-09-10 13:38:14
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; } 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; }