f46f6acaf2f8d3e11ddb5f91da2e5462d9527fe7
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

1) /* BlinkenLib
Christian Heimke BlinkenLib v.0.5.3 (2007-12...

Christian Heimke authored 13 years ago

2)  * version 0.5.3 date 2007-12-28
3)  * Copyright 2004-2007 Stefan Schuermans <stefan@schuermans.info>
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

4)  * Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
5)  * a blinkenarea.org project
6)  */
7) 
8) #include <stdio.h>
9) #include <stdlib.h>
10) #include <string.h>
Christian Heimke BlinkenLib v.0.5.2 (2006-05...

Christian Heimke authored 13 years ago

11) #ifdef WIN32
12) #include <winsock2.h>
13) #include <windows.h>
14) #else
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

15) #include <unistd.h>
16) #include <sys/time.h>
17) #include <sys/types.h>
18) #include <sys/socket.h>
19) #include <sys/select.h>
Christian Heimke BlinkenLib v.0.5.2 (2006-05...

Christian Heimke authored 13 years ago

20) #endif
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

21) 
22) #include "BlinkenConstants.h"
23) #include "BlinkenFrame.h"
24) #include "BlinkenMovie.h"
25) #include "Tools.h"
26) 
27) struct sBlinkenMovie
28) {
29)   int height;
30)   int width;
31)   int channels;
32)   int maxval;
33)   int infoCnt;
34)   char * * * pppInfos;
35)   int frameCnt;
36)   stBlinkenFrame * * ppFrames;
37) };
38) 
Christian Heimke BlinkenLib v.0.5.2 (2006-05...

Christian Heimke authored 13 years ago

39) #ifdef WIN32
40) 
41) static void msleep( unsigned int ms )
42) {
43)   Sleep( ms );
44) }
45) 
46) static unsigned int get_ms( )
47) {
48)   return GetTickCount( );
49) }
50) 
51) #else
52) 
53) static void msleep( unsigned int ms )
54) {
55)   usleep( ms * 1000 );
56) }
57) 
58) static unsigned int get_ms( )
59) {
60)   struct timeval tv;
61)   gettimeofday( &tv, NULL );
62)   return (unsigned int)(tv.tv_usec / 1000 + tv.tv_sec * 1000);
63) }
64) 
65) #endif
66) 
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

67) stBlinkenMovie * BlinkenMovieNew( int height, int width, int channels, int maxval )
68) {
69)   stBlinkenMovie * pMovie;
70) 
71)   if( height < BlinkenHeightMin ) height = BlinkenHeightMin;
72)   if( height > BlinkenHeightMax ) height = BlinkenHeightMax;
73)   if( width < BlinkenWidthMin ) width = BlinkenWidthMin;
74)   if( width > BlinkenWidthMax ) width = BlinkenWidthMax;
75)   if( channels < BlinkenChannelsMin ) channels = BlinkenChannelsMin;
76)   if( channels > BlinkenChannelsMax ) channels = BlinkenMaxvalMax;
77)   if( maxval < BlinkenMaxvalMin ) maxval = BlinkenMaxvalMin;
78)   if( maxval > BlinkenMaxvalMax ) maxval = BlinkenMaxvalMax;
79) 
80)   pMovie = (stBlinkenMovie *)malloc( sizeof( stBlinkenMovie ) );
81)   if( pMovie == NULL )
82)     return NULL;
83) 
84)   pMovie->height = height;
85)   pMovie->width = width;
86)   pMovie->channels = channels;
87)   pMovie->maxval = maxval;
88)   pMovie->infoCnt = 0;
89)   pMovie->pppInfos = (char * * *)malloc2D( 0, 2, sizeof( char * ) );
90)   if( pMovie->pppInfos == NULL )
91)   {
92)     free( pMovie );
93)     return NULL;
94)   }
95)   pMovie->frameCnt = 0;
96)   pMovie->ppFrames = (stBlinkenFrame * *)malloc1D( 0, sizeof( stBlinkenFrame * ) );
97)   if( pMovie->ppFrames == NULL )
98)   {
99)     free( pMovie->pppInfos );
100)     free( pMovie );
101)     return NULL;
102)   }
103) 
104)   return pMovie;
105) }
106) 
107) stBlinkenMovie * BlinkenMovieClone( stBlinkenMovie * pSrcMovie )
108) {
109)   stBlinkenMovie * pMovie;
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

110)   stBlinkenFrame * pFrame;
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

111)   int i;
112) 
113)   pMovie = BlinkenMovieNew( pSrcMovie->height, pSrcMovie->width, pSrcMovie->channels, pSrcMovie->maxval );
114)   if( pMovie == NULL )
115)     return NULL;
116) 
117)   for( i = 0; i < pSrcMovie->infoCnt; i++ )
118)     BlinkenMovieAppendInfo( pMovie, pSrcMovie->pppInfos[i][0], pSrcMovie->pppInfos[i][1] );
119) 
120)   for( i = 0; i < pSrcMovie->frameCnt; i++ )
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

121)   {
122)     pFrame = BlinkenFrameClone( pSrcMovie->ppFrames[i] );
123)     if( BlinkenMovieAppendFrame( pMovie, pFrame ) != 0 )
124)       BlinkenFrameFree( pFrame );
125)   }
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

