Codebase list ocaml-faad / cdcd720
Merge commit 'upstream/0.2.0' Romain Beauxis 13 years ago
23 changed file(s) with 6865 addition(s) and 1202 deletion(s). Raw diff Collapse all Expand all
0 0.2.0 (12-02-2011)
1 =====
2 * Registered close method for the finalizer.
3 * Added a static copy of mp4ff..
4
05 0.1.3 (11-10-2009)
16 =====
27 * Added support for --enable-debugging configure option
+262
-426
COPYING less more
0 GNU LESSER GENERAL PUBLIC LICENSE
1 Version 2.1, February 1999
2
3 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
4 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0 GNU GENERAL PUBLIC LICENSE
1 Version 2, June 1991
2
3 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
4 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
55 Everyone is permitted to copy and distribute verbatim copies
66 of this license document, but changing it is not allowed.
77
8 [This is the first released version of the Lesser GPL. It also counts
9 as the successor of the GNU Library Public License, version 2, hence
10 the version number 2.1.]
11
128 Preamble
139
1410 The licenses for most software are designed to take away your
1511 freedom to share and change it. By contrast, the GNU General Public
16 Licenses are intended to guarantee your freedom to share and change
17 free software--to make sure the software is free for all its users.
18
19 This license, the Lesser General Public License, applies to some
20 specially designated software packages--typically libraries--of the
21 Free Software Foundation and other authors who decide to use it. You
22 can use it too, but we suggest you first think carefully about whether
23 this license or the ordinary General Public License is the better
24 strategy to use in any particular case, based on the explanations below.
25
26 When we speak of free software, we are referring to freedom of use,
27 not price. Our General Public Licenses are designed to make sure that
28 you have the freedom to distribute copies of free software (and charge
29 for this service if you wish); that you receive source code or can get
30 it if you want it; that you can change the software and use pieces of
31 it in new free programs; and that you are informed that you can do
32 these things.
12 License is intended to guarantee your freedom to share and change free
13 software--to make sure the software is free for all its users. This
14 General Public License applies to most of the Free Software
15 Foundation's software and to any other program whose authors commit to
16 using it. (Some other Free Software Foundation software is covered by
17 the GNU Library General Public License instead.) You can apply it to
18 your programs, too.
19
20 When we speak of free software, we are referring to freedom, not
21 price. Our General Public Licenses are designed to make sure that you
22 have the freedom to distribute copies of free software (and charge for
23 this service if you wish), that you receive source code or can get it
24 if you want it, that you can change the software or use pieces of it
25 in new free programs; and that you know you can do these things.
3326
3427 To protect your rights, we need to make restrictions that forbid
35 distributors to deny you these rights or to ask you to surrender these
36 rights. These restrictions translate to certain responsibilities for
37 you if you distribute copies of the library or if you modify it.
38
39 For example, if you distribute copies of the library, whether gratis
40 or for a fee, you must give the recipients all the rights that we gave
41 you. You must make sure that they, too, receive or can get the source
42 code. If you link other code with the library, you must provide
43 complete object files to the recipients, so that they can relink them
44 with the library after making changes to the library and recompiling
45 it. And you must show them these terms so they know their rights.
46
47 We protect your rights with a two-step method: (1) we copyright the
48 library, and (2) we offer you this license, which gives you legal
49 permission to copy, distribute and/or modify the library.
50
51 To protect each distributor, we want to make it very clear that
52 there is no warranty for the free library. Also, if the library is
53 modified by someone else and passed on, the recipients should know
54 that what they have is not the original version, so that the original
55 author's reputation will not be affected by problems that might be
56 introduced by others.
57
58 Finally, software patents pose a constant threat to the existence of
59 any free program. We wish to make sure that a company cannot
60 effectively restrict the users of a free program by obtaining a
61 restrictive license from a patent holder. Therefore, we insist that
62 any patent license obtained for a version of the library must be
63 consistent with the full freedom of use specified in this license.
64
65 Most GNU software, including some libraries, is covered by the
66 ordinary GNU General Public License. This license, the GNU Lesser
67 General Public License, applies to certain designated libraries, and
68 is quite different from the ordinary General Public License. We use
69 this license for certain libraries in order to permit linking those
70 libraries into non-free programs.
71
72 When a program is linked with a library, whether statically or using
73 a shared library, the combination of the two is legally speaking a
74 combined work, a derivative of the original library. The ordinary
75 General Public License therefore permits such linking only if the
76 entire combination fits its criteria of freedom. The Lesser General
77 Public License permits more lax criteria for linking other code with
78 the library.
79
80 We call this license the "Lesser" General Public License because it
81 does Less to protect the user's freedom than the ordinary General
82 Public License. It also provides other free software developers Less
83 of an advantage over competing non-free programs. These disadvantages
84 are the reason we use the ordinary General Public License for many
85 libraries. However, the Lesser license provides advantages in certain
86 special circumstances.
87
88 For example, on rare occasions, there may be a special need to
89 encourage the widest possible use of a certain library, so that it becomes
90 a de-facto standard. To achieve this, non-free programs must be
91 allowed to use the library. A more frequent case is that a free
92 library does the same job as widely used non-free libraries. In this
93 case, there is little to gain by limiting the free library to free
94 software only, so we use the Lesser General Public License.
95
96 In other cases, permission to use a particular library in non-free
97 programs enables a greater number of people to use a large body of
98 free software. For example, permission to use the GNU C Library in
99 non-free programs enables many more people to use the whole GNU
100 operating system, as well as its variant, the GNU/Linux operating
101 system.
102
103 Although the Lesser General Public License is Less protective of the
104 users' freedom, it does ensure that the user of a program that is
105 linked with the Library has the freedom and the wherewithal to run
106 that program using a modified version of the Library.
28 anyone to deny you these rights or to ask you to surrender the rights.
29 These restrictions translate to certain responsibilities for you if you
30 distribute copies of the software, or if you modify it.
31
32 For example, if you distribute copies of such a program, whether
33 gratis or for a fee, you must give the recipients all the rights that
34 you have. You must make sure that they, too, receive or can get the
35 source code. And you must show them these terms so they know their
36 rights.
37
38 We protect your rights with two steps: (1) copyright the software, and
39 (2) offer you this license which gives you legal permission to copy,
40 distribute and/or modify the software.
41
42 Also, for each author's protection and ours, we want to make certain
43 that everyone understands that there is no warranty for this free
44 software. If the software is modified by someone else and passed on, we
45 want its recipients to know that what they have is not the original, so
46 that any problems introduced by others will not reflect on the original
47 authors' reputations.
48
49 Finally, any free program is threatened constantly by software
50 patents. We wish to avoid the danger that redistributors of a free
51 program will individually obtain patent licenses, in effect making the
52 program proprietary. To prevent this, we have made it clear that any
53 patent must be licensed for everyone's free use or not licensed at all.
10754
10855 The precise terms and conditions for copying, distribution and
109 modification follow. Pay close attention to the difference between a
110 "work based on the library" and a "work that uses the library". The
111 former contains code derived from the library, whereas the latter must
112 be combined with the library in order to run.
113
114 GNU LESSER GENERAL PUBLIC LICENSE
56 modification follow.
57
58 GNU GENERAL PUBLIC LICENSE
11559 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
11660
117 0. This License Agreement applies to any software library or other
118 program which contains a notice placed by the copyright holder or
119 other authorized party saying it may be distributed under the terms of
120 this Lesser General Public License (also called "this License").
121 Each licensee is addressed as "you".
122
123 A "library" means a collection of software functions and/or data
124 prepared so as to be conveniently linked with application programs
125 (which use some of those functions and data) to form executables.
126
127 The "Library", below, refers to any such software library or work
128 which has been distributed under these terms. A "work based on the
129 Library" means either the Library or any derivative work under
130 copyright law: that is to say, a work containing the Library or a
131 portion of it, either verbatim or with modifications and/or translated
132 straightforwardly into another language. (Hereinafter, translation is
133 included without limitation in the term "modification".)
134
135 "Source code" for a work means the preferred form of the work for
136 making modifications to it. For a library, complete source code means
137 all the source code for all modules it contains, plus any associated
138 interface definition files, plus the scripts used to control compilation
139 and installation of the library.
140
141 Activities other than copying, distribution and modification are not
61 0. This License applies to any program or other work which contains
62 a notice placed by the copyright holder saying it may be distributed
63 under the terms of this General Public License. The "Program", below,
64 refers to any such program or work, and a "work based on the Program"
65 means either the Program or any derivative work under copyright law:
66 that is to say, a work containing the Program or a portion of it,
67 either verbatim or with modifications and/or translated into another
68 language. (Hereinafter, translation is included without limitation in
69 the term "modification".) Each licensee is addressed as "you".
70
71 Activities other than copying, distribution and modification are not
14272 covered by this License; they are outside its scope. The act of
143 running a program using the Library is not restricted, and output from
144 such a program is covered only if its contents constitute a work based
145 on the Library (independent of the use of the Library in a tool for
146 writing it). Whether that is true depends on what the Library does
147 and what the program that uses the Library does.
148
149 1. You may copy and distribute verbatim copies of the Library's
150 complete source code as you receive it, in any medium, provided that
151 you conspicuously and appropriately publish on each copy an
152 appropriate copyright notice and disclaimer of warranty; keep intact
153 all the notices that refer to this License and to the absence of any
154 warranty; and distribute a copy of this License along with the
155 Library.
156
157 You may charge a fee for the physical act of transferring a copy,
158 and you may at your option offer warranty protection in exchange for a
159 fee.
160
161 2. You may modify your copy or copies of the Library or any portion
162 of it, thus forming a work based on the Library, and copy and
73 running the Program is not restricted, and the output from the Program
74 is covered only if its contents constitute a work based on the
75 Program (independent of having been made by running the Program).
76 Whether that is true depends on what the Program does.
77
78 1. You may copy and distribute verbatim copies of the Program's
79 source code as you receive it, in any medium, provided that you
80 conspicuously and appropriately publish on each copy an appropriate
81 copyright notice and disclaimer of warranty; keep intact all the
82 notices that refer to this License and to the absence of any warranty;
83 and give any other recipients of the Program a copy of this License
84 along with the Program.
85
86 You may charge a fee for the physical act of transferring a copy, and
87 you may at your option offer warranty protection in exchange for a fee.
88
89 2. You may modify your copy or copies of the Program or any portion
90 of it, thus forming a work based on the Program, and copy and
16391 distribute such modifications or work under the terms of Section 1
16492 above, provided that you also meet all of these conditions:
16593
166 a) The modified work must itself be a software library.
167
168 b) You must cause the files modified to carry prominent notices
94 a) You must cause the modified files to carry prominent notices
16995 stating that you changed the files and the date of any change.
17096
171 c) You must cause the whole of the work to be licensed at no
172 charge to all third parties under the terms of this License.
173
174 d) If a facility in the modified Library refers to a function or a
175 table of data to be supplied by an application program that uses
176 the facility, other than as an argument passed when the facility
177 is invoked, then you must make a good faith effort to ensure that,
178 in the event an application does not supply such function or
179 table, the facility still operates, and performs whatever part of
180 its purpose remains meaningful.
181
182 (For example, a function in a library to compute square roots has
183 a purpose that is entirely well-defined independent of the
184 application. Therefore, Subsection 2d requires that any
185 application-supplied function or table used by this function must
186 be optional: if the application does not supply it, the square
187 root function must still compute square roots.)
188
97 b) You must cause any work that you distribute or publish, that in
98 whole or in part contains or is derived from the Program or any
99 part thereof, to be licensed as a whole at no charge to all third
100 parties under the terms of this License.
101
102 c) If the modified program normally reads commands interactively
103 when run, you must cause it, when started running for such
104 interactive use in the most ordinary way, to print or display an
105 announcement including an appropriate copyright notice and a
106 notice that there is no warranty (or else, saying that you provide
107 a warranty) and that users may redistribute the program under
108 these conditions, and telling the user how to view a copy of this
109 License. (Exception: if the Program itself is interactive but
110 does not normally print such an announcement, your work based on
111 the Program is not required to print an announcement.)
112
189113 These requirements apply to the modified work as a whole. If
190 identifiable sections of that work are not derived from the Library,
114 identifiable sections of that work are not derived from the Program,
191115 and can be reasonably considered independent and separate works in
192116 themselves, then this License, and its terms, do not apply to those
193117 sections when you distribute them as separate works. But when you
194118 distribute the same sections as part of a whole which is a work based
195 on the Library, the distribution of the whole must be on the terms of
119 on the Program, the distribution of the whole must be on the terms of
196120 this License, whose permissions for other licensees extend to the
197 entire whole, and thus to each and every part regardless of who wrote
198 it.
121 entire whole, and thus to each and every part regardless of who wrote it.
199122
200123 Thus, it is not the intent of this section to claim rights or contest
201124 your rights to work written entirely by you; rather, the intent is to
202125 exercise the right to control the distribution of derivative or
203 collective works based on the Library.
204
205 In addition, mere aggregation of another work not based on the Library
206 with the Library (or with a work based on the Library) on a volume of
126 collective works based on the Program.
127
128 In addition, mere aggregation of another work not based on the Program
129 with the Program (or with a work based on the Program) on a volume of
207130 a storage or distribution medium does not bring the other work under
208131 the scope of this License.
209132
210 3. You may opt to apply the terms of the ordinary GNU General Public
211 License instead of this License to a given copy of the Library. To do
212 this, you must alter all the notices that refer to this License, so
213 that they refer to the ordinary GNU General Public License, version 2,
214 instead of to this License. (If a newer version than version 2 of the
215 ordinary GNU General Public License has appeared, then you can specify
216 that version instead if you wish.) Do not make any other change in
217 these notices.
218
219 Once this change is made in a given copy, it is irreversible for
220 that copy, so the ordinary GNU General Public License applies to all
221 subsequent copies and derivative works made from that copy.
222
223 This option is useful when you wish to copy part of the code of
224 the Library into a program that is not a library.
225
226 4. You may copy and distribute the Library (or a portion or
227 derivative of it, under Section 2) in object code or executable form
228 under the terms of Sections 1 and 2 above provided that you accompany
229 it with the complete corresponding machine-readable source code, which
230 must be distributed under the terms of Sections 1 and 2 above on a
231 medium customarily used for software interchange.
232
233 If distribution of object code is made by offering access to copy
234 from a designated place, then offering equivalent access to copy the
235 source code from the same place satisfies the requirement to
236 distribute the source code, even though third parties are not
133 3. You may copy and distribute the Program (or a work based on it,
134 under Section 2) in object code or executable form under the terms of
135 Sections 1 and 2 above provided that you also do one of the following:
136
137 a) Accompany it with the complete corresponding machine-readable
138 source code, which must be distributed under the terms of Sections
139 1 and 2 above on a medium customarily used for software interchange; or,
140
141 b) Accompany it with a written offer, valid for at least three
142 years, to give any third party, for a charge no more than your
143 cost of physically performing source distribution, a complete
144 machine-readable copy of the corresponding source code, to be
145 distributed under the terms of Sections 1 and 2 above on a medium
146 customarily used for software interchange; or,
147
148 c) Accompany it with the information you received as to the offer
149 to distribute corresponding source code. (This alternative is
150 allowed only for noncommercial distribution and only if you
151 received the program in object code or executable form with such
152 an offer, in accord with Subsection b above.)
153
154 The source code for a work means the preferred form of the work for
155 making modifications to it. For an executable work, complete source
156 code means all the source code for all modules it contains, plus any
157 associated interface definition files, plus the scripts used to
158 control compilation and installation of the executable. However, as a
159 special exception, the source code distributed need not include
160 anything that is normally distributed (in either source or binary
161 form) with the major components (compiler, kernel, and so on) of the
162 operating system on which the executable runs, unless that component
163 itself accompanies the executable.
164
165 If distribution of executable or object code is made by offering
166 access to copy from a designated place, then offering equivalent
167 access to copy the source code from the same place counts as
168 distribution of the source code, even though third parties are not
237169 compelled to copy the source along with the object code.
238
239 5. A program that contains no derivative of any portion of the
240 Library, but is designed to work with the Library by being compiled or
241 linked with it, is called a "work that uses the Library". Such a
242 work, in isolation, is not a derivative work of the Library, and
243 therefore falls outside the scope of this License.
244
245 However, linking a "work that uses the Library" with the Library
246 creates an executable that is a derivative of the Library (because it
247 contains portions of the Library), rather than a "work that uses the
248 library". The executable is therefore covered by this License.
249 Section 6 states terms for distribution of such executables.
250
251 When a "work that uses the Library" uses material from a header file
252 that is part of the Library, the object code for the work may be a
253 derivative work of the Library even though the source code is not.
254 Whether this is true is especially significant if the work can be
255 linked without the Library, or if the work is itself a library. The
256 threshold for this to be true is not precisely defined by law.
257
258 If such an object file uses only numerical parameters, data
259 structure layouts and accessors, and small macros and small inline
260 functions (ten lines or less in length), then the use of the object
261 file is unrestricted, regardless of whether it is legally a derivative
262 work. (Executables containing this object code plus portions of the
263 Library will still fall under Section 6.)
264
265 Otherwise, if the work is a derivative of the Library, you may
266 distribute the object code for the work under the terms of Section 6.
267 Any executables containing that work also fall under Section 6,
268 whether or not they are linked directly with the Library itself.
269
270 6. As an exception to the Sections above, you may also combine or
271 link a "work that uses the Library" with the Library to produce a
272 work containing portions of the Library, and distribute that work
273 under terms of your choice, provided that the terms permit
274 modification of the work for the customer's own use and reverse
275 engineering for debugging such modifications.
276
277 You must give prominent notice with each copy of the work that the
278 Library is used in it and that the Library and its use are covered by
279 this License. You must supply a copy of this License. If the work
280 during execution displays copyright notices, you must include the
281 copyright notice for the Library among them, as well as a reference
282 directing the user to the copy of this License. Also, you must do one
283 of these things:
284
285 a) Accompany the work with the complete corresponding
286 machine-readable source code for the Library including whatever
287 changes were used in the work (which must be distributed under
288 Sections 1 and 2 above); and, if the work is an executable linked
289 with the Library, with the complete machine-readable "work that
290 uses the Library", as object code and/or source code, so that the
291 user can modify the Library and then relink to produce a modified
292 executable containing the modified Library. (It is understood
293 that the user who changes the contents of definitions files in the
294 Library will not necessarily be able to recompile the application
295 to use the modified definitions.)
296
297 b) Use a suitable shared library mechanism for linking with the
298 Library. A suitable mechanism is one that (1) uses at run time a
299 copy of the library already present on the user's computer system,
300 rather than copying library functions into the executable, and (2)
301 will operate properly with a modified version of the library, if
302 the user installs one, as long as the modified version is
303 interface-compatible with the version that the work was made with.
304
305 c) Accompany the work with a written offer, valid for at
306 least three years, to give the same user the materials
307 specified in Subsection 6a, above, for a charge no more
308 than the cost of performing this distribution.
309
310 d) If distribution of the work is made by offering access to copy
311 from a designated place, offer equivalent access to copy the above
312 specified materials from the same place.
313
314 e) Verify that the user has already received a copy of these
315 materials or that you have already sent this user a copy.
316
317 For an executable, the required form of the "work that uses the
318 Library" must include any data and utility programs needed for
319 reproducing the executable from it. However, as a special exception,
320 the materials to be distributed need not include anything that is
321 normally distributed (in either source or binary form) with the major
322 components (compiler, kernel, and so on) of the operating system on
323 which the executable runs, unless that component itself accompanies
324 the executable.
325
326 It may happen that this requirement contradicts the license
327 restrictions of other proprietary libraries that do not normally
328 accompany the operating system. Such a contradiction means you cannot
329 use both them and the Library together in an executable that you
330 distribute.
331
332 7. You may place library facilities that are a work based on the
333 Library side-by-side in a single library together with other library
334 facilities not covered by this License, and distribute such a combined
335 library, provided that the separate distribution of the work based on
336 the Library and of the other library facilities is otherwise
337 permitted, and provided that you do these two things:
338
339 a) Accompany the combined library with a copy of the same work
340 based on the Library, uncombined with any other library
341 facilities. This must be distributed under the terms of the
342 Sections above.
343
344 b) Give prominent notice with the combined library of the fact
345 that part of it is a work based on the Library, and explaining
346 where to find the accompanying uncombined form of the same work.
347
348 8. You may not copy, modify, sublicense, link with, or distribute
349 the Library except as expressly provided under this License. Any
350 attempt otherwise to copy, modify, sublicense, link with, or
351 distribute the Library is void, and will automatically terminate your
352 rights under this License. However, parties who have received copies,
353 or rights, from you under this License will not have their licenses
354 terminated so long as such parties remain in full compliance.
355
356 9. You are not required to accept this License, since you have not
170
171 4. You may not copy, modify, sublicense, or distribute the Program
172 except as expressly provided under this License. Any attempt
173 otherwise to copy, modify, sublicense or distribute the Program is
174 void, and will automatically terminate your rights under this License.
175 However, parties who have received copies, or rights, from you under
176 this License will not have their licenses terminated so long as such
177 parties remain in full compliance.
178
179 5. You are not required to accept this License, since you have not
357180 signed it. However, nothing else grants you permission to modify or
358 distribute the Library or its derivative works. These actions are
181 distribute the Program or its derivative works. These actions are
359182 prohibited by law if you do not accept this License. Therefore, by
360 modifying or distributing the Library (or any work based on the
361 Library), you indicate your acceptance of this License to do so, and
183 modifying or distributing the Program (or any work based on the
184 Program), you indicate your acceptance of this License to do so, and
362185 all its terms and conditions for copying, distributing or modifying
363 the Library or works based on it.
364
365 10. Each time you redistribute the Library (or any work based on the
366 Library), the recipient automatically receives a license from the
367 original licensor to copy, distribute, link with or modify the Library
368 subject to these terms and conditions. You may not impose any further
186 the Program or works based on it.
187
188 6. Each time you redistribute the Program (or any work based on the
189 Program), the recipient automatically receives a license from the
190 original licensor to copy, distribute or modify the Program subject to
191 these terms and conditions. You may not impose any further
369192 restrictions on the recipients' exercise of the rights granted herein.
370 You are not responsible for enforcing compliance by third parties with
193 You are not responsible for enforcing compliance by third parties to
371194 this License.
372
373 11. If, as a consequence of a court judgment or allegation of patent
195
196 7. If, as a consequence of a court judgment or allegation of patent
374197 infringement or for any other reason (not limited to patent issues),
375198 conditions are imposed on you (whether by court order, agreement or
376199 otherwise) that contradict the conditions of this License, they do not
377200 excuse you from the conditions of this License. If you cannot
378201 distribute so as to satisfy simultaneously your obligations under this
379202 License and any other pertinent obligations, then as a consequence you
380 may not distribute the Library at all. For example, if a patent
381 license would not permit royalty-free redistribution of the Library by
203 may not distribute the Program at all. For example, if a patent
204 license would not permit royalty-free redistribution of the Program by
382205 all those who receive copies directly or indirectly through you, then
383206 the only way you could satisfy both it and this License would be to
384 refrain entirely from distribution of the Library.
385
386 If any portion of this section is held invalid or unenforceable under any
387 particular circumstance, the balance of the section is intended to apply,
388 and the section as a whole is intended to apply in other circumstances.
207 refrain entirely from distribution of the Program.
208
209 If any portion of this section is held invalid or unenforceable under
210 any particular circumstance, the balance of the section is intended to
211 apply and the section as a whole is intended to apply in other
212 circumstances.
389213
390214 It is not the purpose of this section to induce you to infringe any
391215 patents or other property right claims or to contest validity of any
392216 such claims; this section has the sole purpose of protecting the
393 integrity of the free software distribution system which is
217 integrity of the free software distribution system, which is
394218 implemented by public license practices. Many people have made
395219 generous contributions to the wide range of software distributed
396220 through that system in reliance on consistent application of that
400224
401225 This section is intended to make thoroughly clear what is believed to
402226 be a consequence of the rest of this License.
403
404 12. If the distribution and/or use of the Library is restricted in
227
228 8. If the distribution and/or use of the Program is restricted in
405229 certain countries either by patents or by copyrighted interfaces, the
406 original copyright holder who places the Library under this License may add
407 an explicit geographical distribution limitation excluding those countries,
408 so that distribution is permitted only in or among countries not thus
409 excluded. In such case, this License incorporates the limitation as if
410 written in the body of this License.
411
412 13. The Free Software Foundation may publish revised and/or new
413 versions of the Lesser General Public License from time to time.
414 Such new versions will be similar in spirit to the present version,
415 but may differ in detail to address new problems or concerns.
416
417 Each version is given a distinguishing version number. If the Library
418 specifies a version number of this License which applies to it and
419 "any later version", you have the option of following the terms and
420 conditions either of that version or of any later version published by
421 the Free Software Foundation. If the Library does not specify a
422 license version number, you may choose any version ever published by
423 the Free Software Foundation.
424
425 14. If you wish to incorporate parts of the Library into other free
426 programs whose distribution conditions are incompatible with these,
427 write to the author to ask for permission. For software which is
428 copyrighted by the Free Software Foundation, write to the Free
429 Software Foundation; we sometimes make exceptions for this. Our
430 decision will be guided by the two goals of preserving the free status
431 of all derivatives of our free software and of promoting the sharing
432 and reuse of software generally.
230 original copyright holder who places the Program under this License
231 may add an explicit geographical distribution limitation excluding
232 those countries, so that distribution is permitted only in or among
233 countries not thus excluded. In such case, this License incorporates
234 the limitation as if written in the body of this License.
235
236 9. The Free Software Foundation may publish revised and/or new versions
237 of the General Public License from time to time. Such new versions will
238 be similar in spirit to the present version, but may differ in detail to
239 address new problems or concerns.
240
241 Each version is given a distinguishing version number. If the Program
242 specifies a version number of this License which applies to it and "any
243 later version", you have the option of following the terms and conditions
244 either of that version or of any later version published by the Free
245 Software Foundation. If the Program does not specify a version number of
246 this License, you may choose any version ever published by the Free Software
247 Foundation.
248
249 10. If you wish to incorporate parts of the Program into other free
250 programs whose distribution conditions are different, write to the author
251 to ask for permission. For software which is copyrighted by the Free
252 Software Foundation, write to the Free Software Foundation; we sometimes
253 make exceptions for this. Our decision will be guided by the two goals
254 of preserving the free status of all derivatives of our free software and
255 of promoting the sharing and reuse of software generally.
433256
434257 NO WARRANTY
435258
436 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
437 WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
438 EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
439 OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
440 KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
441 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
442 PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
443 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
444 THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
445
446 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
447 WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
448 AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
449 FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
450 CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
451 LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
452 RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
453 FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
454 SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
455 DAMAGES.
259 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
260 FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
261 OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
262 PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
263 OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
264 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
265 TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
266 PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
267 REPAIR OR CORRECTION.
268
269 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
270 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
271 REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
272 INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
273 OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
274 TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
275 YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
276 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
277 POSSIBILITY OF SUCH DAMAGES.
456278
457279 END OF TERMS AND CONDITIONS
458280
459 How to Apply These Terms to Your New Libraries
460
461 If you develop a new library, and you want it to be of the greatest
462 possible use to the public, we recommend making it free software that
463 everyone can redistribute and change. You can do so by permitting
464 redistribution under these terms (or, alternatively, under the terms of the
465 ordinary General Public License).
466
467 To apply these terms, attach the following notices to the library. It is
468 safest to attach them to the start of each source file to most effectively
469 convey the exclusion of warranty; and each file should have at least the
470 "copyright" line and a pointer to where the full notice is found.
471
472 <one line to give the library's name and a brief idea of what it does.>
281 How to Apply These Terms to Your New Programs
282
283 If you develop a new program, and you want it to be of the greatest
284 possible use to the public, the best way to achieve this is to make it
285 free software which everyone can redistribute and change under these terms.
286
287 To do so, attach the following notices to the program. It is safest
288 to attach them to the start of each source file to most effectively
289 convey the exclusion of warranty; and each file should have at least
290 the "copyright" line and a pointer to where the full notice is found.
291
292 <one line to give the program's name and a brief idea of what it does.>
473293 Copyright (C) <year> <name of author>
474294
475 This library is free software; you can redistribute it and/or
476 modify it under the terms of the GNU Lesser General Public
477 License as published by the Free Software Foundation; either
478 version 2.1 of the License, or (at your option) any later version.
479
480 This library is distributed in the hope that it will be useful,
295 This program is free software; you can redistribute it and/or modify
296 it under the terms of the GNU General Public License as published by
297 the Free Software Foundation; either version 2 of the License, or
298 (at your option) any later version.
299
300 This program is distributed in the hope that it will be useful,
481301 but WITHOUT ANY WARRANTY; without even the implied warranty of
482 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
483 Lesser General Public License for more details.
484
485 You should have received a copy of the GNU Lesser General Public
486 License along with this library; if not, write to the Free Software
302 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
303 GNU General Public License for more details.
304
305 You should have received a copy of the GNU General Public License
306 along with this program; if not, write to the Free Software
487307 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
488308
309
489310 Also add information on how to contact you by electronic and paper mail.
490311
312 If the program is interactive, make it output a short notice like this
313 when it starts in an interactive mode:
314
315 Gnomovision version 69, Copyright (C) year name of author
316 Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 This is free software, and you are welcome to redistribute it
318 under certain conditions; type `show c' for details.
319
320 The hypothetical commands `show w' and `show c' should show the appropriate
321 parts of the General Public License. Of course, the commands you use may
322 be called something other than `show w' and `show c'; they could even be
323 mouse-clicks or menu items--whatever suits your program.
324
491325 You should also get your employer (if you work as a programmer) or your
492 school, if any, to sign a "copyright disclaimer" for the library, if
326 school, if any, to sign a "copyright disclaimer" for the program, if
493327 necessary. Here is a sample; alter the names:
494328
495 Yoyodyne, Inc., hereby disclaims all copyright interest in the
496 library `Frob' (a library for tweaking knobs) written by James Random Hacker.
497
498 <signature of Ty Coon>, 1 April 1990
329 Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 `Gnomovision' (which makes passes at compilers) written by James Hacker.
331
332 <signature of Ty Coon>, 1 April 1989
499333 Ty Coon, President of Vice
500334
501 That's all there is to it!
502
503
335 This General Public License does not permit incorporating your program into
336 proprietary programs. If your program is a subroutine library, you may
337 consider it more useful to permit linking proprietary applications with the
338 library. If this is what you want to do, use the GNU Library General
339 Public License instead of this License.
11
22 PROGNAME := ocaml-faad
33 DISTFILES := CHANGES COPYING Makefile.in README \
4 bootstrap configure configure.ac \
4 bootstrap configure configure.ac config.h.in \
55 src/*.ml src/*.mli src/*.c src/Makefile.in src/META.in \
6 src/OCamlMakefile
6 src/OCamlMakefile src/*.h
77 VERSION = @VERSION@
88
99 all clean install uninstall:
00 #!/bin/sh
11
22 aclocal
3 # Doing this only once sometimes yield an error message (AC_MSG_ERROR
4 # undefined).. I give up understanding that.
3 autoheader
54 autoconf
6 autoconf
0 /* config.h.in. Generated from configure.ac by autoheader. */
1
2 /* Define to 1 if you have the <errno.h> header file. */
3 #undef HAVE_ERRNO_H
4
5 /* Define to 1 if you have the <inttypes.h> header file. */
6 #undef HAVE_INTTYPES_H
7
8 /* Define to 1 if you have the <memory.h> header file. */
9 #undef HAVE_MEMORY_H
10
11 /* Define to 1 if you have the <neaacdec.h> header file. */
12 #undef HAVE_NEAACDEC_H
13
14 /* Define to 1 if you have the <stdint.h> header file. */
15 #undef HAVE_STDINT_H
16
17 /* Define to 1 if you have the <stdlib.h> header file. */
18 #undef HAVE_STDLIB_H
19
20 /* Define to 1 if you have the <strings.h> header file. */
21 #undef HAVE_STRINGS_H
22
23 /* Define to 1 if you have the <string.h> header file. */
24 #undef HAVE_STRING_H
25
26 /* Define to 1 if you have the <sys/stat.h> header file. */
27 #undef HAVE_SYS_STAT_H
28
29 /* Define to 1 if you have the <sys/types.h> header file. */
30 #undef HAVE_SYS_TYPES_H
31
32 /* Define to 1 if you have the <unistd.h> header file. */
33 #undef HAVE_UNISTD_H
34
35 /* Define to the address where bug reports for this package should be sent. */
36 #undef PACKAGE_BUGREPORT
37
38 /* Define to the full name of this package. */
39 #undef PACKAGE_NAME
40
41 /* Define to the full name and version of this package. */
42 #undef PACKAGE_STRING
43
44 /* Define to the one symbol short name of this package. */
45 #undef PACKAGE_TARNAME
46
47 /* Define to the home page for this package. */
48 #undef PACKAGE_URL
49
50 /* Define to the version of this package. */
51 #undef PACKAGE_VERSION
52
53 /* Define to 1 if you have the ANSI C header files. */
54 #undef STDC_HEADERS
+1375
-655
configure less more
00 #! /bin/sh
11 # Guess values for system-dependent variables and create Makefiles.
2 # Generated by GNU Autoconf 2.64 for ocaml-faad 0.1.3.
2 # Generated by GNU Autoconf 2.67 for ocaml-faad 0.2.0.
33 #
44 # Report bugs to <savonet-users@lists.sourceforge.net>.
55 #
6 #
67 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
7 # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
8 # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
89 # Foundation, Inc.
10 #
911 #
1012 # This configure script is free software; the Free Software Foundation
1113 # gives unlimited permission to copy, distribute and modify it.
316318 test -d "$as_dir" && break
317319 done
318320 test -z "$as_dirs" || eval "mkdir $as_dirs"
319 } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
321 } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
320322
321323
322324 } # as_fn_mkdir_p
356358 fi # as_fn_arith
357359
358360
359 # as_fn_error ERROR [LINENO LOG_FD]
360 # ---------------------------------
361 # as_fn_error STATUS ERROR [LINENO LOG_FD]
362 # ----------------------------------------
361363 # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
362364 # provided, also output the error to LOG_FD, referencing LINENO. Then exit the
363 # script with status $?, using 1 if that was 0.
365 # script with STATUS, using 1 if that was 0.
364366 as_fn_error ()
365367 {
366 as_status=$?; test $as_status -eq 0 && as_status=1
367 if test "$3"; then
368 as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
369 $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
370 fi
371 $as_echo "$as_me: error: $1" >&2
368 as_status=$1; test $as_status -eq 0 && as_status=1
369 if test "$4"; then
370 as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
371 $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
372 fi
373 $as_echo "$as_me: error: $2" >&2
372374 as_fn_exit $as_status
373375 } # as_fn_error
374376
526528 as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
527529
528530
529 exec 7<&0 </dev/null 6>&1
531 test -n "$DJDIR" || exec 7<&0 </dev/null
532 exec 6>&1
530533
531534 # Name of the host.
532 # hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
535 # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
533536 # so uname gets run too.
534537 ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
535538
548551 # Identity of this package.
549552 PACKAGE_NAME='ocaml-faad'
550553 PACKAGE_TARNAME='ocaml-faad'
551 PACKAGE_VERSION='0.1.3'
552 PACKAGE_STRING='ocaml-faad 0.1.3'
554 PACKAGE_VERSION='0.2.0'
555 PACKAGE_STRING='ocaml-faad 0.2.0'
553556 PACKAGE_BUGREPORT='savonet-users@lists.sourceforge.net'
554557 PACKAGE_URL=''
555558
601604 OCAMLBEST
602605 OCAMLFLAGS
603606 VERSION
607 OCAMLFIND
608 OCAMLDOC
609 OCAMLDEP
610 OCAMLOPTDOTOPT
611 OCAMLCDOTOPT
612 OCAMLOPT
613 OCAMLC
604614 EGREP
605615 GREP
606616 CPP
611621 LDFLAGS
612622 CFLAGS
613623 CC
614 OCAMLFIND
615 OCAMLDOC
616 OCAMLDEP
617 OCAMLOPTDOTOPT
618 OCAMLCDOTOPT
619 OCAMLOPT
620 OCAMLC
621624 target_alias
622625 host_alias
623626 build_alias
733736 fi
734737
735738 case $ac_option in
736 *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
737 *) ac_optarg=yes ;;
739 *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
740 *=) ac_optarg= ;;
741 *) ac_optarg=yes ;;
738742 esac
739743
740744 # Accept the important Cygnus configure options, so we can diagnose typos.
779783 ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
780784 # Reject names that are not valid shell variable names.
781785 expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
782 as_fn_error "invalid feature name: $ac_useropt"
786 as_fn_error $? "invalid feature name: $ac_useropt"
783787 ac_useropt_orig=$ac_useropt
784788 ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
785789 case $ac_user_opts in
805809 ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
806810 # Reject names that are not valid shell variable names.
807811 expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
808 as_fn_error "invalid feature name: $ac_useropt"
812 as_fn_error $? "invalid feature name: $ac_useropt"
809813 ac_useropt_orig=$ac_useropt
810814 ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
811815 case $ac_user_opts in
10091013 ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
10101014 # Reject names that are not valid shell variable names.
10111015 expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
1012 as_fn_error "invalid package name: $ac_useropt"
1016 as_fn_error $? "invalid package name: $ac_useropt"
10131017 ac_useropt_orig=$ac_useropt
10141018 ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
10151019 case $ac_user_opts in
10251029 ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
10261030 # Reject names that are not valid shell variable names.
10271031 expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
1028 as_fn_error "invalid package name: $ac_useropt"
1032 as_fn_error $? "invalid package name: $ac_useropt"
10291033 ac_useropt_orig=$ac_useropt
10301034 ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
10311035 case $ac_user_opts in
10551059 | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
10561060 x_libraries=$ac_optarg ;;
10571061
1058 -*) as_fn_error "unrecognized option: \`$ac_option'
1059 Try \`$0 --help' for more information."
1062 -*) as_fn_error $? "unrecognized option: \`$ac_option'
1063 Try \`$0 --help' for more information"
10601064 ;;
10611065
10621066 *=*)
10641068 # Reject names that are not valid shell variable names.
10651069 case $ac_envvar in #(
10661070 '' | [0-9]* | *[!_$as_cr_alnum]* )
1067 as_fn_error "invalid variable name: \`$ac_envvar'" ;;
1071 as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
10681072 esac
10691073 eval $ac_envvar=\$ac_optarg
10701074 export $ac_envvar ;;
10821086
10831087 if test -n "$ac_prev"; then
10841088 ac_option=--`echo $ac_prev | sed 's/_/-/g'`
1085 as_fn_error "missing argument to $ac_option"
1089 as_fn_error $? "missing argument to $ac_option"
10861090 fi
10871091
10881092 if test -n "$ac_unrecognized_opts"; then
10891093 case $enable_option_checking in
10901094 no) ;;
1091 fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
1095 fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
10921096 *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
10931097 esac
10941098 fi
11111115 [\\/$]* | ?:[\\/]* ) continue;;
11121116 NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
11131117 esac
1114 as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
1118 as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
11151119 done
11161120
11171121 # There might be people who depend on the old broken behavior: `$host'
11251129 if test "x$host_alias" != x; then
11261130 if test "x$build_alias" = x; then
11271131 cross_compiling=maybe
1128 $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
1129 If a cross compiler is detected then cross compile mode will be used." >&2
1132 $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
1133 If a cross compiler is detected then cross compile mode will be used" >&2
11301134 elif test "x$build_alias" != "x$host_alias"; then
11311135 cross_compiling=yes
11321136 fi
11411145 ac_pwd=`pwd` && test -n "$ac_pwd" &&
11421146 ac_ls_di=`ls -di .` &&
11431147 ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
1144 as_fn_error "working directory cannot be determined"
1148 as_fn_error $? "working directory cannot be determined"
11451149 test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
1146 as_fn_error "pwd does not report name of working directory"
1150 as_fn_error $? "pwd does not report name of working directory"
11471151
11481152
11491153 # Find the source files, if location was not specified.
11821186 fi
11831187 if test ! -r "$srcdir/$ac_unique_file"; then
11841188 test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
1185 as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
1189 as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
11861190 fi
11871191 ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
11881192 ac_abs_confdir=`(
1189 cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
1193 cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
11901194 pwd)`
11911195 # When building in place, set srcdir=.
11921196 if test "$ac_abs_confdir" = "$ac_pwd"; then
12121216 # Omit some internal or obsolete options to make the list less imposing.
12131217 # This message is too long to be a string in the A/UX 3.1 sh.
12141218 cat <<_ACEOF
1215 \`configure' configures ocaml-faad 0.1.3 to adapt to many kinds of systems.
1219 \`configure' configures ocaml-faad 0.2.0 to adapt to many kinds of systems.
12161220
12171221 Usage: $0 [OPTION]... [VAR=VALUE]...
12181222
12261230 --help=short display options specific to this package
12271231 --help=recursive display the short help of all the included packages
12281232 -V, --version display version information and exit
1229 -q, --quiet, --silent do not print \`checking...' messages
1233 -q, --quiet, --silent do not print \`checking ...' messages
12301234 --cache-file=FILE cache test results in FILE [disabled]
12311235 -C, --config-cache alias for \`--cache-file=config.cache'
12321236 -n, --no-create do not create output files
12731277
12741278 if test -n "$ac_init_help"; then
12751279 case $ac_init_help in
1276 short | recursive ) echo "Configuration of ocaml-faad 0.1.3:";;
1280 short | recursive ) echo "Configuration of ocaml-faad 0.2.0:";;
12771281 esac
12781282 cat <<\_ACEOF
12791283
12921296 LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
12931297 nonstandard directory <lib dir>
12941298 LIBS libraries to pass to the linker, e.g. -l<library>
1295 CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
1299 CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
12961300 you have headers in a nonstandard directory <include dir>
12971301 CPP C preprocessor
12981302
13621366 test -n "$ac_init_help" && exit $ac_status
13631367 if $ac_init_version; then
13641368 cat <<\_ACEOF
1365 ocaml-faad configure 0.1.3
1366 generated by GNU Autoconf 2.64
1367
1368 Copyright (C) 2009 Free Software Foundation, Inc.
1369 ocaml-faad configure 0.2.0
1370 generated by GNU Autoconf 2.67
1371
1372 Copyright (C) 2010 Free Software Foundation, Inc.
13691373 This configure script is free software; the Free Software Foundation
13701374 gives unlimited permission to copy, distribute and modify it.
13711375 _ACEOF
14101414 ac_retval=1
14111415 fi
14121416 eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
1413 return $ac_retval
1417 as_fn_set_status $ac_retval
14141418
14151419 } # ac_fn_c_try_compile
14161420
14351439 mv -f conftest.er1 conftest.err
14361440 fi
14371441 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
1438 test $ac_status = 0; } >/dev/null && {
1442 test $ac_status = 0; } > conftest.i && {
14391443 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
14401444 test ! -s conftest.err
14411445 }; then :
14471451 ac_retval=1
14481452 fi
14491453 eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
1450 return $ac_retval
1454 as_fn_set_status $ac_retval
14511455
14521456 } # ac_fn_c_try_cpp
14531457
14591463 ac_fn_c_check_header_mongrel ()
14601464 {
14611465 as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
1462 if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
1466 if eval "test \"\${$3+set}\"" = set; then :
14631467 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
14641468 $as_echo_n "checking for $2... " >&6; }
1465 if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
1469 if eval "test \"\${$3+set}\"" = set; then :
14661470 $as_echo_n "(cached) " >&6
14671471 fi
14681472 eval ac_res=\$$3
14981502 else
14991503 ac_header_preproc=no
15001504 fi
1501 rm -f conftest.err conftest.$ac_ext
1505 rm -f conftest.err conftest.i conftest.$ac_ext
15021506 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
15031507 $as_echo "$ac_header_preproc" >&6; }
15041508
15211525 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
15221526 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
15231527 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
1524 ( cat <<\_ASBOX
1525 ## -------------------------------------------------- ##
1528 ( $as_echo "## -------------------------------------------------- ##
15261529 ## Report this to savonet-users@lists.sourceforge.net ##
1527 ## -------------------------------------------------- ##
1528 _ASBOX
1530 ## -------------------------------------------------- ##"
15291531 ) | sed "s/^/$as_me: WARNING: /" >&2
15301532 ;;
15311533 esac
15321534 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
15331535 $as_echo_n "checking for $2... " >&6; }
1534 if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
1536 if eval "test \"\${$3+set}\"" = set; then :
15351537 $as_echo_n "(cached) " >&6
15361538 else
15371539 eval "$3=\$ac_header_compiler"
15821584 fi
15831585 rm -rf conftest.dSYM conftest_ipa8_conftest.oo
15841586 eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
1585 return $ac_retval
1587 as_fn_set_status $ac_retval
15861588
15871589 } # ac_fn_c_try_run
15881590
15951597 as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
15961598 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
15971599 $as_echo_n "checking for $2... " >&6; }
1598 if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
1600 if eval "test \"\${$3+set}\"" = set; then :
15991601 $as_echo_n "(cached) " >&6
16001602 else
16011603 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
16591661 # left behind by Apple's compiler. We do this before executing the actions.
16601662 rm -rf conftest.dSYM conftest_ipa8_conftest.oo
16611663 eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
1662 return $ac_retval
1664 as_fn_set_status $ac_retval
16631665
16641666 } # ac_fn_c_try_link
16651667
16711673 as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
16721674 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
16731675 $as_echo_n "checking for $2... " >&6; }
1674 if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
1676 if eval "test \"\${$3+set}\"" = set; then :
16751677 $as_echo_n "(cached) " >&6
16761678 else
16771679 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
17331735 This file contains any messages produced by compilers while
17341736 running configure, to aid debugging if configure makes a mistake.
17351737
1736 It was created by ocaml-faad $as_me 0.1.3, which was
1737 generated by GNU Autoconf 2.64. Invocation command line was
1738 It was created by ocaml-faad $as_me 0.2.0, which was
1739 generated by GNU Autoconf 2.67. Invocation command line was
17381740
17391741 $ $0 $@
17401742
18441846 {
18451847 echo
18461848
1847 cat <<\_ASBOX
1848 ## ---------------- ##
1849 $as_echo "## ---------------- ##
18491850 ## Cache variables. ##
1850 ## ---------------- ##
1851 _ASBOX
1851 ## ---------------- ##"
18521852 echo
18531853 # The following way of writing the cache mishandles newlines in values,
18541854 (
18821882 )
18831883 echo
18841884
1885 cat <<\_ASBOX
1886 ## ----------------- ##
1885 $as_echo "## ----------------- ##
18871886 ## Output variables. ##
1888 ## ----------------- ##
1889 _ASBOX
1887 ## ----------------- ##"
18901888 echo
18911889 for ac_var in $ac_subst_vars
18921890 do
18991897 echo
19001898
19011899 if test -n "$ac_subst_files"; then
1902 cat <<\_ASBOX
1903 ## ------------------- ##
1900 $as_echo "## ------------------- ##
19041901 ## File substitutions. ##
1905 ## ------------------- ##
1906 _ASBOX
1902 ## ------------------- ##"
19071903 echo
19081904 for ac_var in $ac_subst_files
19091905 do
19171913 fi
19181914
19191915 if test -s confdefs.h; then
1920 cat <<\_ASBOX
1921 ## ----------- ##
1916 $as_echo "## ----------- ##
19221917 ## confdefs.h. ##
1923 ## ----------- ##
1924 _ASBOX
1918 ## ----------- ##"
19251919 echo
19261920 cat confdefs.h
19271921 echo
19761970 ac_site_file1=NONE
19771971 ac_site_file2=NONE
19781972 if test -n "$CONFIG_SITE"; then
1979 ac_site_file1=$CONFIG_SITE
1973 # We do not want a PATH search for config.site.
1974 case $CONFIG_SITE in #((
1975 -*) ac_site_file1=./$CONFIG_SITE;;
1976 */*) ac_site_file1=$CONFIG_SITE;;
1977 *) ac_site_file1=./$CONFIG_SITE;;
1978 esac
19801979 elif test "x$prefix" != xNONE; then
19811980 ac_site_file1=$prefix/share/config.site
19821981 ac_site_file2=$prefix/etc/config.site
19871986 for ac_site_file in "$ac_site_file1" "$ac_site_file2"
19881987 do
19891988 test "x$ac_site_file" = xNONE && continue
1990 if test -r "$ac_site_file"; then
1989 if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
19911990 { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
19921991 $as_echo "$as_me: loading site script $ac_site_file" >&6;}
19931992 sed 's/^/| /' "$ac_site_file" >&5
1994 . "$ac_site_file"
1993 . "$ac_site_file" \
1994 || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
1995 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
1996 as_fn_error $? "failed to load site script $ac_site_file
1997 See \`config.log' for more details" "$LINENO" 5 ; }
19951998 fi
19961999 done
19972000
19982001 if test -r "$cache_file"; then
1999 # Some versions of bash will fail to source /dev/null (special
2000 # files actually), so we avoid doing that.
2001 if test -f "$cache_file"; then
2002 # Some versions of bash will fail to source /dev/null (special files
2003 # actually), so we avoid doing that. DJGPP emulates it as a regular file.
2004 if test /dev/null != "$cache_file" && test -f "$cache_file"; then
20022005 { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
20032006 $as_echo "$as_me: loading cache $cache_file" >&6;}
20042007 case $cache_file in
20672070 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
20682071 { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
20692072 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
2070 as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
2073 as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
20712074 fi
20722075 ## -------------------- ##
20732076 ## Main body of script. ##
20932096 CPPFLAGS="$CPPFLAGS -I$prefix/include"
20942097 fi
20952098
2096 OCAMLFIND_LDCONF=""
2097 # Check whether --enable-ldconf was given.
2098 if test "${enable_ldconf+set}" = set; then :
2099 enableval=$enable_ldconf; ac_enable_ldconf=$enableval
2100 else
2101 ac_enable_ldconf=$enableval
2102 fi
2103
2104 if test "$ac_enable_ldconf" = no ; then
2105 { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabling modification of ld.conf" >&5
2106 $as_echo "disabling modification of ld.conf" >&6; }
2107 OCAMLFIND_LDCONF=dummy
2108 fi
2109
2110 # Check for Ocaml compilers
2111
2112 # we first look for ocamlc in the path; if not present, we fail
2113 # Extract the first word of "ocamlc", so it can be a program name with args.
2114 set dummy ocamlc; ac_word=$2
2115 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
2116 $as_echo_n "checking for $ac_word... " >&6; }
2117 if test "${ac_cv_prog_OCAMLC+set}" = set; then :
2118 $as_echo_n "(cached) " >&6
2119 else
2120 if test -n "$OCAMLC"; then
2121 ac_cv_prog_OCAMLC="$OCAMLC" # Let the user override the test.
2122 else
2123 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
2124 for as_dir in $PATH
2125 do
2126 IFS=$as_save_IFS
2127 test -z "$as_dir" && as_dir=.
2128 for ac_exec_ext in '' $ac_executable_extensions; do
2129 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
2130 ac_cv_prog_OCAMLC="`which ocamlc`"
2131 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
2132 break 2
2133 fi
2134 done
2135 done
2136 IFS=$as_save_IFS
2137
2138 test -z "$ac_cv_prog_OCAMLC" && ac_cv_prog_OCAMLC="no"
2139 fi
2140 fi
2141 OCAMLC=$ac_cv_prog_OCAMLC
2142 if test -n "$OCAMLC"; then
2143 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLC" >&5
2144 $as_echo "$OCAMLC" >&6; }
2145 else
2146 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
2147 $as_echo "no" >&6; }
2148 fi
2149
2150
2151 if test "$OCAMLC" = no ; then
2152 as_fn_error "Cannot find ocamlc." "$LINENO" 5
2153 fi
2154
2155 # we look for the directory of ocamlc in $OCAMLC
2156 OCAMLBIN=`dirname $OCAMLC`
2157
2158 # we extract Ocaml version number and library path
2159 OCAMLVERSION=`$OCAMLC -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
2160 echo "ocaml version is $OCAMLVERSION"
2161 OCAMLLIB=`$OCAMLC -v | tail -n 1 | cut -f 4 -d " "`
2162 echo "ocaml library path is $OCAMLLIB"
2163
2164 # then we look for ocamlopt; if not present, we issue a warning
2165 # if the version is not the same, we also discard it
2166 # we set OCAMLBEST to "opt" or "byte", whether ocamlopt is available or not
2167 # Extract the first word of "ocamlopt", so it can be a program name with args.
2168 set dummy ocamlopt; ac_word=$2
2169 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
2170 $as_echo_n "checking for $ac_word... " >&6; }
2171 if test "${ac_cv_path_OCAMLOPT+set}" = set; then :
2172 $as_echo_n "(cached) " >&6
2173 else
2174 case $OCAMLOPT in
2175 [\\/]* | ?:[\\/]*)
2176 ac_cv_path_OCAMLOPT="$OCAMLOPT" # Let the user override the test with a path.
2177 ;;
2178 *)
2179 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
2180 for as_dir in $PATH
2181 do
2182 IFS=$as_save_IFS
2183 test -z "$as_dir" && as_dir=.
2184 for ac_exec_ext in '' $ac_executable_extensions; do
2185 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
2186 ac_cv_path_OCAMLOPT="$as_dir/$ac_word$ac_exec_ext"
2187 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
2188 break 2
2189 fi
2190 done
2191 done
2192 IFS=$as_save_IFS
2193
2194 test -z "$ac_cv_path_OCAMLOPT" && ac_cv_path_OCAMLOPT="no"
2195 ;;
2196 esac
2197 fi
2198 OCAMLOPT=$ac_cv_path_OCAMLOPT
2199 if test -n "$OCAMLOPT"; then
2200 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLOPT" >&5
2201 $as_echo "$OCAMLOPT" >&6; }
2202 else
2203 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
2204 $as_echo "no" >&6; }
2205 fi
2206
2207
2208 OCAMLBEST=byte
2209 if test "$OCAMLOPT" = no ; then
2210 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find ocamlopt; bytecode compilation only." >&5
2211 $as_echo "$as_me: WARNING: Cannot find ocamlopt; bytecode compilation only." >&2;}
2212 else
2213 { $as_echo "$as_me:${as_lineno-$LINENO}: checking ocamlopt version" >&5
2214 $as_echo_n "checking ocamlopt version... " >&6; }
2215 TMPVERSION=`$OCAMLOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
2216 if test "$TMPVERSION" != "$OCAMLVERSION" ; then
2217 { $as_echo "$as_me:${as_lineno-$LINENO}: result: differs from ocamlc; ocamlopt discarded." >&5
2218 $as_echo "differs from ocamlc; ocamlopt discarded." >&6; }
2219 OCAMLOPT=no
2220 else
2221 { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
2222 $as_echo "ok" >&6; }
2223 OCAMLBEST=opt
2224 fi
2225 fi
2226
2227 # checking for ocamlc.opt
2228 # Extract the first word of "ocamlc.opt", so it can be a program name with args.
2229 set dummy ocamlc.opt; ac_word=$2
2230 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
2231 $as_echo_n "checking for $ac_word... " >&6; }
2232 if test "${ac_cv_path_OCAMLCDOTOPT+set}" = set; then :
2233 $as_echo_n "(cached) " >&6
2234 else
2235 case $OCAMLCDOTOPT in
2236 [\\/]* | ?:[\\/]*)
2237 ac_cv_path_OCAMLCDOTOPT="$OCAMLCDOTOPT" # Let the user override the test with a path.
2238 ;;
2239 *)
2240 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
2241 for as_dir in $PATH
2242 do
2243 IFS=$as_save_IFS
2244 test -z "$as_dir" && as_dir=.
2245 for ac_exec_ext in '' $ac_executable_extensions; do
2246 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
2247 ac_cv_path_OCAMLCDOTOPT="$as_dir/$ac_word$ac_exec_ext"
2248 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
2249 break 2
2250 fi
2251 done
2252 done
2253 IFS=$as_save_IFS
2254
2255 test -z "$ac_cv_path_OCAMLCDOTOPT" && ac_cv_path_OCAMLCDOTOPT="no"
2256 ;;
2257 esac
2258 fi
2259 OCAMLCDOTOPT=$ac_cv_path_OCAMLCDOTOPT
2260 if test -n "$OCAMLCDOTOPT"; then
2261 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLCDOTOPT" >&5
2262 $as_echo "$OCAMLCDOTOPT" >&6; }
2263 else
2264 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
2265 $as_echo "no" >&6; }
2266 fi
2267
2268
2269 if test "$OCAMLCDOTOPT" != no ; then
2270 { $as_echo "$as_me:${as_lineno-$LINENO}: checking ocamlc.opt version" >&5
2271 $as_echo_n "checking ocamlc.opt version... " >&6; }
2272 TMPVERSION=`$OCAMLCDOTOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
2273 if test "$TMPVERSION" != "$OCAMLVERSION" ; then
2274 { $as_echo "$as_me:${as_lineno-$LINENO}: result: differs from ocamlc; ocamlc.opt discarded." >&5
2275 $as_echo "differs from ocamlc; ocamlc.opt discarded." >&6; }
2276 else
2277 { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
2278 $as_echo "ok" >&6; }
2279 OCAMLC=$OCAMLCDOTOPT
2280 fi
2281 fi
2282
2283 # checking for ocamlopt.opt
2284 if test "$OCAMLOPT" != no ; then
2285 # Extract the first word of "ocamlopt.opt", so it can be a program name with args.
2286 set dummy ocamlopt.opt; ac_word=$2
2287 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
2288 $as_echo_n "checking for $ac_word... " >&6; }
2289 if test "${ac_cv_path_OCAMLOPTDOTOPT+set}" = set; then :
2290 $as_echo_n "(cached) " >&6
2291 else
2292 case $OCAMLOPTDOTOPT in
2293 [\\/]* | ?:[\\/]*)
2294 ac_cv_path_OCAMLOPTDOTOPT="$OCAMLOPTDOTOPT" # Let the user override the test with a path.
2295 ;;
2296 *)
2297 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
2298 for as_dir in $PATH
2299 do
2300 IFS=$as_save_IFS
2301 test -z "$as_dir" && as_dir=.
2302 for ac_exec_ext in '' $ac_executable_extensions; do
2303 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
2304 ac_cv_path_OCAMLOPTDOTOPT="$as_dir/$ac_word$ac_exec_ext"
2305 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
2306 break 2
2307 fi
2308 done
2309 done
2310 IFS=$as_save_IFS
2311
2312 test -z "$ac_cv_path_OCAMLOPTDOTOPT" && ac_cv_path_OCAMLOPTDOTOPT="no"
2313 ;;
2314 esac
2315 fi
2316 OCAMLOPTDOTOPT=$ac_cv_path_OCAMLOPTDOTOPT
2317 if test -n "$OCAMLOPTDOTOPT"; then
2318 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLOPTDOTOPT" >&5
2319 $as_echo "$OCAMLOPTDOTOPT" >&6; }
2320 else
2321 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
2322 $as_echo "no" >&6; }
2323 fi
2324
2325
2326 if test "$OCAMLOPTDOTOPT" != no ; then
2327 { $as_echo "$as_me:${as_lineno-$LINENO}: checking ocamlc.opt version" >&5
2328 $as_echo_n "checking ocamlc.opt version... " >&6; }
2329 TMPVER=`$OCAMLOPTDOTOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
2330 if test "$TMPVER" != "$OCAMLVERSION" ; then
2331 { $as_echo "$as_me:${as_lineno-$LINENO}: result: differs from ocamlc; ocamlopt.opt discarded." >&5
2332 $as_echo "differs from ocamlc; ocamlopt.opt discarded." >&6; }
2333 else
2334 { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
2335 $as_echo "ok" >&6; }
2336 OCAMLOPT=$OCAMLOPTDOTOPT
2337 fi
2338 fi
2339 fi
2340
2341 # Extract the first word of "ocamldep", so it can be a program name with args.
2342 set dummy ocamldep; ac_word=$2
2343 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
2344 $as_echo_n "checking for $ac_word... " >&6; }
2345 if test "${ac_cv_path_OCAMLDEP+set}" = set; then :
2346 $as_echo_n "(cached) " >&6
2347 else
2348 case $OCAMLDEP in
2349 [\\/]* | ?:[\\/]*)
2350 ac_cv_path_OCAMLDEP="$OCAMLDEP" # Let the user override the test with a path.
2351 ;;
2352 *)
2353 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
2354 for as_dir in $PATH
2355 do
2356 IFS=$as_save_IFS
2357 test -z "$as_dir" && as_dir=.
2358 for ac_exec_ext in '' $ac_executable_extensions; do
2359 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
2360 ac_cv_path_OCAMLDEP="$as_dir/$ac_word$ac_exec_ext"
2361 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
2362 break 2
2363 fi
2364 done
2365 done
2366 IFS=$as_save_IFS
2367
2368 test -z "$ac_cv_path_OCAMLDEP" && ac_cv_path_OCAMLDEP="no"
2369 ;;
2370 esac
2371 fi
2372 OCAMLDEP=$ac_cv_path_OCAMLDEP
2373 if test -n "$OCAMLDEP"; then
2374 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLDEP" >&5
2375 $as_echo "$OCAMLDEP" >&6; }
2376 else
2377 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
2378 $as_echo "no" >&6; }
2379 fi
2380
2381
2382 if test "$OCAMLDEP" = no ; then
2383 as_fn_error "Cannot find ocamldep." "$LINENO" 5
2384 fi
2385
2386 # Extract the first word of "ocamldoc", so it can be a program name with args.
2387 set dummy ocamldoc; ac_word=$2
2388 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
2389 $as_echo_n "checking for $ac_word... " >&6; }
2390 if test "${ac_cv_path_OCAMLDOC+set}" = set; then :
2391 $as_echo_n "(cached) " >&6
2392 else
2393 case $OCAMLDOC in
2394 [\\/]* | ?:[\\/]*)
2395 ac_cv_path_OCAMLDOC="$OCAMLDOC" # Let the user override the test with a path.
2396 ;;
2397 *)
2398 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
2399 for as_dir in $PATH
2400 do
2401 IFS=$as_save_IFS
2402 test -z "$as_dir" && as_dir=.
2403 for ac_exec_ext in '' $ac_executable_extensions; do
2404 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
2405 ac_cv_path_OCAMLDOC="$as_dir/$ac_word$ac_exec_ext"
2406 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
2407 break 2
2408 fi
2409 done
2410 done
2411 IFS=$as_save_IFS
2412
2413 test -z "$ac_cv_path_OCAMLDOC" && ac_cv_path_OCAMLDOC="no"
2414 ;;
2415 esac
2416 fi
2417 OCAMLDOC=$ac_cv_path_OCAMLDOC
2418 if test -n "$OCAMLDOC"; then
2419 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLDOC" >&5
2420 $as_echo "$OCAMLDOC" >&6; }
2421 else
2422 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
2423 $as_echo "no" >&6; }
2424 fi
2425
2426
2427
2428 # Check whether --enable-debugging was given.
2429 if test "${enable_debugging+set}" = set; then :
2430 enableval=$enable_debugging;
2431 fi
2432
2433
2434 if test "x$enable_debugging" = "xyes" ; then
2435 OCAMLFLAGS="$OCAMLFLAGS -g"
2436 fi
2437
2438 # Extract the first word of "ocamlfind", so it can be a program name with args.
2439 set dummy ocamlfind; ac_word=$2
2440 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
2441 $as_echo_n "checking for $ac_word... " >&6; }
2442 if test "${ac_cv_path_OCAMLFIND+set}" = set; then :
2443 $as_echo_n "(cached) " >&6
2444 else
2445 case $OCAMLFIND in
2446 [\\/]* | ?:[\\/]*)
2447 ac_cv_path_OCAMLFIND="$OCAMLFIND" # Let the user override the test with a path.
2448 ;;
2449 *)
2450 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
2451 for as_dir in $PATH
2452 do
2453 IFS=$as_save_IFS
2454 test -z "$as_dir" && as_dir=.
2455 for ac_exec_ext in '' $ac_executable_extensions; do
2456 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
2457 ac_cv_path_OCAMLFIND="$as_dir/$ac_word$ac_exec_ext"
2458 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
2459 break 2
2460 fi
2461 done
2462 done
2463 IFS=$as_save_IFS
2464
2465 test -z "$ac_cv_path_OCAMLFIND" && ac_cv_path_OCAMLFIND="no"
2466 ;;
2467 esac
2468 fi
2469 OCAMLFIND=$ac_cv_path_OCAMLFIND
2470 if test -n "$OCAMLFIND"; then
2471 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLFIND" >&5
2472 $as_echo "$OCAMLFIND" >&6; }
2473 else
2474 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
2475 $as_echo "no" >&6; }
2476 fi
2477
2478
2479 if test "$OCAMLFIND" = no ; then
2480 as_fn_error "Cannot find ocamlfind." "$LINENO" 5
2481 fi
2482
2483 CAMLLIBPATH=`$OCAMLC -where`
2099 # Include a config.h
2100 ac_config_headers="$ac_config_headers config.h:config.h.in"
2101
2102 # Include it
2103 CFLAGS="$CFLAGS -I`pwd`/`dirname $0` -DHAVE_CONFIG_H"
24842104
24852105 ac_ext=c
24862106 ac_cpp='$CPP $CPPFLAGS'
27822402
27832403 test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
27842404 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
2785 as_fn_error "no acceptable C compiler found in \$PATH
2786 See \`config.log' for more details." "$LINENO" 5; }
2405 as_fn_error $? "no acceptable C compiler found in \$PATH
2406 See \`config.log' for more details" "$LINENO" 5 ; }
27872407
27882408 # Provide some information about the compiler.
27892409 $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
28042424 ... rest of stderr output deleted ...
28052425 10q' conftest.err >conftest.er1
28062426 cat conftest.er1 >&5
2807 rm -f conftest.er1 conftest.err
2808 fi
2427 fi
2428 rm -f conftest.er1 conftest.err
28092429 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
28102430 test $ac_status = 0; }
28112431 done
28122432
28132433 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
28142434 /* end confdefs.h. */
2815 #include <stdio.h>
2435
28162436 int
28172437 main ()
28182438 {
2819 FILE *f = fopen ("conftest.out", "w");
2820 return ferror (f) || fclose (f) != 0;
28212439
28222440 ;
28232441 return 0;
28242442 }
28252443 _ACEOF
28262444 ac_clean_files_save=$ac_clean_files
2827 ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out"
2445 ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
28282446 # Try to create an executable without -o first, disregard a.out.
28292447 # It will help us diagnose broken compilers, and finding out an intuition
28302448 # of exeext.
2831 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
2832 $as_echo_n "checking for C compiler default output file name... " >&6; }
2449 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
2450 $as_echo_n "checking whether the C compiler works... " >&6; }
28332451 ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
28342452
28352453 # The possible output files:
28912509 else
28922510 ac_file=''
28932511 fi
2512 if test -z "$ac_file"; then :
2513 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
2514 $as_echo "no" >&6; }
2515 $as_echo "$as_me: failed program was:" >&5
2516 sed 's/^/| /' conftest.$ac_ext >&5
2517
2518 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
2519 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
2520 as_fn_error 77 "C compiler cannot create executables
2521 See \`config.log' for more details" "$LINENO" 5 ; }
2522 else
2523 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
2524 $as_echo "yes" >&6; }
2525 fi
2526 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
2527 $as_echo_n "checking for C compiler default output file name... " >&6; }
28942528 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
28952529 $as_echo "$ac_file" >&6; }
2896 if test -z "$ac_file"; then :
2897 $as_echo "$as_me: failed program was:" >&5
2898 sed 's/^/| /' conftest.$ac_ext >&5
2899
2900 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
2901 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
2902 { as_fn_set_status 77
2903 as_fn_error "C compiler cannot create executables
2904 See \`config.log' for more details." "$LINENO" 5; }; }
2905 fi
29062530 ac_exeext=$ac_cv_exeext
29072531
2908 # Check that the compiler produces executables we can run. If not, either
2909 # the compiler is broken, or we cross compile.
2910 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
2911 $as_echo_n "checking whether the C compiler works... " >&6; }
2912 # If not cross compiling, check that we can run a simple program.
2913 if test "$cross_compiling" != yes; then
2914 if { ac_try='./$ac_file'
2915 { { case "(($ac_try" in
2916 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
2917 *) ac_try_echo=$ac_try;;
2918 esac
2919 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
2920 $as_echo "$ac_try_echo"; } >&5
2921 (eval "$ac_try") 2>&5
2922 ac_status=$?
2923 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
2924 test $ac_status = 0; }; }; then
2925 cross_compiling=no
2926 else
2927 if test "$cross_compiling" = maybe; then
2928 cross_compiling=yes
2929 else
2930 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
2931 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
2932 as_fn_error "cannot run C compiled programs.
2933 If you meant to cross compile, use \`--host'.
2934 See \`config.log' for more details." "$LINENO" 5; }
2935 fi
2936 fi
2937 fi
2938 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
2939 $as_echo "yes" >&6; }
2940
2941 rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out
2532 rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
29422533 ac_clean_files=$ac_clean_files_save
2943 # Check that the compiler produces executables we can run. If not, either
2944 # the compiler is broken, or we cross compile.
2945 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
2946 $as_echo_n "checking whether we are cross compiling... " >&6; }
2947 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
2948 $as_echo "$cross_compiling" >&6; }
2949
29502534 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
29512535 $as_echo_n "checking for suffix of executables... " >&6; }
29522536 if { { ac_try="$ac_link"
29762560 else
29772561 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
29782562 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
2979 as_fn_error "cannot compute suffix of executables: cannot compile and link
2980 See \`config.log' for more details." "$LINENO" 5; }
2981 fi
2982 rm -f conftest$ac_cv_exeext
2563 as_fn_error $? "cannot compute suffix of executables: cannot compile and link
2564 See \`config.log' for more details" "$LINENO" 5 ; }
2565 fi
2566 rm -f conftest conftest$ac_cv_exeext
29832567 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
29842568 $as_echo "$ac_cv_exeext" >&6; }
29852569
29862570 rm -f conftest.$ac_ext
29872571 EXEEXT=$ac_cv_exeext
29882572 ac_exeext=$EXEEXT
2573 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
2574 /* end confdefs.h. */
2575 #include <stdio.h>
2576 int
2577 main ()
2578 {
2579 FILE *f = fopen ("conftest.out", "w");
2580 return ferror (f) || fclose (f) != 0;
2581
2582 ;
2583 return 0;
2584 }
2585 _ACEOF
2586 ac_clean_files="$ac_clean_files conftest.out"
2587 # Check that the compiler produces executables we can run. If not, either
2588 # the compiler is broken, or we cross compile.
2589 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
2590 $as_echo_n "checking whether we are cross compiling... " >&6; }
2591 if test "$cross_compiling" != yes; then
2592 { { ac_try="$ac_link"
2593 case "(($ac_try" in
2594 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
2595 *) ac_try_echo=$ac_try;;
2596 esac
2597 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
2598 $as_echo "$ac_try_echo"; } >&5
2599 (eval "$ac_link") 2>&5
2600 ac_status=$?
2601 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
2602 test $ac_status = 0; }
2603 if { ac_try='./conftest$ac_cv_exeext'
2604 { { case "(($ac_try" in
2605 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
2606 *) ac_try_echo=$ac_try;;
2607 esac
2608 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
2609 $as_echo "$ac_try_echo"; } >&5
2610 (eval "$ac_try") 2>&5
2611 ac_status=$?
2612 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
2613 test $ac_status = 0; }; }; then
2614 cross_compiling=no
2615 else
2616 if test "$cross_compiling" = maybe; then
2617 cross_compiling=yes
2618 else
2619 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
2620 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
2621 as_fn_error $? "cannot run C compiled programs.
2622 If you meant to cross compile, use \`--host'.
2623 See \`config.log' for more details" "$LINENO" 5 ; }
2624 fi
2625 fi
2626 fi
2627 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
2628 $as_echo "$cross_compiling" >&6; }
2629
2630 rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
2631 ac_clean_files=$ac_clean_files_save
29892632 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
29902633 $as_echo_n "checking for suffix of object files... " >&6; }
29912634 if test "${ac_cv_objext+set}" = set; then :
30282671
30292672 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
30302673 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
3031 as_fn_error "cannot compute suffix of object files: cannot compile
3032 See \`config.log' for more details." "$LINENO" 5; }
2674 as_fn_error $? "cannot compute suffix of object files: cannot compile
2675 See \`config.log' for more details" "$LINENO" 5 ; }
30332676 fi
30342677 rm -f conftest.$ac_cv_objext conftest.$ac_ext
30352678 fi
32492892 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
32502893 ac_compiler_gnu=$ac_cv_c_compiler_gnu
32512894
3252 # Check for libfaad
3253 FAAC_LIBS="-lfaad -lm"
3254 FAAC_CFLAGS=""
3255 FAAC_CPPFLAGS=""
3256 ac_save_CPPFLAGS="$CPPFLAGS"
3257 ac_save_CFLAGS="$CFLAGS"
3258 ac_save_LIBS="$LIBS"
3259 CPPFLAGS="$CPPFLAGS $FAAC_CPPFLAGS"
3260 CFLAGS="$CFLAGS $FAAC_CFLAGS"
3261 LIBS="$FAAC_LIBS $LIBS"
32622895
32632896 ac_ext=c
32642897 ac_cpp='$CPP $CPPFLAGS'
33022935 # Broken: fails on valid input.
33032936 continue
33042937 fi
3305 rm -f conftest.err conftest.$ac_ext
2938 rm -f conftest.err conftest.i conftest.$ac_ext
33062939
33072940 # OK, works on sane cases. Now check whether nonexistent headers
33082941 # can be detected and how.
33182951 ac_preproc_ok=:
33192952 break
33202953 fi
3321 rm -f conftest.err conftest.$ac_ext
2954 rm -f conftest.err conftest.i conftest.$ac_ext
33222955
33232956 done
33242957 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
3325 rm -f conftest.err conftest.$ac_ext
2958 rm -f conftest.i conftest.err conftest.$ac_ext
33262959 if $ac_preproc_ok; then :
33272960 break
33282961 fi
33612994 # Broken: fails on valid input.
33622995 continue
33632996 fi
3364 rm -f conftest.err conftest.$ac_ext
2997 rm -f conftest.err conftest.i conftest.$ac_ext
33652998
33662999 # OK, works on sane cases. Now check whether nonexistent headers
33673000 # can be detected and how.
33773010 ac_preproc_ok=:
33783011 break
33793012 fi
3380 rm -f conftest.err conftest.$ac_ext
3013 rm -f conftest.err conftest.i conftest.$ac_ext
33813014
33823015 done
33833016 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
3384 rm -f conftest.err conftest.$ac_ext
3017 rm -f conftest.i conftest.err conftest.$ac_ext
33853018 if $ac_preproc_ok; then :
33863019
33873020 else
33883021 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
33893022 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
3390 as_fn_error "C preprocessor \"$CPP\" fails sanity check
3391 See \`config.log' for more details." "$LINENO" 5; }
3023 as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
3024 See \`config.log' for more details" "$LINENO" 5 ; }
33923025 fi
33933026
33943027 ac_ext=c
34493082 done
34503083 IFS=$as_save_IFS
34513084 if test -z "$ac_cv_path_GREP"; then
3452 as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
3085 as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
34533086 fi
34543087 else
34553088 ac_cv_path_GREP=$GREP
35153148 done
35163149 IFS=$as_save_IFS
35173150 if test -z "$ac_cv_path_EGREP"; then
3518 as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
3151 as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
35193152 fi
35203153 else
35213154 ac_cv_path_EGREP=$EGREP
36473280 as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
36483281 ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
36493282 "
3650 eval as_val=\$$as_ac_Header
3651 if test "x$as_val" = x""yes; then :
3283 if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
36523284 cat >>confdefs.h <<_ACEOF
36533285 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
36543286 _ACEOF
36583290 done
36593291
36603292
3293 for ac_header in errno.h
3294 do :
3295 ac_fn_c_check_header_mongrel "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default"
3296 if test "x$ac_cv_header_errno_h" = x""yes; then :
3297 cat >>confdefs.h <<_ACEOF
3298 #define HAVE_ERRNO_H 1
3299 _ACEOF
3300
3301 fi
3302
3303 done
3304
3305
3306 OCAMLFIND_LDCONF=""
3307 # Check whether --enable-ldconf was given.
3308 if test "${enable_ldconf+set}" = set; then :
3309 enableval=$enable_ldconf; ac_enable_ldconf=$enableval
3310 else
3311 ac_enable_ldconf=$enableval
3312 fi
3313
3314 if test "$ac_enable_ldconf" = no ; then
3315 { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabling modification of ld.conf" >&5
3316 $as_echo "disabling modification of ld.conf" >&6; }
3317 OCAMLFIND_LDCONF=dummy
3318 fi
3319
3320 # Check for Ocaml compilers
3321
3322 # we first look for ocamlc in the path; if not present, we fail
3323 # Extract the first word of "ocamlc", so it can be a program name with args.
3324 set dummy ocamlc; ac_word=$2
3325 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
3326 $as_echo_n "checking for $ac_word... " >&6; }
3327 if test "${ac_cv_prog_OCAMLC+set}" = set; then :
3328 $as_echo_n "(cached) " >&6
3329 else
3330 if test -n "$OCAMLC"; then
3331 ac_cv_prog_OCAMLC="$OCAMLC" # Let the user override the test.
3332 else
3333 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
3334 for as_dir in $PATH
3335 do
3336 IFS=$as_save_IFS
3337 test -z "$as_dir" && as_dir=.
3338 for ac_exec_ext in '' $ac_executable_extensions; do
3339 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3340 ac_cv_prog_OCAMLC="`which ocamlc`"
3341 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
3342 break 2
3343 fi
3344 done
3345 done
3346 IFS=$as_save_IFS
3347
3348 test -z "$ac_cv_prog_OCAMLC" && ac_cv_prog_OCAMLC="no"
3349 fi
3350 fi
3351 OCAMLC=$ac_cv_prog_OCAMLC
3352 if test -n "$OCAMLC"; then
3353 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLC" >&5
3354 $as_echo "$OCAMLC" >&6; }
3355 else
3356 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3357 $as_echo "no" >&6; }
3358 fi
3359
3360
3361 if test "$OCAMLC" = no ; then
3362 as_fn_error $? "Cannot find ocamlc." "$LINENO" 5
3363 fi
3364
3365 # we look for the directory of ocamlc in $OCAMLC
3366 OCAMLBIN=`dirname $OCAMLC`
3367
3368 # we extract Ocaml version number and library path
3369 OCAMLVERSION=`$OCAMLC -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
3370 echo "ocaml version is $OCAMLVERSION"
3371 OCAMLLIB=`$OCAMLC -v | tail -n 1 | cut -f 4 -d " "`
3372 echo "ocaml library path is $OCAMLLIB"
3373
3374 # then we look for ocamlopt; if not present, we issue a warning
3375 # if the version is not the same, we also discard it
3376 # we set OCAMLBEST to "opt" or "byte", whether ocamlopt is available or not
3377 # Extract the first word of "ocamlopt", so it can be a program name with args.
3378 set dummy ocamlopt; ac_word=$2
3379 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
3380 $as_echo_n "checking for $ac_word... " >&6; }
3381 if test "${ac_cv_path_OCAMLOPT+set}" = set; then :
3382 $as_echo_n "(cached) " >&6
3383 else
3384 case $OCAMLOPT in
3385 [\\/]* | ?:[\\/]*)
3386 ac_cv_path_OCAMLOPT="$OCAMLOPT" # Let the user override the test with a path.
3387 ;;
3388 *)
3389 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
3390 for as_dir in $PATH
3391 do
3392 IFS=$as_save_IFS
3393 test -z "$as_dir" && as_dir=.
3394 for ac_exec_ext in '' $ac_executable_extensions; do
3395 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3396 ac_cv_path_OCAMLOPT="$as_dir/$ac_word$ac_exec_ext"
3397 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
3398 break 2
3399 fi
3400 done
3401 done
3402 IFS=$as_save_IFS
3403
3404 test -z "$ac_cv_path_OCAMLOPT" && ac_cv_path_OCAMLOPT="no"
3405 ;;
3406 esac
3407 fi
3408 OCAMLOPT=$ac_cv_path_OCAMLOPT
3409 if test -n "$OCAMLOPT"; then
3410 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLOPT" >&5
3411 $as_echo "$OCAMLOPT" >&6; }
3412 else
3413 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3414 $as_echo "no" >&6; }
3415 fi
3416
3417
3418 OCAMLBEST=byte
3419 if test "$OCAMLOPT" = no ; then
3420 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find ocamlopt; bytecode compilation only." >&5
3421 $as_echo "$as_me: WARNING: Cannot find ocamlopt; bytecode compilation only." >&2;}
3422 else
3423 { $as_echo "$as_me:${as_lineno-$LINENO}: checking ocamlopt version" >&5
3424 $as_echo_n "checking ocamlopt version... " >&6; }
3425 TMPVERSION=`$OCAMLOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
3426 if test "$TMPVERSION" != "$OCAMLVERSION" ; then
3427 { $as_echo "$as_me:${as_lineno-$LINENO}: result: differs from ocamlc; ocamlopt discarded." >&5
3428 $as_echo "differs from ocamlc; ocamlopt discarded." >&6; }
3429 OCAMLOPT=no
3430 else
3431 { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
3432 $as_echo "ok" >&6; }
3433 OCAMLBEST=opt
3434 fi
3435 fi
3436
3437 # checking for ocamlc.opt
3438 # Extract the first word of "ocamlc.opt", so it can be a program name with args.
3439 set dummy ocamlc.opt; ac_word=$2
3440 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
3441 $as_echo_n "checking for $ac_word... " >&6; }
3442 if test "${ac_cv_path_OCAMLCDOTOPT+set}" = set; then :
3443 $as_echo_n "(cached) " >&6
3444 else
3445 case $OCAMLCDOTOPT in
3446 [\\/]* | ?:[\\/]*)
3447 ac_cv_path_OCAMLCDOTOPT="$OCAMLCDOTOPT" # Let the user override the test with a path.
3448 ;;
3449 *)
3450 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
3451 for as_dir in $PATH
3452 do
3453 IFS=$as_save_IFS
3454 test -z "$as_dir" && as_dir=.
3455 for ac_exec_ext in '' $ac_executable_extensions; do
3456 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3457 ac_cv_path_OCAMLCDOTOPT="$as_dir/$ac_word$ac_exec_ext"
3458 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
3459 break 2
3460 fi
3461 done
3462 done
3463 IFS=$as_save_IFS
3464
3465 test -z "$ac_cv_path_OCAMLCDOTOPT" && ac_cv_path_OCAMLCDOTOPT="no"
3466 ;;
3467 esac
3468 fi
3469 OCAMLCDOTOPT=$ac_cv_path_OCAMLCDOTOPT
3470 if test -n "$OCAMLCDOTOPT"; then
3471 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLCDOTOPT" >&5
3472 $as_echo "$OCAMLCDOTOPT" >&6; }
3473 else
3474 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3475 $as_echo "no" >&6; }
3476 fi
3477
3478
3479 if test "$OCAMLCDOTOPT" != no ; then
3480 { $as_echo "$as_me:${as_lineno-$LINENO}: checking ocamlc.opt version" >&5
3481 $as_echo_n "checking ocamlc.opt version... " >&6; }
3482 TMPVERSION=`$OCAMLCDOTOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
3483 if test "$TMPVERSION" != "$OCAMLVERSION" ; then
3484 { $as_echo "$as_me:${as_lineno-$LINENO}: result: differs from ocamlc; ocamlc.opt discarded." >&5
3485 $as_echo "differs from ocamlc; ocamlc.opt discarded." >&6; }
3486 else
3487 { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
3488 $as_echo "ok" >&6; }
3489 OCAMLC=$OCAMLCDOTOPT
3490 fi
3491 fi
3492
3493 # checking for ocamlopt.opt
3494 if test "$OCAMLOPT" != no ; then
3495 # Extract the first word of "ocamlopt.opt", so it can be a program name with args.
3496 set dummy ocamlopt.opt; ac_word=$2
3497 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
3498 $as_echo_n "checking for $ac_word... " >&6; }
3499 if test "${ac_cv_path_OCAMLOPTDOTOPT+set}" = set; then :
3500 $as_echo_n "(cached) " >&6
3501 else
3502 case $OCAMLOPTDOTOPT in
3503 [\\/]* | ?:[\\/]*)
3504 ac_cv_path_OCAMLOPTDOTOPT="$OCAMLOPTDOTOPT" # Let the user override the test with a path.
3505 ;;
3506 *)
3507 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
3508 for as_dir in $PATH
3509 do
3510 IFS=$as_save_IFS
3511 test -z "$as_dir" && as_dir=.
3512 for ac_exec_ext in '' $ac_executable_extensions; do
3513 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3514 ac_cv_path_OCAMLOPTDOTOPT="$as_dir/$ac_word$ac_exec_ext"
3515 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
3516 break 2
3517 fi
3518 done
3519 done
3520 IFS=$as_save_IFS
3521
3522 test -z "$ac_cv_path_OCAMLOPTDOTOPT" && ac_cv_path_OCAMLOPTDOTOPT="no"
3523 ;;
3524 esac
3525 fi
3526 OCAMLOPTDOTOPT=$ac_cv_path_OCAMLOPTDOTOPT
3527 if test -n "$OCAMLOPTDOTOPT"; then
3528 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLOPTDOTOPT" >&5
3529 $as_echo "$OCAMLOPTDOTOPT" >&6; }
3530 else
3531 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3532 $as_echo "no" >&6; }
3533 fi
3534
3535
3536 if test "$OCAMLOPTDOTOPT" != no ; then
3537 { $as_echo "$as_me:${as_lineno-$LINENO}: checking ocamlc.opt version" >&5
3538 $as_echo_n "checking ocamlc.opt version... " >&6; }
3539 TMPVER=`$OCAMLOPTDOTOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
3540 if test "$TMPVER" != "$OCAMLVERSION" ; then
3541 { $as_echo "$as_me:${as_lineno-$LINENO}: result: differs from ocamlc; ocamlopt.opt discarded." >&5
3542 $as_echo "differs from ocamlc; ocamlopt.opt discarded." >&6; }
3543 else
3544 { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
3545 $as_echo "ok" >&6; }
3546 OCAMLOPT=$OCAMLOPTDOTOPT
3547 fi
3548 fi
3549 fi
3550
3551 # Extract the first word of "ocamldep", so it can be a program name with args.
3552 set dummy ocamldep; ac_word=$2
3553 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
3554 $as_echo_n "checking for $ac_word... " >&6; }
3555 if test "${ac_cv_path_OCAMLDEP+set}" = set; then :
3556 $as_echo_n "(cached) " >&6
3557 else
3558 case $OCAMLDEP in
3559 [\\/]* | ?:[\\/]*)
3560 ac_cv_path_OCAMLDEP="$OCAMLDEP" # Let the user override the test with a path.
3561 ;;
3562 *)
3563 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
3564 for as_dir in $PATH
3565 do
3566 IFS=$as_save_IFS
3567 test -z "$as_dir" && as_dir=.
3568 for ac_exec_ext in '' $ac_executable_extensions; do
3569 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3570 ac_cv_path_OCAMLDEP="$as_dir/$ac_word$ac_exec_ext"
3571 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
3572 break 2
3573 fi
3574 done
3575 done
3576 IFS=$as_save_IFS
3577
3578 test -z "$ac_cv_path_OCAMLDEP" && ac_cv_path_OCAMLDEP="no"
3579 ;;
3580 esac
3581 fi
3582 OCAMLDEP=$ac_cv_path_OCAMLDEP
3583 if test -n "$OCAMLDEP"; then
3584 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLDEP" >&5
3585 $as_echo "$OCAMLDEP" >&6; }
3586 else
3587 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3588 $as_echo "no" >&6; }
3589 fi
3590
3591
3592 if test "$OCAMLDEP" = no ; then
3593 as_fn_error $? "Cannot find ocamldep." "$LINENO" 5
3594 fi
3595
3596 # Extract the first word of "ocamldoc", so it can be a program name with args.
3597 set dummy ocamldoc; ac_word=$2
3598 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
3599 $as_echo_n "checking for $ac_word... " >&6; }
3600 if test "${ac_cv_path_OCAMLDOC+set}" = set; then :
3601 $as_echo_n "(cached) " >&6
3602 else
3603 case $OCAMLDOC in
3604 [\\/]* | ?:[\\/]*)
3605 ac_cv_path_OCAMLDOC="$OCAMLDOC" # Let the user override the test with a path.
3606 ;;
3607 *)
3608 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
3609 for as_dir in $PATH
3610 do
3611 IFS=$as_save_IFS
3612 test -z "$as_dir" && as_dir=.
3613 for ac_exec_ext in '' $ac_executable_extensions; do
3614 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3615 ac_cv_path_OCAMLDOC="$as_dir/$ac_word$ac_exec_ext"
3616 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
3617 break 2
3618 fi
3619 done
3620 done
3621 IFS=$as_save_IFS
3622
3623 test -z "$ac_cv_path_OCAMLDOC" && ac_cv_path_OCAMLDOC="no"
3624 ;;
3625 esac
3626 fi
3627 OCAMLDOC=$ac_cv_path_OCAMLDOC
3628 if test -n "$OCAMLDOC"; then
3629 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLDOC" >&5
3630 $as_echo "$OCAMLDOC" >&6; }
3631 else
3632 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3633 $as_echo "no" >&6; }
3634 fi
3635
3636
3637
3638 # Check whether --enable-debugging was given.
3639 if test "${enable_debugging+set}" = set; then :
3640 enableval=$enable_debugging;
3641 fi
3642
3643
3644 if test "x$enable_debugging" = "xyes" ; then
3645 OCAMLFLAGS="$OCAMLFLAGS -g"
3646 fi
3647
3648 # Extract the first word of "ocamlfind", so it can be a program name with args.
3649 set dummy ocamlfind; ac_word=$2
3650 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
3651 $as_echo_n "checking for $ac_word... " >&6; }
3652 if test "${ac_cv_path_OCAMLFIND+set}" = set; then :
3653 $as_echo_n "(cached) " >&6
3654 else
3655 case $OCAMLFIND in
3656 [\\/]* | ?:[\\/]*)
3657 ac_cv_path_OCAMLFIND="$OCAMLFIND" # Let the user override the test with a path.
3658 ;;
3659 *)
3660 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
3661 for as_dir in $PATH
3662 do
3663 IFS=$as_save_IFS
3664 test -z "$as_dir" && as_dir=.
3665 for ac_exec_ext in '' $ac_executable_extensions; do
3666 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3667 ac_cv_path_OCAMLFIND="$as_dir/$ac_word$ac_exec_ext"
3668 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
3669 break 2
3670 fi
3671 done
3672 done
3673 IFS=$as_save_IFS
3674
3675 test -z "$ac_cv_path_OCAMLFIND" && ac_cv_path_OCAMLFIND="no"
3676 ;;
3677 esac
3678 fi
3679 OCAMLFIND=$ac_cv_path_OCAMLFIND
3680 if test -n "$OCAMLFIND"; then
3681 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLFIND" >&5
3682 $as_echo "$OCAMLFIND" >&6; }
3683 else
3684 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3685 $as_echo "no" >&6; }
3686 fi
3687
3688
3689 if test "$OCAMLFIND" = no ; then
3690 as_fn_error $? "Cannot find ocamlfind." "$LINENO" 5
3691 fi
3692
3693 CAMLLIBPATH=`$OCAMLC -where`
3694
3695 ac_ext=c
3696 ac_cpp='$CPP $CPPFLAGS'
3697 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
3698 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
3699 ac_compiler_gnu=$ac_cv_c_compiler_gnu
3700 if test -n "$ac_tool_prefix"; then
3701 # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
3702 set dummy ${ac_tool_prefix}gcc; ac_word=$2
3703 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
3704 $as_echo_n "checking for $ac_word... " >&6; }
3705 if test "${ac_cv_prog_CC+set}" = set; then :
3706 $as_echo_n "(cached) " >&6
3707 else
3708 if test -n "$CC"; then
3709 ac_cv_prog_CC="$CC" # Let the user override the test.
3710 else
3711 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
3712 for as_dir in $PATH
3713 do
3714 IFS=$as_save_IFS
3715 test -z "$as_dir" && as_dir=.
3716 for ac_exec_ext in '' $ac_executable_extensions; do
3717 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3718 ac_cv_prog_CC="${ac_tool_prefix}gcc"
3719 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
3720 break 2
3721 fi
3722 done
3723 done
3724 IFS=$as_save_IFS
3725
3726 fi
3727 fi
3728 CC=$ac_cv_prog_CC
3729 if test -n "$CC"; then
3730 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
3731 $as_echo "$CC" >&6; }
3732 else
3733 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3734 $as_echo "no" >&6; }
3735 fi
3736
3737
3738 fi
3739 if test -z "$ac_cv_prog_CC"; then
3740 ac_ct_CC=$CC
3741 # Extract the first word of "gcc", so it can be a program name with args.
3742 set dummy gcc; ac_word=$2
3743 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
3744 $as_echo_n "checking for $ac_word... " >&6; }
3745 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
3746 $as_echo_n "(cached) " >&6
3747 else
3748 if test -n "$ac_ct_CC"; then
3749 ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
3750 else
3751 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
3752 for as_dir in $PATH
3753 do
3754 IFS=$as_save_IFS
3755 test -z "$as_dir" && as_dir=.
3756 for ac_exec_ext in '' $ac_executable_extensions; do
3757 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3758 ac_cv_prog_ac_ct_CC="gcc"
3759 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
3760 break 2
3761 fi
3762 done
3763 done
3764 IFS=$as_save_IFS
3765
3766 fi
3767 fi
3768 ac_ct_CC=$ac_cv_prog_ac_ct_CC
3769 if test -n "$ac_ct_CC"; then
3770 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
3771 $as_echo "$ac_ct_CC" >&6; }
3772 else
3773 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3774 $as_echo "no" >&6; }
3775 fi
3776
3777 if test "x$ac_ct_CC" = x; then
3778 CC=""
3779 else
3780 case $cross_compiling:$ac_tool_warned in
3781 yes:)
3782 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
3783 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
3784 ac_tool_warned=yes ;;
3785 esac
3786 CC=$ac_ct_CC
3787 fi
3788 else
3789 CC="$ac_cv_prog_CC"
3790 fi
3791
3792 if test -z "$CC"; then
3793 if test -n "$ac_tool_prefix"; then
3794 # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
3795 set dummy ${ac_tool_prefix}cc; ac_word=$2
3796 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
3797 $as_echo_n "checking for $ac_word... " >&6; }
3798 if test "${ac_cv_prog_CC+set}" = set; then :
3799 $as_echo_n "(cached) " >&6
3800 else
3801 if test -n "$CC"; then
3802 ac_cv_prog_CC="$CC" # Let the user override the test.
3803 else
3804 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
3805 for as_dir in $PATH
3806 do
3807 IFS=$as_save_IFS
3808 test -z "$as_dir" && as_dir=.
3809 for ac_exec_ext in '' $ac_executable_extensions; do
3810 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3811 ac_cv_prog_CC="${ac_tool_prefix}cc"
3812 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
3813 break 2
3814 fi
3815 done
3816 done
3817 IFS=$as_save_IFS
3818
3819 fi
3820 fi
3821 CC=$ac_cv_prog_CC
3822 if test -n "$CC"; then
3823 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
3824 $as_echo "$CC" >&6; }
3825 else
3826 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3827 $as_echo "no" >&6; }
3828 fi
3829
3830
3831 fi
3832 fi
3833 if test -z "$CC"; then
3834 # Extract the first word of "cc", so it can be a program name with args.
3835 set dummy cc; ac_word=$2
3836 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
3837 $as_echo_n "checking for $ac_word... " >&6; }
3838 if test "${ac_cv_prog_CC+set}" = set; then :
3839 $as_echo_n "(cached) " >&6
3840 else
3841 if test -n "$CC"; then
3842 ac_cv_prog_CC="$CC" # Let the user override the test.
3843 else
3844 ac_prog_rejected=no
3845 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
3846 for as_dir in $PATH
3847 do
3848 IFS=$as_save_IFS
3849 test -z "$as_dir" && as_dir=.
3850 for ac_exec_ext in '' $ac_executable_extensions; do
3851 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3852 if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
3853 ac_prog_rejected=yes
3854 continue
3855 fi
3856 ac_cv_prog_CC="cc"
3857 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
3858 break 2
3859 fi
3860 done
3861 done
3862 IFS=$as_save_IFS
3863
3864 if test $ac_prog_rejected = yes; then
3865 # We found a bogon in the path, so make sure we never use it.
3866 set dummy $ac_cv_prog_CC
3867 shift
3868 if test $# != 0; then
3869 # We chose a different compiler from the bogus one.
3870 # However, it has the same basename, so the bogon will be chosen
3871 # first if we set CC to just the basename; use the full file name.
3872 shift
3873 ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
3874 fi
3875 fi
3876 fi
3877 fi
3878 CC=$ac_cv_prog_CC
3879 if test -n "$CC"; then
3880 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
3881 $as_echo "$CC" >&6; }
3882 else
3883 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3884 $as_echo "no" >&6; }
3885 fi
3886
3887
3888 fi
3889 if test -z "$CC"; then
3890 if test -n "$ac_tool_prefix"; then
3891 for ac_prog in cl.exe
3892 do
3893 # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
3894 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
3895 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
3896 $as_echo_n "checking for $ac_word... " >&6; }
3897 if test "${ac_cv_prog_CC+set}" = set; then :
3898 $as_echo_n "(cached) " >&6
3899 else
3900 if test -n "$CC"; then
3901 ac_cv_prog_CC="$CC" # Let the user override the test.
3902 else
3903 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
3904 for as_dir in $PATH
3905 do
3906 IFS=$as_save_IFS
3907 test -z "$as_dir" && as_dir=.
3908 for ac_exec_ext in '' $ac_executable_extensions; do
3909 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3910 ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
3911 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
3912 break 2
3913 fi
3914 done
3915 done
3916 IFS=$as_save_IFS
3917
3918 fi
3919 fi
3920 CC=$ac_cv_prog_CC
3921 if test -n "$CC"; then
3922 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
3923 $as_echo "$CC" >&6; }
3924 else
3925 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3926 $as_echo "no" >&6; }
3927 fi
3928
3929
3930 test -n "$CC" && break
3931 done
3932 fi
3933 if test -z "$CC"; then
3934 ac_ct_CC=$CC
3935 for ac_prog in cl.exe
3936 do
3937 # Extract the first word of "$ac_prog", so it can be a program name with args.
3938 set dummy $ac_prog; ac_word=$2
3939 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
3940 $as_echo_n "checking for $ac_word... " >&6; }
3941 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
3942 $as_echo_n "(cached) " >&6
3943 else
3944 if test -n "$ac_ct_CC"; then
3945 ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
3946 else
3947 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
3948 for as_dir in $PATH
3949 do
3950 IFS=$as_save_IFS
3951 test -z "$as_dir" && as_dir=.
3952 for ac_exec_ext in '' $ac_executable_extensions; do
3953 if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
3954 ac_cv_prog_ac_ct_CC="$ac_prog"
3955 $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
3956 break 2
3957 fi
3958 done
3959 done
3960 IFS=$as_save_IFS
3961
3962 fi
3963 fi
3964 ac_ct_CC=$ac_cv_prog_ac_ct_CC
3965 if test -n "$ac_ct_CC"; then
3966 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
3967 $as_echo "$ac_ct_CC" >&6; }
3968 else
3969 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
3970 $as_echo "no" >&6; }
3971 fi
3972
3973
3974 test -n "$ac_ct_CC" && break
3975 done
3976
3977 if test "x$ac_ct_CC" = x; then
3978 CC=""
3979 else
3980 case $cross_compiling:$ac_tool_warned in
3981 yes:)
3982 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
3983 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
3984 ac_tool_warned=yes ;;
3985 esac
3986 CC=$ac_ct_CC
3987 fi
3988 fi
3989
3990 fi
3991
3992
3993 test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
3994 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
3995 as_fn_error $? "no acceptable C compiler found in \$PATH
3996 See \`config.log' for more details" "$LINENO" 5 ; }
3997
3998 # Provide some information about the compiler.
3999 $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
4000 set X $ac_compile
4001 ac_compiler=$2
4002 for ac_option in --version -v -V -qversion; do
4003 { { ac_try="$ac_compiler $ac_option >&5"
4004 case "(($ac_try" in
4005 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
4006 *) ac_try_echo=$ac_try;;
4007 esac
4008 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
4009 $as_echo "$ac_try_echo"; } >&5
4010 (eval "$ac_compiler $ac_option >&5") 2>conftest.err
4011 ac_status=$?
4012 if test -s conftest.err; then
4013 sed '10a\
4014 ... rest of stderr output deleted ...
4015 10q' conftest.err >conftest.er1
4016 cat conftest.er1 >&5
4017 fi
4018 rm -f conftest.er1 conftest.err
4019 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
4020 test $ac_status = 0; }
4021 done
4022
4023 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
4024 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
4025 if test "${ac_cv_c_compiler_gnu+set}" = set; then :
4026 $as_echo_n "(cached) " >&6
4027 else
4028 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
4029 /* end confdefs.h. */
4030
4031 int
4032 main ()
4033 {
4034 #ifndef __GNUC__
4035 choke me
4036 #endif
4037
4038 ;
4039 return 0;
4040 }
4041 _ACEOF
4042 if ac_fn_c_try_compile "$LINENO"; then :
4043 ac_compiler_gnu=yes
4044 else
4045 ac_compiler_gnu=no
4046 fi
4047 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
4048 ac_cv_c_compiler_gnu=$ac_compiler_gnu
4049
4050 fi
4051 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
4052 $as_echo "$ac_cv_c_compiler_gnu" >&6; }
4053 if test $ac_compiler_gnu = yes; then
4054 GCC=yes
4055 else
4056 GCC=
4057 fi
4058 ac_test_CFLAGS=${CFLAGS+set}
4059 ac_save_CFLAGS=$CFLAGS
4060 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
4061 $as_echo_n "checking whether $CC accepts -g... " >&6; }
4062 if test "${ac_cv_prog_cc_g+set}" = set; then :
4063 $as_echo_n "(cached) " >&6
4064 else
4065 ac_save_c_werror_flag=$ac_c_werror_flag
4066 ac_c_werror_flag=yes
4067 ac_cv_prog_cc_g=no
4068 CFLAGS="-g"
4069 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
4070 /* end confdefs.h. */
4071
4072 int
4073 main ()
4074 {
4075
4076 ;
4077 return 0;
4078 }
4079 _ACEOF
4080 if ac_fn_c_try_compile "$LINENO"; then :
4081 ac_cv_prog_cc_g=yes
4082 else
4083 CFLAGS=""
4084 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
4085 /* end confdefs.h. */
4086
4087 int
4088 main ()
4089 {
4090
4091 ;
4092 return 0;
4093 }
4094 _ACEOF
4095 if ac_fn_c_try_compile "$LINENO"; then :
4096
4097 else
4098 ac_c_werror_flag=$ac_save_c_werror_flag
4099 CFLAGS="-g"
4100 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
4101 /* end confdefs.h. */
4102
4103 int
4104 main ()
4105 {
4106
4107 ;
4108 return 0;
4109 }
4110 _ACEOF
4111 if ac_fn_c_try_compile "$LINENO"; then :
4112 ac_cv_prog_cc_g=yes
4113 fi
4114 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
4115 fi
4116 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
4117 fi
4118 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
4119 ac_c_werror_flag=$ac_save_c_werror_flag
4120 fi
4121 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
4122 $as_echo "$ac_cv_prog_cc_g" >&6; }
4123 if test "$ac_test_CFLAGS" = set; then
4124 CFLAGS=$ac_save_CFLAGS
4125 elif test $ac_cv_prog_cc_g = yes; then
4126 if test "$GCC" = yes; then
4127 CFLAGS="-g -O2"
4128 else
4129 CFLAGS="-g"
4130 fi
4131 else
4132 if test "$GCC" = yes; then
4133 CFLAGS="-O2"
4134 else
4135 CFLAGS=
4136 fi
4137 fi
4138 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
4139 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
4140 if test "${ac_cv_prog_cc_c89+set}" = set; then :
4141 $as_echo_n "(cached) " >&6
4142 else
4143 ac_cv_prog_cc_c89=no
4144 ac_save_CC=$CC
4145 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
4146 /* end confdefs.h. */
4147 #include <stdarg.h>
4148 #include <stdio.h>
4149 #include <sys/types.h>
4150 #include <sys/stat.h>
4151 /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
4152 struct buf { int x; };
4153 FILE * (*rcsopen) (struct buf *, struct stat *, int);
4154 static char *e (p, i)
4155 char **p;
4156 int i;
4157 {
4158 return p[i];
4159 }
4160 static char *f (char * (*g) (char **, int), char **p, ...)
4161 {
4162 char *s;
4163 va_list v;
4164 va_start (v,p);
4165 s = g (p, va_arg (v,int));
4166 va_end (v);
4167 return s;
4168 }
4169
4170 /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
4171 function prototypes and stuff, but not '\xHH' hex character constants.
4172 These don't provoke an error unfortunately, instead are silently treated
4173 as 'x'. The following induces an error, until -std is added to get
4174 proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
4175 array size at least. It's necessary to write '\x00'==0 to get something
4176 that's true only with -std. */
4177 int osf4_cc_array ['\x00' == 0 ? 1 : -1];
4178
4179 /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
4180 inside strings and character constants. */
4181 #define FOO(x) 'x'
4182 int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
4183
4184 int test (int i, double x);
4185 struct s1 {int (*f) (int a);};
4186 struct s2 {int (*f) (double a);};
4187 int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
4188 int argc;
4189 char **argv;
4190 int
4191 main ()
4192 {
4193 return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
4194 ;
4195 return 0;
4196 }
4197 _ACEOF
4198 for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
4199 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
4200 do
4201 CC="$ac_save_CC $ac_arg"
4202 if ac_fn_c_try_compile "$LINENO"; then :
4203 ac_cv_prog_cc_c89=$ac_arg
4204 fi
4205 rm -f core conftest.err conftest.$ac_objext
4206 test "x$ac_cv_prog_cc_c89" != "xno" && break
4207 done
4208 rm -f conftest.$ac_ext
4209 CC=$ac_save_CC
4210
4211 fi
4212 # AC_CACHE_VAL
4213 case "x$ac_cv_prog_cc_c89" in
4214 x)
4215 { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
4216 $as_echo "none needed" >&6; } ;;
4217 xno)
4218 { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
4219 $as_echo "unsupported" >&6; } ;;
4220 *)
4221 CC="$CC $ac_cv_prog_cc_c89"
4222 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
4223 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
4224 esac
4225 if test "x$ac_cv_prog_cc_c89" != xno; then :
4226
4227 fi
4228
4229 ac_ext=c
4230 ac_cpp='$CPP $CPPFLAGS'
4231 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
4232 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
4233 ac_compiler_gnu=$ac_cv_c_compiler_gnu
4234
4235 # Check for libfaad
4236 FAAC_LIBS="-lfaad -lm"
4237 FAAC_CFLAGS=""
4238 FAAC_CPPFLAGS=""
4239 ac_save_CPPFLAGS="$CPPFLAGS"
4240 ac_save_CFLAGS="$CFLAGS"
4241 ac_save_LIBS="$LIBS"
4242 CPPFLAGS="$CPPFLAGS $FAAC_CPPFLAGS"
4243 CFLAGS="$CFLAGS $FAAC_CFLAGS"
4244 LIBS="$FAAC_LIBS $LIBS"
36614245 for ac_header in neaacdec.h
36624246 do :
36634247 ac_fn_c_check_header_mongrel "$LINENO" "neaacdec.h" "ac_cv_header_neaacdec_h" "$ac_includes_default"
36804264 CFLAGS="$ac_save_CFLAGS"
36814265 LIBS="$ac_save_LIBS"
36824266 if test "$ac_have_faad" != "yes"; then
3683 as_fn_error "Cannot find libfaad." "$LINENO" 5
4267 as_fn_error $? "Cannot find libfaad." "$LINENO" 5
36844268 fi
36854269 CPPFLAGS="$CPPFLAGS $FAAC_CPPFLAGS"
36864270 CFLAGS="$CFLAGS $FAAC_CFLAGS"
37964380 # Let make expand exec_prefix.
37974381 test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
37984382
3799 # Transform confdefs.h into DEFS.
3800 # Protect against shell expansion while executing Makefile rules.
3801 # Protect against Makefile macro expansion.
3802 #
3803 # If the first sed substitution is executed (which looks for macros that
3804 # take arguments), then branch to the quote section. Otherwise,
3805 # look for a macro that doesn't take arguments.
3806 ac_script='
3807 :mline
3808 /\\$/{
3809 N
3810 s,\\\n,,
3811 b mline
3812 }
3813 t clear
3814 :clear
3815 s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g
3816 t quote
3817 s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g
3818 t quote
3819 b any
3820 :quote
3821 s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g
3822 s/\[/\\&/g
3823 s/\]/\\&/g
3824 s/\$/$$/g
3825 H
3826 :any
3827 ${
3828 g
3829 s/^\n//
3830 s/\n/ /g
3831 p
3832 }
3833 '
3834 DEFS=`sed -n "$ac_script" confdefs.h`
3835
4383 DEFS=-DHAVE_CONFIG_H
38364384
38374385 ac_libobjs=
38384386 ac_ltlibobjs=
4387 U=
38394388 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
38404389 # 1. Remove the extension, and $U if already installed.
38414390 ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
39974546 (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
39984547
39994548
4000 # as_fn_error ERROR [LINENO LOG_FD]
4001 # ---------------------------------
4549 # as_fn_error STATUS ERROR [LINENO LOG_FD]
4550 # ----------------------------------------
40024551 # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
40034552 # provided, also output the error to LOG_FD, referencing LINENO. Then exit the
4004 # script with status $?, using 1 if that was 0.
4553 # script with STATUS, using 1 if that was 0.
40054554 as_fn_error ()
40064555 {
4007 as_status=$?; test $as_status -eq 0 && as_status=1
4008 if test "$3"; then
4009 as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
4010 $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
4011 fi
4012 $as_echo "$as_me: error: $1" >&2
4556 as_status=$1; test $as_status -eq 0 && as_status=1
4557 if test "$4"; then
4558 as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
4559 $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
4560 fi
4561 $as_echo "$as_me: error: $2" >&2
40134562 as_fn_exit $as_status
40144563 } # as_fn_error
40154564
42054754 test -d "$as_dir" && break
42064755 done
42074756 test -z "$as_dirs" || eval "mkdir $as_dirs"
4208 } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
4757 } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
42094758
42104759
42114760 } # as_fn_mkdir_p
42584807 # report actual input values of CONFIG_FILES etc. instead of their
42594808 # values after options handling.
42604809 ac_log="
4261 This file was extended by ocaml-faad $as_me 0.1.3, which was
4262 generated by GNU Autoconf 2.64. Invocation command line was
4810 This file was extended by ocaml-faad $as_me 0.2.0, which was
4811 generated by GNU Autoconf 2.67. Invocation command line was
42634812
42644813 CONFIG_FILES = $CONFIG_FILES
42654814 CONFIG_HEADERS = $CONFIG_HEADERS
42764825 "*) set x $ac_config_files; shift; ac_config_files=$*;;
42774826 esac
42784827
4828 case $ac_config_headers in *"
4829 "*) set x $ac_config_headers; shift; ac_config_headers=$*;;
4830 esac
42794831
42804832
42814833 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
42824834 # Files that config.status was made for.
42834835 config_files="$ac_config_files"
4836 config_headers="$ac_config_headers"
42844837
42854838 _ACEOF
42864839
42944847
42954848 -h, --help print this help, then exit
42964849 -V, --version print version number and configuration settings, then exit
4850 --config print configuration, then exit
42974851 -q, --quiet, --silent
42984852 do not print progress messages
42994853 -d, --debug don't remove temporary files
43004854 --recheck update $as_me by reconfiguring in the same conditions
43014855 --file=FILE[:TEMPLATE]
43024856 instantiate the configuration file FILE
4857 --header=FILE[:TEMPLATE]
4858 instantiate the configuration header FILE
43034859
43044860 Configuration files:
43054861 $config_files
43064862
4863 Configuration headers:
4864 $config_headers
4865
43074866 Report bugs to <savonet-users@lists.sourceforge.net>."
43084867
43094868 _ACEOF
43104869 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
4870 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
43114871 ac_cs_version="\\
4312 ocaml-faad config.status 0.1.3
4313 configured by $0, generated by GNU Autoconf 2.64,
4314 with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
4315
4316 Copyright (C) 2009 Free Software Foundation, Inc.
4872 ocaml-faad config.status 0.2.0
4873 configured by $0, generated by GNU Autoconf 2.67,
4874 with options \\"\$ac_cs_config\\"
4875
4876 Copyright (C) 2010 Free Software Foundation, Inc.
43174877 This config.status script is free software; the Free Software Foundation
43184878 gives unlimited permission to copy, distribute and modify it."
43194879
43284888 while test $# != 0
43294889 do
43304890 case $1 in
4331 --*=*)
4891 --*=?*)
43324892 ac_option=`expr "X$1" : 'X\([^=]*\)='`
43334893 ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
4894 ac_shift=:
4895 ;;
4896 --*=)
4897 ac_option=`expr "X$1" : 'X\([^=]*\)='`
4898 ac_optarg=
43344899 ac_shift=:
43354900 ;;
43364901 *)
43464911 ac_cs_recheck=: ;;
43474912 --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
43484913 $as_echo "$ac_cs_version"; exit ;;
4914 --config | --confi | --conf | --con | --co | --c )
4915 $as_echo "$ac_cs_config"; exit ;;
43494916 --debug | --debu | --deb | --de | --d | -d )
43504917 debug=: ;;
43514918 --file | --fil | --fi | --f )
43524919 $ac_shift
43534920 case $ac_optarg in
43544921 *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
4922 '') as_fn_error $? "missing file argument" ;;
43554923 esac
43564924 as_fn_append CONFIG_FILES " '$ac_optarg'"
43574925 ac_need_defaults=false;;
4358 --he | --h | --help | --hel | -h )
4926 --header | --heade | --head | --hea )
4927 $ac_shift
4928 case $ac_optarg in
4929 *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
4930 esac
4931 as_fn_append CONFIG_HEADERS " '$ac_optarg'"
4932 ac_need_defaults=false;;
4933 --he | --h)
4934 # Conflict between --help and --header
4935 as_fn_error $? "ambiguous option: \`$1'
4936 Try \`$0 --help' for more information.";;
4937 --help | --hel | -h )
43594938 $as_echo "$ac_cs_usage"; exit ;;
43604939 -q | -quiet | --quiet | --quie | --qui | --qu | --q \
43614940 | -silent | --silent | --silen | --sile | --sil | --si | --s)
43624941 ac_cs_silent=: ;;
43634942
43644943 # This is an error.
4365 -*) as_fn_error "unrecognized option: \`$1'
4944 -*) as_fn_error $? "unrecognized option: \`$1'
43664945 Try \`$0 --help' for more information." ;;
43674946
43684947 *) as_fn_append ac_config_targets " $1"
44114990 for ac_config_target in $ac_config_targets
44124991 do
44134992 case $ac_config_target in
4993 "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:config.h.in" ;;
44144994 "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
44154995 "src/META") CONFIG_FILES="$CONFIG_FILES src/META" ;;
44164996 "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
44174997
4418 *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
4998 *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
44194999 esac
44205000 done
44215001
44265006 # bizarre bug on SunOS 4.1.3.
44275007 if $ac_need_defaults; then
44285008 test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
5009 test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
44295010 fi
44305011
44315012 # Have a temporary directory for convenience. Make it in the build tree
44515032 {
44525033 tmp=./conf$$-$RANDOM
44535034 (umask 077 && mkdir "$tmp")
4454 } || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
5035 } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
44555036
44565037 # Set up the scripts for CONFIG_FILES section.
44575038 # No need to generate them if there are no CONFIG_FILES.
44685049 fi
44695050 ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
44705051 if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
4471 ac_cs_awk_cr='\r'
5052 ac_cs_awk_cr='\\r'
44725053 else
44735054 ac_cs_awk_cr=$ac_cr
44745055 fi
44825063 echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
44835064 echo "_ACEOF"
44845065 } >conf$$subs.sh ||
4485 as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
4486 ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
5066 as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
5067 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
44875068 ac_delim='%!_!# '
44885069 for ac_last_try in false false false false false :; do
44895070 . ./conf$$subs.sh ||
4490 as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
5071 as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
44915072
44925073 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
44935074 if test $ac_delim_n = $ac_delim_num; then
44945075 break
44955076 elif $ac_last_try; then
4496 as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
5077 as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
44975078 else
44985079 ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
44995080 fi
45155096 t delim
45165097 :nl
45175098 h
4518 s/\(.\{148\}\).*/\1/
5099 s/\(.\{148\}\)..*/\1/
45195100 t more1
45205101 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
45215102 p
45295110 t nl
45305111 :delim
45315112 h
4532 s/\(.\{148\}\).*/\1/
5113 s/\(.\{148\}\)..*/\1/
45335114 t more2
45345115 s/["\\]/\\&/g; s/^/"/; s/$/"/
45355116 p
45825163 else
45835164 cat
45845165 fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
4585 || as_fn_error "could not setup config files machinery" "$LINENO" 5
4586 _ACEOF
4587
4588 # VPATH may cause trouble with some makes, so we remove $(srcdir),
4589 # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
5166 || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
5167 _ACEOF
5168
5169 # VPATH may cause trouble with some makes, so we remove sole $(srcdir),
5170 # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
45905171 # trailing colons and then remove the whole line if VPATH becomes empty
45915172 # (actually we leave an empty line to preserve line numbers).
45925173 if test "x$srcdir" = x.; then
4593 ac_vpsub='/^[ ]*VPATH[ ]*=/{
4594 s/:*\$(srcdir):*/:/
4595 s/:*\${srcdir}:*/:/
4596 s/:*@srcdir@:*/:/
4597 s/^\([^=]*=[ ]*\):*/\1/
5174 ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
5175 h
5176 s///
5177 s/^/:/
5178 s/[ ]*$/:/
5179 s/:\$(srcdir):/:/g
5180 s/:\${srcdir}:/:/g
5181 s/:@srcdir@:/:/g
5182 s/^:*//
45985183 s/:*$//
5184 x
5185 s/\(=[ ]*\).*/\1/
5186 G
5187 s/\n//
45995188 s/^[^=]*=[ ]*$//
46005189 }'
46015190 fi
46035192 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
46045193 fi # test -n "$CONFIG_FILES"
46055194
4606
4607 eval set X " :F $CONFIG_FILES "
5195 # Set up the scripts for CONFIG_HEADERS section.
5196 # No need to generate them if there are no CONFIG_HEADERS.
5197 # This happens for instance with `./config.status Makefile'.
5198 if test -n "$CONFIG_HEADERS"; then
5199 cat >"$tmp/defines.awk" <<\_ACAWK ||
5200 BEGIN {
5201 _ACEOF
5202
5203 # Transform confdefs.h into an awk script `defines.awk', embedded as
5204 # here-document in config.status, that substitutes the proper values into
5205 # config.h.in to produce config.h.
5206
5207 # Create a delimiter string that does not exist in confdefs.h, to ease
5208 # handling of long lines.
5209 ac_delim='%!_!# '
5210 for ac_last_try in false false :; do
5211 ac_t=`sed -n "/$ac_delim/p" confdefs.h`
5212 if test -z "$ac_t"; then
5213 break
5214 elif $ac_last_try; then
5215 as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
5216 else
5217 ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
5218 fi
5219 done
5220
5221 # For the awk script, D is an array of macro values keyed by name,
5222 # likewise P contains macro parameters if any. Preserve backslash
5223 # newline sequences.
5224
5225 ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
5226 sed -n '
5227 s/.\{148\}/&'"$ac_delim"'/g
5228 t rset
5229 :rset
5230 s/^[ ]*#[ ]*define[ ][ ]*/ /
5231 t def
5232 d
5233 :def
5234 s/\\$//
5235 t bsnl
5236 s/["\\]/\\&/g
5237 s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
5238 D["\1"]=" \3"/p
5239 s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
5240 d
5241 :bsnl
5242 s/["\\]/\\&/g
5243 s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
5244 D["\1"]=" \3\\\\\\n"\\/p
5245 t cont
5246 s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
5247 t cont
5248 d
5249 :cont
5250 n
5251 s/.\{148\}/&'"$ac_delim"'/g
5252 t clear
5253 :clear
5254 s/\\$//
5255 t bsnlc
5256 s/["\\]/\\&/g; s/^/"/; s/$/"/p
5257 d
5258 :bsnlc
5259 s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
5260 b cont
5261 ' <confdefs.h | sed '
5262 s/'"$ac_delim"'/"\\\
5263 "/g' >>$CONFIG_STATUS || ac_write_fail=1
5264
5265 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
5266 for (key in D) D_is_set[key] = 1
5267 FS = ""
5268 }
5269 /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
5270 line = \$ 0
5271 split(line, arg, " ")
5272 if (arg[1] == "#") {
5273 defundef = arg[2]
5274 mac1 = arg[3]
5275 } else {
5276 defundef = substr(arg[1], 2)
5277 mac1 = arg[2]
5278 }
5279 split(mac1, mac2, "(") #)
5280 macro = mac2[1]
5281 prefix = substr(line, 1, index(line, defundef) - 1)
5282 if (D_is_set[macro]) {
5283 # Preserve the white space surrounding the "#".
5284 print prefix "define", macro P[macro] D[macro]
5285 next
5286 } else {
5287 # Replace #undef with comments. This is necessary, for example,
5288 # in the case of _POSIX_SOURCE, which is predefined and required
5289 # on some systems where configure will not decide to define it.
5290 if (defundef == "undef") {
5291 print "/*", prefix defundef, macro, "*/"
5292 next
5293 }
5294 }
5295 }
5296 { print }
5297 _ACAWK
5298 _ACEOF
5299 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
5300 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
5301 fi # test -n "$CONFIG_HEADERS"
5302
5303
5304 eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS "
46085305 shift
46095306 for ac_tag
46105307 do
46135310 esac
46145311 case $ac_mode$ac_tag in
46155312 :[FHL]*:*);;
4616 :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
5313 :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;;
46175314 :[FH]-) ac_tag=-:-;;
46185315 :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
46195316 esac
46415338 [\\/$]*) false;;
46425339 *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
46435340 esac ||
4644 as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
5341 as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;;
46455342 esac
46465343 case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
46475344 as_fn_append ac_file_inputs " '$ac_f'"
46685365
46695366 case $ac_tag in
46705367 *:-:* | *:-) cat >"$tmp/stdin" \
4671 || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
5368 || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
46725369 esac
46735370 ;;
46745371 esac
47945491 $ac_datarootdir_hack
47955492 "
47965493 eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
4797 || as_fn_error "could not create $ac_file" "$LINENO" 5
5494 || as_fn_error $? "could not create $ac_file" "$LINENO" 5
47985495
47995496 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
48005497 { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
48015498 { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
48025499 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
4803 which seems to be undefined. Please make sure it is defined." >&5
5500 which seems to be undefined. Please make sure it is defined" >&5
48045501 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
4805 which seems to be undefined. Please make sure it is defined." >&2;}
5502 which seems to be undefined. Please make sure it is defined" >&2;}
48065503
48075504 rm -f "$tmp/stdin"
48085505 case $ac_file in
48095506 -) cat "$tmp/out" && rm -f "$tmp/out";;
48105507 *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
48115508 esac \
4812 || as_fn_error "could not create $ac_file" "$LINENO" 5
5509 || as_fn_error $? "could not create $ac_file" "$LINENO" 5
48135510 ;;
4814
5511 :H)
5512 #
5513 # CONFIG_HEADER
5514 #
5515 if test x"$ac_file" != x-; then
5516 {
5517 $as_echo "/* $configure_input */" \
5518 && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
5519 } >"$tmp/config.h" \
5520 || as_fn_error $? "could not create $ac_file" "$LINENO" 5
5521 if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
5522 { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
5523 $as_echo "$as_me: $ac_file is unchanged" >&6;}
5524 else
5525 rm -f "$ac_file"
5526 mv "$tmp/config.h" "$ac_file" \
5527 || as_fn_error $? "could not create $ac_file" "$LINENO" 5
5528 fi
5529 else
5530 $as_echo "/* $configure_input */" \
5531 && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
5532 || as_fn_error $? "could not create -" "$LINENO" 5
5533 fi
5534 ;;
48155535
48165536
48175537 esac
48295549 ac_clean_files=$ac_clean_files_save
48305550
48315551 test $ac_write_fail = 0 ||
4832 as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
5552 as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
48335553
48345554
48355555 # configure is writing to config.log, and then calls config.status.
48505570 exec 5>>config.log
48515571 # Use ||, not &&, to avoid exiting from the if with $? = 1, which
48525572 # would make configure fail if this is the last instruction.
4853 $ac_cs_success || as_fn_exit $?
5573 $ac_cs_success || as_fn_exit 1
48545574 fi
48555575 if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
48565576 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
00
11 # check for one particular file of the sources
2 AC_INIT(ocaml-faad, 0.1.3, savonet-users@lists.sourceforge.net)
2 AC_INIT(ocaml-faad, 0.2.0, savonet-users@lists.sourceforge.net)
33
44 VERSION=$PACKAGE_VERSION
55 AC_MSG_RESULT([configuring $PACKAGE_STRING])
1111 LDFLAGS="$LDFLAGS -L$prefix/lib"
1212 CPPFLAGS="$CPPFLAGS -I$prefix/include"
1313 fi
14
15 # Include a config.h
16 AC_CONFIG_HEADERS([config.h:config.h.in])
17 # Include it
18 CFLAGS="$CFLAGS -I`pwd`/`dirname $0` -DHAVE_CONFIG_H"
19
20 AC_CHECK_HEADERS([errno.h])
1421
1522 OCAMLFIND_LDCONF=""
1623 AC_ARG_ENABLE([ldconf], AC_HELP_STRING([--disable-ldconf],[don't modify the dynamic loader configuration file (default is enable)]),[ac_enable_ldconf=$enableval],[ac_enable_ldconf=$enableval],[ac_enable_ldconf=yes])
2222 PS2PDF = @PS2PDF@
2323 OCAMLLIBPATH = @CAMLLIBPATH@
2424
25 SOURCES = faad.mli faad.ml faad_stubs.c
25 SOURCES = faad.mli faad.ml faad_stubs.c drms.c mp4atom.c mp4ff.c mp4meta.c \
26 mp4sample.c mp4tagupdate.c mp4util.c
2627 RESULT = faad
2728 OCAMLDOCFLAGS = -stars
2829 LIBINSTALL_FILES = $(wildcard *.mli *.cmi *.cma *.cmxa *.cmx *.a *.so)
2930 LDFLAGS = @LDFLAGS@
30 ACLIBS = @LIBS@ -lmp4ff
31 ACLIBS = @LIBS@
3132 CLIBS = $(ACLIBS:-l%=%)
3233 LIBDIRS = $(LDFLAGS:-L%=%)
3334 CC = @CC@
34 CFLAGS = @CFLAGS@ -Wall -DCAML_NAME_SPACE
35 CFLAGS = @CFLAGS@ -Wall -DCAML_NAME_SPACE -DUSE_TAGGING -DITUNES_DRM
3536 CPPFLAGS = @CPPFLAGS@
3637 NO_CUSTOM = yes
3738 OCAMLFLAGS = @OCAMLFLAGS@
0 /*****************************************************************************
1 * drms.c: DRMS
2 *****************************************************************************
3 * Copyright (C) 2004 VideoLAN
4 * $Id: drms.c,v 1.7 2005/02/01 13:15:55 menno Exp $
5 *
6 * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
7 * Sam Hocevar <sam@zoy.org>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
23
24 #include <stdlib.h> /* malloc(), free() */
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 #include "mp4ffint.h"
30
31 #ifdef ITUNES_DRM
32
33 #ifdef _WIN32
34 # include <io.h>
35 # include <stdio.h>
36 # include <sys/stat.h>
37 # define PATH_MAX MAX_PATH
38 #else
39 # include <stdio.h>
40 #endif
41
42 #ifdef HAVE_ERRNO_H
43 # include <errno.h>
44 #endif
45
46 #ifdef HAVE_STRING_H
47 # include <string.h>
48 #endif
49
50 #ifdef _WIN32
51 # include <tchar.h>
52 # include <shlobj.h>
53 # include <windows.h>
54 #endif
55
56 #ifdef HAVE_SYS_STAT_H
57 # include <sys/stat.h>
58 #endif
59 #ifdef HAVE_SYS_TYPES_H
60 # include <sys/types.h>
61 #endif
62
63 /* In Solaris (and perhaps others) PATH_MAX is in limits.h. */
64 #ifdef HAVE_LIMITS_H
65 # include <limits.h>
66 #endif
67
68 #ifdef HAVE_IOKIT_IOKITLIB_H
69 # include <mach/mach.h>
70 # include <IOKit/IOKitLib.h>
71 # include <CoreFoundation/CFNumber.h>
72 #endif
73
74 #ifdef HAVE_SYSFS_LIBSYSFS_H
75 # include <sysfs/libsysfs.h>
76 #endif
77
78 #define XMMS_PATH_MAX 255
79
80 #include "drms.h"
81 #include "drmstables.h"
82
83 /*****************************************************************************
84 * aes_s: AES keys structure
85 *****************************************************************************
86 * This structure stores a set of keys usable for encryption and decryption
87 * with the AES/Rijndael algorithm.
88 *****************************************************************************/
89 struct aes_s
90 {
91 uint32_t pp_enc_keys[ AES_KEY_COUNT + 1 ][ 4 ];
92 uint32_t pp_dec_keys[ AES_KEY_COUNT + 1 ][ 4 ];
93 };
94
95 /*****************************************************************************
96 * md5_s: MD5 message structure
97 *****************************************************************************
98 * This structure stores the static information needed to compute an MD5
99 * hash. It has an extra data buffer to allow non-aligned writes.
100 *****************************************************************************/
101 struct md5_s
102 {
103 uint64_t i_bits; /* Total written bits */
104 uint32_t p_digest[4]; /* The MD5 digest */
105 uint32_t p_data[16]; /* Buffer to cache non-aligned writes */
106 };
107
108 /*****************************************************************************
109 * shuffle_s: shuffle structure
110 *****************************************************************************
111 * This structure stores the static information needed to shuffle data using
112 * a custom algorithm.
113 *****************************************************************************/
114 struct shuffle_s
115 {
116 uint32_t p_commands[ 20 ];
117 uint32_t p_bordel[ 16 ];
118 };
119
120 /*****************************************************************************
121 * drms_s: DRMS structure
122 *****************************************************************************
123 * This structure stores the static information needed to decrypt DRMS data.
124 *****************************************************************************/
125 struct drms_s
126 {
127 uint32_t i_user;
128 uint32_t i_key;
129 uint8_t p_iviv[ 16 ];
130 uint8_t *p_name;
131
132 uint32_t p_key[ 4 ];
133 struct aes_s aes;
134
135 char psz_homedir[ XMMS_PATH_MAX ];
136 };
137
138 /*****************************************************************************
139 * Local prototypes
140 *****************************************************************************/
141 static void InitAES ( struct aes_s *, uint32_t * );
142 static void DecryptAES ( struct aes_s *, uint32_t *, const uint32_t * );
143
144 static void InitMD5 ( struct md5_s * );
145 static void AddMD5 ( struct md5_s *, const uint8_t *, uint32_t );
146 static void EndMD5 ( struct md5_s * );
147 static void Digest ( struct md5_s *, uint32_t * );
148
149 static void InitShuffle ( struct shuffle_s *, uint32_t * );
150 static void DoShuffle ( struct shuffle_s *, uint32_t *, uint32_t );
151
152 static int GetSystemKey ( uint32_t *, uint32_t );
153 static int WriteUserKey ( void *, uint32_t * );
154 static int ReadUserKey ( void *, uint32_t * );
155 static int GetUserKey ( void *, uint32_t * );
156
157 static int GetSCIData ( char *, uint32_t **, uint32_t * );
158 static int HashSystemInfo ( uint32_t * );
159 static int GetiPodID ( int64_t * );
160
161 #ifdef WORDS_BIGENDIAN
162 /*****************************************************************************
163 * Reverse: reverse byte order
164 *****************************************************************************/
165 static __inline void Reverse( uint32_t *p_buffer, int n )
166 {
167 int i;
168
169 for( i = 0; i < n; i++ )
170 {
171 p_buffer[ i ] = GetDWLE(&p_buffer[ i ]);
172 }
173 }
174 # define REVERSE( p, n ) Reverse( p, n )
175 #else
176 # define REVERSE( p, n )
177 #endif
178
179 /*****************************************************************************
180 * BlockXOR: XOR two 128 bit blocks
181 *****************************************************************************/
182 static __inline void BlockXOR( uint32_t *p_dest, uint32_t *p_s1, uint32_t *p_s2 )
183 {
184 int i;
185
186 for( i = 0; i < 4; i++ )
187 {
188 p_dest[ i ] = p_s1[ i ] ^ p_s2[ i ];
189 }
190 }
191
192 /*****************************************************************************
193 * drms_alloc: allocate a DRMS structure
194 *****************************************************************************/
195 void *drms_alloc( char *psz_homedir )
196 {
197 struct drms_s *p_drms;
198
199 p_drms = malloc( sizeof(struct drms_s) );
200
201 if( p_drms == NULL )
202 {
203 return NULL;
204 }
205
206 memset( p_drms, 0, sizeof(struct drms_s) );
207
208 strncpy( p_drms->psz_homedir, psz_homedir, XMMS_PATH_MAX );
209 p_drms->psz_homedir[ XMMS_PATH_MAX - 1 ] = '\0';
210
211 return (void *)p_drms;
212 }
213
214 /*****************************************************************************
215 * drms_free: free a previously allocated DRMS structure
216 *****************************************************************************/
217 void drms_free( void *_p_drms )
218 {
219 struct drms_s *p_drms = (struct drms_s *)_p_drms;
220
221 if( p_drms->p_name != NULL )
222 {
223 free( (void *)p_drms->p_name );
224 }
225
226 free( p_drms );
227 }
228
229 /*****************************************************************************
230 * drms_decrypt: unscramble a chunk of data
231 *****************************************************************************/
232 void drms_decrypt( void *_p_drms, uint32_t *p_buffer, uint32_t i_bytes )
233 {
234 struct drms_s *p_drms = (struct drms_s *)_p_drms;
235 uint32_t p_key[ 4 ];
236 unsigned int i_blocks;
237
238 /* AES is a block cypher, round down the byte count */
239 i_blocks = i_bytes / 16;
240 i_bytes = i_blocks * 16;
241
242 /* Initialise the key */
243 memcpy( p_key, p_drms->p_key, 16 );
244
245 /* Unscramble */
246 while( i_blocks-- )
247 {
248 uint32_t p_tmp[ 4 ];
249
250 REVERSE( p_buffer, 4 );
251 DecryptAES( &p_drms->aes, p_tmp, p_buffer );
252 BlockXOR( p_tmp, p_key, p_tmp );
253
254 /* Use the previous scrambled data as the key for next block */
255 memcpy( p_key, p_buffer, 16 );
256
257 /* Copy unscrambled data back to the buffer */
258 memcpy( p_buffer, p_tmp, 16 );
259 REVERSE( p_buffer, 4 );
260
261 p_buffer += 4;
262 }
263 }
264
265 /*****************************************************************************
266 * drms_init: initialise a DRMS structure
267 *****************************************************************************/
268 int drms_init( void *_p_drms, uint32_t i_type,
269 uint8_t *p_info, uint32_t i_len )
270 {
271 struct drms_s *p_drms = (struct drms_s *)_p_drms;
272 int i_ret = 0;
273
274 switch( i_type )
275 {
276 case FOURCC_user:
277 if( i_len < sizeof(p_drms->i_user) )
278 {
279 i_ret = -1;
280 break;
281 }
282
283 p_drms->i_user = U32_AT( p_info );
284 break;
285
286 case FOURCC_key:
287 if( i_len < sizeof(p_drms->i_key) )
288 {
289 i_ret = -1;
290 break;
291 }
292
293 p_drms->i_key = U32_AT( p_info );
294 break;
295
296 case FOURCC_iviv:
297 if( i_len < sizeof(p_drms->p_key) )
298 {
299 i_ret = -1;
300 break;
301 }
302
303 memcpy( p_drms->p_iviv, p_info, 16 );
304 break;
305
306 case FOURCC_name:
307 p_drms->p_name = (uint8_t *) strdup( (char *) p_info );
308
309 if( p_drms->p_name == NULL )
310 {
311 i_ret = -1;
312 }
313 break;
314
315 case FOURCC_priv:
316 {
317 uint32_t p_priv[ 64 ];
318 struct md5_s md5;
319
320 if( i_len < 64 )
321 {
322 i_ret = -1;
323 break;
324 }
325
326 InitMD5( &md5 );
327 AddMD5( &md5, p_drms->p_name, strlen( (char *) p_drms->p_name ) );
328 AddMD5( &md5, p_drms->p_iviv, 16 );
329 EndMD5( &md5 );
330
331 if( GetUserKey( p_drms, p_drms->p_key ) )
332 {
333 i_ret = -1;
334 break;
335 }
336
337 InitAES( &p_drms->aes, p_drms->p_key );
338
339 memcpy( p_priv, p_info, 64 );
340 memcpy( p_drms->p_key, md5.p_digest, 16 );
341 drms_decrypt( p_drms, p_priv, 64 );
342 REVERSE( p_priv, 64 );
343
344 if( p_priv[ 0 ] != 0x6e757469 ) /* itun */
345 {
346 i_ret = -1;
347 break;
348 }
349
350 InitAES( &p_drms->aes, p_priv + 6 );
351 memcpy( p_drms->p_key, p_priv + 12, 16 );
352
353 free( (void *)p_drms->p_name );
354 p_drms->p_name = NULL;
355 }
356 break;
357 }
358
359 return i_ret;
360 }
361
362 /* The following functions are local */
363
364 /*****************************************************************************
365 * InitAES: initialise AES/Rijndael encryption/decryption tables
366 *****************************************************************************
367 * The Advanced Encryption Standard (AES) is described in RFC 3268
368 *****************************************************************************/
369 static void InitAES( struct aes_s *p_aes, uint32_t *p_key )
370 {
371 unsigned int i, t;
372 uint32_t i_key, i_seed;
373
374 memset( p_aes->pp_enc_keys[1], 0, 16 );
375 memcpy( p_aes->pp_enc_keys[0], p_key, 16 );
376
377 /* Generate the key tables */
378 i_seed = p_aes->pp_enc_keys[ 0 ][ 3 ];
379
380 for( i_key = 0; i_key < AES_KEY_COUNT; i_key++ )
381 {
382 uint32_t j;
383
384 i_seed = AES_ROR( i_seed, 8 );
385
386 j = p_aes_table[ i_key ];
387
388 j ^= p_aes_encrypt[ (i_seed >> 24) & 0xff ]
389 ^ AES_ROR( p_aes_encrypt[ (i_seed >> 16) & 0xff ], 8 )
390 ^ AES_ROR( p_aes_encrypt[ (i_seed >> 8) & 0xff ], 16 )
391 ^ AES_ROR( p_aes_encrypt[ i_seed & 0xff ], 24 );
392
393 j ^= p_aes->pp_enc_keys[ i_key ][ 0 ];
394 p_aes->pp_enc_keys[ i_key + 1 ][ 0 ] = j;
395 j ^= p_aes->pp_enc_keys[ i_key ][ 1 ];
396 p_aes->pp_enc_keys[ i_key + 1 ][ 1 ] = j;
397 j ^= p_aes->pp_enc_keys[ i_key ][ 2 ];
398 p_aes->pp_enc_keys[ i_key + 1 ][ 2 ] = j;
399 j ^= p_aes->pp_enc_keys[ i_key ][ 3 ];
400 p_aes->pp_enc_keys[ i_key + 1 ][ 3 ] = j;
401
402 i_seed = j;
403 }
404
405 memcpy( p_aes->pp_dec_keys[ 0 ],
406 p_aes->pp_enc_keys[ 0 ], 16 );
407
408 for( i = 1; i < AES_KEY_COUNT; i++ )
409 {
410 for( t = 0; t < 4; t++ )
411 {
412 uint32_t j, k, l, m, n;
413
414 j = p_aes->pp_enc_keys[ i ][ t ];
415
416 k = (((j >> 7) & 0x01010101) * 27) ^ ((j & 0xff7f7f7f) << 1);
417 l = (((k >> 7) & 0x01010101) * 27) ^ ((k & 0xff7f7f7f) << 1);
418 m = (((l >> 7) & 0x01010101) * 27) ^ ((l & 0xff7f7f7f) << 1);
419
420 j ^= m;
421
422 n = AES_ROR( l ^ j, 16 ) ^ AES_ROR( k ^ j, 8 ) ^ AES_ROR( j, 24 );
423
424 p_aes->pp_dec_keys[ i ][ t ] = k ^ l ^ m ^ n;
425 }
426 }
427 }
428
429 /*****************************************************************************
430 * DecryptAES: decrypt an AES/Rijndael 128 bit block
431 *****************************************************************************/
432 static void DecryptAES( struct aes_s *p_aes,
433 uint32_t *p_dest, const uint32_t *p_src )
434 {
435 uint32_t p_wtxt[ 4 ]; /* Working cyphertext */
436 uint32_t p_tmp[ 4 ];
437 unsigned int i_round, t;
438
439 for( t = 0; t < 4; t++ )
440 {
441 /* FIXME: are there any endianness issues here? */
442 p_wtxt[ t ] = p_src[ t ] ^ p_aes->pp_enc_keys[ AES_KEY_COUNT ][ t ];
443 }
444
445 /* Rounds 0 - 8 */
446 for( i_round = 0; i_round < (AES_KEY_COUNT - 1); i_round++ )
447 {
448 for( t = 0; t < 4; t++ )
449 {
450 p_tmp[ t ] = AES_XOR_ROR( p_aes_itable, p_wtxt );
451 }
452
453 for( t = 0; t < 4; t++ )
454 {
455 p_wtxt[ t ] = p_tmp[ t ]
456 ^ p_aes->pp_dec_keys[ (AES_KEY_COUNT - 1) - i_round ][ t ];
457 }
458 }
459
460 /* Final round (9) */
461 for( t = 0; t < 4; t++ )
462 {
463 p_dest[ t ] = AES_XOR_ROR( p_aes_decrypt, p_wtxt );
464 p_dest[ t ] ^= p_aes->pp_dec_keys[ 0 ][ t ];
465 }
466 }
467
468 /*****************************************************************************
469 * InitMD5: initialise an MD5 message
470 *****************************************************************************
471 * The MD5 message-digest algorithm is described in RFC 1321
472 *****************************************************************************/
473 static void InitMD5( struct md5_s *p_md5 )
474 {
475 p_md5->p_digest[ 0 ] = 0x67452301;
476 p_md5->p_digest[ 1 ] = 0xefcdab89;
477 p_md5->p_digest[ 2 ] = 0x98badcfe;
478 p_md5->p_digest[ 3 ] = 0x10325476;
479
480 memset( p_md5->p_data, 0, 64 );
481 p_md5->i_bits = 0;
482 }
483
484 /*****************************************************************************
485 * AddMD5: add i_len bytes to an MD5 message
486 *****************************************************************************/
487 static void AddMD5( struct md5_s *p_md5, const uint8_t *p_src, uint32_t i_len )
488 {
489 unsigned int i_current; /* Current bytes in the spare buffer */
490 unsigned int i_offset = 0;
491
492 i_current = (p_md5->i_bits / 8) & 63;
493
494 p_md5->i_bits += 8 * i_len;
495
496 /* If we can complete our spare buffer to 64 bytes, do it and add the
497 * resulting buffer to the MD5 message */
498 if( i_len >= (64 - i_current) )
499 {
500 memcpy( ((uint8_t *)p_md5->p_data) + i_current, p_src,
501 (64 - i_current) );
502 Digest( p_md5, p_md5->p_data );
503
504 i_offset += (64 - i_current);
505 i_len -= (64 - i_current);
506 i_current = 0;
507 }
508
509 /* Add as many entire 64 bytes blocks as we can to the MD5 message */
510 while( i_len >= 64 )
511 {
512 uint32_t p_tmp[ 16 ];
513 memcpy( p_tmp, p_src + i_offset, 64 );
514 Digest( p_md5, p_tmp );
515 i_offset += 64;
516 i_len -= 64;
517 }
518
519 /* Copy our remaining data to the message's spare buffer */
520 memcpy( ((uint8_t *)p_md5->p_data) + i_current, p_src + i_offset, i_len );
521 }
522
523 /*****************************************************************************
524 * EndMD5: finish an MD5 message
525 *****************************************************************************
526 * This function adds adequate padding to the end of the message, and appends
527 * the bit count so that we end at a block boundary.
528 *****************************************************************************/
529 static void EndMD5( struct md5_s *p_md5 )
530 {
531 unsigned int i_current;
532
533 i_current = (p_md5->i_bits / 8) & 63;
534
535 /* Append 0x80 to our buffer. No boundary check because the temporary
536 * buffer cannot be full, otherwise AddMD5 would have emptied it. */
537 ((uint8_t *)p_md5->p_data)[ i_current++ ] = 0x80;
538
539 /* If less than 8 bytes are available at the end of the block, complete
540 * this 64 bytes block with zeros and add it to the message. We'll add
541 * our length at the end of the next block. */
542 if( i_current > 56 )
543 {
544 memset( ((uint8_t *)p_md5->p_data) + i_current, 0, (64 - i_current) );
545 Digest( p_md5, p_md5->p_data );
546 i_current = 0;
547 }
548
549 /* Fill the unused space in our last block with zeroes and put the
550 * message length at the end. */
551 memset( ((uint8_t *)p_md5->p_data) + i_current, 0, (56 - i_current) );
552 p_md5->p_data[ 14 ] = p_md5->i_bits & 0xffffffff;
553 p_md5->p_data[ 15 ] = (p_md5->i_bits >> 32);
554 REVERSE( &p_md5->p_data[ 14 ], 2 );
555
556 Digest( p_md5, p_md5->p_data );
557 }
558
559 #define F1( x, y, z ) ((z) ^ ((x) & ((y) ^ (z))))
560 #define F2( x, y, z ) F1((z), (x), (y))
561 #define F3( x, y, z ) ((x) ^ (y) ^ (z))
562 #define F4( x, y, z ) ((y) ^ ((x) | ~(z)))
563
564 #define MD5_DO( f, w, x, y, z, data, s ) \
565 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
566
567 /*****************************************************************************
568 * Digest: update the MD5 digest with 64 bytes of data
569 *****************************************************************************/
570 static void Digest( struct md5_s *p_md5, uint32_t *p_input )
571 {
572 uint32_t a, b, c, d;
573
574 REVERSE( p_input, 16 );
575
576 a = p_md5->p_digest[ 0 ];
577 b = p_md5->p_digest[ 1 ];
578 c = p_md5->p_digest[ 2 ];
579 d = p_md5->p_digest[ 3 ];
580
581 MD5_DO( F1, a, b, c, d, p_input[ 0 ] + 0xd76aa478, 7 );
582 MD5_DO( F1, d, a, b, c, p_input[ 1 ] + 0xe8c7b756, 12 );
583 MD5_DO( F1, c, d, a, b, p_input[ 2 ] + 0x242070db, 17 );
584 MD5_DO( F1, b, c, d, a, p_input[ 3 ] + 0xc1bdceee, 22 );
585 MD5_DO( F1, a, b, c, d, p_input[ 4 ] + 0xf57c0faf, 7 );
586 MD5_DO( F1, d, a, b, c, p_input[ 5 ] + 0x4787c62a, 12 );
587 MD5_DO( F1, c, d, a, b, p_input[ 6 ] + 0xa8304613, 17 );
588 MD5_DO( F1, b, c, d, a, p_input[ 7 ] + 0xfd469501, 22 );
589 MD5_DO( F1, a, b, c, d, p_input[ 8 ] + 0x698098d8, 7 );
590 MD5_DO( F1, d, a, b, c, p_input[ 9 ] + 0x8b44f7af, 12 );
591 MD5_DO( F1, c, d, a, b, p_input[ 10 ] + 0xffff5bb1, 17 );
592 MD5_DO( F1, b, c, d, a, p_input[ 11 ] + 0x895cd7be, 22 );
593 MD5_DO( F1, a, b, c, d, p_input[ 12 ] + 0x6b901122, 7 );
594 MD5_DO( F1, d, a, b, c, p_input[ 13 ] + 0xfd987193, 12 );
595 MD5_DO( F1, c, d, a, b, p_input[ 14 ] + 0xa679438e, 17 );
596 MD5_DO( F1, b, c, d, a, p_input[ 15 ] + 0x49b40821, 22 );
597
598 MD5_DO( F2, a, b, c, d, p_input[ 1 ] + 0xf61e2562, 5 );
599 MD5_DO( F2, d, a, b, c, p_input[ 6 ] + 0xc040b340, 9 );
600 MD5_DO( F2, c, d, a, b, p_input[ 11 ] + 0x265e5a51, 14 );
601 MD5_DO( F2, b, c, d, a, p_input[ 0 ] + 0xe9b6c7aa, 20 );
602 MD5_DO( F2, a, b, c, d, p_input[ 5 ] + 0xd62f105d, 5 );
603 MD5_DO( F2, d, a, b, c, p_input[ 10 ] + 0x02441453, 9 );
604 MD5_DO( F2, c, d, a, b, p_input[ 15 ] + 0xd8a1e681, 14 );
605 MD5_DO( F2, b, c, d, a, p_input[ 4 ] + 0xe7d3fbc8, 20 );
606 MD5_DO( F2, a, b, c, d, p_input[ 9 ] + 0x21e1cde6, 5 );
607 MD5_DO( F2, d, a, b, c, p_input[ 14 ] + 0xc33707d6, 9 );
608 MD5_DO( F2, c, d, a, b, p_input[ 3 ] + 0xf4d50d87, 14 );
609 MD5_DO( F2, b, c, d, a, p_input[ 8 ] + 0x455a14ed, 20 );
610 MD5_DO( F2, a, b, c, d, p_input[ 13 ] + 0xa9e3e905, 5 );
611 MD5_DO( F2, d, a, b, c, p_input[ 2 ] + 0xfcefa3f8, 9 );
612 MD5_DO( F2, c, d, a, b, p_input[ 7 ] + 0x676f02d9, 14 );
613 MD5_DO( F2, b, c, d, a, p_input[ 12 ] + 0x8d2a4c8a, 20 );
614
615 MD5_DO( F3, a, b, c, d, p_input[ 5 ] + 0xfffa3942, 4 );
616 MD5_DO( F3, d, a, b, c, p_input[ 8 ] + 0x8771f681, 11 );
617 MD5_DO( F3, c, d, a, b, p_input[ 11 ] + 0x6d9d6122, 16 );
618 MD5_DO( F3, b, c, d, a, p_input[ 14 ] + 0xfde5380c, 23 );
619 MD5_DO( F3, a, b, c, d, p_input[ 1 ] + 0xa4beea44, 4 );
620 MD5_DO( F3, d, a, b, c, p_input[ 4 ] + 0x4bdecfa9, 11 );
621 MD5_DO( F3, c, d, a, b, p_input[ 7 ] + 0xf6bb4b60, 16 );
622 MD5_DO( F3, b, c, d, a, p_input[ 10 ] + 0xbebfbc70, 23 );
623 MD5_DO( F3, a, b, c, d, p_input[ 13 ] + 0x289b7ec6, 4 );
624 MD5_DO( F3, d, a, b, c, p_input[ 0 ] + 0xeaa127fa, 11 );
625 MD5_DO( F3, c, d, a, b, p_input[ 3 ] + 0xd4ef3085, 16 );
626 MD5_DO( F3, b, c, d, a, p_input[ 6 ] + 0x04881d05, 23 );
627 MD5_DO( F3, a, b, c, d, p_input[ 9 ] + 0xd9d4d039, 4 );
628 MD5_DO( F3, d, a, b, c, p_input[ 12 ] + 0xe6db99e5, 11 );
629 MD5_DO( F3, c, d, a, b, p_input[ 15 ] + 0x1fa27cf8, 16 );
630 MD5_DO( F3, b, c, d, a, p_input[ 2 ] + 0xc4ac5665, 23 );
631
632 MD5_DO( F4, a, b, c, d, p_input[ 0 ] + 0xf4292244, 6 );
633 MD5_DO( F4, d, a, b, c, p_input[ 7 ] + 0x432aff97, 10 );
634 MD5_DO( F4, c, d, a, b, p_input[ 14 ] + 0xab9423a7, 15 );
635 MD5_DO( F4, b, c, d, a, p_input[ 5 ] + 0xfc93a039, 21 );
636 MD5_DO( F4, a, b, c, d, p_input[ 12 ] + 0x655b59c3, 6 );
637 MD5_DO( F4, d, a, b, c, p_input[ 3 ] + 0x8f0ccc92, 10 );
638 MD5_DO( F4, c, d, a, b, p_input[ 10 ] + 0xffeff47d, 15 );
639 MD5_DO( F4, b, c, d, a, p_input[ 1 ] + 0x85845dd1, 21 );
640 MD5_DO( F4, a, b, c, d, p_input[ 8 ] + 0x6fa87e4f, 6 );
641 MD5_DO( F4, d, a, b, c, p_input[ 15 ] + 0xfe2ce6e0, 10 );
642 MD5_DO( F4, c, d, a, b, p_input[ 6 ] + 0xa3014314, 15 );
643 MD5_DO( F4, b, c, d, a, p_input[ 13 ] + 0x4e0811a1, 21 );
644 MD5_DO( F4, a, b, c, d, p_input[ 4 ] + 0xf7537e82, 6 );
645 MD5_DO( F4, d, a, b, c, p_input[ 11 ] + 0xbd3af235, 10 );
646 MD5_DO( F4, c, d, a, b, p_input[ 2 ] + 0x2ad7d2bb, 15 );
647 MD5_DO( F4, b, c, d, a, p_input[ 9 ] + 0xeb86d391, 21 );
648
649 p_md5->p_digest[ 0 ] += a;
650 p_md5->p_digest[ 1 ] += b;
651 p_md5->p_digest[ 2 ] += c;
652 p_md5->p_digest[ 3 ] += d;
653 }
654
655 /*****************************************************************************
656 * InitShuffle: initialise a shuffle structure
657 *****************************************************************************
658 * This function initialises tables in the p_shuffle structure that will be
659 * used later by DoShuffle. The only external parameter is p_sys_key.
660 *****************************************************************************/
661 static void InitShuffle( struct shuffle_s *p_shuffle, uint32_t *p_sys_key )
662 {
663 char p_secret1[] = "Tv!*";
664 static char const p_secret2[] = "v8rhvsaAvOKMFfUH%798=[;."
665 "f8677680a634ba87fnOIf)(*";
666 unsigned int i;
667
668 /* Fill p_commands using the key and a secret seed */
669 for( i = 0; i < 20; i++ )
670 {
671 struct md5_s md5;
672 int32_t i_hash;
673
674 InitMD5( &md5 );
675 AddMD5( &md5, (uint8_t *)p_sys_key, 16 );
676 AddMD5( &md5, (uint8_t *)p_secret1, 4 );
677 EndMD5( &md5 );
678
679 p_secret1[ 3 ]++;
680
681 REVERSE( md5.p_digest, 1 );
682 i_hash = ((int32_t)U32_AT(md5.p_digest)) % 1024;
683
684 p_shuffle->p_commands[ i ] = i_hash < 0 ? i_hash * -1 : i_hash;
685 }
686
687 /* Fill p_bordel with completely meaningless initial values. */
688 for( i = 0; i < 4; i++ )
689 {
690 p_shuffle->p_bordel[ 4 * i ] = U32_AT(p_sys_key + i);
691 memcpy( p_shuffle->p_bordel + 4 * i + 1, p_secret2 + 12 * i, 12 );
692 REVERSE( p_shuffle->p_bordel + 4 * i + 1, 3 );
693 }
694 }
695
696 /*****************************************************************************
697 * DoShuffle: shuffle buffer
698 *****************************************************************************
699 * This is so ugly and uses so many MD5 checksums that it is most certainly
700 * one-way, though why it needs to be so complicated is beyond me.
701 *****************************************************************************/
702 static void DoShuffle( struct shuffle_s *p_shuffle,
703 uint32_t *p_buffer, uint32_t i_size )
704 {
705 struct md5_s md5;
706 uint32_t p_big_bordel[ 16 ];
707 uint32_t *p_bordel = p_shuffle->p_bordel;
708 unsigned int i;
709
710 /* Using the MD5 hash of a memory block is probably not one-way enough
711 * for the iTunes people. This function randomises p_bordel depending on
712 * the values in p_commands to make things even more messy in p_bordel. */
713 for( i = 0; i < 20; i++ )
714 {
715 uint8_t i_command, i_index;
716
717 if( !p_shuffle->p_commands[ i ] )
718 {
719 continue;
720 }
721
722 i_command = (p_shuffle->p_commands[ i ] & 0x300) >> 8;
723 i_index = p_shuffle->p_commands[ i ] & 0xff;
724
725 switch( i_command )
726 {
727 case 0x3:
728 p_bordel[ i_index & 0xf ] = p_bordel[ i_index >> 4 ]
729 + p_bordel[ ((i_index + 0x10) >> 4) & 0xf ];
730 break;
731 case 0x2:
732 p_bordel[ i_index >> 4 ] ^= p_shuffle_xor[ 0xff - i_index ];
733 break;
734 case 0x1:
735 p_bordel[ i_index >> 4 ] -= p_shuffle_sub[ 0xff - i_index ];
736 break;
737 default:
738 p_bordel[ i_index >> 4 ] += p_shuffle_add[ 0xff - i_index ];
739 break;
740 }
741 }
742
743 /* Convert our newly randomised p_bordel to big endianness and take
744 * its MD5 hash. */
745 InitMD5( &md5 );
746 for( i = 0; i < 16; i++ )
747 {
748 p_big_bordel[ i ] = U32_AT(p_bordel + i);
749 }
750 AddMD5( &md5, (uint8_t *)p_big_bordel, 64 );
751 EndMD5( &md5 );
752
753 /* XOR our buffer with the computed checksum */
754 for( i = 0; i < i_size; i++ )
755 {
756 p_buffer[ i ] ^= md5.p_digest[ i ];
757 }
758 }
759
760 /*****************************************************************************
761 * GetSystemKey: get the system key
762 *****************************************************************************
763 * Compute the system key from various system information, see HashSystemInfo.
764 *****************************************************************************/
765 static int GetSystemKey( uint32_t *p_sys_key, uint32_t b_ipod )
766 {
767 static char const p_secret1[ 8 ] = "YuaFlafu";
768 static char const p_secret2[ 8 ] = "zPif98ga";
769 struct md5_s md5;
770 int64_t i_ipod_id;
771 uint32_t p_system_hash[ 4 ];
772
773 /* Compute the MD5 hash of our system info */
774 if( ( !b_ipod && HashSystemInfo( p_system_hash ) ) ||
775 ( b_ipod && GetiPodID( &i_ipod_id ) ) )
776 {
777 return -1;
778 }
779
780 /* Combine our system info hash with additional secret data. The resulting
781 * MD5 hash will be our system key. */
782 InitMD5( &md5 );
783 AddMD5( &md5, (uint8_t *)p_secret1, 8 );
784
785 if( !b_ipod )
786 {
787 AddMD5( &md5, (uint8_t *)p_system_hash, 6 );
788 AddMD5( &md5, (uint8_t *)p_system_hash, 6 );
789 AddMD5( &md5, (uint8_t *)p_system_hash, 6 );
790 AddMD5( &md5, (uint8_t *)p_secret2, 8 );
791 }
792 else
793 {
794 i_ipod_id = U64_AT(&i_ipod_id);
795 AddMD5( &md5, (uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
796 AddMD5( &md5, (uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
797 AddMD5( &md5, (uint8_t *)&i_ipod_id, sizeof(i_ipod_id) );
798 }
799
800 EndMD5( &md5 );
801
802 memcpy( p_sys_key, md5.p_digest, 16 );
803
804 return 0;
805 }
806
807 #ifdef _WIN32
808 # define DRMS_DIRNAME "drms"
809 #else
810 # define DRMS_DIRNAME ".drms"
811 #endif
812
813 /*****************************************************************************
814 * WriteUserKey: write the user key to hard disk
815 *****************************************************************************
816 * Write the user key to the hard disk so that it can be reused later or used
817 * on operating systems other than Win32.
818 *****************************************************************************/
819 static int WriteUserKey( void *_p_drms, uint32_t *p_user_key )
820 {
821 struct drms_s *p_drms = (struct drms_s *)_p_drms;
822 FILE *file;
823 int i_ret = -1;
824 char psz_path[ XMMS_PATH_MAX ];
825
826 sprintf( psz_path, /* XMMS_PATH_MAX - 1, */
827 "%s/" DRMS_DIRNAME, p_drms->psz_homedir );
828
829 #if defined( HAVE_ERRNO_H )
830 # if defined( _WIN32 )
831 if( !mkdir( psz_path ) || errno == EEXIST )
832 # else
833 if( !mkdir( psz_path, 0755 ) || errno == EEXIST )
834 # endif
835 #else
836 if( !mkdir( psz_path ) )
837 #endif
838 {
839 sprintf( psz_path, /*XMMS_PATH_MAX - 1,*/ "%s/" DRMS_DIRNAME "/%08X.%03d",
840 p_drms->psz_homedir, p_drms->i_user, p_drms->i_key );
841
842 file = fopen( psz_path, "w" );
843 if( file != NULL )
844 {
845 i_ret = fwrite( p_user_key, sizeof(uint32_t),
846 4, file ) == 4 ? 0 : -1;
847 fclose( file );
848 }
849 }
850
851 return i_ret;
852 }
853
854 /*****************************************************************************
855 * ReadUserKey: read the user key from hard disk
856 *****************************************************************************
857 * Retrieve the user key from the hard disk if available.
858 *****************************************************************************/
859 static int ReadUserKey( void *_p_drms, uint32_t *p_user_key )
860 {
861 struct drms_s *p_drms = (struct drms_s *)_p_drms;
862 FILE *file;
863 int i_ret = -1;
864 char psz_path[ XMMS_PATH_MAX ];
865
866 sprintf( psz_path, /*XMMS_PATH_MAX - 1,*/
867 "%s/" DRMS_DIRNAME "/%08X.%03d", p_drms->psz_homedir,
868 p_drms->i_user, p_drms->i_key );
869
870 file = fopen( psz_path, "r" );
871 if( file != NULL )
872 {
873 i_ret = fread( p_user_key, sizeof(uint32_t),
874 4, file ) == 4 ? 0 : -1;
875 fclose( file );
876 }
877
878 return i_ret;
879 }
880
881 /*****************************************************************************
882 * GetUserKey: get the user key
883 *****************************************************************************
884 * Retrieve the user key from the hard disk if available, otherwise generate
885 * it from the system key. If the key could be successfully generated, write
886 * it to the hard disk for future use.
887 *****************************************************************************/
888 static int GetUserKey( void *_p_drms, uint32_t *p_user_key )
889 {
890 static char const p_secret[] = "mUfnpognadfgf873";
891 struct drms_s *p_drms = (struct drms_s *)_p_drms;
892 struct aes_s aes;
893 struct shuffle_s shuffle;
894 uint32_t i, y;
895 uint32_t *p_sci_data;
896 uint32_t i_user, i_key;
897 uint32_t p_sys_key[ 4 ];
898 uint32_t i_sci_size, i_blocks, i_remaining;
899 uint32_t *p_sci0, *p_sci1, *p_buffer;
900 uint32_t p_sci_key[ 4 ];
901 char *psz_ipod;
902 int i_ret = -1;
903
904 if( !ReadUserKey( p_drms, p_user_key ) )
905 {
906 REVERSE( p_user_key, 4 );
907 return 0;
908 }
909
910 psz_ipod = getenv( "IPOD" );
911
912 if( GetSystemKey( p_sys_key, psz_ipod ? 1 : 0 ) )
913 {
914 return -1;
915 }
916
917 if( GetSCIData( psz_ipod, &p_sci_data, &i_sci_size ) )
918 {
919 return -1;
920 }
921
922 /* Phase 1: unscramble the SCI data using the system key and shuffle
923 * it using DoShuffle(). */
924
925 /* Skip the first 4 bytes (some sort of header). Decrypt the rest. */
926 i_blocks = (i_sci_size - 4) / 16;
927 i_remaining = (i_sci_size - 4) - (i_blocks * 16);
928 p_buffer = p_sci_data + 1;
929
930 /* Decrypt and shuffle our data at the same time */
931 InitAES( &aes, p_sys_key );
932 REVERSE( p_sys_key, 4 );
933 InitShuffle( &shuffle, p_sys_key );
934
935 memcpy( p_sci_key, p_secret, 16 );
936 REVERSE( p_sci_key, 4 );
937
938 while( i_blocks-- )
939 {
940 uint32_t p_tmp[ 4 ];
941
942 REVERSE( p_buffer, 4 );
943 DecryptAES( &aes, p_tmp, p_buffer );
944 BlockXOR( p_tmp, p_sci_key, p_tmp );
945
946 /* Use the previous scrambled data as the key for next block */
947 memcpy( p_sci_key, p_buffer, 16 );
948
949 /* Shuffle the decrypted data using a custom routine */
950 DoShuffle( &shuffle, p_tmp, 4 );
951
952 /* Copy this block back to p_buffer */
953 memcpy( p_buffer, p_tmp, 16 );
954
955 p_buffer += 4;
956 }
957
958 if( i_remaining >= 4 )
959 {
960 i_remaining /= 4;
961 REVERSE( p_buffer, i_remaining );
962 DoShuffle( &shuffle, p_buffer, i_remaining );
963 }
964
965 /* Phase 2: look for the user key in the generated data. I must admit I
966 * do not understand what is going on here, because it almost
967 * looks like we are browsing data that makes sense, even though
968 * the DoShuffle() part made it completely meaningless. */
969
970 y = 0;
971 REVERSE( p_sci_data + 5, 1 );
972 i = U32_AT( p_sci_data + 5 );
973 i_sci_size -= 22 * sizeof(uint32_t);
974 p_sci1 = p_sci_data + 22;
975 p_sci0 = NULL;
976
977 while( i_sci_size >= 20 && i > 0 )
978 {
979 if( p_sci0 == NULL )
980 {
981 i_sci_size -= 18 * sizeof(uint32_t);
982 if( i_sci_size < 20 )
983 {
984 break;
985 }
986
987 p_sci0 = p_sci1;
988 REVERSE( p_sci1 + 17, 1 );
989 y = U32_AT( p_sci1 + 17 );
990 p_sci1 += 18;
991 }
992
993 if( !y )
994 {
995 i--;
996 p_sci0 = NULL;
997 continue;
998 }
999
1000 i_user = U32_AT( p_sci0 );
1001 i_key = U32_AT( p_sci1 );
1002 REVERSE( &i_user, 1 );
1003 REVERSE( &i_key, 1 );
1004 if( i_user == p_drms->i_user && ( ( i_key == p_drms->i_key ) ||
1005 ( !p_drms->i_key && ( p_sci1 == (p_sci0 + 18) ) ) ) )
1006 {
1007 memcpy( p_user_key, p_sci1 + 1, 16 );
1008 REVERSE( p_sci1 + 1, 4 );
1009 WriteUserKey( p_drms, p_sci1 + 1 );
1010 i_ret = 0;
1011 break;
1012 }
1013
1014 y--;
1015 p_sci1 += 5;
1016 i_sci_size -= 5 * sizeof(uint32_t);
1017 }
1018
1019 free( p_sci_data );
1020
1021 return i_ret;
1022 }
1023
1024 /*****************************************************************************
1025 * GetSCIData: get SCI data from "SC Info.sidb"
1026 *****************************************************************************
1027 * Read SCI data from "\Apple Computer\iTunes\SC Info\SC Info.sidb"
1028 *****************************************************************************/
1029 static int GetSCIData( char *psz_ipod, uint32_t **pp_sci,
1030 uint32_t *pi_sci_size )
1031 {
1032 FILE *file;
1033 char *psz_path = NULL;
1034 char p_tmp[ XMMS_PATH_MAX ];
1035 int i_ret = -1;
1036
1037 if( psz_ipod == NULL )
1038 {
1039 #ifdef _WIN32
1040 char *p_filename = "\\Apple Computer\\iTunes\\SC Info\\SC Info.sidb";
1041 typedef HRESULT (WINAPI *SHGETFOLDERPATH)( HWND, int, HANDLE, DWORD,
1042 LPSTR );
1043 HINSTANCE shfolder_dll = NULL;
1044 SHGETFOLDERPATH dSHGetFolderPath = NULL;
1045
1046 if( ( shfolder_dll = LoadLibrary( _T("SHFolder.dll") ) ) != NULL )
1047 {
1048 dSHGetFolderPath =
1049 (SHGETFOLDERPATH)GetProcAddress( shfolder_dll,
1050 _T("SHGetFolderPathA") );
1051 }
1052
1053 if( dSHGetFolderPath != NULL &&
1054 SUCCEEDED( dSHGetFolderPath( NULL, /*CSIDL_COMMON_APPDATA*/ 0x0023,
1055 NULL, 0, p_tmp ) ) )
1056 {
1057 strncat( p_tmp, p_filename, min( strlen( p_filename ),
1058 (sizeof(p_tmp)/sizeof(p_tmp[0]) - 1) -
1059 strlen( p_tmp ) ) );
1060 psz_path = p_tmp;
1061 }
1062
1063 if( shfolder_dll != NULL )
1064 {
1065 FreeLibrary( shfolder_dll );
1066 }
1067 #endif
1068 }
1069 else
1070 {
1071 #define ISCINFO "iSCInfo"
1072 if( strstr( psz_ipod, ISCINFO ) == NULL )
1073 {
1074 sprintf( p_tmp, /*sizeof(p_tmp)/sizeof(p_tmp[0]) - 1,*/
1075 "%s/iPod_Control/iTunes/" ISCINFO, psz_ipod );
1076 psz_path = p_tmp;
1077 }
1078 else
1079 {
1080 psz_path = psz_ipod;
1081 }
1082 }
1083
1084 if( psz_path == NULL )
1085 {
1086 return -1;
1087 }
1088
1089 file = fopen( psz_path, "r" );
1090 if( file != NULL )
1091 {
1092 struct stat st;
1093
1094 if( !fstat( fileno( file ), &st ) )
1095 {
1096 *pp_sci = malloc( st.st_size );
1097 if( *pp_sci != NULL )
1098 {
1099 if( fread( *pp_sci, 1, st.st_size,
1100 file ) == (size_t)st.st_size )
1101 {
1102 *pi_sci_size = st.st_size;
1103 i_ret = 0;
1104 }
1105 else
1106 {
1107 free( (void *)*pp_sci );
1108 *pp_sci = NULL;
1109 }
1110 }
1111 }
1112
1113 fclose( file );
1114 }
1115
1116 return i_ret;
1117 }
1118
1119 /*****************************************************************************
1120 * HashSystemInfo: hash system information
1121 *****************************************************************************
1122 * This function computes the MD5 hash of the C: hard drive serial number,
1123 * BIOS version, CPU type and Windows version.
1124 *****************************************************************************/
1125 static int HashSystemInfo( uint32_t *p_system_hash )
1126 {
1127 struct md5_s md5;
1128 int i_ret = 0;
1129
1130 #ifdef _WIN32
1131 HKEY i_key;
1132 unsigned int i;
1133 DWORD i_size;
1134 DWORD i_serial;
1135 LPBYTE p_reg_buf;
1136
1137 static LPCTSTR p_reg_keys[ 3 ][ 2 ] =
1138 {
1139 {
1140 _T("HARDWARE\\DESCRIPTION\\System"),
1141 _T("SystemBiosVersion")
1142 },
1143
1144 {
1145 _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
1146 _T("ProcessorNameString")
1147 },
1148
1149 {
1150 _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"),
1151 _T("ProductId")
1152 }
1153 };
1154
1155 InitMD5( &md5 );
1156
1157 AddMD5( &md5, "cache-control", 13 );
1158 AddMD5( &md5, "Ethernet", 8 );
1159
1160 GetVolumeInformation( _T("C:\\"), NULL, 0, &i_serial,
1161 NULL, NULL, NULL, 0 );
1162 AddMD5( &md5, (uint8_t *)&i_serial, 4 );
1163
1164 for( i = 0; i < sizeof(p_reg_keys) / sizeof(p_reg_keys[ 0 ]); i++ )
1165 {
1166 if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, p_reg_keys[ i ][ 0 ],
1167 0, KEY_READ, &i_key ) != ERROR_SUCCESS )
1168 {
1169 continue;
1170 }
1171
1172 if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
1173 NULL, NULL, NULL, &i_size ) != ERROR_SUCCESS )
1174 {
1175 RegCloseKey( i_key );
1176 continue;
1177 }
1178
1179 p_reg_buf = malloc( i_size );
1180
1181 if( p_reg_buf != NULL )
1182 {
1183 if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
1184 NULL, NULL, p_reg_buf,
1185 &i_size ) == ERROR_SUCCESS )
1186 {
1187 AddMD5( &md5, (uint8_t *)p_reg_buf, i_size );
1188 }
1189
1190 free( p_reg_buf );
1191 }
1192
1193 RegCloseKey( i_key );
1194 }
1195
1196 #else
1197 InitMD5( &md5 );
1198 i_ret = -1;
1199 #endif
1200
1201 EndMD5( &md5 );
1202 memcpy( p_system_hash, md5.p_digest, 16 );
1203
1204 return i_ret;
1205 }
1206
1207 /*****************************************************************************
1208 * GetiPodID: Get iPod ID
1209 *****************************************************************************
1210 * This function gets the iPod ID.
1211 *****************************************************************************/
1212 static int GetiPodID( int64_t *p_ipod_id )
1213 {
1214 int i_ret = -1;
1215
1216 #define PROD_NAME "iPod"
1217 #define VENDOR_NAME "Apple Computer, Inc."
1218
1219 char *psz_ipod_id = getenv( "IPODID" );
1220 if( psz_ipod_id != NULL )
1221 {
1222 #ifndef _WIN32
1223 *p_ipod_id = strtoll( psz_ipod_id, NULL, 16 );
1224 #else
1225 *p_ipod_id = strtol( psz_ipod_id, NULL, 16 );
1226 #endif
1227 return 0;
1228 }
1229
1230 #ifdef HAVE_IOKIT_IOKITLIB_H
1231 CFTypeRef value;
1232 mach_port_t port;
1233 io_object_t device;
1234 io_iterator_t iterator;
1235 CFMutableDictionaryRef matching_dic;
1236
1237 if( IOMasterPort( MACH_PORT_NULL, &port ) == KERN_SUCCESS )
1238 {
1239 if( ( matching_dic = IOServiceMatching( "IOFireWireUnit" ) ) != NULL )
1240 {
1241 CFDictionarySetValue( matching_dic,
1242 CFSTR("FireWire Vendor Name"),
1243 CFSTR(VENDOR_NAME) );
1244 CFDictionarySetValue( matching_dic,
1245 CFSTR("FireWire Product Name"),
1246 CFSTR(PROD_NAME) );
1247
1248 if( IOServiceGetMatchingServices( port, matching_dic,
1249 &iterator ) == KERN_SUCCESS )
1250 {
1251 while( ( device = IOIteratorNext( iterator ) ) != NULL )
1252 {
1253 value = IORegistryEntryCreateCFProperty( device,
1254 CFSTR("GUID"), kCFAllocatorDefault, kNilOptions );
1255
1256 if( value != NULL )
1257 {
1258 if( CFGetTypeID( value ) == CFNumberGetTypeID() )
1259 {
1260 int64_t i_ipod_id;
1261 CFNumberGetValue( (CFNumberRef)value,
1262 kCFNumberLongLongType,
1263 &i_ipod_id );
1264 *p_ipod_id = i_ipod_id;
1265 i_ret = 0;
1266 }
1267
1268 CFRelease( value );
1269 }
1270
1271 IOObjectRelease( device );
1272
1273 if( !i_ret ) break;
1274 }
1275
1276 IOObjectRelease( iterator );
1277 }
1278 }
1279
1280 mach_port_deallocate( mach_task_self(), port );
1281 }
1282
1283 #elif HAVE_SYSFS_LIBSYSFS_H
1284 struct sysfs_bus *bus = NULL;
1285 struct dlist *devlist = NULL;
1286 struct dlist *attributes = NULL;
1287 struct sysfs_device *curdev = NULL;
1288 struct sysfs_attribute *curattr = NULL;
1289
1290 bus = sysfs_open_bus( "ieee1394" );
1291 if( bus != NULL )
1292 {
1293 devlist = sysfs_get_bus_devices( bus );
1294 if( devlist != NULL )
1295 {
1296 dlist_for_each_data( devlist, curdev, struct sysfs_device )
1297 {
1298 attributes = sysfs_get_device_attributes( curdev );
1299 if( attributes != NULL )
1300 {
1301 dlist_for_each_data( attributes, curattr,
1302 struct sysfs_attribute )
1303 {
1304 if( ( strcmp( curattr->name, "model_name" ) == 0 ) &&
1305 ( strncmp( curattr->value, PROD_NAME,
1306 sizeof(PROD_NAME) ) == 0 ) )
1307 {
1308 *p_ipod_id = strtoll( curdev->name, NULL, 16 );
1309 i_ret = 0;
1310 break;
1311 }
1312 }
1313 }
1314
1315 if( !i_ret ) break;
1316 }
1317 }
1318
1319 sysfs_close_bus( bus );
1320 }
1321 #endif
1322
1323 return i_ret;
1324 }
1325
1326 #endif
0 /*****************************************************************************
1 * drms.h : DRMS
2 *****************************************************************************
3 * Copyright (C) 2004 VideoLAN
4 * $Id: drms.h,v 1.7 2005/02/01 13:15:55 menno Exp $
5 *
6 * Author: Jon Lech Johansen <jon-vl@nanocrew.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 *****************************************************************************/
22
23 extern void *drms_alloc( char *psz_homedir );
24 extern void drms_free( void *p_drms );
25 extern int drms_init( void *p_drms, uint32_t i_type,
26 uint8_t *p_info, uint32_t i_len );
27 extern void drms_decrypt( void *p_drms, uint32_t *p_buffer,
28 uint32_t i_len );
29
0 /*****************************************************************************
1 * drmstables.h : AES/Rijndael block cipher and miscellaneous tables
2 *****************************************************************************
3 * Copyright (C) 2004 VideoLAN
4 * $Id: drmstables.h,v 1.6 2005/02/01 13:15:55 menno Exp $
5 *
6 * Author: Jon Lech Johansen <jon-vl@nanocrew.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 *****************************************************************************/
22
23 #define AES_ROR( x, n ) (((x) << (32-(n))) | ((x) >> (n)))
24
25 #define AES_XOR_ROR( p_table, p_tmp ) \
26 ( p_table[ (p_tmp[ t > 2 ? t - 3 : t + 1 ] >> 24) & 0xFF ] \
27 ^ AES_ROR( p_table[ (p_tmp[ t > 1 ? t - 2 : t + 2 ] >> 16) & 0xFF ], 8 ) \
28 ^ AES_ROR( p_table[ (p_tmp[ t > 0 ? t - 1 : t + 3 ] >> 8) & 0xFF ], 16 ) \
29 ^ AES_ROR( p_table[ p_tmp[ t ] & 0xFF ], 24 ) )
30
31 #define AES_KEY_COUNT 10
32
33 static uint32_t const p_aes_table[ AES_KEY_COUNT ] =
34 {
35 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020,
36 0x00000040, 0x00000080, 0x0000001b, 0x00000036
37 };
38
39 static uint32_t const p_aes_encrypt[ 256 ] =
40 {
41 0x63000000, 0x7c000000, 0x77000000, 0x7b000000, 0xf2000000, 0x6b000000,
42 0x6f000000, 0xc5000000, 0x30000000, 0x01000000, 0x67000000, 0x2b000000,
43 0xfe000000, 0xd7000000, 0xab000000, 0x76000000, 0xca000000, 0x82000000,
44 0xc9000000, 0x7d000000, 0xfa000000, 0x59000000, 0x47000000, 0xf0000000,
45 0xad000000, 0xd4000000, 0xa2000000, 0xaf000000, 0x9c000000, 0xa4000000,
46 0x72000000, 0xc0000000, 0xb7000000, 0xfd000000, 0x93000000, 0x26000000,
47 0x36000000, 0x3f000000, 0xf7000000, 0xcc000000, 0x34000000, 0xa5000000,
48 0xe5000000, 0xf1000000, 0x71000000, 0xd8000000, 0x31000000, 0x15000000,
49 0x04000000, 0xc7000000, 0x23000000, 0xc3000000, 0x18000000, 0x96000000,
50 0x05000000, 0x9a000000, 0x07000000, 0x12000000, 0x80000000, 0xe2000000,
51 0xeb000000, 0x27000000, 0xb2000000, 0x75000000, 0x09000000, 0x83000000,
52 0x2c000000, 0x1a000000, 0x1b000000, 0x6e000000, 0x5a000000, 0xa0000000,
53 0x52000000, 0x3b000000, 0xd6000000, 0xb3000000, 0x29000000, 0xe3000000,
54 0x2f000000, 0x84000000, 0x53000000, 0xd1000000, 0x00000000, 0xed000000,
55 0x20000000, 0xfc000000, 0xb1000000, 0x5b000000, 0x6a000000, 0xcb000000,
56 0xbe000000, 0x39000000, 0x4a000000, 0x4c000000, 0x58000000, 0xcf000000,
57 0xd0000000, 0xef000000, 0xaa000000, 0xfb000000, 0x43000000, 0x4d000000,
58 0x33000000, 0x85000000, 0x45000000, 0xf9000000, 0x02000000, 0x7f000000,
59 0x50000000, 0x3c000000, 0x9f000000, 0xa8000000, 0x51000000, 0xa3000000,
60 0x40000000, 0x8f000000, 0x92000000, 0x9d000000, 0x38000000, 0xf5000000,
61 0xbc000000, 0xb6000000, 0xda000000, 0x21000000, 0x10000000, 0xff000000,
62 0xf3000000, 0xd2000000, 0xcd000000, 0x0c000000, 0x13000000, 0xec000000,
63 0x5f000000, 0x97000000, 0x44000000, 0x17000000, 0xc4000000, 0xa7000000,
64 0x7e000000, 0x3d000000, 0x64000000, 0x5d000000, 0x19000000, 0x73000000,
65 0x60000000, 0x81000000, 0x4f000000, 0xdc000000, 0x22000000, 0x2a000000,
66 0x90000000, 0x88000000, 0x46000000, 0xee000000, 0xb8000000, 0x14000000,
67 0xde000000, 0x5e000000, 0x0b000000, 0xdb000000, 0xe0000000, 0x32000000,
68 0x3a000000, 0x0a000000, 0x49000000, 0x06000000, 0x24000000, 0x5c000000,
69 0xc2000000, 0xd3000000, 0xac000000, 0x62000000, 0x91000000, 0x95000000,
70 0xe4000000, 0x79000000, 0xe7000000, 0xc8000000, 0x37000000, 0x6d000000,
71 0x8d000000, 0xd5000000, 0x4e000000, 0xa9000000, 0x6c000000, 0x56000000,
72 0xf4000000, 0xea000000, 0x65000000, 0x7a000000, 0xae000000, 0x08000000,
73 0xba000000, 0x78000000, 0x25000000, 0x2e000000, 0x1c000000, 0xa6000000,
74 0xb4000000, 0xc6000000, 0xe8000000, 0xdd000000, 0x74000000, 0x1f000000,
75 0x4b000000, 0xbd000000, 0x8b000000, 0x8a000000, 0x70000000, 0x3e000000,
76 0xb5000000, 0x66000000, 0x48000000, 0x03000000, 0xf6000000, 0x0e000000,
77 0x61000000, 0x35000000, 0x57000000, 0xb9000000, 0x86000000, 0xc1000000,
78 0x1d000000, 0x9e000000, 0xe1000000, 0xf8000000, 0x98000000, 0x11000000,
79 0x69000000, 0xd9000000, 0x8e000000, 0x94000000, 0x9b000000, 0x1e000000,
80 0x87000000, 0xe9000000, 0xce000000, 0x55000000, 0x28000000, 0xdf000000,
81 0x8c000000, 0xa1000000, 0x89000000, 0x0d000000, 0xbf000000, 0xe6000000,
82 0x42000000, 0x68000000, 0x41000000, 0x99000000, 0x2d000000, 0x0f000000,
83 0xb0000000, 0x54000000, 0xbb000000, 0x16000000
84 };
85
86 static uint32_t const p_aes_itable[ 256 ] =
87 {
88 0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, 0x3bcb6bab, 0x1ff1459d,
89 0xacab58fa, 0x4b9303e3, 0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02,
90 0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362, 0xde495ab1, 0x25671bba,
91 0x45980eea, 0x5de1c0fe, 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3,
92 0x03e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952, 0xd42d83be, 0x58d32174,
93 0x492969e0, 0x8e44c8c9, 0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9,
94 0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, 0x63184adf, 0xe582311a,
95 0x97603351, 0x62457f53, 0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08,
96 0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b, 0xab23d373, 0x72e2024b,
97 0xe3578f1f, 0x662aab55, 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837,
98 0x30f28728, 0x23b2a5bf, 0x02ba6a03, 0xed5c8216, 0x8a2b1ccf, 0xa792b479,
99 0xf3f0f207, 0x4ea1e269, 0x65cdf4da, 0x06d5be05, 0xd11f6234, 0xc48afea6,
100 0x349d532e, 0xa2a055f3, 0x0532e18a, 0xa475ebf6, 0x0b39ec83, 0x40aaef60,
101 0x5e069f71, 0xbd51106e, 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6,
102 0x91b58d54, 0x71055dc4, 0x046fd406, 0x60ff1550, 0x1924fb98, 0xd697e9bd,
103 0x89cc4340, 0x67779ed9, 0xb0bd42e8, 0x07888b89, 0xe7385b19, 0x79dbeec8,
104 0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x00000000, 0x09838680, 0x3248ed2b,
105 0x1eac7011, 0x6c4e725a, 0xfdfbff0e, 0x0f563885, 0x3d1ed5ae, 0x3627392d,
106 0x0a64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36, 0x0cb1670a, 0x930fe757,
107 0xb4d296ee, 0x1b9e919b, 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12,
108 0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, 0x0e0b0d09, 0xf2adc78b,
109 0x2db9a8b6, 0x14c8a91e, 0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f,
110 0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb, 0x8b762943, 0xcbdcc623,
111 0xb668fced, 0xb863f1e4, 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6,
112 0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129, 0x1d4b2f9e, 0xdcf330b2,
113 0x0dec5286, 0x77d0e3c1, 0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9,
114 0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033, 0x87c74e49, 0xd9c1d138,
115 0x8cfea2ca, 0x98360bd4, 0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad,
116 0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e, 0xf6c2138d, 0x90e8b8d8,
117 0x2e5ef739, 0x82f5afc3, 0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225,
118 0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, 0xcd097826, 0x6ef41859,
119 0xec01b79a, 0x83a89a4f, 0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815,
120 0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0, 0x31afb2a4, 0x2a31233f,
121 0xc63094a5, 0x35c066a2, 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7,
122 0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691, 0x768dd64d, 0x434db0ef,
123 0xcc544daa, 0xe4df0496, 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165,
124 0x9d04ea5e, 0x015d358c, 0xfa737487, 0xfb2e410b, 0xb35a1d67, 0x9252d2db,
125 0xe9335610, 0x6d1347d6, 0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13,
126 0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147, 0x9c59dfd2, 0x553f73f2,
127 0x1879ce14, 0x73bf37c7, 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44,
128 0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, 0x1672c31d, 0xbc0c25e2,
129 0x288b493c, 0xff41950d, 0x397101a8, 0x08deb30c, 0xd89ce4b4, 0x6490c156,
130 0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8
131 };
132
133 static uint32_t const p_aes_decrypt[ 256 ] =
134 {
135 0x52000000, 0x09000000, 0x6a000000, 0xd5000000, 0x30000000, 0x36000000,
136 0xa5000000, 0x38000000, 0xbf000000, 0x40000000, 0xa3000000, 0x9e000000,
137 0x81000000, 0xf3000000, 0xd7000000, 0xfb000000, 0x7c000000, 0xe3000000,
138 0x39000000, 0x82000000, 0x9b000000, 0x2f000000, 0xff000000, 0x87000000,
139 0x34000000, 0x8e000000, 0x43000000, 0x44000000, 0xc4000000, 0xde000000,
140 0xe9000000, 0xcb000000, 0x54000000, 0x7b000000, 0x94000000, 0x32000000,
141 0xa6000000, 0xc2000000, 0x23000000, 0x3d000000, 0xee000000, 0x4c000000,
142 0x95000000, 0x0b000000, 0x42000000, 0xfa000000, 0xc3000000, 0x4e000000,
143 0x08000000, 0x2e000000, 0xa1000000, 0x66000000, 0x28000000, 0xd9000000,
144 0x24000000, 0xb2000000, 0x76000000, 0x5b000000, 0xa2000000, 0x49000000,
145 0x6d000000, 0x8b000000, 0xd1000000, 0x25000000, 0x72000000, 0xf8000000,
146 0xf6000000, 0x64000000, 0x86000000, 0x68000000, 0x98000000, 0x16000000,
147 0xd4000000, 0xa4000000, 0x5c000000, 0xcc000000, 0x5d000000, 0x65000000,
148 0xb6000000, 0x92000000, 0x6c000000, 0x70000000, 0x48000000, 0x50000000,
149 0xfd000000, 0xed000000, 0xb9000000, 0xda000000, 0x5e000000, 0x15000000,
150 0x46000000, 0x57000000, 0xa7000000, 0x8d000000, 0x9d000000, 0x84000000,
151 0x90000000, 0xd8000000, 0xab000000, 0x00000000, 0x8c000000, 0xbc000000,
152 0xd3000000, 0x0a000000, 0xf7000000, 0xe4000000, 0x58000000, 0x05000000,
153 0xb8000000, 0xb3000000, 0x45000000, 0x06000000, 0xd0000000, 0x2c000000,
154 0x1e000000, 0x8f000000, 0xca000000, 0x3f000000, 0x0f000000, 0x02000000,
155 0xc1000000, 0xaf000000, 0xbd000000, 0x03000000, 0x01000000, 0x13000000,
156 0x8a000000, 0x6b000000, 0x3a000000, 0x91000000, 0x11000000, 0x41000000,
157 0x4f000000, 0x67000000, 0xdc000000, 0xea000000, 0x97000000, 0xf2000000,
158 0xcf000000, 0xce000000, 0xf0000000, 0xb4000000, 0xe6000000, 0x73000000,
159 0x96000000, 0xac000000, 0x74000000, 0x22000000, 0xe7000000, 0xad000000,
160 0x35000000, 0x85000000, 0xe2000000, 0xf9000000, 0x37000000, 0xe8000000,
161 0x1c000000, 0x75000000, 0xdf000000, 0x6e000000, 0x47000000, 0xf1000000,
162 0x1a000000, 0x71000000, 0x1d000000, 0x29000000, 0xc5000000, 0x89000000,
163 0x6f000000, 0xb7000000, 0x62000000, 0x0e000000, 0xaa000000, 0x18000000,
164 0xbe000000, 0x1b000000, 0xfc000000, 0x56000000, 0x3e000000, 0x4b000000,
165 0xc6000000, 0xd2000000, 0x79000000, 0x20000000, 0x9a000000, 0xdb000000,
166 0xc0000000, 0xfe000000, 0x78000000, 0xcd000000, 0x5a000000, 0xf4000000,
167 0x1f000000, 0xdd000000, 0xa8000000, 0x33000000, 0x88000000, 0x07000000,
168 0xc7000000, 0x31000000, 0xb1000000, 0x12000000, 0x10000000, 0x59000000,
169 0x27000000, 0x80000000, 0xec000000, 0x5f000000, 0x60000000, 0x51000000,
170 0x7f000000, 0xa9000000, 0x19000000, 0xb5000000, 0x4a000000, 0x0d000000,
171 0x2d000000, 0xe5000000, 0x7a000000, 0x9f000000, 0x93000000, 0xc9000000,
172 0x9c000000, 0xef000000, 0xa0000000, 0xe0000000, 0x3b000000, 0x4d000000,
173 0xae000000, 0x2a000000, 0xf5000000, 0xb0000000, 0xc8000000, 0xeb000000,
174 0xbb000000, 0x3c000000, 0x83000000, 0x53000000, 0x99000000, 0x61000000,
175 0x17000000, 0x2b000000, 0x04000000, 0x7e000000, 0xba000000, 0x77000000,
176 0xd6000000, 0x26000000, 0xe1000000, 0x69000000, 0x14000000, 0x63000000,
177 0x55000000, 0x21000000, 0x0c000000, 0x7d000000
178 };
179
180 static uint16_t const p_shuffle_xor[ 256 ] =
181 {
182 0x00d1, 0x0315, 0x1a32, 0x19ec, 0x1bbb, 0x1d6f, 0x14fe, 0x0e9e,
183 0x029e, 0x1b8f, 0x0b70, 0x033a, 0x188e, 0x1d18, 0x0bd8, 0x0edb,
184 0x0c64, 0x1c2b, 0x149c, 0x047b, 0x1064, 0x1c7c, 0x118d, 0x1355,
185 0x0ae5, 0x0f18, 0x016f, 0x17d6, 0x1595, 0x0084, 0x0616, 0x1ccd,
186 0x1d94, 0x0618, 0x182c, 0x195b, 0x196d, 0x0394, 0x07db, 0x0287,
187 0x1636, 0x0b81, 0x1519, 0x0df9, 0x1ba3, 0x1cc3, 0x0ee2, 0x1434,
188 0x1457, 0x0ced, 0x0f7d, 0x0d7b, 0x0b9e, 0x0d13, 0x13d7, 0x18d0,
189 0x1259, 0x1977, 0x0606, 0x1e80, 0x05f2, 0x06b8, 0x1f07, 0x1365,
190 0x0334, 0x0e30, 0x195f, 0x15f1, 0x058e, 0x0aa8, 0x045a, 0x0465,
191 0x0b3e, 0x071e, 0x0a36, 0x105c, 0x01ac, 0x1a1e, 0x04e4, 0x056b,
192 0x12bf, 0x0da2, 0x0b41, 0x0eaf, 0x034f, 0x0181, 0x04e2, 0x002b,
193 0x12e6, 0x01be, 0x10e8, 0x128f, 0x0eb2, 0x1369, 0x05be, 0x1a59,
194 0x117e, 0x047c, 0x1e86, 0x056a, 0x0da7, 0x0d61, 0x03fc, 0x1e6e,
195 0x1d0c, 0x1e6d, 0x14bf, 0x0c50, 0x063a, 0x1b47, 0x17ae, 0x1321,
196 0x041b, 0x0a24, 0x0d4d, 0x1f2b, 0x1cb6, 0x1bed, 0x1549, 0x03a7,
197 0x0254, 0x006c, 0x0c9e, 0x0f73, 0x006c, 0x0008, 0x11f9, 0x0dd5,
198 0x0bcf, 0x0af9, 0x1dfe, 0x0341, 0x0e49, 0x0d38, 0x17cb, 0x1513,
199 0x0e96, 0x00ed, 0x0556, 0x1b28, 0x100c, 0x19d8, 0x14fa, 0x028c,
200 0x1c60, 0x1232, 0x13d3, 0x0d00, 0x1534, 0x192c, 0x14b5, 0x1cf2,
201 0x0504, 0x0b5b, 0x1ecf, 0x0423, 0x183b, 0x06b0, 0x169e, 0x1066,
202 0x04cb, 0x08a2, 0x1b4a, 0x1254, 0x198d, 0x1044, 0x0236, 0x1bd8,
203 0x18a1, 0x03ff, 0x1a0d, 0x0277, 0x0c2d, 0x17c9, 0x007c, 0x116e,
204 0x048a, 0x1eaf, 0x0922, 0x0c45, 0x0766, 0x1e5f, 0x1a28, 0x0120,
205 0x1c15, 0x034c, 0x0508, 0x0e73, 0x0879, 0x0441, 0x09ae, 0x132f,
206 0x14fe, 0x0413, 0x0a9d, 0x1727, 0x01d7, 0x1a2b, 0x0474, 0x18f0,
207 0x1f3b, 0x14f5, 0x1071, 0x0895, 0x1071, 0x18ff, 0x18e3, 0x0eb9,
208 0x0ba9, 0x0961, 0x1599, 0x019e, 0x1d12, 0x1baa, 0x1e94, 0x1921,
209 0x14dc, 0x124e, 0x0a25, 0x03ab, 0x1cc0, 0x1ebb, 0x0b4b, 0x16e5,
210 0x11ea, 0x0d78, 0x1bb3, 0x1ba7, 0x1510, 0x1b7b, 0x0c64, 0x1995,
211 0x1a58, 0x1651, 0x1964, 0x147a, 0x15f2, 0x11bb, 0x1654, 0x166e,
212 0x0ea9, 0x1de1, 0x1443, 0x13c5, 0x00e1, 0x0b2f, 0x0b6f, 0x0a37,
213 0x18ac, 0x08e6, 0x06f0, 0x136e, 0x0853, 0x0b2e, 0x0813, 0x10d6
214 };
215
216 static uint16_t const p_shuffle_sub[ 256 ] =
217 {
218 0x067a, 0x0c7d, 0x0b4f, 0x127d, 0x0bd6, 0x04ac, 0x16e0, 0x1730,
219 0x0587, 0x0afb, 0x1ac3, 0x0120, 0x14b5, 0x0f67, 0x11de, 0x0961,
220 0x1127, 0x1a68, 0x07f0, 0x17d0, 0x1a6f, 0x1f3b, 0x01ef, 0x0919,
221 0x131e, 0x0f90, 0x19e9, 0x18a8, 0x0cb2, 0x1ad0, 0x0c66, 0x0378,
222 0x03b0, 0x01be, 0x1866, 0x1159, 0x197c, 0x1105, 0x010b, 0x0353,
223 0x1abb, 0x09a6, 0x028a, 0x1bad, 0x1b20, 0x0455, 0x0f57, 0x0588,
224 0x1491, 0x0a1d, 0x0f04, 0x0650, 0x191e, 0x1e0e, 0x174b, 0x016b,
225 0x051f, 0x0532, 0x00df, 0x1aea, 0x0005, 0x0e1b, 0x0ff6, 0x08d8,
226 0x14b4, 0x086a, 0x0c20, 0x0149, 0x1971, 0x0f26, 0x1852, 0x017d,
227 0x1228, 0x0352, 0x0a44, 0x1330, 0x18df, 0x1e38, 0x01bc, 0x0bac,
228 0x1a48, 0x021f, 0x02f7, 0x0c31, 0x0bc4, 0x1e75, 0x105c, 0x13e3,
229 0x0b20, 0x03a1, 0x1af3, 0x1a36, 0x0e34, 0x181f, 0x09bd, 0x122b,
230 0x0ee0, 0x163b, 0x0be7, 0x103d, 0x1075, 0x1e9d, 0x02af, 0x0ba2,
231 0x1daa, 0x0cf1, 0x04b6, 0x0598, 0x06a1, 0x0d33, 0x1cfe, 0x04ee,
232 0x1bad, 0x07c8, 0x1a48, 0x05e6, 0x031f, 0x0e0a, 0x0326, 0x1650,
233 0x0526, 0x0b4e, 0x08fc, 0x0e4d, 0x0832, 0x06ea, 0x09bf, 0x0993,
234 0x09eb, 0x0f31, 0x071b, 0x14d5, 0x11ca, 0x0722, 0x120d, 0x014c,
235 0x1993, 0x0ae4, 0x1ccb, 0x04e9, 0x0aee, 0x1708, 0x0c3d, 0x12f2,
236 0x1a19, 0x07c1, 0x05a7, 0x0744, 0x1606, 0x1a9b, 0x042d, 0x1bfc,
237 0x1841, 0x0c3c, 0x0ffe, 0x1ab1, 0x1416, 0x18a9, 0x0320, 0x1ec2,
238 0x0ae7, 0x11c6, 0x124a, 0x11df, 0x0f81, 0x06cf, 0x0ed9, 0x0253,
239 0x1d2b, 0x0349, 0x0805, 0x08b3, 0x1052, 0x12cf, 0x0a44, 0x0ea6,
240 0x03bf, 0x1d90, 0x0ef8, 0x0657, 0x156d, 0x0405, 0x10be, 0x091f,
241 0x1c82, 0x1725, 0x19ef, 0x0b8c, 0x04d9, 0x02c7, 0x025a, 0x1b89,
242 0x0f5c, 0x013d, 0x02f7, 0x12e3, 0x0bc5, 0x1b56, 0x0848, 0x0239,
243 0x0fcf, 0x03a4, 0x092d, 0x1354, 0x1d83, 0x01bd, 0x071a, 0x0af1,
244 0x0875, 0x0793, 0x1b41, 0x1782, 0x0def, 0x1d20, 0x13be, 0x0095,
245 0x1650, 0x19d4, 0x0de3, 0x0980, 0x18f2, 0x0ca3, 0x0098, 0x149a,
246 0x0b81, 0x0ad2, 0x1bba, 0x1a02, 0x027b, 0x1906, 0x07f5, 0x1cae,
247 0x0c3f, 0x02f6, 0x1298, 0x175e, 0x15b2, 0x13d8, 0x14cc, 0x161a,
248 0x0a42, 0x15f3, 0x0870, 0x1c1d, 0x1203, 0x18b1, 0x1738, 0x1954,
249 0x1143, 0x1ae8, 0x1d9d, 0x155b, 0x11e8, 0x0ed9, 0x06f7, 0x04ca
250 };
251
252 static uint16_t const p_shuffle_add[ 256 ] =
253 {
254 0x0706, 0x175a, 0x0def, 0x1e72, 0x0297, 0x1b0e, 0x1d5a, 0x15b8,
255 0x13e2, 0x1347, 0x10c6, 0x0b4f, 0x0629, 0x0a75, 0x0a9b, 0x0f55,
256 0x1a69, 0x09bf, 0x0ba6, 0x1582, 0x1086, 0x1921, 0x01cb, 0x1c6a,
257 0x0ff5, 0x00f7, 0x0a67, 0x0a1e, 0x1838, 0x0196, 0x10d6, 0x0c7a,
258 0x180e, 0x038d, 0x1add, 0x0684, 0x154a, 0x0ab0, 0x18a4, 0x0d73,
259 0x1641, 0x0ec6, 0x09f1, 0x1a62, 0x0414, 0x162a, 0x194e, 0x1ec9,
260 0x022f, 0x0296, 0x1104, 0x14fc, 0x096c, 0x1d02, 0x09bd, 0x027c,
261 0x080e, 0x1324, 0x128c, 0x0dc1, 0x00b9, 0x17f2, 0x0cbc, 0x0f97,
262 0x1b93, 0x1c3c, 0x0415, 0x0395, 0x0c7a, 0x06cc, 0x0d4b, 0x16e2,
263 0x04a2, 0x0dab, 0x1228, 0x012b, 0x0896, 0x0012, 0x1cd6, 0x1dac,
264 0x080d, 0x0446, 0x047a, 0x00ad, 0x029e, 0x0686, 0x17c3, 0x1466,
265 0x0d16, 0x1896, 0x076e, 0x00cd, 0x17dc, 0x1e9f, 0x1a7c, 0x02bb,
266 0x0d06, 0x112b, 0x14cb, 0x0a03, 0x1541, 0x1290, 0x0f6d, 0x1503,
267 0x084b, 0x0382, 0x1a3f, 0x0371, 0x1977, 0x0b67, 0x0cad, 0x1df8,
268 0x1ce3, 0x1306, 0x13f8, 0x1163, 0x1b0b, 0x00bd, 0x0bf0, 0x1a4f,
269 0x16f7, 0x0b4f, 0x0cf8, 0x1254, 0x0541, 0x100d, 0x0296, 0x0410,
270 0x1a2b, 0x1169, 0x17d9, 0x0819, 0x03d6, 0x0d03, 0x194d, 0x184a,
271 0x07ca, 0x1989, 0x0fad, 0x011c, 0x1c71, 0x0ef6, 0x0dc8, 0x0f2f,
272 0x0fa5, 0x11be, 0x0f3b, 0x1d52, 0x0de2, 0x016e, 0x1ad1, 0x0c4a,
273 0x1bc2, 0x0ac9, 0x1485, 0x1bee, 0x0949, 0x1a79, 0x1894, 0x12bb,
274 0x17b6, 0x14f5, 0x16b1, 0x142c, 0x1301, 0x03ef, 0x16ff, 0x0d37,
275 0x0d78, 0x01ff, 0x00d6, 0x1053, 0x1a2a, 0x0f61, 0x1352, 0x0c7f,
276 0x137f, 0x09c4, 0x1d96, 0x021d, 0x1037, 0x1b19, 0x10ef, 0x14e4,
277 0x02a0, 0x0236, 0x0a5d, 0x1519, 0x141c, 0x1399, 0x007e, 0x1e74,
278 0x0941, 0x1b3c, 0x0062, 0x0371, 0x09ad, 0x08e8, 0x0a24, 0x0b97,
279 0x1ed2, 0x0889, 0x136b, 0x0006, 0x1c4c, 0x0444, 0x06f8, 0x0dfb,
280 0x1d0f, 0x198d, 0x0700, 0x0afc, 0x1781, 0x12f3, 0x10da, 0x1f19,
281 0x1055, 0x0dc9, 0x1860, 0x012b, 0x05bf, 0x082d, 0x0c17, 0x1941,
282 0x0359, 0x1232, 0x104c, 0x0762, 0x0897, 0x1d6c, 0x030f, 0x1a36,
283 0x16b0, 0x094d, 0x1782, 0x036f, 0x0eea, 0x06e6, 0x0d00, 0x0187,
284 0x17e2, 0x05e5, 0x19fa, 0x1950, 0x146a, 0x0b2a, 0x0512, 0x0ee0,
285 0x1e27, 0x112d, 0x1df0, 0x0b13, 0x0378, 0x1dd0, 0x00c1, 0x01e6
286 };
287
00 (*
1 Copyright (C) 2003-2008 Samuel Mimram
2
3 This file is part of Ocaml-faad.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1 * Copyright (C) 2003-2008 Samuel Mimram
2 * (C) 2006-2010 The Savonet Team
3 *
4 * Ocaml-faad is free software; you can redistribute it and/or modify<F12>
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * Ocaml-faad 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 General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Ocaml-faad; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1817 *)
1918
2019 type t
3130
3231 external create : unit -> t = "ocaml_faad_open"
3332
34 (* TODO: finalizer *)
35 external close : t -> unit = "ocaml_faad_close"
36
3733 external init : t -> string -> int -> int -> int * int * int = "ocaml_faad_init"
38 external init2 : t -> string -> int -> int -> int * int = "ocaml_faad_init2"
3934
4035 external decode : t -> string -> int -> int -> int * (float array array) = "ocaml_faad_decode"
4136
9388
9489 external metadata : t -> (string * string) array = "ocaml_faad_mp4_metadata"
9590 end
91
00 (*
1 Copyright (C) 2003-2008 Samuel Mimram
2
3 This file is part of Ocaml-faad.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1 * Copyright (C) 2003-2008 Samuel Mimram
2 * (C) 2006-2010 The Savonet Team
3 *
4 * Ocaml-faad is free software; you can redistribute it and/or modify<F12>
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * Ocaml-faad 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 General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Ocaml-faad; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1817 *)
1918
2019 (**
3332 (** Get the error message corresponding to a raised [Error]. *)
3433 val error_message : int -> string
3534
36 (** Create a new decoder. *)
3735 val create : unit -> t
38
39 (** Close a decoder. *)
40 val close : t -> unit
4136
4237 (** [init dec buf ofs len] initializes a decoder given the [len] bytes of data
4338 * in [buf] starting at offset [ofs]. It returns the offset (number of bytes to
4439 * skip), the samplerate and the number of channels of the stream. This function
45 * should be used for AAC data. For MP4 files, [init2] should be used instead.
46 *)
40 * should be used for AAC data. *)
4741 val init : t -> string -> int -> int -> int * int * int
48
49 (** Same as [init] but for MP4 files. Returns the samplerate and the number of
50 * channels. *)
51 val init2 : t -> string -> int -> int -> int * int
5242
5343 (** [decode dec buf ofs len] decodes at most [len] bytes of data in [buf]
5444 * starting at offset [ofs]. It returns the number of bytes actually decoded
00 /*
11 * Copyright (C) 2003-2008 Samuel Mimram
2 * (C) 2008-2010 The Savonet Team
23 *
34 * This file is part of Ocaml-faad.
45 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
6 * Ocaml-faad is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
910 *
10 * This library is distributed in the hope that it will be useful,
11 * Ocaml-faad is distributed in the hope that it will be useful,
1112 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
1415 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 * You should have received a copy of the GNU General Public License
17 * along with Ocaml-faad; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1819 */
1920
2021 /**
3940 #include <stdio.h>
4041
4142 #include <neaacdec.h>
42 #include <mp4ff.h>
43 #include "mp4ff.h"
4344
4445 static void check_err(int n)
4546 {
4748 caml_raise_constant(*caml_named_value("ocaml_faad_exn_failed"));
4849 }
4950
50 #define Dec_val(v) ((NeAACDecHandle)v)
51 #define Dec_val(v) (*(NeAACDecHandle*)Data_custom_val(v))
52
53 static void finalize_faad_dec(value l)
54 {
55 NeAACDecHandle dh = Dec_val(l);
56 NeAACDecClose(dh);
57 }
58
59 static struct custom_operations faad_dec_ops =
60 {
61 "ocaml_faad_dec",
62 finalize_faad_dec,
63 custom_compare_default,
64 custom_hash_default,
65 custom_serialize_default,
66 custom_deserialize_default
67 };
5168
5269 CAMLprim value ocaml_faad_open(value unit)
5370 {
71 CAMLparam0();
72 CAMLlocal1(ret);
5473 NeAACDecHandle dh = NeAACDecOpen();
5574 NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration(dh);
5675
5776 conf->outputFormat = FAAD_FMT_FLOAT;
5877 NeAACDecSetConfiguration(dh, conf);
5978
60 return (value)dh;
61 }
62
63 CAMLprim value ocaml_faad_close(value dh)
64 {
65 NeAACDecClose(Dec_val(dh));
66
67 return Val_unit;
68 }
69
70 CAMLprim value ocaml_faad_init(value dh, value buf, value ofs, value len)
71 {
72 u_int32_t samplerate;
79 ret = caml_alloc_custom(&faad_dec_ops, sizeof(NeAACDecHandle), 0, 1);
80 Dec_val(ret) = dh;
81
82 CAMLreturn(ret);
83 }
84
85 #include <stdio.h>
86
87 CAMLprim value ocaml_faad_init(value dh, value _buf, value _ofs, value _len)
88 {
89 CAMLparam2(dh,_buf);
90 CAMLlocal1(ans);
91
92 unsigned long samplerate;
7393 u_int8_t channels;
74 int32_t ret;
75 value ans;
76
77 ret = NeAACDecInit(Dec_val(dh), (unsigned char*)String_val(buf)+Int_val(ofs), Int_val(len), &samplerate, &channels);
78 check_err(ret);
94 int32_t offset;
95 int32_t pre_offset = 0;
96 int ofs = Int_val(_ofs);
97 int len = Int_val(_len);
98 unsigned char *buf = (unsigned char*)String_val(_buf);
99 int i;
100
101 /* ADTS mpeg file can be a stream and start in the middle of a
102 * frame so we need to have extra loop check here */
103 for (i = ofs; i < len - 1; i++)
104 {
105 if (buf[i] == 0xff && (buf[i+1] & 0xf6) == 0xf0)
106 {
107 pre_offset = i;
108 break;
109 }
110 }
111
112 offset = NeAACDecInit(Dec_val(dh), buf+ofs+pre_offset, len-pre_offset, &samplerate, &channels);
113 check_err(offset);
79114
80115 ans = caml_alloc_tuple(3);
81 Store_field(ans, 0, Val_int(ret));
116 Store_field(ans, 0, Val_int(offset+pre_offset));
82117 Store_field(ans, 1, Val_int(samplerate));
83118 Store_field(ans, 2, Val_int(channels));
84 return ans;
85 }
86
87 CAMLprim value ocaml_faad_init2(value dh, value buf, value ofs, value len)
88 {
89 u_int32_t samplerate;
90 u_int8_t channels;
91 int8_t ret;
92 value ans;
93
94 ret = NeAACDecInit2(Dec_val(dh), (unsigned char*)String_val(buf)+Int_val(ofs), Int_val(len), &samplerate, &channels);
95 check_err(ret);
96
97 ans = caml_alloc_tuple(2);
98 Store_field(ans, 0, Val_int(samplerate));
99 Store_field(ans, 1, Val_int(channels));
100 return ans;
101 }
102
103 CAMLprim value ocaml_faad_decode(value dh, value _inbuf, value _inbufofs, value _inbuflen)
104 {
105 CAMLparam1(_inbuf);
119 CAMLreturn(ans);
120 }
121
122 CAMLprim value ocaml_faad_decode(value _dh, value _inbuf, value _inbufofs, value _inbuflen)
123 {
124 CAMLparam2(_dh,_inbuf);
106125 CAMLlocal2(ans, outbuf);
107126 NeAACDecFrameInfo frameInfo;
108127 int inbufofs = Int_val(_inbufofs);
113132
114133 memcpy(inbuf, String_val(_inbuf)+inbufofs, inbuflen);
115134
116 caml_enter_blocking_section();
117 data = NeAACDecDecode(Dec_val(dh), &frameInfo, inbuf, inbuflen);
135 NeAACDecHandle dh = Dec_val(_dh);
136
137 caml_enter_blocking_section();
138 data = NeAACDecDecode(dh, &frameInfo, inbuf, inbuflen);
118139 caml_leave_blocking_section();
119140
120141 free(inbuf);
121142
122 if (!data)
123 caml_raise_constant(*caml_named_value("ocaml_faad_exn_failed"));
124143 if (frameInfo.error != 0)
125144 caml_raise_with_arg(*caml_named_value("ocaml_faad_exn_error"), Val_int(frameInfo.error));
126145
387406 mp4_t *mp = Mp4_val(m);
388407 int t = Int_val(track);
389408 int ret;
390 unsigned int samplerate;
409 long unsigned int samplerate;
391410 unsigned char channels;
392411 NeAACDecHandle dec = Dec_val(dh);
393412
406425
407426 CAMLreturn(ans);
408427 }
409
410 /*
411 file_time = mp4ff_get_track_duration_use_offsets(mp4fh, track);
412 scale = mp4ff_time_scale(mp4fh, track);
413 */
414428
415429 CAMLprim value ocaml_faad_mp4_num_samples(value m, value track)
416430 {
479493 CAMLreturn(ans);
480494 }
481495
482 /* Same as Faad.decode (Faad.Mp4.read_sample) but more efficient. Share code? */
496 // Same as Faad.decode (Faad.Mp4.read_sample) but more efficient. Share code?
483497 CAMLprim value ocaml_faad_mp4_decode(value m, value track, value sample, value dh)
484498 {
485499 CAMLparam4(m, track, sample, dh);
0 /*
1 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
2 ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
3 **
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU General Public License as published by
6 ** the Free Software Foundation; either version 2 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 General Public License for more details.
13 **
14 ** You should have received a copy of the GNU 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 ** Any non-GPL usage of this software or parts of this software is strictly
19 ** forbidden.
20 **
21 ** Commercial non-GPL licensing of this software is possible.
22 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
23 **
24 ** $Id: mp4atom.c,v 1.22 2005/02/01 13:15:55 menno Exp $
25 **/
26
27 #include <stdlib.h>
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #ifdef _WIN32
33 #include <tchar.h>
34 #ifdef ITUNES_DRM
35 #include <shlobj.h>
36 #endif
37 #include <windows.h>
38 #endif
39 #ifdef HAVE_GETPWUID
40 # include <pwd.h>
41 #endif
42 #ifdef HAVE_STRING_H
43 # include <string.h>
44 #endif
45 #include "mp4ffint.h"
46
47 #include "drms.h"
48
49 /* parse atom header size */
50 int32_t mp4ff_atom_get_size(const uint8_t *data)
51 {
52 uint32_t result;
53 uint32_t a, b, c, d;
54
55 a = (uint8_t)data[0];
56 b = (uint8_t)data[1];
57 c = (uint8_t)data[2];
58 d = (uint8_t)data[3];
59
60 result = (a<<24) | (b<<16) | (c<<8) | d;
61 //if (result > 0 && result < 8) result = 8;
62
63 return (int32_t)result;
64 }
65
66 /* comnapre 2 atom names, returns 1 for equal, 0 for unequal */
67 int32_t mp4ff_atom_compare(const int8_t a1, const int8_t b1, const int8_t c1, const int8_t d1,
68 const int8_t a2, const int8_t b2, const int8_t c2, const int8_t d2)
69 {
70 if (a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2)
71 return 1;
72 else
73 return 0;
74 }
75
76 uint8_t mp4ff_atom_name_to_type(const int8_t a, const int8_t b,
77 const int8_t c, const int8_t d)
78 {
79 if (a == 'm')
80 {
81 if (mp4ff_atom_compare(a,b,c,d, 'm','o','o','v'))
82 return ATOM_MOOV;
83 else if (mp4ff_atom_compare(a,b,c,d, 'm','i','n','f'))
84 return ATOM_MINF;
85 else if (mp4ff_atom_compare(a,b,c,d, 'm','d','i','a'))
86 return ATOM_MDIA;
87 else if (mp4ff_atom_compare(a,b,c,d, 'm','d','a','t'))
88 return ATOM_MDAT;
89 else if (mp4ff_atom_compare(a,b,c,d, 'm','d','h','d'))
90 return ATOM_MDHD;
91 else if (mp4ff_atom_compare(a,b,c,d, 'm','v','h','d'))
92 return ATOM_MVHD;
93 else if (mp4ff_atom_compare(a,b,c,d, 'm','p','4','a'))
94 return ATOM_MP4A;
95 else if (mp4ff_atom_compare(a,b,c,d, 'm','p','4','v'))
96 return ATOM_MP4V;
97 else if (mp4ff_atom_compare(a,b,c,d, 'm','p','4','s'))
98 return ATOM_MP4S;
99 else if (mp4ff_atom_compare(a,b,c,d, 'm','e','t','a'))
100 return ATOM_META;
101 } else if (a == 't') {
102 if (mp4ff_atom_compare(a,b,c,d, 't','r','a','k'))
103 return ATOM_TRAK;
104 else if (mp4ff_atom_compare(a,b,c,d, 't','k','h','d'))
105 return ATOM_TKHD;
106 else if (mp4ff_atom_compare(a,b,c,d, 't','r','e','f'))
107 return ATOM_TREF;
108 else if (mp4ff_atom_compare(a,b,c,d, 't','r','k','n'))
109 return ATOM_TRACK;
110 else if (mp4ff_atom_compare(a,b,c,d, 't','m','p','o'))
111 return ATOM_TEMPO;
112 } else if (a == 's') {
113 if (mp4ff_atom_compare(a,b,c,d, 's','t','b','l'))
114 return ATOM_STBL;
115 else if (mp4ff_atom_compare(a,b,c,d, 's','m','h','d'))
116 return ATOM_SMHD;
117 else if (mp4ff_atom_compare(a,b,c,d, 's','t','s','d'))
118 return ATOM_STSD;
119 else if (mp4ff_atom_compare(a,b,c,d, 's','t','t','s'))
120 return ATOM_STTS;
121 else if (mp4ff_atom_compare(a,b,c,d, 's','t','c','o'))
122 return ATOM_STCO;
123 else if (mp4ff_atom_compare(a,b,c,d, 's','t','s','c'))
124 return ATOM_STSC;
125 else if (mp4ff_atom_compare(a,b,c,d, 's','t','s','z'))
126 return ATOM_STSZ;
127 else if (mp4ff_atom_compare(a,b,c,d, 's','t','z','2'))
128 return ATOM_STZ2;
129 else if (mp4ff_atom_compare(a,b,c,d, 's','k','i','p'))
130 return ATOM_SKIP;
131 else if (mp4ff_atom_compare(a,b,c,d, 's','i','n','f'))
132 return ATOM_SINF;
133 else if (mp4ff_atom_compare(a,b,c,d, 's','c','h','i'))
134 return ATOM_SCHI;
135 } else if (a == '©') {
136 if (mp4ff_atom_compare(a,b,c,d, '©','n','a','m'))
137 return ATOM_TITLE;
138 else if (mp4ff_atom_compare(a,b,c,d, '©','A','R','T'))
139 return ATOM_ARTIST;
140 else if (mp4ff_atom_compare(a,b,c,d, '©','w','r','t'))
141 return ATOM_WRITER;
142 else if (mp4ff_atom_compare(a,b,c,d, '©','a','l','b'))
143 return ATOM_ALBUM;
144 else if (mp4ff_atom_compare(a,b,c,d, '©','d','a','y'))
145 return ATOM_DATE;
146 else if (mp4ff_atom_compare(a,b,c,d, '©','t','o','o'))
147 return ATOM_TOOL;
148 else if (mp4ff_atom_compare(a,b,c,d, '©','c','m','t'))
149 return ATOM_COMMENT;
150 else if (mp4ff_atom_compare(a,b,c,d, '©','g','e','n'))
151 return ATOM_GENRE1;
152 }
153
154 if (mp4ff_atom_compare(a,b,c,d, 'e','d','t','s'))
155 return ATOM_EDTS;
156 else if (mp4ff_atom_compare(a,b,c,d, 'e','s','d','s'))
157 return ATOM_ESDS;
158 else if (mp4ff_atom_compare(a,b,c,d, 'f','t','y','p'))
159 return ATOM_FTYP;
160 else if (mp4ff_atom_compare(a,b,c,d, 'f','r','e','e'))
161 return ATOM_FREE;
162 else if (mp4ff_atom_compare(a,b,c,d, 'h','m','h','d'))
163 return ATOM_HMHD;
164 else if (mp4ff_atom_compare(a,b,c,d, 'v','m','h','d'))
165 return ATOM_VMHD;
166 else if (mp4ff_atom_compare(a,b,c,d, 'u','d','t','a'))
167 return ATOM_UDTA;
168 else if (mp4ff_atom_compare(a,b,c,d, 'i','l','s','t'))
169 return ATOM_ILST;
170 else if (mp4ff_atom_compare(a,b,c,d, 'n','a','m','e'))
171 return ATOM_NAME;
172 else if (mp4ff_atom_compare(a,b,c,d, 'd','a','t','a'))
173 return ATOM_DATA;
174 else if (mp4ff_atom_compare(a,b,c,d, 'd','i','s','k'))
175 return ATOM_DISC;
176 else if (mp4ff_atom_compare(a,b,c,d, 'g','n','r','e'))
177 return ATOM_GENRE2;
178 else if (mp4ff_atom_compare(a,b,c,d, 'c','o','v','r'))
179 return ATOM_COVER;
180 else if (mp4ff_atom_compare(a,b,c,d, 'c','p','i','l'))
181 return ATOM_COMPILATION;
182 else if (mp4ff_atom_compare(a,b,c,d, 'c','t','t','s'))
183 return ATOM_CTTS;
184 else if (mp4ff_atom_compare(a,b,c,d, 'd','r','m','s'))
185 return ATOM_DRMS;
186 else if (mp4ff_atom_compare(a,b,c,d, 'f','r','m','a'))
187 return ATOM_FRMA;
188 else if (mp4ff_atom_compare(a,b,c,d, 'p','r','i','v'))
189 return ATOM_PRIV;
190 else if (mp4ff_atom_compare(a,b,c,d, 'i','v','i','v'))
191 return ATOM_IVIV;
192 else if (mp4ff_atom_compare(a,b,c,d, 'u','s','e','r'))
193 return ATOM_USER;
194 else if (mp4ff_atom_compare(a,b,c,d, 'k','e','y',' '))
195 return ATOM_KEY;
196 else if (mp4ff_atom_compare(a,b,c,d, 'a','l','a','c'))
197 return ATOM_ALAC;
198 else
199 return ATOM_UNKNOWN;
200 }
201
202 /* read atom header, return atom size, atom size is with header included */
203 uint64_t mp4ff_atom_read_header(mp4ff_t *f, uint8_t *atom_type, uint8_t *header_size)
204 {
205 uint64_t size;
206 int32_t ret;
207 uint8_t atom_header[8];
208
209 ret = mp4ff_read_data(f, atom_header, 8);
210 if (ret != 8)
211 return 0;
212
213 size = mp4ff_atom_get_size(atom_header);
214 *header_size = 8;
215
216 /* check for 64 bit atom size */
217 if (size == 1)
218 {
219 *header_size = 16;
220 size = mp4ff_read_int64(f);
221 }
222
223 //printf("%c%c%c%c\n", atom_header[4], atom_header[5], atom_header[6], atom_header[7]);
224
225 *atom_type = mp4ff_atom_name_to_type(atom_header[4], atom_header[5], atom_header[6], atom_header[7]);
226
227 return size;
228 }
229
230 int32_t mp4ff_read_stsz(mp4ff_t *f)
231 {
232 mp4ff_read_char(f); /* version */
233 mp4ff_read_int24(f); /* flags */
234 f->track[f->total_tracks - 1]->stsz_sample_size = mp4ff_read_int32(f);
235 f->track[f->total_tracks - 1]->stsz_sample_count = mp4ff_read_int32(f);
236
237 if (f->track[f->total_tracks - 1]->stsz_sample_size == 0)
238 {
239 int32_t i;
240 f->track[f->total_tracks - 1]->stsz_table =
241 (int32_t*)malloc(f->track[f->total_tracks - 1]->stsz_sample_count*sizeof(int32_t));
242
243 for (i = 0; i < f->track[f->total_tracks - 1]->stsz_sample_count; i++)
244 {
245 f->track[f->total_tracks - 1]->stsz_table[i] = mp4ff_read_int32(f);
246 }
247 }
248
249 return 0;
250 }
251
252 int32_t mp4ff_read_esds(mp4ff_t *f)
253 {
254 uint8_t tag;
255 uint32_t temp;
256
257 mp4ff_read_char(f); /* version */
258 mp4ff_read_int24(f); /* flags */
259
260 /* get and verify ES_DescrTag */
261 tag = mp4ff_read_char(f);
262 if (tag == 0x03)
263 {
264 /* read length */
265 if (mp4ff_read_mp4_descr_length(f) < 5 + 15)
266 {
267 return 1;
268 }
269 /* skip 3 bytes */
270 mp4ff_read_int24(f);
271 } else {
272 /* skip 2 bytes */
273 mp4ff_read_int16(f);
274 }
275
276 /* get and verify DecoderConfigDescrTab */
277 if (mp4ff_read_char(f) != 0x04)
278 {
279 return 1;
280 }
281
282 /* read length */
283 temp = mp4ff_read_mp4_descr_length(f);
284 if (temp < 13) return 1;
285
286 f->track[f->total_tracks - 1]->audioType = mp4ff_read_char(f);
287 mp4ff_read_int32(f);//0x15000414 ????
288 f->track[f->total_tracks - 1]->maxBitrate = mp4ff_read_int32(f);
289 f->track[f->total_tracks - 1]->avgBitrate = mp4ff_read_int32(f);
290
291 /* get and verify DecSpecificInfoTag */
292 if (mp4ff_read_char(f) != 0x05)
293 {
294 return 1;
295 }
296
297 /* read length */
298 f->track[f->total_tracks - 1]->decoderConfigLen = mp4ff_read_mp4_descr_length(f);
299
300 if (f->track[f->total_tracks - 1]->decoderConfig)
301 free(f->track[f->total_tracks - 1]->decoderConfig);
302 f->track[f->total_tracks - 1]->decoderConfig = malloc(f->track[f->total_tracks - 1]->decoderConfigLen);
303 if (f->track[f->total_tracks - 1]->decoderConfig)
304 {
305 mp4ff_read_data(f, f->track[f->total_tracks - 1]->decoderConfig, f->track[f->total_tracks - 1]->decoderConfigLen);
306 } else {
307 f->track[f->total_tracks - 1]->decoderConfigLen = 0;
308 }
309
310 /* will skip the remainder of the atom */
311 return 0;
312 }
313
314 int32_t mp4ff_read_mp4a(mp4ff_t *f)
315 {
316 uint64_t size;
317 int32_t i;
318 uint8_t atom_type = 0;
319 uint8_t header_size = 0;
320
321 for (i = 0; i < 6; i++)
322 {
323 mp4ff_read_char(f); /* reserved */
324 }
325 /* data_reference_index */ mp4ff_read_int16(f);
326
327 mp4ff_read_int32(f); /* reserved */
328 mp4ff_read_int32(f); /* reserved */
329
330 f->track[f->total_tracks - 1]->channelCount = mp4ff_read_int16(f);
331 f->track[f->total_tracks - 1]->sampleSize = mp4ff_read_int16(f);
332
333 mp4ff_read_int16(f);
334 mp4ff_read_int16(f);
335
336 f->track[f->total_tracks - 1]->sampleRate = mp4ff_read_int16(f);
337
338 mp4ff_read_int16(f);
339
340 size = mp4ff_atom_read_header(f, &atom_type, &header_size);
341 if (atom_type == ATOM_ESDS)
342 {
343 mp4ff_read_esds(f);
344 }
345
346 return 0;
347 }
348
349 int32_t mp4ff_read_alac(mp4ff_t *f)
350 {
351 mp4ff_track_t *current_track = f->track[f->total_tracks - 1];
352
353 mp4ff_read_int32(f);
354 mp4ff_read_int32(f);
355 mp4ff_read_int32(f);
356 mp4ff_read_int32(f);
357 mp4ff_read_int32(f);
358 mp4ff_read_int32(f);
359 mp4ff_read_int32(f);
360
361 current_track->decoderConfigLen = 36;
362 if (current_track->decoderConfig)
363 free(current_track->decoderConfig);
364 current_track->decoderConfig = calloc(1, current_track->decoderConfigLen);
365
366 if (current_track->decoderConfig)
367 {
368 mp4ff_read_data(f, current_track->decoderConfig,
369 current_track->decoderConfigLen);
370 } else {
371 current_track->decoderConfigLen = 0;
372 }
373
374 current_track->channelCount = current_track->decoderConfig[21];
375 current_track->avgBitrate = (current_track->decoderConfig[28] << 24) |
376 (current_track->decoderConfig[29] << 16) |
377 (current_track->decoderConfig[30] << 8) |
378 current_track->decoderConfig[31];
379 current_track->sampleRate = (current_track->decoderConfig[32] << 24) |
380 (current_track->decoderConfig[33] << 16) |
381 (current_track->decoderConfig[34] << 8) |
382 current_track->decoderConfig[35];
383 current_track->audioType = 0xff;
384
385 /* will skip the remainder of the atom */
386 return 0;
387 }
388
389 #ifdef ITUNES_DRM
390 char *GetHomeDir( void )
391 {
392 char *p_tmp, *p_homedir = NULL;
393
394 #if defined(HAVE_GETPWUID)
395 struct passwd *p_pw = NULL;
396 #endif
397
398 #if defined(_WIN32) || defined(UNDER_CE)
399 typedef HRESULT (WINAPI *SHGETFOLDERPATH)( HWND, int, HANDLE, DWORD,
400 LPSTR );
401 # define CSIDL_FLAG_CREATE 0x8000
402 # define CSIDL_APPDATA 0x1A
403 # define SHGFP_TYPE_CURRENT 0
404
405 HINSTANCE shfolder_dll;
406 SHGETFOLDERPATH SHGetFolderPath ;
407 /* load the shfolder dll to retrieve SHGetFolderPath */
408 if( ( shfolder_dll = LoadLibrary( _T("SHFolder.dll") ) ) != NULL )
409 {
410 SHGetFolderPath = (void *)GetProcAddress( shfolder_dll,
411 _T("SHGetFolderPathA") );
412 if ( SHGetFolderPath != NULL )
413 {
414 p_homedir = (char *)malloc( MAX_PATH );
415 if( !p_homedir )
416 {
417 return NULL;
418 }
419
420 /* get the "Application Data" folder for the current user */
421 if( S_OK == SHGetFolderPath( NULL,
422 CSIDL_APPDATA | CSIDL_FLAG_CREATE,
423 NULL, SHGFP_TYPE_CURRENT,
424 p_homedir ) )
425 {
426 FreeLibrary( shfolder_dll );
427 return p_homedir;
428 }
429 free( p_homedir );
430 }
431 FreeLibrary( shfolder_dll );
432 }
433 #endif
434
435 #if defined(HAVE_GETPWUID)
436 if( ( p_pw = getpwuid( getuid() ) ) == NULL )
437 #endif
438 {
439 if( ( p_tmp = getenv( "HOME" ) ) == NULL )
440 {
441 if( ( p_tmp = getenv( "TMP" ) ) == NULL )
442 {
443 p_tmp = "/tmp";
444 }
445 }
446
447 p_homedir = strdup( p_tmp );
448 }
449 #if defined(HAVE_GETPWUID)
450 else
451 {
452 p_homedir = strdup( p_pw->pw_dir );
453 }
454 #endif
455
456 return p_homedir;
457 }
458
459 static int32_t mp4ff_read_drms(mp4ff_t *f, uint64_t skip)
460 {
461 uint64_t size;
462 int32_t i;
463 uint8_t atom_type = 0;
464 uint8_t header_size = 0;
465 char *home_dir;
466
467 home_dir = GetHomeDir();
468 f->track[f->total_tracks - 1]->p_drms = drms_alloc( home_dir );
469 free(home_dir);
470
471 for (i = 0; i < 6; i++)
472 {
473 mp4ff_read_char(f); /* reserved */
474 }
475 /* data_reference_index */ mp4ff_read_int16(f);
476
477 mp4ff_read_int32(f); /* reserved */
478 mp4ff_read_int32(f); /* reserved */
479
480 f->track[f->total_tracks - 1]->channelCount = mp4ff_read_int16(f);
481 f->track[f->total_tracks - 1]->sampleSize = mp4ff_read_int16(f);
482
483 mp4ff_read_int16(f);
484 mp4ff_read_int16(f);
485
486 f->track[f->total_tracks - 1]->sampleRate = mp4ff_read_int16(f);
487
488 mp4ff_read_int16(f);
489
490 size = mp4ff_atom_read_header(f, &atom_type, &header_size);
491 if (atom_type == ATOM_ESDS)
492 {
493 mp4ff_read_esds(f);
494 }
495 mp4ff_set_position(f, skip+size+28);
496
497 size = mp4ff_atom_read_header(f, &atom_type, &header_size);
498 if (atom_type == ATOM_SINF)
499 {
500 parse_sub_atoms(f, size-header_size,0);
501 }
502
503 return 0;
504 }
505
506 static int32_t mp4ff_read_frma(mp4ff_t *f)
507 {
508 uint8_t atom_type;
509 uint8_t type[4];
510
511 mp4ff_read_data(f, type, 4);
512
513 atom_type = mp4ff_atom_name_to_type(type[0], type[1], type[2], type[3]);
514
515 if (atom_type == ATOM_MP4A)
516 {
517 f->track[f->total_tracks - 1]->type = TRACK_AUDIO;
518 } else if (atom_type == ATOM_MP4V) {
519 f->track[f->total_tracks - 1]->type = TRACK_VIDEO;
520 } else if (atom_type == ATOM_MP4S) {
521 f->track[f->total_tracks - 1]->type = TRACK_SYSTEM;
522 } else {
523 f->track[f->total_tracks - 1]->type = TRACK_UNKNOWN;
524 }
525
526 return 0;
527 }
528
529 static int32_t mp4ff_read_name(mp4ff_t *f, uint64_t size)
530 {
531 uint8_t *data = malloc(size);
532 mp4ff_read_data(f, data, size);
533
534 if (f->track[f->total_tracks - 1]->p_drms != NULL)
535 {
536 drms_init(f->track[f->total_tracks - 1]->p_drms,
537 FOURCC_name, data, strlen((char *)data) );
538 }
539
540 if (data)
541 free(data);
542
543 return 0;
544 }
545
546 static int32_t mp4ff_read_priv(mp4ff_t *f, uint64_t size)
547 {
548 uint8_t *data = malloc(size);
549 mp4ff_read_data(f, data, size);
550
551 if (f->track[f->total_tracks - 1]->p_drms != 0)
552 {
553 drms_init(f->track[f->total_tracks - 1]->p_drms,
554 FOURCC_priv, data, size );
555 }
556
557 if (data)
558 free(data);
559
560 return 0;
561 }
562
563 static int32_t mp4ff_read_iviv(mp4ff_t *f, uint64_t size)
564 {
565 uint8_t *data = malloc(size);
566 mp4ff_read_data(f, data, size);
567
568 if (f->track[f->total_tracks - 1]->p_drms != 0)
569 {
570 drms_init(f->track[f->total_tracks - 1]->p_drms,
571 FOURCC_iviv, data, sizeof(uint32_t) * 4 );
572 }
573
574 if (data)
575 free(data);
576
577 return 0;
578 }
579
580 static int32_t mp4ff_read_user(mp4ff_t *f, uint64_t size)
581 {
582 uint8_t *data = malloc(size);
583 mp4ff_read_data(f, data, size);
584
585 if (f->track[f->total_tracks - 1]->p_drms != 0)
586 {
587 drms_init(f->track[f->total_tracks - 1]->p_drms,
588 FOURCC_user, data, size );
589 }
590
591 if (data)
592 free(data);
593
594 return 0;
595 }
596
597 static int32_t mp4ff_read_key(mp4ff_t *f, uint64_t size)
598 {
599 uint8_t *data = malloc(size);
600 mp4ff_read_data(f, data, size);
601
602 if (f->track[f->total_tracks - 1]->p_drms != 0)
603 {
604 drms_init(f->track[f->total_tracks - 1]->p_drms,
605 FOURCC_key, data, size );
606 }
607
608 if (data)
609 free(data);
610
611 return 0;
612 }
613 #endif
614
615 int32_t mp4ff_read_stsd(mp4ff_t *f)
616 {
617 int32_t i;
618 uint8_t header_size = 0;
619
620 mp4ff_read_char(f); /* version */
621 mp4ff_read_int24(f); /* flags */
622
623 f->track[f->total_tracks - 1]->stsd_entry_count = mp4ff_read_int32(f);
624
625 for (i = 0; i < f->track[f->total_tracks - 1]->stsd_entry_count; i++)
626 {
627 uint64_t skip = mp4ff_position(f);
628 uint64_t size;
629 uint8_t atom_type = 0;
630 size = mp4ff_atom_read_header(f, &atom_type, &header_size);
631 skip += size;
632
633 if (atom_type == ATOM_MP4A)
634 {
635 f->track[f->total_tracks - 1]->type = TRACK_AUDIO;
636 mp4ff_read_mp4a(f);
637 } else if (atom_type == ATOM_ALAC) {
638 f->track[f->total_tracks - 1]->type = TRACK_AUDIO;
639 mp4ff_read_alac(f);
640 } else if (atom_type == ATOM_MP4V) {
641 f->track[f->total_tracks - 1]->type = TRACK_VIDEO;
642 } else if (atom_type == ATOM_MP4S) {
643 f->track[f->total_tracks - 1]->type = TRACK_SYSTEM;
644 #ifdef ITUNES_DRM
645 } else if (atom_type == ATOM_DRMS) {
646 // track type is read from the "frma" atom
647 f->track[f->total_tracks - 1]->type = TRACK_UNKNOWN;
648 mp4ff_read_drms(f, skip-size+header_size);
649 #endif
650 } else {
651 f->track[f->total_tracks - 1]->type = TRACK_UNKNOWN;
652 }
653
654 mp4ff_set_position(f, skip);
655 }
656
657 return 0;
658 }
659
660 int32_t mp4ff_read_stsc(mp4ff_t *f)
661 {
662 int32_t i;
663
664 mp4ff_read_char(f); /* version */
665 mp4ff_read_int24(f); /* flags */
666 f->track[f->total_tracks - 1]->stsc_entry_count = mp4ff_read_int32(f);
667
668 f->track[f->total_tracks - 1]->stsc_first_chunk =
669 (int32_t*)malloc(f->track[f->total_tracks - 1]->stsc_entry_count*sizeof(int32_t));
670 f->track[f->total_tracks - 1]->stsc_samples_per_chunk =
671 (int32_t*)malloc(f->track[f->total_tracks - 1]->stsc_entry_count*sizeof(int32_t));
672 f->track[f->total_tracks - 1]->stsc_sample_desc_index =
673 (int32_t*)malloc(f->track[f->total_tracks - 1]->stsc_entry_count*sizeof(int32_t));
674
675 for (i = 0; i < f->track[f->total_tracks - 1]->stsc_entry_count; i++)
676 {
677 f->track[f->total_tracks - 1]->stsc_first_chunk[i] = mp4ff_read_int32(f);
678 f->track[f->total_tracks - 1]->stsc_samples_per_chunk[i] = mp4ff_read_int32(f);
679 f->track[f->total_tracks - 1]->stsc_sample_desc_index[i] = mp4ff_read_int32(f);
680 }
681
682 return 0;
683 }
684
685 int32_t mp4ff_read_stco(mp4ff_t *f)
686 {
687 int32_t i;
688
689 mp4ff_read_char(f); /* version */
690 mp4ff_read_int24(f); /* flags */
691 f->track[f->total_tracks - 1]->stco_entry_count = mp4ff_read_int32(f);
692
693 f->track[f->total_tracks - 1]->stco_chunk_offset =
694 (int32_t*)malloc(f->track[f->total_tracks - 1]->stco_entry_count*sizeof(int32_t));
695
696 for (i = 0; i < f->track[f->total_tracks - 1]->stco_entry_count; i++)
697 {
698 f->track[f->total_tracks - 1]->stco_chunk_offset[i] = mp4ff_read_int32(f);
699 }
700
701 return 0;
702 }
703
704 static int32_t mp4ff_read_ctts(mp4ff_t *f)
705 {
706 int32_t i;
707 mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
708
709 if (p_track->ctts_entry_count) return 0;
710
711 mp4ff_read_char(f); /* version */
712 mp4ff_read_int24(f); /* flags */
713 p_track->ctts_entry_count = mp4ff_read_int32(f);
714
715 p_track->ctts_sample_count = (int32_t*)malloc(p_track->ctts_entry_count * sizeof(int32_t));
716 p_track->ctts_sample_offset = (int32_t*)malloc(p_track->ctts_entry_count * sizeof(int32_t));
717
718 if (p_track->ctts_sample_count == 0 || p_track->ctts_sample_offset == 0)
719 {
720 if (p_track->ctts_sample_count) {free(p_track->ctts_sample_count);p_track->ctts_sample_count=0;}
721 if (p_track->ctts_sample_offset) {free(p_track->ctts_sample_offset);p_track->ctts_sample_offset=0;}
722 p_track->ctts_entry_count = 0;
723 return 0;
724 }
725 else
726 {
727 for (i = 0; i < f->track[f->total_tracks - 1]->ctts_entry_count; i++)
728 {
729 p_track->ctts_sample_count[i] = mp4ff_read_int32(f);
730 p_track->ctts_sample_offset[i] = mp4ff_read_int32(f);
731 }
732 return 1;
733 }
734 }
735
736 int32_t mp4ff_read_stts(mp4ff_t *f)
737 {
738 int32_t i;
739 mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
740
741 if (p_track->stts_entry_count) return 0;
742
743 mp4ff_read_char(f); /* version */
744 mp4ff_read_int24(f); /* flags */
745 p_track->stts_entry_count = mp4ff_read_int32(f);
746
747 p_track->stts_sample_count = (int32_t*)malloc(p_track->stts_entry_count * sizeof(int32_t));
748 p_track->stts_sample_delta = (int32_t*)malloc(p_track->stts_entry_count * sizeof(int32_t));
749
750 if (p_track->stts_sample_count == 0 || p_track->stts_sample_delta == 0)
751 {
752 if (p_track->stts_sample_count) {free(p_track->stts_sample_count);p_track->stts_sample_count=0;}
753 if (p_track->stts_sample_delta) {free(p_track->stts_sample_delta);p_track->stts_sample_delta=0;}
754 p_track->stts_entry_count = 0;
755 return 0;
756 }
757 else
758 {
759 for (i = 0; i < f->track[f->total_tracks - 1]->stts_entry_count; i++)
760 {
761 p_track->stts_sample_count[i] = mp4ff_read_int32(f);
762 p_track->stts_sample_delta[i] = mp4ff_read_int32(f);
763 }
764 return 1;
765 }
766 }
767
768 static int32_t mp4ff_read_mvhd(mp4ff_t *f)
769 {
770 int32_t i;
771
772 mp4ff_read_char(f); /* version */
773 mp4ff_read_int24(f); /* flags */
774 /* creation_time */ mp4ff_read_int32(f);
775 /* modification_time */ mp4ff_read_int32(f);
776 f->time_scale = mp4ff_read_int32(f);
777 f->duration = mp4ff_read_int32(f);
778 /* preferred_rate */ mp4ff_read_int32(f); /*mp4ff_read_fixed32(f);*/
779 /* preferred_volume */ mp4ff_read_int16(f); /*mp4ff_read_fixed16(f);*/
780 for (i = 0; i < 10; i++)
781 {
782 /* reserved */ mp4ff_read_char(f);
783 }
784 for (i = 0; i < 9; i++)
785 {
786 mp4ff_read_int32(f); /* matrix */
787 }
788 /* preview_time */ mp4ff_read_int32(f);
789 /* preview_duration */ mp4ff_read_int32(f);
790 /* poster_time */ mp4ff_read_int32(f);
791 /* selection_time */ mp4ff_read_int32(f);
792 /* selection_duration */ mp4ff_read_int32(f);
793 /* current_time */ mp4ff_read_int32(f);
794 /* next_track_id */ mp4ff_read_int32(f);
795
796 return 0;
797 }
798
799 #if 0
800 static int32_t mp4ff_read_tkhd(mp4ff_t *f)
801 {
802 uint8_t version;
803 uint32_t flags;
804 version = mp4ff_read_char(f); /* version */
805 flags = mp4ff_read_int24(f); /* flags */
806 if (version==1)
807 {
808 mp4ff_read_int64(f);//creation-time
809 mp4ff_read_int64(f);//modification-time
810 mp4ff_read_int32(f);//track-id
811 mp4ff_read_int32(f);//reserved
812 f->track[f->total_tracks - 1]->duration = mp4ff_read_int64(f);//duration
813 }
814 else //version == 0
815 {
816 mp4ff_read_int32(f);//creation-time
817 mp4ff_read_int32(f);//modification-time
818 mp4ff_read_int32(f);//track-id
819 mp4ff_read_int32(f);//reserved
820 f->track[f->total_tracks - 1]->duration = mp4ff_read_int32(f);//duration
821 if (f->track[f->total_tracks - 1]->duration == 0xFFFFFFFF)
822 f->track[f->total_tracks - 1]->duration = 0xFFFFFFFFFFFFFFFF;
823
824 }
825 mp4ff_read_int32(f);//reserved
826 mp4ff_read_int32(f);//reserved
827 mp4ff_read_int16(f);//layer
828 mp4ff_read_int16(f);//pre-defined
829 mp4ff_read_int16(f);//volume
830 mp4ff_read_int16(f);//reserved
831
832 //matrix
833 mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f);
834 mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f);
835 mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f);
836 mp4ff_read_int32(f);//width
837 mp4ff_read_int32(f);//height
838 return 1;
839 }
840 #endif
841
842 static int32_t mp4ff_read_mdhd(mp4ff_t *f)
843 {
844 uint32_t version;
845
846 version = mp4ff_read_int32(f);
847 if (version==1)
848 {
849 mp4ff_read_int64(f);//creation-time
850 mp4ff_read_int64(f);//modification-time
851 f->track[f->total_tracks - 1]->timeScale = mp4ff_read_int32(f);//timescale
852 f->track[f->total_tracks - 1]->duration = mp4ff_read_int64(f);//duration
853 }
854 else //version == 0
855 {
856 uint32_t temp;
857
858 mp4ff_read_int32(f);//creation-time
859 mp4ff_read_int32(f);//modification-time
860 f->track[f->total_tracks - 1]->timeScale = mp4ff_read_int32(f);//timescale
861 temp = mp4ff_read_int32(f);
862 f->track[f->total_tracks - 1]->duration = (temp == (uint32_t)(-1)) ? (uint64_t)(-1) : (uint64_t)(temp);
863 }
864 mp4ff_read_int16(f);
865 mp4ff_read_int16(f);
866 return 1;
867 }
868 #ifdef USE_TAGGING
869 int32_t mp4ff_read_meta(mp4ff_t *f, const uint64_t size)
870 {
871 uint64_t subsize, sumsize = 0;
872 uint8_t atom_type;
873 uint8_t header_size = 0;
874
875 mp4ff_read_char(f); /* version */
876 mp4ff_read_int24(f); /* flags */
877
878 while (sumsize < (size-(header_size+4)))
879 {
880 subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
881 if (subsize <= header_size+4)
882 return 1;
883 if (atom_type == ATOM_ILST)
884 {
885 mp4ff_parse_metadata(f, (uint32_t)(subsize-(header_size+4)));
886 } else {
887 mp4ff_set_position(f, mp4ff_position(f)+subsize-header_size);
888 }
889 sumsize += subsize;
890 }
891
892 return 0;
893 }
894 #endif
895
896 int32_t mp4ff_atom_read(mp4ff_t *f, const int32_t size, const uint8_t atom_type)
897 {
898 uint64_t dest_position = mp4ff_position(f)+size-8;
899 if (atom_type == ATOM_STSZ)
900 {
901 /* sample size box */
902 mp4ff_read_stsz(f);
903 } else if (atom_type == ATOM_STTS) {
904 /* time to sample box */
905 mp4ff_read_stts(f);
906 } else if (atom_type == ATOM_CTTS) {
907 /* composition offset box */
908 mp4ff_read_ctts(f);
909 } else if (atom_type == ATOM_STSC) {
910 /* sample to chunk box */
911 mp4ff_read_stsc(f);
912 } else if (atom_type == ATOM_STCO) {
913 /* chunk offset box */
914 mp4ff_read_stco(f);
915 } else if (atom_type == ATOM_STSD) {
916 /* sample description box */
917 mp4ff_read_stsd(f);
918 } else if (atom_type == ATOM_MVHD) {
919 /* movie header box */
920 mp4ff_read_mvhd(f);
921 } else if (atom_type == ATOM_MDHD) {
922 /* track header */
923 mp4ff_read_mdhd(f);
924 #ifdef ITUNES_DRM
925 } else if (atom_type == ATOM_FRMA) {
926 /* DRM track format */
927 mp4ff_read_frma(f);
928 } else if (atom_type == ATOM_IVIV) {
929 mp4ff_read_iviv(f, size-8);
930 } else if (atom_type == ATOM_NAME) {
931 mp4ff_read_name(f, size-8);
932 } else if (atom_type == ATOM_PRIV) {
933 mp4ff_read_priv(f, size-8);
934 } else if (atom_type == ATOM_USER) {
935 mp4ff_read_user(f, size-8);
936 } else if (atom_type == ATOM_KEY) {
937 mp4ff_read_key(f, size-8);
938 #endif
939 #ifdef USE_TAGGING
940 } else if (atom_type == ATOM_META) {
941 /* iTunes Metadata box */
942 mp4ff_read_meta(f, size);
943 #endif
944 }
945
946 mp4ff_set_position(f, dest_position);
947
948
949 return 0;
950 }
0 /*
1 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
2 ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
3 **
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU General Public License as published by
6 ** the Free Software Foundation; either version 2 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 General Public License for more details.
13 **
14 ** You should have received a copy of the GNU 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 ** Any non-GPL usage of this software or parts of this software is strictly
19 ** forbidden.
20 **
21 ** Commercial non-GPL licensing of this software is possible.
22 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
23 **
24 ** $Id: mp4ff.c,v 1.17 2005/02/01 13:15:55 menno Exp $
25 **/
26
27 #include <stdlib.h>
28 #include <string.h>
29 #include "mp4ffint.h"
30
31 #include "drms.h"
32
33 mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f)
34 {
35 mp4ff_t *ff = malloc(sizeof(mp4ff_t));
36
37 memset(ff, 0, sizeof(mp4ff_t));
38
39 ff->stream = f;
40
41 parse_atoms(ff,0);
42
43 return ff;
44 }
45
46 mp4ff_t *mp4ff_open_read_metaonly(mp4ff_callback_t *f)
47 {
48 mp4ff_t *ff = malloc(sizeof(mp4ff_t));
49
50 memset(ff, 0, sizeof(mp4ff_t));
51
52 ff->stream = f;
53
54 parse_atoms(ff,1);
55
56 return ff;
57 }
58
59 void mp4ff_close(mp4ff_t *ff)
60 {
61 int32_t i;
62
63 for (i = 0; i < ff->total_tracks; i++)
64 {
65 if (ff->track[i])
66 {
67 if (ff->track[i]->stsz_table)
68 free(ff->track[i]->stsz_table);
69 if (ff->track[i]->stts_sample_count)
70 free(ff->track[i]->stts_sample_count);
71 if (ff->track[i]->stts_sample_delta)
72 free(ff->track[i]->stts_sample_delta);
73 if (ff->track[i]->stsc_first_chunk)
74 free(ff->track[i]->stsc_first_chunk);
75 if (ff->track[i]->stsc_samples_per_chunk)
76 free(ff->track[i]->stsc_samples_per_chunk);
77 if (ff->track[i]->stsc_sample_desc_index)
78 free(ff->track[i]->stsc_sample_desc_index);
79 if (ff->track[i]->stco_chunk_offset)
80 free(ff->track[i]->stco_chunk_offset);
81 if (ff->track[i]->decoderConfig)
82 free(ff->track[i]->decoderConfig);
83 if (ff->track[i]->ctts_sample_count)
84 free(ff->track[i]->ctts_sample_count);
85 if (ff->track[i]->ctts_sample_offset)
86 free(ff->track[i]->ctts_sample_offset);
87 #ifdef ITUNES_DRM
88 if (ff->track[i]->p_drms)
89 drms_free(ff->track[i]->p_drms);
90 #endif
91 free(ff->track[i]);
92 }
93 }
94
95 #ifdef USE_TAGGING
96 mp4ff_tag_delete(&(ff->tags));
97 #endif
98
99 if (ff) free(ff);
100 }
101
102 void mp4ff_track_add(mp4ff_t *f)
103 {
104 f->total_tracks++;
105
106 f->track[f->total_tracks - 1] = malloc(sizeof(mp4ff_track_t));
107
108 memset(f->track[f->total_tracks - 1], 0, sizeof(mp4ff_track_t));
109 }
110
111 static int need_parse_when_meta_only(uint8_t atom_type)
112 {
113 switch(atom_type)
114 {
115 case ATOM_EDTS:
116 // case ATOM_MDIA:
117 // case ATOM_MINF:
118 case ATOM_DRMS:
119 case ATOM_SINF:
120 case ATOM_SCHI:
121 // case ATOM_STBL:
122 // case ATOM_STSD:
123 case ATOM_STTS:
124 case ATOM_STSZ:
125 case ATOM_STZ2:
126 case ATOM_STCO:
127 case ATOM_STSC:
128 // case ATOM_CTTS:
129 case ATOM_FRMA:
130 case ATOM_IVIV:
131 case ATOM_PRIV:
132 return 0;
133 default:
134 return 1;
135 }
136 }
137
138 /* parse atoms that are sub atoms of other atoms */
139 int32_t parse_sub_atoms(mp4ff_t *f, const uint64_t total_size,int meta_only)
140 {
141 uint64_t size;
142 uint8_t atom_type = 0;
143 uint64_t counted_size = 0;
144 uint8_t header_size = 0;
145
146 while (counted_size < total_size)
147 {
148 size = mp4ff_atom_read_header(f, &atom_type, &header_size);
149 counted_size += size;
150
151 /* check for end of file */
152 if (size == 0)
153 break;
154
155 /* we're starting to read a new track, update index,
156 * so that all data and tables get written in the right place
157 */
158 if (atom_type == ATOM_TRAK)
159 {
160 mp4ff_track_add(f);
161 }
162
163 /* parse subatoms */
164 if (meta_only && !need_parse_when_meta_only(atom_type))
165 {
166 mp4ff_set_position(f, mp4ff_position(f)+size-header_size);
167 } else if (atom_type < SUBATOMIC)
168 {
169 parse_sub_atoms(f, size-header_size,meta_only);
170 } else {
171 mp4ff_atom_read(f, (uint32_t)size, atom_type);
172 }
173 }
174
175 return 0;
176 }
177
178 /* parse root atoms */
179 int32_t parse_atoms(mp4ff_t *f,int meta_only)
180 {
181 uint64_t size;
182 uint8_t atom_type = 0;
183 uint8_t header_size = 0;
184
185 f->file_size = 0;
186
187 while ((size = mp4ff_atom_read_header(f, &atom_type, &header_size)) != 0)
188 {
189 f->file_size += size;
190 f->last_atom = atom_type;
191
192 if (atom_type == ATOM_MDAT && f->moov_read)
193 {
194 /* moov atom is before mdat, we can stop reading when mdat is encountered */
195 /* file position will stay at beginning of mdat data */
196 /* break; */
197 }
198
199 if (atom_type == ATOM_MOOV && size > header_size)
200 {
201 f->moov_read = 1;
202 f->moov_offset = mp4ff_position(f)-header_size;
203 f->moov_size = size;
204 }
205
206 /* parse subatoms */
207 if (meta_only && !need_parse_when_meta_only(atom_type))
208 {
209 mp4ff_set_position(f, mp4ff_position(f)+size-header_size);
210 } else if (atom_type < SUBATOMIC)
211 {
212 parse_sub_atoms(f, size-header_size,meta_only);
213 } else {
214 /* skip this atom */
215 mp4ff_set_position(f, mp4ff_position(f)+size-header_size);
216 }
217 }
218
219 return 0;
220 }
221
222 int32_t mp4ff_get_decoder_config(const mp4ff_t *f, const int32_t track,
223 uint8_t** ppBuf, uint32_t* pBufSize)
224 {
225 if (track >= f->total_tracks)
226 {
227 *ppBuf = NULL;
228 *pBufSize = 0;
229 return 1;
230 }
231
232 if (f->track[track]->decoderConfig == NULL || f->track[track]->decoderConfigLen == 0)
233 {
234 *ppBuf = NULL;
235 *pBufSize = 0;
236 } else {
237 *ppBuf = malloc(f->track[track]->decoderConfigLen);
238 if (*ppBuf == NULL)
239 {
240 *pBufSize = 0;
241 return 1;
242 }
243 memcpy(*ppBuf, f->track[track]->decoderConfig, f->track[track]->decoderConfigLen);
244 *pBufSize = f->track[track]->decoderConfigLen;
245 }
246
247 return 0;
248 }
249
250 int32_t mp4ff_get_track_type(const mp4ff_t *f, const int track)
251 {
252 return f->track[track]->type;
253 }
254
255 int32_t mp4ff_total_tracks(const mp4ff_t *f)
256 {
257 return f->total_tracks;
258 }
259
260 int32_t mp4ff_time_scale(const mp4ff_t *f, const int32_t track)
261 {
262 return f->track[track]->timeScale;
263 }
264
265 uint32_t mp4ff_get_avg_bitrate(const mp4ff_t *f, const int32_t track)
266 {
267 return f->track[track]->avgBitrate;
268 }
269
270 uint32_t mp4ff_get_max_bitrate(const mp4ff_t *f, const int32_t track)
271 {
272 return f->track[track]->maxBitrate;
273 }
274
275 int64_t mp4ff_get_track_duration(const mp4ff_t *f, const int32_t track)
276 {
277 return f->track[track]->duration;
278 }
279
280 int64_t mp4ff_get_track_duration_use_offsets(const mp4ff_t *f, const int32_t track)
281 {
282 int64_t duration = mp4ff_get_track_duration(f,track);
283 if (duration!=-1)
284 {
285 int64_t offset = mp4ff_get_sample_offset(f,track,0);
286 if (offset > duration) duration = 0;
287 else duration -= offset;
288 }
289 return duration;
290 }
291
292
293 int32_t mp4ff_num_samples(const mp4ff_t *f, const int32_t track)
294 {
295 int32_t i;
296 int32_t total = 0;
297
298 for (i = 0; i < f->track[track]->stts_entry_count; i++)
299 {
300 total += f->track[track]->stts_sample_count[i];
301 }
302 return total;
303 }
304
305
306
307
308 uint32_t mp4ff_get_sample_rate(const mp4ff_t *f, const int32_t track)
309 {
310 return f->track[track]->sampleRate;
311 }
312
313 uint32_t mp4ff_get_channel_count(const mp4ff_t * f,const int32_t track)
314 {
315 return f->track[track]->channelCount;
316 }
317
318 uint32_t mp4ff_get_audio_type(const mp4ff_t * f,const int32_t track)
319 {
320 return f->track[track]->audioType;
321 }
322
323 int32_t mp4ff_get_sample_duration_use_offsets(const mp4ff_t *f, const int32_t track, const int32_t sample)
324 {
325 int32_t d,o;
326 d = mp4ff_get_sample_duration(f,track,sample);
327 if (d!=-1)
328 {
329 o = mp4ff_get_sample_offset(f,track,sample);
330 if (o>d) d = 0;
331 else d -= o;
332 }
333 return d;
334 }
335
336 int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample)
337 {
338 int32_t i, co = 0;
339
340 for (i = 0; i < f->track[track]->stts_entry_count; i++)
341 {
342 int32_t delta = f->track[track]->stts_sample_count[i];
343 if (sample < co + delta)
344 return f->track[track]->stts_sample_delta[i];
345 co += delta;
346 }
347 return (int32_t)(-1);
348 }
349
350 int64_t mp4ff_get_sample_position(const mp4ff_t *f, const int32_t track, const int32_t sample)
351 {
352 int32_t i, co = 0;
353 int64_t acc = 0;
354
355 for (i = 0; i < f->track[track]->stts_entry_count; i++)
356 {
357 int32_t delta = f->track[track]->stts_sample_count[i];
358 if (sample < co + delta)
359 {
360 acc += f->track[track]->stts_sample_delta[i] * (sample - co);
361 return acc;
362 }
363 else
364 {
365 acc += f->track[track]->stts_sample_delta[i] * delta;
366 }
367 co += delta;
368 }
369 return (int64_t)(-1);
370 }
371
372 int32_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample)
373 {
374 int32_t i, co = 0;
375
376 for (i = 0; i < f->track[track]->ctts_entry_count; i++)
377 {
378 int32_t delta = f->track[track]->ctts_sample_count[i];
379 if (sample < co + delta)
380 return f->track[track]->ctts_sample_offset[i];
381 co += delta;
382 }
383 return 0;
384 }
385
386 int32_t mp4ff_find_sample(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip)
387 {
388 int32_t i, co = 0;
389 int64_t offset_total = 0;
390 mp4ff_track_t * p_track = f->track[track];
391
392 for (i = 0; i < p_track->stts_entry_count; i++)
393 {
394 int32_t sample_count = p_track->stts_sample_count[i];
395 int32_t sample_delta = p_track->stts_sample_delta[i];
396 int64_t offset_delta = (int64_t)sample_delta * (int64_t)sample_count;
397 if (offset < offset_total + offset_delta)
398 {
399 int64_t offset_fromstts = offset - offset_total;
400 if (toskip) *toskip = (int32_t)(offset_fromstts % sample_delta);
401 return co + (int32_t)(offset_fromstts / sample_delta);
402 }
403 else
404 {
405 offset_total += offset_delta;
406 }
407 co += sample_count;
408 }
409 return (int32_t)(-1);
410 }
411
412 int32_t mp4ff_find_sample_use_offsets(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip)
413 {
414 return mp4ff_find_sample(f,track,offset + mp4ff_get_sample_offset(f,track,0),toskip);
415 }
416
417 int32_t mp4ff_read_sample(mp4ff_t *f, const int32_t track, const int32_t sample,
418 uint8_t **audio_buffer, uint32_t *bytes)
419 {
420 int32_t result = 0;
421
422 *bytes = mp4ff_audio_frame_size(f, track, sample);
423
424 if (*bytes==0) return 0;
425
426 *audio_buffer = (uint8_t*)malloc(*bytes);
427
428 mp4ff_set_sample_position(f, track, sample);
429
430 result = mp4ff_read_data(f, *audio_buffer, *bytes);
431
432 if (!result)
433 {
434 free(*audio_buffer);
435 *audio_buffer = 0;
436 return 0;
437 }
438
439 #ifdef ITUNES_DRM
440 if (f->track[track]->p_drms != NULL)
441 {
442 drms_decrypt(f->track[track]->p_drms, (uint32_t*)*audio_buffer, *bytes);
443 }
444 #endif
445
446 return *bytes;
447 }
448
449
450 int32_t mp4ff_read_sample_v2(mp4ff_t *f, const int track, const int sample,unsigned char *buffer)
451 {
452 int32_t result = 0;
453 int32_t size = mp4ff_audio_frame_size(f,track,sample);
454 if (size<=0) return 0;
455 mp4ff_set_sample_position(f, track, sample);
456 result = mp4ff_read_data(f,buffer,size);
457
458 #ifdef ITUNES_DRM
459 if (f->track[track]->p_drms != NULL)
460 {
461 drms_decrypt(f->track[track]->p_drms, (uint32_t*)buffer, size);
462 }
463 #endif
464
465 return result;
466 }
467
468 int32_t mp4ff_read_sample_getsize(mp4ff_t *f, const int track, const int sample)
469 {
470 int32_t temp = mp4ff_audio_frame_size(f, track, sample);
471 if (temp<0) temp = 0;
472 return temp;
473 }
0 /*
1 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
2 ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
3 **
4 ** This program is free software; you can redistribute it and/or modify
5 ** It under the terms of the GNU General Public License as published by
6 ** the Free Software Foundation; either version 2 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 General Public License for more details.
13 **
14 ** You should have received a copy of the GNU 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 ** Any non-GPL usage of this software or parts of this software is strictly
19 ** forbidden.
20 **
21 ** Commercial non-GPL licensing of this software is possible.
22 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
23 **
24 ** $Id: mp4ff.h,v 1.22 2005/02/01 13:15:55 menno Exp $
25 **/
26
27 #ifndef MP4FF_H
28 #define MP4FF_H
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif /* __cplusplus */
33
34 #include "mp4ff_int_types.h"
35
36 /* file callback structure */
37 typedef struct
38 {
39 uint32_t (*read)(void *user_data, void *buffer, uint32_t length);
40 uint32_t (*write)(void *udata, void *buffer, uint32_t length);
41 uint32_t (*seek)(void *user_data, uint64_t position);
42 uint32_t (*truncate)(void *user_data);
43 void *user_data;
44 } mp4ff_callback_t;
45
46 /* mp4 main file structure */
47 typedef void* mp4ff_t;
48
49
50 /* API */
51
52 mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f);
53 mp4ff_t *mp4ff_open_read_metaonly(mp4ff_callback_t *f);
54 void mp4ff_close(mp4ff_t *f);
55 int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample);
56 int32_t mp4ff_get_sample_duration_use_offsets(const mp4ff_t *f, const int32_t track, const int32_t sample);
57 int64_t mp4ff_get_sample_position(const mp4ff_t *f, const int32_t track, const int32_t sample);
58 int32_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
59 int32_t mp4ff_find_sample(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip);
60 int32_t mp4ff_find_sample_use_offsets(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip);
61
62 int32_t mp4ff_read_sample(mp4ff_t *f, const int track, const int sample,
63 unsigned char **audio_buffer, unsigned int *bytes);
64
65 int32_t mp4ff_read_sample_v2(mp4ff_t *f, const int track, const int sample,unsigned char *buffer);//returns 0 on error, number of bytes read on success, use mp4ff_read_sample_getsize() to check buffer size needed
66 int32_t mp4ff_read_sample_getsize(mp4ff_t *f, const int track, const int sample);//returns 0 on error, buffer size needed for mp4ff_read_sample_v2() on success
67
68
69
70 int32_t mp4ff_get_decoder_config(const mp4ff_t *f, const int track,
71 unsigned char** ppBuf, unsigned int* pBufSize);
72 int32_t mp4ff_get_track_type(const mp4ff_t *f, const int track);
73 int32_t mp4ff_total_tracks(const mp4ff_t *f);
74 int32_t mp4ff_num_samples(const mp4ff_t *f, const int track);
75 int32_t mp4ff_time_scale(const mp4ff_t *f, const int track);
76
77 uint32_t mp4ff_get_avg_bitrate(const mp4ff_t *f, const int32_t track);
78 uint32_t mp4ff_get_max_bitrate(const mp4ff_t *f, const int32_t track);
79 int64_t mp4ff_get_track_duration(const mp4ff_t *f, const int32_t track); //returns (-1) if unknown
80 int64_t mp4ff_get_track_duration_use_offsets(const mp4ff_t *f, const int32_t track); //returns (-1) if unknown
81 uint32_t mp4ff_get_sample_rate(const mp4ff_t *f, const int32_t track);
82 uint32_t mp4ff_get_channel_count(const mp4ff_t * f,const int32_t track);
83 uint32_t mp4ff_get_audio_type(const mp4ff_t * f,const int32_t track);
84
85
86 /* metadata */
87 #ifdef USE_TAGGING
88 int mp4ff_meta_get_num_items(const mp4ff_t *f);
89 int mp4ff_meta_get_by_index(const mp4ff_t *f, unsigned int index,
90 char **item, char **value);
91 int mp4ff_meta_find_by_name(const mp4ff_t *f, const char *item, char **value);
92 int mp4ff_meta_get_title(const mp4ff_t *f, char **value);
93 int mp4ff_meta_get_artist(const mp4ff_t *f, char **value);
94 int mp4ff_meta_get_writer(const mp4ff_t *f, char **value);
95 int mp4ff_meta_get_album(const mp4ff_t *f, char **value);
96 int mp4ff_meta_get_date(const mp4ff_t *f, char **value);
97 int mp4ff_meta_get_tool(const mp4ff_t *f, char **value);
98 int mp4ff_meta_get_comment(const mp4ff_t *f, char **value);
99 int mp4ff_meta_get_genre(const mp4ff_t *f, char **value);
100 int mp4ff_meta_get_track(const mp4ff_t *f, char **value);
101 int mp4ff_meta_get_disc(const mp4ff_t *f, char **value);
102 int mp4ff_meta_get_totaltracks(const mp4ff_t *f, char **value);
103 int mp4ff_meta_get_totaldiscs(const mp4ff_t *f, char **value);
104 int mp4ff_meta_get_compilation(const mp4ff_t *f, char **value);
105 int mp4ff_meta_get_tempo(const mp4ff_t *f, char **value);
106 int32_t mp4ff_meta_get_coverart(const mp4ff_t *f, char **value);
107
108 /* metadata tag structure */
109 typedef struct
110 {
111 char *item;
112 char *value;
113 uint32_t value_length;
114 } mp4ff_tag_t;
115
116 /* metadata list structure */
117 typedef struct
118 {
119 mp4ff_tag_t *tags;
120 uint32_t count;
121 } mp4ff_metadata_t;
122
123 int32_t mp4ff_meta_update(mp4ff_callback_t *f,const mp4ff_metadata_t * data);
124
125 #endif
126
127
128 #ifdef __cplusplus
129 }
130 #endif /* __cplusplus */
131
132 #endif
133
0 #ifndef _MP4FF_INT_TYPES_H_
1 #define _MP4FF_INT_TYPES_H_
2
3 #if defined (_WIN32) && !defined(__MINGW32__)
4
5 typedef char int8_t;
6 typedef unsigned char uint8_t;
7 typedef short int16_t;
8 typedef unsigned short uint16_t;
9 typedef long int32_t;
10 typedef unsigned long uint32_t;
11
12 typedef __int64 int64_t;
13 typedef unsigned __int64 uint64_t;
14
15 #else
16
17 #include <stdint.h>
18
19 #endif
20
21
22 #endif
0 /*
1 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
2 ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
3 **
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU General Public License as published by
6 ** the Free Software Foundation; either version 2 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 General Public License for more details.
13 **
14 ** You should have received a copy of the GNU 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 ** Any non-GPL usage of this software or parts of this software is strictly
19 ** forbidden.
20 **
21 ** Commercial non-GPL licensing of this software is possible.
22 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
23 **
24 ** $Id: mp4ffint.h,v 1.19 2005/02/01 13:15:55 menno Exp $
25 **/
26
27 #ifndef MP4FF_INTERNAL_H
28 #define MP4FF_INTERNAL_H
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif /* __cplusplus */
33
34 #include <stdlib.h>
35 #include "mp4ff_int_types.h"
36
37 #ifdef ITUNES_DRM
38 static __inline uint32_t GetDWLE( void const * _p )
39 {
40 uint8_t * p = (uint8_t *)_p;
41 return ( ((uint32_t)p[3] << 24) | ((uint32_t)p[2] << 16)
42 | ((uint32_t)p[1] << 8) | p[0] );
43 }
44 static __inline uint32_t U32_AT( void const * _p )
45 {
46 uint8_t * p = (uint8_t *)_p;
47 return ( ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16)
48 | ((uint32_t)p[2] << 8) | p[3] );
49 }
50 static __inline uint64_t U64_AT( void const * _p )
51 {
52 uint8_t * p = (uint8_t *)_p;
53 return ( ((uint64_t)p[0] << 56) | ((uint64_t)p[1] << 48)
54 | ((uint64_t)p[2] << 40) | ((uint64_t)p[3] << 32)
55 | ((uint64_t)p[4] << 24) | ((uint64_t)p[5] << 16)
56 | ((uint64_t)p[6] << 8) | p[7] );
57 }
58
59 #ifdef WORDS_BIGENDIAN
60 # define VLC_FOURCC( a, b, c, d ) \
61 ( ((uint32_t)d) | ( ((uint32_t)c) << 8 ) \
62 | ( ((uint32_t)b) << 16 ) | ( ((uint32_t)a) << 24 ) )
63 # define VLC_TWOCC( a, b ) \
64 ( (uint16_t)(b) | ( (uint16_t)(a) << 8 ) )
65
66 #else
67 # define VLC_FOURCC( a, b, c, d ) \
68 ( ((uint32_t)a) | ( ((uint32_t)b) << 8 ) \
69 | ( ((uint32_t)c) << 16 ) | ( ((uint32_t)d) << 24 ) )
70 # define VLC_TWOCC( a, b ) \
71 ( (uint16_t)(a) | ( (uint16_t)(b) << 8 ) )
72 #endif
73
74 #define FOURCC_user VLC_FOURCC( 'u', 's', 'e', 'r' )
75 #define FOURCC_key VLC_FOURCC( 'k', 'e', 'y', ' ' )
76 #define FOURCC_iviv VLC_FOURCC( 'i', 'v', 'i', 'v' )
77 #define FOURCC_name VLC_FOURCC( 'n', 'a', 'm', 'e' )
78 #define FOURCC_priv VLC_FOURCC( 'p', 'r', 'i', 'v' )
79
80 #endif
81 #define MAX_TRACKS 1024
82 #define TRACK_UNKNOWN 0
83 #define TRACK_AUDIO 1
84 #define TRACK_VIDEO 2
85 #define TRACK_SYSTEM 3
86
87
88 #define SUBATOMIC 128
89
90 /* atoms without subatoms */
91 #define ATOM_FTYP 129
92 #define ATOM_MDAT 130
93 #define ATOM_MVHD 131
94 #define ATOM_TKHD 132
95 #define ATOM_TREF 133
96 #define ATOM_MDHD 134
97 #define ATOM_VMHD 135
98 #define ATOM_SMHD 136
99 #define ATOM_HMHD 137
100 #define ATOM_STSD 138
101 #define ATOM_STTS 139
102 #define ATOM_STSZ 140
103 #define ATOM_STZ2 141
104 #define ATOM_STCO 142
105 #define ATOM_STSC 143
106 #define ATOM_MP4A 144
107 #define ATOM_MP4V 145
108 #define ATOM_MP4S 146
109 #define ATOM_ESDS 147
110 #define ATOM_META 148 /* iTunes Metadata box */
111 #define ATOM_NAME 149 /* iTunes Metadata name box */
112 #define ATOM_DATA 150 /* iTunes Metadata data box */
113 #define ATOM_CTTS 151
114 #define ATOM_FRMA 152
115 #define ATOM_IVIV 153
116 #define ATOM_PRIV 154
117 #define ATOM_USER 155
118 #define ATOM_KEY 156
119
120 #define ATOM_ALAC 192
121
122 #define ATOM_UNKNOWN 255
123 #define ATOM_FREE ATOM_UNKNOWN
124 #define ATOM_SKIP ATOM_UNKNOWN
125
126 /* atoms with subatoms */
127 #define ATOM_MOOV 1
128 #define ATOM_TRAK 2
129 #define ATOM_EDTS 3
130 #define ATOM_MDIA 4
131 #define ATOM_MINF 5
132 #define ATOM_STBL 6
133 #define ATOM_UDTA 7
134 #define ATOM_ILST 8 /* iTunes Metadata list */
135 #define ATOM_TITLE 9
136 #define ATOM_ARTIST 10
137 #define ATOM_WRITER 11
138 #define ATOM_ALBUM 12
139 #define ATOM_DATE 13
140 #define ATOM_TOOL 14
141 #define ATOM_COMMENT 15
142 #define ATOM_GENRE1 16
143 #define ATOM_TRACK 17
144 #define ATOM_DISC 18
145 #define ATOM_COMPILATION 19
146 #define ATOM_GENRE2 20
147 #define ATOM_TEMPO 21
148 #define ATOM_COVER 22
149 #define ATOM_DRMS 23
150 #define ATOM_SINF 24
151 #define ATOM_SCHI 25
152
153 #ifdef HAVE_CONFIG_H
154 #include "config.h"
155 #endif
156
157 #if !(defined(_WIN32) || defined(_WIN32_WCE))
158 #define stricmp strcasecmp
159 #else
160 #define stricmp _stricmp
161 #define strdup _strdup
162 #endif
163
164 /* file callback structure */
165 typedef struct
166 {
167 uint32_t (*read)(void *user_data, void *buffer, uint32_t length);
168 uint32_t (*write)(void *udata, void *buffer, uint32_t length);
169 uint32_t (*seek)(void *user_data, uint64_t position);
170 uint32_t (*truncate)(void *user_data);
171 void *user_data;
172 } mp4ff_callback_t;
173
174
175 /* metadata tag structure */
176 typedef struct
177 {
178 char *item;
179 char *value;
180 uint32_t value_length;
181 } mp4ff_tag_t;
182
183 /* metadata list structure */
184 typedef struct
185 {
186 mp4ff_tag_t *tags;
187 uint32_t count;
188 } mp4ff_metadata_t;
189
190
191 typedef struct
192 {
193 int32_t type;
194 int32_t channelCount;
195 int32_t sampleSize;
196 uint16_t sampleRate;
197 int32_t audioType;
198
199 /* stsd */
200 int32_t stsd_entry_count;
201
202 /* stsz */
203 int32_t stsz_sample_size;
204 int32_t stsz_sample_count;
205 int32_t *stsz_table;
206
207 /* stts */
208 int32_t stts_entry_count;
209 int32_t *stts_sample_count;
210 int32_t *stts_sample_delta;
211
212 /* stsc */
213 int32_t stsc_entry_count;
214 int32_t *stsc_first_chunk;
215 int32_t *stsc_samples_per_chunk;
216 int32_t *stsc_sample_desc_index;
217
218 /* stsc */
219 int32_t stco_entry_count;
220 int32_t *stco_chunk_offset;
221
222 /* ctts */
223 int32_t ctts_entry_count;
224 int32_t *ctts_sample_count;
225 int32_t *ctts_sample_offset;
226
227 /* esde */
228 uint8_t *decoderConfig;
229 int32_t decoderConfigLen;
230
231 uint32_t maxBitrate;
232 uint32_t avgBitrate;
233
234 uint32_t timeScale;
235 uint64_t duration;
236
237 #ifdef ITUNES_DRM
238 /* drms */
239 void *p_drms;
240 #endif
241
242 } mp4ff_track_t;
243
244 /* mp4 main file structure */
245 typedef struct
246 {
247 /* stream to read from */
248 mp4ff_callback_t *stream;
249 int64_t current_position;
250
251 int32_t moov_read;
252 uint64_t moov_offset;
253 uint64_t moov_size;
254 uint8_t last_atom;
255 uint64_t file_size;
256
257 /* mvhd */
258 int32_t time_scale;
259 int32_t duration;
260
261 /* incremental track index while reading the file */
262 int32_t total_tracks;
263
264 /* track data */
265 mp4ff_track_t *track[MAX_TRACKS];
266
267 /* metadata */
268 mp4ff_metadata_t tags;
269 } mp4ff_t;
270
271
272
273
274 /* mp4util.c */
275 int32_t mp4ff_read_data(mp4ff_t *f, uint8_t *data, uint32_t size);
276 int32_t mp4ff_write_data(mp4ff_t *f, uint8_t *data, uint32_t size);
277 uint64_t mp4ff_read_int64(mp4ff_t *f);
278 uint32_t mp4ff_read_int32(mp4ff_t *f);
279 uint32_t mp4ff_read_int24(mp4ff_t *f);
280 uint16_t mp4ff_read_int16(mp4ff_t *f);
281 uint8_t mp4ff_read_char(mp4ff_t *f);
282 int32_t mp4ff_write_int32(mp4ff_t *f,const uint32_t data);
283 uint32_t mp4ff_read_mp4_descr_length(mp4ff_t *f);
284 int64_t mp4ff_position(const mp4ff_t *f);
285 int32_t mp4ff_set_position(mp4ff_t *f, const int64_t position);
286 int32_t mp4ff_truncate(mp4ff_t * f);
287 char * mp4ff_read_string(mp4ff_t * f,uint32_t length);
288
289 /* mp4atom.c */
290 int32_t mp4ff_atom_get_size(const uint8_t *data);
291 int32_t mp4ff_atom_compare(const int8_t a1, const int8_t b1, const int8_t c1, const int8_t d1,
292 const int8_t a2, const int8_t b2, const int8_t c2, const int8_t d2);
293 uint8_t mp4ff_atom_name_to_type(const int8_t a, const int8_t b, const int8_t c, const int8_t d);
294 uint64_t mp4ff_atom_read_header(mp4ff_t *f, uint8_t *atom_type, uint8_t *header_size);
295 int32_t mp4ff_read_stsz(mp4ff_t *f);
296 int32_t mp4ff_read_esds(mp4ff_t *f);
297 int32_t mp4ff_read_mp4a(mp4ff_t *f);
298 int32_t mp4ff_read_alac(mp4ff_t *f);
299 int32_t mp4ff_read_stsd(mp4ff_t *f);
300 int32_t mp4ff_read_stsc(mp4ff_t *f);
301 int32_t mp4ff_read_stco(mp4ff_t *f);
302 int32_t mp4ff_read_stts(mp4ff_t *f);
303 #ifdef USE_TAGGING
304 int32_t mp4ff_read_meta(mp4ff_t *f, const uint64_t size);
305 #endif
306 int32_t mp4ff_atom_read(mp4ff_t *f, const int32_t size, const uint8_t atom_type);
307
308 /* mp4sample.c */
309 int32_t mp4ff_chunk_of_sample(const mp4ff_t *f, const int32_t track, const int32_t sample,
310 int32_t *chunk_sample, int32_t *chunk);
311 int32_t mp4ff_chunk_to_offset(const mp4ff_t *f, const int32_t track, const int32_t chunk);
312 int32_t mp4ff_sample_range_size(const mp4ff_t *f, const int32_t track,
313 const int32_t chunk_sample, const int32_t sample);
314 int32_t mp4ff_sample_to_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
315 int32_t mp4ff_audio_frame_size(const mp4ff_t *f, const int32_t track, const int32_t sample);
316 int32_t mp4ff_set_sample_position(mp4ff_t *f, const int32_t track, const int32_t sample);
317
318 #ifdef USE_TAGGING
319 /* mp4meta.c */
320 int32_t mp4ff_tag_add_field_len(mp4ff_metadata_t *tags, const char *item, const char *value, uint32_t valuelen);
321 int32_t mp4ff_tag_add_field(mp4ff_metadata_t *tags, const char *item, const char *value);
322 int32_t mp4ff_tag_set_field(mp4ff_metadata_t *tags, const char *item, const char *value);
323 int32_t mp4ff_set_metadata_name(mp4ff_t *f, const uint8_t atom_type, char **name);
324 int32_t mp4ff_parse_tag(mp4ff_t *f, const uint8_t parent_atom_type, const int32_t size);
325 int32_t mp4ff_parse_metadata(mp4ff_t *f, const int32_t size);
326 int32_t mp4ff_tag_delete(mp4ff_metadata_t *tags);
327 int32_t mp4ff_meta_get_num_items(const mp4ff_t *f);
328 int32_t mp4ff_meta_get_by_index(const mp4ff_t *f, uint32_t index,
329 char **item, char **value);
330 int32_t mp4ff_meta_get_title(const mp4ff_t *f, char **value);
331 int32_t mp4ff_meta_get_artist(const mp4ff_t *f, char **value);
332 int32_t mp4ff_meta_get_writer(const mp4ff_t *f, char **value);
333 int32_t mp4ff_meta_get_album(const mp4ff_t *f, char **value);
334 int32_t mp4ff_meta_get_date(const mp4ff_t *f, char **value);
335 int32_t mp4ff_meta_get_tool(const mp4ff_t *f, char **value);
336 int32_t mp4ff_meta_get_comment(const mp4ff_t *f, char **value);
337 int32_t mp4ff_meta_get_genre(const mp4ff_t *f, char **value);
338 int32_t mp4ff_meta_get_track(const mp4ff_t *f, char **value);
339 int32_t mp4ff_meta_get_disc(const mp4ff_t *f, char **value);
340 int32_t mp4ff_meta_get_compilation(const mp4ff_t *f, char **value);
341 int32_t mp4ff_meta_get_tempo(const mp4ff_t *f, char **value);
342 int32_t mp4ff_meta_get_coverart(const mp4ff_t *f, char **value);
343 #endif
344
345 /* mp4ff.c */
346 mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f);
347 #ifdef USE_TAGGING
348 mp4ff_t *mp4ff_open_edit(mp4ff_callback_t *f);
349 #endif
350 void mp4ff_close(mp4ff_t *ff);
351 void mp4ff_track_add(mp4ff_t *f);
352 int32_t parse_sub_atoms(mp4ff_t *f, const uint64_t total_size,int meta_only);
353 int32_t parse_atoms(mp4ff_t *f,int meta_only);
354
355 int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample);
356 int64_t mp4ff_get_sample_position(const mp4ff_t *f, const int32_t track, const int32_t sample);
357 int32_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
358 int32_t mp4ff_find_sample(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip);
359
360 int32_t mp4ff_read_sample(mp4ff_t *f, const int32_t track, const int32_t sample,
361 uint8_t **audio_buffer, uint32_t *bytes);
362 int32_t mp4ff_get_decoder_config(const mp4ff_t *f, const int32_t track,
363 uint8_t** ppBuf, uint32_t* pBufSize);
364 int32_t mp4ff_total_tracks(const mp4ff_t *f);
365 int32_t mp4ff_time_scale(const mp4ff_t *f, const int32_t track);
366 int32_t mp4ff_num_samples(const mp4ff_t *f, const int32_t track);
367
368 uint32_t mp4ff_meta_genre_to_index(const char * genrestr);//returns 1-based index, 0 if not found
369 const char * mp4ff_meta_index_to_genre(uint32_t idx);//returns pointer to static string
370
371
372 #ifdef __cplusplus
373 }
374 #endif /* __cplusplus */
375
376 #endif
0 /*
1 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
2 ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
3 **
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU General Public License as published by
6 ** the Free Software Foundation; either version 2 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 General Public License for more details.
13 **
14 ** You should have received a copy of the GNU 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 ** Any non-GPL usage of this software or parts of this software is strictly
19 ** forbidden.
20 **
21 ** Commercial non-GPL licensing of this software is possible.
22 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
23 **
24 ** $Id: mp4meta.c,v 1.16 2005/02/01 13:15:55 menno Exp $
25 **/
26
27 #ifdef USE_TAGGING
28
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include "mp4ffint.h"
33
34 int32_t mp4ff_tag_add_field_len(mp4ff_metadata_t *tags, const char *item, const char *value, uint32_t valuelen)
35 {
36 void *backup = (void *)tags->tags;
37
38 if (!item || (item && !*item) || !value) return 0;
39
40 tags->tags = (mp4ff_tag_t*)realloc(tags->tags, (tags->count+1) * sizeof(mp4ff_tag_t));
41 if (!tags->tags)
42 {
43 if (backup) free(backup);
44 return 0;
45 } else {
46 tags->tags[tags->count].item = strdup(item);
47
48 /* ugly hack to make covers work */
49 tags->tags[tags->count].value = malloc(valuelen+1);
50 memcpy(tags->tags[tags->count].value, value, valuelen);
51 tags->tags[tags->count].value[valuelen] = '\0';
52
53 tags->tags[tags->count].value_length = valuelen;
54
55 if (!tags->tags[tags->count].item || !tags->tags[tags->count].value)
56 {
57 if (!tags->tags[tags->count].item) free (tags->tags[tags->count].item);
58 if (!tags->tags[tags->count].value) free (tags->tags[tags->count].value);
59 tags->tags[tags->count].item = NULL;
60 tags->tags[tags->count].value = NULL;
61 tags->tags[tags->count].value_length = 0;
62 return 0;
63 }
64
65 tags->count++;
66 return 1;
67 }
68 }
69
70 int32_t mp4ff_tag_add_field(mp4ff_metadata_t *tags, const char *item, const char *value)
71 {
72 return mp4ff_tag_add_field_len(tags, item, value, strlen(value));
73 }
74
75 int32_t mp4ff_tag_set_field(mp4ff_metadata_t *tags, const char *item, const char *value)
76 {
77 unsigned int i;
78
79 if (!item || (item && !*item) || !value) return 0;
80
81 for (i = 0; i < tags->count; i++)
82 {
83 if (!stricmp(tags->tags[i].item, item))
84 {
85 free(tags->tags[i].value);
86 tags->tags[i].value = strdup(value);
87 tags->tags[i].value_length = strlen(value);
88 return 1;
89 }
90 }
91
92 return mp4ff_tag_add_field(tags, item, value);
93 }
94
95 int32_t mp4ff_tag_delete(mp4ff_metadata_t *tags)
96 {
97 uint32_t i;
98
99 for (i = 0; i < tags->count; i++)
100 {
101 if (tags->tags[i].item) free(tags->tags[i].item);
102 if (tags->tags[i].value) free(tags->tags[i].value);
103 }
104
105 if (tags->tags) free(tags->tags);
106
107 tags->tags = NULL;
108 tags->count = 0;
109
110 return 0;
111 }
112
113 static const char* ID3v1GenreList[] = {
114 "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk",
115 "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies",
116 "Other", "Pop", "R&B", "Rap", "Reggae", "Rock",
117 "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks",
118 "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk",
119 "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House",
120 "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass",
121 "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock",
122 "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk",
123 "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta",
124 "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret",
125 "New Wave", "Psychedelic", "Rave", "Showtunes", "Trailer", "Lo-Fi",
126 "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical",
127 "Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing",
128 "Fast-Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde",
129 "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band",
130 "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson",
131 "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus",
132 "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba",
133 "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet",
134 "Punk Rock", "Drum Solo", "A capella", "Euro-House", "Dance Hall",
135 "Goa", "Drum & Bass", "Club House", "Hardcore", "Terror",
136 "Indie", "BritPop", "NegerPunk", "Polsk Punk", "Beat",
137 "Christian Gangsta", "Heavy Metal", "Black Metal", "Crossover", "Contemporary C",
138 "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop",
139 "SynthPop",
140 };
141
142 uint32_t mp4ff_meta_genre_to_index(const char * genrestr)
143 {
144 unsigned n;
145 for(n=0;n<sizeof(ID3v1GenreList)/sizeof(ID3v1GenreList[0]);n++)
146 {
147 if (!stricmp(genrestr,ID3v1GenreList[n])) return n+1;
148 }
149 return 0;
150 }
151
152 const char * mp4ff_meta_index_to_genre(uint32_t idx)
153 {
154 if (idx>0 && idx<=sizeof(ID3v1GenreList)/sizeof(ID3v1GenreList[0]))
155 {
156 return ID3v1GenreList[idx-1];
157 }
158 else
159 {
160 return 0;
161 }
162 }
163
164
165 int32_t TrackToString(char** str, const uint16_t track, const uint16_t totalTracks)
166 {
167 char temp[32];
168 sprintf(temp, "%.5u of %.5u", track, totalTracks);
169 *str = strdup(temp);
170 return 0;
171 }
172
173 int32_t mp4ff_set_metadata_name(mp4ff_t *f, const uint8_t atom_type, char **name)
174 {
175 static const char *tag_names[] = {
176 "unknown", "title", "artist", "writer", "album",
177 "date", "tool", "comment", "genre", "track",
178 "disc", "compilation", "genre", "tempo", "cover"
179 };
180 uint8_t tag_idx = 0;
181
182 switch (atom_type)
183 {
184 case ATOM_TITLE: tag_idx = 1; break;
185 case ATOM_ARTIST: tag_idx = 2; break;
186 case ATOM_WRITER: tag_idx = 3; break;
187 case ATOM_ALBUM: tag_idx = 4; break;
188 case ATOM_DATE: tag_idx = 5; break;
189 case ATOM_TOOL: tag_idx = 6; break;
190 case ATOM_COMMENT: tag_idx = 7; break;
191 case ATOM_GENRE1: tag_idx = 8; break;
192 case ATOM_TRACK: tag_idx = 9; break;
193 case ATOM_DISC: tag_idx = 10; break;
194 case ATOM_COMPILATION: tag_idx = 11; break;
195 case ATOM_GENRE2: tag_idx = 12; break;
196 case ATOM_TEMPO: tag_idx = 13; break;
197 case ATOM_COVER: tag_idx = 14; break;
198 default: tag_idx = 0; break;
199 }
200
201 *name = strdup(tag_names[tag_idx]);
202
203 return 0;
204 }
205
206 int32_t mp4ff_parse_tag(mp4ff_t *f, const uint8_t parent_atom_type, const int32_t size)
207 {
208 uint8_t atom_type;
209 uint8_t header_size = 0;
210 uint64_t subsize, sumsize = 0;
211 char * name = NULL;
212 char * data = NULL;
213 uint32_t datalen = 0;
214 uint32_t done = 0;
215
216
217 while (sumsize < size)
218 {
219 uint64_t destpos;
220 subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
221 destpos = mp4ff_position(f)+subsize-header_size;
222 if (!done)
223 {
224 if (atom_type == ATOM_DATA)
225 {
226 mp4ff_read_char(f); /* version */
227 mp4ff_read_int24(f); /* flags */
228 mp4ff_read_int32(f); /* reserved */
229
230 /* some need special attention */
231 if (parent_atom_type == ATOM_GENRE2 || parent_atom_type == ATOM_TEMPO)
232 {
233 if (subsize - header_size >= 8 + 2)
234 {
235 uint16_t val = mp4ff_read_int16(f);
236
237 if (parent_atom_type == ATOM_TEMPO)
238 {
239 char temp[16];
240 sprintf(temp, "%.5u BPM", val);
241 mp4ff_tag_add_field(&(f->tags), "tempo", temp);
242 }
243 else
244 {
245 const char * temp = mp4ff_meta_index_to_genre(val);
246 if (temp)
247 {
248 mp4ff_tag_add_field(&(f->tags), "genre", temp);
249 }
250 }
251 done = 1;
252 }
253 } else if (parent_atom_type == ATOM_TRACK || parent_atom_type == ATOM_DISC) {
254 if (!done && subsize - header_size >= 8 + 8)
255 {
256 uint16_t index,total;
257 char temp[32];
258 mp4ff_read_int16(f);
259 index = mp4ff_read_int16(f);
260 total = mp4ff_read_int16(f);
261 mp4ff_read_int16(f);
262
263 sprintf(temp,"%d",index);
264 mp4ff_tag_add_field(&(f->tags), parent_atom_type == ATOM_TRACK ? "track" : "disc", temp);
265 if (total>0)
266 {
267 sprintf(temp,"%d",total);
268 mp4ff_tag_add_field(&(f->tags), parent_atom_type == ATOM_TRACK ? "totaltracks" : "totaldiscs", temp);
269 }
270 done = 1;
271 }
272 } else
273 {
274 if (data) {free(data);data = NULL;}
275 data = mp4ff_read_string(f,(uint32_t)(subsize-(header_size+8)));
276 datalen = (uint32_t)(subsize-(header_size+8));
277 }
278 } else if (atom_type == ATOM_NAME) {
279 if (!done)
280 {
281 mp4ff_read_char(f); /* version */
282 mp4ff_read_int24(f); /* flags */
283 if (name) free(name);
284 name = mp4ff_read_string(f,(uint32_t)(subsize-(header_size+4)));
285 }
286 }
287 mp4ff_set_position(f, destpos);
288 sumsize += subsize;
289 }
290 }
291
292 if (data)
293 {
294 if (!done)
295 {
296 if (name == NULL) mp4ff_set_metadata_name(f, parent_atom_type, &name);
297 if (name) mp4ff_tag_add_field_len(&(f->tags), name, data, datalen);
298 }
299
300 free(data);
301 }
302 if (name) free(name);
303 return 1;
304 }
305
306 int32_t mp4ff_parse_metadata(mp4ff_t *f, const int32_t size)
307 {
308 uint64_t subsize, sumsize = 0;
309 uint8_t atom_type;
310 uint8_t header_size = 0;
311
312 while (sumsize < size)
313 {
314 subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
315 if (subsize == 0)
316 break;
317 mp4ff_parse_tag(f, atom_type, (uint32_t)(subsize-header_size));
318 sumsize += subsize;
319 }
320
321 return 0;
322 }
323
324 /* find a metadata item by name */
325 /* returns 0 if item found, 1 if no such item */
326 int32_t mp4ff_meta_find_by_name(const mp4ff_t *f, const char *item, char **value)
327 {
328 uint32_t i;
329
330 for (i = 0; i < f->tags.count; i++)
331 {
332 if (!stricmp(f->tags.tags[i].item, item))
333 {
334 uint32_t value_length = f->tags.tags[i].value_length;
335
336 if (value_length > 0) {
337 *value = malloc(value_length+1);
338 memcpy(*value, f->tags.tags[i].value, value_length+1);
339 return value_length;
340 }
341 }
342 }
343
344 *value = NULL;
345
346 /* not found */
347 return 0;
348 }
349
350 int32_t mp4ff_meta_get_num_items(const mp4ff_t *f)
351 {
352 return f->tags.count;
353 }
354
355 int32_t mp4ff_meta_get_by_index(const mp4ff_t *f, uint32_t index,
356 char **item, char **value)
357 {
358 if (index >= f->tags.count)
359 {
360 *item = NULL;
361 *value = NULL;
362 return 0;
363 } else {
364 *item = strdup(f->tags.tags[index].item);
365 *value = strdup(f->tags.tags[index].value);
366 return 1;
367 }
368 }
369
370 int32_t mp4ff_meta_get_title(const mp4ff_t *f, char **value)
371 {
372 return mp4ff_meta_find_by_name(f, "title", value);
373 }
374
375 int32_t mp4ff_meta_get_artist(const mp4ff_t *f, char **value)
376 {
377 return mp4ff_meta_find_by_name(f, "artist", value);
378 }
379
380 int32_t mp4ff_meta_get_writer(const mp4ff_t *f, char **value)
381 {
382 return mp4ff_meta_find_by_name(f, "writer", value);
383 }
384
385 int32_t mp4ff_meta_get_album(const mp4ff_t *f, char **value)
386 {
387 return mp4ff_meta_find_by_name(f, "album", value);
388 }
389
390 int32_t mp4ff_meta_get_date(const mp4ff_t *f, char **value)
391 {
392 return mp4ff_meta_find_by_name(f, "date", value);
393 }
394
395 int32_t mp4ff_meta_get_tool(const mp4ff_t *f, char **value)
396 {
397 return mp4ff_meta_find_by_name(f, "tool", value);
398 }
399
400 int32_t mp4ff_meta_get_comment(const mp4ff_t *f, char **value)
401 {
402 return mp4ff_meta_find_by_name(f, "comment", value);
403 }
404
405 int32_t mp4ff_meta_get_genre(const mp4ff_t *f, char **value)
406 {
407 return mp4ff_meta_find_by_name(f, "genre", value);
408 }
409
410 int32_t mp4ff_meta_get_track(const mp4ff_t *f, char **value)
411 {
412 return mp4ff_meta_find_by_name(f, "track", value);
413 }
414
415 int32_t mp4ff_meta_get_totaltracks(const mp4ff_t *f, char **value)
416 {
417 return mp4ff_meta_find_by_name(f, "totaltracks", value);
418 }
419
420 int32_t mp4ff_meta_get_disc(const mp4ff_t *f, char **value)
421 {
422 return mp4ff_meta_find_by_name(f, "disc", value);
423 }
424
425 int32_t mp4ff_meta_get_totaldiscs(const mp4ff_t *f, char **value)
426 {
427 return mp4ff_meta_find_by_name(f, "totaldiscs", value);
428 }
429
430 int32_t mp4ff_meta_get_compilation(const mp4ff_t *f, char **value)
431 {
432 return mp4ff_meta_find_by_name(f, "compilation", value);
433 }
434
435 int32_t mp4ff_meta_get_tempo(const mp4ff_t *f, char **value)
436 {
437 return mp4ff_meta_find_by_name(f, "tempo", value);
438 }
439
440 int32_t mp4ff_meta_get_coverart(const mp4ff_t *f, char **value)
441 {
442 return mp4ff_meta_find_by_name(f, "cover", value);
443 }
444
445 #endif
446
0 /*
1 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
2 ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
3 **
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU General Public License as published by
6 ** the Free Software Foundation; either version 2 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 General Public License for more details.
13 **
14 ** You should have received a copy of the GNU 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 ** Any non-GPL usage of this software or parts of this software is strictly
19 ** forbidden.
20 **
21 ** Commercial non-GPL licensing of this software is possible.
22 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
23 **
24 ** $Id: mp4sample.c,v 1.17 2005/02/01 13:15:55 menno Exp $
25 **/
26
27 #include <stdlib.h>
28 #include "mp4ffint.h"
29
30
31 int32_t mp4ff_chunk_of_sample(const mp4ff_t *f, const int32_t track, const int32_t sample,
32 int32_t *chunk_sample, int32_t *chunk)
33 {
34 int32_t total_entries = 0;
35 int32_t chunk2entry;
36 int32_t chunk1, chunk2, chunk1samples, range_samples, total = 0;
37
38 if (f->track[track] == NULL)
39 {
40 return -1;
41 }
42
43 total_entries = f->track[track]->stsc_entry_count;
44
45 chunk1 = 1;
46 chunk1samples = 0;
47 chunk2entry = 0;
48
49 do
50 {
51 chunk2 = f->track[track]->stsc_first_chunk[chunk2entry];
52 *chunk = chunk2 - chunk1;
53 range_samples = *chunk * chunk1samples;
54
55 if (sample < total + range_samples) break;
56
57 chunk1samples = f->track[track]->stsc_samples_per_chunk[chunk2entry];
58 chunk1 = chunk2;
59
60 if(chunk2entry < total_entries)
61 {
62 chunk2entry++;
63 total += range_samples;
64 }
65 } while (chunk2entry < total_entries);
66
67 if (chunk1samples)
68 *chunk = (sample - total) / chunk1samples + chunk1;
69 else
70 *chunk = 1;
71
72 *chunk_sample = total + (*chunk - chunk1) * chunk1samples;
73
74 return 0;
75 }
76
77 int32_t mp4ff_chunk_to_offset(const mp4ff_t *f, const int32_t track, const int32_t chunk)
78 {
79 const mp4ff_track_t * p_track = f->track[track];
80
81 if (p_track->stco_entry_count && (chunk > p_track->stco_entry_count))
82 {
83 return p_track->stco_chunk_offset[p_track->stco_entry_count - 1];
84 } else if (p_track->stco_entry_count) {
85 return p_track->stco_chunk_offset[chunk - 1];
86 } else {
87 return 8;
88 }
89
90 return 0;
91 }
92
93 int32_t mp4ff_sample_range_size(const mp4ff_t *f, const int32_t track,
94 const int32_t chunk_sample, const int32_t sample)
95 {
96 int32_t i, total;
97 const mp4ff_track_t * p_track = f->track[track];
98
99 if (p_track->stsz_sample_size)
100 {
101 return (sample - chunk_sample) * p_track->stsz_sample_size;
102 }
103 else
104 {
105 if (sample>=p_track->stsz_sample_count) return 0;//error
106
107 for(i = chunk_sample, total = 0; i < sample; i++)
108 {
109 total += p_track->stsz_table[i];
110 }
111 }
112
113 return total;
114 }
115
116 int32_t mp4ff_sample_to_offset(const mp4ff_t *f, const int32_t track, const int32_t sample)
117 {
118 int32_t chunk, chunk_sample, chunk_offset1, chunk_offset2;
119
120 mp4ff_chunk_of_sample(f, track, sample, &chunk_sample, &chunk);
121
122 chunk_offset1 = mp4ff_chunk_to_offset(f, track, chunk);
123 chunk_offset2 = chunk_offset1 + mp4ff_sample_range_size(f, track, chunk_sample, sample);
124
125 return chunk_offset2;
126 }
127
128 int32_t mp4ff_audio_frame_size(const mp4ff_t *f, const int32_t track, const int32_t sample)
129 {
130 int32_t bytes;
131 const mp4ff_track_t * p_track = f->track[track];
132
133 if (p_track->stsz_sample_size)
134 {
135 bytes = p_track->stsz_sample_size;
136 } else {
137 bytes = p_track->stsz_table[sample];
138 }
139
140 return bytes;
141 }
142
143 int32_t mp4ff_set_sample_position(mp4ff_t *f, const int32_t track, const int32_t sample)
144 {
145 int32_t offset;
146
147 offset = mp4ff_sample_to_offset(f, track, sample);
148 mp4ff_set_position(f, offset);
149
150 return 0;
151 }
0 #include <stdlib.h>
1 #include <string.h>
2 #include "mp4ffint.h"
3
4 #ifdef USE_TAGGING
5
6 uint32_t fix_byte_order_32(uint32_t src)
7 {
8 uint32_t result;
9 uint32_t a, b, c, d;
10 int8_t data[4];
11
12 memcpy(data,&src,sizeof(src));
13 a = (uint8_t)data[0];
14 b = (uint8_t)data[1];
15 c = (uint8_t)data[2];
16 d = (uint8_t)data[3];
17
18 result = (a<<24) | (b<<16) | (c<<8) | d;
19 return (uint32_t)result;
20 }
21
22 uint16_t fix_byte_order_16(uint16_t src)
23 {
24 uint16_t result;
25 uint16_t a, b;
26 int8_t data[2];
27
28 memcpy(data,&src,sizeof(src));
29 a = (uint8_t)data[0];
30 b = (uint8_t)data[1];
31
32 result = (a<<8) | b;
33 return (uint16_t)result;
34 }
35
36
37 typedef struct
38 {
39 void * data;
40 unsigned written;
41 unsigned allocated;
42 unsigned error;
43 } membuffer;
44
45 unsigned membuffer_write(membuffer * buf,const void * ptr,unsigned bytes)
46 {
47 unsigned dest_size = buf->written + bytes;
48
49 if (buf->error) return 0;
50 if (dest_size > buf->allocated)
51 {
52 do
53 {
54 buf->allocated <<= 1;
55 } while(dest_size > buf->allocated);
56
57 {
58 void * newptr = realloc(buf->data,buf->allocated);
59 if (newptr==0)
60 {
61 free(buf->data);
62 buf->data = 0;
63 buf->error = 1;
64 return 0;
65 }
66 buf->data = newptr;
67 }
68 }
69
70 if (ptr) memcpy((char*)buf->data + buf->written,ptr,bytes);
71 buf->written += bytes;
72 return bytes;
73 }
74
75 #define membuffer_write_data membuffer_write
76
77 unsigned membuffer_write_int32(membuffer * buf,uint32_t data)
78 {
79 uint8_t temp[4] = {(uint8_t)(data>>24),(uint8_t)(data>>16),(uint8_t)(data>>8),(uint8_t)data};
80 return membuffer_write_data(buf,temp,4);
81 }
82
83 unsigned membuffer_write_int24(membuffer * buf,uint32_t data)
84 {
85 uint8_t temp[3] = {(uint8_t)(data>>16),(uint8_t)(data>>8),(uint8_t)data};
86 return membuffer_write_data(buf,temp,3);
87 }
88
89 unsigned membuffer_write_int16(membuffer * buf,uint16_t data)
90 {
91 uint8_t temp[2] = {(uint8_t)(data>>8),(uint8_t)data};
92 return membuffer_write_data(buf,temp,2);
93 }
94
95 unsigned membuffer_write_atom_name(membuffer * buf,const char * data)
96 {
97 return membuffer_write_data(buf,data,4)==4 ? 1 : 0;
98 }
99
100 void membuffer_write_atom(membuffer * buf,const char * name,unsigned size,const void * data)
101 {
102 membuffer_write_int32(buf,size + 8);
103 membuffer_write_atom_name(buf,name);
104 membuffer_write_data(buf,data,size);
105 }
106
107 unsigned membuffer_write_string(membuffer * buf,const char * data)
108 {
109 return membuffer_write_data(buf,data,strlen(data));
110 }
111
112 unsigned membuffer_write_int8(membuffer * buf,uint8_t data)
113 {
114 return membuffer_write_data(buf,&data,1);
115 }
116
117 void * membuffer_get_ptr(const membuffer * buf)
118 {
119 return buf->data;
120 }
121
122 unsigned membuffer_get_size(const membuffer * buf)
123 {
124 return buf->written;
125 }
126
127 unsigned membuffer_error(const membuffer * buf)
128 {
129 return buf->error;
130 }
131
132 void membuffer_set_error(membuffer * buf) {buf->error = 1;}
133
134 unsigned membuffer_transfer_from_file(membuffer * buf,mp4ff_t * src,unsigned bytes)
135 {
136 unsigned oldsize;
137 void * bufptr;
138
139 oldsize = membuffer_get_size(buf);
140 if (membuffer_write_data(buf,0,bytes) != bytes) return 0;
141
142 bufptr = membuffer_get_ptr(buf);
143 if (bufptr==0) return 0;
144
145 if ((unsigned)mp4ff_read_data(src,(uint8_t *)bufptr + oldsize,bytes)!=bytes)
146 {
147 membuffer_set_error(buf);
148 return 0;
149 }
150
151 return bytes;
152 }
153
154
155 membuffer * membuffer_create()
156 {
157 const unsigned initial_size = 256;
158
159 membuffer * buf = (membuffer *) malloc(sizeof(membuffer));
160 buf->data = malloc(initial_size);
161 buf->written = 0;
162 buf->allocated = initial_size;
163 buf->error = buf->data == 0 ? 1 : 0;
164
165 return buf;
166 }
167
168 void membuffer_free(membuffer * buf)
169 {
170 if (buf->data) free(buf->data);
171 free(buf);
172 }
173
174 void * membuffer_detach(membuffer * buf)
175 {
176 void * ret;
177
178 if (buf->error) return 0;
179
180 ret = realloc(buf->data,buf->written);
181
182 if (ret == 0) free(buf->data);
183
184 buf->data = 0;
185 buf->error = 1;
186
187 return ret;
188 }
189
190 #if 0
191 /* metadata tag structure */
192 typedef struct
193 {
194 char *item;
195 char *value;
196 } mp4ff_tag_t;
197
198 /* metadata list structure */
199 typedef struct
200 {
201 mp4ff_tag_t *tags;
202 uint32_t count;
203 } mp4ff_metadata_t;
204 #endif
205
206 typedef struct
207 {
208 const char * atom;
209 const char * name;
210 } stdmeta_entry;
211
212 static stdmeta_entry stdmetas[] =
213 {
214 {"©nam","title"},
215 {"©ART","artist"},
216 {"©wrt","writer"},
217 {"©alb","album"},
218 {"©day","date"},
219 {"©too","tool"},
220 {"©cmt","comment"},
221 // {"©gen","genre"},
222 {"cpil","compilation"},
223 // {"trkn","track"},
224 // {"disk","disc"},
225 // {"gnre","genre"},
226 {"covr","cover"},
227 };
228
229
230 static const char* find_standard_meta(const char * name) //returns atom name if found, 0 if not
231 {
232 unsigned n;
233 for(n=0;n<sizeof(stdmetas)/sizeof(stdmetas[0]);n++)
234 {
235 if (!stricmp(name,stdmetas[n].name)) return stdmetas[n].atom;
236 }
237 return 0;
238 }
239
240 static void membuffer_write_track_tag(membuffer * buf,const char * name,uint32_t index,uint32_t total)
241 {
242 membuffer_write_int32(buf,8 /*atom header*/ + 8 /*data atom header*/ + 8 /*flags + reserved*/ + 8 /*actual data*/ );
243 membuffer_write_atom_name(buf,name);
244 membuffer_write_int32(buf,8 /*data atom header*/ + 8 /*flags + reserved*/ + 8 /*actual data*/ );
245 membuffer_write_atom_name(buf,"data");
246 membuffer_write_int32(buf,0);//flags
247 membuffer_write_int32(buf,0);//reserved
248 membuffer_write_int16(buf,0);
249 membuffer_write_int16(buf,(uint16_t)index);//track number
250 membuffer_write_int16(buf,(uint16_t)total);//total tracks
251 membuffer_write_int16(buf,0);
252 }
253
254 static void membuffer_write_int16_tag(membuffer * buf,const char * name,uint16_t value)
255 {
256 membuffer_write_int32(buf,8 /*atom header*/ + 8 /*data atom header*/ + 8 /*flags + reserved*/ + 2 /*actual data*/ );
257 membuffer_write_atom_name(buf,name);
258 membuffer_write_int32(buf,8 /*data atom header*/ + 8 /*flags + reserved*/ + 2 /*actual data*/ );
259 membuffer_write_atom_name(buf,"data");
260 membuffer_write_int32(buf,0);//flags
261 membuffer_write_int32(buf,0);//reserved
262 membuffer_write_int16(buf,value);//value
263 }
264
265 static void membuffer_write_std_tag(membuffer * buf,const char * name,const char * value)
266 {
267 membuffer_write_int32(buf,8 /*atom header*/ + 8 /*data atom header*/ + 8 /*flags + reserved*/ + strlen(value) );
268 membuffer_write_atom_name(buf,name);
269 membuffer_write_int32(buf,8 /*data atom header*/ + 8 /*flags + reserved*/ + strlen(value));
270 membuffer_write_atom_name(buf,"data");
271 membuffer_write_int32(buf,1);//flags
272 membuffer_write_int32(buf,0);//reserved
273 membuffer_write_data(buf,value,strlen(value));
274 }
275
276 static void membuffer_write_custom_tag(membuffer * buf,const char * name,const char * value)
277 {
278 membuffer_write_int32(buf,8 /*atom header*/ + 0x1C /*weirdo itunes atom*/ + 12 /*name atom header*/ + strlen(name) + 16 /*data atom header + flags*/ + strlen(value) );
279 membuffer_write_atom_name(buf,"----");
280 membuffer_write_int32(buf,0x1C);//weirdo itunes atom
281 membuffer_write_atom_name(buf,"mean");
282 membuffer_write_int32(buf,0);
283 membuffer_write_data(buf,"com.apple.iTunes",16);
284 membuffer_write_int32(buf,12 + strlen(name));
285 membuffer_write_atom_name(buf,"name");
286 membuffer_write_int32(buf,0);
287 membuffer_write_data(buf,name,strlen(name));
288 membuffer_write_int32(buf,8 /*data atom header*/ + 8 /*flags + reserved*/ + strlen(value));
289 membuffer_write_atom_name(buf,"data");
290 membuffer_write_int32(buf,1);//flags
291 membuffer_write_int32(buf,0);//reserved
292 membuffer_write_data(buf,value,strlen(value));
293
294 }
295
296 static uint32_t myatoi(const char * param)
297 {
298 return param ? atoi(param) : 0;
299 }
300
301 static uint32_t create_ilst(const mp4ff_metadata_t * data,void ** out_buffer,uint32_t * out_size)
302 {
303 membuffer * buf = membuffer_create();
304 unsigned metaptr;
305 char * mask = (char*)malloc(data->count);
306 memset(mask,0,data->count);
307
308 {
309 const char * tracknumber_ptr = 0, * totaltracks_ptr = 0;
310 const char * discnumber_ptr = 0, * totaldiscs_ptr = 0;
311 const char * genre_ptr = 0, * tempo_ptr = 0;
312 for(metaptr = 0; metaptr < data->count; metaptr++)
313 {
314 mp4ff_tag_t * tag = &data->tags[metaptr];
315 if (!stricmp(tag->item,"tracknumber") || !stricmp(tag->item,"track"))
316 {
317 if (tracknumber_ptr==0) tracknumber_ptr = tag->value;
318 mask[metaptr] = 1;
319 }
320 else if (!stricmp(tag->item,"totaltracks"))
321 {
322 if (totaltracks_ptr==0) totaltracks_ptr = tag->value;
323 mask[metaptr] = 1;
324 }
325 else if (!stricmp(tag->item,"discnumber") || !stricmp(tag->item,"disc"))
326 {
327 if (discnumber_ptr==0) discnumber_ptr = tag->value;
328 mask[metaptr] = 1;
329 }
330 else if (!stricmp(tag->item,"totaldiscs"))
331 {
332 if (totaldiscs_ptr==0) totaldiscs_ptr = tag->value;
333 mask[metaptr] = 1;
334 }
335 else if (!stricmp(tag->item,"genre"))
336 {
337 if (genre_ptr==0) genre_ptr = tag->value;
338 mask[metaptr] = 1;
339 }
340 else if (!stricmp(tag->item,"tempo"))
341 {
342 if (tempo_ptr==0) tempo_ptr = tag->value;
343 mask[metaptr] = 1;
344 }
345
346 }
347
348 if (tracknumber_ptr) membuffer_write_track_tag(buf,"trkn",myatoi(tracknumber_ptr),myatoi(totaltracks_ptr));
349 if (discnumber_ptr) membuffer_write_track_tag(buf,"disk",myatoi(discnumber_ptr),myatoi(totaldiscs_ptr));
350 if (tempo_ptr) membuffer_write_int16_tag(buf,"tmpo",(uint16_t)myatoi(tempo_ptr));
351
352 if (genre_ptr)
353 {
354 uint32_t index = mp4ff_meta_genre_to_index(genre_ptr);
355 if (index==0)
356 membuffer_write_std_tag(buf,"©gen",genre_ptr);
357 else
358 membuffer_write_int16_tag(buf,"gnre",(uint16_t)index);
359 }
360 }
361
362 for(metaptr = 0; metaptr < data->count; metaptr++)
363 {
364 if (!mask[metaptr])
365 {
366 mp4ff_tag_t * tag = &data->tags[metaptr];
367 const char * std_meta_atom = find_standard_meta(tag->item);
368 if (std_meta_atom)
369 {
370 membuffer_write_std_tag(buf,std_meta_atom,tag->value);
371 }
372 else
373 {
374 membuffer_write_custom_tag(buf,tag->item,tag->value);
375 }
376 }
377 }
378
379 free(mask);
380
381 if (membuffer_error(buf))
382 {
383 membuffer_free(buf);
384 return 0;
385 }
386
387 *out_size = membuffer_get_size(buf);
388 *out_buffer = membuffer_detach(buf);
389 membuffer_free(buf);
390
391 return 1;
392 }
393
394 static uint32_t find_atom(mp4ff_t * f,uint64_t base,uint32_t size,const char * name)
395 {
396 uint32_t remaining = size;
397 uint64_t atom_offset = base;
398 for(;;)
399 {
400 uint8_t atom_name[4];
401 uint32_t atom_size;
402
403 mp4ff_set_position(f,atom_offset);
404
405 if (remaining < 8) break;
406 atom_size = mp4ff_read_int32(f);
407 if (atom_size > remaining || atom_size < 8) break;
408 mp4ff_read_data(f,atom_name,4);
409
410 if (!memcmp(atom_name,name,4))
411 {
412 mp4ff_set_position(f,atom_offset);
413 return 1;
414 }
415
416 remaining -= atom_size;
417 atom_offset += atom_size;
418 }
419 return 0;
420 }
421
422 static uint32_t find_atom_v2(mp4ff_t * f,uint64_t base,uint32_t size,const char * name,uint32_t extraheaders,const char * name_inside)
423 {
424 uint64_t first_base = (uint64_t)(-1);
425 while(find_atom(f,base,size,name))//try to find atom <name> with atom <name_inside> in it
426 {
427 uint64_t mybase = mp4ff_position(f);
428 uint32_t mysize = mp4ff_read_int32(f);
429
430 if (first_base == (uint64_t)(-1)) first_base = mybase;
431
432 if (mysize < 8 + extraheaders) break;
433
434 if (find_atom(f,mybase+(8+extraheaders),mysize-(8+extraheaders),name_inside))
435 {
436 mp4ff_set_position(f,mybase);
437 return 2;
438 }
439 base += mysize;
440 if (size<=mysize) {size=0;break;}
441 size -= mysize;
442 }
443
444 if (first_base != (uint64_t)(-1))//wanted atom inside not found
445 {
446 mp4ff_set_position(f,first_base);
447 return 1;
448 }
449 else return 0;
450 }
451
452 static uint32_t create_meta(const mp4ff_metadata_t * data,void ** out_buffer,uint32_t * out_size)
453 {
454 membuffer * buf;
455 uint32_t ilst_size;
456 void * ilst_buffer;
457
458 if (!create_ilst(data,&ilst_buffer,&ilst_size)) return 0;
459
460 buf = membuffer_create();
461
462 membuffer_write_int32(buf,0);
463 membuffer_write_atom(buf,"ilst",ilst_size,ilst_buffer);
464 free(ilst_buffer);
465
466 *out_size = membuffer_get_size(buf);
467 *out_buffer = membuffer_detach(buf);
468 membuffer_free(buf);
469 return 1;
470 }
471
472 static uint32_t create_udta(const mp4ff_metadata_t * data,void ** out_buffer,uint32_t * out_size)
473 {
474 membuffer * buf;
475 uint32_t meta_size;
476 void * meta_buffer;
477
478 if (!create_meta(data,&meta_buffer,&meta_size)) return 0;
479
480 buf = membuffer_create();
481
482 membuffer_write_atom(buf,"meta",meta_size,meta_buffer);
483
484 free(meta_buffer);
485
486 *out_size = membuffer_get_size(buf);
487 *out_buffer = membuffer_detach(buf);
488 membuffer_free(buf);
489 return 1;
490 }
491
492 static uint32_t modify_moov(mp4ff_t * f,const mp4ff_metadata_t * data,void ** out_buffer,uint32_t * out_size)
493 {
494 uint64_t total_base = f->moov_offset + 8;
495 uint32_t total_size = (uint32_t)(f->moov_size - 8);
496
497 uint64_t udta_offset,meta_offset,ilst_offset;
498 uint32_t udta_size, meta_size, ilst_size;
499
500 uint32_t new_ilst_size;
501 void * new_ilst_buffer;
502
503 uint8_t * p_out;
504 int32_t size_delta;
505
506
507 if (!find_atom_v2(f,total_base,total_size,"udta",0,"meta"))
508 {
509 membuffer * buf;
510 void * new_udta_buffer;
511 uint32_t new_udta_size;
512 if (!create_udta(data,&new_udta_buffer,&new_udta_size)) return 0;
513
514 buf = membuffer_create();
515 mp4ff_set_position(f,total_base);
516 membuffer_transfer_from_file(buf,f,total_size);
517
518 membuffer_write_atom(buf,"udta",new_udta_size,new_udta_buffer);
519
520 free(new_udta_buffer);
521
522 *out_size = membuffer_get_size(buf);
523 *out_buffer = membuffer_detach(buf);
524 membuffer_free(buf);
525 return 1;
526 }
527 else
528 {
529 udta_offset = mp4ff_position(f);
530 udta_size = mp4ff_read_int32(f);
531 if (!find_atom_v2(f,udta_offset+8,udta_size-8,"meta",4,"ilst"))
532 {
533 membuffer * buf;
534 void * new_meta_buffer;
535 uint32_t new_meta_size;
536 if (!create_meta(data,&new_meta_buffer,&new_meta_size)) return 0;
537
538 buf = membuffer_create();
539 mp4ff_set_position(f,total_base);
540 membuffer_transfer_from_file(buf,f,(uint32_t)(udta_offset - total_base));
541
542 membuffer_write_int32(buf,udta_size + 8 + new_meta_size);
543 membuffer_write_atom_name(buf,"udta");
544 membuffer_transfer_from_file(buf,f,udta_size);
545
546 membuffer_write_atom(buf,"meta",new_meta_size,new_meta_buffer);
547 free(new_meta_buffer);
548
549 *out_size = membuffer_get_size(buf);
550 *out_buffer = membuffer_detach(buf);
551 membuffer_free(buf);
552 return 1;
553 }
554 meta_offset = mp4ff_position(f);
555 meta_size = mp4ff_read_int32(f);
556 if (!find_atom(f,meta_offset+12,meta_size-12,"ilst")) return 0;//shouldn't happen, find_atom_v2 above takes care of it
557 ilst_offset = mp4ff_position(f);
558 ilst_size = mp4ff_read_int32(f);
559
560 if (!create_ilst(data,&new_ilst_buffer,&new_ilst_size)) return 0;
561
562 size_delta = new_ilst_size - (ilst_size - 8);
563
564 *out_size = total_size + size_delta;
565 *out_buffer = malloc(*out_size);
566 if (*out_buffer == 0)
567 {
568 free(new_ilst_buffer);
569 return 0;
570 }
571
572 p_out = (uint8_t*)*out_buffer;
573
574 mp4ff_set_position(f,total_base);
575 mp4ff_read_data(f,p_out,(uint32_t)(udta_offset - total_base )); p_out += (uint32_t)(udta_offset - total_base );
576 *(uint32_t*)p_out = fix_byte_order_32(mp4ff_read_int32(f) + size_delta); p_out += 4;
577 mp4ff_read_data(f,p_out,4); p_out += 4;
578 mp4ff_read_data(f,p_out,(uint32_t)(meta_offset - udta_offset - 8)); p_out += (uint32_t)(meta_offset - udta_offset - 8);
579 *(uint32_t*)p_out = fix_byte_order_32(mp4ff_read_int32(f) + size_delta); p_out += 4;
580 mp4ff_read_data(f,p_out,4); p_out += 4;
581 mp4ff_read_data(f,p_out,(uint32_t)(ilst_offset - meta_offset - 8)); p_out += (uint32_t)(ilst_offset - meta_offset - 8);
582 *(uint32_t*)p_out = fix_byte_order_32(mp4ff_read_int32(f) + size_delta); p_out += 4;
583 mp4ff_read_data(f,p_out,4); p_out += 4;
584
585 memcpy(p_out,new_ilst_buffer,new_ilst_size);
586 p_out += new_ilst_size;
587
588 mp4ff_set_position(f,ilst_offset + ilst_size);
589 mp4ff_read_data(f,p_out,(uint32_t)(total_size - (ilst_offset - total_base) - ilst_size));
590
591 free(new_ilst_buffer);
592 }
593 return 1;
594
595 }
596
597 int32_t mp4ff_meta_update(mp4ff_callback_t *f,const mp4ff_metadata_t * data)
598 {
599 void * new_moov_data;
600 uint32_t new_moov_size;
601
602 mp4ff_t *ff = malloc(sizeof(mp4ff_t));
603
604 memset(ff, 0, sizeof(mp4ff_t));
605 ff->stream = f;
606 mp4ff_set_position(ff,0);
607
608 parse_atoms(ff,1);
609
610
611 if (!modify_moov(ff,data,&new_moov_data,&new_moov_size))
612 {
613 mp4ff_close(ff);
614 return 0;
615 }
616
617 /* copy moov atom to end of the file */
618 if (ff->last_atom != ATOM_MOOV)
619 {
620 uint8_t *free_data = (uint8_t *)"free";
621
622 /* rename old moov to free */
623 mp4ff_set_position(ff, ff->moov_offset + 4);
624 mp4ff_write_data(ff, free_data, 4);
625
626 mp4ff_set_position(ff, ff->file_size);
627 mp4ff_write_int32(ff,new_moov_size + 8);
628 mp4ff_write_data(ff,(uint8_t *)"moov",4);
629 mp4ff_write_data(ff, new_moov_data, new_moov_size);
630 }
631 else
632 {
633 mp4ff_set_position(ff, ff->moov_offset);
634 mp4ff_write_int32(ff,new_moov_size + 8);
635 mp4ff_write_data(ff,(uint8_t *)"moov",4);
636 mp4ff_write_data(ff, new_moov_data, new_moov_size);
637 }
638
639 mp4ff_truncate(ff);
640
641 mp4ff_close(ff);
642 return 1;
643 }
644 #endif
0 /*
1 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
2 ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
3 **
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU General Public License as published by
6 ** the Free Software Foundation; either version 2 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 General Public License for more details.
13 **
14 ** You should have received a copy of the GNU 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 ** Any non-GPL usage of this software or parts of this software is strictly
19 ** forbidden.
20 **
21 ** Commercial non-GPL licensing of this software is possible.
22 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
23 **
24 ** $Id: mp4util.c,v 1.17 2005/02/01 13:15:55 menno Exp $
25 **/
26
27 #include "mp4ffint.h"
28 #include <stdlib.h>
29
30 int32_t mp4ff_read_data(mp4ff_t *f, uint8_t *data, uint32_t size)
31 {
32 int32_t result;
33 uint32_t read = 0;
34
35 while (read < size) {
36 result = f->stream->read(f->stream->user_data, data+read, size-read);
37 if (result <= 0) {
38 break;
39 }
40 read += result;
41 }
42
43 f->current_position += read;
44
45 return read;
46 }
47
48 int32_t mp4ff_truncate(mp4ff_t * f)
49 {
50 return f->stream->truncate(f->stream->user_data);
51 }
52
53 int32_t mp4ff_write_data(mp4ff_t *f, uint8_t *data, uint32_t size)
54 {
55 int32_t result = 1;
56
57 result = f->stream->write(f->stream->user_data, data, size);
58
59 f->current_position += size;
60
61 return result;
62 }
63
64 int32_t mp4ff_write_int32(mp4ff_t *f,const uint32_t data)
65 {
66 uint32_t result;
67 uint32_t a, b, c, d;
68
69 a = data & 0xff;
70 b = (data>>8) & 0xff;
71 c = (data>>16) & 0xff;
72 d = (data>>24) & 0xff;
73
74 result = (a<<24) | (b<<16) | (c<<8) | d;
75
76 return mp4ff_write_data(f,(uint8_t*)&result,sizeof(result));
77 }
78
79 int32_t mp4ff_set_position(mp4ff_t *f, const int64_t position)
80 {
81 f->stream->seek(f->stream->user_data, position);
82 f->current_position = position;
83
84 return 0;
85 }
86
87 int64_t mp4ff_position(const mp4ff_t *f)
88 {
89 return f->current_position;
90 }
91
92 uint64_t mp4ff_read_int64(mp4ff_t *f)
93 {
94 uint8_t data[8];
95 uint64_t result = 0;
96 int i;
97
98 mp4ff_read_data(f, data, 8);
99
100 for (i = 0; i < 8; i++)
101 {
102 result |= ((uint64_t)data[i]) << ((7 - i) * 8);
103 }
104
105 return result;
106 }
107
108 uint32_t mp4ff_read_int32(mp4ff_t *f)
109 {
110 uint32_t result;
111 uint32_t a, b, c, d;
112 uint8_t data[4];
113
114 mp4ff_read_data(f, data, 4);
115 a = data[0];
116 b = data[1];
117 c = data[2];
118 d = data[3];
119
120 result = (a<<24) | (b<<16) | (c<<8) | d;
121 return (uint32_t)result;
122 }
123
124 uint32_t mp4ff_read_int24(mp4ff_t *f)
125 {
126 uint32_t result;
127 uint32_t a, b, c;
128 uint8_t data[4];
129
130 mp4ff_read_data(f, data, 3);
131 a = data[0];
132 b = data[1];
133 c = data[2];
134
135 result = (a<<16) | (b<<8) | c;
136 return (uint32_t)result;
137 }
138
139 uint16_t mp4ff_read_int16(mp4ff_t *f)
140 {
141 uint32_t result;
142 uint32_t a, b;
143 uint8_t data[2];
144
145 mp4ff_read_data(f, data, 2);
146 a = data[0];
147 b = data[1];
148
149 result = (a<<8) | b;
150 return (uint16_t)result;
151 }
152
153 char * mp4ff_read_string(mp4ff_t * f,uint32_t length)
154 {
155 char * str = malloc(length + 1);
156 if (str!=0)
157 {
158 if ((uint32_t)mp4ff_read_data(f,(uint8_t *)str,length)!=length)
159 {
160 free(str);
161 str = 0;
162 }
163 else
164 {
165 str[length] = 0;
166 }
167 }
168 return str;
169 }
170
171 uint8_t mp4ff_read_char(mp4ff_t *f)
172 {
173 uint8_t output;
174 mp4ff_read_data(f, &output, 1);
175 return output;
176 }
177
178 uint32_t mp4ff_read_mp4_descr_length(mp4ff_t *f)
179 {
180 uint8_t b;
181 uint8_t numBytes = 0;
182 uint32_t length = 0;
183
184 do
185 {
186 b = mp4ff_read_char(f);
187 numBytes++;
188 length = (length << 7) | (b & 0x7F);
189 } while ((b & 0x80) && numBytes < 4);
190
191 return length;
192 }