001/* 002 * JOrbisComment -- pure Java Ogg Vorbis Comment Editor 003 * 004 * Copyright (C) 2000 ymnk, JCraft,Inc. 005 * 006 * Written by: 2000 ymnk<ymnk@jcraft.com> 007 * 008 * Many thanks to 009 * Monty <monty@xiph.org> and 010 * The XIPHOPHORUS Company http://www.xiph.org/ . 011 * JOrbis has been based on their awesome works, Vorbis codec and 012 * JOrbisPlayer depends on JOrbis. 013 * 014 * This program is free software; you can redistribute it and/or modify 015 * it under the terms of the GNU General Public License as published by 016 * the Free Software Foundation; either version 2 of the License, or 017 * (at your option) any later version. 018 * 019 * This program is distributed in the hope that it will be useful, 020 * but WITHOUT ANY WARRANTY; without even the implied warranty of 021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 022 * GNU General Public License for more details. 023 * 024 * You should have received a copy of the GNU General Public License 025 * along with this program; if not, write to the Free Software 026 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 027 */ 028package ca.bc.webarts.tools; 029 030import ca.bc.webarts.widgets.Util; 031import com.jcraft.jogg.*; 032import com.jcraft.jorbis.*; 033import java.io.*; 034import java.util.*; 035 036 037/** 038 * A class that reads and writes comments in Ogg Vorbis Files. It uses jcrafts 039 * jorbis impl. 040 * 041 * @author 042 */ 043public class JOrbisComment 044{ 045 046 /** Description of the Field */ 047 private static int CHUNKSIZE = 4096; 048 /** Description of the Field */ 049 State state = null; 050 /** Description of the Field */ 051 File inFile = null; 052 //InputStream vorbisStream_ = null; 053 private final int RAND_HASH_ = (int) (Math.random() * 20000); 054 055 056 String artist_ = ""; 057 String album_ = ""; 058 String title_ = ""; 059 String tracknumber_ = ""; 060 String genre_ = ""; 061 String artistAlbumTrackNum_ = ""; 062 String artistAlbumTrackTitle_ = ""; 063 064 065 /** Constructor for the JOrbisComment object */ 066 public JOrbisComment() 067 { 068 super(); 069 this.state = new State(); 070 } 071 072 073 /** 074 * Constructor for the JOrbisComment object 075 * 076 * @param state Description of the Parameter 077 */ 078 public JOrbisComment(State state) 079 { 080 super(); 081 this.state = state; 082 } 083 084 085 /** 086 * Constructor for the JOrbisComment object 087 * 088 * @param inFile inits and reads the passed file 089 */ 090 public JOrbisComment(File inFile) 091 { 092 super(); 093 this.state = new State(); 094 this.inFile = inFile; 095 readInFile(); 096 } 097 098 099 /** 100 * Constructor for the JOrbisComment object 101 * 102 * @param vorbisStream inits and reads the passed inStream 103 */ 104 public JOrbisComment(InputStream vorbisStream) 105 { 106 super(); 107 this.state = new State(); 108 state.in = vorbisStream; 109 } 110 111 112 /** 113 * flushes its objects to reease memory 114 * 115 */ 116 public void flush() 117 { 118 this.state = null; 119 } 120 121 122 /** 123 * The main program for the JOrbisComment class. 124 * 125 * @param arg The command line arguments 126 */ 127 public static void main(String[] arg) 128 { 129 if (arg.length > 0) 130 { 131 String input = arg[0]; 132 String output = arg[0]; 133 //System.out.println("arg="+arg.length ); 134 InputStream in = null; 135 State foo = new State(); 136 JOrbisComment jorbiscomment = new JOrbisComment(foo); 137 try 138 { 139 in = new FileInputStream(input); 140 jorbiscomment.read(in); 141 System.out.println(jorbiscomment.getArtistAlbumTrackNum()); 142 System.out.println(foo.vc); 143 in.close(); 144 } 145 catch (Exception e) 146 { 147 System.out.println(e); 148 } 149 150 // foo.vc.add("TEST=TESTTEST"); 151 // foo.vc.add_tag("TITLE", "demodemo"); 152 //System.out.println(foo.vc.query("TEST")); 153 //System.out.println(foo.vc.query("TITLE")); 154 //System.out.println(foo.vc.query("ARTIST")); 155 156 // parse any passed comments and add to this 157 if (arg.length > 1) 158 { 159 System.out.println("New Comments Specified "+arg.length ); 160 for (int pair = 1; pair < arg.length; pair+=2) 161 { 162 // an ogg comment was given on the commandline so add them tothe file 163 jorbiscomment.setComment(arg[pair], (arg.length>(pair+1)?arg[pair+1]:"")); 164 System.out.println("added ogg comment: " + 165 arg[pair] + "=" + (arg.length>(pair+1)?arg[pair+1]:"")); 166 } 167 } 168 169 if (arg.length > 1) 170 { 171 try 172 { 173 // persist any changes back to the file NOTE you could persist this to any other file as well. 174 OutputStream out = new FileOutputStream(output); 175 176 jorbiscomment.write(out); 177 out.close(); 178 } 179 catch (Exception e) 180 { 181 e.printStackTrace(); 182 System.out.println(e); 183 } 184 } 185 } 186 else 187 { 188 System.out.println(usage()); 189 } 190 } 191 192 193 public static String usage() 194 { 195 String retVal = "JOrbisComment - A Java query and writer for Ogg Vorbis File comments."; 196 retVal+= Util.SYSTEM_LINE_SEPERATOR; 197 retVal+= "> java ca.bc.webarts.tools.JOrbisComment [inputFile] [commentFiled commentValue]..."; 198 retVal+= Util.SYSTEM_LINE_SEPERATOR; 199 retVal+= " inputFile - is the ogg file to read(and writeiff comments are specified)"; 200 retVal+= Util.SYSTEM_LINE_SEPERATOR; 201 retVal+= " comments are specified in name value pairs"; 202 retVal+= Util.SYSTEM_LINE_SEPERATOR; 203 retVal+= " If only the inputFile is specified, then it is read and the comments are printed on the commandline."; 204 retVal+= Util.SYSTEM_LINE_SEPERATOR; 205 return retVal; 206 } 207 208 209 public boolean setArtist(String value) 210 { 211 return setComment("ARTIST",value); 212 } 213 214 215 public boolean setAlbum(String value) 216 { 217 return setComment("ALBUM",value); 218 } 219 220 221 public boolean setTitle(String value) 222 { 223 return setComment("TITLE",value); 224 } 225 226 227 public boolean setTracknumber(String value) 228 { 229 return setComment("TRACKNUMBER",value); 230 } 231 232 233 public boolean setTrackTotal(String value) 234 { 235 return setComment("TRACKTOTAL",value); 236 } 237 238 239 public boolean setGenre(String value) 240 { 241 return setComment("GENRE",value); 242 } 243 244 245 /** 246 * Sets a comment attribute of the JOrbisComment object BUT does not write to file. 247 * 248 * @param field ThSystem.out.printlne new comment value 249 * @param value The new comment value 250 * @return Description of the Return Value 251 */ 252 public boolean setComment(String field, String value) 253 { 254 boolean retVal = true; 255 try 256 { 257 if (value==null) value=""; 258 this.state.vc.add_tag(field, value); 259 } 260 catch (Exception e) 261 { 262 //e.printStackTrace(); 263 System.out.println("Can't add comment: " + field + "=" + value); 264 retVal = false; 265 } 266 return retVal; 267 } 268 269 270 /** 271 * Gets the comment attribute of the JOrbisComment object. It is case 272 * sensitive - it will search for the exact match of the passed field. 273 * 274 * @param field Description of the Parameter 275 * @return The comment value 276 */ 277 public String getComment(String field) 278 { 279 return (this.state.vc!=null?this.state.vc.query(field):""); 280 281 } 282 283 284 /** 285 * Gets the comment attribute of the JOrbisComment object. NOTE: that this method 286 * looks for the AllCaps version of this tag 1st, then the allLower version 287 * 288 * @param smart flag if the Uppercase should be prioritized. 289 * @param field Description of the Parameter 290 * @return The comment value, or an empty string if not found. 291 */ 292 public String getComment(String field, boolean smart) 293 { 294 String retVal = ""; 295 if (smart) 296 { 297 String caps = getComment(field.toUpperCase()); 298 String sml = getComment(field.toLowerCase()); 299 retVal = (caps!=null?caps:(sml!=null?sml:"")); 300 } 301 else 302 retVal = getComment(field); 303 304 return retVal; 305 } 306 307 308 /** 309 * Gets a concatenation of Artist Album and Track# Comment for this ogg vorbis file. 310 * 311 * @return a concatenation of Artist Album and Track# Comment 312 */ 313 public String getArtistAlbumTrackNum() 314 { 315 // use the cache if available 316 if (artistAlbumTrackNum_.equals("")) 317 { 318 artistAlbumTrackNum_ = 319 ( ( getArtist()!=null ? getArtist():"")+" "+ 320 ( getAlbum() !=null ? getAlbum() :"")+" "+ 321 ( getTracknumber()!=null && !getTracknumber().equals("")? 322 ( getTracknumber().length()<2?"0"+ getTracknumber(): getTracknumber()) : 323 ( getTitle() !=null ? getTitle() :"") 324 ) + 325 "_"+RAND_HASH_ 326 ); 327 } 328 329 return artistAlbumTrackNum_; 330 } 331 332 333 /** 334 * Gets a concatenation of Artist Album and Track Title Comment for this ogg vorbis file. 335 * 336 * @return a concatenation of Artist Album and Track# Comment 337 */ 338 public String getArtistAlbumTrackTitle() 339 { 340 // use the cache if available 341 if (artistAlbumTrackTitle_.equals("")) 342 { 343 artistAlbumTrackTitle_ = 344 ( ( getArtist()!=null ? getArtist():"")+" "+ 345 ( getAlbum() !=null ? getAlbum() :"")+" "+ 346 ( getTitle() !=null ? getTitle() :"") + 347 "_"+RAND_HASH_ 348 ); 349 } 350 351 return artistAlbumTrackTitle_; 352 } 353 354 355 /** 356 * Gets the artist attribute of the JOrbisComment object. 357 * NOTE: It calls the smart upparcase prioritized getComment method. 358 * 359 * @return The artist value 360 */ 361 public String getArtist() 362 { 363 // Uses the cached val if available 364 if (artist_.equals("")) artist_ = getComment("artist",true); 365 return artist_; 366 } 367 368 369 /** 370 * Gets the album attribute of the JOrbisComment object. 371 * NOTE: It calls the smart upparcase prioritized getComment method. 372 * 373 * @return The album value 374 */ 375 public String getAlbum() 376 { 377 // Uses the cached val if available 378 if (album_.equals("")) album_ = getComment("album",true); 379 return album_; 380 } 381 382 383 /** 384 * Gets the title attribute of the JOrbisComment object. NOTE: that this method 385 * looks for the AllCaps version of this tag 1st, then the allLower version 386 * 387 * @return The TITLE comment value, or an empty string if not found. 388 */ 389 public String getTitle() 390 { 391 // Uses the cached val if available 392 if (title_.equals("")) title_ = getComment("title",true); 393 return title_; 394 } 395 396 397 /** 398 * Gets the tracknumber attribute of the JOrbisComment object. 399 * NOTE: It calls the smart upparcase prioritized getComment method. 400 * 401 * @return The tracknumber value 402 */ 403 public String getTracknumber() 404 { 405 // Uses the cached val if available 406 if (tracknumber_.equals("")) tracknumber_ = getComment("tracknumber",true); 407 return tracknumber_; 408 } 409 410 411 /** 412 * Gets the tracktotal attribute of the JOrbisComment object. 413 * NOTE: It calls the smart upparcase prioritized getComment method. 414 * 415 * @return The tracktotal value 416 */ 417 public String getTrackTotal() 418 { 419 return getComment("tracktotal",true); 420 } 421 422 423 /** 424 * Gets the genre attribute of the JOrbisComment object. 425 * NOTE: It calls the smart upparcase prioritized getComment method. 426 * 427 * @return The genre value 428 */ 429 public String getGenre() 430 { 431 // Uses the cached val if available 432 if (genre_.equals("")) genre_ = getComment("genre",true); 433 return genre_; 434 } 435 436 437 /** 438 * Gets the date attribute of the JOrbisComment object. 439 * NOTE: It calls the smart upparcase prioritized getComment method. 440 * 441 * @return The date value 442 */ 443 public String getDate() 444 { 445 return getComment("date",true); 446 } 447 448 449 /** 450 * Gets the MusicBrainz DiscID attribute of the JOrbisComment object. 451 * NOTE: It calls the smart upparcase prioritized getComment method. 452 * 453 * @return The MUSICBRAINZ_DISCID value 454 */ 455 public String getMusicBrainzDiscID() 456 { 457 return getComment("MUSICBRAINZ_DISCID",true); 458 } 459 460 461 /** 462 * Reads from this classes inputstream 463 * 464 */ 465 public boolean read(){ return read(state.in);} 466 467 468 /** 469 * Reads from the classes inFile 470 * 471 */ 472 public boolean readInFile() 473 { 474 InputStream in = null; 475 boolean retVal = true; 476 try 477 { 478 in = new FileInputStream(this.inFile.toString()); 479 if (in != null) 480 { 481 retVal = this.read(in); 482 if (!retVal) System.err.println("Input truncated or empty: "+ this.inFile.toString()); 483 in.close(); 484 } 485 } 486 catch (Exception e) 487 { 488 e.printStackTrace(); 489 retVal = false; 490 } 491 492 return retVal; 493 } 494 495 496 /** 497 * Description of the Method 498 * 499 * @param in Description of the Parameter 500 */ 501 public boolean read(InputStream in) 502 { 503 boolean retVal = true; 504 if (this.state==null) 505 { 506 retVal = false; 507 } 508 else 509 { 510 this.state.in = in; 511 512 Page og = new Page(); 513 514 int index; 515 byte[] buffer; 516 int bytes = 0; 517 518 state.oy = new SyncState(); 519 state.oy.init(); 520 521 index = state.oy.buffer(CHUNKSIZE); 522 buffer = state.oy.data; 523 try 524 { 525 bytes = this.state.in.read(buffer, index, CHUNKSIZE); 526 } 527 catch (Exception e) 528 { 529 //System.err.println("vorbisStream is "+(in==null?"":"NOT ")+" null"); 530 //System.err.println("buffer is "+(buffer==null?"":"NOT ")+" null"); 531 //System.err.println(e); 532 //e.printStackTrace(); 533 return false; 534 } 535 state.oy.wrote(bytes); 536 537 if (state.oy.pageout(og) != 1) 538 { 539 if (bytes < CHUNKSIZE) 540 { 541 System.err.println("Input truncated or empty."); 542 } 543 else 544 { 545 System.err.println("Input is not an Ogg bitstream."); 546 } 547 // goto err; 548 return false; 549 } 550 state.serial = og.serialno(); 551 state.os = new StreamState(); 552 state.os.init(state.serial); 553 // os.reset(); 554 555 state.vi = new Info(); 556 state.vi.init(); 557 558 state.vc = new Comment(); 559 state.vc.init(); 560 561 if (state.os.pagein(og) < 0) 562 { 563 System.err.println("Error reading first page of Ogg bitstream data."); 564 // goto err 565 return false; 566 } 567 568 Packet header_main = new Packet(); 569 570 if (state.os.packetout(header_main) != 1) 571 { 572 System.err.println("Error reading initial header packet."); 573 // goto err 574 return false; 575 } 576 577 if (state.vi.synthesis_headerin(state.vc, header_main) < 0) 578 { 579 System.err.println("This Ogg bitstream does not contain Vorbis data."); 580 // goto err 581 return false; 582 } 583 584 state.mainlen = header_main.bytes; 585 state.mainbuf = new byte[state.mainlen]; 586 System.arraycopy(header_main.packet_base, header_main.packet, 587 state.mainbuf, 0, state.mainlen); 588 589 int i = 0; 590 Packet header; 591 Packet header_comments = new Packet(); 592 Packet header_codebooks = new Packet(); 593 594 header = header_comments; 595 while (i < 2) 596 { 597 while (i < 2) 598 { 599 int result = state.oy.pageout(og); 600 if (result == 0) 601 { 602 break; 603 } 604 /* 605 * Too little data so far 606 */ 607 else if (result == 1) 608 { 609 state.os.pagein(og); 610 while (i < 2) 611 { 612 result = state.os.packetout(header); 613 if (result == 0) 614 { 615 break; 616 } 617 if (result == -1) 618 { 619 System.out.println("Corrupt secondary header."); 620 //goto err; 621 return false; 622 } 623 state.vi.synthesis_headerin(state.vc, header); 624 if (i == 1) 625 { 626 state.booklen = header.bytes; 627 state.bookbuf = new byte[state.booklen]; 628 System.arraycopy(header.packet_base, header.packet, 629 state.bookbuf, 0, header.bytes); 630 } 631 i++; 632 header = header_codebooks; 633 } 634 } 635 } 636 637 index = state.oy.buffer(CHUNKSIZE); 638 buffer = state.oy.data; 639 try 640 { 641 bytes = state.in.read(buffer, index, CHUNKSIZE); 642 } 643 catch (Exception e) 644 { 645 System.err.println(e); 646 return false; 647 } 648 649 if (bytes == 0 && i < 2) 650 { 651 System.out.println("EOF before end of vorbis headers."); 652 // goto err; 653 return false; 654 } 655 state.oy.wrote(bytes); 656 } 657 //System.out.println(state.vi); 658 } 659 return retVal; 660 } 661 662 663 /** 664 * Writes (persists) the JOrbisComment object comments to the original file. 665 * 666 * @return Description of the Return Value 667 */ 668 int write() 669 { 670 int retVal = -1; 671 try 672 { 673 // persist any changes back to the file NOTE you could persist this to any other file as well. 674 OutputStream out = new FileOutputStream(this.inFile); 675 retVal = write(out); 676 out.close(); 677 } 678 catch (Exception e) 679 { 680 e.printStackTrace(); 681 System.out.println(e); 682 } 683 return retVal; 684 } 685 686 687 /** 688 * Writes (persists) the JOrbisComment object comments to the outputstream. 689 * 690 * @param out Description of the Parameter 691 * @return Description of the Return Value 692 */ 693 int write(OutputStream out) 694 { 695 StreamState streamout = new StreamState(); 696 Packet header_main = new Packet(); 697 Packet header_comments = new Packet(); 698 Packet header_codebooks = new Packet(); 699 700 Page ogout = new Page(); 701 702 Packet op = new Packet(); 703 long granpos = 0; 704 705 int result; 706 707 int index; 708 byte[] buffer; 709 710 int bytes; 711 712 int eosin = 0; 713 int needflush = 0; 714 int needout = 0; 715 716 header_main.bytes = state.mainlen; 717 header_main.packet_base = state.mainbuf; 718 header_main.packet = 0; 719 header_main.b_o_s = 1; 720 header_main.e_o_s = 0; 721 header_main.granulepos = 0; 722 723 header_codebooks.bytes = state.booklen; 724 header_codebooks.packet_base = state.bookbuf; 725 header_codebooks.packet = 0; 726 header_codebooks.b_o_s = 0; 727 header_codebooks.e_o_s = 0; 728 header_codebooks.granulepos = 0; 729 730 streamout.init(state.serial); 731 732 state.vc.header_out(header_comments); 733 734 streamout.packetin(header_main); 735 streamout.packetin(header_comments); 736 streamout.packetin(header_codebooks); 737 738//System.out.println("%1"); 739 740 while ((result = streamout.flush(ogout)) != 0) 741 { 742//System.out.println("result="+result); 743 try 744 { 745 out.write(ogout.header_base, ogout.header, ogout.header_len); 746 out.flush(); 747 } 748 catch (Exception e) 749 { 750 //goto cleanup; 751 break; 752 } 753 try 754 { 755 out.write(ogout.body_base, ogout.body, ogout.body_len); 756 out.flush(); 757 } 758 catch (Exception e) 759 { 760 //goto cleanup; 761 break; 762 } 763 } 764 765//System.out.println("%2"); 766 767 while (state.fetch_next_packet(op) != 0) 768 { 769 int size = state.blocksize(op); 770 granpos += size; 771//System.out.println("#1"); 772 if (needflush != 0) 773 { 774//System.out.println("##1"); 775 if (streamout.flush(ogout) != 0) 776 { 777 try 778 { 779 out.write(ogout.header_base, ogout.header, ogout.header_len); 780 out.flush(); 781 } 782 catch (Exception e) 783 { 784 e.printStackTrace(); 785 //goto cleanup; 786 return -1; 787 } 788 try 789 { 790 out.write(ogout.body_base, ogout.body, ogout.body_len); 791 out.flush(); 792 } 793 catch (Exception e) 794 { 795 e.printStackTrace(); 796//System.out.println("ogout.body_base.length="+ogout.body_base.length+ 797// ", ogout.body="+ogout.body+ 798// ", ogout.body_len="+ogout.body_len); 799 //goto cleanup; 800 return -1; 801 } 802 } 803 } 804//System.out.println("%2 eosin="+eosin); 805 else if (needout != 0) 806 { 807//System.out.println("##2"); 808 if (streamout.pageout(ogout) != 0) 809 { 810 try 811 { 812 out.write(ogout.header_base, ogout.header, ogout.header_len); 813 out.flush(); 814 } 815 catch (Exception e) 816 { 817 e.printStackTrace(); 818 //goto cleanup; 819 return -1; 820 } 821 try 822 { 823 out.write(ogout.body_base, ogout.body, ogout.body_len); 824 out.flush(); 825 } 826 catch (Exception e) 827 { 828 e.printStackTrace(); 829//System.out.println("ogout.body_base.length="+ogout.body_base.length+ 830// ", ogout.body="+ogout.body+ 831// ", ogout.body_len="+ogout.body_len); 832 //goto cleanup; 833 return -1; 834 } 835 } 836 } 837 838//System.out.println("#2"); 839 840 needflush = needout = 0; 841 842 if (op.granulepos == -1) 843 { 844 op.granulepos = granpos; 845 streamout.packetin(op); 846 } 847 else 848 { 849 if (granpos > op.granulepos) 850 { 851 granpos = op.granulepos; 852 streamout.packetin(op); 853 needflush = 1; 854 } 855 else 856 { 857 streamout.packetin(op); 858 needout = 1; 859 } 860 } 861//System.out.println("#3"); 862 } 863 864//System.out.println("%3"); 865 866 streamout.e_o_s = 1; 867 while (streamout.flush(ogout) != 0) 868 { 869 try 870 { 871 out.write(ogout.header_base, ogout.header, ogout.header_len); 872 out.flush(); 873 } 874 catch (Exception e) 875 { 876 e.printStackTrace(); 877 //goto cleanup; 878 return -1; 879 } 880 try 881 { 882 out.write(ogout.body_base, ogout.body, ogout.body_len); 883 out.flush(); 884 } 885 catch (Exception e) 886 { 887 e.printStackTrace(); 888//System.out.println("ogout.body_base.length="+ogout.body_base.length+ 889// ", ogout.body="+ogout.body+ 890// ", ogout.body_len="+ogout.body_len); 891 //goto cleanup; 892 return -1; 893 } 894 } 895 896//System.out.println("%4"); 897 898 state.vi.clear(); 899//System.out.println("%3 eosin="+eosin); 900 901//System.out.println("%5"); 902 903 eosin = 0; 904 /* 905 * clear it, because not all paths to here do 906 */ 907 while (eosin == 0) 908 { 909 /* 910 * We reached eos, not eof 911 */ 912 /* 913 * We copy the rest of the stream (other logical streams) 914 * through, a page at a time. 915 */ 916 while (true) 917 { 918 result = state.oy.pageout(ogout); 919//System.out.println(" result4="+result); 920 if (result == 0) 921 { 922 break; 923 } 924 if (result < 0) 925 { 926 System.out.println("Corrupt or missing data, continuing..."); 927 } 928 else 929 { 930 /* 931 * Don't bother going through the rest, we can just 932 * write the page out now 933 */ 934 try 935 { 936 out.write(ogout.header_base, ogout.header, ogout.header_len); 937 out.flush(); 938 } 939 catch (Exception e) 940 { 941 //goto cleanup; 942 return -1; 943 } 944 try 945 { 946 out.write(ogout.body_base, ogout.body, ogout.body_len); 947 out.flush(); 948 } 949 catch (Exception e) 950 { 951 //goto cleanup; 952 return -1; 953 } 954 } 955 } 956 957 index = state.oy.buffer(CHUNKSIZE); 958 buffer = state.oy.data; 959 try 960 { 961 bytes = state.in.read(buffer, index, CHUNKSIZE); 962 } 963 catch (Exception e) 964 { 965 System.err.println(e); 966 return -1; 967 } 968//System.out.println("bytes="+bytes); 969 state.oy.wrote(bytes); 970 971 if (bytes == 0 || bytes == -1) 972 { 973 eosin = 1; 974 break; 975 } 976 } 977 978 /* 979 * cleanup: 980 * ogg_stream_clear(&streamout); 981 * ogg_packet_clear(&header_comments); 982 * free(state->mainbuf); 983 * free(state->bookbuf); 984 * jorbiscomment_clear_internals(state); 985 * if(!eosin) 986 * { 987 * state->lasterror = 988 * "Error writing stream to output. " 989 * "Output stream may be corrupted or truncated."; 990 * return -1; 991 * } 992 * return 0; 993 * } 994 */ 995 return 0; 996 } 997} 998 999 1000/** 1001 * Description of the Class 1002 * 1003 * @author tgutwin 1004 */ 1005class State 1006{ 1007 1008 1009 /** Description of the Field */ 1010 private static int CHUNKSIZE = 4096; 1011 /** Description of the Field */ 1012 SyncState oy; 1013 /** Description of the Field */ 1014 StreamState os; 1015 /** Description of the Field */ 1016 Comment vc; 1017 /** Description of the Field */ 1018 Info vi; 1019 1020 /** Description of the Field */ 1021 InputStream in; 1022 /** Description of the Field */ 1023 int serial; 1024 /** Description of the Field */ 1025 byte[] mainbuf; 1026 /** Description of the Field */ 1027 byte[] bookbuf; 1028 /** Description of the Field */ 1029 int mainlen; 1030 /** Description of the Field */ 1031 int booklen; 1032 /** Description of the Field */ 1033 String lasterror; 1034 1035 /** Description of the Field */ 1036 int prevW; 1037 1038 /** Description of the Field */ 1039 Page og = new Page(); 1040 1041 1042 /** 1043 * Description of the Method 1044 * 1045 * @param p Description of the Parameter 1046 * @return Description of the Return Value 1047 */ 1048 int blocksize(Packet p) 1049 { 1050 int _this = vi.blocksize(p); 1051 int ret = (_this + prevW) / 4; 1052 1053 if (prevW == 0) 1054 { 1055 prevW = _this; 1056 return 0; 1057 } 1058 1059 prevW = _this; 1060 return ret; 1061 } 1062 1063 1064 /** 1065 * Description of the Method 1066 * 1067 * @param p Description of the Parameter 1068 * @return Description of the Return Value 1069 */ 1070 int fetch_next_packet(Packet p) 1071 { 1072 int result; 1073 byte[] buffer; 1074 int index; 1075 int bytes; 1076 1077 result = os.packetout(p); 1078 1079 if (result > 0) 1080 { 1081 return 1; 1082 } 1083 1084 while (oy.pageout(og) <= 0) 1085 { 1086 index = oy.buffer(CHUNKSIZE); 1087 buffer = oy.data; 1088 try 1089 { 1090 bytes = in.read(buffer, index, CHUNKSIZE); 1091 } 1092 catch (Exception e) 1093 { 1094 System.err.println(e); 1095 return 0; 1096 } 1097 if (bytes > 0) 1098 { 1099 oy.wrote(bytes); 1100 } 1101 if (bytes == 0 || bytes == -1) 1102 { 1103 return 0; 1104 } 1105 } 1106 os.pagein(og); 1107 1108 return fetch_next_packet(p); 1109 } 1110} 1111