web-dev-qa-db-ja.com

.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 <stdio.h>
#include <stdlib.h>
#include <string.h>

/***************************************************************************/

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 < 8; j++) edc = (edc >> 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 < major_count; major++) {
    ecc_uint32 index = (major >> 1) * major_mult + (major & 1);
    ecc_uint8 ecc_a = 0;
    ecc_uint8 ecc_b = 0;
    for(minor = 0; minor < minor_count; minor++) {
      ecc_uint8 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
*/
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 < 8; i++) sector[0x814 + i] = 0;
    /* Generate ECC P/Q codes */
    ecc_generate(sector, 0);
    break;
  case 2: /* Mode 2 form 1 */
    /* Compute EDC */
    edc_computeblock(sector + 0x10, 0x808, sector + 0x818);
    /* Generate ECC P/Q codes */
    ecc_generate(sector, 1);
    break;
  case 3: /* Mode 2 form 2 */
    /* Compute EDC */
    edc_computeblock(sector + 0x10, 0x91C, sector + 0x92C);
    break;
  }
}

/***************************************************************************/

unsigned mycounter;
unsigned mycounter_total;

void resetcounter(unsigned total) {
  mycounter = 0;
  mycounter_total = total;
}

void setcounter(unsigned n) {
  if((n >> 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)) << bits;
      bits += 7;
    }
    if(num == 0xFFFFFFFF) break;
    num++;
    if(num >= 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;
}
11
Aymon Fournier

CからJavaへの変換を行うのではなく、 [〜#〜] jni [〜#〜] の使用を検討しましたか?

5
Catchwa

あなたの最善の策は、コードを書き直すことです。

自動化された変換は、せいぜい、品質が低く、保守不可能なコードになります。

14
James McNellis

世界のCビューは、Java世界のビューとうまく混同しません。Javaで実行可能なフォームにコンパイルする場合は、NestedVM- http://nestedvm.ibex.org/ -MIPS方言にコンパイルされるクロスコンパイラで、Java解釈または変換によって簡単に「実行」できます。元のMIPS命令を反映する実際のバイトコードに。

コードのJavaバージョンを取得することをお勧めします。

以前は、Ephedra、Convert2Java、C2J ++と呼ばれるツールがありました。しかし、実際には機能せず、利用できなくなりました。これにより、3つの企業が自動CをJava翻訳を使用不可、有用、優れた範囲で提供しています。

  1. Novosoft 、C2J:作成されたJavaコードは深刻な手作業が必要です。C2Jは(非常に限定されたポインターサポートを使用するために)多少読みにくいコードを作成し、符号なしの型をサポートしていません/ gotoステートメント/ネイティブライブラリ/マクロ/コメント/ ...
  2. Tangible Software Solutions 、C++ 2Java:作成されたJavaコードは、かなりの手作業が必要です。C++ 2Javaは、ポインター/符号なしタイプ/ gotoステートメントをサポートしていません/ native libraries/macros/...(Sachin Bhansaliが上記のunecm Cコードの翻訳を投稿しました)
  3. mtSystems 、Coot:機能的に同等のコード(ポインター、関数ポインター、符号なし型、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();
    }
}
9
user3669782

私は C++ to Java converter を使用して上記のコードを変換しました。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);
    }
}
4
Sachin Bhansali

質問は「どんなツールですか?」と尋ねているので、ここにツールがあります。
ツールが好きではないという理由だけで投票しないでください。

Novosoft C2J 」というCからJavaへの変換ツールを試しました。評決:

  • とてもバギー
  • 頻繁にクラッシュする
  • 所有権がある(「C2Jのベータ版はGNUライセンスの下にありますが、ソースコードがどこにも見つからない)と記載されていても)

依存関係の少ないCファイルをなんとか変換できましたが、C2Jではプロジェクトに含める.hファイルを選択できないため、ヘッダーファイルの内容をヘッダーにコピーアンドペーストして「前処理」する必要がありました。

変換されたコードは静的で、奇妙な「nextlevel()」と「prevlevel()」の呼び出しがあります。
一部の翻訳されたコードは手動での作業が必要です。例:UndefFcs.cisnan([...])

結論:バギーツールですが、これより優れたツールがない場合もあります。

1
Nicolas Raoul

私は自分の解決策を投稿したことがないことに気付きました

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;
}
0
Aymon Fournier