rubyecm2cue 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|