Initial revision
[old-projects.git] / ekit / com / hexidec / util / DMCScodec.java
diff --git a/ekit/com/hexidec/util/DMCScodec.java b/ekit/com/hexidec/util/DMCScodec.java
new file mode 100644 (file)
index 0000000..bf797f0
--- /dev/null
@@ -0,0 +1 @@
+/*\rGNU General Public License\r\rDMCScodec\rCopyright (C) 2002  Howard A Kistler\r\rThis program is free software; you can redistribute it and/or\rmodify it under the terms of the GNU General Public License\ras published by the Free Software Foundation; either version 2\rof the License, or (at your option) any later version.\r\rThis program is distributed in the hope that it will be useful,\rbut WITHOUT ANY WARRANTY; without even the implied warranty of\rMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\rGNU General Public License for more details.\r\rYou should have received a copy of the GNU General Public License\ralong with this program; if not, write to the Free Software\rFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r*/\r\rpackage com.hexidec.util;\r\rimport java.awt.AWTException;\rimport java.io.File;\rimport java.io.FileInputStream;\rimport java.io.FileNotFoundException;\rimport java.io.FileOutputStream;\rimport java.io.FileWriter;\rimport java.io.IOException;\r\r/** DMCScodec\r  *\r  * Utility for reading (and eventually converting) Deluxe Music\r  * Construction Set (DMCS) files\r  *\r  * @author Howard Kistler\r  * @version 0.1\r  *\r  * VERSION HISTORY\r  * 0.1 (03/13/2002) - initial creation (03/13/2002)\r  */\r\rpublic class DMCScodec\r{\r\r//  Constants ---------------------------------------------------------------------------->\r\r/*\r       DMCS File Structure\r\r   FILE HEADER\r    ====================\r   (At the beginning of each file)\r        FILE HEADER BLOCK\r              4 bytes - FORM\r         4 bytes - ?\r            4 bytes - DMCS\r         4 bytes - AMGA (for Amiga files)\r               4 bytes - ? (all zeroes?)\r      SC HEADER BLOCK\r                4 bytes - USC1\r         8 bytes - ?\r            4 bytes - ?\r            8 bytes - ?\r            4 x 32 bytes - ?\r               1 byte - Title Byte count (number of letters in song title)\r            X bytes - Song Title (length stated in previous byte)\r          16 bytes - 00 05 FE 77 01 01 01 02 00 00 3F 80 00 7F 00 00\r\r    SONG BODY\r      ====================\r   UBR1 BLOCKS\r            4 bytes - UBR1\r\r        INSTRUMENT BLOCK\r       ====================\r   (At the end of each file)\r      INSTRUMENT HEAD BLOCK\r          4 bytes - UVLT\r         22 bytes -  00 00 00 12 00 00 00 0A 00 13 00 1F 00 2F 00 3F 00 51 00 69 00 7F\r  INDIVIDUAL INSTRUMENT BLOCKS\r           4 bytes - UIID\r         4 bytes - ? (small int)\r                X bytes - Instrument Name\r              2 bytes - 00 00 (last instrument may have just one byte of 00)\r*/\r\r     // Header Array Sizes\r  private final static byte StartFileHeaderSize = (byte)20;\r      private final static byte InfoHeaderSize = (byte)40; // InfoHeader is always 40 bytes in size for BMP/ICO/CUR format\r\r  // File Header Fields\r  private final static byte[] FileHeaderFormWord = { 'F', 'O', 'R', 'M', };\r      private       static byte[] FileHeaderSizeWord = new byte[4];\r  private final static byte[] FileHeaderTypeWord = { 'D', 'M', 'C', 'S' };\r       private final static byte[] FileHeaderOSAMWord = { 'A', 'M', 'G', 'A' }; // OS Word for Amiga DMCS files\r       private final static byte[] FileHeaderTailWord = { (byte)0, (byte)0, (byte)0, (byte)0 };\r\r      // Song Body Fields\r    private final static byte[] SongBlockUnitWord = { 'U', 'B', 'R', '1' };\r\r       // Instrument Body Fields\r      private final static byte[] InstrumentBlockHeadWord = { 'U', 'V', 'L', 'T' };\r  private final static byte[] InstrumentBlockUnitWord = { 'U', 'I', 'I', 'D' };\r\r//  Public Vartypes ---------------------------------------------------------------------->\r\r    public final static int FILETYPE_DMCS   = 1;\r   public final static int FILETYPE_TEXT   = 2;\r   public final static int FILETYPE_FINALE = 3;\r\r//  Constructor -------------------------------------------------------------------------->\r\r     public DMCScodec()\r     {\r      }\r\r//  Decode Method ------------------------------------------------------------------------>\r\r        public static void decode(String sourceFile, String destFile)\r  throws FileNotFoundException, IOException, AWTException\r        {\r              convertToTextFile(sourceFile, destFile);\r       }\r\r//  Encode Method ------------------------------------------------------------------------>\r\r        public static void encode(String sourceFile, String destFile, int fileType)\r    throws FileNotFoundException, IOException, AWTException\r        {\r//            String newFormat = convertToFormat(sourceFile, fileType);\r//            writeToDMCSFile(newFormat, destFile);\r  }\r\r//  DMCS-to-TEXT File Conversion -------------------------------------------------------->\r\r protected static void convertToTextFile(String inFile, String outFile)\r throws IOException\r     {\r              File srcFile = new File(inFile);\r               FileInputStream fis = new FileInputStream(srcFile);\r            int filesize = (int)(srcFile.length());\r                byte[] bData = new byte[filesize];\r             int iCounter = 0;\r              while(iCounter < filesize)\r             {\r                      bData[iCounter] = (byte)(fis.read());\r                  iCounter++;\r            }\r              fis.close();\r\r          FileWriter fw = new FileWriter(new File(outFile));\r\r            String sOutput = "FILE SIZE  : " + srcFile.length() + "\r";\r            fw.write(sOutput, 0, sOutput.length());\r\r               sOutput = "BYTES READ : " + iCounter + "\r";\r           fw.write(sOutput, 0, sOutput.length());\r\r               int iPlace = 0;\r\r               sOutput = "====================\rFILE HEADER\r====================\r";\r         fw.write(sOutput, 0, sOutput.length());\r\r               sOutput = "--------------------\rFILE HEADER BLOCK\r--------------------\r";\r           fw.write(sOutput, 0, sOutput.length());\r\r               sOutput = "FORM BLOCK : " + (char)(bData[iPlace++]) + (char)(bData[iPlace++]) + (char)(bData[iPlace++]) + (char)(bData[iPlace++]) + "\r";\r              fw.write(sOutput, 0, sOutput.length());\r\r               int iSize =\r                    (int)(\r                         ((bData[iPlace++]) << 24) +\r                            ((bData[iPlace++]) << 16) +\r                            ((bData[iPlace++]) <<  8) +\r                            ((bData[iPlace++])      )\r                              );\r             sOutput = "SIZE BLOCK : " + iSize + "\r";\r              fw.write(sOutput, 0, sOutput.length());\r\r               sOutput = "TYPE BLOCK : " + (char)(bData[iPlace++]) + (char)(bData[iPlace++]) + (char)(bData[iPlace++]) + (char)(bData[iPlace++]) + "\r";\r              fw.write(sOutput, 0, sOutput.length());\r\r               sOutput = "OS BLOCK   : " + (char)(bData[iPlace++]) + (char)(bData[iPlace++]) + (char)(bData[iPlace++]) + (char)(bData[iPlace++]) + "\r";\r              fw.write(sOutput, 0, sOutput.length());\r\r               sOutput = "TAIL BLOCK : " + (char)(bData[iPlace++]) + (char)(bData[iPlace++]) + (char)(bData[iPlace++]) + (char)(bData[iPlace++]) + "\r";\r              fw.write(sOutput, 0, sOutput.length());\r\r               sOutput = "--------------------\rSC HEADER BLOCK\r--------------------\r";\r             fw.write(sOutput, 0, sOutput.length());\r\r               sOutput = "USC1 BLOCK : " + (char)(bData[iPlace++]) + (char)(bData[iPlace++]) + (char)(bData[iPlace++]) + (char)(bData[iPlace++]) + "\r";\r              fw.write(sOutput, 0, sOutput.length());\r\r               int iData =\r                    (int)(\r                         ((bData[iPlace++]) << 24) +\r                            ((bData[iPlace++]) << 16) +\r                            ((bData[iPlace++]) <<  8) +\r                            ((bData[iPlace++])      )\r                              );\r             sOutput = "DATA INT 1 : " + iData + "\r";\r              fw.write(sOutput, 0, sOutput.length());\r\r               iData =\r                        (int)(\r                         ((bData[iPlace++]) << 24) +\r                            ((bData[iPlace++]) << 16) +\r                            ((bData[iPlace++]) <<  8) +\r                            ((bData[iPlace++])      )\r                              );\r             sOutput = "DATA INT 2 : " + iData + "\r";\r              fw.write(sOutput, 0, sOutput.length());\r\r               iData =\r                        (int)(\r                         ((bData[iPlace++]) << 24) +\r                            ((bData[iPlace++]) << 16) +\r                            ((bData[iPlace++]) <<  8) +\r                            ((bData[iPlace++])      )\r                              );\r             sOutput = "DATA INT 3 : " + iData + "\r";\r              fw.write(sOutput, 0, sOutput.length());\r\r               iData =\r                        (int)(\r                         ((bData[iPlace++]) << 24) +\r                            ((bData[iPlace++]) << 16) +\r                            ((bData[iPlace++]) <<  8) +\r                            ((bData[iPlace++])      )\r                              );\r             sOutput = "DATA INT 4 : " + iData + "\r";\r              fw.write(sOutput, 0, sOutput.length());\r\r               iData =\r                        (int)(\r                         ((bData[iPlace++]) << 24) +\r                            ((bData[iPlace++]) << 16) +\r                            ((bData[iPlace++]) <<  8) +\r                            ((bData[iPlace++])      )\r                              );\r             sOutput = "DATA INT 5 : " + iData + "\r";\r              fw.write(sOutput, 0, sOutput.length());\r\r               for(int i = 0; i < 32; i++)\r            {\r                      iData =\r                                (int)(\r                                 ((bData[iPlace++]) << 24) +\r                                    ((bData[iPlace++]) << 16) +\r                                    ((bData[iPlace++]) <<  8) +\r                                    ((bData[iPlace++])      )\r                                      );\r                     sOutput = "SUB INT " + (i+1) + " : " + iData + "\r";\r                   fw.write(sOutput, 0, sOutput.length());\r                }\r\r             sOutput = "PAD BYTES  : " + bData[iPlace++] + bData[iPlace++] + bData[iPlace++] + bData[iPlace++] + "\r";\r              fw.write(sOutput, 0, sOutput.length());\r\r               int titleCharCount = (int)(bData[iPlace++]);\r           sOutput = "TITLE BYTE : " + titleCharCount  + "\r";\r            fw.write(sOutput, 0, sOutput.length());\r\r               sOutput = "SONG TITLE : ";\r             for(int i = 0; i < titleCharCount; i++)\r                {\r                      sOutput = sOutput + (char)(bData[iPlace++]);\r           }\r              sOutput = sOutput + "\r";\r              fw.write(sOutput, 0, sOutput.length());\r\r               for(int i = 0; i < 19; i++)\r            {\r                      sOutput = "POST BYTE " + (i+1) + " : " + bData[iPlace++] + "\r";\r                       fw.write(sOutput, 0, sOutput.length());\r                }\r\r             sOutput = "====================\rSONG BODY\r====================\r";\r           fw.write(sOutput, 0, sOutput.length());\r\r               byte byteA = (byte)0;\r          byte byteB = (byte)0;\r          String blockWord = "";\r         while(iPlace < filesize - 5)\r           {\r                      byteA = bData[iPlace++];\r                       byteB = bData[iPlace++];\r                       blockWord = "" + (char)byteA + (char)byteB;\r                    if(blockWord.equals("UB"))\r                     {\r                              byte byteC = bData[iPlace++];\r                          byte byteD = bData[iPlace++];\r                          String blockWord2 = "" + (char)byteC + (char)byteD;\r                            if(blockWord2.equals("R1"))\r                            {\r                                      sOutput = "--------------------\rUBR1 DATA BLOCK\r--------------------\r";\r                                     fw.write(sOutput, 0, sOutput.length());\r\r                                       sOutput = "DATA HEAD  : " + blockWord + blockWord2 + "\r";\r                                     fw.write(sOutput, 0, sOutput.length());\r                                }\r                              else\r                           {\r                                      int iWord =\r                                            (int)(\r                                                 (byteA <<  8) +\r                                                        (byteB      )\r                                                  );\r                                     sOutput = "WORD VALUE : " + iWord + "\r";\r                                      fw.write(sOutput, 0, sOutput.length());\r                                        iWord =\r                                                (int)(\r                                                 (byteC <<  8) +\r                                                        (byteD      )\r                                                  );\r                                     sOutput = "WORD VALUE : " + iWord + "\r";\r                                      fw.write(sOutput, 0, sOutput.length());\r                                }\r                      }\r                      else if(blockWord.equals("UV"))\r                        {\r                              byte byteC = bData[iPlace++];\r                          byte byteD = bData[iPlace++];\r                          String blockWord2 = "" + (char)byteC + (char)byteD;\r                            if(blockWord2.equals("LT"))\r                            {\r                                      sOutput = "====================\rINSTRUMENT BLOCK\r====================\r";\r                                    fw.write(sOutput, 0, sOutput.length());\r        \r                                       sOutput = "--------------------\rINSTRUMENT HEAD BLOCK\r--------------------\r";\r                                       fw.write(sOutput, 0, sOutput.length());\r        \r                                       sOutput = "GROUP HEAD : " + blockWord + blockWord2 + "\r";\r                                     fw.write(sOutput, 0, sOutput.length());\r\r                                       int iWord = 0;\r                                 for(int i = 0; i < 11; i++)\r                                    {\r                                              iWord =\r                                                        (int)(\r                                                         ((bData[iPlace++]) <<  8) +\r                                                            ((bData[iPlace++])      )\r                                                              );\r                                             sOutput = "SUB WORD " + (i+1) + " : " + iWord + "\r";\r                                          fw.write(sOutput, 0, sOutput.length());\r                                        }\r                              }\r                              else\r                           {\r                                      int iWord =\r                                            (int)(\r                                                 (byteA <<  8) +\r                                                        (byteB      )\r                                                  );\r                                     sOutput = "WORD VALUE : " + iWord + "\r";\r                                      fw.write(sOutput, 0, sOutput.length());\r                                        iWord =\r                                                (int)(\r                                                 (byteC <<  8) +\r                                                        (byteD      )\r                                                  );\r                                     sOutput = "WORD VALUE : " + iWord + "\r";\r                                      fw.write(sOutput, 0, sOutput.length());\r                                }\r                      }\r                      else if(blockWord.equals("UI"))\r                        {\r                              byte byteC = bData[iPlace++];\r                          byte byteD = bData[iPlace++];\r                          String blockWord2 = "" + (char)byteC + (char)byteD;\r                            if(blockWord2.equals("ID"))\r                            {\r                                      sOutput = "--------------------\rINDIVIDUAL INSTRUMENT BLOCK\r--------------------\r";\r                                 fw.write(sOutput, 0, sOutput.length());\r\r                                       sOutput = "INSTR HEAD : " + blockWord + blockWord2 + "\r";\r                                     fw.write(sOutput, 0, sOutput.length());\r\r                                       int iVal =\r                                             (int)(\r                                                 ((bData[iPlace++]) << 24) +\r                                                    ((bData[iPlace++]) << 16) +\r                                                    ((bData[iPlace++]) <<  8) +\r                                                    ((bData[iPlace++])      )\r                                                      );\r                                     sOutput = "NAME BYTES : " + iVal + "\r";\r                                       fw.write(sOutput, 0, sOutput.length());\r\r                                       sOutput = "INSTR NAME : ";\r                                     for(int i = 0; i < iVal - 1; i++)\r                                      {\r                                              sOutput = sOutput + (char)(bData[iPlace++]);\r                                   }\r                                      sOutput = sOutput + "\r";\r                                      fw.write(sOutput, 0, sOutput.length());\r\r                                       if(iPlace < filesize - 2)\r                                      {\r                                              sOutput = "PAD BYTES  : " + bData[iPlace++] + bData[iPlace++] + "\r";\r                                          fw.write(sOutput, 0, sOutput.length());\r                                        }\r                              }\r                              else\r                           {\r                                      int iWord =\r                                            (int)(\r                                                 (byteA <<  8) +\r                                                        (byteB      )\r                                                  );\r                                     sOutput = "WORD VALUE : " + iWord + "\r";\r                                      fw.write(sOutput, 0, sOutput.length());\r                                        iWord =\r                                                (int)(\r                                                 (byteC <<  8) +\r                                                        (byteD      )\r                                                  );\r                                     sOutput = "WORD VALUE : " + iWord + "\r";\r                                      fw.write(sOutput, 0, sOutput.length());\r                                }\r                      }\r                      else {\r                         int iWord =\r                                    (int)(\r                                         (byteA <<  8) +\r                                                (byteB      )\r                                          );\r                             sOutput = "WORD VALUE : " + iWord + "\r";\r                              fw.write(sOutput, 0, sOutput.length());\r                        }\r              }\r\r             fw.flush();\r            fw.close();\r    }\r\r//  File Write Method ------------------------------------------------------------------->\r\r protected static void writeToDMCSFile(String fileData, String outFile)\r throws IOException\r     {\r              FileOutputStream fos = new FileOutputStream(new File(outFile));\r\r               byte FileSizeByte1 = (byte)(fileData.length()         & 0xFF);\r         byte FileSizeByte2 = (byte)((fileData.length() >> 8)  & 0xFF);\r         byte FileSizeByte3 = (byte)((fileData.length() >> 16) & 0xFF);\r         byte FileSizeByte4 = (byte)((fileData.length() >> 24) & 0xFF);\r\r                byte[] DMCSFileHeader = new byte[]\r             {\r                      FileHeaderFormWord[0], FileHeaderFormWord[1], FileHeaderFormWord[2], FileHeaderFormWord[3],\r                    FileSizeByte1,         FileSizeByte2,         FileSizeByte3,         FileSizeByte4,\r                    FileHeaderTypeWord[0], FileHeaderTypeWord[1], FileHeaderTypeWord[2], FileHeaderTypeWord[3],\r                    FileHeaderOSAMWord[0], FileHeaderOSAMWord[1], FileHeaderOSAMWord[2], FileHeaderOSAMWord[3],\r                    FileHeaderTailWord[0], FileHeaderTailWord[1], FileHeaderTailWord[2], FileHeaderTailWord[3]\r             };\r             fos.write(DMCSFileHeader);\r\r/*\r         byte BitmapWidthByte1      = (byte)(IntBitmapWidth          & 0xFF);\r           byte BitmapWidthByte2      = (byte)((IntBitmapWidth >> 8)   & 0xFF);\r           byte BitmapWidthByte3      = (byte)((IntBitmapWidth >> 16)  & 0xFF);\r           byte BitmapWidthByte4      = (byte)((IntBitmapWidth >> 24)  & 0xFF);\r           byte BitmapHeightByte1     = (byte)(IntBitmapHeight         & 0xFF);\r           byte BitmapHeightByte2     = (byte)((IntBitmapHeight >> 8)  & 0xFF);\r           byte BitmapHeightByte3     = (byte)((IntBitmapHeight >> 16) & 0xFF);\r           byte BitmapHeightByte4     = (byte)((IntBitmapHeight >> 24) & 0xFF);\r           byte BitmapImageSizeByte1  = (byte)(IntBitmapSize           & 0xFF);\r           byte BitmapImageSizeByte2  = (byte)((IntBitmapSize >> 8)    & 0xFF);\r           byte BitmapImageSizeByte3  = (byte)((IntBitmapSize >> 16)   & 0xFF);\r           byte BitmapImageSizeByte4  = (byte)((IntBitmapSize >> 24)   & 0xFF);\r\r          byte[] BitmapBodyHeader = new byte[] {\r                 InfoHeaderSizeByte1,        InfoHeaderSizeByte2,        InfoHeaderSizeByte3,        InfoHeaderSizeByte4,\r                       BitmapWidthByte1,           BitmapWidthByte2,           BitmapWidthByte3,           BitmapWidthByte4,\r                  BitmapHeightByte1,          BitmapHeightByte2,          BitmapHeightByte3,          BitmapHeightByte4,\r                 BitmapPlanesByte1,          BitmapPlanesByte2,\r                 BitmapBitCountByte1,        BitmapBitCountByte2,\r                       BitmapCompressionByte1,     BitmapCompressionByte2,     BitmapCompressionByte3,     BitmapCompressionByte4,\r                    BitmapImageSizeByte1,       BitmapImageSizeByte2,       BitmapImageSizeByte3,       BitmapImageSizeByte4,\r                      BitmapXPixelsPerMByte1,     BitmapXPixelsPerMByte2,     BitmapXPixelsPerMByte3,     BitmapXPixelsPerMByte4,\r                    BitmapYPixelsPerMByte1,     BitmapYPixelsPerMByte2,     BitmapYPixelsPerMByte3,     BitmapYPixelsPerMByte4,\r                    BitmapColorsUsedByte1,      BitmapColorsUsedByte2,      BitmapColorsUsedByte3,      BitmapColorsUsedByte4,\r                     BitmapColorsImportantByte1, BitmapColorsImportantByte2, BitmapColorsImportantByte3, BitmapColorsImportantByte4\r         };\r             fos.write(BitmapBodyHeader);\r\r          int bodySize = IntBitmapWidth * IntBitmapHeight;\r               int bitPad = 4 - ((IntBitmapWidth * 3) % 4);\r           if(bitPad == 4) { bitPad = 0; }\r                int countRow = 1;\r              int indexRow = bodySize - IntBitmapWidth;\r              int indexLastRow = indexRow;\r           byte[] rgbArray = new byte[3];\r\r                for(int i = 0; i < bodySize; i++)\r              {\r                      int colorValue = PixelMap[indexRow];\r                   rgbArray[0] = (byte)(colorValue         & 0xFF); // red\r                        rgbArray[1] = (byte)((colorValue >> 8)  & 0xFF); // green\r                      rgbArray[2] = (byte)((colorValue >> 16) & 0xFF); // blue\r                       fos.write(rgbArray);\r                   if(countRow == IntBitmapWidth)\r                 {\r                              // pad row to 4 bits requirement\r                               for(int p = 0; p < bitPad; p++)\r                                {\r                                      fos.write(0x00);\r                               }\r                              countRow = 1;\r                          indexRow = indexLastRow - IntBitmapWidth;\r                              indexLastRow = indexRow;\r                       }\r                      else\r                   {\r                              countRow++;\r                    }\r                      indexRow++;\r            }\r*/\r\r          fos.flush();\r           fos.close();\r   }\r\r     public static void main(String[] args)\r {\r              if(args.length < 3)\r            {\r                      System.out.println("USAGE : DMCScodec -action input output");\r          }\r              else\r           {\r                      if(args[0].equals("-t"))\r                       {\r                              try\r                            {\r                                      decode(args[1], args[2]);\r                              }\r                              catch(Exception e)\r                             {\r                                      System.out.println(e);\r                         }\r                      }\r                      else\r                   {\r                              System.out.println("action " + args[0] + "not yet supported");\r                 }\r              }\r      }\r\r}\r
\ No newline at end of file