Coverage Report

Created: 2025-12-05 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libsndfile/src/dither.c
Line
Count
Source
1
/*
2
** Copyright (C) 2003-2011 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  <stdlib.h>
22
23
#include  "sndfile.h"
24
#include  "sfendian.h"
25
#include  "common.h"
26
27
/*============================================================================
28
**  Rule number 1 is to only apply dither when going from a larger bitwidth
29
**  to a smaller bitwidth. This can happen on both read and write.
30
**
31
**  Need to apply dither on all conversions marked X below.
32
**
33
**  Dither on write:
34
**
35
**                    Input
36
**          | short   int     float   double
37
**      --------+-----------------------------------------------
38
**    O 8 bit | X     X     X     X
39
**    u 16 bit  | none    X     X     X
40
**    t 24 bit  | none    X     X     X
41
**    p 32 bit  | none    none    X     X
42
**    u float | none    none    none    none
43
**    t double  | none    none    none    none
44
**
45
**  Dither on read:
46
**
47
**                    Input
48
**    O     | 8 bit 16 bit  24 bit  32 bit  float double
49
**    u --------+-------------------------------------------------
50
**    t short | none  none  X   X   X   X
51
**    p int   | none  none  none  X   X   X
52
**    u float | none  none  none  none  none  none
53
**    t double  | none  none  none  none  none  none
54
*/
55
56
0
#define SFE_DITHER_BAD_PTR  666
57
#define SFE_DITHER_BAD_TYPE 667
58
59
typedef struct
60
{ int     read_short_dither_bits, read_int_dither_bits ;
61
  int     write_short_dither_bits, write_int_dither_bits ;
62
  double    read_float_dither_scale, read_double_dither_bits ;
63
  double    write_float_dither_scale, write_double_dither_bits ;
64
65
  sf_count_t  (*read_short) (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
66
  sf_count_t  (*read_int)   (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
67
  sf_count_t  (*read_float) (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
68
  sf_count_t  (*read_double)  (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
69
70
  sf_count_t  (*write_short)  (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
71
  sf_count_t  (*write_int)  (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
72
  sf_count_t  (*write_float)  (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
73
  sf_count_t  (*write_double) (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
74
75
  double buffer [SF_BUFFER_LEN / sizeof (double)] ;
76
} DITHER_DATA ;
77
78
static sf_count_t dither_read_short   (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
79
static sf_count_t dither_read_int   (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
80
81
static sf_count_t dither_write_short  (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
82
static sf_count_t dither_write_int    (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
83
static sf_count_t dither_write_float  (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
84
static sf_count_t dither_write_double (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
85
86
int
87
dither_init (SF_PRIVATE *psf, int mode)
88
0
{ DITHER_DATA *pdither ;
89
90
0
  pdither = psf->dither ; /* This may be NULL. */
91
92
  /* Turn off dither on read. */
93
0
  if (mode == SFM_READ && psf->read_dither.type == SFD_NO_DITHER)
94
0
  { if (pdither == NULL)
95
0
      return 0 ; /* Dither is already off, so just return. */
96
97
0
    if (pdither->read_short)
98
0
      psf->read_short = pdither->read_short ;
99
0
    if (pdither->read_int)
100
0
      psf->read_int = pdither->read_int ;
101
0
    if (pdither->read_float)
102
0
      psf->read_float = pdither->read_float ;
103
0
    if (pdither->read_double)
104
0
      psf->read_double = pdither->read_double ;
105
0
    return 0 ;
106
0
    } ;
107
108
  /* Turn off dither on write. */
109
0
  if (mode == SFM_WRITE && psf->write_dither.type == SFD_NO_DITHER)
110
0
  { if (pdither == NULL)
111
0
      return 0 ; /* Dither is already off, so just return. */
112
113
0
    if (pdither->write_short)
114
0
      psf->write_short = pdither->write_short ;
115
0
    if (pdither->write_int)
116
0
      psf->write_int = pdither->write_int ;
117
0
    if (pdither->write_float)
118
0
      psf->write_float = pdither->write_float ;
119
0
    if (pdither->write_double)
120
0
      psf->write_double = pdither->write_double ;
121
0
    return 0 ;
122
0
    } ;
123
124
  /* Turn on dither on read if asked. */
125
0
  if (mode == SFM_READ && psf->read_dither.type != 0)
126
0
  { if (pdither == NULL)
127
0
      pdither = psf->dither = calloc (1, sizeof (DITHER_DATA)) ;
128
0
    if (pdither == NULL)
129
0
      return SFE_MALLOC_FAILED ;
130
131
0
    switch (SF_CODEC (psf->sf.format))
132
0
    { case SF_FORMAT_DOUBLE :
133
0
      case SF_FORMAT_FLOAT :
134
0
          pdither->read_int = psf->read_int ;
135
0
          psf->read_int = dither_read_int ;
136
0
          break ;
137
138
0
      case SF_FORMAT_PCM_32 :
139
0
      case SF_FORMAT_PCM_24 :
140
0
      case SF_FORMAT_PCM_16 :
141
0
      case SF_FORMAT_PCM_S8 :
142
0
      case SF_FORMAT_PCM_U8 :
143
0
          pdither->read_short = psf->read_short ;
144
0
          psf->read_short = dither_read_short ;
145
0
          break ;
146
147
0
      default : break ;
148
0
      } ;
149
0
    } ;
150
151
  /* Turn on dither on write if asked. */
152
0
  if (mode == SFM_WRITE && psf->write_dither.type != 0)
153
0
  { if (pdither == NULL)
154
0
      pdither = psf->dither = calloc (1, sizeof (DITHER_DATA)) ;
155
0
    if (pdither == NULL)
156
0
      return SFE_MALLOC_FAILED ;
157
158
0
    switch (SF_CODEC (psf->sf.format))
159
0
    { case SF_FORMAT_DOUBLE :
160
0
      case SF_FORMAT_FLOAT :
161
0
          pdither->write_int = psf->write_int ;
162
0
          psf->write_int = dither_write_int ;
163
0
          break ;
164
165
0
      case SF_FORMAT_PCM_32 :
166
0
      case SF_FORMAT_PCM_24 :
167
0
      case SF_FORMAT_PCM_16 :
168
0
      case SF_FORMAT_PCM_S8 :
169
0
      case SF_FORMAT_PCM_U8 :
170
0
          break ;
171
172
0
      default : break ;
173
0
      } ;
174
175
0
    pdither->write_short = psf->write_short ;
176
0
    psf->write_short = dither_write_short ;
177
178
0
    pdither->write_int = psf->write_int ;
179
0
    psf->write_int = dither_write_int ;
180
181
0
    pdither->write_float = psf->write_float ;
182
0
    psf->write_float = dither_write_float ;
183
184
0
    pdither->write_double = psf->write_double ;
185
0
    psf->write_double = dither_write_double ;
186
0
    } ;
187
188
0
  return 0 ;
189
0
} /* dither_init */
190
191
/*==============================================================================
192
*/
193
194
static void dither_short  (const short *in, short *out, int frames, int channels) ;
195
static void dither_int    (const int *in, int *out, int frames, int channels) ;
196
197
static void dither_float  (const float *in, float *out, int frames, int channels) ;
198
static void dither_double (const double *in, double *out, int frames, int channels) ;
199
200
static sf_count_t
201
dither_read_short (SF_PRIVATE * UNUSED (psf), short * UNUSED (ptr), sf_count_t len)
202
0
{
203
0
  return len ;
204
0
} /* dither_read_short */
205
206
static sf_count_t
207
dither_read_int (SF_PRIVATE * UNUSED (psf), int * UNUSED (ptr), sf_count_t len)
208
0
{
209
0
  return len ;
210
0
} /* dither_read_int */
211
212
/*------------------------------------------------------------------------------
213
*/
214
215
static sf_count_t
216
dither_write_short  (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
217
0
{ DITHER_DATA *pdither ;
218
0
  int     bufferlen, writecount, thiswrite ;
219
0
  sf_count_t  total = 0 ;
220
221
0
  if ((pdither = psf->dither) == NULL)
222
0
  { psf->error = SFE_DITHER_BAD_PTR ;
223
0
    return 0 ;
224
0
    } ;
225
226
0
  switch (SF_CODEC (psf->sf.format))
227
0
  { case SF_FORMAT_PCM_S8 :
228
0
    case SF_FORMAT_PCM_U8 :
229
0
    case SF_FORMAT_DPCM_8 :
230
0
        break ;
231
232
0
    default :
233
0
      return pdither->write_short (psf, ptr, len) ;
234
0
    } ;
235
236
0
  bufferlen = sizeof (pdither->buffer) / (sizeof (short)) ;
237
238
0
  while (len > 0)
239
0
  { writecount = (len >= bufferlen) ? bufferlen : (int) len ;
240
0
    writecount /= psf->sf.channels ;
241
0
    writecount *= psf->sf.channels ;
242
243
0
    dither_short (ptr, (short*) pdither->buffer, writecount / psf->sf.channels, psf->sf.channels) ;
244
245
0
    thiswrite = (int) pdither->write_short (psf, (short*) pdither->buffer, writecount) ;
246
0
    total += thiswrite ;
247
0
    len -= thiswrite ;
248
0
    if (thiswrite < writecount)
249
0
      break ;
250
0
    } ;
251
252
0
  return total ;
253
0
} /* dither_write_short */
254
255
static sf_count_t
256
dither_write_int  (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
257
0
{ DITHER_DATA *pdither ;
258
0
  int     bufferlen, writecount, thiswrite ;
259
0
  sf_count_t  total = 0 ;
260
261
0
  if ((pdither = psf->dither) == NULL)
262
0
  { psf->error = SFE_DITHER_BAD_PTR ;
263
0
    return 0 ;
264
0
    } ;
265
266
0
  switch (SF_CODEC (psf->sf.format))
267
0
  { case SF_FORMAT_PCM_S8 :
268
0
    case SF_FORMAT_PCM_U8 :
269
0
    case SF_FORMAT_PCM_16 :
270
0
    case SF_FORMAT_PCM_24 :
271
0
        break ;
272
273
0
    case SF_FORMAT_DPCM_8 :
274
0
    case SF_FORMAT_DPCM_16 :
275
0
        break ;
276
277
0
    default :
278
0
      return pdither->write_int (psf, ptr, len) ;
279
0
    } ;
280
281
282
0
  bufferlen = sizeof (pdither->buffer) / (sizeof (int)) ;
283
284
0
  while (len > 0)
285
0
  { writecount = (len >= bufferlen) ? bufferlen : (int) len ;
286
0
    writecount /= psf->sf.channels ;
287
0
    writecount *= psf->sf.channels ;
288
289
0
    dither_int (ptr, (int*) pdither->buffer, writecount / psf->sf.channels, psf->sf.channels) ;
290
291
0
    thiswrite = (int) pdither->write_int (psf, (int*) pdither->buffer, writecount) ;
292
0
    total += thiswrite ;
293
0
    len -= thiswrite ;
294
0
    if (thiswrite < writecount)
295
0
      break ;
296
0
    } ;
297
298
0
  return total ;
299
0
} /* dither_write_int */
300
301
static sf_count_t
302
dither_write_float  (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
303
0
{ DITHER_DATA *pdither ;
304
0
  int     bufferlen, writecount, thiswrite ;
305
0
  sf_count_t  total = 0 ;
306
307
0
  if ((pdither = psf->dither) == NULL)
308
0
  { psf->error = SFE_DITHER_BAD_PTR ;
309
0
    return 0 ;
310
0
    } ;
311
312
0
  switch (SF_CODEC (psf->sf.format))
313
0
  { case SF_FORMAT_PCM_S8 :
314
0
    case SF_FORMAT_PCM_U8 :
315
0
    case SF_FORMAT_PCM_16 :
316
0
    case SF_FORMAT_PCM_24 :
317
0
        break ;
318
319
0
    case SF_FORMAT_DPCM_8 :
320
0
    case SF_FORMAT_DPCM_16 :
321
0
        break ;
322
323
0
    default :
324
0
      return pdither->write_float (psf, ptr, len) ;
325
0
    } ;
326
327
0
  bufferlen = sizeof (pdither->buffer) / (sizeof (float)) ;
328
329
0
  while (len > 0)
330
0
  { writecount = (len >= bufferlen) ? bufferlen : (int) len ;
331
0
    writecount /= psf->sf.channels ;
332
0
    writecount *= psf->sf.channels ;
333
334
0
    dither_float (ptr, (float*) pdither->buffer, writecount / psf->sf.channels, psf->sf.channels) ;
335
336
0
    thiswrite = (int) pdither->write_float (psf, (float*) pdither->buffer, writecount) ;
337
0
    total += thiswrite ;
338
0
    len -= thiswrite ;
339
0
    if (thiswrite < writecount)
340
0
      break ;
341
0
    } ;
342
343
0
  return total ;
344
0
} /* dither_write_float */
345
346
static sf_count_t
347
dither_write_double (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
348
0
{ DITHER_DATA *pdither ;
349
0
  int     bufferlen, writecount, thiswrite ;
350
0
  sf_count_t  total = 0 ;
351
352
0
  if ((pdither = psf->dither) == NULL)
353
0
  { psf->error = SFE_DITHER_BAD_PTR ;
354
0
    return 0 ;
355
0
    } ;
356
357
0
  switch (SF_CODEC (psf->sf.format))
358
0
  { case SF_FORMAT_PCM_S8 :
359
0
    case SF_FORMAT_PCM_U8 :
360
0
    case SF_FORMAT_PCM_16 :
361
0
    case SF_FORMAT_PCM_24 :
362
0
        break ;
363
364
0
    case SF_FORMAT_DPCM_8 :
365
0
    case SF_FORMAT_DPCM_16 :
366
0
        break ;
367
368
0
    default :
369
0
      return pdither->write_double (psf, ptr, len) ;
370
0
    } ;
371
372
373
0
  bufferlen = sizeof (pdither->buffer) / sizeof (double) ;
374
375
0
  while (len > 0)
376
0
  { writecount = (len >= bufferlen) ? bufferlen : (int) len ;
377
0
    writecount /= psf->sf.channels ;
378
0
    writecount *= psf->sf.channels ;
379
380
0
    dither_double (ptr, (double*) pdither->buffer, writecount / psf->sf.channels, psf->sf.channels) ;
381
382
0
    thiswrite = (int) pdither->write_double (psf, (double*) pdither->buffer, writecount) ;
383
0
    total += thiswrite ;
384
0
    len -= thiswrite ;
385
0
    if (thiswrite < writecount)
386
0
      break ;
387
0
    } ;
388
389
0
  return total ;
390
0
} /* dither_write_double */
391
392
/*==============================================================================
393
*/
394
395
static void
396
dither_short (const short *in, short *out, int frames, int channels)
397
0
{ int ch, k ;
398
399
0
  for (ch = 0 ; ch < channels ; ch++)
400
0
    for (k = ch ; k < channels * frames ; k += channels)
401
0
      out [k] = in [k] ;
402
403
0
} /* dither_short */
404
405
static void
406
dither_int (const int *in, int *out, int frames, int channels)
407
0
{ int ch, k ;
408
409
0
  for (ch = 0 ; ch < channels ; ch++)
410
0
    for (k = ch ; k < channels * frames ; k += channels)
411
0
      out [k] = in [k] ;
412
413
0
} /* dither_int */
414
415
static void
416
dither_float (const float *in, float *out, int frames, int channels)
417
0
{ int ch, k ;
418
419
0
  for (ch = 0 ; ch < channels ; ch++)
420
0
    for (k = ch ; k < channels * frames ; k += channels)
421
0
      out [k] = in [k] ;
422
423
0
} /* dither_float */
424
425
static void
426
dither_double (const double *in, double *out, int frames, int channels)
427
0
{ int ch, k ;
428
429
0
  for (ch = 0 ; ch < channels ; ch++)
430
0
    for (k = ch ; k < channels * frames ; k += channels)
431
0
      out [k] = in [k] ;
432
433
0
} /* dither_double */
434
435
/*==============================================================================
436
*/
437
#if 0
438
439
/*
440
** Not made public because this (maybe) requires storage of state information.
441
**
442
** Also maybe need separate state info for each channel!!!!
443
*/
444
445
int
446
DO_NOT_USE_sf_dither_short (const SF_DITHER_INFO *dither, const short *in, short *out, int frames, int channels)
447
{ int ch, k ;
448
449
  if (! dither)
450
    return SFE_DITHER_BAD_PTR ;
451
452
  switch (dither->type & SFD_TYPEMASK)
453
  { case SFD_WHITE :
454
    case SFD_TRIANGULAR_PDF :
455
        for (ch = 0 ; ch < channels ; ch++)
456
          for (k = ch ; k < channels * frames ; k += channels)
457
            out [k] = in [k] ;
458
        break ;
459
460
    default :
461
      return SFE_DITHER_BAD_TYPE ;
462
    } ;
463
464
  return 0 ;
465
} /* DO_NOT_USE_sf_dither_short */
466
467
int
468
DO_NOT_USE_sf_dither_int (const SF_DITHER_INFO *dither, const int *in, int *out, int frames, int channels)
469
{ int ch, k ;
470
471
  if (! dither)
472
    return SFE_DITHER_BAD_PTR ;
473
474
  switch (dither->type & SFD_TYPEMASK)
475
  { case SFD_WHITE :
476
    case SFD_TRIANGULAR_PDF :
477
        for (ch = 0 ; ch < channels ; ch++)
478
          for (k = ch ; k < channels * frames ; k += channels)
479
            out [k] = in [k] ;
480
        break ;
481
482
    default :
483
      return SFE_DITHER_BAD_TYPE ;
484
    } ;
485
486
  return 0 ;
487
} /* DO_NOT_USE_sf_dither_int */
488
489
int
490
DO_NOT_USE_sf_dither_float (const SF_DITHER_INFO *dither, const float *in, float *out, int frames, int channels)
491
{ int ch, k ;
492
493
  if (! dither)
494
    return SFE_DITHER_BAD_PTR ;
495
496
  switch (dither->type & SFD_TYPEMASK)
497
  { case SFD_WHITE :
498
    case SFD_TRIANGULAR_PDF :
499
        for (ch = 0 ; ch < channels ; ch++)
500
          for (k = ch ; k < channels * frames ; k += channels)
501
            out [k] = in [k] ;
502
        break ;
503
504
    default :
505
      return SFE_DITHER_BAD_TYPE ;
506
    } ;
507
508
  return 0 ;
509
} /* DO_NOT_USE_sf_dither_float */
510
511
int
512
DO_NOT_USE_sf_dither_double (const SF_DITHER_INFO *dither, const double *in, double *out, int frames, int channels)
513
{ int ch, k ;
514
515
  if (! dither)
516
    return SFE_DITHER_BAD_PTR ;
517
518
  switch (dither->type & SFD_TYPEMASK)
519
  { case SFD_WHITE :
520
    case SFD_TRIANGULAR_PDF :
521
        for (ch = 0 ; ch < channels ; ch++)
522
          for (k = ch ; k < channels * frames ; k += channels)
523
            out [k] = in [k] ;
524
        break ;
525
526
    default :
527
      return SFE_DITHER_BAD_TYPE ;
528
    } ;
529
530
  return 0 ;
531
} /* DO_NOT_USE_sf_dither_double */
532
533
#endif
534