2 ** Copyright (C) 1999-2006 Erik de Castro Lopo <erikd@mega-nerd.com>
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.
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.
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.
19 #ifndef SNDFILE_COMMON_H
20 #define SNDFILE_COMMON_H
37 #error "This code is not designed to be compiled with a C++ compiler."
41 #elif defined (__GNUC__)
42 # define UNUSED(x) UNUSED_ ## x __attribute__ ((unused))
43 #elif defined (__LCLINT__)
44 # define UNUSED(x) /*@unused@*/ x
50 # define WARN_UNUSED __attribute__ ((warn_unused_result))
55 #define SF_BUFFER_LEN (8192*2)
56 #define SF_FILENAME_LEN (512)
57 #define SF_SYSERR_LEN (256)
58 #define SF_MAX_STRINGS (16)
59 #define SF_STR_BUFFER_LEN (8192)
60 #define SF_HEADER_LEN (4100 + SF_STR_BUFFER_LEN)
62 #define PSF_SEEK_ERROR ((sf_count_t) -1)
65 #define BITWIDTH2BYTES(x) (((x) + 7) / 8)
67 /* For some reason sizeof returns an unsigned value which causes
68 ** a warning when that value is added or subtracted from a signed
69 ** value. Use SIGNED_SIZEOF instead.
71 #define SIGNED_SIZEOF(x) ((int) sizeof (x))
73 #define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof ((x) [0])))
75 #define SF_MAX(a,b) ((a) > (b) ? (a) : (b))
76 #define SF_MIN(a,b) ((a) < (b) ? (a) : (b))
79 { /* PEAK chunk location. */
83 /* PEAK chunk location. */
87 /* str_flags values. */
88 SF_STR_ALLOW_START = 0x0100,
89 SF_STR_ALLOW_END = 0x0200,
91 /* Location of strings. */
92 SF_STR_LOCATE_START = 0x0400,
93 SF_STR_LOCATE_END = 0x0800,
95 SFD_TYPEMASK = 0x0FFFFFFF
98 #define SFM_MASK (SFM_READ | SFM_WRITE | SFM_RDWR)
99 #define SFM_UNMASK (~SFM_MASK)
101 /*---------------------------------------------------------------------------------------
102 ** Formats that may be supported at some time in the future.
103 ** When support is finalised, these values move to src/sndfile.h.
107 { /* Work in progress. */
109 /* Formats supported read only. */
110 SF_FORMAT_WVE = 0x4020000, /* Psion ALaw Sound File */
111 SF_FORMAT_TXW = 0x4030000, /* Yamaha TX16 sampler file */
112 SF_FORMAT_DWD = 0x4040000, /* DiamondWare Digirized */
114 /* Following are detected but not supported. */
115 SF_FORMAT_OGG = 0x4090000,
117 SF_FORMAT_REX = 0x40A0000, /* Propellorheads Rex/Rcy */
118 SF_FORMAT_REX2 = 0x40D0000, /* Propellorheads Rex2 */
119 SF_FORMAT_KRZ = 0x40E0000, /* Kurzweil sampler file */
120 SF_FORMAT_WMA = 0x4100000, /* Windows Media Audio. */
121 SF_FORMAT_SHN = 0x4110000, /* Shorten. */
123 /* Unsupported encodings. */
124 SF_FORMAT_VORBIS = 0x1001,
126 SF_FORMAT_SVX_FIB = 0x1020, /* SVX Fibonacci Delta encoding. */
127 SF_FORMAT_SVX_EXP = 0x1021, /* SVX Exponential Delta encoding. */
129 SF_FORMAT_PCM_N = 0x1030
132 /*---------------------------------------------------------------------------------------
133 ** PEAK_CHUNK - This chunk type is common to both AIFF and WAVE files although their
134 ** endian encodings are different.
138 { double value ; /* signed value of peak */
139 sf_count_t position ; /* the sample frame for the peak */
143 { /* libsndfile internal : write a PEAK chunk at the start or end of the file? */
147 unsigned int version ; /* version of the PEAK chunk */
148 unsigned int timestamp ; /* secs since 1/1/1970 */
151 unsigned int edit_number ;
153 #if HAVE_FLEXIBLE_ARRAY
154 /* the per channel peak info */
158 ** This is not ISO compliant C. It works on some compilers which
159 ** don't support the ISO standard flexible struct array which is
160 ** used above. If your compiler doesn't like this I suggest you find
161 ** youself a 1999 ISO C standards compilant compiler. GCC-3.X is
162 ** highly recommended.
168 static inline PEAK_INFO *
169 peak_info_calloc (int channels)
170 { return calloc (1, sizeof (PEAK_INFO) + channels * sizeof (PEAK_POS)) ;
171 } /* peak_info_calloc */
181 { return (size_t) x ;
182 } /* size_t_of_int */
184 /*=======================================================================================
185 ** SF_PRIVATE stuct - a pointer to this struct is passed back to the caller of the
186 ** sf_open_XXXX functions. The caller however has no knowledge of the struct's
190 typedef struct sf_private_tag
191 { /* Force the compiler to double align the start of buffer. */
193 { double dbuf [SF_BUFFER_LEN / sizeof (double)] ;
194 #if (defined (SIZEOF_INT64_T) && (SIZEOF_INT64_T == 8))
195 int64_t lbuf [SF_BUFFER_LEN / sizeof (int64_t)] ;
197 long lbuf [SF_BUFFER_LEN / sizeof (double)] ;
199 float fbuf [SF_BUFFER_LEN / sizeof (float)] ;
200 int ibuf [SF_BUFFER_LEN / sizeof (int)] ;
201 short sbuf [SF_BUFFER_LEN / sizeof (short)] ;
202 char cbuf [SF_BUFFER_LEN / sizeof (char)] ;
203 signed char scbuf [SF_BUFFER_LEN / sizeof (signed char)] ;
204 unsigned char ucbuf [SF_BUFFER_LEN / sizeof (signed char)] ;
207 char filepath [SF_FILENAME_LEN] ;
208 char rsrcpath [SF_FILENAME_LEN] ;
209 char directory [SF_FILENAME_LEN] ;
210 char filename [SF_FILENAME_LEN / 4] ;
212 char syserr [SF_SYSERR_LEN] ;
214 /* logbuffer and logindex should only be changed within the logging functions
217 char logbuffer [SF_BUFFER_LEN] ;
218 unsigned char header [SF_HEADER_LEN] ; /* Must be unsigned */
219 int rwf_endian ; /* Header endian-ness flag. */
221 /* Storage and housekeeping data for adding/reading strings from
224 STR_DATA strings [SF_MAX_STRINGS] ;
225 char str_storage [SF_STR_BUFFER_LEN] ;
229 /* Guard value. If this changes the buffers above have overflowed. */
232 /* Index variables for maintaining logbuffer and header above. */
234 int headindex, headend ;
236 int do_not_close_descriptor ;
240 ** These fields can only be used in src/file_io.c.
241 ** They are basically the same as a windows file HANDLE.
243 void *hfile, *hrsrc, *hsaved ;
245 /* These fields can only be used in src/file_io.c. */
246 int filedes, rsrcdes, savedes ;
251 int mode ; /* Open mode : SFM_READ, SFM_WRITE or SFM_RDWR. */
252 int endian ; /* File endianness : SF_ENDIAN_LITTLE or SF_ENDIAN_BIG. */
253 int float_endswap ; /* Need to endswap float32s? */
256 ** Maximum float value for calculating the multiplier for
257 ** float/double to short/int conversions.
262 /* Vairables for handling pipes. */
263 int is_pipe ; /* True if file is a pipe. */
264 sf_count_t pipeoffset ; /* Number of bytes read from a pipe. */
266 /* True if clipping must be performed on float->int conversions. */
271 int have_written ; /* Has a single write been done to the file? */
272 PEAK_INFO *peak_info ;
275 SF_LOOP_INFO *loop_info ;
276 SF_INSTRUMENT *instrument ;
278 /* Broadcast (EBU) Info */
279 SF_BROADCAST_INFO *broadcast_info ;
281 sf_count_t filelength ; /* Overall length of (embedded) file. */
282 sf_count_t fileoffset ; /* Offset in number of bytes from beginning of file. */
284 sf_count_t rsrclength ; /* Length of the resource fork (if it exists). */
286 sf_count_t dataoffset ; /* Offset in number of bytes from beginning of file. */
287 sf_count_t datalength ; /* Length in bytes of the audio data. */
288 sf_count_t dataend ; /* Offset to file tailer. */
290 int blockwidth ; /* Size in bytes of one set of interleaved samples. */
291 int bytewidth ; /* Size in bytes of one sample (one channel). */
296 int last_op ; /* Last operation; either SFM_READ or SFM_WRITE */
297 sf_count_t read_current ;
298 sf_count_t write_current ;
300 void *fdata ; /* This is a pointer to dynamically allocated file format
304 SF_DITHER_INFO write_dither ;
305 SF_DITHER_INFO read_dither ;
313 /* A set of file specific function pointers */
315 sf_count_t (*read_short) (struct sf_private_tag*, short *ptr, sf_count_t len) ;
316 sf_count_t (*read_int) (struct sf_private_tag*, int *ptr, sf_count_t len) ;
317 sf_count_t (*read_float) (struct sf_private_tag*, float *ptr, sf_count_t len) ;
318 sf_count_t (*read_double) (struct sf_private_tag*, double *ptr, sf_count_t len) ;
320 sf_count_t (*write_short) (struct sf_private_tag*, const short *ptr, sf_count_t len) ;
321 sf_count_t (*write_int) (struct sf_private_tag*, const int *ptr, sf_count_t len) ;
322 sf_count_t (*write_float) (struct sf_private_tag*, const float *ptr, sf_count_t len) ;
323 sf_count_t (*write_double) (struct sf_private_tag*, const double *ptr, sf_count_t len) ;
325 sf_count_t (*seek) (struct sf_private_tag*, int mode, sf_count_t samples_from_start) ;
326 int (*write_header) (struct sf_private_tag*, int calc_length) ;
327 int (*command) (struct sf_private_tag*, int command, void *data, int datasize) ;
330 ** Separate close functions for the codec and the container.
331 ** The codec close function is always called first.
333 int (*codec_close) (struct sf_private_tag*) ;
334 int (*container_close) (struct sf_private_tag*) ;
338 /* Virtual I/O functions. */
341 void *vio_user_data ;
347 { SFE_NO_ERROR = SF_ERR_NO_ERROR,
348 SFE_BAD_OPEN_FORMAT = SF_ERR_UNRECOGNISED_FORMAT,
349 SFE_SYSTEM = SF_ERR_SYSTEM,
350 SFE_MALFORMED_FILE = SF_ERR_MALFORMED_FILE,
351 SFE_UNSUPPORTED_ENCODING = SF_ERR_UNSUPPORTED_ENCODING,
358 SFE_BAD_SF_INCOMPLETE,
372 SFE_NO_EMBED_SUPPORT,
373 SFE_NO_EMBEDDED_RDWR,
416 SFE_WAV_BAD_BLOCKALIGN,
419 SFE_WAV_ADPCM_NOT4BIT,
420 SFE_WAV_ADPCM_CHANNELS,
421 SFE_WAV_GSM610_FORMAT,
422 SFE_WAV_UNKNOWN_CHUNK,
426 SFE_AIFF_AIFF_NO_FORM,
427 SFE_AIFF_COMM_NO_FORM,
428 SFE_AIFF_SSND_NO_COMM,
429 SFE_AIFF_UNKNOWN_CHUNK,
430 SFE_AIFF_COMM_CHUNK_SIZE,
431 SFE_AIFF_BAD_COMM_CHUNK,
432 SFE_AIFF_PEAK_B4_COMM,
436 SFE_AIFF_RW_SSND_NOT_LAST,
438 SFE_AU_UNKNOWN_FORMAT,
440 SFE_AU_EMBED_BAD_LEN,
442 SFE_RAW_READ_BAD_SPEC,
443 SFE_RAW_BAD_BITWIDTH,
448 SFE_PAF_UNKNOWN_FORMAT,
449 SFE_PAF_SHORT_HEADER,
455 SFE_SVX_BAD_NAME_LENGTH,
458 SFE_NIST_CRLF_CONVERISON,
459 SFE_NIST_BAD_ENCODING,
465 SFE_VOC_BAD_SECTIONS,
466 SFE_VOC_MULTI_SAMPLERATE,
467 SFE_VOC_MULTI_SECTION,
469 SFE_VOC_SECTION_COUNT,
473 SFE_IRCAM_BAD_CHANNELS,
474 SFE_IRCAM_UNKNOWN_FORMAT,
483 SFE_W64_ADPCM_NOT4BIT,
484 SFE_W64_ADPCM_CHANNELS,
485 SFE_W64_GSM610_FORMAT,
488 SFE_MAT4_NO_SAMPLERATE,
489 SFE_MAT4_ZERO_CHANNELS,
493 SFE_MAT5_SAMPLE_RATE,
494 SFE_MAT5_ZERO_CHANNELS,
498 SFE_PVF_BAD_BITWIDTH,
500 SFE_DWVW_BAD_BITWIDTH,
504 SFE_XI_EXCESS_SAMPLES,
510 SFE_SDS_BAD_BIT_WIDTH,
512 SFE_SD2_FD_DISALLOWED,
513 SFE_SD2_BAD_DATA_OFFSET,
514 SFE_SD2_BAD_MAP_OFFSET,
515 SFE_SD2_BAD_DATA_LENGTH,
516 SFE_SD2_BAD_MAP_LENGTH,
518 SFE_SD2_BAD_SAMPLE_SIZE,
521 SFE_FLAC_NEW_DECODER,
522 SFE_FLAC_INIT_DECODER,
524 SFE_FLAC_BAD_SAMPLE_RATE,
525 SFE_FLAC_UNKOWN_ERROR,
527 SFE_MAX_ERROR /* This must be last in list. */
530 int subformat_to_bytewidth (int format) ;
531 int s_bitwidth_to_subformat (int bits) ;
532 int u_bitwidth_to_subformat (int bits) ;
534 /* Functions for reading and writing floats and doubles on processors
535 ** with non-IEEE floats/doubles.
537 float float32_be_read (unsigned char *cptr) ;
538 float float32_le_read (unsigned char *cptr) ;
539 void float32_be_write (float in, unsigned char *out) ;
540 void float32_le_write (float in, unsigned char *out) ;
542 double double64_be_read (unsigned char *cptr) ;
543 double double64_le_read (unsigned char *cptr) ;
544 void double64_be_write (double in, unsigned char *out) ;
545 void double64_le_write (double in, unsigned char *out) ;
547 /* Functions for writing to the internal logging buffer. */
549 void psf_log_printf (SF_PRIVATE *psf, const char *format, ...) ;
550 void psf_log_SF_INFO (SF_PRIVATE *psf) ;
552 void psf_hexdump (void *ptr, int len) ;
554 /* Functions used when writing file headers. */
556 int psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...) ;
557 void psf_asciiheader_printf (SF_PRIVATE *psf, const char *format, ...) ;
559 /* Functions used when reading file headers. */
561 int psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) ;
563 /* Functions used in the write function for updating the peak chunk. */
565 void peak_update_short (SF_PRIVATE *psf, short *ptr, size_t items) ;
566 void peak_update_int (SF_PRIVATE *psf, int *ptr, size_t items) ;
567 void peak_update_double (SF_PRIVATE *psf, double *ptr, size_t items) ;
569 /* Functions defined in command.c. */
571 int psf_get_format_simple_count (void) ;
572 int psf_get_format_simple (SF_FORMAT_INFO *data) ;
574 int psf_get_format_info (SF_FORMAT_INFO *data) ;
576 int psf_get_format_major_count (void) ;
577 int psf_get_format_major (SF_FORMAT_INFO *data) ;
579 int psf_get_format_subtype_count (void) ;
580 int psf_get_format_subtype (SF_FORMAT_INFO *data) ;
582 void psf_generate_format_desc (SF_PRIVATE *psf) ;
584 double psf_calc_signal_max (SF_PRIVATE *psf, int normalize) ;
585 int psf_calc_max_all_channels (SF_PRIVATE *psf, double *peaks, int normalize) ;
587 int psf_get_signal_max (SF_PRIVATE *psf, double *peak) ;
588 int psf_get_max_all_channels (SF_PRIVATE *psf, double *peaks) ;
590 /* Functions in strings.c. */
592 const char* psf_get_string (SF_PRIVATE *psf, int str_type) ;
593 int psf_set_string (SF_PRIVATE *psf, int str_type, const char *str) ;
594 int psf_store_string (SF_PRIVATE *psf, int str_type, const char *str) ;
596 /* Default seek function. Use for PCM and float encoded data. */
597 sf_count_t psf_default_seek (SF_PRIVATE *psf, int mode, sf_count_t samples_from_start) ;
599 /* Generate the currebt date as a string. */
600 void psf_get_date_str (char *str, int maxlen) ;
602 int macos_guess_file_type (SF_PRIVATE *psf, const char *filename) ;
604 /*------------------------------------------------------------------------------------
605 ** File I/O functions which will allow access to large files (> 2 Gig) on
606 ** some 32 bit OSes. Implementation in file_io.c.
609 int psf_fopen (SF_PRIVATE *psf, const char *pathname, int flags) ;
610 int psf_set_stdio (SF_PRIVATE *psf, int mode) ;
611 int psf_file_valid (SF_PRIVATE *psf) ;
612 void psf_set_file (SF_PRIVATE *psf, int fd) ;
613 void psf_init_files (SF_PRIVATE *psf) ;
614 void psf_use_rsrc (SF_PRIVATE *psf, int on_off) ;
616 sf_count_t psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence) ;
617 sf_count_t psf_fread (void *ptr, sf_count_t bytes, sf_count_t count, SF_PRIVATE *psf) ;
618 sf_count_t psf_fwrite (const void *ptr, sf_count_t bytes, sf_count_t count, SF_PRIVATE *psf) ;
619 sf_count_t psf_fgets (char *buffer, sf_count_t bufsize, SF_PRIVATE *psf) ;
620 sf_count_t psf_ftell (SF_PRIVATE *psf) ;
621 sf_count_t psf_get_filelen (SF_PRIVATE *psf) ;
623 void psf_fsync (SF_PRIVATE *psf) ;
625 int psf_is_pipe (SF_PRIVATE *psf) ;
627 int psf_ftruncate (SF_PRIVATE *psf, sf_count_t len) ;
628 int psf_fclose (SF_PRIVATE *psf) ;
630 /* Open and close the resource fork of a file. */
631 int psf_open_rsrc (SF_PRIVATE *psf, int mode) ;
632 int psf_close_rsrc (SF_PRIVATE *psf) ;
635 void psf_fclearerr (SF_PRIVATE *psf) ;
636 int psf_ferror (SF_PRIVATE *psf) ;
639 /*------------------------------------------------------------------------------------
640 ** Functions for reading and writing different file formats.
643 int aiff_open (SF_PRIVATE *psf) ;
644 int au_open (SF_PRIVATE *psf) ;
645 int avr_open (SF_PRIVATE *psf) ;
646 int htk_open (SF_PRIVATE *psf) ;
647 int ircam_open (SF_PRIVATE *psf) ;
648 int mat4_open (SF_PRIVATE *psf) ;
649 int mat5_open (SF_PRIVATE *psf) ;
650 int nist_open (SF_PRIVATE *psf) ;
651 int paf_open (SF_PRIVATE *psf) ;
652 int pvf_open (SF_PRIVATE *psf) ;
653 int raw_open (SF_PRIVATE *psf) ;
654 int sd2_open (SF_PRIVATE *psf) ;
655 int sds_open (SF_PRIVATE *psf) ;
656 int svx_open (SF_PRIVATE *psf) ;
657 int voc_open (SF_PRIVATE *psf) ;
658 int w64_open (SF_PRIVATE *psf) ;
659 int wav_open (SF_PRIVATE *psf) ;
660 int xi_open (SF_PRIVATE *psf) ;
661 int flac_open (SF_PRIVATE *psf) ;
662 int caf_open (SF_PRIVATE *psf) ;
664 /* In progress. Do not currently work. */
666 int mpeg_open (SF_PRIVATE *psf) ;
667 int ogg_open (SF_PRIVATE *psf) ;
668 int rx2_open (SF_PRIVATE *psf) ;
669 int txw_open (SF_PRIVATE *psf) ;
670 int wve_open (SF_PRIVATE *psf) ;
671 int dwd_open (SF_PRIVATE *psf) ;
673 int macbinary3_open (SF_PRIVATE *psf) ;
675 /*------------------------------------------------------------------------------------
676 ** Init functions for a number of common data encodings.
679 int pcm_init (SF_PRIVATE *psf) ;
680 int ulaw_init (SF_PRIVATE *psf) ;
681 int alaw_init (SF_PRIVATE *psf) ;
682 int float32_init (SF_PRIVATE *psf) ;
683 int double64_init (SF_PRIVATE *psf) ;
684 int dwvw_init (SF_PRIVATE *psf, int bitwidth) ;
685 int gsm610_init (SF_PRIVATE *psf) ;
686 int vox_adpcm_init (SF_PRIVATE *psf) ;
687 int flac_init (SF_PRIVATE *psf) ;
688 int g72x_init (SF_PRIVATE * psf) ;
690 int dither_init (SF_PRIVATE *psf, int mode) ;
692 int wav_w64_ima_init (SF_PRIVATE *psf, int blockalign, int samplesperblock) ;
693 int wav_w64_msadpcm_init (SF_PRIVATE *psf, int blockalign, int samplesperblock) ;
695 int aiff_ima_init (SF_PRIVATE *psf, int blockalign, int samplesperblock) ;
697 int interleave_init (SF_PRIVATE *psf) ;
699 /*------------------------------------------------------------------------------------
700 ** Other helper functions.
703 void *psf_memset (void *s, int c, sf_count_t n) ;
705 SF_INSTRUMENT * psf_instrument_alloc (void) ;
708 SF_BROADCAST_INFO* broadcast_info_alloc (void) ;
709 int broadcast_info_copy (SF_BROADCAST_INFO* dst, SF_BROADCAST_INFO* src) ;
710 int broadcast_add_coding_history (SF_BROADCAST_INFO* bext, unsigned int channels, unsigned int samplerate) ;
712 /*------------------------------------------------------------------------------------
713 ** Here's how we fix systems which don't snprintf / vsnprintf.
714 ** Systems without these functions should use the
718 #define LSF_SNPRINTF _snprintf
719 #elif (HAVE_SNPRINTF && ! FORCE_MISSING_SNPRINTF)
720 #define LSF_SNPRINTF snprintf
722 int missing_snprintf (char *str, size_t n, char const *fmt, ...) ;
723 #define LSF_SNPRINTF missing_snprintf
727 #define LSF_VSNPRINTF _vsnprintf
728 #elif (HAVE_VSNPRINTF && ! FORCE_MISSING_SNPRINTF)
729 #define LSF_VSNPRINTF vsnprintf
731 int missing_vsnprintf (char *str, size_t n, const char *fmt, ...) ;
732 #define LSF_VSNPRINTF missing_vsnprintf
735 /*------------------------------------------------------------------------------------
736 ** Extra commands for sf_command(). Not for public use yet.
740 { SFC_TEST_AIFF_ADD_INST_CHUNK = 0x2000,
741 SFC_TEST_WAV_ADD_INFO_CHUNK = 0x2010
745 ** Maybe, one day, make these functions or something like them, public.
747 ** Buffer to buffer dithering. Pointer in and out are allowed to point
748 ** to the same buffer for in-place dithering.
752 int sf_dither_short (const SF_DITHER_INFO *dither, const short *in, short *out, int count) ;
753 int sf_dither_int (const SF_DITHER_INFO *dither, const int *in, int *out, int count) ;
754 int sf_dither_float (const SF_DITHER_INFO *dither, const float *in, float *out, int count) ;
755 int sf_dither_double (const SF_DITHER_INFO *dither, const double *in, double *out, int count) ;
758 #endif /* SNDFILE_COMMON_H */
761 ** Do not edit or modify anything in this comment block.
762 ** The arch-tag line is a file identity tag for the GNU Arch
763 ** revision control system.
765 ** arch-tag: 7b45c0ee-5835-4a18-a4ef-994e4cd95b67