1 /*
2   SDL_mixer:  An audio mixer library based on the SDL library
3   Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
4 
5   This software is provided 'as-is', without any express or implied
6   warranty.  In no event will the authors be held liable for any damages
7   arising from the use of this software.
8 
9   Permission is granted to anyone to use this software for any purpose,
10   including commercial applications, and to alter it and redistribute it
11   freely, subject to the following restrictions:
12 
13   1. The origin of this software must not be misrepresented; you must not
14      claim that you wrote the original software. If you use this software
15      in a product, an acknowledgment in the product documentation would be
16      appreciated but is not required.
17   2. Altered source versions must be plainly marked as such, and must not be
18      misrepresented as being the original software.
19   3. This notice may not be removed or altered from any source distribution.
20 
21   Implementation of the dynamic loading functionality for libFLAC.
22 	~ Austen Dicken (admin@cvpcs.org)
23 */
24 
25 #ifdef FLAC_MUSIC
26 
27 #include "SDL_loadso.h"
28 
29 #include "dynamic_flac.h"
30 
31 flac_loader flac = {
32 	0, NULL
33 };
34 
35 #ifdef FLAC_DYNAMIC
Mix_InitFLAC()36 int Mix_InitFLAC()
37 {
38 	if ( flac.loaded == 0 ) {
39 		flac.handle = SDL_LoadObject(FLAC_DYNAMIC);
40 		if ( flac.handle == NULL ) {
41 			return -1;
42 		}
43 		flac.FLAC__stream_decoder_new =
44 			(FLAC__StreamDecoder *(*)())
45 			SDL_LoadFunction(flac.handle, "FLAC__stream_decoder_new");
46 		if ( flac.FLAC__stream_decoder_new == NULL ) {
47 			SDL_UnloadObject(flac.handle);
48 			return -1;
49 		}
50 		flac.FLAC__stream_decoder_delete =
51 			(void (*)(FLAC__StreamDecoder *))
52 			SDL_LoadFunction(flac.handle, "FLAC__stream_decoder_delete");
53 		if ( flac.FLAC__stream_decoder_delete == NULL ) {
54 			SDL_UnloadObject(flac.handle);
55 			return -1;
56 		}
57 		flac.FLAC__stream_decoder_init_stream =
58 			(FLAC__StreamDecoderInitStatus (*)(
59 						FLAC__StreamDecoder *,
60 						FLAC__StreamDecoderReadCallback,
61 						FLAC__StreamDecoderSeekCallback,
62 						FLAC__StreamDecoderTellCallback,
63 						FLAC__StreamDecoderLengthCallback,
64 						FLAC__StreamDecoderEofCallback,
65 						FLAC__StreamDecoderWriteCallback,
66 						FLAC__StreamDecoderMetadataCallback,
67 						FLAC__StreamDecoderErrorCallback,
68 						void *))
69 			SDL_LoadFunction(flac.handle, "FLAC__stream_decoder_init_stream");
70 		if ( flac.FLAC__stream_decoder_init_stream == NULL ) {
71 			SDL_UnloadObject(flac.handle);
72 			return -1;
73 		}
74 		flac.FLAC__stream_decoder_finish =
75 			(FLAC__bool (*)(FLAC__StreamDecoder *))
76 			SDL_LoadFunction(flac.handle, "FLAC__stream_decoder_finish");
77 		if ( flac.FLAC__stream_decoder_finish == NULL ) {
78 			SDL_UnloadObject(flac.handle);
79 			return -1;
80 		}
81 		flac.FLAC__stream_decoder_flush =
82 			(FLAC__bool (*)(FLAC__StreamDecoder *))
83 			SDL_LoadFunction(flac.handle, "FLAC__stream_decoder_flush");
84 		if ( flac.FLAC__stream_decoder_flush == NULL ) {
85 			SDL_UnloadObject(flac.handle);
86 			return -1;
87 		}
88 		flac.FLAC__stream_decoder_process_single =
89 			(FLAC__bool (*)(FLAC__StreamDecoder *))
90 			SDL_LoadFunction(flac.handle,
91 						"FLAC__stream_decoder_process_single");
92 		if ( flac.FLAC__stream_decoder_process_single == NULL ) {
93 			SDL_UnloadObject(flac.handle);
94 			return -1;
95 		}
96 		flac.FLAC__stream_decoder_process_until_end_of_metadata =
97 			(FLAC__bool (*)(FLAC__StreamDecoder *))
98 			SDL_LoadFunction(flac.handle,
99 						"FLAC__stream_decoder_process_until_end_of_metadata");
100 		if ( flac.FLAC__stream_decoder_process_until_end_of_metadata == NULL ) {
101 			SDL_UnloadObject(flac.handle);
102 			return -1;
103 		}
104 		flac.FLAC__stream_decoder_process_until_end_of_stream =
105 			(FLAC__bool (*)(FLAC__StreamDecoder *))
106 			SDL_LoadFunction(flac.handle,
107 						"FLAC__stream_decoder_process_until_end_of_stream");
108 		if ( flac.FLAC__stream_decoder_process_until_end_of_stream == NULL ) {
109 			SDL_UnloadObject(flac.handle);
110 			return -1;
111 		}
112 		flac.FLAC__stream_decoder_seek_absolute =
113 			(FLAC__bool (*)(FLAC__StreamDecoder *, FLAC__uint64))
114 			SDL_LoadFunction(flac.handle, "FLAC__stream_decoder_seek_absolute");
115 		if ( flac.FLAC__stream_decoder_seek_absolute == NULL ) {
116 			SDL_UnloadObject(flac.handle);
117 			return -1;
118 		}
119 		flac.FLAC__stream_decoder_get_state =
120 			(FLAC__StreamDecoderState (*)(const FLAC__StreamDecoder *decoder))
121 			SDL_LoadFunction(flac.handle, "FLAC__stream_decoder_get_state");
122 		if ( flac.FLAC__stream_decoder_get_state == NULL ) {
123 			SDL_UnloadObject(flac.handle);
124 			return -1;
125 		}
126 	}
127 	++flac.loaded;
128 
129 	return 0;
130 }
Mix_QuitFLAC()131 void Mix_QuitFLAC()
132 {
133 	if ( flac.loaded == 0 ) {
134 		return;
135 	}
136 	if ( flac.loaded == 1 ) {
137 		SDL_UnloadObject(flac.handle);
138 	}
139 	--flac.loaded;
140 }
141 #else
Mix_InitFLAC()142 int Mix_InitFLAC()
143 {
144 	if ( flac.loaded == 0 ) {
145 		flac.FLAC__stream_decoder_new = FLAC__stream_decoder_new;
146 		flac.FLAC__stream_decoder_delete = FLAC__stream_decoder_delete;
147 		flac.FLAC__stream_decoder_init_stream =
148 							FLAC__stream_decoder_init_stream;
149 		flac.FLAC__stream_decoder_finish = FLAC__stream_decoder_finish;
150 		flac.FLAC__stream_decoder_flush = FLAC__stream_decoder_flush;
151 		flac.FLAC__stream_decoder_process_single =
152 							FLAC__stream_decoder_process_single;
153 		flac.FLAC__stream_decoder_process_until_end_of_metadata =
154 							FLAC__stream_decoder_process_until_end_of_metadata;
155 		flac.FLAC__stream_decoder_process_until_end_of_stream =
156 							FLAC__stream_decoder_process_until_end_of_stream;
157 		flac.FLAC__stream_decoder_seek_absolute =
158 							FLAC__stream_decoder_seek_absolute;
159 		flac.FLAC__stream_decoder_get_state =
160 							FLAC__stream_decoder_get_state;
161 	}
162 	++flac.loaded;
163 
164 	return 0;
165 }
Mix_QuitFLAC()166 void Mix_QuitFLAC()
167 {
168 	if ( flac.loaded == 0 ) {
169 		return;
170 	}
171 	if ( flac.loaded == 1 ) {
172 	}
173 	--flac.loaded;
174 }
175 #endif /* FLAC_DYNAMIC */
176 
177 #endif /* FLAC_MUSIC */
178