8461167efc817e62fa41adab216c1f66d5d363c4
[blender.git] / source / blender / avi / intern / avirgb.c
1 /**
2  * avirgb.c
3  *
4  * This is external code. Converts rgb-type avi-s.
5  *
6  * $Id$ 
7  *
8  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version. The Blender
14  * Foundation also sells licenses for use in proprietary software under
15  * the Blender License.  See http://www.blender.org/BL/ for information
16  * about this.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  *
27  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
28  * All rights reserved.
29  *
30  * The Original Code is: all of this file.
31  *
32  * Contributor(s): none yet.
33  *
34  * ***** END GPL/BL DUAL LICENSE BLOCK *****
35  *
36  */
37
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #include "AVI_avi.h"
43 #include <stdlib.h>
44 #include <string.h>
45
46 #include "MEM_guardedalloc.h"
47 #include "avirgb.h"
48
49 #if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__)
50 #define WORDS_BIGENDIAN
51 #endif
52
53
54 /* implementation */
55
56 void *avi_converter_from_avi_rgb (AviMovie *movie, int stream, unsigned char *buffer, int *size) {
57         int x, y,i, rowstride;
58         unsigned char *buf;
59         AviBitmapInfoHeader *bi;
60         short bits= 32;
61
62         bi= (AviBitmapInfoHeader *) movie->streams[stream].sf;
63         if (bi) bits= bi->BitCount;
64
65         if (bits==16) {
66                 unsigned short *pxl;
67                 unsigned char *to;
68                 #ifdef WORDS_BIGENDIAN
69                 unsigned char  *pxla;
70                 #endif            
71                 
72                 buf = MEM_mallocN (movie->header->Height * movie->header->Width * 3, "fromavirgbbuf");
73
74                 y= movie->header->Height;
75                 to= buf;
76                                 
77                 while (y--) {
78                         pxl= (unsigned short *) (buffer + y * movie->header->Width * 2);
79                         
80                         #ifdef WORDS_BIGENDIAN
81                         pxla= (unsigned char *)pxl;
82                         #endif
83
84                         x= movie->header->Width;
85                         while (x--) {
86                                 #ifdef WORDS_BIGENDIAN
87                                 i= pxla[0];
88                                 pxla[0]= pxla[1];
89                                 pxla[1]= i;
90         
91                                 pxla+=2;
92                                 #endif
93                         
94                                 *(to++)= ((*pxl>>10)&0x1f)*8;
95                                 *(to++)= ((*pxl>>5)&0x1f)*8;
96                                 *(to++)= (*pxl&0x1f)*8;
97                                 pxl++;  
98                         }
99                 }
100
101                 MEM_freeN (buffer);
102                 
103                 return buf;
104         } else {
105                 buf = MEM_mallocN (movie->header->Height * movie->header->Width * 3, "fromavirgbbuf");
106         
107                 rowstride = movie->header->Width*3;
108                 if (bits!=16) if (movie->header->Width%2) rowstride++;
109         
110                 for (y=0; y < movie->header->Height; y++) {
111                         memcpy (&buf[y*movie->header->Width*3], &buffer[((movie->header->Height-1)-y)*rowstride], movie->header->Width*3);
112                 }
113         
114                 for (y=0; y < movie->header->Height*movie->header->Width*3; y+=3) {
115                         i = buf[y];
116                         buf[y] = buf[y+2];
117                         buf[y+2] = i;
118                 }
119         
120                 MEM_freeN (buffer);
121         
122                 return buf;
123         }
124 }
125
126 void *avi_converter_to_avi_rgb (AviMovie *movie, int stream, unsigned char *buffer, int *size) {
127         int y, x, i, rowstride;
128         unsigned char *buf;
129
130         *size= movie->header->Height * movie->header->Width * 3;
131         if (movie->header->Width%2) *size+= movie->header->Height;
132         
133         buf = MEM_mallocN (*size,"toavirgbbuf");
134
135         rowstride = movie->header->Width*3;
136         if (movie->header->Width%2) rowstride++;
137
138         for (y=0; y < movie->header->Height; y++) {
139                 memcpy (&buf[y*rowstride], &buffer[((movie->header->Height-1)-y)*movie->header->Width*3], movie->header->Width*3);
140         }
141
142         for (y=0; y < movie->header->Height; y++) {
143                 for (x=0; x < movie->header->Width*3; x+=3) {
144                         i = buf[y*rowstride+x];
145                         buf[y*rowstride+x] = buf[y*rowstride+x+2];
146                         buf[y*rowstride+x+2] = i;
147                 }
148         }
149
150         MEM_freeN (buffer);
151
152         return buf;
153 }