126) 
127)   return pMovie;
128) }
129) 
130) void BlinkenMovieFree( stBlinkenMovie * pMovie )
131) {
132)   int i;
133) 
134)   if( pMovie == NULL )
135)     return;
136) 
137)   for( i = 0; i < pMovie->infoCnt; i++ )
138)   {
139)     free( pMovie->pppInfos[i][0] );
140)     free( pMovie->pppInfos[i][1] );
141)   }
142)   free( pMovie->pppInfos );
143) 
144)   for( i = 0; i < pMovie->frameCnt; i++ )
145)     BlinkenFrameFree( pMovie->ppFrames[i] );
146)   free( pMovie->ppFrames );
147) 
148)   free( pMovie );
149) }
150) 
151) int BlinkenMovieGetHeight( stBlinkenMovie * pMovie )
152) {
153)   if( pMovie == NULL )
154)     return 0;
155) 
156)   return pMovie->height;
157) }
158) 
159) int BlinkenMovieGetWidth( stBlinkenMovie * pMovie )
160) {
161)   if( pMovie == NULL )
162)     return 0;
163) 
164)   return pMovie->width;
165) }
166) 
167) int BlinkenMovieGetChannels( stBlinkenMovie * pMovie )
168) {
169)   if( pMovie == NULL )
170)     return 0;
171) 
172)   return pMovie->channels;
173) }
174) 
175) int BlinkenMovieGetMaxval( stBlinkenMovie * pMovie )
176) {
177)   if( pMovie == NULL )
178)     return 0;
179) 
180)   return pMovie->maxval;
181) }
182) 
183) int BlinkenMovieGetDuration( stBlinkenMovie * pMovie )
184) {
185)   int i, duration;
186) 
187)   if( pMovie == NULL )
188)     return 0;
189) 
190)   duration = 0;
191)   for( i = 0; i < pMovie->frameCnt; i++ )
192)     duration += BlinkenFrameGetDuration( pMovie->ppFrames[i] );
193)   return duration;
194) }
195) 
196) int BlinkenMovieGetInfoCnt( stBlinkenMovie * pMovie )
197) {
198)   if( pMovie == NULL )
199)     return 0;
200) 
201)   return pMovie->infoCnt;
202) }
203) 
204) char * BlinkenMovieGetInfoType( stBlinkenMovie * pMovie, int infoNo )
205) {
206)   if( pMovie == NULL || pMovie->infoCnt < 1 )
207)     return "";
208) 
209)   if( infoNo < 0 ) infoNo = 0;
210)   if( infoNo >= pMovie->infoCnt ) infoNo = pMovie->infoCnt - 1;
211)   return pMovie->pppInfos[infoNo][0];
212) }
213) 
214) char * BlinkenMovieGetInfoData( stBlinkenMovie * pMovie, int infoNo )
215) {
216)   if( pMovie == NULL || pMovie->infoCnt < 1 )
217)     return "";
218) 
219)   if( infoNo < 0 ) infoNo = 0;
220)   if( infoNo >= pMovie->infoCnt ) infoNo = pMovie->infoCnt - 1;
221)   return pMovie->pppInfos[infoNo][1];
222) }
223) 
224) void BlinkenMovieSetInfo( stBlinkenMovie * pMovie, int infoNo, char * pInfoType, char * pInfoData )
225) {
226)   char * pType, * pData;
227) 
228)   if( pMovie == NULL || infoNo < 0 || infoNo >= pMovie->infoCnt )
229)     return;
230) 
231)   pType = strdup( pInfoType );
232)   if( pType == NULL )
233)     return;
234)   pData = strdup( pInfoData );
235)   if( pData == NULL )
236)   {
237)     free( pType );
238)     return;
239)   }
240) 
241)   free( pMovie->pppInfos[infoNo][0] );
242)   pMovie->pppInfos[infoNo][0] = pType;
243)   free( pMovie->pppInfos[infoNo][1] );
244)   pMovie->pppInfos[infoNo][1] = pData;
245) }
246) 
247) void BlinkenMovieInsertInfo( stBlinkenMovie * pMovie, int infoNo, char * pInfoType, char * pInfoData )
248) {
249)   char * * * pppNewInfos, * pType, * pData;
250)   int i;
251) 
252)   if( pMovie == NULL || infoNo < 0 || infoNo > pMovie->infoCnt )
253)     return;
254) 
255)   pppNewInfos = (char * * *)malloc2D( pMovie->infoCnt + 1, 2, sizeof( char * ) );
256)   if( pppNewInfos == NULL )
257)     return;
258) 
259)   pType = strdup( pInfoType );
260)   if( pType == NULL )
261)   {
262)     free( pppNewInfos );
263)     return;
264)   }
265)   pData = strdup( pInfoData );
266)   if( pData == NULL )
267)   {
268)     free( pppNewInfos );
269)     free( pType );
270)     return;
271)   }
272) 
273)   for( i = 0; i < infoNo; i++ )
274)   {
275)     pppNewInfos[i][0] = pMovie->pppInfos[i][0];
276)     pppNewInfos[i][1] = pMovie->pppInfos[i][1];
277)   }
278) 
279)   pppNewInfos[infoNo][0] = pType;
280)   pppNewInfos[infoNo][1] = pData;
281) 
282)   for( i = infoNo; i < pMovie->infoCnt; i++ )
283)   {
284)     pppNewInfos[i+1][0] = pMovie->pppInfos[i][0];
285)     pppNewInfos[i+1][1] = pMovie->pppInfos[i][1];
286)   }
287) 
288)   free( pMovie->pppInfos );
289)   pMovie->pppInfos = pppNewInfos;
290)   pMovie->infoCnt++;
291) }
292) 
293) void BlinkenMovieAppendInfo( stBlinkenMovie * pMovie, char * pInfoType, char * pInfoData )
294) {
295)   if( pMovie == NULL )
296)     return;
297) 
298)   BlinkenMovieInsertInfo( pMovie, pMovie->infoCnt, pInfoType, pInfoData );
299) }
300) 
301) void BlinkenMovieDeleteInfo( stBlinkenMovie * pMovie, int infoNo )
302) {
303)   char * * * pppNewInfos;
304)   int i;
305) 
306)   if( pMovie == NULL || infoNo < 0 || infoNo >= pMovie->infoCnt )
307)     return;
308) 
309)   pppNewInfos = (char * * *)malloc2D( pMovie->infoCnt - 1, 2, sizeof( char * ) );
310)   if( pppNewInfos == NULL )
311)     return;
312) 
313)   for( i = 0; i < infoNo; i++ )
314)   {
315)     pppNewInfos[i][0] = pMovie->pppInfos[i][0];
316)     pppNewInfos[i][1] = pMovie->pppInfos[i][1];
317)   }
318) 
319)   free( pMovie->pppInfos[infoNo][0] );
320)   free( pMovie->pppInfos[infoNo][1] );
321) 
322)   for( i = infoNo; i < pMovie->infoCnt - 1; i++ )
323)   {
324)     pppNewInfos[i][0] = pMovie->pppInfos[i+1][0];
325)     pppNewInfos[i][1] = pMovie->pppInfos[i+1][1];
326)   }
327) 
328)   free( pMovie->pppInfos );
329)   pMovie->pppInfos = pppNewInfos;
330)   pMovie->infoCnt--;
331) }
332) 
333) void BlinkenMovieDeleteInfos( stBlinkenMovie * pMovie )
334) {
335)   char * * * pppNewInfos;
336)   int i;
337) 
338)   if( pMovie == NULL )
339)     return;
340) 
341)   pppNewInfos = (char * * *)malloc2D( 0, 2, sizeof( char * ) );
342)   if( pppNewInfos == NULL )
343)     return;
344) 
345)   for( i = 0; i < pMovie->infoCnt; i++ )
346)   {
347)     free( pMovie->pppInfos[i][0] );
348)     free( pMovie->pppInfos[i][1] );
349)   }
350) 
351)   free( pMovie->pppInfos );
352)   pMovie->pppInfos = pppNewInfos;
353)   pMovie->infoCnt = 0;
354) }
355) 
356) int BlinkenMovieGetFrameCnt( stBlinkenMovie * pMovie )
357) {
358)   if( pMovie == NULL )
359)     return 0;
360) 
361)   return pMovie->frameCnt;
362) }
363) 
364) stBlinkenFrame * BlinkenMovieGetFrame( stBlinkenMovie * pMovie, int frameNo )
365) {
366)   if( pMovie == NULL || pMovie->frameCnt < 1 )
367)     return NULL;
368) 
369)   if( frameNo < 0 ) frameNo = 0;
370)   if( frameNo >= pMovie->frameCnt ) frameNo = pMovie->frameCnt - 1;
371)   return pMovie->ppFrames[frameNo];
372) }
373) 
374) void BlinkenMovieSetFrame( stBlinkenMovie * pMovie, int frameNo, stBlinkenFrame * pFrame )
375) {
376)   if( pMovie == NULL || frameNo < 0 || frameNo >= pMovie->frameCnt )
377)     return;
378) 
379)   BlinkenFrameResize( pFrame, pMovie->height, pMovie->width, pMovie->channels, pMovie->maxval );
380)   pMovie->ppFrames[frameNo] = pFrame;
381) }
382) 
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

383) int BlinkenMovieInsertFrame( stBlinkenMovie * pMovie, int frameNo, stBlinkenFrame * pFrame )
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

384) {
385)   stBlinkenFrame * * ppNewFrames;
386)   int i;
387) 
388)   if( pMovie == NULL || frameNo < 0 || frameNo > pMovie->frameCnt )
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

389)     return -1;
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

390) 
391)   ppNewFrames = (stBlinkenFrame * *)malloc1D( pMovie->frameCnt + 1, sizeof( stBlinkenFrame * ) );
392)   if( ppNewFrames == NULL )
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

393)     return -1;
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

394) 
395)   for( i = 0; i < frameNo; i++ )
396)     ppNewFrames[i] = pMovie->ppFrames[i];
397) 
398)   BlinkenFrameResize( pFrame, pMovie->height, pMovie->width, pMovie->channels, pMovie->maxval );
399)   ppNewFrames[frameNo] = pFrame;
400) 
401)   for( i = frameNo; i < pMovie->frameCnt; i++ )
402)     ppNewFrames[i+1] = pMovie->ppFrames[i];
403) 
404)   free( pMovie->ppFrames );
405)   pMovie->ppFrames = ppNewFrames;
406)   pMovie->frameCnt++;
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

407)   return 0;
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

408) }
409) 
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

410) int BlinkenMovieAppendFrame( stBlinkenMovie * pMovie, stBlinkenFrame * pFrame )
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

411) {
412)   if( pMovie == NULL )
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

413)     return -1;
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

414) 
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

415)   return BlinkenMovieInsertFrame( pMovie, pMovie->frameCnt, pFrame );
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

