chd 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +30 -0
  3. data/chd.gemspec +29 -0
  4. data/ext/chd.c +1008 -0
  5. data/ext/extconf.rb +60 -0
  6. data/lib/chd/cd.rb +272 -0
  7. data/lib/chd/metadata.rb +196 -0
  8. data/lib/chd/version.rb +4 -0
  9. data/lib/chd.rb +21 -0
  10. data/libchdr/CMakeLists.txt +104 -0
  11. data/libchdr/LICENSE.txt +24 -0
  12. data/libchdr/README.md +7 -0
  13. data/libchdr/deps/lzma-19.00/CMakeLists.txt +33 -0
  14. data/libchdr/deps/lzma-19.00/LICENSE +3 -0
  15. data/libchdr/deps/lzma-19.00/include/7zTypes.h +375 -0
  16. data/libchdr/deps/lzma-19.00/include/Alloc.h +51 -0
  17. data/libchdr/deps/lzma-19.00/include/Bra.h +64 -0
  18. data/libchdr/deps/lzma-19.00/include/Compiler.h +33 -0
  19. data/libchdr/deps/lzma-19.00/include/CpuArch.h +336 -0
  20. data/libchdr/deps/lzma-19.00/include/Delta.h +19 -0
  21. data/libchdr/deps/lzma-19.00/include/LzFind.h +121 -0
  22. data/libchdr/deps/lzma-19.00/include/LzHash.h +57 -0
  23. data/libchdr/deps/lzma-19.00/include/Lzma86.h +111 -0
  24. data/libchdr/deps/lzma-19.00/include/LzmaDec.h +234 -0
  25. data/libchdr/deps/lzma-19.00/include/LzmaEnc.h +76 -0
  26. data/libchdr/deps/lzma-19.00/include/LzmaLib.h +131 -0
  27. data/libchdr/deps/lzma-19.00/include/Precomp.h +10 -0
  28. data/libchdr/deps/lzma-19.00/include/Sort.h +18 -0
  29. data/libchdr/deps/lzma-19.00/lzma-history.txt +446 -0
  30. data/libchdr/deps/lzma-19.00/lzma.txt +328 -0
  31. data/libchdr/deps/lzma-19.00/lzma.vcxproj +543 -0
  32. data/libchdr/deps/lzma-19.00/lzma.vcxproj.filters +17 -0
  33. data/libchdr/deps/lzma-19.00/src/Alloc.c +455 -0
  34. data/libchdr/deps/lzma-19.00/src/Bra86.c +82 -0
  35. data/libchdr/deps/lzma-19.00/src/BraIA64.c +53 -0
  36. data/libchdr/deps/lzma-19.00/src/CpuArch.c +218 -0
  37. data/libchdr/deps/lzma-19.00/src/Delta.c +64 -0
  38. data/libchdr/deps/lzma-19.00/src/LzFind.c +1127 -0
  39. data/libchdr/deps/lzma-19.00/src/Lzma86Dec.c +54 -0
  40. data/libchdr/deps/lzma-19.00/src/LzmaDec.c +1185 -0
  41. data/libchdr/deps/lzma-19.00/src/LzmaEnc.c +1330 -0
  42. data/libchdr/deps/lzma-19.00/src/Sort.c +141 -0
  43. data/libchdr/deps/zlib-1.2.11/CMakeLists.txt +29 -0
  44. data/libchdr/deps/zlib-1.2.11/ChangeLog +1515 -0
  45. data/libchdr/deps/zlib-1.2.11/FAQ +368 -0
  46. data/libchdr/deps/zlib-1.2.11/INDEX +68 -0
  47. data/libchdr/deps/zlib-1.2.11/Makefile +5 -0
  48. data/libchdr/deps/zlib-1.2.11/Makefile.in +410 -0
  49. data/libchdr/deps/zlib-1.2.11/README +115 -0
  50. data/libchdr/deps/zlib-1.2.11/adler32.c +186 -0
  51. data/libchdr/deps/zlib-1.2.11/compress.c +86 -0
  52. data/libchdr/deps/zlib-1.2.11/configure +921 -0
  53. data/libchdr/deps/zlib-1.2.11/crc32.c +442 -0
  54. data/libchdr/deps/zlib-1.2.11/crc32.h +441 -0
  55. data/libchdr/deps/zlib-1.2.11/deflate.c +2163 -0
  56. data/libchdr/deps/zlib-1.2.11/deflate.h +349 -0
  57. data/libchdr/deps/zlib-1.2.11/doc/algorithm.txt +209 -0
  58. data/libchdr/deps/zlib-1.2.11/doc/rfc1950.txt +619 -0
  59. data/libchdr/deps/zlib-1.2.11/doc/rfc1951.txt +955 -0
  60. data/libchdr/deps/zlib-1.2.11/doc/rfc1952.txt +675 -0
  61. data/libchdr/deps/zlib-1.2.11/doc/txtvsbin.txt +107 -0
  62. data/libchdr/deps/zlib-1.2.11/gzclose.c +25 -0
  63. data/libchdr/deps/zlib-1.2.11/gzguts.h +218 -0
  64. data/libchdr/deps/zlib-1.2.11/gzlib.c +637 -0
  65. data/libchdr/deps/zlib-1.2.11/gzread.c +654 -0
  66. data/libchdr/deps/zlib-1.2.11/gzwrite.c +665 -0
  67. data/libchdr/deps/zlib-1.2.11/infback.c +640 -0
  68. data/libchdr/deps/zlib-1.2.11/inffast.c +323 -0
  69. data/libchdr/deps/zlib-1.2.11/inffast.h +11 -0
  70. data/libchdr/deps/zlib-1.2.11/inffixed.h +94 -0
  71. data/libchdr/deps/zlib-1.2.11/inflate.c +1561 -0
  72. data/libchdr/deps/zlib-1.2.11/inflate.h +125 -0
  73. data/libchdr/deps/zlib-1.2.11/inftrees.c +304 -0
  74. data/libchdr/deps/zlib-1.2.11/inftrees.h +62 -0
  75. data/libchdr/deps/zlib-1.2.11/make_vms.com +867 -0
  76. data/libchdr/deps/zlib-1.2.11/treebuild.xml +116 -0
  77. data/libchdr/deps/zlib-1.2.11/trees.c +1203 -0
  78. data/libchdr/deps/zlib-1.2.11/trees.h +128 -0
  79. data/libchdr/deps/zlib-1.2.11/uncompr.c +93 -0
  80. data/libchdr/deps/zlib-1.2.11/zconf.h +534 -0
  81. data/libchdr/deps/zlib-1.2.11/zconf.h.cmakein +536 -0
  82. data/libchdr/deps/zlib-1.2.11/zconf.h.in +534 -0
  83. data/libchdr/deps/zlib-1.2.11/zlib.3 +149 -0
  84. data/libchdr/deps/zlib-1.2.11/zlib.3.pdf +0 -0
  85. data/libchdr/deps/zlib-1.2.11/zlib.h +1912 -0
  86. data/libchdr/deps/zlib-1.2.11/zlib.map +94 -0
  87. data/libchdr/deps/zlib-1.2.11/zlib.pc.cmakein +13 -0
  88. data/libchdr/deps/zlib-1.2.11/zlib.pc.in +13 -0
  89. data/libchdr/deps/zlib-1.2.11/zlib2ansi +152 -0
  90. data/libchdr/deps/zlib-1.2.11/zutil.c +325 -0
  91. data/libchdr/deps/zlib-1.2.11/zutil.h +271 -0
  92. data/libchdr/include/dr_libs/dr_flac.h +12280 -0
  93. data/libchdr/include/libchdr/bitstream.h +43 -0
  94. data/libchdr/include/libchdr/cdrom.h +110 -0
  95. data/libchdr/include/libchdr/chd.h +427 -0
  96. data/libchdr/include/libchdr/chdconfig.h +10 -0
  97. data/libchdr/include/libchdr/coretypes.h +60 -0
  98. data/libchdr/include/libchdr/flac.h +50 -0
  99. data/libchdr/include/libchdr/huffman.h +90 -0
  100. data/libchdr/pkg-config.pc.in +10 -0
  101. data/libchdr/src/libchdr_bitstream.c +125 -0
  102. data/libchdr/src/libchdr_cdrom.c +415 -0
  103. data/libchdr/src/libchdr_chd.c +2744 -0
  104. data/libchdr/src/libchdr_flac.c +302 -0
  105. data/libchdr/src/libchdr_huffman.c +545 -0
  106. data/libchdr/src/link.T +5 -0
  107. data/libchdr/tests/CMakeLists.txt +2 -0
  108. data/libchdr/tests/benchmark.c +52 -0
  109. metadata +183 -0
