Bugfix [#27157] keyframing a constrained bone does not work as before
[blender.git] / extern / libredcode / format.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "format.h"
5
6 struct red_reob {
7         unsigned int len;
8         unsigned int head;
9
10         unsigned int rdvo;
11         unsigned int rdvs;
12         unsigned int rdao;
13         unsigned int rdas;
14
15         unsigned int unknown1;
16         unsigned int unknown2;
17         unsigned int totlen;
18         
19         unsigned int avgv;
20         unsigned int avgs;
21
22         unsigned int unknown3;
23         unsigned int unknown4;
24         unsigned int unknown5;
25 };
26
27 struct redcode_handle {
28         FILE * fp;
29         struct red_reob * reob;
30         unsigned int * rdvo;
31         unsigned int * rdvs;
32         unsigned int * rdao;
33         unsigned int * rdas;
34         long cfra;
35         long length;
36 };
37
38 unsigned int read_be32(unsigned int val)
39 {
40         unsigned char * v = (unsigned char*) & val;
41  
42         return  (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | v[3];
43 }
44
45 static unsigned char* read_packet(FILE * fp, char * expect)
46 {
47         unsigned int len;
48         char head[5];
49         unsigned char * rv;
50
51         fread(&len, 4, 1, fp);
52         fread(&head, 4, 1, fp);
53
54         head[4] = 0;
55
56         len = read_be32(len);
57
58         if (strcmp(expect, head) != 0) {
59                 fprintf(stderr, "Read: %s, expect: %s\n", head, expect);
60                 return NULL;
61         }
62
63         rv = (unsigned char*) malloc(len + 8);
64
65         memcpy(rv, &len, 4);
66         memcpy(rv + 4, &head, 4);
67         
68         fread(rv + 8, len, 1, fp);
69
70         return rv;
71 }
72
73 static unsigned int * read_index_packet(FILE * fp, char * expect)
74 {
75         unsigned int * rv = (unsigned int*) read_packet(fp, expect);
76         int i;
77
78         if (!rv) {
79                 return NULL;
80         }
81
82         for (i = 2; i < rv[0]/4; i++) {
83                 rv[i] = read_be32(rv[i]);
84         }
85         return rv;
86 }
87
88 static struct red_reob * read_reob(FILE * fp)
89 {
90         fseek(fp, -0x38, SEEK_END);
91
92         return (struct red_reob *) read_index_packet(fp, "REOB");
93 }
94
95 static unsigned int * read_index(FILE * fp, unsigned int i, char * expect)
96 {
97         fseek(fp, i, SEEK_SET);
98         
99         return (unsigned int*) read_index_packet(fp, expect);
100 }
101
102 static unsigned char * read_data(FILE * fp, unsigned int i, char * expect)
103 {
104         fseek(fp, i, SEEK_SET);
105         
106         return read_packet(fp, expect);
107 }
108
109 struct redcode_handle * redcode_open(const char * fname)
110 {
111         struct redcode_handle * rv = NULL;
112         struct red_reob * reob = NULL;
113         int i;
114
115         FILE * fp = fopen(fname, "rb");
116
117         if (!fp) {
118                 return NULL;
119         }
120
121         reob = read_reob(fp);
122         if (!reob) {
123                 fclose(fp);
124                 return NULL;
125         }
126
127         rv = (struct redcode_handle*) calloc(1, sizeof(struct redcode_handle));
128
129         rv->fp = fp;
130         rv->reob = reob;
131         rv->rdvo = read_index(fp, reob->rdvo, "RDVO");
132         rv->rdvs = read_index(fp, reob->rdvs, "RDVS");
133         rv->rdao = read_index(fp, reob->rdao, "RDAO");
134         rv->rdas = read_index(fp, reob->rdas, "RDAS");
135
136         if (!rv->rdvo || !rv->rdvs || !rv->rdao || !rv->rdas) {
137                 redcode_close(rv);
138                 return NULL;
139         }
140
141         for (i = 0; i < (rv->rdvo[0] - 8)/4; i++) {
142                 if (rv->rdvo[i + 2]) {
143                         rv->length = i;
144                 }
145         }
146
147         return rv;
148 }
149
150 void redcode_close(struct redcode_handle * handle)
151 {
152         if (handle->reob) {
153                 free(handle->reob);
154         }
155         if (handle->rdvo) {
156                 free(handle->rdvo);
157         }
158         if (handle->rdvs) {
159                 free(handle->rdvs);
160         }
161         if (handle->rdao) {
162                 free(handle->rdao);
163         }
164         if (handle->rdas) {
165                 free(handle->rdas);
166         }
167         fclose(handle->fp);
168         free(handle);
169 }
170
171 long redcode_get_length(struct redcode_handle * handle)
172 {
173         return handle->length;
174 }
175
176 struct redcode_frame * redcode_read_video_frame(
177         struct redcode_handle * handle, long frame)
178 {
179         struct redcode_frame * rv;
180         unsigned char * data;
181
182         if (frame > handle->rdvo[0]/4 || handle->rdvo[frame + 2] == 0) {
183                 return NULL;
184         }
185         data = read_data(handle->fp, handle->rdvo[frame + 2], "REDV");
186         if (!data) {
187                 return NULL;
188         }
189
190         rv = (struct redcode_frame*) calloc(1, sizeof(struct redcode_frame));
191
192         rv->offset = 12+8;
193         rv->length = *(unsigned int*)data - rv->offset;
194         rv->data = data;
195
196         return rv;
197 }
198
199 struct redcode_frame * redcode_read_audio_frame(
200         struct redcode_handle * handle, long frame)
201 {
202         struct redcode_frame * rv;
203         unsigned char * data;
204
205         if (frame > handle->rdao[0]/4 || handle->rdao[frame + 2] == 0) {
206                 return NULL;
207         }
208         data = read_data(handle->fp, handle->rdao[frame+2], "REDA");
209         if (!data) {
210                 return NULL;
211         }
212
213         rv = (struct redcode_frame*) calloc(1, sizeof(struct redcode_frame));
214
215         rv->offset = 24+8;
216         rv->length = *(unsigned int*)data - rv->offset;
217         rv->data = data;
218
219         return rv;
220 }
221
222 void redcode_free_frame(struct redcode_frame * frame)
223 {
224         free(frame->data);
225         free(frame);
226 }