416) }
417) 
418) void BlinkenMovieDeleteFrame( stBlinkenMovie * pMovie, int frameNo )
419) {
420)   stBlinkenFrame * * ppNewFrames;
421)   int i;
422) 
423)   if( pMovie == NULL || frameNo < 0 || frameNo >= pMovie->frameCnt )
424)     return;
425) 
426)   ppNewFrames = (stBlinkenFrame * *)malloc1D( pMovie->frameCnt - 1, sizeof( stBlinkenFrame * ) );
427)   if( ppNewFrames == NULL )
428)     return;
429) 
430)   for( i = 0; i < frameNo; i++ )
431)     ppNewFrames[i] = pMovie->ppFrames[i];
432) 
433)   BlinkenFrameFree( pMovie->ppFrames[frameNo] );
434) 
435)   for( i = frameNo; i < pMovie->frameCnt - 1; i++ )
436)     ppNewFrames[i] = pMovie->ppFrames[i+1];
437) 
438)   free( pMovie->ppFrames );
439)   pMovie->ppFrames = ppNewFrames;
440)   pMovie->frameCnt--;
441) }
442) 
443) void BlinkenMovieDeleteFrames( stBlinkenMovie * pMovie )
444) {
445)   stBlinkenFrame * * ppNewFrames;
446)   int i;
447) 
448)   if( pMovie == NULL )
449)     return;
450) 
451)   ppNewFrames = (stBlinkenFrame * *)malloc1D( 0, sizeof( stBlinkenFrame * ) );
452)   if( ppNewFrames == NULL )
453)     return;
454) 
455)   for( i = 0; i < pMovie->frameCnt; i++ )
456)     BlinkenFrameFree( pMovie->ppFrames[i] );
457) 
458)   free( pMovie->ppFrames );
459)   pMovie->ppFrames = ppNewFrames;
460)   pMovie->frameCnt = 0;
461) }
462) 
463) void BlinkenMovieResize( stBlinkenMovie * pMovie, int height, int width, int channels, int maxval )
464) {
465)   int i;
466) 
467)   if( pMovie == NULL )
468)     return;
469) 
470)   if( height < BlinkenHeightMin ) height = BlinkenHeightMin;
471)   if( height > BlinkenHeightMax ) height = BlinkenHeightMax;
472)   if( width < BlinkenWidthMin ) width = BlinkenWidthMin;
473)   if( width > BlinkenWidthMax ) width = BlinkenWidthMax;
474)   if( channels < BlinkenChannelsMin ) channels = BlinkenChannelsMin;
475)   if( channels > BlinkenChannelsMax ) channels = BlinkenMaxvalMax;
476)   if( maxval < BlinkenMaxvalMin ) maxval = BlinkenMaxvalMin;
477)   if( maxval > BlinkenMaxvalMax ) maxval = BlinkenMaxvalMax;
478) 
479)   pMovie->height = height;
480)   pMovie->width = width;
481)   pMovie->channels = channels;
482)   pMovie->maxval = maxval;
483) 
484)   for( i = 0; i < pMovie->frameCnt; i++ )
485)     BlinkenFrameResize( pMovie->ppFrames[i], height, width, channels, maxval );
486) }
487) 
488) void BlinkenMovieScale( stBlinkenMovie * pMovie, int height, int width )
489) {
490)   int i;
491) 
492)   if( pMovie == NULL )
493)     return;
494) 
495)   if( height < BlinkenHeightMin ) height = BlinkenHeightMin;
496)   if( height > BlinkenHeightMax ) height = BlinkenHeightMax;
497)   if( width < BlinkenWidthMin ) width = BlinkenWidthMin;
498)   if( width > BlinkenWidthMax ) width = BlinkenWidthMax;
499) 
500)   pMovie->height = height;
501)   pMovie->width = width;
502) 
503)   for( i = 0; i < pMovie->frameCnt; i++ )
504)     BlinkenFrameScale( pMovie->ppFrames[i], height, width );
505) }
506) 
Christian Heimke BlinkenLib v.0.5.3 (2007-12...

Christian Heimke authored 13 years ago

507) void BlinkenMovieColorize( stBlinkenMovie * pMovie, int channels, int mode )
508) {
509)   int i, step;
510) 
511)   if( pMovie == NULL )
512)     return;
513) 
514)   if( channels < BlinkenChannelsMin ) channels = BlinkenChannelsMin;
515)   if( channels > BlinkenChannelsMax ) channels = BlinkenMaxvalMax;
516) 
517)   pMovie->channels = channels;
518)   pMovie->maxval = BlinkenMaxvalMax;
519) 
520)   step = 0;
521)   for( i = 0; i < pMovie->frameCnt; i++ )
522)   {
523)     BlinkenFrameColorize( pMovie->ppFrames[i], channels, mode, step );
524)     step += BlinkenFrameGetDuration( pMovie->ppFrames[i] );
525)   }
526) }
527) 
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

528) char * BlinkenMovieToString( stBlinkenMovie * pMovie )
529) {
530)   char * * strs, * str, * ptr;
531)   int i, size;
532) 
533)   if( pMovie == NULL )
534)     return NULL;
535) 
536)   strs = (char * *)malloc1D( pMovie->frameCnt, sizeof( char * ) );
537)   if( strs == NULL )
538)     return NULL;
539) 
540)   for( i = 0; i < pMovie->frameCnt; i++ )
541)   {
542)     strs[i] = BlinkenFrameToString( pMovie->ppFrames[i] );
543)     if( strs[i] == NULL )
544)     {
545)       for( i--; i >= 0; i-- )
546)         free( strs[i] );
547)       free( strs );
548)       return NULL;
549)     }
550)   }
551) 
552)   size = 128;
553)   for( i = 0; i < pMovie->infoCnt; i++ )
554)     size += strlen( pMovie->pppInfos[i][0] ) + strlen( pMovie->pppInfos[i][1] ) + 8;
555)   for( i = 0; i < pMovie->frameCnt; i++ )
556)     size += strlen( strs[i] ) + 32;
557) 
558)   str = (char *)malloc( size );
559)   if( str == NULL )
560)   {
561)     for( i = 0; i < pMovie->frameCnt; i++ )
562)       free( strs[i] );
563)     free( strs );
564)     return NULL;
565)   }
566) 
567)   ptr = str;
568) 
569)   sprintf( ptr, "BlinkenMovie %ux%u-%u/%u\n", pMovie->width, pMovie->height, pMovie->channels, pMovie->maxval );
570)   ptr += strlen( ptr );
571) 
572)   for( i = 0; i < pMovie->infoCnt; i++ )
573)   {
574)     sprintf( ptr, "%s = %s\n", pMovie->pppInfos[i][0], pMovie->pppInfos[i][1] );
575)     ptr += strlen( ptr );
576)   }
577) 
578)   for( i = 0; i < pMovie->frameCnt; i++ )
579)   {
580)     sprintf( ptr, "frame %u\n%s", i, strs[i] );
581)     ptr += strlen( ptr );
582)     free( strs[i] );
583)   }
584)   free( strs );
585) 
586)   return str;  
587) }
588) 
589) stBlinkenMovie * BlinkenMovieLoadBlm( char * pFilename )
590) {
591)   FILE * pFile;
592)   stBlinkenMovie * pMovie;
593)   stBlinkenFrame * pFrame;
594)   int width, height, y, x, chr, duration;
595)   char infoType[256], infoData[1024], pixel[2];
596) 
597)   if( pFilename == NULL )
598)     return NULL;
599) 
600)   //open file
601)   pFile = fopen( pFilename, "rt" );
Christian Heimke BlinkenLib v.0.2 (2005-01-27)

Christian Heimke authored 13 years ago

602)   if( pFile == NULL )
603)     return NULL;
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

604) 
605)   //read magic and size
606)   if( fscanf( pFile, " # BlinkenLights Movie %ux%u", &width, &height ) != 2 )
607)   {
608)     fclose( pFile );
609)     return NULL;
610)   }
611) 
612)   //allocate a new movie
613)   pMovie = BlinkenMovieNew( height, width, 1, 1 );
614)   if( pMovie == NULL )
615)   {
616)     fclose( pFile );
617)     return NULL;
618)   }
619) 
620)   //no frame yet
621)   pFrame = NULL;
622)   y = 0;
623) 
624)   //read frames
625)   while( ! feof( pFile ) )
626)   {
627)     //skip rest of previous line (including newline)
628)     while( (chr = fgetc( pFile )) != '\n' && chr != EOF );
629) 
630)     //info line
631)     if( fscanf( pFile, " # %255[A-Za-z0-9] %*[=:] %1023[^\n]", infoType, infoData ) == 2 )
632)     {
633)       BlinkenMovieAppendInfo( pMovie, infoType, infoData );
634)     }
635) 
636)     //start of frame
637)     else if( fscanf( pFile, " @ %u", &duration ) == 1 )
638)     {
639)       //create new frame and append it to movie
640)       pFrame = BlinkenFrameNew( height, width, 1, 1, duration );
641)       if( pFrame != NULL )
642)       {
643)         BlinkenFrameClear( pFrame );
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

