Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert .c to .java [closed]

Any tools to convert C code into Java code? I am interested in converting this code into 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;
}
like image 874
Aymon Fournier Avatar asked Aug 13 '10 03:08

Aymon Fournier


3 Answers

Your best bet is to rewrite the code.

Any automated conversion would, at best, yield poor-quality and unmaintainable code.

like image 113
James McNellis Avatar answered Oct 15 '22 09:10

James McNellis


The C view of the world does not mix well with the Java view of the world. If you really want to compile to a form executable by Java, have a look at NestedVM - http://nestedvm.ibex.org/ - which is a cross compiler compiling to a MIPS-dialect which can then easily be "run" in Java either through interpretation or by conversion to actual bytecode reflecting the original MIPS-instructions.

I would recommend getting a Java version of the code.

like image 24
Thorbjørn Ravn Andersen Avatar answered Oct 15 '22 09:10

Thorbjørn Ravn Andersen


There used to be tools called Ephedra, Convert2Java and C2J++. But they didn't really work and are no longer available. This leaves three companies offering automatic C to Java translation in the range of unusable, helpful and good:

  1. Novosoft, C2J: The created Java code needs serious manual work. C2J creates somewhat unreadable code (to have very limited pointer support) and has no support for unsigned types/goto statements/native libraries/macros/comments/...
  2. Tangible Software Solutions, C++2Java: The created Java code needs quite some manual work. C++2Java has no support for pointers/unsigned types/goto statements/native libraries/macros/... (Sachin Bhansali posted the translation of the unecm C code above)
  3. mtSystems, Coot: Creates functionally equivalent code (by having full support for pointers, function pointers, unsigned types, goto statements, native libraries, ...) and readable code (keeps macros/comments, renames identifiers, applies various optimizations, ...).

Here the created class from mtSystems (unaltered):

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();
    }
}
like image 23
user3669782 Avatar answered Oct 15 '22 08:10

user3669782