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)
|