rubyecm2cue 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ext/rubyecm2cue/extconf.rb +5 -0
- data/ext/rubyecm2cue/rubyecm2cue.c +19 -0
- data/ext/rubyecm2cue/unecm.c +237 -0
- data/ext/rubyecm2cue/unecm.h +11 -0
- metadata +47 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 20666a54dc4d62c54b05d28ec543c49159b9bd0c
|
4
|
+
data.tar.gz: 3b35d5a0ec35f031569406ca11f5d991d58c2db2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 31c76014875eb91b9ea750c8ef48124505323b168ae50fc859f0c0c59d09f0367d085257cf3dd65363491d500707a12b17e66022a284fc8dccfefc9855aa2141
|
7
|
+
data.tar.gz: ac20e8365812dfa88c125a810f3b9669fdf74bc187a97ca61da7c999c25d42eef12068fb9475653f1b39d50178a13de3fa84dbc315094959e0c1bd6e99faf7de
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
#include <stdio.h>
|
3
|
+
#include "unecm.h"
|
4
|
+
|
5
|
+
VALUE RubyEcm2Cue = Qnil;
|
6
|
+
void Init_rubyecm2cue();
|
7
|
+
VALUE method_process(VALUE, VALUE);
|
8
|
+
|
9
|
+
void Init_rubyecm2cue(){
|
10
|
+
VALUE RubyEcm2Cue = rb_define_module("RubyEcm2Cue");
|
11
|
+
rb_define_method(RubyEcm2Cue, "process", method_process, 1);
|
12
|
+
}
|
13
|
+
|
14
|
+
VALUE method_process(VALUE self, VALUE arg_path) {
|
15
|
+
const char *img= StringValueCStr(arg_path);
|
16
|
+
const char *retValue;
|
17
|
+
|
18
|
+
return rb_str_new_cstr(retValue);
|
19
|
+
}
|
@@ -0,0 +1,237 @@
|
|
1
|
+
#include "unecm.h"
|
2
|
+
|
3
|
+
#define ecc_uint8 unsigned char
|
4
|
+
#define ecc_uint16 unsigned short
|
5
|
+
#define ecc_uint32 unsigned
|
6
|
+
|
7
|
+
static ecc_uint8 ecc_f_lut[256];
|
8
|
+
static ecc_uint8 ecc_b_lut[256];
|
9
|
+
static ecc_uint32 edc_lut[256];
|
10
|
+
|
11
|
+
void eccedc_init(void) {
|
12
|
+
ecc_uint32 i, j, edc;
|
13
|
+
for(i = 0; i < 256; i++) {
|
14
|
+
j = (i << 1) ^ (i & 0x80 ? 0x11D : 0);
|
15
|
+
ecc_f_lut[i] = j;
|
16
|
+
ecc_b_lut[i ^ j] = i;
|
17
|
+
edc = i;
|
18
|
+
for(j = 0; j < 8; j++) edc = (edc >> 1) ^ (edc & 1 ? 0xD8018001 : 0);
|
19
|
+
edc_lut[i] = edc;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
ecc_uint32 edc_partial_computeblock(
|
24
|
+
ecc_uint32 edc,
|
25
|
+
const ecc_uint8 *src,
|
26
|
+
ecc_uint16 size
|
27
|
+
) {
|
28
|
+
while(size--) edc = (edc >> 8) ^ edc_lut[(edc ^ (*src++)) & 0xFF];
|
29
|
+
return edc;
|
30
|
+
}
|
31
|
+
|
32
|
+
void edc_computeblock(
|
33
|
+
const ecc_uint8 *src,
|
34
|
+
ecc_uint16 size,
|
35
|
+
ecc_uint8 *dest
|
36
|
+
) {
|
37
|
+
ecc_uint32 edc = edc_partial_computeblock(0, src, size);
|
38
|
+
dest[0] = (edc >> 0) & 0xFF;
|
39
|
+
dest[1] = (edc >> 8) & 0xFF;
|
40
|
+
dest[2] = (edc >> 16) & 0xFF;
|
41
|
+
dest[3] = (edc >> 24) & 0xFF;
|
42
|
+
}
|
43
|
+
|
44
|
+
static void ecc_computeblock(
|
45
|
+
ecc_uint8 *src,
|
46
|
+
ecc_uint32 major_count,
|
47
|
+
ecc_uint32 minor_count,
|
48
|
+
ecc_uint32 major_mult,
|
49
|
+
ecc_uint32 minor_inc,
|
50
|
+
ecc_uint8 *dest
|
51
|
+
) {
|
52
|
+
ecc_uint32 size = major_count * minor_count;
|
53
|
+
ecc_uint32 major, minor;
|
54
|
+
for(major = 0; major < major_count; major++) {
|
55
|
+
ecc_uint32 index = (major >> 1) * major_mult + (major & 1);
|
56
|
+
ecc_uint8 ecc_a = 0;
|
57
|
+
ecc_uint8 ecc_b = 0;
|
58
|
+
for(minor = 0; minor < minor_count; minor++) {
|
59
|
+
ecc_uint8 temp = src[index];
|
60
|
+
index += minor_inc;
|
61
|
+
if(index >= size) index -= size;
|
62
|
+
ecc_a ^= temp;
|
63
|
+
ecc_b ^= temp;
|
64
|
+
ecc_a = ecc_f_lut[ecc_a];
|
65
|
+
}
|
66
|
+
ecc_a = ecc_b_lut[ecc_f_lut[ecc_a] ^ ecc_b];
|
67
|
+
dest[major ] = ecc_a;
|
68
|
+
dest[major + major_count] = ecc_a ^ ecc_b;
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
static void ecc_generate(
|
73
|
+
ecc_uint8 *sector,
|
74
|
+
int zeroaddress
|
75
|
+
) {
|
76
|
+
ecc_uint8 address[4], i;
|
77
|
+
|
78
|
+
if(zeroaddress) for(i = 0; i < 4; i++) {
|
79
|
+
address[i] = sector[12 + i];
|
80
|
+
sector[12 + i] = 0;
|
81
|
+
}
|
82
|
+
|
83
|
+
ecc_computeblock(sector + 0xC, 86, 24, 2, 86, sector + 0x81C);
|
84
|
+
|
85
|
+
ecc_computeblock(sector + 0xC, 52, 43, 86, 88, sector + 0x8C8);
|
86
|
+
|
87
|
+
if(zeroaddress) for(i = 0; i < 4; i++) sector[12 + i] = address[i];
|
88
|
+
}
|
89
|
+
|
90
|
+
void eccedc_generate(ecc_uint8 *sector, int type) {
|
91
|
+
ecc_uint32 i;
|
92
|
+
switch(type) {
|
93
|
+
case 1:
|
94
|
+
edc_computeblock(sector + 0x00, 0x810, sector + 0x810);
|
95
|
+
for(i = 0; i < 8; i++) sector[0x814 + i] = 0;
|
96
|
+
ecc_generate(sector, 0);
|
97
|
+
break;
|
98
|
+
case 2:
|
99
|
+
edc_computeblock(sector + 0x10, 0x808, sector + 0x818);
|
100
|
+
ecc_generate(sector, 1);
|
101
|
+
break;
|
102
|
+
case 3:
|
103
|
+
edc_computeblock(sector + 0x10, 0x91C, sector + 0x92C);
|
104
|
+
break;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
unsigned mycounter;
|
109
|
+
unsigned mycounter_total;
|
110
|
+
|
111
|
+
void resetcounter(unsigned total) {
|
112
|
+
mycounter = 0;
|
113
|
+
mycounter_total = total;
|
114
|
+
}
|
115
|
+
|
116
|
+
void setcounter(unsigned n) {
|
117
|
+
if((n >> 20) != (mycounter >> 20)) {
|
118
|
+
unsigned a = (n+64)/128;
|
119
|
+
unsigned d = (mycounter_total+64)/128;
|
120
|
+
if(!d) d = 1;
|
121
|
+
fprintf(stderr, "Decoding (%02d%%)\r", (100*a) / d);
|
122
|
+
}
|
123
|
+
mycounter = n;
|
124
|
+
}
|
125
|
+
|
126
|
+
int unecmify(
|
127
|
+
FILE *in,
|
128
|
+
FILE *out
|
129
|
+
) {
|
130
|
+
unsigned checkedc = 0;
|
131
|
+
unsigned char sector[2352];
|
132
|
+
unsigned type;
|
133
|
+
unsigned num;
|
134
|
+
fseek(in, 0, SEEK_END);
|
135
|
+
resetcounter(ftell(in));
|
136
|
+
fseek(in, 0, SEEK_SET);
|
137
|
+
if(
|
138
|
+
(fgetc(in) != 'E') ||
|
139
|
+
(fgetc(in) != 'C') ||
|
140
|
+
(fgetc(in) != 'M') ||
|
141
|
+
(fgetc(in) != 0x00)
|
142
|
+
) {
|
143
|
+
fprintf(stderr, "Header not found!\n");
|
144
|
+
goto corrupt;
|
145
|
+
}
|
146
|
+
for(;;) {
|
147
|
+
int c = fgetc(in);
|
148
|
+
int bits = 5;
|
149
|
+
if(c == EOF) goto uneof;
|
150
|
+
type = c & 3;
|
151
|
+
num = (c >> 2) & 0x1F;
|
152
|
+
while(c & 0x80) {
|
153
|
+
c = fgetc(in);
|
154
|
+
if(c == EOF) goto uneof;
|
155
|
+
num |= ((unsigned)(c & 0x7F)) << bits;
|
156
|
+
bits += 7;
|
157
|
+
}
|
158
|
+
if(num == 0xFFFFFFFF) break;
|
159
|
+
num++;
|
160
|
+
if(num >= 0x80000000) goto corrupt;
|
161
|
+
if(!type) {
|
162
|
+
while(num) {
|
163
|
+
int b = num;
|
164
|
+
if(b > 2352) b = 2352;
|
165
|
+
if(fread(sector, 1, b, in) != b) goto uneof;
|
166
|
+
checkedc = edc_partial_computeblock(checkedc, sector, b);
|
167
|
+
fwrite(sector, 1, b, out);
|
168
|
+
num -= b;
|
169
|
+
setcounter(ftell(in));
|
170
|
+
}
|
171
|
+
} else {
|
172
|
+
while(num--) {
|
173
|
+
memset(sector, 0, sizeof(sector));
|
174
|
+
memset(sector + 1, 0xFF, 10);
|
175
|
+
switch(type) {
|
176
|
+
case 1:
|
177
|
+
sector[0x0F] = 0x01;
|
178
|
+
if(fread(sector + 0x00C, 1, 0x003, in) != 0x003) goto uneof;
|
179
|
+
if(fread(sector + 0x010, 1, 0x800, in) != 0x800) goto uneof;
|
180
|
+
eccedc_generate(sector, 1);
|
181
|
+
checkedc = edc_partial_computeblock(checkedc, sector, 2352);
|
182
|
+
fwrite(sector, 2352, 1, out);
|
183
|
+
setcounter(ftell(in));
|
184
|
+
break;
|
185
|
+
case 2:
|
186
|
+
sector[0x0F] = 0x02;
|
187
|
+
if(fread(sector + 0x014, 1, 0x804, in) != 0x804) goto uneof;
|
188
|
+
sector[0x10] = sector[0x14];
|
189
|
+
sector[0x11] = sector[0x15];
|
190
|
+
sector[0x12] = sector[0x16];
|
191
|
+
sector[0x13] = sector[0x17];
|
192
|
+
eccedc_generate(sector, 2);
|
193
|
+
checkedc = edc_partial_computeblock(checkedc, sector + 0x10, 2336);
|
194
|
+
fwrite(sector + 0x10, 2336, 1, out);
|
195
|
+
setcounter(ftell(in));
|
196
|
+
break;
|
197
|
+
case 3:
|
198
|
+
sector[0x0F] = 0x02;
|
199
|
+
if(fread(sector + 0x014, 1, 0x918, in) != 0x918) goto uneof;
|
200
|
+
sector[0x10] = sector[0x14];
|
201
|
+
sector[0x11] = sector[0x15];
|
202
|
+
sector[0x12] = sector[0x16];
|
203
|
+
sector[0x13] = sector[0x17];
|
204
|
+
eccedc_generate(sector, 3);
|
205
|
+
checkedc = edc_partial_computeblock(checkedc, sector + 0x10, 2336);
|
206
|
+
fwrite(sector + 0x10, 2336, 1, out);
|
207
|
+
setcounter(ftell(in));
|
208
|
+
break;
|
209
|
+
}
|
210
|
+
}
|
211
|
+
}
|
212
|
+
}
|
213
|
+
if(fread(sector, 1, 4, in) != 4) goto uneof;
|
214
|
+
fprintf(stderr, "Decoded %ld bytes -> %ld bytes\n", ftell(in), ftell(out));
|
215
|
+
if(
|
216
|
+
(sector[0] != ((checkedc >> 0) & 0xFF)) ||
|
217
|
+
(sector[1] != ((checkedc >> 8) & 0xFF)) ||
|
218
|
+
(sector[2] != ((checkedc >> 16) & 0xFF)) ||
|
219
|
+
(sector[3] != ((checkedc >> 24) & 0xFF))
|
220
|
+
) {
|
221
|
+
fprintf(stderr, "EDC error (%08X, should be %02X%02X%02X%02X)\n",
|
222
|
+
checkedc,
|
223
|
+
sector[3],
|
224
|
+
sector[2],
|
225
|
+
sector[1],
|
226
|
+
sector[0]
|
227
|
+
);
|
228
|
+
goto corrupt;
|
229
|
+
}
|
230
|
+
fprintf(stderr, "Done; file is OK\n");
|
231
|
+
return 0;
|
232
|
+
uneof:
|
233
|
+
fprintf(stderr, "Unexpected EOF!\n");
|
234
|
+
corrupt:
|
235
|
+
fprintf(stderr, "Corrupt ECM file!\n");
|
236
|
+
return 1;
|
237
|
+
}
|
metadata
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubyecm2cue
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ferdinand E. Silva
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-09-04 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: ''
|
14
|
+
email: ferdinandsilva@ferdinandsilva.com
|
15
|
+
executables: []
|
16
|
+
extensions:
|
17
|
+
- ext/rubyecm2cue/extconf.rb
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- ext/rubyecm2cue/extconf.rb
|
21
|
+
- ext/rubyecm2cue/rubyecm2cue.c
|
22
|
+
- ext/rubyecm2cue/unecm.c
|
23
|
+
- ext/rubyecm2cue/unecm.h
|
24
|
+
homepage: http://ferdinandsilva.com
|
25
|
+
licenses: []
|
26
|
+
metadata: {}
|
27
|
+
post_install_message:
|
28
|
+
rdoc_options: []
|
29
|
+
require_paths:
|
30
|
+
- lib
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
requirements: []
|
42
|
+
rubyforge_project:
|
43
|
+
rubygems_version: 2.4.3
|
44
|
+
signing_key:
|
45
|
+
specification_version: 4
|
46
|
+
summary: ''
|
47
|
+
test_files: []
|