Rice GLES2 (from mupen64plus-ae) plugin. Compile but doesn't works well on the OpenPa...
[mupen64plus-pandora.git] / source / gles2rice / src / liblinux / BMGUtils.c
CommitLineData
292f9317 1/*
2// source code for the BMGLib Utility functions
3//
4// Copyright (C) 2001 M. Scott Heiman
5// All Rights Reserved
6//
7// You may use the software for any purpose you see fit. You may modify
8// it, incorporate it in a commercial application, use it for school,
9// even turn it in as homework. You must keep the Copyright in the
10// header and source files. This software is not in the "Public Domain".
11// You may use this software at your own risk. I have made a reasonable
12// effort to verify that this software works in the manner I expect it to;
13// however,...
14//
15// THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND
16// WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, INCLUDING
17// WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A
18// PARTICULAR PURPOSE. IN NO EVENT SHALL MICHAEL S. HEIMAN BE LIABLE TO
19// YOU OR ANYONE ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
20// CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING
21// WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE,
22// OR THE CLAIMS OF THIRD PARTIES, WHETHER OR NOT MICHAEL S. HEIMAN HAS
23// BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
24// ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
25// POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
26*/
27
28#include <stdlib.h>
29#include "BMGUtils.h"
30
31#ifndef _WIN32
32#include <string.h>
33#endif // _WIN32
34
35/* error strings for all BMG errors */
36static char BMGErrorStrings[17][128] = {
37"No Error",
38"Corrupted file or invalid file format",
39"Invalid bits per pixel for this file format",
40"Memory allocation error",
41"Invalid requested image size",
42"Invalid bitmap handle",
43"Windows API Error", /* this will be overwritten */
44"Unable to open file",
45"Unsupported file format option",
46"Invalid pointer to a BMG image",
47"Unsupported file extension",
48"Error reading file",
49"Error writing to the output file",
50"Invalid pointer to a GeoTIFF structure",
51"The background image is undefined",
52"The background image is too small",
53"Corrupt File"
54};
55
56/* stores last BMG error */
57static BMGError LastBMGError;
58
59/* sets the last BMG error */
60void SetLastBMGError( BMGError err )
61{
62 LastBMGError = err;
63}
64
65/* returns the last error state */
66BMGError GetLastBMGError(void)
67{
68 return LastBMGError;
69}
70/* gets the error message */
71void GetLastBMGErrorMessage( const char **msg )
72{
73 if ( LastBMGError == errWindowsAPI )
74 {
75 char* lpMsgBuf = "Erreur BMG\n";
76
77 /* copy the string. */
78 strcpy( BMGErrorStrings[(int)LastBMGError], (char *)lpMsgBuf );
79 }
80
81 *msg = BMGErrorStrings[(int)LastBMGError];
82}
83
84/* Global background color variables */
85static unsigned char BackgroundColor[4];
86static struct BMGImageStruct BackgroundImage;
87
88/* this function simply initializes the background info. It is called from
89 the DllEntryPoint function */
90void InitBackground(void)
91{
92 memset( (void *)BackgroundColor, 0xFF, 3 ); /* white */
93 BackgroundColor[3] = 0; /* ignored */
94 InitBMGImage( &BackgroundImage );
95}
96
97unsigned char *GetBackgroundColor(void)
98{
99 return &BackgroundColor[0];
100}
101
102struct BMGImageStruct *GetBackgroundImage(void)
103{
104 return &BackgroundImage;
105}
106
107/* converts an array of 1-bit scanlines to 8-bit scanlines */
108void Convert1to8( struct BMGImageStruct img,
109 unsigned char *out )
110{
111 unsigned char *p, *q, *r, *s, *end;
112 int i;
113
114 q = out;
115
116 for ( s = img.bits; s < img.bits + img.scan_width * img.height;
117 s += img.scan_width, q += img.width )
118 {
119 i = img.width % 8;
120 end = q + img.width - i;
121 p = s;
122 for ( r = q; r < end; p++ )
123 {
124 *r++ = (unsigned char)((*p & 0x80) ? 1 : 0);
125 *r++ = (unsigned char)((*p & 0x40) ? 1 : 0);
126 *r++ = (unsigned char)((*p & 0x20) ? 1 : 0);
127 *r++ = (unsigned char)((*p & 0x10) ? 1 : 0);
128 *r++ = (unsigned char)((*p & 0x08) ? 1 : 0);
129 *r++ = (unsigned char)((*p & 0x04) ? 1 : 0);
130 *r++ = (unsigned char)((*p & 0x02) ? 1 : 0);
131 *r++ = (unsigned char)(*p & 0x01);
132 }
133
134 if ( i-- )
135 {
136 *r++ = (unsigned char)((*p & 0x80) ? 1 : 0);
137 if ( i-- )
138 {
139 *r++ = (unsigned char)((*p & 0x40) ? 1 : 0);
140 if ( i-- )
141 {
142 *r++ = (unsigned char)((*p & 0x20) ? 1 : 0);
143 if ( i-- )
144 {
145 *r++ = (unsigned char)((*p & 0x10) ? 1 : 0);
146 if ( i-- )
147 {
148 *r++ = (unsigned char)((*p & 0x08) ? 1 : 0);
149 if ( i-- )
150 {
151 *r++ = (unsigned char)((*p & 0x04) ? 1 : 0);
152 if ( i )
153 *r = (unsigned char)((*p & 0x02) ? 1:0);
154 }
155 }
156 }
157 }
158 }
159 }
160 }
161}
162
163/* converts an array of 4-bit scanlines to 8-bit scanlines */
164void Convert4to8( struct BMGImageStruct img,
165 unsigned char *out )
166{
167 unsigned char *p, *q, *r, *s, *end;
168 int i;
169
170 q = out;
171
172 for ( s = img.bits; s < img.bits + img.scan_width * img.height;
173 s += img.scan_width, q += img.width )
174 {
175 i = img.width % 2;
176 end = q + img.width - i;
177 p = s;
178 for ( r = q; r < end; p++ )
179 {
180 *r++ = (unsigned char)((*p >> 4) & 0x0F);
181 *r++ = (unsigned char)(*p & 0x0F);
182 }
183
184 if ( i )
185 *r = (unsigned char)((*p >> 4) & 0x0F);
186 }
187}
188
189/****************************************************************************/
190/* this function performs alpha blending. It is a variation of a function
191 that I found in the PNG example code */
192unsigned char AlphaComp( unsigned char fg,
193 unsigned char alpha,
194 unsigned char bg )
195{
196 unsigned char out;
197 unsigned short temp;
198
199 switch ( alpha )
200 {
201 case 0:
202 out = bg;
203 break;
204 case 255:
205 out = fg;
206 break;
207 default:
208 temp = ((unsigned short)(fg)*(unsigned short)(alpha) +
209 (unsigned short)(bg)*(unsigned short)(255 -
210 (unsigned short)(alpha)) + (unsigned short)128);
211 out = (unsigned char)((temp + (temp >> 8)) >> 8);
212 break;
213 }
214 return out;
215}
216
217/****************************************************************************
218// Converts a 16 BPP image to a 24 BPP image
219// returns 1 if successfull, 0 otherwise */
220BMGError Convert16to24( struct BMGImageStruct *img )
221{
222 unsigned int i;
223 unsigned int new_scan_width;
224 unsigned char *new_bits;
225
226 /* this function will only work with 16 BBP images */
227 if ( img->bits_per_pixel != 16 )
228 return errInvalidPixelFormat;
229
230 /* calculate the new scan width */
231 new_scan_width = 3 * img->width;
232 if ( new_scan_width % 4 && img->opt_for_bmp )
233 new_scan_width += 4 - new_scan_width % 4;
234
235 /* allocate memory for the new pixel values */
236 new_bits = (unsigned char *)calloc( new_scan_width * img->height, sizeof(unsigned char) );
237 if ( new_bits == NULL )
238 return errMemoryAllocation;
239
240 /* convert the 16 BPP pixel values to the equivalent 24 BPP values */
241 for ( i = 0; i < img->height; i++ )
242 {
243 unsigned char *p24;
244 unsigned short *p16 = (unsigned short *)(img->bits + i * img->scan_width);
245 unsigned char *start = new_bits + i * new_scan_width;
246 unsigned char *end = start + new_scan_width;
247 for ( p24 = start; p24 < end; p24 += 3, p16++ )
248 {
249 p24[0] = (unsigned char)( (*p16 & 0x001F) << 3 );
250 p24[1] = (unsigned char)( (*p16 & 0x03E0) >> 2 );
251 p24[2] = (unsigned char)( (*p16 & 0x7C00) >> 7 );
252 }
253 }
254
255 free( img->bits );
256 img->bits = new_bits;
257 img->scan_width = new_scan_width;
258 img->bits_per_pixel = 24;
259
260 return BMG_OK;
261}
262
263/****************************************************************************/
264/* this function undoes alpha blending - kind-a-sort-of ;-) */
265unsigned char InverseAlphaComp( unsigned char fg, unsigned char alpha,
266 unsigned char bg )
267{
268 unsigned char out;
269 short temp;
270
271 switch ( alpha )
272 {
273 case 0:
274 out = bg;
275 break;
276 case 255:
277 out = fg;
278 break;
279 default:
280 temp = (255*fg - bg*(255-alpha))/alpha;
281 if ( temp < 0 )
282 temp = 0;
283 out = (unsigned char)temp;
284 break;
285 }
286 return out;
287}
288
289/****************************************************************************/
290/*
291// Creates a BITMAPINFOHEADER for the given width, height, bit count, and
292// compression. Compression must = BI_RGB, BI_BITFIELDS, BI_RLE4, or BI_RLE8.
293*/
294BITMAPINFO InternalCreateBMI( unsigned int dwWidth, /* width */
295 unsigned int dwHeight, /* height */
296 unsigned short wBitCount, /* bit count */
297 int compression ) /* compression type */
298{
299 BITMAPINFO bi; /* bitmap header */
300 unsigned int dwBytesPerLine; /* Number of bytes per scanline */
301
302 /* clear the bitmapinfo structure */
303 memset(&bi, 0, sizeof(BITMAPINFO));
304
305 /* Make sure bits per pixel is valid */
306 if (wBitCount <= 1)
307 wBitCount = 1;
308 else if (wBitCount <= 4)
309 wBitCount = 4;
310 else if (wBitCount <= 8)
311 wBitCount = 8;
312 else if (wBitCount <= 16)
313 wBitCount = 16;
314 else if (wBitCount <= 24)
315 wBitCount = 24;
316 else if (wBitCount <= 32)
317 wBitCount = 32;
318 else
319 wBitCount = 8; /* set default value to 8 if parameter is bogus */
320
321 dwBytesPerLine = (((wBitCount * dwWidth) + 31) / 32 * 4);
322
323 /* initialize BITMAPINFO */
324 bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
325 bi.bmiHeader.biWidth = dwWidth;
326 bi.bmiHeader.biHeight = dwHeight;
327 bi.bmiHeader.biPlanes = 1; /* must be 1 */
328 bi.bmiHeader.biBitCount = wBitCount;
329 bi.bmiHeader.biCompression = compression;
330 bi.bmiHeader.biSizeImage = dwBytesPerLine*dwHeight;
331 bi.bmiHeader.biXPelsPerMeter = 0;
332 bi.bmiHeader.biYPelsPerMeter = 0;
333 bi.bmiHeader.biClrUsed = wBitCount <= 8 ? 1U << wBitCount : 0;
334 bi.bmiHeader.biClrImportant = bi.bmiHeader.biClrUsed;
335
336 return bi;
337}
338
339short SwapShort( short in )
340{
341 char sin[2];
342 char sout[2];
343
344 memcpy( (char *)sin, (char *)&in, 2 );
345
346 sout[0] = sin[1];
347 sout[1] = sin[0];
348
349 return *((short *)sout);
350}
351
352unsigned short SwapUShort( unsigned short in )
353{
354 char sin[2];
355 char sout[2];
356
357 memcpy( (char *)sin, (char *)&in, 2 );
358
359 sout[0] = sin[1];
360 sout[1] = sin[0];
361
362 return *((unsigned short *)sout);
363}
364
365int SwapLong( int in )
366{
367 char sin[4];
368 char sout[4];
369
370 memcpy( (char *)sin, (char *)&in, 4 );
371
372 sout[0] = sin[3];
373 sout[1] = sin[2];
374 sout[2] = sin[1];
375 sout[3] = sin[0];
376
377 return *((int *)sout);
378}
379
380unsigned int SwapULong( unsigned int in )
381{
382 char sin[4];
383 char sout[4];
384
385 memcpy( (char *)sin, (char *)&in, 4 );
386
387 sout[0] = sin[3];
388 sout[1] = sin[2];
389 sout[2] = sin[1];
390 sout[3] = sin[0];
391
392 return *((unsigned int *)sout);
393}
394