644)         if( BlinkenMovieAppendFrame( pMovie, pFrame ) != 0 )
645)         {
646)           BlinkenFrameFree( pFrame );
647)           pFrame = NULL;
648)         }
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

649)         y = 0;
650)       }
651)     }
652) 
653)     //data line
654)     else if( fscanf( pFile, "%1[01]", pixel ) == 1 )
655)     {
656)       if( pFrame != NULL )
657)       {
658)         for( x = 0; ; x++ )
659)         {
Christian Heimke BlinkenLib v.0.5.2 (2006-05...

Christian Heimke authored 13 years ago

660)           BlinkenFrameSetPixel( pFrame, y, x, 0, (unsigned char)(pixel[0] == '1' ? 1 : 0) ); //set pixel
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

661)           if( fscanf( pFile, "%1[01]", pixel ) != 1 ) //read next pixel
662)             break;
663)         }  
664)         y++; //next row
665)       }
666)     }
667) 
668)   } //while( ! feof( pFile ) )
669) 
670)   //close file
671)   fclose( pFile );
672) 
673)   return pMovie;
674) }
675) 
676) stBlinkenMovie * BlinkenMovieLoadBmm( char * pFilename )
677) {
678)   FILE * pFile;
679)   stBlinkenMovie * pMovie;
680)   stBlinkenFrame * pFrame;
681)   int width, height, y, x, chr, duration, val;
682)   char infoType[256], infoData[1024], pixel[8];
683) 
684)   if( pFilename == NULL )
685)     return NULL;
686) 
687)   //open file
688)   pFile = fopen( pFilename, "rt" );
Christian Heimke BlinkenLib v.0.2 (2005-01-27)

Christian Heimke authored 13 years ago

689)   if( pFile == NULL )
690)     return NULL;
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

691) 
692)   //read magic and size
693)   if( fscanf( pFile, " # BlinkenMini Movie %ux%u", &width, &height ) != 2 )
694)   {
695)     fclose( pFile );
696)     return NULL;
697)   }
698) 
699)   //allocate a new movie
700)   pMovie = BlinkenMovieNew( height, width, 1, 255 );
701)   if( pMovie == NULL )
702)   {
703)     fclose( pFile );
704)     return NULL;
705)   }
706) 
707)   //no frame yet
708)   pFrame = NULL;
709)   y = 0;
710) 
711)   //read frames
712)   while( ! feof( pFile ) )
713)   {
714)     //skip rest of previous line (including newline)
715)     while( (chr = fgetc( pFile )) != '\n' && chr != EOF );
716) 
717)     //info line
718)     if( fscanf( pFile, " # %255[A-Za-z0-9] %*[=:] %1023[^\n]", infoType, infoData ) == 2 )
719)     {
720)       BlinkenMovieAppendInfo( pMovie, infoType, infoData );
721)     }
722) 
723)     //start of frame
724)     else if( fscanf( pFile, " @ %u", &duration ) == 1 )
725)     {
726)       //create new frame and append it to movie
727)       pFrame = BlinkenFrameNew( height, width, 1, 255, duration );
728)       if( pFrame != NULL )
729)       {
730)         BlinkenFrameClear( pFrame );
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

731)         if( BlinkenMovieAppendFrame( pMovie, pFrame ) != 0 )
732)         {
733)           BlinkenFrameFree( pFrame );
734)           pFrame = NULL;
735)         }
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

736)         y = 0;
737)       }
738)     }
739) 
740)     //data line
741)     else if( fscanf( pFile, "%7[0-9A-FXa-fx]", pixel ) == 1 )
742)     {
743)       if( pFrame != NULL )
744)       {
745)         for( x = 0; ; x++ )
746)         {
747)           if( sscanf( pixel, "%i", &val ) != 1 ) //convert pixel to number
748)             break;
749)           BlinkenFrameSetPixel( pFrame, y, x, 0, (unsigned char)val ); //set pixel
750)           fscanf( pFile, "%*[ \t]" ); //kill space
751)           if( fscanf( pFile, "%7[0-9A-FXa-fx]", pixel ) != 1 ) //read next pixel
752)             break;
753)         }  
754)         y++; //next row
755)       }
756)     }
757) 
758)   } //while( ! feof( pFile ) )
759) 
760)   //close file
761)   fclose( pFile );
762) 
763)   return pMovie;
764) }
765) 
766) stBlinkenMovie * BlinkenMovieLoadBml( char * pFilename )
767) {
768)   FILE * pFile;
769)   stBlinkenMovie * pMovie;
770)   stBlinkenFrame * pFrame;
771)   int width, height, channels, bits, maxval, chrs, y, x, c, duration, val;
772)   char buffer[2048], infoType[256], infoData[1024], pixelFormat[16], pixel[8], * ptr, chr;
773) 
774)   if( pFilename == NULL )
775)     return NULL;
776) 
777)   //open file
778)   pFile = fopen( pFilename, "rt" );
Christian Heimke BlinkenLib v.0.2 (2005-01-27)

Christian Heimke authored 13 years ago

779)   if( pFile == NULL )
780)     return NULL;
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

781) 
782)   //no movie yet - blm tag not yet found
783)   pMovie = NULL;
784) 
785)   //no frame yet
786)   pFrame = NULL;
787)   y = 0;
788) 
789)   //read tags
790)   maxval = 0;
791)   while( ! feof( pFile ) )
792)   {
793) 
794)     //skip to just before beginning of next tag
795)     fscanf( pFile, "%*[^<]" );
796)     //skip beginning character of next tag
797)     if( fgetc( pFile ) != '<' )
798)       //end loop (no more tags)
799)       break;
800) 
801)     //no blm tag yet
802)     if( pMovie == NULL )
803)     {
804) 
805)       //blm tag
806)       if( fscanf( pFile, "blm%2047[^>]", buffer ) == 1 )
807)       {
808)         //get attributes
809)         width = 0;
810)         height = 0;
Christian Heimke BlinkenLib v.0.3.1 (2005-03...

Christian Heimke authored 13 years ago

811)         channels = 1;
812)         bits = 4;
813)         maxval = 15;
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

814)         if( (ptr = strstr( buffer, "height=\"" )) != NULL ) //height
815)           sscanf( ptr+8, "%u", &height );
816)         if( (ptr = strstr( buffer, "width=\"" )) != NULL ) //width
817)           sscanf( ptr+7, "%u", &width );
818)         if( (ptr = strstr( buffer, "channels=\"" )) != NULL ) //channels
819)           sscanf( ptr+10, "%u", &channels );
820)         if( (ptr = strstr( buffer, "bits=\"" )) != NULL ) //bits
821)           sscanf( ptr+6, "%u", &bits );
822)         maxval = (1 << bits) - 1; //maxval
823) 
824)         //allocate a new movie
825)         pMovie = BlinkenMovieNew( height, width, channels, maxval );
826)         if( pMovie == NULL )
827)         {
828)           fclose( pFile );
829)           return NULL;
830)         }
831) 
832)         //get number of characters per channel
833)         chrs = (bits + 3) >> 2;
834)         //get fscanf formart string for reading a pixel
835)         sprintf( pixelFormat, "%%%d[0-9A-Fa-f]", chrs > 4 ? 5 : chrs ); //read max 5 chars (2 already in use by prefix)
836)         //initialize pixel buffer with hex prefix
837)         strcpy( pixel, "0x" );
838)       }
839) 
840)     } //if( pMovie == NULL )
841) 
842)     //blm tag was already found
843)     else //if( pMovie == NULL )
844)     {
845) 
846)       //title tag
847)       if( fscanf( pFile, "title>%2047[^<]", buffer ) == 1 )
848)       {
849)         //add info to movie
850)         BlinkenMovieAppendInfo( pMovie, "title", buffer );
851)       }
852) 
853)       //description tag
854)       else if( fscanf( pFile, "description>%2047[^<]", buffer ) == 1 )
855)       {
856)         //check if generic info
857)         if( sscanf( buffer, "%255[A-Za-z0-9] %*[=:] %1023[^\n]", infoType, infoData ) == 2 )
858)           //add info to movie
859)           BlinkenMovieAppendInfo( pMovie, infoType, infoData );
860)         else
861)           //add info to movie
862)           BlinkenMovieAppendInfo( pMovie, "description", buffer );
863)       }
864) 
865)       //creator tag
866)       else if( fscanf( pFile, "creator>%2047[^<]", buffer ) == 1 )
867)       {
868)         //add info to movie
869)         BlinkenMovieAppendInfo( pMovie, "creator", buffer );
870)       }
871) 
872)       //author tag
873)       else if( fscanf( pFile, "author>%2047[^<]", buffer ) == 1 )
874)       {
875)         //add info to movie
876)         BlinkenMovieAppendInfo( pMovie, "author", buffer );
877)       }
878) 
879)       //email tag
880)       else if( fscanf( pFile, "email>%2047[^<]", buffer ) == 1 )
881)       {
882)         //add info to movie
883)         BlinkenMovieAppendInfo( pMovie, "email", buffer );
884)       }
885) 
886)       //url tag
887)       else if( fscanf( pFile, "url>%2047[^<]", buffer ) == 1 )
888)       {
889)         //add info to movie
890)         BlinkenMovieAppendInfo( pMovie, "url", buffer );
891)       }
892) 
893)       //frame tag
894)       else if( fscanf( pFile, "frame%2047[^>]", buffer ) == 1 )
895)       {
896)         //get attributes
897)         duration = 0;
898)         if( (ptr = strstr( buffer, "duration=\"" )) != NULL ) //duration
899)           sscanf( ptr+10, "%u", &duration );
900)         //create new frame and append it to movie
901)         pFrame = BlinkenFrameNew( height, width, channels, maxval, duration );
902)         if( pFrame != NULL )
903)         {
904)           BlinkenFrameClear( pFrame );
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

