将.c转换为.java

有什么工具可以将C代码转换成Java代码吗? 我有兴趣将此代码转换为Java:

***************************************************************************/ /* ** UNECM - Decoder for ECM (Error Code Modeler) format. ** Version 1.0 ** Copyright (C) 2002 Neill Corlett ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License ** as published by the Free Software Foundation; either version 2 ** of the License, or (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /***************************************************************************/ /* ** Portability notes: ** ** - Assumes a 32-bit or higher integer size ** - No assumptions about byte order ** - No assumptions about struct packing ** - No unaligned memory access */ /***************************************************************************/ #include  #include  #include  /***************************************************************************/ void banner(void) { fprintf(stderr, "UNECM - Decoder for Error Code Modeler format v1.0\n" "Copyright (C) 2002 Neill Corlett\n\n" ); } /***************************************************************************/ /* Data types */ #define ecc_uint8 unsigned char #define ecc_uint16 unsigned short #define ecc_uint32 unsigned /* LUTs used for computing ECC/EDC */ static ecc_uint8 ecc_f_lut[256]; static ecc_uint8 ecc_b_lut[256]; static ecc_uint32 edc_lut[256]; /* Init routine */ static void eccedc_init(void) { ecc_uint32 i, j, edc; for(i = 0; i < 256; i++) { j = (i << 1) ^ (i & 0x80 ? 0x11D : 0); ecc_f_lut[i] = j; ecc_b_lut[i ^ j] = i; edc = i; for(j = 0; j > 1) ^ (edc & 1 ? 0xD8018001 : 0); edc_lut[i] = edc; } } /***************************************************************************/ /* ** Compute EDC for a block */ ecc_uint32 edc_partial_computeblock( ecc_uint32 edc, const ecc_uint8 *src, ecc_uint16 size ) { while(size--) edc = (edc >> 8) ^ edc_lut[(edc ^ (*src++)) & 0xFF]; return edc; } void edc_computeblock( const ecc_uint8 *src, ecc_uint16 size, ecc_uint8 *dest ) { ecc_uint32 edc = edc_partial_computeblock(0, src, size); dest[0] = (edc >> 0) & 0xFF; dest[1] = (edc >> 8) & 0xFF; dest[2] = (edc >> 16) & 0xFF; dest[3] = (edc >> 24) & 0xFF; } /***************************************************************************/ /* ** Compute ECC for a block (can do either P or Q) */ static void ecc_computeblock( ecc_uint8 *src, ecc_uint32 major_count, ecc_uint32 minor_count, ecc_uint32 major_mult, ecc_uint32 minor_inc, ecc_uint8 *dest ) { ecc_uint32 size = major_count * minor_count; ecc_uint32 major, minor; for(major = 0; major > 1) * major_mult + (major & 1); ecc_uint8 ecc_a = 0; ecc_uint8 ecc_b = 0; for(minor = 0; minor = size) index -= size; ecc_a ^= temp; ecc_b ^= temp; ecc_a = ecc_f_lut[ecc_a]; } ecc_a = ecc_b_lut[ecc_f_lut[ecc_a] ^ ecc_b]; dest[major ] = ecc_a; dest[major + major_count] = ecc_a ^ ecc_b; } } /* ** Generate ECC P and Q codes for a block */ static void ecc_generate( ecc_uint8 *sector, int zeroaddress ) { ecc_uint8 address[4], i; /* Save the address and zero it out */ if(zeroaddress) for(i = 0; i < 4; i++) { address[i] = sector[12 + i]; sector[12 + i] = 0; } /* Compute ECC P code */ ecc_computeblock(sector + 0xC, 86, 24, 2, 86, sector + 0x81C); /* Compute ECC Q code */ ecc_computeblock(sector + 0xC, 52, 43, 86, 88, sector + 0x8C8); /* Restore the address */ if(zeroaddress) for(i = 0; i < 4; i++) sector[12 + i] = address[i]; } /***************************************************************************/ /* ** Generate ECC/EDC information for a sector (must be 2352 = 0x930 bytes) ** Returns 0 on success */ void eccedc_generate(ecc_uint8 *sector, int type) { ecc_uint32 i; switch(type) { case 1: /* Mode 1 */ /* Compute EDC */ edc_computeblock(sector + 0x00, 0x810, sector + 0x810); /* Write out zero bytes */ for(i = 0; i > 20) != (mycounter >> 20)) { unsigned a = (n+64)/128; unsigned d = (mycounter_total+64)/128; if(!d) d = 1; fprintf(stderr, "Decoding (%02d%%)\r", (100*a) / d); } mycounter = n; } int unecmify( FILE *in, FILE *out ) { unsigned checkedc = 0; unsigned char sector[2352]; unsigned type; unsigned num; fseek(in, 0, SEEK_END); resetcounter(ftell(in)); fseek(in, 0, SEEK_SET); if( (fgetc(in) != 'E') || (fgetc(in) != 'C') || (fgetc(in) != 'M') || (fgetc(in) != 0x00) ) { fprintf(stderr, "Header not found!\n"); goto corrupt; } for(;;) { int c = fgetc(in); int bits = 5; if(c == EOF) goto uneof; type = c & 3; num = (c >> 2) & 0x1F; while(c & 0x80) { c = fgetc(in); if(c == EOF) goto uneof; num |= ((unsigned)(c & 0x7F)) <= 0x80000000) goto corrupt; if(!type) { while(num) { int b = num; if(b > 2352) b = 2352; if(fread(sector, 1, b, in) != b) goto uneof; checkedc = edc_partial_computeblock(checkedc, sector, b); fwrite(sector, 1, b, out); num -= b; setcounter(ftell(in)); } } else { while(num--) { memset(sector, 0, sizeof(sector)); memset(sector + 1, 0xFF, 10); switch(type) { case 1: sector[0x0F] = 0x01; if(fread(sector + 0x00C, 1, 0x003, in) != 0x003) goto uneof; if(fread(sector + 0x010, 1, 0x800, in) != 0x800) goto uneof; eccedc_generate(sector, 1); checkedc = edc_partial_computeblock(checkedc, sector, 2352); fwrite(sector, 2352, 1, out); setcounter(ftell(in)); break; case 2: sector[0x0F] = 0x02; if(fread(sector + 0x014, 1, 0x804, in) != 0x804) goto uneof; sector[0x10] = sector[0x14]; sector[0x11] = sector[0x15]; sector[0x12] = sector[0x16]; sector[0x13] = sector[0x17]; eccedc_generate(sector, 2); checkedc = edc_partial_computeblock(checkedc, sector + 0x10, 2336); fwrite(sector + 0x10, 2336, 1, out); setcounter(ftell(in)); break; case 3: sector[0x0F] = 0x02; if(fread(sector + 0x014, 1, 0x918, in) != 0x918) goto uneof; sector[0x10] = sector[0x14]; sector[0x11] = sector[0x15]; sector[0x12] = sector[0x16]; sector[0x13] = sector[0x17]; eccedc_generate(sector, 3); checkedc = edc_partial_computeblock(checkedc, sector + 0x10, 2336); fwrite(sector + 0x10, 2336, 1, out); setcounter(ftell(in)); break; } } } } if(fread(sector, 1, 4, in) != 4) goto uneof; fprintf(stderr, "Decoded %ld bytes -> %ld bytes\n", ftell(in), ftell(out)); if( (sector[0] != ((checkedc >> 0) & 0xFF)) || (sector[1] != ((checkedc >> 8) & 0xFF)) || (sector[2] != ((checkedc >> 16) & 0xFF)) || (sector[3] != ((checkedc >> 24) & 0xFF)) ) { fprintf(stderr, "EDC error (%08X, should be %02X%02X%02X%02X)\n", checkedc, sector[3], sector[2], sector[1], sector[0] ); goto corrupt; } fprintf(stderr, "Done; file is OK\n"); return 0; uneof: fprintf(stderr, "Unexpected EOF!\n"); corrupt: fprintf(stderr, "Corrupt ECM file!\n"); return 1; } /***************************************************************************/ int main(int argc, char **argv) { FILE *fin, *fout; char *infilename; char *outfilename; banner(); /* ** Initialize the ECC/EDC tables */ eccedc_init(); /* ** Check command line */ if((argc != 2) && (argc != 3)) { fprintf(stderr, "usage: %s ecmfile [outputfile]\n", argv[0]); return 1; } /* ** Verify that the input filename is valid */ infilename = argv[1]; if(strlen(infilename) < 5) { fprintf(stderr, "filename '%s' is too short\n", infilename); return 1; } if(strcasecmp(infilename + strlen(infilename) - 4, ".ecm")) { fprintf(stderr, "filename must end in .ecm\n"); return 1; } /* ** Figure out what the output filename should be */ if(argc == 3) { outfilename = argv[2]; } else { outfilename = malloc(strlen(infilename) - 3); if(!outfilename) abort(); memcpy(outfilename, infilename, strlen(infilename) - 4); outfilename[strlen(infilename) - 4] = 0; } fprintf(stderr, "Decoding %s to %s.\n", infilename, outfilename); /* ** Open both files */ fin = fopen(infilename, "rb"); if(!fin) { perror(infilename); return 1; } fout = fopen(outfilename, "wb"); if(!fout) { perror(outfilename); fclose(fin); return 1; } /* ** Decode */ unecmify(fin, fout); /* ** Close everything */ fclose(fout); fclose(fin); return 0; } 

