[xiph-commits] r3284 -
libfishsound/branches/1.0-stable-flac/src/libfishsound
conrad at svn.annodex.net
conrad at svn.annodex.net
Tue Dec 4 17:35:11 PST 2007
Author: conrad
Date: 2007-12-04 17:35:10 -0800 (Tue, 04 Dec 2007)
New Revision: 3284
Added:
libfishsound/branches/1.0-stable-flac/src/libfishsound/flac.c
Log:
add flac.c from libfishsound-flac-1.patch (build fails)
Added: libfishsound/branches/1.0-stable-flac/src/libfishsound/flac.c
===================================================================
--- libfishsound/branches/1.0-stable-flac/src/libfishsound/flac.c (rev 0)
+++ libfishsound/branches/1.0-stable-flac/src/libfishsound/flac.c 2007-12-05 01:35:10 UTC (rev 3284)
@@ -0,0 +1,561 @@
+#define DEBUG
+#include <stdio.h>
+
+#include "config.h"
+
+#include "private.h"
+#include "convert.h"
+
+#if HAVE_FLAC
+#include "FLAC/all.h"
+
+#define BITS_PER_SAMPLE 24
+
+typedef struct _FishSoundFlacInfo {
+ FLAC__StreamDecoder *fsd;
+ FLAC__StreamEncoder *fse;
+ unsigned char * buffer;
+ char header;
+ long bufferlength;
+ unsigned long packetno;
+ struct {
+ unsigned char major, minor;
+ } version;
+ unsigned short header_packets;
+ void* pcm;
+} FishSoundFlacInfo;
+
+#ifdef FS_DECODE
+FLAC__StreamDecoderReadStatus fs_flac_read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
+{
+ FishSound* fsound = (FishSound*)client_data;
+ FishSoundFlacInfo* fi = (FishSoundFlacInfo *)fsound->codec_data;
+#ifdef DEBUG
+ fprintf(stderr, "fs_flac_read_callback\n");
+#endif
+ if (fi->bufferlength > *bytes) {
+#ifdef DEBUG
+ fprintf(stderr, "too much data\n");
+#endif
+ return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
+ } else if (fi->bufferlength < 1) {
+#ifdef DEBUG
+ fprintf(stderr, "no data\n");
+#endif
+ return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
+ }
+ memcpy(buffer, fi->buffer, fi->bufferlength);
+ *bytes = fi->bufferlength;
+ fi->bufferlength = 0;
+ return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
+}
+
+FLAC__StreamDecoderWriteStatus fs_flac_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
+{
+ FishSound* fsound = (FishSound*)client_data;
+ FishSoundFlacInfo* fi = (FishSoundFlacInfo *)fsound->codec_data;
+ int i, j, offset;
+#ifdef DEBUG
+ fprintf(stderr, "fs_flac_write_callback\n");
+#endif
+ switch (fsound->pcm_type) {
+ case FISH_SOUND_PCM_SHORT:
+ if (fsound->callback.decoded_short) {
+ if (fsound->interleave) {
+ FishSoundDecoded_ShortIlv dsi;
+ short* retpcm;
+ int shift = 16 - frame->header.bits_per_sample;
+ fi->pcm = realloc(fi->pcm, sizeof(short)*frame->header.channels*frame->header.blocksize);
+ retpcm = (short*) fi->pcm;
+ if (shift < 0) {
+ shift = abs(shift);
+ for (i=0; i<frame->header.blocksize; i++) {
+ offset = i*frame->header.channels;
+ for (j=0; j<frame->header.channels; j++)
+ retpcm[offset + j] = buffer[j][i] >> shift;
+ }
+ } else {
+ for (i=0; i<frame->header.blocksize; i++) {
+ offset = i*frame->header.channels;
+ for (j=0; j<frame->header.channels; j++)
+ retpcm[offset + j] = buffer[j][i] << shift;
+ }
+ }
+ dsi = (FishSoundDecoded_ShortIlv)fsound->callback.decoded_short_ilv;
+ dsi (fsound, (short **)retpcm, frame->header.blocksize, fsound->user_data);
+ } else {
+ FishSoundDecoded_Short ds;
+ short** retpcm, *p;
+ int shift = 16 - frame->header.bits_per_sample;
+ fi->pcm = realloc(fi->pcm, sizeof(short)*frame->header.channels*frame->header.blocksize);
+ retpcm = fi->pcm;
+ if (shift < 0) {
+ shift = abs(shift);
+ for (i=0; i<frame->header.blocksize; i++)
+ for (j=0; j<frame->header.channels; j++) {
+ p = retpcm[j];
+ p[i] = buffer[j][i] >> shift;
+ }
+ } else {
+ for (i=0; i<frame->header.blocksize; i++)
+ for (j=0; j<frame->header.channels; j++) {
+ p = retpcm[j];
+ p[i] = buffer[j][i] << shift;
+ }
+ }
+ ds = (FishSoundDecoded_Short)fsound->callback.decoded_short;
+ ds (fsound, retpcm, frame->header.blocksize, fsound->user_data);
+ }
+ }
+ break;
+ case FISH_SOUND_PCM_INT:
+ if (fsound->callback.decoded_int) {
+ if (fsound->interleave) {
+ FishSoundDecoded_IntIlv dii;
+ int* retpcm;
+ int shift = 32 - frame->header.bits_per_sample;
+ fi->pcm = realloc(fi->pcm, sizeof(int)*frame->header.channels*frame->header.blocksize);
+ retpcm = (int*) fi->pcm;
+ for (i=0; i<frame->header.blocksize; i++) {
+ offset = i*frame->header.channels;
+ for (j=0; j<frame->header.channels; j++)
+ retpcm[offset + j] = buffer[j][i] << shift;
+ }
+ dii = (FishSoundDecoded_IntIlv)fsound->callback.decoded_int_ilv;
+ dii (fsound, (int **)retpcm, frame->header.blocksize, fsound->user_data);
+ } else {
+ FishSoundDecoded_Int di;
+ int** retpcm, *p;
+ int shift = 32 - frame->header.bits_per_sample;
+ fi->pcm = realloc(fi->pcm, sizeof(int)*frame->header.channels*frame->header.blocksize);
+ retpcm = fi->pcm;
+ for (i=0; i<frame->header.blocksize; i++)
+ for (j=0; j<frame->header.channels; j++) {
+ p = retpcm[j];
+ p[i] = buffer[j][i] << shift;
+ }
+ di = (FishSoundDecoded_Int)fsound->callback.decoded_int;
+ di (fsound, retpcm, frame->header.blocksize, fsound->user_data);
+ }
+ }
+ break;
+ case FISH_SOUND_PCM_FLOAT:
+ if (fsound->callback.decoded_float) {
+ if (fsound->interleave) {
+ FishSoundDecoded_FloatIlv dfi;
+ float* retpcm, norm = 1.0 / (1 + (1 << (frame->header.bits_per_sample - 1)));
+ fi->pcm = realloc(fi->pcm, sizeof(float)*frame->header.channels*frame->header.blocksize);
+ retpcm = (float*) fi->pcm;
+ for (i=0; i<frame->header.blocksize; i++) {
+ offset = i*frame->header.channels;
+ for (j=0; j<frame->header.channels; j++)
+ retpcm[offset + j] = buffer[j][i] * norm;
+ }
+ dfi = (FishSoundDecoded_FloatIlv)fsound->callback.decoded_float_ilv;
+ dfi (fsound, (float **)retpcm, frame->header.blocksize, fsound->user_data);
+ } else {
+ FishSoundDecoded_Float df;
+ float** retpcm, *p, norm = 1.0 / (1 + (1 << (frame->header.bits_per_sample - 1)));
+ fi->pcm = realloc(fi->pcm, sizeof(float)*frame->header.channels*frame->header.blocksize);
+ retpcm = fi->pcm;
+ for (i=0; i<frame->header.blocksize; i++)
+ for (j=0; j<frame->header.channels; j++) {
+ p = retpcm[j];
+ p[i] = buffer[j][i] * norm;
+ }
+ df = (FishSoundDecoded_Float)fsound->callback.decoded_float;
+ df (fsound, retpcm, frame->header.blocksize, fsound->user_data);
+ }
+ }
+ break;
+ case FISH_SOUND_PCM_DOUBLE:
+ if (fsound->callback.decoded_double) {
+ if (fsound->interleave) {
+ FishSoundDecoded_DoubleIlv ddi;
+ double* retpcm, norm = 1.0 / (1 + (1 << (frame->header.bits_per_sample - 1)));
+ fi->pcm = realloc(fi->pcm, sizeof(double)*frame->header.channels*frame->header.blocksize);
+ retpcm = (double*) fi->pcm;
+ for (i=0; i<frame->header.blocksize; i++) {
+ offset = i*frame->header.channels;
+ for (j=0; j<frame->header.channels; j++)
+ retpcm[offset + j] = buffer[j][i] * norm;
+ }
+ ddi = (FishSoundDecoded_DoubleIlv)fsound->callback.decoded_double_ilv;
+ ddi (fsound, (double **)retpcm, frame->header.blocksize, fsound->user_data);
+ } else {
+ FishSoundDecoded_Double dd;
+ double** retpcm, *p, norm = 1.0 / (1 + (1 << (frame->header.bits_per_sample - 1)));
+ fi->pcm = realloc(fi->pcm, sizeof(double)*frame->header.channels*frame->header.blocksize);
+ retpcm = fi->pcm;
+ for (i=0; i<frame->header.blocksize; i++)
+ for (j=0; j<frame->header.channels; j++) {
+ p = retpcm[j];
+ p[i] = buffer[j][i] * norm;
+ }
+ dd = (FishSoundDecoded_Double)fsound->callback.decoded_double;
+ dd (fsound, retpcm, frame->header.blocksize, fsound->user_data);
+ }
+ }
+ break;
+ default:
+ return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
+ break;
+ }
+ return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+}
+
+void fs_flac_meta_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
+{
+ FishSound* fsound = (FishSound*)client_data;
+ /* FishSoundFlacInfo* fi = (FishSoundFlacInfo *)fsound->codec_data; */
+#ifdef DEBUG
+ fprintf(stderr, "fs_flac_meta_callback\n");
+#endif
+ switch (metadata->type) {
+ case FLAC__METADATA_TYPE_STREAMINFO:
+ fsound->info.channels = metadata->data.stream_info.channels;
+ fsound->info.samplerate = metadata->data.stream_info.sample_rate;
+ break;
+ default:
+#ifdef DEBUG
+ fprintf(stderr, "not yet implemented type\n");
+#endif
+ break;
+ }
+}
+
+void fs_flac_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
+{
+#ifdef DEBUG
+ fprintf(stderr, "fs_flac_error_callback\n");
+#endif
+ fprintf(stderr, "ERROR: %s\n", FLAC__StreamDecoderErrorStatusString[status]);
+}
+#endif
+
+#ifdef FS_ENCODE
+FLAC__StreamEncoderWriteStatus fs_flac_enc_write_callback(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
+{
+ FishSound* fsound = (FishSound*)client_data;
+ FishSoundFlacInfo *fi = fsound->codec_data;
+#ifdef DEBUG
+ fprintf(stderr, "fs_flac_enc_write_callback\n");
+ printf("bytes: %d, samples: %d\n", bytes, samples);
+#endif DEBUG
+ if (fsound->callback.encoded) {
+ FishSoundEncoded encoded = (FishSoundEncoded)fsound->callback.encoded;
+ if (fi->packetno == 0 && fi->header <= 1) {
+ printf("first: %x\n", buffer[0]);
+ if (fi->header == 0) {
+ fi->buffer = (unsigned char*)malloc(sizeof(unsigned char)*(bytes+9));
+ fi->buffer[0] = 0x7f;
+ fi->buffer[1] = 0x46;
+ fi->buffer[2] = 0x4c;
+ fi->buffer[3] = 0x41;
+ fi->buffer[4] = 0x43;
+ fi->buffer[5] = 1;
+ fi->buffer[6] = 0;
+ fi->buffer[7] = 0;
+ fi->buffer[8] = 2;
+ memcpy (fi->buffer+9, buffer, bytes);
+ fi->bufferlength = bytes+9;
+ fi->header++;
+ } else {
+ unsigned char* tmp = (unsigned char*)malloc(sizeof(unsigned char)*(bytes+fi->bufferlength));
+ memcpy (tmp, fi->buffer, fi->bufferlength);
+ memcpy (tmp+fi->bufferlength, buffer, bytes);
+ fs_free(fi->buffer);
+ fi->buffer = tmp;
+ fi->bufferlength += bytes;
+ fi->header++;
+ encoded (fsound, (unsigned char *)fi->buffer, (long)fi->bufferlength,
+ fsound->user_data);
+ }
+ } else {
+ encoded (fsound, (unsigned char *)buffer, (long)bytes,
+ fsound->user_data);
+ }
+ }
+ return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
+}
+
+void fs_flac_enc_meta_callback(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
+{
+ FishSound* fsound = (FishSound*)client_data;
+ /* FishSoundFlacInfo* fi = (FishSoundFlacInfo *)fsound->codec_data; */
+#ifdef DEBUG
+ fprintf(stderr, "fs_flac_meta_callback\n");
+#endif
+ switch (metadata->type) {
+ case FLAC__METADATA_TYPE_STREAMINFO:
+ printf("channels %d\n", metadata->data.stream_info.channels);
+ /*
+ fsound->info.channels = metadata->data.stream_info.channels;
+ fsound->info.samplerate = metadata->data.stream_info.sample_rate;
+ */
+ break;
+ default:
+#ifdef DEBUG
+ fprintf(stderr, "not yet implemented type\n");
+#endif
+ break;
+ }
+}
+#endif
+
+int
+fish_sound_flac_identify (unsigned char * buf, long bytes)
+{
+ if (buf[0] != 0x7f) return FISH_SOUND_UNKNOWN;
+ if (bytes < 8) return FISH_SOUND_UNKNOWN;
+ if (!strncmp ((char *)buf+1, "FLAC", 4)) {
+#ifdef DEBUG
+ fprintf(stderr, "flac found\n");
+#endif
+ /* if only a short buffer was passed, do a weak identify */
+ if (bytes == 8) return FISH_SOUND_FLAC;
+
+ /* otherwise, assume the buffer is an entire initial header and
+ * feed it to vorbis_synthesis_headerin() */
+ if (!strncmp ((char *)buf+9, "fLaC", 4)) {
+ return FISH_SOUND_FLAC;
+ }
+ }
+ return FISH_SOUND_UNKNOWN;
+}
+
+static int
+fs_flac_command (FishSound * fsound, int command, void * data,
+ int datasize)
+{
+ return 0;
+}
+
+#if FS_ENCODE
+static FishSound *
+fs_flac_enc_headers (FishSound * fsound)
+{
+ FishSoundFlacInfo *fi = fsound->codec_data;
+ fi->fse = FLAC__stream_encoder_new();
+ FLAC__stream_encoder_set_channels(fi->fse, fsound->info.channels);
+ FLAC__stream_encoder_set_sample_rate(fi->fse, fsound->info.samplerate);
+ FLAC__stream_encoder_set_bits_per_sample(fi->fse, BITS_PER_SAMPLE);
+ FLAC__stream_encoder_set_write_callback(fi->fse, fs_flac_enc_write_callback);
+ FLAC__stream_encoder_set_metadata_callback(fi->fse, fs_flac_enc_meta_callback);
+ FLAC__stream_encoder_set_client_data(fi->fse, fsound);
+ // FLAC__stream_encoder_set_total_samples_estimate(fi->fse, );
+ if (FLAC__stream_encoder_init(fi->fse) != FLAC__STREAM_ENCODER_OK) return NULL;
+ return fsound;
+}
+
+static long
+fs_flac_encode_i_ilv (FishSound * fsound, int ** pcm, long frames)
+{
+ FishSoundFlacInfo *fi = fsound->codec_data;
+ int i, *p = (int *)pcm;
+ printf("frames: %ld\n", frames);
+ if (fi->packetno == 0)
+ fs_flac_enc_headers (fsound);
+ // FLAC__stream_encoder_process_interleaved(fi->fse, pcm, frames);
+ fi->packetno++;
+ return 0;
+}
+
+static long
+fs_flac_encode_f_ilv (FishSound * fsound, float ** pcm, long frames)
+{
+ FishSoundFlacInfo *fi = fsound->codec_data;
+ FLAC__int32 *buffer;
+ float * p = (float*)pcm, norm = (1 << (BITS_PER_SAMPLE - 1));
+ int i;
+ long length = frames * fsound->info.channels;
+#ifdef DEBUG
+ fprintf(stderr, "fs_flac_encode_f_ilv\n");
+#endif
+ fi->pcm = realloc(fi->pcm, sizeof(FLAC__int32)*fsound->info.channels*frames);
+ buffer = (FLAC__int32*) fi->pcm;
+ for (i=0; i<length; i++)
+ buffer[i] = p[i] * norm;
+
+ if (fi->packetno == 0)
+ fs_flac_enc_headers (fsound);
+ FLAC__stream_encoder_process_interleaved(fi->fse, buffer, frames);
+ fi->packetno++;
+ return 0;
+}
+#endif
+
+#if FS_DECODE
+static void*
+process_header(FishSound * fsound, unsigned char *buf, long bytes)
+{
+ FishSoundFlacInfo *fi = fsound->codec_data;
+ if (buf[0] != 0x7f) return NULL;
+ if (strncmp(buf+1, "FLAC", 4) != 0) return NULL;
+ fi->version.major = buf[5];
+ fi->version.minor = buf[6];
+#ifdef DEBUG
+ printf("Flac Version: %d.%d\n", fi->version.major, fi->version.minor);
+#endif
+ fi->header_packets = buf[7] << 8 | buf[8];
+#ifdef DEBUG
+ printf("Number of Header packets: %d\n", fi->header_packets);
+#endif
+
+ if ((fi->fsd = FLAC__stream_decoder_new()) == NULL) return NULL;
+ FLAC__stream_decoder_set_read_callback(fi->fsd, fs_flac_read_callback);
+ FLAC__stream_decoder_set_write_callback(fi->fsd, fs_flac_write_callback);
+ FLAC__stream_decoder_set_metadata_callback(fi->fsd, fs_flac_meta_callback);
+ FLAC__stream_decoder_set_error_callback(fi->fsd, fs_flac_error_callback);
+ FLAC__stream_decoder_set_client_data(fi->fsd, fsound);
+ if (FLAC__stream_decoder_init(fi->fsd) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
+ return NULL;
+
+ return fi->fsd;
+}
+
+static long
+fs_flac_decode (FishSound * fsound, unsigned char * buf, long bytes)
+{
+ FishSoundFlacInfo *fi = fsound->codec_data;
+#ifdef DEBUG
+ fprintf(stderr, "fs_flac_decode\n");
+#endif
+ if (fi->packetno == 0) {
+ if (process_header(fsound, buf, bytes) == NULL) {
+ fprintf(stderr, "EROROROROR\n");
+ return -1;
+ }
+ fi->buffer = fs_malloc(sizeof(unsigned char)*bytes);
+ memcpy(fi->buffer, buf+9, bytes-9);
+ fi->bufferlength = bytes-9;
+ }
+ else if (fi->packetno <= fi->header_packets){
+ unsigned char* tmp = fs_malloc(sizeof(unsigned char)*(fi->bufferlength+bytes));
+ /* if (fi->packetno == 1) fish_sound_comments_decode (fsound, buf, bytes); */
+ memcpy(tmp, fi->buffer, fi->bufferlength);
+ memcpy(tmp+fi->bufferlength, buf, bytes);
+ fi->bufferlength += bytes;
+ fs_free(fi->buffer);
+ fi->buffer = tmp;
+ if (fi->packetno == fi->header_packets) {
+ FLAC__stream_decoder_process_until_end_of_metadata(fi->fsd);
+ fs_free(fi->buffer);
+ }
+ /*
+ if (fi->packetno == 0) {
+ if (process_header(fi, buf, bytes) == NULL) printf("EROROROROR\n");
+ buf[13] |= 0x80;
+ fi->buffer = buf+9;
+ fi->bufferlength = bytes-9;
+ FLAC__stream_decoder_process_until_end_of_metadata(fi->fsd);
+ // } else if (fi->packetno == 1) {
+ // fish_sound_comments_decode (fsound, buf, bytes);
+ } else if (fi->packetno <= fi->header_packets) {
+ buf[0] |= 0x80;
+ fi->buffer = buf;
+ fi->bufferlength = bytes;
+ FLAC__stream_decoder_process_until_end_of_metadata(fi->fsd);
+ */
+ } else {
+ fi->buffer = buf;
+ fi->bufferlength = bytes;
+ FLAC__stream_decoder_process_single(fi->fsd);
+ }
+ fi->packetno++;
+ return 0;
+}
+#else /* !FS_DECODE */
+
+#define fs_flac_decode NULL
+
+#endif
+
+static FishSound *
+fs_flac_delete (FishSound * fsound)
+{
+ FishSoundFlacInfo * fi = (FishSoundFlacInfo *)fsound->codec_data;
+
+ if (fsound->mode == FISH_SOUND_DECODE) {
+ FLAC__stream_decoder_finish(fi->fsd);
+ FLAC__stream_decoder_delete(fi->fsd);
+ } else if (fsound->mode == FISH_SOUND_ENCODE) {
+ FLAC__stream_encoder_finish(fi->fse);
+ FLAC__stream_encoder_delete(fi->fse);
+ if (fi->buffer) fs_free(fi->buffer);
+ }
+ if (fi->pcm) fs_free(fi->pcm);
+ fs_free (fi);
+ fsound->codec_data = NULL;
+
+ return fsound;
+}
+
+static int
+fs_flac_reset (FishSound * fsound)
+{
+ FishSoundFlacInfo * fi = (FishSoundFlacInfo *)fsound->codec_data;
+ if (fsound->mode == FISH_SOUND_DECODE) {
+ FLAC__stream_decoder_reset(fi->fsd);
+ } else if (fsound->mode == FISH_SOUND_ENCODE) {
+ }
+ return 0;
+}
+
+static FishSound *
+fs_flac_init (FishSound * fsound)
+{
+ FishSoundFlacInfo *fi;
+
+ fi = fs_malloc (sizeof (FishSoundFlacInfo));
+ if (fi == NULL) return NULL;
+ fi->packetno = 0;
+ fi->header = 0;
+ fi->pcm = NULL;
+ fi->header_packets = 0;
+ fi->fsd = NULL;
+ fi->fse = NULL;
+
+ fsound->codec_data = fi;
+
+#if FS_ENCODE
+ /*
+ if (fsound->mode == FISH_SOUND_ENCODE) {
+ fs_flac_enc_init (fsound);
+ }
+ */
+#endif /* FS_ENCODE */
+
+ return fsound;
+}
+
+FishSoundCodec *
+fish_sound_flac_codec (void)
+{
+ FishSoundCodec * codec;
+
+ codec = (FishSoundCodec *) fs_malloc (sizeof (FishSoundCodec));
+
+ codec->format.format = FISH_SOUND_FLAC;
+ codec->format.name = "Flac (Xiph.Org)";
+ codec->format.extension = "ogg";
+
+ codec->init = fs_flac_init;
+ codec->del = fs_flac_delete;
+ codec->reset = fs_flac_reset;
+ codec->command = fs_flac_command;
+ codec->decode = fs_flac_decode;
+ codec->encode_s = NULL;
+ codec->encode_s_ilv = NULL;
+ codec->encode_i = NULL;
+ codec->encode_i_ilv = fs_flac_encode_i_ilv;
+ codec->encode_f = NULL;
+ codec->encode_f_ilv = fs_flac_encode_f_ilv;
+ codec->encode_d = NULL;
+ codec->encode_d_ilv = NULL;
+ codec->flush = NULL;
+
+ return codec;
+}
+
+#endif
More information about the commits
mailing list