905)           if( BlinkenMovieAppendFrame( pMovie, pFrame ) != 0 )
906)           {
907)             BlinkenFrameFree( pFrame );
908)             pFrame = NULL;
909)           }
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

910)           y = 0;
911)         }
912)       }
913) 
914)       //row tag
915)       else if( fscanf( pFile, "row%c", &chr ) == 1 && chr == '>' )
916)       {
917)         if( pFrame != NULL )
918)         {
919)           //parse row
920)           for( x = 0; x < width; x++ )
921)           {
922)             for( c = 0; c < channels; c++ )
923)             {
924)               //read next pixel (one channel of pixel)
925)               if( fscanf( pFile, pixelFormat, pixel+2 ) != 1 )
926)               {
927)                 x = width; //also terminate x loop
928)                 break;
929)               }
930)               //convert pixel (one channel of pixel) to number
931)               if( sscanf( pixel, "%i", &val ) != 1 )
932)               {
933)                 x = width; //also terminate x loop
934)                 break;
935)               }
936)               //set pixel (one channel of pixel)
937)               BlinkenFrameSetPixel( pFrame, y, x, c, (unsigned char)val );
938)             }
939)           }
940)           y++; //next row
941)         }
942)       }
943) 
944)     } //if( pMovie == NULL ) ... else
945) 
946)   } //while( ! feof( pFile ) )
947) 
948)   //close file
949)   fclose( pFile );
950) 
951)   return pMovie;
952) }
953) 
954) stBlinkenMovie * BlinkenMovieLoadBbm( char * pFilename )
955) {
956)   FILE * pFile;
957)   stBlinkenMovie * pMovie;
958)   stBlinkenFrame * pFrame;
959)   unsigned char header[24], subHeader[6], frameStartMarker[4];
960)   unsigned long headerMagic, headerFrameCnt, headerDuration, headerFramePtr;
961)   unsigned short headerHeight, headerWidth, headerChannels, headerMaxval;
962)   unsigned long subHeaderMagic, frameStartMarkerMagic;
963)   unsigned short subHeaderSize;
Christian Heimke BlinkenLib v.0.5.3 (2007-12...

Christian Heimke authored 13 years ago

964)   char * pInfoHeader, * pInfoHeaderX;
965)   unsigned char * pFrameData;
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

966)   int len, duration, y, x, c, i;
967) 
968)   if( pFilename == NULL )
969)     return NULL;
970) 
971)   //open file
972)   pFile = fopen( pFilename, "rb" );
Christian Heimke BlinkenLib v.0.2 (2005-01-27)

Christian Heimke authored 13 years ago

973)   if( pFile == NULL )
974)     return NULL;
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

975) 
976)   //read header
977)   if( fread( header, 1, 24, pFile ) != 24 )
978)   {
979)     fclose( pFile );
980)     return NULL;
981)   }
982)   headerMagic = (unsigned long)header[0] << 24 | (unsigned long)header[1] << 16 | (unsigned long)header[2] << 8 | (unsigned long)header[3];
983)   headerHeight = (unsigned short)header[4] << 8 | (unsigned short)header[5];
984)   headerWidth = (unsigned short)header[6] << 8 | (unsigned short)header[7];
985)   headerChannels = (unsigned short)header[8] << 8 | (unsigned short)header[9];
986)   headerMaxval = (unsigned short)header[10] << 8 | (unsigned short)header[11];
987)   headerFrameCnt = (unsigned long)header[12] << 24 | (unsigned long)header[13] << 16 | (unsigned long)header[14] << 8 | (unsigned long)header[15];
988)   headerDuration = (unsigned long)header[16] << 24 | (unsigned long)header[17] << 16 | (unsigned long)header[18] << 8 | (unsigned long)header[19];
989)   headerFramePtr = (unsigned long)header[20] << 24 | (unsigned long)header[21] << 16 | (unsigned long)header[22] << 8 | (unsigned long)header[23];
990)   //check magic
991)   if( headerMagic != 0x23542666 )
992)   {
993)     fclose( pFile );
994)     return NULL;
995)   }
996) 
997)   //allocate a new movie
998)   pMovie = BlinkenMovieNew( headerHeight, headerWidth, headerChannels, headerMaxval );
999)   if( pMovie == NULL )
1000)   {
1001)     fclose( pFile );
1002)     return NULL;
1003)   }
1004) 
1005)   //read subheaders
1006)   while( ftell( pFile ) + 6 <= (long)headerFramePtr )
1007)   {
1008)     if( fread( subHeader, 1, 6, pFile ) != 6 )
1009)     {
1010)       BlinkenMovieFree( pMovie );
1011)       fclose( pFile );
1012)       return NULL;
1013)     }
1014)     subHeaderMagic = (unsigned long)subHeader[0] << 24 | (unsigned long)subHeader[1] << 16 | (unsigned long)subHeader[2] << 8 | (unsigned long)subHeader[3];
1015)     subHeaderSize = (unsigned short)subHeader[4] << 8 | (unsigned short)subHeader[5];
1016) 
1017)     //header fits into gap to frame start
1018)     if( subHeaderSize >= 6 && ftell( pFile ) + subHeaderSize - 6 <= (long)headerFramePtr )
1019)     {
1020)       //info header
1021)       if( subHeaderMagic == 0x696E666F ) //'i' 'n' 'f' 'o'
1022)       {
1023)         //read rest of info header
Christian Heimke BlinkenLib v.0.5.3 (2007-12...

Christian Heimke authored 13 years ago

1024)         pInfoHeader = (char *)malloc( subHeaderSize - 6 );
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

