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

Christian Heimke authored 13 years ago

1) /* BlinkenLib
Christian Heimke BlinkenLibJava v.0.1.3 (200...

Christian Heimke authored 13 years ago

2)  * version 0.1.3 date 2008-09-29
3)  * Copyright (C) 2004-2008: Stefan Schuermans <1stein@schuermans.info>
Christian Heimke BlinkenLibJava v.0.1.1 (200...

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

Christian Heimke authored 13 years ago

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