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 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: []