1025)         if( pInfoHeader == NULL )
1026)         {
1027)           BlinkenMovieFree( pMovie );
1028)           fclose( pFile );
1029)           return NULL;
1030)         }
1031)         if( fread( pInfoHeader, 1, subHeaderSize - 6, pFile ) != (unsigned short)(subHeaderSize - 6) )
1032)         {
1033)           free( pInfoHeader );
1034)           BlinkenMovieFree( pMovie );
1035)           fclose( pFile );
1036)           return NULL;
1037)         }
1038)         //parse information
1039)         if( (pInfoHeaderX = memchr( pInfoHeader, 0, subHeaderSize - 6 )) != NULL )
1040)         {
1041)           pInfoHeaderX++;
1042)           len = pInfoHeaderX - pInfoHeader;
1043)           if( memchr( pInfoHeaderX, 0, subHeaderSize - 6 - len ) != NULL )
1044)             BlinkenMovieAppendInfo( pMovie, pInfoHeader, pInfoHeaderX );
1045)         }
1046)         free( pInfoHeader );
1047)       }
1048) 
1049)       //unknown subHeader
1050)       else
1051)         //skip
1052)         fseek( pFile, subHeaderSize - 6, SEEK_CUR );
1053) 
1054)     } //if( ftell( pFile ) ...
1055)   } //while( ftell( pFile ) ...
1056) 
1057)   //seek to start of frames
1058)   fseek( pFile, headerFramePtr, SEEK_SET );
1059) 
1060)   //read frame start marker
1061)   if( fread( frameStartMarker, 1, 4, pFile ) != 4 )
1062)   {
1063)     BlinkenMovieFree( pMovie );
1064)     fclose( pFile );
1065)     return NULL;
1066)   }
1067)   frameStartMarkerMagic = (unsigned long)frameStartMarker[0] << 24 | (unsigned long)frameStartMarker[1] << 16 | (unsigned long)frameStartMarker[2] << 8 | (unsigned long)frameStartMarker[3];
1068)   if( frameStartMarkerMagic != 0x66726D73 ) //'f' 'r' 'm' 's'
1069)   {
1070)     BlinkenMovieFree( pMovie );
1071)     fclose( pFile );
1072)     return NULL;
1073)   }
1074) 
1075)   //allocate buffer for frame data
1076)   len = 2 + headerHeight * headerWidth * headerChannels;
1077)   pFrameData = (unsigned char *)malloc( len );
1078)   if( pFrameData == NULL )
1079)   {
1080)     BlinkenMovieFree( pMovie );
1081)     fclose( pFile );
1082)     return NULL;
1083)   }
1084) 
1085)   //read frames
1086)   for( ; ; )
1087)   {
1088)     //read frame
1089)     if( fread( pFrameData, 1, len, pFile ) != (unsigned int)len )
1090)       break;
1091)     duration = (unsigned short)pFrameData[0] << 8 | (unsigned short)pFrameData[1];
1092)     //build frame and append it to movie
1093)     pFrame = BlinkenFrameNew( headerHeight, headerWidth, headerChannels, headerMaxval, duration );
1094)     if( pFrame == NULL )
1095)       break;
1096)     i = 2;
1097)     for( y = 0; y < headerHeight; y++ )
1098)       for( x = 0; x < headerWidth; x++ )
1099)         for( c = 0; c < headerChannels; c++, i++ )
1100)           BlinkenFrameSetPixel( pFrame, y, x, c, pFrameData[i] );
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

