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