@@ -0,0 +1,302 @@
1
+ /* license:BSD-3-Clause
2
+ * copyright-holders:Aaron Giles
3
+ ***************************************************************************
4
+
5
+ flac.c
6
+
7
+ FLAC compression wrappers
8
+
9
+ ***************************************************************************/
10
+
11
+ #include <string.h>
12
+
13
+ #include <libchdr/flac.h>
14
+ #define DR_FLAC_IMPLEMENTATION
15
+ #define DR_FLAC_NO_STDIO
16
+ #include <dr_libs/dr_flac.h>
17
+
18
+ /***************************************************************************
19
+ * FLAC DECODER
20
+ ***************************************************************************
21
+ */
22
+
23
+ static size_t flac_decoder_read_callback(void *userdata, void *buffer, size_t bytes);
24
+ static drflac_bool32 flac_decoder_seek_callback(void *userdata, int offset, drflac_seek_origin origin);
25
+ static void flac_decoder_metadata_callback(void *userdata, drflac_metadata *metadata);
26
+ static void flac_decoder_write_callback(void *userdata, void *buffer, size_t bytes);
27
+
28
+
29
+ /* getters (valid after reset) */
30
+ static uint32_t sample_rate(flac_decoder *decoder) { return decoder->sample_rate; }
31
+ static uint8_t channels(flac_decoder *decoder) { return decoder->channels; }
32
+ static uint8_t bits_per_sample(flac_decoder *decoder) { return decoder->bits_per_sample; }
33
+
34
+ /*-------------------------------------------------
35
+ * flac_decoder - constructor
36
+ *-------------------------------------------------
37
+ */
38
+
39
+ int flac_decoder_init(flac_decoder *decoder)
40
+ {
41
+ decoder->decoder = NULL;
42
+ decoder->sample_rate = 0;
43
+ decoder->channels = 0;
44
+ decoder->bits_per_sample = 0;
45
+ decoder->compressed_offset = 0;
46
+ decoder->compressed_start = NULL;
47
+ decoder->compressed_length = 0;
48
+ decoder->compressed2_start = NULL;
49
+ decoder->compressed2_length = 0;
50
+ decoder->uncompressed_offset = 0;
51
+ decoder->uncompressed_length = 0;
52
+ decoder->uncompressed_swap = 0;
53
+ return 0;
54
+ }
55
+
56
+ /*-------------------------------------------------
57
+ * flac_decoder - destructor
58
+ *-------------------------------------------------
59
+ */
60
+
61
+ void flac_decoder_free(flac_decoder* decoder)
62
+ {
63
+ if ((decoder != NULL) && (decoder->decoder != NULL))
64
+ drflac_close(decoder->decoder);
65
+ decoder->decoder = NULL;
66
+ }
67
+
68
+ /*-------------------------------------------------
69
+ * reset - reset state with the original
70
+ * parameters
71
+ *-------------------------------------------------
72
+ */
73
+
74
+ static int flac_decoder_internal_reset(flac_decoder* decoder)
75
+ {
76
+ decoder->compressed_offset = 0;
77
+ flac_decoder_free(decoder);
78
+ decoder->decoder = drflac_open_with_metadata(
79
+ flac_decoder_read_callback, flac_decoder_seek_callback,
80
+ flac_decoder_metadata_callback, decoder, NULL);
81
+ return (decoder->decoder != NULL);
82
+ }
83
+
84
+ /*-------------------------------------------------
85
+ * reset - reset state with new memory parameters
86
+ * and a custom-generated header
87
+ *-------------------------------------------------
88
+ */
89
+
90
+ int flac_decoder_reset(flac_decoder* decoder, uint32_t sample_rate, uint8_t num_channels, uint32_t block_size, const void *buffer, uint32_t length)
91
+ {
92
+ /* modify the template header with our parameters */
93
+ static const uint8_t s_header_template[0x2a] =
94
+ {
95
+ 0x66, 0x4C, 0x61, 0x43, /* +00: 'fLaC' stream header */
96
+ 0x80, /* +04: metadata block type 0 (STREAMINFO), */
97
+ /* flagged as last block */
98
+ 0x00, 0x00, 0x22, /* +05: metadata block length = 0x22 */
99
+ 0x00, 0x00, /* +08: minimum block size */
100
+ 0x00, 0x00, /* +0A: maximum block size */
101
+ 0x00, 0x00, 0x00, /* +0C: minimum frame size (0 == unknown) */
102
+ 0x00, 0x00, 0x00, /* +0F: maximum frame size (0 == unknown) */
103
+ 0x0A, 0xC4, 0x42, 0xF0, 0x00, 0x00, 0x00, 0x00, /* +12: sample rate (0x0ac44 == 44100), */
104
+ /* numchannels (2), sample bits (16), */
105
+ /* samples in stream (0 == unknown) */
106
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* +1A: MD5 signature (0 == none) */
107
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* +2A: start of stream data */
108
+ };
109
+ memcpy(decoder->custom_header, s_header_template, sizeof(s_header_template));
110
+ decoder->custom_header[0x08] = decoder->custom_header[0x0a] = (block_size*num_channels) >> 8;
111
+ decoder->custom_header[0x09] = decoder->custom_header[0x0b] = (block_size*num_channels) & 0xff;
112
+ decoder->custom_header[0x12] = sample_rate >> 12;
113
+ decoder->custom_header[0x13] = sample_rate >> 4;
114
+ decoder->custom_header[0x14] = (sample_rate << 4) | ((num_channels - 1) << 1);
115
+
116
+ /* configure the header ahead of the provided buffer */
117
+ decoder->compressed_start = (const uint8_t *)(decoder->custom_header);
118
+ decoder->compressed_length = sizeof(decoder->custom_header);
119
+ decoder->compressed2_start = (const uint8_t *)(buffer);
120
+ decoder->compressed2_length = length;
121
+ return flac_decoder_internal_reset(decoder);
122
+ }
123
+
124
+ /*-------------------------------------------------
125
+ * decode_interleaved - decode to an interleaved
126
+ * sound stream
127
+ *-------------------------------------------------
128
+ */
129
+
130
+ int flac_decoder_decode_interleaved(flac_decoder* decoder, int16_t *samples, uint32_t num_samples, int swap_endian)
131
+ {
132
+ /* configure the uncompressed buffer */
133
+ memset(decoder->uncompressed_start, 0, sizeof(decoder->uncompressed_start));
134
+ decoder->uncompressed_start[0] = samples;
135
+ decoder->uncompressed_offset = 0;
136
+ decoder->uncompressed_length = num_samples;
137
+ decoder->uncompressed_swap = swap_endian;
138
+
139
+ #define BUFFER 2352 /* bytes per CD audio sector */
140
+ int16_t buffer[BUFFER];
141
+ uint32_t buf_samples = BUFFER / channels(decoder);
142
+ /* loop until we get everything we want */
143
+ while (decoder->uncompressed_offset < decoder->uncompressed_length) {
144
+ uint32_t frames = (num_samples < buf_samples ? num_samples : buf_samples);
145
+ if (!drflac_read_pcm_frames_s16(decoder->decoder, frames, buffer))
146
+ return 0;
147
+ flac_decoder_write_callback(decoder, buffer, frames*sizeof(*buffer)*channels(decoder));
148
+ num_samples -= frames;
149
+ }
150
+ return 1;
151
+ }
152
+
153
+ /*-------------------------------------------------
154
+ * finish - finish up the decode
155
+ *-------------------------------------------------
156
+ */
157
+
158
+ uint32_t flac_decoder_finish(flac_decoder* decoder)
159
+ {
160
+ /* get the final decoding position and move forward */
161
+ drflac *flac = decoder->decoder;
162
+ uint64_t position = decoder->compressed_offset;
163
+
164
+ /* ugh... there's no function to obtain bytes used in drflac :-/ */
165
+ position -= DRFLAC_CACHE_L2_LINES_REMAINING(&flac->bs) * sizeof(drflac_cache_t);
166
+ position -= DRFLAC_CACHE_L1_BITS_REMAINING(&flac->bs) / 8;
167
+ position -= flac->bs.unalignedByteCount;
168
+
169
+ /* adjust position if we provided the header */
170
+ if (position == 0)
171
+ return 0;
172
+ if (decoder->compressed_start == (const uint8_t *)(decoder->custom_header))
173
+ position -= decoder->compressed_length;
174
+
175
+ flac_decoder_free(decoder);
176
+ return position;
177
+ }
178
+
179
+ /*-------------------------------------------------
180
+ * read_callback - handle reads from the input
181
+ * stream
182
+ *-------------------------------------------------
183
+ */
184
+
185
+ #define MIN(x, y) ((x) < (y) ? (x) : (y))
186
+
187
+ static size_t flac_decoder_read_callback(void *userdata, void *buffer, size_t bytes)
188
+ {
189
+ flac_decoder* decoder = (flac_decoder*)userdata;
190
+ uint8_t *dst = buffer;
191
+
192
+ /* copy from primary buffer first */
193
+ uint32_t outputpos = 0;
194
+ if (outputpos < bytes && decoder->compressed_offset < decoder->compressed_length)
195
+ {
196
+ uint32_t bytes_to_copy = MIN(bytes - outputpos, decoder->compressed_length - decoder->compressed_offset);
197
+ memcpy(&dst[outputpos], decoder->compressed_start + decoder->compressed_offset, bytes_to_copy);
198
+ outputpos += bytes_to_copy;
199
+ decoder->compressed_offset += bytes_to_copy;
200
+ }
201
+
202
+ /* once we're out of that, copy from the secondary buffer */
203
+ if (outputpos < bytes && decoder->compressed_offset < decoder->compressed_length + decoder->compressed2_length)
204
+ {
205
+ uint32_t bytes_to_copy = MIN(bytes - outputpos, decoder->compressed2_length - (decoder->compressed_offset - decoder->compressed_length));
206
+ memcpy(&dst[outputpos], decoder->compressed2_start + decoder->compressed_offset - decoder->compressed_length, bytes_to_copy);
207
+ outputpos += bytes_to_copy;
208
+ decoder->compressed_offset += bytes_to_copy;
209
+ }
210
+
211
+ return outputpos;
212
+ }
213
+
214
+ /*-------------------------------------------------
215
+ * metadata_callback - handle STREAMINFO metadata
216
+ *-------------------------------------------------
217
+ */
218
+
219
+ static void flac_decoder_metadata_callback(void *userdata, drflac_metadata *metadata)
220
+ {
221
+ flac_decoder *decoder = userdata;
222
+
223
+ /* ignore all but STREAMINFO metadata */
224
+ if (metadata->type != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO)
225
+ return;
226
+
227
+ /* parse out the data we care about */
228
+ decoder->sample_rate = metadata->data.streaminfo.sampleRate;
229
+ decoder->bits_per_sample = metadata->data.streaminfo.bitsPerSample;
230
+ decoder->channels = metadata->data.streaminfo.channels;
231
+ }
232
+
233
+ /*-------------------------------------------------
234
+ * write_callback - handle writes to the output
235
+ * stream
236
+ *-------------------------------------------------
237
+ */
238
+
239
+ static void flac_decoder_write_callback(void *userdata, void *buffer, size_t bytes)
240
+ {
241
+ int sampnum, chan;
242
+ int shift, blocksize;
243
+ flac_decoder * decoder = (flac_decoder *)userdata;
244
+ int16_t *sampbuf = (int16_t *)buffer;
245
+ int sampch = channels(decoder);
246
+ uint32_t offset = decoder->uncompressed_offset;
247
+ uint16_t usample;
248
+
249
+ /* interleaved case */
250
+ shift = decoder->uncompressed_swap ? 8 : 0;
251
+ blocksize = bytes / (sampch * sizeof(sampbuf[0]));
252
+ if (decoder->uncompressed_start[1] == NULL)
253
+ {
254
+ int16_t *dest = decoder->uncompressed_start[0] + offset * sampch;
255
+ for (sampnum = 0; sampnum < blocksize && offset < decoder->uncompressed_length; sampnum++, offset++)
256
+ for (chan = 0; chan < sampch; chan++) {
257
+ usample = (uint16_t)*sampbuf++;
258
+ *dest++ = (int16_t)((usample << shift) | (usample >> shift));
259
+ }
260
+ }
261
+
262
+ /* non-interleaved case */
263
+ else
264
+ {
265
+ for (sampnum = 0; sampnum < blocksize && offset < decoder->uncompressed_length; sampnum++, offset++)
266
+ for (chan = 0; chan < sampch; chan++) {
267
+ usample = (uint16_t)*sampbuf++;
268
+ if (decoder->uncompressed_start[chan] != NULL)
269
+ decoder->uncompressed_start[chan][offset] = (int16_t) ((usample << shift) | (usample >> shift));
270
+ }
271
+ }
272
+ decoder->uncompressed_offset = offset;
273
+ }
274
+
275
+
276
+ /*-------------------------------------------------
277
+ * seek_callback - handle seeks on the output
278
+ * stream
279
+ *-------------------------------------------------
280
+ */
281
+
282
+ static drflac_bool32 flac_decoder_seek_callback(void *userdata, int offset, drflac_seek_origin origin)
283
+ {
284
+ flac_decoder * decoder = (flac_decoder *)userdata;
285
+ uint32_t length = decoder->compressed_length + decoder->compressed2_length;
286
+
287
+ if (origin == drflac_seek_origin_start) {
288
+ uint32_t pos = offset;
289
+ if (pos <= length) {
290
+ decoder->compressed_offset = pos;
291
+ return 1;
292
+ }
293
+ } else if (origin == drflac_seek_origin_current) {
294
+ uint32_t pos = decoder->compressed_offset + offset;
295
+ if (pos <= length) {
296
+ decoder->compressed_offset = pos;
297
+ return 1;
298
+ }
299
+ }
300
+ return 0;
301
+ }
302
+