rubyecm2cue 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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,5 @@
1
+ require 'mkmf'
2
+
3
+ extension_name = 'rubyecm2cue'
4
+ dir_config extension_name
5
+ create_makefile extension_name
@@ -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
+ }
@@ -0,0 +1,11 @@
1
+ #ifndef UNECM_H
2
+ #define UNECM_H
3
+
4
+ #include <stdio.h>
5
+ #include <stdlib.h>
6
+ #include <string.h>
7
+
8
+ void eccedc_init(void);
9
+ int unecmify(FILE *in,FILE *out);
10
+
11
+ #endif
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: []