1 /*
2    Header definitions for format converters for the HERMES library
3    Copyright (c) 1998 Christian Nentwich (c.nentwich@cs.ucl.ac.uk)
4    This source code is licensed under the GNU LGPL
5 
6    Please refer to the file COPYING contained in the distribution for
7    licensing conditions
8 */
9 
10 
11 #ifndef __HERMES_INTERNAL_CONVERT__
12 #define __HERMES_INTERNAL_CONVERT__
13 
14 #include "H_Types.h"
15 #include "H_Format.h"
16 #include "Utility.h"
17 #include "HermConf.h"
18 
19 
20 /* Flag to mark generic converters (as opposed to specialised) */
21 
22 #define HERMES_CONVERT_GENERIC 65536
23 
24 
25 
26 /* Pointer to specialised (one-scanline-only) conversion function */
27 
28 typedef void (*HermesConverterPtr)(char8 *source,char8 *dest,
29 				   unsigned int count,unsigned int inc_source);
30 
31 
32 
33 /* Structure for conversion loop routines, don't be scared, size does NOT
34    matter in this case :) */
35 
36 typedef struct {
37   char8 *s_pixels;
38   int s_width,s_height;
39   int s_add;                        /* Offset to next line from end of line */
40 
41   char8 *d_pixels;
42   int d_width,d_height;
43   int d_add;
44 
45   HermesConverterPtr func;
46 
47   int32 *lookup;                    /* Palette lookup table ptr, for 8 bit */
48 
49   int s_pitch;                      /* Source and destination pitch, */
50   int d_pitch;                      /* only used by C routines */
51 
52   HermesGenericInfo info;           /* Only used by generic converters */
53   int32 mask_r,mask_g,mask_b,mask_a;       /* Only used by generic converters */
54   int32 s_mask_a;
55 
56   char s_has_colorkey;
57   int32 s_colorkey;
58 
59   char d_has_colorkey;
60   int32 d_colorkey;
61 } HermesConverterInterface;
62 
63 /* Pointer to loop function (C, assembler main loop, generic routines) */
64 typedef void STACKCALL (*HermesConverterLoopPtr)(HermesConverterInterface*);
65 
66 /* See blit.c for usage for these Jump Table structures */
67 typedef struct {
68 	HermesConverterLoopPtr loopnormal;
69 	HermesConverterLoopPtr loopstretch;
70 	char *converter_name;
71 	} HermesJumpTable;
72 
73 typedef struct {
74 	HermesJumpTable **jt_cc;
75 	HermesJumpTable **jt_ca;
76 	HermesJumpTable **jt_ac;
77 	HermesJumpTable **jt_ao;
78 	HermesJumpTable **jt_aa;
79 	HermesJumpTable **jt_co;
80 	HermesJumpTable **jt_copyonly;
81 	HermesJumpTable **jt_noalpha_alpha;
82 	} HermesJumpTableList;
83 
84 typedef struct {
85 
86   HermesFormat source,dest;                /* Source and destination format */
87   int32* lookup;                           /* Pointer to lookup table (8bit) */
88 
89   unsigned long flags;                     /* Defined in H_Conv.h, DITHER,etc*/
90 
91   HermesConverterLoopPtr loopnormal;       /* Loop routine for normal conv. */
92   HermesConverterLoopPtr loopstretch;
93   HermesConverterPtr normal;               /* One-scanline routine */
94   HermesConverterPtr stretch;
95 
96   HermesConverterLoopPtr dither;           /* Dithering routines always */
97   HermesConverterLoopPtr ditherstretch;    /* convert the whole buffer */
98 
99 } HermesConverter;
100 
101 // Standard macro to convert the RGB format (only used by generic converters)
102 // New_RGB = CONVERT_RGB(Original_RGB);
103 #define CONVERT_RGB(source) ( \
104 	( ( ( (source) >> iface->info.r_right) << iface->info.r_left ) & iface->mask_r ) | \
105         ( ( ( (source) >> iface->info.g_right) << iface->info.g_left ) & iface->mask_g ) | \
106         ( ( ( (source) >> iface->info.b_right) << iface->info.b_left ) & iface->mask_b ) \
107 	)
108 
109 // Standard macro to convert the RGBA format (only used by generic converters)
110 // New_RGBA = CONVERT_RGBA(Original_RGBA);
111 #define CONVERT_RGBA(source) ( \
112         ( ( ( (source) >> iface->info.r_right) << iface->info.r_left ) & iface->mask_r ) | \
113         ( ( ( (source) >> iface->info.g_right) << iface->info.g_left ) & iface->mask_g ) | \
114         ( ( ( (source) >> iface->info.b_right) << iface->info.b_left ) & iface->mask_b ) | \
115         ( ( ( (source) >> iface->info.a_right) << iface->info.a_left ) & iface->mask_a ) \
116 	)
117 
118 // Standard macro to convert the RGBA format with inverse alpha format (only used by generic converters)
119 #define CONVERT_RGBA_NOALPHA(source) ( \
120         ( ( ( (source) >> iface->info.r_right) << iface->info.r_left ) & iface->mask_r ) | \
121         ( ( ( (source) >> iface->info.g_right) << iface->info.g_left ) & iface->mask_g ) | \
122         ( ( ( (source) >> iface->info.b_right) << iface->info.b_left ) & iface->mask_b ) | \
123         ( ( ( (~source) >> iface->info.a_right) << iface->info.a_left ) & iface->mask_a ) \
124 	)
125 
126 
127 // Macro to get a RGB. This may look like a useless macro, however it is required for the generic converter macros
128 #define COPY_RGB(source) source
129 #define COPY_RGBA(source) source
130 
131 // **********************************************
132 // * The General Pixel Conversion Macros        *
133 // * The CG_VARS() and CG_STANDARD() Macros are *
134 // * defined inside the c_genrc*.c source code  *
135 // **********************************************
136 
137 // Define the macro to convert a pixel type
138 // src_read_macro = READxx
139 // dest_write_macro = WRITEyy
140 // src_byte_inc = xx/8
141 // dest_byte_inc = yy/8
142 // dest_read_macro = READyy (0 if unused)
143 #define CG_NORMAL(src_read_macro, dest_write_macro, src_byte_inc, dest_byte_inc, dest_read_macro) \
144  	CG_VARS() \
145 	CG_STANDARD(src_read_macro, dest_write_macro, src_byte_inc, dest_byte_inc, CONVERT_RGB, dest_read_macro)
146 
147 // Define the macro to copy an identical pixel type - checking that the pixel colours are in the same position
148 // src_read_macro = READxx
149 // dest_write_macro = WRITExx
150 // byte_inc = xx/8
151 // dest_read_macro = READyy (0 if unused)
152 #define CG_IDENTICAL(src_read_macro, dest_write_macro, byte_inc, dest_read_macro) \
153  	CG_VARS() \
154 	/* Are the pixel colours in the same position */ \
155 	if (  (iface->info.r_right == iface->info.r_left) \
156 	   && (iface->info.g_right == iface->info.g_left) \
157 	   && (iface->info.b_right == iface->info.b_left) ) \
158 	{ \
159 		CG_STANDARD(src_read_macro, dest_write_macro, byte_inc, byte_inc, COPY_RGB, dest_read_macro) \
160 	}else \
161 	{ \
162 		CG_STANDARD(src_read_macro, dest_write_macro, byte_inc, byte_inc, CONVERT_RGB, dest_read_macro) \
163 	}
164 
165 // Define the stretch macro to convert a pixel type
166 // src_read_macro = READxx
167 // dest_write_macro = WRITEyy
168 // src_byte_inc = xx/8
169 // dest_byte_inc = yy/8
170 // dest_read_macro = READyy (0 if unused)
171 #define CG_S_NORMAL(src_read_macro, dest_write_macro, src_byte_inc, dest_byte_inc, dest_read_macro) \
172  	CG_S_VARS() \
173 	CG_S_STANDARD(src_read_macro, dest_write_macro, src_byte_inc, dest_byte_inc, CONVERT_RGB, dest_read_macro)
174 
175 // Define the stretch macro to copy an identical pixel type - checking that the pixel colours are in the same position
176 // src_read_macro = READxx
177 // dest_write_macro = WRITExx
178 // byte_inc = xx/8
179 // dest_read_macro = READyy (0 if unused)
180 #define CG_S_IDENTICAL(src_read_macro, dest_write_macro, byte_inc, dest_read_macro) \
181  	CG_S_VARS() \
182 	/* Are the pixel colours in the same position */ \
183 	if (  (iface->info.r_right == iface->info.r_left) \
184 	   && (iface->info.g_right == iface->info.g_left) \
185 	   && (iface->info.b_right == iface->info.b_left) ) \
186 	{ \
187 		CG_S_STANDARD(src_read_macro, dest_write_macro, byte_inc, byte_inc, COPY_RGB, dest_read_macro) \
188 	}else \
189 	{ \
190 		CG_S_STANDARD(src_read_macro, dest_write_macro, byte_inc, byte_inc, CONVERT_RGB, dest_read_macro) \
191 	}
192 
193 extern HermesConverter **standardConverters[];
194 extern HermesConverter *equalConverters[];
195 
196 extern int numConverters[];
197 
198 extern HermesJumpTable HJT_NONE[4];
199 extern int HERMES_API Hermes_BlitterRequest_V2(HermesHandle handle, HermesFormat *source, HermesFormat *dest, int api_flags, HermesJumpTableList *tptr);
200 
201 #endif
202 
203 
204