b39aac59efe222c6fbe1f7d6df17e92d07d32e58
Christian Heimke BlinkenLibJava v.0.1.1 (200...

Christian Heimke authored 13 years ago

1) /* BlinkenLib
Stefan Schuermans removed version information...

Stefan Schuermans authored 13 years ago

2)  * Copyright (C) 2004-2011: Stefan Schuermans <stefan@schuermans.info>
Christian Heimke BlinkenLibJava v.0.1.1 (200...

Christian Heimke authored 13 years ago

3)  * Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
4)  * a blinkenarea.org project
5)  */
6) 
7) package org.blinkenarea.BlinkenLib;
8) 
9) import java.util.*;
10) import java.util.regex.*;
11) import java.io.*;
12) import org.blinkenarea.BlinkenLib.*;
13) 
14) public class BlinkenMovie
15) {
16) 
17)   private int height;
18)   private int width;
19)   private int channels;
20)   private int maxval;
21)   private int infoCnt;
22)   private String[][] infos;
23)   private int frameCnt;
24)   private BlinkenFrame[] frames;
25) 
26)   public BlinkenMovie( int height, int width, int channels, int maxval )
27)   {
28)     if( height < BlinkenConstants.BlinkenHeightMin ) height = BlinkenConstants.BlinkenHeightMin;
29)     if( height > BlinkenConstants.BlinkenHeightMax ) height = BlinkenConstants.BlinkenHeightMax;
30)     if( width < BlinkenConstants.BlinkenWidthMin ) width = BlinkenConstants.BlinkenWidthMin;
31)     if( width > BlinkenConstants.BlinkenWidthMax ) width = BlinkenConstants.BlinkenWidthMax;
32)     if( channels < BlinkenConstants.BlinkenChannelsMin ) channels = BlinkenConstants.BlinkenChannelsMin;
33)     if( channels > BlinkenConstants.BlinkenChannelsMax ) channels = BlinkenConstants.BlinkenChannelsMax;
34)     if( maxval < BlinkenConstants.BlinkenMaxvalMin ) maxval = BlinkenConstants.BlinkenMaxvalMin;
35)     if( maxval > BlinkenConstants.BlinkenMaxvalMax ) maxval = BlinkenConstants.BlinkenMaxvalMax;
36) 
37)     this.height = height;
38)     this.width = width;
39)     this.channels = channels;
40)     this.maxval = maxval;
41)     infoCnt = 0;
42)     infos = new String[0][2];
43)     frameCnt = 0;
44)     frames = new BlinkenFrame[0];
45)   }
46) 
47)   public BlinkenMovie( BlinkenMovie movie )
48)   {
49)     int i;
50) 
51)     height = movie.height;
52)     width = movie.width;
53)     channels = movie.channels;
54)     maxval = movie.maxval;
55)     infoCnt = 0;
56)     infos = new String[0][2];
57)     frameCnt = 0;
58)     frames = new BlinkenFrame[0];
59) 
60)     for( i = 0; i < movie.infoCnt; i++ )
61)       appendInfo( new String( movie.infos[i][0] ), new String( movie.infos[i][1] ) );
62) 
63)     for( i = 0; i < movie.frameCnt; i++ )
64)       appendFrame( new BlinkenFrame( movie.frames[i] ) );
65)   }
66) 
67)   public int getHeight( )
68)   {
69)     return height;
70)   }
71) 
72)   public int getWidth( )
73)   {
74)     return width;
75)   }
76) 
77)   public int getChannels( )
78)   {
79)     return channels;
80)   }
81) 
82)   public int getMaxval( )
83)   {
84)     return maxval;
85)   }
86) 
87)   public int getDuration( )
88)   {
89)     int duration, i;
90)     duration = 0;
91)     for( i = 0; i < frameCnt; i++ )
92)       duration += frames[i].getDuration( );
93)     return duration;
94)   }
95) 
96)   public int getInfoCnt( )
97)   {
98)     return infoCnt;
99)   }
100) 
101)   public String getInfoType( int infoNo )
102)   {
103)     if( infoCnt < 1 ) return "";
104)     if( infoNo < 0 ) infoNo = 0;
105)     if( infoNo >= infoCnt ) infoNo = infoCnt - 1;
106)     return infos[infoNo][0];
107)   }
108) 
109)   public String getInfoData( int infoNo )
110)   {
111)     if( infoCnt < 1 ) return "";
112)     if( infoNo < 0 ) infoNo = 0;
113)     if( infoNo >= infoCnt ) infoNo = infoCnt - 1;
114)     return infos[infoNo][1];
115)   }
116) 
117)   public void setInfo( int infoNo, String infoType, String infoData )
118)   {
119)     if( infoNo < 0 || infoNo >= infoCnt )
120)       return;
121)     infos[infoNo][0] = infoType;
122)     infos[infoNo][1] = infoData;
123)   }
124) 
125)   public void insertInfo( int infoNo, String infoType, String infoData )
126)   {
127)     String[][] new_infos;
128)     int i;
129) 
130)     if( infoNo < 0 || infoNo > infoCnt )
131)       return;
132) 
133)     new_infos = new String[infoCnt+1][2];
134) 
135)     for( i = 0; i < infoNo; i++ )
136)     {
137)       new_infos[i][0] = infos[i][0];
138)       new_infos[i][1] = infos[i][1];
139)     }
140) 
141)     new_infos[infoNo][0] = infoType;
142)     new_infos[infoNo][1] = infoData;
143) 
144)     for( i = infoNo; i < infoCnt; i++ )
145)     {
146)       new_infos[i+1][0] = infos[i][0];
147)       new_infos[i+1][1] = infos[i][1];
148)     }
149) 
150)     infos = new_infos;
151)     infoCnt++;
152)   }
153)   
154)   public void appendInfo( String infoType, String infoData )
155)   {
156)     insertInfo( infoCnt, infoType, infoData );
157)   }
158) 
159)   public void deleteInfo( int infoNo )
160)   {
161)     String[][] new_infos;
162)     int i;
163) 
164)     if( infoNo < 0 || infoNo >= infoCnt )
165)       return;
166) 
167)     new_infos = new String[infoCnt-1][2];
168) 
169)     for( i = 0; i < infoNo; i++ )
170)     {
171)       new_infos[i][0] = infos[i][0];
172)       new_infos[i][1] = infos[i][1];
173)     }
174) 
175)     for( i = infoNo; i < infoCnt-1; i++ )
176)     {
177)       new_infos[i][0] = infos[i+1][0];
178)       new_infos[i][1] = infos[i+1][1];
179)     }
180) 
181)     infos = new_infos;
182)     infoCnt--;
183)   }
184)   
185)   public void deleteInfos( )
186)   {
187)     infos = new String[0][2];
188)     infoCnt = 0;
189)   }
190) 
191)   public int getFrameCnt( )
192)   {
193)     return frameCnt;
194)   }
195) 
196)   public BlinkenFrame getFrame( int frameNo )
197)   {
198)     BlinkenFrame frame;
199)     if( frameCnt < 1 )
200)     {
201)       frame = new BlinkenFrame( height, width, channels, maxval, 0 );
202)       frame.clear( );
203)       return frame;
204)     }
205)     if( frameNo < 0 ) frameNo = 0;
206)     if( frameNo >= frameCnt ) frameNo = frameCnt - 1;
207)     return frames[frameNo];
208)   }
209) 
210)   public void setFrame( int frameNo, BlinkenFrame frame )
211)   {
212)     if( frameNo < 0 || frameNo >= frameCnt )
213)       return;
214)     frame.resize( height, width, channels, maxval );
215)     frames[frameNo] = frame;
216)   }
217) 
218)   public void insertFrame( int frameNo, BlinkenFrame frame )
219)   {
220)     BlinkenFrame[] new_frames;
221)     int i;
222) 
223)     if( frameNo < 0 || frameNo > frameCnt )
224)       return;
225) 
226)     new_frames = new BlinkenFrame[frameCnt+1];
227) 
228)     for( i = 0; i < frameNo; i++ )
229)       new_frames[i] = frames[i];
230) 
231)     frame.resize( height, width, channels, maxval );
232)     new_frames[frameNo] = frame;
233) 
234)     for( i = frameNo; i < frameCnt; i++ )
235)       new_frames[i+1] = frames[i];
236) 
237)     frames = new_frames;
238)     frameCnt++;
239)   }
240)   
241)   public void appendFrame( BlinkenFrame frame )
242)   {
243)     insertFrame( frameCnt, frame );
244)   }
245) 
246)   public void deleteFrame( int frameNo )
247)   {
248)     BlinkenFrame[] new_frames;
249)     int i;
250) 
251)     if( frameNo < 0 || frameNo >= frameCnt )
252)       return;
253) 
254)     new_frames = new BlinkenFrame[frameCnt-1];
255) 
256)     for( i = 0; i < frameNo; i++ )
257)       new_frames[i] = frames[i];
258) 
259)     for( i = frameNo; i < frameCnt-1; i++ )
260)       new_frames[i] = frames[i+1];
261) 
262)     frames = new_frames;
263)     frameCnt--;
264)   }
265)   
266)   public void deleteFrames( )
267)   {
268)     frames = new BlinkenFrame[0];
269)     frameCnt = 0;
270)   }
271) 
272)   public void resize( int height, int width, int channels, int maxval )
273)   {
274)     int i;
275) 
276)     if( height < BlinkenConstants.BlinkenHeightMin ) height = BlinkenConstants.BlinkenHeightMin;
277)     if( height > BlinkenConstants.BlinkenHeightMax ) height = BlinkenConstants.BlinkenHeightMax;
278)     if( width < BlinkenConstants.BlinkenWidthMin ) width = BlinkenConstants.BlinkenWidthMin;
279)     if( width > BlinkenConstants.BlinkenWidthMax ) width = BlinkenConstants.BlinkenWidthMax;
280)     if( channels < BlinkenConstants.BlinkenChannelsMin ) channels = BlinkenConstants.BlinkenChannelsMin;
281)     if( channels > BlinkenConstants.BlinkenChannelsMax ) channels = BlinkenConstants.BlinkenChannelsMax;
282)     if( maxval < BlinkenConstants.BlinkenMaxvalMin ) maxval = BlinkenConstants.BlinkenMaxvalMin;
283)     if( maxval > BlinkenConstants.BlinkenMaxvalMax ) maxval = BlinkenConstants.BlinkenMaxvalMax;
284) 
285)     this.height = height;
286)     this.width = width;
287)     this.channels = channels;
288)     this.maxval = maxval;
289) 
290)     for( i = 0; i < frameCnt; i++ )
291)       frames[i].resize( height, width, channels, maxval );
292)   }
293) 
294)   public void scale( int height, int width )
295)   {
296)     int i;
297) 
298)     if( height < BlinkenConstants.BlinkenHeightMin ) height = BlinkenConstants.BlinkenHeightMin;
299)     if( height > BlinkenConstants.BlinkenHeightMax ) height = BlinkenConstants.BlinkenHeightMax;
300)     if( width < BlinkenConstants.BlinkenWidthMin ) width = BlinkenConstants.BlinkenWidthMin;
301)     if( width > BlinkenConstants.BlinkenWidthMax ) width = BlinkenConstants.BlinkenWidthMax;
302) 
303)     this.height = height;
304)     this.width = width;
305) 
306)     for( i = 0; i < frameCnt; i++ )
307)       frames[i].scale( height, width );
308)   }
309) 
310)   public String toString( )
311)   {
312)     String str = "BlinkenMovie " + width + "x" + height + "-" + channels + "/" + (maxval + 1) + "\n";
313)     int i;
314)     for( i = 0; i < infoCnt; i++ )
315)       str += infos[i][0] + " = " + infos[i][1] + "\n";
316)     for( i = 0; i < frameCnt; i++ )
317)       str += "frame " + i + "\n" + frames[i].toString( );
318)     return str;
319)   }
320) 
321)   public boolean loadBlm( BufferedReader reader )
322)   {
323)     Pattern header, infoLine, startOfFrame, dataLine;
324)     String line, pixel;
325)     Matcher matcher;
326)     int new_width, new_height, new_duration, y, x, val;
327)     BlinkenFrame frame;
328) 
329)     //initialize needed regexp patterns
330)     header = Pattern.compile( "^ *# BlinkenLights Movie ([0-9]+)x([0-9]+)" );
331)     infoLine = Pattern.compile( "^ *# ?([A-Za-z0-9]+)(?: *= *|: *)(.*)" );
332)     startOfFrame = Pattern.compile( "^ *@([0-9]+)" );
333)     dataLine = Pattern.compile( " *([01])" );
334) 
335)     //delete all frames
336)     deleteInfos( );
337)     deleteFrames( );
338)     resize( 0, 0, 0, 0 );
339) 
340)     //try to read from buffered reader
341)     try
342)     {
343)       //read magic and size
344)       if( (line = reader.readLine( )) != null )
345)       {
346)         if( (matcher = header.matcher( line )).find( ) )
347)         {
348)           new_width = Integer.parseInt( matcher.group( 1 ) );
349)           new_height = Integer.parseInt( matcher.group( 2 ) );
350)           resize( new_height, new_width, 1, 1 );
351) 
352)           //create unused dummy frame for beginning
353)           frame = new BlinkenFrame( height, width, 1, 1, 0 );
354)           y = 0;
355) 
356)           //read frames
357)           while( (line = reader.readLine( )) != null )
358)           {
359) 
360)             //info line
361)             if( (matcher = infoLine.matcher( line )).find( ) )
362)             {
363)               appendInfo( matcher.group( 1 ), matcher.group( 2 ) );
364)             }
365) 
366)             //start of frame
367)             else if( (matcher = startOfFrame.matcher( line )).find( ) )
368)             {
369)               new_duration = Integer.parseInt( matcher.group( 1 ) );
370)               //create new frame and append it to movie
371)               frame = new BlinkenFrame( height, width, 1, 1, new_duration );
372)               frame.clear( );
373)               appendFrame( frame );
374)               y = 0;
375)             }
376) 
377)             //data line
378)             else if( (matcher = dataLine.matcher( line )).find( ) )
379)             {
380)               x = 0;
381)               while( true )
382)               {
383)                 pixel = matcher.group( 1 );
384)                 val = Integer.parseInt( pixel );
385)                 frame.setPixel( y, x, 0, (byte)val ); //set pixel
386)                 if( ! matcher.find( ) ) //get next pixel
387)                   break;
388)                 x++; //next pixel
389)               }
390)               y++; //next row
391)             }
392) 
393)           } //while( (line = ...
394)         } //if( matcher = header..matcher( ...
395)       } //if( (line = ...
396) 
397)       //success
398)       return true;
399)     }
400)     catch( IOException e ) { }
401) 
402)     //some error
403)     return false;
404)   }
405) 
406)   public boolean loadBlm( String filename )
407)   {
408)     try
409)     {
410)       BufferedReader file = new BufferedReader( new FileReader( filename ) );
411)       boolean ret = loadBlm( file );
412)       file.close( );
413)       return ret;
414)     }
415)     catch( IOException e )
416)     {
417)       return false;
418)     }
419)   }
420) 
421)   public boolean loadBmm( BufferedReader reader )
422)   {
423)     Pattern header, infoLine, startOfFrame, dataLine;
424)     String line, pixel;
425)     Matcher matcher;
426)     int new_width, new_height, new_duration, y, x, val;
427)     BlinkenFrame frame;
428) 
429)     //initialize needed regexp patterns
430)     header = Pattern.compile( "^ *# BlinkenMini Movie ([0-9]+)x([0-9]+)" );
431)     infoLine = Pattern.compile( "^ *# ?([A-Za-z0-9]+)(?: *= *|: *)(.*)" );
432)     startOfFrame = Pattern.compile( "^ *@([0-9]+)" );
433)     dataLine = Pattern.compile( " *(0x[0-9A-Fa-f]+|[0-9]+)" );
434) 
435)     //delete all frames
436)     deleteInfos( );
437)     deleteFrames( );
438)     resize( 0, 0, 0, 0 );
439) 
440)     //try to read from buffered reader
441)     try
442)     {
443)       //read magic and size
444)       if( (line = reader.readLine( )) != null )
445)       {
446)         if( (matcher = header.matcher( line )).find( ) )
447)         {
448)           new_width = Integer.parseInt( matcher.group( 1 ) );
449)           new_height = Integer.parseInt( matcher.group( 2 ) );
450)           resize( new_height, new_width, 1, 255 );
451) 
452)           //create unused dummy frame for beginning
453)           frame = new BlinkenFrame( height, width, 1, 255, 0 );
454)           y = 0;
455) 
456)           //read frames
457)           while( (line = reader.readLine( )) != null )
458)           {
459) 
460)             //info line
461)             if( (matcher = infoLine.matcher( line )).find( ) )
462)             {
463)               appendInfo( matcher.group( 1 ), matcher.group( 2 ) );
464)             }
465) 
466)             //start of frame
467)             else if( (matcher = startOfFrame.matcher( line )).find( ) )
468)             {
469)               new_duration = Integer.parseInt( matcher.group( 1 ) );
470)               //create new frame and append it to movie
471)               frame = new BlinkenFrame( height, width, 1, 255, new_duration );
472)               frame.clear( );
473)               appendFrame( frame );
474)               y = 0;
475)             }
476) 
477)             //data line
478)             else if( (matcher = dataLine.matcher( line )).find( ) )
479)             {
480)               x = 0;
481)               while( true )
482)               {
483)                 pixel = matcher.group( 1 );
484)                 if( pixel.length( ) >= 2 && pixel.substring( 0, 2 ).equals( "0x" ) )
485)                   val = Integer.parseInt( pixel.substring( 2 ), 0x10 );
486)                 else
487)                   val = Integer.parseInt( pixel );
488)                 frame.setPixel( y, x, 0, (byte)val ); //set pixel
489)                 if( ! matcher.find( ) ) //get next pixel
490)                   break;
491)                 x++; //next pixel
492)               }
493)               y++; //next row
494)             }
495) 
496)           } //while( (line = ...
497)         } //if( matcher = header..matcher( ...
498)       } //if( (line = ...
499) 
500)       //success
501)       return true;
502)     }
503)     catch( IOException e ) { }
504) 
505)     //some error
506)     return false;
507)   }
508) 
509)   public boolean loadBmm( String filename )
510)   {
511)     try
512)     {
513)       BufferedReader file = new BufferedReader( new FileReader( filename ) );
514)       boolean ret = loadBmm( file );
515)       file.close( );
516)       return ret;
517)     }
518)     catch( IOException e )
519)     {
520)       return false;
521)     }
522)   }
523) 
524)   public boolean loadBml( BufferedReader reader )
525)   {
526)     Pattern blmTag, blmHeight, blmWidth, blmChannels, blmBits;
527)     Pattern infoTitle, infoDescription, infoGeneric, infoCreator, infoAuthor, infoEmail, infoUrl;
528)     Pattern frameTag, frameDuration, rowTag, tag;
529)     String line, data, row;
530)     boolean blmTagFound;
531)     Matcher matcher, submatcher;
532)     int new_height, new_width, new_channels, bits, new_maxval, chrs, duration, y, x, c, len, i, val;
533)     BlinkenFrame frame;
534) 
535)     //initialize needed regexp patterns
536)     blmTag = Pattern.compile( "^[^<]*<blm([^>]*)>" );
537)     blmHeight = Pattern.compile( "height=\"?([0-9]*)\"?" );
538)     blmWidth = Pattern.compile( "width=\"?([0-9]*)\"?" );
539)     blmChannels = Pattern.compile( "channels=\"?([0-9]*)\"?" );
540)     blmBits = Pattern.compile( "bits=\"?([0-9]*)\"?" );
541)     infoTitle = Pattern.compile( "^[^<]*<title>([^<]*)</title>" );
542)     infoDescription = Pattern.compile( "[^<]*<description>([^<]*)</description>" );
543)     infoGeneric = Pattern.compile( "^([A-Za-z0-9]+)(?: *= *|: *)(.*)" );
544)     infoCreator = Pattern.compile( "^[^<]*<creator>([^<]*)</creator>" );
545)     infoAuthor = Pattern.compile( "^[^<]*<author>([^<]*)</author>" );
546)     infoEmail = Pattern.compile( "^[^<]*<email>([^<]*)</email>" );
547)     infoUrl = Pattern.compile( "^[^<]*<url>([^<]*)</url>" );
548)     frameTag = Pattern.compile( "^[^<]*<frame([^>]*)>" );
549)     frameDuration = Pattern.compile( "duration=\"?([0-9]*)\"?" );
550)     rowTag = Pattern.compile( "^[^<]*<row>([0-9A-Fa-f]*)</row>" );
551)     tag = Pattern.compile( "^[^<]*<[^>]*>" );
552) 
553)     //delete all frames
554)     deleteInfos( );
555)     deleteFrames( );
556)     resize( 0, 0, 0, 0 );
557) 
558)     //try to read from buffered reader
559)     try
560)     {
561)       //create unused dummy frame for beginning
562)       frame = new BlinkenFrame( 0, 0, 0, 0, 0 );
563)       y = 0;
564)       chrs = 1;
565) 
566)       //read
567)       data = "";
568)       blmTagFound = false;
569)       while( (line = reader.readLine( )) != null )
570)       {
571)         data += " " + line; //add new line to data
572) 
573)         //match tags
574)         while( true )
575)         {
576) 
577)           //no blm tag yet
578)           if( ! blmTagFound )
579)           {
580) 
581)             //blm tag
582)             if( (matcher = blmTag.matcher( data )).find( ) )
583)             {
584)               //remove matched part
585)               data = data.substring( matcher.end( ) );
586)               //get attributes
587)               new_width = 0;
588)               new_height = 0;
589)               new_channels = 1;
590)               bits = 4;
591)               new_maxval = 15;
592)               if( (submatcher = blmHeight.matcher( matcher.group( 1 ) )).find( ) ) //height
593)                 new_height = Integer.parseInt( submatcher.group( 1 ) );
594)               if( (submatcher = blmWidth.matcher( matcher.group( 1 ) )).find( ) ) //width
595)                 new_width = Integer.parseInt( submatcher.group( 1 ) );
596)               if( (submatcher = blmChannels.matcher( matcher.group( 1 ) )).find( ) ) //channels
597)                 new_channels = Integer.parseInt( submatcher.group( 1 ) );
598)               if( (submatcher = blmBits.matcher( matcher.group( 1 ) )).find( ) ) //bits
599)                 new_maxval = (1 << (bits = Integer.parseInt( submatcher.group( 1 ) ))) - 1;
600)               //remember that blm tag was found
601)               blmTagFound = true;
602)               //set movie size
603)               resize( new_height, new_width, new_channels, new_maxval );
604)               //get number of characters per channel
605)               chrs = (bits + 3) >> 2;
606)             }
607) 
608)             //unknown tag
609)             else if( (matcher = tag.matcher( data )).find( ) )
610)               //remove matched part
611)               data = data.substring( matcher.end( ) );
612) 
613)             //nothing matches
614)             else
615)               //end loop
616)               break;
617) 
618)           } //if( ! blmTagFound )
619) 
620)           //blm tag was already found
621)           else
622)           {
623) 
624)             //title tag
625)             if( (matcher = infoTitle.matcher( data )).find( ) )
626)             {
627)               //remove matched part
628)               data = data.substring( matcher.end( ) );
629)               //add info to movie
630)               appendInfo( "title", matcher.group( 1 ) );
631)             }
632) 
633)             //description tag
634)             else if( (matcher = infoDescription.matcher( data )).find( ) )
635)             {
636)               //remove matched part
637)               data = data.substring( matcher.end( ) );
638)               //check if generic info
639)               if( (submatcher = infoGeneric.matcher( matcher.group( 1 ) )).find( ) )
640)                 //add info to movie
641)                 appendInfo( submatcher.group( 1 ), submatcher.group( 2 ) );
642)               else
643)                 //add info to movie
644)                 appendInfo( "description", matcher.group( 1 ) );
645)             }
646) 
647)             //creator tag
648)             else if( (matcher = infoCreator.matcher( data )).find( ) )
649)             {
650)               //remove matched part
651)               data = data.substring( matcher.end( ) );
652)               //add info to movie
653)               appendInfo( "creator", matcher.group( 1 ) );
654)             }
655) 
656)             //author tag
657)             else if( (matcher = infoAuthor.matcher( data )).find( ) )
658)             {
659)               //remove matched part
660)               data = data.substring( matcher.end( ) );
661)               //add info to movie
662)               appendInfo( "author", matcher.group( 1 ) );
663)             }
664) 
665)             //email tag
666)             else if( (matcher = infoEmail.matcher( data )).find( ) )
667)             {
668)               //remove matched part
669)               data = data.substring( matcher.end( ) );
670)               //add info to movie
671)               appendInfo( "email", matcher.group( 1 ) );
672)             }
673) 
674)             //url tag
675)             else if( (matcher = infoUrl.matcher( data )).find( ) )
676)             {
677)               //remove matched part
678)               data = data.substring( matcher.end( ) );
679)               //add info to movie
680)               appendInfo( "url", matcher.group( 1 ) );
681)             }
682) 
683)             //frame tag
684)             else if( (matcher = frameTag.matcher( data )).find( ) )
685)             {
686)               //remove matched part
687)               data = data.substring( matcher.end( ) );
688)               //get attributes
689)               duration = 0;
690)               if( (submatcher = frameDuration.matcher( matcher.group( 1 ) )).find( ) ) //duration
691)                 duration = Integer.parseInt( submatcher.group( 1 ) );
692)               //create new frame and append it to movie
693)               frame = new BlinkenFrame( height, width, channels, maxval, duration );
694)               frame.clear( );
695)               appendFrame( frame );
696)               y = 0;
697)             }
698) 
699)             //row tag
700)             else if( (matcher = rowTag.matcher( data )).find( ) )
701)             {
702)               //remove matched part
703)               data = data.substring( matcher.end( ) );
704)               //parse row
705)               row = matcher.group( 1 );
706)               len = row.length( );
707)               i = 0;
708)               for( x = 0; x < this.width && i + chrs <= len; x++ )
709)               {
710)                 for( c = 0; c < this.channels && i + chrs <= len; c++, i += chrs )
711)                 {
712)                   val = Integer.parseInt( row.substring( i, i + chrs ), 0x10 );
713)                   frame.setPixel( y, x, c, (byte)val ); //set pixel
714)                 }
715)               }
716)               y++; //next row
717)             }
718) 
719)             //unknown tag
720)             else if( (matcher = tag.matcher( data )).find( ) )
721)               //remove matched part
722)               data = data.substring( matcher.end( ) );
723) 
724)             //nothing matches
725)             else
726)               //end loop
727)               break;
728) 
729)           } //if( ! blmTagFound ) ... else
730) 
731)         } //while( true )
732) 
733)       } //while( (line = ...
734) 
735)       //success
736)       return true;
737)     }
738)     catch( IOException e ) { }
739) 
740)     //some error
741)     return false;
742)   }
743) 
744)   public boolean loadBml( String filename )
745)   {
746)     try
747)     {
748)       BufferedReader file = new BufferedReader( new FileReader( filename ) );
749)       boolean ret = loadBml( file );
750)       file.close( );
751)       return ret;
752)     }
753)     catch( IOException e )
754)     {
755)       return false;
756)     }
757)   }
758) 
759)   public boolean loadBbm( String filename )
760)   {
761)     RandomAccessFile file;
762)     byte[] header, subHeader, infoHeader, frameStartMarker, frameData;
763)     int headerMagic, headerHeight, headerWidth, headerChannels, headerMaxval;
764)     int headerFrameCnt, headerDuration, headerFramePtr;
765)     int subHeaderMagic, subHeaderSize;
766)     int frameStartMarkerMagic;
767)     StringTokenizer tokenizer;
768)     String infoType, infoData;
769)     int fileLength, frameLength;
770)     int duration, i, y, x, c;
771)     BlinkenFrame frame;
772) 
773)     //delete all frames
774)     deleteInfos( );
775)     deleteFrames( );
776)     resize( 0, 0, 0, 0 );
777) 
778)     //try to read file
779)     try
780)     {
781)       //open file
782)       file = new RandomAccessFile( filename, "r" );
783) 
784)       //read header
785)       header = new byte[24];
786)       file.readFully( header );
787)       headerMagic = ((int)header[0] & 0xFF) << 24 | ((int)header[1] & 0xFF) << 16 | ((int)header[2] & 0xFF) << 8 | ((int)header[3] & 0xFF);
788)       headerHeight = ((int)header[4] & 0xFF) << 8 | ((int)header[5] & 0xFF);
789)       headerWidth = ((int)header[6] & 0xFF) << 8 | ((int)header[7] & 0xFF);
790)       headerChannels = ((int)header[8] & 0xFF) << 8 | ((int)header[9] & 0xFF);
791)       headerMaxval = ((int)header[10] & 0xFF) << 8 | ((int)header[11] & 0xFF);
792)       headerFrameCnt = ((int)header[12] & 0xFF) << 24 | ((int)header[13] & 0xFF) << 16 | ((int)header[14] & 0xFF) << 8 | ((int)header[15] & 0xFF);
793)       headerDuration = ((int)header[16] & 0xFF) << 24 | ((int)header[17] & 0xFF) << 16 | ((int)header[18] & 0xFF) << 8 | ((int)header[19] & 0xFF);
794)       headerFramePtr = ((int)header[20] & 0xFF) << 24 | ((int)header[21] & 0xFF) << 16 | ((int)header[22] & 0xFF) << 8 | ((int)header[23] & 0xFF);
795)       //check magic
796)       if( headerMagic == 0x23542666 )
797)       {
798) 
799)         //adapt movie format
800)         resize( headerHeight, headerWidth, headerChannels, headerMaxval );
801) 
802)         //read subheaders
803)         subHeader = new byte[6];
804)         while( file.getFilePointer( ) + 6 <= headerFramePtr )
805)         {
806)           file.readFully( subHeader );
807)           subHeaderMagic = ((int)subHeader[0] & 0xFF) << 24 | ((int)subHeader[1] & 0xFF) << 16 | ((int)subHeader[2] & 0xFF) << 8 | ((int)subHeader[3] & 0xFF);
808)           subHeaderSize = ((int)subHeader[4] & 0xFF) << 8 | ((int)subHeader[5] & 0xFF);
809) 
810)           //header fits into gap to frame start
811)           if( subHeaderSize >= 6 && file.getFilePointer( ) + subHeaderSize - 6 <= headerFramePtr )
812)           {
813)             //info header
814)             if( subHeaderMagic == 0x696E666F ) //'i' 'n' 'f' 'o'
815)             {
816)               //read rest of info header
817)               infoHeader = new byte[subHeaderSize - 6];
818)               file.readFully( infoHeader );
819)               //parse information
820)               tokenizer = new StringTokenizer( new String( infoHeader ), "\000" );
821)               if( tokenizer.countTokens( ) >= 2 )
822)               {
823)                 infoType = tokenizer.nextToken();
824)                 infoData = tokenizer.nextToken();
825)                 appendInfo( infoType, infoData );
826)               }
827)             }
828) 
829)             //unknown subHeader
830)             else
831)               //skip
832)               file.skipBytes( subHeaderSize - 6 );
833) 
834)           } //if( file.getFilePointer( ) ...
835)         } //while( file.getFilePointer( ) ...
836) 
837)         //seek to start of frames
838)         file.seek( headerFramePtr );
839) 
840)         //read frame start marker
841)         frameStartMarker = new byte[4];
842)         file.readFully( frameStartMarker );
843)         frameStartMarkerMagic = ((int)frameStartMarker[0] & 0xFF) << 24 | ((int)frameStartMarker[1] & 0xFF) << 16 | ((int)frameStartMarker[2] & 0xFF) << 8 | ((int)frameStartMarker[3] & 0xFF);
844)         if( frameStartMarkerMagic == 0x66726D73 ) //'f' 'r' 'm' 's'
845)         {
846) 
847)           //read frames
848)           fileLength = (int)file.length( );
849)           frameLength = 2 + headerHeight * headerWidth * headerChannels;
850)           frameData = new byte[frameLength];
851)           while( file.getFilePointer( ) + frameLength <= fileLength )
852)           {
853)             //read frame
854)             file.readFully( frameData );
855)             duration = ((int)frameData[0] & 0xFF) << 8 | ((int)frameData[1] & 0xFF);
856)             //build frame and append it to movie
857)             frame = new BlinkenFrame( height, width, channels, maxval, duration );
858)             i = 2;
859)             for( y = 0; y < headerHeight; y++ )
860)               for( x = 0; x < headerWidth; x++ )
861)                 for( c = 0; c < headerChannels; c++, i++ )
862)                   frame.setPixel( y, x, c, frameData[i] );
863)             appendFrame( frame );
864) 
865)           } //while( file.getFilePointer ...
866) 
867)         } //if( frameStartMarkerMagic ...
868) 
869)       } //if( headerMagic ...
870) 
871)       //close file
872)       file.close( );
873) 
874)       //success
875)       return true;
876)     }
877)     catch( IOException e ) { }
878) 
879)     //some error
880)     return false;
881)   }
882) 
883)   public boolean load( String filename )
884)   {
885)     if( filename.endsWith( ".blm" ) )
886)       return loadBlm( filename );
887)     if( filename.endsWith( ".bmm" ) )
888)       return loadBmm( filename );
889)     if( filename.endsWith( ".bml" ) )
890)       return loadBml( filename );
891)     if( filename.endsWith( ".bbm" ) )
892)       return loadBbm( filename );
893)     deleteFrames( );
894)     return false;
895)   }
896) 
897)   public boolean saveBlm( BufferedWriter writer )
898)   {
899)     BlinkenMovie movie;
900)     int cnt, i, y, x;
901)     String line;
902) 
903)     //convert movie to suitable format
904)     movie = new BlinkenMovie( this );
905)     movie.resize( movie.height, movie.width, 1, 1 );
906) 
907)     try
908)     {
909)       //write header line
910)       writer.write( "# BlinkenLights Movie " + movie.width + "x" + movie.height + "\n" );
911) 
912)       //write information lines
913)       cnt = movie.getInfoCnt( );
914)       for( i = 0; i < cnt; i++ )
915)         writer.write( "# " + movie.getInfoType( i ) + " = " + movie.getInfoData( i ) + "\n" );
916) 
917)       //write frames
918)       cnt = movie.getFrameCnt( );
919)       for( i = 0; i < cnt; i++ )
920)       {
921)         writer.write( "\n@" + movie.frames[i].getDuration( ) + "\n" );
922)         for( y = 0; y < movie.height; y++ )
923)         {
924)           line = "";
925)           for( x = 0; x < movie.width; x++ )
926)           {
927)             if( movie.frames[i].getPixel( y, x, 0 ) != 0 )
928)               line = line + "1";
929)             else
930)               line = line + "0";
931)           }
932)           writer.write( line + "\n" );
933)         }
934)       }
935) 
936)       //success
937)       return true;
938)     }
939)     catch( IOException e ) { }
940) 
941)     //some error
942)     return false;
943)   }
944) 
945)   public boolean saveBlm( String filename )
946)   {
947)     try
948)     {
949)       BufferedWriter file = new BufferedWriter( new FileWriter( filename ) );
950)       boolean ret = saveBlm( file );
951)       file.close( );
952)       return ret;
953)     }
954)     catch( IOException e )
955)     {
956)       return false;
957)     }
958)   }
959) 
960)   public boolean saveBmm( BufferedWriter writer )
961)   {
962)     BlinkenMovie movie;
963)     int cnt, i, y, x, val;
964)     String line;
965) 
966)     //convert movie to suitable format
967)     movie = new BlinkenMovie( this );
968)     movie.resize( movie.height, movie.width, 1, 255 );
969) 
970)     try
971)     {
972)       //write header line
973)       writer.write( "# BlinkenMini Movie " + movie.width + "x" + movie.height + "\n" );
974) 
975)       //write information lines
976)       cnt = movie.getInfoCnt( );
977)       for( i = 0; i < cnt; i++ )
978)         writer.write( "# " + movie.getInfoType( i ) + " = " + movie.getInfoData( i ) + "\n" );
979) 
980)       //write frames
981)       cnt = movie.getFrameCnt( );
982)       for( i = 0; i < cnt; i++ )
983)       {
984)         writer.write( "\n@" + movie.frames[i].getDuration( ) + "\n" );
985)         for( y = 0; y < movie.height; y++ )
986)         {
987)           line = "";
988)           for( x = 0; x < movie.width; x++ )
989)           {
990)             val = (int)movie.frames[i].getPixel( y, x, 0 ) & 0xFF;
991)             if( val < 0x10 )
992)               line = line + " 0x0" + Integer.toHexString( val ).toUpperCase( );
993)             else
994)               line = line + " 0x" + Integer.toHexString( val ).toUpperCase( );
995)           }
996)           writer.write( line.substring( 1 ) + "\n" );
997)         }
998)       }
999) 
1000)       //success
1001)       return true;
1002)     }
1003)     catch( IOException e ) { }
1004) 
1005)     //some error
1006)     return false;
1007)   }
1008) 
1009)   public boolean saveBmm( String filename )
1010)   {
1011)     try
1012)     {
1013)       BufferedWriter file = new BufferedWriter( new FileWriter( filename ) );
1014)       boolean ret = saveBmm( file );
1015)       file.close( );
1016)       return ret;
1017)     }
1018)     catch( IOException e )
1019)     {
1020)       return false;
1021)     }
1022)   }
1023) 
1024)   public boolean saveBml( BufferedWriter writer )
1025)   {
1026)     BlinkenMovie movie;
1027)     int bits, cnt, i, y, x, c, val;
1028)     String infoType, infoData, line;
1029) 
1030)     //convert movie to suitable format
1031)     movie = new BlinkenMovie( this );
1032)     val = movie.maxval; //get number of bits
1033)     for( bits = 0; val != 0; val >>= 1, bits++ );
1034)     movie.resize( movie.height, movie.width, movie.channels, (1 << bits) - 1 );
1035) 
1036)     try
1037)     {
1038)       //write header line
1039)       writer.write( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
1040) 
1041)       //write blm start tag
1042)       writer.write( "<blm width=\"" + movie.width + "\" height=\"" + movie.height
1043)                   + "\" bits=\"" + bits + "\" channels=\"" + movie.channels + "\">\n" );
1044) 
1045)       //write information lines
1046)       writer.write( "\t<header>\n" );
1047)       cnt = movie.getInfoCnt( );
1048)       for( i = 0; i < cnt; i++ )
1049)       {
1050)         infoType = movie.getInfoType( i );
1051)         infoData = movie.getInfoData( i );
1052)         if( infoType.equals( "title" ) )
1053)           writer.write( "\t\t<title>" + infoData + "</title>\n" );
1054)         else if( infoType.equals( "description" ) )
1055)           writer.write( "\t\t<description>" + infoData + "</description>\n" );
1056)         else if( infoType.equals( "creator" ) )
1057)           writer.write( "\t\t<creator>" + infoData + "</creator>\n" );
1058)         else if( infoType.equals( "author" ) )
1059)           writer.write( "\t\t<author>" + infoData + "</author>\n" );
1060)         else if( infoType.equals( "email" ) )
1061)           writer.write( "\t\t<email>" + infoData + "</email>\n" );
1062)         else if( infoType.equals( "url" ) )
1063)           writer.write( "\t\t<url>" + infoData + "</url>\n" );
1064)         else
1065)           writer.write( "\t\t<description>" + infoType + ": " + infoData + "</description>\n" );
1066)       }
1067)       writer.write( "\t</header>\n" );
1068) 
1069)       //write frames
1070)       cnt = movie.getFrameCnt( );
1071)       for( i = 0; i < cnt; i++ )
1072)       {
1073)         writer.write( "\n\t<frame duration=\"" + movie.frames[i].getDuration( ) + "\">\n" );
1074)         for( y = 0; y < movie.height; y++ )
1075)         {
1076)           line = "";
1077)           for( x = 0; x < movie.width; x++ )
1078)           {
1079)             for( c = 0; c < movie.channels; c++ )
1080)             {
1081)               val = (int)movie.frames[i].getPixel( y, x, c ) & 0xFF;
1082)               if( bits > 4 && val < 0x10 )
1083)                 line = line + "0" + Integer.toHexString( val ).toUpperCase( );
1084)               else
1085)                 line = line + Integer.toHexString( val ).toUpperCase( );
1086)             }
1087)           }
1088)           writer.write( "\t\t<row>" + line + "</row>\n" );
1089)         }
1090)         writer.write( "\t</frame>\n" );
1091)       }
1092) 
1093)       //write blm end tag
1094)       writer.write( "</blm>\n" );
1095) 
1096)       //success
1097)       return true;
1098)     }
1099)     catch( IOException e ) { }
1100) 
1101)     //some error
1102)     return false;
1103)   }
1104) 
1105)   public boolean saveBml( String filename )
1106)   {
1107)     try
1108)     {
1109)       BufferedWriter file = new BufferedWriter( new FileWriter( filename ) );
1110)       boolean ret = saveBml( file );
1111)       file.close( );
1112)       return ret;
1113)     }
1114)     catch( IOException e )
1115)     {
1116)       return false;
1117)     }
1118)   }
1119) 
1120)   public boolean saveBbm( String filename )
1121)   {
1122)     RandomAccessFile file;
1123)     byte[] header, infoHeader, framePointer, frameStartMarker, frameData;
1124)     int cnt, duration, i, j, len, y, x, c, val;
1125)     String infoType, infoData, line;
1126) 
1127)     try
1128)     {
1129)       //open file
1130)       file = new RandomAccessFile( filename, "rw" );
1131) 
Christian Heimke BlinkenLibJava v.0.1.3 (200...

Christian Heimke authored 13 years ago

1132)       //truncate file
1133)      file.setLength( 0 );
1134)