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