48a960a632dd735db56dcd0205f93427de38fffe
[platform/upstream/gst-plugins-good.git] / gst / quicktime / properties.c
1 /* Quicktime muxer plugin for GStreamer
2  * Copyright (C) 2008 Thiago Sousa Santos <thiagoss@embedded.ufcg.edu.br>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library 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 GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include "properties.h"
21
22 /* if needed, re-allocate buffer to ensure size bytes can be written into it
23  * at offset */
24 void
25 prop_copy_ensure_buffer (guint8 ** buffer, guint64 * bsize, guint64 * offset,
26     guint64 size)
27 {
28   if (buffer && *bsize - *offset < size) {
29     *bsize += size + 10 * 1024;
30     *buffer = g_realloc (*buffer, *bsize);
31   }
32 }
33
34 static guint64
35 copy_func (void *prop, guint size, guint8 ** buffer, guint64 * bsize,
36     guint64 * offset)
37 {
38   if (buffer) {
39     prop_copy_ensure_buffer (buffer, bsize, offset, size);
40     memcpy (*buffer + *offset, prop, size);
41   }
42   *offset += size;
43   return size;
44 }
45
46 #define INT_ARRAY_COPY_FUNC_FAST(name, datatype)                        \
47 guint64 prop_copy_ ## name ## _array (datatype *prop, guint size,       \
48     guint8 ** buffer, guint64 * bsize, guint64 * offset) {              \
49   return copy_func (prop, sizeof (datatype) * size, buffer, bsize, offset);\
50 }
51
52 #define INT_ARRAY_COPY_FUNC(name, datatype)                             \
53 guint64 prop_copy_ ## name ## _array (datatype *prop, guint size,       \
54     guint8 ** buffer, guint64 * bsize, guint64 * offset) {              \
55   guint i;                                                              \
56                                                                         \
57   for (i = 0; i < size; i++) {                                          \
58     prop_copy_ ## name (prop[i], buffer, bsize, offset);                \
59   }                                                                     \
60   return sizeof (datatype) * size;                                      \
61 }
62
63 /* INTEGERS */
64 guint64
65 prop_copy_uint8 (guint8 prop, guint8 ** buffer, guint64 * size,
66     guint64 * offset)
67 {
68   return copy_func (&prop, sizeof (guint8), buffer, size, offset);
69 }
70
71 guint64
72 prop_copy_uint16 (guint16 prop, guint8 ** buffer, guint64 * size,
73     guint64 * offset)
74 {
75   prop = GUINT16_TO_BE (prop);
76   return copy_func (&prop, sizeof (guint16), buffer, size, offset);
77 }
78
79 guint64
80 prop_copy_uint32 (guint32 prop, guint8 ** buffer, guint64 * size,
81     guint64 * offset)
82 {
83   prop = GUINT32_TO_BE (prop);
84   return copy_func (&prop, sizeof (guint32), buffer, size, offset);
85 }
86
87 guint64
88 prop_copy_uint64 (guint64 prop, guint8 ** buffer, guint64 * size,
89     guint64 * offset)
90 {
91   prop = GUINT64_TO_BE (prop);
92   return copy_func (&prop, sizeof (guint64), buffer, size, offset);
93 }
94
95 guint64
96 prop_copy_int32 (gint32 prop, guint8 ** buffer, guint64 * size,
97     guint64 * offset)
98 {
99   prop = GINT32_TO_BE (prop);
100   return copy_func (&prop, sizeof (guint32), buffer, size, offset);
101 }
102
103 /* uint8 can use direct copy in any case, and may be used for large quantity */
104 INT_ARRAY_COPY_FUNC_FAST (uint8, guint8);
105 /* not used in large quantity anyway */
106 INT_ARRAY_COPY_FUNC (uint16, guint16);
107 INT_ARRAY_COPY_FUNC (uint32, guint32);
108 INT_ARRAY_COPY_FUNC (uint64, guint64);
109
110 /* FOURCC */
111 guint64
112 prop_copy_fourcc (guint32 prop, guint8 ** buffer, guint64 * size,
113     guint64 * offset)
114 {
115   prop = GINT32_TO_LE (prop);
116   return copy_func (&prop, sizeof (guint32), buffer, size, offset);
117 }
118
119 INT_ARRAY_COPY_FUNC (fourcc, guint32);
120
121 /**
122  * Copies a string of bytes without placing its size at the beginning.
123  *
124  * @string: the string to be copied
125  * @str_size: size of the string
126  * @buffer: the array to copy the string to
127  * @offset: the position in the buffer array.
128  * This value is updated to the point right after the copied string.
129  *
130  * Returns: the number of bytes copied
131  */
132 guint64
133 prop_copy_fixed_size_string (guint8 * string, guint str_size, guint8 ** buffer,
134     guint64 * size, guint64 * offset)
135 {
136   return copy_func (string, str_size * sizeof (guint8), buffer, size, offset);
137 }
138
139 /**
140  * Copies a string and its size to an array. Example:
141  * string = 'abc\0'
142  * result in the array: [3][a][b][c]  (each [x] represents a position)
143  *
144  * @string: the string to be copied
145  * @str_size: size of the string
146  * @buffer: the array to copy the string to
147  * @offset: the position in the buffer array.
148  * This value is updated to the point right after the copied string.
149  *
150  * Returns: the number of bytes copied
151  */
152 guint64
153 prop_copy_size_string (guint8 * string, guint str_size, guint8 ** buffer,
154     guint64 * size, guint64 * offset)
155 {
156   guint64 original_offset = *offset;
157
158   prop_copy_uint8 (str_size, buffer, size, offset);
159   prop_copy_fixed_size_string (string, str_size, buffer, size, offset);
160   return *offset - original_offset;
161 }
162
163 /**
164  * Copies a string including its null terminating char to an array.
165  *
166  * @string: the string to be copied
167  * @buffer: the array to copy the string to
168  * @offset: the position in the buffer array.
169  * This value is updated to the point right after the copied string.
170  *
171  * Returns: the number of bytes copied
172  */
173 guint64
174 prop_copy_null_terminated_string (gchar * string, guint8 ** buffer,
175     guint64 * size, guint64 * offset)
176 {
177   guint64 original_offset = *offset;
178   guint len = strlen (string);
179
180   prop_copy_fixed_size_string ((guint8 *) string, len, buffer, size, offset);
181   prop_copy_uint8 ('\0', buffer, size, offset);
182   return *offset - original_offset;
183 }