您是否考虑过使用JNI而不是费心去做从C到Java的翻译?

最好的办法是重写代码。

任何自动转换最多都会产生质量差且难以维护的代码。

世界的C视图与世界的Java视图并不完美。 如果您真的想要编译为Java可执行的表单,请查看NestedVM – http://nestedvm.ibex.org/ – 这是一个编译为MIPS方言的交叉编译器,然后可以很容易地“运行” Java可以通过解释或转换为反映原始MIPS指令的实际字节码。

我建议获得Java版本的代码。

曾经有一些名为Ephedra,Convert2Java和C2J ++的工具。 但它们并没有真正起作用,而且不再可用。 这使得三家公司在无法使用,有用和良好的范围内提供自动C到Java的翻译:

  1. Novosoft ,C2J:创建的Java代码需要认真的手动工作。 C2J创建了一些不可读的代码(支持非常有限的指针)并且不支持unsigned types / goto语句/ native libraries / macros / comments / …
  2. 有形软件解决方案 ,C ++ 2Java:创建的Java代码需要一些手动工作。 C ++ 2Java不支持指针/无符号类型/ goto语句/本机库/宏/ …(Sachin Bhansali发布了上面的uncm C代码的翻译)
  3. mtSystems ,Coot:创建function等效的代码(通过完全支持指针,函数指针,无符号类型,goto语句,本机库……)和可读代码(保留宏/注释,重命名标识符,应用各种优化,… )。