1101)     if( BlinkenMovieAppendFrame( pMovie, pFrame ) != 0 )
1102)     {
1103)       BlinkenFrameFree( pFrame );
1104)       pFrame = NULL;
1105)     }
Christian Heimke BlinkenLib v.0.1.1 (2005-01...

Christian Heimke authored 13 years ago

1106) 
1107)   } //for( ; ; )
1108) 
1109)   //free buffer for frame data
1110)   free( pFrameData );
1111) 
1112)   //close file
1113)   fclose( pFile );
1114) 
1115)   return pMovie;
1116) }
1117) 
1118) stBlinkenMovie * BlinkenMovieLoad( char * pFilename )
1119) {
1120)   int len;
1121) 
1122)   if( pFilename == NULL )
1123)     return NULL;
1124) 
1125)   len = strlen( pFilename );
1126)   if( len > 4 && strcmp( pFilename + len - 4, ".blm" ) == 0 )
1127)     return BlinkenMovieLoadBlm( pFilename );
1128)   if( len > 4 && strcmp( pFilename + len - 4, ".bmm" ) == 0 )
1129)     return BlinkenMovieLoadBmm( pFilename );
1130)   if( len > 4 && strcmp( pFilename + len - 4, ".bml" ) == 0 )
1131)     return BlinkenMovieLoadBml( pFilename );
1132)   if( len > 4 && strcmp( pFilename + len - 4, ".bbm" ) == 0 )
1133)     return BlinkenMovieLoadBbm( pFilename );
1134)   return NULL;
1135) }
1136) 
1137) int BlinkenMovieSaveBlm( stBlinkenMovie * pMovie, char * pFilename )
1138) {
1139)   stBlinkenMovie * pOutMovie;
1140)   FILE * pFile;
1141)   int i, y, x;
1142) 
1143)   if( pMovie == NULL || pFilename == NULL )
1144)     return -1;
1145) 
1146)   //convert movie to suitable format
1147)   pOutMovie = BlinkenMovieClone( pMovie );
1148)   if( pOutMovie == NULL )
1149)     return -1;
1150)   BlinkenMovieResize( pOutMovie, pOutMovie->height, pOutMovie->width, 1, 1 );
1151) 
1152)   //open file
1153)   pFile = fopen( pFilename, "wt" );
1154)   if( pFile == NULL )
1155)   {
1156)     BlinkenMovieFree( pOutMovie );
1157)     return -1;
1158)   }
1159) 
1160)   //write header line
1161)   fprintf( pFile, "# BlinkenLights Movie %ux%u\n", pOutMovie->width, pOutMovie->height );
1162) 
1163)   //write information lines
1164)   for( i = 0; i < pOutMovie->infoCnt; i++ )
1165)     fprintf( pFile, "# %s = %s\n", pOutMovie->pppInfos[i][0], pOutMovie->pppInfos[i][1] );
1166) 
1167)   //write frames
1168)   for( i = 0; i < pOutMovie->frameCnt; i++ )
1169)   {
1170)     fprintf( pFile, "\n@%u\n", BlinkenFrameGetDuration( pOutMovie->ppFrames[i] ) );
1171)     for( y = 0; y < pOutMovie->height; y++ )
1172)     {
1173)       for( x = 0; x < pOutMovie->width; x++ )
1174)       {
1175)         if( BlinkenFrameGetPixel( pOutMovie->ppFrames[i], y, x, 0 ) != 0 )
1176)           fprintf( pFile, "1" );
1177)         else
1178)           fprintf( pFile, "0" );
1179)       }
1180)       fprintf( pFile, "\n" );
1181)     }
1182)   }
1183) 
1184)   //close file
1185)   fclose( pFile );
1186) 
1187)   //free copied movie
1188)   BlinkenMovieFree( pOutMovie );
1189) 
1190)   //success
1191)   return 0;
1192) }
1193) 
1194) int BlinkenMovieSaveBmm( stBlinkenMovie * pMovie, char * pFilename )
1195) {
1196)   stBlinkenMovie * pOutMovie;
1197)   FILE * pFile;
1198)   int i, y, x;
1199) 
1200)   if( pMovie == NULL || pFilename == NULL )
1201)     return -1;
1202) 
1203)   //convert movie to suitable format
1204)   pOutMovie = BlinkenMovieClone( pMovie );
1205)   if( pOutMovie == NULL )
1206)     return -1;
1207)   BlinkenMovieResize( pOutMovie, pOutMovie->height, pOutMovie->width, 1, 255 );
1208) 
1209)   //open file
1210)   pFile = fopen( pFilename, "wt" );
1211)   if( pFile == NULL )
1212)   {
1213)     BlinkenMovieFree( pOutMovie );
1214)     return -1;
1215)   }
1216) 
1217)   //write header line
1218)   fprintf( pFile, "# BlinkenMini Movie %ux%u\n", pOutMovie->width, pOutMovie->height );
1219) 
1220)   //write information lines
1221)   for( i = 0; i < pOutMovie->infoCnt; i++ )
1222)     fprintf( pFile, "# %s = %s\n", pOutMovie->pppInfos[i][0], pOutMovie->pppInfos[i][1] );
1223) 
1224)   //write frames
1225)   for( i = 0; i < pOutMovie->frameCnt; i++ )
1226)   {
1227)     fprintf( pFile, "\n@%u\n", BlinkenFrameGetDuration( pOutMovie->ppFrames[i] ) );
1228)     for( y = 0; y < pOutMovie->height; y++ )
1229)     {
1230)       fprintf( pFile, "0x%02X", BlinkenFrameGetPixel( pOutMovie->ppFrames[i], y, 0, 0 ) );
1231)       for( x = 1; x < pOutMovie->width; x++ )
1232)         fprintf( pFile, " 0x%02X", BlinkenFrameGetPixel( pOutMovie->ppFrames[i], y, x, 0 ) );
1233)       fprintf( pFile, "\n" );
1234)     }
1235)   }
1236) 
1237)   //close file
1238)   fclose( pFile );
1239) 
1240)   //free copied movie
1241)   BlinkenMovieFree( pOutMovie );
1242) 
1243)   //success
1244)   return 0;
1245) }
1246) 
1247) int BlinkenMovieSaveBml( stBlinkenMovie * pMovie, char * pFilename )
1248) {
1249)   stBlinkenMovie * pOutMovie;
1250)   FILE * pFile;
1251)   int bits, val, i, y, x, c;
1252) 
1253)   if( pMovie == NULL || pFilename == NULL )
1254)     return -1;
1255) 
1256)   //convert movie to suitable format
1257)   pOutMovie = BlinkenMovieClone( pMovie );
1258)   if( pOutMovie == NULL )
1259)     return -1;
1260)   val = pOutMovie->maxval; //get number of bits
1261)   for( bits = 0; val != 0; val >>= 1, bits++ );
1262)   BlinkenMovieResize( pOutMovie, pOutMovie->height, pOutMovie->width, pOutMovie->channels, (1 << bits) - 1 );
1263) 
1264)   //open file
1265)   pFile = fopen( pFilename, "wt" );
1266)   if( pFile == NULL )
1267)   {
1268)     BlinkenMovieFree( pOutMovie );
1269)     return -1;
1270)   }
1271) 
1272)   //write header line
1273)   fprintf( pFile, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
1274) 
1275)   //write blm start tag
1276)   fprintf( pFile, "<blm width=\"%u\" height=\"%u\" bits=\"%u\" channels=\"%u\">\n",
1277)            pOutMovie->width, pOutMovie->height, bits, pOutMovie->channels );
1278) 
1279)   //write information lines
1280)   fprintf( pFile, "\t<header>\n" );
1281)   for( i = 0; i < pOutMovie->infoCnt; i++ )
1282)   {
1283)     if( strcmp( pOutMovie->pppInfos[i][0], "title" ) == 0 )
1284)       fprintf( pFile, "\t\t<title>%s</title>\n", pOutMovie->pppInfos[i][1] );
1285)     else if( strcmp( pOutMovie->pppInfos[i][0], "description" ) == 0 )
1286)       fprintf( pFile, "\t\t<description>%s</description>\n", pOutMovie->pppInfos[i][1] );
1287)     else if( strcmp( pOutMovie->pppInfos[i][0], "creator" ) == 0 )
1288)       fprintf( pFile, "\t\t<creator>%s</creator>\n", pOutMovie->pppInfos[i][1] );
1289)     else if( strcmp( pOutMovie->pppInfos[i][0], "author" ) == 0)
1290)       fprintf( pFile, "\t\t<author>%s</author>\n", pOutMovie->pppInfos[i][1] );
1291)     else if( strcmp( pOutMovie->pppInfos[i][0], "email" ) == 0)
1292)       fprintf( pFile, "\t\t<email>%s</email>\n", pOutMovie->pppInfos[i][1] );
1293)     else if( strcmp( pOutMovie->pppInfos[i][0], "url" ) == 0)
1294)       fprintf( pFile, "\t\t<url>%s</url>\n", pOutMovie->pppInfos[i][1] );
1295)     else
1296)       fprintf( pFile, "\t\t<description>%s: %s</description>\n", pOutMovie->pppInfos[i][0], pOutMovie->pppInfos[i][1] );
1297)   }
1298)   fprintf( pFile, "\t</header>\n" );
1299) 
1300)   //write frames
1301)   for( i = 0; i < pOutMovie->frameCnt; i++ )
1302)   {
1303)     fprintf( pFile, "\n\t<frame duration=\"%u\">\n", BlinkenFrameGetDuration( pOutMovie->ppFrames[i] ) );
1304)     for( y = 0; y < pOutMovie->height; y++ )
1305)     {
1306)       fprintf( pFile, "\t\t<row>" );
1307)       for( x = 0; x < pOutMovie->width; x++ )
1308)         for( c = 0; c < pOutMovie->channels; c++ )
1309)           fprintf( pFile, bits > 4 ? "%02X" : "%01X",
1310)             BlinkenFrameGetPixel( pOutMovie->ppFrames[i], y, x, c ) );
1311)       fprintf( pFile, "</row>\n" );
1312)     }
1313)     fprintf( pFile, "\t</frame>\n" );
1314)   }
1315) 
1316)   //write blm end tag
1317)   fprintf( pFile, "</blm>\n" );
1318) 
1319)   //close file
1320)   fclose( pFile );
1321) 
1322)   //free copied movie
1323)   BlinkenMovieFree( pOutMovie );
1324) 
1325)   //success
1326)   return 0;
1327) }
1328) 
1329) int BlinkenMovieSaveBbm( stBlinkenMovie * pMovie, char * pFilename )
1330) {
1331)   unsigned char * pFrameData;
1332)   FILE * pFile;
1333)   unsigned char header[24], infoHeader[6], framePointer[4], frameStartMarker[4];
1334)   int duration, len, len0, len1, i, j, y, x, c, val;
1335)   long pos;
1336) 
1337)   if( pMovie == NULL || pFilename == NULL )
1338)     return -1;
1339) 
1340)   //allocate frame data buffer
1341)   pFrameData = (unsigned char *)malloc( 2 + pMovie->height * pMovie->width * pMovie->channels );
1342)   if( pFrameData == NULL )
1343)     return -1;
1344) 
1345)   //open file
1346)   pFile = fopen( pFilename, "wb" );
1347)   if( pFile == NULL )
1348)   {
1349)     free( pFrameData );
1350)     return -1;
1351)   }
1352) 
1353)   //write header
1354)   header[0] = 0x23; //magic
1355)   header[1] = 0x54;
1356)   header[2] = 0x26;
1357)   header[3] = 0x66;
1358)   header[4] = (unsigned char)(pMovie->height >> 8);
1359)   header[5] = (unsigned char)pMovie->height;
1360)   header[6] = (unsigned char)(pMovie->width >> 8);
1361)   header[7] = (unsigned char)pMovie->width;
1362)   header[8] = (unsigned char)(pMovie->channels >> 8);
1363)   header[9] = (unsigned char)pMovie->channels;
1364)   header[10] = (unsigned char)(pMovie->maxval >> 8);
1365)   header[11] = (unsigned char)pMovie->maxval;
1366)   header[12] = (unsigned char)(pMovie->frameCnt >> 24);
1367)   header[13] = (unsigned char)(pMovie->frameCnt >> 16);
1368)   header[14] = (unsigned char)(pMovie->frameCnt >> 8);
1369)   header[15] = (unsigned char)pMovie->frameCnt;
1370)   duration = 0;
1371)   for( i = 0; i < pMovie->frameCnt; i++ )
1372)     duration += BlinkenFrameGetDuration( pMovie->ppFrames[i] ); 
1373)   header[16] = (unsigned char)(duration >> 24);
1374)   header[17] = (unsigned char)(duration >> 16);
1375)   header[18] = (unsigned char)(duration >> 8);
1376)   header[19] = (unsigned char)duration;
1377)   header[20] = 0; //frame pointer is written later
1378)   header[21] = 0;
1379)   header[22] = 0;
1380)   header[23] = 0;
1381)   fwrite( header, 1, 24, pFile );
1382) 
1383)   //write information
1384)   for( i = 0; i < pMovie->infoCnt; i++ )
1385)   {
1386)     len0 = strlen( pMovie->pppInfos[i][0] );
1387)     if( len0 > 32760 )
1388)       len0 = 32760;
1389)     len1 = strlen( pMovie->pppInfos[i][1] );
1390)     if( len1 > 32760 )
1391)       len1 = 32760;
1392)     len = 8 + len0 + len1;
1393)     infoHeader[0] = 0x69; //'i'
1394)     infoHeader[1] = 0x6E; //'n'
1395)     infoHeader[2] = 0x66; //'f'
1396)     infoHeader[3] = 0x6F; //'o'
1397)     infoHeader[4] = (unsigned char)(len >> 8);
1398)     infoHeader[5] = (unsigned char)len;
1399)     fwrite( infoHeader, 1, 6, pFile );
1400)     fwrite( pMovie->pppInfos[i][0], 1, len0, pFile );
1401)     fwrite( "\0", 1, 1, pFile );
1402)     fwrite( pMovie->pppInfos[i][1], 1, len1, pFile );
1403)     fwrite( "\0", 1, 1, pFile );
1404)   }
1405) 
1406)   //write frame pointer
1407)   pos = ftell( pFile );
1408)   framePointer[0] = (unsigned char)(pos >> 24);
1409)   framePointer[1] = (unsigned char)(pos >> 16);
1410)   framePointer[2] = (unsigned char)(pos >> 8);
1411)   framePointer[3] = (unsigned char)pos;
1412)   fseek( pFile, 20, SEEK_SET );
1413)   fwrite( framePointer, 1, 4, pFile );
1414)   fseek( pFile, pos, SEEK_SET );
1415) 
1416)   //write frame start marker
1417)   frameStartMarker[0] = 0x66; //'f'
1418)   frameStartMarker[1] = 0x72; //'r'
1419)   frameStartMarker[2] = 0x6D; //'m'
1420)   frameStartMarker[3] = 0x73; //'s'
1421)   fwrite( frameStartMarker, 1, 4, pFile );
1422) 
1423)   //write frames
1424)   for( i = 0; i < pMovie->frameCnt; i++ )
1425)   {
1426)     val = BlinkenFrameGetDuration( pMovie->ppFrames[i] );
1427)     pFrameData[0] = (unsigned char)(val >> 8);
1428)     pFrameData[1] = (unsigned char)val;
1429)     for( j = 2, y = 0; y < pMovie->height; y++ )
1430)       for( x = 0; x < pMovie->width; x++ )
1431)         for( c = 0; c < pMovie->channels; c++, j++ )
1432)           pFrameData[j] = BlinkenFrameGetPixel( pMovie->ppFrames[i], y, x, c );
1433)     fwrite( pFrameData, 1, j, pFile );
1434)   }
1435) 
1436)   //free frame data buffer
1437)   free( pFrameData );
1438) 
1439)   //close file
1440)   fclose( pFile );
1441) 
1442)   //success
1443)   return 0;
1444) }
1445) 
1446) int BlinkenMovieSave( stBlinkenMovie * pMovie, char * pFilename )
1447) {
1448)   int len;
1449) 
1450)   if( pMovie == NULL || pFilename == NULL )
1451)     return -1;
1452) 
1453)   len = strlen( pFilename );
1454)   if( len > 4 && strcmp( pFilename + len - 4, ".blm" ) == 0 )
1455)     return BlinkenMovieSaveBlm( pMovie, pFilename );
1456)   if( len > 4 && strcmp( pFilename + len - 4, ".bmm" ) == 0 )
1457)     return BlinkenMovieSaveBmm( pMovie, pFilename );
1458)   if( len > 4 && strcmp( pFilename + len - 4, ".bml" ) == 0 )
1459)     return BlinkenMovieSaveBml( pMovie, pFilename );
1460)   if( len > 4 && strcmp( pFilename + len - 4, ".bbm" ) == 0 )
1461)     return BlinkenMovieSaveBbm( pMovie, pFilename );
1462)   return -1;
1463) }
1464) 
Christian Heimke BlinkenLib v.0.5.2 (2006-05...

Christian Heimke authored 13 years ago

1465) void BlinkenMovieSend( stBlinkenMovie * pMovie, SOCKET udpSocket, etBlinkenProto proto )
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

