Coverage Report

Created: 2026-01-17 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libsndfile/src/rx2.c
Line
Count
Source
1
/*
2
** Copyright (C) 2001-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
3
**
4
** This program is free software; you can redistribute it and/or modify
5
** it under the terms of the GNU Lesser General Public License as published by
6
** the Free Software Foundation; either version 2.1 of the License, or
7
** (at your option) any later version.
8
**
9
** This program is distributed in the hope that it will be useful,
10
** but WITHOUT ANY WARRANTY; without even the implied warranty of
11
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
** GNU Lesser General Public License for more details.
13
**
14
** You should have received a copy of the GNU Lesser General Public License
15
** along with this program; if not, write to the Free Software
16
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
*/
18
19
#include  "sfconfig.h"
20
21
#include  <stdio.h>
22
#include  <string.h>
23
#include  <ctype.h>
24
#include  <stdarg.h>
25
26
#include  "sndfile.h"
27
#include  "sfendian.h"
28
#include  "common.h"
29
30
#if (ENABLE_EXPERIMENTAL_CODE == 0)
31
32
int
33
rx2_open  (SF_PRIVATE *psf)
34
1
{ if (psf)
35
1
    return SFE_UNIMPLEMENTED ;
36
0
  return 0 ;
37
1
} /* rx2_open */
38
39
#else
40
41
/*------------------------------------------------------------------------------
42
 * Macros to handle big/little endian issues.
43
*/
44
45
#define CAT_MARKER  (MAKE_MARKER ('C', 'A', 'T', ' '))
46
#define GLOB_MARKER (MAKE_MARKER ('G', 'L', 'O', 'B'))
47
48
#define RECY_MARKER (MAKE_MARKER ('R', 'E', 'C', 'Y'))
49
50
#define SLCL_MARKER (MAKE_MARKER ('S', 'L', 'C', 'L'))
51
#define SLCE_MARKER (MAKE_MARKER ('S', 'L', 'C', 'E'))
52
53
#define DEVL_MARKER (MAKE_MARKER ('D', 'E', 'V', 'L'))
54
#define TRSH_MARKER (MAKE_MARKER ('T', 'R', 'S', 'H'))
55
56
#define EQ_MARKER (MAKE_MARKER ('E', 'Q', ' ', ' '))
57
#define COMP_MARKER (MAKE_MARKER ('C', 'O', 'M', 'P'))
58
59
#define SINF_MARKER (MAKE_MARKER ('S', 'I', 'N', 'F'))
60
#define SDAT_MARKER (MAKE_MARKER ('S', 'D', 'A', 'T'))
61
62
/*------------------------------------------------------------------------------
63
 * Typedefs for file chunks.
64
*/
65
66
67
/*------------------------------------------------------------------------------
68
 * Private static functions.
69
*/
70
static int  rx2_close (SF_PRIVATE *psf) ;
71
72
/*------------------------------------------------------------------------------
73
** Public functions.
74
*/
75
76
int
77
rx2_open  (SF_PRIVATE *psf)
78
{ static const char *marker_type [4] =
79
  { "Original Enabled", "Enabled Hidden",
80
    "Additional/PencilTool", "Disabled"
81
    } ;
82
83
  BUF_UNION ubuf ;
84
  int error, marker, length, glob_offset, slce_count, frames ;
85
  int sdat_length = 0, slce_total = 0 ;
86
  int n_channels ;
87
88
89
  /* So far only doing read. */
90
91
  psf_binheader_readf (psf, "Epm4", 0, &marker, &length) ;
92
93
  if (marker != CAT_MARKER)
94
  { psf_log_printf (psf, "length : %d\n", length) ;
95
    return -1000 ;
96
    } ;
97
98
  if (length != psf->filelength - 8)
99
    psf_log_printf (psf, "%M : %d (should be %d)\n", marker, length, psf->filelength - 8) ;
100
  else
101
    psf_log_printf (psf, "%M : %d\n", marker, length) ;
102
103
  /* 'REX2' marker */
104
  psf_binheader_readf (psf, "m", &marker) ;
105
  psf_log_printf (psf, "%M", marker) ;
106
107
  /* 'HEAD' marker */
108
  psf_binheader_readf (psf, "m", &marker) ;
109
  psf_log_printf (psf, "%M\n", marker) ;
110
111
  /* Grab 'GLOB' offset. */
112
  psf_binheader_readf (psf, "E4", &glob_offset) ;
113
  glob_offset += 0x14 ; /* Add the current file offset. */
114
115
  /* Jump to offset 0x30 */
116
  psf_binheader_readf (psf, "p", 0x30) ;
117
118
  /* Get name length */
119
  length = 0 ;
120
  psf_binheader_readf (psf, "1", &length) ;
121
  if (length >= SIGNED_SIZEOF (ubuf.cbuf))
122
  { psf_log_printf (psf, "  Text : %d *** Error : Too sf_count_t!\n") ;
123
    return -1001 ;
124
    }
125
126
  memset (ubuf.cbuf, 0, sizeof (ubuf.cbuf)) ;
127
  psf_binheader_readf (psf, "b", ubuf.cbuf, length) ;
128
  psf_log_printf (psf, " Text : \"%s\"\n", ubuf.cbuf) ;
129
130
  /* Jump to GLOB offset position. */
131
  if (glob_offset & 1)
132
    glob_offset ++ ;
133
134
  psf_binheader_readf (psf, "p", glob_offset) ;
135
136
  slce_count = 0 ;
137
  /* GLOB */
138
  while (1)
139
  { psf_binheader_readf (psf, "m", &marker) ;
140
141
    if (marker != SLCE_MARKER && slce_count > 0)
142
    { psf_log_printf (psf, "   SLCE count : %d\n", slce_count) ;
143
      slce_count = 0 ;
144
      }
145
    switch (marker)
146
    { case GLOB_MARKER:
147
          psf_binheader_readf (psf, "E4", &length) ;
148
          psf_log_printf (psf, " %M : %d\n", marker, length) ;
149
          psf_binheader_readf (psf, "j", length) ;
150
          break ;
151
152
      case RECY_MARKER:
153
          psf_binheader_readf (psf, "E4", &length) ;
154
          psf_log_printf (psf, " %M : %d\n", marker, length) ;
155
          psf_binheader_readf (psf, "j", (length+1) & 0xFFFFFFFE) ; /* ?????? */
156
          break ;
157
158
      case CAT_MARKER:
159
          psf_binheader_readf (psf, "E4", &length) ;
160
          psf_log_printf (psf, " %M : %d\n", marker, length) ;
161
          /*-psf_binheader_readf (psf, "j", length) ;-*/
162
          break ;
163
164
      case DEVL_MARKER:
165
          psf_binheader_readf (psf, "mE4", &marker, &length) ;
166
          psf_log_printf (psf, "  DEVL%M : %d\n", marker, length) ;
167
          if (length & 1)
168
            length ++ ;
169
          psf_binheader_readf (psf, "j", length) ;
170
          break ;
171
172
      case EQ_MARKER:
173
      case COMP_MARKER:
174
          psf_binheader_readf (psf, "E4", &length) ;
175
          psf_log_printf (psf, "   %M : %d\n", marker, length) ;
176
          /* This is weird!!!! why make this (length - 1) */
177
          if (length & 1)
178
            length ++ ;
179
          psf_binheader_readf (psf, "j", length) ;
180
          break ;
181
182
      case SLCL_MARKER:
183
          psf_log_printf (psf, "  %M\n    (Offset, Next Offset, Type)\n", marker) ;
184
          slce_count = 0 ;
185
          break ;
186
187
      case SLCE_MARKER:
188
          { int len [4], indx ;
189
190
            psf_binheader_readf (psf, "E4444", &len [0], &len [1], &len [2], &len [3]) ;
191
192
            indx = ((len [3] & 0x0000FFFF) >> 8) & 3 ;
193
194
            if (len [2] == 1)
195
            { if (indx != 1)
196
                indx = 3 ;  /* 2 cases, where next slice offset = 1 -> disabled & enabled/hidden */
197
198
              psf_log_printf (psf, "   %M : (%6d, ?: 0x%X, %s)\n", marker, len [1], (len [3] & 0xFFFF0000) >> 16, marker_type [indx]) ;
199
              }
200
            else
201
            { slce_total += len [2] ;
202
203
              psf_log_printf (psf, "   %M : (%6d, SLCE_next_ofs:%d, ?: 0x%X, %s)\n", marker, len [1], len [2], (len [3] & 0xFFFF0000) >> 16, marker_type [indx]) ;
204
              } ;
205
206
            slce_count ++ ;
207
            } ;
208
          break ;
209
210
      case SINF_MARKER:
211
          psf_binheader_readf (psf, "E4", &length) ;
212
          psf_log_printf (psf, " %M : %d\n", marker, length) ;
213
214
          psf_binheader_readf (psf, "E2", &n_channels) ;
215
          n_channels = (n_channels & 0x0000FF00) >> 8 ;
216
          psf_log_printf (psf, "  Channels    : %d\n", n_channels) ;
217
218
          psf_binheader_readf (psf, "E44", &psf->sf.samplerate, &frames) ;
219
          psf->sf.frames = frames ;
220
          psf_log_printf (psf, "  Sample Rate : %d\n", psf->sf.samplerate) ;
221
          psf_log_printf (psf, "  Frames      : %D\n", psf->sf.frames) ;
222
223
          psf_binheader_readf (psf, "E4", &length) ;
224
          psf_log_printf (psf, "  ??????????? : %d\n", length) ;
225
226
          psf_binheader_readf (psf, "E4", &length) ;
227
          psf_log_printf (psf, "  ??????????? : %d\n", length) ;
228
          break ;
229
230
      case SDAT_MARKER:
231
          psf_binheader_readf (psf, "E4", &length) ;
232
233
        sdat_length = length ;
234
235
          /* Get the current offset. */
236
          psf->dataoffset = psf_binheader_readf (psf, NULL) ;
237
238
          if (psf->dataoffset + length != psf->filelength)
239
            psf_log_printf (psf, " %M : %d (should be %d)\n", marker, length, psf->dataoffset + psf->filelength) ;
240
          else
241
            psf_log_printf (psf, " %M : %d\n", marker, length) ;
242
          break ;
243
244
      default :
245
          psf_log_printf (psf, "Unknown marker : 0x%X %M", marker, marker) ;
246
          return -1003 ;
247
          break ;
248
      } ;
249
250
    /* SDAT always last marker in file. */
251
    if (marker == SDAT_MARKER)
252
      break ;
253
    } ;
254
255
  puts (psf->parselog.buf) ;
256
  puts ("-----------------------------------") ;
257
258
  printf ("SDAT length  : %d\n", sdat_length) ;
259
  printf ("SLCE count   : %d\n", slce_count) ;
260
261
  /* Hack for zero slice count. */
262
  if (slce_count == 0 && slce_total == 1)
263
    slce_total = frames ;
264
265
  printf ("SLCE samples : %d\n", slce_total) ;
266
267
  /* Two bytes per sample. */
268
  printf ("Comp Ratio   : %f:1\n", (2.0 * slce_total * n_channels) / sdat_length) ;
269
270
  puts (" ") ;
271
272
  psf->parselog.buf [0] = 0 ;
273
274
  /* OK, have the header although not too sure what it all means. */
275
276
  psf->endian = SF_ENDIAN_BIG ;
277
278
  psf->datalength = psf->filelength - psf->dataoffset ;
279
280
  if (psf_fseek (psf, psf->dataoffset, SEEK_SET))
281
    return SFE_BAD_SEEK ;
282
283
  psf->sf.format = (SF_FORMAT_REX2 | SF_FORMAT_DWVW_12) ;
284
285
  psf->sf.channels  = 1 ;
286
  psf->bytewidth    = 2 ;
287
  psf->blockwidth   = psf->sf.channels * psf->bytewidth ;
288
289
  if ((error = dwvw_init (psf, 16)))
290
    return error ;
291
292
  psf->container_close = rx2_close ;
293
294
  if (! psf->sf.frames && psf->blockwidth)
295
    psf->sf.frames = psf->datalength / psf->blockwidth ;
296
297
  /* All done. */
298
299
  return 0 ;
300
} /* rx2_open */
301
302
/*------------------------------------------------------------------------------
303
*/
304
305
static int
306
rx2_close (SF_PRIVATE *psf)
307
{
308
  if (psf->file.mode == SFM_WRITE)
309
  { /*  Now we know for certain the length of the file we can re-write
310
    **  correct values for the FORM, 8SVX and BODY chunks.
311
    */
312
313
    } ;
314
315
  return 0 ;
316
} /* rx2_close */
317
318
#endif