这里是mtSystems创建的类(未改变):

 import static ch.mtsystems.coot.String8.cs8; import static ch.mtsystems.coot.String8.nnc; import ch.mtsystems.coot.String8; import java.io.IOException; import java.io.RandomAccessFile; public class Unecm { public static void banner() { System.err.println("UNECM - Decoder for Error Code Modeler format v1.0\nCopyright (C) 2002 Neill Corlett\n"); } /** * LUTs used for computing ECC/EDC */ private static byte[] eccFLut_U = new byte[256]; private static byte[] eccBLut_U = new byte[256]; private static int[] edcLut_U = new int[256]; /** * Init routine */ private static void eccedcInit() { int j_U, edc_U; for(int i_U = 0; Integer.compareUnsigned(i_U, 256) < 0; i_U++) { j_U = i_U << 1 ^ ((i_U & 0x80) != 0 ? 0x11D : 0); eccFLut_U[i_U] = (byte)j_U; eccBLut_U[i_U ^ j_U] = (byte)i_U; edc_U = i_U; for(j_U = 0; Integer.compareUnsigned(j_U, 8) < 0; j_U++) { edc_U = edc_U >>> 1 ^ ((edc_U & 1) != 0 ? 0xD8018001 : 0); } edcLut_U[i_U] = edc_U; } } /** * Compute EDC for a block */ public static int edcPartialComputeblock_U(int edc_U, String8 src_U, short size_U) { while(size_U-- != 0) { edc_U = edc_U >>> 8 ^ edcLut_U[(edc_U ^ Byte.toUnsignedInt((src_U = nnc(src_U).shift(1)).get(-1))) & 0xFF]; } return edc_U; } public static void edcComputeblock(String8 src_U, short size_U, String8 dest_U) { int edc_U = edcPartialComputeblock_U(0, src_U, size_U); dest_U.set(0, (byte)(edc_U >>> 0 & 0xFF)); dest_U.set(1, (byte)(edc_U >>> 8 & 0xFF)); dest_U.set(2, (byte)(edc_U >>> 16 & 0xFF)); dest_U.set(3, (byte)(edc_U >>> 24 & 0xFF)); } /** * Compute ECC for a block (can do either P or Q) */ private static void eccComputeblock(String8 src_U, int majorCount_U, int minorCount_U, int majorMult_U, int minorInc_U, String8 dest_U) { int size_U = majorCount_U * minorCount_U; for(int major_U = 0; Integer.compareUnsigned(major_U, majorCount_U) < 0; major_U++) { int index_U = (major_U >>> 1) * majorMult_U + (major_U & 1); byte eccA_U = 0; byte eccB_U = 0; for(int minor_U = 0; Integer.compareUnsigned(minor_U, minorCount_U) < 0; minor_U++) { byte temp_U = src_U.get(index_U); index_U += minorInc_U; if(Integer.compareUnsigned(index_U, size_U) >= 0) { index_U -= size_U; } eccA_U = (byte)(Byte.toUnsignedInt(eccA_U) ^ Byte.toUnsignedInt(temp_U)); eccB_U = (byte)(Byte.toUnsignedInt(eccB_U) ^ Byte.toUnsignedInt(temp_U)); eccA_U = eccFLut_U[Byte.toUnsignedInt(eccA_U)]; } eccA_U = eccBLut_U[Byte.toUnsignedInt(eccFLut_U[Byte.toUnsignedInt(eccA_U)]) ^ Byte.toUnsignedInt(eccB_U)]; dest_U.set(major_U, eccA_U); dest_U.set(major_U + majorCount_U, (byte)(Byte.toUnsignedInt(eccA_U) ^ Byte.toUnsignedInt(eccB_U))); } } /** * Generate ECC P and Q codes for a block */ private static void eccGenerate(String8 sector_U, int zeroaddress) { byte[] address_U = new byte[4]; /* Save the address and zero it out */ if(zeroaddress != 0) { for(byte i_U = 0; Byte.toUnsignedInt(i_U) < 4; i_U++) { address_U[Byte.toUnsignedInt(i_U)] = sector_U.get(12 + Byte.toUnsignedInt(i_U)); sector_U.set(12 + Byte.toUnsignedInt(i_U), (byte)0); } } /* Compute ECC P code */ eccComputeblock(nnc(sector_U).shift(0xC), 86, 24, 2, 86, nnc(sector_U).shift(0x81C)); /* Compute ECC Q code */ eccComputeblock(nnc(sector_U).shift(0xC), 52, 43, 86, 88, nnc(sector_U).shift(0x8C8)); /* Restore the address */ if(zeroaddress != 0) { for(byte i_U = 0; Byte.toUnsignedInt(i_U) < 4; i_U++) { sector_U.set(12 + Byte.toUnsignedInt(i_U), address_U[Byte.toUnsignedInt(i_U)]); } } } /** * Generate ECC/EDC information for a sector (must be 2352 = 0x930 bytes) * Returns 0 on success */ public static void eccedcGenerate(String8 sector_U, int type) { switch(type) { case 1: /* Mode 1 */ /* Compute EDC */ edcComputeblock(nnc(sector_U).shift(0x00), (short)0x810, nnc(sector_U).shift(0x810)); /* Write out zero bytes */ for(int i_U = 0; Integer.compareUnsigned(i_U, 8) < 0; i_U++) { sector_U.set(0x814 + i_U, (byte)0); } /* Generate ECC P/Q codes */ eccGenerate(sector_U, 0); break; case 2: /* Mode 2 form 1 */ /* Compute EDC */ edcComputeblock(nnc(sector_U).shift(0x10), (short)0x808, nnc(sector_U).shift(0x818)); /* Generate ECC P/Q codes */ eccGenerate(sector_U, 1); break; case 3: /* Mode 2 form 2 */ /* Compute EDC */ edcComputeblock(nnc(sector_U).shift(0x10), (short)0x91C, nnc(sector_U).shift(0x92C)); break; } } public static int mycounter_U; public static int mycounterTotal_U; public static void resetcounter(int total_U) { mycounter_U = 0; mycounterTotal_U = total_U; } public static void setcounter(int n_U) { if(n_U >>> 20 != mycounter_U >>> 20) { int a_U = Integer.divideUnsigned(n_U + 64, 128); int d_U = Integer.divideUnsigned(mycounterTotal_U + 64, 128); if(d_U == 0) { d_U = 1; } System.err.printf("Decoding (%02d%%)\r", Integer.divideUnsigned(100 * a_U, d_U)); } mycounter_U = n_U; } public static int unecmify(RandomAccessFile in, RandomAccessFile out) throws IOException { final int posUneof = 1, posCorrupt = 2; positionLoop: for(int pos = 0; true;) switch(pos) { default: int checkedc_U = 0; String8 sector_U = new String8(2_352); int type_U; int num_U; in.seek(in.length()); resetcounter((int)in.getFilePointer()); in.seek(0); if(in.read() != 'E' || in.read() != 'C' || in.read() != 'M' || in.read() != 0x00) { System.err.println("Header not found!"); pos = posCorrupt; continue positionLoop; } for(;;) { int c = in.read(); int bits = 5; if(c == -1) { pos = posUneof; continue positionLoop; } type_U = c & 3; num_U = c >> 2 & 0x1F; while((c & 0x80) != 0) { c = in.read(); if(c == -1) { pos = posUneof; continue positionLoop; } num_U |= (c & 0x7F) << bits; bits += 7; } if(num_U == 0xFFFFFFFF) { break; } num_U++; if(Integer.compareUnsigned(num_U, 0x80000000) >= 0) { pos = posCorrupt; continue positionLoop; } if(type_U == 0) { while(num_U != 0) { int b = num_U; if(b > 2_352) { b = 2_352; } byte[] tmpBuf = new byte[b]; int readCount = Math.max(in.read(tmpBuf), 0); sector_U.copyFrom(tmpBuf, readCount); if(readCount != b) { pos = posUneof; continue positionLoop; } checkedc_U = edcPartialComputeblock_U(checkedc_U, sector_U, (short)b); byte[] tmpBuf2 = new byte[b]; sector_U.copyTo(tmpBuf2); out.write(tmpBuf2); num_U -= b; setcounter((int)in.getFilePointer()); } } else { while(num_U-- != 0) { sector_U.fill(0, sector_U.size(), (byte)0); sector_U.shift(1).fill(0, 10, (byte)0xFF); switch(type_U) { case 1: sector_U.set(0x0F, (byte)0x01); byte[] tmpBuf = new byte[0x003]; int readCount = Math.max(in.read(tmpBuf), 0); nnc(sector_U.shift(0x00C)).copyFrom(tmpBuf, readCount); if(readCount != 0x003) { pos = posUneof; continue positionLoop; } byte[] tmpBuf2 = new byte[0x800]; int readCount2 = Math.max(in.read(tmpBuf2), 0); nnc(sector_U.shift(0x010)).copyFrom(tmpBuf2, readCount2); if(readCount2 != 0x800) { pos = posUneof; continue positionLoop; } eccedcGenerate(sector_U, 1); checkedc_U = edcPartialComputeblock_U(checkedc_U, sector_U, (short)2_352); byte[] tmpBuf3 = new byte[2_352]; sector_U.copyTo(tmpBuf3); out.write(tmpBuf3); setcounter((int)in.getFilePointer()); break; case 2: sector_U.set(0x0F, (byte)0x02); byte[] tmpBuf4 = new byte[0x804]; int readCount3 = Math.max(in.read(tmpBuf4), 0); nnc(sector_U.shift(0x014)).copyFrom(tmpBuf4, readCount3); if(readCount3 != 0x804) { pos = posUneof; continue positionLoop; } sector_U.set(0x10, sector_U.get(0x14)); sector_U.set(0x11, sector_U.get(0x15)); sector_U.set(0x12, sector_U.get(0x16)); sector_U.set(0x13, sector_U.get(0x17)); eccedcGenerate(sector_U, 2); checkedc_U = edcPartialComputeblock_U(checkedc_U, sector_U.shift(0x10), (short)2_336); byte[] tmpBuf5 = new byte[2_336]; sector_U.shift(0x10).copyTo(tmpBuf5); out.write(tmpBuf5); setcounter((int)in.getFilePointer()); break; case 3: sector_U.set(0x0F, (byte)0x02); byte[] tmpBuf6 = new byte[0x918]; int readCount4 = Math.max(in.read(tmpBuf6), 0); nnc(sector_U.shift(0x014)).copyFrom(tmpBuf6, readCount4); if(readCount4 != 0x918) { pos = posUneof; continue positionLoop; } sector_U.set(0x10, sector_U.get(0x14)); sector_U.set(0x11, sector_U.get(0x15)); sector_U.set(0x12, sector_U.get(0x16)); sector_U.set(0x13, sector_U.get(0x17)); eccedcGenerate(sector_U, 3); checkedc_U = edcPartialComputeblock_U(checkedc_U, sector_U.shift(0x10), (short)2_336); byte[] tmpBuf7 = new byte[2_336]; sector_U.shift(0x10).copyTo(tmpBuf7); out.write(tmpBuf7); setcounter((int)in.getFilePointer()); break; } } } } byte[] tmpBuf = new byte[4]; int readCount = Math.max(in.read(tmpBuf), 0); sector_U.copyFrom(tmpBuf, readCount); if(readCount != 4) { pos = posUneof; continue positionLoop; } System.err.println("Decoded " + in.getFilePointer() + " bytes -> " + out.getFilePointer() + " bytes"); if(Byte.toUnsignedInt(sector_U.get(0)) != (checkedc_U >>> 0 & 0xFF) || Byte.toUnsignedInt(sector_U.get(1)) != (checkedc_U >>> 8 & 0xFF) || Byte.toUnsignedInt(sector_U.get(2)) != (checkedc_U >>> 16 & 0xFF) || Byte.toUnsignedInt(sector_U.get(3)) != (checkedc_U >>> 24 & 0xFF)) { System.err.printf("EDC error (%08X, should be %02X%02X%02X%02X)\n", checkedc_U, Byte.toUnsignedInt(sector_U.get(3)), Byte.toUnsignedInt(sector_U.get(2)), Byte.toUnsignedInt(sector_U.get(1)), Byte.toUnsignedInt(sector_U.get(0))); pos = posCorrupt; continue positionLoop; } System.err.println("Done; file is OK"); return 0; case posUneof: System.err.println("Unexpected EOF!"); case posCorrupt: System.err.println("Corrupt ECM file!"); return 1; } } public static void main(String[] args) throws IOException { RandomAccessFile fin, fout; String8 infilename; String8 outfilename; banner(); /* ** Initialize the ECC/EDC tables */ eccedcInit(); /* ** Check command line */ if(args.length != 1 && args.length != 2) { System.err.println("usage: " + Unecm.class.getSimpleName() + " ecmfile [outputfile]"); System.exit(1); } /* ** Verify that the input filename is valid */ infilename = cs8(args[0]); if(Integer.compareUnsigned(infilename.length(), 5) < 0) { System.err.println("filename '" + infilename + "' is too short"); System.exit(1); } if(!nnc(infilename).shift(infilename.length() - 4).equalsIgnoreCase(".ecm")) { System.err.println("filename must end in .ecm"); System.exit(1); } /* ** Figure out what the output filename should be */ if(args.length == 2) { outfilename = cs8(args[1]); } else { outfilename = new String8(true, infilename.length() - 3); nnc(outfilename).copyFrom(infilename, infilename.length() - 4); outfilename.set(infilename.length() - 4, (byte)0); } System.err.println("Decoding " + infilename + " to " + outfilename + "."); /* ** Open both files */ try { fin = new RandomAccessFile(infilename.toString(), "r"); } catch(IOException ex) { fin = null; ex.printStackTrace(); System.exit(1); } try { fout = new RandomAccessFile(outfilename.toString(), "rw"); fout.setLength(0); } catch(IOException ex) { fout = null; ex.printStackTrace(); fin.close(); System.exit(1); } /* ** Decode */ unecmify(fin, fout); /* ** Close everything */ fout.close(); fin.close(); } } 