1466) //udp socket must be "connected"
1467) {
1468)   int i, len;
1469)   char buffer[65536]; //64kB is more tham maximum UDP size
1470) 
1471)   for( i = 0; i < pMovie->frameCnt; i++ )
1472)   {
1473)     len = BlinkenFrameToNetwork( pMovie->ppFrames[i], proto, buffer, sizeof( buffer ) );
1474)     if( len > 0 )
1475)       send( udpSocket, buffer, len, 0 );
Christian Heimke BlinkenLib v.0.5.2 (2006-05...

Christian Heimke authored 13 years ago

1476)     msleep( BlinkenFrameGetDuration( pMovie->ppFrames[i] ) );
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

1477)   }
1478) }
1479) 
Christian Heimke BlinkenLib v.0.5.2 (2006-05...

Christian Heimke authored 13 years ago

1480) stBlinkenMovie * BlinkenMovieReceive( SOCKET udpSocket, int timeout, etBlinkenProto * pProto )
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

1481) //udp socket must be "bound" and should be "connected"
1482) //after timeout ms of no reception, the movie is considered to be complete
1483) //returns protocol in *pProto if pProto not NULL
1484) {
1485)   stBlinkenMovie * pMovie;
1486)   stBlinkenFrame * pLastFrame, * pFrame;
1487)   etBlinkenProto proto, p;
1488)   fd_set readFds;
Christian Heimke BlinkenLib v.0.5.2 (2006-05...

Christian Heimke authored 13 years ago

1489)   struct timeval timeo;
1490)   unsigned int lastTime, curTime;
Christian Heimke BlinkenLib v.0.5 (2005-12-06)

Christian Heimke authored 13 years ago

1491)   char buffer[65536]; //64kB is more than maximum UDP size
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

1492)   int len;
1493) 
1494)   //correct timeout
1495)   if( timeout < 0 )
1496)     timeout = 0;
1497) 
1498)   //wait for frames
1499)   pMovie = NULL;
1500)   proto = BlinkenProtoNone;
1501)   pLastFrame = NULL;
Christian Heimke BlinkenLib v.0.5.2 (2006-05...

Christian Heimke authored 13 years ago

1502)   lastTime = get_ms( );
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

1503)   for( ; ; )
1504)   {
1505)     //wait for next frame
1506)     FD_ZERO( &readFds );
1507)     FD_SET( udpSocket, &readFds );
1508)     timeo.tv_sec = timeout / 1000;
1509)     timeo.tv_usec = (timeout % 1000) * 1000;
1510)     if( select( udpSocket + 1, &readFds, NULL, NULL, &timeo ) <= 0 ) //timeout or error
1511)       break;
1512) 
1513)     //fetch data
1514)     len = recv( udpSocket, buffer, sizeof( buffer ), 0 );
1515)     if( len <= 0 )
1516)       break;
1517) 
1518)     //get frame from data
1519)     pFrame = BlinkenFrameFromNetwork( buffer, len, &p );
1520)     if( pFrame != NULL )
1521)     {
1522)       //valid protocol
1523)       if( p != BlinkenProtoNone )
1524)       {
1525)         //first frame
1526)         if( proto == BlinkenProtoNone )
1527)           proto = p; //use this protocol
1528)         //protocol matches
1529)         if( p == proto )
1530)         {
1531)           //no movie yet
1532)           if( pMovie == NULL )
1533)           {
1534)             //allocate a new movie
1535)             pMovie = BlinkenMovieNew( BlinkenFrameGetHeight( pFrame ),
1536)                                       BlinkenFrameGetWidth( pFrame ),
1537)                                       BlinkenFrameGetChannels( pFrame ),
1538)                                       BlinkenFrameGetMaxval( pFrame ) );
1539)             if( pMovie == NULL )
1540)             {
1541)               BlinkenFrameFree( pFrame );
1542)               break;
1543)             }
1544)           }
1545) 
1546)           //append frame to movie
1547)           if( BlinkenMovieAppendFrame( pMovie, pFrame ) == 0 )
1548)           {
1549)             //get current time
Christian Heimke BlinkenLib v.0.5.2 (2006-05...

Christian Heimke authored 13 years ago

1550)             curTime = get_ms( );
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

1551)             //set duration of last frame
1552)             if( pLastFrame != NULL )
Christian Heimke BlinkenLib v.0.5.2 (2006-05...

Christian Heimke authored 13 years ago

1553)               BlinkenFrameSetDuration( pLastFrame, curTime - lastTime );
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

1554)             //remember this frame as last frame appended to movie
1555)             pLastFrame = pFrame;
1556)             pFrame = NULL; //do not free this frame (it was appended)
1557)             lastTime = curTime; //remember time of this frame
1558)           }
1559)         } //if( p == proto )
1560)       } //if( p != BlinkenProtoNone )
1561)       //free frame if it was not appended
1562)       if( pFrame != NULL )
1563)         BlinkenFrameFree( pFrame );
1564)     } //if( pFrame != NULL )
1565)   } //for( ; ; )
1566) 
1567)   //get current time
Christian Heimke BlinkenLib v.0.5.2 (2006-05...

Christian Heimke authored 13 years ago

1568)   curTime = get_ms( );
Christian Heimke BlinkenLib v.0.3 (2005-02-16)

Christian Heimke authored 13 years ago

1569)   //set duration of last frame
1570)   if( pLastFrame != NULL )
Christian Heimke BlinkenLib v.0.5.2 (2006-05...

Christian Heimke authored 13 years ago

1571)     BlinkenFrameSetDuration( pLastFrame, curTime - lastTime );