Merging r46111 through r46136 from trunk into soc-2011-tomato
[blender-staging.git] / source / blender / avi / intern / endian.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (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 Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  *
27  */
28
29 /** \file blender/avi/intern/endian.c
30  *  \ingroup avi
31  *
32  * This is external code. Streams bytes to output depending on the
33  * endianness of the system.
34  */
35
36
37 #include <stdlib.h>
38 #include <string.h>
39 #include <stdio.h> 
40 #include "AVI_avi.h"
41 #include "endian.h"
42 #include "avi_intern.h"
43
44 #ifdef __BIG_ENDIAN__
45 #include "MEM_guardedalloc.h"
46 #endif
47
48 #ifdef __BIG_ENDIAN__
49 static void invert (int *num)
50 {
51         int new=0, i, j;
52
53         for (j=0; j < 4; j++) {
54                 for (i=0; i<8; i++) {
55                         new |= ((*num>>(j*8+i))&1)<<((3-j)*8+i);
56                 }
57         }
58         
59         *num = new;
60 }
61
62 static void sinvert (short int *num)
63 {
64         short int new=0;
65         int i, j;
66
67         for (j=0; j < 2; j++) {
68                 for (i=0; i<8; i++) {
69                         new |= ((*num>>(j*8+i))&1)<<((1-j)*8+i);
70                 }
71         }
72
73         *num = new;
74 }
75
76 static void Ichunk (AviChunk *chunk)
77 {
78         invert (&chunk->fcc);
79         invert (&chunk->size);
80 }
81 #endif
82
83 #ifdef __BIG_ENDIAN__
84 static void Ilist (AviList *list)
85 {
86         invert (&list->fcc);
87         invert (&list->size);
88         invert (&list->ids);
89 }
90
91 static void Imainh (AviMainHeader *mainh)
92 {
93         invert (&mainh->fcc);
94         invert (&mainh->size);
95         invert (&mainh->MicroSecPerFrame);
96         invert (&mainh->MaxBytesPerSec);
97         invert (&mainh->PaddingGranularity);
98         invert (&mainh->Flags);
99         invert (&mainh->TotalFrames);
100         invert (&mainh->InitialFrames);
101         invert (&mainh->Streams);
102         invert (&mainh->SuggestedBufferSize);
103         invert (&mainh->Width);
104         invert (&mainh->Height);
105         invert (&mainh->Reserved[0]);
106         invert (&mainh->Reserved[1]);
107         invert (&mainh->Reserved[2]);
108         invert (&mainh->Reserved[3]);
109 }
110
111 static void Istreamh (AviStreamHeader *streamh)
112 {
113         invert (&streamh->fcc);
114         invert (&streamh->size);
115         invert (&streamh->Type);
116         invert (&streamh->Handler);
117         invert (&streamh->Flags);
118         sinvert (&streamh->Priority);
119         sinvert (&streamh->Language);
120         invert (&streamh->InitialFrames);
121         invert (&streamh->Scale);
122         invert (&streamh->Rate);
123         invert (&streamh->Start);
124         invert (&streamh->Length);
125         invert (&streamh->SuggestedBufferSize);
126         invert (&streamh->Quality);
127         invert (&streamh->SampleSize);
128         sinvert (&streamh->left);
129         sinvert (&streamh->right);
130         sinvert (&streamh->top);
131         sinvert (&streamh->bottom);
132 }
133
134 static void Ibitmaph (AviBitmapInfoHeader *bitmaph)
135 {
136         invert (&bitmaph->fcc);
137         invert (&bitmaph->size);
138         invert (&bitmaph->Size);
139         invert (&bitmaph->Width);
140         invert (&bitmaph->Height);
141         sinvert (&bitmaph->Planes);
142         sinvert (&bitmaph->BitCount);
143         invert (&bitmaph->Compression);
144         invert (&bitmaph->SizeImage);
145         invert (&bitmaph->XPelsPerMeter);
146         invert (&bitmaph->YPelsPerMeter);
147         invert (&bitmaph->ClrUsed);
148         invert (&bitmaph->ClrImportant);
149 }
150
151 static void Imjpegu (AviMJPEGUnknown *mjpgu)
152 {
153         invert (&mjpgu->a);
154         invert (&mjpgu->b);
155         invert (&mjpgu->c);
156         invert (&mjpgu->d);
157         invert (&mjpgu->e);
158         invert (&mjpgu->f);
159         invert (&mjpgu->g);
160 }
161
162 static void Iindexe (AviIndexEntry *indexe)
163 {
164         invert (&indexe->ChunkId);
165         invert (&indexe->Flags);
166         invert (&indexe->Offset);
167         invert (&indexe->Size);
168 }
169 #endif /* __BIG_ENDIAN__ */
170
171 void awrite(AviMovie *movie, void *datain, int block, int size, FILE *fp, int type)
172 {
173 #ifdef __BIG_ENDIAN__
174         void *data;
175
176         data = MEM_mallocN (size, "avi endian");
177
178         memcpy (data, datain, size);
179
180         switch (type) {
181         case AVI_RAW:
182                 fwrite (data, block, size, fp);
183                 break;
184         case AVI_CHUNK:
185                 Ichunk ((AviChunk *) data);
186                 fwrite (data, block, size, fp);
187                 break;
188         case AVI_LIST:
189                 Ilist ((AviList *) data);
190                 fwrite (data, block, size, fp);
191                 break;
192         case AVI_MAINH:
193                 Imainh ((AviMainHeader *) data);
194                 fwrite (data, block, size, fp);
195                 break;
196         case AVI_STREAMH:
197                 Istreamh ((AviStreamHeader *) data);
198                 fwrite (data, block, size, fp);
199                 break;
200         case AVI_BITMAPH:
201                 Ibitmaph ((AviBitmapInfoHeader *) data);
202                 if (size==sizeof(AviBitmapInfoHeader) + sizeof(AviMJPEGUnknown)) {
203                         Imjpegu((AviMJPEGUnknown*)((char*)data+sizeof(AviBitmapInfoHeader)));
204                 }
205                 fwrite (data, block, size, fp);
206                 break;
207         case AVI_MJPEGU:
208                 Imjpegu ((AviMJPEGUnknown *) data);
209                 fwrite (data, block, size, fp);
210                 break;
211         case AVI_INDEXE:
212                 Iindexe ((AviIndexEntry *) data);
213                 fwrite (data, block, size, fp);
214                 break;
215         default:
216                 break;
217         }
218
219         MEM_freeN (data);
220 #else /* __BIG_ENDIAN__ */
221         (void)movie; /* unused */
222         (void)type; /* unused */
223         fwrite (datain, block, size, fp);
224 #endif /* __BIG_ENDIAN__ */
225 }