我使用C ++到Java转换器来转换上面的代码。 它不会100%正确,但至少它提供了关于需要做什么的票价。

 public class GlobalMembersTest { /* ** UNECM - Decoder for ECM (Error Code Modeler) format. ** Version 1.0 ** Copyright (C) 2002 Neill Corlett ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License ** as published by the Free Software Foundation; either version 2 ** of the License, or (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /***************************************************************************/ /* ** Portability notes: ** ** - Assumes a 32-bit or higher integer size ** - No assumptions about byte order ** - No assumptions about struct packing ** - No unaligned memory access */ /***************************************************************************/ /***************************************************************************/ public static void banner() { fprintf(stderr, "UNECM - Decoder for Error Code Modeler format v1.0\n" + "Copyright (C) 2002 Neill Corlett\n\n"); } /***************************************************************************/ /* Data types */ //C++ TO JAVA CONVERTER NOTE: The following #define macro was replaced in-line: ///#define ecc_uint8 unsigned char //C++ TO JAVA CONVERTER NOTE: The following #define macro was replaced in-line: ///#define ecc_uint16 unsigned short //C++ TO JAVA CONVERTER NOTE: The following #define macro was replaced in-line: ///#define ecc_uint32 unsigned /* LUTs used for computing ECC/EDC */ public static byte[] ecc_f_lut = new byte[256]; public static byte[] ecc_b_lut = new byte[256]; public static int[] edc_lut = new int[256]; /* Init routine */ public static void eccedc_init() { int i; int j; int edc; for (i = 0; i < 256; i++) { j = (i << 1) (i & 0x80 ? 0x11D : 0); ecc_f_lut[i] = j; ecc_b_lut[i ^ j] = i; edc = i; for (j = 0; j < 8; j++) edc = (edc >> 1) ^ (edc & 1 ? 0xD8018001 : 0); edc_lut[i] = edc; } } /***************************************************************************/ /* ** Compute EDC for a block */ public static int edc_partial_computeblock(int edc, String src, short size) { while (size--) edc = (edc >> 8) ^ edc_lut[(edc ^ (src++)) & 0xFF]; return edc; } public static void edc_computeblock(String src, short size, byte[] dest) { int edc = GlobalMembersTest.edc_partial_computeblock(0, src, size); dest[0] = (edc >> 0) & 0xFF; dest[1] = (edc >> 8) & 0xFF; dest[2] = (edc >> 16) & 0xFF; dest[3] = (edc >> 24) & 0xFF; } /***************************************************************************/ /* ** Compute ECC for a block (can do either P or Q) */ public static void ecc_computeblock(byte[] src, int major_count, int minor_count, int major_mult, int minor_inc, byte[] dest) { int size = major_count * minor_count; int major; int minor; for (major = 0; major < major_count; major++) { int index = (major >> 1) * major_mult + (major & 1); byte ecc_a = 0; byte ecc_b = 0; for (minor = 0; minor < minor_count; minor++) { byte temp = src[index]; index += minor_inc; if (index >= size) index -= size; ecc_a ^= temp; ecc_b ^= temp; ecc_a = ecc_f_lut[ecc_a]; } ecc_a = ecc_b_lut[ecc_f_lut[ecc_a] ^ ecc_b]; dest[major] = ecc_a; dest[major + major_count] = ecc_a ^ ecc_b; } } /* ** Generate ECC P and Q codes for a block */ public static void ecc_generate(byte[] sector, int zeroaddress) { byte[] address = new byte[4]; byte i; /* Save the address and zero it out */ if (zeroaddress != 0) for (i = 0; i < 4; i++) { address[i] = sector[12 + i]; sector[12 + i] = 0; } /* Compute ECC P code */ GlobalMembersTest.ecc_computeblock(sector + 0xC, 86, 24, 2, 86, sector + 0x81C); /* Compute ECC Q code */ GlobalMembersTest.ecc_computeblock(sector + 0xC, 52, 43, 86, 88, sector + 0x8C8); /* Restore the address */ if (zeroaddress != 0) for (i = 0; i < 4; i++) sector[12 + i] = address[i]; } /***************************************************************************/ /* ** Generate ECC/EDC information for a sector (must be 2352 = 0x930 bytes) ** Returns 0 on success */ public static void eccedc_generate(byte[] sector, int type) { int i; switch (type) { case 1: // Mode 1 /* Compute EDC */ GlobalMembersTest.edc_computeblock(sector + 0x00, 0x810, sector + 0x810); /* Write out zero bytes */ for (i = 0; i < 8; i++) sector[0x814 + i] = 0; /* Generate ECC P/Q codes */ GlobalMembersTest.ecc_generate(sector, 0); break; case 2: // Mode 2 form 1 /* Compute EDC */ GlobalMembersTest.edc_computeblock(sector + 0x10, 0x808, sector + 0x818); /* Generate ECC P/Q codes */ GlobalMembersTest.ecc_generate(sector, 1); break; case 3: // Mode 2 form 2 /* Compute EDC */ GlobalMembersTest.edc_computeblock(sector + 0x10, 0x91C, sector + 0x92C); break; } } /***************************************************************************/ public static int mycounter; public static int mycounter_total; public static void resetcounter(int total) { mycounter = 0; mycounter_total = total; } public static void setcounter(int n) { if ((n >> 20) != (mycounter >> 20)) { int a = (n + 64) / 128; int d = (mycounter_total + 64) / 128; if (d == 0) d = 1; fprintf(stderr, "Decoding (%02d%%)\r", (100 * a) / d); } mycounter = n; } public static int unecmify(FILE in, FILE out) { int checkedc = 0; byte[] sector = new byte[2352]; int type; int num; fseek(in, 0, SEEK_END); GlobalMembersTest.resetcounter(ftell(in)); fseek(in, 0, SEEK_SET); if ((fgetc(in) != 'E') || (fgetc(in) != 'C') || (fgetc(in) != 'M') || (fgetc(in) != 0x00)) { fprintf(stderr, "Header not found!\n"); //C++ TO JAVA CONVERTER TODO TASK: There are no gotos or labels in Java: goto corrupt; } for (;;) { int c = fgetc(in); int bits = 5; if (c == EOF) //C++ TO JAVA CONVERTER TODO TASK: There are no gotos or labels in Java: goto uneof; type = c & 3; num = (c >> 2) & 0x1F; while (c & 0x80 != 0) { c = fgetc(in); if (c == EOF) //C++ TO JAVA CONVERTER TODO TASK: There are no gotos or labels in Java: goto uneof; num |= ((int)(c & 0x7F)) << bits; bits += 7; } if (num == 0xFFFFFFFF) break; num++; if (num >= 0x80000000) //C++ TO JAVA CONVERTER TODO TASK: There are no gotos or labels in Java: goto corrupt; if (type == 0) { while (num != 0) { int b = num; if (b > 2352) b = 2352; if (fread(sector, 1, b, in) != b) //C++ TO JAVA CONVERTER TODO TASK: There are no gotos or labels in Java: goto uneof; checkedc = GlobalMembersTest.edc_partial_computeblock(checkedc, sector, b); fwrite(sector, 1, b, out); num -= b; GlobalMembersTest.setcounter(ftell(in)); } } else { while (num--) { //C++ TO JAVA CONVERTER TODO TASK: The memory management function 'memset' has no equivalent in Java: //C++ TO JAVA CONVERTER TODO TASK: There is no Java equivalent to 'sizeof': memset(sector, 0, sizeof(sector)); //C++ TO JAVA CONVERTER TODO TASK: The memory management function 'memset' has no equivalent in Java: memset(sector + 1, 0xFF, 10); switch (type) { case 1: sector[0x0F] = 0x01; if (fread(sector + 0x00C, 1, 0x003, in) != 0x003) //C++ TO JAVA CONVERTER TODO TASK: There are no gotos or labels in Java: goto uneof; if (fread(sector + 0x010, 1, 0x800, in) != 0x800) //C++ TO JAVA CONVERTER TODO TASK: There are no gotos or labels in Java: goto uneof; GlobalMembersTest.eccedc_generate(sector, 1); checkedc = GlobalMembersTest.edc_partial_computeblock(checkedc, sector, 2352); fwrite(sector, 2352, 1, out); GlobalMembersTest.setcounter(ftell(in)); break; case 2: sector[0x0F] = 0x02; if (fread(sector + 0x014, 1, 0x804, in) != 0x804) //C++ TO JAVA CONVERTER TODO TASK: There are no gotos or labels in Java: goto uneof; sector[0x10] = sector[0x14]; sector[0x11] = sector[0x15]; sector[0x12] = sector[0x16]; sector[0x13] = sector[0x17]; GlobalMembersTest.eccedc_generate(sector, 2); checkedc = GlobalMembersTest.edc_partial_computeblock(checkedc, sector + 0x10, 2336); fwrite(sector + 0x10, 2336, 1, out); GlobalMembersTest.setcounter(ftell(in)); break; case 3: sector[0x0F] = 0x02; if (fread(sector + 0x014, 1, 0x918, in) != 0x918) //C++ TO JAVA CONVERTER TODO TASK: There are no gotos or labels in Java: goto uneof; sector[0x10] = sector[0x14]; sector[0x11] = sector[0x15]; sector[0x12] = sector[0x16]; sector[0x13] = sector[0x17]; GlobalMembersTest.eccedc_generate(sector, 3); checkedc = GlobalMembersTest.edc_partial_computeblock(checkedc, sector + 0x10, 2336); fwrite(sector + 0x10, 2336, 1, out); GlobalMembersTest.setcounter(ftell(in)); break; } } } } if (fread(sector, 1, 4, in) != 4) //C++ TO JAVA CONVERTER TODO TASK: There are no gotos or labels in Java: goto uneof; fprintf(stderr, "Decoded %ld bytes -> %ld bytes\n", ftell(in), ftell(out)); if ((sector[0] != ((checkedc >> 0) & 0xFF)) || (sector[1] != ((checkedc >> 8) & 0xFF)) || (sector[2] != ((checkedc >> 16) & 0xFF)) || (sector[3] != ((checkedc >> 24) & 0xFF))) { fprintf(stderr, "EDC error (%08X, should be %02X%02X%02X%02X)\n", checkedc, sector[3], sector[2], sector[1], sector[0]); //C++ TO JAVA CONVERTER TODO TASK: There are no gotos or labels in Java: goto corrupt; } fprintf(stderr, "Done; file is OK\n"); return 0; //C++ TO JAVA CONVERTER TODO TASK: There are no gotos or labels in Java: uneof: fprintf(stderr, "Unexpected EOF!\n"); //C++ TO JAVA CONVERTER TODO TASK: There are no gotos or labels in Java: corrupt: fprintf(stderr, "Corrupt ECM file!\n"); return 1; } /***************************************************************************/ public static int Main(int argc, String[] args) { FILE fin; FILE fout; String infilename; String outfilename; GlobalMembersTest.banner(); /* ** Initialize the ECC/EDC tables */ GlobalMembersTest.eccedc_init(); /* ** Check command line */ if ((argc != 2) && (argc != 3)) { fprintf(stderr, "usage: %s ecmfile [outputfile]\n", args[0]); return 1; } /* ** Verify that the input filename is valid */ infilename = args[1]; if (infilename.length() < 5) { fprintf(stderr, "filename '%s' is too short\n", infilename); return 1; } if (strcasecmp(infilename + infilename.length() - 4, ".ecm")) { fprintf(stderr, "filename must end in .ecm\n"); return 1; } /* ** Figure out what the output filename should be */ if (argc == 3) { outfilename = args[2]; } else { //C++ TO JAVA CONVERTER TODO TASK: The memory management function 'malloc' has no equivalent in Java: outfilename = malloc(infilename.length() - 3); if (outfilename == null) abort(); //C++ TO JAVA CONVERTER TODO TASK: The memory management function 'memcpy' has no equivalent in Java: memcpy(outfilename, infilename, infilename.length() - 4); outfilename = outfilename.substring(0, infilename.length() - 4); } fprintf(stderr, "Decoding %s to %s.\n", infilename, outfilename); /* ** Open both files */ fin = fopen(infilename, "rb"); if (fin == null) { perror(infilename); return 1; } fout = fopen(outfilename, "wb"); if (fout == null) { perror(outfilename); fclose(fin); return 1; } /* ** Decode */ GlobalMembersTest.unecmify(fin, fout); /* ** Close everything */ fclose(fout); fclose(fin); } } 

问题是问“任何工具?”,所以这里有一个工具。
请不要因为你不喜欢工具而进行投票。

我尝试了一种名为“ Novosoft C2J ”的C-to-Java转换工具。 判决:

  • 非常马车
  • 经常崩溃
  • 专有(即使它声称“C2J的Beta版本在GNU许可下”,源代码无处可寻)

我设法转换一个几乎没有依赖的C文件,但不得不通过将头文件的内容复制粘贴到头文件来“预处理”它,因为C2J不会让我选择.h文件包含在项目中。

翻译的代码是静态的,带有奇怪的“nextlevel()”和“prevlevel()”调用。
一些翻译的代码需要手动工作,例如: UndefFcs.cisnan([...])

结论:Buggy工具,但可能就是没有更好的工具。

我意识到我从未发布过我的解决方案

在Android活动中:

 Public class UnECMActivity extends Activity { ... static { System.loadLibrary("unecm"); } private native int rununecm(String fileName); 

在unecm.c中添加:

 jint Java_com_romcessed_unecm_UnECMActivity_rununecm(JNIEnv* env, jobject javaThis, jstring fileName) { FILE *fin, *fout; jboolean *iscopy; char *infilename = (*env)->GetStringUTFChars(env, fileName, iscopy); char *outfilename; banner(); eccedc_init(); /* ** Verify that the input filename is valid */ if(strlen(infilename) < 5) { fprintf(stderr, "filename '%s' is too short\n", infilename); return 1; } if(strcasecmp(infilename + strlen(infilename) - 4, ".ecm")) { fprintf(stderr, "filename must end in .ecm\n"); return 1; } /* ** Figure out what the output filename should be */ outfilename = malloc(strlen(infilename) - 3); if(!outfilename) abort(); memcpy(outfilename, infilename, strlen(infilename) - 4); outfilename[strlen(infilename) - 4] = 0; fprintf(stderr, "Decoding %s to %s.\n", infilename, outfilename); /* ** Open both files */ fin = fopen(infilename, "rb"); if(!fin) { perror(infilename); return 1; } fout = fopen(outfilename, "wb"); if(!fout) { perror(outfilename); fclose(fin); return 1; } /* ** Decode */ unecmify(fin, fout); /* ** Close everything */ fclose(fout); fclose(fin); return 0; }